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