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