LLDB  mainline
CommandObjectSettings.cpp
Go to the documentation of this file.
1 //===-- CommandObjectSettings.cpp -------------------------------*- C++ -*-===//
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 
24 static constexpr OptionDefinition g_settings_set_options[] = {
25  // clang-format off
26  { LLDB_OPT_SET_2, false, "global", 'g', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Apply the new value to the global default value." },
27  { LLDB_OPT_SET_2, false, "force", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Force an empty value to be accepted as the default." }
28  // clang-format on
29 };
30 
32 public:
34  : CommandObjectRaw(interpreter, "settings set",
35  "Set the value of the specified debugger setting."),
36  m_options() {
39  CommandArgumentData var_name_arg;
40  CommandArgumentData value_arg;
41 
42  // Define the first (and only) variant of this arg.
44  var_name_arg.arg_repetition = eArgRepeatPlain;
45 
46  // There is only one variant this argument could be; put it into the
47  // argument entry.
48  arg1.push_back(var_name_arg);
49 
50  // Define the first (and only) variant of this arg.
51  value_arg.arg_type = eArgTypeValue;
52  value_arg.arg_repetition = eArgRepeatPlain;
53 
54  // There is only one variant this argument could be; put it into the
55  // argument entry.
56  arg2.push_back(value_arg);
57 
58  // Push the data for the first argument into the m_arguments vector.
59  m_arguments.push_back(arg1);
60  m_arguments.push_back(arg2);
61 
62  SetHelpLong(
63  "\nWhen setting a dictionary or array variable, you can set multiple entries \
64 at once by giving the values to the set command. For example:"
65  R"(
66 
67 (lldb) settings set target.run-args value1 value2 value3
68 (lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345
69 
70 (lldb) settings show target.run-args
71  [0]: 'value1'
72  [1]: 'value2'
73  [3]: 'value3'
74 (lldb) settings show target.env-vars
75  'MYPATH=~/.:/usr/bin'
76  'SOME_ENV_VAR=12345'
77 
78 )"
79  "Warning: The 'set' command re-sets the entire array or dictionary. If you \
80 just want to add, remove or update individual values (or add something to \
81 the end), use one of the other settings sub-commands: append, replace, \
82 insert-before or insert-after.");
83  }
84 
85  ~CommandObjectSettingsSet() override = default;
86 
87  // Overrides base class's behavior where WantsCompletion =
88  // !WantsRawCommandString.
89  bool WantsCompletion() override { return true; }
90 
91  Options *GetOptions() override { return &m_options; }
92 
93  class CommandOptions : public Options {
94  public:
95  CommandOptions() : Options(), m_global(false) {}
96 
97  ~CommandOptions() override = default;
98 
99  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
100  ExecutionContext *execution_context) override {
101  Status error;
102  const int short_option = m_getopt_table[option_idx].val;
103 
104  switch (short_option) {
105  case 'f':
106  m_force = true;
107  break;
108  case 'g':
109  m_global = true;
110  break;
111  default:
112  error.SetErrorStringWithFormat("unrecognized options '%c'",
113  short_option);
114  break;
115  }
116 
117  return error;
118  }
119 
120  void OptionParsingStarting(ExecutionContext *execution_context) override {
121  m_global = false;
122  m_force = false;
123  }
124 
125  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
126  return llvm::makeArrayRef(g_settings_set_options);
127  }
128 
129  // Instance variables to hold the values for command options.
130  bool m_global;
131  bool m_force;
132  };
133 
135  CompletionRequest &request,
136  OptionElementVector &opt_element_vector) override {
137 
138  const size_t argc = request.GetParsedLine().GetArgumentCount();
139  const char *arg = nullptr;
140  int setting_var_idx;
141  for (setting_var_idx = 0; setting_var_idx < static_cast<int>(argc);
142  ++setting_var_idx) {
143  arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
144  if (arg && arg[0] != '-')
145  break; // We found our setting variable name index
146  }
147  if (request.GetCursorIndex() == setting_var_idx) {
148  // Attempting to complete setting variable name
149  CommandCompletions::InvokeCommonCompletionCallbacks(
150  GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
151  request, nullptr);
152  } else {
153  arg =
154  request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
155 
156  if (arg) {
157  if (arg[0] == '-') {
158  // Complete option name
159  } else {
160  // Complete setting value
161  const char *setting_var_name =
162  request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
163  Status error;
164  lldb::OptionValueSP value_sp(GetDebugger().GetPropertyValue(
165  &m_exe_ctx, setting_var_name, false, error));
166  if (value_sp) {
167  value_sp->AutoComplete(m_interpreter, request);
168  }
169  }
170  }
171  }
172  return request.GetNumberOfMatches();
173  }
174 
175 protected:
176  bool DoExecute(llvm::StringRef command,
177  CommandReturnObject &result) override {
178  Args cmd_args(command);
179 
180  // Process possible options.
181  if (!ParseOptions(cmd_args, result))
182  return false;
183 
184  const size_t min_argc = m_options.m_force ? 1 : 2;
185  const size_t argc = cmd_args.GetArgumentCount();
186 
187  if ((argc < min_argc) && (!m_options.m_global)) {
188  result.AppendError("'settings set' takes more arguments");
190  return false;
191  }
192 
193  const char *var_name = cmd_args.GetArgumentAtIndex(0);
194  if ((var_name == nullptr) || (var_name[0] == '\0')) {
195  result.AppendError(
196  "'settings set' command requires a valid variable name");
198  return false;
199  }
200 
201  // A missing value corresponds to clearing the setting when "force" is
202  // specified.
203  if (argc == 1 && m_options.m_force) {
204  Status error(GetDebugger().SetPropertyValue(
205  &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
206  if (error.Fail()) {
207  result.AppendError(error.AsCString());
209  return false;
210  }
211  return result.Succeeded();
212  }
213 
214  // Split the raw command into var_name and value pair.
215  llvm::StringRef raw_str(command);
216  std::string var_value_string = raw_str.split(var_name).second.str();
217  const char *var_value_cstr =
218  Args::StripSpaces(var_value_string, true, false, false);
219 
220  Status error;
221  if (m_options.m_global) {
222  error = GetDebugger().SetPropertyValue(nullptr, eVarSetOperationAssign,
223  var_name, var_value_cstr);
224  }
225 
226  if (error.Success()) {
227  // FIXME this is the same issue as the one in commands script import
228  // we could be setting target.load-script-from-symbol-file which would
229  // cause Python scripts to be loaded, which could run LLDB commands (e.g.
230  // settings set target.process.python-os-plugin-path) and cause a crash
231  // if we did not clear the command's exe_ctx first
232  ExecutionContext exe_ctx(m_exe_ctx);
233  m_exe_ctx.Clear();
234  error = GetDebugger().SetPropertyValue(&exe_ctx, eVarSetOperationAssign,
235  var_name, var_value_cstr);
236  }
237 
238  if (error.Fail()) {
239  result.AppendError(error.AsCString());
241  return false;
242  } else {
244  }
245 
246  return result.Succeeded();
247  }
248 
249 private:
250  CommandOptions m_options;
251 };
252 
253 // CommandObjectSettingsShow -- Show current values
254 
256 public:
258  : CommandObjectParsed(interpreter, "settings show",
259  "Show matching debugger settings and their current "
260  "values. Defaults to showing all settings.",
261  nullptr) {
263  CommandArgumentData var_name_arg;
264 
265  // Define the first (and only) variant of this arg.
266  var_name_arg.arg_type = eArgTypeSettingVariableName;
267  var_name_arg.arg_repetition = eArgRepeatOptional;
268 
269  // There is only one variant this argument could be; put it into the
270  // argument entry.
271  arg1.push_back(var_name_arg);
272 
273  // Push the data for the first argument into the m_arguments vector.
274  m_arguments.push_back(arg1);
275  }
276 
277  ~CommandObjectSettingsShow() override = default;
278 
280  CompletionRequest &request,
281  OptionElementVector &opt_element_vector) override {
282  CommandCompletions::InvokeCommonCompletionCallbacks(
283  GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
284  request, nullptr);
285  return request.GetNumberOfMatches();
286  }
287 
288 protected:
289  bool DoExecute(Args &args, CommandReturnObject &result) override {
291 
292  if (!args.empty()) {
293  for (const auto &arg : args) {
294  Status error(GetDebugger().DumpPropertyValue(
295  &m_exe_ctx, result.GetOutputStream(), arg.ref,
296  OptionValue::eDumpGroupValue));
297  if (error.Success()) {
298  result.GetOutputStream().EOL();
299  } else {
300  result.AppendError(error.AsCString());
302  }
303  }
304  } else {
305  GetDebugger().DumpAllPropertyValues(&m_exe_ctx, result.GetOutputStream(),
306  OptionValue::eDumpGroupValue);
307  }
308 
309  return result.Succeeded();
310  }
311 };
312 
313 // CommandObjectSettingsWrite -- Write settings to file
314 
315 static constexpr OptionDefinition g_settings_write_options[] = {
316  // clang-format off
317  { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file into which to write the settings." },
318  { LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append to saved settings file if it exists."},
319  // clang-format on
320 };
321 
323 public:
326  interpreter, "settings export",
327  "Write matching debugger settings and their "
328  "current values to a file that can be read in with "
329  "\"settings read\". Defaults to writing all settings.",
330  nullptr),
331  m_options() {
333  CommandArgumentData var_name_arg;
334 
335  // Define the first (and only) variant of this arg.
336  var_name_arg.arg_type = eArgTypeSettingVariableName;
337  var_name_arg.arg_repetition = eArgRepeatOptional;
338 
339  // There is only one variant this argument could be; put it into the
340  // argument entry.
341  arg1.push_back(var_name_arg);
342 
343  // Push the data for the first argument into the m_arguments vector.
344  m_arguments.push_back(arg1);
345  }
346 
347  ~CommandObjectSettingsWrite() override = default;
348 
349  Options *GetOptions() override { return &m_options; }
350 
351  class CommandOptions : public Options {
352  public:
354 
355  ~CommandOptions() override = default;
356 
357  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
358  ExecutionContext *execution_context) override {
359  Status error;
360  const int short_option = m_getopt_table[option_idx].val;
361 
362  switch (short_option) {
363  case 'f':
364  m_filename.assign(option_arg);
365  break;
366  case 'a':
367  m_append = true;
368  break;
369  default:
370  error.SetErrorStringWithFormat("unrecognized option '%c'",
371  short_option);
372  break;
373  }
374 
375  return error;
376  }
377 
378  void OptionParsingStarting(ExecutionContext *execution_context) override {
379  m_filename.clear();
380  m_append = false;
381  }
382 
383  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
384  return llvm::makeArrayRef(g_settings_write_options);
385  }
386 
387  // Instance variables to hold the values for command options.
388  std::string m_filename;
389  bool m_append = false;
390  };
391 
392 protected:
393  bool DoExecute(Args &args, CommandReturnObject &result) override {
394  FileSpec file_spec(m_options.m_filename);
395  FileSystem::Instance().Resolve(file_spec);
396  std::string path(file_spec.GetPath());
397  uint32_t options = File::OpenOptions::eOpenOptionWrite |
398  File::OpenOptions::eOpenOptionCanCreate;
399  if (m_options.m_append)
400  options |= File::OpenOptions::eOpenOptionAppend;
401  else
402  options |= File::OpenOptions::eOpenOptionTruncate;
403 
404  StreamFile out_file(path.c_str(), options,
405  lldb::eFilePermissionsFileDefault);
406 
407  if (!out_file.GetFile().IsValid()) {
408  result.AppendErrorWithFormat("%s: unable to write to file", path.c_str());
410  return false;
411  }
412 
413  // Exporting should not be context sensitive.
414  ExecutionContext clean_ctx;
415 
416  if (args.empty()) {
417  GetDebugger().DumpAllPropertyValues(&clean_ctx, out_file,
418  OptionValue::eDumpGroupExport);
419  return result.Succeeded();
420  }
421 
422  for (const auto &arg : args) {
423  Status error(GetDebugger().DumpPropertyValue(
424  &clean_ctx, out_file, arg.ref, OptionValue::eDumpGroupExport));
425  if (!error.Success()) {
426  result.AppendError(error.AsCString());
428  }
429  }
430 
431  return result.Succeeded();
432  }
433 
434 private:
435  CommandOptions m_options;
436 };
437 
438 // CommandObjectSettingsRead -- Read settings from file
439 
440 static constexpr OptionDefinition g_settings_read_options[] = {
441  // clang-format off
442  {LLDB_OPT_SET_ALL, true, "file",'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file from which to read the breakpoints." },
443  // clang-format on
444 };
445 
447 public:
450  interpreter, "settings read",
451  "Read settings previously saved to a file with \"settings write\".",
452  nullptr),
453  m_options() {}
454 
455  ~CommandObjectSettingsRead() override = default;
456 
457  Options *GetOptions() override { return &m_options; }
458 
459  class CommandOptions : public Options {
460  public:
462 
463  ~CommandOptions() override = default;
464 
465  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
466  ExecutionContext *execution_context) override {
467  Status error;
468  const int short_option = m_getopt_table[option_idx].val;
469 
470  switch (short_option) {
471  case 'f':
472  m_filename.assign(option_arg);
473  break;
474  default:
475  error.SetErrorStringWithFormat("unrecognized option '%c'",
476  short_option);
477  break;
478  }
479 
480  return error;
481  }
482 
483  void OptionParsingStarting(ExecutionContext *execution_context) override {
484  m_filename.clear();
485  }
486 
487  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
488  return llvm::makeArrayRef(g_settings_read_options);
489  }
490 
491  // Instance variables to hold the values for command options.
492  std::string m_filename;
493  };
494 
495 protected:
496  bool DoExecute(Args &command, CommandReturnObject &result) override {
497  FileSpec file(m_options.m_filename);
498  FileSystem::Instance().Resolve(file);
499  ExecutionContext clean_ctx;
501  options.SetAddToHistory(false);
502  options.SetEchoCommands(false);
503  options.SetPrintResults(true);
504  options.SetStopOnError(false);
505  m_interpreter.HandleCommandsFromFile(file, &clean_ctx, options, result);
506  return result.Succeeded();
507  }
508 
509 private:
510  CommandOptions m_options;
511 };
512 
513 // CommandObjectSettingsList -- List settable variables
514 
516 public:
518  : CommandObjectParsed(interpreter, "settings list",
519  "List and describe matching debugger settings. "
520  "Defaults to all listing all settings.",
521  nullptr) {
523  CommandArgumentData var_name_arg;
524  CommandArgumentData prefix_name_arg;
525 
526  // Define the first variant of this arg.
527  var_name_arg.arg_type = eArgTypeSettingVariableName;
528  var_name_arg.arg_repetition = eArgRepeatOptional;
529 
530  // Define the second variant of this arg.
531  prefix_name_arg.arg_type = eArgTypeSettingPrefix;
532  prefix_name_arg.arg_repetition = eArgRepeatOptional;
533 
534  arg.push_back(var_name_arg);
535  arg.push_back(prefix_name_arg);
536 
537  // Push the data for the first argument into the m_arguments vector.
538  m_arguments.push_back(arg);
539  }
540 
541  ~CommandObjectSettingsList() override = default;
542 
544  CompletionRequest &request,
545  OptionElementVector &opt_element_vector) override {
546  CommandCompletions::InvokeCommonCompletionCallbacks(
547  GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
548  request, nullptr);
549  return request.GetNumberOfMatches();
550  }
551 
552 protected:
553  bool DoExecute(Args &args, CommandReturnObject &result) override {
555 
556  const bool will_modify = false;
557  const size_t argc = args.GetArgumentCount();
558  if (argc > 0) {
559  const bool dump_qualified_name = true;
560 
561  // TODO: Convert to StringRef based enumeration. Requires converting
562  // GetPropertyAtPath first.
563  for (size_t i = 0; i < argc; ++i) {
564  const char *property_path = args.GetArgumentAtIndex(i);
565 
566  const Property *property =
567  GetDebugger().GetValueProperties()->GetPropertyAtPath(
568  &m_exe_ctx, will_modify, property_path);
569 
570  if (property) {
571  property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
572  dump_qualified_name);
573  } else {
574  result.AppendErrorWithFormat("invalid property path '%s'",
575  property_path);
577  }
578  }
579  } else {
580  GetDebugger().DumpAllDescriptions(m_interpreter,
581  result.GetOutputStream());
582  }
583 
584  return result.Succeeded();
585  }
586 };
587 
588 // CommandObjectSettingsRemove
589 
591 public:
593  : CommandObjectRaw(interpreter, "settings remove",
594  "Remove a value from a setting, specified by array "
595  "index or dictionary key.") {
598  CommandArgumentData var_name_arg;
599  CommandArgumentData index_arg;
600  CommandArgumentData key_arg;
601 
602  // Define the first (and only) variant of this arg.
603  var_name_arg.arg_type = eArgTypeSettingVariableName;
604  var_name_arg.arg_repetition = eArgRepeatPlain;
605 
606  // There is only one variant this argument could be; put it into the
607  // argument entry.
608  arg1.push_back(var_name_arg);
609 
610  // Define the first variant of this arg.
611  index_arg.arg_type = eArgTypeSettingIndex;
612  index_arg.arg_repetition = eArgRepeatPlain;
613 
614  // Define the second variant of this arg.
615  key_arg.arg_type = eArgTypeSettingKey;
617 
618  // Push both variants into this arg
619  arg2.push_back(index_arg);
620  arg2.push_back(key_arg);
621 
622  // Push the data for the first argument into the m_arguments vector.
623  m_arguments.push_back(arg1);
624  m_arguments.push_back(arg2);
625  }
626 
627  ~CommandObjectSettingsRemove() override = default;
628 
630  CompletionRequest &request,
631  OptionElementVector &opt_element_vector) override {
632  if (request.GetCursorIndex() < 2)
633  CommandCompletions::InvokeCommonCompletionCallbacks(
634  GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
635  request, nullptr);
636  return request.GetNumberOfMatches();
637  }
638 
639 protected:
640  bool DoExecute(llvm::StringRef command,
641  CommandReturnObject &result) override {
643 
644  Args cmd_args(command);
645 
646  // Process possible options.
647  if (!ParseOptions(cmd_args, result))
648  return false;
649 
650  const size_t argc = cmd_args.GetArgumentCount();
651  if (argc == 0) {
652  result.AppendError("'settings set' takes an array or dictionary item, or "
653  "an array followed by one or more indexes, or a "
654  "dictionary followed by one or more key names to "
655  "remove");
657  return false;
658  }
659 
660  const char *var_name = cmd_args.GetArgumentAtIndex(0);
661  if ((var_name == nullptr) || (var_name[0] == '\0')) {
662  result.AppendError(
663  "'settings set' command requires a valid variable name");
665  return false;
666  }
667 
668  // Split the raw command into var_name and value pair.
669  llvm::StringRef raw_str(command);
670  std::string var_value_string = raw_str.split(var_name).second.str();
671  const char *var_value_cstr =
672  Args::StripSpaces(var_value_string, true, true, false);
673 
674  Status error(GetDebugger().SetPropertyValue(
675  &m_exe_ctx, eVarSetOperationRemove, var_name, var_value_cstr));
676  if (error.Fail()) {
677  result.AppendError(error.AsCString());
679  return false;
680  }
681 
682  return result.Succeeded();
683  }
684 };
685 
686 // CommandObjectSettingsReplace
687 
689 public:
691  : CommandObjectRaw(interpreter, "settings replace",
692  "Replace the debugger setting value specified by "
693  "array index or dictionary key.") {
697  CommandArgumentData var_name_arg;
698  CommandArgumentData index_arg;
699  CommandArgumentData key_arg;
700  CommandArgumentData value_arg;
701 
702  // Define the first (and only) variant of this arg.
703  var_name_arg.arg_type = eArgTypeSettingVariableName;
704  var_name_arg.arg_repetition = eArgRepeatPlain;
705 
706  // There is only one variant this argument could be; put it into the
707  // argument entry.
708  arg1.push_back(var_name_arg);
709 
710  // Define the first (variant of this arg.
711  index_arg.arg_type = eArgTypeSettingIndex;
712  index_arg.arg_repetition = eArgRepeatPlain;
713 
714  // Define the second (variant of this arg.
715  key_arg.arg_type = eArgTypeSettingKey;
717 
718  // Put both variants into this arg
719  arg2.push_back(index_arg);
720  arg2.push_back(key_arg);
721 
722  // Define the first (and only) variant of this arg.
723  value_arg.arg_type = eArgTypeValue;
724  value_arg.arg_repetition = eArgRepeatPlain;
725 
726  // There is only one variant this argument could be; put it into the
727  // argument entry.
728  arg3.push_back(value_arg);
729 
730  // Push the data for the first argument into the m_arguments vector.
731  m_arguments.push_back(arg1);
732  m_arguments.push_back(arg2);
733  m_arguments.push_back(arg3);
734  }
735 
736  ~CommandObjectSettingsReplace() override = default;
737 
738  // Overrides base class's behavior where WantsCompletion =
739  // !WantsRawCommandString.
740  bool WantsCompletion() override { return true; }
741 
743  CompletionRequest &request,
744  OptionElementVector &opt_element_vector) override {
745  // Attempting to complete variable name
746  if (request.GetCursorIndex() < 2)
747  CommandCompletions::InvokeCommonCompletionCallbacks(
748  GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
749  request, nullptr);
750 
751  return request.GetNumberOfMatches();
752  }
753 
754 protected:
755  bool DoExecute(llvm::StringRef command,
756  CommandReturnObject &result) override {
758 
759  Args cmd_args(command);
760  const char *var_name = cmd_args.GetArgumentAtIndex(0);
761  if ((var_name == nullptr) || (var_name[0] == '\0')) {
762  result.AppendError("'settings replace' command requires a valid variable "
763  "name; No value supplied");
765  return false;
766  }
767 
768  // Split the raw command into var_name, index_value, and value triple.
769  llvm::StringRef raw_str(command);
770  std::string var_value_string = raw_str.split(var_name).second.str();
771  const char *var_value_cstr =
772  Args::StripSpaces(var_value_string, true, true, false);
773 
774  Status error(GetDebugger().SetPropertyValue(
775  &m_exe_ctx, eVarSetOperationReplace, var_name, var_value_cstr));
776  if (error.Fail()) {
777  result.AppendError(error.AsCString());
779  return false;
780  } else {
782  }
783 
784  return result.Succeeded();
785  }
786 };
787 
788 // CommandObjectSettingsInsertBefore
789 
791 public:
793  : CommandObjectRaw(interpreter, "settings insert-before",
794  "Insert one or more values into an debugger array "
795  "setting immediately before the specified element "
796  "index.") {
800  CommandArgumentData var_name_arg;
801  CommandArgumentData index_arg;
802  CommandArgumentData value_arg;
803 
804  // Define the first (and only) variant of this arg.
805  var_name_arg.arg_type = eArgTypeSettingVariableName;
806  var_name_arg.arg_repetition = eArgRepeatPlain;
807 
808  // There is only one variant this argument could be; put it into the
809  // argument entry.
810  arg1.push_back(var_name_arg);
811 
812  // Define the first (variant of this arg.
813  index_arg.arg_type = eArgTypeSettingIndex;
814  index_arg.arg_repetition = eArgRepeatPlain;
815 
816  // There is only one variant this argument could be; put it into the
817  // argument entry.
818  arg2.push_back(index_arg);
819 
820  // Define the first (and only) variant of this arg.
821  value_arg.arg_type = eArgTypeValue;
822  value_arg.arg_repetition = eArgRepeatPlain;
823 
824  // There is only one variant this argument could be; put it into the
825  // argument entry.
826  arg3.push_back(value_arg);
827 
828  // Push the data for the first argument into the m_arguments vector.
829  m_arguments.push_back(arg1);
830  m_arguments.push_back(arg2);
831  m_arguments.push_back(arg3);
832  }
833 
834  ~CommandObjectSettingsInsertBefore() override = default;
835 
836  // Overrides base class's behavior where WantsCompletion =
837  // !WantsRawCommandString.
838  bool WantsCompletion() override { return true; }
839 
841  CompletionRequest &request,
842  OptionElementVector &opt_element_vector) override {
843  // Attempting to complete variable name
844  if (request.GetCursorIndex() < 2)
845  CommandCompletions::InvokeCommonCompletionCallbacks(
846  GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
847  request, nullptr);
848 
849  return request.GetNumberOfMatches();
850  }
851 
852 protected:
853  bool DoExecute(llvm::StringRef command,
854  CommandReturnObject &result) override {
856 
857  Args cmd_args(command);
858  const size_t argc = cmd_args.GetArgumentCount();
859 
860  if (argc < 3) {
861  result.AppendError("'settings insert-before' takes more arguments");
863  return false;
864  }
865 
866  const char *var_name = cmd_args.GetArgumentAtIndex(0);
867  if ((var_name == nullptr) || (var_name[0] == '\0')) {
868  result.AppendError("'settings insert-before' command requires a valid "
869  "variable name; No value supplied");
871  return false;
872  }
873 
874  // Split the raw command into var_name, index_value, and value triple.
875  llvm::StringRef raw_str(command);
876  std::string var_value_string = raw_str.split(var_name).second.str();
877  const char *var_value_cstr =
878  Args::StripSpaces(var_value_string, true, true, false);
879 
880  Status error(GetDebugger().SetPropertyValue(
881  &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value_cstr));
882  if (error.Fail()) {
883  result.AppendError(error.AsCString());
885  return false;
886  }
887 
888  return result.Succeeded();
889  }
890 };
891 
892 // CommandObjectSettingInsertAfter
893 
895 public:
897  : CommandObjectRaw(interpreter, "settings insert-after",
898  "Insert one or more values into a debugger array "
899  "settings after the specified element index.") {
903  CommandArgumentData var_name_arg;
904  CommandArgumentData index_arg;
905  CommandArgumentData value_arg;
906 
907  // Define the first (and only) variant of this arg.
908  var_name_arg.arg_type = eArgTypeSettingVariableName;
909  var_name_arg.arg_repetition = eArgRepeatPlain;
910 
911  // There is only one variant this argument could be; put it into the
912  // argument entry.
913  arg1.push_back(var_name_arg);
914 
915  // Define the first (variant of this arg.
916  index_arg.arg_type = eArgTypeSettingIndex;
917  index_arg.arg_repetition = eArgRepeatPlain;
918 
919  // There is only one variant this argument could be; put it into the
920  // argument entry.
921  arg2.push_back(index_arg);
922 
923  // Define the first (and only) variant of this arg.
924  value_arg.arg_type = eArgTypeValue;
925  value_arg.arg_repetition = eArgRepeatPlain;
926 
927  // There is only one variant this argument could be; put it into the
928  // argument entry.
929  arg3.push_back(value_arg);
930 
931  // Push the data for the first argument into the m_arguments vector.
932  m_arguments.push_back(arg1);
933  m_arguments.push_back(arg2);
934  m_arguments.push_back(arg3);
935  }
936 
937  ~CommandObjectSettingsInsertAfter() override = default;
938 
939  // Overrides base class's behavior where WantsCompletion =
940  // !WantsRawCommandString.
941  bool WantsCompletion() override { return true; }
942 
944  CompletionRequest &request,
945  OptionElementVector &opt_element_vector) override {
946  // Attempting to complete variable name
947  if (request.GetCursorIndex() < 2)
948  CommandCompletions::InvokeCommonCompletionCallbacks(
949  GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
950  request, nullptr);
951 
952  return request.GetNumberOfMatches();
953  }
954 
955 protected:
956  bool DoExecute(llvm::StringRef command,
957  CommandReturnObject &result) override {
959 
960  Args cmd_args(command);
961  const size_t argc = cmd_args.GetArgumentCount();
962 
963  if (argc < 3) {
964  result.AppendError("'settings insert-after' takes more arguments");
966  return false;
967  }
968 
969  const char *var_name = cmd_args.GetArgumentAtIndex(0);
970  if ((var_name == nullptr) || (var_name[0] == '\0')) {
971  result.AppendError("'settings insert-after' command requires a valid "
972  "variable name; No value supplied");
974  return false;
975  }
976 
977  // Split the raw command into var_name, index_value, and value triple.
978  llvm::StringRef raw_str(command);
979  std::string var_value_string = raw_str.split(var_name).second.str();
980  const char *var_value_cstr =
981  Args::StripSpaces(var_value_string, true, true, false);
982 
983  Status error(GetDebugger().SetPropertyValue(
984  &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value_cstr));
985  if (error.Fail()) {
986  result.AppendError(error.AsCString());
988  return false;
989  }
990 
991  return result.Succeeded();
992  }
993 };
994 
995 // CommandObjectSettingsAppend
996 
998 public:
1000  : CommandObjectRaw(interpreter, "settings append",
1001  "Append one or more values to a debugger array, "
1002  "dictionary, or string setting.") {
1003  CommandArgumentEntry arg1;
1004  CommandArgumentEntry arg2;
1005  CommandArgumentData var_name_arg;
1006  CommandArgumentData value_arg;
1007 
1008  // Define the first (and only) variant of this arg.
1009  var_name_arg.arg_type = eArgTypeSettingVariableName;
1010  var_name_arg.arg_repetition = eArgRepeatPlain;
1011 
1012  // There is only one variant this argument could be; put it into the
1013  // argument entry.
1014  arg1.push_back(var_name_arg);
1015 
1016  // Define the first (and only) variant of this arg.
1017  value_arg.arg_type = eArgTypeValue;
1018  value_arg.arg_repetition = eArgRepeatPlain;
1019 
1020  // There is only one variant this argument could be; put it into the
1021  // argument entry.
1022  arg2.push_back(value_arg);
1023 
1024  // Push the data for the first argument into the m_arguments vector.
1025  m_arguments.push_back(arg1);
1026  m_arguments.push_back(arg2);
1027  }
1028 
1029  ~CommandObjectSettingsAppend() override = default;
1030 
1031  // Overrides base class's behavior where WantsCompletion =
1032  // !WantsRawCommandString.
1033  bool WantsCompletion() override { return true; }
1034 
1036  CompletionRequest &request,
1037  OptionElementVector &opt_element_vector) override {
1038  // Attempting to complete variable name
1039  if (request.GetCursorIndex() < 2)
1040  CommandCompletions::InvokeCommonCompletionCallbacks(
1041  GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
1042  request, nullptr);
1043 
1044  return request.GetNumberOfMatches();
1045  }
1046 
1047 protected:
1048  bool DoExecute(llvm::StringRef command,
1049  CommandReturnObject &result) override {
1051  Args cmd_args(command);
1052  const size_t argc = cmd_args.GetArgumentCount();
1053 
1054  if (argc < 2) {
1055  result.AppendError("'settings append' takes more arguments");
1057  return false;
1058  }
1059 
1060  const char *var_name = cmd_args.GetArgumentAtIndex(0);
1061  if ((var_name == nullptr) || (var_name[0] == '\0')) {
1062  result.AppendError("'settings append' command requires a valid variable "
1063  "name; No value supplied");
1065  return false;
1066  }
1067 
1068  // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
1069  // character string later on.
1070 
1071  // Split the raw command into var_name and value pair.
1072  llvm::StringRef raw_str(command);
1073  std::string var_value_string = raw_str.split(var_name).second.str();
1074  const char *var_value_cstr =
1075  Args::StripSpaces(var_value_string, true, true, false);
1076 
1077  Status error(GetDebugger().SetPropertyValue(
1078  &m_exe_ctx, eVarSetOperationAppend, var_name, var_value_cstr));
1079  if (error.Fail()) {
1080  result.AppendError(error.AsCString());
1082  return false;
1083  }
1084 
1085  return result.Succeeded();
1086  }
1087 };
1088 
1089 // CommandObjectSettingsClear
1090 
1092 public:
1095  interpreter, "settings clear",
1096  "Clear a debugger setting array, dictionary, or string.", nullptr) {
1098  CommandArgumentData var_name_arg;
1099 
1100  // Define the first (and only) variant of this arg.
1101  var_name_arg.arg_type = eArgTypeSettingVariableName;
1102  var_name_arg.arg_repetition = eArgRepeatPlain;
1103 
1104  // There is only one variant this argument could be; put it into the
1105  // argument entry.
1106  arg.push_back(var_name_arg);
1107 
1108  // Push the data for the first argument into the m_arguments vector.
1109  m_arguments.push_back(arg);
1110  }
1111 
1112  ~CommandObjectSettingsClear() override = default;
1113 
1115  CompletionRequest &request,
1116  OptionElementVector &opt_element_vector) override {
1117  // Attempting to complete variable name
1118  if (request.GetCursorIndex() < 2)
1119  CommandCompletions::InvokeCommonCompletionCallbacks(
1120  GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
1121  request, nullptr);
1122 
1123  return request.GetNumberOfMatches();
1124  }
1125 
1126 protected:
1127  bool DoExecute(Args &command, CommandReturnObject &result) override {
1129  const size_t argc = command.GetArgumentCount();
1130 
1131  if (argc != 1) {
1132  result.AppendError("'settings clear' takes exactly one argument");
1134  return false;
1135  }
1136 
1137  const char *var_name = command.GetArgumentAtIndex(0);
1138  if ((var_name == nullptr) || (var_name[0] == '\0')) {
1139  result.AppendError("'settings clear' command requires a valid variable "
1140  "name; No value supplied");
1142  return false;
1143  }
1144 
1145  Status error(GetDebugger().SetPropertyValue(
1146  &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
1147  if (error.Fail()) {
1148  result.AppendError(error.AsCString());
1150  return false;
1151  }
1152 
1153  return result.Succeeded();
1154  }
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 
int HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
std::vector< CommandArgumentData > CommandArgumentEntry
A command line argument class.
Definition: Args.h:32
bool empty() const
Definition: Args.h:113
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
int HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
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)
int 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:55
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.
std::size_t GetNumberOfMatches() const
int HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override
static constexpr OptionDefinition g_settings_write_options[]
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
static constexpr OptionDefinition g_settings_read_options[]
int 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
CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
int HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
bool DoExecute(Args &command, CommandReturnObject &result) override
int HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
CommandObjectSettingsReplace(CommandInterpreter &interpreter)
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:287
int HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
CommandObjectSettingsShow(CommandInterpreter &interpreter)
bool DoExecute(Args &args, CommandReturnObject &result) override
CommandObjectSettingsRead(CommandInterpreter &interpreter)
bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override
#define LLDB_OPT_SET_2
Definition: lldb-defines.h:112
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 void AppendError(llvm::StringRef in_string)
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
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
#define LLDB_OPT_SET_ALL
Definition: lldb-defines.h:110
const Args & GetParsedLine() const
void OptionParsingStarting(ExecutionContext *execution_context) override
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:255
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:130
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
int HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:376
static constexpr OptionDefinition g_settings_set_options[]
void SetStatus(lldb::ReturnStatus status)
An error handling class.
Definition: Status.h:44