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