blob: b9a7b64f91c4da3729a5d771aae5c27aba2cdc0e [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- CommandObjectSettings.cpp -------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "CommandObjectSettings.h"
10
Eugene Zelenko3f18ea02016-02-24 02:05:55 +000011#include "llvm/ADT/StringRef.h"
12
Zachary Turner3eb2b442017-03-22 23:33:16 +000013#include "lldb/Host/OptionParser.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000014#include "lldb/Interpreter/CommandCompletions.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015#include "lldb/Interpreter/CommandInterpreter.h"
16#include "lldb/Interpreter/CommandReturnObject.h"
Zachary Turner633a29c2015-03-04 01:58:01 +000017#include "lldb/Interpreter/OptionValueProperties.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018
19using namespace lldb;
20using namespace lldb_private;
Jim Ingham5a988412012-06-08 21:56:10 +000021
Jim Ingham5a988412012-06-08 21:56:10 +000022// CommandObjectSettingsSet
Raphael Isemann6f4fb4e2019-07-12 15:30:55 +000023#define LLDB_OPTIONS_settings_set
Raphael Isemannc5a2d742019-07-16 09:27:02 +000024#include "CommandOptions.inc"
Zachary Turner1f0f5b52016-09-22 20:22:55 +000025
Kate Stoneb9c1b512016-09-06 20:57:50 +000026class CommandObjectSettingsSet : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +000027public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000028 CommandObjectSettingsSet(CommandInterpreter &interpreter)
29 : CommandObjectRaw(interpreter, "settings set",
Zachary Turnera4496982016-10-05 21:14:38 +000030 "Set the value of the specified debugger setting."),
Kate Stoneb9c1b512016-09-06 20:57:50 +000031 m_options() {
32 CommandArgumentEntry arg1;
33 CommandArgumentEntry arg2;
34 CommandArgumentData var_name_arg;
35 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +000036
Kate Stoneb9c1b512016-09-06 20:57:50 +000037 // Define the first (and only) variant of this arg.
38 var_name_arg.arg_type = eArgTypeSettingVariableName;
39 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +000040
Kate Stoneb9c1b512016-09-06 20:57:50 +000041 // There is only one variant this argument could be; put it into the
42 // argument entry.
43 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +000044
Kate Stoneb9c1b512016-09-06 20:57:50 +000045 // Define the first (and only) variant of this arg.
46 value_arg.arg_type = eArgTypeValue;
47 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +000048
Kate Stoneb9c1b512016-09-06 20:57:50 +000049 // There is only one variant this argument could be; put it into the
50 // argument entry.
51 arg2.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +000052
Kate Stoneb9c1b512016-09-06 20:57:50 +000053 // Push the data for the first argument into the m_arguments vector.
54 m_arguments.push_back(arg1);
55 m_arguments.push_back(arg2);
56
57 SetHelpLong(
58 "\nWhen setting a dictionary or array variable, you can set multiple entries \
59at once by giving the values to the set command. For example:"
60 R"(
Kate Stoneea671fb2015-07-14 05:48:36 +000061
62(lldb) settings set target.run-args value1 value2 value3
63(lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345
64
65(lldb) settings show target.run-args
66 [0]: 'value1'
67 [1]: 'value2'
68 [3]: 'value3'
69(lldb) settings show target.env-vars
70 'MYPATH=~/.:/usr/bin'
71 'SOME_ENV_VAR=12345'
72
Kate Stoneb9c1b512016-09-06 20:57:50 +000073)"
74 "Warning: The 'set' command re-sets the entire array or dictionary. If you \
Kate Stoneea671fb2015-07-14 05:48:36 +000075just want to add, remove or update individual values (or add something to \
76the end), use one of the other settings sub-commands: append, replace, \
Kate Stoneb9c1b512016-09-06 20:57:50 +000077insert-before or insert-after.");
78 }
Jim Ingham5a988412012-06-08 21:56:10 +000079
Kate Stoneb9c1b512016-09-06 20:57:50 +000080 ~CommandObjectSettingsSet() override = default;
81
82 // Overrides base class's behavior where WantsCompletion =
83 // !WantsRawCommandString.
84 bool WantsCompletion() override { return true; }
85
86 Options *GetOptions() override { return &m_options; }
87
88 class CommandOptions : public Options {
89 public:
90 CommandOptions() : Options(), m_global(false) {}
91
92 ~CommandOptions() override = default;
93
Zachary Turner97206d52017-05-12 04:51:55 +000094 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
95 ExecutionContext *execution_context) override {
96 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +000097 const int short_option = m_getopt_table[option_idx].val;
98
99 switch (short_option) {
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000100 case 'f':
101 m_force = true;
102 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000103 case 'g':
104 m_global = true;
105 break;
106 default:
107 error.SetErrorStringWithFormat("unrecognized options '%c'",
108 short_option);
109 break;
110 }
111
112 return error;
Jim Ingham5a988412012-06-08 21:56:10 +0000113 }
114
Kate Stoneb9c1b512016-09-06 20:57:50 +0000115 void OptionParsingStarting(ExecutionContext *execution_context) override {
116 m_global = false;
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000117 m_force = false;
Jim Ingham5a988412012-06-08 21:56:10 +0000118 }
Jim Ingham5a988412012-06-08 21:56:10 +0000119
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000120 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +0000121 return llvm::makeArrayRef(g_settings_set_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000122 }
Jim Ingham5a988412012-06-08 21:56:10 +0000123
Kate Stoneb9c1b512016-09-06 20:57:50 +0000124 // Instance variables to hold the values for command options.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000125 bool m_global;
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000126 bool m_force;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000127 };
Jim Ingham5a988412012-06-08 21:56:10 +0000128
Raphael Isemannae34ed22019-08-22 07:41:23 +0000129 void
130 HandleArgumentCompletion(CompletionRequest &request,
131 OptionElementVector &opt_element_vector) override {
Jim Ingham5a988412012-06-08 21:56:10 +0000132
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000133 const size_t argc = request.GetParsedLine().GetArgumentCount();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000134 const char *arg = nullptr;
135 int setting_var_idx;
Pavel Labath5f56fca2018-03-09 10:39:40 +0000136 for (setting_var_idx = 0; setting_var_idx < static_cast<int>(argc);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000137 ++setting_var_idx) {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000138 arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000139 if (arg && arg[0] != '-')
140 break; // We found our setting variable name index
Jim Ingham5a988412012-06-08 21:56:10 +0000141 }
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000142 if (request.GetCursorIndex() == setting_var_idx) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000143 // Attempting to complete setting variable name
144 CommandCompletions::InvokeCommonCompletionCallbacks(
145 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000146 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000147 } else {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000148 arg =
149 request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000150
151 if (arg) {
152 if (arg[0] == '-') {
153 // Complete option name
154 } else {
155 // Complete setting value
156 const char *setting_var_name =
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000157 request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
Zachary Turner97206d52017-05-12 04:51:55 +0000158 Status error;
Jonas Devlieghere57179862019-04-27 06:19:42 +0000159 lldb::OptionValueSP value_sp(GetDebugger().GetPropertyValue(
160 &m_exe_ctx, setting_var_name, false, error));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000161 if (value_sp) {
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000162 value_sp->AutoComplete(m_interpreter, request);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163 }
164 }
165 }
166 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000167 }
168
Jim Ingham5a988412012-06-08 21:56:10 +0000169protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000170 bool DoExecute(llvm::StringRef command,
171 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000172 Args cmd_args(command);
Jim Ingham5a988412012-06-08 21:56:10 +0000173
Kate Stoneb9c1b512016-09-06 20:57:50 +0000174 // Process possible options.
175 if (!ParseOptions(cmd_args, result))
176 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000177
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000178 const size_t min_argc = m_options.m_force ? 1 : 2;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000179 const size_t argc = cmd_args.GetArgumentCount();
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000180
181 if ((argc < min_argc) && (!m_options.m_global)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000182 result.AppendError("'settings set' takes more arguments");
183 result.SetStatus(eReturnStatusFailed);
184 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000185 }
Eugene Zelenko3f18ea02016-02-24 02:05:55 +0000186
Kate Stoneb9c1b512016-09-06 20:57:50 +0000187 const char *var_name = cmd_args.GetArgumentAtIndex(0);
188 if ((var_name == nullptr) || (var_name[0] == '\0')) {
189 result.AppendError(
190 "'settings set' command requires a valid variable name");
191 result.SetStatus(eReturnStatusFailed);
192 return false;
193 }
194
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000195 // A missing value corresponds to clearing the setting when "force" is
196 // specified.
197 if (argc == 1 && m_options.m_force) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000198 Status error(GetDebugger().SetPropertyValue(
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000199 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
200 if (error.Fail()) {
201 result.AppendError(error.AsCString());
202 result.SetStatus(eReturnStatusFailed);
203 return false;
204 }
205 return result.Succeeded();
206 }
207
Kate Stoneb9c1b512016-09-06 20:57:50 +0000208 // Split the raw command into var_name and value pair.
209 llvm::StringRef raw_str(command);
210 std::string var_value_string = raw_str.split(var_name).second.str();
211 const char *var_value_cstr =
212 Args::StripSpaces(var_value_string, true, false, false);
213
Zachary Turner97206d52017-05-12 04:51:55 +0000214 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000215 if (m_options.m_global) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000216 error = GetDebugger().SetPropertyValue(nullptr, eVarSetOperationAssign,
217 var_name, var_value_cstr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000218 }
219
220 if (error.Success()) {
221 // FIXME this is the same issue as the one in commands script import
222 // we could be setting target.load-script-from-symbol-file which would
Adrian Prantl05097242018-04-30 16:49:04 +0000223 // cause Python scripts to be loaded, which could run LLDB commands (e.g.
224 // settings set target.process.python-os-plugin-path) and cause a crash
Kate Stoneb9c1b512016-09-06 20:57:50 +0000225 // if we did not clear the command's exe_ctx first
226 ExecutionContext exe_ctx(m_exe_ctx);
227 m_exe_ctx.Clear();
Jonas Devlieghere57179862019-04-27 06:19:42 +0000228 error = GetDebugger().SetPropertyValue(&exe_ctx, eVarSetOperationAssign,
229 var_name, var_value_cstr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000230 }
231
232 if (error.Fail()) {
233 result.AppendError(error.AsCString());
234 result.SetStatus(eReturnStatusFailed);
235 return false;
236 } else {
237 result.SetStatus(eReturnStatusSuccessFinishResult);
238 }
239
240 return result.Succeeded();
241 }
242
Jim Ingham5a988412012-06-08 21:56:10 +0000243private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000244 CommandOptions m_options;
Jim Ingham5a988412012-06-08 21:56:10 +0000245};
246
Jim Ingham5a988412012-06-08 21:56:10 +0000247// CommandObjectSettingsShow -- Show current values
Jim Ingham5a988412012-06-08 21:56:10 +0000248
Kate Stoneb9c1b512016-09-06 20:57:50 +0000249class CommandObjectSettingsShow : public CommandObjectParsed {
Jim Ingham5a988412012-06-08 21:56:10 +0000250public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000251 CommandObjectSettingsShow(CommandInterpreter &interpreter)
252 : CommandObjectParsed(interpreter, "settings show",
253 "Show matching debugger settings and their current "
254 "values. Defaults to showing all settings.",
255 nullptr) {
256 CommandArgumentEntry arg1;
257 CommandArgumentData var_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000258
Kate Stoneb9c1b512016-09-06 20:57:50 +0000259 // Define the first (and only) variant of this arg.
260 var_name_arg.arg_type = eArgTypeSettingVariableName;
261 var_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000262
Kate Stoneb9c1b512016-09-06 20:57:50 +0000263 // There is only one variant this argument could be; put it into the
264 // argument entry.
265 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000266
Kate Stoneb9c1b512016-09-06 20:57:50 +0000267 // Push the data for the first argument into the m_arguments vector.
268 m_arguments.push_back(arg1);
269 }
Jim Ingham5a988412012-06-08 21:56:10 +0000270
Kate Stoneb9c1b512016-09-06 20:57:50 +0000271 ~CommandObjectSettingsShow() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000272
Raphael Isemannae34ed22019-08-22 07:41:23 +0000273 void
274 HandleArgumentCompletion(CompletionRequest &request,
275 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000276 CommandCompletions::InvokeCommonCompletionCallbacks(
277 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000278 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000279 }
Jim Ingham5a988412012-06-08 21:56:10 +0000280
281protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000282 bool DoExecute(Args &args, CommandReturnObject &result) override {
283 result.SetStatus(eReturnStatusSuccessFinishResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000284
Zachary Turner97d2c402016-10-05 23:40:23 +0000285 if (!args.empty()) {
Zachary Turnerd6a24752016-11-22 17:10:15 +0000286 for (const auto &arg : args) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000287 Status error(GetDebugger().DumpPropertyValue(
Zachary Turnerd6a24752016-11-22 17:10:15 +0000288 &m_exe_ctx, result.GetOutputStream(), arg.ref,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000289 OptionValue::eDumpGroupValue));
290 if (error.Success()) {
291 result.GetOutputStream().EOL();
292 } else {
293 result.AppendError(error.AsCString());
294 result.SetStatus(eReturnStatusFailed);
Jim Ingham5a988412012-06-08 21:56:10 +0000295 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000296 }
297 } else {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000298 GetDebugger().DumpAllPropertyValues(&m_exe_ctx, result.GetOutputStream(),
299 OptionValue::eDumpGroupValue);
Jim Ingham5a988412012-06-08 21:56:10 +0000300 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000301
302 return result.Succeeded();
303 }
Jim Ingham5a988412012-06-08 21:56:10 +0000304};
305
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000306// CommandObjectSettingsWrite -- Write settings to file
Raphael Isemann6f4fb4e2019-07-12 15:30:55 +0000307#define LLDB_OPTIONS_settings_write
Raphael Isemannc5a2d742019-07-16 09:27:02 +0000308#include "CommandOptions.inc"
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000309
310class CommandObjectSettingsWrite : public CommandObjectParsed {
311public:
312 CommandObjectSettingsWrite(CommandInterpreter &interpreter)
313 : CommandObjectParsed(
314 interpreter, "settings export",
315 "Write matching debugger settings and their "
316 "current values to a file that can be read in with "
317 "\"settings read\". Defaults to writing all settings.",
318 nullptr),
319 m_options() {
320 CommandArgumentEntry arg1;
321 CommandArgumentData var_name_arg;
322
323 // Define the first (and only) variant of this arg.
324 var_name_arg.arg_type = eArgTypeSettingVariableName;
325 var_name_arg.arg_repetition = eArgRepeatOptional;
326
327 // There is only one variant this argument could be; put it into the
328 // argument entry.
329 arg1.push_back(var_name_arg);
330
331 // Push the data for the first argument into the m_arguments vector.
332 m_arguments.push_back(arg1);
333 }
334
335 ~CommandObjectSettingsWrite() override = default;
336
337 Options *GetOptions() override { return &m_options; }
338
339 class CommandOptions : public Options {
340 public:
341 CommandOptions() : Options() {}
342
343 ~CommandOptions() override = default;
344
345 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
346 ExecutionContext *execution_context) override {
347 Status error;
348 const int short_option = m_getopt_table[option_idx].val;
349
350 switch (short_option) {
351 case 'f':
352 m_filename.assign(option_arg);
353 break;
354 case 'a':
355 m_append = true;
356 break;
357 default:
358 error.SetErrorStringWithFormat("unrecognized option '%c'",
359 short_option);
360 break;
361 }
362
363 return error;
364 }
365
366 void OptionParsingStarting(ExecutionContext *execution_context) override {
367 m_filename.clear();
368 m_append = false;
369 }
370
371 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
372 return llvm::makeArrayRef(g_settings_write_options);
373 }
374
375 // Instance variables to hold the values for command options.
376 std::string m_filename;
377 bool m_append = false;
378 };
379
380protected:
381 bool DoExecute(Args &args, CommandReturnObject &result) override {
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000382 FileSpec file_spec(m_options.m_filename);
383 FileSystem::Instance().Resolve(file_spec);
384 std::string path(file_spec.GetPath());
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000385 uint32_t options = File::OpenOptions::eOpenOptionWrite |
386 File::OpenOptions::eOpenOptionCanCreate;
387 if (m_options.m_append)
388 options |= File::OpenOptions::eOpenOptionAppend;
389 else
390 options |= File::OpenOptions::eOpenOptionTruncate;
391
392 StreamFile out_file(path.c_str(), options,
393 lldb::eFilePermissionsFileDefault);
394
395 if (!out_file.GetFile().IsValid()) {
396 result.AppendErrorWithFormat("%s: unable to write to file", path.c_str());
397 result.SetStatus(eReturnStatusFailed);
398 return false;
399 }
400
401 // Exporting should not be context sensitive.
402 ExecutionContext clean_ctx;
403
404 if (args.empty()) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000405 GetDebugger().DumpAllPropertyValues(&clean_ctx, out_file,
406 OptionValue::eDumpGroupExport);
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000407 return result.Succeeded();
408 }
409
410 for (const auto &arg : args) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000411 Status error(GetDebugger().DumpPropertyValue(
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000412 &clean_ctx, out_file, arg.ref, OptionValue::eDumpGroupExport));
413 if (!error.Success()) {
414 result.AppendError(error.AsCString());
415 result.SetStatus(eReturnStatusFailed);
416 }
417 }
418
419 return result.Succeeded();
420 }
421
422private:
423 CommandOptions m_options;
424};
425
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000426// CommandObjectSettingsRead -- Read settings from file
Raphael Isemann6f4fb4e2019-07-12 15:30:55 +0000427#define LLDB_OPTIONS_settings_read
Raphael Isemannc5a2d742019-07-16 09:27:02 +0000428#include "CommandOptions.inc"
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000429
430class CommandObjectSettingsRead : public CommandObjectParsed {
431public:
432 CommandObjectSettingsRead(CommandInterpreter &interpreter)
433 : CommandObjectParsed(
434 interpreter, "settings read",
435 "Read settings previously saved to a file with \"settings write\".",
436 nullptr),
437 m_options() {}
438
439 ~CommandObjectSettingsRead() override = default;
440
441 Options *GetOptions() override { return &m_options; }
442
443 class CommandOptions : public Options {
444 public:
445 CommandOptions() : Options() {}
446
447 ~CommandOptions() override = default;
448
449 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
450 ExecutionContext *execution_context) override {
451 Status error;
452 const int short_option = m_getopt_table[option_idx].val;
453
454 switch (short_option) {
455 case 'f':
456 m_filename.assign(option_arg);
457 break;
458 default:
459 error.SetErrorStringWithFormat("unrecognized option '%c'",
460 short_option);
461 break;
462 }
463
464 return error;
465 }
466
467 void OptionParsingStarting(ExecutionContext *execution_context) override {
468 m_filename.clear();
469 }
470
471 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
472 return llvm::makeArrayRef(g_settings_read_options);
473 }
474
475 // Instance variables to hold the values for command options.
476 std::string m_filename;
477 };
478
479protected:
480 bool DoExecute(Args &command, CommandReturnObject &result) override {
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000481 FileSpec file(m_options.m_filename);
482 FileSystem::Instance().Resolve(file);
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000483 ExecutionContext clean_ctx;
484 CommandInterpreterRunOptions options;
485 options.SetAddToHistory(false);
486 options.SetEchoCommands(false);
487 options.SetPrintResults(true);
Jonas Devliegherec0b48ab2019-05-08 01:23:47 +0000488 options.SetPrintErrors(true);
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000489 options.SetStopOnError(false);
490 m_interpreter.HandleCommandsFromFile(file, &clean_ctx, options, result);
491 return result.Succeeded();
492 }
493
494private:
495 CommandOptions m_options;
496};
497
Jim Ingham5a988412012-06-08 21:56:10 +0000498// CommandObjectSettingsList -- List settable variables
Jim Ingham5a988412012-06-08 21:56:10 +0000499
Kate Stoneb9c1b512016-09-06 20:57:50 +0000500class CommandObjectSettingsList : public CommandObjectParsed {
Kate Stone7428a182016-07-14 22:03:10 +0000501public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000502 CommandObjectSettingsList(CommandInterpreter &interpreter)
503 : CommandObjectParsed(interpreter, "settings list",
504 "List and describe matching debugger settings. "
505 "Defaults to all listing all settings.",
506 nullptr) {
507 CommandArgumentEntry arg;
508 CommandArgumentData var_name_arg;
509 CommandArgumentData prefix_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000510
Kate Stoneb9c1b512016-09-06 20:57:50 +0000511 // Define the first variant of this arg.
512 var_name_arg.arg_type = eArgTypeSettingVariableName;
513 var_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000514
Kate Stoneb9c1b512016-09-06 20:57:50 +0000515 // Define the second variant of this arg.
516 prefix_name_arg.arg_type = eArgTypeSettingPrefix;
517 prefix_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000518
Kate Stoneb9c1b512016-09-06 20:57:50 +0000519 arg.push_back(var_name_arg);
520 arg.push_back(prefix_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000521
Kate Stoneb9c1b512016-09-06 20:57:50 +0000522 // Push the data for the first argument into the m_arguments vector.
523 m_arguments.push_back(arg);
524 }
Jim Ingham5a988412012-06-08 21:56:10 +0000525
Kate Stoneb9c1b512016-09-06 20:57:50 +0000526 ~CommandObjectSettingsList() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000527
Raphael Isemannae34ed22019-08-22 07:41:23 +0000528 void
529 HandleArgumentCompletion(CompletionRequest &request,
530 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000531 CommandCompletions::InvokeCommonCompletionCallbacks(
532 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000533 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000534 }
Jim Ingham5a988412012-06-08 21:56:10 +0000535
536protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000537 bool DoExecute(Args &args, CommandReturnObject &result) override {
538 result.SetStatus(eReturnStatusSuccessFinishResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000539
Kate Stoneb9c1b512016-09-06 20:57:50 +0000540 const bool will_modify = false;
541 const size_t argc = args.GetArgumentCount();
542 if (argc > 0) {
543 const bool dump_qualified_name = true;
Jim Ingham5a988412012-06-08 21:56:10 +0000544
Zachary Turner97d2c402016-10-05 23:40:23 +0000545 // TODO: Convert to StringRef based enumeration. Requires converting
546 // GetPropertyAtPath first.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000547 for (size_t i = 0; i < argc; ++i) {
548 const char *property_path = args.GetArgumentAtIndex(i);
Greg Clayton67cc0632012-08-22 17:17:09 +0000549
Kate Stoneb9c1b512016-09-06 20:57:50 +0000550 const Property *property =
Jonas Devlieghere57179862019-04-27 06:19:42 +0000551 GetDebugger().GetValueProperties()->GetPropertyAtPath(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000552 &m_exe_ctx, will_modify, property_path);
553
554 if (property) {
555 property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
556 dump_qualified_name);
557 } else {
558 result.AppendErrorWithFormat("invalid property path '%s'",
559 property_path);
560 result.SetStatus(eReturnStatusFailed);
Jim Ingham5a988412012-06-08 21:56:10 +0000561 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000562 }
563 } else {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000564 GetDebugger().DumpAllDescriptions(m_interpreter,
565 result.GetOutputStream());
Jim Ingham5a988412012-06-08 21:56:10 +0000566 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000567
568 return result.Succeeded();
569 }
Jim Ingham5a988412012-06-08 21:56:10 +0000570};
571
Jim Ingham5a988412012-06-08 21:56:10 +0000572// CommandObjectSettingsRemove
Jim Ingham5a988412012-06-08 21:56:10 +0000573
Kate Stoneb9c1b512016-09-06 20:57:50 +0000574class CommandObjectSettingsRemove : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000575public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000576 CommandObjectSettingsRemove(CommandInterpreter &interpreter)
577 : CommandObjectRaw(interpreter, "settings remove",
578 "Remove a value from a setting, specified by array "
Zachary Turnera4496982016-10-05 21:14:38 +0000579 "index or dictionary key.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000580 CommandArgumentEntry arg1;
581 CommandArgumentEntry arg2;
582 CommandArgumentData var_name_arg;
583 CommandArgumentData index_arg;
584 CommandArgumentData key_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000585
Kate Stoneb9c1b512016-09-06 20:57:50 +0000586 // Define the first (and only) variant of this arg.
587 var_name_arg.arg_type = eArgTypeSettingVariableName;
588 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000589
Kate Stoneb9c1b512016-09-06 20:57:50 +0000590 // There is only one variant this argument could be; put it into the
591 // argument entry.
592 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000593
Kate Stoneb9c1b512016-09-06 20:57:50 +0000594 // Define the first variant of this arg.
595 index_arg.arg_type = eArgTypeSettingIndex;
596 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000597
Kate Stoneb9c1b512016-09-06 20:57:50 +0000598 // Define the second variant of this arg.
599 key_arg.arg_type = eArgTypeSettingKey;
600 key_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000601
Kate Stoneb9c1b512016-09-06 20:57:50 +0000602 // Push both variants into this arg
603 arg2.push_back(index_arg);
604 arg2.push_back(key_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000605
Kate Stoneb9c1b512016-09-06 20:57:50 +0000606 // Push the data for the first argument into the m_arguments vector.
607 m_arguments.push_back(arg1);
608 m_arguments.push_back(arg2);
609 }
Jim Ingham5a988412012-06-08 21:56:10 +0000610
Kate Stoneb9c1b512016-09-06 20:57:50 +0000611 ~CommandObjectSettingsRemove() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000612
Raphael Isemann006d22d2019-08-21 12:57:06 +0000613 bool WantsCompletion() override { return true; }
614
Raphael Isemannae34ed22019-08-22 07:41:23 +0000615 void
616 HandleArgumentCompletion(CompletionRequest &request,
617 OptionElementVector &opt_element_vector) override {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000618 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000619 CommandCompletions::InvokeCommonCompletionCallbacks(
620 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000621 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000622 }
Jim Ingham5a988412012-06-08 21:56:10 +0000623
624protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000625 bool DoExecute(llvm::StringRef command,
626 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000627 result.SetStatus(eReturnStatusSuccessFinishNoResult);
628
629 Args cmd_args(command);
630
631 // Process possible options.
632 if (!ParseOptions(cmd_args, result))
633 return false;
634
635 const size_t argc = cmd_args.GetArgumentCount();
636 if (argc == 0) {
Raphael Isemann34a04e72019-08-21 13:24:21 +0000637 result.AppendError("'settings remove' takes an array or dictionary item, "
638 "or an array followed by one or more indexes, or a "
Kate Stoneb9c1b512016-09-06 20:57:50 +0000639 "dictionary followed by one or more key names to "
640 "remove");
641 result.SetStatus(eReturnStatusFailed);
642 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000643 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000644
645 const char *var_name = cmd_args.GetArgumentAtIndex(0);
646 if ((var_name == nullptr) || (var_name[0] == '\0')) {
647 result.AppendError(
Raphael Isemann34a04e72019-08-21 13:24:21 +0000648 "'settings remove' command requires a valid variable name");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000649 result.SetStatus(eReturnStatusFailed);
650 return false;
651 }
652
653 // Split the raw command into var_name and value pair.
654 llvm::StringRef raw_str(command);
655 std::string var_value_string = raw_str.split(var_name).second.str();
656 const char *var_value_cstr =
657 Args::StripSpaces(var_value_string, true, true, false);
658
Jonas Devlieghere57179862019-04-27 06:19:42 +0000659 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000660 &m_exe_ctx, eVarSetOperationRemove, var_name, var_value_cstr));
661 if (error.Fail()) {
662 result.AppendError(error.AsCString());
663 result.SetStatus(eReturnStatusFailed);
664 return false;
665 }
666
667 return result.Succeeded();
668 }
Jim Ingham5a988412012-06-08 21:56:10 +0000669};
670
Jim Ingham5a988412012-06-08 21:56:10 +0000671// CommandObjectSettingsReplace
Jim Ingham5a988412012-06-08 21:56:10 +0000672
Kate Stoneb9c1b512016-09-06 20:57:50 +0000673class CommandObjectSettingsReplace : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000674public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000675 CommandObjectSettingsReplace(CommandInterpreter &interpreter)
676 : CommandObjectRaw(interpreter, "settings replace",
677 "Replace the debugger setting value specified by "
Zachary Turnera4496982016-10-05 21:14:38 +0000678 "array index or dictionary key.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000679 CommandArgumentEntry arg1;
680 CommandArgumentEntry arg2;
681 CommandArgumentEntry arg3;
682 CommandArgumentData var_name_arg;
683 CommandArgumentData index_arg;
684 CommandArgumentData key_arg;
685 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000686
Kate Stoneb9c1b512016-09-06 20:57:50 +0000687 // Define the first (and only) variant of this arg.
688 var_name_arg.arg_type = eArgTypeSettingVariableName;
689 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000690
Kate Stoneb9c1b512016-09-06 20:57:50 +0000691 // There is only one variant this argument could be; put it into the
692 // argument entry.
693 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000694
Kate Stoneb9c1b512016-09-06 20:57:50 +0000695 // Define the first (variant of this arg.
696 index_arg.arg_type = eArgTypeSettingIndex;
697 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000698
Kate Stoneb9c1b512016-09-06 20:57:50 +0000699 // Define the second (variant of this arg.
700 key_arg.arg_type = eArgTypeSettingKey;
701 key_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000702
Kate Stoneb9c1b512016-09-06 20:57:50 +0000703 // Put both variants into this arg
704 arg2.push_back(index_arg);
705 arg2.push_back(key_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000706
Kate Stoneb9c1b512016-09-06 20:57:50 +0000707 // Define the first (and only) variant of this arg.
708 value_arg.arg_type = eArgTypeValue;
709 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000710
Kate Stoneb9c1b512016-09-06 20:57:50 +0000711 // There is only one variant this argument could be; put it into the
712 // argument entry.
713 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000714
Kate Stoneb9c1b512016-09-06 20:57:50 +0000715 // Push the data for the first argument into the m_arguments vector.
716 m_arguments.push_back(arg1);
717 m_arguments.push_back(arg2);
718 m_arguments.push_back(arg3);
719 }
Jim Ingham5a988412012-06-08 21:56:10 +0000720
Kate Stoneb9c1b512016-09-06 20:57:50 +0000721 ~CommandObjectSettingsReplace() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000722
Kate Stoneb9c1b512016-09-06 20:57:50 +0000723 // Overrides base class's behavior where WantsCompletion =
724 // !WantsRawCommandString.
725 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000726
Raphael Isemannae34ed22019-08-22 07:41:23 +0000727 void
728 HandleArgumentCompletion(CompletionRequest &request,
729 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000730 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000731 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000732 CommandCompletions::InvokeCommonCompletionCallbacks(
733 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000734 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000735 }
Jim Ingham5a988412012-06-08 21:56:10 +0000736
737protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000738 bool DoExecute(llvm::StringRef command,
739 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000740 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000741
Kate Stoneb9c1b512016-09-06 20:57:50 +0000742 Args cmd_args(command);
743 const char *var_name = cmd_args.GetArgumentAtIndex(0);
744 if ((var_name == nullptr) || (var_name[0] == '\0')) {
745 result.AppendError("'settings replace' command requires a valid variable "
746 "name; No value supplied");
747 result.SetStatus(eReturnStatusFailed);
748 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000749 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000750
751 // Split the raw command into var_name, index_value, and value triple.
752 llvm::StringRef raw_str(command);
753 std::string var_value_string = raw_str.split(var_name).second.str();
754 const char *var_value_cstr =
755 Args::StripSpaces(var_value_string, true, true, false);
756
Jonas Devlieghere57179862019-04-27 06:19:42 +0000757 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000758 &m_exe_ctx, eVarSetOperationReplace, var_name, var_value_cstr));
759 if (error.Fail()) {
760 result.AppendError(error.AsCString());
761 result.SetStatus(eReturnStatusFailed);
762 return false;
763 } else {
764 result.SetStatus(eReturnStatusSuccessFinishNoResult);
765 }
766
767 return result.Succeeded();
768 }
Jim Ingham5a988412012-06-08 21:56:10 +0000769};
770
Jim Ingham5a988412012-06-08 21:56:10 +0000771// CommandObjectSettingsInsertBefore
Jim Ingham5a988412012-06-08 21:56:10 +0000772
Kate Stoneb9c1b512016-09-06 20:57:50 +0000773class CommandObjectSettingsInsertBefore : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000774public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000775 CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
776 : CommandObjectRaw(interpreter, "settings insert-before",
777 "Insert one or more values into an debugger array "
778 "setting immediately before the specified element "
Zachary Turnera4496982016-10-05 21:14:38 +0000779 "index.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000780 CommandArgumentEntry arg1;
781 CommandArgumentEntry arg2;
782 CommandArgumentEntry arg3;
783 CommandArgumentData var_name_arg;
784 CommandArgumentData index_arg;
785 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000786
Kate Stoneb9c1b512016-09-06 20:57:50 +0000787 // Define the first (and only) variant of this arg.
788 var_name_arg.arg_type = eArgTypeSettingVariableName;
789 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000790
Kate Stoneb9c1b512016-09-06 20:57:50 +0000791 // There is only one variant this argument could be; put it into the
792 // argument entry.
793 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000794
Kate Stoneb9c1b512016-09-06 20:57:50 +0000795 // Define the first (variant of this arg.
796 index_arg.arg_type = eArgTypeSettingIndex;
797 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000798
Kate Stoneb9c1b512016-09-06 20:57:50 +0000799 // There is only one variant this argument could be; put it into the
800 // argument entry.
801 arg2.push_back(index_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000802
Kate Stoneb9c1b512016-09-06 20:57:50 +0000803 // Define the first (and only) variant of this arg.
804 value_arg.arg_type = eArgTypeValue;
805 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000806
Kate Stoneb9c1b512016-09-06 20:57:50 +0000807 // There is only one variant this argument could be; put it into the
808 // argument entry.
809 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000810
Kate Stoneb9c1b512016-09-06 20:57:50 +0000811 // Push the data for the first argument into the m_arguments vector.
812 m_arguments.push_back(arg1);
813 m_arguments.push_back(arg2);
814 m_arguments.push_back(arg3);
815 }
Jim Ingham5a988412012-06-08 21:56:10 +0000816
Kate Stoneb9c1b512016-09-06 20:57:50 +0000817 ~CommandObjectSettingsInsertBefore() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000818
Kate Stoneb9c1b512016-09-06 20:57:50 +0000819 // Overrides base class's behavior where WantsCompletion =
820 // !WantsRawCommandString.
821 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000822
Raphael Isemannae34ed22019-08-22 07:41:23 +0000823 void
824 HandleArgumentCompletion(CompletionRequest &request,
825 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000826 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000827 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000828 CommandCompletions::InvokeCommonCompletionCallbacks(
829 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000830 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000831 }
Jim Ingham5a988412012-06-08 21:56:10 +0000832
833protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000834 bool DoExecute(llvm::StringRef command,
835 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000836 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000837
Kate Stoneb9c1b512016-09-06 20:57:50 +0000838 Args cmd_args(command);
839 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +0000840
Kate Stoneb9c1b512016-09-06 20:57:50 +0000841 if (argc < 3) {
842 result.AppendError("'settings insert-before' takes more arguments");
843 result.SetStatus(eReturnStatusFailed);
844 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000845 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000846
847 const char *var_name = cmd_args.GetArgumentAtIndex(0);
848 if ((var_name == nullptr) || (var_name[0] == '\0')) {
849 result.AppendError("'settings insert-before' command requires a valid "
850 "variable name; No value supplied");
851 result.SetStatus(eReturnStatusFailed);
852 return false;
853 }
854
855 // Split the raw command into var_name, index_value, and value triple.
856 llvm::StringRef raw_str(command);
857 std::string var_value_string = raw_str.split(var_name).second.str();
858 const char *var_value_cstr =
859 Args::StripSpaces(var_value_string, true, true, false);
860
Jonas Devlieghere57179862019-04-27 06:19:42 +0000861 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000862 &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value_cstr));
863 if (error.Fail()) {
864 result.AppendError(error.AsCString());
865 result.SetStatus(eReturnStatusFailed);
866 return false;
867 }
868
869 return result.Succeeded();
870 }
Jim Ingham5a988412012-06-08 21:56:10 +0000871};
872
Jim Ingham5a988412012-06-08 21:56:10 +0000873// CommandObjectSettingInsertAfter
Jim Ingham5a988412012-06-08 21:56:10 +0000874
Kate Stoneb9c1b512016-09-06 20:57:50 +0000875class CommandObjectSettingsInsertAfter : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000876public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000877 CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
878 : CommandObjectRaw(interpreter, "settings insert-after",
879 "Insert one or more values into a debugger array "
Zachary Turnera4496982016-10-05 21:14:38 +0000880 "settings after the specified element index.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000881 CommandArgumentEntry arg1;
882 CommandArgumentEntry arg2;
883 CommandArgumentEntry arg3;
884 CommandArgumentData var_name_arg;
885 CommandArgumentData index_arg;
886 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000887
Kate Stoneb9c1b512016-09-06 20:57:50 +0000888 // Define the first (and only) variant of this arg.
889 var_name_arg.arg_type = eArgTypeSettingVariableName;
890 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000891
Kate Stoneb9c1b512016-09-06 20:57:50 +0000892 // There is only one variant this argument could be; put it into the
893 // argument entry.
894 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000895
Kate Stoneb9c1b512016-09-06 20:57:50 +0000896 // Define the first (variant of this arg.
897 index_arg.arg_type = eArgTypeSettingIndex;
898 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000899
Kate Stoneb9c1b512016-09-06 20:57:50 +0000900 // There is only one variant this argument could be; put it into the
901 // argument entry.
902 arg2.push_back(index_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000903
Kate Stoneb9c1b512016-09-06 20:57:50 +0000904 // Define the first (and only) variant of this arg.
905 value_arg.arg_type = eArgTypeValue;
906 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000907
Kate Stoneb9c1b512016-09-06 20:57:50 +0000908 // There is only one variant this argument could be; put it into the
909 // argument entry.
910 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000911
Kate Stoneb9c1b512016-09-06 20:57:50 +0000912 // Push the data for the first argument into the m_arguments vector.
913 m_arguments.push_back(arg1);
914 m_arguments.push_back(arg2);
915 m_arguments.push_back(arg3);
916 }
Jim Ingham5a988412012-06-08 21:56:10 +0000917
Kate Stoneb9c1b512016-09-06 20:57:50 +0000918 ~CommandObjectSettingsInsertAfter() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000919
Kate Stoneb9c1b512016-09-06 20:57:50 +0000920 // Overrides base class's behavior where WantsCompletion =
921 // !WantsRawCommandString.
922 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000923
Raphael Isemannae34ed22019-08-22 07:41:23 +0000924 void
925 HandleArgumentCompletion(CompletionRequest &request,
926 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000927 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000928 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000929 CommandCompletions::InvokeCommonCompletionCallbacks(
930 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000931 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000932 }
933
Jim Ingham5a988412012-06-08 21:56:10 +0000934protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000935 bool DoExecute(llvm::StringRef command,
936 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000937 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000938
Kate Stoneb9c1b512016-09-06 20:57:50 +0000939 Args cmd_args(command);
940 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +0000941
Kate Stoneb9c1b512016-09-06 20:57:50 +0000942 if (argc < 3) {
943 result.AppendError("'settings insert-after' takes more arguments");
944 result.SetStatus(eReturnStatusFailed);
945 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000946 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000947
948 const char *var_name = cmd_args.GetArgumentAtIndex(0);
949 if ((var_name == nullptr) || (var_name[0] == '\0')) {
950 result.AppendError("'settings insert-after' command requires a valid "
951 "variable name; No value supplied");
952 result.SetStatus(eReturnStatusFailed);
953 return false;
954 }
955
956 // Split the raw command into var_name, index_value, and value triple.
957 llvm::StringRef raw_str(command);
958 std::string var_value_string = raw_str.split(var_name).second.str();
959 const char *var_value_cstr =
960 Args::StripSpaces(var_value_string, true, true, false);
961
Jonas Devlieghere57179862019-04-27 06:19:42 +0000962 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000963 &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value_cstr));
964 if (error.Fail()) {
965 result.AppendError(error.AsCString());
966 result.SetStatus(eReturnStatusFailed);
967 return false;
968 }
969
970 return result.Succeeded();
971 }
Jim Ingham5a988412012-06-08 21:56:10 +0000972};
973
Jim Ingham5a988412012-06-08 21:56:10 +0000974// CommandObjectSettingsAppend
Jim Ingham5a988412012-06-08 21:56:10 +0000975
Kate Stoneb9c1b512016-09-06 20:57:50 +0000976class CommandObjectSettingsAppend : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000977public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000978 CommandObjectSettingsAppend(CommandInterpreter &interpreter)
979 : CommandObjectRaw(interpreter, "settings append",
980 "Append one or more values to a debugger array, "
Zachary Turnera4496982016-10-05 21:14:38 +0000981 "dictionary, or string setting.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000982 CommandArgumentEntry arg1;
983 CommandArgumentEntry arg2;
984 CommandArgumentData var_name_arg;
985 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000986
Kate Stoneb9c1b512016-09-06 20:57:50 +0000987 // Define the first (and only) variant of this arg.
988 var_name_arg.arg_type = eArgTypeSettingVariableName;
989 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000990
Kate Stoneb9c1b512016-09-06 20:57:50 +0000991 // There is only one variant this argument could be; put it into the
992 // argument entry.
993 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000994
Kate Stoneb9c1b512016-09-06 20:57:50 +0000995 // Define the first (and only) variant of this arg.
996 value_arg.arg_type = eArgTypeValue;
997 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000998
Kate Stoneb9c1b512016-09-06 20:57:50 +0000999 // There is only one variant this argument could be; put it into the
1000 // argument entry.
1001 arg2.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001002
Kate Stoneb9c1b512016-09-06 20:57:50 +00001003 // Push the data for the first argument into the m_arguments vector.
1004 m_arguments.push_back(arg1);
1005 m_arguments.push_back(arg2);
1006 }
Jim Ingham5a988412012-06-08 21:56:10 +00001007
Kate Stoneb9c1b512016-09-06 20:57:50 +00001008 ~CommandObjectSettingsAppend() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001009
Kate Stoneb9c1b512016-09-06 20:57:50 +00001010 // Overrides base class's behavior where WantsCompletion =
1011 // !WantsRawCommandString.
1012 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +00001013
Raphael Isemannae34ed22019-08-22 07:41:23 +00001014 void
1015 HandleArgumentCompletion(CompletionRequest &request,
1016 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001017 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001018 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001019 CommandCompletions::InvokeCommonCompletionCallbacks(
1020 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +00001021 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001022 }
Jim Ingham5a988412012-06-08 21:56:10 +00001023
1024protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +00001025 bool DoExecute(llvm::StringRef command,
1026 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001027 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1028 Args cmd_args(command);
1029 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +00001030
Kate Stoneb9c1b512016-09-06 20:57:50 +00001031 if (argc < 2) {
1032 result.AppendError("'settings append' takes more arguments");
1033 result.SetStatus(eReturnStatusFailed);
1034 return false;
Jim Ingham5a988412012-06-08 21:56:10 +00001035 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001036
1037 const char *var_name = cmd_args.GetArgumentAtIndex(0);
1038 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1039 result.AppendError("'settings append' command requires a valid variable "
1040 "name; No value supplied");
1041 result.SetStatus(eReturnStatusFailed);
1042 return false;
1043 }
1044
Adrian Prantl05097242018-04-30 16:49:04 +00001045 // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
1046 // character string later on.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001047
1048 // Split the raw command into var_name and value pair.
1049 llvm::StringRef raw_str(command);
1050 std::string var_value_string = raw_str.split(var_name).second.str();
1051 const char *var_value_cstr =
1052 Args::StripSpaces(var_value_string, true, true, false);
1053
Jonas Devlieghere57179862019-04-27 06:19:42 +00001054 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001055 &m_exe_ctx, eVarSetOperationAppend, var_name, var_value_cstr));
1056 if (error.Fail()) {
1057 result.AppendError(error.AsCString());
1058 result.SetStatus(eReturnStatusFailed);
1059 return false;
1060 }
1061
1062 return result.Succeeded();
1063 }
Jim Ingham5a988412012-06-08 21:56:10 +00001064};
1065
Jim Ingham5a988412012-06-08 21:56:10 +00001066// CommandObjectSettingsClear
Jim Ingham5a988412012-06-08 21:56:10 +00001067
Kate Stoneb9c1b512016-09-06 20:57:50 +00001068class CommandObjectSettingsClear : public CommandObjectParsed {
Jim Ingham5a988412012-06-08 21:56:10 +00001069public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001070 CommandObjectSettingsClear(CommandInterpreter &interpreter)
1071 : CommandObjectParsed(
1072 interpreter, "settings clear",
1073 "Clear a debugger setting array, dictionary, or string.", nullptr) {
1074 CommandArgumentEntry arg;
1075 CommandArgumentData var_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +00001076
Kate Stoneb9c1b512016-09-06 20:57:50 +00001077 // Define the first (and only) variant of this arg.
1078 var_name_arg.arg_type = eArgTypeSettingVariableName;
1079 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +00001080
Kate Stoneb9c1b512016-09-06 20:57:50 +00001081 // There is only one variant this argument could be; put it into the
1082 // argument entry.
1083 arg.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001084
Kate Stoneb9c1b512016-09-06 20:57:50 +00001085 // Push the data for the first argument into the m_arguments vector.
1086 m_arguments.push_back(arg);
1087 }
Jim Ingham5a988412012-06-08 21:56:10 +00001088
Kate Stoneb9c1b512016-09-06 20:57:50 +00001089 ~CommandObjectSettingsClear() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001090
Raphael Isemannae34ed22019-08-22 07:41:23 +00001091 void
1092 HandleArgumentCompletion(CompletionRequest &request,
1093 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001094 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001095 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001096 CommandCompletions::InvokeCommonCompletionCallbacks(
1097 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +00001098 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001099 }
Jim Ingham5a988412012-06-08 21:56:10 +00001100
1101protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001102 bool DoExecute(Args &command, CommandReturnObject &result) override {
1103 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1104 const size_t argc = command.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +00001105
Kate Stoneb9c1b512016-09-06 20:57:50 +00001106 if (argc != 1) {
1107 result.AppendError("'settings clear' takes exactly one argument");
1108 result.SetStatus(eReturnStatusFailed);
1109 return false;
Jim Ingham5a988412012-06-08 21:56:10 +00001110 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001111
1112 const char *var_name = command.GetArgumentAtIndex(0);
1113 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1114 result.AppendError("'settings clear' command requires a valid variable "
1115 "name; No value supplied");
1116 result.SetStatus(eReturnStatusFailed);
1117 return false;
1118 }
1119
Jonas Devlieghere57179862019-04-27 06:19:42 +00001120 Status error(GetDebugger().SetPropertyValue(
Zachary Turner31d97a52016-11-17 18:08:12 +00001121 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001122 if (error.Fail()) {
1123 result.AppendError(error.AsCString());
1124 result.SetStatus(eReturnStatusFailed);
1125 return false;
1126 }
1127
1128 return result.Succeeded();
1129 }
Jim Ingham5a988412012-06-08 21:56:10 +00001130};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001131
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001132// CommandObjectMultiwordSettings
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001133
Kate Stoneb9c1b512016-09-06 20:57:50 +00001134CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
1135 CommandInterpreter &interpreter)
1136 : CommandObjectMultiword(interpreter, "settings",
1137 "Commands for managing LLDB settings.",
1138 "settings <subcommand> [<command-options>]") {
1139 LoadSubCommand("set",
1140 CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
1141 LoadSubCommand("show",
1142 CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
1143 LoadSubCommand("list",
1144 CommandObjectSP(new CommandObjectSettingsList(interpreter)));
1145 LoadSubCommand("remove",
1146 CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
1147 LoadSubCommand("replace", CommandObjectSP(
1148 new CommandObjectSettingsReplace(interpreter)));
1149 LoadSubCommand(
1150 "insert-before",
1151 CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
1152 LoadSubCommand(
1153 "insert-after",
1154 CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
1155 LoadSubCommand("append",
1156 CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
1157 LoadSubCommand("clear",
1158 CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +00001159 LoadSubCommand("write",
1160 CommandObjectSP(new CommandObjectSettingsWrite(interpreter)));
1161 LoadSubCommand("read",
1162 CommandObjectSP(new CommandObjectSettingsRead(interpreter)));
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001163}
1164
Eugene Zelenko3f18ea02016-02-24 02:05:55 +00001165CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default;