1 //===-- CommandObjectType.cpp ----------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "CommandObjectType.h" 11 12 // C Includes 13 14 #include <ctype.h> 15 16 // C++ Includes 17 #include <functional> 18 19 #include "llvm/ADT/StringRef.h" 20 21 #include "lldb/Core/ConstString.h" 22 #include "lldb/Core/Debugger.h" 23 #include "lldb/Core/IOHandler.h" 24 #include "lldb/Core/RegularExpression.h" 25 #include "lldb/Core/State.h" 26 #include "lldb/Core/StringList.h" 27 #include "lldb/DataFormatters/DataVisualization.h" 28 #include "lldb/Interpreter/CommandInterpreter.h" 29 #include "lldb/Interpreter/CommandObject.h" 30 #include "lldb/Interpreter/CommandReturnObject.h" 31 #include "lldb/Interpreter/Options.h" 32 #include "lldb/Interpreter/OptionGroupFormat.h" 33 #include "lldb/Target/Language.h" 34 #include "lldb/Target/Process.h" 35 #include "lldb/Target/StackFrame.h" 36 #include "lldb/Target/Target.h" 37 #include "lldb/Target/Thread.h" 38 #include "lldb/Target/ThreadList.h" 39 40 using namespace lldb; 41 using namespace lldb_private; 42 43 44 class ScriptAddOptions 45 { 46 47 public: 48 49 TypeSummaryImpl::Flags m_flags; 50 51 StringList m_target_types; 52 53 bool m_regex; 54 55 ConstString m_name; 56 57 std::string m_category; 58 59 ScriptAddOptions(const TypeSummaryImpl::Flags& flags, 60 bool regx, 61 const ConstString& name, 62 std::string catg) : 63 m_flags(flags), 64 m_regex(regx), 65 m_name(name), 66 m_category(catg) 67 { 68 } 69 70 typedef std::shared_ptr<ScriptAddOptions> SharedPointer; 71 72 }; 73 74 class SynthAddOptions 75 { 76 77 public: 78 79 bool m_skip_pointers; 80 bool m_skip_references; 81 bool m_cascade; 82 bool m_regex; 83 StringList m_target_types; 84 85 std::string m_category; 86 87 SynthAddOptions(bool sptr, 88 bool sref, 89 bool casc, 90 bool regx, 91 std::string catg) : 92 m_skip_pointers(sptr), 93 m_skip_references(sref), 94 m_cascade(casc), 95 m_regex(regx), 96 m_target_types(), 97 m_category(catg) 98 { 99 } 100 101 typedef std::shared_ptr<SynthAddOptions> SharedPointer; 102 103 }; 104 105 static bool 106 WarnOnPotentialUnquotedUnsignedType (Args& command, CommandReturnObject &result) 107 { 108 for (unsigned idx = 0; idx < command.GetArgumentCount(); idx++) 109 { 110 const char* arg = command.GetArgumentAtIndex(idx); 111 if (idx+1 < command.GetArgumentCount()) 112 { 113 if (arg && 0 == strcmp(arg,"unsigned")) 114 { 115 const char* next = command.GetArgumentAtIndex(idx+1); 116 if (next && 117 (0 == strcmp(next, "int") || 118 0 == strcmp(next, "short") || 119 0 == strcmp(next, "char") || 120 0 == strcmp(next, "long"))) 121 { 122 result.AppendWarningWithFormat("%s %s being treated as two types. if you meant the combined type name use quotes, as in \"%s %s\"\n", 123 arg,next,arg,next); 124 return true; 125 } 126 } 127 } 128 } 129 return false; 130 } 131 132 class CommandObjectTypeSummaryAdd : 133 public CommandObjectParsed, 134 public IOHandlerDelegateMultiline 135 { 136 137 private: 138 139 class CommandOptions : public Options 140 { 141 public: 142 143 CommandOptions (CommandInterpreter &interpreter) : 144 Options (interpreter) 145 { 146 } 147 148 virtual 149 ~CommandOptions (){} 150 151 virtual Error 152 SetOptionValue (uint32_t option_idx, const char *option_arg); 153 154 void 155 OptionParsingStarting (); 156 157 const OptionDefinition* 158 GetDefinitions () 159 { 160 return g_option_table; 161 } 162 163 // Options table: Required for subclasses of Options. 164 165 static OptionDefinition g_option_table[]; 166 167 // Instance variables to hold the values for command options. 168 169 TypeSummaryImpl::Flags m_flags; 170 bool m_regex; 171 std::string m_format_string; 172 ConstString m_name; 173 std::string m_python_script; 174 std::string m_python_function; 175 bool m_is_add_script; 176 std::string m_category; 177 }; 178 179 CommandOptions m_options; 180 181 virtual Options * 182 GetOptions () 183 { 184 return &m_options; 185 } 186 187 bool 188 Execute_ScriptSummary (Args& command, CommandReturnObject &result); 189 190 bool 191 Execute_StringSummary (Args& command, CommandReturnObject &result); 192 193 public: 194 195 enum SummaryFormatType 196 { 197 eRegularSummary, 198 eRegexSummary, 199 eNamedSummary 200 }; 201 202 CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter); 203 204 ~CommandObjectTypeSummaryAdd () 205 { 206 } 207 208 virtual void 209 IOHandlerActivated (IOHandler &io_handler) 210 { 211 static const char *g_summary_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n" 212 "def function (valobj,internal_dict):\n" 213 " \"\"\"valobj: an SBValue which you want to provide a summary for\n" 214 " internal_dict: an LLDB support object not to be used\"\"\"\n"; 215 216 StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 217 if (output_sp) 218 { 219 output_sp->PutCString(g_summary_addreader_instructions); 220 output_sp->Flush(); 221 } 222 } 223 224 225 virtual void 226 IOHandlerInputComplete (IOHandler &io_handler, std::string &data) 227 { 228 StreamFileSP error_sp = io_handler.GetErrorStreamFile(); 229 230 #ifndef LLDB_DISABLE_PYTHON 231 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 232 if (interpreter) 233 { 234 StringList lines; 235 lines.SplitIntoLines(data); 236 if (lines.GetSize() > 0) 237 { 238 ScriptAddOptions *options_ptr = ((ScriptAddOptions*)io_handler.GetUserData()); 239 if (options_ptr) 240 { 241 ScriptAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope 242 243 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 244 if (interpreter) 245 { 246 std::string funct_name_str; 247 if (interpreter->GenerateTypeScriptFunction (lines, funct_name_str)) 248 { 249 if (funct_name_str.empty()) 250 { 251 error_sp->Printf ("unable to obtain a valid function name from the script interpreter.\n"); 252 error_sp->Flush(); 253 } 254 else 255 { 256 // now I have a valid function name, let's add this as script for every type in the list 257 258 TypeSummaryImplSP script_format; 259 script_format.reset(new ScriptSummaryFormat(options->m_flags, 260 funct_name_str.c_str(), 261 lines.CopyList(" ").c_str())); 262 263 Error error; 264 265 for (size_t i = 0; i < options->m_target_types.GetSize(); i++) 266 { 267 const char *type_name = options->m_target_types.GetStringAtIndex(i); 268 CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name), 269 script_format, 270 (options->m_regex ? CommandObjectTypeSummaryAdd::eRegexSummary : CommandObjectTypeSummaryAdd::eRegularSummary), 271 options->m_category, 272 &error); 273 if (error.Fail()) 274 { 275 error_sp->Printf ("error: %s", error.AsCString()); 276 error_sp->Flush(); 277 } 278 } 279 280 if (options->m_name) 281 { 282 CommandObjectTypeSummaryAdd::AddSummary (options->m_name, 283 script_format, 284 CommandObjectTypeSummaryAdd::eNamedSummary, 285 options->m_category, 286 &error); 287 if (error.Fail()) 288 { 289 CommandObjectTypeSummaryAdd::AddSummary (options->m_name, 290 script_format, 291 CommandObjectTypeSummaryAdd::eNamedSummary, 292 options->m_category, 293 &error); 294 if (error.Fail()) 295 { 296 error_sp->Printf ("error: %s", error.AsCString()); 297 error_sp->Flush(); 298 } 299 } 300 else 301 { 302 error_sp->Printf ("error: %s", error.AsCString()); 303 error_sp->Flush(); 304 } 305 } 306 else 307 { 308 if (error.AsCString()) 309 { 310 error_sp->Printf ("error: %s", error.AsCString()); 311 error_sp->Flush(); 312 } 313 } 314 } 315 } 316 else 317 { 318 error_sp->Printf ("error: unable to generate a function.\n"); 319 error_sp->Flush(); 320 } 321 } 322 else 323 { 324 error_sp->Printf ("error: no script interpreter.\n"); 325 error_sp->Flush(); 326 } 327 } 328 else 329 { 330 error_sp->Printf ("error: internal synchronization information missing or invalid.\n"); 331 error_sp->Flush(); 332 } 333 } 334 else 335 { 336 error_sp->Printf ("error: empty function, didn't add python command.\n"); 337 error_sp->Flush(); 338 } 339 } 340 else 341 { 342 error_sp->Printf ("error: script interpreter missing, didn't add python command.\n"); 343 error_sp->Flush(); 344 } 345 #endif // #ifndef LLDB_DISABLE_PYTHON 346 io_handler.SetIsDone(true); 347 } 348 349 static bool 350 AddSummary(ConstString type_name, 351 lldb::TypeSummaryImplSP entry, 352 SummaryFormatType type, 353 std::string category, 354 Error* error = NULL); 355 protected: 356 bool 357 DoExecute (Args& command, CommandReturnObject &result); 358 359 }; 360 361 static const char *g_synth_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n" 362 "You must define a Python class with these methods:\n" 363 " def __init__(self, valobj, dict):\n" 364 " def num_children(self):\n" 365 " def get_child_at_index(self, index):\n" 366 " def get_child_index(self, name):\n" 367 " def update(self):\n" 368 " '''Optional'''\n" 369 "class synthProvider:\n"; 370 371 class CommandObjectTypeSynthAdd : 372 public CommandObjectParsed, 373 public IOHandlerDelegateMultiline 374 { 375 376 private: 377 378 class CommandOptions : public Options 379 { 380 public: 381 382 CommandOptions (CommandInterpreter &interpreter) : 383 Options (interpreter) 384 { 385 } 386 387 virtual 388 ~CommandOptions (){} 389 390 virtual Error 391 SetOptionValue (uint32_t option_idx, const char *option_arg) 392 { 393 Error error; 394 const int short_option = m_getopt_table[option_idx].val; 395 bool success; 396 397 switch (short_option) 398 { 399 case 'C': 400 m_cascade = Args::StringToBoolean(option_arg, true, &success); 401 if (!success) 402 error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg); 403 break; 404 case 'P': 405 handwrite_python = true; 406 break; 407 case 'l': 408 m_class_name = std::string(option_arg); 409 is_class_based = true; 410 break; 411 case 'p': 412 m_skip_pointers = true; 413 break; 414 case 'r': 415 m_skip_references = true; 416 break; 417 case 'w': 418 m_category = std::string(option_arg); 419 break; 420 case 'x': 421 m_regex = true; 422 break; 423 default: 424 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 425 break; 426 } 427 428 return error; 429 } 430 431 void 432 OptionParsingStarting () 433 { 434 m_cascade = true; 435 m_class_name = ""; 436 m_skip_pointers = false; 437 m_skip_references = false; 438 m_category = "default"; 439 is_class_based = false; 440 handwrite_python = false; 441 m_regex = false; 442 } 443 444 const OptionDefinition* 445 GetDefinitions () 446 { 447 return g_option_table; 448 } 449 450 // Options table: Required for subclasses of Options. 451 452 static OptionDefinition g_option_table[]; 453 454 // Instance variables to hold the values for command options. 455 456 bool m_cascade; 457 bool m_skip_references; 458 bool m_skip_pointers; 459 std::string m_class_name; 460 bool m_input_python; 461 std::string m_category; 462 463 bool is_class_based; 464 465 bool handwrite_python; 466 467 bool m_regex; 468 469 }; 470 471 CommandOptions m_options; 472 473 virtual Options * 474 GetOptions () 475 { 476 return &m_options; 477 } 478 479 bool 480 Execute_HandwritePython (Args& command, CommandReturnObject &result); 481 482 bool 483 Execute_PythonClass (Args& command, CommandReturnObject &result); 484 485 protected: 486 bool 487 DoExecute (Args& command, CommandReturnObject &result) 488 { 489 WarnOnPotentialUnquotedUnsignedType(command, result); 490 491 if (m_options.handwrite_python) 492 return Execute_HandwritePython(command, result); 493 else if (m_options.is_class_based) 494 return Execute_PythonClass(command, result); 495 else 496 { 497 result.AppendError("must either provide a children list, a Python class name, or use -P and type a Python class line-by-line"); 498 result.SetStatus(eReturnStatusFailed); 499 return false; 500 } 501 } 502 503 virtual void 504 IOHandlerActivated (IOHandler &io_handler) 505 { 506 StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 507 if (output_sp) 508 { 509 output_sp->PutCString(g_synth_addreader_instructions); 510 output_sp->Flush(); 511 } 512 } 513 514 515 virtual void 516 IOHandlerInputComplete (IOHandler &io_handler, std::string &data) 517 { 518 StreamFileSP error_sp = io_handler.GetErrorStreamFile(); 519 520 #ifndef LLDB_DISABLE_PYTHON 521 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 522 if (interpreter) 523 { 524 StringList lines; 525 lines.SplitIntoLines(data); 526 if (lines.GetSize() > 0) 527 { 528 SynthAddOptions *options_ptr = ((SynthAddOptions*)io_handler.GetUserData()); 529 if (options_ptr) 530 { 531 SynthAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope 532 533 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 534 if (interpreter) 535 { 536 std::string class_name_str; 537 if (interpreter->GenerateTypeSynthClass (lines, class_name_str)) 538 { 539 if (class_name_str.empty()) 540 { 541 error_sp->Printf ("error: unable to obtain a proper name for the class.\n"); 542 error_sp->Flush(); 543 } 544 else 545 { 546 // everything should be fine now, let's add the synth provider class 547 548 SyntheticChildrenSP synth_provider; 549 synth_provider.reset(new ScriptedSyntheticChildren(SyntheticChildren::Flags().SetCascades(options->m_cascade). 550 SetSkipPointers(options->m_skip_pointers). 551 SetSkipReferences(options->m_skip_references), 552 class_name_str.c_str())); 553 554 555 lldb::TypeCategoryImplSP category; 556 DataVisualization::Categories::GetCategory(ConstString(options->m_category.c_str()), category); 557 558 Error error; 559 560 for (size_t i = 0; i < options->m_target_types.GetSize(); i++) 561 { 562 const char *type_name = options->m_target_types.GetStringAtIndex(i); 563 ConstString const_type_name(type_name); 564 if (const_type_name) 565 { 566 if (!CommandObjectTypeSynthAdd::AddSynth(const_type_name, 567 synth_provider, 568 options->m_regex ? CommandObjectTypeSynthAdd::eRegexSynth : CommandObjectTypeSynthAdd::eRegularSynth, 569 options->m_category, 570 &error)) 571 { 572 error_sp->Printf("error: %s\n", error.AsCString()); 573 error_sp->Flush(); 574 break; 575 } 576 } 577 else 578 { 579 error_sp->Printf ("error: invalid type name.\n"); 580 error_sp->Flush(); 581 break; 582 } 583 } 584 } 585 } 586 else 587 { 588 error_sp->Printf ("error: unable to generate a class.\n"); 589 error_sp->Flush(); 590 } 591 } 592 else 593 { 594 error_sp->Printf ("error: no script interpreter.\n"); 595 error_sp->Flush(); 596 } 597 } 598 else 599 { 600 error_sp->Printf ("error: internal synchronization data missing.\n"); 601 error_sp->Flush(); 602 } 603 } 604 else 605 { 606 error_sp->Printf ("error: empty function, didn't add python command.\n"); 607 error_sp->Flush(); 608 } 609 } 610 else 611 { 612 error_sp->Printf ("error: script interpreter missing, didn't add python command.\n"); 613 error_sp->Flush(); 614 } 615 616 #endif // #ifndef LLDB_DISABLE_PYTHON 617 io_handler.SetIsDone(true); 618 } 619 620 public: 621 622 enum SynthFormatType 623 { 624 eRegularSynth, 625 eRegexSynth 626 }; 627 628 CommandObjectTypeSynthAdd (CommandInterpreter &interpreter); 629 630 ~CommandObjectTypeSynthAdd () 631 { 632 } 633 634 static bool 635 AddSynth(ConstString type_name, 636 lldb::SyntheticChildrenSP entry, 637 SynthFormatType type, 638 std::string category_name, 639 Error* error); 640 }; 641 642 //------------------------------------------------------------------------- 643 // CommandObjectTypeFormatAdd 644 //------------------------------------------------------------------------- 645 646 class CommandObjectTypeFormatAdd : public CommandObjectParsed 647 { 648 649 private: 650 651 class CommandOptions : public OptionGroup 652 { 653 public: 654 655 CommandOptions () : 656 OptionGroup() 657 { 658 } 659 660 virtual 661 ~CommandOptions () 662 { 663 } 664 665 virtual uint32_t 666 GetNumDefinitions (); 667 668 virtual const OptionDefinition* 669 GetDefinitions () 670 { 671 return g_option_table; 672 } 673 674 virtual void 675 OptionParsingStarting (CommandInterpreter &interpreter) 676 { 677 m_cascade = true; 678 m_skip_pointers = false; 679 m_skip_references = false; 680 m_regex = false; 681 m_category.assign("default"); 682 m_custom_type_name.clear(); 683 } 684 virtual Error 685 SetOptionValue (CommandInterpreter &interpreter, 686 uint32_t option_idx, 687 const char *option_value) 688 { 689 Error error; 690 const int short_option = g_option_table[option_idx].short_option; 691 bool success; 692 693 switch (short_option) 694 { 695 case 'C': 696 m_cascade = Args::StringToBoolean(option_value, true, &success); 697 if (!success) 698 error.SetErrorStringWithFormat("invalid value for cascade: %s", option_value); 699 break; 700 case 'p': 701 m_skip_pointers = true; 702 break; 703 case 'w': 704 m_category.assign(option_value); 705 break; 706 case 'r': 707 m_skip_references = true; 708 break; 709 case 'x': 710 m_regex = true; 711 break; 712 case 't': 713 m_custom_type_name.assign(option_value); 714 break; 715 default: 716 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 717 break; 718 } 719 720 return error; 721 } 722 723 // Options table: Required for subclasses of Options. 724 725 static OptionDefinition g_option_table[]; 726 727 // Instance variables to hold the values for command options. 728 729 bool m_cascade; 730 bool m_skip_references; 731 bool m_skip_pointers; 732 bool m_regex; 733 std::string m_category; 734 std::string m_custom_type_name; 735 }; 736 737 OptionGroupOptions m_option_group; 738 OptionGroupFormat m_format_options; 739 CommandOptions m_command_options; 740 741 virtual Options * 742 GetOptions () 743 { 744 return &m_option_group; 745 } 746 747 public: 748 CommandObjectTypeFormatAdd (CommandInterpreter &interpreter) : 749 CommandObjectParsed (interpreter, 750 "type format add", 751 "Add a new formatting style for a type.", 752 NULL), 753 m_option_group (interpreter), 754 m_format_options (eFormatInvalid), 755 m_command_options () 756 { 757 CommandArgumentEntry type_arg; 758 CommandArgumentData type_style_arg; 759 760 type_style_arg.arg_type = eArgTypeName; 761 type_style_arg.arg_repetition = eArgRepeatPlus; 762 763 type_arg.push_back (type_style_arg); 764 765 m_arguments.push_back (type_arg); 766 767 SetHelpLong( 768 R"( 769 The following examples of 'type format add' refer to this code snippet for context: 770 771 typedef int Aint; 772 typedef float Afloat; 773 typedef Aint Bint; 774 typedef Afloat Bfloat; 775 776 Aint ix = 5; 777 Bint iy = 5; 778 779 Afloat fx = 3.14; 780 BFloat fy = 3.14; 781 782 Adding default formatting: 783 784 (lldb) type format add -f hex AInt 785 (lldb) frame variable iy 786 787 )" " Produces hexidecimal display of iy, because no formatter is available for Bint and \ 788 the one for Aint is used instead." R"( 789 790 To prevent this use the cascade option '-C no' to prevent evaluation of typedef chains: 791 792 793 (lldb) type format add -f hex -C no AInt 794 795 Similar reasoning applies to this: 796 797 (lldb) type format add -f hex -C no float -p 798 799 )" " All float values and float references are now formatted as hexadecimal, but not \ 800 pointers to floats. Nor will it change the default display for Afloat and Bfloat objects." 801 ); 802 803 // Add the "--format" to all options groups 804 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1); 805 m_option_group.Append (&m_command_options); 806 m_option_group.Finalize(); 807 808 } 809 810 ~CommandObjectTypeFormatAdd () 811 { 812 } 813 814 protected: 815 bool 816 DoExecute (Args& command, CommandReturnObject &result) 817 { 818 const size_t argc = command.GetArgumentCount(); 819 820 if (argc < 1) 821 { 822 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); 823 result.SetStatus(eReturnStatusFailed); 824 return false; 825 } 826 827 const Format format = m_format_options.GetFormat(); 828 if (format == eFormatInvalid && m_command_options.m_custom_type_name.empty()) 829 { 830 result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str()); 831 result.SetStatus(eReturnStatusFailed); 832 return false; 833 } 834 835 TypeFormatImplSP entry; 836 837 if (m_command_options.m_custom_type_name.empty()) 838 entry.reset(new TypeFormatImpl_Format(format, 839 TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade). 840 SetSkipPointers(m_command_options.m_skip_pointers). 841 SetSkipReferences(m_command_options.m_skip_references))); 842 else 843 entry.reset(new TypeFormatImpl_EnumType(ConstString(m_command_options.m_custom_type_name.c_str()), 844 TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade). 845 SetSkipPointers(m_command_options.m_skip_pointers). 846 SetSkipReferences(m_command_options.m_skip_references))); 847 848 // now I have a valid format, let's add it to every type 849 850 TypeCategoryImplSP category_sp; 851 DataVisualization::Categories::GetCategory(ConstString(m_command_options.m_category), category_sp); 852 if (!category_sp) 853 return false; 854 855 WarnOnPotentialUnquotedUnsignedType(command, result); 856 857 for (size_t i = 0; i < argc; i++) 858 { 859 const char* typeA = command.GetArgumentAtIndex(i); 860 ConstString typeCS(typeA); 861 if (typeCS) 862 { 863 if (m_command_options.m_regex) 864 { 865 RegularExpressionSP typeRX(new RegularExpression()); 866 if (!typeRX->Compile(typeCS.GetCString())) 867 { 868 result.AppendError("regex format error (maybe this is not really a regex?)"); 869 result.SetStatus(eReturnStatusFailed); 870 return false; 871 } 872 category_sp->GetRegexTypeSummariesContainer()->Delete(typeCS); 873 category_sp->GetRegexTypeFormatsContainer()->Add(typeRX, entry); 874 } 875 else 876 category_sp->GetTypeFormatsContainer()->Add(typeCS, entry); 877 } 878 else 879 { 880 result.AppendError("empty typenames not allowed"); 881 result.SetStatus(eReturnStatusFailed); 882 return false; 883 } 884 } 885 886 result.SetStatus(eReturnStatusSuccessFinishNoResult); 887 return result.Succeeded(); 888 } 889 }; 890 891 OptionDefinition 892 CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] = 893 { 894 { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, 895 { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, 896 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, 897 { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, 898 { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, 899 { LLDB_OPT_SET_2, false, "type", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Format variables as if they were of this type."}, 900 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 901 }; 902 903 904 uint32_t 905 CommandObjectTypeFormatAdd::CommandOptions::GetNumDefinitions () 906 { 907 return sizeof(g_option_table) / sizeof (OptionDefinition); 908 } 909 910 911 //------------------------------------------------------------------------- 912 // CommandObjectTypeFormatDelete 913 //------------------------------------------------------------------------- 914 915 class CommandObjectTypeFormatDelete : public CommandObjectParsed 916 { 917 private: 918 class CommandOptions : public Options 919 { 920 public: 921 922 CommandOptions (CommandInterpreter &interpreter) : 923 Options (interpreter) 924 { 925 } 926 927 virtual 928 ~CommandOptions (){} 929 930 virtual Error 931 SetOptionValue (uint32_t option_idx, const char *option_arg) 932 { 933 Error error; 934 const int short_option = m_getopt_table[option_idx].val; 935 936 switch (short_option) 937 { 938 case 'a': 939 m_delete_all = true; 940 break; 941 case 'w': 942 m_category = std::string(option_arg); 943 break; 944 default: 945 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 946 break; 947 } 948 949 return error; 950 } 951 952 void 953 OptionParsingStarting () 954 { 955 m_delete_all = false; 956 m_category = "default"; 957 } 958 959 const OptionDefinition* 960 GetDefinitions () 961 { 962 return g_option_table; 963 } 964 965 // Options table: Required for subclasses of Options. 966 967 static OptionDefinition g_option_table[]; 968 969 // Instance variables to hold the values for command options. 970 971 bool m_delete_all; 972 std::string m_category; 973 974 }; 975 976 CommandOptions m_options; 977 978 virtual Options * 979 GetOptions () 980 { 981 return &m_options; 982 } 983 984 static bool 985 PerCategoryCallback(void* param, 986 const lldb::TypeCategoryImplSP& category_sp) 987 { 988 ConstString *name = (ConstString*)param; 989 category_sp->Delete(*name, eFormatCategoryItemValue | eFormatCategoryItemRegexValue); 990 return true; 991 } 992 993 public: 994 CommandObjectTypeFormatDelete (CommandInterpreter &interpreter) : 995 CommandObjectParsed (interpreter, 996 "type format delete", 997 "Delete an existing formatting style for a type.", 998 NULL), 999 m_options(interpreter) 1000 { 1001 CommandArgumentEntry type_arg; 1002 CommandArgumentData type_style_arg; 1003 1004 type_style_arg.arg_type = eArgTypeName; 1005 type_style_arg.arg_repetition = eArgRepeatPlain; 1006 1007 type_arg.push_back (type_style_arg); 1008 1009 m_arguments.push_back (type_arg); 1010 1011 } 1012 1013 ~CommandObjectTypeFormatDelete () 1014 { 1015 } 1016 1017 protected: 1018 bool 1019 DoExecute (Args& command, CommandReturnObject &result) 1020 { 1021 const size_t argc = command.GetArgumentCount(); 1022 1023 if (argc != 1) 1024 { 1025 result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); 1026 result.SetStatus(eReturnStatusFailed); 1027 return false; 1028 } 1029 1030 const char* typeA = command.GetArgumentAtIndex(0); 1031 ConstString typeCS(typeA); 1032 1033 if (!typeCS) 1034 { 1035 result.AppendError("empty typenames not allowed"); 1036 result.SetStatus(eReturnStatusFailed); 1037 return false; 1038 } 1039 1040 if (m_options.m_delete_all) 1041 { 1042 DataVisualization::Categories::LoopThrough(PerCategoryCallback, &typeCS); 1043 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1044 return result.Succeeded(); 1045 } 1046 1047 lldb::TypeCategoryImplSP category; 1048 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 1049 1050 bool delete_category = category->Delete(typeCS, 1051 eFormatCategoryItemValue | eFormatCategoryItemRegexValue); 1052 1053 if (delete_category) 1054 { 1055 result.SetStatus(eReturnStatusSuccessFinishNoResult); 1056 return result.Succeeded(); 1057 } 1058 else 1059 { 1060 result.AppendErrorWithFormat ("no custom format for %s.\n", typeA); 1061 result.SetStatus(eReturnStatusFailed); 1062 return false; 1063 } 1064 1065 } 1066 1067 }; 1068 1069 OptionDefinition 1070 CommandObjectTypeFormatDelete::CommandOptions::g_option_table[] = 1071 { 1072 { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Delete from every category."}, 1073 { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Delete from given category."}, 1074 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 1075 }; 1076 1077 //------------------------------------------------------------------------- 1078 // CommandObjectTypeFormatClear 1079 //------------------------------------------------------------------------- 1080 1081 class CommandObjectTypeFormatClear : public CommandObjectParsed 1082 { 1083 private: 1084 1085 class CommandOptions : public Options 1086 { 1087 public: 1088 1089 CommandOptions (CommandInterpreter &interpreter) : 1090 Options (interpreter) 1091 { 1092 } 1093 1094 virtual 1095 ~CommandOptions (){} 1096 1097 virtual Error 1098 SetOptionValue (uint32_t option_idx, const char *option_arg) 1099 { 1100 Error error; 1101 const int short_option = m_getopt_table[option_idx].val; 1102 1103 switch (short_option) 1104 { 1105 case 'a': 1106 m_delete_all = true; 1107 break; 1108 default: 1109 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1110 break; 1111 } 1112 1113 return error; 1114 } 1115 1116 void 1117 OptionParsingStarting () 1118 { 1119 m_delete_all = false; 1120 } 1121 1122 const OptionDefinition* 1123 GetDefinitions () 1124 { 1125 return g_option_table; 1126 } 1127 1128 // Options table: Required for subclasses of Options. 1129 1130 static OptionDefinition g_option_table[]; 1131 1132 // Instance variables to hold the values for command options. 1133 1134 bool m_delete_all; 1135 bool m_delete_named; 1136 }; 1137 1138 CommandOptions m_options; 1139 1140 virtual Options * 1141 GetOptions () 1142 { 1143 return &m_options; 1144 } 1145 1146 static bool 1147 PerCategoryCallback(void* param, 1148 const lldb::TypeCategoryImplSP& cate) 1149 { 1150 cate->GetTypeFormatsContainer()->Clear(); 1151 cate->GetRegexTypeFormatsContainer()->Clear(); 1152 return true; 1153 1154 } 1155 1156 public: 1157 CommandObjectTypeFormatClear (CommandInterpreter &interpreter) : 1158 CommandObjectParsed (interpreter, 1159 "type format clear", 1160 "Delete all existing format styles.", 1161 NULL), 1162 m_options(interpreter) 1163 { 1164 } 1165 1166 ~CommandObjectTypeFormatClear () 1167 { 1168 } 1169 1170 protected: 1171 bool 1172 DoExecute (Args& command, CommandReturnObject &result) 1173 { 1174 if (m_options.m_delete_all) 1175 DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL); 1176 1177 else 1178 { 1179 lldb::TypeCategoryImplSP category; 1180 if (command.GetArgumentCount() > 0) 1181 { 1182 const char* cat_name = command.GetArgumentAtIndex(0); 1183 ConstString cat_nameCS(cat_name); 1184 DataVisualization::Categories::GetCategory(cat_nameCS, category); 1185 } 1186 else 1187 DataVisualization::Categories::GetCategory(ConstString(NULL), category); 1188 category->Clear(eFormatCategoryItemValue | eFormatCategoryItemRegexValue); 1189 } 1190 1191 result.SetStatus(eReturnStatusSuccessFinishResult); 1192 return result.Succeeded(); 1193 } 1194 1195 }; 1196 1197 OptionDefinition 1198 CommandObjectTypeFormatClear::CommandOptions::g_option_table[] = 1199 { 1200 { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Clear every category."}, 1201 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 1202 }; 1203 1204 //------------------------------------------------------------------------- 1205 // CommandObjectTypeFormatList 1206 //------------------------------------------------------------------------- 1207 1208 bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeFormatImplSP& entry); 1209 bool CommandObjectTypeRXFormatList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeFormatImplSP& entry); 1210 1211 class CommandObjectTypeFormatList; 1212 1213 struct CommandObjectTypeFormatList_LoopCallbackParam { 1214 CommandObjectTypeFormatList* self; 1215 CommandReturnObject* result; 1216 RegularExpression* regex; 1217 RegularExpression* cate_regex; 1218 CommandObjectTypeFormatList_LoopCallbackParam(CommandObjectTypeFormatList* S, CommandReturnObject* R, 1219 RegularExpression* X = NULL, RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {} 1220 }; 1221 1222 class CommandObjectTypeFormatList : public CommandObjectParsed 1223 { 1224 class CommandOptions : public Options 1225 { 1226 public: 1227 1228 CommandOptions (CommandInterpreter &interpreter) : 1229 Options (interpreter) 1230 { 1231 } 1232 1233 virtual 1234 ~CommandOptions (){} 1235 1236 virtual Error 1237 SetOptionValue (uint32_t option_idx, const char *option_arg) 1238 { 1239 Error error; 1240 const int short_option = m_getopt_table[option_idx].val; 1241 1242 switch (short_option) 1243 { 1244 case 'w': 1245 m_category_regex = std::string(option_arg); 1246 break; 1247 default: 1248 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1249 break; 1250 } 1251 1252 return error; 1253 } 1254 1255 void 1256 OptionParsingStarting () 1257 { 1258 m_category_regex = ""; 1259 } 1260 1261 const OptionDefinition* 1262 GetDefinitions () 1263 { 1264 return g_option_table; 1265 } 1266 1267 // Options table: Required for subclasses of Options. 1268 1269 static OptionDefinition g_option_table[]; 1270 1271 // Instance variables to hold the values for command options. 1272 1273 std::string m_category_regex; 1274 1275 }; 1276 1277 CommandOptions m_options; 1278 1279 virtual Options * 1280 GetOptions () 1281 { 1282 return &m_options; 1283 } 1284 1285 public: 1286 CommandObjectTypeFormatList (CommandInterpreter &interpreter) : 1287 CommandObjectParsed (interpreter, 1288 "type format list", 1289 "Show a list of current formatting styles.", 1290 NULL), 1291 m_options(interpreter) 1292 { 1293 CommandArgumentEntry type_arg; 1294 CommandArgumentData type_style_arg; 1295 1296 type_style_arg.arg_type = eArgTypeName; 1297 type_style_arg.arg_repetition = eArgRepeatOptional; 1298 1299 type_arg.push_back (type_style_arg); 1300 1301 m_arguments.push_back (type_arg); 1302 } 1303 1304 ~CommandObjectTypeFormatList () 1305 { 1306 } 1307 1308 protected: 1309 bool 1310 DoExecute (Args& command, CommandReturnObject &result) 1311 { 1312 const size_t argc = command.GetArgumentCount(); 1313 1314 CommandObjectTypeFormatList_LoopCallbackParam *param; 1315 RegularExpression* cate_regex = 1316 m_options.m_category_regex.empty() ? NULL : 1317 new RegularExpression(m_options.m_category_regex.c_str()); 1318 1319 if (argc == 1) 1320 { 1321 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); 1322 regex->Compile(command.GetArgumentAtIndex(0)); 1323 param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,regex,cate_regex); 1324 } 1325 else 1326 param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,NULL,cate_regex); 1327 1328 DataVisualization::Categories::LoopThrough(PerCategoryCallback,param); 1329 delete param; 1330 1331 if (cate_regex) 1332 delete cate_regex; 1333 1334 result.SetStatus(eReturnStatusSuccessFinishResult); 1335 return result.Succeeded(); 1336 } 1337 1338 private: 1339 1340 static bool 1341 PerCategoryCallback(void* param_vp, 1342 const lldb::TypeCategoryImplSP& cate) 1343 { 1344 1345 CommandObjectTypeFormatList_LoopCallbackParam* param = 1346 (CommandObjectTypeFormatList_LoopCallbackParam*)param_vp; 1347 CommandReturnObject* result = param->result; 1348 1349 const char* cate_name = cate->GetName(); 1350 1351 // if the category is disabled or empty and there is no regex, just skip it 1352 if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemValue | eFormatCategoryItemRegexValue) == 0) && param->cate_regex == NULL) 1353 return true; 1354 1355 // if we have a regex and this category does not match it, just skip it 1356 if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false) 1357 return true; 1358 1359 result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n", 1360 cate_name, 1361 (cate->IsEnabled() ? "enabled" : "disabled")); 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 (%s)\n-----------------------\n", 2402 cate_name, 2403 (cate->IsEnabled() ? "enabled" : "disabled")); 2404 2405 cate->GetTypeSummariesContainer()->LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param_vp); 2406 2407 if (cate->GetRegexTypeSummariesContainer()->GetCount() > 0) 2408 { 2409 result->GetOutputStream().Printf("Regex-based summaries (slower):\n"); 2410 cate->GetRegexTypeSummariesContainer()->LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, param_vp); 2411 } 2412 return true; 2413 } 2414 2415 2416 bool 2417 LoopCallback (const char* type, 2418 const lldb::TypeSummaryImplSP& entry, 2419 RegularExpression* regex, 2420 CommandReturnObject *result) 2421 { 2422 if (regex == NULL || strcmp(type,regex->GetText()) == 0 || regex->Execute(type)) 2423 result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str()); 2424 return true; 2425 } 2426 2427 friend bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeSummaryImplSP& entry); 2428 friend bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeSummaryImplSP& entry); 2429 }; 2430 2431 bool 2432 CommandObjectTypeSummaryList_LoopCallback ( 2433 void* pt2self, 2434 ConstString type, 2435 const lldb::TypeSummaryImplSP& entry) 2436 { 2437 CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self; 2438 return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result); 2439 } 2440 2441 bool 2442 CommandObjectTypeRXSummaryList_LoopCallback ( 2443 void* pt2self, 2444 lldb::RegularExpressionSP regex, 2445 const lldb::TypeSummaryImplSP& entry) 2446 { 2447 CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self; 2448 return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); 2449 } 2450 2451 OptionDefinition 2452 CommandObjectTypeSummaryList::CommandOptions::g_option_table[] = 2453 { 2454 { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, 2455 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 2456 }; 2457 2458 //------------------------------------------------------------------------- 2459 // CommandObjectTypeCategoryEnable 2460 //------------------------------------------------------------------------- 2461 2462 class CommandObjectTypeCategoryEnable : public CommandObjectParsed 2463 { 2464 class CommandOptions : public Options 2465 { 2466 public: 2467 2468 CommandOptions (CommandInterpreter &interpreter) : 2469 Options (interpreter) 2470 { 2471 } 2472 2473 virtual 2474 ~CommandOptions (){} 2475 2476 virtual Error 2477 SetOptionValue (uint32_t option_idx, const char *option_arg) 2478 { 2479 Error error; 2480 const int short_option = m_getopt_table[option_idx].val; 2481 2482 switch (short_option) 2483 { 2484 case 'l': 2485 if (option_arg) 2486 { 2487 m_language = Language::GetLanguageTypeFromString(option_arg); 2488 if (m_language == lldb::eLanguageTypeUnknown) 2489 error.SetErrorStringWithFormat ("unrecognized language '%s'", option_arg); 2490 } 2491 break; 2492 default: 2493 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 2494 break; 2495 } 2496 2497 return error; 2498 } 2499 2500 void 2501 OptionParsingStarting () 2502 { 2503 m_language = lldb::eLanguageTypeUnknown; 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 lldb::LanguageType m_language; 2519 2520 }; 2521 2522 CommandOptions m_options; 2523 2524 virtual Options * 2525 GetOptions () 2526 { 2527 return &m_options; 2528 } 2529 2530 public: 2531 CommandObjectTypeCategoryEnable (CommandInterpreter &interpreter) : 2532 CommandObjectParsed (interpreter, 2533 "type category enable", 2534 "Enable a category as a source of formatters.", 2535 NULL), 2536 m_options(interpreter) 2537 { 2538 CommandArgumentEntry type_arg; 2539 CommandArgumentData type_style_arg; 2540 2541 type_style_arg.arg_type = eArgTypeName; 2542 type_style_arg.arg_repetition = eArgRepeatPlus; 2543 2544 type_arg.push_back (type_style_arg); 2545 2546 m_arguments.push_back (type_arg); 2547 2548 } 2549 2550 ~CommandObjectTypeCategoryEnable () 2551 { 2552 } 2553 2554 protected: 2555 bool 2556 DoExecute (Args& command, CommandReturnObject &result) 2557 { 2558 const size_t argc = command.GetArgumentCount(); 2559 2560 if (argc < 1 && 2561 m_options.m_language == lldb::eLanguageTypeUnknown) 2562 { 2563 result.AppendErrorWithFormat ("%s takes arguments and/or a language", m_cmd_name.c_str()); 2564 result.SetStatus(eReturnStatusFailed); 2565 return false; 2566 } 2567 2568 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0) 2569 { 2570 DataVisualization::Categories::EnableStar(); 2571 } 2572 else if (argc > 0) 2573 { 2574 for (int i = argc - 1; i >= 0; i--) 2575 { 2576 const char* typeA = command.GetArgumentAtIndex(i); 2577 ConstString typeCS(typeA); 2578 2579 if (!typeCS) 2580 { 2581 result.AppendError("empty category name not allowed"); 2582 result.SetStatus(eReturnStatusFailed); 2583 return false; 2584 } 2585 DataVisualization::Categories::Enable(typeCS); 2586 lldb::TypeCategoryImplSP cate; 2587 if (DataVisualization::Categories::GetCategory(typeCS, cate) && cate.get()) 2588 { 2589 if (cate->GetCount() == 0) 2590 { 2591 result.AppendWarning("empty category enabled (typo?)"); 2592 } 2593 } 2594 } 2595 } 2596 2597 if (m_options.m_language != lldb::eLanguageTypeUnknown) 2598 DataVisualization::Categories::Enable(m_options.m_language); 2599 2600 result.SetStatus(eReturnStatusSuccessFinishResult); 2601 return result.Succeeded(); 2602 } 2603 2604 }; 2605 2606 OptionDefinition 2607 CommandObjectTypeCategoryEnable::CommandOptions::g_option_table[] = 2608 { 2609 { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Enable the category for this language."}, 2610 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 2611 }; 2612 2613 //------------------------------------------------------------------------- 2614 // CommandObjectTypeCategoryDelete 2615 //------------------------------------------------------------------------- 2616 2617 class CommandObjectTypeCategoryDelete : public CommandObjectParsed 2618 { 2619 public: 2620 CommandObjectTypeCategoryDelete (CommandInterpreter &interpreter) : 2621 CommandObjectParsed (interpreter, 2622 "type category delete", 2623 "Delete a category and all associated formatters.", 2624 NULL) 2625 { 2626 CommandArgumentEntry type_arg; 2627 CommandArgumentData type_style_arg; 2628 2629 type_style_arg.arg_type = eArgTypeName; 2630 type_style_arg.arg_repetition = eArgRepeatPlus; 2631 2632 type_arg.push_back (type_style_arg); 2633 2634 m_arguments.push_back (type_arg); 2635 2636 } 2637 2638 ~CommandObjectTypeCategoryDelete () 2639 { 2640 } 2641 2642 protected: 2643 bool 2644 DoExecute (Args& command, CommandReturnObject &result) 2645 { 2646 const size_t argc = command.GetArgumentCount(); 2647 2648 if (argc < 1) 2649 { 2650 result.AppendErrorWithFormat ("%s takes 1 or more arg.\n", m_cmd_name.c_str()); 2651 result.SetStatus(eReturnStatusFailed); 2652 return false; 2653 } 2654 2655 bool success = true; 2656 2657 // the order is not relevant here 2658 for (int i = argc - 1; i >= 0; i--) 2659 { 2660 const char* typeA = command.GetArgumentAtIndex(i); 2661 ConstString typeCS(typeA); 2662 2663 if (!typeCS) 2664 { 2665 result.AppendError("empty category name not allowed"); 2666 result.SetStatus(eReturnStatusFailed); 2667 return false; 2668 } 2669 if (!DataVisualization::Categories::Delete(typeCS)) 2670 success = false; // keep deleting even if we hit an error 2671 } 2672 if (success) 2673 { 2674 result.SetStatus(eReturnStatusSuccessFinishResult); 2675 return result.Succeeded(); 2676 } 2677 else 2678 { 2679 result.AppendError("cannot delete one or more categories\n"); 2680 result.SetStatus(eReturnStatusFailed); 2681 return false; 2682 } 2683 } 2684 }; 2685 2686 //------------------------------------------------------------------------- 2687 // CommandObjectTypeCategoryDisable 2688 //------------------------------------------------------------------------- 2689 2690 class CommandObjectTypeCategoryDisable : public CommandObjectParsed 2691 { 2692 class CommandOptions : public Options 2693 { 2694 public: 2695 2696 CommandOptions (CommandInterpreter &interpreter) : 2697 Options (interpreter) 2698 { 2699 } 2700 2701 virtual 2702 ~CommandOptions (){} 2703 2704 virtual Error 2705 SetOptionValue (uint32_t option_idx, const char *option_arg) 2706 { 2707 Error error; 2708 const int short_option = m_getopt_table[option_idx].val; 2709 2710 switch (short_option) 2711 { 2712 case 'l': 2713 if (option_arg) 2714 { 2715 m_language = Language::GetLanguageTypeFromString(option_arg); 2716 if (m_language == lldb::eLanguageTypeUnknown) 2717 error.SetErrorStringWithFormat ("unrecognized language '%s'", option_arg); 2718 } 2719 break; 2720 default: 2721 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 2722 break; 2723 } 2724 2725 return error; 2726 } 2727 2728 void 2729 OptionParsingStarting () 2730 { 2731 m_language = lldb::eLanguageTypeUnknown; 2732 } 2733 2734 const OptionDefinition* 2735 GetDefinitions () 2736 { 2737 return g_option_table; 2738 } 2739 2740 // Options table: Required for subclasses of Options. 2741 2742 static OptionDefinition g_option_table[]; 2743 2744 // Instance variables to hold the values for command options. 2745 2746 lldb::LanguageType m_language; 2747 2748 }; 2749 2750 CommandOptions m_options; 2751 2752 virtual Options * 2753 GetOptions () 2754 { 2755 return &m_options; 2756 } 2757 2758 public: 2759 CommandObjectTypeCategoryDisable (CommandInterpreter &interpreter) : 2760 CommandObjectParsed (interpreter, 2761 "type category disable", 2762 "Disable a category as a source of formatters.", 2763 NULL), 2764 m_options(interpreter) 2765 { 2766 CommandArgumentEntry type_arg; 2767 CommandArgumentData type_style_arg; 2768 2769 type_style_arg.arg_type = eArgTypeName; 2770 type_style_arg.arg_repetition = eArgRepeatPlus; 2771 2772 type_arg.push_back (type_style_arg); 2773 2774 m_arguments.push_back (type_arg); 2775 2776 } 2777 2778 ~CommandObjectTypeCategoryDisable () 2779 { 2780 } 2781 2782 protected: 2783 bool 2784 DoExecute (Args& command, CommandReturnObject &result) 2785 { 2786 const size_t argc = command.GetArgumentCount(); 2787 2788 if (argc < 1 && 2789 m_options.m_language == lldb::eLanguageTypeUnknown) 2790 { 2791 result.AppendErrorWithFormat ("%s takes arguments and/or a language", m_cmd_name.c_str()); 2792 result.SetStatus(eReturnStatusFailed); 2793 return false; 2794 } 2795 2796 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0) 2797 { 2798 DataVisualization::Categories::DisableStar(); 2799 } 2800 else if (argc > 0) 2801 { 2802 // the order is not relevant here 2803 for (int i = argc - 1; i >= 0; i--) 2804 { 2805 const char* typeA = command.GetArgumentAtIndex(i); 2806 ConstString typeCS(typeA); 2807 2808 if (!typeCS) 2809 { 2810 result.AppendError("empty category name not allowed"); 2811 result.SetStatus(eReturnStatusFailed); 2812 return false; 2813 } 2814 DataVisualization::Categories::Disable(typeCS); 2815 } 2816 } 2817 2818 if (m_options.m_language != lldb::eLanguageTypeUnknown) 2819 DataVisualization::Categories::Disable(m_options.m_language); 2820 2821 result.SetStatus(eReturnStatusSuccessFinishResult); 2822 return result.Succeeded(); 2823 } 2824 2825 }; 2826 2827 OptionDefinition 2828 CommandObjectTypeCategoryDisable::CommandOptions::g_option_table[] = 2829 { 2830 { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Enable the category for this language."}, 2831 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 2832 }; 2833 2834 //------------------------------------------------------------------------- 2835 // CommandObjectTypeCategoryList 2836 //------------------------------------------------------------------------- 2837 2838 class CommandObjectTypeCategoryList : public CommandObjectParsed 2839 { 2840 private: 2841 2842 struct CommandObjectTypeCategoryList_CallbackParam 2843 { 2844 CommandReturnObject* result; 2845 RegularExpression* regex; 2846 2847 CommandObjectTypeCategoryList_CallbackParam(CommandReturnObject* res, 2848 RegularExpression* rex = NULL) : 2849 result(res), 2850 regex(rex) 2851 { 2852 } 2853 2854 }; 2855 2856 static bool 2857 PerCategoryCallback(void* param_vp, 2858 const lldb::TypeCategoryImplSP& cate) 2859 { 2860 CommandObjectTypeCategoryList_CallbackParam* param = 2861 (CommandObjectTypeCategoryList_CallbackParam*)param_vp; 2862 CommandReturnObject* result = param->result; 2863 RegularExpression* regex = param->regex; 2864 2865 const char* cate_name = cate->GetName(); 2866 2867 if (regex == NULL || strcmp(cate_name, regex->GetText()) == 0 || regex->Execute(cate_name)) 2868 result->GetOutputStream().Printf("Category %s is%s enabled\n", 2869 cate_name, 2870 (cate->IsEnabled() ? "" : " not")); 2871 return true; 2872 } 2873 public: 2874 CommandObjectTypeCategoryList (CommandInterpreter &interpreter) : 2875 CommandObjectParsed (interpreter, 2876 "type category list", 2877 "Provide a list of all existing categories.", 2878 NULL) 2879 { 2880 CommandArgumentEntry type_arg; 2881 CommandArgumentData type_style_arg; 2882 2883 type_style_arg.arg_type = eArgTypeName; 2884 type_style_arg.arg_repetition = eArgRepeatOptional; 2885 2886 type_arg.push_back (type_style_arg); 2887 2888 m_arguments.push_back (type_arg); 2889 } 2890 2891 ~CommandObjectTypeCategoryList () 2892 { 2893 } 2894 2895 protected: 2896 bool 2897 DoExecute (Args& command, CommandReturnObject &result) 2898 { 2899 const size_t argc = command.GetArgumentCount(); 2900 RegularExpression* regex = NULL; 2901 2902 if (argc == 0) 2903 ; 2904 else if (argc == 1) 2905 regex = new RegularExpression(command.GetArgumentAtIndex(0)); 2906 else 2907 { 2908 result.AppendErrorWithFormat ("%s takes 0 or one arg.\n", m_cmd_name.c_str()); 2909 result.SetStatus(eReturnStatusFailed); 2910 return false; 2911 } 2912 2913 CommandObjectTypeCategoryList_CallbackParam param(&result, 2914 regex); 2915 2916 DataVisualization::Categories::LoopThrough(PerCategoryCallback, ¶m); 2917 2918 if (regex) 2919 delete regex; 2920 2921 result.SetStatus(eReturnStatusSuccessFinishResult); 2922 return result.Succeeded(); 2923 } 2924 2925 }; 2926 2927 //------------------------------------------------------------------------- 2928 // CommandObjectTypeFilterList 2929 //------------------------------------------------------------------------- 2930 2931 bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); 2932 bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); 2933 2934 class CommandObjectTypeFilterList; 2935 2936 struct CommandObjectTypeFilterList_LoopCallbackParam { 2937 CommandObjectTypeFilterList* self; 2938 CommandReturnObject* result; 2939 RegularExpression* regex; 2940 RegularExpression* cate_regex; 2941 CommandObjectTypeFilterList_LoopCallbackParam(CommandObjectTypeFilterList* S, CommandReturnObject* R, 2942 RegularExpression* X = NULL, 2943 RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {} 2944 }; 2945 2946 class CommandObjectTypeFilterList : public CommandObjectParsed 2947 { 2948 2949 class CommandOptions : public Options 2950 { 2951 public: 2952 2953 CommandOptions (CommandInterpreter &interpreter) : 2954 Options (interpreter) 2955 { 2956 } 2957 2958 virtual 2959 ~CommandOptions (){} 2960 2961 virtual Error 2962 SetOptionValue (uint32_t option_idx, const char *option_arg) 2963 { 2964 Error error; 2965 const int short_option = m_getopt_table[option_idx].val; 2966 2967 switch (short_option) 2968 { 2969 case 'w': 2970 m_category_regex = std::string(option_arg); 2971 break; 2972 default: 2973 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 2974 break; 2975 } 2976 2977 return error; 2978 } 2979 2980 void 2981 OptionParsingStarting () 2982 { 2983 m_category_regex = ""; 2984 } 2985 2986 const OptionDefinition* 2987 GetDefinitions () 2988 { 2989 return g_option_table; 2990 } 2991 2992 // Options table: Required for subclasses of Options. 2993 2994 static OptionDefinition g_option_table[]; 2995 2996 // Instance variables to hold the values for command options. 2997 2998 std::string m_category_regex; 2999 3000 }; 3001 3002 CommandOptions m_options; 3003 3004 virtual Options * 3005 GetOptions () 3006 { 3007 return &m_options; 3008 } 3009 3010 public: 3011 CommandObjectTypeFilterList (CommandInterpreter &interpreter) : 3012 CommandObjectParsed (interpreter, 3013 "type filter list", 3014 "Show a list of current filters.", 3015 NULL), 3016 m_options(interpreter) 3017 { 3018 CommandArgumentEntry type_arg; 3019 CommandArgumentData type_style_arg; 3020 3021 type_style_arg.arg_type = eArgTypeName; 3022 type_style_arg.arg_repetition = eArgRepeatOptional; 3023 3024 type_arg.push_back (type_style_arg); 3025 3026 m_arguments.push_back (type_arg); 3027 } 3028 3029 ~CommandObjectTypeFilterList () 3030 { 3031 } 3032 3033 protected: 3034 bool 3035 DoExecute (Args& command, CommandReturnObject &result) 3036 { 3037 const size_t argc = command.GetArgumentCount(); 3038 3039 CommandObjectTypeFilterList_LoopCallbackParam *param; 3040 RegularExpression* cate_regex = 3041 m_options.m_category_regex.empty() ? NULL : 3042 new RegularExpression(m_options.m_category_regex.c_str()); 3043 3044 if (argc == 1) 3045 { 3046 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); 3047 regex->Compile(command.GetArgumentAtIndex(0)); 3048 param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,regex,cate_regex); 3049 } 3050 else 3051 param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,NULL,cate_regex); 3052 3053 DataVisualization::Categories::LoopThrough(PerCategoryCallback,param); 3054 delete param; 3055 3056 if (cate_regex) 3057 delete cate_regex; 3058 3059 result.SetStatus(eReturnStatusSuccessFinishResult); 3060 return result.Succeeded(); 3061 } 3062 3063 private: 3064 3065 static bool 3066 PerCategoryCallback(void* param_vp, 3067 const lldb::TypeCategoryImplSP& cate) 3068 { 3069 3070 const char* cate_name = cate->GetName(); 3071 3072 CommandObjectTypeFilterList_LoopCallbackParam* param = 3073 (CommandObjectTypeFilterList_LoopCallbackParam*)param_vp; 3074 CommandReturnObject* result = param->result; 3075 3076 // if the category is disabled or empty and there is no regex, just skip it 3077 if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter) == 0) && param->cate_regex == NULL) 3078 return true; 3079 3080 // if we have a regex and this category does not match it, just skip it 3081 if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false) 3082 return true; 3083 3084 result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n", 3085 cate_name, 3086 (cate->IsEnabled() ? "enabled" : "disabled")); 3087 3088 cate->GetTypeFiltersContainer()->LoopThrough(CommandObjectTypeFilterList_LoopCallback, param_vp); 3089 3090 if (cate->GetRegexTypeFiltersContainer()->GetCount() > 0) 3091 { 3092 result->GetOutputStream().Printf("Regex-based filters (slower):\n"); 3093 cate->GetRegexTypeFiltersContainer()->LoopThrough(CommandObjectTypeFilterRXList_LoopCallback, param_vp); 3094 } 3095 3096 return true; 3097 } 3098 3099 bool 3100 LoopCallback (const char* type, 3101 const SyntheticChildren::SharedPointer& entry, 3102 RegularExpression* regex, 3103 CommandReturnObject *result) 3104 { 3105 if (regex == NULL || regex->Execute(type)) 3106 result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str()); 3107 return true; 3108 } 3109 3110 friend bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); 3111 friend bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); 3112 }; 3113 3114 bool 3115 CommandObjectTypeFilterList_LoopCallback (void* pt2self, 3116 ConstString type, 3117 const SyntheticChildren::SharedPointer& entry) 3118 { 3119 CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self; 3120 return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result); 3121 } 3122 3123 bool 3124 CommandObjectTypeFilterRXList_LoopCallback (void* pt2self, 3125 lldb::RegularExpressionSP regex, 3126 const SyntheticChildren::SharedPointer& entry) 3127 { 3128 CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self; 3129 return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); 3130 } 3131 3132 3133 OptionDefinition 3134 CommandObjectTypeFilterList::CommandOptions::g_option_table[] = 3135 { 3136 { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, 3137 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 3138 }; 3139 3140 #ifndef LLDB_DISABLE_PYTHON 3141 3142 //------------------------------------------------------------------------- 3143 // CommandObjectTypeSynthList 3144 //------------------------------------------------------------------------- 3145 3146 bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); 3147 bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); 3148 3149 class CommandObjectTypeSynthList; 3150 3151 struct CommandObjectTypeSynthList_LoopCallbackParam { 3152 CommandObjectTypeSynthList* self; 3153 CommandReturnObject* result; 3154 RegularExpression* regex; 3155 RegularExpression* cate_regex; 3156 CommandObjectTypeSynthList_LoopCallbackParam(CommandObjectTypeSynthList* S, CommandReturnObject* R, 3157 RegularExpression* X = NULL, 3158 RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {} 3159 }; 3160 3161 class CommandObjectTypeSynthList : public CommandObjectParsed 3162 { 3163 3164 class CommandOptions : public Options 3165 { 3166 public: 3167 3168 CommandOptions (CommandInterpreter &interpreter) : 3169 Options (interpreter) 3170 { 3171 } 3172 3173 virtual 3174 ~CommandOptions (){} 3175 3176 virtual Error 3177 SetOptionValue (uint32_t option_idx, const char *option_arg) 3178 { 3179 Error error; 3180 const int short_option = m_getopt_table[option_idx].val; 3181 3182 switch (short_option) 3183 { 3184 case 'w': 3185 m_category_regex = std::string(option_arg); 3186 break; 3187 default: 3188 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3189 break; 3190 } 3191 3192 return error; 3193 } 3194 3195 void 3196 OptionParsingStarting () 3197 { 3198 m_category_regex = ""; 3199 } 3200 3201 const OptionDefinition* 3202 GetDefinitions () 3203 { 3204 return g_option_table; 3205 } 3206 3207 // Options table: Required for subclasses of Options. 3208 3209 static OptionDefinition g_option_table[]; 3210 3211 // Instance variables to hold the values for command options. 3212 3213 std::string m_category_regex; 3214 3215 }; 3216 3217 CommandOptions m_options; 3218 3219 virtual Options * 3220 GetOptions () 3221 { 3222 return &m_options; 3223 } 3224 3225 public: 3226 CommandObjectTypeSynthList (CommandInterpreter &interpreter) : 3227 CommandObjectParsed (interpreter, 3228 "type synthetic list", 3229 "Show a list of current synthetic providers.", 3230 NULL), 3231 m_options(interpreter) 3232 { 3233 CommandArgumentEntry type_arg; 3234 CommandArgumentData type_style_arg; 3235 3236 type_style_arg.arg_type = eArgTypeName; 3237 type_style_arg.arg_repetition = eArgRepeatOptional; 3238 3239 type_arg.push_back (type_style_arg); 3240 3241 m_arguments.push_back (type_arg); 3242 } 3243 3244 ~CommandObjectTypeSynthList () 3245 { 3246 } 3247 3248 protected: 3249 bool 3250 DoExecute (Args& command, CommandReturnObject &result) 3251 { 3252 const size_t argc = command.GetArgumentCount(); 3253 3254 CommandObjectTypeSynthList_LoopCallbackParam *param; 3255 RegularExpression* cate_regex = 3256 m_options.m_category_regex.empty() ? NULL : 3257 new RegularExpression(m_options.m_category_regex.c_str()); 3258 3259 if (argc == 1) 3260 { 3261 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); 3262 regex->Compile(command.GetArgumentAtIndex(0)); 3263 param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,regex,cate_regex); 3264 } 3265 else 3266 param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,NULL,cate_regex); 3267 3268 DataVisualization::Categories::LoopThrough(PerCategoryCallback,param); 3269 delete param; 3270 3271 if (cate_regex) 3272 delete cate_regex; 3273 3274 result.SetStatus(eReturnStatusSuccessFinishResult); 3275 return result.Succeeded(); 3276 } 3277 3278 private: 3279 3280 static bool 3281 PerCategoryCallback(void* param_vp, 3282 const lldb::TypeCategoryImplSP& cate) 3283 { 3284 3285 CommandObjectTypeSynthList_LoopCallbackParam* param = 3286 (CommandObjectTypeSynthList_LoopCallbackParam*)param_vp; 3287 CommandReturnObject* result = param->result; 3288 3289 const char* cate_name = cate->GetName(); 3290 3291 // if the category is disabled or empty and there is no regex, just skip it 3292 if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth) == 0) && param->cate_regex == NULL) 3293 return true; 3294 3295 // if we have a regex and this category does not match it, just skip it 3296 if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false) 3297 return true; 3298 3299 result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n", 3300 cate_name, 3301 (cate->IsEnabled() ? "enabled" : "disabled")); 3302 3303 cate->GetTypeSyntheticsContainer()->LoopThrough(CommandObjectTypeSynthList_LoopCallback, param_vp); 3304 3305 if (cate->GetRegexTypeSyntheticsContainer()->GetCount() > 0) 3306 { 3307 result->GetOutputStream().Printf("Regex-based synthetic providers (slower):\n"); 3308 cate->GetRegexTypeSyntheticsContainer()->LoopThrough(CommandObjectTypeSynthRXList_LoopCallback, param_vp); 3309 } 3310 3311 return true; 3312 } 3313 3314 bool 3315 LoopCallback (const char* type, 3316 const SyntheticChildren::SharedPointer& entry, 3317 RegularExpression* regex, 3318 CommandReturnObject *result) 3319 { 3320 if (regex == NULL || regex->Execute(type)) 3321 result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str()); 3322 return true; 3323 } 3324 3325 friend bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); 3326 friend bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); 3327 }; 3328 3329 bool 3330 CommandObjectTypeSynthList_LoopCallback (void* pt2self, 3331 ConstString type, 3332 const SyntheticChildren::SharedPointer& entry) 3333 { 3334 CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self; 3335 return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result); 3336 } 3337 3338 bool 3339 CommandObjectTypeSynthRXList_LoopCallback (void* pt2self, 3340 lldb::RegularExpressionSP regex, 3341 const SyntheticChildren::SharedPointer& entry) 3342 { 3343 CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self; 3344 return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); 3345 } 3346 3347 3348 OptionDefinition 3349 CommandObjectTypeSynthList::CommandOptions::g_option_table[] = 3350 { 3351 { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, 3352 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 3353 }; 3354 3355 #endif // #ifndef LLDB_DISABLE_PYTHON 3356 //------------------------------------------------------------------------- 3357 // CommandObjectTypeFilterDelete 3358 //------------------------------------------------------------------------- 3359 3360 class CommandObjectTypeFilterDelete : public CommandObjectParsed 3361 { 3362 private: 3363 class CommandOptions : public Options 3364 { 3365 public: 3366 3367 CommandOptions (CommandInterpreter &interpreter) : 3368 Options (interpreter) 3369 { 3370 } 3371 3372 virtual 3373 ~CommandOptions (){} 3374 3375 virtual Error 3376 SetOptionValue (uint32_t option_idx, const char *option_arg) 3377 { 3378 Error error; 3379 const int short_option = m_getopt_table[option_idx].val; 3380 3381 switch (short_option) 3382 { 3383 case 'a': 3384 m_delete_all = true; 3385 break; 3386 case 'w': 3387 m_category = std::string(option_arg); 3388 break; 3389 default: 3390 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3391 break; 3392 } 3393 3394 return error; 3395 } 3396 3397 void 3398 OptionParsingStarting () 3399 { 3400 m_delete_all = false; 3401 m_category = "default"; 3402 } 3403 3404 const OptionDefinition* 3405 GetDefinitions () 3406 { 3407 return g_option_table; 3408 } 3409 3410 // Options table: Required for subclasses of Options. 3411 3412 static OptionDefinition g_option_table[]; 3413 3414 // Instance variables to hold the values for command options. 3415 3416 bool m_delete_all; 3417 std::string m_category; 3418 3419 }; 3420 3421 CommandOptions m_options; 3422 3423 virtual Options * 3424 GetOptions () 3425 { 3426 return &m_options; 3427 } 3428 3429 static bool 3430 PerCategoryCallback(void* param, 3431 const lldb::TypeCategoryImplSP& cate) 3432 { 3433 ConstString *name = (ConstString*)param; 3434 return cate->Delete(*name, eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter); 3435 } 3436 3437 public: 3438 CommandObjectTypeFilterDelete (CommandInterpreter &interpreter) : 3439 CommandObjectParsed (interpreter, 3440 "type filter delete", 3441 "Delete an existing filter for a type.", 3442 NULL), 3443 m_options(interpreter) 3444 { 3445 CommandArgumentEntry type_arg; 3446 CommandArgumentData type_style_arg; 3447 3448 type_style_arg.arg_type = eArgTypeName; 3449 type_style_arg.arg_repetition = eArgRepeatPlain; 3450 3451 type_arg.push_back (type_style_arg); 3452 3453 m_arguments.push_back (type_arg); 3454 3455 } 3456 3457 ~CommandObjectTypeFilterDelete () 3458 { 3459 } 3460 3461 protected: 3462 bool 3463 DoExecute (Args& command, CommandReturnObject &result) 3464 { 3465 const size_t argc = command.GetArgumentCount(); 3466 3467 if (argc != 1) 3468 { 3469 result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); 3470 result.SetStatus(eReturnStatusFailed); 3471 return false; 3472 } 3473 3474 const char* typeA = command.GetArgumentAtIndex(0); 3475 ConstString typeCS(typeA); 3476 3477 if (!typeCS) 3478 { 3479 result.AppendError("empty typenames not allowed"); 3480 result.SetStatus(eReturnStatusFailed); 3481 return false; 3482 } 3483 3484 if (m_options.m_delete_all) 3485 { 3486 DataVisualization::Categories::LoopThrough(PerCategoryCallback, (void*)&typeCS); 3487 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3488 return result.Succeeded(); 3489 } 3490 3491 lldb::TypeCategoryImplSP category; 3492 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 3493 3494 bool delete_category = category->GetTypeFiltersContainer()->Delete(typeCS); 3495 delete_category = category->GetRegexTypeFiltersContainer()->Delete(typeCS) || delete_category; 3496 3497 if (delete_category) 3498 { 3499 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3500 return result.Succeeded(); 3501 } 3502 else 3503 { 3504 result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA); 3505 result.SetStatus(eReturnStatusFailed); 3506 return false; 3507 } 3508 3509 } 3510 }; 3511 3512 OptionDefinition 3513 CommandObjectTypeFilterDelete::CommandOptions::g_option_table[] = 3514 { 3515 { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Delete from every category."}, 3516 { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Delete from given category."}, 3517 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 3518 }; 3519 3520 #ifndef LLDB_DISABLE_PYTHON 3521 3522 //------------------------------------------------------------------------- 3523 // CommandObjectTypeSynthDelete 3524 //------------------------------------------------------------------------- 3525 3526 class CommandObjectTypeSynthDelete : public CommandObjectParsed 3527 { 3528 private: 3529 class CommandOptions : public Options 3530 { 3531 public: 3532 3533 CommandOptions (CommandInterpreter &interpreter) : 3534 Options (interpreter) 3535 { 3536 } 3537 3538 virtual 3539 ~CommandOptions (){} 3540 3541 virtual Error 3542 SetOptionValue (uint32_t option_idx, const char *option_arg) 3543 { 3544 Error error; 3545 const int short_option = m_getopt_table[option_idx].val; 3546 3547 switch (short_option) 3548 { 3549 case 'a': 3550 m_delete_all = true; 3551 break; 3552 case 'w': 3553 m_category = std::string(option_arg); 3554 break; 3555 default: 3556 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3557 break; 3558 } 3559 3560 return error; 3561 } 3562 3563 void 3564 OptionParsingStarting () 3565 { 3566 m_delete_all = false; 3567 m_category = "default"; 3568 } 3569 3570 const OptionDefinition* 3571 GetDefinitions () 3572 { 3573 return g_option_table; 3574 } 3575 3576 // Options table: Required for subclasses of Options. 3577 3578 static OptionDefinition g_option_table[]; 3579 3580 // Instance variables to hold the values for command options. 3581 3582 bool m_delete_all; 3583 std::string m_category; 3584 3585 }; 3586 3587 CommandOptions m_options; 3588 3589 virtual Options * 3590 GetOptions () 3591 { 3592 return &m_options; 3593 } 3594 3595 static bool 3596 PerCategoryCallback(void* param, 3597 const lldb::TypeCategoryImplSP& cate) 3598 { 3599 ConstString* name = (ConstString*)param; 3600 return cate->Delete(*name, eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth); 3601 } 3602 3603 public: 3604 CommandObjectTypeSynthDelete (CommandInterpreter &interpreter) : 3605 CommandObjectParsed (interpreter, 3606 "type synthetic delete", 3607 "Delete an existing synthetic provider for a type.", 3608 NULL), 3609 m_options(interpreter) 3610 { 3611 CommandArgumentEntry type_arg; 3612 CommandArgumentData type_style_arg; 3613 3614 type_style_arg.arg_type = eArgTypeName; 3615 type_style_arg.arg_repetition = eArgRepeatPlain; 3616 3617 type_arg.push_back (type_style_arg); 3618 3619 m_arguments.push_back (type_arg); 3620 3621 } 3622 3623 ~CommandObjectTypeSynthDelete () 3624 { 3625 } 3626 3627 protected: 3628 bool 3629 DoExecute (Args& command, CommandReturnObject &result) 3630 { 3631 const size_t argc = command.GetArgumentCount(); 3632 3633 if (argc != 1) 3634 { 3635 result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); 3636 result.SetStatus(eReturnStatusFailed); 3637 return false; 3638 } 3639 3640 const char* typeA = command.GetArgumentAtIndex(0); 3641 ConstString typeCS(typeA); 3642 3643 if (!typeCS) 3644 { 3645 result.AppendError("empty typenames not allowed"); 3646 result.SetStatus(eReturnStatusFailed); 3647 return false; 3648 } 3649 3650 if (m_options.m_delete_all) 3651 { 3652 DataVisualization::Categories::LoopThrough(PerCategoryCallback, (void*)&typeCS); 3653 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3654 return result.Succeeded(); 3655 } 3656 3657 lldb::TypeCategoryImplSP category; 3658 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 3659 3660 bool delete_category = category->GetTypeSyntheticsContainer()->Delete(typeCS); 3661 delete_category = category->GetRegexTypeSyntheticsContainer()->Delete(typeCS) || delete_category; 3662 3663 if (delete_category) 3664 { 3665 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3666 return result.Succeeded(); 3667 } 3668 else 3669 { 3670 result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA); 3671 result.SetStatus(eReturnStatusFailed); 3672 return false; 3673 } 3674 3675 } 3676 }; 3677 3678 OptionDefinition 3679 CommandObjectTypeSynthDelete::CommandOptions::g_option_table[] = 3680 { 3681 { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Delete from every category."}, 3682 { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Delete from given category."}, 3683 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 3684 }; 3685 3686 #endif // #ifndef LLDB_DISABLE_PYTHON 3687 3688 //------------------------------------------------------------------------- 3689 // CommandObjectTypeFilterClear 3690 //------------------------------------------------------------------------- 3691 3692 class CommandObjectTypeFilterClear : public CommandObjectParsed 3693 { 3694 private: 3695 3696 class CommandOptions : public Options 3697 { 3698 public: 3699 3700 CommandOptions (CommandInterpreter &interpreter) : 3701 Options (interpreter) 3702 { 3703 } 3704 3705 virtual 3706 ~CommandOptions (){} 3707 3708 virtual Error 3709 SetOptionValue (uint32_t option_idx, const char *option_arg) 3710 { 3711 Error error; 3712 const int short_option = m_getopt_table[option_idx].val; 3713 3714 switch (short_option) 3715 { 3716 case 'a': 3717 m_delete_all = true; 3718 break; 3719 default: 3720 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3721 break; 3722 } 3723 3724 return error; 3725 } 3726 3727 void 3728 OptionParsingStarting () 3729 { 3730 m_delete_all = false; 3731 } 3732 3733 const OptionDefinition* 3734 GetDefinitions () 3735 { 3736 return g_option_table; 3737 } 3738 3739 // Options table: Required for subclasses of Options. 3740 3741 static OptionDefinition g_option_table[]; 3742 3743 // Instance variables to hold the values for command options. 3744 3745 bool m_delete_all; 3746 bool m_delete_named; 3747 }; 3748 3749 CommandOptions m_options; 3750 3751 virtual Options * 3752 GetOptions () 3753 { 3754 return &m_options; 3755 } 3756 3757 static bool 3758 PerCategoryCallback(void* param, 3759 const lldb::TypeCategoryImplSP& cate) 3760 { 3761 cate->Clear(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter); 3762 return true; 3763 3764 } 3765 3766 public: 3767 CommandObjectTypeFilterClear (CommandInterpreter &interpreter) : 3768 CommandObjectParsed (interpreter, 3769 "type filter clear", 3770 "Delete all existing filters.", 3771 NULL), 3772 m_options(interpreter) 3773 { 3774 } 3775 3776 ~CommandObjectTypeFilterClear () 3777 { 3778 } 3779 3780 protected: 3781 bool 3782 DoExecute (Args& command, CommandReturnObject &result) 3783 { 3784 3785 if (m_options.m_delete_all) 3786 DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL); 3787 3788 else 3789 { 3790 lldb::TypeCategoryImplSP category; 3791 if (command.GetArgumentCount() > 0) 3792 { 3793 const char* cat_name = command.GetArgumentAtIndex(0); 3794 ConstString cat_nameCS(cat_name); 3795 DataVisualization::Categories::GetCategory(cat_nameCS, category); 3796 } 3797 else 3798 DataVisualization::Categories::GetCategory(ConstString(NULL), category); 3799 category->GetTypeFiltersContainer()->Clear(); 3800 category->GetRegexTypeFiltersContainer()->Clear(); 3801 } 3802 3803 result.SetStatus(eReturnStatusSuccessFinishResult); 3804 return result.Succeeded(); 3805 } 3806 3807 }; 3808 3809 OptionDefinition 3810 CommandObjectTypeFilterClear::CommandOptions::g_option_table[] = 3811 { 3812 { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Clear every category."}, 3813 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 3814 }; 3815 3816 #ifndef LLDB_DISABLE_PYTHON 3817 //------------------------------------------------------------------------- 3818 // CommandObjectTypeSynthClear 3819 //------------------------------------------------------------------------- 3820 3821 class CommandObjectTypeSynthClear : public CommandObjectParsed 3822 { 3823 private: 3824 3825 class CommandOptions : public Options 3826 { 3827 public: 3828 3829 CommandOptions (CommandInterpreter &interpreter) : 3830 Options (interpreter) 3831 { 3832 } 3833 3834 virtual 3835 ~CommandOptions (){} 3836 3837 virtual Error 3838 SetOptionValue (uint32_t option_idx, const char *option_arg) 3839 { 3840 Error error; 3841 const int short_option = m_getopt_table[option_idx].val; 3842 3843 switch (short_option) 3844 { 3845 case 'a': 3846 m_delete_all = true; 3847 break; 3848 default: 3849 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 3850 break; 3851 } 3852 3853 return error; 3854 } 3855 3856 void 3857 OptionParsingStarting () 3858 { 3859 m_delete_all = false; 3860 } 3861 3862 const OptionDefinition* 3863 GetDefinitions () 3864 { 3865 return g_option_table; 3866 } 3867 3868 // Options table: Required for subclasses of Options. 3869 3870 static OptionDefinition g_option_table[]; 3871 3872 // Instance variables to hold the values for command options. 3873 3874 bool m_delete_all; 3875 bool m_delete_named; 3876 }; 3877 3878 CommandOptions m_options; 3879 3880 virtual Options * 3881 GetOptions () 3882 { 3883 return &m_options; 3884 } 3885 3886 static bool 3887 PerCategoryCallback(void* param, 3888 const lldb::TypeCategoryImplSP& cate) 3889 { 3890 cate->Clear(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth); 3891 return true; 3892 3893 } 3894 3895 public: 3896 CommandObjectTypeSynthClear (CommandInterpreter &interpreter) : 3897 CommandObjectParsed (interpreter, 3898 "type synthetic clear", 3899 "Delete all existing synthetic providers.", 3900 NULL), 3901 m_options(interpreter) 3902 { 3903 } 3904 3905 ~CommandObjectTypeSynthClear () 3906 { 3907 } 3908 3909 protected: 3910 bool 3911 DoExecute (Args& command, CommandReturnObject &result) 3912 { 3913 3914 if (m_options.m_delete_all) 3915 DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL); 3916 3917 else 3918 { 3919 lldb::TypeCategoryImplSP category; 3920 if (command.GetArgumentCount() > 0) 3921 { 3922 const char* cat_name = command.GetArgumentAtIndex(0); 3923 ConstString cat_nameCS(cat_name); 3924 DataVisualization::Categories::GetCategory(cat_nameCS, category); 3925 } 3926 else 3927 DataVisualization::Categories::GetCategory(ConstString(NULL), category); 3928 category->GetTypeSyntheticsContainer()->Clear(); 3929 category->GetRegexTypeSyntheticsContainer()->Clear(); 3930 } 3931 3932 result.SetStatus(eReturnStatusSuccessFinishResult); 3933 return result.Succeeded(); 3934 } 3935 3936 }; 3937 3938 OptionDefinition 3939 CommandObjectTypeSynthClear::CommandOptions::g_option_table[] = 3940 { 3941 { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Clear every category."}, 3942 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 3943 }; 3944 3945 3946 bool 3947 CommandObjectTypeSynthAdd::Execute_HandwritePython (Args& command, CommandReturnObject &result) 3948 { 3949 SynthAddOptions *options = new SynthAddOptions ( m_options.m_skip_pointers, 3950 m_options.m_skip_references, 3951 m_options.m_cascade, 3952 m_options.m_regex, 3953 m_options.m_category); 3954 3955 const size_t argc = command.GetArgumentCount(); 3956 3957 for (size_t i = 0; i < argc; i++) 3958 { 3959 const char* typeA = command.GetArgumentAtIndex(i); 3960 if (typeA && *typeA) 3961 options->m_target_types << typeA; 3962 else 3963 { 3964 result.AppendError("empty typenames not allowed"); 3965 result.SetStatus(eReturnStatusFailed); 3966 return false; 3967 } 3968 } 3969 3970 m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt 3971 *this, // IOHandlerDelegate 3972 true, // Run IOHandler in async mode 3973 options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions 3974 result.SetStatus(eReturnStatusSuccessFinishNoResult); 3975 return result.Succeeded(); 3976 } 3977 3978 bool 3979 CommandObjectTypeSynthAdd::Execute_PythonClass (Args& command, CommandReturnObject &result) 3980 { 3981 const size_t argc = command.GetArgumentCount(); 3982 3983 if (argc < 1) 3984 { 3985 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); 3986 result.SetStatus(eReturnStatusFailed); 3987 return false; 3988 } 3989 3990 if (m_options.m_class_name.empty() && !m_options.m_input_python) 3991 { 3992 result.AppendErrorWithFormat ("%s needs either a Python class name or -P to directly input Python code.\n", m_cmd_name.c_str()); 3993 result.SetStatus(eReturnStatusFailed); 3994 return false; 3995 } 3996 3997 SyntheticChildrenSP entry; 3998 3999 ScriptedSyntheticChildren* impl = new ScriptedSyntheticChildren(SyntheticChildren::Flags(). 4000 SetCascades(m_options.m_cascade). 4001 SetSkipPointers(m_options.m_skip_pointers). 4002 SetSkipReferences(m_options.m_skip_references), 4003 m_options.m_class_name.c_str()); 4004 4005 entry.reset(impl); 4006 4007 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 4008 4009 if (interpreter && interpreter->CheckObjectExists(impl->GetPythonClassName()) == false) 4010 result.AppendWarning("The provided class does not exist - please define it before attempting to use this synthetic provider"); 4011 4012 // now I have a valid provider, let's add it to every type 4013 4014 lldb::TypeCategoryImplSP category; 4015 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 4016 4017 Error error; 4018 4019 for (size_t i = 0; i < argc; i++) 4020 { 4021 const char* typeA = command.GetArgumentAtIndex(i); 4022 ConstString typeCS(typeA); 4023 if (typeCS) 4024 { 4025 if (!AddSynth(typeCS, 4026 entry, 4027 m_options.m_regex ? eRegexSynth : eRegularSynth, 4028 m_options.m_category, 4029 &error)) 4030 { 4031 result.AppendError(error.AsCString()); 4032 result.SetStatus(eReturnStatusFailed); 4033 return false; 4034 } 4035 } 4036 else 4037 { 4038 result.AppendError("empty typenames not allowed"); 4039 result.SetStatus(eReturnStatusFailed); 4040 return false; 4041 } 4042 } 4043 4044 result.SetStatus(eReturnStatusSuccessFinishNoResult); 4045 return result.Succeeded(); 4046 } 4047 4048 CommandObjectTypeSynthAdd::CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) : 4049 CommandObjectParsed (interpreter, 4050 "type synthetic add", 4051 "Add a new synthetic provider for a type.", 4052 NULL), 4053 IOHandlerDelegateMultiline ("DONE"), 4054 m_options (interpreter) 4055 { 4056 CommandArgumentEntry type_arg; 4057 CommandArgumentData type_style_arg; 4058 4059 type_style_arg.arg_type = eArgTypeName; 4060 type_style_arg.arg_repetition = eArgRepeatPlus; 4061 4062 type_arg.push_back (type_style_arg); 4063 4064 m_arguments.push_back (type_arg); 4065 4066 } 4067 4068 bool 4069 CommandObjectTypeSynthAdd::AddSynth(ConstString type_name, 4070 SyntheticChildrenSP entry, 4071 SynthFormatType type, 4072 std::string category_name, 4073 Error* error) 4074 { 4075 lldb::TypeCategoryImplSP category; 4076 DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category); 4077 4078 if (type == eRegularSynth) 4079 { 4080 if (FixArrayTypeNameWithRegex (type_name)) 4081 type = eRegexSynth; 4082 } 4083 4084 if (category->AnyMatches(type_name, 4085 eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter, 4086 false)) 4087 { 4088 if (error) 4089 error->SetErrorStringWithFormat("cannot add synthetic for type %s when filter is defined in same category!", type_name.AsCString()); 4090 return false; 4091 } 4092 4093 if (type == eRegexSynth) 4094 { 4095 RegularExpressionSP typeRX(new RegularExpression()); 4096 if (!typeRX->Compile(type_name.GetCString())) 4097 { 4098 if (error) 4099 error->SetErrorString("regex format error (maybe this is not really a regex?)"); 4100 return false; 4101 } 4102 4103 category->GetRegexTypeSyntheticsContainer()->Delete(type_name); 4104 category->GetRegexTypeSyntheticsContainer()->Add(typeRX, entry); 4105 4106 return true; 4107 } 4108 else 4109 { 4110 category->GetTypeSyntheticsContainer()->Add(type_name, entry); 4111 return true; 4112 } 4113 } 4114 4115 OptionDefinition 4116 CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] = 4117 { 4118 { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, 4119 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, 4120 { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for references-to-tNULL, ype objects."}, 4121 { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, 4122 { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass, "Use this Python class to produce synthetic children."}, 4123 { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument,NULL, NULL, 0, eArgTypeNone, "Type Python code to generate a class that NULL, provides synthetic children."}, 4124 { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, 4125 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 4126 }; 4127 4128 #endif // #ifndef LLDB_DISABLE_PYTHON 4129 4130 class CommandObjectTypeFilterAdd : public CommandObjectParsed 4131 { 4132 4133 private: 4134 4135 class CommandOptions : public Options 4136 { 4137 typedef std::vector<std::string> option_vector; 4138 public: 4139 4140 CommandOptions (CommandInterpreter &interpreter) : 4141 Options (interpreter) 4142 { 4143 } 4144 4145 virtual 4146 ~CommandOptions (){} 4147 4148 virtual Error 4149 SetOptionValue (uint32_t option_idx, const char *option_arg) 4150 { 4151 Error error; 4152 const int short_option = m_getopt_table[option_idx].val; 4153 bool success; 4154 4155 switch (short_option) 4156 { 4157 case 'C': 4158 m_cascade = Args::StringToBoolean(option_arg, true, &success); 4159 if (!success) 4160 error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg); 4161 break; 4162 case 'c': 4163 m_expr_paths.push_back(option_arg); 4164 has_child_list = true; 4165 break; 4166 case 'p': 4167 m_skip_pointers = true; 4168 break; 4169 case 'r': 4170 m_skip_references = true; 4171 break; 4172 case 'w': 4173 m_category = std::string(option_arg); 4174 break; 4175 case 'x': 4176 m_regex = true; 4177 break; 4178 default: 4179 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 4180 break; 4181 } 4182 4183 return error; 4184 } 4185 4186 void 4187 OptionParsingStarting () 4188 { 4189 m_cascade = true; 4190 m_skip_pointers = false; 4191 m_skip_references = false; 4192 m_category = "default"; 4193 m_expr_paths.clear(); 4194 has_child_list = false; 4195 m_regex = false; 4196 } 4197 4198 const OptionDefinition* 4199 GetDefinitions () 4200 { 4201 return g_option_table; 4202 } 4203 4204 // Options table: Required for subclasses of Options. 4205 4206 static OptionDefinition g_option_table[]; 4207 4208 // Instance variables to hold the values for command options. 4209 4210 bool m_cascade; 4211 bool m_skip_references; 4212 bool m_skip_pointers; 4213 bool m_input_python; 4214 option_vector m_expr_paths; 4215 std::string m_category; 4216 4217 bool has_child_list; 4218 4219 bool m_regex; 4220 4221 typedef option_vector::iterator ExpressionPathsIterator; 4222 }; 4223 4224 CommandOptions m_options; 4225 4226 virtual Options * 4227 GetOptions () 4228 { 4229 return &m_options; 4230 } 4231 4232 enum FilterFormatType 4233 { 4234 eRegularFilter, 4235 eRegexFilter 4236 }; 4237 4238 bool 4239 AddFilter(ConstString type_name, 4240 SyntheticChildrenSP entry, 4241 FilterFormatType type, 4242 std::string category_name, 4243 Error* error) 4244 { 4245 lldb::TypeCategoryImplSP category; 4246 DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category); 4247 4248 if (type == eRegularFilter) 4249 { 4250 if (FixArrayTypeNameWithRegex (type_name)) 4251 type = eRegexFilter; 4252 } 4253 4254 if (category->AnyMatches(type_name, 4255 eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth, 4256 false)) 4257 { 4258 if (error) 4259 error->SetErrorStringWithFormat("cannot add filter for type %s when synthetic is defined in same category!", type_name.AsCString()); 4260 return false; 4261 } 4262 4263 if (type == eRegexFilter) 4264 { 4265 RegularExpressionSP typeRX(new RegularExpression()); 4266 if (!typeRX->Compile(type_name.GetCString())) 4267 { 4268 if (error) 4269 error->SetErrorString("regex format error (maybe this is not really a regex?)"); 4270 return false; 4271 } 4272 4273 category->GetRegexTypeFiltersContainer()->Delete(type_name); 4274 category->GetRegexTypeFiltersContainer()->Add(typeRX, entry); 4275 4276 return true; 4277 } 4278 else 4279 { 4280 category->GetTypeFiltersContainer()->Add(type_name, entry); 4281 return true; 4282 } 4283 } 4284 4285 4286 public: 4287 4288 CommandObjectTypeFilterAdd (CommandInterpreter &interpreter) : 4289 CommandObjectParsed (interpreter, 4290 "type filter add", 4291 "Add a new filter for a type.", 4292 NULL), 4293 m_options (interpreter) 4294 { 4295 CommandArgumentEntry type_arg; 4296 CommandArgumentData type_style_arg; 4297 4298 type_style_arg.arg_type = eArgTypeName; 4299 type_style_arg.arg_repetition = eArgRepeatPlus; 4300 4301 type_arg.push_back (type_style_arg); 4302 4303 m_arguments.push_back (type_arg); 4304 4305 SetHelpLong( 4306 R"( 4307 The following examples of 'type filter add' refer to this code snippet for context: 4308 4309 class Foo { 4310 int a; 4311 int b; 4312 int c; 4313 int d; 4314 int e; 4315 int f; 4316 int g; 4317 int h; 4318 int i; 4319 } 4320 Foo my_foo; 4321 4322 Adding a simple filter: 4323 4324 (lldb) type filter add --child a --child g Foo 4325 (lldb) frame variable my_foo 4326 4327 )" "Produces output where only a and g are displayed. Other children of my_foo \ 4328 (b, c, d, e, f, h and i) are available by asking for them explicitly:" R"( 4329 4330 (lldb) frame variable my_foo.b my_foo.c my_foo.i 4331 4332 )" "The formatting option --raw on frame variable bypasses the filter, showing \ 4333 all children of my_foo as if no filter was defined:" R"( 4334 4335 (lldb) frame variable my_foo --raw)" 4336 ); 4337 } 4338 4339 ~CommandObjectTypeFilterAdd () 4340 { 4341 } 4342 4343 protected: 4344 bool 4345 DoExecute (Args& command, CommandReturnObject &result) 4346 { 4347 const size_t argc = command.GetArgumentCount(); 4348 4349 if (argc < 1) 4350 { 4351 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); 4352 result.SetStatus(eReturnStatusFailed); 4353 return false; 4354 } 4355 4356 if (m_options.m_expr_paths.size() == 0) 4357 { 4358 result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str()); 4359 result.SetStatus(eReturnStatusFailed); 4360 return false; 4361 } 4362 4363 SyntheticChildrenSP entry; 4364 4365 TypeFilterImpl* impl = new TypeFilterImpl(SyntheticChildren::Flags().SetCascades(m_options.m_cascade). 4366 SetSkipPointers(m_options.m_skip_pointers). 4367 SetSkipReferences(m_options.m_skip_references)); 4368 4369 entry.reset(impl); 4370 4371 // go through the expression paths 4372 CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end(); 4373 4374 for (begin = m_options.m_expr_paths.begin(); begin != end; begin++) 4375 impl->AddExpressionPath(*begin); 4376 4377 4378 // now I have a valid provider, let's add it to every type 4379 4380 lldb::TypeCategoryImplSP category; 4381 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); 4382 4383 Error error; 4384 4385 WarnOnPotentialUnquotedUnsignedType(command, result); 4386 4387 for (size_t i = 0; i < argc; i++) 4388 { 4389 const char* typeA = command.GetArgumentAtIndex(i); 4390 ConstString typeCS(typeA); 4391 if (typeCS) 4392 { 4393 if (!AddFilter(typeCS, 4394 entry, 4395 m_options.m_regex ? eRegexFilter : eRegularFilter, 4396 m_options.m_category, 4397 &error)) 4398 { 4399 result.AppendError(error.AsCString()); 4400 result.SetStatus(eReturnStatusFailed); 4401 return false; 4402 } 4403 } 4404 else 4405 { 4406 result.AppendError("empty typenames not allowed"); 4407 result.SetStatus(eReturnStatusFailed); 4408 return false; 4409 } 4410 } 4411 4412 result.SetStatus(eReturnStatusSuccessFinishNoResult); 4413 return result.Succeeded(); 4414 } 4415 4416 }; 4417 4418 OptionDefinition 4419 CommandObjectTypeFilterAdd::CommandOptions::g_option_table[] = 4420 { 4421 { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, 4422 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, 4423 { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, 4424 { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, 4425 { LLDB_OPT_SET_ALL, false, "child", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpressionPath, "Include this expression path in the synthetic view."}, 4426 { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, 4427 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 4428 }; 4429 4430 template <typename FormatterType> 4431 class CommandObjectFormatterInfo : public CommandObjectRaw 4432 { 4433 public: 4434 typedef std::function<typename FormatterType::SharedPointer(ValueObject&)> DiscoveryFunction; 4435 CommandObjectFormatterInfo (CommandInterpreter &interpreter, 4436 const char* formatter_name, 4437 DiscoveryFunction discovery_func) : 4438 CommandObjectRaw(interpreter, 4439 nullptr, 4440 nullptr, 4441 nullptr, 4442 eCommandRequiresFrame), 4443 m_formatter_name(formatter_name ? formatter_name : ""), 4444 m_discovery_function(discovery_func) 4445 { 4446 StreamString name; 4447 name.Printf("type %s info", formatter_name); 4448 SetCommandName(name.GetData()); 4449 StreamString help; 4450 help.Printf("This command evaluates the provided expression and shows which %s is applied to the resulting value (if any).", formatter_name); 4451 SetHelp(help.GetData()); 4452 StreamString syntax; 4453 syntax.Printf("type %s info <expr>", formatter_name); 4454 SetSyntax(syntax.GetData()); 4455 } 4456 4457 virtual 4458 ~CommandObjectFormatterInfo () 4459 { 4460 } 4461 4462 protected: 4463 virtual bool 4464 DoExecute (const char *command, CommandReturnObject &result) 4465 { 4466 auto target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); 4467 auto frame_sp = target_sp->GetProcessSP()->GetThreadList().GetSelectedThread()->GetSelectedFrame(); 4468 ValueObjectSP result_valobj_sp; 4469 EvaluateExpressionOptions options; 4470 lldb::ExpressionResults expr_result = target_sp->EvaluateExpression(command, frame_sp.get(), result_valobj_sp, options); 4471 if (expr_result == eExpressionCompleted && result_valobj_sp) 4472 { 4473 result_valobj_sp = result_valobj_sp->GetQualifiedRepresentationIfAvailable(target_sp->GetPreferDynamicValue(), target_sp->GetEnableSyntheticValue()); 4474 typename FormatterType::SharedPointer formatter_sp = m_discovery_function(*result_valobj_sp); 4475 if (formatter_sp) 4476 { 4477 std::string description(formatter_sp->GetDescription()); 4478 result.AppendMessageWithFormat("%s applied to (%s) %s is: %s\n", 4479 m_formatter_name.c_str(), 4480 result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"), 4481 command, 4482 description.c_str()); 4483 result.SetStatus(lldb::eReturnStatusSuccessFinishResult); 4484 } 4485 else 4486 { 4487 result.AppendMessageWithFormat("no %s applies to (%s) %s\n", 4488 m_formatter_name.c_str(), 4489 result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"), 4490 command); 4491 result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult); 4492 } 4493 return true; 4494 } 4495 else 4496 { 4497 result.AppendError("failed to evaluate expression"); 4498 result.SetStatus(lldb::eReturnStatusFailed); 4499 return false; 4500 } 4501 } 4502 4503 private: 4504 std::string m_formatter_name; 4505 DiscoveryFunction m_discovery_function; 4506 }; 4507 4508 class CommandObjectTypeFormat : public CommandObjectMultiword 4509 { 4510 public: 4511 CommandObjectTypeFormat (CommandInterpreter &interpreter) : 4512 CommandObjectMultiword (interpreter, 4513 "type format", 4514 "A set of commands for editing variable value display options", 4515 "type format [<sub-command-options>] ") 4516 { 4517 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFormatAdd (interpreter))); 4518 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFormatClear (interpreter))); 4519 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFormatDelete (interpreter))); 4520 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFormatList (interpreter))); 4521 LoadSubCommand ("info", CommandObjectSP (new CommandObjectFormatterInfo<TypeFormatImpl>(interpreter, 4522 "format", 4523 [](ValueObject& valobj) -> TypeFormatImpl::SharedPointer { 4524 return valobj.GetValueFormat(); 4525 }))); 4526 } 4527 4528 4529 ~CommandObjectTypeFormat () 4530 { 4531 } 4532 }; 4533 4534 #ifndef LLDB_DISABLE_PYTHON 4535 4536 class CommandObjectTypeSynth : public CommandObjectMultiword 4537 { 4538 public: 4539 CommandObjectTypeSynth (CommandInterpreter &interpreter) : 4540 CommandObjectMultiword (interpreter, 4541 "type synthetic", 4542 "A set of commands for operating on synthetic type representations", 4543 "type synthetic [<sub-command-options>] ") 4544 { 4545 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSynthAdd (interpreter))); 4546 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSynthClear (interpreter))); 4547 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSynthDelete (interpreter))); 4548 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSynthList (interpreter))); 4549 LoadSubCommand ("info", CommandObjectSP (new CommandObjectFormatterInfo<SyntheticChildren>(interpreter, 4550 "synthetic", 4551 [](ValueObject& valobj) -> SyntheticChildren::SharedPointer { 4552 return valobj.GetSyntheticChildren(); 4553 }))); 4554 } 4555 4556 4557 ~CommandObjectTypeSynth () 4558 { 4559 } 4560 }; 4561 4562 #endif // #ifndef LLDB_DISABLE_PYTHON 4563 4564 class CommandObjectTypeFilter : public CommandObjectMultiword 4565 { 4566 public: 4567 CommandObjectTypeFilter (CommandInterpreter &interpreter) : 4568 CommandObjectMultiword (interpreter, 4569 "type filter", 4570 "A set of commands for operating on type filters", 4571 "type synthetic [<sub-command-options>] ") 4572 { 4573 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFilterAdd (interpreter))); 4574 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFilterClear (interpreter))); 4575 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFilterDelete (interpreter))); 4576 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFilterList (interpreter))); 4577 } 4578 4579 4580 ~CommandObjectTypeFilter () 4581 { 4582 } 4583 }; 4584 4585 class CommandObjectTypeCategory : public CommandObjectMultiword 4586 { 4587 public: 4588 CommandObjectTypeCategory (CommandInterpreter &interpreter) : 4589 CommandObjectMultiword (interpreter, 4590 "type category", 4591 "A set of commands for operating on categories", 4592 "type category [<sub-command-options>] ") 4593 { 4594 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTypeCategoryEnable (interpreter))); 4595 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTypeCategoryDisable (interpreter))); 4596 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeCategoryDelete (interpreter))); 4597 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeCategoryList (interpreter))); 4598 } 4599 4600 4601 ~CommandObjectTypeCategory () 4602 { 4603 } 4604 }; 4605 4606 class CommandObjectTypeSummary : public CommandObjectMultiword 4607 { 4608 public: 4609 CommandObjectTypeSummary (CommandInterpreter &interpreter) : 4610 CommandObjectMultiword (interpreter, 4611 "type summary", 4612 "A set of commands for editing variable summary display options", 4613 "type summary [<sub-command-options>] ") 4614 { 4615 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSummaryAdd (interpreter))); 4616 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSummaryClear (interpreter))); 4617 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSummaryDelete (interpreter))); 4618 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSummaryList (interpreter))); 4619 LoadSubCommand ("info", CommandObjectSP (new CommandObjectFormatterInfo<TypeSummaryImpl>(interpreter, 4620 "summary", 4621 [](ValueObject& valobj) -> TypeSummaryImpl::SharedPointer { 4622 return valobj.GetSummaryFormat(); 4623 }))); 4624 } 4625 4626 4627 ~CommandObjectTypeSummary () 4628 { 4629 } 4630 }; 4631 4632 //------------------------------------------------------------------------- 4633 // CommandObjectType 4634 //------------------------------------------------------------------------- 4635 4636 CommandObjectType::CommandObjectType (CommandInterpreter &interpreter) : 4637 CommandObjectMultiword (interpreter, 4638 "type", 4639 "A set of commands for operating on the type system", 4640 "type [<sub-command-options>]") 4641 { 4642 LoadSubCommand ("category", CommandObjectSP (new CommandObjectTypeCategory (interpreter))); 4643 LoadSubCommand ("filter", CommandObjectSP (new CommandObjectTypeFilter (interpreter))); 4644 LoadSubCommand ("format", CommandObjectSP (new CommandObjectTypeFormat (interpreter))); 4645 LoadSubCommand ("summary", CommandObjectSP (new CommandObjectTypeSummary (interpreter))); 4646 #ifndef LLDB_DISABLE_PYTHON 4647 LoadSubCommand ("synthetic", CommandObjectSP (new CommandObjectTypeSynth (interpreter))); 4648 #endif 4649 } 4650 4651 4652 CommandObjectType::~CommandObjectType () 4653 { 4654 } 4655 4656 4657