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