summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/lldb/source/Commands/CommandObjectSettings.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/llvm/lldb/source/Commands/CommandObjectSettings.cpp')
-rw-r--r--gnu/llvm/lldb/source/Commands/CommandObjectSettings.cpp1144
1 files changed, 1144 insertions, 0 deletions
diff --git a/gnu/llvm/lldb/source/Commands/CommandObjectSettings.cpp b/gnu/llvm/lldb/source/Commands/CommandObjectSettings.cpp
new file mode 100644
index 00000000000..95f79f45e22
--- /dev/null
+++ b/gnu/llvm/lldb/source/Commands/CommandObjectSettings.cpp
@@ -0,0 +1,1144 @@
+//===-- CommandObjectSettings.cpp -------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandObjectSettings.h"
+
+#include "llvm/ADT/StringRef.h"
+
+#include "lldb/Host/OptionParser.h"
+#include "lldb/Interpreter/CommandCompletions.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+// CommandObjectSettingsSet
+#define LLDB_OPTIONS_settings_set
+#include "CommandOptions.inc"
+
+class CommandObjectSettingsSet : public CommandObjectRaw {
+public:
+ CommandObjectSettingsSet(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "settings set",
+ "Set the value of the specified debugger setting."),
+ m_options() {
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentData var_name_arg;
+ CommandArgumentData value_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(var_name_arg);
+
+ // Define the first (and only) variant of this arg.
+ value_arg.arg_type = eArgTypeValue;
+ value_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg2.push_back(value_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+
+ SetHelpLong(
+ "\nWhen setting a dictionary or array variable, you can set multiple entries \
+at once by giving the values to the set command. For example:"
+ R"(
+
+(lldb) settings set target.run-args value1 value2 value3
+(lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345
+
+(lldb) settings show target.run-args
+ [0]: 'value1'
+ [1]: 'value2'
+ [3]: 'value3'
+(lldb) settings show target.env-vars
+ 'MYPATH=~/.:/usr/bin'
+ 'SOME_ENV_VAR=12345'
+
+)"
+ "Warning: The 'set' command re-sets the entire array or dictionary. If you \
+just want to add, remove or update individual values (or add something to \
+the end), use one of the other settings sub-commands: append, replace, \
+insert-before or insert-after.");
+ }
+
+ ~CommandObjectSettingsSet() override = default;
+
+ // Overrides base class's behavior where WantsCompletion =
+ // !WantsRawCommandString.
+ bool WantsCompletion() override { return true; }
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options(), m_global(false) {}
+
+ ~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 'f':
+ m_force = true;
+ break;
+ case 'g':
+ m_global = true;
+ break;
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_global = false;
+ m_force = false;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_settings_set_options);
+ }
+
+ // Instance variables to hold the values for command options.
+ bool m_global;
+ bool m_force;
+ };
+
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+
+ const size_t argc = request.GetParsedLine().GetArgumentCount();
+ const char *arg = nullptr;
+ size_t setting_var_idx;
+ for (setting_var_idx = 0; setting_var_idx < argc; ++setting_var_idx) {
+ arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
+ if (arg && arg[0] != '-')
+ break; // We found our setting variable name index
+ }
+ if (request.GetCursorIndex() == setting_var_idx) {
+ // Attempting to complete setting variable name
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
+ request, nullptr);
+ return;
+ }
+ arg = request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
+
+ if (!arg)
+ return;
+
+ // Complete option name
+ if (arg[0] != '-')
+ return;
+
+ // Complete setting value
+ const char *setting_var_name =
+ request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
+ Status error;
+ lldb::OptionValueSP value_sp(GetDebugger().GetPropertyValue(
+ &m_exe_ctx, setting_var_name, false, error));
+ if (!value_sp)
+ return;
+ value_sp->AutoComplete(m_interpreter, request);
+ }
+
+protected:
+ bool DoExecute(llvm::StringRef command,
+ CommandReturnObject &result) override {
+ Args cmd_args(command);
+
+ // Process possible options.
+ if (!ParseOptions(cmd_args, result))
+ return false;
+
+ const size_t min_argc = m_options.m_force ? 1 : 2;
+ const size_t argc = cmd_args.GetArgumentCount();
+
+ if ((argc < min_argc) && (!m_options.m_global)) {
+ result.AppendError("'settings set' takes more arguments");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ const char *var_name = cmd_args.GetArgumentAtIndex(0);
+ if ((var_name == nullptr) || (var_name[0] == '\0')) {
+ result.AppendError(
+ "'settings set' command requires a valid variable name");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ // A missing value corresponds to clearing the setting when "force" is
+ // specified.
+ if (argc == 1 && m_options.m_force) {
+ Status error(GetDebugger().SetPropertyValue(
+ &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ return result.Succeeded();
+ }
+
+ // Split the raw command into var_name and value pair.
+ llvm::StringRef var_value(command);
+ var_value = var_value.split(var_name).second.ltrim();
+
+ Status error;
+ if (m_options.m_global)
+ error = GetDebugger().SetPropertyValue(nullptr, eVarSetOperationAssign,
+ var_name, var_value);
+
+ if (error.Success()) {
+ // FIXME this is the same issue as the one in commands script import
+ // we could be setting target.load-script-from-symbol-file which would
+ // cause Python scripts to be loaded, which could run LLDB commands (e.g.
+ // settings set target.process.python-os-plugin-path) and cause a crash
+ // if we did not clear the command's exe_ctx first
+ ExecutionContext exe_ctx(m_exe_ctx);
+ m_exe_ctx.Clear();
+ error = GetDebugger().SetPropertyValue(&exe_ctx, eVarSetOperationAssign,
+ var_name, var_value);
+ }
+
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+
+ return result.Succeeded();
+ }
+
+private:
+ CommandOptions m_options;
+};
+
+// CommandObjectSettingsShow -- Show current values
+
+class CommandObjectSettingsShow : public CommandObjectParsed {
+public:
+ CommandObjectSettingsShow(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "settings show",
+ "Show matching debugger settings and their current "
+ "values. Defaults to showing all settings.",
+ nullptr) {
+ CommandArgumentEntry arg1;
+ CommandArgumentData var_name_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatOptional;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(var_name_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ }
+
+ ~CommandObjectSettingsShow() override = default;
+
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
+ request, nullptr);
+ }
+
+protected:
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+
+ if (!args.empty()) {
+ for (const auto &arg : args) {
+ Status error(GetDebugger().DumpPropertyValue(
+ &m_exe_ctx, result.GetOutputStream(), arg.ref(),
+ OptionValue::eDumpGroupValue));
+ if (error.Success()) {
+ result.GetOutputStream().EOL();
+ } else {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ }
+ } else {
+ GetDebugger().DumpAllPropertyValues(&m_exe_ctx, result.GetOutputStream(),
+ OptionValue::eDumpGroupValue);
+ }
+
+ return result.Succeeded();
+ }
+};
+
+// CommandObjectSettingsWrite -- Write settings to file
+#define LLDB_OPTIONS_settings_write
+#include "CommandOptions.inc"
+
+class CommandObjectSettingsWrite : public CommandObjectParsed {
+public:
+ CommandObjectSettingsWrite(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "settings export",
+ "Write matching debugger settings and their "
+ "current values to a file that can be read in with "
+ "\"settings read\". Defaults to writing all settings.",
+ nullptr),
+ m_options() {
+ CommandArgumentEntry arg1;
+ CommandArgumentData var_name_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatOptional;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(var_name_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ }
+
+ ~CommandObjectSettingsWrite() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+
+ ~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 'f':
+ m_filename.assign(option_arg);
+ break;
+ case 'a':
+ m_append = true;
+ break;
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_filename.clear();
+ m_append = false;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_settings_write_options);
+ }
+
+ // Instance variables to hold the values for command options.
+ std::string m_filename;
+ bool m_append = false;
+ };
+
+protected:
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ FileSpec file_spec(m_options.m_filename);
+ FileSystem::Instance().Resolve(file_spec);
+ std::string path(file_spec.GetPath());
+ auto options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
+ if (m_options.m_append)
+ options |= File::eOpenOptionAppend;
+ else
+ options |= File::eOpenOptionTruncate;
+
+ StreamFile out_file(path.c_str(), options,
+ lldb::eFilePermissionsFileDefault);
+
+ if (!out_file.GetFile().IsValid()) {
+ result.AppendErrorWithFormat("%s: unable to write to file", path.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ // Exporting should not be context sensitive.
+ ExecutionContext clean_ctx;
+
+ if (args.empty()) {
+ GetDebugger().DumpAllPropertyValues(&clean_ctx, out_file,
+ OptionValue::eDumpGroupExport);
+ return result.Succeeded();
+ }
+
+ for (const auto &arg : args) {
+ Status error(GetDebugger().DumpPropertyValue(
+ &clean_ctx, out_file, arg.ref(), OptionValue::eDumpGroupExport));
+ if (!error.Success()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ }
+
+ return result.Succeeded();
+ }
+
+private:
+ CommandOptions m_options;
+};
+
+// CommandObjectSettingsRead -- Read settings from file
+#define LLDB_OPTIONS_settings_read
+#include "CommandOptions.inc"
+
+class CommandObjectSettingsRead : public CommandObjectParsed {
+public:
+ CommandObjectSettingsRead(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "settings read",
+ "Read settings previously saved to a file with \"settings write\".",
+ nullptr),
+ m_options() {}
+
+ ~CommandObjectSettingsRead() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+
+ ~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 'f':
+ m_filename.assign(option_arg);
+ break;
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_filename.clear();
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_settings_read_options);
+ }
+
+ // Instance variables to hold the values for command options.
+ std::string m_filename;
+ };
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ FileSpec file(m_options.m_filename);
+ FileSystem::Instance().Resolve(file);
+ ExecutionContext clean_ctx;
+ CommandInterpreterRunOptions options;
+ options.SetAddToHistory(false);
+ options.SetEchoCommands(false);
+ options.SetPrintResults(true);
+ options.SetPrintErrors(true);
+ options.SetStopOnError(false);
+ m_interpreter.HandleCommandsFromFile(file, &clean_ctx, options, result);
+ return result.Succeeded();
+ }
+
+private:
+ CommandOptions m_options;
+};
+
+// CommandObjectSettingsList -- List settable variables
+
+class CommandObjectSettingsList : public CommandObjectParsed {
+public:
+ CommandObjectSettingsList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "settings list",
+ "List and describe matching debugger settings. "
+ "Defaults to all listing all settings.",
+ nullptr) {
+ CommandArgumentEntry arg;
+ CommandArgumentData var_name_arg;
+ CommandArgumentData prefix_name_arg;
+
+ // Define the first variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatOptional;
+
+ // Define the second variant of this arg.
+ prefix_name_arg.arg_type = eArgTypeSettingPrefix;
+ prefix_name_arg.arg_repetition = eArgRepeatOptional;
+
+ arg.push_back(var_name_arg);
+ arg.push_back(prefix_name_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectSettingsList() override = default;
+
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
+ request, nullptr);
+ }
+
+protected:
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+
+ const bool will_modify = false;
+ const size_t argc = args.GetArgumentCount();
+ if (argc > 0) {
+ const bool dump_qualified_name = true;
+
+ // TODO: Convert to StringRef based enumeration. Requires converting
+ // GetPropertyAtPath first.
+ for (size_t i = 0; i < argc; ++i) {
+ const char *property_path = args.GetArgumentAtIndex(i);
+
+ const Property *property =
+ GetDebugger().GetValueProperties()->GetPropertyAtPath(
+ &m_exe_ctx, will_modify, property_path);
+
+ if (property) {
+ property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
+ dump_qualified_name);
+ } else {
+ result.AppendErrorWithFormat("invalid property path '%s'",
+ property_path);
+ result.SetStatus(eReturnStatusFailed);
+ }
+ }
+ } else {
+ GetDebugger().DumpAllDescriptions(m_interpreter,
+ result.GetOutputStream());
+ }
+
+ return result.Succeeded();
+ }
+};
+
+// CommandObjectSettingsRemove
+
+class CommandObjectSettingsRemove : public CommandObjectRaw {
+public:
+ CommandObjectSettingsRemove(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "settings remove",
+ "Remove a value from a setting, specified by array "
+ "index or dictionary key.") {
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentData var_name_arg;
+ CommandArgumentData index_arg;
+ CommandArgumentData key_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(var_name_arg);
+
+ // Define the first variant of this arg.
+ index_arg.arg_type = eArgTypeSettingIndex;
+ index_arg.arg_repetition = eArgRepeatPlain;
+
+ // Define the second variant of this arg.
+ key_arg.arg_type = eArgTypeSettingKey;
+ key_arg.arg_repetition = eArgRepeatPlain;
+
+ // Push both variants into this arg
+ arg2.push_back(index_arg);
+ arg2.push_back(key_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+ }
+
+ ~CommandObjectSettingsRemove() override = default;
+
+ bool WantsCompletion() override { return true; }
+
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex() < 2)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
+ request, nullptr);
+ }
+
+protected:
+ bool DoExecute(llvm::StringRef command,
+ CommandReturnObject &result) override {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+
+ Args cmd_args(command);
+
+ // Process possible options.
+ if (!ParseOptions(cmd_args, result))
+ return false;
+
+ const size_t argc = cmd_args.GetArgumentCount();
+ if (argc == 0) {
+ result.AppendError("'settings remove' takes an array or dictionary item, "
+ "or an array followed by one or more indexes, or a "
+ "dictionary followed by one or more key names to "
+ "remove");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ const char *var_name = cmd_args.GetArgumentAtIndex(0);
+ if ((var_name == nullptr) || (var_name[0] == '\0')) {
+ result.AppendError(
+ "'settings remove' command requires a valid variable name");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ // Split the raw command into var_name and value pair.
+ llvm::StringRef var_value(command);
+ var_value = var_value.split(var_name).second.trim();
+
+ Status error(GetDebugger().SetPropertyValue(
+ &m_exe_ctx, eVarSetOperationRemove, var_name, var_value));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ return result.Succeeded();
+ }
+};
+
+// CommandObjectSettingsReplace
+
+class CommandObjectSettingsReplace : public CommandObjectRaw {
+public:
+ CommandObjectSettingsReplace(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "settings replace",
+ "Replace the debugger setting value specified by "
+ "array index or dictionary key.") {
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentEntry arg3;
+ CommandArgumentData var_name_arg;
+ CommandArgumentData index_arg;
+ CommandArgumentData key_arg;
+ CommandArgumentData value_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(var_name_arg);
+
+ // Define the first (variant of this arg.
+ index_arg.arg_type = eArgTypeSettingIndex;
+ index_arg.arg_repetition = eArgRepeatPlain;
+
+ // Define the second (variant of this arg.
+ key_arg.arg_type = eArgTypeSettingKey;
+ key_arg.arg_repetition = eArgRepeatPlain;
+
+ // Put both variants into this arg
+ arg2.push_back(index_arg);
+ arg2.push_back(key_arg);
+
+ // Define the first (and only) variant of this arg.
+ value_arg.arg_type = eArgTypeValue;
+ value_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg3.push_back(value_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+ m_arguments.push_back(arg3);
+ }
+
+ ~CommandObjectSettingsReplace() override = default;
+
+ // Overrides base class's behavior where WantsCompletion =
+ // !WantsRawCommandString.
+ bool WantsCompletion() override { return true; }
+
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ // Attempting to complete variable name
+ if (request.GetCursorIndex() < 2)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
+ request, nullptr);
+ }
+
+protected:
+ bool DoExecute(llvm::StringRef command,
+ CommandReturnObject &result) override {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+
+ Args cmd_args(command);
+ const char *var_name = cmd_args.GetArgumentAtIndex(0);
+ if ((var_name == nullptr) || (var_name[0] == '\0')) {
+ result.AppendError("'settings replace' command requires a valid variable "
+ "name; No value supplied");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ // Split the raw command into var_name, index_value, and value triple.
+ llvm::StringRef var_value(command);
+ var_value = var_value.split(var_name).second.trim();
+
+ Status error(GetDebugger().SetPropertyValue(
+ &m_exe_ctx, eVarSetOperationReplace, var_name, var_value));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
+
+ return result.Succeeded();
+ }
+};
+
+// CommandObjectSettingsInsertBefore
+
+class CommandObjectSettingsInsertBefore : public CommandObjectRaw {
+public:
+ CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "settings insert-before",
+ "Insert one or more values into an debugger array "
+ "setting immediately before the specified element "
+ "index.") {
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentEntry arg3;
+ CommandArgumentData var_name_arg;
+ CommandArgumentData index_arg;
+ CommandArgumentData value_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(var_name_arg);
+
+ // Define the first (variant of this arg.
+ index_arg.arg_type = eArgTypeSettingIndex;
+ index_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg2.push_back(index_arg);
+
+ // Define the first (and only) variant of this arg.
+ value_arg.arg_type = eArgTypeValue;
+ value_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg3.push_back(value_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+ m_arguments.push_back(arg3);
+ }
+
+ ~CommandObjectSettingsInsertBefore() override = default;
+
+ // Overrides base class's behavior where WantsCompletion =
+ // !WantsRawCommandString.
+ bool WantsCompletion() override { return true; }
+
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ // Attempting to complete variable name
+ if (request.GetCursorIndex() < 2)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
+ request, nullptr);
+ }
+
+protected:
+ bool DoExecute(llvm::StringRef command,
+ CommandReturnObject &result) override {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+
+ Args cmd_args(command);
+ const size_t argc = cmd_args.GetArgumentCount();
+
+ if (argc < 3) {
+ result.AppendError("'settings insert-before' takes more arguments");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ const char *var_name = cmd_args.GetArgumentAtIndex(0);
+ if ((var_name == nullptr) || (var_name[0] == '\0')) {
+ result.AppendError("'settings insert-before' command requires a valid "
+ "variable name; No value supplied");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ // Split the raw command into var_name, index_value, and value triple.
+ llvm::StringRef var_value(command);
+ var_value = var_value.split(var_name).second.trim();
+
+ Status error(GetDebugger().SetPropertyValue(
+ &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ return result.Succeeded();
+ }
+};
+
+// CommandObjectSettingInsertAfter
+
+class CommandObjectSettingsInsertAfter : public CommandObjectRaw {
+public:
+ CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "settings insert-after",
+ "Insert one or more values into a debugger array "
+ "settings after the specified element index.") {
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentEntry arg3;
+ CommandArgumentData var_name_arg;
+ CommandArgumentData index_arg;
+ CommandArgumentData value_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(var_name_arg);
+
+ // Define the first (variant of this arg.
+ index_arg.arg_type = eArgTypeSettingIndex;
+ index_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg2.push_back(index_arg);
+
+ // Define the first (and only) variant of this arg.
+ value_arg.arg_type = eArgTypeValue;
+ value_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg3.push_back(value_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+ m_arguments.push_back(arg3);
+ }
+
+ ~CommandObjectSettingsInsertAfter() override = default;
+
+ // Overrides base class's behavior where WantsCompletion =
+ // !WantsRawCommandString.
+ bool WantsCompletion() override { return true; }
+
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ // Attempting to complete variable name
+ if (request.GetCursorIndex() < 2)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
+ request, nullptr);
+ }
+
+protected:
+ bool DoExecute(llvm::StringRef command,
+ CommandReturnObject &result) override {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+
+ Args cmd_args(command);
+ const size_t argc = cmd_args.GetArgumentCount();
+
+ if (argc < 3) {
+ result.AppendError("'settings insert-after' takes more arguments");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ const char *var_name = cmd_args.GetArgumentAtIndex(0);
+ if ((var_name == nullptr) || (var_name[0] == '\0')) {
+ result.AppendError("'settings insert-after' command requires a valid "
+ "variable name; No value supplied");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ // Split the raw command into var_name, index_value, and value triple.
+ llvm::StringRef var_value(command);
+ var_value = var_value.split(var_name).second.trim();
+
+ Status error(GetDebugger().SetPropertyValue(
+ &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ return result.Succeeded();
+ }
+};
+
+// CommandObjectSettingsAppend
+
+class CommandObjectSettingsAppend : public CommandObjectRaw {
+public:
+ CommandObjectSettingsAppend(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "settings append",
+ "Append one or more values to a debugger array, "
+ "dictionary, or string setting.") {
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentData var_name_arg;
+ CommandArgumentData value_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(var_name_arg);
+
+ // Define the first (and only) variant of this arg.
+ value_arg.arg_type = eArgTypeValue;
+ value_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg2.push_back(value_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+ }
+
+ ~CommandObjectSettingsAppend() override = default;
+
+ // Overrides base class's behavior where WantsCompletion =
+ // !WantsRawCommandString.
+ bool WantsCompletion() override { return true; }
+
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ // Attempting to complete variable name
+ if (request.GetCursorIndex() < 2)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
+ request, nullptr);
+ }
+
+protected:
+ bool DoExecute(llvm::StringRef command,
+ CommandReturnObject &result) override {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ Args cmd_args(command);
+ const size_t argc = cmd_args.GetArgumentCount();
+
+ if (argc < 2) {
+ result.AppendError("'settings append' takes more arguments");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ const char *var_name = cmd_args.GetArgumentAtIndex(0);
+ if ((var_name == nullptr) || (var_name[0] == '\0')) {
+ result.AppendError("'settings append' command requires a valid variable "
+ "name; No value supplied");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
+ // character string later on.
+
+ // Split the raw command into var_name and value pair.
+ llvm::StringRef var_value(command);
+ var_value = var_value.split(var_name).second.trim();
+
+ Status error(GetDebugger().SetPropertyValue(
+ &m_exe_ctx, eVarSetOperationAppend, var_name, var_value));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ return result.Succeeded();
+ }
+};
+
+// CommandObjectSettingsClear
+
+class CommandObjectSettingsClear : public CommandObjectParsed {
+public:
+ CommandObjectSettingsClear(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "settings clear",
+ "Clear a debugger setting array, dictionary, or string.", nullptr) {
+ CommandArgumentEntry arg;
+ CommandArgumentData var_name_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(var_name_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectSettingsClear() override = default;
+
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ // Attempting to complete variable name
+ if (request.GetCursorIndex() < 2)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
+ request, nullptr);
+ }
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc != 1) {
+ result.AppendError("'settings clear' takes exactly one argument");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ const char *var_name = command.GetArgumentAtIndex(0);
+ if ((var_name == nullptr) || (var_name[0] == '\0')) {
+ result.AppendError("'settings clear' command requires a valid variable "
+ "name; No value supplied");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ Status error(GetDebugger().SetPropertyValue(
+ &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ return result.Succeeded();
+ }
+};
+
+// CommandObjectMultiwordSettings
+
+CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
+ CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "settings",
+ "Commands for managing LLDB settings.",
+ "settings <subcommand> [<command-options>]") {
+ LoadSubCommand("set",
+ CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
+ LoadSubCommand("show",
+ CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
+ LoadSubCommand("list",
+ CommandObjectSP(new CommandObjectSettingsList(interpreter)));
+ LoadSubCommand("remove",
+ CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
+ LoadSubCommand("replace", CommandObjectSP(
+ new CommandObjectSettingsReplace(interpreter)));
+ LoadSubCommand(
+ "insert-before",
+ CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
+ LoadSubCommand(
+ "insert-after",
+ CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
+ LoadSubCommand("append",
+ CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
+ LoadSubCommand("clear",
+ CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
+ LoadSubCommand("write",
+ CommandObjectSP(new CommandObjectSettingsWrite(interpreter)));
+ LoadSubCommand("read",
+ CommandObjectSP(new CommandObjectSettingsRead(interpreter)));
+}
+
+CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default;