diff --git a/CHANGES.current b/CHANGES.current index 66f217d31..66201b2eb 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,14 @@ Version 1.3.25 (In progress) ============================ +02/23/2005: wuzzeb (John Lenz) + Added -external-runtime argument. This argument is used to dump + out all the code needed for external access to the runtime system, + and it replaces including the files directly. This change adds + two new virtual functions to the Language class, which are used + to find the language specific runtime code. I also updated + all languages that use the runtime to implement these two functions. + 02/22/2005: mmatus Fix %template + private error SF#1099976. diff --git a/Doc/Devel/runtime.txt b/Doc/Devel/runtime.txt index b759a8243..46993cc70 100644 --- a/Doc/Devel/runtime.txt +++ b/Doc/Devel/runtime.txt @@ -3,7 +3,7 @@ needs to implement to take advantage of the run time type system. I assume you have read the run-time section of the Typemaps chapter in the SWIG documentation. -Last updated: January 23, 2005 +Last updated: February 23, 2005 The file we are concerned with here should be named langrun.swg. A good example of a simple file is the Lib/mzscheme/mzrun.swg file. First, a few requirements @@ -31,6 +31,13 @@ these function names 6) You need to call void SWIG_InitializeModule(void *clientdata) from your init function. +7) You need to implement the runtimeCode() and defaultExternalRuntimeFilename() +functions inside module.cxx. runtimeCode should return all the language +specific runtime code as a string, and defaultExternalRuntimeFilename should +return a string for the default name of the external runtime header. This is +usually "swigpyrun.h", where "py" is replaced by the language name. These +two functions are used by the -external-runtime argument. + ------------------------------------------------------------------------------- Required Functions ------------------------------------------------------------------------------- diff --git a/Doc/Manual/Modules.html b/Doc/Manual/Modules.html index 77ff39bc8..7df7643d2 100644 --- a/Doc/Manual/Modules.html +++ b/Doc/Manual/Modules.html @@ -75,44 +75,28 @@ languages provide. One solution is to load all modules before spawning any thre the functions SWIG_TypeQuery, SWIG_NewPointerObj, and others sometimes need to be called. Calling these functions from a typemap is supported, since the typemap code is embedded into the _wrap.c file, which has those declerations available. If you need -to call the SWIG run-time functions from another C file, there are three headers you need -to include. They are located in the Lib directory in the SWIG source, or wherever the -SWIG Library was installed. You can see the current library path by running -swig -swiglib.

+to call the SWIG run-time functions from another C file, there is one header you need +to include. To generate the header that needs to be included, run the following command:
-#include <swigrun.swg>
-#include <python/pyrun.swg>  /* Or other header, see below */
-#include <runtime.swg>
+$ swig -python -external-runtime <filename>
 
-

After including these three headers, your code should be able to call SWIG_TypeQuery, +

The filename argument is optional and if it is not passed, then the default filename will +be something like swigpyrun.h, depending on the language. This header file should +be treated like any of the other _wrap.c output files, and should be regenerated when the +_wrap files are. After including this header, your code will be able to call SWIG_TypeQuery, SWIG_NewPointerObj, SWIG_ConvertPtr and others. The exact argument paramaters for these functions might differ between language modules; please check the language module chapters for more information.

-

Inside these headers the functions are declared static and are included inline into the file, +

Inside this header the functions are declared static and are included inline into the file, and thus the file does not need to be linked against any SWIG libraries or code (you might still need to link against the language libraries like libpython-2.3). Data is shared between this -file and the _wrap.c files through a global variable in the wrapping language. It is also -possible to copy these three header files into your own package for distribution along with -the generated wrapper files, so that you can distribute a package that can be compiled -without SWIG installed (this works because the header files are self contained, and do not -need to link with anything).

- -

The headers that should be included in place of the #include <python/pyrun.swg> -for the different language modules are:

- +file and the _wrap.c files through a global variable in the scripting language. It is also +possible to copy this header file along with the generated wrapper files into your own package, +so that you can distribute a package that can be compiled without SWIG installed (this works +because the header file is self contained, and does not need to link with anything).

15.3 A word of caution about static libraries

