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