]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/wxSWIG/SWIG/emit.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  *******************************************************************************/ 
  17 /******************************************************************************* 
  22  * This file contains some useful functions for emitting code that would be 
  23  * common to all of the interface languages.  Mainly this function deals with 
  24  * declaring functions external, creating lists of arguments, and making 
  26  *******************************************************************************/ 
  28 // ----------------------------------------------------------------------------- 
  29 // void emit_banner(FILE *f) 
  31 // Emits the SWIG identifying banner in the wrapper file 
  33 // Inputs : f   = FILE handle 
  37 // Side Effects : None 
  38 // ----------------------------------------------------------------------------- 
  40 void emit_banner(FILE *f
) { 
  42   extern char *get_time(); 
  43   extern char fn_header
[]; 
  49  * This file was automatically generated by :\n\ 
  50  * Simplified Wrapper and Interface Generator (SWIG)\n\ 
  53  * Portions Copyright (c) 1995-1998\n\ 
  54  * The University of Utah and The Regents of the University of California.\n\ 
  55  * Permission is granted to distribute this file in any manner provided\n\ 
  56  * this notice remains intact.\n\ 
  58  * Do not make changes to this file--changes will be lost!\n\ 
  60  */\n\n", fn_header
, SWIG_MAJOR_VERSION
, SWIG_MINOR_VERSION
, SWIG_SPIN
); 
  62   fprintf(f
,"\n#define SWIGCODE\n"); 
  66 // ----------------------------------------------------------------------------- 
  67 // emit_extern_var(char *decl, DataType *t, int extern_type, FILE *f) 
  69 // Emits an external variables declaration.   Extern_type defines the 
  70 // type of external declaration.  Currently, only C/C++ declarations 
  71 // are allowed, but this might be extended to allow Fortran linkage 
  75 //          decl        = Name of the declaration 
  77 //          extern_type = Numeric code indicating type of extern 
  79 //                              1,2 -  Normal extern (C/C++) 
  84 // Side Effects : None 
  85 // ----------------------------------------------------------------------------- 
  87 void emit_extern_var(char *decl
, DataType 
*t
, int extern_type
, FILE *f
) { 
  90   if (t
->arraystr
) arr 
= t
->arraystr
; 
  96     // No extern.  Just a forward reference 
 100     if (t
->is_reference
) { 
 102       fprintf(f
,"%s& %s%s; \n", t
->print_full(), decl
, arr
); 
 105       fprintf(f
,"%s %s%s; \n", t
->print_full(), decl
,arr
); 
 114     // Normal C/C++ extern 
 115 //    fprintf(f,"#line %d \"%s\"\n", line_number, input_file); 
 116     if (t
->is_reference
) { 
 118       fprintf(f
,"extern %s& %s%s; \n", t
->print_full(), decl
,arr
); 
 121       fprintf(f
,"extern %s %s%s; \n", t
->print_full(), decl
,arr
); 
 131 // ----------------------------------------------------------------------------- 
 132 // emit_extern_func(char *decl, DataType *t, ParmList *L, int extern_type, 
 135 // Emits an external function declaration (similiar to emit_extern_var). 
 138 //          decl        = Name of declaration 
 139 //          t           = Return datatype 
 140 //          L           = parameter list 
 141 //          extern_type = Type of extern 
 145 //                           3 - Function declaration (with arg names) 
 150 // Side Effects : None 
 152 // ----------------------------------------------------------------------------- 
 154 void emit_extern_func(char *decl
, DataType 
*t
, ParmList 
*L
, int extern_type
, FILE *f
) { 
 156   switch(extern_type
) { 
 158     if (t
->is_reference
) { 
 160         fprintf(f
,"%s&", t
->print_full()); 
 163       fprintf(f
,"%s", t
->print_full()); 
 166     fprintf(f
,"%s(", decl
); 
 171     // Normal C/C++ extern 
 172 //    fprintf(f,"#line %d \"%s\"\n", line_number, input_file); 
 173     if (t
->is_reference
) { 
 175         fprintf(f
,"extern %s&", t
->print_full()); 
 178       fprintf(f
,"extern %s", t
->print_full()); 
 180     fprintf(f
,"%s(", decl
); 
 185     // A C++ --- > C Extern 
 186 //    fprintf(f,"#line %d \"%s\"\n", line_number, input_file); 
 187     if (t
->is_reference
) { 
 189         fprintf(f
,"extern \"C\" %s&", t
->print_full()); 
 192       fprintf(f
,"extern \"C\" %s", t
->print_full()); 
 194     fprintf(f
,"%s(", decl
); 
 199     // A function declaration (for inlining ) 
 200     if (t
->is_reference
) { 
 202         fprintf(f
,"%s&", t
->print_full()); 
 205       fprintf(f
,"%s", t
->print_full()); 
 208     fprintf(f
,"%s(", decl
); 
 217 // ----------------------------------------------------------------------------- 
 218 // char *emit_local(int i) 
 220 // Returns the name of local variable for parameter i 
 222 // Inputs : i      = Parameter number 
 224 // Output : NULL terminated ASCII string 
 226 // Side Effects : Result is left in a static local variable. 
 227 // ----------------------------------------------------------------------------- 
 229 char *emit_local(int i
) { 
 232   sprintf(arg
,"_arg%d", i
); 
 236 // ----------------------------------------------------------------------------- 
 237 // int emit_args(char *d, DataType *rt, ParmList *l, FILE *f) 
 239 // Creates a list of variable declarations for both the return value 
 240 // and function parameters. 
 242 // The return value is always called _result and arguments label as 
 243 // _arg0, _arg1, _arg2, etc... 
 245 // Returns the number of parameters associated with a function. 
 248 //          d     = Name of function 
 250 //          l     = Parameter list 
 253 // Output : Number of function arguments  
 255 // Side Effects : None 
 257 // Note : This function is obsolete.  Use emit_args below... 
 258 // ----------------------------------------------------------------------------- 
 260 int emit_args(DataType 
*rt
, ParmList 
*l
, FILE *f
) { 
 268   // Declare the return variable 
 270   if ((rt
->type 
!= T_VOID
) || (rt
->is_pointer
)) { 
 271     if ((rt
->type 
== T_USER
) && (!rt
->is_pointer
)) { 
 273       // Special case for return by "value" 
 276       fprintf(f
,"\t %s _result;\n", rt
->print_type()); 
 280       // Normal return value 
 282       fprintf(f
,"\t %s _result;\n", rt
->print_type()); 
 286   // Emit function arguments 
 291     if ((p
->t
->type 
!= T_VOID
) || (p
->t
->is_pointer
))  { 
 292       sprintf(temp
,"_arg%d", i
); 
 294         if ((p
->t
->is_reference
) || ((p
->t
->type 
== T_USER
) && (p
->call_type 
== CALL_REFERENCE
))) 
 295             fprintf(f
,"\t %s _arg%d = &%s;\n", p
->t
->print_type(),i
, p
->defvalue
); 
 297             fprintf(f
,"\t %s _arg%d = %s;\n", p
->t
->print_type(),i
, p
->defvalue
); 
 299         fprintf(f
,"\t %s _arg%d;\n", p
->t
->print_type(),i
); 
 300         tm 
= typemap_lookup("arginit", typemap_lang
, p
->t
, p
->name
,"",temp
); 
 306       // Check for ignore or default typemaps 
 308       tm 
= typemap_lookup("default",typemap_lang
,p
->t
,p
->name
,"",temp
); 
 311       tm 
= typemap_lookup("ignore",typemap_lang
,p
->t
,p
->name
,"",temp
); 
 317       tm 
= typemap_check("build",typemap_lang
,p
->t
,p
->name
); 
 326   fprintf(f
,"%s",def
.get()); 
 328   // i now contains number of parameters 
 335 // ----------------------------------------------------------------------------- 
 336 // int emit_args(char *d, DataType *rt, ParmList *l, WrapperFunction &f) 
 338 // Creates a list of variable declarations for both the return value 
 339 // and function parameters. 
 341 // The return value is always called _result and arguments label as 
 342 // _arg0, _arg1, _arg2, etc... 
 344 // Returns the number of parameters associated with a function. 
 347 //          d     = Name of function 
 349 //          l     = Parameter list 
 350 //          f     = Wrapper function object 
 352 // Output : Number of function arguments  
 354 // Side Effects : None 
 356 // ----------------------------------------------------------------------------- 
 358 int emit_args(DataType 
*rt
, ParmList 
*l
, WrapperFunction 
&f
) { 
 364   // Declare the return variable 
 366   if ((rt
->type 
!= T_VOID
) || (rt
->is_pointer
)) { 
 367     if ((rt
->type 
== T_USER
) && (!rt
->is_pointer
)) { 
 369       // Special case for return by "value" 
 371       f
.add_local(rt
->print_type(), "_result"); 
 375       // Normal return value 
 377       f
.add_local(rt
->print_type(), "_result"); 
 381   // Emit function arguments 
 386     if ((p
->t
->type 
!= T_VOID
) || (p
->t
->is_pointer
))  { 
 387       char *temp 
= emit_local(i
); 
 388       // Figure out default values 
 389       if (((p
->t
->is_reference
) && (p
->defvalue
)) ||  
 390           ((p
->t
->type 
== T_USER
) && (p
->call_type 
== CALL_REFERENCE
) && (p
->defvalue
))) { 
 392         deftmp 
<< "(" << p
->t
->print_type() << ") &" << p
->defvalue
; 
 393         f
.add_local(p
->t
->print_type(),temp
,deftmp
.get()); 
 398           deftmp 
<< "(" << p
->t
->print_type() << ") " << p
->defvalue
; 
 401         f
.add_local(p
->t
->print_type(), temp
, dv
); 
 402         tm 
= typemap_lookup("arginit", typemap_lang
, p
->t
,p
->name
,"",temp
,&f
); 
 404           f
.code 
<< tm 
<< "\n"; 
 407       // Check for ignore or default typemaps 
 408       tm 
= typemap_lookup("default",typemap_lang
,p
->t
,p
->name
,"",temp
,&f
); 
 410         f
.code 
<< tm 
<< "\n"; 
 411       tm 
= typemap_lookup("ignore",typemap_lang
,p
->t
,p
->name
,"",temp
,&f
); 
 413         f
.code 
<< tm 
<< "\n"; 
 416       tm 
= typemap_check("build",typemap_lang
,p
->t
,p
->name
); 
 425   // i now contains number of parameters 
 429 // ----------------------------------------------------------------------------- 
 430 // int emit_func_call(char *decl, DataType *t, ParmList *l, FILE *f) 
 432 // Emits code for a function call. 
 435 //           decl   = name of function 
 436 //           t      = Return datatype 
 437 //           l      = Parameter list 
 442 // Side Effects : None 
 444 // Note : This function is obsolete 
 445 // ----------------------------------------------------------------------------- 
 447 void emit_func_call(char *decl
, DataType 
*t
, ParmList 
*l
, FILE *f
) { 
 452 //  fprintf(f,"#line %d \"%s\"\n", line_number, input_file); 
 455   // First check if there is a return value 
 457   if ((t
->type 
!= T_VOID
) || (t
->is_pointer
)) { 
 458     if ((t
->type 
== T_USER
) && (!t
->is_pointer
)) { 
 460       // Special case for return by "value" 
 461       // Caution : This *will* cause a memory leak if not 
 465         fprintf(f
,"_result = new %s(", t
->print_type()); 
 468         fprintf(f
,"_result = %s malloc(sizeof(", t
->print_cast()); 
 470         fprintf(f
,"%s));\n", t
->print_type()); 
 471         fprintf(f
,"\t*(_result) = "); 
 474       // Check if this is a C++ reference 
 475       if (t
->is_reference
) { 
 477         fprintf(f
,"%s& _result_ref = ", t
->print_full()); 
 481       // Normal return values 
 482         fprintf(f
,"_result = %s", t
->print_cast()); 
 487   // Now print out function call 
 489   fprintf(f
,"%s(",decl
); 
 494     if ((p
->t
->type 
!= T_VOID
) || (p
->t
->is_pointer
)){ 
 495       fprintf(f
,"%s",p
->t
->print_arraycast()); 
 496       if ((!p
->t
->is_reference
) && (p
->call_type 
& CALL_VALUE
)) fprintf(f
,"&"); 
 497       if ((!(p
->call_type 
& CALL_VALUE
)) && 
 498           ((p
->t
->is_reference
) || (p
->call_type 
& CALL_REFERENCE
))) 
 500       fprintf(f
,"_arg%d",i
); 
 509   if ((t
->type 
== T_USER
) && (!t
->is_pointer
)) { 
 515   if (t
->is_reference
) { 
 516     fprintf(f
,"\t _result = %s &_result_ref;\n", t
->print_cast()); 
 522 // ----------------------------------------------------------------------------- 
 523 // int emit_func_call(char *decl, DataType *t, ParmList *l, WrapperFunction &f) 
 525 // Emits code for a function call (new version). 
 527 // Exception handling support : 
 529 //     -  This function checks to see if any sort of exception mechanism 
 530 //        has been defined.  If so, we emit the function call in an exception 
 534 //           decl   = name of function 
 535 //           t      = Return datatype 
 536 //           l      = Parameter list 
 537 //           f      = WrapperFunction object 
 541 // Side Effects : None 
 543 // ----------------------------------------------------------------------------- 
 545 void emit_func_call(char *decl
, DataType 
*t
, ParmList 
*l
, WrapperFunction 
&f
) { 
 553 //  f.code << "#line " << line_number << " \"" << input_file << "\"\n"; 
 556   // First check if there is a return value 
 558   if ((t
->type 
!= T_VOID
) || (t
->is_pointer
)) { 
 559     if ((t
->type 
== T_USER
) && (!t
->is_pointer
)) { 
 561       // Special case for return by "value" 
 562       // Caution : This *will* cause a memory leak if not 
 566         fcall 
<< "_result = new " << t
->print_type() << "("; 
 569         fcall 
<< "_result = " << t
->print_cast() << " malloc(sizeof("; 
 571         fcall 
<< t
->print_type() << "));\n"; 
 572         fcall 
<< tab4 
<< "*(_result) = "; 
 575       // Check if this is a C++ reference 
 576       if (t
->is_reference
) { 
 578         fcall 
<< t
->print_full() << "& _result_ref = "; 
 582         // Normal return value 
 583         fcall 
<< "_result = " << t
->print_cast(); 
 588   // Now print out function call 
 590   fcall 
<< decl 
<< "("; 
 595     if ((p
->t
->type 
!= T_VOID
) || (p
->t
->is_pointer
)){ 
 596       fcall 
<< p
->t
->print_arraycast(); 
 597       if ((!p
->t
->is_reference
) && (p
->call_type 
& CALL_VALUE
)) 
 599       if ((!(p
->call_type 
& CALL_VALUE
)) && 
 600           ((p
->t
->is_reference
) || (p
->call_type 
& CALL_REFERENCE
))) 
 602       fcall 
<< emit_local(i
); 
 611   if ((t
->type 
== T_USER
) && (!t
->is_pointer
)) { 
 618   if (t
->is_reference
) { 
 619     fcall 
<< tab4 
<< "_result = "<< t
->print_cast() << " &_result_ref;\n"; 
 621   // Check for exception handling 
 623   if ((tm 
= typemap_lookup("except",typemap_lang
,t
,decl
,"_result",""))) { 
 624     // Found a type-specific mapping 
 626     exc
.replace("$function",fcall
); 
 627     exc
.replace("$name",decl
); 
 629   } else if ((tm 
= fragment_lookup("except",typemap_lang
, t
->id
))) { 
 631     exc
.replace("$function",fcall
); 
 632     exc
.replace("$name",decl
); 
 639 // ----------------------------------------------------------------------------- 
 640 // void emit_hex(FILE *f) 
 642 // Emits the default C-code to handle pointers.   This is normally contained 
 643 // in the SWIG library file 'swigptr.swg' 
 645 // Inputs : f   = FILE handle 
 649 // Side Effects : None 
 650 // ----------------------------------------------------------------------------- 
 652 void emit_hex(FILE *f
) { 
 656    // Look for a pointer configuration file 
 658    stat 
= insert_file("swigptr.swg", f
); 
 661      fprintf(stderr
,"** Fatal error.  Unable to locate 'swigptr.swg'\n"); 
 666 // ----------------------------------------------------------------------------- 
 667 // void emit_set_get(char *name, char *iname, DataType *type) 
 669 // Emits a pair of functions to set/get the value of a variable. 
 670 // This should be used as backup in case the target language can't 
 671 // provide variable linking. 
 675 // Gets translated into the following : 
 677 // double foo_set(double x) { 
 681 // double foo_get() { 
 685 // Need to handle special cases for char * and for user 
 690 //     Will free previous contents (if any) and allocate 
 691 //     new storage.   Could be risky, but it's a reasonably 
 692 //     natural thing to do. 
 695 //     Will assign value from a pointer.  
 696 //     Will return a pointer to current value. 
 700 //          name    = Name of variable 
 701 //          iname   = Renamed version of variable 
 702 //          type    = Datatype of the variable 
 706 // Side Effects : None 
 707 // ----------------------------------------------------------------------------- 
 709 void emit_set_get(char *name
, char *iname
, DataType 
*t
) { 
 717     // First write a function to set the variable of the variable 
 719     if (!(Status 
& STAT_READONLY
)) { 
 720       if ((t
->type 
== T_USER
) && (!t
->is_pointer
)) { 
 722         fprintf(f_header
,"static %s %s(%s val) {\n", 
 723                 t
->print_type(), name_set(name
), t
->print_type()); 
 726         fprintf(f_header
,"static %s %s(%s val) {\n", 
 727                 t
->print_type(), name_set(name
), t
->print_type()); 
 730       if ((t
->type 
!= T_VOID
) || (t
->is_pointer
)) { 
 731         if (!t
->is_pointer
) { 
 733           // Have a real value here  
 734           // If it's a user defined type, we'll do something special. 
 735           // Otherwise, just assign it. 
 737           if (t
->type 
!= T_USER
) { 
 738             fprintf(f_header
,"\t return (%s) (%s = val);\n", t
->print_type(), name
); 
 740             fprintf(f_header
,"\t %s = *(val);\n", name
); 
 742             fprintf(f_header
,"\t return (%s) &%s;\n", t
->print_type(),name
); 
 747           // Is a pointer type here.  If string, we do something 
 748           // special.  Otherwise. No problem. 
 750           if ((t
->type 
== T_CHAR
) && (t
->is_pointer 
== 1)) { 
 752               fprintf(f_header
,"\t if (%s) delete %s;\n", name
,name
); 
 753               fprintf(f_header
,"\t %s = new char[strlen(val)+1];\n",name
); 
 754               fprintf(f_header
,"\t strcpy(%s,val);\n", name
); 
 755               fprintf(f_header
,"\t return %s;\n", name
); 
 757               fprintf(f_header
,"\t if (%s) free(%s);\n", name
,name
); 
 758               fprintf(f_header
,"\t %s = (char *) malloc(strlen(val)+1);\n",name
); 
 759               fprintf(f_header
,"\t strcpy(%s,val);\n", name
); 
 760               fprintf(f_header
,"\t return %s;\n", name
); 
 763             fprintf(f_header
,"\t return (%s) (%s = val);\n", t
->print_type(), name
); 
 768       fprintf(f_header
,"}\n"); 
 774       if ((t
->type 
== T_USER
) && (!t
->is_pointer
)) p
->t
->is_pointer
++; 
 775       p
->name 
= new char[1]; 
 779       new_name 
= name_set(name
); 
 780       new_iname 
= name_set(iname
); 
 782       if ((t
->type 
== T_USER
) && (!t
->is_pointer
)) { 
 784         lang
->create_function(new_name
, new_iname
, t
, l
); 
 787         lang
->create_function(new_name
, new_iname
, t
, l
); 
 791       if (doc_entry
) doc_entry
->usage 
<< "\n"; 
 794     // Now write a function to get the value of the variable 
 796     if ((t
->type 
== T_USER
) && (!t
->is_pointer
)) { 
 798       fprintf(f_header
,"static %s %s() { \n", 
 799               t
->print_type(), name_get(name
)); 
 800       fprintf(f_header
,"\t return (%s) &%s;\n", t
->print_type(), name
); 
 803       fprintf(f_header
,"static %s %s() { \n", 
 804               t
->print_type(), name_get(name
)); 
 805       fprintf(f_header
,"\t return (%s) %s;\n", t
->print_type(), name
); 
 808     fprintf(f_header
,"}\n"); 
 810     // Wrap this function 
 814     new_name 
= name_get(name
); 
 815     new_iname 
= name_get(iname
); 
 817     if ((t
->type 
== T_USER
) && (!t
->is_pointer
)) { 
 819       lang
->create_function(new_name
, new_iname
, t
, l
); 
 822       lang
->create_function(new_name
, new_iname
, t
, l
);