diff --git a/lldb/docs/man/lldb.rst b/lldb/docs/man/lldb.rst --- a/lldb/docs/man/lldb.rst +++ b/lldb/docs/man/lldb.rst @@ -305,11 +305,15 @@ :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 diff --git a/lldb/include/lldb/API/SBCommandInterpreter.h b/lldb/include/lldb/API/SBCommandInterpreter.h --- a/lldb/include/lldb/API/SBCommandInterpreter.h +++ b/lldb/include/lldb/API/SBCommandInterpreter.h @@ -146,6 +146,8 @@ const char *auto_repeat_command); void SourceInitFileInHomeDirectory(lldb::SBCommandReturnObject &result); + void SourceInitFileInHomeDirectory(lldb::SBCommandReturnObject &result, + bool is_repl); void SourceInitFileInCurrentWorkingDirectory(lldb::SBCommandReturnObject &result); diff --git a/lldb/include/lldb/Interpreter/CommandInterpreter.h b/lldb/include/lldb/Interpreter/CommandInterpreter.h --- a/lldb/include/lldb/Interpreter/CommandInterpreter.h +++ b/lldb/include/lldb/Interpreter/CommandInterpreter.h @@ -256,7 +256,7 @@ } 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); diff --git a/lldb/source/API/SBCommandInterpreter.cpp b/lldb/source/API/SBCommandInterpreter.cpp --- a/lldb/source/API/SBCommandInterpreter.cpp +++ b/lldb/source/API/SBCommandInterpreter.cpp @@ -478,6 +478,24 @@ } } +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 lock; + if (target_sp) + lock = std::unique_lock(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 @@ 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 &)); diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -220,7 +220,7 @@ 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); diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -2090,6 +2090,22 @@ FileSystem::Instance().Resolve(init_file); } +static void GetHomeREPLInitFile(llvm::SmallVectorImpl &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 &init_file) { llvm::StringRef s = ".lldbinit"; init_file.assign(s.begin(), s.end()); @@ -2164,15 +2180,27 @@ /// 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 = diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -493,7 +493,7 @@ // 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());