From 4ac3c87a299368e22151bac3cae11e62cf23c730 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Wed, 20 Jul 2022 15:05:21 +1200 Subject: [PATCH] Sort out predefined SWIG-specific macros Ensure that SWIG_VERSION is defined both at SWIG-time and in the generated C/C++ wrapper code (it was only defined in the wrapper for some target languages previously). SWIGGO and SWIGJAVASCRIPT are now defined in the generated wrappers to match behaviour for all other target languages. Stop defining SWIGVERSION in the wrapper. This only happened as a side-effect of how SWIG_VERSION was defined but was never documented and is redundant. The new testcase also checks that SWIG is defined at SWIG-time but not in the generated wrapper, and that exactly one of a list of target-language specific macros is defined. Fixes #1050 --- CHANGES.current | 11 +++++++ Doc/Manual/Preprocessor.html | 8 +++++ Examples/test-suite/common.mk | 1 + Examples/test-suite/preproc_predefined.h | 27 ++++++++++++++++ Examples/test-suite/preproc_predefined.i | 40 ++++++++++++++++++++++++ Lib/csharp/csharp.swg | 2 ++ Lib/go/go.swg | 2 ++ Lib/guile/guile.i | 2 ++ Lib/java/java.swg | 2 ++ Lib/lua/lua.swg | 2 ++ Lib/mzscheme/mzscheme.swg | 2 ++ Lib/ocaml/ocaml.i | 2 ++ Lib/php/php.swg | 2 ++ Lib/typemaps/README | 1 + Lib/typemaps/swigmacros.swg | 10 +----- Lib/typemaps/swigversion.swg | 17 ++++++++++ Source/Modules/go.cxx | 2 ++ Source/Modules/javascript.cxx | 4 +++ 18 files changed, 128 insertions(+), 9 deletions(-) create mode 100644 Examples/test-suite/preproc_predefined.h create mode 100644 Examples/test-suite/preproc_predefined.i create mode 100644 Lib/typemaps/swigversion.swg diff --git a/CHANGES.current b/CHANGES.current index bfe3f8b0a..921441645 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -7,6 +7,17 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/ Version 4.1.0 (in progress) =========================== +2022-10-04: olly + #1050 Consistently define SWIG_VERSION both at SWIG-time and in + the generated wrapper. Best practice remains to check at SWIG-time + where possible because that results in smaller generated wrapper + sources. + + SWIGGO and SWIGJAVASCRIPT are now defined in the generated wrappers + to match behaviour for all other target languages. + + The undocumented SWIGVERSION macro is no longer defined. + 2022-09-29: olly #2303 SWIG's internal hash tables now use a better hash function. diff --git a/Doc/Manual/Preprocessor.html b/Doc/Manual/Preprocessor.html index 0d5cc6300..c612c56ce 100644 --- a/Doc/Manual/Preprocessor.html +++ b/Doc/Manual/Preprocessor.html @@ -147,6 +147,14 @@ SWIGTCL Defined when using Tcl SWIGXML Defined when using XML +

