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