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