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