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