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