blob: 198beae191aa13a6a2f68f0160d04b01ff91a548 [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
Jason Molenda743e86a2010-06-11 23:44:18 +000017enum PluginAction
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018{
19 ePluginRegisterInstance,
20 ePluginUnregisterInstance,
21 ePluginGetInstanceAtIndex
22};
23
24
25#pragma mark ABI
26
27
Jason Molenda743e86a2010-06-11 23:44:18 +000028struct ABIInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029{
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;
Jason Molenda743e86a2010-06-11 23:44:18 +0000128 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000129}
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
Jason Molenda743e86a2010-06-11 23:44:18 +0000151struct DisassemblerInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000152{
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;
Jason Molenda743e86a2010-06-11 23:44:18 +0000251 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000252}
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
Jason Molenda743e86a2010-06-11 23:44:18 +0000275struct DynamicLoaderInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000276{
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;
Jason Molenda743e86a2010-06-11 23:44:18 +0000375 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000376}
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
Greg Claytonf03bbe22011-02-01 01:37:45 +0000394#pragma mark EmulateInstruction
395
396
397struct EmulateInstructionInstance
398{
399 EmulateInstructionInstance() :
400 name(),
401 description(),
402 create_callback(NULL)
403 {
404 }
405
406 std::string name;
407 std::string description;
408 EmulateInstructionCreateInstance create_callback;
409};
410
411typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
412
413static bool
414AccessEmulateInstructionInstances (PluginAction action, EmulateInstructionInstance &instance, uint32_t index)
415{
416 static EmulateInstructionInstances g_plugin_instances;
417
418 switch (action)
419 {
420 case ePluginRegisterInstance:
421 if (instance.create_callback)
422 {
423 g_plugin_instances.push_back (instance);
424 return true;
425 }
426 break;
427
428 case ePluginUnregisterInstance:
429 if (instance.create_callback)
430 {
431 EmulateInstructionInstances::iterator pos, end = g_plugin_instances.end();
432 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
433 {
434 if (pos->create_callback == instance.create_callback)
435 {
436 g_plugin_instances.erase(pos);
437 return true;
438 }
439 }
440 }
441 break;
442
443 case ePluginGetInstanceAtIndex:
444 if (index < g_plugin_instances.size())
445 {
446 instance = g_plugin_instances[index];
447 return true;
448 }
449 break;
450
451 default:
452 break;
453 }
454 return false;
455}
456
457
458bool
459PluginManager::RegisterPlugin
460(
461 const char *name,
462 const char *description,
463 EmulateInstructionCreateInstance create_callback
464 )
465{
466 if (create_callback)
467 {
468 EmulateInstructionInstance instance;
469 assert (name && name[0]);
470 instance.name = name;
471 if (description && description[0])
472 instance.description = description;
473 instance.create_callback = create_callback;
474 return AccessEmulateInstructionInstances (ePluginRegisterInstance, instance, 0);
475 }
476 return false;
477}
478
479bool
480PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callback)
481{
482 if (create_callback)
483 {
484 EmulateInstructionInstance instance;
485 instance.create_callback = create_callback;
486 return AccessEmulateInstructionInstances (ePluginUnregisterInstance, instance, 0);
487 }
488 return false;
489}
490
491EmulateInstructionCreateInstance
492PluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx)
493{
494 EmulateInstructionInstance instance;
495 if (AccessEmulateInstructionInstances (ePluginGetInstanceAtIndex, instance, idx))
496 return instance.create_callback;
497 return NULL;
498}
499
500EmulateInstructionCreateInstance
501PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const char *name)
502{
503 if (name && name[0])
504 {
505 EmulateInstructionInstance instance;
506 std::string ss_name(name);
507 for (uint32_t idx = 0; AccessEmulateInstructionInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
508 {
509 if (instance.name == ss_name)
510 return instance.create_callback;
511 }
512 }
513 return NULL;
514}
515
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000516
Jim Ingham22777012010-09-23 02:01:19 +0000517#pragma mark LanguageRuntime
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000518
519
Jim Ingham22777012010-09-23 02:01:19 +0000520struct LanguageRuntimeInstance
521{
522 LanguageRuntimeInstance() :
523 name(),
524 description(),
525 create_callback(NULL)
526 {
527 }
528
529 std::string name;
530 std::string description;
531 LanguageRuntimeCreateInstance create_callback;
532};
533
534typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
535
536static bool
537AccessLanguageRuntimeInstances (PluginAction action, LanguageRuntimeInstance &instance, uint32_t index)
538{
539 static LanguageRuntimeInstances g_plugin_instances;
540
541 switch (action)
542 {
543 case ePluginRegisterInstance:
544 if (instance.create_callback)
545 {
546 g_plugin_instances.push_back (instance);
547 return true;
548 }
549 break;
550
551 case ePluginUnregisterInstance:
552 if (instance.create_callback)
553 {
554 LanguageRuntimeInstances::iterator pos, end = g_plugin_instances.end();
555 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
556 {
557 if (pos->create_callback == instance.create_callback)
558 {
559 g_plugin_instances.erase(pos);
560 return true;
561 }
562 }
563 }
564 break;
565
566 case ePluginGetInstanceAtIndex:
567 if (index < g_plugin_instances.size())
568 {
569 instance = g_plugin_instances[index];
570 return true;
571 }
572 break;
573
574 default:
575 break;
576 }
577 return false;
578}
579
580
581bool
582PluginManager::RegisterPlugin
583 (
584 const char *name,
585 const char *description,
586 LanguageRuntimeCreateInstance create_callback
587 )
588{
589 if (create_callback)
590 {
591 LanguageRuntimeInstance instance;
592 assert (name && name[0]);
593 instance.name = name;
594 if (description && description[0])
595 instance.description = description;
596 instance.create_callback = create_callback;
597 return AccessLanguageRuntimeInstances (ePluginRegisterInstance, instance, 0);
598 }
599 return false;
600}
601
602bool
603PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
604{
605 if (create_callback)
606 {
607 LanguageRuntimeInstance instance;
608 instance.create_callback = create_callback;
609 return AccessLanguageRuntimeInstances (ePluginUnregisterInstance, instance, 0);
610 }
611 return false;
612}
613
614LanguageRuntimeCreateInstance
615PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx)
616{
617 LanguageRuntimeInstance instance;
618 if (AccessLanguageRuntimeInstances (ePluginGetInstanceAtIndex, instance, idx))
619 return instance.create_callback;
620 return NULL;
621}
622
623LanguageRuntimeCreateInstance
624PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const char *name)
625{
626 if (name && name[0])
627 {
628 LanguageRuntimeInstance instance;
629 std::string ss_name(name);
630 for (uint32_t idx = 0; AccessLanguageRuntimeInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
631 {
632 if (instance.name == ss_name)
633 return instance.create_callback;
634 }
635 }
636 return NULL;
637}
638
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000639#pragma mark ObjectFile
640
Jason Molenda743e86a2010-06-11 23:44:18 +0000641struct ObjectFileInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000642{
643 ObjectFileInstance() :
644 name(),
645 description(),
646 create_callback(NULL)
647 {
648 }
649
650 std::string name;
651 std::string description;
652 ObjectFileCreateInstance create_callback;
653};
654
655typedef std::vector<ObjectFileInstance> ObjectFileInstances;
656
657static bool
658AccessObjectFileInstances (PluginAction action, ObjectFileInstance &instance, uint32_t index)
659{
660 static ObjectFileInstances 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 ObjectFileInstances::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 ObjectFileCreateInstance create_callback
708)
709{
710 if (create_callback)
711 {
712 ObjectFileInstance 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 AccessObjectFileInstances (ePluginRegisterInstance, instance, 0);
719 }
720 return false;
721}
722
723bool
724PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
725{
726 if (create_callback)
727 {
728 ObjectFileInstance instance;
729 instance.create_callback = create_callback;
730 return AccessObjectFileInstances (ePluginUnregisterInstance, instance, 0);
731 }
732 return false;
733}
734
735ObjectFileCreateInstance
736PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
737{
738 ObjectFileInstance instance;
739 if (AccessObjectFileInstances (ePluginGetInstanceAtIndex, instance, idx))
740 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000741 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000742}
743ObjectFileCreateInstance
744PluginManager::GetObjectFileCreateCallbackForPluginName (const char *name)
745{
746 if (name && name[0])
747 {
748 ObjectFileInstance instance;
749 std::string ss_name(name);
750 for (uint32_t idx = 0; AccessObjectFileInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
751 {
752 if (instance.name == ss_name)
753 return instance.create_callback;
754 }
755 }
756 return NULL;
757}
758
759
760
761#pragma mark ObjectContainer
762
Jason Molenda743e86a2010-06-11 23:44:18 +0000763struct ObjectContainerInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000764{
765 ObjectContainerInstance() :
766 name(),
767 description(),
768 create_callback(NULL)
769 {
770 }
771
772 std::string name;
773 std::string description;
774 ObjectContainerCreateInstance create_callback;
775};
776
777typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
778
779static bool
780AccessObjectContainerInstances (PluginAction action, ObjectContainerInstance &instance, uint32_t index)
781{
782 static ObjectContainerInstances g_plugin_instances;
783
784 switch (action)
785 {
786 case ePluginRegisterInstance:
787 if (instance.create_callback)
788 {
789 g_plugin_instances.push_back (instance);
790 return true;
791 }
792 break;
793
794 case ePluginUnregisterInstance:
795 if (instance.create_callback)
796 {
797 ObjectContainerInstances::iterator pos, end = g_plugin_instances.end();
798 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
799 {
800 if (pos->create_callback == instance.create_callback)
801 {
802 g_plugin_instances.erase(pos);
803 return true;
804 }
805 }
806 }
807 break;
808
809 case ePluginGetInstanceAtIndex:
810 if (index < g_plugin_instances.size())
811 {
812 instance = g_plugin_instances[index];
813 return true;
814 }
815 break;
816
817 default:
818 break;
819 }
820 return false;
821}
822
823
824bool
825PluginManager::RegisterPlugin
826(
827 const char *name,
828 const char *description,
829 ObjectContainerCreateInstance create_callback
830)
831{
832 if (create_callback)
833 {
834 ObjectContainerInstance instance;
835 assert (name && name[0]);
836 instance.name = name;
837 if (description && description[0])
838 instance.description = description;
839 instance.create_callback = create_callback;
840 return AccessObjectContainerInstances (ePluginRegisterInstance, instance, 0);
841 }
842 return false;
843}
844
845bool
846PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
847{
848 if (create_callback)
849 {
850 ObjectContainerInstance instance;
851 instance.create_callback = create_callback;
852 return AccessObjectContainerInstances (ePluginUnregisterInstance, instance, 0);
853 }
854 return false;
855}
856
857ObjectContainerCreateInstance
858PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
859{
860 ObjectContainerInstance instance;
861 if (AccessObjectContainerInstances (ePluginGetInstanceAtIndex, instance, idx))
862 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000863 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000864}
865ObjectContainerCreateInstance
866PluginManager::GetObjectContainerCreateCallbackForPluginName (const char *name)
867{
868 if (name && name[0])
869 {
870 ObjectContainerInstance instance;
871 std::string ss_name(name);
872 for (uint32_t idx = 0; AccessObjectContainerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
873 {
874 if (instance.name == ss_name)
875 return instance.create_callback;
876 }
877 }
878 return NULL;
879}
880
881#pragma mark LogChannel
882
Jason Molenda743e86a2010-06-11 23:44:18 +0000883struct LogChannelInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000884{
885 LogChannelInstance() :
886 name(),
887 description(),
888 create_callback(NULL)
889 {
890 }
891
892 std::string name;
893 std::string description;
894 LogChannelCreateInstance create_callback;
895};
896
897typedef std::vector<LogChannelInstance> LogChannelInstances;
898
899static bool
900AccessLogChannelInstances (PluginAction action, LogChannelInstance &instance, uint32_t index)
901{
902 static LogChannelInstances g_plugin_instances;
903
904 switch (action)
905 {
906 case ePluginRegisterInstance:
907 if (instance.create_callback)
908 {
909 g_plugin_instances.push_back (instance);
910 return true;
911 }
912 break;
913
914 case ePluginUnregisterInstance:
915 if (instance.create_callback)
916 {
917 LogChannelInstances::iterator pos, end = g_plugin_instances.end();
918 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
919 {
920 if (pos->create_callback == instance.create_callback)
921 {
922 g_plugin_instances.erase(pos);
923 return true;
924 }
925 }
926 }
927 break;
928
929 case ePluginGetInstanceAtIndex:
930 if (index < g_plugin_instances.size())
931 {
932 instance = g_plugin_instances[index];
933 return true;
934 }
935 break;
936
937 default:
938 break;
939 }
940 return false;
941}
942
943
944bool
945PluginManager::RegisterPlugin
946(
947 const char *name,
948 const char *description,
949 LogChannelCreateInstance create_callback
950)
951{
952 if (create_callback)
953 {
954 LogChannelInstance instance;
955 assert (name && name[0]);
956 instance.name = name;
957 if (description && description[0])
958 instance.description = description;
959 instance.create_callback = create_callback;
960 return AccessLogChannelInstances (ePluginRegisterInstance, instance, 0);
961 }
962 return false;
963}
964
965bool
966PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
967{
968 if (create_callback)
969 {
970 LogChannelInstance instance;
971 instance.create_callback = create_callback;
972 return AccessLogChannelInstances (ePluginUnregisterInstance, instance, 0);
973 }
974 return false;
975}
976
977const char *
978PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
979{
980 LogChannelInstance instance;
981 if (AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx))
982 return instance.name.c_str();
983 return NULL;
984}
985
986
987LogChannelCreateInstance
988PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
989{
990 LogChannelInstance instance;
991 if (AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx))
992 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +0000993 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000994}
995
996LogChannelCreateInstance
997PluginManager::GetLogChannelCreateCallbackForPluginName (const char *name)
998{
999 if (name && name[0])
1000 {
1001 LogChannelInstance instance;
1002 std::string ss_name(name);
1003 for (uint32_t idx = 0; AccessLogChannelInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1004 {
1005 if (instance.name == ss_name)
1006 return instance.create_callback;
1007 }
1008 }
1009 return NULL;
1010}
1011
1012#pragma mark Process
1013
Jason Molenda743e86a2010-06-11 23:44:18 +00001014struct ProcessInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001015{
1016 ProcessInstance() :
1017 name(),
1018 description(),
1019 create_callback(NULL)
1020 {
1021 }
1022
1023 std::string name;
1024 std::string description;
1025 ProcessCreateInstance create_callback;
1026};
1027
1028typedef std::vector<ProcessInstance> ProcessInstances;
1029
1030static bool
1031AccessProcessInstances (PluginAction action, ProcessInstance &instance, uint32_t index)
1032{
1033 static ProcessInstances g_plugin_instances;
1034
1035 switch (action)
1036 {
1037 case ePluginRegisterInstance:
1038 if (instance.create_callback)
1039 {
1040 g_plugin_instances.push_back (instance);
1041 return true;
1042 }
1043 break;
1044
1045 case ePluginUnregisterInstance:
1046 if (instance.create_callback)
1047 {
1048 ProcessInstances::iterator pos, end = g_plugin_instances.end();
1049 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1050 {
1051 if (pos->create_callback == instance.create_callback)
1052 {
1053 g_plugin_instances.erase(pos);
1054 return true;
1055 }
1056 }
1057 }
1058 break;
1059
1060 case ePluginGetInstanceAtIndex:
1061 if (index < g_plugin_instances.size())
1062 {
1063 instance = g_plugin_instances[index];
1064 return true;
1065 }
1066 break;
1067
1068 default:
1069 break;
1070 }
1071 return false;
1072}
1073
1074
1075bool
1076PluginManager::RegisterPlugin
1077(
1078 const char *name,
1079 const char *description,
1080 ProcessCreateInstance create_callback
1081)
1082{
1083 if (create_callback)
1084 {
1085 ProcessInstance 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 AccessProcessInstances (ePluginRegisterInstance, instance, 0);
1092 }
1093 return false;
1094}
1095
1096bool
1097PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
1098{
1099 if (create_callback)
1100 {
1101 ProcessInstance instance;
1102 instance.create_callback = create_callback;
1103 return AccessProcessInstances (ePluginUnregisterInstance, instance, 0);
1104 }
1105 return false;
1106}
1107
1108ProcessCreateInstance
1109PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
1110{
1111 ProcessInstance instance;
1112 if (AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx))
1113 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001114 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001115}
1116
1117ProcessCreateInstance
1118PluginManager::GetProcessCreateCallbackForPluginName (const char *name)
1119{
1120 if (name && name[0])
1121 {
1122 ProcessInstance instance;
1123 std::string ss_name(name);
1124 for (uint32_t idx = 0; AccessProcessInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1125 {
1126 if (instance.name == ss_name)
1127 return instance.create_callback;
1128 }
1129 }
1130 return NULL;
1131}
1132
1133#pragma mark SymbolFile
1134
Jason Molenda743e86a2010-06-11 23:44:18 +00001135struct SymbolFileInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001136{
1137 SymbolFileInstance() :
1138 name(),
1139 description(),
1140 create_callback(NULL)
1141 {
1142 }
1143
1144 std::string name;
1145 std::string description;
1146 SymbolFileCreateInstance create_callback;
1147};
1148
1149typedef std::vector<SymbolFileInstance> SymbolFileInstances;
1150
1151static bool
1152AccessSymbolFileInstances (PluginAction action, SymbolFileInstance &instance, uint32_t index)
1153{
1154 static SymbolFileInstances g_plugin_instances;
1155
1156 switch (action)
1157 {
1158 case ePluginRegisterInstance:
1159 if (instance.create_callback)
1160 {
1161 g_plugin_instances.push_back (instance);
1162 return true;
1163 }
1164 break;
1165
1166 case ePluginUnregisterInstance:
1167 if (instance.create_callback)
1168 {
1169 SymbolFileInstances::iterator pos, end = g_plugin_instances.end();
1170 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1171 {
1172 if (pos->create_callback == instance.create_callback)
1173 {
1174 g_plugin_instances.erase(pos);
1175 return true;
1176 }
1177 }
1178 }
1179 break;
1180
1181 case ePluginGetInstanceAtIndex:
1182 if (index < g_plugin_instances.size())
1183 {
1184 instance = g_plugin_instances[index];
1185 return true;
1186 }
1187 break;
1188
1189 default:
1190 break;
1191 }
1192 return false;
1193}
1194
1195
1196bool
1197PluginManager::RegisterPlugin
1198(
1199 const char *name,
1200 const char *description,
1201 SymbolFileCreateInstance create_callback
1202)
1203{
1204 if (create_callback)
1205 {
1206 SymbolFileInstance instance;
1207 assert (name && name[0]);
1208 instance.name = name;
1209 if (description && description[0])
1210 instance.description = description;
1211 instance.create_callback = create_callback;
1212 return AccessSymbolFileInstances (ePluginRegisterInstance, instance, 0);
1213 }
1214 return false;
1215}
1216
1217bool
1218PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
1219{
1220 if (create_callback)
1221 {
1222 SymbolFileInstance instance;
1223 instance.create_callback = create_callback;
1224 return AccessSymbolFileInstances (ePluginUnregisterInstance, instance, 0);
1225 }
1226 return false;
1227}
1228
1229SymbolFileCreateInstance
1230PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
1231{
1232 SymbolFileInstance instance;
1233 if (AccessSymbolFileInstances (ePluginGetInstanceAtIndex, instance, idx))
1234 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001235 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001236}
1237SymbolFileCreateInstance
1238PluginManager::GetSymbolFileCreateCallbackForPluginName (const char *name)
1239{
1240 if (name && name[0])
1241 {
1242 SymbolFileInstance instance;
1243 std::string ss_name(name);
1244 for (uint32_t idx = 0; AccessSymbolFileInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1245 {
1246 if (instance.name == ss_name)
1247 return instance.create_callback;
1248 }
1249 }
1250 return NULL;
1251}
1252
1253
1254
1255#pragma mark SymbolVendor
1256
Jason Molenda743e86a2010-06-11 23:44:18 +00001257struct SymbolVendorInstance
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001258{
1259 SymbolVendorInstance() :
1260 name(),
1261 description(),
1262 create_callback(NULL)
1263 {
1264 }
1265
1266 std::string name;
1267 std::string description;
1268 SymbolVendorCreateInstance create_callback;
1269};
1270
1271typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
1272
1273static bool
1274AccessSymbolVendorInstances (PluginAction action, SymbolVendorInstance &instance, uint32_t index)
1275{
1276 static SymbolVendorInstances g_plugin_instances;
1277
1278 switch (action)
1279 {
1280 case ePluginRegisterInstance:
1281 if (instance.create_callback)
1282 {
1283 g_plugin_instances.push_back (instance);
1284 return true;
1285 }
1286 break;
1287
1288 case ePluginUnregisterInstance:
1289 if (instance.create_callback)
1290 {
1291 SymbolVendorInstances::iterator pos, end = g_plugin_instances.end();
1292 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1293 {
1294 if (pos->create_callback == instance.create_callback)
1295 {
1296 g_plugin_instances.erase(pos);
1297 return true;
1298 }
1299 }
1300 }
1301 break;
1302
1303 case ePluginGetInstanceAtIndex:
1304 if (index < g_plugin_instances.size())
1305 {
1306 instance = g_plugin_instances[index];
1307 return true;
1308 }
1309 break;
1310
1311 default:
1312 break;
1313 }
1314 return false;
1315}
1316
1317bool
1318PluginManager::RegisterPlugin
1319(
1320 const char *name,
1321 const char *description,
1322 SymbolVendorCreateInstance create_callback
1323)
1324{
1325 if (create_callback)
1326 {
1327 SymbolVendorInstance instance;
1328 assert (name && name[0]);
1329 instance.name = name;
1330 if (description && description[0])
1331 instance.description = description;
1332 instance.create_callback = create_callback;
1333 return AccessSymbolVendorInstances (ePluginRegisterInstance, instance, 0);
1334 }
1335 return false;
1336}
1337
1338bool
1339PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
1340{
1341 if (create_callback)
1342 {
1343 SymbolVendorInstance instance;
1344 instance.create_callback = create_callback;
1345 return AccessSymbolVendorInstances (ePluginUnregisterInstance, instance, 0);
1346 }
1347 return false;
1348}
1349
1350SymbolVendorCreateInstance
1351PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
1352{
1353 SymbolVendorInstance instance;
1354 if (AccessSymbolVendorInstances (ePluginGetInstanceAtIndex, instance, idx))
1355 return instance.create_callback;
Jason Molenda743e86a2010-06-11 23:44:18 +00001356 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001357}
1358
1359SymbolVendorCreateInstance
1360PluginManager::GetSymbolVendorCreateCallbackForPluginName (const char *name)
1361{
1362 if (name && name[0])
1363 {
1364 SymbolVendorInstance instance;
1365 std::string ss_name(name);
1366 for (uint32_t idx = 0; AccessSymbolVendorInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1367 {
1368 if (instance.name == ss_name)
1369 return instance.create_callback;
1370 }
1371 }
1372 return NULL;
1373}
1374
1375
Jason Molendafbcb7f22010-09-10 07:49:16 +00001376#pragma mark UnwindAssemblyProfiler
1377
1378struct UnwindAssemblyProfilerInstance
1379{
1380 UnwindAssemblyProfilerInstance() :
1381 name(),
1382 description(),
1383 create_callback(NULL)
1384 {
1385 }
1386
1387 std::string name;
1388 std::string description;
1389 UnwindAssemblyProfilerCreateInstance create_callback;
1390};
1391
1392typedef std::vector<UnwindAssemblyProfilerInstance> UnwindAssemblyProfilerInstances;
1393
1394static bool
1395AccessUnwindAssemblyProfilerInstances (PluginAction action, UnwindAssemblyProfilerInstance &instance, uint32_t index)
1396{
1397 static UnwindAssemblyProfilerInstances g_plugin_instances;
1398
1399 switch (action)
1400 {
1401 case ePluginRegisterInstance:
1402 if (instance.create_callback)
1403 {
1404 g_plugin_instances.push_back (instance);
1405 return true;
1406 }
1407 break;
1408
1409 case ePluginUnregisterInstance:
1410 if (instance.create_callback)
1411 {
1412 UnwindAssemblyProfilerInstances::iterator pos, end = g_plugin_instances.end();
1413 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1414 {
1415 if (pos->create_callback == instance.create_callback)
1416 {
1417 g_plugin_instances.erase(pos);
1418 return true;
1419 }
1420 }
1421 }
1422 break;
1423
1424 case ePluginGetInstanceAtIndex:
1425 if (index < g_plugin_instances.size())
1426 {
1427 instance = g_plugin_instances[index];
1428 return true;
1429 }
1430 break;
1431
1432 default:
1433 break;
1434 }
1435 return false;
1436}
1437
1438bool
1439PluginManager::RegisterPlugin
1440(
1441 const char *name,
1442 const char *description,
1443 UnwindAssemblyProfilerCreateInstance create_callback
1444)
1445{
1446 if (create_callback)
1447 {
1448 UnwindAssemblyProfilerInstance instance;
1449 assert (name && name[0]);
1450 instance.name = name;
1451 if (description && description[0])
1452 instance.description = description;
1453 instance.create_callback = create_callback;
1454 return AccessUnwindAssemblyProfilerInstances (ePluginRegisterInstance, instance, 0);
1455 }
1456 return false;
1457}
1458
1459bool
1460PluginManager::UnregisterPlugin (UnwindAssemblyProfilerCreateInstance create_callback)
1461{
1462 if (create_callback)
1463 {
1464 UnwindAssemblyProfilerInstance instance;
1465 instance.create_callback = create_callback;
1466 return AccessUnwindAssemblyProfilerInstances (ePluginUnregisterInstance, instance, 0);
1467 }
1468 return false;
1469}
1470
1471UnwindAssemblyProfilerCreateInstance
1472PluginManager::GetUnwindAssemblyProfilerCreateCallbackAtIndex (uint32_t idx)
1473{
1474 UnwindAssemblyProfilerInstance instance;
1475 if (AccessUnwindAssemblyProfilerInstances (ePluginGetInstanceAtIndex, instance, idx))
1476 return instance.create_callback;
1477 return NULL;
1478}
1479
1480UnwindAssemblyProfilerCreateInstance
1481PluginManager::GetUnwindAssemblyProfilerCreateCallbackForPluginName (const char *name)
1482{
1483 if (name && name[0])
1484 {
1485 UnwindAssemblyProfilerInstance instance;
1486 std::string ss_name(name);
1487 for (uint32_t idx = 0; AccessUnwindAssemblyProfilerInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1488 {
1489 if (instance.name == ss_name)
1490 return instance.create_callback;
1491 }
1492 }
1493 return NULL;
1494}
1495
1496#pragma mark ArchDefaultUnwindPlan
1497
1498struct ArchDefaultUnwindPlanInstance
1499{
1500 ArchDefaultUnwindPlanInstance() :
1501 name(),
1502 description(),
1503 create_callback(NULL)
1504 {
1505 }
1506
1507 std::string name;
1508 std::string description;
1509 ArchDefaultUnwindPlanCreateInstance create_callback;
1510};
1511
1512typedef std::vector<ArchDefaultUnwindPlanInstance> ArchDefaultUnwindPlanInstances;
1513
1514static bool
1515AccessArchDefaultUnwindPlanInstances (PluginAction action, ArchDefaultUnwindPlanInstance &instance, uint32_t index)
1516{
1517 static ArchDefaultUnwindPlanInstances g_plugin_instances;
1518
1519 switch (action)
1520 {
1521 case ePluginRegisterInstance:
1522 if (instance.create_callback)
1523 {
1524 g_plugin_instances.push_back (instance);
1525 return true;
1526 }
1527 break;
1528
1529 case ePluginUnregisterInstance:
1530 if (instance.create_callback)
1531 {
1532 ArchDefaultUnwindPlanInstances::iterator pos, end = g_plugin_instances.end();
1533 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1534 {
1535 if (pos->create_callback == instance.create_callback)
1536 {
1537 g_plugin_instances.erase(pos);
1538 return true;
1539 }
1540 }
1541 }
1542 break;
1543
1544 case ePluginGetInstanceAtIndex:
1545 if (index < g_plugin_instances.size())
1546 {
1547 instance = g_plugin_instances[index];
1548 return true;
1549 }
1550 break;
1551
1552 default:
1553 break;
1554 }
1555 return false;
1556}
1557
1558bool
1559PluginManager::RegisterPlugin
1560(
1561 const char *name,
1562 const char *description,
1563 ArchDefaultUnwindPlanCreateInstance create_callback
1564)
1565{
1566 if (create_callback)
1567 {
1568 ArchDefaultUnwindPlanInstance instance;
1569 assert (name && name[0]);
1570 instance.name = name;
1571 if (description && description[0])
1572 instance.description = description;
1573 instance.create_callback = create_callback;
1574 return AccessArchDefaultUnwindPlanInstances (ePluginRegisterInstance, instance, 0);
1575 }
1576 return false;
1577}
1578
1579bool
1580PluginManager::UnregisterPlugin (ArchDefaultUnwindPlanCreateInstance create_callback)
1581{
1582 if (create_callback)
1583 {
1584 ArchDefaultUnwindPlanInstance instance;
1585 instance.create_callback = create_callback;
1586 return AccessArchDefaultUnwindPlanInstances (ePluginUnregisterInstance, instance, 0);
1587 }
1588 return false;
1589}
1590
1591ArchDefaultUnwindPlanCreateInstance
1592PluginManager::GetArchDefaultUnwindPlanCreateCallbackAtIndex (uint32_t idx)
1593{
1594 ArchDefaultUnwindPlanInstance instance;
1595 if (AccessArchDefaultUnwindPlanInstances (ePluginGetInstanceAtIndex, instance, idx))
1596 return instance.create_callback;
1597 return NULL;
1598}
1599
1600ArchDefaultUnwindPlanCreateInstance
1601PluginManager::GetArchDefaultUnwindPlanCreateCallbackForPluginName (const char *name)
1602{
1603 if (name && name[0])
1604 {
1605 ArchDefaultUnwindPlanInstance instance;
1606 std::string ss_name(name);
1607 for (uint32_t idx = 0; AccessArchDefaultUnwindPlanInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1608 {
1609 if (instance.name == ss_name)
1610 return instance.create_callback;
1611 }
1612 }
1613 return NULL;
1614}
1615
Jason Molenda0c7cc852010-09-22 07:37:07 +00001616#pragma mark ArchVolatileRegs
1617
1618struct ArchVolatileRegsInstance
1619{
1620 ArchVolatileRegsInstance() :
1621 name(),
1622 description(),
1623 create_callback(NULL)
1624 {
1625 }
1626
1627 std::string name;
1628 std::string description;
1629 ArchVolatileRegsCreateInstance create_callback;
1630};
1631
1632typedef std::vector<ArchVolatileRegsInstance> ArchVolatileRegsInstances;
1633
1634static bool
1635AccessArchVolatileRegsInstances (PluginAction action, ArchVolatileRegsInstance &instance, uint32_t index)
1636{
1637 static ArchVolatileRegsInstances g_plugin_instances;
1638
1639 switch (action)
1640 {
1641 case ePluginRegisterInstance:
1642 if (instance.create_callback)
1643 {
1644 g_plugin_instances.push_back (instance);
1645 return true;
1646 }
1647 break;
1648
1649 case ePluginUnregisterInstance:
1650 if (instance.create_callback)
1651 {
1652 ArchVolatileRegsInstances::iterator pos, end = g_plugin_instances.end();
1653 for (pos = g_plugin_instances.begin(); pos != end; ++ pos)
1654 {
1655 if (pos->create_callback == instance.create_callback)
1656 {
1657 g_plugin_instances.erase(pos);
1658 return true;
1659 }
1660 }
1661 }
1662 break;
1663
1664 case ePluginGetInstanceAtIndex:
1665 if (index < g_plugin_instances.size())
1666 {
1667 instance = g_plugin_instances[index];
1668 return true;
1669 }
1670 break;
1671
1672 default:
1673 break;
1674 }
1675 return false;
1676}
1677
1678bool
1679PluginManager::RegisterPlugin
1680(
1681 const char *name,
1682 const char *description,
1683 ArchVolatileRegsCreateInstance create_callback
1684)
1685{
1686 if (create_callback)
1687 {
1688 ArchVolatileRegsInstance instance;
1689 assert (name && name[0]);
1690 instance.name = name;
1691 if (description && description[0])
1692 instance.description = description;
1693 instance.create_callback = create_callback;
1694 return AccessArchVolatileRegsInstances (ePluginRegisterInstance, instance, 0);
1695 }
1696 return false;
1697}
1698
1699bool
1700PluginManager::UnregisterPlugin (ArchVolatileRegsCreateInstance create_callback)
1701{
1702 if (create_callback)
1703 {
1704 ArchVolatileRegsInstance instance;
1705 instance.create_callback = create_callback;
1706 return AccessArchVolatileRegsInstances (ePluginUnregisterInstance, instance, 0);
1707 }
1708 return false;
1709}
1710
1711ArchVolatileRegsCreateInstance
1712PluginManager::GetArchVolatileRegsCreateCallbackAtIndex (uint32_t idx)
1713{
1714 ArchVolatileRegsInstance instance;
1715 if (AccessArchVolatileRegsInstances (ePluginGetInstanceAtIndex, instance, idx))
1716 return instance.create_callback;
1717 return NULL;
1718}
1719
1720ArchVolatileRegsCreateInstance
1721PluginManager::GetArchVolatileRegsCreateCallbackForPluginName (const char *name)
1722{
1723 if (name && name[0])
1724 {
1725 ArchVolatileRegsInstance instance;
1726 std::string ss_name(name);
1727 for (uint32_t idx = 0; AccessArchVolatileRegsInstances (ePluginGetInstanceAtIndex, instance, idx); ++idx)
1728 {
1729 if (instance.name == ss_name)
1730 return instance.create_callback;
1731 }
1732 }
1733 return NULL;
1734}
Jason Molendafbcb7f22010-09-10 07:49:16 +00001735