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