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