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