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