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