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