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