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