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