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