Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / source / Commands / CommandObjectSettings.cpp
blob5fb7dcc80279fd9d82eb30ee11c78a8bd9b8313c
1 //===-- CommandObjectSettings.cpp -----------------------------------------===//
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/CommandOptionArgumentTable.h"
17 #include "lldb/Interpreter/CommandReturnObject.h"
18 #include "lldb/Interpreter/OptionValueProperties.h"
20 using namespace lldb;
21 using namespace lldb_private;
23 // CommandObjectSettingsSet
24 #define LLDB_OPTIONS_settings_set
25 #include "CommandOptions.inc"
27 class CommandObjectSettingsSet : public CommandObjectRaw {
28 public:
29 CommandObjectSettingsSet(CommandInterpreter &interpreter)
30 : CommandObjectRaw(interpreter, "settings set",
31 "Set the value of the specified debugger setting.") {
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() = default;
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 case 'e':
107 m_exists = true;
108 break;
109 default:
110 llvm_unreachable("Unimplemented option");
113 return error;
116 void OptionParsingStarting(ExecutionContext *execution_context) override {
117 m_global = false;
118 m_force = false;
119 m_exists = false;
122 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
123 return llvm::ArrayRef(g_settings_set_options);
126 // Instance variables to hold the values for command options.
127 bool m_global = false;
128 bool m_force = false;
129 bool m_exists = false;
132 void
133 HandleArgumentCompletion(CompletionRequest &request,
134 OptionElementVector &opt_element_vector) override {
136 const size_t argc = request.GetParsedLine().GetArgumentCount();
137 const char *arg = nullptr;
138 size_t setting_var_idx;
139 for (setting_var_idx = 0; setting_var_idx < argc; ++setting_var_idx) {
140 arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
141 if (arg && arg[0] != '-')
142 break; // We found our setting variable name index
144 if (request.GetCursorIndex() == setting_var_idx) {
145 // Attempting to complete setting variable name
146 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
147 GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
148 nullptr);
149 return;
151 arg = request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
153 if (!arg)
154 return;
156 // Complete option name
157 if (arg[0] == '-')
158 return;
160 // Complete setting value
161 const char *setting_var_name =
162 request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
163 Status error;
164 lldb::OptionValueSP value_sp(
165 GetDebugger().GetPropertyValue(&m_exe_ctx, setting_var_name, error));
166 if (!value_sp)
167 return;
168 value_sp->AutoComplete(m_interpreter, request);
171 protected:
172 void DoExecute(llvm::StringRef command,
173 CommandReturnObject &result) override {
174 Args cmd_args(command);
176 // Process possible options.
177 if (!ParseOptions(cmd_args, result))
178 return;
180 const size_t min_argc = m_options.m_force ? 1 : 2;
181 const size_t argc = cmd_args.GetArgumentCount();
183 if ((argc < min_argc) && (!m_options.m_global)) {
184 result.AppendError("'settings set' takes more arguments");
185 return;
188 const char *var_name = cmd_args.GetArgumentAtIndex(0);
189 if ((var_name == nullptr) || (var_name[0] == '\0')) {
190 result.AppendError(
191 "'settings set' command requires a valid variable name");
192 return;
195 // A missing value corresponds to clearing the setting when "force" is
196 // specified.
197 if (argc == 1 && m_options.m_force) {
198 Status error(GetDebugger().SetPropertyValue(
199 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
200 if (error.Fail()) {
201 result.AppendError(error.AsCString());
203 return;
206 // Split the raw command into var_name and value pair.
207 llvm::StringRef var_value(command);
208 var_value = var_value.split(var_name).second.ltrim();
210 Status error;
211 if (m_options.m_global)
212 error = GetDebugger().SetPropertyValue(nullptr, eVarSetOperationAssign,
213 var_name, var_value);
215 if (error.Success()) {
216 // FIXME this is the same issue as the one in commands script import
217 // we could be setting target.load-script-from-symbol-file which would
218 // cause Python scripts to be loaded, which could run LLDB commands (e.g.
219 // settings set target.process.python-os-plugin-path) and cause a crash
220 // if we did not clear the command's exe_ctx first
221 ExecutionContext exe_ctx(m_exe_ctx);
222 m_exe_ctx.Clear();
223 error = GetDebugger().SetPropertyValue(&exe_ctx, eVarSetOperationAssign,
224 var_name, var_value);
227 if (error.Fail() && !m_options.m_exists) {
228 result.AppendError(error.AsCString());
229 return;
232 result.SetStatus(eReturnStatusSuccessFinishResult);
235 private:
236 CommandOptions m_options;
239 // CommandObjectSettingsShow -- Show current values
241 class CommandObjectSettingsShow : public CommandObjectParsed {
242 public:
243 CommandObjectSettingsShow(CommandInterpreter &interpreter)
244 : CommandObjectParsed(interpreter, "settings show",
245 "Show matching debugger settings and their current "
246 "values. Defaults to showing all settings.",
247 nullptr) {
248 CommandArgumentEntry arg1;
249 CommandArgumentData var_name_arg;
251 // Define the first (and only) variant of this arg.
252 var_name_arg.arg_type = eArgTypeSettingVariableName;
253 var_name_arg.arg_repetition = eArgRepeatOptional;
255 // There is only one variant this argument could be; put it into the
256 // argument entry.
257 arg1.push_back(var_name_arg);
259 // Push the data for the first argument into the m_arguments vector.
260 m_arguments.push_back(arg1);
263 ~CommandObjectSettingsShow() override = default;
265 void
266 HandleArgumentCompletion(CompletionRequest &request,
267 OptionElementVector &opt_element_vector) override {
268 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
269 GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
270 nullptr);
273 protected:
274 void DoExecute(Args &args, CommandReturnObject &result) override {
275 result.SetStatus(eReturnStatusSuccessFinishResult);
277 if (!args.empty()) {
278 for (const auto &arg : args) {
279 Status error(GetDebugger().DumpPropertyValue(
280 &m_exe_ctx, result.GetOutputStream(), arg.ref(),
281 OptionValue::eDumpGroupValue));
282 if (error.Success()) {
283 result.GetOutputStream().EOL();
284 } else {
285 result.AppendError(error.AsCString());
288 } else {
289 GetDebugger().DumpAllPropertyValues(&m_exe_ctx, result.GetOutputStream(),
290 OptionValue::eDumpGroupValue);
295 // CommandObjectSettingsWrite -- Write settings to file
296 #define LLDB_OPTIONS_settings_write
297 #include "CommandOptions.inc"
299 class CommandObjectSettingsWrite : public CommandObjectParsed {
300 public:
301 CommandObjectSettingsWrite(CommandInterpreter &interpreter)
302 : CommandObjectParsed(
303 interpreter, "settings export",
304 "Write matching debugger settings and their "
305 "current values to a file that can be read in with "
306 "\"settings read\". Defaults to writing all settings.",
307 nullptr) {
308 CommandArgumentEntry arg1;
309 CommandArgumentData var_name_arg;
311 // Define the first (and only) variant of this arg.
312 var_name_arg.arg_type = eArgTypeSettingVariableName;
313 var_name_arg.arg_repetition = eArgRepeatOptional;
315 // There is only one variant this argument could be; put it into the
316 // argument entry.
317 arg1.push_back(var_name_arg);
319 // Push the data for the first argument into the m_arguments vector.
320 m_arguments.push_back(arg1);
323 ~CommandObjectSettingsWrite() override = default;
325 Options *GetOptions() override { return &m_options; }
327 class CommandOptions : public Options {
328 public:
329 CommandOptions() = default;
331 ~CommandOptions() override = default;
333 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
334 ExecutionContext *execution_context) override {
335 Status error;
336 const int short_option = m_getopt_table[option_idx].val;
338 switch (short_option) {
339 case 'f':
340 m_filename.assign(std::string(option_arg));
341 break;
342 case 'a':
343 m_append = true;
344 break;
345 default:
346 llvm_unreachable("Unimplemented option");
349 return error;
352 void OptionParsingStarting(ExecutionContext *execution_context) override {
353 m_filename.clear();
354 m_append = false;
357 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
358 return llvm::ArrayRef(g_settings_write_options);
361 // Instance variables to hold the values for command options.
362 std::string m_filename;
363 bool m_append = false;
366 protected:
367 void DoExecute(Args &args, CommandReturnObject &result) override {
368 FileSpec file_spec(m_options.m_filename);
369 FileSystem::Instance().Resolve(file_spec);
370 std::string path(file_spec.GetPath());
371 auto options = File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate;
372 if (m_options.m_append)
373 options |= File::eOpenOptionAppend;
374 else
375 options |= File::eOpenOptionTruncate;
377 StreamFile out_file(path.c_str(), options,
378 lldb::eFilePermissionsFileDefault);
380 if (!out_file.GetFile().IsValid()) {
381 result.AppendErrorWithFormat("%s: unable to write to file", path.c_str());
382 return;
385 // Exporting should not be context sensitive.
386 ExecutionContext clean_ctx;
388 if (args.empty()) {
389 GetDebugger().DumpAllPropertyValues(&clean_ctx, out_file,
390 OptionValue::eDumpGroupExport);
391 return;
394 for (const auto &arg : args) {
395 Status error(GetDebugger().DumpPropertyValue(
396 &clean_ctx, out_file, arg.ref(), OptionValue::eDumpGroupExport));
397 if (!error.Success()) {
398 result.AppendError(error.AsCString());
403 private:
404 CommandOptions m_options;
407 // CommandObjectSettingsRead -- Read settings from file
408 #define LLDB_OPTIONS_settings_read
409 #include "CommandOptions.inc"
411 class CommandObjectSettingsRead : public CommandObjectParsed {
412 public:
413 CommandObjectSettingsRead(CommandInterpreter &interpreter)
414 : CommandObjectParsed(
415 interpreter, "settings read",
416 "Read settings previously saved to a file with \"settings write\".",
417 nullptr) {}
419 ~CommandObjectSettingsRead() override = default;
421 Options *GetOptions() override { return &m_options; }
423 class CommandOptions : public Options {
424 public:
425 CommandOptions() = default;
427 ~CommandOptions() override = default;
429 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
430 ExecutionContext *execution_context) override {
431 Status error;
432 const int short_option = m_getopt_table[option_idx].val;
434 switch (short_option) {
435 case 'f':
436 m_filename.assign(std::string(option_arg));
437 break;
438 default:
439 llvm_unreachable("Unimplemented option");
442 return error;
445 void OptionParsingStarting(ExecutionContext *execution_context) override {
446 m_filename.clear();
449 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
450 return llvm::ArrayRef(g_settings_read_options);
453 // Instance variables to hold the values for command options.
454 std::string m_filename;
457 protected:
458 void DoExecute(Args &command, CommandReturnObject &result) override {
459 FileSpec file(m_options.m_filename);
460 FileSystem::Instance().Resolve(file);
461 CommandInterpreterRunOptions options;
462 options.SetAddToHistory(false);
463 options.SetEchoCommands(false);
464 options.SetPrintResults(true);
465 options.SetPrintErrors(true);
466 options.SetStopOnError(false);
467 m_interpreter.HandleCommandsFromFile(file, options, result);
470 private:
471 CommandOptions m_options;
474 // CommandObjectSettingsList -- List settable variables
476 class CommandObjectSettingsList : public CommandObjectParsed {
477 public:
478 CommandObjectSettingsList(CommandInterpreter &interpreter)
479 : CommandObjectParsed(interpreter, "settings list",
480 "List and describe matching debugger settings. "
481 "Defaults to all listing all settings.",
482 nullptr) {
483 CommandArgumentEntry arg;
484 CommandArgumentData var_name_arg;
485 CommandArgumentData prefix_name_arg;
487 // Define the first variant of this arg.
488 var_name_arg.arg_type = eArgTypeSettingVariableName;
489 var_name_arg.arg_repetition = eArgRepeatOptional;
491 // Define the second variant of this arg.
492 prefix_name_arg.arg_type = eArgTypeSettingPrefix;
493 prefix_name_arg.arg_repetition = eArgRepeatOptional;
495 arg.push_back(var_name_arg);
496 arg.push_back(prefix_name_arg);
498 // Push the data for the first argument into the m_arguments vector.
499 m_arguments.push_back(arg);
502 ~CommandObjectSettingsList() override = default;
504 void
505 HandleArgumentCompletion(CompletionRequest &request,
506 OptionElementVector &opt_element_vector) override {
507 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
508 GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
509 nullptr);
512 protected:
513 void DoExecute(Args &args, CommandReturnObject &result) override {
514 result.SetStatus(eReturnStatusSuccessFinishResult);
516 const size_t argc = args.GetArgumentCount();
517 if (argc > 0) {
518 const bool dump_qualified_name = true;
520 for (const Args::ArgEntry &arg : args) {
521 const char *property_path = arg.c_str();
523 const Property *property =
524 GetDebugger().GetValueProperties()->GetPropertyAtPath(
525 &m_exe_ctx, property_path);
527 if (property) {
528 property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
529 dump_qualified_name);
530 } else {
531 result.AppendErrorWithFormat("invalid property path '%s'",
532 property_path);
535 } else {
536 GetDebugger().DumpAllDescriptions(m_interpreter,
537 result.GetOutputStream());
542 // CommandObjectSettingsRemove
544 class CommandObjectSettingsRemove : public CommandObjectRaw {
545 public:
546 CommandObjectSettingsRemove(CommandInterpreter &interpreter)
547 : CommandObjectRaw(interpreter, "settings remove",
548 "Remove a value from a setting, specified by array "
549 "index or dictionary key.") {
550 CommandArgumentEntry arg1;
551 CommandArgumentEntry arg2;
552 CommandArgumentData var_name_arg;
553 CommandArgumentData index_arg;
554 CommandArgumentData key_arg;
556 // Define the first (and only) variant of this arg.
557 var_name_arg.arg_type = eArgTypeSettingVariableName;
558 var_name_arg.arg_repetition = eArgRepeatPlain;
560 // There is only one variant this argument could be; put it into the
561 // argument entry.
562 arg1.push_back(var_name_arg);
564 // Define the first variant of this arg.
565 index_arg.arg_type = eArgTypeSettingIndex;
566 index_arg.arg_repetition = eArgRepeatPlain;
568 // Define the second variant of this arg.
569 key_arg.arg_type = eArgTypeSettingKey;
570 key_arg.arg_repetition = eArgRepeatPlain;
572 // Push both variants into this arg
573 arg2.push_back(index_arg);
574 arg2.push_back(key_arg);
576 // Push the data for the first argument into the m_arguments vector.
577 m_arguments.push_back(arg1);
578 m_arguments.push_back(arg2);
581 ~CommandObjectSettingsRemove() override = default;
583 bool WantsCompletion() override { return true; }
585 void
586 HandleArgumentCompletion(CompletionRequest &request,
587 OptionElementVector &opt_element_vector) override {
588 if (request.GetCursorIndex() < 2)
589 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
590 GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
591 nullptr);
594 protected:
595 void DoExecute(llvm::StringRef command,
596 CommandReturnObject &result) override {
597 result.SetStatus(eReturnStatusSuccessFinishNoResult);
599 Args cmd_args(command);
601 // Process possible options.
602 if (!ParseOptions(cmd_args, result))
603 return;
605 const size_t argc = cmd_args.GetArgumentCount();
606 if (argc == 0) {
607 result.AppendError("'settings remove' takes an array or dictionary item, "
608 "or an array followed by one or more indexes, or a "
609 "dictionary followed by one or more key names to "
610 "remove");
611 return;
614 const char *var_name = cmd_args.GetArgumentAtIndex(0);
615 if ((var_name == nullptr) || (var_name[0] == '\0')) {
616 result.AppendError(
617 "'settings remove' command requires a valid variable name");
618 return;
621 // Split the raw command into var_name and value pair.
622 llvm::StringRef var_value(command);
623 var_value = var_value.split(var_name).second.trim();
625 Status error(GetDebugger().SetPropertyValue(
626 &m_exe_ctx, eVarSetOperationRemove, var_name, var_value));
627 if (error.Fail()) {
628 result.AppendError(error.AsCString());
633 // CommandObjectSettingsReplace
635 class CommandObjectSettingsReplace : public CommandObjectRaw {
636 public:
637 CommandObjectSettingsReplace(CommandInterpreter &interpreter)
638 : CommandObjectRaw(interpreter, "settings replace",
639 "Replace the debugger setting value specified by "
640 "array index or dictionary key.") {
641 CommandArgumentEntry arg1;
642 CommandArgumentEntry arg2;
643 CommandArgumentEntry arg3;
644 CommandArgumentData var_name_arg;
645 CommandArgumentData index_arg;
646 CommandArgumentData key_arg;
647 CommandArgumentData value_arg;
649 // Define the first (and only) variant of this arg.
650 var_name_arg.arg_type = eArgTypeSettingVariableName;
651 var_name_arg.arg_repetition = eArgRepeatPlain;
653 // There is only one variant this argument could be; put it into the
654 // argument entry.
655 arg1.push_back(var_name_arg);
657 // Define the first (variant of this arg.
658 index_arg.arg_type = eArgTypeSettingIndex;
659 index_arg.arg_repetition = eArgRepeatPlain;
661 // Define the second (variant of this arg.
662 key_arg.arg_type = eArgTypeSettingKey;
663 key_arg.arg_repetition = eArgRepeatPlain;
665 // Put both variants into this arg
666 arg2.push_back(index_arg);
667 arg2.push_back(key_arg);
669 // Define the first (and only) variant of this arg.
670 value_arg.arg_type = eArgTypeValue;
671 value_arg.arg_repetition = eArgRepeatPlain;
673 // There is only one variant this argument could be; put it into the
674 // argument entry.
675 arg3.push_back(value_arg);
677 // Push the data for the first argument into the m_arguments vector.
678 m_arguments.push_back(arg1);
679 m_arguments.push_back(arg2);
680 m_arguments.push_back(arg3);
683 ~CommandObjectSettingsReplace() override = default;
685 // Overrides base class's behavior where WantsCompletion =
686 // !WantsRawCommandString.
687 bool WantsCompletion() override { return true; }
689 void
690 HandleArgumentCompletion(CompletionRequest &request,
691 OptionElementVector &opt_element_vector) override {
692 // Attempting to complete variable name
693 if (request.GetCursorIndex() < 2)
694 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
695 GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
696 nullptr);
699 protected:
700 void DoExecute(llvm::StringRef command,
701 CommandReturnObject &result) override {
702 result.SetStatus(eReturnStatusSuccessFinishNoResult);
704 Args cmd_args(command);
705 const char *var_name = cmd_args.GetArgumentAtIndex(0);
706 if ((var_name == nullptr) || (var_name[0] == '\0')) {
707 result.AppendError("'settings replace' command requires a valid variable "
708 "name; No value supplied");
709 return;
712 // Split the raw command into var_name, index_value, and value triple.
713 llvm::StringRef var_value(command);
714 var_value = var_value.split(var_name).second.trim();
716 Status error(GetDebugger().SetPropertyValue(
717 &m_exe_ctx, eVarSetOperationReplace, var_name, var_value));
718 if (error.Fail()) {
719 result.AppendError(error.AsCString());
720 } else {
721 result.SetStatus(eReturnStatusSuccessFinishNoResult);
726 // CommandObjectSettingsInsertBefore
728 class CommandObjectSettingsInsertBefore : public CommandObjectRaw {
729 public:
730 CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
731 : CommandObjectRaw(interpreter, "settings insert-before",
732 "Insert one or more values into an debugger array "
733 "setting immediately before the specified element "
734 "index.") {
735 CommandArgumentEntry arg1;
736 CommandArgumentEntry arg2;
737 CommandArgumentEntry arg3;
738 CommandArgumentData var_name_arg;
739 CommandArgumentData index_arg;
740 CommandArgumentData value_arg;
742 // Define the first (and only) variant of this arg.
743 var_name_arg.arg_type = eArgTypeSettingVariableName;
744 var_name_arg.arg_repetition = eArgRepeatPlain;
746 // There is only one variant this argument could be; put it into the
747 // argument entry.
748 arg1.push_back(var_name_arg);
750 // Define the first (variant of this arg.
751 index_arg.arg_type = eArgTypeSettingIndex;
752 index_arg.arg_repetition = eArgRepeatPlain;
754 // There is only one variant this argument could be; put it into the
755 // argument entry.
756 arg2.push_back(index_arg);
758 // Define the first (and only) variant of this arg.
759 value_arg.arg_type = eArgTypeValue;
760 value_arg.arg_repetition = eArgRepeatPlain;
762 // There is only one variant this argument could be; put it into the
763 // argument entry.
764 arg3.push_back(value_arg);
766 // Push the data for the first argument into the m_arguments vector.
767 m_arguments.push_back(arg1);
768 m_arguments.push_back(arg2);
769 m_arguments.push_back(arg3);
772 ~CommandObjectSettingsInsertBefore() override = default;
774 // Overrides base class's behavior where WantsCompletion =
775 // !WantsRawCommandString.
776 bool WantsCompletion() override { return true; }
778 void
779 HandleArgumentCompletion(CompletionRequest &request,
780 OptionElementVector &opt_element_vector) override {
781 // Attempting to complete variable name
782 if (request.GetCursorIndex() < 2)
783 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
784 GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
785 nullptr);
788 protected:
789 void DoExecute(llvm::StringRef command,
790 CommandReturnObject &result) override {
791 result.SetStatus(eReturnStatusSuccessFinishNoResult);
793 Args cmd_args(command);
794 const size_t argc = cmd_args.GetArgumentCount();
796 if (argc < 3) {
797 result.AppendError("'settings insert-before' takes more arguments");
798 return;
801 const char *var_name = cmd_args.GetArgumentAtIndex(0);
802 if ((var_name == nullptr) || (var_name[0] == '\0')) {
803 result.AppendError("'settings insert-before' command requires a valid "
804 "variable name; No value supplied");
805 return;
808 // Split the raw command into var_name, index_value, and value triple.
809 llvm::StringRef var_value(command);
810 var_value = var_value.split(var_name).second.trim();
812 Status error(GetDebugger().SetPropertyValue(
813 &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value));
814 if (error.Fail()) {
815 result.AppendError(error.AsCString());
820 // CommandObjectSettingInsertAfter
822 class CommandObjectSettingsInsertAfter : public CommandObjectRaw {
823 public:
824 CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
825 : CommandObjectRaw(interpreter, "settings insert-after",
826 "Insert one or more values into a debugger array "
827 "settings after the specified element index.") {
828 CommandArgumentEntry arg1;
829 CommandArgumentEntry arg2;
830 CommandArgumentEntry arg3;
831 CommandArgumentData var_name_arg;
832 CommandArgumentData index_arg;
833 CommandArgumentData value_arg;
835 // Define the first (and only) variant of this arg.
836 var_name_arg.arg_type = eArgTypeSettingVariableName;
837 var_name_arg.arg_repetition = eArgRepeatPlain;
839 // There is only one variant this argument could be; put it into the
840 // argument entry.
841 arg1.push_back(var_name_arg);
843 // Define the first (variant of this arg.
844 index_arg.arg_type = eArgTypeSettingIndex;
845 index_arg.arg_repetition = eArgRepeatPlain;
847 // There is only one variant this argument could be; put it into the
848 // argument entry.
849 arg2.push_back(index_arg);
851 // Define the first (and only) variant of this arg.
852 value_arg.arg_type = eArgTypeValue;
853 value_arg.arg_repetition = eArgRepeatPlain;
855 // There is only one variant this argument could be; put it into the
856 // argument entry.
857 arg3.push_back(value_arg);
859 // Push the data for the first argument into the m_arguments vector.
860 m_arguments.push_back(arg1);
861 m_arguments.push_back(arg2);
862 m_arguments.push_back(arg3);
865 ~CommandObjectSettingsInsertAfter() override = default;
867 // Overrides base class's behavior where WantsCompletion =
868 // !WantsRawCommandString.
869 bool WantsCompletion() override { return true; }
871 void
872 HandleArgumentCompletion(CompletionRequest &request,
873 OptionElementVector &opt_element_vector) override {
874 // Attempting to complete variable name
875 if (request.GetCursorIndex() < 2)
876 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
877 GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
878 nullptr);
881 protected:
882 void DoExecute(llvm::StringRef command,
883 CommandReturnObject &result) override {
884 result.SetStatus(eReturnStatusSuccessFinishNoResult);
886 Args cmd_args(command);
887 const size_t argc = cmd_args.GetArgumentCount();
889 if (argc < 3) {
890 result.AppendError("'settings insert-after' takes more arguments");
891 return;
894 const char *var_name = cmd_args.GetArgumentAtIndex(0);
895 if ((var_name == nullptr) || (var_name[0] == '\0')) {
896 result.AppendError("'settings insert-after' command requires a valid "
897 "variable name; No value supplied");
898 return;
901 // Split the raw command into var_name, index_value, and value triple.
902 llvm::StringRef var_value(command);
903 var_value = var_value.split(var_name).second.trim();
905 Status error(GetDebugger().SetPropertyValue(
906 &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value));
907 if (error.Fail()) {
908 result.AppendError(error.AsCString());
913 // CommandObjectSettingsAppend
915 class CommandObjectSettingsAppend : public CommandObjectRaw {
916 public:
917 CommandObjectSettingsAppend(CommandInterpreter &interpreter)
918 : CommandObjectRaw(interpreter, "settings append",
919 "Append one or more values to a debugger array, "
920 "dictionary, or string setting.") {
921 CommandArgumentEntry arg1;
922 CommandArgumentEntry arg2;
923 CommandArgumentData var_name_arg;
924 CommandArgumentData value_arg;
926 // Define the first (and only) variant of this arg.
927 var_name_arg.arg_type = eArgTypeSettingVariableName;
928 var_name_arg.arg_repetition = eArgRepeatPlain;
930 // There is only one variant this argument could be; put it into the
931 // argument entry.
932 arg1.push_back(var_name_arg);
934 // Define the first (and only) variant of this arg.
935 value_arg.arg_type = eArgTypeValue;
936 value_arg.arg_repetition = eArgRepeatPlain;
938 // There is only one variant this argument could be; put it into the
939 // argument entry.
940 arg2.push_back(value_arg);
942 // Push the data for the first argument into the m_arguments vector.
943 m_arguments.push_back(arg1);
944 m_arguments.push_back(arg2);
947 ~CommandObjectSettingsAppend() override = default;
949 // Overrides base class's behavior where WantsCompletion =
950 // !WantsRawCommandString.
951 bool WantsCompletion() override { return true; }
953 void
954 HandleArgumentCompletion(CompletionRequest &request,
955 OptionElementVector &opt_element_vector) override {
956 // Attempting to complete variable name
957 if (request.GetCursorIndex() < 2)
958 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
959 GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
960 nullptr);
963 protected:
964 void DoExecute(llvm::StringRef command,
965 CommandReturnObject &result) override {
966 result.SetStatus(eReturnStatusSuccessFinishNoResult);
967 Args cmd_args(command);
968 const size_t argc = cmd_args.GetArgumentCount();
970 if (argc < 2) {
971 result.AppendError("'settings append' takes more arguments");
972 return;
975 const char *var_name = cmd_args.GetArgumentAtIndex(0);
976 if ((var_name == nullptr) || (var_name[0] == '\0')) {
977 result.AppendError("'settings append' command requires a valid variable "
978 "name; No value supplied");
979 return;
982 // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
983 // character string later on.
985 // Split the raw command into var_name and value pair.
986 llvm::StringRef var_value(command);
987 var_value = var_value.split(var_name).second.trim();
989 Status error(GetDebugger().SetPropertyValue(
990 &m_exe_ctx, eVarSetOperationAppend, var_name, var_value));
991 if (error.Fail()) {
992 result.AppendError(error.AsCString());
997 // CommandObjectSettingsClear
998 #define LLDB_OPTIONS_settings_clear
999 #include "CommandOptions.inc"
1001 class CommandObjectSettingsClear : public CommandObjectParsed {
1002 public:
1003 CommandObjectSettingsClear(CommandInterpreter &interpreter)
1004 : CommandObjectParsed(
1005 interpreter, "settings clear",
1006 "Clear a debugger setting array, dictionary, or string. "
1007 "If '-a' option is specified, it clears all settings.", nullptr) {
1008 CommandArgumentEntry arg;
1009 CommandArgumentData var_name_arg;
1011 // Define the first (and only) variant of this arg.
1012 var_name_arg.arg_type = eArgTypeSettingVariableName;
1013 var_name_arg.arg_repetition = eArgRepeatPlain;
1015 // There is only one variant this argument could be; put it into the
1016 // argument entry.
1017 arg.push_back(var_name_arg);
1019 // Push the data for the first argument into the m_arguments vector.
1020 m_arguments.push_back(arg);
1023 ~CommandObjectSettingsClear() override = default;
1025 void
1026 HandleArgumentCompletion(CompletionRequest &request,
1027 OptionElementVector &opt_element_vector) override {
1028 // Attempting to complete variable name
1029 if (request.GetCursorIndex() < 2)
1030 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
1031 GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
1032 nullptr);
1035 Options *GetOptions() override { return &m_options; }
1037 class CommandOptions : public Options {
1038 public:
1039 CommandOptions() = default;
1041 ~CommandOptions() override = default;
1043 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1044 ExecutionContext *execution_context) override {
1045 const int short_option = m_getopt_table[option_idx].val;
1046 switch (short_option) {
1047 case 'a':
1048 m_clear_all = true;
1049 break;
1050 default:
1051 llvm_unreachable("Unimplemented option");
1053 return Status();
1056 void OptionParsingStarting(ExecutionContext *execution_context) override {
1057 m_clear_all = false;
1060 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1061 return llvm::ArrayRef(g_settings_clear_options);
1064 bool m_clear_all = false;
1067 protected:
1068 void DoExecute(Args &command, CommandReturnObject &result) override {
1069 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1070 const size_t argc = command.GetArgumentCount();
1072 if (m_options.m_clear_all) {
1073 if (argc != 0) {
1074 result.AppendError("'settings clear --all' doesn't take any arguments");
1075 return;
1077 GetDebugger().GetValueProperties()->Clear();
1078 return;
1081 if (argc != 1) {
1082 result.AppendError("'settings clear' takes exactly one argument");
1083 return;
1086 const char *var_name = command.GetArgumentAtIndex(0);
1087 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1088 result.AppendError("'settings clear' command requires a valid variable "
1089 "name; No value supplied");
1090 return;
1093 Status error(GetDebugger().SetPropertyValue(
1094 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
1095 if (error.Fail()) {
1096 result.AppendError(error.AsCString());
1100 private:
1101 CommandOptions m_options;
1104 // CommandObjectMultiwordSettings
1106 CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
1107 CommandInterpreter &interpreter)
1108 : CommandObjectMultiword(interpreter, "settings",
1109 "Commands for managing LLDB settings.",
1110 "settings <subcommand> [<command-options>]") {
1111 LoadSubCommand("set",
1112 CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
1113 LoadSubCommand("show",
1114 CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
1115 LoadSubCommand("list",
1116 CommandObjectSP(new CommandObjectSettingsList(interpreter)));
1117 LoadSubCommand("remove",
1118 CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
1119 LoadSubCommand("replace", CommandObjectSP(
1120 new CommandObjectSettingsReplace(interpreter)));
1121 LoadSubCommand(
1122 "insert-before",
1123 CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
1124 LoadSubCommand(
1125 "insert-after",
1126 CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
1127 LoadSubCommand("append",
1128 CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
1129 LoadSubCommand("clear",
1130 CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
1131 LoadSubCommand("write",
1132 CommandObjectSP(new CommandObjectSettingsWrite(interpreter)));
1133 LoadSubCommand("read",
1134 CommandObjectSP(new CommandObjectSettingsRead(interpreter)));
1137 CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default;