import source from 1.3.40
[external/swig.git] / Lib / swiginit.swg
1 /* -----------------------------------------------------------------------------
2  * Type initialization:
3  * This problem is tough by the requirement that no dynamic 
4  * memory is used. Also, since swig_type_info structures store pointers to 
5  * swig_cast_info structures and swig_cast_info structures store pointers back
6  * to swig_type_info structures, we need some lookup code at initialization. 
7  * The idea is that swig generates all the structures that are needed. 
8  * The runtime then collects these partially filled structures. 
9  * The SWIG_InitializeModule function takes these initial arrays out of 
10  * swig_module, and does all the lookup, filling in the swig_module.types
11  * array with the correct data and linking the correct swig_cast_info
12  * structures together.
13  *
14  * The generated swig_type_info structures are assigned staticly to an initial 
15  * array. We just loop through that array, and handle each type individually.
16  * First we lookup if this type has been already loaded, and if so, use the
17  * loaded structure instead of the generated one. Then we have to fill in the
18  * cast linked list. The cast data is initially stored in something like a
19  * two-dimensional array. Each row corresponds to a type (there are the same
20  * number of rows as there are in the swig_type_initial array). Each entry in
21  * a column is one of the swig_cast_info structures for that type.
22  * The cast_initial array is actually an array of arrays, because each row has
23  * a variable number of columns. So to actually build the cast linked list,
24  * we find the array of casts associated with the type, and loop through it 
25  * adding the casts to the list. The one last trick we need to do is making
26  * sure the type pointer in the swig_cast_info struct is correct.
27  *
28  * First off, we lookup the cast->type name to see if it is already loaded. 
29  * There are three cases to handle:
30  *  1) If the cast->type has already been loaded AND the type we are adding
31  *     casting info to has not been loaded (it is in this module), THEN we
32  *     replace the cast->type pointer with the type pointer that has already
33  *     been loaded.
34  *  2) If BOTH types (the one we are adding casting info to, and the 
35  *     cast->type) are loaded, THEN the cast info has already been loaded by
36  *     the previous module so we just ignore it.
37  *  3) Finally, if cast->type has not already been loaded, then we add that
38  *     swig_cast_info to the linked list (because the cast->type) pointer will
39  *     be correct.
40  * ----------------------------------------------------------------------------- */
41
42 #ifdef __cplusplus
43 extern "C" {
44 #if 0
45 } /* c-mode */
46 #endif
47 #endif
48
49 #if 0
50 #define SWIGRUNTIME_DEBUG
51 #endif
52
53
54 SWIGRUNTIME void
55 SWIG_InitializeModule(void *clientdata) {
56   size_t i;
57   swig_module_info *module_head, *iter;
58   int found, init;
59
60   clientdata = clientdata;
61
62   /* check to see if the circular list has been setup, if not, set it up */
63   if (swig_module.next==0) {
64     /* Initialize the swig_module */
65     swig_module.type_initial = swig_type_initial;
66     swig_module.cast_initial = swig_cast_initial;
67     swig_module.next = &swig_module;
68     init = 1;
69   } else {
70     init = 0;
71   }
72
73   /* Try and load any already created modules */
74   module_head = SWIG_GetModule(clientdata);
75   if (!module_head) {
76     /* This is the first module loaded for this interpreter */
77     /* so set the swig module into the interpreter */
78     SWIG_SetModule(clientdata, &swig_module);
79     module_head = &swig_module;
80   } else {
81     /* the interpreter has loaded a SWIG module, but has it loaded this one? */
82     found=0;
83     iter=module_head;
84     do {
85       if (iter==&swig_module) {
86         found=1;
87         break;
88       }
89       iter=iter->next;
90     } while (iter!= module_head);
91
92     /* if the is found in the list, then all is done and we may leave */
93     if (found) return;
94     /* otherwise we must add out module into the list */
95     swig_module.next = module_head->next;
96     module_head->next = &swig_module;
97   }
98
99   /* When multiple interpeters are used, a module could have already been initialized in
100      a different interpreter, but not yet have a pointer in this interpreter.
101      In this case, we do not want to continue adding types... everything should be
102      set up already */
103   if (init == 0) return;
104
105   /* Now work on filling in swig_module.types */
106 #ifdef SWIGRUNTIME_DEBUG
107   printf("SWIG_InitializeModule: size %d\n", swig_module.size);
108 #endif
109   for (i = 0; i < swig_module.size; ++i) {
110     swig_type_info *type = 0;
111     swig_type_info *ret;
112     swig_cast_info *cast;
113   
114 #ifdef SWIGRUNTIME_DEBUG
115     printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
116 #endif
117
118     /* if there is another module already loaded */
119     if (swig_module.next != &swig_module) {
120       type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name);
121     }
122     if (type) {
123       /* Overwrite clientdata field */
124 #ifdef SWIGRUNTIME_DEBUG
125       printf("SWIG_InitializeModule: found type %s\n", type->name);
126 #endif
127       if (swig_module.type_initial[i]->clientdata) {
128         type->clientdata = swig_module.type_initial[i]->clientdata;
129 #ifdef SWIGRUNTIME_DEBUG
130       printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name);
131 #endif
132       }
133     } else {
134       type = swig_module.type_initial[i];
135     }
136
137     /* Insert casting types */
138     cast = swig_module.cast_initial[i];
139     while (cast->type) {
140     
141       /* Don't need to add information already in the list */
142       ret = 0;
143 #ifdef SWIGRUNTIME_DEBUG
144       printf("SWIG_InitializeModule: look cast %s\n", cast->type->name);
145 #endif
146       if (swig_module.next != &swig_module) {
147         ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name);
148 #ifdef SWIGRUNTIME_DEBUG
149         if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name);
150 #endif
151       }
152       if (ret) {
153         if (type == swig_module.type_initial[i]) {
154 #ifdef SWIGRUNTIME_DEBUG
155           printf("SWIG_InitializeModule: skip old type %s\n", ret->name);
156 #endif
157           cast->type = ret;
158           ret = 0;
159         } else {
160           /* Check for casting already in the list */
161           swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type);
162 #ifdef SWIGRUNTIME_DEBUG
163           if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name);
164 #endif
165           if (!ocast) ret = 0;
166         }
167       }
168
169       if (!ret) {
170 #ifdef SWIGRUNTIME_DEBUG
171         printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name);
172 #endif
173         if (type->cast) {
174           type->cast->prev = cast;
175           cast->next = type->cast;
176         }
177         type->cast = cast;
178       }
179       cast++;
180     }
181     /* Set entry in modules->types array equal to the type */
182     swig_module.types[i] = type;
183   }
184   swig_module.types[i] = 0;
185
186 #ifdef SWIGRUNTIME_DEBUG
187   printf("**** SWIG_InitializeModule: Cast List ******\n");
188   for (i = 0; i < swig_module.size; ++i) {
189     int j = 0;
190     swig_cast_info *cast = swig_module.cast_initial[i];
191     printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
192     while (cast->type) {
193       printf("SWIG_InitializeModule: cast type %s\n", cast->type->name);
194       cast++;
195       ++j;
196     }
197   printf("---- Total casts: %d\n",j);
198   }
199   printf("**** SWIG_InitializeModule: Cast List ******\n");
200 #endif
201 }
202
203 /* This function will propagate the clientdata field of type to
204 * any new swig_type_info structures that have been added into the list
205 * of equivalent types.  It is like calling
206 * SWIG_TypeClientData(type, clientdata) a second time.
207 */
208 SWIGRUNTIME void
209 SWIG_PropagateClientData(void) {
210   size_t i;
211   swig_cast_info *equiv;
212   static int init_run = 0;
213
214   if (init_run) return;
215   init_run = 1;
216
217   for (i = 0; i < swig_module.size; i++) {
218     if (swig_module.types[i]->clientdata) {
219       equiv = swig_module.types[i]->cast;
220       while (equiv) {
221         if (!equiv->converter) {
222           if (equiv->type && !equiv->type->clientdata)
223             SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata);
224         }
225         equiv = equiv->next;
226       }
227     }
228   }
229 }
230
231 #ifdef __cplusplus
232 #if 0
233 { /* c-mode */
234 #endif
235 }
236 #endif