]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/wxSWIG/SWIG/typemap.cxx
   1 /******************************************************************************* 
   2  * Simplified Wrapper and Interface Generator  (SWIG) 
   4  * Author : David Beazley 
   6  * Department of Computer Science         
   7  * University of Chicago 
  10  * beazley@cs.uchicago.edu 
  12  * Please read the file LICENSE for the copyright and terms by which SWIG 
  13  * can be used and distributed. 
  14  *******************************************************************************/ 
  20 // ------------------------------------------------------------------------ 
  25 // This file provides universal support for typemaps.   Typemaps are created 
  26 // using the following SWIG command in an interface file: 
  28 //       %typemap(lang,operation) type { code }        Make a new typemap 
  29 //       %typemap(lang,operation) type;                Clears any previous typemap 
  31 // lang is an identifier indicating the target language.  The typemap will 
  32 // simply be ignored if its for a different language.  The code is the 
  33 // corresponding C code for the mapping.  An example typemap might look 
  36 //       %typemap(tcl,get) double { 
  37 //              $target = atof($source); 
  39 //       %typemap(tcl,set) double { 
  40 //              sprintf($target,"%0.17f",$source); 
  43 // The variables $target and $source should be used in any type-mappings. 
  44 // Additional local variables can be created, but this should be done  
  45 // by enclosing the entire code fragment in an extra set of braces. 
  47 // The C++ API to the type-mapper is as follows : 
  49 // void typemap_register(char *op, char *lang, DataType *type, char *pname, String &getcode, ParmList *args) 
  50 // char *typemap_lookup(char *op, char *lang, DataType *type, char *pname, char *source, char *target); 
  51 // void typemap_clear(char *op, char *lang, DataType *type, char *pname); 
  53 // The lookup functions return a character string corresponding to the type-mapping 
  54 // code or NULL if none exists.   The string return will have the source and target 
  55 // strings substituted for the strings "$source" and "$target" in the type-mapping code. 
  57 // (2/19/97) This module has been extended somewhat to provide generic mappings 
  58 // of other parts of the code--most notably exceptions. 
  60 // void fragment_register(char *op, char *lang, String &code) 
  61 // char fragment_lookup(char *op, char *lang, int age); 
  62 // char fragment_clear(char *op, char *lang); 
  64 // ------------------------------------------------------------------------ 
  66 // Structure for holding a typemap 
  75   TypeMap     
*previous
;                // Previously defined typemap (if any) 
  76   ParmList    
