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