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 
13 #include "lldb/Host/OptionParser.h"
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 // CommandObjectSettingsSet
23 #define LLDB_OPTIONS_settings_set
24 #include "CommandOptions.inc"
25 
27 public:
29  : CommandObjectRaw(interpreter, "settings set",
30  "Set the value of the specified debugger setting."),
31  m_options() {
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;
47  value_arg.arg_repetition = eArgRepeatPlain;
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 
57  SetHelpLong(
58  "\nWhen setting a dictionary or array variable, you can set multiple entries \
59 at once by giving the values to the set command. For example:"
60  R"(
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 \
75 just want to add, remove or update individual values (or add something to \
76 the end), use one of the other settings sub-commands: append, replace, \
77 insert-before or insert-after.");
78  }
79 
80  ~CommandObjectSettingsSet() override = default;
81 
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() : Options(), m_global(false) {}
91 
92  ~CommandOptions() override = default;
93 
94  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
95  ExecutionContext *execution_context) override {
96  Status error;
97  const int short_option = m_getopt_table[option_idx].val;
98 
99  switch (short_option) {
100  case 'f':
101  m_force = true;
102  break;
103  case 'g':
104  m_global = true;
105  break;
106  default:
107  llvm_unreachable("Unimplemented option");
108  }
109 
110  return error;
111  }
112 
113  void OptionParsingStarting(ExecutionContext *execution_context) override {
114  m_global = false;
115  m_force = false;
116  }
117 
118  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
119  return llvm::makeArrayRef(g_settings_set_options);
120  }
121 
122  // Instance variables to hold the values for command options.
123  bool m_global;
124  bool m_force;
125  };
126 
127  void
129  OptionElementVector &opt_element_vector) override {
130 
131  const size_t argc = request.GetParsedLine().GetArgumentCount();
132  const char *arg = nullptr;
133  size_t setting_var_idx;
134  for (setting_var_idx = 0; setting_var_idx < argc; ++setting_var_idx) {
135  arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
136  if (arg && arg[0] != '-')
137  break; // We found our setting variable name index
138  }
139  if (request.GetCursorIndex() == setting_var_idx) {
140  // Attempting to complete setting variable name
141  CommandCompletions::InvokeCommonCompletionCallbacks(
142  GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
143  request, nullptr);
144  return;
145  }
146  arg = request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
147 
148  if (!arg)
149  return;
150 
151  // Complete option name
152  if (arg[0] != '-')
153  return;
154 
155  // Complete setting value
156  const char *setting_var_name =
157  request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
158  Status error;
159  lldb::OptionValueSP value_sp(GetDebugger().GetPropertyValue(
160  &m_exe_ctx, setting_var_name, false, error));
161  if (!value_sp)
162  return;
163  value_sp->AutoComplete(m_interpreter, request);
164  }
165 
166 protected:
167  bool DoExecute(llvm::StringRef command,
168  CommandReturnObject &result) override {
169  Args cmd_args(command);
170 
171  // Process possible options.
172  if (!ParseOptions(cmd_args, result))
173  return false;
174 
175  const size_t min_argc = m_options.m_force ? 1 : 2;
176  const size_t argc = cmd_args.GetArgumentCount();
177 
178  if ((argc < min_argc) && (!m_options.m_global)) {
179  result.AppendError("'settings set' takes more arguments");
181  return false;
182  }
183 
184  const char *var_name = cmd_args.GetArgumentAtIndex(0);
185  if ((var_name == nullptr) || (var_name[0] == '\0')) {
186  result.AppendError(
187  "'settings set' command requires a valid variable name");
189  return false;
190  }
191 
192  // A missing value corresponds to clearing the setting when "force" is
193  // specified.
194  if (argc == 1 && m_options.m_force) {
195  Status error(GetDebugger().SetPropertyValue(
196  &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
197  if (error.Fail()) {
198  result.AppendError(error.AsCString());
200  return false;
201  }
202  return result.Succeeded();
203  }
204 
205  // Split the raw command into var_name and value pair.
206  llvm::StringRef var_value(command);
207  var_value = var_value.split(var_name).second.ltrim();
208 
209  Status error;
210  if (m_options.m_global)
211  error = GetDebugger().SetPropertyValue(nullptr, eVarSetOperationAssign,
212  var_name, var_value);
213 
214  if (error.Success()) {
215  // FIXME this is the same issue as the one in commands script import
216  // we could be setting target.load-script-from-symbol-file which would
217  // cause Python scripts to be loaded, which could run LLDB commands (e.g.
218  // settings set target.process.python-os-plugin-path) and cause a crash
219  // if we did not clear the command's exe_ctx first
220  ExecutionContext exe_ctx(m_exe_ctx);
221  m_exe_ctx.Clear();
222  error = GetDebugger().SetPropertyValue(&exe_ctx, eVarSetOperationAssign,
223  var_name, var_value);
224  }
225 
226  if (error.Fail()) {
227  result.AppendError(error.AsCString());
229  return false;
230  } else {
232  }
233 
234  return result.Succeeded();
235  }
236 
237 private:
239 };
240 
241 // CommandObjectSettingsShow -- Show current values
242 
244 public:
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.
254  var_name_arg.arg_type = eArgTypeSettingVariableName;
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 {
270  CommandCompletions::InvokeCommonCompletionCallbacks(
271  GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
272  request, nullptr);
273  }
274 
275 protected:
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(),
283  OptionValue::eDumpGroupValue));
284  if (error.Success()) {
285  result.GetOutputStream().EOL();
286  } else {
287  result.AppendError(error.AsCString());
289  }
290  }
291  } else {
292  GetDebugger().DumpAllPropertyValues(&m_exe_ctx, result.GetOutputStream(),
293  OptionValue::eDumpGroupValue);
294  }
295 
296  return result.Succeeded();
297  }
298 };
299 
300 // CommandObjectSettingsWrite -- Write settings to file
301 #define LLDB_OPTIONS_settings_write
302 #include "CommandOptions.inc"
303 
305 public:
308  interpreter, "settings export",
309  "Write matching debugger settings and their "
310  "current values to a file that can be read in with "
311  "\"settings read\". Defaults to writing all settings.",
312  nullptr),
313  m_options() {
315  CommandArgumentData var_name_arg;
316 
317  // Define the first (and only) variant of this arg.
318  var_name_arg.arg_type = eArgTypeSettingVariableName;
319  var_name_arg.arg_repetition = eArgRepeatOptional;
320 
321  // There is only one variant this argument could be; put it into the
322  // argument entry.
323  arg1.push_back(var_name_arg);
324 
325  // Push the data for the first argument into the m_arguments vector.
326  m_arguments.push_back(arg1);
327  }
328 
329  ~CommandObjectSettingsWrite() override = default;
330 
331  Options *GetOptions() override { return &m_options; }
332 
333  class CommandOptions : public Options {
334  public:
336 
337  ~CommandOptions() override = default;
338 
339  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
340  ExecutionContext *execution_context) override {
341  Status error;
342  const int short_option = m_getopt_table[option_idx].val;
343 
344  switch (short_option) {
345  case 'f':
346  m_filename.assign(std::string(option_arg));
347  break;
348  case 'a':
349  m_append = true;
350  break;
351  default:
352  llvm_unreachable("Unimplemented option");
353  }
354 
355  return error;
356  }
357 
358  void OptionParsingStarting(ExecutionContext *execution_context) override {
359  m_filename.clear();
360  m_append = false;
361  }
362 
363  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
364  return llvm::makeArrayRef(g_settings_write_options);
365  }
366 
367  // Instance variables to hold the values for command options.
368  std::string m_filename;
369  bool m_append = false;
370  };
371 
372 protected:
373  bool DoExecute(Args &args, CommandReturnObject &result) override {
374  FileSpec file_spec(m_options.m_filename);
375  FileSystem::Instance().Resolve(file_spec);
376  std::string path(file_spec.GetPath());
377  auto options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
378  if (m_options.m_append)
379  options |= File::eOpenOptionAppend;
380  else
381  options |= File::eOpenOptionTruncate;
382 
383  StreamFile out_file(path.c_str(), options,
384  lldb::eFilePermissionsFileDefault);
385 
386  if (!out_file.GetFile().IsValid()) {
387  result.AppendErrorWithFormat("%s: unable to write to file", path.c_str());
389  return false;
390  }
391 
392  // Exporting should not be context sensitive.
393  ExecutionContext clean_ctx;
394 
395  if (args.empty()) {
396  GetDebugger().DumpAllPropertyValues(&clean_ctx, out_file,
397  OptionValue::eDumpGroupExport);
398  return result.Succeeded();
399  }
400 
401  for (const auto &arg : args) {
402  Status error(GetDebugger().DumpPropertyValue(
403  &clean_ctx, out_file, arg.ref(), OptionValue::eDumpGroupExport));
404  if (!error.Success()) {
405  result.AppendError(error.AsCString());
407  }
408  }
409 
410  return result.Succeeded();
411  }
412 
413 private:
415 };
416 
417 // CommandObjectSettingsRead -- Read settings from file
418 #define LLDB_OPTIONS_settings_read
419 #include "CommandOptions.inc"
420 
422 public:
425  interpreter, "settings read",
426  "Read settings previously saved to a file with \"settings write\".",
427  nullptr),
428  m_options() {}
429 
430  ~CommandObjectSettingsRead() override = default;
431 
432  Options *GetOptions() override { return &m_options; }
433 
434  class CommandOptions : public Options {
435  public:
437 
438  ~CommandOptions() override = default;
439 
440  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
441  ExecutionContext *execution_context) override {
442  Status error;
443  const int short_option = m_getopt_table[option_idx].val;
444 
445  switch (short_option) {
446  case 'f':
447  m_filename.assign(std::string(option_arg));
448  break;
449  default:
450  llvm_unreachable("Unimplemented option");
451  }
452 
453  return error;
454  }
455 
456  void OptionParsingStarting(ExecutionContext *execution_context) override {
457  m_filename.clear();
458  }
459 
460  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
461  return llvm::makeArrayRef(g_settings_read_options);
462  }
463 
464  // Instance variables to hold the values for command options.
465  std::string m_filename;
466  };
467 
468 protected:
469  bool DoExecute(Args &command, CommandReturnObject &result) override {
470  FileSpec file(m_options.m_filename);
471  FileSystem::Instance().Resolve(file);
472  ExecutionContext clean_ctx;
474  options.SetAddToHistory(false);
475  options.SetEchoCommands(false);
476  options.SetPrintResults(true);
477  options.SetPrintErrors(true);
478  options.SetStopOnError(false);
479  m_interpreter.HandleCommandsFromFile(file, &clean_ctx, options, result);
480  return result.Succeeded();
481  }
482 
483 private:
485 };
486 
487 // CommandObjectSettingsList -- List settable variables
488 
490 public:
492  : CommandObjectParsed(interpreter, "settings list",
493  "List and describe matching debugger settings. "
494  "Defaults to all listing all settings.",
495  nullptr) {
497  CommandArgumentData var_name_arg;
498  CommandArgumentData prefix_name_arg;
499 
500  // Define the first variant of this arg.
501  var_name_arg.arg_type = eArgTypeSettingVariableName;
502  var_name_arg.arg_repetition = eArgRepeatOptional;
503 
504  // Define the second variant of this arg.
505  prefix_name_arg.arg_type = eArgTypeSettingPrefix;
506  prefix_name_arg.arg_repetition = eArgRepeatOptional;
507 
508  arg.push_back(var_name_arg);
509  arg.push_back(prefix_name_arg);
510 
511  // Push the data for the first argument into the m_arguments vector.
512  m_arguments.push_back(arg);
513  }
514 
515  ~CommandObjectSettingsList() override = default;
516 
517  void
519  OptionElementVector &opt_element_vector) override {
520  CommandCompletions::InvokeCommonCompletionCallbacks(
521  GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
522  request, nullptr);
523  }
524 
525 protected:
526  bool DoExecute(Args &args, CommandReturnObject &result) override {
528 
529  const bool will_modify = false;
530  const size_t argc = args.GetArgumentCount();
531  if (argc > 0) {
532  const bool dump_qualified_name = true;
533 
534  for (const Args::ArgEntry &arg : args) {
535  const char *property_path = arg.c_str();
536 
537  const Property *property =
538  GetDebugger().GetValueProperties()->GetPropertyAtPath(
539  &m_exe_ctx, will_modify, property_path);
540 
541  if (property) {
542  property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
543  dump_qualified_name);
544  } else {
545  result.AppendErrorWithFormat("invalid property path '%s'",
546  property_path);
548  }
549  }
550  } else {
551  GetDebugger().DumpAllDescriptions(m_interpreter,
552  result.GetOutputStream());
553  }
554 
555  return result.Succeeded();
556  }
557 };
558 
559 // CommandObjectSettingsRemove
560 
562 public:
564  : CommandObjectRaw(interpreter, "settings remove",
565  "Remove a value from a setting, specified by array "
566  "index or dictionary key.") {
569  CommandArgumentData var_name_arg;
570  CommandArgumentData index_arg;
571  CommandArgumentData key_arg;
572 
573  // Define the first (and only) variant of this arg.
574  var_name_arg.arg_type = eArgTypeSettingVariableName;
575  var_name_arg.arg_repetition = eArgRepeatPlain;
576 
577  // There is only one variant this argument could be; put it into the
578  // argument entry.
579  arg1.push_back(var_name_arg);
580 
581  // Define the first variant of this arg.
582  index_arg.arg_type = eArgTypeSettingIndex;
583  index_arg.arg_repetition = eArgRepeatPlain;
584 
585  // Define the second variant of this arg.
586  key_arg.arg_type = eArgTypeSettingKey;
588 
589  // Push both variants into this arg
590  arg2.push_back(index_arg);
591  arg2.push_back(key_arg);
592 
593  // Push the data for the first argument into the m_arguments vector.
594  m_arguments.push_back(arg1);
595  m_arguments.push_back(arg2);
596  }
597 
598  ~CommandObjectSettingsRemove() override = default;
599 
600  bool WantsCompletion() override { return true; }
601 
602  void
604  OptionElementVector &opt_element_vector) override {
605  if (request.GetCursorIndex() < 2)
606  CommandCompletions::InvokeCommonCompletionCallbacks(
607  GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
608  request, nullptr);
609  }
610 
611 protected:
612  bool DoExecute(llvm::StringRef command,
613  CommandReturnObject &result) override {
615 
616  Args cmd_args(command);
617 
618  // Process possible options.
619  if (!ParseOptions(cmd_args, result))
620  return false;
621 
622  const size_t argc = cmd_args.GetArgumentCount();
623  if (argc == 0) {
624  result.AppendError("'settings remove' takes an array or dictionary item, "
625  "or an array followed by one or more indexes, or a "
626  "dictionary followed by one or more key names to "
627  "remove");
629  return false;
630  }
631 
632  const char *var_name = cmd_args.GetArgumentAtIndex(0);
633  if ((var_name == nullptr) || (var_name[0] == '\0')) {
634  result.AppendError(
635  "'settings remove' command requires a valid variable name");
637  return false;
638  }
639 
640  // Split the raw command into var_name and value pair.
641  llvm::StringRef var_value(command);
642  var_value = var_value.split(var_name).second.trim();
643 
644  Status error(GetDebugger().SetPropertyValue(
645  &m_exe_ctx, eVarSetOperationRemove, var_name, var_value));
646  if (error.Fail()) {
647  result.AppendError(error.AsCString());
649  return false;
650  }
651 
652  return result.Succeeded();
653  }
654 };
655 
656 // CommandObjectSettingsReplace
657 
659 public:
661  : CommandObjectRaw(interpreter, "settings replace",
662  "Replace the debugger setting value specified by "
663  "array index or dictionary key.") {
667  CommandArgumentData var_name_arg;
668  CommandArgumentData index_arg;
669  CommandArgumentData key_arg;
670  CommandArgumentData value_arg;
671 
672  // Define the first (and only) variant of this arg.
673  var_name_arg.arg_type = eArgTypeSettingVariableName;
674  var_name_arg.arg_repetition = eArgRepeatPlain;
675 
676  // There is only one variant this argument could be; put it into the
677  // argument entry.
678  arg1.push_back(var_name_arg);
679 
680  // Define the first (variant of this arg.
681  index_arg.arg_type = eArgTypeSettingIndex;
682  index_arg.arg_repetition = eArgRepeatPlain;
683 
684  // Define the second (variant of this arg.
685  key_arg.arg_type = eArgTypeSettingKey;
687 
688  // Put both variants into this arg
689  arg2.push_back(index_arg);
690  arg2.push_back(key_arg);
691 
692  // Define the first (and only) variant of this arg.
693  value_arg.arg_type = eArgTypeValue;
694  value_arg.arg_repetition = eArgRepeatPlain;
695 
696  // There is only one variant this argument could be; put it into the
697  // argument entry.
698  arg3.push_back(value_arg);
699 
700  // Push the data for the first argument into the m_arguments vector.
701  m_arguments.push_back(arg1);
702  m_arguments.push_back(arg2);
703  m_arguments.push_back(arg3);
704  }
705 
706  ~CommandObjectSettingsReplace() override = default;
707 
708  // Overrides base class's behavior where WantsCompletion =
709  // !WantsRawCommandString.
710  bool WantsCompletion() override { return true; }
711 
712  void
714  OptionElementVector &opt_element_vector) override {
715  // Attempting to complete variable name
716  if (request.GetCursorIndex() < 2)
717  CommandCompletions::InvokeCommonCompletionCallbacks(
718  GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
719  request, nullptr);
720  }
721 
722 protected:
723  bool DoExecute(llvm::StringRef command,
724  CommandReturnObject &result) override {
726 
727  Args cmd_args(command);
728  const char *var_name = cmd_args.GetArgumentAtIndex(0);
729  if ((var_name == nullptr) || (var_name[0] == '\0')) {
730  result.AppendError("'settings replace' command requires a valid variable "
731  "name; No value supplied");
733  return false;
734  }
735 
736  // Split the raw command into var_name, index_value, and value triple.
737  llvm::StringRef var_value(command);
738  var_value = var_value.split(var_name).second.trim();
739 
740  Status error(GetDebugger().SetPropertyValue(
741  &m_exe_ctx, eVarSetOperationReplace, var_name, var_value));
742  if (error.Fail()) {
743  result.AppendError(error.AsCString());
745  return false;
746  } else {
748  }
749 
750  return result.Succeeded();
751  }
752 };
753 
754 // CommandObjectSettingsInsertBefore
755 
757 public:
759  : CommandObjectRaw(interpreter, "settings insert-before",
760  "Insert one or more values into an debugger array "
761  "setting immediately before the specified element "
762  "index.") {
766  CommandArgumentData var_name_arg;
767  CommandArgumentData index_arg;
768  CommandArgumentData value_arg;
769 
770  // Define the first (and only) variant of this arg.
771  var_name_arg.arg_type = eArgTypeSettingVariableName;
772  var_name_arg.arg_repetition = eArgRepeatPlain;
773 
774  // There is only one variant this argument could be; put it into the
775  // argument entry.
776  arg1.push_back(var_name_arg);
777 
778  // Define the first (variant of this arg.
779  index_arg.arg_type = eArgTypeSettingIndex;
780  index_arg.arg_repetition = eArgRepeatPlain;
781 
782  // There is only one variant this argument could be; put it into the
783  // argument entry.
784  arg2.push_back(index_arg);
785 
786  // Define the first (and only) variant of this arg.
787  value_arg.arg_type = eArgTypeValue;
788  value_arg.arg_repetition = eArgRepeatPlain;
789 
790  // There is only one variant this argument could be; put it into the
791  // argument entry.
792  arg3.push_back(value_arg);
793 
794  // Push the data for the first argument into the m_arguments vector.
795  m_arguments.push_back(arg1);
796  m_arguments.push_back(arg2);
797  m_arguments.push_back(arg3);
798  }
799 
800  ~CommandObjectSettingsInsertBefore() override = default;
801 
802  // Overrides base class's behavior where WantsCompletion =
803  // !WantsRawCommandString.
804  bool WantsCompletion() override { return true; }
805 
806  void
808  OptionElementVector &opt_element_vector) override {
809  // Attempting to complete variable name
810  if (request.GetCursorIndex() < 2)
811  CommandCompletions::InvokeCommonCompletionCallbacks(
812  GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
813  request, nullptr);
814  }
815 
816 protected:
817  bool DoExecute(llvm::StringRef command,
818  CommandReturnObject &result) override {
820 
821  Args cmd_args(command);
822  const size_t argc = cmd_args.GetArgumentCount();
823 
824  if (argc < 3) {
825  result.AppendError("'settings insert-before' takes more arguments");
827  return false;
828  }
829 
830  const char *var_name = cmd_args.GetArgumentAtIndex(0);
831  if ((var_name == nullptr) || (var_name[0] == '\0')) {
832  result.AppendError("'settings insert-before' command requires a valid "
833  "variable name; No value supplied");
835  return false;
836  }
837 
838  // Split the raw command into var_name, index_value, and value triple.
839  llvm::StringRef var_value(command);
840  var_value = var_value.split(var_name).second.trim();
841 
842  Status error(GetDebugger().SetPropertyValue(
843  &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value));
844  if (error.Fail()) {
845  result.AppendError(error.AsCString());
847  return false;
848  }
849 
850  return result.Succeeded();
851  }
852 };
853 
854 // CommandObjectSettingInsertAfter
855 
857 public:
859  : CommandObjectRaw(interpreter, "settings insert-after",
860  "Insert one or more values into a debugger array "
861  "settings after the specified element index.") {
865  CommandArgumentData var_name_arg;
866  CommandArgumentData index_arg;
867  CommandArgumentData value_arg;
868 
869  // Define the first (and only) variant of this arg.
870  var_name_arg.arg_type = eArgTypeSettingVariableName;
871  var_name_arg.arg_repetition = eArgRepeatPlain;
872 
873  // There is only one variant this argument could be; put it into the
874  // argument entry.
875  arg1.push_back(var_name_arg);
876 
877  // Define the first (variant of this arg.
878  index_arg.arg_type = eArgTypeSettingIndex;
879  index_arg.arg_repetition = eArgRepeatPlain;
880 
881  // There is only one variant this argument could be; put it into the
882  // argument entry.
883  arg2.push_back(index_arg);
884 
885  // Define the first (and only) variant of this arg.
886  value_arg.arg_type = eArgTypeValue;
887  value_arg.arg_repetition = eArgRepeatPlain;
888 
889  // There is only one variant this argument could be; put it into the
890  // argument entry.
891  arg3.push_back(value_arg);
892 
893  // Push the data for the first argument into the m_arguments vector.
894  m_arguments.push_back(arg1);
895  m_arguments.push_back(arg2);
896  m_arguments.push_back(arg3);
897  }
898 
899  ~CommandObjectSettingsInsertAfter() override = default;
900 
901  // Overrides base class's behavior where WantsCompletion =
902  // !WantsRawCommandString.
903  bool WantsCompletion() override { return true; }
904 
905  void
907  OptionElementVector &opt_element_vector) override {
908  // Attempting to complete variable name
909  if (request.GetCursorIndex() < 2)
910  CommandCompletions::InvokeCommonCompletionCallbacks(
911  GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
912  request, nullptr);
913  }
914 
915 protected:
916  bool DoExecute(llvm::StringRef command,
917  CommandReturnObject &result) override {
919 
920  Args cmd_args(command);
921  const size_t argc = cmd_args.GetArgumentCount();
922 
923  if (argc < 3) {
924  result.AppendError("'settings insert-after' takes more arguments");
926  return false;
927  }
928 
929  const char *var_name = cmd_args.GetArgumentAtIndex(0);
930  if ((var_name == nullptr) || (var_name[0] == '\0')) {
931  result.AppendError("'settings insert-after' command requires a valid "
932  "variable name; No value supplied");
934  return false;
935  }
936 
937  // Split the raw command into var_name, index_value, and value triple.
938  llvm::StringRef var_value(command);
939  var_value = var_value.split(var_name).second.trim();
940 
941  Status error(GetDebugger().SetPropertyValue(
942  &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value));
943  if (error.Fail()) {
944  result.AppendError(error.AsCString());
946  return false;
947  }
948 
949  return result.Succeeded();
950  }
951 };
952 
953 // CommandObjectSettingsAppend
954 
956 public:
958  : CommandObjectRaw(interpreter, "settings append",
959  "Append one or more values to a debugger array, "
960  "dictionary, or string setting.") {
963  CommandArgumentData var_name_arg;
964  CommandArgumentData value_arg;
965 
966  // Define the first (and only) variant of this arg.
967  var_name_arg.arg_type = eArgTypeSettingVariableName;
968  var_name_arg.arg_repetition = eArgRepeatPlain;
969 
970  // There is only one variant this argument could be; put it into the
971  // argument entry.
972  arg1.push_back(var_name_arg);
973 
974  // Define the first (and only) variant of this arg.
975  value_arg.arg_type = eArgTypeValue;
976  value_arg.arg_repetition = eArgRepeatPlain;
977 
978  // There is only one variant this argument could be; put it into the
979  // argument entry.
980  arg2.push_back(value_arg);
981 
982  // Push the data for the first argument into the m_arguments vector.
983  m_arguments.push_back(arg1);
984  m_arguments.push_back(arg2);
985  }
986 
987  ~CommandObjectSettingsAppend() override = default;
988 
989  // Overrides base class's behavior where WantsCompletion =
990  // !WantsRawCommandString.
991  bool WantsCompletion() override { return true; }
992 
993  void
995  OptionElementVector &opt_element_vector) override {
996  // Attempting to complete variable name
997  if (request.GetCursorIndex() < 2)
998  CommandCompletions::InvokeCommonCompletionCallbacks(
999  GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
1000  request, nullptr);
1001  }
1002 
1003 protected:
1004  bool DoExecute(llvm::StringRef command,
1005  CommandReturnObject &result) override {
1007  Args cmd_args(command);
1008  const size_t argc = cmd_args.GetArgumentCount();
1009 
1010  if (argc < 2) {
1011  result.AppendError("'settings append' takes more arguments");
1013  return false;
1014  }
1015 
1016  const char *var_name = cmd_args.GetArgumentAtIndex(0);
1017  if ((var_name == nullptr) || (var_name[0] == '\0')) {
1018  result.AppendError("'settings append' command requires a valid variable "
1019  "name; No value supplied");
1021  return false;
1022  }
1023 
1024  // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
1025  // character string later on.
1026 
1027  // Split the raw command into var_name and value pair.
1028  llvm::StringRef var_value(command);
1029  var_value = var_value.split(var_name).second.trim();
1030 
1031  Status error(GetDebugger().SetPropertyValue(
1032  &m_exe_ctx, eVarSetOperationAppend, var_name, var_value));
1033  if (error.Fail()) {
1034  result.AppendError(error.AsCString());
1036  return false;
1037  }
1038 
1039  return result.Succeeded();
1040  }
1041 };
1042 
1043 // CommandObjectSettingsClear
1044 #define LLDB_OPTIONS_settings_clear
1045 #include "CommandOptions.inc"
1046 
1048 public:
1051  interpreter, "settings clear",
1052  "Clear a debugger setting array, dictionary, or string. "
1053  "If '-a' option is specified, it clears all settings.", nullptr) {
1055  CommandArgumentData var_name_arg;
1056 
1057  // Define the first (and only) variant of this arg.
1058  var_name_arg.arg_type = eArgTypeSettingVariableName;
1059  var_name_arg.arg_repetition = eArgRepeatPlain;
1060 
1061  // There is only one variant this argument could be; put it into the
1062  // argument entry.
1063  arg.push_back(var_name_arg);
1064 
1065  // Push the data for the first argument into the m_arguments vector.
1066  m_arguments.push_back(arg);
1067  }
1068 
1069  ~CommandObjectSettingsClear() override = default;
1070 
1071  void
1073  OptionElementVector &opt_element_vector) override {
1074  // Attempting to complete variable name
1075  if (request.GetCursorIndex() < 2)
1076  CommandCompletions::InvokeCommonCompletionCallbacks(
1077  GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
1078  request, nullptr);
1079  }
1080 
1081  Options *GetOptions() override { return &m_options; }
1082 
1083  class CommandOptions : public Options {
1084  public:
1085  CommandOptions() = default;
1086 
1087  ~CommandOptions() override = default;
1088 
1089  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1090  ExecutionContext *execution_context) override {
1091  const int short_option = m_getopt_table[option_idx].val;
1092  switch (short_option) {
1093  case 'a':
1094  m_clear_all = true;
1095  break;
1096  default:
1097  llvm_unreachable("Unimplemented option");
1098  }
1099  return Status();
1100  }
1101 
1102  void OptionParsingStarting(ExecutionContext *execution_context) override {
1103  m_clear_all = false;
1104  }
1105 
1106  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1107  return llvm::makeArrayRef(g_settings_clear_options);
1108  }
1109 
1110  bool m_clear_all = false;
1111  };
1112 
1113 protected:
1114  bool DoExecute(Args &command, CommandReturnObject &result) override {
1116  const size_t argc = command.GetArgumentCount();
1117 
1118  if (m_options.m_clear_all) {
1119  if (argc != 0) {
1120  result.AppendError("'settings clear --all' doesn't take any arguments");
1122  return false;
1123  }
1124  GetDebugger().GetValueProperties()->Clear();
1125  return result.Succeeded();
1126  }
1127 
1128  if (argc != 1) {
1129  result.AppendError("'settings clear' takes exactly one argument");
1131  return false;
1132  }
1133 
1134  const char *var_name = command.GetArgumentAtIndex(0);
1135  if ((var_name == nullptr) || (var_name[0] == '\0')) {
1136  result.AppendError("'settings clear' command requires a valid variable "
1137  "name; No value supplied");
1139  return false;
1140  }
1141 
1142  Status error(GetDebugger().SetPropertyValue(
1143  &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
1144  if (error.Fail()) {
1145  result.AppendError(error.AsCString());
1147  return false;
1148  }
1149 
1150  return result.Succeeded();
1151  }
1152 
1153  private:
1155 };
1156 
1157 // CommandObjectMultiwordSettings
1158 
1159 CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
1160  CommandInterpreter &interpreter)
1161  : CommandObjectMultiword(interpreter, "settings",
1162  "Commands for managing LLDB settings.",
1163  "settings <subcommand> [<command-options>]") {
1164  LoadSubCommand("set",
1165  CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
1166  LoadSubCommand("show",
1167  CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
1168  LoadSubCommand("list",
1169  CommandObjectSP(new CommandObjectSettingsList(interpreter)));
1170  LoadSubCommand("remove",
1171  CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
1172  LoadSubCommand("replace", CommandObjectSP(
1173  new CommandObjectSettingsReplace(interpreter)));
1175  "insert-before",
1176  CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
1178  "insert-after",
1179  CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
1180  LoadSubCommand("append",
1181  CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
1182  LoadSubCommand("clear",
1183  CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
1184  LoadSubCommand("write",
1185  CommandObjectSP(new CommandObjectSettingsWrite(interpreter)));
1186  LoadSubCommand("read",
1187  CommandObjectSP(new CommandObjectSettingsRead(interpreter)));
1188 }
1189 
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
std::vector< CommandArgumentData > CommandArgumentEntry
A command line argument class.
Definition: Args.h:33
bool empty() const
Definition: Args.h:118
A class that represents a running process on the host machine.
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
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
CommandObjectSettingsList(CommandInterpreter &interpreter)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition: Args.cpp:254
bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override
A file utility class.
Definition: FileSpec.h:56
bool DoExecute(Args &args, CommandReturnObject &result) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
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.
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx. ...
Definition: Args.cpp:256
CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
CommandObjectSettingsSet(CommandInterpreter &interpreter)
"lldb/Utility/ArgCompletionRequest.h"
std::vector< OptionArgElement > OptionElementVector
Definition: Options.h:41
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
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
Options * GetOptions() override
size_t EOL()
Output and End of Line character to the stream.
Definition: Stream.cpp:127
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
bool DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectSettingsReplace(CommandInterpreter &interpreter)
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandObjectSettingsRemove(CommandInterpreter &interpreter)
void OptionParsingStarting(ExecutionContext *execution_context) override
bool DoExecute(Args &command, CommandReturnObject &result) override
bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override
bool Success() const
Test for success condition.
Definition: Status.cpp:288
CommandObjectSettingsShow(CommandInterpreter &interpreter)
bool DoExecute(Args &args, CommandReturnObject &result) override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
CommandObjectSettingsRead(CommandInterpreter &interpreter)
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
CommandObjectSettingsClear(CommandInterpreter &interpreter)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
CommandObjectSettingsWrite(CommandInterpreter &interpreter)
bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override
A command line option parsing protocol class.
Definition: Options.h:62
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
void void AppendError(llvm::StringRef in_string)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
bool Fail() const
Test for error condition.
Definition: Status.cpp:182
void DumpDescription(CommandInterpreter &interpreter, Stream &strm, uint32_t output_width, bool display_qualified_name) const
Definition: Property.cpp:264
bool DoExecute(Args &args, CommandReturnObject &result) override
Definition: SBAddress.h:15
bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override
const Args & GetParsedLine() const
void OptionParsingStarting(ExecutionContext *execution_context) override
CommandObjectSettingsAppend(CommandInterpreter &interpreter)
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:131
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:348
void SetStatus(lldb::ReturnStatus status)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
An error handling class.
Definition: Status.h:44