Home | History | Annotate | Download | only in Commands
      1 //===-- CommandObjectSettings.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 "CommandObjectSettings.h"
     13 
     14 // C Includes
     15 // C++ Includes
     16 // Other libraries and framework includes
     17 // Project includes
     18 #include "lldb/Interpreter/CommandInterpreter.h"
     19 #include "lldb/Interpreter/CommandReturnObject.h"
     20 #include "lldb/Interpreter/CommandCompletions.h"
     21 
     22 using namespace lldb;
     23 using namespace lldb_private;
     24 #include "llvm/ADT/StringRef.h"
     25 
     26 //-------------------------------------------------------------------------
     27 // CommandObjectSettingsSet
     28 //-------------------------------------------------------------------------
     29 
     30 class CommandObjectSettingsSet : public CommandObjectRaw
     31 {
     32 public:
     33     CommandObjectSettingsSet (CommandInterpreter &interpreter) :
     34         CommandObjectRaw (interpreter,
     35                           "settings set",
     36                           "Set or change the value of a single debugger setting variable.",
     37                           NULL),
     38         m_options (interpreter)
     39     {
     40         CommandArgumentEntry arg1;
     41         CommandArgumentEntry arg2;
     42         CommandArgumentData var_name_arg;
     43         CommandArgumentData value_arg;
     44 
     45         // Define the first (and only) variant of this arg.
     46         var_name_arg.arg_type = eArgTypeSettingVariableName;
     47         var_name_arg.arg_repetition = eArgRepeatPlain;
     48 
     49         // There is only one variant this argument could be; put it into the argument entry.
     50         arg1.push_back (var_name_arg);
     51 
     52         // Define the first (and only) variant of this arg.
     53         value_arg.arg_type = eArgTypeValue;
     54         value_arg.arg_repetition = eArgRepeatPlain;
     55 
     56         // There is only one variant this argument could be; put it into the argument entry.
     57         arg2.push_back (value_arg);
     58 
     59         // Push the data for the first argument into the m_arguments vector.
     60         m_arguments.push_back (arg1);
     61         m_arguments.push_back (arg2);
     62 
     63         SetHelpLong (
     64 "When setting a dictionary or array variable, you can set multiple entries \n\
     65 at once by giving the values to the set command.  For example: \n\
     66 \n\
     67 (lldb) settings set target.run-args value1 value2 value3 \n\
     68 (lldb) settings set target.env-vars MYPATH=~/.:/usr/bin  SOME_ENV_VAR=12345 \n\
     69 \n\
     70 (lldb) settings show target.run-args \n\
     71   [0]: 'value1' \n\
     72   [1]: 'value2' \n\
     73   [3]: 'value3' \n\
     74 (lldb) settings show target.env-vars \n\
     75   'MYPATH=~/.:/usr/bin'\n\
     76   'SOME_ENV_VAR=12345' \n\
     77 \n\
     78 Warning:  The 'set' command re-sets the entire array or dictionary.  If you \n\
     79 just want to add, remove or update individual values (or add something to \n\
     80 the end), use one of the other settings sub-commands: append, replace, \n\
     81 insert-before or insert-after.\n");
     82 
     83     }
     84 
     85 
     86     virtual
     87     ~CommandObjectSettingsSet () {}
     88 
     89     // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
     90     virtual bool
     91     WantsCompletion() { return true; }
     92 
     93     virtual Options *
     94     GetOptions ()
     95     {
     96         return &m_options;
     97     }
     98 
     99     class CommandOptions : public Options
    100     {
    101     public:
    102 
    103         CommandOptions (CommandInterpreter &interpreter) :
    104             Options (interpreter),
    105             m_global (false)
    106         {
    107         }
    108 
    109         virtual
    110         ~CommandOptions () {}
    111 
    112         virtual Error
    113         SetOptionValue (uint32_t option_idx, const char *option_arg)
    114         {
    115             Error error;
    116             const int short_option = m_getopt_table[option_idx].val;
    117 
    118             switch (short_option)
    119             {
    120                 case 'g':
    121                     m_global = true;
    122                     break;
    123                 default:
    124                     error.SetErrorStringWithFormat ("unrecognized options '%c'", short_option);
    125                     break;
    126             }
    127 
    128             return error;
    129         }
    130 
    131         void
    132         OptionParsingStarting ()
    133         {
    134             m_global = false;
    135         }
    136 
    137         const OptionDefinition*
    138         GetDefinitions ()
    139         {
    140             return g_option_table;
    141         }
    142 
    143         // Options table: Required for subclasses of Options.
    144 
    145         static OptionDefinition g_option_table[];
    146 
    147         // Instance variables to hold the values for command options.
    148 
    149         bool m_global;
    150     };
    151 
    152     virtual int
    153     HandleArgumentCompletion (Args &input,
    154                               int &cursor_index,
    155                               int &cursor_char_position,
    156                               OptionElementVector &opt_element_vector,
    157                               int match_start_point,
    158                               int max_return_elements,
    159                               bool &word_complete,
    160                               StringList &matches)
    161     {
    162         std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
    163 
    164         const size_t argc = input.GetArgumentCount();
    165         const char *arg = NULL;
    166         int setting_var_idx;
    167         for (setting_var_idx = 1; setting_var_idx < argc; ++setting_var_idx)
    168         {
    169             arg = input.GetArgumentAtIndex(setting_var_idx);
    170             if (arg && arg[0] != '-')
    171                 break; // We found our setting variable name index
    172         }
    173         if (cursor_index == setting_var_idx)
    174         {
    175             // Attempting to complete setting variable name
    176             CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
    177                                                                  CommandCompletions::eSettingsNameCompletion,
    178                                                                  completion_str.c_str(),
    179                                                                  match_start_point,
    180                                                                  max_return_elements,
    181                                                                  NULL,
    182                                                                  word_complete,
    183                                                                  matches);
    184         }
    185         else
    186         {
    187             arg = input.GetArgumentAtIndex(cursor_index);
    188 
    189             if (arg)
    190             {
    191                 if (arg[0] == '-')
    192                 {
    193                     // Complete option name
    194                 }
    195                 else
    196                 {
    197                     // Complete setting value
    198                     const char *setting_var_name = input.GetArgumentAtIndex(setting_var_idx);
    199                     Error error;
    200                     lldb::OptionValueSP value_sp (m_interpreter.GetDebugger().GetPropertyValue(&m_exe_ctx, setting_var_name, false, error));
    201                     if (value_sp)
    202                     {
    203                         value_sp->AutoComplete (m_interpreter,
    204                                                 completion_str.c_str(),
    205                                                 match_start_point,
    206                                                 max_return_elements,
    207                                                 word_complete,
    208                                                 matches);
    209                     }
    210                 }
    211             }
    212         }
    213         return matches.GetSize();
    214     }
    215 
    216 protected:
    217     virtual bool
    218     DoExecute (const char *command, CommandReturnObject &result)
    219     {
    220         Args cmd_args(command);
    221 
    222         // Process possible options.
    223         if (!ParseOptions (cmd_args, result))
    224             return false;
    225 
    226         const size_t argc = cmd_args.GetArgumentCount ();
    227         if ((argc < 2) && (!m_options.m_global))
    228         {
    229             result.AppendError ("'settings set' takes more arguments");
    230             result.SetStatus (eReturnStatusFailed);
    231             return false;
    232         }
    233 
    234         const char *var_name = cmd_args.GetArgumentAtIndex (0);
    235         if ((var_name == NULL) || (var_name[0] == '\0'))
    236         {
    237             result.AppendError ("'settings set' command requires a valid variable name");
    238             result.SetStatus (eReturnStatusFailed);
    239             return false;
    240         }
    241 
    242         // Split the raw command into var_name and value pair.
    243         llvm::StringRef raw_str(command);
    244         std::string var_value_string = raw_str.split(var_name).second.str();
    245         const char *var_value_cstr = Args::StripSpaces(var_value_string, true, true, false);
    246 
    247         Error error;
    248         if (m_options.m_global)
    249         {
    250             error = m_interpreter.GetDebugger().SetPropertyValue (NULL,
    251                                                                   eVarSetOperationAssign,
    252                                                                   var_name,
    253                                                                   var_value_cstr);
    254         }
    255 
    256         if (error.Success())
    257         {
    258             // FIXME this is the same issue as the one in commands script import
    259             // we could be setting target.load-script-from-symbol-file which would cause
    260             // Python scripts to be loaded, which could run LLDB commands
    261             // (e.g. settings set target.process.python-os-plugin-path) and cause a crash
    262             // if we did not clear the command's exe_ctx first
    263             ExecutionContext exe_ctx(m_exe_ctx);
    264             m_exe_ctx.Clear();
    265             error = m_interpreter.GetDebugger().SetPropertyValue (&exe_ctx,
    266                                                                   eVarSetOperationAssign,
    267                                                                   var_name,
    268                                                                   var_value_cstr);
    269         }
    270 
    271         if (error.Fail())
    272         {
    273             result.AppendError (error.AsCString());
    274             result.SetStatus (eReturnStatusFailed);
    275             return false;
    276         }
    277         else
    278         {
    279             result.SetStatus (eReturnStatusSuccessFinishResult);
    280         }
    281 
    282         return result.Succeeded();
    283     }
    284 private:
    285     CommandOptions m_options;
    286 };
    287 
    288 OptionDefinition
    289 CommandObjectSettingsSet::CommandOptions::g_option_table[] =
    290 {
    291     { LLDB_OPT_SET_2, false, "global", 'g', no_argument,   NULL, 0, eArgTypeNone, "Apply the new value to the global default value." },
    292     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
    293 };
    294 
    295 
    296 //-------------------------------------------------------------------------
    297 // CommandObjectSettingsShow -- Show current values
    298 //-------------------------------------------------------------------------
    299 
    300 class CommandObjectSettingsShow : public CommandObjectParsed
    301 {
    302 public:
    303     CommandObjectSettingsShow (CommandInterpreter &interpreter) :
    304         CommandObjectParsed (interpreter,
    305                              "settings show",
    306                              "Show the specified internal debugger setting variable and its value, or show all the currently set variables and their values, if nothing is specified.",
    307                              NULL)
    308     {
    309         CommandArgumentEntry arg1;
    310         CommandArgumentData var_name_arg;
    311 
    312         // Define the first (and only) variant of this arg.
    313         var_name_arg.arg_type = eArgTypeSettingVariableName;
    314         var_name_arg.arg_repetition = eArgRepeatOptional;
    315 
    316         // There is only one variant this argument could be; put it into the argument entry.
    317         arg1.push_back (var_name_arg);
    318 
    319         // Push the data for the first argument into the m_arguments vector.
    320         m_arguments.push_back (arg1);
    321     }
    322 
    323     virtual
    324     ~CommandObjectSettingsShow () {}
    325 
    326 
    327     virtual int
    328     HandleArgumentCompletion (Args &input,
    329                               int &cursor_index,
    330                               int &cursor_char_position,
    331                               OptionElementVector &opt_element_vector,
    332                               int match_start_point,
    333                               int max_return_elements,
    334                               bool &word_complete,
    335                               StringList &matches)
    336     {
    337         std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
    338 
    339         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
    340                                                              CommandCompletions::eSettingsNameCompletion,
    341                                                              completion_str.c_str(),
    342                                                              match_start_point,
    343                                                              max_return_elements,
    344                                                              NULL,
    345                                                              word_complete,
    346                                                              matches);
    347         return matches.GetSize();
    348     }
    349 
    350 protected:
    351     virtual bool
    352     DoExecute (Args& args, CommandReturnObject &result)
    353     {
    354         result.SetStatus (eReturnStatusSuccessFinishResult);
    355 
    356         const size_t argc = args.GetArgumentCount ();
    357         if (argc > 0)
    358         {
    359             for (size_t i=0; i<argc; ++i)
    360             {
    361                 const char *property_path = args.GetArgumentAtIndex (i);
    362 
    363                 Error error(m_interpreter.GetDebugger().DumpPropertyValue (&m_exe_ctx, result.GetOutputStream(), property_path, OptionValue::eDumpGroupValue));
    364                 if (error.Success())
    365                 {
    366                     result.GetOutputStream().EOL();
    367                 }
    368                 else
    369                 {
    370                     result.AppendError (error.AsCString());
    371                     result.SetStatus (eReturnStatusFailed);
    372                 }
    373             }
    374         }
    375         else
    376         {
    377             m_interpreter.GetDebugger().DumpAllPropertyValues (&m_exe_ctx, result.GetOutputStream(), OptionValue::eDumpGroupValue);
    378         }
    379 
    380         return result.Succeeded();
    381     }
    382 };
    383 
    384 //-------------------------------------------------------------------------
    385 // CommandObjectSettingsList -- List settable variables
    386 //-------------------------------------------------------------------------
    387 
    388 class CommandObjectSettingsList : public CommandObjectParsed
    389 {
    390 public:
    391     CommandObjectSettingsList (CommandInterpreter &interpreter) :
    392         CommandObjectParsed (interpreter,
    393                              "settings list",
    394                              "List and describe all the internal debugger settings variables that are available to the user to 'set' or 'show', or describe a particular variable or set of variables (by specifying the variable name or a common prefix).",
    395                              NULL)
    396     {
    397         CommandArgumentEntry arg;
    398         CommandArgumentData var_name_arg;
    399         CommandArgumentData prefix_name_arg;
    400 
    401         // Define the first variant of this arg.
    402         var_name_arg.arg_type = eArgTypeSettingVariableName;
    403         var_name_arg.arg_repetition = eArgRepeatOptional;
    404 
    405         // Define the second variant of this arg.
    406         prefix_name_arg.arg_type = eArgTypeSettingPrefix;
    407         prefix_name_arg.arg_repetition = eArgRepeatOptional;
    408 
    409         arg.push_back (var_name_arg);
    410         arg.push_back (prefix_name_arg);
    411 
    412         // Push the data for the first argument into the m_arguments vector.
    413         m_arguments.push_back (arg);
    414     }
    415 
    416     virtual
    417     ~CommandObjectSettingsList () {}
    418 
    419     virtual int
    420     HandleArgumentCompletion (Args &input,
    421                               int &cursor_index,
    422                               int &cursor_char_position,
    423                               OptionElementVector &opt_element_vector,
    424                               int match_start_point,
    425                               int max_return_elements,
    426                               bool &word_complete,
    427                               StringList &matches)
    428     {
    429         std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
    430 
    431         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
    432                                                              CommandCompletions::eSettingsNameCompletion,
    433                                                              completion_str.c_str(),
    434                                                              match_start_point,
    435                                                              max_return_elements,
    436                                                              NULL,
    437                                                              word_complete,
    438                                                              matches);
    439         return matches.GetSize();
    440     }
    441 
    442 protected:
    443     virtual bool
    444     DoExecute (Args& args, CommandReturnObject &result)
    445     {
    446         result.SetStatus (eReturnStatusSuccessFinishResult);
    447 
    448         const bool will_modify = false;
    449         const size_t argc = args.GetArgumentCount ();
    450         if (argc > 0)
    451         {
    452             const bool dump_qualified_name = true;
    453 
    454             for (size_t i=0; i<argc; ++i)
    455             {
    456                 const char *property_path = args.GetArgumentAtIndex (i);
    457 
    458                 const Property *property = m_interpreter.GetDebugger().GetValueProperties()->GetPropertyAtPath (&m_exe_ctx, will_modify, property_path);
    459 
    460                 if (property)
    461                 {
    462                     property->DumpDescription (m_interpreter, result.GetOutputStream(), 0, dump_qualified_name);
    463                 }
    464                 else
    465                 {
    466                     result.AppendErrorWithFormat ("invalid property path '%s'", property_path);
    467                     result.SetStatus (eReturnStatusFailed);
    468                 }
    469             }
    470         }
    471         else
    472         {
    473             m_interpreter.GetDebugger().DumpAllDescriptions (m_interpreter, result.GetOutputStream());
    474         }
    475 
    476         return result.Succeeded();
    477     }
    478 };
    479 
    480 //-------------------------------------------------------------------------
    481 // CommandObjectSettingsRemove
    482 //-------------------------------------------------------------------------
    483 
    484 class CommandObjectSettingsRemove : public CommandObjectRaw
    485 {
    486 public:
    487     CommandObjectSettingsRemove (CommandInterpreter &interpreter) :
    488         CommandObjectRaw (interpreter,
    489                           "settings remove",
    490                           "Remove the specified element from an array or dictionary settings variable.",
    491                           NULL)
    492     {
    493         CommandArgumentEntry arg1;
    494         CommandArgumentEntry arg2;
    495         CommandArgumentData var_name_arg;
    496         CommandArgumentData index_arg;
    497         CommandArgumentData key_arg;
    498 
    499         // Define the first (and only) variant of this arg.
    500         var_name_arg.arg_type = eArgTypeSettingVariableName;
    501         var_name_arg.arg_repetition = eArgRepeatPlain;
    502 
    503         // There is only one variant this argument could be; put it into the argument entry.
    504         arg1.push_back (var_name_arg);
    505 
    506         // Define the first variant of this arg.
    507         index_arg.arg_type = eArgTypeSettingIndex;
    508         index_arg.arg_repetition = eArgRepeatPlain;
    509 
    510         // Define the second variant of this arg.
    511         key_arg.arg_type = eArgTypeSettingKey;
    512         key_arg.arg_repetition = eArgRepeatPlain;
    513 
    514         // Push both variants into this arg
    515         arg2.push_back (index_arg);
    516         arg2.push_back (key_arg);
    517 
    518         // Push the data for the first argument into the m_arguments vector.
    519         m_arguments.push_back (arg1);
    520         m_arguments.push_back (arg2);
    521     }
    522 
    523     virtual
    524     ~CommandObjectSettingsRemove () {}
    525 
    526     virtual int
    527     HandleArgumentCompletion (Args &input,
    528                               int &cursor_index,
    529                               int &cursor_char_position,
    530                               OptionElementVector &opt_element_vector,
    531                               int match_start_point,
    532                               int max_return_elements,
    533                               bool &word_complete,
    534                               StringList &matches)
    535     {
    536         std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
    537 
    538         // Attempting to complete variable name
    539         if (cursor_index < 2)
    540             CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
    541                                                                  CommandCompletions::eSettingsNameCompletion,
    542                                                                  completion_str.c_str(),
    543                                                                  match_start_point,
    544                                                                  max_return_elements,
    545                                                                  NULL,
    546                                                                  word_complete,
    547                                                                  matches);
    548 
    549         return matches.GetSize();
    550     }
    551 
    552 protected:
    553     virtual bool
    554     DoExecute (const char *command, CommandReturnObject &result)
    555     {
    556         result.SetStatus (eReturnStatusSuccessFinishNoResult);
    557 
    558         Args cmd_args(command);
    559 
    560         // Process possible options.
    561         if (!ParseOptions (cmd_args, result))
    562             return false;
    563 
    564         const size_t argc = cmd_args.GetArgumentCount ();
    565         if (argc == 0)
    566         {
    567             result.AppendError ("'settings set' takes an array or dictionary item, or an array followed by one or more indexes, or a dictionary followed by one or more key names to remove");
    568             result.SetStatus (eReturnStatusFailed);
    569             return false;
    570         }
    571 
    572         const char *var_name = cmd_args.GetArgumentAtIndex (0);
    573         if ((var_name == NULL) || (var_name[0] == '\0'))
    574         {
    575             result.AppendError ("'settings set' command requires a valid variable name");
    576             result.SetStatus (eReturnStatusFailed);
    577             return false;
    578         }
    579 
    580         // Split the raw command into var_name and value pair.
    581         llvm::StringRef raw_str(command);
    582         std::string var_value_string = raw_str.split(var_name).second.str();
    583         const char *var_value_cstr = Args::StripSpaces(var_value_string, true, true, false);
    584 
    585         Error error (m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
    586                                                                    eVarSetOperationRemove,
    587                                                                    var_name,
    588                                                                    var_value_cstr));
    589         if (error.Fail())
    590         {
    591             result.AppendError (error.AsCString());
    592             result.SetStatus (eReturnStatusFailed);
    593             return false;
    594         }
    595 
    596         return result.Succeeded();
    597     }
    598 };
    599 
    600 //-------------------------------------------------------------------------
    601 // CommandObjectSettingsReplace
    602 //-------------------------------------------------------------------------
    603 
    604 class CommandObjectSettingsReplace : public CommandObjectRaw
    605 {
    606 public:
    607     CommandObjectSettingsReplace (CommandInterpreter &interpreter) :
    608         CommandObjectRaw (interpreter,
    609                           "settings replace",
    610                           "Replace the specified element from an internal debugger settings array or dictionary variable with the specified new value.",
    611                           NULL)
    612     {
    613         CommandArgumentEntry arg1;
    614         CommandArgumentEntry arg2;
    615         CommandArgumentEntry arg3;
    616         CommandArgumentData var_name_arg;
    617         CommandArgumentData index_arg;
    618         CommandArgumentData key_arg;
    619         CommandArgumentData value_arg;
    620 
    621         // Define the first (and only) variant of this arg.
    622         var_name_arg.arg_type = eArgTypeSettingVariableName;
    623         var_name_arg.arg_repetition = eArgRepeatPlain;
    624 
    625         // There is only one variant this argument could be; put it into the argument entry.
    626         arg1.push_back (var_name_arg);
    627 
    628         // Define the first (variant of this arg.
    629         index_arg.arg_type = eArgTypeSettingIndex;
    630         index_arg.arg_repetition = eArgRepeatPlain;
    631 
    632         // Define the second (variant of this arg.
    633         key_arg.arg_type = eArgTypeSettingKey;
    634         key_arg.arg_repetition = eArgRepeatPlain;
    635 
    636         // Put both variants into this arg
    637         arg2.push_back (index_arg);
    638         arg2.push_back (key_arg);
    639 
    640         // Define the first (and only) variant of this arg.
    641         value_arg.arg_type = eArgTypeValue;
    642         value_arg.arg_repetition = eArgRepeatPlain;
    643 
    644         // There is only one variant this argument could be; put it into the argument entry.
    645         arg3.push_back (value_arg);
    646 
    647         // Push the data for the first argument into the m_arguments vector.
    648         m_arguments.push_back (arg1);
    649         m_arguments.push_back (arg2);
    650         m_arguments.push_back (arg3);
    651     }
    652 
    653 
    654     virtual
    655     ~CommandObjectSettingsReplace () {}
    656 
    657     // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
    658     virtual bool
    659     WantsCompletion() { return true; }
    660 
    661     virtual int
    662     HandleArgumentCompletion (Args &input,
    663                               int &cursor_index,
    664                               int &cursor_char_position,
    665                               OptionElementVector &opt_element_vector,
    666                               int match_start_point,
    667                               int max_return_elements,
    668                               bool &word_complete,
    669                               StringList &matches)
    670     {
    671         std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
    672 
    673         // Attempting to complete variable name
    674         if (cursor_index < 2)
    675             CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
    676                                                                  CommandCompletions::eSettingsNameCompletion,
    677                                                                  completion_str.c_str(),
    678                                                                  match_start_point,
    679                                                                  max_return_elements,
    680                                                                  NULL,
    681                                                                  word_complete,
    682                                                                  matches);
    683 
    684         return matches.GetSize();
    685     }
    686 
    687 protected:
    688     virtual bool
    689     DoExecute (const char *command, CommandReturnObject &result)
    690     {
    691         result.SetStatus (eReturnStatusSuccessFinishNoResult);
    692 
    693         Args cmd_args(command);
    694         const char *var_name = cmd_args.GetArgumentAtIndex (0);
    695         if ((var_name == NULL) || (var_name[0] == '\0'))
    696         {
    697             result.AppendError ("'settings replace' command requires a valid variable name; No value supplied");
    698             result.SetStatus (eReturnStatusFailed);
    699             return false;
    700         }
    701 
    702 
    703         // Split the raw command into var_name, index_value, and value triple.
    704         llvm::StringRef raw_str(command);
    705         std::string var_value_string = raw_str.split(var_name).second.str();
    706         const char *var_value_cstr = Args::StripSpaces(var_value_string, true, true, false);
    707 
    708         Error error(m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
    709                                                                   eVarSetOperationReplace,
    710                                                                   var_name,
    711                                                                   var_value_cstr));
    712         if (error.Fail())
    713         {
    714             result.AppendError (error.AsCString());
    715             result.SetStatus (eReturnStatusFailed);
    716             return false;
    717         }
    718         else
    719         {
    720             result.SetStatus (eReturnStatusSuccessFinishNoResult);
    721 
    722         }
    723 
    724         return result.Succeeded();
    725     }
    726 };
    727 
    728 //-------------------------------------------------------------------------
    729 // CommandObjectSettingsInsertBefore
    730 //-------------------------------------------------------------------------
    731 
    732 class CommandObjectSettingsInsertBefore : public CommandObjectRaw
    733 {
    734 public:
    735     CommandObjectSettingsInsertBefore (CommandInterpreter &interpreter) :
    736         CommandObjectRaw (interpreter,
    737                           "settings insert-before",
    738                           "Insert value(s) into an internal debugger settings array variable, immediately before the specified element.",
    739                           NULL)
    740     {
    741         CommandArgumentEntry arg1;
    742         CommandArgumentEntry arg2;
    743         CommandArgumentEntry arg3;
    744         CommandArgumentData var_name_arg;
    745         CommandArgumentData index_arg;
    746         CommandArgumentData value_arg;
    747 
    748         // Define the first (and only) variant of this arg.
    749         var_name_arg.arg_type = eArgTypeSettingVariableName;
    750         var_name_arg.arg_repetition = eArgRepeatPlain;
    751 
    752         // There is only one variant this argument could be; put it into the argument entry.
    753         arg1.push_back (var_name_arg);
    754 
    755         // Define the first (variant of this arg.
    756         index_arg.arg_type = eArgTypeSettingIndex;
    757         index_arg.arg_repetition = eArgRepeatPlain;
    758 
    759         // There is only one variant this argument could be; put it into the argument entry.
    760         arg2.push_back (index_arg);
    761 
    762         // Define the first (and only) variant of this arg.
    763         value_arg.arg_type = eArgTypeValue;
    764         value_arg.arg_repetition = eArgRepeatPlain;
    765 
    766         // There is only one variant this argument could be; put it into the argument entry.
    767         arg3.push_back (value_arg);
    768 
    769         // Push the data for the first argument into the m_arguments vector.
    770         m_arguments.push_back (arg1);
    771         m_arguments.push_back (arg2);
    772         m_arguments.push_back (arg3);
    773     }
    774 
    775     virtual
    776     ~CommandObjectSettingsInsertBefore () {}
    777 
    778     // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
    779     virtual bool
    780     WantsCompletion() { return true; }
    781 
    782     virtual int
    783     HandleArgumentCompletion (Args &input,
    784                               int &cursor_index,
    785                               int &cursor_char_position,
    786                               OptionElementVector &opt_element_vector,
    787                               int match_start_point,
    788                               int max_return_elements,
    789                               bool &word_complete,
    790                               StringList &matches)
    791     {
    792         std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
    793 
    794         // Attempting to complete variable name
    795         if (cursor_index < 2)
    796             CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
    797                                                                  CommandCompletions::eSettingsNameCompletion,
    798                                                                  completion_str.c_str(),
    799                                                                  match_start_point,
    800                                                                  max_return_elements,
    801                                                                  NULL,
    802                                                                  word_complete,
    803                                                                  matches);
    804 
    805         return matches.GetSize();
    806     }
    807 
    808 protected:
    809     virtual bool
    810     DoExecute (const char *command, CommandReturnObject &result)
    811     {
    812         result.SetStatus (eReturnStatusSuccessFinishNoResult);
    813 
    814         Args cmd_args(command);
    815         const size_t argc = cmd_args.GetArgumentCount ();
    816 
    817         if (argc < 3)
    818         {
    819             result.AppendError ("'settings insert-before' takes more arguments");
    820             result.SetStatus (eReturnStatusFailed);
    821             return false;
    822         }
    823 
    824         const char *var_name = cmd_args.GetArgumentAtIndex (0);
    825         if ((var_name == NULL) || (var_name[0] == '\0'))
    826         {
    827             result.AppendError ("'settings insert-before' command requires a valid variable name; No value supplied");
    828             result.SetStatus (eReturnStatusFailed);
    829             return false;
    830         }
    831 
    832         // Split the raw command into var_name, index_value, and value triple.
    833         llvm::StringRef raw_str(command);
    834         std::string var_value_string = raw_str.split(var_name).second.str();
    835         const char *var_value_cstr = Args::StripSpaces(var_value_string, true, true, false);
    836 
    837         Error error(m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
    838                                                                   eVarSetOperationInsertBefore,
    839                                                                   var_name,
    840                                                                   var_value_cstr));
    841         if (error.Fail())
    842         {
    843             result.AppendError (error.AsCString());
    844             result.SetStatus (eReturnStatusFailed);
    845             return false;
    846         }
    847 
    848         return result.Succeeded();
    849     }
    850 };
    851 
    852 //-------------------------------------------------------------------------
    853 // CommandObjectSettingInsertAfter
    854 //-------------------------------------------------------------------------
    855 
    856 class CommandObjectSettingsInsertAfter : public CommandObjectRaw
    857 {
    858 public:
    859     CommandObjectSettingsInsertAfter (CommandInterpreter &interpreter) :
    860         CommandObjectRaw (interpreter,
    861                           "settings insert-after",
    862                           "Insert value(s) into an internal debugger settings array variable, immediately after the specified element.",
    863                           NULL)
    864     {
    865         CommandArgumentEntry arg1;
    866         CommandArgumentEntry arg2;
    867         CommandArgumentEntry arg3;
    868         CommandArgumentData var_name_arg;
    869         CommandArgumentData index_arg;
    870         CommandArgumentData value_arg;
    871 
    872         // Define the first (and only) variant of this arg.
    873         var_name_arg.arg_type = eArgTypeSettingVariableName;
    874         var_name_arg.arg_repetition = eArgRepeatPlain;
    875 
    876         // There is only one variant this argument could be; put it into the argument entry.
    877         arg1.push_back (var_name_arg);
    878 
    879         // Define the first (variant of this arg.
    880         index_arg.arg_type = eArgTypeSettingIndex;
    881         index_arg.arg_repetition = eArgRepeatPlain;
    882 
    883         // There is only one variant this argument could be; put it into the argument entry.
    884         arg2.push_back (index_arg);
    885 
    886         // Define the first (and only) variant of this arg.
    887         value_arg.arg_type = eArgTypeValue;
    888         value_arg.arg_repetition = eArgRepeatPlain;
    889 
    890         // There is only one variant this argument could be; put it into the argument entry.
    891         arg3.push_back (value_arg);
    892 
    893         // Push the data for the first argument into the m_arguments vector.
    894         m_arguments.push_back (arg1);
    895         m_arguments.push_back (arg2);
    896         m_arguments.push_back (arg3);
    897     }
    898 
    899     virtual
    900     ~CommandObjectSettingsInsertAfter () {}
    901 
    902     // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
    903     virtual bool
    904     WantsCompletion() { return true; }
    905 
    906     virtual int
    907     HandleArgumentCompletion (Args &input,
    908                               int &cursor_index,
    909                               int &cursor_char_position,
    910                               OptionElementVector &opt_element_vector,
    911                               int match_start_point,
    912                               int max_return_elements,
    913                               bool &word_complete,
    914                               StringList &matches)
    915     {
    916         std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
    917 
    918         // Attempting to complete variable name
    919         if (cursor_index < 2)
    920             CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
    921                                                                  CommandCompletions::eSettingsNameCompletion,
    922                                                                  completion_str.c_str(),
    923                                                                  match_start_point,
    924                                                                  max_return_elements,
    925                                                                  NULL,
    926                                                                  word_complete,
    927                                                                  matches);
    928 
    929         return matches.GetSize();
    930     }
    931 
    932 protected:
    933     virtual bool
    934     DoExecute (const char *command, CommandReturnObject &result)
    935     {
    936         result.SetStatus (eReturnStatusSuccessFinishNoResult);
    937 
    938         Args cmd_args(command);
    939         const size_t argc = cmd_args.GetArgumentCount ();
    940 
    941         if (argc < 3)
    942         {
    943             result.AppendError ("'settings insert-after' takes more arguments");
    944             result.SetStatus (eReturnStatusFailed);
    945             return false;
    946         }
    947 
    948         const char *var_name = cmd_args.GetArgumentAtIndex (0);
    949         if ((var_name == NULL) || (var_name[0] == '\0'))
    950         {
    951             result.AppendError ("'settings insert-after' command requires a valid variable name; No value supplied");
    952             result.SetStatus (eReturnStatusFailed);
    953             return false;
    954         }
    955 
    956         // Split the raw command into var_name, index_value, and value triple.
    957         llvm::StringRef raw_str(command);
    958         std::string var_value_string = raw_str.split(var_name).second.str();
    959         const char *var_value_cstr = Args::StripSpaces(var_value_string, true, true, false);
    960 
    961         Error error(m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
    962                                                                   eVarSetOperationInsertAfter,
    963                                                                   var_name,
    964                                                                   var_value_cstr));
    965         if (error.Fail())
    966         {
    967             result.AppendError (error.AsCString());
    968             result.SetStatus (eReturnStatusFailed);
    969             return false;
    970         }
    971 
    972         return result.Succeeded();
    973     }
    974 };
    975 
    976 //-------------------------------------------------------------------------
    977 // CommandObjectSettingsAppend
    978 //-------------------------------------------------------------------------
    979 
    980 class CommandObjectSettingsAppend : public CommandObjectRaw
    981 {
    982 public:
    983     CommandObjectSettingsAppend (CommandInterpreter &interpreter) :
    984         CommandObjectRaw (interpreter,
    985                           "settings append",
    986                           "Append a new value to the end of an internal debugger settings array, dictionary or string variable.",
    987                           NULL)
    988     {
    989         CommandArgumentEntry arg1;
    990         CommandArgumentEntry arg2;
    991         CommandArgumentData var_name_arg;
    992         CommandArgumentData value_arg;
    993 
    994         // Define the first (and only) variant of this arg.
    995         var_name_arg.arg_type = eArgTypeSettingVariableName;
    996         var_name_arg.arg_repetition = eArgRepeatPlain;
    997 
    998         // There is only one variant this argument could be; put it into the argument entry.
    999         arg1.push_back (var_name_arg);
   1000 
   1001         // Define the first (and only) variant of this arg.
   1002         value_arg.arg_type = eArgTypeValue;
   1003         value_arg.arg_repetition = eArgRepeatPlain;
   1004 
   1005         // There is only one variant this argument could be; put it into the argument entry.
   1006         arg2.push_back (value_arg);
   1007 
   1008         // Push the data for the first argument into the m_arguments vector.
   1009         m_arguments.push_back (arg1);
   1010         m_arguments.push_back (arg2);
   1011     }
   1012 
   1013     virtual
   1014     ~CommandObjectSettingsAppend () {}
   1015 
   1016     // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
   1017     virtual bool
   1018     WantsCompletion() { return true; }
   1019 
   1020     virtual int
   1021     HandleArgumentCompletion (Args &input,
   1022                               int &cursor_index,
   1023                               int &cursor_char_position,
   1024                               OptionElementVector &opt_element_vector,
   1025                               int match_start_point,
   1026                               int max_return_elements,
   1027                               bool &word_complete,
   1028                               StringList &matches)
   1029     {
   1030         std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
   1031 
   1032         // Attempting to complete variable name
   1033         if (cursor_index < 2)
   1034             CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
   1035                                                                  CommandCompletions::eSettingsNameCompletion,
   1036                                                                  completion_str.c_str(),
   1037                                                                  match_start_point,
   1038                                                                  max_return_elements,
   1039                                                                  NULL,
   1040                                                                  word_complete,
   1041                                                                  matches);
   1042 
   1043         return matches.GetSize();
   1044     }
   1045 
   1046 protected:
   1047     virtual bool
   1048     DoExecute (const char *command, CommandReturnObject &result)
   1049     {
   1050         result.SetStatus (eReturnStatusSuccessFinishNoResult);
   1051         Args cmd_args(command);
   1052         const size_t argc = cmd_args.GetArgumentCount ();
   1053 
   1054         if (argc < 2)
   1055         {
   1056             result.AppendError ("'settings append' takes more arguments");
   1057             result.SetStatus (eReturnStatusFailed);
   1058             return false;
   1059         }
   1060 
   1061         const char *var_name = cmd_args.GetArgumentAtIndex (0);
   1062         if ((var_name == NULL) || (var_name[0] == '\0'))
   1063         {
   1064             result.AppendError ("'settings append' command requires a valid variable name; No value supplied");
   1065             result.SetStatus (eReturnStatusFailed);
   1066             return false;
   1067         }
   1068 
   1069         // Do not perform cmd_args.Shift() since StringRef is manipulating the
   1070         // raw character string later on.
   1071 
   1072         // Split the raw command into var_name and value pair.
   1073         llvm::StringRef raw_str(command);
   1074         std::string var_value_string = raw_str.split(var_name).second.str();
   1075         const char *var_value_cstr = Args::StripSpaces(var_value_string, true, true, false);
   1076 
   1077         Error error(m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
   1078                                                                   eVarSetOperationAppend,
   1079                                                                   var_name,
   1080                                                                   var_value_cstr));
   1081         if (error.Fail())
   1082         {
   1083             result.AppendError (error.AsCString());
   1084             result.SetStatus (eReturnStatusFailed);
   1085             return false;
   1086         }
   1087 
   1088         return result.Succeeded();
   1089     }
   1090 };
   1091 
   1092 //-------------------------------------------------------------------------
   1093 // CommandObjectSettingsClear
   1094 //-------------------------------------------------------------------------
   1095 
   1096 class CommandObjectSettingsClear : public CommandObjectParsed
   1097 {
   1098 public:
   1099     CommandObjectSettingsClear (CommandInterpreter &interpreter) :
   1100         CommandObjectParsed (interpreter,
   1101                              "settings clear",
   1102                              "Erase all the contents of an internal debugger settings variables; this is only valid for variables with clearable types, i.e. strings, arrays or dictionaries.",
   1103                              NULL)
   1104     {
   1105         CommandArgumentEntry arg;
   1106         CommandArgumentData var_name_arg;
   1107 
   1108         // Define the first (and only) variant of this arg.
   1109         var_name_arg.arg_type = eArgTypeSettingVariableName;
   1110         var_name_arg.arg_repetition = eArgRepeatPlain;
   1111 
   1112         // There is only one variant this argument could be; put it into the argument entry.
   1113         arg.push_back (var_name_arg);
   1114 
   1115         // Push the data for the first argument into the m_arguments vector.
   1116         m_arguments.push_back (arg);
   1117     }
   1118 
   1119     virtual
   1120     ~CommandObjectSettingsClear () {}
   1121 
   1122     virtual int
   1123     HandleArgumentCompletion (Args &input,
   1124                               int &cursor_index,
   1125                               int &cursor_char_position,
   1126                               OptionElementVector &opt_element_vector,
   1127                               int match_start_point,
   1128                               int max_return_elements,
   1129                               bool &word_complete,
   1130                               StringList &matches)
   1131     {
   1132         std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
   1133 
   1134         // Attempting to complete variable name
   1135         if (cursor_index < 2)
   1136             CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
   1137                                                                  CommandCompletions::eSettingsNameCompletion,
   1138                                                                  completion_str.c_str(),
   1139                                                                  match_start_point,
   1140                                                                  max_return_elements,
   1141                                                                  NULL,
   1142                                                                  word_complete,
   1143                                                                  matches);
   1144 
   1145         return matches.GetSize();
   1146     }
   1147 
   1148 protected:
   1149     virtual bool
   1150     DoExecute (Args& command, CommandReturnObject &result)
   1151     {
   1152         result.SetStatus (eReturnStatusSuccessFinishNoResult);
   1153         const size_t argc = command.GetArgumentCount ();
   1154 
   1155         if (argc != 1)
   1156         {
   1157             result.AppendError ("'setttings clear' takes exactly one argument");
   1158             result.SetStatus (eReturnStatusFailed);
   1159             return false;
   1160         }
   1161 
   1162         const char *var_name = command.GetArgumentAtIndex (0);
   1163         if ((var_name == NULL) || (var_name[0] == '\0'))
   1164         {
   1165             result.AppendError ("'settings clear' command requires a valid variable name; No value supplied");
   1166             result.SetStatus (eReturnStatusFailed);
   1167             return false;
   1168         }
   1169 
   1170         Error error (m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
   1171                                                                    eVarSetOperationClear,
   1172                                                                    var_name,
   1173                                                                    NULL));
   1174         if (error.Fail())
   1175         {
   1176             result.AppendError (error.AsCString());
   1177             result.SetStatus (eReturnStatusFailed);
   1178             return false;
   1179         }
   1180 
   1181         return result.Succeeded();
   1182     }
   1183 };
   1184 
   1185 //-------------------------------------------------------------------------
   1186 // CommandObjectMultiwordSettings
   1187 //-------------------------------------------------------------------------
   1188 
   1189 CommandObjectMultiwordSettings::CommandObjectMultiwordSettings (CommandInterpreter &interpreter) :
   1190     CommandObjectMultiword (interpreter,
   1191                             "settings",
   1192                             "A set of commands for manipulating internal settable debugger variables.",
   1193                             "settings <command> [<command-options>]")
   1194 {
   1195     LoadSubCommand ("set",           CommandObjectSP (new CommandObjectSettingsSet (interpreter)));
   1196     LoadSubCommand ("show",          CommandObjectSP (new CommandObjectSettingsShow (interpreter)));
   1197     LoadSubCommand ("list",          CommandObjectSP (new CommandObjectSettingsList (interpreter)));
   1198     LoadSubCommand ("remove",        CommandObjectSP (new CommandObjectSettingsRemove (interpreter)));
   1199     LoadSubCommand ("replace",       CommandObjectSP (new CommandObjectSettingsReplace (interpreter)));
   1200     LoadSubCommand ("insert-before", CommandObjectSP (new CommandObjectSettingsInsertBefore (interpreter)));
   1201     LoadSubCommand ("insert-after",  CommandObjectSP (new CommandObjectSettingsInsertAfter (interpreter)));
   1202     LoadSubCommand ("append",        CommandObjectSP (new CommandObjectSettingsAppend (interpreter)));
   1203     LoadSubCommand ("clear",         CommandObjectSP (new CommandObjectSettingsClear (interpreter)));
   1204 }
   1205 
   1206 CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings ()
   1207 {
   1208 }
   1209