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