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, 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 with 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 "(lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
799                     );
800     }
801 
802     ~CommandObjectCommandsAddRegex()
803     {
804     }
805 
806 
807 protected:
808     bool
809     DoExecute (Args& command, CommandReturnObject &result)
810     {
811         const size_t argc = command.GetArgumentCount();
812         if (argc == 0)
813         {
814             result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
815             result.SetStatus (eReturnStatusFailed);
816         }
817         else
818         {
819             Error error;
820             const char *name = command.GetArgumentAtIndex(0);
821             m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
822                                                                  name,
823                                                                  m_options.GetHelp (),
824                                                                  m_options.GetSyntax (),
825                                                                  10));
826 
827             if (argc == 1)
828             {
829                 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
830                 if (reader_sp)
831                 {
832                     error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback,
833                                                   this,                         // baton
834                                                   eInputReaderGranularityLine,  // token size, to pass to callback function
835                                                   NULL,                         // end token
836                                                   "> ",                         // prompt
837                                                   true);                        // echo input
838                     if (error.Success())
839                     {
840                         m_interpreter.GetDebugger().PushInputReader (reader_sp);
841                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
842                         return true;
843                     }
844                 }
845             }
846             else
847             {
848                 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
849                 {
850                     llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
851                     error = AppendRegexSubstitution (arg_strref);
852                     if (error.Fail())
853                         break;
854                 }
855 
856                 if (error.Success())
857                 {
858                     AddRegexCommandToInterpreter();
859                 }
860             }
861             if (error.Fail())
862             {
863                 result.AppendError (error.AsCString());
864                 result.SetStatus (eReturnStatusFailed);
865             }
866         }
867 
868         return result.Succeeded();
869     }
870 
871     Error
872     AppendRegexSubstitution (const llvm::StringRef &regex_sed)
873     {
874         Error error;
875 
876         if (m_regex_cmd_ap.get() == NULL)
877         {
878             error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
879                                            (int)regex_sed.size(),
880                                            regex_sed.data());
881             return error;
882         }
883 
884         size_t regex_sed_size = regex_sed.size();
885 
886         if (regex_sed_size <= 1)
887         {
888             error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
889                                            (int)regex_sed.size(),
890                                            regex_sed.data());
891             return error;
892         }
893 
894         if (regex_sed[0] != 's')
895         {
896             error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
897                                            (int)regex_sed.size(),
898                                            regex_sed.data());
899             return error;
900         }
901         const size_t first_separator_char_pos = 1;
902         // use the char that follows 's' as the regex separator character
903         // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
904         const char separator_char = regex_sed[first_separator_char_pos];
905         const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
906 
907         if (second_separator_char_pos == std::string::npos)
908         {
909             error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'",
910                                            separator_char,
911                                            (int)(regex_sed.size() - first_separator_char_pos - 1),
912                                            regex_sed.data() + (first_separator_char_pos + 1));
913             return error;
914         }
915 
916         const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
917 
918         if (third_separator_char_pos == std::string::npos)
919         {
920             error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'",
921                                            separator_char,
922                                            (int)(regex_sed.size() - second_separator_char_pos - 1),
923                                            regex_sed.data() + (second_separator_char_pos + 1));
924             return error;
925         }
926 
927         if (third_separator_char_pos != regex_sed_size - 1)
928         {
929             // Make sure that everything that follows the last regex
930             // separator char
931             if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
932             {
933                 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
934                                                (int)third_separator_char_pos + 1,
935                                                regex_sed.data(),
936                                                (int)(regex_sed.size() - third_separator_char_pos - 1),
937                                                regex_sed.data() + (third_separator_char_pos + 1));
938                 return error;
939             }
940 
941         }
942         else if (first_separator_char_pos + 1 == second_separator_char_pos)
943         {
944             error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
945                                            separator_char,
946                                            separator_char,
947                                            separator_char,
948                                            (int)regex_sed.size(),
949                                            regex_sed.data());
950             return error;
951         }
952         else if (second_separator_char_pos + 1 == third_separator_char_pos)
953         {
954             error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
955                                            separator_char,
956                                            separator_char,
957                                            separator_char,
958                                            (int)regex_sed.size(),
959                                            regex_sed.data());
960             return error;
961         }
962         std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
963         std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
964         m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
965                                          subst.c_str());
966         return error;
967     }
968 
969     void
970     AddRegexCommandToInterpreter()
971     {
972         if (m_regex_cmd_ap.get())
973         {
974             if (m_regex_cmd_ap->HasRegexEntries())
975             {
976                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
977                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
978             }
979         }
980     }
981 
982     void
983     InputReaderDidCancel()
984     {
985         m_regex_cmd_ap.reset();
986     }
987 
988     static size_t
989     InputReaderCallback (void *baton,
990                          InputReader &reader,
991                          lldb::InputReaderAction notification,
992                          const char *bytes,
993                          size_t bytes_len)
994     {
995         CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton;
996         bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
997 
998         switch (notification)
999         {
1000             case eInputReaderActivate:
1001                 if (!batch_mode)
1002                 {
1003                     StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream ();
1004                     out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:");
1005                     out_stream->Flush();
1006                 }
1007                 break;
1008             case eInputReaderReactivate:
1009                 break;
1010 
1011             case eInputReaderDeactivate:
1012                 break;
1013 
1014             case eInputReaderAsynchronousOutputWritten:
1015                 break;
1016 
1017             case eInputReaderGotToken:
1018                 while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n'))
1019                     --bytes_len;
1020                 if (bytes_len == 0)
1021                     reader.SetIsDone(true);
1022                 else if (bytes)
1023                 {
1024                     llvm::StringRef bytes_strref (bytes, bytes_len);
1025                     Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref));
1026                     if (error.Fail())
1027                     {
1028                         if (!batch_mode)
1029                         {
1030                             StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
1031                             out_stream->Printf("error: %s\n", error.AsCString());
1032                             out_stream->Flush();
1033                         }
1034                         add_regex_cmd->InputReaderDidCancel ();
1035                         reader.SetIsDone (true);
1036                     }
1037                 }
1038                 break;
1039 
1040             case eInputReaderInterrupt:
1041                 {
1042                     reader.SetIsDone (true);
1043                     if (!batch_mode)
1044                     {
1045                         StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
1046                         out_stream->PutCString("Regular expression command creations was cancelled.\n");
1047                         out_stream->Flush();
1048                     }
1049                     add_regex_cmd->InputReaderDidCancel ();
1050                 }
1051                 break;
1052 
1053             case eInputReaderEndOfFile:
1054                 reader.SetIsDone (true);
1055                 break;
1056 
1057             case eInputReaderDone:
1058                 add_regex_cmd->AddRegexCommandToInterpreter();
1059                 break;
1060         }
1061 
1062         return bytes_len;
1063     }
1064 
1065 private:
1066     std::auto_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1067 
1068      class CommandOptions : public Options
1069      {
1070      public:
1071 
1072          CommandOptions (CommandInterpreter &interpreter) :
1073             Options (interpreter)
1074          {
1075          }
1076 
1077          virtual
1078          ~CommandOptions (){}
1079 
1080          virtual Error
1081          SetOptionValue (uint32_t option_idx, const char *option_arg)
1082          {
1083              Error error;
1084              char short_option = (char) m_getopt_table[option_idx].val;
1085 
1086              switch (short_option)
1087              {
1088                  case 'h':
1089                      m_help.assign (option_arg);
1090                      break;
1091                  case 's':
1092                      m_syntax.assign (option_arg);
1093                      break;
1094 
1095                  default:
1096                      error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1097                      break;
1098              }
1099 
1100              return error;
1101          }
1102 
1103          void
1104          OptionParsingStarting ()
1105          {
1106              m_help.clear();
1107              m_syntax.clear();
1108          }
1109 
1110          const OptionDefinition*
1111          GetDefinitions ()
1112          {
1113              return g_option_table;
1114          }
1115 
1116          // Options table: Required for subclasses of Options.
1117 
1118          static OptionDefinition g_option_table[];
1119 
1120          const char *
1121          GetHelp ()
1122          {
1123              if (m_help.empty())
1124                  return NULL;
1125              return m_help.c_str();
1126          }
1127          const char *
1128          GetSyntax ()
1129          {
1130              if (m_syntax.empty())
1131                  return NULL;
1132              return m_syntax.c_str();
1133          }
1134          // Instance variables to hold the values for command options.
1135      protected:
1136          std::string m_help;
1137          std::string m_syntax;
1138      };
1139 
1140      virtual Options *
1141      GetOptions ()
1142      {
1143          return &m_options;
1144      }
1145 
1146      CommandOptions m_options;
1147 };
1148 
1149 OptionDefinition
1150 CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1151 {
1152 { LLDB_OPT_SET_1, false, "help"  , 'h', required_argument, NULL, 0, eArgTypeNone, "The help text to display for this command."},
1153 { LLDB_OPT_SET_1, false, "syntax", 's', required_argument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
1154 { 0             , false,  NULL   , 0  , 0                , NULL, 0, eArgTypeNone, NULL }
1155 };
1156 
1157 
1158 class CommandObjectPythonFunction : public CommandObjectRaw
1159 {
1160 private:
1161     std::string m_function_name;
1162     ScriptedCommandSynchronicity m_synchro;
1163 
1164 public:
1165 
1166     CommandObjectPythonFunction (CommandInterpreter &interpreter,
1167                                  std::string name,
1168                                  std::string funct,
1169                                  ScriptedCommandSynchronicity synch) :
1170         CommandObjectRaw (interpreter,
1171                           name.c_str(),
1172                           (std::string("Run Python function ") + funct).c_str(),
1173                           NULL),
1174         m_function_name(funct),
1175         m_synchro(synch)
1176     {
1177         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1178         if (scripter)
1179         {
1180             std::string docstring = scripter->GetDocumentationForItem(funct.c_str());
1181             if (!docstring.empty())
1182                 SetHelpLong(docstring);
1183         }
1184     }
1185 
1186     virtual
1187     ~CommandObjectPythonFunction ()
1188     {
1189     }
1190 
1191     virtual bool
1192     IsRemovable ()
1193     {
1194         return true;
1195     }
1196 
1197     const std::string&
1198     GetFunctionName ()
1199     {
1200         return m_function_name;
1201     }
1202 
1203     ScriptedCommandSynchronicity
1204     GetSynchronicity ()
1205     {
1206         return m_synchro;
1207     }
1208 
1209 protected:
1210     virtual bool
1211     DoExecute (const char *raw_command_line, CommandReturnObject &result)
1212     {
1213         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1214 
1215         Error error;
1216 
1217         if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1218                                                          raw_command_line,
1219                                                          m_synchro,
1220                                                          result,
1221                                                          error) == false)
1222         {
1223             result.AppendError(error.AsCString());
1224             result.SetStatus(eReturnStatusFailed);
1225         }
1226         else
1227             result.SetStatus(eReturnStatusSuccessFinishNoResult);
1228 
1229         return result.Succeeded();
1230     }
1231 
1232 };
1233 
1234 //-------------------------------------------------------------------------
1235 // CommandObjectCommandsScriptImport
1236 //-------------------------------------------------------------------------
1237 
1238 class CommandObjectCommandsScriptImport : public CommandObjectParsed
1239 {
1240 public:
1241     CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
1242         CommandObjectParsed (interpreter,
1243                              "command script import",
1244                              "Import a scripting module in LLDB.",
1245                              NULL),
1246         m_options(interpreter)
1247     {
1248         CommandArgumentEntry arg1;
1249         CommandArgumentData cmd_arg;
1250 
1251         // Define the first (and only) variant of this arg.
1252         cmd_arg.arg_type = eArgTypeFilename;
1253         cmd_arg.arg_repetition = eArgRepeatPlain;
1254 
1255         // There is only one variant this argument could be; put it into the argument entry.
1256         arg1.push_back (cmd_arg);
1257 
1258         // Push the data for the first argument into the m_arguments vector.
1259         m_arguments.push_back (arg1);
1260     }
1261 
1262     ~CommandObjectCommandsScriptImport ()
1263     {
1264     }
1265 
1266     int
1267     HandleArgumentCompletion (Args &input,
1268                               int &cursor_index,
1269                               int &cursor_char_position,
1270                               OptionElementVector &opt_element_vector,
1271                               int match_start_point,
1272                               int max_return_elements,
1273                               bool &word_complete,
1274                               StringList &matches)
1275     {
1276         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1277         completion_str.erase (cursor_char_position);
1278 
1279         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1280                                                              CommandCompletions::eDiskFileCompletion,
1281                                                              completion_str.c_str(),
1282                                                              match_start_point,
1283                                                              max_return_elements,
1284                                                              NULL,
1285                                                              word_complete,
1286                                                              matches);
1287         return matches.GetSize();
1288     }
1289 
1290     virtual Options *
1291     GetOptions ()
1292     {
1293         return &m_options;
1294     }
1295 
1296 protected:
1297 
1298     class CommandOptions : public Options
1299     {
1300     public:
1301 
1302         CommandOptions (CommandInterpreter &interpreter) :
1303             Options (interpreter)
1304         {
1305         }
1306 
1307         virtual
1308         ~CommandOptions (){}
1309 
1310         virtual Error
1311         SetOptionValue (uint32_t option_idx, const char *option_arg)
1312         {
1313             Error error;
1314             char short_option = (char) m_getopt_table[option_idx].val;
1315 
1316             switch (short_option)
1317             {
1318                 case 'r':
1319                     m_allow_reload = true;
1320                     break;
1321                 default:
1322                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1323                     break;
1324             }
1325 
1326             return error;
1327         }
1328 
1329         void
1330         OptionParsingStarting ()
1331         {
1332             m_allow_reload = false;
1333         }
1334 
1335         const OptionDefinition*
1336         GetDefinitions ()
1337         {
1338             return g_option_table;
1339         }
1340 
1341         // Options table: Required for subclasses of Options.
1342 
1343         static OptionDefinition g_option_table[];
1344 
1345         // Instance variables to hold the values for command options.
1346 
1347         bool m_allow_reload;
1348     };
1349 
1350     bool
1351     DoExecute (Args& command, CommandReturnObject &result)
1352     {
1353 
1354         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1355         {
1356             result.AppendError ("only scripting language supported for module importing is currently Python");
1357             result.SetStatus (eReturnStatusFailed);
1358             return false;
1359         }
1360 
1361         size_t argc = command.GetArgumentCount();
1362 
1363         if (argc != 1)
1364         {
1365             result.AppendError ("'command script import' requires one argument");
1366             result.SetStatus (eReturnStatusFailed);
1367             return false;
1368         }
1369 
1370         std::string path = command.GetArgumentAtIndex(0);
1371         Error error;
1372 
1373         if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
1374                                                                       m_options.m_allow_reload,
1375                                                                       error))
1376         {
1377             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1378         }
1379         else
1380         {
1381             result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1382             result.SetStatus (eReturnStatusFailed);
1383         }
1384 
1385         return result.Succeeded();
1386     }
1387 
1388     CommandOptions m_options;
1389 };
1390 
1391 OptionDefinition
1392 CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1393 {
1394     { 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)."},
1395     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1396 };
1397 
1398 
1399 //-------------------------------------------------------------------------
1400 // CommandObjectCommandsScriptAdd
1401 //-------------------------------------------------------------------------
1402 
1403 class CommandObjectCommandsScriptAdd : public CommandObjectParsed
1404 {
1405 public:
1406     CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1407         CommandObjectParsed (interpreter,
1408                              "command script add",
1409                              "Add a scripted function as an LLDB command.",
1410                              NULL),
1411         m_options (interpreter)
1412     {
1413         CommandArgumentEntry arg1;
1414         CommandArgumentData cmd_arg;
1415 
1416         // Define the first (and only) variant of this arg.
1417         cmd_arg.arg_type = eArgTypeCommandName;
1418         cmd_arg.arg_repetition = eArgRepeatPlain;
1419 
1420         // There is only one variant this argument could be; put it into the argument entry.
1421         arg1.push_back (cmd_arg);
1422 
1423         // Push the data for the first argument into the m_arguments vector.
1424         m_arguments.push_back (arg1);
1425     }
1426 
1427     ~CommandObjectCommandsScriptAdd ()
1428     {
1429     }
1430 
1431     virtual Options *
1432     GetOptions ()
1433     {
1434         return &m_options;
1435     }
1436 
1437 protected:
1438 
1439     class CommandOptions : public Options
1440     {
1441     public:
1442 
1443         CommandOptions (CommandInterpreter &interpreter) :
1444         Options (interpreter)
1445         {
1446         }
1447 
1448         virtual
1449         ~CommandOptions (){}
1450 
1451         virtual Error
1452         SetOptionValue (uint32_t option_idx, const char *option_arg)
1453         {
1454             Error error;
1455             char short_option = (char) m_getopt_table[option_idx].val;
1456 
1457             switch (short_option)
1458             {
1459                 case 'f':
1460                     m_funct_name = std::string(option_arg);
1461                     break;
1462                 case 's':
1463                     m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
1464                     if (!error.Success())
1465                         error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1466                     break;
1467                 default:
1468                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1469                     break;
1470             }
1471 
1472             return error;
1473         }
1474 
1475         void
1476         OptionParsingStarting ()
1477         {
1478             m_funct_name = "";
1479             m_synchronous = eScriptedCommandSynchronicitySynchronous;
1480         }
1481 
1482         const OptionDefinition*
1483         GetDefinitions ()
1484         {
1485             return g_option_table;
1486         }
1487 
1488         // Options table: Required for subclasses of Options.
1489 
1490         static OptionDefinition g_option_table[];
1491 
1492         // Instance variables to hold the values for command options.
1493 
1494         std::string m_funct_name;
1495         ScriptedCommandSynchronicity m_synchronous;
1496     };
1497 
1498 private:
1499     class PythonAliasReader : public InputReaderEZ
1500     {
1501     private:
1502         CommandInterpreter& m_interpreter;
1503         std::string m_cmd_name;
1504         ScriptedCommandSynchronicity m_synchronous;
1505         StringList m_user_input;
1506         DISALLOW_COPY_AND_ASSIGN (PythonAliasReader);
1507     public:
1508         PythonAliasReader(Debugger& debugger,
1509                           CommandInterpreter& interpreter,
1510                           std::string cmd_name,
1511                           ScriptedCommandSynchronicity synch) :
1512         InputReaderEZ(debugger),
1513         m_interpreter(interpreter),
1514         m_cmd_name(cmd_name),
1515         m_synchronous(synch),
1516         m_user_input()
1517         {}
1518 
1519         virtual
1520         ~PythonAliasReader()
1521         {
1522         }
1523 
1524         virtual void ActivateHandler(HandlerData& data)
1525         {
1526             StreamSP out_stream = data.GetOutStream();
1527             bool batch_mode = data.GetBatchMode();
1528             if (!batch_mode)
1529             {
1530                 out_stream->Printf ("%s\n", g_python_command_instructions);
1531                 if (data.reader.GetPrompt())
1532                     out_stream->Printf ("%s", data.reader.GetPrompt());
1533                 out_stream->Flush();
1534             }
1535         }
1536 
1537         virtual void ReactivateHandler(HandlerData& data)
1538         {
1539             StreamSP out_stream = data.GetOutStream();
1540             bool batch_mode = data.GetBatchMode();
1541             if (data.reader.GetPrompt() && !batch_mode)
1542             {
1543                 out_stream->Printf ("%s", data.reader.GetPrompt());
1544                 out_stream->Flush();
1545             }
1546         }
1547         virtual void GotTokenHandler(HandlerData& data)
1548         {
1549             StreamSP out_stream = data.GetOutStream();
1550             bool batch_mode = data.GetBatchMode();
1551             if (data.bytes && data.bytes_len)
1552             {
1553                 m_user_input.AppendString(data.bytes, data.bytes_len);
1554             }
1555             if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
1556             {
1557                 out_stream->Printf ("%s", data.reader.GetPrompt());
1558                 out_stream->Flush();
1559             }
1560         }
1561         virtual void InterruptHandler(HandlerData& data)
1562         {
1563             StreamSP out_stream = data.GetOutStream();
1564             bool batch_mode = data.GetBatchMode();
1565             data.reader.SetIsDone (true);
1566             if (!batch_mode)
1567             {
1568                 out_stream->Printf ("Warning: No script attached.\n");
1569                 out_stream->Flush();
1570             }
1571         }
1572         virtual void EOFHandler(HandlerData& data)
1573         {
1574             data.reader.SetIsDone (true);
1575         }
1576         virtual void DoneHandler(HandlerData& data)
1577         {
1578             StreamSP out_stream = data.GetOutStream();
1579 
1580             ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1581             if (!interpreter)
1582             {
1583                 out_stream->Printf ("Script interpreter missing: no script attached.\n");
1584                 out_stream->Flush();
1585                 return;
1586             }
1587             std::string funct_name_str;
1588             if (!interpreter->GenerateScriptAliasFunction (m_user_input,
1589                                                            funct_name_str))
1590             {
1591                 out_stream->Printf ("Unable to create function: no script attached.\n");
1592                 out_stream->Flush();
1593                 return;
1594             }
1595             if (funct_name_str.empty())
1596             {
1597                 out_stream->Printf ("Unable to obtain a function name: no script attached.\n");
1598                 out_stream->Flush();
1599                 return;
1600             }
1601             // everything should be fine now, let's add this alias
1602 
1603             CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter,
1604                                                                            m_cmd_name,
1605                                                                            funct_name_str.c_str(),
1606                                                                            m_synchronous));
1607 
1608             if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1609             {
1610                 out_stream->Printf ("Unable to add selected command: no script attached.\n");
1611                 out_stream->Flush();
1612                 return;
1613             }
1614         }
1615     };
1616 
1617 protected:
1618     bool
1619     DoExecute (Args& command, CommandReturnObject &result)
1620     {
1621 
1622         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1623         {
1624             result.AppendError ("only scripting language supported for scripted commands is currently Python");
1625             result.SetStatus (eReturnStatusFailed);
1626             return false;
1627         }
1628 
1629         size_t argc = command.GetArgumentCount();
1630 
1631         if (argc != 1)
1632         {
1633             result.AppendError ("'command script add' requires one argument");
1634             result.SetStatus (eReturnStatusFailed);
1635             return false;
1636         }
1637 
1638         std::string cmd_name = command.GetArgumentAtIndex(0);
1639 
1640         if (m_options.m_funct_name.empty())
1641         {
1642             InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(),
1643                                                             m_interpreter,
1644                                                             cmd_name,
1645                                                             m_options.m_synchronous));
1646 
1647             if (reader_sp)
1648             {
1649 
1650                 InputReaderEZ::InitializationParameters ipr;
1651 
1652                 Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt("     ")));
1653                 if (err.Success())
1654                 {
1655                     m_interpreter.GetDebugger().PushInputReader (reader_sp);
1656                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1657                 }
1658                 else
1659                 {
1660                     result.AppendError (err.AsCString());
1661                     result.SetStatus (eReturnStatusFailed);
1662                 }
1663             }
1664             else
1665             {
1666                 result.AppendError("out of memory");
1667                 result.SetStatus (eReturnStatusFailed);
1668             }
1669         }
1670         else
1671         {
1672             CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
1673                                                                     cmd_name,
1674                                                                     m_options.m_funct_name,
1675                                                                     m_options.m_synchronous));
1676             if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true))
1677             {
1678                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1679             }
1680             else
1681             {
1682                 result.AppendError("cannot add command");
1683                 result.SetStatus (eReturnStatusFailed);
1684             }
1685         }
1686 
1687         return result.Succeeded();
1688 
1689     }
1690 
1691     CommandOptions m_options;
1692 };
1693 
1694 static OptionEnumValueElement g_script_synchro_type[] =
1695 {
1696     { eScriptedCommandSynchronicitySynchronous,      "synchronous",       "Run synchronous"},
1697     { eScriptedCommandSynchronicityAsynchronous,     "asynchronous",      "Run asynchronous"},
1698     { eScriptedCommandSynchronicityCurrentValue,     "current",           "Do not alter current setting"},
1699     { 0, NULL, NULL }
1700 };
1701 
1702 OptionDefinition
1703 CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1704 {
1705     { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypePythonFunction,        "Name of the Python function to bind to this command name."},
1706     { 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."},
1707     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1708 };
1709 
1710 //-------------------------------------------------------------------------
1711 // CommandObjectCommandsScriptList
1712 //-------------------------------------------------------------------------
1713 
1714 class CommandObjectCommandsScriptList : public CommandObjectParsed
1715 {
1716 private:
1717 
1718 public:
1719     CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
1720     CommandObjectParsed (interpreter,
1721                    "command script list",
1722                    "List defined scripted commands.",
1723                    NULL)
1724     {
1725     }
1726 
1727     ~CommandObjectCommandsScriptList ()
1728     {
1729     }
1730 
1731     bool
1732     DoExecute (Args& command, CommandReturnObject &result)
1733     {
1734 
1735         m_interpreter.GetHelp(result,
1736                               CommandInterpreter::eCommandTypesUserDef);
1737 
1738         result.SetStatus (eReturnStatusSuccessFinishResult);
1739 
1740         return true;
1741 
1742 
1743     }
1744 };
1745 
1746 //-------------------------------------------------------------------------
1747 // CommandObjectCommandsScriptClear
1748 //-------------------------------------------------------------------------
1749 
1750 class CommandObjectCommandsScriptClear : public CommandObjectParsed
1751 {
1752 private:
1753 
1754 public:
1755     CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
1756         CommandObjectParsed (interpreter,
1757                              "command script clear",
1758                              "Delete all scripted commands.",
1759                              NULL)
1760     {
1761     }
1762 
1763     ~CommandObjectCommandsScriptClear ()
1764     {
1765     }
1766 
1767 protected:
1768     bool
1769     DoExecute (Args& command, CommandReturnObject &result)
1770     {
1771 
1772         m_interpreter.RemoveAllUser();
1773 
1774         result.SetStatus (eReturnStatusSuccessFinishResult);
1775 
1776         return true;
1777     }
1778 };
1779 
1780 //-------------------------------------------------------------------------
1781 // CommandObjectCommandsScriptDelete
1782 //-------------------------------------------------------------------------
1783 
1784 class CommandObjectCommandsScriptDelete : public CommandObjectParsed
1785 {
1786 public:
1787     CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
1788         CommandObjectParsed (interpreter,
1789                              "command script delete",
1790                              "Delete a scripted command.",
1791                              NULL)
1792     {
1793         CommandArgumentEntry arg1;
1794         CommandArgumentData cmd_arg;
1795 
1796         // Define the first (and only) variant of this arg.
1797         cmd_arg.arg_type = eArgTypeCommandName;
1798         cmd_arg.arg_repetition = eArgRepeatPlain;
1799 
1800         // There is only one variant this argument could be; put it into the argument entry.
1801         arg1.push_back (cmd_arg);
1802 
1803         // Push the data for the first argument into the m_arguments vector.
1804         m_arguments.push_back (arg1);
1805     }
1806 
1807     ~CommandObjectCommandsScriptDelete ()
1808     {
1809     }
1810 
1811 protected:
1812     bool
1813     DoExecute (Args& command, CommandReturnObject &result)
1814     {
1815 
1816         size_t argc = command.GetArgumentCount();
1817 
1818         if (argc != 1)
1819         {
1820             result.AppendError ("'command script delete' requires one argument");
1821             result.SetStatus (eReturnStatusFailed);
1822             return false;
1823         }
1824 
1825         const char* cmd_name = command.GetArgumentAtIndex(0);
1826 
1827         if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
1828         {
1829             m_interpreter.RemoveUser(cmd_name);
1830             result.SetStatus (eReturnStatusSuccessFinishResult);
1831         }
1832         else
1833         {
1834             result.AppendErrorWithFormat ("command %s not found", cmd_name);
1835             result.SetStatus (eReturnStatusFailed);
1836         }
1837 
1838         return result.Succeeded();
1839 
1840     }
1841 };
1842 
1843 #pragma mark CommandObjectMultiwordCommandsScript
1844 
1845 //-------------------------------------------------------------------------
1846 // CommandObjectMultiwordCommandsScript
1847 //-------------------------------------------------------------------------
1848 
1849 class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
1850 {
1851 public:
1852     CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
1853     CommandObjectMultiword (interpreter,
1854                             "command script",
1855                             "A set of commands for managing or customizing script commands.",
1856                             "command script <subcommand> [<subcommand-options>]")
1857     {
1858         LoadSubCommand ("add",  CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
1859         LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
1860         LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
1861         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
1862         LoadSubCommand ("import",   CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
1863     }
1864 
1865     ~CommandObjectMultiwordCommandsScript ()
1866     {
1867     }
1868 
1869 };
1870 
1871 
1872 #pragma mark CommandObjectMultiwordCommands
1873 
1874 //-------------------------------------------------------------------------
1875 // CommandObjectMultiwordCommands
1876 //-------------------------------------------------------------------------
1877 
1878 CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
1879     CommandObjectMultiword (interpreter,
1880                             "command",
1881                             "A set of commands for managing or customizing the debugger commands.",
1882                             "command <subcommand> [<subcommand-options>]")
1883 {
1884     LoadSubCommand ("source",  CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
1885     LoadSubCommand ("alias",   CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
1886     LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
1887     LoadSubCommand ("regex",   CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
1888     LoadSubCommand ("history",   CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
1889     LoadSubCommand ("script",   CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
1890 }
1891 
1892 CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
1893 {
1894 }
1895 
1896