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