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 { LLDB_OPT_SET_2, false, "global", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Apply the new value to the global default value." }, 289 { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 290 }; 291 292 //------------------------------------------------------------------------- 293 // CommandObjectSettingsShow -- Show current values 294 //------------------------------------------------------------------------- 295 296 class CommandObjectSettingsShow : public CommandObjectParsed 297 { 298 public: 299 CommandObjectSettingsShow(CommandInterpreter &interpreter) 300 : CommandObjectParsed( 301 interpreter, "settings show", 302 "Show matching debugger settings and their current values. Defaults to showing all settings.", nullptr) 303 { 304 CommandArgumentEntry arg1; 305 CommandArgumentData var_name_arg; 306 307 // Define the first (and only) variant of this arg. 308 var_name_arg.arg_type = eArgTypeSettingVariableName; 309 var_name_arg.arg_repetition = eArgRepeatOptional; 310 311 // There is only one variant this argument could be; put it into the argument entry. 312 arg1.push_back (var_name_arg); 313 314 // Push the data for the first argument into the m_arguments vector. 315 m_arguments.push_back (arg1); 316 } 317 318 ~CommandObjectSettingsShow() override = default; 319 320 int 321 HandleArgumentCompletion (Args &input, 322 int &cursor_index, 323 int &cursor_char_position, 324 OptionElementVector &opt_element_vector, 325 int match_start_point, 326 int max_return_elements, 327 bool &word_complete, 328 StringList &matches) override 329 { 330 std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position); 331 332 CommandCompletions::InvokeCommonCompletionCallbacks(GetCommandInterpreter(), 333 CommandCompletions::eSettingsNameCompletion, 334 completion_str.c_str(), 335 match_start_point, 336 max_return_elements, 337 nullptr, 338 word_complete, 339 matches); 340 return matches.GetSize(); 341 } 342 343 protected: 344 bool 345 DoExecute (Args& args, CommandReturnObject &result) override 346 { 347 result.SetStatus (eReturnStatusSuccessFinishResult); 348 349 const size_t argc = args.GetArgumentCount (); 350 if (argc > 0) 351 { 352 for (size_t i = 0; i < argc; ++i) 353 { 354 const char *property_path = args.GetArgumentAtIndex (i); 355 356 Error error(m_interpreter.GetDebugger().DumpPropertyValue (&m_exe_ctx, result.GetOutputStream(), property_path, OptionValue::eDumpGroupValue)); 357 if (error.Success()) 358 { 359 result.GetOutputStream().EOL(); 360 } 361 else 362 { 363 result.AppendError (error.AsCString()); 364 result.SetStatus (eReturnStatusFailed); 365 } 366 } 367 } 368 else 369 { 370 m_interpreter.GetDebugger().DumpAllPropertyValues (&m_exe_ctx, result.GetOutputStream(), OptionValue::eDumpGroupValue); 371 } 372 373 return result.Succeeded(); 374 } 375 }; 376 377 //------------------------------------------------------------------------- 378 // CommandObjectSettingsList -- List settable variables 379 //------------------------------------------------------------------------- 380 381 class CommandObjectSettingsList : public CommandObjectParsed 382 { 383 public: 384 CommandObjectSettingsList(CommandInterpreter &interpreter) 385 : CommandObjectParsed(interpreter, "settings list", 386 "List and describe matching debugger settings. Defaults to all listing all settings.", 387 nullptr) 388 { 389 CommandArgumentEntry arg; 390 CommandArgumentData var_name_arg; 391 CommandArgumentData prefix_name_arg; 392 393 // Define the first variant of this arg. 394 var_name_arg.arg_type = eArgTypeSettingVariableName; 395 var_name_arg.arg_repetition = eArgRepeatOptional; 396 397 // Define the second variant of this arg. 398 prefix_name_arg.arg_type = eArgTypeSettingPrefix; 399 prefix_name_arg.arg_repetition = eArgRepeatOptional; 400 401 arg.push_back (var_name_arg); 402 arg.push_back (prefix_name_arg); 403 404 // Push the data for the first argument into the m_arguments vector. 405 m_arguments.push_back (arg); 406 } 407 408 ~CommandObjectSettingsList() override = default; 409 410 int 411 HandleArgumentCompletion (Args &input, 412 int &cursor_index, 413 int &cursor_char_position, 414 OptionElementVector &opt_element_vector, 415 int match_start_point, 416 int max_return_elements, 417 bool &word_complete, 418 StringList &matches) override 419 { 420 std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position); 421 422 CommandCompletions::InvokeCommonCompletionCallbacks(GetCommandInterpreter(), 423 CommandCompletions::eSettingsNameCompletion, 424 completion_str.c_str(), 425 match_start_point, 426 max_return_elements, 427 nullptr, 428 word_complete, 429 matches); 430 return matches.GetSize(); 431 } 432 433 protected: 434 bool 435 DoExecute (Args& args, CommandReturnObject &result) override 436 { 437 result.SetStatus (eReturnStatusSuccessFinishResult); 438 439 const bool will_modify = false; 440 const size_t argc = args.GetArgumentCount (); 441 if (argc > 0) 442 { 443 const bool dump_qualified_name = true; 444 445 for (size_t i = 0; i < argc; ++i) 446 { 447 const char *property_path = args.GetArgumentAtIndex (i); 448 449 const Property *property = m_interpreter.GetDebugger().GetValueProperties()->GetPropertyAtPath (&m_exe_ctx, will_modify, property_path); 450 451 if (property) 452 { 453 property->DumpDescription (m_interpreter, result.GetOutputStream(), 0, dump_qualified_name); 454 } 455 else 456 { 457 result.AppendErrorWithFormat ("invalid property path '%s'", property_path); 458 result.SetStatus (eReturnStatusFailed); 459 } 460 } 461 } 462 else 463 { 464 m_interpreter.GetDebugger().DumpAllDescriptions (m_interpreter, result.GetOutputStream()); 465 } 466 467 return result.Succeeded(); 468 } 469 }; 470 471 //------------------------------------------------------------------------- 472 // CommandObjectSettingsRemove 473 //------------------------------------------------------------------------- 474 475 class CommandObjectSettingsRemove : public CommandObjectRaw 476 { 477 public: 478 CommandObjectSettingsRemove(CommandInterpreter &interpreter) 479 : CommandObjectRaw(interpreter, "settings remove", 480 "Remove a value from a setting, specified by array index or dictionary key.", nullptr) 481 { 482 CommandArgumentEntry arg1; 483 CommandArgumentEntry arg2; 484 CommandArgumentData var_name_arg; 485 CommandArgumentData index_arg; 486 CommandArgumentData key_arg; 487 488 // Define the first (and only) variant of this arg. 489 var_name_arg.arg_type = eArgTypeSettingVariableName; 490 var_name_arg.arg_repetition = eArgRepeatPlain; 491 492 // There is only one variant this argument could be; put it into the argument entry. 493 arg1.push_back (var_name_arg); 494 495 // Define the first variant of this arg. 496 index_arg.arg_type = eArgTypeSettingIndex; 497 index_arg.arg_repetition = eArgRepeatPlain; 498 499 // Define the second variant of this arg. 500 key_arg.arg_type = eArgTypeSettingKey; 501 key_arg.arg_repetition = eArgRepeatPlain; 502 503 // Push both variants into this arg 504 arg2.push_back (index_arg); 505 arg2.push_back (key_arg); 506 507 // Push the data for the first argument into the m_arguments vector. 508 m_arguments.push_back (arg1); 509 m_arguments.push_back (arg2); 510 } 511 512 ~CommandObjectSettingsRemove() override = default; 513 514 int 515 HandleArgumentCompletion (Args &input, 516 int &cursor_index, 517 int &cursor_char_position, 518 OptionElementVector &opt_element_vector, 519 int match_start_point, 520 int max_return_elements, 521 bool &word_complete, 522 StringList &matches) override 523 { 524 std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position); 525 526 // Attempting to complete variable name 527 if (cursor_index < 2) 528 CommandCompletions::InvokeCommonCompletionCallbacks(GetCommandInterpreter(), 529 CommandCompletions::eSettingsNameCompletion, 530 completion_str.c_str(), 531 match_start_point, 532 max_return_elements, 533 nullptr, 534 word_complete, 535 matches); 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(GetCommandInterpreter(), 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(GetCommandInterpreter(), 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(GetCommandInterpreter(), 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(GetCommandInterpreter(), 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(GetCommandInterpreter(), 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