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