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