diff options
Diffstat (limited to 'SWIG/Source')
30 files changed, 1820 insertions, 1236 deletions
diff --git a/SWIG/Source/DOH/Doh/Makefile b/SWIG/Source/DOH/Doh/Makefile deleted file mode 100644 index 0908946e0..000000000 --- a/SWIG/Source/DOH/Doh/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# Generated automatically from Makefile.in by configure. -####################################################################### -# $Header$ -# DOH -####################################################################### - -#.KEEP_STATE: - -# Set your C++ compiler here. g++ works on most machines, -# but you might have to change it depending on your installation. -# -CC = cc -prefix = /r0/beazley/Projects - -# Comment out the following line if you're on an SGI or don't have ranlib! -RANLIB = ranlib -AR = ar - -######################################################################## -# Normally, you shouldn't have to change anything below this point # -######################################################################## - -LIBOBJS = callable.o void.o fio.o memory.o base.o file.o list.o hash.o string.o - -LIBSRCS = callable.c void.c fio.c memory.c base.c file.c list.c hash.c string.c - -LIBHEADERS = ../Include/doh.h -LIB = ../libdoh.a -INCLUDE = -I../Include -CFLAGS = -DDOH_STRING_UPDATE_LINES -SHELL = /bin/sh - -# -# Rules for creation of a .o file from .cxx -.SUFFIXES: .c -.c.o: - $(CC) $(INCLUDE) $(CFLAGS) -c -o $*.o $< - -all: $(LIB) - -$(LIB): $(LIBOBJS) - @echo "Building library" - $(AR) cr $(LIB) $(LIBOBJS) - $(RANLIB) $(LIB) - -clean:: - rm -f *.o ../libdoh.a -nuke:: - rm -f Makefile *~ #* core a.out - diff --git a/SWIG/Source/DOH/configure.in b/SWIG/Source/DOH/configure.in index 0c114907c..6fd2e4642 100644 --- a/SWIG/Source/DOH/configure.in +++ b/SWIG/Source/DOH/configure.in @@ -41,4 +41,4 @@ dnl Checks for header files. AC_HEADER_STDC dnl Checks for library functions. -AC_OUTPUT(Makefile Doh/Makefile Test/Makefile) +AC_OUTPUT(Makefile Doh/Makefile) diff --git a/SWIG/Source/Include/.cvsignore b/SWIG/Source/Include/.cvsignore new file mode 100644 index 000000000..c451252ce --- /dev/null +++ b/SWIG/Source/Include/.cvsignore @@ -0,0 +1 @@ +swigconfig.h diff --git a/SWIG/Source/Include/swigconfig.h.in b/SWIG/Source/Include/swigconfig.h.in index 7a02d27fb..6c672b56a 100644 --- a/SWIG/Source/Include/swigconfig.h.in +++ b/SWIG/Source/Include/swigconfig.h.in @@ -1,6 +1,18 @@ -/* This file contains SWIG specific configuration data for those modules +/* This -*-c-*- file contains SWIG specific configuration data for those modules that care */ -#define SWIG_LIB "@prefix@/lib/swig1.3" +/* Directory where to find the machine-independent SWIG files */ + +#define SWIG_LIB "@-swig_lib-@" + +/* Default language */ + #define SWIG_LANG TCL8 +/* Values returned by swig when invoked with the -ldflags option */ + +#define SWIG_PERL_RUNTIME "-L@-exec_prefix-@/lib -lswigpl@-release_suffix-@" +#define SWIG_PYTHON_RUNTIME "-L@-exec_prefix-@/lib -lswigpy@-release_suffix-@" +#define SWIG_TCL_RUNTIME "-L@-exec_prefix-@/lib -lswigtcl@-release_suffix-@" +#define SWIG_RUBY_RUNTIME "-L@-exec_prefix-@/lib -lswigrb@-release_suffix-@" +#define SWIG_GUILE_RUNTIME "-L@-exec_prefix-@/lib -lswigguile@-release_suffix-@" diff --git a/SWIG/Source/Include/swigver.h b/SWIG/Source/Include/swigver.h index 9da439bbd..7bdb7e412 100644 --- a/SWIG/Source/Include/swigver.h +++ b/SWIG/Source/Include/swigver.h @@ -2,9 +2,9 @@ /* SWIG version information */ #ifndef SWIG_VERSION -#define SWIG_VERSION "1.3u-20000712-1502" +#define SWIG_VERSION "1.3u-20010628-1103" #endif #ifndef SWIG_SPIN -#define SWIG_SPIN "(Alpha 3)" +#define SWIG_SPIN "(Alpha 5)" #endif diff --git a/SWIG/Source/Modules/.cvsignore b/SWIG/Source/Modules/.cvsignore new file mode 100644 index 000000000..f3c7a7c5d --- /dev/null +++ b/SWIG/Source/Modules/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/SWIG/Source/Modules1.1/Makefile.in b/SWIG/Source/Modules1.1/Makefile.in index b9f686a2f..88859a0b7 100644 --- a/SWIG/Source/Modules1.1/Makefile.in +++ b/SWIG/Source/Modules1.1/Makefile.in @@ -13,8 +13,8 @@ AR = @AR@ RANLIB = @RANLIB@ TARGET = libmodules11.a -OBJS = swigmain.o tcl8.o python.o perl5.o guile.o ruby.o mzscheme.o #java.o -SRCS = swigmain.cxx tcl8.cxx python.cxx perl5.cxx guile.cxx ruby.cxx mzscheme.cxx #java.cxx +OBJS = swigmain.o tcl8.o python.o perl5.o guile.o ruby.o mzscheme.o java.o +SRCS = swigmain.cxx tcl8.cxx python.cxx perl5.cxx guile.cxx ruby.cxx mzscheme.cxx java.cxx INCLUDE = -I$(srcdir)/../Include \ -I$(srcdir)/../SWIG1.1 \ diff --git a/SWIG/Source/Modules1.1/guile.cxx b/SWIG/Source/Modules1.1/guile.cxx index 837693176..fa4b5136f 100644 --- a/SWIG/Source/Modules1.1/guile.cxx +++ b/SWIG/Source/Modules1.1/guile.cxx @@ -25,21 +25,28 @@ static char cvsroot[] = "$Header$"; #include "mod11.h" #include "guile.h" +#include "swigconfig.h" static char *guile_usage = (char*)"\ Guile Options (available with -guile)\n\ - -module name - Set base name of module\n\ + -ldflags - Print runtime libraries to link with\n\ + -module name - Set name of module [default \"swig\"]\n\ -prefix name - Use NAME as prefix [default \"gswig_\"]\n\ -package name - Set the path of the module [default NULL]\n\ - -Linkage lstyle - Use linkage protocol LSTYLE [default `ltdlmod']\n\ - -procdoc file - Output procedure documentation to file\n\ + -linkage lstyle - Use linkage protocol LSTYLE [default `module']\n\ + -procdoc file - Output procedure documentation to FILE\n\ \n\ + -procdocformat format - Output procedure documentation in FORMAT;\n\ + one of `guile-1.4', `plain', `texinfo'\n\ The module option does not create a guile module with a separate name\n\ space. It specifies the name of the initialization function and is\n\ called a module here so that it is compadible with the rest of SWIG.\n\ \n\ - When unspecified, the default LSTYLE is `ltdlmod' for libtool ltdl\n\ - modules. Other LSTYLE values are: `hobbit' for hobbit modules.\n\ + When unspecified, the default LSTYLE is `simple'. For native Guile\n\ + module linking (for Guile versions >=1.5.0), use `module'. Other\n\ + LSTYLE values are: `passive' for passive linking (no module-handling\n\ + code), `ltdlmod' for Guile's old dynamic module convention\n\ + (versions <= 1.4), or `hobbit' for hobbit modules.\n\ \n"; // --------------------------------------------------------------------- @@ -59,8 +66,11 @@ GUILE::GUILE () package = NULL; linkage = GUILE_LSTYLE_SIMPLE; procdoc = NULL; + docformat = GUILE_1_4; emit_setters = 0; struct_member = 0; + before_return = NULL; + exported_symbols = NewString(""); } // --------------------------------------------------------------------- @@ -115,15 +125,24 @@ GUILE::parse_args (int argc, char *argv[]) Swig_arg_error(); } } - /* Bogus upcase requirement due to top-level parsing not respecting - language specification. Top-level should stop when it sees "-guile" - or other languages. */ - else if (strcmp (argv[i], "-Linkage") == 0) { + else if (strcmp (argv[i], "-ldflags") == 0) { + printf("%s\n", SWIG_GUILE_RUNTIME); + SWIG_exit (EXIT_SUCCESS); + } + /* The upcase variant is a historic artefact. */ + else if (strcmp (argv[i], "-Linkage") == 0 + || strcmp (argv[i], "-linkage") == 0) { if (argv[i + 1]) { if (0 == strcmp (argv[i + 1], "ltdlmod")) - linkage = GUILE_LSTYLE_LTDLMOD; + linkage = GUILE_LSTYLE_LTDLMOD_1_4; else if (0 == strcmp (argv[i + 1], "hobbit")) linkage = GUILE_LSTYLE_HOBBIT; + else if (0 == strcmp (argv[i + 1], "simple")) + linkage = GUILE_LSTYLE_SIMPLE; + else if (0 == strcmp (argv[i + 1], "passive")) + linkage = GUILE_LSTYLE_PASSIVE; + else if (0 == strcmp (argv[i + 1], "module")) + linkage = GUILE_LSTYLE_MODULE; else Swig_arg_error (); Swig_mark_arg (i); @@ -143,6 +162,18 @@ GUILE::parse_args (int argc, char *argv[]) Swig_arg_error(); } } + else if (strcmp (argv[i], "-procdocformat") == 0) { + if (strcmp(argv[i+1], "guile-1.4") == 0) + docformat = GUILE_1_4; + else if (strcmp(argv[i+1], "plain") == 0) + docformat = PLAIN; + else if (strcmp(argv[i+1], "texinfo") == 0) + docformat = TEXINFO; + else Swig_arg_error(); + Swig_mark_arg(i); + Swig_mark_arg(i+1); + i++; + } else if (strcmp (argv[i], "-emit-setters") == 0) { emit_setters = 1; Swig_mark_arg (i); @@ -174,8 +205,6 @@ GUILE::parse_args (int argc, char *argv[]) void GUILE::parse () { - printf ("Generating wrappers for Guile\n"); - // Print out GUILE specific headers headers(); @@ -197,10 +226,7 @@ GUILE::parse () void GUILE::set_module (char *mod_name) { - if (module) { - printf ("module already set (%s), returning\n", module); - return; - } + if (module) return; module = new char [strlen (mod_name) + 1]; strcpy (module, mod_name); @@ -252,6 +278,9 @@ GUILE::headers (void) void GUILE::initialize (void) { + if (CPlusPlus) { + Printf(f_runtime, "extern \"C\" {\n\n"); + } switch (linkage) { case GUILE_LSTYLE_SIMPLE: /* Simple linkage; we have to export the SWIG_init function. The user can @@ -266,6 +295,9 @@ GUILE::initialize (void) break; } Printf (f_init, "\tSWIG_Guile_Init();\n"); + if (CPlusPlus) { + Printf(f_runtime, "\n}\n"); + } } void @@ -273,6 +305,10 @@ GUILE::emit_linkage (char *module_name) { DOHString *module_func = NewString(""); + if (CPlusPlus) { + Printf(f_init, "extern \"C\" {\n\n"); + } + Printv(module_func,module_name,0); Replace(module_func,"-", "_", DOH_REPLACE_ANY); @@ -280,7 +316,18 @@ GUILE::emit_linkage (char *module_name) case GUILE_LSTYLE_SIMPLE: Printf (f_init, "\n/* Linkage: simple */\n"); break; - case GUILE_LSTYLE_LTDLMOD: + case GUILE_LSTYLE_PASSIVE: + Printf (f_init, "\n/* Linkage: passive */\n"); + Replace(module_func,"/", "_", DOH_REPLACE_ANY); + Insert(module_func,0, "scm_init_"); + Append(module_func,"_module"); + + Printf (f_init, "SCM\n%s (void)\n{\n", module_func); + Printf (f_init, " SWIG_init();\n"); + Printf (f_init, " return SCM_UNSPECIFIED;\n"); + Printf (f_init, "}\n"); + break; + case GUILE_LSTYLE_LTDLMOD_1_4: Printf (f_init, "\n/* Linkage: ltdlmod */\n"); Replace(module_func,"/", "_", DOH_REPLACE_ANY); Insert(module_func,0, "scm_init_"); @@ -296,6 +343,29 @@ GUILE::emit_linkage (char *module_name) } Printf (f_init, "}\n"); break; + case GUILE_LSTYLE_MODULE: + Printf (f_init, "\n/* Linkage: module */\n"); + Replace(module_func,"/", "_", DOH_REPLACE_ANY); + Insert(module_func,0, "scm_init_"); + Append(module_func,"_module"); + + Printf (f_init, "static void SWIG_init_helper(void *data)\n"); + Printf (f_init, "{\n SWIG_init();\n"); + if (Len(exported_symbols) > 0) + Printf (f_init, " scm_c_export(%sNULL);", + exported_symbols); + Printf (f_init, "\n}\n\n"); + + Printf (f_init, "SCM\n%s (void)\n{\n", module_func); + { + DOHString *mod = NewString(module_name); + Replace(mod,"/", " ", DOH_REPLACE_ANY); + Printf(f_init, " SCM module = scm_c_define_module(\"%s\",\n", mod); + Printf(f_init, " SWIG_init_helper, NULL);\n"); + Printf(f_init, " return SCM_UNSPECIFIED;\n"); + } + Printf (f_init, "}\n"); + break; case GUILE_LSTYLE_HOBBIT: Printf (f_init, "\n/* Linkage: hobbit */\n"); Replace(module_func,"/", "_slash_", DOH_REPLACE_ANY); @@ -315,6 +385,9 @@ GUILE::emit_linkage (char *module_name) abort(); // for now } Delete(module_func); + if (CPlusPlus) { + Printf(f_init, "\n}\n"); + } } // --------------------------------------------------------------------- @@ -328,7 +401,7 @@ GUILE::close (void) { SwigType_emit_type_table (f_runtime, f_wrappers); - Printf (f_init, "SWIG_Guile_RegisterTypes(swig_types);\n"); + Printf (f_init, "SWIG_Guile_RegisterTypes(swig_types, swig_types_initial);\n"); Printf (f_init, "}\n\n"); char module_name[256]; @@ -341,42 +414,13 @@ GUILE::close (void) strcpy(module_name,module); } emit_linkage (module_name); - + if (procdoc) { Delete(procdoc); procdoc = NULL; } } -// ---------------------------------------------------------------------- -// get_pointer() -// -// Emits code to get a pointer from a parameter and do type checking. -// parm is the parameter number. This function is only used -// in create_function(). -// ---------------------------------------------------------------------- - -static void -get_pointer (char *iname, int parm, SwigType *t, - Wrapper *f, DOHString_or_char *proc_name, - int num_scheme_parm) -{ - SwigType_remember(t); - /* Pointers are smobs */ - Printf(f->code, " if (SWIG_Guile_GetPtr(s_%d,(void **) &arg%d", parm, parm); - if (SwigType_type(t) == T_VOID) - Printf(f->code, ", NULL)) {\n"); - else - Printv(f->code, ", SWIGTYPE", SwigType_manglestr(t), ")) {\n", 0); - /* Raise exception */ - Printv(f->code, - tab8, - "scm_wrong_type_arg(\"",proc_name, "\", ", - 0); - Printf(f->code,"%d, s_%d);\n", num_scheme_parm, parm); - Printv(f->code, tab4, "}\n", 0); -} - /* Return true iff T is a pointer type */ static int @@ -417,11 +461,42 @@ guile_do_typemap(DOHFile *file, const char *op, if ((tm = guile_typemap_lookup(op, type, arg, source, target, f))) { String *s = NewString(tm); + String *descriptor = NewString(""); + String *basedescriptor = NewString(""); + String *stardescriptor = NewString(""); char argnum_s[10]; + SwigType *startype = NULL; + + if (SwigType_ispointer(type)) { + startype = Copy(type); + SwigType_del_pointer(startype); + Printf(stardescriptor, "SWIGTYPE%s", + SwigType_manglestr(startype)); + } + else Printf(stardescriptor, "SWIGTYPE_BAD"); + Printf(descriptor, "SWIGTYPE%s", + SwigType_manglestr(type)); + Printf(basedescriptor, "SWIGTYPE%s", + SwigType_manglestr(SwigType_base(type))); sprintf(argnum_s, "%d", argnum); Replace(s,"$argnum", argnum_s, DOH_REPLACE_ANY); Replace(s,"$arg", arg, DOH_REPLACE_ANY); Replace(s,"$name", name, DOH_REPLACE_ANY); + if (Replace(s, "$descriptor", + descriptor, DOH_REPLACE_ANY)) + SwigType_remember(type); + if (Replace(s, "$basedescriptor", + basedescriptor, DOH_REPLACE_ANY)) + SwigType_remember(SwigType_base(type)); + if (Replace(s, "$*descriptor", stardescriptor, + DOH_REPLACE_ANY)) { + if (!startype) { + Printf (stderr, "%s : Line %d. $*descriptor is meaningless for non-pointer types.\n", + input_file, line_number); + error_count++; + } + else SwigType_remember(startype); + } if (nonewline_p) Printv(file, s, 0); else Printv(file, s, "\n", 0); @@ -460,6 +535,35 @@ throw_unhandled_guile_type_error (SwigType *d) error_count++; } + +/* Write out procedure documentation */ + +void +GUILE::write_doc(const String *proc_name, + const String *signature, + const String *doc) +{ + switch (docformat) { + case GUILE_1_4: + Printv(procdoc, "\f\n", 0); + Printv(procdoc, "(", signature, ")\n", 0); + Printv(procdoc, doc, "\n", 0); + break; + case PLAIN: + Printv(procdoc, "\f", proc_name, "\n\n", 0); + Printv(procdoc, "(", signature, ")\n", 0); + Printv(procdoc, doc, "\n\n", 0); + break; + case TEXINFO: + Printv(procdoc, "\f", proc_name, "\n", 0); + Printv(procdoc, "@deffn primitive ", signature, "\n", 0); + Printv(procdoc, doc, "\n", 0); + Printv(procdoc, "@end deffn\n\n", 0); + break; + } +} + + // ---------------------------------------------------------------------- // GUILE::create_function(char *name, char *iname, SwigType *d, // ParmList *l) @@ -472,7 +576,7 @@ GUILE::create_function (char *name, char *iname, SwigType *d, ParmList *l) { Parm *p; DOHString *proc_name = 0; - char source[256], target[256]; + char source[256], target[256], wname[256]; Wrapper *f = NewWrapper();; String *cleanup = NewString(""); String *outarg = NewString(""); @@ -485,8 +589,7 @@ GUILE::create_function (char *name, char *iname, SwigType *d, ParmList *l) int numopt = 0; // Make a wrapper name for this - char * wname = new char [strlen (prefix) + strlen (iname) + 2]; - sprintf (wname, "%s%s", prefix, iname); + strcpy(wname, Char(Swig_name_wrapper(name))); // Build the name for scheme. proc_name = NewString(iname); @@ -498,6 +601,7 @@ GUILE::create_function (char *name, char *iname, SwigType *d, ParmList *l) /* Declare return variable */ Wrapper_add_local (f,"gswig_result", "SCM gswig_result"); + Wrapper_add_local (f,"gswig_list_p", "int gswig_list_p = 0"); if (procdoc) guile_do_doc_typemap(returns, "outdoc", d, NULL, @@ -506,7 +610,7 @@ GUILE::create_function (char *name, char *iname, SwigType *d, ParmList *l) /* Open prototype and signature */ Printv(f->def, "static SCM\n", wname," (", 0); - Printv(signature, "(", proc_name, 0); + Printv(signature, proc_name, 0); /* Now write code to extract the parameters */ @@ -536,9 +640,6 @@ GUILE::create_function (char *name, char *iname, SwigType *d, ParmList *l) source, target, numargs, proc_name, f, 0)) { /* nothing to do */ } - else if (is_a_pointer(pt)) { - get_pointer (iname, i, pt, f, proc_name, numargs); - } else { throw_unhandled_guile_type_error (pt); } @@ -583,9 +684,8 @@ GUILE::create_function (char *name, char *iname, SwigType *d, ParmList *l) source, target, numargs, proc_name, f, 0); } - /* Close prototype and signature */ + /* Close prototype */ - Printv(signature, ")\n", 0); Printf(f->def, ")\n{\n"); /* Define the scheme name in C. This define is used by several Guile @@ -604,15 +704,6 @@ GUILE::create_function (char *name, char *iname, SwigType *d, ParmList *l) 0, proc_name, f, 0)) { /* nothing */ } - else if (is_a_pointer(d)) { - SwigType_remember(d); - Printv(f->code, tab4, - "gswig_result = SWIG_Guile_MakePtr (", - "result, ", - "SWIGTYPE", SwigType_manglestr(d), - ");\n", - 0); - } else { throw_unhandled_guile_type_error (d); } @@ -637,6 +728,8 @@ GUILE::create_function (char *name, char *iname, SwigType *d, ParmList *l) // Wrap things up (in a manner of speaking) + if (before_return) + Printv(f->code, before_return, "\n", 0); Printv(f->code, "return gswig_result;\n", 0); // Undefine the scheme name @@ -662,7 +755,7 @@ GUILE::create_function (char *name, char *iname, SwigType *d, ParmList *l) Printv(f_wrappers, ");\n", 0); Printv(f_wrappers, "}\n", 0); /* Register it */ - Printf (f_init, "gh_new_procedure(\"%s\", %s_rest, 0, 0, 1);\n", + Printf (f_init, "gh_new_procedure(\"%s\", (SCM (*) ()) %s_rest, 0, 0, 1);\n", proc_name, wname, numargs-numopt, numopt); } else if (emit_setters && struct_member && strlen(Char(proc_name))>3) { @@ -675,7 +768,7 @@ GUILE::create_function (char *name, char *iname, SwigType *d, ParmList *l) struct_member = 2; /* have a setter */ } else Printf(f_init, "SCM getter = "); - Printf (f_init, "gh_new_procedure(\"%s\", %s, %d, %d, 0);\n", + Printf (f_init, "gh_new_procedure(\"%s\", (SCM (*) ()) %s, %d, %d, 0);\n", proc_name, wname, numargs-numopt, numopt); if (!is_setter) { /* Strip off "-get" */ @@ -693,22 +786,24 @@ GUILE::create_function (char *name, char *iname, SwigType *d, ParmList *l) Printf (f_init, "gh_define(\"%s\", getter);\n", pws_name); } + Printf (exported_symbols, "\"%s\", ", pws_name); free(pws_name); } } else { /* Register the function */ - Printf (f_init, "gh_new_procedure(\"%s\", %s, %d, %d, 0);\n", + Printf (f_init, "gh_new_procedure(\"%s\", (SCM (*) ()) %s, %d, %d, 0);\n", proc_name, wname, numargs-numopt, numopt); } + Printf (exported_symbols, "\"%s\", ", proc_name); if (procdoc) { - /* Write out procedure documentation */ - Printv(signature, "Returns ", 0); - if (Len(returns)==0) Printv(signature, "unspecified", 0); - else if (returns_list) Printv(signature, "list (", returns, ")", 0); - else Printv(signature, returns, 0); - Printv(signature, "\n", 0); - Printv(procdoc, "\f\n", signature, 0); + String *returns_text = NewString(""); + Printv(returns_text, "Returns ", 0); + if (Len(returns)==0) Printv(returns_text, "unspecified", 0); + else if (returns_list) Printv(returns_text, "list (", returns, ")", 0); + else Printv(returns_text, returns, 0); + write_doc(proc_name, signature, returns_text); + Delete(returns_text); } Delete(proc_name); @@ -718,7 +813,6 @@ GUILE::create_function (char *name, char *iname, SwigType *d, ParmList *l) Delete(returns); Delete(tmp); DelWrapper(f); - delete[] wname; } // ----------------------------------------------------------------------- @@ -743,7 +837,7 @@ GUILE::link_variable (char *name, char *iname, SwigType *t) f = NewWrapper(); // evaluation function names - sprintf (var_name, "%svar_%s", prefix, iname); + strcpy(var_name, Char(Swig_name_wrapper(name))); // Build the name for scheme. proc_name = NewString(iname); @@ -751,7 +845,11 @@ GUILE::link_variable (char *name, char *iname, SwigType *t) if ((SwigType_type(t) != T_USER) || (is_a_pointer(t))) { - Printf (f_wrappers, "SCM %s(SCM s_0) {\n", var_name); + Printf (f_wrappers, "static SCM %s(SCM s_0)\n{\n", var_name); + + /* Define the scheme name in C. This define is used by several Guile + macros. */ + Printv(f_wrappers, "#define FUNC_NAME \"", proc_name, "\"\n", 0); if (!(Status & STAT_READONLY) && SwigType_type(t) == T_STRING) { Printf (f_wrappers, "\t char *_temp;\n"); @@ -770,31 +868,9 @@ GUILE::link_variable (char *name, char *iname, SwigType *t) "\"Unable to set %s. Variable is read only.\", SCM_EOL);\n", proc_name, proc_name); } - else if ((tm = guile_typemap_lookup ("varin", - t, name, (char*)"s_0", name, f))) { - Printf (f_wrappers, "%s\n", tm); - } - else if (is_a_pointer(t)) { - if (SwigType_type(t) == T_STRING) { - Printf (f_wrappers, "\t\t _temp = gh_scm2newstr(s_0, &_len);\n"); - Printf (f_wrappers, "\t\t if (%s) { free(%s);}\n", name, name); - Printf (f_wrappers, "\t\t %s = (char *) " - "malloc((_len+1)*sizeof(char));\n", name); - Printf (f_wrappers, "\t\t strncpy(%s,_temp,_len);\n", name); - Printf (f_wrappers, "\t\t %s[_len] = 0;\n", name); - } else { - // Set the value of a pointer - Printf (f_wrappers, "\t if (SWIG_Guile_GetPtr(s_0, " - "(void **) &%s, ", name); - if (SwigType_type(t) == T_VOID) - Printf (f_wrappers, "NULL)) {\n"); - else - Printf (f_wrappers, "SWIGTYPE%s)) {\n", SwigType_manglestr(t)); - /* Raise exception */ - Printf(f_wrappers, "\tscm_wrong_type_arg(\"%s\", " - "%d, s_0);\n", proc_name, 1); - Printf (f_wrappers, "\t}\n"); - } + else if (guile_do_typemap(f_wrappers, "varin", + t, name, (char*) "s_0", name, 1, name, f, 0)) { + /* nothing */ } else { throw_unhandled_guile_type_error (t); @@ -804,24 +880,17 @@ GUILE::link_variable (char *name, char *iname, SwigType *t) // Now return the value of the variable (regardless // of evaluating or setting) - if ((tm = guile_typemap_lookup ("varout", - t, name, name, (char*)"gswig_result", f))) { - Printf (f_wrappers, "%s\n", tm); - } - else if (is_a_pointer(t)) { - if (SwigType_type(t) == T_STRING) { - Printf (f_wrappers, "\t gswig_result = gh_str02scm(%s);\n", name); - } else { - // Is an ordinary pointer type. - Printf (f_wrappers, "\t gswig_result = SWIG_Guile_MakePtr (" - "%s, SWIGTYPE%s);\n", name, SwigType_manglestr(t)); - } + if (guile_do_typemap (f_wrappers, "varout", + t, name, name, (char*)"gswig_result", + 0, name, f, 1)) { + /* nothing */ } else { throw_unhandled_guile_type_error (t); } Printf (f_wrappers, "\t return gswig_result;\n"); - Printf (f_wrappers, "}\n"); + Printf (f_wrappers, "#undef FUNC_NAME\n"); + Printf (f_wrappers, "}\n\n"); // Now add symbol to the Guile interpreter @@ -829,44 +898,44 @@ GUILE::link_variable (char *name, char *iname, SwigType *t) || Status & STAT_READONLY) { /* Read-only variables become a simple procedure returning the value. */ - Printf (f_init, "\t gh_new_procedure(\"%s\", %s, 0, 1, 0);\n", + Printf (f_init, "\t gh_new_procedure(\"%s\", (SCM (*) ()) %s, 0, 1, 0);\n", proc_name, var_name); } else { /* Read/write variables become a procedure with setter. */ - Printf (f_init, "\t{ SCM p = gh_new_procedure(\"%s\", %s, 0, 1, 0);\n", + Printf (f_init, "\t{ SCM p = gh_new_procedure(\"%s\", (SCM (*) ()) %s, 0, 1, 0);\n", proc_name, var_name); Printf (f_init, "\t gh_define(\"%s\", " "scm_make_procedure_with_setter(p, p)); }\n", proc_name); } + Printf (exported_symbols, "\"%s\", ", proc_name); if (procdoc) { /* Compute documentation */ String *signature = NewString(""); + String *doc = NewString(""); if (Status & STAT_READONLY) { - Printv(signature, "(", proc_name, ")\n", 0); - Printv(signature, "Returns constant ", 0); - guile_do_doc_typemap(signature, "varoutdoc", t, NULL, + Printv(signature, proc_name, 0); + Printv(doc, "Returns constant ", 0); + guile_do_doc_typemap(doc, "varoutdoc", t, NULL, 0, proc_name, f); - Printv(signature, "\n", 0); } else { - Printv(signature, "(", proc_name, + Printv(signature, proc_name, " #:optional ", 0); guile_do_doc_typemap(signature, "varindoc", t, "new-value", 1, proc_name, f); - Printv(signature, ")\n", 0); - Printv(signature, "If NEW-VALUE is provided, " + Printv(doc, "If NEW-VALUE is provided, " "set C variable to this value.\n", 0); - Printv(signature, "Returns variable value ", 0); - guile_do_doc_typemap(signature, "varoutdoc", t, NULL, + Printv(doc, "Returns variable value ", 0); + guile_do_doc_typemap(doc, "varoutdoc", t, NULL, 0, proc_name, f); - Printv(signature, "\n", 0); } - Printv(procdoc, "\f\n", signature, 0); + write_doc(proc_name, signature, doc); Delete(signature); + Delete(doc); } } else { @@ -881,12 +950,11 @@ GUILE::link_variable (char *name, char *iname, SwigType *t) // ----------------------------------------------------------------------- // GUILE::declare_const(char *name, char *iname, SwigType *type, char *value) // -// Makes a constant. Not sure how this is really supposed to work. -// I'm going to fake out SWIG and create a variable instead. +// We create a read-only variable. // ------------------------------------------------------------------------ void -GUILE::declare_const (char *name, char *, SwigType *type, char *value) +GUILE::declare_const (char *name, char *iname, SwigType *type, char *value) { int OldStatus = Status; // Save old status flags DOHString *proc_name; @@ -903,7 +971,7 @@ GUILE::declare_const (char *name, char *, SwigType *type, char *value) sprintf (var_name, "%sconst_%s", prefix, name); // Build the name for scheme. - proc_name = NewString(name); + proc_name = NewString(iname); Replace(proc_name,"_", "-", DOH_REPLACE_ANY); if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) { @@ -921,25 +989,17 @@ GUILE::declare_const (char *name, char *, SwigType *type, char *value) } else { rvalue = NewString(value); } - if ((tm = guile_typemap_lookup ("const", type, name, - Char(rvalue), name, f))) { - Printf (f_init, "%s\n", tm); + if (guile_do_typemap(f_header, "const", type, name, + Char(rvalue), name, 0, name, f, 0)) { + /* nothing */ } else { // Create variable and assign it a value - - Printf (f_header, "static %s %s = ", SwigType_lstr(type,0), var_name); - if (SwigType_type(type) == T_STRING) { - Printf (f_header, "\"%s\";\n", value); - } else if (SwigType_type(type) == T_CHAR) { - Printf (f_header, "\'%s\';\n", value); - } else { - Printf (f_header, "%s;\n", value); - } - // Now create a variable declaration - - link_variable (var_name, name, type); - Status = OldStatus; + Printf (f_header, "static %s %s = %s;\n", SwigType_lstr(type,0), + var_name, rvalue); } + // Now create a variable declaration + link_variable (var_name, iname, type); + Status = OldStatus; Delete(proc_name); Delete(rvalue); DelWrapper(f); @@ -959,3 +1019,14 @@ void GUILE::cpp_variable(char *name, char *iname, SwigType *t) Language::cpp_variable(name, iname, t); } } + +void GUILE::pragma(char *lang, char *cmd, char *value) +{ + if (strcmp(lang,(char*)"guile") == 0) { + if (strcmp(cmd, (char*)"beforereturn")==0) { + if (before_return) + Delete(before_return); + before_return = NewString(value); + } + } +} diff --git a/SWIG/Source/Modules1.1/guile.h b/SWIG/Source/Modules1.1/guile.h index bdfc5f75b..093107bf2 100644 --- a/SWIG/Source/Modules1.1/guile.h +++ b/SWIG/Source/Modules1.1/guile.h @@ -32,14 +32,26 @@ private: char *package; enum { GUILE_LSTYLE_SIMPLE, // call `SWIG_init()' - GUILE_LSTYLE_LTDLMOD, // "native" guile? + GUILE_LSTYLE_PASSIVE, // passive linking (no module code) + GUILE_LSTYLE_MODULE, // native guile module linking (Guile >= 1.4.1) + GUILE_LSTYLE_LTDLMOD_1_4, // old (Guile <= 1.4) dynamic module convention GUILE_LSTYLE_HOBBIT // use (hobbit4d link) } linkage; File *procdoc; + enum { + GUILE_1_4, + PLAIN, + TEXINFO + } docformat; int emit_setters; int struct_member; + String *before_return; + String *pragma_name; + String *exported_symbols; void emit_linkage(char *module_name); - + void write_doc(const String *proc_name, + const String *signature, + const String *doc); public : GUILE (); void parse_args (int, char *argv[]); @@ -54,6 +66,7 @@ public : void set_init (char *); void create_command (char *, char *) { }; void cpp_variable(char *name, char *iname, SwigType *t); + void pragma(char *lang, char *cmd, char *value); }; /* guile.h ends here */ diff --git a/SWIG/Source/Modules1.1/java.cxx b/SWIG/Source/Modules1.1/java.cxx index 18b7011d5..e44abca91 100644 --- a/SWIG/Source/Modules1.1/java.cxx +++ b/SWIG/Source/Modules1.1/java.cxx @@ -1,32 +1,11 @@ -/******************************************************************************* - * SWIG Java module - * Author: Harco de Hilster - * AT Consultancy - * Toernooiveld 104 - * P.O. Box 1428 - * 6501 BK Nijmegen - * +31 24 3527282 - * harcoh@ATConsultancy.nl +/* ----------------------------------------------------------------------------- + * java.cxx * - * thanks to the following persons for submitting bug-reports: + * Java wrapper module. * - * James Hicks <jamey@crl.dec.com> - * Lars Schmidt-Thieme <lschmidt@ix.urz.uni-heidelberg.de> - * Per OEyvind Hvidsten Per-Oyvind.Hvidsten@ffi.no - * Geoff Dillon <gdillon@pervasive.com> - * Michael Haller <haller@lionbio.co.uk> - * "Simon J. Julier" <sjulier@erols.com> - * "Pritam Kamat" <pritam@alier.com> - * Marc Hadley <marc_hadley@chrystal.co.uk> - ******************************************************************************* -*/ - -/* !!!!!!! - * DB 7/24/00: Is there any way to clean up the implementation of this module? - * I've tried to bring it as far as I can with core changes, but it's getting - * to be a little rough. - * !!!!!!! - */ + * Copyright (C) 1999-2000. The University of Chicago + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ #include <ctype.h> @@ -37,204 +16,266 @@ char bigbuf[1024]; static char *usage = (char*)"\ Java Options\n\ - -jnic - use c syntax for jni calls\n\ - -jnicpp - use c++ syntax for jni calls\n\ - -module name - set name of module\n\ - -package name - set name of package\n\ - -shadow - enable shadow classes\n\ - -finalize - generate finalize methods\n\ + -jnic - use c syntax for JNI calls\n\ + -jnicpp - use c++ syntax for JNI calls\n\ + -module <name> - set name of the module\n\ + -package <name> - set name of the package\n\ + -shadow - generate shadow classes\n\ + -nofinalize - do not generate finalize methods in shadow classes\n\ -rn - generate register natives code\n\n"; -static char *module = 0; // Name of the module -static char *java_path = (char*)"java"; -static char *package = 0; // Name of the package -static char *c_pkgstr; // Name of the package -static char *jni_pkgstr; // Name of the package -static char *shadow_classname; -static char *jimport = 0; -static char *method_modifiers = (char*)"public final static"; -static FILE *f_java = 0; -static FILE *f_shadow = 0; -static int shadow = 0; -static DOHHash *shadow_classes; -static DOHString *shadow_classdef; -static char *shadow_name = 0; -static char *shadow_baseclass = 0; -static int classdef_emitted = 0; -static int shadow_classdef_emitted = 0; -static int have_default_constructor = 0; -static int native_func = 0; // Set to 1 when wrapping a native function -static int member_func = 0; // Set to 1 when wrapping a member function -static int jnic = -1; // 1: use c syntax jni; 0: use c++ syntax jni -static int finalize = 0; // generate finalize methods -static int useRegisterNatives = 0; // Set to 1 when doing stuff with register natives -static DOHString *registerNativesList = 0; - -char *JAVA::SwigTcToJniType(DataType *t, int ret) { - if(DataType_is_pointer(t) == 1) { - switch(DataType_Gettypecode(t)) { - case T_INT: return (char*)"jintArray"; - case T_SHORT: return (char*)"jshortArray"; - case T_LONG: return (char*)"jlongArray"; - case T_CHAR: return (char*)"jstring"; - case T_FLOAT: return (char*)"jfloatArray"; - case T_DOUBLE: return (char*)"jdoubleArray"; - case T_UINT: return (char*)"jintArray"; - case T_USHORT: return (char*)"jshortArray"; - case T_ULONG: return (char*)"jlongArray"; - case T_UCHAR: return (char*)"jbyteArray"; - case T_SCHAR: return (char*)"jbyteArray"; - case T_BOOL: return (char*)"jbooleanArray"; - case T_VOID: - case T_USER: return (char*)"jlong"; - } - } else if(DataType_is_pointer(t) > 1) { - if(ret) - return (char*)"jlong"; - else return (char*)"jlongArray"; - } else { - switch(DataType_Gettypecode(t)) { - case T_INT: return (char*)"jint"; - case T_SHORT: return (char*)"jshort"; - case T_LONG: return (char*)"jlong"; - case T_CHAR: return (char*)"jbyte"; - case T_FLOAT: return (char*)"jfloat"; - case T_DOUBLE: return (char*)"jdouble"; - case T_UINT: return (char*)"jint"; - case T_USHORT: return (char*)"jshort"; - case T_ULONG: return (char*)"jlong"; - case T_UCHAR: return (char*)"jbyte"; - case T_SCHAR: return (char*)"jbyte"; - case T_BOOL: return (char*)"jboolean"; - case T_VOID: return (char*)"void"; - case T_USER: return (char*)"jlong"; - } +static char *module = 0; // Name of the module +static char *java_path = (char*)"java"; +static char *package = 0; // Name of the package +static char *c_pkgstr; // Name of the package +static char *jni_pkgstr; // Name of the package +static char *shadow_classname; +static FILE *f_java = 0; +static FILE *f_shadow = 0; +static int shadow = 0; +static Hash *shadow_classes; +static String *shadow_classdef; +static char *shadow_variable_name = 0; //Name of a c struct variable or c++ public member variable (may or may not be const) +static int classdef_emitted = 0; +static int shadow_classdef_emitted = 0; +static int have_default_constructor = 0; +static int native_func = 0; // Set to 1 when wrapping a native function +static int enum_flag = 0; // Set to 1 when wrapping an enum +static int static_flag = 0; // Set to 1 when wrapping a static functions or member variables +static int variable_wrapper_flag = 0; // Set to 1 when wrapping a member variable +static int wrapping_member = 0; // Set to 1 when wrapping a member variable/enum/const +static int jnic = -1; // 1: use c syntax jni; 0: use c++ syntax jni +static int nofinalize = 0; // for generating finalize methods +static int useRegisterNatives = 0; // Set to 1 when doing stuff with register natives +static String *registerNativesList = 0; +static String *shadow_enum_code = 0; +static String *java_enum_code = 0; +static String *module_extra_code = 0; // Extra code for the module class from %pragma +static String *all_shadow_extra_code = 0; // Extra code for all shadow classes from %pragma +static String *this_shadow_extra_code = 0; // Extra code for current single shadow class from %pragma +static String *module_import = 0; //module import from %pragma +static String *all_shadow_import = 0; //import for all shadow classes from %pragma +static String *this_shadow_import = 0; //import for current shadow classes from %pragma +static String *module_baseclass = 0; //inheritance for module class from %pragma +static String *all_shadow_baseclass = 0; //inheritance for all shadow classes from %pragma +static String *this_shadow_baseclass = 0; //inheritance for shadow class from %pragma and cpp_inherit +static String *module_interfaces = 0; //interfaces for module class from %pragma +static String *all_shadow_interfaces = 0; //interfaces for all shadow classes from %pragma +static String *this_shadow_interfaces = 0; //interfaces for shadow class from %pragma +static String *module_class_modifiers = 0; //class modifiers for module class overriden by %pragma +static String *all_shadow_class_modifiers = 0; //class modifiers for all shadow classes overriden by %pragma +static String *this_shadow_class_modifiers = 0; //class modifiers for shadow class overriden by %pragma +static String *module_method_modifiers = 0; //native method modifiers overridden by %pragma + +/* Test to see if a type corresponds to something wrapped with a shadow class */ +/* Return NULL if not otherwise the shadow name */ +static String *is_shadow(SwigType *t) { + String *r; + SwigType *lt = Swig_clocal_type(t); + r = Getattr(shadow_classes,lt); + Delete(lt); + return r; +} + +// Return the type of the c array +static SwigType *get_array_type(SwigType *t) { + SwigType *ta = 0; + if (SwigType_type(t) == T_ARRAY) { + SwigType *aop; + ta = Copy(t); + aop = SwigType_pop(ta); } - Printf(stderr, "SwigTcToJniType: unhandled SWIG type %s\n", DataType_str(t,0)); - return NULL; + return ta; } -char *JAVA::SwigTcToJavaType(DataType *t, int ret, int inShadow) { - if(DataType_is_pointer(t) == 1) { - switch(DataType_Gettypecode(t)) { - case T_INT: return (char*)"int []"; - case T_SHORT: return (char*)"short []"; - case T_LONG: return (char*)"long []"; - case T_CHAR: return (char*)"String"; - case T_FLOAT: return (char*)"float []"; - case T_DOUBLE: return (char*)"double []"; - case T_UINT: return (char*)"int []"; - case T_USHORT: return (char*)"short []"; - case T_ULONG: return (char*)"long []"; - case T_UCHAR: return (char*)"byte []"; - case T_SCHAR: return (char*)"byte []"; - case T_BOOL: return (char*)"boolean []"; - case T_VOID: - case T_USER: if(inShadow && Getattr(shadow_classes,DataType_Getname(t))) - return GetChar(shadow_classes,DataType_Getname(t)); - else return (char*)"long"; - } - } else if(DataType_is_pointer(t) > 1) { - if(ret) - return (char*)"long"; - else return (char*)"long []"; - } else { - switch(DataType_Gettypecode(t)) { - case T_INT: return (char*)"int"; - case T_SHORT: return (char*)"short"; - case T_LONG: return (char*)"long"; - case T_CHAR: return (char*)"byte"; - case T_FLOAT: return (char*)"float"; - case T_DOUBLE: return (char*)"double"; - case T_UINT: return (char*)"int"; - case T_USHORT: return (char*)"short"; - case T_ULONG: return (char*)"long"; - case T_UCHAR: return (char*)"byte"; - case T_SCHAR: return (char*)"byte"; - case T_BOOL: return (char*)"boolean"; - case T_VOID: return (char*)"void"; - case T_USER: return (char*)"long"; - } +/* +Return java type in java_type. +The type returned is the java type when shadow_flag=0. +The type returned is the java shadow type when shadow_flag=1. +*/ +void JAVA::SwigToJavaType(SwigType *t, String_or_char *pname, String* java_type, int shadow_flag) { + char *jtype = 0; + if (shadow_flag) + jtype = JavaTypeFromTypemap((char*)"jstype", t, pname); + if (!jtype) + jtype = JavaTypeFromTypemap((char*)"jtype", t, pname); + + if(jtype) { + Printf(java_type, jtype); + } + else { + /* Map type here */ + switch(SwigType_type(t)) { + case T_CHAR: Printf(java_type, "byte"); break; + case T_SCHAR: Printf(java_type, "byte"); break; + case T_UCHAR: Printf(java_type, "short"); break; + case T_SHORT: Printf(java_type, "short"); break; + case T_USHORT: Printf(java_type, "int"); break; + case T_INT: Printf(java_type, "int"); break; + case T_UINT: Printf(java_type, "long"); break; + case T_LONG: Printf(java_type, "long"); break; + case T_ULONG: Printf(java_type, "long"); break; + case T_FLOAT: Printf(java_type, "float"); break; + case T_DOUBLE: Printf(java_type, "double"); break; + case T_BOOL: Printf(java_type, "boolean"); break; + case T_STRING: Printf(java_type, "String"); break; + case T_VOID: Printf(java_type, "void"); break; + case T_POINTER: + case T_REFERENCE: + case T_USER: + if(shadow_flag && is_shadow(t)) + Printf(java_type, Char(is_shadow(t))); + else + Printf(java_type, "long"); + break; + case T_ARRAY: + if(shadow_flag && is_shadow(t)) + Printf(java_type, "%s[]", Char(is_shadow(t))); + else { + SwigType* array_type = get_array_type(t); + /* Arrays of arrays not shadowed properly yet */ + if (SwigType_type(array_type) != T_ARRAY) + SwigToJavaType(array_type, pname, java_type, shadow_flag); + else + Printf(java_type, "long"); + Printv(java_type, "[]", 0); + } + break; + default: + Printf(stderr, "SwigToJavaType: unhandled data type: %s\n", SwigType_str(t,0)); + break; + } +// printf("SwigToJavaType %d [%s]\n", SwigType_type(t), Char(java_type)); } - Printf(stderr, "SwigTcToJavaType: unhandled SWIG type %s\n", DataType_str(t,0)); - return NULL; } -char *JAVA::SwigTcToJniScalarType(DataType *t) { - if(DataType_is_pointer(t) == 1) { - switch(DataType_Gettypecode(t)) { - case T_INT: return (char*)"Int"; - case T_SHORT: return (char*)"Short"; - case T_LONG: return (char*)"Long"; - case T_CHAR: return (char*)"Byte"; - case T_FLOAT: return (char*)"Float"; - case T_DOUBLE: return (char*)"Double"; - case T_UINT: return (char*)"Int"; - case T_USHORT: return (char*)"Short"; - case T_ULONG: return (char*)"Long"; - case T_UCHAR: return (char*)"Byte"; - case T_SCHAR: return (char*)"Byte"; - case T_BOOL: return (char*)"Boolean"; - case T_VOID: - case T_USER: return (char*)"Long"; - } - } else { - return (char*)"Long"; +/* Return JNI type in jni_type. */ +void JAVA::SwigToJNIType(SwigType *t, String_or_char *pname, String* jni_type) { + char *jtype = JavaTypeFromTypemap((char*)"jni", t, pname); + + if(jtype) { + Printf(jni_type, jtype); } + else { + /* Map type here */ + switch(SwigType_type(t)) { + case T_CHAR: Printf(jni_type, "jbyte"); break; + case T_SCHAR: Printf(jni_type, "jbyte"); break; + case T_UCHAR: Printf(jni_type, "jshort"); break; + case T_SHORT: Printf(jni_type, "jshort"); break; + case T_USHORT: Printf(jni_type, "jint"); break; + case T_INT: Printf(jni_type, "jint"); break; + case T_UINT: Printf(jni_type, "jlong"); break; + case T_LONG: Printf(jni_type, "jlong"); break; + case T_ULONG: Printf(jni_type, "jlong"); break; + case T_FLOAT: Printf(jni_type, "jfloat"); break; + case T_DOUBLE: Printf(jni_type, "jdouble"); break; + case T_BOOL: Printf(jni_type, "jboolean"); break; + case T_STRING: Printf(jni_type, "jstring"); break; + case T_VOID: Printf(jni_type, "void"); break; + case T_POINTER: + case T_REFERENCE: + case T_USER: Printf(jni_type, "jlong"); break; + case T_ARRAY: + { + SwigType* array_type = get_array_type(t); + if (SwigType_type(array_type) != T_ARRAY) + SwigToJNIType(array_type, pname, jni_type); + else + Printf(jni_type, "jlong"); // Arrays of arrays not implemented + Printv(jni_type, "Array", 0); + } + break; + default: + Printf(stderr, "SwigToJNIType: unhandled data type: %s\n", SwigType_str(t,0)); + break; + } +// printf("SwigToJNIType %d [%s]\n", SwigType_type(t), Char(jni_type)); + } +} - Printf(stderr, "SwigTcToJniScalarType: unhandled SWIG type %s\n", DataType_str(t,0)); - return NULL; +char *JAVA::SwigToJavaArrayType(SwigType *t) { + switch(SwigType_type(t)) { + case T_CHAR: return (char*)"Byte"; + case T_SCHAR: return (char*)"Byte"; + case T_UCHAR: return (char*)"Short"; + case T_SHORT: return (char*)"Short"; + case T_USHORT: return (char*)"Int"; + case T_INT: return (char*)"Int"; + case T_UINT: return (char*)"Long"; + case T_LONG: return (char*)"Long"; + case T_ULONG: return (char*)"Long"; + case T_FLOAT: return (char*)"Float"; + case T_DOUBLE: return (char*)"Double"; + case T_BOOL: return (char*)"Boolean"; + case T_STRING: return (char*)"String"; + case T_POINTER: + case T_REFERENCE: + case T_ARRAY: + case T_VOID: + case T_USER: + default : return (char*)"Long"; // Treat as a pointer + } } -char *JAVA::JavaMethodSignature(DataType *t, int ret, int inShadow) { - if(DataType_is_pointer(t) == 1) { - switch(DataType_Gettypecode(t)) { - case T_INT: return (char*)"[I"; +/* JavaMethodSignature still needs updating for changes from SWIG1.3a3 to SWIG1.3a5 */ +char *JAVA::JavaMethodSignature(SwigType *t, int ret, int inShadow) { + if(SwigType_ispointer(t) == 1) { + switch(SwigType_type(t)) { + case T_CHAR: return (char*)"Ljava/lang/String;"; + case T_SCHAR: return (char*)"[B"; + case T_UCHAR: return (char*)"[S"; case T_SHORT: return (char*)"[S"; + case T_USHORT: return (char*)"[I"; + case T_INT: return (char*)"[I"; + case T_UINT: return (char*)"[J"; case T_LONG: return (char*)"[J"; - case T_CHAR: return (char*)"Ljava/lang/String;"; + case T_ULONG: return (char*)"[J"; case T_FLOAT: return (char*)"[F"; case T_DOUBLE: return (char*)"[D"; - case T_UINT: return (char*)"[I"; - case T_USHORT: return (char*)"[S"; - case T_ULONG: return (char*)"[J"; - case T_UCHAR: return (char*)"[B"; - case T_SCHAR: return (char*)"[B"; case T_BOOL: return (char*)"[Z"; + case T_STRING: return (char*)"Ljava/lang/String;"; + case T_POINTER: return (char*)"[J"; + case T_REFERENCE: return (char*)"[J"; + case T_ARRAY: return (char*)"???"; case T_VOID: - case T_USER: if(inShadow && Getattr(shadow_classes,DataType_Getname(t))) - return GetChar(shadow_classes,DataType_Getname(t)); + case T_USER: if(inShadow && is_shadow(t)) + return Char(is_shadow(t)); else return (char*)"J"; } - } else if(DataType_is_pointer(t) > 1) { + } else if(SwigType_ispointer(t) > 1) { if(ret) return (char*)"J"; else return (char*)"[J"; } else { - switch(DataType_Gettypecode(t)) { - case T_INT: return (char*)"I"; + switch(SwigType_type(t)) { + case T_CHAR: return (char*)"B"; + case T_SCHAR: return (char*)"B"; + case T_UCHAR: return (char*)"S"; case T_SHORT: return (char*)"S"; + case T_USHORT: return (char*)"I"; + case T_INT: return (char*)"I"; + case T_UINT: return (char*)"J"; case T_LONG: return (char*)"J"; - case T_CHAR: return (char*)"B"; + case T_ULONG: return (char*)"J"; case T_FLOAT: return (char*)"F"; case T_DOUBLE: return (char*)"D"; - case T_UINT: return (char*)"I"; - case T_USHORT: return (char*)"S"; - case T_ULONG: return (char*)"J"; - case T_UCHAR: return (char*)"B"; - case T_SCHAR: return (char*)"B"; case T_BOOL: return (char*)"Z"; + case T_STRING: return (char*)"Ljava/lang/String;"; + case T_POINTER: return (char*)"J"; + case T_REFERENCE: return (char*)"J"; + case T_ARRAY: return (char*)"???"; case T_VOID: return (char*)"V"; case T_USER: return (char*)"J"; } } - Printf(stderr, "JavaMethodSignature: unhandled SWIG type %s\n", DataType_str(t,0)); + Printf(stderr, "JavaMethodSignature: unhandled SWIG type [%d] %s\n", SwigType_type(t), SwigType_str(t,0)); return NULL; } -char *JAVA::JavaTypeFromTypemap(char *op, char *lang, DataType *t, char *pname) { +char *JAVA::JavaTypeFromTypemap(char *op, SwigType *t, String_or_char *pname) { char *tm; char *c = bigbuf; - if(!(tm = typemap_lookup(op, lang, t, pname, (char*)"", (char*)""))) return NULL; + if(!(tm = Swig_typemap_lookup(op, t, pname, (char*)"", (char*)"", NULL))) return NULL; while(*tm && (isspace(*tm) || *tm == '{')) tm++; while(*tm && *tm != '}') *c++ = *tm++; *c='\0'; @@ -248,7 +289,8 @@ char *JAVA::makeValidJniName(char *name) { while(*c) { *b++ = *c; - if(*c == '_') *b++ = '1'; + if(*c == '_') + *b++ = '1'; c++; } *b = '\0'; @@ -257,7 +299,7 @@ char *JAVA::makeValidJniName(char *name) { } // !! this approach fails for functions without arguments -char *JAVA::JNICALL(DOHString_or_char *func) { +char *JAVA::JNICALL(String_or_char *func) { if(jnic) sprintf(bigbuf, "(*jenv)->%s(jenv, ", Char(func)); else @@ -327,7 +369,7 @@ void JAVA::parse_args(int argc, char *argv[]) { if (argv[i]) { if (strcmp(argv[i],"-module") == 0) { if (argv[i+1]) { - set_module(argv[i+1],0); + set_module(argv[i+1]); Swig_mark_arg(i); Swig_mark_arg(i+1); i++; @@ -350,9 +392,9 @@ void JAVA::parse_args(int argc, char *argv[]) { } else if (strcmp(argv[i],"-jnic") == 0) { Swig_mark_arg(i); jnic = 1; - } else if (strcmp(argv[i],"-finalize") == 0) { + } else if (strcmp(argv[i],"-nofinalize") == 0) { Swig_mark_arg(i); - finalize = 1; + nofinalize = 1; } else if (strcmp(argv[i],"-rn") == 0) { Swig_mark_arg(i); useRegisterNatives = 1; @@ -386,28 +428,35 @@ void JAVA::parse_args(int argc, char *argv[]) { // --------------------------------------------------------------------- void JAVA::parse() { - - Printf(stderr,"Generating wrappers for Java\n"); - shadow_classes = NewHash(); shadow_classdef = NewString(""); registerNativesList = NewString(""); + java_enum_code = NewString(""); + module_extra_code = NewString(""); + module_baseclass = NewString(""); + module_interfaces = NewString(""); + module_class_modifiers = NewString(""); + all_shadow_extra_code = NewString(""); + all_shadow_import = NewString(""); + all_shadow_baseclass = NewString(""); + all_shadow_interfaces = NewString(""); + all_shadow_class_modifiers = NewString(""); + module_import = NewString(""); + module_method_modifiers = NewString("public final static"); headers(); // Emit header files and other supporting code yyparse(); // Run the SWIG parser } // --------------------------------------------------------------------- -// JAVA::set_module(char *mod_name,char **mod_list) +// JAVA::set_module(char *mod_name) // // Sets the module name. Does nothing if it's already set (so it can // be overriddent as a command line option). // -// mod_list is a NULL-terminated list of additional modules. This -// is really only useful when building static executables. //---------------------------------------------------------------------- -void JAVA::set_module(char *mod_name, char **mod_list) { +void JAVA::set_module(char *mod_name) { if (module) return; module = new char[strlen(mod_name)+1]; strcpy(module,mod_name); @@ -447,13 +496,13 @@ void JAVA::initialize() } if(package) { - DOHString *s = NewString(package); + String *s = NewString(package); Replace(s,".","_", DOH_REPLACE_ANY); Append(s,"_"); c_pkgstr = Swig_copy_string(Char(s)); Delete(s); - DOHString *s2 = NewString(package); + String *s2 = NewString(package); Replace(s2,".","/", DOH_REPLACE_ANY); Append(s2,"/"); jni_pkgstr = Swig_copy_string(Char(s2)); @@ -464,7 +513,12 @@ void JAVA::initialize() sprintf(bigbuf, "Java_%s%s", c_pkgstr, module); c_pkgstr = Swig_copy_string(bigbuf); - sprintf(bigbuf, "%s_%%f", c_pkgstr); + + if (strchr(module + strlen(module)-1, '_')) //if module has a '_' as last character + sprintf(bigbuf, "%s1_%%f", c_pkgstr); //separate double underscore with 1 + else + sprintf(bigbuf, "%s_%%f", c_pkgstr); + Swig_name_register((char*)"wrapper", Swig_copy_string(bigbuf)); Swig_name_register((char*)"set", (char*)"set_%v"); Swig_name_register((char*)"get", (char*)"get_%v"); @@ -486,9 +540,36 @@ void JAVA::initialize() } } +void emit_banner(FILE *f) { + Printf(f, "/* ----------------------------------------------------------------------------\n"); + Printf(f, " * This file was automatically generated by SWIG (http://www.swig.org).\n"); + Printf(f, " * Version: %s\n", SWIG_VERSION); + Printf(f, " *\n"); + Printf(f, " * Do not make changes to this file unless you know what you are doing--modify\n"); + Printf(f, " * the SWIG interface file instead.\n"); + Printf(f, " * ----------------------------------------------------------------------------- */\n\n"); +} + void JAVA::emit_classdef() { - if(!classdef_emitted) - Printf(f_java, "public class %s {\n", module); + if(!classdef_emitted) { + emit_banner(f_java); + if(module_import) + Printf(f_java, "%s\n", module_import); + + if (module_class_modifiers && *Char(module_class_modifiers)) + Printf(f_java, "%s", module_class_modifiers); + else + Printf(f_java, "public"); + Printf(f_java, " class %s ", module); + + if (module_baseclass) + Printv(f_java, module_baseclass, 0); + if (module_interfaces) + Printv(f_java, module_interfaces, " ", 0); + Printf(f_java, "{\n", module); + if (module_extra_code) + Printv(f_java, module_extra_code, 0); + } classdef_emitted = 1; } @@ -502,12 +583,33 @@ void JAVA::close(void) { if(!classdef_emitted) emit_classdef(); + // Write the enum initialisation code in a static block. + // These are all the enums defined in the global c context. + if (strlen(Char(java_enum_code)) != 0 ) + Printv(f_java, " static {\n // Initialise java constants from c/c++ enums\n", java_enum_code, " }\n",0); + // Finish off the java class Printf(f_java, "}\n"); fclose(f_java); if(useRegisterNatives) writeRegisterNatives(); + + Delete(shadow_classes); shadow_classes = NULL; + Delete(shadow_classdef); shadow_classdef = NULL; + Delete(registerNativesList); registerNativesList = NULL; + Delete(java_enum_code); java_enum_code = NULL; + Delete(module_extra_code); module_extra_code = NULL; + Delete(module_baseclass); module_baseclass = NULL; + Delete(module_interfaces); module_interfaces = NULL; + Delete(module_class_modifiers); module_class_modifiers = NULL; + Delete(all_shadow_extra_code); all_shadow_extra_code = NULL; + Delete(all_shadow_import); all_shadow_import = NULL; + Delete(all_shadow_baseclass); all_shadow_baseclass = NULL; + Delete(all_shadow_interfaces); all_shadow_interfaces = NULL; + Delete(all_shadow_class_modifiers); all_shadow_class_modifiers = NULL; + Delete(module_import); module_import = NULL; + Delete(module_method_modifiers); module_method_modifiers = NULL; } // ---------------------------------------------------------------------- @@ -519,31 +621,54 @@ void JAVA::close(void) void JAVA::create_command(char *cname, char *iname) { } -void JAVA::add_native(char *name, char *iname, DataType *t, ParmList *l) { +void JAVA::add_native(char *name, char *iname, SwigType *t, ParmList *l) { native_func = 1; create_function(name, iname, t, l); native_func = 0; } // ---------------------------------------------------------------------- -// JAVA::create_function(char *name, char *iname, DataType *d, ParmList *l) +// JAVA::create_function(char *name, char *iname, SwigType *d, ParmList *l) // // Create a function declaration and register it with the interpreter. // ---------------------------------------------------------------------- -void JAVA::create_function(char *name, char *iname, DataType *t, ParmList *l) +void JAVA::create_function(char *name, char *iname, SwigType *t, ParmList *l) { - char source[256], target[256]; + char source[256], target[256]; char *tm; - DOHString *cleanup, *outarg, *body; char *javaReturnSignature = 0; - DOHString *javaParameterSignature; - Parm *p; + String *jnirettype = NewString(""); + String *javarettype = NewString(""); + String *cleanup = NewString(""); + String *outarg = NewString(""); + String *body = NewString(""); + String *javaParameterSignature = NewString(""); + + /* + Generate the java class wrapper function ie the java shadow class. Only done for public + member variables. That is this generates the getters/setters for member variables. + */ + if(shadow && wrapping_member && !enum_flag) { + String *member_function_name = NewString(""); + String *java_function_name = NewString(iname); + if(strcmp(iname, Char(Swig_name_set(Swig_name_member(shadow_classname, shadow_variable_name)))) == 0) + Printf(member_function_name,"set"); + else Printf(member_function_name,"get"); + Putc(toupper((int) *shadow_variable_name), member_function_name); + Printf(member_function_name, "%s", shadow_variable_name+1); + + cpp_func(Char(member_function_name), t, l, java_function_name); + + Delete(java_function_name); + Delete(member_function_name); + } - cleanup = NewString(""); - outarg = NewString(""); - body = NewString(""); - javaParameterSignature = NewString(""); + /* + The rest of create_function deals with generating the java wrapper function (that wraps + a c/c++ function) and generating the JNI c code. Each java wrapper function has a + matching JNI c function call. + */ // A new wrapper function object Wrapper *f = NewWrapper(); @@ -551,15 +676,14 @@ void JAVA::create_function(char *name, char *iname, DataType *t, ParmList *l) if(!classdef_emitted) emit_classdef(); // Make a wrapper name for this function - char *jniname = makeValidJniName(iname); - char *wname = Swig_name_wrapper(jniname); + String *wname = Swig_name_wrapper(jniname); + free(jniname); - char *jnirettype = JavaTypeFromTypemap((char*)"jni", typemap_lang, t, iname); - if(!jnirettype) jnirettype = SwigTcToJniType(t, 1); - char *javarettype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, t, iname); - if(!javarettype) javarettype = SwigTcToJavaType(t, 1, 0); + /* Get the java and jni types of the return */ + SwigToJNIType(t, iname, jnirettype); + SwigToJavaType(t, iname, javarettype, 0); // If dumping the registerNative outputs, store the method return type // signature @@ -567,25 +691,15 @@ void JAVA::create_function(char *name, char *iname, DataType *t, ParmList *l) javaReturnSignature = JavaMethodSignature(t, 1, 0); } - if (DataType_type(t) != T_VOID) { - Wrapper_add_localv(f,"_jresult", jnirettype, "_jresult = 0",0); + if (SwigType_type(t) != T_VOID) { + Wrapper_add_localv(f,"jresult", jnirettype, "jresult = 0",0); } - Printf(f_java, " %s ", method_modifiers); + Printf(f_java, " %s ", module_method_modifiers); Printf(f_java, "native %s %s(", javarettype, iname); - if(shadow && member_func) { - DOHString *member_name = NewString(""); - if(strcmp(iname, Swig_name_set(Swig_name_member(shadow_classname, shadow_name))) == 0) - Printf(member_name,"set"); - else Printf(member_name,"get"); - Putc(toupper((int) *shadow_name), member_name); - Printf(member_name, "%s", shadow_name+1); - Printf(f_shadow, " public %s %s(", javarettype, member_name); - Printv(body, tab4, "return ", module, ".", iname, "(_self", 0); - Delete(member_name); - } - if(!jnic) Printf(f->def,"extern \"C\"\n"); + if(!jnic) + Printv(f->def, "extern \"C\"{\n", 0); Printv(f->def, "JNIEXPORT ", jnirettype, " JNICALL ", wname, "(JNIEnv *jenv, jclass jcls", 0); // Emit all of the local variables for holding arguments. @@ -594,198 +708,288 @@ void JAVA::create_function(char *name, char *iname, DataType *t, ParmList *l) int gencomma = 0; // Now walk the function parameter list and generate code to get arguments - p = l; + Parm *p = l; for (int i = 0; i < pcount ; i++, p = Getnext(p)) { - DataType *pt = Gettype(p); - char *pn = Getname(p); - char *target_copy = NULL; - char *target_length = NULL; - char *local_i = NULL; + SwigType *pt = Gettype(p); + String *pn = Getname(p); + String *javaparamtype = NewString(""); + String *jni_param_type = NewString(""); // Produce string representation of source and target arguments - sprintf(source,"jarg%d",i); - sprintf(target,"%s", Getlname(p)); + sprintf(target,"%s", Char(Getlname(p))); + sprintf(source,"j%s", target); - char *jnitype = JavaTypeFromTypemap((char*)"jni", typemap_lang, pt, pn); - if(!jnitype) jnitype = SwigTcToJniType(pt, 0); - char *jtype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, pt, pn); - if(!jtype) jtype = SwigTcToJavaType(pt, 0, 0); if (useRegisterNatives) { Printv(javaParameterSignature, JavaMethodSignature(pt, 0, 0), 0); } if(Getignore(p)) continue; - // Add to java function header - if(shadow && member_func) { - if(i > 0) { - if(i>1) Printf(f_shadow, ", "); - Printf(f_shadow, "%s %s", jtype, source); - Printv(body,", ", source, 0); - } - } + /* Get the java and jni types of the parameter */ + SwigToJNIType(pt, pn, jni_param_type); + SwigToJavaType(pt, pn, javaparamtype, 0); + /* Add to java function header */ if(gencomma) Printf(f_java, ", "); - Printf(f_java, "%s %s", jtype, source); + Printf(f_java, "%s %s", javaparamtype, source); gencomma = 1; // Add to Jni function header - Printv(f->def, ", ", jnitype, " ", source, 0); + Printv(f->def, ", ", jni_param_type, " ", source, 0); // Get typemap for this argument - tm = typemap_lookup((char*)"in",typemap_lang,pt,pn,source,target,f); + tm = Swig_typemap_lookup((char*)"in",pt,pn,source,target,f); if (tm) { - Printf(f->code,"%s\n", tm); - Replace(f->code,"$arg",source, DOH_REPLACE_ANY); + Printf(f->code,"%s\n", tm); + Replace(f->code,"$arg",source, DOH_REPLACE_ANY); } else { - if(!DataType_is_pointer(pt)) - Printv(f->code, tab4, target, " = (", DataType_lstr(pt,0), ") ", source, ";\n", 0); - else if((DataType_Gettypecode(pt) == T_VOID && (DataType_is_pointer(pt) == 1)) || - (DataType_Gettypecode(pt) == T_USER && (DataType_is_pointer(pt) == 1))) { - DataType_add_pointer(pt); - Printv(f->code, tab4, target, " = *(", DataType_lstr(pt,0), ")&", source, ";\n", 0); - DataType_del_pointer(pt); - } else { - if(DataType_type(pt) == T_STRING) { - Printv(f->code, tab4, target, " = (", source, ") ? (char *)", JNICALL((char*)"GetStringUTFChars"), source, ", 0) : NULL;\n", 0); - } else { - char *scalarType = SwigTcToJniScalarType(pt); - - DataType_del_pointer(pt); - const char *basic_jnitype = (DataType_is_pointer(pt) > 0) ? "jlong" : SwigTcToJniType(pt, 0); - char *ctype = DataType_lstr(pt,0); - if(scalarType == NULL || basic_jnitype == NULL) { - Printf(stderr, "\'%s\' does not have a in/jni typemap, and is not a basic type.\n", ctype); - SWIG_exit(1); - }; - DataType_add_pointer(pt); - - DOHString *basic_jniptrtype = NewStringf("%s*",basic_jnitype); - DOHString *source_length = NewStringf("%s%s)", JNICALL((char*)"GetArrayLength"), source); - - target_copy = Swig_copy_string(Wrapper_new_localv(f,target,Char(basic_jniptrtype), target, 0)); - target_length = Swig_copy_string(Wrapper_new_localv(f,target,"jsize", target, "=", Char(source_length),0)); - if(local_i == NULL) local_i = Swig_copy_string(Wrapper_new_local(f,"i","int i")); - - DOHString *scalarFunc = NewStringf("Get%sArrayElements",scalarType); - - Printv(f->code, tab4, target_copy, " = ", JNICALL(scalarFunc), source, ", 0);\n", 0); - Printv(f->code, tab4, target, " = (", DataType_lstr(pt,0), ") malloc(", target_length, " * sizeof(", ctype, "));\n", 0); - Printv(f->code, tab4, "for(i=0; i<", target_length, "; i++)\n", 0); - if(DataType_is_pointer(pt) > 1) { - Printv(f->code, tab8, target, "[i] = *(", DataType_lstr(pt,0), ")&", target_copy, "[i];\n", 0); - } else { - DataType_del_pointer(pt); - Printv(f->code, tab8, target, "[i] = (", DataType_lstr(pt,0), ")", target_copy, "[i];\n", 0); - DataType_add_pointer(pt); - } - Delete(scalarFunc); - Delete(source_length); - Delete(basic_jniptrtype); + switch(SwigType_type(pt)) { + case T_BOOL: + case T_CHAR: + case T_SCHAR: + case T_UCHAR: + case T_SHORT: + case T_USHORT: + case T_INT: + case T_UINT: + case T_LONG: + case T_ULONG: + case T_FLOAT: + case T_DOUBLE: + Printv(f->code, tab4, target, " = (", SwigType_lstr(pt,0), ") ", source, ";\n", 0); + break; + case T_STRING: + Printv(f->code, tab4, target, " = (", source, ") ? (char *)", JNICALL((char*)"GetStringUTFChars"), source, ", 0) : NULL;\n", 0); + break; + case T_VOID: + break; + case T_USER: + Printv(f->code, tab4, target, " = *(", SwigType_lstr(pt,0), "**)&", source, ";\n", 0); + break; + case T_POINTER: + case T_REFERENCE: + Printv(f->code, tab4, target, " = *(", SwigType_lstr(pt,0), "*)&", source, ";\n", 0); + break; + case T_ARRAY: + { + String *jni_array_type = NewString(""); + SwigType *array_type = get_array_type(pt); + char *java_array_type = SwigToJavaArrayType(array_type); + SwigToJNIType(array_type, pn, jni_array_type); + + String *ctype = SwigType_lstr(array_type, 0); + + String *basic_jniptrtype = NewStringf("%s*", jni_array_type); + String *source_length = NewStringf("%s%s)", JNICALL((char*)"GetArrayLength"), source); + String *c_array = NewStringf("%s_carray", source); + String *array_len = NewStringf("%s_len", source); + String *get_array_func = NewStringf("Get%sArrayElements", java_array_type); + + Wrapper_add_localv(f, "i", "int", "i", 0); // Only gets added once if called more than once + Wrapper_add_localv(f, c_array, basic_jniptrtype, c_array, 0); + Wrapper_add_localv(f, array_len, "jsize", array_len, "= ", source_length, 0); + + Printv(f->code, tab4, c_array, " = ", JNICALL(get_array_func), source, ", 0);\n", 0); + Printv(f->code, tab4, target, " = (", SwigType_lstr(pt, 0), ") malloc(", array_len, " * sizeof(", ctype, "));\n", 0); + Printv(f->code, tab4, "for(i=0; i<", array_len, "; i++)\n", 0); + + switch(SwigType_type(array_type)) { + case T_USER: + Printv(f->code, tab8, target, "[i] = **(", ctype, "**)&", c_array, "[i];\n", 0); + break; + case T_POINTER: + Printv(f->code, tab8, target, "[i] = *(", ctype, "*)&", c_array, "[i];\n", 0); + break; + default: + Printv(f->code, tab8, target, "[i] = (", ctype, ")", c_array, "[i];\n", 0); + break; + } + + Delete(jni_array_type); + Delete(basic_jniptrtype); + Delete(source_length); + Delete(c_array); + Delete(array_len); + Delete(get_array_func); } + break; + default: + Printf(stderr,"%s : Line %d. Error: Unknown typecode for type %s\n", input_file,line_number,SwigType_str(pt,0)); + break; } } // Check to see if there was any sort of a constaint typemap - if ((tm = typemap_lookup((char*)"check",typemap_lang,pt,pn,source,target))) { + if ((tm = Swig_typemap_lookup((char*)"check",pt,pn,source,target,NULL))) { // Yep. Use it instead of the default Printf(f->code,"%s\n", tm); Replace(f->code,"$arg",source, DOH_REPLACE_ANY); } // Check if there was any cleanup code (save it for later) - if ((tm = typemap_lookup((char*)"freearg",typemap_lang,pt,pn,source,target))) { + if ((tm = Swig_typemap_lookup((char*)"freearg",pt,pn,source,target,NULL))) { // Yep. Use it instead of the default Printf(cleanup,"%s\n", tm); Replace(cleanup,"$arg",source, DOH_REPLACE_ANY); } - if ((tm = typemap_lookup((char*)"argout",typemap_lang,pt,pn,source,target))) { + if ((tm = Swig_typemap_lookup((char*)"argout",pt,pn,source,target,NULL))) { // Yep. Use it instead of the default Printf(outarg,"%s\n", tm); Replace(outarg,"$arg",source, DOH_REPLACE_ANY); } else { - // if(pt->is_pointer && pt->type != T_USER && pt->type != T_VOID) { - if(DataType_is_pointer(pt)) { - if(DataType_type(pt) == T_STRING) { - Printv(outarg, tab4, "if(", target,") ", JNICALL((char*)"ReleaseStringUTFChars"), source, ", ", target, ");\n", 0); - } else if(((DataType_Gettypecode(pt) == T_VOID) && DataType_is_pointer(pt) == 1) || - ((DataType_Gettypecode(pt) == T_USER) && DataType_is_pointer(pt) == 1)) { - // nothing to do - } else { - char *scalarType = SwigTcToJniScalarType(pt); - - DataType_del_pointer(pt); - const char *basic_jnitype = (DataType_is_pointer(pt) > 0) ? "jlong" : SwigTcToJniType(pt, 0); - char *ctype = DataType_lstr(pt,0); - if(scalarType == NULL || basic_jnitype == NULL) { - Printf(stderr, "\'%s\' does not have a argout/jni typemap, and is not a basic type.\n", ctype); - SWIG_exit(1); - }; - DataType_add_pointer(pt); - Printf(outarg, " for(i=0; i< %d; i++)\n", target_length); - if(DataType_is_pointer(pt) > 1) { - Printv(outarg, tab8, "*(", DataType_lstr(pt,0), ")&", target_copy, "[i] = ", target, "[i];\n", 0); - } else { - Printv(outarg, tab8, target_copy, "[i] = (", basic_jnitype, ") ", target, "[i];\n", 0); - } - DOHString *scalarFunc = NewStringf("Release%sArrayElements",scalarType); - Printv(outarg, tab4, JNICALL(scalarFunc), source, ", ", target_copy, ", 0);\n", 0); - Printv(outarg, tab4, "free(", target, ");\n", 0); - Delete(scalarFunc); - free(target_copy); - free(target_length); - free(local_i); - } - } + switch(SwigType_type(pt)) { + case T_BOOL: + case T_CHAR: + case T_SCHAR: + case T_UCHAR: + case T_SHORT: + case T_USHORT: + case T_INT: + case T_UINT: + case T_LONG: + case T_ULONG: + case T_FLOAT: + case T_DOUBLE: + // nothing to do + break; + case T_STRING: + Printv(outarg, tab4, "if(", target,") ", JNICALL((char*)"ReleaseStringUTFChars"), source, ", ", target, ");\n", 0); + break; + case T_VOID: + case T_USER: + case T_POINTER: + case T_REFERENCE: + // nothing to do + break; + case T_ARRAY: + { + String *jni_array_type = NewString(""); + SwigType *array_type = get_array_type(pt); + char *java_array_type = SwigToJavaArrayType(array_type); + SwigToJNIType(array_type, pn, jni_array_type); + + String *c_array = NewStringf("%s_carray", source); + String *release_array_func = NewStringf("Release%sArrayElements", java_array_type); + + Printv(outarg, tab4, JNICALL(release_array_func), source, ", ", c_array, ", 0);\n", 0); + Printv(outarg, tab4, "free(", target, ");\n", 0); + + Delete(jni_array_type); + Delete(c_array); + Delete(release_array_func); + } + break; + default: + Printf(stderr,"%s : Line %d. Error: Unknown typecode for type %s\n", input_file,line_number,SwigType_str(pt,0)); + break; + } + } + Delete(javaparamtype); + Delete(jni_param_type); } - } Printf(f_java, ");\n"); - if(shadow && member_func) { - Printf(f_shadow, ") {\n"); - Printf(body,")"); - Printf(f_shadow, "%s;\n }\n\n",body); - } Printf(f->def,") {"); // Now write code to make the function call if(!native_func) emit_func_call(name,t,l,f); - // Return value if necessary - if((DataType_type(t) != T_VOID) && !native_func) { - if ((tm = typemap_lookup((char*)"out",typemap_lang,t,iname,(char*)"result",(char*)"_jresult"))) { + if((SwigType_type(t) != T_VOID) && !native_func) { + if ((tm = Swig_typemap_lookup((char*)"out",t,iname,(char*)"result",(char*)"jresult",NULL))) { Printf(f->code,"%s\n", tm); } else { - if(DataType_type(t) == T_USER) { /* return by value */ - DataType_add_pointer(t); - DataType_add_pointer(t); - Printv(f->code, tab4, "*(", DataType_lstr(t,0), ")&_jresult = result;\n", 0); - DataType_del_pointer(t); - DataType_del_pointer(t); - } else if(DataType_is_pointer(t) == 0 && (DataType_Gettypecode(t) != T_USER)) { - Printv(f->code, tab4, "_jresult = (", jnirettype, ") result;\n", 0); - } else if(((DataType_Gettypecode(t) == T_VOID) && DataType_is_pointer(t) == 1) || - ((DataType_Gettypecode(t) == T_USER) && DataType_is_pointer(t) == 1)) { - DataType_add_pointer(t); - Printv(f->code, tab4, "*(", DataType_lstr(t,0), ")&_jresult = result;\n", 0); - DataType_del_pointer(t); - } else { - if(DataType_type(t) == T_STRING) { - Printv(f->code, tab4, "if(result != NULL)\n", 0); - Printv(f->code, tab8, "_jresult = (jstring)", JNICALL((char*)"NewStringUTF"), "result);\n", 0); - } else { - Printf(stderr,"%s : Line %d. Warning: no return typemap for datatype %s\n", input_file,line_number,DataType_str(t,0)); - DataType_add_pointer(t); - Printv(f->code, tab4, "*(", DataType_lstr(t,0), ")&_jresult = result;\n", 0); - DataType_del_pointer(t); + switch(SwigType_type(t)) { + case T_BOOL: + case T_CHAR: + case T_SCHAR: + case T_UCHAR: + case T_SHORT: + case T_USHORT: + case T_INT: + case T_UINT: + case T_LONG: + case T_ULONG: + case T_FLOAT: + case T_DOUBLE: + Printv(f->code, tab4, "jresult = (", jnirettype, ") result;\n", 0); + break; + case T_STRING: + Printv(f->code, tab4, "if(result != NULL)\n", 0); + Printv(f->code, tab8, "jresult = (jstring)", JNICALL((char*)"NewStringUTF"), "result);\n", 0); + break; + case T_VOID: + break; + case T_USER: + Printv(f->code, tab4, "*(", SwigType_lstr(t,0), "**)&jresult = result;\n", 0); + break; + case T_POINTER: + case T_REFERENCE: + Printv(f->code, tab4, "*(", SwigType_lstr(t,0), "*)&jresult = result;\n", 0); + break; + case T_ARRAY: + { + // Handle return values that are one dimension arrays + // Todo: What about void pointers? + // Todo: Check on array size - check user has passed correct size in + + const int dim_no = 0; // Dimension number (0 == 1st ) - currently only 1 supported + String *jnitype_ptr = NewString(""); + String *jnicall_new = NewString(""); + String *jnicall_get = NewString(""); + String *jnicall_release = NewString(""); + String *jni_array_type = NewString(""); + SwigType *array_type = get_array_type(t); + char *java_array_type = SwigToJavaArrayType(array_type); + SwigToJNIType(array_type, iname, jni_array_type); + + Printv(jnitype_ptr, jni_array_type, "*", 0); + Wrapper_add_localv(f, "jnitype_ptr", jnitype_ptr, "jnitype_ptr", "= 0", 0); + Wrapper_add_localv(f, "k", "int", "k", 0); + + // Create a java array for return to Java subsystem, eg for int array + // String jresult = (*jenv)->NewIntArray(jenv, array_size); + Printv(jnicall_new, "New", java_array_type, "Array", 0); + Printv(f->code, tab4, "jresult = ", JNICALL((char*)jnicall_new), SwigType_array_getdim(t, dim_no), ");\n", 0); + + // Get the c memory pointer to the java array, eg for int array + // jnitype_ptr = (*jenv)->GetIntArrayElements(jenv, jresult, 0); + Printv(jnicall_get, "Get", java_array_type, "ArrayElements", 0); + Printv(f->code, tab4, "jnitype_ptr = ", JNICALL((char*)jnicall_get), "jresult, 0);\n", 0); + + // Populate the java array from the c array + Printv(f->code, tab4, "for (k=0; k<", SwigType_array_getdim(t, dim_no), "; k++)\n", 0); + switch(SwigType_type(array_type)) { + case T_USER: + Printv(f->code, tab8, "*(", SwigType_lstr(array_type, 0), "**)&jnitype_ptr[k] = &result[k];\n", 0); + break; + case T_POINTER: + Printv(f->code, tab8, "*(", SwigType_lstr(array_type, 0), "*)&jnitype_ptr[k] = result[k];\n", 0); + break; + default: + Printv(f->code, tab8, "jnitype_ptr[k] = (", jni_array_type, ")result[k];\n", 0); + break; + } + // Release reference to the array so that it may be garbage collected in the future + // (*jenv)->ReleaseIntArrayElements(jenv, jresult, _arg00, 0); + Printv(jnicall_release, "Release", java_array_type, "ArrayElements", 0); + Printv(f->code, tab4, JNICALL((char*)jnicall_release), "jresult, ", "jnitype_ptr", ", 0);\n", 0); + Delete(jnitype_ptr); + Delete(jnicall_new); + Delete(jnicall_get); + Delete(jnicall_release); + Delete(jni_array_type); + } + break; + default: + Printf(stderr,"%s : Line %d. Error: Unknown typecode for type %s\n", input_file,line_number,SwigType_str(t,0)); + break; } } - } } // Dump argument output code; @@ -797,20 +1001,22 @@ void JAVA::create_function(char *name, char *iname, DataType *t, ParmList *l) // Look for any remaining cleanup if (NewObject) { - if ((tm = typemap_lookup((char*)"newfree",typemap_lang,t,iname,(char*)"result",(char*)""))) { + if ((tm = Swig_typemap_lookup((char*)"newfree",t,iname,(char*)"result",(char*)"",NULL))) { Printf(f->code,"%s\n", tm); } } - if((DataType_type(t) != T_VOID) && !native_func) { - if ((tm = typemap_lookup((char*)"ret",typemap_lang,t,iname,(char*)"result",(char*)"_jresult", NULL))) { + if((SwigType_type(t) != T_VOID) && !native_func) { + if ((tm = Swig_typemap_lookup((char*)"ret",t,iname,(char*)"result",(char*)"jresult", NULL))) { Printf(f->code,"%s\n", tm); } } // Wrap things up (in a manner of speaking) - if(DataType_type(t) != T_VOID) - Printv(f->code, tab4, "return _jresult;\n", 0); + if(SwigType_type(t) != T_VOID) + Printv(f->code, tab4, "return jresult;\n", 0); + if(!jnic) + Printf(f->code, "}"); Printf(f->code, "}\n"); // Substitute the cleanup code (some exception handlers like to have this) @@ -831,6 +1037,8 @@ void JAVA::create_function(char *name, char *iname, DataType *t, ParmList *l) } + Delete(jnirettype); + Delete(javarettype); Delete(cleanup); Delete(outarg); Delete(body); @@ -839,103 +1047,163 @@ void JAVA::create_function(char *name, char *iname, DataType *t, ParmList *l) } // ----------------------------------------------------------------------- -// JAVA::link_variable(char *name, char *iname, DataType *t) +// JAVA::link_variable(char *name, char *iname, SwigType *t) // // Create a JAVA link to a C variable. // ----------------------------------------------------------------------- -void JAVA::link_variable(char *name, char *iname, DataType *t) +void JAVA::link_variable(char *name, char *iname, SwigType *t) { emit_set_get(name,iname, t); } // ----------------------------------------------------------------------- -// JAVA::declare_const(char *name, char *iname, DataType *type, char *value) +// JAVA::declare_const(char *name, char *iname, SwigType *type, char *value) // ------------------------------------------------------------------------ -void JAVA::declare_const(char *name, char *iname, DataType *type, char *value) { +void JAVA::declare_const(char *name, char *iname, SwigType *type, char *value) { + int OldStatus = Status; char *tm; FILE *jfile; char *jname; + Status = STAT_READONLY; + String *java_type = NewString(""); if(!classdef_emitted) emit_classdef(); - if(shadow && member_func) { + if(shadow && wrapping_member) { + if(!shadow_classdef_emitted) emit_shadow_classdef(); jfile = f_shadow; - jname = shadow_name; + jname = shadow_variable_name; } else { jfile = f_java; jname = name; } - if ((tm = typemap_lookup((char*)"const",typemap_lang,type,name,name,iname))) { - DOHString *str = NewString(tm); + if ((tm = Swig_typemap_lookup((char*)"const",type,name,name,iname,NULL))) { + String *str = NewString(tm); Replace(str,"$value",value, DOH_REPLACE_ANY); Printf(jfile," %s\n\n", str); Delete(str); } else { - if((DataType_is_pointer(type) == 0)) { - char *jtype = typemap_lookup((char*)"jtype", typemap_lang, type, name, name, iname); - if(!jtype) jtype = SwigTcToJavaType(type, 0, 0); - if(strcmp(jname, value) == 0 || strstr(value,"::") != NULL) { - Printf(stderr, "ignoring enum constant: %s\n", jname); - } else - Printf(jfile, " public final static %s %s = %s;\n\n", jtype, jname, value); - } else { - if(DataType_type(type) == T_STRING) { - Printf(jfile, " public final static String %s = \"%s\";\n\n", jname, value); - } else { - emit_set_get(name,iname, type); + SwigToJavaType(type, iname, java_type, shadow && wrapping_member); + if(strcmp(jname, value) == 0 || strstr(value,"::") != NULL) { + /* + We have found an enum. + The enum implementation is done using a public final static int + in Java. They are then initialised through a JNI call to c in a Java static block. + */ + Printf(jfile, " public final static %s %s;\n", java_type, jname, value); + + if(shadow && wrapping_member) { + Printv(shadow_enum_code, tab4, jname, " = ", module, ".", Swig_name_get(iname), "();\n", 0); + /* + The following is a work around for an apparent bug in the swig core. + When an enum is defined in a c++ class the emit_func_call() should + output ClassName::EnumName, but instead it outputs ClassName_EnumName. + */ + Printv(f_header, "#define ", iname, " ", value, "\n", 0); + } + else { + Printv(java_enum_code, tab4, jname, " = ", Swig_name_get(iname), "();\n", 0); } + enum_flag = 1; + emit_set_get(name,iname, type); + enum_flag = 0; + } else { + if(SwigType_type(type) == T_STRING) + Printf(jfile, " public final static %s %s = \"%s\";\n", java_type, jname, value); + else + Printf(jfile, " public final static %s %s = %s;\n", java_type, jname, value); } } + Delete(java_type); + Status = OldStatus; } - -void emit_shadow_banner(FILE *f) { - Printf(f, "/*\n"); - Printf(f, " *\n"); - Printf(f, " * This file was automatically generated by :\n"); - Printf(f, " * Simplified Wrapper and Interface Generator (SWIG)\n"); - Printf(f, " * Version: %s\n", SWIG_VERSION); - Printf(f, " *\n"); - Printf(f, " * Portions Copyright (c) 1995-1997\n"); - Printf(f, " * The University of Utah and The Regents of the University of California.\n"); - Printf(f, " * Permission is granted to distribute this file in any manner provided\n"); - Printf(f, " * this notice remains intact.\n"); - Printf(f, " *\n"); - Printf(f, " * Portions Copyright (c) 1997-1999\n"); - Printf(f, " * Harco de Hilster, Harco.de.Hilster@ATConsultancy.nl\n"); - Printf(f, " *\n"); - Printf(f, " * Do not make changes to this file--changes will be lost!\n"); - Printf(f, " *\n"); - Printf(f, " */\n\n\n"); -} - +/* +Valid Pragmas: +These pragmas start with 'allshadow' or 'module' + modulebase - base (extends) for the java module class + allshadowbase - base (extends) for all java shadow classes + modulecode - text (java code) is copied verbatim to the java module class + allshadowcode - text (java code) is copied verbatim to all java shadow classes + moduleclassmodifiers - class modifiers for the module class + allshadowclassmodifiers - class modifiers for all shadow classes + moduleimport - import statement generation for the java module class + allshadowimport - import statement generation for all java shadow classes + moduleinterface - interface (implements) for the module class + allshadowinterface - interface (implements) for all shadow classes + modulemethodmodifiers - replaces the generated native calls' default modifiers +*/ void JAVA::pragma(char *lang, char *code, char *value) { if(strcmp(lang, "java") != 0) return; - DOHString *s = NewString(value); - Replace(s,"\\\"", "\"", DOH_REPLACE_ANY); - if(strcmp(code, "import") == 0) { - jimport = Swig_copy_string(Char(s)); - Printf(f_java, "// pragma\nimport %s;\n\n", jimport); - } else if(strcmp(code, "module") == 0) { - if(!classdef_emitted) emit_classdef(); - Printf(f_java, "// pragma\n"); - Printf(f_java, "%s", s); - Printf(f_java, "\n\n"); - } else if(strcmp(code, "shadow") == 0) { - if(shadow && f_shadow) { - Printf(f_shadow, "// pragma\n"); - Printf(f_shadow, "%s", s); - Printf(f_shadow, "\n\n"); + String *strvalue = NewString(value); + Replace(strvalue,"\\\"", "\"", DOH_REPLACE_ANY); + + if(strcmp(code, "moduleimport") == 0) { + Printf(module_import, "import %s;\n", strvalue); + } + else if(strcmp(code, "allshadowimport") == 0) { + if(shadow && all_shadow_import) + Printf(all_shadow_import, "import %s;\n", strvalue); + } + else if(strcmp(code, "import") == 0) { + Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please replace with moduleimport, shadowimport and/or allshadowimport pragmas.\n", input_file, line_number); + } + else if(strcmp(code, "modulecode") == 0 || strcmp(code, "module") == 0) { + if(strcmp(code, "module") == 0) + Printf(stderr,"%s : Line %d. Soon to be deprecated pragma. Please replace with modulecode pragma.\n", input_file, line_number); + Printf(module_extra_code, "%s\n", strvalue); + } + else if(strcmp(code, "allshadowcode") == 0 || strcmp(code, "shadow") == 0) { + if(shadow && all_shadow_extra_code) { + if(strcmp(code, "shadow") == 0) + Printf(stderr,"%s : Line %d. Soon to be deprecated pragma. Please replace with allshadowcode pragma.\n", input_file, line_number); + Printf(all_shadow_extra_code, "%s\n", strvalue); } - } else if(strcmp(code, "modifiers") == 0) { - method_modifiers = Swig_copy_string(value); - } else { - Printf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file,line_number); + } + else if(strcmp(code, "modulebase") == 0) { + if(shadow && module_baseclass) + Printf(module_baseclass, "extends %s ", strvalue); + } + else if(strcmp(code, "allshadowbase") == 0) { + if(shadow && all_shadow_baseclass) + Printf(all_shadow_baseclass, "extends %s ", strvalue); + } + else if(strcmp(code, "moduleinterface") == 0) { + if(shadow && module_interfaces) + if (!*Char(module_interfaces)) + Printf(module_interfaces, "implements %s", strvalue); + else + Printf(module_interfaces, ", %s", strvalue); + } + else if(strcmp(code, "allshadowinterface") == 0) { + if(shadow && all_shadow_interfaces) { + if (!*Char(all_shadow_interfaces)) + Printf(all_shadow_interfaces, "implements %s", strvalue); + else + Printf(all_shadow_interfaces, ", %s", strvalue); + } + } + else if(strcmp(code, "allshadowclassmodifiers") == 0) { + if(shadow && all_shadow_class_modifiers) + Printv(all_shadow_class_modifiers, strvalue, 0); + } + else if(strcmp(code, "moduleclassmodifiers") == 0) { + if(shadow && module_class_modifiers) + Printv(module_class_modifiers, strvalue, 0); + } + else if(strcmp(code, "modulemethodmodifiers") == 0 || strcmp(code, "modifiers") == 0) { + if(strcmp(code, "modifiers") == 0) + Printf(stderr,"%s : Line %d. Soon to be deprecated pragma. Please replace with modulemethodmodifiers pragma.\n", input_file, line_number); + Clear(module_method_modifiers); + Printv(module_method_modifiers, strvalue, 0); + } + else { + Printf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file, line_number); } - Delete(s); + Delete(strvalue); } // --------------------------------------------------------------------- @@ -945,22 +1213,60 @@ void JAVA::pragma(char *lang, char *code, char *value) { // C structs. // --------------------------------------------------------------------- -void JAVA::add_typedef(DataType *t, char *name) { - if(!shadow) return; - - // First check to see if there aren't too many pointers - - if (DataType_is_pointer(t) > 1) return; - - if(Getattr(shadow_classes,name)) return; // Already added - - // Now look up the datatype in our shadow class hash table +/* +C++ pragmas: pragmas declared within a class or c struct for the shadow class. +These pragmas start with 'shadow' +Valid pragmas: + shadowbase - base (extends) for all java shadow classes + shadowcode - text (java code) is copied verbatim to the shadow class + shadowclassmodifiers - class modifiers for the shadow class + shadowimport - import statement generation for the shadow class + shadowinterface - interfaces (extends) for the shadow class +*/ +void JAVA::cpp_pragma(Pragma* plist) { + while (plist) { + if ( (strcmp(Char(plist->lang),(char*)"java") == 0) && shadow) { + String* strvalue = NewString(plist->value); + Replace(strvalue,"\\\"", "\"", DOH_REPLACE_ANY); + + if (strcmp(Char(plist->name),"shadowcode") == 0) { + if (this_shadow_extra_code) + Printf(this_shadow_extra_code, "%s\n", strvalue); + } + else if (strcmp(Char(plist->name),"shadowimport") == 0) { + if (this_shadow_import) + Printf(this_shadow_import, "import %s;\n", strvalue); + } + else if (strcmp(Char(plist->name),"shadowbase") == 0) { + if (this_shadow_baseclass) + Printf(this_shadow_baseclass, "extends %s ", strvalue); + } + else if (strcmp(Char(plist->name),"shadowinterface") == 0) { + if (this_shadow_interfaces) { + if (!*Char(this_shadow_interfaces)) + Printf(this_shadow_interfaces, "implements %s", strvalue); + else + Printf(this_shadow_interfaces, ", %s", strvalue); + } + } + else if (strcmp(Char(plist->name),"shadowclassmodifiers") == 0) { + if (this_shadow_class_modifiers) + Printv(this_shadow_class_modifiers, strvalue, 0); + } + else { + Printf(stderr,"%s : Line %d. Unrecognized pragma for shadow class.\n", plist->filename, plist->lineno); + } - if (Getattr(shadow_classes,DataType_Getname(t))) { + Delete(strvalue); + } + plist = plist->next; + } +} - // Yep. This datatype is in the hash - // Put this types 'new' name into the hash - Setattr(shadow_classes,name,GetChar(shadow_classes,DataType_Getname(t))); +void JAVA::add_typedef(SwigType *t, char *name) { + if(!shadow) return; + if (is_shadow(t)) { + cpp_class_decl(name,Char(is_shadow(t)), (char*) ""); } } @@ -990,44 +1296,86 @@ void JAVA::cpp_open_class(char *classname, char *rename, char *ctype, int strip) Printf(stderr, "Unable to create shadow class file: %s\n", bigbuf); } - emit_shadow_banner(f_shadow); + emit_banner(f_shadow); if(*package) - Printf(f_shadow, "package %s;\n\n", package); - else Printf(f_shadow, "import %s;\n\n", module); - if(jimport != NULL) - Printf(f_shadow, "import %s;\n\n", jimport); + Printf(f_shadow, "package %s;\n\n", package); + else + Printf(f_shadow, "import %s;\n", module); + if(all_shadow_import) + Printf(f_shadow, "%s", all_shadow_import); Clear(shadow_classdef); - Printv(shadow_classdef, "public class ", shadow_classname, " %BASECLASS% ", "{\n", 0); + Printv(shadow_classdef, "$classmodifiers class ", shadow_classname, " $bases", "{\n", 0); - shadow_baseclass = (char*) ""; shadow_classdef_emitted = 0; have_default_constructor = 0; + shadow_enum_code = NewString(""); + this_shadow_baseclass = NewString(""); + this_shadow_extra_code = NewString(""); + this_shadow_interfaces = NewString(""); + this_shadow_import = NewString(""); + this_shadow_class_modifiers = NewString(""); + + if(all_shadow_interfaces) + Printv(this_shadow_interfaces, all_shadow_interfaces, 0); } void JAVA::emit_shadow_classdef() { - if(*shadow_baseclass) { - sprintf(bigbuf, "extends %s", shadow_baseclass); - Replace(shadow_classdef,"%BASECLASS%", bigbuf, DOH_REPLACE_ANY); - Printv(shadow_classdef, " public ", shadow_classname, "(java.lang.Long obj) {\n", tab4, "_self = obj.longValue();\n }\n\n", 0); - } else { - Replace(shadow_classdef,"%BASECLASS%", "",DOH_REPLACE_ANY); - - Printv(shadow_classdef, - " public long _self = 0;\n", - " public boolean _selfown = false;\n\n", - " public static Object newInstance(long p) {\n", - " return new ", shadow_classname, "(new Long(p));\n", - " };\n\n", - - " public ", shadow_classname, "(java.lang.Long obj) {\n", tab4, "_self = obj.longValue();\n }\n\n", - 0); + String* temp_str = NewString(""); + if(this_shadow_baseclass) + Printv(temp_str, this_shadow_baseclass, 0); + if(all_shadow_baseclass) + Printv(temp_str, all_shadow_baseclass, 0); + if(this_shadow_interfaces && *Char(this_shadow_interfaces)) + Printv(temp_str, this_shadow_interfaces, " ", 0); + Replace(shadow_classdef,"$bases", temp_str, DOH_REPLACE_ANY); + + //Display warning on attempt to use multiple inheritance + char* search_str = Char(temp_str); + int count = 0; + while(search_str = strstr(search_str, "extends")) { + search_str += strlen("extends"); + count++; } - Printv(shadow_classdef, " public Class _selfClass() {\n", tab4, "return ", shadow_classname, ".class;\n", " };\n\n", 0); + if (count > 1) + Printf(stderr, "Warning for shadow class %s: Multiple inheritance is not supported in Java.\n", shadow_classname); + + if (this_shadow_class_modifiers && *Char(this_shadow_class_modifiers)) + Replace(shadow_classdef, "$classmodifiers", this_shadow_class_modifiers, DOH_REPLACE_ANY); + else if (all_shadow_class_modifiers && *Char(all_shadow_class_modifiers)) + Replace(shadow_classdef, "$classmodifiers", all_shadow_class_modifiers, DOH_REPLACE_ANY); + else + Replace(shadow_classdef, "$classmodifiers", "public", DOH_REPLACE_ANY); + + Printv(shadow_classdef, + " private long _cPtr = 0;\n", + " private boolean _cMemOwn = false;\n", + "\n", + " public $class(long cPointer, boolean cMemoryOwn) {\n", + " _cPtr = cPointer;\n", + " _cMemOwn = cMemoryOwn;\n", + " }\n", + "\n", + " public long getCPtr() {\n", + " return _cPtr;\n", + " };\n", + "\n", 0); + Replace(shadow_classdef, "$class", shadow_classname, DOH_REPLACE_ANY); + + if (all_shadow_extra_code) + Printv(shadow_classdef, all_shadow_extra_code, 0); + + if (this_shadow_extra_code) + Printv(shadow_classdef, this_shadow_extra_code, 0); + + if(this_shadow_import) + Printf(f_shadow, "%s", this_shadow_import); + Printf(f_shadow, "\n"); Printv(f_shadow, shadow_classdef,0); shadow_classdef_emitted = 1; + Delete(temp_str); } void JAVA::cpp_close_class() { @@ -1036,270 +1384,305 @@ void JAVA::cpp_close_class() { if(!shadow_classdef_emitted) emit_shadow_classdef(); + // No default constructor implies class is abstract. + // Note that abstract in cplus.cxx has this information - it ought to be passed to each + // module when the class is opened. if(have_default_constructor == 0) { - Printf(f_shadow, " public %s() {}\n\n", shadow_classname); + Printf(f_shadow, " protected %s() {}\n\n", shadow_classname); } + // Write the enum initialisation code in a static block. + // These are all the enums defined within the c++ class. + if (strlen(Char(shadow_enum_code)) != 0 ) + Printv(f_shadow, " static {\n // Initialise java constants from c++ enums\n", shadow_enum_code, " }\n",0); + Printf(f_shadow, "}\n"); fclose(f_shadow); f_shadow = NULL; free(shadow_classname); shadow_classname = NULL; -} -void JAVA::cpp_member_func(char *name, char *iname, DataType *t, ParmList *l) { - char arg[256]; - DOHString *nativecall; - - nativecall = NewString(""); + Delete(shadow_enum_code); shadow_enum_code = NULL; + Delete(this_shadow_baseclass); this_shadow_baseclass = NULL; + Delete(this_shadow_extra_code); this_shadow_extra_code = NULL; + Delete(this_shadow_interfaces); this_shadow_interfaces = NULL; + Delete(this_shadow_import); this_shadow_import = NULL; + Delete(this_shadow_class_modifiers); this_shadow_class_modifiers = NULL; +} +void JAVA::cpp_member_func(char *name, char *iname, SwigType *t, ParmList *l) { this->Language::cpp_member_func(name,iname,t,l); - if(!shadow) return; - if(!shadow_classdef_emitted) emit_shadow_classdef(); - - char *javarettype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, t, iname); - if(!javarettype) javarettype = SwigTcToJavaType(t, 1, 0); - char *shadowrettype = JavaTypeFromTypemap((char*)"jstype", typemap_lang, t, iname); - if(!shadowrettype && (DataType_Gettypecode(t) == T_USER) && DataType_is_pointer(t) <= 1) { - shadowrettype = GetChar(shadow_classes,DataType_Getname(t)); +/* +// TODO: modify output so that pure virtual functions are declared abstract and +// have no body. Also make the class declaration abstract. Make other constructor protected. +extern int IsVirtual; + printf("IsVirtual: %d [%s] %s\n", IsVirtual, name, shadow_classname); + if (IsVirtual == PURE_VIRTUAL) { } +*/ + if (shadow && !is_multiple_definition()) { + char* realname = iname ? iname : name; + String* java_function_name = Swig_name_member(shadow_classname, realname); - Printf(f_shadow, " public %s %s(", (shadowrettype) ? shadowrettype : javarettype, iname); - - if(DataType_type(t) != T_VOID) { - Printf(nativecall,"return "); - if(shadowrettype) { - Printv(nativecall, "new ", shadowrettype, "(new Long(", 0); - } + cpp_func(iname, t, l, java_function_name); } - Printv(nativecall, module, ".", Swig_name_member(shadow_classname,iname), "(_self", 0); - - int pcount = ParmList_len(l); - - Parm *p = l; - for (int i = 0; i < pcount ; i++, p = Getnext(p)) { - DataType *pt = Gettype(p); - char *pn = Getname(p); - - // Produce string representation of source and target arguments - if(pn && *(pn)) - strcpy(arg,pn); - else { - sprintf(arg,"arg%d",i); - } - - if((DataType_Gettypecode(pt) == T_USER) && (DataType_is_pointer(pt) <= 1) && Getattr(shadow_classes,DataType_Getname(pt))) { - Printv(nativecall, ", ", arg, "._self", 0); - } else Printv(nativecall, ", ", arg, 0); +} - char *jtype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, pt, pn); - if(!jtype) jtype = SwigTcToJavaType(pt, 0, 0); +void JAVA::cpp_static_func(char *name, char *iname, SwigType *t, ParmList *l) { + this->Language::cpp_static_func(name,iname,t,l); - char *jstype = JavaTypeFromTypemap((char*)"jstype", typemap_lang, pt, pn); - if(!jstype && (DataType_Gettypecode(pt) == T_USER) && (DataType_is_pointer(pt) <= 1)) { - jstype = GetChar(shadow_classes,DataType_Getname(pt)); - } + if (shadow && !is_multiple_definition()) { + char* realname = iname ? iname : name; + String* java_function_name = Swig_name_member(shadow_classname, realname); - // Add to java function header - Printf(f_shadow, "%s %s", (jstype) ? jstype : jtype, arg); - if(i != pcount-1) { - Printf(f_shadow, ", "); - } + static_flag = 1; + cpp_func(iname, t, l, java_function_name); + static_flag = 0; } - - if((DataType_Gettypecode(t) != T_VOID) && shadowrettype) - Printf(nativecall, "))"); - - Printf(nativecall,");\n"); - - Printf(f_shadow, ") {\n"); - Printf(f_shadow, "\t%s\n", nativecall); - Printf(f_shadow, " }\n\n"); - Delete(nativecall); - } -void JAVA::cpp_static_func(char *name, char *iname, DataType *t, ParmList *l) { - char arg[256]; - DOHString *nativecall; - - this->Language::cpp_static_func(name,iname,t,l); +/* +Function called for creating a java class wrapper function around a c++ function in the +java wrapper class. Used for both static and non static functions. +C++ static functions map to java static functions. +iname is the name of the java class wrapper function, which in turn will call +java_function_name, the java function which wraps the c++ function. +*/ +void JAVA::cpp_func(char *iname, SwigType *t, ParmList *l, String* java_function_name) { + char arg[256]; + String *nativecall = NewString(""); + String *shadowrettype = NewString(""); + String *user_arrays = NewString(""); if(!shadow) return; - nativecall = NewString(""); if(!shadow_classdef_emitted) emit_shadow_classdef(); - char *javarettype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, t, iname); - if(!javarettype) javarettype = SwigTcToJavaType(t, 1, 0); - char *shadowrettype = JavaTypeFromTypemap((char*)"jstype", typemap_lang, t, iname); - if(!shadowrettype && (DataType_Gettypecode(t) == T_USER) && (DataType_is_pointer(t) <= 1)) { - shadowrettype = GetChar(shadow_classes,DataType_Getname(t)); - } + /* Get the java return type */ + SwigToJavaType(t, iname, shadowrettype, shadow); - Printf(f_shadow, " public static %s %s(", (shadowrettype) ? shadowrettype : javarettype, iname); + Printf(f_shadow, " public %s %s %s(", (static_flag ? "static":""), shadowrettype, iname); - if(DataType_type(t) != T_VOID) { - Printf(nativecall, "return "); - if(shadowrettype) { - Printv(nativecall, "new ", shadowrettype, "(new Long(", 0); + if(SwigType_type(t) == T_ARRAY && is_shadow(get_array_type(t))) { + Printf(nativecall, "long[] cArray = "); + } + else { + if(SwigType_type(t) != T_VOID) { + Printf(nativecall,"return "); + } + if(is_shadow(t)) { + Printv(nativecall, "new ", shadowrettype, "(", 0); } } - Printv(nativecall, module, ".", Swig_name_member(shadow_classname,iname), "(", 0); + Printv(nativecall, module, ".", java_function_name, "(", 0); + if (!static_flag) + Printv(nativecall, "getCPtr()", 0); + + int gencomma = !static_flag; int pcount = ParmList_len(l); - int gencomma = 0; + /* Output each parameter */ Parm *p = l; - for (int i = 0; i < pcount ; i++, p = Getnext(p)) { - DataType *pt = Gettype(p); - char *pn = Getname(p); - - // Produce string representation of source and target arguments - if(pn && *(pn)) - strcpy(arg,pn); - else { - sprintf(arg,"arg%d",i); - } - - if(gencomma) Printf(nativecall,", "); - if((DataType_Gettypecode(pt) == T_USER) && (DataType_is_pointer(pt) <= 1) && Getattr(shadow_classes,DataType_Getname(pt))) { - Printv(nativecall, arg, "._self", 0); - } else Printv(nativecall,arg,0); +/* Workaround to overcome Getignore(p) not working - p does not always have the Getignore +attribute set. Noticeable when cpp_func is called from cpp_member_func() */ +Wrapper* f = NewWrapper(); +emit_args(NULL, l, f); +DelWrapper(f); +/* Workaround end */ - gencomma = 1; + for (int i = 0; i < pcount ; i++, p = Getnext(p)) { + if(Getignore(p)) continue; - char *jtype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, pt, pn); - if(!jtype) jtype = SwigTcToJavaType(pt, 0, 0); + /* Ignore the 'this' argument for variable wrappers */ + if (!(variable_wrapper_flag && i==0)) + { + SwigType *pt = Gettype(p); + String *pn = Getname(p); + String *javaparamtype = NewString(""); + + /* Produce string representation of source and target arguments */ + if(pn && *(Char(pn))) + strcpy(arg,Char(pn)); + else { + sprintf(arg,"arg%d",i); + } + + if (gencomma) + Printf(nativecall, ", "); + + if(SwigType_type(pt) == T_ARRAY && is_shadow(get_array_type(pt))) { + Printv(user_arrays, tab4, "long[] $arg_cArray = new long[$arg.length];\n", 0); + Printv(user_arrays, tab4, "for (int i=0; i<$arg.length; i++)\n", 0); + Printv(user_arrays, tab4, " $arg_cArray[i] = $arg[i].getCPtr();\n", 0); + Replace(user_arrays, "$arg", pn, DOH_REPLACE_ANY); + + Printv(nativecall, arg, "_cArray", 0); + } else if (is_shadow(pt)) { + Printv(nativecall, arg, ".getCPtr()", 0); + } else Printv(nativecall, arg, 0); + + /* Get the java type of the parameter */ + SwigToJavaType(pt, pn, javaparamtype, shadow); + + /* Add to java shadow function header */ + if (gencomma >= 2) + Printf(f_shadow, ", "); + gencomma = 2; + Printf(f_shadow, "%s %s", javaparamtype, arg); - char *jstype = JavaTypeFromTypemap((char*)"jstype", typemap_lang, pt, pn); - if(!jstype && (DataType_Gettypecode(pt) == T_USER) && (DataType_is_pointer(pt) <= 1)) { - jstype = GetChar(shadow_classes, DataType_Getname(pt)); + Delete(javaparamtype); } + } - // Add to java function header - Printf(f_shadow, "%s %s", (jstype) ? jstype : jtype, arg); - if(i != pcount-1) { - Printf(f_shadow, ", "); + if(SwigType_type(t) == T_ARRAY && is_shadow(get_array_type(t))) { + String* array_ret = NewString(""); + String* user_return_type = NewString(""); + SwigType *array_type = get_array_type(t); + Printf(array_ret,");\n"); + Printv(array_ret, tab4, "$type[] arrayWrapper = new $type[cArray.length];\n", 0); + Printv(array_ret, tab4, "for (int i=0; i<cArray.length; i++)\n", 0); + Printv(array_ret, tab4, " arrayWrapper[i] = new $type(cArray[i], false);\n", 0); + Printv(array_ret, tab4, "return arrayWrapper;\n", 0); + + SwigToJavaType(array_type, iname, user_return_type, shadow); + Replace(array_ret, "$type", user_return_type, DOH_REPLACE_ANY); + Printv(nativecall, array_ret, 0); + Delete(array_ret); + Delete(user_return_type); + } + else { + if(is_shadow(t)) { + switch(SwigType_type(t)) { + case T_USER: + Printf(nativecall, "), true"); + break; + case T_REFERENCE: + case T_POINTER: + Printf(nativecall, "), false"); + break; + default: + Printf(stderr, "Internal Error: unknown shadow type: %s\n", SwigType_str(t,0)); + break; + } } + Printf(nativecall,");\n"); } - - if((DataType_type(t) != T_VOID) && shadowrettype) - Printf(nativecall,"))"); - - Printf(nativecall,");\n"); - Printf(f_shadow, ") {\n"); - Printf(f_shadow, "\t%s\n", nativecall); + Printv(f_shadow, user_arrays, 0); + Printf(f_shadow, "\t%s", nativecall); Printf(f_shadow, " }\n\n"); + Delete(shadowrettype); Delete(nativecall); + Delete(user_arrays); } void JAVA::cpp_constructor(char *name, char *iname, ParmList *l) { this->Language::cpp_constructor(name,iname,l); - if(!shadow) return; - if(!shadow_classdef_emitted) emit_shadow_classdef(); - - DOHString *nativecall = NewString(""); - char arg[256]; - - Printf(f_shadow, " public %s(", shadow_classname); - - Printv(nativecall, " if(_self == 0 && ", shadow_classname, ".class == _selfClass()) {\n", 0); - if (iname != NULL) - Printv(nativecall, tab8, " _self = ", module, ".", Swig_name_construct(iname), "(", 0); - else - Printv(nativecall, tab8, " _self = ", module, ".", Swig_name_construct(shadow_classname), "(", 0); - - int pcount = ParmList_len(l); - if(pcount == 0) // We must have a default constructor - have_default_constructor = 1; - - Parm *p = l; - for (int i = 0; i < pcount ; i++, p = Getnext(p)) { - DataType *pt = Gettype(p); - char *pn = Getname(p); - - // Produce string representation of source and target arguments - if(pn && *(pn)) - strcpy(arg,pn); - else { - sprintf(arg,"arg%d",i); - } - - char *jtype = JavaTypeFromTypemap((char*)"jtype", typemap_lang, pt, pn); - if(!jtype) jtype = SwigTcToJavaType(pt, 0, 0); - - char *jstype = JavaTypeFromTypemap((char*)"jstype", typemap_lang, pt, pn); - if(!jstype && (DataType_Gettypecode(pt) == T_USER) && (DataType_is_pointer(pt) <= 1)) { - jstype = GetChar(shadow_classes, DataType_Getname(pt)); - } - - // Add to java function header - Printf(f_shadow, "%s %s", (jstype) ? jstype : jtype, arg); - - if((DataType_Gettypecode(pt) == T_USER) && (DataType_is_pointer(pt) <= 1) && Getattr(shadow_classes,DataType_Getname(pt))) { - Printv(nativecall,arg, "._self", 0); - } else Printv(nativecall, arg, 0); - - if(i != pcount-1) { - Printf(nativecall, ", "); - Printf(f_shadow, ", "); + if(shadow && !is_multiple_definition()) { + if(!shadow_classdef_emitted) emit_shadow_classdef(); + + String *nativecall = NewString(""); + char arg[256]; + + Printf(f_shadow, " public %s(", shadow_classname); + + Printv(nativecall, " if(getCPtr() == 0) {\n", 0); + if (iname != NULL) + Printv(nativecall, tab8, " _cPtr = ", module, ".", Swig_name_construct(iname), "(", 0); + else + Printv(nativecall, tab8, " _cPtr = ", module, ".", Swig_name_construct(shadow_classname), "(", 0); + + int pcount = ParmList_len(l); + if(pcount == 0) // We must have a default constructor + have_default_constructor = 1; + + /* Output each parameter */ + Parm *p = l; + for (int i = 0; i < pcount ; i++, p = Getnext(p)) { + SwigType *pt = Gettype(p); + String *pn = Getname(p); + String *javaparamtype = NewString(""); + + /* Produce string representation of source and target arguments */ + if(pn && *(Char(pn))) + strcpy(arg,Char(pn)); + else { + sprintf(arg,"arg%d",i); + } + + if(is_shadow(pt)) { + Printv(nativecall, arg, ".getCPtr()", 0); + } else Printv(nativecall, arg, 0); + + /* Get the java type of the parameter */ + SwigToJavaType(pt, pn, javaparamtype, shadow); + + /* Add to java shadow function header */ + Printf(f_shadow, "%s %s", javaparamtype, arg); + + if(i != pcount-1) { + Printf(nativecall, ", "); + Printf(f_shadow, ", "); + } + Delete(javaparamtype); } + + + Printf(f_shadow, ") {\n"); + Printv(nativecall, + ");\n", + tab8, " _cMemOwn = true;\n", + " }\n", + 0); + + Printf(f_shadow, "%s", nativecall); + Printf(f_shadow, " }\n\n"); + Delete(nativecall); } - - - Printf(f_shadow, ") {\n"); - Printv(nativecall, - ");\n", - tab8, " _selfown = true;\n", - " }\n", - 0); - - Printf(f_shadow, "%s", nativecall); - Printf(f_shadow, " }\n\n"); - Delete(nativecall); } void JAVA::cpp_destructor(char *name, char *newname) { this->Language::cpp_destructor(name,newname); - if(!shadow) return; - if(!shadow_classdef_emitted) emit_shadow_classdef(); - - char *realname = (newname) ? newname : name; - - if(finalize) { - Printf(f_shadow, " protected void finalize() {\n"); - Printf(f_shadow, " if(_selfown) {\n"); - Printf(f_shadow, " _delete();\n"); + if(shadow && !is_multiple_definition()) { + if(!shadow_classdef_emitted) emit_shadow_classdef(); + + char *realname = (newname) ? newname : name; + + if(!nofinalize) { + Printf(f_shadow, " protected void finalize() {\n"); + Printf(f_shadow, " _delete();\n"); + Printf(f_shadow, " };\n\n"); + } + + Printf(f_shadow, " public void _delete() {\n"); + Printf(f_shadow, " if(getCPtr() != 0 && _cMemOwn) {\n"); + Printf(f_shadow, "\t%s.%s(_cPtr);\n", module, Swig_name_destroy(shadow_classname)); + Printf(f_shadow, "\t_cPtr = 0;\n"); Printf(f_shadow, " }\n"); - Printf(f_shadow, " };\n\n"); + Printf(f_shadow, " }\n\n"); } - - Printf(f_shadow, " public void _delete() {\n"); - Printf(f_shadow, " if(_self != 0 && %s.class == _selfClass()) {\n", shadow_classname); - Printf(f_shadow, "\t%s.%s(_self);\n", module, Swig_name_destroy(realname)); - Printf(f_shadow, "\t_self = 0;\n"); - Printf(f_shadow, " }\n"); - Printf(f_shadow, " }\n\n"); } void JAVA::cpp_class_decl(char *name, char *rename, char *type) { - this->Language::cpp_class_decl(name,rename, type); - - if(!shadow) return; - - char *realname = (rename) ? rename : name; - - Setattr(shadow_classes,name, realname); - if(type && strcmp(type, "struct") == 0) { - sprintf(bigbuf, "struct %s", name); - Setattr(shadow_classes, bigbuf, rename); + String *stype; +/* Register the class as one for which there will be a java shadow class */ + if (shadow) { + stype = NewString(name); + SwigType_add_pointer(stype); + Setattr(shadow_classes,stype,rename); + Delete(stype); + if (strlen(type) > 0) { + stype = NewStringf("%s %s",type,name); + SwigType_add_pointer(stype); + Setattr(shadow_classes,stype,rename); + Delete(stype); + } } } @@ -1308,39 +1691,55 @@ void JAVA::cpp_inherit(char **baseclass, int) { if(!shadow) return; - int cnt = 0; - char **bc = baseclass; - while(*bc++) cnt++; + int i = 0; + while(baseclass[i]) i++; - if(cnt > 1) + if(i > 1) Printf(stderr, "Warning: %s inherits from multiple base classes. Multiple inheritance is not supported.\n", shadow_classname); - shadow_baseclass = Swig_copy_string(*baseclass); + i=0; + char *bc; + if (baseclass[i]) { + /* See if this is a class we know about */ + String *b = NewString(baseclass[i]); + bc = Char(is_shadow(b)); + if (bc && this_shadow_baseclass) + Printf(this_shadow_baseclass, "extends %s ", bc); + Delete(b); + } } -void JAVA::cpp_variable(char *name, char *iname, DataType *t) { - if(shadow && !shadow_classdef_emitted) emit_shadow_classdef(); +void JAVA::cpp_variable(char *name, char *iname, SwigType *t) { + shadow_variable_name = Swig_copy_string((iname) ? iname : name); - if(shadow) member_func = 1; - shadow_name = Swig_copy_string((iname) ? iname : name); + wrapping_member = 1; + variable_wrapper_flag = 1; this->Language::cpp_variable(name, iname, t); - member_func = 0; + wrapping_member = 0; + variable_wrapper_flag = 0; } -void JAVA::cpp_static_var(char *name, char *iname, DataType *t) { - if(shadow) member_func = 1; - shadow_name = Swig_copy_string((iname) ? iname : name); +void JAVA::cpp_static_var(char *name, char *iname, SwigType *t) { + shadow_variable_name = Swig_copy_string((iname) ? iname : name); + +/* + wrapping_member = 1; + static_flag = 1; + variable_wrapper_flag = 1; this->Language::cpp_static_var(name, iname, t); - member_func = 0; + wrapping_member = 0; + static_flag = 0; + variable_wrapper_flag = 0; +*/ + Printf(stderr, "Ignoring %s::%s. Static member variables are broken in SWIG!\n", shadow_classname, shadow_variable_name); } -void JAVA::cpp_declare_const(char *name, char *iname, DataType *type, char *value) { - if(shadow && !shadow_classdef_emitted) emit_shadow_classdef(); +void JAVA::cpp_declare_const(char *name, char *iname, SwigType *type, char *value) { + shadow_variable_name = Swig_copy_string((iname) ? iname : name); - if(shadow) member_func = 1; - shadow_name = Swig_copy_string((iname) ? iname : name); + wrapping_member = 1; this->Language::cpp_declare_const(name, iname, type, value); - member_func = 0; + wrapping_member = 0; } diff --git a/SWIG/Source/Modules1.1/java.h b/SWIG/Source/Modules1.1/java.h index 6c86b452e..d5b1edb10 100644 --- a/SWIG/Source/Modules1.1/java.h +++ b/SWIG/Source/Modules1.1/java.h @@ -18,11 +18,12 @@ public : void initialize(void); void headers(void); void close(void); - void set_module(char *,char **); + void set_module(char *); void create_command(char *, char *); void pragma(char *lang, char *code, char *value); void add_typedef(SwigType *t, char *name); + void cpp_pragma(Pragma *plist); void cpp_open_class(char *classname, char *rename, char *ctype, int strip); void cpp_close_class(); void cpp_member_func(char *name, char *iname, SwigType *t, ParmList *l); @@ -39,11 +40,12 @@ public : void emit_classdef(); void emit_shadow_classdef(); char *JNICALL(DOHString_or_char *func); - char *SwigTcToJniType(SwigType *t, int ret); - char *SwigTcToJavaType(SwigType *t, int ret, int inShadow); - char *SwigTcToJniScalarType(SwigType *t); - char *JavaTypeFromTypemap(char *op, char *lang, SwigType *t, char *pname); + void SwigToJNIType(SwigType *t, String_or_char *pname, String* jni_type); + void SwigToJavaType(SwigType *t, String_or_char *pname, String* java_type, int shadow_flag); + char *SwigToJavaArrayType(SwigType *t); + char *JavaTypeFromTypemap(char *op, SwigType *t, String_or_char *pname); char *makeValidJniName(char *name); char *JavaMethodSignature(SwigType *t, int ret, int inShadow); void writeRegisterNatives(); + void cpp_func(char *iname, SwigType *t, ParmList *l, String* java_function_name); }; diff --git a/SWIG/Source/Modules1.1/mzscheme.cxx b/SWIG/Source/Modules1.1/mzscheme.cxx index 7414ba859..eb3cc258f 100644 --- a/SWIG/Source/Modules1.1/mzscheme.cxx +++ b/SWIG/Source/Modules1.1/mzscheme.cxx @@ -101,6 +101,9 @@ MZSCHEME::parse_args (int argc, char *argv[]) // Set name of typemaps typemap_lang = (char*)"mzscheme"; + + // Read in default typemaps */ + SWIG_config_file("mzscheme.i"); } // -------------------------------------------------------------------- @@ -113,9 +116,6 @@ void MZSCHEME::parse () { init_func_def = NewString(""); - printf ("Generating wrappers for Mzscheme\n"); - - init_func_def = NewString(""); // Print out MZSCHEME specific headers @@ -172,21 +172,11 @@ MZSCHEME::set_init (char *iname) void MZSCHEME::headers (void) { - Swig_banner (f_header); - - Printf (f_header, "/* Implementation : MZSCHEME */\n\n"); - Printf (f_header, "#include <stdio.h>\n"); - Printf (f_header, "#include <string.h>\n"); - Printf (f_header, "#include <stdlib.h>\n"); + Printf(f_runtime, "/* -*- buffer-read-only: t -*- vi: set ro: */\n"); + Swig_banner (f_runtime); - // insert mzscheme.swg - - if (!NoInclude) { - if (Swig_insert_file ("mzscheme.swg", f_header) == -1) { - Printf (stderr, "SWIG : Fatal error. "); - Printf (stderr, "Unable to locate 'mzscheme.swg' in SWIG library.\n"); - SWIG_exit (1); - } + if (NoInclude) { + Printf(f_runtime, "#define SWIG_NOINCLUDE\n"); } } @@ -257,13 +247,34 @@ mreplace (String *s, String *argnum, String *arg, String *proc_name) static void throw_unhandled_mzscheme_type_error (SwigType *d) { - fflush (stdout); - fprintf (stderr, "ERROR: Unhandled MZSCHEME type error.\n"); - fprintf (stderr, "str: %s\n", Char(SwigType_str(d,0))); - fprintf (stderr, "lstr: %s\n", Char(SwigType_lstr(d,0))); - fprintf (stderr, "manglestr: %s\n", Char(SwigType_manglestr(d))); - Printf (stderr, "\n\nBAILING...\n"); // for now -ttn - abort(); // for now -ttn + Printf (stderr, "%s : Line %d. Unable to handle type %s.\n", input_file, line_number, SwigType_str(d,0)); + error_count++; +} + +/* Return true iff T is a pointer type */ + +static int +is_a_pointer (SwigType *t) +{ + return SwigType_ispointer(SwigType_typedef_resolve_all(t)); +} + +/* Same as Swig_typemap_lookup but fall back to `int' when `enum' is + requested -- enum handling is somewhat broken in the 1.1 parser. + But we don't want to change it now since it is deprecated. */ + +static char * +mzscheme_typemap_lookup(const char *op, SwigType *type, const String_or_char *pname, String_or_char *source, + String_or_char *target, Wrapper *f) +{ + char *tm; + tm = Swig_typemap_lookup((char*) op, type, (char*)pname, source, target, f); + if (!tm) { + SwigType *base = SwigType_typedef_resolve_all(type); + if (strncmp(Char(base), "enum ", 5)==0) + tm = Swig_typemap_lookup((char*) op, (char*) "int", (char*)pname, source, target, f); + } + return tm; } void @@ -281,9 +292,6 @@ MZSCHEME::create_function (char *name, char *iname, SwigType *d, ParmList *l) String *build = NewString(""); SwigType *t; char *tm; - int need_len = 0; - int need_tempc = 0; - int have_build = 0; int argout_set = 0; int i = 0; @@ -304,9 +312,8 @@ MZSCHEME::create_function (char *name, char *iname, SwigType *d, ParmList *l) // they are called arg0, arg1, ... // the return value is called result - int pcount = emit_args(d, l, f); + /* pcount = */ emit_args(d, l, f); int numargs = 0; - int numopt = 0; // adds local variables Wrapper_add_local(f, "_tempc", "char *_tempc"); @@ -332,7 +339,7 @@ MZSCHEME::create_function (char *name, char *iname, SwigType *d, ParmList *l) Printv(f->code, "/* ", Char(Getname(p)), " ignored... */\n", 0); else { ++numargs; - if ((tm = Swig_typemap_lookup ((char*)"in", + if ((tm = mzscheme_typemap_lookup ("in", Gettype(p), Getname(p), source, target, f))) { Printv(f->code, tm, "\n", 0); mreplace (f->code, argnum, arg, proc_name); @@ -343,7 +350,7 @@ MZSCHEME::create_function (char *name, char *iname, SwigType *d, ParmList *l) t = SwigType_typedef_resolve(Gettype(p)); // if a pointer then get it - if (SwigType_ispointer(t)) { + if (is_a_pointer(t)) { get_pointer (proc_name, i, t, f); } // not a pointer @@ -353,7 +360,7 @@ MZSCHEME::create_function (char *name, char *iname, SwigType *d, ParmList *l) // Check if there are any constraints. - if ((tm = Swig_typemap_lookup ((char*)"check", + if ((tm = mzscheme_typemap_lookup ("check", Gettype(p), Getname(p), source, target, f))) { // Yep. Use it instead of the default Printv(f->code, tm, "\n", 0); @@ -362,7 +369,7 @@ MZSCHEME::create_function (char *name, char *iname, SwigType *d, ParmList *l) // Pass output arguments back to the caller. - if ((tm = Swig_typemap_lookup ((char*)"argout", + if ((tm = mzscheme_typemap_lookup ("argout", Gettype(p), Getname(p), source, target, f))) { // Yep. Use it instead of the default Printv(outarg, tm, "\n",0); @@ -371,7 +378,7 @@ MZSCHEME::create_function (char *name, char *iname, SwigType *d, ParmList *l) } // Free up any memory allocated for the arguments. - if ((tm = Swig_typemap_lookup ((char*)"freearg", + if ((tm = mzscheme_typemap_lookup ("freearg", Gettype(p), Getname(p), source, target, f))) { // Yep. Use it instead of the default Printv(cleanup, tm, "\n",0); @@ -391,14 +398,14 @@ MZSCHEME::create_function (char *name, char *iname, SwigType *d, ParmList *l) Printv(f->code, tab4, "swig_result = scheme_void;\n",0); } - else if ((tm = Swig_typemap_lookup ((char*)"out", + else if ((tm = mzscheme_typemap_lookup ("out", d, name, (char*)"result", (char*)"swig_result", f))) { Printv(f->code, tm, "\n",0); mreplace (f->code, argnum, arg, proc_name); } // no typemap found and not void then create a Scheme_Object holding // the C pointer and return it - else if (SwigType_ispointer(d)) { + else if (is_a_pointer(d)) { Printv(f->code, tab4, "swig_result = swig_make_c_pointer(", "result, \"", @@ -418,7 +425,7 @@ MZSCHEME::create_function (char *name, char *iname, SwigType *d, ParmList *l) // Look for any remaining cleanup if (NewObject) { - if ((tm = Swig_typemap_lookup ((char*)"newfree", + if ((tm = mzscheme_typemap_lookup ("newfree", d, iname, (char*)"result", (char*)"", f))) { Printv(f->code, tm, "\n",0); mreplace (f->code, argnum, arg, proc_name); @@ -427,7 +434,7 @@ MZSCHEME::create_function (char *name, char *iname, SwigType *d, ParmList *l) // Free any memory allocated by the function being wrapped.. - if ((tm = Swig_typemap_lookup ((char*)"ret", + if ((tm = mzscheme_typemap_lookup ("ret", d, name, (char*)"result", (char*)"", f))) { // Yep. Use it instead of the default Printv(f->code, tm, "\n",0); @@ -504,11 +511,11 @@ MZSCHEME::link_variable (char *name, char *iname, SwigType *t) Printv(proc_name, iname,0); Replace(proc_name, "_", "-", DOH_REPLACE_ANY); - if ((SwigType_type(t) != T_USER) || (SwigType_ispointer(t))) { + if ((SwigType_type(t) != T_USER) || (is_a_pointer(t))) { Printf (f_wrappers, "static Scheme_Object *%s(int argc, Scheme_Object** argv) {\n", var_name); - if ((SwigType_type(t) == T_CHAR) || (SwigType_ispointer(t))){ + if ((SwigType_type(t) == T_CHAR) || (is_a_pointer(t))){ Printf (f_wrappers, "\t char *_temp, _ptemp[128];\n"); Printf (f_wrappers, "\t int _len;\n"); } @@ -528,14 +535,14 @@ MZSCHEME::link_variable (char *name, char *iname, SwigType *t) Printf (f_wrappers, "\t\t scheme_signal_error(\"Unable to set %s. " "Variable is read only.\");\n", iname); } - else if ((tm = Swig_typemap_lookup ((char*)"varin", + else if ((tm = mzscheme_typemap_lookup ("varin", t, name, (char*)"argv[0]", name,0))) { Printv(tm2, tm,0); mreplace(tm2, argnum, arg, proc_name); Printv(f_wrappers, tm2, "\n",0); } - else if (SwigType_ispointer(t)) { - if ((SwigType_type(t) == T_CHAR) && (SwigType_ispointer(t) == 1)) { + else if (is_a_pointer(t)) { + if ((SwigType_type(t) == T_CHAR) && (is_a_pointer(t) == 1)) { Printf (f_wrappers, "\t\t _temp = SCHEME_STR_VAL(argv[0]);\n"); Printf (f_wrappers, "\t\t _len = SCHEME_STRLEN_VAL(argv[0]);\n"); Printf (f_wrappers, "\t\t if (%s) { free(%s);}\n", name, name); @@ -544,9 +551,9 @@ MZSCHEME::link_variable (char *name, char *iname, SwigType *t) Printf (f_wrappers, "\t\t strncpy(%s,_temp,_len);\n", name); } else { // Set the value of a pointer - Printf(f_wrappers, "\t\tif (!swig_get_c_pointer(argv[0], \"%s\", (void **) &arg0))\n", - SwigType_manglestr(t)); - Printf(f_wrappers, "\t\t\tscheme_wrong_type(\"%s\", %s, 0, argc, argv", \ + Printf(f_wrappers, "\t\tif (!swig_get_c_pointer(argv[0], \"%s\", (void **) &%s))\n", + SwigType_manglestr(t), name); + Printf(f_wrappers, "\t\t\tscheme_wrong_type(\"%s\", \"%s\", 0, argc, argv);", \ var_name, SwigType_manglestr(t)); } } @@ -558,12 +565,12 @@ MZSCHEME::link_variable (char *name, char *iname, SwigType *t) // Now return the value of the variable (regardless // of evaluating or setting) - if ((tm = Swig_typemap_lookup ((char*)"varout", + if ((tm = mzscheme_typemap_lookup ("varout", t, name, name, (char*)"swig_result",0))) { Printf (f_wrappers, "%s\n", tm); } - else if (SwigType_ispointer(t)) { - if ((SwigType_type(t) == T_CHAR) && (SwigType_ispointer(t) == 1)) { + else if (is_a_pointer(t)) { + if ((SwigType_type(t) == T_CHAR) && (is_a_pointer(t) == 1)) { Printf (f_wrappers, "\t swig_result = scheme_make_string(%s);\n", name); } else { // Is an ordinary pointer type. @@ -630,7 +637,7 @@ MZSCHEME::declare_const (char *name, char *, SwigType *type, char *value) Printv(proc_name, name,0); Replace(proc_name, "_", "-", DOH_REPLACE_ANY); - if ((SwigType_type(type) == T_USER) && (!SwigType_ispointer(type))) { + if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) { fprintf (stderr, "%s : Line %d. Unsupported constant value.\n", input_file, line_number); return; @@ -639,18 +646,18 @@ MZSCHEME::declare_const (char *name, char *, SwigType *type, char *value) // See if there's a typemap Printv(rvalue, value,0); - if ((SwigType_type(type) == T_CHAR) && (SwigType_ispointer(type) == 1)) { + if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 1)) { temp = Copy(rvalue); Clear(rvalue); Printv(rvalue, "\"", temp, "\"",0); } - if ((SwigType_type(type) == T_CHAR) && (SwigType_ispointer(type) == 0)) { + if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 0)) { Delete(temp); temp = Copy(rvalue); Clear(rvalue); Printv(rvalue, "'", temp, "'",0); } - if ((tm = Swig_typemap_lookup ((char*)"const", type, name, + if ((tm = mzscheme_typemap_lookup ("const", type, name, rvalue, name,0))) { // Yep. Use it instead of the default Printf (f_init, "%s\n", tm); @@ -658,8 +665,10 @@ MZSCHEME::declare_const (char *name, char *, SwigType *type, char *value) // Create variable and assign it a value Printf (f_header, "static %s %s = ", SwigType_str(type,0), var_name); - if ((SwigType_type(type) == T_CHAR) && (SwigType_ispointer(type) <= 1)) { + if ((SwigType_type(type) == T_STRING)) { Printf (f_header, "\"%s\";\n", value); + } else if (SwigType_type(type) == T_CHAR) { + Printf (f_header, "\'%s\';\n", value); } else { Printf (f_header, "%s;\n", value); } @@ -721,8 +730,8 @@ MZSCHEME::usage_func (char *iname, SwigType *d, ParmList *l, DOHString *usage) // Print the type. Printv(usage," <", Getname(pt), 0); - if (SwigType_ispointer(pt)) { - for (int j = 0; j < SwigType_ispointer(pt); j++) { + if (is_a_pointer(pt)) { + for (int j = 0; j < is_a_pointer(pt); j++) { Putc('*', usage); } } @@ -773,8 +782,8 @@ MZSCHEME::usage_returns (char *iname, SwigType *d, ParmList *l, DOHString *usage // Print the type. Printv(param," $", Getname(pt), 0); - if (SwigType_ispointer(pt)) { - for (j = 0; j < SwigType_ispointer(pt) - 1; j++) { + if (is_a_pointer(pt)) { + for (j = 0; j < is_a_pointer(pt) - 1; j++) { Putc('*',param); } } diff --git a/SWIG/Source/Modules1.1/perl5.cxx b/SWIG/Source/Modules1.1/perl5.cxx index c17173de4..8bceb61db 100644 --- a/SWIG/Source/Modules1.1/perl5.cxx +++ b/SWIG/Source/Modules1.1/perl5.cxx @@ -19,9 +19,11 @@ static char cvsroot[] = "$Header$"; #include "mod11.h" #include "perl5.h" +#include "swigconfig.h" static char *usage = (char*)"\ Perl5 Options (available with -perl5)\n\ + -ldflags - Print runtime libraries to link with\n\ -module name - Set module name\n\ -interface name - Set interface name\n\ -package name - Set package prefix\n\ @@ -49,7 +51,6 @@ static int is_static = 0; static int blessed = 0; /* Enable object oriented features */ static Hash *classes = 0; /* A hash table for storing the classes we've seen so far */ -static Hash *symbols = 0; static int have_constructor = 0; static int have_destructor= 0; static int have_data_members = 0; @@ -134,6 +135,9 @@ PERL5::parse_args(int argc, char *argv[]) { Swig_mark_arg(i); } else if (strcmp(argv[i],"-help") == 0) { fputs(usage,stderr); + } else if (strcmp (argv[i], "-ldflags") == 0) { + printf("%s\n", SWIG_PERL_RUNTIME); + SWIG_exit (EXIT_SUCCESS); } } } @@ -150,7 +154,6 @@ void PERL5::parse() { classes = NewHash(); - symbols = NewHash(); vinit = NewString(""); pm = NewString(""); @@ -282,12 +285,12 @@ PERL5::initialize() Printf(f_init,"XS(SWIG_init) {\n"); Printf(f_init,"\t dXSARGS;\n"); Printf(f_init,"\t int i;\n"); - Printf(f_init,"\t char *file = __FILE__;\n"); + Printf(f_init,"\t char *file = (char *) __FILE__;\n"); Printv(f_init, "for (i = 0; swig_types_initial[i]; i++) {\n", "swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]);\n", "}\n", 0); - Printf(f_init,"\t newXS(\"%s::var_%s_init\", _wrap_perl5_%s_var_init, file);\n",package,cmodule, cmodule); + Printf(f_init,"\t newXS((char *) \"%s::var_%s_init\", _wrap_perl5_%s_var_init, file);\n",package,cmodule, cmodule); Printv(vinit, "XS(_wrap_perl5_", cmodule, "_var_init) {\n", @@ -488,7 +491,7 @@ get_pointer(char *iname, char *srcname, char *src, char *dest, * ----------------------------------------------------------------------------- */ void PERL5::create_command(char *cname, char *iname) { - Printf(f_init,"\t newXS(\"%s::%s\", %s, file);\n", package, iname, Swig_name_wrapper(cname)); + Printf(f_init,"\t newXS((char *) \"%s::%s\", %s, file);\n", package, iname, Swig_name_wrapper(cname)); if (export_all) { Printf(exported,"%s ",iname); } @@ -727,7 +730,7 @@ PERL5::create_function(char *name, char *iname, SwigType *d, ParmList *l) /* Now register the function */ - Printf(f_init,"\t newXS(\"%s::%s\", %s, file);\n", package, iname, Swig_name_wrapper(iname)); + Printf(f_init,"\t newXS((char *) \"%s::%s\", %s, file);\n", package, iname, Swig_name_wrapper(iname)); if (export_all) { Printf(exported,"%s ", iname); @@ -1259,7 +1262,7 @@ PERL5::usage_func(char *iname, SwigType *, ParmList *l) { * ----------------------------------------------------------------------------- */ void PERL5::add_native(char *name, char *funcname, SwigType *, ParmList *) { - Printf(f_init,"\t newXS(\"%s::%s\", %s, file);\n", package,name, funcname); + Printf(f_init,"\t newXS((char *) \"%s::%s\", %s, file);\n", package,name, funcname); if (export_all) Printf(exported,"%s ",name); if (blessed) { @@ -1489,110 +1492,105 @@ PERL5::cpp_member_func(char *name, char *iname, SwigType *t, ParmList *l) { this->Language::cpp_member_func(name,iname,t,l); member_func = 0; - if (!blessed) return; - - func = NewString(""); - cname = NewString("perl5:"); - - /* Now emit a Perl wrapper function around our member function, we might need - to patch up some arguments along the way */ - - if (!iname) - realname = name; - else - realname = iname; - - Printf(cname,"%s::%s",class_name,realname); - if (Getattr(symbols,cname)) { - return; /* Forget it, we saw this already */ - } - Setattr(symbols,cname,cname); - - Printv(func, - "sub ", realname, " {\n", - tab4, "my @args = @_;\n", - 0); - - /* Now we have to go through and patch up the argument list. If any - arguments to our function correspond to other Perl objects, we - need to extract them from a tied-hash table object. */ - - p = l; - pcount = ParmList_len(l); - numopt = check_numopt(l); - i = 1; - while(p) { - SwigType *pt = Gettype(p); - if (!Getignore(p)) { - char sourceNtarget[512]; - sprintf(sourceNtarget, "$args[%d]", i); - - if ((tm = Swig_typemap_lookup((char*)"perl5in",pt,(char*)"",sourceNtarget,sourceNtarget,0))) { - Printf(func,"%s\n",tm); - need_wrapper = 1; + if (blessed && !is_multiple_definition()) { + func = NewString(""); + cname = NewString("perl5:"); + + /* Now emit a Perl wrapper function around our member function, we might need + to patch up some arguments along the way */ + + if (!iname) + realname = name; + else + realname = iname; + + Printf(cname,"%s::%s",class_name,realname); + Printv(func, + "sub ", realname, " {\n", + tab4, "my @args = @_;\n", + 0); + + /* Now we have to go through and patch up the argument list. If any + arguments to our function correspond to other Perl objects, we + need to extract them from a tied-hash table object. */ + + p = l; + pcount = ParmList_len(l); + numopt = check_numopt(l); + i = 1; + while(p) { + SwigType *pt = Gettype(p); + if (!Getignore(p)) { + char sourceNtarget[512]; + sprintf(sourceNtarget, "$args[%d]", i); + + if ((tm = Swig_typemap_lookup((char*)"perl5in",pt,(char*)"",sourceNtarget,sourceNtarget,0))) { + Printf(func,"%s\n",tm); + need_wrapper = 1; + } + i++; } - i++; + p = Getnext(p); } - p = Getnext(p); - } - - /* Okay. We've made argument adjustments, now call into the package */ - - Printv(func, - tab4, "my $result = ", package, "::", Swig_name_member(class_name,realname), - "(@args);\n", - 0); - - /* Now check to see what kind of return result was found. - * If this function is returning a result by 'value', SWIG did an - * implicit malloc/new. We'll mark the object like it was created - * in Perl so we can garbage collect it. */ - - if ((tm = Swig_typemap_lookup((char*)"perl5out",t,(char*)"",name,(char*)"sv",0))) { + + /* Okay. We've made argument adjustments, now call into the package */ + Printv(func, - tm, "\n", - tab4,"return $result;\n", - "}\n", - 0); - need_wrapper = 1; - - } else if (is_shadow(t)) { - - Printv(func,tab4, "return undef if (!defined($result));\n", 0); - - /* If we're returning an object by value, put it's reference - into our local hash table */ - - if (!SwigType_ispointer(t) || NewObject) { - Printv(func, tab4, "$", is_shadow(t), "::OWNER{$result} = 1; \n", 0); + tab4, "my $result = ", package, "::", Swig_name_member(class_name,realname), + "(@args);\n", + 0); + + /* Now check to see what kind of return result was found. + * If this function is returning a result by 'value', SWIG did an + * implicit malloc/new. We'll mark the object like it was created + * in Perl so we can garbage collect it. */ + + if ((tm = Swig_typemap_lookup((char*)"perl5out",t,(char*)"",name,(char*)"sv",0))) { + Printv(func, + tm, "\n", + tab4,"return $result;\n", + "}\n", + 0); + need_wrapper = 1; + + } else if (is_shadow(t)) { + + Printv(func,tab4, "return undef if (!defined($result));\n", 0); + + /* If we're returning an object by value, put it's reference + into our local hash table */ + + if (!SwigType_ispointer(t) || NewObject) { + Printv(func, tab4, "$", is_shadow(t), "::OWNER{$result} = 1; \n", 0); + } + + /* We're returning a Perl "object" of some kind. Turn it into + a tied hash */ + + Printv(func, + tab4, "my %resulthash;\n", + tab4, "tie %resulthash, ref($result), $result;\n", + tab4, "return bless \\%resulthash, ref($result);\n", + "}\n", + 0); + + need_wrapper = 1; + } else { + + /* Hmmm. This doesn't appear to be anything I know about so just + return it unmodified */ + + Printv(func, tab4,"return $result;\n", "}\n", 0); } - - /* We're returning a Perl "object" of some kind. Turn it into - a tied hash */ - - Printv(func, - tab4, "my %resulthash;\n", - tab4, "tie %resulthash, ref($result), $result;\n", - tab4, "return bless \\%resulthash, ref($result);\n", - "}\n", - 0); - - need_wrapper = 1; - } else { - - /* Hmmm. This doesn't appear to be anything I know about so just - return it unmodified */ - - Printv(func, tab4,"return $result;\n", "}\n", 0); - } - - if (need_wrapper) { - Printv(pcode,func,0); - } else { - Printv(pcode,"*",realname," = *", package, "::", Swig_name_member(class_name,realname), ";\n", 0); + + if (need_wrapper) { + Printv(pcode,func,0); + } else { + Printv(pcode,"*",realname," = *", package, "::", Swig_name_member(class_name,realname), ";\n", 0); + } + Delete(func); + Delete(cname); } - Delete(func); - Delete(cname); } /* ----------------------------------------------------------------------------- @@ -1615,9 +1613,6 @@ PERL5::cpp_member_func(char *name, char *iname, SwigType *t, ParmList *l) { void PERL5::cpp_variable(char *name, char *iname, SwigType *t) { char *realname; - String *cname; - - cname = NewString("perl5:"); /* Emit a pair of get/set functions for the variable */ @@ -1625,16 +1620,9 @@ void PERL5::cpp_variable(char *name, char *iname, SwigType *t) { this->Language::cpp_variable(name, iname, t); member_func = 0; - if (iname) realname = iname; - else realname = name; - - if (blessed) { - Printf(cname,"%s::%s", class_name, realname); - if (Getattr(symbols,cname)) { - Delete(cname); - return; - } - Setattr(symbols,cname,cname); + if (blessed && !is_multiple_definition()) { + if (iname) realname = iname; + else realname = name; /* Store name of key for future reference */ Printf(member_keys,"'%s', ", realname); @@ -1652,7 +1640,6 @@ void PERL5::cpp_variable(char *name, char *iname, SwigType *t) { } } have_data_members++; - Delete(cname); } /* ----------------------------------------------------------------------------- @@ -1668,16 +1655,13 @@ PERL5::cpp_constructor(char *name, char *iname, ParmList *l) { Parm *p; int i; String *realname; - String *cname; - - cname = NewString("perl5:constructor:"); /* Emit an old-style constructor for this class */ member_func = 1; this->Language::cpp_constructor(name, iname, l); - if (blessed) { + if (blessed && !is_multiple_definition()) { if (iname) realname = iname; @@ -1686,12 +1670,6 @@ PERL5::cpp_constructor(char *name, char *iname, ParmList *l) { else realname = class_name; } - Printf(cname,"%s::%s", class_name, realname); - if (Getattr(symbols,cname)) { - Delete(cname); - return; - } - Setattr(symbols,cname, cname); if ((Cmp(realname,class_name) == 0) || ((!iname) && (ObjCClass)) ){ /* Emit a blessed constructor */ @@ -1741,7 +1719,6 @@ PERL5::cpp_constructor(char *name, char *iname, ParmList *l) { have_constructor = 1; } - Delete(cname); member_func = 0; } @@ -1754,7 +1731,7 @@ PERL5::cpp_destructor(char *name, char *newname) { member_func = 1; this->Language::cpp_destructor(name, newname); - if (blessed) { + if (blessed && !is_multiple_definition()) { if (newname) realname = newname; else { if (class_renamed) realname = class_name; @@ -1786,11 +1763,12 @@ PERL5::cpp_destructor(char *name, char *newname) { void PERL5::cpp_static_func(char *name, char *iname, SwigType *t, ParmList *l) { this->Language::cpp_static_func(name,iname,t,l); - char *realname; - if (iname) realname = name; - else realname = iname; - if (blessed) { + if (blessed && !is_multiple_definition()) { + char *realname; + if (iname) realname = name; + else realname = iname; + Printv(pcode, "*", realname, " = *", realpackage, "::", Swig_name_member(class_name,realname), ";\n", 0); } } @@ -1840,25 +1818,18 @@ void PERL5::cpp_declare_const(char *name, char *iname, SwigType *type, char *value) { String *realname; int oldblessed = blessed; - char cname[256]; /* Create a normal constant */ blessed = 0; this->Language::cpp_declare_const(name, iname, type, value); blessed = oldblessed; - if (blessed) { + if (blessed && !is_multiple_definition()) { if (!iname) realname = name; else realname = iname; - sprintf(cname,"%s::%s",Char(class_name),Char(realname)); - if (Getattr(symbols, cname)) { - return; - } - Setattr(symbols, cname,cname); - /* Create a symbol table entry for it */ Printv(pcode, "*", realname, " = *", package, "::", Swig_name_member(class_name,realname), ";\n", 0); } diff --git a/SWIG/Source/Modules1.1/python.cxx b/SWIG/Source/Modules1.1/python.cxx index 140668e93..23a8e8562 100644 --- a/SWIG/Source/Modules1.1/python.cxx +++ b/SWIG/Source/Modules1.1/python.cxx @@ -13,6 +13,7 @@ static char cvsroot[] = "$Header$"; #include "mod11.h" #include "python.h" +#include "swigconfig.h" static String *const_code = 0; static String *shadow_methods = 0; @@ -26,7 +27,6 @@ static int use_kw = 0; static int noopt = 1; static FILE *f_shadow; static Hash *hash; -static Hash *symbols; static String *classes; static String *func; static String *vars; @@ -37,6 +37,7 @@ static char *class_name; static char *usage = (char *)"\ Python Options (available with -python)\n\ + -ldflags - Print runtime libraries to link with\n\ -globals name - Set name used to access C global variable ('cvar' by default).\n\ -module name - Set module name\n\ -interface name - Set the lib name\n\ @@ -108,6 +109,9 @@ PYTHON::parse_args(int argc, char *argv[]) { Swig_mark_arg(i); } else if (strcmp(argv[i],"-help") == 0) { fputs(usage,stderr); + } else if (strcmp (argv[i], "-ldflags") == 0) { + printf("%s\n", SWIG_PYTHON_RUNTIME); + SWIG_exit (EXIT_SUCCESS); } } } @@ -123,7 +127,6 @@ void PYTHON::parse() { hash = NewHash(); - symbols = NewHash(); const_code = NewString(""); shadow_methods = NewString(""); classes = NewString(""); @@ -1227,20 +1230,15 @@ void PYTHON::cpp_member_func(char *name, char *iname, SwigType *t, ParmList *l) { char *realname; int oldshadow; - char cname[1024]; /* Create the default member function */ oldshadow = shadow; /* Disable shadowing when wrapping member functions */ if (shadow) shadow = shadow | PYSHADOW_MEMBER; this->Language::cpp_member_func(name,iname,t,l); shadow = oldshadow; - if (shadow) { - realname = iname ? iname : name; - /* Check to see if we've already seen this */ - sprintf(cname,"python:%s::%s",class_name,realname); - if (Getattr(symbols,cname)) return; - Setattr(symbols,cname,cname); + if (shadow && !is_multiple_definition()) { + realname = iname ? iname : name; if (strcmp(realname,"__repr__") == 0) have_repr = 1; @@ -1287,20 +1285,14 @@ void PYTHON::cpp_constructor(char *name, char *iname, ParmList *l) { char *realname; int oldshadow = shadow; - char cname[1024]; if (shadow) shadow = shadow | PYSHADOW_MEMBER; this->Language::cpp_constructor(name,iname,l); shadow = oldshadow; - if (shadow) { + if (shadow && !is_multiple_definition()) { realname = iname ? iname : class_name; - /* Check to see if we've already seen this */ - sprintf(cname,":python:constructor:%s::%s",class_name,realname); - if (Getattr(symbols,cname)) return; - Setattr(symbols,cname,cname); - if (!have_constructor) { if (use_kw) Printv(construct, tab4, "def __init__(self,*args,**kwargs):\n", 0); @@ -1345,13 +1337,13 @@ PYTHON::cpp_destructor(char *name, char *newname) { if (shadow) shadow = shadow | PYSHADOW_MEMBER; this->Language::cpp_destructor(name,newname); shadow = oldshadow; - if (shadow) { + if (shadow && !is_multiple_definition()) { if (newname) realname = newname; else realname = class_renamed ? class_name : name; Printv(pyclass, tab4, "def __del__(self,", module, "=", module, "):\n", 0); emitAddPragmas(pyclass,(char*)"__del__",(char*)tab8); - Printv(pyclass, tab8, "if self.thisown == 1 :\n", + Printv(pyclass, tab8, "if getattr(self,'thisown',0):\n", tab8, tab4, module, ".", Swig_name_destroy(realname), "(self)\n", 0); have_destructor = 1; @@ -1478,23 +1470,16 @@ PYTHON::cpp_variable(char *name, char *iname, SwigType *t) { char *realname; int inhash = 0; int oldshadow = shadow; - char cname[512]; if (shadow) shadow = shadow | PYSHADOW_MEMBER; this->Language::cpp_variable(name,iname,t); shadow = oldshadow; - if (shadow) { + if (shadow && !is_multiple_definition()) { have_getattr = 1; have_setattr = 1; realname = iname ? iname : name; - /* Check to see if we've already seen this */ - sprintf(cname,"python:%s::%s:",class_name,realname); - if (Getattr(symbols,cname)) return; - - Setattr(symbols,cname,cname); - /* Figure out if we've seen this datatype before */ if (is_shadow(t)) inhash = 1; @@ -1518,19 +1503,13 @@ void PYTHON::cpp_declare_const(char *name, char *iname, SwigType *type, char *value) { char *realname; int oldshadow = shadow; - char cname[512]; if (shadow) shadow = shadow | PYSHADOW_MEMBER; this->Language::cpp_declare_const(name,iname,type,value); shadow = oldshadow; - if (shadow) { + if (shadow && !is_multiple_definition()) { realname = iname ? iname : name; - - /* Check to see if we've already seen this */ - sprintf(cname,"python:%s::%s", class_name, realname); - if (Getattr(symbols,cname)) return; - Setattr(symbols,cname,cname); Printv(cinit, tab4, realname, " = ", module, ".", Swig_name_member(class_name,realname), "\n", 0); } } diff --git a/SWIG/Source/Modules1.1/ruby.cxx b/SWIG/Source/Modules1.1/ruby.cxx index 84a2ee3e3..6b401520d 100644 --- a/SWIG/Source/Modules1.1/ruby.cxx +++ b/SWIG/Source/Modules1.1/ruby.cxx @@ -14,6 +14,7 @@ static char cvsroot[] = "$Header$"; #include "mod11.h" #include "ruby.h" +#include "swigconfig.h" #include <ctype.h> #include <string.h> @@ -92,6 +93,7 @@ class RClass { static char *usage = (char*)"\ Ruby Options (available with -ruby)\n\ + -ldflags - Print runtime libraries to link with\n\ -module name - Set module name\n\ -feature name - Set feature name (used by `require')\n"; @@ -155,6 +157,9 @@ void RUBY::parse_args(int argc, char *argv[]) { } } else if (strcmp(argv[i],"-help") == 0) { Printf(stderr,"%s\n", usage); + } else if (strcmp (argv[i], "-ldflags") == 0) { + printf("%s\n", SWIG_RUBY_RUNTIME); + SWIG_exit (EXIT_SUCCESS); } } } @@ -1309,39 +1314,41 @@ void RUBY::cpp_destructor(char *name, char *newname) { current = DESTRUCTOR; this->Language::cpp_destructor(name, newname); - String *freefunc = NewString(""); - String *freeproto = NewString(""); - String *freebody = NewString(""); - - Printv(freefunc, "free_", klass->cname, 0); - Printv(freeproto, "static void ", freefunc, "(", klass->type, " *);\n", 0); - Printv(freebody, "static void\n", - freefunc, "(", klass->type, " *", Swig_cparm_name(0,0), ") {\n", - tab4, 0); - if (AddMethods) { - Printv(freebody, Swig_name_destroy(name), "(", Swig_cparm_name(0,0), ")", 0); - } else { - /* When no addmethods mode, swig emits no destroy function. */ - if (CPlusPlus) - Printv(freebody, Swig_cppdestructor_call(), 0); - else - Printv(freebody, Swig_cdestructor_call(), 0); - } - Printv(freebody, ";\n}\n", 0); - if (CPlusPlus) { - Insert(freefunc,0,"VOIDFUNC("); - Append(freefunc,")"); + if (!is_multiple_definition()) { + String *freefunc = NewString(""); + String *freeproto = NewString(""); + String *freebody = NewString(""); + + Printv(freefunc, "free_", klass->cname, 0); + Printv(freeproto, "static void ", freefunc, "(", klass->type, " *);\n", 0); + Printv(freebody, "static void\n", + freefunc, "(", klass->type, " *", Swig_cparm_name(0,0), ") {\n", + tab4, 0); + if (AddMethods) { + Printv(freebody, Swig_name_destroy(name), "(", Swig_cparm_name(0,0), ")", 0); + } else { + /* When no addmethods mode, swig emits no destroy function. */ + if (CPlusPlus) + Printv(freebody, Swig_cppdestructor_call(), 0); + else + Printv(freebody, Swig_cdestructor_call(), 0); + } + Printv(freebody, ";\n}\n", 0); + if (CPlusPlus) { + Insert(freefunc,0,"VOIDFUNC("); + Append(freefunc,")"); + } + + Replace(klass->header,"$freefunc", freefunc, DOH_REPLACE_ANY); + Replace(klass->header,"$freeproto", freeproto, DOH_REPLACE_ANY); + Printv(f_wrappers, freebody, 0); + + klass->destructor_defined = 1; + current = NO_CPP; + Delete(freefunc); + Delete(freeproto); + Delete(freebody); } - - Replace(klass->header,"$freefunc", freefunc, DOH_REPLACE_ANY); - Replace(klass->header,"$freeproto", freeproto, DOH_REPLACE_ANY); - Printv(f_wrappers, freebody, 0); - - klass->destructor_defined = 1; - current = NO_CPP; - Delete(freefunc); - Delete(freeproto); - Delete(freebody); } /* --------------------------------------------------------------------- diff --git a/SWIG/Source/Modules1.1/swigmain.cxx b/SWIG/Source/Modules1.1/swigmain.cxx index 50f775268..86e8a2f45 100644 --- a/SWIG/Source/Modules1.1/swigmain.cxx +++ b/SWIG/Source/Modules1.1/swigmain.cxx @@ -32,9 +32,7 @@ static char cvsroot[] = "$Header$"; #include "perl5.h" #include "guile.h" -#ifdef OLD #include "java.h" -#endif #include "mzscheme.h" #include "ruby.h" @@ -88,11 +86,9 @@ int main(int argc, char **argv) { } else if (strcmp(argv[i],"-guile") == 0) { dl = new GUILE; Swig_mark_arg(i); -#ifdef OLD } else if (strcmp(argv[i],"-java") == 0) { dl = new JAVA; Swig_mark_arg(i); -#endif } else if (strcmp(argv[i],"-mzscheme") == 0) { dl = new MZSCHEME; Swig_mark_arg(i); diff --git a/SWIG/Source/Modules1.1/tcl8.cxx b/SWIG/Source/Modules1.1/tcl8.cxx index 8ed1ed4fc..105808cb8 100644 --- a/SWIG/Source/Modules1.1/tcl8.cxx +++ b/SWIG/Source/Modules1.1/tcl8.cxx @@ -14,9 +14,11 @@ static char cvsroot[] = "$Header$"; #include "mod11.h" #include "tcl8.h" #include <ctype.h> +#include "swigconfig.h" static char *usage = (char*)"\ Tcl 8.0 Options (available with -tcl)\n\ + -ldflags - Print runtime libraries to link with\n\ -module name - Set name of module\n\ -prefix name - Set a prefix to be appended to all names\n\ -namespace - Build module into a Tcl 8 namespace. \n\ @@ -76,6 +78,9 @@ TCL8::parse_args(int argc, char *argv[]) { Swig_mark_arg(i); } else if (strcmp(argv[i],"-help") == 0) { fputs(usage,stderr); + } else if (strcmp (argv[i], "-ldflags") == 0) { + printf("%s\n", SWIG_TCL_RUNTIME); + SWIG_exit (EXIT_SUCCESS); } } } @@ -230,7 +235,7 @@ TCL8::close(void) { Printf(f_init,"}\n"); Printf(f_init,"for (i = 0; swig_variables[i].name; i++) {\n"); - Printf(f_init,"Tcl_SetVar(interp, (char *) swig_variables[i].name, \"\", TCL_GLOBAL_ONLY);\n"); + Printf(f_init,"Tcl_SetVar(interp, (char *) swig_variables[i].name, (char *) \"\", TCL_GLOBAL_ONLY);\n"); Printf(f_init,"Tcl_TraceVar(interp, (char *) swig_variables[i].name, TCL_TRACE_READS | TCL_GLOBAL_ONLY, swig_variables[i].get, (ClientData) swig_variables[i].addr);\n"); Printf(f_init,"Tcl_TraceVar(interp, (char *) swig_variables[i].name, TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, swig_variables[i].set, (ClientData) swig_variables[i].addr);\n"); Printf(f_init,"}\n"); @@ -1014,7 +1019,7 @@ void TCL8::cpp_member_func(char *name, char *iname, SwigType *t, ParmList *l) { String *rname; this->Language::cpp_member_func(name,iname,t,l); - if (shadow) { + if (shadow && !is_multiple_definition()) { realname = iname ? iname : name; /* Add stubs for this member to our class handler function */ @@ -1033,7 +1038,7 @@ void TCL8::cpp_variable(char *name, char *iname, SwigType *t) { this->Language::cpp_variable(name, iname, t); - if (shadow) { + if (shadow && !is_multiple_definition()) { realname = iname ? iname : name; Printv(attributes, tab4, "{ \"-", realname, "\",", 0); diff --git a/SWIG/Source/Preprocessor/cpp.c b/SWIG/Source/Preprocessor/cpp.c index e72e6550b..7fe5f59f8 100644 --- a/SWIG/Source/Preprocessor/cpp.c +++ b/SWIG/Source/Preprocessor/cpp.c @@ -173,7 +173,7 @@ DOHHash *Preprocessor_define(DOHString_or_char *str, int swigmacro) goto macro_error; } break; - } else if (isidchar(c)) { + } else if (isidchar(c) || (c == '%')) { Putc(c,macroname); } else if (isspace(c)) { break; @@ -283,19 +283,21 @@ find_args(DOHString *s) DOHList *args; DOHString *str; int c, level; + long pos; /* Create a new list */ args = NewList(); copy_location(s,args); /* First look for a '(' */ + pos = Tell(s); skip_whitespace(s,0); /* Now see if the next character is a '(' */ c = Getc(s); if (c != '(') { /* Not a macro, bail out now! */ - cpp_error(Getfile(s),Getline(s),"Missing macro arguments\n"); + Seek(s,pos, SEEK_SET); return args; } c = Getc(s); @@ -401,12 +403,14 @@ expand_macro(DOHString_or_char *name, DOHList *args) ns = NewString(""); Printf(ns,"%s",name); if (args) { - Putc('(',ns); + if (Len(args)) + Putc('(',ns); for (i = 0; i < Len(args); i++) { Printf(ns,"%s",Getitem(args,i)); if (i < (Len(args) -1)) Putc(',',ns); } - Putc(')',ns); + if (i) + Putc(')',ns); } return ns; } @@ -456,6 +460,26 @@ expand_macro(DOHString_or_char *name, DOHList *args) Printf(tempa,"\"%s\"",arg); Replace(ns, temp, tempa, DOH_REPLACE_ANY); } + + /* Non-standard macro expansion. The value `x` is replaced by a quoted + version of the argument except that if the argument is already quoted + nothing happens */ + + if (strstr(Char(ns),"`")) { + String *rep; + char *c; + Clear(temp); + Printf(temp,"`%s`",aname); + c = Char(arg); + if (*c == '\"') { + rep = arg; + } else { + Clear(tempa); + Printf(tempa,"\"%s\"",arg); + rep = tempa; + } + Replace(ns,temp,rep, DOH_REPLACE_ANY); + } Replace(ns, aname, arg, DOH_REPLACE_ID); } } @@ -513,7 +537,7 @@ Preprocessor_replace(DOH *s) while ((c = Getc(s)) != EOF) { switch (state) { case 0: - if (isidentifier(c)) { + if (isidentifier(c) || (c == '%')) { Clear(id); copy_location(s,id); Putc(c,id); @@ -675,19 +699,28 @@ static int check_id(DOH *s) { int c, state = 0; + int hasvalue = 0; Seek(s,0,SEEK_SET); while ((c = Getc(s)) != EOF) { switch(state) { case 0: - if (isdigit(c)) state = 1; + if (isdigit(c)) { + hasvalue =1; + state = 1; + } else if (isidentifier(c)) return 1; - else if (c == '\"') skip_tochar(s,'\"',0); - else if (c == '\'') skip_tochar(s,'\'',0); - else if (c == '/') state = 3; + else if (c == '\"') { + skip_tochar(s,'\"',0); + hasvalue = 1; + } else if (c == '\'') { + skip_tochar(s,'\'',0); + hasvalue = 1; + } else if (c == '/') state = 3; break; case 1: if (isspace(c)) state = 0; + hasvalue = 1; break; case 3: if (c == '*') state = 10; @@ -709,6 +742,7 @@ check_id(DOH *s) break; } } + if (!hasvalue) return 1; return 0; } @@ -906,7 +940,12 @@ Preprocessor_parse(DOH *s) case 45: if (c == '/') state = 46; else if (c == '*') state = 47; - else { + else if (c == '\n') { + Putc('/',value); + Ungetc(c,s); + cpp_lines++; + state = 50; + } else { Putc('/',value); Putc(c,value); state = 43; @@ -946,6 +985,7 @@ Preprocessor_parse(DOH *s) silent_errors = 1; v1 = Preprocessor_replace(v); silent_errors = 0; + /* Printf(stdout,"checking '%s'\n", v1); */ if (!check_id(v1)) { if (Len(comment) == 0) Printf(ns,"%%constant %s %s;\n", Getattr(m,"name"), v1); diff --git a/SWIG/Source/SWIG1.1/.cvsignore b/SWIG/Source/SWIG1.1/.cvsignore index 1c4954aef..8905680c7 100644 --- a/SWIG/Source/SWIG1.1/.cvsignore +++ b/SWIG/Source/SWIG1.1/.cvsignore @@ -1,6 +1,8 @@ -Makefile *.flc .deps -swig -parser.h +Makefile parser.cxx +parser.h +swig +y.tab.c +y.tab.h diff --git a/SWIG/Source/SWIG1.1/cplus.cxx b/SWIG/Source/SWIG1.1/cplus.cxx index 906c81ac2..c77047525 100644 --- a/SWIG/Source/SWIG1.1/cplus.cxx +++ b/SWIG/Source/SWIG1.1/cplus.cxx @@ -699,6 +699,16 @@ void CPP_class::create_all() { c->emit_decls(); lang->cpp_close_class(); } + // Force brute patch to produce the proper casting code + // between "local" classes and "external" ones when + // %import is used. + else if ( (c->wextern) && (c->classtype) ) { + SwigType *t; + t = NewString(c->classname); + SwigType_add_pointer(t); + SwigType_remember(t); + Delete(t); + } } c = c->next; } diff --git a/SWIG/Source/SWIG1.1/lang.cxx b/SWIG/Source/SWIG1.1/lang.cxx index 70a808f9d..b60f7a2e5 100644 --- a/SWIG/Source/SWIG1.1/lang.cxx +++ b/SWIG/Source/SWIG1.1/lang.cxx @@ -44,6 +44,7 @@ Language::add_native(char *, char *iname, SwigType *, ParmList *) { static char *ClassName = 0; /* This is the real name of the current class */ static char *ClassRename = 0; /* This is non-NULL if the class has been renamed */ static char *ClassType = 0; /* Type of class (ie. union, struct, class) */ +static int multiple_definition = 0; /* Defines whether a function has been multiply defined*/ /* ----------------------------------------------------------------------------- * Language::cpp_open_class() @@ -90,6 +91,7 @@ void Language::cpp_close_class() { void Language::cpp_member_func(char *name, char *iname, SwigType *t, ParmList *l) { char new_name[256]; char *prefix; + multiple_definition = 0; /* Generate the C wrapper function name and interpreter name of this function*/ @@ -110,8 +112,9 @@ void Language::cpp_member_func(char *name, char *iname, SwigType *t, ParmList *l /* Now do a symbol table lookup on it : */ if (add_symbol(new_name)) { - Printf(stderr,"%s : Line %d. Function %s (member %s) multiply defined (2nd definition ignored).\n", + Printf(stderr,"%s : Line %d. Function %s (member %s) multiply defined (multiple definition ignored).\n", input_file, line_number, iname, name); + multiple_definition = 1; return; } cplus_emit_member_func(ClassName, ClassType, ClassRename, name, iname, t, l, AddMethods); @@ -124,6 +127,7 @@ void Language::cpp_member_func(char *name, char *iname, SwigType *t, ParmList *l void Language::cpp_constructor(char *name, char *iname, ParmList *l) { char *prefix, *cname; + multiple_definition = 0; if ((strcmp(name,ClassName)) && (!ObjCClass)) { Printf(stderr,"%s : Line %d. Function %s must have a return type.\n", @@ -146,8 +150,9 @@ void Language::cpp_constructor(char *name, char *iname, ParmList *l) { /* Add this function to the SWIG symbol table */ if (add_symbol(cname)) { - Printf(stderr,"%s : Line %d. Constructor %s multiply defined (2nd definition ignored).\n", + Printf(stderr,"%s : Line %d. Constructor %s multiply defined (multiple definition ignored).\n", input_file, line_number, cname); + multiple_definition = 1; return; } @@ -164,6 +169,7 @@ void Language::cpp_constructor(char *name, char *iname, ParmList *l) { void Language::cpp_destructor(char *name, char *iname) { char *cname; + multiple_definition = 0; if (ClassRename) cname = Char(Swig_name_destroy(ClassRename)); @@ -173,8 +179,9 @@ void Language::cpp_destructor(char *name, char *iname) { /* Add this function to the SWIG symbol table */ if (add_symbol(cname)) { - Printf(stderr,"%s : Line %d. Destructor %s multiply defined (2nd definition ignored).\n", + Printf(stderr,"%s : Line %d. Destructor %s multiply defined (multiple definition ignored).\n", input_file, line_number, cname); + multiple_definition = 1; return; } @@ -217,6 +224,7 @@ void Language::cpp_inherit(char **baseclass, int mode) { void Language::cpp_variable(char *name, char *iname, SwigType *t) { char *prefix, *cname; + multiple_definition = 0; /* Set the class prefix */ @@ -234,7 +242,8 @@ void Language::cpp_variable(char *name, char *iname, SwigType *t) { /* Check the symbol table */ if (add_symbol(cname)) { - Printf(stderr,"%s : Line %d. Variable %s multiply defined (2nd definition ignored).\n", input_file, line_number, cname); + Printf(stderr,"%s : Line %d. Variable %s multiply defined (multiple definition ignored).\n", input_file, line_number, cname); + multiple_definition = 1; return; } @@ -259,6 +268,7 @@ void Language::cpp_static_func(char *name, char *iname, SwigType *t, ParmList *l char *prefix; char *mname; char *cname; + multiple_definition = 0; /* Set the classname prefix */ @@ -280,11 +290,12 @@ void Language::cpp_static_func(char *name, char *iname, SwigType *t, ParmList *l if (add_symbol(cname)) { if (ObjCClass) - Printf(stderr,"%s : Line %d. class function %s multiply defined (2nd definition ignored).\n", + Printf(stderr,"%s : Line %d. class function %s multiply defined (multiple definition ignored).\n", input_file, line_number, cname); else - Printf(stderr,"%s : Line %d. static function %s multiply defined (2nd definition ignored).\n", + Printf(stderr,"%s : Line %d. static function %s multiply defined (multiple definition ignored).\n", input_file, line_number, cname); + multiple_definition = 1; return; } cplus_emit_static_func(ClassName,ClassType, ClassRename, name, iname, t, l, AddMethods); @@ -302,6 +313,7 @@ void Language::cpp_declare_const(char *name, char *iname, SwigType *type, char * char mname[256]; char *new_value; char *prefix; + multiple_definition = 0; /* Set the classname prefix */ @@ -321,8 +333,9 @@ void Language::cpp_declare_const(char *name, char *iname, SwigType *type, char * /* Now do a symbol table lookup on it : */ if (add_symbol(cname)) { - Printf(stderr,"%s : Line %d. Constant %s (member %s) multiply defined (2nd definition ignored).\n", + Printf(stderr,"%s : Line %d. Constant %s (member %s) multiply defined (multiple definition ignored).\n", input_file, line_number, cname, name); + multiple_definition = 1; return; } @@ -354,6 +367,7 @@ void Language::cpp_static_var(char *name, char *iname, SwigType *t) { char *cname; char mname[256]; char *prefix; + multiple_definition = 0; /* Set the classname prefix */ @@ -373,8 +387,9 @@ void Language::cpp_static_var(char *name, char *iname, SwigType *t) { /* Now do a symbol table lookup on it : */ if (add_symbol(cname)) { - Printf(stderr,"%s : Line %d. Variable %s (member %s) multiply defined (2nd definition ignored).\n", + Printf(stderr,"%s : Line %d. Variable %s (member %s) multiply defined (multiple definition ignored).\n", input_file, line_number, cname, name); + multiple_definition = 1; return; } @@ -426,3 +441,11 @@ void Language::pragma(char *, char *, char *) { void Language::import(char *) { /* Does nothing by default */ } + +/* ----------------------------------------------------------------------------- + * Language::is_multiple_definition() + * ----------------------------------------------------------------------------- */ + +int Language::is_multiple_definition() { + return multiple_definition; +} diff --git a/SWIG/Source/SWIG1.1/main.cxx b/SWIG/Source/SWIG1.1/main.cxx index 0e6dd26e5..f042c4ae7 100644 --- a/SWIG/Source/SWIG1.1/main.cxx +++ b/SWIG/Source/SWIG1.1/main.cxx @@ -245,10 +245,12 @@ int SWIG_main(int argc, char *argv[], Language *l) { Swig_arg_error(); } } else if (strcmp(argv[i],"-version") == 0) { - fprintf(stderr,"\nSWIG Version %s %s\n", - SWIG_VERSION, SWIG_SPIN); - fprintf(stderr,"Copyright (c) 1995-98\n"); + fprintf(stderr,"\nSWIG Version %s\n", + SWIG_VERSION); + fprintf(stderr,"Copyright (c) 1995-1998\n"); fprintf(stderr,"University of Utah and the Regents of the University of California\n"); + fprintf(stderr,"Copyright (c) 1998-2001\n"); + fprintf(stderr,"University of Chicago\n"); fprintf(stderr,"\nCompiled with %s\n", SWIG_CC); SWIG_exit (EXIT_SUCCESS); } else if (strncmp(argv[i],"-l",2) == 0) { @@ -393,18 +395,16 @@ int SWIG_main(int argc, char *argv[], Language *l) { DOH *cpps; int i; String *fs = NewString(""); - String *ds = Swig_include(input_file); - if (!ds) { + FILE *df = Swig_open(input_file); + if (!df) { Printf(stderr,"Unable to find '%s'\n", input_file); SWIG_exit (EXIT_FAILURE); } + fclose(df); if (lang_config) { Printf(fs,"\n%%include \"%s\"\n", lang_config); } - Printf(fs,"\n%%includefile \"%s\" {\n", Swig_last_file()); - Append(fs, ds); - Append(fs,"\n}\n"); - Delete(ds); + Printf(fs,"%%include \"%s\"\n", Swig_last_file()); for (i = 0; i < Len(libfiles); i++) { Printf(fs,"\n%%include \"%s\"\n", Getitem(libfiles,i)); } diff --git a/SWIG/Source/SWIG1.1/parser.yxx b/SWIG/Source/SWIG1.1/parser.yxx index f77a80963..dbbf04abf 100644 --- a/SWIG/Source/SWIG1.1/parser.yxx +++ b/SWIG/Source/SWIG1.1/parser.yxx @@ -514,7 +514,7 @@ static void dump_nested(char *parent) { %type <id> pname cpptype base_specifier access_specifier typemap_name tm_method; %type <type> type opt_signed opt_unsigned strict_type; %type <decl> declaration nested_decl; -%type <ivalue> stars cpp_vend; +%type <ivalue> stars maybestars cpp_vend; %type <ilist> initlist base_list inherit; %type <dtype> definetype def_args; %type <dtype> etype; @@ -752,12 +752,26 @@ statement : INCLUDE STRING LBRACE { Rename_true = 1; } +/* and its string version */ + + | NAME LPAREN STRING RPAREN { + strcpy(yy_rename,$3); + Rename_true = 1; + } + /* %rename directive */ | RENAME ID ID SEMI { if (!name_hash) name_hash = NewHash(); Setattr(name_hash,$2,$3); } +/* and its string version */ + + | RENAME ID STRING SEMI { + if (!name_hash) name_hash = NewHash(); + Setattr(name_hash,$2,$3); + } + /* %new directive */ | NEW { @@ -1487,17 +1501,28 @@ parm_type : type pname { free($3); } - | type AND pname { - $$ = NewParm($1,$3); + | type maybestars CONST pname { + $$ = NewParm($1,$4); + add_pointers(Gettype($$), $2); + SwigType_add_qualifier($$,(char*)"const"); + Setvalue($$,DefArg); + Delete($1); + free($4); + } + + | type maybestars AND pname { + $$ = NewParm($1,$4); SwigType *pt = Gettype($$); + add_pointers(Gettype($$), $2); SwigType_add_reference(pt); Setvalue($$,DefArg); if (!CPlusPlus) { Printf(stderr,"%s : Line %d. Warning. Use of C++ Reference detected. Use the -c++ option.\n", input_file, line_number); } Delete($1); - free($3); + free($4); } + | type LPAREN stars pname RPAREN LPAREN parms RPAREN { $$ = NewParm($1,$4); SwigType *pt = Gettype($$); @@ -1585,6 +1610,9 @@ stars : STAR empty { $$ = 1; } | STAR stars { $$ = $2 + 1;} ; +maybestars : empty { $$ = 0; } + | stars { $$ = $1; } + ; array : LBRACKET RBRACKET array2 { $$ = $3 + 1; @@ -1616,6 +1644,9 @@ type : TYPE_INT { | TYPE_LONG opt_int { $$ = $1; } + | TYPE_LONG TYPE_LONG opt_int { + $$ = NewString("long long"); + } | TYPE_CHAR { $$ = $1; } @@ -1683,6 +1714,9 @@ strict_type : TYPE_INT { | TYPE_LONG opt_int { $$ = $1; } + | TYPE_LONG TYPE_LONG opt_int { + $$ = NewString("long long"); + } | TYPE_CHAR { $$ = $1; } @@ -1735,6 +1769,9 @@ opt_signed : empty { | TYPE_LONG opt_int { $$ = $1; } + | TYPE_LONG TYPE_LONG opt_int { + $$ = NewString("long long"); + } | TYPE_CHAR { $$ = NewString("signed char"); } @@ -1754,6 +1791,9 @@ opt_unsigned : empty { | TYPE_LONG opt_int { $$ = NewString("unsigned long"); } + | TYPE_LONG TYPE_LONG opt_int { + $$ = NewString("unsigned long long"); + } | TYPE_CHAR { $$ = NewString("unsigned char"); } @@ -2802,6 +2842,7 @@ cpptype : CLASS { $$ = (char*)"class"; } cpp_const : CONST {} | THROW LPAREN parms RPAREN { Delete($3);} + | CONST THROW LPAREN parms RPAREN { Delete($4);} | empty {} ; @@ -3212,17 +3253,18 @@ typemap_parm : type typemap_name { free($3); } - | type AND typemap_name { + | type maybestars AND typemap_name { $$ = NewTMParm(); - $$->p = NewParm($1,$3); + $$->p = NewParm($1,$4); SwigType *pt = Gettype($$->p); + add_pointers(pt,$2); SwigType_add_reference(pt); if (!CPlusPlus) { Printf(stderr,"%s : Line %d. Warning. Use of C++ Reference detected. Use the -c++ option.\n", input_file, line_number); } $$->args = tm_parm; Delete($1); - free($3); + free($4); } | type LPAREN stars typemap_name RPAREN LPAREN parms RPAREN { Printf(stderr,"%s : Line %d. Error. Function pointer not allowed (remap with typedef).\n", input_file, line_number); diff --git a/SWIG/Source/SWIG1.1/scanner.cxx b/SWIG/Source/SWIG1.1/scanner.cxx index 58c69ff8f..6e4f135a5 100644 --- a/SWIG/Source/SWIG1.1/scanner.cxx +++ b/SWIG/Source/SWIG1.1/scanner.cxx @@ -83,6 +83,7 @@ void scanner_file(DOHFile *f) { in->extern_mode = WrapExtern; in->force_extern = ForceExtern; in->inline_mode = 0; + in->line_number = 1; if (!in_head) in->prev = 0; else in->prev = in_head; in_head = in; diff --git a/SWIG/Source/SWIG1.1/swig11.h b/SWIG/Source/SWIG1.1/swig11.h index 9b0fe8870..af1c7d007 100644 --- a/SWIG/Source/SWIG1.1/swig11.h +++ b/SWIG/Source/SWIG1.1/swig11.h @@ -214,6 +214,8 @@ public: virtual void import(char *filename); +protected: + int is_multiple_definition(); // indicates whether the function has already been defined }; /* Emit functions */ diff --git a/SWIG/Source/Swig/cwrap.c b/SWIG/Source/Swig/cwrap.c index 33af4c955..56e25884e 100644 --- a/SWIG/Source/Swig/cwrap.c +++ b/SWIG/Source/Swig/cwrap.c @@ -74,7 +74,7 @@ Swig_clocal(SwigType *t, String_or_char *name, String_or_char *value) { * Swig_clocal_type() * * Creates a string that declares a C local variable type. Converts references - * and user defined types to pointers. + * and user defined types and arrays to pointers. * ----------------------------------------------------------------------------- */ SwigType * @@ -94,6 +94,27 @@ Swig_clocal_type(SwigType *t) { } /* ----------------------------------------------------------------------------- + * Swig_wrapped_var_convert() + * + * Converts a member variable for use in the get and set wrapper methods. + * This function only converts user defined types to pointers. + * ----------------------------------------------------------------------------- */ + +SwigType * +Swig_wrapped_var_type(SwigType *t) { + SwigType *ty; + ty = Copy(t); + switch(SwigType_type(t)) { + case T_USER: + SwigType_add_pointer(ty); + break; + default: + break; + } + return ty; +} + +/* ----------------------------------------------------------------------------- * Swig_clocal_deref() * * Creates a string that can be used to deref a local variable wrapped with @@ -253,7 +274,7 @@ void Swig_cppresult(Wrapper *w, SwigType *t, String_or_char *name, String_or_cha switch(SwigType_type(t)) { case T_USER: - Printf(fcall,");"); + Printf(fcall,");\n"); break; case T_REFERENCE: Printf(fcall,";\n"); @@ -797,6 +818,7 @@ Swig_cmemberset_wrapper(String_or_char *classname, Parm *p; SwigType *t; SwigType *lt; + SwigType *ty; w = NewWrapper(); @@ -810,7 +832,9 @@ Swig_cmemberset_wrapper(String_or_char *classname, Delete(t); lt = Swig_clocal_type(type); - p = NewParm(lt,"value"); + ty = Swig_wrapped_var_type(type); + p = NewParm(ty,"value"); + Setnext(l,p); /* Printf(w->def,"%s %s(%s) {", SwigType_str(lt,0), Wrapper_Getname(w), ParmList_str(l)); */ @@ -829,6 +853,7 @@ Swig_cmemberset_wrapper(String_or_char *classname, Wrapper_Setparms(w,l); Delete(l); Delete(lt); + Delete(ty); return w; } @@ -850,6 +875,7 @@ Swig_cmemberget_wrapper(String_or_char *classname, Parm *p; SwigType *t; SwigType *lt; + SwigType *ty; w = NewWrapper(); @@ -872,10 +898,13 @@ Swig_cmemberget_wrapper(String_or_char *classname, Printv(w->code, code, "\n", 0); } Printf(w->code,"}\n"); - Wrapper_Settype(w,lt); + ty = Swig_wrapped_var_type(type); + Wrapper_Settype(w,ty); + Wrapper_Setparms(w,l); Delete(l); Delete(lt); + Delete(ty); return w; } @@ -894,6 +923,7 @@ Swig_cvarset_wrapper(String_or_char *varname, ParmList *l; Parm *p; SwigType *lt; + SwigType *ty; w = NewWrapper(); @@ -901,15 +931,16 @@ Swig_cvarset_wrapper(String_or_char *varname, Wrapper_Setname(w,Swig_name_set(varname)); lt = Swig_clocal_type(type); - p = NewParm(lt,"value"); + ty = Swig_wrapped_var_type(type); + p = NewParm(ty,"value"); l = p; - Printf(w->def,"%s %s(%s) {", SwigType_str(lt,0), Wrapper_Getname(w), ParmList_str(l)); +/* Printf(w->def,"%s %s(%s) {", SwigType_str(lt,0), Wrapper_Getname(w), ParmList_str(l));*/ + Printf(w->def,"void %s(%s) {", Wrapper_Getname(w), ParmList_str(l)); if (!code) { /* No code supplied. Write a function manually */ - Printf(w->code,"%s = %s;\n", varname, Swig_clocal_deref(lt,"value")); - Printf(w->code,"return %s;\n", Swig_clocal_assign(lt,varname)); + Printf(w->code,"%s = %s;\n", varname, Swig_clocal_deref(type,"value")); } else { Printv(w->code, code, "\n", 0); Replace(w->code,"$target",varname, DOH_REPLACE_ANY); @@ -918,10 +949,11 @@ Swig_cvarset_wrapper(String_or_char *varname, Replace(w->code,"$rtype", SwigType_str(type,""), DOH_REPLACE_ANY); } Printf(w->code,"}\n"); - Wrapper_Settype(w,lt); + Wrapper_Settype(w,"void"); Wrapper_Setparms(w,l); Delete(l); Delete(lt); + Delete(ty); return w; } @@ -939,6 +971,7 @@ Swig_cvarget_wrapper(String_or_char *varname, Wrapper *w; ParmList *l = 0; SwigType *lt; + SwigType *ty; w = NewWrapper(); @@ -956,10 +989,12 @@ Swig_cvarget_wrapper(String_or_char *varname, Printv(w->code, code, "\n", 0); } Printf(w->code,"}\n"); - Wrapper_Settype(w,lt); + ty = Swig_wrapped_var_type(type); + Wrapper_Settype(w,ty); Wrapper_Setparms(w,l); Delete(l); Delete(lt); + Delete(ty); return w; } diff --git a/SWIG/Source/Swig/misc.c b/SWIG/Source/Swig/misc.c index bd4de2e82..74899a5d3 100644 --- a/SWIG/Source/Swig/misc.c +++ b/SWIG/Source/Swig/misc.c @@ -42,13 +42,13 @@ Swig_banner(File *f) { Printf(f, "/* ----------------------------------------------------------------------------\n\ * This file was automatically generated by SWIG (http://www.swig.org).\n\ - * Version %s %s\n\ + * Version %s\n\ * \n\ * This file is not intended to be easily readable and contains a number of \n\ * coding conventions designed to improve portability and efficiency. Do not make\n\ * changes to this file unless you know what you are doing--modify the SWIG \n\ * interface file instead. \n\ - * ----------------------------------------------------------------------------- */\n\n", SWIG_VERSION, SWIG_SPIN); + * ----------------------------------------------------------------------------- */\n\n", SWIG_VERSION); } diff --git a/SWIG/Source/Swig/stype.c b/SWIG/Source/Swig/stype.c index 6618ea7a6..8047cd1c1 100644 --- a/SWIG/Source/Swig/stype.c +++ b/SWIG/Source/Swig/stype.c @@ -812,6 +812,8 @@ SwigType_lstr(SwigType *s, const String_or_char *id) Append(result,")"); Delete(parms); } else if (SwigType_isqualifier(element)) { + } else if (SwigType_isenum(element)) { + Insert(result,0," int "); } else { Insert(result,0," "); Insert(result,0,element); @@ -1329,6 +1331,8 @@ int SwigType_type(SwigType *t) if (strcmp(c,"double") == 0) return T_DOUBLE; if (strcmp(c,"void") == 0) return T_VOID; if (strcmp(c,"bool") == 0) return T_BOOL; + if (strcmp(c,"long long") == 0) return T_LONGLONG; + if (strcmp(c,"unsigned long long") == 0) return T_ULONGLONG; if (strncmp(c,"enum ",5) == 0) return T_INT; /* Hmmm. Unknown type */ if (SwigType_istypedef(t)) { diff --git a/SWIG/Source/Swig/swig.h b/SWIG/Source/Swig/swig.h index 30ceae6c2..d32eb2125 100644 --- a/SWIG/Source/Swig/swig.h +++ b/SWIG/Source/Swig/swig.h @@ -47,6 +47,8 @@ typedef DOH File; #define T_CHAR 12 #define T_USER 13 #define T_VOID 14 +#define T_LONGLONG 15 +#define T_ULONGLONG 16 #define T_STRING 20 #define T_POINTER 21 #define T_REFERENCE 22 diff --git a/SWIG/Source/Swig/typemap.c b/SWIG/Source/Swig/typemap.c index d71d37a00..2a6af339e 100644 --- a/SWIG/Source/Swig/typemap.c +++ b/SWIG/Source/Swig/typemap.c @@ -329,7 +329,14 @@ Swig_typemap_search(char *op, SwigType *type, String_or_char *name) { if (!primitive) primitive = SwigType_default(type); tm = Getattr(typemaps[ts],primitive); - if (tm) { + 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) { /* See if there is simply a type match */ result = Getattr(tm,op); if (result) goto ret_result; } |