Index: lldb/include/lldb/Interpreter/CommandInterpreter.h =================================================================== --- lldb/include/lldb/Interpreter/CommandInterpreter.h +++ lldb/include/lldb/Interpreter/CommandInterpreter.h @@ -533,6 +533,11 @@ private: Status PreprocessCommand(std::string &command); + + void SourceInitFileCwd(CommandReturnObject &result); + void SourceInitFileHome(CommandReturnObject &result); + void SourceInitFile(FileSpec file, CommandReturnObject &result); + // Completely resolves aliases and abbreviations, returning a pointer to the // final command object and updating command_line to the fully substituted // and translated command. Index: lldb/source/Interpreter/CommandInterpreter.cpp =================================================================== --- lldb/source/Interpreter/CommandInterpreter.cpp +++ lldb/source/Interpreter/CommandInterpreter.cpp @@ -2091,100 +2091,130 @@ return position; } -void CommandInterpreter::SourceInitFile(bool in_cwd, +static FileSpec GetHomeInitFile(llvm::StringRef suffix = {}) { + llvm::SmallString<64> buffer; + llvm::sys::path::home_directory(buffer); + llvm::sys::path::append(buffer, ".lldbinit"); + + FileSpec init_file(buffer.c_str()); + FileSystem::Instance().Resolve(init_file); + return init_file; +} + +static FileSpec GetCwdInitFile() { + FileSpec init_file(".lldbinit"); + FileSystem::Instance().Resolve(init_file); + return init_file; +} + +static LoadCWDlldbinitFile ShouldLoadCwdInitFile() { + lldb::TargetPropertiesSP properties = Target::GetGlobalProperties(); + if (!properties) + return eLoadCWDlldbinitFalse; + return properties->GetLoadCWDlldbinitFile(); +} + +void CommandInterpreter::SourceInitFile(FileSpec file, CommandReturnObject &result) { - FileSpec init_file; - if (in_cwd) { - lldb::TargetPropertiesSP properties = Target::GetGlobalProperties(); - if (properties) { - // In the current working directory we don't load any program specific - // .lldbinit files, we only look for a ".lldbinit" file. - if (m_skip_lldbinit_files) - return; + if (!FileSystem::Instance().Exists(file)) { + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return; + } - LoadCWDlldbinitFile should_load = properties->GetLoadCWDlldbinitFile(); - if (should_load == eLoadCWDlldbinitWarn) { - FileSpec dot_lldb(".lldbinit"); - FileSystem::Instance().Resolve(dot_lldb); - llvm::SmallString<64> home_dir_path; - llvm::sys::path::home_directory(home_dir_path); - FileSpec homedir_dot_lldb(home_dir_path.c_str()); - homedir_dot_lldb.AppendPathComponent(".lldbinit"); - FileSystem::Instance().Resolve(homedir_dot_lldb); - if (FileSystem::Instance().Exists(dot_lldb) && - dot_lldb.GetDirectory() != homedir_dot_lldb.GetDirectory()) { - result.AppendErrorWithFormat( - "There is a .lldbinit file in the current directory which is not " - "being read.\n" - "To silence this warning without sourcing in the local " - ".lldbinit,\n" - "add the following to the lldbinit file in your home directory:\n" - " settings set target.load-cwd-lldbinit false\n" - "To allow lldb to source .lldbinit files in the current working " - "directory,\n" - "set the value of this variable to true. Only do so if you " - "understand and\n" - "accept the security risk."); - result.SetStatus(eReturnStatusFailed); - return; - } - } else if (should_load == eLoadCWDlldbinitTrue) { - init_file.SetFile("./.lldbinit", FileSpec::Style::native); - FileSystem::Instance().Resolve(init_file); - } - } - } else { - // If we aren't looking in the current working directory we are looking in - // the home directory. 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. We also obey any requests to not load the - // init files. - llvm::SmallString<64> home_dir_path; - llvm::sys::path::home_directory(home_dir_path); - FileSpec profilePath(home_dir_path.c_str()); - profilePath.AppendPathComponent(".lldbinit"); - std::string init_file_path = profilePath.GetPath(); - - if (!m_skip_app_init_files) { - FileSpec program_file_spec(HostInfo::GetProgramFileSpec()); - const char *program_name = program_file_spec.GetFilename().AsCString(); - - if (program_name) { - char program_init_file_name[PATH_MAX]; - ::snprintf(program_init_file_name, sizeof(program_init_file_name), - "%s-%s", init_file_path.c_str(), program_name); - init_file.SetFile(program_init_file_name, FileSpec::Style::native); - FileSystem::Instance().Resolve(init_file); - if (!FileSystem::Instance().Exists(init_file)) - init_file.Clear(); - } + // Use HandleCommand to 'source' the given file; this will do the actual + // broadcasting of the commands back to any appropriate listener (see + // CommandObjectSource::Execute for more details). + const bool saved_batch = SetBatchCommandMode(true); + CommandInterpreterRunOptions options; + options.SetSilent(true); + options.SetPrintErrors(true); + options.SetStopOnError(false); + options.SetStopOnContinue(true); + + HandleCommandsFromFile(file, + nullptr, // Execution context + options, result); + SetBatchCommandMode(saved_batch); +} + +void CommandInterpreter::SourceInitFileCwd(CommandReturnObject &result) { + assert(!m_skip_lldbinit_files); + + FileSpec init_file = GetCwdInitFile(); + if (!FileSystem::Instance().Exists(init_file)) { + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return; + } + + LoadCWDlldbinitFile should_load = ShouldLoadCwdInitFile(); + if (should_load == eLoadCWDlldbinitFalse) { + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return; + } + + if (should_load == eLoadCWDlldbinitWarn) { + FileSpec home_init_file = GetHomeInitFile(); + if (init_file.GetDirectory() == home_init_file.GetDirectory()) { + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return; } - if (!init_file && !m_skip_lldbinit_files) - init_file.SetFile(init_file_path, FileSpec::Style::native); + result.AppendErrorWithFormat( + "There is a .lldbinit file in the current directory which is not " + "being read.\n" + "To silence this warning without sourcing in the local " + ".lldbinit,\n" + "add the following to the lldbinit file in your home directory:\n" + " settings set target.load-cwd-lldbinit false\n" + "To allow lldb to source .lldbinit files in the current working " + "directory,\n" + "set the value of this variable to true. Only do so if you " + "understand and\n" + "accept the security risk."); + result.SetStatus(eReturnStatusFailed); + return; } - // If the file exists, tell HandleCommand to 'source' it; this will do the - // actual broadcasting of the commands back to any appropriate listener (see - // CommandObjectSource::Execute for more details). + assert(should_load == eLoadCWDlldbinitTrue); + SourceInitFile(init_file, result); +} - if (FileSystem::Instance().Exists(init_file)) { - const bool saved_batch = SetBatchCommandMode(true); - CommandInterpreterRunOptions options; - options.SetSilent(true); - options.SetPrintErrors(true); - options.SetStopOnError(false); - options.SetStopOnContinue(true); - - HandleCommandsFromFile(init_file, - nullptr, // Execution context - options, result); - SetBatchCommandMode(saved_batch); - } else { - // nothing to be done if the file doesn't exist +void CommandInterpreter::SourceInitFileHome(CommandReturnObject &result) { + assert(!m_skip_lldbinit_files); + // 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. + FileSpec init_file = GetHomeInitFile(); + + if (!m_skip_app_init_files) { + FileSpec program_file_spec(HostInfo::GetProgramFileSpec()); + const char *program_name = program_file_spec.GetFilename().AsCString(); + + if (program_name) { + char program_init_file_name[PATH_MAX]; + ::snprintf(program_init_file_name, sizeof(program_init_file_name), + "%s-%s", init_file.GetPath().c_str(), program_name); + FileSpec app_init_file = FileSpec(program_init_file_name); + FileSystem::Instance().Resolve(init_file); + if (FileSystem::Instance().Exists(init_file)) + init_file = app_init_file; + } + } + + SourceInitFile(init_file, result); +} + +void CommandInterpreter::SourceInitFile(bool in_cwd, + CommandReturnObject &result) { + if (m_skip_lldbinit_files) { result.SetStatus(eReturnStatusSuccessFinishNoResult); + return; } + + if (in_cwd) + SourceInitFileCwd(result); + else + SourceInitFileHome(result); } const char *CommandInterpreter::GetCommandPrefix() {