blob: e7e72de5a7eefb4980a82649cec854e2d6776e78 [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
Jim Ingham5a988412012-06-08 21:56:10 +000023
Tatyana Krasnukha8fe53c492018-09-26 18:50:19 +000024static constexpr OptionDefinition g_settings_set_options[] = {
Zachary Turner1f0f5b52016-09-22 20:22:55 +000025 // clang-format off
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +000026 { LLDB_OPT_SET_2, false, "global", 'g', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Apply the new value to the global default value." },
27 { LLDB_OPT_SET_2, false, "force", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Force an empty value to be accepted as the default." }
Zachary Turner1f0f5b52016-09-22 20:22:55 +000028 // clang-format on
29};
30
Kate Stoneb9c1b512016-09-06 20:57:50 +000031class CommandObjectSettingsSet : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +000032public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000033 CommandObjectSettingsSet(CommandInterpreter &interpreter)
34 : CommandObjectRaw(interpreter, "settings set",
Zachary Turnera4496982016-10-05 21:14:38 +000035 "Set the value of the specified debugger setting."),
Kate Stoneb9c1b512016-09-06 20:57:50 +000036 m_options() {
37 CommandArgumentEntry arg1;
38 CommandArgumentEntry arg2;
39 CommandArgumentData var_name_arg;
40 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +000041
Kate Stoneb9c1b512016-09-06 20:57:50 +000042 // Define the first (and only) variant of this arg.
43 var_name_arg.arg_type = eArgTypeSettingVariableName;
44 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +000045
Kate Stoneb9c1b512016-09-06 20:57:50 +000046 // There is only one variant this argument could be; put it into the
47 // argument entry.
48 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +000049
Kate Stoneb9c1b512016-09-06 20:57:50 +000050 // Define the first (and only) variant of this arg.
51 value_arg.arg_type = eArgTypeValue;
52 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +000053
Kate Stoneb9c1b512016-09-06 20:57:50 +000054 // There is only one variant this argument could be; put it into the
55 // argument entry.
56 arg2.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +000057
Kate Stoneb9c1b512016-09-06 20:57:50 +000058 // Push the data for the first argument into the m_arguments vector.
59 m_arguments.push_back(arg1);
60 m_arguments.push_back(arg2);
61
62 SetHelpLong(
63 "\nWhen setting a dictionary or array variable, you can set multiple entries \
64at once by giving the values to the set command. For example:"
65 R"(
Kate Stoneea671fb2015-07-14 05:48:36 +000066
67(lldb) settings set target.run-args value1 value2 value3
68(lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345
69
70(lldb) settings show target.run-args
71 [0]: 'value1'
72 [1]: 'value2'
73 [3]: 'value3'
74(lldb) settings show target.env-vars
75 'MYPATH=~/.:/usr/bin'
76 'SOME_ENV_VAR=12345'
77
Kate Stoneb9c1b512016-09-06 20:57:50 +000078)"
79 "Warning: The 'set' command re-sets the entire array or dictionary. If you \
Kate Stoneea671fb2015-07-14 05:48:36 +000080just want to add, remove or update individual values (or add something to \
81the end), use one of the other settings sub-commands: append, replace, \
Kate Stoneb9c1b512016-09-06 20:57:50 +000082insert-before or insert-after.");
83 }
Jim Ingham5a988412012-06-08 21:56:10 +000084
Kate Stoneb9c1b512016-09-06 20:57:50 +000085 ~CommandObjectSettingsSet() override = default;
86
87 // Overrides base class's behavior where WantsCompletion =
88 // !WantsRawCommandString.
89 bool WantsCompletion() override { return true; }
90
91 Options *GetOptions() override { return &m_options; }
92
93 class CommandOptions : public Options {
94 public:
95 CommandOptions() : Options(), m_global(false) {}
96
97 ~CommandOptions() override = default;
98
Zachary Turner97206d52017-05-12 04:51:55 +000099 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
100 ExecutionContext *execution_context) override {
101 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000102 const int short_option = m_getopt_table[option_idx].val;
103
104 switch (short_option) {
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000105 case 'f':
106 m_force = true;
107 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000108 case 'g':
109 m_global = true;
110 break;
111 default:
112 error.SetErrorStringWithFormat("unrecognized options '%c'",
113 short_option);
114 break;
115 }
116
117 return error;
Jim Ingham5a988412012-06-08 21:56:10 +0000118 }
119
Kate Stoneb9c1b512016-09-06 20:57:50 +0000120 void OptionParsingStarting(ExecutionContext *execution_context) override {
121 m_global = false;
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000122 m_force = false;
Jim Ingham5a988412012-06-08 21:56:10 +0000123 }
Jim Ingham5a988412012-06-08 21:56:10 +0000124
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000125 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +0000126 return llvm::makeArrayRef(g_settings_set_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +0000127 }
Jim Ingham5a988412012-06-08 21:56:10 +0000128
Kate Stoneb9c1b512016-09-06 20:57:50 +0000129 // Instance variables to hold the values for command options.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000130 bool m_global;
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000131 bool m_force;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000132 };
Jim Ingham5a988412012-06-08 21:56:10 +0000133
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000134 int HandleArgumentCompletion(
135 CompletionRequest &request,
136 OptionElementVector &opt_element_vector) override {
Jim Ingham5a988412012-06-08 21:56:10 +0000137
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000138 const size_t argc = request.GetParsedLine().GetArgumentCount();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000139 const char *arg = nullptr;
140 int setting_var_idx;
Pavel Labath5f56fca2018-03-09 10:39:40 +0000141 for (setting_var_idx = 0; setting_var_idx < static_cast<int>(argc);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000142 ++setting_var_idx) {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000143 arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144 if (arg && arg[0] != '-')
145 break; // We found our setting variable name index
Jim Ingham5a988412012-06-08 21:56:10 +0000146 }
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000147 if (request.GetCursorIndex() == setting_var_idx) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000148 // Attempting to complete setting variable name
149 CommandCompletions::InvokeCommonCompletionCallbacks(
150 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000151 request, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000152 } else {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000153 arg =
154 request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000155
156 if (arg) {
157 if (arg[0] == '-') {
158 // Complete option name
159 } else {
160 // Complete setting value
161 const char *setting_var_name =
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000162 request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
Zachary Turner97206d52017-05-12 04:51:55 +0000163 Status error;
Jonas Devlieghere57179862019-04-27 06:19:42 +0000164 lldb::OptionValueSP value_sp(GetDebugger().GetPropertyValue(
165 &m_exe_ctx, setting_var_name, false, error));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000166 if (value_sp) {
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000167 value_sp->AutoComplete(m_interpreter, request);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000168 }
169 }
170 }
171 }
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000172 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000173 }
174
Jim Ingham5a988412012-06-08 21:56:10 +0000175protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000176 bool DoExecute(llvm::StringRef command,
177 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000178 Args cmd_args(command);
Jim Ingham5a988412012-06-08 21:56:10 +0000179
Kate Stoneb9c1b512016-09-06 20:57:50 +0000180 // Process possible options.
181 if (!ParseOptions(cmd_args, result))
182 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000183
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000184 const size_t min_argc = m_options.m_force ? 1 : 2;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000185 const size_t argc = cmd_args.GetArgumentCount();
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000186
187 if ((argc < min_argc) && (!m_options.m_global)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188 result.AppendError("'settings set' takes more arguments");
189 result.SetStatus(eReturnStatusFailed);
190 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000191 }
Eugene Zelenko3f18ea02016-02-24 02:05:55 +0000192
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193 const char *var_name = cmd_args.GetArgumentAtIndex(0);
194 if ((var_name == nullptr) || (var_name[0] == '\0')) {
195 result.AppendError(
196 "'settings set' command requires a valid variable name");
197 result.SetStatus(eReturnStatusFailed);
198 return false;
199 }
200
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000201 // A missing value corresponds to clearing the setting when "force" is
202 // specified.
203 if (argc == 1 && m_options.m_force) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000204 Status error(GetDebugger().SetPropertyValue(
Jonas Devlieghere9c6c2012018-10-24 22:04:20 +0000205 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
206 if (error.Fail()) {
207 result.AppendError(error.AsCString());
208 result.SetStatus(eReturnStatusFailed);
209 return false;
210 }
211 return result.Succeeded();
212 }
213
Kate Stoneb9c1b512016-09-06 20:57:50 +0000214 // Split the raw command into var_name and value pair.
215 llvm::StringRef raw_str(command);
216 std::string var_value_string = raw_str.split(var_name).second.str();
217 const char *var_value_cstr =
218 Args::StripSpaces(var_value_string, true, false, false);
219
Zachary Turner97206d52017-05-12 04:51:55 +0000220 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000221 if (m_options.m_global) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000222 error = GetDebugger().SetPropertyValue(nullptr, eVarSetOperationAssign,
223 var_name, var_value_cstr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000224 }
225
226 if (error.Success()) {
227 // FIXME this is the same issue as the one in commands script import
228 // we could be setting target.load-script-from-symbol-file which would
Adrian Prantl05097242018-04-30 16:49:04 +0000229 // cause Python scripts to be loaded, which could run LLDB commands (e.g.
230 // settings set target.process.python-os-plugin-path) and cause a crash
Kate Stoneb9c1b512016-09-06 20:57:50 +0000231 // if we did not clear the command's exe_ctx first
232 ExecutionContext exe_ctx(m_exe_ctx);
233 m_exe_ctx.Clear();
Jonas Devlieghere57179862019-04-27 06:19:42 +0000234 error = GetDebugger().SetPropertyValue(&exe_ctx, eVarSetOperationAssign,
235 var_name, var_value_cstr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000236 }
237
238 if (error.Fail()) {
239 result.AppendError(error.AsCString());
240 result.SetStatus(eReturnStatusFailed);
241 return false;
242 } else {
243 result.SetStatus(eReturnStatusSuccessFinishResult);
244 }
245
246 return result.Succeeded();
247 }
248
Jim Ingham5a988412012-06-08 21:56:10 +0000249private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000250 CommandOptions m_options;
Jim Ingham5a988412012-06-08 21:56:10 +0000251};
252
Jim Ingham5a988412012-06-08 21:56:10 +0000253// CommandObjectSettingsShow -- Show current values
Jim Ingham5a988412012-06-08 21:56:10 +0000254
Kate Stoneb9c1b512016-09-06 20:57:50 +0000255class CommandObjectSettingsShow : public CommandObjectParsed {
Jim Ingham5a988412012-06-08 21:56:10 +0000256public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000257 CommandObjectSettingsShow(CommandInterpreter &interpreter)
258 : CommandObjectParsed(interpreter, "settings show",
259 "Show matching debugger settings and their current "
260 "values. Defaults to showing all settings.",
261 nullptr) {
262 CommandArgumentEntry arg1;
263 CommandArgumentData var_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000264
Kate Stoneb9c1b512016-09-06 20:57:50 +0000265 // Define the first (and only) variant of this arg.
266 var_name_arg.arg_type = eArgTypeSettingVariableName;
267 var_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000268
Kate Stoneb9c1b512016-09-06 20:57:50 +0000269 // There is only one variant this argument could be; put it into the
270 // argument entry.
271 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000272
Kate Stoneb9c1b512016-09-06 20:57:50 +0000273 // Push the data for the first argument into the m_arguments vector.
274 m_arguments.push_back(arg1);
275 }
Jim Ingham5a988412012-06-08 21:56:10 +0000276
Kate Stoneb9c1b512016-09-06 20:57:50 +0000277 ~CommandObjectSettingsShow() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000278
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000279 int HandleArgumentCompletion(
280 CompletionRequest &request,
281 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000282 CommandCompletions::InvokeCommonCompletionCallbacks(
283 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000284 request, nullptr);
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000285 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000286 }
Jim Ingham5a988412012-06-08 21:56:10 +0000287
288protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000289 bool DoExecute(Args &args, CommandReturnObject &result) override {
290 result.SetStatus(eReturnStatusSuccessFinishResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000291
Zachary Turner97d2c402016-10-05 23:40:23 +0000292 if (!args.empty()) {
Zachary Turnerd6a24752016-11-22 17:10:15 +0000293 for (const auto &arg : args) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000294 Status error(GetDebugger().DumpPropertyValue(
Zachary Turnerd6a24752016-11-22 17:10:15 +0000295 &m_exe_ctx, result.GetOutputStream(), arg.ref,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000296 OptionValue::eDumpGroupValue));
297 if (error.Success()) {
298 result.GetOutputStream().EOL();
299 } else {
300 result.AppendError(error.AsCString());
301 result.SetStatus(eReturnStatusFailed);
Jim Ingham5a988412012-06-08 21:56:10 +0000302 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000303 }
304 } else {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000305 GetDebugger().DumpAllPropertyValues(&m_exe_ctx, result.GetOutputStream(),
306 OptionValue::eDumpGroupValue);
Jim Ingham5a988412012-06-08 21:56:10 +0000307 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000308
309 return result.Succeeded();
310 }
Jim Ingham5a988412012-06-08 21:56:10 +0000311};
312
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000313// CommandObjectSettingsWrite -- Write settings to file
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000314
315static constexpr OptionDefinition g_settings_write_options[] = {
316 // clang-format off
317 { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file into which to write the settings." },
318 { LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append to saved settings file if it exists."},
319 // clang-format on
320};
321
322class CommandObjectSettingsWrite : public CommandObjectParsed {
323public:
324 CommandObjectSettingsWrite(CommandInterpreter &interpreter)
325 : CommandObjectParsed(
326 interpreter, "settings export",
327 "Write matching debugger settings and their "
328 "current values to a file that can be read in with "
329 "\"settings read\". Defaults to writing all settings.",
330 nullptr),
331 m_options() {
332 CommandArgumentEntry arg1;
333 CommandArgumentData var_name_arg;
334
335 // Define the first (and only) variant of this arg.
336 var_name_arg.arg_type = eArgTypeSettingVariableName;
337 var_name_arg.arg_repetition = eArgRepeatOptional;
338
339 // There is only one variant this argument could be; put it into the
340 // argument entry.
341 arg1.push_back(var_name_arg);
342
343 // Push the data for the first argument into the m_arguments vector.
344 m_arguments.push_back(arg1);
345 }
346
347 ~CommandObjectSettingsWrite() override = default;
348
349 Options *GetOptions() override { return &m_options; }
350
351 class CommandOptions : public Options {
352 public:
353 CommandOptions() : Options() {}
354
355 ~CommandOptions() override = default;
356
357 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
358 ExecutionContext *execution_context) override {
359 Status error;
360 const int short_option = m_getopt_table[option_idx].val;
361
362 switch (short_option) {
363 case 'f':
364 m_filename.assign(option_arg);
365 break;
366 case 'a':
367 m_append = true;
368 break;
369 default:
370 error.SetErrorStringWithFormat("unrecognized option '%c'",
371 short_option);
372 break;
373 }
374
375 return error;
376 }
377
378 void OptionParsingStarting(ExecutionContext *execution_context) override {
379 m_filename.clear();
380 m_append = false;
381 }
382
383 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
384 return llvm::makeArrayRef(g_settings_write_options);
385 }
386
387 // Instance variables to hold the values for command options.
388 std::string m_filename;
389 bool m_append = false;
390 };
391
392protected:
393 bool DoExecute(Args &args, CommandReturnObject &result) override {
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000394 FileSpec file_spec(m_options.m_filename);
395 FileSystem::Instance().Resolve(file_spec);
396 std::string path(file_spec.GetPath());
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000397 uint32_t options = File::OpenOptions::eOpenOptionWrite |
398 File::OpenOptions::eOpenOptionCanCreate;
399 if (m_options.m_append)
400 options |= File::OpenOptions::eOpenOptionAppend;
401 else
402 options |= File::OpenOptions::eOpenOptionTruncate;
403
404 StreamFile out_file(path.c_str(), options,
405 lldb::eFilePermissionsFileDefault);
406
407 if (!out_file.GetFile().IsValid()) {
408 result.AppendErrorWithFormat("%s: unable to write to file", path.c_str());
409 result.SetStatus(eReturnStatusFailed);
410 return false;
411 }
412
413 // Exporting should not be context sensitive.
414 ExecutionContext clean_ctx;
415
416 if (args.empty()) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000417 GetDebugger().DumpAllPropertyValues(&clean_ctx, out_file,
418 OptionValue::eDumpGroupExport);
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000419 return result.Succeeded();
420 }
421
422 for (const auto &arg : args) {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000423 Status error(GetDebugger().DumpPropertyValue(
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000424 &clean_ctx, out_file, arg.ref, OptionValue::eDumpGroupExport));
425 if (!error.Success()) {
426 result.AppendError(error.AsCString());
427 result.SetStatus(eReturnStatusFailed);
428 }
429 }
430
431 return result.Succeeded();
432 }
433
434private:
435 CommandOptions m_options;
436};
437
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000438// CommandObjectSettingsRead -- Read settings from file
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000439
440static constexpr OptionDefinition g_settings_read_options[] = {
441 // clang-format off
442 {LLDB_OPT_SET_ALL, true, "file",'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file from which to read the breakpoints." },
443 // clang-format on
444};
445
446class CommandObjectSettingsRead : public CommandObjectParsed {
447public:
448 CommandObjectSettingsRead(CommandInterpreter &interpreter)
449 : CommandObjectParsed(
450 interpreter, "settings read",
451 "Read settings previously saved to a file with \"settings write\".",
452 nullptr),
453 m_options() {}
454
455 ~CommandObjectSettingsRead() override = default;
456
457 Options *GetOptions() override { return &m_options; }
458
459 class CommandOptions : public Options {
460 public:
461 CommandOptions() : Options() {}
462
463 ~CommandOptions() override = default;
464
465 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
466 ExecutionContext *execution_context) override {
467 Status error;
468 const int short_option = m_getopt_table[option_idx].val;
469
470 switch (short_option) {
471 case 'f':
472 m_filename.assign(option_arg);
473 break;
474 default:
475 error.SetErrorStringWithFormat("unrecognized option '%c'",
476 short_option);
477 break;
478 }
479
480 return error;
481 }
482
483 void OptionParsingStarting(ExecutionContext *execution_context) override {
484 m_filename.clear();
485 }
486
487 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
488 return llvm::makeArrayRef(g_settings_read_options);
489 }
490
491 // Instance variables to hold the values for command options.
492 std::string m_filename;
493 };
494
495protected:
496 bool DoExecute(Args &command, CommandReturnObject &result) override {
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000497 FileSpec file(m_options.m_filename);
498 FileSystem::Instance().Resolve(file);
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000499 ExecutionContext clean_ctx;
500 CommandInterpreterRunOptions options;
501 options.SetAddToHistory(false);
502 options.SetEchoCommands(false);
503 options.SetPrintResults(true);
Jonas Devliegherec0b48ab2019-05-08 01:23:47 +0000504 options.SetPrintErrors(true);
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +0000505 options.SetStopOnError(false);
506 m_interpreter.HandleCommandsFromFile(file, &clean_ctx, options, result);
507 return result.Succeeded();
508 }
509
510private:
511 CommandOptions m_options;
512};
513
Jim Ingham5a988412012-06-08 21:56:10 +0000514// CommandObjectSettingsList -- List settable variables
Jim Ingham5a988412012-06-08 21:56:10 +0000515
Kate Stoneb9c1b512016-09-06 20:57:50 +0000516class CommandObjectSettingsList : public CommandObjectParsed {
Kate Stone7428a182016-07-14 22:03:10 +0000517public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000518 CommandObjectSettingsList(CommandInterpreter &interpreter)
519 : CommandObjectParsed(interpreter, "settings list",
520 "List and describe matching debugger settings. "
521 "Defaults to all listing all settings.",
522 nullptr) {
523 CommandArgumentEntry arg;
524 CommandArgumentData var_name_arg;
525 CommandArgumentData prefix_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000526
Kate Stoneb9c1b512016-09-06 20:57:50 +0000527 // Define the first variant of this arg.
528 var_name_arg.arg_type = eArgTypeSettingVariableName;
529 var_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000530
Kate Stoneb9c1b512016-09-06 20:57:50 +0000531 // Define the second variant of this arg.
532 prefix_name_arg.arg_type = eArgTypeSettingPrefix;
533 prefix_name_arg.arg_repetition = eArgRepeatOptional;
Jim Ingham5a988412012-06-08 21:56:10 +0000534
Kate Stoneb9c1b512016-09-06 20:57:50 +0000535 arg.push_back(var_name_arg);
536 arg.push_back(prefix_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000537
Kate Stoneb9c1b512016-09-06 20:57:50 +0000538 // Push the data for the first argument into the m_arguments vector.
539 m_arguments.push_back(arg);
540 }
Jim Ingham5a988412012-06-08 21:56:10 +0000541
Kate Stoneb9c1b512016-09-06 20:57:50 +0000542 ~CommandObjectSettingsList() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000543
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000544 int HandleArgumentCompletion(
545 CompletionRequest &request,
546 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000547 CommandCompletions::InvokeCommonCompletionCallbacks(
548 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000549 request, nullptr);
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000550 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000551 }
Jim Ingham5a988412012-06-08 21:56:10 +0000552
553protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000554 bool DoExecute(Args &args, CommandReturnObject &result) override {
555 result.SetStatus(eReturnStatusSuccessFinishResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000556
Kate Stoneb9c1b512016-09-06 20:57:50 +0000557 const bool will_modify = false;
558 const size_t argc = args.GetArgumentCount();
559 if (argc > 0) {
560 const bool dump_qualified_name = true;
Jim Ingham5a988412012-06-08 21:56:10 +0000561
Zachary Turner97d2c402016-10-05 23:40:23 +0000562 // TODO: Convert to StringRef based enumeration. Requires converting
563 // GetPropertyAtPath first.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000564 for (size_t i = 0; i < argc; ++i) {
565 const char *property_path = args.GetArgumentAtIndex(i);
Greg Clayton67cc0632012-08-22 17:17:09 +0000566
Kate Stoneb9c1b512016-09-06 20:57:50 +0000567 const Property *property =
Jonas Devlieghere57179862019-04-27 06:19:42 +0000568 GetDebugger().GetValueProperties()->GetPropertyAtPath(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000569 &m_exe_ctx, will_modify, property_path);
570
571 if (property) {
572 property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
573 dump_qualified_name);
574 } else {
575 result.AppendErrorWithFormat("invalid property path '%s'",
576 property_path);
577 result.SetStatus(eReturnStatusFailed);
Jim Ingham5a988412012-06-08 21:56:10 +0000578 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000579 }
580 } else {
Jonas Devlieghere57179862019-04-27 06:19:42 +0000581 GetDebugger().DumpAllDescriptions(m_interpreter,
582 result.GetOutputStream());
Jim Ingham5a988412012-06-08 21:56:10 +0000583 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000584
585 return result.Succeeded();
586 }
Jim Ingham5a988412012-06-08 21:56:10 +0000587};
588
Jim Ingham5a988412012-06-08 21:56:10 +0000589// CommandObjectSettingsRemove
Jim Ingham5a988412012-06-08 21:56:10 +0000590
Kate Stoneb9c1b512016-09-06 20:57:50 +0000591class CommandObjectSettingsRemove : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000592public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000593 CommandObjectSettingsRemove(CommandInterpreter &interpreter)
594 : CommandObjectRaw(interpreter, "settings remove",
595 "Remove a value from a setting, specified by array "
Zachary Turnera4496982016-10-05 21:14:38 +0000596 "index or dictionary key.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000597 CommandArgumentEntry arg1;
598 CommandArgumentEntry arg2;
599 CommandArgumentData var_name_arg;
600 CommandArgumentData index_arg;
601 CommandArgumentData key_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000602
Kate Stoneb9c1b512016-09-06 20:57:50 +0000603 // Define the first (and only) variant of this arg.
604 var_name_arg.arg_type = eArgTypeSettingVariableName;
605 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000606
Kate Stoneb9c1b512016-09-06 20:57:50 +0000607 // There is only one variant this argument could be; put it into the
608 // argument entry.
609 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000610
Kate Stoneb9c1b512016-09-06 20:57:50 +0000611 // Define the first variant of this arg.
612 index_arg.arg_type = eArgTypeSettingIndex;
613 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000614
Kate Stoneb9c1b512016-09-06 20:57:50 +0000615 // Define the second variant of this arg.
616 key_arg.arg_type = eArgTypeSettingKey;
617 key_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000618
Kate Stoneb9c1b512016-09-06 20:57:50 +0000619 // Push both variants into this arg
620 arg2.push_back(index_arg);
621 arg2.push_back(key_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000622
Kate Stoneb9c1b512016-09-06 20:57:50 +0000623 // Push the data for the first argument into the m_arguments vector.
624 m_arguments.push_back(arg1);
625 m_arguments.push_back(arg2);
626 }
Jim Ingham5a988412012-06-08 21:56:10 +0000627
Kate Stoneb9c1b512016-09-06 20:57:50 +0000628 ~CommandObjectSettingsRemove() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000629
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000630 int HandleArgumentCompletion(
631 CompletionRequest &request,
632 OptionElementVector &opt_element_vector) override {
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000633 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000634 CommandCompletions::InvokeCommonCompletionCallbacks(
635 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000636 request, nullptr);
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000637 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000638 }
Jim Ingham5a988412012-06-08 21:56:10 +0000639
640protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000641 bool DoExecute(llvm::StringRef command,
642 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000643 result.SetStatus(eReturnStatusSuccessFinishNoResult);
644
645 Args cmd_args(command);
646
647 // Process possible options.
648 if (!ParseOptions(cmd_args, result))
649 return false;
650
651 const size_t argc = cmd_args.GetArgumentCount();
652 if (argc == 0) {
653 result.AppendError("'settings set' takes an array or dictionary item, or "
654 "an array followed by one or more indexes, or a "
655 "dictionary followed by one or more key names to "
656 "remove");
657 result.SetStatus(eReturnStatusFailed);
658 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000659 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000660
661 const char *var_name = cmd_args.GetArgumentAtIndex(0);
662 if ((var_name == nullptr) || (var_name[0] == '\0')) {
663 result.AppendError(
664 "'settings set' command requires a valid variable name");
665 result.SetStatus(eReturnStatusFailed);
666 return false;
667 }
668
669 // Split the raw command into var_name and value pair.
670 llvm::StringRef raw_str(command);
671 std::string var_value_string = raw_str.split(var_name).second.str();
672 const char *var_value_cstr =
673 Args::StripSpaces(var_value_string, true, true, false);
674
Jonas Devlieghere57179862019-04-27 06:19:42 +0000675 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000676 &m_exe_ctx, eVarSetOperationRemove, var_name, var_value_cstr));
677 if (error.Fail()) {
678 result.AppendError(error.AsCString());
679 result.SetStatus(eReturnStatusFailed);
680 return false;
681 }
682
683 return result.Succeeded();
684 }
Jim Ingham5a988412012-06-08 21:56:10 +0000685};
686
Jim Ingham5a988412012-06-08 21:56:10 +0000687// CommandObjectSettingsReplace
Jim Ingham5a988412012-06-08 21:56:10 +0000688
Kate Stoneb9c1b512016-09-06 20:57:50 +0000689class CommandObjectSettingsReplace : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000690public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000691 CommandObjectSettingsReplace(CommandInterpreter &interpreter)
692 : CommandObjectRaw(interpreter, "settings replace",
693 "Replace the debugger setting value specified by "
Zachary Turnera4496982016-10-05 21:14:38 +0000694 "array index or dictionary key.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000695 CommandArgumentEntry arg1;
696 CommandArgumentEntry arg2;
697 CommandArgumentEntry arg3;
698 CommandArgumentData var_name_arg;
699 CommandArgumentData index_arg;
700 CommandArgumentData key_arg;
701 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000702
Kate Stoneb9c1b512016-09-06 20:57:50 +0000703 // Define the first (and only) variant of this arg.
704 var_name_arg.arg_type = eArgTypeSettingVariableName;
705 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000706
Kate Stoneb9c1b512016-09-06 20:57:50 +0000707 // There is only one variant this argument could be; put it into the
708 // argument entry.
709 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000710
Kate Stoneb9c1b512016-09-06 20:57:50 +0000711 // Define the first (variant of this arg.
712 index_arg.arg_type = eArgTypeSettingIndex;
713 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000714
Kate Stoneb9c1b512016-09-06 20:57:50 +0000715 // Define the second (variant of this arg.
716 key_arg.arg_type = eArgTypeSettingKey;
717 key_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000718
Kate Stoneb9c1b512016-09-06 20:57:50 +0000719 // Put both variants into this arg
720 arg2.push_back(index_arg);
721 arg2.push_back(key_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000722
Kate Stoneb9c1b512016-09-06 20:57:50 +0000723 // Define the first (and only) variant of this arg.
724 value_arg.arg_type = eArgTypeValue;
725 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000726
Kate Stoneb9c1b512016-09-06 20:57:50 +0000727 // There is only one variant this argument could be; put it into the
728 // argument entry.
729 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000730
Kate Stoneb9c1b512016-09-06 20:57:50 +0000731 // Push the data for the first argument into the m_arguments vector.
732 m_arguments.push_back(arg1);
733 m_arguments.push_back(arg2);
734 m_arguments.push_back(arg3);
735 }
Jim Ingham5a988412012-06-08 21:56:10 +0000736
Kate Stoneb9c1b512016-09-06 20:57:50 +0000737 ~CommandObjectSettingsReplace() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000738
Kate Stoneb9c1b512016-09-06 20:57:50 +0000739 // Overrides base class's behavior where WantsCompletion =
740 // !WantsRawCommandString.
741 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000742
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000743 int HandleArgumentCompletion(
744 CompletionRequest &request,
745 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000746 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000747 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000748 CommandCompletions::InvokeCommonCompletionCallbacks(
749 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000750 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +0000751
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000752 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000753 }
Jim Ingham5a988412012-06-08 21:56:10 +0000754
755protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000756 bool DoExecute(llvm::StringRef command,
757 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000758 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000759
Kate Stoneb9c1b512016-09-06 20:57:50 +0000760 Args cmd_args(command);
761 const char *var_name = cmd_args.GetArgumentAtIndex(0);
762 if ((var_name == nullptr) || (var_name[0] == '\0')) {
763 result.AppendError("'settings replace' command requires a valid variable "
764 "name; No value supplied");
765 result.SetStatus(eReturnStatusFailed);
766 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000767 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000768
769 // Split the raw command into var_name, index_value, and value triple.
770 llvm::StringRef raw_str(command);
771 std::string var_value_string = raw_str.split(var_name).second.str();
772 const char *var_value_cstr =
773 Args::StripSpaces(var_value_string, true, true, false);
774
Jonas Devlieghere57179862019-04-27 06:19:42 +0000775 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000776 &m_exe_ctx, eVarSetOperationReplace, var_name, var_value_cstr));
777 if (error.Fail()) {
778 result.AppendError(error.AsCString());
779 result.SetStatus(eReturnStatusFailed);
780 return false;
781 } else {
782 result.SetStatus(eReturnStatusSuccessFinishNoResult);
783 }
784
785 return result.Succeeded();
786 }
Jim Ingham5a988412012-06-08 21:56:10 +0000787};
788
Jim Ingham5a988412012-06-08 21:56:10 +0000789// CommandObjectSettingsInsertBefore
Jim Ingham5a988412012-06-08 21:56:10 +0000790
Kate Stoneb9c1b512016-09-06 20:57:50 +0000791class CommandObjectSettingsInsertBefore : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000792public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000793 CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
794 : CommandObjectRaw(interpreter, "settings insert-before",
795 "Insert one or more values into an debugger array "
796 "setting immediately before the specified element "
Zachary Turnera4496982016-10-05 21:14:38 +0000797 "index.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000798 CommandArgumentEntry arg1;
799 CommandArgumentEntry arg2;
800 CommandArgumentEntry arg3;
801 CommandArgumentData var_name_arg;
802 CommandArgumentData index_arg;
803 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000804
Kate Stoneb9c1b512016-09-06 20:57:50 +0000805 // Define the first (and only) variant of this arg.
806 var_name_arg.arg_type = eArgTypeSettingVariableName;
807 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000808
Kate Stoneb9c1b512016-09-06 20:57:50 +0000809 // There is only one variant this argument could be; put it into the
810 // argument entry.
811 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000812
Kate Stoneb9c1b512016-09-06 20:57:50 +0000813 // Define the first (variant of this arg.
814 index_arg.arg_type = eArgTypeSettingIndex;
815 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000816
Kate Stoneb9c1b512016-09-06 20:57:50 +0000817 // There is only one variant this argument could be; put it into the
818 // argument entry.
819 arg2.push_back(index_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000820
Kate Stoneb9c1b512016-09-06 20:57:50 +0000821 // Define the first (and only) variant of this arg.
822 value_arg.arg_type = eArgTypeValue;
823 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000824
Kate Stoneb9c1b512016-09-06 20:57:50 +0000825 // There is only one variant this argument could be; put it into the
826 // argument entry.
827 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000828
Kate Stoneb9c1b512016-09-06 20:57:50 +0000829 // Push the data for the first argument into the m_arguments vector.
830 m_arguments.push_back(arg1);
831 m_arguments.push_back(arg2);
832 m_arguments.push_back(arg3);
833 }
Jim Ingham5a988412012-06-08 21:56:10 +0000834
Kate Stoneb9c1b512016-09-06 20:57:50 +0000835 ~CommandObjectSettingsInsertBefore() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000836
Kate Stoneb9c1b512016-09-06 20:57:50 +0000837 // Overrides base class's behavior where WantsCompletion =
838 // !WantsRawCommandString.
839 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000840
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000841 int HandleArgumentCompletion(
842 CompletionRequest &request,
843 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000844 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000845 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000846 CommandCompletions::InvokeCommonCompletionCallbacks(
847 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000848 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +0000849
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000850 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000851 }
Jim Ingham5a988412012-06-08 21:56:10 +0000852
853protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000854 bool DoExecute(llvm::StringRef command,
855 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000856 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000857
Kate Stoneb9c1b512016-09-06 20:57:50 +0000858 Args cmd_args(command);
859 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +0000860
Kate Stoneb9c1b512016-09-06 20:57:50 +0000861 if (argc < 3) {
862 result.AppendError("'settings insert-before' takes more arguments");
863 result.SetStatus(eReturnStatusFailed);
864 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000865 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000866
867 const char *var_name = cmd_args.GetArgumentAtIndex(0);
868 if ((var_name == nullptr) || (var_name[0] == '\0')) {
869 result.AppendError("'settings insert-before' command requires a valid "
870 "variable name; No value supplied");
871 result.SetStatus(eReturnStatusFailed);
872 return false;
873 }
874
875 // Split the raw command into var_name, index_value, and value triple.
876 llvm::StringRef raw_str(command);
877 std::string var_value_string = raw_str.split(var_name).second.str();
878 const char *var_value_cstr =
879 Args::StripSpaces(var_value_string, true, true, false);
880
Jonas Devlieghere57179862019-04-27 06:19:42 +0000881 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000882 &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value_cstr));
883 if (error.Fail()) {
884 result.AppendError(error.AsCString());
885 result.SetStatus(eReturnStatusFailed);
886 return false;
887 }
888
889 return result.Succeeded();
890 }
Jim Ingham5a988412012-06-08 21:56:10 +0000891};
892
Jim Ingham5a988412012-06-08 21:56:10 +0000893// CommandObjectSettingInsertAfter
Jim Ingham5a988412012-06-08 21:56:10 +0000894
Kate Stoneb9c1b512016-09-06 20:57:50 +0000895class CommandObjectSettingsInsertAfter : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000896public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000897 CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
898 : CommandObjectRaw(interpreter, "settings insert-after",
899 "Insert one or more values into a debugger array "
Zachary Turnera4496982016-10-05 21:14:38 +0000900 "settings after the specified element index.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000901 CommandArgumentEntry arg1;
902 CommandArgumentEntry arg2;
903 CommandArgumentEntry arg3;
904 CommandArgumentData var_name_arg;
905 CommandArgumentData index_arg;
906 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +0000907
Kate Stoneb9c1b512016-09-06 20:57:50 +0000908 // Define the first (and only) variant of this arg.
909 var_name_arg.arg_type = eArgTypeSettingVariableName;
910 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000911
Kate Stoneb9c1b512016-09-06 20:57:50 +0000912 // There is only one variant this argument could be; put it into the
913 // argument entry.
914 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000915
Kate Stoneb9c1b512016-09-06 20:57:50 +0000916 // Define the first (variant of this arg.
917 index_arg.arg_type = eArgTypeSettingIndex;
918 index_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000919
Kate Stoneb9c1b512016-09-06 20:57:50 +0000920 // There is only one variant this argument could be; put it into the
921 // argument entry.
922 arg2.push_back(index_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000923
Kate Stoneb9c1b512016-09-06 20:57:50 +0000924 // Define the first (and only) variant of this arg.
925 value_arg.arg_type = eArgTypeValue;
926 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +0000927
Kate Stoneb9c1b512016-09-06 20:57:50 +0000928 // There is only one variant this argument could be; put it into the
929 // argument entry.
930 arg3.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +0000931
Kate Stoneb9c1b512016-09-06 20:57:50 +0000932 // Push the data for the first argument into the m_arguments vector.
933 m_arguments.push_back(arg1);
934 m_arguments.push_back(arg2);
935 m_arguments.push_back(arg3);
936 }
Jim Ingham5a988412012-06-08 21:56:10 +0000937
Kate Stoneb9c1b512016-09-06 20:57:50 +0000938 ~CommandObjectSettingsInsertAfter() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +0000939
Kate Stoneb9c1b512016-09-06 20:57:50 +0000940 // Overrides base class's behavior where WantsCompletion =
941 // !WantsRawCommandString.
942 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +0000943
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000944 int HandleArgumentCompletion(
945 CompletionRequest &request,
946 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000947 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +0000948 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000949 CommandCompletions::InvokeCommonCompletionCallbacks(
950 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +0000951 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +0000952
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +0000953 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000954 }
955
Jim Ingham5a988412012-06-08 21:56:10 +0000956protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +0000957 bool DoExecute(llvm::StringRef command,
958 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000959 result.SetStatus(eReturnStatusSuccessFinishNoResult);
Jim Ingham5a988412012-06-08 21:56:10 +0000960
Kate Stoneb9c1b512016-09-06 20:57:50 +0000961 Args cmd_args(command);
962 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +0000963
Kate Stoneb9c1b512016-09-06 20:57:50 +0000964 if (argc < 3) {
965 result.AppendError("'settings insert-after' takes more arguments");
966 result.SetStatus(eReturnStatusFailed);
967 return false;
Jim Ingham5a988412012-06-08 21:56:10 +0000968 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000969
970 const char *var_name = cmd_args.GetArgumentAtIndex(0);
971 if ((var_name == nullptr) || (var_name[0] == '\0')) {
972 result.AppendError("'settings insert-after' command requires a valid "
973 "variable name; No value supplied");
974 result.SetStatus(eReturnStatusFailed);
975 return false;
976 }
977
978 // Split the raw command into var_name, index_value, and value triple.
979 llvm::StringRef raw_str(command);
980 std::string var_value_string = raw_str.split(var_name).second.str();
981 const char *var_value_cstr =
982 Args::StripSpaces(var_value_string, true, true, false);
983
Jonas Devlieghere57179862019-04-27 06:19:42 +0000984 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000985 &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value_cstr));
986 if (error.Fail()) {
987 result.AppendError(error.AsCString());
988 result.SetStatus(eReturnStatusFailed);
989 return false;
990 }
991
992 return result.Succeeded();
993 }
Jim Ingham5a988412012-06-08 21:56:10 +0000994};
995
Jim Ingham5a988412012-06-08 21:56:10 +0000996// CommandObjectSettingsAppend
Jim Ingham5a988412012-06-08 21:56:10 +0000997
Kate Stoneb9c1b512016-09-06 20:57:50 +0000998class CommandObjectSettingsAppend : public CommandObjectRaw {
Jim Ingham5a988412012-06-08 21:56:10 +0000999public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001000 CommandObjectSettingsAppend(CommandInterpreter &interpreter)
1001 : CommandObjectRaw(interpreter, "settings append",
1002 "Append one or more values to a debugger array, "
Zachary Turnera4496982016-10-05 21:14:38 +00001003 "dictionary, or string setting.") {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001004 CommandArgumentEntry arg1;
1005 CommandArgumentEntry arg2;
1006 CommandArgumentData var_name_arg;
1007 CommandArgumentData value_arg;
Jim Ingham5a988412012-06-08 21:56:10 +00001008
Kate Stoneb9c1b512016-09-06 20:57:50 +00001009 // Define the first (and only) variant of this arg.
1010 var_name_arg.arg_type = eArgTypeSettingVariableName;
1011 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +00001012
Kate Stoneb9c1b512016-09-06 20:57:50 +00001013 // There is only one variant this argument could be; put it into the
1014 // argument entry.
1015 arg1.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001016
Kate Stoneb9c1b512016-09-06 20:57:50 +00001017 // Define the first (and only) variant of this arg.
1018 value_arg.arg_type = eArgTypeValue;
1019 value_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +00001020
Kate Stoneb9c1b512016-09-06 20:57:50 +00001021 // There is only one variant this argument could be; put it into the
1022 // argument entry.
1023 arg2.push_back(value_arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001024
Kate Stoneb9c1b512016-09-06 20:57:50 +00001025 // Push the data for the first argument into the m_arguments vector.
1026 m_arguments.push_back(arg1);
1027 m_arguments.push_back(arg2);
1028 }
Jim Ingham5a988412012-06-08 21:56:10 +00001029
Kate Stoneb9c1b512016-09-06 20:57:50 +00001030 ~CommandObjectSettingsAppend() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001031
Kate Stoneb9c1b512016-09-06 20:57:50 +00001032 // Overrides base class's behavior where WantsCompletion =
1033 // !WantsRawCommandString.
1034 bool WantsCompletion() override { return true; }
Jim Ingham5a988412012-06-08 21:56:10 +00001035
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001036 int HandleArgumentCompletion(
1037 CompletionRequest &request,
1038 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001039 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001040 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001041 CommandCompletions::InvokeCommonCompletionCallbacks(
1042 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +00001043 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +00001044
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +00001045 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001046 }
Jim Ingham5a988412012-06-08 21:56:10 +00001047
1048protected:
Raphael Isemann4d51a902018-07-12 22:28:52 +00001049 bool DoExecute(llvm::StringRef command,
1050 CommandReturnObject &result) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001051 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1052 Args cmd_args(command);
1053 const size_t argc = cmd_args.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +00001054
Kate Stoneb9c1b512016-09-06 20:57:50 +00001055 if (argc < 2) {
1056 result.AppendError("'settings append' takes more arguments");
1057 result.SetStatus(eReturnStatusFailed);
1058 return false;
Jim Ingham5a988412012-06-08 21:56:10 +00001059 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001060
1061 const char *var_name = cmd_args.GetArgumentAtIndex(0);
1062 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1063 result.AppendError("'settings append' command requires a valid variable "
1064 "name; No value supplied");
1065 result.SetStatus(eReturnStatusFailed);
1066 return false;
1067 }
1068
Adrian Prantl05097242018-04-30 16:49:04 +00001069 // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
1070 // character string later on.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001071
1072 // Split the raw command into var_name and value pair.
1073 llvm::StringRef raw_str(command);
1074 std::string var_value_string = raw_str.split(var_name).second.str();
1075 const char *var_value_cstr =
1076 Args::StripSpaces(var_value_string, true, true, false);
1077
Jonas Devlieghere57179862019-04-27 06:19:42 +00001078 Status error(GetDebugger().SetPropertyValue(
Kate Stoneb9c1b512016-09-06 20:57:50 +00001079 &m_exe_ctx, eVarSetOperationAppend, var_name, var_value_cstr));
1080 if (error.Fail()) {
1081 result.AppendError(error.AsCString());
1082 result.SetStatus(eReturnStatusFailed);
1083 return false;
1084 }
1085
1086 return result.Succeeded();
1087 }
Jim Ingham5a988412012-06-08 21:56:10 +00001088};
1089
Jim Ingham5a988412012-06-08 21:56:10 +00001090// CommandObjectSettingsClear
Jim Ingham5a988412012-06-08 21:56:10 +00001091
Kate Stoneb9c1b512016-09-06 20:57:50 +00001092class CommandObjectSettingsClear : public CommandObjectParsed {
Jim Ingham5a988412012-06-08 21:56:10 +00001093public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001094 CommandObjectSettingsClear(CommandInterpreter &interpreter)
1095 : CommandObjectParsed(
1096 interpreter, "settings clear",
1097 "Clear a debugger setting array, dictionary, or string.", nullptr) {
1098 CommandArgumentEntry arg;
1099 CommandArgumentData var_name_arg;
Jim Ingham5a988412012-06-08 21:56:10 +00001100
Kate Stoneb9c1b512016-09-06 20:57:50 +00001101 // Define the first (and only) variant of this arg.
1102 var_name_arg.arg_type = eArgTypeSettingVariableName;
1103 var_name_arg.arg_repetition = eArgRepeatPlain;
Jim Ingham5a988412012-06-08 21:56:10 +00001104
Kate Stoneb9c1b512016-09-06 20:57:50 +00001105 // There is only one variant this argument could be; put it into the
1106 // argument entry.
1107 arg.push_back(var_name_arg);
Jim Ingham5a988412012-06-08 21:56:10 +00001108
Kate Stoneb9c1b512016-09-06 20:57:50 +00001109 // Push the data for the first argument into the m_arguments vector.
1110 m_arguments.push_back(arg);
1111 }
Jim Ingham5a988412012-06-08 21:56:10 +00001112
Kate Stoneb9c1b512016-09-06 20:57:50 +00001113 ~CommandObjectSettingsClear() override = default;
Jim Ingham5a988412012-06-08 21:56:10 +00001114
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001115 int HandleArgumentCompletion(
1116 CompletionRequest &request,
1117 OptionElementVector &opt_element_vector) override {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001118 // Attempting to complete variable name
Raphael Isemann2443bbd2018-07-02 21:29:56 +00001119 if (request.GetCursorIndex() < 2)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001120 CommandCompletions::InvokeCommonCompletionCallbacks(
1121 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
Raphael Isemanna2e76c02018-07-13 18:28:14 +00001122 request, nullptr);
Jim Ingham5a988412012-06-08 21:56:10 +00001123
Raphael Isemann1a6d7ab2018-07-27 18:42:46 +00001124 return request.GetNumberOfMatches();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001125 }
Jim Ingham5a988412012-06-08 21:56:10 +00001126
1127protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001128 bool DoExecute(Args &command, CommandReturnObject &result) override {
1129 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1130 const size_t argc = command.GetArgumentCount();
Jim Ingham5a988412012-06-08 21:56:10 +00001131
Kate Stoneb9c1b512016-09-06 20:57:50 +00001132 if (argc != 1) {
1133 result.AppendError("'settings clear' takes exactly one argument");
1134 result.SetStatus(eReturnStatusFailed);
1135 return false;
Jim Ingham5a988412012-06-08 21:56:10 +00001136 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001137
1138 const char *var_name = command.GetArgumentAtIndex(0);
1139 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1140 result.AppendError("'settings clear' command requires a valid variable "
1141 "name; No value supplied");
1142 result.SetStatus(eReturnStatusFailed);
1143 return false;
1144 }
1145
Jonas Devlieghere57179862019-04-27 06:19:42 +00001146 Status error(GetDebugger().SetPropertyValue(
Zachary Turner31d97a52016-11-17 18:08:12 +00001147 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001148 if (error.Fail()) {
1149 result.AppendError(error.AsCString());
1150 result.SetStatus(eReturnStatusFailed);
1151 return false;
1152 }
1153
1154 return result.Succeeded();
1155 }
Jim Ingham5a988412012-06-08 21:56:10 +00001156};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001157
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001158// CommandObjectMultiwordSettings
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001159
Kate Stoneb9c1b512016-09-06 20:57:50 +00001160CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
1161 CommandInterpreter &interpreter)
1162 : CommandObjectMultiword(interpreter, "settings",
1163 "Commands for managing LLDB settings.",
1164 "settings <subcommand> [<command-options>]") {
1165 LoadSubCommand("set",
1166 CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
1167 LoadSubCommand("show",
1168 CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
1169 LoadSubCommand("list",
1170 CommandObjectSP(new CommandObjectSettingsList(interpreter)));
1171 LoadSubCommand("remove",
1172 CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
1173 LoadSubCommand("replace", CommandObjectSP(
1174 new CommandObjectSettingsReplace(interpreter)));
1175 LoadSubCommand(
1176 "insert-before",
1177 CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
1178 LoadSubCommand(
1179 "insert-after",
1180 CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
1181 LoadSubCommand("append",
1182 CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
1183 LoadSubCommand("clear",
1184 CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
Jonas Devlieghereb76e25a2018-10-26 00:00:17 +00001185 LoadSubCommand("write",
1186 CommandObjectSP(new CommandObjectSettingsWrite(interpreter)));
1187 LoadSubCommand("read",
1188 CommandObjectSP(new CommandObjectSettingsRead(interpreter)));
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001189}
1190
Eugene Zelenko3f18ea02016-02-24 02:05:55 +00001191CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default;