blob: 3723e7cf89a20b72f8ad519a9bca06e94e215243 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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
15using namespace lldb_private;
16
17typedef enum PluginAction
18{
19 ePluginRegisterInstance,
20 ePluginUnregisterInstance,
21 ePluginGetInstanceAtIndex
22};
23
24
25#pragma mark ABI
26
27
28typedef 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
42typedef std::vector<ABIInstance> ABIInstances;
43
44static bool
45AccessABIInstances (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
89bool
90PluginManager::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
110bool
111PluginManager::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
122ABICreateInstance
123PluginManager::GetABICreateCallbackAtIndex (uint32_t idx)
124{
125 ABIInstance instance;
126 if (AccessABIInstances (ePluginGetInstanceAtIndex, instance, idx))
127 return instance.create_callback;
128 return false;
129}
130
131ABICreateInstance
132PluginManager::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
151typedef 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
165typedef std::vector<DisassemblerInstance> DisassemblerInstances;
166
167static bool
168AccessDisassemblerInstances (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
212bool
213PluginManager::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
233bool
234PluginManager::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
245DisassemblerCreateInstance
246PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx)
247{
248 DisassemblerInstance instance;
249 if (AccessDisassemblerInstances (ePluginGetInstanceAtIndex, instance, idx))
250 return instance.create_callback;
251 return false;
252}
253
254DisassemblerCreateInstance
255PluginManager::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
275typedef 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
289typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
290
291static bool
292AccessDynamicLoaderInstances (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
336bool
337PluginManager::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
357bool
358PluginManager::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
369DynamicLoaderCreateInstance
370PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx)
371{
372 DynamicLoaderInstance instance;
373 if (AccessDynamicLoaderInstances (ePluginGetInstanceAtIndex, instance, idx))
374 return instance.create_callback;
375 return false;
376}
377
378DynamicLoaderCreateInstance
379PluginManager::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
399typedef 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
413typedef std::vector<ObjectFileInstance> ObjectFileInstances;
414
415static bool
416AccessObjectFileInstances (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
460bool
461PluginManager::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
481bool
482PluginManager::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
493ObjectFileCreateInstance
494PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
495{
496 ObjectFileInstance instance;
497 if (AccessObjectFileInstances (ePluginGetInstanceAtIndex, instance, idx))
498 return instance.create_callback;
499 return false;
500}
501ObjectFileCreateInstance
502PluginManager::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
521typedef 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
535typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
536
537static bool
538AccessObjectContainerInstances (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
582bool
583PluginManager::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
603bool
604PluginManager::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
615ObjectContainerCreateInstance
616PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
617{
618 ObjectContainerInstance instance;
619 if (AccessObjectContainerInstances (ePluginGetInstanceAtIndex, instance, idx))
620 return instance.create_callback;
621 return false;
622}
623ObjectContainerCreateInstance
624PluginManager::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
641typedef 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
655typedef std::vector<LogChannelInstance> LogChannelInstances;
656
657static bool
658AccessLogChannelInstances (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
702bool
703PluginManager::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
723bool
724PluginManager::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
735const char *
736PluginManager::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
745LogChannelCreateInstance
746PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
747{
748 LogChannelInstance instance;
749 if (AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx))
750 return instance.create_callback;
751 return false;
752}
753
754LogChannelCreateInstance
755PluginManager::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
772typedef 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
786typedef std::vector<ProcessInstance> ProcessInstances;
787
788static bool
789AccessProcessInstances (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
833bool
834PluginManager::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
854bool
855PluginManager::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
866ProcessCreateInstance
867PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
868{
869 ProcessInstance instance;
870 if (AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx))
871 return instance.create_callback;
872 return false;
873}
874
875ProcessCreateInstance
876PluginManager::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
893typedef 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
907typedef std::vector<SymbolFileInstance> SymbolFileInstances;
908
909static bool
910AccessSymbolFileInstances (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
954bool
955PluginManager::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
975bool
976PluginManager::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
987SymbolFileCreateInstance
988PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
989{
990 SymbolFileInstance instance;
991 if (AccessSymbolFileInstances (ePluginGetInstanceAtIndex, instance, idx))
992 return instance.create_callback;
993 return false;
994}
995SymbolFileCreateInstance
996PluginManager::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
1015typedef 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
1029typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1030
1031static bool
1032AccessSymbolVendorInstances (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
1075bool
1076PluginManager::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
1096bool
1097PluginManager::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
1108SymbolVendorCreateInstance
1109PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
1110{
1111 SymbolVendorInstance instance;
1112 if (AccessSymbolVendorInstances (ePluginGetInstanceAtIndex, instance, idx))
1113 return instance.create_callback;
1114 return false;
1115}
1116
1117SymbolVendorCreateInstance
1118PluginManager::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