LLDB  mainline
CommandObjectCommands.cpp
Go to the documentation of this file.
1 //===-- CommandObjectCommands.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 
9 #include "llvm/ADT/StringRef.h"
10 
11 #include "CommandObjectCommands.h"
12 #include "CommandObjectHelp.h"
13 #include "lldb/Core/Debugger.h"
14 #include "lldb/Core/IOHandler.h"
15 #include "lldb/Host/OptionParser.h"
26 #include "lldb/Utility/Args.h"
28 
29 using namespace lldb;
30 using namespace lldb_private;
31 
32 // CommandObjectCommandsSource
33 
34 static constexpr OptionDefinition g_history_options[] = {
35  // clang-format off
36  { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "How many history commands to print." },
37  { LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)." },
38  { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands." },
39  { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeBoolean, "Clears the current command history." },
40  // clang-format on
41 };
42 
44 public:
46  : CommandObjectParsed(interpreter, "command history",
47  "Dump the history of commands in this session.\n"
48  "Commands in the history list can be run again "
49  "using \"!<INDEX>\". \"!-<OFFSET>\" will re-run "
50  "the command that is <OFFSET> commands from the end"
51  " of the list (counting the current command).",
52  nullptr),
53  m_options() {}
54 
55  ~CommandObjectCommandsHistory() override = default;
56 
57  Options *GetOptions() override { return &m_options; }
58 
59 protected:
60  class CommandOptions : public Options {
61  public:
63  : Options(), m_start_idx(0), m_stop_idx(0), m_count(0), m_clear(false) {
64  }
65 
66  ~CommandOptions() override = default;
67 
68  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
69  ExecutionContext *execution_context) override {
70  Status error;
71  const int short_option = m_getopt_table[option_idx].val;
72 
73  switch (short_option) {
74  case 'c':
75  error = m_count.SetValueFromString(option_arg, eVarSetOperationAssign);
76  break;
77  case 's':
78  if (option_arg == "end") {
79  m_start_idx.SetCurrentValue(UINT64_MAX);
80  m_start_idx.SetOptionWasSet();
81  } else
82  error = m_start_idx.SetValueFromString(option_arg,
84  break;
85  case 'e':
86  error =
87  m_stop_idx.SetValueFromString(option_arg, eVarSetOperationAssign);
88  break;
89  case 'C':
90  m_clear.SetCurrentValue(true);
91  m_clear.SetOptionWasSet();
92  break;
93  default:
94  error.SetErrorStringWithFormat("unrecognized option '%c'",
95  short_option);
96  break;
97  }
98 
99  return error;
100  }
101 
102  void OptionParsingStarting(ExecutionContext *execution_context) override {
103  m_start_idx.Clear();
104  m_stop_idx.Clear();
105  m_count.Clear();
106  m_clear.Clear();
107  }
108 
109  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
110  return llvm::makeArrayRef(g_history_options);
111  }
112 
113  // Instance variables to hold the values for command options.
114 
119  };
120 
121  bool DoExecute(Args &command, CommandReturnObject &result) override {
122  if (m_options.m_clear.GetCurrentValue() &&
123  m_options.m_clear.OptionWasSet()) {
124  m_interpreter.GetCommandHistory().Clear();
126  } else {
127  if (m_options.m_start_idx.OptionWasSet() &&
128  m_options.m_stop_idx.OptionWasSet() &&
129  m_options.m_count.OptionWasSet()) {
130  result.AppendError("--count, --start-index and --end-index cannot be "
131  "all specified in the same invocation");
133  } else {
134  std::pair<bool, uint64_t> start_idx(
135  m_options.m_start_idx.OptionWasSet(),
136  m_options.m_start_idx.GetCurrentValue());
137  std::pair<bool, uint64_t> stop_idx(
138  m_options.m_stop_idx.OptionWasSet(),
139  m_options.m_stop_idx.GetCurrentValue());
140  std::pair<bool, uint64_t> count(m_options.m_count.OptionWasSet(),
141  m_options.m_count.GetCurrentValue());
142 
143  const CommandHistory &history(m_interpreter.GetCommandHistory());
144 
145  if (start_idx.first && start_idx.second == UINT64_MAX) {
146  if (count.first) {
147  start_idx.second = history.GetSize() - count.second;
148  stop_idx.second = history.GetSize() - 1;
149  } else if (stop_idx.first) {
150  start_idx.second = stop_idx.second;
151  stop_idx.second = history.GetSize() - 1;
152  } else {
153  start_idx.second = 0;
154  stop_idx.second = history.GetSize() - 1;
155  }
156  } else {
157  if (!start_idx.first && !stop_idx.first && !count.first) {
158  start_idx.second = 0;
159  stop_idx.second = history.GetSize() - 1;
160  } else if (start_idx.first) {
161  if (count.first) {
162  stop_idx.second = start_idx.second + count.second - 1;
163  } else if (!stop_idx.first) {
164  stop_idx.second = history.GetSize() - 1;
165  }
166  } else if (stop_idx.first) {
167  if (count.first) {
168  if (stop_idx.second >= count.second)
169  start_idx.second = stop_idx.second - count.second + 1;
170  else
171  start_idx.second = 0;
172  }
173  } else /* if (count.first) */
174  {
175  start_idx.second = 0;
176  stop_idx.second = count.second - 1;
177  }
178  }
179  history.Dump(result.GetOutputStream(), start_idx.second,
180  stop_idx.second);
181  }
182  }
183  return result.Succeeded();
184  }
185 
187 };
188 
189 // CommandObjectCommandsSource
190 
191 static constexpr OptionDefinition g_source_options[] = {
192  // clang-format off
193  { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true, stop executing commands on error." },
194  { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true, stop executing commands on continue." },
195  { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true don't echo commands while executing." },
196  // clang-format on
197 };
198 
200 public:
203  interpreter, "command source",
204  "Read and execute LLDB commands from the file <filename>.",
205  nullptr),
206  m_options() {
208  CommandArgumentData file_arg;
209 
210  // Define the first (and only) variant of this arg.
211  file_arg.arg_type = eArgTypeFilename;
212  file_arg.arg_repetition = eArgRepeatPlain;
213 
214  // There is only one variant this argument could be; put it into the
215  // argument entry.
216  arg.push_back(file_arg);
217 
218  // Push the data for the first argument into the m_arguments vector.
219  m_arguments.push_back(arg);
220  }
221 
222  ~CommandObjectCommandsSource() override = default;
223 
224  const char *GetRepeatCommand(Args &current_command_args,
225  uint32_t index) override {
226  return "";
227  }
228 
230  CompletionRequest &request,
231  OptionElementVector &opt_element_vector) override {
232  CommandCompletions::InvokeCommonCompletionCallbacks(
233  GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
234  request, nullptr);
235  return request.GetNumberOfMatches();
236  }
237 
238  Options *GetOptions() override { return &m_options; }
239 
240 protected:
241  class CommandOptions : public Options {
242  public:
244  : Options(), m_stop_on_error(true), m_silent_run(false),
245  m_stop_on_continue(true) {}
246 
247  ~CommandOptions() override = default;
248 
249  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
250  ExecutionContext *execution_context) override {
251  Status error;
252  const int short_option = m_getopt_table[option_idx].val;
253 
254  switch (short_option) {
255  case 'e':
256  error = m_stop_on_error.SetValueFromString(option_arg);
257  break;
258 
259  case 'c':
260  error = m_stop_on_continue.SetValueFromString(option_arg);
261  break;
262 
263  case 's':
264  error = m_silent_run.SetValueFromString(option_arg);
265  break;
266 
267  default:
268  error.SetErrorStringWithFormat("unrecognized option '%c'",
269  short_option);
270  break;
271  }
272 
273  return error;
274  }
275 
276  void OptionParsingStarting(ExecutionContext *execution_context) override {
277  m_stop_on_error.Clear();
278  m_silent_run.Clear();
279  m_stop_on_continue.Clear();
280  }
281 
282  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
283  return llvm::makeArrayRef(g_source_options);
284  }
285 
286  // Instance variables to hold the values for command options.
287 
291  };
292 
293  bool DoExecute(Args &command, CommandReturnObject &result) override {
294  if (command.GetArgumentCount() != 1) {
295  result.AppendErrorWithFormat(
296  "'%s' takes exactly one executable filename argument.\n",
297  GetCommandName().str().c_str());
299  return false;
300  }
301 
302  FileSpec cmd_file(command[0].ref);
303  FileSystem::Instance().Resolve(cmd_file);
304  ExecutionContext *exe_ctx = nullptr; // Just use the default context.
305 
306  // If any options were set, then use them
307  if (m_options.m_stop_on_error.OptionWasSet() ||
308  m_options.m_silent_run.OptionWasSet() ||
309  m_options.m_stop_on_continue.OptionWasSet()) {
310  // Use user set settings
312 
313  if (m_options.m_stop_on_continue.OptionWasSet())
314  options.SetStopOnContinue(
315  m_options.m_stop_on_continue.GetCurrentValue());
316 
317  if (m_options.m_stop_on_error.OptionWasSet())
318  options.SetStopOnError(m_options.m_stop_on_error.GetCurrentValue());
319 
320  // Individual silent setting is override for global command echo settings.
321  if (m_options.m_silent_run.GetCurrentValue()) {
322  options.SetSilent(true);
323  } else {
324  options.SetPrintResults(true);
325  options.SetEchoCommands(m_interpreter.GetEchoCommands());
326  options.SetEchoCommentCommands(m_interpreter.GetEchoCommentCommands());
327  }
328 
329  m_interpreter.HandleCommandsFromFile(cmd_file, exe_ctx, options, result);
330  } else {
331  // No options were set, inherit any settings from nested "command source"
332  // commands, or set to sane default settings...
334  m_interpreter.HandleCommandsFromFile(cmd_file, exe_ctx, options, result);
335  }
336  return result.Succeeded();
337  }
338 
340 };
341 
342 #pragma mark CommandObjectCommandsAlias
343 // CommandObjectCommandsAlias
344 
345 static constexpr OptionDefinition g_alias_options[] = {
346  // clang-format off
347  { LLDB_OPT_SET_ALL, false, "help", 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeHelpText, "Help text for this command" },
348  { LLDB_OPT_SET_ALL, false, "long-help", 'H', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeHelpText, "Long help text for this command" },
349  // clang-format on
350 };
351 
352 static const char *g_python_command_instructions =
353  "Enter your Python command(s). Type 'DONE' to end.\n"
354  "You must define a Python function with this signature:\n"
355  "def my_command_impl(debugger, args, result, internal_dict):\n";
356 
358 protected:
359  class CommandOptions : public OptionGroup {
360  public:
361  CommandOptions() : OptionGroup(), m_help(), m_long_help() {}
362 
363  ~CommandOptions() override = default;
364 
365  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
366  return llvm::makeArrayRef(g_alias_options);
367  }
368 
369  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
370  ExecutionContext *execution_context) override {
371  Status error;
372 
373  const int short_option = GetDefinitions()[option_idx].short_option;
374  std::string option_str(option_value);
375 
376  switch (short_option) {
377  case 'h':
378  m_help.SetCurrentValue(option_str);
379  m_help.SetOptionWasSet();
380  break;
381 
382  case 'H':
383  m_long_help.SetCurrentValue(option_str);
384  m_long_help.SetOptionWasSet();
385  break;
386 
387  default:
388  error.SetErrorStringWithFormat("invalid short option character '%c'",
389  short_option);
390  break;
391  }
392 
393  return error;
394  }
395 
396  void OptionParsingStarting(ExecutionContext *execution_context) override {
397  m_help.Clear();
398  m_long_help.Clear();
399  }
400 
403  };
404 
407 
408 public:
409  Options *GetOptions() override { return &m_option_group; }
410 
413  interpreter, "command alias",
414  "Define a custom command in terms of an existing command."),
415  m_option_group(), m_command_options() {
416  m_option_group.Append(&m_command_options);
417  m_option_group.Finalize();
418 
419  SetHelpLong(
420  "'alias' allows the user to create a short-cut or abbreviation for long \
421 commands, multi-word commands, and commands that take particular options. \
422 Below are some simple examples of how one might use the 'alias' command:"
423  R"(
424 
425 (lldb) command alias sc script
426 
427  Creates the abbreviation 'sc' for the 'script' command.
428 
429 (lldb) command alias bp breakpoint
430 
431 )"
432  " Creates the abbreviation 'bp' for the 'breakpoint' command. Since \
433 breakpoint commands are two-word commands, the user would still need to \
434 enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'."
435  R"(
436 
437 (lldb) command alias bpl breakpoint list
438 
439  Creates the abbreviation 'bpl' for the two-word command 'breakpoint list'.
440 
441 )"
442  "An alias can include some options for the command, with the values either \
443 filled in at the time the alias is created, or specified as positional \
444 arguments, to be filled in when the alias is invoked. The following example \
445 shows how to create aliases with options:"
446  R"(
447 
448 (lldb) command alias bfl breakpoint set -f %1 -l %2
449 
450 )"
451  " Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \
452 options already part of the alias. So if the user wants to set a breakpoint \
453 by file and line without explicitly having to use the -f and -l options, the \
454 user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \
455 for the actual arguments that will be passed when the alias command is used. \
456 The number in the placeholder refers to the position/order the actual value \
457 occupies when the alias is used. All the occurrences of '%1' in the alias \
458 will be replaced with the first argument, all the occurrences of '%2' in the \
459 alias will be replaced with the second argument, and so on. This also allows \
460 actual arguments to be used multiple times within an alias (see 'process \
461 launch' example below)."
462  R"(
463 
464 )"
465  "Note: the positional arguments must substitute as whole words in the resultant \
466 command, so you can't at present do something like this to append the file extension \
467 \".cpp\":"
468  R"(
469 
470 (lldb) command alias bcppfl breakpoint set -f %1.cpp -l %2
471 
472 )"
473  "For more complex aliasing, use the \"command regex\" command instead. In the \
474 'bfl' case above, the actual file value will be filled in with the first argument \
475 following 'bfl' and the actual line number value will be filled in with the second \
476 argument. The user would use this alias as follows:"
477  R"(
478 
479 (lldb) command alias bfl breakpoint set -f %1 -l %2
480 (lldb) bfl my-file.c 137
481 
482 This would be the same as if the user had entered 'breakpoint set -f my-file.c -l 137'.
483 
484 Another example:
485 
486 (lldb) command alias pltty process launch -s -o %1 -e %1
487 (lldb) pltty /dev/tty0
488 
489  Interpreted as 'process launch -s -o /dev/tty0 -e /dev/tty0'
490 
491 )"
492  "If the user always wanted to pass the same value to a particular option, the \
493 alias could be defined with that value directly in the alias as a constant, \
494 rather than using a positional placeholder:"
495  R"(
496 
497 (lldb) command alias bl3 breakpoint set -f %1 -l 3
498 
499  Always sets a breakpoint on line 3 of whatever file is indicated.)");
500 
504  CommandArgumentData alias_arg;
505  CommandArgumentData cmd_arg;
506  CommandArgumentData options_arg;
507 
508  // Define the first (and only) variant of this arg.
509  alias_arg.arg_type = eArgTypeAliasName;
510  alias_arg.arg_repetition = eArgRepeatPlain;
511 
512  // There is only one variant this argument could be; put it into the
513  // argument entry.
514  arg1.push_back(alias_arg);
515 
516  // Define the first (and only) variant of this arg.
517  cmd_arg.arg_type = eArgTypeCommandName;
519 
520  // There is only one variant this argument could be; put it into the
521  // argument entry.
522  arg2.push_back(cmd_arg);
523 
524  // Define the first (and only) variant of this arg.
525  options_arg.arg_type = eArgTypeAliasOptions;
526  options_arg.arg_repetition = eArgRepeatOptional;
527 
528  // There is only one variant this argument could be; put it into the
529  // argument entry.
530  arg3.push_back(options_arg);
531 
532  // Push the data for the first argument into the m_arguments vector.
533  m_arguments.push_back(arg1);
534  m_arguments.push_back(arg2);
535  m_arguments.push_back(arg3);
536  }
537 
538  ~CommandObjectCommandsAlias() override = default;
539 
540 protected:
541  bool DoExecute(llvm::StringRef raw_command_line,
542  CommandReturnObject &result) override {
543  if (raw_command_line.empty()) {
544  result.AppendError("'command alias' requires at least two arguments");
545  return false;
546  }
547 
548  ExecutionContext exe_ctx = GetCommandInterpreter().GetExecutionContext();
549  m_option_group.NotifyOptionParsingStarting(&exe_ctx);
550 
551  OptionsWithRaw args_with_suffix(raw_command_line);
552  const char *remainder = args_with_suffix.GetRawPart().c_str();
553 
554  if (args_with_suffix.HasArgs())
555  if (!ParseOptionsAndNotify(args_with_suffix.GetArgs(), result,
556  m_option_group, exe_ctx))
557  return false;
558 
559  llvm::StringRef raw_command_string(remainder);
560  Args args(raw_command_string);
561 
562  if (args.GetArgumentCount() < 2) {
563  result.AppendError("'command alias' requires at least two arguments");
565  return false;
566  }
567 
568  // Get the alias command.
569 
570  auto alias_command = args[0].ref;
571  if (alias_command.startswith("-")) {
572  result.AppendError("aliases starting with a dash are not supported");
573  if (alias_command == "--help" || alias_command == "--long-help") {
574  result.AppendWarning("if trying to pass options to 'command alias' add "
575  "a -- at the end of the options");
576  }
578  return false;
579  }
580 
581  // Strip the new alias name off 'raw_command_string' (leave it on args,
582  // which gets passed to 'Execute', which does the stripping itself.
583  size_t pos = raw_command_string.find(alias_command);
584  if (pos == 0) {
585  raw_command_string = raw_command_string.substr(alias_command.size());
586  pos = raw_command_string.find_first_not_of(' ');
587  if ((pos != std::string::npos) && (pos > 0))
588  raw_command_string = raw_command_string.substr(pos);
589  } else {
590  result.AppendError("Error parsing command string. No alias created.");
592  return false;
593  }
594 
595  // Verify that the command is alias-able.
596  if (m_interpreter.CommandExists(alias_command)) {
597  result.AppendErrorWithFormat(
598  "'%s' is a permanent debugger command and cannot be redefined.\n",
599  args[0].c_str());
601  return false;
602  }
603 
604  // Get CommandObject that is being aliased. The command name is read from
605  // the front of raw_command_string. raw_command_string is returned with the
606  // name of the command object stripped off the front.
607  llvm::StringRef original_raw_command_string = raw_command_string;
608  CommandObject *cmd_obj =
609  m_interpreter.GetCommandObjectForCommand(raw_command_string);
610 
611  if (!cmd_obj) {
612  result.AppendErrorWithFormat("invalid command given to 'command alias'. "
613  "'%s' does not begin with a valid command."
614  " No alias created.",
615  original_raw_command_string.str().c_str());
617  return false;
618  } else if (!cmd_obj->WantsRawCommandString()) {
619  // Note that args was initialized with the original command, and has not
620  // been updated to this point. Therefore can we pass it to the version of
621  // Execute that does not need/expect raw input in the alias.
622  return HandleAliasingNormalCommand(args, result);
623  } else {
624  return HandleAliasingRawCommand(alias_command, raw_command_string,
625  *cmd_obj, result);
626  }
627  return result.Succeeded();
628  }
629 
630  bool HandleAliasingRawCommand(llvm::StringRef alias_command,
631  llvm::StringRef raw_command_string,
632  CommandObject &cmd_obj,
633  CommandReturnObject &result) {
634  // Verify & handle any options/arguments passed to the alias command
635 
636  OptionArgVectorSP option_arg_vector_sp =
638 
639  if (CommandObjectSP cmd_obj_sp =
640  m_interpreter.GetCommandSPExact(cmd_obj.GetCommandName(), false)) {
641  if (m_interpreter.AliasExists(alias_command) ||
642  m_interpreter.UserCommandExists(alias_command)) {
644  "Overwriting existing definition for '%s'.\n",
645  alias_command.str().c_str());
646  }
647  if (CommandAlias *alias = m_interpreter.AddAlias(
648  alias_command, cmd_obj_sp, raw_command_string)) {
649  if (m_command_options.m_help.OptionWasSet())
650  alias->SetHelp(m_command_options.m_help.GetCurrentValue());
651  if (m_command_options.m_long_help.OptionWasSet())
652  alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
654  } else {
655  result.AppendError("Unable to create requested alias.\n");
657  }
658 
659  } else {
660  result.AppendError("Unable to create requested alias.\n");
662  }
663 
664  return result.Succeeded();
665  }
666 
668  size_t argc = args.GetArgumentCount();
669 
670  if (argc < 2) {
671  result.AppendError("'command alias' requires at least two arguments");
673  return false;
674  }
675 
676  // Save these in std::strings since we're going to shift them off.
677  const std::string alias_command(args[0].ref);
678  const std::string actual_command(args[1].ref);
679 
680  args.Shift(); // Shift the alias command word off the argument vector.
681  args.Shift(); // Shift the old command word off the argument vector.
682 
683  // Verify that the command is alias'able, and get the appropriate command
684  // object.
685 
686  if (m_interpreter.CommandExists(alias_command)) {
687  result.AppendErrorWithFormat(
688  "'%s' is a permanent debugger command and cannot be redefined.\n",
689  alias_command.c_str());
691  return false;
692  }
693 
694  CommandObjectSP command_obj_sp(
695  m_interpreter.GetCommandSPExact(actual_command, true));
696  CommandObjectSP subcommand_obj_sp;
697  bool use_subcommand = false;
698  if (!command_obj_sp) {
699  result.AppendErrorWithFormat("'%s' is not an existing command.\n",
700  actual_command.c_str());
702  return false;
703  }
704  CommandObject *cmd_obj = command_obj_sp.get();
705  CommandObject *sub_cmd_obj = nullptr;
706  OptionArgVectorSP option_arg_vector_sp =
708 
709  while (cmd_obj->IsMultiwordObject() && !args.empty()) {
710  auto sub_command = args[0].ref;
711  assert(!sub_command.empty());
712  subcommand_obj_sp = cmd_obj->GetSubcommandSP(sub_command);
713  if (!subcommand_obj_sp) {
714  result.AppendErrorWithFormat(
715  "'%s' is not a valid sub-command of '%s'. "
716  "Unable to create alias.\n",
717  args[0].c_str(), actual_command.c_str());
719  return false;
720  }
721 
722  sub_cmd_obj = subcommand_obj_sp.get();
723  use_subcommand = true;
724  args.Shift(); // Shift the sub_command word off the argument vector.
725  cmd_obj = sub_cmd_obj;
726  }
727 
728  // Verify & handle any options/arguments passed to the alias command
729 
730  std::string args_string;
731 
732  if (!args.empty()) {
733  CommandObjectSP tmp_sp =
734  m_interpreter.GetCommandSPExact(cmd_obj->GetCommandName(), false);
735  if (use_subcommand)
736  tmp_sp = m_interpreter.GetCommandSPExact(sub_cmd_obj->GetCommandName(),
737  false);
738 
739  args.GetCommandString(args_string);
740  }
741 
742  if (m_interpreter.AliasExists(alias_command) ||
743  m_interpreter.UserCommandExists(alias_command)) {
745  "Overwriting existing definition for '%s'.\n", alias_command.c_str());
746  }
747 
748  if (CommandAlias *alias = m_interpreter.AddAlias(
749  alias_command, use_subcommand ? subcommand_obj_sp : command_obj_sp,
750  args_string)) {
751  if (m_command_options.m_help.OptionWasSet())
752  alias->SetHelp(m_command_options.m_help.GetCurrentValue());
753  if (m_command_options.m_long_help.OptionWasSet())
754  alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
756  } else {
757  result.AppendError("Unable to create requested alias.\n");
759  return false;
760  }
761 
762  return result.Succeeded();
763  }
764 };
765 
766 #pragma mark CommandObjectCommandsUnalias
767 // CommandObjectCommandsUnalias
768 
770 public:
773  interpreter, "command unalias",
774  "Delete one or more custom commands defined by 'command alias'.",
775  nullptr) {
777  CommandArgumentData alias_arg;
778 
779  // Define the first (and only) variant of this arg.
780  alias_arg.arg_type = eArgTypeAliasName;
781  alias_arg.arg_repetition = eArgRepeatPlain;
782 
783  // There is only one variant this argument could be; put it into the
784  // argument entry.
785  arg.push_back(alias_arg);
786 
787  // Push the data for the first argument into the m_arguments vector.
788  m_arguments.push_back(arg);
789  }
790 
791  ~CommandObjectCommandsUnalias() override = default;
792 
793 protected:
794  bool DoExecute(Args &args, CommandReturnObject &result) override {
795  CommandObject::CommandMap::iterator pos;
796  CommandObject *cmd_obj;
797 
798  if (args.empty()) {
799  result.AppendError("must call 'unalias' with a valid alias");
801  return false;
802  }
803 
804  auto command_name = args[0].ref;
805  cmd_obj = m_interpreter.GetCommandObject(command_name);
806  if (!cmd_obj) {
807  result.AppendErrorWithFormat(
808  "'%s' is not a known command.\nTry 'help' to see a "
809  "current list of commands.\n",
810  args[0].c_str());
812  return false;
813  }
814 
815  if (m_interpreter.CommandExists(command_name)) {
816  if (cmd_obj->IsRemovable()) {
817  result.AppendErrorWithFormat(
818  "'%s' is not an alias, it is a debugger command which can be "
819  "removed using the 'command delete' command.\n",
820  args[0].c_str());
821  } else {
822  result.AppendErrorWithFormat(
823  "'%s' is a permanent debugger command and cannot be removed.\n",
824  args[0].c_str());
825  }
827  return false;
828  }
829 
830  if (!m_interpreter.RemoveAlias(command_name)) {
831  if (m_interpreter.AliasExists(command_name))
832  result.AppendErrorWithFormat(
833  "Error occurred while attempting to unalias '%s'.\n",
834  args[0].c_str());
835  else
836  result.AppendErrorWithFormat("'%s' is not an existing alias.\n",
837  args[0].c_str());
839  return false;
840  }
841 
843  return result.Succeeded();
844  }
845 };
846 
847 #pragma mark CommandObjectCommandsDelete
848 // CommandObjectCommandsDelete
849 
851 public:
854  interpreter, "command delete",
855  "Delete one or more custom commands defined by 'command regex'.",
856  nullptr) {
858  CommandArgumentData alias_arg;
859 
860  // Define the first (and only) variant of this arg.
861  alias_arg.arg_type = eArgTypeCommandName;
862  alias_arg.arg_repetition = eArgRepeatPlain;
863 
864  // There is only one variant this argument could be; put it into the
865  // argument entry.
866  arg.push_back(alias_arg);
867 
868  // Push the data for the first argument into the m_arguments vector.
869  m_arguments.push_back(arg);
870  }
871 
872  ~CommandObjectCommandsDelete() override = default;
873 
874 protected:
875  bool DoExecute(Args &args, CommandReturnObject &result) override {
876  CommandObject::CommandMap::iterator pos;
877 
878  if (args.empty()) {
879  result.AppendErrorWithFormat("must call '%s' with one or more valid user "
880  "defined regular expression command names",
881  GetCommandName().str().c_str());
883  }
884 
885  auto command_name = args[0].ref;
886  if (!m_interpreter.CommandExists(command_name)) {
887  StreamString error_msg_stream;
888  const bool generate_upropos = true;
889  const bool generate_type_lookup = false;
890  CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(
891  &error_msg_stream, command_name, llvm::StringRef(), llvm::StringRef(),
892  generate_upropos, generate_type_lookup);
893  result.AppendError(error_msg_stream.GetString());
895  return false;
896  }
897 
898  if (!m_interpreter.RemoveCommand(command_name)) {
899  result.AppendErrorWithFormat(
900  "'%s' is a permanent debugger command and cannot be removed.\n",
901  args[0].c_str());
903  return false;
904  }
905 
907  return true;
908  }
909 };
910 
911 // CommandObjectCommandsAddRegex
912 
913 static constexpr OptionDefinition g_regex_options[] = {
914  // clang-format off
915  { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "The help text to display for this command." },
916  { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "A syntax string showing the typical usage syntax." },
917  // clang-format on
918 };
919 
920 #pragma mark CommandObjectCommandsAddRegex
921 
924 public:
927  interpreter, "command regex", "Define a custom command in terms of "
928  "existing commands by matching "
929  "regular expressions.",
930  "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
932  IOHandlerDelegate::Completion::LLDBCommand),
933  m_options() {
934  SetHelpLong(
935  R"(
936 )"
937  "This command allows the user to create powerful regular expression commands \
938 with substitutions. The regular expressions and substitutions are specified \
939 using the regular expression substitution format of:"
940  R"(
941 
942  s/<regex>/<subst>/
943 
944 )"
945  "<regex> is a regular expression that can use parenthesis to capture regular \
946 expression input and substitute the captured matches in the output using %1 \
947 for the first match, %2 for the second, and so on."
948  R"(
949 
950 )"
951  "The regular expressions can all be specified on the command line if more than \
952 one argument is provided. If just the command name is provided on the command \
953 line, then the regular expressions and substitutions can be entered on separate \
954 lines, followed by an empty line to terminate the command definition."
955  R"(
956 
957 EXAMPLES
958 
959 )"
960  "The following example will define a regular expression command named 'f' that \
961 will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \
962 a number follows 'f':"
963  R"(
964 
965  (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')");
966  }
967 
968  ~CommandObjectCommandsAddRegex() override = default;
969 
970 protected:
971  void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
972  StreamFileSP output_sp(io_handler.GetOutputStreamFile());
973  if (output_sp && interactive) {
974  output_sp->PutCString("Enter one or more sed substitution commands in "
975  "the form: 's/<regex>/<subst>/'.\nTerminate the "
976  "substitution list with an empty line.\n");
977  output_sp->Flush();
978  }
979  }
980 
982  std::string &data) override {
983  io_handler.SetIsDone(true);
984  if (m_regex_cmd_up) {
985  StringList lines;
986  if (lines.SplitIntoLines(data)) {
987  const size_t num_lines = lines.GetSize();
988  bool check_only = false;
989  for (size_t i = 0; i < num_lines; ++i) {
990  llvm::StringRef bytes_strref(lines[i]);
991  Status error = AppendRegexSubstitution(bytes_strref, check_only);
992  if (error.Fail()) {
993  if (!GetDebugger().GetCommandInterpreter().GetBatchCommandMode()) {
994  StreamSP out_stream = GetDebugger().GetAsyncOutputStream();
995  out_stream->Printf("error: %s\n", error.AsCString());
996  }
997  }
998  }
999  }
1000  if (m_regex_cmd_up->HasRegexEntries()) {
1001  CommandObjectSP cmd_sp(m_regex_cmd_up.release());
1002  m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1003  }
1004  }
1005  }
1006 
1007  bool DoExecute(Args &command, CommandReturnObject &result) override {
1008  const size_t argc = command.GetArgumentCount();
1009  if (argc == 0) {
1010  result.AppendError("usage: 'command regex <command-name> "
1011  "[s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
1013  return false;
1014  }
1015 
1016  Status error;
1017  auto name = command[0].ref;
1018  m_regex_cmd_up = llvm::make_unique<CommandObjectRegexCommand>(
1019  m_interpreter, name, m_options.GetHelp(), m_options.GetSyntax(), 10, 0,
1020  true);
1021 
1022  if (argc == 1) {
1023  Debugger &debugger = GetDebugger();
1024  bool color_prompt = debugger.GetUseColor();
1025  const bool multiple_lines = true; // Get multiple lines
1026  IOHandlerSP io_handler_sp(new IOHandlerEditline(
1027  debugger, IOHandler::Type::Other,
1028  "lldb-regex", // Name of input reader for history
1029  llvm::StringRef("> "), // Prompt
1030  llvm::StringRef(), // Continuation prompt
1031  multiple_lines, color_prompt,
1032  0, // Don't show line numbers
1033  *this, nullptr));
1034 
1035  if (io_handler_sp) {
1036  debugger.PushIOHandler(io_handler_sp);
1038  }
1039  } else {
1040  for (auto &entry : command.entries().drop_front()) {
1041  bool check_only = false;
1042  error = AppendRegexSubstitution(entry.ref, check_only);
1043  if (error.Fail())
1044  break;
1045  }
1046 
1047  if (error.Success()) {
1048  AddRegexCommandToInterpreter();
1049  }
1050  }
1051  if (error.Fail()) {
1052  result.AppendError(error.AsCString());
1054  }
1055 
1056  return result.Succeeded();
1057  }
1058 
1059  Status AppendRegexSubstitution(const llvm::StringRef &regex_sed,
1060  bool check_only) {
1061  Status error;
1062 
1063  if (!m_regex_cmd_up) {
1065  "invalid regular expression command object for: '%.*s'",
1066  (int)regex_sed.size(), regex_sed.data());
1067  return error;
1068  }
1069 
1070  size_t regex_sed_size = regex_sed.size();
1071 
1072  if (regex_sed_size <= 1) {
1074  "regular expression substitution string is too short: '%.*s'",
1075  (int)regex_sed.size(), regex_sed.data());
1076  return error;
1077  }
1078 
1079  if (regex_sed[0] != 's') {
1080  error.SetErrorStringWithFormat("regular expression substitution string "
1081  "doesn't start with 's': '%.*s'",
1082  (int)regex_sed.size(), regex_sed.data());
1083  return error;
1084  }
1085  const size_t first_separator_char_pos = 1;
1086  // use the char that follows 's' as the regex separator character so we can
1087  // have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
1088  const char separator_char = regex_sed[first_separator_char_pos];
1089  const size_t second_separator_char_pos =
1090  regex_sed.find(separator_char, first_separator_char_pos + 1);
1091 
1092  if (second_separator_char_pos == std::string::npos) {
1094  "missing second '%c' separator char after '%.*s' in '%.*s'",
1095  separator_char,
1096  (int)(regex_sed.size() - first_separator_char_pos - 1),
1097  regex_sed.data() + (first_separator_char_pos + 1),
1098  (int)regex_sed.size(), regex_sed.data());
1099  return error;
1100  }
1101 
1102  const size_t third_separator_char_pos =
1103  regex_sed.find(separator_char, second_separator_char_pos + 1);
1104 
1105  if (third_separator_char_pos == std::string::npos) {
1107  "missing third '%c' separator char after '%.*s' in '%.*s'",
1108  separator_char,
1109  (int)(regex_sed.size() - second_separator_char_pos - 1),
1110  regex_sed.data() + (second_separator_char_pos + 1),
1111  (int)regex_sed.size(), regex_sed.data());
1112  return error;
1113  }
1114 
1115  if (third_separator_char_pos != regex_sed_size - 1) {
1116  // Make sure that everything that follows the last regex separator char
1117  if (regex_sed.find_first_not_of("\t\n\v\f\r ",
1118  third_separator_char_pos + 1) !=
1119  std::string::npos) {
1121  "extra data found after the '%.*s' regular expression substitution "
1122  "string: '%.*s'",
1123  (int)third_separator_char_pos + 1, regex_sed.data(),
1124  (int)(regex_sed.size() - third_separator_char_pos - 1),
1125  regex_sed.data() + (third_separator_char_pos + 1));
1126  return error;
1127  }
1128  } else if (first_separator_char_pos + 1 == second_separator_char_pos) {
1130  "<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1131  separator_char, separator_char, separator_char, (int)regex_sed.size(),
1132  regex_sed.data());
1133  return error;
1134  } else if (second_separator_char_pos + 1 == third_separator_char_pos) {
1136  "<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1137  separator_char, separator_char, separator_char, (int)regex_sed.size(),
1138  regex_sed.data());
1139  return error;
1140  }
1141 
1142  if (!check_only) {
1143  std::string regex(regex_sed.substr(first_separator_char_pos + 1,
1144  second_separator_char_pos -
1145  first_separator_char_pos - 1));
1146  std::string subst(regex_sed.substr(second_separator_char_pos + 1,
1147  third_separator_char_pos -
1148  second_separator_char_pos - 1));
1149  m_regex_cmd_up->AddRegexCommand(regex.c_str(), subst.c_str());
1150  }
1151  return error;
1152  }
1153 
1155  if (m_regex_cmd_up) {
1156  if (m_regex_cmd_up->HasRegexEntries()) {
1157  CommandObjectSP cmd_sp(m_regex_cmd_up.release());
1158  m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1159  }
1160  }
1161  }
1162 
1163 private:
1164  std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_up;
1165 
1166  class CommandOptions : public Options {
1167  public:
1168  CommandOptions() : Options() {}
1169 
1170  ~CommandOptions() override = default;
1171 
1172  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1173  ExecutionContext *execution_context) override {
1174  Status error;
1175  const int short_option = m_getopt_table[option_idx].val;
1176 
1177  switch (short_option) {
1178  case 'h':
1179  m_help.assign(option_arg);
1180  break;
1181  case 's':
1182  m_syntax.assign(option_arg);
1183  break;
1184  default:
1185  error.SetErrorStringWithFormat("unrecognized option '%c'",
1186  short_option);
1187  break;
1188  }
1189 
1190  return error;
1191  }
1192 
1193  void OptionParsingStarting(ExecutionContext *execution_context) override {
1194  m_help.clear();
1195  m_syntax.clear();
1196  }
1197 
1198  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1199  return llvm::makeArrayRef(g_regex_options);
1200  }
1201 
1202  // TODO: Convert these functions to return StringRefs.
1203  const char *GetHelp() {
1204  return (m_help.empty() ? nullptr : m_help.c_str());
1205  }
1206 
1207  const char *GetSyntax() {
1208  return (m_syntax.empty() ? nullptr : m_syntax.c_str());
1209  }
1210 
1211  protected:
1212  // Instance variables to hold the values for command options.
1213 
1214  std::string m_help;
1215  std::string m_syntax;
1216  };
1217 
1218  Options *GetOptions() override { return &m_options; }
1219 
1220  CommandOptions m_options;
1221 };
1222 
1224 public:
1225  CommandObjectPythonFunction(CommandInterpreter &interpreter, std::string name,
1226  std::string funct, std::string help,
1228  : CommandObjectRaw(interpreter, name),
1229  m_function_name(funct), m_synchro(synch), m_fetched_help_long(false) {
1230  if (!help.empty())
1231  SetHelp(help);
1232  else {
1233  StreamString stream;
1234  stream.Printf("For more information run 'help %s'", name.c_str());
1235  SetHelp(stream.GetString());
1236  }
1237  }
1238 
1239  ~CommandObjectPythonFunction() override = default;
1240 
1241  bool IsRemovable() const override { return true; }
1242 
1243  const std::string &GetFunctionName() { return m_function_name; }
1244 
1246 
1247  llvm::StringRef GetHelpLong() override {
1248  if (m_fetched_help_long)
1249  return CommandObjectRaw::GetHelpLong();
1250 
1251  ScriptInterpreter *scripter = GetDebugger().GetScriptInterpreter();
1252  if (!scripter)
1253  return CommandObjectRaw::GetHelpLong();
1254 
1255  std::string docstring;
1256  m_fetched_help_long =
1257  scripter->GetDocumentationForItem(m_function_name.c_str(), docstring);
1258  if (!docstring.empty())
1259  SetHelpLong(docstring);
1260  return CommandObjectRaw::GetHelpLong();
1261  }
1262 
1263 protected:
1264  bool DoExecute(llvm::StringRef raw_command_line,
1265  CommandReturnObject &result) override {
1266  ScriptInterpreter *scripter = GetDebugger().GetScriptInterpreter();
1267 
1268  Status error;
1269 
1271 
1272  if (!scripter ||
1273  !scripter->RunScriptBasedCommand(m_function_name.c_str(),
1274  raw_command_line, m_synchro, result,
1275  error, m_exe_ctx)) {
1276  result.AppendError(error.AsCString());
1277  result.SetStatus(eReturnStatusFailed);
1278  } else {
1279  // Don't change the status if the command already set it...
1280  if (result.GetStatus() == eReturnStatusInvalid) {
1281  if (result.GetOutputData().empty())
1282  result.SetStatus(eReturnStatusSuccessFinishNoResult);
1283  else
1284  result.SetStatus(eReturnStatusSuccessFinishResult);
1285  }
1286  }
1287 
1288  return result.Succeeded();
1289  }
1290 
1291 private:
1292  std::string m_function_name;
1293  ScriptedCommandSynchronicity m_synchro;
1294  bool m_fetched_help_long;
1295 };
1296 
1298 public:
1300  std::string name,
1301  StructuredData::GenericSP cmd_obj_sp,
1303  : CommandObjectRaw(interpreter, name),
1304  m_cmd_obj_sp(cmd_obj_sp), m_synchro(synch), m_fetched_help_short(false),
1305  m_fetched_help_long(false) {
1306  StreamString stream;
1307  stream.Printf("For more information run 'help %s'", name.c_str());
1308  SetHelp(stream.GetString());
1309  if (ScriptInterpreter *scripter = GetDebugger().GetScriptInterpreter())
1310  GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp));
1311  }
1312 
1313  ~CommandObjectScriptingObject() override = default;
1314 
1315  bool IsRemovable() const override { return true; }
1316 
1318 
1320 
1321  llvm::StringRef GetHelp() override {
1322  if (m_fetched_help_short)
1323  return CommandObjectRaw::GetHelp();
1324  ScriptInterpreter *scripter = GetDebugger().GetScriptInterpreter();
1325  if (!scripter)
1326  return CommandObjectRaw::GetHelp();
1327  std::string docstring;
1328  m_fetched_help_short =
1329  scripter->GetShortHelpForCommandObject(m_cmd_obj_sp, docstring);
1330  if (!docstring.empty())
1331  SetHelp(docstring);
1332 
1333  return CommandObjectRaw::GetHelp();
1334  }
1335 
1336  llvm::StringRef GetHelpLong() override {
1337  if (m_fetched_help_long)
1338  return CommandObjectRaw::GetHelpLong();
1339 
1340  ScriptInterpreter *scripter = GetDebugger().GetScriptInterpreter();
1341  if (!scripter)
1342  return CommandObjectRaw::GetHelpLong();
1343 
1344  std::string docstring;
1345  m_fetched_help_long =
1346  scripter->GetLongHelpForCommandObject(m_cmd_obj_sp, docstring);
1347  if (!docstring.empty())
1348  SetHelpLong(docstring);
1349  return CommandObjectRaw::GetHelpLong();
1350  }
1351 
1352 protected:
1353  bool DoExecute(llvm::StringRef raw_command_line,
1354  CommandReturnObject &result) override {
1355  ScriptInterpreter *scripter = GetDebugger().GetScriptInterpreter();
1356 
1357  Status error;
1358 
1360 
1361  if (!scripter ||
1362  !scripter->RunScriptBasedCommand(m_cmd_obj_sp, raw_command_line,
1363  m_synchro, result, error, m_exe_ctx)) {
1364  result.AppendError(error.AsCString());
1366  } else {
1367  // Don't change the status if the command already set it...
1368  if (result.GetStatus() == eReturnStatusInvalid) {
1369  if (result.GetOutputData().empty())
1371  else
1373  }
1374  }
1375 
1376  return result.Succeeded();
1377  }
1378 
1379 private:
1380  StructuredData::GenericSP m_cmd_obj_sp;
1381  ScriptedCommandSynchronicity m_synchro;
1382  bool m_fetched_help_short : 1;
1383  bool m_fetched_help_long : 1;
1384 };
1385 
1386 // CommandObjectCommandsScriptImport
1387 
1388 static constexpr OptionDefinition g_script_import_options[] = {
1389  // clang-format off
1390  { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not." },
1391  // clang-format on
1392 };
1393 
1395 public:
1397  : CommandObjectParsed(interpreter, "command script import",
1398  "Import a scripting module in LLDB.", nullptr),
1399  m_options() {
1400  CommandArgumentEntry arg1;
1401  CommandArgumentData cmd_arg;
1402 
1403  // Define the first (and only) variant of this arg.
1404  cmd_arg.arg_type = eArgTypeFilename;
1405  cmd_arg.arg_repetition = eArgRepeatPlus;
1406 
1407  // There is only one variant this argument could be; put it into the
1408  // argument entry.
1409  arg1.push_back(cmd_arg);
1410 
1411  // Push the data for the first argument into the m_arguments vector.
1412  m_arguments.push_back(arg1);
1413  }
1414 
1415  ~CommandObjectCommandsScriptImport() override = default;
1416 
1418  CompletionRequest &request,
1419  OptionElementVector &opt_element_vector) override {
1420  CommandCompletions::InvokeCommonCompletionCallbacks(
1421  GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
1422  request, nullptr);
1423  return request.GetNumberOfMatches();
1424  }
1425 
1426  Options *GetOptions() override { return &m_options; }
1427 
1428 protected:
1429  class CommandOptions : public Options {
1430  public:
1432 
1433  ~CommandOptions() override = default;
1434 
1435  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1436  ExecutionContext *execution_context) override {
1437  Status error;
1438  const int short_option = m_getopt_table[option_idx].val;
1439 
1440  switch (short_option) {
1441  case 'r':
1442  m_allow_reload = true;
1443  break;
1444  default:
1445  error.SetErrorStringWithFormat("unrecognized option '%c'",
1446  short_option);
1447  break;
1448  }
1449 
1450  return error;
1451  }
1452 
1453  void OptionParsingStarting(ExecutionContext *execution_context) override {
1454  m_allow_reload = true;
1455  }
1456 
1457  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1458  return llvm::makeArrayRef(g_script_import_options);
1459  }
1460 
1461  // Instance variables to hold the values for command options.
1462 
1464  };
1465 
1466  bool DoExecute(Args &command, CommandReturnObject &result) override {
1467  if (GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) {
1468  result.AppendError("only scripting language supported for module "
1469  "importing is currently Python");
1471  return false;
1472  }
1473 
1474  if (command.empty()) {
1475  result.AppendError("command script import needs one or more arguments");
1477  return false;
1478  }
1479 
1480  for (auto &entry : command.entries()) {
1481  Status error;
1482 
1483  const bool init_session = true;
1484  // FIXME: this is necessary because CommandObject::CheckRequirements()
1485  // assumes that commands won't ever be recursively invoked, but it's
1486  // actually possible to craft a Python script that does other "command
1487  // script imports" in __lldb_init_module the real fix is to have
1488  // recursive commands possible with a CommandInvocation object separate
1489  // from the CommandObject itself, so that recursive command invocations
1490  // won't stomp on each other (wrt to execution contents, options, and
1491  // more)
1492  m_exe_ctx.Clear();
1493  if (GetDebugger().GetScriptInterpreter()->LoadScriptingModule(
1494  entry.c_str(), m_options.m_allow_reload, init_session, error)) {
1496  } else {
1497  result.AppendErrorWithFormat("module importing failed: %s",
1498  error.AsCString());
1500  }
1501  }
1502 
1503  return result.Succeeded();
1504  }
1505 
1507 };
1508 
1509 // CommandObjectCommandsScriptAdd
1510 static constexpr OptionEnumValueElement g_script_synchro_type[] = {
1512  "Run synchronous"},
1514  "Run asynchronous"},
1516  "Do not alter current setting"} };
1517 
1518 static constexpr OptionEnumValues ScriptSynchroType() {
1519  return OptionEnumValues(g_script_synchro_type);
1520 }
1521 
1522 static constexpr OptionDefinition g_script_add_options[] = {
1523  // clang-format off
1524  { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name." },
1525  { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name." },
1526  { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeHelpText, "The help text to display for this command." },
1527  { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, nullptr, ScriptSynchroType(), 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system." },
1528  // clang-format on
1529 };
1530 
1533 public:
1535  : CommandObjectParsed(interpreter, "command script add",
1536  "Add a scripted function as an LLDB command.",
1537  nullptr),
1538  IOHandlerDelegateMultiline("DONE"), m_options() {
1539  CommandArgumentEntry arg1;
1540  CommandArgumentData cmd_arg;
1541 
1542  // Define the first (and only) variant of this arg.
1543  cmd_arg.arg_type = eArgTypeCommandName;
1544  cmd_arg.arg_repetition = eArgRepeatPlain;
1545 
1546  // There is only one variant this argument could be; put it into the
1547  // argument entry.
1548  arg1.push_back(cmd_arg);
1549 
1550  // Push the data for the first argument into the m_arguments vector.
1551  m_arguments.push_back(arg1);
1552  }
1553 
1554  ~CommandObjectCommandsScriptAdd() override = default;
1555 
1556  Options *GetOptions() override { return &m_options; }
1557 
1558 protected:
1559  class CommandOptions : public Options {
1560  public:
1562  : Options(), m_class_name(), m_funct_name(), m_short_help(),
1563  m_synchronicity(eScriptedCommandSynchronicitySynchronous) {}
1564 
1565  ~CommandOptions() override = default;
1566 
1567  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1568  ExecutionContext *execution_context) override {
1569  Status error;
1570  const int short_option = m_getopt_table[option_idx].val;
1571 
1572  switch (short_option) {
1573  case 'f':
1574  if (!option_arg.empty())
1575  m_funct_name = option_arg;
1576  break;
1577  case 'c':
1578  if (!option_arg.empty())
1579  m_class_name = option_arg;
1580  break;
1581  case 'h':
1582  if (!option_arg.empty())
1583  m_short_help = option_arg;
1584  break;
1585  case 's':
1586  m_synchronicity =
1587  (ScriptedCommandSynchronicity)OptionArgParser::ToOptionEnum(
1588  option_arg, GetDefinitions()[option_idx].enum_values, 0, error);
1589  if (!error.Success())
1591  "unrecognized value for synchronicity '%s'",
1592  option_arg.str().c_str());
1593  break;
1594  default:
1595  error.SetErrorStringWithFormat("unrecognized option '%c'",
1596  short_option);
1597  break;
1598  }
1599 
1600  return error;
1601  }
1602 
1603  void OptionParsingStarting(ExecutionContext *execution_context) override {
1604  m_class_name.clear();
1605  m_funct_name.clear();
1606  m_short_help.clear();
1607  m_synchronicity = eScriptedCommandSynchronicitySynchronous;
1608  }
1609 
1610  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1611  return llvm::makeArrayRef(g_script_add_options);
1612  }
1613 
1614  // Instance variables to hold the values for command options.
1615 
1616  std::string m_class_name;
1617  std::string m_funct_name;
1618  std::string m_short_help;
1620  };
1621 
1622  void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
1623  StreamFileSP output_sp(io_handler.GetOutputStreamFile());
1624  if (output_sp && interactive) {
1625  output_sp->PutCString(g_python_command_instructions);
1626  output_sp->Flush();
1627  }
1628  }
1629 
1631  std::string &data) override {
1632  StreamFileSP error_sp = io_handler.GetErrorStreamFile();
1633 
1634  ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
1635  if (interpreter) {
1636 
1637  StringList lines;
1638  lines.SplitIntoLines(data);
1639  if (lines.GetSize() > 0) {
1640  std::string funct_name_str;
1641  if (interpreter->GenerateScriptAliasFunction(lines, funct_name_str)) {
1642  if (funct_name_str.empty()) {
1643  error_sp->Printf("error: unable to obtain a function name, didn't "
1644  "add python command.\n");
1645  error_sp->Flush();
1646  } else {
1647  // everything should be fine now, let's add this alias
1648 
1649  CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(
1650  m_interpreter, m_cmd_name, funct_name_str, m_short_help,
1651  m_synchronicity));
1652 
1653  if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp,
1654  true)) {
1655  error_sp->Printf("error: unable to add selected command, didn't "
1656  "add python command.\n");
1657  error_sp->Flush();
1658  }
1659  }
1660  } else {
1661  error_sp->Printf(
1662  "error: unable to create function, didn't add python command.\n");
1663  error_sp->Flush();
1664  }
1665  } else {
1666  error_sp->Printf("error: empty function, didn't add python command.\n");
1667  error_sp->Flush();
1668  }
1669  } else {
1670  error_sp->Printf(
1671  "error: script interpreter missing, didn't add python command.\n");
1672  error_sp->Flush();
1673  }
1674 
1675  io_handler.SetIsDone(true);
1676  }
1677 
1678 protected:
1679  bool DoExecute(Args &command, CommandReturnObject &result) override {
1680  if (GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) {
1681  result.AppendError("only scripting language supported for scripted "
1682  "commands is currently Python");
1684  return false;
1685  }
1686 
1687  if (command.GetArgumentCount() != 1) {
1688  result.AppendError("'command script add' requires one argument");
1690  return false;
1691  }
1692 
1693  // Store the options in case we get multi-line input
1694  m_cmd_name = command[0].ref;
1695  m_short_help.assign(m_options.m_short_help);
1696  m_synchronicity = m_options.m_synchronicity;
1697 
1698  if (m_options.m_class_name.empty()) {
1699  if (m_options.m_funct_name.empty()) {
1700  m_interpreter.GetPythonCommandsFromIOHandler(
1701  " ", // Prompt
1702  *this, // IOHandlerDelegate
1703  true, // Run IOHandler in async mode
1704  nullptr); // Baton for the "io_handler" that will be passed back
1705  // into our IOHandlerDelegate functions
1706  } else {
1707  CommandObjectSP new_cmd(new CommandObjectPythonFunction(
1708  m_interpreter, m_cmd_name, m_options.m_funct_name,
1709  m_options.m_short_help, m_synchronicity));
1710  if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) {
1712  } else {
1713  result.AppendError("cannot add command");
1715  }
1716  }
1717  } else {
1718  ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
1719  if (!interpreter) {
1720  result.AppendError("cannot find ScriptInterpreter");
1722  return false;
1723  }
1724 
1725  auto cmd_obj_sp = interpreter->CreateScriptCommandObject(
1726  m_options.m_class_name.c_str());
1727  if (!cmd_obj_sp) {
1728  result.AppendError("cannot create helper object");
1730  return false;
1731  }
1732 
1733  CommandObjectSP new_cmd(new CommandObjectScriptingObject(
1734  m_interpreter, m_cmd_name, cmd_obj_sp, m_synchronicity));
1735  if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) {
1737  } else {
1738  result.AppendError("cannot add command");
1740  }
1741  }
1742 
1743  return result.Succeeded();
1744  }
1745 
1747  std::string m_cmd_name;
1748  std::string m_short_help;
1750 };
1751 
1752 // CommandObjectCommandsScriptList
1753 
1755 public:
1757  : CommandObjectParsed(interpreter, "command script list",
1758  "List defined scripted commands.", nullptr) {}
1759 
1760  ~CommandObjectCommandsScriptList() override = default;
1761 
1762  bool DoExecute(Args &command, CommandReturnObject &result) override {
1763  m_interpreter.GetHelp(result, CommandInterpreter::eCommandTypesUserDef);
1764 
1766 
1767  return true;
1768  }
1769 };
1770 
1771 // CommandObjectCommandsScriptClear
1772 
1774 public:
1776  : CommandObjectParsed(interpreter, "command script clear",
1777  "Delete all scripted commands.", nullptr) {}
1778 
1779  ~CommandObjectCommandsScriptClear() override = default;
1780 
1781 protected:
1782  bool DoExecute(Args &command, CommandReturnObject &result) override {
1783  m_interpreter.RemoveAllUser();
1784 
1786 
1787  return true;
1788  }
1789 };
1790 
1791 // CommandObjectCommandsScriptDelete
1792 
1794 public:
1796  : CommandObjectParsed(interpreter, "command script delete",
1797  "Delete a scripted command.", nullptr) {
1798  CommandArgumentEntry arg1;
1799  CommandArgumentData cmd_arg;
1800 
1801  // Define the first (and only) variant of this arg.
1802  cmd_arg.arg_type = eArgTypeCommandName;
1803  cmd_arg.arg_repetition = eArgRepeatPlain;
1804 
1805  // There is only one variant this argument could be; put it into the
1806  // argument entry.
1807  arg1.push_back(cmd_arg);
1808 
1809  // Push the data for the first argument into the m_arguments vector.
1810  m_arguments.push_back(arg1);
1811  }
1812 
1813  ~CommandObjectCommandsScriptDelete() override = default;
1814 
1815 protected:
1816  bool DoExecute(Args &command, CommandReturnObject &result) override {
1817 
1818  if (command.GetArgumentCount() != 1) {
1819  result.AppendError("'command script delete' requires one argument");
1821  return false;
1822  }
1823 
1824  auto cmd_name = command[0].ref;
1825 
1826  if (cmd_name.empty() || !m_interpreter.HasUserCommands() ||
1827  !m_interpreter.UserCommandExists(cmd_name)) {
1828  result.AppendErrorWithFormat("command %s not found", command[0].c_str());
1830  return false;
1831  }
1832 
1833  m_interpreter.RemoveUser(cmd_name);
1835  return true;
1836  }
1837 };
1838 
1839 #pragma mark CommandObjectMultiwordCommandsScript
1840 
1841 // CommandObjectMultiwordCommandsScript
1842 
1844 public:
1847  interpreter, "command script", "Commands for managing custom "
1848  "commands implemented by "
1849  "interpreter scripts.",
1850  "command script <subcommand> [<subcommand-options>]") {
1851  LoadSubCommand("add", CommandObjectSP(
1852  new CommandObjectCommandsScriptAdd(interpreter)));
1853  LoadSubCommand(
1854  "delete",
1855  CommandObjectSP(new CommandObjectCommandsScriptDelete(interpreter)));
1856  LoadSubCommand(
1857  "clear",
1858  CommandObjectSP(new CommandObjectCommandsScriptClear(interpreter)));
1859  LoadSubCommand("list", CommandObjectSP(new CommandObjectCommandsScriptList(
1860  interpreter)));
1861  LoadSubCommand(
1862  "import",
1863  CommandObjectSP(new CommandObjectCommandsScriptImport(interpreter)));
1864  }
1865 
1866  ~CommandObjectMultiwordCommandsScript() override = default;
1867 };
1868 
1869 #pragma mark CommandObjectMultiwordCommands
1870 
1871 // CommandObjectMultiwordCommands
1872 
1873 CommandObjectMultiwordCommands::CommandObjectMultiwordCommands(
1874  CommandInterpreter &interpreter)
1875  : CommandObjectMultiword(interpreter, "command",
1876  "Commands for managing custom LLDB commands.",
1877  "command <subcommand> [<subcommand-options>]") {
1878  LoadSubCommand("source",
1879  CommandObjectSP(new CommandObjectCommandsSource(interpreter)));
1880  LoadSubCommand("alias",
1881  CommandObjectSP(new CommandObjectCommandsAlias(interpreter)));
1882  LoadSubCommand("unalias", CommandObjectSP(
1883  new CommandObjectCommandsUnalias(interpreter)));
1884  LoadSubCommand("delete",
1885  CommandObjectSP(new CommandObjectCommandsDelete(interpreter)));
1887  "regex", CommandObjectSP(new CommandObjectCommandsAddRegex(interpreter)));
1888  LoadSubCommand("history", CommandObjectSP(
1889  new CommandObjectCommandsHistory(interpreter)));
1891  "script",
1892  CommandObjectSP(new CommandObjectMultiwordCommandsScript(interpreter)));
1893 }
1894 
virtual bool GetDocumentationForItem(const char *item, std::string &dest)
A class to manage flag bits.
Definition: Debugger.h:82
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandObjectCommandsHistory(CommandInterpreter &interpreter)
std::vector< CommandArgumentData > CommandArgumentEntry
int HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
A command line argument class.
Definition: Args.h:32
void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override
Called when a line or lines have been retrieved.
bool DoExecute(Args &command, CommandReturnObject &result) override
ScriptedCommandSynchronicity GetSynchronicity()
bool empty() const
Definition: Args.h:113
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
void Shift()
Shifts the first argument C string value of the array off the argument array.
Definition: Args.cpp:284
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
bool DoExecute(Args &command, CommandReturnObject &result) override
StructuredData::GenericSP GetImplementingObject()
CommandObjectPythonFunction(CommandInterpreter &interpreter, std::string name, std::string funct, std::string help, ScriptedCommandSynchronicity synch)
static const char * g_python_command_instructions
void OptionParsingStarting(ExecutionContext *execution_context) override
CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter)
llvm::ArrayRef< ArgEntry > entries() const
Definition: Args.h:123
bool DoExecute(llvm::StringRef raw_command_line, CommandReturnObject &result) override
CommandObjectCommandsAlias(CommandInterpreter &interpreter)
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
virtual bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, std::string &dest)
void OptionParsingStarting(ExecutionContext *execution_context) override
static constexpr OptionEnumValues ScriptSynchroType()
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition: Args.cpp:254
Status AppendRegexSubstitution(const llvm::StringRef &regex_sed, bool check_only)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
A file utility class.
Definition: FileSpec.h:55
int history(History *, HistEvent *, int,...)
std::size_t GetNumberOfMatches() const
bool DoExecute(Args &command, CommandReturnObject &result) override
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
bool DoExecute(llvm::StringRef raw_command_line, CommandReturnObject &result) override
virtual StructuredData::GenericSP CreateScriptCommandObject(const char *class_name)
bool DoExecute(Args &command, CommandReturnObject &result) override
bool HasArgs() const
Returns true if there are any arguments before the raw suffix.
Definition: Args.h:352
lldb::StreamFileSP & GetErrorStreamFile()
Definition: IOHandler.cpp:128
virtual bool RunScriptBasedCommand(const char *impl_function, llvm::StringRef args, ScriptedCommandSynchronicity synchronicity, lldb_private::CommandReturnObject &cmd_retobj, Status &error, const lldb_private::ExecutionContext &exe_ctx)
A delegate class for use with IOHandler subclasses.
Definition: IOHandler.h:188
CommandObjectCommandsDelete(CommandInterpreter &interpreter)
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::StringRef GetHelpLong() override
"lldb/Utility/ArgCompletionRequest.h"
ScriptedCommandSynchronicity GetSynchronicity()
CommandObjectMultiwordCommandsScript(CommandInterpreter &interpreter)
std::vector< OptionArgElement > OptionElementVector
Definition: Options.h:41
virtual bool IsRemovable() const
virtual lldb::CommandObjectSP GetSubcommandSP(llvm::StringRef sub_cmd, StringList *matches=nullptr)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void AppendWarning(llvm::StringRef in_string)
bool DoExecute(Args &args, CommandReturnObject &result) override
std::vector< std::tuple< std::string, int, std::string > > OptionArgVector
Definition: Options.h:25
static constexpr OptionDefinition g_alias_options[]
CommandObjectCommandsScriptList(CommandInterpreter &interpreter)
llvm::StringRef GetHelpLong() override
static constexpr OptionDefinition g_script_import_options[]
int HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
CommandObjectCommandsSource(CommandInterpreter &interpreter)
virtual bool IsMultiwordObject()
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
CommandObjectScriptingObject(CommandInterpreter &interpreter, std::string name, StructuredData::GenericSP cmd_obj_sp, ScriptedCommandSynchronicity synch)
virtual bool WantsRawCommandString()=0
void Clear()
Clear the object state.
Definition: Status.cpp:167
llvm::StringRef GetString() const
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
CommandObjectCommandsUnalias(CommandInterpreter &interpreter)
virtual bool GenerateScriptAliasFunction(StringList &input, std::string &output)
const std::string & GetRawPart() const
Returns the raw suffix part of the parsed string.
Definition: Args.h:390
static constexpr OptionDefinition g_script_add_options[]
void PushIOHandler(const lldb::IOHandlerSP &reader_sp, bool cancel_top_handler=true)
Definition: Debugger.cpp:1095
bool DoExecute(Args &command, CommandReturnObject &result) override
ScriptedCommandSynchronicity m_synchronicity
static constexpr OptionDefinition g_source_options[]
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
bool Success() const
Test for success condition.
Definition: Status.cpp:287
const char * GetCurrentValue() const
void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override
Called when a line or lines have been retrieved.
llvm::StringRef GetHelp() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
bool HandleAliasingNormalCommand(Args &args, CommandReturnObject &result)
CommandObjectCommandsScriptClear(CommandInterpreter &interpreter)
bool DoExecute(Args &command, CommandReturnObject &result) override
bool DoExecute(Args &command, CommandReturnObject &result) override
static constexpr OptionDefinition g_history_options[]
const char * GetRepeatCommand(Args &current_command_args, uint32_t index) override
Get the command that appropriate for a "repeat" of the current command.
size_t GetSize() const
Definition: StringList.cpp:70
#define LLDB_OPT_SET_2
Definition: lldb-defines.h:112
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
A command line option parsing protocol class.
Definition: Options.h:62
static constexpr OptionEnumValueElement g_script_synchro_type[]
void OptionParsingStarting(ExecutionContext *execution_context) override
void OptionParsingStarting(ExecutionContext *execution_context) override
bool GetUseColor() const
Definition: Debugger.cpp:464
void void AppendError(llvm::StringRef in_string)
virtual bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, std::string &dest)
void SetStopOnContinue(bool stop_on_continue)
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override
bool DoExecute(llvm::StringRef raw_command_line, CommandReturnObject &result) override
Definition: SBAddress.h:15
virtual void SetIsDone(bool b)
Definition: IOHandler.h:86
CommandObjectCommandsAddRegex(CommandInterpreter &interpreter)
CommandObjectCommandsScriptImport(CommandInterpreter &interpreter)
static constexpr OptionDefinition g_regex_options[]
#define LLDB_OPT_SET_ALL
Definition: lldb-defines.h:110
Args & GetArgs()
Returns the list of arguments.
Definition: Args.h:357
std::shared_ptr< OptionArgVector > OptionArgVectorSP
Definition: Options.h:28
bool GetCommandString(std::string &command) const
Definition: Args.cpp:207
lldb::StreamFileSP & GetOutputStreamFile()
Definition: IOHandler.cpp:126
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:255
bool HandleAliasingRawCommand(llvm::StringRef alias_command, llvm::StringRef raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
void Append(OptionGroup *group)
Append options from a OptionGroup class.
Definition: Options.cpp:843
#define LLDB_OPT_SET_1
Definition: lldb-defines.h:111
size_t SplitIntoLines(const std::string &lines)
Definition: StringList.cpp:149
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:130
bool DoExecute(Args &command, CommandReturnObject &result) override
std::shared_ptr< Generic > GenericSP
void OptionParsingStarting(ExecutionContext *execution_context) override
void AppendWarningWithFormat(const char *format,...) __attribute__((format(printf
#define UINT64_MAX
Definition: lldb-defines.h:35
A pair of an option list with a &#39;raw&#39; string as a suffix.
Definition: Args.h:341
llvm::StringRef GetCommandName() const
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void SetStatus(lldb::ReturnStatus status)
bool DoExecute(Args &args, CommandReturnObject &result) override
void NotifyOptionParsingStarting(ExecutionContext *execution_context)
Definition: Options.cpp:32
CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter)
An error handling class.
Definition: Status.h:44