1dda28197Spatrick //===-- CommandObjectSettings.cpp -----------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "CommandObjectSettings.h"
10061da546Spatrick
11061da546Spatrick #include "llvm/ADT/StringRef.h"
12061da546Spatrick
13061da546Spatrick #include "lldb/Host/OptionParser.h"
14061da546Spatrick #include "lldb/Interpreter/CommandCompletions.h"
15061da546Spatrick #include "lldb/Interpreter/CommandInterpreter.h"
16*f6aab3d8Srobert #include "lldb/Interpreter/CommandOptionArgumentTable.h"
17061da546Spatrick #include "lldb/Interpreter/CommandReturnObject.h"
18061da546Spatrick #include "lldb/Interpreter/OptionValueProperties.h"
19061da546Spatrick
20061da546Spatrick using namespace lldb;
21061da546Spatrick using namespace lldb_private;
22061da546Spatrick
23061da546Spatrick // CommandObjectSettingsSet
24061da546Spatrick #define LLDB_OPTIONS_settings_set
25061da546Spatrick #include "CommandOptions.inc"
26061da546Spatrick
27061da546Spatrick class CommandObjectSettingsSet : public CommandObjectRaw {
28061da546Spatrick public:
CommandObjectSettingsSet(CommandInterpreter & interpreter)29061da546Spatrick CommandObjectSettingsSet(CommandInterpreter &interpreter)
30061da546Spatrick : CommandObjectRaw(interpreter, "settings set",
31*f6aab3d8Srobert "Set the value of the specified debugger setting.") {
32061da546Spatrick CommandArgumentEntry arg1;
33061da546Spatrick CommandArgumentEntry arg2;
34061da546Spatrick CommandArgumentData var_name_arg;
35061da546Spatrick CommandArgumentData value_arg;
36061da546Spatrick
37061da546Spatrick // Define the first (and only) variant of this arg.
38061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName;
39061da546Spatrick var_name_arg.arg_repetition = eArgRepeatPlain;
40061da546Spatrick
41061da546Spatrick // There is only one variant this argument could be; put it into the
42061da546Spatrick // argument entry.
43061da546Spatrick arg1.push_back(var_name_arg);
44061da546Spatrick
45061da546Spatrick // Define the first (and only) variant of this arg.
46061da546Spatrick value_arg.arg_type = eArgTypeValue;
47061da546Spatrick value_arg.arg_repetition = eArgRepeatPlain;
48061da546Spatrick
49061da546Spatrick // There is only one variant this argument could be; put it into the
50061da546Spatrick // argument entry.
51061da546Spatrick arg2.push_back(value_arg);
52061da546Spatrick
53061da546Spatrick // Push the data for the first argument into the m_arguments vector.
54061da546Spatrick m_arguments.push_back(arg1);
55061da546Spatrick m_arguments.push_back(arg2);
56061da546Spatrick
57061da546Spatrick SetHelpLong(
58061da546Spatrick "\nWhen setting a dictionary or array variable, you can set multiple entries \
59061da546Spatrick at once by giving the values to the set command. For example:"
60061da546Spatrick R"(
61061da546Spatrick
62061da546Spatrick (lldb) settings set target.run-args value1 value2 value3
63061da546Spatrick (lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345
64061da546Spatrick
65061da546Spatrick (lldb) settings show target.run-args
66061da546Spatrick [0]: 'value1'
67061da546Spatrick [1]: 'value2'
68061da546Spatrick [3]: 'value3'
69061da546Spatrick (lldb) settings show target.env-vars
70061da546Spatrick 'MYPATH=~/.:/usr/bin'
71061da546Spatrick 'SOME_ENV_VAR=12345'
72061da546Spatrick
73061da546Spatrick )"
74061da546Spatrick "Warning: The 'set' command re-sets the entire array or dictionary. If you \
75061da546Spatrick just want to add, remove or update individual values (or add something to \
76061da546Spatrick the end), use one of the other settings sub-commands: append, replace, \
77061da546Spatrick insert-before or insert-after.");
78061da546Spatrick }
79061da546Spatrick
80061da546Spatrick ~CommandObjectSettingsSet() override = default;
81061da546Spatrick
82061da546Spatrick // Overrides base class's behavior where WantsCompletion =
83061da546Spatrick // !WantsRawCommandString.
WantsCompletion()84061da546Spatrick bool WantsCompletion() override { return true; }
85061da546Spatrick
GetOptions()86061da546Spatrick Options *GetOptions() override { return &m_options; }
87061da546Spatrick
88061da546Spatrick class CommandOptions : public Options {
89061da546Spatrick public:
90*f6aab3d8Srobert CommandOptions() = default;
91061da546Spatrick
92061da546Spatrick ~CommandOptions() override = default;
93061da546Spatrick
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)94061da546Spatrick Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
95061da546Spatrick ExecutionContext *execution_context) override {
96061da546Spatrick Status error;
97061da546Spatrick const int short_option = m_getopt_table[option_idx].val;
98061da546Spatrick
99061da546Spatrick switch (short_option) {
100061da546Spatrick case 'f':
101061da546Spatrick m_force = true;
102061da546Spatrick break;
103061da546Spatrick case 'g':
104061da546Spatrick m_global = true;
105061da546Spatrick break;
106*f6aab3d8Srobert case 'e':
107*f6aab3d8Srobert m_exists = true;
108*f6aab3d8Srobert break;
109061da546Spatrick default:
110061da546Spatrick llvm_unreachable("Unimplemented option");
111061da546Spatrick }
112061da546Spatrick
113061da546Spatrick return error;
114061da546Spatrick }
115061da546Spatrick
OptionParsingStarting(ExecutionContext * execution_context)116061da546Spatrick void OptionParsingStarting(ExecutionContext *execution_context) override {
117061da546Spatrick m_global = false;
118061da546Spatrick m_force = false;
119*f6aab3d8Srobert m_exists = false;
120061da546Spatrick }
121061da546Spatrick
GetDefinitions()122061da546Spatrick llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
123*f6aab3d8Srobert return llvm::ArrayRef(g_settings_set_options);
124061da546Spatrick }
125061da546Spatrick
126061da546Spatrick // Instance variables to hold the values for command options.
127be691f3bSpatrick bool m_global = false;
128*f6aab3d8Srobert bool m_force = false;
129*f6aab3d8Srobert bool m_exists = false;
130061da546Spatrick };
131061da546Spatrick
132061da546Spatrick void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)133061da546Spatrick HandleArgumentCompletion(CompletionRequest &request,
134061da546Spatrick OptionElementVector &opt_element_vector) override {
135061da546Spatrick
136061da546Spatrick const size_t argc = request.GetParsedLine().GetArgumentCount();
137061da546Spatrick const char *arg = nullptr;
138061da546Spatrick size_t setting_var_idx;
139061da546Spatrick for (setting_var_idx = 0; setting_var_idx < argc; ++setting_var_idx) {
140061da546Spatrick arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
141061da546Spatrick if (arg && arg[0] != '-')
142061da546Spatrick break; // We found our setting variable name index
143061da546Spatrick }
144061da546Spatrick if (request.GetCursorIndex() == setting_var_idx) {
145061da546Spatrick // Attempting to complete setting variable name
146061da546Spatrick CommandCompletions::InvokeCommonCompletionCallbacks(
147061da546Spatrick GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
148061da546Spatrick request, nullptr);
149061da546Spatrick return;
150061da546Spatrick }
151061da546Spatrick arg = request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
152061da546Spatrick
153061da546Spatrick if (!arg)
154061da546Spatrick return;
155061da546Spatrick
156061da546Spatrick // Complete option name
157*f6aab3d8Srobert if (arg[0] == '-')
158061da546Spatrick return;
159061da546Spatrick
160061da546Spatrick // Complete setting value
161061da546Spatrick const char *setting_var_name =
162061da546Spatrick request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
163061da546Spatrick Status error;
164061da546Spatrick lldb::OptionValueSP value_sp(GetDebugger().GetPropertyValue(
165061da546Spatrick &m_exe_ctx, setting_var_name, false, error));
166061da546Spatrick if (!value_sp)
167061da546Spatrick return;
168061da546Spatrick value_sp->AutoComplete(m_interpreter, request);
169061da546Spatrick }
170061da546Spatrick
171061da546Spatrick protected:
DoExecute(llvm::StringRef command,CommandReturnObject & result)172061da546Spatrick bool DoExecute(llvm::StringRef command,
173061da546Spatrick CommandReturnObject &result) override {
174061da546Spatrick Args cmd_args(command);
175061da546Spatrick
176061da546Spatrick // Process possible options.
177061da546Spatrick if (!ParseOptions(cmd_args, result))
178061da546Spatrick return false;
179061da546Spatrick
180061da546Spatrick const size_t min_argc = m_options.m_force ? 1 : 2;
181061da546Spatrick const size_t argc = cmd_args.GetArgumentCount();
182061da546Spatrick
183061da546Spatrick if ((argc < min_argc) && (!m_options.m_global)) {
184061da546Spatrick result.AppendError("'settings set' takes more arguments");
185061da546Spatrick return false;
186061da546Spatrick }
187061da546Spatrick
188061da546Spatrick const char *var_name = cmd_args.GetArgumentAtIndex(0);
189061da546Spatrick if ((var_name == nullptr) || (var_name[0] == '\0')) {
190061da546Spatrick result.AppendError(
191061da546Spatrick "'settings set' command requires a valid variable name");
192061da546Spatrick return false;
193061da546Spatrick }
194061da546Spatrick
195061da546Spatrick // A missing value corresponds to clearing the setting when "force" is
196061da546Spatrick // specified.
197061da546Spatrick if (argc == 1 && m_options.m_force) {
198061da546Spatrick Status error(GetDebugger().SetPropertyValue(
199061da546Spatrick &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
200061da546Spatrick if (error.Fail()) {
201061da546Spatrick result.AppendError(error.AsCString());
202061da546Spatrick return false;
203061da546Spatrick }
204061da546Spatrick return result.Succeeded();
205061da546Spatrick }
206061da546Spatrick
207061da546Spatrick // Split the raw command into var_name and value pair.
208061da546Spatrick llvm::StringRef var_value(command);
209061da546Spatrick var_value = var_value.split(var_name).second.ltrim();
210061da546Spatrick
211061da546Spatrick Status error;
212061da546Spatrick if (m_options.m_global)
213061da546Spatrick error = GetDebugger().SetPropertyValue(nullptr, eVarSetOperationAssign,
214061da546Spatrick var_name, var_value);
215061da546Spatrick
216061da546Spatrick if (error.Success()) {
217061da546Spatrick // FIXME this is the same issue as the one in commands script import
218061da546Spatrick // we could be setting target.load-script-from-symbol-file which would
219061da546Spatrick // cause Python scripts to be loaded, which could run LLDB commands (e.g.
220061da546Spatrick // settings set target.process.python-os-plugin-path) and cause a crash
221061da546Spatrick // if we did not clear the command's exe_ctx first
222061da546Spatrick ExecutionContext exe_ctx(m_exe_ctx);
223061da546Spatrick m_exe_ctx.Clear();
224061da546Spatrick error = GetDebugger().SetPropertyValue(&exe_ctx, eVarSetOperationAssign,
225061da546Spatrick var_name, var_value);
226061da546Spatrick }
227061da546Spatrick
228*f6aab3d8Srobert if (error.Fail() && !m_options.m_exists) {
229061da546Spatrick result.AppendError(error.AsCString());
230061da546Spatrick return false;
231061da546Spatrick }
232061da546Spatrick
233*f6aab3d8Srobert result.SetStatus(eReturnStatusSuccessFinishResult);
234061da546Spatrick return result.Succeeded();
235061da546Spatrick }
236061da546Spatrick
237061da546Spatrick private:
238061da546Spatrick CommandOptions m_options;
239061da546Spatrick };
240061da546Spatrick
241061da546Spatrick // CommandObjectSettingsShow -- Show current values
242061da546Spatrick
243061da546Spatrick class CommandObjectSettingsShow : public CommandObjectParsed {
244061da546Spatrick public:
CommandObjectSettingsShow(CommandInterpreter & interpreter)245061da546Spatrick CommandObjectSettingsShow(CommandInterpreter &interpreter)
246061da546Spatrick : CommandObjectParsed(interpreter, "settings show",
247061da546Spatrick "Show matching debugger settings and their current "
248061da546Spatrick "values. Defaults to showing all settings.",
249061da546Spatrick nullptr) {
250061da546Spatrick CommandArgumentEntry arg1;
251061da546Spatrick CommandArgumentData var_name_arg;
252061da546Spatrick
253061da546Spatrick // Define the first (and only) variant of this arg.
254061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName;
255061da546Spatrick var_name_arg.arg_repetition = eArgRepeatOptional;
256061da546Spatrick
257061da546Spatrick // There is only one variant this argument could be; put it into the
258061da546Spatrick // argument entry.
259061da546Spatrick arg1.push_back(var_name_arg);
260061da546Spatrick
261061da546Spatrick // Push the data for the first argument into the m_arguments vector.
262061da546Spatrick m_arguments.push_back(arg1);
263061da546Spatrick }
264061da546Spatrick
265061da546Spatrick ~CommandObjectSettingsShow() override = default;
266061da546Spatrick
267061da546Spatrick void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)268061da546Spatrick HandleArgumentCompletion(CompletionRequest &request,
269061da546Spatrick OptionElementVector &opt_element_vector) override {
270061da546Spatrick CommandCompletions::InvokeCommonCompletionCallbacks(
271061da546Spatrick GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
272061da546Spatrick request, nullptr);
273061da546Spatrick }
274061da546Spatrick
275061da546Spatrick protected:
DoExecute(Args & args,CommandReturnObject & result)276061da546Spatrick bool DoExecute(Args &args, CommandReturnObject &result) override {
277061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishResult);
278061da546Spatrick
279061da546Spatrick if (!args.empty()) {
280061da546Spatrick for (const auto &arg : args) {
281061da546Spatrick Status error(GetDebugger().DumpPropertyValue(
282061da546Spatrick &m_exe_ctx, result.GetOutputStream(), arg.ref(),
283061da546Spatrick OptionValue::eDumpGroupValue));
284061da546Spatrick if (error.Success()) {
285061da546Spatrick result.GetOutputStream().EOL();
286061da546Spatrick } else {
287061da546Spatrick result.AppendError(error.AsCString());
288061da546Spatrick }
289061da546Spatrick }
290061da546Spatrick } else {
291061da546Spatrick GetDebugger().DumpAllPropertyValues(&m_exe_ctx, result.GetOutputStream(),
292061da546Spatrick OptionValue::eDumpGroupValue);
293061da546Spatrick }
294061da546Spatrick
295061da546Spatrick return result.Succeeded();
296061da546Spatrick }
297061da546Spatrick };
298061da546Spatrick
299061da546Spatrick // CommandObjectSettingsWrite -- Write settings to file
300061da546Spatrick #define LLDB_OPTIONS_settings_write
301061da546Spatrick #include "CommandOptions.inc"
302061da546Spatrick
303061da546Spatrick class CommandObjectSettingsWrite : public CommandObjectParsed {
304061da546Spatrick public:
CommandObjectSettingsWrite(CommandInterpreter & interpreter)305061da546Spatrick CommandObjectSettingsWrite(CommandInterpreter &interpreter)
306061da546Spatrick : CommandObjectParsed(
307061da546Spatrick interpreter, "settings export",
308061da546Spatrick "Write matching debugger settings and their "
309061da546Spatrick "current values to a file that can be read in with "
310061da546Spatrick "\"settings read\". Defaults to writing all settings.",
311*f6aab3d8Srobert nullptr) {
312061da546Spatrick CommandArgumentEntry arg1;
313061da546Spatrick CommandArgumentData var_name_arg;
314061da546Spatrick
315061da546Spatrick // Define the first (and only) variant of this arg.
316061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName;
317061da546Spatrick var_name_arg.arg_repetition = eArgRepeatOptional;
318061da546Spatrick
319061da546Spatrick // There is only one variant this argument could be; put it into the
320061da546Spatrick // argument entry.
321061da546Spatrick arg1.push_back(var_name_arg);
322061da546Spatrick
323061da546Spatrick // Push the data for the first argument into the m_arguments vector.
324061da546Spatrick m_arguments.push_back(arg1);
325061da546Spatrick }
326061da546Spatrick
327061da546Spatrick ~CommandObjectSettingsWrite() override = default;
328061da546Spatrick
GetOptions()329061da546Spatrick Options *GetOptions() override { return &m_options; }
330061da546Spatrick
331061da546Spatrick class CommandOptions : public Options {
332061da546Spatrick public:
333*f6aab3d8Srobert CommandOptions() = default;
334061da546Spatrick
335061da546Spatrick ~CommandOptions() override = default;
336061da546Spatrick
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)337061da546Spatrick Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
338061da546Spatrick ExecutionContext *execution_context) override {
339061da546Spatrick Status error;
340061da546Spatrick const int short_option = m_getopt_table[option_idx].val;
341061da546Spatrick
342061da546Spatrick switch (short_option) {
343061da546Spatrick case 'f':
344dda28197Spatrick m_filename.assign(std::string(option_arg));
345061da546Spatrick break;
346061da546Spatrick case 'a':
347061da546Spatrick m_append = true;
348061da546Spatrick break;
349061da546Spatrick default:
350061da546Spatrick llvm_unreachable("Unimplemented option");
351061da546Spatrick }
352061da546Spatrick
353061da546Spatrick return error;
354061da546Spatrick }
355061da546Spatrick
OptionParsingStarting(ExecutionContext * execution_context)356061da546Spatrick void OptionParsingStarting(ExecutionContext *execution_context) override {
357061da546Spatrick m_filename.clear();
358061da546Spatrick m_append = false;
359061da546Spatrick }
360061da546Spatrick
GetDefinitions()361061da546Spatrick llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
362*f6aab3d8Srobert return llvm::ArrayRef(g_settings_write_options);
363061da546Spatrick }
364061da546Spatrick
365061da546Spatrick // Instance variables to hold the values for command options.
366061da546Spatrick std::string m_filename;
367061da546Spatrick bool m_append = false;
368061da546Spatrick };
369061da546Spatrick
370061da546Spatrick protected:
DoExecute(Args & args,CommandReturnObject & result)371061da546Spatrick bool DoExecute(Args &args, CommandReturnObject &result) override {
372061da546Spatrick FileSpec file_spec(m_options.m_filename);
373061da546Spatrick FileSystem::Instance().Resolve(file_spec);
374061da546Spatrick std::string path(file_spec.GetPath());
375*f6aab3d8Srobert auto options = File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate;
376061da546Spatrick if (m_options.m_append)
377061da546Spatrick options |= File::eOpenOptionAppend;
378061da546Spatrick else
379061da546Spatrick options |= File::eOpenOptionTruncate;
380061da546Spatrick
381061da546Spatrick StreamFile out_file(path.c_str(), options,
382061da546Spatrick lldb::eFilePermissionsFileDefault);
383061da546Spatrick
384061da546Spatrick if (!out_file.GetFile().IsValid()) {
385061da546Spatrick result.AppendErrorWithFormat("%s: unable to write to file", path.c_str());
386061da546Spatrick return false;
387061da546Spatrick }
388061da546Spatrick
389061da546Spatrick // Exporting should not be context sensitive.
390061da546Spatrick ExecutionContext clean_ctx;
391061da546Spatrick
392061da546Spatrick if (args.empty()) {
393061da546Spatrick GetDebugger().DumpAllPropertyValues(&clean_ctx, out_file,
394061da546Spatrick OptionValue::eDumpGroupExport);
395061da546Spatrick return result.Succeeded();
396061da546Spatrick }
397061da546Spatrick
398061da546Spatrick for (const auto &arg : args) {
399061da546Spatrick Status error(GetDebugger().DumpPropertyValue(
400061da546Spatrick &clean_ctx, out_file, arg.ref(), OptionValue::eDumpGroupExport));
401061da546Spatrick if (!error.Success()) {
402061da546Spatrick result.AppendError(error.AsCString());
403061da546Spatrick }
404061da546Spatrick }
405061da546Spatrick
406061da546Spatrick return result.Succeeded();
407061da546Spatrick }
408061da546Spatrick
409061da546Spatrick private:
410061da546Spatrick CommandOptions m_options;
411061da546Spatrick };
412061da546Spatrick
413061da546Spatrick // CommandObjectSettingsRead -- Read settings from file
414061da546Spatrick #define LLDB_OPTIONS_settings_read
415061da546Spatrick #include "CommandOptions.inc"
416061da546Spatrick
417061da546Spatrick class CommandObjectSettingsRead : public CommandObjectParsed {
418061da546Spatrick public:
CommandObjectSettingsRead(CommandInterpreter & interpreter)419061da546Spatrick CommandObjectSettingsRead(CommandInterpreter &interpreter)
420061da546Spatrick : CommandObjectParsed(
421061da546Spatrick interpreter, "settings read",
422061da546Spatrick "Read settings previously saved to a file with \"settings write\".",
423*f6aab3d8Srobert nullptr) {}
424061da546Spatrick
425061da546Spatrick ~CommandObjectSettingsRead() override = default;
426061da546Spatrick
GetOptions()427061da546Spatrick Options *GetOptions() override { return &m_options; }
428061da546Spatrick
429061da546Spatrick class CommandOptions : public Options {
430061da546Spatrick public:
431*f6aab3d8Srobert CommandOptions() = default;
432061da546Spatrick
433061da546Spatrick ~CommandOptions() override = default;
434061da546Spatrick
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)435061da546Spatrick Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
436061da546Spatrick ExecutionContext *execution_context) override {
437061da546Spatrick Status error;
438061da546Spatrick const int short_option = m_getopt_table[option_idx].val;
439061da546Spatrick
440061da546Spatrick switch (short_option) {
441061da546Spatrick case 'f':
442dda28197Spatrick m_filename.assign(std::string(option_arg));
443061da546Spatrick break;
444061da546Spatrick default:
445061da546Spatrick llvm_unreachable("Unimplemented option");
446061da546Spatrick }
447061da546Spatrick
448061da546Spatrick return error;
449061da546Spatrick }
450061da546Spatrick
OptionParsingStarting(ExecutionContext * execution_context)451061da546Spatrick void OptionParsingStarting(ExecutionContext *execution_context) override {
452061da546Spatrick m_filename.clear();
453061da546Spatrick }
454061da546Spatrick
GetDefinitions()455061da546Spatrick llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
456*f6aab3d8Srobert return llvm::ArrayRef(g_settings_read_options);
457061da546Spatrick }
458061da546Spatrick
459061da546Spatrick // Instance variables to hold the values for command options.
460061da546Spatrick std::string m_filename;
461061da546Spatrick };
462061da546Spatrick
463061da546Spatrick protected:
DoExecute(Args & command,CommandReturnObject & result)464061da546Spatrick bool DoExecute(Args &command, CommandReturnObject &result) override {
465061da546Spatrick FileSpec file(m_options.m_filename);
466061da546Spatrick FileSystem::Instance().Resolve(file);
467061da546Spatrick CommandInterpreterRunOptions options;
468061da546Spatrick options.SetAddToHistory(false);
469061da546Spatrick options.SetEchoCommands(false);
470061da546Spatrick options.SetPrintResults(true);
471061da546Spatrick options.SetPrintErrors(true);
472061da546Spatrick options.SetStopOnError(false);
473be691f3bSpatrick m_interpreter.HandleCommandsFromFile(file, options, result);
474061da546Spatrick return result.Succeeded();
475061da546Spatrick }
476061da546Spatrick
477061da546Spatrick private:
478061da546Spatrick CommandOptions m_options;
479061da546Spatrick };
480061da546Spatrick
481061da546Spatrick // CommandObjectSettingsList -- List settable variables
482061da546Spatrick
483061da546Spatrick class CommandObjectSettingsList : public CommandObjectParsed {
484061da546Spatrick public:
CommandObjectSettingsList(CommandInterpreter & interpreter)485061da546Spatrick CommandObjectSettingsList(CommandInterpreter &interpreter)
486061da546Spatrick : CommandObjectParsed(interpreter, "settings list",
487061da546Spatrick "List and describe matching debugger settings. "
488061da546Spatrick "Defaults to all listing all settings.",
489061da546Spatrick nullptr) {
490061da546Spatrick CommandArgumentEntry arg;
491061da546Spatrick CommandArgumentData var_name_arg;
492061da546Spatrick CommandArgumentData prefix_name_arg;
493061da546Spatrick
494061da546Spatrick // Define the first variant of this arg.
495061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName;
496061da546Spatrick var_name_arg.arg_repetition = eArgRepeatOptional;
497061da546Spatrick
498061da546Spatrick // Define the second variant of this arg.
499061da546Spatrick prefix_name_arg.arg_type = eArgTypeSettingPrefix;
500061da546Spatrick prefix_name_arg.arg_repetition = eArgRepeatOptional;
501061da546Spatrick
502061da546Spatrick arg.push_back(var_name_arg);
503061da546Spatrick arg.push_back(prefix_name_arg);
504061da546Spatrick
505061da546Spatrick // Push the data for the first argument into the m_arguments vector.
506061da546Spatrick m_arguments.push_back(arg);
507061da546Spatrick }
508061da546Spatrick
509061da546Spatrick ~CommandObjectSettingsList() override = default;
510061da546Spatrick
511061da546Spatrick void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)512061da546Spatrick HandleArgumentCompletion(CompletionRequest &request,
513061da546Spatrick OptionElementVector &opt_element_vector) override {
514061da546Spatrick CommandCompletions::InvokeCommonCompletionCallbacks(
515061da546Spatrick GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
516061da546Spatrick request, nullptr);
517061da546Spatrick }
518061da546Spatrick
519061da546Spatrick protected:
DoExecute(Args & args,CommandReturnObject & result)520061da546Spatrick bool DoExecute(Args &args, CommandReturnObject &result) override {
521061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishResult);
522061da546Spatrick
523061da546Spatrick const bool will_modify = false;
524061da546Spatrick const size_t argc = args.GetArgumentCount();
525061da546Spatrick if (argc > 0) {
526061da546Spatrick const bool dump_qualified_name = true;
527061da546Spatrick
528dda28197Spatrick for (const Args::ArgEntry &arg : args) {
529dda28197Spatrick const char *property_path = arg.c_str();
530061da546Spatrick
531061da546Spatrick const Property *property =
532061da546Spatrick GetDebugger().GetValueProperties()->GetPropertyAtPath(
533061da546Spatrick &m_exe_ctx, will_modify, property_path);
534061da546Spatrick
535061da546Spatrick if (property) {
536061da546Spatrick property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
537061da546Spatrick dump_qualified_name);
538061da546Spatrick } else {
539061da546Spatrick result.AppendErrorWithFormat("invalid property path '%s'",
540061da546Spatrick property_path);
541061da546Spatrick }
542061da546Spatrick }
543061da546Spatrick } else {
544061da546Spatrick GetDebugger().DumpAllDescriptions(m_interpreter,
545061da546Spatrick result.GetOutputStream());
546061da546Spatrick }
547061da546Spatrick
548061da546Spatrick return result.Succeeded();
549061da546Spatrick }
550061da546Spatrick };
551061da546Spatrick
552061da546Spatrick // CommandObjectSettingsRemove
553061da546Spatrick
554061da546Spatrick class CommandObjectSettingsRemove : public CommandObjectRaw {
555061da546Spatrick public:
CommandObjectSettingsRemove(CommandInterpreter & interpreter)556061da546Spatrick CommandObjectSettingsRemove(CommandInterpreter &interpreter)
557061da546Spatrick : CommandObjectRaw(interpreter, "settings remove",
558061da546Spatrick "Remove a value from a setting, specified by array "
559061da546Spatrick "index or dictionary key.") {
560061da546Spatrick CommandArgumentEntry arg1;
561061da546Spatrick CommandArgumentEntry arg2;
562061da546Spatrick CommandArgumentData var_name_arg;
563061da546Spatrick CommandArgumentData index_arg;
564061da546Spatrick CommandArgumentData key_arg;
565061da546Spatrick
566061da546Spatrick // Define the first (and only) variant of this arg.
567061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName;
568061da546Spatrick var_name_arg.arg_repetition = eArgRepeatPlain;
569061da546Spatrick
570061da546Spatrick // There is only one variant this argument could be; put it into the
571061da546Spatrick // argument entry.
572061da546Spatrick arg1.push_back(var_name_arg);
573061da546Spatrick
574061da546Spatrick // Define the first variant of this arg.
575061da546Spatrick index_arg.arg_type = eArgTypeSettingIndex;
576061da546Spatrick index_arg.arg_repetition = eArgRepeatPlain;
577061da546Spatrick
578061da546Spatrick // Define the second variant of this arg.
579061da546Spatrick key_arg.arg_type = eArgTypeSettingKey;
580061da546Spatrick key_arg.arg_repetition = eArgRepeatPlain;
581061da546Spatrick
582061da546Spatrick // Push both variants into this arg
583061da546Spatrick arg2.push_back(index_arg);
584061da546Spatrick arg2.push_back(key_arg);
585061da546Spatrick
586061da546Spatrick // Push the data for the first argument into the m_arguments vector.
587061da546Spatrick m_arguments.push_back(arg1);
588061da546Spatrick m_arguments.push_back(arg2);
589061da546Spatrick }
590061da546Spatrick
591061da546Spatrick ~CommandObjectSettingsRemove() override = default;
592061da546Spatrick
WantsCompletion()593061da546Spatrick bool WantsCompletion() override { return true; }
594061da546Spatrick
595061da546Spatrick void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)596061da546Spatrick HandleArgumentCompletion(CompletionRequest &request,
597061da546Spatrick OptionElementVector &opt_element_vector) override {
598061da546Spatrick if (request.GetCursorIndex() < 2)
599061da546Spatrick CommandCompletions::InvokeCommonCompletionCallbacks(
600061da546Spatrick GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
601061da546Spatrick request, nullptr);
602061da546Spatrick }
603061da546Spatrick
604061da546Spatrick protected:
DoExecute(llvm::StringRef command,CommandReturnObject & result)605061da546Spatrick bool DoExecute(llvm::StringRef command,
606061da546Spatrick CommandReturnObject &result) override {
607061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishNoResult);
608061da546Spatrick
609061da546Spatrick Args cmd_args(command);
610061da546Spatrick
611061da546Spatrick // Process possible options.
612061da546Spatrick if (!ParseOptions(cmd_args, result))
613061da546Spatrick return false;
614061da546Spatrick
615061da546Spatrick const size_t argc = cmd_args.GetArgumentCount();
616061da546Spatrick if (argc == 0) {
617061da546Spatrick result.AppendError("'settings remove' takes an array or dictionary item, "
618061da546Spatrick "or an array followed by one or more indexes, or a "
619061da546Spatrick "dictionary followed by one or more key names to "
620061da546Spatrick "remove");
621061da546Spatrick return false;
622061da546Spatrick }
623061da546Spatrick
624061da546Spatrick const char *var_name = cmd_args.GetArgumentAtIndex(0);
625061da546Spatrick if ((var_name == nullptr) || (var_name[0] == '\0')) {
626061da546Spatrick result.AppendError(
627061da546Spatrick "'settings remove' command requires a valid variable name");
628061da546Spatrick return false;
629061da546Spatrick }
630061da546Spatrick
631061da546Spatrick // Split the raw command into var_name and value pair.
632061da546Spatrick llvm::StringRef var_value(command);
633061da546Spatrick var_value = var_value.split(var_name).second.trim();
634061da546Spatrick
635061da546Spatrick Status error(GetDebugger().SetPropertyValue(
636061da546Spatrick &m_exe_ctx, eVarSetOperationRemove, var_name, var_value));
637061da546Spatrick if (error.Fail()) {
638061da546Spatrick result.AppendError(error.AsCString());
639061da546Spatrick return false;
640061da546Spatrick }
641061da546Spatrick
642061da546Spatrick return result.Succeeded();
643061da546Spatrick }
644061da546Spatrick };
645061da546Spatrick
646061da546Spatrick // CommandObjectSettingsReplace
647061da546Spatrick
648061da546Spatrick class CommandObjectSettingsReplace : public CommandObjectRaw {
649061da546Spatrick public:
CommandObjectSettingsReplace(CommandInterpreter & interpreter)650061da546Spatrick CommandObjectSettingsReplace(CommandInterpreter &interpreter)
651061da546Spatrick : CommandObjectRaw(interpreter, "settings replace",
652061da546Spatrick "Replace the debugger setting value specified by "
653061da546Spatrick "array index or dictionary key.") {
654061da546Spatrick CommandArgumentEntry arg1;
655061da546Spatrick CommandArgumentEntry arg2;
656061da546Spatrick CommandArgumentEntry arg3;
657061da546Spatrick CommandArgumentData var_name_arg;
658061da546Spatrick CommandArgumentData index_arg;
659061da546Spatrick CommandArgumentData key_arg;
660061da546Spatrick CommandArgumentData value_arg;
661061da546Spatrick
662061da546Spatrick // Define the first (and only) variant of this arg.
663061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName;
664061da546Spatrick var_name_arg.arg_repetition = eArgRepeatPlain;
665061da546Spatrick
666061da546Spatrick // There is only one variant this argument could be; put it into the
667061da546Spatrick // argument entry.
668061da546Spatrick arg1.push_back(var_name_arg);
669061da546Spatrick
670061da546Spatrick // Define the first (variant of this arg.
671061da546Spatrick index_arg.arg_type = eArgTypeSettingIndex;
672061da546Spatrick index_arg.arg_repetition = eArgRepeatPlain;
673061da546Spatrick
674061da546Spatrick // Define the second (variant of this arg.
675061da546Spatrick key_arg.arg_type = eArgTypeSettingKey;
676061da546Spatrick key_arg.arg_repetition = eArgRepeatPlain;
677061da546Spatrick
678061da546Spatrick // Put both variants into this arg
679061da546Spatrick arg2.push_back(index_arg);
680061da546Spatrick arg2.push_back(key_arg);
681061da546Spatrick
682061da546Spatrick // Define the first (and only) variant of this arg.
683061da546Spatrick value_arg.arg_type = eArgTypeValue;
684061da546Spatrick value_arg.arg_repetition = eArgRepeatPlain;
685061da546Spatrick
686061da546Spatrick // There is only one variant this argument could be; put it into the
687061da546Spatrick // argument entry.
688061da546Spatrick arg3.push_back(value_arg);
689061da546Spatrick
690061da546Spatrick // Push the data for the first argument into the m_arguments vector.
691061da546Spatrick m_arguments.push_back(arg1);
692061da546Spatrick m_arguments.push_back(arg2);
693061da546Spatrick m_arguments.push_back(arg3);
694061da546Spatrick }
695061da546Spatrick
696061da546Spatrick ~CommandObjectSettingsReplace() override = default;
697061da546Spatrick
698061da546Spatrick // Overrides base class's behavior where WantsCompletion =
699061da546Spatrick // !WantsRawCommandString.
WantsCompletion()700061da546Spatrick bool WantsCompletion() override { return true; }
701061da546Spatrick
702061da546Spatrick void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)703061da546Spatrick HandleArgumentCompletion(CompletionRequest &request,
704061da546Spatrick OptionElementVector &opt_element_vector) override {
705061da546Spatrick // Attempting to complete variable name
706061da546Spatrick if (request.GetCursorIndex() < 2)
707061da546Spatrick CommandCompletions::InvokeCommonCompletionCallbacks(
708061da546Spatrick GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
709061da546Spatrick request, nullptr);
710061da546Spatrick }
711061da546Spatrick
712061da546Spatrick protected:
DoExecute(llvm::StringRef command,CommandReturnObject & result)713061da546Spatrick bool DoExecute(llvm::StringRef command,
714061da546Spatrick CommandReturnObject &result) override {
715061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishNoResult);
716061da546Spatrick
717061da546Spatrick Args cmd_args(command);
718061da546Spatrick const char *var_name = cmd_args.GetArgumentAtIndex(0);
719061da546Spatrick if ((var_name == nullptr) || (var_name[0] == '\0')) {
720061da546Spatrick result.AppendError("'settings replace' command requires a valid variable "
721061da546Spatrick "name; No value supplied");
722061da546Spatrick return false;
723061da546Spatrick }
724061da546Spatrick
725061da546Spatrick // Split the raw command into var_name, index_value, and value triple.
726061da546Spatrick llvm::StringRef var_value(command);
727061da546Spatrick var_value = var_value.split(var_name).second.trim();
728061da546Spatrick
729061da546Spatrick Status error(GetDebugger().SetPropertyValue(
730061da546Spatrick &m_exe_ctx, eVarSetOperationReplace, var_name, var_value));
731061da546Spatrick if (error.Fail()) {
732061da546Spatrick result.AppendError(error.AsCString());
733061da546Spatrick return false;
734061da546Spatrick } else {
735061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishNoResult);
736061da546Spatrick }
737061da546Spatrick
738061da546Spatrick return result.Succeeded();
739061da546Spatrick }
740061da546Spatrick };
741061da546Spatrick
742061da546Spatrick // CommandObjectSettingsInsertBefore
743061da546Spatrick
744061da546Spatrick class CommandObjectSettingsInsertBefore : public CommandObjectRaw {
745061da546Spatrick public:
CommandObjectSettingsInsertBefore(CommandInterpreter & interpreter)746061da546Spatrick CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
747061da546Spatrick : CommandObjectRaw(interpreter, "settings insert-before",
748061da546Spatrick "Insert one or more values into an debugger array "
749061da546Spatrick "setting immediately before the specified element "
750061da546Spatrick "index.") {
751061da546Spatrick CommandArgumentEntry arg1;
752061da546Spatrick CommandArgumentEntry arg2;
753061da546Spatrick CommandArgumentEntry arg3;
754061da546Spatrick CommandArgumentData var_name_arg;
755061da546Spatrick CommandArgumentData index_arg;
756061da546Spatrick CommandArgumentData value_arg;
757061da546Spatrick
758061da546Spatrick // Define the first (and only) variant of this arg.
759061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName;
760061da546Spatrick var_name_arg.arg_repetition = eArgRepeatPlain;
761061da546Spatrick
762061da546Spatrick // There is only one variant this argument could be; put it into the
763061da546Spatrick // argument entry.
764061da546Spatrick arg1.push_back(var_name_arg);
765061da546Spatrick
766061da546Spatrick // Define the first (variant of this arg.
767061da546Spatrick index_arg.arg_type = eArgTypeSettingIndex;
768061da546Spatrick index_arg.arg_repetition = eArgRepeatPlain;
769061da546Spatrick
770061da546Spatrick // There is only one variant this argument could be; put it into the
771061da546Spatrick // argument entry.
772061da546Spatrick arg2.push_back(index_arg);
773061da546Spatrick
774061da546Spatrick // Define the first (and only) variant of this arg.
775061da546Spatrick value_arg.arg_type = eArgTypeValue;
776061da546Spatrick value_arg.arg_repetition = eArgRepeatPlain;
777061da546Spatrick
778061da546Spatrick // There is only one variant this argument could be; put it into the
779061da546Spatrick // argument entry.
780061da546Spatrick arg3.push_back(value_arg);
781061da546Spatrick
782061da546Spatrick // Push the data for the first argument into the m_arguments vector.
783061da546Spatrick m_arguments.push_back(arg1);
784061da546Spatrick m_arguments.push_back(arg2);
785061da546Spatrick m_arguments.push_back(arg3);
786061da546Spatrick }
787061da546Spatrick
788061da546Spatrick ~CommandObjectSettingsInsertBefore() override = default;
789061da546Spatrick
790061da546Spatrick // Overrides base class's behavior where WantsCompletion =
791061da546Spatrick // !WantsRawCommandString.
WantsCompletion()792061da546Spatrick bool WantsCompletion() override { return true; }
793061da546Spatrick
794061da546Spatrick void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)795061da546Spatrick HandleArgumentCompletion(CompletionRequest &request,
796061da546Spatrick OptionElementVector &opt_element_vector) override {
797061da546Spatrick // Attempting to complete variable name
798061da546Spatrick if (request.GetCursorIndex() < 2)
799061da546Spatrick CommandCompletions::InvokeCommonCompletionCallbacks(
800061da546Spatrick GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
801061da546Spatrick request, nullptr);
802061da546Spatrick }
803061da546Spatrick
804061da546Spatrick protected:
DoExecute(llvm::StringRef command,CommandReturnObject & result)805061da546Spatrick bool DoExecute(llvm::StringRef command,
806061da546Spatrick CommandReturnObject &result) override {
807061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishNoResult);
808061da546Spatrick
809061da546Spatrick Args cmd_args(command);
810061da546Spatrick const size_t argc = cmd_args.GetArgumentCount();
811061da546Spatrick
812061da546Spatrick if (argc < 3) {
813061da546Spatrick result.AppendError("'settings insert-before' takes more arguments");
814061da546Spatrick return false;
815061da546Spatrick }
816061da546Spatrick
817061da546Spatrick const char *var_name = cmd_args.GetArgumentAtIndex(0);
818061da546Spatrick if ((var_name == nullptr) || (var_name[0] == '\0')) {
819061da546Spatrick result.AppendError("'settings insert-before' command requires a valid "
820061da546Spatrick "variable name; No value supplied");
821061da546Spatrick return false;
822061da546Spatrick }
823061da546Spatrick
824061da546Spatrick // Split the raw command into var_name, index_value, and value triple.
825061da546Spatrick llvm::StringRef var_value(command);
826061da546Spatrick var_value = var_value.split(var_name).second.trim();
827061da546Spatrick
828061da546Spatrick Status error(GetDebugger().SetPropertyValue(
829061da546Spatrick &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value));
830061da546Spatrick if (error.Fail()) {
831061da546Spatrick result.AppendError(error.AsCString());
832061da546Spatrick return false;
833061da546Spatrick }
834061da546Spatrick
835061da546Spatrick return result.Succeeded();
836061da546Spatrick }
837061da546Spatrick };
838061da546Spatrick
839061da546Spatrick // CommandObjectSettingInsertAfter
840061da546Spatrick
841061da546Spatrick class CommandObjectSettingsInsertAfter : public CommandObjectRaw {
842061da546Spatrick public:
CommandObjectSettingsInsertAfter(CommandInterpreter & interpreter)843061da546Spatrick CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
844061da546Spatrick : CommandObjectRaw(interpreter, "settings insert-after",
845061da546Spatrick "Insert one or more values into a debugger array "
846061da546Spatrick "settings after the specified element index.") {
847061da546Spatrick CommandArgumentEntry arg1;
848061da546Spatrick CommandArgumentEntry arg2;
849061da546Spatrick CommandArgumentEntry arg3;
850061da546Spatrick CommandArgumentData var_name_arg;
851061da546Spatrick CommandArgumentData index_arg;
852061da546Spatrick CommandArgumentData value_arg;
853061da546Spatrick
854061da546Spatrick // Define the first (and only) variant of this arg.
855061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName;
856061da546Spatrick var_name_arg.arg_repetition = eArgRepeatPlain;
857061da546Spatrick
858061da546Spatrick // There is only one variant this argument could be; put it into the
859061da546Spatrick // argument entry.
860061da546Spatrick arg1.push_back(var_name_arg);
861061da546Spatrick
862061da546Spatrick // Define the first (variant of this arg.
863061da546Spatrick index_arg.arg_type = eArgTypeSettingIndex;
864061da546Spatrick index_arg.arg_repetition = eArgRepeatPlain;
865061da546Spatrick
866061da546Spatrick // There is only one variant this argument could be; put it into the
867061da546Spatrick // argument entry.
868061da546Spatrick arg2.push_back(index_arg);
869061da546Spatrick
870061da546Spatrick // Define the first (and only) variant of this arg.
871061da546Spatrick value_arg.arg_type = eArgTypeValue;
872061da546Spatrick value_arg.arg_repetition = eArgRepeatPlain;
873061da546Spatrick
874061da546Spatrick // There is only one variant this argument could be; put it into the
875061da546Spatrick // argument entry.
876061da546Spatrick arg3.push_back(value_arg);
877061da546Spatrick
878061da546Spatrick // Push the data for the first argument into the m_arguments vector.
879061da546Spatrick m_arguments.push_back(arg1);
880061da546Spatrick m_arguments.push_back(arg2);
881061da546Spatrick m_arguments.push_back(arg3);
882061da546Spatrick }
883061da546Spatrick
884061da546Spatrick ~CommandObjectSettingsInsertAfter() override = default;
885061da546Spatrick
886061da546Spatrick // Overrides base class's behavior where WantsCompletion =
887061da546Spatrick // !WantsRawCommandString.
WantsCompletion()888061da546Spatrick bool WantsCompletion() override { return true; }
889061da546Spatrick
890061da546Spatrick void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)891061da546Spatrick HandleArgumentCompletion(CompletionRequest &request,
892061da546Spatrick OptionElementVector &opt_element_vector) override {
893061da546Spatrick // Attempting to complete variable name
894061da546Spatrick if (request.GetCursorIndex() < 2)
895061da546Spatrick CommandCompletions::InvokeCommonCompletionCallbacks(
896061da546Spatrick GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
897061da546Spatrick request, nullptr);
898061da546Spatrick }
899061da546Spatrick
900061da546Spatrick protected:
DoExecute(llvm::StringRef command,CommandReturnObject & result)901061da546Spatrick bool DoExecute(llvm::StringRef command,
902061da546Spatrick CommandReturnObject &result) override {
903061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishNoResult);
904061da546Spatrick
905061da546Spatrick Args cmd_args(command);
906061da546Spatrick const size_t argc = cmd_args.GetArgumentCount();
907061da546Spatrick
908061da546Spatrick if (argc < 3) {
909061da546Spatrick result.AppendError("'settings insert-after' takes more arguments");
910061da546Spatrick return false;
911061da546Spatrick }
912061da546Spatrick
913061da546Spatrick const char *var_name = cmd_args.GetArgumentAtIndex(0);
914061da546Spatrick if ((var_name == nullptr) || (var_name[0] == '\0')) {
915061da546Spatrick result.AppendError("'settings insert-after' command requires a valid "
916061da546Spatrick "variable name; No value supplied");
917061da546Spatrick return false;
918061da546Spatrick }
919061da546Spatrick
920061da546Spatrick // Split the raw command into var_name, index_value, and value triple.
921061da546Spatrick llvm::StringRef var_value(command);
922061da546Spatrick var_value = var_value.split(var_name).second.trim();
923061da546Spatrick
924061da546Spatrick Status error(GetDebugger().SetPropertyValue(
925061da546Spatrick &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value));
926061da546Spatrick if (error.Fail()) {
927061da546Spatrick result.AppendError(error.AsCString());
928061da546Spatrick return false;
929061da546Spatrick }
930061da546Spatrick
931061da546Spatrick return result.Succeeded();
932061da546Spatrick }
933061da546Spatrick };
934061da546Spatrick
935061da546Spatrick // CommandObjectSettingsAppend
936061da546Spatrick
937061da546Spatrick class CommandObjectSettingsAppend : public CommandObjectRaw {
938061da546Spatrick public:
CommandObjectSettingsAppend(CommandInterpreter & interpreter)939061da546Spatrick CommandObjectSettingsAppend(CommandInterpreter &interpreter)
940061da546Spatrick : CommandObjectRaw(interpreter, "settings append",
941061da546Spatrick "Append one or more values to a debugger array, "
942061da546Spatrick "dictionary, or string setting.") {
943061da546Spatrick CommandArgumentEntry arg1;
944061da546Spatrick CommandArgumentEntry arg2;
945061da546Spatrick CommandArgumentData var_name_arg;
946061da546Spatrick CommandArgumentData value_arg;
947061da546Spatrick
948061da546Spatrick // Define the first (and only) variant of this arg.
949061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName;
950061da546Spatrick var_name_arg.arg_repetition = eArgRepeatPlain;
951061da546Spatrick
952061da546Spatrick // There is only one variant this argument could be; put it into the
953061da546Spatrick // argument entry.
954061da546Spatrick arg1.push_back(var_name_arg);
955061da546Spatrick
956061da546Spatrick // Define the first (and only) variant of this arg.
957061da546Spatrick value_arg.arg_type = eArgTypeValue;
958061da546Spatrick value_arg.arg_repetition = eArgRepeatPlain;
959061da546Spatrick
960061da546Spatrick // There is only one variant this argument could be; put it into the
961061da546Spatrick // argument entry.
962061da546Spatrick arg2.push_back(value_arg);
963061da546Spatrick
964061da546Spatrick // Push the data for the first argument into the m_arguments vector.
965061da546Spatrick m_arguments.push_back(arg1);
966061da546Spatrick m_arguments.push_back(arg2);
967061da546Spatrick }
968061da546Spatrick
969061da546Spatrick ~CommandObjectSettingsAppend() override = default;
970061da546Spatrick
971061da546Spatrick // Overrides base class's behavior where WantsCompletion =
972061da546Spatrick // !WantsRawCommandString.
WantsCompletion()973061da546Spatrick bool WantsCompletion() override { return true; }
974061da546Spatrick
975061da546Spatrick void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)976061da546Spatrick HandleArgumentCompletion(CompletionRequest &request,
977061da546Spatrick OptionElementVector &opt_element_vector) override {
978061da546Spatrick // Attempting to complete variable name
979061da546Spatrick if (request.GetCursorIndex() < 2)
980061da546Spatrick CommandCompletions::InvokeCommonCompletionCallbacks(
981061da546Spatrick GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
982061da546Spatrick request, nullptr);
983061da546Spatrick }
984061da546Spatrick
985061da546Spatrick protected:
DoExecute(llvm::StringRef command,CommandReturnObject & result)986061da546Spatrick bool DoExecute(llvm::StringRef command,
987061da546Spatrick CommandReturnObject &result) override {
988061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishNoResult);
989061da546Spatrick Args cmd_args(command);
990061da546Spatrick const size_t argc = cmd_args.GetArgumentCount();
991061da546Spatrick
992061da546Spatrick if (argc < 2) {
993061da546Spatrick result.AppendError("'settings append' takes more arguments");
994061da546Spatrick return false;
995061da546Spatrick }
996061da546Spatrick
997061da546Spatrick const char *var_name = cmd_args.GetArgumentAtIndex(0);
998061da546Spatrick if ((var_name == nullptr) || (var_name[0] == '\0')) {
999061da546Spatrick result.AppendError("'settings append' command requires a valid variable "
1000061da546Spatrick "name; No value supplied");
1001061da546Spatrick return false;
1002061da546Spatrick }
1003061da546Spatrick
1004061da546Spatrick // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
1005061da546Spatrick // character string later on.
1006061da546Spatrick
1007061da546Spatrick // Split the raw command into var_name and value pair.
1008061da546Spatrick llvm::StringRef var_value(command);
1009061da546Spatrick var_value = var_value.split(var_name).second.trim();
1010061da546Spatrick
1011061da546Spatrick Status error(GetDebugger().SetPropertyValue(
1012061da546Spatrick &m_exe_ctx, eVarSetOperationAppend, var_name, var_value));
1013061da546Spatrick if (error.Fail()) {
1014061da546Spatrick result.AppendError(error.AsCString());
1015061da546Spatrick return false;
1016061da546Spatrick }
1017061da546Spatrick
1018061da546Spatrick return result.Succeeded();
1019061da546Spatrick }
1020061da546Spatrick };
1021061da546Spatrick
1022061da546Spatrick // CommandObjectSettingsClear
1023dda28197Spatrick #define LLDB_OPTIONS_settings_clear
1024dda28197Spatrick #include "CommandOptions.inc"
1025061da546Spatrick
1026061da546Spatrick class CommandObjectSettingsClear : public CommandObjectParsed {
1027061da546Spatrick public:
CommandObjectSettingsClear(CommandInterpreter & interpreter)1028061da546Spatrick CommandObjectSettingsClear(CommandInterpreter &interpreter)
1029061da546Spatrick : CommandObjectParsed(
1030061da546Spatrick interpreter, "settings clear",
1031dda28197Spatrick "Clear a debugger setting array, dictionary, or string. "
1032dda28197Spatrick "If '-a' option is specified, it clears all settings.", nullptr) {
1033061da546Spatrick CommandArgumentEntry arg;
1034061da546Spatrick CommandArgumentData var_name_arg;
1035061da546Spatrick
1036061da546Spatrick // Define the first (and only) variant of this arg.
1037061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName;
1038061da546Spatrick var_name_arg.arg_repetition = eArgRepeatPlain;
1039061da546Spatrick
1040061da546Spatrick // There is only one variant this argument could be; put it into the
1041061da546Spatrick // argument entry.
1042061da546Spatrick arg.push_back(var_name_arg);
1043061da546Spatrick
1044061da546Spatrick // Push the data for the first argument into the m_arguments vector.
1045061da546Spatrick m_arguments.push_back(arg);
1046061da546Spatrick }
1047061da546Spatrick
1048061da546Spatrick ~CommandObjectSettingsClear() override = default;
1049061da546Spatrick
1050061da546Spatrick void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1051061da546Spatrick HandleArgumentCompletion(CompletionRequest &request,
1052061da546Spatrick OptionElementVector &opt_element_vector) override {
1053061da546Spatrick // Attempting to complete variable name
1054061da546Spatrick if (request.GetCursorIndex() < 2)
1055061da546Spatrick CommandCompletions::InvokeCommonCompletionCallbacks(
1056061da546Spatrick GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
1057061da546Spatrick request, nullptr);
1058061da546Spatrick }
1059061da546Spatrick
GetOptions()1060dda28197Spatrick Options *GetOptions() override { return &m_options; }
1061dda28197Spatrick
1062dda28197Spatrick class CommandOptions : public Options {
1063dda28197Spatrick public:
1064dda28197Spatrick CommandOptions() = default;
1065dda28197Spatrick
1066dda28197Spatrick ~CommandOptions() override = default;
1067dda28197Spatrick
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)1068dda28197Spatrick Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1069dda28197Spatrick ExecutionContext *execution_context) override {
1070dda28197Spatrick const int short_option = m_getopt_table[option_idx].val;
1071dda28197Spatrick switch (short_option) {
1072dda28197Spatrick case 'a':
1073dda28197Spatrick m_clear_all = true;
1074dda28197Spatrick break;
1075dda28197Spatrick default:
1076dda28197Spatrick llvm_unreachable("Unimplemented option");
1077dda28197Spatrick }
1078dda28197Spatrick return Status();
1079dda28197Spatrick }
1080dda28197Spatrick
OptionParsingStarting(ExecutionContext * execution_context)1081dda28197Spatrick void OptionParsingStarting(ExecutionContext *execution_context) override {
1082dda28197Spatrick m_clear_all = false;
1083dda28197Spatrick }
1084dda28197Spatrick
GetDefinitions()1085dda28197Spatrick llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1086*f6aab3d8Srobert return llvm::ArrayRef(g_settings_clear_options);
1087dda28197Spatrick }
1088dda28197Spatrick
1089dda28197Spatrick bool m_clear_all = false;
1090dda28197Spatrick };
1091dda28197Spatrick
1092061da546Spatrick protected:
DoExecute(Args & command,CommandReturnObject & result)1093061da546Spatrick bool DoExecute(Args &command, CommandReturnObject &result) override {
1094061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishNoResult);
1095061da546Spatrick const size_t argc = command.GetArgumentCount();
1096061da546Spatrick
1097dda28197Spatrick if (m_options.m_clear_all) {
1098dda28197Spatrick if (argc != 0) {
1099dda28197Spatrick result.AppendError("'settings clear --all' doesn't take any arguments");
1100dda28197Spatrick return false;
1101dda28197Spatrick }
1102dda28197Spatrick GetDebugger().GetValueProperties()->Clear();
1103dda28197Spatrick return result.Succeeded();
1104dda28197Spatrick }
1105dda28197Spatrick
1106061da546Spatrick if (argc != 1) {
1107061da546Spatrick result.AppendError("'settings clear' takes exactly one argument");
1108061da546Spatrick return false;
1109061da546Spatrick }
1110061da546Spatrick
1111061da546Spatrick const char *var_name = command.GetArgumentAtIndex(0);
1112061da546Spatrick if ((var_name == nullptr) || (var_name[0] == '\0')) {
1113061da546Spatrick result.AppendError("'settings clear' command requires a valid variable "
1114061da546Spatrick "name; No value supplied");
1115061da546Spatrick return false;
1116061da546Spatrick }
1117061da546Spatrick
1118061da546Spatrick Status error(GetDebugger().SetPropertyValue(
1119061da546Spatrick &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
1120061da546Spatrick if (error.Fail()) {
1121061da546Spatrick result.AppendError(error.AsCString());
1122061da546Spatrick return false;
1123061da546Spatrick }
1124061da546Spatrick
1125061da546Spatrick return result.Succeeded();
1126061da546Spatrick }
1127dda28197Spatrick
1128dda28197Spatrick private:
1129dda28197Spatrick CommandOptions m_options;
1130061da546Spatrick };
1131061da546Spatrick
1132061da546Spatrick // CommandObjectMultiwordSettings
1133061da546Spatrick
CommandObjectMultiwordSettings(CommandInterpreter & interpreter)1134061da546Spatrick CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
1135061da546Spatrick CommandInterpreter &interpreter)
1136061da546Spatrick : CommandObjectMultiword(interpreter, "settings",
1137061da546Spatrick "Commands for managing LLDB settings.",
1138061da546Spatrick "settings <subcommand> [<command-options>]") {
1139061da546Spatrick LoadSubCommand("set",
1140061da546Spatrick CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
1141061da546Spatrick LoadSubCommand("show",
1142061da546Spatrick CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
1143061da546Spatrick LoadSubCommand("list",
1144061da546Spatrick CommandObjectSP(new CommandObjectSettingsList(interpreter)));
1145061da546Spatrick LoadSubCommand("remove",
1146061da546Spatrick CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
1147061da546Spatrick LoadSubCommand("replace", CommandObjectSP(
1148061da546Spatrick new CommandObjectSettingsReplace(interpreter)));
1149061da546Spatrick LoadSubCommand(
1150061da546Spatrick "insert-before",
1151061da546Spatrick CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
1152061da546Spatrick LoadSubCommand(
1153061da546Spatrick "insert-after",
1154061da546Spatrick CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
1155061da546Spatrick LoadSubCommand("append",
1156061da546Spatrick CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
1157061da546Spatrick LoadSubCommand("clear",
1158061da546Spatrick CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
1159061da546Spatrick LoadSubCommand("write",
1160061da546Spatrick CommandObjectSP(new CommandObjectSettingsWrite(interpreter)));
1161061da546Spatrick LoadSubCommand("read",
1162061da546Spatrick CommandObjectSP(new CommandObjectSettingsRead(interpreter)));
1163061da546Spatrick }
1164061da546Spatrick
1165061da546Spatrick CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default;
1166