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