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 IOHandlerDelegateMultiline
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         IOHandlerDelegateMultiline ("", 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     void
922     IOHandlerActivated (IOHandler &io_handler) override
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     void
933     IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
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                     llvm::StringRef bytes_strref (lines[i]);
946                     Error error = AppendRegexSubstitution (bytes_strref, check_only);
947                     if (error.Fail())
948                     {
949                         if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
950                         {
951                             StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream();
952                             out_stream->Printf("error: %s\n", error.AsCString());
953                         }
954                     }
955                 }
956             }
957             if (m_regex_cmd_ap->HasRegexEntries())
958             {
959                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
960                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
961             }
962         }
963     }
964 
965     bool
966     DoExecute (Args& command, CommandReturnObject &result) override
967     {
968         const size_t argc = command.GetArgumentCount();
969         if (argc == 0)
970         {
971             result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
972             result.SetStatus (eReturnStatusFailed);
973         }
974         else
975         {
976             Error error;
977             const char *name = command.GetArgumentAtIndex(0);
978             m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
979                                                                  name,
980                                                                  m_options.GetHelp (),
981                                                                  m_options.GetSyntax (),
982                                                                  10));
983 
984             if (argc == 1)
985             {
986                 Debugger &debugger = m_interpreter.GetDebugger();
987                 bool color_prompt = debugger.GetUseColor();
988                 const bool multiple_lines = true; // Get multiple lines
989                 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
990                                                                   IOHandler::Type::Other,
991                                                                   "lldb-regex", // Name of input reader for history
992                                                                   "> ",         // Prompt
993                                                                   NULL,         // Continuation prompt
994                                                                   multiple_lines,
995                                                                   color_prompt,
996                                                                   0,            // Don't show line numbers
997                                                                   *this));
998 
999                 if (io_handler_sp)
1000                 {
1001                     debugger.PushIOHandler(io_handler_sp);
1002                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1003                 }
1004             }
1005             else
1006             {
1007                 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
1008                 {
1009                     llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
1010                     bool check_only = false;
1011                     error = AppendRegexSubstitution (arg_strref, check_only);
1012                     if (error.Fail())
1013                         break;
1014                 }
1015 
1016                 if (error.Success())
1017                 {
1018                     AddRegexCommandToInterpreter();
1019                 }
1020             }
1021             if (error.Fail())
1022             {
1023                 result.AppendError (error.AsCString());
1024                 result.SetStatus (eReturnStatusFailed);
1025             }
1026         }
1027 
1028         return result.Succeeded();
1029     }
1030 
1031     Error
1032     AppendRegexSubstitution (const llvm::StringRef &regex_sed, bool check_only)
1033     {
1034         Error error;
1035 
1036         if (m_regex_cmd_ap.get() == NULL)
1037         {
1038             error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
1039                                            (int)regex_sed.size(),
1040                                            regex_sed.data());
1041             return error;
1042         }
1043 
1044         size_t regex_sed_size = regex_sed.size();
1045 
1046         if (regex_sed_size <= 1)
1047         {
1048             error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
1049                                            (int)regex_sed.size(),
1050                                            regex_sed.data());
1051             return error;
1052         }
1053 
1054         if (regex_sed[0] != 's')
1055         {
1056             error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
1057                                            (int)regex_sed.size(),
1058                                            regex_sed.data());
1059             return error;
1060         }
1061         const size_t first_separator_char_pos = 1;
1062         // use the char that follows 's' as the regex separator character
1063         // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
1064         const char separator_char = regex_sed[first_separator_char_pos];
1065         const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
1066 
1067         if (second_separator_char_pos == std::string::npos)
1068         {
1069             error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'",
1070                                            separator_char,
1071                                            (int)(regex_sed.size() - first_separator_char_pos - 1),
1072                                            regex_sed.data() + (first_separator_char_pos + 1),
1073                                            (int)regex_sed.size(),
1074                                            regex_sed.data());
1075             return error;
1076         }
1077 
1078         const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
1079 
1080         if (third_separator_char_pos == std::string::npos)
1081         {
1082             error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'",
1083                                            separator_char,
1084                                            (int)(regex_sed.size() - second_separator_char_pos - 1),
1085                                            regex_sed.data() + (second_separator_char_pos + 1),
1086                                            (int)regex_sed.size(),
1087                                            regex_sed.data());
1088             return error;
1089         }
1090 
1091         if (third_separator_char_pos != regex_sed_size - 1)
1092         {
1093             // Make sure that everything that follows the last regex
1094             // separator char
1095             if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
1096             {
1097                 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
1098                                                (int)third_separator_char_pos + 1,
1099                                                regex_sed.data(),
1100                                                (int)(regex_sed.size() - third_separator_char_pos - 1),
1101                                                regex_sed.data() + (third_separator_char_pos + 1));
1102                 return error;
1103             }
1104 
1105         }
1106         else if (first_separator_char_pos + 1 == second_separator_char_pos)
1107         {
1108             error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1109                                            separator_char,
1110                                            separator_char,
1111                                            separator_char,
1112                                            (int)regex_sed.size(),
1113                                            regex_sed.data());
1114             return error;
1115         }
1116         else if (second_separator_char_pos + 1 == third_separator_char_pos)
1117         {
1118             error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
1119                                            separator_char,
1120                                            separator_char,
1121                                            separator_char,
1122                                            (int)regex_sed.size(),
1123                                            regex_sed.data());
1124             return error;
1125         }
1126 
1127         if (check_only == false)
1128         {
1129             std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
1130             std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
1131             m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
1132                                              subst.c_str());
1133         }
1134         return error;
1135     }
1136 
1137     void
1138     AddRegexCommandToInterpreter()
1139     {
1140         if (m_regex_cmd_ap.get())
1141         {
1142             if (m_regex_cmd_ap->HasRegexEntries())
1143             {
1144                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1145                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1146             }
1147         }
1148     }
1149 
1150 private:
1151     std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1152 
1153      class CommandOptions : public Options
1154      {
1155      public:
1156 
1157          CommandOptions (CommandInterpreter &interpreter) :
1158             Options (interpreter)
1159          {
1160          }
1161 
1162          virtual
1163          ~CommandOptions (){}
1164 
1165          virtual Error
1166          SetOptionValue (uint32_t option_idx, const char *option_arg)
1167          {
1168              Error error;
1169              const int short_option = m_getopt_table[option_idx].val;
1170 
1171              switch (short_option)
1172              {
1173                  case 'h':
1174                      m_help.assign (option_arg);
1175                      break;
1176                  case 's':
1177                      m_syntax.assign (option_arg);
1178                      break;
1179 
1180                  default:
1181                      error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1182                      break;
1183              }
1184 
1185              return error;
1186          }
1187 
1188          void
1189          OptionParsingStarting ()
1190          {
1191              m_help.clear();
1192              m_syntax.clear();
1193          }
1194 
1195          const OptionDefinition*
1196          GetDefinitions ()
1197          {
1198              return g_option_table;
1199          }
1200 
1201          // Options table: Required for subclasses of Options.
1202 
1203          static OptionDefinition g_option_table[];
1204 
1205          const char *
1206          GetHelp ()
1207          {
1208              if (m_help.empty())
1209                  return NULL;
1210              return m_help.c_str();
1211          }
1212          const char *
1213          GetSyntax ()
1214          {
1215              if (m_syntax.empty())
1216                  return NULL;
1217              return m_syntax.c_str();
1218          }
1219          // Instance variables to hold the values for command options.
1220      protected:
1221          std::string m_help;
1222          std::string m_syntax;
1223      };
1224 
1225      Options *
1226      GetOptions () override
1227      {
1228          return &m_options;
1229      }
1230 
1231      CommandOptions m_options;
1232 };
1233 
1234 OptionDefinition
1235 CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1236 {
1237 { LLDB_OPT_SET_1, false, "help"  , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "The help text to display for this command."},
1238 { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
1239 { 0             , false,  NULL   , 0  , 0                , NULL, NULL, 0, eArgTypeNone, NULL }
1240 };
1241 
1242 
1243 class CommandObjectPythonFunction : public CommandObjectRaw
1244 {
1245 private:
1246     std::string m_function_name;
1247     ScriptedCommandSynchronicity m_synchro;
1248     bool m_fetched_help_long;
1249 
1250 public:
1251 
1252     CommandObjectPythonFunction (CommandInterpreter &interpreter,
1253                                  std::string name,
1254                                  std::string funct,
1255                                  std::string help,
1256                                  ScriptedCommandSynchronicity synch) :
1257         CommandObjectRaw (interpreter,
1258                           name.c_str(),
1259                           NULL,
1260                           NULL),
1261         m_function_name(funct),
1262         m_synchro(synch),
1263         m_fetched_help_long(false)
1264     {
1265         if (!help.empty())
1266             SetHelp(help.c_str());
1267         else
1268         {
1269             StreamString stream;
1270             stream.Printf("For more information run 'help %s'",name.c_str());
1271             SetHelp(stream.GetData());
1272         }
1273     }
1274 
1275     virtual
1276     ~CommandObjectPythonFunction ()
1277     {
1278     }
1279 
1280     virtual bool
1281     IsRemovable () const
1282     {
1283         return true;
1284     }
1285 
1286     const std::string&
1287     GetFunctionName ()
1288     {
1289         return m_function_name;
1290     }
1291 
1292     ScriptedCommandSynchronicity
1293     GetSynchronicity ()
1294     {
1295         return m_synchro;
1296     }
1297 
1298     virtual const char *
1299     GetHelpLong ()
1300     {
1301         if (!m_fetched_help_long)
1302         {
1303             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1304             if (scripter)
1305             {
1306                 std::string docstring;
1307                 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1308                 if (!docstring.empty())
1309                     SetHelpLong(docstring);
1310             }
1311         }
1312         return CommandObjectRaw::GetHelpLong();
1313     }
1314 
1315 protected:
1316     virtual bool
1317     DoExecute (const char *raw_command_line, CommandReturnObject &result)
1318     {
1319         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1320 
1321         Error error;
1322 
1323         result.SetStatus(eReturnStatusInvalid);
1324 
1325         if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1326                                                          raw_command_line,
1327                                                          m_synchro,
1328                                                          result,
1329                                                          error,
1330                                                          m_exe_ctx) == false)
1331         {
1332             result.AppendError(error.AsCString());
1333             result.SetStatus(eReturnStatusFailed);
1334         }
1335         else
1336         {
1337             // Don't change the status if the command already set it...
1338             if (result.GetStatus() == eReturnStatusInvalid)
1339             {
1340                 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
1341                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1342                 else
1343                     result.SetStatus(eReturnStatusSuccessFinishResult);
1344             }
1345         }
1346 
1347         return result.Succeeded();
1348     }
1349 
1350 };
1351 
1352 //-------------------------------------------------------------------------
1353 // CommandObjectCommandsScriptImport
1354 //-------------------------------------------------------------------------
1355 
1356 class CommandObjectCommandsScriptImport : public CommandObjectParsed
1357 {
1358 public:
1359     CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
1360         CommandObjectParsed (interpreter,
1361                              "command script import",
1362                              "Import a scripting module in LLDB.",
1363                              NULL),
1364         m_options(interpreter)
1365     {
1366         CommandArgumentEntry arg1;
1367         CommandArgumentData cmd_arg;
1368 
1369         // Define the first (and only) variant of this arg.
1370         cmd_arg.arg_type = eArgTypeFilename;
1371         cmd_arg.arg_repetition = eArgRepeatPlain;
1372 
1373         // There is only one variant this argument could be; put it into the argument entry.
1374         arg1.push_back (cmd_arg);
1375 
1376         // Push the data for the first argument into the m_arguments vector.
1377         m_arguments.push_back (arg1);
1378     }
1379 
1380     ~CommandObjectCommandsScriptImport ()
1381     {
1382     }
1383 
1384     virtual int
1385     HandleArgumentCompletion (Args &input,
1386                               int &cursor_index,
1387                               int &cursor_char_position,
1388                               OptionElementVector &opt_element_vector,
1389                               int match_start_point,
1390                               int max_return_elements,
1391                               bool &word_complete,
1392                               StringList &matches)
1393     {
1394         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1395         completion_str.erase (cursor_char_position);
1396 
1397         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1398                                                              CommandCompletions::eDiskFileCompletion,
1399                                                              completion_str.c_str(),
1400                                                              match_start_point,
1401                                                              max_return_elements,
1402                                                              NULL,
1403                                                              word_complete,
1404                                                              matches);
1405         return matches.GetSize();
1406     }
1407 
1408     virtual Options *
1409     GetOptions ()
1410     {
1411         return &m_options;
1412     }
1413 
1414 protected:
1415 
1416     class CommandOptions : public Options
1417     {
1418     public:
1419 
1420         CommandOptions (CommandInterpreter &interpreter) :
1421             Options (interpreter)
1422         {
1423         }
1424 
1425         virtual
1426         ~CommandOptions (){}
1427 
1428         virtual Error
1429         SetOptionValue (uint32_t option_idx, const char *option_arg)
1430         {
1431             Error error;
1432             const int short_option = m_getopt_table[option_idx].val;
1433 
1434             switch (short_option)
1435             {
1436                 case 'r':
1437                     m_allow_reload = true;
1438                     break;
1439                 default:
1440                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1441                     break;
1442             }
1443 
1444             return error;
1445         }
1446 
1447         void
1448         OptionParsingStarting ()
1449         {
1450             m_allow_reload = true;
1451         }
1452 
1453         const OptionDefinition*
1454         GetDefinitions ()
1455         {
1456             return g_option_table;
1457         }
1458 
1459         // Options table: Required for subclasses of Options.
1460 
1461         static OptionDefinition g_option_table[];
1462 
1463         // Instance variables to hold the values for command options.
1464 
1465         bool m_allow_reload;
1466     };
1467 
1468     bool
1469     DoExecute (Args& command, CommandReturnObject &result)
1470     {
1471 
1472         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1473         {
1474             result.AppendError ("only scripting language supported for module importing is currently Python");
1475             result.SetStatus (eReturnStatusFailed);
1476             return false;
1477         }
1478 
1479         size_t argc = command.GetArgumentCount();
1480 
1481         if (argc != 1)
1482         {
1483             result.AppendError ("'command script import' requires one argument");
1484             result.SetStatus (eReturnStatusFailed);
1485             return false;
1486         }
1487 
1488         std::string path = command.GetArgumentAtIndex(0);
1489         Error error;
1490 
1491         const bool init_session = true;
1492         // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1493         // commands won't ever be recursively invoked, but it's actually possible to craft
1494         // a Python script that does other "command script imports" in __lldb_init_module
1495         // the real fix is to have recursive commands possible with a CommandInvocation object
1496         // separate from the CommandObject itself, so that recursive command invocations
1497         // won't stomp on each other (wrt to execution contents, options, and more)
1498         m_exe_ctx.Clear();
1499         if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
1500                                                                       m_options.m_allow_reload,
1501                                                                       init_session,
1502                                                                       error))
1503         {
1504             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1505         }
1506         else
1507         {
1508             result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1509             result.SetStatus (eReturnStatusFailed);
1510         }
1511 
1512         return result.Succeeded();
1513     }
1514 
1515     CommandOptions m_options;
1516 };
1517 
1518 OptionDefinition
1519 CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
1520 {
1521     { 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."},
1522     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1523 };
1524 
1525 
1526 //-------------------------------------------------------------------------
1527 // CommandObjectCommandsScriptAdd
1528 //-------------------------------------------------------------------------
1529 
1530 class CommandObjectCommandsScriptAdd :
1531     public CommandObjectParsed,
1532     public IOHandlerDelegateMultiline
1533 {
1534 public:
1535     CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1536         CommandObjectParsed (interpreter,
1537                              "command script add",
1538                              "Add a scripted function as an LLDB command.",
1539                              NULL),
1540         IOHandlerDelegateMultiline ("DONE"),
1541         m_options (interpreter)
1542     {
1543         CommandArgumentEntry arg1;
1544         CommandArgumentData cmd_arg;
1545 
1546         // Define the first (and only) variant of this arg.
1547         cmd_arg.arg_type = eArgTypeCommandName;
1548         cmd_arg.arg_repetition = eArgRepeatPlain;
1549 
1550         // There is only one variant this argument could be; put it into the argument entry.
1551         arg1.push_back (cmd_arg);
1552 
1553         // Push the data for the first argument into the m_arguments vector.
1554         m_arguments.push_back (arg1);
1555     }
1556 
1557     ~CommandObjectCommandsScriptAdd ()
1558     {
1559     }
1560 
1561     virtual Options *
1562     GetOptions ()
1563     {
1564         return &m_options;
1565     }
1566 
1567 protected:
1568 
1569     class CommandOptions : public Options
1570     {
1571     public:
1572 
1573         CommandOptions (CommandInterpreter &interpreter) :
1574             Options (interpreter)
1575         {
1576         }
1577 
1578         virtual
1579         ~CommandOptions (){}
1580 
1581         virtual Error
1582         SetOptionValue (uint32_t option_idx, const char *option_arg)
1583         {
1584             Error error;
1585             const int short_option = m_getopt_table[option_idx].val;
1586 
1587             switch (short_option)
1588             {
1589                 case 'f':
1590                     if (option_arg)
1591                         m_funct_name.assign(option_arg);
1592                     break;
1593                 case 'h':
1594                     if (option_arg)
1595                         m_short_help.assign(option_arg);
1596                     break;
1597                 case 's':
1598                     m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
1599                     if (!error.Success())
1600                         error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
1601                     break;
1602                 default:
1603                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1604                     break;
1605             }
1606 
1607             return error;
1608         }
1609 
1610         void
1611         OptionParsingStarting ()
1612         {
1613             m_funct_name.clear();
1614             m_short_help.clear();
1615             m_synchronicity = eScriptedCommandSynchronicitySynchronous;
1616         }
1617 
1618         const OptionDefinition*
1619         GetDefinitions ()
1620         {
1621             return g_option_table;
1622         }
1623 
1624         // Options table: Required for subclasses of Options.
1625 
1626         static OptionDefinition g_option_table[];
1627 
1628         // Instance variables to hold the values for command options.
1629 
1630         std::string m_funct_name;
1631         std::string m_short_help;
1632         ScriptedCommandSynchronicity m_synchronicity;
1633     };
1634 
1635     virtual void
1636     IOHandlerActivated (IOHandler &io_handler)
1637     {
1638         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
1639         if (output_sp)
1640         {
1641             output_sp->PutCString(g_python_command_instructions);
1642             output_sp->Flush();
1643         }
1644     }
1645 
1646 
1647     virtual void
1648     IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
1649     {
1650         StreamFileSP error_sp = io_handler.GetErrorStreamFile();
1651 
1652         ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
1653         if (interpreter)
1654         {
1655 
1656             StringList lines;
1657             lines.SplitIntoLines(data);
1658             if (lines.GetSize() > 0)
1659             {
1660                 std::string funct_name_str;
1661                 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
1662                 {
1663                     if (funct_name_str.empty())
1664                     {
1665                         error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
1666                         error_sp->Flush();
1667                     }
1668                     else
1669                     {
1670                         // everything should be fine now, let's add this alias
1671 
1672                         CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
1673                                                                                         m_cmd_name,
1674                                                                                         funct_name_str.c_str(),
1675                                                                                         m_short_help,
1676                                                                                         m_synchronicity));
1677 
1678                         if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1679                         {
1680                             error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
1681                             error_sp->Flush();
1682                         }
1683                     }
1684                 }
1685                 else
1686                 {
1687                     error_sp->Printf ("error: unable to create function, didn't add python command.\n");
1688                     error_sp->Flush();
1689                 }
1690             }
1691             else
1692             {
1693                 error_sp->Printf ("error: empty function, didn't add python command.\n");
1694                 error_sp->Flush();
1695             }
1696         }
1697         else
1698         {
1699             error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
1700             error_sp->Flush();
1701         }
1702 
1703         io_handler.SetIsDone(true);
1704 
1705 
1706     }
1707 
1708 protected:
1709     bool
1710     DoExecute (Args& command, CommandReturnObject &result)
1711     {
1712 
1713         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1714         {
1715             result.AppendError ("only scripting language supported for scripted commands is currently Python");
1716             result.SetStatus (eReturnStatusFailed);
1717             return false;
1718         }
1719 
1720         size_t argc = command.GetArgumentCount();
1721 
1722         if (argc != 1)
1723         {
1724             result.AppendError ("'command script add' requires one argument");
1725             result.SetStatus (eReturnStatusFailed);
1726             return false;
1727         }
1728 
1729         // Store the options in case we get multi-line input
1730         m_cmd_name = command.GetArgumentAtIndex(0);
1731         m_short_help.assign(m_options.m_short_help);
1732         m_synchronicity = m_options.m_synchronicity;
1733 
1734         if (m_options.m_funct_name.empty())
1735         {
1736             m_interpreter.GetPythonCommandsFromIOHandler ("     ",  // Prompt
1737                                                           *this,    // IOHandlerDelegate
1738                                                           true,     // Run IOHandler in async mode
1739                                                           NULL);    // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
1740         }
1741         else
1742         {
1743             CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
1744                                                                     m_cmd_name,
1745                                                                     m_options.m_funct_name,
1746                                                                     m_options.m_short_help,
1747                                                                     m_synchronicity));
1748             if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
1749             {
1750                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1751             }
1752             else
1753             {
1754                 result.AppendError("cannot add command");
1755                 result.SetStatus (eReturnStatusFailed);
1756             }
1757         }
1758 
1759         return result.Succeeded();
1760 
1761     }
1762 
1763     CommandOptions m_options;
1764     std::string m_cmd_name;
1765     std::string m_short_help;
1766     ScriptedCommandSynchronicity m_synchronicity;
1767 };
1768 
1769 static OptionEnumValueElement g_script_synchro_type[] =
1770 {
1771     { eScriptedCommandSynchronicitySynchronous,      "synchronous",       "Run synchronous"},
1772     { eScriptedCommandSynchronicityAsynchronous,     "asynchronous",      "Run asynchronous"},
1773     { eScriptedCommandSynchronicityCurrentValue,     "current",           "Do not alter current setting"},
1774     { 0, NULL, NULL }
1775 };
1776 
1777 OptionDefinition
1778 CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1779 {
1780     { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction,        "Name of the Python function to bind to this command name."},
1781     { LLDB_OPT_SET_1, false, "help"  , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeHelpText, "The help text to display for this command."},
1782     { 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."},
1783     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1784 };
1785 
1786 //-------------------------------------------------------------------------
1787 // CommandObjectCommandsScriptList
1788 //-------------------------------------------------------------------------
1789 
1790 class CommandObjectCommandsScriptList : public CommandObjectParsed
1791 {
1792 private:
1793 
1794 public:
1795     CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
1796     CommandObjectParsed (interpreter,
1797                    "command script list",
1798                    "List defined scripted commands.",
1799                    NULL)
1800     {
1801     }
1802 
1803     ~CommandObjectCommandsScriptList ()
1804     {
1805     }
1806 
1807     bool
1808     DoExecute (Args& command, CommandReturnObject &result)
1809     {
1810 
1811         m_interpreter.GetHelp(result,
1812                               CommandInterpreter::eCommandTypesUserDef);
1813 
1814         result.SetStatus (eReturnStatusSuccessFinishResult);
1815 
1816         return true;
1817 
1818 
1819     }
1820 };
1821 
1822 //-------------------------------------------------------------------------
1823 // CommandObjectCommandsScriptClear
1824 //-------------------------------------------------------------------------
1825 
1826 class CommandObjectCommandsScriptClear : public CommandObjectParsed
1827 {
1828 private:
1829 
1830 public:
1831     CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
1832         CommandObjectParsed (interpreter,
1833                              "command script clear",
1834                              "Delete all scripted commands.",
1835                              NULL)
1836     {
1837     }
1838 
1839     ~CommandObjectCommandsScriptClear ()
1840     {
1841     }
1842 
1843 protected:
1844     bool
1845     DoExecute (Args& command, CommandReturnObject &result)
1846     {
1847 
1848         m_interpreter.RemoveAllUser();
1849 
1850         result.SetStatus (eReturnStatusSuccessFinishResult);
1851 
1852         return true;
1853     }
1854 };
1855 
1856 //-------------------------------------------------------------------------
1857 // CommandObjectCommandsScriptDelete
1858 //-------------------------------------------------------------------------
1859 
1860 class CommandObjectCommandsScriptDelete : public CommandObjectParsed
1861 {
1862 public:
1863     CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
1864         CommandObjectParsed (interpreter,
1865                              "command script delete",
1866                              "Delete a scripted command.",
1867                              NULL)
1868     {
1869         CommandArgumentEntry arg1;
1870         CommandArgumentData cmd_arg;
1871 
1872         // Define the first (and only) variant of this arg.
1873         cmd_arg.arg_type = eArgTypeCommandName;
1874         cmd_arg.arg_repetition = eArgRepeatPlain;
1875 
1876         // There is only one variant this argument could be; put it into the argument entry.
1877         arg1.push_back (cmd_arg);
1878 
1879         // Push the data for the first argument into the m_arguments vector.
1880         m_arguments.push_back (arg1);
1881     }
1882 
1883     ~CommandObjectCommandsScriptDelete ()
1884     {
1885     }
1886 
1887 protected:
1888     bool
1889     DoExecute (Args& command, CommandReturnObject &result)
1890     {
1891 
1892         size_t argc = command.GetArgumentCount();
1893 
1894         if (argc != 1)
1895         {
1896             result.AppendError ("'command script delete' requires one argument");
1897             result.SetStatus (eReturnStatusFailed);
1898             return false;
1899         }
1900 
1901         const char* cmd_name = command.GetArgumentAtIndex(0);
1902 
1903         if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
1904         {
1905             m_interpreter.RemoveUser(cmd_name);
1906             result.SetStatus (eReturnStatusSuccessFinishResult);
1907         }
1908         else
1909         {
1910             result.AppendErrorWithFormat ("command %s not found", cmd_name);
1911             result.SetStatus (eReturnStatusFailed);
1912         }
1913 
1914         return result.Succeeded();
1915 
1916     }
1917 };
1918 
1919 #pragma mark CommandObjectMultiwordCommandsScript
1920 
1921 //-------------------------------------------------------------------------
1922 // CommandObjectMultiwordCommandsScript
1923 //-------------------------------------------------------------------------
1924 
1925 class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
1926 {
1927 public:
1928     CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
1929     CommandObjectMultiword (interpreter,
1930                             "command script",
1931                             "A set of commands for managing or customizing script commands.",
1932                             "command script <subcommand> [<subcommand-options>]")
1933     {
1934         LoadSubCommand ("add",  CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
1935         LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
1936         LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
1937         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
1938         LoadSubCommand ("import",   CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
1939     }
1940 
1941     ~CommandObjectMultiwordCommandsScript ()
1942     {
1943     }
1944 
1945 };
1946 
1947 
1948 #pragma mark CommandObjectMultiwordCommands
1949 
1950 //-------------------------------------------------------------------------
1951 // CommandObjectMultiwordCommands
1952 //-------------------------------------------------------------------------
1953 
1954 CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
1955     CommandObjectMultiword (interpreter,
1956                             "command",
1957                             "A set of commands for managing or customizing the debugger commands.",
1958                             "command <subcommand> [<subcommand-options>]")
1959 {
1960     LoadSubCommand ("source",  CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
1961     LoadSubCommand ("alias",   CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
1962     LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
1963     LoadSubCommand ("regex",   CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
1964     LoadSubCommand ("history",   CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
1965     LoadSubCommand ("script",   CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
1966 }
1967 
1968 CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
1969 {
1970 }
1971 
1972