X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3bd1e033857b8dd6f4dea024d3f18fcc7682e09d..c90f71dd8c2ec6670edb45c39000a048bd163ae9:/wxPython/wxSWIG/SWIG/emit.cxx diff --git a/wxPython/wxSWIG/SWIG/emit.cxx b/wxPython/wxSWIG/SWIG/emit.cxx new file mode 100644 index 0000000000..57f67af2e0 --- /dev/null +++ b/wxPython/wxSWIG/SWIG/emit.cxx @@ -0,0 +1,829 @@ +/******************************************************************************* + * 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; +} + + + +