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