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