blob: 48ce3753fc29bc0f6556d08d2d0932f2647e16b2 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- CommandObjectSettings.cpp -------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectSettings.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
Eugene Zelenko3f18ea02016-02-24 02:05:55 +000015#include "llvm/ADT/StringRef.h"
16
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017// Project includes
Zachary Turner3eb2b442017-03-22 23:33:16 +000018#include "lldb/Host/OptionParser.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000019#include "lldb/Interpreter/CommandCompletions.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020#include "lldb/Interpreter/CommandInterpreter.h"
21#include "lldb/Interpreter/CommandReturnObject.h"
Zachary Turner633a29c2015-03-04 01:58:01 +000022#include "lldb/Interpreter/OptionValueProperties.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023
24using namespace lldb;
25using namespace lldb_private;
Jim Ingham5a988412012-06-08 21:56:10 +000026
Jim Ingham5a988412012-06-08 21:56:10 +000027//-------------------------------------------------------------------------
28// CommandObjectSettingsSet
29//-------------------------------------------------------------------------
30
Tatyana Krasnukha8fe53c492018-09-26 18:50:19 +000031static constexpr OptionDefinition g_settings_set_options[] = {
Zachary Turner1f0f5b52016-09-22 20:22:55 +000032 // clang-format off
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +000033 { LLDB_OPT_SET_2, false, "global", 'g', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Apply the new value to the global default value." },
34 { LLDB_OPT_SET_2, false, "force", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Force an empty value to be accepted as the default." }
Zachary Turner1f0f5b52016-09-22 20:22:55 +000035 // clang-format on
36};
37
Kate Stoneb9c1b512016-09-06 20:57:50 +000038class CommandObjectSettingsSet : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +000039public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000040 CommandObjectSettingsSet(CommandInterpreter &interpreter)
41 : CommandObjectRaw(interpreter, "settings set",
Zachary Turnera4496982016-10-05 21:14:38 +000042 "Set the value of the specified debugger setting."),
Kate Stoneb9c1b512016-09-06 20:57:50 +000043 m_options() {
44 CommandArgumentEntry arg1;
45 CommandArgumentEntry arg2;
46 CommandArgumentData var_name_arg;
47 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +000048
Kate Stoneb9c1b512016-09-06 20:57:50 +000049 // Define the first (and only) variant of this arg.
50 var_name_arg.arg_type = eArgTypeSettingVariableName;
51 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +000052
Kate Stoneb9c1b512016-09-06 20:57:50 +000053 // There is only one variant this argument could be; put it into the
54 // argument entry.
55 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +000056
Kate Stoneb9c1b512016-09-06 20:57:50 +000057 // Define the first (and only) variant of this arg.
58 value_arg.arg_type = eArgTypeValue;
59 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +000060
Kate Stoneb9c1b512016-09-06 20:57:50 +000061 // There is only one variant this argument could be; put it into the
62 // argument entry.
63 arg2.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +000064
Kate Stoneb9c1b512016-09-06 20:57:50 +000065 // Push the data for the first argument into the m_arguments vector.
66 m_arguments.push_back(arg1);
67 m_arguments.push_back(arg2);
68
69 SetHelpLong(
70 "\nWhen setting a dictionary or array variable, you can set multiple entries \
71at once by giving the values to the set command. For example:"
72 R"(
Kate Stoneea671fb2015-07-14 05:48:36 +000073
74(lldb) settings set target.run-args value1 value2 value3
75(lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345
76
77(lldb) settings show target.run-args
78 [0]: 'value1'
79 [1]: 'value2'
80 [3]: 'value3'
81(lldb) settings show target.env-vars
82 'MYPATH=~/.:/usr/bin'
83 'SOME_ENV_VAR=12345'
84
Kate Stoneb9c1b512016-09-06 20:57:50 +000085)"
86 "Warning: The 'set' command re-sets the entire array or dictionary. If you \
Kate Stoneea671fb2015-07-14 05:48:36 +000087just want to add, remove or update individual values (or add something to \
88the end), use one of the other settings sub-commands: append, replace, \
Kate Stoneb9c1b512016-09-06 20:57:50 +000089insert-before or insert-after.");
90 }
Jim Ingham5a988412012-06-08 21:56:10 +000091
Kate Stoneb9c1b512016-09-06 20:57:50 +000092 ~CommandObjectSettingsSet() override = default;
93
94 // Overrides base class's behavior where WantsCompletion =
95 // !WantsRawCommandString.
96 bool WantsCompletion() override { return true; }
97
98 Options *GetOptions() override { return &m_options; }
99
100 class CommandOptions : public Options {
101 public:
102 CommandOptions() : Options(), m_global(false) {}
103
104 ~CommandOptions() override = default;
105
Zachary Turner97206d52017-05-12 04:51:55 +0000106 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
107 ExecutionContext *execution_context) override {
108 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109 const int short_option = m_getopt_table[option_idx].val;
110
111 switch (short_option) {
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000112 case 'f':
113 m_force = true;
114 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000115 case 'g':
116 m_global = true;
117 break;
118 default:
119 error.SetErrorStringWithFormat("unrecognized options '%c'",
120 short_option);
121 break;
122 }
123
124 return error;
Jim Ingham5a988412012-06-08 21:56:10 +0000125 }
126
Kate Stoneb9c1b512016-09-06 20:57:50 +0000127 void OptionParsingStarting(ExecutionContext *execution_context) override {
128 m_global = false;
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000129 m_force = false;
Jim Ingham5a988412012-06-08 21:56:10 +0000130 }
Jim Ingham5a988412012-06-08 21:56:10 +0000131
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000132 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +0000133 return llvm::makeArrayRef(g_settings_set_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000134 }
Jim Ingham5a988412012-06-08 21:56:10 +0000135
Kate Stoneb9c1b512016-09-06 20:57:50 +0000136 // Instance variables to hold the values for command options.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000137 bool m_global;
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000138 bool m_force;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000139 };
Jim Ingham5a988412012-06-08 21:56:10 +0000140
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000141 int HandleArgumentCompletion(
142 CompletionRequest &request,
143 OptionElementVector &opt_element_vector) override {
Jim Ingham5a988412012-06-08 21:56:10 +0000144
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000145 const size_t argc = request.GetParsedLine().GetArgumentCount();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000146 const char *arg = nullptr;
147 int setting_var_idx;
Pavel Labath5f56fca2018-03-09 10:39:40 +0000148 for (setting_var_idx = 0; setting_var_idx < static_cast<int>(argc);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000149 ++setting_var_idx) {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000150 arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000151 if (arg && arg[0] != '-')
152 break; // We found our setting variable name index
Jim Ingham5a988412012-06-08 21:56:10 +0000153 }
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000154 if (request.GetCursorIndex() == setting_var_idx) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000155 // Attempting to complete setting variable name
156 CommandCompletions::InvokeCommonCompletionCallbacks(
157 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000158 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000159 } else {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000160 arg =
161 request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000162
163 if (arg) {
164 if (arg[0] == '-') {
165 // Complete option name
166 } else {
167 // Complete setting value
168 const char *setting_var_name =
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000169 request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
Zachary Turner97206d52017-05-12 04:51:55 +0000170 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000171 lldb::OptionValueSP value_sp(
172 m_interpreter.GetDebugger().GetPropertyValue(
173 &m_exe_ctx, setting_var_name, false, error));
174 if (value_sp) {
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000175 value_sp->AutoComplete(m_interpreter, request);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000176 }
177 }
178 }
179 }
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000180 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000181 }
182
Jim Ingham5a988412012-06-08 21:56:10 +0000183protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000184 bool DoExecute(llvm::StringRef command,
185 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000186 Args cmd_args(command);
Jim Ingham5a988412012-06-08 21:56:10 +0000187
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188 // Process possible options.
189 if (!ParseOptions(cmd_args, result))
190 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000191
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000192 const size_t min_argc = m_options.m_force ? 1 : 2;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193 const size_t argc = cmd_args.GetArgumentCount();
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000194
195 if ((argc < min_argc) && (!m_options.m_global)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000196 result.AppendError("'settings set' takes more arguments");
197 result.SetStatus(eReturnStatusFailed);
198 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000199 }
Eugene Zelenko3f18ea02016-02-24 02:05:55 +0000200
Kate Stoneb9c1b512016-09-06 20:57:50 +0000201 const char *var_name = cmd_args.GetArgumentAtIndex(0);
202 if ((var_name == nullptr) || (var_name[0] == '\0')) {
203 result.AppendError(
204 "'settings set' command requires a valid variable name");
205 result.SetStatus(eReturnStatusFailed);
206 return false;
207 }
208
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000209 // A missing value corresponds to clearing the setting when "force" is
210 // specified.
211 if (argc == 1 && m_options.m_force) {
212 Status error(m_interpreter.GetDebugger().SetPropertyValue(
213 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
214 if (error.Fail()) {
215 result.AppendError(error.AsCString());
216 result.SetStatus(eReturnStatusFailed);
217 return false;
218 }
219 return result.Succeeded();
220 }
221
Kate Stoneb9c1b512016-09-06 20:57:50 +0000222 // Split the raw command into var_name and value pair.
223 llvm::StringRef raw_str(command);
224 std::string var_value_string = raw_str.split(var_name).second.str();
225 const char *var_value_cstr =
226 Args::StripSpaces(var_value_string, true, false, false);
227
Zachary Turner97206d52017-05-12 04:51:55 +0000228 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000229 if (m_options.m_global) {
230 error = m_interpreter.GetDebugger().SetPropertyValue(
231 nullptr, eVarSetOperationAssign, var_name, var_value_cstr);
232 }
233
234 if (error.Success()) {
235 // FIXME this is the same issue as the one in commands script import
236 // we could be setting target.load-script-from-symbol-file which would
Adrian Prantl05097242018-04-30 16:49:04 +0000237 // cause Python scripts to be loaded, which could run LLDB commands (e.g.
238 // settings set target.process.python-os-plugin-path) and cause a crash
Kate Stoneb9c1b512016-09-06 20:57:50 +0000239 // if we did not clear the command's exe_ctx first
240 ExecutionContext exe_ctx(m_exe_ctx);
241 m_exe_ctx.Clear();
242 error = m_interpreter.GetDebugger().SetPropertyValue(
243 &exe_ctx, eVarSetOperationAssign, var_name, var_value_cstr);
244 }
245
246 if (error.Fail()) {
247 result.AppendError(error.AsCString());
248 result.SetStatus(eReturnStatusFailed);
249 return false;
250 } else {
251 result.SetStatus(eReturnStatusSuccessFinishResult);
252 }
253
254 return result.Succeeded();
255 }
256
Jim Ingham5a988412012-06-08 21:56:10 +0000257private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000258 CommandOptions m_options;
Jim Ingham5a988412012-06-08 21:56:10 +0000259};
260
Jim Ingham5a988412012-06-08 21:56:10 +0000261//-------------------------------------------------------------------------
262// CommandObjectSettingsShow -- Show current values
263//-------------------------------------------------------------------------
264
Kate Stoneb9c1b512016-09-06 20:57:50 +0000265class CommandObjectSettingsShow : public CommandObjectParsed {
Jim Ingham5a988412012-06-08 21:56:10 +0000266public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000267 CommandObjectSettingsShow(CommandInterpreter &interpreter)
268 : CommandObjectParsed(interpreter, "settings show",
269 "Show matching debugger settings and their current "
270 "values. Defaults to showing all settings.",
271 nullptr) {
272 CommandArgumentEntry arg1;
273 CommandArgumentData var_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000274
Kate Stoneb9c1b512016-09-06 20:57:50 +0000275 // Define the first (and only) variant of this arg.
276 var_name_arg.arg_type = eArgTypeSettingVariableName;
277 var_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000278
Kate Stoneb9c1b512016-09-06 20:57:50 +0000279 // There is only one variant this argument could be; put it into the
280 // argument entry.
281 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000282
Kate Stoneb9c1b512016-09-06 20:57:50 +0000283 // Push the data for the first argument into the m_arguments vector.
284 m_arguments.push_back(arg1);
285 }
Jim Ingham5a988412012-06-08 21:56:10 +0000286
Kate Stoneb9c1b512016-09-06 20:57:50 +0000287 ~CommandObjectSettingsShow() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000288
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000289 int HandleArgumentCompletion(
290 CompletionRequest &request,
291 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000292 CommandCompletions::InvokeCommonCompletionCallbacks(
293 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000294 request, nullptr);
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000295 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000296 }
Jim Ingham5a988412012-06-08 21:56:10 +0000297
298protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000299 bool DoExecute(Args &args, CommandReturnObject &result) override {
300 result.SetStatus(eReturnStatusSuccessFinishResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000301
Zachary Turner97d2c402016-10-05 23:40:23 +0000302 if (!args.empty()) {
Zachary Turnerd6a24752016-11-22 17:10:15 +0000303 for (const auto &arg : args) {
Zachary Turner97206d52017-05-12 04:51:55 +0000304 Status error(m_interpreter.GetDebugger().DumpPropertyValue(
Zachary Turnerd6a24752016-11-22 17:10:15 +0000305 &m_exe_ctx, result.GetOutputStream(), arg.ref,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000306 OptionValue::eDumpGroupValue));
307 if (error.Success()) {
308 result.GetOutputStream().EOL();
309 } else {
310 result.AppendError(error.AsCString());
311 result.SetStatus(eReturnStatusFailed);
Jim Ingham5a988412012-06-08 21:56:10 +0000312 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000313 }
314 } else {
315 m_interpreter.GetDebugger().DumpAllPropertyValues(
316 &m_exe_ctx, result.GetOutputStream(), OptionValue::eDumpGroupValue);
Jim Ingham5a988412012-06-08 21:56:10 +0000317 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000318
319 return result.Succeeded();
320 }
Jim Ingham5a988412012-06-08 21:56:10 +0000321};
322
323//-------------------------------------------------------------------------
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000324// CommandObjectSettingsWrite -- Write settings to file
325//-------------------------------------------------------------------------
326
327static constexpr OptionDefinition g_settings_write_options[] = {
328 // clang-format off
329 { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file into which to write the settings." },
330 { LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append to saved settings file if it exists."},
331 // clang-format on
332};
333
334class CommandObjectSettingsWrite : public CommandObjectParsed {
335public:
336 CommandObjectSettingsWrite(CommandInterpreter &interpreter)
337 : CommandObjectParsed(
338 interpreter, "settings export",
339 "Write matching debugger settings and their "
340 "current values to a file that can be read in with "
341 "\"settings read\". Defaults to writing all settings.",
342 nullptr),
343 m_options() {
344 CommandArgumentEntry arg1;
345 CommandArgumentData var_name_arg;
346
347 // Define the first (and only) variant of this arg.
348 var_name_arg.arg_type = eArgTypeSettingVariableName;
349 var_name_arg.arg_repetition = eArgRepeatOptional;
350
351 // There is only one variant this argument could be; put it into the
352 // argument entry.
353 arg1.push_back(var_name_arg);
354
355 // Push the data for the first argument into the m_arguments vector.
356 m_arguments.push_back(arg1);
357 }
358
359 ~CommandObjectSettingsWrite() override = default;
360
361 Options *GetOptions() override { return &m_options; }
362
363 class CommandOptions : public Options {
364 public:
365 CommandOptions() : Options() {}
366
367 ~CommandOptions() override = default;
368
369 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
370 ExecutionContext *execution_context) override {
371 Status error;
372 const int short_option = m_getopt_table[option_idx].val;
373
374 switch (short_option) {
375 case 'f':
376 m_filename.assign(option_arg);
377 break;
378 case 'a':
379 m_append = true;
380 break;
381 default:
382 error.SetErrorStringWithFormat("unrecognized option '%c'",
383 short_option);
384 break;
385 }
386
387 return error;
388 }
389
390 void OptionParsingStarting(ExecutionContext *execution_context) override {
391 m_filename.clear();
392 m_append = false;
393 }
394
395 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
396 return llvm::makeArrayRef(g_settings_write_options);
397 }
398
399 // Instance variables to hold the values for command options.
400 std::string m_filename;
401 bool m_append = false;
402 };
403
404protected:
405 bool DoExecute(Args &args, CommandReturnObject &result) override {
406 std::string path(FileSpec(m_options.m_filename, true).GetPath());
407 uint32_t options = File::OpenOptions::eOpenOptionWrite |
408 File::OpenOptions::eOpenOptionCanCreate;
409 if (m_options.m_append)
410 options |= File::OpenOptions::eOpenOptionAppend;
411 else
412 options |= File::OpenOptions::eOpenOptionTruncate;
413
414 StreamFile out_file(path.c_str(), options,
415 lldb::eFilePermissionsFileDefault);
416
417 if (!out_file.GetFile().IsValid()) {
418 result.AppendErrorWithFormat("%s: unable to write to file", path.c_str());
419 result.SetStatus(eReturnStatusFailed);
420 return false;
421 }
422
423 // Exporting should not be context sensitive.
424 ExecutionContext clean_ctx;
425
426 if (args.empty()) {
427 m_interpreter.GetDebugger().DumpAllPropertyValues(
428 &clean_ctx, out_file, OptionValue::eDumpGroupExport);
429 return result.Succeeded();
430 }
431
432 for (const auto &arg : args) {
433 Status error(m_interpreter.GetDebugger().DumpPropertyValue(
434 &clean_ctx, out_file, arg.ref, OptionValue::eDumpGroupExport));
435 if (!error.Success()) {
436 result.AppendError(error.AsCString());
437 result.SetStatus(eReturnStatusFailed);
438 }
439 }
440
441 return result.Succeeded();
442 }
443
444private:
445 CommandOptions m_options;
446};
447
448//-------------------------------------------------------------------------
449// CommandObjectSettingsRead -- Read settings from file
450//-------------------------------------------------------------------------
451
452static constexpr OptionDefinition g_settings_read_options[] = {
453 // clang-format off
454 {LLDB_OPT_SET_ALL, true, "file",'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file from which to read the breakpoints." },
455 // clang-format on
456};
457
458class CommandObjectSettingsRead : public CommandObjectParsed {
459public:
460 CommandObjectSettingsRead(CommandInterpreter &interpreter)
461 : CommandObjectParsed(
462 interpreter, "settings read",
463 "Read settings previously saved to a file with \"settings write\".",
464 nullptr),
465 m_options() {}
466
467 ~CommandObjectSettingsRead() override = default;
468
469 Options *GetOptions() override { return &m_options; }
470
471 class CommandOptions : public Options {
472 public:
473 CommandOptions() : Options() {}
474
475 ~CommandOptions() override = default;
476
477 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
478 ExecutionContext *execution_context) override {
479 Status error;
480 const int short_option = m_getopt_table[option_idx].val;
481
482 switch (short_option) {
483 case 'f':
484 m_filename.assign(option_arg);
485 break;
486 default:
487 error.SetErrorStringWithFormat("unrecognized option '%c'",
488 short_option);
489 break;
490 }
491
492 return error;
493 }
494
495 void OptionParsingStarting(ExecutionContext *execution_context) override {
496 m_filename.clear();
497 }
498
499 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
500 return llvm::makeArrayRef(g_settings_read_options);
501 }
502
503 // Instance variables to hold the values for command options.
504 std::string m_filename;
505 };
506
507protected:
508 bool DoExecute(Args &command, CommandReturnObject &result) override {
509 FileSpec file(m_options.m_filename, true);
510 ExecutionContext clean_ctx;
511 CommandInterpreterRunOptions options;
512 options.SetAddToHistory(false);
513 options.SetEchoCommands(false);
514 options.SetPrintResults(true);
515 options.SetStopOnError(false);
516 m_interpreter.HandleCommandsFromFile(file, &clean_ctx, options, result);
517 return result.Succeeded();
518 }
519
520private:
521 CommandOptions m_options;
522};
523
524//-------------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +0000525// CommandObjectSettingsList -- List settable variables
526//-------------------------------------------------------------------------
527
Kate Stoneb9c1b512016-09-06 20:57:50 +0000528class CommandObjectSettingsList : public CommandObjectParsed {
Kate Stone7428a182016-07-14 22:03:10 +0000529public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000530 CommandObjectSettingsList(CommandInterpreter &interpreter)
531 : CommandObjectParsed(interpreter, "settings list",
532 "List and describe matching debugger settings. "
533 "Defaults to all listing all settings.",
534 nullptr) {
535 CommandArgumentEntry arg;
536 CommandArgumentData var_name_arg;
537 CommandArgumentData prefix_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000538
Kate Stoneb9c1b512016-09-06 20:57:50 +0000539 // Define the first variant of this arg.
540 var_name_arg.arg_type = eArgTypeSettingVariableName;
541 var_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000542
Kate Stoneb9c1b512016-09-06 20:57:50 +0000543 // Define the second variant of this arg.
544 prefix_name_arg.arg_type = eArgTypeSettingPrefix;
545 prefix_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000546
Kate Stoneb9c1b512016-09-06 20:57:50 +0000547 arg.push_back(var_name_arg);
548 arg.push_back(prefix_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000549
Kate Stoneb9c1b512016-09-06 20:57:50 +0000550 // Push the data for the first argument into the m_arguments vector.
551 m_arguments.push_back(arg);
552 }
Jim Ingham5a988412012-06-08 21:56:10 +0000553
Kate Stoneb9c1b512016-09-06 20:57:50 +0000554 ~CommandObjectSettingsList() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000555
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000556 int HandleArgumentCompletion(
557 CompletionRequest &request,
558 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000559 CommandCompletions::InvokeCommonCompletionCallbacks(
560 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000561 request, nullptr);
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000562 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000563 }
Jim Ingham5a988412012-06-08 21:56:10 +0000564
565protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000566 bool DoExecute(Args &args, CommandReturnObject &result) override {
567 result.SetStatus(eReturnStatusSuccessFinishResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000568
Kate Stoneb9c1b512016-09-06 20:57:50 +0000569 const bool will_modify = false;
570 const size_t argc = args.GetArgumentCount();
571 if (argc > 0) {
572 const bool dump_qualified_name = true;
Jim Ingham5a988412012-06-08 21:56:10 +0000573
Zachary Turner97d2c402016-10-05 23:40:23 +0000574 // TODO: Convert to StringRef based enumeration. Requires converting
575 // GetPropertyAtPath first.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000576 for (size_t i = 0; i < argc; ++i) {
577 const char *property_path = args.GetArgumentAtIndex(i);
Greg Clayton67cc0632012-08-22 17:17:09 +0000578
Kate Stoneb9c1b512016-09-06 20:57:50 +0000579 const Property *property =
580 m_interpreter.GetDebugger().GetValueProperties()->GetPropertyAtPath(
581 &m_exe_ctx, will_modify, property_path);
582
583 if (property) {
584 property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
585 dump_qualified_name);
586 } else {
587 result.AppendErrorWithFormat("invalid property path '%s'",
588 property_path);
589 result.SetStatus(eReturnStatusFailed);
Jim Ingham5a988412012-06-08 21:56:10 +0000590 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000591 }
592 } else {
593 m_interpreter.GetDebugger().DumpAllDescriptions(m_interpreter,
594 result.GetOutputStream());
Jim Ingham5a988412012-06-08 21:56:10 +0000595 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000596
597 return result.Succeeded();
598 }
Jim Ingham5a988412012-06-08 21:56:10 +0000599};
600
601//-------------------------------------------------------------------------
602// CommandObjectSettingsRemove
603//-------------------------------------------------------------------------
604
Kate Stoneb9c1b512016-09-06 20:57:50 +0000605class CommandObjectSettingsRemove : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000606public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000607 CommandObjectSettingsRemove(CommandInterpreter &interpreter)
608 : CommandObjectRaw(interpreter, "settings remove",
609 "Remove a value from a setting, specified by array "
Zachary Turnera4496982016-10-05 21:14:38 +0000610 "index or dictionary key.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000611 CommandArgumentEntry arg1;
612 CommandArgumentEntry arg2;
613 CommandArgumentData var_name_arg;
614 CommandArgumentData index_arg;
615 CommandArgumentData key_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000616
Kate Stoneb9c1b512016-09-06 20:57:50 +0000617 // Define the first (and only) variant of this arg.
618 var_name_arg.arg_type = eArgTypeSettingVariableName;
619 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000620
Kate Stoneb9c1b512016-09-06 20:57:50 +0000621 // There is only one variant this argument could be; put it into the
622 // argument entry.
623 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000624
Kate Stoneb9c1b512016-09-06 20:57:50 +0000625 // Define the first variant of this arg.
626 index_arg.arg_type = eArgTypeSettingIndex;
627 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000628
Kate Stoneb9c1b512016-09-06 20:57:50 +0000629 // Define the second variant of this arg.
630 key_arg.arg_type = eArgTypeSettingKey;
631 key_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000632
Kate Stoneb9c1b512016-09-06 20:57:50 +0000633 // Push both variants into this arg
634 arg2.push_back(index_arg);
635 arg2.push_back(key_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000636
Kate Stoneb9c1b512016-09-06 20:57:50 +0000637 // Push the data for the first argument into the m_arguments vector.
638 m_arguments.push_back(arg1);
639 m_arguments.push_back(arg2);
640 }
Jim Ingham5a988412012-06-08 21:56:10 +0000641
Kate Stoneb9c1b512016-09-06 20:57:50 +0000642 ~CommandObjectSettingsRemove() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000643
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000644 int HandleArgumentCompletion(
645 CompletionRequest &request,
646 OptionElementVector &opt_element_vector) override {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000647 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000648 CommandCompletions::InvokeCommonCompletionCallbacks(
649 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000650 request, nullptr);
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000651 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000652 }
Jim Ingham5a988412012-06-08 21:56:10 +0000653
654protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000655 bool DoExecute(llvm::StringRef command,
656 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000657 result.SetStatus(eReturnStatusSuccessFinishNoResult);
658
659 Args cmd_args(command);
660
661 // Process possible options.
662 if (!ParseOptions(cmd_args, result))
663 return false;
664
665 const size_t argc = cmd_args.GetArgumentCount();
666 if (argc == 0) {
667 result.AppendError("'settings set' takes an array or dictionary item, or "
668 "an array followed by one or more indexes, or a "
669 "dictionary followed by one or more key names to "
670 "remove");
671 result.SetStatus(eReturnStatusFailed);
672 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000673 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000674
675 const char *var_name = cmd_args.GetArgumentAtIndex(0);
676 if ((var_name == nullptr) || (var_name[0] == '\0')) {
677 result.AppendError(
678 "'settings set' command requires a valid variable name");
679 result.SetStatus(eReturnStatusFailed);
680 return false;
681 }
682
683 // Split the raw command into var_name and value pair.
684 llvm::StringRef raw_str(command);
685 std::string var_value_string = raw_str.split(var_name).second.str();
686 const char *var_value_cstr =
687 Args::StripSpaces(var_value_string, true, true, false);
688
Zachary Turner97206d52017-05-12 04:51:55 +0000689 Status error(m_interpreter.GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000690 &m_exe_ctx, eVarSetOperationRemove, var_name, var_value_cstr));
691 if (error.Fail()) {
692 result.AppendError(error.AsCString());
693 result.SetStatus(eReturnStatusFailed);
694 return false;
695 }
696
697 return result.Succeeded();
698 }
Jim Ingham5a988412012-06-08 21:56:10 +0000699};
700
701//-------------------------------------------------------------------------
702// CommandObjectSettingsReplace
703//-------------------------------------------------------------------------
704
Kate Stoneb9c1b512016-09-06 20:57:50 +0000705class CommandObjectSettingsReplace : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000706public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000707 CommandObjectSettingsReplace(CommandInterpreter &interpreter)
708 : CommandObjectRaw(interpreter, "settings replace",
709 "Replace the debugger setting value specified by "
Zachary Turnera4496982016-10-05 21:14:38 +0000710 "array index or dictionary key.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000711 CommandArgumentEntry arg1;
712 CommandArgumentEntry arg2;
713 CommandArgumentEntry arg3;
714 CommandArgumentData var_name_arg;
715 CommandArgumentData index_arg;
716 CommandArgumentData key_arg;
717 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000718
Kate Stoneb9c1b512016-09-06 20:57:50 +0000719 // Define the first (and only) variant of this arg.
720 var_name_arg.arg_type = eArgTypeSettingVariableName;
721 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000722
Kate Stoneb9c1b512016-09-06 20:57:50 +0000723 // There is only one variant this argument could be; put it into the
724 // argument entry.
725 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000726
Kate Stoneb9c1b512016-09-06 20:57:50 +0000727 // Define the first (variant of this arg.
728 index_arg.arg_type = eArgTypeSettingIndex;
729 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000730
Kate Stoneb9c1b512016-09-06 20:57:50 +0000731 // Define the second (variant of this arg.
732 key_arg.arg_type = eArgTypeSettingKey;
733 key_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000734
Kate Stoneb9c1b512016-09-06 20:57:50 +0000735 // Put both variants into this arg
736 arg2.push_back(index_arg);
737 arg2.push_back(key_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000738
Kate Stoneb9c1b512016-09-06 20:57:50 +0000739 // Define the first (and only) variant of this arg.
740 value_arg.arg_type = eArgTypeValue;
741 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000742
Kate Stoneb9c1b512016-09-06 20:57:50 +0000743 // There is only one variant this argument could be; put it into the
744 // argument entry.
745 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000746
Kate Stoneb9c1b512016-09-06 20:57:50 +0000747 // Push the data for the first argument into the m_arguments vector.
748 m_arguments.push_back(arg1);
749 m_arguments.push_back(arg2);
750 m_arguments.push_back(arg3);
751 }
Jim Ingham5a988412012-06-08 21:56:10 +0000752
Kate Stoneb9c1b512016-09-06 20:57:50 +0000753 ~CommandObjectSettingsReplace() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000754
Kate Stoneb9c1b512016-09-06 20:57:50 +0000755 // Overrides base class's behavior where WantsCompletion =
756 // !WantsRawCommandString.
757 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000758
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000759 int HandleArgumentCompletion(
760 CompletionRequest &request,
761 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000762 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000763 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000764 CommandCompletions::InvokeCommonCompletionCallbacks(
765 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000766 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +0000767
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000768 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000769 }
Jim Ingham5a988412012-06-08 21:56:10 +0000770
771protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000772 bool DoExecute(llvm::StringRef command,
773 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000774 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000775
Kate Stoneb9c1b512016-09-06 20:57:50 +0000776 Args cmd_args(command);
777 const char *var_name = cmd_args.GetArgumentAtIndex(0);
778 if ((var_name == nullptr) || (var_name[0] == '\0')) {
779 result.AppendError("'settings replace' command requires a valid variable "
780 "name; No value supplied");
781 result.SetStatus(eReturnStatusFailed);
782 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000783 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000784
785 // Split the raw command into var_name, index_value, and value triple.
786 llvm::StringRef raw_str(command);
787 std::string var_value_string = raw_str.split(var_name).second.str();
788 const char *var_value_cstr =
789 Args::StripSpaces(var_value_string, true, true, false);
790
Zachary Turner97206d52017-05-12 04:51:55 +0000791 Status error(m_interpreter.GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000792 &m_exe_ctx, eVarSetOperationReplace, var_name, var_value_cstr));
793 if (error.Fail()) {
794 result.AppendError(error.AsCString());
795 result.SetStatus(eReturnStatusFailed);
796 return false;
797 } else {
798 result.SetStatus(eReturnStatusSuccessFinishNoResult);
799 }
800
801 return result.Succeeded();
802 }
Jim Ingham5a988412012-06-08 21:56:10 +0000803};
804
805//-------------------------------------------------------------------------
806// CommandObjectSettingsInsertBefore
807//-------------------------------------------------------------------------
808
Kate Stoneb9c1b512016-09-06 20:57:50 +0000809class CommandObjectSettingsInsertBefore : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000810public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000811 CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
812 : CommandObjectRaw(interpreter, "settings insert-before",
813 "Insert one or more values into an debugger array "
814 "setting immediately before the specified element "
Zachary Turnera4496982016-10-05 21:14:38 +0000815 "index.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000816 CommandArgumentEntry arg1;
817 CommandArgumentEntry arg2;
818 CommandArgumentEntry arg3;
819 CommandArgumentData var_name_arg;
820 CommandArgumentData index_arg;
821 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000822
Kate Stoneb9c1b512016-09-06 20:57:50 +0000823 // Define the first (and only) variant of this arg.
824 var_name_arg.arg_type = eArgTypeSettingVariableName;
825 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000826
Kate Stoneb9c1b512016-09-06 20:57:50 +0000827 // There is only one variant this argument could be; put it into the
828 // argument entry.
829 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000830
Kate Stoneb9c1b512016-09-06 20:57:50 +0000831 // Define the first (variant of this arg.
832 index_arg.arg_type = eArgTypeSettingIndex;
833 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000834
Kate Stoneb9c1b512016-09-06 20:57:50 +0000835 // There is only one variant this argument could be; put it into the
836 // argument entry.
837 arg2.push_back(index_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000838
Kate Stoneb9c1b512016-09-06 20:57:50 +0000839 // Define the first (and only) variant of this arg.
840 value_arg.arg_type = eArgTypeValue;
841 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000842
Kate Stoneb9c1b512016-09-06 20:57:50 +0000843 // There is only one variant this argument could be; put it into the
844 // argument entry.
845 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000846
Kate Stoneb9c1b512016-09-06 20:57:50 +0000847 // Push the data for the first argument into the m_arguments vector.
848 m_arguments.push_back(arg1);
849 m_arguments.push_back(arg2);
850 m_arguments.push_back(arg3);
851 }
Jim Ingham5a988412012-06-08 21:56:10 +0000852
Kate Stoneb9c1b512016-09-06 20:57:50 +0000853 ~CommandObjectSettingsInsertBefore() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000854
Kate Stoneb9c1b512016-09-06 20:57:50 +0000855 // Overrides base class's behavior where WantsCompletion =
856 // !WantsRawCommandString.
857 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000858
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000859 int HandleArgumentCompletion(
860 CompletionRequest &request,
861 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000862 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000863 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000864 CommandCompletions::InvokeCommonCompletionCallbacks(
865 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000866 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +0000867
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000868 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000869 }
Jim Ingham5a988412012-06-08 21:56:10 +0000870
871protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000872 bool DoExecute(llvm::StringRef command,
873 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000874 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000875
Kate Stoneb9c1b512016-09-06 20:57:50 +0000876 Args cmd_args(command);
877 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +0000878
Kate Stoneb9c1b512016-09-06 20:57:50 +0000879 if (argc < 3) {
880 result.AppendError("'settings insert-before' takes more arguments");
881 result.SetStatus(eReturnStatusFailed);
882 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000883 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000884
885 const char *var_name = cmd_args.GetArgumentAtIndex(0);
886 if ((var_name == nullptr) || (var_name[0] == '\0')) {
887 result.AppendError("'settings insert-before' command requires a valid "
888 "variable name; No value supplied");
889 result.SetStatus(eReturnStatusFailed);
890 return false;
891 }
892
893 // Split the raw command into var_name, index_value, and value triple.
894 llvm::StringRef raw_str(command);
895 std::string var_value_string = raw_str.split(var_name).second.str();
896 const char *var_value_cstr =
897 Args::StripSpaces(var_value_string, true, true, false);
898
Zachary Turner97206d52017-05-12 04:51:55 +0000899 Status error(m_interpreter.GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000900 &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value_cstr));
901 if (error.Fail()) {
902 result.AppendError(error.AsCString());
903 result.SetStatus(eReturnStatusFailed);
904 return false;
905 }
906
907 return result.Succeeded();
908 }
Jim Ingham5a988412012-06-08 21:56:10 +0000909};
910
911//-------------------------------------------------------------------------
912// CommandObjectSettingInsertAfter
913//-------------------------------------------------------------------------
914
Kate Stoneb9c1b512016-09-06 20:57:50 +0000915class CommandObjectSettingsInsertAfter : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000916public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000917 CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
918 : CommandObjectRaw(interpreter, "settings insert-after",
919 "Insert one or more values into a debugger array "
Zachary Turnera4496982016-10-05 21:14:38 +0000920 "settings after the specified element index.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000921 CommandArgumentEntry arg1;
922 CommandArgumentEntry arg2;
923 CommandArgumentEntry arg3;
924 CommandArgumentData var_name_arg;
925 CommandArgumentData index_arg;
926 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000927
Kate Stoneb9c1b512016-09-06 20:57:50 +0000928 // Define the first (and only) variant of this arg.
929 var_name_arg.arg_type = eArgTypeSettingVariableName;
930 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000931
Kate Stoneb9c1b512016-09-06 20:57:50 +0000932 // There is only one variant this argument could be; put it into the
933 // argument entry.
934 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000935
Kate Stoneb9c1b512016-09-06 20:57:50 +0000936 // Define the first (variant of this arg.
937 index_arg.arg_type = eArgTypeSettingIndex;
938 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000939
Kate Stoneb9c1b512016-09-06 20:57:50 +0000940 // There is only one variant this argument could be; put it into the
941 // argument entry.
942 arg2.push_back(index_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000943
Kate Stoneb9c1b512016-09-06 20:57:50 +0000944 // Define the first (and only) variant of this arg.
945 value_arg.arg_type = eArgTypeValue;
946 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000947
Kate Stoneb9c1b512016-09-06 20:57:50 +0000948 // There is only one variant this argument could be; put it into the
949 // argument entry.
950 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000951
Kate Stoneb9c1b512016-09-06 20:57:50 +0000952 // Push the data for the first argument into the m_arguments vector.
953 m_arguments.push_back(arg1);
954 m_arguments.push_back(arg2);
955 m_arguments.push_back(arg3);
956 }
Jim Ingham5a988412012-06-08 21:56:10 +0000957
Kate Stoneb9c1b512016-09-06 20:57:50 +0000958 ~CommandObjectSettingsInsertAfter() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000959
Kate Stoneb9c1b512016-09-06 20:57:50 +0000960 // Overrides base class's behavior where WantsCompletion =
961 // !WantsRawCommandString.
962 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000963
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000964 int HandleArgumentCompletion(
965 CompletionRequest &request,
966 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000967 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000968 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000969 CommandCompletions::InvokeCommonCompletionCallbacks(
970 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000971 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +0000972
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000973 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000974 }
975
Jim Ingham5a988412012-06-08 21:56:10 +0000976protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000977 bool DoExecute(llvm::StringRef command,
978 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000979 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000980
Kate Stoneb9c1b512016-09-06 20:57:50 +0000981 Args cmd_args(command);
982 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +0000983
Kate Stoneb9c1b512016-09-06 20:57:50 +0000984 if (argc < 3) {
985 result.AppendError("'settings insert-after' takes more arguments");
986 result.SetStatus(eReturnStatusFailed);
987 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000988 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000989
990 const char *var_name = cmd_args.GetArgumentAtIndex(0);
991 if ((var_name == nullptr) || (var_name[0] == '\0')) {
992 result.AppendError("'settings insert-after' command requires a valid "
993 "variable name; No value supplied");
994 result.SetStatus(eReturnStatusFailed);
995 return false;
996 }
997
998 // Split the raw command into var_name, index_value, and value triple.
999 llvm::StringRef raw_str(command);
1000 std::string var_value_string = raw_str.split(var_name).second.str();
1001 const char *var_value_cstr =
1002 Args::StripSpaces(var_value_string, true, true, false);
1003
Zachary Turner97206d52017-05-12 04:51:55 +00001004 Status error(m_interpreter.GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001005 &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value_cstr));
1006 if (error.Fail()) {
1007 result.AppendError(error.AsCString());
1008 result.SetStatus(eReturnStatusFailed);
1009 return false;
1010 }
1011
1012 return result.Succeeded();
1013 }
Jim Ingham5a988412012-06-08 21:56:10 +00001014};
1015
1016//-------------------------------------------------------------------------
1017// CommandObjectSettingsAppend
1018//-------------------------------------------------------------------------
1019
Kate Stoneb9c1b512016-09-06 20:57:50 +00001020class CommandObjectSettingsAppend : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +00001021public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001022 CommandObjectSettingsAppend(CommandInterpreter &interpreter)
1023 : CommandObjectRaw(interpreter, "settings append",
1024 "Append one or more values to a debugger array, "
Zachary Turnera4496982016-10-05 21:14:38 +00001025 "dictionary, or string setting.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001026 CommandArgumentEntry arg1;
1027 CommandArgumentEntry arg2;
1028 CommandArgumentData var_name_arg;
1029 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +00001030
Kate Stoneb9c1b512016-09-06 20:57:50 +00001031 // Define the first (and only) variant of this arg.
1032 var_name_arg.arg_type = eArgTypeSettingVariableName;
1033 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +00001034
Kate Stoneb9c1b512016-09-06 20:57:50 +00001035 // There is only one variant this argument could be; put it into the
1036 // argument entry.
1037 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001038
Kate Stoneb9c1b512016-09-06 20:57:50 +00001039 // Define the first (and only) variant of this arg.
1040 value_arg.arg_type = eArgTypeValue;
1041 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +00001042
Kate Stoneb9c1b512016-09-06 20:57:50 +00001043 // There is only one variant this argument could be; put it into the
1044 // argument entry.
1045 arg2.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001046
Kate Stoneb9c1b512016-09-06 20:57:50 +00001047 // Push the data for the first argument into the m_arguments vector.
1048 m_arguments.push_back(arg1);
1049 m_arguments.push_back(arg2);
1050 }
Jim Ingham5a988412012-06-08 21:56:10 +00001051
Kate Stoneb9c1b512016-09-06 20:57:50 +00001052 ~CommandObjectSettingsAppend() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001053
Kate Stoneb9c1b512016-09-06 20:57:50 +00001054 // Overrides base class's behavior where WantsCompletion =
1055 // !WantsRawCommandString.
1056 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +00001057
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001058 int HandleArgumentCompletion(
1059 CompletionRequest &request,
1060 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001061 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001062 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001063 CommandCompletions::InvokeCommonCompletionCallbacks(
1064 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +00001065 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +00001066
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +00001067 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001068 }
Jim Ingham5a988412012-06-08 21:56:10 +00001069
1070protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +00001071 bool DoExecute(llvm::StringRef command,
1072 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001073 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1074 Args cmd_args(command);
1075 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +00001076
Kate Stoneb9c1b512016-09-06 20:57:50 +00001077 if (argc < 2) {
1078 result.AppendError("'settings append' takes more arguments");
1079 result.SetStatus(eReturnStatusFailed);
1080 return false;
Jim Ingham5a988412012-06-08 21:56:10 +00001081 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001082
1083 const char *var_name = cmd_args.GetArgumentAtIndex(0);
1084 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1085 result.AppendError("'settings append' command requires a valid variable "
1086 "name; No value supplied");
1087 result.SetStatus(eReturnStatusFailed);
1088 return false;
1089 }
1090
Adrian Prantl05097242018-04-30 16:49:04 +00001091 // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
1092 // character string later on.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001093
1094 // Split the raw command into var_name and value pair.
1095 llvm::StringRef raw_str(command);
1096 std::string var_value_string = raw_str.split(var_name).second.str();
1097 const char *var_value_cstr =
1098 Args::StripSpaces(var_value_string, true, true, false);
1099
Zachary Turner97206d52017-05-12 04:51:55 +00001100 Status error(m_interpreter.GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001101 &m_exe_ctx, eVarSetOperationAppend, var_name, var_value_cstr));
1102 if (error.Fail()) {
1103 result.AppendError(error.AsCString());
1104 result.SetStatus(eReturnStatusFailed);
1105 return false;
1106 }
1107
1108 return result.Succeeded();
1109 }
Jim Ingham5a988412012-06-08 21:56:10 +00001110};
1111
1112//-------------------------------------------------------------------------
1113// CommandObjectSettingsClear
1114//-------------------------------------------------------------------------
1115
Kate Stoneb9c1b512016-09-06 20:57:50 +00001116class CommandObjectSettingsClear : public CommandObjectParsed {
Jim Ingham5a988412012-06-08 21:56:10 +00001117public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001118 CommandObjectSettingsClear(CommandInterpreter &interpreter)
1119 : CommandObjectParsed(
1120 interpreter, "settings clear",
1121 "Clear a debugger setting array, dictionary, or string.", nullptr) {
1122 CommandArgumentEntry arg;
1123 CommandArgumentData var_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +00001124
Kate Stoneb9c1b512016-09-06 20:57:50 +00001125 // Define the first (and only) variant of this arg.
1126 var_name_arg.arg_type = eArgTypeSettingVariableName;
1127 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +00001128
Kate Stoneb9c1b512016-09-06 20:57:50 +00001129 // There is only one variant this argument could be; put it into the
1130 // argument entry.
1131 arg.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001132
Kate Stoneb9c1b512016-09-06 20:57:50 +00001133 // Push the data for the first argument into the m_arguments vector.
1134 m_arguments.push_back(arg);
1135 }
Jim Ingham5a988412012-06-08 21:56:10 +00001136
Kate Stoneb9c1b512016-09-06 20:57:50 +00001137 ~CommandObjectSettingsClear() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001138
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001139 int HandleArgumentCompletion(
1140 CompletionRequest &request,
1141 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001142 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001143 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001144 CommandCompletions::InvokeCommonCompletionCallbacks(
1145 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +00001146 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +00001147
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +00001148 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001149 }
Jim Ingham5a988412012-06-08 21:56:10 +00001150
1151protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001152 bool DoExecute(Args &command, CommandReturnObject &result) override {
1153 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1154 const size_t argc = command.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +00001155
Kate Stoneb9c1b512016-09-06 20:57:50 +00001156 if (argc != 1) {
1157 result.AppendError("'settings clear' takes exactly one argument");
1158 result.SetStatus(eReturnStatusFailed);
1159 return false;
Jim Ingham5a988412012-06-08 21:56:10 +00001160 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001161
1162 const char *var_name = command.GetArgumentAtIndex(0);
1163 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1164 result.AppendError("'settings clear' command requires a valid variable "
1165 "name; No value supplied");
1166 result.SetStatus(eReturnStatusFailed);
1167 return false;
1168 }
1169
Zachary Turner97206d52017-05-12 04:51:55 +00001170 Status error(m_interpreter.GetDebugger().SetPropertyValue(
Zachary Turner31d97a52016-11-17 18:08:12 +00001171 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001172 if (error.Fail()) {
1173 result.AppendError(error.AsCString());
1174 result.SetStatus(eReturnStatusFailed);
1175 return false;
1176 }
1177
1178 return result.Succeeded();
1179 }
Jim Ingham5a988412012-06-08 21:56:10 +00001180};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001181
1182//-------------------------------------------------------------------------
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001183// CommandObjectMultiwordSettings
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001184//-------------------------------------------------------------------------
1185
Kate Stoneb9c1b512016-09-06 20:57:50 +00001186CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
1187 CommandInterpreter &interpreter)
1188 : CommandObjectMultiword(interpreter, "settings",
1189 "Commands for managing LLDB settings.",
1190 "settings <subcommand> [<command-options>]") {
1191 LoadSubCommand("set",
1192 CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
1193 LoadSubCommand("show",
1194 CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
1195 LoadSubCommand("list",
1196 CommandObjectSP(new CommandObjectSettingsList(interpreter)));
1197 LoadSubCommand("remove",
1198 CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
1199 LoadSubCommand("replace", CommandObjectSP(
1200 new CommandObjectSettingsReplace(interpreter)));
1201 LoadSubCommand(
1202 "insert-before",
1203 CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
1204 LoadSubCommand(
1205 "insert-after",
1206 CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
1207 LoadSubCommand("append",
1208 CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
1209 LoadSubCommand("clear",
1210 CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +00001211 LoadSubCommand("write",
1212 CommandObjectSP(new CommandObjectSettingsWrite(interpreter)));
1213 LoadSubCommand("read",
1214 CommandObjectSP(new CommandObjectSettingsRead(interpreter)));
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001215}
1216
Eugene Zelenko3f18ea02016-02-24 02:05:55 +00001217CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default;