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