*args
;                    // Local variables (if any) 
  78   TypeMap(char *l
, DataType 
*t
, String 
&c
, ParmList 
*p 
= 0) { 
  79     lang 
= copy_string(l
); 
  80     type 
= new DataType(t
); 
  87       args 
= new ParmList(p
); 
  92   TypeMap(char *l
, DataType 
*t
, char *c
, ParmList 
*p 
= 0) { 
  93     lang 
= copy_string(l
); 
  94     type 
= new DataType(t
); 
 101       args 
= new ParmList(p
); 
 106   TypeMap(char *l
, char *c
) { 
 107     lang 
= copy_string(l
); 
 116   TypeMap(TypeMap 
*t
) { 
 117     lang 
= copy_string(t
->lang
); 
 118     type 
= new DataType(t
->type
); 
 123     previous 
= t
->previous
; 
 125       args 
= new ParmList(args
); 
 132 // Hash tables for storing type-mappings 
 134 static Hash  typemap_hash
; 
 136 // Structure for holding "applications of a typemap" 
 139   char *name
;          // Typemap name; 
 140   DataType 
*type
;      // Typemap type 
 141   TmMethod 
*next
;      // Next method 
 142   TmMethod(char *n
, DataType 
*t
, TmMethod 
*m 
= 0) { 
 143     if (n
) name 
= copy_string(n
); 
 146       type 
= new DataType(t
); 
 154 // Hash table for storing applications of a datatype 
 156 static Hash application_hash
; 
 158 // ------------------------------------------------------------------------ 
 159 // void typemap_apply(DataType *tm_type, char *tm_name, DataType *type, char *pname) 
 161 // Attempts to apply a typemap given by (tm_type,tm_name) to (type,pname) 
 162 // Called by the %apply directive. 
 163 // ------------------------------------------------------------------------ 
 165 void typemap_apply(DataType 
*tm_type
, char *tm_name
, DataType 
*type
, char *pname
) { 
 169   // Form the application name 
 170   if (!pname
) pname 
= ""; 
 171   sprintf(temp
,"%s$%s",type
->print_type(),pname
); 
 173   // See if there is a method already defined 
 175   m 
= (TmMethod 
*) application_hash
.lookup(temp
); 
 178     m 
= new TmMethod(temp
,type
,0); 
 179     application_hash
.add(temp
,m
); 
 182   // Check to see if an array typemap has been applied to a non-array type 
 184   if ((tm_type
->arraystr
) && (!type
->arraystr
)) { 
 185     fprintf(stderr
,"%s:%d: Warning. Array typemap has been applied to a non-array type.\n", 
 186             input_file
,line_number
); 
 189   // If both are arrays, make sure they have the same dimension  
 191   if ((tm_type
->arraystr
) && (type
->arraystr
)) { 
 193     if (tm_type
->array_dimensions() != type
->array_dimensions()) { 
 194       fprintf(stderr
,"%s:%d: Warning. Array types have different number of dimensions.\n", 
 195               input_file
,line_number
); 
 197       for (int i 
= 0; i 
< tm_type
->array_dimensions(); i
++) { 
 198         strcpy(s
,tm_type
->get_dimension(i
)); 
 199         t 
= type
->get_dimension(i
); 
 200         if (strcmp(s
,"ANY") != 0) { 
 202             fprintf(stderr
,"%s:%d: Warning. Array typemap applied to an array of different size.\n", 
 203                     input_file
, line_number
); 
 209   // Add a new mapping corresponding to the typemap 
 211   m1 
= new TmMethod(tm_name
,tm_type
,m
->next
); 
 215 // ------------------------------------------------------------------------ 
 216 // void typemap_clear_apply(DataType *type, char *pname) 
 218 // Clears the application of a typemap. 
 219 // Called by the %clear directive. 
 220 // ------------------------------------------------------------------------ 
 222 void typemap_clear_apply(DataType 
*type
, char *pname
) { 
 224   if (!pname
) pname 
= ""; 
 225   sprintf(temp
,"%s$%s", type
->print_type(), pname
); 
 226   application_hash
.remove(temp
); 
 229 // ------------------------------------------------------------------------ 
 230 // char *typemap_string(char *lang, DataType *type, char *pname, char *ary, char *suffix) 
 232 // Produces a character string corresponding to a lang, datatype, and 
 233 // method.   This string is used as the key for our typemap hash table. 
 234 // ------------------------------------------------------------------------ 
 236 static char *typemap_string(char *lang
, DataType 
*type
, char *pname
, char *ary
, char *suffix
) { 
 240   old_status 
= type
->status
; 
 245     str 
<< lang 
<< type
->print_type() << pname 
<< ary 
<< suffix
; 
 247     str 
<< lang 
<< type
->print_type() << pname 
<< suffix
; 
 249   type
->status 
= old_status
; 
 253 // ------------------------------------------------------------------------ 
 254 // void typemap_register(char *op, char *lang, DataType *type, char *pname, 
 255 //                       char *getcode, ParmList *args) 
 257 // Register a new mapping with the type-mapper.   
 258 // ------------------------------------------------------------------------ 
 260 void typemap_register(char *op
, char *lang
, DataType 
*type
, char *pname
,  
 261                       char *getcode
, ParmList 
*args
) { 
 268   // printf("Registering : %s %s %s %s\n%s\n", op, lang, type->print_type(), pname, getcode); 
 271   tm 
= new TypeMap(lang
,type
,getcode
,args
); 
 272   // If this is a default typemap, downgrade the type! 
 274   if (strcmp(pname
,"SWIG_DEFAULT_TYPE") == 0) { 
 275     tm
->type
->primitive();    
 279   key 
= typemap_string(lang
,tm
->type
,pname
,tm
->type
->arraystr
, op
); 
 281   // Get any previous setting of the typemap 
 283   tm_old 
= (TypeMap 
*) typemap_hash
.lookup(key
); 
 287     // Perform a chaining operation, but only if the last typemap is 
 290     if (type_id 
< tm_old
->last
) { 
 291       sprintf(temp
,"$%s",op
); 
 292       tm
->code
.replace(temp
,tm_old
->code
); 
 295     // If found, we need to attach the old version to the new one 
 297     tm
->previous 
= tm_old
; 
 299     tm_old
->last 
= type_id
; 
 301     // Remove the old one from the hash 
 303     typemap_hash
.remove(key
); 
 306   // Add new typemap to the hash table 
 307   typemap_hash
.add(key
,(void *) tm
); 
 309   // Now try to perform default chaining operation (if available) 
 310   //  if (!is_default) { 
 311   //    sprintf(temp,"$%s",op); 
 312   //    if (strstr(tm->code,temp)) { 
 313   //      tm->code.replace(temp,typemap_resolve_default(op,lang,type)); 
 317   // Just a sanity check to make sure args look okay. 
 321     p 
= tm
->args
->get_first(); 
 324         //      printf("    %s %s\n", p->t->print_type(),p->name); 
 326         fprintf(stderr
,"%s:%d:  Typemap error. Local variables must have a name\n", 
 327                 input_file
, line_number
); 
 329       // If a call by reference thingy, fix that 
 330       if (p
->call_type 
& CALL_REFERENCE
) { 
 334       p 
= tm
->args
->get_next(); 
 339 // ------------------------------------------------------------------------ 
 340 // void typemap_register(char *op, char *lang, char *type, char *pname, 
 341 //                       char *getcode, ParmList *args) 
 343 // Register a new mapping with the type-mapper. Special version that uses a 
 344 // string instead of a datatype. 
 345 // ------------------------------------------------------------------------ 
 347 void typemap_register(char *op
, char *lang
, char *type
, char *pname
,  
 348                       char *getcode
, ParmList 
*args
) { 
 350   strcpy(temp
.name
,type
); 
 353   typemap_register(op
,lang
,&temp
,pname
,getcode
,args
); 
 357 // ------------------------------------------------------------------------ 
 358 // void typemap_register_default(char *op, char *lang, int type, int ptr, char *arraystr, 
 359 //                               char *code, ParmList *args) 
 361 // Registers a default typemap with the system using numerical type codes. 
 362 // type is the numerical code, ptr is the level of indirection.  
 363 // ------------------------------------------------------------------------ 
 365 void typemap_register_default(char *op
, char *lang
, int type
, int ptr
, char *arraystr
, 
 366                            char *code
, ParmList 
*args
) { 
 368   DataType 
*t 
= new DataType(type
); 
 370   // Create a raw datatype from the arguments 
 373   t
->arraystr 
= copy_string(arraystr
); 
 375   // Now, go register this as a default type 
 377   typemap_register(op
,lang
,t
,"SWIG_DEFAULT_TYPE",code
,args
); 
 382 // ------------------------------------------------------------------------ 
 383 // static TypeMap *typemap_search(char *key, int id)  
 385 // An internal function for searching for a particular typemap given 
 386 // a key value and datatype id. 
 388 // Basically this checks the hash table and then checks the id against 
 389 // first and last values, looking for a match.   This is to properly 
 390 // handle scoping problems. 
 391 // ------------------------------------------------------------------------ 
 393 TypeMap 
*typemap_search(char *key
, int id
) { 
 397   tm 
= (TypeMap 
*) typemap_hash
.lookup(key
); 
 399     if ((id 
>= tm
->first
) && (id 
< tm
->last
)) return tm
; 
 405 // ------------------------------------------------------------------------ 
 406 // TypeMap *typemap_search_array(char *op, char *lang, DataType *type, char *pname, String &str) 
 408 // Performs a typemap lookup on an array type.  This is abit complicated 
 409 // because we need to look for ANY tags specifying that any array dimension 
 410 // is valid.   The resulting code will be placed in str with dimension variables 
 412 // ------------------------------------------------------------------------ 
 414 TypeMap 
*typemap_search_array(char *op
, char *lang
, DataType 
*type
, char *pname
, String 
&str
) { 
 415   char      *origarr 
= type
->arraystr
; 
 421   if (!type
->arraystr
) return 0; 
 423   // First check to see if exactly this array has been mapped 
 425   key 
= typemap_string(lang
,type
,pname
,type
->arraystr
,op
); 
 426   tm 
= typemap_search(key
,type
->id
); 
 428   // Check for unnamed array of specific dimensions 
 430     key 
= typemap_string(lang
,type
,"",type
->arraystr
,op
); 
 431     tm 
= typemap_search(key
,type
->id
); 
 435     // We're going to go search for matches with the ANY tag 
 437     ndim 
= type
->array_dimensions();             // Get number of dimensions 
 438     j 
= (1 << ndim
) - 1;                         // Status bits 
 439     for (i 
= 0; i 
< (1 << ndim
); i
++) { 
 440       // Form an array string 
 443       for (n 
= 0; n 
< ndim
; n
++) { 
 445           tempastr 
<< "[" << type
->get_dimension(n
) << "]"; 
 451       //      printf("checking (%s) : %s\n",origarr,tempastr.get()); 
 452       type
->arraystr 
= tempastr
.get(); 
 453       key 
= typemap_string(lang
,type
,pname
,type
->arraystr
,op
); 
 454       tm 
= typemap_search(key
,type
->id
); 
 456         key 
= typemap_string(lang
,type
,"",type
->arraystr
,op
); 
 457         tm 
= typemap_search(key
,type
->id
); 
 459       type
->arraystr 
= origarr
; 
 467     ndim 
= type
->array_dimensions(); 
 468     for (i 
= 0; i 
< ndim
; i
++) { 
 469       sprintf(temp
,"$dim%d",i
); 
 470       str
.replace(temp
,type
->get_dimension(i
)); 
 476 // ------------------------------------------------------------------------ 
 477 // static typemap_locals(Datatype *t, char *pname, String &s, ParmList *l, WrapperFunction &f) 
 479 // Takes a string, a parameter list and a wrapper function argument and 
 480 // starts creating local variables. 
 482 // Substitutes locals in the string with actual values used. 
 483 // ------------------------------------------------------------------------ 
 485 static void typemap_locals(DataType 
*t
, char *pname
, String 
&s
, ParmList 
*l
, WrapperFunction 
&f
) { 
 492       if (strlen(p
->name
) > 0) { 
 496         // If the user gave us $type as the name of the local variable, we'll use 
 497         // the passed datatype instead 
 499         if (strcmp(p
->t
->name
,"$type")==0 || strcmp(p
->t
->name
,"$basetype")==0) { 
 505         // Have a real parameter here 
 508           str 
<< p
->name 
<< tt
->arraystr
; 
 514         // Substitute parameter names 
 515         str
.replace("$arg",pname
); 
 516         if (strcmp(p
->t
->name
,"$basetype")==0) { 
 518           char temp_ip 
= tt
->is_pointer
; 
 519           char temp_ip1 
= tt
->implicit_ptr
; 
 521           tt
->implicit_ptr 
= 0; 
 522           new_name 
= f
.new_local(tt
->print_type(),str
); 
 523           tt
->is_pointer 
= temp_ip
; 
 524           tt
->implicit_ptr 
= temp_ip1
; 
 527           new_name 
= f
.new_local(tt
->print_full(),str
); 
 529         if (tt
->arraystr
) tt
->is_pointer
++; 
 531         s
.replaceid(p
->name
,new_name
); 
 536   // If the original datatype was an array. We're going to go through and substitute 
 537   // it's array dimensions 
 541     for (int i 
= 0; i 
< t
->array_dimensions(); i
++) { 
 542       sprintf(temp
,"$dim%d",i
); 
 543       f
.locals
.replace(temp
,t
->get_dimension(i
)); 
 549 // ------------------------------------------------------------------------ 
 550 // char *typemap_lookup(char *op, char *lang, DataType *type, char *pname, char *source, 
 551 //                      char *target, WrapperFunction *f) 
 553 // Looks up a "get" function in the type-map and returns a character string 
 554 // containing the appropriate translation code. 
 556 // op       is string code for type of mapping 
 557 // lang     is the target language string 
 558 // type     is the datatype 
 559 // pname    is an optional parameter name 
 560 // source   is a string with the source variable 
 561 // target   is a string containing the target value 
 562 // f        is a wrapper function object (optional) 
 564 // Returns NULL if no mapping is found. 
 566 // Typemaps follow a few rules regarding naming and C pointers by checking 
 567 // declarations in this order. 
 569 //         1.   type name []         - A named array (most specific) 
 570 //         2.   type name            - Named argument 
 571 //         3.   type []              - Type with array 
 572 //         4.   type                 - Ordinary type 
 574 // Array checking is only made if the datatype actally has an array specifier       
 576 // Array checking uses a special token "ANY" that indicates that any 
 577 // dimension will match.  Since we are passed a real datatype here, we 
 578 // need to hack this a special case. 
 580 // Array dimensions are substituted into the variables $dim1, $dim2,...,$dim9 
 581 // ------------------------------------------------------------------------ 
 583 static DataType 
*realtype
;       // This is a gross hack 
 584 static char     *realname 
= 0;   // Real parameter name 
 586 char *typemap_lookup_internal(char *op
, char *lang
, DataType 
*type
, char *pname
, char *source
, 
 587                      char *target
, WrapperFunction 
*f
) { 
 596   // First check for named array 
 598   tm 
= typemap_search_array(op
,lang
,type
,pname
,str
); 
 600   // Check for named argument 
 602     key 
= typemap_string(lang
,type
,pname
,0,op
); 
 603     tm 
= typemap_search(key
,type
->id
); 
 608   // Check for unnamed type 
 610     key 
= typemap_string(lang
,type
,"",0,op
); 
 611     tm 
= typemap_search(key
,type
->id
); 
 617   // Now perform character replacements 
 619   str
.replace("$source",source
); 
 620   str
.replace("$target",target
); 
 621   str
.replace("$type", realtype
->print_type()); 
 623     str
.replace("$parmname", realname
); 
 625     str
.replace("$parmname",""); 
 627   // Print base type (without any pointers) 
 629     char temp_ip 
= realtype
->is_pointer
; 
 630     char temp_ip1 
= realtype
->implicit_ptr
; 
 631     realtype
->is_pointer 
= 0; 
 632     realtype
->implicit_ptr 
= 0; 
 633     char *bt 
= realtype
->print_type(); 
 634     if (bt
[strlen(bt
)-1] == ' ')  
 635       bt
[strlen(bt
)-1] = 0; 
 636     str
.replace("$basetype",bt
); 
 637     str
.replace("$basemangle",realtype
->print_mangle()); 
 638     realtype
->is_pointer 
= temp_ip
; 
 639     realtype
->implicit_ptr 
= temp_ip1
; 
 642   str
.replace("$mangle",realtype
->print_mangle()); 
 644   // If there were locals and a wrapper function, replace 
 645   if ((tm
->args
) && f
) { 
 646     typemap_locals(realtype
, pname
, str
,tm
->args
,*f
); 
 649   // If there were locals and no wrapper function, print a warning 
 650   if ((tm
->args
) && !f
) { 
 651     if (!pname
) pname 
= ""; 
 652     fprintf(stderr
,"%s:%d: Warning. '%%typemap(%s,%s) %s %s' being applied with ignored locals.\n", 
 653             input_file
, line_number
, lang
,op
, type
->print_type(), pname
); 
 656   // Return character string 
 661 // ---------------------------------------------------------- 
 662 // Real function call that takes care of application mappings 
 663 // ---------------------------------------------------------- 
 665 char *typemap_lookup(char *op
, char *lang
, DataType 
*type
, char *pname
, char *source
, 
 666                      char *target
, WrapperFunction 
*f
) { 
 673   realtype 
= type
;         // The other half of the gross hack 
 676   // Try to apply typemap right away 
 678   result 
= typemap_lookup_internal(op
,lang
,type
,pname
,source
,target
,f
); 
 680   // If not found, try to pick up anything that might have been 
 681   // specified with %apply 
 683   if ((!result
) && (pname
)) { 
 684     int drop_pointer 
= 0; 
 686     if (!ppname
) ppname 
= ""; 
 688     // The idea : We're going to cycle through applications and 
 689     // drop pointers off until we get a match.    
 691     while (drop_pointer 
<= (type
->is_pointer 
- type
->implicit_ptr
)) { 
 692       type
->is_pointer 
-= drop_pointer
; 
 693       tstr 
= type
->print_type(); 
 694       sprintf(temp
,"%s$%s",tstr
,ppname
); 
 695       // No mapping was found.  See if the name has been mapped with %apply 
 696       m 
= (TmMethod 
*) application_hash
.lookup(temp
); 
 698         sprintf(temp
,"%s$",tstr
); 
 699         m 
= (TmMethod 
*) application_hash
.lookup(temp
); 
 705           static String newarray
; 
 706           if (*(m
->name
)) ppname 
= m
->name
; 
 708           m
->type
->is_pointer 
+= drop_pointer
; 
 710           // Copy old array string (just in case) 
 712           oldary 
= m
->type
->arraystr
;  
 714           // If the mapping type is an array and has the 'ANY' keyword, we 
 715           // have to play some magic 
 717           if ((m
->type
->arraystr
) && (type
->arraystr
)) { 
 718             // Build up the new array string 
 720             for (int n 
= 0; n 
< m
->type
->array_dimensions(); n
++) { 
 721               char *d 
= m
->type
->get_dimension(n
); 
 722               if (strcmp(d
,"ANY") == 0) { 
 723                 newarray 
<< "[" << type
->get_dimension(n
) << "]"; 
 725                 newarray 
<< "[" << d 
<< "]"; 
 728             m
->type
->arraystr 
= newarray
.get(); 
 729           } else if (type
->arraystr
) { 
 730             // If an array string is available for the current datatype, 
 731             // make it available. 
 732             m
->type
->arraystr 
= type
->arraystr
; 
 734           result 
= typemap_lookup_internal(op
,lang
,m
->type
,ppname
,source
,target
,f
); 
 735           m
->type
->arraystr 
= oldary
; 
 736           m
->type
->is_pointer 
-= drop_pointer
; 
 738             type
->is_pointer 
+= drop_pointer
; 
 744       type
->is_pointer 
+= drop_pointer
; 
 748   // Still no idea, try to find a default typemap 
 751     DataType 
*t 
= new DataType(type
); 
 752     t
->primitive(); // Knock it down to its basic type 
 753     result 
= typemap_lookup_internal(op
,lang
,t
,"SWIG_DEFAULT_TYPE",source
,target
,f
); 
 758     if ((t
->type 
== T_USER
) || (t
->is_pointer
)) { 
 759       if ((t
->type 
== T_CHAR
) && (t
->is_pointer 
== 1)) return 0; 
 761       // Still no result, go even more primitive 
 764       if (t
->arraystr
) delete [] t
->arraystr
; 
 767       result 
= typemap_lookup_internal(op
,lang
,t
,"SWIG_DEFAULT_TYPE",source
,target
,f
); 
 774 // ---------------------------------------------------------------------------- 
 775 // char *typemap_check(char *op, char *lang, DataType *type, char *pname) 
 777 // Checks to see if there is a typemap.  Returns typemap string if found, NULL 
 779 // ---------------------------------------------------------------------------- 
 781 char *typemap_check_internal(char *op
, char *lang
, DataType 
*type
, char *pname
) { 
 789   // First check for named array 
 791   tm 
= typemap_search_array(op
,lang
,type
,pname
,str
); 
 793   // First check for named array 
 795   //  if (type->arraystr) { 
 796   //    key = typemap_string(lang,type,pname,type->arraystr,op); 
 797   //    tm = typemap_search(key,type->id); 
 800   // Check for named argument 
 802     key 
= typemap_string(lang
,type
,pname
,0,op
); 
 803     tm 
= typemap_search(key
,type
->id
); 
 806   // Check for unnamed array 
 807   if ((!tm
) && (type
->arraystr
)) { 
 808     key 
= typemap_string(lang
,type
,"",type
->arraystr
,op
); 
 809     tm 
= typemap_search(key
,type
->id
); 
 812   // Check for unname type 
 814     key 
= typemap_string(lang
,type
,"",0,op
); 
 815     tm 
= typemap_search(key
,type
->id
); 
 822   // Return character string 
 827 // Function for checking with applications 
 829 char *typemap_check(char *op
, char *lang
, DataType 
*type
, char *pname
) { 
 835   // Try to apply typemap right away 
 837   result 
= typemap_check_internal(op
,lang
,type
,pname
); 
 840     int drop_pointer 
= 0; 
 842     if (!ppname
) ppname 
= ""; 
 844     // The idea : We're going to cycle through applications and 
 845     // drop pointers off until we get a match.    
 847     while (drop_pointer 
<= (type
->is_pointer 
- type
->implicit_ptr
)) { 
 848       type
->is_pointer 
-= drop_pointer
; 
 849       tstr 
= type
->print_type(); 
 850       sprintf(temp
,"%s$%s",tstr
,ppname
); 
 851       // No mapping was found.  See if the name has been mapped with %apply 
 852       m 
= (TmMethod 
*) application_hash
.lookup(temp
); 
 854         sprintf(temp
,"%s$",tstr
); 
 855         m 
= (TmMethod 
*) application_hash
.lookup(temp
); 
 861           static String newarray
; 
 862           if (*(m
->name
)) ppname 
= m
->name
; 
 864           m
->type
->is_pointer 
+= drop_pointer
; 
 865           oldary 
= m
->type
->arraystr
; 
 867           // If the mapping type is an array and has the 'ANY' keyword, we 
 868           // have to play some magic 
 870           if ((m
->type
->arraystr
) && (type
->arraystr
)) { 
 871             // Build up the new array string 
 873             for (int n 
= 0; n 
< m
->type
->array_dimensions(); n
++) { 
 874               char *d 
= m
->type
->get_dimension(n
); 
 875               if (strcmp(d
,"ANY") == 0) { 
 876                 newarray 
<< "[" << type
->get_dimension(n
) << "]"; 
 878                 newarray 
<< "[" << d 
<< "]"; 
 881             oldary 
= m
->type
->arraystr
; 
 882             m
->type
->arraystr 
= newarray
.get(); 
 883           } else if (type
->arraystr
) { 
 884             m
->type
->arraystr 
= type
->arraystr
; 
 886           result 
= typemap_check_internal(op
,lang
,m
->type
,ppname
); 
 887           m
->type
->arraystr 
= oldary
; 
 888           m
->type
->is_pointer 
-= drop_pointer
; 
 890             type
->is_pointer 
+= drop_pointer
; 
 896       type
->is_pointer 
+= drop_pointer
; 
 901   // If still no result, might have a default typemap 
 903     DataType 
*t 
= new DataType(type
); 
 904     t
->primitive(); // Knock it down to its basic type 
 905     result 
= typemap_check_internal(op
,lang
,t
,"SWIG_DEFAULT_TYPE"); 
 910     if ((t
->type 
== T_USER
) || (t
->is_pointer
)) { 
 911       if ((t
->type 
== T_CHAR
) && (t
->is_pointer 
== 1)) return 0; 
 912       // Still no result, go even more primitive 
 915       if (t
->arraystr
) delete [] t
->arraystr
; 
 918       result 
= typemap_check_internal(op
,lang
,t
,"SWIG_DEFAULT_TYPE"); 
 925 // ------------------------------------------------------------------------ 
 926 // void typemap_clear(char *op, char *lang, DataType *type, char *pname) 
 928 // Clears any previous typemap.   This works like a stack.  Clearing a 
 929 // typemap returns to any previous typemap in force.   If there is no 
 930 // previous map, then don't worry about it. 
 931 // ------------------------------------------------------------------------ 
 933 void typemap_clear(char *op
, char *lang
, DataType 
*type
, char *pname
) { 
 938   key 
= typemap_string(lang
,type
,pname
,type
->arraystr
,op
); 
 940   // Look for any previous version, simply set the last id if 
 943   tm 
= (TypeMap 
*) typemap_hash
.lookup(key
); 
 945     if (tm
->last 
> type_id
) tm
->last 
= type_id
; 
 949 // ------------------------------------------------------------------------ 
 950 // void typemap_copy(char *op, char *lang, DataType *stype, char *sname, 
 951 //                   DataType *ttype, char *tname) 
 953 // Copies the code associate with a typemap 
 954 // ------------------------------------------------------------------------ 
 956 void typemap_copy(char *op
, char *lang
, DataType 
*stype
, char *sname
, 
 957                       DataType 
*ttype
, char *tname
) { 
 960   TypeMap  
*tm
, *tk
, *tn
; 
 962   // Try to locate a previous typemap 
 964   key 
= typemap_string(lang
,stype
,sname
,stype
->arraystr
,op
); 
 965   tm 
= typemap_search(key
,stype
->id
); 
 967   if (strcmp(ttype
->name
,"PREVIOUS") == 0) { 
 968     // Pop back up to the previous typemap (if any) 
 971       tn 
= new TypeMap(tk
);       // Make a copy of the previous typemap 
 972       tn
->next 
= tm
;              // Set up symlinks 
 973       typemap_hash
.remove(key
);   // Remove old hash entry 
 974       typemap_hash
.add(key
,(void *) tn
); 
 977     typemap_register(op
,lang
,ttype
,tname
,tm
->code
,tm
->args
); 
 981 // ------------------------------------------------------------------------ 
 982 // char *fragment_string(char *op, char *lang) 
 984 // Produces a character string corresponding to a language and method 
 985 // This string is used as the key for our typemap hash table. 
 986 // ------------------------------------------------------------------------ 
 988 static char *fragment_string(char *op
, char *lang
) { 
 993   str 
<< "fragment:" << lang 
<< op
; 
 997 // ------------------------------------------------------------------------ 
 998 // void fragment_register(char *op, char *lang, char *code) 
1000 // Register a code fragment with the type-mapper. 
1001 // ------------------------------------------------------------------------ 
1003 void fragment_register(char *op
, char *lang
, char *code
) { 
1006   TypeMap  
*tm
,*tm_old
; 
1009   tm 
= new TypeMap(lang
,code
); 
1010   key 
= fragment_string(op
,lang
); 
1012   // Get any previous setting of the typemap 
1014   tm_old 
= (TypeMap 
*) typemap_hash
.lookup(key
); 
1016     // If found, we need to attach the old version to the new one 
1018     // Perform a chaining operation  
1020     sprintf(temp
,"$%s",op
); 
1021     if (type_id 
< tm_old
->last
) 
1022       tm
->code
.replace(temp
,tm_old
->code
); 
1025     tm_old
->last 
= type_id
; 
1027     // Remove the old one from the hash 
1029     typemap_hash
.remove(key
); 
1032   // Perform a default chaining operation if needed (defaults to nothing) 
1033   sprintf(temp
,"$%s",op
); 
1034   tm
->code
.replace(temp
,""); 
1036   // Add new typemap to the hash table 
1037   typemap_hash
.add(key
,(void *) tm
); 
1042 // ------------------------------------------------------------------------ 
1043 // char *fragment_lookup(char *op, char *lang, int age) 
1045 // op       is string code for type of mapping 
1046 // lang     is the target language string 
1047 // age      is age of fragment. 
1049 // Returns NULL if no mapping is found. 
1051 // ------------------------------------------------------------------------ 
1053 char *fragment_lookup(char *op
, char *lang
, int age
) { 
1063   key 
= fragment_string(op
,lang
); 
1064   tm 
= typemap_search(key
,age
); 
1072 // ------------------------------------------------------------------------ 
1073 // void fragment_clear(char *op, char *lang) 
1075 // Clears any previous fragment definition.   Is a stack operation--will 
1076 // restore any previously declared typemap. 
1077 // ------------------------------------------------------------------------ 
1079 void fragment_clear(char *op
, char *lang
) { 
1084   key 
= fragment_string(op
,lang
); 
1086   // Look for any previous version, simply set the last id if 
1089   tm 
= (TypeMap 
*) typemap_hash
.lookup(key
); 
1091     if (tm
->last 
> type_id
) tm
->last 
= type_id
;