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