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