Home | History | Annotate | Download | only in 2.0.11
      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   /* check to see if the circular list has been setup, if not, set it up */
     61   if (swig_module.next==0) {
     62     /* Initialize the swig_module */
     63     swig_module.type_initial = swig_type_initial;
     64     swig_module.cast_initial = swig_cast_initial;
     65     swig_module.next = &swig_module;
     66     init = 1;
     67   } else {
     68     init = 0;
     69   }
     70 
     71   /* Try and load any already created modules */
     72   module_head = SWIG_GetModule(clientdata);
     73   if (!module_head) {
     74     /* This is the first module loaded for this interpreter */
     75     /* so set the swig module into the interpreter */
     76     SWIG_SetModule(clientdata, &swig_module);
     77     module_head = &swig_module;
     78   } else {
     79     /* the interpreter has loaded a SWIG module, but has it loaded this one? */
     80     found=0;
     81     iter=module_head;
     82     do {
     83       if (iter==&swig_module) {
     84         found=1;
     85         break;
     86       }
     87       iter=iter->next;
     88     } while (iter!= module_head);
     89 
     90     /* if the is found in the list, then all is done and we may leave */
     91     if (found) return;
     92     /* otherwise we must add out module into the list */
     93     swig_module.next = module_head->next;
     94     module_head->next = &swig_module;
     95   }
     96 
     97   /* When multiple interpreters are used, a module could have already been initialized in
     98      a different interpreter, but not yet have a pointer in this interpreter.
     99      In this case, we do not want to continue adding types... everything should be
    100      set up already */
    101   if (init == 0) return;
    102 
    103   /* Now work on filling in swig_module.types */
    104 #ifdef SWIGRUNTIME_DEBUG
    105   printf("SWIG_InitializeModule: size %d\n", swig_module.size);
    106 #endif
    107   for (i = 0; i < swig_module.size; ++i) {
    108     swig_type_info *type = 0;
    109     swig_type_info *ret;
    110     swig_cast_info *cast;
    111 
    112 #ifdef SWIGRUNTIME_DEBUG
    113     printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
    114 #endif
    115 
    116     /* if there is another module already loaded */
    117     if (swig_module.next != &swig_module) {
    118       type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name);
    119     }
    120     if (type) {
    121       /* Overwrite clientdata field */
    122 #ifdef SWIGRUNTIME_DEBUG
    123       printf("SWIG_InitializeModule: found type %s\n", type->name);
    124 #endif
    125       if (swig_module.type_initial[i]->clientdata) {
    126 	type->clientdata = swig_module.type_initial[i]->clientdata;
    127 #ifdef SWIGRUNTIME_DEBUG
    128       printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name);
    129 #endif
    130       }
    131     } else {
    132       type = swig_module.type_initial[i];
    133     }
    134 
    135     /* Insert casting types */
    136     cast = swig_module.cast_initial[i];
    137     while (cast->type) {
    138 
    139       /* Don't need to add information already in the list */
    140       ret = 0;
    141 #ifdef SWIGRUNTIME_DEBUG
    142       printf("SWIG_InitializeModule: look cast %s\n", cast->type->name);
    143 #endif
    144       if (swig_module.next != &swig_module) {
    145         ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name);
    146 #ifdef SWIGRUNTIME_DEBUG
    147 	if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name);
    148 #endif
    149       }
    150       if (ret) {
    151 	if (type == swig_module.type_initial[i]) {
    152 #ifdef SWIGRUNTIME_DEBUG
    153 	  printf("SWIG_InitializeModule: skip old type %s\n", ret->name);
    154 #endif
    155 	  cast->type = ret;
    156 	  ret = 0;
    157 	} else {
    158 	  /* Check for casting already in the list */
    159 	  swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type);
    160 #ifdef SWIGRUNTIME_DEBUG
    161 	  if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name);
    162 #endif
    163 	  if (!ocast) ret = 0;
    164 	}
    165       }
    166 
    167       if (!ret) {
    168 #ifdef SWIGRUNTIME_DEBUG
    169 	printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name);
    170 #endif
    171         if (type->cast) {
    172           type->cast->prev = cast;
    173           cast->next = type->cast;
    174         }
    175         type->cast = cast;
    176       }
    177       cast++;
    178     }
    179     /* Set entry in modules->types array equal to the type */
    180     swig_module.types[i] = type;
    181   }
    182   swig_module.types[i] = 0;
    183 
    184 #ifdef SWIGRUNTIME_DEBUG
    185   printf("**** SWIG_InitializeModule: Cast List ******\n");
    186   for (i = 0; i < swig_module.size; ++i) {
    187     int j = 0;
    188     swig_cast_info *cast = swig_module.cast_initial[i];
    189     printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
    190     while (cast->type) {
    191       printf("SWIG_InitializeModule: cast type %s\n", cast->type->name);
    192       cast++;
    193       ++j;
    194     }
    195   printf("---- Total casts: %d\n",j);
    196   }
    197   printf("**** SWIG_InitializeModule: Cast List ******\n");
    198 #endif
    199 }
    200 
    201 /* This function will propagate the clientdata field of type to
    202 * any new swig_type_info structures that have been added into the list
    203 * of equivalent types.  It is like calling
    204 * SWIG_TypeClientData(type, clientdata) a second time.
    205 */
    206 SWIGRUNTIME void
    207 SWIG_PropagateClientData(void) {
    208   size_t i;
    209   swig_cast_info *equiv;
    210   static int init_run = 0;
    211 
    212   if (init_run) return;
    213   init_run = 1;
    214 
    215   for (i = 0; i < swig_module.size; i++) {
    216     if (swig_module.types[i]->clientdata) {
    217       equiv = swig_module.types[i]->cast;
    218       while (equiv) {
    219         if (!equiv->converter) {
    220           if (equiv->type && !equiv->type->clientdata)
    221             SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata);
    222         }
    223         equiv = equiv->next;
    224       }
    225     }
    226   }
    227 }
    228 
    229 #ifdef __cplusplus
    230 #if 0
    231 { /* c-mode */
    232 #endif
    233 }
    234 #endif
    235