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