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