+SWIG also defines SWIG_VERSION and a target language macro in +the generated wrapper file (since SWIG 4.2.0 - in older versions these +were defined for some target languages but this wasn't consistent). Best +practice is to use SWIG-time conditional checks because that results in smaller +generated wrapper sources. +

+

In addition, SWIG defines the following set of standard C/C++ macros:

diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index da90dd9fd..a308d53c2 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -788,6 +788,7 @@ C_TEST_CASES += \ preproc_gcc_output \ preproc_include \ preproc_line_file \ + preproc_predefined \ register_par \ ret_by_value \ simple_array \ diff --git a/Examples/test-suite/preproc_predefined.h b/Examples/test-suite/preproc_predefined.h new file mode 100644 index 000000000..8d6b6ee28 --- /dev/null +++ b/Examples/test-suite/preproc_predefined.h @@ -0,0 +1,27 @@ +/* This list will need updating when new target languages are added. */ +#if (0\ + +defined(SWIGCSHARP)\ + +defined(SWIGD)\ + +defined(SWIGGO)\ + +defined(SWIGGUILE)\ + +defined(SWIGJAVA)\ + +defined(SWIGJAVASCRIPT)\ + +defined(SWIGLUA)\ + +defined(SWIGMZSCHEME)\ + +defined(SWIGOCAML)\ + +defined(SWIGOCTAVE)\ + +defined(SWIGPERL)\ + +defined(SWIGPHP)\ + +defined(SWIGPYTHON)\ + +defined(SWIGR)\ + +defined(SWIGRUBY)\ + +defined(SWIGSCILAB)\ + +defined(SWIGTCL)\ + +defined(SWIGXML)\ + ) != 1 +# ifdef SWIG +# error Did not detect exactly one target-language-specific macro defined at SWIG time. +# else +# error Did not detect exactly one target-language-specific macro defined in the generated wrapper. +# endif +#endif diff --git a/Examples/test-suite/preproc_predefined.i b/Examples/test-suite/preproc_predefined.i new file mode 100644 index 000000000..7db5352f5 --- /dev/null +++ b/Examples/test-suite/preproc_predefined.i @@ -0,0 +1,40 @@ +%module preproc_predefined + +/* Test that SWIG_VERSION is defined at SWIG-time and in the wrapper. */ +#ifndef SWIG_VERSION +# error SWIG_VERSION not defined at SWIG-time +#endif +%{ +#ifndef SWIG_VERSION +# error SWIG_VERSION not defined in the generated wrapper +#endif +%} + +/* Test that SWIGVERSION is NOT defined at SWIG-time or in the wrapper. + * It used to be defined in the wrapper as a side-effect of how SWIG_VERSION + * was defined in the wrapper but was never documented and is redundant. + */ +#ifdef SWIGVERSION +# error SWIGVERSION should not be defined at SWIG-time +#endif +%{ +#ifdef SWIGVERSION +# error SWIGVERSION should not be defined in the generated wrapper +#endif +%} + +/* Test that SWIG is defined at SWIG-time but not in the wrapper. */ +#ifndef SWIG +# error SWIG not defined at SWIG-time +#endif +%{ +#ifdef SWIG +# error SWIG should not be defined in the generated wrapper +#endif +%} + +/* Test that SWIGxxx is defined at SWIG-time and in the wrapper. */ +%include "preproc_predefined.h" +%{ +#include "preproc_predefined.h" +%} diff --git a/Lib/csharp/csharp.swg b/Lib/csharp/csharp.swg index 1f80d12a1..8514a7705 100644 --- a/Lib/csharp/csharp.swg +++ b/Lib/csharp/csharp.swg @@ -4,6 +4,8 @@ * C# typemaps * ----------------------------------------------------------------------------- */ +%include + %include /* The ctype, imtype and cstype typemaps work together and so there should be one of each. diff --git a/Lib/go/go.swg b/Lib/go/go.swg index 348ae5f0d..47486ab75 100644 --- a/Lib/go/go.swg +++ b/Lib/go/go.swg @@ -4,6 +4,8 @@ * Go configuration module. * ------------------------------------------------------------ */ +%include + %include /* Code insertion directives */ diff --git a/Lib/guile/guile.i b/Lib/guile/guile.i index ef270d74b..10438f483 100644 --- a/Lib/guile/guile.i +++ b/Lib/guile/guile.i @@ -4,6 +4,8 @@ * SWIG Configuration File for Guile. * ----------------------------------------------------------------------------- */ +%include + /* Macro for inserting Scheme code into the stub */ #define %scheme %insert("scheme") #define %goops %insert("goops") diff --git a/Lib/java/java.swg b/Lib/java/java.swg index 8719818bb..28eb8fd0d 100644 --- a/Lib/java/java.swg +++ b/Lib/java/java.swg @@ -4,6 +4,8 @@ * Java typemaps * ----------------------------------------------------------------------------- */ +%include + %include /* The jni, jtype and jstype typemaps work together and so there should be one of each. diff --git a/Lib/lua/lua.swg b/Lib/lua/lua.swg index 12c635d77..263c3966f 100644 --- a/Lib/lua/lua.swg +++ b/Lib/lua/lua.swg @@ -5,6 +5,8 @@ * This file is parsed by SWIG before reading any other interface file. * ----------------------------------------------------------------------------- */ +%include + /* ----------------------------------------------------------------------------- * includes * ----------------------------------------------------------------------------- */ diff --git a/Lib/mzscheme/mzscheme.swg b/Lib/mzscheme/mzscheme.swg index f45c87250..8ded91f3e 100644 --- a/Lib/mzscheme/mzscheme.swg +++ b/Lib/mzscheme/mzscheme.swg @@ -5,6 +5,8 @@ * This file is parsed by SWIG before reading any other interface file. * ----------------------------------------------------------------------------- */ +%include + /* Include headers */ %runtime "swigrun.swg" // Common C API type-checking code %runtime "swigerrors.swg" // SWIG errors diff --git a/Lib/ocaml/ocaml.i b/Lib/ocaml/ocaml.i index cc26d1859..117d0a9b5 100644 --- a/Lib/ocaml/ocaml.i +++ b/Lib/ocaml/ocaml.i @@ -4,6 +4,8 @@ * SWIG Configuration File for Ocaml * ----------------------------------------------------------------------------- */ +%include + /* Insert common stuff */ %insert(runtime) "swigrun.swg" diff --git a/Lib/php/php.swg b/Lib/php/php.swg index 04b7075b7..b22166593 100644 --- a/Lib/php/php.swg +++ b/Lib/php/php.swg @@ -4,6 +4,8 @@ * PHP configuration file * ----------------------------------------------------------------------------- */ +%include + // Default to generating PHP type declarations (for PHP >= 8) except for // cases which are liable to cause compatibility issues with existing // bindings. diff --git a/Lib/typemaps/README b/Lib/typemaps/README index 65134578d..22a0fc0bb 100644 --- a/Lib/typemaps/README +++ b/Lib/typemaps/README @@ -48,6 +48,7 @@ std_strings.swg Common macros to implemented the std::string/std::wstring typem strings.swg Common macros and typemaps for string and wstring (char *, wchar_t *) swigmacros.swg Basic macros +swigversion.swg Define SWIG_VERSION fragments.swg Macros for fragment manipulations diff --git a/Lib/typemaps/swigmacros.swg b/Lib/typemaps/swigmacros.swg index 687b0680e..7db6871d4 100644 --- a/Lib/typemaps/swigmacros.swg +++ b/Lib/typemaps/swigmacros.swg @@ -109,15 +109,7 @@ nocppval #endif %enddef -/* insert the SWIGVERSION in the interface and the wrapper code */ -#if SWIG_VERSION -%insert("header") { -%define_as(SWIGVERSION, SWIG_VERSION) -%#define SWIG_VERSION SWIGVERSION -} -#endif - - +%include /* ----------------------------------------------------------------------------- * Casting operators diff --git a/Lib/typemaps/swigversion.swg b/Lib/typemaps/swigversion.swg new file mode 100644 index 000000000..18f897cad --- /dev/null +++ b/Lib/typemaps/swigversion.swg @@ -0,0 +1,17 @@ +/* ----------------------------------------------------------------------------- + * Define SWIG_VERSION + * ----------------------------------------------------------------------------- */ + +/* Define SWIG_VERSION in the interface and the wrapper code. + * + * Best practice is to use SWIG-time checks for SWIG_VERSION, but SWIG_VERSION + * was unintentionally defined like this for many years, and while it was never + * documented there are likely user interface files which rely on it. + */ +%define %define_swig_version_()%#define SWIG_VERSION_ SWIG_VERSION %enddef +%insert("header") { +%define_swig_version_() +%#define SWIG_VERSION SWIG_VERSION_ +%#undef SWIG_VERSION_ +} +#undef %define_swig_version_ diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx index 1692e905a..7f0ccbe8b 100644 --- a/Source/Modules/go.cxx +++ b/Source/Modules/go.cxx @@ -515,6 +515,8 @@ private: } Printf(f_c_runtime, "#define SWIGMODULE %s\n", module); + Printf(f_c_runtime, "#ifndef SWIGGO\n#define SWIGGO\n#endif\n\n"); + if (gccgo_flag) { Printf(f_c_runtime, "#define SWIGGO_PREFIX %s\n", go_prefix); } diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index b17c5e503..e6e47e3f3 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1615,6 +1615,8 @@ int JSCEmitter::initialize(Node *n) { Swig_banner(f_wrap_cpp); + Printf(f_runtime, "#ifndef SWIGJAVASCRIPT\n#define SWIGJAVASCRIPT\n#endif\n\n"); + return SWIG_OK; } @@ -1945,6 +1947,8 @@ int V8Emitter::initialize(Node *n) { Swig_banner(f_wrap_cpp); + Printf(f_runtime, "#ifndef SWIGJAVASCRIPT\n#define SWIGJAVASCRIPT\n#endif\n\n"); + return SWIG_OK; }