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