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, 0, eArgTypeName, "Add this to the given category instead of the default one."}, 882 { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, 883 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, 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, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, 885 { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, 886 { LLDB_OPT_SET_2, false, "type", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Format variables as if they were of this type."}, 887 { 0, false, NULL, 0, 0, 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, 0, eArgTypeNone, "Delete from every category."}, 1060 { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Delete from given category."}, 1061 { 0, false, NULL, 0, 0, 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, 0, eArgTypeNone, "Clear every category."}, 1188 { 0, false, NULL, 0, 0, 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, 0, eArgTypeName, "Only show categories matching this filter."}, 1401 { 0, false, NULL, 0, 0, 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, 0, eArgTypeName, "Add this to the given category instead of the default one."}, 1886 { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, 1887 { LLDB_OPT_SET_ALL, false, "no-value", 'v', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't show the value, just show the summary, for this type."}, 1888 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, 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, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, 1890 { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, 1891 { LLDB_OPT_SET_1 , true, "inline-children", 'c', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "If true, inline all child values into summary string."}, 1892 { LLDB_OPT_SET_1 , false, "omit-names", 'O', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "If true, omit value names in the summary display."}, 1893 { LLDB_OPT_SET_2 , true, "summary-string", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeSummaryString, "Summary string used to display text and object contents."}, 1894 { LLDB_OPT_SET_3, false, "python-script", 'o', OptionParser::eRequiredArgument, 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, 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, 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, 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, 0, eArgTypeName, "A name for this summary string."}, 1899 { 0, false, NULL, 0, 0, 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, 0, eArgTypeNone, "Delete from every category."}, 2065 { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Delete from given category."}, 2066 { 0, false, NULL, 0, 0, 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, 0, eArgTypeNone, "Clear every category."}, 2192 { 0, false, NULL, 0, 0, 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, 0, eArgTypeName, "Only show categories matching this filter."}, 2421 { 0, false, NULL, 0, 0, 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 // we want to make sure to enable "system" last and "default" first 2469 DataVisualization::Categories::Enable(ConstString("default"), TypeCategoryMap::First); 2470 uint32_t num_categories = DataVisualization::Categories::GetCount(); 2471 for (uint32_t i = 0; i < num_categories; i++) 2472 { 2473 lldb::TypeCategoryImplSP category_sp = DataVisualization::Categories::GetCategoryAtIndex(i); 2474 if (category_sp) 2475 { 2476 if ( ::strcmp(category_sp->GetName(), "system") == 0 || 2477 ::strcmp(category_sp->GetName(), "default") == 0 ) 2478 continue; 2479 else 2480 DataVisualization::Categories::Enable(category_sp, TypeCategoryMap::Default); 2481 } 2482 } 2483 DataVisualization::Categories::Enable(ConstString("system"), TypeCategoryMap::Last); 2484 } 2485 else 2486 { 2487 for (int i = argc - 1; i >= 0; i--) 2488 { 2489 const char* typeA = command.GetArgumentAtIndex(i); 2490 ConstString typeCS(typeA); 2491 2492 if (!typeCS) 2493 { 2494 result.AppendError("empty category name not allowed"); 2495 result.SetStatus(eReturnStatusFailed); 2496 return false; 2497 } 2498 DataVisualization::Categories::Enable(typeCS); 2499 lldb::TypeCategoryImplSP cate; 2500 if (DataVisualization::Categories::GetCategory(typeCS, cate) && cate.get()) 2501 { 2502 if (cate->GetCount() == 0) 2503 { 2504 result.AppendWarning("empty category enabled (typo?)"); 2505 } 2506 } 2507 } 2508 } 2509 2510 result.SetStatus(eReturnStatusSuccessFinishResult); 2511 return result.Succeeded(); 2512 } 2513 2514 }; 2515 2516 //------------------------------------------------------------------------- 2517 // CommandObjectTypeCategoryDelete 2518 //------------------------------------------------------------------------- 2519 2520 class CommandObjectTypeCategoryDelete : public CommandObjectParsed 2521 { 2522 public: 2523 CommandObjectTypeCategoryDelete (CommandInterpreter &interpreter) : 2524 CommandObjectParsed (interpreter, 2525 "type category delete", 2526 "Delete a category and all associated formatters.", 2527 NULL) 2528 { 2529 CommandArgumentEntry type_arg; 2530 CommandArgumentData type_style_arg; 2531 2532 type_style_arg.arg_type = eArgTypeName; 2533 type_style_arg.arg_repetition = eArgRepeatPlus; 2534 2535 type_arg.push_back (type_style_arg); 2536 2537 m_arguments.push_back (type_arg); 2538 2539 } 2540 2541 ~CommandObjectTypeCategoryDelete () 2542 { 2543 } 2544 2545 protected: 2546 bool 2547 DoExecute (Args& command, CommandReturnObject &result) 2548 { 2549 const size_t argc = command.GetArgumentCount(); 2550 2551 if (argc < 1) 2552 { 2553 result.AppendErrorWithFormat ("%s takes 1 or more arg.\n", m_cmd_name.c_str()); 2554 result.SetStatus(eReturnStatusFailed); 2555 return false; 2556 } 2557 2558 bool success = true; 2559 2560 // the order is not relevant here 2561 for (int i = argc - 1; i >= 0; i--) 2562 { 2563 const char* typeA = command.GetArgumentAtIndex(i); 2564 ConstString typeCS(typeA); 2565 2566 if (!typeCS) 2567 { 2568 result.AppendError("empty category name not allowed"); 2569 result.SetStatus(eReturnStatusFailed); 2570 return false; 2571 } 2572 if (!DataVisualization::Categories::Delete(typeCS)) 2573 success = false; // keep deleting even if we hit an error 2574 } 2575 if (success) 2576 { 2577 result.SetStatus(eReturnStatusSuccessFinishResult); 2578 return result.Succeeded(); 2579 } 2580 else 2581 { 2582 result.AppendError("cannot delete one or more categories\n"); 2583 result.SetStatus(eReturnStatusFailed); 2584 return false; 2585 } 2586 } 2587 }; 2588 2589 //------------------------------------------------------------------------- 2590 // CommandObjectTypeCategoryDisable 2591 //------------------------------------------------------------------------- 2592 2593 class CommandObjectTypeCategoryDisable : public CommandObjectParsed 2594 { 2595 public: 2596 CommandObjectTypeCategoryDisable (CommandInterpreter &interpreter) : 2597 CommandObjectParsed (interpreter, 2598 "type category disable", 2599 "Disable a category as a source of formatters.", 2600 NULL) 2601 { 2602 CommandArgumentEntry type_arg; 2603 CommandArgumentData type_style_arg; 2604 2605 type_style_arg.arg_type = eArgTypeName; 2606 type_style_arg.arg_repetition = eArgRepeatPlus; 2607 2608 type_arg.push_back (type_style_arg); 2609 2610 m_arguments.push_back (type_arg); 2611 2612 } 2613 2614 ~CommandObjectTypeCategoryDisable () 2615 { 2616 } 2617 2618 protected: 2619 bool 2620 DoExecute (Args& command, CommandReturnObject &result) 2621 { 2622 const size_t argc = command.GetArgumentCount(); 2623 2624 if (argc < 1) 2625 { 2626 result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str()); 2627 result.SetStatus(eReturnStatusFailed); 2628 return false; 2629 } 2630 2631 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0) 2632 { 2633 uint32_t num_categories = DataVisualization::Categories::GetCount(); 2634 for (uint32_t i = 0; i < num_categories; i++) 2635 { 2636 lldb::TypeCategoryImplSP category_sp = DataVisualization::Categories::GetCategoryAtIndex(i); 2637 // no need to check if the category is enabled - disabling a disabled category has no effect 2638 if (category_sp) 2639 DataVisualization::Categories::Disable(category_sp); 2640 } 2641 } 2642 else 2643 { 2644 // the order is not relevant here 2645 for (int i = argc - 1; i >= 0; i--) 2646 { 2647 const char* typeA = command.GetArgumentAtIndex(i); 2648 ConstString typeCS(typeA); 2649 2650 if (!typeCS) 2651 { 2652 result.AppendError("empty category name not allowed"); 2653 result.SetStatus(eReturnStatusFailed); 2654 return false; 2655 } 2656 DataVisualization::Categories::Disable(typeCS); 2657 } 2658 } 2659 2660 result.SetStatus(eReturnStatusSuccessFinishResult); 2661 return result.Succeeded(); 2662 } 2663 2664 }; 2665 2666 //------------------------------------------------------------------------- 2667 // CommandObjectTypeCategoryList 2668 //------------------------------------------------------------------------- 2669 2670 class CommandObjectTypeCategoryList : public CommandObjectParsed 2671 { 2672 private: 2673 2674 struct CommandObjectTypeCategoryList_CallbackParam 2675 { 2676 CommandReturnObject* result; 2677 RegularExpression* regex; 2678 2679 CommandObjectTypeCategoryList_CallbackParam(CommandReturnObject* res, 2680 RegularExpression* rex = NULL) : 2681 result(res), 2682 regex(rex) 2683 { 2684 } 2685 2686 }; 2687 2688 static bool 2689 PerCategoryCallback(void* param_vp, 2690 const lldb::TypeCategoryImplSP& cate) 2691 { 2692 CommandObjectTypeCategoryList_CallbackParam* param = 2693 (CommandObjectTypeCategoryList_CallbackParam*)param_vp; 2694 CommandReturnObject* result = param->result; 2695 RegularExpression* regex = param->regex; 2696 2697 const char* cate_name = cate->GetName(); 2698 2699 if (regex == NULL || strcmp(cate_name, regex->GetText()) == 0 || regex->Execute(cate_name)) 2700 result->GetOutputStream().Printf("Category %s is%s enabled\n", 2701 cate_name, 2702 (cate->IsEnabled() ? "" : " not")); 2703 return true; 2704 } 2705 public: 2706 CommandObjectTypeCategoryList (CommandInterpreter &interpreter) : 2707 CommandObjectParsed (interpreter, 2708 "type category list", 2709 "Provide a list of all existing categories.", 2710 NULL) 2711 { 2712 CommandArgumentEntry type_arg; 2713 CommandArgumentData type_style_arg; 2714 2715 type_style_arg.arg_type = eArgTypeName; 2716 type_style_arg.arg_repetition = eArgRepeatOptional; 2717 2718 type_arg.push_back (type_style_arg); 2719 2720 m_arguments.push_back (type_arg); 2721 } 2722 2723 ~CommandObjectTypeCategoryList () 2724 { 2725 } 2726 2727 protected: 2728 bool 2729 DoExecute (Args& command, CommandReturnObject &result) 2730 { 2731 const size_t argc = command.GetArgumentCount(); 2732 RegularExpression* regex = NULL; 2733 2734 if (argc == 0) 2735 ; 2736 else if (argc == 1) 2737 regex = new RegularExpression(command.GetArgumentAtIndex(0)); 2738 else 2739 { 2740 result.AppendErrorWithFormat ("%s takes 0 or one arg.\n", m_cmd_name.c_str()); 2741 result.SetStatus(eReturnStatusFailed); 2742 return false; 2743 } 2744 2745 CommandObjectTypeCategoryList_CallbackParam param(&result, 2746 regex); 2747 2748 DataVisualization::Categories::LoopThrough(PerCategoryCallback, ¶m); 2749 2750 if (regex) 2751 delete regex; 2752 2753 result.SetStatus(eReturnStatusSuccessFinishResult); 2754 return result.Succeeded(); 2755 } 2756 2757 }; 2758 2759 //------------------------------------------------------------------------- 2760 // CommandObjectTypeFilterList 2761 //------------------------------------------------------------------------- 2762 2763 bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); 2764 bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); 2765 2766 class CommandObjectTypeFilterList; 2767 2768 struct CommandObjectTypeFilterList_LoopCallbackParam { 2769 CommandObjectTypeFilterList* self; 2770 CommandReturnObject* result; 2771 RegularExpression* regex; 2772 RegularExpression* cate_regex; 2773 CommandObjectTypeFilterList_LoopCallbackParam(CommandObjectTypeFilterList* S, CommandReturnObject* R, 2774 RegularExpression* X = NULL, 2775 RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {} 2776 }; 2777 2778 class CommandObjectTypeFilterList : public CommandObjectParsed 2779 { 2780 2781 class CommandOptions : public Options 2782 { 2783 public: 2784 2785 CommandOptions (CommandInterpreter &interpreter) : 2786 Options (interpreter) 2787 { 2788 } 2789 2790 virtual 2791 ~CommandOptions (){} 2792 2793 virtual Error 2794 SetOptionValue (uint32_t option_idx, const char *option_arg) 2795 { 2796 Error error; 2797 const int short_option = m_getopt_table[option_idx].val; 2798 2799 switch (short_option) 2800 { 2801 case 'w': 2802 m_category_regex = std::string(option_arg); 2803 break; 2804 default: 2805 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 2806 break; 2807 } 2808 2809 return error; 2810 } 2811 2812 void 2813 OptionParsingStarting () 2814 { 2815 m_category_regex = ""; 2816 } 2817 2818 const OptionDefinition* 2819 GetDefinitions () 2820 { 2821 return g_option_table; 2822 } 2823 2824 // Options table: Required for subclasses of Options. 2825 2826 static OptionDefinition g_option_table[]; 2827 2828 // Instance variables to hold the values for command options. 2829 2830 std::string m_category_regex; 2831 2832 }; 2833 2834 CommandOptions m_options; 2835 2836 virtual Options * 2837 GetOptions () 2838 { 2839 return &m_options; 2840 } 2841 2842 public: 2843 CommandObjectTypeFilterList (CommandInterpreter &interpreter) : 2844 CommandObjectParsed (interpreter, 2845 "type filter list", 2846 "Show a list of current filters.", 2847 NULL), 2848 m_options(interpreter) 2849 { 2850 CommandArgumentEntry type_arg; 2851 CommandArgumentData type_style_arg; 2852 2853 type_style_arg.arg_type = eArgTypeName; 2854 type_style_arg.arg_repetition = eArgRepeatOptional; 2855 2856 type_arg.push_back (type_style_arg); 2857 2858 m_arguments.push_back (type_arg); 2859 } 2860 2861 ~CommandObjectTypeFilterList () 2862 { 2863 } 2864 2865 protected: 2866 bool 2867 DoExecute (Args& command, CommandReturnObject &result) 2868 { 2869 const size_t argc = command.GetArgumentCount(); 2870 2871 CommandObjectTypeFilterList_LoopCallbackParam *param; 2872 RegularExpression* cate_regex = 2873 m_options.m_category_regex.empty() ? NULL : 2874 new RegularExpression(m_options.m_category_regex.c_str()); 2875 2876 if (argc == 1) 2877 { 2878 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); 2879 regex->Compile(command.GetArgumentAtIndex(0)); 2880 param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,regex,cate_regex); 2881 } 2882 else 2883 param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,NULL,cate_regex); 2884 2885 DataVisualization::Categories::LoopThrough(PerCategoryCallback,param); 2886 delete param; 2887 2888 if (cate_regex) 2889 delete cate_regex; 2890 2891 result.SetStatus(eReturnStatusSuccessFinishResult); 2892 return result.Succeeded(); 2893 } 2894 2895 private: 2896 2897 static bool 2898 PerCategoryCallback(void* param_vp, 2899 const lldb::TypeCategoryImplSP& cate) 2900 { 2901 2902 const char* cate_name = cate->GetName(); 2903 2904 CommandObjectTypeFilterList_LoopCallbackParam* param = 2905 (CommandObjectTypeFilterList_LoopCallbackParam*)param_vp; 2906 CommandReturnObject* result = param->result; 2907 2908 // if the category is disabled or empty and there is no regex, just skip it 2909 if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter) == 0) && param->cate_regex == NULL) 2910 return true; 2911 2912 // if we have a regex and this category does not match it, just skip it 2913 if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false) 2914 return true; 2915 2916 result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n", 2917 cate_name, 2918 (cate->IsEnabled() ? "enabled" : "disabled")); 2919 2920 cate->GetTypeFiltersContainer()->LoopThrough(CommandObjectTypeFilterList_LoopCallback, param_vp); 2921 2922 if (cate->GetRegexTypeFiltersContainer()->GetCount() > 0) 2923 { 2924 result->GetOutputStream().Printf("Regex-based filters (slower):\n"); 2925 cate->GetRegexTypeFiltersContainer()->LoopThrough(CommandObjectTypeFilterRXList_LoopCallback, param_vp); 2926 } 2927 2928 return true; 2929 } 2930 2931 bool 2932 LoopCallback (const char* type, 2933 const SyntheticChildren::SharedPointer& entry, 2934 RegularExpression* regex, 2935 CommandReturnObject *result) 2936 { 2937 if (regex == NULL || regex->Execute(type)) 2938 result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str()); 2939 return true; 2940 } 2941 2942 friend bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); 2943 friend bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); 2944 }; 2945 2946 bool 2947 CommandObjectTypeFilterList_LoopCallback (void* pt2self, 2948 ConstString type, 2949 const SyntheticChildren::SharedPointer& entry) 2950 { 2951 CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self; 2952 return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result); 2953 } 2954 2955 bool 2956 CommandObjectTypeFilterRXList_LoopCallback (void* pt2self, 2957 lldb::RegularExpressionSP regex, 2958 const SyntheticChildren::SharedPointer& entry) 2959 { 2960 CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self; 2961 return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); 2962 } 2963 2964 2965 OptionDefinition 2966 CommandObjectTypeFilterList::CommandOptions::g_option_table[] = 2967 { 2968 { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, 2969 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 2970 }; 2971 2972 #ifndef LLDB_DISABLE_PYTHON 2973 2974 //------------------------------------------------------------------------- 2975 // CommandObjectTypeSynthList 2976 //------------------------------------------------------------------------- 2977 2978 bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); 2979 bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); 2980 2981 class CommandObjectTypeSynthList; 2982 2983 struct CommandObjectTypeSynthList_LoopCallbackParam { 2984 CommandObjectTypeSynthList* self; 2985 CommandReturnObject* result; 2986 RegularExpression* regex; 2987 RegularExpression* cate_regex; 2988 CommandObjectTypeSynthList_LoopCallbackParam(CommandObjectTypeSynthList* S, CommandReturnObject* R, 2989 RegularExpression* X = NULL, 2990 RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {} 2991 }; 2992 2993 class CommandObjectTypeSynthList : public CommandObjectParsed 2994 { 2995 2996 class CommandOptions : public Options 2997 { 2998 public: 2999 3000 CommandOptions (CommandInterpreter &interpreter) : 3001 Options (interpreter) 3002 { 3003 } 3004 3005 virtual 3006 ~CommandOptions (){} 3007 3008 virtual Error 3009 SetOptionValue (uint32_t option_idx, const char *option_arg) 3010 { 3011 Error error; 3012 const int short_option = m_getopt_table[option_idx].val; 3013 3014 switch (short_option) 3015 { 3016 case 'w': 3017 m_category_regex = std::string(option_arg); 3018 break; 3019 default: 3020 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3021 break; 3022 } 3023 3024 return error; 3025 } 3026 3027 void 3028 OptionParsingStarting () 3029 { 3030 m_category_regex = ""; 3031 } 3032 3033 const OptionDefinition* 3034 GetDefinitions () 3035 { 3036 return g_option_table; 3037 } 3038 3039 // Options table: Required for subclasses of Options. 3040 3041 static OptionDefinition g_option_table[]; 3042 3043 // Instance variables to hold the values for command options. 3044 3045 std::string m_category_regex; 3046 3047 }; 3048 3049 CommandOptions m_options; 3050 3051 virtual Options * 3052 GetOptions () 3053 { 3054 return &m_options; 3055 } 3056 3057 public: 3058 CommandObjectTypeSynthList (CommandInterpreter &interpreter) : 3059 CommandObjectParsed (interpreter, 3060 "type synthetic list", 3061 "Show a list of current synthetic providers.", 3062 NULL), 3063 m_options(interpreter) 3064 { 3065 CommandArgumentEntry type_arg; 3066 CommandArgumentData type_style_arg; 3067 3068 type_style_arg.arg_type = eArgTypeName; 3069 type_style_arg.arg_repetition = eArgRepeatOptional; 3070 3071 type_arg.push_back (type_style_arg); 3072 3073 m_arguments.push_back (type_arg); 3074 } 3075 3076 ~CommandObjectTypeSynthList () 3077 { 3078 } 3079 3080 protected: 3081 bool 3082 DoExecute (Args& command, CommandReturnObject &result) 3083 { 3084 const size_t argc = command.GetArgumentCount(); 3085 3086 CommandObjectTypeSynthList_LoopCallbackParam *param; 3087 RegularExpression* cate_regex = 3088 m_options.m_category_regex.empty() ? NULL : 3089 new RegularExpression(m_options.m_category_regex.c_str()); 3090 3091 if (argc == 1) 3092 { 3093 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); 3094 regex->Compile(command.GetArgumentAtIndex(0)); 3095 param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,regex,cate_regex); 3096 } 3097 else 3098 param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,NULL,cate_regex); 3099 3100 DataVisualization::Categories::LoopThrough(PerCategoryCallback,param); 3101 delete param; 3102 3103 if (cate_regex) 3104 delete cate_regex; 3105 3106 result.SetStatus(eReturnStatusSuccessFinishResult); 3107 return result.Succeeded(); 3108 } 3109 3110 private: 3111 3112 static bool 3113 PerCategoryCallback(void* param_vp, 3114 const lldb::TypeCategoryImplSP& cate) 3115 { 3116 3117 CommandObjectTypeSynthList_LoopCallbackParam* param = 3118 (CommandObjectTypeSynthList_LoopCallbackParam*)param_vp; 3119 CommandReturnObject* result = param->result; 3120 3121 const char* cate_name = cate->GetName(); 3122 3123 // if the category is disabled or empty and there is no regex, just skip it 3124 if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth) == 0) && param->cate_regex == NULL) 3125 return true; 3126 3127 // if we have a regex and this category does not match it, just skip it 3128 if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false) 3129 return true; 3130 3131 result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n", 3132 cate_name, 3133 (cate->IsEnabled() ? "enabled" : "disabled")); 3134 3135 cate->GetTypeSyntheticsContainer()->LoopThrough(CommandObjectTypeSynthList_LoopCallback, param_vp); 3136 3137 if (cate->GetRegexTypeSyntheticsContainer()->GetCount() > 0) 3138 { 3139 result->GetOutputStream().Printf("Regex-based synthetic providers (slower):\n"); 3140 cate->GetRegexTypeSyntheticsContainer()->LoopThrough(CommandObjectTypeSynthRXList_LoopCallback, param_vp); 3141 } 3142 3143 return true; 3144 } 3145 3146 bool 3147 LoopCallback (const char* type, 3148 const SyntheticChildren::SharedPointer& entry, 3149 RegularExpression* regex, 3150 CommandReturnObject *result) 3151 { 3152 if (regex == NULL || regex->Execute(type)) 3153 result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str()); 3154 return true; 3155 } 3156 3157 friend bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); 3158 friend bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); 3159 }; 3160 3161 bool 3162 CommandObjectTypeSynthList_LoopCallback (void* pt2self, 3163 ConstString type, 3164 const SyntheticChildren::SharedPointer& entry) 3165 { 3166 CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self; 3167 return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result); 3168 } 3169 3170 bool 3171 CommandObjectTypeSynthRXList_LoopCallback (void* pt2self, 3172 lldb::RegularExpressionSP regex, 3173 const SyntheticChildren::SharedPointer& entry) 3174 { 3175 CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self; 3176 return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); 3177 } 3178 3179 3180 OptionDefinition 3181 CommandObjectTypeSynthList::CommandOptions::g_option_table[] = 3182 { 3183 { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, 3184 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3185 }; 3186 3187 #endif // #ifndef LLDB_DISABLE_PYTHON 3188 //------------------------------------------------------------------------- 3189 // CommandObjectTypeFilterDelete 3190 //------------------------------------------------------------------------- 3191 3192 class CommandObjectTypeFilterDelete : public CommandObjectParsed 3193 { 3194 private: 3195 class CommandOptions : public Options 3196 { 3197 public: 3198 3199 CommandOptions (CommandInterpreter &interpreter) : 3200 Options (interpreter) 3201 { 3202 } 3203 3204 virtual 3205 ~CommandOptions (){} 3206 3207 virtual Error 3208 SetOptionValue (uint32_t option_idx, const char *option_arg) 3209 { 3210 Error error; 3211 const int short_option = m_getopt_table[option_idx].val; 3212 3213 switch (short_option) 3214 { 3215 case 'a': 3216 m_delete_all = true; 3217 break; 3218 case 'w': 3219 m_category = std::string(option_arg); 3220 break; 3221 default: 3222 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3223 break; 3224 } 3225 3226 return error; 3227 } 3228 3229 void 3230 OptionParsingStarting () 3231 { 3232 m_delete_all = false; 3233 m_category = "default"; 3234 } 3235 3236 const OptionDefinition* 3237 GetDefinitions () 3238 { 3239 return g_option_table; 3240 } 3241 3242 // Options table: Required for subclasses of Options. 3243 3244 static OptionDefinition g_option_table[]; 3245 3246 // Instance variables to hold the values for command options. 3247 3248 bool m_delete_all; 3249 std::string m_category; 3250 3251 }; 3252 3253 CommandOptions m_options; 3254 3255 virtual Options * 3256 GetOptions () 3257 { 3258 return &m_options; 3259 } 3260 3261 static bool 3262 PerCategoryCallback(void* param, 3263 const lldb::TypeCategoryImplSP& cate) 3264 { 3265 ConstString *name = (ConstString*)param; 3266 return cate->Delete(*name, eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter); 3267 } 3268 3269 public: 3270 CommandObjectTypeFilterDelete (CommandInterpreter &interpreter) : 3271 CommandObjectParsed (interpreter, 3272 "type filter delete", 3273 "Delete an existing filter for a type.", 3274 NULL), 3275 m_options(interpreter) 3276 { 3277 CommandArgumentEntry type_arg; 3278 CommandArgumentData type_style_arg; 3279 3280 type_style_arg.arg_type = eArgTypeName; 3281 type_style_arg.arg_repetition = eArgRepeatPlain; 3282 3283 type_arg.push_back (type_style_arg); 3284 3285 m_arguments.push_back (type_arg); 3286 3287 } 3288 3289 ~CommandObjectTypeFilterDelete () 3290 { 3291 } 3292 3293 protected: 3294 bool 3295 DoExecute (Args& command, CommandReturnObject &result) 3296 { 3297 const size_t argc = command.GetArgumentCount(); 3298 3299 if (argc != 1) 3300 { 3301 result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); 3302 result.SetStatus(eReturnStatusFailed); 3303 return false; 3304 } 3305 3306 const char* typeA = command.GetArgumentAtIndex(0); 3307 ConstString typeCS(typeA); 3308 3309 if (!typeCS) 3310 { 3311 result.AppendError("empty typenames not allowed"); 3312 result.SetStatus(eReturnStatusFailed); 3313 return false; 3314 } 3315 3316 if (m_options.m_delete_all) 3317 { 3318 DataVisualization::Categories::LoopThrough(PerCategoryCallback, (void*)&typeCS); 3319 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3320 return result.Succeeded(); 3321 } 3322 3323 lldb::TypeCategoryImplSP category; 3324 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 3325 3326 bool delete_category = category->GetTypeFiltersContainer()->Delete(typeCS); 3327 delete_category = category->GetRegexTypeFiltersContainer()->Delete(typeCS) || delete_category; 3328 3329 if (delete_category) 3330 { 3331 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3332 return result.Succeeded(); 3333 } 3334 else 3335 { 3336 result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA); 3337 result.SetStatus(eReturnStatusFailed); 3338 return false; 3339 } 3340 3341 } 3342 }; 3343 3344 OptionDefinition 3345 CommandObjectTypeFilterDelete::CommandOptions::g_option_table[] = 3346 { 3347 { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Delete from every category."}, 3348 { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Delete from given category."}, 3349 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3350 }; 3351 3352 #ifndef LLDB_DISABLE_PYTHON 3353 3354 //------------------------------------------------------------------------- 3355 // CommandObjectTypeSynthDelete 3356 //------------------------------------------------------------------------- 3357 3358 class CommandObjectTypeSynthDelete : public CommandObjectParsed 3359 { 3360 private: 3361 class CommandOptions : public Options 3362 { 3363 public: 3364 3365 CommandOptions (CommandInterpreter &interpreter) : 3366 Options (interpreter) 3367 { 3368 } 3369 3370 virtual 3371 ~CommandOptions (){} 3372 3373 virtual Error 3374 SetOptionValue (uint32_t option_idx, const char *option_arg) 3375 { 3376 Error error; 3377 const int short_option = m_getopt_table[option_idx].val; 3378 3379 switch (short_option) 3380 { 3381 case 'a': 3382 m_delete_all = true; 3383 break; 3384 case 'w': 3385 m_category = std::string(option_arg); 3386 break; 3387 default: 3388 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3389 break; 3390 } 3391 3392 return error; 3393 } 3394 3395 void 3396 OptionParsingStarting () 3397 { 3398 m_delete_all = false; 3399 m_category = "default"; 3400 } 3401 3402 const OptionDefinition* 3403 GetDefinitions () 3404 { 3405 return g_option_table; 3406 } 3407 3408 // Options table: Required for subclasses of Options. 3409 3410 static OptionDefinition g_option_table[]; 3411 3412 // Instance variables to hold the values for command options. 3413 3414 bool m_delete_all; 3415 std::string m_category; 3416 3417 }; 3418 3419 CommandOptions m_options; 3420 3421 virtual Options * 3422 GetOptions () 3423 { 3424 return &m_options; 3425 } 3426 3427 static bool 3428 PerCategoryCallback(void* param, 3429 const lldb::TypeCategoryImplSP& cate) 3430 { 3431 ConstString* name = (ConstString*)param; 3432 return cate->Delete(*name, eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth); 3433 } 3434 3435 public: 3436 CommandObjectTypeSynthDelete (CommandInterpreter &interpreter) : 3437 CommandObjectParsed (interpreter, 3438 "type synthetic delete", 3439 "Delete an existing synthetic provider for a type.", 3440 NULL), 3441 m_options(interpreter) 3442 { 3443 CommandArgumentEntry type_arg; 3444 CommandArgumentData type_style_arg; 3445 3446 type_style_arg.arg_type = eArgTypeName; 3447 type_style_arg.arg_repetition = eArgRepeatPlain; 3448 3449 type_arg.push_back (type_style_arg); 3450 3451 m_arguments.push_back (type_arg); 3452 3453 } 3454 3455 ~CommandObjectTypeSynthDelete () 3456 { 3457 } 3458 3459 protected: 3460 bool 3461 DoExecute (Args& command, CommandReturnObject &result) 3462 { 3463 const size_t argc = command.GetArgumentCount(); 3464 3465 if (argc != 1) 3466 { 3467 result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); 3468 result.SetStatus(eReturnStatusFailed); 3469 return false; 3470 } 3471 3472 const char* typeA = command.GetArgumentAtIndex(0); 3473 ConstString typeCS(typeA); 3474 3475 if (!typeCS) 3476 { 3477 result.AppendError("empty typenames not allowed"); 3478 result.SetStatus(eReturnStatusFailed); 3479 return false; 3480 } 3481 3482 if (m_options.m_delete_all) 3483 { 3484 DataVisualization::Categories::LoopThrough(PerCategoryCallback, (void*)&typeCS); 3485 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3486 return result.Succeeded(); 3487 } 3488 3489 lldb::TypeCategoryImplSP category; 3490 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 3491 3492 bool delete_category = category->GetTypeSyntheticsContainer()->Delete(typeCS); 3493 delete_category = category->GetRegexTypeSyntheticsContainer()->Delete(typeCS) || delete_category; 3494 3495 if (delete_category) 3496 { 3497 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3498 return result.Succeeded(); 3499 } 3500 else 3501 { 3502 result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA); 3503 result.SetStatus(eReturnStatusFailed); 3504 return false; 3505 } 3506 3507 } 3508 }; 3509 3510 OptionDefinition 3511 CommandObjectTypeSynthDelete::CommandOptions::g_option_table[] = 3512 { 3513 { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Delete from every category."}, 3514 { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Delete from given category."}, 3515 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3516 }; 3517 3518 #endif // #ifndef LLDB_DISABLE_PYTHON 3519 3520 //------------------------------------------------------------------------- 3521 // CommandObjectTypeFilterClear 3522 //------------------------------------------------------------------------- 3523 3524 class CommandObjectTypeFilterClear : public CommandObjectParsed 3525 { 3526 private: 3527 3528 class CommandOptions : public Options 3529 { 3530 public: 3531 3532 CommandOptions (CommandInterpreter &interpreter) : 3533 Options (interpreter) 3534 { 3535 } 3536 3537 virtual 3538 ~CommandOptions (){} 3539 3540 virtual Error 3541 SetOptionValue (uint32_t option_idx, const char *option_arg) 3542 { 3543 Error error; 3544 const int short_option = m_getopt_table[option_idx].val; 3545 3546 switch (short_option) 3547 { 3548 case 'a': 3549 m_delete_all = true; 3550 break; 3551 default: 3552 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3553 break; 3554 } 3555 3556 return error; 3557 } 3558 3559 void 3560 OptionParsingStarting () 3561 { 3562 m_delete_all = false; 3563 } 3564 3565 const OptionDefinition* 3566 GetDefinitions () 3567 { 3568 return g_option_table; 3569 } 3570 3571 // Options table: Required for subclasses of Options. 3572 3573 static OptionDefinition g_option_table[]; 3574 3575 // Instance variables to hold the values for command options. 3576 3577 bool m_delete_all; 3578 bool m_delete_named; 3579 }; 3580 3581 CommandOptions m_options; 3582 3583 virtual Options * 3584 GetOptions () 3585 { 3586 return &m_options; 3587 } 3588 3589 static bool 3590 PerCategoryCallback(void* param, 3591 const lldb::TypeCategoryImplSP& cate) 3592 { 3593 cate->Clear(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter); 3594 return true; 3595 3596 } 3597 3598 public: 3599 CommandObjectTypeFilterClear (CommandInterpreter &interpreter) : 3600 CommandObjectParsed (interpreter, 3601 "type filter clear", 3602 "Delete all existing filters.", 3603 NULL), 3604 m_options(interpreter) 3605 { 3606 } 3607 3608 ~CommandObjectTypeFilterClear () 3609 { 3610 } 3611 3612 protected: 3613 bool 3614 DoExecute (Args& command, CommandReturnObject &result) 3615 { 3616 3617 if (m_options.m_delete_all) 3618 DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL); 3619 3620 else 3621 { 3622 lldb::TypeCategoryImplSP category; 3623 if (command.GetArgumentCount() > 0) 3624 { 3625 const char* cat_name = command.GetArgumentAtIndex(0); 3626 ConstString cat_nameCS(cat_name); 3627 DataVisualization::Categories::GetCategory(cat_nameCS, category); 3628 } 3629 else 3630 DataVisualization::Categories::GetCategory(ConstString(NULL), category); 3631 category->GetTypeFiltersContainer()->Clear(); 3632 category->GetRegexTypeFiltersContainer()->Clear(); 3633 } 3634 3635 result.SetStatus(eReturnStatusSuccessFinishResult); 3636 return result.Succeeded(); 3637 } 3638 3639 }; 3640 3641 OptionDefinition 3642 CommandObjectTypeFilterClear::CommandOptions::g_option_table[] = 3643 { 3644 { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Clear every category."}, 3645 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3646 }; 3647 3648 #ifndef LLDB_DISABLE_PYTHON 3649 //------------------------------------------------------------------------- 3650 // CommandObjectTypeSynthClear 3651 //------------------------------------------------------------------------- 3652 3653 class CommandObjectTypeSynthClear : public CommandObjectParsed 3654 { 3655 private: 3656 3657 class CommandOptions : public Options 3658 { 3659 public: 3660 3661 CommandOptions (CommandInterpreter &interpreter) : 3662 Options (interpreter) 3663 { 3664 } 3665 3666 virtual 3667 ~CommandOptions (){} 3668 3669 virtual Error 3670 SetOptionValue (uint32_t option_idx, const char *option_arg) 3671 { 3672 Error error; 3673 const int short_option = m_getopt_table[option_idx].val; 3674 3675 switch (short_option) 3676 { 3677 case 'a': 3678 m_delete_all = true; 3679 break; 3680 default: 3681 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3682 break; 3683 } 3684 3685 return error; 3686 } 3687 3688 void 3689 OptionParsingStarting () 3690 { 3691 m_delete_all = false; 3692 } 3693 3694 const OptionDefinition* 3695 GetDefinitions () 3696 { 3697 return g_option_table; 3698 } 3699 3700 // Options table: Required for subclasses of Options. 3701 3702 static OptionDefinition g_option_table[]; 3703 3704 // Instance variables to hold the values for command options. 3705 3706 bool m_delete_all; 3707 bool m_delete_named; 3708 }; 3709 3710 CommandOptions m_options; 3711 3712 virtual Options * 3713 GetOptions () 3714 { 3715 return &m_options; 3716 } 3717 3718 static bool 3719 PerCategoryCallback(void* param, 3720 const lldb::TypeCategoryImplSP& cate) 3721 { 3722 cate->Clear(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth); 3723 return true; 3724 3725 } 3726 3727 public: 3728 CommandObjectTypeSynthClear (CommandInterpreter &interpreter) : 3729 CommandObjectParsed (interpreter, 3730 "type synthetic clear", 3731 "Delete all existing synthetic providers.", 3732 NULL), 3733 m_options(interpreter) 3734 { 3735 } 3736 3737 ~CommandObjectTypeSynthClear () 3738 { 3739 } 3740 3741 protected: 3742 bool 3743 DoExecute (Args& command, CommandReturnObject &result) 3744 { 3745 3746 if (m_options.m_delete_all) 3747 DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL); 3748 3749 else 3750 { 3751 lldb::TypeCategoryImplSP category; 3752 if (command.GetArgumentCount() > 0) 3753 { 3754 const char* cat_name = command.GetArgumentAtIndex(0); 3755 ConstString cat_nameCS(cat_name); 3756 DataVisualization::Categories::GetCategory(cat_nameCS, category); 3757 } 3758 else 3759 DataVisualization::Categories::GetCategory(ConstString(NULL), category); 3760 category->GetTypeSyntheticsContainer()->Clear(); 3761 category->GetRegexTypeSyntheticsContainer()->Clear(); 3762 } 3763 3764 result.SetStatus(eReturnStatusSuccessFinishResult); 3765 return result.Succeeded(); 3766 } 3767 3768 }; 3769 3770 OptionDefinition 3771 CommandObjectTypeSynthClear::CommandOptions::g_option_table[] = 3772 { 3773 { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Clear every category."}, 3774 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3775 }; 3776 3777 3778 bool 3779 CommandObjectTypeSynthAdd::Execute_HandwritePython (Args& command, CommandReturnObject &result) 3780 { 3781 SynthAddOptions *options = new SynthAddOptions ( m_options.m_skip_pointers, 3782 m_options.m_skip_references, 3783 m_options.m_cascade, 3784 m_options.m_regex, 3785 m_options.m_category); 3786 3787 const size_t argc = command.GetArgumentCount(); 3788 3789 for (size_t i = 0; i < argc; i++) 3790 { 3791 const char* typeA = command.GetArgumentAtIndex(i); 3792 if (typeA && *typeA) 3793 options->m_target_types << typeA; 3794 else 3795 { 3796 result.AppendError("empty typenames not allowed"); 3797 result.SetStatus(eReturnStatusFailed); 3798 return false; 3799 } 3800 } 3801 3802 m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt 3803 *this, // IOHandlerDelegate 3804 true, // Run IOHandler in async mode 3805 options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions 3806 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3807 return result.Succeeded(); 3808 } 3809 3810 bool 3811 CommandObjectTypeSynthAdd::Execute_PythonClass (Args& command, CommandReturnObject &result) 3812 { 3813 const size_t argc = command.GetArgumentCount(); 3814 3815 if (argc < 1) 3816 { 3817 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); 3818 result.SetStatus(eReturnStatusFailed); 3819 return false; 3820 } 3821 3822 if (m_options.m_class_name.empty() && !m_options.m_input_python) 3823 { 3824 result.AppendErrorWithFormat ("%s needs either a Python class name or -P to directly input Python code.\n", m_cmd_name.c_str()); 3825 result.SetStatus(eReturnStatusFailed); 3826 return false; 3827 } 3828 3829 SyntheticChildrenSP entry; 3830 3831 ScriptedSyntheticChildren* impl = new ScriptedSyntheticChildren(SyntheticChildren::Flags(). 3832 SetCascades(m_options.m_cascade). 3833 SetSkipPointers(m_options.m_skip_pointers). 3834 SetSkipReferences(m_options.m_skip_references), 3835 m_options.m_class_name.c_str()); 3836 3837 entry.reset(impl); 3838 3839 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 3840 3841 if (interpreter && interpreter->CheckObjectExists(impl->GetPythonClassName()) == false) 3842 result.AppendWarning("The provided class does not exist - please define it before attempting to use this synthetic provider"); 3843 3844 // now I have a valid provider, let's add it to every type 3845 3846 lldb::TypeCategoryImplSP category; 3847 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 3848 3849 Error error; 3850 3851 for (size_t i = 0; i < argc; i++) 3852 { 3853 const char* typeA = command.GetArgumentAtIndex(i); 3854 ConstString typeCS(typeA); 3855 if (typeCS) 3856 { 3857 if (!AddSynth(typeCS, 3858 entry, 3859 m_options.m_regex ? eRegexSynth : eRegularSynth, 3860 m_options.m_category, 3861 &error)) 3862 { 3863 result.AppendError(error.AsCString()); 3864 result.SetStatus(eReturnStatusFailed); 3865 return false; 3866 } 3867 } 3868 else 3869 { 3870 result.AppendError("empty typenames not allowed"); 3871 result.SetStatus(eReturnStatusFailed); 3872 return false; 3873 } 3874 } 3875 3876 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3877 return result.Succeeded(); 3878 } 3879 3880 CommandObjectTypeSynthAdd::CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) : 3881 CommandObjectParsed (interpreter, 3882 "type synthetic add", 3883 "Add a new synthetic provider for a type.", 3884 NULL), 3885 IOHandlerDelegateMultiline ("DONE"), 3886 m_options (interpreter) 3887 { 3888 CommandArgumentEntry type_arg; 3889 CommandArgumentData type_style_arg; 3890 3891 type_style_arg.arg_type = eArgTypeName; 3892 type_style_arg.arg_repetition = eArgRepeatPlus; 3893 3894 type_arg.push_back (type_style_arg); 3895 3896 m_arguments.push_back (type_arg); 3897 3898 } 3899 3900 bool 3901 CommandObjectTypeSynthAdd::AddSynth(ConstString type_name, 3902 SyntheticChildrenSP entry, 3903 SynthFormatType type, 3904 std::string category_name, 3905 Error* error) 3906 { 3907 lldb::TypeCategoryImplSP category; 3908 DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category); 3909 3910 if (type == eRegularSynth) 3911 { 3912 if (FixArrayTypeNameWithRegex (type_name)) 3913 type = eRegexSynth; 3914 } 3915 3916 if (category->AnyMatches(type_name, 3917 eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter, 3918 false)) 3919 { 3920 if (error) 3921 error->SetErrorStringWithFormat("cannot add synthetic for type %s when filter is defined in same category!", type_name.AsCString()); 3922 return false; 3923 } 3924 3925 if (type == eRegexSynth) 3926 { 3927 RegularExpressionSP typeRX(new RegularExpression()); 3928 if (!typeRX->Compile(type_name.GetCString())) 3929 { 3930 if (error) 3931 error->SetErrorString("regex format error (maybe this is not really a regex?)"); 3932 return false; 3933 } 3934 3935 category->GetRegexTypeSyntheticsContainer()->Delete(type_name); 3936 category->GetRegexTypeSyntheticsContainer()->Add(typeRX, entry); 3937 3938 return true; 3939 } 3940 else 3941 { 3942 category->GetTypeSyntheticsContainer()->Add(type_name, entry); 3943 return true; 3944 } 3945 } 3946 3947 OptionDefinition 3948 CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] = 3949 { 3950 { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, 3951 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, 3952 { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, 3953 { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, 3954 { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, NULL, 0, eArgTypePythonClass, "Use this Python class to produce synthetic children."}, 3955 { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Type Python code to generate a class that provides synthetic children."}, 3956 { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, 3957 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3958 }; 3959 3960 #endif // #ifndef LLDB_DISABLE_PYTHON 3961 3962 class CommandObjectTypeFilterAdd : public CommandObjectParsed 3963 { 3964 3965 private: 3966 3967 class CommandOptions : public Options 3968 { 3969 typedef std::vector<std::string> option_vector; 3970 public: 3971 3972 CommandOptions (CommandInterpreter &interpreter) : 3973 Options (interpreter) 3974 { 3975 } 3976 3977 virtual 3978 ~CommandOptions (){} 3979 3980 virtual Error 3981 SetOptionValue (uint32_t option_idx, const char *option_arg) 3982 { 3983 Error error; 3984 const int short_option = m_getopt_table[option_idx].val; 3985 bool success; 3986 3987 switch (short_option) 3988 { 3989 case 'C': 3990 m_cascade = Args::StringToBoolean(option_arg, true, &success); 3991 if (!success) 3992 error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg); 3993 break; 3994 case 'c': 3995 m_expr_paths.push_back(option_arg); 3996 has_child_list = true; 3997 break; 3998 case 'p': 3999 m_skip_pointers = true; 4000 break; 4001 case 'r': 4002 m_skip_references = true; 4003 break; 4004 case 'w': 4005 m_category = std::string(option_arg); 4006 break; 4007 case 'x': 4008 m_regex = true; 4009 break; 4010 default: 4011 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 4012 break; 4013 } 4014 4015 return error; 4016 } 4017 4018 void 4019 OptionParsingStarting () 4020 { 4021 m_cascade = true; 4022 m_skip_pointers = false; 4023 m_skip_references = false; 4024 m_category = "default"; 4025 m_expr_paths.clear(); 4026 has_child_list = false; 4027 m_regex = false; 4028 } 4029 4030 const OptionDefinition* 4031 GetDefinitions () 4032 { 4033 return g_option_table; 4034 } 4035 4036 // Options table: Required for subclasses of Options. 4037 4038 static OptionDefinition g_option_table[]; 4039 4040 // Instance variables to hold the values for command options. 4041 4042 bool m_cascade; 4043 bool m_skip_references; 4044 bool m_skip_pointers; 4045 bool m_input_python; 4046 option_vector m_expr_paths; 4047 std::string m_category; 4048 4049 bool has_child_list; 4050 4051 bool m_regex; 4052 4053 typedef option_vector::iterator ExpressionPathsIterator; 4054 }; 4055 4056 CommandOptions m_options; 4057 4058 virtual Options * 4059 GetOptions () 4060 { 4061 return &m_options; 4062 } 4063 4064 enum FilterFormatType 4065 { 4066 eRegularFilter, 4067 eRegexFilter 4068 }; 4069 4070 bool 4071 AddFilter(ConstString type_name, 4072 SyntheticChildrenSP entry, 4073 FilterFormatType type, 4074 std::string category_name, 4075 Error* error) 4076 { 4077 lldb::TypeCategoryImplSP category; 4078 DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category); 4079 4080 if (type == eRegularFilter) 4081 { 4082 if (FixArrayTypeNameWithRegex (type_name)) 4083 type = eRegexFilter; 4084 } 4085 4086 if (category->AnyMatches(type_name, 4087 eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth, 4088 false)) 4089 { 4090 if (error) 4091 error->SetErrorStringWithFormat("cannot add filter for type %s when synthetic is defined in same category!", type_name.AsCString()); 4092 return false; 4093 } 4094 4095 if (type == eRegexFilter) 4096 { 4097 RegularExpressionSP typeRX(new RegularExpression()); 4098 if (!typeRX->Compile(type_name.GetCString())) 4099 { 4100 if (error) 4101 error->SetErrorString("regex format error (maybe this is not really a regex?)"); 4102 return false; 4103 } 4104 4105 category->GetRegexTypeFiltersContainer()->Delete(type_name); 4106 category->GetRegexTypeFiltersContainer()->Add(typeRX, entry); 4107 4108 return true; 4109 } 4110 else 4111 { 4112 category->GetTypeFiltersContainer()->Add(type_name, entry); 4113 return true; 4114 } 4115 } 4116 4117 4118 public: 4119 4120 CommandObjectTypeFilterAdd (CommandInterpreter &interpreter) : 4121 CommandObjectParsed (interpreter, 4122 "type filter add", 4123 "Add a new filter for a type.", 4124 NULL), 4125 m_options (interpreter) 4126 { 4127 CommandArgumentEntry type_arg; 4128 CommandArgumentData type_style_arg; 4129 4130 type_style_arg.arg_type = eArgTypeName; 4131 type_style_arg.arg_repetition = eArgRepeatPlus; 4132 4133 type_arg.push_back (type_style_arg); 4134 4135 m_arguments.push_back (type_arg); 4136 4137 SetHelpLong( 4138 "Some examples of using this command.\n" 4139 "We use as reference the following snippet of code:\n" 4140 "\n" 4141 "class Foo {;\n" 4142 " int a;\n" 4143 " int b;\n" 4144 " int c;\n" 4145 " int d;\n" 4146 " int e;\n" 4147 " int f;\n" 4148 " int g;\n" 4149 " int h;\n" 4150 " int i;\n" 4151 "} \n" 4152 "Typing:\n" 4153 "type filter add --child a --child g Foo\n" 4154 "frame variable a_foo\n" 4155 "will produce an output where only a and g are displayed\n" 4156 "Other children of a_foo (b,c,d,e,f,h and i) are available by asking for them, as in:\n" 4157 "frame variable a_foo.b a_foo.c ... a_foo.i\n" 4158 "\n" 4159 "Use option --raw to frame variable prevails on the filter\n" 4160 "frame variable a_foo --raw\n" 4161 "shows all the children of a_foo (a thru i) as if no filter was defined\n" 4162 ); 4163 } 4164 4165 ~CommandObjectTypeFilterAdd () 4166 { 4167 } 4168 4169 protected: 4170 bool 4171 DoExecute (Args& command, CommandReturnObject &result) 4172 { 4173 const size_t argc = command.GetArgumentCount(); 4174 4175 if (argc < 1) 4176 { 4177 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); 4178 result.SetStatus(eReturnStatusFailed); 4179 return false; 4180 } 4181 4182 if (m_options.m_expr_paths.size() == 0) 4183 { 4184 result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str()); 4185 result.SetStatus(eReturnStatusFailed); 4186 return false; 4187 } 4188 4189 SyntheticChildrenSP entry; 4190 4191 TypeFilterImpl* impl = new TypeFilterImpl(SyntheticChildren::Flags().SetCascades(m_options.m_cascade). 4192 SetSkipPointers(m_options.m_skip_pointers). 4193 SetSkipReferences(m_options.m_skip_references)); 4194 4195 entry.reset(impl); 4196 4197 // go through the expression paths 4198 CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end(); 4199 4200 for (begin = m_options.m_expr_paths.begin(); begin != end; begin++) 4201 impl->AddExpressionPath(*begin); 4202 4203 4204 // now I have a valid provider, let's add it to every type 4205 4206 lldb::TypeCategoryImplSP category; 4207 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 4208 4209 Error error; 4210 4211 WarnOnPotentialUnquotedUnsignedType(command, result); 4212 4213 for (size_t i = 0; i < argc; i++) 4214 { 4215 const char* typeA = command.GetArgumentAtIndex(i); 4216 ConstString typeCS(typeA); 4217 if (typeCS) 4218 { 4219 if (!AddFilter(typeCS, 4220 entry, 4221 m_options.m_regex ? eRegexFilter : eRegularFilter, 4222 m_options.m_category, 4223 &error)) 4224 { 4225 result.AppendError(error.AsCString()); 4226 result.SetStatus(eReturnStatusFailed); 4227 return false; 4228 } 4229 } 4230 else 4231 { 4232 result.AppendError("empty typenames not allowed"); 4233 result.SetStatus(eReturnStatusFailed); 4234 return false; 4235 } 4236 } 4237 4238 result.SetStatus(eReturnStatusSuccessFinishNoResult); 4239 return result.Succeeded(); 4240 } 4241 4242 }; 4243 4244 OptionDefinition 4245 CommandObjectTypeFilterAdd::CommandOptions::g_option_table[] = 4246 { 4247 { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, 4248 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, 4249 { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, 4250 { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, 4251 { LLDB_OPT_SET_ALL, false, "child", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeExpressionPath, "Include this expression path in the synthetic view."}, 4252 { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, 4253 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 4254 }; 4255 4256 class CommandObjectTypeFormat : public CommandObjectMultiword 4257 { 4258 public: 4259 CommandObjectTypeFormat (CommandInterpreter &interpreter) : 4260 CommandObjectMultiword (interpreter, 4261 "type format", 4262 "A set of commands for editing variable value display options", 4263 "type format [<sub-command-options>] ") 4264 { 4265 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFormatAdd (interpreter))); 4266 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFormatClear (interpreter))); 4267 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFormatDelete (interpreter))); 4268 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFormatList (interpreter))); 4269 } 4270 4271 4272 ~CommandObjectTypeFormat () 4273 { 4274 } 4275 }; 4276 4277 #ifndef LLDB_DISABLE_PYTHON 4278 4279 class CommandObjectTypeSynth : public CommandObjectMultiword 4280 { 4281 public: 4282 CommandObjectTypeSynth (CommandInterpreter &interpreter) : 4283 CommandObjectMultiword (interpreter, 4284 "type synthetic", 4285 "A set of commands for operating on synthetic type representations", 4286 "type synthetic [<sub-command-options>] ") 4287 { 4288 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSynthAdd (interpreter))); 4289 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSynthClear (interpreter))); 4290 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSynthDelete (interpreter))); 4291 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSynthList (interpreter))); 4292 } 4293 4294 4295 ~CommandObjectTypeSynth () 4296 { 4297 } 4298 }; 4299 4300 #endif // #ifndef LLDB_DISABLE_PYTHON 4301 4302 class CommandObjectTypeFilter : public CommandObjectMultiword 4303 { 4304 public: 4305 CommandObjectTypeFilter (CommandInterpreter &interpreter) : 4306 CommandObjectMultiword (interpreter, 4307 "type filter", 4308 "A set of commands for operating on type filters", 4309 "type synthetic [<sub-command-options>] ") 4310 { 4311 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFilterAdd (interpreter))); 4312 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFilterClear (interpreter))); 4313 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFilterDelete (interpreter))); 4314 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFilterList (interpreter))); 4315 } 4316 4317 4318 ~CommandObjectTypeFilter () 4319 { 4320 } 4321 }; 4322 4323 class CommandObjectTypeCategory : public CommandObjectMultiword 4324 { 4325 public: 4326 CommandObjectTypeCategory (CommandInterpreter &interpreter) : 4327 CommandObjectMultiword (interpreter, 4328 "type category", 4329 "A set of commands for operating on categories", 4330 "type category [<sub-command-options>] ") 4331 { 4332 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTypeCategoryEnable (interpreter))); 4333 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTypeCategoryDisable (interpreter))); 4334 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeCategoryDelete (interpreter))); 4335 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeCategoryList (interpreter))); 4336 } 4337 4338 4339 ~CommandObjectTypeCategory () 4340 { 4341 } 4342 }; 4343 4344 class CommandObjectTypeSummary : public CommandObjectMultiword 4345 { 4346 public: 4347 CommandObjectTypeSummary (CommandInterpreter &interpreter) : 4348 CommandObjectMultiword (interpreter, 4349 "type summary", 4350 "A set of commands for editing variable summary display options", 4351 "type summary [<sub-command-options>] ") 4352 { 4353 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSummaryAdd (interpreter))); 4354 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSummaryClear (interpreter))); 4355 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSummaryDelete (interpreter))); 4356 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSummaryList (interpreter))); 4357 } 4358 4359 4360 ~CommandObjectTypeSummary () 4361 { 4362 } 4363 }; 4364 4365 //------------------------------------------------------------------------- 4366 // CommandObjectType 4367 //------------------------------------------------------------------------- 4368 4369 CommandObjectType::CommandObjectType (CommandInterpreter &interpreter) : 4370 CommandObjectMultiword (interpreter, 4371 "type", 4372 "A set of commands for operating on the type system", 4373 "type [<sub-command-options>]") 4374 { 4375 LoadSubCommand ("category", CommandObjectSP (new CommandObjectTypeCategory (interpreter))); 4376 LoadSubCommand ("filter", CommandObjectSP (new CommandObjectTypeFilter (interpreter))); 4377 LoadSubCommand ("format", CommandObjectSP (new CommandObjectTypeFormat (interpreter))); 4378 LoadSubCommand ("summary", CommandObjectSP (new CommandObjectTypeSummary (interpreter))); 4379 #ifndef LLDB_DISABLE_PYTHON 4380 LoadSubCommand ("synthetic", CommandObjectSP (new CommandObjectTypeSynth (interpreter))); 4381 #endif 4382 } 4383 4384 4385 CommandObjectType::~CommandObjectType () 4386 { 4387 } 4388 4389 4390