1 //===-- PluginManager.cpp ---------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Core/PluginManager.h" 11 12 #include <string> 13 #include <vector> 14 15 using namespace lldb_private; 16 17 typedef enum PluginAction 18 { 19 ePluginRegisterInstance, 20 ePluginUnregisterInstance, 21 ePluginGetInstanceAtIndex 22 }; 23 24 25 #pragma mark ABI 26 27 28 typedef struct ABIInstance 29 { 30 ABIInstance() : 31 name(), 32 description(), 33 create_callback(NULL) 34 { 35 } 36 37 std::string name; 38 std::string description; 39 ABICreateInstance create_callback; 40 }; 41 42 typedef std::vector<ABIInstance> ABIInstances; 43 44 static bool 45 AccessABIInstances (PluginAction action, ABIInstance &instance, uint32_t index) 46 { 47 static ABIInstances g_plugin_instances; 48 49 switch (action) 50 { 51 case ePluginRegisterInstance: 52 if (instance.create_callback) 53 { 54 g_plugin_instances.push_back (instance); 55 return true; 56 } 57 break; 58 59 case ePluginUnregisterInstance: 60 if (instance.create_callback) 61 { 62 ABIInstances::iterator pos, end = g_plugin_instances.end(); 63 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 64 { 65 if (pos->create_callback == instance.create_callback) 66 { 67 g_plugin_instances.erase(pos); 68 return true; 69 } 70 } 71 } 72 break; 73 74 case ePluginGetInstanceAtIndex: 75 if (index < g_plugin_instances.size()) 76 { 77 instance = g_plugin_instances[index]; 78 return true; 79 } 80 break; 81 82 default: 83 break; 84 } 85 return false; 86 } 87 88 89 bool 90 PluginManager::RegisterPlugin 91 ( 92 const char *name, 93 const char *description, 94 ABICreateInstance create_callback 95 ) 96 { 97 if (create_callback) 98 { 99 ABIInstance instance; 100 assert (name && name[0]); 101 instance.name = name; 102 if (description && description[0]) 103 instance.description = description; 104 instance.create_callback = create_callback; 105 return AccessABIInstances (ePluginRegisterInstance, instance, 0); 106 } 107 return false; 108 } 109 110 bool 111 PluginManager::UnregisterPlugin (ABICreateInstance create_callback) 112 { 113 if (create_callback) 114 { 115 ABIInstance instance; 116 instance.create_callback = create_callback; 117 return AccessABIInstances (ePluginUnregisterInstance, instance, 0); 118 } 119 return false; 120 } 121 122 ABICreateInstance 123 PluginManager::GetABICreateCallbackAtIndex (uint32_t idx) 124 { 125 ABIInstance instance; 126 if (AccessABIInstances (ePluginGetInstanceAtIndex, instance, idx)) 127 return instance.create_callback; 128 return false; 129 } 130 131 ABICreateInstance 132 PluginManager::GetABICreateCallbackForPluginName (const char *name) 133 { 134 if (name && name[0]) 135 { 136 ABIInstance instance; 137 std::string ss_name(name); 138 for (uint32_t idx = 0; AccessABIInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 139 { 140 if (instance.name == ss_name) 141 return instance.create_callback; 142 } 143 } 144 return NULL; 145 } 146 147 148 #pragma mark Disassembler 149 150 151 typedef struct DisassemblerInstance 152 { 153 DisassemblerInstance() : 154 name(), 155 description(), 156 create_callback(NULL) 157 { 158 } 159 160 std::string name; 161 std::string description; 162 DisassemblerCreateInstance create_callback; 163 }; 164 165 typedef std::vector<DisassemblerInstance> DisassemblerInstances; 166 167 static bool 168 AccessDisassemblerInstances (PluginAction action, DisassemblerInstance &instance, uint32_t index) 169 { 170 static DisassemblerInstances g_plugin_instances; 171 172 switch (action) 173 { 174 case ePluginRegisterInstance: 175 if (instance.create_callback) 176 { 177 g_plugin_instances.push_back (instance); 178 return true; 179 } 180 break; 181 182 case ePluginUnregisterInstance: 183 if (instance.create_callback) 184 { 185 DisassemblerInstances::iterator pos, end = g_plugin_instances.end(); 186 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 187 { 188 if (pos->create_callback == instance.create_callback) 189 { 190 g_plugin_instances.erase(pos); 191 return true; 192 } 193 } 194 } 195 break; 196 197 case ePluginGetInstanceAtIndex: 198 if (index < g_plugin_instances.size()) 199 { 200 instance = g_plugin_instances[index]; 201 return true; 202 } 203 break; 204 205 default: 206 break; 207 } 208 return false; 209 } 210 211 212 bool 213 PluginManager::RegisterPlugin 214 ( 215 const char *name, 216 const char *description, 217 DisassemblerCreateInstance create_callback 218 ) 219 { 220 if (create_callback) 221 { 222 DisassemblerInstance instance; 223 assert (name && name[0]); 224 instance.name = name; 225 if (description && description[0]) 226 instance.description = description; 227 instance.create_callback = create_callback; 228 return AccessDisassemblerInstances (ePluginRegisterInstance, instance, 0); 229 } 230 return false; 231 } 232 233 bool 234 PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback) 235 { 236 if (create_callback) 237 { 238 DisassemblerInstance instance; 239 instance.create_callback = create_callback; 240 return AccessDisassemblerInstances (ePluginUnregisterInstance, instance, 0); 241 } 242 return false; 243 } 244 245 DisassemblerCreateInstance 246 PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx) 247 { 248 DisassemblerInstance instance; 249 if (AccessDisassemblerInstances (ePluginGetInstanceAtIndex, instance, idx)) 250 return instance.create_callback; 251 return false; 252 } 253 254 DisassemblerCreateInstance 255 PluginManager::GetDisassemblerCreateCallbackForPluginName (const char *name) 256 { 257 if (name && name[0]) 258 { 259 DisassemblerInstance instance; 260 std::string ss_name(name); 261 for (uint32_t idx = 0; AccessDisassemblerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 262 { 263 if (instance.name == ss_name) 264 return instance.create_callback; 265 } 266 } 267 return NULL; 268 } 269 270 271 272 #pragma mark DynamicLoader 273 274 275 typedef struct DynamicLoaderInstance 276 { 277 DynamicLoaderInstance() : 278 name(), 279 description(), 280 create_callback(NULL) 281 { 282 } 283 284 std::string name; 285 std::string description; 286 DynamicLoaderCreateInstance create_callback; 287 }; 288 289 typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances; 290 291 static bool 292 AccessDynamicLoaderInstances (PluginAction action, DynamicLoaderInstance &instance, uint32_t index) 293 { 294 static DynamicLoaderInstances g_plugin_instances; 295 296 switch (action) 297 { 298 case ePluginRegisterInstance: 299 if (instance.create_callback) 300 { 301 g_plugin_instances.push_back (instance); 302 return true; 303 } 304 break; 305 306 case ePluginUnregisterInstance: 307 if (instance.create_callback) 308 { 309 DynamicLoaderInstances::iterator pos, end = g_plugin_instances.end(); 310 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 311 { 312 if (pos->create_callback == instance.create_callback) 313 { 314 g_plugin_instances.erase(pos); 315 return true; 316 } 317 } 318 } 319 break; 320 321 case ePluginGetInstanceAtIndex: 322 if (index < g_plugin_instances.size()) 323 { 324 instance = g_plugin_instances[index]; 325 return true; 326 } 327 break; 328 329 default: 330 break; 331 } 332 return false; 333 } 334 335 336 bool 337 PluginManager::RegisterPlugin 338 ( 339 const char *name, 340 const char *description, 341 DynamicLoaderCreateInstance create_callback 342 ) 343 { 344 if (create_callback) 345 { 346 DynamicLoaderInstance instance; 347 assert (name && name[0]); 348 instance.name = name; 349 if (description && description[0]) 350 instance.description = description; 351 instance.create_callback = create_callback; 352 return AccessDynamicLoaderInstances (ePluginRegisterInstance, instance, 0); 353 } 354 return false; 355 } 356 357 bool 358 PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback) 359 { 360 if (create_callback) 361 { 362 DynamicLoaderInstance instance; 363 instance.create_callback = create_callback; 364 return AccessDynamicLoaderInstances (ePluginUnregisterInstance, instance, 0); 365 } 366 return false; 367 } 368 369 DynamicLoaderCreateInstance 370 PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx) 371 { 372 DynamicLoaderInstance instance; 373 if (AccessDynamicLoaderInstances (ePluginGetInstanceAtIndex, instance, idx)) 374 return instance.create_callback; 375 return false; 376 } 377 378 DynamicLoaderCreateInstance 379 PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const char *name) 380 { 381 if (name && name[0]) 382 { 383 DynamicLoaderInstance instance; 384 std::string ss_name(name); 385 for (uint32_t idx = 0; AccessDynamicLoaderInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 386 { 387 if (instance.name == ss_name) 388 return instance.create_callback; 389 } 390 } 391 return NULL; 392 } 393 394 395 396 397 #pragma mark ObjectFile 398 399 typedef struct ObjectFileInstance 400 { 401 ObjectFileInstance() : 402 name(), 403 description(), 404 create_callback(NULL) 405 { 406 } 407 408 std::string name; 409 std::string description; 410 ObjectFileCreateInstance create_callback; 411 }; 412 413 typedef std::vector<ObjectFileInstance> ObjectFileInstances; 414 415 static bool 416 AccessObjectFileInstances (PluginAction action, ObjectFileInstance &instance, uint32_t index) 417 { 418 static ObjectFileInstances g_plugin_instances; 419 420 switch (action) 421 { 422 case ePluginRegisterInstance: 423 if (instance.create_callback) 424 { 425 g_plugin_instances.push_back (instance); 426 return true; 427 } 428 break; 429 430 case ePluginUnregisterInstance: 431 if (instance.create_callback) 432 { 433 ObjectFileInstances::iterator pos, end = g_plugin_instances.end(); 434 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 435 { 436 if (pos->create_callback == instance.create_callback) 437 { 438 g_plugin_instances.erase(pos); 439 return true; 440 } 441 } 442 } 443 break; 444 445 case ePluginGetInstanceAtIndex: 446 if (index < g_plugin_instances.size()) 447 { 448 instance = g_plugin_instances[index]; 449 return true; 450 } 451 break; 452 453 default: 454 break; 455 } 456 return false; 457 } 458 459 460 bool 461 PluginManager::RegisterPlugin 462 ( 463 const char *name, 464 const char *description, 465 ObjectFileCreateInstance create_callback 466 ) 467 { 468 if (create_callback) 469 { 470 ObjectFileInstance instance; 471 assert (name && name[0]); 472 instance.name = name; 473 if (description && description[0]) 474 instance.description = description; 475 instance.create_callback = create_callback; 476 return AccessObjectFileInstances (ePluginRegisterInstance, instance, 0); 477 } 478 return false; 479 } 480 481 bool 482 PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback) 483 { 484 if (create_callback) 485 { 486 ObjectFileInstance instance; 487 instance.create_callback = create_callback; 488 return AccessObjectFileInstances (ePluginUnregisterInstance, instance, 0); 489 } 490 return false; 491 } 492 493 ObjectFileCreateInstance 494 PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx) 495 { 496 ObjectFileInstance instance; 497 if (AccessObjectFileInstances (ePluginGetInstanceAtIndex, instance, idx)) 498 return instance.create_callback; 499 return false; 500 } 501 ObjectFileCreateInstance 502 PluginManager::GetObjectFileCreateCallbackForPluginName (const char *name) 503 { 504 if (name && name[0]) 505 { 506 ObjectFileInstance instance; 507 std::string ss_name(name); 508 for (uint32_t idx = 0; AccessObjectFileInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 509 { 510 if (instance.name == ss_name) 511 return instance.create_callback; 512 } 513 } 514 return NULL; 515 } 516 517 518 519 #pragma mark ObjectContainer 520 521 typedef struct ObjectContainerInstance 522 { 523 ObjectContainerInstance() : 524 name(), 525 description(), 526 create_callback(NULL) 527 { 528 } 529 530 std::string name; 531 std::string description; 532 ObjectContainerCreateInstance create_callback; 533 }; 534 535 typedef std::vector<ObjectContainerInstance> ObjectContainerInstances; 536 537 static bool 538 AccessObjectContainerInstances (PluginAction action, ObjectContainerInstance &instance, uint32_t index) 539 { 540 static ObjectContainerInstances g_plugin_instances; 541 542 switch (action) 543 { 544 case ePluginRegisterInstance: 545 if (instance.create_callback) 546 { 547 g_plugin_instances.push_back (instance); 548 return true; 549 } 550 break; 551 552 case ePluginUnregisterInstance: 553 if (instance.create_callback) 554 { 555 ObjectContainerInstances::iterator pos, end = g_plugin_instances.end(); 556 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 557 { 558 if (pos->create_callback == instance.create_callback) 559 { 560 g_plugin_instances.erase(pos); 561 return true; 562 } 563 } 564 } 565 break; 566 567 case ePluginGetInstanceAtIndex: 568 if (index < g_plugin_instances.size()) 569 { 570 instance = g_plugin_instances[index]; 571 return true; 572 } 573 break; 574 575 default: 576 break; 577 } 578 return false; 579 } 580 581 582 bool 583 PluginManager::RegisterPlugin 584 ( 585 const char *name, 586 const char *description, 587 ObjectContainerCreateInstance create_callback 588 ) 589 { 590 if (create_callback) 591 { 592 ObjectContainerInstance instance; 593 assert (name && name[0]); 594 instance.name = name; 595 if (description && description[0]) 596 instance.description = description; 597 instance.create_callback = create_callback; 598 return AccessObjectContainerInstances (ePluginRegisterInstance, instance, 0); 599 } 600 return false; 601 } 602 603 bool 604 PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback) 605 { 606 if (create_callback) 607 { 608 ObjectContainerInstance instance; 609 instance.create_callback = create_callback; 610 return AccessObjectContainerInstances (ePluginUnregisterInstance, instance, 0); 611 } 612 return false; 613 } 614 615 ObjectContainerCreateInstance 616 PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx) 617 { 618 ObjectContainerInstance instance; 619 if (AccessObjectContainerInstances (ePluginGetInstanceAtIndex, instance, idx)) 620 return instance.create_callback; 621 return false; 622 } 623 ObjectContainerCreateInstance 624 PluginManager::GetObjectContainerCreateCallbackForPluginName (const char *name) 625 { 626 if (name && name[0]) 627 { 628 ObjectContainerInstance instance; 629 std::string ss_name(name); 630 for (uint32_t idx = 0; AccessObjectContainerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 631 { 632 if (instance.name == ss_name) 633 return instance.create_callback; 634 } 635 } 636 return NULL; 637 } 638 639 #pragma mark LogChannel 640 641 typedef struct LogChannelInstance 642 { 643 LogChannelInstance() : 644 name(), 645 description(), 646 create_callback(NULL) 647 { 648 } 649 650 std::string name; 651 std::string description; 652 LogChannelCreateInstance create_callback; 653 }; 654 655 typedef std::vector<LogChannelInstance> LogChannelInstances; 656 657 static bool 658 AccessLogChannelInstances (PluginAction action, LogChannelInstance &instance, uint32_t index) 659 { 660 static LogChannelInstances g_plugin_instances; 661 662 switch (action) 663 { 664 case ePluginRegisterInstance: 665 if (instance.create_callback) 666 { 667 g_plugin_instances.push_back (instance); 668 return true; 669 } 670 break; 671 672 case ePluginUnregisterInstance: 673 if (instance.create_callback) 674 { 675 LogChannelInstances::iterator pos, end = g_plugin_instances.end(); 676 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 677 { 678 if (pos->create_callback == instance.create_callback) 679 { 680 g_plugin_instances.erase(pos); 681 return true; 682 } 683 } 684 } 685 break; 686 687 case ePluginGetInstanceAtIndex: 688 if (index < g_plugin_instances.size()) 689 { 690 instance = g_plugin_instances[index]; 691 return true; 692 } 693 break; 694 695 default: 696 break; 697 } 698 return false; 699 } 700 701 702 bool 703 PluginManager::RegisterPlugin 704 ( 705 const char *name, 706 const char *description, 707 LogChannelCreateInstance create_callback 708 ) 709 { 710 if (create_callback) 711 { 712 LogChannelInstance instance; 713 assert (name && name[0]); 714 instance.name = name; 715 if (description && description[0]) 716 instance.description = description; 717 instance.create_callback = create_callback; 718 return AccessLogChannelInstances (ePluginRegisterInstance, instance, 0); 719 } 720 return false; 721 } 722 723 bool 724 PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback) 725 { 726 if (create_callback) 727 { 728 LogChannelInstance instance; 729 instance.create_callback = create_callback; 730 return AccessLogChannelInstances (ePluginUnregisterInstance, instance, 0); 731 } 732 return false; 733 } 734 735 const char * 736 PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx) 737 { 738 LogChannelInstance instance; 739 if (AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx)) 740 return instance.name.c_str(); 741 return NULL; 742 } 743 744 745 LogChannelCreateInstance 746 PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx) 747 { 748 LogChannelInstance instance; 749 if (AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx)) 750 return instance.create_callback; 751 return false; 752 } 753 754 LogChannelCreateInstance 755 PluginManager::GetLogChannelCreateCallbackForPluginName (const char *name) 756 { 757 if (name && name[0]) 758 { 759 LogChannelInstance instance; 760 std::string ss_name(name); 761 for (uint32_t idx = 0; AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 762 { 763 if (instance.name == ss_name) 764 return instance.create_callback; 765 } 766 } 767 return NULL; 768 } 769 770 #pragma mark Process 771 772 typedef struct ProcessInstance 773 { 774 ProcessInstance() : 775 name(), 776 description(), 777 create_callback(NULL) 778 { 779 } 780 781 std::string name; 782 std::string description; 783 ProcessCreateInstance create_callback; 784 }; 785 786 typedef std::vector<ProcessInstance> ProcessInstances; 787 788 static bool 789 AccessProcessInstances (PluginAction action, ProcessInstance &instance, uint32_t index) 790 { 791 static ProcessInstances g_plugin_instances; 792 793 switch (action) 794 { 795 case ePluginRegisterInstance: 796 if (instance.create_callback) 797 { 798 g_plugin_instances.push_back (instance); 799 return true; 800 } 801 break; 802 803 case ePluginUnregisterInstance: 804 if (instance.create_callback) 805 { 806 ProcessInstances::iterator pos, end = g_plugin_instances.end(); 807 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 808 { 809 if (pos->create_callback == instance.create_callback) 810 { 811 g_plugin_instances.erase(pos); 812 return true; 813 } 814 } 815 } 816 break; 817 818 case ePluginGetInstanceAtIndex: 819 if (index < g_plugin_instances.size()) 820 { 821 instance = g_plugin_instances[index]; 822 return true; 823 } 824 break; 825 826 default: 827 break; 828 } 829 return false; 830 } 831 832 833 bool 834 PluginManager::RegisterPlugin 835 ( 836 const char *name, 837 const char *description, 838 ProcessCreateInstance create_callback 839 ) 840 { 841 if (create_callback) 842 { 843 ProcessInstance instance; 844 assert (name && name[0]); 845 instance.name = name; 846 if (description && description[0]) 847 instance.description = description; 848 instance.create_callback = create_callback; 849 return AccessProcessInstances (ePluginRegisterInstance, instance, 0); 850 } 851 return false; 852 } 853 854 bool 855 PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback) 856 { 857 if (create_callback) 858 { 859 ProcessInstance instance; 860 instance.create_callback = create_callback; 861 return AccessProcessInstances (ePluginUnregisterInstance, instance, 0); 862 } 863 return false; 864 } 865 866 ProcessCreateInstance 867 PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx) 868 { 869 ProcessInstance instance; 870 if (AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx)) 871 return instance.create_callback; 872 return false; 873 } 874 875 ProcessCreateInstance 876 PluginManager::GetProcessCreateCallbackForPluginName (const char *name) 877 { 878 if (name && name[0]) 879 { 880 ProcessInstance instance; 881 std::string ss_name(name); 882 for (uint32_t idx = 0; AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 883 { 884 if (instance.name == ss_name) 885 return instance.create_callback; 886 } 887 } 888 return NULL; 889 } 890 891 #pragma mark SymbolFile 892 893 typedef struct SymbolFileInstance 894 { 895 SymbolFileInstance() : 896 name(), 897 description(), 898 create_callback(NULL) 899 { 900 } 901 902 std::string name; 903 std::string description; 904 SymbolFileCreateInstance create_callback; 905 }; 906 907 typedef std::vector<SymbolFileInstance> SymbolFileInstances; 908 909 static bool 910 AccessSymbolFileInstances (PluginAction action, SymbolFileInstance &instance, uint32_t index) 911 { 912 static SymbolFileInstances g_plugin_instances; 913 914 switch (action) 915 { 916 case ePluginRegisterInstance: 917 if (instance.create_callback) 918 { 919 g_plugin_instances.push_back (instance); 920 return true; 921 } 922 break; 923 924 case ePluginUnregisterInstance: 925 if (instance.create_callback) 926 { 927 SymbolFileInstances::iterator pos, end = g_plugin_instances.end(); 928 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 929 { 930 if (pos->create_callback == instance.create_callback) 931 { 932 g_plugin_instances.erase(pos); 933 return true; 934 } 935 } 936 } 937 break; 938 939 case ePluginGetInstanceAtIndex: 940 if (index < g_plugin_instances.size()) 941 { 942 instance = g_plugin_instances[index]; 943 return true; 944 } 945 break; 946 947 default: 948 break; 949 } 950 return false; 951 } 952 953 954 bool 955 PluginManager::RegisterPlugin 956 ( 957 const char *name, 958 const char *description, 959 SymbolFileCreateInstance create_callback 960 ) 961 { 962 if (create_callback) 963 { 964 SymbolFileInstance instance; 965 assert (name && name[0]); 966 instance.name = name; 967 if (description && description[0]) 968 instance.description = description; 969 instance.create_callback = create_callback; 970 return AccessSymbolFileInstances (ePluginRegisterInstance, instance, 0); 971 } 972 return false; 973 } 974 975 bool 976 PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback) 977 { 978 if (create_callback) 979 { 980 SymbolFileInstance instance; 981 instance.create_callback = create_callback; 982 return AccessSymbolFileInstances (ePluginUnregisterInstance, instance, 0); 983 } 984 return false; 985 } 986 987 SymbolFileCreateInstance 988 PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx) 989 { 990 SymbolFileInstance instance; 991 if (AccessSymbolFileInstances (ePluginGetInstanceAtIndex, instance, idx)) 992 return instance.create_callback; 993 return false; 994 } 995 SymbolFileCreateInstance 996 PluginManager::GetSymbolFileCreateCallbackForPluginName (const char *name) 997 { 998 if (name && name[0]) 999 { 1000 SymbolFileInstance instance; 1001 std::string ss_name(name); 1002 for (uint32_t idx = 0; AccessSymbolFileInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 1003 { 1004 if (instance.name == ss_name) 1005 return instance.create_callback; 1006 } 1007 } 1008 return NULL; 1009 } 1010 1011 1012 1013 #pragma mark SymbolVendor 1014 1015 typedef struct SymbolVendorInstance 1016 { 1017 SymbolVendorInstance() : 1018 name(), 1019 description(), 1020 create_callback(NULL) 1021 { 1022 } 1023 1024 std::string name; 1025 std::string description; 1026 SymbolVendorCreateInstance create_callback; 1027 }; 1028 1029 typedef std::vector<SymbolVendorInstance> SymbolVendorInstances; 1030 1031 static bool 1032 AccessSymbolVendorInstances (PluginAction action, SymbolVendorInstance &instance, uint32_t index) 1033 { 1034 static SymbolVendorInstances g_plugin_instances; 1035 1036 switch (action) 1037 { 1038 case ePluginRegisterInstance: 1039 if (instance.create_callback) 1040 { 1041 g_plugin_instances.push_back (instance); 1042 return true; 1043 } 1044 break; 1045 1046 case ePluginUnregisterInstance: 1047 if (instance.create_callback) 1048 { 1049 SymbolVendorInstances::iterator pos, end = g_plugin_instances.end(); 1050 for (pos = g_plugin_instances.begin(); pos != end; ++ pos) 1051 { 1052 if (pos->create_callback == instance.create_callback) 1053 { 1054 g_plugin_instances.erase(pos); 1055 return true; 1056 } 1057 } 1058 } 1059 break; 1060 1061 case ePluginGetInstanceAtIndex: 1062 if (index < g_plugin_instances.size()) 1063 { 1064 instance = g_plugin_instances[index]; 1065 return true; 1066 } 1067 break; 1068 1069 default: 1070 break; 1071 } 1072 return false; 1073 } 1074 1075 bool 1076 PluginManager::RegisterPlugin 1077 ( 1078 const char *name, 1079 const char *description, 1080 SymbolVendorCreateInstance create_callback 1081 ) 1082 { 1083 if (create_callback) 1084 { 1085 SymbolVendorInstance instance; 1086 assert (name && name[0]); 1087 instance.name = name; 1088 if (description && description[0]) 1089 instance.description = description; 1090 instance.create_callback = create_callback; 1091 return AccessSymbolVendorInstances (ePluginRegisterInstance, instance, 0); 1092 } 1093 return false; 1094 } 1095 1096 bool 1097 PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback) 1098 { 1099 if (create_callback) 1100 { 1101 SymbolVendorInstance instance; 1102 instance.create_callback = create_callback; 1103 return AccessSymbolVendorInstances (ePluginUnregisterInstance, instance, 0); 1104 } 1105 return false; 1106 } 1107 1108 SymbolVendorCreateInstance 1109 PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx) 1110 { 1111 SymbolVendorInstance instance; 1112 if (AccessSymbolVendorInstances (ePluginGetInstanceAtIndex, instance, idx)) 1113 return instance.create_callback; 1114 return false; 1115 } 1116 1117 SymbolVendorCreateInstance 1118 PluginManager::GetSymbolVendorCreateCallbackForPluginName (const char *name) 1119 { 1120 if (name && name[0]) 1121 { 1122 SymbolVendorInstance instance; 1123 std::string ss_name(name); 1124 for (uint32_t idx = 0; AccessSymbolVendorInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx) 1125 { 1126 if (instance.name == ss_name) 1127 return instance.create_callback; 1128 } 1129 } 1130 return NULL; 1131 } 1132 1133 1134