special cases and other things in wxPython, and since I plan on making several more, I've decided to put the SWIG sources in wxPython's CVS instead of relying on maintaining patches. This effectivly becomes a fork of an obsolete version of SWIG, :-( but since SWIG 1.3 still doesn't have some things I rely on in 1.1, not to mention that my custom patches would all have to be redone, I felt that this is the easier road to take. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15307 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			830 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			830 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*******************************************************************************
 | |
|  * Simplified Wrapper and Interface Generator  (SWIG)
 | |
|  * 
 | |
|  * Author : David Beazley
 | |
|  *
 | |
|  * Department of Computer Science        
 | |
|  * University of Chicago
 | |
|  * 1100 E 58th Street
 | |
|  * Chicago, IL  60637
 | |
|  * beazley@cs.uchicago.edu
 | |
|  *
 | |
|  * Please read the file LICENSE for the copyright and terms by which SWIG
 | |
|  * can be used and distributed.
 | |
|  *******************************************************************************/
 | |
| 
 | |
| #include "internal.h"
 | |
| /*******************************************************************************
 | |
|  * $Header$
 | |
|  *
 | |
|  * File : emit.cxx
 | |
|  *
 | |
|  * This file contains some useful functions for emitting code that would be
 | |
|  * common to all of the interface languages.  Mainly this function deals with
 | |
|  * declaring functions external, creating lists of arguments, and making
 | |
|  * function calls.
 | |
|  *******************************************************************************/
 | |
| 
 | |
| // -----------------------------------------------------------------------------
 | |
| // void emit_banner(FILE *f)
 | |
| // 
 | |
| // Emits the SWIG identifying banner in the wrapper file
 | |
| //
 | |
| // Inputs : f   = FILE handle
 | |
| //
 | |
| // Output : None
 | |
| //
 | |
| // Side Effects : None
 | |
| // -----------------------------------------------------------------------------
 | |
| 
 | |
| void emit_banner(FILE *f) {
 | |
| 
 | |
|   extern char *get_time();
 | |
|   extern char fn_header[];
 | |
| 
 | |
|   fprintf(f,
 | |
| "/*\n\
 | |
|  * FILE : %s\n\
 | |
|  * \n\
 | |
|  * This file was automatically generated by :\n\
 | |
|  * Simplified Wrapper and Interface Generator (SWIG)\n\
 | |
|  * Version %d.%d %s\n\
 | |
|  * \n\
 | |
|  * Portions Copyright (c) 1995-1998\n\
 | |
|  * The University of Utah and The Regents of the University of California.\n\
 | |
|  * Permission is granted to distribute this file in any manner provided\n\
 | |
|  * this notice remains intact.\n\
 | |
|  * \n\
 | |
|  * Do not make changes to this file--changes will be lost!\n\
 | |
|  *\n\
 | |
|  */\n\n", fn_header, SWIG_MAJOR_VERSION, SWIG_MINOR_VERSION, SWIG_SPIN);
 | |
| 
 | |
|   fprintf(f,"\n#define SWIGCODE\n");
 | |
| 
 | |
| }
 | |
| 
 | |
| // -----------------------------------------------------------------------------
 | |
| // emit_extern_var(char *decl, DataType *t, int extern_type, FILE *f)
 | |
| // 
 | |
| // Emits an external variables declaration.   Extern_type defines the
 | |
| // type of external declaration.  Currently, only C/C++ declarations
 | |
| // are allowed, but this might be extended to allow Fortran linkage
 | |
| // someday
 | |
| //
 | |
| // Inputs :
 | |
| //          decl        = Name of the declaration
 | |
| //          t           = Datatype
 | |
| //          extern_type = Numeric code indicating type of extern
 | |
| //                              0   - No "extern"
 | |
| //                              1,2 -  Normal extern (C/C++)
 | |
| //          f           = FILE handle
 | |
| //
 | |
| // Output : None
 | |
| //
 | |
| // Side Effects : None
 | |
| // -----------------------------------------------------------------------------
 | |
| 
 | |
| void emit_extern_var(char *decl, DataType *t, int extern_type, FILE *f) {
 | |
|   char *arr = 0;
 | |
| 
 | |
|   if (t->arraystr) arr = t->arraystr;
 | |
|   else arr = "";
 | |
| 
 | |
|   switch(extern_type) {
 | |
| 
 | |
|   case 0:
 | |
|     // No extern.  Just a forward reference
 | |
|     if (t->arraystr)
 | |
|       t->is_pointer--;
 | |
| 
 | |
|     if (t->is_reference) {
 | |
|       t->is_pointer--;
 | |
|       fprintf(f,"%s& %s%s; \n", t->print_full(), decl, arr);
 | |
|       t->is_pointer++;
 | |
|     } else {
 | |
|       fprintf(f,"%s %s%s; \n", t->print_full(), decl,arr);
 | |
|     }
 | |
|     if (t->arraystr)
 | |
|       t->is_pointer++;
 | |
|     break;
 | |
|   case 1: case 2:
 | |
|     if (t->arraystr)
 | |
|       t->is_pointer--;
 | |
| 
 | |
|     // Normal C/C++ extern
 | |
| //    fprintf(f,"#line %d \"%s\"\n", line_number, input_file);
 | |
|     if (t->is_reference) {
 | |
|       t->is_pointer--;
 | |
|       fprintf(f,"extern %s& %s%s; \n", t->print_full(), decl,arr);
 | |
|       t->is_pointer++;
 | |
|     } else {
 | |
|       fprintf(f,"extern %s %s%s; \n", t->print_full(), decl,arr);
 | |
|     }
 | |
|     if (t->arraystr)
 | |
|       t->is_pointer++;
 | |
| 
 | |
|   default:
 | |
|     break;
 | |
|   }
 | |
| }
 | |
| 
 | |
| // -----------------------------------------------------------------------------
 | |
| // emit_extern_func(char *decl, DataType *t, ParmList *L, int extern_type,
 | |
| //                  FILE *f)
 | |
| //
 | |
| // Emits an external function declaration (similiar to emit_extern_var).
 | |
| // 
 | |
| // Inputs : 
 | |
| //          decl        = Name of declaration
 | |
| //          t           = Return datatype
 | |
| //          L           = parameter list
 | |
| //          extern_type = Type of extern
 | |
| //                           0 - No "extern"
 | |
| //                           1 - extern
 | |
| //                           2 - extern "C"
 | |
| //                           3 - Function declaration (with arg names)
 | |
| //          f           = FILE Handle
 | |
| //
 | |
| // Output : None
 | |
| //
 | |
| // Side Effects : None
 | |
| // 
 | |
| // -----------------------------------------------------------------------------
 | |
| 
 | |
| void emit_extern_func(char *decl, DataType *t, ParmList *L, int extern_type, FILE *f) {
 | |
| 
 | |
|   switch(extern_type) {
 | |
|   case 0:
 | |
|     if (t->is_reference) {
 | |
| 	t->is_pointer--;
 | |
| 	fprintf(f,"%s&", t->print_full());
 | |
| 	t->is_pointer++;
 | |
|     } else {
 | |
|       fprintf(f,"%s", t->print_full());
 | |
|     }
 | |
|     
 | |
|     fprintf(f,"%s(", decl);
 | |
|     L->print_types(f);
 | |
|     fprintf(f,");\n");
 | |
|     break;
 | |
|   case 1:
 | |
|     // Normal C/C++ extern
 | |
| //    fprintf(f,"#line %d \"%s\"\n", line_number, input_file);
 | |
|     if (t->is_reference) {
 | |
| 	t->is_pointer--;
 | |
| 	fprintf(f,"extern %s&", t->print_full());
 | |
| 	t->is_pointer++;
 | |
|     } else {
 | |
|       fprintf(f,"extern %s", t->print_full());
 | |
|     }
 | |
|     fprintf(f,"%s(", decl);
 | |
|     L->print_types(f);
 | |
|     fprintf(f,");\n");
 | |
|     break;
 | |
|   case 2:
 | |
|     // A C++ --- > C Extern
 | |
| //    fprintf(f,"#line %d \"%s\"\n", line_number, input_file);
 | |
|     if (t->is_reference) {
 | |
| 	t->is_pointer--;
 | |
| 	fprintf(f,"extern \"C\" %s&", t->print_full());
 | |
| 	t->is_pointer++;
 | |
|     } else {
 | |
|       fprintf(f,"extern \"C\" %s", t->print_full());
 | |
|     }
 | |
|     fprintf(f,"%s(", decl);
 | |
|     L->print_types(f);
 | |
|     fprintf(f,");\n");
 | |
|     break;
 | |
|   case 3:
 | |
|     // A function declaration (for inlining )
 | |
|     if (t->is_reference) {
 | |
| 	t->is_pointer--;
 | |
| 	fprintf(f,"%s&", t->print_full());
 | |
| 	t->is_pointer++;
 | |
|     } else {
 | |
|       fprintf(f,"%s", t->print_full());
 | |
|     }
 | |
|     
 | |
|     fprintf(f,"%s(", decl);
 | |
|     L->print_args(f);
 | |
|     fprintf(f,")\n");
 | |
|     break;
 | |
|   default:
 | |
|     break;
 | |
|   }
 | |
| }  
 | |
| 
 | |
| // -----------------------------------------------------------------------------
 | |
| // char *emit_local(int i)
 | |
| //
 | |
| // Returns the name of local variable for parameter i
 | |
| //
 | |
| // Inputs : i      = Parameter number
 | |
| //
 | |
| // Output : NULL terminated ASCII string
 | |
| //
 | |
| // Side Effects : Result is left in a static local variable.
 | |
| // -----------------------------------------------------------------------------
 | |
| 
 | |
| char *emit_local(int i) {
 | |
|   static char arg[64];
 | |
| 
 | |
|   sprintf(arg,"_arg%d", i);
 | |
|   return arg;
 | |
| }
 | |
| 
 | |
| // -----------------------------------------------------------------------------
 | |
| // int emit_args(char *d, DataType *rt, ParmList *l, FILE *f)
 | |
| //
 | |
| // Creates a list of variable declarations for both the return value
 | |
| // and function parameters.
 | |
| //
 | |
| // The return value is always called _result and arguments label as
 | |
| // _arg0, _arg1, _arg2, etc...
 | |
| //
 | |
| // Returns the number of parameters associated with a function.
 | |
| // 
 | |
| // Inputs :
 | |
| //          d     = Name of function
 | |
| //          rt    = Return type
 | |
| //          l     = Parameter list
 | |
| //          f     = FILE Handle
 | |
| //
 | |
| // Output : Number of function arguments 
 | |
| //
 | |
| // Side Effects : None
 | |
| //
 | |
| // Note : This function is obsolete.  Use emit_args below...
 | |
| // -----------------------------------------------------------------------------
 | |
| 
 | |
| int emit_args(DataType *rt, ParmList *l, FILE *f) {
 | |
| 
 | |
|   Parm *p;
 | |
|   int   i;
 | |
|   char  temp[64];
 | |
|   String def;
 | |
|   char  *tm;
 | |
| 
 | |
|   // Declare the return variable
 | |
| 
 | |
|   if ((rt->type != T_VOID) || (rt->is_pointer)) {
 | |
|     if ((rt->type == T_USER) && (!rt->is_pointer)) {
 | |
| 
 | |
|       // Special case for return by "value"
 | |
| 
 | |
|       rt->is_pointer++;
 | |
|       fprintf(f,"\t %s _result;\n", rt->print_type());
 | |
|       rt->is_pointer--;
 | |
|     } else {
 | |
| 
 | |
|       // Normal return value
 | |
| 
 | |
|       fprintf(f,"\t %s _result;\n", rt->print_type());
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // Emit function arguments
 | |
| 
 | |
|   i = 0;
 | |
|   p = l->get_first();
 | |
|   while (p != 0) {
 | |
|     if ((p->t->type != T_VOID) || (p->t->is_pointer))  {
 | |
|       sprintf(temp,"_arg%d", i);
 | |
|       if (p->defvalue) {
 | |
| 	if ((p->t->is_reference) || ((p->t->type == T_USER) && (p->call_type == CALL_REFERENCE)))
 | |
| 	    fprintf(f,"\t %s _arg%d = &%s;\n", p->t->print_type(),i, p->defvalue);
 | |
| 	  else	
 | |
| 	    fprintf(f,"\t %s _arg%d = %s;\n", p->t->print_type(),i, p->defvalue);
 | |
|       } else {
 | |
| 	fprintf(f,"\t %s _arg%d;\n", p->t->print_type(),i);
 | |
| 	tm = typemap_lookup("arginit", typemap_lang, p->t, p->name,"",temp);
 | |
| 	if (tm) {
 | |
| 	  def << tm;
 | |
| 	}
 | |
|       }
 | |
| 
 | |
|       // Check for ignore or default typemaps
 | |
|       
 | |
|       tm = typemap_lookup("default",typemap_lang,p->t,p->name,"",temp);
 | |
|       if (tm) 
 | |
| 	def << tm;
 | |
|       tm = typemap_lookup("ignore",typemap_lang,p->t,p->name,"",temp);
 | |
| 
 | |
|       if (tm) {
 | |
| 	def << tm;
 | |
| 	p->ignore = 1;
 | |
|       }
 | |
|       tm = typemap_check("build",typemap_lang,p->t,p->name);
 | |
|       if (tm) {
 | |
| 	p->ignore = 1;
 | |
|       }
 | |
|       i++;
 | |
|     }
 | |
|     p = l->get_next();
 | |
|   }
 | |
| 
 | |
|   fprintf(f,"%s",def.get());
 | |
| 
 | |
|   // i now contains number of parameters
 | |
|   
 | |
|   return(i);
 | |
| 
 | |
|  }
 | |
| 
 | |
| 
 | |
| // -----------------------------------------------------------------------------
 | |
| // int emit_args(char *d, DataType *rt, ParmList *l, WrapperFunction &f)
 | |
| //
 | |
| // Creates a list of variable declarations for both the return value
 | |
| // and function parameters.
 | |
| //
 | |
| // The return value is always called _result and arguments label as
 | |
| // _arg0, _arg1, _arg2, etc...
 | |
| //
 | |
| // Returns the number of parameters associated with a function.
 | |
| // 
 | |
| // Inputs :
 | |
| //          d     = Name of function
 | |
| //          rt    = Return type
 | |
| //          l     = Parameter list
 | |
| //          f     = Wrapper function object
 | |
| //
 | |
| // Output : Number of function arguments 
 | |
| //
 | |
| // Side Effects : None
 | |
| //
 | |
| // -----------------------------------------------------------------------------
 | |
| 
 | |
| int emit_args(DataType *rt, ParmList *l, WrapperFunction &f) {
 | |
| 
 | |
|   Parm *p;
 | |
|   int   i;
 | |
|   char *tm;
 | |
| 
 | |
|   // Declare the return variable
 | |
| 
 | |
|   if ((rt->type != T_VOID) || (rt->is_pointer)) {
 | |
|     if ((rt->type == T_USER) && (!rt->is_pointer)) {
 | |
| 
 | |
|       // Special case for return by "value"
 | |
|       rt->is_pointer++;
 | |
|       f.add_local(rt->print_type(), "_result");
 | |
|       rt->is_pointer--;
 | |
|     } else {
 | |
| 
 | |
|       // Normal return value
 | |
| 
 | |
|       f.add_local(rt->print_type(), "_result");
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // Emit function arguments
 | |
| 
 | |
|   i = 0;
 | |
|   p = l->get_first();
 | |
|   while (p != 0) {
 | |
|     if ((p->t->type != T_VOID) || (p->t->is_pointer))  {
 | |
|       char *temp = emit_local(i);
 | |
|       // Figure out default values
 | |
|       if (((p->t->is_reference) && (p->defvalue)) || 
 | |
| 	  ((p->t->type == T_USER) && (p->call_type == CALL_REFERENCE) && (p->defvalue))) {
 | |
| 	String deftmp;
 | |
| 	deftmp << "(" << p->t->print_type() << ") &" << p->defvalue;
 | |
| 	f.add_local(p->t->print_type(),temp,deftmp.get());
 | |
|       } else {
 | |
| 	String deftmp;
 | |
| 	char *dv = 0;
 | |
| 	if (p->defvalue) {
 | |
| 	  deftmp << "(" << p->t->print_type() << ") " << p->defvalue;
 | |
| 	  dv = deftmp.get();
 | |
| 	}
 | |
| 	f.add_local(p->t->print_type(), temp, dv);
 | |
| 	tm = typemap_lookup("arginit", typemap_lang, p->t,p->name,"",temp,&f);
 | |
| 	if (tm) {
 | |
| 	  f.code << tm << "\n";
 | |
| 	}
 | |
|       }
 | |
|       // Check for ignore or default typemaps
 | |
|       tm = typemap_lookup("default",typemap_lang,p->t,p->name,"",temp,&f);
 | |
|       if (tm) 
 | |
| 	f.code << tm << "\n";
 | |
|       tm = typemap_lookup("ignore",typemap_lang,p->t,p->name,"",temp,&f);
 | |
|       if (tm) {
 | |
| 	f.code << tm << "\n";
 | |
| 	p->ignore = 1;
 | |
|       }
 | |
|       tm = typemap_check("build",typemap_lang,p->t,p->name);
 | |
|       if (tm) {
 | |
| 	p->ignore = 1;
 | |
|       }
 | |
|       i++;
 | |
|     }
 | |
|     p = l->get_next();
 | |
|   }
 | |
| 
 | |
|   // i now contains number of parameters
 | |
|   return(i);
 | |
| }
 | |
| 
 | |
| // -----------------------------------------------------------------------------
 | |
| // int emit_func_call(char *decl, DataType *t, ParmList *l, FILE *f)
 | |
| //
 | |
| // Emits code for a function call.
 | |
| // 
 | |
| // Inputs :
 | |
| //           decl   = name of function
 | |
| //           t      = Return datatype
 | |
| //           l      = Parameter list
 | |
| //           f      = FILE Handle
 | |
| //
 | |
| // Output : None
 | |
| //
 | |
| // Side Effects : None
 | |
| //
 | |
| // Note : This function is obsolete
 | |
| // -----------------------------------------------------------------------------
 | |
| 
 | |
| void emit_func_call(char *decl, DataType *t, ParmList *l, FILE *f) {
 | |
| 
 | |
|   int  i;
 | |
|   Parm  *p;
 | |
| 
 | |
| //  fprintf(f,"#line %d \"%s\"\n", line_number, input_file);
 | |
|   fprintf(f,"\t ");
 | |
| 
 | |
|   // First check if there is a return value
 | |
| 
 | |
|   if ((t->type != T_VOID) || (t->is_pointer)) {
 | |
|     if ((t->type == T_USER) && (!t->is_pointer)) {
 | |
| 
 | |
|       // Special case for return by "value"
 | |
|       // Caution : This *will* cause a memory leak if not
 | |
|       // used properly.
 | |
| 
 | |
|       if (CPlusPlus) {
 | |
| 	fprintf(f,"_result = new %s(", t->print_type());
 | |
|       } else {
 | |
| 	t->is_pointer++;
 | |
| 	fprintf(f,"_result = %s malloc(sizeof(", t->print_cast());
 | |
| 	t->is_pointer--;
 | |
| 	fprintf(f,"%s));\n", t->print_type());
 | |
| 	fprintf(f,"\t*(_result) = ");
 | |
|       }
 | |
|     } else {
 | |
|       // Check if this is a C++ reference
 | |
|       if (t->is_reference) {
 | |
| 	t->is_pointer--;
 | |
| 	fprintf(f,"%s& _result_ref = ", t->print_full());
 | |
| 	t->is_pointer++;
 | |
|       } else {
 | |
| 	
 | |
|       // Normal return values
 | |
| 	fprintf(f,"_result = %s", t->print_cast());
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // Now print out function call
 | |
| 
 | |
|   fprintf(f,"%s(",decl);
 | |
| 
 | |
|   i = 0;
 | |
|   p = l->get_first();
 | |
|   while(p != 0) {
 | |
|     if ((p->t->type != T_VOID) || (p->t->is_pointer)){
 | |
|       fprintf(f,"%s",p->t->print_arraycast());
 | |
|       if ((!p->t->is_reference) && (p->call_type & CALL_VALUE)) fprintf(f,"&");
 | |
|       if ((!(p->call_type & CALL_VALUE)) &&
 | |
| 	  ((p->t->is_reference) || (p->call_type & CALL_REFERENCE)))
 | |
| 	fprintf(f,"*");
 | |
|       fprintf(f,"_arg%d",i);
 | |
|       i++;
 | |
|     }
 | |
|     p = l->get_next();
 | |
|     if (p != 0)
 | |
|       fprintf(f,",");
 | |
|   }
 | |
| 
 | |
|   fprintf(f,")");
 | |
|   if ((t->type == T_USER) && (!t->is_pointer)) {
 | |
|     if (CPlusPlus) {
 | |
|       fprintf(f,")");
 | |
|     }
 | |
|   }
 | |
|   fprintf(f,";\n");
 | |
|   if (t->is_reference) {
 | |
|     fprintf(f,"\t _result = %s &_result_ref;\n", t->print_cast());
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| // -----------------------------------------------------------------------------
 | |
| // int emit_func_call(char *decl, DataType *t, ParmList *l, WrapperFunction &f)
 | |
| //
 | |
| // Emits code for a function call (new version).
 | |
| // 
 | |
| // Exception handling support :
 | |
| //
 | |
| //     -  This function checks to see if any sort of exception mechanism
 | |
| //        has been defined.  If so, we emit the function call in an exception
 | |
| //        handling block.
 | |
| //
 | |
| // Inputs :
 | |
| //           decl   = name of function
 | |
| //           t      = Return datatype
 | |
| //           l      = Parameter list
 | |
| //           f      = WrapperFunction object
 | |
| //
 | |
| // Output : None
 | |
| //
 | |
| // Side Effects : None
 | |
| //
 | |
| // -----------------------------------------------------------------------------
 | |
| 
 | |
| void emit_func_call(char *decl, DataType *t, ParmList *l, WrapperFunction &f) {
 | |
| 
 | |
|   int  i;
 | |
|   Parm  *p;
 | |
|   String fcall;
 | |
|   String exc;
 | |
|   char *tm;
 | |
| 
 | |
| //  f.code << "#line " << line_number << " \"" << input_file << "\"\n";
 | |
|   fcall << tab4;
 | |
| 
 | |
|   // First check if there is a return value
 | |
| 
 | |
|   if ((t->type != T_VOID) || (t->is_pointer)) {
 | |
|     if ((t->type == T_USER) && (!t->is_pointer)) {
 | |
| 
 | |
|       // Special case for return by "value"
 | |
|       // Caution : This *will* cause a memory leak if not
 | |
|       // used properly.
 | |
| 
 | |
|       if (CPlusPlus) {
 | |
| 	fcall << "_result = new " << t->print_type() << "(";
 | |
|       } else {
 | |
| 	t->is_pointer++;
 | |
| 	fcall << "_result = " << t->print_cast() << " malloc(sizeof(";
 | |
| 	t->is_pointer--;
 | |
| 	fcall << t->print_type() << "));\n";
 | |
| 	fcall << tab4 << "*(_result) = ";
 | |
|       }
 | |
|     } else {
 | |
|       // Check if this is a C++ reference
 | |
|       if (t->is_reference) {
 | |
| 	t->is_pointer--;
 | |
| 	fcall << t->print_full() << "& _result_ref = ";
 | |
| 	t->is_pointer++;
 | |
|       } else {
 | |
| 
 | |
| 	// Normal return value
 | |
| 	fcall << "_result = " << t->print_cast();
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // Now print out function call
 | |
| 
 | |
|   fcall << decl << "(";
 | |
| 
 | |
|   i = 0;
 | |
|   p = l->get_first();
 | |
|   while(p != 0) {
 | |
|     if ((p->t->type != T_VOID) || (p->t->is_pointer)){
 | |
|       fcall << p->t->print_arraycast();
 | |
|       if ((!p->t->is_reference) && (p->call_type & CALL_VALUE))
 | |
| 	fcall << "&";
 | |
|       if ((!(p->call_type & CALL_VALUE)) &&
 | |
| 	  ((p->t->is_reference) || (p->call_type & CALL_REFERENCE)))
 | |
| 	fcall << "*";
 | |
|       fcall << emit_local(i);
 | |
|       i++;
 | |
|     }
 | |
|     p = l->get_next();
 | |
|     if (p != 0)
 | |
|       fcall << ",";
 | |
|   }
 | |
|   fcall << ")";
 | |
| 
 | |
|   if ((t->type == T_USER) && (!t->is_pointer)) {
 | |
|     if (CPlusPlus) {
 | |
|       fcall << ")";
 | |
|     }
 | |
|   }
 | |
|   fcall << ";\n";
 | |
| 
 | |
|   if (t->is_reference) {
 | |
|     fcall << tab4 << "_result = "<< t->print_cast() << " &_result_ref;\n";
 | |
|   }
 | |
|   // Check for exception handling
 | |
| 
 | |
|   if ((tm = typemap_lookup("except",typemap_lang,t,decl,"_result",""))) {
 | |
|     // Found a type-specific mapping
 | |
|     exc << tm;
 | |
|     exc.replace("$function",fcall);
 | |
|     exc.replace("$name",decl);
 | |
|     f.code << exc;
 | |
|   } else if ((tm = fragment_lookup("except",typemap_lang, t->id))) {
 | |
|     exc << tm;
 | |
|     exc.replace("$function",fcall);
 | |
|     exc.replace("$name",decl);
 | |
|     f.code << exc;
 | |
|   } else {
 | |
|     f.code << fcall;
 | |
|   }
 | |
| }
 | |
| 
 | |
| // -----------------------------------------------------------------------------
 | |
| // void emit_hex(FILE *f)
 | |
| // 
 | |
| // Emits the default C-code to handle pointers.   This is normally contained
 | |
| // in the SWIG library file 'swigptr.swg'
 | |
| //
 | |
| // Inputs : f   = FILE handle
 | |
| //
 | |
| // Output : None
 | |
| //
 | |
| // Side Effects : None
 | |
| // -----------------------------------------------------------------------------
 | |
| 
 | |
| void emit_hex(FILE *f) {
 | |
|   
 | |
|   int stat;
 | |
| 
 | |
|    // Look for a pointer configuration file
 | |
| 
 | |
|    stat = insert_file("swigptr.swg", f);
 | |
| 
 | |
|    if (stat == -1) {
 | |
|      fprintf(stderr,"** Fatal error.  Unable to locate 'swigptr.swg'\n");
 | |
|      SWIG_exit(1);
 | |
|    }
 | |
| }
 | |
| 
 | |
| // -----------------------------------------------------------------------------
 | |
| // void emit_set_get(char *name, char *iname, DataType *type)
 | |
| //
 | |
| // Emits a pair of functions to set/get the value of a variable.
 | |
| // This should be used as backup in case the target language can't
 | |
| // provide variable linking.
 | |
| // 
 | |
| // double foo;
 | |
| //
 | |
| // Gets translated into the following :
 | |
| //
 | |
| // double foo_set(double x) {
 | |
| //      return foo = x;
 | |
| // }
 | |
| //
 | |
| // double foo_get() {
 | |
| //      return foo;
 | |
| // }
 | |
| //
 | |
| // Need to handle special cases for char * and for user
 | |
| // defined types. 
 | |
| //
 | |
| // 1.  char *
 | |
| //
 | |
| //     Will free previous contents (if any) and allocate
 | |
| //     new storage.   Could be risky, but it's a reasonably
 | |
| //     natural thing to do.
 | |
| //
 | |
| // 2.  User_Defined
 | |
| //     Will assign value from a pointer. 
 | |
| //     Will return a pointer to current value.
 | |
| // 
 | |
| // 
 | |
| // Inputs :
 | |
| //          name    = Name of variable
 | |
| //          iname   = Renamed version of variable
 | |
| //          type    = Datatype of the variable
 | |
| //
 | |
| // Output : None
 | |
| //
 | |
| // Side Effects : None
 | |
| // -----------------------------------------------------------------------------
 | |
| 
 | |
| void emit_set_get(char *name, char *iname, DataType *t) {
 | |
| 
 | |
|     Parm *p;
 | |
|     ParmList *l;
 | |
|     String new_name;
 | |
|     String new_iname;
 | |
|     String wname;
 | |
| 
 | |
|     // First write a function to set the variable of the variable
 | |
| 
 | |
|     if (!(Status & STAT_READONLY)) {
 | |
|       if ((t->type == T_USER) && (!t->is_pointer)) {
 | |
| 	t->is_pointer++;
 | |
| 	fprintf(f_header,"static %s %s(%s val) {\n",
 | |
| 		t->print_type(), name_set(name), t->print_type());
 | |
| 	t->is_pointer--;
 | |
|       } else {
 | |
| 	fprintf(f_header,"static %s %s(%s val) {\n",
 | |
| 		t->print_type(), name_set(name), t->print_type());
 | |
|       }
 | |
|       
 | |
|       if ((t->type != T_VOID) || (t->is_pointer)) {
 | |
| 	if (!t->is_pointer) {
 | |
| 	  
 | |
| 	  // Have a real value here 
 | |
| 	  // If it's a user defined type, we'll do something special.
 | |
| 	  // Otherwise, just assign it.
 | |
| 	  
 | |
| 	  if (t->type != T_USER) {
 | |
| 	    fprintf(f_header,"\t return (%s) (%s = val);\n", t->print_type(), name);
 | |
| 	  } else {
 | |
| 	    fprintf(f_header,"\t %s = *(val);\n", name);
 | |
| 	    t->is_pointer++;
 | |
| 	    fprintf(f_header,"\t return (%s) &%s;\n", t->print_type(),name);
 | |
| 	    t->is_pointer--;
 | |
| 	  }
 | |
| 	} else {
 | |
| 	  
 | |
| 	  // Is a pointer type here.  If string, we do something
 | |
| 	  // special.  Otherwise. No problem.
 | |
| 	  
 | |
| 	  if ((t->type == T_CHAR) && (t->is_pointer == 1)) {
 | |
| 	    if (CPlusPlus) {
 | |
| 	      fprintf(f_header,"\t if (%s) delete %s;\n", name,name);
 | |
| 	      fprintf(f_header,"\t %s = new char[strlen(val)+1];\n",name);
 | |
| 	      fprintf(f_header,"\t strcpy(%s,val);\n", name);
 | |
| 	      fprintf(f_header,"\t return %s;\n", name);
 | |
| 	    } else {
 | |
| 	      fprintf(f_header,"\t if (%s) free(%s);\n", name,name);
 | |
| 	      fprintf(f_header,"\t %s = (char *) malloc(strlen(val)+1);\n",name);
 | |
| 	      fprintf(f_header,"\t strcpy(%s,val);\n", name);
 | |
| 	      fprintf(f_header,"\t return %s;\n", name);
 | |
| 	    }
 | |
| 	  } else {
 | |
| 	    fprintf(f_header,"\t return (%s) (%s = val);\n", t->print_type(), name);
 | |
| 	  }
 | |
| 	}
 | |
|       }
 | |
| 
 | |
|       fprintf(f_header,"}\n");
 | |
| 
 | |
|       // Now wrap it.
 | |
| 
 | |
|       l = new ParmList;
 | |
|       p = new Parm(t,0);
 | |
|       if ((t->type == T_USER) && (!t->is_pointer)) p->t->is_pointer++;
 | |
|       p->name = new char[1];
 | |
|       p->name[0] = 0;
 | |
|       l->append(p);
 | |
|       
 | |
|       new_name = name_set(name);
 | |
|       new_iname = name_set(iname);
 | |
|       
 | |
|       if ((t->type == T_USER) && (!t->is_pointer)) {
 | |
| 	t->is_pointer++;
 | |
| 	lang->create_function(new_name, new_iname, t, l);
 | |
| 	t->is_pointer--;
 | |
|       } else {
 | |
| 	lang->create_function(new_name, new_iname, t, l);
 | |
|       }
 | |
|       delete l;
 | |
|       delete p;
 | |
|       if (doc_entry) doc_entry->usage << "\n";
 | |
|     }
 | |
| 
 | |
|     // Now write a function to get the value of the variable
 | |
| 
 | |
|     if ((t->type == T_USER) && (!t->is_pointer)) {
 | |
|       t->is_pointer++;
 | |
|       fprintf(f_header,"static %s %s() { \n",
 | |
| 	      t->print_type(), name_get(name));
 | |
|       fprintf(f_header,"\t return (%s) &%s;\n", t->print_type(), name);
 | |
|       t->is_pointer--;
 | |
|     } else {
 | |
|       fprintf(f_header,"static %s %s() { \n",
 | |
| 	      t->print_type(), name_get(name));
 | |
|       fprintf(f_header,"\t return (%s) %s;\n", t->print_type(), name);
 | |
|     }
 | |
| 
 | |
|     fprintf(f_header,"}\n");
 | |
|     
 | |
|     // Wrap this function
 | |
| 
 | |
|     l = new ParmList;
 | |
| 
 | |
|     new_name = name_get(name);
 | |
|     new_iname = name_get(iname);
 | |
| 
 | |
|     if ((t->type == T_USER) && (!t->is_pointer)) {
 | |
|       t->is_pointer++;
 | |
|       lang->create_function(new_name, new_iname, t, l);
 | |
|       t->is_pointer--;
 | |
|     } else {
 | |
|       lang->create_function(new_name, new_iname, t, l);
 | |
|     }
 | |
|     delete l;
 | |
| }
 | |
|   
 | |
| 
 | |
| 
 | |
| 
 |