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 'v': 1442 m_flags.SetDontShowValue(true); 1443 break; 1444 case 'c': 1445 m_flags.SetShowMembersOneLiner(true); 1446 break; 1447 case 's': 1448 m_format_string = std::string(option_arg); 1449 break; 1450 case 'p': 1451 m_flags.SetSkipPointers(true); 1452 break; 1453 case 'r': 1454 m_flags.SetSkipReferences(true); 1455 break; 1456 case 'x': 1457 m_regex = true; 1458 break; 1459 case 'n': 1460 m_name.SetCString(option_arg); 1461 break; 1462 case 'o': 1463 m_python_script = std::string(option_arg); 1464 m_is_add_script = true; 1465 break; 1466 case 'F': 1467 m_python_function = std::string(option_arg); 1468 m_is_add_script = true; 1469 break; 1470 case 'P': 1471 m_is_add_script = true; 1472 break; 1473 case 'w': 1474 m_category = std::string(option_arg); 1475 break; 1476 case 'O': 1477 m_flags.SetHideItemNames(true); 1478 break; 1479 default: 1480 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1481 break; 1482 } 1483 1484 return error; 1485 } 1486 1487 void 1488 CommandObjectTypeSummaryAdd::CommandOptions::OptionParsingStarting () 1489 { 1490 m_flags.Clear().SetCascades().SetDontShowChildren().SetDontShowValue(false); 1491 m_flags.SetShowMembersOneLiner(false).SetSkipPointers(false).SetSkipReferences(false).SetHideItemNames(false); 1492 1493 m_regex = false; 1494 m_name.Clear(); 1495 m_python_script = ""; 1496 m_python_function = ""; 1497 m_format_string = ""; 1498 m_is_add_script = false; 1499 m_category = "default"; 1500 } 1501 1502 1503 1504 #ifndef LLDB_DISABLE_PYTHON 1505 1506 bool 1507 CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturnObject &result) 1508 { 1509 const size_t argc = command.GetArgumentCount(); 1510 1511 if (argc < 1 && !m_options.m_name) 1512 { 1513 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); 1514 result.SetStatus(eReturnStatusFailed); 1515 return false; 1516 } 1517 1518 TypeSummaryImplSP script_format; 1519 1520 if (!m_options.m_python_function.empty()) // we have a Python function ready to use 1521 { 1522 const char *funct_name = m_options.m_python_function.c_str(); 1523 if (!funct_name || !funct_name[0]) 1524 { 1525 result.AppendError ("function name empty.\n"); 1526 result.SetStatus (eReturnStatusFailed); 1527 return false; 1528 } 1529 1530 std::string code = (" " + m_options.m_python_function + "(valobj,internal_dict)"); 1531 1532 script_format.reset(new ScriptSummaryFormat(m_options.m_flags, 1533 funct_name, 1534 code.c_str())); 1535 1536 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 1537 1538 if (interpreter && interpreter->CheckObjectExists(funct_name) == false) 1539 result.AppendWarningWithFormat("The provided function \"%s\" does not exist - " 1540 "please define it before attempting to use this summary.\n", 1541 funct_name); 1542 } 1543 else if (!m_options.m_python_script.empty()) // we have a quick 1-line script, just use it 1544 { 1545 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 1546 if (!interpreter) 1547 { 1548 result.AppendError ("script interpreter missing - unable to generate function wrapper.\n"); 1549 result.SetStatus (eReturnStatusFailed); 1550 return false; 1551 } 1552 StringList funct_sl; 1553 funct_sl << m_options.m_python_script.c_str(); 1554 std::string funct_name_str; 1555 if (!interpreter->GenerateTypeScriptFunction (funct_sl, 1556 funct_name_str)) 1557 { 1558 result.AppendError ("unable to generate function wrapper.\n"); 1559 result.SetStatus (eReturnStatusFailed); 1560 return false; 1561 } 1562 if (funct_name_str.empty()) 1563 { 1564 result.AppendError ("script interpreter failed to generate a valid function name.\n"); 1565 result.SetStatus (eReturnStatusFailed); 1566 return false; 1567 } 1568 1569 std::string code = " " + m_options.m_python_script; 1570 1571 script_format.reset(new ScriptSummaryFormat(m_options.m_flags, 1572 funct_name_str.c_str(), 1573 code.c_str())); 1574 } 1575 else 1576 { 1577 // Use an IOHandler to grab Python code from the user 1578 ScriptAddOptions *options = new ScriptAddOptions(m_options.m_flags, 1579 m_options.m_regex, 1580 m_options.m_name, 1581 m_options.m_category); 1582 1583 for (size_t i = 0; i < argc; i++) 1584 { 1585 const char* typeA = command.GetArgumentAtIndex(i); 1586 if (typeA && *typeA) 1587 options->m_target_types << typeA; 1588 else 1589 { 1590 result.AppendError("empty typenames not allowed"); 1591 result.SetStatus(eReturnStatusFailed); 1592 return false; 1593 } 1594 } 1595 1596 m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt 1597 *this, // IOHandlerDelegate 1598 true, // Run IOHandler in async mode 1599 options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions 1600 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1601 1602 return result.Succeeded(); 1603 } 1604 1605 // if I am here, script_format must point to something good, so I can add that 1606 // as a script summary to all interested parties 1607 1608 Error error; 1609 1610 for (size_t i = 0; i < command.GetArgumentCount(); i++) 1611 { 1612 const char *type_name = command.GetArgumentAtIndex(i); 1613 CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name), 1614 script_format, 1615 (m_options.m_regex ? eRegexSummary : eRegularSummary), 1616 m_options.m_category, 1617 &error); 1618 if (error.Fail()) 1619 { 1620 result.AppendError(error.AsCString()); 1621 result.SetStatus(eReturnStatusFailed); 1622 return false; 1623 } 1624 } 1625 1626 if (m_options.m_name) 1627 { 1628 AddSummary(m_options.m_name, script_format, eNamedSummary, m_options.m_category, &error); 1629 if (error.Fail()) 1630 { 1631 result.AppendError(error.AsCString()); 1632 result.AppendError("added to types, but not given a name"); 1633 result.SetStatus(eReturnStatusFailed); 1634 return false; 1635 } 1636 } 1637 1638 return result.Succeeded(); 1639 } 1640 1641 #endif 1642 1643 1644 bool 1645 CommandObjectTypeSummaryAdd::Execute_StringSummary (Args& command, CommandReturnObject &result) 1646 { 1647 const size_t argc = command.GetArgumentCount(); 1648 1649 if (argc < 1 && !m_options.m_name) 1650 { 1651 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); 1652 result.SetStatus(eReturnStatusFailed); 1653 return false; 1654 } 1655 1656 if (!m_options.m_flags.GetShowMembersOneLiner() && m_options.m_format_string.empty()) 1657 { 1658 result.AppendError("empty summary strings not allowed"); 1659 result.SetStatus(eReturnStatusFailed); 1660 return false; 1661 } 1662 1663 const char* format_cstr = (m_options.m_flags.GetShowMembersOneLiner() ? "" : m_options.m_format_string.c_str()); 1664 1665 // ${var%S} is an endless recursion, prevent it 1666 if (strcmp(format_cstr, "${var%S}") == 0) 1667 { 1668 result.AppendError("recursive summary not allowed"); 1669 result.SetStatus(eReturnStatusFailed); 1670 return false; 1671 } 1672 1673 Error error; 1674 1675 lldb::TypeSummaryImplSP entry(new StringSummaryFormat(m_options.m_flags, 1676 format_cstr)); 1677 1678 if (error.Fail()) 1679 { 1680 result.AppendError(error.AsCString()); 1681 result.SetStatus(eReturnStatusFailed); 1682 return false; 1683 } 1684 1685 // now I have a valid format, let's add it to every type 1686 1687 for (size_t i = 0; i < argc; i++) 1688 { 1689 const char* typeA = command.GetArgumentAtIndex(i); 1690 if (!typeA || typeA[0] == '\0') 1691 { 1692 result.AppendError("empty typenames not allowed"); 1693 result.SetStatus(eReturnStatusFailed); 1694 return false; 1695 } 1696 ConstString typeCS(typeA); 1697 1698 AddSummary(typeCS, 1699 entry, 1700 (m_options.m_regex ? eRegexSummary : eRegularSummary), 1701 m_options.m_category, 1702 &error); 1703 1704 if (error.Fail()) 1705 { 1706 result.AppendError(error.AsCString()); 1707 result.SetStatus(eReturnStatusFailed); 1708 return false; 1709 } 1710 } 1711 1712 if (m_options.m_name) 1713 { 1714 AddSummary(m_options.m_name, entry, eNamedSummary, m_options.m_category, &error); 1715 if (error.Fail()) 1716 { 1717 result.AppendError(error.AsCString()); 1718 result.AppendError("added to types, but not given a name"); 1719 result.SetStatus(eReturnStatusFailed); 1720 return false; 1721 } 1722 } 1723 1724 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1725 return result.Succeeded(); 1726 } 1727 1728 CommandObjectTypeSummaryAdd::CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter) : 1729 CommandObjectParsed (interpreter, 1730 "type summary add", 1731 "Add a new summary style for a type.", 1732 NULL), 1733 IOHandlerDelegateMultiline ("DONE"), 1734 m_options (interpreter) 1735 { 1736 CommandArgumentEntry type_arg; 1737 CommandArgumentData type_style_arg; 1738 1739 type_style_arg.arg_type = eArgTypeName; 1740 type_style_arg.arg_repetition = eArgRepeatPlus; 1741 1742 type_arg.push_back (type_style_arg); 1743 1744 m_arguments.push_back (type_arg); 1745 1746 SetHelpLong( 1747 R"( 1748 The following examples of 'type summary add' refer to this code snippet for context: 1749 1750 struct JustADemo 1751 { 1752 int* ptr; 1753 float value; 1754 JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {} 1755 }; 1756 JustADemo demo_instance(42, 3.14); 1757 1758 typedef JustADemo NewDemo; 1759 NewDemo new_demo_instance(42, 3.14); 1760 1761 (lldb) type summary add --summary-string "the answer is ${*var.ptr}" JustADemo 1762 1763 Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42" 1764 1765 (lldb) type summary add --summary-string "the answer is ${*var.ptr}, and the question is ${var.value}" JustADemo 1766 1767 Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42 and the question is 3.14" 1768 1769 )" "Alternatively, you could define formatting for all pointers to integers and \ 1770 rely on that when formatting JustADemo to obtain the same result:" R"( 1771 1772 (lldb) type summary add --summary-string "${var%V} -> ${*var}" "int *" 1773 (lldb) type summary add --summary-string "the answer is ${var.ptr}, and the question is ${var.value}" JustADemo 1774 1775 )" "Type summaries are automatically applied to derived typedefs, so the examples \ 1776 above apply to both JustADemo and NewDemo. The cascade option can be used to \ 1777 suppress this behavior:" R"( 1778 1779 (lldb) type summary add --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo -C no 1780 1781 The summary will now be used for values of JustADemo but not NewDemo. 1782 1783 )" "By default summaries are shown for pointers and references to values of the \ 1784 specified type. To suppress formatting for pointers use the -p option, or apply \ 1785 the corresponding -r option to suppress formatting for references:" R"( 1786 1787 (lldb) type summary add -p -r --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo 1788 1789 )" "One-line summaries including all fields in a type can be inferred without supplying an \ 1790 explicit summary string by passing the -c option:" R"( 1791 1792 (lldb) type summary add -c JustADemo 1793 (lldb) frame variable demo_instance 1794 (ptr=<address>, value=3.14) 1795 1796 )" "Type summaries normally suppress the nested display of individual fields. To \ 1797 supply a summary to supplement the default structure add the -e option:" R"( 1798 1799 (lldb) type summary add -e --summary-string "*ptr = ${*var.ptr}" JustADemo 1800 1801 )" "Now when displaying JustADemo values the int* is displayed, followed by the \ 1802 standard LLDB sequence of children, one per line:" R"( 1803 1804 *ptr = 42 { 1805 ptr = <address> 1806 value = 3.14 1807 } 1808 1809 )" "You can also add summaries written in Python. These scripts use lldb public API to \ 1810 gather information from your variables and produce a meaningful summary. To start a \ 1811 multi-line script use the -P option. The function declaration will be displayed along with \ 1812 a comment describing the two arguments. End your script with the word 'DONE' on a line by \ 1813 itself:" R"( 1814 1815 (lldb) type summary add JustADemo -P 1816 def function (valobj,internal_dict): 1817 """valobj: an SBValue which you want to provide a summary for 1818 internal_dict: an LLDB support object not to be used""" 1819 value = valobj.GetChildMemberWithName('value'); 1820 return 'My value is ' + value.GetValue(); 1821 DONE 1822 1823 Alternatively, the -o option can be used when providing a simple one-line Python script: 1824 1825 (lldb) type summary add JustADemo -o "value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();")" 1826 ); 1827 } 1828 1829 bool 1830 CommandObjectTypeSummaryAdd::DoExecute (Args& command, CommandReturnObject &result) 1831 { 1832 WarnOnPotentialUnquotedUnsignedType(command, result); 1833 1834 if (m_options.m_is_add_script) 1835 { 1836 #ifndef LLDB_DISABLE_PYTHON 1837 return Execute_ScriptSummary(command, result); 1838 #else 1839 result.AppendError ("python is disabled"); 1840 result.SetStatus(eReturnStatusFailed); 1841 return false; 1842 #endif 1843 } 1844 1845 return Execute_StringSummary(command, result); 1846 } 1847 1848 static bool 1849 FixArrayTypeNameWithRegex (ConstString &type_name) 1850 { 1851 llvm::StringRef type_name_ref(type_name.GetStringRef()); 1852 1853 if (type_name_ref.endswith("[]")) 1854 { 1855 std::string type_name_str(type_name.GetCString()); 1856 type_name_str.resize(type_name_str.length()-2); 1857 if (type_name_str.back() != ' ') 1858 type_name_str.append(" \\[[0-9]+\\]"); 1859 else 1860 type_name_str.append("\\[[0-9]+\\]"); 1861 type_name.SetCString(type_name_str.c_str()); 1862 return true; 1863 } 1864 return false; 1865 } 1866 1867 bool 1868 CommandObjectTypeSummaryAdd::AddSummary(ConstString type_name, 1869 TypeSummaryImplSP entry, 1870 SummaryFormatType type, 1871 std::string category_name, 1872 Error* error) 1873 { 1874 lldb::TypeCategoryImplSP category; 1875 DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category); 1876 1877 if (type == eRegularSummary) 1878 { 1879 if (FixArrayTypeNameWithRegex (type_name)) 1880 type = eRegexSummary; 1881 } 1882 1883 if (type == eRegexSummary) 1884 { 1885 RegularExpressionSP typeRX(new RegularExpression()); 1886 if (!typeRX->Compile(type_name.GetCString())) 1887 { 1888 if (error) 1889 error->SetErrorString("regex format error (maybe this is not really a regex?)"); 1890 return false; 1891 } 1892 1893 category->GetRegexTypeSummariesContainer()->Delete(type_name); 1894 category->GetRegexTypeSummariesContainer()->Add(typeRX, entry); 1895 1896 return true; 1897 } 1898 else if (type == eNamedSummary) 1899 { 1900 // system named summaries do not exist (yet?) 1901 DataVisualization::NamedSummaryFormats::Add(type_name,entry); 1902 return true; 1903 } 1904 else 1905 { 1906 category->GetTypeSummariesContainer()->Add(type_name, entry); 1907 return true; 1908 } 1909 } 1910 1911 OptionDefinition 1912 CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] = 1913 { 1914 { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, 1915 { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, 1916 { 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."}, 1917 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, 1918 { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, 1919 { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, 1920 { LLDB_OPT_SET_1 , true, "inline-children", 'c', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "If true, inline all child values into summary string."}, 1921 { LLDB_OPT_SET_1 , false, "omit-names", 'O', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "If true, omit value names in the summary display."}, 1922 { LLDB_OPT_SET_2 , true, "summary-string", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSummaryString, "Summary string used to display text and object contents."}, 1923 { 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."}, 1924 { 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."}, 1925 { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Input Python code to use for this type manually."}, 1926 { 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."}, 1927 { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "A name for this summary string."}, 1928 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 1929 }; 1930 1931 1932 //------------------------------------------------------------------------- 1933 // CommandObjectTypeSummaryDelete 1934 //------------------------------------------------------------------------- 1935 1936 class CommandObjectTypeSummaryDelete : public CommandObjectParsed 1937 { 1938 private: 1939 class CommandOptions : public Options 1940 { 1941 public: 1942 1943 CommandOptions (CommandInterpreter &interpreter) : 1944 Options (interpreter) 1945 { 1946 } 1947 1948 virtual 1949 ~CommandOptions (){} 1950 1951 virtual Error 1952 SetOptionValue (uint32_t option_idx, const char *option_arg) 1953 { 1954 Error error; 1955 const int short_option = m_getopt_table[option_idx].val; 1956 1957 switch (short_option) 1958 { 1959 case 'a': 1960 m_delete_all = true; 1961 break; 1962 case 'w': 1963 m_category = std::string(option_arg); 1964 break; 1965 default: 1966 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1967 break; 1968 } 1969 1970 return error; 1971 } 1972 1973 void 1974 OptionParsingStarting () 1975 { 1976 m_delete_all = false; 1977 m_category = "default"; 1978 } 1979 1980 const OptionDefinition* 1981 GetDefinitions () 1982 { 1983 return g_option_table; 1984 } 1985 1986 // Options table: Required for subclasses of Options. 1987 1988 static OptionDefinition g_option_table[]; 1989 1990 // Instance variables to hold the values for command options. 1991 1992 bool m_delete_all; 1993 std::string m_category; 1994 1995 }; 1996 1997 CommandOptions m_options; 1998 1999 virtual Options * 2000 GetOptions () 2001 { 2002 return &m_options; 2003 } 2004 2005 static bool 2006 PerCategoryCallback(void* param, 2007 const lldb::TypeCategoryImplSP& category_sp) 2008 { 2009 ConstString *name = (ConstString*)param; 2010 category_sp->Delete(*name, eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary); 2011 return true; 2012 } 2013 2014 public: 2015 CommandObjectTypeSummaryDelete (CommandInterpreter &interpreter) : 2016 CommandObjectParsed (interpreter, 2017 "type summary delete", 2018 "Delete an existing summary style for a type.", 2019 NULL), 2020 m_options(interpreter) 2021 { 2022 CommandArgumentEntry type_arg; 2023 CommandArgumentData type_style_arg; 2024 2025 type_style_arg.arg_type = eArgTypeName; 2026 type_style_arg.arg_repetition = eArgRepeatPlain; 2027 2028 type_arg.push_back (type_style_arg); 2029 2030 m_arguments.push_back (type_arg); 2031 2032 } 2033 2034 ~CommandObjectTypeSummaryDelete () 2035 { 2036 } 2037 2038 protected: 2039 bool 2040 DoExecute (Args& command, CommandReturnObject &result) 2041 { 2042 const size_t argc = command.GetArgumentCount(); 2043 2044 if (argc != 1) 2045 { 2046 result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); 2047 result.SetStatus(eReturnStatusFailed); 2048 return false; 2049 } 2050 2051 const char* typeA = command.GetArgumentAtIndex(0); 2052 ConstString typeCS(typeA); 2053 2054 if (!typeCS) 2055 { 2056 result.AppendError("empty typenames not allowed"); 2057 result.SetStatus(eReturnStatusFailed); 2058 return false; 2059 } 2060 2061 if (m_options.m_delete_all) 2062 { 2063 DataVisualization::Categories::LoopThrough(PerCategoryCallback, &typeCS); 2064 result.SetStatus(eReturnStatusSuccessFinishNoResult); 2065 return result.Succeeded(); 2066 } 2067 2068 lldb::TypeCategoryImplSP category; 2069 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 2070 2071 bool delete_category = category->Delete(typeCS, 2072 eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary); 2073 bool delete_named = DataVisualization::NamedSummaryFormats::Delete(typeCS); 2074 2075 if (delete_category || delete_named) 2076 { 2077 result.SetStatus(eReturnStatusSuccessFinishNoResult); 2078 return result.Succeeded(); 2079 } 2080 else 2081 { 2082 result.AppendErrorWithFormat ("no custom summary for %s.\n", typeA); 2083 result.SetStatus(eReturnStatusFailed); 2084 return false; 2085 } 2086 2087 } 2088 }; 2089 2090 OptionDefinition 2091 CommandObjectTypeSummaryDelete::CommandOptions::g_option_table[] = 2092 { 2093 { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Delete from every category."}, 2094 { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Delete from given category."}, 2095 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 2096 }; 2097 2098 class CommandObjectTypeSummaryClear : public CommandObjectParsed 2099 { 2100 private: 2101 2102 class CommandOptions : public Options 2103 { 2104 public: 2105 2106 CommandOptions (CommandInterpreter &interpreter) : 2107 Options (interpreter) 2108 { 2109 } 2110 2111 virtual 2112 ~CommandOptions (){} 2113 2114 virtual Error 2115 SetOptionValue (uint32_t option_idx, const char *option_arg) 2116 { 2117 Error error; 2118 const int short_option = m_getopt_table[option_idx].val; 2119 2120 switch (short_option) 2121 { 2122 case 'a': 2123 m_delete_all = true; 2124 break; 2125 default: 2126 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 2127 break; 2128 } 2129 2130 return error; 2131 } 2132 2133 void 2134 OptionParsingStarting () 2135 { 2136 m_delete_all = false; 2137 } 2138 2139 const OptionDefinition* 2140 GetDefinitions () 2141 { 2142 return g_option_table; 2143 } 2144 2145 // Options table: Required for subclasses of Options. 2146 2147 static OptionDefinition g_option_table[]; 2148 2149 // Instance variables to hold the values for command options. 2150 2151 bool m_delete_all; 2152 bool m_delete_named; 2153 }; 2154 2155 CommandOptions m_options; 2156 2157 virtual Options * 2158 GetOptions () 2159 { 2160 return &m_options; 2161 } 2162 2163 static bool 2164 PerCategoryCallback(void* param, 2165 const lldb::TypeCategoryImplSP& cate) 2166 { 2167 cate->GetTypeSummariesContainer()->Clear(); 2168 cate->GetRegexTypeSummariesContainer()->Clear(); 2169 return true; 2170 2171 } 2172 2173 public: 2174 CommandObjectTypeSummaryClear (CommandInterpreter &interpreter) : 2175 CommandObjectParsed (interpreter, 2176 "type summary clear", 2177 "Delete all existing summary styles.", 2178 NULL), 2179 m_options(interpreter) 2180 { 2181 } 2182 2183 ~CommandObjectTypeSummaryClear () 2184 { 2185 } 2186 2187 protected: 2188 bool 2189 DoExecute (Args& command, CommandReturnObject &result) 2190 { 2191 2192 if (m_options.m_delete_all) 2193 DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL); 2194 2195 else 2196 { 2197 lldb::TypeCategoryImplSP category; 2198 if (command.GetArgumentCount() > 0) 2199 { 2200 const char* cat_name = command.GetArgumentAtIndex(0); 2201 ConstString cat_nameCS(cat_name); 2202 DataVisualization::Categories::GetCategory(cat_nameCS, category); 2203 } 2204 else 2205 DataVisualization::Categories::GetCategory(ConstString(NULL), category); 2206 category->Clear(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary); 2207 } 2208 2209 DataVisualization::NamedSummaryFormats::Clear(); 2210 2211 result.SetStatus(eReturnStatusSuccessFinishResult); 2212 return result.Succeeded(); 2213 } 2214 2215 }; 2216 2217 OptionDefinition 2218 CommandObjectTypeSummaryClear::CommandOptions::g_option_table[] = 2219 { 2220 { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Clear every category."}, 2221 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 2222 }; 2223 2224 //------------------------------------------------------------------------- 2225 // CommandObjectTypeSummaryList 2226 //------------------------------------------------------------------------- 2227 2228 bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, ConstString type, const StringSummaryFormat::SharedPointer& entry); 2229 bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const StringSummaryFormat::SharedPointer& entry); 2230 2231 class CommandObjectTypeSummaryList; 2232 2233 struct CommandObjectTypeSummaryList_LoopCallbackParam { 2234 CommandObjectTypeSummaryList* self; 2235 CommandReturnObject* result; 2236 RegularExpression* regex; 2237 RegularExpression* cate_regex; 2238 CommandObjectTypeSummaryList_LoopCallbackParam(CommandObjectTypeSummaryList* S, CommandReturnObject* R, 2239 RegularExpression* X = NULL, 2240 RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {} 2241 }; 2242 2243 class CommandObjectTypeSummaryList : public CommandObjectParsed 2244 { 2245 2246 class CommandOptions : public Options 2247 { 2248 public: 2249 2250 CommandOptions (CommandInterpreter &interpreter) : 2251 Options (interpreter) 2252 { 2253 } 2254 2255 virtual 2256 ~CommandOptions (){} 2257 2258 virtual Error 2259 SetOptionValue (uint32_t option_idx, const char *option_arg) 2260 { 2261 Error error; 2262 const int short_option = m_getopt_table[option_idx].val; 2263 2264 switch (short_option) 2265 { 2266 case 'w': 2267 m_category_regex = std::string(option_arg); 2268 break; 2269 default: 2270 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 2271 break; 2272 } 2273 2274 return error; 2275 } 2276 2277 void 2278 OptionParsingStarting () 2279 { 2280 m_category_regex = ""; 2281 } 2282 2283 const OptionDefinition* 2284 GetDefinitions () 2285 { 2286 return g_option_table; 2287 } 2288 2289 // Options table: Required for subclasses of Options. 2290 2291 static OptionDefinition g_option_table[]; 2292 2293 // Instance variables to hold the values for command options. 2294 2295 std::string m_category_regex; 2296 2297 }; 2298 2299 CommandOptions m_options; 2300 2301 virtual Options * 2302 GetOptions () 2303 { 2304 return &m_options; 2305 } 2306 2307 public: 2308 CommandObjectTypeSummaryList (CommandInterpreter &interpreter) : 2309 CommandObjectParsed (interpreter, 2310 "type summary list", 2311 "Show a list of current summary styles.", 2312 NULL), 2313 m_options(interpreter) 2314 { 2315 CommandArgumentEntry type_arg; 2316 CommandArgumentData type_style_arg; 2317 2318 type_style_arg.arg_type = eArgTypeName; 2319 type_style_arg.arg_repetition = eArgRepeatOptional; 2320 2321 type_arg.push_back (type_style_arg); 2322 2323 m_arguments.push_back (type_arg); 2324 } 2325 2326 ~CommandObjectTypeSummaryList () 2327 { 2328 } 2329 2330 protected: 2331 bool 2332 DoExecute (Args& command, CommandReturnObject &result) 2333 { 2334 const size_t argc = command.GetArgumentCount(); 2335 2336 CommandObjectTypeSummaryList_LoopCallbackParam *param; 2337 RegularExpression* cate_regex = 2338 m_options.m_category_regex.empty() ? NULL : 2339 new RegularExpression(m_options.m_category_regex.c_str()); 2340 2341 if (argc == 1) 2342 { 2343 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); 2344 regex->Compile(command.GetArgumentAtIndex(0)); 2345 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex,cate_regex); 2346 } 2347 else 2348 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,NULL,cate_regex); 2349 2350 DataVisualization::Categories::LoopThrough(PerCategoryCallback,param); 2351 delete param; 2352 2353 if (DataVisualization::NamedSummaryFormats::GetCount() > 0) 2354 { 2355 result.GetOutputStream().Printf("Named summaries:\n"); 2356 if (argc == 1) 2357 { 2358 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); 2359 regex->Compile(command.GetArgumentAtIndex(0)); 2360 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex); 2361 } 2362 else 2363 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result); 2364 DataVisualization::NamedSummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param); 2365 delete param; 2366 } 2367 2368 if (cate_regex) 2369 delete cate_regex; 2370 2371 result.SetStatus(eReturnStatusSuccessFinishResult); 2372 return result.Succeeded(); 2373 } 2374 2375 private: 2376 2377 static bool 2378 PerCategoryCallback(void* param_vp, 2379 const lldb::TypeCategoryImplSP& cate) 2380 { 2381 2382 CommandObjectTypeSummaryList_LoopCallbackParam* param = 2383 (CommandObjectTypeSummaryList_LoopCallbackParam*)param_vp; 2384 CommandReturnObject* result = param->result; 2385 2386 const char* cate_name = cate->GetName(); 2387 2388 // if the category is disabled or empty and there is no regex, just skip it 2389 if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary) == 0) && param->cate_regex == NULL) 2390 return true; 2391 2392 // if we have a regex and this category does not match it, just skip it 2393 if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false) 2394 return true; 2395 2396 result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n", 2397 cate_name, 2398 (cate->IsEnabled() ? "enabled" : "disabled")); 2399 2400 cate->GetTypeSummariesContainer()->LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param_vp); 2401 2402 if (cate->GetRegexTypeSummariesContainer()->GetCount() > 0) 2403 { 2404 result->GetOutputStream().Printf("Regex-based summaries (slower):\n"); 2405 cate->GetRegexTypeSummariesContainer()->LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, param_vp); 2406 } 2407 return true; 2408 } 2409 2410 2411 bool 2412 LoopCallback (const char* type, 2413 const lldb::TypeSummaryImplSP& entry, 2414 RegularExpression* regex, 2415 CommandReturnObject *result) 2416 { 2417 if (regex == NULL || strcmp(type,regex->GetText()) == 0 || regex->Execute(type)) 2418 result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str()); 2419 return true; 2420 } 2421 2422 friend bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeSummaryImplSP& entry); 2423 friend bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeSummaryImplSP& entry); 2424 }; 2425 2426 bool 2427 CommandObjectTypeSummaryList_LoopCallback ( 2428 void* pt2self, 2429 ConstString type, 2430 const lldb::TypeSummaryImplSP& entry) 2431 { 2432 CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self; 2433 return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result); 2434 } 2435 2436 bool 2437 CommandObjectTypeRXSummaryList_LoopCallback ( 2438 void* pt2self, 2439 lldb::RegularExpressionSP regex, 2440 const lldb::TypeSummaryImplSP& entry) 2441 { 2442 CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self; 2443 return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); 2444 } 2445 2446 OptionDefinition 2447 CommandObjectTypeSummaryList::CommandOptions::g_option_table[] = 2448 { 2449 { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, 2450 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 2451 }; 2452 2453 //------------------------------------------------------------------------- 2454 // CommandObjectTypeCategoryEnable 2455 //------------------------------------------------------------------------- 2456 2457 class CommandObjectTypeCategoryEnable : public CommandObjectParsed 2458 { 2459 public: 2460 CommandObjectTypeCategoryEnable (CommandInterpreter &interpreter) : 2461 CommandObjectParsed (interpreter, 2462 "type category enable", 2463 "Enable a category as a source of formatters.", 2464 NULL) 2465 { 2466 CommandArgumentEntry type_arg; 2467 CommandArgumentData type_style_arg; 2468 2469 type_style_arg.arg_type = eArgTypeName; 2470 type_style_arg.arg_repetition = eArgRepeatPlus; 2471 2472 type_arg.push_back (type_style_arg); 2473 2474 m_arguments.push_back (type_arg); 2475 2476 } 2477 2478 ~CommandObjectTypeCategoryEnable () 2479 { 2480 } 2481 2482 protected: 2483 bool 2484 DoExecute (Args& command, CommandReturnObject &result) 2485 { 2486 const size_t argc = command.GetArgumentCount(); 2487 2488 if (argc < 1) 2489 { 2490 result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str()); 2491 result.SetStatus(eReturnStatusFailed); 2492 return false; 2493 } 2494 2495 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0) 2496 { 2497 DataVisualization::Categories::EnableStar(); 2498 } 2499 else 2500 { 2501 for (int i = argc - 1; i >= 0; i--) 2502 { 2503 const char* typeA = command.GetArgumentAtIndex(i); 2504 ConstString typeCS(typeA); 2505 2506 if (!typeCS) 2507 { 2508 result.AppendError("empty category name not allowed"); 2509 result.SetStatus(eReturnStatusFailed); 2510 return false; 2511 } 2512 DataVisualization::Categories::Enable(typeCS); 2513 lldb::TypeCategoryImplSP cate; 2514 if (DataVisualization::Categories::GetCategory(typeCS, cate) && cate.get()) 2515 { 2516 if (cate->GetCount() == 0) 2517 { 2518 result.AppendWarning("empty category enabled (typo?)"); 2519 } 2520 } 2521 } 2522 } 2523 2524 result.SetStatus(eReturnStatusSuccessFinishResult); 2525 return result.Succeeded(); 2526 } 2527 2528 }; 2529 2530 //------------------------------------------------------------------------- 2531 // CommandObjectTypeCategoryDelete 2532 //------------------------------------------------------------------------- 2533 2534 class CommandObjectTypeCategoryDelete : public CommandObjectParsed 2535 { 2536 public: 2537 CommandObjectTypeCategoryDelete (CommandInterpreter &interpreter) : 2538 CommandObjectParsed (interpreter, 2539 "type category delete", 2540 "Delete a category and all associated formatters.", 2541 NULL) 2542 { 2543 CommandArgumentEntry type_arg; 2544 CommandArgumentData type_style_arg; 2545 2546 type_style_arg.arg_type = eArgTypeName; 2547 type_style_arg.arg_repetition = eArgRepeatPlus; 2548 2549 type_arg.push_back (type_style_arg); 2550 2551 m_arguments.push_back (type_arg); 2552 2553 } 2554 2555 ~CommandObjectTypeCategoryDelete () 2556 { 2557 } 2558 2559 protected: 2560 bool 2561 DoExecute (Args& command, CommandReturnObject &result) 2562 { 2563 const size_t argc = command.GetArgumentCount(); 2564 2565 if (argc < 1) 2566 { 2567 result.AppendErrorWithFormat ("%s takes 1 or more arg.\n", m_cmd_name.c_str()); 2568 result.SetStatus(eReturnStatusFailed); 2569 return false; 2570 } 2571 2572 bool success = true; 2573 2574 // the order is not relevant here 2575 for (int i = argc - 1; i >= 0; i--) 2576 { 2577 const char* typeA = command.GetArgumentAtIndex(i); 2578 ConstString typeCS(typeA); 2579 2580 if (!typeCS) 2581 { 2582 result.AppendError("empty category name not allowed"); 2583 result.SetStatus(eReturnStatusFailed); 2584 return false; 2585 } 2586 if (!DataVisualization::Categories::Delete(typeCS)) 2587 success = false; // keep deleting even if we hit an error 2588 } 2589 if (success) 2590 { 2591 result.SetStatus(eReturnStatusSuccessFinishResult); 2592 return result.Succeeded(); 2593 } 2594 else 2595 { 2596 result.AppendError("cannot delete one or more categories\n"); 2597 result.SetStatus(eReturnStatusFailed); 2598 return false; 2599 } 2600 } 2601 }; 2602 2603 //------------------------------------------------------------------------- 2604 // CommandObjectTypeCategoryDisable 2605 //------------------------------------------------------------------------- 2606 2607 class CommandObjectTypeCategoryDisable : public CommandObjectParsed 2608 { 2609 public: 2610 CommandObjectTypeCategoryDisable (CommandInterpreter &interpreter) : 2611 CommandObjectParsed (interpreter, 2612 "type category disable", 2613 "Disable a category as a source of formatters.", 2614 NULL) 2615 { 2616 CommandArgumentEntry type_arg; 2617 CommandArgumentData type_style_arg; 2618 2619 type_style_arg.arg_type = eArgTypeName; 2620 type_style_arg.arg_repetition = eArgRepeatPlus; 2621 2622 type_arg.push_back (type_style_arg); 2623 2624 m_arguments.push_back (type_arg); 2625 2626 } 2627 2628 ~CommandObjectTypeCategoryDisable () 2629 { 2630 } 2631 2632 protected: 2633 bool 2634 DoExecute (Args& command, CommandReturnObject &result) 2635 { 2636 const size_t argc = command.GetArgumentCount(); 2637 2638 if (argc < 1) 2639 { 2640 result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str()); 2641 result.SetStatus(eReturnStatusFailed); 2642 return false; 2643 } 2644 2645 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0) 2646 { 2647 DataVisualization::Categories::DisableStar(); 2648 } 2649 else 2650 { 2651 // the order is not relevant here 2652 for (int i = argc - 1; i >= 0; i--) 2653 { 2654 const char* typeA = command.GetArgumentAtIndex(i); 2655 ConstString typeCS(typeA); 2656 2657 if (!typeCS) 2658 { 2659 result.AppendError("empty category name not allowed"); 2660 result.SetStatus(eReturnStatusFailed); 2661 return false; 2662 } 2663 DataVisualization::Categories::Disable(typeCS); 2664 } 2665 } 2666 2667 result.SetStatus(eReturnStatusSuccessFinishResult); 2668 return result.Succeeded(); 2669 } 2670 2671 }; 2672 2673 //------------------------------------------------------------------------- 2674 // CommandObjectTypeCategoryList 2675 //------------------------------------------------------------------------- 2676 2677 class CommandObjectTypeCategoryList : public CommandObjectParsed 2678 { 2679 private: 2680 2681 struct CommandObjectTypeCategoryList_CallbackParam 2682 { 2683 CommandReturnObject* result; 2684 RegularExpression* regex; 2685 2686 CommandObjectTypeCategoryList_CallbackParam(CommandReturnObject* res, 2687 RegularExpression* rex = NULL) : 2688 result(res), 2689 regex(rex) 2690 { 2691 } 2692 2693 }; 2694 2695 static bool 2696 PerCategoryCallback(void* param_vp, 2697 const lldb::TypeCategoryImplSP& cate) 2698 { 2699 CommandObjectTypeCategoryList_CallbackParam* param = 2700 (CommandObjectTypeCategoryList_CallbackParam*)param_vp; 2701 CommandReturnObject* result = param->result; 2702 RegularExpression* regex = param->regex; 2703 2704 const char* cate_name = cate->GetName(); 2705 2706 if (regex == NULL || strcmp(cate_name, regex->GetText()) == 0 || regex->Execute(cate_name)) 2707 result->GetOutputStream().Printf("Category %s is%s enabled\n", 2708 cate_name, 2709 (cate->IsEnabled() ? "" : " not")); 2710 return true; 2711 } 2712 public: 2713 CommandObjectTypeCategoryList (CommandInterpreter &interpreter) : 2714 CommandObjectParsed (interpreter, 2715 "type category list", 2716 "Provide a list of all existing categories.", 2717 NULL) 2718 { 2719 CommandArgumentEntry type_arg; 2720 CommandArgumentData type_style_arg; 2721 2722 type_style_arg.arg_type = eArgTypeName; 2723 type_style_arg.arg_repetition = eArgRepeatOptional; 2724 2725 type_arg.push_back (type_style_arg); 2726 2727 m_arguments.push_back (type_arg); 2728 } 2729 2730 ~CommandObjectTypeCategoryList () 2731 { 2732 } 2733 2734 protected: 2735 bool 2736 DoExecute (Args& command, CommandReturnObject &result) 2737 { 2738 const size_t argc = command.GetArgumentCount(); 2739 RegularExpression* regex = NULL; 2740 2741 if (argc == 0) 2742 ; 2743 else if (argc == 1) 2744 regex = new RegularExpression(command.GetArgumentAtIndex(0)); 2745 else 2746 { 2747 result.AppendErrorWithFormat ("%s takes 0 or one arg.\n", m_cmd_name.c_str()); 2748 result.SetStatus(eReturnStatusFailed); 2749 return false; 2750 } 2751 2752 CommandObjectTypeCategoryList_CallbackParam param(&result, 2753 regex); 2754 2755 DataVisualization::Categories::LoopThrough(PerCategoryCallback, ¶m); 2756 2757 if (regex) 2758 delete regex; 2759 2760 result.SetStatus(eReturnStatusSuccessFinishResult); 2761 return result.Succeeded(); 2762 } 2763 2764 }; 2765 2766 //------------------------------------------------------------------------- 2767 // CommandObjectTypeFilterList 2768 //------------------------------------------------------------------------- 2769 2770 bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); 2771 bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); 2772 2773 class CommandObjectTypeFilterList; 2774 2775 struct CommandObjectTypeFilterList_LoopCallbackParam { 2776 CommandObjectTypeFilterList* self; 2777 CommandReturnObject* result; 2778 RegularExpression* regex; 2779 RegularExpression* cate_regex; 2780 CommandObjectTypeFilterList_LoopCallbackParam(CommandObjectTypeFilterList* S, CommandReturnObject* R, 2781 RegularExpression* X = NULL, 2782 RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {} 2783 }; 2784 2785 class CommandObjectTypeFilterList : public CommandObjectParsed 2786 { 2787 2788 class CommandOptions : public Options 2789 { 2790 public: 2791 2792 CommandOptions (CommandInterpreter &interpreter) : 2793 Options (interpreter) 2794 { 2795 } 2796 2797 virtual 2798 ~CommandOptions (){} 2799 2800 virtual Error 2801 SetOptionValue (uint32_t option_idx, const char *option_arg) 2802 { 2803 Error error; 2804 const int short_option = m_getopt_table[option_idx].val; 2805 2806 switch (short_option) 2807 { 2808 case 'w': 2809 m_category_regex = std::string(option_arg); 2810 break; 2811 default: 2812 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 2813 break; 2814 } 2815 2816 return error; 2817 } 2818 2819 void 2820 OptionParsingStarting () 2821 { 2822 m_category_regex = ""; 2823 } 2824 2825 const OptionDefinition* 2826 GetDefinitions () 2827 { 2828 return g_option_table; 2829 } 2830 2831 // Options table: Required for subclasses of Options. 2832 2833 static OptionDefinition g_option_table[]; 2834 2835 // Instance variables to hold the values for command options. 2836 2837 std::string m_category_regex; 2838 2839 }; 2840 2841 CommandOptions m_options; 2842 2843 virtual Options * 2844 GetOptions () 2845 { 2846 return &m_options; 2847 } 2848 2849 public: 2850 CommandObjectTypeFilterList (CommandInterpreter &interpreter) : 2851 CommandObjectParsed (interpreter, 2852 "type filter list", 2853 "Show a list of current filters.", 2854 NULL), 2855 m_options(interpreter) 2856 { 2857 CommandArgumentEntry type_arg; 2858 CommandArgumentData type_style_arg; 2859 2860 type_style_arg.arg_type = eArgTypeName; 2861 type_style_arg.arg_repetition = eArgRepeatOptional; 2862 2863 type_arg.push_back (type_style_arg); 2864 2865 m_arguments.push_back (type_arg); 2866 } 2867 2868 ~CommandObjectTypeFilterList () 2869 { 2870 } 2871 2872 protected: 2873 bool 2874 DoExecute (Args& command, CommandReturnObject &result) 2875 { 2876 const size_t argc = command.GetArgumentCount(); 2877 2878 CommandObjectTypeFilterList_LoopCallbackParam *param; 2879 RegularExpression* cate_regex = 2880 m_options.m_category_regex.empty() ? NULL : 2881 new RegularExpression(m_options.m_category_regex.c_str()); 2882 2883 if (argc == 1) 2884 { 2885 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); 2886 regex->Compile(command.GetArgumentAtIndex(0)); 2887 param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,regex,cate_regex); 2888 } 2889 else 2890 param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,NULL,cate_regex); 2891 2892 DataVisualization::Categories::LoopThrough(PerCategoryCallback,param); 2893 delete param; 2894 2895 if (cate_regex) 2896 delete cate_regex; 2897 2898 result.SetStatus(eReturnStatusSuccessFinishResult); 2899 return result.Succeeded(); 2900 } 2901 2902 private: 2903 2904 static bool 2905 PerCategoryCallback(void* param_vp, 2906 const lldb::TypeCategoryImplSP& cate) 2907 { 2908 2909 const char* cate_name = cate->GetName(); 2910 2911 CommandObjectTypeFilterList_LoopCallbackParam* param = 2912 (CommandObjectTypeFilterList_LoopCallbackParam*)param_vp; 2913 CommandReturnObject* result = param->result; 2914 2915 // if the category is disabled or empty and there is no regex, just skip it 2916 if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter) == 0) && param->cate_regex == NULL) 2917 return true; 2918 2919 // if we have a regex and this category does not match it, just skip it 2920 if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false) 2921 return true; 2922 2923 result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n", 2924 cate_name, 2925 (cate->IsEnabled() ? "enabled" : "disabled")); 2926 2927 cate->GetTypeFiltersContainer()->LoopThrough(CommandObjectTypeFilterList_LoopCallback, param_vp); 2928 2929 if (cate->GetRegexTypeFiltersContainer()->GetCount() > 0) 2930 { 2931 result->GetOutputStream().Printf("Regex-based filters (slower):\n"); 2932 cate->GetRegexTypeFiltersContainer()->LoopThrough(CommandObjectTypeFilterRXList_LoopCallback, param_vp); 2933 } 2934 2935 return true; 2936 } 2937 2938 bool 2939 LoopCallback (const char* type, 2940 const SyntheticChildren::SharedPointer& entry, 2941 RegularExpression* regex, 2942 CommandReturnObject *result) 2943 { 2944 if (regex == NULL || regex->Execute(type)) 2945 result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str()); 2946 return true; 2947 } 2948 2949 friend bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); 2950 friend bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); 2951 }; 2952 2953 bool 2954 CommandObjectTypeFilterList_LoopCallback (void* pt2self, 2955 ConstString type, 2956 const SyntheticChildren::SharedPointer& entry) 2957 { 2958 CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self; 2959 return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result); 2960 } 2961 2962 bool 2963 CommandObjectTypeFilterRXList_LoopCallback (void* pt2self, 2964 lldb::RegularExpressionSP regex, 2965 const SyntheticChildren::SharedPointer& entry) 2966 { 2967 CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self; 2968 return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); 2969 } 2970 2971 2972 OptionDefinition 2973 CommandObjectTypeFilterList::CommandOptions::g_option_table[] = 2974 { 2975 { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, 2976 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 2977 }; 2978 2979 #ifndef LLDB_DISABLE_PYTHON 2980 2981 //------------------------------------------------------------------------- 2982 // CommandObjectTypeSynthList 2983 //------------------------------------------------------------------------- 2984 2985 bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); 2986 bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); 2987 2988 class CommandObjectTypeSynthList; 2989 2990 struct CommandObjectTypeSynthList_LoopCallbackParam { 2991 CommandObjectTypeSynthList* self; 2992 CommandReturnObject* result; 2993 RegularExpression* regex; 2994 RegularExpression* cate_regex; 2995 CommandObjectTypeSynthList_LoopCallbackParam(CommandObjectTypeSynthList* S, CommandReturnObject* R, 2996 RegularExpression* X = NULL, 2997 RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {} 2998 }; 2999 3000 class CommandObjectTypeSynthList : public CommandObjectParsed 3001 { 3002 3003 class CommandOptions : public Options 3004 { 3005 public: 3006 3007 CommandOptions (CommandInterpreter &interpreter) : 3008 Options (interpreter) 3009 { 3010 } 3011 3012 virtual 3013 ~CommandOptions (){} 3014 3015 virtual Error 3016 SetOptionValue (uint32_t option_idx, const char *option_arg) 3017 { 3018 Error error; 3019 const int short_option = m_getopt_table[option_idx].val; 3020 3021 switch (short_option) 3022 { 3023 case 'w': 3024 m_category_regex = std::string(option_arg); 3025 break; 3026 default: 3027 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3028 break; 3029 } 3030 3031 return error; 3032 } 3033 3034 void 3035 OptionParsingStarting () 3036 { 3037 m_category_regex = ""; 3038 } 3039 3040 const OptionDefinition* 3041 GetDefinitions () 3042 { 3043 return g_option_table; 3044 } 3045 3046 // Options table: Required for subclasses of Options. 3047 3048 static OptionDefinition g_option_table[]; 3049 3050 // Instance variables to hold the values for command options. 3051 3052 std::string m_category_regex; 3053 3054 }; 3055 3056 CommandOptions m_options; 3057 3058 virtual Options * 3059 GetOptions () 3060 { 3061 return &m_options; 3062 } 3063 3064 public: 3065 CommandObjectTypeSynthList (CommandInterpreter &interpreter) : 3066 CommandObjectParsed (interpreter, 3067 "type synthetic list", 3068 "Show a list of current synthetic providers.", 3069 NULL), 3070 m_options(interpreter) 3071 { 3072 CommandArgumentEntry type_arg; 3073 CommandArgumentData type_style_arg; 3074 3075 type_style_arg.arg_type = eArgTypeName; 3076 type_style_arg.arg_repetition = eArgRepeatOptional; 3077 3078 type_arg.push_back (type_style_arg); 3079 3080 m_arguments.push_back (type_arg); 3081 } 3082 3083 ~CommandObjectTypeSynthList () 3084 { 3085 } 3086 3087 protected: 3088 bool 3089 DoExecute (Args& command, CommandReturnObject &result) 3090 { 3091 const size_t argc = command.GetArgumentCount(); 3092 3093 CommandObjectTypeSynthList_LoopCallbackParam *param; 3094 RegularExpression* cate_regex = 3095 m_options.m_category_regex.empty() ? NULL : 3096 new RegularExpression(m_options.m_category_regex.c_str()); 3097 3098 if (argc == 1) 3099 { 3100 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); 3101 regex->Compile(command.GetArgumentAtIndex(0)); 3102 param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,regex,cate_regex); 3103 } 3104 else 3105 param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,NULL,cate_regex); 3106 3107 DataVisualization::Categories::LoopThrough(PerCategoryCallback,param); 3108 delete param; 3109 3110 if (cate_regex) 3111 delete cate_regex; 3112 3113 result.SetStatus(eReturnStatusSuccessFinishResult); 3114 return result.Succeeded(); 3115 } 3116 3117 private: 3118 3119 static bool 3120 PerCategoryCallback(void* param_vp, 3121 const lldb::TypeCategoryImplSP& cate) 3122 { 3123 3124 CommandObjectTypeSynthList_LoopCallbackParam* param = 3125 (CommandObjectTypeSynthList_LoopCallbackParam*)param_vp; 3126 CommandReturnObject* result = param->result; 3127 3128 const char* cate_name = cate->GetName(); 3129 3130 // if the category is disabled or empty and there is no regex, just skip it 3131 if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth) == 0) && param->cate_regex == NULL) 3132 return true; 3133 3134 // if we have a regex and this category does not match it, just skip it 3135 if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false) 3136 return true; 3137 3138 result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n", 3139 cate_name, 3140 (cate->IsEnabled() ? "enabled" : "disabled")); 3141 3142 cate->GetTypeSyntheticsContainer()->LoopThrough(CommandObjectTypeSynthList_LoopCallback, param_vp); 3143 3144 if (cate->GetRegexTypeSyntheticsContainer()->GetCount() > 0) 3145 { 3146 result->GetOutputStream().Printf("Regex-based synthetic providers (slower):\n"); 3147 cate->GetRegexTypeSyntheticsContainer()->LoopThrough(CommandObjectTypeSynthRXList_LoopCallback, param_vp); 3148 } 3149 3150 return true; 3151 } 3152 3153 bool 3154 LoopCallback (const char* type, 3155 const SyntheticChildren::SharedPointer& entry, 3156 RegularExpression* regex, 3157 CommandReturnObject *result) 3158 { 3159 if (regex == NULL || regex->Execute(type)) 3160 result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str()); 3161 return true; 3162 } 3163 3164 friend bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); 3165 friend bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); 3166 }; 3167 3168 bool 3169 CommandObjectTypeSynthList_LoopCallback (void* pt2self, 3170 ConstString type, 3171 const SyntheticChildren::SharedPointer& entry) 3172 { 3173 CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self; 3174 return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result); 3175 } 3176 3177 bool 3178 CommandObjectTypeSynthRXList_LoopCallback (void* pt2self, 3179 lldb::RegularExpressionSP regex, 3180 const SyntheticChildren::SharedPointer& entry) 3181 { 3182 CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self; 3183 return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); 3184 } 3185 3186 3187 OptionDefinition 3188 CommandObjectTypeSynthList::CommandOptions::g_option_table[] = 3189 { 3190 { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, 3191 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 3192 }; 3193 3194 #endif // #ifndef LLDB_DISABLE_PYTHON 3195 //------------------------------------------------------------------------- 3196 // CommandObjectTypeFilterDelete 3197 //------------------------------------------------------------------------- 3198 3199 class CommandObjectTypeFilterDelete : public CommandObjectParsed 3200 { 3201 private: 3202 class CommandOptions : public Options 3203 { 3204 public: 3205 3206 CommandOptions (CommandInterpreter &interpreter) : 3207 Options (interpreter) 3208 { 3209 } 3210 3211 virtual 3212 ~CommandOptions (){} 3213 3214 virtual Error 3215 SetOptionValue (uint32_t option_idx, const char *option_arg) 3216 { 3217 Error error; 3218 const int short_option = m_getopt_table[option_idx].val; 3219 3220 switch (short_option) 3221 { 3222 case 'a': 3223 m_delete_all = true; 3224 break; 3225 case 'w': 3226 m_category = std::string(option_arg); 3227 break; 3228 default: 3229 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3230 break; 3231 } 3232 3233 return error; 3234 } 3235 3236 void 3237 OptionParsingStarting () 3238 { 3239 m_delete_all = false; 3240 m_category = "default"; 3241 } 3242 3243 const OptionDefinition* 3244 GetDefinitions () 3245 { 3246 return g_option_table; 3247 } 3248 3249 // Options table: Required for subclasses of Options. 3250 3251 static OptionDefinition g_option_table[]; 3252 3253 // Instance variables to hold the values for command options. 3254 3255 bool m_delete_all; 3256 std::string m_category; 3257 3258 }; 3259 3260 CommandOptions m_options; 3261 3262 virtual Options * 3263 GetOptions () 3264 { 3265 return &m_options; 3266 } 3267 3268 static bool 3269 PerCategoryCallback(void* param, 3270 const lldb::TypeCategoryImplSP& cate) 3271 { 3272 ConstString *name = (ConstString*)param; 3273 return cate->Delete(*name, eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter); 3274 } 3275 3276 public: 3277 CommandObjectTypeFilterDelete (CommandInterpreter &interpreter) : 3278 CommandObjectParsed (interpreter, 3279 "type filter delete", 3280 "Delete an existing filter for a type.", 3281 NULL), 3282 m_options(interpreter) 3283 { 3284 CommandArgumentEntry type_arg; 3285 CommandArgumentData type_style_arg; 3286 3287 type_style_arg.arg_type = eArgTypeName; 3288 type_style_arg.arg_repetition = eArgRepeatPlain; 3289 3290 type_arg.push_back (type_style_arg); 3291 3292 m_arguments.push_back (type_arg); 3293 3294 } 3295 3296 ~CommandObjectTypeFilterDelete () 3297 { 3298 } 3299 3300 protected: 3301 bool 3302 DoExecute (Args& command, CommandReturnObject &result) 3303 { 3304 const size_t argc = command.GetArgumentCount(); 3305 3306 if (argc != 1) 3307 { 3308 result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); 3309 result.SetStatus(eReturnStatusFailed); 3310 return false; 3311 } 3312 3313 const char* typeA = command.GetArgumentAtIndex(0); 3314 ConstString typeCS(typeA); 3315 3316 if (!typeCS) 3317 { 3318 result.AppendError("empty typenames not allowed"); 3319 result.SetStatus(eReturnStatusFailed); 3320 return false; 3321 } 3322 3323 if (m_options.m_delete_all) 3324 { 3325 DataVisualization::Categories::LoopThrough(PerCategoryCallback, (void*)&typeCS); 3326 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3327 return result.Succeeded(); 3328 } 3329 3330 lldb::TypeCategoryImplSP category; 3331 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 3332 3333 bool delete_category = category->GetTypeFiltersContainer()->Delete(typeCS); 3334 delete_category = category->GetRegexTypeFiltersContainer()->Delete(typeCS) || delete_category; 3335 3336 if (delete_category) 3337 { 3338 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3339 return result.Succeeded(); 3340 } 3341 else 3342 { 3343 result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA); 3344 result.SetStatus(eReturnStatusFailed); 3345 return false; 3346 } 3347 3348 } 3349 }; 3350 3351 OptionDefinition 3352 CommandObjectTypeFilterDelete::CommandOptions::g_option_table[] = 3353 { 3354 { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Delete from every category."}, 3355 { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Delete from given category."}, 3356 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 3357 }; 3358 3359 #ifndef LLDB_DISABLE_PYTHON 3360 3361 //------------------------------------------------------------------------- 3362 // CommandObjectTypeSynthDelete 3363 //------------------------------------------------------------------------- 3364 3365 class CommandObjectTypeSynthDelete : public CommandObjectParsed 3366 { 3367 private: 3368 class CommandOptions : public Options 3369 { 3370 public: 3371 3372 CommandOptions (CommandInterpreter &interpreter) : 3373 Options (interpreter) 3374 { 3375 } 3376 3377 virtual 3378 ~CommandOptions (){} 3379 3380 virtual Error 3381 SetOptionValue (uint32_t option_idx, const char *option_arg) 3382 { 3383 Error error; 3384 const int short_option = m_getopt_table[option_idx].val; 3385 3386 switch (short_option) 3387 { 3388 case 'a': 3389 m_delete_all = true; 3390 break; 3391 case 'w': 3392 m_category = std::string(option_arg); 3393 break; 3394 default: 3395 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3396 break; 3397 } 3398 3399 return error; 3400 } 3401 3402 void 3403 OptionParsingStarting () 3404 { 3405 m_delete_all = false; 3406 m_category = "default"; 3407 } 3408 3409 const OptionDefinition* 3410 GetDefinitions () 3411 { 3412 return g_option_table; 3413 } 3414 3415 // Options table: Required for subclasses of Options. 3416 3417 static OptionDefinition g_option_table[]; 3418 3419 // Instance variables to hold the values for command options. 3420 3421 bool m_delete_all; 3422 std::string m_category; 3423 3424 }; 3425 3426 CommandOptions m_options; 3427 3428 virtual Options * 3429 GetOptions () 3430 { 3431 return &m_options; 3432 } 3433 3434 static bool 3435 PerCategoryCallback(void* param, 3436 const lldb::TypeCategoryImplSP& cate) 3437 { 3438 ConstString* name = (ConstString*)param; 3439 return cate->Delete(*name, eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth); 3440 } 3441 3442 public: 3443 CommandObjectTypeSynthDelete (CommandInterpreter &interpreter) : 3444 CommandObjectParsed (interpreter, 3445 "type synthetic delete", 3446 "Delete an existing synthetic provider for a type.", 3447 NULL), 3448 m_options(interpreter) 3449 { 3450 CommandArgumentEntry type_arg; 3451 CommandArgumentData type_style_arg; 3452 3453 type_style_arg.arg_type = eArgTypeName; 3454 type_style_arg.arg_repetition = eArgRepeatPlain; 3455 3456 type_arg.push_back (type_style_arg); 3457 3458 m_arguments.push_back (type_arg); 3459 3460 } 3461 3462 ~CommandObjectTypeSynthDelete () 3463 { 3464 } 3465 3466 protected: 3467 bool 3468 DoExecute (Args& command, CommandReturnObject &result) 3469 { 3470 const size_t argc = command.GetArgumentCount(); 3471 3472 if (argc != 1) 3473 { 3474 result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); 3475 result.SetStatus(eReturnStatusFailed); 3476 return false; 3477 } 3478 3479 const char* typeA = command.GetArgumentAtIndex(0); 3480 ConstString typeCS(typeA); 3481 3482 if (!typeCS) 3483 { 3484 result.AppendError("empty typenames not allowed"); 3485 result.SetStatus(eReturnStatusFailed); 3486 return false; 3487 } 3488 3489 if (m_options.m_delete_all) 3490 { 3491 DataVisualization::Categories::LoopThrough(PerCategoryCallback, (void*)&typeCS); 3492 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3493 return result.Succeeded(); 3494 } 3495 3496 lldb::TypeCategoryImplSP category; 3497 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 3498 3499 bool delete_category = category->GetTypeSyntheticsContainer()->Delete(typeCS); 3500 delete_category = category->GetRegexTypeSyntheticsContainer()->Delete(typeCS) || delete_category; 3501 3502 if (delete_category) 3503 { 3504 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3505 return result.Succeeded(); 3506 } 3507 else 3508 { 3509 result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA); 3510 result.SetStatus(eReturnStatusFailed); 3511 return false; 3512 } 3513 3514 } 3515 }; 3516 3517 OptionDefinition 3518 CommandObjectTypeSynthDelete::CommandOptions::g_option_table[] = 3519 { 3520 { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Delete from every category."}, 3521 { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Delete from given category."}, 3522 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 3523 }; 3524 3525 #endif // #ifndef LLDB_DISABLE_PYTHON 3526 3527 //------------------------------------------------------------------------- 3528 // CommandObjectTypeFilterClear 3529 //------------------------------------------------------------------------- 3530 3531 class CommandObjectTypeFilterClear : public CommandObjectParsed 3532 { 3533 private: 3534 3535 class CommandOptions : public Options 3536 { 3537 public: 3538 3539 CommandOptions (CommandInterpreter &interpreter) : 3540 Options (interpreter) 3541 { 3542 } 3543 3544 virtual 3545 ~CommandOptions (){} 3546 3547 virtual Error 3548 SetOptionValue (uint32_t option_idx, const char *option_arg) 3549 { 3550 Error error; 3551 const int short_option = m_getopt_table[option_idx].val; 3552 3553 switch (short_option) 3554 { 3555 case 'a': 3556 m_delete_all = true; 3557 break; 3558 default: 3559 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3560 break; 3561 } 3562 3563 return error; 3564 } 3565 3566 void 3567 OptionParsingStarting () 3568 { 3569 m_delete_all = false; 3570 } 3571 3572 const OptionDefinition* 3573 GetDefinitions () 3574 { 3575 return g_option_table; 3576 } 3577 3578 // Options table: Required for subclasses of Options. 3579 3580 static OptionDefinition g_option_table[]; 3581 3582 // Instance variables to hold the values for command options. 3583 3584 bool m_delete_all; 3585 bool m_delete_named; 3586 }; 3587 3588 CommandOptions m_options; 3589 3590 virtual Options * 3591 GetOptions () 3592 { 3593 return &m_options; 3594 } 3595 3596 static bool 3597 PerCategoryCallback(void* param, 3598 const lldb::TypeCategoryImplSP& cate) 3599 { 3600 cate->Clear(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter); 3601 return true; 3602 3603 } 3604 3605 public: 3606 CommandObjectTypeFilterClear (CommandInterpreter &interpreter) : 3607 CommandObjectParsed (interpreter, 3608 "type filter clear", 3609 "Delete all existing filters.", 3610 NULL), 3611 m_options(interpreter) 3612 { 3613 } 3614 3615 ~CommandObjectTypeFilterClear () 3616 { 3617 } 3618 3619 protected: 3620 bool 3621 DoExecute (Args& command, CommandReturnObject &result) 3622 { 3623 3624 if (m_options.m_delete_all) 3625 DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL); 3626 3627 else 3628 { 3629 lldb::TypeCategoryImplSP category; 3630 if (command.GetArgumentCount() > 0) 3631 { 3632 const char* cat_name = command.GetArgumentAtIndex(0); 3633 ConstString cat_nameCS(cat_name); 3634 DataVisualization::Categories::GetCategory(cat_nameCS, category); 3635 } 3636 else 3637 DataVisualization::Categories::GetCategory(ConstString(NULL), category); 3638 category->GetTypeFiltersContainer()->Clear(); 3639 category->GetRegexTypeFiltersContainer()->Clear(); 3640 } 3641 3642 result.SetStatus(eReturnStatusSuccessFinishResult); 3643 return result.Succeeded(); 3644 } 3645 3646 }; 3647 3648 OptionDefinition 3649 CommandObjectTypeFilterClear::CommandOptions::g_option_table[] = 3650 { 3651 { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Clear every category."}, 3652 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 3653 }; 3654 3655 #ifndef LLDB_DISABLE_PYTHON 3656 //------------------------------------------------------------------------- 3657 // CommandObjectTypeSynthClear 3658 //------------------------------------------------------------------------- 3659 3660 class CommandObjectTypeSynthClear : public CommandObjectParsed 3661 { 3662 private: 3663 3664 class CommandOptions : public Options 3665 { 3666 public: 3667 3668 CommandOptions (CommandInterpreter &interpreter) : 3669 Options (interpreter) 3670 { 3671 } 3672 3673 virtual 3674 ~CommandOptions (){} 3675 3676 virtual Error 3677 SetOptionValue (uint32_t option_idx, const char *option_arg) 3678 { 3679 Error error; 3680 const int short_option = m_getopt_table[option_idx].val; 3681 3682 switch (short_option) 3683 { 3684 case 'a': 3685 m_delete_all = true; 3686 break; 3687 default: 3688 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3689 break; 3690 } 3691 3692 return error; 3693 } 3694 3695 void 3696 OptionParsingStarting () 3697 { 3698 m_delete_all = false; 3699 } 3700 3701 const OptionDefinition* 3702 GetDefinitions () 3703 { 3704 return g_option_table; 3705 } 3706 3707 // Options table: Required for subclasses of Options. 3708 3709 static OptionDefinition g_option_table[]; 3710 3711 // Instance variables to hold the values for command options. 3712 3713 bool m_delete_all; 3714 bool m_delete_named; 3715 }; 3716 3717 CommandOptions m_options; 3718 3719 virtual Options * 3720 GetOptions () 3721 { 3722 return &m_options; 3723 } 3724 3725 static bool 3726 PerCategoryCallback(void* param, 3727 const lldb::TypeCategoryImplSP& cate) 3728 { 3729 cate->Clear(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth); 3730 return true; 3731 3732 } 3733 3734 public: 3735 CommandObjectTypeSynthClear (CommandInterpreter &interpreter) : 3736 CommandObjectParsed (interpreter, 3737 "type synthetic clear", 3738 "Delete all existing synthetic providers.", 3739 NULL), 3740 m_options(interpreter) 3741 { 3742 } 3743 3744 ~CommandObjectTypeSynthClear () 3745 { 3746 } 3747 3748 protected: 3749 bool 3750 DoExecute (Args& command, CommandReturnObject &result) 3751 { 3752 3753 if (m_options.m_delete_all) 3754 DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL); 3755 3756 else 3757 { 3758 lldb::TypeCategoryImplSP category; 3759 if (command.GetArgumentCount() > 0) 3760 { 3761 const char* cat_name = command.GetArgumentAtIndex(0); 3762 ConstString cat_nameCS(cat_name); 3763 DataVisualization::Categories::GetCategory(cat_nameCS, category); 3764 } 3765 else 3766 DataVisualization::Categories::GetCategory(ConstString(NULL), category); 3767 category->GetTypeSyntheticsContainer()->Clear(); 3768 category->GetRegexTypeSyntheticsContainer()->Clear(); 3769 } 3770 3771 result.SetStatus(eReturnStatusSuccessFinishResult); 3772 return result.Succeeded(); 3773 } 3774 3775 }; 3776 3777 OptionDefinition 3778 CommandObjectTypeSynthClear::CommandOptions::g_option_table[] = 3779 { 3780 { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Clear every category."}, 3781 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 3782 }; 3783 3784 3785 bool 3786 CommandObjectTypeSynthAdd::Execute_HandwritePython (Args& command, CommandReturnObject &result) 3787 { 3788 SynthAddOptions *options = new SynthAddOptions ( m_options.m_skip_pointers, 3789 m_options.m_skip_references, 3790 m_options.m_cascade, 3791 m_options.m_regex, 3792 m_options.m_category); 3793 3794 const size_t argc = command.GetArgumentCount(); 3795 3796 for (size_t i = 0; i < argc; i++) 3797 { 3798 const char* typeA = command.GetArgumentAtIndex(i); 3799 if (typeA && *typeA) 3800 options->m_target_types << typeA; 3801 else 3802 { 3803 result.AppendError("empty typenames not allowed"); 3804 result.SetStatus(eReturnStatusFailed); 3805 return false; 3806 } 3807 } 3808 3809 m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt 3810 *this, // IOHandlerDelegate 3811 true, // Run IOHandler in async mode 3812 options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions 3813 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3814 return result.Succeeded(); 3815 } 3816 3817 bool 3818 CommandObjectTypeSynthAdd::Execute_PythonClass (Args& command, CommandReturnObject &result) 3819 { 3820 const size_t argc = command.GetArgumentCount(); 3821 3822 if (argc < 1) 3823 { 3824 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); 3825 result.SetStatus(eReturnStatusFailed); 3826 return false; 3827 } 3828 3829 if (m_options.m_class_name.empty() && !m_options.m_input_python) 3830 { 3831 result.AppendErrorWithFormat ("%s needs either a Python class name or -P to directly input Python code.\n", m_cmd_name.c_str()); 3832 result.SetStatus(eReturnStatusFailed); 3833 return false; 3834 } 3835 3836 SyntheticChildrenSP entry; 3837 3838 ScriptedSyntheticChildren* impl = new ScriptedSyntheticChildren(SyntheticChildren::Flags(). 3839 SetCascades(m_options.m_cascade). 3840 SetSkipPointers(m_options.m_skip_pointers). 3841 SetSkipReferences(m_options.m_skip_references), 3842 m_options.m_class_name.c_str()); 3843 3844 entry.reset(impl); 3845 3846 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 3847 3848 if (interpreter && interpreter->CheckObjectExists(impl->GetPythonClassName()) == false) 3849 result.AppendWarning("The provided class does not exist - please define it before attempting to use this synthetic provider"); 3850 3851 // now I have a valid provider, let's add it to every type 3852 3853 lldb::TypeCategoryImplSP category; 3854 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 3855 3856 Error error; 3857 3858 for (size_t i = 0; i < argc; i++) 3859 { 3860 const char* typeA = command.GetArgumentAtIndex(i); 3861 ConstString typeCS(typeA); 3862 if (typeCS) 3863 { 3864 if (!AddSynth(typeCS, 3865 entry, 3866 m_options.m_regex ? eRegexSynth : eRegularSynth, 3867 m_options.m_category, 3868 &error)) 3869 { 3870 result.AppendError(error.AsCString()); 3871 result.SetStatus(eReturnStatusFailed); 3872 return false; 3873 } 3874 } 3875 else 3876 { 3877 result.AppendError("empty typenames not allowed"); 3878 result.SetStatus(eReturnStatusFailed); 3879 return false; 3880 } 3881 } 3882 3883 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3884 return result.Succeeded(); 3885 } 3886 3887 CommandObjectTypeSynthAdd::CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) : 3888 CommandObjectParsed (interpreter, 3889 "type synthetic add", 3890 "Add a new synthetic provider for a type.", 3891 NULL), 3892 IOHandlerDelegateMultiline ("DONE"), 3893 m_options (interpreter) 3894 { 3895 CommandArgumentEntry type_arg; 3896 CommandArgumentData type_style_arg; 3897 3898 type_style_arg.arg_type = eArgTypeName; 3899 type_style_arg.arg_repetition = eArgRepeatPlus; 3900 3901 type_arg.push_back (type_style_arg); 3902 3903 m_arguments.push_back (type_arg); 3904 3905 } 3906 3907 bool 3908 CommandObjectTypeSynthAdd::AddSynth(ConstString type_name, 3909 SyntheticChildrenSP entry, 3910 SynthFormatType type, 3911 std::string category_name, 3912 Error* error) 3913 { 3914 lldb::TypeCategoryImplSP category; 3915 DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category); 3916 3917 if (type == eRegularSynth) 3918 { 3919 if (FixArrayTypeNameWithRegex (type_name)) 3920 type = eRegexSynth; 3921 } 3922 3923 if (category->AnyMatches(type_name, 3924 eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter, 3925 false)) 3926 { 3927 if (error) 3928 error->SetErrorStringWithFormat("cannot add synthetic for type %s when filter is defined in same category!", type_name.AsCString()); 3929 return false; 3930 } 3931 3932 if (type == eRegexSynth) 3933 { 3934 RegularExpressionSP typeRX(new RegularExpression()); 3935 if (!typeRX->Compile(type_name.GetCString())) 3936 { 3937 if (error) 3938 error->SetErrorString("regex format error (maybe this is not really a regex?)"); 3939 return false; 3940 } 3941 3942 category->GetRegexTypeSyntheticsContainer()->Delete(type_name); 3943 category->GetRegexTypeSyntheticsContainer()->Add(typeRX, entry); 3944 3945 return true; 3946 } 3947 else 3948 { 3949 category->GetTypeSyntheticsContainer()->Add(type_name, entry); 3950 return true; 3951 } 3952 } 3953 3954 OptionDefinition 3955 CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] = 3956 { 3957 { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, 3958 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, 3959 { 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."}, 3960 { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, 3961 { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass, "Use this Python class to produce synthetic children."}, 3962 { 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."}, 3963 { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, 3964 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 3965 }; 3966 3967 #endif // #ifndef LLDB_DISABLE_PYTHON 3968 3969 class CommandObjectTypeFilterAdd : public CommandObjectParsed 3970 { 3971 3972 private: 3973 3974 class CommandOptions : public Options 3975 { 3976 typedef std::vector<std::string> option_vector; 3977 public: 3978 3979 CommandOptions (CommandInterpreter &interpreter) : 3980 Options (interpreter) 3981 { 3982 } 3983 3984 virtual 3985 ~CommandOptions (){} 3986 3987 virtual Error 3988 SetOptionValue (uint32_t option_idx, const char *option_arg) 3989 { 3990 Error error; 3991 const int short_option = m_getopt_table[option_idx].val; 3992 bool success; 3993 3994 switch (short_option) 3995 { 3996 case 'C': 3997 m_cascade = Args::StringToBoolean(option_arg, true, &success); 3998 if (!success) 3999 error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg); 4000 break; 4001 case 'c': 4002 m_expr_paths.push_back(option_arg); 4003 has_child_list = true; 4004 break; 4005 case 'p': 4006 m_skip_pointers = true; 4007 break; 4008 case 'r': 4009 m_skip_references = true; 4010 break; 4011 case 'w': 4012 m_category = std::string(option_arg); 4013 break; 4014 case 'x': 4015 m_regex = true; 4016 break; 4017 default: 4018 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 4019 break; 4020 } 4021 4022 return error; 4023 } 4024 4025 void 4026 OptionParsingStarting () 4027 { 4028 m_cascade = true; 4029 m_skip_pointers = false; 4030 m_skip_references = false; 4031 m_category = "default"; 4032 m_expr_paths.clear(); 4033 has_child_list = false; 4034 m_regex = false; 4035 } 4036 4037 const OptionDefinition* 4038 GetDefinitions () 4039 { 4040 return g_option_table; 4041 } 4042 4043 // Options table: Required for subclasses of Options. 4044 4045 static OptionDefinition g_option_table[]; 4046 4047 // Instance variables to hold the values for command options. 4048 4049 bool m_cascade; 4050 bool m_skip_references; 4051 bool m_skip_pointers; 4052 bool m_input_python; 4053 option_vector m_expr_paths; 4054 std::string m_category; 4055 4056 bool has_child_list; 4057 4058 bool m_regex; 4059 4060 typedef option_vector::iterator ExpressionPathsIterator; 4061 }; 4062 4063 CommandOptions m_options; 4064 4065 virtual Options * 4066 GetOptions () 4067 { 4068 return &m_options; 4069 } 4070 4071 enum FilterFormatType 4072 { 4073 eRegularFilter, 4074 eRegexFilter 4075 }; 4076 4077 bool 4078 AddFilter(ConstString type_name, 4079 SyntheticChildrenSP entry, 4080 FilterFormatType type, 4081 std::string category_name, 4082 Error* error) 4083 { 4084 lldb::TypeCategoryImplSP category; 4085 DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category); 4086 4087 if (type == eRegularFilter) 4088 { 4089 if (FixArrayTypeNameWithRegex (type_name)) 4090 type = eRegexFilter; 4091 } 4092 4093 if (category->AnyMatches(type_name, 4094 eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth, 4095 false)) 4096 { 4097 if (error) 4098 error->SetErrorStringWithFormat("cannot add filter for type %s when synthetic is defined in same category!", type_name.AsCString()); 4099 return false; 4100 } 4101 4102 if (type == eRegexFilter) 4103 { 4104 RegularExpressionSP typeRX(new RegularExpression()); 4105 if (!typeRX->Compile(type_name.GetCString())) 4106 { 4107 if (error) 4108 error->SetErrorString("regex format error (maybe this is not really a regex?)"); 4109 return false; 4110 } 4111 4112 category->GetRegexTypeFiltersContainer()->Delete(type_name); 4113 category->GetRegexTypeFiltersContainer()->Add(typeRX, entry); 4114 4115 return true; 4116 } 4117 else 4118 { 4119 category->GetTypeFiltersContainer()->Add(type_name, entry); 4120 return true; 4121 } 4122 } 4123 4124 4125 public: 4126 4127 CommandObjectTypeFilterAdd (CommandInterpreter &interpreter) : 4128 CommandObjectParsed (interpreter, 4129 "type filter add", 4130 "Add a new filter for a type.", 4131 NULL), 4132 m_options (interpreter) 4133 { 4134 CommandArgumentEntry type_arg; 4135 CommandArgumentData type_style_arg; 4136 4137 type_style_arg.arg_type = eArgTypeName; 4138 type_style_arg.arg_repetition = eArgRepeatPlus; 4139 4140 type_arg.push_back (type_style_arg); 4141 4142 m_arguments.push_back (type_arg); 4143 4144 SetHelpLong( 4145 R"( 4146 The following examples of 'type filter add' refer to this code snippet for context: 4147 4148 class Foo { 4149 int a; 4150 int b; 4151 int c; 4152 int d; 4153 int e; 4154 int f; 4155 int g; 4156 int h; 4157 int i; 4158 } 4159 Foo my_foo; 4160 4161 Adding a simple filter: 4162 4163 (lldb) type filter add --child a --child g Foo 4164 (lldb) frame variable my_foo 4165 4166 )" "Produces output where only a and g are displayed. Other children of my_foo \ 4167 (b, c, d, e, f, h and i) are available by asking for them explicitly:" R"( 4168 4169 (lldb) frame variable my_foo.b my_foo.c my_foo.i 4170 4171 )" "The formatting option --raw on frame variable bypasses the filter, showing \ 4172 all children of my_foo as if no filter was defined:" R"( 4173 4174 (lldb) frame variable my_foo --raw)" 4175 ); 4176 } 4177 4178 ~CommandObjectTypeFilterAdd () 4179 { 4180 } 4181 4182 protected: 4183 bool 4184 DoExecute (Args& command, CommandReturnObject &result) 4185 { 4186 const size_t argc = command.GetArgumentCount(); 4187 4188 if (argc < 1) 4189 { 4190 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); 4191 result.SetStatus(eReturnStatusFailed); 4192 return false; 4193 } 4194 4195 if (m_options.m_expr_paths.size() == 0) 4196 { 4197 result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str()); 4198 result.SetStatus(eReturnStatusFailed); 4199 return false; 4200 } 4201 4202 SyntheticChildrenSP entry; 4203 4204 TypeFilterImpl* impl = new TypeFilterImpl(SyntheticChildren::Flags().SetCascades(m_options.m_cascade). 4205 SetSkipPointers(m_options.m_skip_pointers). 4206 SetSkipReferences(m_options.m_skip_references)); 4207 4208 entry.reset(impl); 4209 4210 // go through the expression paths 4211 CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end(); 4212 4213 for (begin = m_options.m_expr_paths.begin(); begin != end; begin++) 4214 impl->AddExpressionPath(*begin); 4215 4216 4217 // now I have a valid provider, let's add it to every type 4218 4219 lldb::TypeCategoryImplSP category; 4220 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 4221 4222 Error error; 4223 4224 WarnOnPotentialUnquotedUnsignedType(command, result); 4225 4226 for (size_t i = 0; i < argc; i++) 4227 { 4228 const char* typeA = command.GetArgumentAtIndex(i); 4229 ConstString typeCS(typeA); 4230 if (typeCS) 4231 { 4232 if (!AddFilter(typeCS, 4233 entry, 4234 m_options.m_regex ? eRegexFilter : eRegularFilter, 4235 m_options.m_category, 4236 &error)) 4237 { 4238 result.AppendError(error.AsCString()); 4239 result.SetStatus(eReturnStatusFailed); 4240 return false; 4241 } 4242 } 4243 else 4244 { 4245 result.AppendError("empty typenames not allowed"); 4246 result.SetStatus(eReturnStatusFailed); 4247 return false; 4248 } 4249 } 4250 4251 result.SetStatus(eReturnStatusSuccessFinishNoResult); 4252 return result.Succeeded(); 4253 } 4254 4255 }; 4256 4257 OptionDefinition 4258 CommandObjectTypeFilterAdd::CommandOptions::g_option_table[] = 4259 { 4260 { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, 4261 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, 4262 { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, 4263 { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, 4264 { LLDB_OPT_SET_ALL, false, "child", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpressionPath, "Include this expression path in the synthetic view."}, 4265 { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, 4266 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 4267 }; 4268 4269 template <typename FormatterType> 4270 class CommandObjectFormatterInfo : public CommandObjectRaw 4271 { 4272 public: 4273 typedef std::function<typename FormatterType::SharedPointer(ValueObject&)> DiscoveryFunction; 4274 CommandObjectFormatterInfo (CommandInterpreter &interpreter, 4275 const char* formatter_name, 4276 DiscoveryFunction discovery_func) : 4277 CommandObjectRaw(interpreter, 4278 nullptr, 4279 nullptr, 4280 nullptr, 4281 eCommandRequiresFrame), 4282 m_formatter_name(formatter_name ? formatter_name : ""), 4283 m_discovery_function(discovery_func) 4284 { 4285 StreamString name; 4286 name.Printf("type %s info", formatter_name); 4287 SetCommandName(name.GetData()); 4288 StreamString help; 4289 help.Printf("This command evaluates the provided expression and shows which %s is applied to the resulting value (if any).", formatter_name); 4290 SetHelp(help.GetData()); 4291 StreamString syntax; 4292 syntax.Printf("type %s info <expr>", formatter_name); 4293 SetSyntax(syntax.GetData()); 4294 } 4295 4296 virtual 4297 ~CommandObjectFormatterInfo () 4298 { 4299 } 4300 4301 protected: 4302 virtual bool 4303 DoExecute (const char *command, CommandReturnObject &result) 4304 { 4305 auto target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); 4306 auto frame_sp = target_sp->GetProcessSP()->GetThreadList().GetSelectedThread()->GetSelectedFrame(); 4307 ValueObjectSP result_valobj_sp; 4308 EvaluateExpressionOptions options; 4309 lldb::ExpressionResults expr_result = target_sp->EvaluateExpression(command, frame_sp.get(), result_valobj_sp, options); 4310 if (expr_result == eExpressionCompleted && result_valobj_sp) 4311 { 4312 result_valobj_sp = result_valobj_sp->GetQualifiedRepresentationIfAvailable(target_sp->GetPreferDynamicValue(), target_sp->GetEnableSyntheticValue()); 4313 typename FormatterType::SharedPointer formatter_sp = m_discovery_function(*result_valobj_sp); 4314 if (formatter_sp) 4315 { 4316 std::string description(formatter_sp->GetDescription()); 4317 result.AppendMessageWithFormat("%s applied to (%s) %s is: %s\n", 4318 m_formatter_name.c_str(), 4319 result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"), 4320 command, 4321 description.c_str()); 4322 result.SetStatus(lldb::eReturnStatusSuccessFinishResult); 4323 } 4324 else 4325 { 4326 result.AppendMessageWithFormat("no %s applies to (%s) %s\n", 4327 m_formatter_name.c_str(), 4328 result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"), 4329 command); 4330 result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult); 4331 } 4332 return true; 4333 } 4334 else 4335 { 4336 result.AppendError("failed to evaluate expression"); 4337 result.SetStatus(lldb::eReturnStatusFailed); 4338 return false; 4339 } 4340 } 4341 4342 private: 4343 std::string m_formatter_name; 4344 DiscoveryFunction m_discovery_function; 4345 }; 4346 4347 class CommandObjectTypeFormat : public CommandObjectMultiword 4348 { 4349 public: 4350 CommandObjectTypeFormat (CommandInterpreter &interpreter) : 4351 CommandObjectMultiword (interpreter, 4352 "type format", 4353 "A set of commands for editing variable value display options", 4354 "type format [<sub-command-options>] ") 4355 { 4356 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFormatAdd (interpreter))); 4357 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFormatClear (interpreter))); 4358 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFormatDelete (interpreter))); 4359 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFormatList (interpreter))); 4360 LoadSubCommand ("info", CommandObjectSP (new CommandObjectFormatterInfo<TypeFormatImpl>(interpreter, 4361 "format", 4362 [](ValueObject& valobj) -> TypeFormatImpl::SharedPointer { 4363 return valobj.GetValueFormat(); 4364 }))); 4365 } 4366 4367 4368 ~CommandObjectTypeFormat () 4369 { 4370 } 4371 }; 4372 4373 #ifndef LLDB_DISABLE_PYTHON 4374 4375 class CommandObjectTypeSynth : public CommandObjectMultiword 4376 { 4377 public: 4378 CommandObjectTypeSynth (CommandInterpreter &interpreter) : 4379 CommandObjectMultiword (interpreter, 4380 "type synthetic", 4381 "A set of commands for operating on synthetic type representations", 4382 "type synthetic [<sub-command-options>] ") 4383 { 4384 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSynthAdd (interpreter))); 4385 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSynthClear (interpreter))); 4386 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSynthDelete (interpreter))); 4387 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSynthList (interpreter))); 4388 LoadSubCommand ("info", CommandObjectSP (new CommandObjectFormatterInfo<SyntheticChildren>(interpreter, 4389 "synthetic", 4390 [](ValueObject& valobj) -> SyntheticChildren::SharedPointer { 4391 return valobj.GetSyntheticChildren(); 4392 }))); 4393 } 4394 4395 4396 ~CommandObjectTypeSynth () 4397 { 4398 } 4399 }; 4400 4401 #endif // #ifndef LLDB_DISABLE_PYTHON 4402 4403 class CommandObjectTypeFilter : public CommandObjectMultiword 4404 { 4405 public: 4406 CommandObjectTypeFilter (CommandInterpreter &interpreter) : 4407 CommandObjectMultiword (interpreter, 4408 "type filter", 4409 "A set of commands for operating on type filters", 4410 "type synthetic [<sub-command-options>] ") 4411 { 4412 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFilterAdd (interpreter))); 4413 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFilterClear (interpreter))); 4414 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFilterDelete (interpreter))); 4415 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFilterList (interpreter))); 4416 } 4417 4418 4419 ~CommandObjectTypeFilter () 4420 { 4421 } 4422 }; 4423 4424 class CommandObjectTypeCategory : public CommandObjectMultiword 4425 { 4426 public: 4427 CommandObjectTypeCategory (CommandInterpreter &interpreter) : 4428 CommandObjectMultiword (interpreter, 4429 "type category", 4430 "A set of commands for operating on categories", 4431 "type category [<sub-command-options>] ") 4432 { 4433 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTypeCategoryEnable (interpreter))); 4434 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTypeCategoryDisable (interpreter))); 4435 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeCategoryDelete (interpreter))); 4436 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeCategoryList (interpreter))); 4437 } 4438 4439 4440 ~CommandObjectTypeCategory () 4441 { 4442 } 4443 }; 4444 4445 class CommandObjectTypeSummary : public CommandObjectMultiword 4446 { 4447 public: 4448 CommandObjectTypeSummary (CommandInterpreter &interpreter) : 4449 CommandObjectMultiword (interpreter, 4450 "type summary", 4451 "A set of commands for editing variable summary display options", 4452 "type summary [<sub-command-options>] ") 4453 { 4454 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSummaryAdd (interpreter))); 4455 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSummaryClear (interpreter))); 4456 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSummaryDelete (interpreter))); 4457 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSummaryList (interpreter))); 4458 LoadSubCommand ("info", CommandObjectSP (new CommandObjectFormatterInfo<TypeSummaryImpl>(interpreter, 4459 "summary", 4460 [](ValueObject& valobj) -> TypeSummaryImpl::SharedPointer { 4461 return valobj.GetSummaryFormat(); 4462 }))); 4463 } 4464 4465 4466 ~CommandObjectTypeSummary () 4467 { 4468 } 4469 }; 4470 4471 //------------------------------------------------------------------------- 4472 // CommandObjectType 4473 //------------------------------------------------------------------------- 4474 4475 CommandObjectType::CommandObjectType (CommandInterpreter &interpreter) : 4476 CommandObjectMultiword (interpreter, 4477 "type", 4478 "A set of commands for operating on the type system", 4479 "type [<sub-command-options>]") 4480 { 4481 LoadSubCommand ("category", CommandObjectSP (new CommandObjectTypeCategory (interpreter))); 4482 LoadSubCommand ("filter", CommandObjectSP (new CommandObjectTypeFilter (interpreter))); 4483 LoadSubCommand ("format", CommandObjectSP (new CommandObjectTypeFormat (interpreter))); 4484 LoadSubCommand ("summary", CommandObjectSP (new CommandObjectTypeSummary (interpreter))); 4485 #ifndef LLDB_DISABLE_PYTHON 4486 LoadSubCommand ("synthetic", CommandObjectSP (new CommandObjectTypeSynth (interpreter))); 4487 #endif 4488 } 4489 4490 4491 CommandObjectType::~CommandObjectType () 4492 { 4493 } 4494 4495 4496