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