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