Home | History | Annotate | Download | only in Commands
      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 
     35 using namespace lldb;
     36 using namespace lldb_private;
     37 
     38 //-------------------------------------------------------------------------
     39 // CommandObjectCommandsSource
     40 //-------------------------------------------------------------------------
     41 
     42 class CommandObjectCommandsHistory : public CommandObjectParsed
     43 {
     44 public:
     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 
     62 protected:
     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 
    227 OptionDefinition
    228 CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
    229 {
    230 { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeUnsignedInteger,        "How many history commands to print."},
    231 { LLDB_OPT_SET_1, false, "start-index", 's', required_argument, 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', required_argument, NULL, 0, eArgTypeUnsignedInteger,    "Index at which to stop printing history commands."},
    233 { LLDB_OPT_SET_2, false, "clear", 'C', no_argument, 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 
    242 class CommandObjectCommandsSource : public CommandObjectParsed
    243 {
    244 public:
    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 
    304 protected:
    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 
    410 OptionDefinition
    411 CommandObjectCommandsSource::CommandOptions::g_option_table[] =
    412 {
    413 { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean,    "If true, stop executing commands on error."},
    414 { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
    415 { LLDB_OPT_SET_ALL, false, "silent-run", 's', required_argument, 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 
    424 static 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 
    429 class CommandObjectCommandsAlias : public CommandObjectRaw
    430 {
    431 
    432 
    433 public:
    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 
    534 protected:
    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 
    774 class CommandObjectCommandsUnalias : public CommandObjectParsed
    775 {
    776 public:
    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 
    801 protected:
    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 
    859 class CommandObjectCommandsAddRegex : public CommandObjectParsed
    860 {
    861 public:
    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 
    901 protected:
    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 
   1159 private:
   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 
   1243 OptionDefinition
   1244 CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
   1245 {
   1246 { LLDB_OPT_SET_1, false, "help"  , 'h', required_argument, NULL, 0, eArgTypeNone, "The help text to display for this command."},
   1247 { LLDB_OPT_SET_1, false, "syntax", 's', required_argument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
   1248 { 0             , false,  NULL   , 0  , 0                , NULL, 0, eArgTypeNone, NULL }
   1249 };
   1250 
   1251 
   1252 class CommandObjectPythonFunction : public CommandObjectRaw
   1253 {
   1254 private:
   1255     std::string m_function_name;
   1256     ScriptedCommandSynchronicity m_synchro;
   1257     bool m_fetched_help_long;
   1258 
   1259 public:
   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 
   1315 protected:
   1316     virtual bool
   1317     DoExecute (const char *raw_command_line, CommandReturnObject &result)
   1318     {
   1319         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
   1320 
   1321         Error error;
   1322 
   1323         result.SetStatus(eReturnStatusInvalid);
   1324 
   1325         if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
   1326                                                          raw_command_line,
   1327                                                          m_synchro,
   1328                                                          result,
   1329                                                          error) == 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 
   1355 class CommandObjectCommandsScriptImport : public CommandObjectParsed
   1356 {
   1357 public:
   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 
   1413 protected:
   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 
   1517 OptionDefinition
   1518 CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
   1519 {
   1520     { LLDB_OPT_SET_1, false, "allow-reload", 'r', no_argument, 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 
   1529 class CommandObjectCommandsScriptAdd : public CommandObjectParsed
   1530 {
   1531 public:
   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 
   1563 protected:
   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 
   1624 private:
   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 
   1743 protected:
   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 
   1820 static 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 
   1828 OptionDefinition
   1829 CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
   1830 {
   1831     { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypePythonFunction,        "Name of the Python function to bind to this command name."},
   1832     { LLDB_OPT_SET_1, false, "synchronicity", 's', required_argument, 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 
   1840 class CommandObjectCommandsScriptList : public CommandObjectParsed
   1841 {
   1842 private:
   1843 
   1844 public:
   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 
   1876 class CommandObjectCommandsScriptClear : public CommandObjectParsed
   1877 {
   1878 private:
   1879 
   1880 public:
   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 
   1893 protected:
   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 
   1910 class CommandObjectCommandsScriptDelete : public CommandObjectParsed
   1911 {
   1912 public:
   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 
   1937 protected:
   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 
   1975 class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
   1976 {
   1977 public:
   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 
   2004 CommandObjectMultiwordCommands::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 
   2018 CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
   2019 {
   2020 }
   2021 
   2022