[lldb/interpreter] Add REPL-specific init file
This patch adds the infrastructure to have language specific REPL init files. It's the foundation work to a following patch that will introduce Swift REPL init file. When lldb is launched with the `--repl` option, it will look for a REPL init file in the home directory and source it. This overrides the default `~/.lldbinit`, which content might make the REPL behave unexpectedly. If the REPL init file doesn't exists, lldb will fall back to the default init file. rdar://65836048 Differential Revision: https://reviews.llvm.org/D86242 Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
This commit is contained in:
parent
428bebaf10
commit
868b45b5b3
|
@ -305,11 +305,15 @@ CONFIGURATION FILES
|
|||
:program:`lldb` reads things like settings, aliases and commands from the
|
||||
.lldbinit file.
|
||||
|
||||
First, it will read the application specific init file whose name is
|
||||
~/.lldbinit followed by a "-" and the name of the current program. This would
|
||||
be ~/.lldbinit-lldb for the command line :program:`lldb` and ~/.lldbinit-Xcode
|
||||
for Xcode. If there is no application specific init file, the global
|
||||
~/.lldbinit is read.
|
||||
First, :program:`lldb` will try to read the application specific init file
|
||||
whose name is ~/.lldbinit followed by a "-" and the name of the current
|
||||
program. This would be ~/.lldbinit-lldb for the command line :program:`lldb`
|
||||
and ~/.lldbinit-Xcode for Xcode. If there is no application specific init
|
||||
file, :program:`lldb` will look for an init file in the home directory.
|
||||
If launched with a `REPL`_ option, it will first look for a REPL configuration
|
||||
file, specific to the REPL language. If this file doesn't exist, or :program:`lldb`
|
||||
wasn't launch with `REPL`_, meaning there is neither a REPL init file nor an
|
||||
application specific init file, `lldb` will fallback to the global ~/.lldbinit.
|
||||
|
||||
Secondly, it will look for an .lldbinit file in the current working directory.
|
||||
For security reasons, :program:`lldb` will print a warning and not source this
|
||||
|
|
|
@ -146,6 +146,8 @@ public:
|
|||
const char *auto_repeat_command);
|
||||
|
||||
void SourceInitFileInHomeDirectory(lldb::SBCommandReturnObject &result);
|
||||
void SourceInitFileInHomeDirectory(lldb::SBCommandReturnObject &result,
|
||||
bool is_repl);
|
||||
|
||||
void
|
||||
SourceInitFileInCurrentWorkingDirectory(lldb::SBCommandReturnObject &result);
|
||||
|
|
|
@ -256,7 +256,7 @@ public:
|
|||
}
|
||||
|
||||
void SourceInitFileCwd(CommandReturnObject &result);
|
||||
void SourceInitFileHome(CommandReturnObject &result);
|
||||
void SourceInitFileHome(CommandReturnObject &result, bool is_repl = false);
|
||||
|
||||
bool AddCommand(llvm::StringRef name, const lldb::CommandObjectSP &cmd_sp,
|
||||
bool can_replace);
|
||||
|
|
|
@ -478,6 +478,24 @@ void SBCommandInterpreter::SourceInitFileInHomeDirectory(
|
|||
}
|
||||
}
|
||||
|
||||
void SBCommandInterpreter::SourceInitFileInHomeDirectory(
|
||||
SBCommandReturnObject &result, bool is_repl) {
|
||||
LLDB_RECORD_METHOD(void, SBCommandInterpreter, SourceInitFileInHomeDirectory,
|
||||
(lldb::SBCommandReturnObject &, bool), result, is_repl);
|
||||
|
||||
result.Clear();
|
||||
if (IsValid()) {
|
||||
TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
|
||||
std::unique_lock<std::recursive_mutex> lock;
|
||||
if (target_sp)
|
||||
lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
|
||||
m_opaque_ptr->SourceInitFileHome(result.ref(), is_repl);
|
||||
} else {
|
||||
result->AppendError("SBCommandInterpreter is not valid");
|
||||
result->SetStatus(eReturnStatusFailed);
|
||||
}
|
||||
}
|
||||
|
||||
void SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory(
|
||||
SBCommandReturnObject &result) {
|
||||
LLDB_RECORD_METHOD(void, SBCommandInterpreter,
|
||||
|
@ -806,6 +824,9 @@ template <> void RegisterMethods<SBCommandInterpreter>(Registry &R) {
|
|||
LLDB_REGISTER_METHOD(void, SBCommandInterpreter,
|
||||
SourceInitFileInHomeDirectory,
|
||||
(lldb::SBCommandReturnObject &));
|
||||
LLDB_REGISTER_METHOD(void, SBCommandInterpreter,
|
||||
SourceInitFileInHomeDirectory,
|
||||
(lldb::SBCommandReturnObject &, bool));
|
||||
LLDB_REGISTER_METHOD(void, SBCommandInterpreter,
|
||||
SourceInitFileInCurrentWorkingDirectory,
|
||||
(lldb::SBCommandReturnObject &));
|
||||
|
|
|
@ -220,7 +220,7 @@ SBDebugger SBDebugger::Create(bool source_init_files,
|
|||
interp.get()->SkipLLDBInitFiles(false);
|
||||
interp.get()->SkipAppInitFiles(false);
|
||||
SBCommandReturnObject result;
|
||||
interp.SourceInitFileInHomeDirectory(result);
|
||||
interp.SourceInitFileInHomeDirectory(result, false);
|
||||
} else {
|
||||
interp.get()->SkipLLDBInitFiles(true);
|
||||
interp.get()->SkipAppInitFiles(true);
|
||||
|
|
|
@ -2090,6 +2090,22 @@ static void GetHomeInitFile(llvm::SmallVectorImpl<char> &init_file,
|
|||
FileSystem::Instance().Resolve(init_file);
|
||||
}
|
||||
|
||||
static void GetHomeREPLInitFile(llvm::SmallVectorImpl<char> &init_file,
|
||||
LanguageType language) {
|
||||
std::string init_file_name;
|
||||
|
||||
switch (language) {
|
||||
// TODO: Add support for a language used with a REPL.
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
llvm::sys::path::home_directory(init_file);
|
||||
llvm::sys::path::append(init_file, init_file_name);
|
||||
|
||||
FileSystem::Instance().Resolve(init_file);
|
||||
}
|
||||
|
||||
static void GetCwdInitFile(llvm::SmallVectorImpl<char> &init_file) {
|
||||
llvm::StringRef s = ".lldbinit";
|
||||
init_file.assign(s.begin(), s.end());
|
||||
|
@ -2164,15 +2180,27 @@ void CommandInterpreter::SourceInitFileCwd(CommandReturnObject &result) {
|
|||
|
||||
/// We will first see if there is an application specific ".lldbinit" file
|
||||
/// whose name is "~/.lldbinit" followed by a "-" and the name of the program.
|
||||
/// If this file doesn't exist, we fall back to just the "~/.lldbinit" file.
|
||||
void CommandInterpreter::SourceInitFileHome(CommandReturnObject &result) {
|
||||
/// If this file doesn't exist, we fall back to the REPL init file or the
|
||||
/// default home init file in "~/.lldbinit".
|
||||
void CommandInterpreter::SourceInitFileHome(CommandReturnObject &result,
|
||||
bool is_repl) {
|
||||
if (m_skip_lldbinit_files) {
|
||||
result.SetStatus(eReturnStatusSuccessFinishNoResult);
|
||||
return;
|
||||
}
|
||||
|
||||
llvm::SmallString<128> init_file;
|
||||
GetHomeInitFile(init_file);
|
||||
|
||||
if (is_repl) {
|
||||
LanguageType language = {};
|
||||
TargetSP target_sp = GetDebugger().GetSelectedTarget();
|
||||
if (target_sp)
|
||||
language = target_sp->GetLanguage();
|
||||
GetHomeREPLInitFile(init_file, language);
|
||||
}
|
||||
|
||||
if (init_file.empty())
|
||||
GetHomeInitFile(init_file);
|
||||
|
||||
if (!m_skip_app_init_files) {
|
||||
llvm::StringRef program_name =
|
||||
|
|
|
@ -493,7 +493,7 @@ int Driver::MainLoop() {
|
|||
// Before we handle any options from the command line, we parse the
|
||||
// .lldbinit file in the user's home directory.
|
||||
SBCommandReturnObject result;
|
||||
sb_interpreter.SourceInitFileInHomeDirectory(result);
|
||||
sb_interpreter.SourceInitFileInHomeDirectory(result, m_option_data.m_repl);
|
||||
if (m_option_data.m_debug_mode) {
|
||||
result.PutError(m_debugger.GetErrorFile());
|
||||
result.PutOutput(m_debugger.GetOutputFile());
|
||||
|
|
Loading…
Reference in a new issue