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