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