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