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