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 22using namespace lldb; 23using namespace lldb_private; 24#include "llvm/ADT/StringRef.h" 25 26//------------------------------------------------------------------------- 27// CommandObjectSettingsSet 28//------------------------------------------------------------------------- 29 30class CommandObjectSettingsSet : public CommandObjectRaw 31{ 32public: 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\ 65at 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\ 78Warning: The 'set' command re-sets the entire array or dictionary. If you \n\ 79just want to add, remove or update individual values (or add something to \n\ 80the end), use one of the other settings sub-commands: append, replace, \n\ 81insert-before or insert-after.\n"); 82 83 } 84 85 86 virtual 87 ~CommandObjectSettingsSet () {} 88 89 // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString. 90 virtual bool 91 WantsCompletion() { return true; } 92 93 virtual Options * 94 GetOptions () 95 { 96 return &m_options; 97 } 98 99 class CommandOptions : public Options 100 { 101 public: 102 103 CommandOptions (CommandInterpreter &interpreter) : 104 Options (interpreter), 105 m_global (false) 106 { 107 } 108 109 virtual 110 ~CommandOptions () {} 111 112 virtual Error 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 132 OptionParsingStarting () 133 { 134 m_global = false; 135 } 136 137 const OptionDefinition* 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 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 216protected: 217 virtual bool 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 } 284private: 285 CommandOptions m_options; 286}; 287 288OptionDefinition 289CommandObjectSettingsSet::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 300class CommandObjectSettingsShow : public CommandObjectParsed 301{ 302public: 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 324 ~CommandObjectSettingsShow () {} 325 326 327 virtual int 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 350protected: 351 virtual bool 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 388class CommandObjectSettingsList : public CommandObjectParsed 389{ 390public: 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 417 ~CommandObjectSettingsList () {} 418 419 virtual int 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 442protected: 443 virtual bool 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 484class CommandObjectSettingsRemove : public CommandObjectRaw 485{ 486public: 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 524 ~CommandObjectSettingsRemove () {} 525 526 virtual int 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 552protected: 553 virtual bool 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 604class CommandObjectSettingsReplace : public CommandObjectRaw 605{ 606public: 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 655 ~CommandObjectSettingsReplace () {} 656 657 // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString. 658 virtual bool 659 WantsCompletion() { return true; } 660 661 virtual int 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 687protected: 688 virtual bool 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 732class CommandObjectSettingsInsertBefore : public CommandObjectRaw 733{ 734public: 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 776 ~CommandObjectSettingsInsertBefore () {} 777 778 // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString. 779 virtual bool 780 WantsCompletion() { return true; } 781 782 virtual int 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 808protected: 809 virtual bool 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 856class CommandObjectSettingsInsertAfter : public CommandObjectRaw 857{ 858public: 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 900 ~CommandObjectSettingsInsertAfter () {} 901 902 // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString. 903 virtual bool 904 WantsCompletion() { return true; } 905 906 virtual int 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 932protected: 933 virtual bool 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 980class CommandObjectSettingsAppend : public CommandObjectRaw 981{ 982public: 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 1014 ~CommandObjectSettingsAppend () {} 1015 1016 // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString. 1017 virtual bool 1018 WantsCompletion() { return true; } 1019 1020 virtual int 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 1046protected: 1047 virtual bool 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 1096class CommandObjectSettingsClear : public CommandObjectParsed 1097{ 1098public: 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 1120 ~CommandObjectSettingsClear () {} 1121 1122 virtual int 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 1148protected: 1149 virtual bool 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 1189CommandObjectMultiwordSettings::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 1206CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings () 1207{ 1208} 1209