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