[PowerPC] Collect some CallLowering arguments into a struct. [NFC]
[llvm-project.git] / lldb / source / Commands / CommandObjectSettings.cpp
blob95f79f45e22bfb5767df1c840bdcedc233b27af0
1 //===-- CommandObjectSettings.cpp -------------------------------*- C++ -*-===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
9 #include "CommandObjectSettings.h"
11 #include "llvm/ADT/StringRef.h"
13 #include "lldb/Host/OptionParser.h"
14 #include "lldb/Interpreter/CommandCompletions.h"
15 #include "lldb/Interpreter/CommandInterpreter.h"
16 #include "lldb/Interpreter/CommandReturnObject.h"
17 #include "lldb/Interpreter/OptionValueProperties.h"
19 using namespace lldb;
20 using namespace lldb_private;
22 // CommandObjectSettingsSet
23 #define LLDB_OPTIONS_settings_set
24 #include "CommandOptions.inc"
26 class CommandObjectSettingsSet : public CommandObjectRaw {
27 public:
28 CommandObjectSettingsSet(CommandInterpreter &interpreter)
29 : CommandObjectRaw(interpreter, "settings set",
30 "Set the value of the specified debugger setting."),
31 m_options() {
32 CommandArgumentEntry arg1;
33 CommandArgumentEntry arg2;
34 CommandArgumentData var_name_arg;
35 CommandArgumentData value_arg;
37 // Define the first (and only) variant of this arg.
38 var_name_arg.arg_type = eArgTypeSettingVariableName;
39 var_name_arg.arg_repetition = eArgRepeatPlain;
41 // There is only one variant this argument could be; put it into the
42 // argument entry.
43 arg1.push_back(var_name_arg);
45 // Define the first (and only) variant of this arg.
46 value_arg.arg_type = eArgTypeValue;
47 value_arg.arg_repetition = eArgRepeatPlain;
49 // There is only one variant this argument could be; put it into the
50 // argument entry.
51 arg2.push_back(value_arg);
53 // Push the data for the first argument into the m_arguments vector.
54 m_arguments.push_back(arg1);
55 m_arguments.push_back(arg2);
57 SetHelpLong(
58 "\nWhen setting a dictionary or array variable, you can set multiple entries \
59 at once by giving the values to the set command. For example:"
60 R"(
62 (lldb) settings set target.run-args value1 value2 value3
63 (lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345
65 (lldb) settings show target.run-args
66 [0]: 'value1'
67 [1]: 'value2'
68 [3]: 'value3'
69 (lldb) settings show target.env-vars
70 'MYPATH=~/.:/usr/bin'
71 'SOME_ENV_VAR=12345'
74 "Warning: The 'set' command re-sets the entire array or dictionary. If you \
75 just want to add, remove or update individual values (or add something to \
76 the end), use one of the other settings sub-commands: append, replace, \
77 insert-before or insert-after.");
80 ~CommandObjectSettingsSet() override = default;
82 // Overrides base class's behavior where WantsCompletion =
83 // !WantsRawCommandString.
84 bool WantsCompletion() override { return true; }
86 Options *GetOptions() override { return &m_options; }
88 class CommandOptions : public Options {
89 public:
90 CommandOptions() : Options(), m_global(false) {}
92 ~CommandOptions() override = default;
94 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
95 ExecutionContext *execution_context) override {
96 Status error;
97 const int short_option = m_getopt_table[option_idx].val;
99 switch (short_option) {
100 case 'f':
101 m_force = true;
102 break;
103 case 'g':
104 m_global = true;
105 break;
106 default:
107 llvm_unreachable("Unimplemented option");
110 return error;
113 void OptionParsingStarting(ExecutionContext *execution_context) override {
114 m_global = false;
115 m_force = false;
118 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
119 return llvm::makeArrayRef(g_settings_set_options);
122 // Instance variables to hold the values for command options.
123 bool m_global;
124 bool m_force;
127 void
128 HandleArgumentCompletion(CompletionRequest &request,
129 OptionElementVector &opt_element_vector) override {
131 const size_t argc = request.GetParsedLine().GetArgumentCount();
132 const char *arg = nullptr;
133 size_t setting_var_idx;
134 for (setting_var_idx = 0; setting_var_idx < argc; ++setting_var_idx) {
135 arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
136 if (arg && arg[0] != '-')
137 break; // We found our setting variable name index
139 if (request.GetCursorIndex() == setting_var_idx) {
140 // Attempting to complete setting variable name
141 CommandCompletions::InvokeCommonCompletionCallbacks(
142 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
143 request, nullptr);
144 return;
146 arg = request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
148 if (!arg)
149 return;
151 // Complete option name
152 if (arg[0] != '-')
153 return;
155 // Complete setting value
156 const char *setting_var_name =
157 request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
158 Status error;
159 lldb::OptionValueSP value_sp(GetDebugger().GetPropertyValue(
160 &m_exe_ctx, setting_var_name, false, error));
161 if (!value_sp)
162 return;
163 value_sp->AutoComplete(m_interpreter, request);
166 protected:
167 bool DoExecute(llvm::StringRef command,
168 CommandReturnObject &result) override {
169 Args cmd_args(command);
171 // Process possible options.
172 if (!ParseOptions(cmd_args, result))
173 return false;
175 const size_t min_argc = m_options.m_force ? 1 : 2;
176 const size_t argc = cmd_args.GetArgumentCount();
178 if ((argc < min_argc) && (!m_options.m_global)) {
179 result.AppendError("'settings set' takes more arguments");
180 result.SetStatus(eReturnStatusFailed);
181 return false;
184 const char *var_name = cmd_args.GetArgumentAtIndex(0);
185 if ((var_name == nullptr) || (var_name[0] == '\0')) {
186 result.AppendError(
187 "'settings set' command requires a valid variable name");
188 result.SetStatus(eReturnStatusFailed);
189 return false;
192 // A missing value corresponds to clearing the setting when "force" is
193 // specified.
194 if (argc == 1 && m_options.m_force) {
195 Status error(GetDebugger().SetPropertyValue(
196 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
197 if (error.Fail()) {
198 result.AppendError(error.AsCString());
199 result.SetStatus(eReturnStatusFailed);
200 return false;
202 return result.Succeeded();
205 // Split the raw command into var_name and value pair.
206 llvm::StringRef var_value(command);
207 var_value = var_value.split(var_name).second.ltrim();
209 Status error;
210 if (m_options.m_global)
211 error = GetDebugger().SetPropertyValue(nullptr, eVarSetOperationAssign,
212 var_name, var_value);
214 if (error.Success()) {
215 // FIXME this is the same issue as the one in commands script import
216 // we could be setting target.load-script-from-symbol-file which would
217 // cause Python scripts to be loaded, which could run LLDB commands (e.g.
218 // settings set target.process.python-os-plugin-path) and cause a crash
219 // if we did not clear the command's exe_ctx first
220 ExecutionContext exe_ctx(m_exe_ctx);
221 m_exe_ctx.Clear();
222 error = GetDebugger().SetPropertyValue(&exe_ctx, eVarSetOperationAssign,
223 var_name, var_value);
226 if (error.Fail()) {
227 result.AppendError(error.AsCString());
228 result.SetStatus(eReturnStatusFailed);
229 return false;
230 } else {
231 result.SetStatus(eReturnStatusSuccessFinishResult);
234 return result.Succeeded();
237 private:
238 CommandOptions m_options;
241 // CommandObjectSettingsShow -- Show current values
243 class CommandObjectSettingsShow : public CommandObjectParsed {
244 public:
245 CommandObjectSettingsShow(CommandInterpreter &interpreter)
246 : CommandObjectParsed(interpreter, "settings show",
247 "Show matching debugger settings and their current "
248 "values. Defaults to showing all settings.",
249 nullptr) {
250 CommandArgumentEntry arg1;
251 CommandArgumentData var_name_arg;
253 // Define the first (and only) variant of this arg.
254 var_name_arg.arg_type = eArgTypeSettingVariableName;
255 var_name_arg.arg_repetition = eArgRepeatOptional;
257 // There is only one variant this argument could be; put it into the
258 // argument entry.
259 arg1.push_back(var_name_arg);
261 // Push the data for the first argument into the m_arguments vector.
262 m_arguments.push_back(arg1);
265 ~CommandObjectSettingsShow() override = default;
267 void
268 HandleArgumentCompletion(CompletionRequest &request,
269 OptionElementVector &opt_element_vector) override {
270 CommandCompletions::InvokeCommonCompletionCallbacks(
271 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
272 request, nullptr);
275 protected:
276 bool DoExecute(Args &args, CommandReturnObject &result) override {
277 result.SetStatus(eReturnStatusSuccessFinishResult);
279 if (!args.empty()) {
280 for (const auto &arg : args) {
281 Status error(GetDebugger().DumpPropertyValue(
282 &m_exe_ctx, result.GetOutputStream(), arg.ref(),
283 OptionValue::eDumpGroupValue));
284 if (error.Success()) {
285 result.GetOutputStream().EOL();
286 } else {
287 result.AppendError(error.AsCString());
288 result.SetStatus(eReturnStatusFailed);
291 } else {
292 GetDebugger().DumpAllPropertyValues(&m_exe_ctx, result.GetOutputStream(),
293 OptionValue::eDumpGroupValue);
296 return result.Succeeded();
300 // CommandObjectSettingsWrite -- Write settings to file
301 #define LLDB_OPTIONS_settings_write
302 #include "CommandOptions.inc"
304 class CommandObjectSettingsWrite : public CommandObjectParsed {
305 public:
306 CommandObjectSettingsWrite(CommandInterpreter &interpreter)
307 : CommandObjectParsed(
308 interpreter, "settings export",
309 "Write matching debugger settings and their "
310 "current values to a file that can be read in with "
311 "\"settings read\". Defaults to writing all settings.",
312 nullptr),
313 m_options() {
314 CommandArgumentEntry arg1;
315 CommandArgumentData var_name_arg;
317 // Define the first (and only) variant of this arg.
318 var_name_arg.arg_type = eArgTypeSettingVariableName;
319 var_name_arg.arg_repetition = eArgRepeatOptional;
321 // There is only one variant this argument could be; put it into the
322 // argument entry.
323 arg1.push_back(var_name_arg);
325 // Push the data for the first argument into the m_arguments vector.
326 m_arguments.push_back(arg1);
329 ~CommandObjectSettingsWrite() override = default;
331 Options *GetOptions() override { return &m_options; }
333 class CommandOptions : public Options {
334 public:
335 CommandOptions() : Options() {}
337 ~CommandOptions() override = default;
339 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
340 ExecutionContext *execution_context) override {
341 Status error;
342 const int short_option = m_getopt_table[option_idx].val;
344 switch (short_option) {
345 case 'f':
346 m_filename.assign(option_arg);
347 break;
348 case 'a':
349 m_append = true;
350 break;
351 default:
352 llvm_unreachable("Unimplemented option");
355 return error;
358 void OptionParsingStarting(ExecutionContext *execution_context) override {
359 m_filename.clear();
360 m_append = false;
363 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
364 return llvm::makeArrayRef(g_settings_write_options);
367 // Instance variables to hold the values for command options.
368 std::string m_filename;
369 bool m_append = false;
372 protected:
373 bool DoExecute(Args &args, CommandReturnObject &result) override {
374 FileSpec file_spec(m_options.m_filename);
375 FileSystem::Instance().Resolve(file_spec);
376 std::string path(file_spec.GetPath());
377 auto options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
378 if (m_options.m_append)
379 options |= File::eOpenOptionAppend;
380 else
381 options |= File::eOpenOptionTruncate;
383 StreamFile out_file(path.c_str(), options,
384 lldb::eFilePermissionsFileDefault);
386 if (!out_file.GetFile().IsValid()) {
387 result.AppendErrorWithFormat("%s: unable to write to file", path.c_str());
388 result.SetStatus(eReturnStatusFailed);
389 return false;
392 // Exporting should not be context sensitive.
393 ExecutionContext clean_ctx;
395 if (args.empty()) {
396 GetDebugger().DumpAllPropertyValues(&clean_ctx, out_file,
397 OptionValue::eDumpGroupExport);
398 return result.Succeeded();
401 for (const auto &arg : args) {
402 Status error(GetDebugger().DumpPropertyValue(
403 &clean_ctx, out_file, arg.ref(), OptionValue::eDumpGroupExport));
404 if (!error.Success()) {
405 result.AppendError(error.AsCString());
406 result.SetStatus(eReturnStatusFailed);
410 return result.Succeeded();
413 private:
414 CommandOptions m_options;
417 // CommandObjectSettingsRead -- Read settings from file
418 #define LLDB_OPTIONS_settings_read
419 #include "CommandOptions.inc"
421 class CommandObjectSettingsRead : public CommandObjectParsed {
422 public:
423 CommandObjectSettingsRead(CommandInterpreter &interpreter)
424 : CommandObjectParsed(
425 interpreter, "settings read",
426 "Read settings previously saved to a file with \"settings write\".",
427 nullptr),
428 m_options() {}
430 ~CommandObjectSettingsRead() override = default;
432 Options *GetOptions() override { return &m_options; }
434 class CommandOptions : public Options {
435 public:
436 CommandOptions() : Options() {}
438 ~CommandOptions() override = default;
440 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
441 ExecutionContext *execution_context) override {
442 Status error;
443 const int short_option = m_getopt_table[option_idx].val;
445 switch (short_option) {
446 case 'f':
447 m_filename.assign(option_arg);
448 break;
449 default:
450 llvm_unreachable("Unimplemented option");
453 return error;
456 void OptionParsingStarting(ExecutionContext *execution_context) override {
457 m_filename.clear();
460 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
461 return llvm::makeArrayRef(g_settings_read_options);
464 // Instance variables to hold the values for command options.
465 std::string m_filename;
468 protected:
469 bool DoExecute(Args &command, CommandReturnObject &result) override {
470 FileSpec file(m_options.m_filename);
471 FileSystem::Instance().Resolve(file);
472 ExecutionContext clean_ctx;
473 CommandInterpreterRunOptions options;
474 options.SetAddToHistory(false);
475 options.SetEchoCommands(false);
476 options.SetPrintResults(true);
477 options.SetPrintErrors(true);
478 options.SetStopOnError(false);
479 m_interpreter.HandleCommandsFromFile(file, &clean_ctx, options, result);
480 return result.Succeeded();
483 private:
484 CommandOptions m_options;
487 // CommandObjectSettingsList -- List settable variables
489 class CommandObjectSettingsList : public CommandObjectParsed {
490 public:
491 CommandObjectSettingsList(CommandInterpreter &interpreter)
492 : CommandObjectParsed(interpreter, "settings list",
493 "List and describe matching debugger settings. "
494 "Defaults to all listing all settings.",
495 nullptr) {
496 CommandArgumentEntry arg;
497 CommandArgumentData var_name_arg;
498 CommandArgumentData prefix_name_arg;
500 // Define the first variant of this arg.
501 var_name_arg.arg_type = eArgTypeSettingVariableName;
502 var_name_arg.arg_repetition = eArgRepeatOptional;
504 // Define the second variant of this arg.
505 prefix_name_arg.arg_type = eArgTypeSettingPrefix;
506 prefix_name_arg.arg_repetition = eArgRepeatOptional;
508 arg.push_back(var_name_arg);
509 arg.push_back(prefix_name_arg);
511 // Push the data for the first argument into the m_arguments vector.
512 m_arguments.push_back(arg);
515 ~CommandObjectSettingsList() override = default;
517 void
518 HandleArgumentCompletion(CompletionRequest &request,
519 OptionElementVector &opt_element_vector) override {
520 CommandCompletions::InvokeCommonCompletionCallbacks(
521 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
522 request, nullptr);
525 protected:
526 bool DoExecute(Args &args, CommandReturnObject &result) override {
527 result.SetStatus(eReturnStatusSuccessFinishResult);
529 const bool will_modify = false;
530 const size_t argc = args.GetArgumentCount();
531 if (argc > 0) {
532 const bool dump_qualified_name = true;
534 // TODO: Convert to StringRef based enumeration. Requires converting
535 // GetPropertyAtPath first.
536 for (size_t i = 0; i < argc; ++i) {
537 const char *property_path = args.GetArgumentAtIndex(i);
539 const Property *property =
540 GetDebugger().GetValueProperties()->GetPropertyAtPath(
541 &m_exe_ctx, will_modify, property_path);
543 if (property) {
544 property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
545 dump_qualified_name);
546 } else {
547 result.AppendErrorWithFormat("invalid property path '%s'",
548 property_path);
549 result.SetStatus(eReturnStatusFailed);
552 } else {
553 GetDebugger().DumpAllDescriptions(m_interpreter,
554 result.GetOutputStream());
557 return result.Succeeded();
561 // CommandObjectSettingsRemove
563 class CommandObjectSettingsRemove : public CommandObjectRaw {
564 public:
565 CommandObjectSettingsRemove(CommandInterpreter &interpreter)
566 : CommandObjectRaw(interpreter, "settings remove",
567 "Remove a value from a setting, specified by array "
568 "index or dictionary key.") {
569 CommandArgumentEntry arg1;
570 CommandArgumentEntry arg2;
571 CommandArgumentData var_name_arg;
572 CommandArgumentData index_arg;
573 CommandArgumentData key_arg;
575 // Define the first (and only) variant of this arg.
576 var_name_arg.arg_type = eArgTypeSettingVariableName;
577 var_name_arg.arg_repetition = eArgRepeatPlain;
579 // There is only one variant this argument could be; put it into the
580 // argument entry.
581 arg1.push_back(var_name_arg);
583 // Define the first variant of this arg.
584 index_arg.arg_type = eArgTypeSettingIndex;
585 index_arg.arg_repetition = eArgRepeatPlain;
587 // Define the second variant of this arg.
588 key_arg.arg_type = eArgTypeSettingKey;
589 key_arg.arg_repetition = eArgRepeatPlain;
591 // Push both variants into this arg
592 arg2.push_back(index_arg);
593 arg2.push_back(key_arg);
595 // Push the data for the first argument into the m_arguments vector.
596 m_arguments.push_back(arg1);
597 m_arguments.push_back(arg2);
600 ~CommandObjectSettingsRemove() override = default;
602 bool WantsCompletion() override { return true; }
604 void
605 HandleArgumentCompletion(CompletionRequest &request,
606 OptionElementVector &opt_element_vector) override {
607 if (request.GetCursorIndex() < 2)
608 CommandCompletions::InvokeCommonCompletionCallbacks(
609 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
610 request, nullptr);
613 protected:
614 bool DoExecute(llvm::StringRef command,
615 CommandReturnObject &result) override {
616 result.SetStatus(eReturnStatusSuccessFinishNoResult);
618 Args cmd_args(command);
620 // Process possible options.
621 if (!ParseOptions(cmd_args, result))
622 return false;
624 const size_t argc = cmd_args.GetArgumentCount();
625 if (argc == 0) {
626 result.AppendError("'settings remove' takes an array or dictionary item, "
627 "or an array followed by one or more indexes, or a "
628 "dictionary followed by one or more key names to "
629 "remove");
630 result.SetStatus(eReturnStatusFailed);
631 return false;
634 const char *var_name = cmd_args.GetArgumentAtIndex(0);
635 if ((var_name == nullptr) || (var_name[0] == '\0')) {
636 result.AppendError(
637 "'settings remove' command requires a valid variable name");
638 result.SetStatus(eReturnStatusFailed);
639 return false;
642 // Split the raw command into var_name and value pair.
643 llvm::StringRef var_value(command);
644 var_value = var_value.split(var_name).second.trim();
646 Status error(GetDebugger().SetPropertyValue(
647 &m_exe_ctx, eVarSetOperationRemove, var_name, var_value));
648 if (error.Fail()) {
649 result.AppendError(error.AsCString());
650 result.SetStatus(eReturnStatusFailed);
651 return false;
654 return result.Succeeded();
658 // CommandObjectSettingsReplace
660 class CommandObjectSettingsReplace : public CommandObjectRaw {
661 public:
662 CommandObjectSettingsReplace(CommandInterpreter &interpreter)
663 : CommandObjectRaw(interpreter, "settings replace",
664 "Replace the debugger setting value specified by "
665 "array index or dictionary key.") {
666 CommandArgumentEntry arg1;
667 CommandArgumentEntry arg2;
668 CommandArgumentEntry arg3;
669 CommandArgumentData var_name_arg;
670 CommandArgumentData index_arg;
671 CommandArgumentData key_arg;
672 CommandArgumentData value_arg;
674 // Define the first (and only) variant of this arg.
675 var_name_arg.arg_type = eArgTypeSettingVariableName;
676 var_name_arg.arg_repetition = eArgRepeatPlain;
678 // There is only one variant this argument could be; put it into the
679 // argument entry.
680 arg1.push_back(var_name_arg);
682 // Define the first (variant of this arg.
683 index_arg.arg_type = eArgTypeSettingIndex;
684 index_arg.arg_repetition = eArgRepeatPlain;
686 // Define the second (variant of this arg.
687 key_arg.arg_type = eArgTypeSettingKey;
688 key_arg.arg_repetition = eArgRepeatPlain;
690 // Put both variants into this arg
691 arg2.push_back(index_arg);
692 arg2.push_back(key_arg);
694 // Define the first (and only) variant of this arg.
695 value_arg.arg_type = eArgTypeValue;
696 value_arg.arg_repetition = eArgRepeatPlain;
698 // There is only one variant this argument could be; put it into the
699 // argument entry.
700 arg3.push_back(value_arg);
702 // Push the data for the first argument into the m_arguments vector.
703 m_arguments.push_back(arg1);
704 m_arguments.push_back(arg2);
705 m_arguments.push_back(arg3);
708 ~CommandObjectSettingsReplace() override = default;
710 // Overrides base class's behavior where WantsCompletion =
711 // !WantsRawCommandString.
712 bool WantsCompletion() override { return true; }
714 void
715 HandleArgumentCompletion(CompletionRequest &request,
716 OptionElementVector &opt_element_vector) override {
717 // Attempting to complete variable name
718 if (request.GetCursorIndex() < 2)
719 CommandCompletions::InvokeCommonCompletionCallbacks(
720 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
721 request, nullptr);
724 protected:
725 bool DoExecute(llvm::StringRef command,
726 CommandReturnObject &result) override {
727 result.SetStatus(eReturnStatusSuccessFinishNoResult);
729 Args cmd_args(command);
730 const char *var_name = cmd_args.GetArgumentAtIndex(0);
731 if ((var_name == nullptr) || (var_name[0] == '\0')) {
732 result.AppendError("'settings replace' command requires a valid variable "
733 "name; No value supplied");
734 result.SetStatus(eReturnStatusFailed);
735 return false;
738 // Split the raw command into var_name, index_value, and value triple.
739 llvm::StringRef var_value(command);
740 var_value = var_value.split(var_name).second.trim();
742 Status error(GetDebugger().SetPropertyValue(
743 &m_exe_ctx, eVarSetOperationReplace, var_name, var_value));
744 if (error.Fail()) {
745 result.AppendError(error.AsCString());
746 result.SetStatus(eReturnStatusFailed);
747 return false;
748 } else {
749 result.SetStatus(eReturnStatusSuccessFinishNoResult);
752 return result.Succeeded();
756 // CommandObjectSettingsInsertBefore
758 class CommandObjectSettingsInsertBefore : public CommandObjectRaw {
759 public:
760 CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
761 : CommandObjectRaw(interpreter, "settings insert-before",
762 "Insert one or more values into an debugger array "
763 "setting immediately before the specified element "
764 "index.") {
765 CommandArgumentEntry arg1;
766 CommandArgumentEntry arg2;
767 CommandArgumentEntry arg3;
768 CommandArgumentData var_name_arg;
769 CommandArgumentData index_arg;
770 CommandArgumentData value_arg;
772 // Define the first (and only) variant of this arg.
773 var_name_arg.arg_type = eArgTypeSettingVariableName;
774 var_name_arg.arg_repetition = eArgRepeatPlain;
776 // There is only one variant this argument could be; put it into the
777 // argument entry.
778 arg1.push_back(var_name_arg);
780 // Define the first (variant of this arg.
781 index_arg.arg_type = eArgTypeSettingIndex;
782 index_arg.arg_repetition = eArgRepeatPlain;
784 // There is only one variant this argument could be; put it into the
785 // argument entry.
786 arg2.push_back(index_arg);
788 // Define the first (and only) variant of this arg.
789 value_arg.arg_type = eArgTypeValue;
790 value_arg.arg_repetition = eArgRepeatPlain;
792 // There is only one variant this argument could be; put it into the
793 // argument entry.
794 arg3.push_back(value_arg);
796 // Push the data for the first argument into the m_arguments vector.
797 m_arguments.push_back(arg1);
798 m_arguments.push_back(arg2);
799 m_arguments.push_back(arg3);
802 ~CommandObjectSettingsInsertBefore() override = default;
804 // Overrides base class's behavior where WantsCompletion =
805 // !WantsRawCommandString.
806 bool WantsCompletion() override { return true; }
808 void
809 HandleArgumentCompletion(CompletionRequest &request,
810 OptionElementVector &opt_element_vector) override {
811 // Attempting to complete variable name
812 if (request.GetCursorIndex() < 2)
813 CommandCompletions::InvokeCommonCompletionCallbacks(
814 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
815 request, nullptr);
818 protected:
819 bool DoExecute(llvm::StringRef command,
820 CommandReturnObject &result) override {
821 result.SetStatus(eReturnStatusSuccessFinishNoResult);
823 Args cmd_args(command);
824 const size_t argc = cmd_args.GetArgumentCount();
826 if (argc < 3) {
827 result.AppendError("'settings insert-before' takes more arguments");
828 result.SetStatus(eReturnStatusFailed);
829 return false;
832 const char *var_name = cmd_args.GetArgumentAtIndex(0);
833 if ((var_name == nullptr) || (var_name[0] == '\0')) {
834 result.AppendError("'settings insert-before' command requires a valid "
835 "variable name; No value supplied");
836 result.SetStatus(eReturnStatusFailed);
837 return false;
840 // Split the raw command into var_name, index_value, and value triple.
841 llvm::StringRef var_value(command);
842 var_value = var_value.split(var_name).second.trim();
844 Status error(GetDebugger().SetPropertyValue(
845 &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value));
846 if (error.Fail()) {
847 result.AppendError(error.AsCString());
848 result.SetStatus(eReturnStatusFailed);
849 return false;
852 return result.Succeeded();
856 // CommandObjectSettingInsertAfter
858 class CommandObjectSettingsInsertAfter : public CommandObjectRaw {
859 public:
860 CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
861 : CommandObjectRaw(interpreter, "settings insert-after",
862 "Insert one or more values into a debugger array "
863 "settings after the specified element index.") {
864 CommandArgumentEntry arg1;
865 CommandArgumentEntry arg2;
866 CommandArgumentEntry arg3;
867 CommandArgumentData var_name_arg;
868 CommandArgumentData index_arg;
869 CommandArgumentData value_arg;
871 // Define the first (and only) variant of this arg.
872 var_name_arg.arg_type = eArgTypeSettingVariableName;
873 var_name_arg.arg_repetition = eArgRepeatPlain;
875 // There is only one variant this argument could be; put it into the
876 // argument entry.
877 arg1.push_back(var_name_arg);
879 // Define the first (variant of this arg.
880 index_arg.arg_type = eArgTypeSettingIndex;
881 index_arg.arg_repetition = eArgRepeatPlain;
883 // There is only one variant this argument could be; put it into the
884 // argument entry.
885 arg2.push_back(index_arg);
887 // Define the first (and only) variant of this arg.
888 value_arg.arg_type = eArgTypeValue;
889 value_arg.arg_repetition = eArgRepeatPlain;
891 // There is only one variant this argument could be; put it into the
892 // argument entry.
893 arg3.push_back(value_arg);
895 // Push the data for the first argument into the m_arguments vector.
896 m_arguments.push_back(arg1);
897 m_arguments.push_back(arg2);
898 m_arguments.push_back(arg3);
901 ~CommandObjectSettingsInsertAfter() override = default;
903 // Overrides base class's behavior where WantsCompletion =
904 // !WantsRawCommandString.
905 bool WantsCompletion() override { return true; }
907 void
908 HandleArgumentCompletion(CompletionRequest &request,
909 OptionElementVector &opt_element_vector) override {
910 // Attempting to complete variable name
911 if (request.GetCursorIndex() < 2)
912 CommandCompletions::InvokeCommonCompletionCallbacks(
913 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
914 request, nullptr);
917 protected:
918 bool DoExecute(llvm::StringRef command,
919 CommandReturnObject &result) override {
920 result.SetStatus(eReturnStatusSuccessFinishNoResult);
922 Args cmd_args(command);
923 const size_t argc = cmd_args.GetArgumentCount();
925 if (argc < 3) {
926 result.AppendError("'settings insert-after' takes more arguments");
927 result.SetStatus(eReturnStatusFailed);
928 return false;
931 const char *var_name = cmd_args.GetArgumentAtIndex(0);
932 if ((var_name == nullptr) || (var_name[0] == '\0')) {
933 result.AppendError("'settings insert-after' command requires a valid "
934 "variable name; No value supplied");
935 result.SetStatus(eReturnStatusFailed);
936 return false;
939 // Split the raw command into var_name, index_value, and value triple.
940 llvm::StringRef var_value(command);
941 var_value = var_value.split(var_name).second.trim();
943 Status error(GetDebugger().SetPropertyValue(
944 &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value));
945 if (error.Fail()) {
946 result.AppendError(error.AsCString());
947 result.SetStatus(eReturnStatusFailed);
948 return false;
951 return result.Succeeded();
955 // CommandObjectSettingsAppend
957 class CommandObjectSettingsAppend : public CommandObjectRaw {
958 public:
959 CommandObjectSettingsAppend(CommandInterpreter &interpreter)
960 : CommandObjectRaw(interpreter, "settings append",
961 "Append one or more values to a debugger array, "
962 "dictionary, or string setting.") {
963 CommandArgumentEntry arg1;
964 CommandArgumentEntry arg2;
965 CommandArgumentData var_name_arg;
966 CommandArgumentData value_arg;
968 // Define the first (and only) variant of this arg.
969 var_name_arg.arg_type = eArgTypeSettingVariableName;
970 var_name_arg.arg_repetition = eArgRepeatPlain;
972 // There is only one variant this argument could be; put it into the
973 // argument entry.
974 arg1.push_back(var_name_arg);
976 // Define the first (and only) variant of this arg.
977 value_arg.arg_type = eArgTypeValue;
978 value_arg.arg_repetition = eArgRepeatPlain;
980 // There is only one variant this argument could be; put it into the
981 // argument entry.
982 arg2.push_back(value_arg);
984 // Push the data for the first argument into the m_arguments vector.
985 m_arguments.push_back(arg1);
986 m_arguments.push_back(arg2);
989 ~CommandObjectSettingsAppend() override = default;
991 // Overrides base class's behavior where WantsCompletion =
992 // !WantsRawCommandString.
993 bool WantsCompletion() override { return true; }
995 void
996 HandleArgumentCompletion(CompletionRequest &request,
997 OptionElementVector &opt_element_vector) override {
998 // Attempting to complete variable name
999 if (request.GetCursorIndex() < 2)
1000 CommandCompletions::InvokeCommonCompletionCallbacks(
1001 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
1002 request, nullptr);
1005 protected:
1006 bool DoExecute(llvm::StringRef command,
1007 CommandReturnObject &result) override {
1008 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1009 Args cmd_args(command);
1010 const size_t argc = cmd_args.GetArgumentCount();
1012 if (argc < 2) {
1013 result.AppendError("'settings append' takes more arguments");
1014 result.SetStatus(eReturnStatusFailed);
1015 return false;
1018 const char *var_name = cmd_args.GetArgumentAtIndex(0);
1019 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1020 result.AppendError("'settings append' command requires a valid variable "
1021 "name; No value supplied");
1022 result.SetStatus(eReturnStatusFailed);
1023 return false;
1026 // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
1027 // character string later on.
1029 // Split the raw command into var_name and value pair.
1030 llvm::StringRef var_value(command);
1031 var_value = var_value.split(var_name).second.trim();
1033 Status error(GetDebugger().SetPropertyValue(
1034 &m_exe_ctx, eVarSetOperationAppend, var_name, var_value));
1035 if (error.Fail()) {
1036 result.AppendError(error.AsCString());
1037 result.SetStatus(eReturnStatusFailed);
1038 return false;
1041 return result.Succeeded();
1045 // CommandObjectSettingsClear
1047 class CommandObjectSettingsClear : public CommandObjectParsed {
1048 public:
1049 CommandObjectSettingsClear(CommandInterpreter &interpreter)
1050 : CommandObjectParsed(
1051 interpreter, "settings clear",
1052 "Clear a debugger setting array, dictionary, or string.", nullptr) {
1053 CommandArgumentEntry arg;
1054 CommandArgumentData var_name_arg;
1056 // Define the first (and only) variant of this arg.
1057 var_name_arg.arg_type = eArgTypeSettingVariableName;
1058 var_name_arg.arg_repetition = eArgRepeatPlain;
1060 // There is only one variant this argument could be; put it into the
1061 // argument entry.
1062 arg.push_back(var_name_arg);
1064 // Push the data for the first argument into the m_arguments vector.
1065 m_arguments.push_back(arg);
1068 ~CommandObjectSettingsClear() override = default;
1070 void
1071 HandleArgumentCompletion(CompletionRequest &request,
1072 OptionElementVector &opt_element_vector) override {
1073 // Attempting to complete variable name
1074 if (request.GetCursorIndex() < 2)
1075 CommandCompletions::InvokeCommonCompletionCallbacks(
1076 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
1077 request, nullptr);
1080 protected:
1081 bool DoExecute(Args &command, CommandReturnObject &result) override {
1082 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1083 const size_t argc = command.GetArgumentCount();
1085 if (argc != 1) {
1086 result.AppendError("'settings clear' takes exactly one argument");
1087 result.SetStatus(eReturnStatusFailed);
1088 return false;
1091 const char *var_name = command.GetArgumentAtIndex(0);
1092 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1093 result.AppendError("'settings clear' command requires a valid variable "
1094 "name; No value supplied");
1095 result.SetStatus(eReturnStatusFailed);
1096 return false;
1099 Status error(GetDebugger().SetPropertyValue(
1100 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
1101 if (error.Fail()) {
1102 result.AppendError(error.AsCString());
1103 result.SetStatus(eReturnStatusFailed);
1104 return false;
1107 return result.Succeeded();
1111 // CommandObjectMultiwordSettings
1113 CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
1114 CommandInterpreter &interpreter)
1115 : CommandObjectMultiword(interpreter, "settings",
1116 "Commands for managing LLDB settings.",
1117 "settings <subcommand> [<command-options>]") {
1118 LoadSubCommand("set",
1119 CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
1120 LoadSubCommand("show",
1121 CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
1122 LoadSubCommand("list",
1123 CommandObjectSP(new CommandObjectSettingsList(interpreter)));
1124 LoadSubCommand("remove",
1125 CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
1126 LoadSubCommand("replace", CommandObjectSP(
1127 new CommandObjectSettingsReplace(interpreter)));
1128 LoadSubCommand(
1129 "insert-before",
1130 CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
1131 LoadSubCommand(
1132 "insert-after",
1133 CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
1134 LoadSubCommand("append",
1135 CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
1136 LoadSubCommand("clear",
1137 CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
1138 LoadSubCommand("write",
1139 CommandObjectSP(new CommandObjectSettingsWrite(interpreter)));
1140 LoadSubCommand("read",
1141 CommandObjectSP(new CommandObjectSettingsRead(interpreter)));
1144 CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default;