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