Imported Upstream version 4.0.2 upstream/4.0.2
authorJinWang An <jinwang.an@samsung.com>
Wed, 23 Feb 2022 02:46:05 +0000 (11:46 +0900)
committerJinWang An <jinwang.an@samsung.com>
Wed, 23 Feb 2022 02:46:05 +0000 (11:46 +0900)
162 files changed:
.travis.yml
ANNOUNCE
CHANGES
CHANGES.current
Doc/Manual/CSharp.html
Doc/Manual/Contents.html
Doc/Manual/Doxygen.html
Doc/Manual/Lua.html
Doc/Manual/Preprocessor.html
Doc/Manual/R.html
Doc/Manual/Ruby.html
Doc/Manual/SWIG.html
Doc/Manual/SWIGDocumentation.html
Doc/Manual/SWIGDocumentation.pdf
Doc/Manual/Sections.html
Doc/Manual/style.css
Examples/Makefile.in
Examples/octave/example.mk
Examples/test-suite/autodoc.i
Examples/test-suite/common.mk
Examples/test-suite/cpp11_final_override.i
Examples/test-suite/cpp11_shared_ptr_template_upcast.i [new file with mode: 0644]
Examples/test-suite/cpp_parameters.i [new file with mode: 0644]
Examples/test-suite/csharp/Makefile.in
Examples/test-suite/csharp/cpp11_shared_ptr_template_upcast_runme.cs [new file with mode: 0644]
Examples/test-suite/csharp/csharp_director_typemaps_runme.cs [new file with mode: 0644]
Examples/test-suite/csharp_director_typemaps.i [new file with mode: 0644]
Examples/test-suite/director_conversion_operators.i [new file with mode: 0644]
Examples/test-suite/doxygen_basic_translate.i
Examples/test-suite/doxygen_basic_translate_style3.i [new file with mode: 0644]
Examples/test-suite/doxygen_code_blocks.i [new file with mode: 0644]
Examples/test-suite/doxygen_misc_constructs.h
Examples/test-suite/doxygen_misc_constructs.i
Examples/test-suite/doxygen_translate_all_tags.i
Examples/test-suite/global_immutable_vars.i [new file with mode: 0644]
Examples/test-suite/global_immutable_vars_cpp.i [new file with mode: 0644]
Examples/test-suite/java/CommentParser.java
Examples/test-suite/java/Makefile.in
Examples/test-suite/java/cpp11_shared_ptr_template_upcast_runme.java [new file with mode: 0644]
Examples/test-suite/java/director_string_runme.java
Examples/test-suite/java/doxygen_alias_runme.java
Examples/test-suite/java/doxygen_basic_notranslate_runme.java
Examples/test-suite/java/doxygen_basic_translate_runme.java
Examples/test-suite/java/doxygen_basic_translate_style2_runme.java
Examples/test-suite/java/doxygen_basic_translate_style3_runme.java [new file with mode: 0644]
Examples/test-suite/java/doxygen_code_blocks_runme.java [new file with mode: 0644]
Examples/test-suite/java/doxygen_ignore_runme.java
Examples/test-suite/java/doxygen_misc_constructs_runme.java
Examples/test-suite/java/doxygen_nested_class_runme.java
Examples/test-suite/java/doxygen_parsing_enums_proper_runme.java
Examples/test-suite/java/doxygen_parsing_enums_simple_runme.java
Examples/test-suite/java/doxygen_parsing_enums_typesafe_runme.java
Examples/test-suite/java/doxygen_parsing_enums_typeunsafe_runme.java
Examples/test-suite/java/doxygen_parsing_runme.java
Examples/test-suite/java/doxygen_translate_all_tags_runme.java
Examples/test-suite/java/doxygen_translate_links_runme.java
Examples/test-suite/java/doxygen_translate_runme.java
Examples/test-suite/kwargs_feature.i
Examples/test-suite/li_std_auto_ptr.i
Examples/test-suite/lua/Makefile.in
Examples/test-suite/lua/lua_lightuserdata_runme.lua [new file with mode: 0644]
Examples/test-suite/lua_lightuserdata.i [new file with mode: 0644]
Examples/test-suite/octave/Makefile.in
Examples/test-suite/python/Makefile.in
Examples/test-suite/python/autodoc_runme.py
Examples/test-suite/python/cpp11_shared_ptr_template_upcast_runme.py [new file with mode: 0644]
Examples/test-suite/python/cpp11_shared_ptr_upcast_runme.py [new file with mode: 0644]
Examples/test-suite/python/cpp_parameters_runme.py [new file with mode: 0644]
Examples/test-suite/python/director_wstring_runme.py
Examples/test-suite/python/doxygen_basic_translate_runme.py
Examples/test-suite/python/doxygen_basic_translate_style2_runme.py
Examples/test-suite/python/doxygen_basic_translate_style3_runme.py [new file with mode: 0644]
Examples/test-suite/python/doxygen_code_blocks_runme.py [new file with mode: 0644]
Examples/test-suite/python/doxygen_misc_constructs_runme.py
Examples/test-suite/python/doxygen_translate_all_tags_runme.py
Examples/test-suite/python/doxygen_translate_runme.py
Examples/test-suite/python/kwargs_feature_runme.py
Examples/test-suite/python/python_append_runme.py
Examples/test-suite/python_append.i
Examples/test-suite/r/Makefile.in
Examples/test-suite/r/abstract_access_runme.R [new file with mode: 0644]
Examples/test-suite/r/r_memory_leak_runme.R [new file with mode: 0644]
Examples/test-suite/r_memory_leak.i [new file with mode: 0644]
Examples/test-suite/ruby/Makefile.in
Examples/test-suite/ruby/global_immutable_vars_cpp_runme.rb [new file with mode: 0644]
Examples/test-suite/ruby/global_immutable_vars_runme.rb [new file with mode: 0644]
Examples/test-suite/ruby/li_std_auto_ptr_runme.rb [new file with mode: 0644]
Examples/test-suite/ruby/newobject2_runme.rb
Examples/test-suite/ruby/ruby_global_immutable_vars_cpp_runme.rb [new file with mode: 0644]
Examples/test-suite/ruby/ruby_global_immutable_vars_runme.rb [new file with mode: 0644]
Examples/test-suite/ruby_global_immutable_vars.i [new file with mode: 0644]
Examples/test-suite/ruby_global_immutable_vars_cpp.i [new file with mode: 0644]
Lib/d/wrapperloader.swg
Lib/lua/luarun.swg
Lib/ocaml/carray.i
Lib/ocaml/ocaml.swg
Lib/ocaml/ocamlrun.swg
Lib/octave/director.swg
Lib/octave/extra-install.list [new file with mode: 0644]
Lib/octave/octcontainer.swg
Lib/octave/octheaders.hpp [new file with mode: 0644]
Lib/octave/octrun.swg
Lib/octave/octruntime.swg
Lib/octave/std_complex.i
Lib/python/builtin.swg
Lib/python/pycontainer.swg
Lib/python/pyhead.swg
Lib/python/pyinit.swg
Lib/python/pyrun.swg
Lib/python/pystdcommon.swg
Lib/python/pystrings.swg
Lib/python/std_map.i
Lib/python/std_multimap.i
Lib/python/std_pair.i
Lib/python/std_unordered_map.i
Lib/python/std_unordered_multimap.i
Lib/r/rfragments.swg
Lib/r/rrun.swg
Lib/r/rtype.swg
Lib/ruby/rubyclasses.swg
Lib/ruby/rubycontainer.swg
Lib/ruby/rubyhead.swg
Lib/ruby/rubyprimtypes.swg
Lib/ruby/rubyrun.swg
Lib/ruby/rubytracking.swg
Lib/ruby/std_auto_ptr.i [new file with mode: 0644]
Lib/ruby/std_shared_ptr.i
Lib/ruby/std_wstring.i
README
RELEASENOTES
Source/CParse/cscanner.c
Source/CParse/parser.c
Source/CParse/parser.y
Source/DOH/README
Source/DOH/doh.h
Source/DOH/memory.c
Source/DOH/string.c
Source/Doxygen/doxycommands.h
Source/Doxygen/doxyparser.cxx
Source/Doxygen/doxyparser.h
Source/Doxygen/javadoc.cxx
Source/Doxygen/pydoc.cxx
Source/Doxygen/pydoc.h
Source/Makefile.in
Source/Modules/csharp.cxx
Source/Modules/d.cxx
Source/Modules/java.cxx
Source/Modules/main.cxx
Source/Modules/ocaml.cxx
Source/Modules/octave.cxx
Source/Modules/python.cxx
Source/Modules/r.cxx
Source/Modules/ruby.cxx
Source/Modules/swigmain.cxx
Source/Modules/typepass.cxx
Source/Swig/misc.c
Source/Swig/swig.h
Tools/travis-linux-install.sh
Tools/travis-osx-install.sh
appveyor.yml
configure
configure.ac

index c9cbd78..b806c85 100644 (file)
@@ -54,7 +54,12 @@ matrix:
       dist: xenial
     - compiler: gcc
       os: linux
-      env: SWIGLANG=d
+      env: SWIGLANG=d VER=2.066.0
+      sudo: required
+      dist: xenial
+    - compiler: gcc
+      os: linux
+      env: SWIGLANG=d VER=2.086.1
       sudo: required
       dist: xenial
     - compiler: gcc
@@ -141,7 +146,12 @@ matrix:
       os: linux
       env: SWIGLANG=octave SWIGJOBS=-j2
       sudo: required
-      dist: xenial
+      dist: xenial   # Octave v4.0.0
+    - compiler: gcc
+      os: linux
+      env: SWIGLANG=octave SWIGJOBS=-j2 CPP11=1
+      sudo: required
+      dist: bionic   # Octave v4.2.2
     - compiler: gcc
       os: linux
       env: SWIGLANG=perl5
@@ -204,6 +214,11 @@ matrix:
       dist: xenial
     - compiler: gcc
       os: linux
+      env: SWIGLANG=python PY3=3 VER=3.8
+      sudo: required
+      dist: xenial
+    - compiler: gcc
+      os: linux
       env: SWIGLANG=python SWIG_FEATURES=-builtin
       sudo: required
       dist: xenial
@@ -217,7 +232,7 @@ matrix:
       sudo: required
       dist: xenial
     - os: linux
-      env: SWIGLANG=python SWIG_FEATURES=-builtin GCC=6 CPP11=1 PY3=3 VER=3.7
+      env: SWIGLANG=python SWIG_FEATURES=-builtin GCC=6 CPP11=1 PY3=3 VER=3.8
       sudo: required
       dist: xenial
     - compiler: gcc
@@ -237,12 +252,17 @@ matrix:
       dist: xenial
     - compiler: gcc
       os: linux
-      env: SWIGLANG=python SWIG_FEATURES="-builtin -O" PY3=3 VER=3.7
+      env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.8
       sudo: required
       dist: xenial
     - compiler: gcc
       os: linux
-      env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.7 SWIGOPTPY3=
+      env: SWIGLANG=python SWIG_FEATURES="-builtin -O" PY3=3 VER=3.8
+      sudo: required
+      dist: xenial
+    - compiler: gcc
+      os: linux
+      env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.8 SWIGOPTPY3=
       sudo: required
       dist: xenial
     - compiler: gcc
@@ -252,7 +272,7 @@ matrix:
       dist: xenial
     - compiler: gcc
       os: linux
-      env: SWIGLANG=python SWIG_FEATURES=-O PY3=3 VER=3.7
+      env: SWIGLANG=python SWIG_FEATURES=-O PY3=3 VER=3.8
       sudo: required
       dist: xenial
     - compiler: gcc
@@ -302,6 +322,11 @@ matrix:
       dist: xenial
     - compiler: gcc
       os: linux
+      env: SWIGLANG=ruby VER=2.7
+      sudo: required
+      dist: xenial
+    - compiler: gcc
+      os: linux
       env: SWIGLANG=scilab
       sudo: required
       dist: xenial
@@ -322,11 +347,6 @@ matrix:
       env: SWIGLANG=java CPP11=1
       sudo: required
       dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=octave SWIGJOBS=-j2 VER=4.4 CPP11=1
-      sudo: required
-      dist: trusty
     - os: linux
       env: SWIGLANG=python CPP11=1
       sudo: required
@@ -384,7 +404,7 @@ matrix:
       sudo: required
       dist: xenial
     - os: linux
-      env: SWIGLANG=python GCC=8 CPP17=1 PY3=3 VER=3.7
+      env: SWIGLANG=python GCC=8 CPP17=1 PY3=3 VER=3.8
       sudo: required
       dist: xenial
     - os: linux
@@ -396,7 +416,12 @@ matrix:
       sudo: required
       dist: xenial
     - os: linux
-      env: SWIGLANG=python GCC=9 CPP17=1 PY3=3 VER=3.7
+      env: SWIGLANG=python GCC=9 CPP17=1 PY3=3 VER=3.8
+      sudo: required
+      dist: xenial
+    - os: linux
+      arch: s390x
+      env: SWIGLANG=ruby CPP11=1
       sudo: required
       dist: xenial
     - compiler: gcc
@@ -413,7 +438,7 @@ matrix:
       env: SWIGLANG=go
     - compiler: clang
       os: osx
-      env: SWIGLANG=guile
+      env: SWIGLANG=guile CSTD=c11
     - compiler: clang
       os: osx
       env: SWIGLANG=java
@@ -422,7 +447,7 @@ matrix:
       env: SWIGLANG=lua
     - compiler: clang
       os: osx
-      env: SWIGLANG=octave SWIGJOBS=-j2
+      env: SWIGLANG=octave SWIGJOBS=-j2 CPP11=1
     - compiler: clang
       os: osx
       env: SWIGLANG=perl5
@@ -448,16 +473,18 @@ matrix:
       osx_image: xcode10.2
 
   allow_failures:
+    # Newer version of D not yet working/supported
+    - compiler: gcc
+      os: linux
+      env: SWIGLANG=d VER=2.086.1
+      sudo: required
+      dist: xenial
     # seg fault in director_basic testcase
     - compiler: gcc
       os: linux
       env: SWIGLANG=php VER=7.2
       sudo: required
       dist: xenial
-    # Sometimes hits the Travis 50 minute time limit
-    - compiler: clang
-      os: osx
-      env: SWIGLANG=octave SWIGJOBS=-j2
     # Experimental languages
     - compiler: gcc
       os: linux
@@ -473,7 +500,7 @@ matrix:
 before_install:
   - date -u
   - uname -a
-  - if test "$TRAVIS_OS_NAME" = "linux"; then lscpu && cat /proc/cpuinfo | grep "model name" && cat /proc/meminfo | grep MemTotal; fi
+  - if test "$TRAVIS_OS_NAME" = "linux"; then lscpu; grep "model name" /proc/cpuinfo || echo 'Unknown CPU model'; grep "MemTotal" /proc/meminfo || echo 'Unknown system memory amount'; fi
   - if test "$TRAVIS_OS_NAME" = "osx"; then sysctl -a | grep brand_string; fi
   # Travis overrides CC environment with compiler predefined values
   - if test -n "$GCC"; then export CC="gcc-$GCC" && export CXX="g++-$GCC"; fi
index 495f101..b99c0c3 100644 (file)
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,8 +1,8 @@
-*** ANNOUNCE: SWIG 4.0.1 (21 Aug 2019) ***
+*** ANNOUNCE: SWIG 4.0.2 (8 Jun 2020) ***
 
 http://www.swig.org
 
-We're pleased to announce SWIG-4.0.1, the latest SWIG release.
+We're pleased to announce SWIG-4.0.2, the latest SWIG release.
 
 What is SWIG?
 =============
@@ -25,11 +25,11 @@ Availability
 ============
 The release is available for download on Sourceforge at
 
-     http://prdownloads.sourceforge.net/swig/swig-4.0.1.tar.gz
+     http://prdownloads.sourceforge.net/swig/swig-4.0.2.tar.gz
 
 A Windows version is also available at
 
-     http://prdownloads.sourceforge.net/swig/swigwin-4.0.1.zip
+     http://prdownloads.sourceforge.net/swig/swigwin-4.0.2.zip
 
 Please report problems with this release to the swig-devel mailing list,
 details at http://www.swig.org/mail.html.
diff --git a/CHANGES b/CHANGES
index 7fd6b6d..fe86967 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,145 @@ 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.0.1 (21 Aug 2019)
+===========================
+
+2019-08-20: TekuConcept
+            [Javascript] #1535 Add %native support to Javascript.
+
+2019-08-20: bkotzz
+            [Java] #1616 Add SWIG_JavaIllegalStateException to support throwing
+            java.lang.IllegalStateException from JNI code.
+
+2019-08-19: sjml
+            [Lua] #1596 tostring output changes to show the underlying C/C++ pointer.
+
+2019-08-08: rokups
+            [C#, Java] #1601 Fix invalid code generated for "%constant enum EnumType.
+
+2019-08-07: wsfulton
+            [Python] Fix method overloading of methods that take STL containers of different
+            types. The following usage (using std::vector) would fail when using -builtin:
+
+              %include <std_string.i>
+              %include <std_vector.i>
+
+              %inline %{
+              struct X {};
+              %}
+
+              %template(VectorX) std::vector<X>;
+              %template(VectorInt) std::vector<int>;
+
+              %inline %{
+              using namespace std;
+              string VectorOverload(vector<X> v);
+              string VectorOverload(vector<int> v);
+              %}
+
+            The following would incorrectly fail:
+
+              s = VectorOverload([1, 2, 3])
+
+            With:
+
+              Traceback (most recent call last):
+                File "runme3.py", line 20, in <module>
+                  ret = VectorOverload([1, 2, 3])
+              TypeError: Wrong number or type of arguments for overloaded function 'VectorOverload'.
+                Possible C/C++ prototypes are:
+                  VectorOverload(std::vector< Number,std::allocator< Number > >)
+                  VectorOverload(std::vector< int,std::allocator< int > >)
+
+            The problem was due to some error handling that was not cleared during typehecking.
+            In this case an error was not cleared when the elements in the list failed the
+            typecheck for converting to X. Only occurs in Python 3+.
+
+            In some combinations of overloaded methods, the following type of error message would
+            occur:
+
+              RuntimeError: in sequence element 0
+
+              The above exception was the direct cause of the following exception:
+
+              Traceback (most recent call last):
+                File "runme3.py", line 23, in <module>
+                  check(VectorOverload(v), "vector<X>")
+              SystemError: <built-in function VectorOverload> returned a result with an error set
+
+2019-08-01: wsfulton
+            #1602 Fix regression in 4.0.0 where a template function containing a parameter
+            with the same name as the function name led to the parameter name used in the
+            target language being incorrectly modified.
+
+2019-07-29: wsfulton
+            Remove all generated files on error. Previously generated files were not removed,
+            potentially breaking Makefiles using file dependencies, especially when -Werror
+            (warnings as errors) was used.
+
+2019-07-23: smithx
+            [C#] #1530 #1532 Fix marshalling of std::wstring to C#.
+
+2019-07-18: gicmo
+            [Python] #1587 Python 3.8 support - remove use of deprecated PyObject_GC_UnTrack.
+
+2019-07-18: cher-nov
+            [Python] #1573 Generated Python code uses consistent string quoting style - double
+            quotes.
+
+2019-07-16: geefr
+            [C#] #616 #1576 Fix C# bool INPUT[], bool OUTPUT[], bool INOUT[] typemaps to marshall
+            as 1-byte.
+
+2019-07-12: vadz
+            [C#, Java] #1568 #1583 Fix std::set<> typemaps for primitive types.
+
+2019-07-12: vadz
+            #1566 #1584 Regression in 4.0.0 - fix missing value for first item of enums with
+            trailing comma.
+
+2019-07-11: mcfarljm
+            #1548 #1578 Fix segfault in Doxygen parser parsing empty lines in some commands like
+            \code.
+
+2019-07-09: IsaacPascual
+            [C#, Java] #1570 Fix name of generated C#/Java classes for %interface macros
+            in swiginterface.i when wrapping nested C++ classes.
+
+2019-07-05: wsfulton
+            [Python] #1547 Whitespace fixes in Doxygen translated comments into pydoc comments
+            for Sphinx compatibility.
+
+2019-06-28: wsfulton
+            [MzScheme, OCaml] #1559 $arg and $input were incorrectly substituted in the
+            argout typemap when two or more arguments were present.
+
+2019-06-24: wsfulton
+            [Python, Ruby] #1538 Remove the UnknownExceptionHandler class in order to be
+            C++17 compliant as it uses std::unexpected_handler which was removed in C++17.
+            This class was intended for director exception handling but was never used by
+            SWIG and was never documented.
+
+            *** POTENTIAL INCOMPATIBILITY ***
+
+2019-06-06: bkotzz
+            [Java] #1552 Improve performance in Java std::vector constructor wrapper that takes
+            a native Java array as input.
+
+2019-06-03: olly
+           [Python] Fix regression in implicit_conv handling of tuples,
+           introduced in SWIG 4.0.0.  Fixes #1553, reported by Alexandre
+           Duret-Lutz.
+
+2019-05-24: wsfulton
+            [Octave] Fix detection of Octave on MacOS.
+
+2019-05-24: opoplawski
+            [Octave] #1522 Adapt OCTAVE_LDFLAGS for Octave 5.1.
+
+2019-05-22: ferdynator
+           [PHP] #1528 Don't add a closing '?>' PHP tag to generated files.
+           PSR-2 says it MUST be omitted for files containing only PHP.
 Version 4.0.0 (27 Apr 2019)
 ===========================
 
index ab69e09..ba71d55 100644 (file)
@@ -4,142 +4,147 @@ 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.0.1 (21 Aug 2019)
-===========================
+Version 4.0.2 (8 Jun 2020)
+==========================
 
-2019-08-20: TekuConcept
-            [Javascript] #1535 Add %native support to Javascript.
+2020-06-07  vigsterkr
+            [Ruby] #1717 Nil fix mangling strings
 
-2019-08-20: bkotzz
-            [Java] #1616 Add SWIG_JavaIllegalStateException to support throwing
-            java.lang.IllegalStateException from JNI code.
+2020-06-07  vadz
+            #1748 Fix doxygen comments quoting issue
 
-2019-08-19: sjml
-            [Lua] #1596 tostring output changes to show the underlying C/C++ pointer.
+2020-06-07  munoah
+            #1800 Escape spaces in file paths for dependencies (-M -MM etc)
 
-2019-08-08: rokups
-            [C#, Java] #1601 Fix invalid code generated for "%constant enum EnumType.
+2020-06-06  andreas-schwab
+            [Ruby] #1801 Fix encoding on big endian systems when wrapping std::wstring.
 
-2019-08-07: wsfulton
-            [Python] Fix method overloading of methods that take STL containers of different
-            types. The following usage (using std::vector) would fail when using -builtin:
+2020-05-31  kwwette
+            [Octave] #1789 error handling improvements and return error code on exit for SWIG wrapped modules.
 
-              %include <std_string.i>
-              %include <std_vector.i>
+2020-05-30  msteinbeck
+            [D] #1593 Replace broken imports when using newer versions of D.
 
-              %inline %{
-              struct X {};
-              %}
+2020-05-29: ZackerySpytz
+            [Python] #1716 Performance improvements converting strings when using Python >= 3.3.
 
-              %template(VectorX) std::vector<X>;
-              %template(VectorInt) std::vector<int>;
+2020-05-28: ZackerySpytz
+            #1776 Quite dramatically decrease run times when generating very large interface files by changing
+            some internal memory pool sizes.
 
-              %inline %{
-              using namespace std;
-              string VectorOverload(vector<X> v);
-              string VectorOverload(vector<int> v);
-              %}
+2020-05-28: mcfarljm
+            #1788 Fix handling of Doxygen \endlink command.
 
-            The following would incorrectly fail:
+2020-05-24: vapier
+            [Javascript] #1796 Fix pkg-config invocation in configure.
 
-              s = VectorOverload([1, 2, 3])
+2020-04-30: kwwette
+            [Octave] Fix exception raising for newer Octave versions
+            Since (at least) Octave 5.1.0, the Octave error() function now raises a C++ exception,
+            which if uncaught immediately exits a SWIG wrapper function, bypassing any cleanup code
+            that may appear after a "fail:" label. This patch adds a "try { ... } catch(...) { }"
+            block around the contents of SWIG wrapper functions to first execute the cleanup code
+            before rethrowing any exception raised. It is backward compatible with earlier versions
+            of Octave where error() does not raise an exception, which will still branch to the
+            "fail:" block to execute cleanup code if an error is encountered.
 
-            With:
+            Note that the new "try { ... } catch(...) { }" block will localise any local variables
+            used in typemaps that were NOT declared through SWIG's %typemap(...) syntax, so it's
+            possible this could break existing SWIG wrappers which were implicitly sharing local
+            variables between typemaps. This can be fixed, however, by declaring local variables
+            which need to be shared between typemaps through SWIG's %typemap(...) syntax.
 
-              Traceback (most recent call last):
-                File "runme3.py", line 20, in <module>
-                  ret = VectorOverload([1, 2, 3])
-              TypeError: Wrong number or type of arguments for overloaded function 'VectorOverload'.
-                Possible C/C++ prototypes are:
-                  VectorOverload(std::vector< Number,std::allocator< Number > >)
-                  VectorOverload(std::vector< int,std::allocator< int > >)
+2020-02-18: ryannevell
+            [Lua] #1728 Add support for LUA lightuserdata to SWIG_Lua_ConvertPtr.
 
-            The problem was due to some error handling that was not cleared during typehecking.
-            In this case an error was not cleared when the elements in the list failed the
-            typecheck for converting to X. Only occurs in Python 3+.
+2020-02-18: dmach
+            [Ruby] #1725 Fix gcc -Wcatch-value warnings.
 
-            In some combinations of overloaded methods, the following type of error message would
-            occur:
+2020-02-14: treitmayr
+            #1724 Fix wrapping of abstract user-defined conversion operators.
 
-              RuntimeError: in sequence element 0
+2020-02-13: ddurham2
+            [Python] #1512 Fix memleak when using STL containers of shared_ptr objects.
 
-              The above exception was the direct cause of the following exception:
+2020-02-06: wsfulton
+            [Python] #1673 #1674 Fix setting 'this' when extending a proxy class with __slots__.
 
-              Traceback (most recent call last):
-                File "runme3.py", line 23, in <module>
-                  check(VectorOverload(v), "vector<X>")
-              SystemError: <built-in function VectorOverload> returned a result with an error set
+2020-01-31: vadz
+            [Ruby] #1651 Add std::auto_ptr<> typemaps.
 
-2019-08-01: wsfulton
-            #1602 Fix regression in 4.0.0 where a template function containing a parameter
-            with the same name as the function name led to the parameter name used in the
-            target language being incorrectly modified.
+2020-01-31: ZackerySpytz
+            [Python] #1700 More robust error checking for failures in calls to Python C API:
+            PyBytes_AsStringAndSize() and PyString_AsStringAndSize().
 
-2019-07-29: wsfulton
-            Remove all generated files on error. Previously generated files were not removed,
-            potentially breaking Makefiles using file dependencies, especially when -Werror
-            (warnings as errors) was used.
+2020-01-31: vadz
+            [Python] #1710 Fix crash parsing empty docstrings.
 
-2019-07-23: smithx
-            [C#] #1530 #1532 Fix marshalling of std::wstring to C#.
+2020-01-30: Alzathar
+            [R] #910 #914 Fix R memory leak on exception.
 
-2019-07-18: gicmo
-            [Python] #1587 Python 3.8 support - remove use of deprecated PyObject_GC_UnTrack.
+2020-01-30: richardbeare
+            [R] #1511 Fix bug wrapping functions. These were previously incorrectly wrapped as if
+            they were variables. This happened when 'get' or 'set' was in the name of the function
+            or method, but sometimes also in some other circumstances. If you were using R
+            attribute syntax to access these methods, you'll need to switch to calling them as R
+            methods.
 
-2019-07-18: cher-nov
-            [Python] #1573 Generated Python code uses consistent string quoting style - double
-            quotes.
+            *** POTENTIAL INCOMPATIBILITY ***
 
-2019-07-16: geefr
-            [C#] #616 #1576 Fix C# bool INPUT[], bool OUTPUT[], bool INOUT[] typemaps to marshall
-            as 1-byte.
+2020-01-24: etse-dignitas, wsfulton
+            [C#, D, Java] #1533 Fix upcasting for shared_ptr's of templated types.
 
-2019-07-12: vadz
-            [C#, Java] #1568 #1583 Fix std::set<> typemaps for primitive types.
+2020-01-16: mcfarljm
+            #1643 #1654 When using -doxygen, fix segfault when nameless parameters or vararg parameters
+            are used.
 
-2019-07-12: vadz
-            #1566 #1584 Regression in 4.0.0 - fix missing value for first item of enums with
-            trailing comma.
+2020-01-16: mcfarljm
+            #1632 #1659 Fix newline handling for doxygen "///" comments.
 
-2019-07-11: mcfarljm
-            #1548 #1578 Fix segfault in Doxygen parser parsing empty lines in some commands like
-            \code.
+2020-01-14: mcfarljm
+            #1647 #1656 Fix crash handling empty doxygen comments.
 
-2019-07-09: IsaacPascual
-            [C#, Java] #1570 Fix name of generated C#/Java classes for %interface macros
-            in swiginterface.i when wrapping nested C++ classes.
+2020-01-14: mcfarljm
+            #1608 Improve doxygen support.
+            - Add support for \param[] commands such as: \param[in].
+            - Optional arguments are marked as 'optional' in pydoc.
+            - Improve support for \code commands so that other languages are supported as code blocks.
+              Support added for java, c and py.  For example Python: \code{.py} ... \endcode
+            - Fix doxygen handling of \em and \p tags for Python.
 
-2019-07-05: wsfulton
-            [Python] #1547 Whitespace fixes in Doxygen translated comments into pydoc comments
-            for Sphinx compatibility.
+2020-01-13: wsfulton
+            [Python] #1595 Python -builtin constructors silently ignored keyword arguments.
+            Instead of silenty ignoring them, now a "TypeError: f() takes no keyword arguments"
+            exception is thrown if keyword arguments are used. Hence constructors and normal methods/
+            functions behave in the same way. Note, -keyword should be used with -builtin to obtain
+            keyword argument support.
 
-2019-06-28: wsfulton
-            [MzScheme, OCaml] #1559 $arg and $input were incorrectly substituted in the
-            argout typemap when two or more arguments were present.
+2020-01-05: jschueller shadchin
+            [Python] #1670 #1696 Add missing field initializers introduced in python 3.8:
+            tp_vectorcall and tp_print.
 
-2019-06-24: wsfulton
-            [Python, Ruby] #1538 Remove the UnknownExceptionHandler class in order to be
-            C++17 compliant as it uses std::unexpected_handler which was removed in C++17.
-            This class was intended for director exception handling but was never used by
-            SWIG and was never documented.
+2020-01-05: friedrichatgc
+            [Octave] #1688 Change swig_this() to use size_t instead of long for compatibility
+            with Windows 64 bit.
 
-            *** POTENTIAL INCOMPATIBILITY ***
+2020-01-05: treitmayr
+            [Ruby] #1692 #1689 Add support for Ruby 2.7
 
-2019-06-06: bkotzz
-            [Java] #1552 Improve performance in Java std::vector constructor wrapper that takes
-            a native Java array as input.
+2019-12-30: treitmayr
+            [Ruby] #1653 #1668 Fix code generated when using -globalmodule option.
 
-2019-06-03: olly
-           [Python] Fix regression in implicit_conv handling of tuples,
-           introduced in SWIG 4.0.0.  Fixes #1553, reported by Alexandre
-           Duret-Lutz.
+2019-12-29: ZackerySpytz
+            [OCaml] #1686 Fix compilation errors with OCaml 4.09.0.
 
-2019-05-24: wsfulton
-            [Octave] Fix detection of Octave on MacOS.
+2019-12-10: wsfulton
+            #1679 Fix parsing of C++11 identifiers with special meaning (final and override) when
+            they are used as part of the scope name of an identifier, such as a namespace name.
 
-2019-05-24: opoplawski
-            [Octave] #1522 Adapt OCTAVE_LDFLAGS for Octave 5.1.
+2019-11-26: wsfulton
+            [C#] #1628 'out' or 'ref' used in a cstype typemap was not always stripped out in parts
+            of director code generation.
 
-2019-05-22: ferdynator
-           [PHP] #1528 Don't add a closing '?>' PHP tag to generated files.
-           PSR-2 says it MUST be omitted for files containing only PHP.
+2019-11-01: wsfulton
+            [Python] #1595 Fix bug in support for keyword arguments (kwargs feature or -keyword)
+            when using -builtin. The fix is in the argument error checking when wrapping zero
+            argument constructors only.
index 1fc2d21..2e6a851 100644 (file)
@@ -66,7 +66,13 @@ PInvoke is part of the ECMA/ISO C# specification.
 It is also better suited for robust production environments due to the Managed C++ flaw called the
 <a href="https://msdn.microsoft.com/en-us/ie/aa290048(v=vs.94)">Mixed DLL Loading Problem</a>.
 SWIG C# works equally well on non-Microsoft operating systems such as Linux, Solaris and Apple Mac using
-<a href="https://www.mono-project.com/Main_Page/">Mono</a> and <a href="http://www.dotgnu.org/pnet.html">Portable.NET</a>.
+<a href="https://www.mono-project.com/Main_Page/">Mono</a>.
+</p>
+
+<p>
+SWIG 3 and later requires .NET 2.0 at a minimum.
+There are some minor exceptions, where the minimum required is .NET 4.0.
+This is when using the <tt>std::complex</tt> and <tt>std::list</tt> STL containers.
 </p>
 
 <p>
index 57aef5b..8d1c09d 100644 (file)
 <li><a href="R.html#R_nn5">General policy</a>
 <li><a href="R.html#R_language_conventions">Language conventions</a>
 <li><a href="R.html#R_nn6">C++ classes</a>
+<ul>
+<li><a href="R.html#R_class_examples">Examples</a>
+</ul>
 <li><a href="R.html#R_nn7">Enumerations</a>
 </ul>
 </div>
index ff025c0..75657dc 100644 (file)
@@ -117,14 +117,15 @@ Documenting the code</a>). Here they are:
 </pre></div>
 
 <p>
-Also any of the above with '&lt;' added after comment-starting symbol,
-like <i>/**&lt;, /*!&lt;, ///&lt;, </i> or <i> //!&lt;</i> will be
+Also any of the above with '<tt>&lt;</tt>' added after comment-starting symbol,
+like <tt>/**&lt;, /*!&lt;, ///&lt;, </tt> or <tt> //!&lt;</tt> will be
 treated as a post-comment and will be assigned to the code before the
 comment.
 
-Any number of '*' or '/' within a Doxygen comment is considered to be a
-separator and is not included in the final comment, so you may safely use
-comments like <i>/*********/</i> or <i>//////////</i>.
+Any number of '<tt>*</tt>' or '<tt>/</tt>' within a Doxygen comment is
+considered to be a separator and is not included in the final comment,
+so you may safely use comments like <tt>/*********/</tt>
+or <tt>//////////</tt>.
 </p>
 
 <p>
@@ -606,6 +607,10 @@ Here is the list of all Doxygen tags and the description of how they are transla
 <td>translated to {@code ...}</td>
 </tr>
 <tr>
+<td>\code{&lt;ext&gt;}</td>
+<td>translated to {@code ...}; code language extension is ignored</td>
+</tr>
+<tr>
 <td>\cond</td>
 <td>translated to 'Conditional comment: &lt;condition&gt;'</td>
 </tr>
@@ -683,7 +688,7 @@ Here is the list of all Doxygen tags and the description of how they are transla
 </tr>
 <tr>
 <td>\n</td>
-<td>replaced with new line char</td>
+<td>replaced with newline char</td>
 </tr>
 <tr>
 <td>\note</td>
@@ -706,6 +711,10 @@ Here is the list of all Doxygen tags and the description of how they are transla
 <td>translated to @param</td>
 </tr>
 <tr>
+<td>\param[&lt;dir&gt;]</td>
+<td>translated to @param; parameter direction ('in'; 'out'; or 'in,out') is ignored</td>
+</tr>
+<tr>
 <td>\remark</td>
 <td>replaced with 'Remarks:'</td>
 </tr>
@@ -829,155 +838,107 @@ These are suppressed with their content just printed out (if the tag has any
 sense, typically text content).
 Here is the list of these tags:
 </p>
+
 <div class="diagram">
-<table border="0" summary="Unsupported Java Doxygen Tags">
-<tr>
-  <th align="left">Unsupported Doxygen tags</th>
-</tr>
-<tr>
-<td>\addindex</td>
-<td>\addtogroup</td>
-<td>\anchor</td>
-<td>\attention</td>
-</tr>
-<tr>
-<td>\brief</td>
-<td>\bug</td>
-<td>\callgraph</td>
-<td>\callergraph</td>
-</tr>
-<tr>
-<td>\class</td>
-<td>\copybrief</td>
-<td>\copydetails</td>
-<td>\copydoc</td>
-</tr>
-<tr>
-<td>\date</td>
-<td>\def</td>
-<td>\defgroup</td>
-<td>\details</td>
-</tr>
-<tr>
-<td>\dir</td>
-<td>\dontinclude</td>
-<td>\dot</td>
-<td>\dotfile</td>
-</tr>
-<tr>
-<td>\enddot</td>
-<td>\endhtmlonly</td>
-<td>\endinternal</td>
-<td>\endlatexonly</td>
-</tr>
-<tr>
-<td>\endmanonly</td>
-<td>\endmsc</td>
-<td>\endrtfonly</td>
-<td>\endxmlonly</td>
-</tr>
-<tr>
-<td>\enum</td>
-<td>\example</td>
-<td>\extends</td>
-</tr>
-<tr>
-<td>\file</td>
-<td>\fn</td>
-<td>\headerfile</td>
-<td>\hideinitializer</td>
-</tr>
-<tr>
-<td>\htmlinclude</td>
-<td>\htmlonly</td>
-<td>\implements</td>
-<td>\include</td>
-</tr>
-<tr>
-<td>\includelineno</td>
-<td>\ingroup</td>
-<td>\internal</td>
-<td>\invariant</td>
-</tr>
-<tr>
-<td>\interface</td>
-<td>\latexonly</td>
-<td>\line</td>
-<td>\mainpage</td>
-</tr>
-<tr>
-<td>\manonly</td>
-<td>\memberof</td>
-<td>\msc</td>
-<td>\mscfile</td>
-</tr>
-<tr>
-<td>\name</td>
-<td>\namespace</td>
-<td>\nosubgrouping</td>
-<td>\package</td>
-</tr>
-<tr>
-<td>\page</td>
-<td>\paragraph</td>
-<td>\post</td>
-<td>\pre</td>
-</tr>
-<tr>
-<td>\private</td>
-<td>\privatesection</td>
-<td>\property</td>
-<td>\protected</td>
-</tr>
-<tr>
-<td>\protectedsection</td>
-<td>\protocol</td>
-<td>\public</td>
-<td>\publicsection</td>
-</tr>
-<tr>
-<td>\ref</td>
-<td>\related</td>
-<td>\relates</td>
-<td>\relatedalso</td>
-</tr>
-<tr>
-<td>\relatesalso</td>
-<td>\retval</td>
-<td>\rtfonly</td>
-<td>\section</td>
-</tr>
-<tr>
-<td>\short</td>
-<td>\showinitializer</td>
-<td>\skip</td>
-<td>\skipline</td>
-</tr>
-<tr>
-<td>\snippet</td>
-<td>\struct</td>
-<td>\subpage</td>
-<td>\subsection</td>
-</tr>
-<tr>
-<td>\subsubsection</td>
-<td>\tableofcontents</td>
-<td>\test</td>
-<td>\typedef</td>
-</tr>
-<tr>
-<td>\union</td>
-<td>\until</td>
-<td>\var</td>
-<td>\verbinclude</td>
-</tr>
-<tr>
-<td>\weakgroup</td>
-<td>\xmlonly</td>
-<td>\xrefitem</td>
-<td>\category</td>
-</tr>
-</table>
+  <b>Unsupported Doxygen tags</b>
+
+  <ul style="list-style-type:none;column-count:4;">
+    <li>\addindex</li>
+    <li>\addtogroup</li>
+    <li>\anchor</li>
+    <li>\attention</li>
+    <li>\brief</li>
+    <li>\bug</li>
+    <li>\callergraph</li>
+    <li>\callgraph</li>
+    <li>\category</li>
+    <li>\class</li>
+    <li>\copybrief</li>
+    <li>\copydetails</li>
+    <li>\copydoc</li>
+    <li>\date</li>
+    <li>\def</li>
+    <li>\defgroup</li>
+    <li>\details</li>
+    <li>\dir</li>
+    <li>\dontinclude</li>
+    <li>\dot</li>
+    <li>\dotfile</li>
+    <li>\enddot</li>
+    <li>\endhtmlonly</li>
+    <li>\endinternal</li>
+    <li>\endlatexonly</li>
+    <li>\endmanonly</li>
+    <li>\endmsc</li>
+    <li>\endrtfonly</li>
+    <li>\endxmlonly</li>
+    <li>\enum</li>
+    <li>\example</li>
+    <li>\extends</li>
+    <li>\file</li>
+    <li>\fn</li>
+    <li>\headerfile</li>
+    <li>\hideinitializer</li>
+    <li>\htmlinclude</li>
+    <li>\htmlonly</li>
+    <li>\implements</li>
+    <li>\include</li>
+    <li>\includelineno</li>
+    <li>\ingroup</li>
+    <li>\interface</li>
+    <li>\internal</li>
+    <li>\invariant</li>
+    <li>\latexonly</li>
+    <li>\line</li>
+    <li>\mainpage</li>
+    <li>\manonly</li>
+    <li>\memberof</li>
+    <li>\msc</li>
+    <li>\mscfile</li>
+    <li>\name</li>
+    <li>\namespace</li>
+    <li>\nosubgrouping</li>
+    <li>\package</li>
+    <li>\page</li>
+    <li>\paragraph</li>
+    <li>\post</li>
+    <li>\pre</li>
+    <li>\private</li>
+    <li>\privatesection</li>
+    <li>\property</li>
+    <li>\protected</li>
+    <li>\protectedsection</li>
+    <li>\protocol</li>
+    <li>\public</li>
+    <li>\publicsection</li>
+    <li>\ref</li>
+    <li>\related</li>
+    <li>\relatedalso</li>
+    <li>\relates</li>
+    <li>\relatesalso</li>
+    <li>\retval</li>
+    <li>\rtfonly</li>
+    <li>\section</li>
+    <li>\short</li>
+    <li>\showinitializer</li>
+    <li>\skip</li>
+    <li>\skipline</li>
+    <li>\snippet</li>
+    <li>\struct</li>
+    <li>\subpage</li>
+    <li>\subsection</li>
+    <li>\subsubsection</li>
+    <li>\tableofcontents</li>
+    <li>\test</li>
+    <li>\typedef</li>
+    <li>\union</li>
+    <li>\until</li>
+    <li>\var</li>
+    <li>\verbinclude</li>
+    <li>\weakgroup</li>
+    <li>\xmlonly</li>
+    <li>\xrefitem</li>
+  </ul>
 </div>
 
 <p>
@@ -987,68 +948,47 @@ comment, the whole comment block is ignored:
 <!-- see parser.y, function isStructuralDoxygen() -->
 
 </p>
-<div class="diagram">
-<table border="0" summary="Ignored Java Doxygen Tags">
-<tr>
-  <th align="left">Ignored Doxygen tags</th>
-</tr>
-<tr>
-<td>\addtogroup</td>
-<td>\callgraph</td>
-<td>\callergraph</td>
-<td>\category</td>
-</tr>
-<tr>
-<td>\class</td>
-<td>\def</td>
-<td>\defgroup</td>
-<td>\dir</td>
-</tr>
-<tr>
-<td>\enum</td>
-<td>\example</td>
-<td>\file</td>
-<td>\fn</td>
-</tr>
-<tr>
-<td>\headerfile</td>
-<td>\hideinitializer</td>
-<td>\interface</td>
-<td>\internal</td>
-</tr>
-<tr>
-<td>\mainpage</td>
-<td>\name</td>
-<td>\namespace</td>
-<td>\nosubgrouping</td>
-</tr>
-<tr>
-<td>\overload</td>
-<td>\package</td>
-<td>\page</td>
-<td>\property</td>
-</tr>
-<tr>
-<td>\protocol</td>
-<td>\relates</td>
-<td>\relatesalso</td>
-<td>\showinitializer</td>
-</tr>
-<tr>
-<td>\struct</td>
-<td>\name</td>
-<td>\namespace</td>
-<td>\nosubgrouping</td>
-</tr>
-<tr>
-<td>\typedef</td>
-<td>\union</td>
-<td>\var</td>
-<td>\weakgroup</td>
-</tr>
 
-</table>
+<div class="diagram">
+  <b>Ignored Doxygen tags</b>
+
+  <ul style="list-style-type:none;column-count:4;">
+    <li>\addtogroup</li>
+    <li>\callergraph</li>
+    <li>\callgraph</li>
+    <li>\category</li>
+    <li>\class</li>
+    <li>\def</li>
+    <li>\defgroup</li>
+    <li>\dir</li>
+    <li>\enum</li>
+    <li>\example</li>
+    <li>\file</li>
+    <li>\fn</li>
+    <li>\headerfile</li>
+    <li>\hideinitializer</li>
+    <li>\interface</li>
+    <li>\internal</li>
+    <li>\mainpage</li>
+    <li>\name</li>
+    <li>\namespace</li>
+    <li>\nosubgrouping</li>
+    <li>\overload</li>
+    <li>\package</li>
+    <li>\page</li>
+    <li>\property</li>
+    <li>\protocol</li>
+    <li>\relates</li>
+    <li>\relatesalso</li>
+    <li>\showinitializer</li>
+    <li>\struct</li>
+    <li>\typedef</li>
+    <li>\union</li>
+    <li>\var</li>
+    <li>\weakgroup</li>
+  </ul>
 </div>
+  
 
 
 
@@ -1246,11 +1186,11 @@ Here is the list of all Doxygen tags and the description of how they are transla
 </tr>
 <tr>
 <td>\a</td>
-<td>wrapped with '_'</td>
+<td>wrapped with '*'</td>
 </tr>
 <tr>
 <td>\arg</td>
-<td>prepended with ' --'</td>
+<td>prepended with ''</td>
 </tr>
 <tr>
 <td>\author</td>
@@ -1258,17 +1198,29 @@ Here is the list of all Doxygen tags and the description of how they are transla
 </tr>
 <tr>
 <td>\authors</td>
-<td>prints 'Author:'</td>
+<td>prints 'Authors:'</td>
 </tr>
 <tr>
 <td>\b</td>
-<td>wrapped with '__'</td>
+<td>wrapped with '**'</td>
+</tr>
+<tr>
+<td>\c</td>
+<td>wrapped with '``'</td>
 </tr>
 <tr>
 <td>\cite</td>
 <td>wrapped with single quotes</td>
 </tr>
 <tr>
+<td>\code</td>
+<td>replaced with '.. code-block:: c++'</td>
+</tr>
+<tr>
+<td>\code{&lt;ext&gt;}</td>
+<td>replaced with '.. code-block:: &lt;lang&gt;', where the following doxygen code languages are recognized: .c -&gt; C, .py -&gt; python, .java &gt; java</td>
+</tr>
+<tr>
 <td>\cond</td>
 <td>translated to 'Conditional comment: &lt;condition&gt;'</td>
 </tr>
@@ -1282,7 +1234,7 @@ Here is the list of all Doxygen tags and the description of how they are transla
 </tr>
 <tr>
 <td>\e</td>
-<td>wrapped with '_'</td>
+<td>wrapped with '*'</td>
 </tr>
 <tr>
 <td>\else</td>
@@ -1294,7 +1246,7 @@ Here is the list of all Doxygen tags and the description of how they are transla
 </tr>
 <tr>
 <td>\em</td>
-<td>wrapped with '_'</td>
+<td>wrapped with '*'</td>
 </tr>
 <tr>
 <td>\endcond</td>
@@ -1305,8 +1257,24 @@ Here is the list of all Doxygen tags and the description of how they are transla
 <td>replaced with '}'</td>
 </tr>
 <tr>
+<td>\example</td>
+<td>replaced with 'Example:'</td>
+</tr>
+<tr>
 <td>\exception</td>
-<td>replaced with 'Throws:'</td>
+<td>replaced with ':raises:'</td>
+</tr>
+<tr>
+<td>\f$</td>
+<td>rendered using ':math:``'</td>
+</tr>
+<tr>
+<td>\f[</td>
+<td>rendered using '.. math::'</td>
+</tr>
+<tr>
+<td>\f{</td>
+<td>rendered using '.. math::'</td>
 </tr>
 <tr>
 <td>\if</td>
@@ -1318,11 +1286,11 @@ Here is the list of all Doxygen tags and the description of how they are transla
 </tr>
 <tr>
 <td>\li</td>
-<td>prepended with ' --'</td>
+<td>prepended with ''</td>
 </tr>
 <tr>
 <td>\n</td>
-<td>replaced with new line char</td>
+<td>replaced with newline char</td>
 </tr>
 <tr>
 <td>\note</td>
@@ -1333,12 +1301,20 @@ Here is the list of all Doxygen tags and the description of how they are transla
 <td>prints 'This is an overloaded ...' according to Doxygen docs</td>
 </tr>
 <tr>
+<td>\p</td>
+<td>wrapped with '``'</td>
+</tr>
+<tr>
 <td>\par</td>
 <td>replaced with 'Title: ...'</td>
 </tr>
 <tr>
 <td>\param</td>
-<td>translated to 'Arguments:\n param(type) --description'</td>
+<td>add ':type:' and ':param:' directives</td>
+</tr>
+<tr>
+<td>\param[&lt;dir&gt;]</td>
+<td>same as \param, but direction ('in'; 'out'; 'in,out') is included in ':type:' directive</td>
 </tr>
 <tr>
 <td>\remark</td>
@@ -1350,15 +1326,15 @@ Here is the list of all Doxygen tags and the description of how they are transla
 </tr>
 <tr>
 <td>\result</td>
-<td>replaced with 'Result:'</td>
+<td>add ':rtype:' and ':return:' directives</td>
 </tr>
 <tr>
 <td>\return</td>
-<td>replaced with 'Result:'</td>
+<td>add ':rtype:' and ':return:' directives</td>
 </tr>
 <tr>
 <td>\returns</td>
-<td>replaced with 'Result:'</td>
+<td>add ':rtype:' and ':return:' directives</td>
 </tr>
 <tr>
 <td>\sa</td>
@@ -1374,11 +1350,11 @@ Here is the list of all Doxygen tags and the description of how they are transla
 </tr>
 <tr>
 <td>\throw</td>
-<td>replaced with 'Throws:'</td>
+<td>replaced with ':raises:'</td>
 </tr>
 <tr>
 <td>\throws</td>
-<td>replaced wih 'Throws:'</td>
+<td>replaced wih ':raises:'</td>
 </tr>
 <tr>
 <td>\todo</td>
@@ -1386,7 +1362,11 @@ Here is the list of all Doxygen tags and the description of how they are transla
 </tr>
 <tr>
 <td>\tparam</td>
-<td>translated to 'Arguments:\n param(type) --description'</td>
+<td>add ':type:' and ':param:' directives</td>
+</tr>
+<tr>
+<td>\verbatim</td>
+<td>content copied verbatim</td>
 </tr>
 <tr>
 <td>\version</td>
@@ -1458,177 +1438,109 @@ are suppressed with their content just printed out (if it has any
 sense, typically text content).
 Here is the list of these tags:
 </p>
+
 <div class="diagram">
-<table border="0" summary="Unsupported Python Doxygen Tags">
-<tr>
-  <th align="left">Unsupported Doxygen tags</th>
-</tr>
-<tr>
-<td>\addindex</td>
-<td>\addtogroup</td>
-<td>\anchor</td>
-<td>\attention</td>
-</tr>
-<tr>
-<td>\brief</td>
-<td>\bug</td>
-<td>\callgraph</td>
-<td>\callergraph</td>
-</tr>
-<tr>
-<td>\class</td>
-<td>\copybrief</td>
-<td>\copydetails</td>
-<td>\copydoc</td>
-</tr>
-<tr>
-<td>\date</td>
-<td>\def</td>
-<td>\defgroup</td>
-<td>\details</td>
-</tr>
-<tr>
-<td>\dir</td>
-<td>\dontinclude</td>
-<td>\dot</td>
-<td>\dotfile</td>
-</tr>
-<tr>
-<td>\code</td>
-<td>\endcode</td>
-<td>\endverbatim</td>
-<td>\endlink</td>
-</tr>
-<tr>
-<td>\enddot</td>
-<td>\endhtmlonly</td>
-<td>\endinternal</td>
-<td>\endlatexonly</td>
-</tr>
-<tr>
-<td>\endmanonly</td>
-<td>\endmsc</td>
-<td>\endrtfonly</td>
-<td>\endxmlonly</td>
-</tr>
-<tr>
-<td>\enum</td>
-<td>\example</td>
-<td>\extends</td>
-<td>\f$</td>
-</tr>
-<tr>
-<td>\f[</td>
-<td>\f]</td>
-<td>\f{</td>
-<td>\f}</td>
-</tr>
-<tr>
-<td>\file</td>
-<td>\fn</td>
-<td>\headerfile</td>
-<td>\hideinitializer</td>
-</tr>
-<tr>
-<td>\htmlinclude</td>
-<td>\htmlonly</td>
-<td>\implements</td>
-<td>\include</td>
-</tr>
-<tr>
-<td>\image</td>
-<td>\link</td>
-<td>\verbatim</td>
-<td>\p</td>
-</tr>
-<tr>
-<td>\includelineno</td>
-<td>\ingroup</td>
-<td>\internal</td>
-<td>\invariant</td>
-</tr>
-<tr>
-<td>\interface</td>
-<td>\latexonly</td>
-<td>\line</td>
-<td>\mainpage</td>
-</tr>
-<tr>
-<td>\manonly</td>
-<td>\memberof</td>
-<td>\msc</td>
-<td>\mscfile</td>
-</tr>
-<tr>
-<td>\name</td>
-<td>\namespace</td>
-<td>\nosubgrouping</td>
-<td>\package</td>
-</tr>
-<tr>
-<td>\page</td>
-<td>\paragraph</td>
-<td>\post</td>
-<td>\pre</td>
-</tr>
-<tr>
-<td>\private</td>
-<td>\privatesection</td>
-<td>\property</td>
-<td>\protected</td>
-</tr>
-<tr>
-<td>\protectedsection</td>
-<td>\protocol</td>
-<td>\public</td>
-<td>\publicsection</td>
-</tr>
-<tr>
-<td>\ref</td>
-<td>\related</td>
-<td>\relates</td>
-<td>\relatedalso</td>
-</tr>
-<tr>
-<td>\relatesalso</td>
-<td>\retval</td>
-<td>\rtfonly</td>
-<td>\section</td>
-</tr>
-<tr>
-<td>\short</td>
-<td>\showinitializer</td>
-<td>\skip</td>
-<td>\skipline</td>
-</tr>
-<tr>
-<td>\snippet</td>
-<td>\struct</td>
-<td>\subpage</td>
-<td>\subsection</td>
-</tr>
-<tr>
-<td>\subsubsection</td>
-<td>\tableofcontents</td>
-<td>\test</td>
-<td>\typedef</td>
-</tr>
-<tr>
-<td>\union</td>
-<td>\until</td>
-<td>\var</td>
-<td>\verbinclude</td>
-</tr>
-<tr>
-<td>\weakgroup</td>
-<td>\xmlonly</td>
-<td>\xrefitem</td>
-<td>\category</td>
-</tr>
-<tr>
-<td>\c</td>
-</tr>
-</table>
+  <b>Unsupported Python Doxygen tags</b>
+
+  <ul style="list-style-type:none;column-count:4;">
+    <li>\addindex</li>
+    <li>\addtogroup</li>
+    <li>\anchor</li>
+    <li>\attention</li>
+    <li>\brief</li>
+    <li>\bug</li>
+    <li>\callergraph</li>
+    <li>\callgraph</li>
+    <li>\category</li>
+    <li>\class</li>
+    <li>\copybrief</li>
+    <li>\copydetails</li>
+    <li>\copydoc</li>
+    <li>\date</li>
+    <li>\def</li>
+    <li>\defgroup</li>
+    <li>\details</li>
+    <li>\dir</li>
+    <li>\dontinclude</li>
+    <li>\dot</li>
+    <li>\dotfile</li>
+    <li>\enddot</li>
+    <li>\endhtmlonly</li>
+    <li>\endinternal</li>
+    <li>\endlatexonly</li>
+    <li>\endlink</li>
+    <li>\endmanonly</li>
+    <li>\endmsc</li>
+    <li>\endrtfonly</li>
+    <li>\endxmlonly</li>
+    <li>\enum</li>
+    <li>\extends</li>
+    <li>\file</li>
+    <li>\fn</li>
+    <li>\headerfile</li>
+    <li>\hideinitializer</li>
+    <li>\htmlinclude</li>
+    <li>\htmlonly</li>
+    <li>\image</li>
+    <li>\implements</li>
+    <li>\include</li>
+    <li>\includelineno</li>
+    <li>\ingroup</li>
+    <li>\interface</li>
+    <li>\internal</li>
+    <li>\invariant</li>
+    <li>\latexonly</li>
+    <li>\line</li>
+    <li>\link</li>
+    <li>\mainpage</li>
+    <li>\manonly</li>
+    <li>\memberof</li>
+    <li>\msc</li>
+    <li>\mscfile</li>
+    <li>\name</li>
+    <li>\namespace</li>
+    <li>\nosubgrouping</li>
+    <li>\package</li>
+    <li>\page</li>
+    <li>\paragraph</li>
+    <li>\post</li>
+    <li>\pre</li>
+    <li>\private</li>
+    <li>\privatesection</li>
+    <li>\property</li>
+    <li>\protected</li>
+    <li>\protectedsection</li>
+    <li>\protocol</li>
+    <li>\public</li>
+    <li>\publicsection</li>
+    <li>\ref</li>
+    <li>\related</li>
+    <li>\relatedalso</li>
+    <li>\relates</li>
+    <li>\relatesalso</li>
+    <li>\retval</li>
+    <li>\rtfonly</li>
+    <li>\section</li>
+    <li>\short</li>
+    <li>\showinitializer</li>
+    <li>\skip</li>
+    <li>\skipline</li>
+    <li>\snippet</li>
+    <li>\struct</li>
+    <li>\subpage</li>
+    <li>\subsection</li>
+    <li>\subsubsection</li>
+    <li>\tableofcontents</li>
+    <li>\test</li>
+    <li>\typedef</li>
+    <li>\union</li>
+    <li>\until</li>
+    <li>\var</li>
+    <li>\verbinclude</li>
+    <li>\weakgroup</li>
+    <li>\xmlonly</li>
+    <li>\xrefitem</li>
+  </ul>
 </div>
 
 <H3><a name="Doxygen_python_further_details">17.4.4 Further details</a></H3>
index 6633eaa..431ac1c 100644 (file)
@@ -145,7 +145,7 @@ The <tt>-elua</tt> option puts all the C function wrappers and variable get/set
 The following table list the additional commandline options available for the Lua module. They can also be seen by using: 
 </p>
 
-<div class="code"><pre>
+<div class="shell"><pre>
 swig -lua -help 
 </pre></div>
 
@@ -747,7 +747,8 @@ Stout
 <p>
 Class data members are accessed in the same manner as C structures. Static class members present a special problem for Lua, as Lua doesn't have support for such features. Therefore, SWIG generates wrappers that try to work around some of these issues. To illustrate, suppose you have a class like this:
 </p>
-<div class="targetlang"><pre>class Spam {
+<div class="code"><pre>
+class Spam {
 public:
   static void foo();
   static int bar;
@@ -756,7 +757,7 @@ public:
 <p>
 In Lua, C++ static members can be accessed as follows:
 </p>
-<div class="code"><pre>
+<div class="targetlang"><pre>
 &gt; example.Spam.foo()            -- calling Spam::foo()
 &gt; a=example.Spam.bar            -- reading Spam::bar 
 &gt; example.Spam.bar=b            -- writing to Spam::bar
@@ -774,7 +775,7 @@ It is not (currently) possible to access static members of an instance:
 <b>Compatibility Note:</b> In versions prior to SWIG-3.0.0 only the following names would work:
 </p>
 
-<div class="code"><pre>
+<div class="targetlang"><pre>
 &gt; example.Spam_foo()            -- calling Spam::foo()
 &gt; a=example.Spam_bar            -- reading Spam::bar 
 &gt; example.Spam_bar=b            -- writing to Spam::bar
@@ -964,7 +965,8 @@ When wrapped, it works like you expect:
 <p>
 One restriction with operator overloading support is that SWIG is not able to fully handle operators that aren't defined as part of the class. For example, if you had code like this
 </p>
-<div class="targetlang"><pre>class Complex {
+<div class="code"><pre>
+class Complex {
 ...
 friend Complex operator+(double, const Complex &amp;c);
 ...
@@ -973,7 +975,8 @@ friend Complex operator+(double, const Complex &amp;c);
 <p>
 then SWIG doesn't know what to do with the friend function--in fact, it simply ignores it and issues a warning. You can still wrap the operator, but you may have to encapsulate it in a special function. For example:
 </p>
-<div class="targetlang"><pre>%rename(Complex_add_dc) operator+(double, const Complex &amp;);
+<div class="code"><pre>
+%rename(Complex_add_dc) operator+(double, const Complex &amp;);
 ...
 Complex operator+(double, const Complex &amp;c);
 </pre></div>
@@ -1446,6 +1449,7 @@ Those names are in a form <tt>$classname_$symbolname</tt> and are added to the s
 If %nspace is enabled, then class namespace is taken as scope. If there is no namespace, or %nspace is disabled,
 then module is considered a class namespace.</p>
 <p> Consider the following C++ code </p>
+
 <div class="code"><pre>%module example
 %nspace MyWorld::Test;
 namespace MyWorld {
@@ -1486,6 +1490,7 @@ surrounding scope without any prefixing. Pretending that Test2 is a struct, not
 
 <p> The internal organization of inheritance has changed. 
 Consider the following C++ code:</p>
+
 <div class="code"><pre>%module example
 class Base {
   public:
@@ -1502,6 +1507,7 @@ were squashed and added to corresponding derived class <tt>ST</tt>: Everything f
 was copied to <tt>.fn</tt> table of class Derived and so on. This was a recursive procedure, so in the end the whole
 inheritance tree of derived class was squashed into derived class. </p>
 <p> That means that any changes done to class Base after module initialization wouldn't affect class Derived:</p>
+
 <div class="targetlang"><pre>
 base = example.Base()
 der = example.Derived()
@@ -1516,6 +1522,8 @@ nil
 </pre></div>
 <p> This behaviour was changed. Now unless -squash-bases option is provided, Derived store a list of it's bases and if some symbol is not found in it's own service tables
 then its bases are searched for it. Option -squash-bases will effectively return old behaviour.
+</p>
+
 <div class="targetlang"><pre>
 &gt; print(der.new_func) -- Now it works
 function
index 3d1bb45..66061a5 100644 (file)
@@ -110,11 +110,13 @@ SWIG_VERSION                    Hexadecimal (binary-coded decimal) number contai
                                 such as 0x010311 (corresponding to SWIG-1.3.11).
 
 SWIGCSHARP                      Defined when using C#
+SWIGD                           Defined when using D
+SWIGGO                          Defined when using Go
 SWIGGUILE                       Defined when using Guile
 SWIGJAVA                        Defined when using Java
 SWIGJAVASCRIPT                  Defined when using Javascript
-SWIG_JAVASCRIPT_JSC             Defined when using Javascript for JavascriptCore
-SWIG_JAVASCRIPT_V8              Defined when using Javascript for v8 or node.js 
+SWIG_JAVASCRIPT_JSC             Defined when using Javascript with -jsc
+SWIG_JAVASCRIPT_V8              Defined when using Javascript with -v8 or -node
 SWIGLUA                         Defined when using Lua
 SWIGMZSCHEME                    Defined when using Mzscheme
 SWIGOCAML                       Defined when using OCaml
@@ -144,11 +146,23 @@ __cplusplus                     Defined when -c++ option used
 </div>
 
 <p>
+The following are language specific symbols that might be defined:
+</p>
+
+<div class="code"><pre>
+SWIG_D_VERSION                  Unsigned integer target version when using D
+SWIGGO_CGO                      Defined when using Go for cgo
+SWIGGO_GCCGO                    Defined when using Go for gccgo
+SWIGGO_INTGO_SIZE               Size of the Go type int when using Go (32 or 64)
+SWIGPYTHON_PY3                  Defined when using Python with -py3
+SWIGPYTHON_BUILTIN              Defined when using Python with -builtin
+SWIG_RUBY_AUTORENAME            Defined when using Ruby with -autorename
+</pre></div>
+
+<p>
 Interface files can look at these symbols as necessary to change the
 way in which an interface is generated or to mix SWIG directives with
-C code. These symbols are also defined within the C code generated by
-SWIG (except for the symbol `<tt>SWIG</tt>' which is only defined
-within the SWIG compiler).
+C code.
 </p>
 
 <H2><a name="Preprocessor_nn5">10.4 Macro Expansion</a></H2>
index 373cd7e..d0713ca 100644 (file)
@@ -17,6 +17,9 @@
 <li><a href="#R_nn5">General policy</a>
 <li><a href="#R_language_conventions">Language conventions</a>
 <li><a href="#R_nn6">C++ classes</a>
+<ul>
+<li><a href="#R_class_examples">Examples</a>
+</ul>
 <li><a href="#R_nn7">Enumerations</a>
 </ul>
 </div>
@@ -33,7 +36,11 @@ href="http://www.r-project.org/">www.r-project.org</a>.
 <p>
 The R bindings are under active development.  They have been used to
 compile and run an R interface to QuantLib running on Mandriva Linux
-with gcc. The R bindings also work on Microsoft Windows using Visual C++.
+with gcc. They are also used to create the SimpleITK R package, which
+runs on Linux and MacOS. SWIG is used to create all wrapper
+interfaces
+to <a href="http://http://www.simpleitk.org/">SimpleITK</a>.  The R
+bindings also work on Microsoft Windows using Visual C++.
 </p>
 
 <H2><a name="R_nn2">33.1 Bugs</a></H2>
@@ -44,7 +51,9 @@ Currently the following features are not implemented or broken:
 </p>
 
 <ul>
-<li>Garbage collection of created objects
+<li>Garbage collection of some created objects. Finalizers are
+  available for wrapped C++ classes and are called by the
+  garbage collection system.
 <li>C Array wrappings
 </ul>
 
@@ -158,7 +167,10 @@ This will generate a compiled R file called BigFile.RData that
 will save a large amount of loading time.
 </p>
 
-
+<p>
+There is no need to precompile large R files if the SWIG-generated code is being included
+in an R package. The package infrastructure provides this service during package installation.
+</p>
 
 <H2><a name="R_nn5">33.4 General policy</a></H2>
 
@@ -173,7 +185,7 @@ to provide R syntax.
 
 
 <p>
-getitem and setitem use C++ conventions (i.e. zero based indices). [<-
+getitem and setitem use C++ conventions (i.e. zero based indices). [&lt;-
 and [ are overloaded to allow for R syntax (one based indices and
 slices)
 </p>
@@ -182,14 +194,122 @@ slices)
 
 
 <p>
-C++ objects are implemented as external pointer objects with the class
-being the mangled name of the class. The C++ classes are encapsulated
-as an SEXP with an external pointer type. The class is the mangled
-name of the class. The nice thing about R is that is allows you to
-keep track of the pointer object which removes the necessity for a lot
-of the proxy class baggage you see in other languages.
+Wrapping of C++ classes for R works quite well. R has a special
+type, known as an external reference, that can be used as a pointer
+to arbitary things, including C++ classes. The proxy layers generated
+for other classes are not required.
+</p>
+
+<p>
+  SWIG currently creates a custom hierarchy of R classes derived from the
+  external reference type and implements
+type checking and function overloading in the R code it generates. In
+the future we hope to utilise the built in R6 class structures.
+</p>
+
+<p>
+The R interface has the following capabilities:
+</p>
+<ul>
+  <li> Destructor methods are registered and called automatically by the R garbage collector.
+<li> A range of std::vector types are converted automatically to R equivalents via the std_vector.i library.
+<li> The $ operator is used for method access.
+<li> Variable accessors are automatically generated and called via the $, [, [[, $&lt;-,  [&lt;-, [[&lt;- operators.
+</ul>
+
+<H3><a name="R_class_examples">33.6.1 Examples</a></H3>
+
+
+<p>
+Consider the following simple example:
 </p>
 
+<div class="code">
+  <pre>
+class Vehicle {
+private:
+  int m_axles;
+
+public:
+  int Axles() {
+    return(m_axles);
+  }
+
+  bool Available;
+
+  Vehicle() {
+    Available=false;
+    m_axles=2;
+  }
+
+  Vehicle(int ax) {
+    Available=false;
+    m_axles=ax;
+  }
+};
+</pre>
+</div>
+
+<p>
+The following options are available in R:
+</p>
+
+<div class="code">
+<pre>
+v1 &lt;- Vehicle()
+v2 &lt;- Vehicle(4)
+# access members
+v1$Axles()
+[1] 2
+v2$Axles
+[1] 4
+v1$Available
+[1] FALSE
+# Set availabilty
+v1$Available &lt;- TRUE
+v1$Available
+[1] TRUE
+</pre>
+</div>
+  
+<p>
+A useful trick to determine the methods that are available is to
+query the R method definition as follows:
+</p>
+
+<div class="code">
+  <pre>
+# display the methods for the class
+getMethod("$", class(v1))
+    
+Method Definition:
+
+function (x, name) 
+{
+    accessorFuns = list(Axles = Vehicle_Axles, Available = Vehicle_Available_get)
+    vaccessors = c("Available")
+    idx = pmatch(name, names(accessorFuns))
+    if (is.na(idx)) 
+        return(callNextMethod(x, name))
+    f = accessorFuns[[idx]]
+    if (is.na(match(name, vaccessors))) 
+        function(...) {
+            f(x, ...)
+        }
+    else f(x)
+}
+
+Signatures:
+        x           
+target  "_p_Vehicle"
+defined "_p_Vehicle"
+
+</pre>
+</div>
+<p>
+The names in the <tt>accessorFuns</tt> list correspond to class methods while names in the <tt>vaccessors</tt> section
+correspond to variables that may be modified.
+</p>
 <H2><a name="R_nn7">33.7 Enumerations</a></H2>
 
 
index 3cfd129..6939a8a 100644 (file)
@@ -615,6 +615,24 @@ directive. For example: </p>
 effect until it is explicitly disabled using <tt>%mutable</tt>.
 </p>
 
+<p>Note: When SWIG is invoked with the <tt>-globalmodule</tt> option in
+effect, the C/C++ global variables will be translated into Ruby global
+variables. Type-checking and the optional read-only characteristic are
+available in the same way as described above. However the example would
+then have to be modified and executed in the following way:
+
+<div class="code targetlang">
+<pre>$ <b>irb</b>
+irb(main):001:0&gt; <b>require 'Example'</b>
+true
+irb(main):002:0&gt; <b>$variable1 = 2</b>
+2
+irb(main):003:0&gt; <b>$Variable2 = 4 * 10.3</b>
+41.2
+irb(main):004:0&gt; <b>$Variable2</b>
+41.2</pre>
+</div>
+
 <H3><a name="Ruby_nn15">34.3.4 Constants</a></H3>
 
 
index aec48ef..c54d117 100644 (file)
@@ -827,6 +827,32 @@ However, for the same conservative reasons even a constant with a simple cast wi
 </div>
 
 <p>
+This logic can lead to false attempts at converting <tt>#define</tt> into <tt>%constant</tt> though.
+For example the following case does not have any undefined symbols within the macro:
+</p>
+
+<div class="code">
+<pre>
+// For indicating pure virtual functions such as: virtual void f() PURE;
+#define PURE = 0
+</pre>
+</div>
+
+<p>
+A warning is issued:
+</p>
+
+<div class="shell">
+<pre>
+pure.h:1: Warning 305: Bad constant value (ignored).
+</pre>
+</div>
+
+<p>
+In such cases simply ignore the warning or suppress it using the normal warning suppression techniques.
+</p>
+
+<p>
 The use of constant expressions is allowed, but SWIG does not evaluate
 them. Rather, it passes them through to the output file and lets the C
 compiler perform the final evaluation (SWIG does perform a limited
index 31f691a..ef3d01a 100644 (file)
@@ -72,6 +72,10 @@ div.diagram {
   font-family: "Courier New", Courier, "Courier 10 Pitch", monospace;
 }
 
+div.diagram li {
+    margin-left: 0;
+}
+
 ul li p {
   margin-left: 0;
   margin-right: 0;
@@ -1809,7 +1813,11 @@ body { font-family: serif; }
 <li><a HREF="#R_nn4">33.3 Precompiling large R files</a></li>
 <li><a HREF="#R_nn5">33.4 General policy</a></li>
 <li><a HREF="#R_language_conventions">33.5 Language conventions</a></li>
-<li><a HREF="#R_nn6">33.6 C++ classes</a></li>
+<li><a HREF="#R_nn6">33.6 C++ classes</a>
+<ul>
+<li><a HREF="#R_class_examples">33.6.1 Examples</a></li>
+</ul>
+</li>
 <li><a HREF="#R_nn7">33.7 Enumerations</a></li>
 </ul>
 <b><a HREF="#Ruby">34 SWIG and Ruby</a></b>
@@ -2279,7 +2287,7 @@ body { font-family: serif; }
 </ul>
 <HR NOSHADE>
 <h1><a name="Sections">SWIG-4.0 Documentation</a></h1>
-<p> Last update : SWIG-4.0.1 (21 Aug 2019)</p>
+<p> Last update : SWIG-4.0.2 (8 Jun 2020)</p>
 <h2><a name="Sections_Sections">Sections</a></h2>
 <h3><a name="Sections_core_docs">SWIG Core Documentation</a></h3>
 <ul>
@@ -4492,6 +4500,23 @@ EXTERN</tt> (what would the value be?). In general, SWIG will not create
 #define F_CONST (double) 5            // A floating point constant with cast
 </pre>
 </div>
+<p> This logic can lead to false attempts at converting <tt>#define</tt>
+ into <tt>%constant</tt> though. For example the following case does not
+ have any undefined symbols within the macro:</p>
+<div class="code">
+<pre>
+// For indicating pure virtual functions such as: virtual void f() PURE;
+#define PURE = 0
+</pre>
+</div>
+<p> A warning is issued:</p>
+<div class="shell">
+<pre>
+pure.h:1: Warning 305: Bad constant value (ignored).
+</pre>
+</div>
+<p> In such cases simply ignore the warning or suppress it using the
+ normal warning suppression techniques.</p>
 <p> The use of constant expressions is allowed, but SWIG does not
  evaluate them. Rather, it passes them through to the output file and
  lets the C compiler perform the final evaluation (SWIG does perform a
@@ -12440,11 +12465,13 @@ SWIG_VERSION                    Hexadecimal (binary-coded decimal) number contai
                                 such as 0x010311 (corresponding to SWIG-1.3.11).
 
 SWIGCSHARP                      Defined when using C#
+SWIGD                           Defined when using D
+SWIGGO                          Defined when using Go
 SWIGGUILE                       Defined when using Guile
 SWIGJAVA                        Defined when using Java
 SWIGJAVASCRIPT                  Defined when using Javascript
-SWIG_JAVASCRIPT_JSC             Defined when using Javascript for JavascriptCore
-SWIG_JAVASCRIPT_V8              Defined when using Javascript for v8 or node.js 
+SWIG_JAVASCRIPT_JSC             Defined when using Javascript with -jsc
+SWIG_JAVASCRIPT_V8              Defined when using Javascript with -v8 or -node
 SWIGLUA                         Defined when using Lua
 SWIGMZSCHEME                    Defined when using Mzscheme
 SWIGOCAML                       Defined when using OCaml
@@ -12470,11 +12497,21 @@ __STDC__                        Defined to indicate ISO C
 __cplusplus                     Defined when -c++ option used
 </pre>
 </div>
+<p> The following are language specific symbols that might be defined:</p>
+<div class="code">
+<pre>
+SWIG_D_VERSION                  Unsigned integer target version when using D
+SWIGGO_CGO                      Defined when using Go for cgo
+SWIGGO_GCCGO                    Defined when using Go for gccgo
+SWIGGO_INTGO_SIZE               Size of the Go type int when using Go (32 or 64)
+SWIGPYTHON_PY3                  Defined when using Python with -py3
+SWIGPYTHON_BUILTIN              Defined when using Python with -builtin
+SWIG_RUBY_AUTORENAME            Defined when using Ruby with -autorename
+</pre>
+</div>
 <p> Interface files can look at these symbols as necessary to change the
  way in which an interface is generated or to mix SWIG directives with C
- code. These symbols are also defined within the C code generated by
- SWIG (except for the symbol `<tt>SWIG</tt>' which is only defined
- within the SWIG compiler).</p>
+ code.</p>
 <h2><a name="Preprocessor_nn5">10.4 Macro Expansion</a></h2>
 <p> Traditional preprocessor macros can be used in SWIG interfaces. Be
  aware that the <tt>#define</tt> statement is also used to try and
@@ -20742,12 +20779,13 @@ Doxygen.</a> Doxygen comments can be present in your main SWIG interface
 //! Another single-line comment
 </pre>
 </div>
-<p> Also any of the above with '&lt;' added after comment-starting symbol,
- like<i> /**&lt;, /*!&lt;, ///&lt;,</i> or<i> //!&lt;</i> will be treated as a
- post-comment and will be assigned to the code before the comment. Any
- number of '*' or '/' within a Doxygen comment is considered to be a
- separator and is not included in the final comment, so you may safely
- use comments like<i> /*********/</i> or<i> //////////</i>.</p>
+<p> Also any of the above with '<tt>&lt;</tt>' added after comment-starting
+ symbol, like <tt>/**&lt;, /*!&lt;, ///&lt;,</tt> or <tt>//!&lt;</tt> will be
+ treated as a post-comment and will be assigned to the code before the
+ comment. Any number of '<tt>*</tt>' or '<tt>/</tt>' within a Doxygen
+ comment is considered to be a separator and is not included in the
+ final comment, so you may safely use comments like <tt>/*********/</tt>
+ or <tt>//////////</tt>.</p>
 <p> Please note, as SWIG parses the input file by itself with strict
  grammar, there is only a limited support for various cases of comment
  placement in the file.</p>
@@ -21106,6 +21144,8 @@ public class Shape {
 <tr><td>\c</td><td>wrapped with &lt;code&gt; html tag</td></tr>
 <tr><td>\cite</td><td>wrapped with &lt;i&gt; html tag</td></tr>
 <tr><td>\code</td><td>translated to {@code ...}</td></tr>
+<tr><td>\code{&lt;ext&gt;}</td><td>translated to {@code ...}; code language
+ extension is ignored</td></tr>
 <tr><td>\cond</td><td>translated to 'Conditional comment: &lt;condition&gt;'</td>
 </tr>
 <tr><td>\copyright</td><td>replaced with 'Copyright:'</td></tr>
@@ -21129,13 +21169,15 @@ public class Shape {
 </tr>
 <tr><td>\li</td><td>wrapped with &lt;li&gt; html tag</td></tr>
 <tr><td>\link</td><td>translated to {@link ...}</td></tr>
-<tr><td>\n</td><td>replaced with new line char</td></tr>
+<tr><td>\n</td><td>replaced with newline char</td></tr>
 <tr><td>\note</td><td>replaced with 'Note:'</td></tr>
 <tr><td>\overload</td><td>prints 'This is an overloaded ...' according
  to Doxygen docs</td></tr>
 <tr><td>\p</td><td>wrapped with &lt;code&gt; html tag</td></tr>
 <tr><td>\par</td><td>replaced with &lt;p alt='title'&gt;...&lt;/p&gt;</td></tr>
 <tr><td>\param</td><td>translated to @param</td></tr>
+<tr><td>\param[&lt;dir&gt;]</td><td>translated to @param; parameter direction
+ ('in'; 'out'; or 'in,out') is ignored</td></tr>
 <tr><td>\remark</td><td>replaced with 'Remarks:'</td></tr>
 <tr><td>\remarks</td><td>replaced with 'Remarks:'</td></tr>
 <tr><td>\result</td><td>translated to @return</td></tr>
@@ -21172,73 +21214,145 @@ Javadoc documentation</a>). As a result several tags have no translation
  or particular use, such as some linking and section tags. These are
  suppressed with their content just printed out (if the tag has any
  sense, typically text content). Here is the list of these tags:</p>
-<div class="diagram">
-<table border="0" summary="Unsupported Java Doxygen Tags">
-<tr><th align="left">Unsupported Doxygen tags</th></tr>
-<tr><td>\addindex</td><td>\addtogroup</td><td>\anchor</td><td>\attention</td>
-</tr>
-<tr><td>\brief</td><td>\bug</td><td>\callgraph</td><td>\callergraph</td></tr>
-<tr><td>\class</td><td>\copybrief</td><td>\copydetails</td><td>\copydoc</td>
-</tr>
-<tr><td>\date</td><td>\def</td><td>\defgroup</td><td>\details</td></tr>
-<tr><td>\dir</td><td>\dontinclude</td><td>\dot</td><td>\dotfile</td></tr>
-<tr><td>\enddot</td><td>\endhtmlonly</td><td>\endinternal</td><td>
-\endlatexonly</td></tr>
-<tr><td>\endmanonly</td><td>\endmsc</td><td>\endrtfonly</td><td>
-\endxmlonly</td></tr>
-<tr><td>\enum</td><td>\example</td><td>\extends</td></tr>
-<tr><td>\file</td><td>\fn</td><td>\headerfile</td><td>\hideinitializer</td>
-</tr>
-<tr><td>\htmlinclude</td><td>\htmlonly</td><td>\implements</td><td>
-\include</td></tr>
-<tr><td>\includelineno</td><td>\ingroup</td><td>\internal</td><td>
-\invariant</td></tr>
-<tr><td>\interface</td><td>\latexonly</td><td>\line</td><td>\mainpage</td>
-</tr>
-<tr><td>\manonly</td><td>\memberof</td><td>\msc</td><td>\mscfile</td></tr>
-<tr><td>\name</td><td>\namespace</td><td>\nosubgrouping</td><td>\package</td>
-</tr>
-<tr><td>\page</td><td>\paragraph</td><td>\post</td><td>\pre</td></tr>
-<tr><td>\private</td><td>\privatesection</td><td>\property</td><td>
-\protected</td></tr>
-<tr><td>\protectedsection</td><td>\protocol</td><td>\public</td><td>
-\publicsection</td></tr>
-<tr><td>\ref</td><td>\related</td><td>\relates</td><td>\relatedalso</td></tr>
-<tr><td>\relatesalso</td><td>\retval</td><td>\rtfonly</td><td>\section</td>
-</tr>
-<tr><td>\short</td><td>\showinitializer</td><td>\skip</td><td>\skipline</td>
-</tr>
-<tr><td>\snippet</td><td>\struct</td><td>\subpage</td><td>\subsection</td>
-</tr>
-<tr><td>\subsubsection</td><td>\tableofcontents</td><td>\test</td><td>
-\typedef</td></tr>
-<tr><td>\union</td><td>\until</td><td>\var</td><td>\verbinclude</td></tr>
-<tr><td>\weakgroup</td><td>\xmlonly</td><td>\xrefitem</td><td>\category</td>
-</tr>
-</table>
+<div class="diagram"><b> Unsupported Doxygen tags</b>
+<ul style="list-style-type:none;column-count:4;">
+<li>\addindex</li>
+<li>\addtogroup</li>
+<li>\anchor</li>
+<li>\attention</li>
+<li>\brief</li>
+<li>\bug</li>
+<li>\callergraph</li>
+<li>\callgraph</li>
+<li>\category</li>
+<li>\class</li>
+<li>\copybrief</li>
+<li>\copydetails</li>
+<li>\copydoc</li>
+<li>\date</li>
+<li>\def</li>
+<li>\defgroup</li>
+<li>\details</li>
+<li>\dir</li>
+<li>\dontinclude</li>
+<li>\dot</li>
+<li>\dotfile</li>
+<li>\enddot</li>
+<li>\endhtmlonly</li>
+<li>\endinternal</li>
+<li>\endlatexonly</li>
+<li>\endmanonly</li>
+<li>\endmsc</li>
+<li>\endrtfonly</li>
+<li>\endxmlonly</li>
+<li>\enum</li>
+<li>\example</li>
+<li>\extends</li>
+<li>\file</li>
+<li>\fn</li>
+<li>\headerfile</li>
+<li>\hideinitializer</li>
+<li>\htmlinclude</li>
+<li>\htmlonly</li>
+<li>\implements</li>
+<li>\include</li>
+<li>\includelineno</li>
+<li>\ingroup</li>
+<li>\interface</li>
+<li>\internal</li>
+<li>\invariant</li>
+<li>\latexonly</li>
+<li>\line</li>
+<li>\mainpage</li>
+<li>\manonly</li>
+<li>\memberof</li>
+<li>\msc</li>
+<li>\mscfile</li>
+<li>\name</li>
+<li>\namespace</li>
+<li>\nosubgrouping</li>
+<li>\package</li>
+<li>\page</li>
+<li>\paragraph</li>
+<li>\post</li>
+<li>\pre</li>
+<li>\private</li>
+<li>\privatesection</li>
+<li>\property</li>
+<li>\protected</li>
+<li>\protectedsection</li>
+<li>\protocol</li>
+<li>\public</li>
+<li>\publicsection</li>
+<li>\ref</li>
+<li>\related</li>
+<li>\relatedalso</li>
+<li>\relates</li>
+<li>\relatesalso</li>
+<li>\retval</li>
+<li>\rtfonly</li>
+<li>\section</li>
+<li>\short</li>
+<li>\showinitializer</li>
+<li>\skip</li>
+<li>\skipline</li>
+<li>\snippet</li>
+<li>\struct</li>
+<li>\subpage</li>
+<li>\subsection</li>
+<li>\subsubsection</li>
+<li>\tableofcontents</li>
+<li>\test</li>
+<li>\typedef</li>
+<li>\union</li>
+<li>\until</li>
+<li>\var</li>
+<li>\verbinclude</li>
+<li>\weakgroup</li>
+<li>\xmlonly</li>
+<li>\xrefitem</li>
+</ul>
 </div>
 <p> If one of the following Doxygen tags appears as the first tag in a
  comment, the whole comment block is ignored:
 <!-- see parser.y, function isStructuralDoxygen() -->
 </p>
-<div class="diagram">
-<table border="0" summary="Ignored Java Doxygen Tags">
-<tr><th align="left">Ignored Doxygen tags</th></tr>
-<tr><td>\addtogroup</td><td>\callgraph</td><td>\callergraph</td><td>
-\category</td></tr>
-<tr><td>\class</td><td>\def</td><td>\defgroup</td><td>\dir</td></tr>
-<tr><td>\enum</td><td>\example</td><td>\file</td><td>\fn</td></tr>
-<tr><td>\headerfile</td><td>\hideinitializer</td><td>\interface</td><td>
-\internal</td></tr>
-<tr><td>\mainpage</td><td>\name</td><td>\namespace</td><td>
-\nosubgrouping</td></tr>
-<tr><td>\overload</td><td>\package</td><td>\page</td><td>\property</td></tr>
-<tr><td>\protocol</td><td>\relates</td><td>\relatesalso</td><td>
-\showinitializer</td></tr>
-<tr><td>\struct</td><td>\name</td><td>\namespace</td><td>\nosubgrouping</td>
-</tr>
-<tr><td>\typedef</td><td>\union</td><td>\var</td><td>\weakgroup</td></tr>
-</table>
+<div class="diagram"><b> Ignored Doxygen tags</b>
+<ul style="list-style-type:none;column-count:4;">
+<li>\addtogroup</li>
+<li>\callergraph</li>
+<li>\callgraph</li>
+<li>\category</li>
+<li>\class</li>
+<li>\def</li>
+<li>\defgroup</li>
+<li>\dir</li>
+<li>\enum</li>
+<li>\example</li>
+<li>\file</li>
+<li>\fn</li>
+<li>\headerfile</li>
+<li>\hideinitializer</li>
+<li>\interface</li>
+<li>\internal</li>
+<li>\mainpage</li>
+<li>\name</li>
+<li>\namespace</li>
+<li>\nosubgrouping</li>
+<li>\overload</li>
+<li>\package</li>
+<li>\page</li>
+<li>\property</li>
+<li>\protocol</li>
+<li>\relates</li>
+<li>\relatesalso</li>
+<li>\showinitializer</li>
+<li>\struct</li>
+<li>\typedef</li>
+<li>\union</li>
+<li>\var</li>
+<li>\weakgroup</li>
+</ul>
 </div>
 <h3><a name="Doxygen_further_details">17.3.4 Further details</a></h3>
 <p> TO BE ADDED.</p>
@@ -21401,47 +21515,58 @@ doxypy</a>) to do the work.</p>
 <div class="diagram">
 <table border="0" summary="Python Doxygen tags">
 <tr><th align="left">Doxygen tags</th></tr>
-<tr><td>\a</td><td>wrapped with '_'</td></tr>
-<tr><td>\arg</td><td>prepended with ' --'</td></tr>
+<tr><td>\a</td><td>wrapped with '*'</td></tr>
+<tr><td>\arg</td><td>prepended with ''</td></tr>
 <tr><td>\author</td><td>prints 'Author:'</td></tr>
-<tr><td>\authors</td><td>prints 'Author:'</td></tr>
-<tr><td>\b</td><td>wrapped with '__'</td></tr>
+<tr><td>\authors</td><td>prints 'Authors:'</td></tr>
+<tr><td>\b</td><td>wrapped with '**'</td></tr>
+<tr><td>\c</td><td>wrapped with '``'</td></tr>
 <tr><td>\cite</td><td>wrapped with single quotes</td></tr>
+<tr><td>\code</td><td>replaced with '.. code-block:: c++'</td></tr>
+<tr><td>\code{&lt;ext&gt;}</td><td>replaced with '.. code-block:: &lt;lang&gt;',
+ where the following doxygen code languages are recognized: .c -&gt; C, .py
+ -&gt; python, .java &gt; java</td></tr>
 <tr><td>\cond</td><td>translated to 'Conditional comment: &lt;condition&gt;'</td>
 </tr>
 <tr><td>\copyright</td><td>prints 'Copyright:'</td></tr>
 <tr><td>\deprecated</td><td>prints 'Deprecated:'</td></tr>
-<tr><td>\e</td><td>wrapped with '_'</td></tr>
+<tr><td>\e</td><td>wrapped with '*'</td></tr>
 <tr><td>\else</td><td>replaced with '}Else:{'</td></tr>
 <tr><td>\elseif</td><td>replaced with '}Else if: &lt;condition&gt;{'</td></tr>
-<tr><td>\em</td><td>wrapped with '_'</td></tr>
+<tr><td>\em</td><td>wrapped with '*'</td></tr>
 <tr><td>\endcond</td><td>replaced with 'End of conditional comment.'</td>
 </tr>
 <tr><td>\endif</td><td>replaced with '}'</td></tr>
-<tr><td>\exception</td><td>replaced with 'Throws:'</td></tr>
+<tr><td>\example</td><td>replaced with 'Example:'</td></tr>
+<tr><td>\exception</td><td>replaced with ':raises:'</td></tr>
+<tr><td>\f$</td><td>rendered using ':math:``'</td></tr>
+<tr><td>\f[</td><td>rendered using '.. math::'</td></tr>
+<tr><td>\f{</td><td>rendered using '.. math::'</td></tr>
 <tr><td>\if</td><td>replaced with 'If: &lt;condition&gt; {'</td></tr>
 <tr><td>\ifnot</td><td>replaced with 'If not: &lt;condition&gt; {'</td></tr>
-<tr><td>\li</td><td>prepended with ' --'</td></tr>
-<tr><td>\n</td><td>replaced with new line char</td></tr>
+<tr><td>\li</td><td>prepended with ''</td></tr>
+<tr><td>\n</td><td>replaced with newline char</td></tr>
 <tr><td>\note</td><td>replaced with 'Note:'</td></tr>
 <tr><td>\overload</td><td>prints 'This is an overloaded ...' according
  to Doxygen docs</td></tr>
+<tr><td>\p</td><td>wrapped with '``'</td></tr>
 <tr><td>\par</td><td>replaced with 'Title: ...'</td></tr>
-<tr><td>\param</td><td>translated to 'Arguments:\n param(type)
- --description'</td></tr>
+<tr><td>\param</td><td>add ':type:' and ':param:' directives</td></tr>
+<tr><td>\param[&lt;dir&gt;]</td><td>same as \param, but direction ('in';
+ 'out'; 'in,out') is included in ':type:' directive</td></tr>
 <tr><td>\remark</td><td>replaced with 'Remarks:'</td></tr>
 <tr><td>\remarks</td><td>replaced with 'Remarks:'</td></tr>
-<tr><td>\result</td><td>replaced with 'Result:'</td></tr>
-<tr><td>\return</td><td>replaced with 'Result:'</td></tr>
-<tr><td>\returns</td><td>replaced with 'Result:'</td></tr>
+<tr><td>\result</td><td>add ':rtype:' and ':return:' directives</td></tr>
+<tr><td>\return</td><td>add ':rtype:' and ':return:' directives</td></tr>
+<tr><td>\returns</td><td>add ':rtype:' and ':return:' directives</td></tr>
 <tr><td>\sa</td><td>replaced with 'See also:'</td></tr>
 <tr><td>\see</td><td>replaced with 'See also:'</td></tr>
 <tr><td>\since</td><td>replaced with 'Since:'</td></tr>
-<tr><td>\throw</td><td>replaced with 'Throws:'</td></tr>
-<tr><td>\throws</td><td>replaced wih 'Throws:'</td></tr>
+<tr><td>\throw</td><td>replaced with ':raises:'</td></tr>
+<tr><td>\throws</td><td>replaced wih ':raises:'</td></tr>
 <tr><td>\todo</td><td>replaced with 'TODO:'</td></tr>
-<tr><td>\tparam</td><td>translated to 'Arguments:\n param(type)
- --description'</td></tr>
+<tr><td>\tparam</td><td>add ':type:' and ':param:' directives</td></tr>
+<tr><td>\verbatim</td><td>content copied verbatim</td></tr>
 <tr><td>\version</td><td>replaced with 'Version:'</td></tr>
 <tr><td>\warning</td><td>translated to 'Warning:'</td></tr>
 <tr><td>\$</td><td>prints $ char</td></tr>
@@ -21465,55 +21590,106 @@ doxypy</a>) to do the work.</p>
  (or particular use, such as some linking and section tags) are
  suppressed with their content just printed out (if it has any sense,
  typically text content). Here is the list of these tags:</p>
-<div class="diagram">
-<table border="0" summary="Unsupported Python Doxygen Tags">
-<tr><th align="left">Unsupported Doxygen tags</th></tr>
-<tr><td>\addindex</td><td>\addtogroup</td><td>\anchor</td><td>\attention</td>
-</tr>
-<tr><td>\brief</td><td>\bug</td><td>\callgraph</td><td>\callergraph</td></tr>
-<tr><td>\class</td><td>\copybrief</td><td>\copydetails</td><td>\copydoc</td>
-</tr>
-<tr><td>\date</td><td>\def</td><td>\defgroup</td><td>\details</td></tr>
-<tr><td>\dir</td><td>\dontinclude</td><td>\dot</td><td>\dotfile</td></tr>
-<tr><td>\code</td><td>\endcode</td><td>\endverbatim</td><td>\endlink</td>
-</tr>
-<tr><td>\enddot</td><td>\endhtmlonly</td><td>\endinternal</td><td>
-\endlatexonly</td></tr>
-<tr><td>\endmanonly</td><td>\endmsc</td><td>\endrtfonly</td><td>
-\endxmlonly</td></tr>
-<tr><td>\enum</td><td>\example</td><td>\extends</td><td>\f$</td></tr>
-<tr><td>\f[</td><td>\f]</td><td>\f{</td><td>\f}</td></tr>
-<tr><td>\file</td><td>\fn</td><td>\headerfile</td><td>\hideinitializer</td>
-</tr>
-<tr><td>\htmlinclude</td><td>\htmlonly</td><td>\implements</td><td>
-\include</td></tr>
-<tr><td>\image</td><td>\link</td><td>\verbatim</td><td>\p</td></tr>
-<tr><td>\includelineno</td><td>\ingroup</td><td>\internal</td><td>
-\invariant</td></tr>
-<tr><td>\interface</td><td>\latexonly</td><td>\line</td><td>\mainpage</td>
-</tr>
-<tr><td>\manonly</td><td>\memberof</td><td>\msc</td><td>\mscfile</td></tr>
-<tr><td>\name</td><td>\namespace</td><td>\nosubgrouping</td><td>\package</td>
-</tr>
-<tr><td>\page</td><td>\paragraph</td><td>\post</td><td>\pre</td></tr>
-<tr><td>\private</td><td>\privatesection</td><td>\property</td><td>
-\protected</td></tr>
-<tr><td>\protectedsection</td><td>\protocol</td><td>\public</td><td>
-\publicsection</td></tr>
-<tr><td>\ref</td><td>\related</td><td>\relates</td><td>\relatedalso</td></tr>
-<tr><td>\relatesalso</td><td>\retval</td><td>\rtfonly</td><td>\section</td>
-</tr>
-<tr><td>\short</td><td>\showinitializer</td><td>\skip</td><td>\skipline</td>
-</tr>
-<tr><td>\snippet</td><td>\struct</td><td>\subpage</td><td>\subsection</td>
-</tr>
-<tr><td>\subsubsection</td><td>\tableofcontents</td><td>\test</td><td>
-\typedef</td></tr>
-<tr><td>\union</td><td>\until</td><td>\var</td><td>\verbinclude</td></tr>
-<tr><td>\weakgroup</td><td>\xmlonly</td><td>\xrefitem</td><td>\category</td>
-</tr>
-<tr><td>\c</td></tr>
-</table>
+<div class="diagram"><b> Unsupported Python Doxygen tags</b>
+<ul style="list-style-type:none;column-count:4;">
+<li>\addindex</li>
+<li>\addtogroup</li>
+<li>\anchor</li>
+<li>\attention</li>
+<li>\brief</li>
+<li>\bug</li>
+<li>\callergraph</li>
+<li>\callgraph</li>
+<li>\category</li>
+<li>\class</li>
+<li>\copybrief</li>
+<li>\copydetails</li>
+<li>\copydoc</li>
+<li>\date</li>
+<li>\def</li>
+<li>\defgroup</li>
+<li>\details</li>
+<li>\dir</li>
+<li>\dontinclude</li>
+<li>\dot</li>
+<li>\dotfile</li>
+<li>\enddot</li>
+<li>\endhtmlonly</li>
+<li>\endinternal</li>
+<li>\endlatexonly</li>
+<li>\endlink</li>
+<li>\endmanonly</li>
+<li>\endmsc</li>
+<li>\endrtfonly</li>
+<li>\endxmlonly</li>
+<li>\enum</li>
+<li>\extends</li>
+<li>\file</li>
+<li>\fn</li>
+<li>\headerfile</li>
+<li>\hideinitializer</li>
+<li>\htmlinclude</li>
+<li>\htmlonly</li>
+<li>\image</li>
+<li>\implements</li>
+<li>\include</li>
+<li>\includelineno</li>
+<li>\ingroup</li>
+<li>\interface</li>
+<li>\internal</li>
+<li>\invariant</li>
+<li>\latexonly</li>
+<li>\line</li>
+<li>\link</li>
+<li>\mainpage</li>
+<li>\manonly</li>
+<li>\memberof</li>
+<li>\msc</li>
+<li>\mscfile</li>
+<li>\name</li>
+<li>\namespace</li>
+<li>\nosubgrouping</li>
+<li>\package</li>
+<li>\page</li>
+<li>\paragraph</li>
+<li>\post</li>
+<li>\pre</li>
+<li>\private</li>
+<li>\privatesection</li>
+<li>\property</li>
+<li>\protected</li>
+<li>\protectedsection</li>
+<li>\protocol</li>
+<li>\public</li>
+<li>\publicsection</li>
+<li>\ref</li>
+<li>\related</li>
+<li>\relatedalso</li>
+<li>\relates</li>
+<li>\relatesalso</li>
+<li>\retval</li>
+<li>\rtfonly</li>
+<li>\section</li>
+<li>\short</li>
+<li>\showinitializer</li>
+<li>\skip</li>
+<li>\skipline</li>
+<li>\snippet</li>
+<li>\struct</li>
+<li>\subpage</li>
+<li>\subsection</li>
+<li>\subsubsection</li>
+<li>\tableofcontents</li>
+<li>\test</li>
+<li>\typedef</li>
+<li>\union</li>
+<li>\until</li>
+<li>\var</li>
+<li>\verbinclude</li>
+<li>\weakgroup</li>
+<li>\xmlonly</li>
+<li>\xrefitem</li>
+</ul>
 </div>
 <h3><a name="Doxygen_python_further_details">17.4.4 Further details</a></h3>
 <p> TO BE ADDED.</p>
@@ -23688,8 +23864,10 @@ APP_STL := gnustl_static
  production environments due to the Managed C++ flaw called the <a href="https://msdn.microsoft.com/en-us/ie/aa290048(v=vs.94)">
 Mixed DLL Loading Problem</a>. SWIG C# works equally well on
  non-Microsoft operating systems such as Linux, Solaris and Apple Mac
- using <a href="https://www.mono-project.com/Main_Page/">Mono</a> and <a href="http://www.dotgnu.org/pnet.html">
-Portable.NET</a>.</p>
+ using <a href="https://www.mono-project.com/Main_Page/">Mono</a>.</p>
+<p> SWIG 3 and later requires .NET 2.0 at a minimum. There are some
+ minor exceptions, where the minimum required is .NET 4.0. This is when
+ using the <tt>std::complex</tt> and <tt>std::list</tt> STL containers.</p>
 <p> To get the most out of this chapter an understanding of interop is
  required. The <a href="https://msdn.microsoft.com">Microsoft Developer
  Network (MSDN)</a> has a good reference guide in a section titled
@@ -37354,7 +37532,7 @@ $ swig -lua -eluac example.i
 <h3><a name="Lua_commandline">28.2.1 Additional command line options</a></h3>
 <p> The following table list the additional commandline options
  available for the Lua module. They can also be seen by using:</p>
-<div class="code">
+<div class="shell">
 <pre>
 swig -lua -help 
 </pre>
@@ -38003,8 +38181,9 @@ class:method(args)</tt>, not <tt>class.method(args)</tt>, it's an easy
  have support for such features. Therefore, SWIG generates wrappers that
  try to work around some of these issues. To illustrate, suppose you
  have a class like this:</p>
-<div class="targetlang">
-<pre>class Spam {
+<div class="code">
+<pre>
+class Spam {
 public:
   static void foo();
   static int bar;
@@ -38012,7 +38191,7 @@ public:
 </pre>
 </div>
 <p> In Lua, C++ static members can be accessed as follows:</p>
-<div class="code">
+<div class="targetlang">
 <pre>
 &gt; example.Spam.foo()            -- calling Spam::foo()
 &gt; a=example.Spam.bar            -- reading Spam::bar 
@@ -38030,7 +38209,7 @@ public:
 </div>
 <p><b> Compatibility Note:</b> In versions prior to SWIG-3.0.0 only the
  following names would work:</p>
-<div class="code">
+<div class="targetlang">
 <pre>
 &gt; example.Spam_foo()            -- calling Spam::foo()
 &gt; a=example.Spam_bar            -- reading Spam::bar 
@@ -38226,8 +38405,9 @@ public:
 <p> One restriction with operator overloading support is that SWIG is
  not able to fully handle operators that aren't defined as part of the
  class. For example, if you had code like this</p>
-<div class="targetlang">
-<pre>class Complex {
+<div class="code">
+<pre>
+class Complex {
 ...
 friend Complex operator+(double, const Complex &amp;c);
 ...
@@ -38238,8 +38418,9 @@ friend Complex operator+(double, const Complex &amp;c);
  it simply ignores it and issues a warning. You can still wrap the
  operator, but you may have to encapsulate it in a special function. For
  example:</p>
-<div class="targetlang">
-<pre>%rename(Complex_add_dc) operator+(double, const Complex &amp;);
+<div class="code">
+<pre>
+%rename(Complex_add_dc) operator+(double, const Complex &amp;);
 ...
 Complex operator+(double, const Complex &amp;c);
 </pre>
@@ -38820,13 +39001,14 @@ nil
 <p> This behaviour was changed. Now unless -squash-bases option is
  provided, Derived store a list of it's bases and if some symbol is not
  found in it's own service tables then its bases are searched for it.
- Option -squash-bases will effectively return old behaviour.<div class="targetlang">
+ Option -squash-bases will effectively return old behaviour.</p>
+<div class="targetlang">
 <pre>
 &gt; print(der.new_func) -- Now it works
 function
 &gt;
 </pre>
-</div></p>
+</div>
 <h2><a name="Lua_nn24">28.4 Typemaps</a></h2>
 <p>This section explains what typemaps are and how to use them. The
  default wrapping behaviour of SWIG is enough in most cases. However
@@ -49364,7 +49546,11 @@ setup.py</tt>):</p>
 <li><a href="#R_nn4">Precompiling large R files</a></li>
 <li><a href="#R_nn5">General policy</a></li>
 <li><a href="#R_language_conventions">Language conventions</a></li>
-<li><a href="#R_nn6">C++ classes</a></li>
+<li><a href="#R_nn6">C++ classes</a>
+<ul>
+<li><a href="#R_class_examples">Examples</a></li>
+</ul>
+</li>
 <li><a href="#R_nn7">Enumerations</a></li>
 </ul>
 </div>
@@ -49374,12 +49560,16 @@ setup.py</tt>):</p>
 www.r-project.org</a>.</p>
 <p> The R bindings are under active development. They have been used to
  compile and run an R interface to QuantLib running on Mandriva Linux
- with gcc. The R bindings also work on Microsoft Windows using Visual
- C++.</p>
+ with gcc. They are also used to create the SimpleITK R package, which
+ runs on Linux and MacOS. SWIG is used to create all wrapper interfaces
+ to <a href="http://http://www.simpleitk.org/">SimpleITK</a>. The R
+ bindings also work on Microsoft Windows using Visual C++.</p>
 <h2><a name="R_nn2">33.1 Bugs</a></h2>
 <p> Currently the following features are not implemented or broken:</p>
 <ul>
-<li>Garbage collection of created objects</li>
+<li>Garbage collection of some created objects. Finalizers are available
+ for wrapped C++ classes and are called by the garbage collection
+ system.</li>
 <li>C Array wrappings</li>
 </ul>
 <h2><a name="R_nn3">33.2 Using R and SWIG</a></h2>
@@ -49463,24 +49653,115 @@ q(save=&quot;no&quot;)
 </div>
 <p> This will generate a compiled R file called BigFile.RData that will
  save a large amount of loading time.</p>
+<p> There is no need to precompile large R files if the SWIG-generated
+ code is being included in an R package. The package infrastructure
+ provides this service during package installation.</p>
 <h2><a name="R_nn5">33.4 General policy</a></h2>
 <p> The general policy of the module is to treat the C/C++ as a basic
  wrapping over the underlying functions and rely on the R type system to
  provide R syntax.</p>
 <h2><a name="R_language_conventions">33.5 Language conventions</a></h2>
-<p> getitem and setitem use C++ conventions (i.e. zero based indices). [
-<!---
-and [ are overloaded to allow for R syntax (one based indices and
-slices)
-&lt;/p-->
-</p>
+<p> getitem and setitem use C++ conventions (i.e. zero based indices).
+ [&lt;- and [ are overloaded to allow for R syntax (one based indices and
+ slices)</p>
 <h2><a name="R_nn6">33.6 C++ classes</a></h2>
-<p> C++ objects are implemented as external pointer objects with the
- class being the mangled name of the class. The C++ classes are
- encapsulated as an SEXP with an external pointer type. The class is the
- mangled name of the class. The nice thing about R is that is allows you
- to keep track of the pointer object which removes the necessity for a
- lot of the proxy class baggage you see in other languages.</p>
+<p> Wrapping of C++ classes for R works quite well. R has a special
+ type, known as an external reference, that can be used as a pointer to
+ arbitary things, including C++ classes. The proxy layers generated for
+ other classes are not required.</p>
+<p> SWIG currently creates a custom hierarchy of R classes derived from
+ the external reference type and implements type checking and function
+ overloading in the R code it generates. In the future we hope to
+ utilise the built in R6 class structures.</p>
+<p> The R interface has the following capabilities:</p>
+<ul>
+<li> Destructor methods are registered and called automatically by the R
+ garbage collector.</li>
+<li> A range of std::vector types are converted automatically to R
+ equivalents via the std_vector.i library.</li>
+<li> The $ operator is used for method access.</li>
+<li> Variable accessors are automatically generated and called via the
+ $, [, [[, $&lt;-, [&lt;-, [[&lt;- operators.</li>
+</ul>
+<h3><a name="R_class_examples">33.6.1 Examples</a></h3>
+<p> Consider the following simple example:</p>
+<div class="code">
+<pre>
+class Vehicle {
+private:
+  int m_axles;
+
+public:
+  int Axles() {
+    return(m_axles);
+  }
+
+  bool Available;
+
+  Vehicle() {
+    Available=false;
+    m_axles=2;
+  }
+
+  Vehicle(int ax) {
+    Available=false;
+    m_axles=ax;
+  }
+};
+</pre>
+</div>
+<p> The following options are available in R:</p>
+<div class="code">
+<pre>
+v1 &lt;- Vehicle()
+v2 &lt;- Vehicle(4)
+# access members
+v1$Axles()
+[1] 2
+v2$Axles
+[1] 4
+v1$Available
+[1] FALSE
+# Set availabilty
+v1$Available &lt;- TRUE
+v1$Available
+[1] TRUE
+</pre>
+</div>
+<p> A useful trick to determine the methods that are available is to
+ query the R method definition as follows:</p>
+<div class="code">
+<pre>
+# display the methods for the class
+getMethod(&quot;$&quot;, class(v1))
+    
+Method Definition:
+
+function (x, name) 
+{
+    accessorFuns = list(Axles = Vehicle_Axles, Available = Vehicle_Available_get)
+    vaccessors = c(&quot;Available&quot;)
+    idx = pmatch(name, names(accessorFuns))
+    if (is.na(idx)) 
+        return(callNextMethod(x, name))
+    f = accessorFuns[[idx]]
+    if (is.na(match(name, vaccessors))) 
+        function(...) {
+            f(x, ...)
+        }
+    else f(x)
+}
+
+Signatures:
+        x           
+target  &quot;_p_Vehicle&quot;
+defined &quot;_p_Vehicle&quot;
+
+</pre>
+</div>
+<p> The names in the <tt>accessorFuns</tt> list correspond to class
+ methods while names in the <tt>vaccessors</tt> section correspond to
+ variables that may be modified.</p>
 <h2><a name="R_nn7">33.7 Enumerations</a></h2>
 <p> R doesn't have a native enumeration type. Enumerations are
  represented as character strings in R, with calls to R functions that
@@ -50029,6 +50310,21 @@ from (irb):5</pre>
 </div>
 <p> The <tt>%immutable</tt> directive stays in effect until it is
  explicitly disabled using <tt>%mutable</tt>.</p>
+<p>Note: When SWIG is invoked with the <tt>-globalmodule</tt> option in
+ effect, the C/C++ global variables will be translated into Ruby global
+ variables. Type-checking and the optional read-only characteristic are
+ available in the same way as described above. However the example would
+ then have to be modified and executed in the following way:<div class="code targetlang">
+<pre>$ <b>irb</b>
+irb(main):001:0&gt; <b>require 'Example'</b>
+true
+irb(main):002:0&gt; <b>$variable1 = 2</b>
+2
+irb(main):003:0&gt; <b>$Variable2 = 4 * 10.3</b>
+41.2
+irb(main):004:0&gt; <b>$Variable2</b>
+41.2</pre>
+</div></p>
 <h3><a name="Ruby_nn15">34.3.4 Constants</a></h3>
 <p> C/C++ constants are wrapped as module constants initialized to the
  appropriate value. To create a constant, use <tt>#define</tt> or the <tt>
index 8b18d16..c8b8fe2 100644 (file)
Binary files a/Doc/Manual/SWIGDocumentation.pdf and b/Doc/Manual/SWIGDocumentation.pdf differ
index cc5f05e..c851b08 100644 (file)
@@ -8,7 +8,7 @@
 <H1><a name="Sections">SWIG-4.0 Documentation</a></H1>
 
 <p>
-Last update : SWIG-4.0.1 (21 Aug 2019)
+Last update : SWIG-4.0.2 (8 Jun 2020)
 </p>
 
 <H2><a name="Sections_Sections">Sections</a></H2>
index 45e51e3..ffadb87 100644 (file)
@@ -65,6 +65,10 @@ div.diagram {
   font-family: "Courier New", Courier, "Courier 10 Pitch", monospace;
 }
 
+div.diagram li {
+    margin-left: 0;
+}
+
 ul li p {
   margin-left: 0;
   margin-right: 0;
index 6fbca29..87386f7 100644 (file)
@@ -58,6 +58,7 @@ INTERFACE  =
 INTERFACEDIR  =
 INTERFACEPATH = $(SRCDIR)$(INTERFACEDIR)$(INTERFACE)
 SWIGOPT    =
+PCHSUPPORT = @PCHSUPPORT@
 
 # SWIG_LIB_DIR and SWIGEXE must be explicitly set by Makefiles using this Makefile
 SWIG_LIB_DIR = ./Lib
@@ -439,13 +440,36 @@ OCTAVE_SO     = @OCTAVE_SO@
 OCTAVE_SCRIPT = $(SRCDIR)$(RUNME).m
 
 # ----------------------------------------------------------------
+# Pre-compile Octave headers, if supported
+# ----------------------------------------------------------------
+
+ifeq (yes,$(PCHSUPPORT))
+
+octave_precompile_headers:
+       echo "precompiling $(OCTHEADERS)"
+       cp -f $(OCTHEADERSSRC) $(OCTHEADERS)
+       if $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) $(OCTAVE_CXX) $(OCTHEADERS); then \
+               : ; \
+       else \
+               rm -f $(OCTHEADERSGCH); \
+               exit 1; \
+       fi
+
+else
+
+octave_precompile_headers:
+       echo "precompiling Octave headers not supported"; exit 1
+
+endif
+
+# ----------------------------------------------------------------
 # Build a C dynamically loadable module
 # Note: Octave requires C++ compiler when compiling C wrappers
 # ----------------------------------------------------------------
 
 octave: $(SRCDIR_SRCS)
-       $(SWIG) -octave $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-       $(CXX) -g -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
+       $(SWIG) -octave $(SWIGOCTHDROPT) $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+       $(CXX) -g -c $(IOCTHEADERS) $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
        $(CC) -g -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CSRCS) $(INCLUDES)
        $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(OCTAVE_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(OCTAVE_SO)
 
@@ -454,8 +478,8 @@ octave: $(SRCDIR_SRCS)
 # -----------------------------------------------------------------
 
 octave_cpp: $(SRCDIR_SRCS)
-       $(SWIG) -c++ -octave $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-       $(CXX) -g -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
+       $(SWIG) -c++ -octave $(SWIGOCTHDROPT) $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+       $(CXX) -g -c $(IOCTHEADERS) $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
        $(CXXSHARED) -g $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(OCTAVE_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(OCTAVE_SO)
 
 # -----------------------------------------------------------------
@@ -481,6 +505,7 @@ octave_clean:
        rm -f *_wrap* *~ .~* myoctave@EXEEXT@ *.pyc
        rm -f core @EXTRA_CLEAN@
        rm -f *.@OBJEXT@ *@SO@ *$(OCTAVE_SO)
+       rm -f $(OCTHEADERS) $(OCTHEADERSGCH)
 
 ##################################################################
 #####                       GUILE                           ######
index 1ab96f0..88608a1 100644 (file)
@@ -8,25 +8,25 @@ TARGET     = swigexample
 INTERFACE  = example.i
 
 check: build
-       $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' octave_run
+       $(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' octave_run
 
 build:
 ifneq (,$(SRCS))
-       $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
+       $(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
        SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
        SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' octave
 else
-       $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
+       $(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
        SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
        SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' octave_cpp
 endif
 ifneq (,$(TARGET2)$(SWIGOPT2))
 ifneq (,$(SRCS))
-       $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
+       $(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
        SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
        SWIGOPT='$(SWIGOPT2)' TARGET='$(TARGET2)' INTERFACE='$(INTERFACE)' octave
 else
-       $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
+       $(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
        SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
        SWIGOPT='$(SWIGOPT2)' TARGET='$(TARGET2)' INTERFACE='$(INTERFACE)' octave_cpp
 endif
@@ -34,4 +34,4 @@ endif
 
 
 clean:
-       $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' octave_clean
+       $(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' octave_clean
index 9f4365e..efc7201 100644 (file)
@@ -183,3 +183,12 @@ const int PROCESS_DEFAULT_VALUE = 17;
 typedef long int some_type;
 int process_complex_defval(int val = PROCESS_DEFAULT_VALUE, int factor = some_type(-1)) { return val*factor; }
 %}
+
+// Test for empty docstring, which should be ignored.
+%feature("docstring") ""
+
+%inline %{
+struct a_structure{
+  char my_array[1];
+};
+%}
index 5f77928..e77f09c 100644 (file)
@@ -159,6 +159,7 @@ CPP_TEST_CASES += \
        cpp_enum \
        cpp_namespace \
        cpp_nodefault \
+       cpp_parameters \
        cpp_static \
        cpp_typedef \
        cpp14_binary_integer_literals \
@@ -183,6 +184,7 @@ CPP_TEST_CASES += \
        director_classes \
        director_classic \
        director_constructor \
+       director_conversion_operators \
        director_default \
        director_detect \
        director_enum \
@@ -250,6 +252,7 @@ CPP_TEST_CASES += \
        funcptr_cpp \
        functors \
        fvirtual \
+       global_immutable_vars_cpp \
        global_namespace \
        global_ns_arg \
        global_scope_types \
@@ -610,11 +613,14 @@ CPP11_TEST_BROKEN = \
 #      cpp11_reference_wrapper \     # No typemaps
 
 # Doxygen support test cases: can only be used with languages supporting
-# Doxygen comment translation, currently only Python and Java.
+# Doxygen comment translation (currently Python and Java) and only if not
+# disabled by configure via SKIP_DOXYGEN_TEST_CASES.
+ifneq ($(SKIP_DOXYGEN_TEST_CASES),1)
 python_HAS_DOXYGEN := 1
 java_HAS_DOXYGEN := 1
 
 $(eval HAS_DOXYGEN := $($(LANGUAGE)_HAS_DOXYGEN))
+endif
 
 ifdef HAS_DOXYGEN
 DOXYGEN_TEST_CASES += \
@@ -622,6 +628,8 @@ DOXYGEN_TEST_CASES += \
        doxygen_basic_notranslate \
        doxygen_basic_translate \
        doxygen_basic_translate_style2 \
+       doxygen_basic_translate_style3 \
+       doxygen_code_blocks \
        doxygen_ignore \
        doxygen_misc_constructs \
        doxygen_nested_class \
@@ -689,6 +697,7 @@ C_TEST_CASES += \
        funcptr \
        function_typedef \
        global_functions \
+       global_immutable_vars \
        immutable_values \
        inctest \
        infinity \
index 8d275b3..c31ae73 100644 (file)
@@ -138,3 +138,31 @@ void DerivedNoVirtualStruct::ef() {}
 DerivedNoVirtualStruct::~DerivedNoVirtualStruct() {}
 %}
 
+%inline %{
+namespace Outer {
+  namespace final {
+    template <typename T> struct smart_ptr {
+      typedef T type;
+    };
+  }
+  namespace override {
+    template <typename T> struct dumb_ptr {
+      typedef T type;
+    };
+  }
+}
+%}
+
+%template(SmartPtrBaseStruct) Outer::final::smart_ptr<DerivedStruct>;
+
+%inline %{
+class ObjectDB
+{
+public:
+  static void smart1(typename Outer::final::smart_ptr<DerivedStruct>::type *objectT) {}
+  static void smart2(Outer::final::smart_ptr<DerivedStruct>::type *objectT) {}
+  static void dumb1(typename Outer::override::dumb_ptr<DerivedStruct>::type *objectT) {}
+  static void dumb2(Outer::override::dumb_ptr<DerivedStruct>::type *objectT) {}
+  static Outer::final::smart_ptr<DerivedStruct>::type get() { return DerivedStruct(); }
+};
+%}
diff --git a/Examples/test-suite/cpp11_shared_ptr_template_upcast.i b/Examples/test-suite/cpp11_shared_ptr_template_upcast.i
new file mode 100644 (file)
index 0000000..38968bb
--- /dev/null
@@ -0,0 +1,88 @@
+%module cpp11_shared_ptr_template_upcast
+
+%{
+#include <memory>
+#include <string>
+%}
+
+%include <std_shared_ptr.i>
+%include <std_string.i>
+
+%{
+class Base {
+public:
+    Base() : value(0) {}
+    Base(int v) : value(v) {}
+    virtual ~Base() {}
+    
+    virtual int GetResult() = 0;
+    
+    int value;
+};
+
+class Derived : public Base {
+public:
+    Derived() : Base() {}
+    Derived(int v) : Base(v) {}
+    virtual ~Derived() {}
+    
+    int GetResult() { return value*2; }
+};
+
+template <class T> class Printable : virtual public T {
+public:
+    Printable(int param) : T(param) {}
+    ~Printable() {}
+
+    std::string GetFormatted() { return std::string("The formatted result is: ").append(std::to_string(this->GetResult())); }
+};
+
+std::shared_ptr<Printable<Derived> > MakePrintableDerived(int param) {
+    return std::make_shared<Printable<Derived> >(param);
+}
+
+%}
+
+%shared_ptr(Base);
+%shared_ptr(Derived);
+%shared_ptr(Printable<Derived>)
+
+class Base {
+public:
+    Base();
+    Base(int v);
+    virtual ~Base();
+    
+    virtual int GetResult() = 0;
+    
+    int value;
+};
+
+class Derived : public Base {
+public:
+    Derived();
+    Derived(int v);
+    virtual ~Derived();
+    
+    int GetResult();
+};
+
+/*
+    Virtual inheritance is contrived for this case, but exposes whether SWIGSmartPtrUpcast generated a correctly typed shared pointer of the upcasted class type -
+    if the pointer type is incorrect, this will result in a segmentation fault (on Windows, this could manifest as undefined behavior) when trying to access members 
+    inherited from T through a shared_ptr<Printable<T> >.
+*/
+template <class T> class Printable : virtual public T {
+public:
+    Printable(int param);
+    ~Printable();
+
+    std::string GetFormatted();
+};
+
+std::shared_ptr<Printable<Derived> > MakePrintableDerived(int param);
+
+
+%template(PrintableDerived) Printable<Derived>;
+
+
diff --git a/Examples/test-suite/cpp_parameters.i b/Examples/test-suite/cpp_parameters.i
new file mode 100644 (file)
index 0000000..e8a4c94
--- /dev/null
@@ -0,0 +1,46 @@
+%module cpp_parameters
+
+%{
+// For Perl
+#ifdef Zero
+#undef Zero
+#endif
+%}
+%inline %{
+
+// Zero arguments
+struct Zero {
+  Zero() {}
+  int zero() { return 0; }
+  static int stat_zero() { return 0; }
+};
+// One mandatory argument
+struct One {
+  One(int a) {}
+  int one(int a) { return a; }
+  static int stat_one(int a) { return a; }
+};
+// Two mandatory arguments
+struct Two {
+  Two(int a, int b) {}
+  int two(int a, int b) { return a + b; }
+  static int stat_two(int a, int b) { return a + b; }
+};
+// Single optional argument
+struct Single {
+  Single(int a=0) {}
+  int single(int a=0) { return a; }
+  static int stat_single(int a=0) { return a; }
+};
+
+int global_zero() { return 0; }
+int global_one(int a) { return a; }
+int global_two(int a, int b) { return a + b; }
+int global_single(int a=0) { return a; }
+
+#ifdef SWIGPYTHON_BUILTIN
+bool is_python_builtin() { return true; }
+#else
+bool is_python_builtin() { return false; }
+#endif
+%}
index 8272864..b0ad0c7 100644 (file)
@@ -16,6 +16,7 @@ CPP_TEST_CASES = \
        complextest \
        csharp_attributes \
        csharp_swig2_compatibility \
+       csharp_director_typemaps \
        csharp_exceptions \
        csharp_features \
        csharp_lib_arrays \
@@ -34,6 +35,7 @@ CPP11_TEST_CASES = \
        cpp11_shared_ptr_const \
        cpp11_shared_ptr_nullptr_in_containers \
        cpp11_shared_ptr_overload \
+       cpp11_shared_ptr_template_upcast \
        cpp11_shared_ptr_upcast \
        cpp11_strongly_typed_enumerations_simple \
 
diff --git a/Examples/test-suite/csharp/cpp11_shared_ptr_template_upcast_runme.cs b/Examples/test-suite/csharp/cpp11_shared_ptr_template_upcast_runme.cs
new file mode 100644 (file)
index 0000000..e76d2ba
--- /dev/null
@@ -0,0 +1,15 @@
+// This is the cpp11_shared_ptr_template_upcast runtime testcase. It checks that SWIG generates the appropriate upcasted shared_ptr type for a template instantiation deriving from a base class.
+// For this case, the expected behavior is: given a cptr with underlying type shared_ptr<Printable<Derived> >, PrintableDerived_SWIGSmartPtrUpcast returns a cptr with 
+// underlying type std::shared_ptr< Derived >, where Printable<Derived> inherits from Derived.
+using System;
+using cpp11_shared_ptr_template_upcastNamespace;
+
+public class cpp11_shared_ptr_template_upcast_runme
+{
+    static void Main()
+    {
+        PrintableDerived pd = cpp11_shared_ptr_template_upcast.MakePrintableDerived(20);
+        pd.GetResult();
+        pd.GetFormatted();
+    }
+}
diff --git a/Examples/test-suite/csharp/csharp_director_typemaps_runme.cs b/Examples/test-suite/csharp/csharp_director_typemaps_runme.cs
new file mode 100644 (file)
index 0000000..6143332
--- /dev/null
@@ -0,0 +1,53 @@
+
+using System;
+using System.Reflection;
+using csharp_director_typemapsNamespace;
+
+public class csharp_director_typemaps_runme {
+
+  class CSharpDirectorTypemaps_InStreamDerived : InStream
+  {
+    private int constant;
+    public CSharpDirectorTypemaps_InStreamDerived(int constant) { this.constant = constant; }
+    public override int Read(global::System.IntPtr buf, int len, out int readLen) {
+      readLen = (buf == global::System.IntPtr.Zero) ? -len - constant : len + constant;
+      return readLen;
+    }
+    public override int Write(global::System.IntPtr buf, int len, out int writeLen) {
+      writeLen = (buf == global::System.IntPtr.Zero) ? -len - constant : len + constant;
+      return writeLen;
+    }
+  }
+  public static void Main() {
+    int outLen = -1;
+    int k = 100;
+    int j = 23;
+    InStream instream = new CSharpDirectorTypemaps_InStreamDerived(k);
+
+    {
+      int ret = csharp_director_typemaps.callRead(instream, InStream.getCPtr(instream).Handle, j, out outLen);
+      Assert(outLen, j + k);
+      Assert(ret, j + k);
+    }
+    {
+      int ret = csharp_director_typemaps.callRead(instream, global::System.IntPtr.Zero, j, out outLen);
+      Assert(outLen, -j - k);
+      Assert(ret, -j - k);
+    }
+
+    {
+      int ret = csharp_director_typemaps.callWrite(instream, InStream.getCPtr(instream).Handle, j, out outLen);
+      Assert(outLen, j + k);
+      Assert(ret, j + k);
+    }
+    {
+      int ret = csharp_director_typemaps.callWrite(instream, global::System.IntPtr.Zero, j, out outLen);
+      Assert(outLen, -j - k);
+      Assert(ret, -j - k);
+    }
+  }
+  private static void Assert(int i1, int i2) {
+    if (i1 != i2)
+      throw new Exception("assertion failure. " + i1 + " != " + i2);
+  }
+}
diff --git a/Examples/test-suite/csharp_director_typemaps.i b/Examples/test-suite/csharp_director_typemaps.i
new file mode 100644 (file)
index 0000000..614bdbf
--- /dev/null
@@ -0,0 +1,37 @@
+%module (directors="1") csharp_director_typemaps
+
+// This tests that the csout typemap is handled correctly in the director code.
+// The 'out' needs stripping in some parts of the generated director code.
+
+%feature("director") InStream;
+
+%apply void *VOID_INT_PTR { void * }
+
+%typemap(ctype)         int* readLen, int* writeLen "/*ctype*/ int*"
+%typemap(imtype)        int* readLen, int* writeLen "/*imtype*/ out int"
+%typemap(cstype)        int* readLen                "/*cstype*/ out int"
+// Note for below: 'out' used in typemap comment
+%typemap(cstype)                      int* writeLen "/*out cstype out*/ out int"
+%typemap(csin)          int* readLen, int* writeLen "/*csin*/ out $csinput"
+%typemap(in)            int* readLen, int* writeLen %{/*in*/  $1 = ($1_ltype)$input; %}
+%typemap(out)           int* readLen, int* writeLen %{/*out*/ $result = (void *)$1; %}
+%typemap(csdirectorin)  int* readLen, int* writeLen "/*csdirectorin*/ out $iminput"
+%typemap(csdirectorout) int* readLen, int* writeLen "/*csdirectorout*/ $cscall"
+%typemap(directorin)    int* readLen, int* writeLen "/*directorin*/ $input = $1;"
+%typemap(directorout)   int* readLen, int* writeLen %{/*directorout*/  $result = ($1_ltype)$input; %}
+
+%inline %{
+class InStream
+{
+public:
+    virtual int Read(void* buf, int len, int* readLen) = 0;
+    virtual int Write(void* buf, int len, int* writeLen) = 0;
+    virtual ~InStream() {}
+};
+int callRead(InStream* stream, void* buf, int len, int* readLen) {
+  return stream->Read(buf, len, readLen);
+}
+int callWrite(InStream* stream, void* buf, int len, int* writeLen) {
+  return stream->Write(buf, len, writeLen);
+}
+%}
diff --git a/Examples/test-suite/director_conversion_operators.i b/Examples/test-suite/director_conversion_operators.i
new file mode 100644 (file)
index 0000000..afcd49d
--- /dev/null
@@ -0,0 +1,35 @@
+%module(directors="1") director_conversion_operators
+
+%feature("director");
+
+%warnfilter(SWIGWARN_TYPEMAP_DIRECTOROUT_PTR) Bar;
+
+%rename(toFoo) Bar::operator Foo();
+%rename(toFooPtr) Bar::operator Foo *();
+%rename(toFooRef) Bar::operator Foo &();
+%rename(toFooPtrRef) Bar::operator Foo *&();
+
+%rename(toOtherFoo) Bar::operator OtherFoo();
+%rename(toOtherFooPtr) Bar::operator OtherFoo *();
+%rename(toOtherFooRef) Bar::operator OtherFoo &();
+%rename(toOtherFooPtrRef) Bar::operator OtherFoo *&();
+
+%inline %{
+   struct Foo {
+   };
+   struct OtherFoo {
+   };
+   struct Bar {
+      Foo myFoo;
+      Foo *myFooPtr;
+      virtual ~Bar() { }
+      virtual operator Foo () { return Foo(); }
+      virtual operator Foo *() { return &myFoo; }
+      virtual operator Foo &() { return myFoo; }
+      virtual operator Foo *&() { return myFooPtr; }
+      virtual operator OtherFoo () = 0;
+      virtual operator OtherFoo *() = 0;
+      virtual operator OtherFoo &() = 0;
+      virtual operator OtherFoo *&() = 0;
+   };
+%}
index da4d809..4e543fe 100644 (file)
@@ -107,6 +107,23 @@ double Atan2(double y, double x)
     return 0;
 }
 
+/* Regression test for crash with empty comment: */
+/**/ 
+
+/**
+ * @brief Test variadic function
+ * @param ... extra args
+ */
+void function8(...) {
+}
+
+/**
+ * @brief Test unnamed argument
+ * @param baz Description of baz
+ */
+void function9(int) {
+} 
+
 /**
  * Comment at the end of file should be ignored.
  */
diff --git a/Examples/test-suite/doxygen_basic_translate_style3.i b/Examples/test-suite/doxygen_basic_translate_style3.i
new file mode 100644 (file)
index 0000000..e364b16
--- /dev/null
@@ -0,0 +1,102 @@
+%module doxygen_basic_translate_style3
+
+%include "doxygen_basic_translate.h"
+
+%inline %{
+
+/// \brief
+/// Brief description.
+///
+/// The comment text.
+///
+/// \author Some author
+///
+/// \return Some number
+///
+/// \sa function2
+int function()
+{
+    return 0;
+}
+
+/// A test of a very very very very very very very very very very very very very very very very
+/// very very very very very long comment string.
+void function2()
+{
+}
+
+/// A test for overloaded functions
+/// This is function \b one
+void function3(int a)
+{
+}
+
+/// A test for overloaded functions
+/// This is function \b two
+void function3(int a, int b)
+{
+}
+
+/// A test of some mixed tag usage
+/// \if CONDITION
+/// This \a code fragment shows us something \.
+/// \par Minuses:
+/// \arg it's senseless
+/// \arg it's stupid
+/// \arg it's null
+///
+/// \warning This may not work as expected
+/// \code
+/// int main() { while(true); }
+///
+/// int testBlankLine() {}
+/// \endcode
+/// \endif
+void function4()
+{
+  // Note: a comment in the above code block will not get processed
+  // correctly with this doxygen comment style, because
+  // DoxygenParser::tokenizeDoxygenComment strips out the leading
+  // comment characters.  Whereas it works in the other doxygen
+  // comment styles (as shown in the other variations of
+  // doxygen_basic_translate), this test is modified to remove the
+  // comment within the code block.
+}
+
+
+void function5(int a)
+{
+}
+///< This is a post comment.
+
+/// Test for default args
+/// @param a Some parameter, default is 42
+void function6(int a=42)
+{
+}
+
+class Shape
+{
+public:
+  typedef Shape* superType;
+};
+
+/// Test for a parameter with difficult type
+/// (mostly for python)
+/// @param a Very strange param
+void function7(Shape::superType *a[10])
+{
+}
+
+/// Multiple parameters test.
+///
+/// @param y Vertical coordinate.
+/// @param x Horizontal coordinate.
+/// @return Arc tangent of @c y/x.
+double Atan2(double y, double x)
+{
+    return 0;
+}
+
+/// Comment at the end of file should be ignored.
+%}
diff --git a/Examples/test-suite/doxygen_code_blocks.i b/Examples/test-suite/doxygen_code_blocks.i
new file mode 100644 (file)
index 0000000..900e8f9
--- /dev/null
@@ -0,0 +1,62 @@
+%module doxygen_code_blocks
+
+// This test is only used with Python
+
+%inline %{
+
+/**
+ * \brief Test for code blocks
+ *
+ * \code
+ * simple code block
+ * \endcode
+ *
+ * More advanced usage with C++ characters:
+ * \code
+ * std::vector<int> first;                                // empty vector of ints
+ * std::vector<int> second (4,100);                       // four ints with value 100
+ * std::vector<int> third (second.begin(),second.end());  // iterating through second
+ * std::vector<int> fourth (third);                       // a copy of third
+ *  // the iterator constructor can also be used to construct from arrays:
+ * int myints[] = {16,2,77,29};
+ * std::vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );
+ *
+ * std::cout << "The contents of fifth are:";
+ * for (std::vector<int>::iterator it = fifth.begin(); it != fifth.end(); ++it)
+ *   std::cout << ' ' << *it;
+ * std::cout << '\n'; 
+ * \endcode
+ *
+ * A code block for C:
+ * \code{.c}
+ * printf("hello world");
+ * \endcode
+ *
+ * A code block for Java:
+ * \code{.java}
+ * public class HelloWorld {
+ *     public static void main(String[] args) {
+ *         // Prints "Hello, World" to the terminal window.
+ *         System.out.println("Hello, World");
+ *     }
+ * }
+ * \endcode
+ * 
+ * A code block for python:
+ * \code{.py}
+ * print('hello world')
+ * \endcode
+ *
+ * A python doctest example:
+ * \code{.py}
+ * >>> 1 + 1
+ * 2
+ * \endcode
+ */
+int function()
+{
+    return 0;
+}  
+
+
+%}
index d677dc3..9e81aaf 100644 (file)
@@ -91,4 +91,12 @@ void backslashC()
 void cycle(int id, char *fileName)
 {}
 
+/// This doc comment ends with a quote: "and that's ok"
+void doc_ends_with_quote() {}
 
+/**
+    This comment contains embedded triple-quoted string:
+
+        """How quaint"""
+ */
+void doc_with_triple_quotes() {}
index c1b3eea..9cf95de 100644 (file)
@@ -36,7 +36,7 @@
      * @param line line number
      * @param isGetSize if set, for every object location both address and size are returned
      *
-     * @link Connection::getId() @endlink <br>
+     * @link Connection::getId() @endlink<br>
      */
     void getAddress(int &fileName,
                     int line,
@@ -62,7 +62,7 @@
      * used for unspecified parameters.
      * <p>
      *
-     * @link advancedWinIDEALaunching.py Python example.@endlink <br>
+     * @link advancedWinIDEALaunching.py Python example.@endlink<br>
      */
     class CConnectionConfig
     {
index 8da683d..b54203d 100644 (file)
@@ -210,7 +210,7 @@ void func05(int a)
  * 
  * \line example
  *
- * \link someMember Some description follows \endlink
+ * \link someMember Some description follows\endlink with text after
  * 
  * \mainpage Some title
  *
@@ -262,6 +262,9 @@ void func06(int a)
  * \paragraph someParagraph Paragraph title
  *
  * \param a the first param
+ * \param[in] b parameter with intent(in)
+ * \param[out] c parameter with intent(out)
+ * \param[in,out] d parameter with intent(in,out)
  * 
  * \post Some description
  *
@@ -273,7 +276,7 @@ void func06(int a)
  *
  * \property someVar
  */
-void func07(int a)
+void func07(int a, int b, int c, int d)
 {
 }
 
diff --git a/Examples/test-suite/global_immutable_vars.i b/Examples/test-suite/global_immutable_vars.i
new file mode 100644 (file)
index 0000000..ab0d4f7
--- /dev/null
@@ -0,0 +1,33 @@
+%module global_immutable_vars
+
+// Test immutable and mutable global variables,
+// see http://www.swig.org/Doc4.0/SWIGDocumentation.html#SWIG_readonly_variables
+
+%inline %{
+  int default_mutable_var = 40;
+%}
+
+%immutable;
+%feature("immutable", "0") specific_mutable_var;
+
+%inline %{
+  int global_immutable_var = 41;
+  int specific_mutable_var = 42;
+%}
+
+%mutable;
+%immutable specific_immutable_var;
+%inline %{
+  int global_mutable_var = 43;
+  int specific_immutable_var = 44;
+
+  int check_values(int default_mutable, int global_immutable, int specific_mutable, int global_mutable, int specific_immutable) {
+    return
+      default_mutable    == default_mutable_var &&
+      global_immutable   == global_immutable_var &&
+      specific_mutable   == specific_mutable_var &&
+      global_mutable     == global_mutable_var &&
+      specific_immutable == specific_immutable_var;
+  }
+%}
+
diff --git a/Examples/test-suite/global_immutable_vars_cpp.i b/Examples/test-suite/global_immutable_vars_cpp.i
new file mode 100644 (file)
index 0000000..40cc08e
--- /dev/null
@@ -0,0 +1,33 @@
+%module global_immutable_vars_cpp
+
+// Test immutable and mutable global variables,
+// see http://www.swig.org/Doc4.0/SWIGDocumentation.html#SWIG_readonly_variables
+
+%inline %{
+  int default_mutable_var = 40;
+%}
+
+%immutable;
+%feature("immutable", "0") specific_mutable_var;
+
+%inline %{
+  int global_immutable_var = 41;
+  int specific_mutable_var = 42;
+%}
+
+%mutable;
+%immutable specific_immutable_var;
+%inline %{
+  int global_mutable_var = 43;
+  int specific_immutable_var = 44;
+
+  int check_values(int default_mutable, int global_immutable, int specific_mutable, int global_mutable, int specific_immutable) {
+    return
+      default_mutable    == default_mutable_var &&
+      global_immutable   == global_immutable_var &&
+      specific_mutable   == specific_mutable_var &&
+      global_mutable     == global_mutable_var &&
+      specific_immutable == specific_immutable_var;
+  }
+%}
+
index 7dc6d59..1fc6f64 100644 (file)
@@ -1,5 +1,6 @@
 
-import com.sun.javadoc.*;
+import com.sun.source.doctree.*;
+import com.sun.source.util.DocTrees;
 import java.util.HashMap;
 import java.util.Map.Entry;
 import java.util.Map;
@@ -9,45 +10,120 @@ import java.io.BufferedWriter;
 import java.io.OutputStreamWriter;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.util.*;
+import java.util.spi.ToolProvider;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+import javax.lang.model.util.*;
+import jdk.javadoc.doclet.*;
 
 
-public class CommentParser {
+public class CommentParser implements Doclet {
     private static Map<String, String> m_parsedComments = new HashMap<String, String>();
 
-    public static boolean start(RootDoc root) {
+    // We need to implement these base class pure virtual methods.
 
+    @Override
+    public void init(Locale locale, Reporter reporter) {
+    }
+
+    @Override
+    public Set<? extends Option> getSupportedOptions() {
+        return new HashSet<>();
+    }
+
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+        return SourceVersion.latest();
+    }
+
+    @Override
+    public String getName() {
+        return "CommentParser";
+    }
+
+    // Element name must be the fully qualified name of the element.
+    //
+    // If there is no comment associated with this element, simply do nothing.
+    private void storeCommentFor(DocTrees docTrees, String fullName, Element e) {
+        DocCommentTree docCommentTree = docTrees.getDocCommentTree(e);
+        if (docCommentTree == null)
+            return;
+
+        StringBuilder name = new StringBuilder(fullName);
+
+        // We must use signature in the key for methods for compatibility with
+        // the existing tests and to allow distinguishing between overloaded
+        // methods.
+        if (e instanceof ExecutableElement) {
+            ExecutableElement ex = (ExecutableElement)e;
+            name.append("(");
+
+            boolean firstParam = true;
+            for (VariableElement p : ex.getParameters()) {
+                if (firstParam) {
+                    firstParam = false;
+                } else {
+                    name.append(", ");
+                }
+
+                name.append(p.asType().toString());
+            }
+
+            name.append(")");
+        }
+
+        // For some reason the comment in the source is split into "body" and
+        // "block tags" parts, so we need to concatenate them back together.
+        StringBuilder comment = new StringBuilder();
+        for (DocTree d : docCommentTree.getFullBody()) {
+            comment.append(d.toString());
+            comment.append("\n");
+        }
+
+        boolean firstBlockTag = true;
+        for (DocTree d : docCommentTree.getBlockTags()) {
+            if (firstBlockTag) {
+                firstBlockTag = false;
+                comment.append("\n");
+            }
+
+            comment.append(d.toString());
+            comment.append("\n");
+        }
+
+        m_parsedComments.put(name.toString(), comment.toString());
+    }
+
+    @Override
+    public boolean run(DocletEnvironment docEnv) {
         /*
          * This method is called by 'javadoc' and gets the whole parsed java
          * file, we get comments and store them
          */
+        DocTrees docTrees = docEnv.getDocTrees();
+        for (TypeElement t : ElementFilter.typesIn(docEnv.getIncludedElements())) {
+            String typeName = t.getQualifiedName().toString();
 
-        for (ClassDoc classDoc : root.classes()) {
+            storeCommentFor(docTrees, typeName, t);
 
-            if (classDoc.getRawCommentText().length() > 0)
-                m_parsedComments.put(classDoc.qualifiedName(), classDoc.getRawCommentText());
+            for (Element e : t.getEnclosedElements()) {
+                // Omit the method name for ctors: this is a bit weird, but
+                // this is what the existing tests expect.
+                String fullName = typeName;
+                if (e.getKind() != ElementKind.CONSTRUCTOR) {
+                    fullName = fullName + "." + e.getSimpleName();
+                }
 
-            for (FieldDoc f : classDoc.enumConstants()) {
-                if (f.getRawCommentText().length() > 0)
-                    m_parsedComments.put(f.qualifiedName(), f.getRawCommentText());
-            }
-            for (FieldDoc f : classDoc.fields()) {
-                if (f.getRawCommentText().length() > 0)
-                    m_parsedComments.put(f.qualifiedName(), f.getRawCommentText());
-            }
-            for (ConstructorDoc c : classDoc.constructors()) {
-                if (c.getRawCommentText().length() > 0)
-                    m_parsedComments.put(c.toString(), c.getRawCommentText());
-            }
-            for (MethodDoc m : classDoc.methods()) {
-                if (m.getRawCommentText().length() > 0)
-                    m_parsedComments.put(m.toString(), m.getRawCommentText());
+                storeCommentFor(docTrees, fullName, e);
             }
         }
+
         return true;
     }
 
     
-    public int check(Map<String, String> wantedComments) {
+    public static int check(Map<String, String> wantedComments) {
         int errorCount=0;
         Iterator<Entry<String, String>> it = m_parsedComments.entrySet().iterator();
 
@@ -93,13 +169,14 @@ public class CommentParser {
                 System.out.println("Output is also saved to files '" + expectedFileName +
                                    "' and '" + gotFileName + "'");
                 // here we print original strings, for nicer output
-                System.out.println("\n\n---\nexpected:\n" + wantedComments.get(e.getKey()));
+                System.out.println("\n\n---\nexpected:\n" + wantedStr);
                 System.out.println("\n\n---\ngot:\n" + e.getValue());
 
                 try {
                     // write expected string to file
                     BufferedWriter expectedFile = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(expectedFileName)));
-                    expectedFile.write(wantedComments.get(e.getKey()));
+                    if (wantedStr != null)
+                        expectedFile.write(wantedStr);
                     expectedFile.close();
 
                     // write translated string to file
@@ -130,7 +207,7 @@ public class CommentParser {
     }
 
     
-    private void printKeys(Map<String, String> map) {
+    private static void printKeys(Map<String, String> map) {
         
         Set<String> keys = map.keySet();
         for (String key : keys) {
@@ -154,6 +231,15 @@ public class CommentParser {
         }
     }
 
+    public static void parse(String sourcefile) {
+        ToolProvider javadoc = ToolProvider.findFirst("javadoc").orElseThrow();
+        int result = javadoc.run(System.out, System.err, new String[]{"-quiet", "-doclet", "CommentParser", sourcefile});
+        if (result != 0) {
+          System.err.println("Executing javadoc failed.");
+          System.exit(result);
+        }
+    }
+
     
     public static void main(String argv[]) {
                
@@ -162,8 +248,7 @@ public class CommentParser {
             System.exit(1);
         }
                
-        com.sun.tools.javadoc.Main.execute("The comment parser program",
-                                           "CommentParser", new String[]{"-quiet", argv[0]});
+        parse(argv[0]);
                
         // if we are run as standalone app, print the list of found comments as it would appear in java source
                
index 2e788fa..a449f28 100644 (file)
@@ -9,6 +9,7 @@ JAVAFLAGS    = @JAVAFLAGS@
 JAVA_CLASSPATH_SEP = @JAVA_CLASSPATH_SEP@
 JAVA_TOOLS_JAR     = @JAVA_TOOLS_JAR@
 SCRIPTSUFFIX = _runme.java
+SKIP_DOXYGEN_TEST_CASES = @JAVA_SKIP_DOXYGEN_TEST_CASES@
 
 srcdir       = @srcdir@
 top_srcdir   = ../@top_srcdir@
@@ -52,6 +53,7 @@ CPP11_TEST_CASES = \
        cpp11_shared_ptr_const \
        cpp11_shared_ptr_nullptr_in_containers \
        cpp11_shared_ptr_overload \
+       cpp11_shared_ptr_template_upcast \
        cpp11_shared_ptr_upcast \
        cpp11_std_unordered_map \
        cpp11_std_unordered_set \
@@ -108,13 +110,11 @@ setup = \
          mkdir $(JAVA_PACKAGE);                                                          \
        fi
 
-# Doxygen test cases need to be compiled together with the CommentParser class
-# which depends on com.sun.javadoc package which is located in this JAR.
+# Doxygen test cases need to be compiled together with the CommentParser class.
 CommentParser.class:
        $(COMPILETOOL) $(JAVAC) -classpath $(JAVA_CLASSPATH) -d . $(srcdir)/CommentParser.java
 
 JAVA_CLASSPATH := .
-$(DOXYGEN_TEST_CASES:=.cpptest): JAVA_CLASSPATH := "$(JAVA_TOOLS_JAR)$(JAVA_CLASSPATH_SEP)."
 $(DOXYGEN_TEST_CASES:=.cpptest): CommentParser.class
 
 # Compiles java files then runs the testcase. A testcase is only run if
diff --git a/Examples/test-suite/java/cpp11_shared_ptr_template_upcast_runme.java b/Examples/test-suite/java/cpp11_shared_ptr_template_upcast_runme.java
new file mode 100644 (file)
index 0000000..2826f58
--- /dev/null
@@ -0,0 +1,24 @@
+// This is the cpp11_shared_ptr_template_upcast runtime testcase. It checks that SWIG generates the appropriate upcasted shared_ptr type for a template instantiation deriving from a base class.
+// For this case, the expected behavior is: given a cptr with underlying type shared_ptr<Printable<Derived> >, PrintableDerived_SWIGSmartPtrUpcast returns a cptr with 
+// underlying type std::shared_ptr< Derived >, where Printable<Derived> inherits from Derived.
+
+import cpp11_shared_ptr_template_upcast.*;
+
+public class cpp11_shared_ptr_template_upcast_runme {
+
+  static {
+    try {
+       System.loadLibrary("cpp11_shared_ptr_template_upcast");
+    } 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[]) {
+    PrintableDerived pd = cpp11_shared_ptr_template_upcast.MakePrintableDerived(20);
+    pd.GetResult();
+    pd.GetFormatted();
+  }
+}
+
index a6ed671..67cb0fe 100644 (file)
@@ -19,7 +19,7 @@ public class director_string_runme {
     director_string_A c = new director_string_A("hi");
     for (int i=0; i<3; i++) {
       s = c.call_get(i);
-      if (!s.equals(new Integer(i).toString())) throw new RuntimeException("director_string_A.get(" + i + ") failed. Got:" + s);
+      if (!s.equals(Integer.valueOf(i).toString())) throw new RuntimeException("director_string_A.get(" + i + ") failed. Got:" + s);
     }
 
     director_string_B b = new director_string_B("hello");
@@ -50,7 +50,7 @@ class director_string_A extends A {
       super(first);
     }
     public String get(int n) {
-      return new Integer(n).toString();
+      return Integer.valueOf(n).toString();
     }
 }
 
index e21ed6d..98cd977 100644 (file)
@@ -1,6 +1,5 @@
 
 import doxygen_alias.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_alias_runme {
@@ -15,10 +14,7 @@ public class doxygen_alias_runme {
 
   public static void main(String argv[])
   {
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_alias runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_alias"});
+    CommentParser.parse("doxygen_alias");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     wantedComments.put("doxygen_alias.doxygen_alias.make_something()",
@@ -27,6 +23,6 @@ public class doxygen_alias_runme {
       "     @return A new object which may be null.\n" +
       "");
 
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
index e3d9b02..621cc9e 100644 (file)
@@ -1,6 +1,5 @@
 
 import doxygen_basic_notranslate.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_basic_notranslate_runme {
@@ -15,14 +14,7 @@ public class doxygen_basic_notranslate_runme {
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_basic_notranslate runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_basic_notranslate"});
+    CommentParser.parse("doxygen_basic_notranslate");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     wantedComments.put("doxygen_basic_notranslate.doxygen_basic_notranslate.function3(int)",
@@ -97,6 +89,6 @@ public class doxygen_basic_notranslate_runme {
                "");
     
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
index ab343b5..c64262a 100644 (file)
@@ -1,6 +1,5 @@
 
 import doxygen_basic_translate.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_basic_translate_runme {
@@ -15,14 +14,7 @@ public class doxygen_basic_translate_runme {
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_basic_translate runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_basic_translate"});
+    CommentParser.parse("doxygen_basic_translate");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -94,8 +86,15 @@ public class doxygen_basic_translate_runme {
                " @param x Horizontal coordinate.\n" +
                " @return Arc tangent of <code>y/x</code>.\n" +
                "");
+    wantedComments.put("doxygen_basic_translate.doxygen_basic_translate.function8()",
+               " Test variadic function\n" +
+               "");
+
+    wantedComments.put("doxygen_basic_translate.doxygen_basic_translate.function9(int)",
+               " Test unnamed argument\n" +
+               "");    
 
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
index 05e51cf..28cf2da 100644 (file)
@@ -1,6 +1,5 @@
 
 import doxygen_basic_translate_style2.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_basic_translate_style2_runme {
@@ -15,14 +14,7 @@ public class doxygen_basic_translate_style2_runme {
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_basic_translate_style2 runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_basic_translate_style2"});
+    CommentParser.parse("doxygen_basic_translate_style2");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -96,6 +88,6 @@ public class doxygen_basic_translate_style2_runme {
                "");
 
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
diff --git a/Examples/test-suite/java/doxygen_basic_translate_style3_runme.java b/Examples/test-suite/java/doxygen_basic_translate_style3_runme.java
new file mode 100644 (file)
index 0000000..a095364
--- /dev/null
@@ -0,0 +1,93 @@
+
+import doxygen_basic_translate_style3.*;
+import java.util.HashMap;
+
+public class doxygen_basic_translate_style3_runme {
+  static {
+    try {
+      System.loadLibrary("doxygen_basic_translate_style3");
+    } 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[]) 
+  {
+    CommentParser.parse("doxygen_basic_translate_style3");
+
+    HashMap<String, String> wantedComments = new HashMap<String, String>();
+    
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.function()",
+               " \n" +
+               " Brief description.\n" +
+               " \n" +
+               " The comment text.\n" +
+               " @author Some author\n" +
+               " @return Some number\n" +
+               " @see function2\n" +
+               " \n" +
+               "");
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.function2()",
+               " A test of a very very very very very very very very very very very very very very very very \n" +
+               " very very very very very long comment string. \n" +
+               " \n" +
+               "");
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.function4()",
+               " A test of some mixed tag usage \n" +
+               " If: CONDITION {\n" +
+               " This <i>code </i>fragment shows us something . \n" +
+               " <p alt=\"Minuses: \">\n" +
+               " <li>it's senseless \n" +
+               " </li><li>it's stupid \n" +
+               " </li><li>it's null \n" +
+               " \n" +
+               " </li></p>Warning: This may not work as expected \n" +
+               " \n" +
+               " {@code \n" +
+               "int main() { while(true); } \n" +
+               "\n" +
+               "int testBlankLine() {} \n" +
+               " }\n" +
+               " }\n" +
+               " \n" +
+               "");
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.function3(int)",
+               " A test for overloaded functions \n" +
+               " This is function <b>one </b>\n" +
+               " \n" +
+               "");
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.function5(int)",
+               " This is a post comment. \n" +
+               "");
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.function6(int)",
+               " Test for default args \n" +
+               " @param a Some parameter, default is 42" +
+               " \n" +
+               "");
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.function6()",
+               " Test for default args \n" +
+               " \n" +
+               "");
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.function7(doxygen_basic_translate_style3.SWIGTYPE_p_p_p_Shape)",
+               " Test for a parameter with difficult type \n" +
+               " (mostly for python) \n" +
+               " @param a Very strange param \n" +
+               "");
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.function3(int, int)",
+               " A test for overloaded functions \n" +
+               " This is function <b>two </b>\n" +
+               " \n" +
+               "");
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.Atan2(double, double)",
+               " Multiple parameters test.\n" +
+               " \n" +
+               " @param y Vertical coordinate.\n" +
+               " @param x Horizontal coordinate.\n" +
+               " @return Arc tangent of <code>y/x</code>.\n" +
+               "");
+
+    // and ask the parser to check comments for us
+    System.exit(CommentParser.check(wantedComments));
+  }
+}
diff --git a/Examples/test-suite/java/doxygen_code_blocks_runme.java b/Examples/test-suite/java/doxygen_code_blocks_runme.java
new file mode 100644 (file)
index 0000000..8e8373b
--- /dev/null
@@ -0,0 +1,75 @@
+
+import doxygen_code_blocks.*;
+import java.util.HashMap;
+
+public class doxygen_code_blocks_runme {
+  static {
+    try {
+      System.loadLibrary("doxygen_code_blocks");
+    } 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[]) 
+  {
+    CommentParser.parse("doxygen_code_blocks");
+
+    HashMap<String, String> wantedComments = new HashMap<String, String>();
+    
+    wantedComments.put("doxygen_code_blocks.doxygen_code_blocks.function()",
+                      " Test for code blocks\n \n" +
+                      " \n \n" +
+                      " {@code  \n" +
+                      " simple code block \n" +
+                      " }\n \n" +
+                      " \n \n" +
+                      " More advanced usage with C++ characters:\n \n" +
+                      " {@code  \n" +
+                      " std::vector<int> first;                                // empty vector of ints \n" +
+                      " std::vector<int> second (4,100);                       // four ints with value 100 \n" +
+                      " std::vector<int> third (second.begin(),second.end());  // iterating through second \n" +
+                      " std::vector<int> fourth (third);                       // a copy of third \n" +
+                      " // the iterator constructor can also be used to construct from arrays: \n" +
+                      " int myints[] = {16,2,77,29}; \n" +
+                      " std::vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) ); \n" +
+                      "  \n" +
+                      " std::cout << \"The contents of fifth are:\"; \n" +
+                      " for (std::vector<int>::iterator it = fifth.begin(); it != fifth.end(); ++it) \n" +
+                      " std::cout << \' \' << *it; \n" +
+                      " std::cout << \'\\n\';  \n" +
+                      " }\n \n" +
+                      " \n \n" +
+                      " A code block for C:\n \n" +
+                      " {@code  \n" +
+                      " printf(\"hello world\"); \n" +
+                      " }\n \n" +
+                      " \n \n" +
+                      " A code block for Java:\n \n" +
+                      " {@code  \n" +
+                      " public class HelloWorld { \n" +
+                      " public static void main(String[] args) { \n" +
+                      " // Prints \"Hello, World\" to the terminal window. \n" +
+                      " System.out.println(\"Hello, World\"); \n" +
+                      " } \n" +
+                      " } \n" +
+                      " }\n \n" +
+                      " \n \n" +
+                      " A code block for python:\n \n" +
+                      " {@code  \n" +
+                      " print(\'hello world\') \n" +
+                      " }\n \n" +
+                      " \n \n" +
+                      " A python doctest example:\n \n" +
+                      " {@code  \n" +
+                      " >>> 1 + 1 \n" +
+                      " 2 \n" +
+                      " } \n" +
+                      " \n" +
+                      "");
+
+    // and ask the parser to check comments for us
+    System.exit(CommentParser.check(wantedComments));
+  }
+}
index 6250ce5..29b6e06 100644 (file)
@@ -1,6 +1,5 @@
 
 import doxygen_ignore.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_ignore_runme {
@@ -15,10 +14,7 @@ public class doxygen_ignore_runme {
 
   public static void main(String argv[]) 
   {
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_ignore runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_ignore"});
+    CommentParser.parse("doxygen_ignore");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     wantedComments.put("doxygen_ignore.doxygen_ignore.func()",
@@ -39,6 +35,6 @@ public class doxygen_ignore_runme {
       "\n" +
       "");
 
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
index 5d95bd5..cae2b21 100644 (file)
@@ -1,6 +1,5 @@
 
 import doxygen_misc_constructs.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_misc_constructs_runme {
@@ -15,14 +14,7 @@ public class doxygen_misc_constructs_runme {
 
   public static void main(String argv[])
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_misc_constructs runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_misc_constructs"});
+    CommentParser.parse("doxygen_misc_constructs");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
 
@@ -193,8 +185,14 @@ public class doxygen_misc_constructs_runme {
                 "\n" +
                 " @param fileName name of the log file\n");
 
+    wantedComments.put("doxygen_misc_constructs.doxygen_misc_constructs.doc_ends_with_quote()",
+            "This doc comment ends with a quote: \"and that's ok\"");
+
+    wantedComments.put("doxygen_misc_constructs.doxygen_misc_constructs.doc_with_triple_quotes()",
+            "This comment contains embedded triple-quoted string:\n" +
+            "\"\"\"How quaint\"\"\"");
 
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
index 3ffa796..e9d1a06 100644 (file)
@@ -1,5 +1,4 @@
 import doxygen_nested_class.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_nested_class_runme {
@@ -14,14 +13,7 @@ public class doxygen_nested_class_runme {
 
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_nested_class runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_nested_class"});
+    CommentParser.parse("doxygen_nested_class");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -43,6 +35,6 @@ public class doxygen_nested_class_runme {
                " doxShort const variable ");
     
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
index ef1f06a..6b1e2b0 100644 (file)
@@ -1,6 +1,5 @@
 
 import doxygen_parsing_enums_proper.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_parsing_enums_proper_runme {
@@ -15,14 +14,7 @@ public class doxygen_parsing_enums_proper_runme {
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_parsing_enums_proper runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_parsing_enums_proper"});
+    CommentParser.parse("doxygen_parsing_enums_proper");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -61,6 +53,6 @@ public class doxygen_parsing_enums_proper_runme {
                "Post comment after last comma.");
     
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
index 85ec0cb..1e0dd74 100644 (file)
@@ -1,6 +1,5 @@
 
 import doxygen_parsing_enums_simple.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_parsing_enums_simple_runme {
@@ -15,14 +14,7 @@ public class doxygen_parsing_enums_simple_runme {
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_parsing_enums_simple runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_parsing_enums_simple"});
+    CommentParser.parse("doxygen_parsing_enums_simple");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -53,6 +45,6 @@ public class doxygen_parsing_enums_simple_runme {
                "Post comment after last comma.");
     
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
index 4e5f4b4..7cf3b17 100644 (file)
@@ -1,6 +1,5 @@
 
 import doxygen_parsing_enums_typesafe.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_parsing_enums_typesafe_runme {
@@ -15,14 +14,7 @@ public class doxygen_parsing_enums_typesafe_runme {
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_parsing_enums_typesafe runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_parsing_enums_typesafe"});
+    CommentParser.parse("doxygen_parsing_enums_typesafe");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -62,6 +54,6 @@ public class doxygen_parsing_enums_typesafe_runme {
 
     
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
index 4286491..3a41fe5 100644 (file)
@@ -1,6 +1,5 @@
 
 import doxygen_parsing_enums_typeunsafe.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_parsing_enums_typeunsafe_runme {
@@ -15,14 +14,7 @@ public class doxygen_parsing_enums_typeunsafe_runme {
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_parsing_enums_typeunsafe runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_parsing_enums_typeunsafe"});
+    CommentParser.parse("doxygen_parsing_enums_typeunsafe");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -61,6 +53,6 @@ public class doxygen_parsing_enums_typeunsafe_runme {
                "Post comment after last comma.");
     
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
index d58b1f4..10d65fc 100644 (file)
@@ -1,6 +1,5 @@
 
 import doxygen_parsing.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_parsing_runme {
@@ -15,14 +14,7 @@ public class doxygen_parsing_runme {
 
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_parsing runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_parsing"});
+    CommentParser.parse("doxygen_parsing");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -136,6 +128,6 @@ public class doxygen_parsing_runme {
                "");
     
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
index d5c533f..56272bf 100644 (file)
@@ -1,6 +1,5 @@
 
 import doxygen_translate_all_tags.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_translate_all_tags_runme {
@@ -15,14 +14,7 @@ public class doxygen_translate_all_tags_runme {
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_translate_all_tags runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_translate_all_tags"});
+    CommentParser.parse("doxygen_translate_all_tags");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -101,10 +93,10 @@ public class doxygen_translate_all_tags_runme {
                " </li><li>With lots of items \n" +
                " </li><li>lots of lots of items \n" +
                " </li></ul> \n" +
-               " {@link someMember Some description follows }\n" +
+               " {@link someMember Some description follows} with text after\n" +
                " This will only appear in man\n");
     
-    wantedComments.put("doxygen_translate_all_tags.doxygen_translate_all_tags.func07(int)",
+    wantedComments.put("doxygen_translate_all_tags.doxygen_translate_all_tags.func07(int, int, int, int)",
                        " Comment for <b>func07()</b>.\n" +
                        " Note: Here \n" +
                " is the note! \n" +
@@ -115,7 +107,10 @@ public class doxygen_translate_all_tags_runme {
                " The paragraph text. \n" +
                " Maybe even multiline \n" +
                " </p>\n" +
-                " @param a the first param\n");
+                " @param a the first param\n" +
+                " @param b parameter with intent(in)\n" +
+                " @param c parameter with intent(out)\n" +
+               " @param d parameter with intent(in,out)\n");
     
     wantedComments.put("doxygen_translate_all_tags.doxygen_translate_all_tags.func08(int)",
                        "<a id=\"someAnchor\"></a>\n" +
@@ -154,6 +149,6 @@ public class doxygen_translate_all_tags_runme {
                " And here goes simple text \n" +
                "");
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
index 6d74e16..afee4ea 100644 (file)
@@ -1,6 +1,5 @@
 
 import doxygen_translate_links.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_translate_links_runme {
@@ -15,14 +14,7 @@ public class doxygen_translate_links_runme {
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_translate_links runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_translate_links"});
+    CommentParser.parse("doxygen_translate_links");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -64,6 +56,6 @@ public class doxygen_translate_links_runme {
                "");
     
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
\ No newline at end of file
index 55e5d23..b049a64 100644 (file)
@@ -1,6 +1,5 @@
 
 import doxygen_translate.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -16,14 +15,7 @@ public class doxygen_translate_runme {
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_translate runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_translate"});
+    CommentParser.parse("doxygen_translate");
 
     Map<String, String> wantedComments = new HashMap<String, String>();
     
@@ -274,6 +266,6 @@ public class doxygen_translate_runme {
                 "");
         
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
index a8d1c38..2b662ca 100644 (file)
 
   int foo_mm(int min = 1, int max = 2) {return min + max; }
 %}
+
+
+// Extended constructors
+%extend Extending0 {
+  Extending0() { return new Extending0(); }
+}
+%extend Extending1 {
+  Extending1(int one) { return new Extending1(); }
+}
+%extend Extending2 {
+  Extending2(int one, const char *two) { return new Extending2(); }
+}
+%extend ExtendingOptArgs1 {
+  ExtendingOptArgs1(int one = 0) { return new ExtendingOptArgs1(); }
+}
+%extend ExtendingOptArgs2 {
+  ExtendingOptArgs2(int one = 0, const char* two = NULL) { return new ExtendingOptArgs2(); }
+}
+
+%inline %{
+struct Extending0 {};
+struct Extending1 {};
+struct Extending2 {};
+struct ExtendingOptArgs1 {};
+struct ExtendingOptArgs2 {};
+%}
index 5bde387..d83732a 100644 (file)
@@ -12,7 +12,7 @@
 #endif
 %}
 
-#if defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPYTHON)
+#if defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPYTHON) || defined(SWIGRUBY)
 
 %include "std_auto_ptr.i"
 
index 63b8692..92559bb 100644 (file)
@@ -15,6 +15,7 @@ top_builddir = @top_builddir@
 CPP_TEST_CASES += \
        lua_no_module_global \
        lua_inherit_getitem  \
+       lua_lightuserdata  \
 
 
 C_TEST_CASES += \
diff --git a/Examples/test-suite/lua/lua_lightuserdata_runme.lua b/Examples/test-suite/lua/lua_lightuserdata_runme.lua
new file mode 100644 (file)
index 0000000..c1c3c1d
--- /dev/null
@@ -0,0 +1,7 @@
+require("import") -- the import fn
+import("lua_lightuserdata") -- import lib
+
+local t = lua_lightuserdata
+local d = t.get_lightuserdata()
+local r = t.check_lighuserdata(d)
+assert(r)
diff --git a/Examples/test-suite/lua_lightuserdata.i b/Examples/test-suite/lua_lightuserdata.i
new file mode 100644 (file)
index 0000000..9069b6a
--- /dev/null
@@ -0,0 +1,17 @@
+%module lua_lightuserdata
+
+%native(get_lightuserdata) int get_lightuserdata(lua_State* L);
+%{
+static int foo;
+int get_lightuserdata(lua_State* L)
+{
+  lua_pushlightuserdata(L, &foo);
+  return 1;
+}
+%}
+
+%inline %{
+bool check_lighuserdata(const void* d) {
+  return d == &foo;
+}
+%}
index 3c8f3b1..1d54a47 100644 (file)
@@ -5,6 +5,7 @@
 LANGUAGE     = octave
 OCTAVE       = @OCTAVE@
 SCRIPTSUFFIX = _runme.m
+PCHSUPPORT   = @PCHSUPPORT@
 
 srcdir       = @srcdir@
 top_srcdir   = @top_srcdir@
@@ -61,6 +62,23 @@ CSRCS      = octave_empty.c
        +$(swig_and_compile_multi_cpp)
        $(run_testcase)
 
+# Pre-compile Octave headers, if supported
+
+ifeq (yes,$(PCHSUPPORT))
+
+export OCTHEADERSSRC = @top_srcdir@/Lib/octave/octheaders.hpp
+export OCTHEADERS    = @top_builddir@/Examples/test-suite/octave/octheaders.hpp
+export OCTHEADERSGCH = $(OCTHEADERS).gch
+export SWIGOCTHDROPT = -DSWIG_OCTAVE_EXTERNAL_OCTHEADERS
+export IOCTHEADERS   = -I@top_builddir@/Examples/test-suite/octave @PCHINCLUDEARG@ $(OCTHEADERS)@PCHINCLUDEEXT@
+
+$(OCTHEADERSGCH): $(OCTHEADERSSRC)
+       $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile octave_precompile_headers
+
+$(NOT_BROKEN_TEST_CASES) $(BROKEN_TEST_CASES): $(OCTHEADERSGCH)
+
+endif
+
 # Runs the testcase. A testcase is only run if
 # a file is found which has _runme.m appended after the testcase name.
 run_testcase = \
index be06f7e..4c0507c 100644 (file)
@@ -11,7 +11,7 @@ endif
 LANGUAGE     = python
 PYTHON       = $(PYBIN)
 PYCODESTYLE       = @PYCODESTYLE@
-PYCODESTYLE_FLAGS = --ignore=E252,E30,E402,E501,E731,W291,W391
+PYCODESTYLE_FLAGS = --ignore=E252,E30,E402,E501,E731,E741,W291,W391
 
 #*_runme.py for Python 2.x, *_runme3.py for Python 3.x
 PY2SCRIPTSUFFIX = _runme.py
index 6002d49..7bc9186 100644 (file)
@@ -279,3 +279,5 @@ check(inspect.getdoc(process3), "process3(int _from, int _in, int var) -> int")
 check(inspect.getdoc(process4), "process4(int _from=0, int _in=1, int var=2) -> int")
 
 check(inspect.getdoc(process_complex_defval), "process_complex_defval(val=PROCESS_DEFAULT_VALUE, factor=some_type(-1)) -> int")
+
+check(inspect.getdoc(a_structure.__init__), "__init__(a_structure self) -> a_structure", None, skip)
diff --git a/Examples/test-suite/python/cpp11_shared_ptr_template_upcast_runme.py b/Examples/test-suite/python/cpp11_shared_ptr_template_upcast_runme.py
new file mode 100644 (file)
index 0000000..08a95c2
--- /dev/null
@@ -0,0 +1,5 @@
+from cpp11_shared_ptr_template_upcast import *
+
+pd = MakePrintableDerived(20)
+pd.GetResult()
+pd.GetFormatted()
diff --git a/Examples/test-suite/python/cpp11_shared_ptr_upcast_runme.py b/Examples/test-suite/python/cpp11_shared_ptr_upcast_runme.py
new file mode 100644 (file)
index 0000000..08546a4
--- /dev/null
@@ -0,0 +1,63 @@
+from cpp11_shared_ptr_upcast import *
+
+# This is a port from the Ruby equivalent test and some tests ported from
+# Examples/test-suite/ruby/cpp11_shared_ptr_upcast_runme.rb are not working and commented out with:
+# not working:
+
+def swig_assert_equal_simple(expected, got):
+    if expected != got:
+        raise RuntimeError("Expected: {}. Got: {}")
+
+# non-overloaded
+swig_assert_equal_simple(7, derived_num1(Derived(7)))
+swig_assert_equal_simple(7, derived_num2([Derived(7)]))
+swig_assert_equal_simple(7, derived_num3({0: Derived(7)}))
+
+swig_assert_equal_simple(-1, base_num1(Derived(7)))
+swig_assert_equal_simple(-1, base_num2([Derived(7)]))
+swig_assert_equal_simple(-1, base_num3({0: Derived(7)}))
+
+swig_assert_equal_simple(999, derived_num1(None))
+# not working: swig_assert_equal_simple(999, derived_num2([None]))
+# not working: swig_assert_equal_simple(999, derived_num3({0: None}))
+
+swig_assert_equal_simple(999, base_num1(None))
+# not working: swig_assert_equal_simple(999, base_num2([None]))
+# not working: swig_assert_equal_simple(999, base_num3({0: None}))
+
+# overloaded
+swig_assert_equal_simple(7, derived_num(Derived(7)))
+swig_assert_equal_simple(7, derived_num([Derived(7)]))
+swig_assert_equal_simple(7, derived_num({0: Derived(7)}))
+
+swig_assert_equal_simple(-1, base_num(Derived(7)))
+swig_assert_equal_simple(-1, base_num([Derived(7)]))
+swig_assert_equal_simple(-1, base_num({0: Derived(7)}))
+
+# ptr to shared_ptr
+swig_assert_equal_simple(7, derived2_num1(Derived2(7)))
+swig_assert_equal_simple(7, derived2_num2([Derived2(7)]))
+swig_assert_equal_simple(7, derived2_num3({0: Derived2(7)}))
+
+swig_assert_equal_simple(-1, base2_num1(Derived2(7)))
+
+# not working: try:
+# not working:     # Upcast for pointers to shared_ptr in this generic framework has not been implemented
+# not working:     swig_assert_equal_simple(-1, base2_num2([Derived2(7)]))
+# not working:     raise RuntimeError, "Failed to catch TypeError"
+# not working: except TypeError:
+# not working:     pass
+# not working: try:
+# not working:     # Upcast for pointers to shared_ptr in this generic framework has not been implemented
+# not working:     swig_assert_equal_simple(-1, base2_num3({0: Derived2(7)}))
+# not working:     raise RuntimeError, "Failed to catch TypeError"
+# not working: except TypeError:
+# not working:     pass
+
+swig_assert_equal_simple(888, derived2_num1(None))
+swig_assert_equal_simple(999, derived2_num2([None])) # although 888 would be more consistent
+swig_assert_equal_simple(999, derived2_num3({0: None})) # although 888 would be more consistent
+
+swig_assert_equal_simple(888, base2_num1(None))
+swig_assert_equal_simple(999, base2_num2([None])) # although 888 would be more consistent
+swig_assert_equal_simple(999, base2_num3({0: None})) # although 888 would be more consistent
diff --git a/Examples/test-suite/python/cpp_parameters_runme.py b/Examples/test-suite/python/cpp_parameters_runme.py
new file mode 100644 (file)
index 0000000..99d14ad
--- /dev/null
@@ -0,0 +1,296 @@
+from cpp_parameters import *
+
+# Testing correct and incorrect parameter counts being passed (kwargs and non-kwargs)
+# Note that the implementation depends a lot on whether zero, one, two or more args are being wrapped
+
+def is_python_fastproxy():
+    """Return True if SWIG is generating Python code using -fastproxy."""
+    import cpp_parameters
+    # Note: _swig_new_instance_method is only generated when using -fastproxy
+    return hasattr(cpp_parameters, "_swig_new_instance_method")
+
+# Zero parameters expected
+x = Zero()
+try:
+    x = Zero(z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    x = Zero(0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    x.zero(z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    x.zero(0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    Zero.stat_zero(z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    Zero.stat_zero(0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    global_zero(z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    global_zero(0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+# One mandatory parameter expected
+x = One(1)
+try:
+    x = One(a=1, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    x = One(1, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    x.one(a=1, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    x.one(1, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    One.stat_one(a=1, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    One.stat_one(1, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    global_one(a=1, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    global_one(1, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+# Two mandatory parameters expected
+x = Two(1, 2)
+try:
+    x = Two(a=1, b=2, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    x = Two(1, 2, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    x.two(a=1, b=2, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    x.two(1, 2, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    Two.stat_two(a=1, b=2, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    Two.stat_two(1, 2, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    global_two(a=1, b=2, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    global_two(1, 2, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+# Single optional parameter expected
+x = Single(1)
+try:
+    x = Single(a=1, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    x = Single(1, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    x.single(a=1, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    x.single(1, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    Single.stat_single(a=1, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    Single.stat_single(1, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    global_single(a=1, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    global_single(1, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+# Test that -builtin option throws TypeError if kwargs are used even when they look like they should work, kwargs are not supported unless using -keyword.
+# Also same for -fastproxy option except that kwargs are supported by default for constructors. TODO: Fix inconsistency.
+
+if is_python_builtin() or is_python_fastproxy():
+    # One mandatory parameter in API
+    x = One(1)
+    if is_python_fastproxy():
+        x = One(a=1)
+    else:
+        try:
+            x = One(a=1)
+            raise RuntimeError("Missed throw")
+        except TypeError:
+            pass
+    try:
+        x.one(a=1)
+        raise RuntimeError("Missed throw")
+    except TypeError:
+        pass
+    try:
+        One.stat_one(a=1)
+        raise RuntimeError("Missed throw")
+    except TypeError:
+        pass
+    try:
+        global_one(a=1)
+        raise RuntimeError("Missed throw")
+    except TypeError:
+        pass
+
+    # Two mandatory parameters in API
+    x = Two(1, 2)
+    if is_python_fastproxy():
+        x = Two(a=1, b=2)
+    else:
+        try:
+            x = Two(a=1, b=2)
+            raise RuntimeError("Missed throw")
+        except TypeError:
+            pass
+    try:
+        x.two(a=1, b=2)
+        raise RuntimeError("Missed throw")
+    except TypeError:
+        pass
+    try:
+        Two.stat_two(a=1, b=2)
+        raise RuntimeError("Missed throw")
+    except TypeError:
+        pass
+    try:
+        global_two(a=1, b=2)
+        raise RuntimeError("Missed throw")
+    except TypeError:
+        pass
+
+    # Single optional parameter in API
+    x = Single(1)
+    if is_python_fastproxy():
+        x = Single(a=1)
+    else:
+        try:
+            x = Single(a=1)
+            raise RuntimeError("Missed throw")
+        except TypeError:
+            pass
+    try:
+        x.single(a=1)
+        raise RuntimeError("Missed throw")
+    except TypeError:
+        pass
+    try:
+        Single.stat_single(a=1)
+        raise RuntimeError("Missed throw")
+    except TypeError:
+        pass
+    try:
+        global_single(a=1)
+        raise RuntimeError("Missed throw")
+    except TypeError:
+        pass
+
+else:
+    # Non-builtin should work as expected
+    # One mandatory parameter in API
+    x = One(a=1)
+    x.one(a=1)
+    One.stat_one(a=1)
+    global_one(a=1)
+
+    # Two mandatory parameters in API
+    x = Two(a=1, b=2)
+    x.two(a=1, b=2)
+    Two.stat_two(a=1, b=2)
+    global_two(a=1, b=2)
+
+    # Single optional parameter in API
+    x = Single(a=1)
+    x.single(a=1)
+    Single.stat_single(a=1)
+    global_single(a=1)
index 242b275..b7929c0 100644 (file)
@@ -9,8 +9,8 @@ class B(A):
     def get_first(self):
         return A.get_first(self) + u" world!"
 
-    def process_text(self, string):
-        self.smem = u"hello"
+    def process_text(self, s):
+        self.smem = s
 
 
 b = B(u"hello")
index 9ef8dbd..4cd5001 100644 (file)
@@ -60,7 +60,7 @@ comment_verifier.check(inspect.getdoc(doxygen_basic_translate.function5),
 comment_verifier.check(inspect.getdoc(doxygen_basic_translate.function6),
     """\
 Test for default args
-:type a: int
+:type a: int, optional
 :param a: Some parameter, default is 42"""
 )
 comment_verifier.check(inspect.getdoc(doxygen_basic_translate.function7),
@@ -70,6 +70,16 @@ Test for a parameter with difficult type
 :type a: :py:class:`Shape`
 :param a: Very strange param"""
 )
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate.function8),
+    """\
+Test variadic function
+:param ...: extra args"""
+)
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate.function9),
+    """\
+Test unnamed argument
+:param baz: Description of baz"""
+)
 
 comment_verifier.check(inspect.getdoc(doxygen_basic_translate.Atan2),
     """\
index b75045d..a24f5de 100644 (file)
@@ -58,7 +58,7 @@ comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style2.function5),
 comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style2.function6),
     """\
 Test for default args
-:type a: int
+:type a: int, optional
 :param a: Some parameter, default is 42"""
 )
 comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style2.function7),
diff --git a/Examples/test-suite/python/doxygen_basic_translate_style3_runme.py b/Examples/test-suite/python/doxygen_basic_translate_style3_runme.py
new file mode 100644 (file)
index 0000000..6872703
--- /dev/null
@@ -0,0 +1,82 @@
+import doxygen_basic_translate_style3
+import inspect
+import string
+import sys
+import comment_verifier
+
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style3.function),
+    """\
+Brief description.
+
+The comment text.
+
+Author: Some author
+
+:rtype: int
+:return: Some number
+
+See also: function2"""
+)
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style3.function2),
+    """\
+A test of a very very very very very very very very very very very very very very very very
+very very very very very long comment string."""
+)
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style3.function3),
+    """*Overload 1:*
+A test for overloaded functions
+This is function **one**
+
+|
+
+*Overload 2:*
+A test for overloaded functions
+This is function **two**"""
+)
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style3.function4),
+    """\
+A test of some mixed tag usage
+If: CONDITION {
+This *code* fragment shows us something .
+Title: Minuses:
+* it\'s senseless
+* it\'s stupid
+* it\'s null
+
+Warning: This may not work as expected
+
+.. code-block:: c++
+
+    int main() { while(true); }
+
+    int testBlankLine() {}
+}"""
+)
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style3.function5),
+    """This is a post comment."""
+)
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style3.function6),
+    """\
+Test for default args
+:type a: int, optional
+:param a: Some parameter, default is 42"""
+)
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style3.function7),
+    """\
+Test for a parameter with difficult type
+(mostly for python)
+:type a: :py:class:`Shape`
+:param a: Very strange param"""
+)
+
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style3.Atan2),
+    """\
+Multiple parameters test.
+
+:type y: float
+:param y: Vertical coordinate.
+:type x: float
+:param x: Horizontal coordinate.
+:rtype: float
+:return: Arc tangent of ``y/x``."""
+)
diff --git a/Examples/test-suite/python/doxygen_code_blocks_runme.py b/Examples/test-suite/python/doxygen_code_blocks_runme.py
new file mode 100644 (file)
index 0000000..46a0a3d
--- /dev/null
@@ -0,0 +1,58 @@
+import doxygen_code_blocks
+import inspect
+import string
+import sys
+import comment_verifier
+
+comment_verifier.check(inspect.getdoc(doxygen_code_blocks.function),
+    """\
+Test for code blocks
+
+.. code-block:: c++
+
+    simple code block
+
+More advanced usage with C++ characters:
+
+.. code-block:: c++
+
+    std::vector<int> first;                                // empty vector of ints
+    std::vector<int> second (4,100);                       // four ints with value 100
+    std::vector<int> third (second.begin(),second.end());  // iterating through second
+    std::vector<int> fourth (third);                       // a copy of third
+     // the iterator constructor can also be used to construct from arrays:
+    int myints[] = {16,2,77,29};
+    std::vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );
+
+    std::cout << "The contents of fifth are:";
+    for (std::vector<int>::iterator it = fifth.begin(); it != fifth.end(); ++it)
+      std::cout << ' ' << *it;
+    std::cout << '\\n';
+
+A code block for C:
+
+.. code-block:: c
+
+    printf("hello world");
+
+A code block for Java:
+
+.. code-block:: java
+
+    public class HelloWorld {
+        public static void main(String[] args) {
+            // Prints "Hello, World" to the terminal window.
+            System.out.println("Hello, World");
+        }
+    }
+
+A code block for python:
+
+.. code-block:: python
+
+    print('hello world')
+
+A python doctest example:
+
+>>> 1 + 1
+2""")
index 11aa53b..44f607f 100644 (file)
@@ -12,7 +12,7 @@ comment_verifier.check(inspect.getdoc(doxygen_misc_constructs.getAddress),
 :param fileName: name of the file, where the source line is located
 :type line: int
 :param line: line number
-:type isGetSize: boolean
+:type isGetSize: boolean, optional
 :param isGetSize: if set, for every object location both address and size are returned
 
 Connection::getId() """)
@@ -131,3 +131,13 @@ Spaces at the start of line should be taken into account:
 :type fileName: string
 :param fileName: name of the log file"""
 );
+
+comment_verifier.check(inspect.getdoc(doxygen_misc_constructs.doc_ends_with_quote),
+    r'''This doc comment ends with a quote: "and that's ok"'''
+);
+
+comment_verifier.check(inspect.getdoc(doxygen_misc_constructs.doc_with_triple_quotes),
+    r'''This comment contains embedded triple-quoted string:
+
+    """How quaint"""'''
+);
index df1c0eb..e884cf9 100644 (file)
@@ -82,7 +82,7 @@ r"""Comment for **func03()**.
 
 *italicword*
 
-emphazedWord
+*emphazedWord*
 
 
 
@@ -175,7 +175,7 @@ This will only appear in LATeX
 
 
 
-someMember Some description follows
+someMember Some description follows with text after
 
 
 
@@ -196,7 +196,7 @@ is the note!
 This is an overloaded member function, provided for convenience.
 It differs from the above function only in what argument(s) it accepts.
 
-someword
+``someword``
 
 
 
@@ -209,7 +209,13 @@ Maybe even multiline
 
 
 :type a: int
-:param a: the first param""")
+:param a: the first param
+:type b: int, in
+:param b: parameter with intent(in)
+:type c: int, out
+:param c: parameter with intent(out)
+:type d: int, in/out
+:param d: parameter with intent(in,out)""")
 
 comment_verifier.check(inspect.getdoc(doxygen_translate_all_tags.func08),
 r"""Text after anchor.
index d698ba8..38dca2e 100644 (file)
@@ -80,7 +80,7 @@ is the note!
 This is an overloaded member function, provided for convenience.
 It differs from the above function only in what argument(s) it accepts.
 
-someword
+``someword``
 
 
 
index a2d4731..31d49d2 100644 (file)
@@ -79,3 +79,46 @@ if rfoo(n=11, x=22) != -11:
 
 if rfoo(x=11, n=22) != 11:
     raise RuntimeError
+
+# Extended constructors
+e = Extending0()
+e = Extending1(one=1)
+e = Extending1(1)
+e = Extending2(1, "two")
+e = Extending2(1, two="two")
+e = Extending2(two="two", one=1)
+e = ExtendingOptArgs1()
+e = ExtendingOptArgs1(1)
+e = ExtendingOptArgs2(one=1)
+e = ExtendingOptArgs2()
+e = ExtendingOptArgs2(one=1)
+e = ExtendingOptArgs2(two="two")
+e = ExtendingOptArgs2(two="two", one=1)
+
+# Invalid kwargs test
+h = Hello()
+try:
+    h = Hello(nonexistent=10)
+    raise RuntimeError("missed exception")
+except TypeError as e:
+    pass
+
+f = Foo(1)
+f = Foo(a=1)
+try:
+    f = Foo(nonexistent=10)
+    raise RuntimeError("missed exception")
+except TypeError as e:
+    pass
+
+try:
+    f = Foo(a=1, nonexistent=10)
+    raise RuntimeError("missed exception")
+except TypeError as e:
+    pass
+
+try:
+    f = Foo(1, nonexistent=10)
+    raise RuntimeError("missed exception")
+except TypeError as e:
+    pass
index eddda53..e5f6b07 100644 (file)
@@ -21,3 +21,16 @@ if grabstaticpath() != None:
 Test.static_func()
 if grabstaticpath() != os.path.basename(mypath):
     raise RuntimeError("grabstaticpath failed")
+
+# slots test
+fs = ForSlots()
+if fs.ValidVariable != 99:
+    raise RuntimeError("ValidVariable failed")
+fs.ValidVariable = 11
+if fs.ValidVariable != 11:
+    raise RuntimeError("ValidVariable failed")
+try:
+    fs.Invalid = 22
+    raise RuntimeError("It should not be possible to set a random variable name")
+except AttributeError:
+    pass
index 0494943..883097e 100644 (file)
@@ -42,13 +42,31 @@ import os.path
 %}
 
 %inline %{
-
 class Test {
 public:
   static void static_func() {};
   void funk() {};
 };
+%}
+
+// Github issue #1674
+%extend ForSlots {
+  %pythoncode %{
+        __slots__ = ["this"]
+    %}
+}
+// While __slots__ does not contain 'ValidVariable' in the list, it is still possible
+// to set 'ValidVariable'. A little odd, but the whole attribute setting is bypassed
+// for setting C/C++ member variables.
+// Not sure how to test the equivalent for -builtin.
+%inline %{
+struct ForSlots {
+  int ValidVariable;
+  ForSlots() : ValidVariable(99) {}
+};
+%}
 
+%inline %{
 #ifdef SWIGPYTHON_BUILTIN
 bool is_python_builtin() { return true; }
 #else
index 33e9d90..98835b9 100644 (file)
@@ -18,6 +18,7 @@ C_TEST_CASES += \
 
 CPP_TEST_CASES += \
        r_double_delete \
+       r_memory_leak \
        r_overload_array \
        r_sexp \
         r_overload_comma \
diff --git a/Examples/test-suite/r/abstract_access_runme.R b/Examples/test-suite/r/abstract_access_runme.R
new file mode 100644 (file)
index 0000000..f6fb409
--- /dev/null
@@ -0,0 +1,74 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+
+dyn.load(paste("abstract_access", .Platform$dynlib.ext, sep=""))
+source("abstract_access.R")
+
+dd <- D()
+unittest(1, dd$z())
+unittest(1, dd$do_x())
+
+## Original version allowed dd$z <- 2
+tryCatch({
+    dd$z <- 2
+    # force an error if the previous line doesn't raise an exception
+    stop("Test Failure A")
+}, error = function(e) {
+    if (e$message == "Test Failure A") {
+      # Raise the error again to cause a failed test
+      stop(e)
+    }
+    message("Correct - no dollar assignment method found")
+}
+)
+
+tryCatch({
+    dd[["z"]] <- 2
+    # force an error if the previous line doesn't raise an exception
+    stop("Test Failure B")
+}, error = function(e) {
+  if (e$message == "Test Failure B") {
+    # Raise the error again to cause a failed test
+    stop(e)
+  }
+  message("Correct - no dollar assignment method found")
+}
+)
+
+## The methods are attached to the parent class - see if we can get
+## them
+tryCatch({
+    m1 <- getMethod('$', "_p_A")
+}, error = function(e) {
+    stop("No $ method found - there should be one")
+}
+)
+
+## These methods should not be present
+## They correspond to the tests that are expected
+## to fail above.
+tryCatch({
+    m2 <- getMethod('$<-', "_p_A")
+    # force an error if the previous line doesn't raise an exception
+    stop("Test Failure C")
+}, error = function(e) {
+  if (e$message == "Test Failure C") {
+    # Raise the error again to cause a failed test
+    stop(e)
+  }
+  message("Correct - no dollar assignment method found")
+}
+)
+
+tryCatch({
+    m3 <- getMethod('[[<-', "_p_A")
+    # force an error if the previous line doesn't raise an exception
+    stop("Test Failure D")
+}, error = function(e) {
+  if (e$message == "Test Failure D") {
+    # Raise the error again to cause a failed test
+    stop(e)
+  }
+  message("Correct - no list assignment method found")
+}
+)
diff --git a/Examples/test-suite/r/r_memory_leak_runme.R b/Examples/test-suite/r/r_memory_leak_runme.R
new file mode 100644 (file)
index 0000000..ef6533a
--- /dev/null
@@ -0,0 +1,26 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+
+dyn.load(paste("r_memory_leak", .Platform$dynlib.ext, sep=""))
+source("r_memory_leak.R")
+cacheMetaData(1)
+
+a <- Foo();
+unittest(Foo_get_count(), 1);
+b <- Foo();
+unittest(Foo_get_count(), 2);
+
+# Normal behaviour
+invisible(trigger_internal_swig_exception("no problem", a));
+unittest(Foo_get_count(), 2);
+# SWIG exception introduced
+result <- tryCatch({
+  trigger_internal_swig_exception("null", b);
+}, warning = function(w) {
+  # print("        Hum... We received a warning, but this should be an error");
+  unittest(1,0);
+}, error = function(e) {
+  # print("        Gotcha!");
+  unittest(1,1);
+})
+unittest(Foo_get_count(), 2);
diff --git a/Examples/test-suite/r_memory_leak.i b/Examples/test-suite/r_memory_leak.i
new file mode 100644 (file)
index 0000000..a240097
--- /dev/null
@@ -0,0 +1,40 @@
+%module r_memory_leak
+
+%include <std_string.i>
+
+%typemap(in) Foo* foo
+{
+  $1 = new Foo;
+}
+%typemap(freearg) Foo* foo
+{
+  printf("    \"        Object deleted\"\n");
+  delete $1;
+}
+%typemap(out) Foo* verify_no_memory_leak
+{
+  if ($1 == NULL)
+    SWIG_exception_fail(SWIG_RuntimeError, "Let's see how the bindings manage this exception!");
+}
+%typemap(scoerceout) Foo*
+  %{ if (!is.null($result) && !is.logical($result)) {$result <- new("$R_class", ref=$result) ;}; %}
+
+%inline %{
+  #include <string>
+
+  class Foo {
+      static unsigned count;
+    public:
+      Foo() { ++count; }
+      ~Foo() { --count; }
+      static unsigned get_count() { return count; }
+  };
+
+  unsigned Foo::count = 0;
+
+  static Foo* trigger_internal_swig_exception(const std::string& message, Foo* foo)
+  {
+    return (message == "null") ? NULL : foo;
+  };
+
+%}
index d75cdb0..2c59029 100644 (file)
@@ -23,6 +23,7 @@ CPP_TEST_CASES = \
        li_std_wstring_inherit \
        primitive_types \
        ruby_alias_method \
+       ruby_global_immutable_vars_cpp \
        ruby_keywords \
        ruby_minherit_shared_ptr \
        ruby_naming \
@@ -48,6 +49,7 @@ C_TEST_CASES += \
        li_cstring \
        ruby_alias_global_function \
        ruby_alias_module_function \
+       ruby_global_immutable_vars \
        ruby_manual_proxy \
 
 include $(srcdir)/../common.mk
@@ -57,6 +59,8 @@ SWIGOPT += -w801 -noautorename -features autodoc=4
 
 # Custom tests - tests with additional commandline options
 ruby_alias_global_function.ctest: SWIGOPT += -globalmodule
+ruby_global_immutable_vars.ctest: SWIGOPT += -globalmodule
+ruby_global_immutable_vars_cpp.cpptest: SWIGOPT += -globalmodule
 ruby_naming.cpptest: SWIGOPT += -autorename
 
 # Rules for the different types of tests
diff --git a/Examples/test-suite/ruby/global_immutable_vars_cpp_runme.rb b/Examples/test-suite/ruby/global_immutable_vars_cpp_runme.rb
new file mode 100644 (file)
index 0000000..7897f7d
--- /dev/null
@@ -0,0 +1,48 @@
+#!/usr/bin/env ruby
+#
+# C++ version of global_immutable_vars_runme.rb
+#
+
+require 'swig_assert'
+
+require 'global_immutable_vars_cpp'
+
+# first check if all variables can be read
+swig_assert_each_line( <<EOF )
+Global_immutable_vars_cpp::default_mutable_var == 40
+Global_immutable_vars_cpp::global_immutable_var == 41
+Global_immutable_vars_cpp::specific_mutable_var == 42
+Global_immutable_vars_cpp::global_mutable_var == 43
+Global_immutable_vars_cpp::specific_immutable_var == 44
+EOF
+
+# check that all mutable variables can be modified
+swig_assert_each_line( <<EOF )
+Global_immutable_vars_cpp::default_mutable_var = 80
+Global_immutable_vars_cpp::default_mutable_var == 80
+Global_immutable_vars_cpp::specific_mutable_var = 82
+Global_immutable_vars_cpp::specific_mutable_var == 82
+Global_immutable_vars_cpp::global_mutable_var = 83
+Global_immutable_vars_cpp::global_mutable_var == 83
+EOF
+
+# now check that immutable variables cannot be modified
+had_exception = false
+begin
+  Global_immutable_vars_cpp::global_immutable_var = 81
+rescue NoMethodError => e
+  had_exception = true
+end
+swig_assert(had_exception, nil,
+            "Global_immutable_vars_cpp::global_immutable_var is writable (expected to be immutable)")
+
+had_exception = false
+begin
+  Global_immutable_vars_cpp::specific_immutable_var = 81
+rescue NoMethodError => e
+  had_exception = true
+end
+swig_assert(had_exception, nil,
+            "Global_immutable_vars_cpp::specific_immutable_var is writable (expected to be immutable)")
+
+swig_assert(Global_immutable_vars_cpp::check_values(80, 41, 82, 83, 44) == 1, nil, "Check values failed")
diff --git a/Examples/test-suite/ruby/global_immutable_vars_runme.rb b/Examples/test-suite/ruby/global_immutable_vars_runme.rb
new file mode 100644 (file)
index 0000000..ffbea27
--- /dev/null
@@ -0,0 +1,52 @@
+#!/usr/bin/env ruby
+#
+# Here the proper generation of mutable and immutable variables is tested
+# in the target language.
+# Immutable variables do not have "<var>=" methods generated by SWIG,
+# therefore trying to assign these variables shall throw a NoMethodError
+# exception.
+#
+
+require 'swig_assert'
+
+require 'global_immutable_vars'
+
+# first check if all variables can be read
+swig_assert_each_line( <<EOF )
+Global_immutable_vars::default_mutable_var == 40
+Global_immutable_vars::global_immutable_var == 41
+Global_immutable_vars::specific_mutable_var == 42
+Global_immutable_vars::global_mutable_var == 43
+Global_immutable_vars::specific_immutable_var == 44
+EOF
+
+# check that all mutable variables can be modified
+swig_assert_each_line( <<EOF )
+Global_immutable_vars::default_mutable_var = 80
+Global_immutable_vars::default_mutable_var == 80
+Global_immutable_vars::specific_mutable_var = 82
+Global_immutable_vars::specific_mutable_var == 82
+Global_immutable_vars::global_mutable_var = 83
+Global_immutable_vars::global_mutable_var == 83
+EOF
+
+# now check that immutable variables cannot be modified
+had_exception = false
+begin
+  Global_immutable_vars::global_immutable_var = 81
+rescue NoMethodError => e
+  had_exception = true
+end
+swig_assert(had_exception, nil,
+            "Global_immutable_vars::global_immutable_var is writable (expected to be immutable)")
+
+had_exception = false
+begin
+  Global_immutable_vars::specific_immutable_var = 81
+rescue NoMethodError => e
+  had_exception = true
+end
+swig_assert(had_exception, nil,
+            "Global_immutable_vars::specific_immutable_var is writable (expected to be immutable)")
+
+swig_assert(Global_immutable_vars::check_values(80, 41, 82, 83, 44) == 1, nil, "Check values failed")
diff --git a/Examples/test-suite/ruby/li_std_auto_ptr_runme.rb b/Examples/test-suite/ruby/li_std_auto_ptr_runme.rb
new file mode 100644 (file)
index 0000000..cec48a5
--- /dev/null
@@ -0,0 +1,27 @@
+#!/usr/bin/env ruby
+
+require 'swig_assert'
+
+require 'li_std_auto_ptr'
+
+def gc_check(expected_count)
+#  GC.start(full_mark: true, immediate_sweep: true)
+  GC.start
+# GC is not reliably run, skip check
+#  swig_assert_equal_simple(expected_count, Li_std_auto_ptr::Klass::getTotal_count())
+end
+
+k1 = Li_std_auto_ptr::makeKlassAutoPtr("first")
+k2 = Li_std_auto_ptr::makeKlassAutoPtr("second")
+swig_assert_equal_simple(2, Li_std_auto_ptr::Klass::getTotal_count())
+
+gc_check(2)
+k1 = nil
+gc_check(1)
+
+swig_assert_equal_simple(k2.getLabel(), "second")
+gc_check(1)
+
+k2 = nil
+gc_check(0)
+
index 04129f4..b7ebea0 100644 (file)
@@ -18,10 +18,12 @@ require 'newobject2'
 include Newobject2
 
 GC.track_class = Foo
+GC.disable
 GC.stats if $VERBOSE
 100.times { foo1 = makeFoo }
 GC.stats if $VERBOSE
 swig_assert( 'fooCount == 100', nil, "but is #{fooCount}" )
+GC.enable
 GC.start
 swig_assert( 'fooCount <= 1', nil, "but is #{fooCount}" )
 
diff --git a/Examples/test-suite/ruby/ruby_global_immutable_vars_cpp_runme.rb b/Examples/test-suite/ruby/ruby_global_immutable_vars_cpp_runme.rb
new file mode 100644 (file)
index 0000000..5523b59
--- /dev/null
@@ -0,0 +1,48 @@
+#!/usr/bin/env ruby
+#
+# C++ version of ruby_global_immutable_vars_runme.rb.
+#
+
+require 'swig_assert'
+
+require 'ruby_global_immutable_vars_cpp'
+
+# first check if all variables can be read
+swig_assert_each_line( <<EOF )
+$default_mutable_var == 40
+$global_immutable_var == 41
+$specific_mutable_var == 42
+$global_mutable_var == 43
+$specific_immutable_var == 44
+EOF
+
+# check that all mutable variables can be modified
+swig_assert_each_line( <<EOF )
+$default_mutable_var = 80
+$default_mutable_var == 80
+$specific_mutable_var = 82
+$specific_mutable_var == 82
+$global_mutable_var = 83
+$global_mutable_var == 83
+EOF
+
+# now check that immutable variables cannot be modified
+had_exception = false
+begin
+  $global_immutable_var = 81
+rescue NameError => e
+  had_exception = true
+end
+swig_assert(had_exception, nil,
+            "$global_immutable_var is writable (expected to be immutable)")
+
+had_exception = false
+begin
+  $specific_immutable_var = 81
+rescue NameError => e
+  had_exception = true
+end
+swig_assert(had_exception, nil,
+            "$specific_immutable_var is writable (expected to be immutable)")
+
+swig_assert(check_values(80, 41, 82, 83, 44) == 1, nil, "Check values failed")
diff --git a/Examples/test-suite/ruby/ruby_global_immutable_vars_runme.rb b/Examples/test-suite/ruby/ruby_global_immutable_vars_runme.rb
new file mode 100644 (file)
index 0000000..45a8506
--- /dev/null
@@ -0,0 +1,52 @@
+#!/usr/bin/env ruby
+#
+# This test program is similar to global_immutable_vars_runme.rb
+# with the difference that the global variables to check are also
+# Ruby global variables (SWIG Ruby option "-globalmodule").
+#
+# Immutable global variables shall throw a NameError exception.
+#
+
+require 'swig_assert'
+
+require 'ruby_global_immutable_vars'
+
+# first check if all variables can be read
+swig_assert_each_line( <<EOF )
+$default_mutable_var == 40
+$global_immutable_var == 41
+$specific_mutable_var == 42
+$global_mutable_var == 43
+$specific_immutable_var == 44
+EOF
+
+# check that all mutable variables can be modified
+swig_assert_each_line( <<EOF )
+$default_mutable_var = 80
+$default_mutable_var == 80
+$specific_mutable_var = 82
+$specific_mutable_var == 82
+$global_mutable_var = 83
+$global_mutable_var == 83
+EOF
+
+# now check that immutable variables cannot be modified
+had_exception = false
+begin
+  $global_immutable_var = 81
+rescue NameError => e
+  had_exception = true
+end
+swig_assert(had_exception, nil,
+            "$global_immutable_var is writable (expected to be immutable)")
+
+had_exception = false
+begin
+  $specific_immutable_var = 81
+rescue NameError => e
+  had_exception = true
+end
+swig_assert(had_exception, nil,
+            "$specific_immutable_var is writable (expected to be immutable)")
+
+swig_assert(check_values(80, 41, 82, 83, 44) == 1, nil, "Check values failed")
diff --git a/Examples/test-suite/ruby_global_immutable_vars.i b/Examples/test-suite/ruby_global_immutable_vars.i
new file mode 100644 (file)
index 0000000..6f067d2
--- /dev/null
@@ -0,0 +1,34 @@
+%module ruby_global_immutable_vars
+
+// This copy of global_immutable_vars.i shall be compiled with the
+// SWIG Ruby option "-globalmodule" in order to check the code path
+// for registering global methods (in contrast to module methods).
+
+%inline %{
+  int default_mutable_var = 40;
+%}
+
+%immutable;
+%feature("immutable", "0") specific_mutable_var;
+
+%inline %{
+  int global_immutable_var = 41;
+  int specific_mutable_var = 42;
+%}
+
+%mutable;
+%immutable specific_immutable_var;
+%inline %{
+  int global_mutable_var = 43;
+  int specific_immutable_var = 44;
+
+  int check_values(int default_mutable, int global_immutable, int specific_mutable, int global_mutable, int specific_immutable) {
+    return
+      default_mutable    == default_mutable_var &&
+      global_immutable   == global_immutable_var &&
+      specific_mutable   == specific_mutable_var &&
+      global_mutable     == global_mutable_var &&
+      specific_immutable == specific_immutable_var;
+  }
+%}
+
diff --git a/Examples/test-suite/ruby_global_immutable_vars_cpp.i b/Examples/test-suite/ruby_global_immutable_vars_cpp.i
new file mode 100644 (file)
index 0000000..511390e
--- /dev/null
@@ -0,0 +1,32 @@
+%module ruby_global_immutable_vars_cpp
+
+// C++ version of ruby_global_immutable_vars.i
+
+%inline %{
+  int default_mutable_var = 40;
+%}
+
+%immutable;
+%feature("immutable", "0") specific_mutable_var;
+
+%inline %{
+  int global_immutable_var = 41;
+  int specific_mutable_var = 42;
+%}
+
+%mutable;
+%immutable specific_immutable_var;
+%inline %{
+  int global_mutable_var = 43;
+  int specific_immutable_var = 44;
+
+  int check_values(int default_mutable, int global_immutable, int specific_mutable, int global_mutable, int specific_immutable) {
+    return
+      default_mutable    == default_mutable_var &&
+      global_immutable   == global_immutable_var &&
+      specific_mutable   == specific_mutable_var &&
+      global_mutable     == global_mutable_var &&
+      specific_immutable == specific_immutable_var;
+  }
+%}
+
index b3c1d0d..67e03bf 100644 (file)
@@ -40,9 +40,10 @@ private {
   } else {
     version(D_Version2) {
       static import std.conv;
+    } else {
+      static import std.c.string;
     }
     static import std.string;
-    static import std.c.string;
   }
 
   version(D_Version2) {
@@ -112,7 +113,7 @@ private {
     version(Tango) {
       import tango.sys.Common;
     } else version(linux) {
-      import std.c.linux.linux;
+      import core.sys.posix.dlfcn;
     } else {
       extern(C) {
         const RTLD_NOW = 2;
index bd764d6..b8ddf00 100644 (file)
@@ -1765,6 +1765,11 @@ SWIGRUNTIME int  SWIG_Lua_ConvertPtr(lua_State *L,int index,void **ptr,swig_type
     *ptr=0;
     return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
   }
+  if (lua_islightuserdata(L,index))
+  {
+    *ptr=lua_touserdata(L,index);
+    return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
+  }
   usr=(swig_lua_userdata*)lua_touserdata(L,index);  /* get data */
   if (usr)
   {
index 5e74c3d..4378f73 100644 (file)
@@ -77,7 +77,7 @@ type _value = c_obj
 
 %typemap(out) SWIGTYPE [] {
     int i;
-    CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr");
+    const CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr");
     $result = caml_array_new($1_dim0);
 
     for( i = 0; i < $1_dim0; i++ ) {
index ac496bd..afb01da 100644 (file)
@@ -62,7 +62,7 @@
 
 #if 0
 %typemap(argout) SWIGTYPE & {
-    CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr");
+    const CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr");
     if( fromval ) {
        swig_result =
            caml_list_append(swig_result,
@@ -75,7 +75,7 @@
     }
 }
 %typemap(argout) SWIGTYPE && {
-    CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr");
+    const CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr");
     if( fromval ) {
        swig_result =
            caml_list_append(swig_result,
index 3d552cc..5a923c5 100644 (file)
@@ -407,7 +407,7 @@ extern "C" {
            CAMLreturn((long)SWIG_Int64_val(SWIG_Field(SWIG_Field(v,0),0)));
        case C_enum: {
            SWIG_CAMLlocal1(ret);
-           CAML_VALUE *enum_to_int = caml_named_value(SWIG_MODULE "_enum_to_int");
+           const CAML_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));
@@ -451,7 +451,7 @@ extern "C" {
        CAMLparam1(v);
        void *outptr = NULL;
         swig_type_info *outdescr = NULL;
-        static CAML_VALUE *func_val = NULL;
+        static const CAML_VALUE *func_val = NULL;
 
        if( v == Val_unit ) {
            *out = 0;
@@ -574,7 +574,7 @@ extern "C" {
         CAMLparam0();
         SWIG_CAMLlocal1(result);
 
-        CAML_VALUE *fromval = caml_named_value(name);
+        const CAML_VALUE *fromval = caml_named_value(name);
         if (fromval) {
             result = caml_callback(*fromval, caml_val_ptr(ptr, descriptor));
         } else {
index bf71d18..5b9cd86 100644 (file)
@@ -7,8 +7,6 @@
 
 # define SWIG_DIRECTOR_CAST(ARG) dynamic_cast<Swig::Director *>(ARG)
 
-#include <exception>
-
 namespace Swig {
 
   class Director {
diff --git a/Lib/octave/extra-install.list b/Lib/octave/extra-install.list
new file mode 100644 (file)
index 0000000..41ef947
--- /dev/null
@@ -0,0 +1,2 @@
+# see top-level Makefile.in
+octheaders.hpp
index 310a849..80d593f 100644 (file)
  * be the case.
  * ----------------------------------------------------------------------------- */
 
-%{
-#include <climits>
-#include <iostream>
-%}
-
-
 #if !defined(SWIG_NO_EXPORT_ITERATOR_METHODS)
 # if !defined(SWIG_EXPORT_ITERATOR_METHODS)
 #  define SWIG_EXPORT_ITERATOR_METHODS SWIG_EXPORT_ITERATOR_METHODS
@@ -64,7 +58,6 @@ namespace swig {
 
 %fragment("OctSequence_Base","header",fragment="<stddef.h>")
 {
-%#include <functional>
 
 namespace std {
   template <>
diff --git a/Lib/octave/octheaders.hpp b/Lib/octave/octheaders.hpp
new file mode 100644 (file)
index 0000000..abf6428
--- /dev/null
@@ -0,0 +1,130 @@
+//
+// This header includes all C++ headers required for generated Octave wrapper code.
+// Using a single header file allows pre-compilation of Octave headers, as follows:
+// * Check out this header file:
+//     swig -octave -co octheaders.hpp
+// * Pre-compile header file into octheaders.hpp.gch:
+//     g++ -c ... octheaders.hpp
+// * Use pre-compiled header file:
+//     g++ -c -include octheaders.hpp ...
+//
+
+#if !defined(_SWIG_OCTAVE_OCTHEADERS_HPP)
+#define _SWIG_OCTAVE_OCTHEADERS_HPP
+
+// Required C++ headers
+#include <cstdlib>
+#include <climits>
+#include <iostream>
+#include <exception>
+#include <functional>
+#include <complex>
+#include <string>
+#include <vector>
+#include <map>
+
+// Minimal headers to define Octave version
+#include <octave/oct.h>
+#include <octave/version.h>
+
+// Macro for enabling features which require Octave version >= major.minor.patch
+// - Use (OCTAVE_PATCH_VERSION + 0) to handle both '<digit>' (released) and '<digit>+' (in development) patch numbers
+#define SWIG_OCTAVE_PREREQ(major, minor, patch) \
+  ( (OCTAVE_MAJOR_VERSION<<16) + (OCTAVE_MINOR_VERSION<<8) + (OCTAVE_PATCH_VERSION + 0) >= ((major)<<16) + ((minor)<<8) + (patch) )
+
+// Reconstruct Octave major, minor, and patch versions for releases prior to 3.8.1
+#if !defined(OCTAVE_MAJOR_VERSION)
+
+# if !defined(OCTAVE_API_VERSION_NUMBER)
+
+// Hack to distinguish between Octave 3.8.0, which removed OCTAVE_API_VERSION_NUMBER but did not yet
+// introduce OCTAVE_MAJOR_VERSION, and Octave <= 3.2, which did not define OCTAVE_API_VERSION_NUMBER
+#  include <octave/ov.h>
+#  if defined(octave_ov_h)
+#   define OCTAVE_MAJOR_VERSION 3
+#   define OCTAVE_MINOR_VERSION 8
+#   define OCTAVE_PATCH_VERSION 0
+#  else
+
+// Hack to distinguish between Octave 3.2 and earlier versions, before OCTAVE_API_VERSION_NUMBER existed
+#   define ComplexLU __ignore
+#   include <octave/CmplxLU.h>
+#   undef ComplexLU
+#   if defined(octave_Complex_LU_h)
+
+// We know only that this version is prior to Octave 3.2, i.e. OCTAVE_API_VERSION_NUMBER < 37
+#    define OCTAVE_MAJOR_VERSION 3
+#    define OCTAVE_MINOR_VERSION 1
+#    define OCTAVE_PATCH_VERSION 99
+
+#   else
+
+// OCTAVE_API_VERSION_NUMBER == 37
+#    define OCTAVE_MAJOR_VERSION 3
+#    define OCTAVE_MINOR_VERSION 2
+#    define OCTAVE_PATCH_VERSION 0
+
+#   endif // defined(octave_Complex_LU_h)
+
+#  endif // defined(octave_ov_h)
+
+// Correlation between Octave API and version numbers extracted from Octave's
+// ChangeLogs; version is the *earliest* released Octave with that API number
+# elif OCTAVE_API_VERSION_NUMBER >= 48
+#  define OCTAVE_MAJOR_VERSION 3
+#  define OCTAVE_MINOR_VERSION 6
+#  define OCTAVE_PATCH_VERSION 0
+
+# elif OCTAVE_API_VERSION_NUMBER >= 45
+#  define OCTAVE_MAJOR_VERSION 3
+#  define OCTAVE_MINOR_VERSION 4
+#  define OCTAVE_PATCH_VERSION 1
+
+# elif OCTAVE_API_VERSION_NUMBER >= 42
+#  define OCTAVE_MAJOR_VERSION 3
+#  define OCTAVE_MINOR_VERSION 3
+#  define OCTAVE_PATCH_VERSION 54
+
+# elif OCTAVE_API_VERSION_NUMBER >= 41
+#  define OCTAVE_MAJOR_VERSION 3
+#  define OCTAVE_MINOR_VERSION 3
+#  define OCTAVE_PATCH_VERSION 53
+
+# elif OCTAVE_API_VERSION_NUMBER >= 40
+#  define OCTAVE_MAJOR_VERSION 3
+#  define OCTAVE_MINOR_VERSION 3
+#  define OCTAVE_PATCH_VERSION 52
+
+# elif OCTAVE_API_VERSION_NUMBER >= 39
+#  define OCTAVE_MAJOR_VERSION 3
+#  define OCTAVE_MINOR_VERSION 3
+#  define OCTAVE_PATCH_VERSION 51
+
+# else // OCTAVE_API_VERSION_NUMBER == 38
+#  define OCTAVE_MAJOR_VERSION 3
+#  define OCTAVE_MINOR_VERSION 3
+#  define OCTAVE_PATCH_VERSION 50
+
+# endif // !defined(OCTAVE_API_VERSION_NUMBER)
+
+#endif // !defined(OCTAVE_MAJOR_VERSION)
+
+// Required Octave headers
+#include <octave/Cell.h>
+#include <octave/dynamic-ld.h>
+#include <octave/oct-env.h>
+#include <octave/oct-map.h>
+#include <octave/ov-scalar.h>
+#include <octave/ov-fcn-handle.h>
+#include <octave/parse.h>
+#if SWIG_OCTAVE_PREREQ(4,2,0)
+#include <octave/interpreter.h>
+#else
+#include <octave/toplev.h>
+#endif
+#include <octave/unwind-prot.h>
+#if SWIG_OCTAVE_PREREQ(4,2,0)
+#include <octave/call-stack.h>
+#endif
+
+#endif // !defined(_SWIG_OCTAVE_OCTHEADERS_HPP)
index ff614e6..1069e0e 100644 (file)
@@ -89,10 +89,6 @@ SWIGRUNTIME void SWIG_Octave_SetModule(void *clientdata, swig_module_info *point
 
 // Runtime API implementation
 
-#include <map>
-#include <vector>
-#include <string>
-
 typedef octave_value_list(*octave_func) (const octave_value_list &, int);
 class octave_swig_type;
 
@@ -203,11 +199,7 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
 
     std::set<std::string> dispatch_classes;
 
-  private:
-
-    DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
   };
-  DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(octave_swig_bound_func, "octave_swig_bound_func", "octave_swig_bound_func");
 #else
 #define SWIG_OCTAVE_BOUND_FUNC(func, args) octave_value(func)
 #endif
@@ -507,10 +499,10 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
        delete this;
     }
 
-    long swig_this() const {
+    size_t swig_this() const {
       if (!types.size())
-       return (long) this;
-      return (long) types[0].second.ptr;
+       return (size_t) this;
+      return (size_t) types[0].second.ptr;
     }
     const char* help_text() const {
       if (!types.size())
@@ -1066,7 +1058,13 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
     octave_swig_type *ptr;
   public:
     octave_swig_ref(octave_swig_type *_ptr = 0)
-      :ptr(_ptr) { }
+      :ptr(_ptr)
+      {
+        // Ensure type_id() is set correctly
+        if (t_id == -1) {
+          t_id = octave_swig_ref::static_type_id();
+        }
+      }
 
     ~octave_swig_ref()
       { if (ptr) ptr->decref(); }
@@ -1207,8 +1205,13 @@ SWIGRUNTIME void swig_acquire_ownership_obj(void *vptr, int own);
   public:
 
     octave_swig_packed(swig_type_info *_type = 0, const void *_buf = 0, size_t _buf_len = 0)
-      :        type(_type), buf((const char*)_buf, (const char*)_buf + _buf_len) {
-    }
+      :        type(_type), buf((const char*)_buf, (const char*)_buf + _buf_len)
+      {
+        // Ensure type_id() is set correctly
+        if (t_id == -1) {
+          t_id = octave_swig_packed::static_type_id();
+        }
+      }
 
     bool copy(swig_type_info *outtype, void *ptr, size_t sz) const {
       if (outtype && outtype != type)
index f98bf4f..a397fb7 100644 (file)
+#ifdef SWIG_OCTAVE_EXTERNAL_OCTHEADERS
 %insert(runtime) %{
-
-#include <cstdlib>
-#include <iostream>
-
-#include <octave/oct.h>
-#include <octave/version.h>
-
-// Macro for enabling features which require Octave version >= major.minor.patch
-// - Use (OCTAVE_PATCH_VERSION + 0) to handle both '<digit>' (released) and '<digit>+' (in development) patch numbers
-#define SWIG_OCTAVE_PREREQ(major, minor, patch) \
-  ( (OCTAVE_MAJOR_VERSION<<16) + (OCTAVE_MINOR_VERSION<<8) + (OCTAVE_PATCH_VERSION + 0) >= ((major)<<16) + ((minor)<<8) + (patch) )
-
-// Reconstruct Octave major, minor, and patch versions for releases prior to 3.8.1
-#if !defined(OCTAVE_MAJOR_VERSION)
-
-# if !defined(OCTAVE_API_VERSION_NUMBER)
-
-// Hack to distinguish between Octave 3.8.0, which removed OCTAVE_API_VERSION_NUMBER but did not yet
-// introduce OCTAVE_MAJOR_VERSION, and Octave <= 3.2, which did not define OCTAVE_API_VERSION_NUMBER
-#  include <octave/ov.h>
-#  if defined(octave_ov_h)
-#   define OCTAVE_MAJOR_VERSION 3
-#   define OCTAVE_MINOR_VERSION 8
-#   define OCTAVE_PATCH_VERSION 0
-#  else
-
-// Hack to distinguish between Octave 3.2 and earlier versions, before OCTAVE_API_VERSION_NUMBER existed
-#   define ComplexLU __ignore
-#   include <octave/CmplxLU.h>
-#   undef ComplexLU
-#   if defined(octave_Complex_LU_h)
-
-// We know only that this version is prior to Octave 3.2, i.e. OCTAVE_API_VERSION_NUMBER < 37
-#    define OCTAVE_MAJOR_VERSION 3
-#    define OCTAVE_MINOR_VERSION 1
-#    define OCTAVE_PATCH_VERSION 99
-
-#   else
-
-// OCTAVE_API_VERSION_NUMBER == 37
-#    define OCTAVE_MAJOR_VERSION 3
-#    define OCTAVE_MINOR_VERSION 2
-#    define OCTAVE_PATCH_VERSION 0
-
-#   endif // defined(octave_Complex_LU_h)
-
-#  endif // defined(octave_ov_h)
-
-// Correlation between Octave API and version numbers extracted from Octave's
-// ChangeLogs; version is the *earliest* released Octave with that API number
-# elif OCTAVE_API_VERSION_NUMBER >= 48
-#  define OCTAVE_MAJOR_VERSION 3
-#  define OCTAVE_MINOR_VERSION 6
-#  define OCTAVE_PATCH_VERSION 0
-
-# elif OCTAVE_API_VERSION_NUMBER >= 45
-#  define OCTAVE_MAJOR_VERSION 3
-#  define OCTAVE_MINOR_VERSION 4
-#  define OCTAVE_PATCH_VERSION 1
-
-# elif OCTAVE_API_VERSION_NUMBER >= 42
-#  define OCTAVE_MAJOR_VERSION 3
-#  define OCTAVE_MINOR_VERSION 3
-#  define OCTAVE_PATCH_VERSION 54
-
-# elif OCTAVE_API_VERSION_NUMBER >= 41
-#  define OCTAVE_MAJOR_VERSION 3
-#  define OCTAVE_MINOR_VERSION 3
-#  define OCTAVE_PATCH_VERSION 53
-
-# elif OCTAVE_API_VERSION_NUMBER >= 40
-#  define OCTAVE_MAJOR_VERSION 3
-#  define OCTAVE_MINOR_VERSION 3
-#  define OCTAVE_PATCH_VERSION 52
-
-# elif OCTAVE_API_VERSION_NUMBER >= 39
-#  define OCTAVE_MAJOR_VERSION 3
-#  define OCTAVE_MINOR_VERSION 3
-#  define OCTAVE_PATCH_VERSION 51
-
-# else // OCTAVE_API_VERSION_NUMBER == 38
-#  define OCTAVE_MAJOR_VERSION 3
-#  define OCTAVE_MINOR_VERSION 3
-#  define OCTAVE_PATCH_VERSION 50
-
-# endif // !defined(OCTAVE_API_VERSION_NUMBER)
-
-#endif // !defined(OCTAVE_MAJOR_VERSION)
-
-#include <octave/Cell.h>
-#include <octave/dynamic-ld.h>
-#include <octave/oct-env.h>
-#include <octave/oct-map.h>
-#include <octave/ov-scalar.h>
-#include <octave/ov-fcn-handle.h>
-#include <octave/parse.h>
-#if SWIG_OCTAVE_PREREQ(4,2,0)
-#include <octave/interpreter.h>
+#include "octheaders.hpp"
+%}
 #else
-#include <octave/toplev.h>
+%insert(runtime) "octheaders.hpp";
 #endif
-#include <octave/unwind-prot.h>
-#if SWIG_OCTAVE_PREREQ(4,2,0)
-#include <octave/call-stack.h>
-#endif
-
-%}
 
 %insert(runtime) "swigrun.swg";
 %insert(runtime) "swigerrors.swg";
@@ -315,13 +214,29 @@ DEFUN_DLD( swig_octave_prereq, args, nargout, swig_octave_prereq_usage ) {
   return octave_value(prereq);
 }
 
+static const char *const swig_exit_usage = "-*- texinfo -*- \n\
+@deftypefn {Loadable Function} {} swig_exit([@var{exit_status}])\n\
+Exit Octave without performing any memory cleanup.\n\
+@end deftypefn";
+
+DEFUN_DLD( swig_exit, args, nargout, swig_exit_usage ) {
+  if (args.length() > 1) {
+    error("swig_exit: must be called with at most one arguments");
+    return octave_value_list();
+  }
+  int exit_status = 0;
+  if (args.length() == 1) {
+    exit_status = args(0).int_value();
+  }
+  ::_Exit(exit_status);
+  return octave_value();
+}
+
 static const char *const SWIG_name_usage = "-*- texinfo -*- \n\
 @deftypefn {Loadable Module} {} " SWIG_name_d "\n\
 Loads the SWIG-generated module `" SWIG_name_d "'.\n\
 @end deftypefn";
 
-void __swig_atexit__(void) { ::_Exit(0); }
-
 DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) {
 
   static octave_swig_type* module_ns = 0;
@@ -329,15 +244,16 @@ DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) {
   // workaround to prevent octave seg-faulting on exit: set Octave exit function
   // octave_exit to _Exit, which exits immediately without trying to cleanup memory.
   // definitely affected version 3.2.*, not sure about 3.3.*, seems to be fixed in
-  // version 3.4.*, but reappeared in 4.2.*, so turn on for all versions after 3.2.*.
+  // version 3.4.*, reappeared in 4.2.*, hack not possible in 4.4.* or later due to
+  // removal of octave_exit, so turn on for all versions between 3.2.*. and 4.4.*.
   // can be turned off with macro definition.
 #ifndef SWIG_OCTAVE_NO_SEGFAULT_HACK
-#if SWIG_OCTAVE_PREREQ(4,4,0)
-  atexit(__swig_atexit__);
-#elif SWIG_OCTAVE_PREREQ(3,2,0)
+#if !SWIG_OCTAVE_PREREQ(4,4,0)
+#if SWIG_OCTAVE_PREREQ(3,2,0)
   octave_exit = ::_Exit;
 #endif
 #endif
+#endif
 
   // check for no input and output args
   if (args.length() != 0 || nargout != 0) {
@@ -376,7 +292,6 @@ DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) {
       string_vector types = typeinfo.installed_type_names();
       bool register_octave_swig_ref = true;
       bool register_octave_swig_packed = true;
-      bool register_octave_swig_bound_func = true;
       for (int i = 0; i < types.numel(); ++i) {
         if (types(i) == octave_swig_ref::static_type_name()) {
           register_octave_swig_ref = false;
@@ -384,9 +299,6 @@ DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) {
         if (types(i) == octave_swig_packed::static_type_name()) {
           register_octave_swig_packed = false;
         }
-        if (types(i) == octave_swig_bound_func::static_type_name()) {
-          register_octave_swig_bound_func = false;
-        }
       }
       if (register_octave_swig_ref) {
         octave_swig_ref::register_type();
@@ -394,9 +306,6 @@ DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) {
       if (register_octave_swig_packed) {
         octave_swig_packed::register_type();
       }
-      if (register_octave_swig_bound_func) {
-        octave_swig_bound_func::register_type();
-      }
     }
 #else
     octave_swig_ref::register_type();
@@ -427,6 +336,9 @@ DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) {
     if (!SWIG_Octave_InstallFunction(me, "swig_octave_prereq")) {
       return octave_value_list();
     }
+    if (!SWIG_Octave_InstallFunction(me, "swig_exit")) {
+      return octave_value_list();
+    }
 
     octave_swig_type* cvar_ns=0;
     if (std::string(SWIG_global_name) != ".") {
index 30c1882..461e2fd 100644 (file)
@@ -4,10 +4,6 @@
 
 %include <octcomplex.swg>
 
-%{
-#include <complex> 
-%}
-
 namespace std {
   %naturalvar complex;
   template<typename T> class complex;
index 28051e6..5308748 100644 (file)
@@ -256,6 +256,12 @@ SwigPyStaticVar_Type(void) {
 #if PY_VERSION_HEX >= 0x03040000
       0,                                        /* tp_finalize */
 #endif
+#if PY_VERSION_HEX >= 0x03080000
+      0,                                        /* tp_vectorcall */
+#endif
+#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)
+      0,                                        /* tp_print */
+#endif
 #ifdef COUNT_ALLOCS
       0,                                        /* tp_allocs */
       0,                                        /* tp_frees */
@@ -334,6 +340,12 @@ SwigPyObjectType(void) {
 #if PY_VERSION_HEX >= 0x03040000
       0,                                        /* tp_finalize */
 #endif
+#if PY_VERSION_HEX >= 0x03080000
+      0,                                        /* tp_vectorcall */
+#endif
+#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)
+      0,                                        /* tp_print */
+#endif
 #ifdef COUNT_ALLOCS
       0,                                        /* tp_allocs */
       0,                                        /* tp_frees */
index fef4e9b..2ddf4c3 100644 (file)
@@ -52,7 +52,7 @@ namespace swig {
   struct container_owner {
     // By default, do not add the back-reference (for value types)
     // Specialization below will check the reference for pointer types.
-    static bool back_reference(PyObject* child, PyObject* owner) {
+    static bool back_reference(PyObject* /*child*/, PyObject* /*owner*/) {
       return false;
     }
   };
@@ -69,8 +69,7 @@ namespace swig {
     static bool back_reference(PyObject* child, PyObject* owner) {
       SwigPyObject* swigThis = SWIG_Python_GetSwigThis(child);
       if (swigThis && (swigThis->own & SWIG_POINTER_OWN) != SWIG_POINTER_OWN) {
-        PyObject_SetAttr(child, container_owner_attribute(), owner);
-        return true;
+        return PyObject_SetAttr(child, container_owner_attribute(), owner) != -1;
       }
       return false;
     }
index c820f90..b3bd39d 100644 (file)
 SWIGINTERN char*
 SWIG_Python_str_AsChar(PyObject *str)
 {
-#if PY_VERSION_HEX >= 0x03000000
+#if PY_VERSION_HEX >= 0x03030000
+  return (char *)PyUnicode_AsUTF8(str);
+#elif PY_VERSION_HEX >= 0x03000000
   char *newstr = 0;
   str = PyUnicode_AsUTF8String(str);
   if (str) {
     char *cstr;
     Py_ssize_t len;
-    PyBytes_AsStringAndSize(str, &cstr, &len);
-    newstr = (char *) malloc(len+1);
-    memcpy(newstr, cstr, len+1);
+    if (PyBytes_AsStringAndSize(str, &cstr, &len) != -1) {
+      newstr = (char *) malloc(len+1);
+      if (newstr)
+        memcpy(newstr, cstr, len+1);
+    }
     Py_XDECREF(str);
   }
   return newstr;
@@ -54,10 +58,10 @@ SWIG_Python_str_AsChar(PyObject *str)
 #endif
 }
 
-#if PY_VERSION_HEX >= 0x03000000
-#  define SWIG_Python_str_DelForPy3(x) free( (void*) (x) )
+#if PY_VERSION_HEX >= 0x03030000 || PY_VERSION_HEX < 0x03000000
+#  define SWIG_Python_str_DelForPy3(x)
 #else
-#  define SWIG_Python_str_DelForPy3(x) 
+#  define SWIG_Python_str_DelForPy3(x) free( (void*) (x) )
 #endif
 
 
index dfbf40b..a6d609d 100644 (file)
@@ -186,6 +186,12 @@ swig_varlink_type(void) {
 #if PY_VERSION_HEX >= 0x03040000
       0,                                  /* tp_finalize */
 #endif
+#if PY_VERSION_HEX >= 0x03080000
+      0,                                  /* tp_vectorcall */
+#endif
+#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)
+      0,                                  /* tp_print */
+#endif
 #ifdef COUNT_ALLOCS
       0,                                  /* tp_allocs */
       0,                                  /* tp_frees */
index 445a1e3..63ff82f 100644 (file)
@@ -183,6 +183,19 @@ SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssi
   }
 }
 
+SWIGINTERN int
+SWIG_Python_CheckNoKeywords(PyObject *kwargs, const char *name) {
+  int no_kwargs = 1;
+  if (kwargs) {
+    assert(PyDict_Check(kwargs));
+    if (PyDict_Size(kwargs) > 0) {
+      PyErr_Format(PyExc_TypeError, "%s() does not take keyword arguments", name);
+      no_kwargs = 0;
+    }
+  }
+  return no_kwargs;
+}
+
 /* A functor is a function object with one single object argument */
 #define SWIG_Python_CallFunctor(functor, obj)          PyObject_CallFunctionObjArgs(functor, obj, NULL);
 
@@ -696,6 +709,12 @@ SwigPyObject_TypeOnce(void) {
 #if PY_VERSION_HEX >= 0x03040000
       0,                                    /* tp_finalize */
 #endif
+#if PY_VERSION_HEX >= 0x03080000
+      0,                                    /* tp_vectorcall */
+#endif
+#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)
+      0,                                    /* tp_print */
+#endif
 #ifdef COUNT_ALLOCS
       0,                                    /* tp_allocs */
       0,                                    /* tp_frees */
@@ -857,6 +876,12 @@ SwigPyPacked_TypeOnce(void) {
 #if PY_VERSION_HEX >= 0x03040000
       0,                                    /* tp_finalize */
 #endif
+#if PY_VERSION_HEX >= 0x03080000
+      0,                                    /* tp_vectorcall */
+#endif
+#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)
+      0,                                    /* tp_print */
+#endif
 #ifdef COUNT_ALLOCS
       0,                                    /* tp_allocs */
       0,                                    /* tp_frees */
@@ -1183,8 +1208,10 @@ SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
        }
       }
 #else
-      PyObject *key = SWIG_This();
-      PyObject_SetAttr(inst, key, swig_this);
+      if (PyObject_SetAttr(inst, SWIG_This(), swig_this) == -1) {
+        Py_DECREF(inst);
+        inst = 0;
+      }
 #endif
     }
   } else {
@@ -1196,8 +1223,12 @@ SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
         inst = ((PyTypeObject *)data->newargs)->tp_new((PyTypeObject *)data->newargs, empty_args, empty_kwargs);
         Py_DECREF(empty_kwargs);
         if (inst) {
-          PyObject_SetAttr(inst, SWIG_This(), swig_this);
-          Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
+          if (PyObject_SetAttr(inst, SWIG_This(), swig_this) == -1) {
+            Py_DECREF(inst);
+            inst = 0;
+          } else {
+            Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
+          }
         }
       }
       Py_DECREF(empty_args);
@@ -1214,25 +1245,21 @@ SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
   return inst;
 }
 
-SWIGRUNTIME void
+SWIGRUNTIME int
 SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this)
 {
- PyObject *dict;
 #if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
- PyObject **dictptr = _PyObject_GetDictPtr(inst);
- if (dictptr != NULL) {
-   dict = *dictptr;
-   if (dict == NULL) {
-     dict = PyDict_New();
-     *dictptr = dict;
-   }
-   PyDict_SetItem(dict, SWIG_This(), swig_this);
-   return;
- }
+  PyObject **dictptr = _PyObject_GetDictPtr(inst);
+  if (dictptr != NULL) {
+    PyObject *dict = *dictptr;
+    if (dict == NULL) {
+      dict = PyDict_New();
+      *dictptr = dict;
+    }
+    return PyDict_SetItem(dict, SWIG_This(), swig_this);
+  }
 #endif
- dict = PyObject_GetAttrString(inst, "__dict__");
- PyDict_SetItem(dict, SWIG_This(), swig_this);
- Py_DECREF(dict);
+  return PyObject_SetAttr(inst, SWIG_This(), swig_this);
 } 
 
 
@@ -1246,7 +1273,8 @@ SWIG_Python_InitShadowInstance(PyObject *args) {
     if (sthis) {
       SwigPyObject_append((PyObject*) sthis, obj[1]);
     } else {
-      SWIG_Python_SetSwigThis(obj[0], obj[1]);
+      if (SWIG_Python_SetSwigThis(obj[0], obj[1]) != 0)
+        return NULL;
     }
     return SWIG_Py_Void();
   }
index 0242e4d..afa7135 100644 (file)
@@ -45,11 +45,20 @@ namespace swig {
   template <class Type>
   struct traits_asptr {   
     static int asptr(PyObject *obj, Type **val) {
-      Type *p = 0;
+      int res = SWIG_ERROR;
       swig_type_info *descriptor = type_info<Type>();
-      int res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR;
-      if (SWIG_IsOK(res)) {
-       if (val) *val = p;
+      if (val) {
+        Type *p = 0;
+        int newmem = 0;
+        res = descriptor ? SWIG_ConvertPtrAndOwn(obj, (void **)&p, descriptor, 0, &newmem) : SWIG_ERROR;
+        if (SWIG_IsOK(res)) {
+          if (newmem & SWIG_CAST_NEW_MEMORY) {
+            res |= SWIG_NEWOBJMASK;
+          }
+          *val = p;
+        }
+      } else {
+        res = descriptor ? SWIG_ConvertPtr(obj, 0, descriptor, 0) : SWIG_ERROR;
       }
       return res;
     }
index 93f48ac..64ed685 100644 (file)
@@ -32,9 +32,11 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
     if (alloc)
       *alloc = SWIG_NEWOBJ;
 %#endif
-    PyBytes_AsStringAndSize(obj, &cstr, &len);
+    if (PyBytes_AsStringAndSize(obj, &cstr, &len) == -1)
+      return SWIG_TypeError;
 %#else
-    PyString_AsStringAndSize(obj, &cstr, &len);
+    if (PyString_AsStringAndSize(obj, &cstr, &len) == -1)
+      return SWIG_TypeError;
 %#endif
     if (cptr) {
       if (alloc) {
index 8ae483c..e0b7d69 100644 (file)
 %#endif
          res = traits_asptr_stdseq<map_type, std::pair<K, T> >::asptr(items, val);
        } else {
-         map_type *p;
+         map_type *p = 0;
          swig_type_info *descriptor = swig::type_info<map_type>();
          res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR;
          if (SWIG_IsOK(res) && val)  *val = p;
index f78a527..bbffb6b 100644 (file)
@@ -29,7 +29,7 @@
 %#endif
          res = traits_asptr_stdseq<std::multimap<K,T>, std::pair<K, T> >::asptr(items, val);
        } else {
-         multimap_type *p;
+         multimap_type *p = 0;
          swig_type_info *descriptor = swig::type_info<multimap_type>();
          res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR;
          if (SWIG_IsOK(res) && val)  *val = p;
index 172572b..cf463cb 100644 (file)
@@ -47,7 +47,7 @@
            res = get_pair(first, second, val);
          }
        } else {
-         value_type *p;
+         value_type *p = 0;
          swig_type_info *descriptor = swig::type_info<value_type>();
          res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR;
          if (SWIG_IsOK(res) && val)  *val = *p;
            res = get_pair(first, second, val);
          }
        } else {
-         value_type *p;
+         value_type *p = 0;
          swig_type_info *descriptor = swig::type_info<value_type>();
          res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR;
          if (SWIG_IsOK(res) && val)  *val = p;
index 042d5b6..784be4c 100644 (file)
@@ -87,7 +87,7 @@
 %#endif
          res = traits_asptr_stdseq<std::unordered_map<K,T,Hash,Compare,Alloc>, std::pair<K, T> >::asptr(items, val);
        } else {
-         unordered_map_type *p;
+         unordered_map_type *p = 0;
          swig_type_info *descriptor = swig::type_info<unordered_map_type>();
          res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR;
          if (SWIG_IsOK(res) && val)  *val = p;
index 2811404..bc095ea 100644 (file)
@@ -36,7 +36,7 @@
 %#endif
          res = traits_asptr_stdseq<std::unordered_multimap<K,T,Hash,Compare,Alloc>, std::pair<K, T> >::asptr(items, val);
        } else {
-         unordered_multimap_type *p;
+         unordered_multimap_type *p = 0;
          swig_type_info *descriptor = swig::type_info<unordered_multimap_type>();
          res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR;
          if (SWIG_IsOK(res) && val)  *val = p;
index b89212b..c3b40a9 100644 (file)
@@ -1,7 +1,3 @@
-#define SWIG_Error(code, msg) Rf_warning(msg); return Rf_ScalarLogical(NA_LOGICAL)
-
-#define SWIG_fail return Rf_ScalarLogical(NA_LOGICAL)
-
 /* for raw pointers */
 #define SWIG_ConvertPtr(oc, ptr, ty, flags)             SWIG_R_ConvertPtr(oc, ptr, ty, flags)
 #define SWIG_ConvertFunctionPtr(oc, ptr, ty)            SWIG_R_ConvertPtr(oc, ptr, ty, 0)
index c341321..7984461 100644 (file)
@@ -1,4 +1,3 @@
-
 /* Remove global namespace pollution */
 #if !defined(SWIG_NO_R_NO_REMAP)
 # define R_NO_REMAP
@@ -23,6 +22,7 @@ extern "C" {
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
+#include <stdarg.h>
 
 #if R_VERSION >= R_Version(2,6,0)
 #define VMAXTYPE void *
@@ -30,6 +30,47 @@ extern "C" {
 #define VMAXTYPE char *
 #endif
 
+/* Last error */
+static int SWIG_lasterror_code = 0;
+static char SWIG_lasterror_msg[1024];
+SWIGRUNTIME void SWIG_Error(int code, const char *format, ...) {
+  va_list arg;
+  SWIG_lasterror_code = code;
+  va_start(arg, format);
+  vsnprintf(SWIG_lasterror_msg, sizeof(SWIG_lasterror_msg), format, arg);
+  va_end(arg);
+}
+
+SWIGRUNTIME const char *SWIG_ErrorType(int code) {
+  switch (code) {
+  case SWIG_MemoryError:
+    return "SWIG:MemoryError";
+  case SWIG_IOError:
+    return "SWIG:IOError";
+  case SWIG_RuntimeError:
+    return "SWIG:RuntimeError";
+  case SWIG_IndexError:
+    return "SWIG:IndexError";
+  case SWIG_TypeError:
+    return "SWIG:TypeError";
+  case SWIG_DivisionByZero:
+    return "SWIG:DivisionByZero";
+  case SWIG_OverflowError:
+    return "SWIG:OverflowError";
+  case SWIG_SyntaxError:
+    return "SWIG:SyntaxError";
+  case SWIG_ValueError:
+    return "SWIG:ValueError";
+  case SWIG_SystemError:
+    return "SWIG:SystemError";
+  case SWIG_AttributeError:
+    return "SWIG:AttributeError";
+  }
+  return "SWIG:UnknownError";
+}
+
+#define SWIG_fail goto fail
+
 /*
   This is mainly a way to avoid having lots of local variables that may 
   conflict with those in the routine.
index bdc48c2..8fe1223 100644 (file)
   %{  $input = enumToInteger($input, "$R_class"); %}
 
 %typemap(scoercein) SWIGTYPE, SWIGTYPE *, SWIGTYPE *const, SWIGTYPE &, SWIGTYPE &&
- %{ if (inherits($input, "ExternalReference")) $input = slot($input,"ref") %}
+ %{ if (inherits($input, "ExternalReference")) $input = slot($input,"ref"); %}
 
 /*
 %typemap(scoercein) SWIGTYPE *, SWIGTYPE *const
-  %{ $input = coerceIfNotSubclass($input, "$R_class") %}
+  %{ $input = coerceIfNotSubclass($input, "$R_class"); %}
 
 %typemap(scoercein) SWIGTYPE & 
-  %{ $input = coerceIfNotSubclass($input, "$R_class") %}
+  %{ $input = coerceIfNotSubclass($input, "$R_class"); %}
 
 %typemap(scoercein) SWIGTYPE && 
-  %{ $input = coerceIfNotSubclass($input, "$R_class") %}
+  %{ $input = coerceIfNotSubclass($input, "$R_class"); %}
 
 %typemap(scoercein) SWIGTYPE  
-  %{ $input = coerceIfNotSubclass($input, "$&R_class") %}
+  %{ $input = coerceIfNotSubclass($input, "$&R_class"); %}
 */
 
 %typemap(scoercein) SWIGTYPE[ANY]  
index f7b51bd..b345fce 100644 (file)
@@ -174,7 +174,7 @@ namespace swig {
       return rb_inspect(_obj);
     }
 
-    static VALUE swig_rescue_swallow(VALUE)
+    static VALUE swig_rescue_swallow(VALUE, VALUE)
     {
       /*
       VALUE errstr = rb_obj_as_string(rb_errinfo());
@@ -203,8 +203,8 @@ namespace swig {
         args.id     = op_id;
         args.nargs  = 1;
         args.target = VALUE(other);
-        ret = rb_rescue(RUBY_METHOD_FUNC(swig_rescue_funcall), VALUE(&args),
-                       (RUBY_METHOD_FUNC(swig_rescue_swallow)), Qnil);
+        ret = rb_rescue(VALUEFUNC(swig_rescue_funcall), VALUE(&args),
+                       (VALUEFUNC(swig_rescue_swallow)), Qnil);
       }
       if (ret == Qnil) {
         VALUE a = rb_funcall(         _obj, hash_id, 0 );
@@ -243,8 +243,8 @@ namespace swig {
       args.id     = op_id;
       args.nargs  = 0;
       args.target = Qnil;
-      ret = rb_rescue(RUBY_METHOD_FUNC(swig_rescue_funcall), VALUE(&args),
-                     (RUBY_METHOD_FUNC(swig_rescue_swallow)), Qnil);
+      ret = rb_rescue(VALUEFUNC(swig_rescue_funcall), VALUE(&args),
+                     (VALUEFUNC(swig_rescue_swallow)), Qnil);
       SWIG_RUBY_THREAD_END_BLOCK;
       return ret;
     }
@@ -262,8 +262,8 @@ namespace swig {
       args.id     = op_id;
       args.nargs  = 1;
       args.target = VALUE(other);
-      ret = rb_rescue(RUBY_METHOD_FUNC(swig_rescue_funcall), VALUE(&args),
-                     (RUBY_METHOD_FUNC(swig_rescue_swallow)), Qnil);
+      ret = rb_rescue(VALUEFUNC(swig_rescue_funcall), VALUE(&args),
+                     (VALUEFUNC(swig_rescue_swallow)), Qnil);
       SWIG_RUBY_THREAD_END_BLOCK;
       return GC_VALUE(ret);
     }
index 9fa205b..e723308 100644 (file)
@@ -628,7 +628,7 @@ namespace swig
       try {
        r = swig::from< const Sequence* >( swig::getslice(self, i, j) );
       }
-      catch( std::out_of_range ) {
+      catch( const std::out_of_range& ) {
       }
       return r;
     }
@@ -687,9 +687,8 @@ namespace swig
        r = swig::from< Sequence::value_type >( *(at) );
        $self->erase(at); 
       }
-      catch (std::out_of_range)
-       {
-       }
+      catch (const std::out_of_range&) {
+      }
       return r;
     }
   }
@@ -757,7 +756,7 @@ namespace swig
       try {
        r = swig::from< Sequence::value_type >( *(swig::cgetpos(self, i)) );
       }
-      catch( std::out_of_range ) {
+      catch( const std::out_of_range& ) {
       }
       return r;
     }
@@ -780,7 +779,7 @@ namespace swig
       try {
        r = swig::from< const Sequence* >( swig::getslice(self, i, j) );
       }
-      catch( std::out_of_range ) {
+      catch( const std::out_of_range& ) {
       }
       return r;
     }
@@ -790,7 +789,7 @@ namespace swig
       try {
        r = swig::from< Sequence::value_type >( *(swig::cgetpos(self, i)) );
       }
-      catch( std::out_of_range ) {
+      catch( const std::out_of_range& ) {
       }
       return r;
     }
@@ -1017,7 +1016,7 @@ namespace swig {
          } else {
            return rubyseq.check() ? SWIG_OK : SWIG_ERROR;
          }
-       } catch (std::exception& e) {
+       } catch (const std::exception& e) {
          if (seq) {
            VALUE lastErr = rb_gv_get("$!");
            if (lastErr == Qnil) {
@@ -1057,7 +1056,7 @@ namespace swig {
          } else {
            return true;
          }
-       } catch (std::exception& e) {
+       } catch (const std::exception& e) {
          if (seq) {
            VALUE lastErr = rb_gv_get("$!");
            if (lastErr == Qnil) {
index 90f07cf..bf4e362 100644 (file)
 
 
 /*
- * Need to be very careful about how these macros are defined, especially
- * when compiling C++ code or C code with an ANSI C compiler.
+ * The following macros are used for providing the correct type of a
+ * function pointer to the Ruby C API.
+ * Starting with Ruby 2.7 (corresponding to RB_METHOD_DEFINITION_DECL being
+ * defined) these macros act transparently due to Ruby's moving away from
+ * ANYARGS and instead employing strict function signatures.
  *
- * VALUEFUNC(f) is a macro used to typecast a C function that implements
- * a Ruby method so that it can be passed as an argument to API functions
- * like rb_define_method() and rb_define_singleton_method().
+ * Note: In case of C (not C++) the macros are transparent even before
+ * Ruby 2.7 due to the fact that the Ruby C API used function declarators
+ * with empty parentheses, which allows for an unspecified number of
+ * arguments.
  *
- * VOIDFUNC(f) is a macro used to typecast a C function that implements
- * either the "mark" or "free" stuff for a Ruby Data object, so that it
- * can be passed as an argument to API functions like Data_Wrap_Struct()
+ * PROTECTFUNC(f) is used for the function pointer argument of the Ruby
+ * C API function rb_protect().
+ *
+ * VALUEFUNC(f) is used for the function pointer argument(s) of Ruby C API
+ * functions like rb_define_method() and rb_define_singleton_method().
+ *
+ * VOIDFUNC(f) is used to typecast a C function that implements either
+ * the "mark" or "free" stuff for a Ruby Data object, so that it can be
+ * passed as an argument to Ruby C API functions like Data_Wrap_Struct()
  * and Data_Make_Struct().
+ *
+ * SWIG_RUBY_VOID_ANYARGS_FUNC(f) is used for the function pointer
+ * argument(s) of Ruby C API functions like rb_define_virtual_variable().
+ *
+ * SWIG_RUBY_INT_ANYARGS_FUNC(f) is used for the function pointer
+ * argument(s) of Ruby C API functions like st_foreach().
  */
-#ifdef __cplusplus
-#  ifndef RUBY_METHOD_FUNC /* These definitions should work for Ruby 1.4.6 */
-#    define PROTECTFUNC(f) ((VALUE (*)()) f)
-#    define VALUEFUNC(f) ((VALUE (*)()) f)
-#    define VOIDFUNC(f)  ((void (*)()) f)
-#  else
-#    ifndef ANYARGS /* These definitions should work for Ruby 1.6 */
-#      define PROTECTFUNC(f) ((VALUE (*)()) f)
-#      define VALUEFUNC(f) ((VALUE (*)()) f)
-#      define VOIDFUNC(f)  ((RUBY_DATA_FUNC) f)
-#    else /* These definitions should work for Ruby 1.7+ */
-#      define PROTECTFUNC(f) ((VALUE (*)(VALUE)) f)
-#      define VALUEFUNC(f) ((VALUE (*)(ANYARGS)) f)
-#      define VOIDFUNC(f)  ((RUBY_DATA_FUNC) f)
-#    endif
-#  endif
+#if defined(__cplusplus) && !defined(RB_METHOD_DEFINITION_DECL)
+#  define PROTECTFUNC(f) ((VALUE (*)(VALUE)) f)
+#  define VALUEFUNC(f) ((VALUE (*)(ANYARGS)) f)
+#  define VOIDFUNC(f) ((RUBY_DATA_FUNC) f)
+#  define SWIG_RUBY_VOID_ANYARGS_FUNC(f) ((void (*)(ANYARGS))(f))
+#  define SWIG_RUBY_INT_ANYARGS_FUNC(f) ((int (*)(ANYARGS))(f))
 #else
+#  define PROTECTFUNC(f) (f)
 #  define VALUEFUNC(f) (f)
 #  define VOIDFUNC(f) (f)
+#  define SWIG_RUBY_VOID_ANYARGS_FUNC(f) (f)
+#  define SWIG_RUBY_INT_ANYARGS_FUNC(f) (f)
 #endif
 
 /* Don't use for expressions have side effect */
index 3a84819..4b078de 100644 (file)
 %fragment("SWIG_ruby_failed","header")
 {
 SWIGINTERN VALUE
-SWIG_ruby_failed(void)
+SWIG_ruby_failed(VALUE SWIGUNUSEDPARM(arg1), VALUE SWIGUNUSEDPARM(arg2))
 {
   return Qnil;
 } 
 }
 
 %define %ruby_aux_method(Type, Method, Action)
-SWIGINTERN VALUE SWIG_AUX_##Method##(VALUE *args)
+SWIGINTERN VALUE SWIG_AUX_##Method##(VALUE arg)
 {
+  VALUE *args = (VALUE *)arg;
   VALUE obj = args[0];
   VALUE type = TYPE(obj);
   Type *res = (Type *)(args[1]);
@@ -79,7 +80,7 @@ SWIG_AsVal_dec(long)(VALUE obj, long* val)
     VALUE a[2];
     a[0] = obj;
     a[1] = (VALUE)(&v);
-    if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2LONG), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
+    if (rb_rescue(VALUEFUNC(SWIG_AUX_NUM2LONG), (VALUE)a, VALUEFUNC(SWIG_ruby_failed), 0) != Qnil) {
       if (val) *val = v;
       return SWIG_OK;
     }
@@ -111,7 +112,7 @@ SWIG_AsVal_dec(unsigned long)(VALUE obj, unsigned long *val)
     VALUE a[2];
     a[0] = obj;
     a[1] = (VALUE)(&v);
-    if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2ULONG), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
+    if (rb_rescue(VALUEFUNC(SWIG_AUX_NUM2ULONG), (VALUE)a, VALUEFUNC(SWIG_ruby_failed), 0) != Qnil) {
       if (val) *val = v;
       return SWIG_OK;
     }
@@ -149,7 +150,7 @@ SWIG_AsVal_dec(long long)(VALUE obj, long long *val)
     VALUE a[2];
     a[0] = obj;
     a[1] = (VALUE)(&v);
-    if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2LL), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
+    if (rb_rescue(VALUEFUNC(SWIG_AUX_NUM2LL), (VALUE)a, VALUEFUNC(SWIG_ruby_failed), 0) != Qnil) {
       if (val) *val = v;
       return SWIG_OK;
     }
@@ -187,7 +188,7 @@ SWIG_AsVal_dec(unsigned long long)(VALUE obj, unsigned long long *val)
     VALUE a[2];
     a[0] = obj;
     a[1] = (VALUE)(&v);
-    if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2ULL), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
+    if (rb_rescue(VALUEFUNC(SWIG_AUX_NUM2ULL), (VALUE)a, VALUEFUNC(SWIG_ruby_failed), 0) != Qnil) {
       if (val) *val = v;
       return SWIG_OK;
     }
@@ -215,7 +216,7 @@ SWIG_AsVal_dec(double)(VALUE obj, double *val)
     VALUE a[2];
     a[0] = obj;
     a[1] = (VALUE)(&v);
-    if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2DBL), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
+    if (rb_rescue(VALUEFUNC(SWIG_AUX_NUM2DBL), (VALUE)a, VALUEFUNC(SWIG_ruby_failed), 0) != Qnil) {
       if (val) *val = v;
       return SWIG_OK;
     }
index 4b2ffe4..3b6fd32 100644 (file)
@@ -235,6 +235,8 @@ SWIGRUNTIMEINLINE char *
 SWIG_Ruby_MangleStr(VALUE obj)
 {
   VALUE stype = rb_iv_get(obj, "@__swigtype__");
+  if (NIL_P(stype))
+    return NULL;
   return StringValuePtr(stype);
 }
 
index b9fb249..1edcc56 100644 (file)
@@ -32,7 +32,7 @@ extern "C" {
 */
 static st_table* swig_ruby_trackings = NULL;
 
-static VALUE swig_ruby_trackings_count(ANYARGS) {
+static VALUE swig_ruby_trackings_count(ID id, VALUE *var) {
   return SWIG2NUM(swig_ruby_trackings->num_entries);
 }
 
@@ -69,7 +69,9 @@ SWIGRUNTIME void SWIG_RubyInitializeTrackings(void) {
     swig_ruby_trackings = (st_table*)NUM2SWIG(trackings_value);
   }
 
-  rb_define_virtual_variable("SWIG_TRACKINGS_COUNT", swig_ruby_trackings_count, NULL);
+  rb_define_virtual_variable("SWIG_TRACKINGS_COUNT",
+                             VALUEFUNC(swig_ruby_trackings_count),
+                             SWIG_RUBY_VOID_ANYARGS_FUNC((rb_gvar_setter_t*)NULL));
 }
 
 /* Add a Tracking from a C/C++ struct to a Ruby object */
@@ -118,13 +120,15 @@ SWIGRUNTIME void SWIG_RubyUnlinkObjects(void* ptr) {
    to the passed callback function. */
 
 /* Proxy method to abstract the internal trackings datatype */
-static int swig_ruby_internal_iterate_callback(void* ptr, VALUE obj, void(*meth)(void* ptr, VALUE obj)) {
-  (*meth)(ptr, obj);
+static int swig_ruby_internal_iterate_callback(st_data_t ptr, st_data_t obj, st_data_t meth) {
+  ((void (*) (void *, VALUE))meth)((void *)ptr, (VALUE)obj);
   return ST_CONTINUE;
 }
 
 SWIGRUNTIME void SWIG_RubyIterateTrackings( void(*meth)(void* ptr, VALUE obj) ) {
-  st_foreach(swig_ruby_trackings, (int (*)(ANYARGS))&swig_ruby_internal_iterate_callback, (st_data_t)meth);
+  st_foreach(swig_ruby_trackings,
+             SWIG_RUBY_INT_ANYARGS_FUNC(swig_ruby_internal_iterate_callback),
+             (st_data_t)meth);
 }
 
 #ifdef __cplusplus
diff --git a/Lib/ruby/std_auto_ptr.i b/Lib/ruby/std_auto_ptr.i
new file mode 100644 (file)
index 0000000..3a415b9
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+    The typemaps here allow to handle functions returning std::auto_ptr<>,
+    which is the most common use of this type. If you have functions taking it
+    as parameter, these typemaps can't be used for them and you need to do
+    something else (e.g. use shared_ptr<> which SWIG supports fully).
+ */
+
+%define %auto_ptr(TYPE)
+%typemap (out) std::auto_ptr<TYPE > %{
+   %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+%template() std::auto_ptr<TYPE >;
+%enddef
+
+namespace std {
+   template <class T> class auto_ptr {};
+}
index dee35ec..086e308 100644 (file)
@@ -13,24 +13,27 @@ namespace swig {
   template <class Type>
   struct traits_asptr<std::shared_ptr<Type> > {
     static int asptr(VALUE obj, std::shared_ptr<Type> **val) {
-      std::shared_ptr<Type> *p = 0;
+      int res = SWIG_ERROR;
       swig_type_info *descriptor = type_info<std::shared_ptr<Type> >();
-      swig_ruby_owntype newmem = {0, 0};
-      int res = descriptor ? SWIG_ConvertPtrAndOwn(obj, (void **)&p, descriptor, 0, &newmem) : SWIG_ERROR;
-      if (SWIG_IsOK(res)) {
-       if (val) {
-         if (*val) {
-           **val = p ? *p : std::shared_ptr<Type>();
-         } else {
-           *val = p;
-           if (newmem.own & SWIG_CAST_NEW_MEMORY) {
-             // Upcast for pointers to shared_ptr in this generic framework has not been implemented
-             res = SWIG_ERROR;
-           }
-         }
-       }
-       if (newmem.own & SWIG_CAST_NEW_MEMORY)
-         delete p;
+      if (val) {
+        std::shared_ptr<Type> *p = 0;
+        swig_ruby_owntype newmem = {0, 0};
+        res = descriptor ? SWIG_ConvertPtrAndOwn(obj, (void **)&p, descriptor, 0, &newmem) : SWIG_ERROR;
+        if (SWIG_IsOK(res)) {
+          if (*val) {
+            **val = p ? *p : std::shared_ptr<Type>();
+          } else {
+            *val = p;
+            if (newmem.own & SWIG_CAST_NEW_MEMORY) {
+              // Upcast for pointers to shared_ptr in this generic framework has not been implemented
+              res = SWIG_ERROR;
+            }
+          }
+          if (newmem.own & SWIG_CAST_NEW_MEMORY)
+            delete p;
+        }
+      } else {
+        res = descriptor ? SWIG_ConvertPtr(obj, 0, descriptor, 0) : SWIG_ERROR;
       }
       return res;
     }
index 2b63343..c5d168a 100644 (file)
@@ -1,4 +1,15 @@
 %{
+#if defined(__linux__)
+#include <endian.h>
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define SWIG_RUBY_ENDIAN "LE"
+#elif BYTE_ORDER == BIG_ENDIAN
+#define SWIG_RUBY_ENDIAN "BE"
+#endif
+#else
+#define SWIG_RUBY_ENDIAN "LE"
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -15,9 +26,9 @@ extern "C" {
 #ifndef SWIG_RUBY_WSTRING_ENCODING
 
 #if WCHAR_MAX == 0x7fff || WCHAR_MAX == 0xffff
-#define SWIG_RUBY_WSTRING_ENCODING "UTF-16LE"
+#define SWIG_RUBY_WSTRING_ENCODING "UTF-16" SWIG_RUBY_ENDIAN
 #elif WCHAR_MAX == 0x7fffffff || WCHAR_MAX == 0xffffffff
-#define SWIG_RUBY_WSTRING_ENCODING "UTF-32LE"
+#define SWIG_RUBY_WSTRING_ENCODING "UTF-32" SWIG_RUBY_ENDIAN
 #else
 #error unsupported wchar_t size. SWIG_RUBY_WSTRING_ENCODING must be given.
 #endif
diff --git a/README b/README
index 6d11833..24a0de3 100644 (file)
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
 SWIG (Simplified Wrapper and Interface Generator)
 
-Version: 4.0.1 (21 Aug 2019)
+Version: 4.0.2 (8 Jun 2020)
 
 Tagline: SWIG is a compiler that integrates C and C++ with languages
          including Perl, Python, Tcl, Ruby, PHP, Java, C#, D, Go, Lua,
index 8633dad..cc3ba07 100644 (file)
@@ -7,6 +7,14 @@ Release Notes
 Detailed release notes are available with the release and are also
 published on the SWIG web site at http://swig.org/release.html.
 
+SWIG-4.0.2 summary:
+- A few fixes around doxygen comment handling.
+- Ruby 2.7 support added.
+- Various minor improvements to C#, D, Java, OCaml, Octave, Python,
+  R, Ruby.
+- Considerable performance improvement running SWIG on large
+  interface files.
+
 SWIG-4.0.1 summary:
 - SWIG now cleans up on error by removing all generated files.
 - Add Python 3.8 support.
index 4566817..19a0138 100644 (file)
@@ -428,17 +428,32 @@ static int yylook(void) {
        /* Concatenate or skip all consecutive comments at once. */
        do {
          String *cmt = Scanner_text(scan);
+         String *cmt_modified = 0;
          char *loc = Char(cmt);
          if ((strncmp(loc, "/*@SWIG", 7) == 0) && (loc[Len(cmt)-3] == '@')) {
            Scanner_locator(scan, cmt);
          }
          if (scan_doxygen_comments) { /* else just skip this node, to avoid crashes in parser module*/
+
+           int slashStyle = 0; /* Flag for "///" style doxygen comments */
+           if (strncmp(loc, "///", 3) == 0) {
+             slashStyle = 1;
+             if (Len(cmt) == 3) {
+               /* Modify to make length=4 to ensure that the empty comment does
+                  get processed to preserve the newlines in the original comments. */
+               cmt_modified = NewStringf("%s ", cmt);
+               cmt = cmt_modified;
+               loc = Char(cmt);
+             }
+           }
+           
            /* Check for all possible Doxygen comment start markers while ignoring
               comments starting with a row of asterisks or slashes just as
-              Doxygen itself does. */
+              Doxygen itself does.  Also skip empty comment (slash-star-star-slash), 
+              which causes a crash due to begin > end. */
            if (Len(cmt) > 3 && loc[0] == '/' &&
                ((loc[1] == '/' && ((loc[2] == '/' && loc[3] != '/') || loc[2] == '!')) ||
-                (loc[1] == '*' && ((loc[2] == '*' && loc[3] != '*') || loc[2] == '!')))) {
+                (loc[1] == '*' && ((loc[2] == '*' && loc[3] != '*' && loc[3] != '/') || loc[2] == '!')))) {
              comment_kind_t this_comment = loc[3] == '<' ? DOX_COMMENT_POST : DOX_COMMENT_PRE;
              if (existing_comment != DOX_COMMENT_NONE && this_comment != existing_comment) {
                /* We can't concatenate together Doxygen pre- and post-comments. */
@@ -461,6 +476,13 @@ static int yylook(void) {
                  Setline(yylval.str, Scanner_start_line(scan));
                  Setfile(yylval.str, Scanner_file(scan));
                } else {
+                 if (slashStyle) {
+                   /* Add a newline to the end of each doxygen "///" comment,
+                      since they are processed individually, unlike the
+                      slash-star style, which gets processed as a block with
+                      newlines included. */
+                   Append(yylval.str, "\n");
+                 }
                  Append(yylval.str, str);
                }
 
@@ -471,6 +493,7 @@ static int yylook(void) {
          do {
            tok = Scanner_token(scan);
          } while (tok == SWIG_TOKEN_ENDLINE);
+         Delete(cmt_modified);
        } while (tok == SWIG_TOKEN_COMMENT);
 
        Scanner_pushtoken(scan, tok, Scanner_text(scan));
@@ -873,10 +896,14 @@ int yylex(void) {
          return (USING);
        if (strcmp(yytext, "namespace") == 0)
          return (NAMESPACE);
-       if (strcmp(yytext, "override") == 0)
+       if (strcmp(yytext, "override") == 0) {
+         last_id = 1;
          return (OVERRIDE);
-       if (strcmp(yytext, "final") == 0)
+       }
+       if (strcmp(yytext, "final") == 0) {
+         last_id = 1;
          return (FINAL);
+       }
       } else {
        if (strcmp(yytext, "class") == 0) {
          Swig_warning(WARN_PARSE_CLASS_KEYWORD, cparse_file, cparse_line, "class keyword used, but not in C++ mode.\n");
index 678b461..2f51ef6 100644 (file)
@@ -2301,46 +2301,46 @@ static const yytype_uint16 yyrline[] =
     4550,  4572,  4599,  4616,  4621,  4616,  4629,  4630,  4631,  4631,
     4647,  4648,  4665,  4666,  4667,  4668,  4669,  4670,  4671,  4672,
     4673,  4674,  4675,  4676,  4677,  4678,  4679,  4680,  4682,  4685,
-    4689,  4701,  4730,  4760,  4793,  4809,  4827,  4846,  4866,  4886,
-    4894,  4901,  4908,  4916,  4924,  4927,  4931,  4934,  4935,  4936,
-    4937,  4938,  4939,  4940,  4941,  4944,  4955,  4966,  4979,  4990,
-    5001,  5015,  5018,  5021,  5022,  5026,  5028,  5036,  5048,  5049,
-    5050,  5051,  5052,  5053,  5054,  5055,  5056,  5057,  5058,  5059,
-    5060,  5061,  5062,  5063,  5064,  5065,  5066,  5067,  5074,  5085,
-    5089,  5096,  5100,  5105,  5109,  5121,  5131,  5141,  5144,  5148,
-    5154,  5167,  5171,  5174,  5178,  5182,  5210,  5218,  5231,  5247,
-    5258,  5268,  5280,  5284,  5288,  5295,  5317,  5334,  5353,  5372,
-    5379,  5387,  5396,  5405,  5409,  5418,  5429,  5440,  5452,  5462,
-    5476,  5484,  5493,  5502,  5506,  5515,  5526,  5537,  5549,  5559,
-    5569,  5580,  5593,  5600,  5608,  5624,  5632,  5643,  5654,  5665,
-    5684,  5692,  5709,  5717,  5724,  5731,  5742,  5754,  5765,  5777,
-    5788,  5799,  5819,  5840,  5846,  5852,  5859,  5866,  5875,  5884,
-    5887,  5896,  5905,  5912,  5919,  5926,  5934,  5944,  5955,  5966,
-    5977,  5984,  5991,  5994,  6011,  6029,  6039,  6046,  6052,  6057,
-    6064,  6068,  6073,  6080,  6084,  6090,  6094,  6100,  6101,  6102,
-    6108,  6114,  6118,  6119,  6123,  6130,  6133,  6134,  6138,  6139,
-    6141,  6144,  6147,  6152,  6163,  6188,  6191,  6245,  6249,  6253,
-    6257,  6261,  6265,  6269,  6273,  6277,  6281,  6285,  6289,  6293,
-    6297,  6303,  6303,  6319,  6324,  6327,  6333,  6348,  6364,  6365,
-    6368,  6369,  6373,  6374,  6384,  6388,  6393,  6403,  6414,  6419,
-    6424,  6427,  6433,  6441,  6453,  6468,  6469,  6489,  6493,  6503,
-    6509,  6512,  6515,  6519,  6524,  6529,  6530,  6535,  6549,  6565,
-    6575,  6593,  6600,  6607,  6614,  6622,  6630,  6634,  6638,  6644,
-    6645,  6646,  6647,  6648,  6649,  6650,  6651,  6654,  6658,  6662,
-    6666,  6670,  6674,  6678,  6682,  6686,  6690,  6694,  6698,  6702,
-    6706,  6720,  6724,  6728,  6734,  6738,  6742,  6746,  6750,  6766,
-    6771,  6774,  6779,  6784,  6784,  6785,  6788,  6805,  6814,  6814,
-    6832,  6832,  6850,  6851,  6852,  6855,  6859,  6863,  6867,  6873,
-    6876,  6880,  6886,  6890,  6894,  6900,  6903,  6908,  6909,  6912,
-    6915,  6918,  6921,  6926,  6929,  6934,  6940,  6946,  6952,  6958,
-    6964,  6972,  6980,  6985,  6992,  6995,  7005,  7016,  7027,  7037,
-    7047,  7055,  7067,  7068,  7071,  7072,  7073,  7074,  7077,  7089,
-    7095,  7104,  7105,  7106,  7109,  7110,  7111,  7114,  7115,  7118,
-    7123,  7127,  7130,  7133,  7136,  7139,  7144,  7148,  7151,  7158,
-    7164,  7167,  7172,  7175,  7181,  7186,  7190,  7193,  7196,  7199,
-    7204,  7208,  7211,  7214,  7220,  7223,  7226,  7234,  7237,  7240,
-    7244,  7249,  7262,  7266,  7271,  7277,  7281,  7286,  7290,  7297,
-    7300,  7305
+    4689,  4701,  4730,  4760,  4793,  4812,  4833,  4855,  4878,  4901,
+    4909,  4916,  4923,  4931,  4939,  4942,  4946,  4949,  4950,  4951,
+    4952,  4953,  4954,  4955,  4956,  4959,  4970,  4981,  4994,  5005,
+    5016,  5030,  5033,  5036,  5037,  5041,  5043,  5051,  5063,  5064,
+    5065,  5066,  5067,  5068,  5069,  5070,  5071,  5072,  5073,  5074,
+    5075,  5076,  5077,  5078,  5079,  5080,  5081,  5082,  5089,  5100,
+    5104,  5111,  5115,  5120,  5124,  5136,  5146,  5156,  5159,  5163,
+    5169,  5182,  5186,  5189,  5193,  5197,  5225,  5233,  5246,  5262,
+    5273,  5283,  5295,  5299,  5303,  5310,  5332,  5349,  5368,  5387,
+    5394,  5402,  5411,  5420,  5424,  5433,  5444,  5455,  5467,  5477,
+    5491,  5499,  5508,  5517,  5521,  5530,  5541,  5552,  5564,  5574,
+    5584,  5595,  5608,  5615,  5623,  5639,  5647,  5658,  5669,  5680,
+    5699,  5707,  5724,  5732,  5739,  5746,  5757,  5769,  5780,  5792,
+    5803,  5814,  5834,  5855,  5861,  5867,  5874,  5881,  5890,  5899,
+    5902,  5911,  5920,  5927,  5934,  5941,  5949,  5959,  5970,  5981,
+    5992,  5999,  6006,  6009,  6026,  6044,  6054,  6061,  6067,  6072,
+    6079,  6083,  6088,  6095,  6099,  6105,  6109,  6115,  6116,  6117,
+    6123,  6129,  6133,  6134,  6138,  6145,  6148,  6149,  6153,  6154,
+    6156,  6159,  6162,  6167,  6178,  6203,  6206,  6260,  6264,  6268,
+    6272,  6276,  6280,  6284,  6288,  6292,  6296,  6300,  6304,  6308,
+    6312,  6318,  6318,  6334,  6339,  6342,  6348,  6363,  6379,  6380,
+    6383,  6384,  6388,  6389,  6399,  6403,  6408,  6418,  6429,  6434,
+    6439,  6442,  6448,  6456,  6468,  6483,  6484,  6504,  6508,  6518,
+    6524,  6527,  6530,  6534,  6539,  6544,  6545,  6550,  6564,  6580,
+    6590,  6608,  6615,  6622,  6629,  6637,  6645,  6649,  6653,  6659,
+    6660,  6661,  6662,  6663,  6664,  6665,  6666,  6669,  6673,  6677,
+    6681,  6685,  6689,  6693,  6697,  6701,  6705,  6709,  6713,  6717,
+    6721,  6735,  6739,  6743,  6749,  6753,  6757,  6761,  6765,  6781,
+    6786,  6789,  6794,  6799,  6799,  6800,  6803,  6820,  6829,  6829,
+    6847,  6847,  6865,  6866,  6867,  6870,  6874,  6878,  6882,  6888,
+    6891,  6895,  6901,  6905,  6909,  6915,  6918,  6923,  6924,  6927,
+    6930,  6933,  6936,  6941,  6944,  6949,  6955,  6961,  6967,  6973,
+    6979,  6987,  6995,  7000,  7007,  7010,  7020,  7031,  7042,  7052,
+    7062,  7070,  7082,  7083,  7086,  7087,  7088,  7089,  7092,  7104,
+    7110,  7119,  7120,  7121,  7124,  7125,  7126,  7129,  7130,  7133,
+    7138,  7142,  7145,  7148,  7151,  7154,  7159,  7163,  7166,  7173,
+    7179,  7182,  7187,  7190,  7196,  7201,  7205,  7208,  7211,  7214,
+    7219,  7223,  7226,  7229,  7235,  7238,  7241,  7249,  7252,  7255,
+    7259,  7264,  7277,  7281,  7286,  7292,  7296,  7301,  7305,  7312,
+    7315,  7320
 };
 #endif
 
@@ -8667,17 +8667,20 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                 if ((yyvsp[0].dtype).qualifier) {
                   SwigType_push((yyvsp[-4].type),(yyvsp[0].dtype).qualifier);
                 }
+                if ((yyvsp[0].dtype).val) {
+                  Setattr((yyval.node),"value",(yyvsp[0].dtype).val);
+                }
                 Setattr((yyval.node),"refqualifier",(yyvsp[0].dtype).refqualifier);
                 Setattr((yyval.node),"decl",(yyvsp[-4].type));
                 Setattr((yyval.node),"parms",(yyvsp[-2].pl));
                 Setattr((yyval.node),"conversion_operator","1");
                 add_symbols((yyval.node));
               }
-#line 8677 "y.tab.c" /* yacc.c:1646  */
+#line 8680 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 225:
-#line 4809 "parser.y" /* yacc.c:1646  */
+#line 4812 "parser.y" /* yacc.c:1646  */
     {
                 SwigType *decl;
                  (yyval.node) = new_node("cdecl");
@@ -8690,17 +8693,20 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                 if ((yyvsp[0].dtype).qualifier) {
                   SwigType_push(decl,(yyvsp[0].dtype).qualifier);
                 }
+                if ((yyvsp[0].dtype).val) {
+                  Setattr((yyval.node),"value",(yyvsp[0].dtype).val);
+                }
                 Setattr((yyval.node),"refqualifier",(yyvsp[0].dtype).refqualifier);
                 Setattr((yyval.node),"decl",decl);
                 Setattr((yyval.node),"parms",(yyvsp[-2].pl));
                 Setattr((yyval.node),"conversion_operator","1");
                 add_symbols((yyval.node));
               }
-#line 8700 "y.tab.c" /* yacc.c:1646  */
+#line 8706 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 226:
-#line 4827 "parser.y" /* yacc.c:1646  */
+#line 4833 "parser.y" /* yacc.c:1646  */
     {
                 SwigType *decl;
                  (yyval.node) = new_node("cdecl");
@@ -8713,17 +8719,20 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                 if ((yyvsp[0].dtype).qualifier) {
                   SwigType_push(decl,(yyvsp[0].dtype).qualifier);
                 }
+                if ((yyvsp[0].dtype).val) {
+                  Setattr((yyval.node),"value",(yyvsp[0].dtype).val);
+                }
                 Setattr((yyval.node),"refqualifier",(yyvsp[0].dtype).refqualifier);
                 Setattr((yyval.node),"decl",decl);
                 Setattr((yyval.node),"parms",(yyvsp[-2].pl));
                 Setattr((yyval.node),"conversion_operator","1");
                 add_symbols((yyval.node));
               }
-#line 8723 "y.tab.c" /* yacc.c:1646  */
+#line 8732 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 227:
-#line 4846 "parser.y" /* yacc.c:1646  */
+#line 4855 "parser.y" /* yacc.c:1646  */
     {
                 SwigType *decl;
                  (yyval.node) = new_node("cdecl");
@@ -8737,17 +8746,20 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                 if ((yyvsp[0].dtype).qualifier) {
                   SwigType_push(decl,(yyvsp[0].dtype).qualifier);
                 }
+                if ((yyvsp[0].dtype).val) {
+                  Setattr((yyval.node),"value",(yyvsp[0].dtype).val);
+                }
                 Setattr((yyval.node),"refqualifier",(yyvsp[0].dtype).refqualifier);
                 Setattr((yyval.node),"decl",decl);
                 Setattr((yyval.node),"parms",(yyvsp[-2].pl));
                 Setattr((yyval.node),"conversion_operator","1");
                 add_symbols((yyval.node));
               }
-#line 8747 "y.tab.c" /* yacc.c:1646  */
+#line 8759 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 228:
-#line 4866 "parser.y" /* yacc.c:1646  */
+#line 4878 "parser.y" /* yacc.c:1646  */
     {
                String *t = NewStringEmpty();
                (yyval.node) = new_node("cdecl");
@@ -8758,131 +8770,134 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                if ((yyvsp[0].dtype).qualifier) {
                  SwigType_push(t,(yyvsp[0].dtype).qualifier);
                }
-                Setattr((yyval.node),"refqualifier",(yyvsp[0].dtype).refqualifier);
+               if ((yyvsp[0].dtype).val) {
+                 Setattr((yyval.node),"value",(yyvsp[0].dtype).val);
+               }
+               Setattr((yyval.node),"refqualifier",(yyvsp[0].dtype).refqualifier);
                Setattr((yyval.node),"decl",t);
                Setattr((yyval.node),"parms",(yyvsp[-2].pl));
                Setattr((yyval.node),"conversion_operator","1");
                add_symbols((yyval.node));
               }
-#line 8768 "y.tab.c" /* yacc.c:1646  */
+#line 8783 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 229:
-#line 4886 "parser.y" /* yacc.c:1646  */
+#line 4901 "parser.y" /* yacc.c:1646  */
     {
                  skip_balanced('{','}');
                  (yyval.node) = 0;
                }
-#line 8777 "y.tab.c" /* yacc.c:1646  */
+#line 8792 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 230:
-#line 4894 "parser.y" /* yacc.c:1646  */
+#line 4909 "parser.y" /* yacc.c:1646  */
     {
                 skip_balanced('(',')');
                 (yyval.node) = 0;
               }
-#line 8786 "y.tab.c" /* yacc.c:1646  */
+#line 8801 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 231:
-#line 4901 "parser.y" /* yacc.c:1646  */
+#line 4916 "parser.y" /* yacc.c:1646  */
     { 
                 (yyval.node) = new_node("access");
                Setattr((yyval.node),"kind","public");
                 cplus_mode = CPLUS_PUBLIC;
               }
-#line 8796 "y.tab.c" /* yacc.c:1646  */
+#line 8811 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 232:
-#line 4908 "parser.y" /* yacc.c:1646  */
+#line 4923 "parser.y" /* yacc.c:1646  */
     { 
                 (yyval.node) = new_node("access");
                 Setattr((yyval.node),"kind","private");
                cplus_mode = CPLUS_PRIVATE;
              }
-#line 8806 "y.tab.c" /* yacc.c:1646  */
+#line 8821 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 233:
-#line 4916 "parser.y" /* yacc.c:1646  */
+#line 4931 "parser.y" /* yacc.c:1646  */
     { 
                (yyval.node) = new_node("access");
                Setattr((yyval.node),"kind","protected");
                cplus_mode = CPLUS_PROTECTED;
              }
-#line 8816 "y.tab.c" /* yacc.c:1646  */
+#line 8831 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 234:
-#line 4924 "parser.y" /* yacc.c:1646  */
+#line 4939 "parser.y" /* yacc.c:1646  */
     { (yyval.node) = (yyvsp[0].node); }
-#line 8822 "y.tab.c" /* yacc.c:1646  */
+#line 8837 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 235:
-#line 4927 "parser.y" /* yacc.c:1646  */
+#line 4942 "parser.y" /* yacc.c:1646  */
     { (yyval.node) = (yyvsp[0].node); }
-#line 8828 "y.tab.c" /* yacc.c:1646  */
+#line 8843 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 236:
-#line 4931 "parser.y" /* yacc.c:1646  */
+#line 4946 "parser.y" /* yacc.c:1646  */
     { (yyval.node) = (yyvsp[0].node); }
-#line 8834 "y.tab.c" /* yacc.c:1646  */
+#line 8849 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 237:
-#line 4934 "parser.y" /* yacc.c:1646  */
+#line 4949 "parser.y" /* yacc.c:1646  */
     { (yyval.node) = (yyvsp[0].node); }
-#line 8840 "y.tab.c" /* yacc.c:1646  */
+#line 8855 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 238:
-#line 4935 "parser.y" /* yacc.c:1646  */
+#line 4950 "parser.y" /* yacc.c:1646  */
     { (yyval.node) = (yyvsp[0].node); }
-#line 8846 "y.tab.c" /* yacc.c:1646  */
+#line 8861 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 239:
-#line 4936 "parser.y" /* yacc.c:1646  */
+#line 4951 "parser.y" /* yacc.c:1646  */
     { (yyval.node) = (yyvsp[0].node); }
-#line 8852 "y.tab.c" /* yacc.c:1646  */
+#line 8867 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 240:
-#line 4937 "parser.y" /* yacc.c:1646  */
+#line 4952 "parser.y" /* yacc.c:1646  */
     { (yyval.node) = (yyvsp[0].node); }
-#line 8858 "y.tab.c" /* yacc.c:1646  */
+#line 8873 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 241:
-#line 4938 "parser.y" /* yacc.c:1646  */
+#line 4953 "parser.y" /* yacc.c:1646  */
     { (yyval.node) = (yyvsp[0].node); }
-#line 8864 "y.tab.c" /* yacc.c:1646  */
+#line 8879 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 242:
-#line 4939 "parser.y" /* yacc.c:1646  */
+#line 4954 "parser.y" /* yacc.c:1646  */
     { (yyval.node) = (yyvsp[0].node); }
-#line 8870 "y.tab.c" /* yacc.c:1646  */
+#line 8885 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 243:
-#line 4940 "parser.y" /* yacc.c:1646  */
+#line 4955 "parser.y" /* yacc.c:1646  */
     { (yyval.node) = (yyvsp[0].node); }
-#line 8876 "y.tab.c" /* yacc.c:1646  */
+#line 8891 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 244:
-#line 4941 "parser.y" /* yacc.c:1646  */
+#line 4956 "parser.y" /* yacc.c:1646  */
     { (yyval.node) = (yyvsp[0].node); }
-#line 8882 "y.tab.c" /* yacc.c:1646  */
+#line 8897 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 245:
-#line 4944 "parser.y" /* yacc.c:1646  */
+#line 4959 "parser.y" /* yacc.c:1646  */
     {
                    Clear(scanner_ccode);
                    (yyval.dtype).val = 0;
@@ -8894,11 +8909,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    (yyval.dtype).nexcept = (yyvsp[-1].dtype).nexcept;
                    (yyval.dtype).final = (yyvsp[-1].dtype).final;
                }
-#line 8898 "y.tab.c" /* yacc.c:1646  */
+#line 8913 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 246:
-#line 4955 "parser.y" /* yacc.c:1646  */
+#line 4970 "parser.y" /* yacc.c:1646  */
     {
                    Clear(scanner_ccode);
                    (yyval.dtype).val = (yyvsp[-1].dtype).val;
@@ -8910,11 +8925,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    (yyval.dtype).nexcept = (yyvsp[-3].dtype).nexcept;
                    (yyval.dtype).final = (yyvsp[-3].dtype).final;
                }
-#line 8914 "y.tab.c" /* yacc.c:1646  */
+#line 8929 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 247:
-#line 4966 "parser.y" /* yacc.c:1646  */
+#line 4981 "parser.y" /* yacc.c:1646  */
     { 
                    skip_balanced('{','}'); 
                    (yyval.dtype).val = 0;
@@ -8926,11 +8941,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    (yyval.dtype).nexcept = (yyvsp[-1].dtype).nexcept;
                    (yyval.dtype).final = (yyvsp[-1].dtype).final;
               }
-#line 8930 "y.tab.c" /* yacc.c:1646  */
+#line 8945 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 248:
-#line 4979 "parser.y" /* yacc.c:1646  */
+#line 4994 "parser.y" /* yacc.c:1646  */
     { 
                      Clear(scanner_ccode);
                      (yyval.dtype).val = 0;
@@ -8942,11 +8957,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                      (yyval.dtype).nexcept = (yyvsp[-1].dtype).nexcept;
                      (yyval.dtype).final = (yyvsp[-1].dtype).final;
                 }
-#line 8946 "y.tab.c" /* yacc.c:1646  */
+#line 8961 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 249:
-#line 4990 "parser.y" /* yacc.c:1646  */
+#line 5005 "parser.y" /* yacc.c:1646  */
     { 
                      Clear(scanner_ccode);
                      (yyval.dtype).val = (yyvsp[-1].dtype).val;
@@ -8958,11 +8973,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                      (yyval.dtype).nexcept = (yyvsp[-3].dtype).nexcept;
                      (yyval.dtype).final = (yyvsp[-3].dtype).final;
                }
-#line 8962 "y.tab.c" /* yacc.c:1646  */
+#line 8977 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 250:
-#line 5001 "parser.y" /* yacc.c:1646  */
+#line 5016 "parser.y" /* yacc.c:1646  */
     { 
                      skip_balanced('{','}');
                      (yyval.dtype).val = 0;
@@ -8974,51 +8989,51 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                      (yyval.dtype).nexcept = (yyvsp[-1].dtype).nexcept;
                      (yyval.dtype).final = (yyvsp[-1].dtype).final;
                }
-#line 8978 "y.tab.c" /* yacc.c:1646  */
+#line 8993 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 251:
-#line 5015 "parser.y" /* yacc.c:1646  */
+#line 5030 "parser.y" /* yacc.c:1646  */
     { }
-#line 8984 "y.tab.c" /* yacc.c:1646  */
+#line 8999 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 252:
-#line 5018 "parser.y" /* yacc.c:1646  */
+#line 5033 "parser.y" /* yacc.c:1646  */
     { (yyval.type) = (yyvsp[0].type);
                   /* Printf(stdout,"primitive = '%s'\n", $$);*/
                 }
-#line 8992 "y.tab.c" /* yacc.c:1646  */
+#line 9007 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 253:
-#line 5021 "parser.y" /* yacc.c:1646  */
+#line 5036 "parser.y" /* yacc.c:1646  */
     { (yyval.type) = (yyvsp[0].type); }
-#line 8998 "y.tab.c" /* yacc.c:1646  */
+#line 9013 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 254:
-#line 5022 "parser.y" /* yacc.c:1646  */
+#line 5037 "parser.y" /* yacc.c:1646  */
     { (yyval.type) = (yyvsp[0].type); }
-#line 9004 "y.tab.c" /* yacc.c:1646  */
+#line 9019 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 255:
-#line 5026 "parser.y" /* yacc.c:1646  */
+#line 5041 "parser.y" /* yacc.c:1646  */
     { (yyval.type) = (yyvsp[0].type); }
-#line 9010 "y.tab.c" /* yacc.c:1646  */
+#line 9025 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 256:
-#line 5028 "parser.y" /* yacc.c:1646  */
+#line 5043 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.type) = (yyvsp[0].str);
                }
-#line 9018 "y.tab.c" /* yacc.c:1646  */
+#line 9033 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 257:
-#line 5036 "parser.y" /* yacc.c:1646  */
+#line 5051 "parser.y" /* yacc.c:1646  */
     {
                    if (Strcmp((yyvsp[0].str),"C") == 0) {
                     (yyval.id) = "externc";
@@ -9029,131 +9044,131 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                     (yyval.id) = 0;
                   }
                }
-#line 9033 "y.tab.c" /* yacc.c:1646  */
+#line 9048 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 258:
-#line 5048 "parser.y" /* yacc.c:1646  */
+#line 5063 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "extern"; }
-#line 9039 "y.tab.c" /* yacc.c:1646  */
+#line 9054 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 259:
-#line 5049 "parser.y" /* yacc.c:1646  */
+#line 5064 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = (yyvsp[0].id); }
-#line 9045 "y.tab.c" /* yacc.c:1646  */
+#line 9060 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 260:
-#line 5050 "parser.y" /* yacc.c:1646  */
+#line 5065 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "thread_local"; }
-#line 9051 "y.tab.c" /* yacc.c:1646  */
+#line 9066 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 261:
-#line 5051 "parser.y" /* yacc.c:1646  */
+#line 5066 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "typedef"; }
-#line 9057 "y.tab.c" /* yacc.c:1646  */
+#line 9072 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 262:
-#line 5052 "parser.y" /* yacc.c:1646  */
+#line 5067 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "static"; }
-#line 9063 "y.tab.c" /* yacc.c:1646  */
+#line 9078 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 263:
-#line 5053 "parser.y" /* yacc.c:1646  */
+#line 5068 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "typedef"; }
-#line 9069 "y.tab.c" /* yacc.c:1646  */
+#line 9084 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 264:
-#line 5054 "parser.y" /* yacc.c:1646  */
+#line 5069 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "virtual"; }
-#line 9075 "y.tab.c" /* yacc.c:1646  */
+#line 9090 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 265:
-#line 5055 "parser.y" /* yacc.c:1646  */
+#line 5070 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "friend"; }
-#line 9081 "y.tab.c" /* yacc.c:1646  */
+#line 9096 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 266:
-#line 5056 "parser.y" /* yacc.c:1646  */
+#line 5071 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "explicit"; }
-#line 9087 "y.tab.c" /* yacc.c:1646  */
+#line 9102 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 267:
-#line 5057 "parser.y" /* yacc.c:1646  */
+#line 5072 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "constexpr"; }
-#line 9093 "y.tab.c" /* yacc.c:1646  */
+#line 9108 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 268:
-#line 5058 "parser.y" /* yacc.c:1646  */
+#line 5073 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "explicit constexpr"; }
-#line 9099 "y.tab.c" /* yacc.c:1646  */
+#line 9114 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 269:
-#line 5059 "parser.y" /* yacc.c:1646  */
+#line 5074 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "explicit constexpr"; }
-#line 9105 "y.tab.c" /* yacc.c:1646  */
+#line 9120 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 270:
-#line 5060 "parser.y" /* yacc.c:1646  */
+#line 5075 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "static constexpr"; }
-#line 9111 "y.tab.c" /* yacc.c:1646  */
+#line 9126 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 271:
-#line 5061 "parser.y" /* yacc.c:1646  */
+#line 5076 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "static constexpr"; }
-#line 9117 "y.tab.c" /* yacc.c:1646  */
+#line 9132 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 272:
-#line 5062 "parser.y" /* yacc.c:1646  */
+#line 5077 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "thread_local"; }
-#line 9123 "y.tab.c" /* yacc.c:1646  */
+#line 9138 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 273:
-#line 5063 "parser.y" /* yacc.c:1646  */
+#line 5078 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "static thread_local"; }
-#line 9129 "y.tab.c" /* yacc.c:1646  */
+#line 9144 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 274:
-#line 5064 "parser.y" /* yacc.c:1646  */
+#line 5079 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "static thread_local"; }
-#line 9135 "y.tab.c" /* yacc.c:1646  */
+#line 9150 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 275:
-#line 5065 "parser.y" /* yacc.c:1646  */
+#line 5080 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "extern thread_local"; }
-#line 9141 "y.tab.c" /* yacc.c:1646  */
+#line 9156 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 276:
-#line 5066 "parser.y" /* yacc.c:1646  */
+#line 5081 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "extern thread_local"; }
-#line 9147 "y.tab.c" /* yacc.c:1646  */
+#line 9162 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 277:
-#line 5067 "parser.y" /* yacc.c:1646  */
+#line 5082 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = 0; }
-#line 9153 "y.tab.c" /* yacc.c:1646  */
+#line 9168 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 278:
-#line 5074 "parser.y" /* yacc.c:1646  */
+#line 5089 "parser.y" /* yacc.c:1646  */
     {
                  Parm *p;
                 (yyval.pl) = (yyvsp[0].pl);
@@ -9163,55 +9178,55 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                   p = nextSibling(p);
                  }
                }
-#line 9167 "y.tab.c" /* yacc.c:1646  */
+#line 9182 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 279:
-#line 5085 "parser.y" /* yacc.c:1646  */
+#line 5100 "parser.y" /* yacc.c:1646  */
     {
                   set_nextSibling((yyvsp[-1].p),(yyvsp[0].pl));
                   (yyval.pl) = (yyvsp[-1].p);
                }
-#line 9176 "y.tab.c" /* yacc.c:1646  */
+#line 9191 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 280:
-#line 5089 "parser.y" /* yacc.c:1646  */
+#line 5104 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.pl) = 0;
                  previousNode = currentNode;
                  currentNode=0;
               }
-#line 9186 "y.tab.c" /* yacc.c:1646  */
+#line 9201 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 281:
-#line 5096 "parser.y" /* yacc.c:1646  */
+#line 5111 "parser.y" /* yacc.c:1646  */
     {
                  set_nextSibling((yyvsp[-1].p),(yyvsp[0].pl));
                 (yyval.pl) = (yyvsp[-1].p);
                 }
-#line 9195 "y.tab.c" /* yacc.c:1646  */
+#line 9210 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 282:
-#line 5100 "parser.y" /* yacc.c:1646  */
+#line 5115 "parser.y" /* yacc.c:1646  */
     {
                 set_comment(previousNode, (yyvsp[-2].str));
                  set_nextSibling((yyvsp[-1].p), (yyvsp[0].pl));
                 (yyval.pl) = (yyvsp[-1].p);
                }
-#line 9205 "y.tab.c" /* yacc.c:1646  */
+#line 9220 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 283:
-#line 5105 "parser.y" /* yacc.c:1646  */
+#line 5120 "parser.y" /* yacc.c:1646  */
     { (yyval.pl) = 0; }
-#line 9211 "y.tab.c" /* yacc.c:1646  */
+#line 9226 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 284:
-#line 5109 "parser.y" /* yacc.c:1646  */
+#line 5124 "parser.y" /* yacc.c:1646  */
     {
                    SwigType_push((yyvsp[-1].type),(yyvsp[0].decl).type);
                   (yyval.p) = NewParmWithoutFileLineInfo((yyvsp[-1].type),(yyvsp[0].decl).id);
@@ -9223,11 +9238,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                     Setattr((yyval.p),"value",(yyvsp[0].decl).defarg);
                   }
                }
-#line 9227 "y.tab.c" /* yacc.c:1646  */
+#line 9242 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 285:
-#line 5121 "parser.y" /* yacc.c:1646  */
+#line 5136 "parser.y" /* yacc.c:1646  */
     {
                   (yyval.p) = NewParmWithoutFileLineInfo(NewStringf("template<class> %s %s", (yyvsp[-2].id),(yyvsp[-1].str)), 0);
                  previousNode = currentNode;
@@ -9238,11 +9253,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                     Setattr((yyval.p),"value",(yyvsp[0].dtype).val);
                   }
                 }
-#line 9242 "y.tab.c" /* yacc.c:1646  */
+#line 9257 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 286:
-#line 5131 "parser.y" /* yacc.c:1646  */
+#line 5146 "parser.y" /* yacc.c:1646  */
     {
                  SwigType *t = NewString("v(...)");
                  (yyval.p) = NewParmWithoutFileLineInfo(t, 0);
@@ -9251,37 +9266,37 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                  Setfile((yyval.p),cparse_file);
                  Setline((yyval.p),cparse_line);
                }
-#line 9255 "y.tab.c" /* yacc.c:1646  */
+#line 9270 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 287:
-#line 5141 "parser.y" /* yacc.c:1646  */
+#line 5156 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.p) = (yyvsp[0].p);
                }
-#line 9263 "y.tab.c" /* yacc.c:1646  */
+#line 9278 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 288:
-#line 5144 "parser.y" /* yacc.c:1646  */
+#line 5159 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.p) = (yyvsp[0].p);
                  set_comment((yyvsp[0].p), (yyvsp[-1].str));
                }
-#line 9272 "y.tab.c" /* yacc.c:1646  */
+#line 9287 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 289:
-#line 5148 "parser.y" /* yacc.c:1646  */
+#line 5163 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.p) = (yyvsp[-1].p);
                  set_comment((yyvsp[-1].p), (yyvsp[0].str));
                }
-#line 9281 "y.tab.c" /* yacc.c:1646  */
+#line 9296 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 290:
-#line 5154 "parser.y" /* yacc.c:1646  */
+#line 5169 "parser.y" /* yacc.c:1646  */
     {
                  Parm *p;
                 (yyval.p) = (yyvsp[0].p);
@@ -9293,41 +9308,41 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                   p = nextSibling(p);
                  }
                }
-#line 9297 "y.tab.c" /* yacc.c:1646  */
+#line 9312 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 291:
-#line 5167 "parser.y" /* yacc.c:1646  */
+#line 5182 "parser.y" /* yacc.c:1646  */
     {
                   set_nextSibling((yyvsp[-1].p),(yyvsp[0].p));
                   (yyval.p) = (yyvsp[-1].p);
                }
-#line 9306 "y.tab.c" /* yacc.c:1646  */
+#line 9321 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 292:
-#line 5171 "parser.y" /* yacc.c:1646  */
+#line 5186 "parser.y" /* yacc.c:1646  */
     { (yyval.p) = 0; }
-#line 9312 "y.tab.c" /* yacc.c:1646  */
+#line 9327 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 293:
-#line 5174 "parser.y" /* yacc.c:1646  */
+#line 5189 "parser.y" /* yacc.c:1646  */
     {
                  set_nextSibling((yyvsp[-1].p),(yyvsp[0].p));
                 (yyval.p) = (yyvsp[-1].p);
                 }
-#line 9321 "y.tab.c" /* yacc.c:1646  */
+#line 9336 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 294:
-#line 5178 "parser.y" /* yacc.c:1646  */
+#line 5193 "parser.y" /* yacc.c:1646  */
     { (yyval.p) = 0; }
-#line 9327 "y.tab.c" /* yacc.c:1646  */
+#line 9342 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 295:
-#line 5182 "parser.y" /* yacc.c:1646  */
+#line 5197 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.p) = (yyvsp[0].p);
                  {
@@ -9356,22 +9371,22 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                  }
 
                }
-#line 9360 "y.tab.c" /* yacc.c:1646  */
+#line 9375 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 296:
-#line 5210 "parser.y" /* yacc.c:1646  */
+#line 5225 "parser.y" /* yacc.c:1646  */
     {
                   (yyval.p) = NewParmWithoutFileLineInfo(0,0);
                   Setfile((yyval.p),cparse_file);
                  Setline((yyval.p),cparse_line);
                  Setattr((yyval.p),"value",(yyvsp[0].dtype).val);
                }
-#line 9371 "y.tab.c" /* yacc.c:1646  */
+#line 9386 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 297:
-#line 5218 "parser.y" /* yacc.c:1646  */
+#line 5233 "parser.y" /* yacc.c:1646  */
     { 
                   (yyval.dtype) = (yyvsp[0].dtype); 
                  if ((yyvsp[0].dtype).type == T_ERROR) {
@@ -9385,11 +9400,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    (yyval.dtype).final = 0;
                  }
                }
-#line 9389 "y.tab.c" /* yacc.c:1646  */
+#line 9404 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 298:
-#line 5231 "parser.y" /* yacc.c:1646  */
+#line 5246 "parser.y" /* yacc.c:1646  */
     { 
                  (yyval.dtype) = (yyvsp[-3].dtype);
                  if ((yyvsp[-3].dtype).type == T_ERROR) {
@@ -9406,11 +9421,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    (yyval.dtype).val = NewStringf("%s[%s]",(yyvsp[-3].dtype).val,(yyvsp[-1].dtype).val); 
                  }               
                }
-#line 9410 "y.tab.c" /* yacc.c:1646  */
+#line 9425 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 299:
-#line 5247 "parser.y" /* yacc.c:1646  */
+#line 5262 "parser.y" /* yacc.c:1646  */
     {
                 skip_balanced('{','}');
                 (yyval.dtype).val = NewString(scanner_ccode);
@@ -9422,11 +9437,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                 (yyval.dtype).nexcept = 0;
                 (yyval.dtype).final = 0;
               }
-#line 9426 "y.tab.c" /* yacc.c:1646  */
+#line 9441 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 300:
-#line 5258 "parser.y" /* yacc.c:1646  */
+#line 5273 "parser.y" /* yacc.c:1646  */
     { 
                 (yyval.dtype).val = 0;
                 (yyval.dtype).rawval = 0;
@@ -9437,11 +9452,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                 (yyval.dtype).nexcept = 0;
                 (yyval.dtype).final = 0;
               }
-#line 9441 "y.tab.c" /* yacc.c:1646  */
+#line 9456 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 301:
-#line 5268 "parser.y" /* yacc.c:1646  */
+#line 5283 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype).val = 0;
                  (yyval.dtype).rawval = 0;
@@ -9452,39 +9467,39 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                 (yyval.dtype).nexcept = 0;
                 (yyval.dtype).final = 0;
                }
-#line 9456 "y.tab.c" /* yacc.c:1646  */
+#line 9471 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 302:
-#line 5280 "parser.y" /* yacc.c:1646  */
+#line 5295 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.decl) = (yyvsp[-1].decl);
                 (yyval.decl).defarg = (yyvsp[0].dtype).rawval ? (yyvsp[0].dtype).rawval : (yyvsp[0].dtype).val;
             }
-#line 9465 "y.tab.c" /* yacc.c:1646  */
+#line 9480 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 303:
-#line 5284 "parser.y" /* yacc.c:1646  */
+#line 5299 "parser.y" /* yacc.c:1646  */
     {
               (yyval.decl) = (yyvsp[-1].decl);
              (yyval.decl).defarg = (yyvsp[0].dtype).rawval ? (yyvsp[0].dtype).rawval : (yyvsp[0].dtype).val;
             }
-#line 9474 "y.tab.c" /* yacc.c:1646  */
+#line 9489 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 304:
-#line 5288 "parser.y" /* yacc.c:1646  */
+#line 5303 "parser.y" /* yacc.c:1646  */
     {
              (yyval.decl).type = 0;
               (yyval.decl).id = 0;
              (yyval.decl).defarg = (yyvsp[0].dtype).rawval ? (yyvsp[0].dtype).rawval : (yyvsp[0].dtype).val;
             }
-#line 9484 "y.tab.c" /* yacc.c:1646  */
+#line 9499 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 305:
-#line 5295 "parser.y" /* yacc.c:1646  */
+#line 5310 "parser.y" /* yacc.c:1646  */
     {
              SwigType *t;
              (yyval.decl) = (yyvsp[-4].decl);
@@ -9505,11 +9520,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
              }
              (yyval.decl).defarg = 0;
            }
-#line 9509 "y.tab.c" /* yacc.c:1646  */
+#line 9524 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 306:
-#line 5317 "parser.y" /* yacc.c:1646  */
+#line 5332 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.decl) = (yyvsp[0].decl);
                 if (SwigType_isfunction((yyvsp[0].decl).type)) {
@@ -9527,11 +9542,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                   (yyval.decl).parms = 0;
                 }
             }
-#line 9531 "y.tab.c" /* yacc.c:1646  */
+#line 9546 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 307:
-#line 5334 "parser.y" /* yacc.c:1646  */
+#line 5349 "parser.y" /* yacc.c:1646  */
     {
               (yyval.decl) = (yyvsp[0].decl);
              if (SwigType_isfunction((yyvsp[0].decl).type)) {
@@ -9549,11 +9564,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                (yyval.decl).parms = 0;
              }
             }
-#line 9553 "y.tab.c" /* yacc.c:1646  */
+#line 9568 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 308:
-#line 5353 "parser.y" /* yacc.c:1646  */
+#line 5368 "parser.y" /* yacc.c:1646  */
     {
              SwigType *t;
              (yyval.decl) = (yyvsp[-4].decl);
@@ -9573,21 +9588,21 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                (yyval.decl).type = t;
              }
            }
-#line 9577 "y.tab.c" /* yacc.c:1646  */
+#line 9592 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 309:
-#line 5372 "parser.y" /* yacc.c:1646  */
+#line 5387 "parser.y" /* yacc.c:1646  */
     {
              (yyval.decl).type = 0;
               (yyval.decl).id = 0;
              (yyval.decl).parms = 0;
              }
-#line 9587 "y.tab.c" /* yacc.c:1646  */
+#line 9602 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 310:
-#line 5379 "parser.y" /* yacc.c:1646  */
+#line 5394 "parser.y" /* yacc.c:1646  */
     {
               (yyval.decl) = (yyvsp[0].decl);
              if ((yyval.decl).type) {
@@ -9596,11 +9611,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
              }
              (yyval.decl).type = (yyvsp[-1].type);
            }
-#line 9600 "y.tab.c" /* yacc.c:1646  */
+#line 9615 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 311:
-#line 5387 "parser.y" /* yacc.c:1646  */
+#line 5402 "parser.y" /* yacc.c:1646  */
     {
               (yyval.decl) = (yyvsp[0].decl);
              SwigType_add_reference((yyvsp[-2].type));
@@ -9610,11 +9625,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
              }
              (yyval.decl).type = (yyvsp[-2].type);
            }
-#line 9614 "y.tab.c" /* yacc.c:1646  */
+#line 9629 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 312:
-#line 5396 "parser.y" /* yacc.c:1646  */
+#line 5411 "parser.y" /* yacc.c:1646  */
     {
               (yyval.decl) = (yyvsp[0].decl);
              SwigType_add_rvalue_reference((yyvsp[-2].type));
@@ -9624,20 +9639,20 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
              }
              (yyval.decl).type = (yyvsp[-2].type);
            }
-#line 9628 "y.tab.c" /* yacc.c:1646  */
+#line 9643 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 313:
-#line 5405 "parser.y" /* yacc.c:1646  */
+#line 5420 "parser.y" /* yacc.c:1646  */
     {
               (yyval.decl) = (yyvsp[0].decl);
              if (!(yyval.decl).type) (yyval.decl).type = NewStringEmpty();
            }
-#line 9637 "y.tab.c" /* yacc.c:1646  */
+#line 9652 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 314:
-#line 5409 "parser.y" /* yacc.c:1646  */
+#line 5424 "parser.y" /* yacc.c:1646  */
     {
             (yyval.decl) = (yyvsp[0].decl);
             (yyval.decl).type = NewStringEmpty();
@@ -9647,11 +9662,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
               Delete((yyvsp[0].decl).type);
             }
            }
-#line 9651 "y.tab.c" /* yacc.c:1646  */
+#line 9666 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 315:
-#line 5418 "parser.y" /* yacc.c:1646  */
+#line 5433 "parser.y" /* yacc.c:1646  */
     {
             /* Introduced in C++11, move operator && */
              /* Adds one S/R conflict */
@@ -9663,11 +9678,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
               Delete((yyvsp[0].decl).type);
             }
            }
-#line 9667 "y.tab.c" /* yacc.c:1646  */
+#line 9682 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 316:
-#line 5429 "parser.y" /* yacc.c:1646  */
+#line 5444 "parser.y" /* yacc.c:1646  */
     { 
             SwigType *t = NewStringEmpty();
 
@@ -9679,11 +9694,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
             }
             (yyval.decl).type = t;
             }
-#line 9683 "y.tab.c" /* yacc.c:1646  */
+#line 9698 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 317:
-#line 5440 "parser.y" /* yacc.c:1646  */
+#line 5455 "parser.y" /* yacc.c:1646  */
     { 
             SwigType *t = NewStringEmpty();
             (yyval.decl) = (yyvsp[0].decl);
@@ -9696,11 +9711,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
             (yyval.decl).type = (yyvsp[-3].type);
             Delete(t);
           }
-#line 9700 "y.tab.c" /* yacc.c:1646  */
+#line 9715 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 318:
-#line 5452 "parser.y" /* yacc.c:1646  */
+#line 5467 "parser.y" /* yacc.c:1646  */
     { 
             (yyval.decl) = (yyvsp[0].decl);
             SwigType_add_memberpointer((yyvsp[-4].type),(yyvsp[-3].str));
@@ -9711,11 +9726,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
             }
             (yyval.decl).type = (yyvsp[-4].type);
           }
-#line 9715 "y.tab.c" /* yacc.c:1646  */
+#line 9730 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 319:
-#line 5462 "parser.y" /* yacc.c:1646  */
+#line 5477 "parser.y" /* yacc.c:1646  */
     { 
             SwigType *t = NewStringEmpty();
             (yyval.decl) = (yyvsp[0].decl);
@@ -9727,11 +9742,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
             } 
             (yyval.decl).type = t;
           }
-#line 9731 "y.tab.c" /* yacc.c:1646  */
+#line 9746 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 320:
-#line 5476 "parser.y" /* yacc.c:1646  */
+#line 5491 "parser.y" /* yacc.c:1646  */
     {
               (yyval.decl) = (yyvsp[0].decl);
              if ((yyval.decl).type) {
@@ -9740,11 +9755,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
              }
              (yyval.decl).type = (yyvsp[-4].type);
            }
-#line 9744 "y.tab.c" /* yacc.c:1646  */
+#line 9759 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 321:
-#line 5484 "parser.y" /* yacc.c:1646  */
+#line 5499 "parser.y" /* yacc.c:1646  */
     {
               (yyval.decl) = (yyvsp[0].decl);
              SwigType_add_reference((yyvsp[-5].type));
@@ -9754,11 +9769,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
              }
              (yyval.decl).type = (yyvsp[-5].type);
            }
-#line 9758 "y.tab.c" /* yacc.c:1646  */
+#line 9773 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 322:
-#line 5493 "parser.y" /* yacc.c:1646  */
+#line 5508 "parser.y" /* yacc.c:1646  */
     {
               (yyval.decl) = (yyvsp[0].decl);
              SwigType_add_rvalue_reference((yyvsp[-5].type));
@@ -9768,20 +9783,20 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
              }
              (yyval.decl).type = (yyvsp[-5].type);
            }
-#line 9772 "y.tab.c" /* yacc.c:1646  */
+#line 9787 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 323:
-#line 5502 "parser.y" /* yacc.c:1646  */
+#line 5517 "parser.y" /* yacc.c:1646  */
     {
               (yyval.decl) = (yyvsp[0].decl);
              if (!(yyval.decl).type) (yyval.decl).type = NewStringEmpty();
            }
-#line 9781 "y.tab.c" /* yacc.c:1646  */
+#line 9796 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 324:
-#line 5506 "parser.y" /* yacc.c:1646  */
+#line 5521 "parser.y" /* yacc.c:1646  */
     {
             (yyval.decl) = (yyvsp[0].decl);
             (yyval.decl).type = NewStringEmpty();
@@ -9791,11 +9806,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
               Delete((yyvsp[0].decl).type);
             }
            }
-#line 9795 "y.tab.c" /* yacc.c:1646  */
+#line 9810 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 325:
-#line 5515 "parser.y" /* yacc.c:1646  */
+#line 5530 "parser.y" /* yacc.c:1646  */
     {
             /* Introduced in C++11, move operator && */
              /* Adds one S/R conflict */
@@ -9807,11 +9822,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
               Delete((yyvsp[0].decl).type);
             }
            }
-#line 9811 "y.tab.c" /* yacc.c:1646  */
+#line 9826 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 326:
-#line 5526 "parser.y" /* yacc.c:1646  */
+#line 5541 "parser.y" /* yacc.c:1646  */
     { 
             SwigType *t = NewStringEmpty();
 
@@ -9823,11 +9838,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
             }
             (yyval.decl).type = t;
             }
-#line 9827 "y.tab.c" /* yacc.c:1646  */
+#line 9842 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 327:
-#line 5537 "parser.y" /* yacc.c:1646  */
+#line 5552 "parser.y" /* yacc.c:1646  */
     { 
             SwigType *t = NewStringEmpty();
             (yyval.decl) = (yyvsp[0].decl);
@@ -9840,11 +9855,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
             (yyval.decl).type = (yyvsp[-6].type);
             Delete(t);
           }
-#line 9844 "y.tab.c" /* yacc.c:1646  */
+#line 9859 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 328:
-#line 5549 "parser.y" /* yacc.c:1646  */
+#line 5564 "parser.y" /* yacc.c:1646  */
     { 
             (yyval.decl) = (yyvsp[0].decl);
             SwigType_add_memberpointer((yyvsp[-7].type),(yyvsp[-6].str));
@@ -9855,11 +9870,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
             }
             (yyval.decl).type = (yyvsp[-7].type);
           }
-#line 9859 "y.tab.c" /* yacc.c:1646  */
+#line 9874 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 329:
-#line 5559 "parser.y" /* yacc.c:1646  */
+#line 5574 "parser.y" /* yacc.c:1646  */
     { 
             (yyval.decl) = (yyvsp[0].decl);
             SwigType_add_memberpointer((yyvsp[-7].type),(yyvsp[-6].str));
@@ -9870,11 +9885,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
             }
             (yyval.decl).type = (yyvsp[-7].type);
           }
-#line 9874 "y.tab.c" /* yacc.c:1646  */
+#line 9889 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 330:
-#line 5569 "parser.y" /* yacc.c:1646  */
+#line 5584 "parser.y" /* yacc.c:1646  */
     { 
             SwigType *t = NewStringEmpty();
             (yyval.decl) = (yyvsp[0].decl);
@@ -9886,11 +9901,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
             } 
             (yyval.decl).type = t;
           }
-#line 9890 "y.tab.c" /* yacc.c:1646  */
+#line 9905 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 331:
-#line 5580 "parser.y" /* yacc.c:1646  */
+#line 5595 "parser.y" /* yacc.c:1646  */
     { 
             SwigType *t = NewStringEmpty();
             (yyval.decl) = (yyvsp[0].decl);
@@ -9902,11 +9917,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
             } 
             (yyval.decl).type = t;
           }
-#line 9906 "y.tab.c" /* yacc.c:1646  */
+#line 9921 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 332:
-#line 5593 "parser.y" /* yacc.c:1646  */
+#line 5608 "parser.y" /* yacc.c:1646  */
     {
                 /* Note: This is non-standard C.  Template declarator is allowed to follow an identifier */
                  (yyval.decl).id = Char((yyvsp[0].str));
@@ -9914,33 +9929,33 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                 (yyval.decl).parms = 0;
                 (yyval.decl).have_parms = 0;
                   }
-#line 9918 "y.tab.c" /* yacc.c:1646  */
+#line 9933 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 333:
-#line 5600 "parser.y" /* yacc.c:1646  */
+#line 5615 "parser.y" /* yacc.c:1646  */
     {
                   (yyval.decl).id = Char(NewStringf("~%s",(yyvsp[0].str)));
                   (yyval.decl).type = 0;
                   (yyval.decl).parms = 0;
                   (yyval.decl).have_parms = 0;
                   }
-#line 9929 "y.tab.c" /* yacc.c:1646  */
+#line 9944 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 334:
-#line 5608 "parser.y" /* yacc.c:1646  */
+#line 5623 "parser.y" /* yacc.c:1646  */
     {
                   (yyval.decl).id = Char((yyvsp[-1].str));
                   (yyval.decl).type = 0;
                   (yyval.decl).parms = 0;
                   (yyval.decl).have_parms = 0;
                   }
-#line 9940 "y.tab.c" /* yacc.c:1646  */
+#line 9955 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 335:
-#line 5624 "parser.y" /* yacc.c:1646  */
+#line 5639 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.decl) = (yyvsp[-1].decl);
                    if ((yyval.decl).type) {
@@ -9949,11 +9964,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    (yyval.decl).type = (yyvsp[-2].type);
                   }
-#line 9953 "y.tab.c" /* yacc.c:1646  */
+#line 9968 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 336:
-#line 5632 "parser.y" /* yacc.c:1646  */
+#line 5647 "parser.y" /* yacc.c:1646  */
     {
                    SwigType *t;
                    (yyval.decl) = (yyvsp[-1].decl);
@@ -9965,11 +9980,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    (yyval.decl).type = t;
                    }
-#line 9969 "y.tab.c" /* yacc.c:1646  */
+#line 9984 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 337:
-#line 5643 "parser.y" /* yacc.c:1646  */
+#line 5658 "parser.y" /* yacc.c:1646  */
     { 
                    SwigType *t;
                    (yyval.decl) = (yyvsp[-2].decl);
@@ -9981,11 +9996,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    (yyval.decl).type = t;
                   }
-#line 9985 "y.tab.c" /* yacc.c:1646  */
+#line 10000 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 338:
-#line 5654 "parser.y" /* yacc.c:1646  */
+#line 5669 "parser.y" /* yacc.c:1646  */
     { 
                    SwigType *t;
                    (yyval.decl) = (yyvsp[-3].decl);
@@ -9997,11 +10012,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    (yyval.decl).type = t;
                   }
-#line 10001 "y.tab.c" /* yacc.c:1646  */
+#line 10016 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 339:
-#line 5665 "parser.y" /* yacc.c:1646  */
+#line 5680 "parser.y" /* yacc.c:1646  */
     {
                    SwigType *t;
                     (yyval.decl) = (yyvsp[-3].decl);
@@ -10019,11 +10034,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                      (yyval.decl).type = t;
                    }
                  }
-#line 10023 "y.tab.c" /* yacc.c:1646  */
+#line 10038 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 340:
-#line 5684 "parser.y" /* yacc.c:1646  */
+#line 5699 "parser.y" /* yacc.c:1646  */
     {
                 /* Note: This is non-standard C.  Template declarator is allowed to follow an identifier */
                  (yyval.decl).id = Char((yyvsp[0].str));
@@ -10031,22 +10046,22 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                 (yyval.decl).parms = 0;
                 (yyval.decl).have_parms = 0;
                   }
-#line 10035 "y.tab.c" /* yacc.c:1646  */
+#line 10050 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 341:
-#line 5692 "parser.y" /* yacc.c:1646  */
+#line 5707 "parser.y" /* yacc.c:1646  */
     {
                   (yyval.decl).id = Char(NewStringf("~%s",(yyvsp[0].str)));
                   (yyval.decl).type = 0;
                   (yyval.decl).parms = 0;
                   (yyval.decl).have_parms = 0;
                   }
-#line 10046 "y.tab.c" /* yacc.c:1646  */
+#line 10061 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 342:
-#line 5709 "parser.y" /* yacc.c:1646  */
+#line 5724 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.decl) = (yyvsp[-1].decl);
                    if ((yyval.decl).type) {
@@ -10055,11 +10070,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    (yyval.decl).type = (yyvsp[-2].type);
                   }
-#line 10059 "y.tab.c" /* yacc.c:1646  */
+#line 10074 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 343:
-#line 5717 "parser.y" /* yacc.c:1646  */
+#line 5732 "parser.y" /* yacc.c:1646  */
     {
                     (yyval.decl) = (yyvsp[-1].decl);
                    if (!(yyval.decl).type) {
@@ -10067,11 +10082,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    SwigType_add_reference((yyval.decl).type);
                   }
-#line 10071 "y.tab.c" /* yacc.c:1646  */
+#line 10086 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 344:
-#line 5724 "parser.y" /* yacc.c:1646  */
+#line 5739 "parser.y" /* yacc.c:1646  */
     {
                     (yyval.decl) = (yyvsp[-1].decl);
                    if (!(yyval.decl).type) {
@@ -10079,11 +10094,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    SwigType_add_rvalue_reference((yyval.decl).type);
                   }
-#line 10083 "y.tab.c" /* yacc.c:1646  */
+#line 10098 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 345:
-#line 5731 "parser.y" /* yacc.c:1646  */
+#line 5746 "parser.y" /* yacc.c:1646  */
     {
                    SwigType *t;
                    (yyval.decl) = (yyvsp[-1].decl);
@@ -10095,11 +10110,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    (yyval.decl).type = t;
                  }
-#line 10099 "y.tab.c" /* yacc.c:1646  */
+#line 10114 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 346:
-#line 5742 "parser.y" /* yacc.c:1646  */
+#line 5757 "parser.y" /* yacc.c:1646  */
     {
                    SwigType *t;
                    (yyval.decl) = (yyvsp[-1].decl);
@@ -10112,11 +10127,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    (yyval.decl).type = t;
                  }
-#line 10116 "y.tab.c" /* yacc.c:1646  */
+#line 10131 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 347:
-#line 5754 "parser.y" /* yacc.c:1646  */
+#line 5769 "parser.y" /* yacc.c:1646  */
     {
                    SwigType *t;
                    (yyval.decl) = (yyvsp[-1].decl);
@@ -10128,11 +10143,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    (yyval.decl).type = t;
                  }
-#line 10132 "y.tab.c" /* yacc.c:1646  */
+#line 10147 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 348:
-#line 5765 "parser.y" /* yacc.c:1646  */
+#line 5780 "parser.y" /* yacc.c:1646  */
     {
                    SwigType *t;
                    (yyval.decl) = (yyvsp[-1].decl);
@@ -10145,11 +10160,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    (yyval.decl).type = t;
                  }
-#line 10149 "y.tab.c" /* yacc.c:1646  */
+#line 10164 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 349:
-#line 5777 "parser.y" /* yacc.c:1646  */
+#line 5792 "parser.y" /* yacc.c:1646  */
     { 
                    SwigType *t;
                    (yyval.decl) = (yyvsp[-2].decl);
@@ -10161,11 +10176,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    (yyval.decl).type = t;
                   }
-#line 10165 "y.tab.c" /* yacc.c:1646  */
+#line 10180 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 350:
-#line 5788 "parser.y" /* yacc.c:1646  */
+#line 5803 "parser.y" /* yacc.c:1646  */
     { 
                    SwigType *t;
                    (yyval.decl) = (yyvsp[-3].decl);
@@ -10177,11 +10192,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    (yyval.decl).type = t;
                   }
-#line 10181 "y.tab.c" /* yacc.c:1646  */
+#line 10196 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 351:
-#line 5799 "parser.y" /* yacc.c:1646  */
+#line 5814 "parser.y" /* yacc.c:1646  */
     {
                    SwigType *t;
                     (yyval.decl) = (yyvsp[-3].decl);
@@ -10199,11 +10214,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                      (yyval.decl).type = t;
                    }
                  }
-#line 10203 "y.tab.c" /* yacc.c:1646  */
+#line 10218 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 352:
-#line 5819 "parser.y" /* yacc.c:1646  */
+#line 5834 "parser.y" /* yacc.c:1646  */
     {
                    SwigType *t;
                     Append((yyvsp[-4].str), " "); /* intervening space is mandatory */
@@ -10223,33 +10238,33 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                      (yyval.decl).type = t;
                    }
                  }
-#line 10227 "y.tab.c" /* yacc.c:1646  */
+#line 10242 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 353:
-#line 5840 "parser.y" /* yacc.c:1646  */
+#line 5855 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.decl).type = (yyvsp[0].type);
                     (yyval.decl).id = 0;
                    (yyval.decl).parms = 0;
                    (yyval.decl).have_parms = 0;
                   }
-#line 10238 "y.tab.c" /* yacc.c:1646  */
+#line 10253 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 354:
-#line 5846 "parser.y" /* yacc.c:1646  */
+#line 5861 "parser.y" /* yacc.c:1646  */
     { 
                      (yyval.decl) = (yyvsp[0].decl);
                      SwigType_push((yyvsp[-1].type),(yyvsp[0].decl).type);
                     (yyval.decl).type = (yyvsp[-1].type);
                     Delete((yyvsp[0].decl).type);
                   }
-#line 10249 "y.tab.c" /* yacc.c:1646  */
+#line 10264 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 355:
-#line 5852 "parser.y" /* yacc.c:1646  */
+#line 5867 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.decl).type = (yyvsp[-1].type);
                    SwigType_add_reference((yyval.decl).type);
@@ -10257,11 +10272,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    (yyval.decl).parms = 0;
                    (yyval.decl).have_parms = 0;
                  }
-#line 10261 "y.tab.c" /* yacc.c:1646  */
+#line 10276 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 356:
-#line 5859 "parser.y" /* yacc.c:1646  */
+#line 5874 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.decl).type = (yyvsp[-1].type);
                    SwigType_add_rvalue_reference((yyval.decl).type);
@@ -10269,11 +10284,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    (yyval.decl).parms = 0;
                    (yyval.decl).have_parms = 0;
                  }
-#line 10273 "y.tab.c" /* yacc.c:1646  */
+#line 10288 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 357:
-#line 5866 "parser.y" /* yacc.c:1646  */
+#line 5881 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.decl) = (yyvsp[0].decl);
                    SwigType_add_reference((yyvsp[-2].type));
@@ -10283,11 +10298,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    (yyval.decl).type = (yyvsp[-2].type);
                   }
-#line 10287 "y.tab.c" /* yacc.c:1646  */
+#line 10302 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 358:
-#line 5875 "parser.y" /* yacc.c:1646  */
+#line 5890 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.decl) = (yyvsp[0].decl);
                    SwigType_add_rvalue_reference((yyvsp[-2].type));
@@ -10297,19 +10312,19 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    (yyval.decl).type = (yyvsp[-2].type);
                   }
-#line 10301 "y.tab.c" /* yacc.c:1646  */
+#line 10316 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 359:
-#line 5884 "parser.y" /* yacc.c:1646  */
+#line 5899 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.decl) = (yyvsp[0].decl);
                   }
-#line 10309 "y.tab.c" /* yacc.c:1646  */
+#line 10324 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 360:
-#line 5887 "parser.y" /* yacc.c:1646  */
+#line 5902 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.decl) = (yyvsp[0].decl);
                    (yyval.decl).type = NewStringEmpty();
@@ -10319,11 +10334,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                      Delete((yyvsp[0].decl).type);
                    }
                   }
-#line 10323 "y.tab.c" /* yacc.c:1646  */
+#line 10338 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 361:
-#line 5896 "parser.y" /* yacc.c:1646  */
+#line 5911 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.decl) = (yyvsp[0].decl);
                    (yyval.decl).type = NewStringEmpty();
@@ -10333,11 +10348,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                      Delete((yyvsp[0].decl).type);
                    }
                   }
-#line 10337 "y.tab.c" /* yacc.c:1646  */
+#line 10352 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 362:
-#line 5905 "parser.y" /* yacc.c:1646  */
+#line 5920 "parser.y" /* yacc.c:1646  */
     {
                     (yyval.decl).id = 0;
                     (yyval.decl).parms = 0;
@@ -10345,11 +10360,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                     (yyval.decl).type = NewStringEmpty();
                    SwigType_add_reference((yyval.decl).type);
                   }
-#line 10349 "y.tab.c" /* yacc.c:1646  */
+#line 10364 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 363:
-#line 5912 "parser.y" /* yacc.c:1646  */
+#line 5927 "parser.y" /* yacc.c:1646  */
     {
                     (yyval.decl).id = 0;
                     (yyval.decl).parms = 0;
@@ -10357,11 +10372,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                     (yyval.decl).type = NewStringEmpty();
                    SwigType_add_rvalue_reference((yyval.decl).type);
                   }
-#line 10361 "y.tab.c" /* yacc.c:1646  */
+#line 10376 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 364:
-#line 5919 "parser.y" /* yacc.c:1646  */
+#line 5934 "parser.y" /* yacc.c:1646  */
     { 
                    (yyval.decl).type = NewStringEmpty();
                     SwigType_add_memberpointer((yyval.decl).type,(yyvsp[-1].str));
@@ -10369,11 +10384,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                     (yyval.decl).parms = 0;
                    (yyval.decl).have_parms = 0;
                  }
-#line 10373 "y.tab.c" /* yacc.c:1646  */
+#line 10388 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 365:
-#line 5926 "parser.y" /* yacc.c:1646  */
+#line 5941 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.decl).type = NewStringEmpty();
                    SwigType_add_memberpointer((yyval.decl).type, (yyvsp[-2].str));
@@ -10382,11 +10397,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    (yyval.decl).parms = 0;
                    (yyval.decl).have_parms = 0;
                  }
-#line 10386 "y.tab.c" /* yacc.c:1646  */
+#line 10401 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 366:
-#line 5934 "parser.y" /* yacc.c:1646  */
+#line 5949 "parser.y" /* yacc.c:1646  */
     { 
                    SwigType *t = NewStringEmpty();
                     (yyval.decl).type = (yyvsp[-2].type);
@@ -10397,11 +10412,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    SwigType_push((yyval.decl).type,t);
                    Delete(t);
                   }
-#line 10401 "y.tab.c" /* yacc.c:1646  */
+#line 10416 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 367:
-#line 5944 "parser.y" /* yacc.c:1646  */
+#line 5959 "parser.y" /* yacc.c:1646  */
     { 
                    (yyval.decl) = (yyvsp[0].decl);
                    SwigType_add_memberpointer((yyvsp[-3].type),(yyvsp[-2].str));
@@ -10411,11 +10426,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    (yyval.decl).type = (yyvsp[-3].type);
                   }
-#line 10415 "y.tab.c" /* yacc.c:1646  */
+#line 10430 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 368:
-#line 5955 "parser.y" /* yacc.c:1646  */
+#line 5970 "parser.y" /* yacc.c:1646  */
     { 
                    SwigType *t;
                    (yyval.decl) = (yyvsp[-2].decl);
@@ -10427,11 +10442,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    (yyval.decl).type = t;
                   }
-#line 10431 "y.tab.c" /* yacc.c:1646  */
+#line 10446 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 369:
-#line 5966 "parser.y" /* yacc.c:1646  */
+#line 5981 "parser.y" /* yacc.c:1646  */
     { 
                    SwigType *t;
                    (yyval.decl) = (yyvsp[-3].decl);
@@ -10443,11 +10458,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    (yyval.decl).type = t;
                   }
-#line 10447 "y.tab.c" /* yacc.c:1646  */
+#line 10462 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 370:
-#line 5977 "parser.y" /* yacc.c:1646  */
+#line 5992 "parser.y" /* yacc.c:1646  */
     { 
                    (yyval.decl).type = NewStringEmpty();
                    (yyval.decl).id = 0;
@@ -10455,11 +10470,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    (yyval.decl).have_parms = 0;
                    SwigType_add_array((yyval.decl).type,"");
                   }
-#line 10459 "y.tab.c" /* yacc.c:1646  */
+#line 10474 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 371:
-#line 5984 "parser.y" /* yacc.c:1646  */
+#line 5999 "parser.y" /* yacc.c:1646  */
     { 
                    (yyval.decl).type = NewStringEmpty();
                    (yyval.decl).id = 0;
@@ -10467,19 +10482,19 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    (yyval.decl).have_parms = 0;
                    SwigType_add_array((yyval.decl).type,(yyvsp[-1].dtype).val);
                  }
-#line 10471 "y.tab.c" /* yacc.c:1646  */
+#line 10486 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 372:
-#line 5991 "parser.y" /* yacc.c:1646  */
+#line 6006 "parser.y" /* yacc.c:1646  */
     {
                     (yyval.decl) = (yyvsp[-1].decl);
                  }
-#line 10479 "y.tab.c" /* yacc.c:1646  */
+#line 10494 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 373:
-#line 5994 "parser.y" /* yacc.c:1646  */
+#line 6009 "parser.y" /* yacc.c:1646  */
     {
                    SwigType *t;
                     (yyval.decl) = (yyvsp[-3].decl);
@@ -10497,11 +10512,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                      (yyval.decl).have_parms = 1;
                    }
                  }
-#line 10501 "y.tab.c" /* yacc.c:1646  */
+#line 10516 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 374:
-#line 6011 "parser.y" /* yacc.c:1646  */
+#line 6026 "parser.y" /* yacc.c:1646  */
     {
                    SwigType *t;
                     (yyval.decl) = (yyvsp[-4].decl);
@@ -10520,11 +10535,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                      (yyval.decl).have_parms = 1;
                    }
                  }
-#line 10524 "y.tab.c" /* yacc.c:1646  */
+#line 10539 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 375:
-#line 6029 "parser.y" /* yacc.c:1646  */
+#line 6044 "parser.y" /* yacc.c:1646  */
     {
                     (yyval.decl).type = NewStringEmpty();
                     SwigType_add_function((yyval.decl).type,(yyvsp[-1].pl));
@@ -10532,11 +10547,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    (yyval.decl).have_parms = 1;
                    (yyval.decl).id = 0;
                   }
-#line 10536 "y.tab.c" /* yacc.c:1646  */
+#line 10551 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 376:
-#line 6039 "parser.y" /* yacc.c:1646  */
+#line 6054 "parser.y" /* yacc.c:1646  */
     { 
              (yyval.type) = NewStringEmpty();
              SwigType_add_pointer((yyval.type));
@@ -10544,223 +10559,223 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
             SwigType_push((yyval.type),(yyvsp[0].type));
             Delete((yyvsp[0].type));
            }
-#line 10548 "y.tab.c" /* yacc.c:1646  */
+#line 10563 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 377:
-#line 6046 "parser.y" /* yacc.c:1646  */
+#line 6061 "parser.y" /* yacc.c:1646  */
     {
             (yyval.type) = NewStringEmpty();
             SwigType_add_pointer((yyval.type));
             SwigType_push((yyval.type),(yyvsp[0].type));
             Delete((yyvsp[0].type));
           }
-#line 10559 "y.tab.c" /* yacc.c:1646  */
+#line 10574 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 378:
-#line 6052 "parser.y" /* yacc.c:1646  */
+#line 6067 "parser.y" /* yacc.c:1646  */
     { 
             (yyval.type) = NewStringEmpty();
             SwigType_add_pointer((yyval.type));
             SwigType_push((yyval.type),(yyvsp[0].str));
            }
-#line 10569 "y.tab.c" /* yacc.c:1646  */
+#line 10584 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 379:
-#line 6057 "parser.y" /* yacc.c:1646  */
+#line 6072 "parser.y" /* yacc.c:1646  */
     {
             (yyval.type) = NewStringEmpty();
             SwigType_add_pointer((yyval.type));
            }
-#line 10578 "y.tab.c" /* yacc.c:1646  */
+#line 10593 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 380:
-#line 6064 "parser.y" /* yacc.c:1646  */
+#line 6079 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype).qualifier = (yyvsp[0].str);
                  (yyval.dtype).refqualifier = 0;
               }
-#line 10587 "y.tab.c" /* yacc.c:1646  */
+#line 10602 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 381:
-#line 6068 "parser.y" /* yacc.c:1646  */
+#line 6083 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype).qualifier = (yyvsp[-1].str);
                  (yyval.dtype).refqualifier = (yyvsp[0].str);
                  SwigType_push((yyval.dtype).qualifier, (yyvsp[0].str));
               }
-#line 10597 "y.tab.c" /* yacc.c:1646  */
+#line 10612 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 382:
-#line 6073 "parser.y" /* yacc.c:1646  */
+#line 6088 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype).qualifier = NewStringEmpty();
                  (yyval.dtype).refqualifier = (yyvsp[0].str);
                  SwigType_push((yyval.dtype).qualifier, (yyvsp[0].str));
               }
-#line 10607 "y.tab.c" /* yacc.c:1646  */
+#line 10622 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 383:
-#line 6080 "parser.y" /* yacc.c:1646  */
+#line 6095 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.str) = NewStringEmpty();
                  SwigType_add_reference((yyval.str));
               }
-#line 10616 "y.tab.c" /* yacc.c:1646  */
+#line 10631 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 384:
-#line 6084 "parser.y" /* yacc.c:1646  */
+#line 6099 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.str) = NewStringEmpty();
                  SwigType_add_rvalue_reference((yyval.str));
               }
-#line 10625 "y.tab.c" /* yacc.c:1646  */
+#line 10640 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 385:
-#line 6090 "parser.y" /* yacc.c:1646  */
+#line 6105 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.str) = NewStringEmpty();
                  if ((yyvsp[0].id)) SwigType_add_qualifier((yyval.str),(yyvsp[0].id));
                }
-#line 10634 "y.tab.c" /* yacc.c:1646  */
+#line 10649 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 386:
-#line 6094 "parser.y" /* yacc.c:1646  */
+#line 6109 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.str) = (yyvsp[0].str);
                  if ((yyvsp[-1].id)) SwigType_add_qualifier((yyval.str),(yyvsp[-1].id));
                }
-#line 10643 "y.tab.c" /* yacc.c:1646  */
+#line 10658 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 387:
-#line 6100 "parser.y" /* yacc.c:1646  */
+#line 6115 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "const"; }
-#line 10649 "y.tab.c" /* yacc.c:1646  */
+#line 10664 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 388:
-#line 6101 "parser.y" /* yacc.c:1646  */
+#line 6116 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = "volatile"; }
-#line 10655 "y.tab.c" /* yacc.c:1646  */
+#line 10670 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 389:
-#line 6102 "parser.y" /* yacc.c:1646  */
+#line 6117 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = 0; }
-#line 10661 "y.tab.c" /* yacc.c:1646  */
+#line 10676 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 390:
-#line 6108 "parser.y" /* yacc.c:1646  */
+#line 6123 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.type) = (yyvsp[0].type);
                    Replace((yyval.type),"typename ","", DOH_REPLACE_ANY);
                 }
-#line 10670 "y.tab.c" /* yacc.c:1646  */
+#line 10685 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 391:
-#line 6114 "parser.y" /* yacc.c:1646  */
+#line 6129 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.type) = (yyvsp[0].type);
                   SwigType_push((yyval.type),(yyvsp[-1].str));
                }
-#line 10679 "y.tab.c" /* yacc.c:1646  */
+#line 10694 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 392:
-#line 6118 "parser.y" /* yacc.c:1646  */
+#line 6133 "parser.y" /* yacc.c:1646  */
     { (yyval.type) = (yyvsp[0].type); }
-#line 10685 "y.tab.c" /* yacc.c:1646  */
+#line 10700 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 393:
-#line 6119 "parser.y" /* yacc.c:1646  */
+#line 6134 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.type) = (yyvsp[-1].type);
                  SwigType_push((yyval.type),(yyvsp[0].str));
               }
-#line 10694 "y.tab.c" /* yacc.c:1646  */
+#line 10709 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 394:
-#line 6123 "parser.y" /* yacc.c:1646  */
+#line 6138 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.type) = (yyvsp[-1].type);
                  SwigType_push((yyval.type),(yyvsp[0].str));
                  SwigType_push((yyval.type),(yyvsp[-2].str));
               }
-#line 10704 "y.tab.c" /* yacc.c:1646  */
+#line 10719 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 395:
-#line 6130 "parser.y" /* yacc.c:1646  */
+#line 6145 "parser.y" /* yacc.c:1646  */
     { (yyval.type) = (yyvsp[0].type);
                   /* Printf(stdout,"primitive = '%s'\n", $$);*/
                }
-#line 10712 "y.tab.c" /* yacc.c:1646  */
+#line 10727 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 396:
-#line 6133 "parser.y" /* yacc.c:1646  */
+#line 6148 "parser.y" /* yacc.c:1646  */
     { (yyval.type) = (yyvsp[0].type); }
-#line 10718 "y.tab.c" /* yacc.c:1646  */
+#line 10733 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 397:
-#line 6134 "parser.y" /* yacc.c:1646  */
+#line 6149 "parser.y" /* yacc.c:1646  */
     { (yyval.type) = (yyvsp[0].type); }
-#line 10724 "y.tab.c" /* yacc.c:1646  */
+#line 10739 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 398:
-#line 6138 "parser.y" /* yacc.c:1646  */
+#line 6153 "parser.y" /* yacc.c:1646  */
     { (yyval.type) = NewStringf("enum %s", (yyvsp[0].str)); }
-#line 10730 "y.tab.c" /* yacc.c:1646  */
+#line 10745 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 399:
-#line 6139 "parser.y" /* yacc.c:1646  */
+#line 6154 "parser.y" /* yacc.c:1646  */
     { (yyval.type) = (yyvsp[0].type); }
-#line 10736 "y.tab.c" /* yacc.c:1646  */
+#line 10751 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 400:
-#line 6141 "parser.y" /* yacc.c:1646  */
+#line 6156 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.type) = (yyvsp[0].str);
                }
-#line 10744 "y.tab.c" /* yacc.c:1646  */
+#line 10759 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 401:
-#line 6144 "parser.y" /* yacc.c:1646  */
+#line 6159 "parser.y" /* yacc.c:1646  */
     { 
                 (yyval.type) = NewStringf("%s %s", (yyvsp[-1].id), (yyvsp[0].str));
                }
-#line 10752 "y.tab.c" /* yacc.c:1646  */
+#line 10767 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 402:
-#line 6147 "parser.y" /* yacc.c:1646  */
+#line 6162 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.type) = (yyvsp[0].type);
                }
-#line 10760 "y.tab.c" /* yacc.c:1646  */
+#line 10775 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 403:
-#line 6152 "parser.y" /* yacc.c:1646  */
+#line 6167 "parser.y" /* yacc.c:1646  */
     {
                  Node *n = Swig_symbol_clookup((yyvsp[-1].str),0);
                  if (!n) {
@@ -10770,11 +10785,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    (yyval.type) = Getattr(n, "type");
                  }
                }
-#line 10774 "y.tab.c" /* yacc.c:1646  */
+#line 10789 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 404:
-#line 6163 "parser.y" /* yacc.c:1646  */
+#line 6178 "parser.y" /* yacc.c:1646  */
     {
                 if (!(yyvsp[0].ptype).type) (yyvsp[0].ptype).type = NewString("int");
                 if ((yyvsp[0].ptype).us) {
@@ -10798,19 +10813,19 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                   (yyval.type) = NewString("long long");
                 }
                }
-#line 10802 "y.tab.c" /* yacc.c:1646  */
+#line 10817 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 405:
-#line 6188 "parser.y" /* yacc.c:1646  */
+#line 6203 "parser.y" /* yacc.c:1646  */
     { 
                  (yyval.ptype) = (yyvsp[0].ptype);
                }
-#line 10810 "y.tab.c" /* yacc.c:1646  */
+#line 10825 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 406:
-#line 6191 "parser.y" /* yacc.c:1646  */
+#line 6206 "parser.y" /* yacc.c:1646  */
     {
                     if ((yyvsp[-1].ptype).us && (yyvsp[0].ptype).us) {
                      Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", (yyvsp[0].ptype).us);
@@ -10862,143 +10877,143 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                      }
                    }
                }
-#line 10866 "y.tab.c" /* yacc.c:1646  */
+#line 10881 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 407:
-#line 6245 "parser.y" /* yacc.c:1646  */
+#line 6260 "parser.y" /* yacc.c:1646  */
     { 
                    (yyval.ptype).type = NewString("int");
                     (yyval.ptype).us = 0;
                }
-#line 10875 "y.tab.c" /* yacc.c:1646  */
+#line 10890 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 408:
-#line 6249 "parser.y" /* yacc.c:1646  */
+#line 6264 "parser.y" /* yacc.c:1646  */
     { 
                     (yyval.ptype).type = NewString("short");
                     (yyval.ptype).us = 0;
                 }
-#line 10884 "y.tab.c" /* yacc.c:1646  */
+#line 10899 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 409:
-#line 6253 "parser.y" /* yacc.c:1646  */
+#line 6268 "parser.y" /* yacc.c:1646  */
     { 
                     (yyval.ptype).type = NewString("long");
                     (yyval.ptype).us = 0;
                 }
-#line 10893 "y.tab.c" /* yacc.c:1646  */
+#line 10908 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 410:
-#line 6257 "parser.y" /* yacc.c:1646  */
+#line 6272 "parser.y" /* yacc.c:1646  */
     { 
                     (yyval.ptype).type = NewString("char");
                     (yyval.ptype).us = 0;
                 }
-#line 10902 "y.tab.c" /* yacc.c:1646  */
+#line 10917 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 411:
-#line 6261 "parser.y" /* yacc.c:1646  */
+#line 6276 "parser.y" /* yacc.c:1646  */
     { 
                     (yyval.ptype).type = NewString("wchar_t");
                     (yyval.ptype).us = 0;
                 }
-#line 10911 "y.tab.c" /* yacc.c:1646  */
+#line 10926 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 412:
-#line 6265 "parser.y" /* yacc.c:1646  */
+#line 6280 "parser.y" /* yacc.c:1646  */
     { 
                     (yyval.ptype).type = NewString("float");
                     (yyval.ptype).us = 0;
                 }
-#line 10920 "y.tab.c" /* yacc.c:1646  */
+#line 10935 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 413:
-#line 6269 "parser.y" /* yacc.c:1646  */
+#line 6284 "parser.y" /* yacc.c:1646  */
     { 
                     (yyval.ptype).type = NewString("double");
                     (yyval.ptype).us = 0;
                 }
-#line 10929 "y.tab.c" /* yacc.c:1646  */
+#line 10944 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 414:
-#line 6273 "parser.y" /* yacc.c:1646  */
+#line 6288 "parser.y" /* yacc.c:1646  */
     { 
                     (yyval.ptype).us = NewString("signed");
                     (yyval.ptype).type = 0;
                 }
-#line 10938 "y.tab.c" /* yacc.c:1646  */
+#line 10953 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 415:
-#line 6277 "parser.y" /* yacc.c:1646  */
+#line 6292 "parser.y" /* yacc.c:1646  */
     { 
                     (yyval.ptype).us = NewString("unsigned");
                     (yyval.ptype).type = 0;
                 }
-#line 10947 "y.tab.c" /* yacc.c:1646  */
+#line 10962 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 416:
-#line 6281 "parser.y" /* yacc.c:1646  */
+#line 6296 "parser.y" /* yacc.c:1646  */
     { 
                     (yyval.ptype).type = NewString("complex");
                     (yyval.ptype).us = 0;
                 }
-#line 10956 "y.tab.c" /* yacc.c:1646  */
+#line 10971 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 417:
-#line 6285 "parser.y" /* yacc.c:1646  */
+#line 6300 "parser.y" /* yacc.c:1646  */
     { 
                     (yyval.ptype).type = NewString("__int8");
                     (yyval.ptype).us = 0;
                 }
-#line 10965 "y.tab.c" /* yacc.c:1646  */
+#line 10980 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 418:
-#line 6289 "parser.y" /* yacc.c:1646  */
+#line 6304 "parser.y" /* yacc.c:1646  */
     { 
                     (yyval.ptype).type = NewString("__int16");
                     (yyval.ptype).us = 0;
                 }
-#line 10974 "y.tab.c" /* yacc.c:1646  */
+#line 10989 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 419:
-#line 6293 "parser.y" /* yacc.c:1646  */
+#line 6308 "parser.y" /* yacc.c:1646  */
     { 
                     (yyval.ptype).type = NewString("__int32");
                     (yyval.ptype).us = 0;
                 }
-#line 10983 "y.tab.c" /* yacc.c:1646  */
+#line 10998 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 420:
-#line 6297 "parser.y" /* yacc.c:1646  */
+#line 6312 "parser.y" /* yacc.c:1646  */
     { 
                     (yyval.ptype).type = NewString("__int64");
                     (yyval.ptype).us = 0;
                 }
-#line 10992 "y.tab.c" /* yacc.c:1646  */
+#line 11007 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 421:
-#line 6303 "parser.y" /* yacc.c:1646  */
+#line 6318 "parser.y" /* yacc.c:1646  */
     { /* scanner_check_typedef(); */ }
-#line 10998 "y.tab.c" /* yacc.c:1646  */
+#line 11013 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 422:
-#line 6303 "parser.y" /* yacc.c:1646  */
+#line 6318 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.dtype) = (yyvsp[0].dtype);
                   if ((yyval.dtype).type == T_STRING) {
@@ -11015,35 +11030,35 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                   (yyval.dtype).final = 0;
                   scanner_ignore_typedef();
                 }
-#line 11019 "y.tab.c" /* yacc.c:1646  */
+#line 11034 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 423:
-#line 6319 "parser.y" /* yacc.c:1646  */
+#line 6334 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype) = (yyvsp[0].dtype);
                }
-#line 11027 "y.tab.c" /* yacc.c:1646  */
+#line 11042 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 424:
-#line 6324 "parser.y" /* yacc.c:1646  */
+#line 6339 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype) = (yyvsp[0].dtype);
                }
-#line 11035 "y.tab.c" /* yacc.c:1646  */
+#line 11050 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 425:
-#line 6327 "parser.y" /* yacc.c:1646  */
+#line 6342 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype) = (yyvsp[0].dtype);
                }
-#line 11043 "y.tab.c" /* yacc.c:1646  */
+#line 11058 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 426:
-#line 6333 "parser.y" /* yacc.c:1646  */
+#line 6348 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype).val = NewString("delete");
                  (yyval.dtype).rawval = 0;
@@ -11056,11 +11071,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                  (yyval.dtype).nexcept = 0;
                  (yyval.dtype).final = 0;
                }
-#line 11060 "y.tab.c" /* yacc.c:1646  */
+#line 11075 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 427:
-#line 6348 "parser.y" /* yacc.c:1646  */
+#line 6363 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype).val = NewString("default");
                  (yyval.dtype).rawval = 0;
@@ -11073,42 +11088,42 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                  (yyval.dtype).nexcept = 0;
                  (yyval.dtype).final = 0;
                }
-#line 11077 "y.tab.c" /* yacc.c:1646  */
+#line 11092 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 428:
-#line 6364 "parser.y" /* yacc.c:1646  */
+#line 6379 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = (yyvsp[0].id); }
-#line 11083 "y.tab.c" /* yacc.c:1646  */
+#line 11098 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 429:
-#line 6365 "parser.y" /* yacc.c:1646  */
+#line 6380 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = (char *) 0;}
-#line 11089 "y.tab.c" /* yacc.c:1646  */
+#line 11104 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 434:
-#line 6384 "parser.y" /* yacc.c:1646  */
+#line 6399 "parser.y" /* yacc.c:1646  */
     {
                  Setattr((yyvsp[0].node),"_last",(yyvsp[0].node));
                  (yyval.node) = (yyvsp[0].node);
                }
-#line 11098 "y.tab.c" /* yacc.c:1646  */
+#line 11113 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 435:
-#line 6388 "parser.y" /* yacc.c:1646  */
+#line 6403 "parser.y" /* yacc.c:1646  */
     {
                  Setattr((yyvsp[-1].node),"_last",(yyvsp[-1].node));
                  set_comment((yyvsp[-1].node), (yyvsp[0].str));
                  (yyval.node) = (yyvsp[-1].node);
                }
-#line 11108 "y.tab.c" /* yacc.c:1646  */
+#line 11123 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 436:
-#line 6393 "parser.y" /* yacc.c:1646  */
+#line 6408 "parser.y" /* yacc.c:1646  */
     {
                  if ((yyvsp[0].node)) {
                    set_nextSibling((yyvsp[-2].node), (yyvsp[0].node));
@@ -11119,11 +11134,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                  }
                  (yyval.node) = (yyvsp[-2].node);
                }
-#line 11123 "y.tab.c" /* yacc.c:1646  */
+#line 11138 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 437:
-#line 6403 "parser.y" /* yacc.c:1646  */
+#line 6418 "parser.y" /* yacc.c:1646  */
     {
                  if ((yyvsp[0].node)) {
                    set_nextSibling((yyvsp[-3].node), (yyvsp[0].node));
@@ -11135,44 +11150,44 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                  set_comment((yyvsp[-3].node), (yyvsp[-1].str));
                  (yyval.node) = (yyvsp[-3].node);
                }
-#line 11139 "y.tab.c" /* yacc.c:1646  */
+#line 11154 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 438:
-#line 6414 "parser.y" /* yacc.c:1646  */
+#line 6429 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.node) = 0;
                }
-#line 11147 "y.tab.c" /* yacc.c:1646  */
+#line 11162 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 439:
-#line 6419 "parser.y" /* yacc.c:1646  */
+#line 6434 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.node) = (yyvsp[-1].node);
                }
-#line 11155 "y.tab.c" /* yacc.c:1646  */
+#line 11170 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 440:
-#line 6424 "parser.y" /* yacc.c:1646  */
+#line 6439 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.node) = (yyvsp[0].node);
                }
-#line 11163 "y.tab.c" /* yacc.c:1646  */
+#line 11178 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 441:
-#line 6427 "parser.y" /* yacc.c:1646  */
+#line 6442 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.node) = (yyvsp[0].node);
                  set_comment((yyvsp[0].node), (yyvsp[-1].str));
                }
-#line 11172 "y.tab.c" /* yacc.c:1646  */
+#line 11187 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 442:
-#line 6433 "parser.y" /* yacc.c:1646  */
+#line 6448 "parser.y" /* yacc.c:1646  */
     {
                   SwigType *type = NewSwigType(T_INT);
                   (yyval.node) = new_node("enumitem");
@@ -11181,11 +11196,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                   SetFlag((yyval.node),"feature:immutable");
                   Delete(type);
                 }
-#line 11185 "y.tab.c" /* yacc.c:1646  */
+#line 11200 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 443:
-#line 6441 "parser.y" /* yacc.c:1646  */
+#line 6456 "parser.y" /* yacc.c:1646  */
     {
                   SwigType *type = NewSwigType((yyvsp[0].dtype).type == T_BOOL ? T_BOOL : ((yyvsp[0].dtype).type == T_CHAR ? T_CHAR : T_INT));
                   (yyval.node) = new_node("enumitem");
@@ -11196,11 +11211,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                   Setattr((yyval.node),"value",(yyvsp[-2].id));
                   Delete(type);
                  }
-#line 11200 "y.tab.c" /* yacc.c:1646  */
+#line 11215 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 444:
-#line 6453 "parser.y" /* yacc.c:1646  */
+#line 6468 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.dtype) = (yyvsp[0].dtype);
                   if (((yyval.dtype).type != T_INT) && ((yyval.dtype).type != T_UINT) &&
@@ -11212,17 +11227,17 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                     Swig_error(cparse_file,cparse_line,"Type error. Expecting an integral type\n");
                   }
                 }
-#line 11216 "y.tab.c" /* yacc.c:1646  */
+#line 11231 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 445:
-#line 6468 "parser.y" /* yacc.c:1646  */
+#line 6483 "parser.y" /* yacc.c:1646  */
     { (yyval.dtype) = (yyvsp[0].dtype); }
-#line 11222 "y.tab.c" /* yacc.c:1646  */
+#line 11237 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 446:
-#line 6469 "parser.y" /* yacc.c:1646  */
+#line 6484 "parser.y" /* yacc.c:1646  */
     {
                 Node *n;
                 (yyval.dtype).val = (yyvsp[0].type);
@@ -11240,99 +11255,99 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                 }
                }
-#line 11244 "y.tab.c" /* yacc.c:1646  */
+#line 11259 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 447:
-#line 6489 "parser.y" /* yacc.c:1646  */
+#line 6504 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("%s->%s", (yyvsp[-2].id), (yyvsp[0].id));
                 (yyval.dtype).type = 0;
               }
-#line 11253 "y.tab.c" /* yacc.c:1646  */
+#line 11268 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 448:
-#line 6493 "parser.y" /* yacc.c:1646  */
+#line 6508 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype) = (yyvsp[-2].dtype);
                 Printf((yyval.dtype).val, "->%s", (yyvsp[0].id));
               }
-#line 11262 "y.tab.c" /* yacc.c:1646  */
+#line 11277 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 449:
-#line 6503 "parser.y" /* yacc.c:1646  */
+#line 6518 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype) = (yyvsp[-2].dtype);
                 Printf((yyval.dtype).val, ".%s", (yyvsp[0].id));
               }
-#line 11271 "y.tab.c" /* yacc.c:1646  */
+#line 11286 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 450:
-#line 6509 "parser.y" /* yacc.c:1646  */
+#line 6524 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.dtype) = (yyvsp[0].dtype);
                }
-#line 11279 "y.tab.c" /* yacc.c:1646  */
+#line 11294 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 451:
-#line 6512 "parser.y" /* yacc.c:1646  */
+#line 6527 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.dtype) = (yyvsp[0].dtype);
                }
-#line 11287 "y.tab.c" /* yacc.c:1646  */
+#line 11302 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 452:
-#line 6515 "parser.y" /* yacc.c:1646  */
+#line 6530 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.dtype).val = (yyvsp[0].str);
                     (yyval.dtype).type = T_STRING;
                }
-#line 11296 "y.tab.c" /* yacc.c:1646  */
+#line 11311 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 453:
-#line 6519 "parser.y" /* yacc.c:1646  */
+#line 6534 "parser.y" /* yacc.c:1646  */
     {
                  SwigType_push((yyvsp[-2].type),(yyvsp[-1].decl).type);
                  (yyval.dtype).val = NewStringf("sizeof(%s)",SwigType_str((yyvsp[-2].type),0));
                  (yyval.dtype).type = T_ULONG;
                }
-#line 11306 "y.tab.c" /* yacc.c:1646  */
+#line 11321 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 454:
-#line 6524 "parser.y" /* yacc.c:1646  */
+#line 6539 "parser.y" /* yacc.c:1646  */
     {
                  SwigType_push((yyvsp[-2].type),(yyvsp[-1].decl).type);
                  (yyval.dtype).val = NewStringf("sizeof...(%s)",SwigType_str((yyvsp[-2].type),0));
                  (yyval.dtype).type = T_ULONG;
                }
-#line 11316 "y.tab.c" /* yacc.c:1646  */
+#line 11331 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 455:
-#line 6529 "parser.y" /* yacc.c:1646  */
+#line 6544 "parser.y" /* yacc.c:1646  */
     { (yyval.dtype) = (yyvsp[0].dtype); }
-#line 11322 "y.tab.c" /* yacc.c:1646  */
+#line 11337 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 456:
-#line 6530 "parser.y" /* yacc.c:1646  */
+#line 6545 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.dtype).val = (yyvsp[0].str);
                    (yyval.dtype).rawval = NewStringf("L\"%s\"", (yyval.dtype).val);
                     (yyval.dtype).type = T_WSTRING;
               }
-#line 11332 "y.tab.c" /* yacc.c:1646  */
+#line 11347 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 457:
-#line 6535 "parser.y" /* yacc.c:1646  */
+#line 6550 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype).val = NewString((yyvsp[0].str));
                  if (Len((yyval.dtype).val)) {
@@ -11347,11 +11362,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                  (yyval.dtype).nexcept = 0;
                  (yyval.dtype).final = 0;
               }
-#line 11351 "y.tab.c" /* yacc.c:1646  */
+#line 11366 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 458:
-#line 6549 "parser.y" /* yacc.c:1646  */
+#line 6564 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype).val = NewString((yyvsp[0].str));
                  if (Len((yyval.dtype).val)) {
@@ -11366,11 +11381,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                  (yyval.dtype).nexcept = 0;
                  (yyval.dtype).final = 0;
               }
-#line 11370 "y.tab.c" /* yacc.c:1646  */
+#line 11385 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 459:
-#line 6565 "parser.y" /* yacc.c:1646  */
+#line 6580 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.dtype).val = NewStringf("(%s)",(yyvsp[-1].dtype).val);
                    if ((yyvsp[-1].dtype).rawval) {
@@ -11378,11 +11393,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    }
                    (yyval.dtype).type = (yyvsp[-1].dtype).type;
               }
-#line 11382 "y.tab.c" /* yacc.c:1646  */
+#line 11397 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 460:
-#line 6575 "parser.y" /* yacc.c:1646  */
+#line 6590 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype) = (yyvsp[0].dtype);
                 if ((yyvsp[0].dtype).type != T_STRING) {
@@ -11401,11 +11416,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                 }
                 (yyval.dtype).type = promote((yyvsp[-2].dtype).type, (yyvsp[0].dtype).type);
               }
-#line 11405 "y.tab.c" /* yacc.c:1646  */
+#line 11420 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 461:
-#line 6593 "parser.y" /* yacc.c:1646  */
+#line 6608 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype) = (yyvsp[0].dtype);
                 if ((yyvsp[0].dtype).type != T_STRING) {
@@ -11413,11 +11428,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                   (yyval.dtype).val = NewStringf("(%s) %s", SwigType_str((yyvsp[-3].dtype).val,0), (yyvsp[0].dtype).val);
                 }
               }
-#line 11417 "y.tab.c" /* yacc.c:1646  */
+#line 11432 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 462:
-#line 6600 "parser.y" /* yacc.c:1646  */
+#line 6615 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype) = (yyvsp[0].dtype);
                 if ((yyvsp[0].dtype).type != T_STRING) {
@@ -11425,11 +11440,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                   (yyval.dtype).val = NewStringf("(%s) %s", SwigType_str((yyvsp[-3].dtype).val,0), (yyvsp[0].dtype).val);
                 }
               }
-#line 11429 "y.tab.c" /* yacc.c:1646  */
+#line 11444 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 463:
-#line 6607 "parser.y" /* yacc.c:1646  */
+#line 6622 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype) = (yyvsp[0].dtype);
                 if ((yyvsp[0].dtype).type != T_STRING) {
@@ -11437,11 +11452,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                   (yyval.dtype).val = NewStringf("(%s) %s", SwigType_str((yyvsp[-3].dtype).val,0), (yyvsp[0].dtype).val);
                 }
               }
-#line 11441 "y.tab.c" /* yacc.c:1646  */
+#line 11456 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 464:
-#line 6614 "parser.y" /* yacc.c:1646  */
+#line 6629 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype) = (yyvsp[0].dtype);
                 if ((yyvsp[0].dtype).type != T_STRING) {
@@ -11450,11 +11465,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                   (yyval.dtype).val = NewStringf("(%s) %s", SwigType_str((yyvsp[-4].dtype).val,0), (yyvsp[0].dtype).val);
                 }
               }
-#line 11454 "y.tab.c" /* yacc.c:1646  */
+#line 11469 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 465:
-#line 6622 "parser.y" /* yacc.c:1646  */
+#line 6637 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype) = (yyvsp[0].dtype);
                 if ((yyvsp[0].dtype).type != T_STRING) {
@@ -11463,277 +11478,277 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                   (yyval.dtype).val = NewStringf("(%s) %s", SwigType_str((yyvsp[-4].dtype).val,0), (yyvsp[0].dtype).val);
                 }
               }
-#line 11467 "y.tab.c" /* yacc.c:1646  */
+#line 11482 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 466:
-#line 6630 "parser.y" /* yacc.c:1646  */
+#line 6645 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype) = (yyvsp[0].dtype);
                  (yyval.dtype).val = NewStringf("&%s",(yyvsp[0].dtype).val);
               }
-#line 11476 "y.tab.c" /* yacc.c:1646  */
+#line 11491 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 467:
-#line 6634 "parser.y" /* yacc.c:1646  */
+#line 6649 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype) = (yyvsp[0].dtype);
                  (yyval.dtype).val = NewStringf("&&%s",(yyvsp[0].dtype).val);
               }
-#line 11485 "y.tab.c" /* yacc.c:1646  */
+#line 11500 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 468:
-#line 6638 "parser.y" /* yacc.c:1646  */
+#line 6653 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype) = (yyvsp[0].dtype);
                  (yyval.dtype).val = NewStringf("*%s",(yyvsp[0].dtype).val);
               }
-#line 11494 "y.tab.c" /* yacc.c:1646  */
+#line 11509 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 469:
-#line 6644 "parser.y" /* yacc.c:1646  */
+#line 6659 "parser.y" /* yacc.c:1646  */
     { (yyval.dtype) = (yyvsp[0].dtype); }
-#line 11500 "y.tab.c" /* yacc.c:1646  */
+#line 11515 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 470:
-#line 6645 "parser.y" /* yacc.c:1646  */
+#line 6660 "parser.y" /* yacc.c:1646  */
     { (yyval.dtype) = (yyvsp[0].dtype); }
-#line 11506 "y.tab.c" /* yacc.c:1646  */
+#line 11521 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 471:
-#line 6646 "parser.y" /* yacc.c:1646  */
+#line 6661 "parser.y" /* yacc.c:1646  */
     { (yyval.dtype) = (yyvsp[0].dtype); }
-#line 11512 "y.tab.c" /* yacc.c:1646  */
+#line 11527 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 472:
-#line 6647 "parser.y" /* yacc.c:1646  */
+#line 6662 "parser.y" /* yacc.c:1646  */
     { (yyval.dtype) = (yyvsp[0].dtype); }
-#line 11518 "y.tab.c" /* yacc.c:1646  */
+#line 11533 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 473:
-#line 6648 "parser.y" /* yacc.c:1646  */
+#line 6663 "parser.y" /* yacc.c:1646  */
     { (yyval.dtype) = (yyvsp[0].dtype); }
-#line 11524 "y.tab.c" /* yacc.c:1646  */
+#line 11539 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 474:
-#line 6649 "parser.y" /* yacc.c:1646  */
+#line 6664 "parser.y" /* yacc.c:1646  */
     { (yyval.dtype) = (yyvsp[0].dtype); }
-#line 11530 "y.tab.c" /* yacc.c:1646  */
+#line 11545 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 475:
-#line 6650 "parser.y" /* yacc.c:1646  */
+#line 6665 "parser.y" /* yacc.c:1646  */
     { (yyval.dtype) = (yyvsp[0].dtype); }
-#line 11536 "y.tab.c" /* yacc.c:1646  */
+#line 11551 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 476:
-#line 6651 "parser.y" /* yacc.c:1646  */
+#line 6666 "parser.y" /* yacc.c:1646  */
     { (yyval.dtype) = (yyvsp[0].dtype); }
-#line 11542 "y.tab.c" /* yacc.c:1646  */
+#line 11557 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 477:
-#line 6654 "parser.y" /* yacc.c:1646  */
+#line 6669 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("%s+%s", COMPOUND_EXPR_VAL((yyvsp[-2].dtype)),COMPOUND_EXPR_VAL((yyvsp[0].dtype)));
                 (yyval.dtype).type = promote((yyvsp[-2].dtype).type,(yyvsp[0].dtype).type);
               }
-#line 11551 "y.tab.c" /* yacc.c:1646  */
+#line 11566 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 478:
-#line 6658 "parser.y" /* yacc.c:1646  */
+#line 6673 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("%s-%s",COMPOUND_EXPR_VAL((yyvsp[-2].dtype)),COMPOUND_EXPR_VAL((yyvsp[0].dtype)));
                 (yyval.dtype).type = promote((yyvsp[-2].dtype).type,(yyvsp[0].dtype).type);
               }
-#line 11560 "y.tab.c" /* yacc.c:1646  */
+#line 11575 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 479:
-#line 6662 "parser.y" /* yacc.c:1646  */
+#line 6677 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("%s*%s",COMPOUND_EXPR_VAL((yyvsp[-2].dtype)),COMPOUND_EXPR_VAL((yyvsp[0].dtype)));
                 (yyval.dtype).type = promote((yyvsp[-2].dtype).type,(yyvsp[0].dtype).type);
               }
-#line 11569 "y.tab.c" /* yacc.c:1646  */
+#line 11584 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 480:
-#line 6666 "parser.y" /* yacc.c:1646  */
+#line 6681 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("%s/%s",COMPOUND_EXPR_VAL((yyvsp[-2].dtype)),COMPOUND_EXPR_VAL((yyvsp[0].dtype)));
                 (yyval.dtype).type = promote((yyvsp[-2].dtype).type,(yyvsp[0].dtype).type);
               }
-#line 11578 "y.tab.c" /* yacc.c:1646  */
+#line 11593 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 481:
-#line 6670 "parser.y" /* yacc.c:1646  */
+#line 6685 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("%s%%%s",COMPOUND_EXPR_VAL((yyvsp[-2].dtype)),COMPOUND_EXPR_VAL((yyvsp[0].dtype)));
                 (yyval.dtype).type = promote((yyvsp[-2].dtype).type,(yyvsp[0].dtype).type);
               }
-#line 11587 "y.tab.c" /* yacc.c:1646  */
+#line 11602 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 482:
-#line 6674 "parser.y" /* yacc.c:1646  */
+#line 6689 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("%s&%s",COMPOUND_EXPR_VAL((yyvsp[-2].dtype)),COMPOUND_EXPR_VAL((yyvsp[0].dtype)));
                 (yyval.dtype).type = promote((yyvsp[-2].dtype).type,(yyvsp[0].dtype).type);
               }
-#line 11596 "y.tab.c" /* yacc.c:1646  */
+#line 11611 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 483:
-#line 6678 "parser.y" /* yacc.c:1646  */
+#line 6693 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("%s|%s",COMPOUND_EXPR_VAL((yyvsp[-2].dtype)),COMPOUND_EXPR_VAL((yyvsp[0].dtype)));
                 (yyval.dtype).type = promote((yyvsp[-2].dtype).type,(yyvsp[0].dtype).type);
               }
-#line 11605 "y.tab.c" /* yacc.c:1646  */
+#line 11620 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 484:
-#line 6682 "parser.y" /* yacc.c:1646  */
+#line 6697 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("%s^%s",COMPOUND_EXPR_VAL((yyvsp[-2].dtype)),COMPOUND_EXPR_VAL((yyvsp[0].dtype)));
                 (yyval.dtype).type = promote((yyvsp[-2].dtype).type,(yyvsp[0].dtype).type);
               }
-#line 11614 "y.tab.c" /* yacc.c:1646  */
+#line 11629 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 485:
-#line 6686 "parser.y" /* yacc.c:1646  */
+#line 6701 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("%s << %s",COMPOUND_EXPR_VAL((yyvsp[-2].dtype)),COMPOUND_EXPR_VAL((yyvsp[0].dtype)));
                 (yyval.dtype).type = promote_type((yyvsp[-2].dtype).type);
               }
-#line 11623 "y.tab.c" /* yacc.c:1646  */
+#line 11638 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 486:
-#line 6690 "parser.y" /* yacc.c:1646  */
+#line 6705 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("%s >> %s",COMPOUND_EXPR_VAL((yyvsp[-2].dtype)),COMPOUND_EXPR_VAL((yyvsp[0].dtype)));
                 (yyval.dtype).type = promote_type((yyvsp[-2].dtype).type);
               }
-#line 11632 "y.tab.c" /* yacc.c:1646  */
+#line 11647 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 487:
-#line 6694 "parser.y" /* yacc.c:1646  */
+#line 6709 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("%s&&%s",COMPOUND_EXPR_VAL((yyvsp[-2].dtype)),COMPOUND_EXPR_VAL((yyvsp[0].dtype)));
                 (yyval.dtype).type = cparse_cplusplus ? T_BOOL : T_INT;
               }
-#line 11641 "y.tab.c" /* yacc.c:1646  */
+#line 11656 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 488:
-#line 6698 "parser.y" /* yacc.c:1646  */
+#line 6713 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("%s||%s",COMPOUND_EXPR_VAL((yyvsp[-2].dtype)),COMPOUND_EXPR_VAL((yyvsp[0].dtype)));
                 (yyval.dtype).type = cparse_cplusplus ? T_BOOL : T_INT;
               }
-#line 11650 "y.tab.c" /* yacc.c:1646  */
+#line 11665 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 489:
-#line 6702 "parser.y" /* yacc.c:1646  */
+#line 6717 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("%s==%s",COMPOUND_EXPR_VAL((yyvsp[-2].dtype)),COMPOUND_EXPR_VAL((yyvsp[0].dtype)));
                 (yyval.dtype).type = cparse_cplusplus ? T_BOOL : T_INT;
               }
-#line 11659 "y.tab.c" /* yacc.c:1646  */
+#line 11674 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 490:
-#line 6706 "parser.y" /* yacc.c:1646  */
+#line 6721 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("%s!=%s",COMPOUND_EXPR_VAL((yyvsp[-2].dtype)),COMPOUND_EXPR_VAL((yyvsp[0].dtype)));
                 (yyval.dtype).type = cparse_cplusplus ? T_BOOL : T_INT;
               }
-#line 11668 "y.tab.c" /* yacc.c:1646  */
+#line 11683 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 491:
-#line 6720 "parser.y" /* yacc.c:1646  */
+#line 6735 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("%s >= %s", COMPOUND_EXPR_VAL((yyvsp[-2].dtype)), COMPOUND_EXPR_VAL((yyvsp[0].dtype)));
                 (yyval.dtype).type = cparse_cplusplus ? T_BOOL : T_INT;
               }
-#line 11677 "y.tab.c" /* yacc.c:1646  */
+#line 11692 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 492:
-#line 6724 "parser.y" /* yacc.c:1646  */
+#line 6739 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("%s <= %s", COMPOUND_EXPR_VAL((yyvsp[-2].dtype)), COMPOUND_EXPR_VAL((yyvsp[0].dtype)));
                 (yyval.dtype).type = cparse_cplusplus ? T_BOOL : T_INT;
               }
-#line 11686 "y.tab.c" /* yacc.c:1646  */
+#line 11701 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 493:
-#line 6728 "parser.y" /* yacc.c:1646  */
+#line 6743 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("%s?%s:%s", COMPOUND_EXPR_VAL((yyvsp[-4].dtype)), COMPOUND_EXPR_VAL((yyvsp[-2].dtype)), COMPOUND_EXPR_VAL((yyvsp[0].dtype)));
                 /* This may not be exactly right, but is probably good enough
                  * for the purposes of parsing constant expressions. */
                 (yyval.dtype).type = promote((yyvsp[-2].dtype).type, (yyvsp[0].dtype).type);
               }
-#line 11697 "y.tab.c" /* yacc.c:1646  */
+#line 11712 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 494:
-#line 6734 "parser.y" /* yacc.c:1646  */
+#line 6749 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("-%s",(yyvsp[0].dtype).val);
                 (yyval.dtype).type = (yyvsp[0].dtype).type;
               }
-#line 11706 "y.tab.c" /* yacc.c:1646  */
+#line 11721 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 495:
-#line 6738 "parser.y" /* yacc.c:1646  */
+#line 6753 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype).val = NewStringf("+%s",(yyvsp[0].dtype).val);
                 (yyval.dtype).type = (yyvsp[0].dtype).type;
               }
-#line 11715 "y.tab.c" /* yacc.c:1646  */
+#line 11730 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 496:
-#line 6742 "parser.y" /* yacc.c:1646  */
+#line 6757 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.dtype).val = NewStringf("~%s",(yyvsp[0].dtype).val);
                 (yyval.dtype).type = (yyvsp[0].dtype).type;
               }
-#line 11724 "y.tab.c" /* yacc.c:1646  */
+#line 11739 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 497:
-#line 6746 "parser.y" /* yacc.c:1646  */
+#line 6761 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.dtype).val = NewStringf("!%s",COMPOUND_EXPR_VAL((yyvsp[0].dtype)));
                 (yyval.dtype).type = T_INT;
               }
-#line 11733 "y.tab.c" /* yacc.c:1646  */
+#line 11748 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 498:
-#line 6750 "parser.y" /* yacc.c:1646  */
+#line 6765 "parser.y" /* yacc.c:1646  */
     {
                 String *qty;
                  skip_balanced('(',')');
@@ -11748,61 +11763,61 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                 (yyval.dtype).type = T_INT;
                 Delete(qty);
                }
-#line 11752 "y.tab.c" /* yacc.c:1646  */
+#line 11767 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 499:
-#line 6766 "parser.y" /* yacc.c:1646  */
+#line 6781 "parser.y" /* yacc.c:1646  */
     {
                (yyval.str) = NewString("...");
              }
-#line 11760 "y.tab.c" /* yacc.c:1646  */
+#line 11775 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 500:
-#line 6771 "parser.y" /* yacc.c:1646  */
+#line 6786 "parser.y" /* yacc.c:1646  */
     {
                (yyval.str) = (yyvsp[0].str);
              }
-#line 11768 "y.tab.c" /* yacc.c:1646  */
+#line 11783 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 501:
-#line 6774 "parser.y" /* yacc.c:1646  */
+#line 6789 "parser.y" /* yacc.c:1646  */
     {
                (yyval.str) = 0;
              }
-#line 11776 "y.tab.c" /* yacc.c:1646  */
+#line 11791 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 502:
-#line 6779 "parser.y" /* yacc.c:1646  */
+#line 6794 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.bases) = (yyvsp[0].bases);
                }
-#line 11784 "y.tab.c" /* yacc.c:1646  */
+#line 11799 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 503:
-#line 6784 "parser.y" /* yacc.c:1646  */
+#line 6799 "parser.y" /* yacc.c:1646  */
     { inherit_list = 1; }
-#line 11790 "y.tab.c" /* yacc.c:1646  */
+#line 11805 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 504:
-#line 6784 "parser.y" /* yacc.c:1646  */
+#line 6799 "parser.y" /* yacc.c:1646  */
     { (yyval.bases) = (yyvsp[0].bases); inherit_list = 0; }
-#line 11796 "y.tab.c" /* yacc.c:1646  */
+#line 11811 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 505:
-#line 6785 "parser.y" /* yacc.c:1646  */
+#line 6800 "parser.y" /* yacc.c:1646  */
     { (yyval.bases) = 0; }
-#line 11802 "y.tab.c" /* yacc.c:1646  */
+#line 11817 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 506:
-#line 6788 "parser.y" /* yacc.c:1646  */
+#line 6803 "parser.y" /* yacc.c:1646  */
     {
                   Hash *list = NewHash();
                   Node *base = (yyvsp[0].node);
@@ -11819,11 +11834,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                   Append(Getattr(list,Getattr(base,"access")),name);
                   (yyval.bases) = list;
                }
-#line 11823 "y.tab.c" /* yacc.c:1646  */
+#line 11838 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 507:
-#line 6805 "parser.y" /* yacc.c:1646  */
+#line 6820 "parser.y" /* yacc.c:1646  */
     {
                   Hash *list = (yyvsp[-2].bases);
                   Node *base = (yyvsp[0].node);
@@ -11831,19 +11846,19 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                   Append(Getattr(list,Getattr(base,"access")),name);
                    (yyval.bases) = list;
                }
-#line 11835 "y.tab.c" /* yacc.c:1646  */
+#line 11850 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 508:
-#line 6814 "parser.y" /* yacc.c:1646  */
+#line 6829 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.intvalue) = cparse_line;
               }
-#line 11843 "y.tab.c" /* yacc.c:1646  */
+#line 11858 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 509:
-#line 6816 "parser.y" /* yacc.c:1646  */
+#line 6831 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.node) = NewHash();
                 Setfile((yyval.node),cparse_file);
@@ -11860,19 +11875,19 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                 if ((yyvsp[0].str))
                   SetFlag((yyval.node), "variadic");
                }
-#line 11864 "y.tab.c" /* yacc.c:1646  */
+#line 11879 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 510:
-#line 6832 "parser.y" /* yacc.c:1646  */
+#line 6847 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.intvalue) = cparse_line;
               }
-#line 11872 "y.tab.c" /* yacc.c:1646  */
+#line 11887 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 511:
-#line 6834 "parser.y" /* yacc.c:1646  */
+#line 6849 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.node) = NewHash();
                 Setfile((yyval.node),cparse_file);
@@ -11887,248 +11902,248 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                 if ((yyvsp[0].str))
                   SetFlag((yyval.node), "variadic");
                }
-#line 11891 "y.tab.c" /* yacc.c:1646  */
+#line 11906 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 512:
-#line 6850 "parser.y" /* yacc.c:1646  */
+#line 6865 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = (char*)"public"; }
-#line 11897 "y.tab.c" /* yacc.c:1646  */
+#line 11912 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 513:
-#line 6851 "parser.y" /* yacc.c:1646  */
+#line 6866 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = (char*)"private"; }
-#line 11903 "y.tab.c" /* yacc.c:1646  */
+#line 11918 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 514:
-#line 6852 "parser.y" /* yacc.c:1646  */
+#line 6867 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = (char*)"protected"; }
-#line 11909 "y.tab.c" /* yacc.c:1646  */
+#line 11924 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 515:
-#line 6855 "parser.y" /* yacc.c:1646  */
+#line 6870 "parser.y" /* yacc.c:1646  */
     { 
                    (yyval.id) = (char*)"class"; 
                   if (!inherit_list) last_cpptype = (yyval.id);
                }
-#line 11918 "y.tab.c" /* yacc.c:1646  */
+#line 11933 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 516:
-#line 6859 "parser.y" /* yacc.c:1646  */
+#line 6874 "parser.y" /* yacc.c:1646  */
     { 
                    (yyval.id) = (char *)"typename"; 
                   if (!inherit_list) last_cpptype = (yyval.id);
                }
-#line 11927 "y.tab.c" /* yacc.c:1646  */
+#line 11942 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 517:
-#line 6863 "parser.y" /* yacc.c:1646  */
+#line 6878 "parser.y" /* yacc.c:1646  */
     { 
                    (yyval.id) = (char *)"class..."; 
                   if (!inherit_list) last_cpptype = (yyval.id);
                }
-#line 11936 "y.tab.c" /* yacc.c:1646  */
+#line 11951 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 518:
-#line 6867 "parser.y" /* yacc.c:1646  */
+#line 6882 "parser.y" /* yacc.c:1646  */
     { 
                    (yyval.id) = (char *)"typename..."; 
                   if (!inherit_list) last_cpptype = (yyval.id);
                }
-#line 11945 "y.tab.c" /* yacc.c:1646  */
+#line 11960 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 519:
-#line 6873 "parser.y" /* yacc.c:1646  */
+#line 6888 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.id) = (yyvsp[0].id);
                }
-#line 11953 "y.tab.c" /* yacc.c:1646  */
+#line 11968 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 520:
-#line 6876 "parser.y" /* yacc.c:1646  */
+#line 6891 "parser.y" /* yacc.c:1646  */
     { 
                    (yyval.id) = (char*)"struct"; 
                   if (!inherit_list) last_cpptype = (yyval.id);
                }
-#line 11962 "y.tab.c" /* yacc.c:1646  */
+#line 11977 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 521:
-#line 6880 "parser.y" /* yacc.c:1646  */
+#line 6895 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.id) = (char*)"union"; 
                   if (!inherit_list) last_cpptype = (yyval.id);
                }
-#line 11971 "y.tab.c" /* yacc.c:1646  */
+#line 11986 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 522:
-#line 6886 "parser.y" /* yacc.c:1646  */
+#line 6901 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.id) = (char*)"class";
                   if (!inherit_list) last_cpptype = (yyval.id);
                }
-#line 11980 "y.tab.c" /* yacc.c:1646  */
+#line 11995 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 523:
-#line 6890 "parser.y" /* yacc.c:1646  */
+#line 6905 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.id) = (char*)"struct";
                   if (!inherit_list) last_cpptype = (yyval.id);
                }
-#line 11989 "y.tab.c" /* yacc.c:1646  */
+#line 12004 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 524:
-#line 6894 "parser.y" /* yacc.c:1646  */
+#line 6909 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.id) = (char*)"union";
                   if (!inherit_list) last_cpptype = (yyval.id);
                }
-#line 11998 "y.tab.c" /* yacc.c:1646  */
+#line 12013 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 525:
-#line 6900 "parser.y" /* yacc.c:1646  */
+#line 6915 "parser.y" /* yacc.c:1646  */
     {
                   (yyval.id) = (yyvsp[0].id);
                }
-#line 12006 "y.tab.c" /* yacc.c:1646  */
+#line 12021 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 526:
-#line 6903 "parser.y" /* yacc.c:1646  */
+#line 6918 "parser.y" /* yacc.c:1646  */
     {
                   (yyval.id) = 0;
                }
-#line 12014 "y.tab.c" /* yacc.c:1646  */
+#line 12029 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 529:
-#line 6912 "parser.y" /* yacc.c:1646  */
+#line 6927 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.str) = 0;
               }
-#line 12022 "y.tab.c" /* yacc.c:1646  */
+#line 12037 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 530:
-#line 6915 "parser.y" /* yacc.c:1646  */
+#line 6930 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.str) = NewString("1");
               }
-#line 12030 "y.tab.c" /* yacc.c:1646  */
+#line 12045 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 531:
-#line 6918 "parser.y" /* yacc.c:1646  */
+#line 6933 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.str) = NewString("1");
               }
-#line 12038 "y.tab.c" /* yacc.c:1646  */
+#line 12053 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 532:
-#line 6921 "parser.y" /* yacc.c:1646  */
+#line 6936 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.str) = NewString("1");
               }
-#line 12046 "y.tab.c" /* yacc.c:1646  */
+#line 12061 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 533:
-#line 6926 "parser.y" /* yacc.c:1646  */
+#line 6941 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.str) = (yyvsp[0].str);
                }
-#line 12054 "y.tab.c" /* yacc.c:1646  */
+#line 12069 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 534:
-#line 6929 "parser.y" /* yacc.c:1646  */
+#line 6944 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.str) = 0;
                }
-#line 12062 "y.tab.c" /* yacc.c:1646  */
+#line 12077 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 535:
-#line 6934 "parser.y" /* yacc.c:1646  */
+#line 6949 "parser.y" /* yacc.c:1646  */
     {
                     (yyval.dtype).throws = (yyvsp[-1].pl);
                     (yyval.dtype).throwf = NewString("1");
                     (yyval.dtype).nexcept = 0;
                     (yyval.dtype).final = 0;
               }
-#line 12073 "y.tab.c" /* yacc.c:1646  */
+#line 12088 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 536:
-#line 6940 "parser.y" /* yacc.c:1646  */
+#line 6955 "parser.y" /* yacc.c:1646  */
     {
                     (yyval.dtype).throws = 0;
                     (yyval.dtype).throwf = 0;
                     (yyval.dtype).nexcept = NewString("true");
                     (yyval.dtype).final = 0;
               }
-#line 12084 "y.tab.c" /* yacc.c:1646  */
+#line 12099 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 537:
-#line 6946 "parser.y" /* yacc.c:1646  */
+#line 6961 "parser.y" /* yacc.c:1646  */
     {
                     (yyval.dtype).throws = 0;
                     (yyval.dtype).throwf = 0;
                     (yyval.dtype).nexcept = 0;
                     (yyval.dtype).final = (yyvsp[0].str);
               }
-#line 12095 "y.tab.c" /* yacc.c:1646  */
+#line 12110 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 538:
-#line 6952 "parser.y" /* yacc.c:1646  */
+#line 6967 "parser.y" /* yacc.c:1646  */
     {
                     (yyval.dtype).throws = (yyvsp[-2].pl);
                     (yyval.dtype).throwf = NewString("1");
                     (yyval.dtype).nexcept = 0;
                     (yyval.dtype).final = (yyvsp[0].str);
               }
-#line 12106 "y.tab.c" /* yacc.c:1646  */
+#line 12121 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 539:
-#line 6958 "parser.y" /* yacc.c:1646  */
+#line 6973 "parser.y" /* yacc.c:1646  */
     {
                     (yyval.dtype).throws = 0;
                     (yyval.dtype).throwf = 0;
                     (yyval.dtype).nexcept = NewString("true");
                     (yyval.dtype).final = (yyvsp[0].str);
               }
-#line 12117 "y.tab.c" /* yacc.c:1646  */
+#line 12132 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 540:
-#line 6964 "parser.y" /* yacc.c:1646  */
+#line 6979 "parser.y" /* yacc.c:1646  */
     {
                     (yyval.dtype).throws = 0;
                     (yyval.dtype).throwf = 0;
                     (yyval.dtype).nexcept = (yyvsp[-1].dtype).val;
                     (yyval.dtype).final = 0;
               }
-#line 12128 "y.tab.c" /* yacc.c:1646  */
+#line 12143 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 541:
-#line 6972 "parser.y" /* yacc.c:1646  */
+#line 6987 "parser.y" /* yacc.c:1646  */
     {
                     (yyval.dtype).throws = 0;
                     (yyval.dtype).throwf = 0;
@@ -12137,39 +12152,39 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                     (yyval.dtype).qualifier = (yyvsp[0].dtype).qualifier;
                     (yyval.dtype).refqualifier = (yyvsp[0].dtype).refqualifier;
                }
-#line 12141 "y.tab.c" /* yacc.c:1646  */
+#line 12156 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 542:
-#line 6980 "parser.y" /* yacc.c:1646  */
+#line 6995 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.dtype) = (yyvsp[0].dtype);
                     (yyval.dtype).qualifier = 0;
                     (yyval.dtype).refqualifier = 0;
                }
-#line 12151 "y.tab.c" /* yacc.c:1646  */
+#line 12166 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 543:
-#line 6985 "parser.y" /* yacc.c:1646  */
+#line 7000 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.dtype) = (yyvsp[0].dtype);
                     (yyval.dtype).qualifier = (yyvsp[-1].dtype).qualifier;
                     (yyval.dtype).refqualifier = (yyvsp[-1].dtype).refqualifier;
                }
-#line 12161 "y.tab.c" /* yacc.c:1646  */
+#line 12176 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 544:
-#line 6992 "parser.y" /* yacc.c:1646  */
+#line 7007 "parser.y" /* yacc.c:1646  */
     {
                     (yyval.dtype) = (yyvsp[0].dtype);
                }
-#line 12169 "y.tab.c" /* yacc.c:1646  */
+#line 12184 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 545:
-#line 6995 "parser.y" /* yacc.c:1646  */
+#line 7010 "parser.y" /* yacc.c:1646  */
     { 
                     (yyval.dtype).throws = 0;
                     (yyval.dtype).throwf = 0;
@@ -12178,11 +12193,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                     (yyval.dtype).qualifier = 0;
                     (yyval.dtype).refqualifier = 0;
                }
-#line 12182 "y.tab.c" /* yacc.c:1646  */
+#line 12197 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 546:
-#line 7005 "parser.y" /* yacc.c:1646  */
+#line 7020 "parser.y" /* yacc.c:1646  */
     { 
                     Clear(scanner_ccode); 
                     (yyval.decl).have_parms = 0; 
@@ -12194,11 +12209,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                     if ((yyvsp[-2].dtype).qualifier)
                       Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
                }
-#line 12198 "y.tab.c" /* yacc.c:1646  */
+#line 12213 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 547:
-#line 7016 "parser.y" /* yacc.c:1646  */
+#line 7031 "parser.y" /* yacc.c:1646  */
     { 
                     skip_balanced('{','}'); 
                     (yyval.decl).have_parms = 0; 
@@ -12210,11 +12225,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                     if ((yyvsp[-2].dtype).qualifier)
                       Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
                }
-#line 12214 "y.tab.c" /* yacc.c:1646  */
+#line 12229 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 548:
-#line 7027 "parser.y" /* yacc.c:1646  */
+#line 7042 "parser.y" /* yacc.c:1646  */
     { 
                     Clear(scanner_ccode); 
                     (yyval.decl).parms = (yyvsp[-2].pl); 
@@ -12225,11 +12240,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                    (yyval.decl).nexcept = 0;
                    (yyval.decl).final = 0;
                }
-#line 12229 "y.tab.c" /* yacc.c:1646  */
+#line 12244 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 549:
-#line 7037 "parser.y" /* yacc.c:1646  */
+#line 7052 "parser.y" /* yacc.c:1646  */
     {
                     skip_balanced('{','}'); 
                     (yyval.decl).parms = (yyvsp[-2].pl); 
@@ -12240,11 +12255,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                     (yyval.decl).nexcept = 0;
                     (yyval.decl).final = 0;
                }
-#line 12244 "y.tab.c" /* yacc.c:1646  */
+#line 12259 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 550:
-#line 7047 "parser.y" /* yacc.c:1646  */
+#line 7062 "parser.y" /* yacc.c:1646  */
     { 
                     (yyval.decl).have_parms = 0; 
                     (yyval.decl).defarg = (yyvsp[-1].dtype).val; 
@@ -12253,11 +12268,11 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                     (yyval.decl).nexcept = 0;
                     (yyval.decl).final = 0;
                }
-#line 12257 "y.tab.c" /* yacc.c:1646  */
+#line 12272 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 551:
-#line 7055 "parser.y" /* yacc.c:1646  */
+#line 7070 "parser.y" /* yacc.c:1646  */
     {
                     (yyval.decl).have_parms = 0;
                     (yyval.decl).defarg = (yyvsp[-1].dtype).val;
@@ -12268,349 +12283,349 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                     if ((yyvsp[-3].dtype).qualifier)
                       Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
                }
-#line 12272 "y.tab.c" /* yacc.c:1646  */
+#line 12287 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 558:
-#line 7077 "parser.y" /* yacc.c:1646  */
+#line 7092 "parser.y" /* yacc.c:1646  */
     {
                  skip_balanced('(',')');
                  Clear(scanner_ccode);
                }
-#line 12281 "y.tab.c" /* yacc.c:1646  */
+#line 12296 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 559:
-#line 7089 "parser.y" /* yacc.c:1646  */
+#line 7104 "parser.y" /* yacc.c:1646  */
     {
                  skip_balanced('{','}');
                  Clear(scanner_ccode);
                }
-#line 12290 "y.tab.c" /* yacc.c:1646  */
+#line 12305 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 560:
-#line 7095 "parser.y" /* yacc.c:1646  */
+#line 7110 "parser.y" /* yacc.c:1646  */
     {
                      String *s = NewStringEmpty();
                      SwigType_add_template(s,(yyvsp[-1].p));
                      (yyval.id) = Char(s);
                     scanner_last_id(1);
                 }
-#line 12301 "y.tab.c" /* yacc.c:1646  */
+#line 12316 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 561:
-#line 7104 "parser.y" /* yacc.c:1646  */
+#line 7119 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = (yyvsp[0].id); }
-#line 12307 "y.tab.c" /* yacc.c:1646  */
+#line 12322 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 562:
-#line 7105 "parser.y" /* yacc.c:1646  */
+#line 7120 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = Swig_copy_string("override"); }
-#line 12313 "y.tab.c" /* yacc.c:1646  */
+#line 12328 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 563:
-#line 7106 "parser.y" /* yacc.c:1646  */
+#line 7121 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = Swig_copy_string("final"); }
-#line 12319 "y.tab.c" /* yacc.c:1646  */
+#line 12334 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 564:
-#line 7109 "parser.y" /* yacc.c:1646  */
+#line 7124 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = (yyvsp[0].id); }
-#line 12325 "y.tab.c" /* yacc.c:1646  */
+#line 12340 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 565:
-#line 7110 "parser.y" /* yacc.c:1646  */
+#line 7125 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = Char((yyvsp[0].dtype).val); }
-#line 12331 "y.tab.c" /* yacc.c:1646  */
+#line 12346 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 566:
-#line 7111 "parser.y" /* yacc.c:1646  */
+#line 7126 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = Char((yyvsp[0].str)); }
-#line 12337 "y.tab.c" /* yacc.c:1646  */
+#line 12352 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 567:
-#line 7114 "parser.y" /* yacc.c:1646  */
+#line 7129 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = (yyvsp[0].id); }
-#line 12343 "y.tab.c" /* yacc.c:1646  */
+#line 12358 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 568:
-#line 7115 "parser.y" /* yacc.c:1646  */
+#line 7130 "parser.y" /* yacc.c:1646  */
     { (yyval.id) = 0; }
-#line 12349 "y.tab.c" /* yacc.c:1646  */
+#line 12364 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 569:
-#line 7118 "parser.y" /* yacc.c:1646  */
+#line 7133 "parser.y" /* yacc.c:1646  */
     { 
                   (yyval.str) = 0;
                  if (!(yyval.str)) (yyval.str) = NewStringf("%s%s", (yyvsp[-1].str),(yyvsp[0].str));
                  Delete((yyvsp[0].str));
                }
-#line 12359 "y.tab.c" /* yacc.c:1646  */
+#line 12374 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 570:
-#line 7123 "parser.y" /* yacc.c:1646  */
+#line 7138 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.str) = NewStringf("::%s%s",(yyvsp[-1].str),(yyvsp[0].str));
                  Delete((yyvsp[0].str));
                }
-#line 12368 "y.tab.c" /* yacc.c:1646  */
+#line 12383 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 571:
-#line 7127 "parser.y" /* yacc.c:1646  */
+#line 7142 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.str) = NewString((yyvsp[0].str));
               }
-#line 12376 "y.tab.c" /* yacc.c:1646  */
+#line 12391 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 572:
-#line 7130 "parser.y" /* yacc.c:1646  */
+#line 7145 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.str) = NewStringf("::%s",(yyvsp[0].str));
                }
-#line 12384 "y.tab.c" /* yacc.c:1646  */
+#line 12399 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 573:
-#line 7133 "parser.y" /* yacc.c:1646  */
+#line 7148 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.str) = NewStringf("%s", (yyvsp[0].str));
               }
-#line 12392 "y.tab.c" /* yacc.c:1646  */
+#line 12407 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 574:
-#line 7136 "parser.y" /* yacc.c:1646  */
+#line 7151 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.str) = NewStringf("%s%s", (yyvsp[-1].str), (yyvsp[0].id));
               }
-#line 12400 "y.tab.c" /* yacc.c:1646  */
+#line 12415 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 575:
-#line 7139 "parser.y" /* yacc.c:1646  */
+#line 7154 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.str) = NewStringf("::%s",(yyvsp[0].str));
                }
-#line 12408 "y.tab.c" /* yacc.c:1646  */
+#line 12423 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 576:
-#line 7144 "parser.y" /* yacc.c:1646  */
+#line 7159 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.str) = NewStringf("::%s%s",(yyvsp[-1].str),(yyvsp[0].str));
                   Delete((yyvsp[0].str));
                }
-#line 12417 "y.tab.c" /* yacc.c:1646  */
+#line 12432 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 577:
-#line 7148 "parser.y" /* yacc.c:1646  */
+#line 7163 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.str) = NewStringf("::%s",(yyvsp[0].str));
                }
-#line 12425 "y.tab.c" /* yacc.c:1646  */
+#line 12440 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 578:
-#line 7151 "parser.y" /* yacc.c:1646  */
+#line 7166 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.str) = NewStringf("::%s",(yyvsp[0].str));
                }
-#line 12433 "y.tab.c" /* yacc.c:1646  */
+#line 12448 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 579:
-#line 7158 "parser.y" /* yacc.c:1646  */
+#line 7173 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.str) = NewStringf("::~%s",(yyvsp[0].str));
                }
-#line 12441 "y.tab.c" /* yacc.c:1646  */
+#line 12456 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 580:
-#line 7164 "parser.y" /* yacc.c:1646  */
+#line 7179 "parser.y" /* yacc.c:1646  */
     {
                (yyval.str) = NewStringf("%s", (yyvsp[0].id));
              }
-#line 12449 "y.tab.c" /* yacc.c:1646  */
+#line 12464 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 581:
-#line 7167 "parser.y" /* yacc.c:1646  */
+#line 7182 "parser.y" /* yacc.c:1646  */
     {
                (yyval.str) = NewStringf("%s%s", (yyvsp[-1].id), (yyvsp[0].id));
              }
-#line 12457 "y.tab.c" /* yacc.c:1646  */
+#line 12472 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 582:
-#line 7172 "parser.y" /* yacc.c:1646  */
+#line 7187 "parser.y" /* yacc.c:1646  */
     {
                (yyval.str) = (yyvsp[0].str);
              }
-#line 12465 "y.tab.c" /* yacc.c:1646  */
+#line 12480 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 583:
-#line 7175 "parser.y" /* yacc.c:1646  */
+#line 7190 "parser.y" /* yacc.c:1646  */
     {
                (yyval.str) = NewStringf("%s%s", (yyvsp[-1].id), (yyvsp[0].id));
              }
-#line 12473 "y.tab.c" /* yacc.c:1646  */
+#line 12488 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 584:
-#line 7181 "parser.y" /* yacc.c:1646  */
+#line 7196 "parser.y" /* yacc.c:1646  */
     {
                   (yyval.str) = 0;
                  if (!(yyval.str)) (yyval.str) = NewStringf("%s%s", (yyvsp[-1].id),(yyvsp[0].str));
                  Delete((yyvsp[0].str));
                }
-#line 12483 "y.tab.c" /* yacc.c:1646  */
+#line 12498 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 585:
-#line 7186 "parser.y" /* yacc.c:1646  */
+#line 7201 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.str) = NewStringf("::%s%s",(yyvsp[-1].id),(yyvsp[0].str));
                  Delete((yyvsp[0].str));
                }
-#line 12492 "y.tab.c" /* yacc.c:1646  */
+#line 12507 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 586:
-#line 7190 "parser.y" /* yacc.c:1646  */
+#line 7205 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.str) = NewString((yyvsp[0].id));
               }
-#line 12500 "y.tab.c" /* yacc.c:1646  */
+#line 12515 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 587:
-#line 7193 "parser.y" /* yacc.c:1646  */
+#line 7208 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.str) = NewStringf("::%s",(yyvsp[0].id));
                }
-#line 12508 "y.tab.c" /* yacc.c:1646  */
+#line 12523 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 588:
-#line 7196 "parser.y" /* yacc.c:1646  */
+#line 7211 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.str) = NewString((yyvsp[0].str));
               }
-#line 12516 "y.tab.c" /* yacc.c:1646  */
+#line 12531 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 589:
-#line 7199 "parser.y" /* yacc.c:1646  */
+#line 7214 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.str) = NewStringf("::%s",(yyvsp[0].str));
                }
-#line 12524 "y.tab.c" /* yacc.c:1646  */
+#line 12539 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 590:
-#line 7204 "parser.y" /* yacc.c:1646  */
+#line 7219 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.str) = NewStringf("::%s%s",(yyvsp[-1].id),(yyvsp[0].str));
                   Delete((yyvsp[0].str));
                }
-#line 12533 "y.tab.c" /* yacc.c:1646  */
+#line 12548 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 591:
-#line 7208 "parser.y" /* yacc.c:1646  */
+#line 7223 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.str) = NewStringf("::%s",(yyvsp[0].id));
                }
-#line 12541 "y.tab.c" /* yacc.c:1646  */
+#line 12556 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 592:
-#line 7211 "parser.y" /* yacc.c:1646  */
+#line 7226 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.str) = NewStringf("::%s",(yyvsp[0].str));
                }
-#line 12549 "y.tab.c" /* yacc.c:1646  */
+#line 12564 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 593:
-#line 7214 "parser.y" /* yacc.c:1646  */
+#line 7229 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.str) = NewStringf("::~%s",(yyvsp[0].id));
                }
-#line 12557 "y.tab.c" /* yacc.c:1646  */
+#line 12572 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 594:
-#line 7220 "parser.y" /* yacc.c:1646  */
+#line 7235 "parser.y" /* yacc.c:1646  */
     { 
                    (yyval.str) = NewStringf("%s%s", (yyvsp[-1].str), (yyvsp[0].id));
                }
-#line 12565 "y.tab.c" /* yacc.c:1646  */
+#line 12580 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 595:
-#line 7223 "parser.y" /* yacc.c:1646  */
+#line 7238 "parser.y" /* yacc.c:1646  */
     { (yyval.str) = NewString((yyvsp[0].id));}
-#line 12571 "y.tab.c" /* yacc.c:1646  */
+#line 12586 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 596:
-#line 7226 "parser.y" /* yacc.c:1646  */
+#line 7241 "parser.y" /* yacc.c:1646  */
     {
                    (yyval.str) = NewStringf("%s%s", (yyvsp[-1].str), (yyvsp[0].id));
                }
-#line 12579 "y.tab.c" /* yacc.c:1646  */
+#line 12594 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 597:
-#line 7234 "parser.y" /* yacc.c:1646  */
+#line 7249 "parser.y" /* yacc.c:1646  */
     { (yyval.str) = NewString((yyvsp[0].id));}
-#line 12585 "y.tab.c" /* yacc.c:1646  */
+#line 12600 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 598:
-#line 7237 "parser.y" /* yacc.c:1646  */
+#line 7252 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.str) = (yyvsp[0].str);
                }
-#line 12593 "y.tab.c" /* yacc.c:1646  */
+#line 12608 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 599:
-#line 7240 "parser.y" /* yacc.c:1646  */
+#line 7255 "parser.y" /* yacc.c:1646  */
     {
                   skip_balanced('{','}');
                  (yyval.str) = NewString(scanner_ccode);
                }
-#line 12602 "y.tab.c" /* yacc.c:1646  */
+#line 12617 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 600:
-#line 7244 "parser.y" /* yacc.c:1646  */
+#line 7259 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.str) = (yyvsp[0].str);
               }
-#line 12610 "y.tab.c" /* yacc.c:1646  */
+#line 12625 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 601:
-#line 7249 "parser.y" /* yacc.c:1646  */
+#line 7264 "parser.y" /* yacc.c:1646  */
     {
                   Hash *n;
                   (yyval.node) = NewHash();
@@ -12624,92 +12639,92 @@ Printf(stdout, "  Scope %s [creating single scope C++17 style]\n", scopename);
                     n = nextSibling(n);
                  }
                }
-#line 12628 "y.tab.c" /* yacc.c:1646  */
+#line 12643 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 602:
-#line 7262 "parser.y" /* yacc.c:1646  */
+#line 7277 "parser.y" /* yacc.c:1646  */
     { (yyval.node) = 0; }
-#line 12634 "y.tab.c" /* yacc.c:1646  */
+#line 12649 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 603:
-#line 7266 "parser.y" /* yacc.c:1646  */
+#line 7281 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.node) = NewHash();
                 Setattr((yyval.node),"name",(yyvsp[-2].id));
                 Setattr((yyval.node),"value",(yyvsp[0].str));
                }
-#line 12644 "y.tab.c" /* yacc.c:1646  */
+#line 12659 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 604:
-#line 7271 "parser.y" /* yacc.c:1646  */
+#line 7286 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.node) = NewHash();
                 Setattr((yyval.node),"name",(yyvsp[-4].id));
                 Setattr((yyval.node),"value",(yyvsp[-2].str));
                 set_nextSibling((yyval.node),(yyvsp[0].node));
                }
-#line 12655 "y.tab.c" /* yacc.c:1646  */
+#line 12670 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 605:
-#line 7277 "parser.y" /* yacc.c:1646  */
+#line 7292 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.node) = NewHash();
                  Setattr((yyval.node),"name",(yyvsp[0].id));
               }
-#line 12664 "y.tab.c" /* yacc.c:1646  */
+#line 12679 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 606:
-#line 7281 "parser.y" /* yacc.c:1646  */
+#line 7296 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.node) = NewHash();
                  Setattr((yyval.node),"name",(yyvsp[-2].id));
                  set_nextSibling((yyval.node),(yyvsp[0].node));
                }
-#line 12674 "y.tab.c" /* yacc.c:1646  */
+#line 12689 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 607:
-#line 7286 "parser.y" /* yacc.c:1646  */
+#line 7301 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.node) = (yyvsp[0].node);
                 Setattr((yyval.node),"name",(yyvsp[-2].id));
                }
-#line 12683 "y.tab.c" /* yacc.c:1646  */
+#line 12698 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 608:
-#line 7290 "parser.y" /* yacc.c:1646  */
+#line 7305 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.node) = (yyvsp[-2].node);
                 Setattr((yyval.node),"name",(yyvsp[-4].id));
                 set_nextSibling((yyval.node),(yyvsp[0].node));
                }
-#line 12693 "y.tab.c" /* yacc.c:1646  */
+#line 12708 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 609:
-#line 7297 "parser.y" /* yacc.c:1646  */
+#line 7312 "parser.y" /* yacc.c:1646  */
     {
                 (yyval.str) = (yyvsp[0].str);
                }
-#line 12701 "y.tab.c" /* yacc.c:1646  */
+#line 12716 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 610:
-#line 7300 "parser.y" /* yacc.c:1646  */
+#line 7315 "parser.y" /* yacc.c:1646  */
     {
                  (yyval.str) = Char((yyvsp[0].dtype).val);
                }
-#line 12709 "y.tab.c" /* yacc.c:1646  */
+#line 12724 "y.tab.c" /* yacc.c:1646  */
     break;
 
 
-#line 12713 "y.tab.c" /* yacc.c:1646  */
+#line 12728 "y.tab.c" /* yacc.c:1646  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -12937,7 +12952,7 @@ yyreturn:
 #endif
   return yyresult;
 }
-#line 7307 "parser.y" /* yacc.c:1906  */
+#line 7322 "parser.y" /* yacc.c:1906  */
 
 
 SwigType *Swig_cparse_type(String *s) {
index 470b7d0..8029dee 100644 (file)
@@ -4800,6 +4800,9 @@ cpp_conversion_operator : storage_class CONVERSIONOPERATOR type pointer LPAREN p
                 if ($8.qualifier) {
                   SwigType_push($4,$8.qualifier);
                 }
+                if ($8.val) {
+                  Setattr($$,"value",$8.val);
+                }
                 Setattr($$,"refqualifier",$8.refqualifier);
                 Setattr($$,"decl",$4);
                 Setattr($$,"parms",$6);
@@ -4818,6 +4821,9 @@ cpp_conversion_operator : storage_class CONVERSIONOPERATOR type pointer LPAREN p
                 if ($8.qualifier) {
                   SwigType_push(decl,$8.qualifier);
                 }
+                if ($8.val) {
+                  Setattr($$,"value",$8.val);
+                }
                 Setattr($$,"refqualifier",$8.refqualifier);
                 Setattr($$,"decl",decl);
                 Setattr($$,"parms",$6);
@@ -4836,6 +4842,9 @@ cpp_conversion_operator : storage_class CONVERSIONOPERATOR type pointer LPAREN p
                 if ($8.qualifier) {
                   SwigType_push(decl,$8.qualifier);
                 }
+                if ($8.val) {
+                  Setattr($$,"value",$8.val);
+                }
                 Setattr($$,"refqualifier",$8.refqualifier);
                 Setattr($$,"decl",decl);
                 Setattr($$,"parms",$6);
@@ -4856,6 +4865,9 @@ cpp_conversion_operator : storage_class CONVERSIONOPERATOR type pointer LPAREN p
                 if ($9.qualifier) {
                   SwigType_push(decl,$9.qualifier);
                 }
+                if ($9.val) {
+                  Setattr($$,"value",$9.val);
+                }
                 Setattr($$,"refqualifier",$9.refqualifier);
                 Setattr($$,"decl",decl);
                 Setattr($$,"parms",$7);
@@ -4873,7 +4885,10 @@ cpp_conversion_operator : storage_class CONVERSIONOPERATOR type pointer LPAREN p
                if ($7.qualifier) {
                  SwigType_push(t,$7.qualifier);
                }
-                Setattr($$,"refqualifier",$7.refqualifier);
+               if ($7.val) {
+                 Setattr($$,"value",$7.val);
+               }
+               Setattr($$,"refqualifier",$7.refqualifier);
                Setattr($$,"decl",t);
                Setattr($$,"parms",$5);
                Setattr($$,"conversion_operator","1");
index 8be5f65..be90f25 100644 (file)
@@ -73,11 +73,17 @@ Replace(obj, orig, rep, flags)  Replace occurrences of orig with rep.
 Chop(obj)                       Remove trailing whitespace
 
 flags is one of the following:
-     DOH_REPLACE_ANY
-     DOH_REPLACE_NOQUOTE
-     DOH_REPLACE_ID
-     DOH_REPLACE_FIRST
-             
+    DOH_REPLACE_ID
+    DOH_REPLACE_ID_BEGIN
+    DOH_REPLACE_ID_END
+    DOH_REPLACE_NUMBER_END
+
+and can be combined with one or more of the following:
+    DOH_REPLACE_ANY
+    DOH_REPLACE_NOQUOTE
+    DOH_REPLACE_NOCOMMENT
+    DOH_REPLACE_FIRST
+
 Callable Operations
 -------------------
 Call(obj, args)                 Perform a function call with arguments args.
index 7fb64c0..fd0530e 100644 (file)
@@ -289,11 +289,12 @@ extern char *DohStrchr(const DOHString_or_char *s1, int ch);
 
 #define   DOH_REPLACE_ANY         0x01
 #define   DOH_REPLACE_NOQUOTE     0x02
-#define   DOH_REPLACE_ID          0x04
-#define   DOH_REPLACE_FIRST       0x08
-#define   DOH_REPLACE_ID_BEGIN    0x10
-#define   DOH_REPLACE_ID_END      0x20
-#define   DOH_REPLACE_NUMBER_END  0x40
+#define   DOH_REPLACE_NOCOMMENT   0x04
+#define   DOH_REPLACE_ID          0x08
+#define   DOH_REPLACE_FIRST       0x10
+#define   DOH_REPLACE_ID_BEGIN    0x20
+#define   DOH_REPLACE_ID_END      0x40
+#define   DOH_REPLACE_NUMBER_END  0x80
 
 #define Replaceall(s,t,r)  DohReplace(s,t,r,DOH_REPLACE_ANY)
 #define Replaceid(s,t,r)   DohReplace(s,t,r,DOH_REPLACE_ID)
index e0e4c68..4a9494e 100644 (file)
@@ -15,7 +15,7 @@
 #include "dohint.h"
 
 #ifndef DOH_POOL_SIZE
-#define DOH_POOL_SIZE         16384
+#define DOH_POOL_SIZE         4194304
 #endif
 
 /* Checks stale DOH object use - will use a lot more memory as pool memory is not re-used. */
index 6c67285..3689f4f 100644 (file)
@@ -595,6 +595,13 @@ static char *end_quote(char *s) {
   }
 }
 
+static char *end_comment(char *s) {
+  char *substring = strstr(s, "*/");
+  if (substring)
+    ++substring;
+  return substring;
+}
+
 static char *match_simple(char *base, char *s, char *token, int tokenlen) {
   (void) base;
   (void) tokenlen;
@@ -677,6 +684,7 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
   int ic;
   int rcount = 0;
   int noquote = 0;
+  int nocomment = 0;
   char *c, *s, *t, *first;
   char *q, *q2;
   char *base;
@@ -698,6 +706,11 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
   if (flags & DOH_REPLACE_NOQUOTE)
     noquote = 1;
 
+  if (flags & DOH_REPLACE_NOCOMMENT)
+    nocomment = 1;
+
+  assert(!(noquote && nocomment)); /* quote and comment combination not implemented */
+
   /* If we are not replacing inside quotes, we need to do a little extra work */
   if (noquote) {
     q = strpbrk(base, "\"\'");
@@ -723,6 +736,31 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
     }
   }
 
+  /* If we are not replacing inside comments, we need to do a little extra work */
+  if (nocomment) {
+    q = strstr(base, "/*");
+    if (!q) {
+      nocomment = 0;           /* Well, no comments to worry about. Oh well */
+    } else {
+      while (q && (q < s)) {
+       /* First match was found inside a comment.  Try to find another match */
+       q2 = end_comment(q);
+       if (!q2) {
+         return 0;
+       }
+       if (q2 > s) {
+         /* Find next match */
+         s = (*match) (base, q2 + 1, token, tokenlen);
+       }
+       if (!s)
+         return 0;             /* Oh well, no matches */
+       q = strstr(q2 + 1, "/*");
+       if (!q)
+         nocomment = 0;                /* No more comments */
+      }
+    }
+  }
+
   first = s;
   replen = (int)strlen(rep);
 
@@ -768,6 +806,28 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
          }
        }
       }
+      if (nocomment) {
+       q = strstr(s, "/*");
+       if (!q) {
+         nocomment = 0;
+       } else {
+         while (q && (q < c)) {
+           /* First match was found inside a comment.  Try to find another match */
+           q2 = end_comment(q);
+           if (!q2) {
+             c = 0;
+             break;
+           }
+           if (q2 > c)
+             c = (*match) (base, q2 + 1, token, tokenlen);
+           if (!c)
+             break;
+           q = strstr(q2 + 1, "/*");
+           if (!q)
+             nocomment = 0;    /* No more comments */
+         }
+       }
+      }
       if (delta) {
        if (c) {
          memmove(t, s, c - s);
@@ -823,6 +883,29 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
          }
        }
       }
+      if (nocomment) {
+       q = strstr(s, "/*");
+       if (!q) {
+         break;
+       } else {
+         while (q && (q < c)) {
+           /* First match was found inside a comment.  Try to find another match */
+           q2 = end_comment(q);
+           if (!q2) {
+             c = 0;
+             break;
+           }
+           if (q2 > c) {
+             c = (*match) (base, q2 + 1, token, tokenlen);
+             if (!c)
+               break;
+           }
+           q = strstr(q2 + 1, "/*");
+           if (!q)
+             nocomment = 0;
+         }
+       }
+      }
       if (c) {
        rcount++;
        ic--;
@@ -875,6 +958,29 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
          }
        }
       }
+      if (nocomment) {
+       q = strstr(s, "/*");
+       if (!q) {
+         nocomment = 0;
+       } else {
+         while (q && (q < c)) {
+           /* First match was found inside a comment.  Try to find another match */
+           q2 = end_comment(q);
+           if (!q2) {
+             c = 0;
+             break;
+           }
+           if (q2 > c) {
+             c = (*match) (base, q2 + 1, token, tokenlen);
+             if (!c)
+               break;
+           }
+           q = strstr(q2 + 1, "/*");
+           if (!q)
+             nocomment = 0;    /* No more comments */
+         }
+       }
+      }
       if (i < (rcount - 1)) {
        memcpy(t, s, c - s);
        t += (c - s);
index 1f7b5fa..b5d65af 100644 (file)
 const char *CMD_HTML_ONLY = "htmlonly";
 // doxy commands are not processed inside this block
 const char *CMD_VERBATIM = "verbatim";
+const char *CMD_CODE = "code";
 const char *CMD_LATEX_1 = "f$";
 const char *CMD_LATEX_2 = "f{";
 const char *CMD_LATEX_3 = "f[";
 const char *CMD_END_HTML_ONLY = "endhtmlonly";
 const char *CMD_END_VERBATIM = "endverbatim";
+const char *CMD_END_CODE = "endcode";
 const char *CMD_END_LATEX_1 = "f$";
 const char *CMD_END_LATEX_2 = "f}";
 const char *CMD_END_LATEX_3 = "f]";
index 2e826b2..35d1836 100644 (file)
@@ -34,6 +34,30 @@ std::set<std::string> DoxygenParser::doxygenSectionIndicators;
 const int TOKENSPERLINE = 8; //change this to change the printing behaviour of the token list
 const std::string END_HTML_TAG_MARK("/");
 
+std::string getBaseCommand(const std::string &cmd) {
+  if (cmd.substr(0,5) == "param")
+    return "param";
+  else if (cmd.substr(0,4) == "code")
+    return "code";
+  else
+    return cmd;
+}
+
+// Find the first position beyond the word command.  Extra logic is
+// used to avoid putting the characters "," and "." in
+// DOXYGEN_WORD_CHARS.
+static size_t getEndOfWordCommand(const std::string &line, size_t pos) {
+  size_t endOfWordPos = line.find_first_not_of(DOXYGEN_WORD_CHARS, pos);
+  if (line.substr(pos, 6) == "param[")
+    // include ",", which can appear in param[in,out]
+    endOfWordPos = line.find_first_not_of(string(DOXYGEN_WORD_CHARS)+ ",", pos);  
+  else if (line.substr(pos, 5) == "code{")
+    // include ".", which can appear in e.g. code{.py}
+    endOfWordPos = line.find_first_not_of(string(DOXYGEN_WORD_CHARS)+ ".", pos);
+  return endOfWordPos;
+}
+
+
 DoxygenParser::DoxygenParser(bool noisy) : noisy(noisy) {
   fillTables();
 }
@@ -118,7 +142,7 @@ void DoxygenParser::printTree(const DoxygenEntityList &rootList) {
 }
 
 DoxygenParser::DoxyCommandEnum DoxygenParser::commandBelongs(const std::string &theCommand) {
-  DoxyCommandsMapIt it = doxygenCommands.find(stringToLower(theCommand));
+  DoxyCommandsMapIt it = doxygenCommands.find(stringToLower(getBaseCommand(theCommand)));
 
   if (it != doxygenCommands.end()) {
     return it->second;
@@ -312,7 +336,7 @@ DoxygenParser::TokenListCIt DoxygenParser::getEndOfParagraph(const TokenList &to
 
     } else if (endOfParagraph->m_tokenType == COMMAND) {
 
-      if (isSectionIndicator(endOfParagraph->m_tokenString)) {
+      if (isSectionIndicator(getBaseCommand(endOfParagraph->m_tokenString))) {
         return endOfParagraph;
       } else {
         endOfParagraph++;
@@ -666,7 +690,7 @@ void DoxygenParser::addCommandUnique(const std::string &theCommand, const TokenL
   // \f{ ... \f}
   // \f{env}{ ... \f}
   // \f$ ... \f$
-  else if (theCommand == "code" || theCommand == "verbatim"
+  else if (getBaseCommand(theCommand) == "code" || theCommand == "verbatim"
            || theCommand == "dot" || theCommand == "msc" || theCommand == "f[" || theCommand == "f{" || theCommand == "f$") {
     if (!endCommands.size()) {
       // fill in static table of end commands
@@ -683,7 +707,7 @@ void DoxygenParser::addCommandUnique(const std::string &theCommand, const TokenL
     if (it != endCommands.end())
       endCommand = it->second;
     else
-      endCommand = "end" + theCommand;
+      endCommand = "end" + getBaseCommand(theCommand);
 
     std::string content = getStringTilEndCommand(endCommand, tokList);
     aNewList.push_back(DoxygenEntity("plainstd::string", content));
@@ -1090,7 +1114,7 @@ size_t DoxygenParser::processVerbatimText(size_t pos, const std::string &line) {
     size_t endOfWordPos = line.find_first_not_of(DOXYGEN_WORD_CHARS, pos);
     string cmd = line.substr(pos, endOfWordPos - pos);
 
-    if (cmd == CMD_END_HTML_ONLY || cmd == CMD_END_VERBATIM || cmd == CMD_END_LATEX_1 || cmd == CMD_END_LATEX_2 || cmd == CMD_END_LATEX_3) {
+    if (cmd == CMD_END_HTML_ONLY || cmd == CMD_END_VERBATIM || cmd == CMD_END_LATEX_1 || cmd == CMD_END_LATEX_2 || cmd == CMD_END_LATEX_3 || cmd == CMD_END_CODE) {
 
       m_isVerbatimText = false;
       addDoxyCommand(m_tokenList, cmd);
@@ -1154,22 +1178,38 @@ bool DoxygenParser::processEscapedChars(size_t &pos, const std::string &line) {
  */
 void DoxygenParser::processWordCommands(size_t &pos, const std::string &line) {
   pos++;
-  size_t endOfWordPos = line.find_first_not_of(DOXYGEN_WORD_CHARS, pos);
+  size_t endOfWordPos = getEndOfWordCommand(line, pos);
 
   string cmd = line.substr(pos, endOfWordPos - pos);
   addDoxyCommand(m_tokenList, cmd);
 
-  if (cmd == CMD_HTML_ONLY || cmd == CMD_VERBATIM || cmd == CMD_LATEX_1 || cmd == CMD_LATEX_2 || cmd == CMD_LATEX_3) {
+  // A flag for whether we want to skip leading spaces after the command
+  bool skipLeadingSpace = true;
+
+  if (cmd == CMD_HTML_ONLY || cmd == CMD_VERBATIM || cmd == CMD_LATEX_1 || cmd == CMD_LATEX_2 || cmd == CMD_LATEX_3 || getBaseCommand(cmd) == CMD_CODE) {
 
     m_isVerbatimText = true;
 
-  } else {
+    // Skipping leading space is necessary with inline \code command,
+    // and it won't hurt anything for block \code (TODO: are the other
+    // commands also compatible with skip leading space?  If so, just
+    // do it every time.)
+    if (getBaseCommand(cmd) == CMD_CODE) skipLeadingSpace = true;
+    else skipLeadingSpace = false;
+  } else if (cmd.substr(0,3) == "end") {
+    // If processing an "end" command such as "endlink", don't skip
+    // the space before the next string
+    skipLeadingSpace = false;
+  }
+
+  if (skipLeadingSpace) {
     // skip any possible spaces after command, because some commands have parameters,
     // and spaces between command and parameter must be ignored.
     if (endOfWordPos != string::npos) {
       endOfWordPos = line.find_first_not_of(" \t", endOfWordPos);
     }
   }
+  
   pos = endOfWordPos;
 }
 
index 96c71d2..e692729 100644 (file)
 
 #include "doxyentity.h"
 
+// Utility function to return the base part of a command that may
+// include options, e.g. param[in] -> param
+std::string getBaseCommand(const std::string &cmd);
+
+
 class DoxygenParser {
 private:
 
index 72f84ab..d9313f9 100644 (file)
@@ -334,7 +334,7 @@ std::string JavaDocConverter::translateSubtree(DoxygenEntity &doxygenEntity) {
 void JavaDocConverter::translateEntity(DoxygenEntity &tag, std::string &translatedComment) {
 
   std::map<std::string, std::pair<tagHandler, std::string> >::iterator it;
-  it = tagHandlers.find(tag.typeOfEntity);
+  it = tagHandlers.find(getBaseCommand(tag.typeOfEntity));
 
   if (it != tagHandlers.end()) {
     (this->*(it->second.first))(tag, translatedComment, it->second.second);
index eb48993..c84095b 100644 (file)
@@ -174,7 +174,8 @@ static string padCodeAndVerbatimBlocks(const string &docString) {
     } else {
       if (lastLineWasNonBlank &&
          (line.compare(pos, 13, ".. code-block") == 0 ||
-         line.compare(pos, 7, ".. math") == 0)) {
+          line.compare(pos, 7, ".. math") == 0 ||
+          line.compare(pos, 3, ">>>") == 0)) {
        // Must separate code or math blocks from the previous line
        result += '\n';
       }
@@ -184,6 +185,21 @@ static string padCodeAndVerbatimBlocks(const string &docString) {
   return result;
 }
 
+// Helper function to extract the option value from a command,
+// e.g. param[in] -> in
+static std::string getCommandOption(const std::string &command, char openChar, char closeChar) {
+  string option;
+
+  size_t opt_begin, opt_end;
+  opt_begin = command.find(openChar);
+  opt_end = command.find(closeChar);
+  if (opt_begin != string::npos && opt_end != string::npos)
+    option = command.substr(opt_begin+1, opt_end-opt_begin-1);
+
+  return option;
+}
+
+
 /* static */
 PyDocConverter::TagHandlersMap::mapped_type PyDocConverter::make_handler(tagHandler handler) {
   return make_pair(handler, std::string());
@@ -245,7 +261,7 @@ void PyDocConverter::fillStaticTables() {
   tagHandlers["date"] = make_handler(&PyDocConverter::handleParagraph);
   tagHandlers["deprecated"] = make_handler(&PyDocConverter::handleParagraph);
   tagHandlers["details"] = make_handler(&PyDocConverter::handleParagraph);
-  tagHandlers["em"] = make_handler(&PyDocConverter::handleParagraph, " ");
+  tagHandlers["em"] = make_handler(&PyDocConverter::handleTagWrap, "*");
   tagHandlers["example"] = make_handler(&PyDocConverter::handleParagraph);
   tagHandlers["exception"] = tagHandlers["throw"] = tagHandlers["throws"] = make_handler(&PyDocConverter::handleTagException);
   tagHandlers["htmlonly"] = make_handler(&PyDocConverter::handleParagraph);
@@ -254,7 +270,7 @@ void PyDocConverter::fillStaticTables() {
   tagHandlers["link"] = make_handler(&PyDocConverter::handleParagraph);
   tagHandlers["manonly"] = make_handler(&PyDocConverter::handleParagraph);
   tagHandlers["note"] = make_handler(&PyDocConverter::handleParagraph);
-  tagHandlers["p"] = make_handler(&PyDocConverter::handleParagraph);
+  tagHandlers["p"] = make_handler(&PyDocConverter::handleTagWrap, "``");
   tagHandlers["partofdescription"] = make_handler(&PyDocConverter::handleParagraph);
   tagHandlers["rtfonly"] = make_handler(&PyDocConverter::handleParagraph);
   tagHandlers["remark"] = make_handler(&PyDocConverter::handleParagraph);
@@ -418,16 +434,32 @@ std::string PyDocConverter::getParamType(std::string param) {
   ParmList *plist = CopyParmList(Getattr(currentNode, "parms"));
   for (Parm *p = plist; p; p = nextSibling(p)) {
     String *pname = Getattr(p, "name");
-    if (Char(pname) != param)
-      continue;
-
-    type = getPyDocType(p, pname);
-    break;
+    if (pname && Char(pname) == param) {
+      type = getPyDocType(p, pname);
+      break;
+    }
   }
   Delete(plist);
   return type;
 }
 
+std::string PyDocConverter::getParamValue(std::string param) {
+  std::string value;
+
+  ParmList *plist = CopyParmList(Getattr(currentNode, "parms"));
+  for (Parm *p = plist; p; p = nextSibling(p)) {
+    String *pname = Getattr(p, "name");
+    if (pname && Char(pname) == param) {
+      String *pval = Getattr(p, "value");
+      if (pval)
+       value = Char(pval);
+      break;
+    }
+  }
+  Delete(plist);
+  return value;
+}
+
 std::string PyDocConverter::translateSubtree(DoxygenEntity &doxygenEntity) {
   std::string translatedComment;
 
@@ -456,7 +488,7 @@ std::string PyDocConverter::translateSubtree(DoxygenEntity &doxygenEntity) {
 void PyDocConverter::translateEntity(DoxygenEntity &doxyEntity, std::string &translatedComment) {
   // check if we have needed handler and call it
   std::map<std::string, std::pair<tagHandler, std::string> >::iterator it;
-  it = tagHandlers.find(doxyEntity.typeOfEntity);
+  it = tagHandlers.find(getBaseCommand(doxyEntity.typeOfEntity));
   if (it != tagHandlers.end())
     (this->*(it->second.first)) (doxyEntity, translatedComment, it->second.second);
 }
@@ -531,19 +563,29 @@ void PyDocConverter::handleCode(DoxygenEntity &tag, std::string &translatedComme
 
   trimWhitespace(translatedComment);
 
-  // Use the current indent for the code-block line itself.
-  translatedComment += indent.getFirstLineIndent();
-
-  // Go out on a limb and assume that examples in the C or C++ sources use C++.
-  // In the worst case, we'll highlight C code using C++ syntax which is not a
-  // big deal (TODO: handle Doxygen code command language argument).
-  translatedComment += ".. code-block:: c++\n\n";
-
-  // Specify the level of extra indentation that will be used for
-  // subsequent lines within the code block.  Note that the correct
-  // "starting indentation" is already present in the input, so we
-  // only need to add the desired code block indentation.
-  string codeIndent = m_indent;
+  // Check for an option given to the code command (e.g. code{.py}),
+  // and try to set the code-block language accordingly.
+  string option = getCommandOption(tag.typeOfEntity, '{', '}');
+  // Set up the language option to the code-block command, which can
+  // be any language supported by pygments:
+  string codeLanguage;
+  if (option == ".py")
+    // Other possibilities here are "default" or "python3".  In Sphinx
+    // 2.1.2, basic syntax doesn't render quite the same in these as
+    // with "python", which for basic keywords seems to provide
+    // slightly richer formatting.  Another option would be to leave
+    // the language empty, but testing with Sphinx 1.8.5 has produced
+    // an error "1 argument required".
+    codeLanguage = "python";
+  else if (option == ".java")
+    codeLanguage = "java";
+  else if (option == ".c")
+    codeLanguage = "c";
+  else
+    // If there is not a match, or if no option was given, go out on a
+    // limb and assume that the examples in the C or C++ sources use
+    // C++.
+    codeLanguage = "c++";
 
   std::string code;
   handleTagVerbatim(tag, code, arg);
@@ -552,6 +594,27 @@ void PyDocConverter::handleCode(DoxygenEntity &tag, std::string &translatedComme
   // command:
   eraseLeadingNewLine(code);
 
+  // Check for python doctest blocks, and treat them specially:
+  bool isDocTestBlock = false;
+  size_t startPos;
+  // ">>>" would normally appear at the beginning, but doxygen comment
+  // style may have space in front, so skip leading whitespace
+  if ((startPos=code.find_first_not_of(" \t")) != string::npos && code.substr(startPos,3) == ">>>")
+    isDocTestBlock = true;
+
+  string codeIndent;
+  if (! isDocTestBlock) {
+    // Use the current indent for the code-block line itself.
+    translatedComment += indent.getFirstLineIndent();
+    translatedComment += ".. code-block:: " + codeLanguage + "\n\n";
+
+    // Specify the level of extra indentation that will be used for
+    // subsequent lines within the code block.  Note that the correct
+    // "starting indentation" is already present in the input, so we
+    // only need to add the desired code block indentation.
+    codeIndent = m_indent;
+  }
+
   translatedComment += codeIndent;
   for (size_t n = 0; n < code.length(); n++) {
     if (code[n] == '\n') {
@@ -636,8 +699,26 @@ void PyDocConverter::handleTagParam(DoxygenEntity &tag, std::string &translatedC
   const std::string &paramName = paramNameEntity.data;
 
   const std::string paramType = getParamType(paramName);
+  const std::string paramValue = getParamValue(paramName);
+
+  // Get command option, e.g. "in", "out", or "in,out"
+  string commandOpt = getCommandOption(tag.typeOfEntity, '[', ']');
+  if (commandOpt == "in,out") commandOpt = "in/out";
+
+  // If provided, append the parameter direction to the type
+  // information via a suffix:
+  std::string suffix;
+  if (commandOpt.size() > 0)
+    suffix = ", " + commandOpt;
+  
+  // If the parameter has a default value, flag it as optional in the
+  // generated type definition.  Particularly helpful when the python
+  // call is generated with *args, **kwargs.
+  if (paramValue.size() > 0)
+    suffix += ", optional";  
+
   if (!paramType.empty()) {
-    translatedComment += ":type " + paramName + ": " + paramType + "\n";
+    translatedComment += ":type " + paramName + ": " + paramType + suffix + "\n";
     translatedComment += indent.getFirstLineIndent();
   }
 
@@ -909,3 +990,4 @@ String *PyDocConverter::makeDocumentation(Node *n) {
 
   return NewString(pyDocString.c_str());
 }
+
index df8997d..07c5ce5 100644 (file)
@@ -178,6 +178,11 @@ protected:
    */
   std::string getParamType(std::string name);
 
+  /*
+   * Simple helper function to retrieve the parameter value
+   */
+  std::string getParamValue(std::string name);
+
 private:
   // temporary thing, should be refactored somehow
   Node *currentNode;
index 0537edb..da41bfd 100644 (file)
@@ -301,7 +301,7 @@ JAVALDSHARED = @JAVALDSHARED@
 JAVALIBRARYPREFIX = @JAVALIBRARYPREFIX@
 JAVASO = @JAVASO@
 JAVA_CLASSPATH_SEP = @JAVA_CLASSPATH_SEP@
-JAVA_TOOLS_JAR = @JAVA_TOOLS_JAR@
+JAVA_SKIP_DOXYGEN_TEST_CASES = @JAVA_SKIP_DOXYGEN_TEST_CASES@
 JSCENABLED = @JSCENABLED@
 JSCOREDYNAMICLINKING = @JSCOREDYNAMICLINKING@
 JSCOREINC = @JSCOREINC@
@@ -352,6 +352,9 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
 PACKAGE_URL = @PACKAGE_URL@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
+PCHINCLUDEARG = @PCHINCLUDEARG@
+PCHINCLUDEEXT = @PCHINCLUDEEXT@
+PCHSUPPORT = @PCHSUPPORT@
 PCRE_CFLAGS = @PCRE_CFLAGS@
 PCRE_CONFIG = @PCRE_CONFIG@
 PCRE_LIBS = @PCRE_LIBS@
index 17100b3..27cc65b 100644 (file)
@@ -1709,11 +1709,11 @@ public:
    * addInterfaceNameAndUpcasts()
    * ----------------------------------------------------------------------------- */
 
-  void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, String *c_classname) {
+  void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, SwigType *c_classname) {
     List *keys = Keys(base_list);
     for (Iterator it = First(keys); it.item; it = Next(it)) {
       Node *base = Getattr(base_list, it.item);
-      String *c_baseclass = SwigType_namestr(Getattr(base, "name"));
+      SwigType *c_baseclassname = Getattr(base, "name");
       String *interface_name = Getattr(base, "interface:name");
       if (Len(interface_list))
        Append(interface_list, ", ");
@@ -1733,12 +1733,11 @@ public:
       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_baseclass);
+      upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname);
 
       Delete(upcast_method_name);
       Delete(cptr_method_name);
       Delete(interface_code);
-      Delete(c_baseclass);
     }
     Delete(keys);
   }
@@ -1749,7 +1748,7 @@ public:
    * Add code for C++ casting to base class
    * ----------------------------------------------------------------------------- */
 
-  void upcastsCode(SwigType *smart, String *upcast_method_name, String *c_classname, String *c_baseclass) {
+  void upcastsCode(SwigType *smart, 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);
@@ -1757,28 +1756,35 @@ public:
 
     Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name);
 
+    String *classname = SwigType_namestr(c_classname);
+    String *baseclassname = SwigType_namestr(c_baseclassname);
     if (smart) {
-      SwigType *bsmart = Copy(smart);
-      SwigType *rclassname = SwigType_typedef_resolve_all(c_classname);
-      SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass);
-      Replaceall(bsmart, rclassname, rbaseclass);
-      Delete(rclassname);
-      Delete(rbaseclass);
       String *smartnamestr = SwigType_namestr(smart);
-      String *bsmartnamestr = SwigType_namestr(bsmart);
+      String *bsmartnamestr = SwigType_namestr(smart);
+
+      // TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
+      SwigType *rclassname = SwigType_typedef_resolve_all(classname);
+      SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
+      Replaceall(bsmartnamestr, rclassname, rbaseclassname);
+
       Printv(upcasts_code,
          "SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", wname, "(", smartnamestr, " *jarg1) {\n",
          "    return jarg1 ? new ", bsmartnamestr, "(*jarg1) : 0;\n"
          "}\n", "\n", NIL);
+
+      Delete(rbaseclassname);
+      Delete(rclassname);
       Delete(bsmartnamestr);
       Delete(smartnamestr);
-      Delete(bsmart);
     } else {
       Printv(upcasts_code,
-         "SWIGEXPORT ", c_baseclass, " * SWIGSTDCALL ", wname, "(", c_classname, " *jarg1) {\n",
-         "    return (", c_baseclass, " *)jarg1;\n"
+         "SWIGEXPORT ", baseclassname, " * SWIGSTDCALL ", wname, "(", classname, " *jarg1) {\n",
+         "    return (", baseclassname, " *)jarg1;\n"
          "}\n", "\n", NIL);
     }
+
+    Delete(baseclassname);
+    Delete(classname);
     Delete(wname);
   }
 
@@ -1787,10 +1793,9 @@ public:
    * ----------------------------------------------------------------------------- */
 
   void emitProxyClassDefAndCPPCasts(Node *n) {
-    String *c_classname = SwigType_namestr(Getattr(n, "name"));
-    String *c_baseclass = NULL;
+    SwigType *c_classname = Getattr(n, "name");
+    SwigType *c_baseclassname = NULL;
     String *baseclass = NULL;
-    String *c_baseclassname = NULL;
     String *interface_list = NewStringEmpty();
     String *interface_upcasts = NewStringEmpty();
     SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
@@ -1812,12 +1817,13 @@ public:
        Iterator base = First(baselist);
        while (base.item) {
          if (!(GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface"))) {
-           String *baseclassname = Getattr(base.item, "name");
+           SwigType *baseclassname = Getattr(base.item, "name");
            if (!c_baseclassname) {
-             c_baseclassname = baseclassname;
-             baseclass = Copy(getProxyName(baseclassname));
-             if (baseclass)
-               c_baseclass = SwigType_namestr(baseclassname);
+             String *name = getProxyName(baseclassname);
+             if (name) {
+               c_baseclassname = baseclassname;
+               baseclass = name;
+             }
            } else {
              /* Warn about multiple inheritance for additional base class(es) */
              String *proxyclassname = Getattr(n, "classtypeobj");
@@ -1833,7 +1839,7 @@ public:
     if (interface_bases)
       addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname);
 
-    bool derived = baseclass && getProxyName(c_baseclassname);
+    bool derived = baseclass != 0;
     if (derived && purebase_notderived)
       pure_baseclass = empty_string;
     const String *wanted_base = baseclass ? baseclass : pure_baseclass;
@@ -1841,7 +1847,6 @@ public:
     if (purebase_replace) {
       wanted_base = pure_baseclass;
       derived = false;
-      Delete(baseclass);
       baseclass = NULL;
       if (purebase_notderived)
         Swig_error(Getfile(n), Getline(n), "The csbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type);
@@ -2032,12 +2037,11 @@ public:
 
     if (derived) {
       String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
-      upcastsCode(smart, upcast_method_name, c_classname, c_baseclass);
+      upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname);
       Delete(upcast_method_name);
     }
 
     Delete(smart);
-    Delete(baseclass);
   }
 
   /* ----------------------------------------------------------------------
@@ -4064,11 +4068,10 @@ public:
              /* Get the C# parameter type */
              if ((tm = Getattr(p, "tmap:cstype"))) {
                substituteClassname(pt, tm);
-               if (Strncmp(tm, "ref ", 4) == 0) {
-                 Replace(tm, "ref ", "", DOH_REPLACE_FIRST);
+               int flags = DOH_REPLACE_FIRST | DOH_REPLACE_ID_BEGIN | DOH_REPLACE_NOCOMMENT;
+               if (Replace(tm, "ref ", "", flags) || Replace(tm, "ref\t", "", flags)) {
                  Printf(proxy_method_types, "typeof(%s).MakeByRefType()", tm);
-               } else if (Strncmp(tm, "out ", 4) == 0) {
-                 Replace(tm, "out ", "", DOH_REPLACE_FIRST);
+               } else if (Replace(tm, "out ", "", flags) || Replace(tm, "out\t", "", flags)) {
                  Printf(proxy_method_types, "typeof(%s).MakeByRefType()", tm);
                } else {
                  Printf(proxy_method_types, "typeof(%s)", tm);
index 5e82dfd..b7283ea 100644 (file)
@@ -3140,11 +3140,10 @@ private:
      * Handle inheriting from D and C++ classes.
      */
 
-    String *c_classname = SwigType_namestr(Getattr(n, "name"));
-    String *c_baseclass = NULL;
-    Node *basenode = NULL;
-    String *basename = NULL;
+    String *c_classname = Getattr(n, "name");
     String *c_baseclassname = NULL;
+    Node *basenode = NULL;
+    String *baseclass = NULL;
 
     // Inheritance from pure D classes.
     Node *attributes = NewHash();
@@ -3161,13 +3160,14 @@ private:
        Iterator base = First(baselist);
        while (base.item) {
          if (!GetFlag(base.item, "feature:ignore")) {
-           String *baseclassname = Getattr(base.item, "name");
+           SwigType *baseclassname = Getattr(base.item, "name");
            if (!c_baseclassname) {
              basenode = base.item;
-             c_baseclassname = baseclassname;
-             basename = createProxyName(c_baseclassname);
-             if (basename)
-               c_baseclass = SwigType_namestr(baseclassname);
+             String *name = createProxyName(baseclassname);
+             if (name) {
+               c_baseclassname = baseclassname;
+               baseclass = name;
+             }
            } else {
              /* Warn about multiple inheritance for additional base class(es) */
              String *proxyclassname = Getattr(n, "classtypeobj");
@@ -3180,25 +3180,24 @@ private:
       }
     }
 
-    bool derived = (basename != NULL);
+    bool derived = baseclass != NULL;
 
     if (derived && purebase_notderived) {
       pure_baseclass = empty_string;
     }
-    const String *wanted_base = basename ? basename : pure_baseclass;
+    const String *wanted_base = baseclass ? baseclass : pure_baseclass;
 
     if (purebase_replace) {
       wanted_base = pure_baseclass;
       derived = false;
       basenode = NULL;
-      Delete(basename);
-      basename = NULL;
+      baseclass = NULL;
       if (purebase_notderived) {
        Swig_error(Getfile(n), Getline(n),
          "The dbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n",
          typemap_lookup_type);
       }
-    } else if (basename && Len(pure_baseclass) > 0) {
+    } else if (baseclass && Len(pure_baseclass) > 0) {
       Swig_warning(WARN_D_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
        "Warning for %s, base class %s ignored. Multiple inheritance is not supported in D. "
        "Perhaps you need one of the 'replace' or 'notderived' attributes in the dbase typemap?\n", typemap_lookup_type, pure_baseclass);
@@ -3206,7 +3205,7 @@ private:
 
     // 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_baseclass);
+      writeClassUpcast(n, proxy_class_name, c_classname, c_baseclassname);
     }
 
     /*
@@ -3354,8 +3353,7 @@ private:
     // Write the class body and the curly bracket closing the class definition
     // to the proxy module.
     indentCode(body);
-    Replaceall(body, "$dbaseclass", basename);
-    Delete(basename);
+    Replaceall(body, "$dbaseclass", baseclass);
 
     Printv(proxy_class_code, body, "\n}\n", NIL);
     Delete(body);
@@ -3368,7 +3366,7 @@ private:
   /* ---------------------------------------------------------------------------
    * D::writeClassUpcast()
    * --------------------------------------------------------------------------- */
-  void writeClassUpcast(Node *n, const String* d_class_name, String* c_class_name, String* c_base_name) {
+  void writeClassUpcast(Node *n, const String* d_class_name, SwigType* c_classname, SwigType* c_baseclassname) {
 
     SwigType *smart = Swig_cparse_smartptr(n);
     String *upcast_name = Swig_name_member(getNSpace(), d_class_name, (smart != 0 ? "SmartPtrUpcast" : "Upcast"));
@@ -3377,36 +3375,42 @@ private:
     writeImDModuleFunction(upcast_name, "void*", "(void* objectRef)",
       upcast_wrapper_name);
 
+    String *classname = SwigType_namestr(c_classname);
+    String *baseclassname = SwigType_namestr(c_baseclassname);
     if (smart) {
-      SwigType *bsmart = Copy(smart);
-      SwigType *rclassname = SwigType_typedef_resolve_all(c_class_name);
-      SwigType *rbaseclass = SwigType_typedef_resolve_all(c_base_name);
-      Replaceall(bsmart, rclassname, rbaseclass);
-      Delete(rclassname);
-      Delete(rbaseclass);
       String *smartnamestr = SwigType_namestr(smart);
-      String *bsmartnamestr = SwigType_namestr(bsmart);
+      String *bsmartnamestr = SwigType_namestr(smart);
+
+      // TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
+      SwigType *rclassname = SwigType_typedef_resolve_all(classname);
+      SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
+      Replaceall(bsmartnamestr, rclassname, rbaseclassname);
+
       Printv(upcasts_code,
        "SWIGEXPORT ", bsmartnamestr, " * ", upcast_wrapper_name,
          "(", smartnamestr, " *objectRef) {\n",
        "    return objectRef ? new ", bsmartnamestr, "(*objectRef) : 0;\n"
        "}\n",
        "\n", NIL);
+
+      Delete(rbaseclassname);
+      Delete(rclassname);
       Delete(bsmartnamestr);
       Delete(smartnamestr);
-      Delete(bsmart);
     } else {
       Printv(upcasts_code,
-       "SWIGEXPORT ", c_base_name, " * ", upcast_wrapper_name,
-         "(", c_base_name, " *objectRef) {\n",
-       "    return (", c_base_name, " *)objectRef;\n"
+       "SWIGEXPORT ", baseclassname, " * ", upcast_wrapper_name,
+         "(", baseclassname, " *objectRef) {\n",
+       "    return (", baseclassname, " *)objectRef;\n"
        "}\n",
        "\n", NIL);
     }
 
-    Replaceall(upcasts_code, "$cclass", c_class_name);
-    Replaceall(upcasts_code, "$cbaseclass", c_base_name);
+    Replaceall(upcasts_code, "$cclass", classname);
+    Replaceall(upcasts_code, "$cbaseclass", baseclassname);
 
+    Delete(baseclassname);
+    Delete(classname);
     Delete(upcast_name);
     Delete(upcast_wrapper_name);
     Delete(smart);
index fcc8381..7734c64 100644 (file)
@@ -1853,11 +1853,11 @@ public:
    * addInterfaceNameAndUpcasts()
    * ----------------------------------------------------------------------------- */
 
-  void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, String *c_classname) {
+  void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, SwigType *c_classname) {
     List *keys = Keys(base_list);
     for (Iterator it = First(keys); it.item; it = Next(it)) {
       Node *base = Getattr(base_list, it.item);
-      String *c_baseclass = SwigType_namestr(Getattr(base, "name"));
+      SwigType *c_baseclassname = Getattr(base, "name");
       String *interface_name = Getattr(base, "interface:name");
       if (Len(interface_list))
        Append(interface_list, ", ");
@@ -1877,11 +1877,11 @@ public:
       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_baseclass);
+      upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname);
+
       Delete(upcast_method_name);
       Delete(cptr_method_name);
       Delete(interface_code);
-      Delete(c_baseclass);
     }
     Delete(keys);
   }
@@ -1892,19 +1892,23 @@ public:
    * Add code for C++ casting to base class
    * ----------------------------------------------------------------------------- */
 
-  void upcastsCode(SwigType *smart, String *upcast_method_name, String *c_classname, String *c_baseclass) {
+  void upcastsCode(SwigType *smart, 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);
+
+    String *classname = SwigType_namestr(c_classname);
+    String *baseclassname = SwigType_namestr(c_baseclassname);
     if (smart) {
-      SwigType *bsmart = Copy(smart);
-      SwigType *rclassname = SwigType_typedef_resolve_all(c_classname);
-      SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass);
-      Replaceall(bsmart, rclassname, rbaseclass);
-      Delete(rclassname);
-      Delete(rbaseclass);
       String *smartnamestr = SwigType_namestr(smart);
-      String *bsmartnamestr = SwigType_namestr(bsmart);
+      String *bsmartnamestr = SwigType_namestr(smart);
+
+      // TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
+      SwigType *rclassname = SwigType_typedef_resolve_all(classname);
+      SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);
+      Replaceall(bsmartnamestr, rclassname, rbaseclassname);
+
       Printv(upcasts_code,
          "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
          "    jlong baseptr = 0;\n"
@@ -1915,19 +1919,24 @@ public:
          "    *(", bsmartnamestr, " **)&baseptr = argp1 ? new ", bsmartnamestr, "(*argp1) : 0;\n"
          "    return baseptr;\n"
          "}\n", "\n", NIL);
+
+      Delete(rbaseclassname);
+      Delete(rclassname);
       Delete(bsmartnamestr);
       Delete(smartnamestr);
-      Delete(bsmart);
     } else {
       Printv(upcasts_code,
          "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
          "    jlong baseptr = 0;\n"
          "    (void)jenv;\n"
          "    (void)jcls;\n"
-         "    *(", c_baseclass, " **)&baseptr = *(", c_classname, " **)&jarg1;\n"
+         "    *(", baseclassname, " **)&baseptr = *(", classname, " **)&jarg1;\n"
          "    return baseptr;\n"
          "}\n", "\n", NIL);
     }
+
+    Delete(baseclassname);
+    Delete(classname);
     Delete(wname);
     Delete(jniname);
   }
@@ -1937,10 +1946,9 @@ public:
    * ----------------------------------------------------------------------------- */
 
   void emitProxyClassDefAndCPPCasts(Node *n) {
-    String *c_classname = SwigType_namestr(Getattr(n, "name"));
-    String *c_baseclass = NULL;
+    SwigType *c_classname = Getattr(n, "name");
+    SwigType *c_baseclassname = NULL;
     String *baseclass = NULL;
-    String *c_baseclassname = NULL;
     String *interface_list = NewStringEmpty();
     String *interface_upcasts = NewStringEmpty();
     SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
@@ -1962,12 +1970,13 @@ public:
        Iterator base = First(baselist);
        while (base.item) {
          if (!(GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface"))) {
-           String *baseclassname = Getattr(base.item, "name");
+           SwigType *baseclassname = Getattr(base.item, "name");
            if (!c_baseclassname) {
-             c_baseclassname = baseclassname;
-             baseclass = Copy(getProxyName(baseclassname));
-             if (baseclass)
-               c_baseclass = SwigType_namestr(baseclassname);
+             String *name = getProxyName(baseclassname);
+             if (name) {
+               c_baseclassname = baseclassname;
+               baseclass = name;
+             }
            } else {
              /* Warn about multiple inheritance for additional base class(es) */
              String *proxyclassname = Getattr(n, "classtypeobj");
@@ -1984,7 +1993,7 @@ public:
     if (interface_bases)
       addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname);
 
-    bool derived = baseclass && getProxyName(c_baseclassname);
+    bool derived = baseclass != 0;
     if (derived && purebase_notderived)
       pure_baseclass = empty_string;
     const String *wanted_base = baseclass ? baseclass : pure_baseclass;
@@ -1992,7 +2001,6 @@ public:
     if (purebase_replace) {
       wanted_base = pure_baseclass;
       derived = false;
-      Delete(baseclass);
       baseclass = NULL;
       if (purebase_notderived)
         Swig_error(Getfile(n), Getline(n), "The javabase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type);
@@ -2115,12 +2123,11 @@ public:
 
     if (derived) {
       String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
-      upcastsCode(smart, upcast_method_name, c_classname, c_baseclass);
+      upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname);
       Delete(upcast_method_name);
     }
 
     Delete(smart);
-    Delete(baseclass);
   }
 
   /* ----------------------------------------------------------------------
index 72b765b..d8f2ab6 100644 (file)
@@ -1141,9 +1141,9 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
          } else
            f_dependencies_file = stdout;
          if (dependencies_target) {
-           Printf(f_dependencies_file, "%s: ", dependencies_target);
+           Printf(f_dependencies_file, "%s: ", Swig_filename_escape_space(dependencies_target));
          } else {
-           Printf(f_dependencies_file, "%s: ", outfile);
+           Printf(f_dependencies_file, "%s: ", Swig_filename_escape_space(outfile));
          }
          List *files = Preprocessor_depend();
          List *phony_targets = NewList();
@@ -1154,7 +1154,7 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
                 use_file = 0;
             }
             if (use_file) {
-              Printf(f_dependencies_file, "\\\n  %s ", Getitem(files, i));
+              Printf(f_dependencies_file, "\\\n  %s ", Swig_filename_escape_space(Getitem(files, i)));
               if (depend_phony)
                 Append(phony_targets, Getitem(files, i));
             }
@@ -1162,7 +1162,7 @@ int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
          Printf(f_dependencies_file, "\n");
          if (depend_phony) {
            for (int i = 0; i < Len(phony_targets); i++) {
-             Printf(f_dependencies_file, "\n%s:\n", Getitem(phony_targets, i));
+             Printf(f_dependencies_file, "\n%s:\n", Swig_filename_escape_space(Getitem(phony_targets, i)));
            }
          }
 
index 6f2a349..9f7504b 100644 (file)
@@ -1619,7 +1619,7 @@ public:
       /* 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 CAML_VALUE *swig_ocaml_func_val = NULL;\n" "if (!swig_ocaml_func_val) {\n");
+      Printf(w->code, "static const CAML_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 */
index 1297d24..b1769e4 100644 (file)
@@ -567,6 +567,10 @@ public:
     Wrapper *f = NewWrapper();
     Octave_begin_function(n, f->def, iname, overname, !overloaded);
 
+    // Start default try block to execute
+    // cleanup code if exception is thrown
+    Printf(f->code, "try {\n");
+
     emit_parameter_variables(l, f);
     emit_attach_parmmaps(l, f);
     Setattr(n, "wrap:parms", l);
@@ -754,9 +758,20 @@ public:
     }
 
     Printf(f->code, "return _out;\n");
-    Printf(f->code, "fail:\n");        // we should free locals etc if this happens
+
+    // Execute cleanup code if branched to fail: label
+    Printf(f->code, "fail:\n");
     Printv(f->code, cleanup, NIL);
     Printf(f->code, "return octave_value_list();\n");
+
+    // Execute cleanup code if exception was thrown
+    Printf(f->code, "}\n");
+    Printf(f->code, "catch(...) {\n");
+    Printv(f->code, cleanup, NIL);
+    Printf(f->code, "throw;\n");
+    Printf(f->code, "}\n");
+
+    // End wrapper function
     Printf(f->code, "}\n");
 
     /* Substitute the cleanup code */
@@ -830,7 +845,7 @@ public:
     String *setwname = Swig_name_wrapper(setname);
 
     Octave_begin_function(n, setf->def, setname, setwname, true);
-    Printf(setf->def, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();", iname);
+    Printf(setf->code, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();", iname);
     if (is_assignable(n)) {
       Setattr(n, "wrap:name", setname);
       if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
@@ -845,8 +860,9 @@ public:
       } else {
         Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
       }
+      Append(setf->code, "return octave_value_list();\n");
       Append(setf->code, "fail:\n");
-      Printf(setf->code, "return octave_value_list();\n");
+      Append(setf->code, "return octave_value_list();\n");
     } else {
       Printf(setf->code, "return octave_set_immutable(args,nargout);");
     }
@@ -866,10 +882,10 @@ public:
     } else {
       Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
     }
-    Append(getf->code, "  return obj;\n");
+    Append(getf->code, "return obj;\n");
     if (addfail) {
       Append(getf->code, "fail:\n");
-      Append(getf->code, "  return octave_value_list();\n");
+      Append(getf->code, "return octave_value_list();\n");
     }
     Append(getf->code, "}\n");
     Wrapper_print(getf, f_wrappers);
index ea31af0..c8c45df 100644 (file)
@@ -1484,8 +1484,15 @@ public:
 
   String *build_combined_docstring(Node *n, autodoc_t ad_type, const String *indent = "", bool low_level = false) {
     String *docstr = Getattr(n, "feature:docstring");
-    if (docstr && Len(docstr)) {
-      docstr = Copy(docstr);
+    if (docstr) {
+      // Simplify the code below by just ignoring empty docstrings.
+      if (!Len(docstr))
+       docstr = NULL;
+      else
+       docstr = Copy(docstr);
+    }
+
+    if (docstr) {
       char *t = Char(docstr);
       if (*t == '{') {
        Delitem(docstr, 0);
@@ -1496,7 +1503,7 @@ public:
     if (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")) {
       String *autodoc = make_autodoc(n, ad_type, low_level);
       if (autodoc && Len(autodoc) > 0) {
-       if (docstr && Len(docstr)) {
+       if (docstr) {
          Append(autodoc, "\n");
          Append(autodoc, docstr);
        }
@@ -1509,7 +1516,7 @@ public:
       Delete(autodoc);
     }
 
-    if (!docstr || !Len(docstr)) {
+    if (!docstr) {
       if (doxygen) {
        docstr = Getattr(n, "python:docstring");
        if (!docstr && doxygenTranslator->hasDocumentation(n)) {
@@ -1564,7 +1571,8 @@ public:
 
   String *docstring(Node *n, autodoc_t ad_type, const String *indent, bool low_level = false) {
     String *docstr = build_combined_docstring(n, ad_type, indent, low_level);
-    if (!Len(docstr))
+    const int len = Len(docstr);
+    if (!len)
       return docstr;
 
     // Notice that all comments are created as raw strings (prefix "r"),
@@ -1577,9 +1585,32 @@ public:
     // escape '\x'. '\' may additionally appear in verbatim or htmlonly sections
     // of doxygen doc, Latex expressions, ...
     String *doc = NewString("");
-    Append(doc, "r\"\"\"");
+
+    // Determine which kind of quotes to use as delimiters: for single line
+    // strings we can avoid problems with having a quote as the last character
+    // of the docstring by using different kind of quotes as delimiters. For
+    // multi-line strings this problem doesn't arise, as we always have a new
+    // line or spaces at the end of it, but it still does no harm to do it for
+    // them too.
+    //
+    // Note: we use double quotes by default, i.e. if there is no reason to
+    // prefer using single ones, for consistency with the older SWIG versions.
+    const bool useSingleQuotes = (Char(docstr))[len - 1] == '"';
+
+    Append(doc, useSingleQuotes ? "r'''" : "r\"\"\"");
+
+    // We also need to avoid having triple quotes of whichever type we use, as
+    // this would break Python doc string syntax too. Unfortunately there is no
+    // way to have triple quotes inside of raw-triple-quoted string, so we have
+    // to break the string in parts and rely on concatenation of the adjacent
+    // string literals.
+    if (useSingleQuotes)
+      Replaceall(docstr, "'''", "''' \"'''\" '''");
+    else
+      Replaceall(docstr, "\"\"\"", "\"\"\" '\"\"\"' \"\"\"");
+
     Append(doc, docstr);
-    Append(doc, "\"\"\"");
+    Append(doc, useSingleQuotes ? "'''" : "\"\"\"");
     Delete(docstr);
 
     return doc;
@@ -2493,7 +2524,7 @@ public:
     String *symname = Getattr(n, "sym:name");
     String *wname = Swig_name_wrapper(symname);
 
-    const char *builtin_kwargs = builtin_ctor ? ", PyObject *SWIGUNUSEDPARM(kwargs)" : "";
+    const char *builtin_kwargs = builtin_ctor ? ", PyObject *kwargs" : "";
     Printv(f->def, linkage, builtin_ctor ? "int " : "PyObject *", wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
 
     Wrapper_add_local(f, "argc", "Py_ssize_t argc");
@@ -2503,6 +2534,9 @@ public:
     if (!fastunpack) {
       Wrapper_add_local(f, "ii", "Py_ssize_t ii");
 
+      if (builtin_ctor)
+       Printf(f->code, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", symname);
+
       if (maxargs - (add_self ? 1 : 0) > 0) {
         Append(f->code, "if (!PyTuple_Check(args)) SWIG_fail;\n");
         Append(f->code, "argc = PyObject_Length(args);\n");
@@ -2518,8 +2552,9 @@ public:
       if (add_self)
        Append(f->code, "argc++;\n");
     } else {
-      String *iname = Getattr(n, "sym:name");
-      Printf(f->code, "if (!(argc = SWIG_Python_UnpackTuple(args, \"%s\", 0, %d, argv%s))) SWIG_fail;\n", iname, maxargs, add_self ? "+1" : "");
+      if (builtin_ctor)
+       Printf(f->code, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", symname);
+      Printf(f->code, "if (!(argc = SWIG_Python_UnpackTuple(args, \"%s\", 0, %d, argv%s))) SWIG_fail;\n", symname, maxargs, add_self ? "+1" : "");
       if (add_self)
        Append(f->code, "argv[0] = self;\n");
       else
@@ -2700,8 +2735,12 @@ public:
       --tuple_required;
     }
     num_fixed_arguments = tuple_required;
+
+    // builtin handles/checks kwargs by default except in constructor wrappers so we need to explicitly handle them in the C constructor wrapper
+    // The check below is for zero arguments. Sometimes (eg directors) self is the first argument for a method with zero arguments.
     if (((num_arguments == 0) && (num_required == 0)) || ((num_arguments == 1) && (num_required == 1) && Getattr(l, "self")))
-      allow_kwargs = 0;
+      if (!builtin_ctor)
+       allow_kwargs = 0;
     varargs = emit_isvarargs(l);
 
     String *wname = Copy(wrapper_name);
@@ -2709,7 +2748,7 @@ public:
       Append(wname, overname);
     }
 
-    const char *builtin_kwargs = builtin_ctor ? ", PyObject *SWIGUNUSEDPARM(kwargs)" : "";
+    const char *builtin_kwargs = builtin_ctor ? ", PyObject *kwargs" : "";
     if (!allow_kwargs || overname) {
       if (!varargs) {
        Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL);
@@ -2727,7 +2766,7 @@ public:
       }
       Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args, PyObject *kwargs) {", NIL);
     }
-    if (!builtin || !in_class || tuple_arguments > 0) {
+    if (!builtin || !in_class || tuple_arguments > 0 || builtin_ctor) {
       if (!allow_kwargs) {
        Append(parse_args, "    if (!PyArg_ParseTuple(args, \"");
       } else {
@@ -2876,14 +2915,13 @@ public:
       Printv(f->locals, "  char * kwnames[] = ", kwargs, ";\n", NIL);
     }
 
-    if (builtin && !funpack && in_class && tuple_arguments == 0) {
-      Printf(parse_args, "    if (args && PyTuple_Check(args) && PyTuple_GET_SIZE(args) > 0) SWIG_exception_fail(SWIG_TypeError, \"%s takes no arguments\");\n", iname);
-    } else if (use_parse || allow_kwargs) {
+    if (use_parse || allow_kwargs) {
       Printf(parse_args, ":%s\"", iname);
       Printv(parse_args, arglist, ")) SWIG_fail;\n", NIL);
       funpack = 0;
     } else {
       Clear(parse_args);
+
       if (funpack) {
        Clear(f->def);
        if (overname) {
@@ -2896,6 +2934,8 @@ public:
        } else {
          int is_tp_call = Equal(Getattr(n, "feature:python:slot"), "tp_call");
          Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL);
+         if (builtin_ctor)
+           Printf(parse_args, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", iname);
          if (onearg && !builtin_ctor && !is_tp_call) {
            Printf(parse_args, "if (!args) SWIG_fail;\n");
            Append(parse_args, "swig_obj[0] = args;\n");
@@ -2906,8 +2946,14 @@ public:
          }
        }
       } else {
-       Printf(parse_args, "if (!PyArg_UnpackTuple(args, \"%s\", %d, %d", iname, num_fixed_arguments, tuple_arguments);
-       Printv(parse_args, arglist, ")) SWIG_fail;\n", NIL);
+       if (builtin_ctor)
+         Printf(parse_args, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", iname);
+       if (builtin && in_class && tuple_arguments == 0) {
+         Printf(parse_args, "    if (args && PyTuple_Check(args) && PyTuple_GET_SIZE(args) > 0) SWIG_exception_fail(SWIG_TypeError, \"%s takes no arguments\");\n", iname);
+       } else {
+         Printf(parse_args, "if (!PyArg_UnpackTuple(args, \"%s\", %d, %d", iname, num_fixed_arguments, tuple_arguments);
+         Printv(parse_args, arglist, ")) SWIG_fail;\n", NIL);
+       }
       }
     }
 
@@ -4128,6 +4174,13 @@ public:
     Printv(f, "#if PY_VERSION_HEX >= 0x03040000\n", NIL);
     printSlot(f, getSlot(n, "feature:python:tp_finalize"), "tp_finalize", "destructor");
     Printv(f, "#endif\n", NIL);
+    Printv(f, "#if PY_VERSION_HEX >= 0x03080000\n", NIL);
+    printSlot(f, getSlot(n, "feature:python:tp_vectorcall"), "tp_vectorcall", "vectorcallfunc");
+    Printv(f, "#endif\n", NIL);
+    Printv(f, "#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)\n", NIL);
+    printSlot(f, getSlot(), "tp_print");
+    Printv(f, "#endif\n", NIL);
+
     Printv(f, "#ifdef COUNT_ALLOCS\n", NIL);
     printSlot(f, getSlot(n, "feature:python:tp_allocs"), "tp_allocs", "Py_ssize_t");
     printSlot(f, getSlot(n, "feature:python:tp_frees"), "tp_frees", "Py_ssize_t");
index bb43dad..3e3c23e 100644 (file)
@@ -36,11 +36,6 @@ static String * getRTypeName(SwigType *t, int *outCount = NULL) {
   if(Strncmp(b, "struct ", 7) == 0)
     Replace(b, "struct ", "", DOH_REPLACE_FIRST);
 
-  /* Printf(stdout, "<getRTypeName> %s,base = %s\n", t, b);
-     for(i = 0; i < Len(els); i++)
-     Printf(stdout, "%d) %s, ", i, Getitem(els,i));
-     Printf(stdout, "\n"); */
-
   for(i = 0; i < Len(els); i++) {
     String *el = Getitem(els, i);
     if(Strcmp(el, "p.") == 0 || Strncmp(el, "a(", 2) == 0) {
@@ -56,13 +51,6 @@ static String * getRTypeName(SwigType *t, int *outCount = NULL) {
   Insert(tmp, 0, retName);
   return tmp;
 
-  /*
-    if(count)
-    return(b);
-
-    Delete(b);
-    return(NewString(""));
-  */
 }
 
 /* --------------------------------------------------------------
@@ -101,7 +89,6 @@ static String *getRClassName(String *retType, int deRef=0, int upRef=0) {
 static String * getRClassNameCopyStruct(String *retType, int addRef) {
   String *tmp = NewString("");
 
-#if 1
   List *l = SwigType_split(retType);
   int n = Len(l);
   if(!l || n == 0) {
@@ -127,24 +114,6 @@ static String * getRClassNameCopyStruct(String *retType, int addRef) {
     }
   }
 
-#else
-  char *retName = Char(SwigType_manglestr(retType));
-  if(!retName)
-    return(tmp);
-
-  if(addRef) {
-    while(retName && strlen(retName) > 1 &&
-         strncmp(retName, "_p", 2) == 0)  {
-      retName += 2;
-      Printf(tmp, "Ref");
-    }
-  }
-
-  if(retName[0] == '_')
-    retName ++;
-  Insert(tmp, 0, retName);
-#endif
-
   return tmp;
 }
 
@@ -285,12 +254,7 @@ protected:
   int generateCopyRoutines(Node *n);
   int DumpCode(Node *n);
 
-  int OutputMemberReferenceMethod(String *className, int isSet, List *el, File *out);
-  int OutputArrayMethod(String *className, List *el, File *out);
-  int OutputClassMemberTable(Hash *tb, File *out);
-  int OutputClassMethodsTable(File *out);
-  int OutputClassAccessInfo(Hash *tb, File *out);
-
+  int OutputMemberReferenceMethod(String *className, int isSet, List *memberList, List *nameList, List *typeList, File *out);
   int defineArrayAccessors(SwigType *type);
 
   void addNamespaceFunction(String *name) {
@@ -334,10 +298,14 @@ protected:
 
 
   void addAccessor(String *memberName, Wrapper *f,
-                  String *name, int isSet = -1);
+                  String *name, String *methodSetGet);
 
   static int getFunctionPointerNumArgs(Node *n, SwigType *tt);
 
+  // filtering of class member lists by function type. Used in constructing accessors
+  // are we allowed to use stl style functors to customise this?
+  List* filterMemberList(List *class_member_function_types, List *class_member_other, String *R_MEMBER, bool equal);
+
 protected:
   bool copyStruct;
   bool memoryProfile;
@@ -367,11 +335,18 @@ protected:
   String *member_name;
   String *class_name;
 
+  String *R_MEMBER_NORMAL;
+  String *R_MEMBER_SET;
+  String *R_MEMBER_GET;
 
   int processing_class_member_function;
-  List *class_member_functions;
-  List *class_member_set_functions;
-
+  // Spread out the lists so that they are simpler to process
+  // by storing the type of the method (i.e. set, get or nothing)
+  // and having separate lists for name, membername and wrapper
+  List *class_member_function_types;
+  List *class_member_function_names;
+  List *class_member_function_membernames;
+  List *class_member_function_wrappernames;
   /* */
   Hash *ClassMemberTable;
   Hash *ClassMethodsTable;
@@ -429,9 +404,14 @@ R::R() :
   processing_member_access_function(0),
   member_name(0),
   class_name(0),
+  R_MEMBER_NORMAL(NewString("normal")),
+  R_MEMBER_SET(NewString("set")),
+  R_MEMBER_GET(NewString("get")),
   processing_class_member_function(0),
-  class_member_functions(0),
-  class_member_set_functions(0),
+  class_member_function_types(0),
+  class_member_function_names(0),
+  class_member_function_membernames(0),
+  class_member_function_wrappernames(0),
   ClassMemberTable(0),
   ClassMethodsTable(0),
   SClassDefs(0),
@@ -510,7 +490,7 @@ String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) {
   SwigType *funcparams = SwigType_functionpointer_decompose(rettype);
   String *rtype = SwigType_str(rettype, 0);
 
-  //   ParmList *parms = Getattr(n, "parms");
+  // ParmList *parms = Getattr(n, "parms");
   // memory leak
   ParmList *parms = SwigType_function_parms(SwigType_del_pointer(Copy(t)), n);
 
@@ -720,18 +700,6 @@ void R::init() {
 }
 
 
-
-#if 0
-int R::cDeclaration(Node *n) {
-  SwigType *t = Getattr(n, "type");
-  SwigType *name = Getattr(n, "name");
-  if (debugMode)
-    Printf(stdout, "cDeclaration (%s): %s\n", name, SwigType_lstr(t, 0));
-  return Language::cDeclaration(n);
-}
-#endif
-
-
 /* -------------------------------------------------------------
  *  Method from Language that is called to start the entire
  *  processing off, i.e. the generation of the code.
@@ -755,6 +723,8 @@ int R::top(Node *n) {
     Swig_register_filebyname("snamespace", s_namespace);
     Printf(s_namespace, "useDynLib(%s)\n", DllName);
   }
+  // Register the naming functions
+  Swig_name_register("wrapper", "R_swig_%f");
 
   /* Associate the different streams with names so that they can be used in %insert directives by the
      typemap code. */
@@ -888,7 +858,33 @@ int R::DumpCode(Node *n) {
 }
 
 
+List *R::filterMemberList(List *class_member_types, 
+                          List *class_member_other, 
+                          String *R_MEMBER, bool equal) {
+  // filters class_member_other based on whether corresponding elements of
+  // class_member_function_types are equal or notequal to R_MEMBER
+  List *CM = NewList();
+  Iterator ftype, other;
+
+  for (ftype = First(class_member_types), other = First(class_member_other);
+       ftype.item; 
+       ftype=Next(ftype), other=Next(other)) {
+    // verbose, clean up later if the overall structure works
+    if (equal) {
+      if (ftype.item == R_MEMBER) {
+        Append(CM, other.item);
+      }
+    } else {
+      if (ftype.item != R_MEMBER) {
+        Append(CM, other.item);
+      }
+    }
+  }
+  return(CM);
+}
 
+# if 0
+// not called
 /* -------------------------------------------------------------
  * We may need to do more.... so this is left as a
  * stub for the moment.
@@ -975,9 +971,6 @@ int R::OutputClassMemberTable(Hash *tb, File *out) {
       isSet = strcmp(ptr, "_set") == 0;
     }
 
-    //        OutputArrayMethod(className, el, out);  
-    OutputMemberReferenceMethod(className, isSet, el, out);
-
     if(outputNamespaceInfo)
       Printf(s_namespace, "\"%s\"%s", className, i < n-1 ? "," : "");
   }
@@ -988,6 +981,8 @@ int R::OutputClassMemberTable(Hash *tb, File *out) {
   return n;
 }
 
+// end not used
+#endif
 /* --------------------------------------------------------------
  * Write the methods for $ or $<- for accessing a member field in an
  * struct or union (or class).
@@ -1000,9 +995,10 @@ int R::OutputClassMemberTable(Hash *tb, File *out) {
  * out - the stream where we write the code.
  * --------------------------------------------------------------*/
 
-int R::OutputMemberReferenceMethod(String *className, int isSet,
-                                  List *el, File *out) {
-  int numMems = Len(el), j;
+int R::OutputMemberReferenceMethod(String *className, int isSet,  
+                                  List *memberList, List *nameList,
+                                  List *typeList, File *out) {
+  int numMems = Len(memberList), j;
   int varaccessor = 0;
   if (numMems == 0)
     return SWIG_OK;
@@ -1017,13 +1013,12 @@ int R::OutputMemberReferenceMethod(String *className, int isSet,
 
   Node *itemList = NewHash();
   bool has_prev = false;
-  for(j = 0; j < numMems; j+=3) {
-    String *item = Getitem(el, j);
-    String *dup = Getitem(el, j + 1);
-    char *ptr = Char(dup);
-    ptr = &ptr[Len(dup) - 3];
+  for(j = 0; j < numMems; j++) {
+    String *item = Getitem(memberList, j);
+    String *dup = Getitem(nameList, j);
+    String *setgetmethod = Getitem(typeList, j);
 
-    if (!strcmp(ptr, "get"))
+    if (setgetmethod == R_MEMBER_GET)
       varaccessor++;
 
     if (Getattr(itemList, item))
@@ -1053,30 +1048,20 @@ int R::OutputMemberReferenceMethod(String *className, int isSet,
 
   if (!isSet && varaccessor > 0) {
     Printf(f->code, "%svaccessors = c(", tab8);
-    int first = 1;
-    for(j = 0; j < numMems; j+=3) {
-      String *item = Getitem(el, j);
-      String *dup = Getitem(el, j + 1);
-      char *ptr = Char(dup);
-      ptr = &ptr[Len(dup) - 3];
-
-      if (!strcmp(ptr, "get")) {
+    bool first = true;
+    for(j = 0; j < numMems; j++) {
+      String *item = Getitem(memberList, j);
+      String *setgetmethod = Getitem(typeList, j);
+
+      // Check the type here instead of the name
+      if (setgetmethod == R_MEMBER_GET) {
        Printf(f->code, "%s'%s'", first ? "" : ", ", item);
-       first = 0;
+       first = false;
       }
     }
     Printf(f->code, ");\n");
   }
 
-
-  /*    Printv(f->code, tab8,
-       "idx = pmatch(name, names(accessorFuns))\n",
-       tab8,
-       "if(is.na(idx)) {\n",
-       tab8, tab4,
-       "stop(\"No ", (isSet ? "modifiable" : "accessible"), " field named \", name, \" in ", className,
-       ": fields are \", paste(names(accessorFuns), sep = \", \")",
-       ")", "\n}\n", NIL); */
   Printv(f->code, ";", tab8,
         "idx = pmatch(name, names(accessorFuns));\n",
         tab8,
@@ -1098,8 +1083,8 @@ int R::OutputMemberReferenceMethod(String *className, int isSet,
   }
   Printf(f->code, "}\n");
 
-
-  Printf(out, "# Start of accessor method for %s\n", className);
+  String *classname_str = SwigType_namestr(className);
+  Printf(out, "# Start of accessor method for %s\n", classname_str);
   Printf(out, "setMethod('$%s', '_p%s', ",
         isSet ? "<-" : "",
         getRClassName(className));
@@ -1115,54 +1100,15 @@ int R::OutputMemberReferenceMethod(String *className, int isSet,
     Printf(out, ");\n");
   }
 
+  Printf(out, "# end of accessor method for %s\n", classname_str);
+
+  Delete(classname_str);
   DelWrapper(attr);
   DelWrapper(f);
 
-  Printf(out, "# end of accessor method for %s\n", className);
-
-  return SWIG_OK;
-}
-
-/* -------------------------------------------------------------
- * Write the methods for [ or [<- for accessing a member field in an
- * struct or union (or class).
- * className - the name of the struct or union (e.g. Bar for struct Bar)
- * el - a list of length  2 * # accessible member elements  + 1.
- *     The first element is the name of the class.
- *     The other pairs are  member name and the name of the R function to access it.
- * out - the stream where we write the code.
- * --------------------------------------------------------------*/
-
-int R::OutputArrayMethod(String *className, List *el, File *out) {
-  int numMems = Len(el), j;
-
-  if(!el || numMems == 0)
-    return(0);
-
-  Printf(out, "# start of array methods for %s\n", className);
-  for(j = 0; j < numMems; j+=3) {
-    String *item = Getitem(el, j);
-    String *dup = Getitem(el, j + 1);
-    if (!Strcmp(item, "__getitem__")) {
-      Printf(out,
-            "setMethod('[', '_p%s', function(x, i, j, ..., drop =TRUE) ",
-            getRClassName(className));
-      Printf(out, "  sapply(i, function (n)  %s(x, as.integer(n-1))))\n\n", dup);
-    }
-    if (!Strcmp(item, "__setitem__")) {
-      Printf(out, "setMethod('[<-', '_p%s', function(x, i, j, ..., value)",
-            getRClassName(className));
-      Printf(out, "  sapply(1:length(i), function(n) %s(x, as.integer(i[n]-1), value[n])))\n\n", dup);
-    }
-
-  }
-
-  Printf(out, "# end of array methods for %s\n", className);
-
   return SWIG_OK;
 }
 
-
 /* -------------------------------------------------------------
  * Called when a enumeration is to be processed.
  * We want to call the R function defineEnumeration().
@@ -1207,7 +1153,6 @@ int R::enumDeclaration(Node *n) {
     Printf(enum_def_calls, "defineEnumeration(\"%s\",\n .values=c(%s))\n\n", ename, enum_values);
     Delete(enum_values);
     Delete(ename);
-    //Delete(symname);
   }
   return SWIG_OK;
 }
@@ -1335,31 +1280,21 @@ int R::variableWrapper(Node *n) {
  * --------------------------------------------------------------*/
 
 void R::addAccessor(String *memberName, Wrapper *wrapper, String *name,
-                   int isSet) {
-  if(isSet < 0) {
-    int n = Len(name);
-    char *ptr = Char(name);
-    if (n>4) {
-      isSet = Strcmp(NewString(&ptr[n-4]), "_set") == 0;
-    }
-  }
-
-  List *l = isSet ? class_member_set_functions : class_member_functions;
+                   String *methodSetGet) {
 
-  if(!l) {
-    l = NewList();
-    if(isSet)
-      class_member_set_functions = l;
-    else
-      class_member_functions = l;
+  if (!class_member_function_names) {
+    class_member_function_names = NewList();
+    class_member_function_membernames = NewList();
+    class_member_function_wrappernames = NewList();
+    class_member_function_types = NewList();
   }
-
-  Append(l, memberName);
-  Append(l, name);
-
+  Append(class_member_function_types, methodSetGet);
+  Append(class_member_function_names, name);
+  Append(class_member_function_membernames, memberName);
+  
   String *tmp = NewString("");
   Wrapper_print(wrapper, tmp);
-  Append(l, tmp);
+  Append(class_member_function_wrappernames, tmp);
   // if we could put the wrapper in directly:       Append(l, Copy(sfun));
   if (debugMode)
     Printf(stdout, "Adding accessor: %s (%s) => %s\n", memberName, name, tmp);
@@ -1390,11 +1325,6 @@ List * R::Swig_overload_rank(Node *n,
       c = Getattr(c,"sym:nextSibling");
       continue;
     }
-    /*    if (SmartPointer && Getattr(c,"cplus:staticbase")) {
-         c = Getattr(c,"sym:nextSibling");
-         continue;
-         } */
-
     /* Make a list of all the declarations (methods) that are overloaded with
      * this one particular method name */
 
@@ -1815,14 +1745,9 @@ int R::functionWrapper(Node *n) {
     /* Add the name of this member to a list for this class_name.
        We will dump all these at the end. */
 
-    int n = Len(iname);
-    char *ptr = Char(iname);
-    bool isSet(0);
-    if (n > 4) isSet = Strcmp(NewString(&ptr[n-4]), "_set") == 0;
+    bool isSet(GetFlag(n, "memberset"));
 
-
-    String *tmp = NewString("");
-    Printf(tmp, "%s_%s", class_name, isSet ? "set" : "get");
+    String *tmp = NewString(isSet ? Swig_name_set(NSPACE_TODO, class_name) : Swig_name_get(NSPACE_TODO, class_name));
 
     List *memList = Getattr(ClassMemberTable, tmp);
     if(!memList) {
@@ -1839,7 +1764,7 @@ int R::functionWrapper(Node *n) {
   int nargs;
 
   String *wname = Swig_name_wrapper(iname);
-  Replace(wname, "_wrap", "R_swig", DOH_REPLACE_FIRST);
+
   if(overname)
     Append(wname, overname);
   Setattr(n,"wrap:name", wname);
@@ -1859,11 +1784,6 @@ int R::functionWrapper(Node *n) {
   if(!isVoidReturnType)
     addCopyParam = addCopyParameter(rtype);
 
-
-  // Can we get the nodeType() of the type node! and see if it is a struct.
-  //    int addCopyParam = SwigType_isclass(rtype);
-
-  //    if(addCopyParam)
   if (debugMode)
     Printf(stdout, "Adding a .copy argument to %s for %s = %s\n",
           iname, type, addCopyParam ? "yes" : "no");
@@ -1978,7 +1898,7 @@ int R::functionWrapper(Node *n) {
               name, " = getNativeSymbolInfo(", name, ");",
               "\n};\n",
               "if(is(", name, ", \"NativeSymbolInfo\")) {\n",
-              name, " = ", name, "$address", ";\n}\n",
+              name, " = ", name, "$address", ";\n};\n",
               "if(is(", name, ", \"ExternalReference\")) {\n",
               name, " = ", name, "@ref;\n}\n",
               "}; \n",
@@ -2065,7 +1985,9 @@ int R::functionWrapper(Node *n) {
   for (p = l; p;) {
     if ((tm = Getattr(p, "tmap:freearg"))) {
       Replaceall(tm, "$source", Getattr(p, "lname"));
-      Printv(cleanup, tm, "\n", NIL);
+      if (tm && (Len(tm) != 0)) {
+        Printv(cleanup, tm, "\n", NIL);
+      }
       p = Getattr(p, "tmap:freearg:next");
     } else {
       p = nextSibling(p);
@@ -2112,18 +2034,7 @@ int R::functionWrapper(Node *n) {
       Replaceall(tm,"$owner", "0");
     }
 
-#if 0
-    if(addCopyParam) {
-      Printf(f->code, "if(LOGICAL(s_swig_copy)[0]) {\n");
-      Printf(f->code, "/* Deal with returning a reference. */\nr_ans = R_NilValue;\n");
-      Printf(f->code, "}\n else {\n");
-    }
-#endif
     Printf(f->code, "%s\n", tm);
-#if 0
-    if(addCopyParam)
-      Printf(f->code, "}\n"); /* end of if(s_swig_copy) ... else { ... } */
-#endif
 
   } else {
     Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
@@ -2157,8 +2068,10 @@ int R::functionWrapper(Node *n) {
   }
 
   /* Output cleanup code */
-  Printv(f->code, cleanup, NIL);
-  Delete(cleanup);
+  int need_cleanup = Len(cleanup) != 0;
+  if (need_cleanup) {
+    Printv(f->code, cleanup, NIL);
+  }
 
   /* Look to see if there is any newfree cleanup code */
   if (GetFlag(n, "feature:new")) {
@@ -2207,7 +2120,7 @@ int R::functionWrapper(Node *n) {
        {
          String *finalizer = NewString(iname);
          Replace(finalizer, "new_", "", DOH_REPLACE_FIRST);
-         Printf(sfun->code, "reg.finalizer(ans@ref, delete_%s)\n", finalizer);
+         Printf(sfun->code, "reg.finalizer(ans@ref, delete_%s);\n", finalizer);
        }
       Printf(sfun->code, "ans\n");
     }
@@ -2215,7 +2128,18 @@ int R::functionWrapper(Node *n) {
   if (destructor)
     Printv(f->code, "R_ClearExternalPtr(self);\n", NIL);
 
-  Printv(f->code, "return r_ans;\n}\n", NIL);
+  Printv(f->code, "return r_ans;\n", NIL);
+  
+  /* Error handling code */
+  Printv(f->code, "fail: SWIGUNUSED;\n", NIL);
+  if (need_cleanup) {
+    Printv(f->code, cleanup, NIL);
+  }
+  Printv(f->code, "  Rf_error(\"%s %s\", SWIG_ErrorType(SWIG_lasterror_code), SWIG_lasterror_msg);\n", NIL);
+  Printv(f->code, "  return R_NilValue;\n", NIL);
+  Delete(cleanup);
+  
+  Printv(f->code, "}\n", NIL);
   Printv(sfun->code, "\n}", NIL);
 
   /* Substitute the function name */
@@ -2261,7 +2185,13 @@ int R::functionWrapper(Node *n) {
      Would like to be able to do this so that we can potentially insert
   */
   if(processing_member_access_function || processing_class_member_function) {
-    addAccessor(member_name, sfun, iname);
+    String *method_type = R_MEMBER_NORMAL;
+    if (GetFlag(n, "memberset")) {
+      method_type = R_MEMBER_SET;
+    } else if (GetFlag(n, "memberget")) {
+      method_type = R_MEMBER_GET;
+    }
+    addAccessor(member_name, sfun, iname, method_type);
   }
 
   if (Getattr(n, "sym:overloaded") &&
@@ -2455,20 +2385,49 @@ int R::classDeclaration(Node *n) {
   opaqueClassDeclaration = NULL;
 
 
-  // OutputArrayMethod(name, class_member_functions, sfile);
-  if (class_member_functions)
-    OutputMemberReferenceMethod(name, 0, class_member_functions, sfile);
-  if (class_member_set_functions)
-    OutputMemberReferenceMethod(name, 1, class_member_set_functions, sfile);
+  if (class_member_function_types) {
 
-  if(class_member_functions) {
-    Delete(class_member_functions);
-    class_member_functions = NULL;
-  }
-  if(class_member_set_functions) {
-    Delete(class_member_set_functions);
-    class_member_set_functions = NULL;
-  }
+    // collect the "set" methods
+    List *class_set_membernames   = filterMemberList(class_member_function_types, 
+                                                     class_member_function_membernames, R_MEMBER_SET, true);
+    List *class_set_functionnames = filterMemberList(class_member_function_types, 
+                                                     class_member_function_names, R_MEMBER_SET, true);
+    // this one isn't used - collecting to keep code simpler
+    List *class_set_functiontypes = filterMemberList(class_member_function_types, 
+                                                     class_member_function_types, R_MEMBER_SET, true);
+
+    // collect the others
+    List *class_other_membernames   = filterMemberList(class_member_function_types, 
+                                                       class_member_function_membernames, R_MEMBER_SET, false);
+    List *class_other_functionnames = filterMemberList(class_member_function_types, 
+                                                       class_member_function_names, R_MEMBER_SET, false);
+    List *class_other_functiontypes = filterMemberList(class_member_function_types, 
+                                                       class_member_function_types, R_MEMBER_SET, false);
+
+    if (Len(class_other_membernames) > 0) {
+      OutputMemberReferenceMethod(name, 0, class_other_membernames, class_other_functionnames, class_other_functiontypes, sfile);
+    }
+    if (Len(class_set_membernames) > 0) {
+      OutputMemberReferenceMethod(name, 1, class_set_membernames, class_set_functionnames, class_set_functiontypes, sfile);
+    }
+    Delete(class_set_membernames);
+    Delete(class_set_functionnames);
+    Delete(class_set_functiontypes);
+    Delete(class_other_membernames);
+    Delete(class_other_functionnames);
+    Delete(class_other_functiontypes);
+ }
+
+  if (class_member_function_types) {
+    Delete(class_member_function_types);
+    class_member_function_types = NULL;
+    Delete(class_member_function_names);
+    class_member_function_names = NULL;
+    Delete(class_member_function_membernames);
+    class_member_function_membernames = NULL;
+    Delete(class_member_function_wrappernames);
+    class_member_function_wrappernames = NULL;
+   }
   if (Getattr(n, "has_destructor")) {
     Printf(sfile, "setMethod('delete', '_p%s', function(obj) {delete%s(obj)})\n", getRClassName(name), getRClassName(name));
 
@@ -2494,9 +2453,6 @@ int R::classDeclaration(Node *n) {
        c = nextSibling(c);
        continue;
       }
-#if 0
-      tp = getRType(c);
-#else
       tp = Swig_typemap_lookup("rtype", c, "", 0);
       if(!tp) {
        c = nextSibling(c);
@@ -2523,7 +2479,7 @@ int R::classDeclaration(Node *n) {
       // returns ""  tp = processType(elType, c, NULL);
       //           Printf(stdout, "<classDeclaration> elType %p\n", elType);
       //           tp = getRClassNameCopyStruct(Getattr(c, "type"), 1);
-#endif
+
       String *elNameT = replaceInitialDash(elName);
       Printf(def, "%s%s = \"%s\"", tab8, elNameT, tp);
       firstItem = false;
@@ -2884,10 +2840,6 @@ String * R::processType(SwigType *t, Node *n, int *nargs) {
     return tmp;
   }
 
-#if 0
-  SwigType_isfunction(t) && SwigType_ispointer(t)
-#endif
-
     return NULL;
 }
 
index 6a1e16d..48b0efa 100644 (file)
@@ -2191,6 +2191,12 @@ public:
     String *tm;
     String *getfname, *setfname;
     Wrapper *getf, *setf;
+    const int assignable = is_assignable(n);
+
+    // Determine whether virtual global variables shall be used
+    // which have different getter and setter signatures,
+    // see https://docs.ruby-lang.org/en/2.6.0/extension_rdoc.html#label-Global+Variables+Shared+Between+C+and+Ruby
+    const bool use_virtual_var = (current == NO_CPP && useGlobalModule);
 
     getf = NewWrapper();
     setf = NewWrapper();
@@ -2201,7 +2207,7 @@ public:
     getfname = Swig_name_wrapper(getname);
     Setattr(n, "wrap:name", getfname);
     Printv(getf->def, "SWIGINTERN VALUE\n", getfname, "(", NIL);
-    Printf(getf->def, "VALUE self");
+    Printf(getf->def, (use_virtual_var) ? "ID id, VALUE *data" : "VALUE self");
     Printf(getf->def, ") {");
     Wrapper_add_local(getf, "_val", "VALUE _val");
 
@@ -2224,8 +2230,8 @@ public:
 
     Wrapper_print(getf, f_wrappers);
 
-    if (!is_assignable(n)) {
-      setfname = NewString("NULL");
+    if (!assignable) {
+      setfname = NewString("(rb_gvar_setter_t *)NULL");
     } else {
       /* create setter */
       String* docs = docstring(n, AUTODOC_SETTER);
@@ -2235,8 +2241,12 @@ public:
       String *setname = Swig_name_set(NSPACE_TODO, iname);
       setfname = Swig_name_wrapper(setname);
       Setattr(n, "wrap:name", setfname);
-      Printv(setf->def, "SWIGINTERN VALUE\n", setfname, "(VALUE self, ", NIL);
-      Printf(setf->def, "VALUE _val) {");
+      Printf(setf->def, "SWIGINTERN ");
+      if (use_virtual_var) {
+        Printv(setf->def, "void\n", setfname, "(VALUE _val, ID id, VALUE *data) {", NIL);
+      } else {
+        Printv(setf->def, "VALUE\n", setfname, "(VALUE self, VALUE _val) {", NIL);
+      }
       tm = Swig_typemap_lookup("varin", n, name, 0);
       if (tm) {
        Replaceall(tm, "$input", "_val");
@@ -2247,28 +2257,31 @@ public:
       } else {
        Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s\n", SwigType_str(t, 0));
       }
-      Printv(setf->code, tab4, "return _val;\n", NIL);
-      Printf(setf->code, "fail:\n");
-      Printv(setf->code, tab4, "return Qnil;\n", NIL);
+      if (use_virtual_var) {
+        Printf(setf->code, "fail:\n");
+        Printv(setf->code, tab4, "return;\n", NIL);
+      } else {
+        Printv(setf->code, tab4, "return _val;\n", NIL);
+        Printf(setf->code, "fail:\n");
+        Printv(setf->code, tab4, "return Qnil;\n", NIL);
+      }
       Printf(setf->code, "}\n");
       Wrapper_print(setf, f_wrappers);
       Delete(setname);
     }
 
-    /* define accessor method */
-    if (CPlusPlus) {
-      Insert(getfname, 0, "VALUEFUNC(");
-      Append(getfname, ")");
-      Insert(setfname, 0, "VALUEFUNC(");
-      Append(setfname, ")");
-    }
+    /* define accessor methods */
+    Insert(getfname, 0, "VALUEFUNC(");
+    Append(getfname, ")");
+    Insert(setfname, 0, (use_virtual_var) ? "SWIG_RUBY_VOID_ANYARGS_FUNC(" : "VALUEFUNC(");
+    Append(setfname, ")");
 
     String *s = NewString("");
     switch (current) {
     case STATIC_VAR:
       /* C++ class variable */
       Printv(s, tab4, "rb_define_singleton_method(", klass->vname, ", \"", klass->strip(iname), "\", ", getfname, ", 0);\n", NIL);
-      if (!GetFlag(n, "feature:immutable")) {
+      if (assignable) {
        Printv(s, tab4, "rb_define_singleton_method(", klass->vname, ", \"", klass->strip(iname), "=\", ", setfname, ", 1);\n", NIL);
       }
       Printv(klass->init, s, NIL);
@@ -2279,14 +2292,11 @@ public:
       assert(current == NO_CPP);
       if (!useGlobalModule) {
        Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "\", ", getfname, ", 0);\n", NIL);
-       if (!GetFlag(n, "feature:immutable")) {
+       if (assignable) {
          Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "=\", ", setfname, ", 1);\n", NIL);
        }
       } else {
-       Printv(s, tab4, "rb_define_global_method(\"", iname, "\", ", getfname, ", 0);\n", NIL);
-       if (!GetFlag(n, "feature:immutable")) {
-         Printv(s, tab4, "rb_define_global_method(\"", iname, "=\", ", setfname, ", 1);\n", NIL);
-       }
+       Printv(s, tab4, "rb_define_virtual_variable(\"$", iname, "\", ", getfname, ", ", setfname, ");\n", NIL);
       }
       Printv(f_init, s, NIL);
       Delete(s);
index 8d52af1..84ac742 100644 (file)
@@ -163,7 +163,7 @@ static void merge_options_files(int *argc, char ***argv) {
   i = 1;
   while (i < new_argc) {
     if (new_argv[i] && new_argv[i][0] == '@' && (f = fopen(&new_argv[i][1], "r"))) {
-      char c;
+      int ci;
       char *b;
       char *be = &buffer[BUFFER_SIZE];
       int quote = 0;
@@ -174,7 +174,8 @@ static void merge_options_files(int *argc, char ***argv) {
       insert = i;
       b = buffer;
 
-      while ((c = fgetc(f)) != EOF) {
+      while ((ci = fgetc(f)) != EOF) {
+        const char c = static_cast<char>(ci);
         if (escape) {
           if (b != be) {
             *b = c;
index 8dbf086..dc84cf9 100644 (file)
@@ -267,6 +267,8 @@ class TypePass:private Dispatcher {
               and smart pointer to base class, so that smart pointer upcasts
               are automatically generated. */
            SwigType *bsmart = Copy(smart);
+
+           // TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates
            SwigType *rclsname = SwigType_typedef_resolve_all(clsname);
            SwigType *rbname = SwigType_typedef_resolve_all(bname);
            int replace_count = Replaceall(bsmart, rclsname, rbname);
@@ -276,6 +278,12 @@ class TypePass:private Dispatcher {
              String *firstname = Getattr(first, "name");
              Replaceall(bsmart, firstname, rbname);
            }
+           // The code above currently creates a smartptr of the base class by substitution, replacing Derived
+           // with Base resulting in something like: 'smartptr< Derived >' from 'smartptr< Base >'. Instead
+           // the feature:smartptr should be used as it also contains 'smartptr< Base >' as specified by the user.
+           // A similar fix should also be done in upcastsCode in java.cxx, csharp.cxx and writeClassUpcast in d.cxx.
+           // Printf(stdout, "smartcomparison %s <=> %s\n", SwigType_namestr(bsmart), Getattr(bclass, "feature:smartptr"));
+
            Delete(rclsname);
            Delete(rbname);
            String *smartnamestr = SwigType_namestr(smart);
index 7b81847..ef6fcc0 100644 (file)
@@ -250,6 +250,19 @@ String *Swig_filename_escape(String *filename) {
 }
 
 /* -----------------------------------------------------------------------------
+ * Swig_filename_escape()
+ *
+ * Escapes spaces in filename - for Makefiles
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_filename_escape_space(String *filename) {
+  String *adjusted_filename = Copy(filename);
+  Swig_filename_correct(adjusted_filename);
+  Replaceall(adjusted_filename, " ", "\\ ");
+  return adjusted_filename;
+}
+
+/* -----------------------------------------------------------------------------
  * Swig_filename_unescape()
  *
  * Remove double backslash escaping in filename - for Windows
index e0783da..7669126 100644 (file)
@@ -315,6 +315,7 @@ extern int        ParmList_is_compactdefargs(ParmList *p);
   extern String *Swig_new_subdirectory(String *basedirectory, String *subdirectory);
   extern void Swig_filename_correct(String *filename);
   extern String *Swig_filename_escape(String *filename);
+  extern String *Swig_filename_escape_space(String *filename);
   extern void Swig_filename_unescape(String *filename);
   extern int Swig_storage_isextern(Node *n);
   extern int Swig_storage_isexternc(Node *n);
index 37ef841..e25b85f 100755 (executable)
@@ -13,7 +13,7 @@ if [[ -n "$GCC" ]]; then
        travis_retry sudo apt-get install -qq g++-$GCC
 fi
 
-travis_retry sudo apt-get -qq install libboost-dev
+travis_retry sudo apt-get -qq install libboost-dev libpcre3-dev
 
 WITHLANG=$SWIGLANG
 
@@ -23,8 +23,8 @@ case "$SWIGLANG" in
                travis_retry sudo apt-get -qq install mono-devel
                ;;
        "d")
-               travis_retry wget http://downloads.dlang.org/releases/2014/dmd_2.066.0-0_amd64.deb
-               travis_retry sudo dpkg -i dmd_2.066.0-0_amd64.deb
+               travis_retry wget http://downloads.dlang.org/releases/2.x/${VER}/dmd_${VER}-0_amd64.deb
+               travis_retry sudo dpkg -i dmd_${VER}-0_amd64.deb
                ;;
        "go")
                if [[ "$VER" ]]; then
@@ -39,9 +39,11 @@ case "$SWIGLANG" in
                                [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
                                travis_retry nvm install ${VER}
                                nvm use ${VER}
-                               if [ "$VER" == "0.10" ] || [ "$VER" == "0.12" ] || [ "$VER" == "4" ] ; then
+                               if [ "$VER" == "0.10" ] || [ "$VER" == "0.12" ] || [ "$VER" == "4" ] || [ "$VER" == "6" ] ; then
 #                                      travis_retry sudo apt-get install -qq nodejs node-gyp
                                        travis_retry npm install -g node-gyp@$VER
+                               elif [ "$VER" == "8" ] ; then
+                                       travis_retry npm install -g node-gyp@6
                                else
                                        travis_retry npm install -g node-gyp
                                fi
@@ -71,21 +73,7 @@ case "$SWIGLANG" in
                travis_retry sudo apt-get -qq install ocaml camlp4
                ;;
        "octave")
-               if [[ -z "$VER" ]]; then
-                       travis_retry sudo apt-get -qq install liboctave-dev
-               else
-                       # Travis adds external PPAs which contain newer versions of packages
-                       # than in baseline trusty. These newer packages prevent some of the
-                       # Octave packages in ppa:kwwette/octave, which rely on the older
-                       # packages in trusty, from installing. To prevent these kind of
-                       # interactions arising, clean out all external PPAs added by Travis
-                       # before installing Octave
-                       sudo rm -rf /etc/apt/sources.list.d/*
-                       travis_retry sudo apt-get -qq update
-                       travis_retry sudo add-apt-repository -y ppa:kwwette/octaves
-                       travis_retry sudo apt-get -qq update
-                       travis_retry sudo apt-get -qq install liboctave${VER}-dev
-               fi
+               travis_retry sudo apt-get -qq install liboctave-dev
                ;;
        "php")
                travis_retry sudo add-apt-repository -y ppa:ondrej/php
@@ -109,6 +97,12 @@ case "$SWIGLANG" in
                travis_retry sudo apt-get -qq install r-base
                ;;
        "ruby")
+               if [[ "$VER" == "2.7" ]]; then
+                       # Ruby 2.7 support is currently only rvm master (30 Dec 2019)
+                       travis_retry rvm get master
+                       rvm reload
+                       rvm list known
+               fi
                if [[ "$VER" ]]; then
                        travis_retry rvm install $VER
                fi
index 393d96e..71d2b2d 100755 (executable)
@@ -4,6 +4,9 @@
 
 set -e # exit on failure (same as -o errexit)
 
+# Disable 'brew cleanup', just wastes Travis job run time
+export HOMEBREW_NO_INSTALL_CLEANUP=1
+
 sw_vers
 travis_retry brew update
 travis_retry brew list
@@ -23,7 +26,7 @@ case "$SWIGLANG" in
                travis_retry brew install lua
                ;;
        "octave")
-               travis_retry brew install octave
+               travis_retry Tools/brew-install octave
                ;;
        "python")
                WITHLANG=$SWIGLANG$PY3
index 42eaa36..f87cefd 100644 (file)
@@ -16,10 +16,10 @@ environment:
   - SWIGLANG: python
     VSVER: 14
     VER: 27
-  - SWIGLANG: python
-    VSVER: 14
-    VER: 36
-    PY3: 3
+# - SWIGLANG: python
+#   VSVER: 14
+#   VER: 36
+#   PY3: 3
   - SWIGLANG: python
     OSVARIANT: cygwin
   - SWIGLANG: python
index 8b688e2..a8c4d84 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for swig 4.0.1.
+# Generated by GNU Autoconf 2.69 for swig 4.0.2.
 #
 # Report bugs to <http://www.swig.org>.
 #
@@ -580,8 +580,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='swig'
 PACKAGE_TARNAME='swig'
-PACKAGE_VERSION='4.0.1'
-PACKAGE_STRING='swig 4.0.1'
+PACKAGE_VERSION='4.0.2'
+PACKAGE_STRING='swig 4.0.2'
 PACKAGE_BUGREPORT='http://www.swig.org'
 PACKAGE_URL=''
 
@@ -724,9 +724,9 @@ JAVALDSHARED
 JAVASO
 JAVALIBRARYPREFIX
 JAVADYNAMICLINKING
-JAVA_TOOLS_JAR
 JAVA_CLASSPATH_SEP
 JAVAINC
+JAVA_SKIP_DOXYGEN_TEST_CASES
 JAVAC
 JAVA
 SCILABOPT
@@ -785,6 +785,9 @@ CXXSHARED
 CCSHARED
 LDSHARED
 SO
+PCHINCLUDEEXT
+PCHINCLUDEARG
+PCHSUPPORT
 BOOST_LDFLAGS
 BOOST_CPPFLAGS
 YFLAGS
@@ -1529,7 +1532,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures swig 4.0.1 to adapt to many kinds of systems.
+\`configure' configures swig 4.0.2 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1600,7 +1603,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of swig 4.0.1:";;
+     short | recursive ) echo "Configuration of swig 4.0.2:";;
    esac
   cat <<\_ACEOF
 
@@ -1795,7 +1798,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-swig configure 4.0.1
+swig configure 4.0.2
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2385,7 +2388,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by swig $as_me 4.0.1, which was
+It was created by swig $as_me 4.0.2, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3324,7 +3327,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='swig'
- VERSION='4.0.1'
+ VERSION='4.0.2'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -6071,15 +6074,6 @@ fi
 
 
 
-# -I should not be used on system directories (GCC)
-if test "$GCC" = yes; then
-    ISYSTEM="-isystem "
-else
-    ISYSTEM="-I"
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: ISYSTEM: $ISYSTEM" >&5
-$as_echo "$as_me: ISYSTEM: $ISYSTEM" >&6;}
-
 
 # SO is the extension of shared libraries (including the dot!)
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking SO" >&5
@@ -6422,6 +6416,51 @@ case $host in
   *) ;;
 esac
 
+# Check for compiler pre-compiled header support
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports pre-compiled headers" >&5
+$as_echo_n "checking if compiler supports pre-compiled headers... " >&6; }
+PCHSUPPORT=no
+if test "$CLANGXX" = "yes"; then
+   PCHINCLUDEARG="-include-pch"
+   PCHINCLUDEEXT=".gch"
+else
+   PCHINCLUDEARG="-include"
+   PCHINCLUDEEXT=""
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+echo '#include <cstdlib>' > conftest.hpp
+echo '#include "conftest.hpp"' > conftest.cpp
+$CXX -c conftest.hpp 2>/dev/null
+if test $? -eq 0; then
+   if test -f conftest.hpp.gch; then
+      $CXX -H -c -I. ${PCHINCLUDEARG} ./conftest.hpp${PCHINCLUDEEXT} -o conftest.o conftest.cpp >conftest.out 2>&1
+      if test $? -eq 0; then
+         if test "$CLANGXX" = "yes"; then
+            PCHSUPPORT=yes
+         elif grep -q '^!.*conftest.hpp.gch$' conftest.out; then
+            PCHSUPPORT=yes
+         fi
+      fi
+   fi
+fi
+rm -f conftest.hpp conftest.cpp conftest.out
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PCHSUPPORT" >&5
+$as_echo "$PCHSUPPORT" >&6; }
+
+
+
+
 # Set info about shared libraries.
 
 
@@ -6968,7 +7007,7 @@ fi
 # Check whether --with-tclincl was given.
 if test "${with_tclincl+set}" = set; then :
   withval=$with_tclincl;
-       TCLINCLUDE="$ISYSTEM$withval"
+       TCLINCLUDE="-I$withval"
 else
   TCLINCLUDE=
 fi
@@ -7025,7 +7064,7 @@ else
 $as_echo "found $TCLCONFIG/tclConfig.sh" >&6; }
     . $TCLCONFIG/tclConfig.sh
     if test -z "$TCLINCLUDE"; then
-        TCLINCLUDE=`echo $TCL_INCLUDE_SPEC | sed "s/-I/$ISYSTEM/"`
+        TCLINCLUDE=`echo $TCL_INCLUDE_SPEC`
     fi
     if test -z "$TCLLIB"; then
         TCLLIB=$TCL_LIB_SPEC
@@ -7034,7 +7073,7 @@ fi
 
 if test -z "$TCLINCLUDE"; then
    if test "x$TCLPACKAGE" != xyes; then
-       TCLINCLUDE="$ISYSTEM$TCLPACKAGE/include"
+       TCLINCLUDE="-I$TCLPACKAGE/include"
    fi
 fi
 
@@ -7063,7 +7102,7 @@ if test -z "$TCLINCLUDE"; then
                if test -r $i/tcl.h; then
                        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $i" >&5
 $as_echo "$i" >&6; }
-                       TCLINCLUDE="$ISYSTEM$i"
+                       TCLINCLUDE="-I$i"
                        break
                fi
        done
@@ -7904,7 +7943,7 @@ $as_echo "$PERL5LIB" >&6; }
                fi
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Perl5 ccflags" >&5
 $as_echo_n "checking for Perl5 ccflags... " >&6; }
-               PERL5CCFLAGS=`($PERL -e 'use Config; print $Config{ccflags}, "\n"' | sed "s/-Wdeclaration-after-statement//" | sed "s/-I/$ISYSTEM/") 2>/dev/null`
+               PERL5CCFLAGS=`($PERL -e 'use Config; print $Config{ccflags}, "\n"' | sed "s/-Wdeclaration-after-statement//") 2>/dev/null`
                if test -z "$PERL5CCFLAGS" ; then
                        { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
 $as_echo "not found" >&6; }
@@ -8058,8 +8097,8 @@ $as_echo "yes" >&6; }
 
 else
 
-      { $as_echo "$as_me:${as_lineno-$LINENO}: no" >&5
-$as_echo "$as_me: no" >&6;}
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
       OCTAVE=
 
 fi
@@ -8084,6 +8123,7 @@ $as_echo_n "checking for mkoctfile... " >&6; }
 $as_echo "${mkoctfile}" >&6; }
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ${mkoctfile} works" >&5
 $as_echo_n "checking if ${mkoctfile} works... " >&6; }
+  mkoctfile="env - PATH=$PATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH ${mkoctfile}"
   if test "x`${mkoctfile} --version 2>/dev/null | sed -n -e '1p' | sed -n -e '/mkoctfile, version/p'`" != x; then :
 
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
@@ -8105,7 +8145,7 @@ if test -n "$OCTAVE"; then
 $as_echo_n "checking for Octave preprocessor flags... " >&6; }
    OCTAVE_CPPFLAGS=
    for var in CPPFLAGS INCFLAGS ALL_CXXFLAGS; do
-      for flag in `env - ${mkoctfile} -p ${var}`; do
+      for flag in `${mkoctfile} -p ${var}`; do
          case ${flag} in
             -D*|-I*) OCTAVE_CPPFLAGS="${OCTAVE_CPPFLAGS} ${flag}";;
             *) ;;
@@ -8119,7 +8159,7 @@ $as_echo "$OCTAVE_CPPFLAGS" >&6; }
 $as_echo_n "checking for Octave compiler flags... " >&6; }
    OCTAVE_CXXFLAGS=
    for var in CXX ALL_CXXFLAGS; do
-      for flag in `env - ${mkoctfile} -p ${var}`; do
+      for flag in `${mkoctfile} -p ${var}`; do
          case ${flag} in
             -std=*|-g*|-W*) OCTAVE_CXXFLAGS="${OCTAVE_CXXFLAGS} ${flag}";;
             *) ;;
@@ -8155,10 +8195,10 @@ $as_echo "$OCTAVE_CXXFLAGS" >&6; }
 $as_echo_n "checking for Octave linker flags... " >&6; }
    OCTAVE_LDFLAGS=
    for var in OCTLIBDIR; do
-     OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "-L`env - ${mkoctfile} -p ${var}`
+     OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "-L`${mkoctfile} -p ${var}`
    done
    for var in RDYNAMIC_FLAG RLD_FLAG OCTAVE_LIBS LIBS; do
-     OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "`env - ${mkoctfile} -p ${var}`
+     OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "`${mkoctfile} -p ${var}`
    done
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCTAVE_LDFLAGS" >&5
 $as_echo "$OCTAVE_LDFLAGS" >&6; }
@@ -8541,6 +8581,36 @@ else
   JAVAC="$JAVACBIN"
 fi
 
+# Check Java version: we require Java 9 or later for Doxygen tests.
+if test -n "$JAVAC"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if java version is 9 or greater" >&5
+$as_echo_n "checking if java version is 9 or greater... " >&6; }
+    javac_version=`"$JAVAC" -version 2>&1`
+    java_version_num=`echo $javac_version | sed -n 's/^javac //p'`
+    if test -z "$java_version_num"; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unknown format for Java version returned by \"$JAVAC\" ($javac_version)" >&5
+$as_echo "$as_me: WARNING: unknown format for Java version returned by \"$JAVAC\" ($javac_version)" >&2;}
+        JAVA_SKIP_DOXYGEN_TEST_CASES=1
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" >&5
+$as_echo "unknown" >&6; }
+    else
+                        case $java_version_num in
+            1.*)
+                JAVA_SKIP_DOXYGEN_TEST_CASES=1
+                { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, disabling Doxygen tests" >&5
+$as_echo "no, disabling Doxygen tests" >&6; }
+                ;;
+
+            *)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+                ;;
+        esac
+    fi
+
+
+fi
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for java include file jni.h" >&5
 $as_echo_n "checking for java include file jni.h... " >&6; }
 
@@ -8617,18 +8687,6 @@ $as_echo "not found" >&6; }
   fi
 fi
 
-# Javadoc support required for the Java test-suite is available by default in jdk9+ and in tools.jar in earlier jdk versions
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for java tools.jar" >&5
-$as_echo_n "checking for java tools.jar... " >&6; }
-if test -n "$JAVA_HOME" && test -r "$JAVA_HOME/lib/tools.jar" ; then
-  JAVA_TOOLS_JAR="$JAVA_HOME/lib/tools.jar"
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVA_TOOLS_JAR" >&5
-$as_echo "$JAVA_TOOLS_JAR" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
-fi
-
 case $host in
 *-*-cygwin*)
         # TODO: Only use this flag if the compiler supports it, later versions of gcc no longer have it
@@ -8703,7 +8761,6 @@ fi
 
 
 
-
 #----------------------------------------------------------------
 # Look for Javascript
 #----------------------------------------------------------------
@@ -8900,7 +8957,7 @@ fi
   if test -z "$JSCORELIB" -a -n "$PKGCONFIG"; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JavaScriptCore/Webkit library" >&5
 $as_echo_n "checking for JavaScriptCore/Webkit library... " >&6; }
-    if pkg-config javascriptcoregtk-1.0; then
+    if $PKGCONFIG javascriptcoregtk-1.0; then
       JSCORELIB=`$PKGCONFIG --libs javascriptcoregtk-1.0`
       JSCOREVERSION=`$PKGCONFIG --modversion javascriptcoregtk-1.0`
     fi
@@ -10698,7 +10755,7 @@ eval ac_res=\$$as_ac_File
               { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
 if eval test \"x\$"$as_ac_File"\" = x"yes"; then :
-  LUAFLAGS="$ISYSTEM$LUAINCLUDE"
+  LUAFLAGS="-I$LUAINCLUDE"
 else
   LUABIN=
 fi
@@ -10752,7 +10809,7 @@ $as_echo_n "checking for lua.h in other locations... " >&6; }
         if test -r $i/lua.h; then
           { $as_echo "$as_me:${as_lineno-$LINENO}: result: $i/lua.h" >&5
 $as_echo "$i/lua.h" >&6; }
-          LUAFLAGS="$ISYSTEM$i"
+          LUAFLAGS="-I$i"
           break
         fi
       done
@@ -12150,7 +12207,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by swig $as_me 4.0.1, which was
+This file was extended by swig $as_me 4.0.2, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -12216,7 +12273,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-swig config.status 4.0.1
+swig config.status 4.0.2
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
index 63509cd..22e3672 100644 (file)
@@ -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.0.1],[http://www.swig.org])
+AC_INIT([swig],[4.0.2],[http://www.swig.org])
 AC_PREREQ(2.60)
 
 AC_CONFIG_SRCDIR([Source/Swig/swig.h])
@@ -115,15 +115,6 @@ dnl Some test cases require Boost
 AX_BOOST_BASE(,,,)
 AC_SUBST(BOOST_CPPFLAGS)
 
-dnl How to specify include directories that may be system directories.
-# -I should not be used on system directories (GCC)
-if test "$GCC" = yes; then
-    ISYSTEM="-isystem "
-else
-    ISYSTEM="-I"
-fi
-AC_MSG_NOTICE(ISYSTEM: $ISYSTEM)
-
 dnl Info for building shared libraries ... in order to run the examples
 
 # SO is the extension of shared libraries (including the dot!)
@@ -333,6 +324,39 @@ case $host in
   *) ;;
 esac
 
+# Check for compiler pre-compiled header support
+AC_MSG_CHECKING([if compiler supports pre-compiled headers])
+PCHSUPPORT=no
+if test "$CLANGXX" = "yes"; then
+   PCHINCLUDEARG="-include-pch"
+   PCHINCLUDEEXT=".gch"
+else
+   PCHINCLUDEARG="-include"
+   PCHINCLUDEEXT=""
+fi
+AC_LANG_PUSH([C++])
+echo '#include <cstdlib>' > conftest.hpp
+echo '#include "conftest.hpp"' > conftest.cpp
+$CXX -c conftest.hpp 2>/dev/null
+if test $? -eq 0; then
+   if test -f conftest.hpp.gch; then
+      $CXX -H -c -I. ${PCHINCLUDEARG} ./conftest.hpp${PCHINCLUDEEXT} -o conftest.o conftest.cpp >conftest.out 2>&1
+      if test $? -eq 0; then
+         if test "$CLANGXX" = "yes"; then
+            PCHSUPPORT=yes
+         elif grep -q '^!.*conftest.hpp.gch$' conftest.out; then
+            PCHSUPPORT=yes
+         fi
+      fi
+   fi
+fi
+rm -f conftest.hpp conftest.cpp conftest.out
+AC_LANG_POP([C++])
+AC_MSG_RESULT([$PCHSUPPORT])
+AC_SUBST(PCHSUPPORT)
+AC_SUBST(PCHINCLUDEARG)
+AC_SUBST(PCHINCLUDEEXT)
+
 # Set info about shared libraries.
 AC_SUBST(SO)
 AC_SUBST(LDSHARED)
@@ -451,7 +475,7 @@ AC_ARG_WITH(tcl,
  [  --with-tcl=path         Set location of Tcl package],[
        TCLPACKAGE="$withval"], [TCLPACKAGE="$alllang_default"])
 AC_ARG_WITH(tclincl,[  --with-tclincl=path     Set location of Tcl include directory],[
-       TCLINCLUDE="$ISYSTEM$withval"], [TCLINCLUDE=])
+       TCLINCLUDE="-I$withval"], [TCLINCLUDE=])
 AC_ARG_WITH(tcllib,[  --with-tcllib=path      Set location of Tcl library directory],[
        TCLLIB="-L$withval"], [TCLLIB=])
 
@@ -493,7 +517,7 @@ else
     AC_MSG_RESULT(found $TCLCONFIG/tclConfig.sh)
     . $TCLCONFIG/tclConfig.sh
     if test -z "$TCLINCLUDE"; then
-        TCLINCLUDE=`echo $TCL_INCLUDE_SPEC | sed "s/-I/$ISYSTEM/"`
+        TCLINCLUDE=`echo $TCL_INCLUDE_SPEC`
     fi
     if test -z "$TCLLIB"; then
         TCLLIB=$TCL_LIB_SPEC
@@ -502,7 +526,7 @@ fi
 
 if test -z "$TCLINCLUDE"; then
    if test "x$TCLPACKAGE" != xyes; then
-       TCLINCLUDE="$ISYSTEM$TCLPACKAGE/include"
+       TCLINCLUDE="-I$TCLPACKAGE/include"
    fi
 fi
 
@@ -520,7 +544,7 @@ if test -z "$TCLINCLUDE"; then
        for i in $dirs ; do
                if test -r $i/tcl.h; then
                        AC_MSG_RESULT($i)
-                       TCLINCLUDE="$ISYSTEM$i"
+                       TCLINCLUDE="-I$i"
                        break
                fi
        done
@@ -971,7 +995,7 @@ if test -n "$PERL"; then
                        AC_MSG_RESULT($PERL5LIB)
                fi
     AC_MSG_CHECKING(for Perl5 ccflags)
-               PERL5CCFLAGS=`($PERL -e 'use Config; print $Config{ccflags}, "\n"' | sed "s/-Wdeclaration-after-statement//" | sed "s/-I/$ISYSTEM/") 2>/dev/null`
+               PERL5CCFLAGS=`($PERL -e 'use Config; print $Config{ccflags}, "\n"' | sed "s/-Wdeclaration-after-statement//") 2>/dev/null`
                if test -z "$PERL5CCFLAGS" ; then
                        AC_MSG_RESULT(not found)
                else
@@ -1058,7 +1082,7 @@ if test -n "$OCTAVE"; then
    AS_IF([test "x`${OCTAVE} --version 2>/dev/null | sed -n -e '1p' | sed -n -e '/Octave, version/p'`" != x],[
       AC_MSG_RESULT([yes])
    ],[
-      AC_MSG_NOTICE([no])
+      AC_MSG_RESULT([no])
       OCTAVE=
    ])
 fi
@@ -1079,6 +1103,7 @@ if test -n "$OCTAVE"; then
   fi
   AC_MSG_RESULT([${mkoctfile}])
   AC_MSG_CHECKING([if ${mkoctfile} works])
+  mkoctfile="env - PATH=$PATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH ${mkoctfile}"
   AS_IF([test "x`${mkoctfile} --version 2>/dev/null | sed -n -e '1p' | sed -n -e '/mkoctfile, version/p'`" != x],[
       AC_MSG_RESULT([yes])
     ],[
@@ -1093,7 +1118,7 @@ if test -n "$OCTAVE"; then
    AC_MSG_CHECKING([for Octave preprocessor flags])
    OCTAVE_CPPFLAGS=
    for var in CPPFLAGS INCFLAGS ALL_CXXFLAGS; do
-      for flag in `env - ${mkoctfile} -p ${var}`; do
+      for flag in `${mkoctfile} -p ${var}`; do
          case ${flag} in
             -D*|-I*) OCTAVE_CPPFLAGS="${OCTAVE_CPPFLAGS} ${flag}";;
             *) ;;
@@ -1105,7 +1130,7 @@ if test -n "$OCTAVE"; then
    AC_MSG_CHECKING([for Octave compiler flags])
    OCTAVE_CXXFLAGS=
    for var in CXX ALL_CXXFLAGS; do
-      for flag in `env - ${mkoctfile} -p ${var}`; do
+      for flag in `${mkoctfile} -p ${var}`; do
          case ${flag} in
             -std=*|-g*|-W*) OCTAVE_CXXFLAGS="${OCTAVE_CXXFLAGS} ${flag}";;
             *) ;;
@@ -1125,10 +1150,10 @@ if test -n "$OCTAVE"; then
    AC_MSG_CHECKING([for Octave linker flags])
    OCTAVE_LDFLAGS=
    for var in OCTLIBDIR; do
-     OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "-L`env - ${mkoctfile} -p ${var}`
+     OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "-L`${mkoctfile} -p ${var}`
    done
    for var in RDYNAMIC_FLAG RLD_FLAG OCTAVE_LIBS LIBS; do
-     OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "`env - ${mkoctfile} -p ${var}`
+     OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "`${mkoctfile} -p ${var}`
    done
    AC_MSG_RESULT([$OCTAVE_LDFLAGS])
 
@@ -1348,6 +1373,33 @@ else
   JAVAC="$JAVACBIN"
 fi
 
+# Check Java version: we require Java 9 or later for Doxygen tests.
+if test -n "$JAVAC"; then
+    AC_MSG_CHECKING(if java version is 9 or greater)
+    javac_version=`"$JAVAC" -version 2>&1`
+    java_version_num=`echo $javac_version | sed -n 's/^javac //p'`
+    if test -z "$java_version_num"; then
+        AC_MSG_WARN([unknown format for Java version returned by "$JAVAC" ($javac_version)])
+        JAVA_SKIP_DOXYGEN_TEST_CASES=1
+        AC_MSG_RESULT(unknown)
+    else
+        dnl Until Java 8 version number was in format "1.x", starting from
+        dnl Java 9 it's just "x".
+        case $java_version_num in
+            1.*)
+                JAVA_SKIP_DOXYGEN_TEST_CASES=1
+                AC_MSG_RESULT([no, disabling Doxygen tests])
+                ;;
+
+            *)
+                AC_MSG_RESULT(yes)
+                ;;
+        esac
+    fi
+
+    AC_SUBST(JAVA_SKIP_DOXYGEN_TEST_CASES)
+fi
+
 AC_MSG_CHECKING(for java include file jni.h)
 AC_ARG_WITH(javaincl, [  --with-javaincl=path    Set location of Java include directory], [JAVAINCDIR="$withval"], [JAVAINCDIR=])
 
@@ -1408,15 +1460,6 @@ if test -z "$JAVA_HOME" && test -n "$JAVA_HOME_MAYBE" ; then
   fi
 fi
 
-# Javadoc support required for the Java test-suite is available by default in jdk9+ and in tools.jar in earlier jdk versions
-AC_MSG_CHECKING(for java tools.jar)
-if test -n "$JAVA_HOME" && test -r "$JAVA_HOME/lib/tools.jar" ; then
-  JAVA_TOOLS_JAR="$JAVA_HOME/lib/tools.jar"
-  AC_MSG_RESULT([$JAVA_TOOLS_JAR])
-else
-  AC_MSG_RESULT(not found)
-fi
-
 case $host in
 *-*-cygwin*)
         # TODO: Only use this flag if the compiler supports it, later versions of gcc no longer have it
@@ -1483,7 +1526,6 @@ AC_SUBST(JAVA)
 AC_SUBST(JAVAC)
 AC_SUBST(JAVAINC)
 AC_SUBST(JAVA_CLASSPATH_SEP)
-AC_SUBST(JAVA_TOOLS_JAR)
 AC_SUBST(JAVADYNAMICLINKING)
 AC_SUBST(JAVALIBRARYPREFIX)
 AC_SUBST(JAVASO)
@@ -1580,7 +1622,7 @@ else
 
   if test -z "$JSCORELIB" -a -n "$PKGCONFIG"; then
     AC_MSG_CHECKING(for JavaScriptCore/Webkit library)
-    if pkg-config javascriptcoregtk-1.0; then
+    if $PKGCONFIG javascriptcoregtk-1.0; then
       JSCORELIB=`$PKGCONFIG --libs javascriptcoregtk-1.0`
       JSCOREVERSION=`$PKGCONFIG --modversion javascriptcoregtk-1.0`
     fi
@@ -2275,7 +2317,7 @@ if test "$LUABIN"; then
   # look for the header files & set LUAFLAGS accordingly
   # will clear LUABIN if not present
   if test -n "$LUAINCLUDE"; then
-    AC_CHECK_FILE($LUAINCLUDE/lua.h,[LUAFLAGS="$ISYSTEM$LUAINCLUDE"],[LUABIN=])
+    AC_CHECK_FILE($LUAINCLUDE/lua.h,[LUAFLAGS="-I$LUAINCLUDE"],[LUABIN=])
   else
     LUA_OK="1"
     CFLAGS_SAVED=$CFLAGS
@@ -2299,7 +2341,7 @@ if test "$LUABIN"; then
         #echo "$i"
         if test -r $i/lua.h; then
           AC_MSG_RESULT($i/lua.h)
-          LUAFLAGS="$ISYSTEM$i"
+          LUAFLAGS="-I$i"
           break
         fi
       done