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
43extern "C" {
44#if 0
45} /* c-mode */
46#endif
47#endif
48
49#if 0
50#define SWIGRUNTIME_DEBUG
51#endif
52
53
54SWIGRUNTIME void
55SWIG_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*/
208SWIGRUNTIME void
209SWIG_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
237