blob: d756e031de58d7865e3819116b6bbe02509a88ba [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- CommandObjectSettings.cpp -------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "CommandObjectSettings.h"
10
Eugene Zelenko3f18ea02016-02-24 02:05:55 +000011#include "llvm/ADT/StringRef.h"
12
Zachary Turner3eb2b442017-03-22 23:33:16 +000013#include "lldb/Host/OptionParser.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000014#include "lldb/Interpreter/CommandCompletions.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015#include "lldb/Interpreter/CommandInterpreter.h"
16#include "lldb/Interpreter/CommandReturnObject.h"
Zachary Turner633a29c2015-03-04 01:58:01 +000017#include "lldb/Interpreter/OptionValueProperties.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018
19using namespace lldb;
20using namespace lldb_private;
Jim Ingham5a988412012-06-08 21:56:10 +000021
Jim Ingham5a988412012-06-08 21:56:10 +000022// CommandObjectSettingsSet
Raphael Isemann6f4fb4e2019-07-12 15:30:55 +000023#define LLDB_OPTIONS_settings_set
Raphael Isemannc5a2d742019-07-16 09:27:02 +000024#include "CommandOptions.inc"
Zachary Turner1f0f5b52016-09-22 20:22:55 +000025
Kate Stoneb9c1b512016-09-06 20:57:50 +000026class CommandObjectSettingsSet : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +000027public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000028 CommandObjectSettingsSet(CommandInterpreter &interpreter)
29 : CommandObjectRaw(interpreter, "settings set",
Zachary Turnera4496982016-10-05 21:14:38 +000030 "Set the value of the specified debugger setting."),
Kate Stoneb9c1b512016-09-06 20:57:50 +000031 m_options() {
32 CommandArgumentEntry arg1;
33 CommandArgumentEntry arg2;
34 CommandArgumentData var_name_arg;
35 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +000036
Kate Stoneb9c1b512016-09-06 20:57:50 +000037 // Define the first (and only) variant of this arg.
38 var_name_arg.arg_type = eArgTypeSettingVariableName;
39 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +000040
Kate Stoneb9c1b512016-09-06 20:57:50 +000041 // There is only one variant this argument could be; put it into the
42 // argument entry.
43 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +000044
Kate Stoneb9c1b512016-09-06 20:57:50 +000045 // Define the first (and only) variant of this arg.
46 value_arg.arg_type = eArgTypeValue;
47 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +000048
Kate Stoneb9c1b512016-09-06 20:57:50 +000049 // There is only one variant this argument could be; put it into the
50 // argument entry.
51 arg2.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +000052
Kate Stoneb9c1b512016-09-06 20:57:50 +000053 // Push the data for the first argument into the m_arguments vector.
54 m_arguments.push_back(arg1);
55 m_arguments.push_back(arg2);
56
57 SetHelpLong(
58 "\nWhen setting a dictionary or array variable, you can set multiple entries \
59at once by giving the values to the set command. For example:"
60 R"(
Kate Stoneea671fb2015-07-14 05:48:36 +000061
62(lldb) settings set target.run-args value1 value2 value3
63(lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345
64
65(lldb) settings show target.run-args
66 [0]: 'value1'
67 [1]: 'value2'
68 [3]: 'value3'
69(lldb) settings show target.env-vars
70 'MYPATH=~/.:/usr/bin'
71 'SOME_ENV_VAR=12345'
72
Kate Stoneb9c1b512016-09-06 20:57:50 +000073)"
74 "Warning: The 'set' command re-sets the entire array or dictionary. If you \
Kate Stoneea671fb2015-07-14 05:48:36 +000075just want to add, remove or update individual values (or add something to \
76the end), use one of the other settings sub-commands: append, replace, \
Kate Stoneb9c1b512016-09-06 20:57:50 +000077insert-before or insert-after.");
78 }
Jim Ingham5a988412012-06-08 21:56:10 +000079
Kate Stoneb9c1b512016-09-06 20:57:50 +000080 ~CommandObjectSettingsSet() override = default;
81
82 // Overrides base class's behavior where WantsCompletion =
83 // !WantsRawCommandString.
84 bool WantsCompletion() override { return true; }
85
86 Options *GetOptions() override { return &m_options; }
87
88 class CommandOptions : public Options {
89 public:
90 CommandOptions() : Options(), m_global(false) {}
91
92 ~CommandOptions() override = default;
93
Zachary Turner97206d52017-05-12 04:51:55 +000094 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
95 ExecutionContext *execution_context) override {
96 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +000097 const int short_option = m_getopt_table[option_idx].val;
98
99 switch (short_option) {
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000100 case 'f':
101 m_force = true;
102 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000103 case 'g':
104 m_global = true;
105 break;
106 default:
107 error.SetErrorStringWithFormat("unrecognized options '%c'",
108 short_option);
109 break;
110 }
111
112 return error;
Jim Ingham5a988412012-06-08 21:56:10 +0000113 }
114
Kate Stoneb9c1b512016-09-06 20:57:50 +0000115 void OptionParsingStarting(ExecutionContext *execution_context) override {
116 m_global = false;
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000117 m_force = false;
Jim Ingham5a988412012-06-08 21:56:10 +0000118 }
Jim Ingham5a988412012-06-08 21:56:10 +0000119
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000120 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +0000121 return llvm::makeArrayRef(g_settings_set_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000122 }
Jim Ingham5a988412012-06-08 21:56:10 +0000123
Kate Stoneb9c1b512016-09-06 20:57:50 +0000124 // Instance variables to hold the values for command options.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000125 bool m_global;
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000126 bool m_force;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000127 };
Jim Ingham5a988412012-06-08 21:56:10 +0000128
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000129 int HandleArgumentCompletion(
130 CompletionRequest &request,
131 OptionElementVector &opt_element_vector) override {
Jim Ingham5a988412012-06-08 21:56:10 +0000132
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000133 const size_t argc = request.GetParsedLine().GetArgumentCount();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000134 const char *arg = nullptr;
135 int setting_var_idx;
Pavel Labath5f56fca2018-03-09 10:39:40 +0000136 for (setting_var_idx = 0; setting_var_idx < static_cast<int>(argc);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000137 ++setting_var_idx) {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000138 arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000139 if (arg && arg[0] != '-')
140 break; // We found our setting variable name index
Jim Ingham5a988412012-06-08 21:56:10 +0000141 }
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000142 if (request.GetCursorIndex() == setting_var_idx) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000143 // Attempting to complete setting variable name
144 CommandCompletions::InvokeCommonCompletionCallbacks(
145 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000146 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000147 } else {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000148 arg =
149 request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000150
151 if (arg) {
152 if (arg[0] == '-') {
153 // Complete option name
154 } else {
155 // Complete setting value
156 const char *setting_var_name =
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000157 request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
Zachary Turner97206d52017-05-12 04:51:55 +0000158 Status error;
Jonas Devlieghere57179862019-04-27 06:19:42 +0000159 lldb::OptionValueSP value_sp(GetDebugger().GetPropertyValue(
160 &m_exe_ctx, setting_var_name, false, error));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000161 if (value_sp) {
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000162 value_sp->AutoComplete(m_interpreter, request);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163 }
164 }
165 }
166 }
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000167 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000168 }
169
Jim Ingham5a988412012-06-08 21:56:10 +0000170protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000171 bool DoExecute(llvm::StringRef command,
172 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000173 Args cmd_args(command);
Jim Ingham5a988412012-06-08 21:56:10 +0000174
Kate Stoneb9c1b512016-09-06 20:57:50 +0000175 // Process possible options.
176 if (!ParseOptions(cmd_args, result))
177 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000178
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000179 const size_t min_argc = m_options.m_force ? 1 : 2;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000180 const size_t argc = cmd_args.GetArgumentCount();
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000181
182 if ((argc < min_argc) && (!m_options.m_global)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000183 result.AppendError("'settings set' takes more arguments");
184 result.SetStatus(eReturnStatusFailed);
185 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000186 }
Eugene Zelenko3f18ea02016-02-24 02:05:55 +0000187
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188 const char *var_name = cmd_args.GetArgumentAtIndex(0);
189 if ((var_name == nullptr) || (var_name[0] == '\0')) {
190 result.AppendError(
191 "'settings set' command requires a valid variable name");
192 result.SetStatus(eReturnStatusFailed);
193 return false;
194 }
195
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000196 // A missing value corresponds to clearing the setting when "force" is
197 // specified.
198 if (argc == 1 && m_options.m_force) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000199 Status error(GetDebugger().SetPropertyValue(
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000200 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
201 if (error.Fail()) {
202 result.AppendError(error.AsCString());
203 result.SetStatus(eReturnStatusFailed);
204 return false;
205 }
206 return result.Succeeded();
207 }
208
Kate Stoneb9c1b512016-09-06 20:57:50 +0000209 // Split the raw command into var_name and value pair.
210 llvm::StringRef raw_str(command);
211 std::string var_value_string = raw_str.split(var_name).second.str();
212 const char *var_value_cstr =
213 Args::StripSpaces(var_value_string, true, false, false);
214
Zachary Turner97206d52017-05-12 04:51:55 +0000215 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000216 if (m_options.m_global) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000217 error = GetDebugger().SetPropertyValue(nullptr, eVarSetOperationAssign,
218 var_name, var_value_cstr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000219 }
220
221 if (error.Success()) {
222 // FIXME this is the same issue as the one in commands script import
223 // we could be setting target.load-script-from-symbol-file which would
Adrian Prantl05097242018-04-30 16:49:04 +0000224 // cause Python scripts to be loaded, which could run LLDB commands (e.g.
225 // settings set target.process.python-os-plugin-path) and cause a crash
Kate Stoneb9c1b512016-09-06 20:57:50 +0000226 // if we did not clear the command's exe_ctx first
227 ExecutionContext exe_ctx(m_exe_ctx);
228 m_exe_ctx.Clear();
Jonas Devlieghere57179862019-04-27 06:19:42 +0000229 error = GetDebugger().SetPropertyValue(&exe_ctx, eVarSetOperationAssign,
230 var_name, var_value_cstr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000231 }
232
233 if (error.Fail()) {
234 result.AppendError(error.AsCString());
235 result.SetStatus(eReturnStatusFailed);
236 return false;
237 } else {
238 result.SetStatus(eReturnStatusSuccessFinishResult);
239 }
240
241 return result.Succeeded();
242 }
243
Jim Ingham5a988412012-06-08 21:56:10 +0000244private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000245 CommandOptions m_options;
Jim Ingham5a988412012-06-08 21:56:10 +0000246};
247
Jim Ingham5a988412012-06-08 21:56:10 +0000248// CommandObjectSettingsShow -- Show current values
Jim Ingham5a988412012-06-08 21:56:10 +0000249
Kate Stoneb9c1b512016-09-06 20:57:50 +0000250class CommandObjectSettingsShow : public CommandObjectParsed {
Jim Ingham5a988412012-06-08 21:56:10 +0000251public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000252 CommandObjectSettingsShow(CommandInterpreter &interpreter)
253 : CommandObjectParsed(interpreter, "settings show",
254 "Show matching debugger settings and their current "
255 "values. Defaults to showing all settings.",
256 nullptr) {
257 CommandArgumentEntry arg1;
258 CommandArgumentData var_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000259
Kate Stoneb9c1b512016-09-06 20:57:50 +0000260 // Define the first (and only) variant of this arg.
261 var_name_arg.arg_type = eArgTypeSettingVariableName;
262 var_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000263
Kate Stoneb9c1b512016-09-06 20:57:50 +0000264 // There is only one variant this argument could be; put it into the
265 // argument entry.
266 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000267
Kate Stoneb9c1b512016-09-06 20:57:50 +0000268 // Push the data for the first argument into the m_arguments vector.
269 m_arguments.push_back(arg1);
270 }
Jim Ingham5a988412012-06-08 21:56:10 +0000271
Kate Stoneb9c1b512016-09-06 20:57:50 +0000272 ~CommandObjectSettingsShow() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000273
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000274 int HandleArgumentCompletion(
275 CompletionRequest &request,
276 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000277 CommandCompletions::InvokeCommonCompletionCallbacks(
278 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000279 request, nullptr);
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000280 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000281 }
Jim Ingham5a988412012-06-08 21:56:10 +0000282
283protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000284 bool DoExecute(Args &args, CommandReturnObject &result) override {
285 result.SetStatus(eReturnStatusSuccessFinishResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000286
Zachary Turner97d2c402016-10-05 23:40:23 +0000287 if (!args.empty()) {
Zachary Turnerd6a24752016-11-22 17:10:15 +0000288 for (const auto &arg : args) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000289 Status error(GetDebugger().DumpPropertyValue(
Zachary Turnerd6a24752016-11-22 17:10:15 +0000290 &m_exe_ctx, result.GetOutputStream(), arg.ref,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000291 OptionValue::eDumpGroupValue));
292 if (error.Success()) {
293 result.GetOutputStream().EOL();
294 } else {
295 result.AppendError(error.AsCString());
296 result.SetStatus(eReturnStatusFailed);
Jim Ingham5a988412012-06-08 21:56:10 +0000297 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000298 }
299 } else {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000300 GetDebugger().DumpAllPropertyValues(&m_exe_ctx, result.GetOutputStream(),
301 OptionValue::eDumpGroupValue);
Jim Ingham5a988412012-06-08 21:56:10 +0000302 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000303
304 return result.Succeeded();
305 }
Jim Ingham5a988412012-06-08 21:56:10 +0000306};
307
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000308// CommandObjectSettingsWrite -- Write settings to file
Raphael Isemann6f4fb4e2019-07-12 15:30:55 +0000309#define LLDB_OPTIONS_settings_write
Raphael Isemannc5a2d742019-07-16 09:27:02 +0000310#include "CommandOptions.inc"
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000311
312class CommandObjectSettingsWrite : public CommandObjectParsed {
313public:
314 CommandObjectSettingsWrite(CommandInterpreter &interpreter)
315 : CommandObjectParsed(
316 interpreter, "settings export",
317 "Write matching debugger settings and their "
318 "current values to a file that can be read in with "
319 "\"settings read\". Defaults to writing all settings.",
320 nullptr),
321 m_options() {
322 CommandArgumentEntry arg1;
323 CommandArgumentData var_name_arg;
324
325 // Define the first (and only) variant of this arg.
326 var_name_arg.arg_type = eArgTypeSettingVariableName;
327 var_name_arg.arg_repetition = eArgRepeatOptional;
328
329 // There is only one variant this argument could be; put it into the
330 // argument entry.
331 arg1.push_back(var_name_arg);
332
333 // Push the data for the first argument into the m_arguments vector.
334 m_arguments.push_back(arg1);
335 }
336
337 ~CommandObjectSettingsWrite() override = default;
338
339 Options *GetOptions() override { return &m_options; }
340
341 class CommandOptions : public Options {
342 public:
343 CommandOptions() : Options() {}
344
345 ~CommandOptions() override = default;
346
347 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
348 ExecutionContext *execution_context) override {
349 Status error;
350 const int short_option = m_getopt_table[option_idx].val;
351
352 switch (short_option) {
353 case 'f':
354 m_filename.assign(option_arg);
355 break;
356 case 'a':
357 m_append = true;
358 break;
359 default:
360 error.SetErrorStringWithFormat("unrecognized option '%c'",
361 short_option);
362 break;
363 }
364
365 return error;
366 }
367
368 void OptionParsingStarting(ExecutionContext *execution_context) override {
369 m_filename.clear();
370 m_append = false;
371 }
372
373 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
374 return llvm::makeArrayRef(g_settings_write_options);
375 }
376
377 // Instance variables to hold the values for command options.
378 std::string m_filename;
379 bool m_append = false;
380 };
381
382protected:
383 bool DoExecute(Args &args, CommandReturnObject &result) override {
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000384 FileSpec file_spec(m_options.m_filename);
385 FileSystem::Instance().Resolve(file_spec);
386 std::string path(file_spec.GetPath());
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000387 uint32_t options = File::OpenOptions::eOpenOptionWrite |
388 File::OpenOptions::eOpenOptionCanCreate;
389 if (m_options.m_append)
390 options |= File::OpenOptions::eOpenOptionAppend;
391 else
392 options |= File::OpenOptions::eOpenOptionTruncate;
393
394 StreamFile out_file(path.c_str(), options,
395 lldb::eFilePermissionsFileDefault);
396
397 if (!out_file.GetFile().IsValid()) {
398 result.AppendErrorWithFormat("%s: unable to write to file", path.c_str());
399 result.SetStatus(eReturnStatusFailed);
400 return false;
401 }
402
403 // Exporting should not be context sensitive.
404 ExecutionContext clean_ctx;
405
406 if (args.empty()) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000407 GetDebugger().DumpAllPropertyValues(&clean_ctx, out_file,
408 OptionValue::eDumpGroupExport);
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000409 return result.Succeeded();
410 }
411
412 for (const auto &arg : args) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000413 Status error(GetDebugger().DumpPropertyValue(
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000414 &clean_ctx, out_file, arg.ref, OptionValue::eDumpGroupExport));
415 if (!error.Success()) {
416 result.AppendError(error.AsCString());
417 result.SetStatus(eReturnStatusFailed);
418 }
419 }
420
421 return result.Succeeded();
422 }
423
424private:
425 CommandOptions m_options;
426};
427
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000428// CommandObjectSettingsRead -- Read settings from file
Raphael Isemann6f4fb4e2019-07-12 15:30:55 +0000429#define LLDB_OPTIONS_settings_read
Raphael Isemannc5a2d742019-07-16 09:27:02 +0000430#include "CommandOptions.inc"
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000431
432class CommandObjectSettingsRead : public CommandObjectParsed {
433public:
434 CommandObjectSettingsRead(CommandInterpreter &interpreter)
435 : CommandObjectParsed(
436 interpreter, "settings read",
437 "Read settings previously saved to a file with \"settings write\".",
438 nullptr),
439 m_options() {}
440
441 ~CommandObjectSettingsRead() override = default;
442
443 Options *GetOptions() override { return &m_options; }
444
445 class CommandOptions : public Options {
446 public:
447 CommandOptions() : Options() {}
448
449 ~CommandOptions() override = default;
450
451 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
452 ExecutionContext *execution_context) override {
453 Status error;
454 const int short_option = m_getopt_table[option_idx].val;
455
456 switch (short_option) {
457 case 'f':
458 m_filename.assign(option_arg);
459 break;
460 default:
461 error.SetErrorStringWithFormat("unrecognized option '%c'",
462 short_option);
463 break;
464 }
465
466 return error;
467 }
468
469 void OptionParsingStarting(ExecutionContext *execution_context) override {
470 m_filename.clear();
471 }
472
473 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
474 return llvm::makeArrayRef(g_settings_read_options);
475 }
476
477 // Instance variables to hold the values for command options.
478 std::string m_filename;
479 };
480
481protected:
482 bool DoExecute(Args &command, CommandReturnObject &result) override {
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000483 FileSpec file(m_options.m_filename);
484 FileSystem::Instance().Resolve(file);
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000485 ExecutionContext clean_ctx;
486 CommandInterpreterRunOptions options;
487 options.SetAddToHistory(false);
488 options.SetEchoCommands(false);
489 options.SetPrintResults(true);
Jonas Devliegherec0b48ab2019-05-08 01:23:47 +0000490 options.SetPrintErrors(true);
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000491 options.SetStopOnError(false);
492 m_interpreter.HandleCommandsFromFile(file, &clean_ctx, options, result);
493 return result.Succeeded();
494 }
495
496private:
497 CommandOptions m_options;
498};
499
Jim Ingham5a988412012-06-08 21:56:10 +0000500// CommandObjectSettingsList -- List settable variables
Jim Ingham5a988412012-06-08 21:56:10 +0000501
Kate Stoneb9c1b512016-09-06 20:57:50 +0000502class CommandObjectSettingsList : public CommandObjectParsed {
Kate Stone7428a182016-07-14 22:03:10 +0000503public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000504 CommandObjectSettingsList(CommandInterpreter &interpreter)
505 : CommandObjectParsed(interpreter, "settings list",
506 "List and describe matching debugger settings. "
507 "Defaults to all listing all settings.",
508 nullptr) {
509 CommandArgumentEntry arg;
510 CommandArgumentData var_name_arg;
511 CommandArgumentData prefix_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000512
Kate Stoneb9c1b512016-09-06 20:57:50 +0000513 // Define the first variant of this arg.
514 var_name_arg.arg_type = eArgTypeSettingVariableName;
515 var_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000516
Kate Stoneb9c1b512016-09-06 20:57:50 +0000517 // Define the second variant of this arg.
518 prefix_name_arg.arg_type = eArgTypeSettingPrefix;
519 prefix_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000520
Kate Stoneb9c1b512016-09-06 20:57:50 +0000521 arg.push_back(var_name_arg);
522 arg.push_back(prefix_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000523
Kate Stoneb9c1b512016-09-06 20:57:50 +0000524 // Push the data for the first argument into the m_arguments vector.
525 m_arguments.push_back(arg);
526 }
Jim Ingham5a988412012-06-08 21:56:10 +0000527
Kate Stoneb9c1b512016-09-06 20:57:50 +0000528 ~CommandObjectSettingsList() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000529
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000530 int HandleArgumentCompletion(
531 CompletionRequest &request,
532 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000533 CommandCompletions::InvokeCommonCompletionCallbacks(
534 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000535 request, nullptr);
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000536 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000537 }
Jim Ingham5a988412012-06-08 21:56:10 +0000538
539protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000540 bool DoExecute(Args &args, CommandReturnObject &result) override {
541 result.SetStatus(eReturnStatusSuccessFinishResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000542
Kate Stoneb9c1b512016-09-06 20:57:50 +0000543 const bool will_modify = false;
544 const size_t argc = args.GetArgumentCount();
545 if (argc > 0) {
546 const bool dump_qualified_name = true;
Jim Ingham5a988412012-06-08 21:56:10 +0000547
Zachary Turner97d2c402016-10-05 23:40:23 +0000548 // TODO: Convert to StringRef based enumeration. Requires converting
549 // GetPropertyAtPath first.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000550 for (size_t i = 0; i < argc; ++i) {
551 const char *property_path = args.GetArgumentAtIndex(i);
Greg Clayton67cc0632012-08-22 17:17:09 +0000552
Kate Stoneb9c1b512016-09-06 20:57:50 +0000553 const Property *property =
Jonas Devlieghere57179862019-04-27 06:19:42 +0000554 GetDebugger().GetValueProperties()->GetPropertyAtPath(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000555 &m_exe_ctx, will_modify, property_path);
556
557 if (property) {
558 property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
559 dump_qualified_name);
560 } else {
561 result.AppendErrorWithFormat("invalid property path '%s'",
562 property_path);
563 result.SetStatus(eReturnStatusFailed);
Jim Ingham5a988412012-06-08 21:56:10 +0000564 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000565 }
566 } else {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000567 GetDebugger().DumpAllDescriptions(m_interpreter,
568 result.GetOutputStream());
Jim Ingham5a988412012-06-08 21:56:10 +0000569 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000570
571 return result.Succeeded();
572 }
Jim Ingham5a988412012-06-08 21:56:10 +0000573};
574
Jim Ingham5a988412012-06-08 21:56:10 +0000575// CommandObjectSettingsRemove
Jim Ingham5a988412012-06-08 21:56:10 +0000576
Kate Stoneb9c1b512016-09-06 20:57:50 +0000577class CommandObjectSettingsRemove : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000578public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000579 CommandObjectSettingsRemove(CommandInterpreter &interpreter)
580 : CommandObjectRaw(interpreter, "settings remove",
581 "Remove a value from a setting, specified by array "
Zachary Turnera4496982016-10-05 21:14:38 +0000582 "index or dictionary key.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000583 CommandArgumentEntry arg1;
584 CommandArgumentEntry arg2;
585 CommandArgumentData var_name_arg;
586 CommandArgumentData index_arg;
587 CommandArgumentData key_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000588
Kate Stoneb9c1b512016-09-06 20:57:50 +0000589 // Define the first (and only) variant of this arg.
590 var_name_arg.arg_type = eArgTypeSettingVariableName;
591 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000592
Kate Stoneb9c1b512016-09-06 20:57:50 +0000593 // There is only one variant this argument could be; put it into the
594 // argument entry.
595 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000596
Kate Stoneb9c1b512016-09-06 20:57:50 +0000597 // Define the first variant of this arg.
598 index_arg.arg_type = eArgTypeSettingIndex;
599 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000600
Kate Stoneb9c1b512016-09-06 20:57:50 +0000601 // Define the second variant of this arg.
602 key_arg.arg_type = eArgTypeSettingKey;
603 key_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000604
Kate Stoneb9c1b512016-09-06 20:57:50 +0000605 // Push both variants into this arg
606 arg2.push_back(index_arg);
607 arg2.push_back(key_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000608
Kate Stoneb9c1b512016-09-06 20:57:50 +0000609 // Push the data for the first argument into the m_arguments vector.
610 m_arguments.push_back(arg1);
611 m_arguments.push_back(arg2);
612 }
Jim Ingham5a988412012-06-08 21:56:10 +0000613
Kate Stoneb9c1b512016-09-06 20:57:50 +0000614 ~CommandObjectSettingsRemove() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000615
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000616 int HandleArgumentCompletion(
617 CompletionRequest &request,
618 OptionElementVector &opt_element_vector) override {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000619 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000620 CommandCompletions::InvokeCommonCompletionCallbacks(
621 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000622 request, nullptr);
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000623 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000624 }
Jim Ingham5a988412012-06-08 21:56:10 +0000625
626protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000627 bool DoExecute(llvm::StringRef command,
628 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000629 result.SetStatus(eReturnStatusSuccessFinishNoResult);
630
631 Args cmd_args(command);
632
633 // Process possible options.
634 if (!ParseOptions(cmd_args, result))
635 return false;
636
637 const size_t argc = cmd_args.GetArgumentCount();
638 if (argc == 0) {
639 result.AppendError("'settings set' takes an array or dictionary item, or "
640 "an array followed by one or more indexes, or a "
641 "dictionary followed by one or more key names to "
642 "remove");
643 result.SetStatus(eReturnStatusFailed);
644 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000645 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000646
647 const char *var_name = cmd_args.GetArgumentAtIndex(0);
648 if ((var_name == nullptr) || (var_name[0] == '\0')) {
649 result.AppendError(
650 "'settings set' command requires a valid variable name");
651 result.SetStatus(eReturnStatusFailed);
652 return false;
653 }
654
655 // Split the raw command into var_name and value pair.
656 llvm::StringRef raw_str(command);
657 std::string var_value_string = raw_str.split(var_name).second.str();
658 const char *var_value_cstr =
659 Args::StripSpaces(var_value_string, true, true, false);
660
Jonas Devlieghere57179862019-04-27 06:19:42 +0000661 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000662 &m_exe_ctx, eVarSetOperationRemove, var_name, var_value_cstr));
663 if (error.Fail()) {
664 result.AppendError(error.AsCString());
665 result.SetStatus(eReturnStatusFailed);
666 return false;
667 }
668
669 return result.Succeeded();
670 }
Jim Ingham5a988412012-06-08 21:56:10 +0000671};
672
Jim Ingham5a988412012-06-08 21:56:10 +0000673// CommandObjectSettingsReplace
Jim Ingham5a988412012-06-08 21:56:10 +0000674
Kate Stoneb9c1b512016-09-06 20:57:50 +0000675class CommandObjectSettingsReplace : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000676public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000677 CommandObjectSettingsReplace(CommandInterpreter &interpreter)
678 : CommandObjectRaw(interpreter, "settings replace",
679 "Replace the debugger setting value specified by "
Zachary Turnera4496982016-10-05 21:14:38 +0000680 "array index or dictionary key.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000681 CommandArgumentEntry arg1;
682 CommandArgumentEntry arg2;
683 CommandArgumentEntry arg3;
684 CommandArgumentData var_name_arg;
685 CommandArgumentData index_arg;
686 CommandArgumentData key_arg;
687 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000688
Kate Stoneb9c1b512016-09-06 20:57:50 +0000689 // Define the first (and only) variant of this arg.
690 var_name_arg.arg_type = eArgTypeSettingVariableName;
691 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000692
Kate Stoneb9c1b512016-09-06 20:57:50 +0000693 // There is only one variant this argument could be; put it into the
694 // argument entry.
695 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000696
Kate Stoneb9c1b512016-09-06 20:57:50 +0000697 // Define the first (variant of this arg.
698 index_arg.arg_type = eArgTypeSettingIndex;
699 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000700
Kate Stoneb9c1b512016-09-06 20:57:50 +0000701 // Define the second (variant of this arg.
702 key_arg.arg_type = eArgTypeSettingKey;
703 key_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000704
Kate Stoneb9c1b512016-09-06 20:57:50 +0000705 // Put both variants into this arg
706 arg2.push_back(index_arg);
707 arg2.push_back(key_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000708
Kate Stoneb9c1b512016-09-06 20:57:50 +0000709 // Define the first (and only) variant of this arg.
710 value_arg.arg_type = eArgTypeValue;
711 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000712
Kate Stoneb9c1b512016-09-06 20:57:50 +0000713 // There is only one variant this argument could be; put it into the
714 // argument entry.
715 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000716
Kate Stoneb9c1b512016-09-06 20:57:50 +0000717 // Push the data for the first argument into the m_arguments vector.
718 m_arguments.push_back(arg1);
719 m_arguments.push_back(arg2);
720 m_arguments.push_back(arg3);
721 }
Jim Ingham5a988412012-06-08 21:56:10 +0000722
Kate Stoneb9c1b512016-09-06 20:57:50 +0000723 ~CommandObjectSettingsReplace() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000724
Kate Stoneb9c1b512016-09-06 20:57:50 +0000725 // Overrides base class's behavior where WantsCompletion =
726 // !WantsRawCommandString.
727 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000728
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000729 int HandleArgumentCompletion(
730 CompletionRequest &request,
731 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000732 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000733 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000734 CommandCompletions::InvokeCommonCompletionCallbacks(
735 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000736 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +0000737
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000738 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000739 }
Jim Ingham5a988412012-06-08 21:56:10 +0000740
741protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000742 bool DoExecute(llvm::StringRef command,
743 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000744 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000745
Kate Stoneb9c1b512016-09-06 20:57:50 +0000746 Args cmd_args(command);
747 const char *var_name = cmd_args.GetArgumentAtIndex(0);
748 if ((var_name == nullptr) || (var_name[0] == '\0')) {
749 result.AppendError("'settings replace' command requires a valid variable "
750 "name; No value supplied");
751 result.SetStatus(eReturnStatusFailed);
752 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000753 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000754
755 // Split the raw command into var_name, index_value, and value triple.
756 llvm::StringRef raw_str(command);
757 std::string var_value_string = raw_str.split(var_name).second.str();
758 const char *var_value_cstr =
759 Args::StripSpaces(var_value_string, true, true, false);
760
Jonas Devlieghere57179862019-04-27 06:19:42 +0000761 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000762 &m_exe_ctx, eVarSetOperationReplace, var_name, var_value_cstr));
763 if (error.Fail()) {
764 result.AppendError(error.AsCString());
765 result.SetStatus(eReturnStatusFailed);
766 return false;
767 } else {
768 result.SetStatus(eReturnStatusSuccessFinishNoResult);
769 }
770
771 return result.Succeeded();
772 }
Jim Ingham5a988412012-06-08 21:56:10 +0000773};
774
Jim Ingham5a988412012-06-08 21:56:10 +0000775// CommandObjectSettingsInsertBefore
Jim Ingham5a988412012-06-08 21:56:10 +0000776
Kate Stoneb9c1b512016-09-06 20:57:50 +0000777class CommandObjectSettingsInsertBefore : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000778public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000779 CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
780 : CommandObjectRaw(interpreter, "settings insert-before",
781 "Insert one or more values into an debugger array "
782 "setting immediately before the specified element "
Zachary Turnera4496982016-10-05 21:14:38 +0000783 "index.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000784 CommandArgumentEntry arg1;
785 CommandArgumentEntry arg2;
786 CommandArgumentEntry arg3;
787 CommandArgumentData var_name_arg;
788 CommandArgumentData index_arg;
789 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000790
Kate Stoneb9c1b512016-09-06 20:57:50 +0000791 // Define the first (and only) variant of this arg.
792 var_name_arg.arg_type = eArgTypeSettingVariableName;
793 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000794
Kate Stoneb9c1b512016-09-06 20:57:50 +0000795 // There is only one variant this argument could be; put it into the
796 // argument entry.
797 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000798
Kate Stoneb9c1b512016-09-06 20:57:50 +0000799 // Define the first (variant of this arg.
800 index_arg.arg_type = eArgTypeSettingIndex;
801 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000802
Kate Stoneb9c1b512016-09-06 20:57:50 +0000803 // There is only one variant this argument could be; put it into the
804 // argument entry.
805 arg2.push_back(index_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000806
Kate Stoneb9c1b512016-09-06 20:57:50 +0000807 // Define the first (and only) variant of this arg.
808 value_arg.arg_type = eArgTypeValue;
809 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000810
Kate Stoneb9c1b512016-09-06 20:57:50 +0000811 // There is only one variant this argument could be; put it into the
812 // argument entry.
813 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000814
Kate Stoneb9c1b512016-09-06 20:57:50 +0000815 // Push the data for the first argument into the m_arguments vector.
816 m_arguments.push_back(arg1);
817 m_arguments.push_back(arg2);
818 m_arguments.push_back(arg3);
819 }
Jim Ingham5a988412012-06-08 21:56:10 +0000820
Kate Stoneb9c1b512016-09-06 20:57:50 +0000821 ~CommandObjectSettingsInsertBefore() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000822
Kate Stoneb9c1b512016-09-06 20:57:50 +0000823 // Overrides base class's behavior where WantsCompletion =
824 // !WantsRawCommandString.
825 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000826
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000827 int HandleArgumentCompletion(
828 CompletionRequest &request,
829 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000830 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000831 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000832 CommandCompletions::InvokeCommonCompletionCallbacks(
833 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000834 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +0000835
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000836 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000837 }
Jim Ingham5a988412012-06-08 21:56:10 +0000838
839protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000840 bool DoExecute(llvm::StringRef command,
841 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000842 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000843
Kate Stoneb9c1b512016-09-06 20:57:50 +0000844 Args cmd_args(command);
845 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +0000846
Kate Stoneb9c1b512016-09-06 20:57:50 +0000847 if (argc < 3) {
848 result.AppendError("'settings insert-before' takes more arguments");
849 result.SetStatus(eReturnStatusFailed);
850 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000851 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000852
853 const char *var_name = cmd_args.GetArgumentAtIndex(0);
854 if ((var_name == nullptr) || (var_name[0] == '\0')) {
855 result.AppendError("'settings insert-before' command requires a valid "
856 "variable name; No value supplied");
857 result.SetStatus(eReturnStatusFailed);
858 return false;
859 }
860
861 // Split the raw command into var_name, index_value, and value triple.
862 llvm::StringRef raw_str(command);
863 std::string var_value_string = raw_str.split(var_name).second.str();
864 const char *var_value_cstr =
865 Args::StripSpaces(var_value_string, true, true, false);
866
Jonas Devlieghere57179862019-04-27 06:19:42 +0000867 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000868 &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value_cstr));
869 if (error.Fail()) {
870 result.AppendError(error.AsCString());
871 result.SetStatus(eReturnStatusFailed);
872 return false;
873 }
874
875 return result.Succeeded();
876 }
Jim Ingham5a988412012-06-08 21:56:10 +0000877};
878
Jim Ingham5a988412012-06-08 21:56:10 +0000879// CommandObjectSettingInsertAfter
Jim Ingham5a988412012-06-08 21:56:10 +0000880
Kate Stoneb9c1b512016-09-06 20:57:50 +0000881class CommandObjectSettingsInsertAfter : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000882public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000883 CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
884 : CommandObjectRaw(interpreter, "settings insert-after",
885 "Insert one or more values into a debugger array "
Zachary Turnera4496982016-10-05 21:14:38 +0000886 "settings after the specified element index.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000887 CommandArgumentEntry arg1;
888 CommandArgumentEntry arg2;
889 CommandArgumentEntry arg3;
890 CommandArgumentData var_name_arg;
891 CommandArgumentData index_arg;
892 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000893
Kate Stoneb9c1b512016-09-06 20:57:50 +0000894 // Define the first (and only) variant of this arg.
895 var_name_arg.arg_type = eArgTypeSettingVariableName;
896 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000897
Kate Stoneb9c1b512016-09-06 20:57:50 +0000898 // There is only one variant this argument could be; put it into the
899 // argument entry.
900 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000901
Kate Stoneb9c1b512016-09-06 20:57:50 +0000902 // Define the first (variant of this arg.
903 index_arg.arg_type = eArgTypeSettingIndex;
904 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000905
Kate Stoneb9c1b512016-09-06 20:57:50 +0000906 // There is only one variant this argument could be; put it into the
907 // argument entry.
908 arg2.push_back(index_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000909
Kate Stoneb9c1b512016-09-06 20:57:50 +0000910 // Define the first (and only) variant of this arg.
911 value_arg.arg_type = eArgTypeValue;
912 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000913
Kate Stoneb9c1b512016-09-06 20:57:50 +0000914 // There is only one variant this argument could be; put it into the
915 // argument entry.
916 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000917
Kate Stoneb9c1b512016-09-06 20:57:50 +0000918 // Push the data for the first argument into the m_arguments vector.
919 m_arguments.push_back(arg1);
920 m_arguments.push_back(arg2);
921 m_arguments.push_back(arg3);
922 }
Jim Ingham5a988412012-06-08 21:56:10 +0000923
Kate Stoneb9c1b512016-09-06 20:57:50 +0000924 ~CommandObjectSettingsInsertAfter() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000925
Kate Stoneb9c1b512016-09-06 20:57:50 +0000926 // Overrides base class's behavior where WantsCompletion =
927 // !WantsRawCommandString.
928 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000929
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000930 int HandleArgumentCompletion(
931 CompletionRequest &request,
932 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000933 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000934 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000935 CommandCompletions::InvokeCommonCompletionCallbacks(
936 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000937 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +0000938
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000939 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000940 }
941
Jim Ingham5a988412012-06-08 21:56:10 +0000942protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000943 bool DoExecute(llvm::StringRef command,
944 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000945 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000946
Kate Stoneb9c1b512016-09-06 20:57:50 +0000947 Args cmd_args(command);
948 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +0000949
Kate Stoneb9c1b512016-09-06 20:57:50 +0000950 if (argc < 3) {
951 result.AppendError("'settings insert-after' takes more arguments");
952 result.SetStatus(eReturnStatusFailed);
953 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000954 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000955
956 const char *var_name = cmd_args.GetArgumentAtIndex(0);
957 if ((var_name == nullptr) || (var_name[0] == '\0')) {
958 result.AppendError("'settings insert-after' command requires a valid "
959 "variable name; No value supplied");
960 result.SetStatus(eReturnStatusFailed);
961 return false;
962 }
963
964 // Split the raw command into var_name, index_value, and value triple.
965 llvm::StringRef raw_str(command);
966 std::string var_value_string = raw_str.split(var_name).second.str();
967 const char *var_value_cstr =
968 Args::StripSpaces(var_value_string, true, true, false);
969
Jonas Devlieghere57179862019-04-27 06:19:42 +0000970 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000971 &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value_cstr));
972 if (error.Fail()) {
973 result.AppendError(error.AsCString());
974 result.SetStatus(eReturnStatusFailed);
975 return false;
976 }
977
978 return result.Succeeded();
979 }
Jim Ingham5a988412012-06-08 21:56:10 +0000980};
981
Jim Ingham5a988412012-06-08 21:56:10 +0000982// CommandObjectSettingsAppend
Jim Ingham5a988412012-06-08 21:56:10 +0000983
Kate Stoneb9c1b512016-09-06 20:57:50 +0000984class CommandObjectSettingsAppend : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000985public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000986 CommandObjectSettingsAppend(CommandInterpreter &interpreter)
987 : CommandObjectRaw(interpreter, "settings append",
988 "Append one or more values to a debugger array, "
Zachary Turnera4496982016-10-05 21:14:38 +0000989 "dictionary, or string setting.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000990 CommandArgumentEntry arg1;
991 CommandArgumentEntry arg2;
992 CommandArgumentData var_name_arg;
993 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000994
Kate Stoneb9c1b512016-09-06 20:57:50 +0000995 // Define the first (and only) variant of this arg.
996 var_name_arg.arg_type = eArgTypeSettingVariableName;
997 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000998
Kate Stoneb9c1b512016-09-06 20:57:50 +0000999 // There is only one variant this argument could be; put it into the
1000 // argument entry.
1001 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001002
Kate Stoneb9c1b512016-09-06 20:57:50 +00001003 // Define the first (and only) variant of this arg.
1004 value_arg.arg_type = eArgTypeValue;
1005 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +00001006
Kate Stoneb9c1b512016-09-06 20:57:50 +00001007 // There is only one variant this argument could be; put it into the
1008 // argument entry.
1009 arg2.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001010
Kate Stoneb9c1b512016-09-06 20:57:50 +00001011 // Push the data for the first argument into the m_arguments vector.
1012 m_arguments.push_back(arg1);
1013 m_arguments.push_back(arg2);
1014 }
Jim Ingham5a988412012-06-08 21:56:10 +00001015
Kate Stoneb9c1b512016-09-06 20:57:50 +00001016 ~CommandObjectSettingsAppend() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001017
Kate Stoneb9c1b512016-09-06 20:57:50 +00001018 // Overrides base class's behavior where WantsCompletion =
1019 // !WantsRawCommandString.
1020 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +00001021
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001022 int HandleArgumentCompletion(
1023 CompletionRequest &request,
1024 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001025 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001026 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001027 CommandCompletions::InvokeCommonCompletionCallbacks(
1028 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +00001029 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +00001030
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +00001031 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001032 }
Jim Ingham5a988412012-06-08 21:56:10 +00001033
1034protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +00001035 bool DoExecute(llvm::StringRef command,
1036 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001037 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1038 Args cmd_args(command);
1039 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +00001040
Kate Stoneb9c1b512016-09-06 20:57:50 +00001041 if (argc < 2) {
1042 result.AppendError("'settings append' takes more arguments");
1043 result.SetStatus(eReturnStatusFailed);
1044 return false;
Jim Ingham5a988412012-06-08 21:56:10 +00001045 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001046
1047 const char *var_name = cmd_args.GetArgumentAtIndex(0);
1048 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1049 result.AppendError("'settings append' command requires a valid variable "
1050 "name; No value supplied");
1051 result.SetStatus(eReturnStatusFailed);
1052 return false;
1053 }
1054
Adrian Prantl05097242018-04-30 16:49:04 +00001055 // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
1056 // character string later on.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001057
1058 // Split the raw command into var_name and value pair.
1059 llvm::StringRef raw_str(command);
1060 std::string var_value_string = raw_str.split(var_name).second.str();
1061 const char *var_value_cstr =
1062 Args::StripSpaces(var_value_string, true, true, false);
1063
Jonas Devlieghere57179862019-04-27 06:19:42 +00001064 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001065 &m_exe_ctx, eVarSetOperationAppend, var_name, var_value_cstr));
1066 if (error.Fail()) {
1067 result.AppendError(error.AsCString());
1068 result.SetStatus(eReturnStatusFailed);
1069 return false;
1070 }
1071
1072 return result.Succeeded();
1073 }
Jim Ingham5a988412012-06-08 21:56:10 +00001074};
1075
Jim Ingham5a988412012-06-08 21:56:10 +00001076// CommandObjectSettingsClear
Jim Ingham5a988412012-06-08 21:56:10 +00001077
Kate Stoneb9c1b512016-09-06 20:57:50 +00001078class CommandObjectSettingsClear : public CommandObjectParsed {
Jim Ingham5a988412012-06-08 21:56:10 +00001079public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001080 CommandObjectSettingsClear(CommandInterpreter &interpreter)
1081 : CommandObjectParsed(
1082 interpreter, "settings clear",
1083 "Clear a debugger setting array, dictionary, or string.", nullptr) {
1084 CommandArgumentEntry arg;
1085 CommandArgumentData var_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +00001086
Kate Stoneb9c1b512016-09-06 20:57:50 +00001087 // Define the first (and only) variant of this arg.
1088 var_name_arg.arg_type = eArgTypeSettingVariableName;
1089 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +00001090
Kate Stoneb9c1b512016-09-06 20:57:50 +00001091 // There is only one variant this argument could be; put it into the
1092 // argument entry.
1093 arg.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001094
Kate Stoneb9c1b512016-09-06 20:57:50 +00001095 // Push the data for the first argument into the m_arguments vector.
1096 m_arguments.push_back(arg);
1097 }
Jim Ingham5a988412012-06-08 21:56:10 +00001098
Kate Stoneb9c1b512016-09-06 20:57:50 +00001099 ~CommandObjectSettingsClear() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001100
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001101 int HandleArgumentCompletion(
1102 CompletionRequest &request,
1103 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001104 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001105 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001106 CommandCompletions::InvokeCommonCompletionCallbacks(
1107 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +00001108 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +00001109
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +00001110 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001111 }
Jim Ingham5a988412012-06-08 21:56:10 +00001112
1113protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001114 bool DoExecute(Args &command, CommandReturnObject &result) override {
1115 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1116 const size_t argc = command.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +00001117
Kate Stoneb9c1b512016-09-06 20:57:50 +00001118 if (argc != 1) {
1119 result.AppendError("'settings clear' takes exactly one argument");
1120 result.SetStatus(eReturnStatusFailed);
1121 return false;
Jim Ingham5a988412012-06-08 21:56:10 +00001122 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001123
1124 const char *var_name = command.GetArgumentAtIndex(0);
1125 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1126 result.AppendError("'settings clear' command requires a valid variable "
1127 "name; No value supplied");
1128 result.SetStatus(eReturnStatusFailed);
1129 return false;
1130 }
1131
Jonas Devlieghere57179862019-04-27 06:19:42 +00001132 Status error(GetDebugger().SetPropertyValue(
Zachary Turner31d97a52016-11-17 18:08:12 +00001133 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001134 if (error.Fail()) {
1135 result.AppendError(error.AsCString());
1136 result.SetStatus(eReturnStatusFailed);
1137 return false;
1138 }
1139
1140 return result.Succeeded();
1141 }
Jim Ingham5a988412012-06-08 21:56:10 +00001142};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001143
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001144// CommandObjectMultiwordSettings
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001145
Kate Stoneb9c1b512016-09-06 20:57:50 +00001146CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
1147 CommandInterpreter &interpreter)
1148 : CommandObjectMultiword(interpreter, "settings",
1149 "Commands for managing LLDB settings.",
1150 "settings <subcommand> [<command-options>]") {
1151 LoadSubCommand("set",
1152 CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
1153 LoadSubCommand("show",
1154 CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
1155 LoadSubCommand("list",
1156 CommandObjectSP(new CommandObjectSettingsList(interpreter)));
1157 LoadSubCommand("remove",
1158 CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
1159 LoadSubCommand("replace", CommandObjectSP(
1160 new CommandObjectSettingsReplace(interpreter)));
1161 LoadSubCommand(
1162 "insert-before",
1163 CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
1164 LoadSubCommand(
1165 "insert-after",
1166 CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
1167 LoadSubCommand("append",
1168 CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
1169 LoadSubCommand("clear",
1170 CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +00001171 LoadSubCommand("write",
1172 CommandObjectSP(new CommandObjectSettingsWrite(interpreter)));
1173 LoadSubCommand("read",
1174 CommandObjectSP(new CommandObjectSettingsRead(interpreter)));
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001175}
1176
Eugene Zelenko3f18ea02016-02-24 02:05:55 +00001177CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default;