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