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