xref: /llvm-project/lldb/source/Commands/CommandObjectSettings.cpp (revision 2c76eb02a9ff404f77e58248b153523fcb33397a)
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 var_value_str = raw_str.split(var_name).second;
148     StripLeadingSpaces(var_value_str);
149     std::string var_value_string = var_value_str.str();
150 
151     if (!m_options.m_reset
152         && var_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                                        var_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::ExecuteRawCommandString (const char *raw_command, CommandReturnObject &result)
694 {
695     UserSettingsControllerSP usc_sp (Debugger::GetSettingsController ());
696 
697     Args cmd_args(raw_command);
698     const int argc = cmd_args.GetArgumentCount ();
699 
700     if (argc < 3)
701     {
702         result.AppendError ("'settings replace' takes more arguments");
703         result.SetStatus (eReturnStatusFailed);
704         return false;
705     }
706 
707     const char *var_name = cmd_args.GetArgumentAtIndex (0);
708     std::string var_name_string;
709     if ((var_name == NULL) || (var_name[0] == '\0'))
710     {
711         result.AppendError ("'settings replace' command requires a valid variable name; No value supplied");
712         result.SetStatus (eReturnStatusFailed);
713         return false;
714     }
715 
716     var_name_string = var_name;
717     cmd_args.Shift();
718 
719     const char *index_value = cmd_args.GetArgumentAtIndex (0);
720     std::string index_value_string;
721     if ((index_value == NULL) || (index_value[0] == '\0'))
722     {
723         result.AppendError ("'settings insert-before' command requires an index value; no value supplied");
724         result.SetStatus (eReturnStatusFailed);
725         return false;
726     }
727 
728     index_value_string = index_value;
729     cmd_args.Shift();
730 
731     // Split the raw command into var_name, index_value, and value triple.
732     llvm::StringRef raw_str(raw_command);
733     llvm::StringRef var_value_str = raw_str.split(var_name).second.split(index_value).second;
734     StripLeadingSpaces(var_value_str);
735     std::string var_value_string = var_value_str.str();
736 
737     if (var_value_string.empty())
738     {
739         result.AppendError ("'settings replace' command requires a valid variable value; no value supplied");
740         result.SetStatus (eReturnStatusFailed);
741     }
742     else
743     {
744         Error err = usc_sp->SetVariable (var_name_string.c_str(),
745                                          var_value_string.c_str(),
746                                          eVarSetOperationReplace,
747                                          true,
748                                          m_interpreter.GetDebugger().GetInstanceName().AsCString(),
749                                          index_value_string.c_str());
750         if (err.Fail ())
751         {
752             result.AppendError (err.AsCString());
753             result.SetStatus (eReturnStatusFailed);
754         }
755         else
756             result.SetStatus (eReturnStatusSuccessFinishNoResult);
757     }
758 
759     return result.Succeeded();
760 }
761 
762 int
763 CommandObjectSettingsReplace::HandleArgumentCompletion (Args &input,
764                                                         int &cursor_index,
765                                                         int &cursor_char_position,
766                                                         OptionElementVector &opt_element_vector,
767                                                         int match_start_point,
768                                                         int max_return_elements,
769                                                         bool &word_complete,
770                                                         StringList &matches)
771 {
772     std::string completion_str (input.GetArgumentAtIndex (cursor_index));
773     completion_str.erase (cursor_char_position);
774 
775     // Attempting to complete variable name
776     if (cursor_index < 2)
777         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
778                                                              CommandCompletions::eSettingsNameCompletion,
779                                                              completion_str.c_str(),
780                                                              match_start_point,
781                                                              max_return_elements,
782                                                              NULL,
783                                                              word_complete,
784                                                              matches);
785 
786     return matches.GetSize();
787 }
788 
789 //-------------------------------------------------------------------------
790 // CommandObjectSettingsInsertBefore
791 //-------------------------------------------------------------------------
792 
793 CommandObjectSettingsInsertBefore::CommandObjectSettingsInsertBefore (CommandInterpreter &interpreter) :
794     CommandObject (interpreter,
795                    "settings insert-before",
796                    "Insert value(s) into an internal debugger settings array variable, immediately before the specified element.",
797                    NULL)
798 {
799     CommandArgumentEntry arg1;
800     CommandArgumentEntry arg2;
801     CommandArgumentEntry arg3;
802     CommandArgumentData var_name_arg;
803     CommandArgumentData index_arg;
804     CommandArgumentData value_arg;
805 
806     // Define the first (and only) variant of this arg.
807     var_name_arg.arg_type = eArgTypeSettingVariableName;
808     var_name_arg.arg_repetition = eArgRepeatPlain;
809 
810     // There is only one variant this argument could be; put it into the argument entry.
811     arg1.push_back (var_name_arg);
812 
813     // Define the first (variant of this arg.
814     index_arg.arg_type = eArgTypeSettingIndex;
815     index_arg.arg_repetition = eArgRepeatPlain;
816 
817     // There is only one variant this argument could be; put it into the argument entry.
818     arg2.push_back (index_arg);
819 
820     // Define the first (and only) variant of this arg.
821     value_arg.arg_type = eArgTypeValue;
822     value_arg.arg_repetition = eArgRepeatPlain;
823 
824     // There is only one variant this argument could be; put it into the argument entry.
825     arg3.push_back (value_arg);
826 
827     // Push the data for the first argument into the m_arguments vector.
828     m_arguments.push_back (arg1);
829     m_arguments.push_back (arg2);
830     m_arguments.push_back (arg3);
831 }
832 
833 CommandObjectSettingsInsertBefore::~CommandObjectSettingsInsertBefore ()
834 {
835 }
836 
837 bool
838 CommandObjectSettingsInsertBefore::ExecuteRawCommandString (const char *raw_command, CommandReturnObject &result)
839 {
840     UserSettingsControllerSP usc_sp (Debugger::GetSettingsController ());
841 
842     Args cmd_args(raw_command);
843     const int argc = cmd_args.GetArgumentCount ();
844 
845     if (argc < 3)
846     {
847         result.AppendError ("'settings insert-before' takes more arguments");
848         result.SetStatus (eReturnStatusFailed);
849         return false;
850     }
851 
852     const char *var_name = cmd_args.GetArgumentAtIndex (0);
853     std::string var_name_string;
854     if ((var_name == NULL) || (var_name[0] == '\0'))
855     {
856         result.AppendError ("'settings insert-before' command requires a valid variable name; No value supplied");
857         result.SetStatus (eReturnStatusFailed);
858         return false;
859     }
860 
861     var_name_string = var_name;
862     cmd_args.Shift();
863 
864     const char *index_value = cmd_args.GetArgumentAtIndex (0);
865     std::string index_value_string;
866     if ((index_value == NULL) || (index_value[0] == '\0'))
867     {
868         result.AppendError ("'settings insert-before' command requires an index value; no value supplied");
869         result.SetStatus (eReturnStatusFailed);
870         return false;
871     }
872 
873     index_value_string = index_value;
874     cmd_args.Shift();
875 
876     // Split the raw command into var_name, index_value, and value triple.
877     llvm::StringRef raw_str(raw_command);
878     llvm::StringRef var_value_str = raw_str.split(var_name).second.split(index_value).second;
879     StripLeadingSpaces(var_value_str);
880     std::string var_value_string = var_value_str.str();
881 
882     if (var_value_string.empty())
883     {
884         result.AppendError ("'settings insert-before' command requires a valid variable value;"
885                             " No value supplied");
886         result.SetStatus (eReturnStatusFailed);
887     }
888     else
889     {
890         Error err = usc_sp->SetVariable (var_name_string.c_str(),
891                                          var_value_string.c_str(),
892                                          eVarSetOperationInsertBefore,
893                                          true,
894                                          m_interpreter.GetDebugger().GetInstanceName().AsCString(),
895                                          index_value_string.c_str());
896         if (err.Fail ())
897         {
898             result.AppendError (err.AsCString());
899             result.SetStatus (eReturnStatusFailed);
900         }
901         else
902             result.SetStatus (eReturnStatusSuccessFinishNoResult);
903     }
904 
905     return result.Succeeded();
906 }
907 
908 
909 int
910 CommandObjectSettingsInsertBefore::HandleArgumentCompletion (Args &input,
911                                                              int &cursor_index,
912                                                              int &cursor_char_position,
913                                                              OptionElementVector &opt_element_vector,
914                                                              int match_start_point,
915                                                              int max_return_elements,
916                                                              bool &word_complete,
917                                                              StringList &matches)
918 {
919     std::string completion_str (input.GetArgumentAtIndex (cursor_index));
920     completion_str.erase (cursor_char_position);
921 
922     // Attempting to complete variable name
923     if (cursor_index < 2)
924         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
925                                                              CommandCompletions::eSettingsNameCompletion,
926                                                              completion_str.c_str(),
927                                                              match_start_point,
928                                                              max_return_elements,
929                                                              NULL,
930                                                              word_complete,
931                                                              matches);
932 
933     return matches.GetSize();
934 }
935 
936 //-------------------------------------------------------------------------
937 // CommandObjectSettingInsertAfter
938 //-------------------------------------------------------------------------
939 
940 CommandObjectSettingsInsertAfter::CommandObjectSettingsInsertAfter (CommandInterpreter &interpreter) :
941     CommandObject (interpreter,
942                    "settings insert-after",
943                    "Insert value(s) into an internal debugger settings array variable, immediately after the specified element.",
944                    NULL)
945 {
946     CommandArgumentEntry arg1;
947     CommandArgumentEntry arg2;
948     CommandArgumentEntry arg3;
949     CommandArgumentData var_name_arg;
950     CommandArgumentData index_arg;
951     CommandArgumentData value_arg;
952 
953     // Define the first (and only) variant of this arg.
954     var_name_arg.arg_type = eArgTypeSettingVariableName;
955     var_name_arg.arg_repetition = eArgRepeatPlain;
956 
957     // There is only one variant this argument could be; put it into the argument entry.
958     arg1.push_back (var_name_arg);
959 
960     // Define the first (variant of this arg.
961     index_arg.arg_type = eArgTypeSettingIndex;
962     index_arg.arg_repetition = eArgRepeatPlain;
963 
964     // There is only one variant this argument could be; put it into the argument entry.
965     arg2.push_back (index_arg);
966 
967     // Define the first (and only) variant of this arg.
968     value_arg.arg_type = eArgTypeValue;
969     value_arg.arg_repetition = eArgRepeatPlain;
970 
971     // There is only one variant this argument could be; put it into the argument entry.
972     arg3.push_back (value_arg);
973 
974     // Push the data for the first argument into the m_arguments vector.
975     m_arguments.push_back (arg1);
976     m_arguments.push_back (arg2);
977     m_arguments.push_back (arg3);
978 }
979 
980 CommandObjectSettingsInsertAfter::~CommandObjectSettingsInsertAfter ()
981 {
982 }
983 
984 bool
985 CommandObjectSettingsInsertAfter::ExecuteRawCommandString (const char *raw_command, CommandReturnObject &result)
986 {
987     UserSettingsControllerSP usc_sp (Debugger::GetSettingsController ());
988 
989     Args cmd_args(raw_command);
990     const int argc = cmd_args.GetArgumentCount ();
991 
992     if (argc < 3)
993     {
994         result.AppendError ("'settings insert-after' takes more arguments");
995         result.SetStatus (eReturnStatusFailed);
996         return false;
997     }
998 
999     const char *var_name = cmd_args.GetArgumentAtIndex (0);
1000     std::string var_name_string;
1001     if ((var_name == NULL) || (var_name[0] == '\0'))
1002     {
1003         result.AppendError ("'settings insert-after' command requires a valid variable name; No value supplied");
1004         result.SetStatus (eReturnStatusFailed);
1005         return false;
1006     }
1007 
1008     var_name_string = var_name;
1009     cmd_args.Shift();
1010 
1011     const char *index_value = cmd_args.GetArgumentAtIndex (0);
1012     std::string index_value_string;
1013     if ((index_value == NULL) || (index_value[0] == '\0'))
1014     {
1015         result.AppendError ("'settings insert-after' command requires an index value; no value supplied");
1016         result.SetStatus (eReturnStatusFailed);
1017         return false;
1018     }
1019 
1020     index_value_string = index_value;
1021     cmd_args.Shift();
1022 
1023     // Split the raw command into var_name, index_value, and value triple.
1024     llvm::StringRef raw_str(raw_command);
1025     llvm::StringRef var_value_str = raw_str.split(var_name).second.split(index_value).second;
1026     StripLeadingSpaces(var_value_str);
1027     std::string var_value_string = var_value_str.str();
1028 
1029     if (var_value_string.empty())
1030     {
1031         result.AppendError ("'settings insert-after' command requires a valid variable value;"
1032                             " No value supplied");
1033         result.SetStatus (eReturnStatusFailed);
1034     }
1035     else
1036     {
1037         Error err = usc_sp->SetVariable (var_name_string.c_str(),
1038                                          var_value_string.c_str(),
1039                                          eVarSetOperationInsertAfter,
1040                                          true,
1041                                          m_interpreter.GetDebugger().GetInstanceName().AsCString(),
1042                                          index_value_string.c_str());
1043         if (err.Fail ())
1044         {
1045             result.AppendError (err.AsCString());
1046             result.SetStatus (eReturnStatusFailed);
1047         }
1048         else
1049             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1050     }
1051 
1052     return result.Succeeded();
1053 }
1054 
1055 
1056 int
1057 CommandObjectSettingsInsertAfter::HandleArgumentCompletion (Args &input,
1058                                                             int &cursor_index,
1059                                                             int &cursor_char_position,
1060                                                             OptionElementVector &opt_element_vector,
1061                                                             int match_start_point,
1062                                                             int max_return_elements,
1063                                                             bool &word_complete,
1064                                                             StringList &matches)
1065 {
1066     std::string completion_str (input.GetArgumentAtIndex (cursor_index));
1067     completion_str.erase (cursor_char_position);
1068 
1069     // Attempting to complete variable name
1070     if (cursor_index < 2)
1071         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1072                                                              CommandCompletions::eSettingsNameCompletion,
1073                                                              completion_str.c_str(),
1074                                                              match_start_point,
1075                                                              max_return_elements,
1076                                                              NULL,
1077                                                              word_complete,
1078                                                              matches);
1079 
1080     return matches.GetSize();
1081 }
1082 
1083 //-------------------------------------------------------------------------
1084 // CommandObjectSettingsAppend
1085 //-------------------------------------------------------------------------
1086 
1087 CommandObjectSettingsAppend::CommandObjectSettingsAppend (CommandInterpreter &interpreter) :
1088     CommandObject (interpreter,
1089                    "settings append",
1090                    "Append a new value to the end of an internal debugger settings array, dictionary or string variable.",
1091                    NULL)
1092 {
1093     CommandArgumentEntry arg1;
1094     CommandArgumentEntry arg2;
1095     CommandArgumentData var_name_arg;
1096     CommandArgumentData value_arg;
1097 
1098     // Define the first (and only) variant of this arg.
1099     var_name_arg.arg_type = eArgTypeSettingVariableName;
1100     var_name_arg.arg_repetition = eArgRepeatPlain;
1101 
1102     // There is only one variant this argument could be; put it into the argument entry.
1103     arg1.push_back (var_name_arg);
1104 
1105     // Define the first (and only) variant of this arg.
1106     value_arg.arg_type = eArgTypeValue;
1107     value_arg.arg_repetition = eArgRepeatPlain;
1108 
1109     // There is only one variant this argument could be; put it into the argument entry.
1110     arg2.push_back (value_arg);
1111 
1112     // Push the data for the first argument into the m_arguments vector.
1113     m_arguments.push_back (arg1);
1114     m_arguments.push_back (arg2);
1115 }
1116 
1117 CommandObjectSettingsAppend::~CommandObjectSettingsAppend ()
1118 {
1119 }
1120 
1121 bool
1122 CommandObjectSettingsAppend::ExecuteRawCommandString (const char *raw_command, CommandReturnObject &result)
1123 {
1124     UserSettingsControllerSP usc_sp (Debugger::GetSettingsController ());
1125 
1126     Args cmd_args(raw_command);
1127     const int argc = cmd_args.GetArgumentCount ();
1128 
1129     if (argc < 2)
1130     {
1131         result.AppendError ("'settings append' takes more arguments");
1132         result.SetStatus (eReturnStatusFailed);
1133         return false;
1134     }
1135 
1136     const char *var_name = cmd_args.GetArgumentAtIndex (0);
1137     std::string var_name_string;
1138     if ((var_name == NULL) || (var_name[0] == '\0'))
1139     {
1140         result.AppendError ("'settings append' command requires a valid variable name; No value supplied");
1141         result.SetStatus (eReturnStatusFailed);
1142         return false;
1143     }
1144 
1145     var_name_string = var_name;
1146     // Do not perform cmd_args.Shift() since StringRef is manipulating the
1147     // raw character string later on.
1148 
1149     // Split the raw command into var_name and value pair.
1150     llvm::StringRef raw_str(raw_command);
1151     llvm::StringRef var_value_str = raw_str.split(var_name).second;
1152     StripLeadingSpaces(var_value_str);
1153     std::string var_value_string = var_value_str.str();
1154 
1155     if (var_value_string.empty())
1156     {
1157         result.AppendError ("'settings append' command requires a valid variable value;"
1158                             " No value supplied");
1159         result.SetStatus (eReturnStatusFailed);
1160     }
1161     else
1162     {
1163         Error err = usc_sp->SetVariable (var_name_string.c_str(),
1164                                          var_value_string.c_str(),
1165                                          eVarSetOperationAppend,
1166                                          true,
1167                                          m_interpreter.GetDebugger().GetInstanceName().AsCString());
1168         if (err.Fail ())
1169         {
1170             result.AppendError (err.AsCString());
1171             result.SetStatus (eReturnStatusFailed);
1172         }
1173         else
1174             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1175     }
1176 
1177     return result.Succeeded();
1178 }
1179 
1180 
1181 int
1182 CommandObjectSettingsAppend::HandleArgumentCompletion (Args &input,
1183                                                        int &cursor_index,
1184                                                        int &cursor_char_position,
1185                                                        OptionElementVector &opt_element_vector,
1186                                                        int match_start_point,
1187                                                        int max_return_elements,
1188                                                        bool &word_complete,
1189                                                        StringList &matches)
1190 {
1191     std::string completion_str (input.GetArgumentAtIndex (cursor_index));
1192     completion_str.erase (cursor_char_position);
1193 
1194     // Attempting to complete variable name
1195     if (cursor_index < 2)
1196         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1197                                                              CommandCompletions::eSettingsNameCompletion,
1198                                                              completion_str.c_str(),
1199                                                              match_start_point,
1200                                                              max_return_elements,
1201                                                              NULL,
1202                                                              word_complete,
1203                                                              matches);
1204 
1205     return matches.GetSize();
1206 }
1207 
1208 //-------------------------------------------------------------------------
1209 // CommandObjectSettingsClear
1210 //-------------------------------------------------------------------------
1211 
1212 CommandObjectSettingsClear::CommandObjectSettingsClear (CommandInterpreter &interpreter) :
1213     CommandObject (interpreter,
1214                    "settings clear",
1215                    "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.",
1216                    NULL)
1217 {
1218     CommandArgumentEntry arg;
1219     CommandArgumentData var_name_arg;
1220 
1221     // Define the first (and only) variant of this arg.
1222     var_name_arg.arg_type = eArgTypeSettingVariableName;
1223     var_name_arg.arg_repetition = eArgRepeatPlain;
1224 
1225     // There is only one variant this argument could be; put it into the argument entry.
1226     arg.push_back (var_name_arg);
1227 
1228     // Push the data for the first argument into the m_arguments vector.
1229     m_arguments.push_back (arg);
1230 }
1231 
1232 CommandObjectSettingsClear::~CommandObjectSettingsClear ()
1233 {
1234 }
1235 
1236 bool
1237 CommandObjectSettingsClear::Execute (Args& command, CommandReturnObject &result)
1238 {
1239     UserSettingsControllerSP usc_sp (Debugger::GetSettingsController ());
1240 
1241     const int argc = command.GetArgumentCount ();
1242 
1243     if (argc != 1)
1244     {
1245         result.AppendError ("'setttings clear' takes exactly one argument");
1246         result.SetStatus (eReturnStatusFailed);
1247         return false;
1248     }
1249 
1250     const char *var_name = command.GetArgumentAtIndex (0);
1251     if ((var_name == NULL) || (var_name[0] == '\0'))
1252     {
1253         result.AppendError ("'settings clear' command requires a valid variable name; No value supplied");
1254         result.SetStatus (eReturnStatusFailed);
1255         return false;
1256     }
1257 
1258     Error err = usc_sp->SetVariable (var_name,
1259                                      NULL,
1260                                      eVarSetOperationClear,
1261                                      false,
1262                                      m_interpreter.GetDebugger().GetInstanceName().AsCString());
1263 
1264     if (err.Fail ())
1265     {
1266         result.AppendError (err.AsCString());
1267         result.SetStatus (eReturnStatusFailed);
1268     }
1269     else
1270         result.SetStatus (eReturnStatusSuccessFinishNoResult);
1271 
1272     return result.Succeeded();
1273 }
1274 
1275 
1276 int
1277 CommandObjectSettingsClear::HandleArgumentCompletion (Args &input,
1278                                                       int &cursor_index,
1279                                                       int &cursor_char_position,
1280                                                       OptionElementVector &opt_element_vector,
1281                                                       int match_start_point,
1282                                                       int max_return_elements,
1283                                                       bool &word_complete,
1284                                                       StringList &matches)
1285 {
1286     std::string completion_str (input.GetArgumentAtIndex (cursor_index));
1287     completion_str.erase (cursor_char_position);
1288 
1289     // Attempting to complete variable name
1290     if (cursor_index < 2)
1291         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1292                                                              CommandCompletions::eSettingsNameCompletion,
1293                                                              completion_str.c_str(),
1294                                                              match_start_point,
1295                                                              max_return_elements,
1296                                                              NULL,
1297                                                              word_complete,
1298                                                              matches);
1299 
1300     return matches.GetSize();
1301 }
1302