diff --git a/Lib/runtime.swg b/Lib/runtime.swg index 750473d52..b4910a717 100644 --- a/Lib/runtime.swg +++ b/Lib/runtime.swg @@ -1,17 +1,9 @@ /* -----------------------------------------------------------------------------* Standard SWIG API for use inside user code. - You need to include in your code as follow: - -#include // or using your favorite language -#include -#include // or using your favorite language -#include - - For perl, the following -#include -#include -#include + Don't include this file directly, run the command + swig -python -external-runtime + Also, read the Modules chapter of the SWIG Manual. * -----------------------------------------------------------------------------*/ diff --git a/Source/Modules/chicken.cxx b/Source/Modules/chicken.cxx index da5dec9e0..5be35db8f 100644 --- a/Source/Modules/chicken.cxx +++ b/Source/Modules/chicken.cxx @@ -93,6 +93,9 @@ protected: String *chickenNameMapping(String *, String_or_char *); String *chickenPrimitiveName(String *); + + String *runtimeCode(); + String *defaultExternalRuntimeFilename(); }; /* ----------------------------------------------------------------------- @@ -1329,3 +1332,15 @@ CHICKEN::validIdentifier(String *s) } return n; } + + String *CHICKEN::runtimeCode() { + String *s = Swig_include_sys("chickenrun.swg"); + if (!s) { + Printf(stderr, "*** Unable to open 'chickenrun.swg'\n"); + s = NewString(""); + } + } + + String *CHICKEN::defaultExternalRuntimeFilename() { + return NewString("swigchickenrun.h"); + } diff --git a/Source/Modules/guile.cxx b/Source/Modules/guile.cxx index 23c24e9a7..3dee99b48 100644 --- a/Source/Modules/guile.cxx +++ b/Source/Modules/guile.cxx @@ -1772,6 +1772,32 @@ public: } return 1; } + + String *runtimeCode() { + String *s; + if (use_scm_interface) { + s = Swig_include_sys("guile_scm_run.swg"); + if (!s) { + Printf(stderr, "*** Unable to open 'guile_scm_run.swg"); + s = NewString(""); + } + } else { + s = Swig_include_sys("guile_gh_run.swg"); + if (!s) { + Printf(stderr, "*** Unable to open 'guile_gh_run.swg"); + s = NewString(""); + } + } + return s; + } + + String *defaultExternalRuntimeFilename() { + if (use_scm_interface) { + return NewString("swigguilerun.h"); + } else { + return NewString("swigguileghrun.h"); + } + } }; /* ----------------------------------------------------------------------------- diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index ac53eddb1..7f8ba656a 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -2915,3 +2915,11 @@ int Language::is_assignable(Node *n) } return 1; } + +String *Language::runtimeCode() { + return NewString(""); +} + +String *Language::defaultExternalRuntimeFilename() { + return 0; +} diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx index b2776a7f3..737ce067b 100644 --- a/Source/Modules/main.cxx +++ b/Source/Modules/main.cxx @@ -128,6 +128,8 @@ static DOH *libfiles = 0; static DOH *cpps = 0 ; static String *dependencies_file = 0; static File *f_dependencies_file = 0; +static int external_runtime = 0; +static String *external_runtime_name = 0; // ----------------------------------------------------------------------------- // check_suffix(char *name) @@ -269,6 +271,56 @@ void SWIG_getfeatures(const char *c) Delete(name); } +/* This function handles the -external-runtime command option */ +static void SWIG_dump_runtime() { + String *outfile; + File *runtime; + String *s; + + outfile = external_runtime_name; + if (!outfile) { + outfile = lang->defaultExternalRuntimeFilename(); + if (!outfile) { + Printf(stderr, "*** Please provide a filename for the external runtime\n"); + SWIG_exit(EXIT_FAILURE); + } + } + + runtime = NewFile(outfile, "w"); + if (!runtime) { + Printf(stderr, "*** Unable to open '%s'\n", outfile); + Close(runtime); + SWIG_exit(EXIT_FAILURE); + } + + Swig_banner(runtime); + + s = Swig_include_sys("swigrun.swg"); + if (!s) { + Printf(stderr, "*** Unable to open 'swigrun.swg'\n"); + Close(runtime); + SWIG_exit(EXIT_FAILURE); + } + Printf(runtime, "%s", s); + Delete(s); + + s = lang->runtimeCode(); + Printf(runtime, "%s", s); + Delete(s); + + s = Swig_include_sys("runtime.swg"); + if (!s) { + Printf(stderr, "*** Unable to open 'runtime.swg'\n"); + Close(runtime); + SWIG_exit(EXIT_FAILURE); + } + Printf(runtime, "%s", s); + Delete(s); + + Close(runtime); + SWIG_exit(EXIT_SUCCESS); +} + void SWIG_getoptions(int argc, char *argv[]) { int i; @@ -341,6 +393,14 @@ void SWIG_getoptions(int argc, char *argv[]) Swig_mark_arg(i); Swig_warning(WARN_DEPRECATED_OPTC, "SWIG",1, "-c, -runtime, -noruntime command line options are deprecated.\n"); SwigRuntime = 2; + } else if (strcmp(argv[i], "-external-runtime") == 0) { + external_runtime = 1; + Swig_mark_arg(i); + if (argv[i+1]) { + external_runtime_name = NewString(argv[i+1]); + Swig_mark_arg(i+1); + i++; + } } else if ((strcmp(argv[i],"-make_default") == 0) || (strcmp(argv[i],"-makedefault") == 0)) { GenerateDefault = 1; Swig_mark_arg(i); @@ -645,7 +705,8 @@ int SWIG_main(int argc, char *argv[], Language *l) { } // Check all of the options to make sure we're cool. - Swig_check_options(); + // Don't check for an input file if -external-runtime is passed + Swig_check_options(external_runtime ? 0 : 1); install_opts(argc, argv); @@ -674,6 +735,10 @@ int SWIG_main(int argc, char *argv[], Language *l) { } } + // handle the -external-runtime argument + if (external_runtime) + SWIG_dump_runtime(); + // If we made it this far, looks good. go for it.... input_file = argv[argc-1]; diff --git a/Source/Modules/mzscheme.cxx b/Source/Modules/mzscheme.cxx index 64408315c..b5abe0037 100644 --- a/Source/Modules/mzscheme.cxx +++ b/Source/Modules/mzscheme.cxx @@ -798,6 +798,19 @@ public: } return 1; } + + String *runtimeCode() { + String *s = Swig_include_sys("mzrun.swg"); + if (!s) { + Printf(stderr, "*** Unable to open 'mzrun.swg'\n"); + s = NewString(""); + } + return s; + } + + String *defaultExternalRuntimeFilename() { + return NewString("swigmzrun.h"); + } }; /* ----------------------------------------------------------------------------- diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx index ca1285706..9b5e4ec3f 100755 --- a/Source/Modules/ocaml.cxx +++ b/Source/Modules/ocaml.cxx @@ -1931,6 +1931,19 @@ public: } return SWIG_OK; } + + String *runtimeCode() { + String *s = Swig_include_sys("ocaml.swg"); + if (!s) { + Printf(stderr, "*** Unable to open 'ocaml.swg'\n"); + s = NewString(""); + } + return s; + } + + String *defaultExternalRuntimeFilename() { + return NewString("swigocamlrun.h"); + } }; /* ------------------------------------------------------------------------- diff --git a/Source/Modules/perl5.cxx b/Source/Modules/perl5.cxx index a502ceef1..99638fca8 100644 --- a/Source/Modules/perl5.cxx +++ b/Source/Modules/perl5.cxx @@ -1527,6 +1527,19 @@ public: } return SWIG_OK; } + + String *runtimeCode() { + String *s = Swig_include_sys("perlrun.swg"); + if (!s) { + Printf(stderr, "*** Unable to open 'perlrun.swg'\n"); + s = NewString(""); + } + return s; + } + + String *defaultExternalRuntimeFilename() { + return NewString("swigperlrun.h"); + } }; /* ----------------------------------------------------------------------------- diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index b66ef470c..b1b2e7a89 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -2470,6 +2470,20 @@ public: } return SWIG_OK; } + + virtual String *runtimeCode() { + String *s = Swig_include_sys("pyrun.swg"); + if (!s) { + Printf(stderr, "*** Unable to open 'pyrun.swg'\n"); + s = NewString(""); + } + return s; + } + + virtual String *defaultExternalRuntimeFilename() { + return NewString("swigpyrun.h"); + } + }; /* --------------------------------------------------------------- diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx index 0c7fb257c..3f3f54c8b 100644 --- a/Source/Modules/ruby.cxx +++ b/Source/Modules/ruby.cxx @@ -2470,6 +2470,19 @@ public: p = nextSibling(p); } } + + String *runtimeCode() { + String *s = Swig_include_sys("rubydef.swg"); + if (!s) { + Printf(stderr, "*** Unable to open 'rubydef.swg'\n"); + s = NewString(""); + } + return s; + } + + String *defaultExternalRuntimeFilename() { + return NewString("swigrubyrun.h"); + } }; /* class RUBY */ /* ----------------------------------------------------------------------------- diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h index 6687bc1e9..5deb48013 100644 --- a/Source/Modules/swigmod.h +++ b/Source/Modules/swigmod.h @@ -224,6 +224,8 @@ public: virtual Node *enumLookup(SwigType *s); /* Enum lookup */ virtual int abstractClassTest(Node *n); /* Is class really abstract? */ virtual int is_assignable(Node *n); /* Is variable assignable? */ + virtual String *runtimeCode(); /* returns the language specific runtime code */ + virtual String *defaultExternalRuntimeFilename(); /* the default filename for the external runtime */ /* Allow director related code generation */ void allow_directors(int val = 1); diff --git a/Source/Modules/tcl8.cxx b/Source/Modules/tcl8.cxx index a4ac2459b..681b96fd4 100644 --- a/Source/Modules/tcl8.cxx +++ b/Source/Modules/tcl8.cxx @@ -1219,6 +1219,19 @@ public: } return Char(temp); } + + String *runtimeCode() { + String *s = Swig_include_sys("swigtcl8.swg"); + if (!s) { + Printf(stderr, "*** Unable to open 'swigtcl8.swg'\n"); + s = NewString(""); + } + return s; + } + + String *defaultExternalRuntimeFilename() { + return NewString("swigtclrun.h"); + } }; /* ---------------------------------------------------------------------- diff --git a/Source/Swig/getopt.c b/Source/Swig/getopt.c index 77f53cf9b..2beb9a526 100644 --- a/Source/Swig/getopt.c +++ b/Source/Swig/getopt.c @@ -79,11 +79,12 @@ Swig_check_marked(int n) { * ----------------------------------------------------------------------------- */ void -Swig_check_options() { +Swig_check_options(int check_input) { int error = 0; int i; + int max = check_input ? numargs - 1 : numargs; assert(marked); - for (i = 1; i < numargs-1; i++) { + for (i = 1; i < max; i++) { if (!marked[i]) { Printf(stderr,"swig error : Unrecognized option %s\n", args[i]); error=1; @@ -93,7 +94,7 @@ Swig_check_options() { Printf(stderr,"Use 'swig -help' for available options.\n"); exit(1); } - if (marked[numargs-1]) { + if (check_input && marked[numargs-1]) { Printf(stderr,"Must specify an input file. Use -help for available options.\n"); exit(1); } diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index 357b4e06c..afc54d762 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -132,7 +132,7 @@ extern char *Swig_file_dirname(const String_or_char *filename); extern void Swig_init_args(int argc, char **argv); extern void Swig_mark_arg(int n); extern int Swig_check_marked(int n); -extern void Swig_check_options(); +extern void Swig_check_options(int check_input); extern void Swig_arg_error(); /* --- Scanner Interface --- */ diff --git a/Source/Swig/swig.i b/Source/Swig/swig.i index 33d174ddf..a04f5339b 100644 --- a/Source/Swig/swig.i +++ b/Source/Swig/swig.i @@ -723,7 +723,7 @@ extern DOH *Swig_include(DOH *name); extern void Swig_init_args(int argc, char **argv); extern void Swig_mark_arg(int n); -extern void Swig_check_options(); +extern void Swig_check_options(int check_input); extern void Swig_arg_error(); %section "Miscelaneous", after