blob: 2bdbcd52bc19efb20ab216351b883fc26364e637 [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 Isemann006d22d2019-08-21 12:57:06 +0000616 bool WantsCompletion() override { return true; }
617
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000618 int HandleArgumentCompletion(
619 CompletionRequest &request,
620 OptionElementVector &opt_element_vector) override {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000621 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000622 CommandCompletions::InvokeCommonCompletionCallbacks(
623 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000624 request, nullptr);
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000625 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000626 }
Jim Ingham5a988412012-06-08 21:56:10 +0000627
628protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000629 bool DoExecute(llvm::StringRef command,
630 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000631 result.SetStatus(eReturnStatusSuccessFinishNoResult);
632
633 Args cmd_args(command);
634
635 // Process possible options.
636 if (!ParseOptions(cmd_args, result))
637 return false;
638
639 const size_t argc = cmd_args.GetArgumentCount();
640 if (argc == 0) {
Raphael Isemann34a04e72019-08-21 13:24:21 +0000641 result.AppendError("'settings remove' takes an array or dictionary item, "
642 "or an array followed by one or more indexes, or a "
Kate Stoneb9c1b512016-09-06 20:57:50 +0000643 "dictionary followed by one or more key names to "
644 "remove");
645 result.SetStatus(eReturnStatusFailed);
646 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000647 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000648
649 const char *var_name = cmd_args.GetArgumentAtIndex(0);
650 if ((var_name == nullptr) || (var_name[0] == '\0')) {
651 result.AppendError(
Raphael Isemann34a04e72019-08-21 13:24:21 +0000652 "'settings remove' command requires a valid variable name");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000653 result.SetStatus(eReturnStatusFailed);
654 return false;
655 }
656
657 // Split the raw command into var_name and value pair.
658 llvm::StringRef raw_str(command);
659 std::string var_value_string = raw_str.split(var_name).second.str();
660 const char *var_value_cstr =
661 Args::StripSpaces(var_value_string, true, true, false);
662
Jonas Devlieghere57179862019-04-27 06:19:42 +0000663 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000664 &m_exe_ctx, eVarSetOperationRemove, var_name, var_value_cstr));
665 if (error.Fail()) {
666 result.AppendError(error.AsCString());
667 result.SetStatus(eReturnStatusFailed);
668 return false;
669 }
670
671 return result.Succeeded();
672 }
Jim Ingham5a988412012-06-08 21:56:10 +0000673};
674
Jim Ingham5a988412012-06-08 21:56:10 +0000675// CommandObjectSettingsReplace
Jim Ingham5a988412012-06-08 21:56:10 +0000676
Kate Stoneb9c1b512016-09-06 20:57:50 +0000677class CommandObjectSettingsReplace : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000678public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000679 CommandObjectSettingsReplace(CommandInterpreter &interpreter)
680 : CommandObjectRaw(interpreter, "settings replace",
681 "Replace the debugger setting value specified by "
Zachary Turnera4496982016-10-05 21:14:38 +0000682 "array index or dictionary key.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000683 CommandArgumentEntry arg1;
684 CommandArgumentEntry arg2;
685 CommandArgumentEntry arg3;
686 CommandArgumentData var_name_arg;
687 CommandArgumentData index_arg;
688 CommandArgumentData key_arg;
689 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000690
Kate Stoneb9c1b512016-09-06 20:57:50 +0000691 // Define the first (and only) variant of this arg.
692 var_name_arg.arg_type = eArgTypeSettingVariableName;
693 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000694
Kate Stoneb9c1b512016-09-06 20:57:50 +0000695 // There is only one variant this argument could be; put it into the
696 // argument entry.
697 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000698
Kate Stoneb9c1b512016-09-06 20:57:50 +0000699 // Define the first (variant of this arg.
700 index_arg.arg_type = eArgTypeSettingIndex;
701 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000702
Kate Stoneb9c1b512016-09-06 20:57:50 +0000703 // Define the second (variant of this arg.
704 key_arg.arg_type = eArgTypeSettingKey;
705 key_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000706
Kate Stoneb9c1b512016-09-06 20:57:50 +0000707 // Put both variants into this arg
708 arg2.push_back(index_arg);
709 arg2.push_back(key_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000710
Kate Stoneb9c1b512016-09-06 20:57:50 +0000711 // Define the first (and only) variant of this arg.
712 value_arg.arg_type = eArgTypeValue;
713 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000714
Kate Stoneb9c1b512016-09-06 20:57:50 +0000715 // There is only one variant this argument could be; put it into the
716 // argument entry.
717 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000718
Kate Stoneb9c1b512016-09-06 20:57:50 +0000719 // Push the data for the first argument into the m_arguments vector.
720 m_arguments.push_back(arg1);
721 m_arguments.push_back(arg2);
722 m_arguments.push_back(arg3);
723 }
Jim Ingham5a988412012-06-08 21:56:10 +0000724
Kate Stoneb9c1b512016-09-06 20:57:50 +0000725 ~CommandObjectSettingsReplace() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000726
Kate Stoneb9c1b512016-09-06 20:57:50 +0000727 // Overrides base class's behavior where WantsCompletion =
728 // !WantsRawCommandString.
729 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000730
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000731 int HandleArgumentCompletion(
732 CompletionRequest &request,
733 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000734 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000735 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000736 CommandCompletions::InvokeCommonCompletionCallbacks(
737 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000738 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +0000739
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000740 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000741 }
Jim Ingham5a988412012-06-08 21:56:10 +0000742
743protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000744 bool DoExecute(llvm::StringRef command,
745 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000746 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000747
Kate Stoneb9c1b512016-09-06 20:57:50 +0000748 Args cmd_args(command);
749 const char *var_name = cmd_args.GetArgumentAtIndex(0);
750 if ((var_name == nullptr) || (var_name[0] == '\0')) {
751 result.AppendError("'settings replace' command requires a valid variable "
752 "name; No value supplied");
753 result.SetStatus(eReturnStatusFailed);
754 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000755 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000756
757 // Split the raw command into var_name, index_value, and value triple.
758 llvm::StringRef raw_str(command);
759 std::string var_value_string = raw_str.split(var_name).second.str();
760 const char *var_value_cstr =
761 Args::StripSpaces(var_value_string, true, true, false);
762
Jonas Devlieghere57179862019-04-27 06:19:42 +0000763 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000764 &m_exe_ctx, eVarSetOperationReplace, var_name, var_value_cstr));
765 if (error.Fail()) {
766 result.AppendError(error.AsCString());
767 result.SetStatus(eReturnStatusFailed);
768 return false;
769 } else {
770 result.SetStatus(eReturnStatusSuccessFinishNoResult);
771 }
772
773 return result.Succeeded();
774 }
Jim Ingham5a988412012-06-08 21:56:10 +0000775};
776
Jim Ingham5a988412012-06-08 21:56:10 +0000777// CommandObjectSettingsInsertBefore
Jim Ingham5a988412012-06-08 21:56:10 +0000778
Kate Stoneb9c1b512016-09-06 20:57:50 +0000779class CommandObjectSettingsInsertBefore : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000780public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000781 CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
782 : CommandObjectRaw(interpreter, "settings insert-before",
783 "Insert one or more values into an debugger array "
784 "setting immediately before the specified element "
Zachary Turnera4496982016-10-05 21:14:38 +0000785 "index.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000786 CommandArgumentEntry arg1;
787 CommandArgumentEntry arg2;
788 CommandArgumentEntry arg3;
789 CommandArgumentData var_name_arg;
790 CommandArgumentData index_arg;
791 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000792
Kate Stoneb9c1b512016-09-06 20:57:50 +0000793 // Define the first (and only) variant of this arg.
794 var_name_arg.arg_type = eArgTypeSettingVariableName;
795 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000796
Kate Stoneb9c1b512016-09-06 20:57:50 +0000797 // There is only one variant this argument could be; put it into the
798 // argument entry.
799 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000800
Kate Stoneb9c1b512016-09-06 20:57:50 +0000801 // Define the first (variant of this arg.
802 index_arg.arg_type = eArgTypeSettingIndex;
803 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000804
Kate Stoneb9c1b512016-09-06 20:57:50 +0000805 // There is only one variant this argument could be; put it into the
806 // argument entry.
807 arg2.push_back(index_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000808
Kate Stoneb9c1b512016-09-06 20:57:50 +0000809 // Define the first (and only) variant of this arg.
810 value_arg.arg_type = eArgTypeValue;
811 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000812
Kate Stoneb9c1b512016-09-06 20:57:50 +0000813 // There is only one variant this argument could be; put it into the
814 // argument entry.
815 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000816
Kate Stoneb9c1b512016-09-06 20:57:50 +0000817 // Push the data for the first argument into the m_arguments vector.
818 m_arguments.push_back(arg1);
819 m_arguments.push_back(arg2);
820 m_arguments.push_back(arg3);
821 }
Jim Ingham5a988412012-06-08 21:56:10 +0000822
Kate Stoneb9c1b512016-09-06 20:57:50 +0000823 ~CommandObjectSettingsInsertBefore() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000824
Kate Stoneb9c1b512016-09-06 20:57:50 +0000825 // Overrides base class's behavior where WantsCompletion =
826 // !WantsRawCommandString.
827 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000828
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000829 int HandleArgumentCompletion(
830 CompletionRequest &request,
831 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000832 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000833 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000834 CommandCompletions::InvokeCommonCompletionCallbacks(
835 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000836 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +0000837
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000838 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000839 }
Jim Ingham5a988412012-06-08 21:56:10 +0000840
841protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000842 bool DoExecute(llvm::StringRef command,
843 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000844 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000845
Kate Stoneb9c1b512016-09-06 20:57:50 +0000846 Args cmd_args(command);
847 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +0000848
Kate Stoneb9c1b512016-09-06 20:57:50 +0000849 if (argc < 3) {
850 result.AppendError("'settings insert-before' takes more arguments");
851 result.SetStatus(eReturnStatusFailed);
852 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000853 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000854
855 const char *var_name = cmd_args.GetArgumentAtIndex(0);
856 if ((var_name == nullptr) || (var_name[0] == '\0')) {
857 result.AppendError("'settings insert-before' command requires a valid "
858 "variable name; No value supplied");
859 result.SetStatus(eReturnStatusFailed);
860 return false;
861 }
862
863 // Split the raw command into var_name, index_value, and value triple.
864 llvm::StringRef raw_str(command);
865 std::string var_value_string = raw_str.split(var_name).second.str();
866 const char *var_value_cstr =
867 Args::StripSpaces(var_value_string, true, true, false);
868
Jonas Devlieghere57179862019-04-27 06:19:42 +0000869 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000870 &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value_cstr));
871 if (error.Fail()) {
872 result.AppendError(error.AsCString());
873 result.SetStatus(eReturnStatusFailed);
874 return false;
875 }
876
877 return result.Succeeded();
878 }
Jim Ingham5a988412012-06-08 21:56:10 +0000879};
880
Jim Ingham5a988412012-06-08 21:56:10 +0000881// CommandObjectSettingInsertAfter
Jim Ingham5a988412012-06-08 21:56:10 +0000882
Kate Stoneb9c1b512016-09-06 20:57:50 +0000883class CommandObjectSettingsInsertAfter : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000884public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000885 CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
886 : CommandObjectRaw(interpreter, "settings insert-after",
887 "Insert one or more values into a debugger array "
Zachary Turnera4496982016-10-05 21:14:38 +0000888 "settings after the specified element index.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000889 CommandArgumentEntry arg1;
890 CommandArgumentEntry arg2;
891 CommandArgumentEntry arg3;
892 CommandArgumentData var_name_arg;
893 CommandArgumentData index_arg;
894 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000895
Kate Stoneb9c1b512016-09-06 20:57:50 +0000896 // Define the first (and only) variant of this arg.
897 var_name_arg.arg_type = eArgTypeSettingVariableName;
898 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000899
Kate Stoneb9c1b512016-09-06 20:57:50 +0000900 // There is only one variant this argument could be; put it into the
901 // argument entry.
902 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000903
Kate Stoneb9c1b512016-09-06 20:57:50 +0000904 // Define the first (variant of this arg.
905 index_arg.arg_type = eArgTypeSettingIndex;
906 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000907
Kate Stoneb9c1b512016-09-06 20:57:50 +0000908 // There is only one variant this argument could be; put it into the
909 // argument entry.
910 arg2.push_back(index_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000911
Kate Stoneb9c1b512016-09-06 20:57:50 +0000912 // Define the first (and only) variant of this arg.
913 value_arg.arg_type = eArgTypeValue;
914 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000915
Kate Stoneb9c1b512016-09-06 20:57:50 +0000916 // There is only one variant this argument could be; put it into the
917 // argument entry.
918 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000919
Kate Stoneb9c1b512016-09-06 20:57:50 +0000920 // Push the data for the first argument into the m_arguments vector.
921 m_arguments.push_back(arg1);
922 m_arguments.push_back(arg2);
923 m_arguments.push_back(arg3);
924 }
Jim Ingham5a988412012-06-08 21:56:10 +0000925
Kate Stoneb9c1b512016-09-06 20:57:50 +0000926 ~CommandObjectSettingsInsertAfter() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000927
Kate Stoneb9c1b512016-09-06 20:57:50 +0000928 // Overrides base class's behavior where WantsCompletion =
929 // !WantsRawCommandString.
930 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000931
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000932 int HandleArgumentCompletion(
933 CompletionRequest &request,
934 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000935 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000936 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000937 CommandCompletions::InvokeCommonCompletionCallbacks(
938 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000939 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +0000940
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000941 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000942 }
943
Jim Ingham5a988412012-06-08 21:56:10 +0000944protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000945 bool DoExecute(llvm::StringRef command,
946 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000947 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000948
Kate Stoneb9c1b512016-09-06 20:57:50 +0000949 Args cmd_args(command);
950 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +0000951
Kate Stoneb9c1b512016-09-06 20:57:50 +0000952 if (argc < 3) {
953 result.AppendError("'settings insert-after' takes more arguments");
954 result.SetStatus(eReturnStatusFailed);
955 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000956 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000957
958 const char *var_name = cmd_args.GetArgumentAtIndex(0);
959 if ((var_name == nullptr) || (var_name[0] == '\0')) {
960 result.AppendError("'settings insert-after' command requires a valid "
961 "variable name; No value supplied");
962 result.SetStatus(eReturnStatusFailed);
963 return false;
964 }
965
966 // Split the raw command into var_name, index_value, and value triple.
967 llvm::StringRef raw_str(command);
968 std::string var_value_string = raw_str.split(var_name).second.str();
969 const char *var_value_cstr =
970 Args::StripSpaces(var_value_string, true, true, false);
971
Jonas Devlieghere57179862019-04-27 06:19:42 +0000972 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000973 &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value_cstr));
974 if (error.Fail()) {
975 result.AppendError(error.AsCString());
976 result.SetStatus(eReturnStatusFailed);
977 return false;
978 }
979
980 return result.Succeeded();
981 }
Jim Ingham5a988412012-06-08 21:56:10 +0000982};
983
Jim Ingham5a988412012-06-08 21:56:10 +0000984// CommandObjectSettingsAppend
Jim Ingham5a988412012-06-08 21:56:10 +0000985
Kate Stoneb9c1b512016-09-06 20:57:50 +0000986class CommandObjectSettingsAppend : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000987public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000988 CommandObjectSettingsAppend(CommandInterpreter &interpreter)
989 : CommandObjectRaw(interpreter, "settings append",
990 "Append one or more values to a debugger array, "
Zachary Turnera4496982016-10-05 21:14:38 +0000991 "dictionary, or string setting.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000992 CommandArgumentEntry arg1;
993 CommandArgumentEntry arg2;
994 CommandArgumentData var_name_arg;
995 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000996
Kate Stoneb9c1b512016-09-06 20:57:50 +0000997 // Define the first (and only) variant of this arg.
998 var_name_arg.arg_type = eArgTypeSettingVariableName;
999 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +00001000
Kate Stoneb9c1b512016-09-06 20:57:50 +00001001 // There is only one variant this argument could be; put it into the
1002 // argument entry.
1003 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001004
Kate Stoneb9c1b512016-09-06 20:57:50 +00001005 // Define the first (and only) variant of this arg.
1006 value_arg.arg_type = eArgTypeValue;
1007 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +00001008
Kate Stoneb9c1b512016-09-06 20:57:50 +00001009 // There is only one variant this argument could be; put it into the
1010 // argument entry.
1011 arg2.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001012
Kate Stoneb9c1b512016-09-06 20:57:50 +00001013 // Push the data for the first argument into the m_arguments vector.
1014 m_arguments.push_back(arg1);
1015 m_arguments.push_back(arg2);
1016 }
Jim Ingham5a988412012-06-08 21:56:10 +00001017
Kate Stoneb9c1b512016-09-06 20:57:50 +00001018 ~CommandObjectSettingsAppend() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001019
Kate Stoneb9c1b512016-09-06 20:57:50 +00001020 // Overrides base class's behavior where WantsCompletion =
1021 // !WantsRawCommandString.
1022 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +00001023
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001024 int HandleArgumentCompletion(
1025 CompletionRequest &request,
1026 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001027 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001028 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001029 CommandCompletions::InvokeCommonCompletionCallbacks(
1030 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +00001031 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +00001032
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +00001033 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001034 }
Jim Ingham5a988412012-06-08 21:56:10 +00001035
1036protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +00001037 bool DoExecute(llvm::StringRef command,
1038 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001039 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1040 Args cmd_args(command);
1041 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +00001042
Kate Stoneb9c1b512016-09-06 20:57:50 +00001043 if (argc < 2) {
1044 result.AppendError("'settings append' takes more arguments");
1045 result.SetStatus(eReturnStatusFailed);
1046 return false;
Jim Ingham5a988412012-06-08 21:56:10 +00001047 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001048
1049 const char *var_name = cmd_args.GetArgumentAtIndex(0);
1050 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1051 result.AppendError("'settings append' command requires a valid variable "
1052 "name; No value supplied");
1053 result.SetStatus(eReturnStatusFailed);
1054 return false;
1055 }
1056
Adrian Prantl05097242018-04-30 16:49:04 +00001057 // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
1058 // character string later on.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001059
1060 // Split the raw command into var_name and value pair.
1061 llvm::StringRef raw_str(command);
1062 std::string var_value_string = raw_str.split(var_name).second.str();
1063 const char *var_value_cstr =
1064 Args::StripSpaces(var_value_string, true, true, false);
1065
Jonas Devlieghere57179862019-04-27 06:19:42 +00001066 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001067 &m_exe_ctx, eVarSetOperationAppend, var_name, var_value_cstr));
1068 if (error.Fail()) {
1069 result.AppendError(error.AsCString());
1070 result.SetStatus(eReturnStatusFailed);
1071 return false;
1072 }
1073
1074 return result.Succeeded();
1075 }
Jim Ingham5a988412012-06-08 21:56:10 +00001076};
1077
Jim Ingham5a988412012-06-08 21:56:10 +00001078// CommandObjectSettingsClear
Jim Ingham5a988412012-06-08 21:56:10 +00001079
Kate Stoneb9c1b512016-09-06 20:57:50 +00001080class CommandObjectSettingsClear : public CommandObjectParsed {
Jim Ingham5a988412012-06-08 21:56:10 +00001081public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001082 CommandObjectSettingsClear(CommandInterpreter &interpreter)
1083 : CommandObjectParsed(
1084 interpreter, "settings clear",
1085 "Clear a debugger setting array, dictionary, or string.", nullptr) {
1086 CommandArgumentEntry arg;
1087 CommandArgumentData var_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +00001088
Kate Stoneb9c1b512016-09-06 20:57:50 +00001089 // Define the first (and only) variant of this arg.
1090 var_name_arg.arg_type = eArgTypeSettingVariableName;
1091 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +00001092
Kate Stoneb9c1b512016-09-06 20:57:50 +00001093 // There is only one variant this argument could be; put it into the
1094 // argument entry.
1095 arg.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001096
Kate Stoneb9c1b512016-09-06 20:57:50 +00001097 // Push the data for the first argument into the m_arguments vector.
1098 m_arguments.push_back(arg);
1099 }
Jim Ingham5a988412012-06-08 21:56:10 +00001100
Kate Stoneb9c1b512016-09-06 20:57:50 +00001101 ~CommandObjectSettingsClear() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001102
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001103 int HandleArgumentCompletion(
1104 CompletionRequest &request,
1105 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001106 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001107 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001108 CommandCompletions::InvokeCommonCompletionCallbacks(
1109 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +00001110 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +00001111
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +00001112 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001113 }
Jim Ingham5a988412012-06-08 21:56:10 +00001114
1115protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001116 bool DoExecute(Args &command, CommandReturnObject &result) override {
1117 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1118 const size_t argc = command.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +00001119
Kate Stoneb9c1b512016-09-06 20:57:50 +00001120 if (argc != 1) {
1121 result.AppendError("'settings clear' takes exactly one argument");
1122 result.SetStatus(eReturnStatusFailed);
1123 return false;
Jim Ingham5a988412012-06-08 21:56:10 +00001124 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001125
1126 const char *var_name = command.GetArgumentAtIndex(0);
1127 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1128 result.AppendError("'settings clear' command requires a valid variable "
1129 "name; No value supplied");
1130 result.SetStatus(eReturnStatusFailed);
1131 return false;
1132 }
1133
Jonas Devlieghere57179862019-04-27 06:19:42 +00001134 Status error(GetDebugger().SetPropertyValue(
Zachary Turner31d97a52016-11-17 18:08:12 +00001135 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001136 if (error.Fail()) {
1137 result.AppendError(error.AsCString());
1138 result.SetStatus(eReturnStatusFailed);
1139 return false;
1140 }
1141
1142 return result.Succeeded();
1143 }
Jim Ingham5a988412012-06-08 21:56:10 +00001144};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001145
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001146// CommandObjectMultiwordSettings
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001147
Kate Stoneb9c1b512016-09-06 20:57:50 +00001148CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
1149 CommandInterpreter &interpreter)
1150 : CommandObjectMultiword(interpreter, "settings",
1151 "Commands for managing LLDB settings.",
1152 "settings <subcommand> [<command-options>]") {
1153 LoadSubCommand("set",
1154 CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
1155 LoadSubCommand("show",
1156 CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
1157 LoadSubCommand("list",
1158 CommandObjectSP(new CommandObjectSettingsList(interpreter)));
1159 LoadSubCommand("remove",
1160 CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
1161 LoadSubCommand("replace", CommandObjectSP(
1162 new CommandObjectSettingsReplace(interpreter)));
1163 LoadSubCommand(
1164 "insert-before",
1165 CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
1166 LoadSubCommand(
1167 "insert-after",
1168 CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
1169 LoadSubCommand("append",
1170 CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
1171 LoadSubCommand("clear",
1172 CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +00001173 LoadSubCommand("write",
1174 CommandObjectSP(new CommandObjectSettingsWrite(interpreter)));
1175 LoadSubCommand("read",
1176 CommandObjectSP(new CommandObjectSettingsRead(interpreter)));
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001177}
1178
Eugene Zelenko3f18ea02016-02-24 02:05:55 +00001179CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default;