llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: Med Ismail Bennani (medismailben) <details> <summary>Changes</summary> This patch introduces a new `template` multiword sub-command to the `scripting` top-level command. As the name suggests, this sub-command operates on scripting templates, and currently has the ability to automatically discover the various scripting extensions that lldb supports. Signed-off-by: Med Ismail Bennani <ismail@<!-- -->bennani.ma> --- Patch is 36.11 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/97273.diff 17 Files Affected: - (modified) lldb/include/lldb/Core/PluginManager.h (+25) - (modified) lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h (+7) - (modified) lldb/include/lldb/lldb-private-interfaces.h (+4) - (modified) lldb/source/Commands/CMakeLists.txt (+1-1) - (removed) lldb/source/Commands/CommandObjectScript.cpp (-113) - (removed) lldb/source/Commands/CommandObjectScript.h (-42) - (added) lldb/source/Commands/CommandObjectScripting.cpp (+290) - (added) lldb/source/Commands/CommandObjectScripting.h (+80) - (modified) lldb/source/Commands/Options.td (+8-2) - (modified) lldb/source/Core/PluginManager.cpp (+83) - (modified) lldb/source/Interpreter/CommandInterpreter.cpp (+7-2) - (modified) lldb/source/Plugins/CMakeLists.txt (+3) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/CMakeLists.txt (+5) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.cpp (+23) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedProcessPythonInterface.h (+12-1) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.cpp (+18) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedThreadPlanPythonInterface.h (+12-1) ``````````diff diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h index f2296e2920238..df20109e791a5 100644 --- a/lldb/include/lldb/Core/PluginManager.h +++ b/lldb/include/lldb/Core/PluginManager.h @@ -487,6 +487,31 @@ class PluginManager { static LanguageSet GetAllTypeSystemSupportedLanguagesForExpressions(); + // Scripted Interface + static bool + RegisterPlugin(llvm::StringRef name, llvm::StringRef description, + ScriptedInterfaceCreateInstance create_callback, + lldb::ScriptLanguage language, + std::vector<llvm::StringRef> command_interpreter_usages, + std::vector<llvm::StringRef> api_usages); + + static bool UnregisterPlugin(ScriptedInterfaceCreateInstance create_callback); + + static ScriptedInterfaceCreateInstance + GetScriptedInterfaceCreateCallbackAtIndex(uint32_t idx); + + static llvm::StringRef GetScriptedInterfaceNameAtIndex(uint32_t idx); + + static llvm::StringRef GetScriptedInterfaceDescriptionAtIndex(uint32_t idx); + + static lldb::ScriptLanguage GetScriptedInterfaceLanguageAtIndex(uint32_t idx); + + static std::vector<llvm::StringRef> + GetScriptedInterfaceCommandInterpreterUsagesAtIndex(uint32_t idx); + + static std::vector<llvm::StringRef> + GetScriptedInterfaceAPIUsagesAtIndex(uint32_t idx); + // REPL static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, REPLCreateInstance create_callback, diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h index 69504dbcda5dc..23658b90bb90a 100644 --- a/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h +++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedInterface.h @@ -68,6 +68,13 @@ class ScriptedInterface { return true; } + static bool + CreateInstance(lldb::ScriptLanguage language, + std::vector<llvm::StringRef> command_interpreter_usages, + std::vector<llvm::StringRef> api_usages) { + return false; + } + protected: StructuredData::GenericSP m_object_instance_sp; }; diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h index cdd9b51d9329c..2404e28158690 100644 --- a/lldb/include/lldb/lldb-private-interfaces.h +++ b/lldb/include/lldb/lldb-private-interfaces.h @@ -124,6 +124,10 @@ typedef lldb::REPLSP (*REPLCreateInstance)(Status &error, lldb::LanguageType language, Debugger *debugger, Target *target, const char *repl_options); +typedef bool (*ScriptedInterfaceCreateInstance)( + lldb::ScriptLanguage language, + std::vector<llvm::StringRef> command_interpreter_usages, + std::vector<llvm::StringRef> api_usages); typedef int (*ComparisonFunction)(const void *, const void *); typedef void (*DebuggerInitializeCallback)(Debugger &debugger); /// Trace 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..f03c93ed1ef9d --- /dev/null +++ b/lldb/source/Commands/CommandObjectScripting.cpp @@ -0,0 +1,290 @@ +//===-- 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/Core/PluginManager.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; + +#pragma mark CommandObjectScriptingExecute + +#define LLDB_OPTIONS_scripting_execute +#include "CommandOptions.inc" + +Status CommandObjectScriptingExecute::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 CommandObjectScriptingExecute::CommandOptions::OptionParsingStarting( + ExecutionContext *execution_context) { + language = lldb::eScriptLanguageNone; +} + +llvm::ArrayRef<OptionDefinition> +CommandObjectScriptingExecute::CommandOptions::GetDefinitions() { + return llvm::ArrayRef(g_scripting_execute_options); +} + +CommandObjectScriptingExecute::CommandObjectScriptingExecute( + CommandInterpreter &interpreter) + : CommandObjectRaw( + interpreter, "scripting execute", + "Invoke the script interpreter with provided code and display any " + "results. Start the interactive interpreter if no code is supplied.", + "scripting execute [--language <scripting-language> --] " + "[<script-code>]") {} + +CommandObjectScriptingExecute::~CommandObjectScriptingExecute() = default; + +void CommandObjectScriptingExecute::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); +} + +#pragma mark CommandObjectScriptingTemplateList + +#define LLDB_OPTIONS_scripting_template_list +#include "CommandOptions.inc" + +Status CommandObjectScriptingTemplateList::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 CommandObjectScriptingTemplateList::CommandOptions::OptionParsingStarting( + ExecutionContext *execution_context) { + language = lldb::eScriptLanguageNone; +} + +llvm::ArrayRef<OptionDefinition> +CommandObjectScriptingTemplateList::CommandOptions::GetDefinitions() { + return llvm::ArrayRef(g_scripting_execute_options); +} + +CommandObjectScriptingTemplateList::CommandObjectScriptingTemplateList( + CommandInterpreter &interpreter) + : CommandObjectParsed( + interpreter, "scripting template list", + "List all the available scripting affordances templates. ", + "scripting template list [--language <scripting-language> --]") {} + +CommandObjectScriptingTemplateList::~CommandObjectScriptingTemplateList() = + default; + +void CommandObjectScriptingTemplateList::DoExecute( + Args &command, CommandReturnObject &result) { + 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; + } + + Stream &s = result.GetOutputStream(); + s.Printf("Available scripted affordances:\n"); + + auto print_field = [&s](llvm::StringRef key, llvm::StringRef value, + bool check_validy = false) { + if (!check_validy || !value.empty()) { + s.IndentMore(); + s.Indent(); + s << key << ": " << value << '\n'; + s.IndentLess(); + } + }; + auto print_usages = [&s](llvm::StringRef usage_kind, + std::vector<llvm::StringRef> &usages) { + s.IndentMore(); + s.Indent(); + s << usage_kind << " Usages:"; + if (usages.empty()) + s << " No usages.\n"; + else if (usages.size() == 1) + s << " " << usages.front() << '\n'; + else { + s << '\n'; + for (llvm::StringRef usage : usages) { + s.IndentMore(); + s.Indent(); + s << usage << '\n'; + s.IndentLess(); + } + } + s.IndentLess(); + }; + + size_t i = 0; + for (llvm::StringRef plugin_name = + PluginManager::GetScriptedInterfaceNameAtIndex(i); + !plugin_name.empty();) { + + llvm::StringRef desc = + PluginManager::GetScriptedInterfaceDescriptionAtIndex(i); + lldb::ScriptLanguage lang = + PluginManager::GetScriptedInterfaceLanguageAtIndex(i); + std::vector<llvm::StringRef> ci_usages = + PluginManager::GetScriptedInterfaceCommandInterpreterUsagesAtIndex(i); + std::vector<llvm::StringRef> api_usages = + PluginManager::GetScriptedInterfaceAPIUsagesAtIndex(i); + + print_field("Name", plugin_name); + switch (lang) { + case eScriptLanguagePython: + print_field("Language", "Python"); + break; + case eScriptLanguageLua: + print_field("Language", "Lua"); + break; + default: + break; + } + print_field("Description", desc); + print_usages("Command Interpreter", ci_usages); + print_usages("API", api_usages); + + plugin_name = PluginManager::GetScriptedInterfaceNameAtIndex(++i); + if (!plugin_name.empty()) + s.EOL(); + } +} + +#pragma mark CommandObjectMultiwordScriptingTemplate + +// CommandObjectMultiwordScriptingTemplate + +CommandObjectMultiwordScriptingTemplate:: + CommandObjectMultiwordScriptingTemplate(CommandInterpreter &interpreter) + : CommandObjectMultiword( + interpreter, "scripting template", + "Commands for operating on the scripting templates.", + "scripting template [<subcommand-options>]") { + LoadSubCommand("list", CommandObjectSP(new CommandObjectScriptingTemplateList( + interpreter))); +} + +CommandObjectMultiwordScriptingTemplate:: + ~CommandObjectMultiwordScriptingTemplate() = default; + +#pragma mark CommandObjectMultiwordScripting + +// CommandObjectMultiwordScripting + +CommandObjectMultiwordScripting::CommandObjectMultiwordScripting( + CommandInterpreter &interpreter) + : CommandObjectMultiword( + interpreter, "scripting", + "Commands for operating on the scripting functionnalities.", + "scripting <subcommand> [<subcommand-options>]") { + LoadSubCommand("execute", CommandObjectSP(new CommandObjectScriptingExecute( + interpreter))); + LoadSubCommand("template", + CommandObjectSP( + new CommandObjectMultiwordScriptingTemplate(interpreter))); +} + +CommandObjectMultiwordScripting::~CommandObjectMultiwordScripting() = default; diff --git a/lldb/source/Commands/CommandObjectScripting.h b/lldb/source/Commands/CommandObjectScripting.h new file mode 100644 index 0000000000000..a9af6ee62e298 --- /dev/null +++ b/lldb/source/Commands/CommandObjectScripting.h @@ -0,0 +1,80 @@ +//===-- 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_INTE... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/97273 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits