diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a88c7195e9e..57d88b944c0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,6 +34,10 @@ jobs: include: - SWIGLANG: "" CPPFLAGS: "-DDOH_POISON" + - SWIGLANG: "" + GCC: 7 + CPPSTD: c++98 + CSTD: c90 - SWIGLANG: "" GCC: 7 - SWIGLANG: "" @@ -110,6 +114,9 @@ jobs: VER: '5.3' - SWIGLANG: octave CPPSTD: c++11 + - SWIGLANG: octave + os: ubuntu-22.04 # Octave 6.4.0 + CPPSTD: c++11 - SWIGLANG: perl5 - SWIGLANG: php VER: '8.0' @@ -184,7 +191,7 @@ jobs: CPPSTD: c++11 - SWIGLANG: ruby CPPSTD: c++11 - VER: '3.2' + VER: '3.2.2' # import_fragments testcase started to fail on upgrade to 3.2.3, see https://github.com/swig/swig/issues/2800 - SWIGLANG: scilab VER: '5.5.2' - SWIGLANG: scilab @@ -336,11 +343,11 @@ jobs: # Experimental languages (these are allowed to fail) - SWIGLANG: mzscheme continue-on-error: true - #- SWIGLANG: ocaml - # CPPSTD: c++17 - # GCC: 13 - # continue-on-error: true - # os: ubuntu-18.04 # ocaml-4.08 in ubuntu-20.04 not yet working + - SWIGLANG: ocaml + CPPSTD: c++17 + GCC: 13 + os: ubuntu-22.04 # ocaml-4.08 in ubuntu-20.04 doesn't work + continue-on-error: true # Run all of them, as opposed to aborting when one fails fail-fast: false @@ -357,9 +364,21 @@ jobs: EXTRA_CXXFLAGS: ${{ matrix.EXTRA_CXXFLAGS }} steps: + - name: Machine Info + run: | + echo "nproc..." + nproc --all + echo "uname..." + uname --all + echo "meminfo..." + cat /proc/meminfo + echo "lsb-release..." + cat /etc/lsb-release + - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: + show-progress: false submodules: recursive - name: Install CCache @@ -470,6 +489,16 @@ jobs: unset SWIGJOBS esac ;; + ocaml) + # `make check-ocaml-test-suite` fails with parallel make with: + # + # File "swig.ml", line 1: + # Error: Could not find the .cmi file for interface swig.mli. + # + # Apparently we ought to be using `ocamldep` to generate make + # dependencies. + unset SWIGJOBS + ;; esac # Stricter compile flags for examples. Various headers and SWIG generated code prevents full use of -pedantic. diff --git a/.github/workflows/nuget.yml b/.github/workflows/nuget.yml index d3fe7006b02..05eb57addbc 100644 --- a/.github/workflows/nuget.yml +++ b/.github/workflows/nuget.yml @@ -23,8 +23,9 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: + show-progress: false submodules: recursive - name: Install Dependencies diff --git a/ANNOUNCE b/ANNOUNCE index f45475f3224..dfc1cf7df1f 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,8 +1,8 @@ -*** ANNOUNCE: SWIG 4.2.0 (30 Dec 2023) *** +*** ANNOUNCE: SWIG 4.2.1 (24 Feb 2024) *** https://www.swig.org -We're pleased to announce SWIG-4.2.0, the latest SWIG release. +We're pleased to announce SWIG-4.2.1, the latest SWIG release. What is SWIG? ============= @@ -25,11 +25,11 @@ Availability ============ The release is available for download on Sourceforge at - https://prdownloads.sourceforge.net/swig/swig-4.2.0.tar.gz + https://prdownloads.sourceforge.net/swig/swig-4.2.1.tar.gz A Windows version is also available at - https://prdownloads.sourceforge.net/swig/swigwin-4.2.0.zip + https://prdownloads.sourceforge.net/swig/swigwin-4.2.1.zip Please report problems with this release to the swig-devel mailing list, details at https://www.swig.org/mail.html. diff --git a/CHANGES b/CHANGES index ec61635ae37..ccd8a074802 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,1133 @@ See the RELEASENOTES file for a summary of changes in each release. Issue # numbers mentioned below can be found on Github. For more details, add the issue number to the end of the URL: https://github.com/swig/swig/issues/ +Version 4.2.0 (30 Dec 2023) +=========================== + +2023-12-24: degasus + [Python] #2494 Fix integer overflow / undefined behavior for python + castmode on sizeof(long)==8 platforms for implicit conversions around + edge cases of LONG_MAX and ULONG_MAX, for example: + + void as_l(long x); // C interface + + Usage from Python: + + lmaxd = math.nextafter(float(2**63), 0.0) # LONG_MAX == 2**63-1 + # Now below correctly raises a TypeError due to the overflow + as_l(math.nextafter(lmaxd, float('inf'))) + +2023-12-21: olly + [PHP] `%feature("php:allowdynamicproperties", 0) Foo;` is now handled as + the feature being off to match other boolean features. Previously + any value set was treated as on. + +2023-12-20: treitmayr + [Ruby] #2033 Fix missing checks for negative numbers when passing numbers + to unsigned long/unsigned long long C types. + +2023-12-20: crhilton + [C#] #2722 Add support the "cs:defaultargs" feature. + + This adds a way to wrap C++ functions that have default arguments + with an equivalent C# function with default arguments, instead of + generating an overloaded C# method for each defaulted argument. + +2023-12-20: vadz, vadimcn, wangito33, wsfulton, clintonstimpson + [Python] #1613 #1687 #1727 #2190 #2727 #2428 Add support for the Python stable + ABI using default Python options. Code is generated that compiles when + setting the C macro Py_LIMITED_API to 0x03040000 (at C/C++ compile time). + Note that the -builtin, -fast (used by -O) options are not supported. + +2023-12-20: wsfulton + [Python] More efficient input string marshalling for Python 3. + + Previously a copy of a string was made while converting from a Python 3 + string to a char * or std::string. This copy is no longer needed making + string marshalling more efficient. Does not apply to the stable ABI + targetting Python < 3.10 where a copy is still required where the stable + ABI does not provide PyUnicode_AsUTF8AndSize. + +2023-12-20: wsfulton + #2190 Replace SWIG_Python_str_AsChar with SWIG_PyUnicode_AsUTF8AndSize. + + SWIG_Python_str_AsChar has undefined behaviour when Py_LIMITED_API is defined + as it returns a pointer to a string in a PyBytes object that no longer exists. + + SWIG_PyUnicode_AsUTF8AndSize is an efficient replacement, but requires a + different API and the caller to decrement the refcount on the intermediate + PyObject in the Py_LIMITED_API < 0x030A0000 implementation. The alternative + would have required copying the returned char * string as was done in a + previous implementation requiring a call to the defunct SWIG_Python_str_DelForPy3 + function. + + *** POTENTIAL INCOMPATIBILITY *** + +2023-12-14: PaulObermeier + [Tcl] #2730 Rename SWIG's Tcl_GetBoolFromObj() since Tcl 8.7 (TIP 618) + introduces a function with the same name. + + [Tcl] #2729 Use Tcl_GetString() instead of Tcl_GetStringFromObj(..., NULL) + for compatibility with Tcl 9. + +2023-12-03: olly + [Ocaml] Remove -suffix command line option which has emitted a + deprecation warning since SWIG 3.0.4 - if you want to specify + a different filename extension for generated C++ files use -cppext + instead, which works for all SWIG target language backends. + +2023-12-01: saiarcot895 + [Python] #2413 Prevent potential multi-threading crash; gracefully exit running + daemon threads on main thread exit. + +2023-11-24: wsfulton + Add support for parsing C++20 constexpr destructors. + +2023-11-19: olly + Fix handling of constant expressions containing < and > to not + drop parentheses around the subexpression as doing so can change + its value in some cases. + +2023-11-18: yasamoka, jmarrec + [Python] #2639 Add std_filesystem.i for wrapping std::filesystem::path + with pathlib.Path. + +2023-11-17: chrstphrchvz + [Tcl] #2711 Fix -Wmissing-braces warning in generated code. + +2023-11-17: chrstphrchvz + [Tcl] #2710 Stop using Tcl's CONST macro. It's no longer needed + and is set to be deprecated in Tcl 8.7, and removed in Tcl 9.0. + +2023-11-08: wsfulton + [C#] Replace empty() method with IsEmpty property for std::vector, std::list, std::map + containers for consistency across all containers. + + The empty() method is actually still wrapped, but as a private proxy method. For backwards + compatibility, the method can be made public again using %csmethodmodifiers for all + vectors as follows: + + %extend std::vector { + %csmethodmodifiers empty() const "public" + } + %include "std_vector.i" + + or alternatively for each individual %template instantiation as follows: + + %csmethodmodifiers std::vector::empty() const "public" + %template(VectorDouble) std::vector; + + + *** POTENTIAL INCOMPATIBILITY *** + +2023-11-08: wsfulton + [C#] Add std_unordered_set.i for wrapping std::std_unordered_set, implementing + C# System.Collections.Generic.ISet<>. + +2023-11-09: olly + #2591 SWIG now supports command line options -std=cXX and + -std=c++XX to specify the C/C++ standards version. The only effect + of these options is to set appropriate values for __STDC_VERSION__ + and __cplusplus respectively, which is useful if you're wrapping + headers which have preprocessor checks based on their values. + +2023-11-09: olly + SWIG now defines __STDC__ to 1 to match the behaviour of ISO C/C++ + compilers - previously it had an empty value. + + *** POTENTIAL INCOMPATIBILITY *** + +2023-11-09: olly + When -c++ is used, SWIG now defines __cplusplus to be 199711L (the + value for C++98) by default - previously its value was set to + __cplusplus. + + *** POTENTIAL INCOMPATIBILITY *** + +2023-11-08: emmenlau + #2480 [C#] Add std_unordered_map.i for wrapping std::std_unordered_map, implementing + C# System.Collections.Generic.IDictionary<>. + +2023-11-06: wsfulton + [D, Java] Add the dbegin option to the %module directive for generating code at + the beginning of every D file. Similarly javabegin for Java. This enables one + to add a common comment at the start of each D/Java file. + +2023-11-06: wsfulton + [C#] #2681 Support nullable reference types. A generic C# option to the + %module directive allows one to add in any code at the beginning of every + C# file. This can add the #nullable enable preprocessor directive at the beginning + of every C# file in order to enable nullable reference types as follows: + + %module(csbegin="#nullable enable\n") mymodule + +2023-10-21: wsfulton + [Python] #1783 Don't swallow all exceptions into a NotImplemented return + when wrapping operators which are marked with %pythonmaybecall. Corrects the + implementation of PEP 207. + +2023-10-18: wsfulton + [C#, D] #902 Use the C++11 enum base, that is, the underlying enum + type. + + For C#, it is used as the underlying type in the generated C# enum. + For D, it is used as the enum base type in the generated D enum. + +2023-10-16: wsfulton + #2687 Another using declarations fix for inheritance hierarchies more than + two deep and the using declarations are overloaded. Using declarations + from a base class' base were not available for use in the target + language when the using declaration was before a method declaration. + +2023-10-11: wsfulton + [C#, D, Go, Guile, Java, Javascript, Lua, Ocaml, R, Racket] #1680 + carrays.i library modified to use size_t instead of int for the functions + provided by %array_functions and %array_class. + + If the old types are required for backwards compatibility, use %apply to + restore the old types as follows: + + %include "carrays.i" + %apply int { size_t nelements, size_t index } + ... %array_functions and %array_class ... + %clear size_t nelements, size_t index; # To be safe in case used elsewhere + + *** POTENTIAL INCOMPATIBILITY *** + +2023-10-11: olly + [PHP] #2685 Fix testcase director_finalizer to work with PHP 8.3. + +2023-10-06: wsfulton + #2307 std::vector::capacity and std::vector::reserve signature changes. + + Java api changes from: + public long capacity() { ... } + public void reserve(long n) { ... } + to: + public int capacity() { ... } + public void reserve(int n) { ... } + to fit in with the usual Java convention of using int for container + indexing and sizing. + + The original api for std::vector::reserve can be also be made available via + %extend to add in an overloaded method as follows: + + %include + %extend std::vector { + void reserve(jlong n) throw (std::length_error, std::out_of_range) { + if (n < 0) + throw std::out_of_range("vector reserve size must be positive"); + self->reserve(n); + } + } + + This change is partially driven by the need to seamlessly support the full + 64-bit range for size_t generically, apart from the customisations for the + STL containers, by using: + + %apply unsigned long long { size_t }; + %apply const unsigned long long & { const size_t & }; + + *** POTENTIAL INCOMPATIBILITY *** + +2023-10-05: wsfulton + [C#] #2379 Defining SWIGWORDSIZE64 now applies the (unsigned) + long long typemaps to (unsigned) long for a better match on systems + where long is 64-bits. A new "Type mapping" section has been added into + the CSharp.html documentation covering this and marshalling of primitive + types. C (unsigned) long handling remains as is by default, that is, + marshall as 32-bit. + + The INPUT[], OUTPUT[], INOUT[], FIXED[] typemaps for long and unsigned long + in arrays_csharp.i can now be used and compiled on 64-bit platforms where + sizeof(long) != sizeof(int). Requires SWIGWORDSIZE64 to be defined. + +2023-09-27: wsfulton + [Java] #646 #649 Defining SWIGWORDSIZE64 now applies the (unsigned) + long long typemaps to (unsigned) long for a better match on systems + where long is 64-bits. + +2023-09-18: christophe-calmejane + #2631 C++17 std::map fix for values that are not default constructible. + Enhancements for all target languages except Python and Ruby. + +2023-09-14: mmomtchev + #2675 #2676 Temporary variable zero initialisation in the wrappers for + consistency with handling pointers. + +2023-09-11: emmenlau + #2394 Add support to preprocessor for true and false. Note that this + is for C++ not C. + +2023-09-11: wsfulton + [R] #2605 Complete transition to rtypecheck typemaps from hard coded + logic. Also see entry dated 2022-10-28 for swig-4.1.1. The rtypecheck + typemaps implement typechecking in R for each function parameter using + functions such as is.numeric, is.character, is.logical, is.null etc. + +2023-09-09: wsfulton + https://sourceforge.net/p/swig/bugs/919/ + + Fix incorrect variable setters being generated when wrapping arrays. + A setter is no longer generated if the type of the array members + are non-assignable. + +2023-09-09: wsfulton + Non-assignable detection fixes when wrapping const member variables. + Const member variables such as the following are non-assignable by + by default: + + char * const x; + const int x; + const int x[1]; + + but not: + + const char * x; + + Variable setters are not generated when wrapping these non-assignable + variables and classes containing such non-assignable variables. + +2023-09-07: wsfulton + Non-assignable detection fixes when wrapping rvalue reference variables. + Rvalue reference variables such as the following are non-assignable by + by default: + + X &&v; + + Variable setters are not generated when wrapping these non-assignable + variables and classes containing such non-assignable variables. + +2023-09-06: wsfulton + Non-assignable detection fixes when wrapping reference variables. + Reference variables such as the following are non-assignable by + by default: + + int &v; + + Variable setters are not generated when wrapping these non-assignable + variables and classes containing such non-assignable variables. + +2023-09-06: wsfulton + Assignment operator detection fixes when wrapping static member + variables. + +2023-09-06: wsfulton + #1416 Implicit assignment operator detection fixes. + + A class that does not have an explicit assignment operator does not + have an implicit assignment operator if a member variable is not + assignable. Similarly should one of the base classes also not be + assignable. Detection of these scenarios has been fixed so that when + wrapping a variable that is not assignable, a variable setter is not + generated in order to avoid a compiler error. + + Template instantiation via %template is required in order for this to + work for templates that are not assignable. + +2023-09-03: wsfulton + https://sourceforge.net/p/swig/bugs/1006/ + Fix incorrect variable setters being generated when the type of the + variable is not assignable, due to variable type inheriting a private + assignment operator further up the inheritance chain (further up than + the immediate base). + +2023-09-03: wsfulton + [Guile, Ocaml, Perl] Don't attempt to generate a setter when wrapping + variables which have a private assignment operator as assignment is not + possible. This now matches the behaviour of all the other target languages. + +2023-09-02: wsfulton + Fix problems wrapping deleted destructors. Derived classes are not + constructible, so don't attempt to generate default constructor or + copy constructor wrappers. + + struct StackOnly1 { + // Only constructible on the stack + ~StackOnly1() = delete; + }; + struct StackOnlyDerived1 : StackOnly1 { + // this class is not constructible due to deleted base destructor + }; + +2023-09-02: wsfulton + Fix %copyctor feature when used on classes with deleted copy constructors. + A default constructor wrapper was sometimes incorrectly generated. + +2023-09-02: wsfulton + #1644 Fix wrapping types passed by value where the type has a deleted + default constructor. + +2023-08-16: shadchin + [Python] #2665 Fix missing-field-initializers warning to provide support + for python-3.12. + +2023-08-09: olly + [Ruby] Remove -feature command line option which has been + deprecated since SWIG 1.3.32 in 2007. Use -initname instead. + +2023-08-06: wsfulton + Add support for using declarations to introduce templated member + methods and for inheriting templated constructors, such as: + + struct Base { + // templated constructor + template Base(const T &t, const char *s) {} + // templated member method + template void template_method(const T &t, const char *s) {} + }; + + %template(Base) Base::Base; + %template(template_method) Base::template_method; + + struct Derived : Base { + using Base::Base; + using Base::template_method; + }; + + Previously the templated methods and constructors were ignored and + not introduced into the Derived class. + +2023-08-04: wsfulton + Fix using declarations for inheritance hierarchies more than + two deep and the using declarations are overloaded. Using declarations + from a base class' base were not available for use in the target + language. For example in the code below, Using1::usingmethod(int i) + was not wrapped for use in Using3: + + struct Using1 { + protected: + void usingmethod(int i) {} + }; + struct Using2 : Using1 { + protected: + void usingmethod(int i, int j) {} + using Using1::usingmethod; + }; + struct Using3 : Using2 { + void usingmethod(int i, int j, int k) {} + using Using2::usingmethod; + }; + + Similarly for C++11 using declarations for inheriting constructors. + +2023-08-02: wsfulton + https://sourceforge.net/p/swig/bugs/932/ + Fix missing constructor generation due to abstract class test + failure when a method is declared in the class along with a + using declaration and the using declaration is declared before + the method that implemented the pure virtual method, such as: + + struct ConcreteDerived : AbstractBase { + ConcreteDerived() {} // was not wrapped + using AbstractBase::f; + virtual void f(int n) override {} + }; + +2023-08-02: olly + [PHP] Implement overloading between different integer types and + between double and float. + +2023-07-29: wsfulton + https://sourceforge.net/p/swig/bugs/678/ + Fix %copyctor used on class hierarchies with non-const copy + constructors. Previously SWIG always attempted to call a copy + constructor taking a const reference parameter instead of a + non-const reference parameter. + +2023-07-28: wsfulton + #2541 Fix overloading of templated constructors and %copyctor. + +2023-07-21: wsfulton + Don't generate a default constructor wrapper when a class has a + templated constructor, as there isn't actually an implied default + constructor. For example: + + struct TConstructor3 { + template TConstructor3(T val) {} + }; + + Previously wrappers were generated for a non-existent default + constructor which failed to compile. + +2023-07-15: wsfulton + C++11 using declarations for inheriting constructors has now been + extended to support the directors feature. + +2023-07-13: wsfulton + C++11 using declarations for inheriting constructors support now + also includes inheriting implicitly defined default constructors + from the base class. + +2023-07-04: wsfulton + #2641 Add support for C++11 using declarations for inheriting + constructors. + +2023-06-30: wsfulton + #2640 Fix syntax error parsing an expression which calls a function + with no parameters within additional brackets. + +2023-06-27: mmomtchev + [Javascript] #2545 New Javascript generator targeting the Node.js + binary stable ABI Node-API. + +2023-06-27: olly + [Java] Completely remove pragmas which were deprecated in 2002 and + have triggered an error since SWIG 2.0: + + moduleimport Use the moduleimports pragma + moduleinterface Use the moduleinterfaces pragma + modulemethodmodifiers Use %javamethodmodifiers + allshadowimport Use %typemap(javaimports) + allshadowcode Use %typemap(javacode) + allshadowbase Use %typemap(javabase) + allshadowinterface Use %typemap(javainterfaces) + allshadowclassmodifiers Use %typemap(javaclassmodifiers) + shadowcode Use %typemap(javacode) + shadowimport Use %typemap(javaimports) + shadowbase Use %typemap(javabase) + shadowinterface Use %typemap(javainterfaces) + shadowclassmodifiers Use %typemap(javaclassmodifiers) + +2023-06-24: wsfulton + #2616 https://sourceforge.net/p/swig/bugs/1102/ Fix directors and + allprotected mode and using declarations. Previously SWIG either + seg faulted or generated code that did not compile. + +2023-06-20: olly + #2486 Fix handling of template in array size, which was being + rejected by SWIG because the type string contains '<' not followed + by '('. Drop this check as it should be unnecessary now since the + fixes that ensure that template parameters are enclosed within + '<(' and ')>'. + +2023-06-16: olly + [Java] Remove deprecated command line options which have done + nothing except emit a deprecation message since 2002 or before: + + -jnic / -jnicpp JNI calling convention now automatic. + -nofinalize Use javafinalize typemap instead. + -proxy / -shadow Now on by default. + +2023-06-16: olly + [Guile] Drop support for -Linkage ltdlmod which was only useful + for Guile <= 1.4 which we no longer support. + +2023-06-15: olly + [Guile] The -gh and -scm command line options have been removed. + These have done nothing except emit a message since 2013 when + SWIG dropped support for generating bindings which used GH. + +2023-06-15: olly + Remove pointer.i from the SWIG library. It's been a dummy file + which has done nothing except %echo a deprecation message since + 2002. The replacement is cpointer.i. + +2023-06-15: olly + SWIG will no longer fall back to using the include path to find the + input file, which has been deprecated and emitted a warning since + SWIG 1.3.37 (2009-01-13). This makes the behaviour of SWIG the + same as C/C++ compilers and works with ccache. + +2023-06-15: olly + Remove features deprecated in SWIG 1.x and 2.x. Most of these have + emitted a deprecation warning or error for well over a decade and + have replacements with fewer shortcomings so we expect users will + have migrated away from them long ago, but in case you need + them replacements are noted below: + + %addmethods Use %extend instead. + %attribute_ref Use %attributeref instead (NB: If called with + 4 parameters, the 3rd and 4th need switching). + %disabledoc Use Doxygen support instead. + %doconly Use Doxygen support instead. + %enabledoc Use Doxygen support instead. + %except Use %exception instead. + %extern Use %import instead. + %localstyle Use Doxygen support instead. + %name Use %rename instead. + %new Use %newobject instead. + %out %apply OUTPUT typemap rule instead. + %readonly Use %immutable instead. + %readwrite Use %mutable instead. + %section Use Doxygen support instead. + %style Use Doxygen support instead. + %subsection Use Doxygen support instead. + %subsubsection Use Doxygen support instead. + %text Use Doxygen support instead. + %title Use Doxygen support instead. + %typemap(except) Use %exception instead. + %typemap(ignore) Use %typemap(in,numinputs=0) instead. + %val Use typemaps instead. + -debug_template Use -debug-template instead. + -debug_typemap Use -debug-typemap instead. + -dump_classes Use -debug-classes instead. + -dump_memory Use -debug-memory instead. + -dump_module Use -debug-module 4 instead. + -dump_parse_module Use -debug-module 1 instead. + -dump_parse_top Use -debug-top 1 instead. + -dump_tags Use -debug-tags instead. + -dump_top Use -debug-top 4 instead. + -dump_tree Use -debug-top 4 instead. + -dump_typedef Use -debug-typedef instead. + -dump_xml Use -xmlout /dev/stdout instead. + -make_default On by default since SWIG 1.3.7 (2001-09-03). + -makedefault On by default since SWIG 1.3.7 (2001-09-03). + -no_default Use %nodefaultctor/%nodedefaultdtor instead. + -nodefault Use %nodefaultctor/%nodedefaultdtor instead. + -noextern option On by default since SWIG 1.3.26 (2005-10-09). + -noruntime Type sharing happens via target lang global. + -runtime Type sharing happens via target lang global. + -show_templates Use -debug-template instead. + -tm_debug Use -debug-typemap instead. + -xml out.xml Use -xml -o out.xml instead. + BOTH typemap rule Use INOUT typemap rule instead. + SWIG_INTRUSIVE_PTR(PROXYCLASS, TYPE) + Use %intrusive_ptr(TYPE) instead. + SWIG_INTRUSIVE_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE) + Use %intrusive_ptr(TYPE) instead. + SWIG_INTRUSIVE_PTR_NO_WRAP(PROXYCLASS, TYPE) + Use %intrusive_ptr_no_wrap(TYPE) instead. + SWIG_INTRUSIVE_PTR_DERIVED_NO_WRAP(PROXYCLASS, BASECLASSTYPE, TYPE) + Use %intrusive_ptr_no_wrap(TYPE) instead. + SWIG_SHARED_PTR(PROXYCLASS, TYPE) + Use %shared_ptr(TYPE) instead. + SWIG_SHARED_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE...) + Use %shared_ptr(TYPE) instead. + SWIG_STD_VECTOR_SPECIALIZE(CSTYPE, CTYPE) + Use SWIG_STD_VECTOR_ENHANCED(CTYPE) instead. + SWIG_STD_VECTOR_SPECIALIZE_MINIMUM(CSTYPE, CTYPE) + No longer required - remove uses. + specialize_std_map_on_both + No longer required - remove uses. + specialize_std_map_on_key + No longer required - remove uses. + specialize_std_map_on_value + No longer required - remove uses. + +2023-06-15: olly + [Guile] Fix freearg typemaps to go with char **INOUT and char + *INOUT in typemaps. Previously the char **INOUT typemap would + leak memory if must_free$argnum was true, and the char *INOUT + typemap would generate code that didn't compile. + +2023-06-07: olly + #2630 Fix preprocessor handling of a slash immediately followed by + a single quote, which wasn't getting recognised as starting a + character literal. + +2023-06-07: olly + #2630 Fix parsing of <= and >= in templated lambda. + + Skipping between matching delimiters is now done at the token level + rather than the character level. + +2023-06-02: mmomtchev + [Javascript] #2622 Fix support for %typemap(default) and improve + support for default arguments in general. + +2023-06-01: olly + [Perl] #2470 Fix some integer truncation warnings in generated + wrappers. + +2023-05-30: olly + [Lua] Fix bug when passing a Lua number to a C++ function expected + std::string. Order of evaluation of C++ function arguments is not + defined, and if lua_rawlen() was called before lua_tostring() then + it would return 0 (because the value was still a number) and an + empty string would be passed. + +2023-05-30: mmomtchev + [Javascript] #2618 Fix handling of C++ pointer to member function. + +2023-05-25: olly + #1032 Allow typename disambiguator in: + + using typename NodeT::links_type; + +2023-05-25: olly + SWIG now discriminates between long double, double and float + constants. For example, this means that for target languages which + support a separate float type (such as C# and D) this will now + create a float constant instead of a double constant in the target + language: + + #define PI_ISH 3.1414f + +2023-05-25: olly + C++11 `auto` variables and `decltype()` can now deduce the + type of some expressions which involve literals of built-in types. + +2023-05-25: olly + #1125 Support parsing C++11 auto variables. This uses the + existing type deduction code from decltype so has the same + limitations, and such variables will only actually be wrapped + when SWIG can deduce the type. + +2023-05-23: olly + [Ruby] Fix deprecation warnings about ANYARGS when compiling + C++ code for SWIG-generated Ruby wrappers with Ruby 3.x. + + This is a recurrence of a problem fixed in 4.0.2. Our fix was + conditional on RB_METHOD_DEFINITION_DECL being defined, but Ruby + 3.0 stopped defining this. + +2023-05-23: olly + #2606 Improve error output when SWIG reaches EOF while looking for + a closing delimiter. This is reported with an error like: + + Error: Missing '}'. Reached end of input. + + We now exit after reporting this and so no longer report a second + more generic error like: + + Error: Syntax error in input(1). + +2023-05-22: mmomtchev + [Javascript] #2600 Improve test coverage by adding _runme.js files + for 22 test cases. + +2023-05-20: erezgeva + [C#, D, Java, Javascript, Guile, Scilab] #2552 Implement argcargv.i + library multi-argument typemaps. + +2023-05-20: erezgeva + [D] #56 #2538 #2570 The generated code now works with recent D releases: + adds override keyword on overridden methods. + + Support is now working using DMD, gcc D and LLVM D compilers. + +2023-05-20: olly + Support deducing the type for decltype(false) and + decltype(true). + +2023-05-19: olly + #2446 Add support for auto without trailing return type, which is a + C++14 feature. + +2023-05-19: olly + SWIG no longer defines preprocessor symbols corresponding to + command line options (e.g. `-module blah` was resulting in + `SWIGOPT_MODULE` being set to `blah`). This feature was added in + 2001 so that "[m]odules can look for these symbols to alter their + code generation if needed", but it's never been used for that + purpose in over 20 years, and has never been documented outside of + CHANGES. + +2023-05-18: olly + #2591 Add new -U command line option to undefine a preprocessor + symbol. + +2023-05-18: olly + #1589 #2335 Support parsing arbitrary expression in decltype. + + Use parser error recovery to skip to the closing matching `)` and + issue a warning that we can't deduce the decltype for the + expression (like we already do for any expression which isn't a + simple variable or similar). + +2023-05-12: mmomtchev, erezgeva + [Javascript] #2561 Support check typemaps for Javascript. + +2023-05-12: olly + [Java] #2556 Suppress Java removal warnings on finalize method. + SWIG will need to stop relying on finalize methods, but we know + that and meanwhile these warnings make the testsuite output very + noisy. + +2023-05-11: olly + #302 #2079 #2474 Parse storage class more flexibly. + + Previously we had a hard-coded list of allowed combinations in the + grammar, but this suffers from combinatorial explosion, and results + in a vague `Syntax error in input` error for invalid (and missing) + combinations. + + This means we now support a number of cases which are valid C++ but + weren't supported, including `friend constexpr` and `virtual + explicit`. + +2023-05-08: olly + #1567 Add support for std::string_view (new in C++17) for C#, Java, + Lua, Perl, PHP, Python, Ruby and Tcl. + +2023-05-08: olly + [PHP] #2544 Wrap overloaded method with both static and non-static + forms. We now wrap this as a non-static method in PHP, which means + the static form is only callable via an object. + + Previously this case could end up wrapped as static or non-static + in PHP. If it was wrapped as static, attempting to call non-static + overloaded forms would crash with a segmentation fault. + +2023-05-06: mmomtchev, wsfulton + #2550 Fix typedef/using declarations to a typedef struct/class. + +2023-05-04: erezgeva + [D] #2538 Drop support for D1/Tango, which was discontinued in + 2012. Wrappers for D2/Phobos are now generated by default, though + the -d2 command line option is still accepted (and now ignored) for + backward compatibility. + + *** POTENTIAL INCOMPATIBILITY *** + +2023-04-27: olly + #2502 Allow using snprintf() instead of sprintf() in wrappers. + + We aim to produce code that works with C90 or C++98 so we can't + assume snprintf() is available, but it almost always is (even + on systems from before it was standardised) so having a way to + use it is helpful. + + We enable this automatically if the compiler claims conformance + with at least C99 or C++11. It can also be enabled manually by + defining SWIG_HAVE_SNPRINTF. Define SWIG_NO_SNPRINTF to disable + completely. + + The fallback is to call sprintf() without a buffer size check, + which is what we've done until now. Adding a check after the + call seems of limited benefit - if the buffer was overflowed + then it's too late to block it, and most of our uses either have a + fixed maximum possible size or dynamically allocate a buffer that's + large enough. + +2023-04-26: mmomtchev + [Javascript] Take into account numinputs when counting arguments. + +2023-04-24: olly + [PHP] Add throws typemaps for std:string* and const std::string*. + +2023-04-23: olly + [Javascript] #2453 The testsuite and examples now select which + Javascript engine to test based on what was detected by configure. + Previously they'd always test with node you specified a different + engine (e.g. with `ENGINE=jsc` on the make command line). Now you + only need to specify ENGINE if you have more than one engine + installed. + +2023-04-23: olly + [Javascript] Turn on C++ output when wrapping for node, like + we already do when wrapping for V8-without-node. + + The testsuite was masking this bug by using SWIG options + `-v8 -DBUILDING_NODE_EXTENSION=1` rather than `-node` when testing + with nodejs, while the javascript examples were masking this by + all getting processed with -c++. + + This shouldn't be an incompatible change for users, as if you're + wrapping a C API you'd have to be working around the problem before + this change (like our testsuite and examples were), and this change + shouldn't break your workaround - it just makes it unnecessary. + +2023-04-21: mmomtchev + [Javascript] Fix naming of internal C++ helper for wrapping + variables for node to use the "getter" naming scheme rather + than the function wrapping one. In practice this didn't actually + cause problems because Node wrappers are always compiled as C++ + and the parameters are always different even if the names are + the same. + +2023-04-21: olly + [PHP] Support INPUT,INOUT,OUTPUT for std::string&. + + By default SWIG/PHP wraps std::string& as a pass-by-reference PHP + string parameter, but sometimes such a parameter is only for input + or only for output, so add support for the named typemaps that other + target languages support. + +2023-04-21: degasus + #2519 Fix CanCastAsInteger range check to clear errno first to fix + bogus failures for valid inputs.if errno is set. + +2023-04-21: ZackerySpytz + [OCaml] #1439 Fix reference typemaps for std::string + +2023-04-21: olly + #2183 Fix #ifdef and #ifndef to work inside a %define. Previously + they were silently ignored in this context (but #if defined already + worked here if you need a workaround which works for older + versions). + +2023-04-20: erezgeva + [Go] #2533 Implement argcargv.i library for Go. + +2023-04-19: davidcl + [Scilab] Add support for Scilab 2023.x. + Introduce a new `-gatewayxml6` option to generate XML with full + function names. + +2023-04-19: mmomtchev + https://sourceforge.net/p/swig/bugs/1163/ #1882 #2525 + Fix preprocessor expansion when a macro expands to the name of + another macro which takes parameters from the input following the + original macro expansion. + +2023-04-19: wildmaples + [Ruby] #2527 Fix "undefining the allocator of T_DATA" warning seen + with Ruby 3.2. + +2023-04-18: davidcl + [Scilab] #894 extract values with ":" for typemap (int* IN, int IN_SIZE) + +2023-04-14: olly + [PHP7] Support for PHP7 has been removed. PHP7 security support + ended 2022-11-28 so it doesn't make sense to include support for + it in the SWIG 4.2.x release series. + + *** POTENTIAL INCOMPATIBILITY *** + +2023-04-05: wsfulton + [Python] #2515 Add support for all STL containers to be constructible from a Python set. + + The previous implementation used the Python Sequence Protocol to convert from Python types + to STL containers. The new implementation uses the Python Iterator Protocol instead and + thereby can convert from a Python set too. + +2023-03-25: alatina + [Octave] #2512 Add support for Octave 8.1. + +2023-03-22: wsfulton + [C#] #2478 Minor enhancements to std::array wrappers in std_array.i. + +2023-03-13: wsfulton + Improved error checking when using %template to instantiate templates within + the correct scope. + + 1. When a template is instantiated via %template and uses the unary scope + operator ::, an error occurs if the instantiation is attempted within a + namespace that does not enclose the instantiated template. + For example, the following will now error as ::test::max is not enclosed within test1: + + Error: '::test::max' resolves to 'test::max' and was incorrectly instantiated in + scope 'test1' instead of within scope 'test'. + namespace test1 { + %template(maxchar) ::test::max; + } + + 2. SWIG previously failed to always detect a template did not exist when using + %template. In particular when instantiating a global template incorrectly within + namespace. The code below now correctly emits an error: + + Error: Template 'test5::GlobalVector' undefined. + namespace test5 { + } + template struct GlobalVector {}; + %template(GVI) test5::GlobalVector; + +2023-03-13: wsfulton + Error out if an attempt is made to define a class using the unary scope + operator ::. The following is not legal C++ and now results in an error: + + Error: Using the unary scope operator :: in class definition '::Space2::B' is invalid. + namespace Space2 { + struct B; + } + struct ::Space2::B {}; + +2023-03-08: wsfulton + Fix duplicate const in generated code when template instantiation type is const + and use of template parameter is also explicitly const, such as: + + template struct Conster { + void cccc1(T const& t) {} + }; + %template(ConsterInt) Conster; + + Above previously led to generated code: + (arg1)->cccc1((int const const &)*arg2); + instead of + (arg1)->cccc1((int const &)*arg2); + +2023-03-01: wsfulton + Partial template specialization fixes to support default arguments from the primary + template's parameter list. + + template struct X { void primary() {} }; + // Previously the specialization below resulted in: + // Error: Inconsistent argument count in template partial specialization. 1 2 + template struct X { void special(YY*) {} }; + + // Both of these correctly wrap the partially specialized template + %template(StringPtr) X; + %template(ShortPtr) X; + +2023-02-15: wsfulton + #1300 Further partial template specialization fixes. + Fixes when templates are used as a template parameter in a partially specialized + instantiation such as: + + template struct Vect {}; + template class Foo { ... }; + template class Foo, TTS> { ... }; + %template(VectInt) Vect; + %template(FooVectIntDouble) Foo, double>; // was previously attempting to use primary template + + Also fixes partial specialization where the same template parameter name is used twice, + for example: + + template struct H { ... }; + template struct H { ... }; + %template(HInts) H; // was previously attempting to use primary template + +2023-01-27: jschueller + #2492 [python] Fix unused parameter warnings for self parameter in + generated C/C++ wrapper code. + +2023-01-14: wsfulton + Fix deduction of partially specialized template parameters when the specialized + parameter is non-trivial, used in a wrapped method and the type to %template uses + typedefs. For example: + + typedef double & DoubleRef; + template struct XX {}; + template struct XX { void fn(T t) {} }; + %template(XXD) XX; + + The type of the parameter in the instantiated template for fn is now correctly deduced + as double. + +2023-01-03: wsfulton + #983 Fix seg fault when instantiating templates with parameters that are function + parameters containing templates, such as: + + %template(MyC) C)>; + +2023-01-03: wsfulton + Complete support for C++11 variadic function templates. Support was previously limited + to just one template parameter. Now zero or more template parameters are supported + in the %template instantiation. + +2022-12-29: wsfulton + #1863 Syntax error fixes parsing more elaborate parameter pack arguments that are + used in function pointers, member function pointers: + + template struct VariadicParms { + void ParmsFuncPtrPtr(int (*)(V*...)) {} + void ParmsFuncPtrPtrRef(int (*)(V*&...)) {} + void ParmsFuncPtrPtrRValueRef(int (*)(V*&&...)) {} + void ParmsFuncPtrRef(int (*)(V&...)) {} + void ParmsFuncPtrRValueRef(int (*)(V&&...)) {} + + void ParmsMemFuncPtrPtr(int (KlassMemFuncs::*)(V*...)) {} + void ParmsMemFuncPtrPtrRef(int (KlassMemFuncs::*)(V*&...)) {} + void ParmsMemFuncPtrPtrRValueRef(int (KlassMemFuncs::*)(V*&&...)) {} + void ParmsMemFuncPtrRef(int (KlassMemFuncs::*)(V&...)) {} + void ParmsMemFuncPtrRValueRef(int (KlassMemFuncs::*)(V&&...)) {} + }; + + %template(VariadicParms0) VariadicParms<>; + %template(VariadicParms1) VariadicParms; + + Also in various other places such as within noexcept specifiers: + + template + void emplace(Args &&... args) noexcept( + std::is_nothrow_constructible::value); + +2022-12-27: wsfulton + Fix instantiation of variadic class templates containing parameter pack arguments that + are function pointers. + + template struct VariadicParms { + void ParmsFuncPtrVal(int (*)(V...)) {} + }; + + %template(VariadicParms0) VariadicParms<>; + %template(VariadicParms1) VariadicParms; + +2022-12-23: wsfulton + #1863 Fix syntax error parsing variadic templates containing parameter pack arguments that + are function pointers. + +2022-12-22: wsfulton + Complete support for C++11 variadic class templates. Support was previously limited + to just one template parameter. Now zero or more template parameters are supported. + +2022-12-06: wsfulton + #1636 Fix syntax error for misplaced Doxygen comment after struct/class member. + Fix syntax error using Doxygen member groups syntax, "///*}", when used after + final struct/class member. + +2022-12-05: wsfulton + #2023 Fix garbled Doxygen post comments in parameter lists. + Fix syntax error parsing a trailing Doxygen comment in parameter lists. + +2022-12-03: wsfulton + #1609 Fix syntax error parsing of Doxygen comments after last enum item. + +2022-12-03: wsfulton + #1715 Fix syntax error parsing of unconventionally placed Doxygen post + comments for enum items. + +2022-12-02: wsfulton + #624 #1021 Improved template template parameters support. Previously, specifying more + than one simple template template parameter resulted in a parse error. Now + multiple template template parameters are working including instantiation with + %template. Example: + + template class, class> class Op, template class X, class Y> + class C { ... }; + +2022-11-26: wsfulton + #1589 #1590 Slightly better decltype() support for expressions, such as: + + int i; + ... decltype(&i) ... + + These result in a warning for non-trivial expressions which SWIG cannot evaluate: + + Warning 344: Unable to deduce decltype for '&i'. + + See 'Type Inference' in CPlusPlus.html for workarounds. + +2022-11-22: wsfulton + #366 #1037 Fix seg fault handling template parameter expressions + containing '<=' or '>='. + +2022-11-18: wsfulton + Duplicate class template instantiations via %template now issue a warning and are ignored. + + %template(Aint) A; + %template(Aint2) A; // Now ignored and issues a warning + + example.i:7: Warning 404: Duplicate template instantiation of 'A< int >' with name 'Aint2' ignored, + example.i:6: Warning 404: previous instantiation of 'A< int >' with name 'Aint'. + + A single empty template instantiation before a named instantiation is the one exception + for allowing duplicate template instantiations as the empty template instantiation does not + create a wrapper for the template, it merely adds the instantiation into SWIG's internal + type system. + Duplicate empty template instantiations are quietly ignored. + + %template() B; + %template(Bint) B; // OK + + %template() C; + %template() C; // Quietly ignored now + %template(Cint) C; // OK + + Note that default template parameters are considered when looking for duplicates such as: + + template struct D {}; + %template(Dint) D; + %template(Dintshort) D; + + example.i:7: Warning 404: Duplicate template instantiation of 'D< int,short >' with name 'Dintshort' ignored, + example.i:6: Warning 404: previous instantiation of 'D< int >' with name 'Dint'. + + Note that the following always was ignored, but that was because the chosen name was a + duplicate rather than the template being a duplicate: + + %template(Eint) E; + %template(Eint) E; // Always has been ignored as a redefined identifier + + The old warning was: + + example.i:7: Warning 302: Identifier 'Eint' redefined (ignored) (Renamed from 'E< int >'), + example.i:6: Warning 302: previous definition of 'Eint' (Renamed from 'E< int >'). + + *** POTENTIAL INCOMPATIBILITY *** + Version 4.1.1 (30 Nov 2022) =========================== diff --git a/CHANGES.current b/CHANGES.current index 4a45554741f..f44ab054a48 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -4,1130 +4,142 @@ See the RELEASENOTES file for a summary of changes in each release. Issue # numbers mentioned below can be found on Github. For more details, add the issue number to the end of the URL: https://github.com/swig/swig/issues/ -Version 4.2.0 (30 Dec 2023) +Version 4.2.1 (24 Feb 2024) =========================== -2023-12-24: degasus - [Python] #2494 Fix integer overflow / undefined behavior for python - castmode on sizeof(long)==8 platforms for implicit conversions around - edge cases of LONG_MAX and ULONG_MAX, for example: - - void as_l(long x); // C interface - - Usage from Python: - - lmaxd = math.nextafter(float(2**63), 0.0) # LONG_MAX == 2**63-1 - # Now below correctly raises a TypeError due to the overflow - as_l(math.nextafter(lmaxd, float('inf'))) - -2023-12-21: olly - [PHP] `%feature("php:allowdynamicproperties", 0) Foo;` is now handled as - the feature being off to match other boolean features. Previously - any value set was treated as on. - -2023-12-20: treitmayr - [Ruby] #2033 Fix missing checks for negative numbers when passing numbers - to unsigned long/unsigned long long C types. - -2023-12-20: crhilton - [C#] #2722 Add support the "cs:defaultargs" feature. - - This adds a way to wrap C++ functions that have default arguments - with an equivalent C# function with default arguments, instead of - generating an overloaded C# method for each defaulted argument. - -2023-12-20: vadz, vadimcn, wangito33, wsfulton, clintonstimpson - [Python] #1613 #1687 #1727 #2190 #2727 #2428 Add support for the Python stable - ABI using default Python options. Code is generated that compiles when - setting the C macro Py_LIMITED_API to 0x03040000 (at C/C++ compile time). - Note that the -builtin, -fast (used by -O) options are not supported. - -2023-12-20: wsfulton - [Python] More efficient input string marshalling for Python 3. - - Previously a copy of a string was made while converting from a Python 3 - string to a char * or std::string. This copy is no longer needed making - string marshalling more efficient. Does not apply to the stable ABI - targetting Python < 3.10 where a copy is still required where the stable - ABI does not provide PyUnicode_AsUTF8AndSize. - -2023-12-20: wsfulton - #2190 Replace SWIG_Python_str_AsChar with SWIG_PyUnicode_AsUTF8AndSize. - - SWIG_Python_str_AsChar has undefined behaviour when Py_LIMITED_API is defined - as it returns a pointer to a string in a PyBytes object that no longer exists. - - SWIG_PyUnicode_AsUTF8AndSize is an efficient replacement, but requires a - different API and the caller to decrement the refcount on the intermediate - PyObject in the Py_LIMITED_API < 0x030A0000 implementation. The alternative - would have required copying the returned char * string as was done in a - previous implementation requiring a call to the defunct SWIG_Python_str_DelForPy3 - function. - - *** POTENTIAL INCOMPATIBILITY *** - -2023-12-14: PaulObermeier - [Tcl] #2730 Rename SWIG’s Tcl_GetBoolFromObj() since Tcl 8.7 (TIP 618) - introduces a function with the same name. - -2023-12-13: chrstphrchvz - [Tcl] #2729 Use Tcl_GetString() instead of Tcl_GetStringFromObj(…, NULL) - for compatibility with Tcl 9. - -2023-12-03: olly - [Ocaml] Remove -suffix command line option which has emitted a - deprecation warning since SWIG 3.0.4 - if you want to specify - a different filename extension for generated C++ files use -cppext - instead, which works for all SWIG target language backends. - -2023-12-01: saiarcot895 - [Python] #2413 Prevent potential multi-threading crash; gracefully exit running - daemon threads on main thread exit. - -2023-11-24: wsfulton - Add support for parsing C++20 constexpr destructors. - -2023-11-19: olly - Fix handling of constant expressions containing < and > to not - drop parentheses around the subexpression as doing so can change - its value in some cases. - -2023-11-18: yasamoka, jmarrec - [Python] #2639 Add std_filesystem.i for wrapping std::filesystem::path - with pathlib.Path. - -2023-11-17: chrstphrchvz - [Tcl] #2711 Fix -Wmissing-braces warning in generated code. - -2023-11-17: chrstphrchvz - [Tcl] #2710 Stop using Tcl's CONST macro. It's no longer needed - and is set to be deprecated in Tcl 8.7, and removed in Tcl 9.0. - -2023-11-08: wsfulton - [C#] Replace empty() method with IsEmpty property for std::vector, std::list, std::map - containers for consistency across all containers. - - The empty() method is actually still wrapped, but as a private proxy method. For backwards - compatibility, the method can be made public again using %csmethodmodifiers for all - vectors as follows: - - %extend std::vector { - %csmethodmodifiers empty() const "public" - } - %include "std_vector.i" - - or alternatively for each individual %template instantiation as follows: - - %csmethodmodifiers std::vector::empty() const "public" - %template(VectorDouble) std::vector; - - - *** POTENTIAL INCOMPATIBILITY *** - -2023-11-08: wsfulton - [C#] Add std_unordered_set.i for wrapping std::std_unordered_set, implementing - C# System.Collections.Generic.ISet<>. - -2023-11-09: olly - #2591 SWIG now supports command line options -std=cXX and - -std=c++XX to specify the C/C++ standards version. The only effect - of these options is to set appropriate values for __STDC_VERSION__ - and __cplusplus respectively, which is useful if you're wrapping - headers which have preprocessor checks based on their values. - -2023-11-09: olly - SWIG now defines __STDC__ to 1 to match the behaviour of ISO C/C++ - compilers - previously it had an empty value. - - *** POTENTIAL INCOMPATIBILITY *** - -2023-11-09: olly - When -c++ is used, SWIG now defines __cplusplus to be 199711L (the - value for C++98) by default - previously its value was set to - __cplusplus. - - *** POTENTIAL INCOMPATIBILITY *** - -2023-11-08: emmenlau - #2480 [C#] Add std_unordered_map.i for wrapping std::std_unordered_map, implementing - C# System.Collections.Generic.IDictionary<>. - -2023-11-06: wsfulton - [D, Java] Add the dbegin option to the %module directive for generating code at - the beginning of every D file. Similarly javabegin for Java. This enables one - to add a common comment at the start of each D/Java file. - -2023-11-06: wsfulton - [C#] #2681 Support nullable reference types. A generic C# option to the - %module directive allows one to add in any code at the beginning of every - C# file. This can add the #nullable enable preprocessor directive at the beginning - of every C# file in order to enable nullable reference types as follows: - - %module(csbegin="#nullable enable\n") mymodule - -2023-10-21: wsfulton - [Python] #1783 Don't swallow all exceptions into a NotImplemented return - when wrapping operators which are marked with %pythonmaybecall. Corrects the - implementation of PEP 207. - -2023-10-18: wsfulton - [C#, D] #902 Use the C++11 enum base, that is, the underlying enum - type. - - For C#, it is used as the underlying type in the generated C# enum. - For D, it is used as the enum base type in the generated D enum. - -2023-10-16: wsfulton - #2687 Another using declarations fix for inheritance hierarchies more than - two deep and the using declarations are overloaded. Using declarations - from a base class' base were not available for use in the target - language when the using declaration was before a method declaration. - -2023-10-11: wsfulton - [C#, D, Go, Guile, Java, Javascript, Lua, Ocaml, R, Racket] #1680 - carrays.i library modified to use size_t instead of int for the functions - provided by %array_functions and %array_class. - - If the old types are required for backwards compatibility, use %apply to - restore the old types as follows: - - %include "carrays.i" - %apply int { size_t nelements, size_t index } - ... %array_functions and %array_class ... - %clear size_t nelements, size_t index; # To be safe in case used elsewhere - - *** POTENTIAL INCOMPATIBILITY *** - -2023-10-11: olly - [PHP] #2685 Fix testcase director_finalizer to work with PHP 8.3. - -2023-10-06: wsfulton - #2307 std::vector::capacity and std::vector::reserve signature changes. - - Java api changes from: - public long capacity() { ... } - public void reserve(long n) { ... } - to: - public int capacity() { ... } - public void reserve(int n) { ... } - to fit in with the usual Java convention of using int for container - indexing and sizing. - - The original api for std::vector::reserve can be also be made available via - %extend to add in an overloaded method as follows: - - %include - %extend std::vector { - void reserve(jlong n) throw (std::length_error, std::out_of_range) { - if (n < 0) - throw std::out_of_range("vector reserve size must be positive"); - self->reserve(n); - } +2024-02-23: wsfulton + #2814 Correctly ignore duplicate template instantiation (when the + duplicate contains typedef'd template parameters). + +2024-02-22: erezgeva + [Ruby, Octave, R] #2284 Fix segfault shrinking STL containers. + +2024-02-22: simark + Fix -Wundef warning about testing the value of __cplusplus when + compiling SWIG-generated C code. Warning introduced by a change in + SWIG 4.2.0. + +2024-02-21: olly + #2808 [PHP] Fix memory leak when getting or setting a PHP + attribute which wraps a C++ member variable. Bug introduced in + SWIG 4.1.0. + +2024-02-18: wsfulton + #2745 Fix for wrapping STL containers that are static member variables + or global variables (most scripting languages). Previously a copy of the + STL container was made into a target language container when reading the + variable. Changes, such as adjusting an element or adding/erasing + elements, were made to the copy of the container rather the actual + underlying C++ container. Also applies to const reference STL static + members. + + If you really need the old behaviour, add in the typemap that used + to provide it. For example, for std::list< int > and + const std::list< int >&, use: + + %typemap(varout,noblock=1,fragment="SWIG_" "Traits" "_" {std::list< int >}) + std::list< int >, const std::list< int >& { + $result = swig::from(static_cast< std::list< int > >($1)); } - This change is partially driven by the need to seamlessly support the full - 64-bit range for size_t generically, apart from the customisations for the - STL containers, by using: - - %apply unsigned long long { size_t }; - %apply const unsigned long long & { const size_t & }; - *** POTENTIAL INCOMPATIBILITY *** -2023-10-05: wsfulton - [C#] #2379 Defining SWIGWORDSIZE64 now applies the (unsigned) - long long typemaps to (unsigned) long for a better match on systems - where long is 64-bits. A new "Type mapping" section has been added into - the CSharp.html documentation covering this and marshalling of primitive - types. C (unsigned) long handling remains as is by default, that is, - marshall as 32-bit. - - The INPUT[], OUTPUT[], INOUT[], FIXED[] typemaps for long and unsigned long - in arrays_csharp.i can now be used and compiled on 64-bit platforms where - sizeof(long) != sizeof(int). Requires SWIGWORDSIZE64 to be defined. - -2023-09-27: wsfulton - [Java] #646 #649 Defining SWIGWORDSIZE64 now applies the (unsigned) - long long typemaps to (unsigned) long for a better match on systems - where long is 64-bits. - -2023-09-18: christophe-calmejane - #2631 C++17 std::map fix for values that are not default constructible. - Enhancements for all target languages except Python and Ruby. - -2023-09-14: mmomtchev - #2675 #2676 Temporary variable zero initialisation in the wrappers for - consistency with handling pointers. - -2023-09-11: emmenlau - #2394 Add support to preprocessor for true and false. Note that this - is for C++ not C. - -2023-09-11: wsfulton - [R] #2605 Complete transition to rtypecheck typemaps from hard coded - logic. Also see entry dated 2022-10-28 for swig-4.1.1. The rtypecheck - typemaps implement typechecking in R for each function parameter using - functions such as is.numeric, is.character, is.logical, is.null etc. - -2023-09-09: wsfulton - https://sourceforge.net/p/swig/bugs/919/ - - Fix incorrect variable setters being generated when wrapping arrays. - A setter is no longer generated if the type of the array members - are non-assignable. - -2023-09-09: wsfulton - Non-assignable detection fixes when wrapping const member variables. - Const member variables such as the following are non-assignable by - by default: - - char * const x; - const int x; - const int x[1]; - - but not: - - const char * x; - - Variable setters are not generated when wrapping these non-assignable - variables and classes containing such non-assignable variables. - -2023-09-07: wsfulton - Non-assignable detection fixes when wrapping rvalue reference variables. - Rvalue reference variables such as the following are non-assignable by - by default: - - X &&v; - - Variable setters are not generated when wrapping these non-assignable - variables and classes containing such non-assignable variables. - -2023-09-06: wsfulton - Non-assignable detection fixes when wrapping reference variables. - Reference variables such as the following are non-assignable by - by default: - - int &v; - - Variable setters are not generated when wrapping these non-assignable - variables and classes containing such non-assignable variables. - -2023-09-06: wsfulton - Assignment operator detection fixes when wrapping static member - variables. - -2023-09-06: wsfulton - #1416 Implicit assignment operator detection fixes. - - A class that does not have an explicit assignment operator does not - have an implicit assignment operator if a member variable is not - assignable. Similarly should one of the base classes also not be - assignable. Detection of these scenarios has been fixed so that when - wrapping a variable that is not assignable, a variable setter is not - generated in order to avoid a compiler error. - - Template instantiation via %template is required in order for this to - work for templates that are not assignable. - -2023-09-03: wsfulton - https://sourceforge.net/p/swig/bugs/1006/ - Fix incorrect variable setters being generated when the type of the - variable is not assignable, due to variable type inheriting a private - assignment operator further up the inheritance chain (further up than - the immediate base). - -2023-09-03: wsfulton - [Guile, Ocaml, Perl] Don't attempt to generate a setter when wrapping - variables which have a private assignment operator as assignment is not - possible. This now matches the behaviour of all the other target languages. - -2023-09-02: wsfulton - Fix problems wrapping deleted destructors. Derived classes are not - constructible, so don't attempt to generate default constructor or - copy constructor wrappers. - - struct StackOnly1 { - // Only constructible on the stack - ~StackOnly1() = delete; - }; - struct StackOnlyDerived1 : StackOnly1 { - // this class is not constructible due to deleted base destructor - }; - -2023-09-02: wsfulton - Fix %copyctor feature when used on classes with deleted copy constructors. - A default constructor wrapper was sometimes incorrectly generated. - -2023-09-02: wsfulton - #1644 Fix wrapping types passed by value where the type has a deleted - default constructor. - -2023-08-16: shadchin - [Python] #2665 Fix missing-field-initializers warning to provide support - for python-3.12. - -2023-08-09: olly - [Ruby] Remove -feature command line option which has been - deprecated since SWIG 1.3.32 in 2007. Use -initname instead. - -2023-08-06: wsfulton - Add support for using declarations to introduce templated member - methods and for inheriting templated constructors, such as: - - struct Base { - // templated constructor - template Base(const T &t, const char *s) {} - // templated member method - template void template_method(const T &t, const char *s) {} - }; - - %template(Base) Base::Base; - %template(template_method) Base::template_method; - - struct Derived : Base { - using Base::Base; - using Base::template_method; - }; - - Previously the templated methods and constructors were ignored and - not introduced into the Derived class. - -2023-08-04: wsfulton - Fix using declarations for inheritance hierarchies more than - two deep and the using declarations are overloaded. Using declarations - from a base class' base were not available for use in the target - language. For example in the code below, Using1::usingmethod(int i) - was not wrapped for use in Using3: - - struct Using1 { - protected: - void usingmethod(int i) {} - }; - struct Using2 : Using1 { - protected: - void usingmethod(int i, int j) {} - using Using1::usingmethod; - }; - struct Using3 : Using2 { - void usingmethod(int i, int j, int k) {} - using Using2::usingmethod; - }; - - Similarly for C++11 using declarations for inheriting constructors. - -2023-08-02: wsfulton - https://sourceforge.net/p/swig/bugs/932/ - Fix missing constructor generation due to abstract class test - failure when a method is declared in the class along with a - using declaration and the using declaration is declared before - the method that implemented the pure virtual method, such as: - - struct ConcreteDerived : AbstractBase { - ConcreteDerived() {} // was not wrapped - using AbstractBase::f; - virtual void f(int n) override {} - }; - -2023-08-02: olly - [PHP] Implement overloading between different integer types and - between double and float. - -2023-07-29: wsfulton - https://sourceforge.net/p/swig/bugs/678/ - Fix %copyctor used on class hierarchies with non-const copy - constructors. Previously SWIG always attempted to call a copy - constructor taking a const reference parameter instead of a - non-const reference parameter. - -2023-07-28: wsfulton - #2541 Fix overloading of templated constructors and %copyctor. - -2023-07-21: wsfulton - Don't generate a default constructor wrapper when a class has a - templated constructor, as there isn't actually an implied default - constructor. For example: - - struct TConstructor3 { - template TConstructor3(T val) {} - }; - - Previously wrappers were generated for a non-existent default - constructor which failed to compile. - -2023-07-15: wsfulton - C++11 using declarations for inheriting constructors has now been - extended to support the directors feature. - -2023-07-13: wsfulton - C++11 using declarations for inheriting constructors support now - also includes inheriting implicitly defined default constructors - from the base class. - -2023-07-04: wsfulton - #2641 Add support for C++11 using declarations for inheriting - constructors. - -2023-06-30: wsfulton - #2640 Fix syntax error parsing an expression which calls a function - with no parameters within additional brackets. - -2023-06-27: mmomtchev - [Javascript] #2545 New Javascript generator targeting the Node.js - binary stable ABI Node-API. - -2023-06-27: olly - [Java] Completely remove pragmas which were deprecated in 2002 and - have triggered an error since SWIG 2.0: - - moduleimport Use the moduleimports pragma - moduleinterface Use the moduleinterfaces pragma - modulemethodmodifiers Use %javamethodmodifiers - allshadowimport Use %typemap(javaimports) - allshadowcode Use %typemap(javacode) - allshadowbase Use %typemap(javabase) - allshadowinterface Use %typemap(javainterfaces) - allshadowclassmodifiers Use %typemap(javaclassmodifiers) - shadowcode Use %typemap(javacode) - shadowimport Use %typemap(javaimports) - shadowbase Use %typemap(javabase) - shadowinterface Use %typemap(javainterfaces) - shadowclassmodifiers Use %typemap(javaclassmodifiers) - -2023-06-24: wsfulton - #2616 https://sourceforge.net/p/swig/bugs/1102/ Fix directors and - allprotected mode and using declarations. Previously SWIG either - seg faulted or generated code that did not compile. - -2023-06-20: olly - #2486 Fix handling of template in array size, which was being - rejected by SWIG because the type string contains '<' not followed - by '('. Drop this check as it should be unnecessary now since the - fixes that ensure that template parameters are enclosed within - '<(' and ')>'. - -2023-06-16: olly - [Java] Remove deprecated command line options which have done - nothing except emit a deprecation message since 2002 or before: +2024-02-15: olly + Improve type deduction for enum values in expressions. - -jnic / -jnicpp JNI calling convention now automatic. - -nofinalize Use javafinalize typemap instead. - -proxy / -shadow Now on by default. +2024-02-15: rlaboiss + #2799 [Octave] Add support for Octave 9.0; fix warnings about use + of deprecated Octave APIs with Octave 7 and later. -2023-06-16: olly - [Guile] Drop support for -Linkage ltdlmod which was only useful - for Guile <= 1.4 which we no longer support. +2024-02-14: olly + SWIG now warns and ignores if %constant is used with an implicit + type which SWIG can't deduce. -2023-06-15: olly - [Guile] The -gh and -scm command line options have been removed. - These have done nothing except emit a message since 2013 when - SWIG dropped support for generating bindings which used GH. +2024-02-13: olly + Fix type deduction for certain cases involving C-style casts, or + which are syntactically like a C-style cast applied to an unary + operator, such as: (7)*6 -2023-06-15: olly - Remove pointer.i from the SWIG library. It's been a dummy file - which has done nothing except %echo a deprecation message since - 2002. The replacement is cpointer.i. +2024-02-13: olly + #2796 Fix handling of enum initialised by expression including a + cast to a typedef-ed type. Regression introduced in 4.2.0. -2023-06-15: olly - SWIG will no longer fall back to using the include path to find the - input file, which has been deprecated and emitted a warning since - SWIG 1.3.37 (2009-01-13). This makes the behaviour of SWIG the - same as C/C++ compilers and works with ccache. +2024-02-09: wsfulton + #2794 Fix SwigType_isvariadic assertion to add support for variadic + templated functions in a template. -2023-06-15: olly - Remove features deprecated in SWIG 1.x and 2.x. Most of these have - emitted a deprecation warning or error for well over a decade and - have replacements with fewer shortcomings so we expect users will - have migrated away from them long ago, but in case you need - them replacements are noted below: +2024-02-08: wsfulton + #2761 [Tcl] Fix assert in SWIG_Tcl_ConvertPtrFromString(). - %addmethods Use %extend instead. - %attribute_ref Use %attributeref instead (NB: If called with - 4 parameters, the 3rd and 4th need switching). - %disabledoc Use Doxygen support instead. - %doconly Use Doxygen support instead. - %enabledoc Use Doxygen support instead. - %except Use %exception instead. - %extern Use %import instead. - %localstyle Use Doxygen support instead. - %name Use %rename instead. - %new Use %newobject instead. - %out %apply OUTPUT typemap rule instead. - %readonly Use %immutable instead. - %readwrite Use %mutable instead. - %section Use Doxygen support instead. - %style Use Doxygen support instead. - %subsection Use Doxygen support instead. - %subsubsection Use Doxygen support instead. - %text Use Doxygen support instead. - %title Use Doxygen support instead. - %typemap(except) Use %exception instead. - %typemap(ignore) Use %typemap(in,numinputs=0) instead. - %val Use typemaps instead. - -debug_template Use -debug-template instead. - -debug_typemap Use -debug-typemap instead. - -dump_classes Use -debug-classes instead. - -dump_memory Use -debug-memory instead. - -dump_module Use -debug-module 4 instead. - -dump_parse_module Use -debug-module 1 instead. - -dump_parse_top Use -debug-top 1 instead. - -dump_tags Use -debug-tags instead. - -dump_top Use -debug-top 4 instead. - -dump_tree Use -debug-top 4 instead. - -dump_typedef Use -debug-typedef instead. - -dump_xml Use -xmlout /dev/stdout instead. - -make_default On by default since SWIG 1.3.7 (2001-09-03). - -makedefault On by default since SWIG 1.3.7 (2001-09-03). - -no_default Use %nodefaultctor/%nodedefaultdtor instead. - -nodefault Use %nodefaultctor/%nodedefaultdtor instead. - -noextern option On by default since SWIG 1.3.26 (2005-10-09). - -noruntime Type sharing happens via target lang global. - -runtime Type sharing happens via target lang global. - -show_templates Use -debug-template instead. - -tm_debug Use -debug-typemap instead. - -xml out.xml Use -xml -o out.xml instead. - BOTH typemap rule Use INOUT typemap rule instead. - SWIG_INTRUSIVE_PTR(PROXYCLASS, TYPE) - Use %intrusive_ptr(TYPE) instead. - SWIG_INTRUSIVE_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE) - Use %intrusive_ptr(TYPE) instead. - SWIG_INTRUSIVE_PTR_NO_WRAP(PROXYCLASS, TYPE) - Use %intrusive_ptr_no_wrap(TYPE) instead. - SWIG_INTRUSIVE_PTR_DERIVED_NO_WRAP(PROXYCLASS, BASECLASSTYPE, TYPE) - Use %intrusive_ptr_no_wrap(TYPE) instead. - SWIG_SHARED_PTR(PROXYCLASS, TYPE) - Use %shared_ptr(TYPE) instead. - SWIG_SHARED_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE...) - Use %shared_ptr(TYPE) instead. - SWIG_STD_VECTOR_SPECIALIZE(CSTYPE, CTYPE) - Use SWIG_STD_VECTOR_ENHANCED(CTYPE) instead. - SWIG_STD_VECTOR_SPECIALIZE_MINIMUM(CSTYPE, CTYPE) - No longer required - remove uses. - specialize_std_map_on_both - No longer required - remove uses. - specialize_std_map_on_key - No longer required - remove uses. - specialize_std_map_on_value - No longer required - remove uses. +2024-02-03: wsfulton + #1897 [C#, Java] Fix crash handling enums with same name in different + namespaces. -2023-06-15: olly - [Guile] Fix freearg typemaps to go with char **INOUT and char - *INOUT in typemaps. Previously the char **INOUT typemap would - leak memory if must_free$argnum was true, and the char *INOUT - typemap would generate code that didn't compile. +2024-02-01: wsfulton + #2781 Correctly report line number warnings/errors for base classes that + are templates. -2023-06-07: olly - #2630 Fix preprocessor handling of a slash immediately followed by - a single quote, which wasn't getting recognised as starting a - character literal. +2024-01-31: olly + Fix assertion failure and segfault trying to use %constant to + deduce the type of a "float _Complex" constant. -2023-06-07: olly - #2630 Fix parsing of <= and >= in templated lambda. +2024-01-31: jim-easterbrook + #2771 [Python] builtin fixes to handle NULL values passed to slots using + functype: ssizeobjargproc and ternaryfunc. - Skipping between matching delimiters is now done at the token level - rather than the character level. +2024-01-31: olly + [Java] #2766 Fix segfault trying to wrap a constant whose type is unknown + to SWIG with "%javaconst(1);" enabled. -2023-06-02: mmomtchev - [Javascript] #2622 Fix support for %typemap(default) and improve - support for default arguments in general. +2024-01-31: wsfulton + #2768 Fix seg fault handling upcasting when using %shared_ptr on some + templates. -2023-06-01: olly - [Perl] #2470 Fix some integer truncation warnings in generated - wrappers. +2024-01-31: olly + #2783 Fix incorrectly deduced type for function call. Regression + introduced in 4.2.0. -2023-05-30: olly - [Lua] Fix bug when passing a Lua number to a C++ function expected - std::string. Order of evaluation of C++ function arguments is not - defined, and if lua_rawlen() was called before lua_tostring() then - it would return 0 (because the value was still a number) and an - empty string would be passed. +2024-01-27: wsfulton + [Python] Fix compilation error when wrapping two or more classes that + have the same friend operator overload when the classes are in a namespace. -2023-05-30: mmomtchev - [Javascript] #2618 Fix handling of C++ pointer to member function. +2024-01-15: wsfulton + https://sourceforge.net/p/swig/bugs/960/ + https://sourceforge.net/p/swig/bugs/807/ + Fix so that friend operators within a namespace can be correctly ignored + or renamed. -2023-05-25: olly - #1032 Allow typename disambiguator in: +2024-01-15: wsfulton + Wrap friend functions that are defined or declared within a namespace. + Previously unqualified friend definitions/declarations in a namespace were + ignored. - using typename NodeT::links_type; + The visibility of unqualified friend functions in C++ is somewhat quirky + and the documentation has been enhanced to aid wrapping of friends. -2023-05-25: olly - SWIG now discriminates between long double, double and float - constants. For example, this means that for target languages which - support a separate float type (such as C# and D) this will now - create a float constant instead of a double constant in the target - language: +2024-01-12: wsfulton + #2749 Fix seg fault handling friend constructor/destructor declarations. - #define PI_ISH 3.1414f +2024-01-12: olly + [Ruby, Tcl] #2751 Fix -external-runtime output to define + SWIG_snprintf (bug introduced in 4.2.0). -2023-05-25: olly - C++11 `auto` variables and `decltype()` can now deduce the - type of some expressions which involve literals of built-in types. +2024-01-12: olly + Improve preprocessor warning for use of an undefined function-like + macro. SWIG now warns: -2023-05-25: olly - #1125 Support parsing C++11 auto variables. This uses the - existing type deduction code from decltype so has the same - limitations, and such variables will only actually be wrapped - when SWIG can deduce the type. + Warning 202: Could not evaluate expression 'MY_VERSION_AT_LEAST(1,2,3)' + Warning 202: Use of undefined function-like macro -2023-05-23: olly - [Ruby] Fix deprecation warnings about ANYARGS when compiling - C++ code for SWIG-generated Ruby wrappers with Ruby 3.x. + instead of: - This is a recurrence of a problem fixed in 4.0.2. Our fix was - conditional on RB_METHOD_DEFINITION_DECL being defined, but Ruby - 3.0 stopped defining this. + Warning 202: Could not evaluate expression 'MY_VERSION_AT_LEAST(1,2,3)' + Warning 202: Syntax error: expected operator -2023-05-23: olly - #2606 Improve error output when SWIG reaches EOF while looking for - a closing delimiter. This is reported with an error like: +2024-01-11: PaulObermeier + [Tcl] Improve support for Tcl 9.0. All examples and tests now pass + with Tcl 9.0.b1. - Error: Missing '}'. Reached end of input. - - We now exit after reporting this and so no longer report a second - more generic error like: - - Error: Syntax error in input(1). - -2023-05-22: mmomtchev - [Javascript] #2600 Improve test coverage by adding _runme.js files - for 22 test cases. - -2023-05-20: erezgeva - [C#, D, Java, Javascript, Guile, Scilab] #2552 Implement argcargv.i - library multi-argument typemaps. - -2023-05-20: erezgeva - [D] #56 #2538 #2570 The generated code now works with recent D releases: - adds override keyword on overridden methods. - - Support is now working using DMD, gcc D and LLVM D compilers. - -2023-05-20: olly - Support deducing the type for decltype(false) and - decltype(true). - -2023-05-19: olly - #2446 Add support for auto without trailing return type, which is a - C++14 feature. - -2023-05-19: olly - SWIG no longer defines preprocessor symbols corresponding to - command line options (e.g. `-module blah` was resulting in - `SWIGOPT_MODULE` being set to `blah`). This feature was added in - 2001 so that "[m]odules can look for these symbols to alter their - code generation if needed", but it's never been used for that - purpose in over 20 years, and has never been documented outside of - CHANGES. - -2023-05-18: olly - #2591 Add new -U command line option to undefine a preprocessor - symbol. - -2023-05-18: olly - #1589 #2335 Support parsing arbitrary expression in decltype. - - Use parser error recovery to skip to the closing matching `)` and - issue a warning that we can't deduce the decltype for the - expression (like we already do for any expression which isn't a - simple variable or similar). - -2023-05-12: mmomtchev, erezgeva - [Javascript] #2561 Support check typemaps for Javascript. - -2023-05-12: olly - [Java] #2556 Suppress Java removal warnings on finalize method. - SWIG will need to stop relying on finalize methods, but we know - that and meanwhile these warnings make the testsuite output very - noisy. - -2023-05-11: olly - #302 #2079 #2474 Parse storage class more flexibly. - - Previously we had a hard-coded list of allowed combinations in the - grammar, but this suffers from combinatorial explosion, and results - in a vague `Syntax error in input` error for invalid (and missing) - combinations. - - This means we now support a number of cases which are valid C++ but - weren't supported, including `friend constexpr` and `virtual - explicit`. - -2023-05-08: olly - #1567 Add support for std::string_view (new in C++17) for C#, Java, - Lua, Perl, PHP, Python, Ruby and Tcl. - -2023-05-08: olly - [PHP] #2544 Wrap overloaded method with both static and non-static - forms. We now wrap this as a non-static method in PHP, which means - the static form is only callable via an object. - - Previously this case could end up wrapped as static or non-static - in PHP. If it was wrapped as static, attempting to call non-static - overloaded forms would crash with a segmentation fault. - -2023-05-06: mmomtchev, wsfulton - #2550 Fix typedef/using declarations to a typedef struct/class. - -2023-05-04: erezgeva - [D] #2538 Drop support for D1/Tango, which was discontinued in - 2012. Wrappers for D2/Phobos are now generated by default, though - the -d2 command line option is still accepted (and now ignored) for - backward compatibility. - - *** POTENTIAL INCOMPATIBILITY *** - -2023-04-27: olly - #2502 Allow using snprintf() instead of sprintf() in wrappers. - - We aim to produce code that works with C90 or C++98 so we can't - assume snprintf() is available, but it almost always is (even - on systems from before it was standardised) so having a way to - use it is helpful. - - We enable this automatically if the compiler claims conformance - with at least C99 or C++11. It can also be enabled manually by - defining SWIG_HAVE_SNPRINTF. Define SWIG_NO_SNPRINTF to disable - completely. - - The fallback is to call sprintf() without a buffer size check, - which is what we've done until now. Adding a check after the - call seems of limited benefit - if the buffer was overflowed - then it's too late to block it, and most of our uses either have a - fixed maximum possible size or dynamically allocate a buffer that's - large enough. - -2023-04-26: mmomtchev - [Javascript] Take into account numinputs when counting arguments. - -2023-04-24: olly - [PHP] Add throws typemaps for std:string* and const std::string*. - -2023-04-23: olly - [Javascript] #2453 The testsuite and examples now select which - Javascript engine to test based on what was detected by configure. - Previously they'd always test with node you specified a different - engine (e.g. with `ENGINE=jsc` on the make command line). Now you - only need to specify ENGINE if you have more than one engine - installed. - -2023-04-23: olly - [Javascript] Turn on C++ output when wrapping for node, like - we already do when wrapping for V8-without-node. - - The testsuite was masking this bug by using SWIG options - `-v8 -DBUILDING_NODE_EXTENSION=1` rather than `-node` when testing - with nodejs, while the javascript examples were masking this by - all getting processed with -c++. - - This shouldn't be an incompatible change for users, as if you're - wrapping a C API you'd have to be working around the problem before - this change (like our testsuite and examples were), and this change - shouldn't break your workaround - it just makes it unnecessary. - -2023-04-21: mmomtchev - [Javascript] Fix naming of internal C++ helper for wrapping - variables for node to use the "getter" naming scheme rather - than the function wrapping one. In practice this didn't actually - cause problems because Node wrappers are always compiled as C++ - and the parameters are always different even if the names are - the same. - -2023-04-21: olly - [PHP] Support INPUT,INOUT,OUTPUT for std::string&. - - By default SWIG/PHP wraps std::string& as a pass-by-reference PHP - string parameter, but sometimes such a parameter is only for input - or only for output, so add support for the named typemaps that other - target languages support. - -2023-04-21: degasus - #2519 Fix CanCastAsInteger range check to clear errno first to fix - bogus failures for valid inputs.if errno is set. - -2023-04-21: ZackerySpytz - [OCaml] #1439 Fix reference typemaps for std::string - -2023-04-21: olly - #2183 Fix #ifdef and #ifndef to work inside a %define. Previously - they were silently ignored in this context (but #if defined already - worked here if you need a workaround which works for older - versions). - -2023-04-20: erezgeva - [Go] #2533 Implement argcargv.i library for Go. - -2023-04-19: davidcl - [Scilab] Add support for Scilab 2023.x. - Introduce a new `-gatewayxml6` option to generate XML with full - function names. - -2023-04-19: mmomtchev - https://sourceforge.net/p/swig/bugs/1163/ #1882 #2525 - Fix preprocessor expansion when a macro expands to the name of - another macro which takes parameters from the input following the - original macro expansion. - -2023-04-19: wildmaples - [Ruby] #2527 Fix "undefining the allocator of T_DATA" warning seen - with Ruby 3.2. - -2023-04-18: davidcl - [Scilab] #894 extract values with ":" for typemap (int* IN, int IN_SIZE) - -2023-04-14: olly - [PHP7] Support for PHP7 has been removed. PHP7 security support - ended 2022-11-28 so it doesn't make sense to include support for - it in the SWIG 4.2.x release series. - - *** POTENTIAL INCOMPATIBILITY *** - -2023-04-05: wsfulton - [Python] #2515 Add support for all STL containers to be constructible from a Python set. - - The previous implementation used the Python Sequence Protocol to convert from Python types - to STL containers. The new implementation uses the Python Iterator Protocol instead and - thereby can convert from a Python set too. - -2023-03-25: alatina - [Octave] #2512 Add support for Octave 8.1. - -2023-03-22: wsfulton - [C#] #2478 Minor enhancements to std::array wrappers in std_array.i. - -2023-03-13: wsfulton - Improved error checking when using %template to instantiate templates within - the correct scope. - - 1. When a template is instantiated via %template and uses the unary scope - operator ::, an error occurs if the instantiation is attempted within a - namespace that does not enclose the instantiated template. - For example, the following will now error as ::test::max is not enclosed within test1: - - Error: '::test::max' resolves to 'test::max' and was incorrectly instantiated in - scope 'test1' instead of within scope 'test'. - namespace test1 { - %template(maxchar) ::test::max; - } - - 2. SWIG previously failed to always detect a template did not exist when using - %template. In particular when instantiating a global template incorrectly within - namespace. The code below now correctly emits an error: - - Error: Template 'test5::GlobalVector' undefined. - namespace test5 { - } - template struct GlobalVector {}; - %template(GVI) test5::GlobalVector; - -2023-03-13: wsfulton - Error out if an attempt is made to define a class using the unary scope - operator ::. The following is not legal C++ and now results in an error: - - Error: Using the unary scope operator :: in class definition '::Space2::B' is invalid. - namespace Space2 { - struct B; - } - struct ::Space2::B {}; - -2023-03-08: wsfulton - Fix duplicate const in generated code when template instantiation type is const - and use of template parameter is also explicitly const, such as: - - template struct Conster { - void cccc1(T const& t) {} - }; - %template(ConsterInt) Conster; - - Above previously led to generated code: - (arg1)->cccc1((int const const &)*arg2); - instead of - (arg1)->cccc1((int const &)*arg2); - -2023-03-01: wsfulton - Partial template specialization fixes to support default arguments from the primary - template's parameter list. - - template struct X { void primary() {} }; - // Previously the specialization below resulted in: - // Error: Inconsistent argument count in template partial specialization. 1 2 - template struct X { void special(YY*) {} }; - - // Both of these correctly wrap the partially specialized template - %template(StringPtr) X; - %template(ShortPtr) X; - -2023-02-15: wsfulton - #1300 Further partial template specialization fixes. - Fixes when templates are used as a template parameter in a partially specialized - instantiation such as: - - template struct Vect {}; - template class Foo { ... }; - template class Foo, TTS> { ... }; - %template(VectInt) Vect; - %template(FooVectIntDouble) Foo, double>; // was previously attempting to use primary template - - Also fixes partial specialization where the same template parameter name is used twice, - for example: - - template struct H { ... }; - template struct H { ... }; - %template(HInts) H; // was previously attempting to use primary template - -2023-01-27: jschueller - #2492 [python] Fix unused parameter warnings for self parameter in - generated C/C++ wrapper code. - -2023-01-14: wsfulton - Fix deduction of partially specialized template parameters when the specialized - parameter is non-trivial, used in a wrapped method and the type to %template uses - typedefs. For example: - - typedef double & DoubleRef; - template struct XX {}; - template struct XX { void fn(T t) {} }; - %template(XXD) XX; - - The type of the parameter in the instantiated template for fn is now correctly deduced - as double. - -2023-01-03: wsfulton - #983 Fix seg fault when instantiating templates with parameters that are function - parameters containing templates, such as: - - %template(MyC) C)>; - -2023-01-03: wsfulton - Complete support for C++11 variadic function templates. Support was previously limited - to just one template parameter. Now zero or more template parameters are supported - in the %template instantiation. - -2022-12-29: wsfulton - #1863 Syntax error fixes parsing more elaborate parameter pack arguments that are - used in function pointers, member function pointers: - - template struct VariadicParms { - void ParmsFuncPtrPtr(int (*)(V*...)) {} - void ParmsFuncPtrPtrRef(int (*)(V*&...)) {} - void ParmsFuncPtrPtrRValueRef(int (*)(V*&&...)) {} - void ParmsFuncPtrRef(int (*)(V&...)) {} - void ParmsFuncPtrRValueRef(int (*)(V&&...)) {} - - void ParmsMemFuncPtrPtr(int (KlassMemFuncs::*)(V*...)) {} - void ParmsMemFuncPtrPtrRef(int (KlassMemFuncs::*)(V*&...)) {} - void ParmsMemFuncPtrPtrRValueRef(int (KlassMemFuncs::*)(V*&&...)) {} - void ParmsMemFuncPtrRef(int (KlassMemFuncs::*)(V&...)) {} - void ParmsMemFuncPtrRValueRef(int (KlassMemFuncs::*)(V&&...)) {} - }; - - %template(VariadicParms0) VariadicParms<>; - %template(VariadicParms1) VariadicParms; - - Also in various other places such as within noexcept specifiers: - - template - void emplace(Args &&... args) noexcept( - std::is_nothrow_constructible::value); - -2022-12-27: wsfulton - Fix instantiation of variadic class templates containing parameter pack arguments that - are function pointers. - - template struct VariadicParms { - void ParmsFuncPtrVal(int (*)(V...)) {} - }; - - %template(VariadicParms0) VariadicParms<>; - %template(VariadicParms1) VariadicParms; - -2022-12-23: wsfulton - #1863 Fix syntax error parsing variadic templates containing parameter pack arguments that - are function pointers. - -2022-12-22: wsfulton - Complete support for C++11 variadic class templates. Support was previously limited - to just one template parameter. Now zero or more template parameters are supported. - -2022-12-06: wsfulton - #1636 Fix syntax error for misplaced Doxygen comment after struct/class member. - Fix syntax error using Doxygen member groups syntax, "///*}", when used after - final struct/class member. - -2022-12-05: wsfulton - #2023 Fix garbled Doxygen post comments in parameter lists. - Fix syntax error parsing a trailing Doxygen comment in parameter lists. - -2022-12-03: wsfulton - #1609 Fix syntax error parsing of Doxygen comments after last enum item. - -2022-12-03: wsfulton - #1715 Fix syntax error parsing of unconventionally placed Doxygen post - comments for enum items. - -2022-12-02: wsfulton - #624 #1021 Improved template template parameters support. Previously, specifying more - than one simple template template parameter resulted in a parse error. Now - multiple template template parameters are working including instantiation with - %template. Example: - - template class, class> class Op, template class X, class Y> - class C { ... }; - -2022-11-26: wsfulton - #1589 #1590 Slightly better decltype() support for expressions, such as: - - int i; - ... decltype(&i) ... - - These result in a warning for non-trivial expressions which SWIG cannot evaluate: - - Warning 344: Unable to deduce decltype for '&i'. - - See 'Type Inference' in CPlusPlus.html for workarounds. - -2022-11-22: wsfulton - #366 #1037 Fix seg fault handling template parameter expressions - containing '<=' or '>='. - -2022-11-18: wsfulton - Duplicate class template instantiations via %template now issue a warning and are ignored. - - %template(Aint) A; - %template(Aint2) A; // Now ignored and issues a warning - - example.i:7: Warning 404: Duplicate template instantiation of 'A< int >' with name 'Aint2' ignored, - example.i:6: Warning 404: previous instantiation of 'A< int >' with name 'Aint'. - - A single empty template instantiation before a named instantiation is the one exception - for allowing duplicate template instantiations as the empty template instantiation does not - create a wrapper for the template, it merely adds the instantiation into SWIG's internal - type system. - Duplicate empty template instantiations are quietly ignored. - - %template() B; - %template(Bint) B; // OK - - %template() C; - %template() C; // Quietly ignored now - %template(Cint) C; // OK - - Note that default template parameters are considered when looking for duplicates such as: - - template struct D {}; - %template(Dint) D; - %template(Dintshort) D; - - example.i:7: Warning 404: Duplicate template instantiation of 'D< int,short >' with name 'Dintshort' ignored, - example.i:6: Warning 404: previous instantiation of 'D< int >' with name 'Dint'. - - Note that the following always was ignored, but that was because the chosen name was a - duplicate rather than the template being a duplicate: - - %template(Eint) E; - %template(Eint) E; // Always has been ignored as a redefined identifier - - The old warning was: - - example.i:7: Warning 302: Identifier 'Eint' redefined (ignored) (Renamed from 'E< int >'), - example.i:6: Warning 302: previous definition of 'Eint' (Renamed from 'E< int >'). - - *** POTENTIAL INCOMPATIBILITY *** +2024-01-06: wsfulton + [Python] #2744 Regression fix - add in missing SwigPyIterator_T fragment for + SwigPyIteratorClosed_T when using %import on an instantiated std::map. diff --git a/CMakeLists.txt b/CMakeLists.txt index 09db262d27b..ba06761dcc7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,7 +91,7 @@ option (WITH_PCRE "Enable PCRE" OFF) configure_file (${SWIG_ROOT}/Tools/cmake/swigconfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/Source/Include/swigconfig.h) -find_package (BISON REQUIRED) +find_package (BISON 3.5 REQUIRED) # Compiler flags diff --git a/Doc/Devel/internals.html b/Doc/Devel/internals.html index af844922708..51fc7dad42c 100644 --- a/Doc/Devel/internals.html +++ b/Doc/Devel/internals.html @@ -555,7 +555,7 @@

3. Types and Typemaps

  • SwigType_str(SwigType *t, char *name).
    This function produces the exact string representation of the datatype t. name is an optional parameter that -specifies a declaration name. This is used when dealing with more complicated datatypes +specifies a declaration name and can be NULL. This is used when dealing with more complicated datatypes such as arrays and pointers to functions where the output might look something like "int (*name)(int, double)". diff --git a/Doc/Devel/scanner.html b/Doc/Devel/scanner.html index e663f05f6cb..efa553e0322 100644 --- a/Doc/Devel/scanner.html +++ b/Doc/Devel/scanner.html @@ -112,7 +112,7 @@

    Scanner Functions

    -void Scanner_set_location(Scanner *s, int startchar, int endchar) +void Scanner_set_location(Scanner *s, String *file, int line)

    Changes the current filename and line number of the scanner.
    @@ -136,7 +136,7 @@

    Scanner Functions

    -void Scanner_idstart(Scanner *s, char *idchar) +void Scanner_idstart(Scanner *s, const char *idchar)

    Sets additional characters (other than the C default) that may be used to start C identifiers. idchar is a string containing the characters (e.g., "%@"). The purpose of this function is to up special keywords such as "%module" or "@directive" as diff --git a/Doc/Manual/CSharp.html b/Doc/Manual/CSharp.html index 9e2b6248960..1c0994c4698 100644 --- a/Doc/Manual/CSharp.html +++ b/Doc/Manual/CSharp.html @@ -3185,7 +3185,7 @@

    23.9.9 Underlying type for enums -C# enums use int as the underlying type for each enum item, unless there is a C++11 enum base specifiying the underlying C++ enum type. +C# enums use int as the underlying type for each enum item, unless there is a C++11 enum base specifying the underlying C++ enum type. If there is a C++ base enum then this is automatically converted to the equivalent C# integral type. If you wish to change the underlying type to something else, then use the csbase typemap. For example when your C++ code uses a value larger than int, this is necessary as the C# compiler will not compile values which are too large to fit into an int. diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html index 65cc2a534c6..4aef5978dc3 100644 --- a/Doc/Manual/Contents.html +++ b/Doc/Manual/Contents.html @@ -237,6 +237,12 @@

    6 SWIG and C++

  • Protection
  • Enums and constants
  • Friends +
  • References and pointers
  • Pass and return by value
  • Inheritance diff --git a/Doc/Manual/Ocaml.html b/Doc/Manual/Ocaml.html index ffb9d2cde5f..ba18a7be713 100644 --- a/Doc/Manual/Ocaml.html +++ b/Doc/Manual/Ocaml.html @@ -92,7 +92,8 @@

    39.1 Preliminaries

    -SWIG is compatible with OCaml 3.12.0 and above. Given the choice, +SWIG is known to be compatible with OCaml 4.13.1 and above - older versions +are not regularly tested. Given the choice, you should use the latest stable release. The SWIG Ocaml module has been tested on Linux (x86, PPC, Sparc) and Cygwin on Windows. The best way to determine whether your system will work is to compile the diff --git a/Doc/Manual/Octave.html b/Doc/Manual/Octave.html index ca38b4165b1..724fc515745 100644 --- a/Doc/Manual/Octave.html +++ b/Doc/Manual/Octave.html @@ -51,8 +51,8 @@

    30 SWIG and Octave

    - Octave is a high-level language intended for numerical programming that is mostly compatible with MATLAB. -More information can be found at Octave web site. +Octave is a high-level language intended for numerical programming that is mostly compatible with MATLAB. +More information can be found at Octave web site.

    @@ -64,7 +64,8 @@

    30.1 Preliminaries

    -SWIG is regularly tested against the following versions of Octave: 3.8, 4.0, 4.2. +SWIG is regularly tested against the following versions of Octave: 5.2, 6.4. +SWIG 4.2.1 has also been manually tested with 7.3, 8.4 and 9.0.

    @@ -104,9 +105,6 @@

    30.2 Running SWIG

    $ swig -octave -c++ -o example_wrap.cpp example.i 
    -

    -This creates a C++ source file "example_wrap.cpp". A C++ file is generated even when wrapping C code as Octave is itself written in C++ and requires wrapper code to be in the same language. The generated C++ source file contains the low-level wrappers that need to be compiled and linked with the rest of your C/C++ application (in this case, the gcd implementation) to create an extension module. -

    30.2.1 Command-line options

    @@ -865,6 +863,7 @@

    30.3.15 Memory management

    As noted above, swig_ref represents a reference counted pointer to a C/C++-side object. It also contains a flag indicating whether Octave or the C/C++ code owns the object. If Octave owns it, any destructors will be called when the reference count reaches zero. If the C/C++ side owns the object, then destructors will not be called when the reference count goes to zero. +As noted above, swig_ref represents a reference counted pointer to a C/C++-side object. It also contains a flag indicating whether Octave or the C/C++ code owns the object. If Octave owns it, any destructors will be called when the reference count reaches zero. If the C/C++ side owns the object, then destructors will not be called when the reference count goes to zero.

    For example, diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html index 9499063f0d6..17cfde3b5fd 100644 --- a/Doc/Manual/SWIGPlus.html +++ b/Doc/Manual/SWIGPlus.html @@ -34,6 +34,12 @@

    6 SWIG and C++

  • Protection
  • Enums and constants
  • Friends +
  • References and pointers
  • Pass and return by value
  • Inheritance @@ -93,8 +99,8 @@

    6 SWIG and C++

    It is mostly concerned about C++ as defined by the C++ 98 and 03 standards. For additions to the original C++ standard, please read the SWIG and C++11, -SWIG and C++14 and -SWIG and C++17 chapters. +SWIG and C++14, +SWIG and C++17 and SWIG and C++20 chapters. As a prerequisite, you should first read the chapter SWIG Basics to see @@ -1167,64 +1173,218 @@

    6.8 Enums and constants

    6.9 Friends

    +

    6.9.1 Friend classes

    + +

    -Friend declarations are recognised by SWIG. For example, if -you have this code: +Friend classes are a C++ feature that do not affect SWIG wrappers. +SWIG simply parses the friend class declarations, but they are effectively ignored +as they have no meaningful effect for wrappers. +An example of friend classes:

    -class Foo {
    -public:
    +class X;
    +class Y;
    +class C {
    +  // Friend classes have no effect on generated wrappers
    +  friend class X;
    +  friend Y;
       ...
    -  friend void blah(Foo *f);
    +};
    +
    +
    + +

    6.9.2 Friend function definitions

    + + +

    +A friend function definition in a C++ class defines a non-member function of the class +and simultaneously makes it a friend of the class. +For example, if you have this code: +

    + +
    +
    +class Buddy {
    +  int val;
    +  friend int blah(Buddy *b) { return b->val; }
    +public:
       ...
     };
     

    -then the friend declaration does result in a wrapper code -equivalent to one generated for the following declaration +then the friend function definition results in wrapper code +equivalent to one generated for the following:

    -class Foo {
    +class Buddy {
    +  int val;
    +  friend int blah(Buddy *b);
     public:
       ...
     };
     
    -void blah(Foo *f);    
    +int blah(Buddy *b) { return b->val; }
     

    -A friend declaration, as in C++, is understood to be in the same scope -where the class is declared, hence, you can have +Access from target languages is thus as if blah was wrapped as a non-member function. +The function is available and wrapped even if the friend is defined with private or protected access. +

    + +

    +A friend definition, as in C++, is understood to be in the same scope +that the class is defined in, hence the scoping required for SWIG directives, such as %ignore, is as follows:

    -
    -%ignore bar::blah(Foo *f);
    +%ignore bar::blah(Buddy *b);
    +// Not: %ignore bar::Buddy::blah(Buddy *b);
     
     namespace bar {
    -
    -  class Foo {
    +  class Buddy {
    +    int val;
    +    friend int blah(Buddy *b) { return b->val; }
       public:
         ...
    -    friend void blah(Foo *f);
    -    ...
       };
     }
     

    -and a wrapper for the method 'blah' will not be generated. +and a wrapper for blah will not be generated. +

    + +

    6.9.3 Friend function declarations

    + + +

    +A C++ class can specify friends via friend function declarations. +These functions are allowed access to the private and protected members of a class. +This is pure C++ functionality and these friend function declarations are hence quietly ignored by SWIG and do not result in any wrappers. +Well, not always! The C++ rules for friends that SWIG needs to follow are not that simple. +Technically, only qualified function declarations are silently ignored by SWIG. +Below are some examples of qualified friend declarations in A that are quietly ignored: +

    + +
    +
    +struct B {
    +  int f();
    +  B();
    +  ~B();
    +  ...
    +};
    +
    +int g();
    +
    +class A {
    +public:
    +  // The following friend function-declarations are silently ignored (including constructor and destructor friends)
    +  friend B::B();
    +  friend B::~B();
    +  friend int B::f();
    +  friend int ::g();
    +  ...
    +};
    +
    +
    + +

    +In the example above, if SWIG parses the struct B and global function g(), +then they are of course wrapped as normal. +

    + + +

    6.9.4 Unqualified friend functions

    + + +

    +Further clarification is required regarding both friend function definitions and declarations. +In C++, friend function definitions can only be unqualified, whereas, friend function declarations can be either unqualified or qualified. Qualified friend function declarations are silently ignored by SWIG as covered in the previous section. SWIG does generate wrappers for any unqualified friend functions that it parses. This section goes through some of the complexities of wrapping unqualified friend functions. +

    + +

    +Consider an unqualified friend function definition: +

    + +
    +
    +class Chum {
    +  int val;
    +  friend int blah() { Chum c; c.private_function(); return c.val; }
    +  void private_function();
    +public:
    +  ...
    +};
    +
    +
    + +

    +The Chum::blah() friend is very similar to the Buddy::blah(Buddy *) friend presented earlier. +However, the generated code to call blah() may not compile unlike the code to call blah(Buddy *). +The compiler error will be something like: + +

    +
    +error: 'blah' was not declared in this scope
    +
    +
    + +

    +The reason one works and the other doesn't is due to the rules around unqualified friend definitions/declarations. Broadly, friends are not visible for lookup except via argument dependent lookup that considers the class that the friend is defined/declared in, unless there is a matching declaration at namespace scope. +This will probably only make sense if you are conversant with this C++ concept, which is covered quite well at Argument-dependent lookup. +In our examples, blah(Buddy *) is visible via argument dependent lookup, but blah() is not. The solution is thus to provide a matching declaration in order to make the function visible to the compiler. Simply add:

    +
    +
    +int blah();
    +
    +
    + +

    +SWIG does not have to parse it. In all likelihood, your code already has the matching declaration as it is required in order for the friend function definition to be usable from pure C++ code. +

    + +

    +The same potential problem applies to unqualified friend function declarations, such as: +

    + +
    +
    +class Mate {
    +  int val;
    +  friend int blah(); // Unqualified friend function declaration
    +  void private_function();
    +public:
    +  ...
    +};
    +
    +
    + +

    +Again, the actual function declaration needs to be visible to the compiler. +Or just the actual function definition as shown below. +This must be defined in the same scope as Mate. +Of course the function definition is necessary in order to avoid linking issues too. +

    + +
    +
    +int blah() { Mate m; m.private_function(); return m.val; }
    +
    +
    +

    6.10 References and pointers

    @@ -4343,8 +4503,8 @@

    6.19 Namespaces

    -example.i:26. Error. 'foo' is multiply defined in the generated target language module.
    -example.i:23. Previous declaration of 'foo'
    +example.i:26: Error: 'foo' is multiply defined in the generated target language module.
    +example.i:23: Error: Previous declaration of 'foo'
     
    diff --git a/Doc/Manual/Sections.html b/Doc/Manual/Sections.html index 7a635343e1d..cd848e0c4b9 100644 --- a/Doc/Manual/Sections.html +++ b/Doc/Manual/Sections.html @@ -8,7 +8,7 @@

    SWIG-4.2 Documentation

    -Last update : SWIG-4.2.0 (30 Dec 2023) +Last update : SWIG-4.2.1 (24 Feb 2024)

    Sections

    diff --git a/Doc/Manual/Tcl.html b/Doc/Manual/Tcl.html index dd3e843e42f..df9dd0fb0fa 100644 --- a/Doc/Manual/Tcl.html +++ b/Doc/Manual/Tcl.html @@ -81,7 +81,7 @@

    37 SWIG and Tcl

    This chapter discusses SWIG's support of Tcl. Since SWIG 4.1.0, Tcl 8.4 or a later release is required. Prior to that earlier Tcl 8.x releases were also -supported. +supported. Tcl 9.0 is supported since SWIG 4.2.1.

    37.1 Preliminaries

    diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html index 2085b7fd0d2..0e646e5e46d 100644 --- a/Doc/Manual/Warnings.html +++ b/Doc/Manual/Warnings.html @@ -394,16 +394,14 @@

    19.9.3 C/C++ Parser (300-399)

  • 301. class keyword used, but not in C++ mode.
  • 302. Redefinition of identifier 'name' as decl ignored.
  • 303. %extend defined for an undeclared class 'name'. +
  • 304. Unsupported constant value (ignored).
  • 305. Bad constant value (ignored). -
  • 306. 'identifier' is private in this context.
  • 308. Namespace alias 'name' not allowed here. Assuming 'name'
  • 309. [private | protected] inheritance ignored. -
  • 310. Template 'name' was already wrapped as 'name' (ignored)
  • 312. Unnamed nested class not currently supported (ignored).
  • 313. Unrecognized extern type "name" (ignored).
  • 314. 'identifier' is a lang keyword.
  • 315. Nothing known about 'identifier'. -
  • 316. Repeated %module directive.
  • 317. Specialization of non-template 'name'.
  • 318. Instantiation of template 'name' is ambiguous, instantiation templ used, instantiation templ ignored.
  • 319. No access specifier given for base class name (ignored). @@ -415,6 +413,8 @@

    19.9.3 C/C++ Parser (300-399)

  • 325. Nested kind not currently supported (name ignored).
  • 326. Deprecated %extend name used - the kind name 'name' should be used instead of the typedef name 'name'.
  • 327. Extern template ignored. +
  • 328. Value assigned to name not used due to limited parsing implementation. +
  • 329. Using declaration 'name' for inheriting constructors uses base 'name' which is not an immediate base of 'name'.
  • 340. Lambda expressions and closures are not fully supported yet.
  • 344. Unable to deduce decltype for 'expr'.
  • 345. Unable to deduce auto return type for 'name' (ignored). @@ -465,6 +465,8 @@

    19.9.3 C/C++ Parser (300-399)

  • 393. operator& ignored (unary).
  • 394. operator new[] ignored.
  • 395. operator delete[] ignored. +
  • 396. operator*() ignored. +
  • 397. operator<=> delete[] ignored.

    19.9.4 Types and typemaps (400-499)

    @@ -475,10 +477,13 @@

    19.9.4 Types and typemaps (400-499)

  • 402. Base class 'name' is incomplete.
  • 403. Class 'name' might be abstract.
  • 404. Duplicate template instantiation of 'type' with name 'name' ignored, previous instantiation of 'type' with name 'name'. +
  • 405. Method with rvalue ref-qualifier name ignored.
  • 450. Reserved
  • 451. Setting const char * variable may leak memory.
  • 452. Reserved
  • 453. Can't apply (pattern). No typemaps are defined. +
  • 454. Setting a pointer/reference variable may leak memory +
  • 455. Setting a const wchar_t * variable may leak memory.
  • 460. Unable to use type type as a function argument.
  • 461. Unable to use return type type in function name.
  • 462. Unable to set variable of type type. @@ -497,6 +502,7 @@

    19.9.4 Types and typemaps (400-499)

  • 475. Multiple calls to method might be generated due to optimal attribute usage in the out typemap.
  • 476. Initialization using std::initializer_list.
  • 477. No directorthrows typemap defined for type +
  • 490. Fragment 'name' not found. diff --git a/Examples/ocaml/std_vector/runme.ml b/Examples/ocaml/std_vector/runme.ml index 0f5519b6f0b..dc2fcf9cfa8 100644 --- a/Examples/ocaml/std_vector/runme.ml +++ b/Examples/ocaml/std_vector/runme.ml @@ -23,13 +23,13 @@ let v = new_DoubleVector '() let rec fill_dv v x = if x < 0.0001 then v else begin - v -> push_back ((x to float)) ; + ignore(v -> push_back ((x to float))) ; fill_dv v (x *. x) end let _ = fill_dv v 0.999 let _ = print_DoubleVector v let u = new_IntVector '() let _ = for i = 1 to 4 do - u -> push_back ((i to int)) + ignore(u -> push_back ((i to int))) done let _ = (print_float ((_average u) as float) ; print_newline ()) diff --git a/Examples/ocaml/stl/runme.ml b/Examples/ocaml/stl/runme.ml index 2fa5d20b81d..3875b2a1427 100644 --- a/Examples/ocaml/stl/runme.ml +++ b/Examples/ocaml/stl/runme.ml @@ -7,7 +7,7 @@ let v = new_StringVector '() let _ = for i = 0 to (Array.length Sys.argv) - 1 do - let str = (Sys.argv.(i)) to string in v -> push_back (str) + let str = (Sys.argv.(i)) to string in ignore(v -> push_back (str)) done let _ = _vec_write '(v) diff --git a/Examples/python/check.list b/Examples/python/check.list index 025278f899d..a9c4aef73ef 100644 --- a/Examples/python/check.list +++ b/Examples/python/check.list @@ -15,7 +15,6 @@ functor import import_packages import_template -#libffi multimap operator pointer diff --git a/Examples/python/libffi/Makefile b/Examples/python/libffi/Makefile deleted file mode 100644 index 0875fdd9666..00000000000 --- a/Examples/python/libffi/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -TOP = ../.. -SWIGEXE = $(TOP)/../swig -SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib -SRCS = -TARGET = example -INTERFACE = example.i - -check: build - $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_run - -build: - $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \ - SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \ - TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' LIBS='-L/usr/local/lib -lffi' python - -static: - $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \ - SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \ - TARGET='mypython' INTERFACE='$(INTERFACE)' python_static - -clean: - $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='$(TARGET)' python_clean diff --git a/Examples/python/libffi/example.i b/Examples/python/libffi/example.i deleted file mode 100644 index 3f5d766c56f..00000000000 --- a/Examples/python/libffi/example.i +++ /dev/null @@ -1,176 +0,0 @@ -/* File : example.i */ -%module example - -%{ -#include -#include -%} - -/* A wrapper for execlp() using libffi to handle an arbitrary - number of arguments */ - -%typemap(in) (...) { - char **argv; - int argc; - int i; - - argc = PyTuple_Size(varargs); - argv = (char **) malloc(sizeof(char *)*(argc+1)); - for (i = 0; i < argc; i++) { - PyObject *o = PyTuple_GetItem(varargs,i); - if (!PyString_Check(o)) { - PyErr_SetString(PyExc_ValueError,"Expected a string"); - SWIG_fail; - } - argv[i] = PyString_AsString(o); - } - argv[i] = NULL; - $1 = (void *) argv; -} - -/* Rewrite the function call, using libffi */ -%feature("action") execlp { - int i, vc; - ffi_cif cif; - ffi_type **types; - void **values; - char **args; - - vc = PyTuple_Size(varargs); - types = (ffi_type **) malloc((vc+3)*sizeof(ffi_type *)); - values = (void **) malloc((vc+3)*sizeof(void *)); - args = (char **) arg3; - - /* Set up path parameter */ - types[0] = &ffi_type_pointer; - values[0] = &arg1; - - /* Set up first argument */ - types[1] = &ffi_type_pointer; - values[1] = &arg2; - - /* Set up rest of parameters */ - for (i = 0; i <= vc; i++) { - types[2+i] = &ffi_type_pointer; - values[2+i] = &args[i]; - } - if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+3, - &ffi_type_uint, types) == FFI_OK) { - ffi_call(&cif, (void (*)()) execlp, &result, values); - } else { - free(types); - free(values); - free(arg3); - PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!"); - SWIG_fail; - } - free(types); - free(values); - free(arg3); -} - -int execlp(const char *path, const char *arg1, ...); - - -/* A wrapper for printf() using libffi */ - -%{ - typedef struct { - int type; - union { - int ivalue; - double dvalue; - void *pvalue; - } val; - } vtype; - enum { VT_INT, VT_DOUBLE, VT_POINTER }; - %} - -%typemap(in) (const char *fmt, ...) { - vtype *argv; - int argc; - int i; - - $1 = PyString_AsString($input); - - argc = PyTuple_Size(varargs); - argv = (vtype *) malloc(argc*sizeof(vtype)); - for (i = 0; i < argc; i++) { - PyObject *o = PyTuple_GetItem(varargs,i); - if (PyInt_Check(o)) { - argv[i].type = VT_INT; - argv[i].val.ivalue = PyInt_AsLong(o); - } else if (PyFloat_Check(o)) { - argv[i].type = VT_DOUBLE; - argv[i].val.dvalue = PyFloat_AsDouble(o); - } else if (PyString_Check(o)) { - argv[i].type = VT_POINTER; - argv[i].val.pvalue = (void *) PyString_AsString(o); - } else { - free(argv); - PyErr_SetString(PyExc_ValueError,"Unsupported argument type"); - SWIG_fail; - } - } - - $2 = (void *) argv; -} - -/* Rewrite the function call, using libffi */ -%feature("action") printf { - int i, vc; - ffi_cif cif; - ffi_type **types; - void **values; - vtype *args; - - vc = PyTuple_Size(varargs); - types = (ffi_type **) malloc((vc+1)*sizeof(ffi_type *)); - values = (void **) malloc((vc+1)*sizeof(void *)); - args = (vtype *) arg2; - - /* Set up fmt parameter */ - types[0] = &ffi_type_pointer; - values[0] = &arg1; - - /* Set up rest of parameters */ - for (i = 0; i < vc; i++) { - switch(args[i].type) { - case VT_INT: - types[1+i] = &ffi_type_uint; - values[1+i] = &args[i].val.ivalue; - break; - case VT_DOUBLE: - types[1+i] = &ffi_type_double; - values[1+i] = &args[i].val.dvalue; - break; - case VT_POINTER: - types[1+i] = &ffi_type_pointer; - values[1+i] = &args[i].val.pvalue; - break; - default: - abort(); /* Whoa! We're seriously hosed */ - break; - } - } - if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+1, - &ffi_type_uint, types) == FFI_OK) { - ffi_call(&cif, (void (*)()) printf, &result, values); - } else { - free(types); - free(values); - free(args); - PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!"); - SWIG_fail; - } - free(types); - free(values); - free(args); -} - -int printf(const char *fmt, ...); - - - - - diff --git a/Examples/tcl/multimap/example.i b/Examples/tcl/multimap/example.i index 272c022394b..60ab419493b 100644 --- a/Examples/tcl/multimap/example.i +++ b/Examples/tcl/multimap/example.i @@ -19,10 +19,12 @@ extern int gcd(int x, int y); %typemap(in) (int argc, char *argv[]) { Tcl_Obj **listobjv = 0; int i; - if (Tcl_ListObjGetElements(interp,$input, &$1, &listobjv) == TCL_ERROR) { + Tcl_Size tmpSize; + if (Tcl_ListObjGetElements(interp,$input, &tmpSize, &listobjv) == TCL_ERROR) { SWIG_exception(SWIG_ValueError,"Expected a list"); return TCL_ERROR; } + $1 = (int)tmpSize; $2 = (char **) malloc(($1+1)*sizeof(char *)); for (i = 0; i < $1; i++) { $2[i] = Tcl_GetString(listobjv[i]); @@ -37,7 +39,9 @@ extern int gcd(int x, int y); extern int gcdmain(int argc, char *argv[]); %typemap(in) (char *bytes, int len) { - $1 = Tcl_GetStringFromObj($input,&$2); + Tcl_Size tmpSize; + $1 = Tcl_GetStringFromObj($input,&tmpSize); + $2 = (int)tmpSize; } extern int count(char *bytes, int len, char c); @@ -47,7 +51,9 @@ extern int count(char *bytes, int len, char c); %typemap(in) (char *str, int len) { char *temp; - temp = Tcl_GetStringFromObj($input,&$2); + Tcl_Size tmpSize; + temp = Tcl_GetStringFromObj($input,&tmpSize); + $2 = (int)tmpSize; $1 = (char *) malloc($2+1); memmove($1,temp,$2); } diff --git a/Examples/test-suite/ccomplextest.i b/Examples/test-suite/ccomplextest.i index c631dc02e25..0530aa08ba8 100644 --- a/Examples/test-suite/ccomplextest.i +++ b/Examples/test-suite/ccomplextest.i @@ -5,7 +5,7 @@ %{ #include -#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199001L +#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L && !defined __STDC_NO_COMPLEX__ #define HAS_C99_COMPLEX_FOR_TESTING 1 #else /* c99 complex not supported - super hack tests to just test plain floating point numbers */ @@ -26,6 +26,11 @@ #endif %} +%inline %{ +static float _Complex CPLX_CONSTANT_ = 0; +%} +%constant CPLX_CONSTANT = CPLX_CONSTANT_; + %inline { int has_c99_complex(void) { diff --git a/Examples/test-suite/class_scope_weird.i b/Examples/test-suite/class_scope_weird.i index cc55dc88006..d7409f23e96 100644 --- a/Examples/test-suite/class_scope_weird.i +++ b/Examples/test-suite/class_scope_weird.i @@ -3,22 +3,24 @@ // Use this version with extra qualifiers to test SWIG as some compilers accept this class Foo { public: - Foo::Foo(void) {} + Foo::Foo() {} Foo::Foo(int) {} int Foo::bar(int x) { return x; } + void Foo::member() { } }; // Remove extra qualifiers for the compiler as some compilers won't compile the extra qaulification (eg gcc-4.1 onwards) %{ class Foo { public: - Foo(void) {} + Foo() {} Foo(int) {} int bar(int x) { return x; } + void member() { } }; %} @@ -37,7 +39,7 @@ public: Quat::Quat(const matrix4& m){} }; -// Remove extra qualifiers for the compiler as some compilers won't compile the extra qaulification (eg gcc-4.1 onwards) +// Remove extra qualifiers for the compiler as some compilers won't compile the extra qualification (eg gcc-4.1 onwards) %{ class Quat { public: diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 0f6010bc03e..b75d7fe34b1 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -263,6 +263,7 @@ CPP_TEST_CASES += \ features \ fragments \ friends \ + friends_operator_overloading \ friends_template \ funcptr_cpp \ functors \ @@ -462,6 +463,7 @@ CPP_TEST_CASES += \ template_default_inherit \ template_default_qualify \ template_default_vw \ + template_duplicate \ template_empty_inherit \ template_enum \ template_enum_ns_inherit \ @@ -648,6 +650,7 @@ CPP11_TEST_CASES += \ cpp11_template_double_brackets \ cpp11_template_explicit \ cpp11_template_parameters_decltype \ + cpp11_template_templated_methods \ cpp11_template_typedefs \ cpp11_type_traits \ cpp11_type_aliasing \ diff --git a/Examples/test-suite/constant_directive.i b/Examples/test-suite/constant_directive.i index 3e4775df1d8..f30123b3feb 100644 --- a/Examples/test-suite/constant_directive.i +++ b/Examples/test-suite/constant_directive.i @@ -52,3 +52,13 @@ Type1 getType1Instance() { return Type1(111); } /* Regular constant */ %constant int TYPE_INT = 0; %constant enum EnumType newValue = enumValue; + +/* Test handling of %constant with an implicit type which SWIG can't handle. */ +#pragma SWIG nowarn=SWIGWARN_PARSE_UNSUPPORTED_VALUE +%ignore ignored_int_variable; +%inline %{ +int ignored_int_variable = 42; +%} +%constant unsupported_constant_value1 = &ignored_int_variable; +%constant unsupported_constant_value2 = getType1Instance; +%constant unsupported_constant_value3 = &getType1Instance; diff --git a/Examples/test-suite/cpp11_decltype.i b/Examples/test-suite/cpp11_decltype.i index 0ac70648483..6855f3d470c 100644 --- a/Examples/test-suite/cpp11_decltype.i +++ b/Examples/test-suite/cpp11_decltype.i @@ -58,6 +58,13 @@ decltype(~'x') should_be_int3; decltype(int(0)) should_be_int4; + decltype((int)0.0) should_be_int5; + decltype((6)-7) should_be_int6; + decltype((6)+7) should_be_int7; + decltype((6)*7) should_be_int8; + decltype((6)&7) should_be_int9; + enum e { E1 }; + decltype(+E1) should_be_int10; static constexpr decltype(*"abc") should_be_char = 0; @@ -67,7 +74,6 @@ // so this would end up wrapped as int. decltype(!0) should_be_bool; - enum e { E1 }; decltype(E1) should_be_enum; auto get_number_sum(decltype(i+j) a) -> decltype(i+j) { diff --git a/Examples/test-suite/cpp11_shared_ptr_crtp_upcast.i b/Examples/test-suite/cpp11_shared_ptr_crtp_upcast.i new file mode 100644 index 00000000000..f00dc1ff46e --- /dev/null +++ b/Examples/test-suite/cpp11_shared_ptr_crtp_upcast.i @@ -0,0 +1,92 @@ +%module cpp11_shared_ptr_crtp_upcast + +// Cutdown testcase for assert reported in https://github.com/swig/swig/issues/2768 +// Note that this test has CRTP and %template instantiations for DiscretisedDensity template parameters not fully resolved + +%warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, + SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_RUBY_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) stir::DiscretisedDensity<3,float>; + +%include + +%{ +#include +namespace stir {} +using namespace stir; +%} + +%inline %{ +namespace stir { + // Note: CRTP + template + class RegisteredParsingObject : public Parent { + }; +} +%} + +%shared_ptr(stir::Array<3,float>) +%inline %{ +namespace stir { + template + class Array { + }; +} +%} +%template(FloatArray3D) stir::Array<3,float>; + +%shared_ptr(stir::ExamData); +%inline %{ +namespace stir { + class ExamData { + }; +} +%} + +%shared_ptr(stir::DiscretisedDensity<3,float>) +%inline %{ +namespace stir { + template + class DiscretisedDensity : public ExamData, public Array { + }; +} +%} + +%shared_ptr(stir::DataProcessor >) +%shared_ptr(stir::RegisteredParsingObject< + stir::ChainedDataProcessor >, + stir::DataProcessor >, + stir::DataProcessor > >) +%shared_ptr(stir::ChainedDataProcessor >) + +%inline %{ +namespace stir { + template + class DataProcessor { + }; + + template + class ChainedDataProcessor : public RegisteredParsingObject< ChainedDataProcessor, DataProcessor, DataProcessor > { + }; +} +%} + +// SWIG will qualify Discretised in the %template() declaration even though Discretised +// is not in scope with the 'using namespace stir' below commented out. +//using namespace stir; +%template(Float3DDiscretisedDensity) stir::DiscretisedDensity<3,float>; +%template(DataProcessor3DFloat) stir::DataProcessor >; +%template(RPChainedDataProcessor3DFloat) stir::RegisteredParsingObject< + stir::ChainedDataProcessor >, + stir::DataProcessor >, + stir::DataProcessor > >; +%template(ChainedDataProcessor3DFloat) stir::ChainedDataProcessor >; + +%inline %{ +void useobject(stir::RegisteredParsingObject< + stir::ChainedDataProcessor >, + stir::DataProcessor >, + stir::DataProcessor > >) { +} +%} diff --git a/Examples/test-suite/cpp11_template_templated_methods.i b/Examples/test-suite/cpp11_template_templated_methods.i new file mode 100644 index 00000000000..712f85c1ba9 --- /dev/null +++ b/Examples/test-suite/cpp11_template_templated_methods.i @@ -0,0 +1,136 @@ +%module cpp11_template_templated_methods + +// Testing templated methods in a template +// Including variadic templated method reported in https://github.com/swig/swig/issues/2794 + +#if defined(SWIGLUA) || defined(SWIGOCAML) +%rename(end_renamed) end; +%rename(begin_renamed) begin; +#endif + +%include + +%inline %{ +namespace eprosima { +namespace fastrtps { + +template < + typename _Ty, + typename _Collection = std::vector<_Ty> > +class ResourceLimitedVector +{ +public: + + using collection_type = _Collection; + using value_type = _Ty; + using pointer = typename collection_type::pointer; + using const_pointer = typename collection_type::const_pointer; + using reference = typename collection_type::reference; + using const_reference = typename collection_type::const_reference; + using size_type = typename collection_type::size_type; + using difference_type = typename collection_type::difference_type; + using iterator = typename collection_type::iterator; + using const_iterator = typename collection_type::const_iterator; + using reverse_iterator = typename collection_type::reverse_iterator; + using const_reverse_iterator = typename collection_type::const_reverse_iterator; + + // Templated method in template + template + void assign( InputIterator first, InputIterator last) + { + size_type n = static_cast(std::distance(first, last)); + InputIterator value = first; + std::advance(value, n); + collection_.assign(first, value); + } + + // Templated method in template using template parameter from the templated method (InputIterator) and the class (_Ty) + template + void assign_and_append( InputIterator first, InputIterator last, const _Ty& val) + { + assign(first, last); + collection_.push_back(val); + } + + // Variadic templated method in template + template + void emplace_back( Args&& ... args ) + { + collection_.emplace_back(args ...); + } + + // Variadic templated constructor in template + template + ResourceLimitedVector( Args&& ... args ) + { + collection_.emplace_back(args ...); + } + + ResourceLimitedVector() + { + } + + collection_type& getCollection() { return collection_; } + +private: + collection_type collection_; +}; + +namespace rtps { + struct octet { + int num; + octet(int i=0) : num(i) {} + }; +} +} +} +%} + +class SimpleIterator {}; + +%{ +#include + +class SimpleIterator +{ + std::vector::iterator it; +public: + using iterator_category = std::forward_iterator_tag; + using value_type = eprosima::fastrtps::rtps::octet; + using difference_type = std::ptrdiff_t; + using pointer = eprosima::fastrtps::rtps::octet *; + using reference = eprosima::fastrtps::rtps::octet &; + SimpleIterator() : it() {} + SimpleIterator(std::vector::iterator it) :it(it) {} + SimpleIterator& operator++() {++it;return *this;} + SimpleIterator operator++(int) {SimpleIterator tmp(*this); operator++(); return tmp;} + bool operator==(const SimpleIterator& rhs) const {return it==rhs.it;} + bool operator!=(const SimpleIterator& rhs) const {return it!=rhs.it;} + eprosima::fastrtps::rtps::octet& operator*() const {return *it;} +}; +%} + +%inline %{ +struct SimpleContainer { + std::vector container; + SimpleContainer(std::vector v) : container(v) {} + SimpleIterator begin() { return SimpleIterator(container.begin()); } + SimpleIterator end() { return SimpleIterator(container.end()); } +}; +%} + +%apply const int & {int &&}; // for emplace_back + +%template(OctetVector) std::vector; +%template(OctetResourceLimitedVector) eprosima::fastrtps::ResourceLimitedVector; +%extend eprosima::fastrtps::ResourceLimitedVector { + %template(assign) assign; + %template(assign_and_append) assign_and_append; + // emplace_back template parameters need to match those in the octet constructor + %template(emplace_back) emplace_back<>; + %template(emplace_back) emplace_back; + %template(emplace_back) emplace_back; + // Variadic templated constructor in template + %template(ResourceLimitedVector) ResourceLimitedVector; + %template(ResourceLimitedVector) ResourceLimitedVector; +} diff --git a/Examples/test-suite/cpp11_variadic_templates.i b/Examples/test-suite/cpp11_variadic_templates.i index 935c2f2f9f2..dfa8f79a5d1 100644 --- a/Examples/test-suite/cpp11_variadic_templates.i +++ b/Examples/test-suite/cpp11_variadic_templates.i @@ -218,3 +218,13 @@ public: %template(FixedAndVariadicParms1) FixedAndVariadicParms; %template(FixedAndVariadicParms2) FixedAndVariadicParms; %template(FixedAndVariadicParms3) FixedAndVariadicParms; + +%inline %{ +struct PlainStruct { + template void ParmsPlainStructVariadic(const VVV& ... args) {} +}; +%} +%template(PlainStructParms0) PlainStruct::ParmsPlainStructVariadic<>; +%template(PlainStructParms1) PlainStruct::ParmsPlainStructVariadic; +%template(PlainStructParms2) PlainStruct::ParmsPlainStructVariadic; +%template(PlainStructParms3) PlainStruct::ParmsPlainStructVariadic; diff --git a/Examples/test-suite/cpp_enum.i b/Examples/test-suite/cpp_enum.i index 548c65de418..83b22a5527b 100644 --- a/Examples/test-suite/cpp_enum.i +++ b/Examples/test-suite/cpp_enum.i @@ -58,3 +58,36 @@ extern "C" typedef enum { PLAY = true, STOP = false } play_state; %} +// Regression test for https://github.com/swig/swig/issues/2796 +// Skip for C# as this enum can't be wrapper as a C# proper enum. +#if defined SWIGCSHARP || defined SWIGD +%ignore Enum2796; +#endif +%inline %{ +typedef int mytype0; +typedef mytype0 mytype1; +#ifndef SWIG +typedef int unknown_to_swig_type; +#endif +typedef unknown_to_swig_type mytype2; + +enum Enum2796 +{ + CASE0A = (mytype0)10, + CASE0B = mytype0(10), + CASE0C = static_cast(10), + CASE1A = (mytype1)10, // Used to fail + CASE1B = mytype1(10), + CASE1C = static_cast(10), + CASE2A = (mytype2)10, // Used to fail + CASE2B = mytype2(10), + CASE2C = static_cast(10), + CASE3A = (unknown_to_swig_type)10, + CASE3B = unknown_to_swig_type(10), + CASE3C = static_cast(10), + CASE4A = (5)*2, + CASE4B = (14)&11, + CASE4C = (3)+7, + CASE4D = (42)-32, +}; +%} diff --git a/Examples/test-suite/csharp/Makefile.in b/Examples/test-suite/csharp/Makefile.in index ca5a59160e9..6bda2ab56d1 100644 --- a/Examples/test-suite/csharp/Makefile.in +++ b/Examples/test-suite/csharp/Makefile.in @@ -41,6 +41,7 @@ CPP_TEST_CASES = \ CPP11_TEST_CASES = \ cpp11_shared_ptr_const \ + cpp11_shared_ptr_crtp_upcast \ cpp11_shared_ptr_nullptr_in_containers \ cpp11_shared_ptr_overload \ cpp11_shared_ptr_template_upcast \ diff --git a/Examples/test-suite/csharp/friends_runme.cs b/Examples/test-suite/csharp/friends_runme.cs index 9dfd9ba0937..b2a2041575e 100644 --- a/Examples/test-suite/csharp/friends_runme.cs +++ b/Examples/test-suite/csharp/friends_runme.cs @@ -2,6 +2,11 @@ using friendsNamespace; public class friends_runme { + private static void check_equal(int a, int b) { + if (a != b) + throw new Exception("Not equal " + a + " != " + b); + } + public static void Main() { A a = new A(2); @@ -38,6 +43,22 @@ public static void Main() { throw new Exception("failed"); if (friends.get_val1(dd) != 1.3) throw new Exception("failed"); + + if (friends.chum_blah() != 1234) + throw new Exception("failed"); + if (friends.mate_blah() != 4321) + throw new Exception("failed"); + + Foe foe = new Foe(111); + check_equal(friends.friend_definition(), 10); + check_equal(friends.friend_declaration(), 11); + check_equal(friends.friend_args_definition(foe), 111); + check_equal(friends.friend_args_declaration(foe), 111); + + check_equal(friends.friend_definition_compiler(), 20); + check_equal(friends.friend_declaration_compiler(), 21); + check_equal(friends.friend_args_definition_compiler(foe), 111); + check_equal(friends.friend_args_declaration_compiler(foe), 111); } } diff --git a/Examples/test-suite/d/Makefile.in b/Examples/test-suite/d/Makefile.in index c9ece61408c..10eddf17aff 100644 --- a/Examples/test-suite/d/Makefile.in +++ b/Examples/test-suite/d/Makefile.in @@ -18,6 +18,7 @@ CPP_TEST_CASES = \ CPP11_TEST_CASES = \ cpp11_shared_ptr_const \ + cpp11_shared_ptr_crtp_upcast \ cpp11_shared_ptr_nullptr_in_containers \ cpp11_shared_ptr_overload \ cpp11_shared_ptr_upcast \ diff --git a/Examples/test-suite/director_using.i b/Examples/test-suite/director_using.i index d86546e86bb..1eec373ab70 100644 --- a/Examples/test-suite/director_using.i +++ b/Examples/test-suite/director_using.i @@ -1,7 +1,5 @@ %module(directors="1",dirprot="1") director_using -%warnfilter(SWIGWARN_PHP_PUBLIC_BASE) FooBar; - %{ #include #include diff --git a/Examples/test-suite/errors/cpp_recursive_typedef.stderr b/Examples/test-suite/errors/cpp_recursive_typedef.stderr index d9135aa4345..b5a59238b6f 100644 --- a/Examples/test-suite/errors/cpp_recursive_typedef.stderr +++ b/Examples/test-suite/errors/cpp_recursive_typedef.stderr @@ -1 +1 @@ -:1: Error: Recursive typedef detected resolving 'pds *' to 'std::set< pds > *' to 'std::set< std::set< pds > > *' and so on... +cpp_recursive_typedef.i:3: Error: Recursive typedef detected resolving 'pds *' to 'std::set< pds > *' to 'std::set< std::set< pds > > *' and so on... diff --git a/Examples/test-suite/errors/cpp_smartptr_feature.i b/Examples/test-suite/errors/cpp_smartptr_feature.i new file mode 100644 index 00000000000..4a0d510cdcf --- /dev/null +++ b/Examples/test-suite/errors/cpp_smartptr_feature.i @@ -0,0 +1,14 @@ +%module xxx + +%feature("smartptr", noblock=1) AA { std::shared_ptr< AA > } +%feature("smartptr", noblock=1) DD { std::shared_ptr< } + + +struct AA {}; +struct BB : AA {}; +struct CC : AA {}; +struct DD : AA {}; + +%feature("smartptr", noblock=1) YY { std::shared_ptr< YY > } +struct XX {}; +struct YY : XX {}; diff --git a/Examples/test-suite/errors/cpp_smartptr_feature.stderr b/Examples/test-suite/errors/cpp_smartptr_feature.stderr new file mode 100644 index 00000000000..442f795ac8c --- /dev/null +++ b/Examples/test-suite/errors/cpp_smartptr_feature.stderr @@ -0,0 +1,5 @@ +cpp_smartptr_feature.i:8: Warning 520: Derived class 'BB' of 'AA' is not similarly marked as a smart pointer. +cpp_smartptr_feature.i:9: Warning 520: Derived class 'CC' of 'AA' is not similarly marked as a smart pointer. +cpp_smartptr_feature.i:10: Error: Invalid type (std::shared_ptr<) in 'smartptr' feature for class DD. +cpp_smartptr_feature.i:10: Warning 520: Derived class 'DD' of 'AA' is not similarly marked as a smart pointer. +cpp_smartptr_feature.i:14: Warning 520: Base class 'XX' of 'YY' is not similarly marked as a smart pointer. diff --git a/Examples/test-suite/errors/cpp_template_duplicate.i b/Examples/test-suite/errors/cpp_template_duplicate.i new file mode 100644 index 00000000000..672c9884f9e --- /dev/null +++ b/Examples/test-suite/errors/cpp_template_duplicate.i @@ -0,0 +1,20 @@ +%module xxx + +%include + +// Note these 404 warnings come from two different places in the SWIG code base + +%inline %{ +typedef unsigned char uint8_T; +typedef unsigned char boolean_T; +%} + +%template(std_vector_boolean_type) std::vector; +%template(std_vector_boolean_type_duplicate) std::vector; +%template(std_vector_uint8_type) std::vector; + +namespace std { +%template(std_vector_boolean_type_again) vector; +%template(std_vector_uint8_type_again) vector; +%template(std_vector_unsigned_char) vector; +} diff --git a/Examples/test-suite/errors/cpp_template_duplicate.stderr b/Examples/test-suite/errors/cpp_template_duplicate.stderr new file mode 100644 index 00000000000..b23e64dbbf9 --- /dev/null +++ b/Examples/test-suite/errors/cpp_template_duplicate.stderr @@ -0,0 +1,10 @@ +cpp_template_duplicate.i:13: Warning 404: Duplicate template instantiation of 'vector< boolean_T >' with name 'std_vector_boolean_type_duplicate' ignored, +cpp_template_duplicate.i:12: Warning 404: previous instantiation of 'vector< boolean_T >' with name 'std_vector_boolean_type'. +cpp_template_duplicate.i:17: Warning 404: Duplicate template instantiation of 'vector< boolean_T >' with name 'std_vector_boolean_type_again' ignored, +cpp_template_duplicate.i:12: Warning 404: previous instantiation of 'vector< boolean_T >' with name 'std_vector_boolean_type'. +cpp_template_duplicate.i:18: Warning 404: Duplicate template instantiation of 'vector< uint8_T >' with name 'std_vector_uint8_type_again' ignored, +cpp_template_duplicate.i:14: Warning 404: previous instantiation of 'vector< uint8_T >' with name 'std_vector_uint8_type'. +cpp_template_duplicate.i:12: Warning 404: Duplicate template instantiation of 'vector< boolean_T >' with name 'std_vector_boolean_type' ignored, +cpp_template_duplicate.i:19: Warning 404: previous instantiation of 'vector< unsigned char >' with name 'std_vector_unsigned_char'. +cpp_template_duplicate.i:14: Warning 404: Duplicate template instantiation of 'vector< uint8_T >' with name 'std_vector_uint8_type' ignored, +cpp_template_duplicate.i:19: Warning 404: previous instantiation of 'vector< unsigned char >' with name 'std_vector_unsigned_char'. diff --git a/Examples/test-suite/errors/cpp_template_missing_base.i b/Examples/test-suite/errors/cpp_template_missing_base.i new file mode 100644 index 00000000000..56d44ea24d6 --- /dev/null +++ b/Examples/test-suite/errors/cpp_template_missing_base.i @@ -0,0 +1,35 @@ +%module xx + +struct Low : High { +}; + +struct Small; + +struct Big : Small { +}; + +%inline %{ +namespace A { + class XYZ {}; + template struct ABC : + public B::ABC { +}; +} +namespace B { + template struct ABC { + void aaa(T t) {} + }; +} +%} +%template(ABCXYZ) A::ABC; + +%template() B::ABC; +%template(ABCint) A::ABC; + +template +struct Another : WrongOrderBase { +}; +%template(AnotherBool) Another; + +template class WrongOrderBase {}; +%template(ForAnotherInt) WrongOrderBase; diff --git a/Examples/test-suite/errors/cpp_template_missing_base.stderr b/Examples/test-suite/errors/cpp_template_missing_base.stderr new file mode 100644 index 00000000000..c7698035612 --- /dev/null +++ b/Examples/test-suite/errors/cpp_template_missing_base.stderr @@ -0,0 +1,9 @@ +cpp_template_missing_base.i:3: Warning 401: Nothing known about base class 'High'. Ignored. +cpp_template_missing_base.i:8: Warning 402: Base class 'Small' is incomplete. +cpp_template_missing_base.i:6: Warning 402: Only forward declaration 'Small' was found. +cpp_template_missing_base.i:15: Warning 401: Nothing known about base class 'B::ABC< A::XYZ >'. Ignored. +cpp_template_missing_base.i:15: Warning 401: Maybe you forgot to instantiate 'B::ABC< A::XYZ >' using %template. +cpp_template_missing_base.i:15: Warning 401: Base class 'B::ABC< int >' has no name as it is an empty template instantiated with '%template()'. Ignored. +cpp_template_missing_base.i:26: Warning 401: The %template directive must be written before 'B::ABC< int >' is used as a base class and be declared with a name. +cpp_template_missing_base.i:30: Warning 401: Base class 'WrongOrderBase< int >' undefined. +cpp_template_missing_base.i:35: Warning 401: 'WrongOrderBase< int >' must be defined before it is used as a base class. diff --git a/Examples/test-suite/errors/pp_expressions_bad.i b/Examples/test-suite/errors/pp_expressions_bad.i index eea178388ce..8f1929e32f4 100644 --- a/Examples/test-suite/errors/pp_expressions_bad.i +++ b/Examples/test-suite/errors/pp_expressions_bad.i @@ -72,3 +72,8 @@ */ #if (4 <=> 2) < 0 #endif + +/* Check handling of use of an undefined function-like macro. */ +#if MY_VERSION_AT_LEAST(1,2,3) +#warning This should not warn +#endif diff --git a/Examples/test-suite/errors/pp_expressions_bad.stderr b/Examples/test-suite/errors/pp_expressions_bad.stderr index e8d187cb500..23c641621d8 100644 --- a/Examples/test-suite/errors/pp_expressions_bad.stderr +++ b/Examples/test-suite/errors/pp_expressions_bad.stderr @@ -33,3 +33,5 @@ pp_expressions_bad.i:67: Warning 202: Could not evaluate expression '"1" == +"1" pp_expressions_bad.i:67: Warning 202: Syntax error: attempt to apply unary operator to string pp_expressions_bad.i:73: Warning 202: Could not evaluate expression '(4 <=> 2) < 0' pp_expressions_bad.i:73: Warning 202: Syntax error +pp_expressions_bad.i:77: Warning 202: Could not evaluate expression 'MY_VERSION_AT_LEAST(1,2,3)' +pp_expressions_bad.i:77: Warning 202: Use of undefined function-like macro diff --git a/Examples/test-suite/errors/swig_command_encoder.stderr b/Examples/test-suite/errors/swig_command_encoder.stderr index 0fcf2dfb872..24792462358 100644 --- a/Examples/test-suite/errors/swig_command_encoder.stderr +++ b/Examples/test-suite/errors/swig_command_encoder.stderr @@ -1 +1 @@ -SWIG:1: Error: Command encoder no longer supported - use regex encoder instead. +SWIG:EOF: Error: Command encoder no longer supported - use regex encoder instead, command:sed -e 's//([a-z]/)//U/1/' -e 's//(_/)/([a-z]/)//U/2/g' << %} -%warnfilter(SWIGWARN_LANG_IDENTIFIER); +%warnfilter(SWIGWARN_LANG_IDENTIFIER) operator<<; +%warnfilter(SWIGWARN_LANG_IDENTIFIER) operator>>; #if defined(SWIGOCTAVE) %warnfilter(SWIGWARN_IGNORE_OPERATOR_LSHIFT_MSG) operator<<; @@ -139,45 +140,114 @@ }; namespace ns1 { - void bas() {} - void baz() {} } } -// Use this version with extra qualifiers to test SWIG as some compilers accept this +%inline %{ + class CModelParameterSpecies; + class CModelParameterCompartment { + CModelParameterSpecies *species; + public: + int getSpeciesVal(); + CModelParameterCompartment(); + ~CModelParameterCompartment(); + }; + class CModelParameterSpecies + { + int private_val; + public: + // Friend function-declarations are silently ignored (including constructor and destructor declarations) + friend CModelParameterCompartment::~CModelParameterCompartment(); + friend CModelParameterCompartment::CModelParameterCompartment(); + friend int CModelParameterCompartment::getSpeciesVal(); + }; +%} + +%{ +CModelParameterCompartment::CModelParameterCompartment() { + species = new CModelParameterSpecies(); + species->private_val = 1; +} +CModelParameterCompartment::~CModelParameterCompartment() { + species->private_val = 0; + delete species; +} +int CModelParameterCompartment::getSpeciesVal() { + return species->private_val; +} +%} + + +// Unqualified friend function definition and declaration example from SWIG docs +%inline %{ +class Chum { + int val; + friend int chum_blah() { Chum c; c.private_function(); return c.val; } + void private_function(); +}; + +class Mate { + int val; + friend int mate_blah(); // Unqualified friend function declaration + void private_function(); +}; +%} + +%{ +// Only seen by the compiler, not seen by SWIG +int chum_blah(); +int mate_blah() { Mate m; m.private_function(); return m.val; } + +void Chum::private_function() { this->val = 1234; } +void Mate::private_function() { this->val = 4321; } +%} + + +// Foe class tests friend definitions/declarations in a namespace +%inline %{ namespace ns1 { namespace ns2 { - class Foo { + class Foe { + int val; public: - Foo::Foo() {}; - friend void bar(); - friend void ns1::baz(); - void Foo::member() { } - + Foe() : val() {} + Foe(int val) : val(val) {} + // Unqualified friends visible to SWIG in outer scope + friend int friend_definition() { return Foe(10).val; } + friend int friend_declaration(); + friend int friend_args_definition(Foe &foe) { return foe.val; } + friend int friend_args_declaration(Foe &foe); + + // Unqualified friends only visible to C++ compiler in outer scope + friend int friend_definition_compiler() { return Foe(20).val; } + friend int friend_declaration_compiler(); + friend int friend_args_definition_compiler(Foe &foe) { return foe.val; } + friend int friend_args_declaration_compiler(Foe &foe); + + // Qualified friend (silently ignored) + friend void ns1::baz(); }; - void bar() {} + int friend_definition(); + int friend_declaration() { return Foe(11).val; } + int friend_args_definition(Foe &foe); + int friend_args_declaration(Foe &foe) { return foe.val; } } } +%} -// Remove extra qualifiers for the compiler as some compilers won't compile the extra qaulification (eg gcc-4.1 onwards) %{ namespace ns1 { namespace ns2 { - class Foo { - public: - Foo() {}; - friend void bar(); - friend void ns1::baz(); - void member() { } - - }; - void bar() {} + int friend_definition_compiler(); + int friend_declaration_compiler() { return Foe(21).val; } + // int friend_args_definition_compiler(Foe &foe); // ADL is used to find this, so no declaration is needed + int friend_args_declaration_compiler(Foe &foe) { return foe.val; } } } %} - + %template(D_i) D; %template(D_d) D; diff --git a/Examples/test-suite/friends_operator_overloading.i b/Examples/test-suite/friends_operator_overloading.i new file mode 100644 index 00000000000..bbf503360aa --- /dev/null +++ b/Examples/test-suite/friends_operator_overloading.i @@ -0,0 +1,114 @@ +%module friends_operator_overloading + +// Tests friend operators within a namespace +// Demonstrates how to turn friend operators into member functions (required for some languages - tests includes a Python runtime test) +// Note that by default the friend functions result in global function wrappers (overloaded as there are friends from two different classes) +// Testcase highlighted a compilation problem with Python builtin wrappers +// Tests only the languages that don't ignore operator<< + +%warnfilter(SWIGWARN_LANG_IDENTIFIER, // Warning 503: Can't wrap 'operator <<' unless renamed to a valid identifier. + SWIGWARN_IGNORE_OPERATOR_LSHIFT) operator<<; // Warning 373: operator<< ignored + +%inline %{ +// Remove this define to test the equivalent implementation using member methods instead of friends +#define FRIENDS + +// Debugging/tracing using printf +#include +//#define myprintf(a, b) printf(a, b) +#define myprintf(a, b) + +namespace shifting { + +class ShiftA { + int val; +public: + ShiftA(int val = 0) : val(val) {} +#if !defined(FRIENDS) + ShiftA operator<<(const ShiftA& gd) { + ShiftA ret(val - gd.getVal()); + myprintf("member operator << (GeoData) %d\n", ret.getVal()); + return ret; + } + ShiftA operator<<(int amount) { + ShiftA ret(val - amount); + myprintf("member operator << (int) %d\n", ret.getVal()); + return ret; + } +#else + friend ShiftA operator<<(const ShiftA& this_, const ShiftA& gd) { + ShiftA ret(this_.val - gd.getVal()); + myprintf("friend operator << (GeoData) %d\n", ret.getVal()); + return ret; + } + friend ShiftA operator<<(const ShiftA& this_, int amount) { + ShiftA ret(this_.val - amount); + myprintf("friend operator << (int) %d\n", ret.getVal()); + return ret; + } +#if defined(SWIG) +%extend { + ShiftA operator<<(const ShiftA& gd) { return *$self << gd; } + ShiftA operator<<(int amount) { return *$self << amount; } +} +#endif +#endif + int getVal() const { return val; } +}; + +class ShiftB { + int val; +public: + ShiftB(int val = 0) : val(val) {} +#if !defined(FRIENDS) + ShiftB operator<<(const ShiftB& gd) { + ShiftB ret(val - gd.getVal()); + myprintf("member operator << (GeoData) %d\n", ret.getVal()); + return ret; + } + ShiftB operator<<(int amount) { + ShiftB ret(val - amount); + myprintf("member operator << (int) %d\n", ret.getVal()); + return ret; + } +#else + friend ShiftB operator<<(const ShiftB& this_, const ShiftB& gd) { + ShiftB ret(this_.val - gd.getVal()); + myprintf("friend operator << (GeoData) %d\n", ret.getVal()); + return ret; + } + friend ShiftB operator<<(const ShiftB& this_, int amount) { + ShiftB ret(this_.val - amount); + myprintf("friend operator << (int) %d\n", ret.getVal()); + return ret; + } +#if defined(SWIG) +%extend { + ShiftB operator<<(const ShiftB& gd) { return *$self << gd; } + ShiftB operator<<(int amount) { return *$self << amount; } +} +#endif +#endif + int getVal() const { return val; } +}; + +void sanity_checker_ShiftA() { + ShiftA gd1(20); + ShiftA gd2(100); + ShiftA gd3(gd2 << gd1); + myprintf("gd3 %d\n", gd3.getVal()); + ShiftA gd4(gd2 << 30); + myprintf("gd4 %d\n", gd4.getVal()); + +} +void sanity_checker_ShiftB() { + ShiftB gd1(20); + ShiftB gd2(100); + ShiftB gd3(gd2 << gd1); + myprintf("gd3 %d\n", gd3.getVal()); + ShiftB gd4(gd2 << 30); + myprintf("gd4 %d\n", gd4.getVal()); +} + +} +%} diff --git a/Examples/test-suite/go/friends_runme.go b/Examples/test-suite/go/friends_runme.go index f7836ad2fb2..393d6f61e04 100644 --- a/Examples/test-suite/go/friends_runme.go +++ b/Examples/test-suite/go/friends_runme.go @@ -47,4 +47,11 @@ func main() { if friends.Get_val1(dd).(float64) != 1.3 { panic(0) } + + if friends.Chum_blah() != 1234 { + panic(0) + } + if friends.Mate_blah() != 4321 { + panic(0) + } } diff --git a/Examples/test-suite/java/Makefile.in b/Examples/test-suite/java/Makefile.in index 00ebb100b81..83335d4d489 100644 --- a/Examples/test-suite/java/Makefile.in +++ b/Examples/test-suite/java/Makefile.in @@ -55,6 +55,7 @@ CPP_TEST_CASES = \ CPP11_TEST_CASES = \ cpp11_shared_ptr_const \ + cpp11_shared_ptr_crtp_upcast \ cpp11_shared_ptr_nullptr_in_containers \ cpp11_shared_ptr_overload \ cpp11_shared_ptr_template_upcast \ diff --git a/Examples/test-suite/java/cpp11_template_templated_methods_runme.java b/Examples/test-suite/java/cpp11_template_templated_methods_runme.java new file mode 100644 index 00000000000..dd087a04015 --- /dev/null +++ b/Examples/test-suite/java/cpp11_template_templated_methods_runme.java @@ -0,0 +1,81 @@ + +import cpp11_template_templated_methods.*; + +public class cpp11_template_templated_methods_runme { + + static { + try { + System.loadLibrary("cpp11_template_templated_methods"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + // assign test + { + OctetVector ov = new OctetVector(); + octet o = new octet(111); + ov.add(o); + SimpleContainer sc = new SimpleContainer(ov); + OctetResourceLimitedVector orlv = new OctetResourceLimitedVector(); + orlv.assign(sc.begin(), sc.end()); + OctetVector collection = orlv.getCollection(); + if (collection.size() != 1) + throw new RuntimeException("wrong size"); + octet oo = collection.get(0); + if (oo.getNum() != 111) + throw new RuntimeException("wrong val"); + } + // assign_and_append test + { + OctetVector ov = new OctetVector(); + octet o = new octet(222); + ov.add(o); + SimpleContainer sc = new SimpleContainer(ov); + OctetResourceLimitedVector orlv = new OctetResourceLimitedVector(); + octet final_octet = new octet(333); + orlv.assign_and_append(sc.begin(), sc.end(), final_octet); + OctetVector collection = orlv.getCollection(); + if (collection.size() != 2) + throw new RuntimeException("wrong size"); + octet oo = collection.get(0); + if (oo.getNum() != 222) + throw new RuntimeException("wrong val"); + oo = collection.get(1); + if (oo.getNum() != 333) + throw new RuntimeException("wrong finalval"); + } + // emplace_back test + { + OctetVector ov = new OctetVector(); + octet o = new octet(222); + ov.add(o); + SimpleContainer sc = new SimpleContainer(ov); + OctetResourceLimitedVector orlv = new OctetResourceLimitedVector(); + octet final_octet = new octet(444); + orlv.emplace_back(final_octet); + orlv.emplace_back(); + orlv.emplace_back(555); + OctetVector collection = orlv.getCollection(); + if (collection.size() != 3) + throw new RuntimeException("wrong size"); + octet oo = collection.get(0); + if (oo.getNum() != 444) + throw new RuntimeException("wrong value 0"); + oo = collection.get(1); + if (oo.getNum() != 0) + throw new RuntimeException("wrong value 1"); + oo = collection.get(2); + if (oo.getNum() != 555) + throw new RuntimeException("wrong value 2"); + } + // Variadic templated constructor in template + { + OctetResourceLimitedVector orlv = new OctetResourceLimitedVector(999); + octet o = new octet(888); + OctetResourceLimitedVector orlv2 = new OctetResourceLimitedVector(o); + } + } +} diff --git a/Examples/test-suite/java/friends_runme.java b/Examples/test-suite/java/friends_runme.java index ebec103c19f..165b0520efc 100644 --- a/Examples/test-suite/java/friends_runme.java +++ b/Examples/test-suite/java/friends_runme.java @@ -11,6 +11,11 @@ public class friends_runme { } } + private static void check_equal(int a, int b) { + if (a != b) + throw new RuntimeException("Not equal " + a + " != " + b); + } + public static void main(String argv[]) throws Throwable { A a = new A(2); @@ -48,6 +53,22 @@ public static void main(String argv[]) throws Throwable throw new RuntimeException("failed"); if (friends.get_val1(dd) != 1.3) throw new RuntimeException("failed"); + + if (friends.chum_blah() != 1234) + throw new RuntimeException("failed"); + if (friends.mate_blah() != 4321) + throw new RuntimeException("failed"); + + Foe foe = new Foe(111); + check_equal(friends.friend_definition(), 10); + check_equal(friends.friend_declaration(), 11); + check_equal(friends.friend_args_definition(foe), 111); + check_equal(friends.friend_args_declaration(foe), 111); + + check_equal(friends.friend_definition_compiler(), 20); + check_equal(friends.friend_declaration_compiler(), 21); + check_equal(friends.friend_args_definition_compiler(foe), 111); + check_equal(friends.friend_args_declaration_compiler(foe), 111); } } diff --git a/Examples/test-suite/javascript/friends_runme.js b/Examples/test-suite/javascript/friends_runme.js index 29f184a9f88..6913eb93530 100644 --- a/Examples/test-suite/javascript/friends_runme.js +++ b/Examples/test-suite/javascript/friends_runme.js @@ -44,3 +44,10 @@ if (friends.get_val1(di) != 4) { if (friends.get_val1(dd) != 1.3) { throw new Error; } + +if (friends.chum_blah() != 1234) { + throw new Error("failed"); +} +if (friends.mate_blah() != 4321) { + throw new Error("failed"); +} diff --git a/Examples/test-suite/li_std_vector.i b/Examples/test-suite/li_std_vector.i index 64d057d752e..a76604b3d0a 100644 --- a/Examples/test-suite/li_std_vector.i +++ b/Examples/test-suite/li_std_vector.i @@ -150,3 +150,17 @@ int sum(int v) { return v; } %} + +// Variables +%inline %{ +struct VariableHolder { + static std::vector static_variable; + std::vector instance_variable; +}; +std::vector VariableHolder::static_variable; +std::vector global_variable; + +void vector_append(std::vector& vec, int val) { + vec.push_back(val); +} +%} diff --git a/Examples/test-suite/lua/friends_runme.lua b/Examples/test-suite/lua/friends_runme.lua index bdf97934dcf..c41d0aec6e2 100644 --- a/Examples/test-suite/lua/friends_runme.lua +++ b/Examples/test-suite/lua/friends_runme.lua @@ -25,3 +25,6 @@ d1 = f.D_i(7) assert(f.get_val1(d1) == 7) f.set(d1,9) assert(f.get_val1(d1) == 9) + +assert(friends.chum_blah() == 1234) +assert(friends.mate_blah() == 4321) diff --git a/Examples/test-suite/ocaml/Makefile.in b/Examples/test-suite/ocaml/Makefile.in index ffd62049d6b..1863a4d74f8 100644 --- a/Examples/test-suite/ocaml/Makefile.in +++ b/Examples/test-suite/ocaml/Makefile.in @@ -19,8 +19,8 @@ top_builddir = @top_builddir@ FAILING_CPP_TESTS = \ allprotected \ -apply_signed_char \ apply_strings \ +cpp11_decltype \ cpp11_director_enums \ cpp11_strongly_typed_enumerations \ cpp_enum \ @@ -29,19 +29,13 @@ director_binary_string \ director_comparison_operators \ director_enum \ director_primitives \ -director_redefined \ director_string \ director_using_member_scopes \ enum_thorough \ -li_windows \ -member_pointer_const \ -preproc_constants \ -rename_camel \ smart_pointer_inherit \ FAILING_C_TESTS = \ enums \ -preproc_constants_c \ CPP_TEST_CASES += \ inout \ diff --git a/Examples/test-suite/octave/Makefile.in b/Examples/test-suite/octave/Makefile.in index 3de1f72fcbf..78d4dec924f 100644 --- a/Examples/test-suite/octave/Makefile.in +++ b/Examples/test-suite/octave/Makefile.in @@ -26,6 +26,7 @@ CPP_TEST_CASES += \ CPP11_TEST_CASES += \ cpp11_shared_ptr_const \ + cpp11_shared_ptr_crtp_upcast \ cpp11_shared_ptr_nullptr_in_containers \ cpp11_shared_ptr_overload \ cpp11_shared_ptr_upcast \ diff --git a/Examples/test-suite/octave/friends_runme.m b/Examples/test-suite/octave/friends_runme.m index 163f05b8d5d..1b6071004d2 100644 --- a/Examples/test-suite/octave/friends_runme.m +++ b/Examples/test-suite/octave/friends_runme.m @@ -49,3 +49,10 @@ if (friends.get_val1(dd) != 1.3) error("failed"); endif + +if (friends.chum_blah() != 1234) + error("failed"); +endif +if (friends.mate_blah() != 4321) + error("failed"); +endif diff --git a/Examples/test-suite/operator_overload.i b/Examples/test-suite/operator_overload.i index 43967bcc9d3..cfbced8e64b 100644 --- a/Examples/test-suite/operator_overload.i +++ b/Examples/test-suite/operator_overload.i @@ -177,22 +177,22 @@ inline bool operator>=(const Op& a,const Op& b){return a.i>=b.i;} // in order to wrap this correctly we need to extend the class // to make the friends & non members part of the class -%extend Op{ - Op operator &&(const Op& b){return Op($self->i&&b.i);} - Op operator or(const Op& b){return Op($self->i||b.i);} - - Op operator+(const Op& b){return Op($self->i+b.i);} - Op operator-(const Op& b){return Op($self->i-b.i);} - Op operator*(const Op& b){return Op($self->i*b.i);} - Op operator/(const Op& b){return Op($self->i/b.i);} - Op operator%(const Op& b){return Op($self->i%b.i);} - - bool operator==(const Op& b){return $self->i==b.i;} - bool operator!=(const Op& b){return $self->i!=b.i;} - bool operator< (const Op& b){return $self->ii<=b.i;} - bool operator> (const Op& b){return $self->i>b.i;} - bool operator>=(const Op& b){return $self->i>=b.i;} +%extend Op { + Op operator &&(const Op& b){return *$self && b;} + Op operator or(const Op& b){return *self || b;} + + Op operator+(const Op& b){return *$self + b;} + Op operator-(const Op& b){return *$self - b;} + Op operator*(const Op& b){return *$self * b;} + Op operator/(const Op& b){return *$self / b;} + Op operator%(const Op& b){return *$self % b;} + + bool operator==(const Op& b){return *$self == b;} + bool operator!=(const Op& b){return *$self != b;} + bool operator< (const Op& b){return *$self < b;} + bool operator<=(const Op& b){return *$self <= b;} + bool operator> (const Op& b){return *$self > b;} + bool operator>=(const Op& b){return *$self >= b;} // subtraction with reversed arguments Op __rsub__(const int b){return Op(b - $self->i);} diff --git a/Examples/test-suite/php/cpp11_decltype_runme.php b/Examples/test-suite/php/cpp11_decltype_runme.php index a7b959600e5..6c19f065115 100644 --- a/Examples/test-suite/php/cpp11_decltype_runme.php +++ b/Examples/test-suite/php/cpp11_decltype_runme.php @@ -44,6 +44,12 @@ check::equal(gettype($b->should_be_int2), "integer"); check::equal(gettype($b->should_be_int3), "integer"); check::equal(gettype($b->should_be_int4), "integer"); +check::equal(gettype($b->should_be_int5), "integer"); +check::equal(gettype($b->should_be_int6), "integer"); +check::equal(gettype($b->should_be_int7), "integer"); +check::equal(gettype($b->should_be_int8), "integer"); +check::equal(gettype($b->should_be_int9), "integer"); +check::equal(gettype($b->should_be_int10), "integer"); check::equal(gettype($b->should_be_bool), "boolean"); diff --git a/Examples/test-suite/php/cpp_enum_runme.php b/Examples/test-suite/php/cpp_enum_runme.php new file mode 100644 index 00000000000..5028f689443 --- /dev/null +++ b/Examples/test-suite/php/cpp_enum_runme.php @@ -0,0 +1,43 @@ +hola, Foo::Hello); + +$f->hola = Foo::Hi; +check::equal($f->hola, Foo::Hi); + +$f->hola = Foo::Hello; +check::equal($f->hola, Foo::Hello); + +$hi = Hello; +check::equal($hi, Hello); + +check::equal(CASE0A, 10); +check::equal(CASE0B, 10); +check::equal(CASE0C, 10); +check::equal(CASE1A, 10); +check::equal(CASE1B, 10); +check::equal(CASE1C, 10); +check::equal(CASE2A, 10); +check::equal(CASE2B, 10); +check::equal(CASE2C, 10); +check::equal(CASE3A, 10); +check::equal(CASE3B, 10); +check::equal(CASE3C, 10); +check::equal(CASE4A, 10); +check::equal(CASE4B, 10); +check::equal(CASE4C, 10); +check::equal(CASE4D, 10); + +check::done(); diff --git a/Examples/test-suite/php/friends_runme.php b/Examples/test-suite/php/friends_runme.php index f0ef5df5854..4107817f71c 100644 --- a/Examples/test-suite/php/friends_runme.php +++ b/Examples/test-suite/php/friends_runme.php @@ -2,8 +2,8 @@ require "tests.php"; -check::functions(array('globalscope','mix','get_val2','get_val3','bas','baz','bar','get_val1','set')); -check::classes(array('friends','Foo','A','B','D_i','D_d')); +check::functions(array('globalscope','mix','get_val2','get_val3','bas','baz','get_val1','set','chum_blah','mate_blah','friend_definition','friend_declaration','friend_args_definition','friend_args_declaration','friend_definition_compiler','friend_declaration_compiler','friend_args_definition_compiler','friend_args_declaration_compiler')); +check::classes(array('friends','Foe','A','B','D_i','D_d','CModelParameterCompartment','CModelParameterSpecies','Chum','Mate')); // No new vars check::globals(array()); @@ -34,4 +34,18 @@ check::equal(get_val1($di), 4); check::equal(get_val1($dd), 1.3); +check::equal(chum_blah(), 1234); +check::equal(mate_blah(), 4321); + +$foe = new Foe(111); +check::equal(friend_definition(), 10); +check::equal(friend_declaration(), 11); +check::equal(friend_args_definition($foe), 111); +check::equal(friend_args_declaration($foe), 111); + +check::equal(friend_definition_compiler(), 20); +check::equal(friend_declaration_compiler(), 21); +check::equal(friend_args_definition_compiler($foe), 111); +check::equal(friend_args_declaration_compiler($foe), 111); + check::done(); diff --git a/Examples/test-suite/php/overload_simple_runme.php b/Examples/test-suite/php/overload_simple_runme.php index a2d145cc1c0..60cd7798d3e 100644 --- a/Examples/test-suite/php/overload_simple_runme.php +++ b/Examples/test-suite/php/overload_simple_runme.php @@ -1,7 +1,7 @@ idx = idx; + return 123; + } + void __setitem__(int idx, PyObject* value) { + this->idx = idx; + this->value = value ? (int)PyInt_AsLong(value) : -11; + } + void __call__(PyObject* args, PyObject* kw) { + this->args_count = args ? (int)PyTuple_Size(args) : -11; + this->kw_count = kw ? (int)PyDict_Size(kw) : -11; + } + void reset() { + idx = -100; + value = -100; + args_count = -100; + kw_count = -100; + } +}; +%} diff --git a/Examples/test-suite/rename_scope.i b/Examples/test-suite/rename_scope.i index 9a09949c431..0692927c0e5 100644 --- a/Examples/test-suite/rename_scope.i +++ b/Examples/test-suite/rename_scope.i @@ -48,9 +48,16 @@ namespace oss } } -%rename("equals") operator==; +// Note not: Utilities::Bucket::operator== +%rename("equals") Utilities::operator==; + +%ignore Utilities::operator<<; +namespace Utilities { + %ignore operator>>; +} %inline %{ +#include namespace Utilities { class Bucket @@ -60,6 +67,8 @@ namespace oss friend bool operator==(const Bucket& lhs, const Bucket& rhs){ return ( rhs.m_left == lhs.m_left ); } + friend std::ostream& operator<<(std::ostream&, const Bucket &); + friend std::ostream& operator>>(std::ostream&, const Bucket &); private: int m_left; }; diff --git a/Examples/test-suite/ruby/Makefile.in b/Examples/test-suite/ruby/Makefile.in index c831f1940dc..20ed68c6573 100644 --- a/Examples/test-suite/ruby/Makefile.in +++ b/Examples/test-suite/ruby/Makefile.in @@ -20,6 +20,7 @@ FAILING_CPP_TESTS = \ CPP_TEST_CASES = \ li_cstring \ li_factory \ + li_std_containers_int \ li_std_functors \ li_std_list \ li_std_multimap \ @@ -44,6 +45,7 @@ CPP_TEST_CASES = \ CPP11_TEST_CASES = \ cpp11_hash_tables \ cpp11_shared_ptr_const \ + cpp11_shared_ptr_crtp_upcast \ cpp11_shared_ptr_nullptr_in_containers \ cpp11_shared_ptr_overload \ cpp11_shared_ptr_upcast \ diff --git a/Examples/test-suite/ruby/friends_runme.rb b/Examples/test-suite/ruby/friends_runme.rb index c5c1caa01f9..232bb68ee1b 100644 --- a/Examples/test-suite/ruby/friends_runme.rb +++ b/Examples/test-suite/ruby/friends_runme.rb @@ -17,3 +17,6 @@ raise RuntimeError if Friends::get_val1(a) != 2 raise RuntimeError if Friends::get_val2(a) != 4 raise RuntimeError if Friends::get_val3(a) != 6 + +raise RuntimeError if Friends.chum_blah() != 1234 +raise RuntimeError if Friends.mate_blah() != 4321 diff --git a/Examples/test-suite/ruby/li_std_containers_int_runme.rb b/Examples/test-suite/ruby/li_std_containers_int_runme.rb new file mode 100644 index 00000000000..73594173c44 --- /dev/null +++ b/Examples/test-suite/ruby/li_std_containers_int_runme.rb @@ -0,0 +1,203 @@ +#!/usr/bin/env ruby + +# Check std::vector and std::list behaves the same as Ruby iterable +# types (list) + +require 'swig_assert' +require 'li_std_containers_int' + +def failed(a, b, msg) + # to_a() convert to array + # convert to array, so we can call join(). + # join() join array element to string with a seperator. + raise RuntimeError, msg+" ["+a.to_a().join(", ")+"] ["+b.to_a().join(", ")+"]" +end + +def compare_sequences(a, b) + # A start, out of range, may produce nil value + # As long as vector behave as list, we do not care :-) + if a == nil and b == nil then + return + end + if a.size != b.size then + failed(a, b, "different sizes") + end + a.each_index do |i| + if a[i] != b[i] then + failed(a, b, "elements are different") + end + end +end + +def compare_containers(pythonlist, swigvector, swiglist) + compare_sequences(pythonlist, swigvector) + compare_sequences(pythonlist, swiglist) +end + +# Check std::vector and std::list assignment behaves same as Ruby list +# assignment including exceptions +def container_insert_step(i, l, newval) + ps = (1..6).to_a + iv = Li_std_containers_int::Vector_int.new(ps) + il = Li_std_containers_int::List_int.new(ps) + + # Ruby slice + begin + if l == nil then + ps[i] = newval + else + ps[i,l] = newval + end + ps_error = nil + rescue => e + ps_error = e + end + + begin + if l == nil then + iv[i] = newval + else + iv[i,l] = newval + end + iv_error = nil + rescue => e + iv_error = e + end + + begin + if l == nil then + il[i] = newval + else + il[i,l] = newval + end + il_error = nil + rescue => e + il_error = e + end + + if iv_error != nil and il_error == nil then + raise RuntimeError, "ValueError std::vector<> fails while std::list<> pass: " + iv_error.to_s + end + if iv_error == nil and il_error != nil then + raise RuntimeError, "ValueError std::vector<> pass while std::list<> fail: " + il_error.to_s + end + if ps_error != nil and iv_error == nil then + raise RuntimeError, "ValueError C++ wrapper should fail like ruby: " + ps_error.to_s + end + if ps_error != nil and iv_error != nil and il_error != nil then + compare_containers(ps, iv, il) + end +end + +# Check std::vector and std::list delete behaves same as Ruby list +# delete including exceptions +def container_delete(i, j) + ps = (1..6).to_a + iv = Li_std_containers_int::Vector_int.new(ps) + il = Li_std_containers_int::List_int.new(ps) + + # Ruby slice + begin + if j == nil then + ps[i] = nil + else + ps[i,(j - i)] = nil + end + ps_error = nil + rescue => e + ps_error = e + end + + # std::vector + begin + if j == nil then + iv[i] = nil + else + iv[i,(j - i)] = nil + end + iv_error = nil + rescue => e + iv_error = e + end + + # std::list + begin + if j == nil then + il[i] = nil + else + il[i,(j - i)] = nil + end + il_error = nil + rescue => e + il_error = e + end + + if iv_error != nil and il_error == nil then + raise RuntimeError, "ValueError std::vector<> fails while std::list<> pass: " + iv_error.to_s + end + if iv_error == nil and il_error != nil then + raise RuntimeError, "ValueError std::vector<> pass while std::list<> fail: " + il_error.to_s + end + if ps_error != nil and iv_error == nil then + raise RuntimeError, "ValueError C++ wrapper should fail like ruby: " + ps_error.to_s + end + if ps_error != nil and iv_error != nil and il_error != nil then + compare_containers(ps, iv, il) + end +end + +ps = [0, 1, 2, 3, 4, 5] +iv = Li_std_containers_int::Vector_int.new(ps) +il = Li_std_containers_int::List_int.new(ps) + +# Ruby use array[start, length] +# slices +compare_containers(ps[0,0], iv[0,0], il[0,0]) +compare_containers(ps[1,0], iv[1,0], il[1,0]) +compare_containers(ps[1,2], iv[1,2], il[1,2]) +compare_containers(ps[2,2], iv[2,2], il[2,2]) +compare_containers(ps[0,3], iv[0,3], il[0,3]) +compare_containers(ps[3,3], iv[3,3], il[3,3]) +compare_containers(ps[3,7], iv[3,7], il[3,7]) # beyond end of range + +# before beginning of range (negative indexing) +compare_containers(ps[-1,6], iv[-1,6], il[-1,6]) +compare_containers(ps[-2,6], iv[-2,6], il[-2,6]) +compare_containers(ps[-5,6], iv[-5,6], il[-5,6]) +compare_containers(ps[-6,6], iv[-6,6], il[-6,6]) + +# before beginning of range (negative indexing, negative index is > +# container size) +compare_containers(ps[-7,7], iv[-7,7], il[-7,7]) +compare_containers(ps[-100,7], iv[-100,7], il[-100,7]) + +compare_containers(ps[3,9], iv[3,9], il[3,9]) +compare_containers(ps[0,3], iv[0,3], il[0,3]) +compare_containers(ps, iv, il) +compare_containers(ps[-3,9], iv[-3,9], il[-3,9]) +compare_containers(ps[-6,9], iv[-6,9], il[-6,9]) + +# insert sequences (growing, shrinking and staying same size) +(-6..6).step do |start| + # single element set/replace + container_insert_step(start, nil, 111) + (0..6).step do |len| + container_insert_step(start, len, [111, 222, 333, 444, 555, 666, 777]) + container_insert_step(start, len, [111, 222, 333, 444, 555, 666]) + container_insert_step(start, len, [111, 222, 333, 444, 555]) + container_insert_step(start, len, [111, 222, 333, 444]) + container_insert_step(start, len, [111, 222, 333]) + container_insert_step(start, len, [111, 222]) + container_insert_step(start, len, [111]) + container_insert_step(start, len, []) + end +end + +# delete sequences (growing, shrinking and staying same size) +for start in [-102, -100, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 100, 102] + # single element delete + container_delete(start, nil) + for vend in [-102, -100, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 100, 102] + container_delete(start, vend) + end +end diff --git a/Examples/test-suite/ruby/li_std_map_runme.rb b/Examples/test-suite/ruby/li_std_map_runme.rb index 0ec8cac84b1..9661e4cd469 100644 --- a/Examples/test-suite/ruby/li_std_map_runme.rb +++ b/Examples/test-suite/ruby/li_std_map_runme.rb @@ -43,6 +43,16 @@ m.each_key { |k| swig_assert_equal("pm[#{k.inspect}]", "m[#{k.inspect}]", binding) } EOF + +Li_std_map::populate(Li_std_map.MyMap) +Li_std_map.MyMap["eeeeee"] = 6 +swig_assert( "Li_std_map.MyMap['a'] == 1", binding ) +swig_assert( "Li_std_map.MyMap['aa'] == 2", binding ) +swig_assert( "Li_std_map.MyMap['zzz'] == 3", binding ) +swig_assert( "Li_std_map.MyMap['xxxx'] == 4", binding ) +swig_assert( "Li_std_map.MyMap['aaaaa'] == 5", binding ) +swig_assert( "Li_std_map.MyMap['eeeeee'] == 6", binding ) + mii = Li_std_map::IntIntMap.new mii[1] = 1 diff --git a/Examples/test-suite/ruby/li_std_vector_runme.rb b/Examples/test-suite/ruby/li_std_vector_runme.rb index 68feb8f1af2..dfcf285c3d3 100644 --- a/Examples/test-suite/ruby/li_std_vector_runme.rb +++ b/Examples/test-suite/ruby/li_std_vector_runme.rb @@ -260,3 +260,20 @@ def set_slice(i, length, expect_nil_expanded_elements) lv = LanguageVector.new('crapola') rescue end + +# Variables +vh = VariableHolder.new +vector_append(vh.instance_variable, 10) +swig_assert_equal("vh.instance_variable[0]", "10", binding) +vh.instance_variable.clear +swig_assert_equal("vh.instance_variable.empty?", "true", binding) + +vector_append(VariableHolder.static_variable, 20) +swig_assert_equal("VariableHolder.static_variable[0]", "20", binding) +VariableHolder.static_variable.clear +swig_assert_equal("VariableHolder.static_variable.empty?", "true", binding) + +vector_append(Li_std_vector::global_variable, 30) +swig_assert_equal("Li_std_vector::global_variable[0]", "30", binding) +Li_std_vector::global_variable.clear +swig_assert_equal("Li_std_vector::global_variable.empty?", "true", binding) diff --git a/Examples/test-suite/tcl/cpp17_string_view_runme.tcl b/Examples/test-suite/tcl/cpp17_string_view_runme.tcl index 1b6fec85e3b..9be2a439652 100644 --- a/Examples/test-suite/tcl/cpp17_string_view_runme.tcl +++ b/Examples/test-suite/tcl/cpp17_string_view_runme.tcl @@ -1,5 +1,5 @@ -if [ catch { load ./cpp17_string_view[info sharedlibextension] cpp17_string_view} err_msg ] { +if [ catch { load ./cpp17_string_view[info sharedlibextension] Cpp17_string_view} err_msg ] { puts stderr "Could not load shared object:\n$err_msg" } diff --git a/Examples/test-suite/tcl/li_carrays_runme.tcl b/Examples/test-suite/tcl/li_carrays_runme.tcl new file mode 100644 index 00000000000..5d68fdbe034 --- /dev/null +++ b/Examples/test-suite/tcl/li_carrays_runme.tcl @@ -0,0 +1,71 @@ + +if [ catch { load ./li_carrays[info sharedlibextension] Li_carrays} err_msg ] { + puts stderr "Could not load shared object:\n$err_msg" +} + + +# Testing for %array_functions(int,intArray) +set ary [new_intArray 2] +intArray_setitem $ary 0 0 +intArray_setitem $ary 1 1 +if {[intArray_getitem $ary 0] != 0} { + error "wrong value index 0" +} +if {[intArray_getitem $ary 1] != 1} { + error "wrong value index 1" +} +delete_intArray $ary + +# Testing for %array_class(double, doubleArray) +doubleArray d 10 +doubleArray_setitem d 0 7 +doubleArray_setitem d 5 [expr [doubleArray_getitem d 0] + 3] +if {[expr [doubleArray_getitem d 5] + [doubleArray_getitem d 0]] != 17} { + error "wrong value doubleArray" +} + + +# Tcl Array wrapper based on Tcl.html documentation "Building new kinds of Tcl interfaces (in Tcl)" +proc Array {type size} { + set ptr [new_$type $size] + set code { + set method [lindex $args 0] + set parms [concat $ptr [lrange $args 1 end]] + switch $method { + get {return [eval "${type}_getitem $parms"]} + set {return [eval "${type}_setitem $parms"]} + delete {eval "delete_$type $ptr; rename $ptr {}"} + } + } + # Create a procedure + uplevel "proc $ptr args {set ptr $ptr; set type $type;$code}" + return $ptr +} + +# The memory handling for Tcl is not working properly. +# %newobject (not used here though) is crippled and does not take ownership of the underlying +# pointer - see SWIGTYPE * typemap overrides in tcltypemaps.swg. +# +# As soon as a is set below, it gets deleted by the interpreter, even though $a is used a +# few lines later. The interpreter seems to replace the command object created in +# SWIG_Tcl_NewInstanceObj some sort of generic one. +# The underlying C array is not actually deleted (it leaks) when $a is deleted, so the code +# using $a does actually seem to work. + +set a [Array doubleArray 100] ;# Create a double [100] +for {set i 0} {$i < 100} {incr i 1} { ;# Clear the array + $a set $i 0.0 +} + +$a set 3 3.1455 ;# Set an individual element +set b [$a get 10] ;# Retrieve an element + +set ia [Array intArray 50] ;# Create an int[50] +for {set i 0} {$i < 50} {incr i 1} { ;# Clear it + $ia set $i 0 +} +$ia set 3 7 ;# Set an individual element +set ib [$ia get 10] ;# Get an individual element + +$a delete ;# Destroy a +$ia delete ;# Destroy ia diff --git a/Examples/test-suite/tcl/li_constraints_runme.tcl b/Examples/test-suite/tcl/li_constraints_runme.tcl index 5ef802a06ed..ca7a182e39a 100644 --- a/Examples/test-suite/tcl/li_constraints_runme.tcl +++ b/Examples/test-suite/tcl/li_constraints_runme.tcl @@ -1,4 +1,4 @@ -if [ catch { load ./li_constraints[info sharedlibextension] li_constraints} err_msg ] { +if [ catch { load ./li_constraints[info sharedlibextension] Li_constraints} err_msg ] { puts stderr "Could not load shared object:\n$err_msg" } diff --git a/Examples/test-suite/template_duplicate.i b/Examples/test-suite/template_duplicate.i new file mode 100644 index 00000000000..a9860f01f16 --- /dev/null +++ b/Examples/test-suite/template_duplicate.i @@ -0,0 +1,21 @@ +%module template_duplicate + +%include + +%warnfilter(SWIGWARN_TYPE_REDEFINED) std::vector; +%warnfilter(SWIGWARN_TYPE_REDEFINED) std::vector; + +%inline %{ +typedef unsigned char uint8_T; +typedef unsigned char boolean_T; +%} + +%template(std_vector_boolean_type) std::vector; +%template(std_vector_boolean_type_duplicate) std::vector; +%template(std_vector_uint8_type) std::vector; + +namespace std { +%template(std_vector_boolean_type_again) vector; +%template(std_vector_uint8_type_again) vector; +%template(std_vector_unsigned_char) vector; +} diff --git a/Lib/lua/luarun.swg b/Lib/lua/luarun.swg index 8dac491dd57..af6cd66f38d 100644 --- a/Lib/lua/luarun.swg +++ b/Lib/lua/luarun.swg @@ -833,6 +833,7 @@ SWIGINTERN int SWIG_Lua_class_do_get_item(lua_State *L, swig_type_info *type, i int bases_search_result; int substack_start = lua_gettop(L)-2; assert(first_arg == substack_start+1); + (void)first_arg; lua_checkstack(L,5); assert(lua_isuserdata(L,-2)); /* just in case */ lua_getmetatable(L,-2); /* get the meta table */ @@ -871,6 +872,7 @@ SWIGINTERN int SWIG_Lua_class_do_get(lua_State *L, swig_type_info *type, int SW int bases_search_result; int substack_start = lua_gettop(L)-2; assert(first_arg == substack_start+1); + (void)first_arg; lua_checkstack(L,5); assert(lua_isuserdata(L,-2)); /* just in case */ lua_getmetatable(L,-2); /* get the meta table */ diff --git a/Lib/ocaml/carray.i b/Lib/ocaml/carray.i index 4378f7333e1..71631aab85e 100644 --- a/Lib/ocaml/carray.i +++ b/Lib/ocaml/carray.i @@ -77,7 +77,7 @@ type _value = c_obj %typemap(out) SWIGTYPE [] { int i; - const CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr"); + const value *fromval = caml_named_value("create_$ntype_from_ptr"); $result = caml_array_new($1_dim0); for( i = 0; i < $1_dim0; i++ ) { diff --git a/Lib/ocaml/director.swg b/Lib/ocaml/director.swg index eb91aaf4b3f..4cdb0c6239a 100644 --- a/Lib/ocaml/director.swg +++ b/Lib/ocaml/director.swg @@ -67,13 +67,13 @@ namespace Swig { class Director { private: /* pointer to the wrapped ocaml object */ - CAML_VALUE swig_self; + value swig_self; /* flag indicating whether the object is owned by ocaml or c++ */ mutable bool swig_disown_flag; public: /* wrap a ocaml object. */ - Director(CAML_VALUE self) : swig_self(self), swig_disown_flag(false) { + Director(value self) : swig_self(self), swig_disown_flag(false) { caml_register_global_root(&swig_self); } @@ -85,7 +85,7 @@ namespace Swig { } /* return a pointer to the wrapped ocaml object */ - CAML_VALUE swig_get_self() const { + value swig_get_self() const { return swig_self; } diff --git a/Lib/ocaml/ocaml.swg b/Lib/ocaml/ocaml.swg index 703b7e44889..b3ccab59478 100644 --- a/Lib/ocaml/ocaml.swg +++ b/Lib/ocaml/ocaml.swg @@ -63,7 +63,7 @@ #if 0 %typemap(argout) SWIGTYPE & { - const CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr"); + const value *fromval = caml_named_value("create_$ntype_from_ptr"); if( fromval ) { swig_result = caml_list_append(swig_result, @@ -76,7 +76,7 @@ } } %typemap(argout) SWIGTYPE && { - const CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr"); + const value *fromval = caml_named_value("create_$ntype_from_ptr"); if( fromval ) { swig_result = caml_list_append(swig_result, @@ -193,8 +193,8 @@ SIMPLE_MAP(unsigned long long,caml_val_ulong,caml_long_val); /* Pass through value */ -%typemap (in) CAML_VALUE "$1=$input;" -%typemap (out) CAML_VALUE "$result=$1;" +%typemap (in) value "$1=$input;" +%typemap (out) value "$result=$1;" #if 0 %include diff --git a/Lib/ocaml/ocamlrun.swg b/Lib/ocaml/ocamlrun.swg index 53ad952fba6..95350eacd88 100644 --- a/Lib/ocaml/ocamlrun.swg +++ b/Lib/ocaml/ocamlrun.swg @@ -91,20 +91,20 @@ extern "C" { } } - SWIGINTERN void caml_print_list( CAML_VALUE v ); + SWIGINTERN void caml_print_list( value v ); - SWIGINTERN void caml_print_val( CAML_VALUE v ) { - switch( SWIG_Tag_val(v) ) { + SWIGINTERN void caml_print_val( value v ) { + switch( Tag_val(v) ) { case C_bool: - if( Bool_val(SWIG_Field(v,0)) ) fprintf( stderr, "true " ); + if( Bool_val(Field(v,0)) ) fprintf( stderr, "true " ); else fprintf( stderr, "false " ); break; case C_char: case C_uchar: fprintf( stderr, "'%c' (\\%03d) ", - (Int_val(SWIG_Field(v,0)) >= ' ' && - Int_val(SWIG_Field(v,0)) < 127) ? Int_val(SWIG_Field(v,0)) : '.', - Int_val(SWIG_Field(v,0)) ); + (Int_val(Field(v,0)) >= ' ' && + Int_val(Field(v,0)) < 127) ? Int_val(Field(v,0)) : '.', + Int_val(Field(v,0)) ); break; case C_short: case C_ushort: @@ -127,7 +127,7 @@ extern "C" { case C_ptr: { void *vout = 0; - swig_type_info *ty = (swig_type_info *)(long)SWIG_Int64_val(SWIG_Field(v,1)); + swig_type_info *ty = (swig_type_info *)(long)Int64_val(Field(v,1)); caml_ptr_val_internal(v,&vout,0); fprintf( stderr, "PTR(%p,%s) ", vout, @@ -137,15 +137,15 @@ extern "C" { case C_array: { unsigned int i; - for( i = 0; i < Wosize_val( SWIG_Field(v,0) ); i++ ) - caml_print_val( SWIG_Field(SWIG_Field(v,0),i) ); + for( i = 0; i < Wosize_val( Field(v,0) ); i++ ) + caml_print_val( Field(Field(v,0),i) ); } break; case C_list: - caml_print_list( SWIG_Field(v,0) ); + caml_print_list( Field(v,0) ); break; case C_obj: - fprintf( stderr, "OBJ(%p) ", (void *)SWIG_Field(v,0) ); + fprintf( stderr, "OBJ(%p) ", (void *)Field(v,0) ); break; case C_string: { @@ -157,30 +157,30 @@ extern "C" { } } - SWIGINTERN void caml_print_list( CAML_VALUE v ) { + SWIGINTERN void caml_print_list( value v ) { CAMLparam1(v); while( v && Is_block(v) ) { fprintf( stderr, "[ " ); - caml_print_val( SWIG_Field(v,0) ); + caml_print_val( Field(v,0) ); fprintf( stderr, "]\n" ); - v = SWIG_Field(v,1); + v = Field(v,1); } CAMLreturn0; } - SWIGINTERN CAML_VALUE caml_list_nth( CAML_VALUE lst, int n ) { + SWIGINTERN value caml_list_nth( value lst, int n ) { CAMLparam1(lst); int i = 0; while( i < n && lst && Is_block(lst) ) { - i++; lst = SWIG_Field(lst,1); + i++; lst = Field(lst,1); } if( lst == Val_unit ) CAMLreturn(Val_unit); - else CAMLreturn(SWIG_Field(lst,0)); + else CAMLreturn(Field(lst,0)); } - SWIGINTERN CAML_VALUE caml_list_append( CAML_VALUE lst, CAML_VALUE elt ) { + SWIGINTERN value caml_list_append( value lst, value elt ) { CAMLparam2(lst,elt); - SWIG_CAMLlocal3(v,vt,lh); + CAMLlocal3(v,vt,lh); lh = Val_unit; v = Val_unit; @@ -190,224 +190,224 @@ extern "C" { while( lst && Is_block(lst) ) { if( v && v != Val_unit ) { vt = caml_alloc_tuple(2); - SWIG_Store_field(v,1,vt); + Store_field(v,1,vt); v = vt; } else { v = lh = caml_alloc_tuple(2); } - SWIG_Store_field(v,0,SWIG_Field(lst,0)); - lst = SWIG_Field(lst,1); + Store_field(v,0,Field(lst,0)); + lst = Field(lst,1); } if( v && Is_block(v) ) { vt = caml_alloc_tuple(2); - SWIG_Store_field(v,1,vt); + Store_field(v,1,vt); v = vt; } else { v = lh = caml_alloc_tuple(2); } - SWIG_Store_field(v,0,elt); - SWIG_Store_field(v,1,Val_unit); + Store_field(v,0,elt); + Store_field(v,1,Val_unit); CAMLreturn(lh); } - SWIGINTERN int caml_list_length( CAML_VALUE lst ) { + SWIGINTERN int caml_list_length( value lst ) { CAMLparam1(lst); int i = 0; - while( lst && Is_block(lst) ) { i++; lst = SWIG_Field(lst,1); } + while( lst && Is_block(lst) ) { i++; lst = Field(lst,1); } CAMLreturn(i); } - SWIGINTERN void caml_array_set( CAML_VALUE arr, int n, CAML_VALUE item ) { + SWIGINTERN void caml_array_set( value arr, int n, value item ) { CAMLparam2(arr,item); - SWIG_Store_field(SWIG_Field(arr,0),n,item); + Store_field(Field(arr,0),n,item); CAMLreturn0; } - SWIGINTERN value caml_array_nth( CAML_VALUE arr, int n ) { + SWIGINTERN value caml_array_nth( value arr, int n ) { CAMLparam1(arr); - if( SWIG_Tag_val(arr) == C_array ) - CAMLreturn(SWIG_Field(SWIG_Field(arr,0),n)); - else if( SWIG_Tag_val(arr) == C_list ) + if( Tag_val(arr) == C_array ) + CAMLreturn(Field(Field(arr,0),n)); + else if( Tag_val(arr) == C_list ) CAMLreturn(caml_list_nth(arr,0)); else caml_failwith("Need array or list"); } - SWIGINTERN int caml_array_len( CAML_VALUE arr ) { + SWIGINTERN int caml_array_len( value arr ) { CAMLparam1(arr); - if( SWIG_Tag_val(arr) == C_array ) - CAMLreturn(Wosize_val(SWIG_Field(arr,0))); - else if( SWIG_Tag_val(arr) == C_list ) + if( Tag_val(arr) == C_array ) + CAMLreturn(Wosize_val(Field(arr,0))); + else if( Tag_val(arr) == C_list ) CAMLreturn(caml_list_length(arr)); else caml_failwith("Need array or list"); } - SWIGINTERN CAML_VALUE caml_swig_alloc(int x,int y) { + SWIGINTERN value caml_swig_alloc(int x,int y) { return caml_alloc(x,y); } SWIGINTERN value caml_array_new( int n ) { CAMLparam0(); - SWIG_CAMLlocal1(vv); + CAMLlocal1(vv); vv = caml_swig_alloc(1,C_array); - SWIG_Store_field(vv,0,caml_alloc_tuple(n)); + Store_field(vv,0,caml_alloc_tuple(n)); CAMLreturn(vv); } - SWIGINTERN CAML_VALUE caml_val_bool( int b ) { + SWIGINTERN value caml_val_bool( int b ) { CAMLparam0(); - SWIG_CAMLlocal1(bv); + CAMLlocal1(bv); bv = caml_swig_alloc(1,C_bool); - SWIG_Store_field(bv,0,Val_bool(b)); + Store_field(bv,0,Val_bool(b)); CAMLreturn(bv); } - SWIGINTERN CAML_VALUE caml_val_char( char c ) { + SWIGINTERN value caml_val_char( char c ) { CAMLparam0(); - SWIG_CAMLlocal1(cv); + CAMLlocal1(cv); cv = caml_swig_alloc(1,C_char); - SWIG_Store_field(cv,0,Val_int(c)); + Store_field(cv,0,Val_int(c)); CAMLreturn(cv); } - SWIGINTERN CAML_VALUE caml_val_uchar( unsigned char uc ) { + SWIGINTERN value caml_val_uchar( unsigned char uc ) { CAMLparam0(); - SWIG_CAMLlocal1(ucv); + CAMLlocal1(ucv); ucv = caml_swig_alloc(1,C_uchar); - SWIG_Store_field(ucv,0,Val_int(uc)); + Store_field(ucv,0,Val_int(uc)); CAMLreturn(ucv); } - SWIGINTERN CAML_VALUE caml_val_short( short s ) { + SWIGINTERN value caml_val_short( short s ) { CAMLparam0(); - SWIG_CAMLlocal1(sv); + CAMLlocal1(sv); sv = caml_swig_alloc(1,C_short); - SWIG_Store_field(sv,0,Val_int(s)); + Store_field(sv,0,Val_int(s)); CAMLreturn(sv); } - SWIGINTERN CAML_VALUE caml_val_ushort( unsigned short us ) { + SWIGINTERN value caml_val_ushort( unsigned short us ) { CAMLparam0(); - SWIG_CAMLlocal1(usv); + CAMLlocal1(usv); usv = caml_swig_alloc(1,C_ushort); - SWIG_Store_field(usv,0,Val_int(us)); + Store_field(usv,0,Val_int(us)); CAMLreturn(usv); } - SWIGINTERN CAML_VALUE caml_val_int( int i ) { + SWIGINTERN value caml_val_int( int i ) { CAMLparam0(); - SWIG_CAMLlocal1(iv); + CAMLlocal1(iv); iv = caml_swig_alloc(1,C_int); - SWIG_Store_field(iv,0,Val_int(i)); + Store_field(iv,0,Val_int(i)); CAMLreturn(iv); } - SWIGINTERN CAML_VALUE caml_val_uint( unsigned int ui ) { + SWIGINTERN value caml_val_uint( unsigned int ui ) { CAMLparam0(); - SWIG_CAMLlocal1(uiv); + CAMLlocal1(uiv); uiv = caml_swig_alloc(1,C_int); - SWIG_Store_field(uiv,0,Val_int(ui)); + Store_field(uiv,0,Val_int(ui)); CAMLreturn(uiv); } - SWIGINTERN CAML_VALUE caml_val_long( long l ) { + SWIGINTERN value caml_val_long( long l ) { CAMLparam0(); - SWIG_CAMLlocal1(lv); + CAMLlocal1(lv); lv = caml_swig_alloc(1,C_int64); - SWIG_Store_field(lv,0,caml_copy_int64(l)); + Store_field(lv,0,caml_copy_int64(l)); CAMLreturn(lv); } - SWIGINTERN CAML_VALUE caml_val_ulong( unsigned long ul ) { + SWIGINTERN value caml_val_ulong( unsigned long ul ) { CAMLparam0(); - SWIG_CAMLlocal1(ulv); + CAMLlocal1(ulv); ulv = caml_swig_alloc(1,C_int64); - SWIG_Store_field(ulv,0,caml_copy_int64(ul)); + Store_field(ulv,0,caml_copy_int64(ul)); CAMLreturn(ulv); } - SWIGINTERN CAML_VALUE caml_val_float( float f ) { + SWIGINTERN value caml_val_float( float f ) { CAMLparam0(); - SWIG_CAMLlocal1(fv); + CAMLlocal1(fv); fv = caml_swig_alloc(1,C_float); - SWIG_Store_field(fv,0,caml_copy_double((double)f)); + Store_field(fv,0,caml_copy_double((double)f)); CAMLreturn(fv); } - SWIGINTERN CAML_VALUE caml_val_double( double d ) { + SWIGINTERN value caml_val_double( double d ) { CAMLparam0(); - SWIG_CAMLlocal1(fv); + CAMLlocal1(fv); fv = caml_swig_alloc(1,C_double); - SWIG_Store_field(fv,0,caml_copy_double(d)); + Store_field(fv,0,caml_copy_double(d)); CAMLreturn(fv); } - SWIGINTERN CAML_VALUE caml_val_ptr( void *p, swig_type_info *info ) { + SWIGINTERN value caml_val_ptr( void *p, swig_type_info *info ) { CAMLparam0(); - SWIG_CAMLlocal1(vv); + CAMLlocal1(vv); vv = caml_swig_alloc(2,C_ptr); - SWIG_Store_field(vv,0,caml_copy_int64((long)p)); - SWIG_Store_field(vv,1,caml_copy_int64((long)info)); + Store_field(vv,0,caml_copy_int64((long)p)); + Store_field(vv,1,caml_copy_int64((long)info)); CAMLreturn(vv); } - SWIGINTERN CAML_VALUE caml_val_string( const char *p ) { + SWIGINTERN value caml_val_string( const char *p ) { CAMLparam0(); - SWIG_CAMLlocal1(vv); + CAMLlocal1(vv); if( !p ) CAMLreturn(caml_val_ptr( (void *)p, 0 )); vv = caml_swig_alloc(1,C_string); - SWIG_Store_field(vv,0,caml_copy_string(p)); + Store_field(vv,0,caml_copy_string(p)); CAMLreturn(vv); } - SWIGINTERN CAML_VALUE caml_val_string_len( const char *p, int len ) { + SWIGINTERN value caml_val_string_len( const char *p, int len ) { CAMLparam0(); - SWIG_CAMLlocal1(vv); + CAMLlocal1(vv); if( !p || len < 0 ) CAMLreturn(caml_val_ptr( (void *)p, 0 )); vv = caml_swig_alloc(1,C_string); - SWIG_Store_field(vv,0,caml_alloc_string(len)); - memcpy(Bp_val(SWIG_Field(vv,0)),p,len); + Store_field(vv,0,caml_alloc_string(len)); + memcpy(Bp_val(Field(vv,0)),p,len); CAMLreturn(vv); } #define caml_val_obj(v, name) caml_val_obj_helper(v, SWIG_TypeQuery((name)), name) - SWIGINTERN CAML_VALUE caml_val_obj_helper( void *v, swig_type_info *type, char *name) { + SWIGINTERN value caml_val_obj_helper( void *v, swig_type_info *type, char *name) { CAMLparam0(); CAMLreturn(caml_callback2(*caml_named_value("caml_create_object_fn"), caml_val_ptr(v,type), caml_copy_string(name))); } - SWIGINTERN long caml_long_val_full( CAML_VALUE v, const char *name ) { + SWIGINTERN long caml_long_val_full( value v, const char *name ) { CAMLparam1(v); if( !Is_block(v) ) return 0; - switch( SWIG_Tag_val(v) ) { + switch( Tag_val(v) ) { case C_bool: case C_char: case C_uchar: case C_short: case C_ushort: case C_int: - CAMLreturn(Int_val(SWIG_Field(v,0))); + CAMLreturn(Int_val(Field(v,0))); case C_uint: case C_int32: - CAMLreturn(Int32_val(SWIG_Field(v,0))); + CAMLreturn(Int32_val(Field(v,0))); case C_int64: - CAMLreturn((long)SWIG_Int64_val(SWIG_Field(v,0))); + CAMLreturn((long)Int64_val(Field(v,0))); case C_float: case C_double: - CAMLreturn((long)Double_val(SWIG_Field(v,0))); + CAMLreturn((long)Double_val(Field(v,0))); case C_string: - CAMLreturn((long)String_val(SWIG_Field(v,0))); + CAMLreturn((long)String_val(Field(v,0))); case C_ptr: - CAMLreturn((long)SWIG_Int64_val(SWIG_Field(SWIG_Field(v,0),0))); + CAMLreturn((long)Int64_val(Field(Field(v,0),0))); case C_enum: { - SWIG_CAMLlocal1(ret); - const CAML_VALUE *enum_to_int = caml_named_value(SWIG_MODULE "_enum_to_int"); + CAMLlocal1(ret); + const value *enum_to_int = caml_named_value(SWIG_MODULE "_enum_to_int"); if( !name ) caml_failwith( "Not an enum conversion" ); ret = caml_callback2(*enum_to_int,*caml_named_value(name),v); CAMLreturn(caml_long_val(ret)); @@ -417,100 +417,100 @@ extern "C" { } } - SWIGINTERN long caml_long_val( CAML_VALUE v ) { + SWIGINTERN long caml_long_val( value v ) { return caml_long_val_full(v,0); } - SWIGINTERN double caml_double_val( CAML_VALUE v ) { + SWIGINTERN double caml_double_val( value v ) { CAMLparam1(v); if( !Is_block(v) ) return 0.0; - switch( SWIG_Tag_val(v) ) { + switch( Tag_val(v) ) { case C_bool: case C_char: case C_uchar: case C_short: case C_ushort: case C_int: - CAMLreturn_type(Int_val(SWIG_Field(v,0))); + CAMLreturnT(double, Int_val(Field(v,0))); case C_uint: case C_int32: - CAMLreturn_type(Int32_val(SWIG_Field(v,0))); + CAMLreturnT(double, Int32_val(Field(v,0))); case C_int64: - CAMLreturn_type(SWIG_Int64_val(SWIG_Field(v,0))); + CAMLreturnT(double, Int64_val(Field(v,0))); case C_float: case C_double: - CAMLreturn_type(Double_val(SWIG_Field(v,0))); + CAMLreturnT(double, Double_val(Field(v,0))); default: - fprintf( stderr, "Unknown block tag %d\n", SWIG_Tag_val(v) ); + fprintf( stderr, "Unknown block tag %d\n", Tag_val(v) ); caml_failwith("No conversion to double"); } } - SWIGINTERN int caml_ptr_val_internal( CAML_VALUE v, void **out, + SWIGINTERN int caml_ptr_val_internal( value v, void **out, swig_type_info *descriptor ) { CAMLparam1(v); void *outptr = NULL; swig_type_info *outdescr = NULL; - static const CAML_VALUE *func_val = NULL; + static const value *func_val = NULL; if( v == Val_unit ) { *out = 0; - CAMLreturn_type(0); + CAMLreturnT(int, 0); } if( !Is_block(v) ) return -1; - switch( SWIG_Tag_val(v) ) { + switch( Tag_val(v) ) { case C_obj: if (!func_val) { func_val = caml_named_value("caml_obj_ptr"); } - CAMLreturn_type(caml_ptr_val_internal(caml_callback(*func_val, v), out, descriptor)); + CAMLreturnT(int, caml_ptr_val_internal(caml_callback(*func_val, v), out, descriptor)); case C_string: - outptr = (void *)String_val(SWIG_Field(v,0)); + outptr = (void *)String_val(Field(v,0)); break; case C_ptr: - outptr = (void *)(long)SWIG_Int64_val(SWIG_Field(v,0)); - outdescr = (swig_type_info *)(long)SWIG_Int64_val(SWIG_Field(v,1)); + outptr = (void *)(long)Int64_val(Field(v,0)); + outdescr = (swig_type_info *)(long)Int64_val(Field(v,1)); break; default: *out = 0; - CAMLreturn_type(1); + CAMLreturnT(int, 1); break; } - CAMLreturn_type(SWIG_GetPtr(outptr, out, outdescr, descriptor)); + CAMLreturnT(int, SWIG_GetPtr(outptr, out, outdescr, descriptor)); } - SWIGINTERN void *caml_ptr_val( CAML_VALUE v, swig_type_info *descriptor ) { + SWIGINTERN void *caml_ptr_val( value v, swig_type_info *descriptor ) { CAMLparam0(); #ifdef TYPE_CAST_VERBOSE caml_print_val( v ); #endif void *out = NULL; if( !caml_ptr_val_internal( v, &out, descriptor ) ) - CAMLreturn_type(out); + CAMLreturnT(void*, out); else caml_failwith( "No appropriate conversion found." ); } - SWIGINTERN char *caml_string_val( CAML_VALUE v ) { + SWIGINTERN char *caml_string_val( value v ) { return (char *)caml_ptr_val( v, 0 ); } - SWIGINTERN int caml_string_len( CAML_VALUE v ) { - switch( SWIG_Tag_val(v) ) { + SWIGINTERN int caml_string_len( value v ) { + switch( Tag_val(v) ) { case C_string: - return caml_string_length(SWIG_Field(v,0)); + return caml_string_length(Field(v,0)); default: return strlen((char *)caml_ptr_val(v,0)); } } - SWIGINTERN int caml_bool_check( CAML_VALUE v ) { + SWIGINTERN int caml_bool_check( value v ) { CAMLparam1(v); if( !Is_block(v) ) return 0; - switch( SWIG_Tag_val(v) ) { + switch( Tag_val(v) ) { case C_bool: case C_ptr: case C_string: @@ -520,12 +520,12 @@ extern "C" { } } - SWIGINTERN int caml_int_check( CAML_VALUE v ) { + SWIGINTERN int caml_int_check( value v ) { CAMLparam1(v); if( !Is_block(v) ) return 0; - switch( SWIG_Tag_val(v) ) { + switch( Tag_val(v) ) { case C_char: case C_uchar: case C_short: @@ -541,11 +541,11 @@ extern "C" { } } - SWIGINTERN int caml_float_check( CAML_VALUE v ) { + SWIGINTERN int caml_float_check( value v ) { CAMLparam1(v); if( !Is_block(v) ) return 0; - switch( SWIG_Tag_val(v) ) { + switch( Tag_val(v) ) { case C_float: case C_double: CAMLreturn(1); @@ -555,11 +555,11 @@ extern "C" { } } - SWIGINTERN int caml_ptr_check( CAML_VALUE v ) { + SWIGINTERN int caml_ptr_check( value v ) { CAMLparam1(v); if( !Is_block(v) ) return 0; - switch( SWIG_Tag_val(v) ) { + switch( Tag_val(v) ) { case C_string: case C_ptr: case C_int64: @@ -570,11 +570,11 @@ extern "C" { } } - SWIGINTERN CAML_VALUE SWIG_Ocaml_ptr_to_val(const char *name, void *ptr, swig_type_info *descriptor) { + SWIGINTERN value SWIG_Ocaml_ptr_to_val(const char *name, void *ptr, swig_type_info *descriptor) { CAMLparam0(); - SWIG_CAMLlocal1(result); + CAMLlocal1(result); - const CAML_VALUE *fromval = caml_named_value(name); + const value *fromval = caml_named_value(name); if (fromval) { result = caml_callback(*fromval, caml_val_ptr(ptr, descriptor)); } else { @@ -584,17 +584,17 @@ extern "C" { } static swig_module_info *SWIG_Ocaml_GetModule(void *SWIGUNUSEDPARM(clientdata)) { - CAML_VALUE pointer; + value pointer; pointer = caml_callback(*caml_named_value("swig_find_type_info"), caml_val_int(0)); - if (Is_block(pointer) && SWIG_Tag_val(pointer) == C_ptr) { - return (swig_module_info *)(void *)(long)SWIG_Int64_val(SWIG_Field(pointer,0)); + if (Is_block(pointer) && Tag_val(pointer) == C_ptr) { + return (swig_module_info *)(void *)(long)Int64_val(Field(pointer,0)); } return 0; } static void SWIG_Ocaml_SetModule(swig_module_info *pointer) { - CAML_VALUE mod_pointer; + value mod_pointer; mod_pointer = caml_val_ptr(pointer, NULL); caml_callback(*caml_named_value("swig_set_type_info"), mod_pointer); @@ -603,5 +603,3 @@ extern "C" { #ifdef __cplusplus } #endif -#undef value - diff --git a/Lib/ocaml/ocamlrundec.swg b/Lib/ocaml/ocamlrundec.swg index dde0b8e5cfd..4d20f34b261 100644 --- a/Lib/ocaml/ocamlrundec.swg +++ b/Lib/ocaml/ocamlrundec.swg @@ -14,8 +14,6 @@ SWIGEXT { #else #define SWIGEXT #endif -#define value caml_value_t -#define CAML_VALUE caml_value_t #define CAML_NAME_SPACE #include #include @@ -34,95 +32,6 @@ SWIGEXT { #define caml_array_set swig_caml_array_set -/* Adapted from memory.h and mlvalues.h */ - -#define SWIG_CAMLlocal1(x) \ - caml_value_t x = 0; \ - CAMLxparam1 (x) - -#define SWIG_CAMLlocal2(x, y) \ - caml_value_t x = 0, y = 0; \ - CAMLxparam2 (x, y) - -#define SWIG_CAMLlocal3(x, y, z) \ - caml_value_t x = 0, y = 0, z = 0; \ - CAMLxparam3 (x, y, z) - -#define SWIG_CAMLlocal4(x, y, z, t) \ - caml_value_t x = 0, y = 0, z = 0, t = 0; \ - CAMLxparam4 (x, y, z, t) - -#define SWIG_CAMLlocal5(x, y, z, t, u) \ - caml_value_t x = 0, y = 0, z = 0, t = 0, u = 0; \ - CAMLxparam5 (x, y, z, t, u) - -#define SWIG_CAMLlocalN(x, size) \ - caml_value_t x [(size)] = { 0, /* 0, 0, ... */ }; \ - CAMLxparamN (x, (size)) - -#define SWIG_Field(x, i) (((caml_value_t *)(x)) [i]) /* Also an l-value. */ -#define SWIG_Store_field(block, offset, val) do{ \ - mlsize_t caml__temp_offset = (offset); \ - caml_value_t caml__temp_val = (val); \ - caml_modify (&SWIG_Field ((block), caml__temp_offset), caml__temp_val); \ -}while(0) - -#define SWIG_Data_custom_val(v) ((void *) &SWIG_Field((v), 1)) -#ifdef ARCH_BIG_ENDIAN -#define SWIG_Tag_val(val) (((unsigned char *) (val)) [-1]) - /* Also an l-value. */ -#define SWIG_Tag_hp(hp) (((unsigned char *) (hp)) [sizeof(caml_value_t)-1]) - /* Also an l-value. */ -#else -#define SWIG_Tag_val(val) (((unsigned char *) (val)) [-sizeof(caml_value_t)]) - /* Also an l-value. */ -#define SWIG_Tag_hp(hp) (((unsigned char *) (hp)) [0]) - /* Also an l-value. */ -#endif - -#ifdef CAMLreturn0 -#undef CAMLreturn0 -#endif -#define CAMLreturn0 do{ \ - caml_local_roots = caml__frame; \ - return; \ -}while (0) - -#ifdef CAMLreturn -#undef CAMLreturn -#endif -#define CAMLreturn(result) do{ \ - caml_value_t caml__temp_result = (result); \ - caml_local_roots = caml__frame; \ - return (caml__temp_result); \ -}while(0) - -#define CAMLreturn_type(result) do{ \ - caml_local_roots = caml__frame; \ - return result; \ -}while(0) - -#ifdef CAMLnoreturn -#undef CAMLnoreturn -#endif -#define CAMLnoreturn ((void) caml__frame) - - -#ifndef ARCH_ALIGN_INT64 -#if OCAML_VERSION >= 40300 -#define SWIG_Int64_val(v) (*((int64_t *) SWIG_Data_custom_val(v))) -#else -#define SWIG_Int64_val(v) (*((int64 *) SWIG_Data_custom_val(v))) -#endif -#else -#if OCAML_VERSION >= 40300 -CAMLextern int64_t Int64_val(caml_value_t v); -#else -CAMLextern int64 Int64_val(caml_value_t v); -#endif -#define SWIG_Int64_val(v) Int64_val(v) -#endif - #define SWIG_NewPointerObj(p,type,flags) caml_val_ptr(p,type) #define SWIG_GetModule(clientdata) SWIG_Ocaml_GetModule(clientdata) #define SWIG_SetModule(clientdata, pointer) SWIG_Ocaml_SetModule(pointer) @@ -141,7 +50,7 @@ typedef enum { SWIGINTERN void SWIG_OCamlThrowException(SWIG_OCamlExceptionCodes code, const char *msg) { CAMLparam0(); - SWIG_CAMLlocal1(str); + CAMLlocal1(str); switch (code) { case SWIG_OCamlIllegalArgumentException: @@ -169,43 +78,43 @@ SWIGINTERN void SWIG_OCamlThrowException(SWIG_OCamlExceptionCodes code, const ch SWIGINTERN int SWIG_GetPtr(void *source, void **result, swig_type_info *type, swig_type_info *result_type); - SWIGINTERN CAML_VALUE caml_list_nth( CAML_VALUE lst, int n ); - SWIGINTERN CAML_VALUE caml_list_append( CAML_VALUE lst, CAML_VALUE elt ); - SWIGINTERN int caml_list_length( CAML_VALUE lst ); - SWIGINTERN CAML_VALUE caml_array_new( int n ); - SWIGINTERN void caml_array_set( CAML_VALUE arr, int n, CAML_VALUE item ); - SWIGINTERN CAML_VALUE caml_array_nth( CAML_VALUE arr, int n ); - SWIGINTERN int caml_array_len( CAML_VALUE arr ); + SWIGINTERN value caml_list_nth( value lst, int n ); + SWIGINTERN value caml_list_append( value lst, value elt ); + SWIGINTERN int caml_list_length( value lst ); + SWIGINTERN value caml_array_new( int n ); + SWIGINTERN void caml_array_set( value arr, int n, value item ); + SWIGINTERN value caml_array_nth( value arr, int n ); + SWIGINTERN int caml_array_len( value arr ); - SWIGINTERN CAML_VALUE caml_val_char( char c ); - SWIGINTERN CAML_VALUE caml_val_uchar( unsigned char c ); + SWIGINTERN value caml_val_char( char c ); + SWIGINTERN value caml_val_uchar( unsigned char c ); - SWIGINTERN CAML_VALUE caml_val_short( short s ); - SWIGINTERN CAML_VALUE caml_val_ushort( unsigned short s ); + SWIGINTERN value caml_val_short( short s ); + SWIGINTERN value caml_val_ushort( unsigned short s ); - SWIGINTERN CAML_VALUE caml_val_int( int x ); - SWIGINTERN CAML_VALUE caml_val_uint( unsigned int x ); + SWIGINTERN value caml_val_int( int x ); + SWIGINTERN value caml_val_uint( unsigned int x ); - SWIGINTERN CAML_VALUE caml_val_long( long x ); - SWIGINTERN CAML_VALUE caml_val_ulong( unsigned long x ); + SWIGINTERN value caml_val_long( long x ); + SWIGINTERN value caml_val_ulong( unsigned long x ); - SWIGINTERN CAML_VALUE caml_val_float( float f ); - SWIGINTERN CAML_VALUE caml_val_double( double d ); + SWIGINTERN value caml_val_float( float f ); + SWIGINTERN value caml_val_double( double d ); - SWIGINTERN CAML_VALUE caml_val_ptr( void *p, swig_type_info *descriptor ); + SWIGINTERN value caml_val_ptr( void *p, swig_type_info *descriptor ); - SWIGINTERN CAML_VALUE caml_val_string( const char *str ); - SWIGINTERN CAML_VALUE caml_val_string_len( const char *str, int len ); + SWIGINTERN value caml_val_string( const char *str ); + SWIGINTERN value caml_val_string_len( const char *str, int len ); - SWIGINTERN long caml_long_val( CAML_VALUE v ); - SWIGINTERN double caml_double_val( CAML_VALUE v ); + SWIGINTERN long caml_long_val( value v ); + SWIGINTERN double caml_double_val( value v ); - SWIGINTERN int caml_ptr_val_internal( CAML_VALUE v, void **out, + SWIGINTERN int caml_ptr_val_internal( value v, void **out, swig_type_info *descriptor ); - SWIGINTERN void *caml_ptr_val( CAML_VALUE v, swig_type_info *descriptor ); + SWIGINTERN void *caml_ptr_val( value v, swig_type_info *descriptor ); - SWIGINTERN char *caml_string_val( CAML_VALUE v ); - SWIGINTERN int caml_string_len( CAML_VALUE v ); + SWIGINTERN char *caml_string_val( value v ); + SWIGINTERN int caml_string_len( value v ); #ifdef __cplusplus } diff --git a/Lib/ocaml/std_common.i b/Lib/ocaml/std_common.i index 7e64607d914..62a8d3cd212 100644 --- a/Lib/ocaml/std_common.i +++ b/Lib/ocaml/std_common.i @@ -12,12 +12,12 @@ %{ #include SWIGINTERNINLINE -CAML_VALUE SwigString_FromString(const std::string &s) { +value SwigString_FromString(const std::string &s) { return caml_val_string((char *)s.c_str()); } SWIGINTERNINLINE -std::string SwigString_AsString(CAML_VALUE o) { +std::string SwigString_AsString(value o) { return std::string((char *)caml_ptr_val(o,0)); } %} diff --git a/Lib/ocaml/typecheck.i b/Lib/ocaml/typecheck.i index 238f90d8d12..1466d1c5f01 100644 --- a/Lib/ocaml/typecheck.i +++ b/Lib/ocaml/typecheck.i @@ -7,7 +7,7 @@ %typecheck(SWIG_TYPECHECK_INT8) char, signed char, const char &, const signed char & { if( !Is_block($input) ) $1 = 0; else { - switch( SWIG_Tag_val($input) ) { + switch( Tag_val($input) ) { case C_char: $1 = 1; break; default: $1 = 0; break; } @@ -17,7 +17,7 @@ %typecheck(SWIG_TYPECHECK_UINT8) unsigned char, const unsigned char & { if( !Is_block($input) ) $1 = 0; else { - switch( SWIG_Tag_val($input) ) { + switch( Tag_val($input) ) { case C_uchar: $1 = 1; break; default: $1 = 0; break; } @@ -27,7 +27,7 @@ %typecheck(SWIG_TYPECHECK_INT16) short, signed short, const short &, const signed short &, wchar_t { if( !Is_block($input) ) $1 = 0; else { - switch( SWIG_Tag_val($input) ) { + switch( Tag_val($input) ) { case C_short: $1 = 1; break; default: $1 = 0; break; } @@ -37,7 +37,7 @@ %typecheck(SWIG_TYPECHECK_UINT16) unsigned short, const unsigned short & { if( !Is_block($input) ) $1 = 0; else { - switch( SWIG_Tag_val($input) ) { + switch( Tag_val($input) ) { case C_ushort: $1 = 1; break; default: $1 = 0; break; } @@ -50,7 +50,7 @@ %typecheck(SWIG_TYPECHECK_INT32) int, signed int, const int &, const signed int &, enum SWIGTYPE { if( !Is_block($input) ) $1 = 0; else { - switch( SWIG_Tag_val($input) ) { + switch( Tag_val($input) ) { case C_int: $1 = 1; break; default: $1 = 0; break; } @@ -60,7 +60,7 @@ %typecheck(SWIG_TYPECHECK_UINT32) unsigned int, const unsigned int & { if( !Is_block($input) ) $1 = 0; else { - switch( SWIG_Tag_val($input) ) { + switch( Tag_val($input) ) { case C_uint: $1 = 1; break; case C_int32: $1 = 1; break; default: $1 = 0; break; @@ -77,7 +77,7 @@ { if( !Is_block($input) ) $1 = 0; else { - switch( SWIG_Tag_val($input) ) { + switch( Tag_val($input) ) { case C_int64: $1 = 1; break; default: $1 = 0; break; } @@ -87,7 +87,7 @@ %typecheck(SWIG_TYPECHECK_BOOL) bool, const bool & { if( !Is_block($input) ) $1 = 0; else { - switch( SWIG_Tag_val($input) ) { + switch( Tag_val($input) ) { case C_bool: $1 = 1; break; default: $1 = 0; break; } @@ -97,7 +97,7 @@ %typecheck(SWIG_TYPECHECK_FLOAT) float, const float & { if( !Is_block($input) ) $1 = 0; else { - switch( SWIG_Tag_val($input) ) { + switch( Tag_val($input) ) { case C_float: $1 = 1; break; default: $1 = 0; break; } @@ -107,7 +107,7 @@ %typecheck(SWIG_TYPECHECK_DOUBLE) double, const double & { if( !Is_block($input) ) $1 = 0; else { - switch( SWIG_Tag_val($input) ) { + switch( Tag_val($input) ) { case C_double: $1 = 1; break; default: $1 = 0; break; } @@ -117,11 +117,11 @@ %typecheck(SWIG_TYPECHECK_STRING) char * { if( !Is_block($input) ) $1 = 0; else { - switch( SWIG_Tag_val($input) ) { + switch( Tag_val($input) ) { case C_string: $1 = 1; break; case C_ptr: { swig_type_info *typeinfo = - (swig_type_info *)(long)SWIG_Int64_val(SWIG_Field($input,1)); + (swig_type_info *)(long)Int64_val(Field($input,1)); $1 = SWIG_TypeCheck("char *",typeinfo) || SWIG_TypeCheck("signed char *",typeinfo) || SWIG_TypeCheck("unsigned char *",typeinfo) || @@ -136,7 +136,7 @@ } %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] { - if (!Is_block($input) || !(SWIG_Tag_val($input) == C_obj || SWIG_Tag_val($input) == C_ptr)) { + if (!Is_block($input) || !(Tag_val($input) == C_obj || Tag_val($input) == C_ptr)) { $1 = 0; } else { void *ptr; @@ -149,14 +149,14 @@ if (!Is_block($input)) { $1 = 0; } else { - switch (SWIG_Tag_val($input)) { + switch (Tag_val($input)) { case C_obj: { void *ptr; $1 = !caml_ptr_val_internal($input, &ptr, $&1_descriptor); break; } case C_ptr: { - typeinfo = (swig_type_info *)SWIG_Int64_val(SWIG_Field($input, 1)); + typeinfo = (swig_type_info *)Int64_val(Field($input, 1)); $1 = SWIG_TypeCheck("$1_type", typeinfo) != NULL; break; } @@ -170,7 +170,7 @@ $1 = !caml_ptr_val_internal($input, &ptr, 0); } -%typecheck(SWIG_TYPECHECK_SWIGOBJECT) CAML_VALUE "$1 = 1;" +%typecheck(SWIG_TYPECHECK_SWIGOBJECT) value "$1 = 1;" /* ------------------------------------------------------------ * Exception handling diff --git a/Lib/octave/octcontainer.swg b/Lib/octave/octcontainer.swg index 2a6f602a9f6..97a345eba2d 100644 --- a/Lib/octave/octcontainer.swg +++ b/Lib/octave/octcontainer.swg @@ -66,7 +66,11 @@ namespace std { bool operator()(const octave_value& v, const octave_value& w) const { +%#if SWIG_OCTAVE_PREREQ(7,0,0) + octave_value res = octave::binary_op(octave_value::op_le,v,w); +%#else octave_value res = do_binary_op(octave_value::op_le,v,w); +%#endif return res.is_true(); } }; @@ -136,25 +140,29 @@ namespace swig { template inline void - setslice(Sequence* self, Difference i, Difference j, const InputSeq& v) { + setslice(Sequence* self, Difference i, Difference j, const InputSeq& is) { typename Sequence::size_type size = self->size(); typename Sequence::size_type ii = swig::check_index(i, size, true); typename Sequence::size_type jj = swig::slice_index(j, size); if (jj < ii) jj = ii; size_t ssize = jj - ii; - if (ssize <= v.size()) { + if (ssize <= is.size()) { + // expanding/staying the same size typename Sequence::iterator sb = self->begin(); - typename InputSeq::const_iterator vmid = v.begin(); + typename InputSeq::const_iterator vmid = is.begin(); std::advance(sb,ii); std::advance(vmid, jj - ii); - self->insert(std::copy(v.begin(), vmid, sb), vmid, v.end()); + self->insert(std::copy(is.begin(), vmid, sb), vmid, is.end()); } else { + // shrinking typename Sequence::iterator sb = self->begin(); typename Sequence::iterator se = self->begin(); std::advance(sb,ii); std::advance(se,jj); self->erase(sb,se); - self->insert(sb, v.begin(), v.end()); + sb = self->begin(); + std::advance(sb,ii); + self->insert(sb, is.begin(), is.end()); } } diff --git a/Lib/octave/octrun.swg b/Lib/octave/octrun.swg index 27389d57731..5865c921b3e 100644 --- a/Lib/octave/octrun.swg +++ b/Lib/octave/octrun.swg @@ -402,7 +402,11 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own); } static octave_value make_value_hack(const octave_base_value &x) { +#if SWIG_OCTAVE_PREREQ(9,0,0) + ((octave_swig_type &) x).m_count++; +#else ((octave_swig_type &) x).count++; +#endif return octave_value((octave_base_value *) &x); } @@ -427,7 +431,11 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own); ~octave_swig_type() { if (thisown) { +#if SWIG_OCTAVE_PREREQ(9,0,0) + ++m_count; +#else ++count; +#endif for (unsigned int j = 0; j < types.size(); ++j) { if (!types[j].first || !types[j].first->clientdata) continue; @@ -515,16 +523,28 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own); } octave_value as_value() { +#if SWIG_OCTAVE_PREREQ(9,0,0) + ++m_count; +#else ++count; +#endif return Swig::swig_value_ref(this); } void incref() { +#if SWIG_OCTAVE_PREREQ(9,0,0) + ++m_count; +#else ++count; +#endif } void decref() { +#if SWIG_OCTAVE_PREREQ(9,0,0) + if (!--m_count) +#else if (!--count) +#endif delete this; } @@ -1123,8 +1143,13 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own); :ptr(_ptr) { // Ensure type_id() is set correctly +#if SWIG_OCTAVE_PREREQ(9,0,0) + if (s_t_id == -1) { + s_t_id = octave_swig_ref::static_type_id(); +#else if (t_id == -1) { t_id = octave_swig_ref::static_type_id(); +#endif } } @@ -1254,8 +1279,12 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own); #endif { return ptr->print(os, pr_as_read_syntax); } -#if SWIG_OCTAVE_PREREQ(4,4,0) +#if SWIG_OCTAVE_PREREQ(9,0,0) + static void set_type_id(int type_id) { s_t_id=type_id; } +#else +# if SWIG_OCTAVE_PREREQ(4,4,0) static void set_type_id(int type_id) { t_id=type_id; } +# endif #endif virtual type_conv_info numeric_conversion_function(void) const { @@ -1288,8 +1317,13 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own); : type(_type), buf((const char*)_buf, (const char*)_buf + _buf_len) { // Ensure type_id() is set correctly +#if SWIG_OCTAVE_PREREQ(9,0,0) + if (s_t_id == -1) { + s_t_id = octave_swig_packed::static_type_id(); +#else if (t_id == -1) { t_id = octave_swig_packed::static_type_id(); +#endif } } @@ -1369,8 +1403,12 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own); # endif #endif -#if SWIG_OCTAVE_PREREQ(4,4,0) +#if SWIG_OCTAVE_PREREQ(9,0,0) + static void set_type_id(int type_id) { s_t_id=type_id; } +#else +# if SWIG_OCTAVE_PREREQ(4,4,0) static void set_type_id(int type_id) { t_id=type_id; } +# endif #endif private: diff --git a/Lib/python/builtin.swg b/Lib/python/builtin.swg index d7593941533..6c2c311e65d 100644 --- a/Lib/python/builtin.swg +++ b/Lib/python/builtin.swg @@ -540,8 +540,10 @@ SwigPyBuiltin_ternaryfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, Py assert(tuple); Py_INCREF(b); PyTuple_SET_ITEM(tuple, 0, b); - Py_INCREF(c); - PyTuple_SET_ITEM(tuple, 1, c); + if (c) { + Py_INCREF(c); + PyTuple_SET_ITEM(tuple, 1, c); + } result = wrapper(a, tuple); Py_DECREF(tuple); return result; @@ -656,8 +658,10 @@ SwigPyBuiltin_ssizeobjargproc_closure(SwigPyWrapperFunction wrapper, PyObject *a tuple = PyTuple_New(2); assert(tuple); PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b)); - Py_INCREF(c); - PyTuple_SET_ITEM(tuple, 1, c); + if (c) { + Py_INCREF(c); + PyTuple_SET_ITEM(tuple, 1, c); + } resultobj = wrapper(a, tuple); result = resultobj ? 0 : -1; Py_XDECREF(resultobj); diff --git a/Lib/python/std_map.i b/Lib/python/std_map.i index 3f8f3b06bb5..954e7eb2d9a 100644 --- a/Lib/python/std_map.i +++ b/Lib/python/std_map.i @@ -2,7 +2,7 @@ Maps */ -%fragment("StdMapCommonTraits","header",fragment="StdSequenceTraits") +%fragment("StdMapCommonTraits","header",fragment="StdSequenceTraits",fragment="SwigPyIterator_T") { namespace swig { template diff --git a/Lib/r/rcontainer.swg b/Lib/r/rcontainer.swg index 54b31b39a44..84a6c6908cf 100644 --- a/Lib/r/rcontainer.swg +++ b/Lib/r/rcontainer.swg @@ -75,25 +75,29 @@ namespace swig { template inline void - setslice(Sequence* self, Difference i, Difference j, const InputSeq& v) { + setslice(Sequence* self, Difference i, Difference j, const InputSeq& is) { typename Sequence::size_type size = self->size(); typename Sequence::size_type ii = swig::check_index(i, size, true); typename Sequence::size_type jj = swig::slice_index(j, size); if (jj < ii) jj = ii; size_t ssize = jj - ii; - if (ssize <= v.size()) { + if (ssize <= is.size()) { + // expanding/staying the same size typename Sequence::iterator sb = self->begin(); - typename InputSeq::const_iterator vmid = v.begin(); + typename InputSeq::const_iterator vmid = is.begin(); std::advance(sb,ii); std::advance(vmid, jj - ii); - self->insert(std::copy(v.begin(), vmid, sb), vmid, v.end()); + self->insert(std::copy(is.begin(), vmid, sb), vmid, is.end()); } else { + // shrinking typename Sequence::iterator sb = self->begin(); typename Sequence::iterator se = self->begin(); std::advance(sb,ii); std::advance(se,jj); self->erase(sb,se); - self->insert(sb, v.begin(), v.end()); + sb = self->begin(); + std::advance(sb,ii); + self->insert(sb, is.begin(), is.end()); } } @@ -148,9 +152,9 @@ namespace swig { return swig::getslice(self, i, j); } - void __setslice__(difference_type i, difference_type j, const Sequence& v) + void __setslice__(difference_type i, difference_type j, const Sequence& is) throw (std::out_of_range, std::invalid_argument) { - swig::setslice(self, i, j, v); + swig::setslice(self, i, j, is); } void __delslice__(difference_type i, difference_type j) throw (std::out_of_range) { diff --git a/Lib/ruby/rubycontainer.swg b/Lib/ruby/rubycontainer.swg index ab2eeae83aa..cd912d959bb 100644 --- a/Lib/ruby/rubycontainer.swg +++ b/Lib/ruby/rubycontainer.swg @@ -101,7 +101,7 @@ namespace swig { inline Sequence* getslice(const Sequence* self, Difference i, Difference j) { typename Sequence::size_type size = self->size(); - typename Sequence::size_type ii = swig::check_index(i, size, (i == size && j == size)); + typename Sequence::size_type ii = swig::check_index(i, size, (i == (Difference)size && j == (Difference)size)); typename Sequence::size_type jj = swig::slice_index(j, size); if (jj > ii) { @@ -117,25 +117,29 @@ namespace swig { template inline void - setslice(Sequence* self, Difference i, Difference j, const InputSeq& v) { + setslice(Sequence* self, Difference i, Difference j, const InputSeq& is) { typename Sequence::size_type size = self->size(); typename Sequence::size_type ii = swig::check_index(i, size, true); typename Sequence::size_type jj = swig::slice_index(j, size); if (jj < ii) jj = ii; size_t ssize = jj - ii; - if (ssize <= v.size()) { + if (ssize <= is.size()) { + // expanding/staying the same size typename Sequence::iterator sb = self->begin(); - typename InputSeq::const_iterator vmid = v.begin(); + typename InputSeq::const_iterator vmid = is.begin(); std::advance(sb,ii); std::advance(vmid, jj - ii); - self->insert(std::copy(v.begin(), vmid, sb), vmid, v.end()); + self->insert(std::copy(is.begin(), vmid, sb), vmid, is.end()); } else { + // shrinking typename Sequence::iterator sb = self->begin(); typename Sequence::iterator se = self->begin(); std::advance(sb,ii); std::advance(se,jj); self->erase(sb,se); - self->insert(sb, v.begin(), v.end()); + sb = self->begin(); + std::advance(sb,ii); + self->insert(sb, is.begin(), is.end()); } } @@ -338,7 +342,7 @@ namespace swig typedef T value_type; typedef T* pointer; typedef int difference_type; - typedef int size_type; + typedef std::size_t size_type; typedef const pointer const_pointer; typedef RubySequence_InputIterator iterator; typedef RubySequence_InputIterator const_iterator; @@ -837,7 +841,7 @@ namespace swig return swig::from< Sequence::value_type >( x ); } - VALUE __setitem__(difference_type i, difference_type length, const Sequence& v) throw (std::invalid_argument) { + VALUE __setitem__(difference_type i, difference_type length, const Sequence& is) throw (std::invalid_argument) { if ( length < 0 ) return Qnil; @@ -849,13 +853,13 @@ namespace swig i = len + i; } Sequence::difference_type j = length + i; - if ( j > static_cast(len) ) { - swig::resize( $self, j, *(v.begin()) ); + if ( j > static_cast(len) && is.size() > 0 ) { + swig::resize( $self, j, *(is.begin()) ); } VALUE r = Qnil; - swig::setslice($self, i, j, v); - r = swig::from< const Sequence* >( &v ); + swig::setslice($self, i, j, is); + r = swig::from< const Sequence* >( &is ); return r; } } diff --git a/Lib/ruby/std_array.i b/Lib/ruby/std_array.i index a4d3ef54b8b..c00685f273e 100644 --- a/Lib/ruby/std_array.i +++ b/Lib/ruby/std_array.i @@ -41,7 +41,7 @@ getslice(const std::array* self, Difference i, Difference j) { typedef std::array Sequence; typename Sequence::size_type size = self->size(); - typename Sequence::size_type ii = swig::check_index(i, size, (i == size && j == size)); + typename Sequence::size_type ii = swig::check_index(i, size, (i == (Difference)size && j == (Difference)size)); typename Sequence::size_type jj = swig::slice_index(j, size); if (ii == 0 && jj == size) { diff --git a/Lib/swig.swg b/Lib/swig.swg index ce516368549..db7e08cf67c 100644 --- a/Lib/swig.swg +++ b/Lib/swig.swg @@ -711,23 +711,4 @@ template T SwigValueInit() { %} #endif -%insert("runtime") %{ -/* C99 and C++11 should provide snprintf, but define SWIG_NO_SNPRINTF - * if you're missing it. - */ -#if ((defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) || \ - (defined __cplusplus && __cplusplus >= 201103L) || \ - defined SWIG_HAVE_SNPRINTF) && \ - !defined SWIG_NO_SNPRINTF -# define SWIG_snprintf(O,S,F,A) snprintf(O,S,F,A) -# define SWIG_snprintf2(O,S,F,A,B) snprintf(O,S,F,A,B) -#else -/* Fallback versions ignore the buffer size, but most of our uses either have a - * fixed maximum possible size or dynamically allocate a buffer that's large - * enough. - */ -# define SWIG_snprintf(O,S,F,A) sprintf(O,F,A) -# define SWIG_snprintf2(O,S,F,A,B) sprintf(O,F,A,B) -#endif - -%} +%insert("runtime") "swigcompat.swg" diff --git a/Lib/swigcompat.swg b/Lib/swigcompat.swg new file mode 100644 index 00000000000..7d29b75391e --- /dev/null +++ b/Lib/swigcompat.swg @@ -0,0 +1,23 @@ +/* ----------------------------------------------------------------------------- + * swigcompat.swg + * + * Macros to provide support compatibility with older C and C++ standards. + * ----------------------------------------------------------------------------- */ + +/* C99 and C++11 should provide snprintf, but define SWIG_NO_SNPRINTF + * if you're missing it. + */ +#if ((defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) || \ + (defined __cplusplus && __cplusplus >= 201103L) || \ + defined SWIG_HAVE_SNPRINTF) && \ + !defined SWIG_NO_SNPRINTF +# define SWIG_snprintf(O,S,F,A) snprintf(O,S,F,A) +# define SWIG_snprintf2(O,S,F,A,B) snprintf(O,S,F,A,B) +#else +/* Fallback versions ignore the buffer size, but most of our uses either have a + * fixed maximum possible size or dynamically allocate a buffer that's large + * enough. + */ +# define SWIG_snprintf(O,S,F,A) sprintf(O,F,A) +# define SWIG_snprintf2(O,S,F,A,B) sprintf(O,F,A,B) +#endif diff --git a/Lib/swiglabels.swg b/Lib/swiglabels.swg index 0b9ad23830f..58d87e92a6e 100644 --- a/Lib/swiglabels.swg +++ b/Lib/swiglabels.swg @@ -122,7 +122,7 @@ # pragma warning disable 592 #endif -#if __cplusplus >=201103L +#if defined(__cplusplus) && __cplusplus >=201103L # define SWIG_NULLPTR nullptr #else # define SWIG_NULLPTR NULL diff --git a/Lib/tcl/argcargv.i b/Lib/tcl/argcargv.i index ecb2f4bff53..e93f6914622 100644 --- a/Lib/tcl/argcargv.i +++ b/Lib/tcl/argcargv.i @@ -3,7 +3,7 @@ * ------------------------------------------------------------- */ %typemap(in) (int ARGC, char **ARGV) { - int i, nitems; + Tcl_Size i, nitems; Tcl_Obj **listobjv; if (Tcl_ListObjGetElements(interp, $input, &nitems, &listobjv) == TCL_ERROR) { SWIG_exception_fail(SWIG_ValueError, "in method '$symname', Expecting list of argv"); @@ -18,7 +18,7 @@ } %typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) { - int len; + Tcl_Size len; $1 = Tcl_ListObjLength(interp, $input, &len) == TCL_OK; } diff --git a/Lib/tcl/std_vector.i b/Lib/tcl/std_vector.i index 599f058db8b..f950ee3fd5c 100644 --- a/Lib/tcl/std_vector.i +++ b/Lib/tcl/std_vector.i @@ -35,7 +35,7 @@ #include SWIGINTERN Tcl_Obj* SwigString_FromString(const std::string &s) { - return Tcl_NewStringObj(s.data(), (int)s.length()); + return Tcl_NewStringObj(s.data(), (Tcl_Size)s.length()); } SWIGINTERN int SWIG_Tcl_GetBoolFromObj(Tcl_Interp *interp, Tcl_Obj *o, bool *val) { @@ -48,7 +48,7 @@ SWIGINTERN int SWIG_Tcl_GetBoolFromObj(Tcl_Interp *interp, Tcl_Obj *o, bool *val } SWIGINTERN int SwigString_AsString(Tcl_Interp *interp, Tcl_Obj *o, std::string *val) { - int len; + Tcl_Size len; const char* temp = Tcl_GetStringFromObj(o, &len); (void)interp; if (temp == NULL) @@ -85,8 +85,8 @@ namespace std { template class vector { %typemap(in) vector< T > (std::vector< T > *v) { Tcl_Obj **listobjv; - int nitems; - int i; + Tcl_Size nitems; + Tcl_Size i; T* temp; if (SWIG_ConvertPtr($input, (void **) &v, @@ -114,8 +114,8 @@ namespace std { %typemap(in) const vector< T >* (std::vector< T > *v, std::vector< T > w), const vector< T >& (std::vector< T > *v, std::vector< T > w) { Tcl_Obj **listobjv; - int nitems; - int i; + Tcl_Size nitems; + Tcl_Size i; T* temp; if(SWIG_ConvertPtr($input, (void **) &v, @@ -153,7 +153,7 @@ namespace std { %typecheck(SWIG_TYPECHECK_VECTOR) vector< T > { Tcl_Obj **listobjv; - int nitems; + Tcl_Size nitems; T* temp; std::vector< T > *v; @@ -182,7 +182,7 @@ namespace std { %typecheck(SWIG_TYPECHECK_VECTOR) const vector< T >&, const vector< T >* { Tcl_Obj **listobjv; - int nitems; + Tcl_Size nitems; T* temp; std::vector< T > *v; @@ -261,8 +261,8 @@ namespace std { %typemap(in) vector< T > (std::vector< T > *v){ Tcl_Obj **listobjv; - int nitems; - int i; + Tcl_Size nitems; + Tcl_Size i; T temp; if(SWIG_ConvertPtr($input, (void **) &v, @@ -285,8 +285,8 @@ namespace std { %typemap(in) const vector< T >& (std::vector< T > *v,std::vector< T > w), const vector< T >* (std::vector< T > *v,std::vector< T > w) { Tcl_Obj **listobjv; - int nitems; - int i; + Tcl_Size nitems; + Tcl_Size i; T temp; if(SWIG_ConvertPtr($input, (void **) &v, @@ -316,7 +316,7 @@ namespace std { %typecheck(SWIG_TYPECHECK_VECTOR) vector< T > { Tcl_Obj **listobjv; - int nitems; + Tcl_Size nitems; T temp; std::vector< T > *v; @@ -343,7 +343,7 @@ namespace std { %typecheck(SWIG_TYPECHECK_VECTOR) const vector< T >&, const vector< T >*{ Tcl_Obj **listobjv; - int nitems; + Tcl_Size nitems; T temp; std::vector< T > *v; diff --git a/Lib/tcl/tclinit.swg b/Lib/tcl/tclinit.swg index cf14de88144..eb9e3ecaa05 100644 --- a/Lib/tcl/tclinit.swg +++ b/Lib/tcl/tclinit.swg @@ -24,7 +24,7 @@ SWIGEXPORT int SWIG_init(Tcl_Interp *); /* Compatibility version for TCL stubs */ #ifndef SWIG_TCL_STUBS_VERSION -#define SWIG_TCL_STUBS_VERSION "8.4" +#define SWIG_TCL_STUBS_VERSION "8.4-" #endif %} diff --git a/Lib/tcl/tclprimtypes.swg b/Lib/tcl/tclprimtypes.swg index 06cc527748a..ddefa7db511 100644 --- a/Lib/tcl/tclprimtypes.swg +++ b/Lib/tcl/tclprimtypes.swg @@ -82,7 +82,7 @@ SWIG_AsVal_dec(unsigned long)(Tcl_Obj *obj, unsigned long *val) { get it as a string so we can distinguish these cases. */ } { - int len = 0; + Tcl_Size len = 0; const char *nptr = Tcl_GetStringFromObj(obj, &len); if (nptr && len > 0) { char *endptr; @@ -183,7 +183,7 @@ SWIG_AsVal_dec(unsigned long long)(Tcl_Obj *obj, unsigned long long *val) if (val) *val = (unsigned long) v; return SWIG_OK; } else { - int len = 0; + Tcl_Size len = 0; const char *nptr = Tcl_GetStringFromObj(obj, &len); if (nptr && len > 0) { char *endptr; diff --git a/Lib/tcl/tclrun.swg b/Lib/tcl/tclrun.swg index b53176874ed..debbd091e8d 100644 --- a/Lib/tcl/tclrun.swg +++ b/Lib/tcl/tclrun.swg @@ -118,6 +118,8 @@ SWIG_Tcl_Disown(void *ptr) { return 0; } +SWIGRUNTIME void SWIG_Tcl_ObjectDelete(ClientData clientData); + /* Convert a pointer value */ SWIGRUNTIME int SWIG_Tcl_ConvertPtrFromString(Tcl_Interp *interp, const char *c, void **ptr, swig_type_info *ty, int flags) { @@ -164,10 +166,16 @@ SWIG_Tcl_ConvertPtrFromString(Tcl_Interp *interp, const char *c, void **ptr, swi c = SWIG_UnpackData(c,ptr,sizeof(void *)); if (ty) { + Tcl_CmdInfo info; tc = c ? SWIG_TypeCheck(c,ty) : 0; - if (tc) { - Tcl_CmdInfo info; - if (Tcl_GetCommandInfo(interp, cmd_name, &info)) { + if (!tc) { + return SWIG_ERROR; + } + if (Tcl_GetCommandInfo(interp, cmd_name, &info)) { + /* When creating a pointer string, SWIG_Tcl_NewInstanceObj calls Tcl_CreateObjCommand and sets + * info.objClientData to an instance of swig_instance. Detecting when we can cast any info.objClientData + * to swig_instance is not simple as it may be an unrelated command; we use deleteProc to determine this. */ + if (info.deleteProc == SWIG_Tcl_ObjectDelete) { swig_instance *inst = (swig_instance *)info.objClientData; if (!inst->thisvalue) { *ptr = 0; @@ -184,13 +192,11 @@ SWIG_Tcl_ConvertPtrFromString(Tcl_Interp *interp, const char *c, void **ptr, swi } { int newmemory = 0; - *ptr = SWIG_TypeCast(tc,(void *) *ptr,&newmemory); + *ptr = SWIG_TypeCast(tc,(void *) *ptr, &newmemory); assert(!newmemory); /* newmemory handling not yet implemented */ } } } - } else { - return SWIG_ERROR; } } @@ -521,7 +527,7 @@ SWIG_Tcl_NewInstanceObj(Tcl_Interp *interp, void *thisvalue, swig_type_info *typ newinst->thisvalue = thisvalue; newinst->classptr = (swig_class *) type->clientdata; newinst->destroy = flags; - newinst->cmdtok = Tcl_CreateObjCommand(interp, Tcl_GetString(robj), (swig_wrapper_func) SWIG_MethodCommand, (ClientData) newinst, (swig_delete_func) SWIG_ObjectDelete); + newinst->cmdtok = Tcl_CreateObjCommand(interp, Tcl_GetString(robj), (swig_wrapper_func) SWIG_Tcl_MethodCommand, (ClientData) newinst, (swig_delete_func) SWIG_Tcl_ObjectDelete); if (flags) { SWIG_Acquire(thisvalue); } @@ -613,7 +619,7 @@ SWIG_Tcl_ObjectConstructor(ClientData clientData, Tcl_Interp *interp, int objc, if (destroy) { SWIG_Acquire(thisvalue); } - newinst->cmdtok = Tcl_CreateObjCommand(interp,name, (swig_wrapper) SWIG_MethodCommand, (ClientData) newinst, (swig_delete_func) SWIG_ObjectDelete); + newinst->cmdtok = Tcl_CreateObjCommand(interp,name, (swig_wrapper) SWIG_Tcl_MethodCommand, (ClientData) newinst, (swig_delete_func) SWIG_Tcl_ObjectDelete); return TCL_OK; } @@ -674,7 +680,7 @@ SWIG_Tcl_GetArgs(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], const char break; case 's': case 'S': if (*(c+1) == '#') { - int *vlptr = (int *) va_arg(ap, void *); + Tcl_Size *vlptr = (Tcl_Size *) va_arg(ap, void *); *((char **) vptr) = Tcl_GetStringFromObj(obj, vlptr); c++; } else { diff --git a/Lib/tcl/tclruntime.swg b/Lib/tcl/tclruntime.swg index bb4edd74545..3b34a76c000 100644 --- a/Lib/tcl/tclruntime.swg +++ b/Lib/tcl/tclruntime.swg @@ -6,6 +6,22 @@ #include #include #include + +/* Check, if Tcl version supports Tcl_Size, + which was introduced in Tcl 8.7 and 9. +*/ +#ifndef TCL_SIZE_MAX + #include + #define TCL_SIZE_MAX INT_MAX + + #ifndef Tcl_Size + typedef int Tcl_Size; + #endif + + #define TCL_SIZE_MODIFIER "" + #define Tcl_GetSizeIntFromObj Tcl_GetIntFromObj + #define Tcl_NewSizeIntObj Tcl_NewIntObj +#endif %} %insert(runtime) "swigrun.swg"; /* Common C API type-checking code */ diff --git a/Lib/tcl/tclstrings.swg b/Lib/tcl/tclstrings.swg index 540d6270eb2..738c8136296 100644 --- a/Lib/tcl/tclstrings.swg +++ b/Lib/tcl/tclstrings.swg @@ -6,7 +6,7 @@ SWIGINTERN int SWIG_AsCharPtrAndSize(Tcl_Obj *obj, char** cptr, size_t* psize, int *alloc) { - int len = 0; + Tcl_Size len = 0; char *cstr = Tcl_GetStringFromObj(obj, &len); if (cstr) { if (cptr) *cptr = cstr; @@ -24,7 +24,7 @@ SWIG_AsCharPtrAndSize(Tcl_Obj *obj, char** cptr, size_t* psize, int *alloc) SWIGINTERNINLINE Tcl_Obj * SWIG_FromCharPtrAndSize(const char* carray, size_t size) { - return (size < INT_MAX) ? Tcl_NewStringObj(carray, %numeric_cast(size,int)) : NULL; + return (size < TCL_SIZE_MAX) ? Tcl_NewStringObj(carray, %numeric_cast(size,Tcl_Size)) : NULL; } } diff --git a/Lib/tcl/tclwstrings.swg b/Lib/tcl/tclwstrings.swg index 09374c54fac..76da2ab0887 100644 --- a/Lib/tcl/tclwstrings.swg +++ b/Lib/tcl/tclwstrings.swg @@ -12,14 +12,14 @@ SWIGINTERN int SWIG_AsWCharPtrAndSize(Tcl_Obj *obj, wchar_t** cptr, size_t* psize, int *alloc) { - int len = 0; + Tcl_Size len = 0; Tcl_UniChar *ustr = Tcl_GetUnicodeFromObj(obj, &len); if (ustr) { if (cptr) { Tcl_Encoding encoding = NULL; char *src = (char *) ustr; - int srcLen = (len)*sizeof(Tcl_UniChar); - int dstLen = sizeof(wchar_t)*(len + 1); + Tcl_Size srcLen = (len)*sizeof(Tcl_UniChar); + Tcl_Size dstLen = sizeof(wchar_t)*(len + 1); char *dst = %new_array(dstLen, char); int flags = 0; Tcl_EncodingState *statePtr = 0; @@ -44,11 +44,11 @@ SWIGINTERNINLINE Tcl_Obj * SWIG_FromWCharPtrAndSize(const wchar_t* carray, size_t size) { Tcl_Obj *res = NULL; - if (size < INT_MAX) { + if (size < TCL_SIZE_MAX) { Tcl_Encoding encoding = NULL; char *src = (char *) carray; - int srcLen = (int)(size*sizeof(wchar_t)); - int dstLen = (int)(size*sizeof(Tcl_UniChar)); + Tcl_Size srcLen = (Tcl_Size)(size*sizeof(wchar_t)); + Tcl_Size dstLen = (Tcl_Size)(size*sizeof(Tcl_UniChar)); char *dst = %new_array(dstLen, char); int flags = 0; Tcl_EncodingState *statePtr = 0; @@ -59,7 +59,7 @@ SWIG_FromWCharPtrAndSize(const wchar_t* carray, size_t size) Tcl_ExternalToUtf(0, encoding, src, srcLen, flags, statePtr, dst, dstLen, &srcRead, &dstWrote, &dstChars); - res = Tcl_NewUnicodeObj((Tcl_UniChar*)dst, (int)size); + res = Tcl_NewUnicodeObj((Tcl_UniChar*)dst, (Tcl_Size)size); %delete_array(dst); } return res; diff --git a/Lib/typemaps/ptrtypes.swg b/Lib/typemaps/ptrtypes.swg index ca54fcdc265..8619b31800e 100644 --- a/Lib/typemaps/ptrtypes.swg +++ b/Lib/typemaps/ptrtypes.swg @@ -183,14 +183,34 @@ %ptr_input_typemap(%arg(CheckCode),%arg(AsPtrMeth),%arg(AsPtrFrag),Type); %enddef +/*--------------------------------------------------------------------- + * typemap definition for types with from method for ptr types + * Same as typemaps_from but without varout typemap + *---------------------------------------------------------------------*/ + +%define %ptr_typemaps_from(FromMeth, FromFrag, Type...) + %value_out_typemap(%arg(FromMeth), %arg(FromFrag), Type); + /* No varout typemap */ + %value_constcode_typemap(%arg(FromMeth), %arg(FromFrag), Type); + %value_directorin_typemap(%arg(FromMeth), %arg(FromFrag), Type); + %value_throws_typemap(%arg(FromMeth), %arg(FromFrag), Type); + %value_output_typemap(%arg(FromMeth), %arg(FromFrag), Type); +%enddef + /*--------------------------------------------------------------------- * typemap definition for types with asptr/from methods *---------------------------------------------------------------------*/ %define %typemaps_asptrfrom(CheckCode, AsPtrMeth, FromMeth, AsPtrFrag, FromFrag, Type...) + %typemaps_asptr(%arg(CheckCode), %arg(AsPtrMeth), %arg(AsPtrFrag), Type) + %ptr_typemaps_from(%arg(FromMeth), %arg(FromFrag), Type); + %ptr_inout_typemap(Type); +%enddef + +// Same as typemaps_asptrfrom but defines a varout typemap to wrap with value semantics instead of the default pointer semantics +%define %_typemaps_asptrfrom(CheckCode, AsPtrMeth, FromMeth, AsPtrFrag, FromFrag, Type...) %typemaps_asptr(%arg(CheckCode), %arg(AsPtrMeth), %arg(AsPtrFrag), Type) %typemaps_from(%arg(FromMeth), %arg(FromFrag), Type); - %value_output_typemap(%arg(FromMeth), %arg(FromFrag), Type); %ptr_inout_typemap(Type); %enddef @@ -199,7 +219,7 @@ *---------------------------------------------------------------------*/ %define %typemaps_asptrfromn(CheckCode, Type...) -%typemaps_asptrfrom(%arg(CheckCode), +%_typemaps_asptrfrom(%arg(CheckCode), %arg(SWIG_AsPtr(Type)), %arg(SWIG_From(Type)), %arg(SWIG_AsPtr_frag(Type)), diff --git a/Lib/typemaps/valtypes.swg b/Lib/typemaps/valtypes.swg index f2f34acfca4..7623ff049b0 100644 --- a/Lib/typemaps/valtypes.swg +++ b/Lib/typemaps/valtypes.swg @@ -180,6 +180,7 @@ /*--------------------------------------------------------------------- * typemap definition for types with from method *---------------------------------------------------------------------*/ + %define %typemaps_from(FromMeth, FromFrag, Type...) %value_out_typemap(%arg(FromMeth), %arg(FromFrag), Type); %value_varout_typemap(%arg(FromMeth), %arg(FromFrag), Type); @@ -191,7 +192,7 @@ /*--------------------------------------------------------------------- - * typemap definition for types with alval/from method + * typemap definition for types with asval/from method *---------------------------------------------------------------------*/ %define %typemaps_asvalfrom(CheckCode, AsValMeth, FromMeth, diff --git a/RELEASENOTES b/RELEASENOTES index 76b5a7a8ec6..e4cfb7859a2 100644 --- a/RELEASENOTES +++ b/RELEASENOTES @@ -7,6 +7,14 @@ Release Notes Detailed release notes are available with the release and are also published on the SWIG web site at https://swig.org/release.html. +SWIG-4.2.1 summary: +- Tcl 9.0 support. +- Octave 9.0 support. +- Improvements wrapping friend functions. +- Variadic templated functions within a template support. +- Type deduction enhancements. +- Stability and regression fixes. + SWIG-4.2.0 summary: - Various template wrapping improvements: template template parameters, variadic templates, partially specialized templates, const template diff --git a/Source/CParse/cscanner.c b/Source/CParse/cscanner.c index f7584c68130..e15a25c8033 100644 --- a/Source/CParse/cscanner.c +++ b/Source/CParse/cscanner.c @@ -643,6 +643,7 @@ int yylex(void) { case NUM_BOOL: yylval.dtype.type = T_BOOL; num_common: + yylval.dtype.unary_arg_type = 0; yylval.dtype.val = NewString(Scanner_text(scan)); yylval.dtype.bitfield = 0; yylval.dtype.throws = 0; diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index e5a79f128fa..4a7040d96f8 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -321,7 +321,14 @@ Hash *Swig_cparse_features(void) { return features_hash; } -/* Fully qualify any template parameters */ +/* ----------------------------------------------------------------------------- + * feature_identifier_fix() + * + * If a template, return template with all template parameters fully resolved. + * + * This is a copy and modification of typemap_identifier_fix. + * ----------------------------------------------------------------------------- */ + static String *feature_identifier_fix(String *s) { String *tp = SwigType_istemplate_templateprefix(s); if (tp) { @@ -411,7 +418,6 @@ static void add_symbols(Node *n) { } while (n) { String *symname = 0; - /* for friends, we need to pop the scope once */ String *old_prefix = 0; Symtab *old_scope = 0; int isfriend = inclass && Checkattr(n, "storage", "friend"); @@ -421,28 +427,24 @@ static void add_symbols(Node *n) { if (inclass) { String *name = Getattr(n, "name"); if (isfriend) { - /* for friends, we need to add the scopename if needed */ + /* For friends, set the scope to the same as the class that the friend is defined/declared in, that is, pop scope once */ String *prefix = name ? Swig_scopename_prefix(name) : 0; old_prefix = Namespaceprefix; old_scope = Swig_symbol_popscope(); Namespaceprefix = Swig_symbol_qualifiedscopename(0); if (!prefix) { + /* To check - this should probably apply to operators too */ if (name && !is_operator(name) && Namespaceprefix) { - String *nname = NewStringf("%s::%s", Namespaceprefix, name); - Setattr(n,"name",nname); - Delete(nname); + String *friendusing = NewStringf("using namespace %s;", Namespaceprefix); + Setattr(n, "friendusing", friendusing); + Delete(friendusing); } } else { - Symtab *st = Swig_symbol_getscope(prefix); - String *ns = st ? Getattr(st,"name") : prefix; - String *base = Swig_scopename_last(name); - String *nname = NewStringf("%s::%s", ns, base); - Setattr(n,"name",nname); - Delete(nname); - Delete(base); - Delete(prefix); + /* Qualified friend declarations should not be possible as they are ignored in the parse tree */ + /* TODO: uncomment out for swig-4.3.0 + assert(0); + */ } - Namespaceprefix = 0; } else if (Equal(nodeType(n), "using")) { String *uname = Getattr(n, "uname"); Node *cls = current_class ? current_class : currentOuterClass; /* Current class seems to vary depending on whether it is a template class or a plain class */ @@ -1606,6 +1608,11 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier) String *val; String *rawval; int type; + /* The type code for the argument when the top level operator is unary. + * This is useful because our grammar parses cases such as (7)*6 as a + * cast applied to an unary operator. + */ + int unary_arg_type; String *qualifier; String *refqualifier; String *bitfield; @@ -1647,7 +1654,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier) Node *node; }; -// Define special token END for end of input. +/* Define special token END for end of input. */ %token END 0 %token ID @@ -1776,8 +1783,9 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier) /* C++ decltype/auto type deduction. */ static SwigType *deduce_type(const struct Define *dtype) { + Node *n; if (!dtype->val) return NULL; - Node *n = Swig_symbol_clookup(dtype->val, 0); + n = Swig_symbol_clookup(dtype->val, 0); if (n) { if (Strcmp(nodeType(n),"enumitem") == 0) { /* For an enumitem, the "type" attribute gives us the underlying integer @@ -2037,15 +2045,20 @@ clear_directive : CLEAR tm_list SEMI { constant_directive : CONSTANT identifier EQUAL definetype SEMI { SwigType *type = NewSwigType($4.type); - $$ = new_node("constant"); - Setattr($$, "name", $2); - Setattr($$, "type", type); - Setattr($$, "value", $4.val); - if ($4.rawval) Setattr($$, "rawval", $4.rawval); - Setattr($$, "storage", "%constant"); - SetFlag($$, "feature:immutable"); - add_symbols($$); - Delete(type); + if (Len(type) > 0) { + $$ = new_node("constant"); + Setattr($$, "name", $2); + Setattr($$, "type", type); + Setattr($$, "value", $4.val); + if ($4.rawval) Setattr($$, "rawval", $4.rawval); + Setattr($$, "storage", "%constant"); + SetFlag($$, "feature:immutable"); + add_symbols($$); + Delete(type); + } else { + Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE, cparse_file, cparse_line, "Unsupported constant value (ignored)\n"); + $$ = 0; + } } | CONSTANT type declarator def_args SEMI { SwigType_push($2, $3.type); @@ -3166,10 +3179,13 @@ c_decl : storage_class type declarator cpp_const initializer c_decl_tail { if ($5.val && $5.type) { /* store initializer type as it might be different to the declared type */ SwigType *valuetype = NewSwigType($5.type); - if (Len(valuetype) > 0) - Setattr($$,"valuetype",valuetype); - else - Delete(valuetype); + if (Len(valuetype) > 0) { + Setattr($$, "valuetype", valuetype); + } else { + /* If we can't determine the initializer type use the declared type. */ + Setattr($$, "valuetype", $2); + } + Delete(valuetype); } if (!$6) { if (Len(scanner_ccode)) { @@ -3193,27 +3209,26 @@ c_decl : storage_class type declarator cpp_const initializer c_decl_tail { } if ($3.id) { - /* Look for "::" declarations (ignored) */ - if (Strstr($3.id, "::")) { + /* Ignore all scoped declarations, could be 1. out of class function definition 2. friend function declaration 3. ... */ + String *p = Swig_scopename_prefix($3.id); + if (p) { /* This is a special case. If the scope name of the declaration exactly matches that of the declaration, then we will allow it. Otherwise, delete. */ - String *p = Swig_scopename_prefix($3.id); - if (p) { - if ((Namespaceprefix && Strcmp(p, Namespaceprefix) == 0) || - (Classprefix && Strcmp(p, Classprefix) == 0)) { - String *lstr = Swig_scopename_last($3.id); - Setattr($$, "name", lstr); - Delete(lstr); - set_nextSibling($$, $6); - } else { - Delete($$); - $$ = $6; - } - Delete(p); + if ((Namespaceprefix && Strcmp(p, Namespaceprefix) == 0) || + (Classprefix && Strcmp(p, Classprefix) == 0)) { + String *lstr = Swig_scopename_last($3.id); + Setattr($$, "name", lstr); + Delete(lstr); + set_nextSibling($$, $6); } else { Delete($$); $$ = $6; } + Delete(p); + } else if (Strncmp($3.id, "::", 2) == 0) { + /* global scope declaration/definition ignored */ + Delete($$); + $$ = $6; } else { set_nextSibling($$, $6); } @@ -3246,7 +3261,8 @@ c_decl : storage_class type declarator cpp_const initializer c_decl_tail { Setattr($$, "noexcept", $4.nexcept); Setattr($$, "final", $4.final); - if (Strstr($3.id, "::")) { + if ($3.id) { + /* Ignore all scoped declarations, could be 1. out of class function definition 2. friend function declaration 3. ... */ String *p = Swig_scopename_prefix($3.id); if (p) { if ((Namespaceprefix && Strcmp(p, Namespaceprefix) == 0) || @@ -3259,7 +3275,8 @@ c_decl : storage_class type declarator cpp_const initializer c_decl_tail { $$ = 0; } Delete(p); - } else { + } else if (Strncmp($3.id, "::", 2) == 0) { + /* global scope declaration/definition ignored */ Delete($$); $$ = 0; } @@ -3300,8 +3317,9 @@ c_decl : storage_class type declarator cpp_const initializer c_decl_tail { } } - if (Strstr($3.id,"::")) { - String *p = Swig_scopename_prefix($3.id); + if ($3.id) { + /* Ignore all scoped declarations, could be 1. out of class function definition 2. friend function declaration 3. ... */ + String *p = Swig_scopename_prefix($3.id); if (p) { if ((Namespaceprefix && Strcmp(p, Namespaceprefix) == 0) || (Classprefix && Strcmp(p, Classprefix) == 0)) { @@ -3314,7 +3332,8 @@ c_decl : storage_class type declarator cpp_const initializer c_decl_tail { $$ = $9; } Delete(p); - } else { + } else if (Strncmp($3.id, "::", 2) == 0) { + /* global scope declaration/definition ignored */ Delete($$); $$ = $9; } @@ -3348,8 +3367,9 @@ c_decl : storage_class type declarator cpp_const initializer c_decl_tail { Setattr($$, "noexcept", $4.nexcept); Setattr($$, "final", $4.final); - if (Strstr($3.id, "::")) { - String *p = Swig_scopename_prefix($3.id); + if ($3.id) { + /* Ignore all scoped declarations, could be 1. out of class function definition 2. friend function declaration 3. ... */ + String *p = Swig_scopename_prefix($3.id); if (p) { if ((Namespaceprefix && Strcmp(p, Namespaceprefix) == 0) || (Classprefix && Strcmp(p, Classprefix) == 0)) { @@ -3361,7 +3381,8 @@ c_decl : storage_class type declarator cpp_const initializer c_decl_tail { $$ = 0; } Delete(p); - } else { + } else if (Strncmp($3.id, "::", 2) == 0) { + /* global scope declaration/definition ignored */ Delete($$); $$ = 0; } @@ -3758,7 +3779,6 @@ cpp_class_decl: storage_class cpptype idcolon class_virt_specifier_opt inherit L int errored_flag = 0; String *code; $$ = new_node("class"); - Setline($$,cparse_start_line); Setattr($$,"kind",$2); if ($5) { Setattr($$,"baselist", Getattr($5,"public")); @@ -4003,7 +4023,6 @@ cpp_class_decl: storage_class cpptype idcolon class_virt_specifier_opt inherit L String *code; unnamed = make_unnamed(); $$ = new_node("class"); - Setline($$,cparse_start_line); Setattr($$,"kind",$2); if ($3) { Setattr($$,"baselist", Getattr($3,"public")); @@ -4445,10 +4464,10 @@ templateparameter : templcpptype def_args { } | parm { Parm *p = $1; + String *name = Getattr(p, "name"); $$ = $1; /* Correct the 'type name' parameter string, split into the appropriate "name" and "type" attributes */ - String *name = Getattr(p, "name"); if (!name) { String *type = Getattr(p, "type"); if ((Strncmp(type, "class ", 6) == 0) || (Strncmp(type, "typename ", 9) == 0)) { @@ -4732,7 +4751,10 @@ cpp_member : cpp_member_no_dox */ cpp_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end { - if (inclass || extendmode) { + /* Cannot be a constructor declaration/definition if parsed as a friend destructor/constructor + or a badly declared friend function without return type */ + int isfriend = Strstr($1, "friend") != NULL; + if (!isfriend && (inclass || extendmode)) { String *name = SwigType_templateprefix($2); /* A constructor can optionally be declared with template parameters before C++20, strip these off */ SwigType *decl = NewStringEmpty(); $$ = new_node("constructor"); @@ -5251,7 +5273,8 @@ def_args : EQUAL definetype { if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE); $$.val = NewString(scanner_ccode); $$.rawval = 0; - $$.type = T_UNKNOWN; + $$.type = T_UNKNOWN; + $$.unary_arg_type = 0; $$.bitfield = 0; $$.throws = 0; $$.throwf = 0; @@ -5272,6 +5295,7 @@ def_args : EQUAL definetype { $$.val = 0; $$.rawval = 0; $$.type = T_UNKNOWN; + $$.unary_arg_type = 0; $$.bitfield = 0; $$.throws = 0; $$.throwf = 0; @@ -6358,6 +6382,7 @@ deleted_definition : DELETE_KW { $$.val = NewString("delete"); $$.rawval = 0; $$.type = T_STRING; + $$.unary_arg_type = 0; $$.qualifier = 0; $$.refqualifier = 0; $$.bitfield = 0; @@ -6373,6 +6398,7 @@ explicit_default : DEFAULT { $$.val = NewString("default"); $$.rawval = 0; $$.type = T_STRING; + $$.unary_arg_type = 0; $$.qualifier = 0; $$.refqualifier = 0; $$.bitfield = 0; @@ -6491,13 +6517,15 @@ edecl : identifier { etype : expr { $$ = $1; + /* We get T_USER here for a typedef - unfortunately we can't + * currently resolve typedefs at this stage of parsing. */ if (($$.type != T_INT) && ($$.type != T_UINT) && ($$.type != T_LONG) && ($$.type != T_ULONG) && ($$.type != T_LONGLONG) && ($$.type != T_ULONGLONG) && ($$.type != T_SHORT) && ($$.type != T_USHORT) && ($$.type != T_SCHAR) && ($$.type != T_UCHAR) && ($$.type != T_CHAR) && ($$.type != T_BOOL) && - ($$.type != T_UNKNOWN)) { + ($$.type != T_UNKNOWN) && ($$.type != T_USER)) { Swig_error(cparse_file,cparse_line,"Type error. Expecting an integral type\n"); } } @@ -6510,6 +6538,7 @@ expr : valexpr Node *n; $$.val = $1; $$.type = T_UNKNOWN; + $$.unary_arg_type = 0; /* Check if value is in scope */ n = Swig_symbol_clookup($1,0); if (n) { @@ -6518,6 +6547,7 @@ expr : valexpr String *q = Swig_symbol_qualified(n); if (q) { $$.val = NewStringf("%s::%s", q, Getattr(n,"name")); + $$.type = SwigType_type(Getattr(n, "type")); Delete(q); } } else { @@ -6571,16 +6601,19 @@ exprsimple : exprnum | string { $$.val = $1; $$.type = T_STRING; + $$.unary_arg_type = 0; } | SIZEOF LPAREN type parameter_declarator RPAREN { SwigType_push($3,$4.type); $$.val = NewStringf("sizeof(%s)",SwigType_str($3,0)); $$.type = T_ULONG; + $$.unary_arg_type = 0; } | SIZEOF ELLIPSIS LPAREN type parameter_declarator RPAREN { SwigType_push($4,$5.type); $$.val = NewStringf("sizeof...(%s)",SwigType_str($4,0)); $$.type = T_ULONG; + $$.unary_arg_type = 0; } /* We don't support all valid expressions here currently - e.g. * sizeof( x) doesn't work - but those are unlikely to @@ -6591,7 +6624,8 @@ exprsimple : exprnum */ | SIZEOF LPAREN exprsimple RPAREN { $$.val = NewStringf("sizeof(%s)", $3.val); - $$.type = T_ULONG; + $$.type = T_ULONG; + $$.unary_arg_type = 0; } /* `sizeof expr` without parentheses is valid for an expression, * but not for a type. This doesn't support `sizeof x` in @@ -6600,11 +6634,13 @@ exprsimple : exprnum | SIZEOF exprsimple { $$.val = NewStringf("sizeof(%s)", $2.val); $$.type = T_ULONG; + $$.unary_arg_type = 0; } | wstring { $$.val = $1; $$.rawval = NewStringf("L\"%s\"", $$.val); $$.type = T_WSTRING; + $$.unary_arg_type = 0; } | CHARCONST { $$.val = NewString($1); @@ -6614,6 +6650,7 @@ exprsimple : exprnum $$.rawval = NewString("'\\0'"); } $$.type = T_CHAR; + $$.unary_arg_type = 0; $$.bitfield = 0; $$.throws = 0; $$.throwf = 0; @@ -6628,6 +6665,7 @@ exprsimple : exprnum $$.rawval = NewString("L'\\0'"); } $$.type = T_WCHAR; + $$.unary_arg_type = 0; $$.bitfield = 0; $$.throws = 0; $$.throwf = 0; @@ -6652,7 +6690,9 @@ valexpr : exprsimple /* A few common casting operations */ | LPAREN expr RPAREN expr %prec CAST { - $$ = $4; + int cast_type_code = SwigType_type($2.val); + $$ = $4; + $$.unary_arg_type = 0; if ($4.type != T_STRING) { switch ($2.type) { case T_FLOAT: @@ -6667,10 +6707,28 @@ valexpr : exprsimple break; } } - $$.type = promote($2.type, $4.type); + /* As well as C-style casts, this grammar rule currently also + * matches a binary operator with a LHS in parentheses for + * binary operators which also have an unary form, e.g.: + * + * (6)*7 + * (6)&7 + * (6)+7 + * (6)-7 + */ + if (cast_type_code != T_USER && cast_type_code != T_UNKNOWN) { + /* $2 is definitely a type so we know this is a cast. */ + $$.type = cast_type_code; + } else if ($4.type == 0 || $4.unary_arg_type == 0) { + /* Not one of the cases above, so we know this is a cast. */ + $$.type = cast_type_code; + } else { + $$.type = promote($2.type, $4.unary_arg_type); + } } | LPAREN expr pointer RPAREN expr %prec CAST { $$ = $5; + $$.unary_arg_type = 0; if ($5.type != T_STRING) { SwigType_push($2.val,$3); $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val); @@ -6678,6 +6736,7 @@ valexpr : exprsimple } | LPAREN expr AND RPAREN expr %prec CAST { $$ = $5; + $$.unary_arg_type = 0; if ($5.type != T_STRING) { SwigType_add_reference($2.val); $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val); @@ -6685,6 +6744,7 @@ valexpr : exprsimple } | LPAREN expr LAND RPAREN expr %prec CAST { $$ = $5; + $$.unary_arg_type = 0; if ($5.type != T_STRING) { SwigType_add_rvalue_reference($2.val); $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val); @@ -6692,6 +6752,7 @@ valexpr : exprsimple } | LPAREN expr pointer AND RPAREN expr %prec CAST { $$ = $6; + $$.unary_arg_type = 0; if ($6.type != T_STRING) { SwigType_push($2.val,$3); SwigType_add_reference($2.val); @@ -6700,6 +6761,7 @@ valexpr : exprsimple } | LPAREN expr pointer LAND RPAREN expr %prec CAST { $$ = $6; + $$.unary_arg_type = 0; if ($6.type != T_STRING) { SwigType_push($2.val,$3); SwigType_add_rvalue_reference($2.val); @@ -6710,6 +6772,11 @@ valexpr : exprsimple $$ = $2; $$.val = NewStringf("&%s", $2.val); $$.rawval = 0; + /* Record the type code for expr so we can properly handle + * cases such as (6)&7 which get parsed using this rule then + * the rule for a C-style cast. + */ + $$.unary_arg_type = $2.type; switch ($$.type) { case T_CHAR: $$.type = T_STRING; @@ -6725,6 +6792,11 @@ valexpr : exprsimple $$ = $2; $$.val = NewStringf("*%s", $2.val); $$.rawval = 0; + /* Record the type code for expr so we can properly handle + * cases such as (6)*7 which get parsed using this rule then + * the rule for a C-style cast. + */ + $$.unary_arg_type = $2.type; switch ($$.type) { case T_STRING: $$.type = T_CHAR; @@ -6844,6 +6916,7 @@ exprcompound : expr PLUS expr { * better than it deducing the wrong type). */ $$.type = T_USER; + $$.unary_arg_type = 0; } | expr QUESTIONMARK expr COLON expr %prec QUESTIONMARK { $$.val = NewStringf("%s?%s:%s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3), COMPOUND_EXPR_VAL($5)); @@ -6854,10 +6927,20 @@ exprcompound : expr PLUS expr { | MINUS expr %prec UMINUS { $$.val = NewStringf("-%s",$2.val); $$.type = promote_type($2.type); + /* Record the type code for expr so we can properly handle + * cases such as (6)-7 which get parsed using this rule then + * the rule for a C-style cast. + */ + $$.unary_arg_type = $2.type; } | PLUS expr %prec UMINUS { $$.val = NewStringf("+%s",$2.val); $$.type = promote_type($2.type); + /* Record the type code for expr so we can properly handle + * cases such as (6)+7 which get parsed using this rule then + * the rule for a C-style cast. + */ + $$.unary_arg_type = $2.type; } | NOT expr { $$.val = NewStringf("~%s",$2.val); @@ -6878,7 +6961,17 @@ exprcompound : expr PLUS expr { } $$.val = NewStringf("%s%s",qty,scanner_ccode); Clear(scanner_ccode); + /* Try to deduce the type - this could be a C++ "constructor + * cast" such as `double(4)` or a function call such as + * `some_func()`. In the latter case we get T_USER, but that + * is wrong so we map it to T_UNKNOWN until we can actually + * deduce the return type of a function call (which is + * complicated because the return type can vary between + * overloaded forms). + */ $$.type = SwigType_type(qty); + if ($$.type == T_USER) $$.type = T_UNKNOWN; + $$.unary_arg_type = 0; Delete(qty); } ; diff --git a/Source/CParse/templ.c b/Source/CParse/templ.c index 79fe77e9934..35ac85c50ba 100644 --- a/Source/CParse/templ.c +++ b/Source/CParse/templ.c @@ -269,7 +269,7 @@ static void cparse_template_expand(Node *templnode, Node *n, String *tname, Stri Append(patchlist, uname); } if (!(Getattr(n, "templatetype"))) { - // Copied from handling "constructor" .. not sure if all this is needed + /* Copied from handling "constructor" .. not sure if all this is needed */ String *symname; String *stripped_name = SwigType_templateprefix(name); if (Strstr(tname, stripped_name)) { @@ -494,8 +494,9 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab /* Printf(stdout,"partial '%s' '%s' ---> '%s'\n", tptype, ptype, partial_type); */ if (partial_name && strchr(Char(partial_name), '$') == Char(partial_name)) { int index = atoi(Char(partial_name) + 1) - 1; + Parm *parm; assert(index >= 0); - Parm *parm = ParmList_nth_parm(templateparms, index); + parm = ParmList_nth_parm(templateparms, index); assert(parm); if (parm) { Setattr(parm, "type", partial_type); @@ -578,8 +579,9 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab sz = Len(typelist); for (i = 0; i < sz; i++) { SwigType *s = Getitem(typelist, i); + Node *tynode; + String *tyname; - assert(!SwigType_isvariadic(s)); /* All parameters should have already been expanded, this is for function that contain variadic parameters only, such as f(v.p.V) */ SwigType_variadic_replace(s, unexpanded_variadic_parm, expanded_variadic_parms); /* @@ -588,8 +590,8 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab We will not replace template args if a type/class exists with the same name which is not a template. */ - Node *tynode = Swig_symbol_clookup(s, 0); - String *tyname = tynode ? Getattr(tynode, "sym:name") : 0; + tynode = Swig_symbol_clookup(s, 0); + tyname = tynode ? Getattr(tynode, "sym:name") : 0; /* Printf(stdout, " replacing %s with %s to %s or %s to %s\n", s, name, dvalue, tbase, name_with_templateargs); Printf(stdout, " %d %s to %s\n", tp == unexpanded_variadic_parm, name, ParmList_str_defaultargs(expanded_variadic_parms)); @@ -625,7 +627,6 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab sz = Len(typelist); for (i = 0; i < sz; i++) { String *s = Getitem(typelist, i); - assert(!SwigType_isvariadic(s)); /* All parameters should have already been expanded, this is for function that contain variadic parameters only, such as f(v.p.V) */ SwigType_variadic_replace(s, unexpanded_variadic_parm, expanded_variadic_parms); SwigType_typename_replace(s, tbase, name_with_templateargs); } diff --git a/Source/DOH/hash.c b/Source/DOH/hash.c index b9d501e3c42..1a29b350122 100644 --- a/Source/DOH/hash.c +++ b/Source/DOH/hash.c @@ -130,6 +130,7 @@ static void DelHash(DOH *ho) { * Hash_clear() * * Clear all of the entries in the hash table. + * File and line numbering info left unmodified. * ----------------------------------------------------------------------------- */ static void Hash_clear(DOH *ho) { diff --git a/Source/DOH/list.c b/Source/DOH/list.c index cc619022d87..f2282fe794b 100644 --- a/Source/DOH/list.c +++ b/Source/DOH/list.c @@ -73,6 +73,7 @@ static void DelList(DOH *lo) { * List_clear() * * Remove all of the list entries, but keep the list object intact. + * File and line numbering info left unmodified. * ----------------------------------------------------------------------------- */ static void List_clear(DOH *lo) { diff --git a/Source/DOH/memory.c b/Source/DOH/memory.c index f8081d3aeef..8b372a678ec 100644 --- a/Source/DOH/memory.c +++ b/Source/DOH/memory.c @@ -258,13 +258,13 @@ static void allocation_failed(size_t n, size_t size) { /* Report and exit as directly as possible to try to avoid further issues due * to lack of memory. */ if (n == 1) { -#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 19901L +#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 199901L fprintf(stderr, "Failed to allocate %zu bytes\n", size); #else fprintf(stderr, "Failed to allocate %lu bytes\n", (unsigned long)size); #endif } else { -#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 19901L +#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 199901L fprintf(stderr, "Failed to allocate %zu*%zu bytes\n", n, size); #else fprintf(stderr, "Failed to allocate %lu*%lu bytes\n", (unsigned long)n, (unsigned long)size); diff --git a/Source/DOH/string.c b/Source/DOH/string.c index c86cab0be58..cdebc3b3820 100644 --- a/Source/DOH/string.c +++ b/Source/DOH/string.c @@ -256,7 +256,9 @@ static void DohString_append(DOH *so, const DOHString_or_char *str) { /* ----------------------------------------------------------------------------- - * String_clear() - Clear a string + * String_clear() - Clear string contents + * + * File and line numbering info left unmodified. * ----------------------------------------------------------------------------- */ static void String_clear(DOH *so) { @@ -265,7 +267,6 @@ static void String_clear(DOH *so) { s->len = 0; *(s->str) = 0; s->sp = 0; - s->line = 1; } /* ----------------------------------------------------------------------------- @@ -1162,7 +1163,7 @@ DOHString *DohNewString(const DOHString_or_char *so) { str = (String *) DohMalloc(sizeof(String)); str->hashkey = hashkey; str->sp = 0; - str->line = 1; + str->line = 0; str->file = 0; max = INIT_MAXSIZE; if (s) { @@ -1192,7 +1193,7 @@ DOHString *DohNewStringEmpty(void) { String *str = (String *) DohMalloc(sizeof(String)); str->hashkey = 0; str->sp = 0; - str->line = 1; + str->line = 0; str->file = 0; str->str = (char *) DohMalloc(max); str->maxsize = max; @@ -1218,7 +1219,7 @@ DOHString *DohNewStringWithSize(const DOHString_or_char *so, int len) { str = (String *) DohMalloc(sizeof(String)); str->hashkey = -1; str->sp = 0; - str->line = 1; + str->line = 0; str->file = 0; max = INIT_MAXSIZE; if (s) { diff --git a/Source/Doxygen/pydoc.cxx b/Source/Doxygen/pydoc.cxx index c43368e33d8..03986a49c9a 100644 --- a/Source/Doxygen/pydoc.cxx +++ b/Source/Doxygen/pydoc.cxx @@ -400,7 +400,7 @@ static std::string getPyDocType(Node *n, const_String_or_char_ptr lname = "") { String *s = Swig_typemap_lookup("doctype", n, lname, 0); if (!s) { if (String *t = Getattr(n, "type")) - s = SwigType_str(t, ""); + s = SwigType_str(t, NULL); } if (!s) diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h index 169dfe05d23..6ffec1b64ff 100644 --- a/Source/Include/swigwarn.h +++ b/Source/Include/swigwarn.h @@ -70,19 +70,19 @@ #define WARN_PARSE_CLASS_KEYWORD 301 #define WARN_PARSE_REDEFINED 302 #define WARN_PARSE_EXTEND_UNDEF 303 -/* Unused since 4.2.0: #define WARN_PARSE_UNSUPPORTED_VALUE 304 */ +#define WARN_PARSE_UNSUPPORTED_VALUE 304 #define WARN_PARSE_BAD_VALUE 305 -#define WARN_PARSE_PRIVATE 306 +/* Unused since 1.3.32: #define WARN_PARSE_PRIVATE 306 */ /* Unused since 4.2.0: #define WARN_PARSE_BAD_DEFAULT 307 */ #define WARN_PARSE_NAMESPACE_ALIAS 308 #define WARN_PARSE_PRIVATE_INHERIT 309 -#define WARN_PARSE_TEMPLATE_REPEAT 310 -#define WARN_PARSE_TEMPLATE_PARTIAL 311 +/* Unused since 1.3.18: #define WARN_PARSE_TEMPLATE_REPEAT 310 */ +/* Unused since 1.3.18: #define WARN_PARSE_TEMPLATE_PARTIAL 311 */ #define WARN_PARSE_UNNAMED_NESTED_CLASS 312 #define WARN_PARSE_UNDEFINED_EXTERN 313 #define WARN_PARSE_KEYWORD 314 #define WARN_PARSE_USING_UNDEF 315 -#define WARN_PARSE_MODULE_REPEAT 316 +/* Unused since 1.3.18: #define WARN_PARSE_MODULE_REPEAT 316 */ #define WARN_PARSE_TEMPLATE_SP_UNDEF 317 #define WARN_PARSE_TEMPLATE_AMBIG 318 #define WARN_PARSE_NO_ACCESS 319 @@ -98,9 +98,9 @@ #define WARN_PARSE_USING_CONSTRUCTOR 329 #define WARN_CPP11_LAMBDA 340 -#define WARN_CPP11_ALIAS_DECLARATION 341 /* redundant now */ -#define WARN_CPP11_ALIAS_TEMPLATE 342 /* redundant now */ -#define WARN_CPP11_VARIADIC_TEMPLATE 343 /* redundant now */ +/* Unused since 3.0.11: #define WARN_CPP11_ALIAS_DECLARATION 341 */ +/* Unused since 3.0.11: #define WARN_CPP11_ALIAS_TEMPLATE 342 */ +/* Unused since 4.2.0: #define WARN_CPP11_VARIADIC_TEMPLATE 343 */ #define WARN_CPP11_DECLTYPE 344 #define WARN_CPP14_AUTO 345 #define WARN_CPP11_AUTO 346 @@ -164,9 +164,9 @@ #define WARN_TYPE_REDEFINED 404 #define WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405 -#define WARN_TYPEMAP_SOURCETARGET 450 /* No longer issued */ +/* Unused since 4.1.0: #define WARN_TYPEMAP_SOURCETARGET 450 */ #define WARN_TYPEMAP_CHARLEAK 451 -#define WARN_TYPEMAP_SWIGTYPE 452 /* No longer issued */ +/* Unused since 1.3.32: #define WARN_TYPEMAP_SWIGTYPE 452 */ #define WARN_TYPEMAP_APPLY_UNDEF 453 #define WARN_TYPEMAP_SWIGTYPELEAK 454 #define WARN_TYPEMAP_WCHARLEAK 455 @@ -204,7 +204,7 @@ #define WARN_LANG_NATIVE_UNIMPL 507 #define WARN_LANG_DEREF_SHADOW 508 #define WARN_LANG_OVERLOAD_SHADOW 509 -#define WARN_LANG_FRIEND_IGNORE 510 +#define WARN_LANG_FRIEND_IGNORE 510 /* No longer issued */ #define WARN_LANG_OVERLOAD_KEYWORD 511 #define WARN_LANG_OVERLOAD_CONST 512 #define WARN_LANG_CLASS_UNNAMED 513 @@ -320,7 +320,7 @@ #define WARN_PHP_MULTIPLE_INHERITANCE 870 #define WARN_PHP_UNKNOWN_PRAGMA 871 -#define WARN_PHP_PUBLIC_BASE 872 +/* Unused since 4.1.0: define WARN_PHP_PUBLIC_BASE 872 */ /* please leave 870-889 free for PHP */ diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index 45a396f5a88..b0103f3c163 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -290,7 +290,8 @@ class CSHARP:public Language { virtual int top(Node *n) { // Get any options set in the module directive - Node *optionsnode = Getattr(Getattr(n, "module"), "options"); + Node *module = Getattr(n, "module"); + Node *optionsnode = Getattr(module, "options"); if (optionsnode) { if (Getattr(optionsnode, "imclassname")) @@ -374,9 +375,9 @@ class CSHARP:public Language { } // module class and intermediary classes are always created - if (!addSymbol(imclass_name, n)) + if (!addSymbol(imclass_name, module)) return SWIG_ERROR; - if (!addSymbol(module_class_name, n)) + if (!addSymbol(module_class_name, module)) return SWIG_ERROR; imclass_class_code = NewString(""); @@ -1176,21 +1177,6 @@ class CSHARP:public Language { return SWIG_NOWRAP; String *nspace = Getattr(n, "sym:nspace"); // NSpace/getNSpace() only works during Language::enumDeclaration call - if (proxy_flag && !is_wrapping_class()) { - // Global enums / enums in a namespace - assert(!full_imclass_name); - - if (!nspace) { - full_imclass_name = NewStringf("%s", imclass_name); - } else { - if (namespce) { - full_imclass_name = NewStringf("%s.%s", namespce, imclass_name); - } else { - full_imclass_name = NewStringf("%s", imclass_name); - } - } - } - enum_code = NewString(""); String *symname = Getattr(n, "sym:name"); String *constants_code = (proxy_flag && is_wrapping_class())? proxy_class_constants_code : module_class_constants_code; @@ -1243,9 +1229,29 @@ class CSHARP:public Language { Printf(constants_code, " // %s \n", symname); } + if (proxy_flag && !is_wrapping_class()) { + // Global enums / enums in a namespace + assert(!full_imclass_name); + + if (!nspace) { + full_imclass_name = NewStringf("%s", imclass_name); + } else { + if (namespce) { + full_imclass_name = NewStringf("%s.%s", namespce, imclass_name); + } else { + full_imclass_name = NewStringf("%s", imclass_name); + } + } + } + // Emit each enum item Language::enumDeclaration(n); + if (proxy_flag && !is_wrapping_class()) { + Delete(full_imclass_name); + full_imclass_name = 0; + } + if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) { // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper C# enum // Finish the enum declaration @@ -1297,11 +1303,6 @@ class CSHARP:public Language { Delete(enum_code); enum_code = NULL; - - if (proxy_flag && !is_wrapping_class()) { - Delete(full_imclass_name); - full_imclass_name = 0; - } } return SWIG_OK; } @@ -1729,6 +1730,7 @@ class CSHARP:public Language { Node *base = it.item; SwigType *c_baseclassname = Getattr(base, "name"); String *interface_name = Getattr(base, "interface:name"); + SwigType *bsmart = Getattr(base, "smart"); if (Len(interface_list)) Append(interface_list, ", "); Append(interface_list, interface_name); @@ -1747,7 +1749,7 @@ class CSHARP:public Language { Replaceall(cptr_method_name, "$interfacename", interface_name); String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), cptr_method_name); - upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname); + upcastsCode(smart, bsmart, upcast_method_name, c_classname, c_baseclassname); Delete(upcast_method_name); Delete(cptr_method_name); @@ -1761,7 +1763,7 @@ class CSHARP:public Language { * Add code for C++ casting to base class * ----------------------------------------------------------------------------- */ - void upcastsCode(SwigType *smart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) { + void upcastsCode(SwigType *smart, SwigType *bsmart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) { String *wname = Swig_name_wrapper(upcast_method_name); Printv(imclass_cppcasts_code, "\n [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL); @@ -1770,18 +1772,18 @@ class CSHARP:public Language { Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name); if (smart) { - SwigType *bsmart = Swig_smartptr_upcast(smart, c_classname, c_baseclassname); - String *smartnamestr = SwigType_namestr(smart); - String *bsmartnamestr = SwigType_namestr(bsmart); + if (bsmart) { + String *smartnamestr = SwigType_namestr(smart); + String *bsmartnamestr = SwigType_namestr(bsmart); - Printv(upcasts_code, - "SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", wname, "(", smartnamestr, " *jarg1) {\n", - " return jarg1 ? new ", bsmartnamestr, "(*jarg1) : 0;\n" - "}\n", "\n", NIL); + Printv(upcasts_code, + "SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", wname, "(", smartnamestr, " *jarg1) {\n", + " return jarg1 ? new ", bsmartnamestr, "(*jarg1) : 0;\n" + "}\n", "\n", NIL); - Delete(bsmartnamestr); - Delete(smartnamestr); - Delete(bsmart); + Delete(bsmartnamestr); + Delete(smartnamestr); + } } else { String *classname = SwigType_namestr(c_classname); String *baseclassname = SwigType_namestr(c_baseclassname); @@ -1811,7 +1813,8 @@ class CSHARP:public Language { SwigType *typemap_lookup_type = Getattr(n, "classtypeobj"); bool feature_director = Swig_directorclass(n) ? true : false; bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested"); - SwigType *smart = Swig_cparse_smartptr(n); + SwigType *smart = Getattr(n, "smart"); + SwigType *bsmart = 0; // Inheritance from pure C# classes Node *attributes = NewHash(); @@ -1833,6 +1836,7 @@ class CSHARP:public Language { if (name) { c_baseclassname = baseclassname; baseclass = name; + bsmart = Getattr(base.item, "smart"); } } else { /* Warn about multiple inheritance for additional base class(es) */ @@ -2070,11 +2074,9 @@ class CSHARP:public Language { if (derived) { String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast"); - upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname); + upcastsCode(smart, bsmart, upcast_method_name, c_classname, c_baseclassname); Delete(upcast_method_name); } - - Delete(smart); } /* ---------------------------------------------------------------------- @@ -3809,7 +3811,8 @@ class CSHARP:public Language { String *qualified_classname = Copy(sym_name); String *nspace = getNSpace(); String *dirClassName = directorClassName(n); - String *smartptr = Getattr(n, "feature:smartptr"); + SwigType *smart = Getattr(n, "smart"); + String *smartptr = smart ? SwigType_namestr(smart) : 0; if (!GetFlag(n, "feature:flatnested")) { for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) { diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx index 6fed3af4b71..b86f14a430f 100644 --- a/Source/Modules/d.cxx +++ b/Source/Modules/d.cxx @@ -347,7 +347,8 @@ class D : public Language { * --------------------------------------------------------------------------- */ virtual int top(Node *n) { // Get any options set in the module directive - Node *optionsnode = Getattr(Getattr(n, "module"), "options"); + Node *module = Getattr(n, "module"); + Node *optionsnode = Getattr(module, "options"); if (optionsnode) { if (Getattr(optionsnode, "imdmodulename")) { @@ -3183,6 +3184,7 @@ class D : public Language { String *c_baseclassname = NULL; Node *basenode = NULL; String *baseclass = NULL; + SwigType *bsmart = 0; // Inheritance from pure D classes. Node *attributes = NewHash(); @@ -3206,6 +3208,7 @@ class D : public Language { if (name) { c_baseclassname = baseclassname; baseclass = name; + bsmart = Getattr(base.item, "smart"); } } else { /* Warn about multiple inheritance for additional base class(es) */ @@ -3244,7 +3247,7 @@ class D : public Language { // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy) if (derived) { - writeClassUpcast(n, proxy_class_name, c_classname, c_baseclassname); + writeClassUpcast(n, bsmart, proxy_class_name, c_classname, c_baseclassname); } /* @@ -3405,9 +3408,9 @@ class D : public Language { /* --------------------------------------------------------------------------- * D::writeClassUpcast() * --------------------------------------------------------------------------- */ - void writeClassUpcast(Node *n, const String* d_class_name, SwigType* c_classname, SwigType* c_baseclassname) { + void writeClassUpcast(Node *n, SwigType *bsmart, const String *d_class_name, SwigType *c_classname, SwigType *c_baseclassname) { - SwigType *smart = Swig_cparse_smartptr(n); + SwigType *smart = Getattr(n, "smart"); String *upcast_name = Swig_name_member(getNSpace(), d_class_name, (smart != 0 ? "SmartPtrUpcast" : "Upcast")); String *upcast_wrapper_name = Swig_name_wrapper(upcast_name); @@ -3417,20 +3420,20 @@ class D : public Language { String *baseclassname = SwigType_namestr(c_baseclassname); if (smart) { - SwigType *bsmart = Swig_smartptr_upcast(smart, c_classname, c_baseclassname); - String *smartnamestr = SwigType_namestr(smart); - String *bsmartnamestr = SwigType_namestr(bsmart); - - Printv(upcasts_code, - "SWIGEXPORT ", bsmartnamestr, " * ", upcast_wrapper_name, - "(", smartnamestr, " *objectRef) {\n", - " return objectRef ? new ", bsmartnamestr, "(*objectRef) : 0;\n" - "}\n", - "\n", NIL); - - Delete(bsmartnamestr); - Delete(smartnamestr); - Delete(bsmart); + if (bsmart) { + String *smartnamestr = SwigType_namestr(smart); + String *bsmartnamestr = SwigType_namestr(bsmart); + + Printv(upcasts_code, + "SWIGEXPORT ", bsmartnamestr, " * ", upcast_wrapper_name, + "(", smartnamestr, " *objectRef) {\n", + " return objectRef ? new ", bsmartnamestr, "(*objectRef) : 0;\n" + "}\n", + "\n", NIL); + + Delete(bsmartnamestr); + Delete(smartnamestr); + } } else { Printv(upcasts_code, "SWIGEXPORT ", baseclassname, " * ", upcast_wrapper_name, @@ -3447,7 +3450,6 @@ class D : public Language { Delete(classname); Delete(upcast_wrapper_name); Delete(upcast_name); - Delete(smart); } /* --------------------------------------------------------------------------- diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index 203485831ac..c115cae45a7 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -332,7 +332,8 @@ class JAVA:public Language { virtual int top(Node *n) { // Get any options set in the module directive - Node *optionsnode = Getattr(Getattr(n, "module"), "options"); + Node *module = Getattr(n, "module"); + Node *optionsnode = Getattr(module, "options"); if (optionsnode) { if (Getattr(optionsnode, "jniclassname")) @@ -417,9 +418,9 @@ class JAVA:public Language { constants_interface_name = NewStringf("%sConstants", module_class_name); // module class and intermediary classes are always created - if (!addSymbol(imclass_name, n)) + if (!addSymbol(imclass_name, module)) return SWIG_ERROR; - if (!addSymbol(module_class_name, n)) + if (!addSymbol(module_class_name, module)) return SWIG_ERROR; imclass_class_code = NewString(""); @@ -1245,11 +1246,6 @@ class JAVA:public Language { return SWIG_NOWRAP; String *nspace = Getattr(n, "sym:nspace"); // NSpace/getNSpace() only works during Language::enumDeclaration call - if (proxy_flag && !is_wrapping_class()) { - // Global enums / enums in a namespace - assert(!full_imclass_name); - constructIntermediateClassName(n); - } enum_code = NewString(""); String *symname = Getattr(n, "sym:name"); @@ -1300,9 +1296,20 @@ class JAVA:public Language { } } + if (proxy_flag && !is_wrapping_class()) { + // Global enums / enums in a namespace + assert(!full_imclass_name); + constructIntermediateClassName(n); + } + // Emit each enum item Language::enumDeclaration(n); + if (proxy_flag && !is_wrapping_class()) { + Delete(full_imclass_name); + full_imclass_name = 0; + } + if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) { // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper Java enum // Finish the enum declaration @@ -1369,11 +1376,6 @@ class JAVA:public Language { Delete(enum_code); enum_code = NULL; - - if (proxy_flag && !is_wrapping_class()) { - Delete(full_imclass_name); - full_imclass_name = 0; - } } return SWIG_OK; } @@ -1808,6 +1810,7 @@ class JAVA:public Language { Node *base = it.item; SwigType *c_baseclassname = Getattr(base, "name"); String *interface_name = Getattr(base, "interface:name"); + SwigType *bsmart = Getattr(base, "smart"); if (Len(interface_list)) Append(interface_list, ", "); Append(interface_list, interface_name); @@ -1826,7 +1829,7 @@ class JAVA:public Language { Replaceall(cptr_method_name, "$interfacename", interface_name); String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), cptr_method_name); - upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname); + upcastsCode(smart, bsmart, upcast_method_name, c_classname, c_baseclassname); Delete(upcast_method_name); Delete(cptr_method_name); @@ -1840,31 +1843,31 @@ class JAVA:public Language { * Add code for C++ casting to base class * ----------------------------------------------------------------------------- */ - void upcastsCode(SwigType *smart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) { + void upcastsCode(SwigType *smart, SwigType *bsmart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) { String *jniname = makeValidJniName(upcast_method_name); String *wname = Swig_name_wrapper(jniname); Printf(imclass_cppcasts_code, " public final static native long %s(long jarg1);\n", upcast_method_name); if (smart) { - SwigType *bsmart = Swig_smartptr_upcast(smart, c_classname, c_baseclassname); - String *smartnamestr = SwigType_namestr(smart); - String *bsmartnamestr = SwigType_namestr(bsmart); - - Printv(upcasts_code, - "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n", - " jlong baseptr = 0;\n" - " ", smartnamestr, " *argp1;\n" - " (void)jenv;\n" - " (void)jcls;\n" - " argp1 = *(", smartnamestr, " **)&jarg1;\n" - " *(", bsmartnamestr, " **)&baseptr = argp1 ? new ", bsmartnamestr, "(*argp1) : 0;\n" - " return baseptr;\n" - "}\n", "\n", NIL); - - Delete(bsmartnamestr); - Delete(smartnamestr); - Delete(bsmart); + if (bsmart) { + String *smartnamestr = SwigType_namestr(smart); + String *bsmartnamestr = SwigType_namestr(bsmart); + + Printv(upcasts_code, + "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n", + " jlong baseptr = 0;\n" + " ", smartnamestr, " *argp1;\n" + " (void)jenv;\n" + " (void)jcls;\n" + " argp1 = *(", smartnamestr, " **)&jarg1;\n" + " *(", bsmartnamestr, " **)&baseptr = argp1 ? new ", bsmartnamestr, "(*argp1) : 0;\n" + " return baseptr;\n" + "}\n", "\n", NIL); + + Delete(bsmartnamestr); + Delete(smartnamestr); + } } else { String *classname = SwigType_namestr(c_classname); String *baseclassname = SwigType_namestr(c_baseclassname); @@ -1899,7 +1902,8 @@ class JAVA:public Language { SwigType *typemap_lookup_type = Getattr(n, "classtypeobj"); bool feature_director = Swig_directorclass(n) ? true : false; bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested"); - SwigType *smart = Swig_cparse_smartptr(n); + SwigType *smart = Getattr(n, "smart"); + SwigType *bsmart = 0; // Inheritance from pure Java classes Node *attributes = NewHash(); @@ -1921,6 +1925,7 @@ class JAVA:public Language { if (name) { c_baseclassname = baseclassname; baseclass = name; + bsmart = Getattr(base.item, "smart"); } } else { /* Warn about multiple inheritance for additional base class(es) */ @@ -2068,11 +2073,9 @@ class JAVA:public Language { if (derived) { String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast"); - upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname); + upcastsCode(smart, bsmart, upcast_method_name, c_classname, c_baseclassname); Delete(upcast_method_name); } - - Delete(smart); } /* ---------------------------------------------------------------------- @@ -3790,7 +3793,8 @@ class JAVA:public Language { String *norm_name = SwigType_namestr(Getattr(n, "name")); String *swig_director_connect = Swig_name_member(getNSpace(), getClassPrefix(), "director_connect"); String *swig_director_connect_jni = makeValidJniName(swig_director_connect); - String *smartptr = Getattr(n, "feature:smartptr"); + SwigType *smart = Getattr(n, "smart"); + String *smartptr = smart ? SwigType_namestr(smart) : 0; String *dirClassName = directorClassName(n); Wrapper *code_wrap; @@ -3836,7 +3840,7 @@ class JAVA:public Language { "SWIGEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jtake_or_release) {\n", jnipackage, jni_imclass_name, changeown_jnimethod_name); - if (Len(smartptr)) { + if (smartptr) { Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", smartptr, smartptr); Printf(code_wrap->code, " // Keep a local instance of the smart pointer around while we are using the raw pointer\n"); Printf(code_wrap->code, " // Avoids using smart pointer specific API.\n"); diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 3078a2b033b..8fe394f92eb 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1425,7 +1425,7 @@ String *JSEmitter::emitInputTypemap(Node *n, Parm *p, Wrapper *wrapper, String * String *JSEmitter::emitCheckTypemap(Node *, Parm *p, Wrapper *wrapper, String *arg) { String *tm = Getattr(p, "tmap:check"); - if (tm != nullptr) { + if (tm != NULL) { Replaceall(tm, "$input", arg); Printf(wrapper->code, "%s\n", tm); } diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index fbe99347053..92f0cebd31b 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -1166,7 +1166,20 @@ int Language::globalfunctionHandler(Node *n) { String *extendname = Getattr(n, "extendname"); String *call = Swig_cfunction_call(extendname ? extendname : name, parms); String *cres = Swig_cresult(type, Swig_cresult_name(), call); - Setattr(n, "wrap:action", cres); + String *friendusing = Getattr(n, "friendusing"); + if (friendusing) { + // Add a using directive to avoid having to possibly fully qualify the call to the friend function. + // Unconventional for SWIG generation, but the alternative is to implement Argument Dependent Lookup + // as friend functions are quirky and not visible, except for ADL. An ADL implementation would be needed + // in order to work out when the friend function is visible or not, in order to determine whether to + // rely on ADL (with no qualification) or to fully qualify the call to the friend function made + // visible via a matching declaration at namespace scope. + String *action = NewStringf("%s\n%s", friendusing, cres); + Setattr(n, "wrap:action", action); + Delete(action); + } else { + Setattr(n, "wrap:action", cres); + } Delete(cres); Delete(call); functionWrapper(n); @@ -1816,6 +1829,8 @@ int Language::typedefHandler(Node *n) { */ SwigType *name = Getattr(n, "name"); SwigType *decl = Getattr(n, "decl"); + Setfile(name, Getfile(n)); + Setline(name, Getline(n)); if (!SwigType_ispointer(decl) && !SwigType_isreference(decl)) { SwigType *pname = Copy(name); SwigType_add_pointer(pname); @@ -3003,8 +3018,8 @@ void Language::main(int argc, char *argv[]) { * ----------------------------------------------------------------------------- */ int Language::addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope) { - //Printf( stdout, "addSymbol: %s %s\n", s, scope ); - Hash *symbols = Getattr(symtabs, scope ? scope : ""); + //Printf( stdout, "addSymbol: %s %s %s:%d\n", s, scope, Getfile(n), Getline(n) ); + Hash *symbols = symbolScopeLookup(scope); if (!symbols) { symbols = symbolAddScope(scope); } else { @@ -3051,15 +3066,15 @@ int Language::addInterfaceSymbol(const String *interface_name, Node *n, const_St * Language::symbolAddScope() * * Creates a scope (symbols Hash) for given name. This method is auxiliary, - * you don't have to call it - addSymbols will lazily create scopes automatically. + * you don't have to call it - addSymbol will lazily create scopes automatically. * If scope with given name already exists, then do nothing. * Returns newly created (or already existing) scope. * ----------------------------------------------------------------------------- */ -Hash* Language::symbolAddScope(const_String_or_char_ptr scope) { +Hash *Language::symbolAddScope(const_String_or_char_ptr scope/*, Node *n*/) { Hash *symbols = symbolScopeLookup(scope); - if(!symbols) { + if (!symbols) { // The order in which the following code is executed is important. In the Language - // constructor addScope("") is called to create a top level scope. + // constructor symbolAddScope("") is called to create a top level scope. // Thus we must first add a symbols hash to symtab and only then add pseudo // symbols to the top-level scope. @@ -3071,8 +3086,22 @@ Hash* Language::symbolAddScope(const_String_or_char_ptr scope) { // Alternatively the target language must add it in before attempting to add symbols into the scope. const_String_or_char_ptr top_scope = ""; Hash *topscope_symbols = Getattr(symtabs, top_scope); - Hash *pseudo_symbol = NewHash(); - Setattr(pseudo_symbol, "sym:scope", "1"); + + // TODO: + // Stop using pseudo scopes, the symbol Node containing the new scope should be passed into this function. + // This will require explicit calls to symbolScopeLookup() in each language and removing the call from addSymbol(). + // addSymbol() should then instead assert that the scope exists. + // All this just to fix up the file/line numbering of the scopes for error reporting. + //Node *symbol = n; + Node *symbol = Getattr(topscope_symbols, scope); + + Hash *pseudo_symbol = 0; + if (symbol) { + pseudo_symbol = symbol; + } else { + pseudo_symbol = NewHash(); + Setattr(pseudo_symbol, "sym:scope", "1"); + } Setattr(topscope_symbols, scope, pseudo_symbol); } return symbols; @@ -3084,7 +3113,7 @@ Hash* Language::symbolAddScope(const_String_or_char_ptr scope) { * Lookup and returns a symtable (hash) representing given scope. Hash contains * all symbols in this scope. * ----------------------------------------------------------------------------- */ -Hash* Language::symbolScopeLookup( const_String_or_char_ptr scope ) { +Hash *Language::symbolScopeLookup(const_String_or_char_ptr scope) { Hash *symbols = Getattr(symtabs, scope ? scope : ""); return symbols; } @@ -3103,7 +3132,7 @@ Hash* Language::symbolScopeLookup( const_String_or_char_ptr scope ) { * There is no difference from symbolLookup() method except for signature * and return type. * ----------------------------------------------------------------------------- */ -Hash* Language::symbolScopePseudoSymbolLookup( const_String_or_char_ptr scope ) +Hash *Language::symbolScopePseudoSymbolLookup(const_String_or_char_ptr scope) { /* Getting top scope */ const_String_or_char_ptr top_scope = ""; @@ -3130,6 +3159,7 @@ void Language::dumpSymbols() { while (it.key) { String *symname = it.key; Printf(stdout, " %s\n", symname); + //Printf(stdout, " %s (%s:%d)\n", symname, Getfile(it.item), Getline(it.item)); it = Next(it); } } diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx index 8a44921ad61..76b4f9d28d3 100644 --- a/Source/Modules/main.cxx +++ b/Source/Modules/main.cxx @@ -379,6 +379,15 @@ static void SWIG_dump_runtime() { Swig_banner(runtime); Printf(runtime, "\n"); + s = Swig_include_sys("swigcompat.swg"); + if (!s) { + Printf(stderr, "*** Unable to open 'swigcompat.swg'\n"); + Delete(runtime); + Exit(EXIT_FAILURE); + } + Printf(runtime, "%s", s); + Delete(s); + s = Swig_include_sys("swiglabels.swg"); if (!s) { Printf(stderr, "*** Unable to open 'swiglabels.swg'\n"); diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx index 121e22af479..82a8f4b4227 100644 --- a/Source/Modules/ocaml.cxx +++ b/Source/Modules/ocaml.cxx @@ -513,8 +513,8 @@ class OCAML:public Language { Setattr(seen_constructors, mangled_name, "true"); } // writing the function wrapper function - Printv(f->def, "SWIGEXT CAML_VALUE ", wname, " (", NIL); - Printv(f->def, "CAML_VALUE args", NIL); + Printv(f->def, "SWIGEXT value ", wname, " (", NIL); + Printv(f->def, "value args", NIL); Printv(f->def, ")\n{", NIL); /* Define the scheme name in C. This define is used by several @@ -523,7 +523,7 @@ class OCAML:public Language { // adds local variables Wrapper_add_local(f, "args", "CAMLparam1(args)"); - Wrapper_add_local(f, "ret", "SWIG_CAMLlocal2(swig_result,rv)"); + Wrapper_add_local(f, "ret", "CAMLlocal2(swig_result,rv)"); d = SwigType_typedef_qualified(d); emit_parameter_variables(l, f); @@ -708,7 +708,7 @@ class OCAML:public Language { "free(argv);\n" "CAMLreturn(%s(args));\n", &maxargs); - Wrapper_add_local(df, "argv", "CAML_VALUE *argv"); + Wrapper_add_local(df, "argv", "value *argv"); /* Undifferentiate name .. this is the dispatch function */ wname = Swig_name_wrapper(iname); @@ -717,9 +717,9 @@ class OCAML:public Language { Append(wname, module); Printv(df->def, - "SWIGEXT CAML_VALUE ", wname, "(CAML_VALUE args) {\n" " CAMLparam1(args);\n" " int i;\n" " int argc = caml_list_length(args);\n", NIL); + "SWIGEXT value ", wname, "(value args) {\n" " CAMLparam1(args);\n" " int i;\n" " int argc = caml_list_length(args);\n", NIL); Printv(df->code, - "argv = (CAML_VALUE *)malloc( argc * sizeof( CAML_VALUE ) );\n" + "argv = (value *)malloc( argc * sizeof( value ) );\n" "for( i = 0; i < argc; i++ ) {\n" " argv[i] = caml_list_nth(args,i);\n" "}\n", NIL); Printv(df->code, dispatch, "\nfree(argv);\n", NIL); Node *sibl = n; @@ -812,11 +812,11 @@ class OCAML:public Language { Printv(proc_name, iname, NIL); Setattr(n, "wrap:name", proc_name); - Printf(f->def, "SWIGEXT CAML_VALUE %s(CAML_VALUE args) {\n", var_name); + Printf(f->def, "SWIGEXT value %s(value args) {\n", var_name); // Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL); Wrapper_add_local(f, "args", "CAMLparam1(args)"); - Wrapper_add_local(f, "swig_result", "SWIG_CAMLlocal1(swig_result)"); + Wrapper_add_local(f, "swig_result", "CAMLlocal1(swig_result)"); Printf(f->code, "swig_result = Val_unit;\n"); int assignable = !is_immutable(n); @@ -1097,7 +1097,7 @@ class OCAML:public Language { if (sizeof_feature) { Printf(f_wrappers, - "SWIGEXT CAML_VALUE _wrap_%s_sizeof( CAML_VALUE args ) {\n" + "SWIGEXT value _wrap_%s_sizeof( value args ) {\n" " CAMLparam1(args);\n" " CAMLreturn(Val_int(sizeof(%s)));\n" "}\n", mangled_name, name_normalized); Printf(f_mlbody, "external __%s_sizeof : unit -> int = " "\"_wrap_%s_sizeof\"\n", mangled_name, mangled_name); @@ -1459,14 +1459,14 @@ class OCAML:public Language { if (is_void) Printf(w->code, "%s;\n", super_call); else - Printf(w->code, "CAMLreturn_type(%s);\n", super_call); + Printf(w->code, "CAMLreturnT(%s, %s);\n", SwigType_str(returntype, 0), super_call); Delete(super_call); } else { Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name)); } } else { - Wrapper_add_local(w, "swig_result", "SWIG_CAMLlocal2(swig_result, args)"); + Wrapper_add_local(w, "swig_result", "CAMLlocal2(swig_result, args)"); /* attach typemaps to arguments (C/C++ -> Ocaml) */ String *arglist = NewString(""); @@ -1536,7 +1536,7 @@ class OCAML:public Language { if (target) { String *director = NewStringf("director_%s", mangle); Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL); - Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL); + Wrapper_add_localv(w, source, "value", source, "= Val_unit", NIL); Printf(wrap_args, "%s = dynamic_cast(%s);\n", director, nonconst); Printf(wrap_args, "if (!%s) {\n", director); Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle); @@ -1546,7 +1546,7 @@ class OCAML:public Language { Delete(director); Printv(arglist, source, NIL); } else { - Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL); + Wrapper_add_localv(w, source, "value", source, "= Val_unit", NIL); Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle); //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n", // source, nonconst, base); @@ -1573,8 +1573,8 @@ class OCAML:public Language { /* pass the method call on to the OCaml object */ Printv(w->code, - "swig_result = caml_swig_alloc(1,C_list);\n" "SWIG_Store_field(swig_result,0,args);\n" "args = swig_result;\n" "swig_result = Val_unit;\n", 0); - Printf(w->code, "static const CAML_VALUE *swig_ocaml_func_val = NULL;\n" "if (!swig_ocaml_func_val) {\n"); + "swig_result = caml_swig_alloc(1,C_list);\n" "Store_field(swig_result,0,args);\n" "args = swig_result;\n" "swig_result = Val_unit;\n", 0); + Printf(w->code, "static const value *swig_ocaml_func_val = NULL;\n" "if (!swig_ocaml_func_val) {\n"); Printf(w->code, " swig_ocaml_func_val = caml_named_value(\"swig_runmethod\");\n }\n"); Printf(w->code, "swig_result = caml_callback3(*swig_ocaml_func_val,swig_get_self(),caml_copy_string(\"%s\"),args);\n", Getattr(n, "name")); /* exception handling */ @@ -1584,7 +1584,7 @@ class OCAML:public Language { } if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) { Printf(w->code, "if (!%s) {\n", Swig_cresult_name()); - Printf(w->code, " CAML_VALUE error = *caml_named_value(\"director_except\");\n"); + Printf(w->code, " value error = *caml_named_value(\"director_except\");\n"); Replaceall(tm, "$error", "error"); Printv(w->code, Str(tm), "\n", NIL); Printf(w->code, "}\n"); @@ -1638,9 +1638,9 @@ class OCAML:public Language { if (!(ignored_method && !pure_virtual)) { String *rettype = SwigType_str(returntype, 0); if (!SwigType_isreference(returntype)) { - Printf(w->code, "CAMLreturn_type((%s)c_result);\n", rettype); + Printf(w->code, "CAMLreturnT(%s, (%s)c_result);\n", rettype, rettype); } else { - Printf(w->code, "CAMLreturn_type((%s)*c_result);\n", rettype); + Printf(w->code, "CAMLreturnT(%s, (%s)*c_result);\n", rettype, rettype); } Delete(rettype); } @@ -1698,7 +1698,7 @@ class OCAML:public Language { Parm *p, *q; ParmList *superparms = Getattr(n, "parms"); ParmList *parms = CopyParmList(superparms); - String *type = NewString("CAML_VALUE"); + String *type = NewString("value"); p = NewParm(type, NewString("self"), n); q = Copy(p); set_nextSibling(q, superparms); @@ -1751,18 +1751,18 @@ class OCAML:public Language { Parm *p, *q; ParmList *superparms = Getattr(n, "parms"); ParmList *parms = CopyParmList(superparms); - String *type = NewString("CAML_VALUE"); + String *type = NewString("value"); p = NewParm(type, NewString("self"), n); q = Copy(p); set_nextSibling(p, parms); { Wrapper *w = NewWrapper(); - Printf(w->def, "SwigDirector_%s::SwigDirector_%s(CAML_VALUE self) : Swig::Director(self) { }", classname, classname); + Printf(w->def, "SwigDirector_%s::SwigDirector_%s(value self) : Swig::Director(self) { }", classname, classname); Wrapper_print(w, f_directors); DelWrapper(w); } - Printf(f_directors_h, " SwigDirector_%s(CAML_VALUE self);\n", classname); + Printf(f_directors_h, " SwigDirector_%s(value self);\n", classname); Delete(classname); Setattr(n, "parms", q); return Language::classDirectorDefaultConstructor(n); diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx index a16858d2a4a..a85320b92bb 100644 --- a/Source/Modules/octave.cxx +++ b/Source/Modules/octave.cxx @@ -964,13 +964,14 @@ class OCTAVE:public Language { SwigType_add_pointer(t); // Replace storing a pointer to underlying class with a smart pointer (intended for use with non-intrusive smart pointers) - SwigType *smart = Swig_cparse_smartptr(n); + SwigType *smart = Getattr(n, "smart"); String *wrap_class = NewStringf("&_wrap_class_%s", class_name); if (smart) { - SwigType_add_pointer(smart); - SwigType_remember_clientdata(smart, wrap_class); + SwigType *psmart = Copy(smart); + SwigType_add_pointer(psmart); + SwigType_remember_clientdata(psmart, wrap_class); + Delete(psmart); } - //String *wrap_class = NewStringf("&_wrap_class_%s", class_name); SwigType_remember_clientdata(t, wrap_class); int use_director = Swig_directorclass(n); @@ -1047,7 +1048,6 @@ class OCTAVE:public Language { Delete(base_class); Delete(base_class_names); - Delete(smart); Delete(t); Delete(s_members_tab); s_members_tab = 0; diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 27c937d4b85..aad3c6d4c42 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -2058,11 +2058,13 @@ class PHP : public Language { Printf(magic_set, "\nelse if (strcmp(ZSTR_VAL(arg2),\"%s\") == 0) {\n", v_name); Printf(magic_set, "ZVAL_STRING(&tempZval, \"%s_set\");\n", v_name); - Printf(magic_set, "call_user_function(EG(function_table),ZEND_THIS,&tempZval,return_value,1,&args[1]);\n}\n"); + Printf(magic_set, "call_user_function(EG(function_table),ZEND_THIS,&tempZval,return_value,1,&args[1]);\n"); + Printf(magic_set, "zval_ptr_dtor(&tempZval);\n}\n"); Printf(magic_get, "\nelse if (strcmp(ZSTR_VAL(arg2),\"%s\") == 0) {\n", v_name); Printf(magic_get, "ZVAL_STRING(&tempZval, \"%s_get\");\n", v_name); - Printf(magic_get, "call_user_function(EG(function_table),ZEND_THIS,&tempZval,return_value,0,NULL);\n}\n"); + Printf(magic_get, "call_user_function(EG(function_table),ZEND_THIS,&tempZval,return_value,0,NULL);\n"); + Printf(magic_get, "zval_ptr_dtor(&tempZval);\n}\n"); Printf(magic_isset, "\nelse if (strcmp(ZSTR_VAL(arg2),\"%s\") == 0) {\n", v_name); Printf(magic_isset, "RETVAL_TRUE;\n}\n"); diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 69e47d6d053..905a0263a2d 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -2718,6 +2718,7 @@ class PYTHON:public Language { int constructor = (!Cmp(nodeType, "constructor")); int destructor = (!Cmp(nodeType, "destructor")); String *storage = Getattr(n, "storage"); + int isfriend = Strstr(storage, "friend") != NULL; /* Only the first constructor is handled as init method. Others constructor can be emitted via %rename */ int handled_as_init = 0; @@ -3374,7 +3375,7 @@ class PYTHON:public Language { if (in_class && builtin) { /* Handle operator overloads for builtin types */ String *slot = Getattr(n, "feature:python:slot"); - if (slot) { + if (slot && !isfriend) { String *func_type = Getattr(n, "feature:python:slot:functype"); String *closure_decl = getClosure(func_type, wrapper_name, overname ? 0 : funpack); String *feature_name = NewStringf("feature:python:%s", slot); @@ -4364,12 +4365,14 @@ class PYTHON:public Language { Printf(clientdata, "&%s_clientdata", templ); SwigType_remember_mangleddata(pmname, clientdata); - SwigType *smart = Swig_cparse_smartptr(n); + SwigType *smart = Getattr(n, "smart"); if (smart) { - SwigType_add_pointer(smart); - String *smart_pmname = SwigType_manglestr(smart); + SwigType *psmart = Copy(smart); + SwigType_add_pointer(psmart); + String *smart_pmname = SwigType_manglestr(psmart); SwigType_remember_mangleddata(smart_pmname, clientdata); Delete(smart_pmname); + Delete(psmart); } String *clientdata_klass = NewString("0"); @@ -4394,7 +4397,6 @@ class PYTHON:public Language { Printv(f_init, " d = md;\n", NIL); Delete(clientdata); - Delete(smart); Delete(sname); Delete(rname); Delete(mname); @@ -4572,7 +4574,7 @@ class PYTHON:public Language { if (shadow) { /* Generate a class registration function */ // Replace storing a pointer to underlying class with a smart pointer (intended for use with non-intrusive smart pointers) - SwigType *smart = Swig_cparse_smartptr(n); + SwigType *smart = Getattr(n, "smart"); SwigType *ct = Copy(smart ? smart : real_classname); SwigType_add_pointer(ct); SwigType *realct = Copy(real_classname); @@ -4594,7 +4596,6 @@ class PYTHON:public Language { add_method(cname, cname, 0, 0, 1, 1, 1); Delete(cname); } - Delete(smart); Delete(ct); Delete(realct); if (!have_constructor) { diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx index cb7d79fc971..fea6177b1d3 100644 --- a/Source/Modules/ruby.cxx +++ b/Source/Modules/ruby.cxx @@ -1809,7 +1809,7 @@ class RUBY:public Language { Wrapper_add_local(f, "classname", classname); } if (action) { - SwigType *smart = Swig_cparse_smartptr(pn); + SwigType *smart = Getattr(pn, "smart"); String *result_name = NewStringf("%s%s", smart ? "smart" : "", Swig_cresult_name()); if (smart) { String *result_var = NewStringf("%s *%s = 0", SwigType_namestr(smart), result_name); @@ -1821,7 +1821,6 @@ class RUBY:public Language { Printf(action, "\nSWIG_RubyAddTracking(%s, self);", result_name); } Delete(result_name); - Delete(smart); } } @@ -1888,16 +1887,17 @@ class RUBY:public Language { /* Extra code needed for new and initialize methods */ if (current == CONSTRUCTOR_ALLOCATE) { Node *pn = Swig_methodclass(n); - SwigType *smart = Swig_cparse_smartptr(pn); - if (smart) - SwigType_add_pointer(smart); - String *classtype = smart ? smart : t; + SwigType *smart = Getattr(pn, "smart"); + SwigType *psmart = smart ? Copy(smart) : 0; + if (psmart) + SwigType_add_pointer(psmart); + SwigType *classtype = psmart ? psmart : t; need_result = 1; Printf(f->code, "VALUE vresult = SWIG_NewClassInstance(self, SWIGTYPE%s);\n", Char(SwigType_manglestr(classtype))); Printf(f->code, "#ifndef HAVE_RB_DEFINE_ALLOC_FUNC\n"); Printf(f->code, "rb_obj_call_init(vresult, argc, argv);\n"); Printf(f->code, "#endif\n"); - Delete(smart); + Delete(psmart); } else if (current == CONSTRUCTOR_INITIALIZE) { need_result = 1; } @@ -2399,12 +2399,13 @@ class RUBY:public Language { SwigType *btype = NewString(basename); SwigType_add_pointer(btype); SwigType_remember(btype); - SwigType *smart = Swig_cparse_smartptr(base.item); - if (smart) { - SwigType_add_pointer(smart); - SwigType_remember(smart); + SwigType *smart = Getattr(base.item, "smart"); + SwigType *psmart = smart ? Copy(smart) : 0; + if (psmart) { + SwigType_add_pointer(psmart); + SwigType_remember(psmart); } - String *bmangle = SwigType_manglestr(smart ? smart : btype); + String *bmangle = SwigType_manglestr(psmart ? psmart : btype); if (multipleInheritance) { Insert(bmangle, 0, "((swig_class *) SWIGTYPE"); Append(bmangle, "->clientdata)->mImpl"); @@ -2415,7 +2416,7 @@ class RUBY:public Language { Replaceall(klass->init, "$super", bmangle); } Delete(bmangle); - Delete(smart); + Delete(psmart); Delete(btype); } base = Next(base); @@ -2516,15 +2517,16 @@ class RUBY:public Language { SwigType *tt = NewString(name); SwigType_add_pointer(tt); SwigType_remember(tt); - SwigType *smart = Swig_cparse_smartptr(n); - if (smart) { - SwigType_add_pointer(smart); - SwigType_remember(smart); + SwigType *smart = Getattr(n, "smart"); + SwigType *psmart = smart ? Copy(smart) : 0; + if (psmart) { + SwigType_add_pointer(psmart); + SwigType_remember(psmart); } - String *tm = SwigType_manglestr(smart ? smart : tt); + String *tm = SwigType_manglestr(psmart ? psmart : tt); Printf(klass->init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) &SwigClass%s);\n", tm, valid_name); Delete(tm); - Delete(smart); + Delete(psmart); Delete(tt); Delete(valid_name); diff --git a/Source/Modules/swigmain.cxx b/Source/Modules/swigmain.cxx index 677df495985..750b96daaf2 100644 --- a/Source/Modules/swigmain.cxx +++ b/Source/Modules/swigmain.cxx @@ -53,9 +53,9 @@ extern "C" { static TargetLanguageModule modules[] = { {"-allegrocl", NULL, "ALLEGROCL", Disabled}, + {"-cffi", NULL, "CFFI", Disabled}, {"-chicken", NULL, "CHICKEN", Disabled}, {"-clisp", NULL, "CLISP", Disabled}, - {"-cffi", NULL, "CFFI", Disabled}, {"-csharp", swig_csharp, "C#", Supported}, {"-objc", swig_objectivec, "Objective C", Experimental}, {"-d", swig_d, "D", Supported}, diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h index fa89a636399..c146d17ac58 100644 --- a/Source/Modules/swigmod.h +++ b/Source/Modules/swigmod.h @@ -212,7 +212,7 @@ class Language:public Dispatcher { virtual int addInterfaceSymbol(const String *interface_name, Node *n, const_String_or_char_ptr scope = ""); virtual void dumpSymbols(); virtual Node *symbolLookup(const String *s, const_String_or_char_ptr scope = ""); /* Symbol lookup */ - virtual Hash* symbolAddScope(const_String_or_char_ptr scope); + virtual Hash* symbolAddScope(const_String_or_char_ptr scope/*, Node *n = 0*/); virtual Hash* symbolScopeLookup(const_String_or_char_ptr scope); virtual Hash* symbolScopePseudoSymbolLookup(const_String_or_char_ptr scope); static Node *classLookup(const SwigType *s); /* Class lookup */ @@ -421,7 +421,6 @@ void Wrapper_cast_dispatch_mode_set(int); void Wrapper_naturalvar_mode_set(int); void clean_overloaded(Node *n); -SwigType *Swig_smartptr_upcast(SwigType *smart, SwigType *c_classname, SwigType *c_baseclassname); extern "C" { const char *Swig_to_string(DOH *object, int count = -1); diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index 74171f355e7..aa35c4ec7f2 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -253,20 +253,18 @@ class TypePass:private Dispatcher { int len = Len(ilist); int i; for (i = 0; i < len; i++) { - Node *n = Getitem(ilist, i); - SwigType *bname = Getattr(n, "name"); - Node *bclass = n; /* Getattr(n,"class"); */ + Node *bclass = Getitem(ilist, i); + SwigType *bname = Getattr(bclass, "name"); Hash *scopes = Getattr(bclass, "typescope"); SwigType_inherit(clsname, bname, cast, 0); if (ispublic && !GetFlag(bclass, "feature:ignore")) { - String *smartptr = Getattr(first, "feature:smartptr"); - if (smartptr) { - SwigType *smart = Swig_cparse_smartptr(first); - if (smart) { - /* Record a (fake) inheritance relationship between smart pointer - and smart pointer to base class, so that smart pointer upcasts - are automatically generated. */ - SwigType *bsmart = Swig_smartptr_upcast(smart, clsname, bname); + String *smart = Getattr(first, "smart"); + if (smart) { + /* Record a (fake) inheritance relationship between smart pointer + and smart pointer to base class, so that smart pointer upcasts + are automatically generated. */ + SwigType *bsmart = Getattr(bclass, "smart"); + if (bsmart) { String *smartnamestr = SwigType_namestr(smart); String *bsmartnamestr = SwigType_namestr(bsmart); @@ -275,17 +273,15 @@ class TypePass:private Dispatcher { /* setup inheritance relationship between smart pointer templates */ SwigType_inherit(smart, bsmart, 0, convcode); - if (!GetFlag(bclass, "feature:smartptr")) - Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Base class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(bclass, "name")), SwigType_namestr(Getattr(first, "name"))); Delete(bsmartnamestr); Delete(smartnamestr); Delete(convcode); - Delete(bsmart); + } else { + Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Base class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(bclass, "name")), SwigType_namestr(Getattr(first, "name"))); } - Delete(smart); } else { - if (GetFlag(bclass, "feature:smartptr")) + if (GetFlag(bclass, "smart")) Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Derived class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(first, "name")), SwigType_namestr(Getattr(bclass, "name"))); } } @@ -446,9 +442,10 @@ class TypePass:private Dispatcher { SwigType_typedef_class(fname); scopename = Copy(fname); } else { - // Does this code ever get executed ?? - Swig_warning(WARN_TYPE_REDEFINED, Getfile(n), Getline(n), "Template '%s' was already wrapped,\n", SwigType_namestr(name)); - Swig_warning(WARN_TYPE_REDEFINED, Getfile(cn), Getline(cn), "previous wrap of '%s'.\n", SwigType_namestr(Getattr(cn, "name"))); + // Arguably the parser should instead ignore these duplicate template instantiations, in particular for ensuring the first parsed instantiation is used + SetFlag(n, "feature:ignore"); + Swig_warning(WARN_TYPE_REDEFINED, Getfile(n), Getline(n), "Duplicate template instantiation of '%s' with name '%s' ignored,\n", SwigType_namestr(name), Getattr(n, "sym:name")); + Swig_warning(WARN_TYPE_REDEFINED, Getfile(cn), Getline(cn), "previous instantiation of '%s' with name '%s'.\n", SwigType_namestr(Getattr(cn, "name")), Getattr(cn, "sym:name")); scopename = 0; } } else { @@ -503,6 +500,16 @@ class TypePass:private Dispatcher { SwigType_new_scope(scopename); SwigType_attach_symtab(Getattr(n, "symtab")); + if (!GetFlag(n, "feature:ignore")) { + SwigType *smart = Swig_cparse_smartptr(n); + if (smart) { + // Resolve the type in 'feature:smartptr' in the scope of the class it is attached to + normalize_type(smart); + Setattr(n, "smart", smart); + Delete(smart); + } + } + /* Inherit type definitions into the class */ if (name && !(GetFlag(n, "nested") && !checkAttribute(n, "access", "public") && (GetFlag(n, "feature:flatnested") || Language::instance()->nestedClassesSupport() == Language::NCS_None))) { diff --git a/Source/Modules/utils.cxx b/Source/Modules/utils.cxx index 2ae1afa61a6..2d956c4c86e 100644 --- a/Source/Modules/utils.cxx +++ b/Source/Modules/utils.cxx @@ -122,67 +122,6 @@ void Swig_set_max_hash_expand(int count) { SetMaxHashExpand(count); } -/* ----------------------------------------------------------------------------- - * misc_identifier_fix() - * - * If a template, return template with all template parameters fully resolved. - * - * This is a copy and modification of feature_identifier_fix and typemap_identifier_fix. - * ----------------------------------------------------------------------------- */ - -static SwigType *misc_identifier_fix(const SwigType *s) { - String *tp = SwigType_istemplate_templateprefix(s); - if (tp) { - String *ts, *ta, *tq, *tr; - ts = SwigType_templatesuffix(s); - ta = SwigType_templateargs(s); - tq = Swig_symbol_type_qualify(ta, 0); - tr = SwigType_typedef_resolve_all(ta); - Append(tp, tr); - Append(tp, ts); - Delete(ts); - Delete(ta); - Delete(tq); - Delete(tr); - } - return tp; -} - -/* ----------------------------------------------------------------------------- - * Swig_smartptr_upcast() - * - * Replace classname with baseclassname in smart (smart pointer) to morph smart into a - * smart pointer containing the base class instead of the given classname. - * All parameters should be fully qualified types. - * ----------------------------------------------------------------------------- */ - -SwigType *Swig_smartptr_upcast(SwigType *smart, SwigType *classname, SwigType *baseclassname) { - SwigType *bsmart = Copy(smart); - - SwigType *rclassname = SwigType_typedef_resolve_all(classname); - SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname); - - int replace_count = Replaceall(bsmart, rclassname, rbaseclassname); - if (replace_count == 0) { - // If no replacement made, it will be because rclassname is fully resolved, but the - // type in the smartptr feature used a typedef or is not a fully resolved name. - replace_count = Replaceall(bsmart, classname, rbaseclassname); - if (replace_count == 0) { - // Next try with all the template parameters in the smartptr resolved - Delete(bsmart); - SwigType *bsmart = misc_identifier_fix(smart); - if (bsmart) { - replace_count = Replaceall(bsmart, rclassname, rbaseclassname); - } - assert(replace_count); // failed to substitute - } - } - - Delete(rbaseclassname); - Delete(rclassname); - return bsmart; -} - extern "C" { diff --git a/Source/Preprocessor/expr.c b/Source/Preprocessor/expr.c index 4dcbc5ab2cb..c14f7ed81bf 100644 --- a/Source/Preprocessor/expr.c +++ b/Source/Preprocessor/expr.c @@ -357,6 +357,17 @@ int Preprocessor_expr(DOH *s, int *error) { stack[sp].svalue = NewString(Scanner_text(scan)); stack[sp].op = EXPR_VALUE; } else if (token == SWIG_TOKEN_ID) { + int next_token = expr_token(scan); + if (next_token == SWIG_TOKEN_LPAREN) { + /* This is a use of an unknown function-like macro so we emit a + * warning. + */ + errmsg = "Use of undefined function-like macro"; + *error = 1; + return 0; + } + Scanner_pushtoken(scan, next_token, Scanner_text(scan)); + /* Defined macros have been expanded already so this is an unknown * macro, which gets treated as zero. */ diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c index 0c32d0b97be..927eec58b33 100644 --- a/Source/Swig/cwrap.c +++ b/Source/Swig/cwrap.c @@ -875,7 +875,7 @@ void Swig_replace_special_variables(Node *n, Node *parentnode, String *code) { String *parentclassname = 0; if (parentclass) parentclassname = Getattr(parentclass, "name"); - Replaceall(code, "$parentclassname", parentclassname ? SwigType_str(parentclassname, "") : ""); + Replaceall(code, "$parentclassname", parentclassname ? SwigType_str(parentclassname, NULL) : ""); } } diff --git a/Source/Swig/error.c b/Source/Swig/error.c index efd644f9a8e..c85f16df29d 100644 --- a/Source/Swig/error.c +++ b/Source/Swig/error.c @@ -189,7 +189,6 @@ void Swig_warnfilter(const_String_or_char_ptr wlist, int add) { filter = NewStringEmpty(); s = NewString(""); - Clear(s); cw = Char(wlist); while (*cw != '\0') { if (*cw != ' ') { diff --git a/Source/Swig/extend.c b/Source/Swig/extend.c index fa5c0da290c..4e430ed5dee 100644 --- a/Source/Swig/extend.c +++ b/Source/Swig/extend.c @@ -60,9 +60,10 @@ void Swig_extend_merge(Node *cls, Node *am) { symname = Getattr(n,"sym:name"); DohIncref(symname); if ((symname) && (!Getattr(n,"error"))) { + Node *c; /* Remove node from its symbol table */ Swig_symbol_remove(n); - Node *c = Swig_symbol_add(symname,n); + c = Swig_symbol_add(symname,n); if (c != n) { /* Conflict with previous definition. Nuke previous definition */ String *e = NewStringEmpty(); diff --git a/Source/Swig/misc.c b/Source/Swig/misc.c index b6c5cdd34fe..3cd1675aebf 100644 --- a/Source/Swig/misc.c +++ b/Source/Swig/misc.c @@ -1033,7 +1033,7 @@ int Swig_scopename_check(const String *s) { * ----------------------------------------------------------------------------- */ String *Swig_string_command(String *s) { - Swig_error("SWIG", Getline(s), "Command encoder no longer supported - use regex encoder instead.\n"); + Swig_error("SWIG", Getline(s), "Command encoder no longer supported - use regex encoder instead, command:%s\n", s); Exit(EXIT_FAILURE); return 0; } diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c index 2b8e167d47e..6f557a2801d 100644 --- a/Source/Swig/naming.c +++ b/Source/Swig/naming.c @@ -1875,9 +1875,9 @@ String *Swig_name_decl(Node *n) { if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor") || Equal(nodetype, "cdecl"))) { String *d = Getattr(n, "decl"); if (SwigType_isfunction(d)) { - Printv(decl, "(", ParmList_errorstr(Getattr(n, "parms")), ")", NIL); SwigType *decl_temp = Copy(d); SwigType *qualifiers = SwigType_pop_function_qualifiers(decl_temp); + Printv(decl, "(", ParmList_errorstr(Getattr(n, "parms")), ")", NIL); if (qualifiers) { String *qualifiers_string = SwigType_str(qualifiers, 0); Printv(decl, " ", qualifiers_string, NIL); diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c index 6be309e9df1..b0eec2fdb92 100644 --- a/Source/Swig/stype.c +++ b/Source/Swig/stype.c @@ -131,6 +131,8 @@ SwigType *NewSwigType(int t) { return NewString("double"); case T_LONGDOUBLE: return NewString("long double"); + case T_FLTCPLX: + return NewString("float _Complex"); case T_COMPLEX: return NewString("_Complex"); case T_CHAR: @@ -1414,6 +1416,7 @@ void SwigType_variadic_replace(SwigType *t, Parm *unexpanded_variadic_parm, Parm String *unexpanded_name = Getattr(unexpanded_variadic_parm, "name"); ParmList *expanded = CopyParmList(expanded_variadic_parms); Parm *ep = expanded; + SwigType *fparms; while (ep) { SwigType *newtype = Copy(t); SwigType_del_variadic(newtype); @@ -1422,7 +1425,7 @@ void SwigType_variadic_replace(SwigType *t, Parm *unexpanded_variadic_parm, Parm ep = nextSibling(ep); } Clear(t); - SwigType *fparms = SwigType_function_parms_only(expanded); + fparms = SwigType_function_parms_only(expanded); Append(t, fparms); Delete(expanded); diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index b76203454c3..3294bdf778f 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -69,8 +69,6 @@ static Hash *typemaps; * resolving the template parameters. * * This is a copy and modification of feature_identifier_fix in parser.y. - * Also, Swig_smartptr_upcast() could be removed if SwigType_typedef_resolve_all - * is fixed to resolve all template parameters like below. * ----------------------------------------------------------------------------- */ static SwigType *typemap_identifier_fix(const SwigType *s) { diff --git a/Source/Swig/typeobj.c b/Source/Swig/typeobj.c index 74f5898f6ed..fc443d8aa16 100644 --- a/Source/Swig/typeobj.c +++ b/Source/Swig/typeobj.c @@ -115,21 +115,6 @@ * reliable manner. * ----------------------------------------------------------------------------- */ - -/* ----------------------------------------------------------------------------- - * NewSwigType() - * - * Constructs a new type object. Eventually, it would be nice for this function - * to accept an initial value in the form a C/C++ abstract type (currently unimplemented). - * ----------------------------------------------------------------------------- */ - -#ifdef NEW -SwigType *NewSwigType(const_String_or_char_ptr initial) { - return NewString(initial); -} - -#endif - /* The next few functions are utility functions used in the construction and management of types */ diff --git a/Tools/CI-linux-install.sh b/Tools/CI-linux-install.sh index 5f4097a2011..c16eb95d235 100644 --- a/Tools/CI-linux-install.sh +++ b/Tools/CI-linux-install.sh @@ -124,7 +124,7 @@ case "$SWIGLANG" in "ruby") if [[ "$VER" ]]; then case "$VER" in - 3.1 | 3.2 | 3.3 ) + 3.1 | 3.2 | 3.2.2 | 3.3 ) # Ruby 3.1+ support is currently only rvm master (2023-04-19) # YOLO curl -sSL https://rvm.io/mpapis.asc | gpg --import - diff --git a/configure.ac b/configure.ac index c0600287211..7ab65a87602 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script. dnl The macros which aren't shipped with the autotools are stored in the dnl Tools/config directory in .m4 files. -AC_INIT([swig],[4.2.0],[https://www.swig.org]) +AC_INIT([swig],[4.2.1],[https://www.swig.org]) AC_PREREQ([2.60]) AC_CONFIG_SRCDIR([Source/Swig/swig.h]) @@ -1684,7 +1684,11 @@ if test -n "$OCTAVE"; then OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "-L`${mkoctfile} -p ${var}` done for var in RDYNAMIC_FLAG RLD_FLAG OCTAVE_LIBS LIBS; do - OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "`${mkoctfile} -p ${var}` + # RLD_FLAG gives "mkoctfile: unknown variable 'RLD_FLAG'" on stderr + # with Octave 7.3 so just discard stderr here. Apparently RLD_FLAG has + # reported an empty value since somewhere between 3.4.3 and 3.6.1 so + # can be removed below once we require Octave 4. + OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "`${mkoctfile} -p ${var} 2>/dev/null` done AC_MSG_RESULT([$OCTAVE_LDFLAGS])