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