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