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