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