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