================ @@ -46,12 +48,255 @@ class CommandObjectPluginLoad : public CommandObjectParsed { } }; +namespace { +// Helper function to perform an action on each matching plugin. +// The action callback is given the containing namespace along with plugin info +// for each matching plugin. +static int ActOnMatchingPlugins( + const llvm::StringRef pattern, + std::function<void(const PluginNamespace &plugin_namespace, + const std::vector<RegisteredPluginInfo> &plugin_info)> + action) { + int num_matching = 0; + + for (const PluginNamespace &plugin_namespace : + PluginManager::GetPluginNamespaces()) { + + std::vector<RegisteredPluginInfo> matching_plugins; + for (const RegisteredPluginInfo &plugin_info : + plugin_namespace.get_info()) { + if (PluginManager::MatchPluginName(pattern, plugin_namespace, + plugin_info)) + matching_plugins.push_back(plugin_info); + } + + if (!matching_plugins.empty()) { + num_matching += matching_plugins.size(); + action(plugin_namespace, matching_plugins); + } + } + + return num_matching; +} + +// Call the "SetEnable" function for each matching plugins. +// Used to share the majority of the code between the enable +// and disable commands. +int SetEnableOnMatchingPlugins(const llvm::StringRef &pattern, + CommandReturnObject &result, bool enabled) { + return ActOnMatchingPlugins( + pattern, [&](const PluginNamespace &plugin_namespace, + const std::vector<RegisteredPluginInfo> &plugins) { + result.AppendMessage(plugin_namespace.name); + for (const auto &plugin : plugins) { + if (!plugin_namespace.set_enabled(plugin.name, enabled)) { + result.AppendErrorWithFormat("failed to enable plugin %s.%s", + plugin_namespace.name.data(), + plugin.name.data()); + continue; + } + + result.AppendMessageWithFormat( + " %s %-30s %s\n", enabled ? "[+]" : "[-]", plugin.name.data(), + plugin.description.data()); + } + }); +} + +static std::string ConvertJSONToPrettyString(const llvm::json::Value &json) { + std::string str; + llvm::raw_string_ostream os(str); + os << llvm::formatv("{0:2}", json).str(); + os.flush(); + return str; +} + +#define LLDB_OPTIONS_plugin_list +#include "CommandOptions.inc" + +// These option definitions are used by the plugin list command. +class PluginListCommandOptions : public Options { +public: + PluginListCommandOptions() = default; + + ~PluginListCommandOptions() 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 'j': + m_json_format = true; + break; + default: + llvm_unreachable("Unimplemented option"); + } + + return error; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_json_format = false; + } + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { + return llvm::ArrayRef(g_plugin_list_options); + } + + // Instance variables to hold the values for command options. + bool m_json_format = false; +}; +} // namespace + +class CommandObjectPluginList : public CommandObjectParsed { +public: + CommandObjectPluginList(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "plugin list", + "Report info about registered LLDB plugins.", + nullptr) { + AddSimpleArgumentList(eArgTypeManagedPlugin); + SetHelpLong(R"( +Display information about registered plugins. +The plugin information is formatted as shown below: + + <plugin-namespace> + [+] <plugin-name> Plugin #1 description + [-] <plugin-name> Plugin #2 description + +An enabled plugin is marked with [+] and a disabled plugin is marked with [-]. + +Plugins can be listed by namespace and name with: + + plugin list <plugin-namespace>[.<plugin-name>] + +Plugins can be listed by namespace alone or with a fully qualified name. When listed +with just a namespace all plugins in that namespace are listed. When no arguments +are given all plugins are listed. + +Examples: +List all plugins + + (lldb) plugin list + +List all plugins in the system-runtime namespace + + (lldb) plugin list system-runtime + +List only the plugin 'foo' matching a fully qualified name exactly + + (lldb) plugin list system-runtime.foo +)"); + } + + ~CommandObjectPluginList() override = default; + + Options *GetOptions() override { return &m_options; } + +protected: + void DoExecute(Args &command, CommandReturnObject &result) override { + size_t argc = command.GetArgumentCount(); + if (argc > 1) { + result.AppendError("'plugin list' requires zero or one arguments"); + return; + } + llvm::StringRef pattern = argc ? command[0].ref() : ""; + result.SetStatus(eReturnStatusSuccessFinishResult); + + bool found_matching = false; + if (m_options.m_json_format) { + llvm::json::Object obj = PluginManager::GetJSON(pattern); + found_matching = obj.size() > 0; + if (found_matching) + result.AppendMessage(ConvertJSONToPrettyString(std::move(obj))); + } else { + int num_matching = ActOnMatchingPlugins( + pattern, [&](const PluginNamespace &plugin_namespace, + const std::vector<RegisteredPluginInfo> &plugins) { + result.AppendMessage(plugin_namespace.name); + for (auto &plugin : plugins) { + result.AppendMessageWithFormat( + " %s %-30s %s\n", plugin.enabled ? "[+]" : "[-]", + plugin.name.data(), plugin.description.data()); + } + }); + found_matching = num_matching > 0; + } + + if (!found_matching) + result.AppendErrorWithFormat("Found no matching plugins"); + } + + PluginListCommandOptions m_options; +}; + +class CommandObjectPluginEnable : public CommandObjectParsed { +public: + CommandObjectPluginEnable(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "plugin enable", + "Enable registered LLDB plugins.", nullptr) { + AddSimpleArgumentList(eArgTypeManagedPlugin); + } + + ~CommandObjectPluginEnable() override = default; + +protected: + void DoExecute(Args &command, CommandReturnObject &result) override { + size_t argc = command.GetArgumentCount(); + if (argc != 1) { + result.AppendError("'plugin enable' requires one argument"); ---------------- dmpots wrote:
Added support for multiple plugin names to the `list`, `enable`, and `disable` commands. https://github.com/llvm/llvm-project/pull/134418 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits