c90f71dd8c
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;
|
|
}
|
|
|
|
|
|
|
|
|