LLDB mainline
CommandObjectSettings.cpp
Go to the documentation of this file.
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//===----------------------------------------------------------------------===//
8
10
11#include "llvm/ADT/StringRef.h"
12
19
20using namespace lldb;
21using namespace lldb_private;
22
23// CommandObjectSettingsSet
24#define LLDB_OPTIONS_settings_set
25#include "CommandOptions.inc"
26
28public:
30 : CommandObjectRaw(interpreter, "settings set",
31 "Set the value of the specified debugger setting.") {
34 CommandArgumentData var_name_arg;
35 CommandArgumentData value_arg;
36
37 // Define the first (and only) variant of this arg.
39 var_name_arg.arg_repetition = eArgRepeatPlain;
40
41 // There is only one variant this argument could be; put it into the
42 // argument entry.
43 arg1.push_back(var_name_arg);
44
45 // Define the first (and only) variant of this arg.
46 value_arg.arg_type = eArgTypeValue;
48
49 // There is only one variant this argument could be; put it into the
50 // argument entry.
51 arg2.push_back(value_arg);
52
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);
56
58 "\nWhen setting a dictionary or array variable, you can set multiple entries \
59at once by giving the values to the set command. For example:"
60 R"(
61
62(lldb) settings set target.run-args value1 value2 value3
63(lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345
64
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'
72
73)"
74 "Warning: The 'set' command re-sets the entire array or dictionary. If you \
75just want to add, remove or update individual values (or add something to \
76the end), use one of the other settings sub-commands: append, replace, \
77insert-before or insert-after.");
78 }
80 ~CommandObjectSettingsSet() override = default;
82 // Overrides base class's behavior where WantsCompletion =
83 // !WantsRawCommandString.
84 bool WantsCompletion() override { return true; }
85
86 Options *GetOptions() override { return &m_options; }
87
88 class CommandOptions : public Options {
89 public:
90 CommandOptions() = default;
91
92 ~CommandOptions() override = default;
93
94 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
95 ExecutionContext *execution_context) override {
97 const int short_option = m_getopt_table[option_idx].val;
98
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");
111 }
112
113 return error;
116 void OptionParsingStarting(ExecutionContext *execution_context) override {
117 m_global = false;
118 m_force = false;
119 m_exists = false;
121
122 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
123 return llvm::ArrayRef(g_settings_set_options);
124 }
125
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;
130 };
131
132 void
134 OptionElementVector &opt_element_vector) override {
135
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
143 }
144 if (request.GetCursorIndex() == setting_var_idx) {
145 // Attempting to complete setting variable name
148 nullptr);
149 return;
150 }
151 arg = request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
152
153 if (!arg)
154 return;
155
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);
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);
169 }
170
171protected:
172 bool DoExecute(llvm::StringRef command,
173 CommandReturnObject &result) override {
174 Args cmd_args(command);
175
176 // Process possible options.
177 if (!ParseOptions(cmd_args, result))
178 return false;
179
180 const size_t min_argc = m_options.m_force ? 1 : 2;
181 const size_t argc = cmd_args.GetArgumentCount();
182
183 if ((argc < min_argc) && (!m_options.m_global)) {
184 result.AppendError("'settings set' takes more arguments");
185 return false;
186 }
187
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 false;
193 }
194
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());
202 return false;
203 }
204 return result.Succeeded();
205 }
206
207 // Split the raw command into var_name and value pair.
208 llvm::StringRef var_value(command);
209 var_value = var_value.split(var_name).second.ltrim();
210
214 var_name, var_value);
215
216 if (error.Success()) {
217 // FIXME this is the same issue as the one in commands script import
218 // we could be setting target.load-script-from-symbol-file which would
219 // cause Python scripts to be loaded, which could run LLDB commands (e.g.
220 // settings set target.process.python-os-plugin-path) and cause a crash
221 // if we did not clear the command's exe_ctx first
225 var_name, var_value);
226 }
227
228 if (error.Fail() && !m_options.m_exists) {
229 result.AppendError(error.AsCString());
230 return false;
231 }
232
234 return result.Succeeded();
235 }
236
237private:
238 CommandOptions m_options;
239};
240
241// CommandObjectSettingsShow -- Show current values
242
244public:
246 : CommandObjectParsed(interpreter, "settings show",
247 "Show matching debugger settings and their current "
248 "values. Defaults to showing all settings.",
249 nullptr) {
251 CommandArgumentData var_name_arg;
252
253 // Define the first (and only) variant of this arg.
255 var_name_arg.arg_repetition = eArgRepeatOptional;
256
257 // There is only one variant this argument could be; put it into the
258 // argument entry.
259 arg1.push_back(var_name_arg);
260
261 // Push the data for the first argument into the m_arguments vector.
262 m_arguments.push_back(arg1);
263 }
264
265 ~CommandObjectSettingsShow() override = default;
266
267 void
269 OptionElementVector &opt_element_vector) override {
272 nullptr);
273 }
274
275protected:
276 bool DoExecute(Args &args, CommandReturnObject &result) override {
278
279 if (!args.empty()) {
280 for (const auto &arg : args) {
281 Status error(GetDebugger().DumpPropertyValue(
282 &m_exe_ctx, result.GetOutputStream(), arg.ref(),
284 if (error.Success()) {
285 result.GetOutputStream().EOL();
286 } else {
287 result.AppendError(error.AsCString());
288 }
289 }
290 } else {
293 }
294
295 return result.Succeeded();
296 }
297};
298
299// CommandObjectSettingsWrite -- Write settings to file
300#define LLDB_OPTIONS_settings_write
301#include "CommandOptions.inc"
302
304public:
307 interpreter, "settings export",
308 "Write matching debugger settings and their "
309 "current values to a file that can be read in with "
310 "\"settings read\". Defaults to writing all settings.",
311 nullptr) {
313 CommandArgumentData var_name_arg;
314
315 // Define the first (and only) variant of this arg.
317 var_name_arg.arg_repetition = eArgRepeatOptional;
318
319 // There is only one variant this argument could be; put it into the
320 // argument entry.
321 arg1.push_back(var_name_arg);
322
323 // Push the data for the first argument into the m_arguments vector.
324 m_arguments.push_back(arg1);
325 }
326
327 ~CommandObjectSettingsWrite() override = default;
328
329 Options *GetOptions() override { return &m_options; }
330
331 class CommandOptions : public Options {
332 public:
333 CommandOptions() = default;
334
335 ~CommandOptions() override = default;
336
337 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
338 ExecutionContext *execution_context) override {
340 const int short_option = m_getopt_table[option_idx].val;
341
342 switch (short_option) {
343 case 'f':
344 m_filename.assign(std::string(option_arg));
345 break;
346 case 'a':
347 m_append = true;
348 break;
349 default:
350 llvm_unreachable("Unimplemented option");
351 }
352
353 return error;
354 }
355
356 void OptionParsingStarting(ExecutionContext *execution_context) override {
357 m_filename.clear();
358 m_append = false;
359 }
360
361 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
362 return llvm::ArrayRef(g_settings_write_options);
363 }
364
365 // Instance variables to hold the values for command options.
366 std::string m_filename;
367 bool m_append = false;
368 };
369
370protected:
371 bool DoExecute(Args &args, CommandReturnObject &result) override {
372 FileSpec file_spec(m_options.m_filename);
373 FileSystem::Instance().Resolve(file_spec);
374 std::string path(file_spec.GetPath());
377 options |= File::eOpenOptionAppend;
378 else
379 options |= File::eOpenOptionTruncate;
380
381 StreamFile out_file(path.c_str(), options,
382 lldb::eFilePermissionsFileDefault);
383
384 if (!out_file.GetFile().IsValid()) {
385 result.AppendErrorWithFormat("%s: unable to write to file", path.c_str());
386 return false;
387 }
388
389 // Exporting should not be context sensitive.
390 ExecutionContext clean_ctx;
391
392 if (args.empty()) {
393 GetDebugger().DumpAllPropertyValues(&clean_ctx, out_file,
395 return result.Succeeded();
396 }
397
398 for (const auto &arg : args) {
399 Status error(GetDebugger().DumpPropertyValue(
400 &clean_ctx, out_file, arg.ref(), OptionValue::eDumpGroupExport));
401 if (!error.Success()) {
402 result.AppendError(error.AsCString());
403 }
404 }
405
406 return result.Succeeded();
407 }
408
409private:
411};
412
413// CommandObjectSettingsRead -- Read settings from file
414#define LLDB_OPTIONS_settings_read
415#include "CommandOptions.inc"
416
418public:
421 interpreter, "settings read",
422 "Read settings previously saved to a file with \"settings write\".",
423 nullptr) {}
424
425 ~CommandObjectSettingsRead() override = default;
426
427 Options *GetOptions() override { return &m_options; }
428
429 class CommandOptions : public Options {
430 public:
431 CommandOptions() = default;
432
433 ~CommandOptions() override = default;
434
435 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
436 ExecutionContext *execution_context) override {
438 const int short_option = m_getopt_table[option_idx].val;
439
440 switch (short_option) {
441 case 'f':
442 m_filename.assign(std::string(option_arg));
443 break;
444 default:
445 llvm_unreachable("Unimplemented option");
446 }
447
448 return error;
449 }
450
451 void OptionParsingStarting(ExecutionContext *execution_context) override {
452 m_filename.clear();
453 }
454
455 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
456 return llvm::ArrayRef(g_settings_read_options);
457 }
458
459 // Instance variables to hold the values for command options.
460 std::string m_filename;
461 };
462
463protected:
464 bool DoExecute(Args &command, CommandReturnObject &result) override {
468 options.SetAddToHistory(false);
469 options.SetEchoCommands(false);
470 options.SetPrintResults(true);
471 options.SetPrintErrors(true);
472 options.SetStopOnError(false);
473 m_interpreter.HandleCommandsFromFile(file, options, result);
474 return result.Succeeded();
475 }
476
477private:
479};
480
481// CommandObjectSettingsList -- List settable variables
482
484public:
486 : CommandObjectParsed(interpreter, "settings list",
487 "List and describe matching debugger settings. "
488 "Defaults to all listing all settings.",
489 nullptr) {
491 CommandArgumentData var_name_arg;
492 CommandArgumentData prefix_name_arg;
493
494 // Define the first variant of this arg.
496 var_name_arg.arg_repetition = eArgRepeatOptional;
497
498 // Define the second variant of this arg.
499 prefix_name_arg.arg_type = eArgTypeSettingPrefix;
500 prefix_name_arg.arg_repetition = eArgRepeatOptional;
501
502 arg.push_back(var_name_arg);
503 arg.push_back(prefix_name_arg);
504
505 // Push the data for the first argument into the m_arguments vector.
506 m_arguments.push_back(arg);
507 }
508
509 ~CommandObjectSettingsList() override = default;
510
511 void
513 OptionElementVector &opt_element_vector) override {
516 nullptr);
517 }
518
519protected:
520 bool DoExecute(Args &args, CommandReturnObject &result) override {
522
523 const size_t argc = args.GetArgumentCount();
524 if (argc > 0) {
525 const bool dump_qualified_name = true;
526
527 for (const Args::ArgEntry &arg : args) {
528 const char *property_path = arg.c_str();
529
530 const Property *property =
531 GetDebugger().GetValueProperties()->GetPropertyAtPath(
532 &m_exe_ctx, property_path);
533
534 if (property) {
535 property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
536 dump_qualified_name);
537 } else {
538 result.AppendErrorWithFormat("invalid property path '%s'",
539 property_path);
540 }
541 }
542 } else {
544 result.GetOutputStream());
545 }
546
547 return result.Succeeded();
548 }
549};
550
551// CommandObjectSettingsRemove
552
554public:
556 : CommandObjectRaw(interpreter, "settings remove",
557 "Remove a value from a setting, specified by array "
558 "index or dictionary key.") {
561 CommandArgumentData var_name_arg;
562 CommandArgumentData index_arg;
563 CommandArgumentData key_arg;
564
565 // Define the first (and only) variant of this arg.
567 var_name_arg.arg_repetition = eArgRepeatPlain;
568
569 // There is only one variant this argument could be; put it into the
570 // argument entry.
571 arg1.push_back(var_name_arg);
572
573 // Define the first variant of this arg.
574 index_arg.arg_type = eArgTypeSettingIndex;
576
577 // Define the second variant of this arg.
580
581 // Push both variants into this arg
582 arg2.push_back(index_arg);
583 arg2.push_back(key_arg);
584
585 // Push the data for the first argument into the m_arguments vector.
586 m_arguments.push_back(arg1);
587 m_arguments.push_back(arg2);
588 }
589
590 ~CommandObjectSettingsRemove() override = default;
591
592 bool WantsCompletion() override { return true; }
593
594 void
596 OptionElementVector &opt_element_vector) override {
597 if (request.GetCursorIndex() < 2)
600 nullptr);
601 }
602
603protected:
604 bool DoExecute(llvm::StringRef command,
605 CommandReturnObject &result) override {
607
608 Args cmd_args(command);
609
610 // Process possible options.
611 if (!ParseOptions(cmd_args, result))
612 return false;
613
614 const size_t argc = cmd_args.GetArgumentCount();
615 if (argc == 0) {
616 result.AppendError("'settings remove' takes an array or dictionary item, "
617 "or an array followed by one or more indexes, or a "
618 "dictionary followed by one or more key names to "
619 "remove");
620 return false;
621 }
622
623 const char *var_name = cmd_args.GetArgumentAtIndex(0);
624 if ((var_name == nullptr) || (var_name[0] == '\0')) {
625 result.AppendError(
626 "'settings remove' command requires a valid variable name");
627 return false;
628 }
629
630 // Split the raw command into var_name and value pair.
631 llvm::StringRef var_value(command);
632 var_value = var_value.split(var_name).second.trim();
633
634 Status error(GetDebugger().SetPropertyValue(
635 &m_exe_ctx, eVarSetOperationRemove, var_name, var_value));
636 if (error.Fail()) {
637 result.AppendError(error.AsCString());
638 return false;
639 }
640
641 return result.Succeeded();
642 }
643};
644
645// CommandObjectSettingsReplace
646
648public:
650 : CommandObjectRaw(interpreter, "settings replace",
651 "Replace the debugger setting value specified by "
652 "array index or dictionary key.") {
656 CommandArgumentData var_name_arg;
657 CommandArgumentData index_arg;
658 CommandArgumentData key_arg;
659 CommandArgumentData value_arg;
660
661 // Define the first (and only) variant of this arg.
663 var_name_arg.arg_repetition = eArgRepeatPlain;
664
665 // There is only one variant this argument could be; put it into the
666 // argument entry.
667 arg1.push_back(var_name_arg);
668
669 // Define the first (variant of this arg.
670 index_arg.arg_type = eArgTypeSettingIndex;
672
673 // Define the second (variant of this arg.
676
677 // Put both variants into this arg
678 arg2.push_back(index_arg);
679 arg2.push_back(key_arg);
680
681 // Define the first (and only) variant of this arg.
682 value_arg.arg_type = eArgTypeValue;
684
685 // There is only one variant this argument could be; put it into the
686 // argument entry.
687 arg3.push_back(value_arg);
688
689 // Push the data for the first argument into the m_arguments vector.
690 m_arguments.push_back(arg1);
691 m_arguments.push_back(arg2);
692 m_arguments.push_back(arg3);
693 }
694
695 ~CommandObjectSettingsReplace() override = default;
696
697 // Overrides base class's behavior where WantsCompletion =
698 // !WantsRawCommandString.
699 bool WantsCompletion() override { return true; }
700
701 void
703 OptionElementVector &opt_element_vector) override {
704 // Attempting to complete variable name
705 if (request.GetCursorIndex() < 2)
708 nullptr);
709 }
710
711protected:
712 bool DoExecute(llvm::StringRef command,
713 CommandReturnObject &result) override {
715
716 Args cmd_args(command);
717 const char *var_name = cmd_args.GetArgumentAtIndex(0);
718 if ((var_name == nullptr) || (var_name[0] == '\0')) {
719 result.AppendError("'settings replace' command requires a valid variable "
720 "name; No value supplied");
721 return false;
722 }
723
724 // Split the raw command into var_name, index_value, and value triple.
725 llvm::StringRef var_value(command);
726 var_value = var_value.split(var_name).second.trim();
727
728 Status error(GetDebugger().SetPropertyValue(
729 &m_exe_ctx, eVarSetOperationReplace, var_name, var_value));
730 if (error.Fail()) {
731 result.AppendError(error.AsCString());
732 return false;
733 } else {
735 }
736
737 return result.Succeeded();
738 }
739};
740
741// CommandObjectSettingsInsertBefore
742
744public:
746 : CommandObjectRaw(interpreter, "settings insert-before",
747 "Insert one or more values into an debugger array "
748 "setting immediately before the specified element "
749 "index.") {
753 CommandArgumentData var_name_arg;
754 CommandArgumentData index_arg;
755 CommandArgumentData value_arg;
756
757 // Define the first (and only) variant of this arg.
759 var_name_arg.arg_repetition = eArgRepeatPlain;
760
761 // There is only one variant this argument could be; put it into the
762 // argument entry.
763 arg1.push_back(var_name_arg);
764
765 // Define the first (variant of this arg.
766 index_arg.arg_type = eArgTypeSettingIndex;
768
769 // There is only one variant this argument could be; put it into the
770 // argument entry.
771 arg2.push_back(index_arg);
772
773 // Define the first (and only) variant of this arg.
774 value_arg.arg_type = eArgTypeValue;
776
777 // There is only one variant this argument could be; put it into the
778 // argument entry.
779 arg3.push_back(value_arg);
780
781 // Push the data for the first argument into the m_arguments vector.
782 m_arguments.push_back(arg1);
783 m_arguments.push_back(arg2);
784 m_arguments.push_back(arg3);
785 }
786
788
789 // Overrides base class's behavior where WantsCompletion =
790 // !WantsRawCommandString.
791 bool WantsCompletion() override { return true; }
792
793 void
795 OptionElementVector &opt_element_vector) override {
796 // Attempting to complete variable name
797 if (request.GetCursorIndex() < 2)
800 nullptr);
801 }
802
803protected:
804 bool DoExecute(llvm::StringRef command,
805 CommandReturnObject &result) override {
807
808 Args cmd_args(command);
809 const size_t argc = cmd_args.GetArgumentCount();
810
811 if (argc < 3) {
812 result.AppendError("'settings insert-before' takes more arguments");
813 return false;
814 }
815
816 const char *var_name = cmd_args.GetArgumentAtIndex(0);
817 if ((var_name == nullptr) || (var_name[0] == '\0')) {
818 result.AppendError("'settings insert-before' command requires a valid "
819 "variable name; No value supplied");
820 return false;
821 }
822
823 // Split the raw command into var_name, index_value, and value triple.
824 llvm::StringRef var_value(command);
825 var_value = var_value.split(var_name).second.trim();
826
827 Status error(GetDebugger().SetPropertyValue(
828 &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value));
829 if (error.Fail()) {
830 result.AppendError(error.AsCString());
831 return false;
832 }
833
834 return result.Succeeded();
835 }
836};
837
838// CommandObjectSettingInsertAfter
839
841public:
843 : CommandObjectRaw(interpreter, "settings insert-after",
844 "Insert one or more values into a debugger array "
845 "settings after the specified element index.") {
849 CommandArgumentData var_name_arg;
850 CommandArgumentData index_arg;
851 CommandArgumentData value_arg;
852
853 // Define the first (and only) variant of this arg.
855 var_name_arg.arg_repetition = eArgRepeatPlain;
856
857 // There is only one variant this argument could be; put it into the
858 // argument entry.
859 arg1.push_back(var_name_arg);
860
861 // Define the first (variant of this arg.
862 index_arg.arg_type = eArgTypeSettingIndex;
864
865 // There is only one variant this argument could be; put it into the
866 // argument entry.
867 arg2.push_back(index_arg);
868
869 // Define the first (and only) variant of this arg.
870 value_arg.arg_type = eArgTypeValue;
872
873 // There is only one variant this argument could be; put it into the
874 // argument entry.
875 arg3.push_back(value_arg);
876
877 // Push the data for the first argument into the m_arguments vector.
878 m_arguments.push_back(arg1);
879 m_arguments.push_back(arg2);
880 m_arguments.push_back(arg3);
881 }
882
884
885 // Overrides base class's behavior where WantsCompletion =
886 // !WantsRawCommandString.
887 bool WantsCompletion() override { return true; }
888
889 void
891 OptionElementVector &opt_element_vector) override {
892 // Attempting to complete variable name
893 if (request.GetCursorIndex() < 2)
896 nullptr);
897 }
898
899protected:
900 bool DoExecute(llvm::StringRef command,
901 CommandReturnObject &result) override {
903
904 Args cmd_args(command);
905 const size_t argc = cmd_args.GetArgumentCount();
906
907 if (argc < 3) {
908 result.AppendError("'settings insert-after' takes more arguments");
909 return false;
910 }
911
912 const char *var_name = cmd_args.GetArgumentAtIndex(0);
913 if ((var_name == nullptr) || (var_name[0] == '\0')) {
914 result.AppendError("'settings insert-after' command requires a valid "
915 "variable name; No value supplied");
916 return false;
917 }
918
919 // Split the raw command into var_name, index_value, and value triple.
920 llvm::StringRef var_value(command);
921 var_value = var_value.split(var_name).second.trim();
922
923 Status error(GetDebugger().SetPropertyValue(
924 &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value));
925 if (error.Fail()) {
926 result.AppendError(error.AsCString());
927 return false;
928 }
929
930 return result.Succeeded();
931 }
932};
933
934// CommandObjectSettingsAppend
935
937public:
939 : CommandObjectRaw(interpreter, "settings append",
940 "Append one or more values to a debugger array, "
941 "dictionary, or string setting.") {
944 CommandArgumentData var_name_arg;
945 CommandArgumentData value_arg;
946
947 // Define the first (and only) variant of this arg.
949 var_name_arg.arg_repetition = eArgRepeatPlain;
950
951 // There is only one variant this argument could be; put it into the
952 // argument entry.
953 arg1.push_back(var_name_arg);
954
955 // Define the first (and only) variant of this arg.
956 value_arg.arg_type = eArgTypeValue;
958
959 // There is only one variant this argument could be; put it into the
960 // argument entry.
961 arg2.push_back(value_arg);
962
963 // Push the data for the first argument into the m_arguments vector.
964 m_arguments.push_back(arg1);
965 m_arguments.push_back(arg2);
966 }
967
968 ~CommandObjectSettingsAppend() override = default;
969
970 // Overrides base class's behavior where WantsCompletion =
971 // !WantsRawCommandString.
972 bool WantsCompletion() override { return true; }
973
974 void
976 OptionElementVector &opt_element_vector) override {
977 // Attempting to complete variable name
978 if (request.GetCursorIndex() < 2)
981 nullptr);
982 }
983
984protected:
985 bool DoExecute(llvm::StringRef command,
986 CommandReturnObject &result) override {
988 Args cmd_args(command);
989 const size_t argc = cmd_args.GetArgumentCount();
990
991 if (argc < 2) {
992 result.AppendError("'settings append' takes more arguments");
993 return false;
994 }
995
996 const char *var_name = cmd_args.GetArgumentAtIndex(0);
997 if ((var_name == nullptr) || (var_name[0] == '\0')) {
998 result.AppendError("'settings append' command requires a valid variable "
999 "name; No value supplied");
1000 return false;
1001 }
1002
1003 // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
1004 // character string later on.
1005
1006 // Split the raw command into var_name and value pair.
1007 llvm::StringRef var_value(command);
1008 var_value = var_value.split(var_name).second.trim();
1009
1010 Status error(GetDebugger().SetPropertyValue(
1011 &m_exe_ctx, eVarSetOperationAppend, var_name, var_value));
1012 if (error.Fail()) {
1013 result.AppendError(error.AsCString());
1014 return false;
1015 }
1016
1017 return result.Succeeded();
1018 }
1019};
1020
1021// CommandObjectSettingsClear
1022#define LLDB_OPTIONS_settings_clear
1023#include "CommandOptions.inc"
1024
1026public:
1029 interpreter, "settings clear",
1030 "Clear a debugger setting array, dictionary, or string. "
1031 "If '-a' option is specified, it clears all settings.", nullptr) {
1033 CommandArgumentData var_name_arg;
1034
1035 // Define the first (and only) variant of this arg.
1037 var_name_arg.arg_repetition = eArgRepeatPlain;
1038
1039 // There is only one variant this argument could be; put it into the
1040 // argument entry.
1041 arg.push_back(var_name_arg);
1042
1043 // Push the data for the first argument into the m_arguments vector.
1044 m_arguments.push_back(arg);
1045 }
1046
1047 ~CommandObjectSettingsClear() override = default;
1048
1049 void
1051 OptionElementVector &opt_element_vector) override {
1052 // Attempting to complete variable name
1053 if (request.GetCursorIndex() < 2)
1056 nullptr);
1057 }
1058
1059 Options *GetOptions() override { return &m_options; }
1060
1061 class CommandOptions : public Options {
1062 public:
1063 CommandOptions() = default;
1064
1065 ~CommandOptions() override = default;
1066
1067 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1068 ExecutionContext *execution_context) override {
1069 const int short_option = m_getopt_table[option_idx].val;
1070 switch (short_option) {
1071 case 'a':
1072 m_clear_all = true;
1073 break;
1074 default:
1075 llvm_unreachable("Unimplemented option");
1076 }
1077 return Status();
1078 }
1079
1080 void OptionParsingStarting(ExecutionContext *execution_context) override {
1081 m_clear_all = false;
1082 }
1083
1084 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1085 return llvm::ArrayRef(g_settings_clear_options);
1086 }
1087
1088 bool m_clear_all = false;
1089 };
1090
1091protected:
1092 bool DoExecute(Args &command, CommandReturnObject &result) override {
1094 const size_t argc = command.GetArgumentCount();
1095
1096 if (m_options.m_clear_all) {
1097 if (argc != 0) {
1098 result.AppendError("'settings clear --all' doesn't take any arguments");
1099 return false;
1100 }
1101 GetDebugger().GetValueProperties()->Clear();
1102 return result.Succeeded();
1103 }
1104
1105 if (argc != 1) {
1106 result.AppendError("'settings clear' takes exactly one argument");
1107 return false;
1108 }
1109
1110 const char *var_name = command.GetArgumentAtIndex(0);
1111 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1112 result.AppendError("'settings clear' command requires a valid variable "
1113 "name; No value supplied");
1114 return false;
1115 }
1116
1117 Status error(GetDebugger().SetPropertyValue(
1118 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
1119 if (error.Fail()) {
1120 result.AppendError(error.AsCString());
1121 return false;
1122 }
1123
1124 return result.Succeeded();
1125 }
1126
1127 private:
1129};
1130
1131// CommandObjectMultiwordSettings
1132
1134 CommandInterpreter &interpreter)
1135 : CommandObjectMultiword(interpreter, "settings",
1136 "Commands for managing LLDB settings.",
1137 "settings <subcommand> [<command-options>]") {
1138 LoadSubCommand("set",
1139 CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
1140 LoadSubCommand("show",
1141 CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
1142 LoadSubCommand("list",
1143 CommandObjectSP(new CommandObjectSettingsList(interpreter)));
1144 LoadSubCommand("remove",
1145 CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
1146 LoadSubCommand("replace", CommandObjectSP(
1147 new CommandObjectSettingsReplace(interpreter)));
1149 "insert-before",
1150 CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
1152 "insert-after",
1153 CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
1154 LoadSubCommand("append",
1155 CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
1156 LoadSubCommand("clear",
1157 CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
1158 LoadSubCommand("write",
1159 CommandObjectSP(new CommandObjectSettingsWrite(interpreter)));
1160 LoadSubCommand("read",
1161 CommandObjectSP(new CommandObjectSettingsRead(interpreter)));
1162}
1163
static llvm::raw_ostream & error(Stream &strm)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
CommandObjectSettingsAppend(CommandInterpreter &interpreter)
~CommandObjectSettingsAppend() override=default
bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
bool DoExecute(Args &command, CommandReturnObject &result) override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
~CommandObjectSettingsClear() override=default
CommandObjectSettingsClear(CommandInterpreter &interpreter)
~CommandObjectSettingsInsertAfter() override=default
CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
~CommandObjectSettingsInsertBefore() override=default
bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override
CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
CommandObjectSettingsList(CommandInterpreter &interpreter)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
~CommandObjectSettingsList() override=default
bool DoExecute(Args &args, CommandReturnObject &result) override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
~CommandObjectSettingsRead() override=default
CommandObjectSettingsRead(CommandInterpreter &interpreter)
bool DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectSettingsRemove(CommandInterpreter &interpreter)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
~CommandObjectSettingsRemove() override=default
bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override
CommandObjectSettingsReplace(CommandInterpreter &interpreter)
~CommandObjectSettingsReplace() override=default
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override
Options * GetOptions() override
CommandObjectSettingsSet(CommandInterpreter &interpreter)
~CommandObjectSettingsSet() override=default
CommandObjectSettingsShow(CommandInterpreter &interpreter)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
bool DoExecute(Args &args, CommandReturnObject &result) override
~CommandObjectSettingsShow() override=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
~CommandObjectSettingsWrite() override=default
bool DoExecute(Args &args, CommandReturnObject &result) override
CommandObjectSettingsWrite(CommandInterpreter &interpreter)
A command line argument class.
Definition: Args.h:33
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition: Args.h:116
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Definition: Args.cpp:263
bool empty() const
Definition: Args.h:118
static bool InvokeCommonCompletionCallbacks(CommandInterpreter &interpreter, uint32_t completion_mask, lldb_private::CompletionRequest &request, SearchFilter *searcher)
void HandleCommandsFromFile(FileSpec &file, const ExecutionContext &context, const CommandInterpreterRunOptions &options, CommandReturnObject &result)
Execute a list of commands from a file.
CommandObjectMultiwordSettings(CommandInterpreter &interpreter)
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
std::vector< CommandArgumentData > CommandArgumentEntry
virtual void SetHelpLong(llvm::StringRef str)
ExecutionContext m_exe_ctx
std::vector< CommandArgumentEntry > m_arguments
CommandInterpreter & GetCommandInterpreter()
CommandInterpreter & m_interpreter
bool ParseOptions(Args &args, CommandReturnObject &result)
void void AppendError(llvm::StringRef in_string)
void SetStatus(lldb::ReturnStatus status)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
"lldb/Utility/ArgCompletionRequest.h"
const Args & GetParsedLine() const
Status SetPropertyValue(const ExecutionContext *exe_ctx, VarSetOperationType op, llvm::StringRef property_path, llvm::StringRef value) override
Definition: Debugger.cpp:200
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void Clear()
Clear the object's state.
A file utility class.
Definition: FileSpec.h:56
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:366
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
static FileSystem & Instance()
@ eOpenOptionWriteOnly
Definition: File.h:52
@ eOpenOptionAppend
Definition: File.h:54
@ eOpenOptionCanCreate
Definition: File.h:56
@ eOpenOptionTruncate
Definition: File.h:57
bool IsValid() const override
IsValid.
Definition: File.cpp:112
A command line option parsing protocol class.
Definition: Options.h:58
std::vector< Option > m_getopt_table
Definition: Options.h:198
virtual void DumpAllDescriptions(CommandInterpreter &interpreter, Stream &strm) const
virtual void DumpAllPropertyValues(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask, bool is_json=false)
virtual lldb::OptionValuePropertiesSP GetValueProperties() const
An error handling class.
Definition: Status.h:44
size_t EOL()
Output and End of Line character to the stream.
Definition: Stream.cpp:128
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
std::vector< OptionArgElement > OptionElementVector
Definition: Options.h:43
Definition: SBAddress.h:15
@ eSettingsNameCompletion
@ eReturnStatusSuccessFinishResult
@ eReturnStatusSuccessFinishNoResult
@ eArgTypeSettingKey
@ eArgTypeSettingPrefix
@ eArgTypeSettingIndex
@ eArgTypeSettingVariableName
Used to build individual command argument lists.
Definition: CommandObject.h:93