1cfca06d7SDimitry Andric //===-- CommandObjectSettings.cpp -----------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste
9f034231aSEd Maste #include "CommandObjectSettings.h"
10f034231aSEd Maste
11f3fbd1c0SDimitry Andric #include "llvm/ADT/StringRef.h"
12f3fbd1c0SDimitry Andric
1374a628f7SDimitry Andric #include "lldb/Host/OptionParser.h"
1414f1b3e8SDimitry Andric #include "lldb/Interpreter/CommandCompletions.h"
15f034231aSEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
164b4fe385SDimitry Andric #include "lldb/Interpreter/CommandOptionArgumentTable.h"
17f034231aSEd Maste #include "lldb/Interpreter/CommandReturnObject.h"
185e95aa85SEd Maste #include "lldb/Interpreter/OptionValueProperties.h"
19f034231aSEd Maste
20f034231aSEd Maste using namespace lldb;
21f034231aSEd Maste using namespace lldb_private;
22f034231aSEd Maste
23f034231aSEd Maste // CommandObjectSettingsSet
245f29bb8aSDimitry Andric #define LLDB_OPTIONS_settings_set
255f29bb8aSDimitry Andric #include "CommandOptions.inc"
2614f1b3e8SDimitry Andric
2714f1b3e8SDimitry Andric class CommandObjectSettingsSet : public CommandObjectRaw {
28f034231aSEd Maste public:
CommandObjectSettingsSet(CommandInterpreter & interpreter)29f3fbd1c0SDimitry Andric CommandObjectSettingsSet(CommandInterpreter &interpreter)
3014f1b3e8SDimitry Andric : CommandObjectRaw(interpreter, "settings set",
316f8fc217SDimitry Andric "Set the value of the specified debugger setting.") {
32f034231aSEd Maste CommandArgumentEntry arg1;
33f034231aSEd Maste CommandArgumentEntry arg2;
34f034231aSEd Maste CommandArgumentData var_name_arg;
35f034231aSEd Maste CommandArgumentData value_arg;
36f034231aSEd Maste
37f034231aSEd Maste // Define the first (and only) variant of this arg.
38f034231aSEd Maste var_name_arg.arg_type = eArgTypeSettingVariableName;
39f034231aSEd Maste var_name_arg.arg_repetition = eArgRepeatPlain;
40f034231aSEd Maste
4114f1b3e8SDimitry Andric // There is only one variant this argument could be; put it into the
4214f1b3e8SDimitry Andric // argument entry.
43f034231aSEd Maste arg1.push_back(var_name_arg);
44f034231aSEd Maste
45f034231aSEd Maste // Define the first (and only) variant of this arg.
46f034231aSEd Maste value_arg.arg_type = eArgTypeValue;
47f034231aSEd Maste value_arg.arg_repetition = eArgRepeatPlain;
48f034231aSEd Maste
4914f1b3e8SDimitry Andric // There is only one variant this argument could be; put it into the
5014f1b3e8SDimitry Andric // argument entry.
51f034231aSEd Maste arg2.push_back(value_arg);
52f034231aSEd Maste
53f034231aSEd Maste // Push the data for the first argument into the m_arguments vector.
54f034231aSEd Maste m_arguments.push_back(arg1);
55f034231aSEd Maste m_arguments.push_back(arg2);
56f034231aSEd Maste
57f034231aSEd Maste SetHelpLong(
58027f1c96SDimitry Andric "\nWhen setting a dictionary or array variable, you can set multiple entries \
5914f1b3e8SDimitry Andric at once by giving the values to the set command. For example:"
6014f1b3e8SDimitry Andric R"(
61027f1c96SDimitry Andric
62027f1c96SDimitry Andric (lldb) settings set target.run-args value1 value2 value3
63027f1c96SDimitry Andric (lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345
64027f1c96SDimitry Andric
65027f1c96SDimitry Andric (lldb) settings show target.run-args
66027f1c96SDimitry Andric [0]: 'value1'
67027f1c96SDimitry Andric [1]: 'value2'
68027f1c96SDimitry Andric [3]: 'value3'
69027f1c96SDimitry Andric (lldb) settings show target.env-vars
70027f1c96SDimitry Andric 'MYPATH=~/.:/usr/bin'
71027f1c96SDimitry Andric 'SOME_ENV_VAR=12345'
72027f1c96SDimitry Andric
7314f1b3e8SDimitry Andric )"
7414f1b3e8SDimitry Andric "Warning: The 'set' command re-sets the entire array or dictionary. If you \
75027f1c96SDimitry Andric just want to add, remove or update individual values (or add something to \
76027f1c96SDimitry Andric the end), use one of the other settings sub-commands: append, replace, \
7714f1b3e8SDimitry Andric insert-before or insert-after.");
78f034231aSEd Maste }
79f034231aSEd Maste
80f3fbd1c0SDimitry Andric ~CommandObjectSettingsSet() override = default;
81f034231aSEd Maste
8214f1b3e8SDimitry Andric // Overrides base class's behavior where WantsCompletion =
8314f1b3e8SDimitry Andric // !WantsRawCommandString.
WantsCompletion()8414f1b3e8SDimitry Andric bool WantsCompletion() override { return true; }
85f034231aSEd Maste
GetOptions()8614f1b3e8SDimitry Andric Options *GetOptions() override { return &m_options; }
87f034231aSEd Maste
8814f1b3e8SDimitry Andric class CommandOptions : public Options {
89f034231aSEd Maste public:
90145449b1SDimitry Andric CommandOptions() = default;
91f034231aSEd Maste
92f3fbd1c0SDimitry Andric ~CommandOptions() override = default;
93f034231aSEd Maste
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)94b76161e4SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
9514f1b3e8SDimitry Andric ExecutionContext *execution_context) override {
96b76161e4SDimitry Andric Status error;
97f034231aSEd Maste const int short_option = m_getopt_table[option_idx].val;
98f034231aSEd Maste
9914f1b3e8SDimitry Andric switch (short_option) {
10094994d37SDimitry Andric case 'f':
10194994d37SDimitry Andric m_force = true;
10294994d37SDimitry Andric break;
103f034231aSEd Maste case 'g':
104f034231aSEd Maste m_global = true;
105f034231aSEd Maste break;
106145449b1SDimitry Andric case 'e':
107145449b1SDimitry Andric m_exists = true;
108145449b1SDimitry Andric break;
109f034231aSEd Maste default:
110ead24645SDimitry Andric llvm_unreachable("Unimplemented option");
111f034231aSEd Maste }
112f034231aSEd Maste
113f034231aSEd Maste return error;
114f034231aSEd Maste }
115f034231aSEd Maste
OptionParsingStarting(ExecutionContext * execution_context)11614f1b3e8SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
117f034231aSEd Maste m_global = false;
11894994d37SDimitry Andric m_force = false;
119145449b1SDimitry Andric m_exists = false;
120f034231aSEd Maste }
121f034231aSEd Maste
GetDefinitions()12214f1b3e8SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
123e3b55780SDimitry Andric return llvm::ArrayRef(g_settings_set_options);
124f034231aSEd Maste }
125f034231aSEd Maste
126f034231aSEd Maste // Instance variables to hold the values for command options.
127344a3780SDimitry Andric bool m_global = false;
128145449b1SDimitry Andric bool m_force = false;
129145449b1SDimitry Andric bool m_exists = false;
130f034231aSEd Maste };
131f034231aSEd Maste
132ead24645SDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)133ead24645SDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
134f73363f1SDimitry Andric OptionElementVector &opt_element_vector) override {
135f034231aSEd Maste
136f73363f1SDimitry Andric const size_t argc = request.GetParsedLine().GetArgumentCount();
137f3fbd1c0SDimitry Andric const char *arg = nullptr;
138ead24645SDimitry Andric size_t setting_var_idx;
139ead24645SDimitry Andric for (setting_var_idx = 0; setting_var_idx < argc; ++setting_var_idx) {
140f73363f1SDimitry Andric arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
141f034231aSEd Maste if (arg && arg[0] != '-')
142f034231aSEd Maste break; // We found our setting variable name index
143f034231aSEd Maste }
144f73363f1SDimitry Andric if (request.GetCursorIndex() == setting_var_idx) {
145f034231aSEd Maste // Attempting to complete setting variable name
1467fa27ce4SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
1477fa27ce4SDimitry Andric GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
1487fa27ce4SDimitry Andric nullptr);
149ead24645SDimitry Andric return;
150ead24645SDimitry Andric }
151706b4fc4SDimitry Andric arg = request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
152f034231aSEd Maste
153ead24645SDimitry Andric if (!arg)
154ead24645SDimitry Andric return;
155ead24645SDimitry Andric
156f034231aSEd Maste // Complete option name
157e3b55780SDimitry Andric if (arg[0] == '-')
158ead24645SDimitry Andric return;
159ead24645SDimitry Andric
160f034231aSEd Maste // Complete setting value
16114f1b3e8SDimitry Andric const char *setting_var_name =
162f73363f1SDimitry Andric request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
163b76161e4SDimitry Andric Status error;
1647fa27ce4SDimitry Andric lldb::OptionValueSP value_sp(
1657fa27ce4SDimitry Andric GetDebugger().GetPropertyValue(&m_exe_ctx, setting_var_name, error));
166ead24645SDimitry Andric if (!value_sp)
167ead24645SDimitry Andric return;
168f73363f1SDimitry Andric value_sp->AutoComplete(m_interpreter, request);
169f034231aSEd Maste }
170f034231aSEd Maste
171f034231aSEd Maste protected:
DoExecute(llvm::StringRef command,CommandReturnObject & result)172b1c73532SDimitry Andric void DoExecute(llvm::StringRef command,
173f73363f1SDimitry Andric CommandReturnObject &result) override {
174f034231aSEd Maste Args cmd_args(command);
175f034231aSEd Maste
176f034231aSEd Maste // Process possible options.
177f034231aSEd Maste if (!ParseOptions(cmd_args, result))
178b1c73532SDimitry Andric return;
179f034231aSEd Maste
18094994d37SDimitry Andric const size_t min_argc = m_options.m_force ? 1 : 2;
181f034231aSEd Maste const size_t argc = cmd_args.GetArgumentCount();
18294994d37SDimitry Andric
18394994d37SDimitry Andric if ((argc < min_argc) && (!m_options.m_global)) {
184f034231aSEd Maste result.AppendError("'settings set' takes more arguments");
185b1c73532SDimitry Andric return;
186f034231aSEd Maste }
187f034231aSEd Maste
188f034231aSEd Maste const char *var_name = cmd_args.GetArgumentAtIndex(0);
18914f1b3e8SDimitry Andric if ((var_name == nullptr) || (var_name[0] == '\0')) {
19014f1b3e8SDimitry Andric result.AppendError(
19114f1b3e8SDimitry Andric "'settings set' command requires a valid variable name");
192b1c73532SDimitry Andric return;
193f034231aSEd Maste }
194f034231aSEd Maste
19594994d37SDimitry Andric // A missing value corresponds to clearing the setting when "force" is
19694994d37SDimitry Andric // specified.
19794994d37SDimitry Andric if (argc == 1 && m_options.m_force) {
1985f29bb8aSDimitry Andric Status error(GetDebugger().SetPropertyValue(
19994994d37SDimitry Andric &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
20094994d37SDimitry Andric if (error.Fail()) {
20194994d37SDimitry Andric result.AppendError(error.AsCString());
20294994d37SDimitry Andric }
203b1c73532SDimitry Andric return;
20494994d37SDimitry Andric }
20594994d37SDimitry Andric
206f034231aSEd Maste // Split the raw command into var_name and value pair.
207ead24645SDimitry Andric llvm::StringRef var_value(command);
208ead24645SDimitry Andric var_value = var_value.split(var_name).second.ltrim();
209f034231aSEd Maste
210b76161e4SDimitry Andric Status error;
211ead24645SDimitry Andric if (m_options.m_global)
2125f29bb8aSDimitry Andric error = GetDebugger().SetPropertyValue(nullptr, eVarSetOperationAssign,
213ead24645SDimitry Andric var_name, var_value);
214f034231aSEd Maste
21514f1b3e8SDimitry Andric if (error.Success()) {
216f034231aSEd Maste // FIXME this is the same issue as the one in commands script import
21714f1b3e8SDimitry Andric // we could be setting target.load-script-from-symbol-file which would
218f73363f1SDimitry Andric // cause Python scripts to be loaded, which could run LLDB commands (e.g.
219f73363f1SDimitry Andric // settings set target.process.python-os-plugin-path) and cause a crash
220f034231aSEd Maste // if we did not clear the command's exe_ctx first
221f034231aSEd Maste ExecutionContext exe_ctx(m_exe_ctx);
222f034231aSEd Maste m_exe_ctx.Clear();
2235f29bb8aSDimitry Andric error = GetDebugger().SetPropertyValue(&exe_ctx, eVarSetOperationAssign,
224ead24645SDimitry Andric var_name, var_value);
225f034231aSEd Maste }
226f034231aSEd Maste
227145449b1SDimitry Andric if (error.Fail() && !m_options.m_exists) {
228f034231aSEd Maste result.AppendError(error.AsCString());
229b1c73532SDimitry Andric return;
230f034231aSEd Maste }
231f034231aSEd Maste
232145449b1SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
233f034231aSEd Maste }
234f3fbd1c0SDimitry Andric
235f034231aSEd Maste private:
236f034231aSEd Maste CommandOptions m_options;
237f034231aSEd Maste };
238f034231aSEd Maste
239f034231aSEd Maste // CommandObjectSettingsShow -- Show current values
240f034231aSEd Maste
24114f1b3e8SDimitry Andric class CommandObjectSettingsShow : public CommandObjectParsed {
242f034231aSEd Maste public:
CommandObjectSettingsShow(CommandInterpreter & interpreter)243f3fbd1c0SDimitry Andric CommandObjectSettingsShow(CommandInterpreter &interpreter)
24414f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "settings show",
24514f1b3e8SDimitry Andric "Show matching debugger settings and their current "
24614f1b3e8SDimitry Andric "values. Defaults to showing all settings.",
24714f1b3e8SDimitry Andric nullptr) {
248ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeSettingVariableName, eArgRepeatOptional);
249f034231aSEd Maste }
250f034231aSEd Maste
251f3fbd1c0SDimitry Andric ~CommandObjectSettingsShow() override = default;
252f034231aSEd Maste
253f034231aSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)254b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
255f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
256f034231aSEd Maste
25714f1b3e8SDimitry Andric if (!args.empty()) {
25814f1b3e8SDimitry Andric for (const auto &arg : args) {
2595f29bb8aSDimitry Andric Status error(GetDebugger().DumpPropertyValue(
260ead24645SDimitry Andric &m_exe_ctx, result.GetOutputStream(), arg.ref(),
26114f1b3e8SDimitry Andric OptionValue::eDumpGroupValue));
26214f1b3e8SDimitry Andric if (error.Success()) {
263f034231aSEd Maste result.GetOutputStream().EOL();
26414f1b3e8SDimitry Andric } else {
265f034231aSEd Maste result.AppendError(error.AsCString());
266f034231aSEd Maste }
267f034231aSEd Maste }
26814f1b3e8SDimitry Andric } else {
2695f29bb8aSDimitry Andric GetDebugger().DumpAllPropertyValues(&m_exe_ctx, result.GetOutputStream(),
2705f29bb8aSDimitry Andric OptionValue::eDumpGroupValue);
271f034231aSEd Maste }
272f034231aSEd Maste }
273f034231aSEd Maste };
274f034231aSEd Maste
27594994d37SDimitry Andric // CommandObjectSettingsWrite -- Write settings to file
2765f29bb8aSDimitry Andric #define LLDB_OPTIONS_settings_write
2775f29bb8aSDimitry Andric #include "CommandOptions.inc"
27894994d37SDimitry Andric
27994994d37SDimitry Andric class CommandObjectSettingsWrite : public CommandObjectParsed {
28094994d37SDimitry Andric public:
CommandObjectSettingsWrite(CommandInterpreter & interpreter)28194994d37SDimitry Andric CommandObjectSettingsWrite(CommandInterpreter &interpreter)
28294994d37SDimitry Andric : CommandObjectParsed(
28394994d37SDimitry Andric interpreter, "settings export",
28494994d37SDimitry Andric "Write matching debugger settings and their "
28594994d37SDimitry Andric "current values to a file that can be read in with "
28694994d37SDimitry Andric "\"settings read\". Defaults to writing all settings.",
2876f8fc217SDimitry Andric nullptr) {
288ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeSettingVariableName, eArgRepeatOptional);
28994994d37SDimitry Andric }
29094994d37SDimitry Andric
29194994d37SDimitry Andric ~CommandObjectSettingsWrite() override = default;
29294994d37SDimitry Andric
GetOptions()29394994d37SDimitry Andric Options *GetOptions() override { return &m_options; }
29494994d37SDimitry Andric
29594994d37SDimitry Andric class CommandOptions : public Options {
29694994d37SDimitry Andric public:
297145449b1SDimitry Andric CommandOptions() = default;
29894994d37SDimitry Andric
29994994d37SDimitry Andric ~CommandOptions() override = default;
30094994d37SDimitry Andric
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)30194994d37SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
30294994d37SDimitry Andric ExecutionContext *execution_context) override {
30394994d37SDimitry Andric Status error;
30494994d37SDimitry Andric const int short_option = m_getopt_table[option_idx].val;
30594994d37SDimitry Andric
30694994d37SDimitry Andric switch (short_option) {
30794994d37SDimitry Andric case 'f':
308cfca06d7SDimitry Andric m_filename.assign(std::string(option_arg));
30994994d37SDimitry Andric break;
31094994d37SDimitry Andric case 'a':
31194994d37SDimitry Andric m_append = true;
31294994d37SDimitry Andric break;
31394994d37SDimitry Andric default:
314ead24645SDimitry Andric llvm_unreachable("Unimplemented option");
31594994d37SDimitry Andric }
31694994d37SDimitry Andric
31794994d37SDimitry Andric return error;
31894994d37SDimitry Andric }
31994994d37SDimitry Andric
OptionParsingStarting(ExecutionContext * execution_context)32094994d37SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
32194994d37SDimitry Andric m_filename.clear();
32294994d37SDimitry Andric m_append = false;
32394994d37SDimitry Andric }
32494994d37SDimitry Andric
GetDefinitions()32594994d37SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
326e3b55780SDimitry Andric return llvm::ArrayRef(g_settings_write_options);
32794994d37SDimitry Andric }
32894994d37SDimitry Andric
32994994d37SDimitry Andric // Instance variables to hold the values for command options.
33094994d37SDimitry Andric std::string m_filename;
33194994d37SDimitry Andric bool m_append = false;
33294994d37SDimitry Andric };
33394994d37SDimitry Andric
33494994d37SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)335b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
33694994d37SDimitry Andric FileSpec file_spec(m_options.m_filename);
33794994d37SDimitry Andric FileSystem::Instance().Resolve(file_spec);
33894994d37SDimitry Andric std::string path(file_spec.GetPath());
339c0981da4SDimitry Andric auto options = File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate;
34094994d37SDimitry Andric if (m_options.m_append)
341ead24645SDimitry Andric options |= File::eOpenOptionAppend;
34294994d37SDimitry Andric else
343ead24645SDimitry Andric options |= File::eOpenOptionTruncate;
34494994d37SDimitry Andric
34594994d37SDimitry Andric StreamFile out_file(path.c_str(), options,
34694994d37SDimitry Andric lldb::eFilePermissionsFileDefault);
34794994d37SDimitry Andric
34894994d37SDimitry Andric if (!out_file.GetFile().IsValid()) {
34994994d37SDimitry Andric result.AppendErrorWithFormat("%s: unable to write to file", path.c_str());
350b1c73532SDimitry Andric return;
35194994d37SDimitry Andric }
35294994d37SDimitry Andric
35394994d37SDimitry Andric // Exporting should not be context sensitive.
35494994d37SDimitry Andric ExecutionContext clean_ctx;
35594994d37SDimitry Andric
35694994d37SDimitry Andric if (args.empty()) {
3575f29bb8aSDimitry Andric GetDebugger().DumpAllPropertyValues(&clean_ctx, out_file,
3585f29bb8aSDimitry Andric OptionValue::eDumpGroupExport);
359b1c73532SDimitry Andric return;
36094994d37SDimitry Andric }
36194994d37SDimitry Andric
36294994d37SDimitry Andric for (const auto &arg : args) {
3635f29bb8aSDimitry Andric Status error(GetDebugger().DumpPropertyValue(
364ead24645SDimitry Andric &clean_ctx, out_file, arg.ref(), OptionValue::eDumpGroupExport));
36594994d37SDimitry Andric if (!error.Success()) {
36694994d37SDimitry Andric result.AppendError(error.AsCString());
36794994d37SDimitry Andric }
36894994d37SDimitry Andric }
36994994d37SDimitry Andric }
37094994d37SDimitry Andric
37194994d37SDimitry Andric private:
37294994d37SDimitry Andric CommandOptions m_options;
37394994d37SDimitry Andric };
37494994d37SDimitry Andric
37594994d37SDimitry Andric // CommandObjectSettingsRead -- Read settings from file
3765f29bb8aSDimitry Andric #define LLDB_OPTIONS_settings_read
3775f29bb8aSDimitry Andric #include "CommandOptions.inc"
37894994d37SDimitry Andric
37994994d37SDimitry Andric class CommandObjectSettingsRead : public CommandObjectParsed {
38094994d37SDimitry Andric public:
CommandObjectSettingsRead(CommandInterpreter & interpreter)38194994d37SDimitry Andric CommandObjectSettingsRead(CommandInterpreter &interpreter)
38294994d37SDimitry Andric : CommandObjectParsed(
38394994d37SDimitry Andric interpreter, "settings read",
38494994d37SDimitry Andric "Read settings previously saved to a file with \"settings write\".",
3856f8fc217SDimitry Andric nullptr) {}
38694994d37SDimitry Andric
38794994d37SDimitry Andric ~CommandObjectSettingsRead() override = default;
38894994d37SDimitry Andric
GetOptions()38994994d37SDimitry Andric Options *GetOptions() override { return &m_options; }
39094994d37SDimitry Andric
39194994d37SDimitry Andric class CommandOptions : public Options {
39294994d37SDimitry Andric public:
393145449b1SDimitry Andric CommandOptions() = default;
39494994d37SDimitry Andric
39594994d37SDimitry Andric ~CommandOptions() override = default;
39694994d37SDimitry Andric
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)39794994d37SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
39894994d37SDimitry Andric ExecutionContext *execution_context) override {
39994994d37SDimitry Andric Status error;
40094994d37SDimitry Andric const int short_option = m_getopt_table[option_idx].val;
40194994d37SDimitry Andric
40294994d37SDimitry Andric switch (short_option) {
40394994d37SDimitry Andric case 'f':
404cfca06d7SDimitry Andric m_filename.assign(std::string(option_arg));
40594994d37SDimitry Andric break;
40694994d37SDimitry Andric default:
407ead24645SDimitry Andric llvm_unreachable("Unimplemented option");
40894994d37SDimitry Andric }
40994994d37SDimitry Andric
41094994d37SDimitry Andric return error;
41194994d37SDimitry Andric }
41294994d37SDimitry Andric
OptionParsingStarting(ExecutionContext * execution_context)41394994d37SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
41494994d37SDimitry Andric m_filename.clear();
41594994d37SDimitry Andric }
41694994d37SDimitry Andric
GetDefinitions()41794994d37SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
418e3b55780SDimitry Andric return llvm::ArrayRef(g_settings_read_options);
41994994d37SDimitry Andric }
42094994d37SDimitry Andric
42194994d37SDimitry Andric // Instance variables to hold the values for command options.
42294994d37SDimitry Andric std::string m_filename;
42394994d37SDimitry Andric };
42494994d37SDimitry Andric
42594994d37SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)426b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
42794994d37SDimitry Andric FileSpec file(m_options.m_filename);
42894994d37SDimitry Andric FileSystem::Instance().Resolve(file);
42994994d37SDimitry Andric CommandInterpreterRunOptions options;
43094994d37SDimitry Andric options.SetAddToHistory(false);
43194994d37SDimitry Andric options.SetEchoCommands(false);
43294994d37SDimitry Andric options.SetPrintResults(true);
4335f29bb8aSDimitry Andric options.SetPrintErrors(true);
43494994d37SDimitry Andric options.SetStopOnError(false);
435344a3780SDimitry Andric m_interpreter.HandleCommandsFromFile(file, options, result);
43694994d37SDimitry Andric }
43794994d37SDimitry Andric
43894994d37SDimitry Andric private:
43994994d37SDimitry Andric CommandOptions m_options;
44094994d37SDimitry Andric };
44194994d37SDimitry Andric
442f034231aSEd Maste // CommandObjectSettingsList -- List settable variables
443f034231aSEd Maste
44414f1b3e8SDimitry Andric class CommandObjectSettingsList : public CommandObjectParsed {
445f034231aSEd Maste public:
CommandObjectSettingsList(CommandInterpreter & interpreter)446f3fbd1c0SDimitry Andric CommandObjectSettingsList(CommandInterpreter &interpreter)
447f3fbd1c0SDimitry Andric : CommandObjectParsed(interpreter, "settings list",
44814f1b3e8SDimitry Andric "List and describe matching debugger settings. "
44914f1b3e8SDimitry Andric "Defaults to all listing all settings.",
45014f1b3e8SDimitry Andric nullptr) {
451f034231aSEd Maste CommandArgumentEntry arg;
452f034231aSEd Maste CommandArgumentData var_name_arg;
453f034231aSEd Maste CommandArgumentData prefix_name_arg;
454f034231aSEd Maste
455f034231aSEd Maste // Define the first variant of this arg.
456f034231aSEd Maste var_name_arg.arg_type = eArgTypeSettingVariableName;
457f034231aSEd Maste var_name_arg.arg_repetition = eArgRepeatOptional;
458f034231aSEd Maste
459f034231aSEd Maste // Define the second variant of this arg.
460f034231aSEd Maste prefix_name_arg.arg_type = eArgTypeSettingPrefix;
461f034231aSEd Maste prefix_name_arg.arg_repetition = eArgRepeatOptional;
462f034231aSEd Maste
463f034231aSEd Maste arg.push_back(var_name_arg);
464f034231aSEd Maste arg.push_back(prefix_name_arg);
465f034231aSEd Maste
466f034231aSEd Maste // Push the data for the first argument into the m_arguments vector.
467f034231aSEd Maste m_arguments.push_back(arg);
468f034231aSEd Maste }
469f034231aSEd Maste
470f3fbd1c0SDimitry Andric ~CommandObjectSettingsList() override = default;
471f034231aSEd Maste
472ead24645SDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)473ead24645SDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
474f73363f1SDimitry Andric OptionElementVector &opt_element_vector) override {
4757fa27ce4SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
4767fa27ce4SDimitry Andric GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
4777fa27ce4SDimitry Andric nullptr);
478f034231aSEd Maste }
479f034231aSEd Maste
480f034231aSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)481b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
482f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
483f034231aSEd Maste
484f034231aSEd Maste const size_t argc = args.GetArgumentCount();
48514f1b3e8SDimitry Andric if (argc > 0) {
486f034231aSEd Maste const bool dump_qualified_name = true;
487f034231aSEd Maste
488cfca06d7SDimitry Andric for (const Args::ArgEntry &arg : args) {
489cfca06d7SDimitry Andric const char *property_path = arg.c_str();
490f034231aSEd Maste
49114f1b3e8SDimitry Andric const Property *property =
4925f29bb8aSDimitry Andric GetDebugger().GetValueProperties()->GetPropertyAtPath(
4937fa27ce4SDimitry Andric &m_exe_ctx, property_path);
494f034231aSEd Maste
49514f1b3e8SDimitry Andric if (property) {
49614f1b3e8SDimitry Andric property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
49714f1b3e8SDimitry Andric dump_qualified_name);
49814f1b3e8SDimitry Andric } else {
49914f1b3e8SDimitry Andric result.AppendErrorWithFormat("invalid property path '%s'",
50014f1b3e8SDimitry Andric property_path);
501f034231aSEd Maste }
502f034231aSEd Maste }
50314f1b3e8SDimitry Andric } else {
5045f29bb8aSDimitry Andric GetDebugger().DumpAllDescriptions(m_interpreter,
50514f1b3e8SDimitry Andric result.GetOutputStream());
506f034231aSEd Maste }
507f034231aSEd Maste }
508f034231aSEd Maste };
509f034231aSEd Maste
510f034231aSEd Maste // CommandObjectSettingsRemove
511f034231aSEd Maste
51214f1b3e8SDimitry Andric class CommandObjectSettingsRemove : public CommandObjectRaw {
513f034231aSEd Maste public:
CommandObjectSettingsRemove(CommandInterpreter & interpreter)514f3fbd1c0SDimitry Andric CommandObjectSettingsRemove(CommandInterpreter &interpreter)
515f3fbd1c0SDimitry Andric : CommandObjectRaw(interpreter, "settings remove",
51614f1b3e8SDimitry Andric "Remove a value from a setting, specified by array "
51714f1b3e8SDimitry Andric "index or dictionary key.") {
518f034231aSEd Maste CommandArgumentEntry arg1;
519f034231aSEd Maste CommandArgumentEntry arg2;
520f034231aSEd Maste CommandArgumentData var_name_arg;
521f034231aSEd Maste CommandArgumentData index_arg;
522f034231aSEd Maste CommandArgumentData key_arg;
523f034231aSEd Maste
524f034231aSEd Maste // Define the first (and only) variant of this arg.
525f034231aSEd Maste var_name_arg.arg_type = eArgTypeSettingVariableName;
526f034231aSEd Maste var_name_arg.arg_repetition = eArgRepeatPlain;
527f034231aSEd Maste
52814f1b3e8SDimitry Andric // There is only one variant this argument could be; put it into the
52914f1b3e8SDimitry Andric // argument entry.
530f034231aSEd Maste arg1.push_back(var_name_arg);
531f034231aSEd Maste
532f034231aSEd Maste // Define the first variant of this arg.
533f034231aSEd Maste index_arg.arg_type = eArgTypeSettingIndex;
534f034231aSEd Maste index_arg.arg_repetition = eArgRepeatPlain;
535f034231aSEd Maste
536f034231aSEd Maste // Define the second variant of this arg.
537f034231aSEd Maste key_arg.arg_type = eArgTypeSettingKey;
538f034231aSEd Maste key_arg.arg_repetition = eArgRepeatPlain;
539f034231aSEd Maste
540f034231aSEd Maste // Push both variants into this arg
541f034231aSEd Maste arg2.push_back(index_arg);
542f034231aSEd Maste arg2.push_back(key_arg);
543f034231aSEd Maste
544f034231aSEd Maste // Push the data for the first argument into the m_arguments vector.
545f034231aSEd Maste m_arguments.push_back(arg1);
546f034231aSEd Maste m_arguments.push_back(arg2);
547f034231aSEd Maste }
548f034231aSEd Maste
549f3fbd1c0SDimitry Andric ~CommandObjectSettingsRemove() override = default;
550f034231aSEd Maste
WantsCompletion()551ead24645SDimitry Andric bool WantsCompletion() override { return true; }
552ead24645SDimitry Andric
553ead24645SDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)554ead24645SDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
555f73363f1SDimitry Andric OptionElementVector &opt_element_vector) override {
556f73363f1SDimitry Andric if (request.GetCursorIndex() < 2)
5577fa27ce4SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
5587fa27ce4SDimitry Andric GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
5597fa27ce4SDimitry Andric nullptr);
560f034231aSEd Maste }
561f034231aSEd Maste
562f034231aSEd Maste protected:
DoExecute(llvm::StringRef command,CommandReturnObject & result)563b1c73532SDimitry Andric void DoExecute(llvm::StringRef command,
564f73363f1SDimitry Andric CommandReturnObject &result) override {
565f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
566f034231aSEd Maste
567f034231aSEd Maste Args cmd_args(command);
568f034231aSEd Maste
569f034231aSEd Maste // Process possible options.
570f034231aSEd Maste if (!ParseOptions(cmd_args, result))
571b1c73532SDimitry Andric return;
572f034231aSEd Maste
573f034231aSEd Maste const size_t argc = cmd_args.GetArgumentCount();
57414f1b3e8SDimitry Andric if (argc == 0) {
575ead24645SDimitry Andric result.AppendError("'settings remove' takes an array or dictionary item, "
576ead24645SDimitry Andric "or an array followed by one or more indexes, or a "
57714f1b3e8SDimitry Andric "dictionary followed by one or more key names to "
57814f1b3e8SDimitry Andric "remove");
579b1c73532SDimitry Andric return;
580f034231aSEd Maste }
581f034231aSEd Maste
582f034231aSEd Maste const char *var_name = cmd_args.GetArgumentAtIndex(0);
58314f1b3e8SDimitry Andric if ((var_name == nullptr) || (var_name[0] == '\0')) {
58414f1b3e8SDimitry Andric result.AppendError(
585ead24645SDimitry Andric "'settings remove' command requires a valid variable name");
586b1c73532SDimitry Andric return;
587f034231aSEd Maste }
588f034231aSEd Maste
589f034231aSEd Maste // Split the raw command into var_name and value pair.
590ead24645SDimitry Andric llvm::StringRef var_value(command);
591ead24645SDimitry Andric var_value = var_value.split(var_name).second.trim();
592f034231aSEd Maste
5935f29bb8aSDimitry Andric Status error(GetDebugger().SetPropertyValue(
594ead24645SDimitry Andric &m_exe_ctx, eVarSetOperationRemove, var_name, var_value));
59514f1b3e8SDimitry Andric if (error.Fail()) {
596f034231aSEd Maste result.AppendError(error.AsCString());
597f034231aSEd Maste }
598f034231aSEd Maste }
599f034231aSEd Maste };
600f034231aSEd Maste
601f034231aSEd Maste // CommandObjectSettingsReplace
602f034231aSEd Maste
60314f1b3e8SDimitry Andric class CommandObjectSettingsReplace : public CommandObjectRaw {
604f034231aSEd Maste public:
CommandObjectSettingsReplace(CommandInterpreter & interpreter)605f3fbd1c0SDimitry Andric CommandObjectSettingsReplace(CommandInterpreter &interpreter)
606f3fbd1c0SDimitry Andric : CommandObjectRaw(interpreter, "settings replace",
60714f1b3e8SDimitry Andric "Replace the debugger setting value specified by "
60814f1b3e8SDimitry Andric "array index or dictionary key.") {
609f034231aSEd Maste CommandArgumentEntry arg1;
610f034231aSEd Maste CommandArgumentEntry arg2;
611f034231aSEd Maste CommandArgumentEntry arg3;
612f034231aSEd Maste CommandArgumentData var_name_arg;
613f034231aSEd Maste CommandArgumentData index_arg;
614f034231aSEd Maste CommandArgumentData key_arg;
615f034231aSEd Maste CommandArgumentData value_arg;
616f034231aSEd Maste
617f034231aSEd Maste // Define the first (and only) variant of this arg.
618f034231aSEd Maste var_name_arg.arg_type = eArgTypeSettingVariableName;
619f034231aSEd Maste var_name_arg.arg_repetition = eArgRepeatPlain;
620f034231aSEd Maste
62114f1b3e8SDimitry Andric // There is only one variant this argument could be; put it into the
62214f1b3e8SDimitry Andric // argument entry.
623f034231aSEd Maste arg1.push_back(var_name_arg);
624f034231aSEd Maste
625f034231aSEd Maste // Define the first (variant of this arg.
626f034231aSEd Maste index_arg.arg_type = eArgTypeSettingIndex;
627f034231aSEd Maste index_arg.arg_repetition = eArgRepeatPlain;
628f034231aSEd Maste
629f034231aSEd Maste // Define the second (variant of this arg.
630f034231aSEd Maste key_arg.arg_type = eArgTypeSettingKey;
631f034231aSEd Maste key_arg.arg_repetition = eArgRepeatPlain;
632f034231aSEd Maste
633f034231aSEd Maste // Put both variants into this arg
634f034231aSEd Maste arg2.push_back(index_arg);
635f034231aSEd Maste arg2.push_back(key_arg);
636f034231aSEd Maste
637f034231aSEd Maste // Define the first (and only) variant of this arg.
638f034231aSEd Maste value_arg.arg_type = eArgTypeValue;
639f034231aSEd Maste value_arg.arg_repetition = eArgRepeatPlain;
640f034231aSEd Maste
64114f1b3e8SDimitry Andric // There is only one variant this argument could be; put it into the
64214f1b3e8SDimitry Andric // argument entry.
643f034231aSEd Maste arg3.push_back(value_arg);
644f034231aSEd Maste
645f034231aSEd Maste // Push the data for the first argument into the m_arguments vector.
646f034231aSEd Maste m_arguments.push_back(arg1);
647f034231aSEd Maste m_arguments.push_back(arg2);
648f034231aSEd Maste m_arguments.push_back(arg3);
649f034231aSEd Maste }
650f034231aSEd Maste
651f3fbd1c0SDimitry Andric ~CommandObjectSettingsReplace() override = default;
652f034231aSEd Maste
65314f1b3e8SDimitry Andric // Overrides base class's behavior where WantsCompletion =
65414f1b3e8SDimitry Andric // !WantsRawCommandString.
WantsCompletion()65514f1b3e8SDimitry Andric bool WantsCompletion() override { return true; }
656f034231aSEd Maste
657ead24645SDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)658ead24645SDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
659f73363f1SDimitry Andric OptionElementVector &opt_element_vector) override {
660f034231aSEd Maste // Attempting to complete variable name
661f73363f1SDimitry Andric if (request.GetCursorIndex() < 2)
6627fa27ce4SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
6637fa27ce4SDimitry Andric GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
6647fa27ce4SDimitry Andric nullptr);
665f034231aSEd Maste }
666f034231aSEd Maste
667f034231aSEd Maste protected:
DoExecute(llvm::StringRef command,CommandReturnObject & result)668b1c73532SDimitry Andric void DoExecute(llvm::StringRef command,
669f73363f1SDimitry Andric CommandReturnObject &result) override {
670f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
671f034231aSEd Maste
672f034231aSEd Maste Args cmd_args(command);
673f034231aSEd Maste const char *var_name = cmd_args.GetArgumentAtIndex(0);
67414f1b3e8SDimitry Andric if ((var_name == nullptr) || (var_name[0] == '\0')) {
67514f1b3e8SDimitry Andric result.AppendError("'settings replace' command requires a valid variable "
67614f1b3e8SDimitry Andric "name; No value supplied");
677b1c73532SDimitry Andric return;
678f034231aSEd Maste }
679f034231aSEd Maste
680f034231aSEd Maste // Split the raw command into var_name, index_value, and value triple.
681ead24645SDimitry Andric llvm::StringRef var_value(command);
682ead24645SDimitry Andric var_value = var_value.split(var_name).second.trim();
683f034231aSEd Maste
6845f29bb8aSDimitry Andric Status error(GetDebugger().SetPropertyValue(
685ead24645SDimitry Andric &m_exe_ctx, eVarSetOperationReplace, var_name, var_value));
68614f1b3e8SDimitry Andric if (error.Fail()) {
687f034231aSEd Maste result.AppendError(error.AsCString());
68814f1b3e8SDimitry Andric } else {
689f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
690f034231aSEd Maste }
691f034231aSEd Maste }
692f034231aSEd Maste };
693f034231aSEd Maste
694f034231aSEd Maste // CommandObjectSettingsInsertBefore
695f034231aSEd Maste
69614f1b3e8SDimitry Andric class CommandObjectSettingsInsertBefore : public CommandObjectRaw {
697f034231aSEd Maste public:
CommandObjectSettingsInsertBefore(CommandInterpreter & interpreter)698f3fbd1c0SDimitry Andric CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
69914f1b3e8SDimitry Andric : CommandObjectRaw(interpreter, "settings insert-before",
70014f1b3e8SDimitry Andric "Insert one or more values into an debugger array "
701f3fbd1c0SDimitry Andric "setting immediately before the specified element "
70214f1b3e8SDimitry Andric "index.") {
703f034231aSEd Maste CommandArgumentEntry arg1;
704f034231aSEd Maste CommandArgumentEntry arg2;
705f034231aSEd Maste CommandArgumentEntry arg3;
706f034231aSEd Maste CommandArgumentData var_name_arg;
707f034231aSEd Maste CommandArgumentData index_arg;
708f034231aSEd Maste CommandArgumentData value_arg;
709f034231aSEd Maste
710f034231aSEd Maste // Define the first (and only) variant of this arg.
711f034231aSEd Maste var_name_arg.arg_type = eArgTypeSettingVariableName;
712f034231aSEd Maste var_name_arg.arg_repetition = eArgRepeatPlain;
713f034231aSEd Maste
71414f1b3e8SDimitry Andric // There is only one variant this argument could be; put it into the
71514f1b3e8SDimitry Andric // argument entry.
716f034231aSEd Maste arg1.push_back(var_name_arg);
717f034231aSEd Maste
718f034231aSEd Maste // Define the first (variant of this arg.
719f034231aSEd Maste index_arg.arg_type = eArgTypeSettingIndex;
720f034231aSEd Maste index_arg.arg_repetition = eArgRepeatPlain;
721f034231aSEd Maste
72214f1b3e8SDimitry Andric // There is only one variant this argument could be; put it into the
72314f1b3e8SDimitry Andric // argument entry.
724f034231aSEd Maste arg2.push_back(index_arg);
725f034231aSEd Maste
726f034231aSEd Maste // Define the first (and only) variant of this arg.
727f034231aSEd Maste value_arg.arg_type = eArgTypeValue;
728f034231aSEd Maste value_arg.arg_repetition = eArgRepeatPlain;
729f034231aSEd Maste
73014f1b3e8SDimitry Andric // There is only one variant this argument could be; put it into the
73114f1b3e8SDimitry Andric // argument entry.
732f034231aSEd Maste arg3.push_back(value_arg);
733f034231aSEd Maste
734f034231aSEd Maste // Push the data for the first argument into the m_arguments vector.
735f034231aSEd Maste m_arguments.push_back(arg1);
736f034231aSEd Maste m_arguments.push_back(arg2);
737f034231aSEd Maste m_arguments.push_back(arg3);
738f034231aSEd Maste }
739f034231aSEd Maste
740f3fbd1c0SDimitry Andric ~CommandObjectSettingsInsertBefore() override = default;
741f034231aSEd Maste
74214f1b3e8SDimitry Andric // Overrides base class's behavior where WantsCompletion =
74314f1b3e8SDimitry Andric // !WantsRawCommandString.
WantsCompletion()74414f1b3e8SDimitry Andric bool WantsCompletion() override { return true; }
745f034231aSEd Maste
746ead24645SDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)747ead24645SDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
748f73363f1SDimitry Andric OptionElementVector &opt_element_vector) override {
749f034231aSEd Maste // Attempting to complete variable name
750f73363f1SDimitry Andric if (request.GetCursorIndex() < 2)
7517fa27ce4SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
7527fa27ce4SDimitry Andric GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
7537fa27ce4SDimitry Andric nullptr);
754f034231aSEd Maste }
755f034231aSEd Maste
756f034231aSEd Maste protected:
DoExecute(llvm::StringRef command,CommandReturnObject & result)757b1c73532SDimitry Andric void DoExecute(llvm::StringRef command,
758f73363f1SDimitry Andric CommandReturnObject &result) override {
759f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
760f034231aSEd Maste
761f034231aSEd Maste Args cmd_args(command);
762f034231aSEd Maste const size_t argc = cmd_args.GetArgumentCount();
763f034231aSEd Maste
76414f1b3e8SDimitry Andric if (argc < 3) {
765f034231aSEd Maste result.AppendError("'settings insert-before' takes more arguments");
766b1c73532SDimitry Andric return;
767f034231aSEd Maste }
768f034231aSEd Maste
769f034231aSEd Maste const char *var_name = cmd_args.GetArgumentAtIndex(0);
77014f1b3e8SDimitry Andric if ((var_name == nullptr) || (var_name[0] == '\0')) {
77114f1b3e8SDimitry Andric result.AppendError("'settings insert-before' command requires a valid "
77214f1b3e8SDimitry Andric "variable name; No value supplied");
773b1c73532SDimitry Andric return;
774f034231aSEd Maste }
775f034231aSEd Maste
776f034231aSEd Maste // Split the raw command into var_name, index_value, and value triple.
777ead24645SDimitry Andric llvm::StringRef var_value(command);
778ead24645SDimitry Andric var_value = var_value.split(var_name).second.trim();
779f034231aSEd Maste
7805f29bb8aSDimitry Andric Status error(GetDebugger().SetPropertyValue(
781ead24645SDimitry Andric &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value));
78214f1b3e8SDimitry Andric if (error.Fail()) {
783f034231aSEd Maste result.AppendError(error.AsCString());
784f034231aSEd Maste }
785f034231aSEd Maste }
786f034231aSEd Maste };
787f034231aSEd Maste
788f034231aSEd Maste // CommandObjectSettingInsertAfter
789f034231aSEd Maste
79014f1b3e8SDimitry Andric class CommandObjectSettingsInsertAfter : public CommandObjectRaw {
791f034231aSEd Maste public:
CommandObjectSettingsInsertAfter(CommandInterpreter & interpreter)792f3fbd1c0SDimitry Andric CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
79314f1b3e8SDimitry Andric : CommandObjectRaw(interpreter, "settings insert-after",
79414f1b3e8SDimitry Andric "Insert one or more values into a debugger array "
79514f1b3e8SDimitry Andric "settings after the specified element index.") {
796f034231aSEd Maste CommandArgumentEntry arg1;
797f034231aSEd Maste CommandArgumentEntry arg2;
798f034231aSEd Maste CommandArgumentEntry arg3;
799f034231aSEd Maste CommandArgumentData var_name_arg;
800f034231aSEd Maste CommandArgumentData index_arg;
801f034231aSEd Maste CommandArgumentData value_arg;
802f034231aSEd Maste
803f034231aSEd Maste // Define the first (and only) variant of this arg.
804f034231aSEd Maste var_name_arg.arg_type = eArgTypeSettingVariableName;
805f034231aSEd Maste var_name_arg.arg_repetition = eArgRepeatPlain;
806f034231aSEd Maste
80714f1b3e8SDimitry Andric // There is only one variant this argument could be; put it into the
80814f1b3e8SDimitry Andric // argument entry.
809f034231aSEd Maste arg1.push_back(var_name_arg);
810f034231aSEd Maste
811f034231aSEd Maste // Define the first (variant of this arg.
812f034231aSEd Maste index_arg.arg_type = eArgTypeSettingIndex;
813f034231aSEd Maste index_arg.arg_repetition = eArgRepeatPlain;
814f034231aSEd Maste
81514f1b3e8SDimitry Andric // There is only one variant this argument could be; put it into the
81614f1b3e8SDimitry Andric // argument entry.
817f034231aSEd Maste arg2.push_back(index_arg);
818f034231aSEd Maste
819f034231aSEd Maste // Define the first (and only) variant of this arg.
820f034231aSEd Maste value_arg.arg_type = eArgTypeValue;
821f034231aSEd Maste value_arg.arg_repetition = eArgRepeatPlain;
822f034231aSEd Maste
82314f1b3e8SDimitry Andric // There is only one variant this argument could be; put it into the
82414f1b3e8SDimitry Andric // argument entry.
825f034231aSEd Maste arg3.push_back(value_arg);
826f034231aSEd Maste
827f034231aSEd Maste // Push the data for the first argument into the m_arguments vector.
828f034231aSEd Maste m_arguments.push_back(arg1);
829f034231aSEd Maste m_arguments.push_back(arg2);
830f034231aSEd Maste m_arguments.push_back(arg3);
831f034231aSEd Maste }
832f034231aSEd Maste
833f3fbd1c0SDimitry Andric ~CommandObjectSettingsInsertAfter() override = default;
834f034231aSEd Maste
83514f1b3e8SDimitry Andric // Overrides base class's behavior where WantsCompletion =
83614f1b3e8SDimitry Andric // !WantsRawCommandString.
WantsCompletion()83714f1b3e8SDimitry Andric bool WantsCompletion() override { return true; }
838f034231aSEd Maste
839ead24645SDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)840ead24645SDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
841f73363f1SDimitry Andric OptionElementVector &opt_element_vector) override {
842f034231aSEd Maste // Attempting to complete variable name
843f73363f1SDimitry Andric if (request.GetCursorIndex() < 2)
8447fa27ce4SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
8457fa27ce4SDimitry Andric GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
8467fa27ce4SDimitry Andric nullptr);
847f034231aSEd Maste }
848f034231aSEd Maste
849f034231aSEd Maste protected:
DoExecute(llvm::StringRef command,CommandReturnObject & result)850b1c73532SDimitry Andric void DoExecute(llvm::StringRef command,
851f73363f1SDimitry Andric CommandReturnObject &result) override {
852f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
853f034231aSEd Maste
854f034231aSEd Maste Args cmd_args(command);
855f034231aSEd Maste const size_t argc = cmd_args.GetArgumentCount();
856f034231aSEd Maste
85714f1b3e8SDimitry Andric if (argc < 3) {
858f034231aSEd Maste result.AppendError("'settings insert-after' takes more arguments");
859b1c73532SDimitry Andric return;
860f034231aSEd Maste }
861f034231aSEd Maste
862f034231aSEd Maste const char *var_name = cmd_args.GetArgumentAtIndex(0);
86314f1b3e8SDimitry Andric if ((var_name == nullptr) || (var_name[0] == '\0')) {
86414f1b3e8SDimitry Andric result.AppendError("'settings insert-after' command requires a valid "
86514f1b3e8SDimitry Andric "variable name; No value supplied");
866b1c73532SDimitry Andric return;
867f034231aSEd Maste }
868f034231aSEd Maste
869f034231aSEd Maste // Split the raw command into var_name, index_value, and value triple.
870ead24645SDimitry Andric llvm::StringRef var_value(command);
871ead24645SDimitry Andric var_value = var_value.split(var_name).second.trim();
872f034231aSEd Maste
8735f29bb8aSDimitry Andric Status error(GetDebugger().SetPropertyValue(
874ead24645SDimitry Andric &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value));
87514f1b3e8SDimitry Andric if (error.Fail()) {
876f034231aSEd Maste result.AppendError(error.AsCString());
877f034231aSEd Maste }
878f034231aSEd Maste }
879f034231aSEd Maste };
880f034231aSEd Maste
881f034231aSEd Maste // CommandObjectSettingsAppend
882f034231aSEd Maste
88314f1b3e8SDimitry Andric class CommandObjectSettingsAppend : public CommandObjectRaw {
884f034231aSEd Maste public:
CommandObjectSettingsAppend(CommandInterpreter & interpreter)885f3fbd1c0SDimitry Andric CommandObjectSettingsAppend(CommandInterpreter &interpreter)
886f3fbd1c0SDimitry Andric : CommandObjectRaw(interpreter, "settings append",
88714f1b3e8SDimitry Andric "Append one or more values to a debugger array, "
88814f1b3e8SDimitry Andric "dictionary, or string setting.") {
889f034231aSEd Maste CommandArgumentEntry arg1;
890f034231aSEd Maste CommandArgumentEntry arg2;
891f034231aSEd Maste CommandArgumentData var_name_arg;
892f034231aSEd Maste CommandArgumentData value_arg;
893f034231aSEd Maste
894f034231aSEd Maste // Define the first (and only) variant of this arg.
895f034231aSEd Maste var_name_arg.arg_type = eArgTypeSettingVariableName;
896f034231aSEd Maste var_name_arg.arg_repetition = eArgRepeatPlain;
897f034231aSEd Maste
89814f1b3e8SDimitry Andric // There is only one variant this argument could be; put it into the
89914f1b3e8SDimitry Andric // argument entry.
900f034231aSEd Maste arg1.push_back(var_name_arg);
901f034231aSEd Maste
902f034231aSEd Maste // Define the first (and only) variant of this arg.
903f034231aSEd Maste value_arg.arg_type = eArgTypeValue;
904f034231aSEd Maste value_arg.arg_repetition = eArgRepeatPlain;
905f034231aSEd Maste
90614f1b3e8SDimitry Andric // There is only one variant this argument could be; put it into the
90714f1b3e8SDimitry Andric // argument entry.
908f034231aSEd Maste arg2.push_back(value_arg);
909f034231aSEd Maste
910f034231aSEd Maste // Push the data for the first argument into the m_arguments vector.
911f034231aSEd Maste m_arguments.push_back(arg1);
912f034231aSEd Maste m_arguments.push_back(arg2);
913f034231aSEd Maste }
914f034231aSEd Maste
915f3fbd1c0SDimitry Andric ~CommandObjectSettingsAppend() override = default;
916f034231aSEd Maste
91714f1b3e8SDimitry Andric // Overrides base class's behavior where WantsCompletion =
91814f1b3e8SDimitry Andric // !WantsRawCommandString.
WantsCompletion()91914f1b3e8SDimitry Andric bool WantsCompletion() override { return true; }
920f034231aSEd Maste
921ead24645SDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)922ead24645SDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
923f73363f1SDimitry Andric OptionElementVector &opt_element_vector) override {
924f034231aSEd Maste // Attempting to complete variable name
925f73363f1SDimitry Andric if (request.GetCursorIndex() < 2)
9267fa27ce4SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
9277fa27ce4SDimitry Andric GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
9287fa27ce4SDimitry Andric nullptr);
929f034231aSEd Maste }
930f034231aSEd Maste
931f034231aSEd Maste protected:
DoExecute(llvm::StringRef command,CommandReturnObject & result)932b1c73532SDimitry Andric void DoExecute(llvm::StringRef command,
933f73363f1SDimitry Andric CommandReturnObject &result) override {
934f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
935f034231aSEd Maste Args cmd_args(command);
936f034231aSEd Maste const size_t argc = cmd_args.GetArgumentCount();
937f034231aSEd Maste
93814f1b3e8SDimitry Andric if (argc < 2) {
939f034231aSEd Maste result.AppendError("'settings append' takes more arguments");
940b1c73532SDimitry Andric return;
941f034231aSEd Maste }
942f034231aSEd Maste
943f034231aSEd Maste const char *var_name = cmd_args.GetArgumentAtIndex(0);
94414f1b3e8SDimitry Andric if ((var_name == nullptr) || (var_name[0] == '\0')) {
94514f1b3e8SDimitry Andric result.AppendError("'settings append' command requires a valid variable "
94614f1b3e8SDimitry Andric "name; No value supplied");
947b1c73532SDimitry Andric return;
948f034231aSEd Maste }
949f034231aSEd Maste
950f73363f1SDimitry Andric // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
951f73363f1SDimitry Andric // character string later on.
952f034231aSEd Maste
953f034231aSEd Maste // Split the raw command into var_name and value pair.
954ead24645SDimitry Andric llvm::StringRef var_value(command);
955ead24645SDimitry Andric var_value = var_value.split(var_name).second.trim();
956f034231aSEd Maste
9575f29bb8aSDimitry Andric Status error(GetDebugger().SetPropertyValue(
958ead24645SDimitry Andric &m_exe_ctx, eVarSetOperationAppend, var_name, var_value));
95914f1b3e8SDimitry Andric if (error.Fail()) {
960f034231aSEd Maste result.AppendError(error.AsCString());
961f034231aSEd Maste }
962f034231aSEd Maste }
963f034231aSEd Maste };
964f034231aSEd Maste
965f034231aSEd Maste // CommandObjectSettingsClear
966cfca06d7SDimitry Andric #define LLDB_OPTIONS_settings_clear
967cfca06d7SDimitry Andric #include "CommandOptions.inc"
968f034231aSEd Maste
96914f1b3e8SDimitry Andric class CommandObjectSettingsClear : public CommandObjectParsed {
970f034231aSEd Maste public:
CommandObjectSettingsClear(CommandInterpreter & interpreter)971f3fbd1c0SDimitry Andric CommandObjectSettingsClear(CommandInterpreter &interpreter)
97214f1b3e8SDimitry Andric : CommandObjectParsed(
97314f1b3e8SDimitry Andric interpreter, "settings clear",
974cfca06d7SDimitry Andric "Clear a debugger setting array, dictionary, or string. "
975cfca06d7SDimitry Andric "If '-a' option is specified, it clears all settings.", nullptr) {
976ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeSettingVariableName);
977f034231aSEd Maste }
978f034231aSEd Maste
979f3fbd1c0SDimitry Andric ~CommandObjectSettingsClear() override = default;
980f034231aSEd Maste
981ead24645SDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)982ead24645SDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
983f73363f1SDimitry Andric OptionElementVector &opt_element_vector) override {
984f034231aSEd Maste // Attempting to complete variable name
985f73363f1SDimitry Andric if (request.GetCursorIndex() < 2)
9867fa27ce4SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
9877fa27ce4SDimitry Andric GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
9887fa27ce4SDimitry Andric nullptr);
989f034231aSEd Maste }
990f034231aSEd Maste
GetOptions()991cfca06d7SDimitry Andric Options *GetOptions() override { return &m_options; }
992cfca06d7SDimitry Andric
993cfca06d7SDimitry Andric class CommandOptions : public Options {
994cfca06d7SDimitry Andric public:
995cfca06d7SDimitry Andric CommandOptions() = default;
996cfca06d7SDimitry Andric
997cfca06d7SDimitry Andric ~CommandOptions() override = default;
998cfca06d7SDimitry Andric
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)999cfca06d7SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1000cfca06d7SDimitry Andric ExecutionContext *execution_context) override {
1001cfca06d7SDimitry Andric const int short_option = m_getopt_table[option_idx].val;
1002cfca06d7SDimitry Andric switch (short_option) {
1003cfca06d7SDimitry Andric case 'a':
1004cfca06d7SDimitry Andric m_clear_all = true;
1005cfca06d7SDimitry Andric break;
1006cfca06d7SDimitry Andric default:
1007cfca06d7SDimitry Andric llvm_unreachable("Unimplemented option");
1008cfca06d7SDimitry Andric }
1009cfca06d7SDimitry Andric return Status();
1010cfca06d7SDimitry Andric }
1011cfca06d7SDimitry Andric
OptionParsingStarting(ExecutionContext * execution_context)1012cfca06d7SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
1013cfca06d7SDimitry Andric m_clear_all = false;
1014cfca06d7SDimitry Andric }
1015cfca06d7SDimitry Andric
GetDefinitions()1016cfca06d7SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1017e3b55780SDimitry Andric return llvm::ArrayRef(g_settings_clear_options);
1018cfca06d7SDimitry Andric }
1019cfca06d7SDimitry Andric
1020cfca06d7SDimitry Andric bool m_clear_all = false;
1021cfca06d7SDimitry Andric };
1022cfca06d7SDimitry Andric
1023f034231aSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)1024b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
1025f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
1026f034231aSEd Maste const size_t argc = command.GetArgumentCount();
1027f034231aSEd Maste
1028cfca06d7SDimitry Andric if (m_options.m_clear_all) {
1029cfca06d7SDimitry Andric if (argc != 0) {
1030cfca06d7SDimitry Andric result.AppendError("'settings clear --all' doesn't take any arguments");
1031b1c73532SDimitry Andric return;
1032cfca06d7SDimitry Andric }
1033cfca06d7SDimitry Andric GetDebugger().GetValueProperties()->Clear();
1034b1c73532SDimitry Andric return;
1035cfca06d7SDimitry Andric }
1036cfca06d7SDimitry Andric
103714f1b3e8SDimitry Andric if (argc != 1) {
10380cac4ca3SEd Maste result.AppendError("'settings clear' takes exactly one argument");
1039b1c73532SDimitry Andric return;
1040f034231aSEd Maste }
1041f034231aSEd Maste
1042f034231aSEd Maste const char *var_name = command.GetArgumentAtIndex(0);
104314f1b3e8SDimitry Andric if ((var_name == nullptr) || (var_name[0] == '\0')) {
104414f1b3e8SDimitry Andric result.AppendError("'settings clear' command requires a valid variable "
104514f1b3e8SDimitry Andric "name; No value supplied");
1046b1c73532SDimitry Andric return;
1047f034231aSEd Maste }
1048f034231aSEd Maste
10495f29bb8aSDimitry Andric Status error(GetDebugger().SetPropertyValue(
105014f1b3e8SDimitry Andric &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
105114f1b3e8SDimitry Andric if (error.Fail()) {
1052f034231aSEd Maste result.AppendError(error.AsCString());
1053f034231aSEd Maste }
1054f034231aSEd Maste }
1055cfca06d7SDimitry Andric
1056cfca06d7SDimitry Andric private:
1057cfca06d7SDimitry Andric CommandOptions m_options;
1058f034231aSEd Maste };
1059f034231aSEd Maste
1060f034231aSEd Maste // CommandObjectMultiwordSettings
1061f034231aSEd Maste
CommandObjectMultiwordSettings(CommandInterpreter & interpreter)106214f1b3e8SDimitry Andric CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
106314f1b3e8SDimitry Andric CommandInterpreter &interpreter)
106414f1b3e8SDimitry Andric : CommandObjectMultiword(interpreter, "settings",
106514f1b3e8SDimitry Andric "Commands for managing LLDB settings.",
106614f1b3e8SDimitry Andric "settings <subcommand> [<command-options>]") {
106714f1b3e8SDimitry Andric LoadSubCommand("set",
106814f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
106914f1b3e8SDimitry Andric LoadSubCommand("show",
107014f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
107114f1b3e8SDimitry Andric LoadSubCommand("list",
107214f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectSettingsList(interpreter)));
107314f1b3e8SDimitry Andric LoadSubCommand("remove",
107414f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
107514f1b3e8SDimitry Andric LoadSubCommand("replace", CommandObjectSP(
107614f1b3e8SDimitry Andric new CommandObjectSettingsReplace(interpreter)));
107714f1b3e8SDimitry Andric LoadSubCommand(
107814f1b3e8SDimitry Andric "insert-before",
107914f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
108014f1b3e8SDimitry Andric LoadSubCommand(
108114f1b3e8SDimitry Andric "insert-after",
108214f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
108314f1b3e8SDimitry Andric LoadSubCommand("append",
108414f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
108514f1b3e8SDimitry Andric LoadSubCommand("clear",
108614f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
108794994d37SDimitry Andric LoadSubCommand("write",
108894994d37SDimitry Andric CommandObjectSP(new CommandObjectSettingsWrite(interpreter)));
108994994d37SDimitry Andric LoadSubCommand("read",
109094994d37SDimitry Andric CommandObjectSP(new CommandObjectSettingsRead(interpreter)));
1091f034231aSEd Maste }
1092f034231aSEd Maste
1093f3fbd1c0SDimitry Andric CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default;
1094