1 //===-- CommandObjectType.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 "lldb/lldb-python.h" 11 12 #include "CommandObjectType.h" 13 14 // C Includes 15 16 #include <ctype.h> 17 18 // C++ Includes 19 20 #include "lldb/Core/ConstString.h" 21 #include "lldb/Core/Debugger.h" 22 #include "lldb/Core/InputReaderEZ.h" 23 #include "lldb/Core/RegularExpression.h" 24 #include "lldb/Core/State.h" 25 #include "lldb/Core/StringList.h" 26 #include "lldb/DataFormatters/DataVisualization.h" 27 #include "lldb/Interpreter/CommandInterpreter.h" 28 #include "lldb/Interpreter/CommandObject.h" 29 #include "lldb/Interpreter/CommandReturnObject.h" 30 #include "lldb/Interpreter/Options.h" 31 #include "lldb/Interpreter/OptionGroupFormat.h" 32 33 using namespace lldb; 34 using namespace lldb_private; 35 36 37 class ScriptAddOptions 38 { 39 40 public: 41 42 TypeSummaryImpl::Flags m_flags; 43 44 StringList m_target_types; 45 StringList m_user_source; 46 47 bool m_regex; 48 49 ConstString m_name; 50 51 std::string m_category; 52 53 ScriptAddOptions(const TypeSummaryImpl::Flags& flags, 54 bool regx, 55 const ConstString& name, 56 std::string catg) : 57 m_flags(flags), 58 m_regex(regx), 59 m_name(name), 60 m_category(catg) 61 { 62 } 63 64 typedef std::shared_ptr<ScriptAddOptions> SharedPointer; 65 66 }; 67 68 class SynthAddOptions 69 { 70 71 public: 72 73 bool m_skip_pointers; 74 bool m_skip_references; 75 bool m_cascade; 76 bool m_regex; 77 StringList m_user_source; 78 StringList m_target_types; 79 80 std::string m_category; 81 82 SynthAddOptions(bool sptr, 83 bool sref, 84 bool casc, 85 bool regx, 86 std::string catg) : 87 m_skip_pointers(sptr), 88 m_skip_references(sref), 89 m_cascade(casc), 90 m_regex(regx), 91 m_user_source(), 92 m_target_types(), 93 m_category(catg) 94 { 95 } 96 97 typedef std::shared_ptr<SynthAddOptions> SharedPointer; 98 99 }; 100 101 102 103 class CommandObjectTypeSummaryAdd : public CommandObjectParsed 104 { 105 106 private: 107 108 class CommandOptions : public Options 109 { 110 public: 111 112 CommandOptions (CommandInterpreter &interpreter) : 113 Options (interpreter) 114 { 115 } 116 117 virtual 118 ~CommandOptions (){} 119 120 virtual Error 121 SetOptionValue (uint32_t option_idx, const char *option_arg); 122 123 void 124 OptionParsingStarting (); 125 126 const OptionDefinition* 127 GetDefinitions () 128 { 129 return g_option_table; 130 } 131 132 // Options table: Required for subclasses of Options. 133 134 static OptionDefinition g_option_table[]; 135 136 // Instance variables to hold the values for command options. 137 138 TypeSummaryImpl::Flags m_flags; 139 bool m_regex; 140 std::string m_format_string; 141 ConstString m_name; 142 std::string m_python_script; 143 std::string m_python_function; 144 bool m_is_add_script; 145 std::string m_category; 146 }; 147 148 CommandOptions m_options; 149 150 virtual Options * 151 GetOptions () 152 { 153 return &m_options; 154 } 155 156 void 157 CollectPythonScript(ScriptAddOptions *options, 158 CommandReturnObject &result); 159 160 bool 161 Execute_ScriptSummary (Args& command, CommandReturnObject &result); 162 163 bool 164 Execute_StringSummary (Args& command, CommandReturnObject &result); 165 166 public: 167 168 enum SummaryFormatType 169 { 170 eRegularSummary, 171 eRegexSummary, 172 eNamedSummary 173 }; 174 175 CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter); 176 177 ~CommandObjectTypeSummaryAdd () 178 { 179 } 180 181 static bool 182 AddSummary(ConstString type_name, 183 lldb::TypeSummaryImplSP entry, 184 SummaryFormatType type, 185 std::string category, 186 Error* error = NULL); 187 protected: 188 bool 189 DoExecute (Args& command, CommandReturnObject &result); 190 191 }; 192 193 class CommandObjectTypeSynthAdd : public CommandObjectParsed 194 { 195 196 private: 197 198 class CommandOptions : public Options 199 { 200 public: 201 202 CommandOptions (CommandInterpreter &interpreter) : 203 Options (interpreter) 204 { 205 } 206 207 virtual 208 ~CommandOptions (){} 209 210 virtual Error 211 SetOptionValue (uint32_t option_idx, const char *option_arg) 212 { 213 Error error; 214 const int short_option = m_getopt_table[option_idx].val; 215 bool success; 216 217 switch (short_option) 218 { 219 case 'C': 220 m_cascade = Args::StringToBoolean(option_arg, true, &success); 221 if (!success) 222 error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg); 223 break; 224 case 'P': 225 handwrite_python = true; 226 break; 227 case 'l': 228 m_class_name = std::string(option_arg); 229 is_class_based = true; 230 break; 231 case 'p': 232 m_skip_pointers = true; 233 break; 234 case 'r': 235 m_skip_references = true; 236 break; 237 case 'w': 238 m_category = std::string(option_arg); 239 break; 240 case 'x': 241 m_regex = true; 242 break; 243 default: 244 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 245 break; 246 } 247 248 return error; 249 } 250 251 void 252 OptionParsingStarting () 253 { 254 m_cascade = true; 255 m_class_name = ""; 256 m_skip_pointers = false; 257 m_skip_references = false; 258 m_category = "default"; 259 is_class_based = false; 260 handwrite_python = false; 261 m_regex = false; 262 } 263 264 const OptionDefinition* 265 GetDefinitions () 266 { 267 return g_option_table; 268 } 269 270 // Options table: Required for subclasses of Options. 271 272 static OptionDefinition g_option_table[]; 273 274 // Instance variables to hold the values for command options. 275 276 bool m_cascade; 277 bool m_skip_references; 278 bool m_skip_pointers; 279 std::string m_class_name; 280 bool m_input_python; 281 std::string m_category; 282 283 bool is_class_based; 284 285 bool handwrite_python; 286 287 bool m_regex; 288 289 }; 290 291 CommandOptions m_options; 292 293 virtual Options * 294 GetOptions () 295 { 296 return &m_options; 297 } 298 299 void 300 CollectPythonScript (SynthAddOptions *options, 301 CommandReturnObject &result); 302 bool 303 Execute_HandwritePython (Args& command, CommandReturnObject &result); 304 305 bool 306 Execute_PythonClass (Args& command, CommandReturnObject &result); 307 308 protected: 309 bool 310 DoExecute (Args& command, CommandReturnObject &result); 311 312 public: 313 314 enum SynthFormatType 315 { 316 eRegularSynth, 317 eRegexSynth 318 }; 319 320 CommandObjectTypeSynthAdd (CommandInterpreter &interpreter); 321 322 ~CommandObjectTypeSynthAdd () 323 { 324 } 325 326 static bool 327 AddSynth(ConstString type_name, 328 lldb::SyntheticChildrenSP entry, 329 SynthFormatType type, 330 std::string category_name, 331 Error* error); 332 }; 333 334 //------------------------------------------------------------------------- 335 // CommandObjectTypeFormatAdd 336 //------------------------------------------------------------------------- 337 338 class CommandObjectTypeFormatAdd : public CommandObjectParsed 339 { 340 341 private: 342 343 class CommandOptions : public OptionGroup 344 { 345 public: 346 347 CommandOptions () : 348 OptionGroup() 349 { 350 } 351 352 virtual 353 ~CommandOptions () 354 { 355 } 356 357 virtual uint32_t 358 GetNumDefinitions (); 359 360 virtual const OptionDefinition* 361 GetDefinitions () 362 { 363 return g_option_table; 364 } 365 366 virtual void 367 OptionParsingStarting (CommandInterpreter &interpreter) 368 { 369 m_cascade = true; 370 m_skip_pointers = false; 371 m_skip_references = false; 372 m_regex = false; 373 m_category.assign("default"); 374 m_custom_type_name.clear(); 375 } 376 virtual Error 377 SetOptionValue (CommandInterpreter &interpreter, 378 uint32_t option_idx, 379 const char *option_value) 380 { 381 Error error; 382 const int short_option = g_option_table[option_idx].short_option; 383 bool success; 384 385 switch (short_option) 386 { 387 case 'C': 388 m_cascade = Args::StringToBoolean(option_value, true, &success); 389 if (!success) 390 error.SetErrorStringWithFormat("invalid value for cascade: %s", option_value); 391 break; 392 case 'p': 393 m_skip_pointers = true; 394 break; 395 case 'w': 396 m_category.assign(option_value); 397 break; 398 case 'r': 399 m_skip_references = true; 400 break; 401 case 'x': 402 m_regex = true; 403 break; 404 case 't': 405 m_custom_type_name.assign(option_value); 406 break; 407 default: 408 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 409 break; 410 } 411 412 return error; 413 } 414 415 // Options table: Required for subclasses of Options. 416 417 static OptionDefinition g_option_table[]; 418 419 // Instance variables to hold the values for command options. 420 421 bool m_cascade; 422 bool m_skip_references; 423 bool m_skip_pointers; 424 bool m_regex; 425 std::string m_category; 426 std::string m_custom_type_name; 427 }; 428 429 OptionGroupOptions m_option_group; 430 OptionGroupFormat m_format_options; 431 CommandOptions m_command_options; 432 433 virtual Options * 434 GetOptions () 435 { 436 return &m_option_group; 437 } 438 439 public: 440 CommandObjectTypeFormatAdd (CommandInterpreter &interpreter) : 441 CommandObjectParsed (interpreter, 442 "type format add", 443 "Add a new formatting style for a type.", 444 NULL), 445 m_option_group (interpreter), 446 m_format_options (eFormatInvalid), 447 m_command_options () 448 { 449 CommandArgumentEntry type_arg; 450 CommandArgumentData type_style_arg; 451 452 type_style_arg.arg_type = eArgTypeName; 453 type_style_arg.arg_repetition = eArgRepeatPlus; 454 455 type_arg.push_back (type_style_arg); 456 457 m_arguments.push_back (type_arg); 458 459 SetHelpLong( 460 "Some examples of using this command.\n" 461 "We use as reference the following snippet of code:\n" 462 "\n" 463 "typedef int Aint;\n" 464 "typedef float Afloat;\n" 465 "typedef Aint Bint;\n" 466 "typedef Afloat Bfloat;\n" 467 "\n" 468 "Aint ix = 5;\n" 469 "Bint iy = 5;\n" 470 "\n" 471 "Afloat fx = 3.14;\n" 472 "BFloat fy = 3.14;\n" 473 "\n" 474 "Typing:\n" 475 "type format add -f hex AInt\n" 476 "frame variable iy\n" 477 "will produce an hex display of iy, because no formatter is available for Bint and the one for Aint is used instead\n" 478 "To prevent this type\n" 479 "type format add -f hex -C no AInt\n" 480 "\n" 481 "A similar reasoning applies to\n" 482 "type format add -f hex -C no float -p\n" 483 "which now prints all floats and float&s as hexadecimal, but does not format float*s\n" 484 "and does not change the default display for Afloat and Bfloat objects.\n" 485 ); 486 487 // Add the "--format" to all options groups 488 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1); 489 m_option_group.Append (&m_command_options); 490 m_option_group.Finalize(); 491 492 } 493 494 ~CommandObjectTypeFormatAdd () 495 { 496 } 497 498 protected: 499 bool 500 DoExecute (Args& command, CommandReturnObject &result) 501 { 502 const size_t argc = command.GetArgumentCount(); 503 504 if (argc < 1) 505 { 506 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); 507 result.SetStatus(eReturnStatusFailed); 508 return false; 509 } 510 511 const Format format = m_format_options.GetFormat(); 512 if (format == eFormatInvalid && m_command_options.m_custom_type_name.empty()) 513 { 514 result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str()); 515 result.SetStatus(eReturnStatusFailed); 516 return false; 517 } 518 519 TypeFormatImplSP entry; 520 521 if (m_command_options.m_custom_type_name.empty()) 522 entry.reset(new TypeFormatImpl_Format(format, 523 TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade). 524 SetSkipPointers(m_command_options.m_skip_pointers). 525 SetSkipReferences(m_command_options.m_skip_references))); 526 else 527 entry.reset(new TypeFormatImpl_EnumType(ConstString(m_command_options.m_custom_type_name.c_str()), 528 TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade). 529 SetSkipPointers(m_command_options.m_skip_pointers). 530 SetSkipReferences(m_command_options.m_skip_references))); 531 532 // now I have a valid format, let's add it to every type 533 534 TypeCategoryImplSP category_sp; 535 DataVisualization::Categories::GetCategory(ConstString(m_command_options.m_category), category_sp); 536 if (!category_sp) 537 return false; 538 539 for (size_t i = 0; i < argc; i++) 540 { 541 const char* typeA = command.GetArgumentAtIndex(i); 542 ConstString typeCS(typeA); 543 if (typeCS) 544 { 545 if (m_command_options.m_regex) 546 { 547 RegularExpressionSP typeRX(new RegularExpression()); 548 if (!typeRX->Compile(typeCS.GetCString())) 549 { 550 result.AppendError("regex format error (maybe this is not really a regex?)"); 551 result.SetStatus(eReturnStatusFailed); 552 return false; 553 } 554 category_sp->GetRegexTypeSummariesContainer()->Delete(typeCS); 555 category_sp->GetRegexTypeFormatsContainer()->Add(typeRX, entry); 556 } 557 else 558 category_sp->GetTypeFormatsContainer()->Add(typeCS, entry); 559 } 560 else 561 { 562 result.AppendError("empty typenames not allowed"); 563 result.SetStatus(eReturnStatusFailed); 564 return false; 565 } 566 } 567 568 result.SetStatus(eReturnStatusSuccessFinishNoResult); 569 return result.Succeeded(); 570 } 571 }; 572 573 OptionDefinition 574 CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] = 575 { 576 { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, 577 { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, 578 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, 579 { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, 580 { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, 581 { LLDB_OPT_SET_2, false, "type", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Format variables as if they were of this type."}, 582 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 583 }; 584 585 586 uint32_t 587 CommandObjectTypeFormatAdd::CommandOptions::GetNumDefinitions () 588 { 589 return sizeof(g_option_table) / sizeof (OptionDefinition); 590 } 591 592 593 //------------------------------------------------------------------------- 594 // CommandObjectTypeFormatDelete 595 //------------------------------------------------------------------------- 596 597 class CommandObjectTypeFormatDelete : public CommandObjectParsed 598 { 599 private: 600 class CommandOptions : public Options 601 { 602 public: 603 604 CommandOptions (CommandInterpreter &interpreter) : 605 Options (interpreter) 606 { 607 } 608 609 virtual 610 ~CommandOptions (){} 611 612 virtual Error 613 SetOptionValue (uint32_t option_idx, const char *option_arg) 614 { 615 Error error; 616 const int short_option = m_getopt_table[option_idx].val; 617 618 switch (short_option) 619 { 620 case 'a': 621 m_delete_all = true; 622 break; 623 case 'w': 624 m_category = std::string(option_arg); 625 break; 626 default: 627 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 628 break; 629 } 630 631 return error; 632 } 633 634 void 635 OptionParsingStarting () 636 { 637 m_delete_all = false; 638 m_category = "default"; 639 } 640 641 const OptionDefinition* 642 GetDefinitions () 643 { 644 return g_option_table; 645 } 646 647 // Options table: Required for subclasses of Options. 648 649 static OptionDefinition g_option_table[]; 650 651 // Instance variables to hold the values for command options. 652 653 bool m_delete_all; 654 std::string m_category; 655 656 }; 657 658 CommandOptions m_options; 659 660 virtual Options * 661 GetOptions () 662 { 663 return &m_options; 664 } 665 666 static bool 667 PerCategoryCallback(void* param, 668 const lldb::TypeCategoryImplSP& category_sp) 669 { 670 ConstString *name = (ConstString*)param; 671 category_sp->Delete(*name, eFormatCategoryItemValue | eFormatCategoryItemRegexValue); 672 return true; 673 } 674 675 public: 676 CommandObjectTypeFormatDelete (CommandInterpreter &interpreter) : 677 CommandObjectParsed (interpreter, 678 "type format delete", 679 "Delete an existing formatting style for a type.", 680 NULL), 681 m_options(interpreter) 682 { 683 CommandArgumentEntry type_arg; 684 CommandArgumentData type_style_arg; 685 686 type_style_arg.arg_type = eArgTypeName; 687 type_style_arg.arg_repetition = eArgRepeatPlain; 688 689 type_arg.push_back (type_style_arg); 690 691 m_arguments.push_back (type_arg); 692 693 } 694 695 ~CommandObjectTypeFormatDelete () 696 { 697 } 698 699 protected: 700 bool 701 DoExecute (Args& command, CommandReturnObject &result) 702 { 703 const size_t argc = command.GetArgumentCount(); 704 705 if (argc != 1) 706 { 707 result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); 708 result.SetStatus(eReturnStatusFailed); 709 return false; 710 } 711 712 const char* typeA = command.GetArgumentAtIndex(0); 713 ConstString typeCS(typeA); 714 715 if (!typeCS) 716 { 717 result.AppendError("empty typenames not allowed"); 718 result.SetStatus(eReturnStatusFailed); 719 return false; 720 } 721 722 if (m_options.m_delete_all) 723 { 724 DataVisualization::Categories::LoopThrough(PerCategoryCallback, &typeCS); 725 result.SetStatus(eReturnStatusSuccessFinishNoResult); 726 return result.Succeeded(); 727 } 728 729 lldb::TypeCategoryImplSP category; 730 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 731 732 bool delete_category = category->Delete(typeCS, 733 eFormatCategoryItemValue | eFormatCategoryItemRegexValue); 734 735 if (delete_category) 736 { 737 result.SetStatus(eReturnStatusSuccessFinishNoResult); 738 return result.Succeeded(); 739 } 740 else 741 { 742 result.AppendErrorWithFormat ("no custom format for %s.\n", typeA); 743 result.SetStatus(eReturnStatusFailed); 744 return false; 745 } 746 747 } 748 749 }; 750 751 OptionDefinition 752 CommandObjectTypeFormatDelete::CommandOptions::g_option_table[] = 753 { 754 { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Delete from every category."}, 755 { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Delete from given category."}, 756 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 757 }; 758 759 //------------------------------------------------------------------------- 760 // CommandObjectTypeFormatClear 761 //------------------------------------------------------------------------- 762 763 class CommandObjectTypeFormatClear : public CommandObjectParsed 764 { 765 private: 766 767 class CommandOptions : public Options 768 { 769 public: 770 771 CommandOptions (CommandInterpreter &interpreter) : 772 Options (interpreter) 773 { 774 } 775 776 virtual 777 ~CommandOptions (){} 778 779 virtual Error 780 SetOptionValue (uint32_t option_idx, const char *option_arg) 781 { 782 Error error; 783 const int short_option = m_getopt_table[option_idx].val; 784 785 switch (short_option) 786 { 787 case 'a': 788 m_delete_all = true; 789 break; 790 default: 791 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 792 break; 793 } 794 795 return error; 796 } 797 798 void 799 OptionParsingStarting () 800 { 801 m_delete_all = false; 802 } 803 804 const OptionDefinition* 805 GetDefinitions () 806 { 807 return g_option_table; 808 } 809 810 // Options table: Required for subclasses of Options. 811 812 static OptionDefinition g_option_table[]; 813 814 // Instance variables to hold the values for command options. 815 816 bool m_delete_all; 817 bool m_delete_named; 818 }; 819 820 CommandOptions m_options; 821 822 virtual Options * 823 GetOptions () 824 { 825 return &m_options; 826 } 827 828 static bool 829 PerCategoryCallback(void* param, 830 const lldb::TypeCategoryImplSP& cate) 831 { 832 cate->GetTypeFormatsContainer()->Clear(); 833 cate->GetRegexTypeFormatsContainer()->Clear(); 834 return true; 835 836 } 837 838 public: 839 CommandObjectTypeFormatClear (CommandInterpreter &interpreter) : 840 CommandObjectParsed (interpreter, 841 "type format clear", 842 "Delete all existing format styles.", 843 NULL), 844 m_options(interpreter) 845 { 846 } 847 848 ~CommandObjectTypeFormatClear () 849 { 850 } 851 852 protected: 853 bool 854 DoExecute (Args& command, CommandReturnObject &result) 855 { 856 if (m_options.m_delete_all) 857 DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL); 858 859 else 860 { 861 lldb::TypeCategoryImplSP category; 862 if (command.GetArgumentCount() > 0) 863 { 864 const char* cat_name = command.GetArgumentAtIndex(0); 865 ConstString cat_nameCS(cat_name); 866 DataVisualization::Categories::GetCategory(cat_nameCS, category); 867 } 868 else 869 DataVisualization::Categories::GetCategory(ConstString(NULL), category); 870 category->Clear(eFormatCategoryItemValue | eFormatCategoryItemRegexValue); 871 } 872 873 result.SetStatus(eReturnStatusSuccessFinishResult); 874 return result.Succeeded(); 875 } 876 877 }; 878 879 OptionDefinition 880 CommandObjectTypeFormatClear::CommandOptions::g_option_table[] = 881 { 882 { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Clear every category."}, 883 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 884 }; 885 886 //------------------------------------------------------------------------- 887 // CommandObjectTypeFormatList 888 //------------------------------------------------------------------------- 889 890 bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeFormatImplSP& entry); 891 bool CommandObjectTypeRXFormatList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeFormatImplSP& entry); 892 893 class CommandObjectTypeFormatList; 894 895 struct CommandObjectTypeFormatList_LoopCallbackParam { 896 CommandObjectTypeFormatList* self; 897 CommandReturnObject* result; 898 RegularExpression* regex; 899 RegularExpression* cate_regex; 900 CommandObjectTypeFormatList_LoopCallbackParam(CommandObjectTypeFormatList* S, CommandReturnObject* R, 901 RegularExpression* X = NULL, RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {} 902 }; 903 904 class CommandObjectTypeFormatList : public CommandObjectParsed 905 { 906 class CommandOptions : public Options 907 { 908 public: 909 910 CommandOptions (CommandInterpreter &interpreter) : 911 Options (interpreter) 912 { 913 } 914 915 virtual 916 ~CommandOptions (){} 917 918 virtual Error 919 SetOptionValue (uint32_t option_idx, const char *option_arg) 920 { 921 Error error; 922 const int short_option = m_getopt_table[option_idx].val; 923 924 switch (short_option) 925 { 926 case 'w': 927 m_category_regex = std::string(option_arg); 928 break; 929 default: 930 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 931 break; 932 } 933 934 return error; 935 } 936 937 void 938 OptionParsingStarting () 939 { 940 m_category_regex = ""; 941 } 942 943 const OptionDefinition* 944 GetDefinitions () 945 { 946 return g_option_table; 947 } 948 949 // Options table: Required for subclasses of Options. 950 951 static OptionDefinition g_option_table[]; 952 953 // Instance variables to hold the values for command options. 954 955 std::string m_category_regex; 956 957 }; 958 959 CommandOptions m_options; 960 961 virtual Options * 962 GetOptions () 963 { 964 return &m_options; 965 } 966 967 public: 968 CommandObjectTypeFormatList (CommandInterpreter &interpreter) : 969 CommandObjectParsed (interpreter, 970 "type format list", 971 "Show a list of current formatting styles.", 972 NULL), 973 m_options(interpreter) 974 { 975 CommandArgumentEntry type_arg; 976 CommandArgumentData type_style_arg; 977 978 type_style_arg.arg_type = eArgTypeName; 979 type_style_arg.arg_repetition = eArgRepeatOptional; 980 981 type_arg.push_back (type_style_arg); 982 983 m_arguments.push_back (type_arg); 984 } 985 986 ~CommandObjectTypeFormatList () 987 { 988 } 989 990 protected: 991 bool 992 DoExecute (Args& command, CommandReturnObject &result) 993 { 994 const size_t argc = command.GetArgumentCount(); 995 996 CommandObjectTypeFormatList_LoopCallbackParam *param; 997 RegularExpression* cate_regex = 998 m_options.m_category_regex.empty() ? NULL : 999 new RegularExpression(m_options.m_category_regex.c_str()); 1000 1001 if (argc == 1) 1002 { 1003 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); 1004 regex->Compile(command.GetArgumentAtIndex(0)); 1005 param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,regex,cate_regex); 1006 } 1007 else 1008 param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,NULL,cate_regex); 1009 1010 DataVisualization::Categories::LoopThrough(PerCategoryCallback,param); 1011 delete param; 1012 1013 if (cate_regex) 1014 delete cate_regex; 1015 1016 result.SetStatus(eReturnStatusSuccessFinishResult); 1017 return result.Succeeded(); 1018 } 1019 1020 private: 1021 1022 static bool 1023 PerCategoryCallback(void* param_vp, 1024 const lldb::TypeCategoryImplSP& cate) 1025 { 1026 1027 CommandObjectTypeFormatList_LoopCallbackParam* param = 1028 (CommandObjectTypeFormatList_LoopCallbackParam*)param_vp; 1029 CommandReturnObject* result = param->result; 1030 1031 const char* cate_name = cate->GetName(); 1032 1033 // if the category is disabled or empty and there is no regex, just skip it 1034 if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemValue | eFormatCategoryItemRegexValue) == 0) && param->cate_regex == NULL) 1035 return true; 1036 1037 // if we have a regex and this category does not match it, just skip it 1038 if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false) 1039 return true; 1040 1041 result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n", 1042 cate_name, 1043 (cate->IsEnabled() ? "enabled" : "disabled")); 1044 1045 cate->GetTypeFormatsContainer()->LoopThrough(CommandObjectTypeFormatList_LoopCallback, param_vp); 1046 1047 if (cate->GetRegexTypeSummariesContainer()->GetCount() > 0) 1048 { 1049 result->GetOutputStream().Printf("Regex-based summaries (slower):\n"); 1050 cate->GetRegexTypeFormatsContainer()->LoopThrough(CommandObjectTypeRXFormatList_LoopCallback, param_vp); 1051 } 1052 return true; 1053 } 1054 1055 1056 bool 1057 LoopCallback (const char* type, 1058 const lldb::TypeFormatImplSP& entry, 1059 RegularExpression* regex, 1060 CommandReturnObject *result) 1061 { 1062 if (regex == NULL || strcmp(type,regex->GetText()) == 0 || regex->Execute(type)) 1063 result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str()); 1064 return true; 1065 } 1066 1067 friend bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeFormatImplSP& entry); 1068 friend bool CommandObjectTypeRXFormatList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeFormatImplSP& entry); 1069 1070 }; 1071 1072 bool 1073 CommandObjectTypeFormatList_LoopCallback ( 1074 void* pt2self, 1075 ConstString type, 1076 const lldb::TypeFormatImplSP& entry) 1077 { 1078 CommandObjectTypeFormatList_LoopCallbackParam* param = (CommandObjectTypeFormatList_LoopCallbackParam*)pt2self; 1079 return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result); 1080 } 1081 1082 bool 1083 CommandObjectTypeRXFormatList_LoopCallback ( 1084 void* pt2self, 1085 lldb::RegularExpressionSP regex, 1086 const lldb::TypeFormatImplSP& entry) 1087 { 1088 CommandObjectTypeFormatList_LoopCallbackParam* param = (CommandObjectTypeFormatList_LoopCallbackParam*)pt2self; 1089 return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); 1090 } 1091 1092 OptionDefinition 1093 CommandObjectTypeFormatList::CommandOptions::g_option_table[] = 1094 { 1095 { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, 1096 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1097 }; 1098 1099 #ifndef LLDB_DISABLE_PYTHON 1100 1101 //------------------------------------------------------------------------- 1102 // CommandObjectTypeSummaryAdd 1103 //------------------------------------------------------------------------- 1104 1105 static const char *g_summary_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n" 1106 "def function (valobj,internal_dict):\n" 1107 " \"\"\"valobj: an SBValue which you want to provide a summary for\n" 1108 " internal_dict: an LLDB support object not to be used\"\"\""; 1109 1110 class TypeScriptAddInputReader : public InputReaderEZ 1111 { 1112 private: 1113 DISALLOW_COPY_AND_ASSIGN (TypeScriptAddInputReader); 1114 public: 1115 TypeScriptAddInputReader(Debugger& debugger) : 1116 InputReaderEZ(debugger) 1117 {} 1118 1119 virtual 1120 ~TypeScriptAddInputReader() 1121 { 1122 } 1123 1124 virtual void ActivateHandler(HandlerData& data) 1125 { 1126 StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream(); 1127 bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); 1128 if (!batch_mode) 1129 { 1130 out_stream->Printf ("%s\n", g_summary_addreader_instructions); 1131 if (data.reader.GetPrompt()) 1132 out_stream->Printf ("%s", data.reader.GetPrompt()); 1133 out_stream->Flush(); 1134 } 1135 } 1136 1137 virtual void ReactivateHandler(HandlerData& data) 1138 { 1139 StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream(); 1140 bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); 1141 if (data.reader.GetPrompt() && !batch_mode) 1142 { 1143 out_stream->Printf ("%s", data.reader.GetPrompt()); 1144 out_stream->Flush(); 1145 } 1146 } 1147 virtual void GotTokenHandler(HandlerData& data) 1148 { 1149 StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream(); 1150 bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); 1151 if (data.bytes && data.bytes_len && data.baton) 1152 { 1153 ((ScriptAddOptions*)data.baton)->m_user_source.AppendString(data.bytes, data.bytes_len); 1154 } 1155 if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode) 1156 { 1157 out_stream->Printf ("%s", data.reader.GetPrompt()); 1158 out_stream->Flush(); 1159 } 1160 } 1161 virtual void InterruptHandler(HandlerData& data) 1162 { 1163 StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream(); 1164 bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); 1165 data.reader.SetIsDone (true); 1166 if (!batch_mode) 1167 { 1168 out_stream->Printf ("Warning: No command attached to breakpoint.\n"); 1169 out_stream->Flush(); 1170 } 1171 } 1172 virtual void EOFHandler(HandlerData& data) 1173 { 1174 data.reader.SetIsDone (true); 1175 } 1176 virtual void DoneHandler(HandlerData& data) 1177 { 1178 StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream(); 1179 ScriptAddOptions *options_ptr = ((ScriptAddOptions*)data.baton); 1180 if (!options_ptr) 1181 { 1182 out_stream->Printf ("internal synchronization information missing or invalid.\n"); 1183 out_stream->Flush(); 1184 return; 1185 } 1186 1187 ScriptAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope 1188 1189 ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 1190 if (!interpreter) 1191 { 1192 out_stream->Printf ("no script interpreter.\n"); 1193 out_stream->Flush(); 1194 return; 1195 } 1196 std::string funct_name_str; 1197 if (!interpreter->GenerateTypeScriptFunction (options->m_user_source, 1198 funct_name_str)) 1199 { 1200 out_stream->Printf ("unable to generate a function.\n"); 1201 out_stream->Flush(); 1202 return; 1203 } 1204 if (funct_name_str.empty()) 1205 { 1206 out_stream->Printf ("unable to obtain a valid function name from the script interpreter.\n"); 1207 out_stream->Flush(); 1208 return; 1209 } 1210 // now I have a valid function name, let's add this as script for every type in the list 1211 1212 TypeSummaryImplSP script_format; 1213 script_format.reset(new ScriptSummaryFormat(options->m_flags, 1214 funct_name_str.c_str(), 1215 options->m_user_source.CopyList(" ").c_str())); 1216 1217 Error error; 1218 1219 for (size_t i = 0; i < options->m_target_types.GetSize(); i++) 1220 { 1221 const char *type_name = options->m_target_types.GetStringAtIndex(i); 1222 CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name), 1223 script_format, 1224 (options->m_regex ? CommandObjectTypeSummaryAdd::eRegexSummary : CommandObjectTypeSummaryAdd::eRegularSummary), 1225 options->m_category, 1226 &error); 1227 if (error.Fail()) 1228 { 1229 out_stream->Printf ("%s", error.AsCString()); 1230 out_stream->Flush(); 1231 return; 1232 } 1233 } 1234 1235 if (options->m_name) 1236 { 1237 CommandObjectTypeSummaryAdd::AddSummary (options->m_name, 1238 script_format, 1239 CommandObjectTypeSummaryAdd::eNamedSummary, 1240 options->m_category, 1241 &error); 1242 if (error.Fail()) 1243 { 1244 CommandObjectTypeSummaryAdd::AddSummary (options->m_name, 1245 script_format, 1246 CommandObjectTypeSummaryAdd::eNamedSummary, 1247 options->m_category, 1248 &error); 1249 if (error.Fail()) 1250 { 1251 out_stream->Printf ("%s", error.AsCString()); 1252 out_stream->Flush(); 1253 return; 1254 } 1255 } 1256 else 1257 { 1258 out_stream->Printf ("%s", error.AsCString()); 1259 out_stream->Flush(); 1260 return; 1261 } 1262 } 1263 else 1264 { 1265 if (error.AsCString()) 1266 { 1267 out_stream->PutCString (error.AsCString()); 1268 out_stream->Flush(); 1269 } 1270 return; 1271 } 1272 } 1273 }; 1274 1275 #endif // #ifndef LLDB_DISABLE_PYTHON 1276 1277 Error 1278 CommandObjectTypeSummaryAdd::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg) 1279 { 1280 Error error; 1281 const int short_option = m_getopt_table[option_idx].val; 1282 bool success; 1283 1284 switch (short_option) 1285 { 1286 case 'C': 1287 m_flags.SetCascades(Args::StringToBoolean(option_arg, true, &success)); 1288 if (!success) 1289 error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg); 1290 break; 1291 case 'e': 1292 m_flags.SetDontShowChildren(false); 1293 break; 1294 case 'v': 1295 m_flags.SetDontShowValue(true); 1296 break; 1297 case 'c': 1298 m_flags.SetShowMembersOneLiner(true); 1299 break; 1300 case 's': 1301 m_format_string = std::string(option_arg); 1302 break; 1303 case 'p': 1304 m_flags.SetSkipPointers(true); 1305 break; 1306 case 'r': 1307 m_flags.SetSkipReferences(true); 1308 break; 1309 case 'x': 1310 m_regex = true; 1311 break; 1312 case 'n': 1313 m_name.SetCString(option_arg); 1314 break; 1315 case 'o': 1316 m_python_script = std::string(option_arg); 1317 m_is_add_script = true; 1318 break; 1319 case 'F': 1320 m_python_function = std::string(option_arg); 1321 m_is_add_script = true; 1322 break; 1323 case 'P': 1324 m_is_add_script = true; 1325 break; 1326 case 'w': 1327 m_category = std::string(option_arg); 1328 break; 1329 case 'O': 1330 m_flags.SetHideItemNames(true); 1331 break; 1332 default: 1333 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1334 break; 1335 } 1336 1337 return error; 1338 } 1339 1340 void 1341 CommandObjectTypeSummaryAdd::CommandOptions::OptionParsingStarting () 1342 { 1343 m_flags.Clear().SetCascades().SetDontShowChildren().SetDontShowValue(false); 1344 m_flags.SetShowMembersOneLiner(false).SetSkipPointers(false).SetSkipReferences(false).SetHideItemNames(false); 1345 1346 m_regex = false; 1347 m_name.Clear(); 1348 m_python_script = ""; 1349 m_python_function = ""; 1350 m_format_string = ""; 1351 m_is_add_script = false; 1352 m_category = "default"; 1353 } 1354 1355 #ifndef LLDB_DISABLE_PYTHON 1356 void 1357 CommandObjectTypeSummaryAdd::CollectPythonScript (ScriptAddOptions *options, 1358 CommandReturnObject &result) 1359 { 1360 InputReaderSP reader_sp (new TypeScriptAddInputReader(m_interpreter.GetDebugger())); 1361 if (reader_sp && options) 1362 { 1363 1364 InputReaderEZ::InitializationParameters ipr; 1365 1366 Error err (reader_sp->Initialize (ipr.SetBaton(options).SetPrompt(" "))); 1367 if (err.Success()) 1368 { 1369 m_interpreter.GetDebugger().PushInputReader (reader_sp); 1370 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1371 } 1372 else 1373 { 1374 result.AppendError (err.AsCString()); 1375 result.SetStatus (eReturnStatusFailed); 1376 } 1377 } 1378 else 1379 { 1380 result.AppendError("out of memory"); 1381 result.SetStatus (eReturnStatusFailed); 1382 } 1383 } 1384 1385 bool 1386 CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturnObject &result) 1387 { 1388 const size_t argc = command.GetArgumentCount(); 1389 1390 if (argc < 1 && !m_options.m_name) 1391 { 1392 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); 1393 result.SetStatus(eReturnStatusFailed); 1394 return false; 1395 } 1396 1397 TypeSummaryImplSP script_format; 1398 1399 if (!m_options.m_python_function.empty()) // we have a Python function ready to use 1400 { 1401 const char *funct_name = m_options.m_python_function.c_str(); 1402 if (!funct_name || !funct_name[0]) 1403 { 1404 result.AppendError ("function name empty.\n"); 1405 result.SetStatus (eReturnStatusFailed); 1406 return false; 1407 } 1408 1409 std::string code = (" " + m_options.m_python_function + "(valobj,internal_dict)"); 1410 1411 script_format.reset(new ScriptSummaryFormat(m_options.m_flags, 1412 funct_name, 1413 code.c_str())); 1414 1415 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 1416 1417 if (interpreter && interpreter->CheckObjectExists(funct_name) == false) 1418 result.AppendWarningWithFormat("The provided function \"%s\" does not exist - " 1419 "please define it before attempting to use this summary.\n", 1420 funct_name); 1421 } 1422 else if (!m_options.m_python_script.empty()) // we have a quick 1-line script, just use it 1423 { 1424 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 1425 if (!interpreter) 1426 { 1427 result.AppendError ("script interpreter missing - unable to generate function wrapper.\n"); 1428 result.SetStatus (eReturnStatusFailed); 1429 return false; 1430 } 1431 StringList funct_sl; 1432 funct_sl << m_options.m_python_script.c_str(); 1433 std::string funct_name_str; 1434 if (!interpreter->GenerateTypeScriptFunction (funct_sl, 1435 funct_name_str)) 1436 { 1437 result.AppendError ("unable to generate function wrapper.\n"); 1438 result.SetStatus (eReturnStatusFailed); 1439 return false; 1440 } 1441 if (funct_name_str.empty()) 1442 { 1443 result.AppendError ("script interpreter failed to generate a valid function name.\n"); 1444 result.SetStatus (eReturnStatusFailed); 1445 return false; 1446 } 1447 1448 std::string code = " " + m_options.m_python_script; 1449 1450 script_format.reset(new ScriptSummaryFormat(m_options.m_flags, 1451 funct_name_str.c_str(), 1452 code.c_str())); 1453 } 1454 else // use an InputReader to grab Python code from the user 1455 { 1456 ScriptAddOptions *options = new ScriptAddOptions(m_options.m_flags, 1457 m_options.m_regex, 1458 m_options.m_name, 1459 m_options.m_category); 1460 1461 for (size_t i = 0; i < argc; i++) 1462 { 1463 const char* typeA = command.GetArgumentAtIndex(i); 1464 if (typeA && *typeA) 1465 options->m_target_types << typeA; 1466 else 1467 { 1468 result.AppendError("empty typenames not allowed"); 1469 result.SetStatus(eReturnStatusFailed); 1470 return false; 1471 } 1472 } 1473 1474 CollectPythonScript(options,result); 1475 return result.Succeeded(); 1476 } 1477 1478 // if I am here, script_format must point to something good, so I can add that 1479 // as a script summary to all interested parties 1480 1481 Error error; 1482 1483 for (size_t i = 0; i < command.GetArgumentCount(); i++) 1484 { 1485 const char *type_name = command.GetArgumentAtIndex(i); 1486 CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name), 1487 script_format, 1488 (m_options.m_regex ? eRegexSummary : eRegularSummary), 1489 m_options.m_category, 1490 &error); 1491 if (error.Fail()) 1492 { 1493 result.AppendError(error.AsCString()); 1494 result.SetStatus(eReturnStatusFailed); 1495 return false; 1496 } 1497 } 1498 1499 if (m_options.m_name) 1500 { 1501 AddSummary(m_options.m_name, script_format, eNamedSummary, m_options.m_category, &error); 1502 if (error.Fail()) 1503 { 1504 result.AppendError(error.AsCString()); 1505 result.AppendError("added to types, but not given a name"); 1506 result.SetStatus(eReturnStatusFailed); 1507 return false; 1508 } 1509 } 1510 1511 return result.Succeeded(); 1512 } 1513 1514 #endif 1515 1516 1517 bool 1518 CommandObjectTypeSummaryAdd::Execute_StringSummary (Args& command, CommandReturnObject &result) 1519 { 1520 const size_t argc = command.GetArgumentCount(); 1521 1522 if (argc < 1 && !m_options.m_name) 1523 { 1524 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); 1525 result.SetStatus(eReturnStatusFailed); 1526 return false; 1527 } 1528 1529 if (!m_options.m_flags.GetShowMembersOneLiner() && m_options.m_format_string.empty()) 1530 { 1531 result.AppendError("empty summary strings not allowed"); 1532 result.SetStatus(eReturnStatusFailed); 1533 return false; 1534 } 1535 1536 const char* format_cstr = (m_options.m_flags.GetShowMembersOneLiner() ? "" : m_options.m_format_string.c_str()); 1537 1538 // ${var%S} is an endless recursion, prevent it 1539 if (strcmp(format_cstr, "${var%S}") == 0) 1540 { 1541 result.AppendError("recursive summary not allowed"); 1542 result.SetStatus(eReturnStatusFailed); 1543 return false; 1544 } 1545 1546 Error error; 1547 1548 lldb::TypeSummaryImplSP entry(new StringSummaryFormat(m_options.m_flags, 1549 format_cstr)); 1550 1551 if (error.Fail()) 1552 { 1553 result.AppendError(error.AsCString()); 1554 result.SetStatus(eReturnStatusFailed); 1555 return false; 1556 } 1557 1558 // now I have a valid format, let's add it to every type 1559 1560 for (size_t i = 0; i < argc; i++) 1561 { 1562 const char* typeA = command.GetArgumentAtIndex(i); 1563 if (!typeA || typeA[0] == '\0') 1564 { 1565 result.AppendError("empty typenames not allowed"); 1566 result.SetStatus(eReturnStatusFailed); 1567 return false; 1568 } 1569 ConstString typeCS(typeA); 1570 1571 AddSummary(typeCS, 1572 entry, 1573 (m_options.m_regex ? eRegexSummary : eRegularSummary), 1574 m_options.m_category, 1575 &error); 1576 1577 if (error.Fail()) 1578 { 1579 result.AppendError(error.AsCString()); 1580 result.SetStatus(eReturnStatusFailed); 1581 return false; 1582 } 1583 } 1584 1585 if (m_options.m_name) 1586 { 1587 AddSummary(m_options.m_name, entry, eNamedSummary, m_options.m_category, &error); 1588 if (error.Fail()) 1589 { 1590 result.AppendError(error.AsCString()); 1591 result.AppendError("added to types, but not given a name"); 1592 result.SetStatus(eReturnStatusFailed); 1593 return false; 1594 } 1595 } 1596 1597 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1598 return result.Succeeded(); 1599 } 1600 1601 CommandObjectTypeSummaryAdd::CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter) : 1602 CommandObjectParsed (interpreter, 1603 "type summary add", 1604 "Add a new summary style for a type.", 1605 NULL), 1606 m_options (interpreter) 1607 { 1608 CommandArgumentEntry type_arg; 1609 CommandArgumentData type_style_arg; 1610 1611 type_style_arg.arg_type = eArgTypeName; 1612 type_style_arg.arg_repetition = eArgRepeatPlus; 1613 1614 type_arg.push_back (type_style_arg); 1615 1616 m_arguments.push_back (type_arg); 1617 1618 SetHelpLong( 1619 "Some examples of using this command.\n" 1620 "We use as reference the following snippet of code:\n" 1621 "struct JustADemo\n" 1622 "{\n" 1623 "int* ptr;\n" 1624 "float value;\n" 1625 "JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}\n" 1626 "};\n" 1627 "JustADemo object(42,3.14);\n" 1628 "struct AnotherDemo : public JustADemo\n" 1629 "{\n" 1630 "uint8_t byte;\n" 1631 "AnotherDemo(uint8_t b = 'E', int p = 1, float v = 0.1) : JustADemo(p,v), byte(b) {}\n" 1632 "};\n" 1633 "AnotherDemo *another_object = new AnotherDemo('E',42,3.14);\n" 1634 "\n" 1635 "type summary add --summary-string \"the answer is ${*var.ptr}\" JustADemo\n" 1636 "when typing frame variable object you will get \"the answer is 42\"\n" 1637 "type summary add --summary-string \"the answer is ${*var.ptr}, and the question is ${var.value}\" JustADemo\n" 1638 "when typing frame variable object you will get \"the answer is 42 and the question is 3.14\"\n" 1639 "\n" 1640 "Alternatively, you could also say\n" 1641 "type summary add --summary-string \"${var%V} -> ${*var}\" \"int *\"\n" 1642 "and replace the above summary string with\n" 1643 "type summary add --summary-string \"the answer is ${var.ptr}, and the question is ${var.value}\" JustADemo\n" 1644 "to obtain a similar result\n" 1645 "\n" 1646 "To add a summary valid for both JustADemo and AnotherDemo you can use the scoping operator, as in:\n" 1647 "type summary add --summary-string \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes\n" 1648 "\n" 1649 "This will be used for both variables of type JustADemo and AnotherDemo. To prevent this, change the -C to read -C no\n" 1650 "If you do not want pointers to be shown using that summary, you can use the -p option, as in:\n" 1651 "type summary add --summary-string \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes -p\n" 1652 "A similar option -r exists for references.\n" 1653 "\n" 1654 "If you simply want a one-line summary of the content of your variable, without typing an explicit string to that effect\n" 1655 "you can use the -c option, without giving any summary string:\n" 1656 "type summary add -c JustADemo\n" 1657 "frame variable object\n" 1658 "the output being similar to (ptr=0xsomeaddress, value=3.14)\n" 1659 "\n" 1660 "If you want to display some summary text, but also expand the structure of your object, you can add the -e option, as in:\n" 1661 "type summary add -e --summary-string \"*ptr = ${*var.ptr}\" JustADemo\n" 1662 "Here the value of the int* is displayed, followed by the standard LLDB sequence of children objects, one per line.\n" 1663 "to get an output like:\n" 1664 "\n" 1665 "*ptr = 42 {\n" 1666 " ptr = 0xsomeaddress\n" 1667 " value = 3.14\n" 1668 "}\n" 1669 "\n" 1670 "You can also add Python summaries, in which case you will use lldb public API to gather information from your variables" 1671 "and elaborate them to a meaningful summary inside a script written in Python. The variable object will be passed to your" 1672 "script as an SBValue object. The following example might help you when starting to use the Python summaries feature:\n" 1673 "type summary add JustADemo -o \"value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();\"\n" 1674 "If you prefer to type your scripts on multiple lines, you will use the -P option and then type your script, ending it with " 1675 "the word DONE on a line by itself to mark you're finished editing your code:\n" 1676 "(lldb)type summary add JustADemo -P\n" 1677 " value = valobj.GetChildMemberWithName('value');\n" 1678 " return 'My value is ' + value.GetValue();\n" 1679 "DONE\n" 1680 "(lldb) <-- type further LLDB commands here\n" 1681 ); 1682 } 1683 1684 bool 1685 CommandObjectTypeSummaryAdd::DoExecute (Args& command, CommandReturnObject &result) 1686 { 1687 if (m_options.m_is_add_script) 1688 { 1689 #ifndef LLDB_DISABLE_PYTHON 1690 return Execute_ScriptSummary(command, result); 1691 #else 1692 result.AppendError ("python is disabled"); 1693 result.SetStatus(eReturnStatusFailed); 1694 return false; 1695 #endif 1696 } 1697 1698 return Execute_StringSummary(command, result); 1699 } 1700 1701 bool 1702 CommandObjectTypeSummaryAdd::AddSummary(ConstString type_name, 1703 TypeSummaryImplSP entry, 1704 SummaryFormatType type, 1705 std::string category_name, 1706 Error* error) 1707 { 1708 lldb::TypeCategoryImplSP category; 1709 DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category); 1710 1711 if (type == eRegularSummary) 1712 { 1713 std::string type_name_str(type_name.GetCString()); 1714 if (type_name_str.compare(type_name_str.length() - 2, 2, "[]") == 0) 1715 { 1716 type_name_str.resize(type_name_str.length()-2); 1717 if (type_name_str.back() != ' ') 1718 type_name_str.append(" \\[[0-9]+\\]"); 1719 else 1720 type_name_str.append("\\[[0-9]+\\]"); 1721 type_name.SetCString(type_name_str.c_str()); 1722 type = eRegexSummary; 1723 } 1724 } 1725 1726 if (type == eRegexSummary) 1727 { 1728 RegularExpressionSP typeRX(new RegularExpression()); 1729 if (!typeRX->Compile(type_name.GetCString())) 1730 { 1731 if (error) 1732 error->SetErrorString("regex format error (maybe this is not really a regex?)"); 1733 return false; 1734 } 1735 1736 category->GetRegexTypeSummariesContainer()->Delete(type_name); 1737 category->GetRegexTypeSummariesContainer()->Add(typeRX, entry); 1738 1739 return true; 1740 } 1741 else if (type == eNamedSummary) 1742 { 1743 // system named summaries do not exist (yet?) 1744 DataVisualization::NamedSummaryFormats::Add(type_name,entry); 1745 return true; 1746 } 1747 else 1748 { 1749 category->GetTypeSummariesContainer()->Add(type_name, entry); 1750 return true; 1751 } 1752 } 1753 1754 OptionDefinition 1755 CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] = 1756 { 1757 { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, 1758 { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, 1759 { LLDB_OPT_SET_ALL, false, "no-value", 'v', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't show the value, just show the summary, for this type."}, 1760 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, 1761 { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, 1762 { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, 1763 { LLDB_OPT_SET_1 , true, "inline-children", 'c', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "If true, inline all child values into summary string."}, 1764 { LLDB_OPT_SET_1 , false, "omit-names", 'O', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "If true, omit value names in the summary display."}, 1765 { LLDB_OPT_SET_2 , true, "summary-string", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeSummaryString, "Summary string used to display text and object contents."}, 1766 { LLDB_OPT_SET_3, false, "python-script", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypePythonScript, "Give a one-liner Python script as part of the command."}, 1767 { LLDB_OPT_SET_3, false, "python-function", 'F', OptionParser::eRequiredArgument, NULL, 0, eArgTypePythonFunction, "Give the name of a Python function to use for this type."}, 1768 { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Input Python code to use for this type manually."}, 1769 { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "expand", 'e', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Expand aggregate data types to show children on separate lines."}, 1770 { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "A name for this summary string."}, 1771 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1772 }; 1773 1774 1775 //------------------------------------------------------------------------- 1776 // CommandObjectTypeSummaryDelete 1777 //------------------------------------------------------------------------- 1778 1779 class CommandObjectTypeSummaryDelete : public CommandObjectParsed 1780 { 1781 private: 1782 class CommandOptions : public Options 1783 { 1784 public: 1785 1786 CommandOptions (CommandInterpreter &interpreter) : 1787 Options (interpreter) 1788 { 1789 } 1790 1791 virtual 1792 ~CommandOptions (){} 1793 1794 virtual Error 1795 SetOptionValue (uint32_t option_idx, const char *option_arg) 1796 { 1797 Error error; 1798 const int short_option = m_getopt_table[option_idx].val; 1799 1800 switch (short_option) 1801 { 1802 case 'a': 1803 m_delete_all = true; 1804 break; 1805 case 'w': 1806 m_category = std::string(option_arg); 1807 break; 1808 default: 1809 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1810 break; 1811 } 1812 1813 return error; 1814 } 1815 1816 void 1817 OptionParsingStarting () 1818 { 1819 m_delete_all = false; 1820 m_category = "default"; 1821 } 1822 1823 const OptionDefinition* 1824 GetDefinitions () 1825 { 1826 return g_option_table; 1827 } 1828 1829 // Options table: Required for subclasses of Options. 1830 1831 static OptionDefinition g_option_table[]; 1832 1833 // Instance variables to hold the values for command options. 1834 1835 bool m_delete_all; 1836 std::string m_category; 1837 1838 }; 1839 1840 CommandOptions m_options; 1841 1842 virtual Options * 1843 GetOptions () 1844 { 1845 return &m_options; 1846 } 1847 1848 static bool 1849 PerCategoryCallback(void* param, 1850 const lldb::TypeCategoryImplSP& category_sp) 1851 { 1852 ConstString *name = (ConstString*)param; 1853 category_sp->Delete(*name, eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary); 1854 return true; 1855 } 1856 1857 public: 1858 CommandObjectTypeSummaryDelete (CommandInterpreter &interpreter) : 1859 CommandObjectParsed (interpreter, 1860 "type summary delete", 1861 "Delete an existing summary style for a type.", 1862 NULL), 1863 m_options(interpreter) 1864 { 1865 CommandArgumentEntry type_arg; 1866 CommandArgumentData type_style_arg; 1867 1868 type_style_arg.arg_type = eArgTypeName; 1869 type_style_arg.arg_repetition = eArgRepeatPlain; 1870 1871 type_arg.push_back (type_style_arg); 1872 1873 m_arguments.push_back (type_arg); 1874 1875 } 1876 1877 ~CommandObjectTypeSummaryDelete () 1878 { 1879 } 1880 1881 protected: 1882 bool 1883 DoExecute (Args& command, CommandReturnObject &result) 1884 { 1885 const size_t argc = command.GetArgumentCount(); 1886 1887 if (argc != 1) 1888 { 1889 result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); 1890 result.SetStatus(eReturnStatusFailed); 1891 return false; 1892 } 1893 1894 const char* typeA = command.GetArgumentAtIndex(0); 1895 ConstString typeCS(typeA); 1896 1897 if (!typeCS) 1898 { 1899 result.AppendError("empty typenames not allowed"); 1900 result.SetStatus(eReturnStatusFailed); 1901 return false; 1902 } 1903 1904 if (m_options.m_delete_all) 1905 { 1906 DataVisualization::Categories::LoopThrough(PerCategoryCallback, &typeCS); 1907 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1908 return result.Succeeded(); 1909 } 1910 1911 lldb::TypeCategoryImplSP category; 1912 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 1913 1914 bool delete_category = category->Delete(typeCS, 1915 eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary); 1916 bool delete_named = DataVisualization::NamedSummaryFormats::Delete(typeCS); 1917 1918 if (delete_category || delete_named) 1919 { 1920 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1921 return result.Succeeded(); 1922 } 1923 else 1924 { 1925 result.AppendErrorWithFormat ("no custom summary for %s.\n", typeA); 1926 result.SetStatus(eReturnStatusFailed); 1927 return false; 1928 } 1929 1930 } 1931 }; 1932 1933 OptionDefinition 1934 CommandObjectTypeSummaryDelete::CommandOptions::g_option_table[] = 1935 { 1936 { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Delete from every category."}, 1937 { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Delete from given category."}, 1938 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1939 }; 1940 1941 class CommandObjectTypeSummaryClear : public CommandObjectParsed 1942 { 1943 private: 1944 1945 class CommandOptions : public Options 1946 { 1947 public: 1948 1949 CommandOptions (CommandInterpreter &interpreter) : 1950 Options (interpreter) 1951 { 1952 } 1953 1954 virtual 1955 ~CommandOptions (){} 1956 1957 virtual Error 1958 SetOptionValue (uint32_t option_idx, const char *option_arg) 1959 { 1960 Error error; 1961 const int short_option = m_getopt_table[option_idx].val; 1962 1963 switch (short_option) 1964 { 1965 case 'a': 1966 m_delete_all = true; 1967 break; 1968 default: 1969 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1970 break; 1971 } 1972 1973 return error; 1974 } 1975 1976 void 1977 OptionParsingStarting () 1978 { 1979 m_delete_all = false; 1980 } 1981 1982 const OptionDefinition* 1983 GetDefinitions () 1984 { 1985 return g_option_table; 1986 } 1987 1988 // Options table: Required for subclasses of Options. 1989 1990 static OptionDefinition g_option_table[]; 1991 1992 // Instance variables to hold the values for command options. 1993 1994 bool m_delete_all; 1995 bool m_delete_named; 1996 }; 1997 1998 CommandOptions m_options; 1999 2000 virtual Options * 2001 GetOptions () 2002 { 2003 return &m_options; 2004 } 2005 2006 static bool 2007 PerCategoryCallback(void* param, 2008 const lldb::TypeCategoryImplSP& cate) 2009 { 2010 cate->GetTypeSummariesContainer()->Clear(); 2011 cate->GetRegexTypeSummariesContainer()->Clear(); 2012 return true; 2013 2014 } 2015 2016 public: 2017 CommandObjectTypeSummaryClear (CommandInterpreter &interpreter) : 2018 CommandObjectParsed (interpreter, 2019 "type summary clear", 2020 "Delete all existing summary styles.", 2021 NULL), 2022 m_options(interpreter) 2023 { 2024 } 2025 2026 ~CommandObjectTypeSummaryClear () 2027 { 2028 } 2029 2030 protected: 2031 bool 2032 DoExecute (Args& command, CommandReturnObject &result) 2033 { 2034 2035 if (m_options.m_delete_all) 2036 DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL); 2037 2038 else 2039 { 2040 lldb::TypeCategoryImplSP category; 2041 if (command.GetArgumentCount() > 0) 2042 { 2043 const char* cat_name = command.GetArgumentAtIndex(0); 2044 ConstString cat_nameCS(cat_name); 2045 DataVisualization::Categories::GetCategory(cat_nameCS, category); 2046 } 2047 else 2048 DataVisualization::Categories::GetCategory(ConstString(NULL), category); 2049 category->Clear(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary); 2050 } 2051 2052 DataVisualization::NamedSummaryFormats::Clear(); 2053 2054 result.SetStatus(eReturnStatusSuccessFinishResult); 2055 return result.Succeeded(); 2056 } 2057 2058 }; 2059 2060 OptionDefinition 2061 CommandObjectTypeSummaryClear::CommandOptions::g_option_table[] = 2062 { 2063 { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Clear every category."}, 2064 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 2065 }; 2066 2067 //------------------------------------------------------------------------- 2068 // CommandObjectTypeSummaryList 2069 //------------------------------------------------------------------------- 2070 2071 bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, ConstString type, const StringSummaryFormat::SharedPointer& entry); 2072 bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const StringSummaryFormat::SharedPointer& entry); 2073 2074 class CommandObjectTypeSummaryList; 2075 2076 struct CommandObjectTypeSummaryList_LoopCallbackParam { 2077 CommandObjectTypeSummaryList* self; 2078 CommandReturnObject* result; 2079 RegularExpression* regex; 2080 RegularExpression* cate_regex; 2081 CommandObjectTypeSummaryList_LoopCallbackParam(CommandObjectTypeSummaryList* S, CommandReturnObject* R, 2082 RegularExpression* X = NULL, 2083 RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {} 2084 }; 2085 2086 class CommandObjectTypeSummaryList : public CommandObjectParsed 2087 { 2088 2089 class CommandOptions : public Options 2090 { 2091 public: 2092 2093 CommandOptions (CommandInterpreter &interpreter) : 2094 Options (interpreter) 2095 { 2096 } 2097 2098 virtual 2099 ~CommandOptions (){} 2100 2101 virtual Error 2102 SetOptionValue (uint32_t option_idx, const char *option_arg) 2103 { 2104 Error error; 2105 const int short_option = m_getopt_table[option_idx].val; 2106 2107 switch (short_option) 2108 { 2109 case 'w': 2110 m_category_regex = std::string(option_arg); 2111 break; 2112 default: 2113 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 2114 break; 2115 } 2116 2117 return error; 2118 } 2119 2120 void 2121 OptionParsingStarting () 2122 { 2123 m_category_regex = ""; 2124 } 2125 2126 const OptionDefinition* 2127 GetDefinitions () 2128 { 2129 return g_option_table; 2130 } 2131 2132 // Options table: Required for subclasses of Options. 2133 2134 static OptionDefinition g_option_table[]; 2135 2136 // Instance variables to hold the values for command options. 2137 2138 std::string m_category_regex; 2139 2140 }; 2141 2142 CommandOptions m_options; 2143 2144 virtual Options * 2145 GetOptions () 2146 { 2147 return &m_options; 2148 } 2149 2150 public: 2151 CommandObjectTypeSummaryList (CommandInterpreter &interpreter) : 2152 CommandObjectParsed (interpreter, 2153 "type summary list", 2154 "Show a list of current summary styles.", 2155 NULL), 2156 m_options(interpreter) 2157 { 2158 CommandArgumentEntry type_arg; 2159 CommandArgumentData type_style_arg; 2160 2161 type_style_arg.arg_type = eArgTypeName; 2162 type_style_arg.arg_repetition = eArgRepeatOptional; 2163 2164 type_arg.push_back (type_style_arg); 2165 2166 m_arguments.push_back (type_arg); 2167 } 2168 2169 ~CommandObjectTypeSummaryList () 2170 { 2171 } 2172 2173 protected: 2174 bool 2175 DoExecute (Args& command, CommandReturnObject &result) 2176 { 2177 const size_t argc = command.GetArgumentCount(); 2178 2179 CommandObjectTypeSummaryList_LoopCallbackParam *param; 2180 RegularExpression* cate_regex = 2181 m_options.m_category_regex.empty() ? NULL : 2182 new RegularExpression(m_options.m_category_regex.c_str()); 2183 2184 if (argc == 1) 2185 { 2186 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); 2187 regex->Compile(command.GetArgumentAtIndex(0)); 2188 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex,cate_regex); 2189 } 2190 else 2191 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,NULL,cate_regex); 2192 2193 DataVisualization::Categories::LoopThrough(PerCategoryCallback,param); 2194 delete param; 2195 2196 if (DataVisualization::NamedSummaryFormats::GetCount() > 0) 2197 { 2198 result.GetOutputStream().Printf("Named summaries:\n"); 2199 if (argc == 1) 2200 { 2201 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); 2202 regex->Compile(command.GetArgumentAtIndex(0)); 2203 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex); 2204 } 2205 else 2206 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result); 2207 DataVisualization::NamedSummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param); 2208 delete param; 2209 } 2210 2211 if (cate_regex) 2212 delete cate_regex; 2213 2214 result.SetStatus(eReturnStatusSuccessFinishResult); 2215 return result.Succeeded(); 2216 } 2217 2218 private: 2219 2220 static bool 2221 PerCategoryCallback(void* param_vp, 2222 const lldb::TypeCategoryImplSP& cate) 2223 { 2224 2225 CommandObjectTypeSummaryList_LoopCallbackParam* param = 2226 (CommandObjectTypeSummaryList_LoopCallbackParam*)param_vp; 2227 CommandReturnObject* result = param->result; 2228 2229 const char* cate_name = cate->GetName(); 2230 2231 // if the category is disabled or empty and there is no regex, just skip it 2232 if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary) == 0) && param->cate_regex == NULL) 2233 return true; 2234 2235 // if we have a regex and this category does not match it, just skip it 2236 if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false) 2237 return true; 2238 2239 result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n", 2240 cate_name, 2241 (cate->IsEnabled() ? "enabled" : "disabled")); 2242 2243 cate->GetTypeSummariesContainer()->LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param_vp); 2244 2245 if (cate->GetRegexTypeSummariesContainer()->GetCount() > 0) 2246 { 2247 result->GetOutputStream().Printf("Regex-based summaries (slower):\n"); 2248 cate->GetRegexTypeSummariesContainer()->LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, param_vp); 2249 } 2250 return true; 2251 } 2252 2253 2254 bool 2255 LoopCallback (const char* type, 2256 const lldb::TypeSummaryImplSP& entry, 2257 RegularExpression* regex, 2258 CommandReturnObject *result) 2259 { 2260 if (regex == NULL || strcmp(type,regex->GetText()) == 0 || regex->Execute(type)) 2261 result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str()); 2262 return true; 2263 } 2264 2265 friend bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeSummaryImplSP& entry); 2266 friend bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeSummaryImplSP& entry); 2267 }; 2268 2269 bool 2270 CommandObjectTypeSummaryList_LoopCallback ( 2271 void* pt2self, 2272 ConstString type, 2273 const lldb::TypeSummaryImplSP& entry) 2274 { 2275 CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self; 2276 return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result); 2277 } 2278 2279 bool 2280 CommandObjectTypeRXSummaryList_LoopCallback ( 2281 void* pt2self, 2282 lldb::RegularExpressionSP regex, 2283 const lldb::TypeSummaryImplSP& entry) 2284 { 2285 CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self; 2286 return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); 2287 } 2288 2289 OptionDefinition 2290 CommandObjectTypeSummaryList::CommandOptions::g_option_table[] = 2291 { 2292 { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, 2293 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 2294 }; 2295 2296 //------------------------------------------------------------------------- 2297 // CommandObjectTypeCategoryEnable 2298 //------------------------------------------------------------------------- 2299 2300 class CommandObjectTypeCategoryEnable : public CommandObjectParsed 2301 { 2302 public: 2303 CommandObjectTypeCategoryEnable (CommandInterpreter &interpreter) : 2304 CommandObjectParsed (interpreter, 2305 "type category enable", 2306 "Enable a category as a source of formatters.", 2307 NULL) 2308 { 2309 CommandArgumentEntry type_arg; 2310 CommandArgumentData type_style_arg; 2311 2312 type_style_arg.arg_type = eArgTypeName; 2313 type_style_arg.arg_repetition = eArgRepeatPlus; 2314 2315 type_arg.push_back (type_style_arg); 2316 2317 m_arguments.push_back (type_arg); 2318 2319 } 2320 2321 ~CommandObjectTypeCategoryEnable () 2322 { 2323 } 2324 2325 protected: 2326 bool 2327 DoExecute (Args& command, CommandReturnObject &result) 2328 { 2329 const size_t argc = command.GetArgumentCount(); 2330 2331 if (argc < 1) 2332 { 2333 result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str()); 2334 result.SetStatus(eReturnStatusFailed); 2335 return false; 2336 } 2337 2338 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0) 2339 { 2340 // we want to make sure to enable "system" last and "default" first 2341 DataVisualization::Categories::Enable(ConstString("default"), TypeCategoryMap::First); 2342 uint32_t num_categories = DataVisualization::Categories::GetCount(); 2343 for (uint32_t i = 0; i < num_categories; i++) 2344 { 2345 lldb::TypeCategoryImplSP category_sp = DataVisualization::Categories::GetCategoryAtIndex(i); 2346 if (category_sp) 2347 { 2348 if ( ::strcmp(category_sp->GetName(), "system") == 0 || 2349 ::strcmp(category_sp->GetName(), "default") == 0 ) 2350 continue; 2351 else 2352 DataVisualization::Categories::Enable(category_sp, TypeCategoryMap::Default); 2353 } 2354 } 2355 DataVisualization::Categories::Enable(ConstString("system"), TypeCategoryMap::Last); 2356 } 2357 else 2358 { 2359 for (int i = argc - 1; i >= 0; i--) 2360 { 2361 const char* typeA = command.GetArgumentAtIndex(i); 2362 ConstString typeCS(typeA); 2363 2364 if (!typeCS) 2365 { 2366 result.AppendError("empty category name not allowed"); 2367 result.SetStatus(eReturnStatusFailed); 2368 return false; 2369 } 2370 DataVisualization::Categories::Enable(typeCS); 2371 lldb::TypeCategoryImplSP cate; 2372 if (DataVisualization::Categories::GetCategory(typeCS, cate) && cate.get()) 2373 { 2374 if (cate->GetCount() == 0) 2375 { 2376 result.AppendWarning("empty category enabled (typo?)"); 2377 } 2378 } 2379 } 2380 } 2381 2382 result.SetStatus(eReturnStatusSuccessFinishResult); 2383 return result.Succeeded(); 2384 } 2385 2386 }; 2387 2388 //------------------------------------------------------------------------- 2389 // CommandObjectTypeCategoryDelete 2390 //------------------------------------------------------------------------- 2391 2392 class CommandObjectTypeCategoryDelete : public CommandObjectParsed 2393 { 2394 public: 2395 CommandObjectTypeCategoryDelete (CommandInterpreter &interpreter) : 2396 CommandObjectParsed (interpreter, 2397 "type category delete", 2398 "Delete a category and all associated formatters.", 2399 NULL) 2400 { 2401 CommandArgumentEntry type_arg; 2402 CommandArgumentData type_style_arg; 2403 2404 type_style_arg.arg_type = eArgTypeName; 2405 type_style_arg.arg_repetition = eArgRepeatPlus; 2406 2407 type_arg.push_back (type_style_arg); 2408 2409 m_arguments.push_back (type_arg); 2410 2411 } 2412 2413 ~CommandObjectTypeCategoryDelete () 2414 { 2415 } 2416 2417 protected: 2418 bool 2419 DoExecute (Args& command, CommandReturnObject &result) 2420 { 2421 const size_t argc = command.GetArgumentCount(); 2422 2423 if (argc < 1) 2424 { 2425 result.AppendErrorWithFormat ("%s takes 1 or more arg.\n", m_cmd_name.c_str()); 2426 result.SetStatus(eReturnStatusFailed); 2427 return false; 2428 } 2429 2430 bool success = true; 2431 2432 // the order is not relevant here 2433 for (int i = argc - 1; i >= 0; i--) 2434 { 2435 const char* typeA = command.GetArgumentAtIndex(i); 2436 ConstString typeCS(typeA); 2437 2438 if (!typeCS) 2439 { 2440 result.AppendError("empty category name not allowed"); 2441 result.SetStatus(eReturnStatusFailed); 2442 return false; 2443 } 2444 if (!DataVisualization::Categories::Delete(typeCS)) 2445 success = false; // keep deleting even if we hit an error 2446 } 2447 if (success) 2448 { 2449 result.SetStatus(eReturnStatusSuccessFinishResult); 2450 return result.Succeeded(); 2451 } 2452 else 2453 { 2454 result.AppendError("cannot delete one or more categories\n"); 2455 result.SetStatus(eReturnStatusFailed); 2456 return false; 2457 } 2458 } 2459 }; 2460 2461 //------------------------------------------------------------------------- 2462 // CommandObjectTypeCategoryDisable 2463 //------------------------------------------------------------------------- 2464 2465 class CommandObjectTypeCategoryDisable : public CommandObjectParsed 2466 { 2467 public: 2468 CommandObjectTypeCategoryDisable (CommandInterpreter &interpreter) : 2469 CommandObjectParsed (interpreter, 2470 "type category disable", 2471 "Disable a category as a source of formatters.", 2472 NULL) 2473 { 2474 CommandArgumentEntry type_arg; 2475 CommandArgumentData type_style_arg; 2476 2477 type_style_arg.arg_type = eArgTypeName; 2478 type_style_arg.arg_repetition = eArgRepeatPlus; 2479 2480 type_arg.push_back (type_style_arg); 2481 2482 m_arguments.push_back (type_arg); 2483 2484 } 2485 2486 ~CommandObjectTypeCategoryDisable () 2487 { 2488 } 2489 2490 protected: 2491 bool 2492 DoExecute (Args& command, CommandReturnObject &result) 2493 { 2494 const size_t argc = command.GetArgumentCount(); 2495 2496 if (argc < 1) 2497 { 2498 result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str()); 2499 result.SetStatus(eReturnStatusFailed); 2500 return false; 2501 } 2502 2503 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0) 2504 { 2505 uint32_t num_categories = DataVisualization::Categories::GetCount(); 2506 for (uint32_t i = 0; i < num_categories; i++) 2507 { 2508 lldb::TypeCategoryImplSP category_sp = DataVisualization::Categories::GetCategoryAtIndex(i); 2509 // no need to check if the category is enabled - disabling a disabled category has no effect 2510 if (category_sp) 2511 DataVisualization::Categories::Disable(category_sp); 2512 } 2513 } 2514 else 2515 { 2516 // the order is not relevant here 2517 for (int i = argc - 1; i >= 0; i--) 2518 { 2519 const char* typeA = command.GetArgumentAtIndex(i); 2520 ConstString typeCS(typeA); 2521 2522 if (!typeCS) 2523 { 2524 result.AppendError("empty category name not allowed"); 2525 result.SetStatus(eReturnStatusFailed); 2526 return false; 2527 } 2528 DataVisualization::Categories::Disable(typeCS); 2529 } 2530 } 2531 2532 result.SetStatus(eReturnStatusSuccessFinishResult); 2533 return result.Succeeded(); 2534 } 2535 2536 }; 2537 2538 //------------------------------------------------------------------------- 2539 // CommandObjectTypeCategoryList 2540 //------------------------------------------------------------------------- 2541 2542 class CommandObjectTypeCategoryList : public CommandObjectParsed 2543 { 2544 private: 2545 2546 struct CommandObjectTypeCategoryList_CallbackParam 2547 { 2548 CommandReturnObject* result; 2549 RegularExpression* regex; 2550 2551 CommandObjectTypeCategoryList_CallbackParam(CommandReturnObject* res, 2552 RegularExpression* rex = NULL) : 2553 result(res), 2554 regex(rex) 2555 { 2556 } 2557 2558 }; 2559 2560 static bool 2561 PerCategoryCallback(void* param_vp, 2562 const lldb::TypeCategoryImplSP& cate) 2563 { 2564 CommandObjectTypeCategoryList_CallbackParam* param = 2565 (CommandObjectTypeCategoryList_CallbackParam*)param_vp; 2566 CommandReturnObject* result = param->result; 2567 RegularExpression* regex = param->regex; 2568 2569 const char* cate_name = cate->GetName(); 2570 2571 if (regex == NULL || strcmp(cate_name, regex->GetText()) == 0 || regex->Execute(cate_name)) 2572 result->GetOutputStream().Printf("Category %s is%s enabled\n", 2573 cate_name, 2574 (cate->IsEnabled() ? "" : " not")); 2575 return true; 2576 } 2577 public: 2578 CommandObjectTypeCategoryList (CommandInterpreter &interpreter) : 2579 CommandObjectParsed (interpreter, 2580 "type category list", 2581 "Provide a list of all existing categories.", 2582 NULL) 2583 { 2584 CommandArgumentEntry type_arg; 2585 CommandArgumentData type_style_arg; 2586 2587 type_style_arg.arg_type = eArgTypeName; 2588 type_style_arg.arg_repetition = eArgRepeatOptional; 2589 2590 type_arg.push_back (type_style_arg); 2591 2592 m_arguments.push_back (type_arg); 2593 } 2594 2595 ~CommandObjectTypeCategoryList () 2596 { 2597 } 2598 2599 protected: 2600 bool 2601 DoExecute (Args& command, CommandReturnObject &result) 2602 { 2603 const size_t argc = command.GetArgumentCount(); 2604 RegularExpression* regex = NULL; 2605 2606 if (argc == 0) 2607 ; 2608 else if (argc == 1) 2609 regex = new RegularExpression(command.GetArgumentAtIndex(0)); 2610 else 2611 { 2612 result.AppendErrorWithFormat ("%s takes 0 or one arg.\n", m_cmd_name.c_str()); 2613 result.SetStatus(eReturnStatusFailed); 2614 return false; 2615 } 2616 2617 CommandObjectTypeCategoryList_CallbackParam param(&result, 2618 regex); 2619 2620 DataVisualization::Categories::LoopThrough(PerCategoryCallback, ¶m); 2621 2622 if (regex) 2623 delete regex; 2624 2625 result.SetStatus(eReturnStatusSuccessFinishResult); 2626 return result.Succeeded(); 2627 } 2628 2629 }; 2630 2631 //------------------------------------------------------------------------- 2632 // CommandObjectTypeFilterList 2633 //------------------------------------------------------------------------- 2634 2635 bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); 2636 bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); 2637 2638 class CommandObjectTypeFilterList; 2639 2640 struct CommandObjectTypeFilterList_LoopCallbackParam { 2641 CommandObjectTypeFilterList* self; 2642 CommandReturnObject* result; 2643 RegularExpression* regex; 2644 RegularExpression* cate_regex; 2645 CommandObjectTypeFilterList_LoopCallbackParam(CommandObjectTypeFilterList* S, CommandReturnObject* R, 2646 RegularExpression* X = NULL, 2647 RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {} 2648 }; 2649 2650 class CommandObjectTypeFilterList : public CommandObjectParsed 2651 { 2652 2653 class CommandOptions : public Options 2654 { 2655 public: 2656 2657 CommandOptions (CommandInterpreter &interpreter) : 2658 Options (interpreter) 2659 { 2660 } 2661 2662 virtual 2663 ~CommandOptions (){} 2664 2665 virtual Error 2666 SetOptionValue (uint32_t option_idx, const char *option_arg) 2667 { 2668 Error error; 2669 const int short_option = m_getopt_table[option_idx].val; 2670 2671 switch (short_option) 2672 { 2673 case 'w': 2674 m_category_regex = std::string(option_arg); 2675 break; 2676 default: 2677 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 2678 break; 2679 } 2680 2681 return error; 2682 } 2683 2684 void 2685 OptionParsingStarting () 2686 { 2687 m_category_regex = ""; 2688 } 2689 2690 const OptionDefinition* 2691 GetDefinitions () 2692 { 2693 return g_option_table; 2694 } 2695 2696 // Options table: Required for subclasses of Options. 2697 2698 static OptionDefinition g_option_table[]; 2699 2700 // Instance variables to hold the values for command options. 2701 2702 std::string m_category_regex; 2703 2704 }; 2705 2706 CommandOptions m_options; 2707 2708 virtual Options * 2709 GetOptions () 2710 { 2711 return &m_options; 2712 } 2713 2714 public: 2715 CommandObjectTypeFilterList (CommandInterpreter &interpreter) : 2716 CommandObjectParsed (interpreter, 2717 "type filter list", 2718 "Show a list of current filters.", 2719 NULL), 2720 m_options(interpreter) 2721 { 2722 CommandArgumentEntry type_arg; 2723 CommandArgumentData type_style_arg; 2724 2725 type_style_arg.arg_type = eArgTypeName; 2726 type_style_arg.arg_repetition = eArgRepeatOptional; 2727 2728 type_arg.push_back (type_style_arg); 2729 2730 m_arguments.push_back (type_arg); 2731 } 2732 2733 ~CommandObjectTypeFilterList () 2734 { 2735 } 2736 2737 protected: 2738 bool 2739 DoExecute (Args& command, CommandReturnObject &result) 2740 { 2741 const size_t argc = command.GetArgumentCount(); 2742 2743 CommandObjectTypeFilterList_LoopCallbackParam *param; 2744 RegularExpression* cate_regex = 2745 m_options.m_category_regex.empty() ? NULL : 2746 new RegularExpression(m_options.m_category_regex.c_str()); 2747 2748 if (argc == 1) 2749 { 2750 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); 2751 regex->Compile(command.GetArgumentAtIndex(0)); 2752 param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,regex,cate_regex); 2753 } 2754 else 2755 param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,NULL,cate_regex); 2756 2757 DataVisualization::Categories::LoopThrough(PerCategoryCallback,param); 2758 delete param; 2759 2760 if (cate_regex) 2761 delete cate_regex; 2762 2763 result.SetStatus(eReturnStatusSuccessFinishResult); 2764 return result.Succeeded(); 2765 } 2766 2767 private: 2768 2769 static bool 2770 PerCategoryCallback(void* param_vp, 2771 const lldb::TypeCategoryImplSP& cate) 2772 { 2773 2774 const char* cate_name = cate->GetName(); 2775 2776 CommandObjectTypeFilterList_LoopCallbackParam* param = 2777 (CommandObjectTypeFilterList_LoopCallbackParam*)param_vp; 2778 CommandReturnObject* result = param->result; 2779 2780 // if the category is disabled or empty and there is no regex, just skip it 2781 if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter) == 0) && param->cate_regex == NULL) 2782 return true; 2783 2784 // if we have a regex and this category does not match it, just skip it 2785 if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false) 2786 return true; 2787 2788 result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n", 2789 cate_name, 2790 (cate->IsEnabled() ? "enabled" : "disabled")); 2791 2792 cate->GetTypeFiltersContainer()->LoopThrough(CommandObjectTypeFilterList_LoopCallback, param_vp); 2793 2794 if (cate->GetRegexTypeFiltersContainer()->GetCount() > 0) 2795 { 2796 result->GetOutputStream().Printf("Regex-based filters (slower):\n"); 2797 cate->GetRegexTypeFiltersContainer()->LoopThrough(CommandObjectTypeFilterRXList_LoopCallback, param_vp); 2798 } 2799 2800 return true; 2801 } 2802 2803 bool 2804 LoopCallback (const char* type, 2805 const SyntheticChildren::SharedPointer& entry, 2806 RegularExpression* regex, 2807 CommandReturnObject *result) 2808 { 2809 if (regex == NULL || regex->Execute(type)) 2810 result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str()); 2811 return true; 2812 } 2813 2814 friend bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); 2815 friend bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); 2816 }; 2817 2818 bool 2819 CommandObjectTypeFilterList_LoopCallback (void* pt2self, 2820 ConstString type, 2821 const SyntheticChildren::SharedPointer& entry) 2822 { 2823 CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self; 2824 return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result); 2825 } 2826 2827 bool 2828 CommandObjectTypeFilterRXList_LoopCallback (void* pt2self, 2829 lldb::RegularExpressionSP regex, 2830 const SyntheticChildren::SharedPointer& entry) 2831 { 2832 CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self; 2833 return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); 2834 } 2835 2836 2837 OptionDefinition 2838 CommandObjectTypeFilterList::CommandOptions::g_option_table[] = 2839 { 2840 { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, 2841 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 2842 }; 2843 2844 #ifndef LLDB_DISABLE_PYTHON 2845 2846 //------------------------------------------------------------------------- 2847 // CommandObjectTypeSynthList 2848 //------------------------------------------------------------------------- 2849 2850 bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); 2851 bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); 2852 2853 class CommandObjectTypeSynthList; 2854 2855 struct CommandObjectTypeSynthList_LoopCallbackParam { 2856 CommandObjectTypeSynthList* self; 2857 CommandReturnObject* result; 2858 RegularExpression* regex; 2859 RegularExpression* cate_regex; 2860 CommandObjectTypeSynthList_LoopCallbackParam(CommandObjectTypeSynthList* S, CommandReturnObject* R, 2861 RegularExpression* X = NULL, 2862 RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {} 2863 }; 2864 2865 class CommandObjectTypeSynthList : public CommandObjectParsed 2866 { 2867 2868 class CommandOptions : public Options 2869 { 2870 public: 2871 2872 CommandOptions (CommandInterpreter &interpreter) : 2873 Options (interpreter) 2874 { 2875 } 2876 2877 virtual 2878 ~CommandOptions (){} 2879 2880 virtual Error 2881 SetOptionValue (uint32_t option_idx, const char *option_arg) 2882 { 2883 Error error; 2884 const int short_option = m_getopt_table[option_idx].val; 2885 2886 switch (short_option) 2887 { 2888 case 'w': 2889 m_category_regex = std::string(option_arg); 2890 break; 2891 default: 2892 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 2893 break; 2894 } 2895 2896 return error; 2897 } 2898 2899 void 2900 OptionParsingStarting () 2901 { 2902 m_category_regex = ""; 2903 } 2904 2905 const OptionDefinition* 2906 GetDefinitions () 2907 { 2908 return g_option_table; 2909 } 2910 2911 // Options table: Required for subclasses of Options. 2912 2913 static OptionDefinition g_option_table[]; 2914 2915 // Instance variables to hold the values for command options. 2916 2917 std::string m_category_regex; 2918 2919 }; 2920 2921 CommandOptions m_options; 2922 2923 virtual Options * 2924 GetOptions () 2925 { 2926 return &m_options; 2927 } 2928 2929 public: 2930 CommandObjectTypeSynthList (CommandInterpreter &interpreter) : 2931 CommandObjectParsed (interpreter, 2932 "type synthetic list", 2933 "Show a list of current synthetic providers.", 2934 NULL), 2935 m_options(interpreter) 2936 { 2937 CommandArgumentEntry type_arg; 2938 CommandArgumentData type_style_arg; 2939 2940 type_style_arg.arg_type = eArgTypeName; 2941 type_style_arg.arg_repetition = eArgRepeatOptional; 2942 2943 type_arg.push_back (type_style_arg); 2944 2945 m_arguments.push_back (type_arg); 2946 } 2947 2948 ~CommandObjectTypeSynthList () 2949 { 2950 } 2951 2952 protected: 2953 bool 2954 DoExecute (Args& command, CommandReturnObject &result) 2955 { 2956 const size_t argc = command.GetArgumentCount(); 2957 2958 CommandObjectTypeSynthList_LoopCallbackParam *param; 2959 RegularExpression* cate_regex = 2960 m_options.m_category_regex.empty() ? NULL : 2961 new RegularExpression(m_options.m_category_regex.c_str()); 2962 2963 if (argc == 1) 2964 { 2965 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); 2966 regex->Compile(command.GetArgumentAtIndex(0)); 2967 param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,regex,cate_regex); 2968 } 2969 else 2970 param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,NULL,cate_regex); 2971 2972 DataVisualization::Categories::LoopThrough(PerCategoryCallback,param); 2973 delete param; 2974 2975 if (cate_regex) 2976 delete cate_regex; 2977 2978 result.SetStatus(eReturnStatusSuccessFinishResult); 2979 return result.Succeeded(); 2980 } 2981 2982 private: 2983 2984 static bool 2985 PerCategoryCallback(void* param_vp, 2986 const lldb::TypeCategoryImplSP& cate) 2987 { 2988 2989 CommandObjectTypeSynthList_LoopCallbackParam* param = 2990 (CommandObjectTypeSynthList_LoopCallbackParam*)param_vp; 2991 CommandReturnObject* result = param->result; 2992 2993 const char* cate_name = cate->GetName(); 2994 2995 // if the category is disabled or empty and there is no regex, just skip it 2996 if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth) == 0) && param->cate_regex == NULL) 2997 return true; 2998 2999 // if we have a regex and this category does not match it, just skip it 3000 if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false) 3001 return true; 3002 3003 result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n", 3004 cate_name, 3005 (cate->IsEnabled() ? "enabled" : "disabled")); 3006 3007 cate->GetTypeSyntheticsContainer()->LoopThrough(CommandObjectTypeSynthList_LoopCallback, param_vp); 3008 3009 if (cate->GetRegexTypeSyntheticsContainer()->GetCount() > 0) 3010 { 3011 result->GetOutputStream().Printf("Regex-based synthetic providers (slower):\n"); 3012 cate->GetRegexTypeSyntheticsContainer()->LoopThrough(CommandObjectTypeSynthRXList_LoopCallback, param_vp); 3013 } 3014 3015 return true; 3016 } 3017 3018 bool 3019 LoopCallback (const char* type, 3020 const SyntheticChildren::SharedPointer& entry, 3021 RegularExpression* regex, 3022 CommandReturnObject *result) 3023 { 3024 if (regex == NULL || regex->Execute(type)) 3025 result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str()); 3026 return true; 3027 } 3028 3029 friend bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); 3030 friend bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); 3031 }; 3032 3033 bool 3034 CommandObjectTypeSynthList_LoopCallback (void* pt2self, 3035 ConstString type, 3036 const SyntheticChildren::SharedPointer& entry) 3037 { 3038 CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self; 3039 return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result); 3040 } 3041 3042 bool 3043 CommandObjectTypeSynthRXList_LoopCallback (void* pt2self, 3044 lldb::RegularExpressionSP regex, 3045 const SyntheticChildren::SharedPointer& entry) 3046 { 3047 CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self; 3048 return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); 3049 } 3050 3051 3052 OptionDefinition 3053 CommandObjectTypeSynthList::CommandOptions::g_option_table[] = 3054 { 3055 { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, 3056 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3057 }; 3058 3059 #endif // #ifndef LLDB_DISABLE_PYTHON 3060 //------------------------------------------------------------------------- 3061 // CommandObjectTypeFilterDelete 3062 //------------------------------------------------------------------------- 3063 3064 class CommandObjectTypeFilterDelete : public CommandObjectParsed 3065 { 3066 private: 3067 class CommandOptions : public Options 3068 { 3069 public: 3070 3071 CommandOptions (CommandInterpreter &interpreter) : 3072 Options (interpreter) 3073 { 3074 } 3075 3076 virtual 3077 ~CommandOptions (){} 3078 3079 virtual Error 3080 SetOptionValue (uint32_t option_idx, const char *option_arg) 3081 { 3082 Error error; 3083 const int short_option = m_getopt_table[option_idx].val; 3084 3085 switch (short_option) 3086 { 3087 case 'a': 3088 m_delete_all = true; 3089 break; 3090 case 'w': 3091 m_category = std::string(option_arg); 3092 break; 3093 default: 3094 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3095 break; 3096 } 3097 3098 return error; 3099 } 3100 3101 void 3102 OptionParsingStarting () 3103 { 3104 m_delete_all = false; 3105 m_category = "default"; 3106 } 3107 3108 const OptionDefinition* 3109 GetDefinitions () 3110 { 3111 return g_option_table; 3112 } 3113 3114 // Options table: Required for subclasses of Options. 3115 3116 static OptionDefinition g_option_table[]; 3117 3118 // Instance variables to hold the values for command options. 3119 3120 bool m_delete_all; 3121 std::string m_category; 3122 3123 }; 3124 3125 CommandOptions m_options; 3126 3127 virtual Options * 3128 GetOptions () 3129 { 3130 return &m_options; 3131 } 3132 3133 static bool 3134 PerCategoryCallback(void* param, 3135 const lldb::TypeCategoryImplSP& cate) 3136 { 3137 ConstString *name = (ConstString*)param; 3138 return cate->Delete(*name, eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter); 3139 } 3140 3141 public: 3142 CommandObjectTypeFilterDelete (CommandInterpreter &interpreter) : 3143 CommandObjectParsed (interpreter, 3144 "type filter delete", 3145 "Delete an existing filter for a type.", 3146 NULL), 3147 m_options(interpreter) 3148 { 3149 CommandArgumentEntry type_arg; 3150 CommandArgumentData type_style_arg; 3151 3152 type_style_arg.arg_type = eArgTypeName; 3153 type_style_arg.arg_repetition = eArgRepeatPlain; 3154 3155 type_arg.push_back (type_style_arg); 3156 3157 m_arguments.push_back (type_arg); 3158 3159 } 3160 3161 ~CommandObjectTypeFilterDelete () 3162 { 3163 } 3164 3165 protected: 3166 bool 3167 DoExecute (Args& command, CommandReturnObject &result) 3168 { 3169 const size_t argc = command.GetArgumentCount(); 3170 3171 if (argc != 1) 3172 { 3173 result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); 3174 result.SetStatus(eReturnStatusFailed); 3175 return false; 3176 } 3177 3178 const char* typeA = command.GetArgumentAtIndex(0); 3179 ConstString typeCS(typeA); 3180 3181 if (!typeCS) 3182 { 3183 result.AppendError("empty typenames not allowed"); 3184 result.SetStatus(eReturnStatusFailed); 3185 return false; 3186 } 3187 3188 if (m_options.m_delete_all) 3189 { 3190 DataVisualization::Categories::LoopThrough(PerCategoryCallback, (void*)&typeCS); 3191 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3192 return result.Succeeded(); 3193 } 3194 3195 lldb::TypeCategoryImplSP category; 3196 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 3197 3198 bool delete_category = category->GetTypeFiltersContainer()->Delete(typeCS); 3199 delete_category = category->GetRegexTypeFiltersContainer()->Delete(typeCS) || delete_category; 3200 3201 if (delete_category) 3202 { 3203 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3204 return result.Succeeded(); 3205 } 3206 else 3207 { 3208 result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA); 3209 result.SetStatus(eReturnStatusFailed); 3210 return false; 3211 } 3212 3213 } 3214 }; 3215 3216 OptionDefinition 3217 CommandObjectTypeFilterDelete::CommandOptions::g_option_table[] = 3218 { 3219 { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Delete from every category."}, 3220 { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Delete from given category."}, 3221 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3222 }; 3223 3224 #ifndef LLDB_DISABLE_PYTHON 3225 3226 //------------------------------------------------------------------------- 3227 // CommandObjectTypeSynthDelete 3228 //------------------------------------------------------------------------- 3229 3230 class CommandObjectTypeSynthDelete : public CommandObjectParsed 3231 { 3232 private: 3233 class CommandOptions : public Options 3234 { 3235 public: 3236 3237 CommandOptions (CommandInterpreter &interpreter) : 3238 Options (interpreter) 3239 { 3240 } 3241 3242 virtual 3243 ~CommandOptions (){} 3244 3245 virtual Error 3246 SetOptionValue (uint32_t option_idx, const char *option_arg) 3247 { 3248 Error error; 3249 const int short_option = m_getopt_table[option_idx].val; 3250 3251 switch (short_option) 3252 { 3253 case 'a': 3254 m_delete_all = true; 3255 break; 3256 case 'w': 3257 m_category = std::string(option_arg); 3258 break; 3259 default: 3260 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3261 break; 3262 } 3263 3264 return error; 3265 } 3266 3267 void 3268 OptionParsingStarting () 3269 { 3270 m_delete_all = false; 3271 m_category = "default"; 3272 } 3273 3274 const OptionDefinition* 3275 GetDefinitions () 3276 { 3277 return g_option_table; 3278 } 3279 3280 // Options table: Required for subclasses of Options. 3281 3282 static OptionDefinition g_option_table[]; 3283 3284 // Instance variables to hold the values for command options. 3285 3286 bool m_delete_all; 3287 std::string m_category; 3288 3289 }; 3290 3291 CommandOptions m_options; 3292 3293 virtual Options * 3294 GetOptions () 3295 { 3296 return &m_options; 3297 } 3298 3299 static bool 3300 PerCategoryCallback(void* param, 3301 const lldb::TypeCategoryImplSP& cate) 3302 { 3303 ConstString* name = (ConstString*)param; 3304 return cate->Delete(*name, eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth); 3305 } 3306 3307 public: 3308 CommandObjectTypeSynthDelete (CommandInterpreter &interpreter) : 3309 CommandObjectParsed (interpreter, 3310 "type synthetic delete", 3311 "Delete an existing synthetic provider for a type.", 3312 NULL), 3313 m_options(interpreter) 3314 { 3315 CommandArgumentEntry type_arg; 3316 CommandArgumentData type_style_arg; 3317 3318 type_style_arg.arg_type = eArgTypeName; 3319 type_style_arg.arg_repetition = eArgRepeatPlain; 3320 3321 type_arg.push_back (type_style_arg); 3322 3323 m_arguments.push_back (type_arg); 3324 3325 } 3326 3327 ~CommandObjectTypeSynthDelete () 3328 { 3329 } 3330 3331 protected: 3332 bool 3333 DoExecute (Args& command, CommandReturnObject &result) 3334 { 3335 const size_t argc = command.GetArgumentCount(); 3336 3337 if (argc != 1) 3338 { 3339 result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); 3340 result.SetStatus(eReturnStatusFailed); 3341 return false; 3342 } 3343 3344 const char* typeA = command.GetArgumentAtIndex(0); 3345 ConstString typeCS(typeA); 3346 3347 if (!typeCS) 3348 { 3349 result.AppendError("empty typenames not allowed"); 3350 result.SetStatus(eReturnStatusFailed); 3351 return false; 3352 } 3353 3354 if (m_options.m_delete_all) 3355 { 3356 DataVisualization::Categories::LoopThrough(PerCategoryCallback, (void*)&typeCS); 3357 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3358 return result.Succeeded(); 3359 } 3360 3361 lldb::TypeCategoryImplSP category; 3362 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 3363 3364 bool delete_category = category->GetTypeSyntheticsContainer()->Delete(typeCS); 3365 delete_category = category->GetRegexTypeSyntheticsContainer()->Delete(typeCS) || delete_category; 3366 3367 if (delete_category) 3368 { 3369 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3370 return result.Succeeded(); 3371 } 3372 else 3373 { 3374 result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA); 3375 result.SetStatus(eReturnStatusFailed); 3376 return false; 3377 } 3378 3379 } 3380 }; 3381 3382 OptionDefinition 3383 CommandObjectTypeSynthDelete::CommandOptions::g_option_table[] = 3384 { 3385 { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Delete from every category."}, 3386 { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Delete from given category."}, 3387 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3388 }; 3389 3390 #endif // #ifndef LLDB_DISABLE_PYTHON 3391 3392 //------------------------------------------------------------------------- 3393 // CommandObjectTypeFilterClear 3394 //------------------------------------------------------------------------- 3395 3396 class CommandObjectTypeFilterClear : public CommandObjectParsed 3397 { 3398 private: 3399 3400 class CommandOptions : public Options 3401 { 3402 public: 3403 3404 CommandOptions (CommandInterpreter &interpreter) : 3405 Options (interpreter) 3406 { 3407 } 3408 3409 virtual 3410 ~CommandOptions (){} 3411 3412 virtual Error 3413 SetOptionValue (uint32_t option_idx, const char *option_arg) 3414 { 3415 Error error; 3416 const int short_option = m_getopt_table[option_idx].val; 3417 3418 switch (short_option) 3419 { 3420 case 'a': 3421 m_delete_all = true; 3422 break; 3423 default: 3424 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3425 break; 3426 } 3427 3428 return error; 3429 } 3430 3431 void 3432 OptionParsingStarting () 3433 { 3434 m_delete_all = false; 3435 } 3436 3437 const OptionDefinition* 3438 GetDefinitions () 3439 { 3440 return g_option_table; 3441 } 3442 3443 // Options table: Required for subclasses of Options. 3444 3445 static OptionDefinition g_option_table[]; 3446 3447 // Instance variables to hold the values for command options. 3448 3449 bool m_delete_all; 3450 bool m_delete_named; 3451 }; 3452 3453 CommandOptions m_options; 3454 3455 virtual Options * 3456 GetOptions () 3457 { 3458 return &m_options; 3459 } 3460 3461 static bool 3462 PerCategoryCallback(void* param, 3463 const lldb::TypeCategoryImplSP& cate) 3464 { 3465 cate->Clear(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter); 3466 return true; 3467 3468 } 3469 3470 public: 3471 CommandObjectTypeFilterClear (CommandInterpreter &interpreter) : 3472 CommandObjectParsed (interpreter, 3473 "type filter clear", 3474 "Delete all existing filters.", 3475 NULL), 3476 m_options(interpreter) 3477 { 3478 } 3479 3480 ~CommandObjectTypeFilterClear () 3481 { 3482 } 3483 3484 protected: 3485 bool 3486 DoExecute (Args& command, CommandReturnObject &result) 3487 { 3488 3489 if (m_options.m_delete_all) 3490 DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL); 3491 3492 else 3493 { 3494 lldb::TypeCategoryImplSP category; 3495 if (command.GetArgumentCount() > 0) 3496 { 3497 const char* cat_name = command.GetArgumentAtIndex(0); 3498 ConstString cat_nameCS(cat_name); 3499 DataVisualization::Categories::GetCategory(cat_nameCS, category); 3500 } 3501 else 3502 DataVisualization::Categories::GetCategory(ConstString(NULL), category); 3503 category->GetTypeFiltersContainer()->Clear(); 3504 category->GetRegexTypeFiltersContainer()->Clear(); 3505 } 3506 3507 result.SetStatus(eReturnStatusSuccessFinishResult); 3508 return result.Succeeded(); 3509 } 3510 3511 }; 3512 3513 OptionDefinition 3514 CommandObjectTypeFilterClear::CommandOptions::g_option_table[] = 3515 { 3516 { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Clear every category."}, 3517 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3518 }; 3519 3520 #ifndef LLDB_DISABLE_PYTHON 3521 //------------------------------------------------------------------------- 3522 // CommandObjectTypeSynthClear 3523 //------------------------------------------------------------------------- 3524 3525 class CommandObjectTypeSynthClear : public CommandObjectParsed 3526 { 3527 private: 3528 3529 class CommandOptions : public Options 3530 { 3531 public: 3532 3533 CommandOptions (CommandInterpreter &interpreter) : 3534 Options (interpreter) 3535 { 3536 } 3537 3538 virtual 3539 ~CommandOptions (){} 3540 3541 virtual Error 3542 SetOptionValue (uint32_t option_idx, const char *option_arg) 3543 { 3544 Error error; 3545 const int short_option = m_getopt_table[option_idx].val; 3546 3547 switch (short_option) 3548 { 3549 case 'a': 3550 m_delete_all = true; 3551 break; 3552 default: 3553 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3554 break; 3555 } 3556 3557 return error; 3558 } 3559 3560 void 3561 OptionParsingStarting () 3562 { 3563 m_delete_all = false; 3564 } 3565 3566 const OptionDefinition* 3567 GetDefinitions () 3568 { 3569 return g_option_table; 3570 } 3571 3572 // Options table: Required for subclasses of Options. 3573 3574 static OptionDefinition g_option_table[]; 3575 3576 // Instance variables to hold the values for command options. 3577 3578 bool m_delete_all; 3579 bool m_delete_named; 3580 }; 3581 3582 CommandOptions m_options; 3583 3584 virtual Options * 3585 GetOptions () 3586 { 3587 return &m_options; 3588 } 3589 3590 static bool 3591 PerCategoryCallback(void* param, 3592 const lldb::TypeCategoryImplSP& cate) 3593 { 3594 cate->Clear(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth); 3595 return true; 3596 3597 } 3598 3599 public: 3600 CommandObjectTypeSynthClear (CommandInterpreter &interpreter) : 3601 CommandObjectParsed (interpreter, 3602 "type synthetic clear", 3603 "Delete all existing synthetic providers.", 3604 NULL), 3605 m_options(interpreter) 3606 { 3607 } 3608 3609 ~CommandObjectTypeSynthClear () 3610 { 3611 } 3612 3613 protected: 3614 bool 3615 DoExecute (Args& command, CommandReturnObject &result) 3616 { 3617 3618 if (m_options.m_delete_all) 3619 DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL); 3620 3621 else 3622 { 3623 lldb::TypeCategoryImplSP category; 3624 if (command.GetArgumentCount() > 0) 3625 { 3626 const char* cat_name = command.GetArgumentAtIndex(0); 3627 ConstString cat_nameCS(cat_name); 3628 DataVisualization::Categories::GetCategory(cat_nameCS, category); 3629 } 3630 else 3631 DataVisualization::Categories::GetCategory(ConstString(NULL), category); 3632 category->GetTypeSyntheticsContainer()->Clear(); 3633 category->GetRegexTypeSyntheticsContainer()->Clear(); 3634 } 3635 3636 result.SetStatus(eReturnStatusSuccessFinishResult); 3637 return result.Succeeded(); 3638 } 3639 3640 }; 3641 3642 OptionDefinition 3643 CommandObjectTypeSynthClear::CommandOptions::g_option_table[] = 3644 { 3645 { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Clear every category."}, 3646 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3647 }; 3648 3649 3650 //------------------------------------------------------------------------- 3651 // TypeSynthAddInputReader 3652 //------------------------------------------------------------------------- 3653 3654 static const char *g_synth_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n" 3655 "You must define a Python class with these methods:\n" 3656 " def __init__(self, valobj, dict):\n" 3657 " def num_children(self):\n" 3658 " def get_child_at_index(self, index):\n" 3659 " def get_child_index(self, name):\n" 3660 "Optionally, you can also define a method:\n" 3661 " def update(self):\n" 3662 "if your synthetic provider is holding on to any per-object state variables (currently, this is not implemented because of the way LLDB handles instances of SBValue and you should not rely on object persistence and per-object state)\n" 3663 "class synthProvider:"; 3664 3665 class TypeSynthAddInputReader : public InputReaderEZ 3666 { 3667 public: 3668 TypeSynthAddInputReader(Debugger& debugger) : 3669 InputReaderEZ(debugger) 3670 {} 3671 3672 virtual 3673 ~TypeSynthAddInputReader() 3674 { 3675 } 3676 3677 virtual void ActivateHandler(HandlerData& data) 3678 { 3679 StreamSP out_stream = data.GetOutStream(); 3680 bool batch_mode = data.GetBatchMode(); 3681 if (!batch_mode) 3682 { 3683 out_stream->Printf ("%s\n", g_synth_addreader_instructions); 3684 if (data.reader.GetPrompt()) 3685 out_stream->Printf ("%s", data.reader.GetPrompt()); 3686 out_stream->Flush(); 3687 } 3688 } 3689 3690 virtual void ReactivateHandler(HandlerData& data) 3691 { 3692 StreamSP out_stream = data.GetOutStream(); 3693 bool batch_mode = data.GetBatchMode(); 3694 if (data.reader.GetPrompt() && !batch_mode) 3695 { 3696 out_stream->Printf ("%s", data.reader.GetPrompt()); 3697 out_stream->Flush(); 3698 } 3699 } 3700 virtual void GotTokenHandler(HandlerData& data) 3701 { 3702 StreamSP out_stream = data.GetOutStream(); 3703 bool batch_mode = data.GetBatchMode(); 3704 if (data.bytes && data.bytes_len && data.baton) 3705 { 3706 ((SynthAddOptions*)data.baton)->m_user_source.AppendString(data.bytes, data.bytes_len); 3707 } 3708 if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode) 3709 { 3710 out_stream->Printf ("%s", data.reader.GetPrompt()); 3711 out_stream->Flush(); 3712 } 3713 } 3714 virtual void InterruptHandler(HandlerData& data) 3715 { 3716 StreamSP out_stream = data.GetOutStream(); 3717 bool batch_mode = data.GetBatchMode(); 3718 data.reader.SetIsDone (true); 3719 if (!batch_mode) 3720 { 3721 out_stream->Printf ("Warning: No command attached to breakpoint.\n"); 3722 out_stream->Flush(); 3723 } 3724 } 3725 virtual void EOFHandler(HandlerData& data) 3726 { 3727 data.reader.SetIsDone (true); 3728 } 3729 virtual void DoneHandler(HandlerData& data) 3730 { 3731 StreamSP out_stream = data.GetOutStream(); 3732 SynthAddOptions *options_ptr = ((SynthAddOptions*)data.baton); 3733 if (!options_ptr) 3734 { 3735 out_stream->Printf ("internal synchronization data missing.\n"); 3736 out_stream->Flush(); 3737 return; 3738 } 3739 3740 SynthAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope 3741 3742 ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 3743 if (!interpreter) 3744 { 3745 out_stream->Printf ("no script interpreter.\n"); 3746 out_stream->Flush(); 3747 return; 3748 } 3749 std::string class_name_str; 3750 if (!interpreter->GenerateTypeSynthClass (options->m_user_source, 3751 class_name_str)) 3752 { 3753 out_stream->Printf ("unable to generate a class.\n"); 3754 out_stream->Flush(); 3755 return; 3756 } 3757 if (class_name_str.empty()) 3758 { 3759 out_stream->Printf ("unable to obtain a proper name for the class.\n"); 3760 out_stream->Flush(); 3761 return; 3762 } 3763 3764 // everything should be fine now, let's add the synth provider class 3765 3766 SyntheticChildrenSP synth_provider; 3767 synth_provider.reset(new ScriptedSyntheticChildren(SyntheticChildren::Flags().SetCascades(options->m_cascade). 3768 SetSkipPointers(options->m_skip_pointers). 3769 SetSkipReferences(options->m_skip_references), 3770 class_name_str.c_str())); 3771 3772 3773 lldb::TypeCategoryImplSP category; 3774 DataVisualization::Categories::GetCategory(ConstString(options->m_category.c_str()), category); 3775 3776 Error error; 3777 3778 for (size_t i = 0; i < options->m_target_types.GetSize(); i++) 3779 { 3780 const char *type_name = options->m_target_types.GetStringAtIndex(i); 3781 ConstString typeCS(type_name); 3782 if (typeCS) 3783 { 3784 if (!CommandObjectTypeSynthAdd::AddSynth(typeCS, 3785 synth_provider, 3786 options->m_regex ? CommandObjectTypeSynthAdd::eRegexSynth : CommandObjectTypeSynthAdd::eRegularSynth, 3787 options->m_category, 3788 &error)) 3789 { 3790 out_stream->Printf("%s\n", error.AsCString()); 3791 out_stream->Flush(); 3792 return; 3793 } 3794 } 3795 else 3796 { 3797 out_stream->Printf ("invalid type name.\n"); 3798 out_stream->Flush(); 3799 return; 3800 } 3801 } 3802 } 3803 3804 private: 3805 DISALLOW_COPY_AND_ASSIGN (TypeSynthAddInputReader); 3806 }; 3807 3808 void 3809 CommandObjectTypeSynthAdd::CollectPythonScript (SynthAddOptions *options, 3810 CommandReturnObject &result) 3811 { 3812 InputReaderSP reader_sp (new TypeSynthAddInputReader(m_interpreter.GetDebugger())); 3813 if (reader_sp && options) 3814 { 3815 3816 InputReaderEZ::InitializationParameters ipr; 3817 3818 Error err (reader_sp->Initialize (ipr.SetBaton(options).SetPrompt(" "))); 3819 if (err.Success()) 3820 { 3821 m_interpreter.GetDebugger().PushInputReader (reader_sp); 3822 result.SetStatus (eReturnStatusSuccessFinishNoResult); 3823 } 3824 else 3825 { 3826 result.AppendError (err.AsCString()); 3827 result.SetStatus (eReturnStatusFailed); 3828 } 3829 } 3830 else 3831 { 3832 result.AppendError("out of memory"); 3833 result.SetStatus (eReturnStatusFailed); 3834 } 3835 } 3836 3837 bool 3838 CommandObjectTypeSynthAdd::Execute_HandwritePython (Args& command, CommandReturnObject &result) 3839 { 3840 SynthAddOptions *options = new SynthAddOptions ( m_options.m_skip_pointers, 3841 m_options.m_skip_references, 3842 m_options.m_cascade, 3843 m_options.m_regex, 3844 m_options.m_category); 3845 3846 const size_t argc = command.GetArgumentCount(); 3847 3848 for (size_t i = 0; i < argc; i++) 3849 { 3850 const char* typeA = command.GetArgumentAtIndex(i); 3851 if (typeA && *typeA) 3852 options->m_target_types << typeA; 3853 else 3854 { 3855 result.AppendError("empty typenames not allowed"); 3856 result.SetStatus(eReturnStatusFailed); 3857 return false; 3858 } 3859 } 3860 3861 CollectPythonScript(options,result); 3862 return result.Succeeded(); 3863 } 3864 3865 bool 3866 CommandObjectTypeSynthAdd::Execute_PythonClass (Args& command, CommandReturnObject &result) 3867 { 3868 const size_t argc = command.GetArgumentCount(); 3869 3870 if (argc < 1) 3871 { 3872 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); 3873 result.SetStatus(eReturnStatusFailed); 3874 return false; 3875 } 3876 3877 if (m_options.m_class_name.empty() && !m_options.m_input_python) 3878 { 3879 result.AppendErrorWithFormat ("%s needs either a Python class name or -P to directly input Python code.\n", m_cmd_name.c_str()); 3880 result.SetStatus(eReturnStatusFailed); 3881 return false; 3882 } 3883 3884 SyntheticChildrenSP entry; 3885 3886 ScriptedSyntheticChildren* impl = new ScriptedSyntheticChildren(SyntheticChildren::Flags(). 3887 SetCascades(m_options.m_cascade). 3888 SetSkipPointers(m_options.m_skip_pointers). 3889 SetSkipReferences(m_options.m_skip_references), 3890 m_options.m_class_name.c_str()); 3891 3892 entry.reset(impl); 3893 3894 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 3895 3896 if (interpreter && interpreter->CheckObjectExists(impl->GetPythonClassName()) == false) 3897 result.AppendWarning("The provided class does not exist - please define it before attempting to use this synthetic provider"); 3898 3899 // now I have a valid provider, let's add it to every type 3900 3901 lldb::TypeCategoryImplSP category; 3902 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 3903 3904 Error error; 3905 3906 for (size_t i = 0; i < argc; i++) 3907 { 3908 const char* typeA = command.GetArgumentAtIndex(i); 3909 ConstString typeCS(typeA); 3910 if (typeCS) 3911 { 3912 if (!AddSynth(typeCS, 3913 entry, 3914 m_options.m_regex ? eRegexSynth : eRegularSynth, 3915 m_options.m_category, 3916 &error)) 3917 { 3918 result.AppendError(error.AsCString()); 3919 result.SetStatus(eReturnStatusFailed); 3920 return false; 3921 } 3922 } 3923 else 3924 { 3925 result.AppendError("empty typenames not allowed"); 3926 result.SetStatus(eReturnStatusFailed); 3927 return false; 3928 } 3929 } 3930 3931 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3932 return result.Succeeded(); 3933 } 3934 3935 CommandObjectTypeSynthAdd::CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) : 3936 CommandObjectParsed (interpreter, 3937 "type synthetic add", 3938 "Add a new synthetic provider for a type.", 3939 NULL), 3940 m_options (interpreter) 3941 { 3942 CommandArgumentEntry type_arg; 3943 CommandArgumentData type_style_arg; 3944 3945 type_style_arg.arg_type = eArgTypeName; 3946 type_style_arg.arg_repetition = eArgRepeatPlus; 3947 3948 type_arg.push_back (type_style_arg); 3949 3950 m_arguments.push_back (type_arg); 3951 3952 } 3953 3954 bool 3955 CommandObjectTypeSynthAdd::AddSynth(ConstString type_name, 3956 SyntheticChildrenSP entry, 3957 SynthFormatType type, 3958 std::string category_name, 3959 Error* error) 3960 { 3961 lldb::TypeCategoryImplSP category; 3962 DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category); 3963 3964 if (type == eRegularSynth) 3965 { 3966 std::string type_name_str(type_name.GetCString()); 3967 if (type_name_str.compare(type_name_str.length() - 2, 2, "[]") == 0) 3968 { 3969 type_name_str.resize(type_name_str.length()-2); 3970 if (type_name_str.back() != ' ') 3971 type_name_str.append(" \\[[0-9]+\\]"); 3972 else 3973 type_name_str.append("\\[[0-9]+\\]"); 3974 type_name.SetCString(type_name_str.c_str()); 3975 type = eRegularSynth; 3976 } 3977 } 3978 3979 if (category->AnyMatches(type_name, 3980 eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter, 3981 false)) 3982 { 3983 if (error) 3984 error->SetErrorStringWithFormat("cannot add synthetic for type %s when filter is defined in same category!", type_name.AsCString()); 3985 return false; 3986 } 3987 3988 if (type == eRegexSynth) 3989 { 3990 RegularExpressionSP typeRX(new RegularExpression()); 3991 if (!typeRX->Compile(type_name.GetCString())) 3992 { 3993 if (error) 3994 error->SetErrorString("regex format error (maybe this is not really a regex?)"); 3995 return false; 3996 } 3997 3998 category->GetRegexTypeSyntheticsContainer()->Delete(type_name); 3999 category->GetRegexTypeSyntheticsContainer()->Add(typeRX, entry); 4000 4001 return true; 4002 } 4003 else 4004 { 4005 category->GetTypeSyntheticsContainer()->Add(type_name, entry); 4006 return true; 4007 } 4008 } 4009 4010 bool 4011 CommandObjectTypeSynthAdd::DoExecute (Args& command, CommandReturnObject &result) 4012 { 4013 if (m_options.handwrite_python) 4014 return Execute_HandwritePython(command, result); 4015 else if (m_options.is_class_based) 4016 return Execute_PythonClass(command, result); 4017 else 4018 { 4019 result.AppendError("must either provide a children list, a Python class name, or use -P and type a Python class line-by-line"); 4020 result.SetStatus(eReturnStatusFailed); 4021 return false; 4022 } 4023 } 4024 4025 OptionDefinition 4026 CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] = 4027 { 4028 { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, 4029 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, 4030 { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, 4031 { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, 4032 { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypePythonClass, "Use this Python class to produce synthetic children."}, 4033 { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Type Python code to generate a class that provides synthetic children."}, 4034 { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, 4035 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 4036 }; 4037 4038 #endif // #ifndef LLDB_DISABLE_PYTHON 4039 4040 class CommandObjectTypeFilterAdd : public CommandObjectParsed 4041 { 4042 4043 private: 4044 4045 class CommandOptions : public Options 4046 { 4047 typedef std::vector<std::string> option_vector; 4048 public: 4049 4050 CommandOptions (CommandInterpreter &interpreter) : 4051 Options (interpreter) 4052 { 4053 } 4054 4055 virtual 4056 ~CommandOptions (){} 4057 4058 virtual Error 4059 SetOptionValue (uint32_t option_idx, const char *option_arg) 4060 { 4061 Error error; 4062 const int short_option = m_getopt_table[option_idx].val; 4063 bool success; 4064 4065 switch (short_option) 4066 { 4067 case 'C': 4068 m_cascade = Args::StringToBoolean(option_arg, true, &success); 4069 if (!success) 4070 error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg); 4071 break; 4072 case 'c': 4073 m_expr_paths.push_back(option_arg); 4074 has_child_list = true; 4075 break; 4076 case 'p': 4077 m_skip_pointers = true; 4078 break; 4079 case 'r': 4080 m_skip_references = true; 4081 break; 4082 case 'w': 4083 m_category = std::string(option_arg); 4084 break; 4085 case 'x': 4086 m_regex = true; 4087 break; 4088 default: 4089 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 4090 break; 4091 } 4092 4093 return error; 4094 } 4095 4096 void 4097 OptionParsingStarting () 4098 { 4099 m_cascade = true; 4100 m_skip_pointers = false; 4101 m_skip_references = false; 4102 m_category = "default"; 4103 m_expr_paths.clear(); 4104 has_child_list = false; 4105 m_regex = false; 4106 } 4107 4108 const OptionDefinition* 4109 GetDefinitions () 4110 { 4111 return g_option_table; 4112 } 4113 4114 // Options table: Required for subclasses of Options. 4115 4116 static OptionDefinition g_option_table[]; 4117 4118 // Instance variables to hold the values for command options. 4119 4120 bool m_cascade; 4121 bool m_skip_references; 4122 bool m_skip_pointers; 4123 bool m_input_python; 4124 option_vector m_expr_paths; 4125 std::string m_category; 4126 4127 bool has_child_list; 4128 4129 bool m_regex; 4130 4131 typedef option_vector::iterator ExpressionPathsIterator; 4132 }; 4133 4134 CommandOptions m_options; 4135 4136 virtual Options * 4137 GetOptions () 4138 { 4139 return &m_options; 4140 } 4141 4142 enum FilterFormatType 4143 { 4144 eRegularFilter, 4145 eRegexFilter 4146 }; 4147 4148 bool 4149 AddFilter(ConstString type_name, 4150 SyntheticChildrenSP entry, 4151 FilterFormatType type, 4152 std::string category_name, 4153 Error* error) 4154 { 4155 lldb::TypeCategoryImplSP category; 4156 DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category); 4157 4158 if (type == eRegularFilter) 4159 { 4160 std::string type_name_str(type_name.GetCString()); 4161 if (type_name_str.compare(type_name_str.length() - 2, 2, "[]") == 0) 4162 { 4163 type_name_str.resize(type_name_str.length()-2); 4164 if (type_name_str.back() != ' ') 4165 type_name_str.append(" \\[[0-9]+\\]"); 4166 else 4167 type_name_str.append("\\[[0-9]+\\]"); 4168 type_name.SetCString(type_name_str.c_str()); 4169 type = eRegexFilter; 4170 } 4171 } 4172 4173 if (category->AnyMatches(type_name, 4174 eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth, 4175 false)) 4176 { 4177 if (error) 4178 error->SetErrorStringWithFormat("cannot add filter for type %s when synthetic is defined in same category!", type_name.AsCString()); 4179 return false; 4180 } 4181 4182 if (type == eRegexFilter) 4183 { 4184 RegularExpressionSP typeRX(new RegularExpression()); 4185 if (!typeRX->Compile(type_name.GetCString())) 4186 { 4187 if (error) 4188 error->SetErrorString("regex format error (maybe this is not really a regex?)"); 4189 return false; 4190 } 4191 4192 category->GetRegexTypeFiltersContainer()->Delete(type_name); 4193 category->GetRegexTypeFiltersContainer()->Add(typeRX, entry); 4194 4195 return true; 4196 } 4197 else 4198 { 4199 category->GetTypeFiltersContainer()->Add(type_name, entry); 4200 return true; 4201 } 4202 } 4203 4204 4205 public: 4206 4207 CommandObjectTypeFilterAdd (CommandInterpreter &interpreter) : 4208 CommandObjectParsed (interpreter, 4209 "type filter add", 4210 "Add a new filter for a type.", 4211 NULL), 4212 m_options (interpreter) 4213 { 4214 CommandArgumentEntry type_arg; 4215 CommandArgumentData type_style_arg; 4216 4217 type_style_arg.arg_type = eArgTypeName; 4218 type_style_arg.arg_repetition = eArgRepeatPlus; 4219 4220 type_arg.push_back (type_style_arg); 4221 4222 m_arguments.push_back (type_arg); 4223 4224 SetHelpLong( 4225 "Some examples of using this command.\n" 4226 "We use as reference the following snippet of code:\n" 4227 "\n" 4228 "class Foo {;\n" 4229 " int a;\n" 4230 " int b;\n" 4231 " int c;\n" 4232 " int d;\n" 4233 " int e;\n" 4234 " int f;\n" 4235 " int g;\n" 4236 " int h;\n" 4237 " int i;\n" 4238 "} \n" 4239 "Typing:\n" 4240 "type filter add --child a --child g Foo\n" 4241 "frame variable a_foo\n" 4242 "will produce an output where only a and g are displayed\n" 4243 "Other children of a_foo (b,c,d,e,f,h and i) are available by asking for them, as in:\n" 4244 "frame variable a_foo.b a_foo.c ... a_foo.i\n" 4245 "\n" 4246 "Use option --raw to frame variable prevails on the filter\n" 4247 "frame variable a_foo --raw\n" 4248 "shows all the children of a_foo (a thru i) as if no filter was defined\n" 4249 ); 4250 } 4251 4252 ~CommandObjectTypeFilterAdd () 4253 { 4254 } 4255 4256 protected: 4257 bool 4258 DoExecute (Args& command, CommandReturnObject &result) 4259 { 4260 const size_t argc = command.GetArgumentCount(); 4261 4262 if (argc < 1) 4263 { 4264 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); 4265 result.SetStatus(eReturnStatusFailed); 4266 return false; 4267 } 4268 4269 if (m_options.m_expr_paths.size() == 0) 4270 { 4271 result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str()); 4272 result.SetStatus(eReturnStatusFailed); 4273 return false; 4274 } 4275 4276 SyntheticChildrenSP entry; 4277 4278 TypeFilterImpl* impl = new TypeFilterImpl(SyntheticChildren::Flags().SetCascades(m_options.m_cascade). 4279 SetSkipPointers(m_options.m_skip_pointers). 4280 SetSkipReferences(m_options.m_skip_references)); 4281 4282 entry.reset(impl); 4283 4284 // go through the expression paths 4285 CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end(); 4286 4287 for (begin = m_options.m_expr_paths.begin(); begin != end; begin++) 4288 impl->AddExpressionPath(*begin); 4289 4290 4291 // now I have a valid provider, let's add it to every type 4292 4293 lldb::TypeCategoryImplSP category; 4294 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 4295 4296 Error error; 4297 4298 for (size_t i = 0; i < argc; i++) 4299 { 4300 const char* typeA = command.GetArgumentAtIndex(i); 4301 ConstString typeCS(typeA); 4302 if (typeCS) 4303 { 4304 if (!AddFilter(typeCS, 4305 entry, 4306 m_options.m_regex ? eRegexFilter : eRegularFilter, 4307 m_options.m_category, 4308 &error)) 4309 { 4310 result.AppendError(error.AsCString()); 4311 result.SetStatus(eReturnStatusFailed); 4312 return false; 4313 } 4314 } 4315 else 4316 { 4317 result.AppendError("empty typenames not allowed"); 4318 result.SetStatus(eReturnStatusFailed); 4319 return false; 4320 } 4321 } 4322 4323 result.SetStatus(eReturnStatusSuccessFinishNoResult); 4324 return result.Succeeded(); 4325 } 4326 4327 }; 4328 4329 OptionDefinition 4330 CommandObjectTypeFilterAdd::CommandOptions::g_option_table[] = 4331 { 4332 { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, 4333 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, 4334 { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, 4335 { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, 4336 { LLDB_OPT_SET_ALL, false, "child", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeExpressionPath, "Include this expression path in the synthetic view."}, 4337 { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, 4338 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 4339 }; 4340 4341 class CommandObjectTypeFormat : public CommandObjectMultiword 4342 { 4343 public: 4344 CommandObjectTypeFormat (CommandInterpreter &interpreter) : 4345 CommandObjectMultiword (interpreter, 4346 "type format", 4347 "A set of commands for editing variable value display options", 4348 "type format [<sub-command-options>] ") 4349 { 4350 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFormatAdd (interpreter))); 4351 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFormatClear (interpreter))); 4352 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFormatDelete (interpreter))); 4353 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFormatList (interpreter))); 4354 } 4355 4356 4357 ~CommandObjectTypeFormat () 4358 { 4359 } 4360 }; 4361 4362 #ifndef LLDB_DISABLE_PYTHON 4363 4364 class CommandObjectTypeSynth : public CommandObjectMultiword 4365 { 4366 public: 4367 CommandObjectTypeSynth (CommandInterpreter &interpreter) : 4368 CommandObjectMultiword (interpreter, 4369 "type synthetic", 4370 "A set of commands for operating on synthetic type representations", 4371 "type synthetic [<sub-command-options>] ") 4372 { 4373 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSynthAdd (interpreter))); 4374 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSynthClear (interpreter))); 4375 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSynthDelete (interpreter))); 4376 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSynthList (interpreter))); 4377 } 4378 4379 4380 ~CommandObjectTypeSynth () 4381 { 4382 } 4383 }; 4384 4385 #endif // #ifndef LLDB_DISABLE_PYTHON 4386 4387 class CommandObjectTypeFilter : public CommandObjectMultiword 4388 { 4389 public: 4390 CommandObjectTypeFilter (CommandInterpreter &interpreter) : 4391 CommandObjectMultiword (interpreter, 4392 "type filter", 4393 "A set of commands for operating on type filters", 4394 "type synthetic [<sub-command-options>] ") 4395 { 4396 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFilterAdd (interpreter))); 4397 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFilterClear (interpreter))); 4398 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFilterDelete (interpreter))); 4399 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFilterList (interpreter))); 4400 } 4401 4402 4403 ~CommandObjectTypeFilter () 4404 { 4405 } 4406 }; 4407 4408 class CommandObjectTypeCategory : public CommandObjectMultiword 4409 { 4410 public: 4411 CommandObjectTypeCategory (CommandInterpreter &interpreter) : 4412 CommandObjectMultiword (interpreter, 4413 "type category", 4414 "A set of commands for operating on categories", 4415 "type category [<sub-command-options>] ") 4416 { 4417 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTypeCategoryEnable (interpreter))); 4418 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTypeCategoryDisable (interpreter))); 4419 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeCategoryDelete (interpreter))); 4420 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeCategoryList (interpreter))); 4421 } 4422 4423 4424 ~CommandObjectTypeCategory () 4425 { 4426 } 4427 }; 4428 4429 class CommandObjectTypeSummary : public CommandObjectMultiword 4430 { 4431 public: 4432 CommandObjectTypeSummary (CommandInterpreter &interpreter) : 4433 CommandObjectMultiword (interpreter, 4434 "type summary", 4435 "A set of commands for editing variable summary display options", 4436 "type summary [<sub-command-options>] ") 4437 { 4438 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSummaryAdd (interpreter))); 4439 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSummaryClear (interpreter))); 4440 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSummaryDelete (interpreter))); 4441 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSummaryList (interpreter))); 4442 } 4443 4444 4445 ~CommandObjectTypeSummary () 4446 { 4447 } 4448 }; 4449 4450 //------------------------------------------------------------------------- 4451 // CommandObjectType 4452 //------------------------------------------------------------------------- 4453 4454 CommandObjectType::CommandObjectType (CommandInterpreter &interpreter) : 4455 CommandObjectMultiword (interpreter, 4456 "type", 4457 "A set of commands for operating on the type system", 4458 "type [<sub-command-options>]") 4459 { 4460 LoadSubCommand ("category", CommandObjectSP (new CommandObjectTypeCategory (interpreter))); 4461 LoadSubCommand ("filter", CommandObjectSP (new CommandObjectTypeFilter (interpreter))); 4462 LoadSubCommand ("format", CommandObjectSP (new CommandObjectTypeFormat (interpreter))); 4463 LoadSubCommand ("summary", CommandObjectSP (new CommandObjectTypeSummary (interpreter))); 4464 #ifndef LLDB_DISABLE_PYTHON 4465 LoadSubCommand ("synthetic", CommandObjectSP (new CommandObjectTypeSynth (interpreter))); 4466 #endif 4467 } 4468 4469 4470 CommandObjectType::~CommandObjectType () 4471 { 4472 } 4473 4474 4475