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