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
This commit is contained in:
Olly Betts 2022-07-20 15:05:21 +12:00
commit 4ac3c87a29
18 changed files with 128 additions and 9 deletions

View file

@ -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.

View file

@ -147,6 +147,14 @@ SWIGTCL Defined when using Tcl
SWIGXML Defined when using XML
</pre></div>
<p>
SWIG also defines <tt>SWIG_VERSION</tt> 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.
</p>
<p>
In addition, SWIG defines the following set of standard C/C++ macros:
</p>

View file

@ -788,6 +788,7 @@ C_TEST_CASES += \
preproc_gcc_output \
preproc_include \
preproc_line_file \
preproc_predefined \
register_par \
ret_by_value \
simple_array \

View file

@ -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

View file

@ -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"
%}

View file

@ -4,6 +4,8 @@
* C# typemaps
* ----------------------------------------------------------------------------- */
%include <typemaps/swigversion.swg>
%include <csharphead.swg>
/* The ctype, imtype and cstype typemaps work together and so there should be one of each.

View file

@ -4,6 +4,8 @@
* Go configuration module.
* ------------------------------------------------------------ */
%include <typemaps/swigversion.swg>
%include <gostring.swg>
/* Code insertion directives */

View file

@ -4,6 +4,8 @@
* SWIG Configuration File for Guile.
* ----------------------------------------------------------------------------- */
%include <typemaps/swigversion.swg>
/* Macro for inserting Scheme code into the stub */
#define %scheme %insert("scheme")
#define %goops %insert("goops")

View file

@ -4,6 +4,8 @@
* Java typemaps
* ----------------------------------------------------------------------------- */
%include <typemaps/swigversion.swg>
%include <javahead.swg>
/* The jni, jtype and jstype typemaps work together and so there should be one of each.

View file

@ -5,6 +5,8 @@
* This file is parsed by SWIG before reading any other interface file.
* ----------------------------------------------------------------------------- */
%include <typemaps/swigversion.swg>
/* -----------------------------------------------------------------------------
* includes
* ----------------------------------------------------------------------------- */

View file

@ -5,6 +5,8 @@
* This file is parsed by SWIG before reading any other interface file.
* ----------------------------------------------------------------------------- */
%include <typemaps/swigversion.swg>
/* Include headers */
%runtime "swigrun.swg" // Common C API type-checking code
%runtime "swigerrors.swg" // SWIG errors

View file

@ -4,6 +4,8 @@
* SWIG Configuration File for Ocaml
* ----------------------------------------------------------------------------- */
%include <typemaps/swigversion.swg>
/* Insert common stuff */
%insert(runtime) "swigrun.swg"

View file

@ -4,6 +4,8 @@
* PHP configuration file
* ----------------------------------------------------------------------------- */
%include <typemaps/swigversion.swg>
// Default to generating PHP type declarations (for PHP >= 8) except for
// cases which are liable to cause compatibility issues with existing
// bindings.

View file

@ -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

View file

@ -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 <typemaps/swigversion.swg>
/* -----------------------------------------------------------------------------
* Casting operators

View file

@ -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_

View file

@ -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);
}

View file

@ -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;
}