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