1 //===-- CommandObjectSettings.cpp -------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "CommandObjectSettings.h"
12 #include "llvm/ADT/StringRef.h"
14 #include "lldb/Host/OptionParser.h"
15 #include "lldb/Interpreter/CommandCompletions.h"
16 #include "lldb/Interpreter/CommandInterpreter.h"
17 #include "lldb/Interpreter/CommandReturnObject.h"
18 #include "lldb/Interpreter/OptionValueProperties.h"
21 using namespace lldb_private;
23 //-------------------------------------------------------------------------
24 // CommandObjectSettingsSet
25 //-------------------------------------------------------------------------
27 static constexpr OptionDefinition g_settings_set_options[] = {
29 { LLDB_OPT_SET_2, false, "global", 'g', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Apply the new value to the global default value." },
30 { LLDB_OPT_SET_2, false, "force", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Force an empty value to be accepted as the default." }
34 class CommandObjectSettingsSet : public CommandObjectRaw {
36 CommandObjectSettingsSet(CommandInterpreter &interpreter)
37 : CommandObjectRaw(interpreter, "settings set",
38 "Set the value of the specified debugger setting."),
40 CommandArgumentEntry arg1;
41 CommandArgumentEntry arg2;
42 CommandArgumentData var_name_arg;
43 CommandArgumentData value_arg;
45 // Define the first (and only) variant of this arg.
46 var_name_arg.arg_type = eArgTypeSettingVariableName;
47 var_name_arg.arg_repetition = eArgRepeatPlain;
49 // There is only one variant this argument could be; put it into the
51 arg1.push_back(var_name_arg);
53 // Define the first (and only) variant of this arg.
54 value_arg.arg_type = eArgTypeValue;
55 value_arg.arg_repetition = eArgRepeatPlain;
57 // There is only one variant this argument could be; put it into the
59 arg2.push_back(value_arg);
61 // Push the data for the first argument into the m_arguments vector.
62 m_arguments.push_back(arg1);
63 m_arguments.push_back(arg2);
66 "\nWhen setting a dictionary or array variable, you can set multiple entries \
67 at once by giving the values to the set command. For example:"
70 (lldb) settings set target.run-args value1 value2 value3
71 (lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345
73 (lldb) settings show target.run-args
77 (lldb) settings show target.env-vars
82 "Warning: The 'set' command re-sets the entire array or dictionary. If you \
83 just want to add, remove or update individual values (or add something to \
84 the end), use one of the other settings sub-commands: append, replace, \
85 insert-before or insert-after.");
88 ~CommandObjectSettingsSet() override = default;
90 // Overrides base class's behavior where WantsCompletion =
91 // !WantsRawCommandString.
92 bool WantsCompletion() override { return true; }
94 Options *GetOptions() override { return &m_options; }
96 class CommandOptions : public Options {
98 CommandOptions() : Options(), m_global(false) {}
100 ~CommandOptions() override = default;
102 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
103 ExecutionContext *execution_context) override {
105 const int short_option = m_getopt_table[option_idx].val;
107 switch (short_option) {
115 error.SetErrorStringWithFormat("unrecognized options '%c'",
123 void OptionParsingStarting(ExecutionContext *execution_context) override {
128 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
129 return llvm::makeArrayRef(g_settings_set_options);
132 // Instance variables to hold the values for command options.
137 int HandleArgumentCompletion(
138 CompletionRequest &request,
139 OptionElementVector &opt_element_vector) override {
141 const size_t argc = request.GetParsedLine().GetArgumentCount();
142 const char *arg = nullptr;
144 for (setting_var_idx = 0; setting_var_idx < static_cast<int>(argc);
146 arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
147 if (arg && arg[0] != '-')
148 break; // We found our setting variable name index
150 if (request.GetCursorIndex() == setting_var_idx) {
151 // Attempting to complete setting variable name
152 CommandCompletions::InvokeCommonCompletionCallbacks(
153 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
157 request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
161 // Complete option name
163 // Complete setting value
164 const char *setting_var_name =
165 request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
167 lldb::OptionValueSP value_sp(
168 m_interpreter.GetDebugger().GetPropertyValue(
169 &m_exe_ctx, setting_var_name, false, error));
171 value_sp->AutoComplete(m_interpreter, request);
176 return request.GetNumberOfMatches();
180 bool DoExecute(llvm::StringRef command,
181 CommandReturnObject &result) override {
182 Args cmd_args(command);
184 // Process possible options.
185 if (!ParseOptions(cmd_args, result))
188 const size_t min_argc = m_options.m_force ? 1 : 2;
189 const size_t argc = cmd_args.GetArgumentCount();
191 if ((argc < min_argc) && (!m_options.m_global)) {
192 result.AppendError("'settings set' takes more arguments");
193 result.SetStatus(eReturnStatusFailed);
197 const char *var_name = cmd_args.GetArgumentAtIndex(0);
198 if ((var_name == nullptr) || (var_name[0] == '\0')) {
200 "'settings set' command requires a valid variable name");
201 result.SetStatus(eReturnStatusFailed);
205 // A missing value corresponds to clearing the setting when "force" is
207 if (argc == 1 && m_options.m_force) {
208 Status error(m_interpreter.GetDebugger().SetPropertyValue(
209 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
211 result.AppendError(error.AsCString());
212 result.SetStatus(eReturnStatusFailed);
215 return result.Succeeded();
218 // Split the raw command into var_name and value pair.
219 llvm::StringRef raw_str(command);
220 std::string var_value_string = raw_str.split(var_name).second.str();
221 const char *var_value_cstr =
222 Args::StripSpaces(var_value_string, true, false, false);
225 if (m_options.m_global) {
226 error = m_interpreter.GetDebugger().SetPropertyValue(
227 nullptr, eVarSetOperationAssign, var_name, var_value_cstr);
230 if (error.Success()) {
231 // FIXME this is the same issue as the one in commands script import
232 // we could be setting target.load-script-from-symbol-file which would
233 // cause Python scripts to be loaded, which could run LLDB commands (e.g.
234 // settings set target.process.python-os-plugin-path) and cause a crash
235 // if we did not clear the command's exe_ctx first
236 ExecutionContext exe_ctx(m_exe_ctx);
238 error = m_interpreter.GetDebugger().SetPropertyValue(
239 &exe_ctx, eVarSetOperationAssign, var_name, var_value_cstr);
243 result.AppendError(error.AsCString());
244 result.SetStatus(eReturnStatusFailed);
247 result.SetStatus(eReturnStatusSuccessFinishResult);
250 return result.Succeeded();
254 CommandOptions m_options;
257 //-------------------------------------------------------------------------
258 // CommandObjectSettingsShow -- Show current values
259 //-------------------------------------------------------------------------
261 class CommandObjectSettingsShow : public CommandObjectParsed {
263 CommandObjectSettingsShow(CommandInterpreter &interpreter)
264 : CommandObjectParsed(interpreter, "settings show",
265 "Show matching debugger settings and their current "
266 "values. Defaults to showing all settings.",
268 CommandArgumentEntry arg1;
269 CommandArgumentData var_name_arg;
271 // Define the first (and only) variant of this arg.
272 var_name_arg.arg_type = eArgTypeSettingVariableName;
273 var_name_arg.arg_repetition = eArgRepeatOptional;
275 // There is only one variant this argument could be; put it into the
277 arg1.push_back(var_name_arg);
279 // Push the data for the first argument into the m_arguments vector.
280 m_arguments.push_back(arg1);
283 ~CommandObjectSettingsShow() override = default;
285 int HandleArgumentCompletion(
286 CompletionRequest &request,
287 OptionElementVector &opt_element_vector) override {
288 CommandCompletions::InvokeCommonCompletionCallbacks(
289 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
291 return request.GetNumberOfMatches();
295 bool DoExecute(Args &args, CommandReturnObject &result) override {
296 result.SetStatus(eReturnStatusSuccessFinishResult);
299 for (const auto &arg : args) {
300 Status error(m_interpreter.GetDebugger().DumpPropertyValue(
301 &m_exe_ctx, result.GetOutputStream(), arg.ref,
302 OptionValue::eDumpGroupValue));
303 if (error.Success()) {
304 result.GetOutputStream().EOL();
306 result.AppendError(error.AsCString());
307 result.SetStatus(eReturnStatusFailed);
311 m_interpreter.GetDebugger().DumpAllPropertyValues(
312 &m_exe_ctx, result.GetOutputStream(), OptionValue::eDumpGroupValue);
315 return result.Succeeded();
319 //-------------------------------------------------------------------------
320 // CommandObjectSettingsWrite -- Write settings to file
321 //-------------------------------------------------------------------------
323 static constexpr OptionDefinition g_settings_write_options[] = {
325 { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file into which to write the settings." },
326 { LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append to saved settings file if it exists."},
330 class CommandObjectSettingsWrite : public CommandObjectParsed {
332 CommandObjectSettingsWrite(CommandInterpreter &interpreter)
333 : CommandObjectParsed(
334 interpreter, "settings export",
335 "Write matching debugger settings and their "
336 "current values to a file that can be read in with "
337 "\"settings read\". Defaults to writing all settings.",
340 CommandArgumentEntry arg1;
341 CommandArgumentData var_name_arg;
343 // Define the first (and only) variant of this arg.
344 var_name_arg.arg_type = eArgTypeSettingVariableName;
345 var_name_arg.arg_repetition = eArgRepeatOptional;
347 // There is only one variant this argument could be; put it into the
349 arg1.push_back(var_name_arg);
351 // Push the data for the first argument into the m_arguments vector.
352 m_arguments.push_back(arg1);
355 ~CommandObjectSettingsWrite() override = default;
357 Options *GetOptions() override { return &m_options; }
359 class CommandOptions : public Options {
361 CommandOptions() : Options() {}
363 ~CommandOptions() override = default;
365 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
366 ExecutionContext *execution_context) override {
368 const int short_option = m_getopt_table[option_idx].val;
370 switch (short_option) {
372 m_filename.assign(option_arg);
378 error.SetErrorStringWithFormat("unrecognized option '%c'",
386 void OptionParsingStarting(ExecutionContext *execution_context) override {
391 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
392 return llvm::makeArrayRef(g_settings_write_options);
395 // Instance variables to hold the values for command options.
396 std::string m_filename;
397 bool m_append = false;
401 bool DoExecute(Args &args, CommandReturnObject &result) override {
402 FileSpec file_spec(m_options.m_filename);
403 FileSystem::Instance().Resolve(file_spec);
404 std::string path(file_spec.GetPath());
405 uint32_t options = File::OpenOptions::eOpenOptionWrite |
406 File::OpenOptions::eOpenOptionCanCreate;
407 if (m_options.m_append)
408 options |= File::OpenOptions::eOpenOptionAppend;
410 options |= File::OpenOptions::eOpenOptionTruncate;
412 StreamFile out_file(path.c_str(), options,
413 lldb::eFilePermissionsFileDefault);
415 if (!out_file.GetFile().IsValid()) {
416 result.AppendErrorWithFormat("%s: unable to write to file", path.c_str());
417 result.SetStatus(eReturnStatusFailed);
421 // Exporting should not be context sensitive.
422 ExecutionContext clean_ctx;
425 m_interpreter.GetDebugger().DumpAllPropertyValues(
426 &clean_ctx, out_file, OptionValue::eDumpGroupExport);
427 return result.Succeeded();
430 for (const auto &arg : args) {
431 Status error(m_interpreter.GetDebugger().DumpPropertyValue(
432 &clean_ctx, out_file, arg.ref, OptionValue::eDumpGroupExport));
433 if (!error.Success()) {
434 result.AppendError(error.AsCString());
435 result.SetStatus(eReturnStatusFailed);
439 return result.Succeeded();
443 CommandOptions m_options;
446 //-------------------------------------------------------------------------
447 // CommandObjectSettingsRead -- Read settings from file
448 //-------------------------------------------------------------------------
450 static constexpr OptionDefinition g_settings_read_options[] = {
452 {LLDB_OPT_SET_ALL, true, "file",'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file from which to read the breakpoints." },
456 class CommandObjectSettingsRead : public CommandObjectParsed {
458 CommandObjectSettingsRead(CommandInterpreter &interpreter)
459 : CommandObjectParsed(
460 interpreter, "settings read",
461 "Read settings previously saved to a file with \"settings write\".",
465 ~CommandObjectSettingsRead() override = default;
467 Options *GetOptions() override { return &m_options; }
469 class CommandOptions : public Options {
471 CommandOptions() : Options() {}
473 ~CommandOptions() override = default;
475 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
476 ExecutionContext *execution_context) override {
478 const int short_option = m_getopt_table[option_idx].val;
480 switch (short_option) {
482 m_filename.assign(option_arg);
485 error.SetErrorStringWithFormat("unrecognized option '%c'",
493 void OptionParsingStarting(ExecutionContext *execution_context) override {
497 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
498 return llvm::makeArrayRef(g_settings_read_options);
501 // Instance variables to hold the values for command options.
502 std::string m_filename;
506 bool DoExecute(Args &command, CommandReturnObject &result) override {
507 FileSpec file(m_options.m_filename);
508 FileSystem::Instance().Resolve(file);
509 ExecutionContext clean_ctx;
510 CommandInterpreterRunOptions options;
511 options.SetAddToHistory(false);
512 options.SetEchoCommands(false);
513 options.SetPrintResults(true);
514 options.SetStopOnError(false);
515 m_interpreter.HandleCommandsFromFile(file, &clean_ctx, options, result);
516 return result.Succeeded();
520 CommandOptions m_options;
523 //-------------------------------------------------------------------------
524 // CommandObjectSettingsList -- List settable variables
525 //-------------------------------------------------------------------------
527 class CommandObjectSettingsList : public CommandObjectParsed {
529 CommandObjectSettingsList(CommandInterpreter &interpreter)
530 : CommandObjectParsed(interpreter, "settings list",
531 "List and describe matching debugger settings. "
532 "Defaults to all listing all settings.",
534 CommandArgumentEntry arg;
535 CommandArgumentData var_name_arg;
536 CommandArgumentData prefix_name_arg;
538 // Define the first variant of this arg.
539 var_name_arg.arg_type = eArgTypeSettingVariableName;
540 var_name_arg.arg_repetition = eArgRepeatOptional;
542 // Define the second variant of this arg.
543 prefix_name_arg.arg_type = eArgTypeSettingPrefix;
544 prefix_name_arg.arg_repetition = eArgRepeatOptional;
546 arg.push_back(var_name_arg);
547 arg.push_back(prefix_name_arg);
549 // Push the data for the first argument into the m_arguments vector.
550 m_arguments.push_back(arg);
553 ~CommandObjectSettingsList() override = default;
555 int HandleArgumentCompletion(
556 CompletionRequest &request,
557 OptionElementVector &opt_element_vector) override {
558 CommandCompletions::InvokeCommonCompletionCallbacks(
559 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
561 return request.GetNumberOfMatches();
565 bool DoExecute(Args &args, CommandReturnObject &result) override {
566 result.SetStatus(eReturnStatusSuccessFinishResult);
568 const bool will_modify = false;
569 const size_t argc = args.GetArgumentCount();
571 const bool dump_qualified_name = true;
573 // TODO: Convert to StringRef based enumeration. Requires converting
574 // GetPropertyAtPath first.
575 for (size_t i = 0; i < argc; ++i) {
576 const char *property_path = args.GetArgumentAtIndex(i);
578 const Property *property =
579 m_interpreter.GetDebugger().GetValueProperties()->GetPropertyAtPath(
580 &m_exe_ctx, will_modify, property_path);
583 property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
584 dump_qualified_name);
586 result.AppendErrorWithFormat("invalid property path '%s'",
588 result.SetStatus(eReturnStatusFailed);
592 m_interpreter.GetDebugger().DumpAllDescriptions(m_interpreter,
593 result.GetOutputStream());
596 return result.Succeeded();
600 //-------------------------------------------------------------------------
601 // CommandObjectSettingsRemove
602 //-------------------------------------------------------------------------
604 class CommandObjectSettingsRemove : public CommandObjectRaw {
606 CommandObjectSettingsRemove(CommandInterpreter &interpreter)
607 : CommandObjectRaw(interpreter, "settings remove",
608 "Remove a value from a setting, specified by array "
609 "index or dictionary key.") {
610 CommandArgumentEntry arg1;
611 CommandArgumentEntry arg2;
612 CommandArgumentData var_name_arg;
613 CommandArgumentData index_arg;
614 CommandArgumentData key_arg;
616 // Define the first (and only) variant of this arg.
617 var_name_arg.arg_type = eArgTypeSettingVariableName;
618 var_name_arg.arg_repetition = eArgRepeatPlain;
620 // There is only one variant this argument could be; put it into the
622 arg1.push_back(var_name_arg);
624 // Define the first variant of this arg.
625 index_arg.arg_type = eArgTypeSettingIndex;
626 index_arg.arg_repetition = eArgRepeatPlain;
628 // Define the second variant of this arg.
629 key_arg.arg_type = eArgTypeSettingKey;
630 key_arg.arg_repetition = eArgRepeatPlain;
632 // Push both variants into this arg
633 arg2.push_back(index_arg);
634 arg2.push_back(key_arg);
636 // Push the data for the first argument into the m_arguments vector.
637 m_arguments.push_back(arg1);
638 m_arguments.push_back(arg2);
641 ~CommandObjectSettingsRemove() override = default;
643 int HandleArgumentCompletion(
644 CompletionRequest &request,
645 OptionElementVector &opt_element_vector) override {
646 if (request.GetCursorIndex() < 2)
647 CommandCompletions::InvokeCommonCompletionCallbacks(
648 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
650 return request.GetNumberOfMatches();
654 bool DoExecute(llvm::StringRef command,
655 CommandReturnObject &result) override {
656 result.SetStatus(eReturnStatusSuccessFinishNoResult);
658 Args cmd_args(command);
660 // Process possible options.
661 if (!ParseOptions(cmd_args, result))
664 const size_t argc = cmd_args.GetArgumentCount();
666 result.AppendError("'settings set' takes an array or dictionary item, or "
667 "an array followed by one or more indexes, or a "
668 "dictionary followed by one or more key names to "
670 result.SetStatus(eReturnStatusFailed);
674 const char *var_name = cmd_args.GetArgumentAtIndex(0);
675 if ((var_name == nullptr) || (var_name[0] == '\0')) {
677 "'settings set' command requires a valid variable name");
678 result.SetStatus(eReturnStatusFailed);
682 // Split the raw command into var_name and value pair.
683 llvm::StringRef raw_str(command);
684 std::string var_value_string = raw_str.split(var_name).second.str();
685 const char *var_value_cstr =
686 Args::StripSpaces(var_value_string, true, true, false);
688 Status error(m_interpreter.GetDebugger().SetPropertyValue(
689 &m_exe_ctx, eVarSetOperationRemove, var_name, var_value_cstr));
691 result.AppendError(error.AsCString());
692 result.SetStatus(eReturnStatusFailed);
696 return result.Succeeded();
700 //-------------------------------------------------------------------------
701 // CommandObjectSettingsReplace
702 //-------------------------------------------------------------------------
704 class CommandObjectSettingsReplace : public CommandObjectRaw {
706 CommandObjectSettingsReplace(CommandInterpreter &interpreter)
707 : CommandObjectRaw(interpreter, "settings replace",
708 "Replace the debugger setting value specified by "
709 "array index or dictionary key.") {
710 CommandArgumentEntry arg1;
711 CommandArgumentEntry arg2;
712 CommandArgumentEntry arg3;
713 CommandArgumentData var_name_arg;
714 CommandArgumentData index_arg;
715 CommandArgumentData key_arg;
716 CommandArgumentData value_arg;
718 // Define the first (and only) variant of this arg.
719 var_name_arg.arg_type = eArgTypeSettingVariableName;
720 var_name_arg.arg_repetition = eArgRepeatPlain;
722 // There is only one variant this argument could be; put it into the
724 arg1.push_back(var_name_arg);
726 // Define the first (variant of this arg.
727 index_arg.arg_type = eArgTypeSettingIndex;
728 index_arg.arg_repetition = eArgRepeatPlain;
730 // Define the second (variant of this arg.
731 key_arg.arg_type = eArgTypeSettingKey;
732 key_arg.arg_repetition = eArgRepeatPlain;
734 // Put both variants into this arg
735 arg2.push_back(index_arg);
736 arg2.push_back(key_arg);
738 // Define the first (and only) variant of this arg.
739 value_arg.arg_type = eArgTypeValue;
740 value_arg.arg_repetition = eArgRepeatPlain;
742 // There is only one variant this argument could be; put it into the
744 arg3.push_back(value_arg);
746 // Push the data for the first argument into the m_arguments vector.
747 m_arguments.push_back(arg1);
748 m_arguments.push_back(arg2);
749 m_arguments.push_back(arg3);
752 ~CommandObjectSettingsReplace() override = default;
754 // Overrides base class's behavior where WantsCompletion =
755 // !WantsRawCommandString.
756 bool WantsCompletion() override { return true; }
758 int HandleArgumentCompletion(
759 CompletionRequest &request,
760 OptionElementVector &opt_element_vector) override {
761 // Attempting to complete variable name
762 if (request.GetCursorIndex() < 2)
763 CommandCompletions::InvokeCommonCompletionCallbacks(
764 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
767 return request.GetNumberOfMatches();
771 bool DoExecute(llvm::StringRef command,
772 CommandReturnObject &result) override {
773 result.SetStatus(eReturnStatusSuccessFinishNoResult);
775 Args cmd_args(command);
776 const char *var_name = cmd_args.GetArgumentAtIndex(0);
777 if ((var_name == nullptr) || (var_name[0] == '\0')) {
778 result.AppendError("'settings replace' command requires a valid variable "
779 "name; No value supplied");
780 result.SetStatus(eReturnStatusFailed);
784 // Split the raw command into var_name, index_value, and value triple.
785 llvm::StringRef raw_str(command);
786 std::string var_value_string = raw_str.split(var_name).second.str();
787 const char *var_value_cstr =
788 Args::StripSpaces(var_value_string, true, true, false);
790 Status error(m_interpreter.GetDebugger().SetPropertyValue(
791 &m_exe_ctx, eVarSetOperationReplace, var_name, var_value_cstr));
793 result.AppendError(error.AsCString());
794 result.SetStatus(eReturnStatusFailed);
797 result.SetStatus(eReturnStatusSuccessFinishNoResult);
800 return result.Succeeded();
804 //-------------------------------------------------------------------------
805 // CommandObjectSettingsInsertBefore
806 //-------------------------------------------------------------------------
808 class CommandObjectSettingsInsertBefore : public CommandObjectRaw {
810 CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
811 : CommandObjectRaw(interpreter, "settings insert-before",
812 "Insert one or more values into an debugger array "
813 "setting immediately before the specified element "
815 CommandArgumentEntry arg1;
816 CommandArgumentEntry arg2;
817 CommandArgumentEntry arg3;
818 CommandArgumentData var_name_arg;
819 CommandArgumentData index_arg;
820 CommandArgumentData value_arg;
822 // Define the first (and only) variant of this arg.
823 var_name_arg.arg_type = eArgTypeSettingVariableName;
824 var_name_arg.arg_repetition = eArgRepeatPlain;
826 // There is only one variant this argument could be; put it into the
828 arg1.push_back(var_name_arg);
830 // Define the first (variant of this arg.
831 index_arg.arg_type = eArgTypeSettingIndex;
832 index_arg.arg_repetition = eArgRepeatPlain;
834 // There is only one variant this argument could be; put it into the
836 arg2.push_back(index_arg);
838 // Define the first (and only) variant of this arg.
839 value_arg.arg_type = eArgTypeValue;
840 value_arg.arg_repetition = eArgRepeatPlain;
842 // There is only one variant this argument could be; put it into the
844 arg3.push_back(value_arg);
846 // Push the data for the first argument into the m_arguments vector.
847 m_arguments.push_back(arg1);
848 m_arguments.push_back(arg2);
849 m_arguments.push_back(arg3);
852 ~CommandObjectSettingsInsertBefore() override = default;
854 // Overrides base class's behavior where WantsCompletion =
855 // !WantsRawCommandString.
856 bool WantsCompletion() override { return true; }
858 int HandleArgumentCompletion(
859 CompletionRequest &request,
860 OptionElementVector &opt_element_vector) override {
861 // Attempting to complete variable name
862 if (request.GetCursorIndex() < 2)
863 CommandCompletions::InvokeCommonCompletionCallbacks(
864 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
867 return request.GetNumberOfMatches();
871 bool DoExecute(llvm::StringRef command,
872 CommandReturnObject &result) override {
873 result.SetStatus(eReturnStatusSuccessFinishNoResult);
875 Args cmd_args(command);
876 const size_t argc = cmd_args.GetArgumentCount();
879 result.AppendError("'settings insert-before' takes more arguments");
880 result.SetStatus(eReturnStatusFailed);
884 const char *var_name = cmd_args.GetArgumentAtIndex(0);
885 if ((var_name == nullptr) || (var_name[0] == '\0')) {
886 result.AppendError("'settings insert-before' command requires a valid "
887 "variable name; No value supplied");
888 result.SetStatus(eReturnStatusFailed);
892 // Split the raw command into var_name, index_value, and value triple.
893 llvm::StringRef raw_str(command);
894 std::string var_value_string = raw_str.split(var_name).second.str();
895 const char *var_value_cstr =
896 Args::StripSpaces(var_value_string, true, true, false);
898 Status error(m_interpreter.GetDebugger().SetPropertyValue(
899 &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value_cstr));
901 result.AppendError(error.AsCString());
902 result.SetStatus(eReturnStatusFailed);
906 return result.Succeeded();
910 //-------------------------------------------------------------------------
911 // CommandObjectSettingInsertAfter
912 //-------------------------------------------------------------------------
914 class CommandObjectSettingsInsertAfter : public CommandObjectRaw {
916 CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
917 : CommandObjectRaw(interpreter, "settings insert-after",
918 "Insert one or more values into a debugger array "
919 "settings after the specified element index.") {
920 CommandArgumentEntry arg1;
921 CommandArgumentEntry arg2;
922 CommandArgumentEntry arg3;
923 CommandArgumentData var_name_arg;
924 CommandArgumentData index_arg;
925 CommandArgumentData value_arg;
927 // Define the first (and only) variant of this arg.
928 var_name_arg.arg_type = eArgTypeSettingVariableName;
929 var_name_arg.arg_repetition = eArgRepeatPlain;
931 // There is only one variant this argument could be; put it into the
933 arg1.push_back(var_name_arg);
935 // Define the first (variant of this arg.
936 index_arg.arg_type = eArgTypeSettingIndex;
937 index_arg.arg_repetition = eArgRepeatPlain;
939 // There is only one variant this argument could be; put it into the
941 arg2.push_back(index_arg);
943 // Define the first (and only) variant of this arg.
944 value_arg.arg_type = eArgTypeValue;
945 value_arg.arg_repetition = eArgRepeatPlain;
947 // There is only one variant this argument could be; put it into the
949 arg3.push_back(value_arg);
951 // Push the data for the first argument into the m_arguments vector.
952 m_arguments.push_back(arg1);
953 m_arguments.push_back(arg2);
954 m_arguments.push_back(arg3);
957 ~CommandObjectSettingsInsertAfter() override = default;
959 // Overrides base class's behavior where WantsCompletion =
960 // !WantsRawCommandString.
961 bool WantsCompletion() override { return true; }
963 int HandleArgumentCompletion(
964 CompletionRequest &request,
965 OptionElementVector &opt_element_vector) override {
966 // Attempting to complete variable name
967 if (request.GetCursorIndex() < 2)
968 CommandCompletions::InvokeCommonCompletionCallbacks(
969 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
972 return request.GetNumberOfMatches();
976 bool DoExecute(llvm::StringRef command,
977 CommandReturnObject &result) override {
978 result.SetStatus(eReturnStatusSuccessFinishNoResult);
980 Args cmd_args(command);
981 const size_t argc = cmd_args.GetArgumentCount();
984 result.AppendError("'settings insert-after' takes more arguments");
985 result.SetStatus(eReturnStatusFailed);
989 const char *var_name = cmd_args.GetArgumentAtIndex(0);
990 if ((var_name == nullptr) || (var_name[0] == '\0')) {
991 result.AppendError("'settings insert-after' command requires a valid "
992 "variable name; No value supplied");
993 result.SetStatus(eReturnStatusFailed);
997 // Split the raw command into var_name, index_value, and value triple.
998 llvm::StringRef raw_str(command);
999 std::string var_value_string = raw_str.split(var_name).second.str();
1000 const char *var_value_cstr =
1001 Args::StripSpaces(var_value_string, true, true, false);
1003 Status error(m_interpreter.GetDebugger().SetPropertyValue(
1004 &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value_cstr));
1006 result.AppendError(error.AsCString());
1007 result.SetStatus(eReturnStatusFailed);
1011 return result.Succeeded();
1015 //-------------------------------------------------------------------------
1016 // CommandObjectSettingsAppend
1017 //-------------------------------------------------------------------------
1019 class CommandObjectSettingsAppend : public CommandObjectRaw {
1021 CommandObjectSettingsAppend(CommandInterpreter &interpreter)
1022 : CommandObjectRaw(interpreter, "settings append",
1023 "Append one or more values to a debugger array, "
1024 "dictionary, or string setting.") {
1025 CommandArgumentEntry arg1;
1026 CommandArgumentEntry arg2;
1027 CommandArgumentData var_name_arg;
1028 CommandArgumentData value_arg;
1030 // Define the first (and only) variant of this arg.
1031 var_name_arg.arg_type = eArgTypeSettingVariableName;
1032 var_name_arg.arg_repetition = eArgRepeatPlain;
1034 // There is only one variant this argument could be; put it into the
1036 arg1.push_back(var_name_arg);
1038 // Define the first (and only) variant of this arg.
1039 value_arg.arg_type = eArgTypeValue;
1040 value_arg.arg_repetition = eArgRepeatPlain;
1042 // There is only one variant this argument could be; put it into the
1044 arg2.push_back(value_arg);
1046 // Push the data for the first argument into the m_arguments vector.
1047 m_arguments.push_back(arg1);
1048 m_arguments.push_back(arg2);
1051 ~CommandObjectSettingsAppend() override = default;
1053 // Overrides base class's behavior where WantsCompletion =
1054 // !WantsRawCommandString.
1055 bool WantsCompletion() override { return true; }
1057 int HandleArgumentCompletion(
1058 CompletionRequest &request,
1059 OptionElementVector &opt_element_vector) override {
1060 // Attempting to complete variable name
1061 if (request.GetCursorIndex() < 2)
1062 CommandCompletions::InvokeCommonCompletionCallbacks(
1063 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
1066 return request.GetNumberOfMatches();
1070 bool DoExecute(llvm::StringRef command,
1071 CommandReturnObject &result) override {
1072 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1073 Args cmd_args(command);
1074 const size_t argc = cmd_args.GetArgumentCount();
1077 result.AppendError("'settings append' takes more arguments");
1078 result.SetStatus(eReturnStatusFailed);
1082 const char *var_name = cmd_args.GetArgumentAtIndex(0);
1083 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1084 result.AppendError("'settings append' command requires a valid variable "
1085 "name; No value supplied");
1086 result.SetStatus(eReturnStatusFailed);
1090 // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
1091 // character string later on.
1093 // Split the raw command into var_name and value pair.
1094 llvm::StringRef raw_str(command);
1095 std::string var_value_string = raw_str.split(var_name).second.str();
1096 const char *var_value_cstr =
1097 Args::StripSpaces(var_value_string, true, true, false);
1099 Status error(m_interpreter.GetDebugger().SetPropertyValue(
1100 &m_exe_ctx, eVarSetOperationAppend, var_name, var_value_cstr));
1102 result.AppendError(error.AsCString());
1103 result.SetStatus(eReturnStatusFailed);
1107 return result.Succeeded();
1111 //-------------------------------------------------------------------------
1112 // CommandObjectSettingsClear
1113 //-------------------------------------------------------------------------
1115 class CommandObjectSettingsClear : public CommandObjectParsed {
1117 CommandObjectSettingsClear(CommandInterpreter &interpreter)
1118 : CommandObjectParsed(
1119 interpreter, "settings clear",
1120 "Clear a debugger setting array, dictionary, or string.", nullptr) {
1121 CommandArgumentEntry arg;
1122 CommandArgumentData var_name_arg;
1124 // Define the first (and only) variant of this arg.
1125 var_name_arg.arg_type = eArgTypeSettingVariableName;
1126 var_name_arg.arg_repetition = eArgRepeatPlain;
1128 // There is only one variant this argument could be; put it into the
1130 arg.push_back(var_name_arg);
1132 // Push the data for the first argument into the m_arguments vector.
1133 m_arguments.push_back(arg);
1136 ~CommandObjectSettingsClear() override = default;
1138 int HandleArgumentCompletion(
1139 CompletionRequest &request,
1140 OptionElementVector &opt_element_vector) override {
1141 // Attempting to complete variable name
1142 if (request.GetCursorIndex() < 2)
1143 CommandCompletions::InvokeCommonCompletionCallbacks(
1144 GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
1147 return request.GetNumberOfMatches();
1151 bool DoExecute(Args &command, CommandReturnObject &result) override {
1152 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1153 const size_t argc = command.GetArgumentCount();
1156 result.AppendError("'settings clear' takes exactly one argument");
1157 result.SetStatus(eReturnStatusFailed);
1161 const char *var_name = command.GetArgumentAtIndex(0);
1162 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1163 result.AppendError("'settings clear' command requires a valid variable "
1164 "name; No value supplied");
1165 result.SetStatus(eReturnStatusFailed);
1169 Status error(m_interpreter.GetDebugger().SetPropertyValue(
1170 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
1172 result.AppendError(error.AsCString());
1173 result.SetStatus(eReturnStatusFailed);
1177 return result.Succeeded();
1181 //-------------------------------------------------------------------------
1182 // CommandObjectMultiwordSettings
1183 //-------------------------------------------------------------------------
1185 CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
1186 CommandInterpreter &interpreter)
1187 : CommandObjectMultiword(interpreter, "settings",
1188 "Commands for managing LLDB settings.",
1189 "settings <subcommand> [<command-options>]") {
1190 LoadSubCommand("set",
1191 CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
1192 LoadSubCommand("show",
1193 CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
1194 LoadSubCommand("list",
1195 CommandObjectSP(new CommandObjectSettingsList(interpreter)));
1196 LoadSubCommand("remove",
1197 CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
1198 LoadSubCommand("replace", CommandObjectSP(
1199 new CommandObjectSettingsReplace(interpreter)));
1202 CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
1205 CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
1206 LoadSubCommand("append",
1207 CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
1208 LoadSubCommand("clear",
1209 CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
1210 LoadSubCommand("write",
1211 CommandObjectSP(new CommandObjectSettingsWrite(interpreter)));
1212 LoadSubCommand("read",
1213 CommandObjectSP(new CommandObjectSettingsRead(interpreter)));
1216 CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default;