blob: cceb4201bc503676363f1cd609f79f5064c9c3e9 [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 {
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000406 FileSpec file_spec(m_options.m_filename);
407 FileSystem::Instance().Resolve(file_spec);
408 std::string path(file_spec.GetPath());
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000409 uint32_t options = File::OpenOptions::eOpenOptionWrite |
410 File::OpenOptions::eOpenOptionCanCreate;
411 if (m_options.m_append)
412 options |= File::OpenOptions::eOpenOptionAppend;
413 else
414 options |= File::OpenOptions::eOpenOptionTruncate;
415
416 StreamFile out_file(path.c_str(), options,
417 lldb::eFilePermissionsFileDefault);
418
419 if (!out_file.GetFile().IsValid()) {
420 result.AppendErrorWithFormat("%s: unable to write to file", path.c_str());
421 result.SetStatus(eReturnStatusFailed);
422 return false;
423 }
424
425 // Exporting should not be context sensitive.
426 ExecutionContext clean_ctx;
427
428 if (args.empty()) {
429 m_interpreter.GetDebugger().DumpAllPropertyValues(
430 &clean_ctx, out_file, OptionValue::eDumpGroupExport);
431 return result.Succeeded();
432 }
433
434 for (const auto &arg : args) {
435 Status error(m_interpreter.GetDebugger().DumpPropertyValue(
436 &clean_ctx, out_file, arg.ref, OptionValue::eDumpGroupExport));
437 if (!error.Success()) {
438 result.AppendError(error.AsCString());
439 result.SetStatus(eReturnStatusFailed);
440 }
441 }
442
443 return result.Succeeded();
444 }
445
446private:
447 CommandOptions m_options;
448};
449
450//-------------------------------------------------------------------------
451// CommandObjectSettingsRead -- Read settings from file
452//-------------------------------------------------------------------------
453
454static constexpr OptionDefinition g_settings_read_options[] = {
455 // clang-format off
456 {LLDB_OPT_SET_ALL, true, "file",'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file from which to read the breakpoints." },
457 // clang-format on
458};
459
460class CommandObjectSettingsRead : public CommandObjectParsed {
461public:
462 CommandObjectSettingsRead(CommandInterpreter &interpreter)
463 : CommandObjectParsed(
464 interpreter, "settings read",
465 "Read settings previously saved to a file with \"settings write\".",
466 nullptr),
467 m_options() {}
468
469 ~CommandObjectSettingsRead() override = default;
470
471 Options *GetOptions() override { return &m_options; }
472
473 class CommandOptions : public Options {
474 public:
475 CommandOptions() : Options() {}
476
477 ~CommandOptions() override = default;
478
479 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
480 ExecutionContext *execution_context) override {
481 Status error;
482 const int short_option = m_getopt_table[option_idx].val;
483
484 switch (short_option) {
485 case 'f':
486 m_filename.assign(option_arg);
487 break;
488 default:
489 error.SetErrorStringWithFormat("unrecognized option '%c'",
490 short_option);
491 break;
492 }
493
494 return error;
495 }
496
497 void OptionParsingStarting(ExecutionContext *execution_context) override {
498 m_filename.clear();
499 }
500
501 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
502 return llvm::makeArrayRef(g_settings_read_options);
503 }
504
505 // Instance variables to hold the values for command options.
506 std::string m_filename;
507 };
508
509protected:
510 bool DoExecute(Args &command, CommandReturnObject &result) override {
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000511 FileSpec file(m_options.m_filename);
512 FileSystem::Instance().Resolve(file);
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000513 ExecutionContext clean_ctx;
514 CommandInterpreterRunOptions options;
515 options.SetAddToHistory(false);
516 options.SetEchoCommands(false);
517 options.SetPrintResults(true);
518 options.SetStopOnError(false);
519 m_interpreter.HandleCommandsFromFile(file, &clean_ctx, options, result);
520 return result.Succeeded();
521 }
522
523private:
524 CommandOptions m_options;
525};
526
527//-------------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +0000528// CommandObjectSettingsList -- List settable variables
529//-------------------------------------------------------------------------
530
Kate Stoneb9c1b512016-09-06 20:57:50 +0000531class CommandObjectSettingsList : public CommandObjectParsed {
Kate Stone7428a182016-07-14 22:03:10 +0000532public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000533 CommandObjectSettingsList(CommandInterpreter &interpreter)
534 : CommandObjectParsed(interpreter, "settings list",
535 "List and describe matching debugger settings. "
536 "Defaults to all listing all settings.",
537 nullptr) {
538 CommandArgumentEntry arg;
539 CommandArgumentData var_name_arg;
540 CommandArgumentData prefix_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000541
Kate Stoneb9c1b512016-09-06 20:57:50 +0000542 // Define the first variant of this arg.
543 var_name_arg.arg_type = eArgTypeSettingVariableName;
544 var_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000545
Kate Stoneb9c1b512016-09-06 20:57:50 +0000546 // Define the second variant of this arg.
547 prefix_name_arg.arg_type = eArgTypeSettingPrefix;
548 prefix_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000549
Kate Stoneb9c1b512016-09-06 20:57:50 +0000550 arg.push_back(var_name_arg);
551 arg.push_back(prefix_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000552
Kate Stoneb9c1b512016-09-06 20:57:50 +0000553 // Push the data for the first argument into the m_arguments vector.
554 m_arguments.push_back(arg);
555 }
Jim Ingham5a988412012-06-08 21:56:10 +0000556
Kate Stoneb9c1b512016-09-06 20:57:50 +0000557 ~CommandObjectSettingsList() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000558
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000559 int HandleArgumentCompletion(
560 CompletionRequest &request,
561 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000562 CommandCompletions::InvokeCommonCompletionCallbacks(
563 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000564 request, nullptr);
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000565 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000566 }
Jim Ingham5a988412012-06-08 21:56:10 +0000567
568protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000569 bool DoExecute(Args &args, CommandReturnObject &result) override {
570 result.SetStatus(eReturnStatusSuccessFinishResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000571
Kate Stoneb9c1b512016-09-06 20:57:50 +0000572 const bool will_modify = false;
573 const size_t argc = args.GetArgumentCount();
574 if (argc > 0) {
575 const bool dump_qualified_name = true;
Jim Ingham5a988412012-06-08 21:56:10 +0000576
Zachary Turner97d2c402016-10-05 23:40:23 +0000577 // TODO: Convert to StringRef based enumeration. Requires converting
578 // GetPropertyAtPath first.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000579 for (size_t i = 0; i < argc; ++i) {
580 const char *property_path = args.GetArgumentAtIndex(i);
Greg Clayton67cc0632012-08-22 17:17:09 +0000581
Kate Stoneb9c1b512016-09-06 20:57:50 +0000582 const Property *property =
583 m_interpreter.GetDebugger().GetValueProperties()->GetPropertyAtPath(
584 &m_exe_ctx, will_modify, property_path);
585
586 if (property) {
587 property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
588 dump_qualified_name);
589 } else {
590 result.AppendErrorWithFormat("invalid property path '%s'",
591 property_path);
592 result.SetStatus(eReturnStatusFailed);
Jim Ingham5a988412012-06-08 21:56:10 +0000593 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000594 }
595 } else {
596 m_interpreter.GetDebugger().DumpAllDescriptions(m_interpreter,
597 result.GetOutputStream());
Jim Ingham5a988412012-06-08 21:56:10 +0000598 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000599
600 return result.Succeeded();
601 }
Jim Ingham5a988412012-06-08 21:56:10 +0000602};
603
604//-------------------------------------------------------------------------
605// CommandObjectSettingsRemove
606//-------------------------------------------------------------------------
607
Kate Stoneb9c1b512016-09-06 20:57:50 +0000608class CommandObjectSettingsRemove : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000609public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000610 CommandObjectSettingsRemove(CommandInterpreter &interpreter)
611 : CommandObjectRaw(interpreter, "settings remove",
612 "Remove a value from a setting, specified by array "
Zachary Turnera4496982016-10-05 21:14:38 +0000613 "index or dictionary key.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000614 CommandArgumentEntry arg1;
615 CommandArgumentEntry arg2;
616 CommandArgumentData var_name_arg;
617 CommandArgumentData index_arg;
618 CommandArgumentData key_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000619
Kate Stoneb9c1b512016-09-06 20:57:50 +0000620 // Define the first (and only) variant of this arg.
621 var_name_arg.arg_type = eArgTypeSettingVariableName;
622 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000623
Kate Stoneb9c1b512016-09-06 20:57:50 +0000624 // There is only one variant this argument could be; put it into the
625 // argument entry.
626 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000627
Kate Stoneb9c1b512016-09-06 20:57:50 +0000628 // Define the first variant of this arg.
629 index_arg.arg_type = eArgTypeSettingIndex;
630 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000631
Kate Stoneb9c1b512016-09-06 20:57:50 +0000632 // Define the second variant of this arg.
633 key_arg.arg_type = eArgTypeSettingKey;
634 key_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000635
Kate Stoneb9c1b512016-09-06 20:57:50 +0000636 // Push both variants into this arg
637 arg2.push_back(index_arg);
638 arg2.push_back(key_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000639
Kate Stoneb9c1b512016-09-06 20:57:50 +0000640 // Push the data for the first argument into the m_arguments vector.
641 m_arguments.push_back(arg1);
642 m_arguments.push_back(arg2);
643 }
Jim Ingham5a988412012-06-08 21:56:10 +0000644
Kate Stoneb9c1b512016-09-06 20:57:50 +0000645 ~CommandObjectSettingsRemove() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000646
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000647 int HandleArgumentCompletion(
648 CompletionRequest &request,
649 OptionElementVector &opt_element_vector) override {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000650 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000651 CommandCompletions::InvokeCommonCompletionCallbacks(
652 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000653 request, nullptr);
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000654 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000655 }
Jim Ingham5a988412012-06-08 21:56:10 +0000656
657protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000658 bool DoExecute(llvm::StringRef command,
659 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000660 result.SetStatus(eReturnStatusSuccessFinishNoResult);
661
662 Args cmd_args(command);
663
664 // Process possible options.
665 if (!ParseOptions(cmd_args, result))
666 return false;
667
668 const size_t argc = cmd_args.GetArgumentCount();
669 if (argc == 0) {
670 result.AppendError("'settings set' takes an array or dictionary item, or "
671 "an array followed by one or more indexes, or a "
672 "dictionary followed by one or more key names to "
673 "remove");
674 result.SetStatus(eReturnStatusFailed);
675 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000676 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000677
678 const char *var_name = cmd_args.GetArgumentAtIndex(0);
679 if ((var_name == nullptr) || (var_name[0] == '\0')) {
680 result.AppendError(
681 "'settings set' command requires a valid variable name");
682 result.SetStatus(eReturnStatusFailed);
683 return false;
684 }
685
686 // Split the raw command into var_name and value pair.
687 llvm::StringRef raw_str(command);
688 std::string var_value_string = raw_str.split(var_name).second.str();
689 const char *var_value_cstr =
690 Args::StripSpaces(var_value_string, true, true, false);
691
Zachary Turner97206d52017-05-12 04:51:55 +0000692 Status error(m_interpreter.GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000693 &m_exe_ctx, eVarSetOperationRemove, var_name, var_value_cstr));
694 if (error.Fail()) {
695 result.AppendError(error.AsCString());
696 result.SetStatus(eReturnStatusFailed);
697 return false;
698 }
699
700 return result.Succeeded();
701 }
Jim Ingham5a988412012-06-08 21:56:10 +0000702};
703
704//-------------------------------------------------------------------------
705// CommandObjectSettingsReplace
706//-------------------------------------------------------------------------
707
Kate Stoneb9c1b512016-09-06 20:57:50 +0000708class CommandObjectSettingsReplace : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000709public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000710 CommandObjectSettingsReplace(CommandInterpreter &interpreter)
711 : CommandObjectRaw(interpreter, "settings replace",
712 "Replace the debugger setting value specified by "
Zachary Turnera4496982016-10-05 21:14:38 +0000713 "array index or dictionary key.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000714 CommandArgumentEntry arg1;
715 CommandArgumentEntry arg2;
716 CommandArgumentEntry arg3;
717 CommandArgumentData var_name_arg;
718 CommandArgumentData index_arg;
719 CommandArgumentData key_arg;
720 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000721
Kate Stoneb9c1b512016-09-06 20:57:50 +0000722 // Define the first (and only) variant of this arg.
723 var_name_arg.arg_type = eArgTypeSettingVariableName;
724 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000725
Kate Stoneb9c1b512016-09-06 20:57:50 +0000726 // There is only one variant this argument could be; put it into the
727 // argument entry.
728 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000729
Kate Stoneb9c1b512016-09-06 20:57:50 +0000730 // Define the first (variant of this arg.
731 index_arg.arg_type = eArgTypeSettingIndex;
732 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000733
Kate Stoneb9c1b512016-09-06 20:57:50 +0000734 // Define the second (variant of this arg.
735 key_arg.arg_type = eArgTypeSettingKey;
736 key_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000737
Kate Stoneb9c1b512016-09-06 20:57:50 +0000738 // Put both variants into this arg
739 arg2.push_back(index_arg);
740 arg2.push_back(key_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000741
Kate Stoneb9c1b512016-09-06 20:57:50 +0000742 // Define the first (and only) variant of this arg.
743 value_arg.arg_type = eArgTypeValue;
744 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000745
Kate Stoneb9c1b512016-09-06 20:57:50 +0000746 // There is only one variant this argument could be; put it into the
747 // argument entry.
748 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000749
Kate Stoneb9c1b512016-09-06 20:57:50 +0000750 // Push the data for the first argument into the m_arguments vector.
751 m_arguments.push_back(arg1);
752 m_arguments.push_back(arg2);
753 m_arguments.push_back(arg3);
754 }
Jim Ingham5a988412012-06-08 21:56:10 +0000755
Kate Stoneb9c1b512016-09-06 20:57:50 +0000756 ~CommandObjectSettingsReplace() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000757
Kate Stoneb9c1b512016-09-06 20:57:50 +0000758 // Overrides base class's behavior where WantsCompletion =
759 // !WantsRawCommandString.
760 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000761
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000762 int HandleArgumentCompletion(
763 CompletionRequest &request,
764 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000765 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000766 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000767 CommandCompletions::InvokeCommonCompletionCallbacks(
768 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000769 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +0000770
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000771 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000772 }
Jim Ingham5a988412012-06-08 21:56:10 +0000773
774protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000775 bool DoExecute(llvm::StringRef command,
776 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000777 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000778
Kate Stoneb9c1b512016-09-06 20:57:50 +0000779 Args cmd_args(command);
780 const char *var_name = cmd_args.GetArgumentAtIndex(0);
781 if ((var_name == nullptr) || (var_name[0] == '\0')) {
782 result.AppendError("'settings replace' command requires a valid variable "
783 "name; No value supplied");
784 result.SetStatus(eReturnStatusFailed);
785 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000786 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000787
788 // Split the raw command into var_name, index_value, and value triple.
789 llvm::StringRef raw_str(command);
790 std::string var_value_string = raw_str.split(var_name).second.str();
791 const char *var_value_cstr =
792 Args::StripSpaces(var_value_string, true, true, false);
793
Zachary Turner97206d52017-05-12 04:51:55 +0000794 Status error(m_interpreter.GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000795 &m_exe_ctx, eVarSetOperationReplace, var_name, var_value_cstr));
796 if (error.Fail()) {
797 result.AppendError(error.AsCString());
798 result.SetStatus(eReturnStatusFailed);
799 return false;
800 } else {
801 result.SetStatus(eReturnStatusSuccessFinishNoResult);
802 }
803
804 return result.Succeeded();
805 }
Jim Ingham5a988412012-06-08 21:56:10 +0000806};
807
808//-------------------------------------------------------------------------
809// CommandObjectSettingsInsertBefore
810//-------------------------------------------------------------------------
811
Kate Stoneb9c1b512016-09-06 20:57:50 +0000812class CommandObjectSettingsInsertBefore : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000813public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000814 CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
815 : CommandObjectRaw(interpreter, "settings insert-before",
816 "Insert one or more values into an debugger array "
817 "setting immediately before the specified element "
Zachary Turnera4496982016-10-05 21:14:38 +0000818 "index.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000819 CommandArgumentEntry arg1;
820 CommandArgumentEntry arg2;
821 CommandArgumentEntry arg3;
822 CommandArgumentData var_name_arg;
823 CommandArgumentData index_arg;
824 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000825
Kate Stoneb9c1b512016-09-06 20:57:50 +0000826 // Define the first (and only) variant of this arg.
827 var_name_arg.arg_type = eArgTypeSettingVariableName;
828 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000829
Kate Stoneb9c1b512016-09-06 20:57:50 +0000830 // There is only one variant this argument could be; put it into the
831 // argument entry.
832 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000833
Kate Stoneb9c1b512016-09-06 20:57:50 +0000834 // Define the first (variant of this arg.
835 index_arg.arg_type = eArgTypeSettingIndex;
836 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000837
Kate Stoneb9c1b512016-09-06 20:57:50 +0000838 // There is only one variant this argument could be; put it into the
839 // argument entry.
840 arg2.push_back(index_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000841
Kate Stoneb9c1b512016-09-06 20:57:50 +0000842 // Define the first (and only) variant of this arg.
843 value_arg.arg_type = eArgTypeValue;
844 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000845
Kate Stoneb9c1b512016-09-06 20:57:50 +0000846 // There is only one variant this argument could be; put it into the
847 // argument entry.
848 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000849
Kate Stoneb9c1b512016-09-06 20:57:50 +0000850 // Push the data for the first argument into the m_arguments vector.
851 m_arguments.push_back(arg1);
852 m_arguments.push_back(arg2);
853 m_arguments.push_back(arg3);
854 }
Jim Ingham5a988412012-06-08 21:56:10 +0000855
Kate Stoneb9c1b512016-09-06 20:57:50 +0000856 ~CommandObjectSettingsInsertBefore() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000857
Kate Stoneb9c1b512016-09-06 20:57:50 +0000858 // Overrides base class's behavior where WantsCompletion =
859 // !WantsRawCommandString.
860 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000861
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000862 int HandleArgumentCompletion(
863 CompletionRequest &request,
864 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000865 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000866 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000867 CommandCompletions::InvokeCommonCompletionCallbacks(
868 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000869 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +0000870
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000871 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000872 }
Jim Ingham5a988412012-06-08 21:56:10 +0000873
874protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000875 bool DoExecute(llvm::StringRef command,
876 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000877 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000878
Kate Stoneb9c1b512016-09-06 20:57:50 +0000879 Args cmd_args(command);
880 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +0000881
Kate Stoneb9c1b512016-09-06 20:57:50 +0000882 if (argc < 3) {
883 result.AppendError("'settings insert-before' takes more arguments");
884 result.SetStatus(eReturnStatusFailed);
885 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000886 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000887
888 const char *var_name = cmd_args.GetArgumentAtIndex(0);
889 if ((var_name == nullptr) || (var_name[0] == '\0')) {
890 result.AppendError("'settings insert-before' command requires a valid "
891 "variable name; No value supplied");
892 result.SetStatus(eReturnStatusFailed);
893 return false;
894 }
895
896 // Split the raw command into var_name, index_value, and value triple.
897 llvm::StringRef raw_str(command);
898 std::string var_value_string = raw_str.split(var_name).second.str();
899 const char *var_value_cstr =
900 Args::StripSpaces(var_value_string, true, true, false);
901
Zachary Turner97206d52017-05-12 04:51:55 +0000902 Status error(m_interpreter.GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000903 &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value_cstr));
904 if (error.Fail()) {
905 result.AppendError(error.AsCString());
906 result.SetStatus(eReturnStatusFailed);
907 return false;
908 }
909
910 return result.Succeeded();
911 }
Jim Ingham5a988412012-06-08 21:56:10 +0000912};
913
914//-------------------------------------------------------------------------
915// CommandObjectSettingInsertAfter
916//-------------------------------------------------------------------------
917
Kate Stoneb9c1b512016-09-06 20:57:50 +0000918class CommandObjectSettingsInsertAfter : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000919public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000920 CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
921 : CommandObjectRaw(interpreter, "settings insert-after",
922 "Insert one or more values into a debugger array "
Zachary Turnera4496982016-10-05 21:14:38 +0000923 "settings after the specified element index.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000924 CommandArgumentEntry arg1;
925 CommandArgumentEntry arg2;
926 CommandArgumentEntry arg3;
927 CommandArgumentData var_name_arg;
928 CommandArgumentData index_arg;
929 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000930
Kate Stoneb9c1b512016-09-06 20:57:50 +0000931 // Define the first (and only) variant of this arg.
932 var_name_arg.arg_type = eArgTypeSettingVariableName;
933 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000934
Kate Stoneb9c1b512016-09-06 20:57:50 +0000935 // There is only one variant this argument could be; put it into the
936 // argument entry.
937 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000938
Kate Stoneb9c1b512016-09-06 20:57:50 +0000939 // Define the first (variant of this arg.
940 index_arg.arg_type = eArgTypeSettingIndex;
941 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000942
Kate Stoneb9c1b512016-09-06 20:57:50 +0000943 // There is only one variant this argument could be; put it into the
944 // argument entry.
945 arg2.push_back(index_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000946
Kate Stoneb9c1b512016-09-06 20:57:50 +0000947 // Define the first (and only) variant of this arg.
948 value_arg.arg_type = eArgTypeValue;
949 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000950
Kate Stoneb9c1b512016-09-06 20:57:50 +0000951 // There is only one variant this argument could be; put it into the
952 // argument entry.
953 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000954
Kate Stoneb9c1b512016-09-06 20:57:50 +0000955 // Push the data for the first argument into the m_arguments vector.
956 m_arguments.push_back(arg1);
957 m_arguments.push_back(arg2);
958 m_arguments.push_back(arg3);
959 }
Jim Ingham5a988412012-06-08 21:56:10 +0000960
Kate Stoneb9c1b512016-09-06 20:57:50 +0000961 ~CommandObjectSettingsInsertAfter() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000962
Kate Stoneb9c1b512016-09-06 20:57:50 +0000963 // Overrides base class's behavior where WantsCompletion =
964 // !WantsRawCommandString.
965 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000966
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000967 int HandleArgumentCompletion(
968 CompletionRequest &request,
969 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000970 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000971 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000972 CommandCompletions::InvokeCommonCompletionCallbacks(
973 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000974 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +0000975
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000976 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000977 }
978
Jim Ingham5a988412012-06-08 21:56:10 +0000979protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000980 bool DoExecute(llvm::StringRef command,
981 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000982 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000983
Kate Stoneb9c1b512016-09-06 20:57:50 +0000984 Args cmd_args(command);
985 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +0000986
Kate Stoneb9c1b512016-09-06 20:57:50 +0000987 if (argc < 3) {
988 result.AppendError("'settings insert-after' takes more arguments");
989 result.SetStatus(eReturnStatusFailed);
990 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000991 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000992
993 const char *var_name = cmd_args.GetArgumentAtIndex(0);
994 if ((var_name == nullptr) || (var_name[0] == '\0')) {
995 result.AppendError("'settings insert-after' command requires a valid "
996 "variable name; No value supplied");
997 result.SetStatus(eReturnStatusFailed);
998 return false;
999 }
1000
1001 // Split the raw command into var_name, index_value, and value triple.
1002 llvm::StringRef raw_str(command);
1003 std::string var_value_string = raw_str.split(var_name).second.str();
1004 const char *var_value_cstr =
1005 Args::StripSpaces(var_value_string, true, true, false);
1006
Zachary Turner97206d52017-05-12 04:51:55 +00001007 Status error(m_interpreter.GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001008 &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value_cstr));
1009 if (error.Fail()) {
1010 result.AppendError(error.AsCString());
1011 result.SetStatus(eReturnStatusFailed);
1012 return false;
1013 }
1014
1015 return result.Succeeded();
1016 }
Jim Ingham5a988412012-06-08 21:56:10 +00001017};
1018
1019//-------------------------------------------------------------------------
1020// CommandObjectSettingsAppend
1021//-------------------------------------------------------------------------
1022
Kate Stoneb9c1b512016-09-06 20:57:50 +00001023class CommandObjectSettingsAppend : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +00001024public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001025 CommandObjectSettingsAppend(CommandInterpreter &interpreter)
1026 : CommandObjectRaw(interpreter, "settings append",
1027 "Append one or more values to a debugger array, "
Zachary Turnera4496982016-10-05 21:14:38 +00001028 "dictionary, or string setting.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001029 CommandArgumentEntry arg1;
1030 CommandArgumentEntry arg2;
1031 CommandArgumentData var_name_arg;
1032 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +00001033
Kate Stoneb9c1b512016-09-06 20:57:50 +00001034 // Define the first (and only) variant of this arg.
1035 var_name_arg.arg_type = eArgTypeSettingVariableName;
1036 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +00001037
Kate Stoneb9c1b512016-09-06 20:57:50 +00001038 // There is only one variant this argument could be; put it into the
1039 // argument entry.
1040 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001041
Kate Stoneb9c1b512016-09-06 20:57:50 +00001042 // Define the first (and only) variant of this arg.
1043 value_arg.arg_type = eArgTypeValue;
1044 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +00001045
Kate Stoneb9c1b512016-09-06 20:57:50 +00001046 // There is only one variant this argument could be; put it into the
1047 // argument entry.
1048 arg2.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001049
Kate Stoneb9c1b512016-09-06 20:57:50 +00001050 // Push the data for the first argument into the m_arguments vector.
1051 m_arguments.push_back(arg1);
1052 m_arguments.push_back(arg2);
1053 }
Jim Ingham5a988412012-06-08 21:56:10 +00001054
Kate Stoneb9c1b512016-09-06 20:57:50 +00001055 ~CommandObjectSettingsAppend() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001056
Kate Stoneb9c1b512016-09-06 20:57:50 +00001057 // Overrides base class's behavior where WantsCompletion =
1058 // !WantsRawCommandString.
1059 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +00001060
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001061 int HandleArgumentCompletion(
1062 CompletionRequest &request,
1063 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001064 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001065 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001066 CommandCompletions::InvokeCommonCompletionCallbacks(
1067 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +00001068 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +00001069
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +00001070 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001071 }
Jim Ingham5a988412012-06-08 21:56:10 +00001072
1073protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +00001074 bool DoExecute(llvm::StringRef command,
1075 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001076 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1077 Args cmd_args(command);
1078 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +00001079
Kate Stoneb9c1b512016-09-06 20:57:50 +00001080 if (argc < 2) {
1081 result.AppendError("'settings append' takes more arguments");
1082 result.SetStatus(eReturnStatusFailed);
1083 return false;
Jim Ingham5a988412012-06-08 21:56:10 +00001084 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001085
1086 const char *var_name = cmd_args.GetArgumentAtIndex(0);
1087 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1088 result.AppendError("'settings append' command requires a valid variable "
1089 "name; No value supplied");
1090 result.SetStatus(eReturnStatusFailed);
1091 return false;
1092 }
1093
Adrian Prantl05097242018-04-30 16:49:04 +00001094 // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
1095 // character string later on.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001096
1097 // Split the raw command into var_name and value pair.
1098 llvm::StringRef raw_str(command);
1099 std::string var_value_string = raw_str.split(var_name).second.str();
1100 const char *var_value_cstr =
1101 Args::StripSpaces(var_value_string, true, true, false);
1102
Zachary Turner97206d52017-05-12 04:51:55 +00001103 Status error(m_interpreter.GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001104 &m_exe_ctx, eVarSetOperationAppend, var_name, var_value_cstr));
1105 if (error.Fail()) {
1106 result.AppendError(error.AsCString());
1107 result.SetStatus(eReturnStatusFailed);
1108 return false;
1109 }
1110
1111 return result.Succeeded();
1112 }
Jim Ingham5a988412012-06-08 21:56:10 +00001113};
1114
1115//-------------------------------------------------------------------------
1116// CommandObjectSettingsClear
1117//-------------------------------------------------------------------------
1118
Kate Stoneb9c1b512016-09-06 20:57:50 +00001119class CommandObjectSettingsClear : public CommandObjectParsed {
Jim Ingham5a988412012-06-08 21:56:10 +00001120public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001121 CommandObjectSettingsClear(CommandInterpreter &interpreter)
1122 : CommandObjectParsed(
1123 interpreter, "settings clear",
1124 "Clear a debugger setting array, dictionary, or string.", nullptr) {
1125 CommandArgumentEntry arg;
1126 CommandArgumentData var_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +00001127
Kate Stoneb9c1b512016-09-06 20:57:50 +00001128 // Define the first (and only) variant of this arg.
1129 var_name_arg.arg_type = eArgTypeSettingVariableName;
1130 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +00001131
Kate Stoneb9c1b512016-09-06 20:57:50 +00001132 // There is only one variant this argument could be; put it into the
1133 // argument entry.
1134 arg.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001135
Kate Stoneb9c1b512016-09-06 20:57:50 +00001136 // Push the data for the first argument into the m_arguments vector.
1137 m_arguments.push_back(arg);
1138 }
Jim Ingham5a988412012-06-08 21:56:10 +00001139
Kate Stoneb9c1b512016-09-06 20:57:50 +00001140 ~CommandObjectSettingsClear() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001141
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001142 int HandleArgumentCompletion(
1143 CompletionRequest &request,
1144 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001145 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001146 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001147 CommandCompletions::InvokeCommonCompletionCallbacks(
1148 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +00001149 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +00001150
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +00001151 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001152 }
Jim Ingham5a988412012-06-08 21:56:10 +00001153
1154protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001155 bool DoExecute(Args &command, CommandReturnObject &result) override {
1156 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1157 const size_t argc = command.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +00001158
Kate Stoneb9c1b512016-09-06 20:57:50 +00001159 if (argc != 1) {
1160 result.AppendError("'settings clear' takes exactly one argument");
1161 result.SetStatus(eReturnStatusFailed);
1162 return false;
Jim Ingham5a988412012-06-08 21:56:10 +00001163 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001164
1165 const char *var_name = command.GetArgumentAtIndex(0);
1166 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1167 result.AppendError("'settings clear' command requires a valid variable "
1168 "name; No value supplied");
1169 result.SetStatus(eReturnStatusFailed);
1170 return false;
1171 }
1172
Zachary Turner97206d52017-05-12 04:51:55 +00001173 Status error(m_interpreter.GetDebugger().SetPropertyValue(
Zachary Turner31d97a52016-11-17 18:08:12 +00001174 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001175 if (error.Fail()) {
1176 result.AppendError(error.AsCString());
1177 result.SetStatus(eReturnStatusFailed);
1178 return false;
1179 }
1180
1181 return result.Succeeded();
1182 }
Jim Ingham5a988412012-06-08 21:56:10 +00001183};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001184
1185//-------------------------------------------------------------------------
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001186// CommandObjectMultiwordSettings
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001187//-------------------------------------------------------------------------
1188
Kate Stoneb9c1b512016-09-06 20:57:50 +00001189CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
1190 CommandInterpreter &interpreter)
1191 : CommandObjectMultiword(interpreter, "settings",
1192 "Commands for managing LLDB settings.",
1193 "settings <subcommand> [<command-options>]") {
1194 LoadSubCommand("set",
1195 CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
1196 LoadSubCommand("show",
1197 CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
1198 LoadSubCommand("list",
1199 CommandObjectSP(new CommandObjectSettingsList(interpreter)));
1200 LoadSubCommand("remove",
1201 CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
1202 LoadSubCommand("replace", CommandObjectSP(
1203 new CommandObjectSettingsReplace(interpreter)));
1204 LoadSubCommand(
1205 "insert-before",
1206 CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
1207 LoadSubCommand(
1208 "insert-after",
1209 CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
1210 LoadSubCommand("append",
1211 CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
1212 LoadSubCommand("clear",
1213 CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +00001214 LoadSubCommand("write",
1215 CommandObjectSP(new CommandObjectSettingsWrite(interpreter)));
1216 LoadSubCommand("read",
1217 CommandObjectSP(new CommandObjectSettingsRead(interpreter)));
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001218}
1219
Eugene Zelenko3f18ea02016-02-24 02:05:55 +00001220CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default;