blob: 58dbaee967d4e8c0f457aca0f5d0acbaa13b217a [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- CommandObjectSettings.cpp -------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectSettings.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
Eugene Zelenko3f18ea02016-02-24 02:05:55 +000015#include "llvm/ADT/StringRef.h"
16
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017// Project includes
Zachary Turner3eb2b442017-03-22 23:33:16 +000018#include "lldb/Host/OptionParser.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000019#include "lldb/Interpreter/CommandCompletions.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020#include "lldb/Interpreter/CommandInterpreter.h"
21#include "lldb/Interpreter/CommandReturnObject.h"
Zachary Turner633a29c2015-03-04 01:58:01 +000022#include "lldb/Interpreter/OptionValueProperties.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023
24using namespace lldb;
25using namespace lldb_private;
Jim Ingham5a988412012-06-08 21:56:10 +000026
Jim Ingham5a988412012-06-08 21:56:10 +000027//-------------------------------------------------------------------------
28// CommandObjectSettingsSet
29//-------------------------------------------------------------------------
30
Zachary Turner1f0f5b52016-09-22 20:22:55 +000031static OptionDefinition g_settings_set_options[] = {
32 // clang-format off
33 { LLDB_OPT_SET_2, false, "global", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Apply the new value to the global default value." }
34 // clang-format on
35};
36
Kate Stoneb9c1b512016-09-06 20:57:50 +000037class CommandObjectSettingsSet : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +000038public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000039 CommandObjectSettingsSet(CommandInterpreter &interpreter)
40 : CommandObjectRaw(interpreter, "settings set",
Zachary Turnera4496982016-10-05 21:14:38 +000041 "Set the value of the specified debugger setting."),
Kate Stoneb9c1b512016-09-06 20:57:50 +000042 m_options() {
43 CommandArgumentEntry arg1;
44 CommandArgumentEntry arg2;
45 CommandArgumentData var_name_arg;
46 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +000047
Kate Stoneb9c1b512016-09-06 20:57:50 +000048 // Define the first (and only) variant of this arg.
49 var_name_arg.arg_type = eArgTypeSettingVariableName;
50 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +000051
Kate Stoneb9c1b512016-09-06 20:57:50 +000052 // There is only one variant this argument could be; put it into the
53 // argument entry.
54 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +000055
Kate Stoneb9c1b512016-09-06 20:57:50 +000056 // Define the first (and only) variant of this arg.
57 value_arg.arg_type = eArgTypeValue;
58 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +000059
Kate Stoneb9c1b512016-09-06 20:57:50 +000060 // There is only one variant this argument could be; put it into the
61 // argument entry.
62 arg2.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +000063
Kate Stoneb9c1b512016-09-06 20:57:50 +000064 // Push the data for the first argument into the m_arguments vector.
65 m_arguments.push_back(arg1);
66 m_arguments.push_back(arg2);
67
68 SetHelpLong(
69 "\nWhen setting a dictionary or array variable, you can set multiple entries \
70at once by giving the values to the set command. For example:"
71 R"(
Kate Stoneea671fb2015-07-14 05:48:36 +000072
73(lldb) settings set target.run-args value1 value2 value3
74(lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345
75
76(lldb) settings show target.run-args
77 [0]: 'value1'
78 [1]: 'value2'
79 [3]: 'value3'
80(lldb) settings show target.env-vars
81 'MYPATH=~/.:/usr/bin'
82 'SOME_ENV_VAR=12345'
83
Kate Stoneb9c1b512016-09-06 20:57:50 +000084)"
85 "Warning: The 'set' command re-sets the entire array or dictionary. If you \
Kate Stoneea671fb2015-07-14 05:48:36 +000086just want to add, remove or update individual values (or add something to \
87the end), use one of the other settings sub-commands: append, replace, \
Kate Stoneb9c1b512016-09-06 20:57:50 +000088insert-before or insert-after.");
89 }
Jim Ingham5a988412012-06-08 21:56:10 +000090
Kate Stoneb9c1b512016-09-06 20:57:50 +000091 ~CommandObjectSettingsSet() override = default;
92
93 // Overrides base class's behavior where WantsCompletion =
94 // !WantsRawCommandString.
95 bool WantsCompletion() override { return true; }
96
97 Options *GetOptions() override { return &m_options; }
98
99 class CommandOptions : public Options {
100 public:
101 CommandOptions() : Options(), m_global(false) {}
102
103 ~CommandOptions() override = default;
104
Zachary Turner97206d52017-05-12 04:51:55 +0000105 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
106 ExecutionContext *execution_context) override {
107 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000108 const int short_option = m_getopt_table[option_idx].val;
109
110 switch (short_option) {
111 case 'g':
112 m_global = true;
113 break;
114 default:
115 error.SetErrorStringWithFormat("unrecognized options '%c'",
116 short_option);
117 break;
118 }
119
120 return error;
Jim Ingham5a988412012-06-08 21:56:10 +0000121 }
122
Kate Stoneb9c1b512016-09-06 20:57:50 +0000123 void OptionParsingStarting(ExecutionContext *execution_context) override {
124 m_global = false;
Jim Ingham5a988412012-06-08 21:56:10 +0000125 }
Jim Ingham5a988412012-06-08 21:56:10 +0000126
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000127 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +0000128 return llvm::makeArrayRef(g_settings_set_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000129 }
Jim Ingham5a988412012-06-08 21:56:10 +0000130
Kate Stoneb9c1b512016-09-06 20:57:50 +0000131 // Instance variables to hold the values for command options.
Jim Ingham5a988412012-06-08 21:56:10 +0000132
Kate Stoneb9c1b512016-09-06 20:57:50 +0000133 bool m_global;
134 };
Jim Ingham5a988412012-06-08 21:56:10 +0000135
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000136 int HandleArgumentCompletion(
137 CompletionRequest &request,
138 OptionElementVector &opt_element_vector) override {
139 std::string completion_str(
140 request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
141 request.GetCursorCharPosition());
Jim Ingham5a988412012-06-08 21:56:10 +0000142
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000143 const size_t argc = request.GetParsedLine().GetArgumentCount();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144 const char *arg = nullptr;
145 int setting_var_idx;
Pavel Labath5f56fca2018-03-09 10:39:40 +0000146 for (setting_var_idx = 0; setting_var_idx < static_cast<int>(argc);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000147 ++setting_var_idx) {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000148 arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000149 if (arg && arg[0] != '-')
150 break; // We found our setting variable name index
Jim Ingham5a988412012-06-08 21:56:10 +0000151 }
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000152 if (request.GetCursorIndex() == setting_var_idx) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000153 // Attempting to complete setting variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000154 bool word_complete = request.GetWordComplete();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000155 CommandCompletions::InvokeCommonCompletionCallbacks(
156 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000157 completion_str.c_str(), request.GetMatchStartPoint(),
158 request.GetMaxReturnElements(), nullptr, word_complete,
159 request.GetMatches());
160 request.SetWordComplete(word_complete);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000161 } else {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000162 arg =
163 request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000164
165 if (arg) {
166 if (arg[0] == '-') {
167 // Complete option name
168 } else {
169 // Complete setting value
170 const char *setting_var_name =
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000171 request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
Zachary Turner97206d52017-05-12 04:51:55 +0000172 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000173 lldb::OptionValueSP value_sp(
174 m_interpreter.GetDebugger().GetPropertyValue(
175 &m_exe_ctx, setting_var_name, false, error));
176 if (value_sp) {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000177 bool word_complete = request.GetWordComplete();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000178 value_sp->AutoComplete(m_interpreter, completion_str.c_str(),
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000179 request.GetMatchStartPoint(),
180 request.GetMaxReturnElements(),
181 word_complete, request.GetMatches());
182 request.SetWordComplete(word_complete);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000183 }
184 }
185 }
186 }
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000187 return request.GetMatches().GetSize();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188 }
189
Jim Ingham5a988412012-06-08 21:56:10 +0000190protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000191 bool DoExecute(const char *command, CommandReturnObject &result) override {
192 Args cmd_args(command);
Jim Ingham5a988412012-06-08 21:56:10 +0000193
Kate Stoneb9c1b512016-09-06 20:57:50 +0000194 // Process possible options.
195 if (!ParseOptions(cmd_args, result))
196 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000197
Kate Stoneb9c1b512016-09-06 20:57:50 +0000198 const size_t argc = cmd_args.GetArgumentCount();
199 if ((argc < 2) && (!m_options.m_global)) {
200 result.AppendError("'settings set' takes more arguments");
201 result.SetStatus(eReturnStatusFailed);
202 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000203 }
Eugene Zelenko3f18ea02016-02-24 02:05:55 +0000204
Kate Stoneb9c1b512016-09-06 20:57:50 +0000205 const char *var_name = cmd_args.GetArgumentAtIndex(0);
206 if ((var_name == nullptr) || (var_name[0] == '\0')) {
207 result.AppendError(
208 "'settings set' command requires a valid variable name");
209 result.SetStatus(eReturnStatusFailed);
210 return false;
211 }
212
213 // Split the raw command into var_name and value pair.
214 llvm::StringRef raw_str(command);
215 std::string var_value_string = raw_str.split(var_name).second.str();
216 const char *var_value_cstr =
217 Args::StripSpaces(var_value_string, true, false, false);
218
Zachary Turner97206d52017-05-12 04:51:55 +0000219 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000220 if (m_options.m_global) {
221 error = m_interpreter.GetDebugger().SetPropertyValue(
222 nullptr, eVarSetOperationAssign, var_name, var_value_cstr);
223 }
224
225 if (error.Success()) {
226 // FIXME this is the same issue as the one in commands script import
227 // we could be setting target.load-script-from-symbol-file which would
Adrian Prantl05097242018-04-30 16:49:04 +0000228 // cause Python scripts to be loaded, which could run LLDB commands (e.g.
229 // settings set target.process.python-os-plugin-path) and cause a crash
Kate Stoneb9c1b512016-09-06 20:57:50 +0000230 // if we did not clear the command's exe_ctx first
231 ExecutionContext exe_ctx(m_exe_ctx);
232 m_exe_ctx.Clear();
233 error = m_interpreter.GetDebugger().SetPropertyValue(
234 &exe_ctx, eVarSetOperationAssign, var_name, var_value_cstr);
235 }
236
237 if (error.Fail()) {
238 result.AppendError(error.AsCString());
239 result.SetStatus(eReturnStatusFailed);
240 return false;
241 } else {
242 result.SetStatus(eReturnStatusSuccessFinishResult);
243 }
244
245 return result.Succeeded();
246 }
247
Jim Ingham5a988412012-06-08 21:56:10 +0000248private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000249 CommandOptions m_options;
Jim Ingham5a988412012-06-08 21:56:10 +0000250};
251
Jim Ingham5a988412012-06-08 21:56:10 +0000252//-------------------------------------------------------------------------
253// CommandObjectSettingsShow -- Show current values
254//-------------------------------------------------------------------------
255
Kate Stoneb9c1b512016-09-06 20:57:50 +0000256class CommandObjectSettingsShow : public CommandObjectParsed {
Jim Ingham5a988412012-06-08 21:56:10 +0000257public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000258 CommandObjectSettingsShow(CommandInterpreter &interpreter)
259 : CommandObjectParsed(interpreter, "settings show",
260 "Show matching debugger settings and their current "
261 "values. Defaults to showing all settings.",
262 nullptr) {
263 CommandArgumentEntry arg1;
264 CommandArgumentData var_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000265
Kate Stoneb9c1b512016-09-06 20:57:50 +0000266 // Define the first (and only) variant of this arg.
267 var_name_arg.arg_type = eArgTypeSettingVariableName;
268 var_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000269
Kate Stoneb9c1b512016-09-06 20:57:50 +0000270 // There is only one variant this argument could be; put it into the
271 // argument entry.
272 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000273
Kate Stoneb9c1b512016-09-06 20:57:50 +0000274 // Push the data for the first argument into the m_arguments vector.
275 m_arguments.push_back(arg1);
276 }
Jim Ingham5a988412012-06-08 21:56:10 +0000277
Kate Stoneb9c1b512016-09-06 20:57:50 +0000278 ~CommandObjectSettingsShow() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000279
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000280 int HandleArgumentCompletion(
281 CompletionRequest &request,
282 OptionElementVector &opt_element_vector) override {
283 std::string completion_str(
284 request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
285 request.GetCursorCharPosition());
Jim Ingham5a988412012-06-08 21:56:10 +0000286
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000287 bool word_complete = request.GetWordComplete();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000288 CommandCompletions::InvokeCommonCompletionCallbacks(
289 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000290 completion_str.c_str(), request.GetMatchStartPoint(),
291 request.GetMaxReturnElements(), nullptr, word_complete,
292 request.GetMatches());
293 request.SetWordComplete(word_complete);
294 return request.GetMatches().GetSize();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000295 }
Jim Ingham5a988412012-06-08 21:56:10 +0000296
297protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000298 bool DoExecute(Args &args, CommandReturnObject &result) override {
299 result.SetStatus(eReturnStatusSuccessFinishResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000300
Zachary Turner97d2c402016-10-05 23:40:23 +0000301 if (!args.empty()) {
Zachary Turnerd6a24752016-11-22 17:10:15 +0000302 for (const auto &arg : args) {
Zachary Turner97206d52017-05-12 04:51:55 +0000303 Status error(m_interpreter.GetDebugger().DumpPropertyValue(
Zachary Turnerd6a24752016-11-22 17:10:15 +0000304 &m_exe_ctx, result.GetOutputStream(), arg.ref,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000305 OptionValue::eDumpGroupValue));
306 if (error.Success()) {
307 result.GetOutputStream().EOL();
308 } else {
309 result.AppendError(error.AsCString());
310 result.SetStatus(eReturnStatusFailed);
Jim Ingham5a988412012-06-08 21:56:10 +0000311 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000312 }
313 } else {
314 m_interpreter.GetDebugger().DumpAllPropertyValues(
315 &m_exe_ctx, result.GetOutputStream(), OptionValue::eDumpGroupValue);
Jim Ingham5a988412012-06-08 21:56:10 +0000316 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000317
318 return result.Succeeded();
319 }
Jim Ingham5a988412012-06-08 21:56:10 +0000320};
321
322//-------------------------------------------------------------------------
323// CommandObjectSettingsList -- List settable variables
324//-------------------------------------------------------------------------
325
Kate Stoneb9c1b512016-09-06 20:57:50 +0000326class CommandObjectSettingsList : public CommandObjectParsed {
Kate Stone7428a182016-07-14 22:03:10 +0000327public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000328 CommandObjectSettingsList(CommandInterpreter &interpreter)
329 : CommandObjectParsed(interpreter, "settings list",
330 "List and describe matching debugger settings. "
331 "Defaults to all listing all settings.",
332 nullptr) {
333 CommandArgumentEntry arg;
334 CommandArgumentData var_name_arg;
335 CommandArgumentData prefix_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000336
Kate Stoneb9c1b512016-09-06 20:57:50 +0000337 // Define the first variant of this arg.
338 var_name_arg.arg_type = eArgTypeSettingVariableName;
339 var_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000340
Kate Stoneb9c1b512016-09-06 20:57:50 +0000341 // Define the second variant of this arg.
342 prefix_name_arg.arg_type = eArgTypeSettingPrefix;
343 prefix_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000344
Kate Stoneb9c1b512016-09-06 20:57:50 +0000345 arg.push_back(var_name_arg);
346 arg.push_back(prefix_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000347
Kate Stoneb9c1b512016-09-06 20:57:50 +0000348 // Push the data for the first argument into the m_arguments vector.
349 m_arguments.push_back(arg);
350 }
Jim Ingham5a988412012-06-08 21:56:10 +0000351
Kate Stoneb9c1b512016-09-06 20:57:50 +0000352 ~CommandObjectSettingsList() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000353
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000354 int HandleArgumentCompletion(
355 CompletionRequest &request,
356 OptionElementVector &opt_element_vector) override {
357 std::string completion_str(
358 request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
359 request.GetCursorCharPosition());
Jim Ingham5a988412012-06-08 21:56:10 +0000360
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000361 bool word_complete = request.GetWordComplete();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000362 CommandCompletions::InvokeCommonCompletionCallbacks(
363 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000364 completion_str.c_str(), request.GetMatchStartPoint(),
365 request.GetMaxReturnElements(), nullptr, word_complete,
366 request.GetMatches());
367 request.SetWordComplete(word_complete);
368 return request.GetMatches().GetSize();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000369 }
Jim Ingham5a988412012-06-08 21:56:10 +0000370
371protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000372 bool DoExecute(Args &args, CommandReturnObject &result) override {
373 result.SetStatus(eReturnStatusSuccessFinishResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000374
Kate Stoneb9c1b512016-09-06 20:57:50 +0000375 const bool will_modify = false;
376 const size_t argc = args.GetArgumentCount();
377 if (argc > 0) {
378 const bool dump_qualified_name = true;
Jim Ingham5a988412012-06-08 21:56:10 +0000379
Zachary Turner97d2c402016-10-05 23:40:23 +0000380 // TODO: Convert to StringRef based enumeration. Requires converting
381 // GetPropertyAtPath first.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000382 for (size_t i = 0; i < argc; ++i) {
383 const char *property_path = args.GetArgumentAtIndex(i);
Greg Clayton67cc0632012-08-22 17:17:09 +0000384
Kate Stoneb9c1b512016-09-06 20:57:50 +0000385 const Property *property =
386 m_interpreter.GetDebugger().GetValueProperties()->GetPropertyAtPath(
387 &m_exe_ctx, will_modify, property_path);
388
389 if (property) {
390 property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
391 dump_qualified_name);
392 } else {
393 result.AppendErrorWithFormat("invalid property path '%s'",
394 property_path);
395 result.SetStatus(eReturnStatusFailed);
Jim Ingham5a988412012-06-08 21:56:10 +0000396 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000397 }
398 } else {
399 m_interpreter.GetDebugger().DumpAllDescriptions(m_interpreter,
400 result.GetOutputStream());
Jim Ingham5a988412012-06-08 21:56:10 +0000401 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000402
403 return result.Succeeded();
404 }
Jim Ingham5a988412012-06-08 21:56:10 +0000405};
406
407//-------------------------------------------------------------------------
408// CommandObjectSettingsRemove
409//-------------------------------------------------------------------------
410
Kate Stoneb9c1b512016-09-06 20:57:50 +0000411class CommandObjectSettingsRemove : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000412public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000413 CommandObjectSettingsRemove(CommandInterpreter &interpreter)
414 : CommandObjectRaw(interpreter, "settings remove",
415 "Remove a value from a setting, specified by array "
Zachary Turnera4496982016-10-05 21:14:38 +0000416 "index or dictionary key.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000417 CommandArgumentEntry arg1;
418 CommandArgumentEntry arg2;
419 CommandArgumentData var_name_arg;
420 CommandArgumentData index_arg;
421 CommandArgumentData key_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000422
Kate Stoneb9c1b512016-09-06 20:57:50 +0000423 // Define the first (and only) variant of this arg.
424 var_name_arg.arg_type = eArgTypeSettingVariableName;
425 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000426
Kate Stoneb9c1b512016-09-06 20:57:50 +0000427 // There is only one variant this argument could be; put it into the
428 // argument entry.
429 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000430
Kate Stoneb9c1b512016-09-06 20:57:50 +0000431 // Define the first variant of this arg.
432 index_arg.arg_type = eArgTypeSettingIndex;
433 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000434
Kate Stoneb9c1b512016-09-06 20:57:50 +0000435 // Define the second variant of this arg.
436 key_arg.arg_type = eArgTypeSettingKey;
437 key_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000438
Kate Stoneb9c1b512016-09-06 20:57:50 +0000439 // Push both variants into this arg
440 arg2.push_back(index_arg);
441 arg2.push_back(key_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000442
Kate Stoneb9c1b512016-09-06 20:57:50 +0000443 // Push the data for the first argument into the m_arguments vector.
444 m_arguments.push_back(arg1);
445 m_arguments.push_back(arg2);
446 }
Jim Ingham5a988412012-06-08 21:56:10 +0000447
Kate Stoneb9c1b512016-09-06 20:57:50 +0000448 ~CommandObjectSettingsRemove() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000449
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000450 int HandleArgumentCompletion(
451 CompletionRequest &request,
452 OptionElementVector &opt_element_vector) override {
453 std::string completion_str(
454 request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
455 request.GetCursorCharPosition());
Jim Ingham5a988412012-06-08 21:56:10 +0000456
Kate Stoneb9c1b512016-09-06 20:57:50 +0000457 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000458 bool word_complete = request.GetWordComplete();
459 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000460 CommandCompletions::InvokeCommonCompletionCallbacks(
461 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000462 completion_str.c_str(), request.GetMatchStartPoint(),
463 request.GetMaxReturnElements(), nullptr, word_complete,
464 request.GetMatches());
465 request.SetWordComplete(word_complete);
466 return request.GetMatches().GetSize();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000467 }
Jim Ingham5a988412012-06-08 21:56:10 +0000468
469protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000470 bool DoExecute(const char *command, CommandReturnObject &result) override {
471 result.SetStatus(eReturnStatusSuccessFinishNoResult);
472
473 Args cmd_args(command);
474
475 // Process possible options.
476 if (!ParseOptions(cmd_args, result))
477 return false;
478
479 const size_t argc = cmd_args.GetArgumentCount();
480 if (argc == 0) {
481 result.AppendError("'settings set' takes an array or dictionary item, or "
482 "an array followed by one or more indexes, or a "
483 "dictionary followed by one or more key names to "
484 "remove");
485 result.SetStatus(eReturnStatusFailed);
486 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000487 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000488
489 const char *var_name = cmd_args.GetArgumentAtIndex(0);
490 if ((var_name == nullptr) || (var_name[0] == '\0')) {
491 result.AppendError(
492 "'settings set' command requires a valid variable name");
493 result.SetStatus(eReturnStatusFailed);
494 return false;
495 }
496
497 // Split the raw command into var_name and value pair.
498 llvm::StringRef raw_str(command);
499 std::string var_value_string = raw_str.split(var_name).second.str();
500 const char *var_value_cstr =
501 Args::StripSpaces(var_value_string, true, true, false);
502
Zachary Turner97206d52017-05-12 04:51:55 +0000503 Status error(m_interpreter.GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000504 &m_exe_ctx, eVarSetOperationRemove, var_name, var_value_cstr));
505 if (error.Fail()) {
506 result.AppendError(error.AsCString());
507 result.SetStatus(eReturnStatusFailed);
508 return false;
509 }
510
511 return result.Succeeded();
512 }
Jim Ingham5a988412012-06-08 21:56:10 +0000513};
514
515//-------------------------------------------------------------------------
516// CommandObjectSettingsReplace
517//-------------------------------------------------------------------------
518
Kate Stoneb9c1b512016-09-06 20:57:50 +0000519class CommandObjectSettingsReplace : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000520public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000521 CommandObjectSettingsReplace(CommandInterpreter &interpreter)
522 : CommandObjectRaw(interpreter, "settings replace",
523 "Replace the debugger setting value specified by "
Zachary Turnera4496982016-10-05 21:14:38 +0000524 "array index or dictionary key.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000525 CommandArgumentEntry arg1;
526 CommandArgumentEntry arg2;
527 CommandArgumentEntry arg3;
528 CommandArgumentData var_name_arg;
529 CommandArgumentData index_arg;
530 CommandArgumentData key_arg;
531 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000532
Kate Stoneb9c1b512016-09-06 20:57:50 +0000533 // Define the first (and only) variant of this arg.
534 var_name_arg.arg_type = eArgTypeSettingVariableName;
535 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000536
Kate Stoneb9c1b512016-09-06 20:57:50 +0000537 // There is only one variant this argument could be; put it into the
538 // argument entry.
539 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000540
Kate Stoneb9c1b512016-09-06 20:57:50 +0000541 // Define the first (variant of this arg.
542 index_arg.arg_type = eArgTypeSettingIndex;
543 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000544
Kate Stoneb9c1b512016-09-06 20:57:50 +0000545 // Define the second (variant of this arg.
546 key_arg.arg_type = eArgTypeSettingKey;
547 key_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000548
Kate Stoneb9c1b512016-09-06 20:57:50 +0000549 // Put both variants into this arg
550 arg2.push_back(index_arg);
551 arg2.push_back(key_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000552
Kate Stoneb9c1b512016-09-06 20:57:50 +0000553 // Define the first (and only) variant of this arg.
554 value_arg.arg_type = eArgTypeValue;
555 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000556
Kate Stoneb9c1b512016-09-06 20:57:50 +0000557 // There is only one variant this argument could be; put it into the
558 // argument entry.
559 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000560
Kate Stoneb9c1b512016-09-06 20:57:50 +0000561 // Push the data for the first argument into the m_arguments vector.
562 m_arguments.push_back(arg1);
563 m_arguments.push_back(arg2);
564 m_arguments.push_back(arg3);
565 }
Jim Ingham5a988412012-06-08 21:56:10 +0000566
Kate Stoneb9c1b512016-09-06 20:57:50 +0000567 ~CommandObjectSettingsReplace() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000568
Kate Stoneb9c1b512016-09-06 20:57:50 +0000569 // Overrides base class's behavior where WantsCompletion =
570 // !WantsRawCommandString.
571 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000572
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000573 int HandleArgumentCompletion(
574 CompletionRequest &request,
575 OptionElementVector &opt_element_vector) override {
576 std::string completion_str(
577 request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
578 request.GetCursorCharPosition());
Jim Ingham5a988412012-06-08 21:56:10 +0000579
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000580 bool word_complete = request.GetWordComplete();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000581 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000582 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000583 CommandCompletions::InvokeCommonCompletionCallbacks(
584 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000585 completion_str.c_str(), request.GetMatchStartPoint(),
586 request.GetMaxReturnElements(), nullptr, word_complete,
587 request.GetMatches());
588 request.SetWordComplete(word_complete);
Jim Ingham5a988412012-06-08 21:56:10 +0000589
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000590 return request.GetMatches().GetSize();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000591 }
Jim Ingham5a988412012-06-08 21:56:10 +0000592
593protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000594 bool DoExecute(const char *command, CommandReturnObject &result) override {
595 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000596
Kate Stoneb9c1b512016-09-06 20:57:50 +0000597 Args cmd_args(command);
598 const char *var_name = cmd_args.GetArgumentAtIndex(0);
599 if ((var_name == nullptr) || (var_name[0] == '\0')) {
600 result.AppendError("'settings replace' command requires a valid variable "
601 "name; No value supplied");
602 result.SetStatus(eReturnStatusFailed);
603 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000604 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000605
606 // Split the raw command into var_name, index_value, and value triple.
607 llvm::StringRef raw_str(command);
608 std::string var_value_string = raw_str.split(var_name).second.str();
609 const char *var_value_cstr =
610 Args::StripSpaces(var_value_string, true, true, false);
611
Zachary Turner97206d52017-05-12 04:51:55 +0000612 Status error(m_interpreter.GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000613 &m_exe_ctx, eVarSetOperationReplace, var_name, var_value_cstr));
614 if (error.Fail()) {
615 result.AppendError(error.AsCString());
616 result.SetStatus(eReturnStatusFailed);
617 return false;
618 } else {
619 result.SetStatus(eReturnStatusSuccessFinishNoResult);
620 }
621
622 return result.Succeeded();
623 }
Jim Ingham5a988412012-06-08 21:56:10 +0000624};
625
626//-------------------------------------------------------------------------
627// CommandObjectSettingsInsertBefore
628//-------------------------------------------------------------------------
629
Kate Stoneb9c1b512016-09-06 20:57:50 +0000630class CommandObjectSettingsInsertBefore : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000631public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000632 CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
633 : CommandObjectRaw(interpreter, "settings insert-before",
634 "Insert one or more values into an debugger array "
635 "setting immediately before the specified element "
Zachary Turnera4496982016-10-05 21:14:38 +0000636 "index.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000637 CommandArgumentEntry arg1;
638 CommandArgumentEntry arg2;
639 CommandArgumentEntry arg3;
640 CommandArgumentData var_name_arg;
641 CommandArgumentData index_arg;
642 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000643
Kate Stoneb9c1b512016-09-06 20:57:50 +0000644 // Define the first (and only) variant of this arg.
645 var_name_arg.arg_type = eArgTypeSettingVariableName;
646 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000647
Kate Stoneb9c1b512016-09-06 20:57:50 +0000648 // There is only one variant this argument could be; put it into the
649 // argument entry.
650 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000651
Kate Stoneb9c1b512016-09-06 20:57:50 +0000652 // Define the first (variant of this arg.
653 index_arg.arg_type = eArgTypeSettingIndex;
654 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000655
Kate Stoneb9c1b512016-09-06 20:57:50 +0000656 // There is only one variant this argument could be; put it into the
657 // argument entry.
658 arg2.push_back(index_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000659
Kate Stoneb9c1b512016-09-06 20:57:50 +0000660 // Define the first (and only) variant of this arg.
661 value_arg.arg_type = eArgTypeValue;
662 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000663
Kate Stoneb9c1b512016-09-06 20:57:50 +0000664 // There is only one variant this argument could be; put it into the
665 // argument entry.
666 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000667
Kate Stoneb9c1b512016-09-06 20:57:50 +0000668 // Push the data for the first argument into the m_arguments vector.
669 m_arguments.push_back(arg1);
670 m_arguments.push_back(arg2);
671 m_arguments.push_back(arg3);
672 }
Jim Ingham5a988412012-06-08 21:56:10 +0000673
Kate Stoneb9c1b512016-09-06 20:57:50 +0000674 ~CommandObjectSettingsInsertBefore() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000675
Kate Stoneb9c1b512016-09-06 20:57:50 +0000676 // Overrides base class's behavior where WantsCompletion =
677 // !WantsRawCommandString.
678 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000679
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000680 int HandleArgumentCompletion(
681 CompletionRequest &request,
682 OptionElementVector &opt_element_vector) override {
683 std::string completion_str(
684 request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
685 request.GetCursorCharPosition());
Jim Ingham5a988412012-06-08 21:56:10 +0000686
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000687 bool word_complete = request.GetWordComplete();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000688 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000689 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000690 CommandCompletions::InvokeCommonCompletionCallbacks(
691 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000692 completion_str.c_str(), request.GetMatchStartPoint(),
693 request.GetMaxReturnElements(), nullptr, word_complete,
694 request.GetMatches());
695 request.SetWordComplete(word_complete);
Jim Ingham5a988412012-06-08 21:56:10 +0000696
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000697 return request.GetMatches().GetSize();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000698 }
Jim Ingham5a988412012-06-08 21:56:10 +0000699
700protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000701 bool DoExecute(const char *command, CommandReturnObject &result) override {
702 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000703
Kate Stoneb9c1b512016-09-06 20:57:50 +0000704 Args cmd_args(command);
705 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +0000706
Kate Stoneb9c1b512016-09-06 20:57:50 +0000707 if (argc < 3) {
708 result.AppendError("'settings insert-before' takes more arguments");
709 result.SetStatus(eReturnStatusFailed);
710 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000711 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000712
713 const char *var_name = cmd_args.GetArgumentAtIndex(0);
714 if ((var_name == nullptr) || (var_name[0] == '\0')) {
715 result.AppendError("'settings insert-before' command requires a valid "
716 "variable name; No value supplied");
717 result.SetStatus(eReturnStatusFailed);
718 return false;
719 }
720
721 // Split the raw command into var_name, index_value, and value triple.
722 llvm::StringRef raw_str(command);
723 std::string var_value_string = raw_str.split(var_name).second.str();
724 const char *var_value_cstr =
725 Args::StripSpaces(var_value_string, true, true, false);
726
Zachary Turner97206d52017-05-12 04:51:55 +0000727 Status error(m_interpreter.GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000728 &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value_cstr));
729 if (error.Fail()) {
730 result.AppendError(error.AsCString());
731 result.SetStatus(eReturnStatusFailed);
732 return false;
733 }
734
735 return result.Succeeded();
736 }
Jim Ingham5a988412012-06-08 21:56:10 +0000737};
738
739//-------------------------------------------------------------------------
740// CommandObjectSettingInsertAfter
741//-------------------------------------------------------------------------
742
Kate Stoneb9c1b512016-09-06 20:57:50 +0000743class CommandObjectSettingsInsertAfter : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000744public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000745 CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
746 : CommandObjectRaw(interpreter, "settings insert-after",
747 "Insert one or more values into a debugger array "
Zachary Turnera4496982016-10-05 21:14:38 +0000748 "settings after the specified element index.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000749 CommandArgumentEntry arg1;
750 CommandArgumentEntry arg2;
751 CommandArgumentEntry arg3;
752 CommandArgumentData var_name_arg;
753 CommandArgumentData index_arg;
754 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000755
Kate Stoneb9c1b512016-09-06 20:57:50 +0000756 // Define the first (and only) variant of this arg.
757 var_name_arg.arg_type = eArgTypeSettingVariableName;
758 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000759
Kate Stoneb9c1b512016-09-06 20:57:50 +0000760 // There is only one variant this argument could be; put it into the
761 // argument entry.
762 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000763
Kate Stoneb9c1b512016-09-06 20:57:50 +0000764 // Define the first (variant of this arg.
765 index_arg.arg_type = eArgTypeSettingIndex;
766 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000767
Kate Stoneb9c1b512016-09-06 20:57:50 +0000768 // There is only one variant this argument could be; put it into the
769 // argument entry.
770 arg2.push_back(index_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000771
Kate Stoneb9c1b512016-09-06 20:57:50 +0000772 // Define the first (and only) variant of this arg.
773 value_arg.arg_type = eArgTypeValue;
774 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000775
Kate Stoneb9c1b512016-09-06 20:57:50 +0000776 // There is only one variant this argument could be; put it into the
777 // argument entry.
778 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000779
Kate Stoneb9c1b512016-09-06 20:57:50 +0000780 // Push the data for the first argument into the m_arguments vector.
781 m_arguments.push_back(arg1);
782 m_arguments.push_back(arg2);
783 m_arguments.push_back(arg3);
784 }
Jim Ingham5a988412012-06-08 21:56:10 +0000785
Kate Stoneb9c1b512016-09-06 20:57:50 +0000786 ~CommandObjectSettingsInsertAfter() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000787
Kate Stoneb9c1b512016-09-06 20:57:50 +0000788 // Overrides base class's behavior where WantsCompletion =
789 // !WantsRawCommandString.
790 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000791
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000792 int HandleArgumentCompletion(
793 CompletionRequest &request,
794 OptionElementVector &opt_element_vector) override {
795 std::string completion_str(
796 request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
797 request.GetCursorCharPosition());
Jim Ingham5a988412012-06-08 21:56:10 +0000798
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000799 bool word_complete = request.GetWordComplete();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000800 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000801 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000802 CommandCompletions::InvokeCommonCompletionCallbacks(
803 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000804 completion_str.c_str(), request.GetMatchStartPoint(),
805 request.GetMaxReturnElements(), nullptr, word_complete,
806 request.GetMatches());
807 request.SetWordComplete(word_complete);
Jim Ingham5a988412012-06-08 21:56:10 +0000808
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000809 return request.GetMatches().GetSize();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000810 }
811
Jim Ingham5a988412012-06-08 21:56:10 +0000812protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000813 bool DoExecute(const char *command, CommandReturnObject &result) override {
814 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000815
Kate Stoneb9c1b512016-09-06 20:57:50 +0000816 Args cmd_args(command);
817 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +0000818
Kate Stoneb9c1b512016-09-06 20:57:50 +0000819 if (argc < 3) {
820 result.AppendError("'settings insert-after' takes more arguments");
821 result.SetStatus(eReturnStatusFailed);
822 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000823 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000824
825 const char *var_name = cmd_args.GetArgumentAtIndex(0);
826 if ((var_name == nullptr) || (var_name[0] == '\0')) {
827 result.AppendError("'settings insert-after' command requires a valid "
828 "variable name; No value supplied");
829 result.SetStatus(eReturnStatusFailed);
830 return false;
831 }
832
833 // Split the raw command into var_name, index_value, and value triple.
834 llvm::StringRef raw_str(command);
835 std::string var_value_string = raw_str.split(var_name).second.str();
836 const char *var_value_cstr =
837 Args::StripSpaces(var_value_string, true, true, false);
838
Zachary Turner97206d52017-05-12 04:51:55 +0000839 Status error(m_interpreter.GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000840 &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value_cstr));
841 if (error.Fail()) {
842 result.AppendError(error.AsCString());
843 result.SetStatus(eReturnStatusFailed);
844 return false;
845 }
846
847 return result.Succeeded();
848 }
Jim Ingham5a988412012-06-08 21:56:10 +0000849};
850
851//-------------------------------------------------------------------------
852// CommandObjectSettingsAppend
853//-------------------------------------------------------------------------
854
Kate Stoneb9c1b512016-09-06 20:57:50 +0000855class CommandObjectSettingsAppend : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000856public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000857 CommandObjectSettingsAppend(CommandInterpreter &interpreter)
858 : CommandObjectRaw(interpreter, "settings append",
859 "Append one or more values to a debugger array, "
Zachary Turnera4496982016-10-05 21:14:38 +0000860 "dictionary, or string setting.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000861 CommandArgumentEntry arg1;
862 CommandArgumentEntry arg2;
863 CommandArgumentData var_name_arg;
864 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000865
Kate Stoneb9c1b512016-09-06 20:57:50 +0000866 // Define the first (and only) variant of this arg.
867 var_name_arg.arg_type = eArgTypeSettingVariableName;
868 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000869
Kate Stoneb9c1b512016-09-06 20:57:50 +0000870 // There is only one variant this argument could be; put it into the
871 // argument entry.
872 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000873
Kate Stoneb9c1b512016-09-06 20:57:50 +0000874 // Define the first (and only) variant of this arg.
875 value_arg.arg_type = eArgTypeValue;
876 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000877
Kate Stoneb9c1b512016-09-06 20:57:50 +0000878 // There is only one variant this argument could be; put it into the
879 // argument entry.
880 arg2.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000881
Kate Stoneb9c1b512016-09-06 20:57:50 +0000882 // Push the data for the first argument into the m_arguments vector.
883 m_arguments.push_back(arg1);
884 m_arguments.push_back(arg2);
885 }
Jim Ingham5a988412012-06-08 21:56:10 +0000886
Kate Stoneb9c1b512016-09-06 20:57:50 +0000887 ~CommandObjectSettingsAppend() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000888
Kate Stoneb9c1b512016-09-06 20:57:50 +0000889 // Overrides base class's behavior where WantsCompletion =
890 // !WantsRawCommandString.
891 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000892
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000893 int HandleArgumentCompletion(
894 CompletionRequest &request,
895 OptionElementVector &opt_element_vector) override {
896 std::string completion_str(
897 request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
898 request.GetCursorCharPosition());
Jim Ingham5a988412012-06-08 21:56:10 +0000899
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000900 bool word_complete = request.GetWordComplete();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000901 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000902 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000903 CommandCompletions::InvokeCommonCompletionCallbacks(
904 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000905 completion_str.c_str(), request.GetMatchStartPoint(),
906 request.GetMaxReturnElements(), nullptr, word_complete,
907 request.GetMatches());
908 request.SetWordComplete(word_complete);
Jim Ingham5a988412012-06-08 21:56:10 +0000909
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000910 return request.GetMatches().GetSize();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000911 }
Jim Ingham5a988412012-06-08 21:56:10 +0000912
913protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000914 bool DoExecute(const char *command, CommandReturnObject &result) override {
915 result.SetStatus(eReturnStatusSuccessFinishNoResult);
916 Args cmd_args(command);
917 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +0000918
Kate Stoneb9c1b512016-09-06 20:57:50 +0000919 if (argc < 2) {
920 result.AppendError("'settings append' takes more arguments");
921 result.SetStatus(eReturnStatusFailed);
922 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000923 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000924
925 const char *var_name = cmd_args.GetArgumentAtIndex(0);
926 if ((var_name == nullptr) || (var_name[0] == '\0')) {
927 result.AppendError("'settings append' command requires a valid variable "
928 "name; No value supplied");
929 result.SetStatus(eReturnStatusFailed);
930 return false;
931 }
932
Adrian Prantl05097242018-04-30 16:49:04 +0000933 // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
934 // character string later on.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000935
936 // Split the raw command into var_name and value pair.
937 llvm::StringRef raw_str(command);
938 std::string var_value_string = raw_str.split(var_name).second.str();
939 const char *var_value_cstr =
940 Args::StripSpaces(var_value_string, true, true, false);
941
Zachary Turner97206d52017-05-12 04:51:55 +0000942 Status error(m_interpreter.GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000943 &m_exe_ctx, eVarSetOperationAppend, var_name, var_value_cstr));
944 if (error.Fail()) {
945 result.AppendError(error.AsCString());
946 result.SetStatus(eReturnStatusFailed);
947 return false;
948 }
949
950 return result.Succeeded();
951 }
Jim Ingham5a988412012-06-08 21:56:10 +0000952};
953
954//-------------------------------------------------------------------------
955// CommandObjectSettingsClear
956//-------------------------------------------------------------------------
957
Kate Stoneb9c1b512016-09-06 20:57:50 +0000958class CommandObjectSettingsClear : public CommandObjectParsed {
Jim Ingham5a988412012-06-08 21:56:10 +0000959public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000960 CommandObjectSettingsClear(CommandInterpreter &interpreter)
961 : CommandObjectParsed(
962 interpreter, "settings clear",
963 "Clear a debugger setting array, dictionary, or string.", nullptr) {
964 CommandArgumentEntry arg;
965 CommandArgumentData var_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000966
Kate Stoneb9c1b512016-09-06 20:57:50 +0000967 // Define the first (and only) variant of this arg.
968 var_name_arg.arg_type = eArgTypeSettingVariableName;
969 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000970
Kate Stoneb9c1b512016-09-06 20:57:50 +0000971 // There is only one variant this argument could be; put it into the
972 // argument entry.
973 arg.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000974
Kate Stoneb9c1b512016-09-06 20:57:50 +0000975 // Push the data for the first argument into the m_arguments vector.
976 m_arguments.push_back(arg);
977 }
Jim Ingham5a988412012-06-08 21:56:10 +0000978
Kate Stoneb9c1b512016-09-06 20:57:50 +0000979 ~CommandObjectSettingsClear() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000980
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000981 int HandleArgumentCompletion(
982 CompletionRequest &request,
983 OptionElementVector &opt_element_vector) override {
984 std::string completion_str(
985 request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()),
986 request.GetCursorCharPosition());
Jim Ingham5a988412012-06-08 21:56:10 +0000987
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000988 bool word_complete = request.GetWordComplete();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000989 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000990 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000991 CommandCompletions::InvokeCommonCompletionCallbacks(
992 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000993 completion_str.c_str(), request.GetMatchStartPoint(),
994 request.GetMaxReturnElements(), nullptr, word_complete,
995 request.GetMatches());
996 request.SetWordComplete(word_complete);
Jim Ingham5a988412012-06-08 21:56:10 +0000997
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000998 return request.GetMatches().GetSize();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000999 }
Jim Ingham5a988412012-06-08 21:56:10 +00001000
1001protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001002 bool DoExecute(Args &command, CommandReturnObject &result) override {
1003 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1004 const size_t argc = command.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +00001005
Kate Stoneb9c1b512016-09-06 20:57:50 +00001006 if (argc != 1) {
1007 result.AppendError("'settings clear' takes exactly one argument");
1008 result.SetStatus(eReturnStatusFailed);
1009 return false;
Jim Ingham5a988412012-06-08 21:56:10 +00001010 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001011
1012 const char *var_name = command.GetArgumentAtIndex(0);
1013 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1014 result.AppendError("'settings clear' command requires a valid variable "
1015 "name; No value supplied");
1016 result.SetStatus(eReturnStatusFailed);
1017 return false;
1018 }
1019
Zachary Turner97206d52017-05-12 04:51:55 +00001020 Status error(m_interpreter.GetDebugger().SetPropertyValue(
Zachary Turner31d97a52016-11-17 18:08:12 +00001021 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001022 if (error.Fail()) {
1023 result.AppendError(error.AsCString());
1024 result.SetStatus(eReturnStatusFailed);
1025 return false;
1026 }
1027
1028 return result.Succeeded();
1029 }
Jim Ingham5a988412012-06-08 21:56:10 +00001030};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001031
1032//-------------------------------------------------------------------------
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001033// CommandObjectMultiwordSettings
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001034//-------------------------------------------------------------------------
1035
Kate Stoneb9c1b512016-09-06 20:57:50 +00001036CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
1037 CommandInterpreter &interpreter)
1038 : CommandObjectMultiword(interpreter, "settings",
1039 "Commands for managing LLDB settings.",
1040 "settings <subcommand> [<command-options>]") {
1041 LoadSubCommand("set",
1042 CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
1043 LoadSubCommand("show",
1044 CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
1045 LoadSubCommand("list",
1046 CommandObjectSP(new CommandObjectSettingsList(interpreter)));
1047 LoadSubCommand("remove",
1048 CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
1049 LoadSubCommand("replace", CommandObjectSP(
1050 new CommandObjectSettingsReplace(interpreter)));
1051 LoadSubCommand(
1052 "insert-before",
1053 CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
1054 LoadSubCommand(
1055 "insert-after",
1056 CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
1057 LoadSubCommand("append",
1058 CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
1059 LoadSubCommand("clear",
1060 CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001061}
1062
Eugene Zelenko3f18ea02016-02-24 02:05:55 +00001063CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default;