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;
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;
m_stop_on_error.Clear();
m_silent_run.Clear();
m_stop_on_continue.Clear();
+ m_cmd_relative_to_command_file.Clear();
}
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
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 {
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;
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 {
# 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)
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)
--- /dev/null
+command source -C subdir/subcmds.txt
--- /dev/null
+command source -C /tmp/somefile.txt
+script import my
--- /dev/null
+command source -C ../commands.txt