blob: 5f6a4dc97aee1114c47e57ef1222e3d790089033 [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:
Raphael Isemann36162012019-08-22 08:08:05 +0000107 llvm_unreachable("Unimplemented option");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000108 }
109
110 return error;
Jim Ingham5a988412012-06-08 21:56:10 +0000111 }
112
Kate Stoneb9c1b512016-09-06 20:57:50 +0000113 void OptionParsingStarting(ExecutionContext *execution_context) override {
114 m_global = false;
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000115 m_force = false;
Jim Ingham5a988412012-06-08 21:56:10 +0000116 }
Jim Ingham5a988412012-06-08 21:56:10 +0000117
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000118 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +0000119 return llvm::makeArrayRef(g_settings_set_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000120 }
Jim Ingham5a988412012-06-08 21:56:10 +0000121
Kate Stoneb9c1b512016-09-06 20:57:50 +0000122 // Instance variables to hold the values for command options.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000123 bool m_global;
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000124 bool m_force;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000125 };
Jim Ingham5a988412012-06-08 21:56:10 +0000126
Raphael Isemannae34ed22019-08-22 07:41:23 +0000127 void
128 HandleArgumentCompletion(CompletionRequest &request,
129 OptionElementVector &opt_element_vector) override {
Jim Ingham5a988412012-06-08 21:56:10 +0000130
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000131 const size_t argc = request.GetParsedLine().GetArgumentCount();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000132 const char *arg = nullptr;
133 int setting_var_idx;
Pavel Labath5f56fca2018-03-09 10:39:40 +0000134 for (setting_var_idx = 0; setting_var_idx < static_cast<int>(argc);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000135 ++setting_var_idx) {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000136 arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000137 if (arg && arg[0] != '-')
138 break; // We found our setting variable name index
Jim Ingham5a988412012-06-08 21:56:10 +0000139 }
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000140 if (request.GetCursorIndex() == setting_var_idx) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000141 // Attempting to complete setting variable name
142 CommandCompletions::InvokeCommonCompletionCallbacks(
143 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000144 request, nullptr);
Raphael Isemann1153dc92019-08-22 09:02:54 +0000145 return;
146 }
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000147 arg =
148 request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000149
Raphael Isemann1153dc92019-08-22 09:02:54 +0000150 if (!arg)
151 return;
152
153 // Complete option name
154 if (arg[0] != '-')
155 return;
156
157 // Complete setting value
158 const char *setting_var_name =
159 request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
160 Status error;
161 lldb::OptionValueSP value_sp(GetDebugger().GetPropertyValue(
162 &m_exe_ctx, setting_var_name, false, error));
163 if (!value_sp)
164 return;
165 value_sp->AutoComplete(m_interpreter, request);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000166 }
167
Jim Ingham5a988412012-06-08 21:56:10 +0000168protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000169 bool DoExecute(llvm::StringRef command,
170 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000171 Args cmd_args(command);
Jim Ingham5a988412012-06-08 21:56:10 +0000172
Kate Stoneb9c1b512016-09-06 20:57:50 +0000173 // Process possible options.
174 if (!ParseOptions(cmd_args, result))
175 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000176
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000177 const size_t min_argc = m_options.m_force ? 1 : 2;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000178 const size_t argc = cmd_args.GetArgumentCount();
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000179
180 if ((argc < min_argc) && (!m_options.m_global)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000181 result.AppendError("'settings set' takes more arguments");
182 result.SetStatus(eReturnStatusFailed);
183 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000184 }
Eugene Zelenko3f18ea02016-02-24 02:05:55 +0000185
Kate Stoneb9c1b512016-09-06 20:57:50 +0000186 const char *var_name = cmd_args.GetArgumentAtIndex(0);
187 if ((var_name == nullptr) || (var_name[0] == '\0')) {
188 result.AppendError(
189 "'settings set' command requires a valid variable name");
190 result.SetStatus(eReturnStatusFailed);
191 return false;
192 }
193
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000194 // A missing value corresponds to clearing the setting when "force" is
195 // specified.
196 if (argc == 1 && m_options.m_force) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000197 Status error(GetDebugger().SetPropertyValue(
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000198 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
199 if (error.Fail()) {
200 result.AppendError(error.AsCString());
201 result.SetStatus(eReturnStatusFailed);
202 return false;
203 }
204 return result.Succeeded();
205 }
206
Kate Stoneb9c1b512016-09-06 20:57:50 +0000207 // Split the raw command into var_name and value pair.
208 llvm::StringRef raw_str(command);
209 std::string var_value_string = raw_str.split(var_name).second.str();
210 const char *var_value_cstr =
211 Args::StripSpaces(var_value_string, true, false, false);
212
Zachary Turner97206d52017-05-12 04:51:55 +0000213 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000214 if (m_options.m_global) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000215 error = GetDebugger().SetPropertyValue(nullptr, eVarSetOperationAssign,
216 var_name, var_value_cstr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000217 }
218
219 if (error.Success()) {
220 // FIXME this is the same issue as the one in commands script import
221 // we could be setting target.load-script-from-symbol-file which would
Adrian Prantl05097242018-04-30 16:49:04 +0000222 // cause Python scripts to be loaded, which could run LLDB commands (e.g.
223 // settings set target.process.python-os-plugin-path) and cause a crash
Kate Stoneb9c1b512016-09-06 20:57:50 +0000224 // if we did not clear the command's exe_ctx first
225 ExecutionContext exe_ctx(m_exe_ctx);
226 m_exe_ctx.Clear();
Jonas Devlieghere57179862019-04-27 06:19:42 +0000227 error = GetDebugger().SetPropertyValue(&exe_ctx, eVarSetOperationAssign,
228 var_name, var_value_cstr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000229 }
230
231 if (error.Fail()) {
232 result.AppendError(error.AsCString());
233 result.SetStatus(eReturnStatusFailed);
234 return false;
235 } else {
236 result.SetStatus(eReturnStatusSuccessFinishResult);
237 }
238
239 return result.Succeeded();
240 }
241
Jim Ingham5a988412012-06-08 21:56:10 +0000242private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000243 CommandOptions m_options;
Jim Ingham5a988412012-06-08 21:56:10 +0000244};
245
Jim Ingham5a988412012-06-08 21:56:10 +0000246// CommandObjectSettingsShow -- Show current values
Jim Ingham5a988412012-06-08 21:56:10 +0000247
Kate Stoneb9c1b512016-09-06 20:57:50 +0000248class CommandObjectSettingsShow : public CommandObjectParsed {
Jim Ingham5a988412012-06-08 21:56:10 +0000249public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000250 CommandObjectSettingsShow(CommandInterpreter &interpreter)
251 : CommandObjectParsed(interpreter, "settings show",
252 "Show matching debugger settings and their current "
253 "values. Defaults to showing all settings.",
254 nullptr) {
255 CommandArgumentEntry arg1;
256 CommandArgumentData var_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000257
Kate Stoneb9c1b512016-09-06 20:57:50 +0000258 // Define the first (and only) variant of this arg.
259 var_name_arg.arg_type = eArgTypeSettingVariableName;
260 var_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000261
Kate Stoneb9c1b512016-09-06 20:57:50 +0000262 // There is only one variant this argument could be; put it into the
263 // argument entry.
264 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000265
Kate Stoneb9c1b512016-09-06 20:57:50 +0000266 // Push the data for the first argument into the m_arguments vector.
267 m_arguments.push_back(arg1);
268 }
Jim Ingham5a988412012-06-08 21:56:10 +0000269
Kate Stoneb9c1b512016-09-06 20:57:50 +0000270 ~CommandObjectSettingsShow() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000271
Raphael Isemannae34ed22019-08-22 07:41:23 +0000272 void
273 HandleArgumentCompletion(CompletionRequest &request,
274 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000275 CommandCompletions::InvokeCommonCompletionCallbacks(
276 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000277 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000278 }
Jim Ingham5a988412012-06-08 21:56:10 +0000279
280protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000281 bool DoExecute(Args &args, CommandReturnObject &result) override {
282 result.SetStatus(eReturnStatusSuccessFinishResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000283
Zachary Turner97d2c402016-10-05 23:40:23 +0000284 if (!args.empty()) {
Zachary Turnerd6a24752016-11-22 17:10:15 +0000285 for (const auto &arg : args) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000286 Status error(GetDebugger().DumpPropertyValue(
Zachary Turnerd6a24752016-11-22 17:10:15 +0000287 &m_exe_ctx, result.GetOutputStream(), arg.ref,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000288 OptionValue::eDumpGroupValue));
289 if (error.Success()) {
290 result.GetOutputStream().EOL();
291 } else {
292 result.AppendError(error.AsCString());
293 result.SetStatus(eReturnStatusFailed);
Jim Ingham5a988412012-06-08 21:56:10 +0000294 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000295 }
296 } else {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000297 GetDebugger().DumpAllPropertyValues(&m_exe_ctx, result.GetOutputStream(),
298 OptionValue::eDumpGroupValue);
Jim Ingham5a988412012-06-08 21:56:10 +0000299 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000300
301 return result.Succeeded();
302 }
Jim Ingham5a988412012-06-08 21:56:10 +0000303};
304
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000305// CommandObjectSettingsWrite -- Write settings to file
Raphael Isemann6f4fb4e2019-07-12 15:30:55 +0000306#define LLDB_OPTIONS_settings_write
Raphael Isemannc5a2d742019-07-16 09:27:02 +0000307#include "CommandOptions.inc"
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000308
309class CommandObjectSettingsWrite : public CommandObjectParsed {
310public:
311 CommandObjectSettingsWrite(CommandInterpreter &interpreter)
312 : CommandObjectParsed(
313 interpreter, "settings export",
314 "Write matching debugger settings and their "
315 "current values to a file that can be read in with "
316 "\"settings read\". Defaults to writing all settings.",
317 nullptr),
318 m_options() {
319 CommandArgumentEntry arg1;
320 CommandArgumentData var_name_arg;
321
322 // Define the first (and only) variant of this arg.
323 var_name_arg.arg_type = eArgTypeSettingVariableName;
324 var_name_arg.arg_repetition = eArgRepeatOptional;
325
326 // There is only one variant this argument could be; put it into the
327 // argument entry.
328 arg1.push_back(var_name_arg);
329
330 // Push the data for the first argument into the m_arguments vector.
331 m_arguments.push_back(arg1);
332 }
333
334 ~CommandObjectSettingsWrite() override = default;
335
336 Options *GetOptions() override { return &m_options; }
337
338 class CommandOptions : public Options {
339 public:
340 CommandOptions() : Options() {}
341
342 ~CommandOptions() override = default;
343
344 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
345 ExecutionContext *execution_context) override {
346 Status error;
347 const int short_option = m_getopt_table[option_idx].val;
348
349 switch (short_option) {
350 case 'f':
351 m_filename.assign(option_arg);
352 break;
353 case 'a':
354 m_append = true;
355 break;
356 default:
Raphael Isemann36162012019-08-22 08:08:05 +0000357 llvm_unreachable("Unimplemented option");
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000358 }
359
360 return error;
361 }
362
363 void OptionParsingStarting(ExecutionContext *execution_context) override {
364 m_filename.clear();
365 m_append = false;
366 }
367
368 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
369 return llvm::makeArrayRef(g_settings_write_options);
370 }
371
372 // Instance variables to hold the values for command options.
373 std::string m_filename;
374 bool m_append = false;
375 };
376
377protected:
378 bool DoExecute(Args &args, CommandReturnObject &result) override {
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000379 FileSpec file_spec(m_options.m_filename);
380 FileSystem::Instance().Resolve(file_spec);
381 std::string path(file_spec.GetPath());
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000382 uint32_t options = File::OpenOptions::eOpenOptionWrite |
383 File::OpenOptions::eOpenOptionCanCreate;
384 if (m_options.m_append)
385 options |= File::OpenOptions::eOpenOptionAppend;
386 else
387 options |= File::OpenOptions::eOpenOptionTruncate;
388
389 StreamFile out_file(path.c_str(), options,
390 lldb::eFilePermissionsFileDefault);
391
392 if (!out_file.GetFile().IsValid()) {
393 result.AppendErrorWithFormat("%s: unable to write to file", path.c_str());
394 result.SetStatus(eReturnStatusFailed);
395 return false;
396 }
397
398 // Exporting should not be context sensitive.
399 ExecutionContext clean_ctx;
400
401 if (args.empty()) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000402 GetDebugger().DumpAllPropertyValues(&clean_ctx, out_file,
403 OptionValue::eDumpGroupExport);
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000404 return result.Succeeded();
405 }
406
407 for (const auto &arg : args) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000408 Status error(GetDebugger().DumpPropertyValue(
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000409 &clean_ctx, out_file, arg.ref, OptionValue::eDumpGroupExport));
410 if (!error.Success()) {
411 result.AppendError(error.AsCString());
412 result.SetStatus(eReturnStatusFailed);
413 }
414 }
415
416 return result.Succeeded();
417 }
418
419private:
420 CommandOptions m_options;
421};
422
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000423// CommandObjectSettingsRead -- Read settings from file
Raphael Isemann6f4fb4e2019-07-12 15:30:55 +0000424#define LLDB_OPTIONS_settings_read
Raphael Isemannc5a2d742019-07-16 09:27:02 +0000425#include "CommandOptions.inc"
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000426
427class CommandObjectSettingsRead : public CommandObjectParsed {
428public:
429 CommandObjectSettingsRead(CommandInterpreter &interpreter)
430 : CommandObjectParsed(
431 interpreter, "settings read",
432 "Read settings previously saved to a file with \"settings write\".",
433 nullptr),
434 m_options() {}
435
436 ~CommandObjectSettingsRead() override = default;
437
438 Options *GetOptions() override { return &m_options; }
439
440 class CommandOptions : public Options {
441 public:
442 CommandOptions() : Options() {}
443
444 ~CommandOptions() override = default;
445
446 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
447 ExecutionContext *execution_context) override {
448 Status error;
449 const int short_option = m_getopt_table[option_idx].val;
450
451 switch (short_option) {
452 case 'f':
453 m_filename.assign(option_arg);
454 break;
455 default:
Raphael Isemann36162012019-08-22 08:08:05 +0000456 llvm_unreachable("Unimplemented option");
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000457 }
458
459 return error;
460 }
461
462 void OptionParsingStarting(ExecutionContext *execution_context) override {
463 m_filename.clear();
464 }
465
466 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
467 return llvm::makeArrayRef(g_settings_read_options);
468 }
469
470 // Instance variables to hold the values for command options.
471 std::string m_filename;
472 };
473
474protected:
475 bool DoExecute(Args &command, CommandReturnObject &result) override {
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000476 FileSpec file(m_options.m_filename);
477 FileSystem::Instance().Resolve(file);
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000478 ExecutionContext clean_ctx;
479 CommandInterpreterRunOptions options;
480 options.SetAddToHistory(false);
481 options.SetEchoCommands(false);
482 options.SetPrintResults(true);
Jonas Devliegherec0b48ab2019-05-08 01:23:47 +0000483 options.SetPrintErrors(true);
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000484 options.SetStopOnError(false);
485 m_interpreter.HandleCommandsFromFile(file, &clean_ctx, options, result);
486 return result.Succeeded();
487 }
488
489private:
490 CommandOptions m_options;
491};
492
Jim Ingham5a988412012-06-08 21:56:10 +0000493// CommandObjectSettingsList -- List settable variables
Jim Ingham5a988412012-06-08 21:56:10 +0000494
Kate Stoneb9c1b512016-09-06 20:57:50 +0000495class CommandObjectSettingsList : public CommandObjectParsed {
Kate Stone7428a182016-07-14 22:03:10 +0000496public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000497 CommandObjectSettingsList(CommandInterpreter &interpreter)
498 : CommandObjectParsed(interpreter, "settings list",
499 "List and describe matching debugger settings. "
500 "Defaults to all listing all settings.",
501 nullptr) {
502 CommandArgumentEntry arg;
503 CommandArgumentData var_name_arg;
504 CommandArgumentData prefix_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000505
Kate Stoneb9c1b512016-09-06 20:57:50 +0000506 // Define the first variant of this arg.
507 var_name_arg.arg_type = eArgTypeSettingVariableName;
508 var_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000509
Kate Stoneb9c1b512016-09-06 20:57:50 +0000510 // Define the second variant of this arg.
511 prefix_name_arg.arg_type = eArgTypeSettingPrefix;
512 prefix_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000513
Kate Stoneb9c1b512016-09-06 20:57:50 +0000514 arg.push_back(var_name_arg);
515 arg.push_back(prefix_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000516
Kate Stoneb9c1b512016-09-06 20:57:50 +0000517 // Push the data for the first argument into the m_arguments vector.
518 m_arguments.push_back(arg);
519 }
Jim Ingham5a988412012-06-08 21:56:10 +0000520
Kate Stoneb9c1b512016-09-06 20:57:50 +0000521 ~CommandObjectSettingsList() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000522
Raphael Isemannae34ed22019-08-22 07:41:23 +0000523 void
524 HandleArgumentCompletion(CompletionRequest &request,
525 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000526 CommandCompletions::InvokeCommonCompletionCallbacks(
527 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000528 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000529 }
Jim Ingham5a988412012-06-08 21:56:10 +0000530
531protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000532 bool DoExecute(Args &args, CommandReturnObject &result) override {
533 result.SetStatus(eReturnStatusSuccessFinishResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000534
Kate Stoneb9c1b512016-09-06 20:57:50 +0000535 const bool will_modify = false;
536 const size_t argc = args.GetArgumentCount();
537 if (argc > 0) {
538 const bool dump_qualified_name = true;
Jim Ingham5a988412012-06-08 21:56:10 +0000539
Zachary Turner97d2c402016-10-05 23:40:23 +0000540 // TODO: Convert to StringRef based enumeration. Requires converting
541 // GetPropertyAtPath first.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000542 for (size_t i = 0; i < argc; ++i) {
543 const char *property_path = args.GetArgumentAtIndex(i);
Greg Clayton67cc0632012-08-22 17:17:09 +0000544
Kate Stoneb9c1b512016-09-06 20:57:50 +0000545 const Property *property =
Jonas Devlieghere57179862019-04-27 06:19:42 +0000546 GetDebugger().GetValueProperties()->GetPropertyAtPath(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000547 &m_exe_ctx, will_modify, property_path);
548
549 if (property) {
550 property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
551 dump_qualified_name);
552 } else {
553 result.AppendErrorWithFormat("invalid property path '%s'",
554 property_path);
555 result.SetStatus(eReturnStatusFailed);
Jim Ingham5a988412012-06-08 21:56:10 +0000556 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000557 }
558 } else {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000559 GetDebugger().DumpAllDescriptions(m_interpreter,
560 result.GetOutputStream());
Jim Ingham5a988412012-06-08 21:56:10 +0000561 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000562
563 return result.Succeeded();
564 }
Jim Ingham5a988412012-06-08 21:56:10 +0000565};
566
Jim Ingham5a988412012-06-08 21:56:10 +0000567// CommandObjectSettingsRemove
Jim Ingham5a988412012-06-08 21:56:10 +0000568
Kate Stoneb9c1b512016-09-06 20:57:50 +0000569class CommandObjectSettingsRemove : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000570public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000571 CommandObjectSettingsRemove(CommandInterpreter &interpreter)
572 : CommandObjectRaw(interpreter, "settings remove",
573 "Remove a value from a setting, specified by array "
Zachary Turnera4496982016-10-05 21:14:38 +0000574 "index or dictionary key.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000575 CommandArgumentEntry arg1;
576 CommandArgumentEntry arg2;
577 CommandArgumentData var_name_arg;
578 CommandArgumentData index_arg;
579 CommandArgumentData key_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000580
Kate Stoneb9c1b512016-09-06 20:57:50 +0000581 // Define the first (and only) variant of this arg.
582 var_name_arg.arg_type = eArgTypeSettingVariableName;
583 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000584
Kate Stoneb9c1b512016-09-06 20:57:50 +0000585 // There is only one variant this argument could be; put it into the
586 // argument entry.
587 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000588
Kate Stoneb9c1b512016-09-06 20:57:50 +0000589 // Define the first variant of this arg.
590 index_arg.arg_type = eArgTypeSettingIndex;
591 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000592
Kate Stoneb9c1b512016-09-06 20:57:50 +0000593 // Define the second variant of this arg.
594 key_arg.arg_type = eArgTypeSettingKey;
595 key_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000596
Kate Stoneb9c1b512016-09-06 20:57:50 +0000597 // Push both variants into this arg
598 arg2.push_back(index_arg);
599 arg2.push_back(key_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000600
Kate Stoneb9c1b512016-09-06 20:57:50 +0000601 // Push the data for the first argument into the m_arguments vector.
602 m_arguments.push_back(arg1);
603 m_arguments.push_back(arg2);
604 }
Jim Ingham5a988412012-06-08 21:56:10 +0000605
Kate Stoneb9c1b512016-09-06 20:57:50 +0000606 ~CommandObjectSettingsRemove() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000607
Raphael Isemann006d22d2019-08-21 12:57:06 +0000608 bool WantsCompletion() override { return true; }
609
Raphael Isemannae34ed22019-08-22 07:41:23 +0000610 void
611 HandleArgumentCompletion(CompletionRequest &request,
612 OptionElementVector &opt_element_vector) override {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000613 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000614 CommandCompletions::InvokeCommonCompletionCallbacks(
615 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000616 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000617 }
Jim Ingham5a988412012-06-08 21:56:10 +0000618
619protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000620 bool DoExecute(llvm::StringRef command,
621 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000622 result.SetStatus(eReturnStatusSuccessFinishNoResult);
623
624 Args cmd_args(command);
625
626 // Process possible options.
627 if (!ParseOptions(cmd_args, result))
628 return false;
629
630 const size_t argc = cmd_args.GetArgumentCount();
631 if (argc == 0) {
Raphael Isemann34a04e72019-08-21 13:24:21 +0000632 result.AppendError("'settings remove' takes an array or dictionary item, "
633 "or an array followed by one or more indexes, or a "
Kate Stoneb9c1b512016-09-06 20:57:50 +0000634 "dictionary followed by one or more key names to "
635 "remove");
636 result.SetStatus(eReturnStatusFailed);
637 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000638 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000639
640 const char *var_name = cmd_args.GetArgumentAtIndex(0);
641 if ((var_name == nullptr) || (var_name[0] == '\0')) {
642 result.AppendError(
Raphael Isemann34a04e72019-08-21 13:24:21 +0000643 "'settings remove' command requires a valid variable name");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000644 result.SetStatus(eReturnStatusFailed);
645 return false;
646 }
647
648 // Split the raw command into var_name and value pair.
649 llvm::StringRef raw_str(command);
650 std::string var_value_string = raw_str.split(var_name).second.str();
651 const char *var_value_cstr =
652 Args::StripSpaces(var_value_string, true, true, false);
653
Jonas Devlieghere57179862019-04-27 06:19:42 +0000654 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000655 &m_exe_ctx, eVarSetOperationRemove, var_name, var_value_cstr));
656 if (error.Fail()) {
657 result.AppendError(error.AsCString());
658 result.SetStatus(eReturnStatusFailed);
659 return false;
660 }
661
662 return result.Succeeded();
663 }
Jim Ingham5a988412012-06-08 21:56:10 +0000664};
665
Jim Ingham5a988412012-06-08 21:56:10 +0000666// CommandObjectSettingsReplace
Jim Ingham5a988412012-06-08 21:56:10 +0000667
Kate Stoneb9c1b512016-09-06 20:57:50 +0000668class CommandObjectSettingsReplace : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000669public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000670 CommandObjectSettingsReplace(CommandInterpreter &interpreter)
671 : CommandObjectRaw(interpreter, "settings replace",
672 "Replace the debugger setting value specified by "
Zachary Turnera4496982016-10-05 21:14:38 +0000673 "array index or dictionary key.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000674 CommandArgumentEntry arg1;
675 CommandArgumentEntry arg2;
676 CommandArgumentEntry arg3;
677 CommandArgumentData var_name_arg;
678 CommandArgumentData index_arg;
679 CommandArgumentData key_arg;
680 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000681
Kate Stoneb9c1b512016-09-06 20:57:50 +0000682 // Define the first (and only) variant of this arg.
683 var_name_arg.arg_type = eArgTypeSettingVariableName;
684 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000685
Kate Stoneb9c1b512016-09-06 20:57:50 +0000686 // There is only one variant this argument could be; put it into the
687 // argument entry.
688 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000689
Kate Stoneb9c1b512016-09-06 20:57:50 +0000690 // Define the first (variant of this arg.
691 index_arg.arg_type = eArgTypeSettingIndex;
692 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000693
Kate Stoneb9c1b512016-09-06 20:57:50 +0000694 // Define the second (variant of this arg.
695 key_arg.arg_type = eArgTypeSettingKey;
696 key_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000697
Kate Stoneb9c1b512016-09-06 20:57:50 +0000698 // Put both variants into this arg
699 arg2.push_back(index_arg);
700 arg2.push_back(key_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000701
Kate Stoneb9c1b512016-09-06 20:57:50 +0000702 // Define the first (and only) variant of this arg.
703 value_arg.arg_type = eArgTypeValue;
704 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000705
Kate Stoneb9c1b512016-09-06 20:57:50 +0000706 // There is only one variant this argument could be; put it into the
707 // argument entry.
708 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000709
Kate Stoneb9c1b512016-09-06 20:57:50 +0000710 // Push the data for the first argument into the m_arguments vector.
711 m_arguments.push_back(arg1);
712 m_arguments.push_back(arg2);
713 m_arguments.push_back(arg3);
714 }
Jim Ingham5a988412012-06-08 21:56:10 +0000715
Kate Stoneb9c1b512016-09-06 20:57:50 +0000716 ~CommandObjectSettingsReplace() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000717
Kate Stoneb9c1b512016-09-06 20:57:50 +0000718 // Overrides base class's behavior where WantsCompletion =
719 // !WantsRawCommandString.
720 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000721
Raphael Isemannae34ed22019-08-22 07:41:23 +0000722 void
723 HandleArgumentCompletion(CompletionRequest &request,
724 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000725 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000726 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000727 CommandCompletions::InvokeCommonCompletionCallbacks(
728 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000729 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000730 }
Jim Ingham5a988412012-06-08 21:56:10 +0000731
732protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000733 bool DoExecute(llvm::StringRef command,
734 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000735 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000736
Kate Stoneb9c1b512016-09-06 20:57:50 +0000737 Args cmd_args(command);
738 const char *var_name = cmd_args.GetArgumentAtIndex(0);
739 if ((var_name == nullptr) || (var_name[0] == '\0')) {
740 result.AppendError("'settings replace' command requires a valid variable "
741 "name; No value supplied");
742 result.SetStatus(eReturnStatusFailed);
743 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000744 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000745
746 // Split the raw command into var_name, index_value, and value triple.
747 llvm::StringRef raw_str(command);
748 std::string var_value_string = raw_str.split(var_name).second.str();
749 const char *var_value_cstr =
750 Args::StripSpaces(var_value_string, true, true, false);
751
Jonas Devlieghere57179862019-04-27 06:19:42 +0000752 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000753 &m_exe_ctx, eVarSetOperationReplace, var_name, var_value_cstr));
754 if (error.Fail()) {
755 result.AppendError(error.AsCString());
756 result.SetStatus(eReturnStatusFailed);
757 return false;
758 } else {
759 result.SetStatus(eReturnStatusSuccessFinishNoResult);
760 }
761
762 return result.Succeeded();
763 }
Jim Ingham5a988412012-06-08 21:56:10 +0000764};
765
Jim Ingham5a988412012-06-08 21:56:10 +0000766// CommandObjectSettingsInsertBefore
Jim Ingham5a988412012-06-08 21:56:10 +0000767
Kate Stoneb9c1b512016-09-06 20:57:50 +0000768class CommandObjectSettingsInsertBefore : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000769public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000770 CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
771 : CommandObjectRaw(interpreter, "settings insert-before",
772 "Insert one or more values into an debugger array "
773 "setting immediately before the specified element "
Zachary Turnera4496982016-10-05 21:14:38 +0000774 "index.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000775 CommandArgumentEntry arg1;
776 CommandArgumentEntry arg2;
777 CommandArgumentEntry arg3;
778 CommandArgumentData var_name_arg;
779 CommandArgumentData index_arg;
780 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000781
Kate Stoneb9c1b512016-09-06 20:57:50 +0000782 // Define the first (and only) variant of this arg.
783 var_name_arg.arg_type = eArgTypeSettingVariableName;
784 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000785
Kate Stoneb9c1b512016-09-06 20:57:50 +0000786 // There is only one variant this argument could be; put it into the
787 // argument entry.
788 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000789
Kate Stoneb9c1b512016-09-06 20:57:50 +0000790 // Define the first (variant of this arg.
791 index_arg.arg_type = eArgTypeSettingIndex;
792 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000793
Kate Stoneb9c1b512016-09-06 20:57:50 +0000794 // There is only one variant this argument could be; put it into the
795 // argument entry.
796 arg2.push_back(index_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000797
Kate Stoneb9c1b512016-09-06 20:57:50 +0000798 // Define the first (and only) variant of this arg.
799 value_arg.arg_type = eArgTypeValue;
800 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000801
Kate Stoneb9c1b512016-09-06 20:57:50 +0000802 // There is only one variant this argument could be; put it into the
803 // argument entry.
804 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000805
Kate Stoneb9c1b512016-09-06 20:57:50 +0000806 // Push the data for the first argument into the m_arguments vector.
807 m_arguments.push_back(arg1);
808 m_arguments.push_back(arg2);
809 m_arguments.push_back(arg3);
810 }
Jim Ingham5a988412012-06-08 21:56:10 +0000811
Kate Stoneb9c1b512016-09-06 20:57:50 +0000812 ~CommandObjectSettingsInsertBefore() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000813
Kate Stoneb9c1b512016-09-06 20:57:50 +0000814 // Overrides base class's behavior where WantsCompletion =
815 // !WantsRawCommandString.
816 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000817
Raphael Isemannae34ed22019-08-22 07:41:23 +0000818 void
819 HandleArgumentCompletion(CompletionRequest &request,
820 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000821 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000822 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000823 CommandCompletions::InvokeCommonCompletionCallbacks(
824 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000825 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000826 }
Jim Ingham5a988412012-06-08 21:56:10 +0000827
828protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000829 bool DoExecute(llvm::StringRef command,
830 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000831 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000832
Kate Stoneb9c1b512016-09-06 20:57:50 +0000833 Args cmd_args(command);
834 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +0000835
Kate Stoneb9c1b512016-09-06 20:57:50 +0000836 if (argc < 3) {
837 result.AppendError("'settings insert-before' takes more arguments");
838 result.SetStatus(eReturnStatusFailed);
839 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000840 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000841
842 const char *var_name = cmd_args.GetArgumentAtIndex(0);
843 if ((var_name == nullptr) || (var_name[0] == '\0')) {
844 result.AppendError("'settings insert-before' command requires a valid "
845 "variable name; No value supplied");
846 result.SetStatus(eReturnStatusFailed);
847 return false;
848 }
849
850 // Split the raw command into var_name, index_value, and value triple.
851 llvm::StringRef raw_str(command);
852 std::string var_value_string = raw_str.split(var_name).second.str();
853 const char *var_value_cstr =
854 Args::StripSpaces(var_value_string, true, true, false);
855
Jonas Devlieghere57179862019-04-27 06:19:42 +0000856 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000857 &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value_cstr));
858 if (error.Fail()) {
859 result.AppendError(error.AsCString());
860 result.SetStatus(eReturnStatusFailed);
861 return false;
862 }
863
864 return result.Succeeded();
865 }
Jim Ingham5a988412012-06-08 21:56:10 +0000866};
867
Jim Ingham5a988412012-06-08 21:56:10 +0000868// CommandObjectSettingInsertAfter
Jim Ingham5a988412012-06-08 21:56:10 +0000869
Kate Stoneb9c1b512016-09-06 20:57:50 +0000870class CommandObjectSettingsInsertAfter : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000871public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000872 CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
873 : CommandObjectRaw(interpreter, "settings insert-after",
874 "Insert one or more values into a debugger array "
Zachary Turnera4496982016-10-05 21:14:38 +0000875 "settings after the specified element index.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000876 CommandArgumentEntry arg1;
877 CommandArgumentEntry arg2;
878 CommandArgumentEntry arg3;
879 CommandArgumentData var_name_arg;
880 CommandArgumentData index_arg;
881 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000882
Kate Stoneb9c1b512016-09-06 20:57:50 +0000883 // Define the first (and only) variant of this arg.
884 var_name_arg.arg_type = eArgTypeSettingVariableName;
885 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000886
Kate Stoneb9c1b512016-09-06 20:57:50 +0000887 // There is only one variant this argument could be; put it into the
888 // argument entry.
889 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000890
Kate Stoneb9c1b512016-09-06 20:57:50 +0000891 // Define the first (variant of this arg.
892 index_arg.arg_type = eArgTypeSettingIndex;
893 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000894
Kate Stoneb9c1b512016-09-06 20:57:50 +0000895 // There is only one variant this argument could be; put it into the
896 // argument entry.
897 arg2.push_back(index_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000898
Kate Stoneb9c1b512016-09-06 20:57:50 +0000899 // Define the first (and only) variant of this arg.
900 value_arg.arg_type = eArgTypeValue;
901 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000902
Kate Stoneb9c1b512016-09-06 20:57:50 +0000903 // There is only one variant this argument could be; put it into the
904 // argument entry.
905 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000906
Kate Stoneb9c1b512016-09-06 20:57:50 +0000907 // Push the data for the first argument into the m_arguments vector.
908 m_arguments.push_back(arg1);
909 m_arguments.push_back(arg2);
910 m_arguments.push_back(arg3);
911 }
Jim Ingham5a988412012-06-08 21:56:10 +0000912
Kate Stoneb9c1b512016-09-06 20:57:50 +0000913 ~CommandObjectSettingsInsertAfter() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000914
Kate Stoneb9c1b512016-09-06 20:57:50 +0000915 // Overrides base class's behavior where WantsCompletion =
916 // !WantsRawCommandString.
917 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000918
Raphael Isemannae34ed22019-08-22 07:41:23 +0000919 void
920 HandleArgumentCompletion(CompletionRequest &request,
921 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000922 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000923 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000924 CommandCompletions::InvokeCommonCompletionCallbacks(
925 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000926 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000927 }
928
Jim Ingham5a988412012-06-08 21:56:10 +0000929protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000930 bool DoExecute(llvm::StringRef command,
931 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000932 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000933
Kate Stoneb9c1b512016-09-06 20:57:50 +0000934 Args cmd_args(command);
935 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +0000936
Kate Stoneb9c1b512016-09-06 20:57:50 +0000937 if (argc < 3) {
938 result.AppendError("'settings insert-after' takes more arguments");
939 result.SetStatus(eReturnStatusFailed);
940 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000941 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000942
943 const char *var_name = cmd_args.GetArgumentAtIndex(0);
944 if ((var_name == nullptr) || (var_name[0] == '\0')) {
945 result.AppendError("'settings insert-after' command requires a valid "
946 "variable name; No value supplied");
947 result.SetStatus(eReturnStatusFailed);
948 return false;
949 }
950
951 // Split the raw command into var_name, index_value, and value triple.
952 llvm::StringRef raw_str(command);
953 std::string var_value_string = raw_str.split(var_name).second.str();
954 const char *var_value_cstr =
955 Args::StripSpaces(var_value_string, true, true, false);
956
Jonas Devlieghere57179862019-04-27 06:19:42 +0000957 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000958 &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value_cstr));
959 if (error.Fail()) {
960 result.AppendError(error.AsCString());
961 result.SetStatus(eReturnStatusFailed);
962 return false;
963 }
964
965 return result.Succeeded();
966 }
Jim Ingham5a988412012-06-08 21:56:10 +0000967};
968
Jim Ingham5a988412012-06-08 21:56:10 +0000969// CommandObjectSettingsAppend
Jim Ingham5a988412012-06-08 21:56:10 +0000970
Kate Stoneb9c1b512016-09-06 20:57:50 +0000971class CommandObjectSettingsAppend : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000972public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000973 CommandObjectSettingsAppend(CommandInterpreter &interpreter)
974 : CommandObjectRaw(interpreter, "settings append",
975 "Append one or more values to a debugger array, "
Zachary Turnera4496982016-10-05 21:14:38 +0000976 "dictionary, or string setting.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000977 CommandArgumentEntry arg1;
978 CommandArgumentEntry arg2;
979 CommandArgumentData var_name_arg;
980 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000981
Kate Stoneb9c1b512016-09-06 20:57:50 +0000982 // Define the first (and only) variant of this arg.
983 var_name_arg.arg_type = eArgTypeSettingVariableName;
984 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000985
Kate Stoneb9c1b512016-09-06 20:57:50 +0000986 // There is only one variant this argument could be; put it into the
987 // argument entry.
988 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000989
Kate Stoneb9c1b512016-09-06 20:57:50 +0000990 // Define the first (and only) variant of this arg.
991 value_arg.arg_type = eArgTypeValue;
992 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000993
Kate Stoneb9c1b512016-09-06 20:57:50 +0000994 // There is only one variant this argument could be; put it into the
995 // argument entry.
996 arg2.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000997
Kate Stoneb9c1b512016-09-06 20:57:50 +0000998 // Push the data for the first argument into the m_arguments vector.
999 m_arguments.push_back(arg1);
1000 m_arguments.push_back(arg2);
1001 }
Jim Ingham5a988412012-06-08 21:56:10 +00001002
Kate Stoneb9c1b512016-09-06 20:57:50 +00001003 ~CommandObjectSettingsAppend() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001004
Kate Stoneb9c1b512016-09-06 20:57:50 +00001005 // Overrides base class's behavior where WantsCompletion =
1006 // !WantsRawCommandString.
1007 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +00001008
Raphael Isemannae34ed22019-08-22 07:41:23 +00001009 void
1010 HandleArgumentCompletion(CompletionRequest &request,
1011 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001012 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001013 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001014 CommandCompletions::InvokeCommonCompletionCallbacks(
1015 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +00001016 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001017 }
Jim Ingham5a988412012-06-08 21:56:10 +00001018
1019protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +00001020 bool DoExecute(llvm::StringRef command,
1021 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001022 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1023 Args cmd_args(command);
1024 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +00001025
Kate Stoneb9c1b512016-09-06 20:57:50 +00001026 if (argc < 2) {
1027 result.AppendError("'settings append' takes more arguments");
1028 result.SetStatus(eReturnStatusFailed);
1029 return false;
Jim Ingham5a988412012-06-08 21:56:10 +00001030 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001031
1032 const char *var_name = cmd_args.GetArgumentAtIndex(0);
1033 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1034 result.AppendError("'settings append' command requires a valid variable "
1035 "name; No value supplied");
1036 result.SetStatus(eReturnStatusFailed);
1037 return false;
1038 }
1039
Adrian Prantl05097242018-04-30 16:49:04 +00001040 // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
1041 // character string later on.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001042
1043 // Split the raw command into var_name and value pair.
1044 llvm::StringRef raw_str(command);
1045 std::string var_value_string = raw_str.split(var_name).second.str();
1046 const char *var_value_cstr =
1047 Args::StripSpaces(var_value_string, true, true, false);
1048
Jonas Devlieghere57179862019-04-27 06:19:42 +00001049 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001050 &m_exe_ctx, eVarSetOperationAppend, var_name, var_value_cstr));
1051 if (error.Fail()) {
1052 result.AppendError(error.AsCString());
1053 result.SetStatus(eReturnStatusFailed);
1054 return false;
1055 }
1056
1057 return result.Succeeded();
1058 }
Jim Ingham5a988412012-06-08 21:56:10 +00001059};
1060
Jim Ingham5a988412012-06-08 21:56:10 +00001061// CommandObjectSettingsClear
Jim Ingham5a988412012-06-08 21:56:10 +00001062
Kate Stoneb9c1b512016-09-06 20:57:50 +00001063class CommandObjectSettingsClear : public CommandObjectParsed {
Jim Ingham5a988412012-06-08 21:56:10 +00001064public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001065 CommandObjectSettingsClear(CommandInterpreter &interpreter)
1066 : CommandObjectParsed(
1067 interpreter, "settings clear",
1068 "Clear a debugger setting array, dictionary, or string.", nullptr) {
1069 CommandArgumentEntry arg;
1070 CommandArgumentData var_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +00001071
Kate Stoneb9c1b512016-09-06 20:57:50 +00001072 // Define the first (and only) variant of this arg.
1073 var_name_arg.arg_type = eArgTypeSettingVariableName;
1074 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +00001075
Kate Stoneb9c1b512016-09-06 20:57:50 +00001076 // There is only one variant this argument could be; put it into the
1077 // argument entry.
1078 arg.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001079
Kate Stoneb9c1b512016-09-06 20:57:50 +00001080 // Push the data for the first argument into the m_arguments vector.
1081 m_arguments.push_back(arg);
1082 }
Jim Ingham5a988412012-06-08 21:56:10 +00001083
Kate Stoneb9c1b512016-09-06 20:57:50 +00001084 ~CommandObjectSettingsClear() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001085
Raphael Isemannae34ed22019-08-22 07:41:23 +00001086 void
1087 HandleArgumentCompletion(CompletionRequest &request,
1088 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001089 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001090 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001091 CommandCompletions::InvokeCommonCompletionCallbacks(
1092 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +00001093 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001094 }
Jim Ingham5a988412012-06-08 21:56:10 +00001095
1096protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001097 bool DoExecute(Args &command, CommandReturnObject &result) override {
1098 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1099 const size_t argc = command.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +00001100
Kate Stoneb9c1b512016-09-06 20:57:50 +00001101 if (argc != 1) {
1102 result.AppendError("'settings clear' takes exactly one argument");
1103 result.SetStatus(eReturnStatusFailed);
1104 return false;
Jim Ingham5a988412012-06-08 21:56:10 +00001105 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001106
1107 const char *var_name = command.GetArgumentAtIndex(0);
1108 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1109 result.AppendError("'settings clear' command requires a valid variable "
1110 "name; No value supplied");
1111 result.SetStatus(eReturnStatusFailed);
1112 return false;
1113 }
1114
Jonas Devlieghere57179862019-04-27 06:19:42 +00001115 Status error(GetDebugger().SetPropertyValue(
Zachary Turner31d97a52016-11-17 18:08:12 +00001116 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001117 if (error.Fail()) {
1118 result.AppendError(error.AsCString());
1119 result.SetStatus(eReturnStatusFailed);
1120 return false;
1121 }
1122
1123 return result.Succeeded();
1124 }
Jim Ingham5a988412012-06-08 21:56:10 +00001125};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001126
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001127// CommandObjectMultiwordSettings
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001128
Kate Stoneb9c1b512016-09-06 20:57:50 +00001129CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
1130 CommandInterpreter &interpreter)
1131 : CommandObjectMultiword(interpreter, "settings",
1132 "Commands for managing LLDB settings.",
1133 "settings <subcommand> [<command-options>]") {
1134 LoadSubCommand("set",
1135 CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
1136 LoadSubCommand("show",
1137 CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
1138 LoadSubCommand("list",
1139 CommandObjectSP(new CommandObjectSettingsList(interpreter)));
1140 LoadSubCommand("remove",
1141 CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
1142 LoadSubCommand("replace", CommandObjectSP(
1143 new CommandObjectSettingsReplace(interpreter)));
1144 LoadSubCommand(
1145 "insert-before",
1146 CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
1147 LoadSubCommand(
1148 "insert-after",
1149 CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
1150 LoadSubCommand("append",
1151 CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
1152 LoadSubCommand("clear",
1153 CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +00001154 LoadSubCommand("write",
1155 CommandObjectSP(new CommandObjectSettingsWrite(interpreter)));
1156 LoadSubCommand("read",
1157 CommandObjectSP(new CommandObjectSettingsRead(interpreter)));
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001158}
1159
Eugene Zelenko3f18ea02016-02-24 02:05:55 +00001160CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default;