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