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