https://github.com/medismailben updated https://github.com/llvm/llvm-project/pull/97263
>From b9eba8c81b342d038f0ca6cb40f2390225c3770f Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani <ism...@bennani.ma> Date: Mon, 1 Jul 2024 20:45:34 -0700 Subject: [PATCH] [lldb/Commands] Alias `script` command to `scripting run` This patch introduces a new top-level `scripting` command with an `run` sub-command, that basically replaces the `script` raw command. To avoid breaking the `script` command usages, this patch also adds an `script` alias to the `scripting run` sub-command. The reason behind this change is to have a top-level command that will cover scripting related subcommands. Signed-off-by: Med Ismail Bennani <ism...@bennani.ma> --- lldb/source/Commands/CMakeLists.txt | 2 +- lldb/source/Commands/CommandObjectScript.cpp | 113 -------------- lldb/source/Commands/CommandObjectScript.h | 42 ----- .../Commands/CommandObjectScripting.cpp | 144 ++++++++++++++++++ lldb/source/Commands/CommandObjectScripting.h | 25 +++ lldb/source/Commands/Options.td | 2 +- .../source/Interpreter/CommandInterpreter.cpp | 13 +- .../abbreviation/TestAbbreviations.py | 8 +- 8 files changed, 189 insertions(+), 160 deletions(-) delete mode 100644 lldb/source/Commands/CommandObjectScript.cpp delete mode 100644 lldb/source/Commands/CommandObjectScript.h create mode 100644 lldb/source/Commands/CommandObjectScripting.cpp create mode 100644 lldb/source/Commands/CommandObjectScripting.h diff --git a/lldb/source/Commands/CMakeLists.txt b/lldb/source/Commands/CMakeLists.txt index 6a36c5376d5c5..76397227d535d 100644 --- a/lldb/source/Commands/CMakeLists.txt +++ b/lldb/source/Commands/CMakeLists.txt @@ -26,7 +26,7 @@ add_lldb_library(lldbCommands NO_PLUGIN_DEPENDENCIES CommandObjectQuit.cpp CommandObjectRegexCommand.cpp CommandObjectRegister.cpp - CommandObjectScript.cpp + CommandObjectScripting.cpp CommandObjectSession.cpp CommandObjectSettings.cpp CommandObjectSource.cpp diff --git a/lldb/source/Commands/CommandObjectScript.cpp b/lldb/source/Commands/CommandObjectScript.cpp deleted file mode 100644 index 25f25b8e65947..0000000000000 --- a/lldb/source/Commands/CommandObjectScript.cpp +++ /dev/null @@ -1,113 +0,0 @@ -//===-- CommandObjectScript.cpp -------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "CommandObjectScript.h" -#include "lldb/Core/Debugger.h" -#include "lldb/DataFormatters/DataVisualization.h" -#include "lldb/Host/Config.h" -#include "lldb/Host/OptionParser.h" -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/CommandOptionArgumentTable.h" -#include "lldb/Interpreter/CommandReturnObject.h" -#include "lldb/Interpreter/OptionArgParser.h" -#include "lldb/Interpreter/ScriptInterpreter.h" -#include "lldb/Utility/Args.h" - -using namespace lldb; -using namespace lldb_private; - -#define LLDB_OPTIONS_script -#include "CommandOptions.inc" - -Status CommandObjectScript::CommandOptions::SetOptionValue( - uint32_t option_idx, llvm::StringRef option_arg, - ExecutionContext *execution_context) { - Status error; - const int short_option = m_getopt_table[option_idx].val; - - switch (short_option) { - case 'l': - language = (lldb::ScriptLanguage)OptionArgParser::ToOptionEnum( - option_arg, GetDefinitions()[option_idx].enum_values, - eScriptLanguageNone, error); - if (!error.Success()) - error.SetErrorStringWithFormat("unrecognized value for language '%s'", - option_arg.str().c_str()); - break; - default: - llvm_unreachable("Unimplemented option"); - } - - return error; -} - -void CommandObjectScript::CommandOptions::OptionParsingStarting( - ExecutionContext *execution_context) { - language = lldb::eScriptLanguageNone; -} - -llvm::ArrayRef<OptionDefinition> -CommandObjectScript::CommandOptions::GetDefinitions() { - return llvm::ArrayRef(g_script_options); -} - -CommandObjectScript::CommandObjectScript(CommandInterpreter &interpreter) - : CommandObjectRaw( - interpreter, "script", - "Invoke the script interpreter with provided code and display any " - "results. Start the interactive interpreter if no code is supplied.", - "script [--language <scripting-language> --] [<script-code>]") {} - -CommandObjectScript::~CommandObjectScript() = default; - -void CommandObjectScript::DoExecute(llvm::StringRef command, - CommandReturnObject &result) { - // Try parsing the language option but when the command contains a raw part - // separated by the -- delimiter. - OptionsWithRaw raw_args(command); - if (raw_args.HasArgs()) { - if (!ParseOptions(raw_args.GetArgs(), result)) - return; - command = raw_args.GetRawPart(); - } - - lldb::ScriptLanguage language = - (m_options.language == lldb::eScriptLanguageNone) - ? m_interpreter.GetDebugger().GetScriptLanguage() - : m_options.language; - - if (language == lldb::eScriptLanguageNone) { - result.AppendError( - "the script-lang setting is set to none - scripting not available"); - return; - } - - ScriptInterpreter *script_interpreter = - GetDebugger().GetScriptInterpreter(true, language); - - if (script_interpreter == nullptr) { - result.AppendError("no script interpreter"); - return; - } - - // Script might change Python code we use for formatting. Make sure we keep - // up to date with it. - DataVisualization::ForceUpdate(); - - if (command.empty()) { - script_interpreter->ExecuteInterpreterLoop(); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - return; - } - - // We can do better when reporting the status of one-liner script execution. - if (script_interpreter->ExecuteOneLine(command, &result)) - result.SetStatus(eReturnStatusSuccessFinishNoResult); - else - result.SetStatus(eReturnStatusFailed); -} diff --git a/lldb/source/Commands/CommandObjectScript.h b/lldb/source/Commands/CommandObjectScript.h deleted file mode 100644 index 3a8c4a890404a..0000000000000 --- a/lldb/source/Commands/CommandObjectScript.h +++ /dev/null @@ -1,42 +0,0 @@ -//===-- CommandObjectScript.h -----------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_SOURCE_INTERPRETER_COMMANDOBJECTSCRIPT_H -#define LLDB_SOURCE_INTERPRETER_COMMANDOBJECTSCRIPT_H - -#include "lldb/Interpreter/CommandObject.h" - -namespace lldb_private { - -class CommandObjectScript : public CommandObjectRaw { -public: - CommandObjectScript(CommandInterpreter &interpreter); - ~CommandObjectScript() override; - Options *GetOptions() override { return &m_options; } - - class CommandOptions : public Options { - public: - CommandOptions() = default; - ~CommandOptions() override = default; - Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, - ExecutionContext *execution_context) override; - void OptionParsingStarting(ExecutionContext *execution_context) override; - llvm::ArrayRef<OptionDefinition> GetDefinitions() override; - lldb::ScriptLanguage language = lldb::eScriptLanguageNone; - }; - -protected: - void DoExecute(llvm::StringRef command, CommandReturnObject &result) override; - -private: - CommandOptions m_options; -}; - -} // namespace lldb_private - -#endif // LLDB_SOURCE_INTERPRETER_COMMANDOBJECTSCRIPT_H diff --git a/lldb/source/Commands/CommandObjectScripting.cpp b/lldb/source/Commands/CommandObjectScripting.cpp new file mode 100644 index 0000000000000..fee0565a7c48a --- /dev/null +++ b/lldb/source/Commands/CommandObjectScripting.cpp @@ -0,0 +1,144 @@ +//===-- CommandObjectScripting.cpp ----------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CommandObjectScripting.h" +#include "lldb/Core/Debugger.h" +#include "lldb/DataFormatters/DataVisualization.h" +#include "lldb/Host/Config.h" +#include "lldb/Host/OptionParser.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandOptionArgumentTable.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Utility/Args.h" + +using namespace lldb; +using namespace lldb_private; + +#define LLDB_OPTIONS_scripting_run +#include "CommandOptions.inc" + +class CommandObjectScriptingRun : public CommandObjectRaw { +public: + CommandObjectScriptingRun(CommandInterpreter &interpreter) + : CommandObjectRaw( + interpreter, "scripting run", + "Invoke the script interpreter with provided code and display any " + "results. Start the interactive interpreter if no code is " + "supplied.", + "scripting run [--language <scripting-language> --] " + "[<script-code>]") {} + + ~CommandObjectScriptingRun() override = default; + + Options *GetOptions() override { return &m_options; } + + class CommandOptions : public Options { + public: + CommandOptions() = default; + ~CommandOptions() override = default; + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) override { + Status error; + const int short_option = m_getopt_table[option_idx].val; + + switch (short_option) { + case 'l': + language = (lldb::ScriptLanguage)OptionArgParser::ToOptionEnum( + option_arg, GetDefinitions()[option_idx].enum_values, + eScriptLanguageNone, error); + if (!error.Success()) + error.SetErrorStringWithFormat("unrecognized value for language '%s'", + option_arg.str().c_str()); + break; + default: + llvm_unreachable("Unimplemented option"); + } + + return error; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + language = lldb::eScriptLanguageNone; + } + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { + return llvm::ArrayRef(g_scripting_run_options); + } + + lldb::ScriptLanguage language = lldb::eScriptLanguageNone; + }; + +protected: + void DoExecute(llvm::StringRef command, + CommandReturnObject &result) override { + // Try parsing the language option but when the command contains a raw part + // separated by the -- delimiter. + OptionsWithRaw raw_args(command); + if (raw_args.HasArgs()) { + if (!ParseOptions(raw_args.GetArgs(), result)) + return; + command = raw_args.GetRawPart(); + } + + lldb::ScriptLanguage language = + (m_options.language == lldb::eScriptLanguageNone) + ? m_interpreter.GetDebugger().GetScriptLanguage() + : m_options.language; + + if (language == lldb::eScriptLanguageNone) { + result.AppendError( + "the script-lang setting is set to none - scripting not available"); + return; + } + + ScriptInterpreter *script_interpreter = + GetDebugger().GetScriptInterpreter(true, language); + + if (script_interpreter == nullptr) { + result.AppendError("no script interpreter"); + return; + } + + // Script might change Python code we use for formatting. Make sure we keep + // up to date with it. + DataVisualization::ForceUpdate(); + + if (command.empty()) { + script_interpreter->ExecuteInterpreterLoop(); + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return; + } + + // We can do better when reporting the status of one-liner script execution. + if (script_interpreter->ExecuteOneLine(command, &result)) + result.SetStatus(eReturnStatusSuccessFinishNoResult); + else + result.SetStatus(eReturnStatusFailed); + } + +private: + CommandOptions m_options; +}; + +#pragma mark CommandObjectMultiwordScripting + +// CommandObjectMultiwordScripting + +CommandObjectMultiwordScripting::CommandObjectMultiwordScripting( + CommandInterpreter &interpreter) + : CommandObjectMultiword( + interpreter, "scripting", + "Commands for operating on the scripting functionnalities.", + "scripting <subcommand> [<subcommand-options>]") { + LoadSubCommand("run", + CommandObjectSP(new CommandObjectScriptingRun(interpreter))); +} + +CommandObjectMultiwordScripting::~CommandObjectMultiwordScripting() = default; diff --git a/lldb/source/Commands/CommandObjectScripting.h b/lldb/source/Commands/CommandObjectScripting.h new file mode 100644 index 0000000000000..7558568dada5e --- /dev/null +++ b/lldb/source/Commands/CommandObjectScripting.h @@ -0,0 +1,25 @@ +//===-- CommandObjectScripting.h --------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_INTERPRETER_COMMANDOBJECTSCRIPT_H +#define LLDB_SOURCE_INTERPRETER_COMMANDOBJECTSCRIPT_H + +#include "lldb/Interpreter/CommandObjectMultiword.h" + +namespace lldb_private { + +class CommandObjectMultiwordScripting : public CommandObjectMultiword { +public: + CommandObjectMultiwordScripting(CommandInterpreter &interpreter); + + ~CommandObjectMultiwordScripting() override; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_INTERPRETER_COMMANDOBJECTSCRIPT_H diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index fa8af7cb3d762..24e97f3bb97d3 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -835,7 +835,7 @@ let Command = "container add" in { Desc<"Overwrite an existing command at this node.">; } -let Command = "script" in { +let Command = "scripting run" in { def script_language : Option<"language", "l">, EnumArg<"ScriptLang">, Desc<"Specify the scripting " " language. If none is specific the default scripting language is used.">; diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index 40c915b2c94fc..fc07168b6c0ac 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -33,7 +33,7 @@ #include "Commands/CommandObjectQuit.h" #include "Commands/CommandObjectRegexCommand.h" #include "Commands/CommandObjectRegister.h" -#include "Commands/CommandObjectScript.h" +#include "Commands/CommandObjectScripting.h" #include "Commands/CommandObjectSession.h" #include "Commands/CommandObjectSettings.h" #include "Commands/CommandObjectSource.h" @@ -518,6 +518,15 @@ void CommandInterpreter::Initialize() { AddAlias("re", cmd_obj_sp); } + cmd_obj_sp = GetCommandSPExact("scripting run"); + if (cmd_obj_sp) { + AddAlias("sc", cmd_obj_sp); + AddAlias("scr", cmd_obj_sp); + AddAlias("scri", cmd_obj_sp); + AddAlias("scrip", cmd_obj_sp); + AddAlias("script", cmd_obj_sp); + } + cmd_obj_sp = GetCommandSPExact("session history"); if (cmd_obj_sp) { AddAlias("history", cmd_obj_sp); @@ -569,7 +578,7 @@ void CommandInterpreter::LoadCommandDictionary() { REGISTER_COMMAND_OBJECT("process", CommandObjectMultiwordProcess); REGISTER_COMMAND_OBJECT("quit", CommandObjectQuit); REGISTER_COMMAND_OBJECT("register", CommandObjectRegister); - REGISTER_COMMAND_OBJECT("script", CommandObjectScript); + REGISTER_COMMAND_OBJECT("scripting", CommandObjectMultiwordScripting); REGISTER_COMMAND_OBJECT("settings", CommandObjectMultiwordSettings); REGISTER_COMMAND_OBJECT("session", CommandObjectSession); REGISTER_COMMAND_OBJECT("source", CommandObjectMultiwordSource); diff --git a/lldb/test/API/functionalities/abbreviation/TestAbbreviations.py b/lldb/test/API/functionalities/abbreviation/TestAbbreviations.py index 10431e41dc81a..02ee581da516d 100644 --- a/lldb/test/API/functionalities/abbreviation/TestAbbreviations.py +++ b/lldb/test/API/functionalities/abbreviation/TestAbbreviations.py @@ -80,7 +80,13 @@ def test_command_abbreviations_and_aliases(self): # Check a command that wants the raw input. command_interpreter.ResolveCommand(r"""sc print("\n\n\tHello!\n")""", result) self.assertTrue(result.Succeeded()) - self.assertEqual(r"""script print("\n\n\tHello!\n")""", result.GetOutput()) + self.assertEqual( + r"""scripting run print("\n\n\tHello!\n")""", result.GetOutput() + ) + + command_interpreter.ResolveCommand("script 1+1", result) + self.assertTrue(result.Succeeded()) + self.assertEqual("scripting run 1+1", result.GetOutput()) # Prompt changing stuff should be tested, but this doesn't seem like the # right test to do it in. It has nothing to do with aliases or abbreviations. _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits