| /* ----------------------------------------------------------------------------- |
| * java.cxx |
| * |
| * Java wrapper module. |
| * |
| * Copyright (C) 1999-2000. The University of Chicago |
| * See the file LICENSE for information on usage and redistribution. |
| * ----------------------------------------------------------------------------- */ |
| |
| #include <ctype.h> |
| |
| #include "mod11.h" |
| #include "java.h" |
| |
| 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 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 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); |
| } |
| return ta; |
| } |
| |
| /* |
| 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)); |
| } |
| } |
| |
| /* 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)); |
| } |
| } |
| |
| 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 |
| } |
| } |
| |
| /* 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_ULONG: return (char*)"[J"; |
| case T_FLOAT: return (char*)"[F"; |
| case T_DOUBLE: return (char*)"[D"; |
| 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 && is_shadow(t)) |
| return Char(is_shadow(t)); |
| else return (char*)"J"; |
| } |
| } else if(SwigType_ispointer(t) > 1) { |
| if(ret) return (char*)"J"; |
| else return (char*)"[J"; |
| } else { |
| 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_ULONG: return (char*)"J"; |
| case T_FLOAT: return (char*)"F"; |
| case T_DOUBLE: return (char*)"D"; |
| 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 [%d] %s\n", SwigType_type(t), SwigType_str(t,0)); |
| return NULL; |
| } |
| |
| char *JAVA::JavaTypeFromTypemap(char *op, SwigType *t, String_or_char *pname) { |
| char *tm; |
| char *c = bigbuf; |
| 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'; |
| |
| return strdup(bigbuf); |
| } |
| |
| char *JAVA::makeValidJniName(char *name) { |
| char *c = name; |
| char *b = bigbuf; |
| |
| while(*c) { |
| *b++ = *c; |
| if(*c == '_') |
| *b++ = '1'; |
| c++; |
| } |
| *b = '\0'; |
| |
| return strdup(bigbuf); |
| } |
| |
| // !! this approach fails for functions without arguments |
| char *JAVA::JNICALL(String_or_char *func) { |
| if(jnic) |
| sprintf(bigbuf, "(*jenv)->%s(jenv, ", Char(func)); |
| else |
| sprintf(bigbuf, "jenv->%s(", Char(func)); |
| |
| return strdup(bigbuf); |
| } |
| |
| void JAVA::writeRegisterNatives() |
| { |
| if(Len(registerNativesList) == 0) |
| return; |
| |
| Printf(f_wrappers,"\n"); |
| Printf(f_wrappers,"JNINativeMethod nativeMethods[] = {\n"); |
| Printv(f_wrappers, registerNativesList, 0); |
| Printf(f_wrappers, "};\n"); |
| |
| Printf(f_wrappers,"\nint numberOfNativeMethods=sizeof(nativeMethods)/sizeof(JNINativeMethod);\n\n"); |
| |
| // The registerNatives function |
| |
| Printv(f_wrappers, |
| "jint registerNatives(JNIEnv *jenv) {", "\n", |
| tab4, "jclass nativeClass = ", JNICALL((char*)"FindClass"), |
| "\"", jni_pkgstr, module, "\");","\n", |
| 0); |
| |
| Printv(f_wrappers, |
| tab4, "if (nativeClass == 0)", "\n", tab8, "return -1;", "\n", |
| tab4, "return ", JNICALL((char*)"RegisterNatives"), "nativeClass, nativeMethods, ", "numberOfNativeMethods);", "\n", |
| "}", "\n", "\n", |
| 0); |
| |
| // The unregisterNatives function |
| |
| Printv(f_wrappers, |
| "jint unregisterNatives(JNIEnv *jenv) {", "\n", |
| tab4, "jclass nativeClass = ", JNICALL((char*)"FindClass"), |
| "\"", jni_pkgstr, module, "\");","\n", |
| 0); |
| |
| Printv(f_wrappers, |
| tab4, "if (nativeClass == 0)", "\n", tab8, "return -1;", "\n", |
| tab4, "// Sun documentation suggests that this method should not be invoked in ", |
| "\"normal native code\".", "\n", |
| tab4, "// return ", JNICALL((char*)"UnregisterNatives"), "nativeClass);", "\n", |
| tab4, "return 0;", "\n", |
| "}", "\n", |
| 0); |
| } |
| |
| // --------------------------------------------------------------------- |
| // JAVA::parse_args(int argc, char *argv[]) |
| // |
| // Parse my command line options and initialize by variables. |
| // --------------------------------------------------------------------- |
| |
| void JAVA::parse_args(int argc, char *argv[]) { |
| |
| // file::set_library(java_path); |
| sprintf(LibDir,"%s", "java"); |
| |
| |
| // Look for certain command line options |
| for (int i = 1; i < argc; i++) { |
| if (argv[i]) { |
| if (strcmp(argv[i],"-module") == 0) { |
| if (argv[i+1]) { |
| set_module(argv[i+1]); |
| Swig_mark_arg(i); |
| Swig_mark_arg(i+1); |
| i++; |
| } else { |
| Swig_arg_error(); |
| } |
| } else if (strcmp(argv[i],"-package") == 0) { |
| if (argv[i+1]) { |
| package = new char[strlen(argv[i+1])+1]; |
| strcpy(package, argv[i+1]); |
| Swig_mark_arg(i); |
| Swig_mark_arg(i+1); |
| i++; |
| } else { |
| Swig_arg_error(); |
| } |
| } else if (strcmp(argv[i],"-shadow") == 0) { |
| Swig_mark_arg(i); |
| shadow = 1; |
| } else if (strcmp(argv[i],"-jnic") == 0) { |
| Swig_mark_arg(i); |
| jnic = 1; |
| } else if (strcmp(argv[i],"-nofinalize") == 0) { |
| Swig_mark_arg(i); |
| nofinalize = 1; |
| } else if (strcmp(argv[i],"-rn") == 0) { |
| Swig_mark_arg(i); |
| useRegisterNatives = 1; |
| } else if (strcmp(argv[i],"-jnicpp") == 0) { |
| Swig_mark_arg(i); |
| jnic = 0; |
| } else if (strcmp(argv[i],"-help") == 0) { |
| Printf(stderr,"%s\n", usage); |
| } |
| } |
| } |
| |
| if(jnic == -1) { |
| if(CPlusPlus) |
| jnic = 0; |
| else jnic = 1; |
| } |
| |
| // Add a symbol to the parser for conditional compilation |
| // cpp::define("SWIGJAVA"); |
| Preprocessor_define((void *) "SWIGJAVA 1",0); |
| |
| // Add typemap definitions |
| typemap_lang = (char*)"java"; |
| } |
| |
| // --------------------------------------------------------------------- |
| // void JAVA::parse() |
| // |
| // Start parsing an interface file for JAVA. |
| // --------------------------------------------------------------------- |
| |
| void JAVA::parse() { |
| 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) |
| // |
| // Sets the module name. Does nothing if it's already set (so it can |
| // be overriddent as a command line option). |
| // |
| //---------------------------------------------------------------------- |
| |
| void JAVA::set_module(char *mod_name) { |
| if (module) return; |
| module = new char[strlen(mod_name)+1]; |
| strcpy(module,mod_name); |
| } |
| |
| // --------------------------------------------------------------------- |
| // JAVA::headers(void) |
| // |
| // Generate the appropriate header files for JAVA interface. |
| // ---------------------------------------------------------------------- |
| |
| void JAVA::headers(void) |
| { |
| Swig_banner(f_header); // Print the SWIG banner message |
| Printf(f_header,"/* Implementation : Java */\n\n"); |
| |
| // Include header file code fragment into the output |
| // if (file::include("java.swg",f_header) == -1) { |
| if (Swig_insert_file("java.swg",f_header) == -1) { |
| Printf(stderr,"Fatal Error. Unable to locate 'java.swg'.\n"); |
| SWIG_exit (EXIT_FAILURE); |
| } |
| } |
| |
| // -------------------------------------------------------------------- |
| // JAVA::initialize(void) |
| // |
| // Produces an initialization function. Assumes that the init function |
| // name has already been specified. |
| // --------------------------------------------------------------------- |
| |
| void JAVA::initialize() |
| { |
| if (!module) { |
| Printf(stderr,"*** Error. No module name specified.\n"); |
| SWIG_exit(1); |
| } |
| |
| if(package) { |
| String *s = NewString(package); |
| Replace(s,".","_", DOH_REPLACE_ANY); |
| Append(s,"_"); |
| c_pkgstr = Swig_copy_string(Char(s)); |
| Delete(s); |
| |
| String *s2 = NewString(package); |
| Replace(s2,".","/", DOH_REPLACE_ANY); |
| Append(s2,"/"); |
| jni_pkgstr = Swig_copy_string(Char(s2)); |
| Delete(s2); |
| } else { |
| package = c_pkgstr = jni_pkgstr = (char*)""; |
| } |
| |
| sprintf(bigbuf, "Java_%s%s", c_pkgstr, module); |
| c_pkgstr = Swig_copy_string(bigbuf); |
| |
| 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"); |
| Swig_name_register((char*)"member", (char*)"%c_%m"); |
| |
| // Generate the java class |
| sprintf(bigbuf, "%s.java", module); |
| if((f_java = fopen(bigbuf, "w")) == 0) { |
| Printf(stderr,"Unable to open %s\n", bigbuf); |
| SWIG_exit(1); |
| } |
| |
| Printf(f_header, "#define J_CLASSNAME %s\n", module); |
| if(package && *package) { |
| Printf(f_java, "package %s;\n\n", package); |
| Printf(f_header, "#define J_PACKAGE %s\n", package); |
| } else { |
| Printf(f_header, "#define J_PACKAGE\n"); |
| } |
| } |
| |
| 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) { |
| 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; |
| } |
| |
| // --------------------------------------------------------------------- |
| // JAVA::close(void) |
| // |
| // Wrap things up. Close initialization function. |
| // --------------------------------------------------------------------- |
| |
| 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; |
| } |
| |
| // ---------------------------------------------------------------------- |
| // JAVA::create_command(char *cname, char *iname) |
| // |
| // Creates a JAVA command from a C function. |
| // ---------------------------------------------------------------------- |
| |
| void JAVA::create_command(char *cname, char *iname) { |
| } |
| |
| 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, SwigType *d, ParmList *l) |
| // |
| // Create a function declaration and register it with the interpreter. |
| // ---------------------------------------------------------------------- |
| |
| void JAVA::create_function(char *name, char *iname, SwigType *t, ParmList *l) |
| { |
| char source[256], target[256]; |
| char *tm; |
| char *javaReturnSignature = 0; |
| 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); |
| } |
| |
| /* |
| 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(); |
| |
| if(!classdef_emitted) emit_classdef(); |
| |
| // Make a wrapper name for this function |
| char *jniname = makeValidJniName(iname); |
| String *wname = Swig_name_wrapper(jniname); |
| |
| free(jniname); |
| |
| /* 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 |
| if (useRegisterNatives) { |
| javaReturnSignature = JavaMethodSignature(t, 1, 0); |
| } |
| |
| if (SwigType_type(t) != T_VOID) { |
| Wrapper_add_localv(f,"jresult", jnirettype, "jresult = 0",0); |
| } |
| |
| Printf(f_java, " %s ", module_method_modifiers); |
| Printf(f_java, "native %s %s(", javarettype, iname); |
| |
| 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. |
| int pcount = emit_args(t,l,f); |
| |
| int gencomma = 0; |
| |
| // Now walk the function parameter list and generate code to get arguments |
| Parm *p = l; |
| for (int i = 0; i < pcount ; i++, p = Getnext(p)) { |
| 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(target,"%s", Char(Getlname(p))); |
| sprintf(source,"j%s", target); |
| |
| if (useRegisterNatives) { |
| Printv(javaParameterSignature, JavaMethodSignature(pt, 0, 0), 0); |
| } |
| |
| if(Getignore(p)) continue; |
| |
| /* 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", javaparamtype, source); |
| |
| gencomma = 1; |
| |
| // Add to Jni function header |
| Printv(f->def, ", ", jni_param_type, " ", source, 0); |
| |
| // Get typemap for this argument |
| 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); |
| } else { |
| 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 = 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 = 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 = 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 { |
| 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"); |
| 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((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 { |
| 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; |
| Printv(f->code, outarg, 0); |
| |
| // Dump the argument cleanup code |
| Printv(f->code,cleanup, 0); |
| |
| // Look for any remaining cleanup |
| |
| if (NewObject) { |
| if ((tm = Swig_typemap_lookup((char*)"newfree",t,iname,(char*)"result",(char*)"",NULL))) { |
| Printf(f->code,"%s\n", tm); |
| } |
| } |
| |
| 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(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) |
| Replace(f->code,"$cleanup",cleanup, DOH_REPLACE_ANY); |
| |
| // Emit the function |
| |
| if(!native_func) |
| Wrapper_print(f,f_wrappers); |
| |
| // If registerNatives is active, store the table entry for this method |
| if (useRegisterNatives) { |
| Printv(registerNativesList, |
| tab4, "{", |
| "\"", name, "\", \"(", javaParameterSignature, ")", javaReturnSignature, "\", ", wname, |
| "},\n", |
| 0); |
| |
| } |
| |
| Delete(jnirettype); |
| Delete(javarettype); |
| Delete(cleanup); |
| Delete(outarg); |
| Delete(body); |
| Delete(javaParameterSignature); |
| DelWrapper(f); |
| } |
| |
| // ----------------------------------------------------------------------- |
| // 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, SwigType *t) |
| { |
| emit_set_get(name,iname, t); |
| } |
| |
| // ----------------------------------------------------------------------- |
| // JAVA::declare_const(char *name, char *iname, SwigType *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 && wrapping_member) { |
| if(!shadow_classdef_emitted) emit_shadow_classdef(); |
| jfile = f_shadow; |
| jname = shadow_variable_name; |
| } else { |
| jfile = f_java; |
| jname = name; |
| } |
| |
| 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 { |
| 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; |
| } |
| /* |
| 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; |
| |
| 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, "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(strvalue); |
| } |
| |
| // --------------------------------------------------------------------- |
| // C++ Handling |
| // |
| // The following functions provide some support for C++ classes and |
| // C structs. |
| // --------------------------------------------------------------------- |
| |
| /* |
| 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); |
| } |
| |
| Delete(strvalue); |
| } |
| plist = plist->next; |
| } |
| } |
| |
| void JAVA::add_typedef(SwigType *t, char *name) { |
| if(!shadow) return; |
| if (is_shadow(t)) { |
| cpp_class_decl(name,Char(is_shadow(t)), (char*) ""); |
| } |
| } |
| |
| void JAVA::cpp_open_class(char *classname, char *rename, char *ctype, int strip) { |
| |
| this->Language::cpp_open_class(classname,rename,ctype,strip); |
| |
| if(!shadow) return; |
| |
| if(rename) |
| shadow_classname = Swig_copy_string(rename); |
| else shadow_classname = Swig_copy_string(classname); |
| |
| if (strcmp(shadow_classname, module) == 0) { |
| Printf(stderr, "class name cannot be equal to module name: %s\n", shadow_classname); |
| SWIG_exit(1); |
| } |
| |
| Setattr(shadow_classes,classname, shadow_classname); |
| if(ctype && strcmp(ctype, "struct") == 0) { |
| sprintf(bigbuf, "struct %s", classname); |
| Setattr(shadow_classes, bigbuf, shadow_classname); |
| } |
| |
| sprintf(bigbuf, "%s.java", shadow_classname); |
| if(!(f_shadow = fopen(bigbuf, "w"))) { |
| Printf(stderr, "Unable to create shadow class file: %s\n", bigbuf); |
| } |
| |
| emit_banner(f_shadow); |
| |
| if(*package) |
| 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, "$classmodifiers class ", shadow_classname, " $bases", "{\n", 0); |
| |
| 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() { |
| 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++; |
| } |
| 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() { |
| this->Language::cpp_close_class(); |
| if(!shadow) return; |
| |
| 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, " 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; |
| |
| 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); |
| |
| /* |
| // 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); |
| |
| cpp_func(iname, t, l, java_function_name); |
| } |
| } |
| |
| void JAVA::cpp_static_func(char *name, char *iname, SwigType *t, ParmList *l) { |
| this->Language::cpp_static_func(name,iname,t,l); |
| |
| if (shadow && !is_multiple_definition()) { |
| char* realname = iname ? iname : name; |
| String* java_function_name = Swig_name_member(shadow_classname, realname); |
| |
| static_flag = 1; |
| cpp_func(iname, t, l, java_function_name); |
| static_flag = 0; |
| } |
| } |
| |
| /* |
| 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; |
| if(!shadow_classdef_emitted) emit_shadow_classdef(); |
| |
| /* Get the java return type */ |
| SwigToJavaType(t, iname, shadowrettype, shadow); |
| |
| Printf(f_shadow, " public %s %s %s(", (static_flag ? "static":""), shadowrettype, iname); |
| |
| 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, ".", java_function_name, "(", 0); |
| if (!static_flag) |
| Printv(nativecall, "getCPtr()", 0); |
| |
| int gencomma = !static_flag; |
| int pcount = ParmList_len(l); |
| |
| /* Output each parameter */ |
| Parm *p = l; |
| |
| /* 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 */ |
| |
| for (int i = 0; i < pcount ; i++, p = Getnext(p)) { |
| if(Getignore(p)) continue; |
| |
| /* 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); |
| |
| Delete(javaparamtype); |
| } |
| } |
| |
| 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"); |
| } |
| |
| Printf(f_shadow, ") {\n"); |
| 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 && !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); |
| } |
| } |
| |
| void JAVA::cpp_destructor(char *name, char *newname) { |
| this->Language::cpp_destructor(name,newname); |
| |
| 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"); |
| } |
| } |
| |
| void JAVA::cpp_class_decl(char *name, char *rename, char *type) { |
| 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); |
| } |
| } |
| } |
| |
| void JAVA::cpp_inherit(char **baseclass, int) { |
| this->Language::cpp_inherit(baseclass, 0); |
| |
| if(!shadow) return; |
| |
| int i = 0; |
| while(baseclass[i]) i++; |
| |
| if(i > 1) |
| Printf(stderr, "Warning: %s inherits from multiple base classes. Multiple inheritance is not supported.\n", shadow_classname); |
| |
| 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, SwigType *t) { |
| shadow_variable_name = Swig_copy_string((iname) ? iname : name); |
| |
| wrapping_member = 1; |
| variable_wrapper_flag = 1; |
| this->Language::cpp_variable(name, iname, t); |
| wrapping_member = 0; |
| variable_wrapper_flag = 0; |
| } |
| |
| 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); |
| 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, SwigType *type, char *value) { |
| shadow_variable_name = Swig_copy_string((iname) ? iname : name); |
| |
| wrapping_member = 1; |
| this->Language::cpp_declare_const(name, iname, type, value); |
| wrapping_member = 0; |
| } |
| |
| |
| |