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