From 503746e964f545dccaf7b05cd8c4041049b2c409 Mon Sep 17 00:00:00 2001 From: Dave Beazley Date: Tue, 15 Aug 2000 18:29:23 +0000 Subject: [PATCH] Eliminated old typemap/except code. Variety of minor bug fixes throughout. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@655 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules1.1/tcl8.cxx | 22 +- Source/SWIG1.1/Makefile.in | 5 +- Source/SWIG1.1/emit.cxx | 40 +- Source/SWIG1.1/main.cxx | 22 +- Source/SWIG1.1/parser.yxx | 32 +- Source/SWIG1.1/swig11.h | 41 -- Source/SWIG1.1/typemap.cxx | 969 ---------------------------- Source/Swig/Makefile.in | 4 +- Source/Swig/map.c | 5 + Source/Swig/oldtypes.c | 1229 ------------------------------------ Source/Swig/stype.c | 1 - Source/Swig/swig.h | 23 +- Source/Swig/typemap.c | 478 ++++++++++++++ 13 files changed, 585 insertions(+), 2286 deletions(-) delete mode 100644 Source/SWIG1.1/typemap.cxx delete mode 100644 Source/Swig/oldtypes.c create mode 100644 Source/Swig/typemap.c diff --git a/Source/Modules1.1/tcl8.cxx b/Source/Modules1.1/tcl8.cxx index 5ebeac3fc..313ab7881 100644 --- a/Source/Modules1.1/tcl8.cxx +++ b/Source/Modules1.1/tcl8.cxx @@ -522,7 +522,7 @@ void TCL8::create_function(char *name, char *iname, SwigType *d, ParmList *l) if (j == (pcount-numopt)) Putc('|',argstr); - if ((tm = typemap_lookup((char*)"in",(char*)"tcl8",pt,pn,source,target,f))) { + if ((tm = Swig_typemap_lookup((char*)"in",pt,pn,source,target,f))) { Putc('o',argstr); Printf(args,",0"); @@ -621,7 +621,7 @@ void TCL8::create_function(char *name, char *iname, SwigType *d, ParmList *l) } // Check to see if there was any sort of a constaint typemap - if ((tm = typemap_lookup((char*)"check",(char*)"tcl8",pt,pn,source,target,0))) { + if ((tm = Swig_typemap_lookup((char*)"check",pt,pn,source,target,0))) { // Yep. Use it instead of the default Printf(incode,"%s\n", tm); Replace(incode,"$argnum",argnum, DOH_REPLACE_ANY); @@ -629,14 +629,14 @@ void TCL8::create_function(char *name, char *iname, SwigType *d, ParmList *l) } // Check if there was any cleanup code (save it for later) - if ((tm = typemap_lookup((char*)"freearg",(char*)"tcl8",pt,pn,target,(char*)"tcl_result",0))) { + if ((tm = Swig_typemap_lookup((char*)"freearg",pt,pn,target,(char*)"tcl_result",0))) { // Yep. Use it instead of the default Printf(cleanup,"%s\n", tm); Replace(cleanup,"$argnum",argnum, DOH_REPLACE_ANY); Replace(cleanup,"$arg",source,DOH_REPLACE_ANY); } // Look for output arguments - if ((tm = typemap_lookup((char*)"argout",(char*)"tcl8",pt,pn,target,(char*)"tcl_result",0))) { + if ((tm = Swig_typemap_lookup((char*)"argout",pt,pn,target,(char*)"tcl_result",0))) { Printf(outarg,"%s\n", tm); Replace(outarg,"$argnum",argnum, DOH_REPLACE_ANY); Replace(outarg,"$arg",source, DOH_REPLACE_ANY); @@ -657,7 +657,7 @@ void TCL8::create_function(char *name, char *iname, SwigType *d, ParmList *l) // Return value if necessary - if ((tm = typemap_lookup((char*)"out",(char*)"tcl8",d,name,(char*)"result",(char*)"tcl_result",0))) { + if ((tm = Swig_typemap_lookup((char*)"out",d,name,(char*)"result",(char*)"tcl_result",0))) { // Yep. Use it instead of the default Printf(f->code,"%s\n", tm); } else { @@ -729,12 +729,12 @@ void TCL8::create_function(char *name, char *iname, SwigType *d, ParmList *l) // Look for any remaining cleanup if (NewObject) { - if ((tm = typemap_lookup((char*)"newfree",(char*)"tcl8",d,iname,(char*)"result",(char*)"",0))) { + if ((tm = Swig_typemap_lookup((char*)"newfree",d,iname,(char*)"result",(char*)"",0))) { Printf(f->code,"%s\n", tm); } } - if ((tm = typemap_lookup((char*)"ret",(char*)"tcl8",d,name,(char*)"result",(char*)"",0))) { + if ((tm = Swig_typemap_lookup((char*)"ret",d,name,(char*)"result",(char*)"",0))) { // Yep. Use it instead of the default Printf(f->code,"%s\n", tm); } @@ -772,8 +772,8 @@ void TCL8::link_variable(char *name, char *iname, SwigType *t) // See if there were any typemaps - tm = typemap_lookup((char*)"varin",(char*)"tcl8",t,name,(char*)"",(char*)"",0); - tm1 = typemap_lookup((char*)"varout",(char*)"tcl8",t,name,(char*)"",(char*)"",0); + tm = Swig_typemap_lookup((char*)"varin",t,name,(char*)"",(char*)"",0); + tm1 = Swig_typemap_lookup((char*)"varout",t,name,(char*)"",(char*)"",0); if (tm || tm1) { Printf(stderr,"%s : Line %d. Warning. varin/varout typemap methods not supported.", input_file, line_number); @@ -978,7 +978,7 @@ void TCL8::declare_const(char *name, char *, SwigType *type, char *value) { } else { rvalue = NewString(value); } - if ((tm = typemap_lookup((char*)"const",(char*)"tcl8",type,name,Char(rvalue),name,0))) { + if ((tm = Swig_typemap_lookup((char*)"const",type,name,Char(rvalue),name,0))) { // Yep. Use it instead of the default Printf(f_init,"%s\n",tm); } else { @@ -1116,7 +1116,7 @@ char * TCL8::usage_string(char *iname, SwigType *, ParmList *l) { // Only print an argument if not ignored - if (!typemap_check((char*)"ignore",(char*)"tcl8",pt,pn)) { + if (!Swig_typemap_search((char*)"ignore",pt,pn)) { if (i >= (pcount-numopt)) Putc('?',temp); diff --git a/Source/SWIG1.1/Makefile.in b/Source/SWIG1.1/Makefile.in index 4e4fb07f7..d7ef8741f 100644 --- a/Source/SWIG1.1/Makefile.in +++ b/Source/SWIG1.1/Makefile.in @@ -15,11 +15,10 @@ RANLIB = @RANLIB@ TARGET = libswig11.a OBJS = parser.o main.o scanner.o \ - emit.o cplus.o lang.o typemap.o + emit.o cplus.o lang.o SRCS = main.cxx scanner.cxx \ - emit.cxx cplus.cxx lang.cxx \ - typemap.cxx + emit.cxx cplus.cxx lang.cxx PARSER = $(srcdir)/parser.yxx INCLUDE = -I$(srcdir)/../Include \ diff --git a/Source/SWIG1.1/emit.cxx b/Source/SWIG1.1/emit.cxx index 516a4abb1..ca8400731 100644 --- a/Source/SWIG1.1/emit.cxx +++ b/Source/SWIG1.1/emit.cxx @@ -50,16 +50,16 @@ int emit_args(SwigType *rt, ParmList *l, Wrapper *f) { pname = Getname(p); pvalue = Getvalue(p); - tm = typemap_lookup((char*)"arginit", typemap_lang, pt,pname,(char*)"",lname,f); + tm = Swig_typemap_lookup((char*)"arginit",pt,pname,(char*)"",lname,f); if (tm) { Printv(f->code,tm,"\n",0); } /* Check for ignore or default typemaps */ - tm = typemap_lookup((char*)"default",typemap_lang,pt,pname,(char*)"",lname,f); + tm = Swig_typemap_lookup((char*)"default",pt,pname,(char*)"",lname,f); if (tm) { Printv(f->code,tm,"\n",0); } - tm = typemap_lookup((char*)"ignore",typemap_lang,pt,pname,(char*)"",lname,f); + tm = Swig_typemap_lookup((char*)"ignore",pt,pname,(char*)"",lname,f); if (tm) { Printv(f->code,tm,"\n",0); Setignore(p,1); @@ -92,10 +92,10 @@ void emit_set_action(DOHString_or_char *decl) { void emit_func_call(char *decl, SwigType *t, ParmList *l, Wrapper *f) { char *tm; - if ((tm = typemap_lookup((char*)"except",typemap_lang,t,decl,(char*)"result",(char*)"",0))) { + if ((tm = Swig_typemap_lookup((char*)"except",t,decl,(char*)"result",(char*)"",0))) { Printv(f->code,tm,0); Replace(f->code,"$name",decl,DOH_REPLACE_ANY); - } else if ((tm = fragment_lookup((char*)"except",typemap_lang))) { + } else if ((tm = Swig_except_lookup())) { Printv(f->code,tm,0); Replace(f->code,"$name",decl,DOH_REPLACE_ANY); } else { @@ -183,6 +183,36 @@ void emit_set_get(char *name, char *iname, SwigType *t) { DelWrapper(w); } +/* ------------------------------------------------------------------ + * int check_numopt() + * + * Gets the number of optional arguments for a ParmList. + * ------------------------------------------------------------------ */ + +int check_numopt(ParmList *p) { + int n = 0; + int i = 0; + int state = 0; + + for (;p; p = Getnext(p),i++) { + SwigType *pt = Gettype(p); + String *pn = Getname(p); + if (Getvalue(p)) { + n++; + state = 1; + } else if (Swig_typemap_search((char*)"default",pt,pn)) { + n++; + state = 1; + } else if (Swig_typemap_search((char*)"ignore",pt,pn)) { + n++; + } else { + if (state) { + Printf(stderr,"%s : Line %d. Argument %d must have a default value!\n", input_file,line_number,i+1); + } + } + } + return n; +} diff --git a/Source/SWIG1.1/main.cxx b/Source/SWIG1.1/main.cxx index 4bcb8bdef..5b6831cee 100644 --- a/Source/SWIG1.1/main.cxx +++ b/Source/SWIG1.1/main.cxx @@ -55,7 +55,7 @@ extern "C" { int GenerateDefault = 0; // Generate default constructors char *Config = 0; int NoInclude = 0; - char *typemap_lang = 0; // Typemap name + int error_count = 0; // Error count int Verbose = 0; @@ -135,13 +135,12 @@ int SWIG_main(int argc, char *argv[], Language *l) { int help = 0; int checkout = 0; int cpp_only = 0; - + int tm_debug = 0; char *includefiles[256]; int includecount = 0; extern int check_suffix(char *); extern void scanner_file(DOHFile *); extern void parser_init(void); - extern void typemap_initialize(); DOH *libfiles = 0; { @@ -154,7 +153,8 @@ int SWIG_main(int argc, char *argv[], Language *l) { // Initialize the preprocessor Preprocessor_init(); - typemap_initialize(); + Swig_typemap_init(); + f_wrappers = 0; f_init = 0; f_header = 0; @@ -259,6 +259,9 @@ int SWIG_main(int argc, char *argv[], Language *l) { } else if (strcmp(argv[i],"-includeall") == 0) { Preprocessor_include_all(1); Swig_mark_arg(i); + } else if (strcmp(argv[i],"-tm_debug") == 0) { + tm_debug = 1; + Swig_mark_arg(i); } else if (strcmp(argv[i],"-help") == 0) { fputs(usage,stderr); Swig_mark_arg(i); @@ -414,18 +417,12 @@ int SWIG_main(int argc, char *argv[], Language *l) { f_init = NewString(""); // Set up the typemap for handling new return strings -#ifdef OLD { - DataType *temp_t = NewDataType(T_CHAR); - DataType_add_pointer(temp_t); if (CPlusPlus) - typemap_register((char*)"newfree",typemap_lang,temp_t,(char*)"",(char*)"delete [] $source;\n",0); + Swig_typemap_register((char*)"newfree",(char*)"p.char",(char*)"",(char*)"delete [] $source;\n",0); else - typemap_register((char*)"newfree",typemap_lang,temp_t,(char*)"",(char*)"free($source);\n",0); - - DelDataType(temp_t); + Swig_typemap_register((char*)"newfree",(char*)"p.char",(char*)"",(char*)"free($source);\n",0); } -#endif // If in Objective-C mode. Load in a configuration file @@ -461,6 +458,7 @@ int SWIG_main(int argc, char *argv[], Language *l) { remove(input_file); } } + if (tm_debug) Swig_typemap_debug(); while (freeze); return error_count; } diff --git a/Source/SWIG1.1/parser.yxx b/Source/SWIG1.1/parser.yxx index 96d128f89..8932a88b2 100644 --- a/Source/SWIG1.1/parser.yxx +++ b/Source/SWIG1.1/parser.yxx @@ -34,6 +34,7 @@ extern void scanner_ignore_typedef(void); extern void scanner_clear_start(void); extern void start_inline(char *, int); extern void swig_pragma(char *, char *); + char *typemap_lang = 0; #include "internal.h" extern "C" { @@ -1048,7 +1049,8 @@ statement : INCLUDE STRING LBRACE { skip_brace(); p = $7; while (p) { - typemap_register($5,$3,Gettype(p->p),Getname(p->p),Char(CCode),p->args); + if (strcmp($3,typemap_lang) == 0) + Swig_typemap_register($5,Gettype(p->p),Getname(p->p), CCode, p->args); p = p->next; } free($3); @@ -1066,7 +1068,7 @@ statement : INCLUDE STRING LBRACE { skip_brace(); p = $5; while (p) { - typemap_register($3,typemap_lang,Gettype(p->p),Getname(p->p),Char(CCode),p->args); + Swig_typemap_register($3,Gettype(p->p),Getname(p->p), CCode, p->args); p = p->next; } } @@ -1079,7 +1081,9 @@ statement : INCLUDE STRING LBRACE { TMParm *p; p = $7; while (p) { - typemap_clear($5,$3,Gettype(p->p),Getname(p->p)); + if (strcmp($3,typemap_lang) == 0) { + Swig_typemap_clear($5,Gettype(p->p),Getname(p->p)); + } p = p->next; } free($3); @@ -1096,7 +1100,7 @@ statement : INCLUDE STRING LBRACE { TMParm *p; p = $5; while (p) { - typemap_clear($3,typemap_lang,Gettype(p->p),Getname(p->p)); + Swig_typemap_clear($3,Gettype(p->p),Getname(p->p)); p = p->next; } } @@ -1109,7 +1113,9 @@ statement : INCLUDE STRING LBRACE { TMParm *p; p = $7; while (p) { - typemap_copy($5,$3,Gettype($9->p),Getname($9->p),Gettype(p->p),Getname(p->p)); + if (strcmp($3,typemap_lang) == 0) { + Swig_typemap_copy($5,Gettype($9->p),Getname($9->p),Gettype(p->p),Getname(p->p)); + } p = p->next; } free($3); @@ -1129,7 +1135,7 @@ statement : INCLUDE STRING LBRACE { TMParm *p; p = $5; while (p) { - typemap_copy($3,typemap_lang,Gettype($7->p),Getname($7->p),Gettype(p->p),Getname(p->p)); + Swig_typemap_copy($3,Gettype($7->p),Getname($7->p),Gettype(p->p),Getname(p->p)); p = p->next; } } @@ -1145,7 +1151,7 @@ statement : INCLUDE STRING LBRACE { TMParm *p; p = $4; while(p) { - typemap_apply(Gettype($2->p),Getname($2->p),Gettype(p->p),Getname(p->p)); + Swig_typemap_apply(Gettype($2->p),Getname($2->p),Gettype(p->p),Getname(p->p)); p = p->next; } free($4); @@ -1156,7 +1162,7 @@ statement : INCLUDE STRING LBRACE { TMParm *p; p = $2; while (p) { - typemap_clear_apply(Gettype(p->p), Getname(p->p)); + Swig_typemap_clear_apply(Gettype(p->p), Getname(p->p)); p = p->next; } } @@ -1171,25 +1177,27 @@ statement : INCLUDE STRING LBRACE { /* An exception definition */ | EXCEPT LPAREN ID RPAREN LBRACE { skip_brace(); - fragment_register((char *)"except",$3, Char(CCode)); + if (strcmp($3,typemap_lang) == 0) { + Swig_except_register(CCode); + } free($3); } /* A Generic Exception (no language specified */ | EXCEPT LBRACE { skip_brace(); - fragment_register((char *) "except",typemap_lang, Char(CCode)); + Swig_except_register(CCode); } /* Clear an exception */ | EXCEPT LPAREN ID RPAREN SEMI { - fragment_clear((char *) "except",$3); + Swig_except_clear(); } /* Generic clear */ | EXCEPT SEMI { - fragment_clear((char *) "except",typemap_lang); + Swig_except_clear(); } /* Miscellaenous stuff */ diff --git a/Source/SWIG1.1/swig11.h b/Source/SWIG1.1/swig11.h index 03b26d3d8..53f392e2b 100644 --- a/Source/SWIG1.1/swig11.h +++ b/Source/SWIG1.1/swig11.h @@ -267,46 +267,5 @@ extern "C" { extern int emit_args(SwigType *, ParmList *, Wrapper *f); extern void emit_func_call(char *, SwigType *, ParmList *, Wrapper *f); extern void SWIG_exit(int); - -// ----------------------------------------------------------------------- -// Typemap support -// ----------------------------------------------------------------------- -#ifndef OLD -extern void typemap_register(char *op, char *lang, SwigType *type, String_or_char *pname, String_or_char *code, ParmList *l = 0); -extern char *typemap_lookup(char *op, char *lang, SwigType *type, String_or_char *pname, String_or_char *source, String_or_char *target, Wrapper *f = 0); -extern void typemap_clear(char *op, char *lang, SwigType *type, String_or_char *pname); -extern void typemap_copy(char *op, char *lang, SwigType *stype, String_or_char *sname, - SwigType *ttype, String_or_char *tname); -extern char *typemap_check(char *op, char *lang, SwigType *type, String_or_char *pname); -extern void typemap_apply(SwigType *tm_type, String_or_char *tmname, SwigType *type, String_or_char *pname); -extern void typemap_clear_apply(SwigType *type, String_or_char *pname); extern int check_numopt(ParmList *); - -// ----------------------------------------------------------------------- -// Code fragment support -// ----------------------------------------------------------------------- - -extern void fragment_register(char *op, char *lang, String_or_char *code); -extern char *fragment_lookup(char *op, char *lang); -extern void fragment_clear(char *op, char *lang); - -#else - -#define typemap_register(op,lang,type,pname,code,l) -#define typemap_register_default(op,lang,type,ptr,arraystr,code,l) -#define typemap_lookup(op,lang,type,pname,source,target,f) 0 - -#define typemap_clear(op,lang,type,pname) -#define typemap_copy(op,lang,stype,sname,ttype,tname) -#define typemap_check(op,lang,type,pname) 0 -#define typemap_apply(tm,tmname,type,pname) -#define typemap_clear_apply(type,pname) -#define check_numopt(l) ParmList_len(l) -#define fragment_register(op,lang,code) -#define fragment_lookup(op,lang,age) 0 -#define fragment_clear(op,lang) - -#endif - - diff --git a/Source/SWIG1.1/typemap.cxx b/Source/SWIG1.1/typemap.cxx deleted file mode 100644 index a9de3a04c..000000000 --- a/Source/SWIG1.1/typemap.cxx +++ /dev/null @@ -1,969 +0,0 @@ -/* ----------------------------------------------------------------------------- - * typemap.cxx - * - * Typemap support. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 1998-2000. The University of Chicago - * Copyright (C) 1995-1998. The University of Utah and The Regents of the - * University of California. - * - * See the file LICENSE for information on usage and redistribution. - * ----------------------------------------------------------------------------- */ - -static char cvsroot[] = "$Header$"; - -#include "internal.h" -#include - -extern "C" { -#include "doh.h" -} - -/* ------------------------------------------------------------------------ - * This file provides universal support for typemaps. Typemaps are created - * using the following SWIG command in an interface file: - * - * %typemap(lang,operation) type { code } Make a new typemap - * %typemap(lang,operation) type; Clears any previous typemap - * - * lang is an identifier indicating the target language. The typemap will - * simply be ignored if its for a different language. The code is the - * corresponding C code for the mapping. An example typemap might look - * like this : - * - * %typemap(tcl,get) double { - * $target = atof($source); - * } - * %typemap(tcl,set) double { - * sprintf($target,"%0.17f",$source); - * } - * - * The variables $target and $source should be used in any type-mappings. - * Additional local variables can be created, but this should be done - * by enclosing the entire code fragment in an extra set of braces. - * - * The C++ API to the type-mapper is as follows : - * - * void typemap_register(char *op, char *lang, DataType *type, char *pname, String &getcode, ParmList *args) - * char *typemap_lookup(char *op, char *lang, DataType *type, char *pname, char *source, char *target); - * void typemap_clear(char *op, char *lang, DataType *type, char *pname); - * - * The lookup functions return a character string corresponding to the type-mapping - * code or NULL if none exists. The string return will have the source and target - * strings substituted for the strings "$source" and "$target" in the type-mapping code. - * - * (2/19/97) This module has been extended somewhat to provide generic mappings - * of other parts of the code--most notably exceptions. - * - * void fragment_register(char *op, char *lang, String &code) - * char fragment_lookup(char *op, char *lang, int age); - * char fragment_clear(char *op, char *lang); - * - * ------------------------------------------------------------------------ */ - -static ParmList *last_args = 0; -char *typemap_lang = 0; // Typemap language name - -int type_id = 0; - -/* Structure for holding a typemap */ - -struct TypeMap { - char *lang; - SwigType *type; - DOHString *code; - int first; - int last; - TypeMap *next; - TypeMap *previous; /* Previously defined typemap (if any) */ - ParmList *args; /* Local variables (if any) */ - - TypeMap(char *l, SwigType *t, String_or_char *c, ParmList *p = 0) { - lang = Swig_copy_string(l); - type = Copy(t); - code = NewString(c); - first = type_id; - last = INT_MAX; - next = 0; - previous = 0; - if (p) { - args = CopyParmList(p); - } else { - args = 0; - } - } - TypeMap(char *l, String_or_char *c) { - lang = Swig_copy_string(l); - type = 0; - code = NewString(c); - first = type_id; - last = INT_MAX; - next = 0; - previous = 0; - args = 0; - } - TypeMap(TypeMap *t) { - lang = Swig_copy_string(t->lang); - type = Copy(t->type); - code = Copy(t->code); - first = type_id; - last = INT_MAX; - next = 0; - previous = t->previous; - if (args) { - args = CopyParmList(args); - } else { - args = 0; - } - } -}; - -/* Hash tables for storing type-mappings */ - -static DOH *typemap_hash = 0; - -/* Structure for holding "applications of a typemap" */ - -struct TmMethod { - String *name; /* Typemap name; */ - SwigType *type; /* Typemap type */ - TmMethod *next; /* Next method */ - TmMethod(String *n, SwigType *t, TmMethod *m = 0) { - if (n) name = Copy(n); - else name = 0; - if (t) { - type = Copy(t); - } else { - type = 0; - } - next = m; - } -}; - -/* Hash table for storing applications of a datatype */ - -static DOH *application_hash = 0; - -/* ------------------------------------------------------------------------ - * void typemap_apply(DataType *tm_type, char *tm_name, DataType *type, char *pname) - * - * Attempts to apply a typemap given by (tm_type,tm_name) to (type,pname) - * Called by the %apply directive. - * ------------------------------------------------------------------------ */ - -void typemap_apply(SwigType *tm_type, String_or_char *tm_name, SwigType *type, String_or_char *pname) { - TmMethod *m,*m1; - String *temp; - - /* Form the application name */ - if (!pname) pname = (String_or_char*)""; - temp = NewStringf("%s$%s",SwigType_str(type,0),pname); - - /* See if there is a method already defined */ - - if (!application_hash) application_hash = NewHash(); - m = (TmMethod *) GetVoid(application_hash,temp); - - if (!m) { - m = new TmMethod(temp,type,0); - SetVoid(application_hash,temp,m); - } - - Delete(temp); - - /* Check to see if an array typemap has been applied to a non-array type */ - - if ((SwigType_isarray(tm_type)) && (!SwigType_isarray(type))) { - Printf(stderr,"%s:%d: Warning. Array typemap has been applied to a non-array type.\n", - input_file,line_number); - } - - /* If both are arrays, make sure they have the same dimension */ - - if ((SwigType_isarray(tm_type)) && (SwigType_isarray(type))) { - if (SwigType_array_ndim(tm_type) != SwigType_array_ndim(type)) { - Printf(stderr,"%s:%d: Warning. Array types have different number of dimensions.\n", - input_file,line_number); - } else { - for (int i = 0; i < SwigType_array_ndim(tm_type); i++) { - String *s1 = SwigType_array_getdim(tm_type,i); - String *s2 = SwigType_array_getdim(type,i); - if (Cmp(s1,"") != 0) { - if (Cmp(s1,s2)) - Printf(stderr,"%s:%d: Warning. Array typemap applied to an array of different size.\n", - input_file, line_number); - } - } - } - } - - /* Add a new mapping corresponding to the typemap */ - m1 = new TmMethod(tm_name,tm_type,m->next); - m->next = m1; - -} -/* ------------------------------------------------------------------------ - * void typemap_clear_apply(SwigType *type, char *pname) - * - * Clears the application of a typemap. - * Called by the %clear directive. - * ------------------------------------------------------------------------ */ - -void typemap_clear_apply(SwigType *type, String_or_char *pname) { - String *temp; - if (!pname) pname = (String_or_char*)""; - temp = NewStringf("%s$%s", SwigType_str(type,0), pname); - if (!application_hash) application_hash = NewHash(); - Delattr(application_hash,temp); - Delete(temp); -} - -/* ------------------------------------------------------------------------ - * char *typemap_string() - * - * Produces a character string corresponding to a lang, datatype, and - * method. This string is used as the key for our typemap hash table. - * ------------------------------------------------------------------------ */ - -static char *typemap_string(char *op, SwigType *type, String_or_char *pname) { - static char str[1024]; - sprintf(str,"%s-%s-%s",op, Char(type), Char(pname)); - return str; -} - -/* ------------------------------------------------------------------------ - * void typemap_register(char *op, char *lang, DataType *type, char *pname, - * char *getcode, ParmList *args) - * - * Register a new mapping with the type-mapper. - * ------------------------------------------------------------------------ */ - -void typemap_register(char *op, char *lang, SwigType *type, String_or_char *pname, - String_or_char *getcode, ParmList *args) { - - char *key; - TypeMap *tm, *tm_old; - int is_default = 0; - - if (!typemap_lang || (strcmp(typemap_lang,lang))) return; - if (!typemap_hash) typemap_hash = NewHash(); - - tm = new TypeMap(lang,type,getcode,args); - /* If this is a default typemap, downgrade the type! */ - - if (Cmp(pname,"SWIG_DEFAULT_TYPE") == 0) { - tm->type = SwigType_default(tm->type); - is_default = 1; - } - - key = typemap_string(op,tm->type,pname); - - /* Get any previous setting of the typemap */ - tm_old = (TypeMap *) GetVoid(typemap_hash, key); - if (tm_old) { - - /* Perform a chaining operation, but only if the last typemap is active. */ - /* If found, we need to attach the old version to the new one */ - - tm->previous = tm_old; - tm->next = tm_old; - tm_old->last = type_id; - } - - /* Add new typemap to the hash table */ - SetVoid(typemap_hash,key,tm); - - /* Just a sanity check to make sure args look okay. */ - - if (args) { - Parm *p = tm->args; - while (p) { - String *pn = Getname(p); - if (pn) { - /* printf(" %s %s\n", pt,pn); */ - } else { - Printf(stderr,"%s:%d: Typemap error. Local variables must have a name\n", - input_file, line_number); - } - p = Getnext(p); - } - } -} - -/* ------------------------------------------------------------------------ - * static TypeMap *typemap_search(char *key, int id) - * - * An internal function for searching for a particular typemap given - * a key value and datatype id. - * - * Basically this checks the hash table and then checks the id against - * first and last values, looking for a match. This is to properly - * handle scoping problems. - * ------------------------------------------------------------------------ */ - -static TypeMap * -typemap_search(String_or_char *key, int id) { - TypeMap *tm; - if (!typemap_hash) typemap_hash = NewHash(); - tm = (TypeMap *) GetVoid(typemap_hash,key); - while (tm) { - if ((id >= tm->first) && (id < tm->last)) return tm; - else tm = tm->next; - } - return tm; -} - -/* ------------------------------------------------------------------------ - * TypeMap *typemap_search_array(char *op, char *lang, DataType *type, char *pname, DOHString *str) - * - * Performs a typemap lookup on an array type. This is abit complicated - * because we need to look for ANY tags specifying that any array dimension - * is valid. The resulting code will be placed in str with dimension variables - * substituted. - * ------------------------------------------------------------------------ */ - -static -TypeMap *typemap_search_array(char *op, char *lang, SwigType *type, String_or_char *pname, DOHString *str) { - SwigType *atype; - char *key; - int ndim,i,j,k,n; - TypeMap *tm; - char temp[10]; - - if (!SwigType_isarray(type)) return 0; - - /* First check to see if exactly this array has been mapped */ - - key = typemap_string(op,type,pname); - tm = typemap_search(key,type_id); - - /* Check for unnamed array of specific dimensions */ - if (!tm) { - key = typemap_string(op,type,(char*)""); - tm = typemap_search(key,type_id); - } - - if (!tm) { - /* We're going to go search for matches with the ANY tag */ - ndim = SwigType_array_ndim(type); /* Get number of dimensions */ - j = (1 << ndim) - 1; /* Status bits */ - for (i = 0; i < (1 << ndim); i++) { - /* Form an array string */ - atype = Copy(type); - k = j; - for (n = 0; n < ndim; n++) { - if (!(k & 1)) { - SwigType_array_setdim(atype,n,"ANY"); - } - k = k >> 1; - } - key = typemap_string(op,type,pname); - tm = typemap_search(key,type_id); - if (!tm) { - key = typemap_string(op,type,(char*)""); - tm = typemap_search(key,type_id); - } - if (tm) { - Delete(atype); - break; - } - j--; - Delete(atype); - } - } - - if (tm) { - Printf(str,"%s",tm->code); - ndim = SwigType_array_ndim(type); - sprintf(temp,"%d",ndim); - Replace(str,"$ndim",temp, DOH_REPLACE_ANY); - for (i = 0; i < ndim; i++) { - sprintf(temp,"$dim%d",i); - Replace(str,temp,SwigType_array_getdim(type,i), DOH_REPLACE_ANY); - } - } - return tm; -} - -/* ------------------------------------------------------------------------ - * static typemap_locals(Datatype *t, char *pname, String &s, ParmList *l, Wrapper *f) - * - * Takes a string, a parameter list and a wrapper function argument and - * starts creating local variables. - * - * Substitutes locals in the string with actual values used. - * ------------------------------------------------------------------------ */ - -static void typemap_locals(SwigType *t, String_or_char *pname, DOHString *s, ParmList *l, Wrapper *f) { - Parm *p; - char *new_name; - - p = l; - while (p) { - SwigType *pt = Gettype(p); - String *pn = Getname(p); - if (pn) { - if (Len(pn) > 0) { - DOHString *str; - SwigType *tt; - - str = NewString(""); - /* If the user gave us $type as the name of the local variable, we'll use - the passed datatype instead */ - - if (Cmp(SwigType_base(pt),"$type")==0 || Cmp(SwigType_base(pt),"$basetype")==0) { - tt = t; - } else { - tt = pt; - } - Printf(str,"%s",pn); - /* Substitute parameter names */ - Replace(str,"$arg",pname, DOH_REPLACE_ANY); - if (Cmp(SwigType_base(pt),"$basetype")==0) { - /* use $basetype */ - new_name = Wrapper_new_localv(f,str,SwigType_base(tt),str,0); - } else { - new_name = Wrapper_new_localv(f,str, SwigType_str(tt,str), 0); - } - /* Substitute */ - Replace(s,pn,new_name,DOH_REPLACE_ID); - } - } - p = Getnext(l); - } - /* If the original datatype was an array. We're going to go through and substitute - it's array dimensions */ - - if (SwigType_isarray(t)) { - char temp[10]; - for (int i = 0; i < SwigType_array_ndim(t); i++) { - sprintf(temp,"$dim%d",i); - Replace(f->locals,temp,SwigType_array_getdim(t,i), DOH_REPLACE_ANY); - } - } -} - -/* ------------------------------------------------------------------------ - * char *typemap_lookup(char *op, char *lang, DataType *type, char *pname, char *source, - * char *target, WrapperFunction *f) - * - * Looks up a "get" function in the type-map and returns a character string - * containing the appropriate translation code. - * - * op is string code for type of mapping - * lang is the target language string - * type is the datatype - * pname is an optional parameter name - * source is a string with the source variable - * target is a string containing the target value - * f is a wrapper function object (optional) - * - * Returns NULL if no mapping is found. - * - * Typemaps follow a few rules regarding naming and C pointers by checking - * declarations in this order. - * - * 1. type name [] - A named array (most specific) - * 2. type name - Named argument - * 3. type [] - Type with array - * 4. type - Ordinary type - * - * Array checking is only made if the datatype actally has an array specifier - * - * Array checking uses a special token "ANY" that indicates that any - * dimension will match. Since we are passed a real datatype here, we - * need to hack this a special case. - * - * Array dimensions are substituted into the variables $dim1, $dim2,...,$dim9 - * ------------------------------------------------------------------------ */ - -static SwigType *realtype; /* This is a gross hack */ -static String *realname = 0; /* Real parameter name */ - -static char *typemap_lookup_internal(char *op, char *lang, SwigType *type, String_or_char *pname, - String_or_char *source, String_or_char *target, Wrapper *f) { - String *str = 0; - char *key = 0; - TypeMap *tm = 0; - - last_args = 0; - if (!lang) { - return 0; - } - str = NewString(""); - /* First check for named array */ - tm = typemap_search_array(op,lang,type,pname,str); - - /* Check for named argument */ - if (!tm) { - key = typemap_string(op,type,pname); - tm = typemap_search(key,type_id); - if (tm) - Printf(str,"%s",tm->code); - } - - /* Check for unnamed type */ - if (!tm) { - key = typemap_string(op,type,(char*)""); - tm = typemap_search(key,type_id); - if (tm) - Printf(str,"%s", tm->code); - } - if (!tm) { - Delete(str); - return 0; - } - - /* Now perform character replacements */ - - Replace(str,"$source",source,DOH_REPLACE_ANY); - Replace(str,"$target",target,DOH_REPLACE_ANY); - Replace(str,"$type",SwigType_str(realtype,0),DOH_REPLACE_ANY); - if (realname) { - Replace(str,"$parmname",realname,DOH_REPLACE_ANY); - } else { - Replace(str,"$parmname","", DOH_REPLACE_ANY); - } - /* Print base type (without any pointers) */ - Replace(str,"$basetype",SwigType_base(realtype), DOH_REPLACE_ANY); - Replace(str,"$basemangle",SwigType_manglestr(SwigType_base(realtype)), DOH_REPLACE_ANY); - Replace(str,"$mangle",SwigType_manglestr(realtype), DOH_REPLACE_ANY); - - /* If there were locals and a wrapper function, replace */ - if ((tm->args) && f) { - typemap_locals(realtype, pname, str,tm->args,f); - } - - /* Return character string */ - last_args = tm->args; - Swig_temp_result(str); - return Char(str); -} - -/* ---------------------------------------------------------- - * Real function call that takes care of application mappings - * ---------------------------------------------------------- */ - -char *typemap_lookup(char *op, char *lang, SwigType *type, String_or_char *pname, String_or_char *source, - String_or_char *target, Wrapper *f) { - TmMethod *m; - char *result; - String *temp; - - realtype = type; /* The other half of the gross hack */ - realname = pname; - - // Printf(stdout,"Looking up %s\n", SwigType_str(type,pname)); - - /* Try to apply typemap right away */ - - result = typemap_lookup_internal(op,lang,type,pname,source,target,f); - - /* If not found, try to pick up anything that might have been - specified with %apply */ - - if (!result) { - temp = NewStringf("%s$%s", SwigType_str(type,0), pname); - m = (TmMethod *) GetVoid(application_hash,temp); - if (!m) { - Clear(temp); - Printf(temp,"%s$",SwigType_str(type,0)); - m = (TmMethod *) GetVoid(application_hash,temp); - } - Delete(temp); - if (m) { - m = m->next; - while (m) { - result = typemap_lookup_internal(op,lang,m->type,m->name,source,target,f); - if (result) { - return result; - } - m = m->next; - } - } - } - - /* Still no idea, try to find a default typemap */ - - if (!result) { - SwigType *t = SwigType_default(type); - result = typemap_lookup_internal(op,lang,t,(char*)"SWIG_DEFAULT_TYPE",source,target,f); - if (result) { - Delete(t); - return result; - } - Delete(t); - } - return result; -} - -/* ---------------------------------------------------------------------------- - * char *typemap_check(char *op, char *lang, SwigType *type, String_or_char *pname) - * - * Checks to see if there is a typemap. Returns typemap string if found, NULL - * if not. - * ---------------------------------------------------------------------------- */ - -char *typemap_check_internal(char *op, char *lang, SwigType *type, String_or_char *pname) { - DOHString *str = 0; - char *key = 0; - TypeMap *tm = 0; - - - if (!lang) { - return 0; - } - str = NewString(""); - - /* First check for named array */ - - tm = typemap_search_array(op,lang,type,pname,str); - - /* Check for named argument */ - if (!tm) { - key = typemap_string(op,type,pname); - tm = typemap_search(key,type_id); - } - - /* Check for unnamed array */ - if ((!tm) && (SwigType_isarray(type))) { - key = typemap_string(op,type,(char*)""); - tm = typemap_search(key,type_id); - } - - /* Check for unnamed type */ - if (!tm) { - key = typemap_string(op,type,(char*)""); - tm = typemap_search(key,type_id); - } - if (!tm) { - Delete(str); - return 0; - } - Printf(str,"%s",tm->code); - /* Return character string */ - Swig_temp_result(str); - return Char(str); -} - -/** Function for checking with applications */ - -char *typemap_check(char *op, char *lang, SwigType *type, String_or_char *pname) { - TmMethod *m; - String *temp; - char *result; - - /* Try to apply typemap right away */ - - result = typemap_check_internal(op,lang,type,pname); - - /* If not found, try to pick up anything that might have been - specified with %apply */ - - if (!result) { - temp = NewStringf("%s$%s", SwigType_str(type,0), pname); - m = (TmMethod *) GetVoid(application_hash,temp); - if (!m) { - Clear(temp); - Printf(temp,"%s$",SwigType_str(type,0)); - m = (TmMethod *) GetVoid(application_hash,temp); - } - Delete(temp); - if (m) { - m = m->next; - while (m) { - result = typemap_check_internal(op,lang,m->type,m->name); - if (result) { - return result; - } - m = m->next; - } - } - } - - /* If still no result, might have a default typemap */ - if (!result) { - SwigType *t = SwigType_default(type); - result = typemap_check_internal(op,lang,t,(char*)"SWIG_DEFAULT_TYPE"); - if (result) { - Delete(t); - return result; - } - Delete(t); - } - return result; -} - -/* ------------------------------------------------------------------------ - * void typemap_clear(char *op, char *lang, DataType *type, char *pname) - * - * Clears any previous typemap. This works like a stack. Clearing a - * typemap returns to any previous typemap in force. If there is no - * previous map, then don't worry about it. - * ------------------------------------------------------------------------ */ - -void typemap_clear(char *op, char *lang, SwigType *type, String_or_char *pname) { - - char *key; - TypeMap *tm; - - if (!typemap_lang || (strcmp(lang,typemap_lang))) return; - key = typemap_string(op,type,pname); - - /* Look for any previous version, simply set the last id if - applicable. */ - - if (!typemap_hash) typemap_hash = NewHash(); - tm = (TypeMap *) GetVoid(typemap_hash,key); - if (tm) { - if (tm->last > type_id) tm->last = type_id; - } -} - -/* ------------------------------------------------------------------------ - * void typemap_copy(char *op, char *lang, DataType *stype, char *sname, - * DataType *ttype, char *tname) - * - * Copies the code associate with a typemap - * ------------------------------------------------------------------------ */ - -void typemap_copy(char *op, char *lang, SwigType *stype, String_or_char *sname, - SwigType *ttype, String_or_char *tname) { - - char *key; - TypeMap *tm; - - /* Try to locate a previous typemap */ - if (!typemap_lang || (strcmp(typemap_lang,lang))) return; - - key = typemap_string(op,stype,sname); - tm = typemap_search(key,type_id); - if (!tm) return; - typemap_register(op,lang,ttype,tname,tm->code,tm->args); -} - -/* ------------------------------------------------------------------------ - * char *fragment_string(char *op, char *lang) - * - * Produces a character string corresponding to a language and method - * This string is used as the key for our typemap hash table. - * ------------------------------------------------------------------------ */ - -static char *fragment_string(char *op) { - static char str[512]; - sprintf(str,"fragment:%s", op); - return str; -} - -/* ------------------------------------------------------------------------ - * void fragment_register(char *op, char *lang, char *code) - * - * Register a code fragment with the type-mapper. - * ------------------------------------------------------------------------ */ - -void fragment_register(char *op, char *lang, String_or_char *code) { - - char *key; - TypeMap *tm,*tm_old; - char temp[256]; - - if (!typemap_lang || (strcmp(typemap_lang,lang))) return; - - tm = new TypeMap(lang,code); - key = fragment_string(op); - - /* Get any previous setting of the typemap */ - - tm_old = (TypeMap *) GetVoid(typemap_hash,key); - if (tm_old) { - /* If found, we need to attach the old version to the new one */ - - /* Perform a chaining operation */ - - sprintf(temp,"$%s",op); - if (type_id < tm_old->last) - Replace(tm->code,temp,tm_old->code,DOH_REPLACE_ANY); - - tm->next = tm_old; - tm_old->last = type_id; - - /* Remove the old one from the hash */ - - Delattr(typemap_hash,key); - } - - /* Perform a default chaining operation if needed (defaults to nothing) */ - sprintf(temp,"$%s",op); - Replace(tm->code,temp,"", DOH_REPLACE_ANY); - - /* Add new typemap to the hash table */ - SetVoid(typemap_hash,key,tm); -} - - -/* ------------------------------------------------------------------------ - * char *fragment_lookup(char *op, char *lang) - * - * op is string code for type of mapping - * lang is the target language string - * - * Returns NULL if no mapping is found. - * - * ------------------------------------------------------------------------ */ - -char *fragment_lookup(char *op, char *lang) { - DOHString *str; - char *key = 0; - TypeMap *tm = 0; - - if (!typemap_lang || (strcmp(typemap_lang,lang))) return 0; - - str = NewString(""); - key = fragment_string(op); - tm = typemap_search(key,type_id); - - if (!tm) return 0; - - Append(str,tm->code); - Swig_temp_result(str); - return Char(str); -} - -/* ------------------------------------------------------------------------ - * void fragment_clear(char *op, char *lang) - * - * Clears any previous fragment definition. Is a stack operation--will - * restore any previously declared typemap. - * ------------------------------------------------------------------------ */ - -void fragment_clear(char *op, char *lang) { - - char *key; - TypeMap *tm; - - if (!typemap_lang || (strcmp(typemap_lang,lang))) return; - - key = fragment_string(op); - - /* Look for any previous version, simply set the last id if - applicable. */ - - tm = (TypeMap *) GetVoid(typemap_hash,key); - if (tm) { - if (tm->last > type_id) tm->last = type_id; - } -} - -/* ----------------------------------------------------------------------------- - * typemap_initialize() - * - * Initialize the hash tables - * ----------------------------------------------------------------------------- */ - -void -typemap_initialize() { - typemap_hash = NewHash(); - application_hash = NewHash(); -} - - -/* ------------------------------------------------------------------ - * int check_numopt() - * - * Gets the number of optional arguments for a ParmList. - * ------------------------------------------------------------------ */ - -int check_numopt(ParmList *p) { - int n = 0; - int i = 0; - int state = 0; - - for (;p; p = Getnext(p),i++) { - SwigType *pt = Gettype(p); - String *pn = Getname(p); - if (Getvalue(p)) { - n++; - state = 1; - } else if (typemap_check((char*)"default",typemap_lang,pt,pn)) { - n++; - state = 1; - } else if (typemap_check((char*)"ignore",typemap_lang,pt,pn)) { - n++; - } else { - if (state) { - Printf(stderr,"%s : Line %d. Argument %d must have a default value!\n", input_file,line_number,i+1); - } - } - } - return n; -} - - -/* ----------------------------------------------------------------------------- - * typemap_match_parms() - * - * Match typemaps for a list of parameters. This function is only a hack to - * ease the migration to the new SWIG typemap system. Returns a DOH list - * of hash table objects containing all of the matches. - * ----------------------------------------------------------------------------- */ - -DOHList * -typemap_match_parms(ParmList *l) { - - DOHList *tl; - DOHHash *tm; - Parm *p; - - char *s; - tl = NewList(); - - p = l; - while (p) { - SwigType *pt = Gettype(p); - String *pn = Getname(p); - ParmList *vars = 0; - - tm = NewHash(); - - /* Look up all of the argument related typemaps */ - /* "in" */ - if ((s = typemap_lookup((char*)"in",typemap_lang,pt,pn,(char *)"$source",(char *)"$target",0))) { - Setattr(tm,"in",s); - } - - /* "ignore" */ - if ((s = typemap_lookup((char*)"ignore",typemap_lang,pt,pn,(char *)"$source",(char *)"$target",0))) { - Setattr(tm,"ignore",s); - } - - /* "argout" */ - if ((s = typemap_lookup((char*)"argout",typemap_lang,pt,pn,(char *)"$source",(char *)"$target",0))) { - Setattr(tm,"argout",s); - } - - /* "default" */ - if ((s = typemap_lookup((char*)"default",typemap_lang,pt,pn,(char *)"$source",(char *)"$target",0))) { - Setattr(tm,"default",s); - } - - /* "check" */ - if ((s = typemap_lookup((char*)"check",typemap_lang,pt,pn,(char *)"$source",(char *)"$target",0))) { - Setattr(tm,"check",s); - } - - /* "arginit" */ - if ((s = typemap_lookup((char*)"arginit",typemap_lang,pt,pn,(char *)"$source",(char *)"$target",0))) { - Setattr(tm,"arginit",s); - } - Setattr(tm,"locals", vars); - Append(tl,tm); - Delete(tm); - p = Getnext(p); - } - return tl; -} - - - diff --git a/Source/Swig/Makefile.in b/Source/Swig/Makefile.in index c4ebd1499..228714e9d 100644 --- a/Source/Swig/Makefile.in +++ b/Source/Swig/Makefile.in @@ -6,9 +6,9 @@ srcdir = @srcdir@ VPATH = @srcdir@ SRCS = map.c wrapfunc.c naming.c tree.c stype.c scanner.c include.c getopt.c misc.c \ - parms.c cwrap.c + parms.c cwrap.c typemap.c OBJS = map.o wrapfunc.o naming.o tree.o stype.o scanner.o include.o getopt.o misc.o \ - parms.o cwrap.o + parms.o cwrap.o typemap.o prefix = @prefix@ exec_prefix = @exec_prefix@ diff --git a/Source/Swig/map.c b/Source/Swig/map.c index ed788cbab..6dee6dcd6 100644 --- a/Source/Swig/map.c +++ b/Source/Swig/map.c @@ -346,3 +346,8 @@ Swig_map_match_type(Hash *ruleset, DOH *type, String_or_char *name) { Delete(p); return obj; } + + + + + diff --git a/Source/Swig/oldtypes.c b/Source/Swig/oldtypes.c deleted file mode 100644 index 04c3afd71..000000000 --- a/Source/Swig/oldtypes.c +++ /dev/null @@ -1,1229 +0,0 @@ -/* ----------------------------------------------------------------------------- - * types.cxx - * - * This file contains code for SWIG1.1 type objects. - * - * !!! This file is deprecated and is being replaced !!! - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 1998-2000. The University of Chicago - * Copyright (C) 1995-1998. The University of Utah and The Regents of the - * University of California. - * - * See the file LICENSE for information on usage and redistribution. - * ----------------------------------------------------------------------------- */ - -static char cvsroot[] = "$Header$"; - -#include "swig.h" - -int type_id = 0; - -/* Create a data type only from the type code (used to form constants) */ - -DataType *NewDataType(int t) { - DataType *ty = (DataType *) malloc(sizeof(DataType)); - switch(t) { - case T_BOOL: - strcpy(ty->_name,"bool"); - break; - case T_INT: - strcpy(ty->_name,"int"); - break; - case T_UINT: - strcpy(ty->_name,"unsigned int"); - break; - case T_SHORT: - strcpy(ty->_name,"short"); - break; - case T_USHORT: - strcpy(ty->_name,"unsigned short"); - break; - case T_LONG: - strcpy(ty->_name,"long"); - break; - case T_ULONG: - strcpy(ty->_name,"unsigned long"); - break; - case T_FLOAT: - strcpy(ty->_name, "float"); - break; - case T_DOUBLE: - strcpy(ty->_name, "double"); - break; - case T_CHAR: case T_SCHAR: - strcpy(ty->_name, "char"); - break; - case T_UCHAR: - strcpy(ty->_name,"unsigned char"); - break; - case T_VOID: - strcpy(ty->_name,"void"); - break; - case T_USER: - strcpy(ty->_name,"USER"); - break; - default : - strcpy(ty->_name,""); - break; - } - ty->_type = t; - ty->_is_pointer = 0; - ty->_implicit_ptr = 0; - ty->_qualifier = 0; - ty->_is_reference = 0; - ty->_status = 0; - ty->_arraystr = 0; - ty->_id = type_id++; - return ty; -} - -DataType *CopyDataType(DataType *t) { - DataType *ty = (DataType *) malloc(sizeof(DataType)); - ty->_type = t->_type; - strcpy(ty->_name,t->_name); - ty->_is_pointer = t->_is_pointer; - ty->_implicit_ptr = t->_implicit_ptr; - ty->_qualifier = Swig_copy_string(t->_qualifier); - ty->_is_reference = t->_is_reference; - ty->_status = t->_status; - ty->_arraystr = Swig_copy_string(t->_arraystr); - ty->_id = t->_id; - return ty; -} - -void DelDataType(DataType *t) { - if (t->_qualifier) free(t->_qualifier); - if (t->_arraystr) free(t->_arraystr); - free(t); -} - -int DataType_type(DataType *t) { - if ((t->_type == T_CHAR) && (t->_is_pointer == 1)) return T_STRING; - if (t->_arraystr) return T_ARRAY; - if (t->_is_reference) return T_REFERENCE; - if (t->_is_pointer) return T_POINTER; - return t->_type; -} - -int DataType_Gettypecode(DataType *t) { - return t->_type; -} - -void DataType_Settypecode(DataType *t, int ty) { - t->_type = ty; -} - -char *DataType_qualifier(DataType *t) { - return t->_qualifier; -} - -void DataType_set_qualifier(DataType *t, char *q) { - if (t->_qualifier) free(t->_qualifier); - t->_qualifier = Swig_copy_string(q); -} - -char *DataType_arraystr(DataType *t) { - return t->_arraystr; -} - -void DataType_set_arraystr(DataType *t, char *a) { - if (t->_arraystr) free(t->_arraystr); - t->_arraystr = Swig_copy_string(a); -} - -void DataType_add_reference(DataType *t) { - t->_is_reference = 1; -} - -int DataType_is_reference(DataType *t) { - return t->_is_reference; -} - -int DataType_is_pointer(DataType *t) { - return t->_is_pointer; -} - -void DataType_add_pointer(DataType *t) { - t->_is_pointer++; -} - -void DataType_del_pointer(DataType *t) { - t->_is_pointer--; -} - -void DataType_Setname(DataType *t, char *n) { - strcpy(t->_name, n); -} - -char *DataType_Getname(DataType *t) { - return t->_name; -} - -/* -------------------------------------------------------------------- - * DataType_primitive() - * - * Turns a datatype into its bare-bones primitive type. Rarely used, - * but sometimes used for typemaps. Permanently alters the datatype! - * -------------------------------------------------------------------- */ - -void DataType_primitive(DataType *t) { - switch(t->_type) { - case T_BOOL: - strcpy(t->_name,"bool"); - break; - case T_INT: - strcpy(t->_name,"int"); - break; - case T_SHORT: - strcpy(t->_name,"short"); - break; - case T_LONG: - strcpy(t->_name,"long"); - break; - case T_CHAR: - strcpy(t->_name,"char"); - break; - case T_SCHAR: - strcpy(t->_name,"signed char"); - break; - case T_UINT: - strcpy(t->_name,"unsigned int"); - break; - case T_USHORT: - strcpy(t->_name,"unsigned short"); - break; - case T_ULONG: - strcpy(t->_name,"unsigned long"); - break; - case T_UCHAR: - strcpy(t->_name,"unsigned char"); - break; - case T_FLOAT: - strcpy(t->_name,"float"); - break; - case T_DOUBLE: - strcpy(t->_name,"double"); - break; - case T_VOID: - strcpy(t->_name,"void"); - break; - case T_USER: - strcpy(t->_name,"USER"); - break; - default: - strcpy(t->_name,"UNKNOWN"); - break; - } - t->_implicit_ptr = 0; /* Gets rid of typedef'd pointers */ - if (t->_qualifier) { - free(t->_qualifier); - t->_qualifier = 0; - } - t->_qualifier = 0; - t->_status = 0; -} - -/* -------------------------------------------------------------------- - * char *mangle_default() - * - * Prints a mangled version of this datatype. Used for run-time type - * checking in order to print out a "language friendly" version (ie. no - * spaces and no weird characters). - * -------------------------------------------------------------------- */ - -char *DataType_mangle_default(DataType *t) { - static char result[8][256]; - static int ri = 0; - int i; - char *c; - char *d; - - ri = ri % 8; - c = t->_name; - - result[ri][0] = '_'; - - d = result[ri] + 1; - - if ((strncmp(c,"struct ",7) == 0) || (strncmp(c,"class ",6) == 0) || (strncmp(c,"union ",6) == 0)) { - c = strchr(c,' ') + 1; - } - for (; *c; c++) { - if ((*c == ' ') || (*c == ':') || (*c == '<') || (*c == '>')) *(d++) = '_'; - else *(d++) = *c; - } - if ((t->_is_pointer-t->_implicit_ptr)) *(d++) = '_'; - for (i = 0; i < (t->_is_pointer-t->_implicit_ptr); i++) - *(d++) = 'p'; - - *d = 0; - return result[ri++]; -} - -/* This is kind of ugly but needed for each language to support a - custom name mangling mechanism. (ie. Perl5). */ - -static char *(*mangler)(DataType *t) = DataType_mangle_default; - -char *DataType_manglestr(DataType *t) { - /* Call into target language for name mangling. */ - return (*mangler)(t); -} - -void DataType_set_mangle(char *(*m)(DataType *t)) { - mangler = m; -} - -/* ----------------------------------------------------------------------------- - * char *DataType_str() - * - * Produces an exact string representation of the datatype along with an optional - * variable name. - * ----------------------------------------------------------------------------- */ - -char *DataType_str(DataType *t, DOHString_or_char *name) { - static char result[8][256]; - static int ri = 0; - int i; - - ri = ri % 8; - if (t->_arraystr) t->_is_pointer--; - if (t->_is_reference) t->_is_pointer--; - if (t->_qualifier) { - sprintf(result[ri],"%s %s", t->_qualifier, t->_name); - } else { - sprintf(result[ri],"%s ", t->_name); - } - - for (i = 0; i < (t->_is_pointer-t->_implicit_ptr); i++) { - strcat(result[ri],"*"); - } - if (t->_is_reference) strcat(result[ri],"&"); - if (name) strcat(result[ri],Char(name)); - if (t->_arraystr) { - strcat(result[ri],t->_arraystr); - t->_is_pointer++; - } - if (t->_is_reference) t->_is_pointer++; - return result[ri++]; -} - -/* -------------------------------------------------------------------- - * char *DataType_lstr() - * - * Produces a type-string that is suitable as a lvalue in an expression. - * That is, a type that can be freely assigned a value without violating - * any C assignment rules. - * - * - Qualifiers such as 'const' and 'volatile' are stripped. - * - Arrays are converted into a *single* pointer (i.e., - * double [][] becomes double *). - * - References are converted into a pointer. - * - Typedef names that refer to read-only types will be replaced - * with an equivalent assignable version. - * -------------------------------------------------------------------- */ - -char *DataType_lstr(DataType *ty, DOHString_or_char *name) { - static char result[8][256]; - static int ri = 0; - int i; - DataType *t = ty; - - if (ty->_status & STAT_REPLACETYPE) { - t = CopyDataType(ty); - DataType_typedef_replace(t); /* Replace the type with its typedef value */ - } - ri = ri % 8; - sprintf(result[ri],"%s ", t->_name); - for (i = 0; i < (t->_is_pointer-t->_implicit_ptr); i++) - strcat(result[ri],"*"); - - if (ty->_status & STAT_REPLACETYPE) { - DelDataType(t); - } - if (name) { - strcat(result[ri],Char(name)); - } - return result[ri++]; -} - -/* ----------------------------------------------------------------------------- - * DataType_ltype(DataType *ty) - * - * Returns a type object corresponding to the string created by lstr - * ----------------------------------------------------------------------------- */ - -DataType *DataType_ltype(DataType *t) { - - DataType *ty = CopyDataType(t); - if (ty->_status & STAT_REPLACETYPE) { - DataType_typedef_replace(ty); /* Replace the type with its typedef value */ - } - if (ty->_qualifier) { - free(ty->_qualifier); - ty->_qualifier = 0; - } - if (ty->_arraystr) { - free(ty->_arraystr); - ty->_arraystr = 0; - } - ty->_is_reference = 0; - return ty; -} - -/* ----------------------------------------------------------------------------- - * char *DataType_rcaststr(DataType *t, char *name) - * - * Produces a casting string that maps the type returned by lstr() to the real - * datatype printed by str(). - * ----------------------------------------------------------------------------- */ - -char *DataType_rcaststr(DataType *ty, DOHString_or_char *name) { - static char result[8][256]; - static int ri = 0; - DataType *t = 0; - ri = ri % 8; - - strcpy(result[ri],""); - if (ty->_arraystr) { - t = ty; - if (ty->_status & STAT_REPLACETYPE) { - t = CopyDataType(ty); - DataType_typedef_replace(t); - } - - ri = ri % 8; - if (t->_arraystr) { - int ndim; - char *c; - ndim = 0; - c = t->_arraystr; - while (*c) { - if (*c == '[') ndim++; - c++; - } - if (ndim > 1) { - /* a Multidimensional array. Provide a special cast for it */ - char *oldarr = 0; - int oldstatus = ty->_status; - t->_status = t->_status & (~STAT_REPLACETYPE); - t->_is_pointer--; - oldarr = t->_arraystr; - t->_arraystr = 0; - sprintf(result[ri],"(%s", DataType_str(t,0)); - t->_arraystr = oldarr; - t->_is_pointer++; - t->_status = oldstatus; - strcat(result[ri]," (*)"); - c = t->_arraystr; - while (*c) { - if (*c == ']') break; - c++; - } - if (*c) c++; - strcat(result[ri],c); - strcat(result[ri],")"); - } - } - if (ty->_status & STAT_REPLACETYPE) { - DelDataType(t); - } - } else if (ty->_qualifier) { - /* Make a cast to restore const/volatile */ - sprintf(result[ri],"(%s)", DataType_str(ty,0)); - } - - if (name) { - if (ty->_is_reference) { - strcat(result[ri],"*"); - } - strcat(result[ri],Char(name)); - } - return result[ri++]; -} - -/* ----------------------------------------------------------------------------- - * DataType_lcaststr() - * - * Casts a variable from the real type to the local datatype. - * ----------------------------------------------------------------------------- */ - -char *DataType_lcaststr(DataType *ty, DOHString_or_char *name) { - static char result[8][256]; - static int ri = 0; - ri = ri % 8; - - strcpy(result[ri],""); - - if (ty->_arraystr) { - sprintf(result[ri],"(%s)", DataType_lstr(ty,0)); - if (name) - strcat(result[ri], Char(name)); - } else if (ty->_is_reference) { - sprintf(result[ri],"(%s)", DataType_lstr(ty,0)); - if (name) { - strcat(result[ri], "&"); - strcat(result[ri], Char(name)); - } - } else if (ty->_qualifier) { - sprintf(result[ri],"(%s)", DataType_lstr(ty,0)); - if (name) { - strcat(result[ri], Char(name)); - } - } else { - if (name) { - strcat(result[ri], Char(name)); - } - } - return result[ri++]; -} - -/* -------------------------------------------------------------------- - * int DataType_array_dimensions() - * - * Returns the number of dimensions in an array or 0 if not an array. - * -------------------------------------------------------------------- */ - -int DataType_array_dimensions(DataType *t) { - char *c; - int ndim = 0; - - if (!t->_arraystr) return 0; - c = t->_arraystr; - while (*c) { - if (*c == '[') { - ndim++; - } - c++; - } - return ndim; -} - -/* -------------------------------------------------------------------- - * char *DataType_get_dimension(int n) - * - * Returns a string containing the value specified for dimension n. - * -------------------------------------------------------------------- */ - -char *DataType_get_dimension(DataType *t, int n) { - static char dim[256]; - char *c; - char *d = dim; - - if (n >= DataType_array_dimensions(t)) { - *d = 0; - return dim; - } - - /* Attempt to locate the right dimension */ - - c = t->_arraystr; - while ((*c) && (n >= 0)) { - if (*c == '[') n--; - c++; - } - - /* c is now at start of array dimension */ - if (*c) { - while ((*c) && (*c != ']')) { - *(d++) = *(c++); - } - } - *d = 0; - return dim; -} - -/* -------------------------------------------------------------------- - * typedef support. This needs to be scoped. - * -------------------------------------------------------------------- */ -#define MAXSCOPE 16 - -static DOHHash *typedef_hash[MAXSCOPE]; -static int scope = 0; /* Current scope */ - -/* ----------------------------------------------------------------------------- - * void DataType_init_typedef() - * - * Inputs : None - * - * Output : None - * - * Side Effects : Initializes the typedef hash tables - * ----------------------------------------------------------------------------- */ - -void DataType_init_typedef() { - int i; - for (i = 0; i < MAXSCOPE; i++) - typedef_hash[i] = 0; - scope = 0; - typedef_hash[scope] = NewHash(); -} - -/* -------------------------------------------------------------------- - * int DataType_typedef_add() - * - * Adds this datatype to the typedef hash table. mode is an optional - * flag that can be used to only add the symbol as a typedef, but not - * generate any support code for the SWIG typechecker. This is used - * for some of the more obscure datatypes like function pointers, - * arrays, and enums. - * --------------------------------------------------------------------*/ - -int DataType_typedef_add(DataType *t,char *tname, int mode) { - char *name1, *name2; - DataType *nt, *t1; - void typeeq_addtypedef(char *name, char *eqname, DataType *); - - /* Check to see if this typedef already defined - * We only check in the local scope. C++ classes may make typedefs - * that shadow global ones.*/ - - if (Getattr(typedef_hash[scope],tname)) { - return -1; - } - - /* Make a new datatype that we will place in our hash table */ - - nt = CopyDataType(t); - nt->_implicit_ptr = (t->_is_pointer-t->_implicit_ptr); /* Record if mapped type is a pointer*/ - nt->_is_pointer = (t->_is_pointer-t->_implicit_ptr); /* Adjust pointer value to be correct */ - DataType_typedef_resolve(nt,0); /* Resolve any other mappings of this type */ - - /* Add this type to our hash table */ - SetVoid(typedef_hash[scope],tname, (void *) nt); - - /* Now add this type mapping to our type-equivalence table */ - - if (mode == 0) { - if ((t->_type != T_VOID) && (strcmp(t->_name,tname) != 0)) { - t1 = NewDataType(0); - strcpy(t1->_name,tname); - name2 = DataType_manglestr(t1); - name1 = DataType_manglestr(t); - typeeq_addtypedef(name1,name2,t1); - typeeq_addtypedef(name2,name1,t); - DelDataType(t1); - } - } - /* Call into the target language with this typedef */ - /* lang->add_typedef(t,tname); */ - return 0; -} - -/* -------------------------------------------------------------------- - * void DataType_typedef_resolve(int level = 0) - * - * Checks to see if this datatype is in the typedef hash and - * resolves it if necessary. This will check all of the typedef - * hash tables we know about. - * - * level is an optional parameter that determines which scope to use. - * Usually this is only used with a bare :: operator in a datatype. - * - * The const headache : - * - * Normally SWIG will fail if a const variable is used in a typedef - * like this : - * - * typedef const char *String; - * - * This is because future occurrences of "String" will be treated like - * a char *, but without regard to the "constness". To work around - * this problem. The resolve() method checks to see if these original - * data type is const. If so, we'll substitute the name of the original - * datatype instead. Got it? Whew. In a nutshell, this means that - * all future occurrences of "String" will really be "const char *". - * -------------------------------------------------------------------- */ - -void DataType_typedef_resolve(DataType *t, int level) { - - DataType *td; - int s = scope - level; - - while (s >= 0) { - if ((td = (DataType *) GetVoid(typedef_hash[s],t->_name))) { - t->_type = td->_type; - t->_is_pointer += td->_is_pointer; - t->_implicit_ptr += td->_implicit_ptr; - t->_status = t->_status | td->_status; - - /* Check for constness, and replace type name if necessary*/ - - if (td->_qualifier) { - if (strcmp(td->_qualifier,"const") == 0) { - strcpy(t->_name,td->_name); - t->_qualifier = Swig_copy_string(td->_qualifier); - t->_implicit_ptr -= td->_implicit_ptr; - } - } - return; - } - s--; - } - /* Not found, do nothing */ - return; -} - -/* -------------------------------------------------------------------- - * void DataType_typedef_replace() - * - * Checks to see if this datatype is in the typedef hash and - * replaces it with the hash entry. Only applies to current scope. - * -------------------------------------------------------------------- */ - -void DataType_typedef_replace (DataType *t) { - DataType *td; - char temp[512]; - - temp[0] = 0; - - if ((td = (DataType *) GetVoid(typedef_hash[scope],t->_name))) { - t->_type = td->_type; - t->_is_pointer = td->_is_pointer; - t->_implicit_ptr -= td->_implicit_ptr; - strcpy(t->_name, td->_name); - if (td->_arraystr) { - if (t->_arraystr) { - strcat(temp,t->_arraystr); - free(t->_arraystr); - } - strcat(temp,td->_arraystr); - t->_arraystr = Swig_copy_string(temp); - } - } - /* Not found, do nothing */ - return; -} - -/* --------------------------------------------------------------- - * int DataType_is_typedef(char *t) - * - * Checks to see whether t is the name of a datatype we know - * about. Returns 1 if there's a match, 0 otherwise - * --------------------------------------------------------------- */ - -int DataType_is_typedef(char *t) { - int s = scope; - while (s >= 0) { - if (Getattr(typedef_hash[s],t)) return 1; - s--; - } - return 0; -} - -/* --------------------------------------------------------------- - * void DataType_typedef_updatestatus(int newstatus) - * - * Checks to see if this datatype is in the hash table. If - * so, we'll update its status. This is sometimes used with - * typemap handling. Only applies to current scope. - * --------------------------------------------------------------- */ - -void DataType_typedef_updatestatus(DataType *t, int newstatus) { - - DataType *nt; - if ((nt = (DataType *) GetVoid(typedef_hash[scope],t->_name))) { - nt->_status = newstatus; - } -} - -/* ----------------------------------------------------------------------------- - * void DataType_merge_scope(Hash *h) - * - * Copies all of the entries in scope h into the current scope. This is - * primarily done with C++ inheritance. - * - * Inputs : Hash table h. - * - * Output : None - * - * Side Effects : Copies all of the entries in h to current scope. - * ----------------------------------------------------------------------------- */ - -void DataType_merge_scope(void *ho) { - DOHString *key; - DataType *t, *nt; - DOHHash *h = (DOHHash *) ho; - - if (h) { - /* Copy all of the entries in the given hash table to this new one */ - key = Firstkey(h); - while (key) { - /* printf("%s\n", key); */ - t = (DataType *) GetVoid(h,key); - nt = CopyDataType(t); - SetVoid(typedef_hash[scope],key,(void *) nt); - key = Nextkey(h); - } - } -} - -/* ----------------------------------------------------------------------------- - * void DataType_new_scope(Hash *h = 0) - * - * Creates a new scope for handling typedefs. This is used in C++ handling - * to create typedef local to a class definition. - * - * Inputs : h = Optional hash table scope (Used for C++ inheritance). - * - * Output : None - * - * Side Effects : Creates a new hash table and increments the scope counter - * ----------------------------------------------------------------------------- */ - -void DataType_new_scope(void *ho) { - scope++; - typedef_hash[scope] = NewHash(); - if (ho) { - DataType_merge_scope(ho); - } -} - -/* ----------------------------------------------------------------------------- - * Hash *DataType_collapse_scope(char *prefix) - * - * Collapses the current scope into the previous one, but applies a prefix to - * all of the datatypes. This is done in order to properly handle C++ stuff. - * For example : - * - * class Foo { - * ... - * typedef double Real; - * } - * - * will have a type mapping of "double --> Real" within the class itself. - * When we collapse the scope, this mapping will become "double --> Foo::Real" - * - * Inputs : None - * - * Output : None - * - * Side Effects : Returns the hash table corresponding to the current scope - * ----------------------------------------------------------------------------- */ - -void *DataType_collapse_scope(char *prefix) { - DataType *t,*nt; - DOHString *key; - char *temp; - DOHHash *h; - - if (scope > 0) { - if (prefix) { - key = Firstkey(typedef_hash[scope]); - while (key) { - t = (DataType *) GetVoid(typedef_hash[scope],key); - nt = CopyDataType(t); - temp = (char *) malloc(strlen(prefix)+strlen(Char(key)) + 4); - sprintf(temp,"%s::%s",prefix,Char(key)); - SetVoid(typedef_hash[scope-1],temp, (void *)nt); - free(temp); - key = Nextkey(typedef_hash[scope]); - } - } - h = typedef_hash[scope]; - typedef_hash[scope] = 0; - scope--; - return (void *) h; - } - return 0; -} - -/* ------------------------------------------------------------- - * Class equivalency lists - * - * These are used to keep track of which datatypes are equivalent. - * This information can be dumped in tabular form upon completion - * for use in the pointer type checker. - * - * cast is an extension needed to properly handle multiple inheritance - * -------------------------------------------------------------- */ - -typedef struct EqEntry { - char *name; - char *cast; - DataType *type; - struct EqEntry *next; -} EqEntry; - -static DOHHash *typeeq_hash = 0; -static int te_init = 0; - -void typeeq_init() { - void typeeq_standard(); - if (!typeeq_hash) typeeq_hash = NewHash(); - te_init = 1; - typeeq_standard(); -} - - -/* -------------------------------------------------------------- - * typeeq_add(char *name, char *eqname, char *cast) - * - * Adds a new name to the type-equivalence tables. - * Creates a new entry if it doesn't exit. - * - * Cast is an optional name for a pointer casting function. - * -------------------------------------------------------------- */ - -void typeeq_add(char *name, char *eqname, char *cast, DataType *type) { - EqEntry *e1,*e2; - - if (!te_init) typeeq_init(); - - if (strcmp(name,eqname) == 0) return; /* If they're the same, forget it. */ - - /* Search for "name" entry in the hash table */ - - e1 = (EqEntry *) GetVoid(typeeq_hash,name); - - if (!e1) { - /* Create a new entry */ - e1 = (EqEntry *) malloc(sizeof(EqEntry)); - e1->name = Swig_copy_string(name); - e1->next = 0; - e1->cast = 0; - /* Add it to the hash table */ - SetVoid(typeeq_hash,name,(void *) e1); - } - - /* Add new type to the list - * We'll first check to see if it's already been added */ - - e2 = e1->next; - while (e2) { - if (strcmp(e2->name, eqname) == 0) { - if (cast) - e2->cast = Swig_copy_string(cast); - return; - } - e2 = e2->next; - } - - e2 = (EqEntry *) malloc(sizeof(EqEntry)); - e2->name = Swig_copy_string(eqname); - e2->cast = Swig_copy_string(cast); - if (type) - e2->type = CopyDataType(type); - else - e2->type = 0; - e2->next = e1->next; /* Add onto the linked list for name */ - e1->next = e2; - -} - -/* -------------------------------------------------------------- - * typeeq_addtypedef(char *name, char *eqname, DataType *t) - * - * Adds a new typedef declaration to the equivelency list. - * -------------------------------------------------------------- */ - -void typeeq_addtypedef(char *name, char *eqname, DataType *t) { - EqEntry *e1,*e2; - - if (!te_init) typeeq_init(); - - if (!t) { - t = NewDataType(T_USER); - strcpy(t->_name, eqname); - } - - /*printf("addtypedef: %s : %s : %s\n", name, eqname, t->print_type()); */ - - /* First we're going to add the equivalence, no matter what */ - - typeeq_add(name,eqname,0,t); - - /* Now find the hash entry */ - - e1 = (EqEntry *) GetVoid(typeeq_hash,name); - if (!e1) return; - - /* Walk down the list and make other equivalences */ - - e2 = e1->next; - while (e2) { - if (strcmp(e2->name, eqname) != 0) { - typeeq_add(e2->name, eqname,e2->cast,t); - typeeq_add(eqname, e2->name,e2->cast,e2->type); - } - e2 = e2->next; - } -} - -/* ---------------------------------------------------------------- - * void emit_ptr_equivalence() - * - * Dump out the pointer equivalence table to file. - * - * Changed to register datatypes with the type checker in order - * to support proper type-casting (needed for multiple inheritance) - * ---------------------------------------------------------------- */ - -void emit_ptr_equivalence(DOHFile *tablef, DOHFile *initf) { - - EqEntry *e1,*e2; - DOH *k; - void typeeq_standard(); - DOHString *ttable; - - if (!te_init) typeeq_init(); - - ttable = NewString(""); - - Printv(ttable,"\ -/*\n\ - * This table is used by the pointer type-checker\n\ - */\n\ -static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = {\n", - 0); - - k = Firstkey(typeeq_hash); - while (k) { - e1 = (EqEntry *) GetVoid(typeeq_hash,k); - e2 = e1->next; - /* Walk through the equivalency list */ - while (e2) { - if (e2->cast) - Printv(ttable, - " { \"", e1->name, "\",\"", e2->name, "\"," , e2->cast , "},\n", - 0); - else - Printv(ttable, - " { \"", e1->name, "\",\"", e2->name, "\",0},\n", - 0); - - e2 = e2->next; - } - k = Nextkey(typeeq_hash); - } - Printf(ttable,"{0,0,0}};\n"); - Printf(tablef,"%s\n", Char(ttable)); - Printf(initf,"{\n"); - Printf(initf," int i;\n"); - Printf(initf," for (i = 0; _swig_mapping[i].n1; i++)\n"); - Printf(initf," SWIG_RegisterMapping(_swig_mapping[i].n1,_swig_mapping[i].n2,_swig_mapping[i].pcnv);\n"); - Printf(initf,"}\n"); - Delete(ttable); -} - -/* ------------------------------------------------------------------------------ - * typeeq_derived(char *n1, char *n2, char *cast) - * - * Adds a one-way mapping between datatypes. - * ------------------------------------------------------------------------------ */ - -void typeeq_derived(char *n1, char *n2, char *cast) { - DataType *t,*t1; - char *name, *name2; - - t = NewDataType(0); - t1 = NewDataType(0); - if (!te_init) typeeq_init(); - - t->_type = T_USER; - t1->_type = T_USER; - strcpy(t->_name,n1); - strcpy(t1->_name,n2); - name = DataType_manglestr(t); - name2 = DataType_manglestr(t1); - typeeq_add(name,name2, cast, t1); - DelDataType(t); - DelDataType(t1); -} - -/* ------------------------------------------------------------------------------ - * typeeq_mangle(char *n1, char *n2, char *cast=) - * - * Adds a single type equivalence - * ------------------------------------------------------------------------------ */ - -void typeeq_mangle(char *n1, char *n2, char *cast) { - DataType *t,*t1; - char *name, *name2; - - t = NewDataType(0); - t1 = NewDataType(0); - if (!te_init) typeeq_init(); - - strcpy(t->_name,n1); - strcpy(t1->_name,n2); - name = DataType_manglestr(t); - name2 = DataType_manglestr(t1); - typeeq_add(name,name2,cast,0); - DelDataType(t); - DelDataType(t1); -} - -/* ------------------------------------------------------------------------------ - * typeeq_standard(void) - * - * Generate standard type equivalences (well, pointers that can map into - * other pointers naturally). - * - * ------------------------------------------------------------------------------- */ - -void typeeq_standard(void) { - - typeeq_mangle((char*)"int", (char*)"signed int",0); - typeeq_mangle((char*)"int", (char*)"unsigned int",0); - typeeq_mangle((char*)"signed int", (char*)"int",0); - typeeq_mangle((char*)"unsigned int", (char*)"int",0); - typeeq_mangle((char*)"short",(char*)"signed short",0); - typeeq_mangle((char*)"signed short",(char*)"short",0); - typeeq_mangle((char*)"short",(char*)"unsigned short",0); - typeeq_mangle((char*)"unsigned short",(char*)"short",0); - typeeq_mangle((char*)"long",(char*)"signed long",0); - typeeq_mangle((char*)"signed long",(char*)"long",0); - typeeq_mangle((char*)"long",(char*)"unsigned long",0); - typeeq_mangle((char*)"unsigned long",(char*)"long",0); - -} - -/* ---------------------------------------------------------------------- - * char *check_equivalent(DataType *t) - * - * Checks for type names equivalent to t. Returns a string with entries - * suitable for output. - * ---------------------------------------------------------------------- */ - -static char * -check_equivalent(DataType *t) { - EqEntry *e1, *e2; - static DOHString *out = 0; - int npointer = t->_is_pointer; - char *m; - DOHString *k; - - if (!out) out = NewString(""); - Clear(out); - - while (t->_is_pointer >= t->_implicit_ptr) { - m = Swig_copy_string(DataType_manglestr(t)); - - if (!te_init) typeeq_init(); - - k = Firstkey(typeeq_hash); - while (k) { - e1 = (EqEntry *) GetVoid(typeeq_hash,k); - if (strcmp(m,e1->name) == 0) { - e2 = e1->next; - while (e2) { - if (e2->type) { - e2->type->_is_pointer += (npointer - t->_is_pointer); - Printf(out,"{ \"%s\",", DataType_manglestr(e2->type)); - e2->type->_is_pointer -= (npointer - t->_is_pointer); - if (e2->cast) - Printf(out,"%s}, ", e2->cast); - else - Printf(out,"0}, "); - } - e2 = e2->next; - } - } - k = Nextkey(typeeq_hash); - } - free(m); - t->_is_pointer--; - } - t->_is_pointer = npointer; - Printf(out,"{0}"); - return Char(out); -} - -/* ----------------------------------------------------------------------------- - * void DataType_record_base(char *derived, char *base) - * - * Record base class information. This is a hack to make runtime libraries - * work across multiple files. - * ----------------------------------------------------------------------------- */ - -static DOHHash *bases = 0; - -void DataType_record_base(char *derived, char *base) -{ - DOHHash *nh; - if (!bases) bases = NewHash(); - nh = Getattr(bases,derived); - if (!nh) { - nh = NewHash(); - Setattr(bases,derived,nh); - } - if (!Getattr(nh,base)) { - Setattr(nh,base,base); - } -} - -/* ---------------------------------------------------------------------- - * void DataType_remember() - * - * Marks a datatype as being used in the interface file. We use this to - * construct a big table of pointer values at the end. - * ---------------------------------------------------------------------- */ - -static DOHHash *remembered = 0; - -void DataType_remember(DataType *ty) { - DOHHash *h; - DataType *t = CopyDataType(ty); - - if (!remembered) remembered = NewHash(); - SetVoid(remembered, DataType_manglestr(t), t); - - if (!bases) bases = NewHash(); - /* Now, do the base-class hack */ - h = Getattr(bases,t->_name); - if (h) { - DOH *key; - key = Firstkey(h); - while (key) { - DataType *nt = CopyDataType(t); - strcpy(nt->_name,Char(key)); - if (!Getattr(remembered,DataType_manglestr(nt))) - DataType_remember(nt); - DelDataType(nt); - key = Nextkey(h); - } - } -} - -void -emit_type_table(DOHFile *out) { - DOH *key; - DOHString *types, *table; - int i = 0; - - if (!remembered) remembered = NewHash(); - - table = NewString(""); - types = NewString(""); - Printf(table,"static _swig_type_info *_swig_types_initial[] = {\n"); - key = Firstkey(remembered); - Printf(out,"/* ---- TYPES TABLE (BEGIN) ---- */\n"); - while (key) { - Printf(out,"#define SWIGTYPE%s _swig_types[%d] \n", key, i); - Printv(types,"static _swig_type_info _swigt_", Char(key), "[] = {", 0); - Printv(types,"{\"", Char(key), "\",0},", 0); - Printv(types, "{\"", Char(key), "\",0},", 0); - Printv(types, check_equivalent((DataType *)GetVoid(remembered,key)), "};\n", 0); - Printv(table, "_swigt_", Char(key), ", \n", 0); - key = Nextkey(remembered); - i++; - } - - Printf(table, "0\n};\n"); - Printf(out,"static _swig_type_info *_swig_types[%d];\n", i+1); - - Printf(out,"%s\n", types); - Printf(out,"%s\n", table); - Printf(out,"/* ---- TYPES TABLE (END) ---- */\n\n"); - Delete(types); - Delete(table); -} - - - - - - diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c index 23de30839..823ffd7f1 100644 --- a/Source/Swig/stype.c +++ b/Source/Swig/stype.c @@ -1517,7 +1517,6 @@ SwigType_emit_type_table(File *f_forward, File *f_table) { SwigType_inherit_equiv(f_table); - #ifdef DEBUG Printf(stdout,"---r_mangled---\n"); Printf(stdout,"%s\n", r_mangled); diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index 182aa79d2..f59d9f932 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -30,7 +30,8 @@ typedef DOH List; typedef DOH String_or_char; typedef DOH File; -/* --- Legacy DataType interface. This is being replaced --- */ +/* --- Legacy DataType interface. These type codes are provided solely + for backwards compatibility with older modules --- */ #define T_INT 1 #define T_SHORT 2 @@ -338,6 +339,26 @@ extern Wrapper *Swig_cvarget_wrapper(String_or_char *varname, String_or_char *code); +/* --- Legacy Typemap API (somewhat simplified) --- */ + +extern void Swig_typemap_init(); +extern void Swig_typemap_register(char *op, SwigType *type, String_or_char *name, String_or_char *code, ParmList *locals); +extern void Swig_typemap_copy(char *op, SwigType *stype, String_or_char *sname, + SwigType *ttype, String_or_char *tname); +extern void Swig_typemap_clear(char *op, SwigType *type, String_or_char *name); +extern void Swig_typemap_apply(SwigType *tm_type, String_or_char *tmname, SwigType *type, String_or_char *pname); +extern void Swig_typemap_clear_apply(SwigType *type, String_or_char *pname); +extern void Swig_typemap_debug(); +extern Hash *Swig_typemap_search(char *op, SwigType *type, String_or_char *pname); +extern char *Swig_typemap_lookup(char *op, SwigType *type, String_or_char *pname, String_or_char *source, String_or_char *target, Wrapper *f); +extern void Swig_typemap_new_scope(); +extern Hash *Swig_typemap_pop_scope(); + +/* --- Legacy %except directive API --- */ +extern void Swig_except_register(String_or_char *code); +extern char *Swig_except_lookup(); +extern void Swig_except_clear(); + /* --- Attribute access macros --- */ #define Gettype(x) Getattr(x,"type") diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c new file mode 100644 index 000000000..1b73278ff --- /dev/null +++ b/Source/Swig/typemap.c @@ -0,0 +1,478 @@ +/* ----------------------------------------------------------------------------- + * typemap.c + * + * A somewhat generalized implementation of SWIG1.1 typemaps. + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (C) 1999-2000. The University of Chicago + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +static char cvsroot[] = "$Header$"; + +#include "swig.h" + +#define MAX_SCOPE 32 + +static Hash *typemaps[MAX_SCOPE]; +static int tm_scope = 0; + +/* ----------------------------------------------------------------------------- + * Swig_typemap_init() + * + * Initialize the typemap system + * ----------------------------------------------------------------------------- */ + +void Swig_typemap_init() { + int i; + for (i = 0; i < MAX_SCOPE; i++) { + typemaps[i] = 0; + } + typemaps[0] = NewHash(); + tm_scope = 0; +} + +static char *parm_key(String_or_char *pname) { + static char temp[512] = "-"; + strcpy(temp+1,Char(pname)); + return temp; +} + +/* ----------------------------------------------------------------------------- + * Swig_typemap_new_scope() + * + * Create a new typemap scope + * ----------------------------------------------------------------------------- */ + +void Swig_typemap_new_scope() { + tm_scope++; + typemaps[tm_scope] = NewHash(); +} + +/* ----------------------------------------------------------------------------- + * Swig_typemap_pop_scope() + * + * Pop the last typemap scope off + * ----------------------------------------------------------------------------- */ + +Hash * +Swig_typemap_pop_scope() { + if (tm_scope > 0) { + return Swig_temp_result(typemaps[tm_scope--]); + } + return 0; +} + +/* ----------------------------------------------------------------------------- + * Swig_typemap_register() + * + * Add a new typemap + * ----------------------------------------------------------------------------- */ + +void +Swig_typemap_register(char *op, SwigType *type, String_or_char *pname, String_or_char *code, ParmList *locals) { + char *key; + Hash *tm; + Hash *tm1; + Hash *tm2; + + if ((pname) && (Cmp(pname,"SWIG_DEFAULT_TYPE") == 0)) { + type = SwigType_default(type); + Swig_temp_result(type); + } + + /* See if this type has been seen before */ + tm = Getattr(typemaps[tm_scope],type); + if (!tm) { + tm = NewHash(); + Setattr(typemaps[tm_scope],Char(type),tm); + Delete(tm); + } + if ((pname) && Len(pname)) { + /* See if parameter has been seen before */ + key = parm_key(pname); + tm1 = Getattr(tm,key); + if (!tm1) { + tm1 = NewHash(); + Setattr(tm,key,tm1); + Delete(tm1); + } + tm = tm1; + } + tm2 = NewHash(); + Setattr(tm2,"code",NewString(code)); + Setattr(tm2,"locals", CopyParmList(locals)); + Setattr(tm,op,tm2); + Delete(tm2); +} + +/* ----------------------------------------------------------------------------- + * Swig_typemap_get() + * + * Retrieve typemap information from current scope. + * ----------------------------------------------------------------------------- */ + +static Hash * +Swig_typemap_get(SwigType *type, String_or_char *name, int scope) { + Hash *tm, *tm1; + /* See if this type has been seen before */ + if ((scope < 0) || (scope > tm_scope)) return 0; + tm = Getattr(typemaps[scope],type); + if (!tm) { + return 0; + } + if ((name) && Len(name)) { + tm1 = Getattr(tm, parm_key(name)); + return tm1; + } + return tm; +} + +/* ----------------------------------------------------------------------------- + * Swig_typemap_copy() + * + * Copy a typemap + * ----------------------------------------------------------------------------- */ + +void +Swig_typemap_copy(char *op, SwigType *stype, String_or_char *sname, + SwigType *ttype, String_or_char *tname) { + + Hash *tm=0, *tm1; + int ts = tm_scope; + while (ts >= 0) { + tm = Swig_typemap_get(stype,sname,ts); + if (tm) break; + tm = Swig_typemap_get(stype,0,ts); + if (tm) break; + ts--; + } + if (!tm) return; + tm1 = Getattr(tm,op); + if (!tm1) return; + Swig_typemap_register(op,ttype,tname, Getattr(tm1,"code"), Getattr(tm1,"locals")); +} + +/* ----------------------------------------------------------------------------- + * Swig_typemap_clear() + * + * Delete a typemap + * ----------------------------------------------------------------------------- */ + +void +Swig_typemap_clear(char *op, SwigType *type, String_or_char *name) { + Hash *tm; + + tm = Swig_typemap_get(type,name,tm_scope); + if (tm) + Delattr(tm,op); +} + +/* ----------------------------------------------------------------------------- + * Swig_typemap_apply() + * + * %apply directive. This function is nothing more than a glorified typemap + * copy. Note: this is *very* different than SWIG1.1 although the end result + * is very "similar." + * ----------------------------------------------------------------------------- */ + +static void merge_attributes(Hash *target, Hash *source) { + String *key; + for (key = Firstkey(source); key; key = Nextkey(source)) { + if (Getattr(target,key)) continue; + Setattr(target,key,Getattr(source,key)); + } +} + +void +Swig_typemap_apply(SwigType *tm_type, String_or_char *tmname, SwigType *type, String_or_char *pname) { + Hash *tm, *tm1, *am; + int ts = tm_scope; + char *key; + + tm = Swig_typemap_get(type,pname,tm_scope); + if (!tm) { + tm = Getattr(typemaps[tm_scope],type); + if (!tm) { + tm = NewHash(); + Setattr(typemaps[tm_scope], Char(type), tm); + Delete(tm); + } + if ((pname) && Len(pname)) { + key = parm_key(pname); + tm1 = NewHash(); + Setattr(tm,key,tm1); + Delete(tm1); + tm = tm1; + } + } + /* tm contains the typemap table into which we are going to be copying */ + while (ts >= 0) { + am = Swig_typemap_get(tm_type, tmname,ts); + if (am) { + merge_attributes(tm,am); + } + ts--; + } +} + +/* ----------------------------------------------------------------------------- + * Swig_typemap_clear_apply() + * + * %clear directive. Clears all typemaps for a type. + * ----------------------------------------------------------------------------- */ + +void +Swig_typemap_clear_apply(SwigType *type, String_or_char *name) { + Hash *tm; + + tm = Getattr(typemaps[tm_scope],type); + if (!tm) return; + if ((name) && (Len(name))) { + Delattr(tm,parm_key(name)); + } else { + Delattr(typemaps[tm_scope],type); + } +} + + +/* Internal function to strip array dimensions. */ +static SwigType *strip_arrays(SwigType *type) { + SwigType *t; + int ndim; + int i; + t = Copy(type); + ndim = SwigType_array_ndim(t); + for (i = 0; i < ndim; i++) { + SwigType_array_setdim(t,i,"ANY"); + } + return t; +} + +/* ----------------------------------------------------------------------------- + * Swig_typemap_search_op() + * + * Search for a typemap match. + * ----------------------------------------------------------------------------- */ + +Hash * +Swig_typemap_search(char *op, SwigType *type, String_or_char *name) { + Hash *result = 0, *tm, *tm1, *tma; + SwigType *noarrays = 0; + SwigType *primitive = 0; + int ts; + int isarray; + char *cname = 0; + + if ((name) && Len(name)) cname = parm_key(name); + isarray = SwigType_isarray(type); + ts = tm_scope; + while (ts >= 0) { + /* Try to get an exact type-match */ + tm = Getattr(typemaps[ts],type); + if (tm && cname) { + tm1 = Getattr(tm,cname); + if (tm1) { + result = Getattr(tm1,op); /* See if there is a type-name match */ + if (result) goto ret_result; + } + } + if (tm) { + result = Getattr(tm,op); /* See if there is simply a type match */ + if (result) goto ret_result; + } + + if (isarray) { + /* If working with arrays, strip away all of the dimensions and replace with ANY. + See if that generates a match */ + if (!noarrays) noarrays = strip_arrays(type); + tma = Getattr(typemaps[ts],noarrays); + if (tma && cname) { + tm1 = Getattr(tma,cname); + if (tm1) { + result = Getattr(tm1,op); /* type-name match */ + if (result) goto ret_result; + } + } + if (tma) { + result = Getattr(tma,op); /* type match */ + if (result) goto ret_result; + } + } + /* Hmmm. Well, no match seems to be found at all. See if there is some kind of default + mapping */ + + if (!primitive) { + primitive = SwigType_default(type); + } + tm = Getattr(typemaps[ts],primitive); + if (tm) { + tm1 = Getattr(tm,"-SWIG_DEFAULT_TYPE"); + if (tm1) { + result = Getattr(tm1,op); + if (result) goto ret_result; + } + } + ts--; + } + + ret_result: + if (noarrays) Delete(noarrays); + if (primitive) Delete(primitive); + return result; +} + + +/* ------------------------------------------------------------------------ + * static typemap_locals() + * + * Takes a string, a parameter list and a wrapper function argument and + * creates the local variables. + * ------------------------------------------------------------------------ */ + +static void typemap_locals(SwigType *t, String_or_char *pname, DOHString *s, ParmList *l, Wrapper *f) { + Parm *p; + char *new_name; + + p = l; + while (p) { + SwigType *pt = Gettype(p); + String *pn = Getname(p); + if (pn) { + if (Len(pn) > 0) { + DOHString *str; + SwigType *tt; + + str = NewString(""); + /* If the user gave us $type as the name of the local variable, we'll use + the passed datatype instead */ + + if (Cmp(SwigType_base(pt),"$type")==0 || Cmp(SwigType_base(pt),"$basetype")==0) { + tt = t; + } else { + tt = pt; + } + Printf(str,"%s",pn); + /* Substitute parameter names */ + Replace(str,"$arg",pname, DOH_REPLACE_ANY); + if (Cmp(SwigType_base(pt),"$basetype")==0) { + /* use $basetype */ + new_name = Wrapper_new_localv(f,str,SwigType_base(tt),str,0); + } else { + new_name = Wrapper_new_localv(f,str, SwigType_str(tt,str), 0); + } + /* Substitute */ + Replace(s,pn,new_name,DOH_REPLACE_ID); + } + } + p = Getnext(l); + } +} + +/* ----------------------------------------------------------------------------- + * Swig_typemap_lookup() + * + * Perform a typemap lookup (ala SWIG1.1) + * ----------------------------------------------------------------------------- */ + +char *Swig_typemap_lookup(char *op, SwigType *type, String_or_char *pname, String_or_char *source, + String_or_char *target, Wrapper *f) +{ + Hash *tm; + String *s; + ParmList *locals; + + tm = Swig_typemap_search(op,type,pname); + if (!tm) return 0; + + s = Getattr(tm,"code"); + if (!s) return 0; + s = Copy(s); /* Make a local copy of the typemap code */ + + locals = Getattr(tm,"locals"); + + /* Replace array dimensions */ + if (locals && f) { + typemap_locals(type,pname,s,locals,f); + } + + /* If the original datatype was an array. We're going to go through and substitute + it's array dimensions */ + + if (SwigType_isarray(type)) { + char temp[10]; + int ndim = SwigType_array_ndim(type); + int i; + for (i = 0; i < ndim; i++) { + DOHString *dim = SwigType_array_getdim(type,i); + sprintf(temp,"$dim%d",i); + Replace(f->locals,temp,dim, DOH_REPLACE_ANY); + Replace(s,temp,dim,DOH_REPLACE_ANY); + } + } + + /* Now perform character replacements */ + Replace(s,"$source",source,DOH_REPLACE_ANY); + Replace(s,"$target",target,DOH_REPLACE_ANY); + Replace(s,"$type",SwigType_str(type,0),DOH_REPLACE_ANY); + Replace(s,"$parmname",pname, DOH_REPLACE_ANY); + + /* Print base type (without any pointers) */ + Replace(s,"$basetype",SwigType_base(type), DOH_REPLACE_ANY); + Replace(s,"$basemangle",SwigType_manglestr(SwigType_base(type)), DOH_REPLACE_ANY); + Replace(s,"$mangle",SwigType_manglestr(type), DOH_REPLACE_ANY); + Swig_temp_result(s); + return Char(s); +} + +/* ----------------------------------------------------------------------------- + * Swig_typemap_debug() + * ----------------------------------------------------------------------------- */ + +void Swig_typemap_debug() { + int ts; + Printf(stdout,"---[ typemaps ]--------------------------------------------------------------\n"); + + ts = tm_scope; + while (ts >= 0) { + Printf(stdout,"::: scope %d\n\n",ts); + Printf(stdout,"%s\n", typemaps[ts]); + ts--; + } + Printf(stdout,"-----------------------------------------------------------------------------\n"); +} + + +/* ----------------------------------------------------------------------------- + * %except directive support. + * + * These functions technically don't really have anything to do with typemaps + * except that they have the same scoping rules. Therefore, it's easy enough to + * just use the hash table structure of the typemap code. + * ----------------------------------------------------------------------------- */ + +void Swig_except_register(String_or_char *code) { + String *s = NewString(code); + Setattr(typemaps[tm_scope],"*except*",s); + Delete(s); +} + +char *Swig_except_lookup() { + String *s; + int ts = tm_scope; + while (ts >= 0) { + s = Getattr(typemaps[tm_scope],"*except*"); + if (s) { + s = Copy(s); + Swig_temp_result(s); + return Char(s); + } + ts--; + } + return 0; +} + +void Swig_except_clear() { + Delattr(typemaps[tm_scope],"*except*"); +}