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