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