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