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