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