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 request, 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(GetDebugger().GetPropertyValue(
165 &m_exe_ctx, setting_var_name, false, 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 request, 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 request, nullptr);
517 }
518
519protected:
520 bool DoExecute(Args &args, CommandReturnObject &result) override {
522
523 const bool will_modify = false;
524 const size_t argc = args.GetArgumentCount();
525 if (argc > 0) {
526 const bool dump_qualified_name = true;
527
528 for (const Args::ArgEntry &arg : args) {
529 const char *property_path = arg.c_str();
530
531 const Property *property =
532 GetDebugger().GetValueProperties()->GetPropertyAtPath(
533 &m_exe_ctx, will_modify, property_path);
534
535 if (property) {
536 property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
537 dump_qualified_name);
538 } else {
539 result.AppendErrorWithFormat("invalid property path '%s'",
540 property_path);
541 }
542 }
543 } else {
545 result.GetOutputStream());
546 }
547
548 return result.Succeeded();
549 }
550};
551
552// CommandObjectSettingsRemove
553
555public:
557 : CommandObjectRaw(interpreter, "settings remove",
558 "Remove a value from a setting, specified by array "
559 "index or dictionary key.") {
562 CommandArgumentData var_name_arg;
563 CommandArgumentData index_arg;
564 CommandArgumentData key_arg;
565
566 // Define the first (and only) variant of this arg.
568 var_name_arg.arg_repetition = eArgRepeatPlain;
569
570 // There is only one variant this argument could be; put it into the
571 // argument entry.
572 arg1.push_back(var_name_arg);
573
574 // Define the first variant of this arg.
575 index_arg.arg_type = eArgTypeSettingIndex;
577
578 // Define the second variant of this arg.
581
582 // Push both variants into this arg
583 arg2.push_back(index_arg);
584 arg2.push_back(key_arg);
585
586 // Push the data for the first argument into the m_arguments vector.
587 m_arguments.push_back(arg1);
588 m_arguments.push_back(arg2);
589 }
590
591 ~CommandObjectSettingsRemove() override = default;
592
593 bool WantsCompletion() override { return true; }
594
595 void
597 OptionElementVector &opt_element_vector) override {
598 if (request.GetCursorIndex() < 2)
601 request, nullptr);
602 }
603
604protected:
605 bool DoExecute(llvm::StringRef command,
606 CommandReturnObject &result) override {
608
609 Args cmd_args(command);
610
611 // Process possible options.
612 if (!ParseOptions(cmd_args, result))
613 return false;
614
615 const size_t argc = cmd_args.GetArgumentCount();
616 if (argc == 0) {
617 result.AppendError("'settings remove' takes an array or dictionary item, "
618 "or an array followed by one or more indexes, or a "
619 "dictionary followed by one or more key names to "
620 "remove");
621 return false;
622 }
623
624 const char *var_name = cmd_args.GetArgumentAtIndex(0);
625 if ((var_name == nullptr) || (var_name[0] == '\0')) {
626 result.AppendError(
627 "'settings remove' command requires a valid variable name");
628 return false;
629 }
630
631 // Split the raw command into var_name and value pair.
632 llvm::StringRef var_value(command);
633 var_value = var_value.split(var_name).second.trim();
634
635 Status error(GetDebugger().SetPropertyValue(
636 &m_exe_ctx, eVarSetOperationRemove, var_name, var_value));
637 if (error.Fail()) {
638 result.AppendError(error.AsCString());
639 return false;
640 }
641
642 return result.Succeeded();
643 }
644};
645
646// CommandObjectSettingsReplace
647
649public:
651 : CommandObjectRaw(interpreter, "settings replace",
652 "Replace the debugger setting value specified by "
653 "array index or dictionary key.") {
657 CommandArgumentData var_name_arg;
658 CommandArgumentData index_arg;
659 CommandArgumentData key_arg;
660 CommandArgumentData value_arg;
661
662 // Define the first (and only) variant of this arg.
664 var_name_arg.arg_repetition = eArgRepeatPlain;
665
666 // There is only one variant this argument could be; put it into the
667 // argument entry.
668 arg1.push_back(var_name_arg);
669
670 // Define the first (variant of this arg.
671 index_arg.arg_type = eArgTypeSettingIndex;
673
674 // Define the second (variant of this arg.
677
678 // Put both variants into this arg
679 arg2.push_back(index_arg);
680 arg2.push_back(key_arg);
681
682 // Define the first (and only) variant of this arg.
683 value_arg.arg_type = eArgTypeValue;
685
686 // There is only one variant this argument could be; put it into the
687 // argument entry.
688 arg3.push_back(value_arg);
689
690 // Push the data for the first argument into the m_arguments vector.
691 m_arguments.push_back(arg1);
692 m_arguments.push_back(arg2);
693 m_arguments.push_back(arg3);
694 }
695
696 ~CommandObjectSettingsReplace() override = default;
697
698 // Overrides base class's behavior where WantsCompletion =
699 // !WantsRawCommandString.
700 bool WantsCompletion() override { return true; }
701
702 void
704 OptionElementVector &opt_element_vector) override {
705 // Attempting to complete variable name
706 if (request.GetCursorIndex() < 2)
709 request, nullptr);
710 }
711
712protected:
713 bool DoExecute(llvm::StringRef command,
714 CommandReturnObject &result) override {
716
717 Args cmd_args(command);
718 const char *var_name = cmd_args.GetArgumentAtIndex(0);
719 if ((var_name == nullptr) || (var_name[0] == '\0')) {
720 result.AppendError("'settings replace' command requires a valid variable "
721 "name; No value supplied");
722 return false;
723 }
724
725 // Split the raw command into var_name, index_value, and value triple.
726 llvm::StringRef var_value(command);
727 var_value = var_value.split(var_name).second.trim();
728
729 Status error(GetDebugger().SetPropertyValue(
730 &m_exe_ctx, eVarSetOperationReplace, var_name, var_value));
731 if (error.Fail()) {
732 result.AppendError(error.AsCString());
733 return false;
734 } else {
736 }
737
738 return result.Succeeded();
739 }
740};
741
742// CommandObjectSettingsInsertBefore
743
745public:
747 : CommandObjectRaw(interpreter, "settings insert-before",
748 "Insert one or more values into an debugger array "
749 "setting immediately before the specified element "
750 "index.") {
754 CommandArgumentData var_name_arg;
755 CommandArgumentData index_arg;
756 CommandArgumentData value_arg;
757
758 // Define the first (and only) variant of this arg.
760 var_name_arg.arg_repetition = eArgRepeatPlain;
761
762 // There is only one variant this argument could be; put it into the
763 // argument entry.
764 arg1.push_back(var_name_arg);
765
766 // Define the first (variant of this arg.
767 index_arg.arg_type = eArgTypeSettingIndex;
769
770 // There is only one variant this argument could be; put it into the
771 // argument entry.
772 arg2.push_back(index_arg);
773
774 // Define the first (and only) variant of this arg.
775 value_arg.arg_type = eArgTypeValue;
777
778 // There is only one variant this argument could be; put it into the
779 // argument entry.
780 arg3.push_back(value_arg);
781
782 // Push the data for the first argument into the m_arguments vector.
783 m_arguments.push_back(arg1);
784 m_arguments.push_back(arg2);
785 m_arguments.push_back(arg3);
786 }
787
789
790 // Overrides base class's behavior where WantsCompletion =
791 // !WantsRawCommandString.
792 bool WantsCompletion() override { return true; }
793
794 void
796 OptionElementVector &opt_element_vector) override {
797 // Attempting to complete variable name
798 if (request.GetCursorIndex() < 2)
801 request, nullptr);
802 }
803
804protected:
805 bool DoExecute(llvm::StringRef command,
806 CommandReturnObject &result) override {
808
809 Args cmd_args(command);
810 const size_t argc = cmd_args.GetArgumentCount();
811
812 if (argc < 3) {
813 result.AppendError("'settings insert-before' takes more arguments");
814 return false;
815 }
816
817 const char *var_name = cmd_args.GetArgumentAtIndex(0);
818 if ((var_name == nullptr) || (var_name[0] == '\0')) {
819 result.AppendError("'settings insert-before' command requires a valid "
820 "variable name; No value supplied");
821 return false;
822 }
823
824 // Split the raw command into var_name, index_value, and value triple.
825 llvm::StringRef var_value(command);
826 var_value = var_value.split(var_name).second.trim();
827
828 Status error(GetDebugger().SetPropertyValue(
829 &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value));
830 if (error.Fail()) {
831 result.AppendError(error.AsCString());
832 return false;
833 }
834
835 return result.Succeeded();
836 }
837};
838
839// CommandObjectSettingInsertAfter
840
842public:
844 : CommandObjectRaw(interpreter, "settings insert-after",
845 "Insert one or more values into a debugger array "
846 "settings after the specified element index.") {
850 CommandArgumentData var_name_arg;
851 CommandArgumentData index_arg;
852 CommandArgumentData value_arg;
853
854 // Define the first (and only) variant of this arg.
856 var_name_arg.arg_repetition = eArgRepeatPlain;
857
858 // There is only one variant this argument could be; put it into the
859 // argument entry.
860 arg1.push_back(var_name_arg);
861
862 // Define the first (variant of this arg.
863 index_arg.arg_type = eArgTypeSettingIndex;
865
866 // There is only one variant this argument could be; put it into the
867 // argument entry.
868 arg2.push_back(index_arg);
869
870 // Define the first (and only) variant of this arg.
871 value_arg.arg_type = eArgTypeValue;
873
874 // There is only one variant this argument could be; put it into the
875 // argument entry.
876 arg3.push_back(value_arg);
877
878 // Push the data for the first argument into the m_arguments vector.
879 m_arguments.push_back(arg1);
880 m_arguments.push_back(arg2);
881 m_arguments.push_back(arg3);
882 }
883
885
886 // Overrides base class's behavior where WantsCompletion =
887 // !WantsRawCommandString.
888 bool WantsCompletion() override { return true; }
889
890 void
892 OptionElementVector &opt_element_vector) override {
893 // Attempting to complete variable name
894 if (request.GetCursorIndex() < 2)
897 request, nullptr);
898 }
899
900protected:
901 bool DoExecute(llvm::StringRef command,
902 CommandReturnObject &result) override {
904
905 Args cmd_args(command);
906 const size_t argc = cmd_args.GetArgumentCount();
907
908 if (argc < 3) {
909 result.AppendError("'settings insert-after' takes more arguments");
910 return false;
911 }
912
913 const char *var_name = cmd_args.GetArgumentAtIndex(0);
914 if ((var_name == nullptr) || (var_name[0] == '\0')) {
915 result.AppendError("'settings insert-after' command requires a valid "
916 "variable name; No value supplied");
917 return false;
918 }
919
920 // Split the raw command into var_name, index_value, and value triple.
921 llvm::StringRef var_value(command);
922 var_value = var_value.split(var_name).second.trim();
923
924 Status error(GetDebugger().SetPropertyValue(
925 &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value));
926 if (error.Fail()) {
927 result.AppendError(error.AsCString());
928 return false;
929 }
930
931 return result.Succeeded();
932 }
933};
934
935// CommandObjectSettingsAppend
936
938public:
940 : CommandObjectRaw(interpreter, "settings append",
941 "Append one or more values to a debugger array, "
942 "dictionary, or string setting.") {
945 CommandArgumentData var_name_arg;
946 CommandArgumentData value_arg;
947
948 // Define the first (and only) variant of this arg.
950 var_name_arg.arg_repetition = eArgRepeatPlain;
951
952 // There is only one variant this argument could be; put it into the
953 // argument entry.
954 arg1.push_back(var_name_arg);
955
956 // Define the first (and only) variant of this arg.
957 value_arg.arg_type = eArgTypeValue;
959
960 // There is only one variant this argument could be; put it into the
961 // argument entry.
962 arg2.push_back(value_arg);
963
964 // Push the data for the first argument into the m_arguments vector.
965 m_arguments.push_back(arg1);
966 m_arguments.push_back(arg2);
967 }
968
969 ~CommandObjectSettingsAppend() override = default;
970
971 // Overrides base class's behavior where WantsCompletion =
972 // !WantsRawCommandString.
973 bool WantsCompletion() override { return true; }
974
975 void
977 OptionElementVector &opt_element_vector) override {
978 // Attempting to complete variable name
979 if (request.GetCursorIndex() < 2)
982 request, nullptr);
983 }
984
985protected:
986 bool DoExecute(llvm::StringRef command,
987 CommandReturnObject &result) override {
989 Args cmd_args(command);
990 const size_t argc = cmd_args.GetArgumentCount();
991
992 if (argc < 2) {
993 result.AppendError("'settings append' takes more arguments");
994 return false;
995 }
996
997 const char *var_name = cmd_args.GetArgumentAtIndex(0);
998 if ((var_name == nullptr) || (var_name[0] == '\0')) {
999 result.AppendError("'settings append' command requires a valid variable "
1000 "name; No value supplied");
1001 return false;
1002 }
1003
1004 // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
1005 // character string later on.
1006
1007 // Split the raw command into var_name and value pair.
1008 llvm::StringRef var_value(command);
1009 var_value = var_value.split(var_name).second.trim();
1010
1011 Status error(GetDebugger().SetPropertyValue(
1012 &m_exe_ctx, eVarSetOperationAppend, var_name, var_value));
1013 if (error.Fail()) {
1014 result.AppendError(error.AsCString());
1015 return false;
1016 }
1017
1018 return result.Succeeded();
1019 }
1020};
1021
1022// CommandObjectSettingsClear
1023#define LLDB_OPTIONS_settings_clear
1024#include "CommandOptions.inc"
1025
1027public:
1030 interpreter, "settings clear",
1031 "Clear a debugger setting array, dictionary, or string. "
1032 "If '-a' option is specified, it clears all settings.", nullptr) {
1034 CommandArgumentData var_name_arg;
1035
1036 // Define the first (and only) variant of this arg.
1038 var_name_arg.arg_repetition = eArgRepeatPlain;
1039
1040 // There is only one variant this argument could be; put it into the
1041 // argument entry.
1042 arg.push_back(var_name_arg);
1043
1044 // Push the data for the first argument into the m_arguments vector.
1045 m_arguments.push_back(arg);
1046 }
1047
1048 ~CommandObjectSettingsClear() override = default;
1049
1050 void
1052 OptionElementVector &opt_element_vector) override {
1053 // Attempting to complete variable name
1054 if (request.GetCursorIndex() < 2)
1057 request, nullptr);
1058 }
1059
1060 Options *GetOptions() override { return &m_options; }
1061
1062 class CommandOptions : public Options {
1063 public:
1064 CommandOptions() = default;
1065
1066 ~CommandOptions() override = default;
1067
1068 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1069 ExecutionContext *execution_context) override {
1070 const int short_option = m_getopt_table[option_idx].val;
1071 switch (short_option) {
1072 case 'a':
1073 m_clear_all = true;
1074 break;
1075 default:
1076 llvm_unreachable("Unimplemented option");
1077 }
1078 return Status();
1079 }
1080
1081 void OptionParsingStarting(ExecutionContext *execution_context) override {
1082 m_clear_all = false;
1083 }
1084
1085 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1086 return llvm::ArrayRef(g_settings_clear_options);
1087 }
1088
1089 bool m_clear_all = false;
1090 };
1091
1092protected:
1093 bool DoExecute(Args &command, CommandReturnObject &result) override {
1095 const size_t argc = command.GetArgumentCount();
1096
1097 if (m_options.m_clear_all) {
1098 if (argc != 0) {
1099 result.AppendError("'settings clear --all' doesn't take any arguments");
1100 return false;
1101 }
1102 GetDebugger().GetValueProperties()->Clear();
1103 return result.Succeeded();
1104 }
1105
1106 if (argc != 1) {
1107 result.AppendError("'settings clear' takes exactly one argument");
1108 return false;
1109 }
1110
1111 const char *var_name = command.GetArgumentAtIndex(0);
1112 if ((var_name == nullptr) || (var_name[0] == '\0')) {
1113 result.AppendError("'settings clear' command requires a valid variable "
1114 "name; No value supplied");
1115 return false;
1116 }
1117
1118 Status error(GetDebugger().SetPropertyValue(
1119 &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
1120 if (error.Fail()) {
1121 result.AppendError(error.AsCString());
1122 return false;
1123 }
1124
1125 return result.Succeeded();
1126 }
1127
1128 private:
1130};
1131
1132// CommandObjectMultiwordSettings
1133
1135 CommandInterpreter &interpreter)
1136 : CommandObjectMultiword(interpreter, "settings",
1137 "Commands for managing LLDB settings.",
1138 "settings <subcommand> [<command-options>]") {
1139 LoadSubCommand("set",
1140 CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
1141 LoadSubCommand("show",
1142 CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
1143 LoadSubCommand("list",
1144 CommandObjectSP(new CommandObjectSettingsList(interpreter)));
1145 LoadSubCommand("remove",
1146 CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
1147 LoadSubCommand("replace", CommandObjectSP(
1148 new CommandObjectSettingsReplace(interpreter)));
1150 "insert-before",
1151 CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
1153 "insert-after",
1154 CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
1155 LoadSubCommand("append",
1156 CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
1157 LoadSubCommand("clear",
1158 CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
1159 LoadSubCommand("write",
1160 CommandObjectSP(new CommandObjectSettingsWrite(interpreter)));
1161 LoadSubCommand("read",
1162 CommandObjectSP(new CommandObjectSettingsRead(interpreter)));
1163}
1164
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:264
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:201
"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:57
std::vector< Option > m_getopt_table
Definition: Options.h:197
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.
std::vector< OptionArgElement > OptionElementVector
Definition: Options.h:42
Definition: SBAddress.h:15
@ eReturnStatusSuccessFinishResult
@ eReturnStatusSuccessFinishNoResult
@ eArgTypeSettingKey
@ eArgTypeSettingPrefix
@ eArgTypeSettingIndex
@ eArgTypeSettingVariableName
Used to build individual command argument lists.
Definition: CommandObject.h:93