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     bool m_fetched_help_long;
1166 
1167 public:
1168 
1169     CommandObjectPythonFunction (CommandInterpreter &interpreter,
1170                                  std::string name,
1171                                  std::string funct,
1172                                  ScriptedCommandSynchronicity synch) :
1173         CommandObjectRaw (interpreter,
1174                           name.c_str(),
1175                           (std::string("Run Python function ") + funct).c_str(),
1176                           NULL),
1177         m_function_name(funct),
1178         m_synchro(synch),
1179         m_fetched_help_long(false)
1180     {
1181     }
1182 
1183     virtual
1184     ~CommandObjectPythonFunction ()
1185     {
1186     }
1187 
1188     virtual bool
1189     IsRemovable ()
1190     {
1191         return true;
1192     }
1193 
1194     const std::string&
1195     GetFunctionName ()
1196     {
1197         return m_function_name;
1198     }
1199 
1200     ScriptedCommandSynchronicity
1201     GetSynchronicity ()
1202     {
1203         return m_synchro;
1204     }
1205 
1206     virtual const char *
1207     GetHelpLong ()
1208     {
1209         if (!m_fetched_help_long)
1210         {
1211             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1212             if (scripter)
1213             {
1214                 std::string docstring;
1215                 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1216                 if (!docstring.empty())
1217                     SetHelpLong(docstring);
1218             }
1219         }
1220         return CommandObjectRaw::GetHelpLong();
1221     }
1222 
1223 protected:
1224     virtual bool
1225     DoExecute (const char *raw_command_line, CommandReturnObject &result)
1226     {
1227         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1228 
1229         Error error;
1230 
1231         result.SetStatus(eReturnStatusInvalid);
1232 
1233         if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1234                                                          raw_command_line,
1235                                                          m_synchro,
1236                                                          result,
1237                                                          error) == false)
1238         {
1239             result.AppendError(error.AsCString());
1240             result.SetStatus(eReturnStatusFailed);
1241         }
1242         else
1243         {
1244             // Don't change the status if the command already set it...
1245             if (result.GetStatus() == eReturnStatusInvalid)
1246             {
1247                 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
1248                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1249                 else
1250                     result.SetStatus(eReturnStatusSuccessFinishResult);
1251             }
1252         }
1253 
1254         return result.Succeeded();
1255     }
1256 
1257 };
1258 
1259 //-------------------------------------------------------------------------
1260 // CommandObjectCommandsScriptImport
1261 //-------------------------------------------------------------------------
1262 
1263 class CommandObjectCommandsScriptImport : public CommandObjectParsed
1264 {
1265 public:
1266     CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
1267         CommandObjectParsed (interpreter,
1268                              "command script import",
1269                              "Import a scripting module in LLDB.",
1270                              NULL),
1271         m_options(interpreter)
1272     {
1273         CommandArgumentEntry arg1;
1274         CommandArgumentData cmd_arg;
1275 
1276         // Define the first (and only) variant of this arg.
1277         cmd_arg.arg_type = eArgTypeFilename;
1278         cmd_arg.arg_repetition = eArgRepeatPlain;
1279 
1280         // There is only one variant this argument could be; put it into the argument entry.
1281         arg1.push_back (cmd_arg);
1282 
1283         // Push the data for the first argument into the m_arguments vector.
1284         m_arguments.push_back (arg1);
1285     }
1286 
1287     ~CommandObjectCommandsScriptImport ()
1288     {
1289     }
1290 
1291     int
1292     HandleArgumentCompletion (Args &input,
1293                               int &cursor_index,
1294                               int &cursor_char_position,
1295                               OptionElementVector &opt_element_vector,
1296                               int match_start_point,
1297                               int max_return_elements,
1298                               bool &word_complete,
1299                               StringList &matches)
1300     {
1301         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1302         completion_str.erase (cursor_char_position);
1303 
1304         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1305                                                              CommandCompletions::eDiskFileCompletion,
1306                                                              completion_str.c_str(),
1307                                                              match_start_point,
1308                                                              max_return_elements,
1309                                                              NULL,
1310                                                              word_complete,
1311                                                              matches);
1312         return matches.GetSize();
1313     }
1314 
1315     virtual Options *
1316     GetOptions ()
1317     {
1318         return &m_options;
1319     }
1320 
1321 protected:
1322 
1323     class CommandOptions : public Options
1324     {
1325     public:
1326 
1327         CommandOptions (CommandInterpreter &interpreter) :
1328             Options (interpreter)
1329         {
1330         }
1331 
1332         virtual
1333         ~CommandOptions (){}
1334 
1335         virtual Error
1336         SetOptionValue (uint32_t option_idx, const char *option_arg)
1337         {
1338             Error error;
1339             char short_option = (char) m_getopt_table[option_idx].val;
1340 
1341             switch (short_option)
1342             {
1343                 case 'r':
1344                     m_allow_reload = true;
1345                     break;
1346                 default:
1347                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1348                     break;
1349             }
1350 
1351             return error;
1352         }
1353 
1354         void
1355         OptionParsingStarting ()
1356         {
1357             m_allow_reload = false;
1358         }
1359 
1360         const OptionDefinition*
1361         GetDefinitions ()
1362         {
1363             return g_option_table;
1364         }
1365 
1366         // Options table: Required for subclasses of Options.
1367 
1368         static OptionDefinition g_option_table[];
1369 
1370         // Instance variables to hold the values for command options.
1371 
1372         bool m_allow_reload;
1373     };
1374 
1375     bool
1376     DoExecute (Args& command, CommandReturnObject &result)
1377     {
1378 
1379         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1380         {
1381             result.AppendError ("only scripting language supported for module importing is currently Python");
1382             result.SetStatus (eReturnStatusFailed);
1383             return false;
1384         }
1385 
1386         size_t argc = command.GetArgumentCount();
1387 
1388         if (argc != 1)
1389         {
1390             result.AppendError ("'command script import' requires one argument");
1391             result.SetStatus (eReturnStatusFailed);
1392             return false;
1393         }
1394 
1395         std::string path = command.GetArgumentAtIndex(0);
1396         Error error;
1397 
1398         if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
1399                                                                       m_options.m_allow_reload,
1400                                                                       error))
1401         {
1402             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1403         }
1404         else
1405         {
1406             result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1407             result.SetStatus (eReturnStatusFailed);
1408         }
1409 
1410         return result.Succeeded();
1411     }
1412 
1413     CommandOptions m_options;
1414 };
1415 
1416 OptionDefinition
1417 CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1418 {
1419     { 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)."},
1420     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1421 };
1422 
1423 
1424 //-------------------------------------------------------------------------
1425 // CommandObjectCommandsScriptAdd
1426 //-------------------------------------------------------------------------
1427 
1428 class CommandObjectCommandsScriptAdd : public CommandObjectParsed
1429 {
1430 public:
1431     CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1432         CommandObjectParsed (interpreter,
1433                              "command script add",
1434                              "Add a scripted function as an LLDB command.",
1435                              NULL),
1436         m_options (interpreter)
1437     {
1438         CommandArgumentEntry arg1;
1439         CommandArgumentData cmd_arg;
1440 
1441         // Define the first (and only) variant of this arg.
1442         cmd_arg.arg_type = eArgTypeCommandName;
1443         cmd_arg.arg_repetition = eArgRepeatPlain;
1444 
1445         // There is only one variant this argument could be; put it into the argument entry.
1446         arg1.push_back (cmd_arg);
1447 
1448         // Push the data for the first argument into the m_arguments vector.
1449         m_arguments.push_back (arg1);
1450     }
1451 
1452     ~CommandObjectCommandsScriptAdd ()
1453     {
1454     }
1455 
1456     virtual Options *
1457     GetOptions ()
1458     {
1459         return &m_options;
1460     }
1461 
1462 protected:
1463 
1464     class CommandOptions : public Options
1465     {
1466     public:
1467 
1468         CommandOptions (CommandInterpreter &interpreter) :
1469         Options (interpreter)
1470         {
1471         }
1472 
1473         virtual
1474         ~CommandOptions (){}
1475 
1476         virtual Error
1477         SetOptionValue (uint32_t option_idx, const char *option_arg)
1478         {
1479             Error error;
1480             char short_option = (char) m_getopt_table[option_idx].val;
1481 
1482             switch (short_option)
1483             {
1484                 case 'f':
1485                     m_funct_name = std::string(option_arg);
1486                     break;
1487                 case 's':
1488                     m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
1489                     if (!error.Success())
1490                         error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1491                     break;
1492                 default:
1493                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1494                     break;
1495             }
1496 
1497             return error;
1498         }
1499 
1500         void
1501         OptionParsingStarting ()
1502         {
1503             m_funct_name = "";
1504             m_synchronous = eScriptedCommandSynchronicitySynchronous;
1505         }
1506 
1507         const OptionDefinition*
1508         GetDefinitions ()
1509         {
1510             return g_option_table;
1511         }
1512 
1513         // Options table: Required for subclasses of Options.
1514 
1515         static OptionDefinition g_option_table[];
1516 
1517         // Instance variables to hold the values for command options.
1518 
1519         std::string m_funct_name;
1520         ScriptedCommandSynchronicity m_synchronous;
1521     };
1522 
1523 private:
1524     class PythonAliasReader : public InputReaderEZ
1525     {
1526     private:
1527         CommandInterpreter& m_interpreter;
1528         std::string m_cmd_name;
1529         ScriptedCommandSynchronicity m_synchronous;
1530         StringList m_user_input;
1531         DISALLOW_COPY_AND_ASSIGN (PythonAliasReader);
1532     public:
1533         PythonAliasReader(Debugger& debugger,
1534                           CommandInterpreter& interpreter,
1535                           std::string cmd_name,
1536                           ScriptedCommandSynchronicity synch) :
1537         InputReaderEZ(debugger),
1538         m_interpreter(interpreter),
1539         m_cmd_name(cmd_name),
1540         m_synchronous(synch),
1541         m_user_input()
1542         {}
1543 
1544         virtual
1545         ~PythonAliasReader()
1546         {
1547         }
1548 
1549         virtual void ActivateHandler(HandlerData& data)
1550         {
1551             StreamSP out_stream = data.GetOutStream();
1552             bool batch_mode = data.GetBatchMode();
1553             if (!batch_mode)
1554             {
1555                 out_stream->Printf ("%s\n", g_python_command_instructions);
1556                 if (data.reader.GetPrompt())
1557                     out_stream->Printf ("%s", data.reader.GetPrompt());
1558                 out_stream->Flush();
1559             }
1560         }
1561 
1562         virtual void ReactivateHandler(HandlerData& data)
1563         {
1564             StreamSP out_stream = data.GetOutStream();
1565             bool batch_mode = data.GetBatchMode();
1566             if (data.reader.GetPrompt() && !batch_mode)
1567             {
1568                 out_stream->Printf ("%s", data.reader.GetPrompt());
1569                 out_stream->Flush();
1570             }
1571         }
1572         virtual void GotTokenHandler(HandlerData& data)
1573         {
1574             StreamSP out_stream = data.GetOutStream();
1575             bool batch_mode = data.GetBatchMode();
1576             if (data.bytes && data.bytes_len)
1577             {
1578                 m_user_input.AppendString(data.bytes, data.bytes_len);
1579             }
1580             if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
1581             {
1582                 out_stream->Printf ("%s", data.reader.GetPrompt());
1583                 out_stream->Flush();
1584             }
1585         }
1586         virtual void InterruptHandler(HandlerData& data)
1587         {
1588             StreamSP out_stream = data.GetOutStream();
1589             bool batch_mode = data.GetBatchMode();
1590             data.reader.SetIsDone (true);
1591             if (!batch_mode)
1592             {
1593                 out_stream->Printf ("Warning: No script attached.\n");
1594                 out_stream->Flush();
1595             }
1596         }
1597         virtual void EOFHandler(HandlerData& data)
1598         {
1599             data.reader.SetIsDone (true);
1600         }
1601         virtual void DoneHandler(HandlerData& data)
1602         {
1603             StreamSP out_stream = data.GetOutStream();
1604 
1605             ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1606             if (!interpreter)
1607             {
1608                 out_stream->Printf ("Script interpreter missing: no script attached.\n");
1609                 out_stream->Flush();
1610                 return;
1611             }
1612             std::string funct_name_str;
1613             if (!interpreter->GenerateScriptAliasFunction (m_user_input,
1614                                                            funct_name_str))
1615             {
1616                 out_stream->Printf ("Unable to create function: no script attached.\n");
1617                 out_stream->Flush();
1618                 return;
1619             }
1620             if (funct_name_str.empty())
1621             {
1622                 out_stream->Printf ("Unable to obtain a function name: no script attached.\n");
1623                 out_stream->Flush();
1624                 return;
1625             }
1626             // everything should be fine now, let's add this alias
1627 
1628             CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter,
1629                                                                            m_cmd_name,
1630                                                                            funct_name_str.c_str(),
1631                                                                            m_synchronous));
1632 
1633             if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1634             {
1635                 out_stream->Printf ("Unable to add selected command: no script attached.\n");
1636                 out_stream->Flush();
1637                 return;
1638             }
1639         }
1640     };
1641 
1642 protected:
1643     bool
1644     DoExecute (Args& command, CommandReturnObject &result)
1645     {
1646 
1647         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1648         {
1649             result.AppendError ("only scripting language supported for scripted commands is currently Python");
1650             result.SetStatus (eReturnStatusFailed);
1651             return false;
1652         }
1653 
1654         size_t argc = command.GetArgumentCount();
1655 
1656         if (argc != 1)
1657         {
1658             result.AppendError ("'command script add' requires one argument");
1659             result.SetStatus (eReturnStatusFailed);
1660             return false;
1661         }
1662 
1663         std::string cmd_name = command.GetArgumentAtIndex(0);
1664 
1665         if (m_options.m_funct_name.empty())
1666         {
1667             InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(),
1668                                                             m_interpreter,
1669                                                             cmd_name,
1670                                                             m_options.m_synchronous));
1671 
1672             if (reader_sp)
1673             {
1674 
1675                 InputReaderEZ::InitializationParameters ipr;
1676 
1677                 Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt("     ")));
1678                 if (err.Success())
1679                 {
1680                     m_interpreter.GetDebugger().PushInputReader (reader_sp);
1681                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1682                 }
1683                 else
1684                 {
1685                     result.AppendError (err.AsCString());
1686                     result.SetStatus (eReturnStatusFailed);
1687                 }
1688             }
1689             else
1690             {
1691                 result.AppendError("out of memory");
1692                 result.SetStatus (eReturnStatusFailed);
1693             }
1694         }
1695         else
1696         {
1697             CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
1698                                                                     cmd_name,
1699                                                                     m_options.m_funct_name,
1700                                                                     m_options.m_synchronous));
1701             if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true))
1702             {
1703                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1704             }
1705             else
1706             {
1707                 result.AppendError("cannot add command");
1708                 result.SetStatus (eReturnStatusFailed);
1709             }
1710         }
1711 
1712         return result.Succeeded();
1713 
1714     }
1715 
1716     CommandOptions m_options;
1717 };
1718 
1719 static OptionEnumValueElement g_script_synchro_type[] =
1720 {
1721     { eScriptedCommandSynchronicitySynchronous,      "synchronous",       "Run synchronous"},
1722     { eScriptedCommandSynchronicityAsynchronous,     "asynchronous",      "Run asynchronous"},
1723     { eScriptedCommandSynchronicityCurrentValue,     "current",           "Do not alter current setting"},
1724     { 0, NULL, NULL }
1725 };
1726 
1727 OptionDefinition
1728 CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1729 {
1730     { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypePythonFunction,        "Name of the Python function to bind to this command name."},
1731     { 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."},
1732     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1733 };
1734 
1735 //-------------------------------------------------------------------------
1736 // CommandObjectCommandsScriptList
1737 //-------------------------------------------------------------------------
1738 
1739 class CommandObjectCommandsScriptList : public CommandObjectParsed
1740 {
1741 private:
1742 
1743 public:
1744     CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
1745     CommandObjectParsed (interpreter,
1746                    "command script list",
1747                    "List defined scripted commands.",
1748                    NULL)
1749     {
1750     }
1751 
1752     ~CommandObjectCommandsScriptList ()
1753     {
1754     }
1755 
1756     bool
1757     DoExecute (Args& command, CommandReturnObject &result)
1758     {
1759 
1760         m_interpreter.GetHelp(result,
1761                               CommandInterpreter::eCommandTypesUserDef);
1762 
1763         result.SetStatus (eReturnStatusSuccessFinishResult);
1764 
1765         return true;
1766 
1767 
1768     }
1769 };
1770 
1771 //-------------------------------------------------------------------------
1772 // CommandObjectCommandsScriptClear
1773 //-------------------------------------------------------------------------
1774 
1775 class CommandObjectCommandsScriptClear : public CommandObjectParsed
1776 {
1777 private:
1778 
1779 public:
1780     CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
1781         CommandObjectParsed (interpreter,
1782                              "command script clear",
1783                              "Delete all scripted commands.",
1784                              NULL)
1785     {
1786     }
1787 
1788     ~CommandObjectCommandsScriptClear ()
1789     {
1790     }
1791 
1792 protected:
1793     bool
1794     DoExecute (Args& command, CommandReturnObject &result)
1795     {
1796 
1797         m_interpreter.RemoveAllUser();
1798 
1799         result.SetStatus (eReturnStatusSuccessFinishResult);
1800 
1801         return true;
1802     }
1803 };
1804 
1805 //-------------------------------------------------------------------------
1806 // CommandObjectCommandsScriptDelete
1807 //-------------------------------------------------------------------------
1808 
1809 class CommandObjectCommandsScriptDelete : public CommandObjectParsed
1810 {
1811 public:
1812     CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
1813         CommandObjectParsed (interpreter,
1814                              "command script delete",
1815                              "Delete a scripted command.",
1816                              NULL)
1817     {
1818         CommandArgumentEntry arg1;
1819         CommandArgumentData cmd_arg;
1820 
1821         // Define the first (and only) variant of this arg.
1822         cmd_arg.arg_type = eArgTypeCommandName;
1823         cmd_arg.arg_repetition = eArgRepeatPlain;
1824 
1825         // There is only one variant this argument could be; put it into the argument entry.
1826         arg1.push_back (cmd_arg);
1827 
1828         // Push the data for the first argument into the m_arguments vector.
1829         m_arguments.push_back (arg1);
1830     }
1831 
1832     ~CommandObjectCommandsScriptDelete ()
1833     {
1834     }
1835 
1836 protected:
1837     bool
1838     DoExecute (Args& command, CommandReturnObject &result)
1839     {
1840 
1841         size_t argc = command.GetArgumentCount();
1842 
1843         if (argc != 1)
1844         {
1845             result.AppendError ("'command script delete' requires one argument");
1846             result.SetStatus (eReturnStatusFailed);
1847             return false;
1848         }
1849 
1850         const char* cmd_name = command.GetArgumentAtIndex(0);
1851 
1852         if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
1853         {
1854             m_interpreter.RemoveUser(cmd_name);
1855             result.SetStatus (eReturnStatusSuccessFinishResult);
1856         }
1857         else
1858         {
1859             result.AppendErrorWithFormat ("command %s not found", cmd_name);
1860             result.SetStatus (eReturnStatusFailed);
1861         }
1862 
1863         return result.Succeeded();
1864 
1865     }
1866 };
1867 
1868 #pragma mark CommandObjectMultiwordCommandsScript
1869 
1870 //-------------------------------------------------------------------------
1871 // CommandObjectMultiwordCommandsScript
1872 //-------------------------------------------------------------------------
1873 
1874 class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
1875 {
1876 public:
1877     CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
1878     CommandObjectMultiword (interpreter,
1879                             "command script",
1880                             "A set of commands for managing or customizing script commands.",
1881                             "command script <subcommand> [<subcommand-options>]")
1882     {
1883         LoadSubCommand ("add",  CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
1884         LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
1885         LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
1886         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
1887         LoadSubCommand ("import",   CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
1888     }
1889 
1890     ~CommandObjectMultiwordCommandsScript ()
1891     {
1892     }
1893 
1894 };
1895 
1896 
1897 #pragma mark CommandObjectMultiwordCommands
1898 
1899 //-------------------------------------------------------------------------
1900 // CommandObjectMultiwordCommands
1901 //-------------------------------------------------------------------------
1902 
1903 CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
1904     CommandObjectMultiword (interpreter,
1905                             "command",
1906                             "A set of commands for managing or customizing the debugger commands.",
1907                             "command <subcommand> [<subcommand-options>]")
1908 {
1909     LoadSubCommand ("source",  CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
1910     LoadSubCommand ("alias",   CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
1911     LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
1912     LoadSubCommand ("regex",   CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
1913     LoadSubCommand ("history",   CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
1914     LoadSubCommand ("script",   CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
1915 }
1916 
1917 CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
1918 {
1919 }
1920 
1921