diff --git a/.project b/.project new file mode 100644 index 000000000..86af75213 --- /dev/null +++ b/.project @@ -0,0 +1,11 @@ + + + SWIG + + + + + + + + diff --git a/Lib/mzscheme/mzrun.swg b/Lib/mzscheme/mzrun.swg index 52aa87aca..6a71fb79a 100644 --- a/Lib/mzscheme/mzrun.swg +++ b/Lib/mzscheme/mzrun.swg @@ -252,6 +252,199 @@ SWIG_MzScheme_new_scheme_struct (Scheme_Env* env, const char* basename, return new_type; } +/*** DLOPEN PATCH ****************************************************** + * Contributed by Hans Oesterholt-Dijkema (jan. 2006) + ***********************************************************************/ + +#if defined(_WIN32) || defined(__WIN32__) +#define __OS_WIN32 +#endif + +#ifdef __OS_WIN32 +#include +#else +#include +#endif + + static char **mz_dlopen_libraries=NULL; + static void **mz_libraries=NULL; + static char **mz_dynload_libpaths=NULL; + + static void mz_set_dlopen_libraries(const char *_libs) + { + int i,k,n; + int mz_dynload_debug=(1==0); + char *extra_paths[1000]; + char *EP; + + { + char *dbg=getenv("MZ_DYNLOAD_DEBUG"); + if (dbg!=NULL) { + mz_dynload_debug=atoi(dbg); + } + } + + { + char *ep=getenv("MZ_DYNLOAD_LIBPATH"); + int i,k,j; + k=0; + if (ep!=NULL) { + EP=strdup(ep); + for(i=0,j=0;EP[i]!='\0';i++) { + if (EP[i]==':') { + EP[i]='\0'; + extra_paths[k++]=&EP[j]; + j=i+1; + } + } + if (j!=i) { + extra_paths[k++]=&EP[j]; + } + } + else { + EP=strdup(""); + } + extra_paths[k]=NULL; + k+=1; + + if (mz_dynload_debug) { + fprintf(stderr,"SWIG:mzscheme:MZ_DYNLOAD_LIBPATH=%s\n",(ep==NULL) ? "(null)" : ep); + fprintf(stderr,"SWIG:mzscheme:extra_paths[%d]\n",k-1); + for(i=0;i %p\n",libp,mz_libraries[i]); + } + free(libp); + } + } + } + } + { + int i; + void *func=NULL; + + for(i=0;mz_dlopen_libraries[i]!=NULL && func==NULL;i++) { + if (mz_libraries[i]!=NULL) { +#ifdef __OS_WIN32 + func=GetProcAddress(mz_libraries[i],function); +#else + func=dlsym(mz_libraries[i],function); +#endif + } + if (mz_dynload_debug) { + fprintf(stderr, + "SWIG:mzscheme:library:%s;dlopen=%p,function=%s,func=%p\n", + mz_dlopen_libraries[i],mz_libraries[i],function,func + ); + } + } + + return func; + } + } + } + +/*** DLOPEN PATCH ****************************************************** + * Contributed by Hans Oesterholt-Dijkema (jan. 2006) + ***********************************************************************/ + /* The interpreter will store a pointer to this structure in a global variable called swig-runtime-data-type-pointer. The instance of this struct is only used if no other module has yet been loaded */ @@ -311,3 +504,4 @@ SWIG_MzScheme_SetModule(Scheme_Env *env, swig_module_info *module) { #ifdef __cplusplus } #endif + diff --git a/Source/Modules/mzscheme.cxx b/Source/Modules/mzscheme.cxx index e68bc0f6c..4085086df 100644 --- a/Source/Modules/mzscheme.cxx +++ b/Source/Modules/mzscheme.cxx @@ -15,10 +15,13 @@ char cvsroot_mzscheme_cxx[] = "$Header$"; static const char *usage = (char*)"\ Mzscheme Options (available with -mzscheme)\n\ - -prefix - Set a prefix to be prepended to all names\n\ - -declaremodule - Create extension that declares a module\n\ - -noinit - Do not emit scheme_initialize, scheme_reload,\n\ - scheme_module_name functions\n"; + -prefix - Set a prefix to be prepended to all names\n\ + -declaremodule - Create extension that declares a module\n\ + -noinit - Do not emit scheme_initialize, scheme_reload,\n\ + scheme_module_name functions\n\ + -dynamic-load ,[library,...] - Do not link with these libraries, dynamic load\n\ + them\n\ +"; static String *fieldnames_tab = 0; static String *convert_tab = 0; @@ -29,6 +32,9 @@ static String *mangled_struct_name = 0; static char *prefix=0; static bool declaremodule = false; static bool noinit = false; +//DLOPEN PATCH +static char *load_libraries = NULL; +//DLOPEN PATCH static String *module=0; static char *mzscheme_path=(char*)"mzscheme"; static String *init_func_def = 0; @@ -79,6 +85,14 @@ public: noinit = true; Swig_mark_arg (i); } +// DLOPEN PATCH + else if (strcmp(argv[i],"-dynamic-load") == 0) { + load_libraries=new char[strlen(argv[i+1])+2]; + strcpy(load_libraries,argv[i+1]); + Swig_mark_arg(i++); + Swig_mark_arg(i); + } +// DLOPEN PATCH } } @@ -153,6 +167,13 @@ public: } Printf (f_init, "\treturn scheme_void;\n}\n"); Printf(f_init, "Scheme_Object *scheme_initialize(Scheme_Env *env) {\n"); + + // DLOPEN PATCH + if (load_libraries) { + Printf(f_init,"mz_set_dlopen_libraries(\"%s\");\n",load_libraries); + } + // DLOPEN PATCH + Printf(f_init, "\treturn scheme_reload(env);\n"); Printf (f_init, "}\n"); @@ -217,6 +238,15 @@ public: int numreq; String *overname = 0; + // PATCH DLOPEN + if (load_libraries) { + ParmList *parms=Getattr(n,"parms"); + SwigType *type=Getattr(n,"type"); + String *name=NewString("caller"); + Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cfunction_call(name,parms))); + } + // PATCH DLOPEN + // Make a wrapper name for this String *wname = Swig_name_wrapper(iname); if (Getattr(n,"sym:overloaded")) { @@ -255,11 +285,32 @@ public: numargs = emit_num_arguments(l); numreq = emit_num_required(l); + + // DLOPEN PATCH + /* Add the holder for the pointer to the function to be opened */ + if (load_libraries) { + Wrapper_add_local(f, "_function_loaded","static int _function_loaded=(1==0)"); + Wrapper_add_local(f, "_the_function", "static void *_the_function=NULL"); + { + String *parms=ParmList_protostr(l); + String *func=NewStringf("(*caller)(%s)",parms); + Wrapper_add_local(f,"caller",SwigType_lstr(d,func)); /*"(*caller)()"));*/ + } + } + // DLOPEN PATCH // adds local variables Wrapper_add_local(f, "lenv", "int lenv = 1"); Wrapper_add_local(f, "values", "Scheme_Object *values[MAXVALUES]"); + // DLOPEN PATCH + if (load_libraries) { + Printf(f->code,"if (!_function_loaded) { _the_function=mz_load_function(\"%s\");_function_loaded=(1==1); }\n",iname); + Printf(f->code,"if (!_the_function) { scheme_signal_error(\"Cannot load C function '%s'\"); }\n",iname); + Printf(f->code,"caller=_the_function;\n"); + } + // DLOPEN PATCH + // Now write code to extract the parameters (this is super ugly) for (i = 0, p = l; i < numargs; i++) {