From 3bf3b96629e8dfc55d01ba0cb05ca01a467017fa Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Mon, 27 Sep 2021 17:51:37 -0700 Subject: [PATCH] Add the --relative-to-command-file to "command source" so you can have linked command files in a source tree and get to them all from one main command file. Differential Revision: https://reviews.llvm.org/D110601 --- lldb/source/Commands/CommandObjectCommands.cpp | 30 +++++++++++++++++++++- lldb/source/Commands/Options.td | 4 +++ .../commands/command/source/TestCommandSource.py | 29 ++++++++++++++++++--- .../test/API/commands/command/source/commands2.txt | 1 + .../API/commands/command/source/not-relative.txt | 2 ++ .../API/commands/command/source/subdir/subcmds.txt | 1 + 6 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 lldb/test/API/commands/command/source/commands2.txt create mode 100644 lldb/test/API/commands/command/source/not-relative.txt create mode 100644 lldb/test/API/commands/command/source/subdir/subcmds.txt diff --git a/lldb/source/Commands/CommandObjectCommands.cpp b/lldb/source/Commands/CommandObjectCommands.cpp index 9a8b81c..6392798 100644 --- a/lldb/source/Commands/CommandObjectCommands.cpp +++ b/lldb/source/Commands/CommandObjectCommands.cpp @@ -77,7 +77,7 @@ protected: public: CommandOptions() : Options(), m_stop_on_error(true), m_silent_run(false), - m_stop_on_continue(true) {} + m_stop_on_continue(true), m_cmd_relative_to_command_file(false) {} ~CommandOptions() override = default; @@ -95,6 +95,10 @@ protected: error = m_stop_on_continue.SetValueFromString(option_arg); break; + case 'C': + m_cmd_relative_to_command_file = true; + break; + case 's': error = m_silent_run.SetValueFromString(option_arg); break; @@ -110,6 +114,7 @@ protected: m_stop_on_error.Clear(); m_silent_run.Clear(); m_stop_on_continue.Clear(); + m_cmd_relative_to_command_file.Clear(); } llvm::ArrayRef GetDefinitions() override { @@ -121,6 +126,7 @@ protected: OptionValueBoolean m_stop_on_error; OptionValueBoolean m_silent_run; OptionValueBoolean m_stop_on_continue; + OptionValueBoolean m_cmd_relative_to_command_file; }; bool DoExecute(Args &command, CommandReturnObject &result) override { @@ -131,7 +137,29 @@ protected: return false; } + FileSpec source_dir = {}; + if (m_options.m_cmd_relative_to_command_file) { + source_dir = GetDebugger().GetCommandInterpreter().GetCurrentSourceDir(); + if (!source_dir) { + result.AppendError("command source -C can only be specified " + "from a command file"); + result.SetStatus(eReturnStatusFailed); + return false; + } + } + FileSpec cmd_file(command[0].ref()); + if (source_dir) { + // Prepend the source_dir to the cmd_file path: + if (!cmd_file.IsRelative()) { + result.AppendError("command source -C can only be used " + "with a relative path."); + result.SetStatus(eReturnStatusFailed); + return false; + } + cmd_file.MakeAbsolute(source_dir); + } + FileSystem::Instance().Resolve(cmd_file); CommandInterpreterRunOptions options; diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 83df2ac..3d69bb8 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -536,6 +536,10 @@ let Command = "source" in { Desc<"If true, stop executing commands on continue.">; def source_silent_run : Option<"silent-run", "s">, Arg<"Boolean">, Desc<"If true don't echo commands while executing.">; + def cmd_relative_to_command_file : Option<"relative-to-command-file", "C">, + Desc<"Resolve non-absolute paths relative to the location of the " + "current command file. This argument can only be used when the command is " + "being sourced from a file.">; } let Command = "alias" in { diff --git a/lldb/test/API/commands/command/source/TestCommandSource.py b/lldb/test/API/commands/command/source/TestCommandSource.py index 6d2717b..dc32e20 100644 --- a/lldb/test/API/commands/command/source/TestCommandSource.py +++ b/lldb/test/API/commands/command/source/TestCommandSource.py @@ -21,7 +21,18 @@ class CommandSourceTestCase(TestBase): # Sourcing .lldb in the current working directory, which in turn imports # the "my" package that defines the date() function. self.runCmd("command source .lldb") + self.check_results() + + @no_debug_info_test + def test_command_source_relative(self): + """Test that lldb command "command source" works correctly with relative paths.""" + # Sourcing .lldb in the current working directory, which in turn imports + # the "my" package that defines the date() function. + self.runCmd("command source commands2.txt") + self.check_results() + + def check_results(self, failure=False): # Python should evaluate "my.date()" successfully. command_interpreter = self.dbg.GetCommandInterpreter() self.assertTrue(command_interpreter, VALID_COMMAND_INTERPRETER) @@ -29,6 +40,18 @@ class CommandSourceTestCase(TestBase): command_interpreter.HandleCommand("script my.date()", result) import datetime - self.expect(result.GetOutput(), "script my.date() runs successfully", - exe=False, - substrs=[str(datetime.date.today())]) + if failure: + self.expect(result.GetOutput(), "script my.date() runs successfully", + exe=False, error=True) + else: + self.expect(result.GetOutput(), "script my.date() runs successfully", + exe=False, + substrs=[str(datetime.date.today())]) + + @no_debug_info_test + def test_command_source_relative_error(self): + """Test that 'command source -C' gives an error for a relative path""" + source_dir = self.getSourceDir() + result = lldb.SBCommandReturnObject() + self.runCmd("command source --stop-on-error 1 not-relative.txt") + self.check_results(failure=True) diff --git a/lldb/test/API/commands/command/source/commands2.txt b/lldb/test/API/commands/command/source/commands2.txt new file mode 100644 index 0000000..f0850b5 --- /dev/null +++ b/lldb/test/API/commands/command/source/commands2.txt @@ -0,0 +1 @@ +command source -C subdir/subcmds.txt diff --git a/lldb/test/API/commands/command/source/not-relative.txt b/lldb/test/API/commands/command/source/not-relative.txt new file mode 100644 index 0000000..ca90def --- /dev/null +++ b/lldb/test/API/commands/command/source/not-relative.txt @@ -0,0 +1,2 @@ +command source -C /tmp/somefile.txt +script import my diff --git a/lldb/test/API/commands/command/source/subdir/subcmds.txt b/lldb/test/API/commands/command/source/subdir/subcmds.txt new file mode 100644 index 0000000..c7e5933 --- /dev/null +++ b/lldb/test/API/commands/command/source/subdir/subcmds.txt @@ -0,0 +1 @@ +command source -C ../commands.txt -- 2.7.4