diff --git a/.gitignore b/.gitignore index e94087e29..d2e6b841f 100644 --- a/.gitignore +++ b/.gitignore @@ -66,6 +66,7 @@ CCache/ccache_swig_config.h CCache/config.h CCache/config.log CCache/config.status +CCache/config_win32.h Examples/Makefile Examples/d/example.mk Examples/guile/Makefile @@ -85,6 +86,8 @@ swig.spec # Build Artifacts .dirstamp CCache/ccache-swig +CCache/ccache-swig.1 +CCache/web/ccache-swig-man.html Lib/swigwarn.swg Source/CParse/parser.c Source/CParse/parser.h diff --git a/.travis.yml b/.travis.yml index 27237815d..a82b2bc47 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,6 @@ matrix: env: SWIGLANG= sudo: required dist: trusty - - compiler: gcc - os: linux - env: SWIGLANG= - compiler: gcc os: linux env: SWIGLANG= @@ -55,6 +52,8 @@ matrix: - compiler: gcc os: linux env: SWIGLANG=javascript ENGINE=node + sudo: required + dist: trusty - compiler: gcc os: linux env: SWIGLANG=javascript ENGINE=jsc @@ -75,6 +74,11 @@ matrix: env: SWIGLANG=lua VER=5.3 sudo: required dist: trusty + - compiler: gcc + os: linux + env: SWIGLANG=ocaml + sudo: required + dist: trusty - compiler: gcc os: linux env: SWIGLANG=octave SWIGJOBS=-j2 # 3.8 @@ -160,6 +164,14 @@ matrix: env: SWIGLANG=python SWIG_FEATURES=-builtin sudo: required dist: trusty + - os: linux + env: SWIGLANG=python SWIG_FEATURES=-builtin SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1 + sudo: required + dist: trusty + - os: linux + env: SWIGLANG=python SWIG_FEATURES=-builtin SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1 PY3=3 VER=3.5 + sudo: required + dist: trusty - compiler: gcc os: linux env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.4 @@ -219,6 +231,10 @@ matrix: env: SWIGLANG=csharp SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1 sudo: required dist: trusty + - os: linux + env: SWIGLANG=go SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1 + sudo: required + dist: trusty - os: linux env: SWIGLANG=java SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1 sudo: required @@ -227,10 +243,26 @@ matrix: env: SWIGLANG=python SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1 sudo: required dist: trusty + - os: linux + env: SWIGLANG=r CPP11=1 # Note: making 'R CMD SHLIB' use a different compiler is non-trivial + sudo: required + dist: trusty + - os: linux + env: SWIGLANG=ruby SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1 + sudo: required + dist: trusty + - os: linux + env: SWIGLANG=tcl SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1 + sudo: required + dist: trusty - os: linux env: SWIGLANG=csharp SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1 sudo: required dist: trusty + - os: linux + env: SWIGLANG=go SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1 + sudo: required + dist: trusty - os: linux env: SWIGLANG=java SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1 sudo: required @@ -239,6 +271,14 @@ matrix: env: SWIGLANG=python SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1 sudo: required dist: trusty + - os: linux + env: SWIGLANG=ruby SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1 + sudo: required + dist: trusty + - os: linux + env: SWIGLANG=tcl SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1 + sudo: required + dist: trusty - compiler: gcc os: osx env: SWIGLANG= @@ -280,6 +320,10 @@ matrix: env: SWIGLANG=tcl allow_failures: + # Started failing after upgrade from Guile 2.0.14 to Guile 2.2.0 + - compiler: clang + os: osx + env: SWIGLANG=guile # Lots of failing tests currently - compiler: gcc os: linux diff --git a/ANNOUNCE b/ANNOUNCE index e0bd4d0f9..109cf9216 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,8 +1,8 @@ -*** ANNOUNCE: SWIG 3.0.13 (in progress) *** +*** ANNOUNCE: SWIG 4.0.0 (in progress) *** http://www.swig.org -We're pleased to announce SWIG-3.0.13, the latest SWIG release. +We're pleased to announce SWIG-4.0.0, the latest SWIG release. What is SWIG? ============= @@ -27,11 +27,11 @@ Availability ============ The release is available for download on Sourceforge at - http://prdownloads.sourceforge.net/swig/swig-3.0.13.tar.gz + http://prdownloads.sourceforge.net/swig/swig-4.0.0.tar.gz A Windows version is also available at - http://prdownloads.sourceforge.net/swig/swigwin-3.0.13.zip + http://prdownloads.sourceforge.net/swig/swigwin-4.0.0.zip Please report problems with this release to the swig-devel mailing list, details at http://www.swig.org/mail.html. diff --git a/CCache/Makefile.in b/CCache/Makefile.in index 67fd3f363..d1bb8c526 100644 --- a/CCache/Makefile.in +++ b/CCache/Makefile.in @@ -8,6 +8,7 @@ bindir=@bindir@ mandir=@mandir@ INSTALLCMD=@INSTALL@ PACKAGE_NAME=@PACKAGE_NAME@ +PROGRAM_NAME=@PROGRAM_NAME@ # Soft link test can be skipped on systems that don't support soft linking NOSOFTLINKSTEST= @@ -17,13 +18,10 @@ SWIG=swig SWIG_LIB=../$(srcdir)/../Lib EXEEXT=@EXEEXT@ -# Use standard autoconf approach to transform executable name using --program-prefix and --program-suffix -transform = @program_transform_name@ - LIBS= @LIBS@ OBJS= ccache.o mdfour.o hash.o execute.o util.o args.o stats.o \ cleanup.o snprintf.o unify.o -HEADERS = ccache.h mdfour.h +HEADERS = ccache.h mdfour.h config.h config_win32.h all: $(PACKAGE_NAME)$(EXEEXT) @@ -32,7 +30,7 @@ Makefile: $(srcdir)/Makefile.in ./config.status $(SHELL) ./config.status # Note that HTML documentation is actually generated and used from the main SWIG documentation Makefile -docs: $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/ccache-man.html +docs: $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/$(PACKAGE_NAME)-man.html $(PACKAGE_NAME)$(EXEEXT): $(OBJS) $(HEADERS) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) @@ -40,40 +38,43 @@ $(PACKAGE_NAME)$(EXEEXT): $(OBJS) $(HEADERS) $(srcdir)/$(PACKAGE_NAME).1: $(srcdir)/ccache.yo -yodl2man -o $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/ccache.yo -$(srcdir)/web/ccache-man.html: $(srcdir)/ccache.yo - yodl2html -o $(srcdir)/web/ccache-man.html $(srcdir)/ccache.yo +$(srcdir)/web/$(PACKAGE_NAME)-man.html: $(srcdir)/ccache.yo + yodl2html -o $(srcdir)/web/$(PACKAGE_NAME)-man.html $(srcdir)/ccache.yo install: $(PACKAGE_NAME)$(EXEEXT) @echo "Installing $(PACKAGE_NAME)" - @echo "Installing $(DESTDIR)${bindir}/`echo $(PACKAGE_NAME) | sed '$(transform)'`$(EXEEXT)" + @echo "Installing $(DESTDIR)${bindir}/$(PROGRAM_NAME)$(EXEEXT)" ${INSTALLCMD} -d $(DESTDIR)${bindir} - ${INSTALLCMD} -m 755 $(PACKAGE_NAME)$(EXEEXT) $(DESTDIR)${bindir}/`echo $(PACKAGE_NAME) | sed '$(transform)'`$(EXEEXT) + ${INSTALLCMD} -m 755 $(PACKAGE_NAME)$(EXEEXT) $(DESTDIR)${bindir}/$(PROGRAM_NAME)$(EXEEXT) install-docs: $(srcdir)/$(PACKAGE_NAME).1 - @echo "Installing $(DESTDIR)${mandir}/man1/`echo $(PACKAGE_NAME) | sed '$(transform)'`.1" + @echo "Installing $(DESTDIR)${mandir}/man1/$(PROGRAM_NAME).1" ${INSTALLCMD} -d $(DESTDIR)${mandir}/man1 - ${INSTALLCMD} -m 644 $(srcdir)/$(PACKAGE_NAME).1 $(DESTDIR)${mandir}/man1/`echo $(PACKAGE_NAME) | sed '$(transform)'`.1 + ${INSTALLCMD} -m 644 $(srcdir)/$(PACKAGE_NAME).1 $(DESTDIR)${mandir}/man1/$(PROGRAM_NAME).1 uninstall: $(PACKAGE_NAME)$(EXEEXT) - rm -f $(DESTDIR)${bindir}/`echo $(PACKAGE_NAME) | sed '$(transform)'`$(EXEEXT) + rm -f $(DESTDIR)${bindir}/$(PROGRAM_NAME)$(EXEEXT) uninstall-docs: $(srcdir)/$(PACKAGE_NAME).1 - rm -f $(DESTDIR)${mandir}/man1/`echo $(PACKAGE_NAME) | sed '$(transform)'`.1 + rm -f $(DESTDIR)${mandir}/man1/$(PROGRAM_NAME).1 -clean: +clean: clean-docs /bin/rm -f $(OBJS) *~ $(PACKAGE_NAME)$(EXEEXT) +clean-docs: + rm -f $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/$(PACKAGE_NAME)-man.html + test: test.sh - SWIG_LIB='$(SWIG_LIB)' PATH=../..:$$PATH SWIG='$(SWIG)' CC='$(CC)' NOSOFTLINKSTEST='$(NOSOFTLINKSTEST)' $(srcdir)/test.sh + SWIG_LIB='$(SWIG_LIB)' PATH=../..:$$PATH SWIG='$(SWIG)' CC='$(CC)' NOSOFTLINKSTEST='$(NOSOFTLINKSTEST)' CCACHE='../$(PACKAGE_NAME)' CCACHE_PROG=$(PROGRAM_NAME) $(srcdir)/test.sh check: test distclean: clean - /bin/rm -f Makefile config.h config.sub config.log build-stamp config.status ccache_swig_config.h + /bin/rm -f Makefile config.h config.sub config.log build-stamp config.status ccache_swig_config.h config_win32.h /bin/rm -rf autom4te.cache maintainer-clean: distclean - /bin/rm -f $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/ccache-man.html + /bin/rm -f $(srcdir)/$(PACKAGE_NAME).1 $(srcdir)/web/$(PACKAGE_NAME)-man.html # FIXME: To fix this, test.sh needs to be able to take ccache from the diff --git a/CCache/ccache.h b/CCache/ccache.h index a79d88322..25e786496 100644 --- a/CCache/ccache.h +++ b/CCache/ccache.h @@ -6,7 +6,7 @@ #include "config.h" #else #include -#define PACKAGE_NAME "ccache-swig.exe" +#include "config_win32.h" #endif #include @@ -51,7 +51,7 @@ #define STATUS_FATAL 4 #define STATUS_NOCACHE 5 -#define MYNAME PACKAGE_NAME +#define MYNAME PROGRAM_NAME #define LIMIT_MULTIPLE 0.8 diff --git a/CCache/config_win32.h.in b/CCache/config_win32.h.in new file mode 100644 index 000000000..2d5ab97e3 --- /dev/null +++ b/CCache/config_win32.h.in @@ -0,0 +1,3 @@ +#if !defined(PROGRAM_NAME) +#define PROGRAM_NAME "@PROGRAM_NAME@.exe" +#endif diff --git a/CCache/configure.ac b/CCache/configure.ac index dfbf86dbc..e1c761860 100644 --- a/CCache/configure.ac +++ b/CCache/configure.ac @@ -7,6 +7,7 @@ AC_CONFIG_SRCDIR([ccache.h]) AC_MSG_NOTICE([Configuring ccache]) AC_CONFIG_HEADER(config.h) +AC_CONFIG_FILES([config_win32.h]) dnl Checks for programs. AC_PROG_CC @@ -14,6 +15,20 @@ AC_PROG_CPP AC_PROG_INSTALL AC_ARG_PROGRAM # for program_transform_name +AC_SUBST(PROGRAM_NAME) +if test "x$program_prefix" != "xNONE" -a "x$program_prefix" != "x" +then + PROGRAM_NAME="$program_prefix$PACKAGE_NAME" +else + PROGRAM_NAME="$PACKAGE_NAME" +fi +if test "x$program_suffix" != "xNONE" -a "x$program_suffix" != "x" +then + PROGRAM_NAME="$PROGRAM_NAME$program_suffix" +fi + +AC_DEFINE_UNQUOTED(PROGRAM_NAME, "$PROGRAM_NAME", [Define my program name]) + AC_DEFINE([_GNU_SOURCE], 1, [Define _GNU_SOURCE so that we get all necessary prototypes]) diff --git a/CCache/test.sh b/CCache/test.sh index 438e782cd..5b6f92a35 100755 --- a/CCache/test.sh +++ b/CCache/test.sh @@ -20,7 +20,12 @@ fi PATH="`echo $PATH | \ sed -e 's!:/usr\(/local\)*/lib\([0-9]\)*/ccache\(/\)*!!g'`" -CCACHE=../ccache-swig +if test -n "$CCACHE"; then + CCACHE="$CCACHE" +else + CCACHE=../ccache-swig +fi + TESTDIR=test.$$ test_failed() { @@ -406,6 +411,10 @@ swigtests() { # main program rm -rf $TESTDIR mkdir $TESTDIR +if test -n "$CCACHE_PROG"; then + ln -s $CCACHE $TESTDIR/$CCACHE_PROG + CCACHE=./$CCACHE_PROG +fi cd $TESTDIR || exit 1 unset CCACHE_DIR diff --git a/CHANGES b/CHANGES index 1b5cd47e4..8376c0b36 100644 --- a/CHANGES +++ b/CHANGES @@ -5,7 +5,7 @@ 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 3.0.13 (27 Jan 2017) +Version 3.0.12 (27 Jan 2017) ============================ 2017-01-27: wsfulton @@ -21116,7 +21116,7 @@ Version 1.3.7 (September 3, 2001) typedef __name vector; %enddef - An a specific instantiation is created in exactly the same way: + A specific instantiation is created in exactly the same way: %template(intvec) vector; diff --git a/CHANGES.current b/CHANGES.current index 16cbf043f..f76e5a58e 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -4,6 +4,437 @@ 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 3.0.13 (in progress) -============================ +Version 4.0.0 (in progress) +=========================== +2017-09-18: wsfulton + Fix type promotion wrapping constant expressions of the form: + # define EXPR_MIXED1 (0x80 + 11.1) - 1 + This was previously an integral type instead of a floating point type. + +2017-09-17: wsfulton + Fix generated code for constant expressions containing wchar_t L literals such as: + # define __WCHAR_MAX (0x7fffffff + L'\0') + # define __WCHAR_MIN (-__WCHAR_MAX - 1) + +2017-09-10: mlamarre + [Python] Patch #1083. Define_DEBUG to 1 to do exactly like Visual Studio + /LDd, /MDd or /MTd compiler options. + +2017-08-25: wsfulton + Issue #1059. Add support for C++11 ref-qualifiers on non-static member functions. + Members with lvalue ref-qualifiers such as: + + struct RQ { + void m1(int x) &; + void m2(int x) const &; + }; + + are wrapped like any other member function. Member functions with rvalue ref-qualifiers + are ignored by default, such as: + + struct RQ { + void m3(int x) &&; + void m4(int x) const &&; + }; + + example.i:7: Warning 405: Method with rvalue ref-qualifier m3(int) && ignored. + example.i:8: Warning 405: Method with rvalue ref-qualifier m4(int) const && ignored. + + These can be unignored and exposed to the target language, see further documentation in + CPlusPlus11.html. + +2017-08-16: wsfulton + Fix #1063. Add using declarations to templates into typedef table. + + Using declarations to templates were missing in SWIG's internal typedef tables. + This led to a few problems, such as, templates that did not instantiate and generated + C++ code that did not compile as SWIG did not know what scope the template was + in. This happened mostly when a using declaration was used on a template type in a + completely unrelated namespace. + +2017-08-16: wsfulton + Fix type lookup in the presence of using directives and using declarations. + + Fix some cases of type lookup failure via a combination of both using directives and + using declarations resulting in C++ code that did not compile as the generated type was + not fully qualified for use in the global namespace. Example below: + + namespace Space5 { + namespace SubSpace5 { + namespace SubSubSpace5 { + struct F {}; + } + } + using namespace SubSpace5; + using SubSubSpace5::F; + void func(SubSubSpace5::F f); + } + +2017-08-16: wsfulton + Issue #1051. %template scope enforcement and class definition fixes. + + The scoping rules around %template have been specified and enforced. + The %template directive for a class template is the equivalent to an + explicit instantiation of a C++ class template. The scope for a valid + %template instantiation is now the same as the scope required for a + valid explicit instantiation of a C++ template. A definition of the + template for the explicit instantiation must be in scope where the + instantiation is declared and must not be enclosed within a different + namespace. + + For example, a few %template and C++ explicit instantiations of std::vector + are shown below: + + // valid + namespace std { + %template(vin) vector; + template class vector; + } + + // valid + using namespace std; + %template(vin) vector; + template class vector; + + // valid + using std::vector; + %template(vin) vector; + template class vector; + + // ill-formed + namespace unrelated { + using std::vector; + %template(vin) vector; + template class vector; + } + + // ill-formed + namespace unrelated { + using namespace std; + %template(vin) vector; + template class vector; + } + + // ill-formed + namespace unrelated { + namespace std { + %template(vin) vector; + template class vector; + } + } + + // ill-formed + namespace unrelated { + %template(vin) std::vector; + template class std::vector; + } + + When the scope is incorrect, an error now occurs such as: + + cpp_template_scope.i:34: Error: 'vector' resolves to 'std::vector' and + was incorrectly instantiated in scope 'unrelated' instead of within scope 'std'. + + Previously SWIG accepted the ill-formed examples above but this led to + numerous subtle template scope problems especially in the presence of + using declarations and using directives as well as with %feature and %typemap. + + Actually, a valid instantiation is one which conforms to the C++03 + standard as C++11 made a change to disallow using declarations and + using directives to find a template. + + // valid C++03, ill-formed C++11 + using std::vector; + template class vector; + + Similar fixes for defining classes using forward class references have + also been put in place. For example: + + namespace Space1 { + struct A; + } + namespace Space2 { + struct Space1::A { + void x(); + } + } + + will now error out with: + + cpp_class_definition.i:5: Error: 'Space1::A' resolves to 'Space1::A' and + was incorrectly instantiated in scope 'Space2' instead of within scope 'Space1'. + +2017-08-16: wsfulton + Fix scope lookup for template parameters containing unary scope operators. + + Fixes cases like: + + namespace Alloc { + template struct Rebind { + typedef int Integer; + }; + } + %template(RebindBucket) Alloc::Rebind< Bucket >; + OR + %template(RebindBucket) Alloc::Rebind< ::Bucket >; + + Alloc::Rebind< Bucket >::Integer Bucket1(); + Alloc::Rebind< ::Bucket >::Integer Bucket2(); + Alloc::Rebind<::template TemplateBucket>::Integer Bucket3(); + +2017-08-16: wsfulton + For templates only, the template parameters are fully resolved when + handling typemaps. Without this, it is too hard to have decent rules + to apply typemaps when parameter types are typedef'd and template + parameters have default values. + + Fixes %clear for typedefs in templates, eg: + + %typemap("in") XXX::Long "..." + template typename struct XXX { + typedef long Long; + }; + %clear XXX::Long; + + as the typemap was previously incorrectly stored as a typemap for long + instead of XXX::Long. + +2017-08-05: olly + [C++11] Allow static_assert at the top level (and disallow it right + after template). Fixes https://github.com/swig/swig/issues/1031 + reported by Artem V L. + +2017-08-02: wsfulton + Fix incorrectly shown warning when an empty template instantiation was used on a + class used as a base class and that base class was explicitly ignored with %ignore. + Example of the warning which will no longer appear: + + Warning 401: Base class 'Functor< int,int >' has no name as it is an empty + template instantiated with '%template()'. Ignored. + +2017-07-17: fflexo + [Java] #674 Add std_list.i to add support for std::list containers. The Java proxy + extends java.util.AbstractSequentialList and makes the C++ std::list container look + and feel much like a java.util.LinkedList from Java. + +2017-07-07: wsfulton + [Python] Fix display of documented template types when using the autodoc + feature. For example when wrapping: + + %feature("autodoc"); + template struct T {}; + %template(TInteger) T; + + the generated documentation contains: + """Proxy of C++ T< int > class.""" + instead of: + """Proxy of C++ T<(int)> class.""" + and + """__init__(TInteger self) -> TInteger""" + instead of + """__init__(T<(int)> self) -> TInteger""" + +2017-06-27: nihaln + [PHP] Update the OUTPUT Typemap to add return statement to the + PHP Wrapper. + +2017-06-27: nihaln + [PHP] Update the enum and value examples to use the OO wrappers + rather than the flat functions produced with -noproxy. There's + not been a good reason to use -noproxy for since PHP5 OO wrapping + was fixed back in 2005. + +2017-06-23: m7thon + [Python] fix and improve default argument handling: + + 1. Fix negative octals. Currently not handled correctly by `-py3` + (unusual case, but incorrect). + 2. Fix arguments of type "octal + something" (e.g. `0640 | 04`). + Currently drops everything after the first octal. Nasty! + 3. Fix bool arguments "0 + something" (e.g. `0 | 1`) are always + "False" (unusual case, but incorrect). + 4. Remove special handling of "TRUE" and "FALSE" from + `convertValue` since there's no reason these have to match + "true" and "false". + 5. Remove the Python 2 vs. Python 3 distinction based on the + `-py3` flag. Now the same python code is produced for default + arguments for Python 2 and Python 3. For this, octal default + arguments, e.g. 0644, are now wrapped as `int('644', 8)`. This + is required, as Python 2 and Python 3 have incompatible syntax + for octal literals. + + Fixes #707 + +2017-06-21: futatuki + #1004 - Fix ccache-swig executable name to respect configure's --program-prefix and + --program-suffix values if used. + +2017-06-21: tamuratak + [Ruby] #911 - Add std::wstring support. + +2017-06-19: wsfulton + [Python] Fix handling of rich comparisons when wrapping overloaded operators: + + operator< operator<= operator> operator>= operator== operator!= + + Previously a TypeError was always thrown if the type was not correct. NotImplemented + is now returned from these wrapped functions if the type being compared with is + not correct. The subsequent behaviour varies between different versions of Python + and the comparison function being used, but is now consistent with normal Python + behaviour. For example, for the first 4 operator overloads above, a TypeError + 'unorderable types' is thrown in Python 3, but Python 2 will return True or False. + NotImplemented should be returned when the comparison cannot be done, see PEP 207 and + https://docs.python.org/3/library/constants.html#NotImplemented + + Note that the bug was only present when overloaded operators did not also have a + function overload. + + Fixes SF bug #1208 (3441262) and SF patch #303. + + *** POTENTIAL INCOMPATIBILITY *** + +2017-06-17: fabrice102 + [Go] Fix Go callback example. Fixes github #600, #955, #1000. + +2017-06-16: wsfulton + Make sure warning and error messages are not split up by other processes writing to + stdout at the same time. + +2017-06-16: wsfulton + [R] Fix wrapping function pointers containing rvalue and lvalue reference parameters. + +2017-06-13: olly + [Perl] Fix testsuite to work without . in @INC - it was removed in + Perl 5.26 for security reasons, and has also been removed from + older versions in some distros. Fixes + https://github.com/swig/swig/issues/997 reported by lfam. + +2017-06-03: wsfulton + Fix %import on a file containing a file scope %fragment forced inclusion to not + generate the fragment contents as %import should not result in code being generated. + The behaviour is now the same as importing code insertion blocks. + Wrapping FileC.i in the following example will result in no generated code, whereas + previously "#include " was generated: + + // FileA.i + %fragment("", "header") %{ + #include + %} + + %{ + #include + %} + %fragment(""); + + // FileC.i + %import "FileA.i" + + *** POTENTIAL INCOMPATIBILITY *** + +2017-05-26: Volker Diels-Grabsch, vadz + [Java] #842 Extend from java.util.AbstractList<> and implement java.util.RandomAccess for + std::vector wrappers. This notably allows to iterate over wrapped vectors in a natural way. +2017-05-30: davidcl + [Scilab] #994 Undefined symbol error when loading in Scilab 6 + +2017-05-25: asibross + [Java] #370 #417 Missing smart pointer handling in Java director extra methods + swigReleaseOwnership() and swigTakeOwnership(). + +2017-05-23: wsfulton + [Java] #230 #759 Fix Java shared_ptr and directors for derived classes java compilation + error. + + For shared_ptr proxy proxy classes, add a protected method swigSetCMemOwn for modifying + the swigCMemOwn and swigCMemOwnDerived member variables which are used by various other + methods for controlling memory ownership. + +2017-05-21: Sghirate + [Java, C#, D] #449 Remove unnecessary use of dynamic_cast in directors to enable + non-RTTI compilation. + +2017-05-21: wsfulton + [Python] #993 Fix handling of default -ve unsigned values, such as: + void f(unsigned = -1U); + +2017-05-20: jschueller + [Python] #991 Fix E731 PEP8 warning: do not assign a lambda expression + +2017-05-16: nihal95 + [PHP] Add %pragma version directive to allow the version of the + extension to be set. Patch #970, fixes #360. + +2017-05-13: yag00 + Patch #975 - Add support for noexcept on director methods. + +2017-04-27: redbrain + Issue #974, Patch #976 - Fix preprocessor handling of macros with commas in a comment. + +2017-04-25: jleveque + [Lua] #959 - Fix Visual Studio C4244 conversion warnings in Lua wrappers. + +2017-04-21: tamuratak + [Ruby] #964 - Add shared_ptr director typemaps. + +2017-04-20: wsfulton + [Ruby] #586, #935 Add assert for invalid NULL type parameter when calling SWIG_Ruby_NewPointerObj. + +2017-04-20: tamuratak + [Ruby] #930, #937 - Fix containers of std::shared_ptr. + Upcasting, const types (eg vector>) and NULL/nullptr support added. + +2017-04-12: smarchetto + [Scilab] New parameter targetversion to specify the Scilab target version (5, 6, ..) for code generation + With Scilab 6 target specified, identifier names truncation is disabled (no longer necessary) + +2017-03-24: tamuratak + [Ruby] Fix #939 - Wrapping std::vector fix due to incorrect null checks + on VALUE obj. + +2017-03-17: vadz + [C#] #947 Add support for std::complex + +2017-03-17: wsfulton + [Go] Fix handling of typedef'd function pointers and typedef'd member function pointers + such as: + + typedef int (*FnPtr_td)(int, int); + int do_op(int x, int y, FnPtr_td op); + +2017-03-16: wsfulton + Add support for member const function pointers such as: + + int fn(short (Funcs::* parm)(bool)) const; + + Also fix parsing of references/pointers and qualifiers to member + pointers such as: + + int fn(short (Funcs::* const parm)(bool)); + int fn(short (Funcs::* & parm)(bool)); + +2017-03-10: wsfulton + Extend C++11 alternate function syntax parsing to support const and noexcept, such as: + + auto sum1(int x, int y) const -> int { return x + y; } + auto sum2(int x, int y) noexcept -> int { return x + y; } + +2017-02-29: tamuratak + [Ruby] #917 - Add Enumerable module to all container class wrappers. It was missing + for std::list, std::multiset, std::unordered_multiset and std::unordered_map. + +2017-02-27: assambar + [C++11] Extend parser to support throw specifier in combination + with override and/or final. + +2017-02-10: tamuratak + [Ruby] #883 - Add support for C++11 hash tables: + std::unordered_map + std::unordered_set + std::unordered_multimap + std::unordered_multiset + +2017-02-08: jcsharp + [C#] #887 Improve std::vector wrapper constructors - + Replace constructor taking ICollection with IEnumerable and also add IEnumerable + constructor to avoid the boxing and unboxing overhead of the original constructor, + when the type parameter is a value type. diff --git a/Doc/Manual/Allegrocl.html b/Doc/Manual/Allegrocl.html index ddb6fba55..c4d898130 100644 --- a/Doc/Manual/Allegrocl.html +++ b/Doc/Manual/Allegrocl.html @@ -155,7 +155,7 @@ SWIG directives. SWIG can be furnished with a header file, but an interface can also be generated without library headers by supplying a simple text file--called the interface file, which is typically named with a .i extension--containing any foreign declarations of -identifiers you wish to use. The most common approach is to use a an +identifiers you wish to use. The most common approach is to use an interface file with directives to parse the needed headers. A straight parse of library headers will result in usable code, but SWIG directives provides much freedom in how a user might tailor the diff --git a/Doc/Manual/Android.html b/Doc/Manual/Android.html index b295b5e04..726314228 100644 --- a/Doc/Manual/Android.html +++ b/Doc/Manual/Android.html @@ -409,7 +409,7 @@ All the steps required to compile and use a simple hierarchy of classes for shap

First create an Android project called SwigClass in a subdirectory called class. -The steps below create and build a the JNI C++ app. +The steps below create and build the JNI C++ app. Adjust the --target id as mentioned earlier in the Examples introduction.

diff --git a/Doc/Manual/CCache.html b/Doc/Manual/CCache.html index d23b0cb2f..521184ff0 100644 --- a/Doc/Manual/CCache.html +++ b/Doc/Manual/CCache.html @@ -411,7 +411,7 @@ following conditions need to be met:

-ccache was inspired by the compilercache shell script script written +ccache was inspired by the compilercache shell script written by Erik Thiele and I would like to thank him for an excellent piece of work. See http://www.erikyyy.de/compilercache/ diff --git a/Doc/Manual/CPlusPlus11.html b/Doc/Manual/CPlusPlus11.html index 4d4261cd7..f9281bd56 100644 --- a/Doc/Manual/CPlusPlus11.html +++ b/Doc/Manual/CPlusPlus11.html @@ -42,6 +42,7 @@

  • Exception specifications and noexcept
  • Control and query object alignment
  • Attributes +
  • Methods with ref-qualifiers
  • Standard library changes
      @@ -877,7 +878,8 @@ so in this case it is entirely possible to pass an int instead of a double to -SWIG correctly parses the new static_assert declarations. +SWIG correctly parses the new static_assert declarations (though 3.0.12 and earlier +had a bug which meant this wasn't accepted at file scope). This is a C++ compile time directive so there isn't anything useful that SWIG can do with it.

      @@ -970,6 +972,104 @@ int [[attr1]] i [[attr2, attr3]]; [[noreturn, nothrow]] void f [[noreturn]] (); + +

      7.2.29 Methods with ref-qualifiers

      + + +

      +C++11 non-static member functions can be declared with ref-qualifiers. +Member functions declared with a & lvalue ref-qualifiers are wrapped like any other function without ref-qualifiers. +Member functions declared with a && rvalue ref-qualifiers are ignored by default +as they are unlikely to be required from non-C++ languages where the concept of rvalue-ness +for the implied *this pointer does not apply. +The warning is hidden by default, but can be displayed as described in the section on Enabling extra warnings. +

      + +

      +Consider: +

      + +
      +struct RQ {
      +  void m1(int x) &;
      +  void m2(int x) &&;
      +};
      +
      + +

      +The only wrapped method will be the lvalue ref-qualified method m1 +and if SWIG is run with the -Wextra command-line option, the following warning will be issued indicating m2 is not wrapped: +

      + +
      +
      +example.i:7: Warning 405: Method with rvalue ref-qualifier m2(int) && ignored.
      +
      +
      + +

      +If you unignore the method as follows, wrappers for m2 will be generated: +

      + +
      +%feature("ignore", "0") RQ::m2(int x) &&;
      +struct RQ {
      +  void m1(int x) &;
      +  void m2(int x) &&;
      +};
      +
      + +

      +Inspection of the generated C++ code, will show that std::move is used on the instance +of the RQ * class: +

      + +
      +  RQ *arg1 = (RQ *) 0 ;
      +  int arg2 ;
      +
      +  arg1 = ...marshalled from target language...
      +  arg2 = ...marshalled from target language...
      +
      +  std::move(*arg1).m2(arg2);
      +
      + +

      +This will compile but when run, the move effects may not be what you want. +As stated earlier, rvalue ref-qualifiers aren't really applicable outside the world of C++. +However, if you really know what you are doing, full control over the call to the method is +possible via the low-level "action" feature. +This feature completely replaces the call to the underlying function, that is, the last line in the snippet of code above. +

      + +
      +%feature("ignore", "0") RQ::m2(int x) &&;
      +%feature("action") RQ::m2(int x) && %{
      +  RQ().m2(arg2);
      +%}
      +struct RQ {
      +  void m1(int x) &;
      +  void m2(int x) &&;
      +};
      +
      + +

      +resulting in: +

      + +
      +  RQ *arg1 = (RQ *) 0 ;
      +  int arg2 ;
      +
      +  arg1 = ...marshalled from target language...
      +  arg2 = ...marshalled from target language...
      +
      +  RQ().m2(arg2);
      +
      + +

      +Compatibility note: SWIG-4.0.0 was the first version to support ref-qualifiers. +

      7.3 Standard library changes

      @@ -994,7 +1094,8 @@ Variadic template support requires further work to provide substantial tuple wra

      The new hash tables in the STL are unordered_set, unordered_multiset, unordered_map, unordered_multimap. -These are not available in SWIG, but in principle should be easily implemented by adapting the current STL containers. +These are not available in all target languages. +Any missing support can in principle be easily implemented by adapting the current STL containers.

      7.3.4 Regular expressions

      @@ -1175,5 +1276,6 @@ Phew, that is a lot of hard work to get a callback working. You could just go with the more attractive option of just using double as the return type in the function declaration instead of result_of!

      + diff --git a/Doc/Manual/CSharp.html b/Doc/Manual/CSharp.html index 5be63a340..70010c992 100644 --- a/Doc/Manual/CSharp.html +++ b/Doc/Manual/CSharp.html @@ -677,7 +677,7 @@ As a result, we get the following method in the module class:
       public static void myArrayCopy(int[] sourceArray, int[] targetArray, int nitems) {
      -    examplePINVOKE.myArrayCopy(sourceArray, targetArray, nitems);
      +  examplePINVOKE.myArrayCopy(sourceArray, targetArray, nitems);
       }
       
      @@ -997,9 +997,9 @@ When the following C# code is executed:
       public class runme {
      -    static void Main() {
      -      example.positivesonly(-1);
      -    }
      +  static void Main() {
      +    example.positivesonly(-1);
      +  }
       }
       
      @@ -1772,7 +1772,7 @@ should pass the call on to CSharpDefaults.DefaultMethod(int)using the C

      -When using multiple modules it is is possible to compile each SWIG generated wrapper +When using multiple modules it is possible to compile each SWIG generated wrapper into a different assembly. However, by default the generated code may not compile if generated classes in one assembly use generated classes in another assembly. @@ -1846,12 +1846,12 @@ and the following usage from C# after running the code through SWIG:

      -      Wheel wheel = new Bike(10).getWheel();
      -      Console.WriteLine("wheel size: " + wheel.size);
      -      // Simulate a garbage collection
      -      global::System.GC.Collect();
      -      global::System.GC.WaitForPendingFinalizers();
      -      global::System.Console.WriteLine("wheel size: " + wheel.size);
      +  Wheel wheel = new Bike(10).getWheel();
      +  Console.WriteLine("wheel size: " + wheel.size);
      +  // Simulate a garbage collection
      +  global::System.GC.Collect();
      +  global::System.GC.WaitForPendingFinalizers();
      +  global::System.Console.WriteLine("wheel size: " + wheel.size);
       
      @@ -1980,9 +1980,9 @@ and more or less equivalent usage from C#
      -      Container container = new Container();
      -      Element element = new Element(20);
      -      container.setElement(element);
      +  Container container = new Container();
      +  Element element = new Element(20);
      +  container.setElement(element);
       
      @@ -1993,14 +1993,14 @@ In order to understand why, consider a garbage collection occuring...
      -      Container container = new Container();
      -      Element element = new Element(20);
      -      container.setElement(element);
      -      Console.WriteLine("element.value: " + container.getElement().value);
      -      // Simulate a garbage collection
      -      global::System.GC.Collect();
      -      global::System.GC.WaitForPendingFinalizers();
      -      global::System.Console.WriteLine("element.value: " + container.getElement().value);
      +  Container container = new Container();
      +  Element element = new Element(20);
      +  container.setElement(element);
      +  Console.WriteLine("element.value: " + container.getElement().value);
      +  // Simulate a garbage collection
      +  global::System.GC.Collect();
      +  global::System.GC.WaitForPendingFinalizers();
      +  global::System.Console.WriteLine("element.value: " + container.getElement().value);
       
      diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html index 00ac3ca3b..559452aeb 100644 --- a/Doc/Manual/Contents.html +++ b/Doc/Manual/Contents.html @@ -228,7 +228,6 @@
    • Static members
    • Member data
    -
  • Default arguments
  • Protection
  • Enums and constants
  • Friends @@ -236,16 +235,27 @@
  • Pass and return by value
  • Inheritance
  • A brief discussion of multiple inheritance, pointers, and type checking -
  • Wrapping Overloaded Functions and Methods +
  • Default arguments +
  • Overloaded functions and methods -
  • Wrapping overloaded operators +
  • Overloaded operators
  • Class extension
  • Templates +
  • Namespaces
  • Standard library changes diff --git a/Doc/Manual/Customization.html b/Doc/Manual/Customization.html index 0e5fb2869..269e659e0 100644 --- a/Doc/Manual/Customization.html +++ b/Doc/Manual/Customization.html @@ -356,7 +356,7 @@ In this case, the exception handler is only attached to declarations named "allocate". This would include both global and member functions. The names supplied to %exception follow the same rules as for %rename described in the section on -Ambiguity resolution and renaming. +Renaming and ambiguity resolution. For example, if you wanted to define an exception handler for a specific class, you might write this:

    @@ -516,7 +516,7 @@ The special variables are often used in situations where method calls are logged $action } catch (MemoryError) { - croak("Out of memory in $decl"); + croak("Out of memory in $decl"); } } void log(const char *message); @@ -796,7 +796,7 @@ involving %feature:

    -The name matching rules outlined in the Ambiguity resolution and renaming +The name matching rules outlined in the Renaming and ambiguity resolution section applies to all %feature directives. In fact the %rename directive is just a special form of %feature. The matching rules mean that features are very flexible and can be applied with diff --git a/Doc/Manual/D.html b/Doc/Manual/D.html index 45b57e18b..1a317a005 100644 --- a/Doc/Manual/D.html +++ b/Doc/Manual/D.html @@ -280,7 +280,7 @@ class SomeClass : AnInterface, AnotherInterface { ... } -

    For this to work, AnInterface and AnotherInterface have to be in scope. If SWIG is not in split proxy mode, this is already the case, but it it is, they have to be added to the import list via the dimports typemap. Additionally, the import statement depends on the package SWIG is configured to emit the modules to.

    +

    For this to work, AnInterface and AnotherInterface have to be in scope. If SWIG is not in split proxy mode, this is already the case, but if it is, they have to be added to the import list via the dimports typemap. Additionally, the import statement depends on the package SWIG is configured to emit the modules to.

    The $importtype macro helps you to elegantly solve this problem:

     %typemap(dimports) RemoteMpe %{
    diff --git a/Doc/Manual/Extending.html b/Doc/Manual/Extending.html
    index 80fe77d4d..b56657847 100644
    --- a/Doc/Manual/Extending.html
    +++ b/Doc/Manual/Extending.html
    @@ -729,7 +729,7 @@ For instance, the following example uses %rename in reverse to generate
     
     %rename(foo) foo_i(int);
    -%rename(foo) foo_d(double;
    +%rename(foo) foo_d(double);
     
     void foo_i(int);
     void foo_d(double);
    @@ -1576,7 +1576,7 @@ return the node for the first class member.
     
     
    Returns the last child node. You might use this if you wanted to append a new -node to the of a class. +node to the children of a class.

    @@ -2592,36 +2592,36 @@ command line options, simply use code similar to this:

     void Language::main(int argc, char *argv[]) {
       for (int i = 1; i < argc; i++) {
    -      if (argv[i]) {
    -          if (strcmp(argv[i], "-interface") == 0) {
    -            if (argv[i+1]) {
    -              interface = NewString(argv[i+1]);
    -              Swig_mark_arg(i);
    -              Swig_mark_arg(i+1);
    -              i++;
    -            } else {
    -              Swig_arg_error();
    -            }
    -          } else if (strcmp(argv[i], "-globals") == 0) {
    -            if (argv[i+1]) {
    -              global_name = NewString(argv[i+1]);
    -              Swig_mark_arg(i);
    -              Swig_mark_arg(i+1);
    -              i++;
    -            } else {
    -              Swig_arg_error();
    -            }
    -          } else if ((strcmp(argv[i], "-proxy") == 0)) {
    -            proxy_flag = 1;
    -            Swig_mark_arg(i);
    -          } else if (strcmp(argv[i], "-keyword") == 0) {
    -            use_kw = 1;
    -            Swig_mark_arg(i);
    -          } else if (strcmp(argv[i], "-help") == 0) {
    -            fputs(usage, stderr);
    -          }
    -          ...
    +    if (argv[i]) {
    +      if (strcmp(argv[i], "-interface") == 0) {
    +        if (argv[i+1]) {
    +          interface = NewString(argv[i+1]);
    +          Swig_mark_arg(i);
    +          Swig_mark_arg(i+1);
    +          i++;
    +        } else {
    +          Swig_arg_error();
    +        }
    +      } else if (strcmp(argv[i], "-globals") == 0) {
    +        if (argv[i+1]) {
    +          global_name = NewString(argv[i+1]);
    +          Swig_mark_arg(i);
    +          Swig_mark_arg(i+1);
    +          i++;
    +        } else {
    +          Swig_arg_error();
    +        }
    +      } else if ((strcmp(argv[i], "-proxy") == 0)) {
    +        proxy_flag = 1;
    +        Swig_mark_arg(i);
    +      } else if (strcmp(argv[i], "-keyword") == 0) {
    +        use_kw = 1;
    +        Swig_mark_arg(i);
    +      } else if (strcmp(argv[i], "-help") == 0) {
    +        fputs(usage, stderr);
           }
    +      ...
    +    }
       }
     }
     
    @@ -3164,7 +3164,7 @@ these kinds of problems.

    Examples/Makefile.in -
    Nothing special here; see comments at top the of this file +
    Nothing special here; see comments at the top of this file and look to the existing languages for examples.
    Examples/qux99/check.list diff --git a/Doc/Manual/Go.html b/Doc/Manual/Go.html index f25e9850b..820921bd5 100644 --- a/Doc/Manual/Go.html +++ b/Doc/Manual/Go.html @@ -639,12 +639,12 @@ public: virtual ~FooBarAbstract() {}; std::string FooBar() { - return this->Foo() + ", " + this->Bar(); + return this->Foo() + ", " + this->Bar(); }; protected: virtual std::string Foo() { - return "Foo"; + return "Foo"; }; virtual std::string Bar() = 0; diff --git a/Doc/Manual/Java.html b/Doc/Manual/Java.html index bd259e60d..85757d1cb 100644 --- a/Doc/Manual/Java.html +++ b/Doc/Manual/Java.html @@ -3923,12 +3923,24 @@ is used in the feature code. Consider the following, which also happens to be th if ($error) { jenv->ExceptionClear(); $directorthrowshandlers - throw Swig::DirectorException(jenv, $error); + Swig::DirectorException::raise(jenv, $error); } %}
    +

    +where Swig::DirectorException::raise is a helper method in the DirectorException class to throw a C++ exception (implemented in director.swg): +

    + +
    +
    +  static void raise(JNIEnv *jenv, jthrowable throwable) {
    +    throw DirectorException(jenv, throwable);
    +  }
    +
    +
    +

    The code generated using the director:except feature replaces the $directorthrowshandlers special variable with the code in the "directorthrows" typemaps, for each and every exception defined for the method. @@ -3963,7 +3975,7 @@ if (swigerror) { throw std::out_of_range(Swig::JavaExceptionMessage(jenv, swigerror).message()); } - throw Swig::DirectorException(jenv, swigerror); + Swig::DirectorException::raise(jenv, swigerror); }

    @@ -4093,7 +4105,7 @@ the exception specification or %catches feature.

    Note that the "directorthrows" typemaps are important -only if it is important for the the exceptions passed through the C++ +only if it is important for the exceptions passed through the C++ layer to be mapped to distinct C++ exceptions. If director methods are being called by C++ code that is itself wrapped in a SWIG generated Java wrapper and access is always through this wrapper, @@ -4323,16 +4335,16 @@ struct Vector { %extend Vector { char *toString() { - static char tmp[1024]; - sprintf(tmp, "Vector(%g, %g, %g)", $self->x, $self->y, $self->z); - return tmp; + static char tmp[1024]; + sprintf(tmp, "Vector(%g, %g, %g)", $self->x, $self->y, $self->z); + return tmp; } Vector(double x, double y, double z) { - Vector *v = (Vector *) malloc(sizeof(Vector)); - v->x = x; - v->y = y; - v->z = z; - return v; + Vector *v = (Vector *) malloc(sizeof(Vector)); + v->x = x; + v->y = y; + v->z = z; + return v; } }; @@ -5266,7 +5278,7 @@ void * operator new(size_t t) { throw bad_alloc(); pJalloc->ref = 0; return static_cast<void *>( - static_cast<char *>(static_cast<void *>(pJalloc)) + sizeof(Jalloc)); + static_cast<char *>(static_cast<void *>(pJalloc)) + sizeof(Jalloc)); } } @@ -5681,6 +5693,17 @@ The most important of these implement the mapping of C/C++ types to Java types: In other words the typemap provides the conversion from the native method call return type. + +jboxtype +Java boxed type. + These are Java code typemaps to provide the Java boxed type, such as, Integer for C type int. + As autoboxing is only relevant to the Java primitive types, these are only provided for the + C types that map to Java primitive types. + This typemap is usually only used by C++ STL container wrappers that are wrapped by Java generic + types as the boxed type must be used instead of the unboxed/primitive type when declaring a Java generic type. + + + javadirectorin Conversion from jtype to jstype for director methods. @@ -7217,7 +7240,7 @@ public class runme { example.print_args(animals); String args[] = example.get_args(); for (int i=0; i<args.length; i++) - System.out.println(i + ":" + args[i]); + System.out.println(i + ":" + args[i]); } } diff --git a/Doc/Manual/Library.html b/Doc/Manual/Library.html index 4bad9a03e..8939c8df0 100644 --- a/Doc/Manual/Library.html +++ b/Doc/Manual/Library.html @@ -12,26 +12,32 @@

    -

    9.4 STL/C++ Library

    +

    9.4 STL/C++ library

    @@ -1385,16 +1391,24 @@ The following table shows which C++ classes are supported and the equivalent SWI SWIG Interface library file + std::array (C++11) array std_array.i std::auto_ptr memory std_auto_ptr.i + std::complex complex std_complex.i std::deque deque std_deque.i std::list list std_list.i std::map map std_map.i + std::multimap (C++11) multimap std_multimap.i + std::multiset (C++11) multiset std_multiset.i std::pair utility std_pair.i std::set set std_set.i std::string string std_string.i + std::unordered_map (C++11) unordered_map std_unordered_map.i + std::unordered_multimap (C++11) unordered_multimap std_unordered_multimap.i + std::unordered_multiset (C++11) unordered_multiset std_unordered_multiset.i + std::unordered_set (C++11) unordered_set std_unordered_set.i std::vector vector std_vector.i - std::array array (C++11) std_array.i - std::shared_ptr shared_ptr (C++11) std_shared_ptr.i + std::wstring wstring std_wstring.i + std::shared_ptr (C++11) shared_ptr std_shared_ptr.i @@ -1720,6 +1734,9 @@ Any thrown STL exceptions will then be gracefully handled instead of causing a c

    9.4.4 shared_ptr smart pointer

    +

    9.4.4.1 shared_ptr basics

    + +

    Some target languages have support for handling the shared_ptr reference counted smart pointer. This smart pointer is available in the standard C++11 library as std::shared_ptr. @@ -1813,8 +1830,11 @@ System.out.println(val1 + " " + val2);

    +

    9.4.4.2 shared_ptr and inheritance

    + +

    -This shared_ptr library works quite differently to SWIG's normal, but somewhat limited, +The shared_ptr library works quite differently to SWIG's normal, but somewhat limited, smart pointer handling. The shared_ptr library does not generate extra wrappers, just for smart pointer handling, in addition to the proxy class. The normal proxy class including inheritance relationships is generated as usual. @@ -1892,7 +1912,7 @@ Adding the missing %shared_ptr macros will fix this:

    -%include "boost_shared_ptr.i"
    +%include <boost_shared_ptr.i>
     %shared_ptr(GrandParent);
     %shared_ptr(Parent);
     %shared_ptr(Child);
    @@ -1901,8 +1921,52 @@ Adding the missing %shared_ptr macros will fix this:
     
    +

    9.4.4.3 shared_ptr and templates

    +

    -Note: There is somewhat limited support for %shared_ptr and the director feature +The %shared_ptr macro should be used for all the required instantiations +of the template before each of the %template instantiations. +For example, consider number.h containing the following illustrative template: +

    + +
    +
    +#include <memory>
    +
    +template<int N> struct Number {
    +  int num;
    +  Number() : num(N) {}
    +  static std::shared_ptr<Number<N>> make() { return std::make_shared<Number<N>>(); }
    +};
    +
    +
    + +

    +The SWIG code below shows the required ordering: +

    + +
    +
    +%include <std_shared_ptr.i>
    +
    +%shared_ptr(Number<10>);
    +%shared_ptr(Number<42>);
    +
    +%{
    +  #include "number.h"
    +%}
    +%include "number.h"
    +
    +%template(Number10) Number<10>;
    +%template(Number42) Number<42>;
    +
    +
    + +

    9.4.4.4 shared_ptr and directors

    + + +

    +There is somewhat limited support for %shared_ptr and the director feature and the degrees of success varies among the different target languages. Please help to improve this support by providing patches with improvements.

    diff --git a/Doc/Manual/Lisp.html b/Doc/Manual/Lisp.html index ba42f735c..7bf8562c5 100644 --- a/Doc/Manual/Lisp.html +++ b/Doc/Manual/Lisp.html @@ -122,9 +122,12 @@ swig -cffi -help

    27.2.2 Generating CFFI bindings

    +

    + As we mentioned earlier the ideal way to use SWIG is to use interface files. To illustrate the use of it, let's assume that we have a file named test.h with the following C code: +

     #define y 5
    @@ -155,7 +158,10 @@ void lispsort_double (int n, double * array);
     enum color { RED, BLUE, GREEN};
     
    +

    Corresponding to this we will write a simple interface file: +

    +
     %module test
     
    @@ -163,7 +169,9 @@ Corresponding to this we will write a simple interface file:
     
     
    +

    The generated SWIG Code will be: +

     ;;;SWIG wrapper code starts here
    @@ -430,8 +438,10 @@ Also, while parsing the C++ file and generating C wrapper code SWIG
     %include "target/header.h"
     
     
    +

    Various features which were available for C headers can also be used here. The target header which we are going to use here is: +

     namespace OpenDemo {
       class Test
    @@ -478,8 +488,10 @@ namespace OpenDemo {
     %include "test.cpp"
     
    +

    SWIG generates 3 files, the first one is a C wrap which we don't show, the second is the plain CFFI wrapper which is as shown below: +

     (cffi:defcfun ("_wrap_Test_x_set" Test_x_set) :void
       (self :pointer)
    @@ -528,11 +540,13 @@ SWIG generates 3 files, the first one is a C wrap which we don't show,
     (cffi:defcfun ("_wrap_RandomUnitVectorOnXZPlane" RandomUnitVectorOnXZPlane) :pointer)
     
    +

    The output is pretty good but it fails in disambiguating overloaded functions such as the constructor, in this case. One way of resolving this problem is to make the interface use the rename directiv, but hopefully there are better solutions. In addition SWIG also generates, a CLOS file +

    diff --git a/Doc/Manual/Lua.html b/Doc/Manual/Lua.html
    index c94fe31dc..c5c944225 100644
    --- a/Doc/Manual/Lua.html
    +++ b/Doc/Manual/Lua.html
    @@ -1008,11 +1008,10 @@ The following operators cannot be overloaded (mainly because they are not suppor
     

    SWIG also accepts the __str__() member function which converts an object to a string. This function should return a const char*, preferably to static memory. This will be used for the print() and tostring() functions in Lua. Assuming the complex class has a function

    -
    const char* __str__()
    -{
    -        static char buffer[255];
    -        sprintf(buffer, "Complex(%g, %g)", this->re(), this->im());
    -        return buffer;
    +
    const char* __str__() {
    +  static char buffer[255];
    +  sprintf(buffer, "Complex(%g, %g)", this->re(), this->im());
    +  return buffer;
     }
     

    @@ -1031,11 +1030,10 @@ Complex(10, 12)

    It is also possible to overload the operator[], but currently this cannot be automatically performed. To overload the operator[] you need to provide two functions, __getitem__() and __setitem__()

    -
    class Complex
    -{
    -        //....
    -        double __getitem__(int i)const; // i is the index, returns the data
    -        void __setitem__(int i, double d); // i is the index, d is the data
    +
    class Complex {
    +  //....
    +  double __getitem__(int i)const; // i is the index, returns the data
    +  void __setitem__(int i, double d); // i is the index, d is the data
     };
     

    diff --git a/Doc/Manual/Perl5.html b/Doc/Manual/Perl5.html index 96e9f7517..8ea43ad6b 100644 --- a/Doc/Manual/Perl5.html +++ b/Doc/Manual/Perl5.html @@ -949,7 +949,7 @@ Foo *BarToFoo(Bar *b) { } Foo *IncrFoo(Foo *f, int i) { - return f+i; + return f+i; } %}

    @@ -1057,7 +1057,7 @@ produces a single accessor function like this:
     int *Foo_x_get(Foo *self) {
    -    return self->x;
    +  return self->x;
     };
     
    @@ -1092,11 +1092,11 @@ generates accessor functions such as this:
     Foo *Bar_f_get(Bar *b) {
    -    return &b->f;
    +  return &b->f;
     }
     
     void Bar_f_set(Bar *b, Foo *val) {
    -    b->f = *val;
    +  b->f = *val;
     }
     
    @@ -1633,9 +1633,8 @@ class DoubleArray { void setitem(int i, double val) { if ((i >= 0) && (i < n)) ptr[i] = val; - else { + else throw RangeError(); - } } };
    @@ -1888,9 +1887,9 @@ like this:
     %typemap(out) int {
    -    $result = sv_newmortal();
    -    set_setiv($result, (IV) $1);
    -    argvi++;
    +  $result = sv_newmortal();
    +  set_setiv($result, (IV) $1);
    +  argvi++;
     }
     
    @@ -2313,8 +2312,8 @@ Consider the following data structure:
     #define SIZE  8
     typedef struct {
    -    int   values[SIZE];
    -    ...
    +  int   values[SIZE];
    +  ...
     } Foo;
     
     
    @@ -2328,10 +2327,10 @@ To make the member writable, a "memberin" typemap can be used.
     %typemap(memberin) int [SIZE] {
    -    int i;
    -    for (i = 0; i < SIZE; i++) {
    -        $1[i] = $input[i];
    -    }
    +  int i;
    +  for (i = 0; i < SIZE; i++) {
    +    $1[i] = $input[i];
    +  }
     }
     
     
    @@ -2600,48 +2599,48 @@ package example::Vector; %BLESSEDMEMBERS = (); sub new () { - my $self = shift; - my @args = @_; - $self = vectorc::new_Vector(@args); - return undef if (!defined($self)); - bless $self, "example::Vector"; - $OWNER{$self} = 1; - my %retval; - tie %retval, "example::Vector", $self; - return bless \%retval, "Vector"; + my $self = shift; + my @args = @_; + $self = vectorc::new_Vector(@args); + return undef if (!defined($self)); + bless $self, "example::Vector"; + $OWNER{$self} = 1; + my %retval; + tie %retval, "example::Vector", $self; + return bless \%retval, "Vector"; } sub DESTROY { - return unless $_[0]->isa('HASH'); - my $self = tied(%{$_[0]}); - delete $ITERATORS{$self}; - if (exists $OWNER{$self}) { - examplec::delete_Vector($self)); - delete $OWNER{$self}; - } + return unless $_[0]->isa('HASH'); + my $self = tied(%{$_[0]}); + delete $ITERATORS{$self}; + if (exists $OWNER{$self}) { + examplec::delete_Vector($self)); + delete $OWNER{$self}; + } } sub FETCH { - my ($self, $field) = @_; - my $member_func = "vectorc::Vector_${field}_get"; - my $val = &$member_func($self); - if (exists $BLESSEDMEMBERS{$field}) { - return undef if (!defined($val)); - my %retval; - tie %retval, $BLESSEDMEMBERS{$field}, $val; - return bless \%retval, $BLESSEDMEMBERS{$field}; - } - return $val; + my ($self, $field) = @_; + my $member_func = "vectorc::Vector_${field}_get"; + my $val = &$member_func($self); + if (exists $BLESSEDMEMBERS{$field}) { + return undef if (!defined($val)); + my %retval; + tie %retval, $BLESSEDMEMBERS{$field}, $val; + return bless \%retval, $BLESSEDMEMBERS{$field}; + } + return $val; } sub STORE { - my ($self, $field, $newval) = @_; - my $member_func = "vectorc::Vector_${field}_set"; - if (exists $BLESSEDMEMBERS{$field}) { - &$member_func($self, tied(%{$newval})); - } else { - &$member_func($self, $newval); - } + my ($self, $field, $newval) = @_; + my $member_func = "vectorc::Vector_${field}_set"; + if (exists $BLESSEDMEMBERS{$field}) { + &$member_func($self, tied(%{$newval})); + } else { + &$member_func($self, $newval); + } }
    @@ -2842,11 +2841,11 @@ this:
     sub dot_product {
    -    my @args = @_;
    -    $args[0] = tied(%{$args[0]});         # Get the real pointer values
    -    $args[1] = tied(%{$args[1]});
    -    my $result = vectorc::dot_product(@args);
    -    return $result;
    +  my @args = @_;
    +  $args[0] = tied(%{$args[0]});         # Get the real pointer values
    +  $args[1] = tied(%{$args[1]});
    +  my $result = vectorc::dot_product(@args);
    +  return $result;
     }
     
    @@ -2985,7 +2984,7 @@ sub set_transform for (my $j = 0; $j < 4, $j++) { mat44_set($a, $i, $j, $x->[i][j]) - } + } } example.set_transform($im, $a); free_mat44($a); @@ -3104,14 +3103,14 @@ the methods one() and two() (but not three()): %feature("director") Foo; class Foo { public: - Foo(int foo); - virtual void one(); - virtual void two(); + Foo(int foo); + virtual void one(); + virtual void two(); }; class Bar: public Foo { public: - virtual void three(); + virtual void three(); }; @@ -3279,9 +3278,9 @@ suffice in most cases:
     %feature("director:except") {
    -    if ($error != NULL) {
    -        throw Swig::DirectorMethodException();
    -    }
    +  if ($error != NULL) {
    +    throw Swig::DirectorMethodException();
    +  }
     }
     
    @@ -3305,8 +3304,8 @@ suitable exception handler:
     %exception {
    -    try { $action }
    -    catch (Swig::DirectorException &e) { SWIG_fail; }
    +  try { $action }
    +  catch (Swig::DirectorException &e) { SWIG_fail; }
     }
     
    diff --git a/Doc/Manual/Php.html b/Doc/Manual/Php.html index 52bedf87f..9fbfd75c0 100644 --- a/Doc/Manual/Php.html +++ b/Doc/Manual/Php.html @@ -163,7 +163,7 @@ If the module is in PHP's default extension directory, you can omit the path.

    For some SAPIs (for example, the CLI SAPI) you can instead use the dl() function to load -an extension at run time, by adding a like like this to the start of each +an extension at run time, by adding a line like this to the start of each PHP script which uses your extension:

    @@ -390,8 +390,7 @@ Although PHP does not support overloading functions natively, swig will generate dispatch functions which will use %typecheck typemaps to allow overloading. This dispatch function's operation and precedence is described in Wrapping -Overloaded Functions and Methods. +href="SWIGPlus.html#SWIGPlus_overloaded_methods">Overloaded functions and methods.

    @@ -162,7 +167,7 @@ Basics" chapter.

    To build Python extension modules, SWIG uses a layered approach in which -parts of the extension module are defined in C and other parts are +parts of the extension module are defined in C and other parts are defined in Python. The C layer contains low-level wrappers whereas Python code is used to define high-level features.

    @@ -221,16 +226,15 @@ resulting C file should be built as a python extension, inserting the module #include "example.h" int fact(int n) { - if (n < 0){ /* This should probably return an error, but this is simpler */ - return 0; - } - if (n == 0) { - return 1; - } - else { - /* testing for overflow would be a good idea here */ - return n * fact(n-1); - } + if (n < 0) { /* This should probably return an error, but this is simpler */ + return 0; + } + if (n == 0) { + return 1; + } else { + /* testing for overflow would be a good idea here */ + return n * fact(n-1); + } } @@ -395,9 +399,9 @@ $ gcc -shared example.o example_wrap.o -o _example.so

    -The exact commands for doing this vary from platform to platform. -However, SWIG tries to guess the right options when it is installed. Therefore, -you may want to start with one of the examples in the SWIG/Examples/python +The exact commands for doing this vary from platform to platform. +However, SWIG tries to guess the right options when it is installed. Therefore, +you may want to start with one of the examples in the SWIG/Examples/python directory. If that doesn't work, you will need to read the man-pages for your compiler and linker to get the right set of options. You might also check the SWIG Wiki for @@ -409,7 +413,7 @@ When linking the module, the name of the output file has to match the name of the module prefixed by an underscore. If the name of your module is "example", then the name of the corresponding object file should be "_example.so" or "_examplemodule.so". -The name of the module is specified using the %module directive or the +The name of the module is specified using the %module directive or the -module command line option.

    @@ -433,7 +437,7 @@ An alternative approach to dynamic linking is to rebuild the Python interpreter with your extension module added to it. In the past, this approach was sometimes necessary due to limitations in dynamic loading support on certain machines. However, the situation has improved greatly -over the last few years and you should not consider this approach +over the last few years and you should not consider this approach unless there is really no other option.

    @@ -493,7 +497,7 @@ linking if possible. Some programmers may be inclined to use static linking in the interest of getting better performance. However, the performance gained by static linking tends to be rather minimal in most situations (and quite frankly not worth the extra -hassle in the opinion of this author). +hassle in the opinion of this author).

    @@ -552,13 +556,13 @@ Another possible error is the following: Traceback (most recent call last): File "<stdin>", line 1, in ? ImportError: dynamic module does not define init function (init_example) ->>> +>>>

    -This error is almost always caused when a bad name is given to the shared object file. -For example, if you created a file example.so instead of _example.so you would +This error is almost always caused when a bad name is given to the shared object file. +For example, if you created a file example.so instead of _example.so you would get this error. Alternatively, this error could arise if the name of the module is inconsistent with the module name supplied with the %module directive. Double-check the interface to make sure the module name and the shared object @@ -584,7 +588,7 @@ This error usually indicates that you forgot to include some object files or libraries in the linking of the shared library file. Make sure you compile both the SWIG wrapper file and your original program into a shared library file. Make sure you pass all of the required libraries -to the linker. +to the linker.

    @@ -619,7 +623,7 @@ problem when you try to use your module: Traceback (most recent call last): File "<stdin>", line 1, in ? ImportError: libfoo.so: cannot open shared object file: No such file or directory ->>> +>>> @@ -642,7 +646,7 @@ $ gcc -shared example.o example_wrap.o -L/home/beazley/projects/lib -lfoo \

    Alternatively, you can set the LD_LIBRARY_PATH environment variable to -include the directory with your shared libraries. +include the directory with your shared libraries. If setting LD_LIBRARY_PATH, be aware that setting this variable can introduce a noticeable performance impact on all other applications that you run. To set it only for Python, you might want to do this instead: @@ -707,7 +711,7 @@ $ CC -G example.o example_wrap.o -L/opt/SUNWspro/lib -o _example.so -lCrun

    -Of course, the extra libraries to use are completely non-portable---you will +Of course, the extra libraries to use are completely non-portable---you will probably need to do some experimentation.

    @@ -715,8 +719,8 @@ probably need to do some experimentation. Sometimes people have suggested that it is necessary to relink the Python interpreter using the C++ compiler to make C++ extension modules work. In the experience of this author, this has never actually appeared to be -necessary. Relinking the interpreter with C++ really only includes the -special run-time libraries described above---as long as you link your extension +necessary. Relinking the interpreter with C++ really only includes the +special run-time libraries described above---as long as you link your extension modules with these libraries, it should not be necessary to rebuild Python.

    @@ -760,7 +764,7 @@ might want to investigate using a more formal standard such as COM. On platforms that support 64-bit applications (Solaris, Irix, etc.), special care is required when building extension modules. On these machines, 64-bit applications are compiled and linked using a different -set of compiler/linker options. In addition, it is not generally possible to mix +set of compiler/linker options. In addition, it is not generally possible to mix 32-bit and 64-bit code together in the same application.

    @@ -814,10 +818,10 @@ If you need to build it on your own, the following notes are provided:

    -You will need to create a DLL that can be loaded into the interpreter. +You will need to create a DLL that can be loaded into the interpreter. This section briefly describes the use of SWIG with Microsoft Visual C++. As a starting point, many of SWIG's examples include project -files (.dsp files) for Visual C++ 6. These can be opened by more +files (.dsp files) for Visual C++ 6. These can be opened by more recent versions of Visual Studio. You might want to take a quick look at these examples in addition to reading this section. @@ -852,7 +856,7 @@ settings, select the "Custom Build" option. "C++:Preprocessor". Add the include directories for your Python installation under "Additional include directories". -

  • Define the symbol __WIN32__ under preprocessor options. +
  • Define the symbol __WIN32__ under preprocessor options.
  • Finally, select the settings for the entire project and go to "Link Options". Add the Python library file to your link libraries. @@ -866,7 +870,7 @@ match the name of your Python module, ie. _example.pyd - Note that _example.dll If all went well, SWIG will be automatically invoked whenever you build your project. Any changes made to the interface file will result in SWIG being automatically executed to produce a new version of -the wrapper file. +the wrapper file.

    @@ -885,9 +889,9 @@ $ python

    If you get an ImportError exception when importing the module, you may have forgotten to include additional library files when you built your module. -If you get an access violation or some kind of general protection fault -immediately upon import, you have a more serious problem. This -is often caused by linking your extension module against the wrong +If you get an access violation or some kind of general protection fault +immediately upon import, you have a more serious problem. This +is often caused by linking your extension module against the wrong set of Win32 debug or thread libraries. You will have to fiddle around with the build options of project to try and track this down.

    @@ -938,7 +942,7 @@ wrapped into a Python 'example' module. Underneath the covers, this module consists of a Python source file example.py and a low-level extension module _example.so. When choosing a module name, make sure you don't use the same name as a built-in -Python command or standard module name. +Python command or standard module name.

    36.3.2 Functions

    @@ -991,8 +995,8 @@ then "a" and "b" are both names for the object containing the value 3.4. Thus, there is only one object containing 3.4 and "a" and "b" are both names that refer to it. This is quite different than C where a variable name refers to a memory location in which -a value is stored (and assignment copies data into that location). -Because of this, there is no direct way to map variable +a value is stored (and assignment copies data into that location). +Because of this, there is no direct way to map variable assignment in C to variable assignment in Python.

    @@ -1038,7 +1042,7 @@ error message. For example: Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: C variable 'density (double )' ->>> +>>>

    @@ -1188,7 +1192,7 @@ simply represented as opaque values using an especial python container object:

    This pointer value can be freely passed around to different C functions that -expect to receive an object of type FILE *. The only thing you can't do is +expect to receive an object of type FILE *. The only thing you can't do is dereference the pointer from Python. Of course, that isn't much of a concern in this example.

    @@ -1271,7 +1275,7 @@ Foo *BarToFoo(Bar *b) { } Foo *IncrFoo(Foo *f, int i) { - return f+i; + return f+i; } %} @@ -1309,7 +1313,7 @@ is used as follows: >>> v.y = 7.2 >>> print v.x, v.y, v.z 7.8 -4.5 0.0 ->>> +>>>

    @@ -1368,7 +1372,7 @@ struct Foo {

    When char * members of a structure are wrapped, the contents are assumed to be dynamically allocated using malloc or new (depending on whether or not -SWIG is run with the -c++ option). When the structure member is set, the old contents will be +SWIG is run with the -c++ option). When the structure member is set, the old contents will be released and a new value created. If this is not the behavior you want, you will have to use a typemap (described later).

    @@ -1381,7 +1385,7 @@ example, consider this:
     struct Bar {
    -    int  x[16];
    +  int  x[16];
     };
     
    @@ -1395,7 +1399,7 @@ If accessed in Python, you will see behavior like this: >>> b = example.Bar() >>> print b.x _801861a4_p_int ->>> +>>> @@ -1460,7 +1464,7 @@ Foo *x = &b->f; /* Points inside b */

    -Because the pointer points inside the structure, you can modify the contents and +Because the pointer points inside the structure, you can modify the contents and everything works just like you would expect. For example:

    @@ -1468,7 +1472,7 @@ everything works just like you would expect. For example:
     >>> b = Bar()
     >>> b.f.a = 3               # Modify attribute of structure member
    ->>> x = b.f                   
    +>>> x = b.f
     >>> x.a = 3                 # Modifies the same structure
     
    @@ -1510,13 +1514,13 @@ you can use it in Python like this:

    -Class data members are accessed in the same manner as C structures. +Class data members are accessed in the same manner as C structures.

    -Static class members present a special problem for Python. Prior to Python-2.2, +Static class members present a special problem for Python. Prior to Python-2.2, Python classes had no support for static methods and no version of Python -supports static member variables in a manner that SWIG can utilize. Therefore, +supports static member variables in a manner that SWIG can utilize. Therefore, SWIG generates wrappers that try to work around some of these issues. To illustrate, suppose you have a class like this:

    @@ -1669,10 +1673,10 @@ const Foo &spam9();

    then all three functions will return a pointer to some Foo object. -Since the third function (spam8) returns a value, newly allocated memory is used -to hold the result and a pointer is returned (Python will release this memory +Since the third function (spam8) returns a value, newly allocated memory is used +to hold the result and a pointer is returned (Python will release this memory when the return value is garbage collected). The fourth case (spam9) -which returns a const reference, in most of the cases will be +which returns a const reference, in most of the cases will be treated as a returning value, and it will follow the same allocation/deallocation process.

    @@ -1711,9 +1715,9 @@ Similarly, if you have a class like this,
     class Foo {
     public:
    -    Foo();
    -    Foo(const Foo &);
    -    ...
    +  Foo();
    +  Foo(const Foo &);
    +  ...
     };
     
    @@ -1771,7 +1775,7 @@ To fix this, you either need to ignore or rename one of the methods. For exampl
     %rename(spam_short) spam(short);
     ...
    -void spam(int);    
    +void spam(int);
     void spam(short);   // Accessed as spam_short
     
    @@ -1784,7 +1788,7 @@ or
     %ignore spam(short);
     ...
    -void spam(int);    
    +void spam(int);
     void spam(short);   // Ignored
     
    @@ -1797,7 +1801,7 @@ first declaration takes precedence.

    -Please refer to the "SWIG and C++" chapter for more information about overloading. +Please refer to the "SWIG and C++" chapter for more information about overloading.

    36.3.11 C++ operators

    @@ -1823,7 +1827,7 @@ public: Complex operator-(const Complex &c) const; Complex operator*(const Complex &c) const; Complex operator-() const; - + double re() const { return rpart; } double im() const { return ipart; } }; @@ -1889,6 +1893,14 @@ Also, be aware that certain operators don't map cleanly to Python. For instance overloaded assignment operators don't map to Python semantics and will be ignored.

    +

    +Operator overloading is implemented in the pyopers.swg library file. +In particular overloaded operators are marked with the python:maybecall feature, also known as %pythonmaybecall. +This feature forces SWIG to generate code that return an instance of Python's NotImplemented +instead of raising an exception when the comparison fails, that is, on any kind of error. +This follows the guidelines in PEP 207 - Rich Comparisons and NotImplemented Python constant. +

    +

    36.3.12 C++ namespaces

    @@ -1938,11 +1950,11 @@ For example: %rename(Bar_spam) Bar::spam; namespace Foo { - int spam(); + int spam(); } namespace Bar { - int spam(); + int spam(); } @@ -2005,7 +2017,7 @@ In Python:

    Obviously, there is more to template wrapping than shown in this example. -More details can be found in the SWIG and C++ chapter. +More details can be found in the SWIG and C++ chapter. Some more complicated examples will appear later.

    @@ -2153,9 +2165,9 @@ have a class like this
     class Foo {
     public:
    -    int x;
    -    int spam(int);
    -    ...
    +  int x;
    +  int spam(int);
    +  ...
     
    @@ -2166,19 +2178,19 @@ then SWIG transforms it into a set of low-level procedural wrappers. For example
     Foo *new_Foo() {
    -    return new Foo();
    +  return new Foo();
     }
     void delete_Foo(Foo *f) {
    -    delete f;
    +  delete f;
     }
     int Foo_x_get(Foo *f) {
    -    return f->x;
    +  return f->x;
     }
     void Foo_x_set(Foo *f, int value) {
    -    f->x = value;
    +  f->x = value;
     }
     int Foo_spam(Foo *f, int arg1) {
    -    return f->spam(arg1);
    +  return f->spam(arg1);
     }
     
    @@ -2188,7 +2200,7 @@ These wrappers can be found in the low-level extension module (e.g., _exampl

    -Using these wrappers, SWIG generates a high-level Python proxy class (also known as a shadow class) like this (shown +Using these wrappers, SWIG generates a high-level Python proxy class (also known as a shadow class) like this (shown for Python 2.2):

    @@ -2210,7 +2222,7 @@ class Foo(object):

    -This class merely holds a pointer to the underlying C++ object (.this) and dispatches methods and +This class merely holds a pointer to the underlying C++ object (.this) and dispatches methods and member variable access to that object using the low-level accessor functions. From a user's point of view, it makes the class work normally:

    @@ -2254,7 +2266,7 @@ class Foo(object):

    When a Foo instance is created, the call to _example.new_Foo() -creates a new C++ Foo instance; wraps that C++ instance inside an instance of +creates a new C++ Foo instance; wraps that C++ instance inside an instance of a python built-in type called SwigPyObject; and stores the SwigPyObject instance in the 'this' field of the python Foo object. Did you get all that? So, the python Foo object is composed of three parts:

    @@ -2297,10 +2309,10 @@ please refer to the python documentation:

     typedef struct {
    -    PyObject_HEAD
    -    PyObject *dict;
    -    PyObject *args;
    -    PyObject *message;
    +  PyObject_HEAD
    +  PyObject *dict;
    +  PyObject *args;
    +  PyObject *message;
     } PyBaseExceptionObject;
     
    @@ -2310,12 +2322,12 @@ typedef struct {
     typedef struct {
    -    PyObject_HEAD
    -    void *ptr;
    -    swig_type_info *ty;
    -    int own;
    -    PyObject *next;
    -    PyObject *dict;
    +  PyObject_HEAD
    +  void *ptr;
    +  swig_type_info *ty;
    +  int own;
    +  PyObject *next;
    +  PyObject *dict;
     } SwigPyObject;
     
    @@ -2326,13 +2338,13 @@ typedef struct {
     class MyException {
     public:
    -    MyException (const char *msg_);
    -    ~MyException ();
    +  MyException (const char *msg_);
    +  ~MyException ();
     
    -    const char *what () const;
    +  const char *what () const;
     
     private:
    -    char *msg;
    +  char *msg;
     };
     
    @@ -2359,9 +2371,9 @@ strings, you can define an 'operator+ (const char*)' method :

     class MyString {
     public:
    -    MyString (const char *init);
    -    MyString operator+ (const char *other) const;
    -    ...
    +  MyString (const char *init);
    +  MyString operator+ (const char *other) const;
    +  ...
     };
     
    @@ -2460,11 +2472,12 @@ slot entries. For example, suppose you have this class:
     class Twit {
     public:
    -    Twit operator+ (const Twit& twit) const;
    +  Twit operator+ (const Twit& twit) const;
     
    -    // Forward to operator+
    -    Twit add (const Twit& twit) const
    -    { return *this + twit; }
    +  // Forward to operator+
    +  Twit add (const Twit& twit) const {
    +    return *this + twit;
    +  }
     };
     
    @@ -2545,16 +2558,16 @@ public:

    -If you examine the generated code, the supplied hash function will now be +If you examine the generated code, the supplied hash function will now be the function callback in the tp_hash slot for the builtin type for MyClass:

     static PyHeapTypeObject SwigPyBuiltin__MyClass_type = {
    -    ...
    -    (hashfunc) myHashFunc,       /* tp_hash */
    -    ...
    +  ...
    +  (hashfunc) myHashFunc,       /* tp_hash */
    +  ...
     
    @@ -2609,7 +2622,7 @@ when the -builtin option is used.

    Associated with proxy object, is an ownership flag .thisown The value of this flag determines who is responsible for deleting the underlying C++ object. If set to 1, -the Python interpreter will destroy the C++ object when the proxy class is +the Python interpreter will destroy the C++ object when the proxy class is garbage collected. If set to 0 (or if the attribute is missing), then the destruction of the proxy class has no effect on the C++ object.

    @@ -2623,8 +2636,8 @@ ownership of the result. For example:
     class Foo {
     public:
    -    Foo();
    -    Foo bar();
    +  Foo();
    +  Foo bar();
     };
     
    @@ -2653,9 +2666,9 @@ they came from. Therefore, the ownership is set to zero. For example:
     class Foo {
     public:
    -    ...
    -    Foo *spam();
    -    ...
    +  ...
    +  Foo *spam();
    +  ...
     };
     
    @@ -2694,8 +2707,8 @@ or global variable. For example, consider this interface: %module example struct Foo { - int value; - Foo *next; + int value; + Foo *next; }; Foo *head = 0; @@ -2712,7 +2725,7 @@ is assigned to a global variable. For example: >>> f = example.Foo() >>> f.thisown 1 ->>> example.cvar.head = f +>>> example.cvar.head = f >>> f.thisown 0 >>> @@ -2813,7 +2826,7 @@ To address differences between Python versions, SWIG currently emits dual-mode proxy class wrappers. In Python-2.2 and newer releases, these wrappers encapsulate C++ objects in new-style classes that take advantage of new features (static methods and properties). However, -if these very same wrappers are imported into an older version of Python, +if these very same wrappers are imported into an older version of Python, old-style classes are used instead.

    @@ -2883,18 +2896,18 @@ option to the %module directive, like this:

    Without this option no director code will be generated. Second, you -must use the %feature("director") directive to tell SWIG which classes -and methods should get directors. The %feature directive can be applied +must use the %feature("director") directive to tell SWIG which classes +and methods should get directors. The %feature directive can be applied globally, to specific classes, and to specific methods, like this:

     // generate directors for all classes that have virtual methods
    -%feature("director");         
    +%feature("director");
     
     // generate directors for all virtual methods in class Foo
    -%feature("director") Foo;      
    +%feature("director") Foo;
     
    @@ -2912,11 +2925,11 @@ directors for specific classes or methods. So for example,

    will generate directors for all virtual methods of class Foo except -bar(). +bar().

    -Directors can also be generated implicitly through inheritance. +Directors can also be generated implicitly through inheritance. In the following, class Bar will get a director class that handles the methods one() and two() (but not three()):

    @@ -2926,15 +2939,15 @@ the methods one() and two() (but not three()): %feature("director") Foo; class Foo { public: - Foo(int foo); - virtual ~Foo(); - virtual void one(); - virtual void two(); + Foo(int foo); + virtual ~Foo(); + virtual void one(); + virtual void two(); }; class Bar: public Foo { public: - virtual void three(); + virtual void three(); }; @@ -2961,9 +2974,6 @@ class MyFoo(mymodule.Foo):

    36.5.2 Director classes

    - - -

    For each class that has directors enabled, SWIG generates a new class that derives from both the class in question and a special @@ -3077,12 +3087,12 @@ references. Here is an example:

     class Foo {
     public:
    -    ...
    +  ...
     };
     class FooContainer {
     public:
    -    void addFoo(Foo *);
    -    ...
    +  void addFoo(Foo *);
    +  ...
     };
     
    @@ -3123,9 +3133,9 @@ suffice in most cases:
     %feature("director:except") {
    -    if ($error != NULL) {
    -        throw Swig::DirectorMethodException();
    -    }
    +  if ($error != NULL) {
    +    throw Swig::DirectorMethodException();
    +  }
     }
     
    @@ -3152,8 +3162,8 @@ suitable exception handler:
     %exception {
    -    try { $action }
    -    catch (Swig::DirectorException &e) { SWIG_fail; }
    +  try { $action }
    +  catch (Swig::DirectorException &e) { SWIG_fail; }
     }
     
    @@ -3224,13 +3234,13 @@ be able to use std::vector, std::string, etc., as you would any other type.

    Note: The director typemaps for return types based in const -references, such as +references, such as

     class Foo {
     …
    -    virtual const int& bar();
    +  virtual const int& bar();
     …
     };
     
    @@ -3248,7 +3258,7 @@ types, wherever possible, for example
     class Foo {
     …
    -    virtual int bar();
    +  virtual int bar();
     …
     };
     
    @@ -3498,16 +3508,16 @@ def bar(*args): $action #do something after %} - + class Foo { public: - int bar(int x); + int bar(int x); };

    where $action will be replaced by the call to -the C/C++ proper method. +the C/C++ proper method.

    @@ -3525,7 +3535,7 @@ proxy, just before the return statement.

     %module example
     
    -// Add python code to bar() 
    +// Add python code to bar()
     
     %feature("pythonprepend") Foo::bar(int) %{
         #do something before C++ call
    @@ -3535,10 +3545,10 @@ proxy, just before the return statement.
         #do something after C++ call
     %}
     
    -    
    +
     class Foo {
     public:
    -    int bar(int x);
    +  int bar(int x);
     };
     
    @@ -3554,7 +3564,7 @@ SWIG version 1.3.28 you can use the directive forms
     %module example
     
    -// Add python code to bar() 
    +// Add python code to bar()
     
     %pythonprepend Foo::bar(int) %{
         #do something before C++ call
    @@ -3564,10 +3574,10 @@ SWIG version 1.3.28 you can use the directive forms
         #do something after C++ call
     %}
     
    -    
    +
     class Foo {
     public:
    -    int bar(int x);
    +  int bar(int x);
     };
     
    @@ -3596,8 +3606,8 @@ as it will then get attached to all the overloaded C++ methods. For example: class Foo { public: - int bar(int x); - int bar(); + int bar(int x); + int bar(); }; @@ -3658,7 +3668,7 @@ Vector(2, 3, 4)

    -%extend can be used for many more tasks than this. +%extend can be used for many more tasks than this. For example, if you wanted to overload a Python operator, you might do this:

    @@ -3687,7 +3697,7 @@ Use it like this: >>> w = example.Vector(10, 11, 12) >>> print v+w Vector(12, 14, 16) ->>> +>>> @@ -3991,7 +4001,7 @@ int send_message(char *text, int *success);

    -When used in Python, the function will return multiple values. +When used in Python, the function will return multiple values.

    @@ -4132,17 +4142,17 @@ Sometimes a C function expects an array to be passed as a pointer. For example,
     int sumitems(int *first, int nitems) {
    -    int i, sum = 0;
    -    for (i = 0; i < nitems; i++) {
    -        sum += first[i];
    -    }
    -    return sum;
    +  int i, sum = 0;
    +  for (i = 0; i < nitems; i++) {
    +    sum += first[i];
    +  }
    +  return sum;
     }
     

    -To wrap this into Python, you need to pass an array pointer as the first argument. +To wrap this into Python, you need to pass an array pointer as the first argument. A simple way to do this is to use the carrays.i library file. For example:

    @@ -4219,13 +4229,13 @@ using the cstring.i library file described in the Default arguments section. -There is also an optional Python specific feature that can be used called the python:cdefaultargs +There is also an optional Python specific feature that can be used called the python:cdefaultargs feature flag. By default, SWIG attempts to convert C++ default argument values into Python values and generates code into the Python layer containing these values. @@ -4303,7 +4313,7 @@ class CDA(object):

    Adding the feature:

    - +
     %feature("python:cdefaultargs") CDA::fff;
    @@ -4364,7 +4374,7 @@ as the material in the "Typemaps" chapter.
     

    -Before proceeding, it should be stressed that typemaps are not a required +Before proceeding, it should be stressed that typemaps are not a required part of using SWIG---the default wrapping behavior is enough in most cases. Typemaps are only used if you want to change some aspect of the primitive C-Python interface or if you want to elevate your guru status. @@ -4374,7 +4384,7 @@ C-Python interface or if you want to elevate your guru status.

    -A typemap is nothing more than a code generation rule that is attached to +A typemap is nothing more than a code generation rule that is attached to a specific C datatype. For example, to convert integers from Python to C, you might define a typemap like this:

    @@ -4506,7 +4516,7 @@ like this:

    A detailed list of available methods can be found in the "Typemaps" chapter. +href="Typemaps.html#Typemaps">Typemaps" chapter.

    @@ -4568,7 +4578,7 @@ A PyObject * that holds the result to be returned to Python.

    -The parameter name that was matched. +The parameter name that was matched.

    @@ -4812,7 +4822,7 @@ In the example, two different typemaps are used. The "in" typemap is used to receive an input argument and convert it to a C array. Since dynamic memory allocation is used to allocate memory for the array, the "freearg" typemap is used to later release this memory after the execution of -the C function. +the C function.

    36.9.2 Expanding a Python object into multiple arguments

    @@ -4878,7 +4888,7 @@ previous example:

    -When writing a multiple-argument typemap, each of the types is referenced by a variable such +When writing a multiple-argument typemap, each of the types is referenced by a variable such as $1 or $2. The typemap code simply fills in the appropriate values from the supplied Python object.

    @@ -4960,7 +4970,7 @@ A typemap can be used to handle this case as follows : %module outarg // This tells SWIG to treat an double * argument with name 'OutValue' as -// an output value. We'll append the value to the current result which +// an output value. We'll append the value to the current result which // is guaranteed to be a List object by SWIG. %typemap(argout) double *OutValue { @@ -5312,7 +5322,7 @@ example:
     %define DOCSTRING
    -"The `XmlResource` class allows program resources defining menus, 
    +"The `XmlResource` class allows program resources defining menus,
     layout of controls on a panel, etc. to be loaded from an XML file."
     %enddef
     
    @@ -5607,7 +5617,7 @@ Packages for more information.
     
     

    If you place a SWIG generated module into a Python package then there -are details concerning the way SWIG +are details concerning the way SWIG searches for the wrapper module that you may want to familiarize yourself with.

    @@ -6036,7 +6046,7 @@ zipimporter requires python-3.5.1 or newer to work with subpackages.

    When SWIG creates wrappers from an interface file, say foo.i, two Python modules are -created. There is a pure Python module module (foo.py) and C/C++ code which is +created. There is a pure Python module (foo.py) and C/C++ code which is built and linked into a dynamically (or statically) loaded low-level module _foo (see the Preliminaries section for details). So, the interface file really defines two Python modules. How these two modules are loaded is @@ -6331,7 +6341,7 @@ is backported to 2.6.

     %include <pybuffer.i>
     %pybuffer_mutable_string(char *str);
    -void get_path(char *s);
    +void get_path(char *str);
     

    @@ -6378,7 +6388,7 @@ In Python: >>> snprintf(buf, "Hello world!") >>> print(buf) bytearray(b'Hello\x00') ->>> +>>>

    @@ -6414,7 +6424,7 @@ bytearray(b'FOO\x00')

    Both %pybuffer_mutable_binary and %pybuffer_mutable_string -require the provided buffer to be mutable, eg. they can accept a +require the provided buffer to be mutable, eg. they can accept a bytearray type but can't accept an immutable byte type.

    @@ -6516,7 +6526,7 @@ string that cannot be completely decoded as UTF-8: %inline %{ const char* non_utf8_c_str(void) { - return "h\xe9llo w\xc3\xb6rld"; + return "h\xe9llo w\xc3\xb6rld"; } %} @@ -6730,6 +6740,110 @@ the first is allowing unicode conversion and the second is explicitly prohibiting it.

    +

    36.13 Support for Multithreaded Applications

    + + +

    By default, SWIG does not enable support for multithreaded Python applications. More +specifically, the Python wrappers generated by SWIG will not release the + Python's interpreter's Global Interpreter Lock (GIL) when wrapped C/C++ code is +entered. Hence, while any of the wrapped C/C++ code is executing, the Python interpreter +will not be able to run any other threads, even if the wrapped C/C++ code is waiting + in a blocking call for something like network or disk IO. + + Fortunately, SWIG does have the ability to enable multithreaded support and automatic + release of the GIL either for all wrapped code in a module or on a more selective basis. The user + interface for this is described in the next section. +

    + +

    36.13.1 UI for Enabling Multithreading Support

    + + +

    The user interface is as follows:

    +
      +
    1. Module thread support can be enabled in two ways:

      +
        +
      • +

        + The -threads swig python option at the command line (or in setup.py): +

        +
        $ swig -python -threads example.i
        +
      • +
      • +

        + The threads module option in the *.i template file: +

        +
        %feature("nothread") method;
        +
      • +
      +
    2. +
    3. You can disable thread support for a given method:

      +
      %module("threads"=1)
      + or +
      %nothread method;
      +
    4. +
    5. You can partially disable thread support for a given method:

      +
        +
      • To disable the C++/python thread protection:

        +
        %feature("nothreadblock") method;
        + or +
        %nothreadblock method;
        +
      • +
      • +

        To disable the python/C++ thread protection

        +
        %feature("nothreadallow") method;
        + or +
        %nothreadallow method;
        +
      • +
      +
    6. +
    + +

    36.13.2 Multithread Performance

    + + +

    + For the curious about performance, here are some numbers for the profiletest.i test, + which is used to check the speed of the wrapped code: +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Thread ModeExecution Time (sec)Comment
    Single Threaded9.6no "-threads" option given
    Fully Multithreaded15.5"-threads" option = 'allow' + 'block'
    No Thread block12.2only 'allow'
    No Thread Allow13.6only block'
    + +

    + Fully threaded code decreases the wrapping performance by + around 60%. If that is important to your application, you + can tune each method using the different 'nothread', + 'nothreadblock' or 'nothreadallow' features as + needed. Note that for some methods deactivating the + 'thread block' or 'thread allow' code is not an option, + so, be careful. +

    + diff --git a/Doc/Manual/R.html b/Doc/Manual/R.html index 40b96d6c9..08c2217af 100644 --- a/Doc/Manual/R.html +++ b/Doc/Manual/R.html @@ -129,7 +129,7 @@ These two files can be loaded in any order
  • If you do not set the output file name appropriately, you might see errors like
    -> fact(4)
    +> fact(4)
     Error in .Call("R_swig_fact", s_arg1, as.logical(.copy), PACKAGE = "example") :
       "R_swig_fact" not available for .Call() for package "example"
     
    diff --git a/Doc/Manual/SWIG.html b/Doc/Manual/SWIG.html index e5b441fbb..d677a223f 100644 --- a/Doc/Manual/SWIG.html +++ b/Doc/Manual/SWIG.html @@ -389,7 +389,7 @@ For example /* bar not wrapped unless foo has been defined and the declaration of bar within foo has already been parsed */ int foo::bar(int) { - ... whatever ... + ... whatever ... }
    @@ -1043,14 +1043,14 @@ expect :

     # Copy a file 
     def filecopy(source, target):
    -  f1 = fopen(source, "r")
    -  f2 = fopen(target, "w")
    -  buffer = malloc(8192)
    -  nbytes = fread(buffer, 8192, 1, f1)
    -  while (nbytes > 0):
    -    fwrite(buffer, 8192, 1, f2)
    -          nbytes = fread(buffer, 8192, 1, f1)
    -  free(buffer)
    +    f1 = fopen(source, "r")
    +    f2 = fopen(target, "w")
    +    buffer = malloc(8192)
    +    nbytes = fread(buffer, 8192, 1, f1)
    +    while (nbytes > 0):
    +        fwrite(buffer, 8192, 1, f2)
    +            nbytes = fread(buffer, 8192, 1, f1)
    +    free(buffer)
     

    @@ -1236,9 +1236,9 @@ creating a wrapper equivalent to the following:

     double wrap_dot_product(Vector *a, Vector *b) {
    -    Vector x = *a;
    -    Vector y = *b;
    -    return dot_product(x, y);
    +  Vector x = *a;
    +  Vector y = *b;
    +  return dot_product(x, y);
     }
     
    @@ -1266,12 +1266,12 @@ pointers. As a result, SWIG creates a wrapper like this:
     Vector *wrap_cross_product(Vector *v1, Vector *v2) {
    -        Vector x = *v1;
    -        Vector y = *v2;
    -        Vector *result;
    -        result = (Vector *) malloc(sizeof(Vector));
    -        *(result) = cross(x, y);
    -        return result;
    +  Vector x = *v1;
    +  Vector y = *v2;
    +  Vector *result;
    +  result = (Vector *) malloc(sizeof(Vector));
    +  *(result) = cross(x, y);
    +  return result;
     }
     
    @@ -1280,10 +1280,10 @@ or if SWIG was run with the -c++ option:

     Vector *wrap_cross(Vector *v1, Vector *v2) {
    -        Vector x = *v1;
    -        Vector y = *v2;
    -        Vector *result = new Vector(cross(x, y)); // Uses default copy constructor
    -        return result;
    +  Vector x = *v1;
    +  Vector y = *v2;
    +  Vector *result = new Vector(cross(x, y)); // Uses default copy constructor
    +  return result;
     }
     
    @@ -1736,6 +1736,16 @@ already defined in the target scripting language. However, if you are careful about namespaces and your use of modules, you can usually avoid these problems.

    +

    +When wrapping C code, simple use of identifiers/symbols with %rename usually suffices. +When wrapping C++ code, simple use of simple identifiers/symbols with %rename might be too +limiting when using C++ features such as function overloading, default arguments, namespaces, template specialization etc. +If you are using the %rename directive and C++, make sure you read the +SWIG and C++ chapter and in particular the section on +Renaming and ambiguity resolution +for method overloading and default arguments. +

    +

    Closely related to %rename is the %ignore directive. %ignore instructs SWIG to ignore declarations that match a given identifier. For example: @@ -2078,7 +2088,7 @@ except those consisting of capital letters only:

    Finally, variants of %rename and %ignore directives can be used to help wrap C++ overloaded functions and methods or C++ methods which use default arguments. This is described in the -Ambiguity resolution and renaming section in the C++ chapter. +Renaming and ambiguity resolution section in the C++ chapter.

    @@ -2368,10 +2378,10 @@ defined in the interface. For example:
     struct Vector *new_Vector() {
    -    return (Vector *) calloc(1, sizeof(struct Vector));
    +  return (Vector *) calloc(1, sizeof(struct Vector));
     }
     void delete_Vector(struct Vector *obj) {
    -    free(obj);
    +  free(obj);
     }
     
    @@ -2602,10 +2612,10 @@ like this:
     WORD Foo_w_get(Foo *f) {
    -    return f->w;
    +  return f->w;
     }
     void Foo_w_set(FOO *f, WORD value) {
    -    f->w = value;
    +  f->w = value;
     }
     
    @@ -2896,7 +2906,7 @@ instead of a method. To do this, you might write some code like this:
     // Add a new attribute to Vector
     %extend Vector {
    -    const double magnitude;
    +  const double magnitude;
     }
     // Now supply the implementation of the Vector_magnitude_get function
     %{
    @@ -3293,11 +3303,27 @@ Vector *new_Vector() {
       return (Vector *) malloc(sizeof(Vector));
     }
     %}
    -
     

    -The %inline directive inserts all of the code that follows +This is the same as writing: +

    + +
    +%{
    +/* Create a new vector */
    +Vector *new_Vector() {
    +  return (Vector *) malloc(sizeof(Vector));
    +}
    +%}
    +
    +/* Create a new vector */
    +Vector *new_Vector() {
    +  return (Vector *) malloc(sizeof(Vector));
    +}
    +
    +

    +In other words, the %inline directive inserts all of the code that follows verbatim into the header portion of an interface file. The code is then parsed by both the SWIG preprocessor and parser. Thus, the above example creates a new command new_Vector using only one @@ -3305,6 +3331,11 @@ declaration. Since the code inside an %inline %{ ... %} block is given to both the C compiler and SWIG, it is illegal to include any SWIG directives inside a %{ ... %} block.

    + +

    +Note: The usual SWIG C preprocessor rules apply to code in %apply blocks when SWIG parses this code. For example, as mentioned earlier, SWIG's C Preprocessor does not follow #include directives by default. +

    +

    5.6.4 Initialization blocks

    diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html index 3e7860b9b..18059b40d 100644 --- a/Doc/Manual/SWIGPlus.html +++ b/Doc/Manual/SWIGPlus.html @@ -31,7 +31,6 @@
  • Static members
  • Member data -
  • Default arguments
  • Protection
  • Enums and constants
  • Friends @@ -39,16 +38,27 @@
  • Pass and return by value
  • Inheritance
  • A brief discussion of multiple inheritance, pointers, and type checking -
  • Wrapping Overloaded Functions and Methods +
  • Default arguments +
  • Overloaded functions and methods -
  • Wrapping overloaded operators +
  • Overloaded operators
  • Class extension
  • Templates +
  • Namespaces
    • The nspace feature for namespaces @@ -346,8 +356,8 @@ public: class Spam { public: - Foo *value; - ... + Foo *value; + ... }; @@ -706,7 +716,7 @@ class Foo { protected: Foo(); // Not wrapped. public: - ... + ... }; @@ -726,7 +736,7 @@ public: class Grok : public Bar { public: - Grok(); // Not wrapped. No implementation of abstract spam(). + Grok(); // Not wrapped. No implementation of abstract spam(). }; @@ -777,9 +787,9 @@ the normal constructor function. For example, if you have this:
       class List {
       public:
      -    List();    
      -    List(const List &);      // Copy constructor
      -    ...
      +  List();    
      +  List(const List &);      // Copy constructor
      +  ...
       };
       
      @@ -803,7 +813,7 @@ through a special function like this:
       List *copy_List(List *f) {
      -    return new List(*f);
      +  return new List(*f);
       }
       
      @@ -832,7 +842,7 @@ However, copy constructor wrappers can be generated if using the copyctor @@ -851,9 +861,9 @@ could be wrapped, but they had to be renamed. For example:
       class Foo {
       public:
      -    Foo();
      +  Foo();
         %name(CopyFoo) Foo(const Foo &);
      -    ...
      +  ...
       };
       
      @@ -969,8 +979,8 @@ not primitive types, such as classes. For instance, if you had another class lik
       class Foo {
       public:
      -    List items;
      -    ...
      +  List items;
      +  ...
       
      @@ -982,10 +992,10 @@ For example:
       List *Foo_items_get(Foo *self) {
      -    return &self->items;
      +  return &self->items;
       }
       void Foo_items_set(Foo *self, List *value) {
      -    self->items = *value;
      +  self->items = *value;
       }
       
      @@ -1007,10 +1017,10 @@ It is the naturalvar feature and can be used to effectively change the way acces
       const List &Foo_items_get(Foo *self) {
      -    return self->items;
      +  return self->items;
       }
       void Foo_items_set(Foo *self, const List &value) {
      -    self->items = value;
      +  self->items = value;
       }
       
      @@ -1094,113 +1104,7 @@ a few problems related to structure wrapping and some of SWIG's customization features.

      -

      6.7 Default arguments

      - - -

      -SWIG will wrap all types of functions that have default arguments. For example member functions: -

      - -
      -
      -class Foo {
      -public:
      -    void bar(int x, int y = 3, int z = 4);
      -};
      -
      -
      - -

      -SWIG handles default arguments by generating an extra overloaded method for each defaulted argument. -SWIG is effectively handling methods with default arguments as if it was wrapping the equivalent overloaded methods. -Thus for the example above, it is as if we had instead given the following to SWIG: -

      - -
      -
      -class Foo {
      -public:
      -    void bar(int x, int y, int z);
      -    void bar(int x, int y);
      -    void bar(int x);
      -};
      -
      -
      - -

      -The wrappers produced are exactly the same as if the above code was instead fed into SWIG. -Details of this are covered later in the Wrapping Overloaded Functions and Methods section. -This approach allows SWIG to wrap all possible default arguments, but can be verbose. -For example if a method has ten default arguments, then eleven wrapper methods are generated. -

      - -

      -Please see the Features and default arguments -section for more information on using %feature with functions with default arguments. -The Ambiguity resolution and renaming section -also deals with using %rename and %ignore on methods with default arguments. -If you are writing your own typemaps for types used in methods with default arguments, you may also need to write a typecheck typemap. -See the Typemaps and overloading section for details or otherwise -use the compactdefaultargs feature flag as mentioned below. -

      - -

      -Compatibility note: Versions of SWIG prior to SWIG-1.3.23 wrapped default arguments slightly differently. -Instead a single wrapper method was generated and the default values were copied into the C++ wrappers -so that the method being wrapped was then called with all the arguments specified. -If the size of the wrappers are a concern then this approach to wrapping methods with default arguments -can be re-activated by using the compactdefaultargs -feature flag. -

      - -
      -
      -%feature("compactdefaultargs") Foo::bar;
      -class Foo {
      -public:
      -    void bar(int x, int y = 3, int z = 4);
      -};
      -
      -
      - - -

      -This is great for reducing the size of the wrappers, but the caveat is it does not work for the statically typed languages, -such as C# and Java, -which don't have optional arguments in the language, -Another restriction of this feature is that it cannot handle default arguments that are not public. -The following example illustrates this: -

      - -
      -
      -class Foo {
      -private:
      -  static const int spam;
      -public:
      -  void bar(int x, int y = spam);   // Won't work with %feature("compactdefaultargs") -
      -                                   // private default value
      -};
      -
      -
      - -

      -This produces uncompilable wrapper code because default values in C++ are -evaluated in the same scope as the member function whereas SWIG -evaluates them in the scope of a wrapper function (meaning that the -values have to be public). -

      - -

      -The compactdefaultargs feature is automatically turned on when wrapping C code with default arguments. -Some target languages will also automatically turn on this feature -if the keyword arguments feature (kwargs) is specified for either C or C++ functions, and the target language supports kwargs, -the compactdefaultargs feature is also automatically turned on. -Keyword arguments are a language feature of some scripting languages, for example Ruby and Python. -SWIG is unable to support kwargs when wrapping overloaded methods, so the default approach cannot be used. -

      - -

      6.8 Protection

      +

      6.7 Protection

      @@ -1220,7 +1124,7 @@ until you explicitly give a `public:' declaration (This is the same convention used by C++).

      -

      6.9 Enums and constants

      +

      6.8 Enums and constants

      @@ -1250,7 +1154,7 @@ Swig_STOUT = Swig::STOUT Members declared as const are wrapped as read-only members and do not create constants.

      -

      6.10 Friends

      +

      6.9 Friends

      @@ -1278,7 +1182,7 @@ equivalent to one generated for the following declaration

       class Foo {
       public:
      -    ...
      +  ...
       };
       
       void blah(Foo *f);    
      @@ -1311,7 +1215,7 @@ namespace bar {
       and a wrapper for the method 'blah' will not be generated.
       

      -

      6.11 References and pointers

      +

      6.10 References and pointers

      @@ -1411,7 +1315,7 @@ templates and the STL. This was first added in SWIG-1.3.12.

      -

      6.12 Pass and return by value

      +

      6.11 Pass and return by value

      @@ -1485,8 +1389,8 @@ class A; %feature("valuewrapper") B; struct B { - B(); - // .... + B(); + // .... };

      @@ -1515,7 +1419,7 @@ classes that don't define a default constructor. It is not used for C++ pointers or references.

      -

      6.13 Inheritance

      +

      6.12 Inheritance

      @@ -1701,7 +1605,7 @@ functions for virtual members that are already defined in a base class.

      -

      6.14 A brief discussion of multiple inheritance, pointers, and type checking

      +

      6.13 A brief discussion of multiple inheritance, pointers, and type checking

      @@ -1833,7 +1737,113 @@ int y = B_function((B *) pB); In practice, the pointer is held as an integral number in the target language proxy class.

      -

      6.15 Wrapping Overloaded Functions and Methods

      +

      6.14 Default arguments

      + + +

      +SWIG will wrap all types of functions that have default arguments. For example member functions: +

      + +
      +
      +class Foo {
      +public:
      +  void bar(int x, int y = 3, int z = 4);
      +};
      +
      +
      + +

      +SWIG handles default arguments by generating an extra overloaded method for each defaulted argument. +SWIG is effectively handling methods with default arguments as if it was wrapping the equivalent overloaded methods. +Thus for the example above, it is as if we had instead given the following to SWIG: +

      + +
      +
      +class Foo {
      +public:
      +  void bar(int x, int y, int z);
      +  void bar(int x, int y);
      +  void bar(int x);
      +};
      +
      +
      + +

      +The wrappers produced are exactly the same as if the above code was instead fed into SWIG. +Details of this are covered in the next section Overloaded functions and methods. +This approach allows SWIG to wrap all possible default arguments, but can be verbose. +For example if a method has ten default arguments, then eleven wrapper methods are generated. +

      + +

      +Please see the Features and default arguments +section for more information on using %feature with functions with default arguments. +The Renaming and ambiguity resolution section +also deals with using %rename and %ignore on methods with default arguments. +If you are writing your own typemaps for types used in methods with default arguments, you may also need to write a typecheck typemap. +See the Typemaps and overloading section for details or otherwise +use the compactdefaultargs feature flag as mentioned below. +

      + +

      +Compatibility note: Versions of SWIG prior to SWIG-1.3.23 wrapped default arguments slightly differently. +Instead a single wrapper method was generated and the default values were copied into the C++ wrappers +so that the method being wrapped was then called with all the arguments specified. +If the size of the wrappers are a concern then this approach to wrapping methods with default arguments +can be re-activated by using the compactdefaultargs +feature flag. +

      + +
      +
      +%feature("compactdefaultargs") Foo::bar;
      +class Foo {
      +public:
      +  void bar(int x, int y = 3, int z = 4);
      +};
      +
      +
      + + +

      +This is great for reducing the size of the wrappers, but the caveat is it does not work for the statically typed languages, +such as C# and Java, +which don't have optional arguments in the language, +Another restriction of this feature is that it cannot handle default arguments that are not public. +The following example illustrates this: +

      + +
      +
      +class Foo {
      +private:
      +  static const int spam;
      +public:
      +  void bar(int x, int y = spam);   // Won't work with %feature("compactdefaultargs") -
      +                                   // private default value
      +};
      +
      +
      + +

      +This produces uncompilable wrapper code because default values in C++ are +evaluated in the same scope as the member function whereas SWIG +evaluates them in the scope of a wrapper function (meaning that the +values have to be public). +

      + +

      +The compactdefaultargs feature is automatically turned on when wrapping C code with default arguments. +Some target languages will also automatically turn on this feature +if the keyword arguments feature (kwargs) is specified for either C or C++ functions, and the target language supports kwargs, +the compactdefaultargs feature is also automatically turned on. +Keyword arguments are a language feature of some scripting languages, for example Ruby and Python. +SWIG is unable to support kwargs when wrapping overloaded methods, so the default approach cannot be used. +

      + +

      6.15 Overloaded functions and methods

      @@ -2021,7 +2031,7 @@ checked in the same order as they appear in this ranking. If you're still confused, don't worry about it---SWIG is probably doing the right thing.

      -

      6.15.2 Ambiguity in Overloading

      +

      6.15.2 Ambiguity in overloading

      @@ -2139,7 +2149,7 @@ it means that the target language module has not yet implemented support for ove functions and methods. The only way to fix the problem is to read the next section.

      -

      6.15.3 Ambiguity resolution and renaming

      +

      6.15.3 Renaming and ambiguity resolution

      @@ -2399,8 +2409,8 @@ the first renaming rule found on a depth-first traversal of the class hierarchy is used.

    • -
    • The name matching rules strictly follow member qualification rules. -For example, if you have a class like this:

      +
    • The name matching rules strictly follow member qualifier rules. +For example, if you have a class and member with a member that is const qualified like this:

      @@ -2424,7 +2434,7 @@ the declaration
       

      -will not apply as there is no unqualified member bar(). The following will apply as +will not apply as there is no unqualified member bar(). The following will apply the rename as the qualifier matches correctly:

      @@ -2434,6 +2444,26 @@ the qualifier matches correctly: +

      +Similarly for combinations of cv-qualifiers and ref-qualifiers, all the qualifiers must be specified to match correctly: +

      + +
      +
      +%rename(name) Jam::bar();          // will not match
      +%rename(name) Jam::bar() &;        // will not match
      +%rename(name) Jam::bar() const;    // will not match
      +%rename(name) Jam::bar() const &;  // ok, will match
      +
      +class Jam {
      +public:
      +  ...
      +  void bar() const &;
      +  ...
      +};
      +
      +
      +

      An often overlooked C++ feature is that classes can define two different overloaded members that differ only in their qualifiers, like this: @@ -2466,7 +2496,7 @@ For example we can give them separate names in the target language:

      Similarly, if you merely wanted to ignore one of the declarations, use %ignore -with the full qualification. For example, the following directive +with the full qualifier. For example, the following directive would tell SWIG to ignore the const version of bar() above:

      @@ -2532,8 +2562,7 @@ exactly matches the wrapped method:

      The C++ method can then be called from the target language with the new name no matter how many arguments are specified, for example: newbar(2, 2.0), newbar(2) or newbar(). -However, if the %rename does not contain the default arguments, it will only apply to the single equivalent target language overloaded method. -So if instead we have: +However, if the %rename does not contain the default arguments:

      @@ -2542,9 +2571,24 @@ So if instead we have:
      +

      +then only one of the three equivalent overloaded methods will be renamed and wrapped as if SWIG parsed: +

      + +
      +
      +void Spam::newbar(int i, double d);
      +void Spam::bar(int i);
      +void Spam::bar();
      +
      +
      +

      The C++ method must then be called from the target language with the new name newbar(2, 2.0) when both arguments are supplied or with the original name as bar(2) (one argument) or bar() (no arguments). +

      + +

      In fact it is possible to use %rename on the equivalent overloaded methods, to rename all the equivalent overloaded methods:

      @@ -2586,7 +2630,7 @@ As a general rule, statically typed languages like Java are able to provide more than dynamically typed languages like Perl, Python, Ruby, and Tcl.

      -

      6.16 Wrapping overloaded operators

      +

      6.16 Overloaded operators

      @@ -2779,7 +2823,7 @@ into two methods such that additional logic can be packed into the operations; C this[type key] { get { ... } set { ... }}, Python uses __getitem__ and __setitem__, etc. In C++ if the return type of operator[] is a reference and the method is const, it is often indicative of the setter, -and and the getter is usually a const function return an object by value. +and the getter is usually a const function return an object by value. In the absence of any hard and fast rules and the fact that there may be multiple index operators, it is up to the user to choose the getter and setter to use by using %rename as shown earlier.

      @@ -2936,63 +2980,76 @@ as vector<int>. The wrapper for foo() will accept either variant.

      +

      6.18.1 The %template directive

      + +

      -Starting with SWIG-1.3.7, simple C++ template declarations can also be -wrapped. SWIG-1.3.12 greatly expands upon the earlier implementation. Before discussing this any further, there are a few things -you need to know about template wrapping. First, a bare C++ template +There are a couple of important points about template wrapping. +First, a bare C++ template does not define any sort of runnable object-code for which SWIG can normally create a wrapper. Therefore, in order to wrap a template, you need to give SWIG information about a particular template -instantiation (e.g., vector<int>, +instantiation (e.g., vector<int>, array<double>, etc.). Second, an instantiation name such as vector<int> is generally not a valid identifier name in most target languages. Thus, you will need to give the -template instantiation a more suitable name such as intvector -when creating a wrapper. +template instantiation a more suitable name such as intvector.

      -To illustrate, consider the following template definition: +To illustrate, consider the following class template definition:

       template<class T> class List {
       private:
      -    T *data;
      -    int nitems;
      -    int maxitems;
      +  T *data;
      +  int nitems;
      +  int maxitems;
       public:
      -    List(int max) {
      -      data = new T [max];
      -      nitems = 0;
      -      maxitems = max;
      -    }
      -    ~List() {
      -      delete [] data;
      -    };
      -    void append(T obj) {
      -      if (nitems < maxitems) {
      -        data[nitems++] = obj;
      -      }
      -    }
      -    int length() {
      -      return nitems;
      -    }
      -    T get(int n) {
      -      return data[n];
      +  List(int max) {
      +    data = new T [max];
      +    nitems = 0;
      +    maxitems = max;
      +  }
      +  ~List() {
      +    delete [] data;
      +  };
      +  void append(T obj) {
      +    if (nitems < maxitems) {
      +      data[nitems++] = obj;
           }
      +  }
      +  int length() {
      +    return nitems;
      +  }
      +  T get(int n) {
      +    return data[n];
      +  }
       };
       

      -By itself, this template declaration is useless--SWIG simply ignores it -because it doesn't know how to generate any code until unless a definition of +By itself, this class template is useless--SWIG simply ignores it +because it doesn't know how to generate any code unless a definition of T is provided. +The %template directive is required to instantiate the template for use in a target language. +The directive requires an identifier name for use in the target language plus the template for instantiation. +The example below instantiates List<int> for use as a class named intList:

      +
      +
      +%template(intList) List<int>;
      +
      +
      +

      -One way to create wrappers for a specific template instantiation is to simply -provide an expanded version of the class directly like this: +The instantiation expands the template code as a C++ compiler would do and then makes it available +under the given identifier name. +Essentially it is the same as wrapping the following concept code where +the class template definition has T expanded to int +(note that this is not entirely valid syntax):

      @@ -3000,42 +3057,20 @@ provide an expanded version of the class directly like this: %rename(intList) List<int>; // Rename to a suitable identifier class List<int> { private: - int *data; - int nitems; - int maxitems; + int *data; + int nitems; + int maxitems; public: - List(int max); - ~List(); - void append(int obj); - int length(); - int get(int n); + List(int max); + ~List(); + void append(int obj); + int length(); + int get(int n); };
      -

      -The %rename directive is needed to give the template class an appropriate identifier -name in the target language (most languages would not recognize C++ template syntax as a valid -class name). The rest of the code is the same as what would appear in a normal -class definition. -

      - -

      -Since manual expansion of templates gets old in a hurry, the %template directive can -be used to create instantiations of a template class. Semantically, %template is -simply a shortcut---it expands template code in exactly the same way as shown above. Here -are some examples: -

      - -
      -
      -/* Instantiate a few different versions of the template */
      -%template(intList) List<int>;
      -%template(doubleList) List<double>;
      -
      -
      -

      The argument to %template() is the name of the instantiation in the target language. The name you choose should not conflict with @@ -3053,7 +3088,81 @@ typedef List<int> intList; // OK

      -SWIG can also generate wrappers for function templates using a similar technique. +The %template directive +must always appear after the definition of the template to be expanded, so the following will work: +

      + +
      +
      +template<class T> class List { ... };
      +%template(intList) List<int>;
      +
      +
      + +

      +but if %template is used before the template definition, such as: +

      + +
      +
      +%template(intList) List<int>;
      +template<class T> class List { ... };
      +
      +
      + +

      +SWIG will generate an error: +

      + +
      +
      +example.i:3: Error: Template 'List' undefined.
      +
      +
      + +

      +Since the type system knows how to handle typedef, it is +generally not necessary to instantiate different versions of a template +for typenames that are equivalent. For instance, consider this code: +

      + +
      +
      +%template(intList) List<int>;
      +typedef int Integer;
      +...
      +void foo(List<Integer> *x);
      +
      +
      + +

      +In this case, List<Integer> is exactly the same type as +List<int>. Any use of List<Integer> is mapped back to the +instantiation of List<int> created earlier. Therefore, it is +not necessary to instantiate a new class for the type Integer (doing so is +redundant and will simply result in code bloat). +

      + +

      +The template provide to %template for instantiation must be the actual template and not a typedef to a template. +

      + +
      +
      +typedef List<int> ListOfInt;
      +
      +%template(intList) List<int>; // ok
      +%template(intList) ListOfInt; // illegal - Syntax error
      +
      +
      + + +

      6.18.2 Function templates

      + + +

      +SWIG can also generate wrappers for function templates using a similar technique +to that shown above for class templates. For example:

      @@ -3073,6 +3182,28 @@ In this case, maxint and maxdouble become unique names for spe instantiations of the function.

      +

      +SWIG even supports overloaded templated functions. As usual the %template directive +is used to wrap templated functions. For example: +

      + +
      +
      +template<class T> void foo(T x) { };
      +template<class T> void foo(T x, T y) { };
      +
      +%template(foo) foo<int>;
      +
      +
      + +

      +This will generate two overloaded wrapper methods, the first will take a single integer as an argument +and the second will take two integer arguments. +

      + +

      6.18.3 Default template arguments

      + +

      The number of arguments supplied to %template should match that in the original template definition. Template default arguments are supported. For example: @@ -3110,28 +3241,8 @@ instantiation only once in order to reduce the potential for code bloat.

      -

      -Since the type system knows how to handle typedef, it is -generally not necessary to instantiate different versions of a template -for typenames that are equivalent. For instance, consider this code: -

      +

      6.18.4 Template base classes

      -
      -
      -%template(intList) vector<int>;
      -typedef int Integer;
      -...
      -void foo(vector<Integer> *x);
      -
      -
      - -

      -In this case, vector<Integer> is exactly the same type as -vector<int>. Any use of Vector<Integer> is mapped back to the -instantiation of vector<int> created earlier. Therefore, it is -not necessary to instantiate a new class for the type Integer (doing so is -redundant and will simply result in code bloat). -

      When a template is instantiated using %template, information @@ -3158,13 +3269,13 @@ nothing is known about List<int>, you will get a warning message

      -example.h:42: Warning 401. Nothing known about class 'List<int >'. Ignored. 
      -example.h:42: Warning 401. Maybe you forgot to instantiate 'List<int >' using %template. 
      +example.h:42: Warning 401. Nothing known about class 'List< int >'. Ignored. 
      +example.h:42: Warning 401. Maybe you forgot to instantiate 'List< int >' using %template. 
       

      -If a template class inherits from another template class, you need to +If a class template inherits from another class template, you need to make sure that base classes are instantiated before derived classes. For example:

      @@ -3235,6 +3346,9 @@ TEMPLATE_WRAP(PairStringInt, std::pair<string, int>) Note the use of a vararg macro for the type T. If this wasn't used, the comma in the templated type in the last example would not be possible.

      +

      6.18.5 Template specialization

      + +

      The SWIG template mechanism does support specialization. For instance, if you define a class like this, @@ -3244,15 +3358,15 @@ a class like this,

       template<> class List<int> {
       private:
      -    int *data;
      -    int nitems;
      -    int maxitems;
      +  int *data;
      +  int nitems;
      +  int maxitems;
       public:
      -    List(int max);
      -    ~List();
      -    void append(int obj);
      -    int length();
      -    int get(int n);
      +  List(int max);
      +  ~List();
      +  void append(int obj);
      +  int length();
      +  int get(int n);
       };
       
      @@ -3275,15 +3389,15 @@ code defines a template that is applied when the template argument is a pointer.
       template<class T> class List<T*> {
       private:
      -    T *data;
      -    int nitems;
      -    int maxitems;
      +  T *data;
      +  int nitems;
      +  int maxitems;
       public:
      -    List(int max);
      -    ~List();
      -    void append(int obj);
      -    int length();
      -    T get(int n);
      +  List(int max);
      +  ~List();
      +  void append(T obj);
      +  int length();
      +  T get(int n);
       };
       
      @@ -3322,10 +3436,13 @@ SWIG implements template argument deduction so that the following partial specia +

      6.18.6 Member templates

      + +

      -Member function templates are supported. The underlying principle is the same +Member templates are supported. The underlying principle is the same as for normal templates--SWIG can't create a wrapper unless you provide -more information about types. For example, a class with a member template might +more information about types. For example, a class with a member function template might look like this:

      @@ -3399,11 +3516,6 @@ methods to the Foo class.

      -

      -Note: because of the way that templates are handled, the %template directive -must always appear after the definition of the template to be expanded. -

      -

      Now, if your target language supports overloading, you can even try

      @@ -3424,7 +3536,7 @@ depending on the argument type.

      When used with members, the %template directive may be placed in another -template class. Here is a slightly perverse example: +class template. Here is a slightly perverse example:

      @@ -3475,7 +3587,7 @@ template<class T1, class T2> struct pair {

      This declaration is perfectly acceptable to SWIG, but the constructor template will be ignored unless you explicitly expand it. To do that, you could expand a few versions of the constructor -in the template class itself. For example: +in the class template itself. For example:

      @@ -3536,6 +3648,110 @@ constructor, that will dispatch the proper call depending on the argument type.

      +

      6.18.7 Scoping and templates

      + + +

      +The %template directive for a class template is the equivalent to an explicit instantiation +of a C++ class template. The scope for a valid %template instantiation is the same +as the scope required for a valid explicit instantiation of a C++ template. +A definition of the template for the explicit instantiation must be in scope +where the instantiation is declared and must not be enclosed within a different namespace. +

      + +

      +For example, a few %template instantiations and C++ explicit instantiations are shown below: +

      + +
      +
      +namespace N {
      +  template<typename T> class C {};
      +}
      +
      +// valid
      +%template(cin) N::C<int>;
      +template class N::C<int>;
      +
      +// valid
      +namespace N {
      +  %template(cin) C<int>;
      +  template class C<int>;
      +}
      +
      +// valid
      +using namespace N;
      +%template(cin) C<int>;
      +template class C<int>;
      +
      +// valid
      +using N::C;
      +%template(cin) C<int>;
      +template class C<int>;
      +
      +// ill-formed
      +namespace unrelated {
      +  using N::C;
      +  %template(cin) C<int>;
      +  template class C<int>;
      +}
      +
      +// ill-formed
      +namespace unrelated {
      +  using namespace N;
      +  %template(cin) C<int>;
      +  template class C<int>;
      +}
      +
      +// ill-formed
      +namespace unrelated {
      +  namespace N {
      +    %template(cin) C<int>;
      +    template class C<int>;
      +  }
      +}
      +
      +// ill-formed
      +namespace unrelated {
      +  %template(cin) N::C<int>;
      +  template class N::C<int>;
      +}
      +
      +
      + +

      +When the scope is incorrect, such as for the ill-formed examples above, an error occurs: +

      + +
      +
      +cpp_template_scope.i:34: Error: 'C' resolves to 'N::C' and was incorrectly instantiated
      +in scope 'unrelated' instead of within scope 'N'.
      +
      +
      + +

      +A note for the C++ standard geeks out there; a valid instantiation is one which conforms to +the C++03 standard as C++11 made a change to disallow using declarations and using directives to find a template. +

      + +
      +
      +// valid C++03, ill-formed C++11
      +using N::C;
      +template class C<int>;
      +
      +
      + +

      +Compatibility Note: Versions prior to SWIG-4.0.0 did not error out with incorrectly scoped +%template declarations, but this led to numerous subtle template scope problems. +

      + + +

      6.18.8 More on templates

      + +

      If all of this isn't quite enough and you really want to make someone's head explode, SWIG directives such as @@ -3568,7 +3784,7 @@ instantiation.

      -It is also possible to separate these declarations from the template class. For example: +It is also possible to separate these declarations from the class template. For example:

      @@ -3587,11 +3803,11 @@ It is also possible to separate these declarations from the template class. For ... template<class T> class List { - ... - public: - List() { } - T get(int index); - ... + ... + public: + List() { } + T get(int index); + ... };
      @@ -3609,32 +3825,13 @@ additional methods to a specific instantiation. For example: %template(intList) List<int>; %extend List<int> { - void blah() { - printf("Hey, I'm an List<int>!\n"); - } + void blah() { + printf("Hey, I'm an List<int>!\n"); + } };
      -

      -SWIG even supports overloaded templated functions. As usual the %template directive -is used to wrap templated functions. For example: -

      - -
      -
      -template<class T> void foo(T x) { };
      -template<class T> void foo(T x, T y) { };
      -
      -%template(foo) foo<int>;
      -
      -
      - -

      -This will generate two overloaded wrapper methods, the first will take a single integer as an argument -and the second will take two integer arguments. -

      -

      It is even possible to extend a class via %extend with template methods, for example:

      @@ -3694,20 +3891,20 @@ For example:
       template <class T> class OuterTemplateClass {};
       
      -// The nested class OuterClass::InnerClass inherits from the template class
      +// The nested class OuterClass::InnerClass inherits from the class template
       // OuterTemplateClass<OuterClass::InnerStruct> and thus the template needs
       // to be expanded with %template before the OuterClass declaration.
       %template(OuterTemplateClass_OuterClass__InnerStruct)
      -    OuterTemplateClass<OuterClass::InnerStruct>
      +  OuterTemplateClass<OuterClass::InnerStruct>
       
       
       // Don't forget to use %feature("flatnested") for OuterClass::InnerStruct and
       // OuterClass::InnerClass if the target language doesn't support nested classes.
       class OuterClass {
      -    public:
      -        // Forward declarations:
      -        struct InnerStruct;
      -        class InnerClass;
      +  public:
      +    // Forward declarations:
      +    struct InnerStruct;
      +    class InnerClass;
       };
       
       struct OuterClass::InnerStruct {};
      @@ -3736,7 +3933,7 @@ introduced a new class name.  This name could then be used with other directives
       
       %template(vectori) vector<int>;
       %extend vectori {
      -    void somemethod() { }
      +  void somemethod() { }
       };
       
      @@ -3750,7 +3947,7 @@ as the class name. For example:
       %template(vectori) vector<int>;
       %extend vector<int> {
      -    void somemethod() { }
      +  void somemethod() { }
       };
       
      @@ -3915,6 +4112,8 @@ then SWIG simply creates three wrapper functions bar(), spam(), and blah() in the target language. SWIG does not prepend the names with a namespace prefix nor are the functions packaged in any kind of nested scope. +Note that the default handling of flattening all the namespace scopes in the target language +can be changed via the nspace feature.

      @@ -4009,7 +4208,7 @@ in a different namespace. For example:

       namespace foo {
      -    template<typename T> T max(T a, T b) { return a > b ? a : b; }
      +  template<typename T> T max(T a, T b) { return a > b ? a : b; }
       }
       
       using foo::max;
      @@ -4018,8 +4217,8 @@ using foo::max;
       %template(maxfloat) foo::max<float>;    // Okay (qualified name).
       
       namespace bar {
      -    using namespace foo;
      -    %template(maxdouble)  max<double>;    // Okay.
      +  using namespace foo;
      +  %template(maxdouble)  max<double>;    // Okay.
       }
       
      @@ -4040,7 +4239,7 @@ namespace foo { typedef int Integer; class bar { public: - ... + ... }; } @@ -4203,9 +4402,7 @@ namespace foo {

      Note: The flattening of namespaces is only intended to serve as a basic namespace implementation. -None of the target language modules are currently programmed -with any namespace awareness. In the future, language modules may or may not provide -more advanced namespace support. +More advanced handling of namespaces is discussed next.

      6.19.1 The nspace feature for namespaces

      @@ -4301,9 +4498,9 @@ In the example below, the generic template type is used to rename to bbb
      -%rename(bbb) Space::ABC::aaa(T t);                  // will match but with lower precedence than ccc
      +%rename(bbb) Space::ABC::aaa(T t);                     // will match but with lower precedence than ccc
       %rename(ccc) Space::ABC<Space::XYZ>::aaa(Space::XYZ t);// will match but with higher precedence
      -                                                             // than bbb
      +                                                       // than bbb
       
       namespace Space {
         class XYZ {};
      @@ -4381,9 +4578,9 @@ class Error { };
       
       class Foo {
       public:
      -    ...
      -    void blah() throw(Error);
      -    ...
      +  ...
      +  void blah() throw(Error);
      +  ...
       };
       
      @@ -4445,10 +4642,10 @@ struct Error4 : EBase { }; class Foo { public: - ... - void bar(); - void blah() throw(Error1, Error2, Error3, Error4); - ... + ... + void bar(); + void blah() throw(Error1, Error2, Error3, Error4); + ... }; @@ -4524,7 +4721,7 @@ for member pointers.

      In some C++ programs, objects are often encapsulated by smart-pointers or proxy classes. This is sometimes done to implement automatic memory management (reference counting) or -persistence. Typically a smart-pointer is defined by a template class where +persistence. Typically a smart-pointer is defined by a class template where the -> operator has been overloaded. This class is then wrapped around some other class. For example:

      @@ -4533,21 +4730,21 @@ around some other class. For example:
       // Smart-pointer class
       template<class T> class SmartPtr {
      -    T *pointee;
      +  T *pointee;
       public:
      -    SmartPtr(T *p) : pointee(p) { ... }
      -    T *operator->() {
      -        return pointee;
      -    }
      -    ...
      +  SmartPtr(T *p) : pointee(p) { ... }
      +  T *operator->() {
      +    return pointee;
      +  }
      +  ...
       };
       
       // Ordinary class
       class Foo_Impl {
       public:
      -    int x;
      -    virtual void bar();
      -    ...
      +  int x;
      +  virtual void bar();
      +  ...
       };
       
       // Smart-pointer wrapper
      @@ -4555,13 +4752,13 @@ typedef SmartPtr<Foo_Impl> Foo;
       
       // Create smart pointer Foo
       Foo make_Foo() {
      -    return SmartPtr<Foo_Impl>(new Foo_Impl());
      +  return SmartPtr<Foo_Impl>(new Foo_Impl());
       }
       
       // Do something with smart pointer Foo
       void do_something(Foo f) {
      -    printf("x = %d\n", f->x);
      -    f->bar();
      +  printf("x = %d\n", f->x);
      +  f->bar();
       }
       
       // Call the wrapped smart pointer proxy class in the target language 'Foo'
      @@ -4660,13 +4857,13 @@ example, if you have this code

       class Foo {
       public:
      -    int x;
      +  int x;
       };
       
       class Bar {
       public:
      -    int x;       
      -    Foo *operator->();
      +  int x;       
      +  Foo *operator->();
       };
       
      @@ -4915,19 +5112,19 @@ base classes. For example:
       class Foo {
       public:
      -      int  blah(int x);
      +  int  blah(int x);
       };
       
       class Bar {
       public:
      -      double blah(double x);
      +  double blah(double x);
       };
       
       class FooBar : public Foo, public Bar {
       public:
      -      using Foo::blah;  
      -      using Bar::blah;
      -      char *blah(const char *x);
      +  using Foo::blah;
      +  using Bar::blah;
      +  char *blah(const char *x);
       };
       
      @@ -4970,14 +5167,14 @@ you wrap this code in Python, the module works just like you would expect:
       class Foo {
       protected:
      -    int x;
      -    int blah(int x);
      +  int x;
      +  int blah(int x);
       };
       
       class Bar : public Foo {
       public:
      -    using Foo::x;       // Make x public
      -    using Foo::blah;    // Make blah public
      +  using Foo::x;       // Make x public
      +  using Foo::blah;    // Make blah public
       };
       
      @@ -5008,14 +5205,14 @@ correctly, you can always change the interface to the following: class FooBar : public Foo, public Bar { public: #ifndef SWIG - using Foo::blah; - using Bar::blah; + using Foo::blah; + using Bar::blah; #else - int blah(int x); // explicitly tell SWIG about other declarations - double blah(double x); + int blah(int x); // explicitly tell SWIG about other declarations + double blah(double x); #endif - char *blah(const char *x); + char *blah(const char *x); };
      diff --git a/Doc/Manual/Scilab.html b/Doc/Manual/Scilab.html index 90bd8bb9a..fafb0b5a3 100644 --- a/Doc/Manual/Scilab.html +++ b/Doc/Manual/Scilab.html @@ -121,15 +121,15 @@ In this example we bind from C a function and a global variable into Scilab. The double Foo = 3.0; int fact(int n) { - if (n < 0) { - return 0; - } - else if (n == 0) { - return 1; - } - else { - return n * fact(n-1); - } + if (n < 0) { + return 0; + } + else if (n == 0) { + return 1; + } + else { + return n * fact(n-1); + } } %} @@ -304,6 +304,11 @@ The following table lists the Scilab specific command line options in addition t Generate the gateway XML with the given <gateway_id> + +-targetversion +Generate for Scilab target (major) version + +

      @@ -331,13 +336,17 @@ There are a few exceptions, such as constants and enumerations, which can be wra

      -In Scilab 5.x, identifier names are composed of 24 characters maximum (this limitation should disappear from Scilab 6.0 onwards). -
      Thus long function or variable names may be truncated and this can cause ambiguities. +In Scilab 5.x, identifier names are composed of 24 characters maximum (this limitation disappears from Scilab 6.0 onwards). +
      By default, variable, member, and function names longer than 24 charaters are truncated, and a warning is produced for each truncation.

      -

      This happens especially when wrapping structs/classes, for which the wrapped function name is composed of the struct/class name and field names. +

      This can cause ambiguities, especially when wrapping structs/classes, for which the wrapped function name is composed of the struct/class name and field names. In these cases, the %rename directive can be used to choose a different Scilab name.

      +

      +Note: truncations can be disabled by specifying the target version 6 of Scilab in the targetversion argument (i.e. -targetversion 6). +

      +

      39.3.3 Functions

      @@ -887,8 +896,8 @@ Let's see it on an example of a struct with two members: %inline %{ typedef struct { - int x; - int arr[4]; + int x; + int arr[4]; } Foo; %} @@ -1124,21 +1133,21 @@ But we can use either use the get_perimeter() function of the parent cl

      -As explained in 6.15 SWIG provides support for overloaded functions and constructors. +As explained in Overloaded functions and methods SWIG provides support for overloaded functions and constructors.

      -

      As SWIG knows pointer types, the overloading works also with pointer types, here is is an example with a function magnify overloaded for the previous classes Shape and Circle: +

      As SWIG knows pointer types, the overloading works also with pointer types, here is an example with a function magnify overloaded for the previous classes Shape and Circle:

       %module example
       
       void magnify(Square *square, double factor) {
      -    square->size *= factor;
      +  square->size *= factor;
       };
       
       void magnify(Circle *circle, double factor) {
      -    square->radius *= factor;
      +  square->radius *= factor;
       };
       
      @@ -1611,11 +1620,11 @@ void printArray(int values[], int len) {

      -There are no specific typemaps for pointer-to-pointers, they are are mapped as pointers in Scilab. +There are no specific typemaps for pointer-to-pointers, they are mapped as pointers in Scilab.

      -Pointer-to-pointers are sometimes used to implement matrices in C. The following is a an example of this: +Pointer-to-pointers are sometimes used to implement matrices in C. The following is an example of this:

      @@ -2053,7 +2062,7 @@ In this mode, the following SWIG options may be used to setup the build: Let's give an example how to build a module example, composed of two sources, and using a library dependency:

        -
      • the sources are baa1.c and baa2.c (and are stored in in the current directory)
      • +
      • the sources are baa1.c and baa2.c (and are stored in the current directory)
      • the library is libfoo in /opt/foo (headers stored in /opt/foo/include, and shared library in /opt/foo/lib)
      diff --git a/Doc/Manual/Sections.html b/Doc/Manual/Sections.html index bdf590ac9..c17f9e84e 100644 --- a/Doc/Manual/Sections.html +++ b/Doc/Manual/Sections.html @@ -1,14 +1,14 @@ -SWIG-3.0 Documentation +SWIG-4.0 Documentation -

      SWIG-3.0 Documentation

      +

      SWIG-4.0 Documentation

      -Last update : SWIG-3.0.13 (in progress) +Last update : SWIG-4.0.0 (in progress)

      Sections

      diff --git a/Doc/Manual/Tcl.html b/Doc/Manual/Tcl.html index 38d4103e0..41cb78661 100644 --- a/Doc/Manual/Tcl.html +++ b/Doc/Manual/Tcl.html @@ -958,7 +958,7 @@ Foo *BarToFoo(Bar *b) { } Foo *IncrFoo(Foo *f, int i) { - return f+i; + return f+i; } %} @@ -1054,7 +1054,7 @@ example, consider this:
       struct Bar {
      -    int  x[16];
      +  int  x[16];
       };
       
      @@ -1456,9 +1456,9 @@ Similarly, if you have a class like this,
       class Foo {
       public:
      -    Foo();
      -    Foo(const Foo &);
      -    ...
      +  Foo();
      +  Foo(const Foo &);
      +  ...
       };
       
      @@ -1693,11 +1693,11 @@ For example: %rename(Bar_spam) Bar::spam; namespace Foo { - int spam(); + int spam(); } namespace Bar { - int spam(); + int spam(); } @@ -1886,19 +1886,19 @@ then SWIG transforms it into a set of low-level procedural wrappers. For example
       Foo *new_Foo() {
      -    return new Foo();
      +  return new Foo();
       }
       void delete_Foo(Foo *f) {
      -    delete f;
      +  delete f;
       }
       int Foo_x_get(Foo *f) {
      -    return f->x;
      +  return f->x;
       }
       void Foo_x_set(Foo *f, int value) {
      -    f->x = value;
      +  f->x = value;
       }
       int Foo_spam(Foo *f, int arg1) {
      -    return f->spam(arg1);
      +  return f->spam(arg1);
       }
       
      @@ -1945,8 +1945,8 @@ ownership of the result. For example:
       class Foo {
       public:
      -    Foo();
      -    Foo bar();
      +  Foo();
      +  Foo bar();
       };
       
      @@ -1975,9 +1975,9 @@ they came from. Therefore, the ownership is set to zero. For example:
       class Foo {
       public:
      -    ...
      -    Foo *spam();
      -    ...
      +  ...
      +  Foo *spam();
      +  ...
       };
       
      @@ -2011,8 +2011,8 @@ or global variable. For example, consider this interface: %module example struct Foo { - int value; - Foo *next; + int value; + Foo *next; }; Foo *head = 0; @@ -2465,9 +2465,9 @@ you might define a typemap like this: %module example %typemap(in) int { - if (Tcl_GetIntFromObj(interp, $input, &$1) == TCL_ERROR) - return TCL_ERROR; - printf("Received an integer : %d\n", $1); + if (Tcl_GetIntFromObj(interp, $input, &$1) == TCL_ERROR) + return TCL_ERROR; + printf("Received an integer : %d\n", $1); } %inline %{ extern int fact(int n); @@ -2585,7 +2585,7 @@ like this:
       %typemap(out) int {
      -    Tcl_SetObjResult(interp, Tcl_NewIntObj($1));
      +  Tcl_SetObjResult(interp, Tcl_NewIntObj($1));
       }
       
      @@ -3215,28 +3215,28 @@ helper functions to access arrays : %inline %{ double *new_double(int size) { - return (double *) malloc(size*sizeof(double)); + return (double *) malloc(size*sizeof(double)); } void delete_double(double *a) { - free(a); + free(a); } double get_double(double *a, int index) { - return a[index]; + return a[index]; } void set_double(double *a, int index, double val) { - a[index] = val; + a[index] = val; } int *new_int(int size) { - return (int *) malloc(size*sizeof(int)); + return (int *) malloc(size*sizeof(int)); } void delete_int(int *a) { - free(a); + free(a); } int get_int(int *a, int index) { - return a[index]; + return a[index]; } int set_int(int *a, int index, int val) { - a[index] = val; + a[index] = val; } %} diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html index a3a3e09cb..eeabdd89a 100644 --- a/Doc/Manual/Typemaps.html +++ b/Doc/Manual/Typemaps.html @@ -3904,9 +3904,9 @@ A fragment can use one or more additional fragments, for example:
      -%fragment("<limits.h>", "header") {
      -  %#include <limits.h>
      -}
      +%fragment("<limits.h>", "header") %{
      +  #include <limits.h>
      +%}
       
       
       %fragment("AsMyClass", "header", fragment="<limits.h>") {
      @@ -3989,8 +3989,91 @@ Finally, you can force the inclusion of a fragment at any point in the generated
       

      -which is very useful inside a template class, for example. +which, for example, is very useful inside a template class. +Another useful case is when using %extend inside a class +where the additional code in the %extend block depends on the contents of the fragment.

      + +
      +
      +%fragment("<limits.h>", "header") %{
      +  #include <limits.h>
      +%}
      +
      +struct X {
      +  ...
      +  %extend {
      +    %fragment("<limits.h>");
      +    bool check(short val) {
      +      if (val < SHRT_MIN /*defined in <limits.h>*/) {
      +        return true;
      +      } else {
      +        return false;
      +      }
      +    }
      +  }
      +};
      +
      +
      + + +

      +Forced inclusion of fragments can be used as a replacement for code insertion block, ensuring the +code block is only generated once. +Consider the contents of FileA.i below which first uses a code insertion block and then a forced fragment inclusion to generate code: +

      +
      +
      +// FileA.i
      +%{
      +  #include <stdio.h>
      +%}
      +%fragment("<limits.h>");
      +
      +
      + +

      +and another file including the above: +

      + +
      +
      +// FileB.i
      +%include "FileA.i"
      +
      +
      + +

      +The resulting code in the wrappers for FileB.i is: +

      + +
      +
      +  #include <stdio.h>
      +
      +  #include <limits.h>
      +
      +
      + +

      +A note of caution must be mentioned when using %fragment forced inclusion or code insertion blocks with %import. +If %import is used instead: +

      + +
      +
      +// FileC.i
      +%import "FileA.i"
      +
      +
      + +

      +then nothing is generated in the resulting code in the wrappers for FileC.i. +This is because %import is for collecting type information and does not result in any code +being generated, see File Imports. +

      + +

      diff --git a/Doc/Manual/Varargs.html b/Doc/Manual/Varargs.html index fb58ee39a..eba816382 100644 --- a/Doc/Manual/Varargs.html +++ b/Doc/Manual/Varargs.html @@ -423,8 +423,8 @@ Variable length arguments may be used in typemap specifications. For example:

       %typemap(in) (...) {
      -    // Get variable length arguments (somehow)
      -    ...
      +  // Get variable length arguments (somehow)
      +  ...
       }
       
       %typemap(in) (const char *fmt, ...) {
      diff --git a/Doc/Manual/index.html b/Doc/Manual/index.html
      index 26cc81ea1..e720e70d0 100644
      --- a/Doc/Manual/index.html
      +++ b/Doc/Manual/index.html
      @@ -1,11 +1,11 @@
       
       
       
      -SWIG-3.0 Documentation
      +SWIG-4.0 Documentation
       
       
       
      -

      SWIG-3.0 Documentation

      +

      SWIG-4.0 Documentation

      The SWIG documentation is available in one of the following formats.
        diff --git a/Examples/Makefile.in b/Examples/Makefile.in index c56bd9629..bdef605af 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -282,7 +282,7 @@ perl5_static_cpp: $(SRCDIR_SRCS) # ----------------------------------------------------------------- perl5_run: - $(RUNTOOL) $(PERL) $(PERL5_SCRIPT) $(RUNPIPE) + $(RUNTOOL) $(PERL) -I. $(PERL5_SCRIPT) $(RUNPIPE) # ----------------------------------------------------------------- # Version display @@ -897,10 +897,10 @@ mzscheme_clean: ##### Ocaml ##### ################################################################## -OCC=@OCAMLC@ -OCAMLDLGEN=@OCAMLDLGEN@ -OCAMLFIND=@OCAMLFIND@ -OCAMLMKTOP=@OCAMLMKTOP@ $(SWIGWHERE) +OCC=$(COMPILETOOL) @OCAMLC@ +OCAMLDLGEN=$(COMPILETOOL) @OCAMLDLGEN@ +OCAMLFIND=$(COMPILETOOL) @OCAMLFIND@ +OCAMLMKTOP=$(COMPILETOOL) @OCAMLMKTOP@ $(SWIGWHERE) NOLINK ?= false OCAMLPP= -pp "camlp4o ./swigp4.cmo" OCAMLP4WHERE=`$(COMPILETOOL) @CAMLP4@ -where` @@ -911,8 +911,7 @@ OCAMLCORE=\ $(SWIG) -ocaml -co swigp4.ml 2>/dev/null && \ $(OCC) -c swig.mli && \ $(OCC) -c swig.ml && \ - $(OCC) -I $(OCAMLP4WHERE) -pp "camlp4o pa_extend.cmo q_MLast.cmo" \ - -c swigp4.ml + $(OCC) -I $(OCAMLP4WHERE) -pp "camlp4o pa_extend.cmo q_MLast.cmo" -c swigp4.ml ocaml_static: $(SRCDIR_SRCS) $(OCAMLCORE) @@ -920,32 +919,20 @@ ocaml_static: $(SRCDIR_SRCS) $(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS) $(OCC) -g -c $(INTERFACE:%.i=%.mli) $(OCC) -g -c $(INTERFACE:%.i=%.ml) - test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \ - $(OCC) $(OCAMLPP) -c $(PROGFILE) - $(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) \ - swig.cmo \ - $(INTERFACE:%.i=%.cmo) \ - $(PROGFILE:%.ml=%.cmo) \ - $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)" + test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE) + $(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) swig.cmo $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)" ocaml_dynamic: $(SRCDIR_SRCS) $(OCAMLCORE) $(SWIG) -ocaml $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH) $(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS) - $(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(CCSHARED) -o $(INTERFACE:%.i=%@SO@) \ - $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) $(LIBS) - $(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > \ - $(INTERFACE:%.i=%_dynamic.ml) + $(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(CCSHARED) -o $(INTERFACE:%.i=%@SO@) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) $(LIBS) + $(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > $(INTERFACE:%.i=%_dynamic.ml) mv $(INTERFACE:%.i=%_dynamic.ml) $(INTERFACE:%.i=%.ml) rm $(INTERFACE:%.i=%.mli) $(OCAMLFIND) $(OCC) -g -c -package dl $(INTERFACE:%.i=%.ml) - test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \ - $(OCC) $(OCAMLPP) -c $(PROGFILE) - $(NOLINK) || $(OCAMLFIND) \ - $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) \ - swig.cmo \ - -package dl -linkpkg \ - $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) + test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE) + $(NOLINK) || $(OCAMLFIND) $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) swig.cmo -package dl -linkpkg $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) ocaml_static_toplevel: $(SRCDIR_SRCS) $(OCAMLCORE) @@ -953,72 +940,41 @@ ocaml_static_toplevel: $(SRCDIR_SRCS) $(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS) $(OCC) -g -c $(INTERFACE:%.i=%.mli) $(OCC) -g -c $(INTERFACE:%.i=%.ml) - test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \ - $(OCC) $(OCAMLPP) -c $(PROGFILE) - $(NOLINK) || $(OCAMLMKTOP) \ - swig.cmo \ - -I $(OCAMLP4WHERE) camlp4o.cma swigp4.cmo \ - -g -ccopt -g -cclib -g -custom -o $(TARGET)_top \ - $(INTERFACE:%.i=%.cmo) \ - $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)" + test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE) + $(NOLINK) || $(OCAMLMKTOP) swig.cmo -I $(OCAMLP4WHERE) camlp4o.cma swigp4.cmo -g -ccopt -g -cclib -g -custom -o $(TARGET)_top $(INTERFACE:%.i=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)" ocaml_static_cpp: $(SRCDIR_SRCS) $(OCAMLCORE) $(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH) cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c) - $(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" \ - $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) + $(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(OCC) -g -c $(INTERFACE:%.i=%.mli) $(OCC) -g -c $(INTERFACE:%.i=%.ml) - test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \ - $(OCC) $(OCAMLPP) -c $(PROGFILE) - $(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) \ - swig.cmo \ - $(INTERFACE:%.i=%.cmo) \ - $(PROGFILE:%.ml=%.cmo) \ - $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) \ - -cclib "$(LIBS)" -cc '$(CXX) -Wno-write-strings' + test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE) + $(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) swig.cmo $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)" -cc '$(CXX) -Wno-write-strings' ocaml_static_cpp_toplevel: $(SRCDIR_SRCS) $(OCAMLCORE) $(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH) cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c) - $(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" \ - $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) + $(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(OCC) -g -c $(INTERFACE:%.i=%.mli) $(OCC) -g -c $(INTERFACE:%.i=%.ml) - test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \ - $(OCC) $(OCAMLPP) -c $(PROGFILE) - $(NOLINK) || $(OCAMLMKTOP) \ - swig.cmo \ - -I $(OCAMLP4WHERE) dynlink.cma camlp4o.cma swigp4.cmo \ - -g -ccopt -g -cclib -g -custom -o $(TARGET)_top \ - $(INTERFACE:%.i=%.cmo) \ - $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) \ - -cclib "$(LIBS)" -cc '$(CXX) -Wno-write-strings' + test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE) + $(NOLINK) || $(OCAMLMKTOP) swig.cmo -I $(OCAMLP4WHERE) dynlink.cma camlp4o.cma swigp4.cmo -g -ccopt -g -cclib -g -custom -o $(TARGET)_top $(INTERFACE:%.i=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)" -cc '$(CXX) -Wno-write-strings' ocaml_dynamic_cpp: $(SRCDIR_SRCS) $(OCAMLCORE) $(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH) cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c) - $(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" \ - $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) -ccopt -fPIC - $(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $(INTERFACE:%.i=%@SO@) \ - $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) \ - $(CPP_DLLIBS) $(LIBS) - $(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > \ - $(INTERFACE:%.i=%_dynamic.ml) + $(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) -ccopt -fPIC + $(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $(INTERFACE:%.i=%@SO@) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) $(CPP_DLLIBS) $(LIBS) + $(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > $(INTERFACE:%.i=%_dynamic.ml) mv $(INTERFACE:%.i=%_dynamic.ml) $(INTERFACE:%.i=%.ml) rm $(INTERFACE:%.i=%.mli) $(OCAMLFIND) $(OCC) -g -c -package dl $(INTERFACE:%.i=%.ml) - test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \ - $(OCC) $(OCAMLPP) -c $(PROGFILE) - $(NOLINK) || $(OCAMLFIND) \ - swig.cmo \ - $(OCC) -cclib -export-dynamic -g -ccopt -g -cclib -g -custom \ - -o $(TARGET) \ - -package dl -linkpkg \ - $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) -cc '$(CXX) -Wno-write-strings' + test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE) + $(NOLINK) || $(OCAMLFIND) swig.cmo $(OCC) -cclib -export-dynamic -g -ccopt -g -cclib -g -custom -o $(TARGET) -package dl -linkpkg $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) -cc '$(CXX) -Wno-write-strings' # ----------------------------------------------------------------- # Run ocaml example @@ -1738,7 +1694,7 @@ r: $(SRCDIR_SRCS) ifneq ($(SRCDIR_SRCS),) $(CC) -g -c $(CPPFLAGS) $(CFLAGS) $(R_CFLAGS) $(SRCDIR_SRCS) $(INCLUDES) endif - +( PKG_CPPFLAGS="$(CPPFLAGS) $(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) $(OBJS) > /dev/null ) + +( PKG_CPPFLAGS="$(CPPFLAGS) $(INCLUDES)" PKG_CFLAGS="$(CFLAGS)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) $(OBJS) > /dev/null ) # ---------------------------------------------------------------- # Build a R dynamically loadable module (C++) @@ -1748,7 +1704,7 @@ r_cpp: $(SRCDIR_CXXSRCS) ifneq ($(SRCDIR_CXXSRCS),) $(CXX) -g -c $(CPPFLAGS) $(CXXFLAGS) $(R_CFLAGS) $(SRCDIR_CXXSRCS) $(INCLUDES) endif - +( PKG_CPPFLAGS="$(CPPFLAGS) $(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(RCXXSRCS) $(OBJS) > /dev/null ) + +( PKG_CPPFLAGS="$(CPPFLAGS) $(INCLUDES)" PKG_CXXFLAGS="$(CXXFLAGS)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(RCXXSRCS) $(OBJS) > /dev/null ) # ----------------------------------------------------------------- # Run R example diff --git a/Examples/go/callback/gocallback.go b/Examples/go/callback/gocallback.go index 20fd0627a..881f505e0 100644 --- a/Examples/go/callback/gocallback.go +++ b/Examples/go/callback/gocallback.go @@ -36,6 +36,6 @@ func DeleteGoCallback(p GoCallback) { p.deleteCallback() } -func (p *goCallback) Run() { +func (p *overwrittenMethodsOnCallback) Run() { fmt.Println("GoCallback.Run") } diff --git a/Examples/javascript/enum/runme.js b/Examples/javascript/enum/runme.js index 851d43c4b..f3264889c 100644 --- a/Examples/javascript/enum/runme.js +++ b/Examples/javascript/enum/runme.js @@ -30,5 +30,5 @@ f.enum_test(example.Foo.LUDICROUS); // enum value BLUE of enum color is accessed as property of cconst console.log("example.BLUE= " + example.BLUE); -// enum value LUDICROUS of enum Foo::speed is accessed as as property of cconst +// enum value LUDICROUS of enum Foo::speed is accessed as property of cconst console.log("example.speed.LUDICROUS= " + example.Foo.LUDICROUS); diff --git a/Examples/javascript/exception/example.h b/Examples/javascript/exception/example.h index 7cf917d01..1658ec770 100644 --- a/Examples/javascript/exception/example.h +++ b/Examples/javascript/exception/example.h @@ -19,6 +19,10 @@ public: #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif class Test { public: @@ -50,4 +54,7 @@ public: #if defined(_MSC_VER) #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif diff --git a/Examples/lua/exception/example.h b/Examples/lua/exception/example.h index 251ef1132..ea3b4fc63 100644 --- a/Examples/lua/exception/example.h +++ b/Examples/lua/exception/example.h @@ -19,10 +19,14 @@ public: #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif class Test { public: - int simple() throw(int&) { + int simple() throw(int) { throw(37); return 1; } @@ -50,4 +54,7 @@ public: #if defined(_MSC_VER) #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif diff --git a/Examples/octave/extend/runme.m b/Examples/octave/extend/runme.m index bc73184a8..c88a7c151 100644 --- a/Examples/octave/extend/runme.m +++ b/Examples/octave/extend/runme.m @@ -14,7 +14,7 @@ CEO=@(name) subclass(swigexample.Manager(name),'getPosition',@(self) "CEO"); # Create an instance of our employee extension class, CEO. The calls to # getName() and getPosition() are standard, the call to getTitle() uses -# the director wrappers to call CEO.getPosition. e = CEO("Alice") +# the director wrappers to call CEO.getPosition. e = CEO("Alice"); printf("%s is a %s\n",e.getName(),e.getPosition()); diff --git a/Examples/php/enum/Makefile b/Examples/php/enum/Makefile index 4483f781e..063a0645f 100644 --- a/Examples/php/enum/Makefile +++ b/Examples/php/enum/Makefile @@ -5,7 +5,7 @@ CXXSRCS = example.cxx TARGET = example INTERFACE = example.i LIBS = -SWIGOPT = -noproxy +SWIGOPT = check: build $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run diff --git a/Examples/php/enum/runme.php b/Examples/php/enum/runme.php index 55b0bc4c3..813476645 100644 --- a/Examples/php/enum/runme.php +++ b/Examples/php/enum/runme.php @@ -11,22 +11,22 @@ print " BLUE =" . BLUE; print " GREEN =" . GREEN; print "\n*** Foo::speed ***"; -print " Foo_IMPULSE =" . Foo_IMPULSE; -print " Foo_WARP =" . Foo_WARP; -print " Foo_LUDICROUS =" . Foo_LUDICROUS; +print " Foo::IMPULSE =" . Foo::IMPULSE; +print " Foo::WARP =" . Foo::WARP; +print " Foo::LUDICROUS =" . Foo::LUDICROUS; print "\nTesting use of enums with functions\n"; -enum_test(RED, Foo_IMPULSE); -enum_test(BLUE, Foo_WARP); -enum_test(GREEN, Foo_LUDICROUS); +enum_test(RED, Foo::IMPULSE); +enum_test(BLUE, Foo::WARP); +enum_test(GREEN, Foo::LUDICROUS); enum_test(1234,5678); print "\nTesting use of enum with class method\n"; -$f = new_Foo(); +$f = new Foo(); -Foo_enum_test($f,Foo_IMPULSE); -Foo_enum_test($f,Foo_WARP); -Foo_enum_test($f,Foo_LUDICROUS); +$f->enum_test(Foo::IMPULSE); +$f->enum_test(Foo::WARP); +$f->enum_test(Foo::LUDICROUS); ?> diff --git a/Examples/php/pragmas/example.i b/Examples/php/pragmas/example.i index c7e8bf303..f9307a663 100644 --- a/Examples/php/pragmas/example.i +++ b/Examples/php/pragmas/example.i @@ -27,5 +27,6 @@ # This code is inserted into example.php echo \"this was php code\\n\"; " +%pragma(php) version="1.5" %pragma(php) phpinfo="php_info_print_table_start();" diff --git a/Examples/php/pragmas/runme.php b/Examples/php/pragmas/runme.php index 538548b6f..b99cf37a4 100644 --- a/Examples/php/pragmas/runme.php +++ b/Examples/php/pragmas/runme.php @@ -2,4 +2,5 @@ require "example.php"; +echo "Version - " . ((new ReflectionExtension('example'))->getVersion()); ?> diff --git a/Examples/php/value/Makefile b/Examples/php/value/Makefile index 28fc3a127..47e5ed9f9 100644 --- a/Examples/php/value/Makefile +++ b/Examples/php/value/Makefile @@ -5,7 +5,7 @@ SRCS = example.c TARGET = example INTERFACE = example.i LIBS = -SWIGOPT = -noproxy +SWIGOPT = check: build $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_run diff --git a/Examples/php/value/runme.php b/Examples/php/value/runme.php index 49115376c..569c87cf5 100644 --- a/Examples/php/value/runme.php +++ b/Examples/php/value/runme.php @@ -3,15 +3,15 @@ require "example.php"; - $v = new_vector(); - vector_x_set($v,1.0); - vector_y_set($v,2.0); - vector_z_set($v,3.0); + $v = new Vector(); + $v->x = 1.0; + $v->y = 2.0; + $v->z = 3.0; - $w = new_vector(); - vector_x_set($w,10.0); - vector_y_set($w,11.0); - vector_z_set($w,12.0); + $w = new Vector(); + $w->x = 10.0; + $w->y = 11.0; + $w->z = 12.0; echo "I just created the following vector\n"; vector_print($v); @@ -25,7 +25,7 @@ echo "\nNow I'm going to add the vectors together\n"; - $r = new_vector(); + $r = new Vector(); vector_add($v, $w, $r); vector_print($r); diff --git a/Examples/php/variables/runme.php b/Examples/php/variables/runme.php index bbfeb610b..14f27f389 100644 --- a/Examples/php/variables/runme.php +++ b/Examples/php/variables/runme.php @@ -26,10 +26,10 @@ echo "pt = ".pt_get(), point_print(pt_get()) , "\n"; /* Try to set the values of some global variables */ -$a = "42.14"; + $a = "42.14"; ivar_set($a); -echo "a = $a\n"; + echo "a = $a\n"; svar_set(-31000); lvar_set(65537); uivar_set(123456); diff --git a/Examples/php5/pragmas/example.i b/Examples/php5/pragmas/example.i index c7e8bf303..f9307a663 100644 --- a/Examples/php5/pragmas/example.i +++ b/Examples/php5/pragmas/example.i @@ -27,5 +27,6 @@ # This code is inserted into example.php echo \"this was php code\\n\"; " +%pragma(php) version="1.5" %pragma(php) phpinfo="php_info_print_table_start();" diff --git a/Examples/php5/pragmas/runme.php b/Examples/php5/pragmas/runme.php index 538548b6f..b99cf37a4 100644 --- a/Examples/php5/pragmas/runme.php +++ b/Examples/php5/pragmas/runme.php @@ -2,4 +2,5 @@ require "example.php"; +echo "Version - " . ((new ReflectionExtension('example'))->getVersion()); ?> diff --git a/Examples/php5/variables/runme.php b/Examples/php5/variables/runme.php index bbfeb610b..14f27f389 100644 --- a/Examples/php5/variables/runme.php +++ b/Examples/php5/variables/runme.php @@ -26,10 +26,10 @@ echo "pt = ".pt_get(), point_print(pt_get()) , "\n"; /* Try to set the values of some global variables */ -$a = "42.14"; + $a = "42.14"; ivar_set($a); -echo "a = $a\n"; + echo "a = $a\n"; svar_set(-31000); lvar_set(65537); uivar_set(123456); diff --git a/Examples/python/exception/example.h b/Examples/python/exception/example.h index 8f9a977b0..ea3b4fc63 100644 --- a/Examples/python/exception/example.h +++ b/Examples/python/exception/example.h @@ -19,6 +19,10 @@ public: #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif class Test { public: @@ -50,4 +54,7 @@ public: #if defined(_MSC_VER) #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif diff --git a/Examples/python/exceptproxy/example.h b/Examples/python/exceptproxy/example.h index ec7107a5e..0c03873fc 100644 --- a/Examples/python/exceptproxy/example.h +++ b/Examples/python/exceptproxy/example.h @@ -11,6 +11,10 @@ class FullError { #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif template class Queue { int maxsize; @@ -51,4 +55,7 @@ template class Queue { #if defined(_MSC_VER) #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif diff --git a/Examples/python/extend/runme.py b/Examples/python/extend/runme.py index 2bb38fadc..e97358b99 100644 --- a/Examples/python/extend/runme.py +++ b/Examples/python/extend/runme.py @@ -18,7 +18,7 @@ class CEO(example.Manager): # Create an instance of our employee extension class, CEO. The calls to # getName() and getPosition() are standard, the call to getTitle() uses -# the director wrappers to call CEO.getPosition. e = CEO("Alice") +# the director wrappers to call CEO.getPosition. e = CEO("Alice") print e.getName(), "is a", e.getPosition() diff --git a/Examples/python/import_packages/namespace_pkg/nonpkg.py b/Examples/python/import_packages/namespace_pkg/nonpkg.py index acf0aedbd..dc910b846 100644 --- a/Examples/python/import_packages/namespace_pkg/nonpkg.py +++ b/Examples/python/import_packages/namespace_pkg/nonpkg.py @@ -2,4 +2,5 @@ import robin -assert(robin.run() == "AWAY!") +if not(robin.run() == "AWAY!"): + raise RuntimeError("test failed") diff --git a/Examples/python/import_packages/namespace_pkg/normal.py b/Examples/python/import_packages/namespace_pkg/normal.py index fc26c0216..231d4cccd 100644 --- a/Examples/python/import_packages/namespace_pkg/normal.py +++ b/Examples/python/import_packages/namespace_pkg/normal.py @@ -4,4 +4,5 @@ sys.path.insert(0, 'path1') from brave import robin -assert(robin.run() == "AWAY!") +if not(robin.run() == "AWAY!"): + raise RuntimeError("test failed") diff --git a/Examples/python/import_packages/namespace_pkg/split.py b/Examples/python/import_packages/namespace_pkg/split.py index 1b66c2d49..88d17d5fe 100644 --- a/Examples/python/import_packages/namespace_pkg/split.py +++ b/Examples/python/import_packages/namespace_pkg/split.py @@ -6,4 +6,5 @@ sys.path.insert(0, 'path3') from brave import robin -assert(robin.run() == "AWAY!") +if not(robin.run() == "AWAY!"): + raise RuntimeError("test failed") diff --git a/Examples/python/import_packages/namespace_pkg/zipsplit.py b/Examples/python/import_packages/namespace_pkg/zipsplit.py index 9e35559e3..b027b11c1 100644 --- a/Examples/python/import_packages/namespace_pkg/zipsplit.py +++ b/Examples/python/import_packages/namespace_pkg/zipsplit.py @@ -6,4 +6,5 @@ sys.path.insert(0, 'path3') from brave import robin -assert(robin.run() == "AWAY!") +if not(robin.run() == "AWAY!"): + raise RuntimeError("test failed") diff --git a/Examples/python/import_packages/split_modules/vanilla/runme.py b/Examples/python/import_packages/split_modules/vanilla/runme.py index a188364f1..4c46ef200 100644 --- a/Examples/python/import_packages/split_modules/vanilla/runme.py +++ b/Examples/python/import_packages/split_modules/vanilla/runme.py @@ -7,4 +7,5 @@ import pkg1.foo print " Finished importing pkg1.foo" -assert(pkg1.foo.count() == 3) +if not(pkg1.foo.count() == 3): + raise RuntimeError("test failed") diff --git a/Examples/python/import_packages/split_modules/vanilla_split/runme.py b/Examples/python/import_packages/split_modules/vanilla_split/runme.py index a188364f1..4c46ef200 100644 --- a/Examples/python/import_packages/split_modules/vanilla_split/runme.py +++ b/Examples/python/import_packages/split_modules/vanilla_split/runme.py @@ -7,4 +7,5 @@ import pkg1.foo print " Finished importing pkg1.foo" -assert(pkg1.foo.count() == 3) +if not(pkg1.foo.count() == 3): + raise RuntimeError("test failed") diff --git a/Examples/ruby/exception_class/Makefile b/Examples/ruby/exceptproxy/Makefile similarity index 100% rename from Examples/ruby/exception_class/Makefile rename to Examples/ruby/exceptproxy/Makefile diff --git a/Examples/ruby/exception_class/example.h b/Examples/ruby/exceptproxy/example.h similarity index 59% rename from Examples/ruby/exception_class/example.h rename to Examples/ruby/exceptproxy/example.h index 9facde4bd..c29a562db 100644 --- a/Examples/ruby/exception_class/example.h +++ b/Examples/ruby/exceptproxy/example.h @@ -8,6 +8,14 @@ class FullError { FullError(int m) : maxsize(m) { } }; +#if defined(_MSC_VER) + #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif + template class Queue { int maxsize; T *items; @@ -44,6 +52,12 @@ template class Queue { }; +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif diff --git a/Examples/ruby/exception_class/example.i b/Examples/ruby/exceptproxy/example.i similarity index 100% rename from Examples/ruby/exception_class/example.i rename to Examples/ruby/exceptproxy/example.i diff --git a/Examples/ruby/exception_class/runme.rb b/Examples/ruby/exceptproxy/runme.rb similarity index 100% rename from Examples/ruby/exception_class/runme.rb rename to Examples/ruby/exceptproxy/runme.rb diff --git a/Examples/test-suite/README b/Examples/test-suite/README index aac7636c6..3b7cea477 100644 --- a/Examples/test-suite/README +++ b/Examples/test-suite/README @@ -47,6 +47,6 @@ testdir/README file. Further Documentation --------------------- -There is documentation about the test-suite and how to use use it in +There is documentation about the test-suite and how to use it in the SWIG documentation - Doc/Manual/Extending.html#Extending_test_suite. diff --git a/Examples/test-suite/autodoc.i b/Examples/test-suite/autodoc.i index a2d9f5b4e..97c05d791 100644 --- a/Examples/test-suite/autodoc.i +++ b/Examples/test-suite/autodoc.i @@ -133,6 +133,14 @@ typedef int Integer; void banana(S *a, const struct tagS *b, int c, Integer d) {} %} +// Check docs for a template type +%inline %{ +template struct T { + T inout(T t) { return t; } +}; +%} +%template(TInteger) T; + %inline %{ #ifdef SWIGPYTHON_BUILTIN bool is_python_builtin() { return true; } @@ -140,4 +148,3 @@ bool is_python_builtin() { return true; } bool is_python_builtin() { return false; } #endif %} - diff --git a/Examples/test-suite/catches.i b/Examples/test-suite/catches.i index 8f09ae24c..8456cc00b 100644 --- a/Examples/test-suite/catches.i +++ b/Examples/test-suite/catches.i @@ -4,6 +4,10 @@ #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif %} %include // for throws(...) typemap @@ -31,3 +35,11 @@ void test_catches_all(int i) { } %} +%{ +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +%} diff --git a/Examples/test-suite/class_scope_namespace.i b/Examples/test-suite/class_scope_namespace.i new file mode 100644 index 000000000..730c076aa --- /dev/null +++ b/Examples/test-suite/class_scope_namespace.i @@ -0,0 +1,160 @@ +// Test a mix of forward class declarations, class definitions, using declarations and using directives. + +%module class_scope_namespace + +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) H::HH; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Space8::I::II; + +%inline %{ +struct A; +namespace Space1 { + namespace SubSpace1 { + struct A { + void aa(Space1::SubSpace1::A, SubSpace1::A, A) {} + }; + void aaa(Space1::SubSpace1::A, SubSpace1::A, A) {} + } +} + +namespace Space2 { + struct B; +} +using Space2::B; +#ifdef __clang__ +namespace Space2 { + struct B { + void bb(Space2::B, B) {} + }; +} +#else +struct B { + void bb(Space2::B, B) {} +}; +#endif +void bbb(Space2::B, B) {} + +namespace Space3 { + namespace SubSpace3 { + struct C; + struct D; + } +} +struct C; +struct D; +namespace Space3 { + struct C; + struct SubSpace3::C { + void cc(Space3::SubSpace3::C, SubSpace3::C) {} + }; + using SubSpace3::D; + struct SubSpace3::D { + void dd(Space3::SubSpace3::D, SubSpace3::D, D) {} + }; + void ccc(Space3::SubSpace3::C, SubSpace3::C) {} + void ddd(Space3::SubSpace3::D, SubSpace3::D, D) {} +} + +namespace Space4 { + namespace SubSpace4 { + struct E; + } +} +using namespace Space4; +using SubSpace4::E; +// Was added to incorrect namespace in swig-3.0.12 +struct SubSpace4::E { + void ee(Space4::SubSpace4::E, SubSpace4::E, E) {} +}; +void eee(Space4::SubSpace4::E, SubSpace4::E, E) {} + +namespace Space5 { + namespace SubSpace5 { + namespace SubSubSpace5 { + struct F; + } + } +} +namespace Space5 { + using namespace SubSpace5; + using SubSubSpace5::F; + // Was added to incorrect namespace in swig-3.0.12 + struct SubSubSpace5::F { + void ff(Space5::SubSpace5::SubSubSpace5::F, SubSpace5::SubSubSpace5::F, SubSubSpace5::F, F) {} + }; + void fff(Space5::SubSpace5::SubSubSpace5::F, SubSpace5::SubSubSpace5::F, SubSubSpace5::F, F) {} +} + +namespace Space6 { + struct G; + namespace SubSpace6 { + struct G; + } +} +namespace Space6 { + struct SubSpace6::G { + void gg(Space6::SubSpace6::G, SubSpace6::G) {} + }; + void ggg(Space6::SubSpace6::G, SubSpace6::G) {} +} + +struct HH; +struct H { + struct HH { + void hh(H::HH) {} + }; +}; +void hhh(H::HH) {} + +namespace Space8 { + struct II; + struct I { + struct II { + void ii(Space8::I::II, I::II) {} + }; + }; + void iii(Space8::I::II, I::II) {} +} + +struct J; +namespace Space9 { + namespace SubSpace9 { + struct J { + void jj(Space9::SubSpace9::J, SubSpace9::J, J) {} + }; + void jjj(Space9::SubSpace9::J, SubSpace9::J, J) {} + } +} + +namespace Space10 { + struct K; +} +namespace Space10 { + namespace SubSpace10 { + struct K { + void kk(Space10::SubSpace10::K, SubSpace10::K, K) {} + }; + void kkk(Space10::SubSpace10::K, SubSpace10::K, K) {} + } +} + +namespace OtherSpace { + struct L; + struct M; +} +using OtherSpace::L; +namespace Space11 { + using OtherSpace::M; + namespace SubSpace11 { + struct L { + void ll(Space11::SubSpace11::L, SubSpace11::L, L) {} + }; + void lll(Space11::SubSpace11::L, SubSpace11::L, L) {} + struct M { + void mm(Space11::SubSpace11::M, SubSpace11::M, M) {} + }; + void mmm(Space11::SubSpace11::M, SubSpace11::M, M) {} + } +} + +%} + diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 313120529..d2b35f100 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -99,7 +99,7 @@ CPP_TEST_BROKEN += \ # Broken C test cases. (Can be run individually using: make testcase.ctest) C_TEST_BROKEN += \ - tag_no_clash_with_variable + tag_no_clash_with_variable \ # C++ test cases. (Can be run individually using: make testcase.cpptest) CPP_TEST_CASES += \ @@ -136,6 +136,7 @@ CPP_TEST_CASES += \ char_binary \ char_strings \ chartest \ + class_scope_namespace \ class_forward \ class_ignore \ class_scope_weird \ @@ -246,6 +247,7 @@ CPP_TEST_CASES += \ global_vars \ grouping \ ignore_parameter \ + import_fragments \ import_nomodule \ inherit \ inherit_member \ @@ -278,6 +280,7 @@ CPP_TEST_CASES += \ memberin_extend \ member_funcptr_galore \ member_pointer \ + member_pointer_const \ member_template \ minherit \ minherit2 \ @@ -289,6 +292,7 @@ CPP_TEST_CASES += \ multiple_inheritance_shared_ptr \ name_cxx \ name_warnings \ + namespace_chase \ namespace_class \ namespace_enum \ namespace_extend \ @@ -416,6 +420,7 @@ CPP_TEST_CASES += \ template_default_inherit \ template_default_qualify \ template_default_vw \ + template_empty_inherit \ template_enum \ template_enum_ns_inherit \ template_enum_typedef \ @@ -432,6 +437,7 @@ CPP_TEST_CASES += \ template_methods \ template_namespace_forward_declaration \ template_using_directive_and_declaration_forward \ + template_using_directive_typedef \ template_nested \ template_nested_typemaps \ template_ns \ @@ -442,6 +448,7 @@ CPP_TEST_CASES += \ template_ns_enum2 \ template_ns_inherit \ template_ns_scope \ + template_parameters_global_scope \ template_partial_arg \ template_partial_specialization \ template_partial_specialization_typedef \ @@ -531,10 +538,10 @@ CPP_TEST_CASES += \ virtual_vs_nonvirtual_base \ voidtest \ wallkw \ - wrapmacro + wrapmacro \ # C++11 test cases. -CPP11_TEST_CASES = \ +CPP11_TEST_CASES += \ cpp11_alignment \ cpp11_alternate_function_syntax \ cpp11_constexpr \ @@ -542,6 +549,7 @@ CPP11_TEST_CASES = \ cpp11_default_delete \ cpp11_delegating_constructors \ cpp11_director_enums \ + cpp11_directors \ cpp11_explicit_conversion_operators \ cpp11_final_override \ cpp11_function_objects \ @@ -553,6 +561,9 @@ CPP11_TEST_CASES = \ cpp11_noexcept \ cpp11_null_pointer_constant \ cpp11_raw_string_literals \ + cpp11_ref_qualifiers \ + cpp11_ref_qualifiers_rvalue_unignore \ + cpp11_ref_qualifiers_typemaps \ cpp11_result_of \ cpp11_rvalue_reference \ cpp11_rvalue_reference2 \ @@ -572,7 +583,6 @@ CPP11_TEST_CASES = \ # Broken C++11 test cases. CPP11_TEST_BROKEN = \ -# cpp11_hash_tables \ # not fully implemented yet # cpp11_variadic_templates \ # Broken for some languages (such as Java) # cpp11_reference_wrapper \ # No typemaps @@ -621,9 +631,7 @@ CPP_STD_TEST_CASES += \ smart_pointer_inherit \ template_typedef_fnc \ template_type_namespace \ - template_opaque -# li_std_list - + template_opaque \ ifndef SKIP_CPP_STD_CASES CPP_TEST_CASES += ${CPP_STD_TEST_CASES} @@ -687,7 +695,7 @@ C_TEST_CASES += \ typedef_struct \ typemap_subst \ union_parameter \ - unions + unions \ # Multi-module C++ test cases . (Can be run individually using make testcase.multicpptest) @@ -698,7 +706,7 @@ MULTI_CPP_TEST_CASES += \ packageoption \ mod \ template_typedef_import \ - multi_import + multi_import \ # Custom tests - tests with additional commandline options wallkw.cpptest: SWIGOPT += -Wallkw @@ -791,7 +799,7 @@ swig_and_compile_external = \ $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' \ SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \ TARGET='$*_wrap_hdr.h' \ - $(LANGUAGE)$(VARIANT)_externalhdr; \ + $(LANGUAGE)$(VARIANT)_externalhdr && \ $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS) $*_external.cxx' \ SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \ INCLUDES='$(INCLUDES)' SWIGOPT='$(SWIGOPT)' NOLINK=true \ @@ -805,7 +813,7 @@ setup = \ echo "$(ACTION)ing $(LANGUAGE) testcase $* (with run test)" ; \ else \ echo "$(ACTION)ing $(LANGUAGE) testcase $*" ; \ - fi; + fi diff --git a/Examples/test-suite/complextest.i b/Examples/test-suite/complextest.i index 64c751a82..6e82e8915 100644 --- a/Examples/test-suite/complextest.i +++ b/Examples/test-suite/complextest.i @@ -34,6 +34,11 @@ return b; } #endif + + struct ComplexPair + { + std::complex z1, z2; + }; } diff --git a/Examples/test-suite/constructor_copy.i b/Examples/test-suite/constructor_copy.i index 7dcd05e8b..222c12f32 100644 --- a/Examples/test-suite/constructor_copy.i +++ b/Examples/test-suite/constructor_copy.i @@ -73,12 +73,18 @@ public: %include "std_vector.i" -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGR) || defined(SWIGOCTAVE) || defined(SWIGRUBY) || defined(SWIGJAVASCRIPT) || defined(SWIGSCILAB) +#if defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGR) || defined(SWIGOCTAVE) || defined(SWIGRUBY) || defined(SWIGJAVASCRIPT) || defined(SWIGSCILAB) #define SWIG_GOOD_VECTOR %ignore std::vector::vector(size_type); %ignore std::vector::resize(size_type); #endif +#if defined(SWIGJAVA) +#define SWIG_GOOD_VECTOR +%ignore std::vector::vector(jint); +%ignore std::vector::resize(jint); +#endif + #if defined(SWIGTCL) || defined(SWIGPERL) #define SWIG_GOOD_VECTOR /* here, for languages with bad declaration */ diff --git a/Examples/test-suite/cplusplus_throw.i b/Examples/test-suite/cplusplus_throw.i index 3b11c48ca..112f9f3b5 100644 --- a/Examples/test-suite/cplusplus_throw.i +++ b/Examples/test-suite/cplusplus_throw.i @@ -9,6 +9,10 @@ #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif %} %nodefaultctor; @@ -26,3 +30,11 @@ public: %} +%{ +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +%} diff --git a/Examples/test-suite/cpp11_alternate_function_syntax.i b/Examples/test-suite/cpp11_alternate_function_syntax.i index 227a1c8c8..b3ecabc8c 100644 --- a/Examples/test-suite/cpp11_alternate_function_syntax.i +++ b/Examples/test-suite/cpp11_alternate_function_syntax.i @@ -6,13 +6,26 @@ struct SomeStruct { int addNormal(int x, int y); auto addAlternate(int x, int y) -> int; + auto addAlternateConst(int x, int y) const -> int; + auto addAlternateNoExcept(int x, int y) noexcept -> int; + auto addAlternateConstNoExcept(int x, int y) const noexcept -> int; + auto addAlternateMemberPtrParm(int x, int (SomeStruct::*mp)(int, int)) -> int; + auto addAlternateMemberPtrConstParm(int x, int (SomeStruct::*mp)(int, int) const) const -> int; + + virtual auto addFinal(int x, int y) const noexcept -> int final { return x + y; } + virtual ~SomeStruct() = default; }; -auto SomeStruct::addAlternate(int x, int y) -> int { - return x + y; +int SomeStruct::addNormal(int x, int y) { return x + y; } +auto SomeStruct::addAlternate(int x, int y) -> int { return x + y; } +auto SomeStruct::addAlternateConst(int x, int y) const -> int { return x + y; } +auto SomeStruct::addAlternateNoExcept(int x, int y) noexcept -> int { return x + y; } +auto SomeStruct::addAlternateConstNoExcept(int x, int y) const noexcept -> int { return x + y; } +auto SomeStruct::addAlternateMemberPtrParm(int x, int (SomeStruct::*mp)(int, int)) -> int { + return 100*x + (this->*mp)(x, x); +} +auto SomeStruct::addAlternateMemberPtrConstParm(int x, int (SomeStruct::*mp)(int, int) const) const -> int { + return 1000*x + (this->*mp)(x, x); } -int SomeStruct::addNormal(int x, int y) { - return x + y; -} %} diff --git a/Examples/test-suite/cpp11_constexpr.i b/Examples/test-suite/cpp11_constexpr.i index d91107cc6..755efb0e0 100644 --- a/Examples/test-suite/cpp11_constexpr.i +++ b/Examples/test-suite/cpp11_constexpr.i @@ -3,11 +3,17 @@ */ %module cpp11_constexpr + %inline %{ +#ifdef SWIG +#define SWIGTESTCONST const +#else +#define SWIGTESTCONST +#endif constexpr int AAA = 10; constexpr const int BBB = 20; constexpr int CCC() { return 30; } -constexpr const int DDD() { return 40; } +constexpr SWIGTESTCONST int DDD() { return 40; } constexpr int XXX() { return 10; } constexpr int YYY = XXX() + 100; @@ -17,7 +23,7 @@ struct ConstExpressions { static constexpr int KKK = 200; static const int LLL = 300; constexpr int MMM() { return 400; } - constexpr const int NNN() { return 500; } + constexpr SWIGTESTCONST int NNN() { return 500; } // Regression tests for support added in SWIG 3.0.4: static constexpr const int JJJ1 = 101; constexpr static int KKK1 = 201; diff --git a/Examples/test-suite/cpp11_default_delete.i b/Examples/test-suite/cpp11_default_delete.i index 79c02cddc..b5e84ed51 100644 --- a/Examples/test-suite/cpp11_default_delete.i +++ b/Examples/test-suite/cpp11_default_delete.i @@ -17,20 +17,20 @@ public: }; struct A1 { - void func(int i) {} + void funk(int i) {} A1() = default; ~A1() = default; - void func(double i) = delete; /* Don't cast double to int. Compiler returns an error */ + void funk(double i) = delete; /* Don't cast double to int. Compiler returns an error */ private: A1(const A1&); }; A1::A1(const A1&) = default; struct A2 { - void func(int i) {} + void funk(int i) {} virtual void fff(int) = delete; virtual ~A2() = default; - template void func(T) = delete; + template void funk(T) = delete; }; struct trivial { diff --git a/Examples/test-suite/cpp11_directors.i b/Examples/test-suite/cpp11_directors.i new file mode 100644 index 000000000..4462c1d52 --- /dev/null +++ b/Examples/test-suite/cpp11_directors.i @@ -0,0 +1,20 @@ +%module(directors="1") cpp11_directors +%feature("director"); + +%{ + +class Foo { + public: + virtual ~Foo() noexcept {} + virtual int ping() noexcept = 0; + virtual int pong() noexcept = 0; +}; + +%} + +class Foo { + public: + virtual ~Foo() noexcept {} + virtual int ping() noexcept = 0; + virtual int pong() noexcept = 0; +}; \ No newline at end of file diff --git a/Examples/test-suite/cpp11_final_override.i b/Examples/test-suite/cpp11_final_override.i index f691f8770..7abf50123 100644 --- a/Examples/test-suite/cpp11_final_override.i +++ b/Examples/test-suite/cpp11_final_override.i @@ -16,6 +16,8 @@ struct Base { virtual void finaloverride2() {} virtual void finaloverride3() {} virtual void finaloverride4() const {} + virtual void finaloverride5() {} + virtual void finaloverride6() const {} virtual ~Base() {} }; @@ -31,6 +33,8 @@ struct Derived /*final*/ : Base { virtual void finaloverride2() override final {} virtual void finaloverride3() noexcept override final {} virtual void finaloverride4() const noexcept override final {} + virtual void finaloverride5() throw(int) override final {} + virtual void finaloverride6() const throw(int) override final {} virtual ~Derived() override final {} }; void Derived::override2() const noexcept {} @@ -78,6 +82,7 @@ struct Destructors4 : Base { struct FinalOverrideMethods { virtual void final() {} virtual void override(int) {} + virtual ~FinalOverrideMethods() = default; }; struct FinalOverrideVariables { int final; diff --git a/Examples/test-suite/cpp11_hash_tables.i b/Examples/test-suite/cpp11_hash_tables.i index 4f68cbac5..0c671aa5d 100644 --- a/Examples/test-suite/cpp11_hash_tables.i +++ b/Examples/test-suite/cpp11_hash_tables.i @@ -4,19 +4,27 @@ %inline %{ #include -//#include +#include #include -//#include +#include %} %include "std_set.i" -//%include "std_map.i" +%include "std_multiset.i" +%include "std_map.i" +%include "std_multimap.i" %include "std_unordered_set.i" -//%include "std_unordered_map.i" +%include "std_unordered_multiset.i" +%include "std_unordered_map.i" +%include "std_unordered_multimap.i" %template (SetInt) std::set; -//%template (MapIntInt) std::map; +%template (MultiSetInt) std::multiset; +%template (MapIntInt) std::map; +%template (MultiMapIntInt) std::multimap; %template (UnorderedSetInt) std::unordered_set; -//%template (UnorderedMapIntInt) std::unordered_map; +%template (UnorderedMultiSetInt) std::unordered_multiset; +%template (UnorderedMapIntInt) std::unordered_map; +%template (UnorderedMultiMapIntInt) std::unordered_multimap; %inline %{ using namespace std; @@ -25,19 +33,19 @@ class MyClass { public: set getSet() { return _set; } void addSet(int elt) { _set.insert(_set.begin(), elt); } -// map getMap() { return _map; } -// void addMap(int elt1, int elt2) { _map.insert(make_pair(elt1, elt2)); } + map getMap() { return _map; } + void addMap(int elt1, int elt2) { _map.insert(make_pair(elt1, elt2)); } unordered_set getUnorderedSet() { return _unordered_set; } void addUnorderedSet(int elt) { _unordered_set.insert(_unordered_set.begin(), elt); } -// unordered_map getUnorderedMap() { return _unordered_map; } -// void addUnorderedMap(int elt1, int elt2) { _unordered_map.insert(make_pair(elt1, elt2)); } + unordered_map getUnorderedMap() { return _unordered_map; } + void addUnorderedMap(int elt1, int elt2) { _unordered_map.insert(make_pair(elt1, elt2)); } private: set _set; -// map _map; + map _map; unordered_set _unordered_set; -// unordered_map _unordered_map; + unordered_map _unordered_map; }; %} diff --git a/Examples/test-suite/cpp11_noexcept.i b/Examples/test-suite/cpp11_noexcept.i index ef96fd8a7..a77eb046f 100644 --- a/Examples/test-suite/cpp11_noexcept.i +++ b/Examples/test-suite/cpp11_noexcept.i @@ -3,9 +3,13 @@ %ignore NoExceptClass(NoExceptClass&&); %rename(Assignment) NoExceptClass::operator=; +%{ +extern "C" void global_noexcept(int, bool) noexcept {} +%} %inline %{ extern "C" void global_noexcept(int, bool) noexcept; +extern "C" void global_noexcept2(int, bool) noexcept {} struct NoExceptClass { static const bool VeryTrue = true; @@ -14,7 +18,7 @@ struct NoExceptClass { NoExceptClass(const NoExceptClass&) noexcept {} NoExceptClass(NoExceptClass&&) noexcept {} NoExceptClass& operator=(const NoExceptClass&) noexcept { return *this; } - ~NoExceptClass() noexcept {} + virtual ~NoExceptClass() noexcept {} void noex0() noexcept {} void noex1() noexcept(sizeof(int) == 4) {} diff --git a/Examples/test-suite/cpp11_raw_string_literals.i b/Examples/test-suite/cpp11_raw_string_literals.i index 6fd13a0d0..1dea90e0c 100644 --- a/Examples/test-suite/cpp11_raw_string_literals.i +++ b/Examples/test-suite/cpp11_raw_string_literals.i @@ -17,7 +17,9 @@ %warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) hh; %warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) ii; +#if defined(SWIGTCL) || defined(SWIGCSHARP) || defined(SWIGOCTAVE) || defined(SWIGRUBY) || defined(SWIGPYTHON) || defined(SWIGJAVA) %include +#endif %inline %{ #include diff --git a/Examples/test-suite/cpp11_ref_qualifiers.i b/Examples/test-suite/cpp11_ref_qualifiers.i new file mode 100644 index 000000000..e37136770 --- /dev/null +++ b/Examples/test-suite/cpp11_ref_qualifiers.i @@ -0,0 +1,226 @@ +%module cpp11_ref_qualifiers + +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) ccextra2; +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) ccextra3; +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc2; +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc3; +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc5; + +%include + +%ignore Host::h() const &; + +// Basic testing +%inline %{ +using std::string; +class Host { + string s; +public: + string h1() & { return string(); } + string h2() const & { return string(); } + string h3() && { return std::move(string()); } + string h4() const && { return std::move(string()); } + string h5() const { return string(); } + string h6() volatile const & { return string(); } + string h7() const volatile & { return string(); } + string h8() volatile const && { return std::move(string()); } + string h9() const volatile && { return std::move(string()); } + + string h() & { return string(); } + string h() const & { return string(); } + string h() && { return std::move(string()); } + string h() const && { return std::move(string()); } +}; +%} + +// %feature testing +%feature("except") F1() & %{ result = "F1"; %} +%feature("except") F2 %{ result = "F2"; %} +%feature("except") F3 %{ result = "F3"; %} +%feature("except") F3() %{ _should_not_be_used_ %} + +%feature("except") C1(int i) const & %{ result = "C1"; %} +%feature("except") C2 %{ result = "C2"; %} +%feature("except") C3 %{ result = "C3"; %} +%feature("except") C3(int i) %{ _should_not_be_used_ %} + +%inline %{ +struct Features { + string F1() & { return string(); } + string F2() & { return string(); } + string F3() & { return string(); } + + string C1(int i) const & { return string(); } + string C2(int i) const & { return string(); } + string C3(int i) const & { return string(); } +}; +%} + +// %rename testing +%rename(RR1) R1; +%rename(RR2) R2() &; +%rename(RR3) R3; +%rename(RR3Bad) R3(); + +%rename(SS1) S1; +%rename(SS2) S2(int i) const &; +%rename(SS3) S3; +%rename(SS3Bad) S3(int i); +%rename(SS3BadConst) S3(int i) const; +%rename(SS3BadLValue) S3(int i) &; + +%inline %{ +struct Renames { + string R1() & { return string(); } + string R2() & { return string(); } + string R3() & { return string(); } + + string S1(int i) const & { return string(); } + string S2(int i) const & { return string(); } + string S3(int i) const & { return string(); } +}; +%} + +// Conversion operators +%rename(StringConvertCopy) operator string() &; +%rename(StringConvertMove) operator string() &&; +%feature("ignore", "0") operator string() &&; // unignore as it is ignored by default + +%inline %{ +struct ConversionOperators { + virtual operator string() & { return string(); } + virtual operator string() && { return std::move(string()); } + virtual ~ConversionOperators() {} +}; +struct ConversionOperators2 { + virtual operator string() && { return std::move(string()); } + virtual ~ConversionOperators2() {} +}; +%} + +%inline %{ +struct Funcs { + short FF(bool) { return 0; } + short CC(bool) const & { return 0; } +}; + +class MemberFuncPtrs +{ +public: + // member ref-qualified function pointers, unnamed parameters + int aaa1(short (Funcs::*)(bool) &) const; + int aaa2(short (Funcs::* const *&)(bool) &) const; + int aaa3(short (Funcs::* *&)(bool) &) const; + int aaa4(short (Funcs::* *const&)(bool) &) const; + int aaa5(short (Funcs::* &)(bool) &) const; + int aaa6(short (Funcs::* const)(bool) &) const; + int aaa7(short (Funcs::* const&)(bool) &) const; + + int aaa8(short (Funcs::* const&)(bool) &&) const; + + // member cv-qualified and ref-qualified function pointers, unnamed parameters + int bbb1(short (Funcs::*)(bool) const &) const; + int bbb2(short (Funcs::* const *&)(bool) const &) const; + int bbb3(short (Funcs::* *&)(bool) const &) const; + int bbb4(short (Funcs::* *const&)(bool) const &) const; + int bbb5(short (Funcs::* &)(bool) const &) const; + int bbb6(short (Funcs::* const)(bool) const &) const; + int bbb7(short (Funcs::* const&)(bool) const &) const; + + int bbb8(short (Funcs::*)(bool) const &&) const; + + // member ref-qualified function pointers, named parameters + int qqq1(short (Funcs::* qq1)(bool) &) const; + int qqq2(short (Funcs::* const *& qq2)(bool) &) const; + int qqq3(short (Funcs::* *& qq3)(bool) &) const; + int qqq4(short (Funcs::* *const& qq4)(bool) &) const; + int qqq5(short (Funcs::* & qq5)(bool) &) const; + int qqq6(short (Funcs::* const qq6)(bool) &) const; + int qqq7(short (Funcs::* const& qq7)(bool) &) const; + + int qqq8(short (Funcs::* const& qq8)(bool) &&) const; + + // member cv-qualified and ref-qualified function pointers, named parameters + int rrr1(short (Funcs::* rr1)(bool) const &) const; + int rrr2(short (Funcs::* const *& rr2)(bool) const &) const; + int rrr3(short (Funcs::* *& rr3)(bool) const &) const; + int rrr4(short (Funcs::* *const& rr4)(bool) const &) const; + int rrr5(short (Funcs::* & rr5)(bool) const &) const; + int rrr6(short (Funcs::* const rr6)(bool) const &) const; + int rrr7(short (Funcs::* const& rr7)(bool) const &) const; + + int rrr8(short (Funcs::* rr1)(bool) const &&) const; +}; + +// member ref-qualified function pointers, unnamed parameters +int MemberFuncPtrs::aaa1(short (Funcs::*)(bool) &) const { return 0; } +int MemberFuncPtrs::aaa2(short (Funcs::* const *&)(bool) &) const { return 0; } +int MemberFuncPtrs::aaa3(short (Funcs::* *&)(bool) &) const { return 0; } +int MemberFuncPtrs::aaa4(short (Funcs::* *const&)(bool) &) const { return 0; } +int MemberFuncPtrs::aaa5(short (Funcs::* &)(bool) &) const { return 0; } +int MemberFuncPtrs::aaa6(short (Funcs::* const)(bool) &) const { return 0; } +int MemberFuncPtrs::aaa7(short (Funcs::* const&)(bool) &) const { return 0; } + +int MemberFuncPtrs::aaa8(short (Funcs::* const&)(bool) &&) const { return 0; } + +// member cv-qualified and ref-qualified function pointers, unnamed parameters +int MemberFuncPtrs::bbb1(short (Funcs::*)(bool) const &) const { return 0; } +int MemberFuncPtrs::bbb2(short (Funcs::* const *&)(bool) const &) const { return 0; } +int MemberFuncPtrs::bbb3(short (Funcs::* *&)(bool) const &) const { return 0; } +int MemberFuncPtrs::bbb4(short (Funcs::* *const&)(bool) const &) const { return 0; } +int MemberFuncPtrs::bbb5(short (Funcs::* &)(bool) const &) const { return 0; } +int MemberFuncPtrs::bbb6(short (Funcs::* const)(bool) const &) const { return 0; } +int MemberFuncPtrs::bbb7(short (Funcs::* const&)(bool) const &) const { return 0; } + +int MemberFuncPtrs::bbb8(short (Funcs::*)(bool) const &&) const { return 0; } + +// member ref-qualified function pointers, named parameters +int MemberFuncPtrs::qqq1(short (Funcs::* qq1)(bool) &) const { return 0; } +int MemberFuncPtrs::qqq2(short (Funcs::* const *& qq2)(bool) &) const { return 0; } +int MemberFuncPtrs::qqq3(short (Funcs::* *& qq3)(bool) &) const { return 0; } +int MemberFuncPtrs::qqq4(short (Funcs::* *const& qq4)(bool) &) const { return 0; } +int MemberFuncPtrs::qqq5(short (Funcs::* & qq5)(bool) &) const { return 0; } +int MemberFuncPtrs::qqq6(short (Funcs::* const qq6)(bool) &) const { return 0; } +int MemberFuncPtrs::qqq7(short (Funcs::* const& qq7)(bool) &) const { return 0; } + +int MemberFuncPtrs::qqq8(short (Funcs::* const& qq8)(bool) &&) const { return 0; } + +// member cv-qualified and ref-qualified function pointers, named parameters +int MemberFuncPtrs::rrr1(short (Funcs::* rr1)(bool) const &) const { return 0; } +int MemberFuncPtrs::rrr2(short (Funcs::* const *& rr2)(bool) const &) const { return 0; } +int MemberFuncPtrs::rrr3(short (Funcs::* *& rr3)(bool) const &) const { return 0; } +int MemberFuncPtrs::rrr4(short (Funcs::* *const& rr4)(bool) const &) const { return 0; } +int MemberFuncPtrs::rrr5(short (Funcs::* & rr5)(bool) const &) const { return 0; } +int MemberFuncPtrs::rrr6(short (Funcs::* const rr6)(bool) const &) const { return 0; } +int MemberFuncPtrs::rrr7(short (Funcs::* const& rr7)(bool) const &) const { return 0; } + +int MemberFuncPtrs::rrr8(short (Funcs::* rr1)(bool) const &&) const { return 0; } + +// member cv-qualified and ref-qualified pointer variables +short (Funcs::* cc1)(bool) const & = &Funcs::CC; + +short (Funcs::* const * ccextra2)(bool) const & = &cc1; +short (Funcs::* * ccextra3)(bool) const & = &cc1; +short (Funcs::* *const ccextra4)(bool) const & = &cc1; + +short (Funcs::* const *& cc2)(bool) const & = ccextra2; +short (Funcs::* *& cc3)(bool) const & = ccextra3; +short (Funcs::* *const& cc4)(bool) const & = ccextra4; +short (Funcs::* & cc5)(bool) const & = cc1; +short (Funcs::* const cc6)(bool) const & = &Funcs::CC; +short (Funcs::* const& cc7)(bool) const & = cc1; +%} + +%inline %{ + +struct Funktions { + int addByValue(const int &a, int b) const & { return a+b; } + int * addByPointer(const int &a, int b) const & { static int val; val = a+b; return &val; } + int & addByReference(const int &a, int b) const & { static int val; val = a+b; return val; } +}; + +int call1(int (Funktions::*d)(const int &, int) const &, int a, int b) { Funktions f; return (f.*d)(a, b); } +//int call2(int * (Funktions::*d)(const int &, int) const &, int a, int b) { Funktions f; return *(f.*d)(a, b); } +//int call3(int & (Funktions::*d)(const int &, int) const &, int a, int b) { Funktions f; return (f.*d)(a, b); } +%} +%constant int (Funktions::*ADD_BY_VALUE)(const int &, int) const & = &Funktions::addByValue; diff --git a/Examples/test-suite/cpp11_ref_qualifiers_rvalue_unignore.i b/Examples/test-suite/cpp11_ref_qualifiers_rvalue_unignore.i new file mode 100644 index 000000000..2f5fadfc6 --- /dev/null +++ b/Examples/test-suite/cpp11_ref_qualifiers_rvalue_unignore.i @@ -0,0 +1,15 @@ +%module cpp11_ref_qualifiers_rvalue_unignore + +// This is a minimal test that does not include any C++ headers to make sure the required +// header is generated from a fragment for the generated std::move call + +// m1 and m2 are ignored by default, unignore them +%feature("ignore", "0") RefQualifier::m1() &&; +%feature("ignore", "0") RefQualifier::m2() const &&; + +%inline %{ +struct RefQualifier { + void m1() && {} + void m2() const && {} +}; +%} diff --git a/Examples/test-suite/cpp11_ref_qualifiers_typemaps.i b/Examples/test-suite/cpp11_ref_qualifiers_typemaps.i new file mode 100644 index 000000000..0e1c3fe53 --- /dev/null +++ b/Examples/test-suite/cpp11_ref_qualifiers_typemaps.i @@ -0,0 +1,74 @@ +%module cpp11_ref_qualifiers_typemaps + +%typemap(in) SWIGTYPE (CLASS::*) %{ + _this_will_fail_to_compile_if_used_ +%} + +// typemaps to completely ignore the input parm and override it +%typemap(in) short (Funcs::*ff)(bool) const %{ $1 = &Funcs::FFF2; %} +%typemap(in) short (Funcs::*cc)(bool) & %{ $1 = &Funcs::CCC5; %} +%typemap(in) short (Funcs::*gg)(bool) const & %{ $1 = &Funcs::GGG8; %} +%typemap(in) short (Funcs::*hh)(bool) && %{ $1 = &Funcs::HHH11; %} + +%typemap(in) short (Funcs::*)(bool) const %{ $1 = &Funcs::FFF3; %} +%typemap(in) short (Funcs::*)(bool) & %{ $1 = &Funcs::CCC6; %} +%typemap(in) short (Funcs::*)(bool) const & %{ $1 = &Funcs::GGG9; %} +%typemap(in) short (Funcs::*)(bool) && %{ $1 = &Funcs::HHH12; %} + +%inline %{ +struct Funcs { + short FFF1(bool) const { return 1; } + short FFF2(bool) const { return 2; } + short FFF3(bool) const { return 3; } + short CCC4(bool) & { return 4; } + short CCC5(bool) & { return 5; } + short CCC6(bool) & { return 6; } + short GGG7(bool) const & { return 7; } + short GGG8(bool) const & { return 8; } + short GGG9(bool) const & { return 9; } + short HHH10(bool) && { return 10; } + short HHH11(bool) && { return 11; } + short HHH12(bool) && { return 12; } +}; +struct TypemapsNamedParms +{ + short fff(short (Funcs::*ff)(bool) const) { + Funcs funcs; + return (funcs.*ff)(true); + } + short ccc(short (Funcs::*cc)(bool) &) { + Funcs funcs; + return (funcs.*cc)(true); + } + short ggg(short (Funcs::*gg)(bool) const &) { + Funcs funcs; + return (funcs.*gg)(true); + } + short hhh(short (Funcs::*hh)(bool) &&) { + return (Funcs().*hh)(true); + } +}; +struct TypemapsUnnamedParms +{ + short fff(short (Funcs::*f)(bool) const) { + Funcs funcs; + return (funcs.*f)(true); + } + short ccc(short (Funcs::*c)(bool) &) { + Funcs funcs; + return (funcs.*c)(true); + } + short ggg(short (Funcs::*g)(bool) const &) { + Funcs funcs; + return (funcs.*g)(true); + } + short hhh(short (Funcs::*h)(bool) &&) { + return (Funcs().*h)(true); + } +}; +%} + +%constant short (Funcs::*FF1_MFP)(bool) const = &Funcs::FFF1; +%constant short (Funcs::*CC4_MFP)(bool) & = &Funcs::CCC4; +%constant short (Funcs::*GG7_MFP)(bool) const & = &Funcs::GGG7; +%constant short (Funcs::*HH10_MFP)(bool) && = &Funcs::HHH10; diff --git a/Examples/test-suite/cpp11_rvalue_reference2.i b/Examples/test-suite/cpp11_rvalue_reference2.i index 6718a3941..9aaf4accb 100644 --- a/Examples/test-suite/cpp11_rvalue_reference2.i +++ b/Examples/test-suite/cpp11_rvalue_reference2.i @@ -23,7 +23,7 @@ struct Thingy { int val; int &lvalref; int &&rvalref; - Thingy(int v) : val(v), lvalref(val), rvalref(22) {} + Thingy(int v, int &&rvalv) : val(v), lvalref(val), rvalref(std::move(rvalv)) {} void refIn(long &i) {} void rvalueIn(long &&i) {} short && rvalueInOut(short &&i) { return std::move(i); } @@ -32,7 +32,7 @@ struct Thingy { void compactDefaultArgs(const bool &&b = (const bool &&)PublicGlobalTrue, const UserDef &&u = (const UserDef &&)PublicUserDef) {} void privateDefaultArgs(const bool &&b = (const bool &&)PrivateTrue) {} operator int &&() { return std::move(0); } - Thingy(const Thingy& rhs) : val(rhs.val), lvalref(rhs.lvalref), rvalref(copy_int(rhs.rvalref)) {} + Thingy(const Thingy& rhs) : val(rhs.val), lvalref(rhs.lvalref), rvalref(std::move(rhs.rvalref)) {} Thingy& operator=(const Thingy& rhs) { val = rhs.val; lvalref = rhs.lvalref; @@ -41,23 +41,25 @@ struct Thingy { } private: static const bool PrivateTrue; - int copy_int(int& i) { return i; } Thingy(); }; const bool Thingy::PrivateTrue = true; short && globalRvalueInOut(short &&i) { return std::move(i); } -Thingy &&globalrrval = Thingy(55); +int glob = 123; -short && func(short &&i) { return std::move(i); } -Thingy getit() { return Thingy(22); } +Thingy &&globalrrval = Thingy(55, std::move(glob)); + +short && funk(short &&i) { return std::move(i); } +Thingy getit() { return Thingy(22, std::move(glob)); } void rvalrefFunction1(int &&v = (int &&)5) {} -void rvalrefFunctionBYVAL(short (Thingy::*memFunc)(short)) {} -void rvalrefFunctionLVALUE(short &(Thingy::*memFunc)(short &)) {} -void rvalrefFunction2(short && (Thingy::*memFunc)(short &&)) {} -void rvalrefFunction3(short && (*memFunc)(short &&)) {} +void rvalrefFunctionBYVAL(short (Thingy::*fptr)(short)) {} +void rvalrefFunctionPTR(short * (*fptr)(short *)) {} +void rvalrefFunctionLVALUE(short & (Thingy::*fptr)(short &)) {} +void rvalrefFunction2(short && (Thingy::*fptr)(short &&)) {} +void rvalrefFunction3(short && (*fptr)(short &&)) {} template struct RemoveReference { typedef T type; diff --git a/Examples/test-suite/cpp11_rvalue_reference3.i b/Examples/test-suite/cpp11_rvalue_reference3.i index c65309945..6dfe4c098 100644 --- a/Examples/test-suite/cpp11_rvalue_reference3.i +++ b/Examples/test-suite/cpp11_rvalue_reference3.i @@ -31,7 +31,13 @@ struct Containing { Thing *const&& member_rvalue_ref_ptr3 = 0; Thing const*const &&member_rvalue_ref_ptr4 = 0; - Containing() : member_rvalue_ref(Thing()) {} + Containing(Thing&&r, Thing*&& r1, Thing const*&& r2, Thing *const&& r3, Thing const*const && r4) : + member_rvalue_ref(std::move(r)), + member_rvalue_ref_ptr1(std::move(r1)), + member_rvalue_ref_ptr2(std::move(r2)), + member_rvalue_ref_ptr3(std::move(r3)), + member_rvalue_ref_ptr4(std::move(r4)) + {} }; %} @@ -62,6 +68,12 @@ struct IntContaining { int *const&& member_rvalue_ref_ptr3 = 0; int const*const &&member_rvalue_ref_ptr4 = 0; - IntContaining() : member_rvalue_ref(55) {} + IntContaining(int&& r, int*&& r1, int const*&& r2, int *const&& r3, int const*const && r4) : + member_rvalue_ref(std::move(r)), + member_rvalue_ref_ptr1(std::move(r1)), + member_rvalue_ref_ptr2(std::move(r2)), + member_rvalue_ref_ptr3(std::move(r3)), + member_rvalue_ref_ptr4(std::move(r4)) + {} }; %} diff --git a/Examples/test-suite/cpp11_shared_ptr_const.i b/Examples/test-suite/cpp11_shared_ptr_const.i new file mode 100644 index 000000000..0d1acdac0 --- /dev/null +++ b/Examples/test-suite/cpp11_shared_ptr_const.i @@ -0,0 +1,57 @@ +%module cpp11_shared_ptr_const + +%{ + +#include +#include + +class Foo +{ +public: + Foo(int i) : m(i) {} + int get_m() { return m;} + int m; +}; + +std::shared_ptr foo(Foo v) { + return std::shared_ptr(new Foo(v)); +} + +std::shared_ptr const_foo(Foo v) { + return std::shared_ptr(new Foo(v)); +} + +std::vector > foo_vec(Foo v) { + std::vector > result; + result.push_back( std::shared_ptr(new Foo(v)) ); + return result; +} + +std::vector > const_foo_vec(Foo v) { + std::vector > result; + result.push_back( std::shared_ptr(new Foo(v)) ); + return result; +} + +%} + +%include +%include + +%shared_ptr(Foo); + +%template (FooVector) std::vector >; +%template (FooConstVector) std::vector >; + +class Foo +{ +public: + Foo(int i); + int get_m(); + int m; +}; +std::shared_ptr foo(Foo v); +std::shared_ptr const_foo(Foo v); +std::vector > foo_vec(Foo v) const; +std::vector > const_foo_vec(Foo v) const; + diff --git a/Examples/test-suite/cpp11_shared_ptr_nullptr_in_containers.i b/Examples/test-suite/cpp11_shared_ptr_nullptr_in_containers.i new file mode 100644 index 000000000..46e2501d7 --- /dev/null +++ b/Examples/test-suite/cpp11_shared_ptr_nullptr_in_containers.i @@ -0,0 +1,50 @@ +%module cpp11_shared_ptr_nullptr_in_containers + +%{ +#include +#include + +class C; +%} + +%include +%include + +%shared_ptr(C) + +%inline %{ + +class C { +public: + C() : m(-1) {} + C(int i) : m(i) {} + int get_m() { return m; } + int m; +}; + +%} + +%template() std::vector >; + +%inline %{ + + std::vector > ret_vec_c_shared_ptr() { + std::vector > ret(3); + ret[0] = std::shared_ptr(new C(0)); + ret[2] = std::shared_ptr(new C(2)); + return ret; + } + + std::vector > ret_arg_vec(const std::vector >& v) { + return v; + } + + bool is_last_null(const std::vector >& v) { + if( v.back() ) { + return false; + } else { + return true; + } + } + +%} diff --git a/Examples/test-suite/cpp11_shared_ptr_upcast.i b/Examples/test-suite/cpp11_shared_ptr_upcast.i new file mode 100644 index 000000000..3427829d9 --- /dev/null +++ b/Examples/test-suite/cpp11_shared_ptr_upcast.i @@ -0,0 +1,188 @@ +%module cpp11_shared_ptr_upcast + +%{ +#include +#include +#include +#include +#include +#include +%} + +%include +%include +%include + +%{ + +class Base { +public: + Base() : m(-1) {} + Base(int i) : m(i) {} + int get_m() { return m; } + int m; +}; + +class Derived : public Base { +public: + Derived() : n(-2) {} + Derived(int i) : n(i) {} + int get_n() { return n; } + int n; +}; + +typedef std::shared_ptr BasePtr; +typedef std::shared_ptr DerivedPtr; + +// non-overloaded +int derived_num1(DerivedPtr v) { + return v == nullptr ? 999 : (*v).get_n(); +} + +int derived_num2(std::vector v) { + return v[0] == nullptr ? 999 : (*v[0]).get_n(); +} + +int derived_num3(std::map v) { + return v[0] == nullptr ? 999 : (*v[0]).get_n(); +} + +int base_num1(BasePtr v) { + return v == nullptr ? 999 : (*v).get_m(); +} + +int base_num2(std::vector v) { + return v[0] == nullptr ? 999 : (*v[0]).get_m(); +} + +int base_num3(std::map v) { + return v[0] == nullptr ? 999 : (*v[0]).get_m(); +} + +// overloaded +int derived_num(DerivedPtr v) { + return derived_num1(v); +} + +int derived_num(std::vector v) { + return derived_num2(v); +} + +int derived_num(std::map v) { + return derived_num3(v); +} + +int base_num(BasePtr v) { + return base_num1(v); +} + +int base_num(std::vector v) { + return base_num2(v); +} + +int base_num(std::map v) { + return base_num3(v); +} +%} + + +%shared_ptr(Base); +%shared_ptr(Derived); + +%template(BaseList) std::vector >; +%template(DerivedList) std::vector >; + +%template(BaseMap) std::map >; +%template(DerivedMap) std::map >; + +class Base { +public: + Base(); + int get_m(); + int m; +}; + +class Derived : public Base { +public: + Derived(); + Derived(int i); + int get_n(); + int n; +}; + +typedef std::shared_ptr BasePtr; +typedef std::shared_ptr DerivedPtr; + +// non-overloaded +int derived_num1(DerivedPtr); +int derived_num2(std::vector > v); +int derived_num3(std::map v); +int base_num1(BasePtr); +int base_num2(std::vector > v); +int base_num3(std::map v); + +// overloaded +int derived_num(DerivedPtr); +int derived_num(std::vector > v); +int derived_num(std::map v); +int base_num(BasePtr); +int base_num(std::vector > v); +int base_num(std::map v); + +// ptr to shared_ptr +%shared_ptr(Base2); +%shared_ptr(Derived2) + +%inline %{ +class Base2 { +public: + Base2() : m(-1) {} + Base2(int i) : m(i) {} + int get_m() { return m; } + int m; +}; + + +class Derived2 : public Base2 { +public: + Derived2() : n(0) {} + Derived2(int i) : n(i) {} + int get_n_2() { return n; } + int n; +}; +%} + +%template(Base2List) std::vector * >; +%template(Base2Map) std::map * >; + +%template(Derived2List) std::vector * >; +%template(Derived2Map) std::map * >; + +%inline %{ +typedef std::shared_ptr * Derived2Ptr; +typedef std::shared_ptr * Base2Ptr; + +int base2_num1(Base2Ptr v) { + return v == nullptr ? 999 : *v == nullptr ? 888 : (*v)->get_m(); +} + +int base2_num2(std::vector v) { + return v[0] == nullptr ? 999 : *v[0] == nullptr ? 888 : (*v[0])->get_m(); +} + +int base2_num3(std::map v) { + return v[0] == nullptr ? 999 : *v[0] == nullptr ? 888 : (*v[0])->get_m(); +} + +int derived2_num1(Derived2Ptr v) { + return v == nullptr ? 999 : *v == nullptr ? 888 : (*v)->get_n_2(); +} + +int derived2_num2(std::vector v) { + return v[0] == nullptr ? 999 : *v[0] == nullptr ? 888 : (*v[0])->get_n_2(); +} + +int derived2_num3(std::map v) { + return v[0] == nullptr ? 999 : *v[0] == nullptr ? 888 : (*v[0])->get_n_2(); +} +%} diff --git a/Examples/test-suite/cpp11_static_assert.i b/Examples/test-suite/cpp11_static_assert.i index 8d616f96c..7ca452d85 100644 --- a/Examples/test-suite/cpp11_static_assert.i +++ b/Examples/test-suite/cpp11_static_assert.i @@ -1,12 +1,32 @@ -/* This test case checks whether SWIG correctly parses and ignores the - keywords "static_assert()" inside the class or struct. +/* This test case checks whether SWIG correctly parses and ignores + "static_assert()" in various places. */ %module cpp11_static_assert %inline %{ +static_assert(sizeof(int) >= 2, "What? int size is invalid!"); + +namespace dummy { +// C++17 allows the message to be omitted, so check that works too. +// But only show the C++17 version to SWIG, as the compiler may +// lack C++17 support. +#ifdef SWIG +static_assert(sizeof(int) >= sizeof(short)); +#else +static_assert(sizeof(int) >= sizeof(short), "blah"); +#endif +} + template struct Check1 { static_assert(sizeof(int) <= sizeof(T), "not big enough"); + Check1() { +#ifdef SWIG + static_assert(true); +#else + static_assert(true, "true"); +#endif + } }; template diff --git a/Examples/test-suite/cpp11_std_unordered_map.i b/Examples/test-suite/cpp11_std_unordered_map.i new file mode 100644 index 000000000..56c4a5248 --- /dev/null +++ b/Examples/test-suite/cpp11_std_unordered_map.i @@ -0,0 +1,5 @@ +%module cpp11_std_unordered_map + +%include + +%template(UnorderedMapIntInt) std::unordered_map; diff --git a/Examples/test-suite/cpp11_std_unordered_multimap.i b/Examples/test-suite/cpp11_std_unordered_multimap.i new file mode 100644 index 000000000..8556b26b5 --- /dev/null +++ b/Examples/test-suite/cpp11_std_unordered_multimap.i @@ -0,0 +1,7 @@ +%module cpp11_std_unordered_multimap + +%include +%include + +%template(PairIntInt) std::pair; +%template(UnorderedMultiMapIntInt) std::unordered_multimap; diff --git a/Examples/test-suite/cpp11_std_unordered_multiset.i b/Examples/test-suite/cpp11_std_unordered_multiset.i new file mode 100644 index 000000000..c9907425e --- /dev/null +++ b/Examples/test-suite/cpp11_std_unordered_multiset.i @@ -0,0 +1,5 @@ +%module cpp11_std_unordered_multiset + +%include + +%template(UnorderedMultiSetInt) std::unordered_multiset; diff --git a/Examples/test-suite/cpp11_std_unordered_set.i b/Examples/test-suite/cpp11_std_unordered_set.i new file mode 100644 index 000000000..f5652cb88 --- /dev/null +++ b/Examples/test-suite/cpp11_std_unordered_set.i @@ -0,0 +1,5 @@ +%module cpp11_std_unordered_set + +%include + +%template(UnorderedSetInt) std::unordered_set; diff --git a/Examples/test-suite/cpp11_type_aliasing.i b/Examples/test-suite/cpp11_type_aliasing.i index 2f6ea3aa7..abc1642c4 100644 --- a/Examples/test-suite/cpp11_type_aliasing.i +++ b/Examples/test-suite/cpp11_type_aliasing.i @@ -108,5 +108,5 @@ PairSubclass::data_t plus1(PairSubclass::const_ref_data_t x) { return x + 1; } using callback_t = int(*)(int); callback_t get_callback() { return mult2; } -int call(callback_t func, int param) { return func(param); } +int call(callback_t funk, int param) { return funk(param); } %} diff --git a/Examples/test-suite/csharp/Makefile.in b/Examples/test-suite/csharp/Makefile.in index 0c799c7d9..292854a9f 100644 --- a/Examples/test-suite/csharp/Makefile.in +++ b/Examples/test-suite/csharp/Makefile.in @@ -13,6 +13,7 @@ top_srcdir = ../@top_srcdir@ top_builddir = ../@top_builddir@ CPP_TEST_CASES = \ + complextest \ csharp_attributes \ csharp_swig2_compatibility \ csharp_exceptions \ @@ -40,6 +41,7 @@ CSHARPFLAGSSPECIAL = # Custom tests - tests with additional commandline options intermediary_classname.cpptest: SWIGOPT += -dllimport intermediary_classname +complextest.cpptest: CSHARPFLAGSSPECIAL = -r:System.Numerics.dll csharp_lib_arrays.cpptest: CSHARPFLAGSSPECIAL = -unsafe csharp_swig2_compatibility.cpptest: SWIGOPT += -DSWIG2_CSHARP diff --git a/Examples/test-suite/csharp/complextest_runme.cs b/Examples/test-suite/csharp/complextest_runme.cs new file mode 100644 index 000000000..2b7e4cc84 --- /dev/null +++ b/Examples/test-suite/csharp/complextest_runme.cs @@ -0,0 +1,34 @@ +// This is the complex runtime testcase. It checks that the C++ std::complex type works. +// It requires .NET 4.0 as the previous versions didn't have System.Numerics.Complex type. + +using System; +using System.Numerics; + +using complextestNamespace; + +public class complextest_runme { + + public static void Main() { + var a = new Complex(-1, 2); + if ( complextest.Conj(a) != Complex.Conjugate(a) ) + throw new Exception("std::complex test failed"); + + if ( complextest.Conjf(a) != Complex.Conjugate(a) ) + throw new Exception("std::complex test failed"); + + var vec = new VectorStdCplx(); + vec.Add(new Complex(1, 2)); + vec.Add(new Complex(2, 3)); + vec.Add(new Complex(4, 3)); + vec.Add(new Complex(1, 0)); + + if ( complextest.Copy_h(vec).Count != 2 ) + throw new Exception("vector test failed"); + + var p = new ComplexPair(); + p.z1 = new Complex(0, 1); + p.z2 = new Complex(0, -1); + if ( Complex.Conjugate(p.z2) != p.z1 ) + throw new Exception("vector test failed"); + } +} diff --git a/Examples/test-suite/csharp/director_smartptr_runme.cs b/Examples/test-suite/csharp/director_smartptr_runme.cs index 559dff7a0..33037a1da 100644 --- a/Examples/test-suite/csharp/director_smartptr_runme.cs +++ b/Examples/test-suite/csharp/director_smartptr_runme.cs @@ -26,6 +26,29 @@ public class runme } } + private class director_smartptr_MyBarFooDerived : FooDerived + { + public override string ping() + { + return "director_smartptr_MyBarFooDerived.ping()"; + } + + public override string pong() + { + return "director_smartptr_MyBarFooDerived.pong();" + ping(); + } + + public override string upcall(FooBar fooBarPtr) + { + return "overrideDerived;" + fooBarPtr.FooBarDo(); + } + + public override Foo makeFoo() + { + return new Foo(); + } + } + private static void check(string got, string expected) { if (got != expected) @@ -49,5 +72,11 @@ public class runme Foo myFoo2 = new Foo().makeFoo(); check(myFoo2.pong(), "Foo::pong();Foo::ping()"); check(Foo.callPong(myFoo2), "Foo::pong();Foo::ping()"); + + FooDerived myBarFooDerived = new director_smartptr_MyBarFooDerived(); + check(myBarFooDerived.ping(), "director_smartptr_MyBarFooDerived.ping()"); + check(FooDerived.callPong(myBarFooDerived), "director_smartptr_MyBarFooDerived.pong();director_smartptr_MyBarFooDerived.ping()"); + check(FooDerived.callUpcall(myBarFooDerived, fooBar), "overrideDerived;Bar::Foo2::Foo2Bar()"); + } } diff --git a/Examples/test-suite/csharp/li_std_map_runme.cs b/Examples/test-suite/csharp/li_std_map_runme.cs index 0fe1ab5cd..b21c81e4e 100644 --- a/Examples/test-suite/csharp/li_std_map_runme.cs +++ b/Examples/test-suite/csharp/li_std_map_runme.cs @@ -18,7 +18,7 @@ public class li_std_map_runme { public static void Main() { - // Set up an int int map + // Set up an string to int map StringIntMap simap = new StringIntMap(); for (int i = 0; i < collectionSize; i++) { diff --git a/Examples/test-suite/csharp/li_std_vector_runme.cs b/Examples/test-suite/csharp/li_std_vector_runme.cs index fa8700d89..453faa6c1 100644 --- a/Examples/test-suite/csharp/li_std_vector_runme.cs +++ b/Examples/test-suite/csharp/li_std_vector_runme.cs @@ -121,7 +121,7 @@ public class li_std_vector_runme { throw new Exception("Contains test 4 failed"); { - // ICollection constructor + // IEnumerable constructor double[] doubleArray = new double[] { 0.0, 11.1, 22.2, 33.3, 44.4, 55.5, 33.3 }; DoubleVector dv = new DoubleVector(doubleArray); if (doubleArray.Length != dv.Count) @@ -619,6 +619,55 @@ public class li_std_vector_runme { } } + // Test construction + { + string[] one_two_three = new string[] { "one", "two", "three" }; + + // Test construction from array + { + string[] collection = one_two_three; + check123(new StringVector(collection)); + } + + // Test construction from IEnumerable + { + global::System.Collections.IEnumerable collection = one_two_three; + check123(new StringVector(collection)); + } + + // Test construction from IEnumerable<> + { + global::System.Collections.Generic.IEnumerable collection = one_two_three; + check123(new StringVector(collection)); + } + + // Test construction from IList<> + { + global::System.Collections.Generic.IList collection = one_two_three; + check123(new StringVector(collection)); + } + + // Test construction from ICollection + { + global::System.Collections.ICollection collection = one_two_three; + check123(new StringVector(collection)); + } + + // Test construction from ICollection<> + { + global::System.Collections.Generic.ICollection collection = new global::System.Collections.Generic.List(one_two_three); + check123(new StringVector(collection)); + } + } + + } + + private static void check123(StringVector stringv) { + string concatenated = ""; + foreach (string s in stringv) + concatenated = concatenated + s; + if (concatenated != "onetwothree") + throw new Exception("concatenated string failed: " + concatenated); } } diff --git a/Examples/test-suite/csharp/preproc_constants_c_runme.cs b/Examples/test-suite/csharp/preproc_constants_c_runme.cs index 76c684d85..5966d5266 100644 --- a/Examples/test-suite/csharp/preproc_constants_c_runme.cs +++ b/Examples/test-suite/csharp/preproc_constants_c_runme.cs @@ -36,7 +36,7 @@ public class runme { assert( typeof(string) == preproc_constants_c.CONST_STRING2.GetType() ); assert( typeof(int) == preproc_constants_c.INT_AND_BOOL.GetType() ); -// assert( typeof(int) == preproc_constants_c.INT_AND_CHAR.GetType() ); + assert( typeof(int) == preproc_constants_c.INT_AND_CHAR.GetType() ); assert( typeof(int) == preproc_constants_c.INT_AND_INT.GetType() ); assert( typeof(uint) == preproc_constants_c.INT_AND_UINT.GetType() ); assert( typeof(int) == preproc_constants_c.INT_AND_LONG.GetType() ); @@ -61,7 +61,9 @@ public class runme { assert( typeof(int) == preproc_constants_c.EXPR_LAND.GetType() ); assert( typeof(int) == preproc_constants_c.EXPR_LOR.GetType() ); assert( typeof(double) == preproc_constants_c.EXPR_CONDITIONAL.GetType() ); - + assert( typeof(double) == preproc_constants_c.EXPR_MIXED1.GetType() ); + assert( typeof(int) == preproc_constants_c.EXPR_WCHAR_MAX.GetType() ); + assert( typeof(int) == preproc_constants_c.EXPR_WCHAR_MIN.GetType() ); } static void assert(bool assertion) { if (!assertion) diff --git a/Examples/test-suite/csharp/preproc_constants_runme.cs b/Examples/test-suite/csharp/preproc_constants_runme.cs index 9fae5914a..6af8f20a4 100644 --- a/Examples/test-suite/csharp/preproc_constants_runme.cs +++ b/Examples/test-suite/csharp/preproc_constants_runme.cs @@ -35,7 +35,7 @@ public class runme { assert( typeof(string) == preproc_constants.CONST_STRING2.GetType() ); assert( typeof(int) == preproc_constants.INT_AND_BOOL.GetType() ); -// assert( typeof(int) == preproc_constants.INT_AND_CHAR.GetType() ); + assert( typeof(int) == preproc_constants.INT_AND_CHAR.GetType() ); assert( typeof(int) == preproc_constants.INT_AND_INT.GetType() ); assert( typeof(uint) == preproc_constants.INT_AND_UINT.GetType() ); assert( typeof(int) == preproc_constants.INT_AND_LONG.GetType() ); @@ -60,6 +60,9 @@ public class runme { assert( typeof(bool) == preproc_constants.EXPR_LAND.GetType() ); assert( typeof(bool) == preproc_constants.EXPR_LOR.GetType() ); assert( typeof(double) == preproc_constants.EXPR_CONDITIONAL.GetType() ); + assert( typeof(double) == preproc_constants.EXPR_MIXED1.GetType() ); + assert( typeof(int) == preproc_constants.EXPR_WCHAR_MAX.GetType() ); + assert( typeof(int) == preproc_constants.EXPR_WCHAR_MIN.GetType() ); } static void assert(bool assertion) { diff --git a/Examples/test-suite/csharp_exceptions.i b/Examples/test-suite/csharp_exceptions.i index e5b4d495b..53e51eb09 100644 --- a/Examples/test-suite/csharp_exceptions.i +++ b/Examples/test-suite/csharp_exceptions.i @@ -40,6 +40,10 @@ #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif // %exception tests void ThrowByValue() { throw Ex("ThrowByValue"); } @@ -239,3 +243,12 @@ struct ThrowsClass { %inline %{ void InnerExceptionTest() { throw Ex("My InnerException message"); } %} + +%{ +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +%} diff --git a/Examples/test-suite/d/preproc_constants_c_runme.1.d b/Examples/test-suite/d/preproc_constants_c_runme.1.d index d846c71ac..a6c2f3d10 100644 --- a/Examples/test-suite/d/preproc_constants_c_runme.1.d +++ b/Examples/test-suite/d/preproc_constants_c_runme.1.d @@ -36,7 +36,7 @@ void main() { static assert(is(char[] == typeof(CONST_STRING2()))); static assert(is(int == typeof(INT_AND_BOOL()))); -// static assert(is(int == typeof(INT_AND_CHAR()))); + static assert(is(int == typeof(INT_AND_CHAR()))); static assert(is(int == typeof(INT_AND_INT()))); static assert(is(uint == typeof(INT_AND_UINT()))); static assert(is(c_long == typeof(INT_AND_LONG()))); @@ -61,4 +61,7 @@ void main() { static assert(is(int == typeof(EXPR_LAND()))); static assert(is(int == typeof(EXPR_LOR()))); static assert(is(double == typeof(EXPR_CONDITIONAL()))); + static assert(is(double == typeof(EXPR_MIXED1()))); + static assert(is(int == typeof(EXPR_WCHAR_MAX()))); + static assert(is(int == typeof(EXPR_WCHAR_MIN()))); } diff --git a/Examples/test-suite/d/preproc_constants_c_runme.2.d b/Examples/test-suite/d/preproc_constants_c_runme.2.d index 9bdbb9372..786cb48cc 100644 --- a/Examples/test-suite/d/preproc_constants_c_runme.2.d +++ b/Examples/test-suite/d/preproc_constants_c_runme.2.d @@ -36,7 +36,7 @@ void main() { static assert(is(string == typeof(CONST_STRING2()))); static assert(is(int == typeof(INT_AND_BOOL()))); -// static assert(is(int == typeof(INT_AND_CHAR()))); + static assert(is(int == typeof(INT_AND_CHAR()))); static assert(is(int == typeof(INT_AND_INT()))); static assert(is(uint == typeof(INT_AND_UINT()))); static assert(is(c_long == typeof(INT_AND_LONG()))); @@ -61,4 +61,7 @@ void main() { static assert(is(int == typeof(EXPR_LAND()))); static assert(is(int == typeof(EXPR_LOR()))); static assert(is(double == typeof(EXPR_CONDITIONAL()))); + static assert(is(double == typeof(EXPR_MIXED1()))); + static assert(is(int == typeof(EXPR_WCHAR_MAX()))); + static assert(is(int == typeof(EXPR_WCHAR_MIN()))); } diff --git a/Examples/test-suite/d/preproc_constants_runme.1.d b/Examples/test-suite/d/preproc_constants_runme.1.d index 009405fc7..85fa918e4 100644 --- a/Examples/test-suite/d/preproc_constants_runme.1.d +++ b/Examples/test-suite/d/preproc_constants_runme.1.d @@ -35,7 +35,7 @@ void main() { static assert(is(char[] == typeof(CONST_STRING2()))); static assert(is(int == typeof(INT_AND_BOOL()))); -// static assert(is(int == typeof(INT_AND_CHAR()))); + static assert(is(int == typeof(INT_AND_CHAR()))); static assert(is(int == typeof(INT_AND_INT()))); static assert(is(uint == typeof(INT_AND_UINT()))); static assert(is(c_long == typeof(INT_AND_LONG()))); @@ -60,4 +60,7 @@ void main() { static assert(is(bool == typeof(EXPR_LAND()))); static assert(is(bool == typeof(EXPR_LOR()))); static assert(is(double == typeof(EXPR_CONDITIONAL()))); + static assert(is(double == typeof(EXPR_MIXED1()))); + static assert(is(int == typeof(EXPR_WCHAR_MAX()))); + static assert(is(int == typeof(EXPR_WCHAR_MIN()))); } diff --git a/Examples/test-suite/d/preproc_constants_runme.2.d b/Examples/test-suite/d/preproc_constants_runme.2.d index 2d92ef052..c81e53160 100644 --- a/Examples/test-suite/d/preproc_constants_runme.2.d +++ b/Examples/test-suite/d/preproc_constants_runme.2.d @@ -35,7 +35,7 @@ void main() { static assert(is(string == typeof(CONST_STRING2()))); static assert(is(int == typeof(INT_AND_BOOL()))); -// static assert(is(int == typeof(INT_AND_CHAR()))); + static assert(is(int == typeof(INT_AND_CHAR()))); static assert(is(int == typeof(INT_AND_INT()))); static assert(is(uint == typeof(INT_AND_UINT()))); static assert(is(c_long == typeof(INT_AND_LONG()))); @@ -60,4 +60,7 @@ void main() { static assert(is(bool == typeof(EXPR_LAND()))); static assert(is(bool == typeof(EXPR_LOR()))); static assert(is(double == typeof(EXPR_CONDITIONAL()))); + static assert(is(double == typeof(EXPR_MIXED1()))); + static assert(is(int == typeof(EXPR_WCHAR_MAX()))); + static assert(is(int == typeof(EXPR_WCHAR_MIN()))); } diff --git a/Examples/test-suite/default_args.i b/Examples/test-suite/default_args.i index 02d860765..1f7183f47 100644 --- a/Examples/test-suite/default_args.i +++ b/Examples/test-suite/default_args.i @@ -5,6 +5,11 @@ %{ #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) + #pragma warning(disable: 4146) // unary minus operator applied to unsigned type, result still unsigned +#endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 #endif %} @@ -14,14 +19,20 @@ #include // All kinds of numbers: hex, octal (which pose special problems to Python), negative... - void trickyvalue1(int first, int pos = -1) {} - void trickyvalue2(int first, unsigned rgb = 0xabcdef) {} - void trickyvalue3(int first, int mode = 0644) {} + + class TrickyInPython { + public: + int value_m1(int first, int pos = -1) { return pos; } + unsigned value_0xabcdef(int first, unsigned rgb = 0xabcdef) { return rgb; } + int value_0644(int first, int mode = 0644) { return mode; } + int value_perm(int first, int mode = 0640 | 0004) { return mode; } + int value_m01(int first, int val = -01) { return val; } + bool booltest2(bool x = 0 | 1) { return x; } + }; void doublevalue1(int first, double num = 0.0e-1) {} void doublevalue2(int first, double num = -0.0E2) {} - // Long long arguments are not handled at Python level currently but still work. void seek(long long offset = 0LL) {} void seek2(unsigned long long offset = 0ULL) {} void seek3(long offset = 0L) {} @@ -152,6 +163,9 @@ int double_if_handle_is_null(int n, MyHandle h = 0) { return h ? n : 2*n; } int double_if_dbl_ptr_is_null(int n, double* null_by_default) { return null_by_default ? n : 2*n; } + + void defaulted1(unsigned offset = -1U) {} // minus unsigned! + void defaulted2(int offset = -1U) {} // minus unsigned! }; int Foo::bar = 1; int Foo::spam = 2; @@ -305,3 +319,11 @@ struct CDA { }; %} +%{ +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +%} diff --git a/Examples/test-suite/director_exception.i b/Examples/test-suite/director_exception.i index abe23b381..1ce14dedf 100644 --- a/Examples/test-suite/director_exception.i +++ b/Examples/test-suite/director_exception.i @@ -7,6 +7,10 @@ #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif #include @@ -31,9 +35,9 @@ class DirectorMethodException: public Swig::DirectorException {}; #ifdef SWIGPHP %feature("director:except") { - if ($error == FAILURE) { - throw Swig::DirectorMethodException(); - } + if ($error == FAILURE) { + Swig::DirectorMethodException::raise("$symname"); + } } %exception { @@ -46,9 +50,9 @@ class DirectorMethodException: public Swig::DirectorException {}; #ifdef SWIGPYTHON %feature("director:except") { - if ($error != NULL) { - throw Swig::DirectorMethodException(); - } + if ($error != NULL) { + Swig::DirectorMethodException::raise("$symname"); + } } %exception { @@ -84,7 +88,7 @@ class DirectorMethodException: public Swig::DirectorException {}; #ifdef SWIGRUBY %feature("director:except") { - throw Swig::DirectorMethodException($error); + Swig::DirectorMethodException::raise($error); } %exception { diff --git a/Examples/test-suite/director_extend.i b/Examples/test-suite/director_extend.i index cec930a42..60a9d4cf0 100644 --- a/Examples/test-suite/director_extend.i +++ b/Examples/test-suite/director_extend.i @@ -25,7 +25,7 @@ namespace Swig { size_t ExceptionMethod() { // Check positioning of director code in wrapper file -// Below is what we really want to test, but director exceptions vary too much across across all languages +// Below is what we really want to test, but director exceptions vary too much across all languages // throw Swig::DirectorException("DirectorException was not in scope!!"); // Instead check definition of Director class as that is defined in the same place as DirectorException (director.swg) size_t size = sizeof(Swig::Director); diff --git a/Examples/test-suite/director_smartptr.i b/Examples/test-suite/director_smartptr.i index 9d0be80f0..d016af17e 100644 --- a/Examples/test-suite/director_smartptr.i +++ b/Examples/test-suite/director_smartptr.i @@ -44,7 +44,6 @@ public: %include %shared_ptr(Foo) - %feature("director") Foo; class FooBar { @@ -72,5 +71,12 @@ public: static Foo* get_self(Foo *self_); }; +%shared_ptr(FooDerived) +%feature("director") FooDerived; + +%inline %{ +struct FooDerived : Foo { +}; +%} #endif diff --git a/Examples/test-suite/director_thread.i b/Examples/test-suite/director_thread.i index 2732eb907..260bce774 100644 --- a/Examples/test-suite/director_thread.i +++ b/Examples/test-suite/director_thread.i @@ -11,25 +11,36 @@ #ifdef _WIN32 #include #include +#include #else #include #include #include #endif -#include +#include +#include "swig_examples_lock.h" class Foo; extern "C" { #ifdef _WIN32 - unsigned int __stdcall working(void* t); - unsigned int thread_id(0); + static unsigned int __stdcall working(void* t); + static HANDLE thread_handle = 0; #else void* working(void* t); - pthread_t thread; + static pthread_t thread; #endif + static int thread_terminate = 0; - + static SwigExamples::CriticalSection critical_section; + int get_thread_terminate() { + SwigExamples::Lock lock(critical_section); + return thread_terminate; + } + void set_thread_terminate(int value) { + SwigExamples::Lock lock(critical_section); + thread_terminate = value; + } } %} @@ -55,9 +66,10 @@ extern "C" { } void stop() { - thread_terminate = 1; + set_thread_terminate(1); %#ifdef _WIN32 - /*TODO(bhy) what to do for win32? */ + WaitForSingleObject(thread_handle, INFINITE); + CloseHandle(thread_handle); %#else pthread_join(thread, NULL); %#endif @@ -65,9 +77,18 @@ extern "C" { void run() { %#ifdef _WIN32 - _beginthreadex(NULL,0,working,this,0,&thread_id); + unsigned int thread_id = 0; + thread_handle = (HANDLE)_beginthreadex(NULL,0,working,this,0,&thread_id); + if (thread_handle == 0) { + fprintf(stderr, "_beginthreadex failed in run()\n"); + assert(0); + } %#else - pthread_create(&thread,NULL,working,this); + int create = pthread_create(&thread,NULL,working,this); + if (create != 0) { + fprintf(stderr, "pthread_create failed in run()\n"); + assert(0); + } %#endif MilliSecondSleep(500); } @@ -87,15 +108,10 @@ extern "C" { #endif { Foo* f = static_cast(t); - while ( ! thread_terminate ) { + while (!get_thread_terminate()) { MilliSecondSleep(50); f->do_foo(); } -#ifdef _WIN32 - /* TODO(bhy) what's the corresponding of pthread_exit in win32? */ -#else - pthread_exit(0); -#endif return 0; } } diff --git a/Examples/test-suite/errors/cpp_bad_global_memberptr.i b/Examples/test-suite/errors/cpp_bad_global_memberptr.i new file mode 100644 index 000000000..f0d95cfed --- /dev/null +++ b/Examples/test-suite/errors/cpp_bad_global_memberptr.i @@ -0,0 +1,6 @@ +%module xxx + +struct Funcs {}; + +short (Funcs::* *)(bool) = 0; +short (Funcs::* const*)(bool) = 0; diff --git a/Examples/test-suite/errors/cpp_bad_global_memberptr.stderr b/Examples/test-suite/errors/cpp_bad_global_memberptr.stderr new file mode 100644 index 000000000..ac3f9cbe0 --- /dev/null +++ b/Examples/test-suite/errors/cpp_bad_global_memberptr.stderr @@ -0,0 +1,2 @@ +cpp_bad_global_memberptr.i:5: Error: Missing symbol name for global declaration +cpp_bad_global_memberptr.i:6: Error: Missing symbol name for global declaration diff --git a/Examples/test-suite/errors/cpp_class_definition.i b/Examples/test-suite/errors/cpp_class_definition.i new file mode 100644 index 000000000..8381e75cc --- /dev/null +++ b/Examples/test-suite/errors/cpp_class_definition.i @@ -0,0 +1,26 @@ +%module xxx + +// This should error but doesn't +#if 0 +namespace OtherSpace { + struct L; +} +namespace Space11 { + namespace SubSpace11 { + using OtherSpace::L; + struct L { + void ll(); + }; + } +} +#endif + +namespace Space1 { + struct A; +} +namespace Space2 { + struct Space1::A { + void x(); + }; +} + diff --git a/Examples/test-suite/errors/cpp_class_definition.stderr b/Examples/test-suite/errors/cpp_class_definition.stderr new file mode 100644 index 000000000..2c4102842 --- /dev/null +++ b/Examples/test-suite/errors/cpp_class_definition.stderr @@ -0,0 +1 @@ +cpp_class_definition.i:22: Error: 'Space1::A' resolves to 'Space1::A' and was incorrectly instantiated in scope 'Space2' instead of within scope 'Space1'. diff --git a/Examples/test-suite/errors/cpp_invalid_qualifiers.i b/Examples/test-suite/errors/cpp_invalid_qualifiers.i new file mode 100644 index 000000000..fd3b36332 --- /dev/null +++ b/Examples/test-suite/errors/cpp_invalid_qualifiers.i @@ -0,0 +1,43 @@ +%module cpp_invalid_qualifiers + +// Constructors, destructors and static methods cannot have qualifiers +struct A { + ~A() const; +}; +struct B { + virtual ~B() const; +}; +struct C { + ~C() &; +}; +struct D { + virtual ~D() &; +}; +struct E { + ~E() &&; +}; +struct F { + virtual ~F() &&; +}; + +struct J { + J() const; + J(int) const; +}; +struct K { + K() &; + K(int) &; +}; +struct L { + L() &&; + L(int) &&; +}; + +struct M { + static void m1() const; + static void m2() &; + thread_local static void m3() &&; + static auto m4() const -> int; + static auto m5() & -> int; + static auto m6() && -> int; +}; diff --git a/Examples/test-suite/errors/cpp_invalid_qualifiers.stderr b/Examples/test-suite/errors/cpp_invalid_qualifiers.stderr new file mode 100644 index 000000000..7b3e442eb --- /dev/null +++ b/Examples/test-suite/errors/cpp_invalid_qualifiers.stderr @@ -0,0 +1,20 @@ +cpp_invalid_qualifiers.i:5: Error: Destructor ~A() const cannot have a qualifier. +cpp_invalid_qualifiers.i:8: Error: Destructor ~B() const cannot have a qualifier. +cpp_invalid_qualifiers.i:11: Error: Destructor ~C() & cannot have a qualifier. +cpp_invalid_qualifiers.i:14: Error: Destructor ~D() & cannot have a qualifier. +cpp_invalid_qualifiers.i:17: Error: Destructor ~E() && cannot have a qualifier. +cpp_invalid_qualifiers.i:20: Error: Destructor ~F() && cannot have a qualifier. +cpp_invalid_qualifiers.i:24: Error: Constructor cannot have a qualifier. +cpp_invalid_qualifiers.i:25: Error: Constructor cannot have a qualifier. +cpp_invalid_qualifiers.i:28: Error: Constructor cannot have a qualifier. +cpp_invalid_qualifiers.i:29: Error: Constructor cannot have a qualifier. +cpp_invalid_qualifiers.i:32: Error: Constructor cannot have a qualifier. +cpp_invalid_qualifiers.i:33: Error: Constructor cannot have a qualifier. +cpp_invalid_qualifiers.i:37: Error: Static function m1() const cannot have a qualifier. +cpp_invalid_qualifiers.i:38: Error: Static function m2() & cannot have a qualifier. +cpp_invalid_qualifiers.i:39: Error: Static function m3() && cannot have a qualifier. +cpp_invalid_qualifiers.i:39: Warning 405: Method with rvalue ref-qualifier m3() && ignored. +cpp_invalid_qualifiers.i:40: Error: Static function m4() const cannot have a qualifier. +cpp_invalid_qualifiers.i:41: Error: Static function m5() & cannot have a qualifier. +cpp_invalid_qualifiers.i:42: Error: Static function m6() && cannot have a qualifier. +cpp_invalid_qualifiers.i:42: Warning 405: Method with rvalue ref-qualifier m6() && ignored. diff --git a/Examples/test-suite/errors/cpp_invalid_template.i b/Examples/test-suite/errors/cpp_invalid_template.i new file mode 100644 index 000000000..ea0d7beac --- /dev/null +++ b/Examples/test-suite/errors/cpp_invalid_template.i @@ -0,0 +1,9 @@ +%module cpp_invalid_scope + +%template(abc) SSS::AAA; + +namespace UUU { + struct JJJ; +} + +%template(xxx) UUU::JJJ; diff --git a/Examples/test-suite/errors/cpp_invalid_template.stderr b/Examples/test-suite/errors/cpp_invalid_template.stderr new file mode 100644 index 000000000..f6bfaaf7d --- /dev/null +++ b/Examples/test-suite/errors/cpp_invalid_template.stderr @@ -0,0 +1,3 @@ +cpp_invalid_template.i:3: Error: Undefined scope 'SSS' +cpp_invalid_template.i:3: Error: Template 'SSS::AAA' undefined. +cpp_invalid_template.i:9: Error: 'JJJ' is not defined as a template. (classforward) diff --git a/Examples/test-suite/errors/cpp_namespace_template_bad.i b/Examples/test-suite/errors/cpp_namespace_template_bad.i new file mode 100644 index 000000000..5c42d6dcb --- /dev/null +++ b/Examples/test-suite/errors/cpp_namespace_template_bad.i @@ -0,0 +1,40 @@ +%module namespace_template + +namespace test { + template T max(T a, T b) { return (a > b) ? a : b; } + template class vector { + public: + vector() { } + ~vector() { } + }; +} + +namespace test2 { + using namespace test; + %template(maxshort) max; + %template(vectorshort) vector; +} + +namespace test3 { + using test::max; + using test::vector; + %template(maxlong) max; + %template(vectorlong) vector; +} + +namespace test4 { + using namespace test; + typedef int Integer; +} + +namespace test4 { + %template(maxInteger) max; + %template(vectorInteger) vector; +} + +using namespace test; +namespace test5 { + %template(maxdouble) max; + %template(vectordouble) vector; +} + diff --git a/Examples/test-suite/errors/cpp_namespace_template_bad.stderr b/Examples/test-suite/errors/cpp_namespace_template_bad.stderr new file mode 100644 index 000000000..5965d529c --- /dev/null +++ b/Examples/test-suite/errors/cpp_namespace_template_bad.stderr @@ -0,0 +1,9 @@ +cpp_namespace_template_bad.i:14: Error: 'max' resolves to 'test::max' and was incorrectly instantiated in scope 'test2' instead of within scope 'test'. +cpp_namespace_template_bad.i:15: Error: 'vector' resolves to 'test::vector' and was incorrectly instantiated in scope 'test2' instead of within scope 'test'. +cpp_namespace_template_bad.i:21: Error: 'max' resolves to 'test::max' and was incorrectly instantiated in scope 'test3' instead of within scope 'test'. +cpp_namespace_template_bad.i:22: Error: 'vector' resolves to 'test::vector' and was incorrectly instantiated in scope 'test3' instead of within scope 'test'. +cpp_namespace_template_bad.i:31: Error: 'max' resolves to 'test::max' and was incorrectly instantiated in scope 'test4' instead of within scope 'test'. +cpp_namespace_template_bad.i:32: Error: 'vector' resolves to 'test::vector' and was incorrectly instantiated in scope 'test4' instead of within scope 'test'. +cpp_namespace_template_bad.i:37: Error: 'max' resolves to 'test::max' and was incorrectly instantiated in scope 'test5' instead of within scope 'test'. +cpp_namespace_template_bad.i:37: Error: Template 'max' undefined. +cpp_namespace_template_bad.i:38: Error: 'vector' resolves to 'test::vector' and was incorrectly instantiated in scope 'test5' instead of within scope 'test'. diff --git a/Examples/test-suite/errors/cpp_nested_template.stderr b/Examples/test-suite/errors/cpp_nested_template.stderr index 9e46cff74..363a260f6 100644 --- a/Examples/test-suite/errors/cpp_nested_template.stderr +++ b/Examples/test-suite/errors/cpp_nested_template.stderr @@ -1,2 +1,4 @@ +cpp_nested_template.i:9: Error: 'Temply' resolves to '::Temply' and was incorrectly instantiated in scope 'A' instead of within scope ''. cpp_nested_template.i:9: Warning 324: Named nested template instantiations not supported. Processing as if no name was given to %template(). +cpp_nested_template.i:18: Error: 'Temply' resolves to '::Temply' and was incorrectly instantiated in scope 'B' instead of within scope ''. cpp_nested_template.i:18: Warning 324: Named nested template instantiations not supported. Processing as if no name was given to %template(). diff --git a/Examples/test-suite/errors/cpp_raw_string_termination.i b/Examples/test-suite/errors/cpp_raw_string_termination.i new file mode 100644 index 000000000..3858b1f1e --- /dev/null +++ b/Examples/test-suite/errors/cpp_raw_string_termination.i @@ -0,0 +1,4 @@ +%module xxx + +%feature("docstring") func2 R"ABC(Calculate :math:`D^\nu \rho(x)`.)AB"; +void func2(double* foo, int bar, char** baz); diff --git a/Examples/test-suite/errors/cpp_raw_string_termination.stderr b/Examples/test-suite/errors/cpp_raw_string_termination.stderr new file mode 100644 index 000000000..37dd512e0 --- /dev/null +++ b/Examples/test-suite/errors/cpp_raw_string_termination.stderr @@ -0,0 +1,2 @@ +cpp_raw_string_termination.i:3: Error: Unterminated raw string, started with R"ABC( is not terminated by )ABC" +cpp_raw_string_termination.i:3: Error: Syntax error in input(1). diff --git a/Examples/test-suite/errors/cpp_refqualifier.i b/Examples/test-suite/errors/cpp_refqualifier.i new file mode 100644 index 000000000..afd6632fc --- /dev/null +++ b/Examples/test-suite/errors/cpp_refqualifier.i @@ -0,0 +1,28 @@ +%module cpp_refqualifier + +%ignore Host::h_ignored; +%ignore Host::i_ignored() &&; +%ignore Host::j_ignored() const &&; + +class Host { +public: + void h1() &; + void h2() const &; + void h3() &&; + void h4() const &&; + + void h() &; + void h() const &; + void h() &&; + void h() const &&; + + void h_ignored() &&; + void i_ignored() &&; + void i_ignored() &&; +}; + +%feature("ignore", "0") Unignore::k_unignored() const &&; + +struct Unignore { + void k_unignored() const &&; +}; diff --git a/Examples/test-suite/errors/cpp_refqualifier.stderr b/Examples/test-suite/errors/cpp_refqualifier.stderr new file mode 100644 index 000000000..ea2cd220a --- /dev/null +++ b/Examples/test-suite/errors/cpp_refqualifier.stderr @@ -0,0 +1,6 @@ +cpp_refqualifier.i:11: Warning 405: Method with rvalue ref-qualifier h3() && ignored. +cpp_refqualifier.i:12: Warning 405: Method with rvalue ref-qualifier h4() const && ignored. +cpp_refqualifier.i:16: Warning 405: Method with rvalue ref-qualifier h() && ignored. +cpp_refqualifier.i:17: Warning 405: Method with rvalue ref-qualifier h() const && ignored. +cpp_refqualifier.i:15: Warning 512: Overloaded method Host::h() const & ignored, +cpp_refqualifier.i:14: Warning 512: using non-const method Host::h() & instead. diff --git a/Examples/test-suite/errors/cpp_template_scope.i b/Examples/test-suite/errors/cpp_template_scope.i new file mode 100644 index 000000000..ec0f0a577 --- /dev/null +++ b/Examples/test-suite/errors/cpp_template_scope.i @@ -0,0 +1,57 @@ +%module xxx + +namespace std { + template class vector {}; +} + +struct S1 {}; +struct S2 {}; +struct S3 {}; +struct S4 {}; +struct S5 {}; +struct S6 {}; +struct S7 {}; + +// valid +namespace std { + %template(vi1) vector; + template class vector; +} + +// valid +using namespace std; +%template(vi2) vector; +template class vector; + +// valid +using std::vector; +%template(vi3) vector; +template class vector; + +// ill-formed +namespace unrelated { + using std::vector; + %template(vi4) vector; + template class vector; +} + +// ill-formed +namespace unrelated { + using namespace std; + %template(vi5) vector; + template class vector; +} + +// ill-formed +namespace unrelated { + namespace std { + %template(vi6) vector; + template class vector; + } +} + +// ill-formed +namespace unrelated { + %template(vi7) std::vector; + template class std::vector; +} diff --git a/Examples/test-suite/errors/cpp_template_scope.stderr b/Examples/test-suite/errors/cpp_template_scope.stderr new file mode 100644 index 000000000..e47630268 --- /dev/null +++ b/Examples/test-suite/errors/cpp_template_scope.stderr @@ -0,0 +1,11 @@ +cpp_template_scope.i:18: Warning 320: Explicit template instantiation ignored. +cpp_template_scope.i:24: Warning 320: Explicit template instantiation ignored. +cpp_template_scope.i:29: Warning 320: Explicit template instantiation ignored. +cpp_template_scope.i:34: Error: 'vector' resolves to 'std::vector' and was incorrectly instantiated in scope 'unrelated' instead of within scope 'std'. +cpp_template_scope.i:35: Warning 320: Explicit template instantiation ignored. +cpp_template_scope.i:41: Error: 'vector' resolves to 'std::vector' and was incorrectly instantiated in scope 'unrelated' instead of within scope 'std'. +cpp_template_scope.i:42: Warning 320: Explicit template instantiation ignored. +cpp_template_scope.i:48: Error: 'vector' resolves to 'std::vector' and was incorrectly instantiated in scope 'unrelated::std' instead of within scope 'std'. +cpp_template_scope.i:49: Warning 320: Explicit template instantiation ignored. +cpp_template_scope.i:55: Error: 'std::vector' resolves to 'std::vector' and was incorrectly instantiated in scope 'unrelated' instead of within scope 'std'. +cpp_template_scope.i:56: Warning 320: Explicit template instantiation ignored. diff --git a/Examples/test-suite/exception_order.i b/Examples/test-suite/exception_order.i index 02674fef9..194394332 100644 --- a/Examples/test-suite/exception_order.i +++ b/Examples/test-suite/exception_order.i @@ -16,6 +16,10 @@ #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif %} /* @@ -146,3 +150,12 @@ bool is_python_builtin() { return false; } %template(ET_i) ET; %template(ET_d) ET; + +%{ +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +%} diff --git a/Examples/test-suite/extern_throws.i b/Examples/test-suite/extern_throws.i index eab26244e..81eeb64c2 100644 --- a/Examples/test-suite/extern_throws.i +++ b/Examples/test-suite/extern_throws.i @@ -4,6 +4,10 @@ #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif %} %inline %{ @@ -16,3 +20,11 @@ extern int get() throw(std::exception); int get() throw(std::exception) { return 0; } %} +%{ +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +%} diff --git a/Examples/test-suite/funcptr_cpp.i b/Examples/test-suite/funcptr_cpp.i index b63749dc1..8e05d308d 100644 --- a/Examples/test-suite/funcptr_cpp.i +++ b/Examples/test-suite/funcptr_cpp.i @@ -15,6 +15,8 @@ int & addByReference(const int &a, int b) { static int val; val = a+b; return va int call1(int (*d)(const int &, int), int a, int b) { return d(a, b); } int call2(int * (*d)(const int &, int), int a, int b) { return *d(a, b); } int call3(int & (*d)(const int &, int), int a, int b) { return d(a, b); } +int call4(int & (*d)(int &, int *), int a, int b) { return d(a, &b); } +int call5(int & (*d)(int &, int const * const), int a, int b) { return d(a, &b); } %} %constant int (*ADD_BY_VALUE)(const int &, int) = addByValue; diff --git a/Examples/test-suite/go/Makefile.in b/Examples/test-suite/go/Makefile.in index 01989b0d3..b7be554d7 100644 --- a/Examples/test-suite/go/Makefile.in +++ b/Examples/test-suite/go/Makefile.in @@ -182,12 +182,3 @@ clean: rm -f import_stl_a.go import_stl_a.gox rm -f import_stl_b.go import_stl_b.gox rm -rf gopath - -cvsignore: - @echo '*_gc.c *_wrap.* *.so *.dll *.exp *.lib' - @echo Makefile - @echo mod_a.go mod_b.go imports_a.go imports_b.go - @echo clientdata_prop_a.go clientdata_prop_b.go - @echo multi_import_a.go multi_import_b.go - @echo packageoption_a.go packageoption_b.go packageoption_c.go - @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do echo $$i.go; done diff --git a/Examples/test-suite/go/typedef_funcptr_runme.go b/Examples/test-suite/go/typedef_funcptr_runme.go new file mode 100644 index 000000000..49d7086b1 --- /dev/null +++ b/Examples/test-suite/go/typedef_funcptr_runme.go @@ -0,0 +1,29 @@ +package main + +import . "./typedef_funcptr" + +func main() { + a := 100 + b := 10 + + if Do_op(a,b,Addf) != 110 { + panic(0) + } + if Do_op(a,b,Subf) != 90 { + panic(0) + } + + if Do_op_typedef_int(a,b,Addf) != 110 { + panic(0) + } + if Do_op_typedef_int(a,b,Subf) != 90 { + panic(0) + } + + if Do_op_typedef_Integer(a,b,Addf) != 110 { + panic(0) + } + if Do_op_typedef_Integer(a,b,Subf) != 90 { + panic(0) + } +} diff --git a/Examples/test-suite/ignore_template_constructor.i b/Examples/test-suite/ignore_template_constructor.i index 31a5505fb..bdffbec3e 100644 --- a/Examples/test-suite/ignore_template_constructor.i +++ b/Examples/test-suite/ignore_template_constructor.i @@ -1,12 +1,18 @@ %module ignore_template_constructor %include std_vector.i -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGPERL) || defined(SWIGRUBY) +#if defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGPERL) || defined(SWIGRUBY) #define SWIG_GOOD_VECTOR %ignore std::vector::vector(size_type); %ignore std::vector::resize(size_type); #endif +#if defined(SWIGJAVA) +#define SWIG_GOOD_VECTOR +%ignore std::vector::vector(jint); +%ignore std::vector::resize(jint); +#endif + #if defined(SWIGTCL) || defined(SWIGPERL) #define SWIG_GOOD_VECTOR /* here, for languages with bad declaration */ diff --git a/Examples/test-suite/import_fragments.i b/Examples/test-suite/import_fragments.i new file mode 100644 index 000000000..26b87cdb2 --- /dev/null +++ b/Examples/test-suite/import_fragments.i @@ -0,0 +1,18 @@ +%module import_fragments + +// Check %fragments forced inclusion does not result in code generation when using %import +%import "import_fragments_a.i" + +%{ +template +struct TemplateA4 {}; +%} + +%template(TemplateA4Int) TemplateA4; + +%inline %{ +int getImport4() { + // Requires the ImportA4 fragment to be generated in order to compile + return ImportA4; +} +%} diff --git a/Examples/test-suite/import_fragments_a.i b/Examples/test-suite/import_fragments_a.i new file mode 100644 index 000000000..1babea95f --- /dev/null +++ b/Examples/test-suite/import_fragments_a.i @@ -0,0 +1,48 @@ +#if !defined(SWIGGO) +// Prevent Go from generating a Go module import - this test is not set up as true multiple modules +%module import_fragments_a +#endif + +%fragment("ImportA1", "header") %{ +ImportA1_this_will_not_compile; +%} +%fragment("ImportA2", "header") %{ +ImportA2_this_will_not_compile; +%} +%fragment("ImportA3", "header") %{ +ImportA3_this_will_not_compile; +%} +%fragment("ImportA4", "header") %{ +static int ImportA4 = 99; +%} +%fragment("ImportA5", "header") %{ +ImportA5_this_will_not_compile; +%} + +%fragment("ImportA1"); + +%{ +Import_will_not_compile; +%} + +struct StructA { + %fragment("ImportA2"); +}; + +template +struct TemplateA3 { + %fragment("ImportA3"); +}; + +template +struct TemplateA4 { + %fragment("ImportA4"); +}; + +template +struct TemplateA5 { + %fragment("ImportA5"); +}; +%template(TemplateA5Double) TemplateA5; + +%include "import_fragments_b.i" diff --git a/Examples/test-suite/import_fragments_b.i b/Examples/test-suite/import_fragments_b.i new file mode 100644 index 000000000..615db4796 --- /dev/null +++ b/Examples/test-suite/import_fragments_b.i @@ -0,0 +1,9 @@ +%module import_fragments_b + +%fragment("ImportB", "header") %{ +ImportB_this_will_not_compile; +%} + +%fragment("ImportB"); + + diff --git a/Examples/test-suite/java/Makefile.in b/Examples/test-suite/java/Makefile.in index f8dc48a4a..e6ed3c225 100644 --- a/Examples/test-suite/java/Makefile.in +++ b/Examples/test-suite/java/Makefile.in @@ -43,6 +43,7 @@ CPP_TEST_CASES = \ java_throws \ java_typemaps_proxy \ java_typemaps_typewrapper \ + li_std_list \ # li_boost_intrusive_ptr CPP11_TEST_CASES = \ diff --git a/Examples/test-suite/java/class_scope_namespace_runme.java b/Examples/test-suite/java/class_scope_namespace_runme.java new file mode 100644 index 000000000..9d74a6ca6 --- /dev/null +++ b/Examples/test-suite/java/class_scope_namespace_runme.java @@ -0,0 +1,59 @@ + +import class_scope_namespace.*; + +public class class_scope_namespace_runme { + + static { + try { + System.loadLibrary("class_scope_namespace"); + } 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[]) + { + A a = new A(); + B b = new B(); + C c = new C(); + D d = new D(); + E e = new E(); + F f = new F(); + G g = new G(); + H.HH h = new H.HH(); + I.II i = new I.II(); + J j = new J(); + K k = new K(); + L l = new L(); + M m = new M(); + + a.aa(a, a, a); + b.bb(b, b); + c.cc(c, c); + d.dd(d, d, d); + e.ee(e, e, e); + f.ff(f, f, f, f); + g.gg(g, g); + h.hh(h); + i.ii(i, i); + j.jj(j, j, j); + k.kk(k, k, k); + l.ll(l, l, l); + m.mm(m, m, m); + + class_scope_namespace.aaa(a, a, a); + class_scope_namespace.bbb(b, b); + class_scope_namespace.ccc(c, c); + class_scope_namespace.ddd(d, d, d); + class_scope_namespace.eee(e, e, e); + class_scope_namespace.fff(f, f, f, f); + class_scope_namespace.ggg(g, g); + class_scope_namespace.hhh(h); + class_scope_namespace.iii(i, i); + class_scope_namespace.jjj(j, j, j); + class_scope_namespace.kkk(k, k, k); + class_scope_namespace.lll(l, l, l); + class_scope_namespace.mmm(m, m, m); + } +} diff --git a/Examples/test-suite/java/cpp11_ref_qualifiers_runme.java b/Examples/test-suite/java/cpp11_ref_qualifiers_runme.java new file mode 100644 index 000000000..4755f8d1f --- /dev/null +++ b/Examples/test-suite/java/cpp11_ref_qualifiers_runme.java @@ -0,0 +1,56 @@ + +import cpp11_ref_qualifiers.*; + +public class cpp11_ref_qualifiers_runme { + + static { + try { + System.loadLibrary("cpp11_ref_qualifiers"); + } 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[]) { + Host h = new Host(); + + // Basic testing + h.h1(); + h.h2(); + h.h6(); + h.h7(); + + h.h(); + + // %feature testing + Features f = new Features(); + if (!f.F1().equals("F1")) throw new RuntimeException("Fail"); + if (!f.F2().equals("F2")) throw new RuntimeException("Fail"); + if (!f.F3().equals("F3")) throw new RuntimeException("Fail"); + + if (!f.C1(0).equals("C1")) throw new RuntimeException("Fail"); + if (!f.C2(0).equals("C2")) throw new RuntimeException("Fail"); + if (!f.C3(0).equals("C3")) throw new RuntimeException("Fail"); + + // %rename testing + Renames r = new Renames(); + r.RR1(); + r.RR2(); + r.RR3(); + + r.SS1(0); + r.SS2(0); + r.SS3(0); + + // Conversion operators + String s = null; + ConversionOperators co = new ConversionOperators(); + s = co.StringConvertCopy(); + s = co.StringConvertMove(); + + ConversionOperators2 co2 = new ConversionOperators2(); + s = co2.StringConvertMove(); + } +} + diff --git a/Examples/test-suite/java/cpp11_ref_qualifiers_rvalue_unignore_runme.java b/Examples/test-suite/java/cpp11_ref_qualifiers_rvalue_unignore_runme.java new file mode 100644 index 000000000..bbbe6f788 --- /dev/null +++ b/Examples/test-suite/java/cpp11_ref_qualifiers_rvalue_unignore_runme.java @@ -0,0 +1,20 @@ + +import cpp11_ref_qualifiers_rvalue_unignore.*; + +public class cpp11_ref_qualifiers_rvalue_unignore_runme { + + static { + try { + System.loadLibrary("cpp11_ref_qualifiers_rvalue_unignore"); + } 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[]) { + new RefQualifier().m1(); + new RefQualifier().m2(); + } +} + diff --git a/Examples/test-suite/java/cpp11_ref_qualifiers_typemaps_runme.java b/Examples/test-suite/java/cpp11_ref_qualifiers_typemaps_runme.java new file mode 100644 index 000000000..8c6a21b15 --- /dev/null +++ b/Examples/test-suite/java/cpp11_ref_qualifiers_typemaps_runme.java @@ -0,0 +1,39 @@ +import cpp11_ref_qualifiers_typemaps.*; + +public class cpp11_ref_qualifiers_typemaps_runme { + static { + try { + System.loadLibrary("cpp11_ref_qualifiers_typemaps"); + } 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[]) + { + { + TypemapsNamedParms tm = new TypemapsNamedParms(); + if (tm.fff(cpp11_ref_qualifiers_typemaps.FF1_MFP) != 2) + throw new RuntimeException("failed"); + if (tm.ccc(cpp11_ref_qualifiers_typemaps.CC4_MFP) != 5) + throw new RuntimeException("failed"); + if (tm.ggg(cpp11_ref_qualifiers_typemaps.GG7_MFP) != 8) + throw new RuntimeException("failed"); + if (tm.hhh(cpp11_ref_qualifiers_typemaps.HH10_MFP) != 11) + throw new RuntimeException("failed"); + } + { + TypemapsUnnamedParms tm = new TypemapsUnnamedParms(); + if (tm.fff(cpp11_ref_qualifiers_typemaps.FF1_MFP) != 3) + throw new RuntimeException("failed"); + if (tm.ccc(cpp11_ref_qualifiers_typemaps.CC4_MFP) != 6) + throw new RuntimeException("failed"); + if (tm.ggg(cpp11_ref_qualifiers_typemaps.GG7_MFP) != 9) + throw new RuntimeException("failed"); + if (tm.hhh(cpp11_ref_qualifiers_typemaps.HH10_MFP) != 12) + throw new RuntimeException("failed"); + } + } +} + diff --git a/Examples/test-suite/java/cpp11_template_typedefs_runme.java b/Examples/test-suite/java/cpp11_template_typedefs_runme.java new file mode 100644 index 000000000..473e7cf07 --- /dev/null +++ b/Examples/test-suite/java/cpp11_template_typedefs_runme.java @@ -0,0 +1,19 @@ +import cpp11_template_typedefs.*; + +public class cpp11_template_typedefs_runme { + + static { + try { + System.loadLibrary("cpp11_template_typedefs"); + } 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[]) { + int alloc1 = cpp11_template_typedefs.get_bucket_allocator1(); + int alloc2 = cpp11_template_typedefs.get_bucket_allocator2(); + } +} + diff --git a/Examples/test-suite/java/director_smartptr_runme.java b/Examples/test-suite/java/director_smartptr_runme.java index 710ece710..53d68f995 100644 --- a/Examples/test-suite/java/director_smartptr_runme.java +++ b/Examples/test-suite/java/director_smartptr_runme.java @@ -33,6 +33,19 @@ public class director_smartptr_runme { director_smartptr.Foo myFoo2 = new director_smartptr.Foo().makeFoo(); check(myFoo2.pong(), "Foo::pong();Foo::ping()"); check(director_smartptr.Foo.callPong(myFoo2), "Foo::pong();Foo::ping()"); + + director_smartptr.FooDerived myBarFooDerived = new director_smartptr_MyBarFooDerived(); + check(myBarFooDerived.ping(), "director_smartptr_MyBarFooDerived.ping()"); + check(director_smartptr.FooDerived.callPong(myBarFooDerived), "director_smartptr_MyBarFooDerived.pong();director_smartptr_MyBarFooDerived.ping()"); + check(director_smartptr.FooDerived.callUpcall(myBarFooDerived, fooBar), "overrideDerived;Bar::Foo2::Foo2Bar()"); + + director_smartptr.Foo myFoo3 = myBarFoo.makeFoo(); + myFoo3.swigReleaseOwnership(); + myFoo3.swigTakeOwnership(); + director_smartptr.FooDerived myBarFooDerived2 = new director_smartptr_MyBarFooDerived(); + myBarFooDerived2.swigReleaseOwnership(); + myBarFooDerived2.swigTakeOwnership(); + } } @@ -58,3 +71,26 @@ class director_smartptr_MyBarFoo extends director_smartptr.Foo { return new director_smartptr.Foo(); } } + +class director_smartptr_MyBarFooDerived extends director_smartptr.FooDerived { + + @Override + public String ping() { + return "director_smartptr_MyBarFooDerived.ping()"; + } + + @Override + public String pong() { + return "director_smartptr_MyBarFooDerived.pong();" + ping(); + } + + @Override + public String upcall(director_smartptr.FooBar fooBarPtr) { + return "overrideDerived;" + fooBarPtr.FooBarDo(); + } + + @Override + public director_smartptr.Foo makeFoo() { + return new director_smartptr.Foo(); + } +} diff --git a/Examples/test-suite/java/java_director_assumeoverride_runme.java b/Examples/test-suite/java/java_director_assumeoverride_runme.java index e876a79c9..6c4d6918e 100644 --- a/Examples/test-suite/java/java_director_assumeoverride_runme.java +++ b/Examples/test-suite/java/java_director_assumeoverride_runme.java @@ -18,7 +18,7 @@ public class java_director_assumeoverride_runme { public static void main(String argv[]) { OverrideMe overrideMe = new MyOverrideMe(); - // MyOverrideMe doesn't actually override func(), but because assumeoverride + // MyOverrideMe doesn't actually override funk(), but because assumeoverride // was set to true, the C++ side will believe it was overridden. if (!java_director_assumeoverride.isFuncOverridden(overrideMe)) { throw new RuntimeException ( "isFuncOverridden()" ); diff --git a/Examples/test-suite/java/li_boost_shared_ptr_director_runme.java b/Examples/test-suite/java/li_boost_shared_ptr_director_runme.java new file mode 100644 index 000000000..904eab387 --- /dev/null +++ b/Examples/test-suite/java/li_boost_shared_ptr_director_runme.java @@ -0,0 +1,60 @@ +public class li_boost_shared_ptr_runme { + + static { + try { + System.loadLibrary("li_boost_shared_ptr"); + } 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); + } + } + + private static void check(String got, String expected) { + if (!got.equals(expected)) + throw new RuntimeException("Failed, got: " + got + " expected: " + expected); + } + + public static void main(String argv[]) { + li_boost_shared_ptr_director_Derived a = li_boost_shared_ptr_director_Derived.new(false); + li_boost_shared_ptr_director_Derived b = li_boost_shared_ptr_director_Derived.new(true); + + check(call_ret_c_shared_ptr(a) == 1); + check(call_ret_c_shared_ptr(b) == -1); + check(call_ret_c_by_value(a) == 1); + + check(call_take_c_by_value(a) == 5); + check(call_take_c_shared_ptr_by_value(a) == 6); + check(call_take_c_shared_ptr_by_ref(a) == 7); + check(call_take_c_shared_ptr_by_pointer(a) == 8); + check(call_take_c_shared_ptr_by_pointer_ref(a) == 9); + + check(call_take_c_shared_ptr_by_value_with_null(a) == -2); + check(call_take_c_shared_ptr_by_ref_with_null(a) == -3); + check(call_take_c_shared_ptr_by_pointer_with_null(a) == -4); + check(call_take_c_shared_ptr_by_pointer_ref_with_null(a) == -5); + + } +} + +class li_boost_shared_ptr_director_Derived extends li_boost_shared_ptr_director.Base { + + @Override + public String ping() { + return "li_boost_shared_ptr_director_MyBarFoo.ping()"; + } + + @Override + public String pong() { + return "li_boost_shared_ptr_director_MyBarFoo.pong();" + ping(); + } + + @Override + public String upcall(li_boost_shared_ptr_director.FooBar fooBarPtr) { + return "override;" + fooBarPtr.FooBarDo(); + } + + @Override + public li_boost_shared_ptr_director.Foo makeFoo() { + return new li_boost_shared_ptr_director.Foo(); + } +} diff --git a/Examples/test-suite/java/li_std_list_runme.java b/Examples/test-suite/java/li_std_list_runme.java new file mode 100644 index 000000000..e45b8968b --- /dev/null +++ b/Examples/test-suite/java/li_std_list_runme.java @@ -0,0 +1,180 @@ +import li_std_list.*; + +public class li_std_list_runme { + + static { + try { + System.loadLibrary("li_std_list"); + } 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[]) throws Throwable + { + IntList v1 = new IntList(); + DoubleList v2 = new DoubleList(); + + if (!v1.isEmpty()) throw new RuntimeException("v1 test (1) failed"); + if (v1.size() != 0) throw new RuntimeException("v1 test (2) failed"); + if (!v1.add(123)) throw new RuntimeException("v1 test (3) failed"); + if (v1.size() != 1) throw new RuntimeException("v1 test (4) failed"); + if (v1.isEmpty()) throw new RuntimeException("v1 test (5) failed"); + + int sum = 0; + for (int n : v1) { + if (n != 123) throw new RuntimeException("v1 loop test failed"); + sum += n; + } + if (sum != 123) throw new RuntimeException("v1 sum test failed"); + if (v1.get(0) != 123) throw new RuntimeException("v1 test failed"); + v1.clear(); + if (!v1.isEmpty()) throw new RuntimeException("v1 test clear failed"); + v1.add(123); + + if (v1.set(0, 456) != 123) throw new RuntimeException("v1 test (6) failed"); + if (v1.size() != 1) throw new RuntimeException("v1 test (7) failed"); + if (v1.get(0) != 456) throw new RuntimeException("v1 test (8) failed"); + + java.util.Iterator v1_iterator = v1.iterator(); + if (!v1_iterator.hasNext()) throw new RuntimeException("v1 test (9) failed"); + if (v1_iterator.next() != 456) throw new RuntimeException("v1 test (10) failed"); + if (v1_iterator.hasNext()) throw new RuntimeException("v1 test (11) failed"); + try { + v1_iterator.next(); + throw new RuntimeException("v1 test (12) failed"); + } catch (java.util.NoSuchElementException e) { + } + + if (v1.remove(new Integer(123))) throw new RuntimeException("v1 test (13) failed"); + if (!v1.remove(new Integer(456))) throw new RuntimeException("v1 test (14) failed"); + if (!v1.isEmpty()) throw new RuntimeException("v1 test (15) failed"); + if (v1.size() != 0) throw new RuntimeException("v1 test (16) failed"); + if (v1.remove(new Integer(456))) throw new RuntimeException("v1 test (17) failed"); + + if (new IntList(3).size() != 3) throw new RuntimeException("constructor initial size test failed"); + for (int n : new IntList(10, 999)) + if (n != 999) throw new RuntimeException("constructor initialization with value failed"); + for (int n : new IntList(new IntList(10, 999))) + if (n != 999) throw new RuntimeException("copy constructor initialization with value failed"); + + StructList v4 = new StructList(); + StructPtrList v5 = new StructPtrList(); + StructConstPtrList v6 = new StructConstPtrList(); + + v4.add(new Struct(12)); + v5.add(new Struct(34)); + v6.add(new Struct(56)); + + if (v4.get(0).getNum() != 12) throw new RuntimeException("v4 test failed"); + if (v5.get(0).getNum() != 34) throw new RuntimeException("v5 test failed"); + if (v6.get(0).getNum() != 56) throw new RuntimeException("v6 test failed"); + + for (Struct s : v4) { + if (s.getNum() != 12) throw new RuntimeException("v4 loop test failed"); + } + for (Struct s : v5) { + if (s.getNum() != 34) throw new RuntimeException("v5 loop test failed"); + } + for (Struct s : v6) { + if (s.getNum() != 56) throw new RuntimeException("v6 loop test failed"); + } + + StructList v7 = li_std_list.CopyContainerStruct(new StructList()); + v7.add(new Struct(1)); + v7.add(new Struct(23)); + v7.add(new Struct(456)); + v7.add(new Struct(7890)); + if (v7.size() != 4) throw new RuntimeException("v7 test (1) failed"); + { + double[] a7 = {1, 23, 456, 7890}; + int i7 = 0; + for (Struct s7 : v7) { + if (s7.getNum() != a7[i7]) throw new RuntimeException("v7 test (2) failed"); + i7++; + } + if (i7 != a7.length) throw new RuntimeException("v7 test (3) failed"); + } + if (v7.remove(2).getNum() != 456) throw new RuntimeException("v7 test (4) failed"); + { + double[] a7 = {1, 23, 7890}; + int i7 = 0; + for (Struct s7 : v7) { + if (s7.getNum() != a7[i7]) throw new RuntimeException("v7 test (5) failed"); + i7++; + } + if (i7 != a7.length) throw new RuntimeException("v7 test (6) failed"); + } + v7.add(1, new Struct(123)); + { + double[] a7 = {1, 123, 23, 7890}; + int i7 = 0; + for (Struct s7 : v7) { + if (s7.getNum() != a7[i7]) throw new RuntimeException("v7 test (7) failed"); + i7++; + } + if (i7 != a7.length) throw new RuntimeException("v7 test (8) failed"); + } + + BoolList v8 = new BoolList(); + if (!v8.add(true)) throw new RuntimeException("v8 test (1) failed");; + if (v8.get(0) != true) throw new RuntimeException("v8 test (2) failed");; + if (v8.set(0, false) != true) throw new RuntimeException("v8 test (3) failed");; + if (v8.set(0, false) != false) throw new RuntimeException("v8 test (4) failed");; + if (v8.size() != 1) throw new RuntimeException("v8 test (5) failed");; + + java.util.ArrayList bl = new java.util.ArrayList(java.util.Arrays.asList(true, false, true, false)); + BoolList bv = new BoolList(java.util.Arrays.asList(true, false, true, false)); + BoolList bv2 = new BoolList(bl); + java.util.ArrayList bl2 = new java.util.ArrayList(bv); + boolean bbb1 = bv.get(0); + Boolean bbb2 = bv.get(0); + + IntList v9 = new IntList(java.util.Arrays.asList(10, 20, 30, 40)); + v9.add(50); + v9.add(60); + v9.add(70); + if (v9.size() != 7) throw new RuntimeException("v9 test (1) failed"); + if (!v9.remove(new Integer(60))) throw new RuntimeException("v9 test (2) failed"); + if (v9.size() != 6) throw new RuntimeException("v9 test (3) failed"); + v9.addFirst(-10); + v9.addLast(80); + if (v9.size() != 8) throw new RuntimeException("v9 test (4) failed"); + if (v9.get(0) != -10) throw new RuntimeException("v9 test (5) failed");; + if (v9.get(v9.size()-1) != 80) throw new RuntimeException("v9 test (6) failed");; + v9.removeFirst(); + if (v9.get(0) != 10) throw new RuntimeException("v9 test (7) failed");; + v9.removeLast(); + if (v9.size() != 6) throw new RuntimeException("v9 test (8) failed"); + if (v9.get(v9.size()-1) != 70) throw new RuntimeException("v9 test (9) failed");; + + IntList v10 = new IntList(java.util.Arrays.asList(10, 20, 30, 40, 50)); + v10.subList(1, 4).clear(); // Recommended way to call protected method removeRange(1,3) + if (v10.size() != 2) throw new RuntimeException("v10 test (1) failed"); + if (v10.get(0) != 10) throw new RuntimeException("v10 test (2) failed"); + if (v10.get(1) != 50) throw new RuntimeException("v10 test (3) failed"); + v10.addAll(1, java.util.Arrays.asList(22, 33)); + if (v10.size() != 4) throw new RuntimeException("v10 test (4) failed"); + if (v10.get(1) != 22) throw new RuntimeException("v10 test (5) failed"); + if (v10.get(2) != 33) throw new RuntimeException("v10 test (6) failed"); + + v10.add(v10.size(), 55); + if (v10.size() != 5) throw new RuntimeException("v10 test (7) failed"); + if (v10.get(4) != 55) throw new RuntimeException("v10 test (8) failed"); + + IntList v11 = new IntList(java.util.Arrays.asList(11, 22, 33, 44)); + v11.listIterator(0); + v11.listIterator(v11.size()); + try { + v11.listIterator(v11.size() + 1); + throw new RuntimeException("v11 test (1) failed"); + } catch (IndexOutOfBoundsException e) { + } + try { + v11.listIterator(-1); + throw new RuntimeException("v11 test (2) failed"); + } catch (IndexOutOfBoundsException e) { + } + } +} diff --git a/Examples/test-suite/java/li_std_vector_runme.java b/Examples/test-suite/java/li_std_vector_runme.java index b422655a4..d23bbe7cd 100644 --- a/Examples/test-suite/java/li_std_vector_runme.java +++ b/Examples/test-suite/java/li_std_vector_runme.java @@ -4,7 +4,7 @@ public class li_std_vector_runme { static { try { - System.loadLibrary("li_std_vector"); + System.loadLibrary("li_std_vector"); } 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); @@ -17,8 +17,48 @@ public class li_std_vector_runme { IntPtrVector v2 = li_std_vector.vecintptr(new IntPtrVector()); IntConstPtrVector v3 = li_std_vector.vecintconstptr(new IntConstPtrVector()); - v1.add(123); + if (!v1.isEmpty()) throw new RuntimeException("v1 test (1) failed"); + if (v1.size() != 0) throw new RuntimeException("v1 test (2) failed"); + if (!v1.add(123)) throw new RuntimeException("v1 test (3) failed"); + if (v1.size() != 1) throw new RuntimeException("v1 test (4) failed"); + if (v1.isEmpty()) throw new RuntimeException("v1 test (5) failed"); + + int sum = 0; + for (int n : v1) { + if (n != 123) throw new RuntimeException("v1 loop test failed"); + sum += n; + } + if (sum != 123) throw new RuntimeException("v1 sum test failed"); if (v1.get(0) != 123) throw new RuntimeException("v1 test failed"); + v1.clear(); + if (!v1.isEmpty()) throw new RuntimeException("v1 test clear failed"); + v1.add(123); + + if (v1.set(0, 456) != 123) throw new RuntimeException("v1 test (6) failed"); + if (v1.size() != 1) throw new RuntimeException("v1 test (7) failed"); + if (v1.get(0) != 456) throw new RuntimeException("v1 test (8) failed"); + + java.util.Iterator v1_iterator = v1.iterator(); + if (!v1_iterator.hasNext()) throw new RuntimeException("v1 test (9) failed"); + if (v1_iterator.next() != 456) throw new RuntimeException("v1 test (10) failed"); + if (v1_iterator.hasNext()) throw new RuntimeException("v1 test (11) failed"); + try { + v1_iterator.next(); + throw new RuntimeException("v1 test (12) failed"); + } catch (java.util.NoSuchElementException e) { + } + + if (v1.remove(new Integer(123))) throw new RuntimeException("v1 test (13) failed"); + if (!v1.remove(new Integer(456))) throw new RuntimeException("v1 test (14) failed"); + if (!v1.isEmpty()) throw new RuntimeException("v1 test (15) failed"); + if (v1.size() != 0) throw new RuntimeException("v1 test (16) failed"); + if (v1.remove(new Integer(456))) throw new RuntimeException("v1 test (17) failed"); + + if (new IntVector(3).size() != 3) throw new RuntimeException("constructor initial size test failed"); + for (int n : new IntVector(10, 999)) + if (n != 999) throw new RuntimeException("constructor initialization with value failed"); + for (int n : new IntVector(new IntVector(10, 999))) + if (n != 999) throw new RuntimeException("copy constructor initialization with value failed"); StructVector v4 = li_std_vector.vecstruct(new StructVector()); StructPtrVector v5 = li_std_vector.vecstructptr(new StructPtrVector()); @@ -28,9 +68,104 @@ public class li_std_vector_runme { v5.add(new Struct(34)); v6.add(new Struct(56)); - Struct s = null; if (v4.get(0).getNum() != 12) throw new RuntimeException("v4 test failed"); if (v5.get(0).getNum() != 34) throw new RuntimeException("v5 test failed"); if (v6.get(0).getNum() != 56) throw new RuntimeException("v6 test failed"); + + for (Struct s : v4) { + if (s.getNum() != 12) throw new RuntimeException("v4 loop test failed"); + } + for (Struct s : v5) { + if (s.getNum() != 34) throw new RuntimeException("v5 loop test failed"); + } + for (Struct s : v6) { + if (s.getNum() != 56) throw new RuntimeException("v6 loop test failed"); + } + + StructVector v7 = li_std_vector.vecstruct(new StructVector()); + v7.add(new Struct(1)); + v7.add(new Struct(23)); + v7.add(new Struct(456)); + v7.add(new Struct(7890)); + if (v7.size() != 4) throw new RuntimeException("v7 test (1) failed"); + { + double[] a7 = {1, 23, 456, 7890}; + int i7 = 0; + for (Struct s7 : v7) { + if (s7.getNum() != a7[i7]) throw new RuntimeException("v7 test (2) failed"); + i7++; + } + if (i7 != a7.length) throw new RuntimeException("v7 test (3) failed"); + } + if (v7.remove(2).getNum() != 456) throw new RuntimeException("v7 test (4) failed"); + { + double[] a7 = {1, 23, 7890}; + int i7 = 0; + for (Struct s7 : v7) { + if (s7.getNum() != a7[i7]) throw new RuntimeException("v7 test (5) failed"); + i7++; + } + if (i7 != a7.length) throw new RuntimeException("v7 test (6) failed"); + } + v7.add(1, new Struct(123)); + { + double[] a7 = {1, 123, 23, 7890}; + int i7 = 0; + for (Struct s7 : v7) { + if (s7.getNum() != a7[i7]) throw new RuntimeException("v7 test (7) failed"); + i7++; + } + if (i7 != a7.length) throw new RuntimeException("v7 test (8) failed"); + } + + BoolVector v8 = new BoolVector(); + if (!v8.add(true)) throw new RuntimeException("v8 test (1) failed");; + if (v8.get(0) != true) throw new RuntimeException("v8 test (2) failed");; + if (v8.set(0, false) != true) throw new RuntimeException("v8 test (3) failed");; + if (v8.set(0, false) != false) throw new RuntimeException("v8 test (4) failed");; + if (v8.size() != 1) throw new RuntimeException("v8 test (5) failed");; + + java.util.ArrayList bl = new java.util.ArrayList(java.util.Arrays.asList(true, false, true, false)); + BoolVector bv = new BoolVector(java.util.Arrays.asList(true, false, true, false)); + BoolVector bv2 = new BoolVector(bl); + java.util.ArrayList bl2 = new java.util.ArrayList(bv); + boolean bbb1 = bv.get(0); + Boolean bbb2 = bv.get(0); + + IntVector v9 = new IntVector(java.util.Arrays.asList(10, 20, 30, 40)); + v9.add(50); + v9.add(60); + v9.add(70); + if (v9.size() != 7) throw new RuntimeException("v9 test (1) failed"); + if (!v9.remove(new Integer(60))) throw new RuntimeException("v9 test (2) failed"); + if (v9.size() != 6) throw new RuntimeException("v9 test (3) failed"); + + IntVector v10 = new IntVector(java.util.Arrays.asList(10, 20, 30, 40, 50)); + v10.subList(1, 4).clear(); // Recommended way to call protected method removeRange(1,3) + if (v10.size() != 2) throw new RuntimeException("v10 test (1) failed"); + if (v10.get(0) != 10) throw new RuntimeException("v10 test (2) failed"); + if (v10.get(1) != 50) throw new RuntimeException("v10 test (3) failed"); + v10.addAll(1, java.util.Arrays.asList(22, 33)); + if (v10.size() != 4) throw new RuntimeException("v10 test (4) failed"); + if (v10.get(1) != 22) throw new RuntimeException("v10 test (5) failed"); + if (v10.get(2) != 33) throw new RuntimeException("v10 test (6) failed"); + + v10.add(v10.size(), 55); + if (v10.size() != 5) throw new RuntimeException("v10 test (7) failed"); + if (v10.get(4) != 55) throw new RuntimeException("v10 test (8) failed"); + + IntVector v11 = new IntVector(java.util.Arrays.asList(11, 22, 33, 44)); + v11.listIterator(0); + v11.listIterator(v11.size()); + try { + v11.listIterator(v11.size() + 1); + throw new RuntimeException("v11 test (1) failed"); + } catch (IndexOutOfBoundsException e) { + } + try { + v11.listIterator(-1); + throw new RuntimeException("v11 test (2) failed"); + } catch (IndexOutOfBoundsException e) { + } } } diff --git a/Examples/test-suite/java/member_pointer_const_runme.java b/Examples/test-suite/java/member_pointer_const_runme.java new file mode 100644 index 000000000..89735d3eb --- /dev/null +++ b/Examples/test-suite/java/member_pointer_const_runme.java @@ -0,0 +1,60 @@ +import member_pointer_const.*; + +public class member_pointer_const_runme { + + static { + try { + System.loadLibrary("member_pointer_const"); + } 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 SWIGTYPE_m_Shape__f_void__double memberPtr = null; + + public static void main(String argv[]) { + // Get the pointers + + SWIGTYPE_m_Shape__f_void__double area_pt = member_pointer_const.areapt(); + SWIGTYPE_m_Shape__f_void__double perim_pt = member_pointer_const.perimeterpt(); + + // Create some objects + + Square s = new Square(10); + + // Do some calculations + + check( "Square area ", 100.0, member_pointer_const.do_op(s,area_pt) ); + check( "Square perim", 40.0, member_pointer_const.do_op(s,perim_pt) ); + + memberPtr = member_pointer_const.getAreavar(); + memberPtr = member_pointer_const.getPerimetervar(); + + // Try the variables + check( "Square area ", 100.0, member_pointer_const.do_op(s,member_pointer_const.getAreavar()) ); + check( "Square perim", 40.0, member_pointer_const.do_op(s,member_pointer_const.getPerimetervar()) ); + + // Modify one of the variables + member_pointer_const.setAreavar(perim_pt); + + check( "Square perimeter", 40.0, member_pointer_const.do_op(s,member_pointer_const.getAreavar()) ); + + // Try the constants + + memberPtr = member_pointer_const.AREAPT; + memberPtr = member_pointer_const.PERIMPT; + memberPtr = member_pointer_const.NULLPT; + + check( "Square area ", 100.0, member_pointer_const.do_op(s,member_pointer_const.AREAPT) ); + check( "Square perim", 40.0, member_pointer_const.do_op(s,member_pointer_const.PERIMPT) ); + + // Typedefs + check( "Square perim", 40.0, member_pointer_const.do_op_td(s,perim_pt) ); + } + + private static void check(String what, double expected, double actual) { + if (expected != actual) + throw new RuntimeException("Failed: " + what + " Expected: " + expected + " Actual: " + actual); + } +} diff --git a/Examples/test-suite/java/member_pointer_runme.java b/Examples/test-suite/java/member_pointer_runme.java index f8dcfbcb8..d0520a99c 100644 --- a/Examples/test-suite/java/member_pointer_runme.java +++ b/Examples/test-suite/java/member_pointer_runme.java @@ -49,6 +49,8 @@ public class member_pointer_runme { check( "Square area ", 100.0, member_pointer.do_op(s,member_pointer.AREAPT) ); check( "Square perim", 40.0, member_pointer.do_op(s,member_pointer.PERIMPT) ); + // Typedefs + check( "Square perim", 40.0, member_pointer.do_op_td(s,perim_pt) ); } private static void check(String what, double expected, double actual) { diff --git a/Examples/test-suite/java/namespace_chase_runme.java b/Examples/test-suite/java/namespace_chase_runme.java new file mode 100644 index 000000000..9b4898bd0 --- /dev/null +++ b/Examples/test-suite/java/namespace_chase_runme.java @@ -0,0 +1,26 @@ + +import namespace_chase.*; + +public class namespace_chase_runme { + + static { + try { + System.loadLibrary("namespace_chase"); + } 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[]) + { + Struct1A s1a = new Struct1A(); + Struct1B s1b = new Struct1B(); + Struct1C s1c = new Struct1C(); + + namespace_chase.sss3a(s1a, s1b, s1c); + namespace_chase.sss3b(s1a, s1b, s1c); + // needs fixing +// namespace_chase.sss3c(s1a, s1b, s1c); + } +} diff --git a/Examples/test-suite/java/namespace_template_runme.java b/Examples/test-suite/java/namespace_template_runme.java new file mode 100644 index 000000000..c0c7ba135 --- /dev/null +++ b/Examples/test-suite/java/namespace_template_runme.java @@ -0,0 +1,32 @@ + +import namespace_template.*; + +public class namespace_template_runme { + + static { + try { + System.loadLibrary("namespace_template"); + } 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[]) { + vectorchar vc = new vectorchar(); + vectorshort vs = new vectorshort(); + vectorint vi = new vectorint(); + vectorlong vl = new vectorlong(); + + vc.blah((char)10); + vs.blah((short)10); + vi.blah(10); + vl.blah(10); + + vc.vectoruse(vc, vc); + vs.vectoruse(vs, vs); + vi.vectoruse(vi, vi); + vl.vectoruse(vl, vl); + } +} + diff --git a/Examples/test-suite/java/template_parameters_global_scope_runme.java b/Examples/test-suite/java/template_parameters_global_scope_runme.java new file mode 100644 index 000000000..a536fe476 --- /dev/null +++ b/Examples/test-suite/java/template_parameters_global_scope_runme.java @@ -0,0 +1,75 @@ +import template_parameters_global_scope.*; + +public class template_parameters_global_scope_runme { + + static { + try { + System.loadLibrary("template_parameters_global_scope"); + } 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[]) { + + int alloc = 0; + + // Check 1 + alloc = template_parameters_global_scope.Bucket1(); + alloc = template_parameters_global_scope.Bucket2(); + alloc = template_parameters_global_scope.Bucket3(); + alloc = template_parameters_global_scope.Bucket4(); + alloc = template_parameters_global_scope.Bucket5(); + alloc = template_parameters_global_scope.Bucket6(); + + // Check 2 + alloc = template_parameters_global_scope.Spade1(); + alloc = template_parameters_global_scope.Spade2(); + alloc = template_parameters_global_scope.Spade3(); + alloc = template_parameters_global_scope.Spade4(); + alloc = template_parameters_global_scope.Spade5(); + alloc = template_parameters_global_scope.Spade6(); + + // Check 3 + alloc = template_parameters_global_scope.Ball1(); + alloc = template_parameters_global_scope.Ball2(); + alloc = template_parameters_global_scope.Ball3(); + alloc = template_parameters_global_scope.Ball4(); + alloc = template_parameters_global_scope.Ball5(); + alloc = template_parameters_global_scope.Ball6(); + + // Check 4 + alloc = template_parameters_global_scope.Bat1(); + alloc = template_parameters_global_scope.Bat2(); + alloc = template_parameters_global_scope.Bat3(); + alloc = template_parameters_global_scope.Bat4(); + alloc = template_parameters_global_scope.Bat5(); + alloc = template_parameters_global_scope.Bat6(); + + // Check 5 + alloc = template_parameters_global_scope.Chair1(); + alloc = template_parameters_global_scope.Chair2(); + alloc = template_parameters_global_scope.Chair3(); + alloc = template_parameters_global_scope.Chair4(); + alloc = template_parameters_global_scope.Chair5(); + alloc = template_parameters_global_scope.Chair6(); + + // Check 6 + alloc = template_parameters_global_scope.Table1(); + alloc = template_parameters_global_scope.Table2(); + alloc = template_parameters_global_scope.Table3(); + alloc = template_parameters_global_scope.Table4(); + alloc = template_parameters_global_scope.Table5(); + alloc = template_parameters_global_scope.Table6(); + + /* + alloc = template_parameters_global_scope.rejig1(); + alloc = template_parameters_global_scope.rejig2(); + alloc = template_parameters_global_scope.rejig3(); + alloc = template_parameters_global_scope.rejig4(); + alloc = template_parameters_global_scope.rejig5(); + alloc = template_parameters_global_scope.rejig6(); + */ + } +} diff --git a/Examples/test-suite/java/template_using_directive_and_declaration_forward_runme.java b/Examples/test-suite/java/template_using_directive_and_declaration_forward_runme.java index 080945e02..3aab5fa8f 100644 --- a/Examples/test-suite/java/template_using_directive_and_declaration_forward_runme.java +++ b/Examples/test-suite/java/template_using_directive_and_declaration_forward_runme.java @@ -19,32 +19,32 @@ public class template_using_directive_and_declaration_forward_runme { template_using_directive_and_declaration_forward.useit1b(new Thing1Int()); template_using_directive_and_declaration_forward.useit1c(new Thing1Int()); -//BROKEN template_using_directive_and_declaration_forward.useit2(new Thing2Int()); + template_using_directive_and_declaration_forward.useit2(new Thing2Int()); template_using_directive_and_declaration_forward.useit2a(new Thing2Int()); template_using_directive_and_declaration_forward.useit2b(new Thing2Int()); template_using_directive_and_declaration_forward.useit2c(new Thing2Int()); template_using_directive_and_declaration_forward.useit2d(new Thing2Int()); -//BROKEN template_using_directive_and_declaration_forward.useit3(new Thing3Int()); + template_using_directive_and_declaration_forward.useit3(new Thing3Int()); template_using_directive_and_declaration_forward.useit3a(new Thing3Int()); template_using_directive_and_declaration_forward.useit3b(new Thing3Int()); template_using_directive_and_declaration_forward.useit3c(new Thing3Int()); template_using_directive_and_declaration_forward.useit3d(new Thing3Int()); -//BROKEN template_using_directive_and_declaration_forward.useit4(new Thing4Int()); + template_using_directive_and_declaration_forward.useit4(new Thing4Int()); template_using_directive_and_declaration_forward.useit4a(new Thing4Int()); template_using_directive_and_declaration_forward.useit4b(new Thing4Int()); template_using_directive_and_declaration_forward.useit4c(new Thing4Int()); template_using_directive_and_declaration_forward.useit4d(new Thing4Int()); -//BROKEN template_using_directive_and_declaration_forward.useit5(new Thing5Int()); + template_using_directive_and_declaration_forward.useit5(new Thing5Int()); template_using_directive_and_declaration_forward.useit5a(new Thing5Int()); template_using_directive_and_declaration_forward.useit5b(new Thing5Int()); template_using_directive_and_declaration_forward.useit5c(new Thing5Int()); template_using_directive_and_declaration_forward.useit5d(new Thing5Int()); -//BROKEN template_using_directive_and_declaration_forward.useit7(new Thing7Int()); + template_using_directive_and_declaration_forward.useit7(new Thing7Int()); template_using_directive_and_declaration_forward.useit7a(new Thing7Int()); template_using_directive_and_declaration_forward.useit7b(new Thing7Int()); template_using_directive_and_declaration_forward.useit7c(new Thing7Int()); diff --git a/Examples/test-suite/java/template_using_directive_typedef_runme.java b/Examples/test-suite/java/template_using_directive_typedef_runme.java new file mode 100644 index 000000000..bec077399 --- /dev/null +++ b/Examples/test-suite/java/template_using_directive_typedef_runme.java @@ -0,0 +1,31 @@ + +import template_using_directive_typedef.*; + +public class template_using_directive_typedef_runme { + + static { + try { + System.loadLibrary("template_using_directive_typedef"); + } 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[]) { + Vector_Obj vo = new Vector_Obj(); + + Holder h = new Holder(); + h.holder_use1(vo, vo, vo); + h.holder_use2(vo, vo, vo); + h.holder_use3(vo, vo, vo); + + template_using_directive_typedef.tns_holder_use(vo, vo); + template_using_directive_typedef.tns_use(vo, vo, vo); + template_using_directive_typedef.global_holder_use(vo); + template_using_directive_typedef.global_use(vo, vo, vo); + template_using_directive_typedef.ns1_holder_use(vo); + template_using_directive_typedef.ns2_holder_use(vo, vo, vo, vo); + } +} + diff --git a/Examples/test-suite/java/typedef_funcptr_runme.java b/Examples/test-suite/java/typedef_funcptr_runme.java new file mode 100644 index 000000000..0dd44cecd --- /dev/null +++ b/Examples/test-suite/java/typedef_funcptr_runme.java @@ -0,0 +1,34 @@ + +import typedef_funcptr.*; + +public class typedef_funcptr_runme { + + static { + try { + System.loadLibrary("typedef_funcptr"); + } 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[]) { + int a = 100; + int b = 10; + + if (typedef_funcptr.do_op(a,b,typedef_funcptr.addf) != 110) + throw new RuntimeException("addf failed"); + if (typedef_funcptr.do_op(a,b,typedef_funcptr.subf) != 90) + throw new RuntimeException("subf failed"); + + if (typedef_funcptr.do_op_typedef_int(a,b,typedef_funcptr.addf) != 110) + throw new RuntimeException("addf failed"); + if (typedef_funcptr.do_op_typedef_int(a,b,typedef_funcptr.subf) != 90) + throw new RuntimeException("subf failed"); + + if (typedef_funcptr.do_op_typedef_Integer(a,b,typedef_funcptr.addf) != 110) + throw new RuntimeException("addf failed"); + if (typedef_funcptr.do_op_typedef_Integer(a,b,typedef_funcptr.subf) != 90) + throw new RuntimeException("subf failed"); + } +} diff --git a/Examples/test-suite/java_director_assumeoverride.i b/Examples/test-suite/java_director_assumeoverride.i index cddebb4d7..f0eb37049 100644 --- a/Examples/test-suite/java_director_assumeoverride.i +++ b/Examples/test-suite/java_director_assumeoverride.i @@ -4,7 +4,7 @@ class OverrideMe { public: virtual ~OverrideMe() {} - virtual void func() {}; + virtual void funk() {}; }; #include "java_director_assumeoverride_wrap.h" @@ -23,7 +23,7 @@ bool isFuncOverridden(OverrideMe* f) { class OverrideMe { public: virtual ~OverrideMe(); - virtual void func(); + virtual void funk(); }; bool isFuncOverridden(OverrideMe* f); diff --git a/Examples/test-suite/java_director_exception_feature.i b/Examples/test-suite/java_director_exception_feature.i index d6f1e3f55..a0b3b7261 100644 --- a/Examples/test-suite/java_director_exception_feature.i +++ b/Examples/test-suite/java_director_exception_feature.i @@ -8,14 +8,17 @@ #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif - -#include +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif %} %include // DEFINE exceptions in header section using std::runtime_error %{ + #include #include #include diff --git a/Examples/test-suite/java_director_exception_feature_nspace.i b/Examples/test-suite/java_director_exception_feature_nspace.i index 264c2a938..3111538fc 100644 --- a/Examples/test-suite/java_director_exception_feature_nspace.i +++ b/Examples/test-suite/java_director_exception_feature_nspace.i @@ -15,14 +15,17 @@ #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif - -#include +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif %} %include // DEFINE exceptions in header section using std::runtime_error %{ + #include #include #include diff --git a/Examples/test-suite/java_director_typemaps.i b/Examples/test-suite/java_director_typemaps.i index 8d86c59a4..e7bc9a659 100644 --- a/Examples/test-suite/java_director_typemaps.i +++ b/Examples/test-suite/java_director_typemaps.i @@ -185,7 +185,7 @@ public: void etest() { bool boolarg_inout = false; - signed char signed_chararg_inout = 150; + signed char signed_chararg_inout = 111; unsigned char unsigned_chararg_inout = 150; short shortarg_inout = 150; diff --git a/Examples/test-suite/java_throws.i b/Examples/test-suite/java_throws.i index 48a0eeabc..c628a45e6 100644 --- a/Examples/test-suite/java_throws.i +++ b/Examples/test-suite/java_throws.i @@ -42,10 +42,19 @@ short full_of_exceptions(int num) { #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif + bool throw_spec_function(int value) throw (int) { throw (int)0; } + #if defined(_MSC_VER) #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif %} %catches(int) catches_function(int value); diff --git a/Examples/test-suite/javascript/null_pointer_runme.js b/Examples/test-suite/javascript/null_pointer_runme.js index 7c0d61244..8a9b61186 100644 --- a/Examples/test-suite/javascript/null_pointer_runme.js +++ b/Examples/test-suite/javascript/null_pointer_runme.js @@ -1,6 +1,6 @@ var null_pointer = require("null_pointer"); -if (!null_pointer.func(null)) { +if (!null_pointer.funk(null)) { throw new Error("Javascript 'null' should be converted into NULL."); } diff --git a/Examples/test-suite/li_boost_shared_ptr_director.i b/Examples/test-suite/li_boost_shared_ptr_director.i new file mode 100644 index 000000000..8f36bf31c --- /dev/null +++ b/Examples/test-suite/li_boost_shared_ptr_director.i @@ -0,0 +1,90 @@ +%module(directors="1") "li_boost_shared_ptr_director" + +%{ +#include +%} + +%include "boost_shared_ptr.i"; +%shared_ptr(C); +%feature("director") Base; + +%inline %{ +struct C { + C() : m(1) {} + C(int n) : m(n) {} + int get_m() { return m; } + int m; +}; + +struct Base { + Base() {} + virtual boost::shared_ptr ret_c_shared_ptr() = 0; + virtual C ret_c_by_value() = 0; + virtual int take_c_by_value(C c) = 0; + virtual int take_c_shared_ptr_by_value(boost::shared_ptr c) = 0; + virtual int take_c_shared_ptr_by_ref(boost::shared_ptr& c) = 0; + virtual int take_c_shared_ptr_by_pointer(boost::shared_ptr* c) = 0; + virtual int take_c_shared_ptr_by_pointer_ref(boost::shared_ptr*const&c) = 0; + virtual ~Base() {} +}; + +int call_ret_c_shared_ptr(Base* b) { + boost::shared_ptr ptr = b->ret_c_shared_ptr(); + if (ptr) { + return ptr->get_m(); + } else { + return -1; + } +} + +int call_ret_c_by_value(Base* b) { + C c = b->ret_c_by_value(); + return c.get_m(); +} + +int call_take_c_by_value(Base* b) { + C c(5); + return b->take_c_by_value(c); +} + +int call_take_c_shared_ptr_by_value(Base* b) { + boost::shared_ptr ptr(new C(6)); + return b->take_c_shared_ptr_by_value(ptr); +} + +int call_take_c_shared_ptr_by_value_with_null(Base* b) { + boost::shared_ptr ptr; + return b->take_c_shared_ptr_by_value(ptr); +} + +int call_take_c_shared_ptr_by_ref(Base* b) { + boost::shared_ptr ptr(new C(7)); + return b->take_c_shared_ptr_by_ref(ptr); +} + +int call_take_c_shared_ptr_by_ref_with_null(Base* b) { + boost::shared_ptr ptr; + return b->take_c_shared_ptr_by_ref(ptr); +} + +int call_take_c_shared_ptr_by_pointer(Base* b) { + boost::shared_ptr ptr(new C(8)); + return b->take_c_shared_ptr_by_pointer(&ptr); +} + +int call_take_c_shared_ptr_by_pointer_with_null(Base* b) { + boost::shared_ptr ptr; + return b->take_c_shared_ptr_by_pointer(&ptr); +} + +int call_take_c_shared_ptr_by_pointer_ref(Base* b) { + boost::shared_ptr *ptr = new boost::shared_ptr(new C(9)); + return b->take_c_shared_ptr_by_pointer_ref(ptr); +} + +int call_take_c_shared_ptr_by_pointer_ref_with_null(Base* b) { + boost::shared_ptr *ptr = new boost::shared_ptr(); + return b->take_c_shared_ptr_by_pointer_ref(ptr); +} + +%} diff --git a/Examples/test-suite/li_std_except.i b/Examples/test-suite/li_std_except.i index b79d36bc1..8c96a11f8 100644 --- a/Examples/test-suite/li_std_except.i +++ b/Examples/test-suite/li_std_except.i @@ -6,6 +6,10 @@ #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif %} @@ -38,3 +42,13 @@ void throw_underflow_error() throw(std::underflow_error) { throw std::underflow_error("oops"); } }; %} + + +%{ +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +%} diff --git a/Examples/test-suite/li_std_except_as_class.i b/Examples/test-suite/li_std_except_as_class.i index 01ed1f07c..1b5dd6082 100644 --- a/Examples/test-suite/li_std_except_as_class.i +++ b/Examples/test-suite/li_std_except_as_class.i @@ -9,6 +9,10 @@ #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif %} %{ @@ -31,3 +35,12 @@ bool is_python_builtin() { return true; } bool is_python_builtin() { return false; } #endif %} + +%{ +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +%} diff --git a/Examples/test-suite/li_std_list.i b/Examples/test-suite/li_std_list.i index bae475eea..d1ec4e7e4 100644 --- a/Examples/test-suite/li_std_list.i +++ b/Examples/test-suite/li_std_list.i @@ -1,6 +1,7 @@ %module li_std_list %include "std_list.i" +%include "std_string.i" %{ #include @@ -8,19 +9,18 @@ #include %} -namespace std { - %template(IntList) list; -} - +%template(BoolList) std::list; +%template(CharList) std::list; +%template(ShortList) std::list; +%template(IntList) std::list; +%template(LongList) std::list; +%template(UCharList) std::list; +%template(UIntList) std::list; +%template(UShortList) std::list; +%template(ULongList) std::list; +%template(FloatList) std::list; %template(DoubleList) std::list; - -%inline %{ -typedef float Real; -%} - -namespace std { - %template(RealList) list; -} +%template(StringList) std::list; %inline %{ @@ -40,7 +40,21 @@ struct Struct { Struct(double d) : num(d) {} // bool operator==(const Struct &other) { return (num == other.num); } }; + +const std::list & CopyContainerStruct(const std::list & container) { return container; } +const std::list & CopyContainerStructPtr(const std::list & container) { return container; } +const std::list & CopyContainerStructConstPtr(const std::list & container) { return container; } + +enum Fruit { + APPLE, + BANANNA, + PEAR, + KIWI, +}; %} +%template(StructList) std::list; +%template(StructPtrList) std::list; +%template(StructConstPtrList) std::list; - +%template(FruitList) std::list; diff --git a/Examples/test-suite/li_std_string.i b/Examples/test-suite/li_std_string.i index a1a55ed85..15042c464 100644 --- a/Examples/test-suite/li_std_string.i +++ b/Examples/test-suite/li_std_string.i @@ -6,6 +6,16 @@ %apply std::string& INOUT { std::string &inout } #endif +%{ +#if defined(_MSC_VER) + #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif +%} + %inline %{ @@ -49,10 +59,6 @@ void test_reference_inout(std::string &inout) { inout += inout; } -#if defined(_MSC_VER) - #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) -#endif - void test_throw() throw(std::string){ static std::string x = "test_throw message"; throw x; @@ -154,6 +160,13 @@ public: const char *get_null(const char *a) { return a == 0 ? a : "non-null"; } - - +%} + +%{ +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif %} diff --git a/Examples/test-suite/li_std_wstring.i b/Examples/test-suite/li_std_wstring.i index 80f860338..fe1166be3 100644 --- a/Examples/test-suite/li_std_wstring.i +++ b/Examples/test-suite/li_std_wstring.i @@ -78,9 +78,17 @@ std::wstring& test_reference_out() { return x; } +bool test_equal_abc(const std::wstring &s) { + return L"abc" == s; +} + #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif void test_throw() throw(std::wstring){ static std::wstring x = L"x"; @@ -91,6 +99,9 @@ void test_throw() throw(std::wstring){ #if defined(_MSC_VER) #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif #ifdef SWIGPYTHON_BUILTIN bool is_python_builtin() { return true; } diff --git a/Examples/test-suite/lua/Makefile.in b/Examples/test-suite/lua/Makefile.in index 7a77bbb9e..63b8692b1 100644 --- a/Examples/test-suite/lua/Makefile.in +++ b/Examples/test-suite/lua/Makefile.in @@ -58,9 +58,3 @@ run_testcase = \ clean: $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' lua_clean - -cvsignore: - @echo '*wrap* *.so *.dll *.exp *.lib' - @echo Makefile - @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do echo $$i.lua; done - @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do if grep -q $${i}_runme.lua CVS/Entries ; then echo $${i}_runme.lua; fi; done diff --git a/Examples/test-suite/member_funcptr_galore.i b/Examples/test-suite/member_funcptr_galore.i index 9a012f306..27c2f02a7 100644 --- a/Examples/test-suite/member_funcptr_galore.i +++ b/Examples/test-suite/member_funcptr_galore.i @@ -1,5 +1,17 @@ %module member_funcptr_galore +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) extra2; +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) extra3; +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) pp2; +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) pp3; +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) pp5; + +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) ccextra2; +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) ccextra3; +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc2; +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc3; +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc5; + %{ #if defined(__SUNPRO_CC) #pragma error_messages (off, badargtype2w) /* Formal argument ... is being passed extern "C" ... */ @@ -27,6 +39,8 @@ public: void move(double dx, double dy); virtual double area(Shape &ref, int & (FunkSpace::Funktions::*d)(const int &, int)) { return 0.0; } + virtual double area_const(Shape &ref, int & (FunkSpace::Funktions::*)(const int &, int) const) { return 0.0; } // Note: unnamed parameter + virtual double zyx(int (FunkSpace::Funktions::*)() const) { return 0.0; } // Note: unnamed parameter virtual double abc(Thing ts, Thing< const Space::Shape * > tda[]) { return 0.0; } virtual ~Shape() {} }; @@ -55,6 +69,10 @@ double do_op(Space::Shape *s, double (Space::Shape::*m)(void)) { return (s->*m)(); } +double do_op_const(Space::Shape *s, double (Space::Shape::*m)(void) const) { + return (s->*m)(); +} + double (Space::Shape::*areapt(Space::Shape &ref, int & (FunkSpace::Funktions::*d)(const int &, int)))(Space::Shape &, int & (FunkSpace::Funktions::*d)(const int &, int)) { return &Space::Shape::area; } @@ -75,6 +93,7 @@ double (Space::Shape::*abcvar)(Thing, Thing< const Space::Shape * >[]) = /* Some constants */ %constant double (Space::Shape::*AREAPT)(Space::Shape &, int & (FunkSpace::Funktions::*)(const int &, int)) = &Space::Shape::area; +%constant double (Space::Shape::*AREAPT_CONST)(Space::Shape &, int & (FunkSpace::Funktions::*)(const int &, int) const) = &Space::Shape::area_const; %constant double (Space::Shape::*PERIMPT)(Thing, Thing< const Space::Shape * >[]) = &Space::Shape::abc; %constant double (Space::Shape::*NULLPT)(void) = 0; @@ -94,3 +113,115 @@ int call3(int & (FunkSpace::Funktions::*d)(const int &, int), int a, int b) { Fu int unreal1(double (Space::Shape::*memptr)(Space::Shape &, int & (FunkSpace::Funktions::*)(const int &, int))) { return 0; } int unreal2(double (Space::Shape::*memptr)(Thing)) { return 0; } %} + + +%inline %{ +struct Funcs { + short FF(bool) { return 0; } + short CC(bool) const { return 0; } +}; + +class MemberFuncPtrs +{ +public: + // member const function pointers, unnamed parameters + int aaa1(short (Funcs::* )(bool) const) const; + int aaa2(short (Funcs::* const *&)(bool) const) const; + int aaa3(short (Funcs::* *& )(bool) const) const; + int aaa4(short (Funcs::* *const& )(bool) const) const; + int aaa5(short (Funcs::* & )(bool) const) const; + int aaa6(short (Funcs::* const)(bool) const) const; + int aaa7(short (Funcs::* const&)(bool) const) const; + + // member non-const function pointers, unnamed parameters + int bbb1(short (Funcs::* )(bool)) const; + int bbb2(short (Funcs::* const *&)(bool)) const; + int bbb3(short (Funcs::* *& )(bool)) const; + int bbb4(short (Funcs::* *const& )(bool)) const; + int bbb5(short (Funcs::* & )(bool)) const; + int bbb6(short (Funcs::* const)(bool)) const; + int bbb7(short (Funcs::* const&)(bool)) const; + + // member const function pointers, named parameters + int ppp1(short (Funcs::* pp1)(bool) const) const; + int ppp2(short (Funcs::* const *& pp2)(bool) const) const; + int ppp3(short (Funcs::* *& pp3)(bool) const) const; + int ppp4(short (Funcs::* *const& pp4)(bool) const) const; + int ppp5(short (Funcs::* & pp5)(bool) const) const; + int ppp6(short (Funcs::* const pp6)(bool) const) const; + int ppp7(short (Funcs::* const& pp7)(bool) const) const; + + // member non-const function pointers, named parameters + int qqq1(short (Funcs::* qq1)(bool)) const; + int qqq2(short (Funcs::* const *& qq2)(bool)) const; + int qqq3(short (Funcs::* *& qq3)(bool)) const; + int qqq4(short (Funcs::* *const& qq4)(bool)) const; + int qqq5(short (Funcs::* & qq5)(bool)) const; + int qqq6(short (Funcs::* const qq6)(bool)) const; + int qqq7(short (Funcs::* const& qq7)(bool)) const; +}; + +// member const function pointers, unnamed parameters +int MemberFuncPtrs::aaa1(short (Funcs::* )(bool) const) const { return 0; } +int MemberFuncPtrs::aaa2(short (Funcs::* const *&)(bool) const) const { return 0; } +int MemberFuncPtrs::aaa3(short (Funcs::* *& )(bool) const) const { return 0; } +int MemberFuncPtrs::aaa4(short (Funcs::* *const& )(bool) const) const { return 0; } +int MemberFuncPtrs::aaa5(short (Funcs::* & )(bool) const) const { return 0; } +int MemberFuncPtrs::aaa6(short (Funcs::* const)(bool) const) const { return 0; } +int MemberFuncPtrs::aaa7(short (Funcs::* const&)(bool) const) const { return 0; } + +// member non-const function pointers, unnamed parameters +int MemberFuncPtrs::bbb1(short (Funcs::* )(bool)) const { return 0; } +int MemberFuncPtrs::bbb2(short (Funcs::* const *&)(bool)) const { return 0; } +int MemberFuncPtrs::bbb3(short (Funcs::* *& )(bool)) const { return 0; } +int MemberFuncPtrs::bbb4(short (Funcs::* *const& )(bool)) const { return 0; } +int MemberFuncPtrs::bbb5(short (Funcs::* & )(bool)) const { return 0; } +int MemberFuncPtrs::bbb6(short (Funcs::* const)(bool)) const { return 0; } +int MemberFuncPtrs::bbb7(short (Funcs::* const&)(bool)) const { return 0; } + +// member const function pointers, named parameters +int MemberFuncPtrs::ppp1(short (Funcs::* pp1)(bool) const) const { return 0; } +int MemberFuncPtrs::ppp2(short (Funcs::* const *& pp2)(bool) const) const { return 0; } +int MemberFuncPtrs::ppp3(short (Funcs::* *& pp3)(bool) const) const { return 0; } +int MemberFuncPtrs::ppp4(short (Funcs::* *const& pp4)(bool) const) const { return 0; } +int MemberFuncPtrs::ppp5(short (Funcs::* & pp5)(bool) const) const { return 0; } +int MemberFuncPtrs::ppp6(short (Funcs::* const pp6)(bool) const) const { return 0; } +int MemberFuncPtrs::ppp7(short (Funcs::* const& pp7)(bool) const) const { return 0; } + +// member non-const function pointers, named parameters +int MemberFuncPtrs::qqq1(short (Funcs::* qq1)(bool)) const { return 0; } +int MemberFuncPtrs::qqq2(short (Funcs::* const *& qq2)(bool)) const { return 0; } +int MemberFuncPtrs::qqq3(short (Funcs::* *& qq3)(bool)) const { return 0; } +int MemberFuncPtrs::qqq4(short (Funcs::* *const& qq4)(bool)) const { return 0; } +int MemberFuncPtrs::qqq5(short (Funcs::* & qq5)(bool)) const { return 0; } +int MemberFuncPtrs::qqq6(short (Funcs::* const qq6)(bool)) const { return 0; } +int MemberFuncPtrs::qqq7(short (Funcs::* const& qq7)(bool)) const { return 0; } + +// member non-const function pointer variables +short (Funcs::* pp1)(bool) = &Funcs::FF; + +short (Funcs::* const * extra2)(bool) = &pp1; +short (Funcs::* * extra3)(bool) = &pp1; +short (Funcs::* *const extra4)(bool) = &pp1; + +short (Funcs::* const *& pp2)(bool) = extra2; +short (Funcs::* *& pp3)(bool) = extra3; +short (Funcs::* *const& pp4)(bool) = extra4; +short (Funcs::* & pp5)(bool) = pp1; +short (Funcs::* const pp6)(bool) = &Funcs::FF; +short (Funcs::* const& pp7)(bool) = pp1; + +// member const function pointer variables +short (Funcs::* cc1)(bool) const = &Funcs::CC; + +short (Funcs::* const * ccextra2)(bool) const = &cc1; +short (Funcs::* * ccextra3)(bool) const = &cc1; +short (Funcs::* *const ccextra4)(bool) const = &cc1; + +short (Funcs::* const *& cc2)(bool) const = ccextra2; +short (Funcs::* *& cc3)(bool) const = ccextra3; +short (Funcs::* *const& cc4)(bool) const = ccextra4; +short (Funcs::* & cc5)(bool) const = cc1; +short (Funcs::* const cc6)(bool) const = &Funcs::CC; +short (Funcs::* const& cc7)(bool) const = cc1; +%} diff --git a/Examples/test-suite/member_pointer.i b/Examples/test-suite/member_pointer.i index fe454302a..e3b4f85ab 100644 --- a/Examples/test-suite/member_pointer.i +++ b/Examples/test-suite/member_pointer.i @@ -44,17 +44,22 @@ public: virtual double perimeter(void); }; +/* Typedef */ +typedef double (Shape::*PerimeterFunc_td)(void); + extern double do_op(Shape *s, double (Shape::*m)(void)); +extern double do_op_td(Shape *s, PerimeterFunc_td m); /* Functions that return member pointers */ extern double (Shape::*areapt())(void); extern double (Shape::*perimeterpt())(void); +extern PerimeterFunc_td perimeterpt_td(); /* Global variables that are member pointers */ extern double (Shape::*areavar)(void); extern double (Shape::*perimetervar)(void); - +extern PerimeterFunc_td perimetervar_td; %} %{ @@ -88,6 +93,10 @@ double do_op(Shape *s, double (Shape::*m)(void)) { return (s->*m)(); } +double do_op_td(Shape *s, PerimeterFunc_td m) { + return (s->*m)(); +} + double (Shape::*areapt())(void) { return &Shape::area; } @@ -96,9 +105,14 @@ double (Shape::*perimeterpt())(void) { return &Shape::perimeter; } +PerimeterFunc_td perimeterpt_td() { + return &Shape::perimeter; +} + /* Member pointer variables */ double (Shape::*areavar)(void) = &Shape::area; double (Shape::*perimetervar)(void) = &Shape::perimeter; +PerimeterFunc_td perimetervar_td = &Shape::perimeter; %} diff --git a/Examples/test-suite/member_pointer_const.i b/Examples/test-suite/member_pointer_const.i new file mode 100644 index 000000000..4af712f7f --- /dev/null +++ b/Examples/test-suite/member_pointer_const.i @@ -0,0 +1,149 @@ +%module member_pointer_const +// Same as member_pointer.i but using member pointer const functions + +%{ +#if defined(__SUNPRO_CC) +#pragma error_messages (off, badargtype2w) /* Formal argument ... is being passed extern "C" ... */ +#pragma error_messages (off, wbadinit) /* Using extern "C" ... to initialize ... */ +#pragma error_messages (off, wbadasg) /* Assigning extern "C" ... */ +#endif +%} + +%inline %{ +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + double *z; + + void move(double dx, double dy); + virtual double area(void) const = 0; + virtual double perimeter(void) const = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(void) const; + virtual double perimeter(void) const; +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(void) const; + virtual double perimeter(void) const; +}; + +/* Typedef */ +typedef double (Shape::*PerimeterFunc_td)(void) const; + +extern double do_op(Shape *s, double (Shape::*m)(void) const); +extern double do_op_td(Shape *s, PerimeterFunc_td m); + +/* Functions that return member pointers */ + +extern double (Shape::*areapt())(void) const; +extern double (Shape::*perimeterpt())(void) const; +extern PerimeterFunc_td perimeterpt_td(); + +/* Global variables that are member pointers */ +extern double (Shape::*areavar)(void) const; +extern double (Shape::*perimetervar)(void) const; +extern PerimeterFunc_td perimetervar_td; +%} + +%{ +# define SWIG_M_PI 3.14159265358979323846 + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area(void) const { + return SWIG_M_PI*radius*radius; +} + +double Circle::perimeter(void) const { + return 2*SWIG_M_PI*radius; +} + +double Square::area(void) const { + return width*width; +} + +double Square::perimeter(void) const { + return 4*width; +} + +double do_op(Shape *s, double (Shape::*m)(void) const) { + return (s->*m)(); +} + +double do_op_td(Shape *s, PerimeterFunc_td m) { + return (s->*m)(); +} + +double (Shape::*areapt())(void) const { + return &Shape::area; +} + +double (Shape::*perimeterpt())(void) const { + return &Shape::perimeter; +} + +PerimeterFunc_td perimeterpt_td() { + return &Shape::perimeter; +} + +/* Member pointer variables */ +double (Shape::*areavar)(void) const = &Shape::area; +double (Shape::*perimetervar)(void) const = &Shape::perimeter; +PerimeterFunc_td perimetervar_td = &Shape::perimeter; +%} + + +/* Some constants */ +%constant double (Shape::*AREAPT)(void) const = &Shape::area; +%constant double (Shape::*PERIMPT)(void) const = &Shape::perimeter; +%constant double (Shape::*NULLPT)(void) const = 0; + +/* +%inline %{ + struct Funktions { + void retByRef(int & (*d)(double)) {} + }; + void byRef(int & (Funktions::*d)(double)) {} +%} +*/ + +%inline %{ + +struct Funktions { + int addByValue(const int &a, int b) const { return a+b; } + int * addByPointer(const int &a, int b) const { static int val; val = a+b; return &val; } + int & addByReference(const int &a, int b) const { static int val; val = a+b; return val; } +}; + +int call1(int (Funktions::*d)(const int &, int) const, int a, int b) { Funktions f; return (f.*d)(a, b); } +//int call2(int * (Funktions::*d)(const int &, int) const, int a, int b) { Funktions f; return *(f.*d)(a, b); } +//int call3(int & (Funktions::*d)(const int &, int) const, int a, int b) { Funktions f; return (f.*d)(a, b); } +%} + +%constant int (Funktions::*ADD_BY_VALUE)(const int &, int) const = &Funktions::addByValue; +//%constant int * (Funktions::*ADD_BY_POINTER)(const int &, int) const = &Funktions::addByPointer; +//%constant int & (Funktions::*ADD_BY_REFERENCE)(const int &, int) const = &Funktions::addByReference; diff --git a/Examples/test-suite/name_warnings.i b/Examples/test-suite/name_warnings.i index 3455c03bf..0b62ec5d7 100644 --- a/Examples/test-suite/name_warnings.i +++ b/Examples/test-suite/name_warnings.i @@ -40,9 +40,7 @@ namespace std #endif virtual ~A() {} -#ifndef SWIGGO // func is a keyword in Go. - virtual int func() = 0; -#endif + virtual int funk() = 0; private: typedef complex False; }; diff --git a/Examples/test-suite/namespace_chase.i b/Examples/test-suite/namespace_chase.i new file mode 100644 index 000000000..5e3921d0d --- /dev/null +++ b/Examples/test-suite/namespace_chase.i @@ -0,0 +1,36 @@ +%module namespace_chase + +%inline %{ + namespace Space1A { + struct Struct1A {}; + namespace Space1B { + struct Struct1B {}; + namespace Space1C { + struct Struct1C {}; + } + } + } + namespace Space2A { + using namespace Space1A; + namespace Space2B { + using namespace Space1B; + namespace Space2C { + using namespace Space1C; + } + } + } + namespace Space3 { + using namespace Space2A; + void sss3a(Space1A::Struct1A, Space1A::Space1B::Struct1B, Space1A::Space1B::Space1C::Struct1C) {} + void sss3b(Struct1A, Space1B::Struct1B, Space1B::Space1C::Struct1C) {} + // To fix: the last two parameters below fail and result in SWIGTYPE_ types instead of proxy classes + void sss3c(Space2A::Struct1A, Space2A::Space1B::Struct1B, Space2A::Space1B::Space1C::Struct1C) {} + } + namespace Space4 { + using namespace Space2A; + using namespace Space2A::Space2B; + using namespace Space2A::Space2B::Space2C; + void sss4a(Struct1A, Struct1B, Space2C::Struct1C) {} + void sss4b(Struct1A, Struct1B, Struct1C) {} + } +%} diff --git a/Examples/test-suite/namespace_template.i b/Examples/test-suite/namespace_template.i index a36abb19b..8a4b6dca9 100644 --- a/Examples/test-suite/namespace_template.i +++ b/Examples/test-suite/namespace_template.i @@ -2,10 +2,10 @@ %module namespace_template -%warnfilter(SWIGWARN_RUBY_WRONG_NAME) vector; /* Ruby, wrong class name */ -%warnfilter(SWIGWARN_RUBY_WRONG_NAME) test2::vector; /* Ruby, wrong class name */ -%warnfilter(SWIGWARN_RUBY_WRONG_NAME) test3::vector; /* Ruby, wrong class name */ -%warnfilter(SWIGWARN_RUBY_WRONG_NAME) vector; /* Ruby, wrong class name */ +%warnfilter(SWIGWARN_RUBY_WRONG_NAME) test::vector; /* Ruby, wrong class name */ +%warnfilter(SWIGWARN_RUBY_WRONG_NAME) test::vector; /* Ruby, wrong class name */ +%warnfilter(SWIGWARN_RUBY_WRONG_NAME) test::vector; /* Ruby, wrong class name */ +%warnfilter(SWIGWARN_RUBY_WRONG_NAME) test::vector; /* Ruby, wrong class name */ %{ #ifdef max @@ -23,20 +23,9 @@ namespace test { char * blah(T x) { return (char *) "vector::blah"; } + void vectoruse(vector a, test::vector b) {} }; } - -namespace test2 { - using namespace test; -} - -namespace test3 { - using test::max; - using test::vector; -} - -using namespace test2; -namespace T4 = test; %} namespace test { @@ -48,6 +37,7 @@ namespace test { char * blah(T x) { return (char *) "vector::blah"; } + void vectoruse(vector a, test::vector b) {} }; } @@ -55,30 +45,26 @@ using namespace test; %template(maxint) max; %template(vectorint) vector; -namespace test2 { - using namespace test; +namespace test { %template(maxshort) max; %template(vectorshort) vector; } -namespace test3 { - using test::max; - using test::vector; +namespace test { %template(maxlong) max; %template(vectorlong) vector; } %inline %{ -namespace test4 { - using namespace test; - typedef int Integer; +namespace test { + typedef char Char; } %} -namespace test4 { - %template(maxInteger) max; - %template(vectorInteger) vector; +namespace test { + %template(maxchar) max; + %template(vectorchar) vector; } diff --git a/Examples/test-suite/null_pointer.i b/Examples/test-suite/null_pointer.i index 0da827f99..f40d6929f 100644 --- a/Examples/test-suite/null_pointer.i +++ b/Examples/test-suite/null_pointer.i @@ -1,11 +1,9 @@ %module null_pointer -%warnfilter(SWIGWARN_PARSE_KEYWORD) func; // 'func' is a Go keyword, renamed as 'Xfunc' - %inline { struct A {}; - bool func(A* a) { + bool funk(A* a) { return !a; } diff --git a/Examples/test-suite/ocaml/Makefile.in b/Examples/test-suite/ocaml/Makefile.in index ecdf32e9f..5cea4b236 100644 --- a/Examples/test-suite/ocaml/Makefile.in +++ b/Examples/test-suite/ocaml/Makefile.in @@ -11,7 +11,38 @@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = @top_builddir@ -C_TEST_CASES = +FAILING_CPP_TESTS = \ +allowexcept \ +allprotected \ +apply_signed_char \ +apply_strings \ +cpp_enum \ +default_constructor \ +director_binary_string \ +director_enum \ +director_exception \ +director_ignore \ +director_nested \ +director_pass_by_value \ +director_primitives \ +director_protected \ +director_redefined \ +director_string \ +director_using \ +enum_thorough \ +member_pointer_const \ +minherit \ +nested_directors \ +preproc_constants \ +smart_pointer_inherit \ +typedef_mptr \ +using_protected \ + +FAILING_C_TESTS = \ +enums \ +preproc_constants_c \ +string_simple \ +unions \ run_testcase = \ if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) -a \ diff --git a/Examples/test-suite/octave/Makefile.in b/Examples/test-suite/octave/Makefile.in index be47904e2..31a86fb66 100644 --- a/Examples/test-suite/octave/Makefile.in +++ b/Examples/test-suite/octave/Makefile.in @@ -70,20 +70,6 @@ run_testcase = \ clean: $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' octave_clean -cvsignore: - @echo '*wrap* *.mc *.so *.dll *.exp *.lib' - @echo Makefile - @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do echo $$i.m; done - @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do if grep -q $${i}_runme.m CVS/Entries ; then echo $${i}_runme.m; fi; done - @echo clientdata_prop_a.m - @echo clientdata_prop_b.m - @echo imports_a.m - @echo imports_b.m - @echo mod_a.m mod_b.m - @echo hugemod.h hugemod_a.i hugemod_b.i hugemod_a.m hugemod_b.m hugemod_runme.m - @echo template_typedef_import.m - - hugemod: perl hugemod.pl $(MAKE) hugemod_a.cpptest diff --git a/Examples/test-suite/octave/null_pointer_runme.m b/Examples/test-suite/octave/null_pointer_runme.m index 9d55d8be2..72362f451 100644 --- a/Examples/test-suite/octave/null_pointer_runme.m +++ b/Examples/test-suite/octave/null_pointer_runme.m @@ -5,4 +5,4 @@ endif null_pointer; -assert(func([])); +assert(funk([])); diff --git a/Examples/test-suite/octave/octave_cell_deref_runme.m b/Examples/test-suite/octave/octave_cell_deref_runme.m index d00d17282..0a45999d3 100644 --- a/Examples/test-suite/octave/octave_cell_deref_runme.m +++ b/Examples/test-suite/octave/octave_cell_deref_runme.m @@ -5,8 +5,8 @@ endif octave_cell_deref; -assert(func("hello")); -assert(func({"hello"})); +assert(funk("hello")); +assert(funk({"hello"})); c = func2(); assert(strcmp(c{1}, "hello")); diff --git a/Examples/test-suite/octave_cell_deref.i b/Examples/test-suite/octave_cell_deref.i index 2e92ec4de..272ba7c99 100644 --- a/Examples/test-suite/octave_cell_deref.i +++ b/Examples/test-suite/octave_cell_deref.i @@ -1,7 +1,7 @@ %module octave_cell_deref %inline { - bool func(const char* s) { + bool funk(const char* s) { return !strcmp("hello",s); } diff --git a/Examples/test-suite/perl5/README b/Examples/test-suite/perl5/README index 804dec8e8..f15c07849 100644 --- a/Examples/test-suite/perl5/README +++ b/Examples/test-suite/perl5/README @@ -6,7 +6,7 @@ Test::More Support == Test::More is a standard perl test harness tool. -Support was added for for using Test::More in 1.3.28. +Support was added for using Test::More in 1.3.28. If adding a new test to this suite, please use Test::More. There are a few legacy test cases which do not use Test::More and these ought to be converted: diff --git a/Examples/test-suite/perl5/run-perl-test.pl b/Examples/test-suite/perl5/run-perl-test.pl index 106bf002b..5ea4e5115 100644 --- a/Examples/test-suite/perl5/run-perl-test.pl +++ b/Examples/test-suite/perl5/run-perl-test.pl @@ -7,7 +7,7 @@ use strict; my $command = shift @ARGV; -my $output = `$^X $command 2>&1`; +my $output = `$^X -I. $command 2>&1`; die "SWIG Perl test failed: \n\n$output\n" if $?; diff --git a/Examples/test-suite/php/Makefile.in b/Examples/test-suite/php/Makefile.in index c554e2b17..64f0d1f9d 100644 --- a/Examples/test-suite/php/Makefile.in +++ b/Examples/test-suite/php/Makefile.in @@ -14,6 +14,7 @@ CPP_TEST_CASES += \ li_factory \ php_iterator \ php_namewarn_rename \ + php_pragma \ include $(srcdir)/../common.mk diff --git a/Examples/test-suite/php/php_pragma_runme.php b/Examples/test-suite/php/php_pragma_runme.php new file mode 100644 index 000000000..ae92f6818 --- /dev/null +++ b/Examples/test-suite/php/php_pragma_runme.php @@ -0,0 +1,12 @@ +getVersion(),"1.5==version(php_pragma)"); + +check::done(); + +?> + diff --git a/Examples/test-suite/php/preproc_constants_c_runme.php b/Examples/test-suite/php/preproc_constants_c_runme.php index af9b76e1c..20868dcc0 100644 --- a/Examples/test-suite/php/preproc_constants_c_runme.php +++ b/Examples/test-suite/php/preproc_constants_c_runme.php @@ -62,5 +62,8 @@ check::equal(gettype(preproc_constants_c::EXPR_OR), "integer", "preproc_constant check::equal(gettype(preproc_constants_c::EXPR_LAND), "integer", "preproc_constants.EXPR_LAND has unexpected type"); check::equal(gettype(preproc_constants_c::EXPR_LOR), "integer", "preproc_constants.EXPR_LOR has unexpected type"); check::equal(gettype(preproc_constants_c::EXPR_CONDITIONAL), "double", "preproc_constants.EXPR_CONDITIONAL has unexpected type"); +check::equal(gettype(preproc_constants_c::EXPR_MIXED1), "double", "preproc_constants.EXPR_MIXED1 has unexpected type"); +check::equal(gettype(preproc_constants_c::EXPR_WCHAR_MAX), "integer", "preproc_constants.EXPR_WCHAR_MAX has unexpected type"); +check::equal(gettype(preproc_constants_c::EXPR_WCHAR_MIN), "integer", "preproc_constants.EXPR_WCHAR_MIN has unexpected type"); ?> diff --git a/Examples/test-suite/php/preproc_constants_runme.php b/Examples/test-suite/php/preproc_constants_runme.php index 5c9119b3e..bd216c269 100644 --- a/Examples/test-suite/php/preproc_constants_runme.php +++ b/Examples/test-suite/php/preproc_constants_runme.php @@ -61,5 +61,8 @@ check::equal(gettype(preproc_constants::EXPR_OR), "integer", "preproc_constants. check::equal(gettype(preproc_constants::EXPR_LAND), "boolean", "preproc_constants.EXPR_LAND has unexpected type"); check::equal(gettype(preproc_constants::EXPR_LOR), "boolean", "preproc_constants.EXPR_LOR has unexpected type"); check::equal(gettype(preproc_constants::EXPR_CONDITIONAL), "double", "preproc_constants.EXPR_CONDITIONAL has unexpected type"); +check::equal(gettype(preproc_constants::EXPR_MIXED1), "double", "preproc_constants.EXPR_MIXED1 has unexpected type"); +check::equal(gettype(preproc_constants::EXPR_WCHAR_MAX), "integer", "preproc_constants.EXPR_WCHAR_MAX has unexpected type"); +check::equal(gettype(preproc_constants::EXPR_WCHAR_MIN), "integer", "preproc_constants.EXPR_WCHAR_MIN has unexpected type"); ?> diff --git a/Examples/test-suite/php5/Makefile.in b/Examples/test-suite/php5/Makefile.in index 391ca2c53..179ce59d6 100644 --- a/Examples/test-suite/php5/Makefile.in +++ b/Examples/test-suite/php5/Makefile.in @@ -14,6 +14,7 @@ CPP_TEST_CASES += \ li_factory \ php_iterator \ php_namewarn_rename \ + php_pragma \ include $(srcdir)/../common.mk diff --git a/Examples/test-suite/php5/php_pragma_runme.php b/Examples/test-suite/php5/php_pragma_runme.php new file mode 100644 index 000000000..c76cfc9b5 --- /dev/null +++ b/Examples/test-suite/php5/php_pragma_runme.php @@ -0,0 +1,11 @@ +getVersion(),"1.5==version(php_pragma)"); + +check::done(); + +?> diff --git a/Examples/test-suite/php5/preproc_constants_c_runme.php b/Examples/test-suite/php5/preproc_constants_c_runme.php index 1ea01950e..d55d4233d 100644 --- a/Examples/test-suite/php5/preproc_constants_c_runme.php +++ b/Examples/test-suite/php5/preproc_constants_c_runme.php @@ -62,5 +62,8 @@ check::equal(gettype(preproc_constants_c::EXPR_OR), "integer", "preproc_constant check::equal(gettype(preproc_constants_c::EXPR_LAND), "integer", "preproc_constants.EXPR_LAND has unexpected type"); check::equal(gettype(preproc_constants_c::EXPR_LOR), "integer", "preproc_constants.EXPR_LOR has unexpected type"); check::equal(gettype(preproc_constants_c::EXPR_CONDITIONAL), "double", "preproc_constants.EXPR_CONDITIONAL has unexpected type"); +check::equal(gettype(preproc_constants_c::EXPR_MIXED1), "double", "preproc_constants.EXPR_MIXED1 has unexpected type"); +check::equal(gettype(preproc_constants_c::EXPR_WCHAR_MAX), "integer", "preproc_constants.EXPR_WCHAR_MAX has unexpected type"); +check::equal(gettype(preproc_constants_c::EXPR_WCHAR_MIN), "integer", "preproc_constants.EXPR_WCHAR_MIN has unexpected type"); ?> diff --git a/Examples/test-suite/php5/preproc_constants_runme.php b/Examples/test-suite/php5/preproc_constants_runme.php index fb9ee4fa7..01137b06b 100644 --- a/Examples/test-suite/php5/preproc_constants_runme.php +++ b/Examples/test-suite/php5/preproc_constants_runme.php @@ -70,5 +70,8 @@ check::equal(gettype(preproc_constants::EXPR_LAND), "integer", "preproc_constant check::equal(gettype(preproc_constants::EXPR_LOR), "integer", "preproc_constants.EXPR_LOR has unexpected type"); check::equal(gettype(preproc_constants::EXPR_CONDITIONAL), "double", "preproc_constants.EXPR_CONDITIONAL has unexpected type"); +check::equal(gettype(preproc_constants::EXPR_MIXED1), "double", "preproc_constants.EXPR_MIXED1 has unexpected type"); +check::equal(gettype(preproc_constants::EXPR_WCHAR_MAX), "integer", "preproc_constants.EXPR_WCHAR_MAX has unexpected type"); +check::equal(gettype(preproc_constants::EXPR_WCHAR_MIN), "integer", "preproc_constants.EXPR_WCHAR_MIN has unexpected type"); ?> diff --git a/Examples/test-suite/php_pragma.i b/Examples/test-suite/php_pragma.i new file mode 100644 index 000000000..4d14f1357 --- /dev/null +++ b/Examples/test-suite/php_pragma.i @@ -0,0 +1,6 @@ +// Test pragma of php - pragma version. + +%module php_pragma + +%pragma(php) version= "1.5" + diff --git a/Examples/test-suite/preproc.i b/Examples/test-suite/preproc.i index f236bfdff..8d9c5176f 100644 --- a/Examples/test-suite/preproc.i +++ b/Examples/test-suite/preproc.i @@ -370,3 +370,21 @@ int methodX(int x); int methodX(int x) { return x+100; } %} +// Comma in macro - Github issue #974 +%inline %{ +#define swig__attribute__(x) +#define TCX_PACKED(d) d swig__attribute__ ((__packed__)) + + +TCX_PACKED (typedef struct tcxMessageTestImpl +{ + int mHeader; /**< comment */ +}) tcxMessageTest; + + +TCX_PACKED (typedef struct tcxMessageBugImpl +{ + int mBid; /**< Bid price and size, check PresentMap if available in message */ +}) tcxMessageBug; +%} + diff --git a/Examples/test-suite/preproc_constants.i b/Examples/test-suite/preproc_constants.i index 3a999ada3..628cae1dd 100644 --- a/Examples/test-suite/preproc_constants.i +++ b/Examples/test-suite/preproc_constants.i @@ -86,6 +86,10 @@ #define EXPR_LAND 0xFF && 1 #define EXPR_LOR 0xFF || 1 #define EXPR_CONDITIONAL true ? 2 : 2.2 +#define EXPR_MIXED1 (0x80 + 11.1) - 1 + +#define EXPR_WCHAR_MAX (0x7fffffff + L'\0') +#define EXPR_WCHAR_MIN (-EXPR_WCHAR_MAX - 1) #define EXPR_CHAR_COMPOUND_ADD 'A' + 12 #define EXPR_CHAR_COMPOUND_LSHIFT 'B' << 6 diff --git a/Examples/test-suite/primitive_types.i b/Examples/test-suite/primitive_types.i index b9b973a2b..c68b1fc8f 100644 --- a/Examples/test-suite/primitive_types.i +++ b/Examples/test-suite/primitive_types.i @@ -11,6 +11,10 @@ #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif %} // Ruby constant names diff --git a/Examples/test-suite/python/Makefile.in b/Examples/test-suite/python/Makefile.in index 133b7056a..0ea46ee18 100644 --- a/Examples/test-suite/python/Makefile.in +++ b/Examples/test-suite/python/Makefile.in @@ -73,18 +73,21 @@ CPP_TEST_CASES += \ simutry \ std_containers \ swigobject \ - template_matrix + template_matrix \ # li_std_carray # director_profile # python_pybuf +CPP11_TEST_CASES = \ + cpp11_hash_tables \ + C_TEST_CASES += \ file_test \ li_cstring \ li_cwstring \ python_nondynamic \ - python_varargs_typemap + python_varargs_typemap \ # # This test only works with modern C compilers @@ -159,7 +162,7 @@ convert_testcase = \ $(MAKE) $(SCRIPTDIR)/$(py_runme); \ fi -$(SCRIPTDIR)/$(SCRIPTPREFIX)%$(SCRIPTSUFFIX): $(srcdir)/$(SCRIPTPREFIX)%$(PY2SCRIPTSUFFIX) +$(SCRIPTDIR)/$(SCRIPTPREFIX)%$(SCRIPTSUFFIX): $(abspath $(srcdir)/$(SCRIPTPREFIX)%$(PY2SCRIPTSUFFIX)) test x$< = x$@ || cp $< $@ || exit 1 test x$(PY3) = x || $(PY2TO3) -w $@ >/dev/null 2>&1 || exit 1 @@ -179,19 +182,6 @@ clean: rm -f imports_a.py imports_b.py mod_a.py mod_b.py multi_import_a.py rm -f multi_import_b.py packageoption_a.py packageoption_b.py packageoption_c.py -cvsignore: - @echo '*wrap* *.pyc *.so *.dll *.exp *.lib' - @echo Makefile - @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do echo $$i.py; done - @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do if grep -q $${i}_runme.py CVS/Entries ; then echo $${i}_runme.py; fi; done - @echo clientdata_prop_a.py - @echo clientdata_prop_b.py - @echo imports_a.py - @echo imports_b.py - @echo mod_a.py mod_b.py - @echo hugemod.h hugemod_a.i hugemod_b.i hugemod_a.py hugemod_b.py hugemod_runme.py - @echo template_typedef_import.py - hugemod_runme = hugemod$(SCRIPTPREFIX) hugemod: diff --git a/Examples/test-suite/python/autodoc_runme.py b/Examples/test-suite/python/autodoc_runme.py index 474599a50..7635f6c4a 100644 --- a/Examples/test-suite/python/autodoc_runme.py +++ b/Examples/test-suite/python/autodoc_runme.py @@ -201,3 +201,7 @@ check(inspect.getdoc(func_output), "func_output() -> int") check(inspect.getdoc(func_inout), "func_inout(int * INOUT) -> int") check(inspect.getdoc(func_cb), "func_cb(int c, int d) -> int") check(inspect.getdoc(banana), "banana(S a, S b, int c, Integer d)") + +check(inspect.getdoc(TInteger), "Proxy of C++ T< int > class.", "::T< int >") +check(inspect.getdoc(TInteger.__init__), "__init__(TInteger self) -> TInteger", None, skip) +check(inspect.getdoc(TInteger.inout), "inout(TInteger self, TInteger t) -> TInteger") diff --git a/Examples/test-suite/python/complextest_runme.py b/Examples/test-suite/python/complextest_runme.py index 7dd7f5a3b..a55e6098b 100644 --- a/Examples/test-suite/python/complextest_runme.py +++ b/Examples/test-suite/python/complextest_runme.py @@ -15,3 +15,9 @@ try: complextest.Copy_h(v) except: pass + +p = complextest.ComplexPair() +p.z1 = complex(0, 1) +p.z2 = complex(0, -1) +if complextest.Conj(p.z2) != p.z1: + raise RuntimeError, "bad complex mapping" diff --git a/Examples/test-suite/python/cpp11_alternate_function_syntax_runme.py b/Examples/test-suite/python/cpp11_alternate_function_syntax_runme.py index 363736a84..cc7b5cd91 100644 --- a/Examples/test-suite/python/cpp11_alternate_function_syntax_runme.py +++ b/Examples/test-suite/python/cpp11_alternate_function_syntax_runme.py @@ -4,11 +4,20 @@ a = cpp11_alternate_function_syntax.SomeStruct() res = a.addNormal(4, 5) if res != 9: - raise RuntimeError, ("SomeStruct::addNormal(4,5) returns ", - res, " should be 9.") - + raise RuntimeError, ("SomeStruct::addNormal(4,5) returns ", res, " should be 9.") res = a.addAlternate(4, 5) if res != 9: - raise RuntimeError, ("SomeStruct::addAlternate(4,5) returns ", - res, " should be 9.") + raise RuntimeError, ("SomeStruct::addAlternate(4,5) returns ", res, " should be 9.") + +res = a.addAlternateConst(4, 5) +if res != 9: + raise RuntimeError, ("SomeStruct::addAlternateConst(4,5) returns ", res, " should be 9.") + +res = a.addAlternateNoExcept(4, 5) +if res != 9: + raise RuntimeError, ("SomeStruct::addAlternateNoExcept(4,5) returns ", res, " should be 9.") + +res = a.addAlternateConstNoExcept(4, 5) +if res != 9: + raise RuntimeError, ("SomeStruct::addAlternateConstNoExcept(4,5) returns ", res, " should be 9.") diff --git a/Examples/test-suite/python/cpp11_hash_tables_runme.py b/Examples/test-suite/python/cpp11_hash_tables_runme.py new file mode 100644 index 000000000..d8c63208a --- /dev/null +++ b/Examples/test-suite/python/cpp11_hash_tables_runme.py @@ -0,0 +1,54 @@ +import cpp11_hash_tables + +def swig_assert_equal(a, b): + if a != b: + raise RuntimeError(str(a) + " != " + str(b)) + +for x in [cpp11_hash_tables.MapIntInt({1:7}), + cpp11_hash_tables.MultiMapIntInt({1:7}), +# TODO: fix for -builtin +# cpp11_hash_tables.UnorderedMapIntInt({1:7}), +# cpp11_hash_tables.UnorderedMultiMapIntInt({1:7}) + ]: + + swig_assert_equal([(k, v) for k, v in x.iteritems()], [(1, 7)]) + + swig_assert_equal(x[1], 7) + swig_assert_equal(2 in x, False) + x[2] = 9 + swig_assert_equal(x[2], 9) + del x[2] + swig_assert_equal(2 in x, False) + swig_assert_equal(x.empty(), False) + del x[1] + swig_assert_equal(x.empty(), True) + swig_assert_equal(1 in x, False) + +for x in [cpp11_hash_tables.MultiMapIntInt({1:7}), + cpp11_hash_tables.UnorderedMultiMapIntInt({1:7})]: + x[1] = 9 +# TODO: fix for -builtin +# swig_assert_equal(sorted([v for k, v in x.iteritems()]), [7, 9]) +# Is this broken?... +# swig_assert_equal(sorted([v for v in x[1]]), [7, 9]) + +for x in [cpp11_hash_tables.SetInt([1]), + cpp11_hash_tables.MultiSetInt([1]), + cpp11_hash_tables.UnorderedSetInt([1]), + cpp11_hash_tables.UnorderedMultiSetInt([1])]: + + swig_assert_equal([e for e in x], [1]) + + swig_assert_equal(1 in x, True) + swig_assert_equal(2 in x, False) + x.append(2) + swig_assert_equal(2 in x, True) + x.erase(2) + swig_assert_equal(x.empty(), False) + x.erase(1) + swig_assert_equal(x.empty(), True) + +for x in [cpp11_hash_tables.MultiSetInt([1]), + cpp11_hash_tables.UnorderedMultiSetInt([1])]: + x.append(1) + swig_assert_equal(x.count(1), 2) diff --git a/Examples/test-suite/python/cpp11_ref_qualifiers_runme.py b/Examples/test-suite/python/cpp11_ref_qualifiers_runme.py new file mode 100644 index 000000000..d3aa98c47 --- /dev/null +++ b/Examples/test-suite/python/cpp11_ref_qualifiers_runme.py @@ -0,0 +1,45 @@ +import cpp11_ref_qualifiers + +h = cpp11_ref_qualifiers.Host() + +# Basic testing +h.h1() +h.h2() +h.h6() +h.h7() + +h.h() + +# %feature testing +f = cpp11_ref_qualifiers.Features() +if f.F1() != "F1": + raise RuntimeException("Fail") +if f.F2() != "F2": + raise RuntimeException("Fail") +if f.F3() != "F3": + raise RuntimeException("Fail") + +if f.C1(0) != "C1": + raise RuntimeException("Fail") +if f.C2(0) != "C2": + raise RuntimeException("Fail") +if f.C3(0) != "C3": + raise RuntimeException("Fail") + +# %rename testing +r = cpp11_ref_qualifiers.Renames() +r.RR1() +r.RR2() +r.RR3() + +r.SS1(0) +r.SS2(0) +r.SS3(0) + +# Conversion operators +co = cpp11_ref_qualifiers.ConversionOperators() +s = co.StringConvertCopy() +s = co.StringConvertMove() + +co2 = cpp11_ref_qualifiers.ConversionOperators2() +s = co2.StringConvertMove() diff --git a/Examples/test-suite/python/cpp11_ref_qualifiers_rvalue_unignore_runme.py b/Examples/test-suite/python/cpp11_ref_qualifiers_rvalue_unignore_runme.py new file mode 100644 index 000000000..6352c79c2 --- /dev/null +++ b/Examples/test-suite/python/cpp11_ref_qualifiers_rvalue_unignore_runme.py @@ -0,0 +1,4 @@ +import cpp11_ref_qualifiers_rvalue_unignore + +cpp11_ref_qualifiers_rvalue_unignore.RefQualifier().m1() +cpp11_ref_qualifiers_rvalue_unignore.RefQualifier().m2() diff --git a/Examples/test-suite/python/default_args_runme.py b/Examples/test-suite/python/default_args_runme.py index 9d275e4a1..ddaf2cd4f 100644 --- a/Examples/test-suite/python/default_args_runme.py +++ b/Examples/test-suite/python/default_args_runme.py @@ -32,6 +32,8 @@ def run(module_name): f.newname() f.newname(1) + f.defaulted1() + f.defaulted2() if f.double_if_void_ptr_is_null(2, None) != 4: raise RuntimeError @@ -113,15 +115,39 @@ def run(module_name): if Klass_inc().val != 0: raise RuntimeError("Klass::inc failed") - default_args.trickyvalue1(10) - default_args.trickyvalue1(10, 10) - default_args.trickyvalue2(10) - default_args.trickyvalue2(10, 10) - default_args.trickyvalue3(10) - default_args.trickyvalue3(10, 10) + tricky_failure = False + tricky = default_args.TrickyInPython() + if tricky.value_m1(10) != -1: + print "trickyvalue_m1 failed" + tricky_failure = True + if tricky.value_m1(10, 10) != 10: + print "trickyvalue_m1 failed" + tricky_failure = True + if tricky.value_0xabcdef(10) != 0xabcdef: + print "trickyvalue_0xabcdef failed" + tricky_failure = True + if tricky.value_0644(10) != 420: + print "trickyvalue_0644 failed" + tricky_failure = True + if tricky.value_perm(10) != 420: + print "trickyvalue_perm failed" + tricky_failure = True + if tricky.value_m01(10) != -1: + print "trickyvalue_m01 failed" + tricky_failure = True + if not tricky.booltest2(): + print "booltest2 failed" + tricky_failure = True + + if tricky_failure: + raise RuntimeError + default_args.seek() default_args.seek(10) + if not default_args.booltest(): + raise RuntimeError("booltest failed") + if default_args.slightly_off_square(10) != 102: raise RuntimeError diff --git a/Examples/test-suite/python/director_smartptr_runme.py b/Examples/test-suite/python/director_smartptr_runme.py index c8bab9d7a..23e22d0fb 100644 --- a/Examples/test-suite/python/director_smartptr_runme.py +++ b/Examples/test-suite/python/director_smartptr_runme.py @@ -15,6 +15,20 @@ class director_smartptr_MyBarFoo(Foo): def makeFoo(self): return Foo() +class director_smartptr_MyBarFooDerived(FooDerived): + + def ping(self): + return "director_smartptr_MyBarFooDerived.ping()" + + def pong(self): + return "director_smartptr_MyBarFooDerived.pong();" + self.ping() + + def upcall(self, fooBarPtr): + return "overrideDerived;" + fooBarPtr.FooBarDo() + + def makeFoo(self): + return Foo() + def check(got, expected): if (got != expected): raise RuntimeError, "Failed, got: " + got + " expected: " + expected @@ -35,3 +49,8 @@ myFoo2 = Foo().makeFoo() check(myFoo2.pong(), "Foo::pong();Foo::ping()") check(Foo.callPong(myFoo2), "Foo::pong();Foo::ping()") check(myFoo2.upcall(FooBar()), "Bar::Foo2::Foo2Bar()") + +myBarFooDerived = director_smartptr_MyBarFooDerived() +check(myBarFooDerived.ping(), "director_smartptr_MyBarFooDerived.ping()") +check(FooDerived.callPong(myBarFooDerived), "director_smartptr_MyBarFooDerived.pong();director_smartptr_MyBarFooDerived.ping()") +check(FooDerived.callUpcall(myBarFooDerived, fooBar), "overrideDerived;Bar::Foo2::Foo2Bar()") diff --git a/Examples/test-suite/python/member_pointer_const_runme.py b/Examples/test-suite/python/member_pointer_const_runme.py new file mode 100644 index 000000000..ad6c2df99 --- /dev/null +++ b/Examples/test-suite/python/member_pointer_const_runme.py @@ -0,0 +1,51 @@ +# Example using pointers to member functions + +from member_pointer_const import * + + +def check(what, expected, actual): + if expected != actual: + raise RuntimeError( + "Failed: ", what, " Expected: ", expected, " Actual: ", actual) + +# Get the pointers + +area_pt = areapt() +perim_pt = perimeterpt() + +# Create some objects + +s = Square(10) + +# Do some calculations + +check("Square area ", 100.0, do_op(s, area_pt)) +check("Square perim", 40.0, do_op(s, perim_pt)) + +memberPtr = cvar.areavar +memberPtr = cvar.perimetervar + +# Try the variables +check("Square area ", 100.0, do_op(s, cvar.areavar)) +check("Square perim", 40.0, do_op(s, cvar.perimetervar)) + +# Modify one of the variables +cvar.areavar = perim_pt + +check("Square perimeter", 40.0, do_op(s, cvar.areavar)) + +# Try the constants + +memberPtr = AREAPT +memberPtr = PERIMPT +memberPtr = NULLPT + +check("Square area ", 100.0, do_op(s, AREAPT)) +check("Square perim", 40.0, do_op(s, PERIMPT)) + +# Typedefs +check("Square perim", 40.0, do_op_td(s, perim_pt)); + +check("Add by value", 3, call1(ADD_BY_VALUE, 1, 2)) +#check("Add by pointer", 7, call2(ADD_BY_POINTER, 3, 4)) +#check("Add by reference", 11, call3(ADD_BY_REFERENCE, 5, 6)) diff --git a/Examples/test-suite/python/member_pointer_runme.py b/Examples/test-suite/python/member_pointer_runme.py index 5ae7ab9a4..f6f165863 100644 --- a/Examples/test-suite/python/member_pointer_runme.py +++ b/Examples/test-suite/python/member_pointer_runme.py @@ -43,6 +43,9 @@ memberPtr = NULLPT check("Square area ", 100.0, do_op(s, AREAPT)) check("Square perim", 40.0, do_op(s, PERIMPT)) +# Typedefs +check("Square perim", 40.0, do_op_td(s, perim_pt)); + check("Add by value", 3, call1(ADD_BY_VALUE, 1, 2)) check("Add by pointer", 7, call2(ADD_BY_POINTER, 3, 4)) check("Add by reference", 11, call3(ADD_BY_REFERENCE, 5, 6)) diff --git a/Examples/test-suite/python/preproc_runme.py b/Examples/test-suite/python/preproc_runme.py index 99a6d0307..071362bc3 100644 --- a/Examples/test-suite/python/preproc_runme.py +++ b/Examples/test-suite/python/preproc_runme.py @@ -14,3 +14,6 @@ if 2 * preproc.one != preproc.two: if preproc.methodX(99) != 199: raise RuntimeError + +t1 = preproc.tcxMessageTest() +t2 = preproc.tcxMessageBug() diff --git a/Examples/test-suite/python/python_append_runme.py b/Examples/test-suite/python/python_append_runme.py index 6675f3509..ce5514dff 100644 --- a/Examples/test-suite/python/python_append_runme.py +++ b/Examples/test-suite/python/python_append_runme.py @@ -9,7 +9,7 @@ if is_python_builtin(): exit(0) t = Test() -t.func() +t.funk() if is_new_style_class(Test): t.static_func() else: diff --git a/Examples/test-suite/python/python_richcompare_runme.py b/Examples/test-suite/python/python_richcompare_runme.py index a68da2f98..247660301 100644 --- a/Examples/test-suite/python/python_richcompare_runme.py +++ b/Examples/test-suite/python/python_richcompare_runme.py @@ -1,4 +1,13 @@ import python_richcompare +import sys + +def check_unorderable_types(exception): +# if str(exception).find("unorderable types") == -1: +# raise RuntimeError("A TypeError 'unorderable types' exception was expected"), None, sys.exc_info()[2] + pass # Exception message seems to vary from one version of Python to another + +def is_new_style_class(cls): + return hasattr(cls, "__class__") base1 = python_richcompare.BaseClass(1) base2 = python_richcompare.BaseClass(2) @@ -65,6 +74,18 @@ if (b1 == a1): raise RuntimeError( "Comparing equivalent instances of different subclasses, == returned True") +# Check comparison to other objects +#------------------------------------------------------------------------------- +if (base1 == 42) : + raise RuntimeError("Comparing class to incompatible type, == returned True") +if not (base1 != 42) : + raise RuntimeError("Comparing class to incompatible type, != returned False") + +if (a1 == 42) : + raise RuntimeError("Comparing class (with overloaded operator ==) to incompatible type, == returned True") +if not (a1 != 42) : + raise RuntimeError("Comparing class (with overloaded operator ==) to incompatible type, != returned False") + # Check inequalities #------------------------------------------------------------------------- @@ -80,6 +101,42 @@ if not (a2 >= b2): if not (a2 <= b2): raise RuntimeError("operator<= failed") +# Check inequalities to other objects +#------------------------------------------------------------------------------- +if is_new_style_class(python_richcompare.BaseClass): + # Skip testing -classic option + if sys.version_info[0:2] < (3, 0): + if (base1 < 42): + raise RuntimeError("Comparing class to incompatible type, < returned True") + if (base1 <= 42): + raise RuntimeError("Comparing class to incompatible type, <= returned True") + if not (base1 > 42): + raise RuntimeError("Comparing class to incompatible type, > returned False") + if not (base1 >= 42): + raise RuntimeError("Comparing class to incompatible type, >= returned False") + else: + # Python 3 throws: TypeError: unorderable types + try: + res = base1 < 42 + raise RuntimeError("Failed to throw") + except TypeError,e: + check_unorderable_types(e) + try: + res = base1 <= 42 + raise RuntimeError("Failed to throw") + except TypeError,e: + check_unorderable_types(e) + try: + res = base1 > 42 + raise RuntimeError("Failed to throw") + except TypeError,e: + check_unorderable_types(e) + try: + res = base1 >= 42 + raise RuntimeError("Failed to throw") + except TypeError,e: + check_unorderable_types(e) + # Check inequalities used for ordering #------------------------------------------------------------------------- diff --git a/Examples/test-suite/python/template_using_directive_typedef_runme.py b/Examples/test-suite/python/template_using_directive_typedef_runme.py new file mode 100644 index 000000000..363a3b754 --- /dev/null +++ b/Examples/test-suite/python/template_using_directive_typedef_runme.py @@ -0,0 +1,15 @@ +import template_using_directive_typedef + +vo = template_using_directive_typedef.Vector_Obj(); + +h = template_using_directive_typedef.Holder(); +h.holder_use1(vo, vo, vo); +h.holder_use2(vo, vo, vo); +h.holder_use3(vo, vo, vo); + +template_using_directive_typedef.tns_holder_use(vo, vo); +template_using_directive_typedef.tns_use(vo, vo, vo); +template_using_directive_typedef.global_holder_use(vo); +template_using_directive_typedef.global_use(vo, vo, vo); +template_using_directive_typedef.ns1_holder_use(vo); +template_using_directive_typedef.ns2_holder_use(vo, vo, vo, vo); diff --git a/Examples/test-suite/python/typedef_funcptr_runme.py b/Examples/test-suite/python/typedef_funcptr_runme.py new file mode 100644 index 000000000..a186963f7 --- /dev/null +++ b/Examples/test-suite/python/typedef_funcptr_runme.py @@ -0,0 +1,20 @@ +import typedef_funcptr + +a = 100 +b = 10 + +if typedef_funcptr.do_op(a,b,typedef_funcptr.addf) != 110: + raise RuntimeError("addf failed") +if typedef_funcptr.do_op(a,b,typedef_funcptr.subf) != 90: + raise RuntimeError("subf failed") + +if typedef_funcptr.do_op_typedef_int(a,b,typedef_funcptr.addf) != 110: + raise RuntimeError("addf failed") +if typedef_funcptr.do_op_typedef_int(a,b,typedef_funcptr.subf) != 90: + raise RuntimeError("subf failed") + +if typedef_funcptr.do_op_typedef_Integer(a,b,typedef_funcptr.addf) != 110: + raise RuntimeError("addf failed") +if typedef_funcptr.do_op_typedef_Integer(a,b,typedef_funcptr.subf) != 90: + raise RuntimeError("subf failed") + diff --git a/Examples/test-suite/python/typemap_template_typedef_runme.py b/Examples/test-suite/python/typemap_template_typedef_runme.py new file mode 100644 index 000000000..a2458367e --- /dev/null +++ b/Examples/test-suite/python/typemap_template_typedef_runme.py @@ -0,0 +1,32 @@ +from typemap_template_typedef import * + +def check(got, expected): + if got != expected: + raise RuntimeError("got: " + str(got) + " expected: " + str(expected)) + +x = XXXInt() + +check(x.aa1(0), 0) +check(x.aa2(0), 55) +check(x.aa3(0), 0) +check(aa1(0), 0) +check(aa2(0), 0) + +check(x.bb1(0), 0) +check(x.bb2(0), 66) +check(x.bb3(0), 0) +check(bb1(0), 0) +check(bb2(0), 0) + +check(x.cc1(0), 0) +check(x.cc2(0), 77) +check(x.cc3(0), 77) +check(cc1(0), 0) +check(cc2(0), 0) + +check(x.dd1(0), 0) +check(x.dd2(0), 88) +check(x.dd3(0), 0) +check(dd1(0), 0) +check(dd2(0), 0) + diff --git a/Examples/test-suite/python_append.i b/Examples/test-suite/python_append.i index 2a71b5784..049494319 100644 --- a/Examples/test-suite/python_append.i +++ b/Examples/test-suite/python_append.i @@ -17,11 +17,11 @@ def clearstaticpath(): staticfuncpath = None %} -%pythonappend Test::func %{ +%pythonappend Test::funk %{ funcpath = os.path.dirname(funcpath) %} -%pythonprepend Test::func %{ +%pythonprepend Test::funk %{ global funcpath funcpath = mypath %} @@ -46,7 +46,7 @@ import os.path class Test { public: static void static_func() {}; - void func() {}; + void funk() {}; }; #ifdef SWIGPYTHON_BUILTIN diff --git a/Examples/test-suite/python_builtin.i b/Examples/test-suite/python_builtin.i index d4e245dc4..21cbda3e9 100644 --- a/Examples/test-suite/python_builtin.i +++ b/Examples/test-suite/python_builtin.i @@ -6,6 +6,10 @@ #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif %} %inline %{ @@ -223,3 +227,12 @@ void Dealloc2Destroyer(PyObject *v) { } }; %} + +%{ +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +%} diff --git a/Examples/test-suite/ruby/Makefile.in b/Examples/test-suite/ruby/Makefile.in index d94ac7061..ee9d390fe 100644 --- a/Examples/test-suite/ruby/Makefile.in +++ b/Examples/test-suite/ruby/Makefile.in @@ -11,23 +11,36 @@ top_srcdir = @top_srcdir@ top_builddir = @top_builddir@ CPP_TEST_CASES = \ + li_boost_shared_ptr_director \ li_cstring \ li_factory \ li_std_functors \ + li_std_list \ li_std_multimap \ li_std_pair_lang_object \ li_std_queue \ li_std_set \ li_std_stack \ + li_std_wstring \ primitive_types \ ruby_keywords \ ruby_minherit_shared_ptr \ ruby_naming \ ruby_track_objects \ ruby_track_objects_directors \ - std_containers -# ruby_li_std_speed -# stl_new + std_containers \ +# ruby_li_std_speed \ +# stl_new \ + +CPP11_TEST_CASES = \ + cpp11_hash_tables \ + cpp11_shared_ptr_const \ + cpp11_shared_ptr_nullptr_in_containers \ + cpp11_shared_ptr_upcast \ + cpp11_std_unordered_map \ + cpp11_std_unordered_multimap \ + cpp11_std_unordered_multiset \ + cpp11_std_unordered_set \ C_TEST_CASES += \ li_cstring \ diff --git a/Examples/test-suite/ruby/cpp11_hash_tables_runme.rb b/Examples/test-suite/ruby/cpp11_hash_tables_runme.rb new file mode 100644 index 000000000..203b0ce06 --- /dev/null +++ b/Examples/test-suite/ruby/cpp11_hash_tables_runme.rb @@ -0,0 +1,61 @@ +require 'swig_assert' +require 'cpp11_hash_tables' + +[Cpp11_hash_tables::MapIntInt.new({1=>7}), + Cpp11_hash_tables::MultiMapIntInt.new({1=>7}), + Cpp11_hash_tables::UnorderedMapIntInt.new({1=>7}), + Cpp11_hash_tables::UnorderedMultiMapIntInt.new({1=>7})].each{|x| + + swig_assert_equal("x.find_all{|e,k| e == 1}", "[[1,7]]", binding) + + swig_assert_equal("x[1]", "7", binding) + swig_assert_equal("x[2]", "nil", binding) + x[2] = 9 + swig_assert_equal("x[2]", "9", binding) + x.delete(2) + swig_assert_equal("x[2]", "nil", binding) + swig_assert_equal("x.empty?", "false", binding) + x.delete(1) + swig_assert_equal("x.empty?", "true", binding) + swig_assert_equal("x.include?(1)", "false", binding) +} + +[Cpp11_hash_tables::MultiMapIntInt.new({1=>7}), + Cpp11_hash_tables::UnorderedMultiMapIntInt.new({1=>7})].each{|x| + x[1] = 9 + swig_assert_equal("x[1].sort", "[7,9]", binding) +} + +[Cpp11_hash_tables::SetInt.new([1]), + Cpp11_hash_tables::MultiSetInt.new([1]), + Cpp11_hash_tables::UnorderedSetInt.new([1]), + Cpp11_hash_tables::UnorderedMultiSetInt.new([1])].each{|x| + + swig_assert_equal("x.find_all{|e| e == 1}", "[1]", binding) + + swig_assert_equal("x.include?(1)", "true", binding) + swig_assert_equal("x.include?(2)", "false", binding) + x << 2 + swig_assert_equal("x.include?(2)", "true", binding) + x.erase(2) + swig_assert_equal("x.empty?", "false", binding) + x.erase(1) + swig_assert_equal("x.empty?", "true", binding) +} + +[Cpp11_hash_tables::MultiSetInt.new([1]), + Cpp11_hash_tables::UnorderedMultiSetInt.new([1])].each{|x| + x << 1 + swig_assert_equal("x.count(1)", "2", binding) +} + +[Cpp11_hash_tables::MapIntInt, + Cpp11_hash_tables::MultiMapIntInt, + Cpp11_hash_tables::UnorderedMapIntInt, + Cpp11_hash_tables::UnorderedMultiMapIntInt, + Cpp11_hash_tables::SetInt, + Cpp11_hash_tables::MultiSetInt, + Cpp11_hash_tables::UnorderedSetInt, + Cpp11_hash_tables::UnorderedMultiSetInt].each{|k| + swig_assert("k.include?(Enumerable)", binding) +} diff --git a/Examples/test-suite/ruby/cpp11_shared_ptr_const_runme.rb b/Examples/test-suite/ruby/cpp11_shared_ptr_const_runme.rb new file mode 100644 index 000000000..149aa0898 --- /dev/null +++ b/Examples/test-suite/ruby/cpp11_shared_ptr_const_runme.rb @@ -0,0 +1,9 @@ +require "swig_assert" +require "cpp11_shared_ptr_const" + +include Cpp11_shared_ptr_const + +swig_assert_equal_simple(1, foo( Foo.new(1) ).get_m ) +swig_assert_equal_simple(7, const_foo( Foo.new(7) ).get_m ) +swig_assert_equal_simple(7, foo_vec( Foo.new(7) )[0].get_m ) +swig_assert_equal_simple(8, const_foo_vec( Foo.new(8) )[0].get_m ) diff --git a/Examples/test-suite/ruby/cpp11_shared_ptr_nullptr_in_containers_runme.rb b/Examples/test-suite/ruby/cpp11_shared_ptr_nullptr_in_containers_runme.rb new file mode 100644 index 000000000..9d8b3c050 --- /dev/null +++ b/Examples/test-suite/ruby/cpp11_shared_ptr_nullptr_in_containers_runme.rb @@ -0,0 +1,16 @@ +require "cpp11_shared_ptr_nullptr_in_containers" + +include Cpp11_shared_ptr_nullptr_in_containers + +a = ret_vec_c_shared_ptr() +raise unless a[0].get_m == 0 +raise unless a[1] == nil +raise unless a[2].get_m == 2 + +a = ret_arg_vec([C.new(7), nil, C.new(9)]) +raise unless a[0].get_m == 7 +raise unless a[1] == nil +raise unless a[2].get_m == 9 + +raise unless is_last_null([C.new(7), C.new(8), nil]) +raise if is_last_null([C.new(7), C.new(8)]) diff --git a/Examples/test-suite/ruby/cpp11_shared_ptr_upcast_runme.rb b/Examples/test-suite/ruby/cpp11_shared_ptr_upcast_runme.rb new file mode 100644 index 000000000..000b9b6a9 --- /dev/null +++ b/Examples/test-suite/ruby/cpp11_shared_ptr_upcast_runme.rb @@ -0,0 +1,60 @@ +require 'swig_assert' +require 'cpp11_shared_ptr_upcast' + + +include Cpp11_shared_ptr_upcast + +# non-overloaded +swig_assert_equal_simple( 7, derived_num1(Derived.new(7)) ) +swig_assert_equal_simple( 7, derived_num2([Derived.new(7)]) ) +swig_assert_equal_simple( 7, derived_num3({0 => Derived.new(7)}) ) + +swig_assert_equal_simple(-1, base_num1(Derived.new(7)) ) +swig_assert_equal_simple(-1, base_num2([Derived.new(7)]) ) +swig_assert_equal_simple(-1, base_num3({0 => Derived.new(7)}) ) + +swig_assert_equal_simple( 999, derived_num1(nil) ) +swig_assert_equal_simple( 999, derived_num2([nil]) ) +swig_assert_equal_simple( 999, derived_num3({0 => nil}) ) + +swig_assert_equal_simple( 999, base_num1(nil) ) +swig_assert_equal_simple( 999, base_num2([nil]) ) +swig_assert_equal_simple( 999, base_num3({0 => nil}) ) + +# overloaded +swig_assert_equal_simple( 7, derived_num(Derived.new(7)) ) +swig_assert_equal_simple( 7, derived_num([Derived.new(7)]) ) +swig_assert_equal_simple( 7, derived_num({0 => Derived.new(7)}) ) + +swig_assert_equal_simple(-1, base_num(Derived.new(7)) ) +swig_assert_equal_simple(-1, base_num([Derived.new(7)]) ) +swig_assert_equal_simple(-1, base_num({0 => Derived.new(7)}) ) + +# ptr to shared_ptr +swig_assert_equal_simple( 7, derived2_num1(Derived2.new(7)) ) +swig_assert_equal_simple( 7, derived2_num2([Derived2.new(7)]) ) +swig_assert_equal_simple( 7, derived2_num3({0 => Derived2.new(7)}) ) + +swig_assert_equal_simple( -1, base2_num1(Derived2.new(7)) ) + +begin + # Upcast for pointers to shared_ptr in this generic framework has not been implemented + swig_assert_equal_simple( -1, base2_num2([Derived2.new(7)]) ) + raise RuntimeError, "Failed to catch TypeError" +rescue TypeError +end +begin + # Upcast for pointers to shared_ptr in this generic framework has not been implemented + swig_assert_equal_simple( -1, base2_num3({0 => Derived2.new(7)}) ) + raise RuntimeError, "Failed to catch TypeError" +rescue TypeError +end + +swig_assert_equal_simple( 888, derived2_num1(nil) ) +swig_assert_equal_simple( 999, derived2_num2([nil]) ) # although 888 would be more consistent +swig_assert_equal_simple( 999, derived2_num3({0 => nil}) ) # although 888 would be more consistent + +swig_assert_equal_simple( 888, base2_num1(nil) ) +swig_assert_equal_simple( 999, base2_num2([nil]) ) # although 888 would be more consistent +swig_assert_equal_simple( 999, base2_num3({0 => nil}) ) # although 888 would be more consistent + diff --git a/Examples/test-suite/ruby/director_smartptr_runme.rb b/Examples/test-suite/ruby/director_smartptr_runme.rb index 8b4bd3d6d..46ef8b1b5 100644 --- a/Examples/test-suite/ruby/director_smartptr_runme.rb +++ b/Examples/test-suite/ruby/director_smartptr_runme.rb @@ -30,6 +30,25 @@ class Director_smartptr_MyBarFoo < Foo end end +class Director_smartptr_MyBarFooDerived < FooDerived + + def ping() + return "director_smartptr_MyBarFooDerived.ping()" + end + + def pong() + return "director_smartptr_MyBarFooDerived.pong();" + ping() + end + + def upcall(fooBarPtr) + return "overrideDerived;" + fooBarPtr.FooBarDo() + end + + def makeFoo() + return Foo.new() + end +end + def check(got, expected) if (got != expected) raise RuntimeError, "Failed, got: #{got} expected: #{expected}" @@ -52,3 +71,8 @@ myFoo2 = Foo.new().makeFoo() check(myFoo2.pong(), "Foo::pong();Foo::ping()") check(Foo.callPong(myFoo2), "Foo::pong();Foo::ping()") check(myFoo2.upcall(FooBar.new()), "Bar::Foo2::Foo2Bar()") + +myBarFooDerived = Director_smartptr_MyBarFooDerived.new() +check(myBarFooDerived.ping(), "director_smartptr_MyBarFooDerived.ping()") +check(FooDerived.callPong(myBarFooDerived), "director_smartptr_MyBarFooDerived.pong();director_smartptr_MyBarFooDerived.ping()") +check(FooDerived.callUpcall(myBarFooDerived, fooBar), "overrideDerived;Bar::Foo2::Foo2Bar()") diff --git a/Examples/test-suite/ruby/li_boost_shared_ptr_director_runme.rb b/Examples/test-suite/ruby/li_boost_shared_ptr_director_runme.rb new file mode 100644 index 000000000..0f7f14b46 --- /dev/null +++ b/Examples/test-suite/ruby/li_boost_shared_ptr_director_runme.rb @@ -0,0 +1,79 @@ +require 'li_boost_shared_ptr_director' + +include Li_boost_shared_ptr_director + +class Derived < Base + + def initialize(flag) + @return_none = flag + super() + end + + def ret_c_shared_ptr + if @return_none + nil + else + C.new + end + end + + def ret_c_by_value + C.new + end + + def take_c_by_value(c) + c.get_m + end + + def take_c_shared_ptr_by_value(c) + if c + c.get_m + else + -2 + end + end + + def take_c_shared_ptr_by_ref(c) + if c + c.get_m + else + -3 + end + end + + def take_c_shared_ptr_by_pointer(c) + if c + c.get_m + else + -4 + end + end + + def take_c_shared_ptr_by_pointer_ref(c) + if c + c.get_m + else + -5 + end + end + +end + +a = Derived.new(false) +b = Derived.new(true) + +raise unless call_ret_c_shared_ptr(a) == 1 +raise unless call_ret_c_shared_ptr(b) == -1 +raise unless call_ret_c_by_value(a) == 1 + +raise unless call_take_c_by_value(a) == 5 +raise unless call_take_c_shared_ptr_by_value(a) == 6 +raise unless call_take_c_shared_ptr_by_ref(a) == 7 +raise unless call_take_c_shared_ptr_by_pointer(a) == 8 +raise unless call_take_c_shared_ptr_by_pointer_ref(a) == 9 + +raise unless call_take_c_shared_ptr_by_value_with_null(a) == -2 +raise unless call_take_c_shared_ptr_by_ref_with_null(a) == -3 +raise unless call_take_c_shared_ptr_by_pointer_with_null(a) == -4 +raise unless call_take_c_shared_ptr_by_pointer_ref_with_null(a) == -5 + diff --git a/Examples/test-suite/ruby/li_std_list_runme.rb b/Examples/test-suite/ruby/li_std_list_runme.rb new file mode 100644 index 000000000..b1182e2e3 --- /dev/null +++ b/Examples/test-suite/ruby/li_std_list_runme.rb @@ -0,0 +1,8 @@ +require 'swig_assert' + +require 'li_std_list' + +include Li_std_list + +x = DoubleList.new([1,2,3]) +swig_assert_equal("[1.0]", "x.find_all{|e| e == 1 }", binding) diff --git a/Examples/test-suite/ruby/li_std_wstring_runme.rb b/Examples/test-suite/ruby/li_std_wstring_runme.rb new file mode 100644 index 000000000..0cf38ae4b --- /dev/null +++ b/Examples/test-suite/ruby/li_std_wstring_runme.rb @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +require 'swig_assert' +require 'li_std_wstring' + +x = "abc" +swig_assert_equal("Li_std_wstring.test_wchar_overload(x)", "x", binding) +swig_assert_equal("Li_std_wstring.test_ccvalue(x)", "x", binding) +swig_assert_equal("Li_std_wstring.test_value(Li_std_wstring::Wstring.new(x))", "x", binding) + +swig_assert_equal("Li_std_wstring.test_wchar_overload()", "nil", binding) + +swig_assert_equal("Li_std_wstring.test_pointer(Li_std_wstring::Wstring.new(x))", "nil", binding) +swig_assert_equal("Li_std_wstring.test_const_pointer(Li_std_wstring::Wstring.new(x))", "nil", binding) +swig_assert_equal("Li_std_wstring.test_const_pointer(Li_std_wstring::Wstring.new(x))", "nil", binding) +swig_assert_equal("Li_std_wstring.test_reference(Li_std_wstring::Wstring.new(x))", "nil", binding) + +x = "y" +swig_assert_equal("Li_std_wstring.test_value(x)", "x", binding) +a = Li_std_wstring::A.new(x) +swig_assert_equal("Li_std_wstring.test_value(a)", "x", binding) + +x = "hello" +swig_assert_equal("Li_std_wstring.test_const_reference(x)", "x", binding) + + +swig_assert_equal("Li_std_wstring.test_pointer_out", "'x'", binding) +swig_assert_equal("Li_std_wstring.test_const_pointer_out", "'x'", binding) +swig_assert_equal("Li_std_wstring.test_reference_out()", "'x'", binding) + +s = "abc" +swig_assert("Li_std_wstring.test_equal_abc(s)", binding) + +begin + Li_std_wstring.test_throw +rescue RuntimeError => e + swig_assert_equal("e.message", "'x'", binding) +end + +x = "abc\0def" +swig_assert_equal("Li_std_wstring.test_value(x)", "x", binding) +swig_assert_equal("Li_std_wstring.test_ccvalue(x)", '"abc"', binding) +swig_assert_equal("Li_std_wstring.test_wchar_overload(x)", '"abc"', binding) diff --git a/Examples/test-suite/ruby/std_containers_runme.rb b/Examples/test-suite/ruby/std_containers_runme.rb index 73d443218..65a8b5b86 100644 --- a/Examples/test-suite/ruby/std_containers_runme.rb +++ b/Examples/test-suite/ruby/std_containers_runme.rb @@ -13,6 +13,8 @@ require 'swig_assert' require 'std_containers' include Std_containers +swig_assert_equal("[true, false]", "videntb([true, false])") + swig_assert_each_line(<<'EOF', binding) cube = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]] diff --git a/Examples/test-suite/ruby/swig_assert.rb b/Examples/test-suite/ruby/swig_assert.rb index 69a1a0207..5b3f9b5ce 100644 --- a/Examples/test-suite/ruby/swig_assert.rb +++ b/Examples/test-suite/ruby/swig_assert.rb @@ -1,12 +1,7 @@ #!/usr/bin/env ruby # -# A simple function to create useful asserts +# Useful assert functions # -# -# -# -# - # # Exception raised when some swig binding test fails @@ -15,6 +10,21 @@ class SwigRubyError < RuntimeError end +# +# Simple assertions. Strings are not needed as arguments. +# +def swig_assert_equal_simple(a, b) + unless a == b + raise SwigRubyError.new("\n#{a} expected but was \n#{b}") + end +end + +def swig_assert_simple(a) + unless a + raise SwigRubyError.new("assertion falied.") + end +end + # # Asserts whether a and b are equal. # diff --git a/Examples/test-suite/scilab/null_pointer_runme.sci b/Examples/test-suite/scilab/null_pointer_runme.sci index 2c693d259..dab59acf8 100644 --- a/Examples/test-suite/scilab/null_pointer_runme.sci +++ b/Examples/test-suite/scilab/null_pointer_runme.sci @@ -2,6 +2,6 @@ exec("swigtest.start", -1); p = getnull(); checkequal(SWIG_this(p), 0, "SWIG_this(p)"); -checkequal(func(p), %T, "func(p)"); +checkequal(funk(p), %T, "funk(p)"); exec("swigtest.quit", -1); diff --git a/Examples/test-suite/simutry.i b/Examples/test-suite/simutry.i index addea14db..ad45da425 100644 --- a/Examples/test-suite/simutry.i +++ b/Examples/test-suite/simutry.i @@ -23,7 +23,7 @@ namespace simuPOP { } - virtual int func() const + virtual int funk() const { return m_pop.m_a; } }; @@ -32,7 +32,7 @@ namespace simuPOP struct DerivedOperator: public Operator { DerivedOperator(int a):Operator(a){} - virtual int func() const + virtual int funk() const { return 2*this->m_pop.m_a; } }; @@ -90,7 +90,7 @@ namespace simuPOP void test( const std::vector< Operator*>& para) { for( size_t i =0; i < para.size(); ++i) - para[i]->func(); + para[i]->funk(); } } } diff --git a/Examples/test-suite/smart_pointer_namespace2.i b/Examples/test-suite/smart_pointer_namespace2.i index 882799862..e78364c25 100644 --- a/Examples/test-suite/smart_pointer_namespace2.i +++ b/Examples/test-suite/smart_pointer_namespace2.i @@ -49,11 +49,6 @@ namespace one }; } -%define PTR_DEF(o) -typedef one::Ptr o ## _ptr; -%template(o ## _ptr) one::Ptr; -%enddef - namespace one { class Obj1 @@ -63,7 +58,8 @@ namespace one void donothing() {} }; - PTR_DEF(Obj1) + typedef one::Ptr Obj1_ptr; + %template(Obj1_ptr) one::Ptr; } namespace two @@ -75,6 +71,9 @@ namespace two void donothing() {} }; - PTR_DEF(Obj2) + typedef one::Ptr Obj2_ptr; } +using two::Obj2; +%template(Obj2_ptr) one::Ptr; + diff --git a/Examples/test-suite/std_containers.i b/Examples/test-suite/std_containers.i index ae69b6418..80409a1f0 100644 --- a/Examples/test-suite/std_containers.i +++ b/Examples/test-suite/std_containers.i @@ -115,6 +115,10 @@ return v; } + std::vector videntb(const std::vector& v) + { + return v; + } int get_elem(const std::vector& v, int index) { diff --git a/Examples/test-suite/tcl/null_pointer_runme.tcl b/Examples/test-suite/tcl/null_pointer_runme.tcl index be99c7166..7ed87c153 100644 --- a/Examples/test-suite/tcl/null_pointer_runme.tcl +++ b/Examples/test-suite/tcl/null_pointer_runme.tcl @@ -3,7 +3,7 @@ if [ catch { load ./null_pointer[info sharedlibextension] null_pointer} err_msg } set a [A] -if {[func $a] != 0} { +if {[funk $a] != 0} { puts stderr "null_pointer test 1 failed" exit 1 } diff --git a/Examples/test-suite/template_empty_inherit.i b/Examples/test-suite/template_empty_inherit.i new file mode 100644 index 000000000..5677b8b1a --- /dev/null +++ b/Examples/test-suite/template_empty_inherit.i @@ -0,0 +1,34 @@ +%module template_empty_inherit + +%rename(FunctorOperator) operator(); + +%inline %{ +template struct Functor { + virtual Result operator()(Arg x) const = 0; + virtual ~Functor() {} +}; +%} + +// Bug fix - %ignore was resulting in this warning: +// Warning 401: Base class 'Functor< int,int >' has no name as it is an empty template instantiated with '%template()'. Ignored. +%ignore Functor; +%template() Functor; + +%inline %{ +#include +#include +struct SquareFunctor : Functor { + int operator()(int v) const { return v*v; } +}; +%} + +%include +%template(VectorInt) std::vector; + +%inline %{ +std::vector squares(const std::vector& vi) { + std::vector result; + std::transform(vi.begin(), vi.end(), std::back_inserter(result), SquareFunctor()); + return result; +} +%} diff --git a/Examples/test-suite/template_nested_typemaps.i b/Examples/test-suite/template_nested_typemaps.i index 54f5bc503..577a88e14 100644 --- a/Examples/test-suite/template_nested_typemaps.i +++ b/Examples/test-suite/template_nested_typemaps.i @@ -1,25 +1,30 @@ -#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_TEMPLATE - %module template_nested_typemaps -// Testing that the typemaps invoked within a class via %template are picked up by appropriate methods +#pragma SWIG nowarn=SWIGWARN_PARSE_NAMED_NESTED_CLASS -template struct Typemap { - %typemap(in) T { - $1 = -99; - } -}; -template <> struct Typemap { // Note explicit specialization - %typemap(in) short { - $1 = -77; - } -}; +// Testing that the typemaps invoked within a class via %template are picked up by appropriate methods +// Only for languages that support nested classes %inline %{ int globalInt1(int s) { return s; } short globalShort1(short s) { return s; } template struct Breeze { + template struct Typemap { +#ifdef SWIG + %typemap(in) TMT { + $1 = -99; + } +#endif + }; + template struct TypemapShort { +#ifdef SWIG + %typemap(in) short { + $1 = -77; + } +#endif + }; + int methodInt1(int s) { return s; } #if defined(SWIG) %template() Typemap; @@ -29,7 +34,7 @@ template struct Breeze { short methodShort1(short s) { return s; } #if defined(SWIG) - %template(TypemapShort) Typemap; // should issue warning SWIGWARN_PARSE_NESTED_TEMPLATE + %template() TypemapShort; #endif short methodShort2(short s) { return s; } // should pick up the typemap within Typemap }; diff --git a/Examples/test-suite/template_parameters_global_scope.i b/Examples/test-suite/template_parameters_global_scope.i new file mode 100644 index 000000000..a828187b5 --- /dev/null +++ b/Examples/test-suite/template_parameters_global_scope.i @@ -0,0 +1,133 @@ +%module template_parameters_global_scope + +%inline %{ +namespace Alloc { + template struct Rebind { + typedef int Integer; + }; +} +%} + +%inline %{ +struct Bucket_ {}; +typedef Bucket_ TDBucket; +typedef ::Bucket_ TDGlobalBucket; +%} + +// Check 1: %template no unary scope operator +%template(RebindBucket) Alloc::Rebind< Bucket_ >; + +%inline %{ +Alloc::Rebind< Bucket_ >::Integer Bucket1() { return 1; } +Alloc::Rebind< ::Bucket_ >::Integer Bucket2() { return 2; } +Alloc::Rebind< TDBucket >::Integer Bucket3() { return 3; } +Alloc::Rebind< ::TDBucket >::Integer Bucket4() { return 4; } +Alloc::Rebind< TDGlobalBucket >::Integer Bucket5() { return 5; } +Alloc::Rebind< ::TDGlobalBucket >::Integer Bucket6() { return 6; } +%} + +// Check 2: %template with unary scope operator +%inline %{ +struct Spade {}; +typedef Spade TDSpade; +typedef ::Spade TDGlobalSpade; +%} +%template(RebindSpade) Alloc::Rebind< ::Spade >; + +%inline %{ +Alloc::Rebind< Spade >::Integer Spade1() { return 1; } +Alloc::Rebind< ::Spade >::Integer Spade2() { return 2; } +Alloc::Rebind< TDSpade >::Integer Spade3() { return 3; } +Alloc::Rebind< ::TDSpade >::Integer Spade4() { return 4; } +Alloc::Rebind< TDGlobalSpade >::Integer Spade5() { return 5; } +Alloc::Rebind< ::TDGlobalSpade >::Integer Spade6() { return 6; } +%} + +// Check 3: %template typedef no unary scope operator +%inline %{ +struct Ball {}; +typedef Ball TDBall; +typedef ::Ball TDGlobalBall; +%} +%template(RebindBall) Alloc::Rebind< TDBall >; + +%inline %{ +Alloc::Rebind< Ball >::Integer Ball1() { return 1; } +Alloc::Rebind< ::Ball >::Integer Ball2() { return 2; } +Alloc::Rebind< TDBall >::Integer Ball3() { return 3; } +Alloc::Rebind< ::TDBall >::Integer Ball4() { return 4; } +Alloc::Rebind< TDGlobalBall >::Integer Ball5() { return 5; } +Alloc::Rebind< ::TDGlobalBall >::Integer Ball6() { return 6; } +%} + +// Check 4: %template typedef with unary scope operator +%inline %{ +struct Bat {}; +typedef Bat TDBat; +typedef ::Bat TDGlobalBat; +%} +%template(RebindBat) Alloc::Rebind< ::TDBat >; + +%inline %{ +Alloc::Rebind< Bat >::Integer Bat1() { return 1; } +Alloc::Rebind< ::Bat >::Integer Bat2() { return 2; } +Alloc::Rebind< TDBat >::Integer Bat3() { return 3; } +Alloc::Rebind< ::TDBat >::Integer Bat4() { return 4; } +Alloc::Rebind< TDGlobalBat >::Integer Bat5() { return 5; } +Alloc::Rebind< ::TDGlobalBat >::Integer Bat6() { return 6; } +%} + +// Check 5: %template double typedef no unary scope operator +%inline %{ +struct Chair {}; +typedef Chair TDChair; +typedef ::Chair TDGlobalChair; +%} +%template(RebindChair) Alloc::Rebind< TDGlobalChair >; + +%inline %{ +Alloc::Rebind< Chair >::Integer Chair1() { return 1; } +Alloc::Rebind< ::Chair >::Integer Chair2() { return 2; } +Alloc::Rebind< TDChair >::Integer Chair3() { return 3; } +Alloc::Rebind< ::TDChair >::Integer Chair4() { return 4; } +Alloc::Rebind< TDGlobalChair >::Integer Chair5() { return 5; } +Alloc::Rebind< ::TDGlobalChair >::Integer Chair6() { return 6; } +%} + +// Check 6: %template double typedef with unary scope operator +%inline %{ +struct Table {}; +typedef Table TDTable; +typedef ::Table TDGlobalTable; +%} +%template(RebindTable) Alloc::Rebind< ::TDGlobalTable >; + +%inline %{ +Alloc::Rebind< Table >::Integer Table1() { return 1; } +Alloc::Rebind< ::Table >::Integer Table2() { return 2; } +Alloc::Rebind< TDTable >::Integer Table3() { return 3; } +Alloc::Rebind< ::TDTable >::Integer Table4() { return 4; } +Alloc::Rebind< TDGlobalTable >::Integer Table5() { return 5; } +Alloc::Rebind< ::TDGlobalTable >::Integer Table6() { return 6; } +%} + +#if 0 +%inline %{ +namespace Alloc { + template struct Rejig { + typedef int Integer; + }; +} +%} + +%template(RejigSpade) Alloc::Rejig<::Spade>; + +%inline %{ +Alloc::Rejig<>::Integer rejig1() { return 1; } +Alloc::Rejig< ::Spade >::Integer rejig2() { return 2; } +Alloc::Rejig< ::TDSpade >::Integer rejig3() { return 3; } +Alloc::Rejig< ::TDSpade >::Integer rejig4() { return 4; } +Alloc::Rejig< TDGlobalSpade >::Integer rejig5() { return 5; } +Alloc::Rejig< ::TDGlobalSpade >::Integer rejig6() { return 6; } +%} +#endif diff --git a/Examples/test-suite/template_partial_specialization.i b/Examples/test-suite/template_partial_specialization.i index 8781fbbda..a7afd3000 100644 --- a/Examples/test-suite/template_partial_specialization.i +++ b/Examples/test-suite/template_partial_specialization.i @@ -32,7 +32,7 @@ namespace One { %template(H) One::OneParm; // %template scope explicit specializations -namespace ONE { +namespace One { %template(I) One::OneParm; %template(J) ::One::OneParm; } @@ -42,7 +42,7 @@ namespace One { } // %template scope partial specializations -namespace ONE { +namespace One { %template(BB) One::OneParm; %template(BBB) ::One::OneParm; } diff --git a/Examples/test-suite/template_partial_specialization_typedef.i b/Examples/test-suite/template_partial_specialization_typedef.i index 6fdbf99aa..9c00efc98 100644 --- a/Examples/test-suite/template_partial_specialization_typedef.i +++ b/Examples/test-suite/template_partial_specialization_typedef.i @@ -59,7 +59,7 @@ namespace One { %template(H) One::OneParm; // %template scope explicit specializations -namespace ONE { +namespace One { %template(I) One::OneParm; %template(J) ::One::OneParm; } @@ -69,7 +69,7 @@ namespace One { } // %template scope partial specializations -namespace ONE { +namespace One { %template(BB) One::OneParm; %template(BBB) ::One::OneParm; } diff --git a/Examples/test-suite/template_using_directive_typedef.i b/Examples/test-suite/template_using_directive_typedef.i new file mode 100644 index 000000000..1c8bcb9dd --- /dev/null +++ b/Examples/test-suite/template_using_directive_typedef.i @@ -0,0 +1,44 @@ +%module template_using_directive_typedef + +%inline %{ +namespace space { + template class Vector {}; + class VectorClass {}; +} +struct Obj {}; +%} + +%template(Vector_Obj) space::Vector; + +%inline %{ +namespace tns { + using space::Vector; // template using directives were not being added into the typedef table + using space::VectorClass; + typedef Vector NSVec; +} +%} + +%inline %{ +namespace tns { + struct Holder { +// using Vec = Vector; + typedef Vector Vec; + typedef VectorClass VecClass; + Vec items; + void holder_use1(space::Vector, tns::NSVec, tns::Vector) {} + void holder_use2(space::Vector, NSVec, Vector) {} + void holder_use3(tns::Holder::Vec, Holder::Vec, Vec) {} + }; + void tns_holder_use(tns::Holder::Vec, Holder::Vec) {} + void tns_use(space::Vector, NSVec, tns::NSVec) {} +} +void global_holder_use(tns::Holder::Vec) {} +void global_use(space::Vector, tns::NSVec, tns::Vector) {} +namespace ns1 { + void ns1_holder_use(tns::Holder::Vec) {} +} +namespace ns2 { + using namespace tns; + void ns2_holder_use(tns::Holder::Vec, Holder::Vec, NSVec, Vector) {} +} +%} diff --git a/Examples/test-suite/threads_exception.i b/Examples/test-suite/threads_exception.i index caa79c78e..a9865da3c 100644 --- a/Examples/test-suite/threads_exception.i +++ b/Examples/test-suite/threads_exception.i @@ -14,6 +14,10 @@ struct A {}; #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif class Exc { public: @@ -58,4 +62,11 @@ bool is_python_builtin() { return true; } #else bool is_python_builtin() { return false; } #endif + +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif %} diff --git a/Examples/test-suite/throw_exception.i b/Examples/test-suite/throw_exception.i index 396c633a6..777e55b9e 100644 --- a/Examples/test-suite/throw_exception.i +++ b/Examples/test-suite/throw_exception.i @@ -4,6 +4,10 @@ #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif %} %warnfilter(SWIGWARN_RUBY_WRONG_NAME) Namespace::enum1; @@ -77,3 +81,11 @@ public: %} +%{ +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +%} diff --git a/Examples/test-suite/typedef_funcptr.i b/Examples/test-suite/typedef_funcptr.i index f8cdd14b3..45ea99ef2 100644 --- a/Examples/test-suite/typedef_funcptr.i +++ b/Examples/test-suite/typedef_funcptr.i @@ -21,6 +21,16 @@ extern "C" Integer do_op(Integer x, Integer y, Integer (*op)(Integer, Integer)) { return (*op)(x,y); } + +typedef int (*FnPtr_int_td)(int, int); +int do_op_typedef_int(int x, int y, FnPtr_int_td op) { + return (*op)(x,y); +} + +typedef Integer (*FnPtr_Integer_td)(Integer, Integer); +Integer do_op_typedef_Integer(Integer x, Integer y, FnPtr_Integer_td op) { + return (*op)(x,y); +} %} %constant int addf(int x, int y); diff --git a/Examples/test-suite/typemap_template_typedef.i b/Examples/test-suite/typemap_template_typedef.i new file mode 100644 index 000000000..c84416ef9 --- /dev/null +++ b/Examples/test-suite/typemap_template_typedef.i @@ -0,0 +1,66 @@ +%module typemap_template_typedef +//%module("templatereduce") typemap_template_typedef + +%typemap(in) int TMAP55 %{ $1 = 55; /* int TMAP55 typemap */ %} +%typemap(in) int TMAP66 %{ $1 = 66; /* int TMAP66 typemap */ %} +%typemap(in) int TMAP77 %{ $1 = 77; /* int TMAP77 typemap */ %} +%typemap(in) int TMAP88 %{ $1 = 88; /* int TMAP88 typemap */ %} + +%apply int TMAP77 { XXX::Long cc } + +%inline %{ +typedef int Integer; + +template struct XXX { +#ifdef SWIG +// In swig-3.0.12 'Long aa' was actually stored as 'long aa' in typemap table instead of 'XXX::Long aa' +%apply int TMAP55 { Long aa } +%apply int TMAP66 { XXX::Long bb } +%apply int TMAP88 { XXX::Long dd } +#endif + typedef long Long; + long aa1(long aa) { return aa; } + long aa2(Long aa) { return aa; } + long bb1(long bb) { return bb; } + long bb2(Long bb) { return bb; } + long cc1(long cc) { return cc; } + long cc2(Long cc) { return cc; } + long dd1(long dd) { return dd; } + long dd2(Long dd) { return dd; } +#ifdef SWIG +%clear Long aa; +%clear XXX::Long bb; +%clear XXX::Long dd; +#endif + long aa3(Long aa) { return aa; } + long bb3(Long bb) { return bb; } + long cc3(Long cc) { return cc; } + long dd3(Long dd) { return dd; } +}; +%} + +%template(XXXInt) XXX; + +%clear XXX::Long cc; + +%inline %{ + long aa1(XXX::Long aa) { return aa; } + long aa2(long aa) { return aa; } + long bb1(XXX::Long bb) { return bb; } + long bb2(long bb) { return bb; } + long cc1(XXX::Long cc) { return cc; } + long cc2(long cc) { return cc; } + long dd1(XXX::Long dd) { return dd; } + long dd2(long dd) { return dd; } +%} + +%inline %{ +typedef Integer INTEGER; +template struct YYY { + void meff(T1 t1, T2 t2) {} +}; +%} +%template(YYYIntInt) YYY; +%inline %{ + void whyohwhy(YYY yy) {} +%} diff --git a/Examples/test-suite/using_pointers.i b/Examples/test-suite/using_pointers.i index b2d6abe4d..569acce25 100644 --- a/Examples/test-suite/using_pointers.i +++ b/Examples/test-suite/using_pointers.i @@ -8,6 +8,10 @@ #if defined(_MSC_VER) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11 +#endif %} %inline %{ @@ -34,3 +38,11 @@ %} +%{ +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +%} diff --git a/Lib/allegrocl/allegrocl.swg b/Lib/allegrocl/allegrocl.swg index 152e5e6f0..524aa7c11 100644 --- a/Lib/allegrocl/allegrocl.swg +++ b/Lib/allegrocl/allegrocl.swg @@ -232,6 +232,8 @@ $body)" /* const pointers */ %apply SWIGTYPE * { SWIGTYPE *const } +%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) } +%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) } /* name conversion for overloaded operators. */ #ifdef __cplusplus diff --git a/Lib/cffi/cffi.swg b/Lib/cffi/cffi.swg index 3ad767ef8..f7294956f 100644 --- a/Lib/cffi/cffi.swg +++ b/Lib/cffi/cffi.swg @@ -136,6 +136,8 @@ /* const pointers */ %apply SWIGTYPE * { SWIGTYPE *const } +%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) } +%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) } %{ diff --git a/Lib/chicken/chicken.swg b/Lib/chicken/chicken.swg index 17f0d0ac3..571c392ea 100644 --- a/Lib/chicken/chicken.swg +++ b/Lib/chicken/chicken.swg @@ -716,6 +716,8 @@ $result = C_SCHEME_UNDEFINED; /* const pointers */ %apply SWIGTYPE * { SWIGTYPE *const } +%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) } +%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) } /* ------------------------------------------------------------ * Overloaded operator support diff --git a/Lib/csharp/boost_shared_ptr.i b/Lib/csharp/boost_shared_ptr.i index 2b65bf20d..8d65d7953 100644 --- a/Lib/csharp/boost_shared_ptr.i +++ b/Lib/csharp/boost_shared_ptr.i @@ -14,7 +14,7 @@ %naturalvar SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >; // destructor mods -%feature("unref") TYPE +%feature("unref") TYPE //"if (debug_shared) { cout << \"deleting use_count: \" << (*smartarg1).use_count() << \" [\" << (boost::get_deleter(*smartarg1) ? std::string(\"CANNOT BE DETERMINED SAFELY\") : ( (*smartarg1).get() ? (*smartarg1)->getValue() : std::string(\"NULL PTR\") )) << \"]\" << endl << flush; }\n" "(void)arg1; delete smartarg1;" @@ -28,7 +28,7 @@ return $null; } $1 = *argp; %} -%typemap(out) CONST TYPE +%typemap(out) CONST TYPE %{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %} // plain pointer @@ -66,7 +66,7 @@ %typemap(in, canthrow=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & ($*1_ltype tempnull) %{ $1 = $input ? ($1_ltype)$input : &tempnull; %} %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & -%{ $result = *$1 ? new $*1_ltype(*$1) : 0; %} +%{ $result = *$1 ? new $*1_ltype(*$1) : 0; %} // shared_ptr by pointer %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * ($*1_ltype tempnull) @@ -80,7 +80,7 @@ %{ temp = $input ? *($1_ltype)&$input : &tempnull; $1 = &temp; %} %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& -%{ *($1_ltype)&$result = (*$1 && **$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(**$1) : 0; %} +%{ *($1_ltype)&$result = (*$1 && **$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(**$1) : 0; %} // various missing typemaps - If ever used (unlikely) ensure compilation error rather than runtime bug %typemap(in) CONST TYPE[], CONST TYPE[ANY], CONST TYPE (CLASS::*) %{ @@ -91,20 +91,20 @@ %} -%typemap (ctype) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >, +%typemap (ctype) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& "void *" -%typemap (imtype, out="global::System.IntPtr") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >, +%typemap (imtype, out="global::System.IntPtr") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& "global::System.Runtime.InteropServices.HandleRef" -%typemap (cstype) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >, +%typemap (cstype) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& "$typemap(cstype, TYPE)" -%typemap(csin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >, +%typemap(csin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& "$typemap(cstype, TYPE).getCPtr($csinput)" diff --git a/Lib/csharp/complex.i b/Lib/csharp/complex.i new file mode 100644 index 000000000..4a6f91cdf --- /dev/null +++ b/Lib/csharp/complex.i @@ -0,0 +1,5 @@ +#ifdef __cplusplus +%include +#else +#error C# module only supports complex in C++ mode. +#endif diff --git a/Lib/csharp/csharp.swg b/Lib/csharp/csharp.swg index 8dc2ba813..bf1e126d8 100644 --- a/Lib/csharp/csharp.swg +++ b/Lib/csharp/csharp.swg @@ -843,6 +843,13 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { $*csclassname ret = (cPtr == global::System.IntPtr.Zero) ? null : new $*csclassname(cPtr, $owner);$excode return ret; } +%typemap(csvarout, excode=SWIGEXCODE) SWIGTYPE *const& %{ + get { + global::System.IntPtr cPtr = $imcall; + $*csclassname ret = (cPtr == global::System.IntPtr.Zero) ? null : new $*csclassname(cPtr, $owner);$excode + return ret; + } %} + %typemap(in) SWIGTYPE *const& ($*1_ltype temp = 0) %{ temp = ($*1_ltype)$input; $1 = ($1_ltype)&temp; %} @@ -1011,6 +1018,8 @@ SWIG_CSBODY_TYPEWRAPPER(internal, protected, internal, SWIGTYPE) /* const pointers */ %apply SWIGTYPE * { SWIGTYPE *const } +%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) } +%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) } /* csharp keywords */ %include diff --git a/Lib/csharp/director.swg b/Lib/csharp/director.swg index 3438f2bf0..5d2ab5d9b 100644 --- a/Lib/csharp/director.swg +++ b/Lib/csharp/director.swg @@ -41,6 +41,10 @@ namespace Swig { public: DirectorPureVirtualException(const char *msg) : DirectorException(std::string("Attempt to invoke pure virtual method ") + msg) { } + + static void raise(const char *msg) { + throw DirectorPureVirtualException(msg); + } }; } diff --git a/Lib/csharp/std_array.i b/Lib/csharp/std_array.i index 61bb510de..e7d392b85 100644 --- a/Lib/csharp/std_array.i +++ b/Lib/csharp/std_array.i @@ -174,7 +174,7 @@ bool empty() const; %rename(Fill) fill; - void fill(const value_type& val); + void fill(const value_type& value); %rename(Swap) swap; void swap(array& other); @@ -192,9 +192,9 @@ else throw std::out_of_range("index"); } - void setitem(int index, const_reference val) throw (std::out_of_range) { + void setitem(int index, const_reference value) throw (std::out_of_range) { if (index>=0 && index<(int)$self->size()) - (*$self)[index] = val; + (*$self)[index] = value; else throw std::out_of_range("index"); } diff --git a/Lib/csharp/std_complex.i b/Lib/csharp/std_complex.i new file mode 100644 index 000000000..e69d17067 --- /dev/null +++ b/Lib/csharp/std_complex.i @@ -0,0 +1,92 @@ +/* ----------------------------------------------------------------------------- + * std_complex.i + * + * Typemaps for handling std::complex and std::complex as a .NET + * System.Numerics.Complex type. Requires .NET 4 minimum. + * ----------------------------------------------------------------------------- */ + +%{ +#include +%} + +%fragment("SwigSystemNumericsComplex", "header") { +extern "C" { +// Identical to the layout of System.Numerics.Complex, but does assume that it is +// LayoutKind.Sequential on the managed side +struct SwigSystemNumericsComplex { + double real; + double imag; +}; +} + +SWIGINTERN SwigSystemNumericsComplex SwigCreateSystemNumericsComplex(double real, double imag) { + SwigSystemNumericsComplex cpx; + cpx.real = real; + cpx.imag = imag; + return cpx; +} +} + +namespace std { + +%naturalvar complex; + +template +class complex +{ +public: + complex(T re = T(), T im = T()); +}; + +} + +%define SWIG_COMPLEX_TYPEMAPS(T) +%typemap(ctype, fragment="SwigSystemNumericsComplex") std::complex, const std::complex & "SwigSystemNumericsComplex" +%typemap(imtype) std::complex, const std::complex & "System.Numerics.Complex" +%typemap(cstype) std::complex, const std::complex & "System.Numerics.Complex" + +%typemap(in) std::complex($*1_ltype temp), const std::complex &($*1_ltype temp) +%{temp = std::complex< double >($input.real, $input.imag); + $1 = &temp;%} + +%typemap(out, null="SwigCreateSystemNumericsComplex(0.0, 0.0)") std::complex +%{$result = SwigCreateSystemNumericsComplex($1.real(), $1.imag());%} + +%typemap(out, null="SwigCreateSystemNumericsComplex(0.0, 0.0)") const std::complex & +%{$result = SwigCreateSystemNumericsComplex($1->real(), $1->imag());%} + +%typemap(cstype) std::complex, const std::complex & "System.Numerics.Complex" + +%typemap(csin) std::complex, const std::complex & "$csinput" + +%typemap(csout, excode=SWIGEXCODE) std::complex, const std::complex & { + System.Numerics.Complex ret = $imcall;$excode + return ret; + } + +%typemap(csvarin, excode=SWIGEXCODE2) const std::complex & %{ + set { + $imcall;$excode + } + %} + +%typemap(csvarout, excode=SWIGEXCODE2) const std::complex & %{ + get { + System.Numerics.Complex ret = $imcall;$excode + return ret; + } + %} + +%template() std::complex; +%enddef + +// By default, typemaps for both std::complex and std::complex +// are defined, but one of them can be disabled by predefining the +// corresponding symbol before including this file. +#ifndef SWIG_NO_STD_COMPLEX_DOUBLE +SWIG_COMPLEX_TYPEMAPS(double) +#endif + +#ifndef SWIG_NO_STD_COMPLEX_FLOAT +SWIG_COMPLEX_TYPEMAPS(float) +#endif diff --git a/Lib/csharp/std_map.i b/Lib/csharp/std_map.i index 90a865079..9d07bc830 100644 --- a/Lib/csharp/std_map.i +++ b/Lib/csharp/std_map.i @@ -4,14 +4,14 @@ * SWIG typemaps for std::map< K, T, C > * * The C# wrapper is made to look and feel like a C# System.Collections.Generic.IDictionary<>. - * + * * Using this wrapper is fairly simple. For example, to create a map from integers to doubles use: * * %include * %template(MapIntDouble) std::map * * Notes: - * 1) IEnumerable<> is implemented in the proxy class which is useful for using LINQ with + * 1) IEnumerable<> is implemented in the proxy class which is useful for using LINQ with * C++ std::map wrappers. * * Warning: heavy macro usage in this file. Use swig -E to get a sane view on the real file contents! @@ -55,8 +55,8 @@ } public bool IsReadOnly { - get { - return false; + get { + return false; } } @@ -84,7 +84,7 @@ return vals; } } - + public void Add(global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> item) { Add(item.Key, item.Value); } @@ -143,7 +143,7 @@ /// whenever the collection is modified. This has been done for changes in the size of the /// collection but not when one of the elements of the collection is modified as it is a bit /// tricky to detect unmanaged code that modifies the collection under our feet. - public sealed class $csclassnameEnumerator : global::System.Collections.IEnumerator, + public sealed class $csclassnameEnumerator : global::System.Collections.IEnumerator, global::System.Collections.Generic.IEnumerator> { private $csclassname collectionRef; @@ -206,7 +206,7 @@ currentObject = null; } } - + %} public: @@ -239,11 +239,11 @@ return iter != $self->end(); } - void Add(const key_type& key, const mapped_type& val) throw (std::out_of_range) { + void Add(const key_type& key, const mapped_type& value) throw (std::out_of_range) { std::map< K, T, C >::iterator iter = $self->find(key); if (iter != $self->end()) throw std::out_of_range("key already exists"); - $self->insert(std::pair< K, T >(key, val)); + $self->insert(std::pair< K, T >(key, value)); } bool Remove(const key_type& key) { @@ -251,7 +251,7 @@ if (iter != $self->end()) { $self->erase(iter); return true; - } + } return false; } @@ -285,12 +285,12 @@ %csmethodmodifiers std::map::destroy_iterator "private" // Default implementation -namespace std { +namespace std { template > class map { SWIG_STD_MAP_INTERNAL(K, T, C) }; } - + // Legacy macros (deprecated) %define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) diff --git a/Lib/csharp/std_vector.i b/Lib/csharp/std_vector.i index 12220aa57..0d1476f7f 100644 --- a/Lib/csharp/std_vector.i +++ b/Lib/csharp/std_vector.i @@ -5,9 +5,9 @@ * C# implementation * The C# wrapper is made to look and feel like a C# System.Collections.Generic.List<> collection. * - * Note that IEnumerable<> is implemented in the proxy class which is useful for using LINQ with + * Note that IEnumerable<> is implemented in the proxy class which is useful for using LINQ with * C++ std::vector wrappers. The IList<> interface is also implemented to provide enhanced functionality - * whenever we are confident that the required C++ operator== is available. This is the case for when + * whenever we are confident that the required C++ operator== is available. This is the case for when * T is a primitive type or a pointer. If T does define an operator==, then use the SWIG_STD_VECTOR_ENHANCED * macro to obtain this enhanced functionality, for example: * @@ -26,7 +26,15 @@ %define SWIG_STD_VECTOR_MINIMUM_INTERNAL(CSINTERFACE, CONST_REFERENCE, CTYPE...) %typemap(csinterfaces) std::vector< CTYPE > "global::System.IDisposable, global::System.Collections.IEnumerable\n , global::System.Collections.Generic.CSINTERFACE<$typemap(cstype, CTYPE)>\n"; %proxycode %{ - public $csclassname(global::System.Collections.ICollection c) : this() { + public $csclassname(global::System.Collections.IEnumerable c) : this() { + if (c == null) + throw new global::System.ArgumentNullException("c"); + foreach ($typemap(cstype, CTYPE) element in c) { + this.Add(element); + } + } + + public $csclassname(global::System.Collections.Generic.IEnumerable<$typemap(cstype, CTYPE)> c) : this() { if (c == null) throw new global::System.ArgumentNullException("c"); foreach ($typemap(cstype, CTYPE) element in c) { @@ -62,7 +70,7 @@ set { if (value < size()) throw new global::System.ArgumentOutOfRangeException("Capacity"); - reserve((uint)value); + reserve(($typemap(cstype, size_t))value); } } @@ -223,9 +231,9 @@ else throw std::out_of_range("index"); } - void setitem(int index, CTYPE const& val) throw (std::out_of_range) { + void setitem(int index, CTYPE const& value) throw (std::out_of_range) { if (index>=0 && index<(int)$self->size()) - (*$self)[index] = val; + (*$self)[index] = value; else throw std::out_of_range("index"); } @@ -324,7 +332,7 @@ std::vector< CTYPE >::iterator it = std::find($self->begin(), $self->end(), value); if (it != $self->end()) { $self->erase(it); - return true; + return true; } return false; } diff --git a/Lib/d/director.swg b/Lib/d/director.swg index a7d9c7688..02da0e0ac 100644 --- a/Lib/d/director.swg +++ b/Lib/d/director.swg @@ -40,6 +40,10 @@ namespace Swig { public: DirectorPureVirtualException(const char *msg) : DirectorException(std::string("Attempted to invoke pure virtual method ") + msg) { } + + static void raise(const char *msg) { + throw DirectorPureVirtualException(msg); + } }; } diff --git a/Lib/d/dmemberfunctionpointers.swg b/Lib/d/dmemberfunctionpointers.swg index c63eca23e..a07d0a5d8 100644 --- a/Lib/d/dmemberfunctionpointers.swg +++ b/Lib/d/dmemberfunctionpointers.swg @@ -43,6 +43,8 @@ return ret; } +%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) } +%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) } /* * Helper functions to pack/unpack arbitrary binary data (member function diff --git a/Lib/d/dswigtype.swg b/Lib/d/dswigtype.swg index f91d6dfe6..5043741d5 100644 --- a/Lib/d/dswigtype.swg +++ b/Lib/d/dswigtype.swg @@ -162,7 +162,7 @@ return ret; } -// Treat references to arrays like like references to a single element. +// Treat references to arrays like references to a single element. %apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) } diff --git a/Lib/d/std_map.i b/Lib/d/std_map.i index 0e8574b8a..d2ba04118 100644 --- a/Lib/d/std_map.i +++ b/Lib/d/std_map.i @@ -16,44 +16,41 @@ #include %} -// exported class - namespace std { - template class map { - // add typemaps here - public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef K key_type; - typedef T mapped_type; - map(); - map(const map &); + template class map { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef K key_type; + typedef T mapped_type; + map(); + map(const map &); - unsigned int size() const; - bool empty() const; - void clear(); - %extend { - const T& get(const K& key) throw (std::out_of_range) { - std::map::iterator i = self->find(key); - if (i != self->end()) - return i->second; - else - throw std::out_of_range("key not found"); - } - void set(const K& key, const T& x) { - (*self)[key] = x; - } - void del(const K& key) throw (std::out_of_range) { - std::map::iterator i = self->find(key); - if (i != self->end()) - self->erase(i); - else - throw std::out_of_range("key not found"); - } - bool has_key(const K& key) { - std::map::iterator i = self->find(key); - return i != self->end(); - } + unsigned int size() const; + bool empty() const; + void clear(); + %extend { + const T& get(const K& key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + return i->second; + else + throw std::out_of_range("key not found"); } - }; + void set(const K& key, const T& x) { + (*self)[key] = x; + } + void del(const K& key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + self->erase(i); + else + throw std::out_of_range("key not found"); + } + bool has_key(const K& key) { + std::map::iterator i = self->find(key); + return i != self->end(); + } + } + }; } diff --git a/Lib/d/std_vector.i b/Lib/d/std_vector.i index 56f7188c7..c67057180 100644 --- a/Lib/d/std_vector.i +++ b/Lib/d/std_vector.i @@ -165,11 +165,11 @@ public void capacity(size_t value) { // generation issue when using const pointers as vector elements (like // std::vector< const int* >). %extend { - void setElement(size_type index, CTYPE const& val) throw (std::out_of_range) { + void setElement(size_type index, CTYPE const& value) throw (std::out_of_range) { if ((index < 0) || ($self->size() <= index)) { throw std::out_of_range("Tried to set value of element with invalid index."); } - (*$self)[index] = val; + (*$self)[index] = value; } } @@ -517,11 +517,11 @@ int opApply(int delegate(ref size_t index, ref $typemap(dtype, CTYPE) value) dg) // generation issue when using const pointers as vector elements (like // std::vector< const int* >). %extend { - void setElement(size_type index, CTYPE const& val) throw (std::out_of_range) { + void setElement(size_type index, CTYPE const& value) throw (std::out_of_range) { if ((index < 0) || ($self->size() <= index)) { throw std::out_of_range("Tried to set value of element with invalid index."); } - (*$self)[index] = val; + (*$self)[index] = value; } } diff --git a/Lib/go/go.swg b/Lib/go/go.swg index 53b653f7c..3e1fab2d9 100644 --- a/Lib/go/go.swg +++ b/Lib/go/go.swg @@ -341,8 +341,6 @@ %typemap(directorout) SWIGTYPE * %{ $result = *($&1_ltype)&$input; %} -%apply SWIGTYPE * { SWIGTYPE *const } - /* Pointer references. */ %typemap(gotype) SWIGTYPE *const& @@ -692,6 +690,10 @@ SWIGTYPE (CLASS::*) "" +%apply SWIGTYPE * { SWIGTYPE *const } +%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) } +%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) } + /* Go keywords. */ %include diff --git a/Lib/guile/typemaps.i b/Lib/guile/typemaps.i index a01e73f64..0d130f523 100644 --- a/Lib/guile/typemaps.i +++ b/Lib/guile/typemaps.i @@ -468,5 +468,7 @@ typedef unsigned long SCM; /* const pointers */ %apply SWIGTYPE * { SWIGTYPE *const } +%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) } +%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) } /* typemaps.i ends here */ diff --git a/Lib/java/boost_intrusive_ptr.i b/Lib/java/boost_intrusive_ptr.i index a484a3b6c..48e530c63 100644 --- a/Lib/java/boost_intrusive_ptr.i +++ b/Lib/java/boost_intrusive_ptr.i @@ -29,26 +29,26 @@ SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null $1_type"); return $null; } - $1 = *argp; + $1 = *argp; %} -%typemap(out, fragment="SWIG_intrusive_deleter") CONST TYPE %{ +%typemap(out, fragment="SWIG_intrusive_deleter") CONST TYPE %{ //plain value(out) $1_ltype* resultp = new $1_ltype(($1_ltype &)$1); intrusive_ptr_add_ref(resultp); - *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(resultp, SWIG_intrusive_deleter< CONST TYPE >()); + *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(resultp, SWIG_intrusive_deleter< CONST TYPE >()); %} %typemap(in) CONST TYPE * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{ // plain pointer smartarg = *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input; - $1 = (TYPE *)(smartarg ? smartarg->get() : 0); + $1 = (TYPE *)(smartarg ? smartarg->get() : 0); %} %typemap(out, fragment="SWIG_intrusive_deleter,SWIG_null_deleter") CONST TYPE * %{ //plain pointer(out) #if ($owner) if ($1) { intrusive_ptr_add_ref($1); - *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1, SWIG_intrusive_deleter< CONST TYPE >()); + *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1, SWIG_intrusive_deleter< CONST TYPE >()); } else { *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = 0; } @@ -63,70 +63,70 @@ if(!$1) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type reference is null"); return $null; - } + } %} -%typemap(out, fragment="SWIG_intrusive_deleter,SWIG_null_deleter") CONST TYPE & %{ +%typemap(out, fragment="SWIG_intrusive_deleter,SWIG_null_deleter") CONST TYPE & %{ //plain reference(out) #if ($owner) if ($1) { intrusive_ptr_add_ref($1); - *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1, SWIG_intrusive_deleter< CONST TYPE >()); + *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1, SWIG_intrusive_deleter< CONST TYPE >()); } else { *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = 0; - } + } #else *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = $1 ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1 SWIG_NO_NULL_DELETER_0) : 0; #endif %} -%typemap(in) TYPE *CONST& ($*1_ltype temp = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{ +%typemap(in) TYPE *CONST& ($*1_ltype temp = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{ // plain pointer by reference temp = ($*1_ltype)((*(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input) ? (*(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input)->get() : 0); - $1 = &temp; + $1 = &temp; %} -%typemap(out, fragment="SWIG_intrusive_deleter,SWIG_null_deleter") TYPE *CONST& %{ +%typemap(out, fragment="SWIG_intrusive_deleter,SWIG_null_deleter") TYPE *CONST& %{ // plain pointer by reference(out) #if ($owner) if (*$1) { intrusive_ptr_add_ref(*$1); - *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1, SWIG_intrusive_deleter< CONST TYPE >()); + *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1, SWIG_intrusive_deleter< CONST TYPE >()); } else { *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = 0; - } + } #else *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(*$1 SWIG_NO_NULL_DELETER_0); #endif %} -%typemap(in) SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > ($&1_type argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * smartarg) %{ +%typemap(in) SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > ($&1_type argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * smartarg) %{ // intrusive_ptr by value smartarg = *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >**)&$input; if (smartarg) { - $1 = SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE >(smartarg->get(), true); + $1 = SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE >(smartarg->get(), true); } %} -%typemap(out, fragment="SWIG_intrusive_deleter") SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > %{ +%typemap(out, fragment="SWIG_intrusive_deleter") SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > %{ if ($1) { intrusive_ptr_add_ref(result.get()); *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(result.get(), SWIG_intrusive_deleter< CONST TYPE >()); } else { - *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = 0; + *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = 0; } %} %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > swigSharedPtrUpcast ($&1_type smartarg) %{ // shared_ptr by value - smartarg = *($&1_ltype*)&$input; - if (smartarg) $1 = *smartarg; + smartarg = *($&1_ltype*)&$input; + if (smartarg) $1 = *smartarg; %} -%typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > ANY_TYPE_SWIGSharedPtrUpcast %{ - *($&1_ltype*)&$result = $1 ? new $1_ltype($1) : 0; +%typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > ANY_TYPE_SWIGSharedPtrUpcast %{ + *($&1_ltype*)&$result = $1 ? new $1_ltype($1) : 0; %} -%typemap(in) SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > & ($*1_ltype tempnull, $*1_ltype temp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * smartarg) %{ +%typemap(in) SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > & ($*1_ltype tempnull, $*1_ltype temp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * smartarg) %{ // intrusive_ptr by reference if ( $input ) { - smartarg = *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >**)&$input; + smartarg = *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >**)&$input; temp = SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE >(smartarg->get(), true); $1 = &temp; } else { @@ -140,21 +140,21 @@ $1 = *temp; } %} -%typemap(out, fragment="SWIG_intrusive_deleter") SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > & %{ +%typemap(out, fragment="SWIG_intrusive_deleter") SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > & %{ if (*$1) { intrusive_ptr_add_ref($1->get()); *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1->get(), SWIG_intrusive_deleter< CONST TYPE >()); } else { *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = 0; } -%} +%} -%typemap(in) SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > * ($*1_ltype tempnull, $*1_ltype temp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * smartarg) %{ +%typemap(in) SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > * ($*1_ltype tempnull, $*1_ltype temp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * smartarg) %{ // intrusive_ptr by pointer if ( $input ) { - smartarg = *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >**)&$input; + smartarg = *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >**)&$input; temp = SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE >(smartarg->get(), true); - $1 = &temp; + $1 = &temp; } else { $1 = &tempnull; } @@ -163,17 +163,17 @@ delete $1; if ($self) $1 = new SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE >(*$input); %} -%typemap(out, fragment="SWIG_intrusive_deleter") SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > * %{ +%typemap(out, fragment="SWIG_intrusive_deleter") SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > * %{ if ($1 && *$1) { intrusive_ptr_add_ref($1->get()); *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1->get(), SWIG_intrusive_deleter< CONST TYPE >()); } else { *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = 0; } - if ($owner) delete $1; + if ($owner) delete $1; %} -%typemap(in) SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > *& (SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > temp, $*1_ltype tempp = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * smartarg) %{ +%typemap(in) SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > *& (SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > temp, $*1_ltype tempp = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * smartarg) %{ // intrusive_ptr by pointer reference smartarg = *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >**)&$input; if ($input) { @@ -185,14 +185,14 @@ %typemap(memberin) SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > *& %{ if ($self) $1 = *$input; %} -%typemap(out, fragment="SWIG_intrusive_deleter") SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > *& %{ +%typemap(out, fragment="SWIG_intrusive_deleter") SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > *& %{ if (*$1 && **$1) { intrusive_ptr_add_ref((*$1)->get()); *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >((*$1)->get(), SWIG_intrusive_deleter< CONST TYPE >()); } else { *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = 0; } -%} +%} // various missing typemaps - If ever used (unlikely) ensure compilation error rather than runtime bug %typemap(in) CONST TYPE[], CONST TYPE[ANY], CONST TYPE (CLASS::*) %{ @@ -208,7 +208,7 @@ SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > &, SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > *, SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > *& "jlong" -%typemap (jtype) SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE >, +%typemap (jtype) SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE >, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >, SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > &, SWIG_INTRUSIVE_PTR_QNAMESPACE::intrusive_ptr< CONST TYPE > *, @@ -341,7 +341,7 @@ return $null; } $1 = *argp; %} -%typemap(out) CONST TYPE +%typemap(out) CONST TYPE %{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %} // plain pointer @@ -371,11 +371,11 @@ %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > swigSharedPtrUpcast ($&1_type smartarg) %{ // shared_ptr by value - smartarg = *($&1_ltype*)&$input; - if (smartarg) $1 = *smartarg; + smartarg = *($&1_ltype*)&$input; + if (smartarg) $1 = *smartarg; %} -%typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > ANY_TYPE_SWIGSharedPtrUpcast %{ - *($&1_ltype*)&$result = $1 ? new $1_ltype($1) : 0; +%typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > ANY_TYPE_SWIGSharedPtrUpcast %{ + *($&1_ltype*)&$result = $1 ? new $1_ltype($1) : 0; %} // various missing typemaps - If ever used (unlikely) ensure compilation error rather than runtime bug diff --git a/Lib/java/boost_shared_ptr.i b/Lib/java/boost_shared_ptr.i index 5ed16aa32..699a8a0a0 100644 --- a/Lib/java/boost_shared_ptr.i +++ b/Lib/java/boost_shared_ptr.i @@ -14,7 +14,7 @@ %naturalvar SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >; // destructor wrapper customisation -%feature("unref") TYPE +%feature("unref") TYPE //"if (debug_shared) { cout << \"deleting use_count: \" << (*smartarg1).use_count() << \" [\" << (boost::get_deleter(*smartarg1) ? std::string(\"CANNOT BE DETERMINED SAFELY\") : ( (*smartarg1).get() ? (*smartarg1)->getValue() : std::string(\"NULL PTR\") )) << \"]\" << endl << flush; }\n" "(void)arg1; delete smartarg1;" @@ -28,7 +28,7 @@ return $null; } $1 = *argp; %} -%typemap(out) CONST TYPE +%typemap(out) CONST TYPE %{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %} // plain pointer @@ -58,7 +58,7 @@ // shared_ptr by value %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > ($&1_type argp) -%{ argp = *($&1_ltype*)&$input; +%{ argp = *($&1_ltype*)&$input; if (argp) $1 = *argp; %} %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > %{ *($&1_ltype*)&$result = $1 ? new $1_ltype($1) : 0; %} @@ -67,7 +67,7 @@ %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & ($*1_ltype tempnull) %{ $1 = $input ? *($&1_ltype)&$input : &tempnull; %} %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & -%{ *($&1_ltype)&$result = *$1 ? new $*1_ltype(*$1) : 0; %} +%{ *($&1_ltype)&$result = *$1 ? new $*1_ltype(*$1) : 0; %} // shared_ptr by pointer %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * ($*1_ltype tempnull) @@ -81,7 +81,7 @@ %{ temp = $input ? *($1_ltype)&$input : &tempnull; $1 = &temp; %} %typemap(out) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& -%{ *($1_ltype)&$result = (*$1 && **$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(**$1) : 0; %} +%{ *($1_ltype)&$result = (*$1 && **$1) ? new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(**$1) : 0; %} // various missing typemaps - If ever used (unlikely) ensure compilation error rather than runtime bug %typemap(in) CONST TYPE[], CONST TYPE[ANY], CONST TYPE (CLASS::*) %{ @@ -92,20 +92,20 @@ %} -%typemap (jni) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >, +%typemap (jni) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& "jlong" -%typemap (jtype) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >, +%typemap (jtype) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& "long" -%typemap (jstype) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >, +%typemap (jstype) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& "$typemap(jstype, TYPE)" -%typemap(javain) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >, +%typemap(javain) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& "$typemap(jstype, TYPE).getCPtr($javainput)" @@ -156,6 +156,10 @@ CPTR_VISIBILITY static long getCPtr($javaclassname obj) { return (obj == null) ? 0 : obj.swigCPtr; } + + CPTR_VISIBILITY void swigSetCMemOwn(boolean own) { + swigCMemOwn = own; + } %} // Derived proxy classes @@ -172,6 +176,11 @@ CPTR_VISIBILITY static long getCPtr($javaclassname obj) { return (obj == null) ? 0 : obj.swigCPtr; } + + CPTR_VISIBILITY void swigSetCMemOwn(boolean own) { + swigCMemOwnDerived = own; + super.swigSetCMemOwn(own); + } %} %typemap(javadestruct, methodname="delete", methodmodifiers="public synchronized") TYPE { @@ -195,6 +204,26 @@ super.delete(); } +%typemap(directordisconnect, methodname="swigDirectorDisconnect") TYPE %{ + protected void $methodname() { + swigSetCMemOwn(false); + $jnicall; + } +%} + +%typemap(directorowner_release, methodname="swigReleaseOwnership") TYPE %{ + public void $methodname() { + swigSetCMemOwn(false); + $jnicall; + } +%} + +%typemap(directorowner_take, methodname="swigTakeOwnership") TYPE %{ + public void $methodname() { + swigSetCMemOwn(true); + $jnicall; + } +%} %template() SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >; %enddef diff --git a/Lib/java/director.swg b/Lib/java/director.swg index 355e62d67..abde72286 100644 --- a/Lib/java/director.swg +++ b/Lib/java/director.swg @@ -356,6 +356,10 @@ namespace Swig { } } + static void raise(JNIEnv *jenv, jthrowable throwable) { + throw DirectorException(jenv, throwable); + } + private: static char *copypath(const char *srcmsg) { char *target = copystr(srcmsg); diff --git a/Lib/java/java.swg b/Lib/java/java.swg index d173cb627..b49826ba0 100644 --- a/Lib/java/java.swg +++ b/Lib/java/java.swg @@ -54,6 +54,14 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { } } +%fragment("SWIG_JavaIntFromSize_t", "header") { +/* Check for overflow converting to Java int (always signed 32-bit) from (unsigned variable-bit) size_t */ +SWIGINTERN jint SWIG_JavaIntFromSize_t(size_t size) { + static const jint JINT_MAX = 0x7FFFFFFF; + return (size > (size_t)JINT_MAX) ? -1 : (jint)size; +} +} + /* Primitive types */ %typemap(jni) bool, const bool & "jboolean" %typemap(jni) char, const char & "jchar" @@ -103,6 +111,21 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { %typemap(jstype) double, const double & "double" %typemap(jstype) void "void" +%typemap(jboxtype) bool, const bool & "Boolean" +%typemap(jboxtype) char, const char & "Character" +%typemap(jboxtype) signed char, const signed char & "Byte" +%typemap(jboxtype) unsigned char, const unsigned char & "Short" +%typemap(jboxtype) short, const short & "Short" +%typemap(jboxtype) unsigned short, const unsigned short & "Integer" +%typemap(jboxtype) int, const int & "Integer" +%typemap(jboxtype) unsigned int, const unsigned int & "Long" +%typemap(jboxtype) long, const long & "Integer" +%typemap(jboxtype) unsigned long, const unsigned long & "Long" +%typemap(jboxtype) long long, const long long & "Long" +%typemap(jboxtype) unsigned long long, const unsigned long long & "java.math.BigInteger" +%typemap(jboxtype) float, const float & "Float" +%typemap(jboxtype) double, const double & "Double" + %typemap(jni) char *, char *&, char[ANY], char[] "jstring" %typemap(jtype) char *, char *&, char[ANY], char[] "String" %typemap(jstype) char *, char *&, char[ANY], char[] "String" @@ -172,6 +195,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { %typemap(jni) SWIGTYPE "jlong" %typemap(jtype) SWIGTYPE "long" %typemap(jstype) SWIGTYPE "$&javaclassname" +%typemap(jboxtype) SWIGTYPE "$typemap(jstype, $1_type)" %typemap(jni) SWIGTYPE [] "jlong" %typemap(jtype) SWIGTYPE [] "long" @@ -1260,7 +1284,7 @@ SWIG_JAVABODY_TYPEWRAPPER(protected, protected, protected, SWIGTYPE) */ %define SWIG_PROXY_CONSTRUCTOR(OWNERSHIP, WEAKREF, TYPENAME...) -%typemap(javaconstruct,directorconnect="\n $imclassname.$javaclazznamedirector_connect(this, swigCPtr, swigCMemOwn, WEAKREF);") TYPENAME { +%typemap(javaconstruct,directorconnect="\n $imclassname.$javaclazznamedirector_connect(this, swigCPtr, OWNERSHIP, WEAKREF);") TYPENAME { this($imcall, OWNERSHIP);$directorconnect } %enddef @@ -1338,6 +1362,8 @@ SWIG_PROXY_CONSTRUCTOR(true, true, SWIGTYPE) /* const pointers */ %apply SWIGTYPE * { SWIGTYPE *const } +%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) } +%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) } /* String & length */ %typemap(jni) (char *STRING, size_t LENGTH) "jbyteArray" diff --git a/Lib/java/std_array.i b/Lib/java/std_array.i index cbacfe673..0944d932f 100644 --- a/Lib/java/std_array.i +++ b/Lib/java/std_array.i @@ -8,13 +8,13 @@ namespace std { template class array { public: - typedef T& reference; - typedef const T& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef T value_type; - typedef T* pointer; - typedef const T* const_pointer; + typedef T &reference; + typedef const T &const_reference; + typedef T *pointer; + typedef const T *const_pointer; array(); array(const array& other); size_type size() const; @@ -29,10 +29,10 @@ namespace std { else throw std::out_of_range("array index out of range"); } - void set(int i, const value_type& val) throw (std::out_of_range) { + void set(int i, const value_type& value) throw (std::out_of_range) { int size = int(self->size()); if (i>=0 && i + +%{ +#include +#include +%} + +%fragment("SWIG_ListSize", "header", fragment="SWIG_JavaIntFromSize_t") { +SWIGINTERN jint SWIG_ListSize(size_t size) { + jint sz = SWIG_JavaIntFromSize_t(size); + if (sz == -1) + throw std::out_of_range("list size is too large to fit into a Java int"); + return sz; +} +} + +%javamethodmodifiers std::list::begin "private"; +%javamethodmodifiers std::list::insert "private"; +%javamethodmodifiers std::list::doSize "private"; +%javamethodmodifiers std::list::doPreviousIndex "private"; +%javamethodmodifiers std::list::doNextIndex "private"; +%javamethodmodifiers std::list::doHasNext "private"; + +// Match Java style better: +%rename(Iterator) std::list::iterator; + +%nodefaultctor std::list::iterator; + +namespace std { + template class list { + +%typemap(javabase) std::list "java.util.AbstractSequentialList<$typemap(jboxtype, T)>" +%proxycode %{ + public $javaclassname(java.util.Collection c) { + this(); + java.util.ListIterator<$typemap(jboxtype, T)> it = listIterator(0); + // Special case the "copy constructor" here to avoid lots of cross-language calls + for (Object o : c) { + it.add(($typemap(jboxtype, T))o); + } + } + + public int size() { + return doSize(); + } + + public boolean add($typemap(jboxtype, T) value) { + addLast(value); + return true; + } + + public java.util.ListIterator<$typemap(jboxtype, T)> listIterator(int index) { + return new java.util.ListIterator<$typemap(jboxtype, T)>() { + private Iterator pos; + private Iterator last; + + private java.util.ListIterator<$typemap(jboxtype, T)> init(int index) { + if (index < 0 || index > $javaclassname.this.size()) + throw new IndexOutOfBoundsException("Index: " + index); + pos = $javaclassname.this.begin(); + pos = pos.advance_unchecked(index); + return this; + } + + public void add($typemap(jboxtype, T) v) { + // Technically we can invalidate last here, but this makes more sense + last = $javaclassname.this.insert(pos, v); + } + + public void set($typemap(jboxtype, T) v) { + if (null == last) { + throw new IllegalStateException(); + } + last.set_unchecked(v); + } + + public void remove() { + if (null == last) { + throw new IllegalStateException(); + } + $javaclassname.this.remove(last); + last = null; + } + + public int previousIndex() { + return $javaclassname.this.doPreviousIndex(pos); + } + + public int nextIndex() { + return $javaclassname.this.doNextIndex(pos); + } + + public $typemap(jboxtype, T) previous() { + if (previousIndex() < 0) { + throw new java.util.NoSuchElementException(); + } + last = pos; + pos = pos.previous_unchecked(); + return last.deref_unchecked(); + } + + public $typemap(jboxtype, T) next() { + if (!hasNext()) { + throw new java.util.NoSuchElementException(); + } + last = pos; + pos = pos.next_unchecked(); + return last.deref_unchecked(); + } + + public boolean hasPrevious() { + // This call to previousIndex() will be much slower than the hasNext() implementation, but it's simpler like this with C++ forward iterators + return previousIndex() != -1; + } + + public boolean hasNext() { + return $javaclassname.this.doHasNext(pos); + } + }.init(index); + } +%} + + public: + typedef size_t size_type; + typedef T value_type; + typedef T &reference; + + /* + * We'd actually be better off having the nested class *not* be static in the wrapper + * output, but this doesn't actually remove the $static from the nested class still. + * (This would allow us to somewhat simplify the implementation of the ListIterator + * interface and give "natural" semantics to Java users of the C++ iterator) + */ + //%typemap(javaclassmodifiers) iterator "public class" + //%typemap(javainterfaces) iterator "java.util.ListIterator<$typemap(jboxtype, T)>" + + struct iterator { + %extend { + void set_unchecked(const T &v) { + **$self = v; + } + + iterator next_unchecked() const { + std::list::iterator ret = *$self; + ++ret; + return ret; + } + + iterator previous_unchecked() const { + std::list::iterator ret = *$self; + --ret; + return ret; + } + + T deref_unchecked() const { + return **$self; + } + + iterator advance_unchecked(size_type index) const { + std::list::iterator ret = *$self; + std::advance(ret, index); + return ret; + } + } + }; + + list(); + list(const list &other); + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(remove) erase; + iterator erase(iterator pos); + %rename(removeLast) pop_back; + void pop_back(); + %rename(removeFirst) pop_front; + void pop_front(); + %rename(addLast) push_back; + void push_back(const T &value); + %rename(addFirst) push_front; + void push_front(const T &value); + iterator begin(); + iterator end(); + iterator insert(iterator pos, const T &value); + + %extend { + %fragment("SWIG_ListSize"); + list(jint count) throw (std::out_of_range) { + if (count < 0) + throw std::out_of_range("list count must be positive"); + return new std::list(static_cast::size_type>(count)); + } + + list(jint count, const T &value) throw (std::out_of_range) { + if (count < 0) + throw std::out_of_range("list count must be positive"); + return new std::list(static_cast::size_type>(count), value); + } + + jint doSize() const throw (std::out_of_range) { + return SWIG_ListSize(self->size()); + } + + jint doPreviousIndex(const iterator &pos) const throw (std::out_of_range) { + return pos == self->begin() ? -1 : SWIG_ListSize(std::distance(self->begin(), static_cast::const_iterator>(pos))); + } + + jint doNextIndex(const iterator &pos) const throw (std::out_of_range) { + return pos == self->end() ? SWIG_ListSize(self->size()) : SWIG_ListSize(std::distance(self->begin(), static_cast::const_iterator>(pos))); + } + + bool doHasNext(const iterator &pos) const { + return pos != $self->end(); + } + } + }; +} diff --git a/Lib/java/std_map.i b/Lib/java/std_map.i index e7812f38a..2405571fa 100644 --- a/Lib/java/std_map.i +++ b/Lib/java/std_map.i @@ -16,47 +16,44 @@ #include %} -// exported class - namespace std { - template class map { - // add typemaps here - public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef K key_type; - typedef T mapped_type; - map(); - map(const map &); - - unsigned int size() const; - bool empty() const; - void clear(); - %extend { - const T& get(const K& key) throw (std::out_of_range) { - std::map::iterator i = self->find(key); - if (i != self->end()) - return i->second; - else - throw std::out_of_range("key not found"); - } - void set(const K& key, const T& x) { - (*self)[key] = x; - } - void del(const K& key) throw (std::out_of_range) { - std::map::iterator i = self->find(key); - if (i != self->end()) - self->erase(i); - else - throw std::out_of_range("key not found"); - } - bool has_key(const K& key) { - std::map::iterator i = self->find(key); - return i != self->end(); - } + template class map { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef K key_type; + typedef T mapped_type; + map(); + map(const map &); + + unsigned int size() const; + bool empty() const; + void clear(); + %extend { + const T& get(const K& key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + return i->second; + else + throw std::out_of_range("key not found"); } - }; + void set(const K& key, const T& x) { + (*self)[key] = x; + } + void del(const K& key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + self->erase(i); + else + throw std::out_of_range("key not found"); + } + bool has_key(const K& key) { + std::map::iterator i = self->find(key); + return i != self->end(); + } + } + }; // Legacy macros (deprecated) %define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) diff --git a/Lib/java/std_vector.i b/Lib/java/std_vector.i index 971b426a1..57368c81a 100644 --- a/Lib/java/std_vector.i +++ b/Lib/java/std_vector.i @@ -1,5 +1,10 @@ /* ----------------------------------------------------------------------------- * std_vector.i + * + * SWIG typemaps for std::vector. + * The Java proxy class extends java.util.AbstractList and implements + * java.util.RandomAccess. The std::vector container looks and feels much like a + * java.util.ArrayList from Java. * ----------------------------------------------------------------------------- */ %include @@ -9,73 +14,171 @@ #include %} -namespace std { - - template class vector { - public: - typedef size_t size_type; - typedef T value_type; - typedef const value_type& const_reference; - vector(); - vector(size_type n); - size_type size() const; - size_type capacity() const; - void reserve(size_type n); - %rename(isEmpty) empty; - bool empty() const; - void clear(); - %rename(add) push_back; - void push_back(const value_type& x); - %extend { - const_reference get(int i) throw (std::out_of_range) { - int size = int(self->size()); - if (i>=0 && isize()); - if (i>=0 && i "java.util.AbstractList<$typemap(jboxtype, CTYPE)>" +%typemap(javainterfaces) std::vector< CTYPE > "java.util.RandomAccess" +%proxycode %{ + public $javaclassname($typemap(jstype, CTYPE)[] initialElements) { + this(); + for ($typemap(jstype, CTYPE) element : initialElements) { + add(element); + } + } + + public $javaclassname(Iterable<$typemap(jboxtype, CTYPE)> initialElements) { + this(); + for ($typemap(jstype, CTYPE) element : initialElements) { + add(element); + } + } + + public $typemap(jboxtype, CTYPE) get(int index) { + return doGet(index); + } + + public $typemap(jboxtype, CTYPE) set(int index, $typemap(jboxtype, CTYPE) e) { + return doSet(index, e); + } + + public boolean add($typemap(jboxtype, CTYPE) e) { + modCount++; + doAdd(e); + return true; + } + + public void add(int index, $typemap(jboxtype, CTYPE) e) { + modCount++; + doAdd(index, e); + } + + public $typemap(jboxtype, CTYPE) remove(int index) { + modCount++; + return doRemove(index); + } + + protected void removeRange(int fromIndex, int toIndex) { + modCount++; + doRemoveRange(fromIndex, toIndex); + } + + public int size() { + return doSize(); + } +%} + + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef CTYPE value_type; + typedef CTYPE &reference; + typedef CREF_TYPE const_reference; + typedef CTYPE *pointer; + typedef CTYPE const *const_pointer; + + vector(); + vector(const vector &other); + size_type capacity() const; + void reserve(size_type n) throw (std::length_error); + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %extend { + %fragment("SWIG_VectorSize"); + vector(jint count) throw (std::out_of_range) { + if (count < 0) + throw std::out_of_range("vector count must be positive"); + return new std::vector< CTYPE >(static_cast::size_type>(count)); + } + + vector(jint count, const CTYPE &value) throw (std::out_of_range) { + if (count < 0) + throw std::out_of_range("vector count must be positive"); + return new std::vector< CTYPE >(static_cast::size_type>(count), value); + } + + jint doSize() const throw (std::out_of_range) { + return SWIG_VectorSize(self->size()); + } + + void doAdd(const value_type& value) { + self->push_back(value); + } + + void doAdd(jint index, const value_type& value) throw (std::out_of_range) { + const jint size = static_cast::size_type>(self->size()); + if (0 <= index && index <= size) { + self->insert(self->begin() + index, value); + } else { + throw std::out_of_range("vector index out of range"); } + } + + value_type doRemove(jint index) throw (std::out_of_range) { + const jint size = static_cast::size_type>(self->size()); + if (0 <= index && index < size) { + CTYPE const old_value = (*self)[index]; + self->erase(self->begin() + index); + return old_value; + } else { + throw std::out_of_range("vector index out of range"); + } + } + + CREF_TYPE doGet(jint index) throw (std::out_of_range) { + const jint size = static_cast::size_type>(self->size()); + if (index >= 0 && index < size) + return (*self)[index]; + else + throw std::out_of_range("vector index out of range"); + } + + value_type doSet(jint index, const value_type& value) throw (std::out_of_range) { + const jint size = static_cast::size_type>(self->size()); + if (index >= 0 && index < size) { + CTYPE const old_value = (*self)[index]; + (*self)[index] = value; + return old_value; + } + else + throw std::out_of_range("vector index out of range"); + } + + void doRemoveRange(jint fromIndex, jint toIndex) throw (std::out_of_range) { + const jint size = static_cast::size_type>(self->size()); + if (0 <= fromIndex && fromIndex <= toIndex && toIndex <= size) { + self->erase(self->begin() + fromIndex, self->begin() + toIndex); + } else { + throw std::out_of_range("vector index out of range"); + } + } + } +%enddef + +%javamethodmodifiers std::vector::doSize "private"; +%javamethodmodifiers std::vector::doAdd "private"; +%javamethodmodifiers std::vector::doGet "private"; +%javamethodmodifiers std::vector::doSet "private"; +%javamethodmodifiers std::vector::doRemove "private"; +%javamethodmodifiers std::vector::doRemoveRange "private"; + +namespace std { + + template class vector { + SWIG_STD_VECTOR_MINIMUM_INTERNAL(T, const T&) }; // bool specialization template<> class vector { - public: - typedef size_t size_type; - typedef bool value_type; - typedef bool const_reference; - vector(); - vector(size_type n); - size_type size() const; - size_type capacity() const; - void reserve(size_type n); - %rename(isEmpty) empty; - bool empty() const; - void clear(); - %rename(add) push_back; - void push_back(const value_type& x); - %extend { - bool get(int i) throw (std::out_of_range) { - int size = int(self->size()); - if (i>=0 && isize()); - if (i>=0 && i raise (NoSuchClass nm) + try (Obj.magic (Hashtbl.find class_master_list nm)) with _ -> raise (NoSuchClass nm) diff --git a/Lib/ocaml/typemaps.i b/Lib/ocaml/typemaps.i index 7602ad629..b70b78928 100644 --- a/Lib/ocaml/typemaps.i +++ b/Lib/ocaml/typemaps.i @@ -368,4 +368,6 @@ SIMPLE_MAP(unsigned long long,caml_val_ulong,caml_long_val); /* const pointers */ %apply SWIGTYPE * { SWIGTYPE *const } +%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) } +%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) } diff --git a/Lib/octave/boost_shared_ptr.i b/Lib/octave/boost_shared_ptr.i index e91862057..4ef646831 100644 --- a/Lib/octave/boost_shared_ptr.i +++ b/Lib/octave/boost_shared_ptr.i @@ -8,7 +8,7 @@ %naturalvar SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >; // destructor wrapper customisation -%feature("unref") TYPE +%feature("unref") TYPE //"if (debug_shared) { cout << \"deleting use_count: \" << (*smartarg1).use_count() << \" [\" << (boost::get_deleter(*smartarg1) ? std::string(\"CANNOT BE DETERMINED SAFELY\") : ( (*smartarg1).get() ? (*smartarg1)->getValue() : std::string(\"NULL PTR\") )) << \"]\" << endl << flush; }\n" "(void)arg1; delete smartarg1;" @@ -19,7 +19,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (!argp) { %argument_nullref("$type", $symname, $argnum); @@ -58,7 +58,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { tempshared = *%reinterpret_cast(argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *); @@ -102,7 +102,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (!argp) { %argument_nullref("$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { @@ -148,7 +148,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { tempshared = *%reinterpret_cast(argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *); @@ -176,7 +176,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (argp) $1 = *(%reinterpret_cast(argp, $<ype)); if (newmem & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(argp, $<ype); @@ -206,7 +206,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { if (argp) tempshared = *%reinterpret_cast(argp, $ltype); @@ -233,7 +233,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { if (argp) tempshared = *%reinterpret_cast(argp, $ltype); @@ -261,7 +261,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (argp) tempshared = *%reinterpret_cast(argp, $*ltype); if (newmem & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(argp, $*ltype); @@ -281,9 +281,9 @@ %} // Typecheck typemaps -// Note: SWIG_ConvertPtr with void ** parameter set to 0 instead of using SWIG_ConvertPtrAndOwn, so that the casting +// Note: SWIG_ConvertPtr with void ** parameter set to 0 instead of using SWIG_ConvertPtrAndOwn, so that the casting // function is not called thereby avoiding a possible smart pointer copy constructor call when casting up the inheritance chain. -%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) +%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) TYPE CONST, TYPE CONST &, TYPE CONST *, diff --git a/Lib/octave/octcontainer.swg b/Lib/octave/octcontainer.swg index 771edbde0..9b6520739 100644 --- a/Lib/octave/octcontainer.swg +++ b/Lib/octave/octcontainer.swg @@ -202,8 +202,8 @@ namespace swig // swig::SwigVar_PyObject item = OctSequence_GetItem(_seq, _index); octave_value item; // * todo try { - return swig::as(item, true); - } catch (std::exception& e) { + return swig::as(item); + } catch (const std::exception& e) { char msg[1024]; sprintf(msg, "in sequence element %d ", _index); if (!Octave_Error_Occurred()) { diff --git a/Lib/octave/octstdcommon.swg b/Lib/octave/octstdcommon.swg index 799d369a7..80b2154d9 100644 --- a/Lib/octave/octstdcommon.swg +++ b/Lib/octave/octstdcommon.swg @@ -41,7 +41,7 @@ namespace swig { template struct traits_asptr { static int asptr(const octave_value& obj, Type **val) { - Type *p; + Type *p = 0; swig_type_info *descriptor = type_info(); int res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res)) { @@ -103,14 +103,14 @@ namespace swig { template struct traits_as { - static Type as(const octave_value& obj, bool throw_error) { + static Type as(const octave_value& obj) { Type v; int res = asval(obj, &v); if (!obj.is_defined() || !SWIG_IsOK(res)) { if (!Octave_Error_Occurred()) { %type_error(swig::type_name()); } - if (throw_error) throw std::invalid_argument("bad type"); + throw std::invalid_argument("bad type"); } return v; } @@ -118,7 +118,7 @@ namespace swig { template struct traits_as { - static Type as(const octave_value& obj, bool throw_error) { + static Type as(const octave_value& obj) { Type *v = 0; int res = traits_asptr::asptr(obj, &v); if (SWIG_IsOK(res) && v) { @@ -130,21 +130,17 @@ namespace swig { return *v; } } else { - // Uninitialized return value, no Type() constructor required. - static Type *v_def = (Type*) malloc(sizeof(Type)); if (!Octave_Error_Occurred()) { %type_error(swig::type_name()); } - if (throw_error) throw std::invalid_argument("bad type"); - memset(v_def,0,sizeof(Type)); - return *v_def; + throw std::invalid_argument("bad type"); } } }; template struct traits_as { - static Type* as(const octave_value& obj, bool throw_error) { + static Type* as(const octave_value& obj) { Type *v = 0; int res = traits_asptr::asptr(obj, &v); if (SWIG_IsOK(res)) { @@ -153,15 +149,14 @@ namespace swig { if (!Octave_Error_Occurred()) { %type_error(swig::type_name()); } - if (throw_error) throw std::invalid_argument("bad type"); - return 0; + throw std::invalid_argument("bad type"); } } }; template - inline Type as(const octave_value& obj, bool te = false) { - return traits_as::category>::as(obj, te); + inline Type as(const octave_value& obj) { + return traits_as::category>::as(obj); } template diff --git a/Lib/perl5/perlrun.swg b/Lib/perl5/perlrun.swg index d1865de0a..cc4ba446a 100644 --- a/Lib/perl5/perlrun.swg +++ b/Lib/perl5/perlrun.swg @@ -392,7 +392,7 @@ SWIG_Perl_NewPackedObj(SWIG_MAYBE_PERL_OBJECT void *ptr, int sz, swig_type_info return result; } -/* Convert a packed value value */ +/* Convert a packed pointer value */ SWIGRUNTIME int SWIG_Perl_ConvertPacked(SWIG_MAYBE_PERL_OBJECT SV *obj, void *ptr, int sz, swig_type_info *ty) { swig_cast_info *tc; diff --git a/Lib/php/php.swg b/Lib/php/php.swg index c9b9a5217..83f76217a 100644 --- a/Lib/php/php.swg +++ b/Lib/php/php.swg @@ -134,7 +134,7 @@ %typemap(in) SWIGTYPE *DISOWN %{ if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, SWIG_POINTER_DISOWN ) < 0) { - SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $&1_descriptor"); + SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor"); } %} @@ -525,7 +525,8 @@ /* const pointers */ %apply SWIGTYPE * { SWIGTYPE *const } - +%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) } +%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) } /* php keywords */ %include diff --git a/Lib/php5/php.swg b/Lib/php5/php.swg index 535c7d347..6f8470ff9 100644 --- a/Lib/php5/php.swg +++ b/Lib/php5/php.swg @@ -134,7 +134,7 @@ %typemap(in) SWIGTYPE *DISOWN { if(SWIG_ConvertPtr(*$input, (void **) &$1, $1_descriptor, SWIG_POINTER_DISOWN ) < 0) { - SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $&1_descriptor"); + SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor"); } } @@ -523,7 +523,8 @@ /* const pointers */ %apply SWIGTYPE * { SWIGTYPE *const } - +%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) } +%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) } /* php keywords */ %include diff --git a/Lib/pike/pike.swg b/Lib/pike/pike.swg index 95cc20835..a36bf3ad2 100644 --- a/Lib/pike/pike.swg +++ b/Lib/pike/pike.swg @@ -273,6 +273,8 @@ extern "C" { /* const pointers */ %apply SWIGTYPE * { SWIGTYPE *const } +%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) } +%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) } /* ------------------------------------------------------------ * Overloaded operator support diff --git a/Lib/python/boost_shared_ptr.i b/Lib/python/boost_shared_ptr.i index c031adcc8..19e440865 100644 --- a/Lib/python/boost_shared_ptr.i +++ b/Lib/python/boost_shared_ptr.i @@ -18,7 +18,7 @@ %naturalvar SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >; // destructor wrapper customisation -%feature("unref") TYPE +%feature("unref") TYPE //"if (debug_shared) { cout << \"deleting use_count: \" << (*smartarg1).use_count() << \" [\" << (boost::get_deleter(*smartarg1) ? std::string(\"CANNOT BE DETERMINED SAFELY\") : ( (*smartarg1).get() ? (*smartarg1)->getValue() : std::string(\"NULL PTR\") )) << \"]\" << endl << flush; }\n" "(void)arg1; delete smartarg1;" @@ -29,7 +29,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (!argp) { %argument_nullref("$type", $symname, $argnum); @@ -68,7 +68,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SHARED_PTR_DISOWN | %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { tempshared = *%reinterpret_cast(argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *); @@ -113,7 +113,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (!argp) { %argument_nullref("$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { @@ -159,7 +159,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SHARED_PTR_DISOWN | %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { tempshared = *%reinterpret_cast(argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *); @@ -187,7 +187,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (argp) $1 = *(%reinterpret_cast(argp, $<ype)); if (newmem & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(argp, $<ype); @@ -217,7 +217,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { if (argp) tempshared = *%reinterpret_cast(argp, $ltype); @@ -244,7 +244,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { if (argp) tempshared = *%reinterpret_cast(argp, $ltype); @@ -272,7 +272,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (argp) tempshared = *%reinterpret_cast(argp, $*ltype); if (newmem & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(argp, $*ltype); @@ -292,9 +292,9 @@ %} // Typecheck typemaps -// Note: SWIG_ConvertPtr with void ** parameter set to 0 instead of using SWIG_ConvertPtrAndOwn, so that the casting +// Note: SWIG_ConvertPtr with void ** parameter set to 0 instead of using SWIG_ConvertPtrAndOwn, so that the casting // function is not called thereby avoiding a possible smart pointer copy constructor call when casting up the inheritance chain. -%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) +%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) TYPE CONST, TYPE CONST &, TYPE CONST *, @@ -324,4 +324,3 @@ %enddef - diff --git a/Lib/python/builtin.swg b/Lib/python/builtin.swg index 4fd19471a..99903a9b5 100644 --- a/Lib/python/builtin.swg +++ b/Lib/python/builtin.swg @@ -393,10 +393,10 @@ SwigPyStaticVar_new_getset(PyTypeObject *type, PyGetSetDef *getset) { SWIGINTERN void SwigPyBuiltin_InitBases (PyTypeObject *type, PyTypeObject **bases) { - int base_count = 0; + Py_ssize_t base_count = 0; PyTypeObject **b; PyObject *tuple; - int i; + Py_ssize_t i; if (!bases[0]) { bases[0] = SwigPyObject_type(); diff --git a/Lib/python/pycontainer.swg b/Lib/python/pycontainer.swg index d40b0baa8..36557d75e 100644 --- a/Lib/python/pycontainer.swg +++ b/Lib/python/pycontainer.swg @@ -102,7 +102,7 @@ namespace swig { } } -%fragment("SwigPySequence_Base","header",fragment="") +%fragment("SwigPySequence_Base","header",fragment="",fragment="StdTraits") { %#include @@ -351,7 +351,7 @@ namespace swig { typename Sequence::const_iterator isit = is.begin(); typename Sequence::iterator it = self->begin(); std::advance(it,ii); - for (size_t rc=0; rcend(); ++rc) { *it++ = *isit++; for (Py_ssize_t c=0; c<(step-1) && it != self->end(); ++c) it++; @@ -367,7 +367,7 @@ namespace swig { typename Sequence::const_iterator isit = is.begin(); typename Sequence::reverse_iterator it = self->rbegin(); std::advance(it,size-ii-1); - for (size_t rc=0; rcrend(); ++rc) { *it++ = *isit++; for (Py_ssize_t c=0; c<(-step-1) && it != self->rend(); ++c) it++; @@ -434,8 +434,8 @@ namespace swig { swig::SwigVar_PyObject item = PySequence_GetItem(_seq, _index); try { - return swig::as(item, true); - } catch (std::exception& e) { + return swig::as(item); + } catch (const std::invalid_argument& e) { char msg[1024]; sprintf(msg, "in sequence element %d ", (int)_index); if (!PyErr_Occurred()) { @@ -655,6 +655,14 @@ namespace swig } %define %swig_sequence_iterator(Sequence...) + %swig_sequence_iterator_with_making_function(swig::make_output_iterator,Sequence...) +%enddef + +%define %swig_sequence_forward_iterator(Sequence...) + %swig_sequence_iterator_with_making_function(swig::make_output_forward_iterator,Sequence...) +%enddef + +%define %swig_sequence_iterator_with_making_function(Make_output_iterator,Sequence...) #if defined(SWIG_EXPORT_ITERATOR_METHODS) class iterator; class reverse_iterator; @@ -663,15 +671,15 @@ namespace swig %typemap(out,noblock=1,fragment="SwigPySequence_Cont") iterator, reverse_iterator, const_iterator, const_reverse_iterator { - $result = SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &)), + $result = SWIG_NewPointerObj(Make_output_iterator(%static_cast($1,const $type &)), swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN); } %typemap(out,noblock=1,fragment="SwigPySequence_Cont") std::pair, std::pair { $result = PyTuple_New(2); - PyTuple_SetItem($result,0,SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &).first), + PyTuple_SetItem($result,0,SWIG_NewPointerObj(Make_output_iterator(%static_cast($1,const $type &).first), swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN)); - PyTuple_SetItem($result,1,SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &).second), + PyTuple_SetItem($result,1,SWIG_NewPointerObj(Make_output_iterator(%static_cast($1,const $type &).second), swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN)); } @@ -680,7 +688,7 @@ namespace swig %typemap(out,noblock=1,fragment="SwigPyPairBoolOutputIterator") std::pair, std::pair { $result = PyTuple_New(2); - PyTuple_SetItem($result,0,SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &).first), + PyTuple_SetItem($result,0,SWIG_NewPointerObj(Make_output_iterator(%static_cast($1,const $type &).first), swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN)); PyTuple_SetItem($result,1,SWIG_From(bool)(%static_cast($1,const $type &).second)); } @@ -715,7 +723,7 @@ namespace swig %newobject iterator(PyObject **PYTHON_SELF); %extend { swig::SwigPyIterator* iterator(PyObject **PYTHON_SELF) { - return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF); + return Make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF); } #if defined(SWIGPYTHON_BUILTIN) diff --git a/Lib/python/pyinit.swg b/Lib/python/pyinit.swg index 2cc582841..fe45ac941 100644 --- a/Lib/python/pyinit.swg +++ b/Lib/python/pyinit.swg @@ -306,9 +306,9 @@ SWIG_Python_FixMethods(PyMethodDef *methods, char *ndoc = (char*)malloc(ldoc + lptr + 10); if (ndoc) { char *buff = ndoc; - strncpy(buff, methods[i].ml_doc, ldoc); + memcpy(buff, methods[i].ml_doc, ldoc); buff += ldoc; - strncpy(buff, "swig_ptr: ", 10); + memcpy(buff, "swig_ptr: ", 10); buff += 10; SWIG_PackVoidPtr(buff, ptr, ty->name, lptr); methods[i].ml_doc = ndoc; diff --git a/Lib/python/pyiterators.swg b/Lib/python/pyiterators.swg index 8fbb31226..cb15e35cd 100644 --- a/Lib/python/pyiterators.swg +++ b/Lib/python/pyiterators.swg @@ -198,16 +198,16 @@ namespace swig { template::value_type, typename FromOper = from_oper > - class SwigPyIteratorOpen_T : public SwigPyIterator_T + class SwigPyForwardIteratorOpen_T : public SwigPyIterator_T { public: FromOper from; typedef OutIterator out_iterator; typedef ValueType value_type; typedef SwigPyIterator_T base; - typedef SwigPyIteratorOpen_T self_type; + typedef SwigPyForwardIteratorOpen_T self_type; - SwigPyIteratorOpen_T(out_iterator curr, PyObject *seq) + SwigPyForwardIteratorOpen_T(out_iterator curr, PyObject *seq) : SwigPyIterator_T(curr, seq) { } @@ -229,6 +229,25 @@ namespace swig { return this; } + }; + + template::value_type, + typename FromOper = from_oper > + class SwigPyIteratorOpen_T : public SwigPyForwardIteratorOpen_T + { + public: + FromOper from; + typedef OutIterator out_iterator; + typedef ValueType value_type; + typedef SwigPyIterator_T base; + typedef SwigPyIteratorOpen_T self_type; + + SwigPyIteratorOpen_T(out_iterator curr, PyObject *seq) + : SwigPyForwardIteratorOpen_T(curr, seq) + { + } + SwigPyIterator *decr(size_t n = 1) { while (n--) { @@ -241,16 +260,16 @@ namespace swig { template::value_type, typename FromOper = from_oper > - class SwigPyIteratorClosed_T : public SwigPyIterator_T + class SwigPyForwardIteratorClosed_T : public SwigPyIterator_T { public: FromOper from; typedef OutIterator out_iterator; typedef ValueType value_type; typedef SwigPyIterator_T base; - typedef SwigPyIteratorClosed_T self_type; + typedef SwigPyForwardIteratorClosed_T self_type; - SwigPyIteratorClosed_T(out_iterator curr, out_iterator first, out_iterator last, PyObject *seq) + SwigPyForwardIteratorClosed_T(out_iterator curr, out_iterator first, out_iterator last, PyObject *seq) : SwigPyIterator_T(curr, seq), begin(first), end(last) { } @@ -280,10 +299,33 @@ namespace swig { return this; } + protected: + out_iterator begin; + out_iterator end; + }; + + template::value_type, + typename FromOper = from_oper > + class SwigPyIteratorClosed_T : public SwigPyForwardIteratorClosed_T + { + public: + FromOper from; + typedef OutIterator out_iterator; + typedef ValueType value_type; + typedef SwigPyIterator_T base; + typedef SwigPyForwardIteratorClosed_T base0; + typedef SwigPyIteratorClosed_T self_type; + + SwigPyIteratorClosed_T(out_iterator curr, out_iterator first, out_iterator last, PyObject *seq) + : SwigPyForwardIteratorClosed_T(curr, first, last, seq) + { + } + SwigPyIterator *decr(size_t n = 1) { while (n--) { - if (base::current == begin) { + if (base::current == base0::begin) { throw stop_iteration(); } else { --base::current; @@ -291,12 +333,16 @@ namespace swig { } return this; } - - private: - out_iterator begin; - out_iterator end; }; + + template + inline SwigPyIterator* + make_output_forward_iterator(const OutIter& current, const OutIter& begin,const OutIter& end, PyObject *seq = 0) + { + return new SwigPyForwardIteratorClosed_T(current, begin, end, seq); + } + template inline SwigPyIterator* make_output_iterator(const OutIter& current, const OutIter& begin,const OutIter& end, PyObject *seq = 0) @@ -304,6 +350,13 @@ namespace swig { return new SwigPyIteratorClosed_T(current, begin, end, seq); } + template + inline SwigPyIterator* + make_output_forward_iterator(const OutIter& current, PyObject *seq = 0) + { + return new SwigPyForwardIteratorOpen_T(current, seq); + } + template inline SwigPyIterator* make_output_iterator(const OutIter& current, PyObject *seq = 0) diff --git a/Lib/python/pyrun.swg b/Lib/python/pyrun.swg index ab1237f62..efc476613 100644 --- a/Lib/python/pyrun.swg +++ b/Lib/python/pyrun.swg @@ -538,7 +538,7 @@ SwigPyObject_dealloc(PyObject *v) PyObject *res; /* PyObject_CallFunction() has the potential to silently drop - the active active exception. In cases of unnamed temporary + the active exception. In cases of unnamed temporary variable or where we just finished iterating over a generator StopIteration will be active right now, and this needs to remain true upon return from SwigPyObject_dealloc. So save @@ -1287,31 +1287,28 @@ SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { return SWIG_ConvertPtr(obj, ptr, ty, 0); } else { void *vptr = 0; - + swig_cast_info *tc; + /* here we get the method pointer for callbacks */ const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0; if (desc) desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0; - if (!desc) + if (!desc) return SWIG_ERROR; - if (ty) { - swig_cast_info *tc = SWIG_TypeCheck(desc,ty); - if (tc) { - int newmemory = 0; - *ptr = SWIG_TypeCast(tc,vptr,&newmemory); - assert(!newmemory); /* newmemory handling not yet implemented */ - } else { - return SWIG_ERROR; - } + tc = SWIG_TypeCheck(desc,ty); + if (tc) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + assert(!newmemory); /* newmemory handling not yet implemented */ } else { - *ptr = vptr; + return SWIG_ERROR; } return SWIG_OK; } } -/* Convert a packed value value */ +/* Convert a packed pointer value */ SWIGRUNTIME int SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { diff --git a/Lib/python/pyruntime.swg b/Lib/python/pyruntime.swg index fad97be9f..26d3081a0 100644 --- a/Lib/python/pyruntime.swg +++ b/Lib/python/pyruntime.swg @@ -3,7 +3,7 @@ /* Use debug wrappers with the Python release dll */ # undef _DEBUG # include -# define _DEBUG +# define _DEBUG 1 #else # include #endif diff --git a/Lib/python/pystdcommon.swg b/Lib/python/pystdcommon.swg index 8372426a0..0242e4d35 100644 --- a/Lib/python/pystdcommon.swg +++ b/Lib/python/pystdcommon.swg @@ -45,7 +45,7 @@ namespace swig { template struct traits_asptr { static int asptr(PyObject *obj, Type **val) { - Type *p; + Type *p = 0; swig_type_info *descriptor = type_info(); int res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res)) { @@ -107,14 +107,14 @@ namespace swig { template struct traits_as { - static Type as(PyObject *obj, bool throw_error) { + static Type as(PyObject *obj) { Type v; int res = asval(obj, &v); if (!obj || !SWIG_IsOK(res)) { if (!PyErr_Occurred()) { ::%type_error(swig::type_name()); } - if (throw_error) throw std::invalid_argument("bad type"); + throw std::invalid_argument("bad type"); } return v; } @@ -122,7 +122,7 @@ namespace swig { template struct traits_as { - static Type as(PyObject *obj, bool throw_error) { + static Type as(PyObject *obj) { Type *v = 0; int res = (obj ? traits_asptr::asptr(obj, &v) : SWIG_ERROR); if (SWIG_IsOK(res) && v) { @@ -134,21 +134,17 @@ namespace swig { return *v; } } else { - // Uninitialized return value, no Type() constructor required. - static Type *v_def = (Type*) malloc(sizeof(Type)); if (!PyErr_Occurred()) { %type_error(swig::type_name()); } - if (throw_error) throw std::invalid_argument("bad type"); - memset(v_def,0,sizeof(Type)); - return *v_def; + throw std::invalid_argument("bad type"); } } }; template struct traits_as { - static Type* as(PyObject *obj, bool throw_error) { + static Type* as(PyObject *obj) { Type *v = 0; int res = (obj ? traits_asptr::asptr(obj, &v) : SWIG_ERROR); if (SWIG_IsOK(res)) { @@ -157,15 +153,14 @@ namespace swig { if (!PyErr_Occurred()) { %type_error(swig::type_name()); } - if (throw_error) throw std::invalid_argument("bad type"); - return 0; + throw std::invalid_argument("bad type"); } } }; template - inline Type as(PyObject *obj, bool te = false) { - return traits_as::category>::as(obj, te); + inline Type as(PyObject *obj) { + return traits_as::category>::as(obj); } template diff --git a/Lib/python/std_multimap.i b/Lib/python/std_multimap.i index 3209fb0f8..f78a5277c 100644 --- a/Lib/python/std_multimap.i +++ b/Lib/python/std_multimap.i @@ -23,7 +23,11 @@ int res = SWIG_ERROR; if (PyDict_Check(obj)) { SwigVar_PyObject items = PyObject_CallMethod(obj,(char *)"items",NULL); - return traits_asptr_stdseq, std::pair >::asptr(items, val); +%#if PY_VERSION_HEX >= 0x03000000 + /* In Python 3.x the ".items()" method returns a dict_items object */ + items = PySequence_Fast(items, ".items() didn't return a sequence!"); +%#endif + res = traits_asptr_stdseq, std::pair >::asptr(items, val); } else { multimap_type *p; swig_type_info *descriptor = swig::type_info(); @@ -68,7 +72,17 @@ %define %swig_multimap_methods(Type...) %swig_map_common(Type); + +#if defined(SWIGPYTHON_BUILTIN) + %feature("python:slot", "mp_ass_subscript", functype="objobjargproc") __setitem__; +#endif + %extend { + // This will be called through the mp_ass_subscript slot to delete an entry. + void __setitem__(const key_type& key) { + self->erase(key); + } + void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) { self->insert(Type::value_type(key,x)); } diff --git a/Lib/python/std_unordered_map.i b/Lib/python/std_unordered_map.i index 894840c6c..53f6aa283 100644 --- a/Lib/python/std_unordered_map.i +++ b/Lib/python/std_unordered_map.i @@ -2,7 +2,7 @@ Unordered Maps */ -%fragment("StdMapTraits","header",fragment="StdSequenceTraits") +%fragment("StdUnorderedMapTraits","header",fragment="StdSequenceTraits") { namespace swig { template @@ -53,7 +53,7 @@ static PyObject *from(const unordered_map_type& unordered_map) { swig_type_info *desc = swig::type_info(); if (desc && desc->clientdata) { - return SWIG_NewPointerObj(new unordered_map_type(unordered_map), desc, SWIG_POINTER_OWN); + return SWIG_InternalNewPointerObj(new unordered_map_type(unordered_map), desc, SWIG_POINTER_OWN); } else { size_type size = unordered_map.size(); Py_ssize_t pysize = (size <= (size_type) INT_MAX) ? (Py_ssize_t) size : -1; @@ -74,33 +74,11 @@ } }; - template - struct from_key_oper - { - typedef const ValueType& argument_type; - typedef PyObject *result_type; - result_type operator()(argument_type v) const - { - return swig::from(v.first); - } - }; - - template - struct from_value_oper - { - typedef const ValueType& argument_type; - typedef PyObject *result_type; - result_type operator()(argument_type v) const - { - return swig::from(v.second); - } - }; - template - struct SwigPyMapIterator_T : SwigPyIteratorClosed_T + struct SwigPyMapForwardIterator_T : SwigPyForwardIteratorClosed_T { - SwigPyMapIterator_T(OutIterator curr, OutIterator first, OutIterator last, PyObject *seq) - : SwigPyIteratorClosed_T(curr, first, last, seq) + SwigPyMapForwardIterator_T(OutIterator curr, OutIterator first, OutIterator last, PyObject *seq) + : SwigPyForwardIteratorClosed_T(curr, first, last, seq) { } }; @@ -108,27 +86,27 @@ template > - struct SwigPyMapKeyIterator_T : SwigPyMapIterator_T + struct SwigPyMapKeyForwardIterator_T : SwigPyMapForwardIterator_T { - SwigPyMapKeyIterator_T(OutIterator curr, OutIterator first, OutIterator last, PyObject *seq) - : SwigPyMapIterator_T(curr, first, last, seq) + SwigPyMapKeyForwardIterator_T(OutIterator curr, OutIterator first, OutIterator last, PyObject *seq) + : SwigPyMapForwardIterator_T(curr, first, last, seq) { } }; template inline SwigPyIterator* - make_output_key_iterator(const OutIter& current, const OutIter& begin, const OutIter& end, PyObject *seq = 0) + make_output_key_forward_iterator(const OutIter& current, const OutIter& begin, const OutIter& end, PyObject *seq = 0) { - return new SwigPyMapKeyIterator_T(current, begin, end, seq); + return new SwigPyMapKeyForwardIterator_T(current, begin, end, seq); } template > - struct SwigPyMapValueITerator_T : SwigPyMapIterator_T + struct SwigPyMapValueForwardIterator_T : SwigPyMapForwardIterator_T { - SwigPyMapValueITerator_T(OutIterator curr, OutIterator first, OutIterator last, PyObject *seq) - : SwigPyMapIterator_T(curr, first, last, seq) + SwigPyMapValueForwardIterator_T(OutIterator curr, OutIterator first, OutIterator last, PyObject *seq) + : SwigPyMapForwardIterator_T(curr, first, last, seq) { } }; @@ -136,15 +114,15 @@ template inline SwigPyIterator* - make_output_value_iterator(const OutIter& current, const OutIter& begin, const OutIter& end, PyObject *seq = 0) + make_output_value_forward_iterator(const OutIter& current, const OutIter& begin, const OutIter& end, PyObject *seq = 0) { - return new SwigPyMapValueITerator_T(current, begin, end, seq); + return new SwigPyMapValueForwardIterator_T(current, begin, end, seq); } } } %define %swig_unordered_map_common(Map...) - %swig_sequence_iterator(Map); + %swig_sequence_forward_iterator(Map); %swig_container_methods(Map) %extend { @@ -227,12 +205,12 @@ %newobject key_iterator(PyObject **PYTHON_SELF); swig::SwigPyIterator* key_iterator(PyObject **PYTHON_SELF) { - return swig::make_output_key_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF); + return swig::make_output_key_forward_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF); } %newobject value_iterator(PyObject **PYTHON_SELF); swig::SwigPyIterator* value_iterator(PyObject **PYTHON_SELF) { - return swig::make_output_value_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF); + return swig::make_output_value_forward_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF); } %pythoncode %{def __iter__(self): @@ -248,7 +226,17 @@ %define %swig_unordered_map_methods(Map...) %swig_unordered_map_common(Map) + +#if defined(SWIGPYTHON_BUILTIN) + %feature("python:slot", "mp_ass_subscript", functype="objobjargproc") __setitem__; +#endif + %extend { + // This will be called through the mp_ass_subscript slot to delete an entry. + void __setitem__(const key_type& key) { + self->erase(key); + } + void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) { (*self)[key] = x; } diff --git a/Lib/python/std_unordered_multimap.i b/Lib/python/std_unordered_multimap.i index 2410aa52b..6d7def900 100644 --- a/Lib/python/std_unordered_multimap.i +++ b/Lib/python/std_unordered_multimap.i @@ -30,7 +30,11 @@ int res = SWIG_ERROR; if (PyDict_Check(obj)) { SwigVar_PyObject items = PyObject_CallMethod(obj,(char *)"items",NULL); - return traits_asptr_stdseq, std::pair >::asptr(items, val); +%#if PY_VERSION_HEX >= 0x03000000 + /* In Python 3.x the ".items()" method returns a dict_items object */ + items = PySequence_Fast(items, ".items() didn't return a sequence!"); +%#endif + res = traits_asptr_stdseq, std::pair >::asptr(items, val); } else { unordered_multimap_type *p; swig_type_info *descriptor = swig::type_info(); @@ -50,7 +54,7 @@ static PyObject *from(const unordered_multimap_type& unordered_multimap) { swig_type_info *desc = swig::type_info(); if (desc && desc->clientdata) { - return SWIG_NewPointerObj(new unordered_multimap_type(unordered_multimap), desc, SWIG_POINTER_OWN); + return SWIG_InternalNewPointerObj(new unordered_multimap_type(unordered_multimap), desc, SWIG_POINTER_OWN); } else { size_type size = unordered_multimap.size(); Py_ssize_t pysize = (size <= (size_type) INT_MAX) ? (Py_ssize_t) size : -1; @@ -74,8 +78,18 @@ } %define %swig_unordered_multimap_methods(Type...) - %swig_map_common(Type); + %swig_unordered_map_common(Type); + +#if defined(SWIGPYTHON_BUILTIN) + %feature("python:slot", "mp_ass_subscript", functype="objobjargproc") __setitem__; +#endif + %extend { + // This will be called through the mp_ass_subscript slot to delete an entry. + void __setitem__(const key_type& key) { + self->erase(key); + } + void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) { self->insert(Type::value_type(key,x)); } diff --git a/Lib/python/std_unordered_multiset.i b/Lib/python/std_unordered_multiset.i index 0d9f3d9c6..d90a97bdc 100644 --- a/Lib/python/std_unordered_multiset.i +++ b/Lib/python/std_unordered_multiset.i @@ -41,7 +41,7 @@ } %} -#define %swig_unordered_multiset_methods(Set...) %swig_set_methods(Set) +#define %swig_unordered_multiset_methods(Set...) %swig_unordered_set_methods(Set) diff --git a/Lib/python/std_unordered_set.i b/Lib/python/std_unordered_set.i index 855a28da5..6c646509c 100644 --- a/Lib/python/std_unordered_set.i +++ b/Lib/python/std_unordered_set.i @@ -40,7 +40,7 @@ %} %define %swig_unordered_set_methods(unordered_set...) - %swig_sequence_iterator(unordered_set); + %swig_sequence_forward_iterator(unordered_set); %swig_container_methods(unordered_set); %extend { diff --git a/Lib/r/boost_shared_ptr.i b/Lib/r/boost_shared_ptr.i index 8ef8d2ef2..4a56d7cba 100644 --- a/Lib/r/boost_shared_ptr.i +++ b/Lib/r/boost_shared_ptr.i @@ -8,7 +8,7 @@ %naturalvar SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >; // destructor wrapper customisation -%feature("unref") TYPE +%feature("unref") TYPE //"if (debug_shared) { cout << \"deleting use_count: \" << (*smartarg1).use_count() << \" [\" << (boost::get_deleter(*smartarg1) ? std::string(\"CANNOT BE DETERMINED SAFELY\") : ( (*smartarg1).get() ? (*smartarg1)->getValue() : std::string(\"NULL PTR\") )) << \"]\" << endl << flush; }\n" "(void)arg1; delete smartarg1;" @@ -19,7 +19,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (!argp) { %argument_nullref("$type", $symname, $argnum); @@ -56,7 +56,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { tempshared = *%reinterpret_cast(argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *); @@ -100,7 +100,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (!argp) { %argument_nullref("$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { @@ -146,7 +146,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { tempshared = *%reinterpret_cast(argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *); @@ -174,7 +174,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (argp) $1 = *(%reinterpret_cast(argp, $<ype)); if (newmem & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(argp, $<ype); @@ -204,7 +204,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { if (argp) tempshared = *%reinterpret_cast(argp, $ltype); @@ -231,7 +231,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { if (argp) tempshared = *%reinterpret_cast(argp, $ltype); @@ -259,7 +259,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (argp) tempshared = *%reinterpret_cast(argp, $*ltype); if (newmem & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(argp, $*ltype); @@ -279,9 +279,9 @@ %} // Typecheck typemaps -// Note: SWIG_ConvertPtr with void ** parameter set to 0 instead of using SWIG_ConvertPtrAndOwn, so that the casting +// Note: SWIG_ConvertPtr with void ** parameter set to 0 instead of using SWIG_ConvertPtrAndOwn, so that the casting // function is not called thereby avoiding a possible smart pointer copy constructor call when casting up the inheritance chain. -%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) +%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) TYPE CONST, TYPE CONST &, TYPE CONST *, diff --git a/Lib/r/rrun.swg b/Lib/r/rrun.swg index 81f6461d2..63b7ecc70 100644 --- a/Lib/r/rrun.swg +++ b/Lib/r/rrun.swg @@ -350,7 +350,7 @@ SWIG_R_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { return ptr ? RSwigPacked_New((void *) ptr, sz, type) : R_NilValue; } -/* Convert a packed value value */ +/* Convert a packed pointer value */ SWIGRUNTIME int SWIG_R_ConvertPacked(SEXP obj, void *ptr, size_t sz, swig_type_info *ty) { diff --git a/Lib/r/rstdcommon.swg b/Lib/r/rstdcommon.swg index e6c873a07..5f41fd144 100644 --- a/Lib/r/rstdcommon.swg +++ b/Lib/r/rstdcommon.swg @@ -39,7 +39,7 @@ namespace swig { template struct traits_asptr { static int asptr(SWIG_Object obj, Type **val) { - Type *p; + Type *p = 0; swig_type_info *descriptor = type_info(); int res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res)) { @@ -101,12 +101,11 @@ namespace swig { template struct traits_as { - static Type as(SWIG_Object obj, bool throw_error) { + static Type as(SWIG_Object obj) { Type v; int res = asval(obj, &v); if (!obj || !SWIG_IsOK(res)) { - if (throw_error) - throw std::invalid_argument("bad type"); + throw std::invalid_argument("bad type"); } return v; } @@ -114,7 +113,7 @@ namespace swig { template struct traits_as { - static Type as(SWIG_Object obj, bool throw_error) { + static Type as(SWIG_Object obj) { Type *v = 0; int res = (obj ? traits_asptr::asptr(obj, &v) : SWIG_ERROR); if (SWIG_IsOK(res) && v) { @@ -126,12 +125,7 @@ namespace swig { return *v; } } else { - // Uninitialized return value, no Type() constructor required. - static Type *v_def = (Type*) malloc(sizeof(Type)); - if (throw_error) throw std::invalid_argument("bad type"); - memset(v_def,0,sizeof(Type)); - return *v_def; } } }; @@ -152,8 +146,8 @@ namespace swig { }; template - inline Type as(SWIG_Object obj, bool te = false) { - return traits_as::category>::as(obj, te); + inline Type as(SWIG_Object obj) { + return traits_as::category>::as(obj); } template diff --git a/Lib/r/srun.swg b/Lib/r/srun.swg index 2045ab94e..d07218a77 100644 --- a/Lib/r/srun.swg +++ b/Lib/r/srun.swg @@ -7,7 +7,7 @@ # This could be provided as a separate run-time library but this -# approach allows the code to to be included directly into the +# approach allows the code to be included directly into the # generated bindings and so removes the need to have and install an # additional library. We may however end up with multiple copies of # this and some confusion at run-time as to which class to use. This diff --git a/Lib/ruby/boost_shared_ptr.i b/Lib/ruby/boost_shared_ptr.i index 938074d81..02e2f999f 100644 --- a/Lib/ruby/boost_shared_ptr.i +++ b/Lib/ruby/boost_shared_ptr.i @@ -62,6 +62,24 @@ %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN)); } +%typemap(directorout,noblock=1) CONST TYPE (void *argp, int res = 0) { + swig_ruby_owntype newmem = {0, 0}; + res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); + if (!SWIG_IsOK(res)) { + %dirout_fail(res, "$type"); + } + if (!argp) { + %dirout_nullref("$type"); + } else { + $result = *(%reinterpret_cast(argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *)->get()); + if (newmem.own & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *); + } +} +%typemap(directorin,noblock=1) CONST TYPE { + SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); + $input = SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags); +} + // plain pointer // Note: $disown not implemented by default as it will lead to a memory leak of the shared_ptr instance %typemap(in) CONST TYPE * (void *argp = 0, int res = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) { @@ -108,6 +126,13 @@ %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN)); } +%typemap(directorin,noblock=1) CONST TYPE * %{ +#error "directorin typemap for plain pointer not implemented" +%} +%typemap(directorout,noblock=1) CONST TYPE * %{ +#error "directorout typemap for plain pointer not implemented" +%} + // plain reference %typemap(in) CONST TYPE & (void *argp = 0, int res = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared) { swig_ruby_owntype newmem = {0, 0}; @@ -153,6 +178,13 @@ %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN)); } +%typemap(directorin,noblock=1) CONST TYPE & %{ +#error "directorin typemap for plain reference not implemented" +%} +%typemap(directorout,noblock=1) CONST TYPE & %{ +#error "directorout typemap for plain reference not implemented" +%} + // plain pointer by reference // Note: $disown not implemented by default as it will lead to a memory leak of the shared_ptr instance %typemap(in) TYPE *CONST& (void *argp = 0, int res = 0, $*1_ltype temp = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared) { @@ -182,6 +214,13 @@ #error "varout typemap not implemented" %} +%typemap(directorin,noblock=1) TYPE *CONST& %{ +#error "directorin typemap for plain pointer by reference not implemented" +%} +%typemap(directorout,noblock=1) TYPE *CONST& %{ +#error "directorout typemap for plain pointer by reference not implemented" +%} + // shared_ptr by value %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (void *argp, int res = 0) { swig_ruby_owntype newmem = {0, 0}; @@ -212,6 +251,26 @@ %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN)); } +%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > { + if ($1) { + SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >($1); + $input = SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags); + } else { + $input = Qnil; + } +} +%typemap(directorout,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (void * swig_argp, int swig_res = 0) { + if (NIL_P($input)) { + $result = $ltype(); + } else { + swig_res = SWIG_ConvertPtr($input, &swig_argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags); + if (!SWIG_IsOK(swig_res)) { + %dirout_fail(swig_res,"$type"); + } + $result = *(%reinterpret_cast(swig_argp, $<ype)); + } +} + // shared_ptr by reference %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & (void *argp, int res = 0, $*1_ltype tempshared) { swig_ruby_owntype newmem = {0, 0}; @@ -239,6 +298,14 @@ #error "varout typemap not implemented" %} +%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > & { + if ($1) { + $input = SWIG_NewPointerObj(%as_voidptr(&$1), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %newpointer_flags); + } else { + $input = Qnil; + } +} + // shared_ptr by pointer %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * (void *argp, int res = 0, $*1_ltype tempshared) { swig_ruby_owntype newmem = {0, 0}; @@ -267,6 +334,14 @@ #error "varout typemap not implemented" %} +%typemap(directorin,noblock=1) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *const& { + if ($1 && *$1) { + $input = SWIG_NewPointerObj(%as_voidptr($1), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %newpointer_flags); + } else { + $input = Qnil; + } +} + // shared_ptr by pointer reference %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *& (void *argp, int res = 0, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > tempshared, $*1_ltype temp = 0) { swig_ruby_owntype newmem = {0, 0}; diff --git a/Lib/ruby/rubycontainer.swg b/Lib/ruby/rubycontainer.swg index 4f1c6f55e..4d0163f51 100644 --- a/Lib/ruby/rubycontainer.swg +++ b/Lib/ruby/rubycontainer.swg @@ -183,8 +183,8 @@ namespace swig { VALUE item = rb_ary_entry(_seq, _index ); try { - return swig::as(item, true); - } catch (std::exception& e) { + return swig::as(item); + } catch (const std::invalid_argument& e) { char msg[1024]; sprintf(msg, "in sequence element %d ", _index); VALUE lastErr = rb_gv_get("$!"); @@ -926,7 +926,7 @@ namespace swig VALUE elem = argv[0]; int idx = 0; try { - Sequence::value_type val = swig::as( elem, true ); + Sequence::value_type val = swig::as( elem ); if ( i >= len ) { $self->resize(i-1, val); return $self; @@ -943,7 +943,7 @@ namespace swig } } - catch( std::invalid_argument ) + catch( const std::invalid_argument & ) { rb_raise( rb_eArgError, "%s", Ruby_Format_TypeError( "", @@ -967,10 +967,10 @@ namespace swig Sequence::iterator start = $self->begin(); VALUE elem = argv[idx]; try { - Sequence::value_type val = swig::as( elem, true ); + Sequence::value_type val = swig::as( elem ); $self->insert( start, val ); } - catch( std::invalid_argument ) + catch( const std::invalid_argument & ) { rb_raise( rb_eArgError, "%s", Ruby_Format_TypeError( "", diff --git a/Lib/ruby/rubyrun.swg b/Lib/ruby/rubyrun.swg index 249494ab0..1afc5c1d0 100644 --- a/Lib/ruby/rubyrun.swg +++ b/Lib/ruby/rubyrun.swg @@ -171,10 +171,11 @@ SWIG_Ruby_NewPointerObj(void *ptr, swig_type_info *type, int flags) swig_class *sklass; VALUE klass; VALUE obj; - + if (!ptr) return Qnil; - + + assert(type); if (type->clientdata) { sklass = (swig_class *) type->clientdata; @@ -182,7 +183,7 @@ SWIG_Ruby_NewPointerObj(void *ptr, swig_type_info *type, int flags) track = sklass->trackObjects; if (track) { obj = SWIG_RubyInstanceFor(ptr); - + /* Check the object's type and make sure it has the correct type. It might not in cases where methods do things like downcast methods. */ @@ -214,7 +215,7 @@ SWIG_Ruby_NewPointerObj(void *ptr, swig_type_info *type, int flags) obj = Data_Wrap_Struct(klass, 0, 0, ptr); } rb_iv_set(obj, "@__swigtype__", rb_str_new2(type->name)); - + return obj; } @@ -246,7 +247,7 @@ typedef struct { SWIGRUNTIME swig_ruby_owntype SWIG_Ruby_AcquirePtr(VALUE obj, swig_ruby_owntype own) { swig_ruby_owntype oldown = {0, 0}; - if (obj) { + if (TYPE(obj) == T_DATA) { oldown.datafree = RDATA(obj)->dfree; RDATA(obj)->dfree = own.datafree; } @@ -362,7 +363,7 @@ SWIG_Ruby_NewPackedObj(void *ptr, int sz, swig_type_info *type) { return rb_str_new2(result); } -/* Convert a packed value value */ +/* Convert a packed pointer value */ SWIGRUNTIME int SWIG_Ruby_ConvertPacked(VALUE obj, void *ptr, int sz, swig_type_info *ty) { swig_cast_info *tc; diff --git a/Lib/ruby/rubystdcommon.swg b/Lib/ruby/rubystdcommon.swg index f72745b56..99dd7f81e 100644 --- a/Lib/ruby/rubystdcommon.swg +++ b/Lib/ruby/rubystdcommon.swg @@ -3,8 +3,9 @@ * The Ruby classes, for C++ * ------------------------------------------------------------ */ %include +%include -%fragment("StdTraits","header",fragment="StdTraitsCommon") +%fragment("StdTraits","header",fragment="StdTraitsCommon",fragment="StdTraitsForwardDeclaration") { namespace swig { @@ -52,7 +53,7 @@ namespace swig { template struct traits_asptr { static int asptr(VALUE obj, Type **val) { - Type *p; + Type *p = 0; swig_type_info *descriptor = type_info(); int res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res)) { @@ -114,15 +115,15 @@ namespace swig { template struct traits_as { - static Type as(VALUE obj, bool throw_error) { + static Type as(VALUE obj) { Type v; int res = asval(obj, &v); - if (!obj || !SWIG_IsOK(res)) { - if (throw_error) throw std::invalid_argument("bad type"); + if (!SWIG_IsOK(res)) { VALUE lastErr = rb_gv_get("$!"); if (lastErr == Qnil) { %type_error(swig::type_name()); } + throw std::invalid_argument("bad type"); } return v; } @@ -130,9 +131,9 @@ namespace swig { template struct traits_as { - static Type as(VALUE obj, bool throw_error) { + static Type as(VALUE obj) { Type *v = 0; - int res = (obj ? traits_asptr::asptr(obj, &v) : SWIG_ERROR); + int res = traits_asptr::asptr(obj, &v); if (SWIG_IsOK(res) && v) { if (SWIG_IsNewObj(res)) { Type r(*v); @@ -142,46 +143,41 @@ namespace swig { return *v; } } else { - // Uninitialized return value, no Type() constructor required. - if (throw_error) throw std::invalid_argument("bad type"); VALUE lastErr = rb_gv_get("$!"); if (lastErr == Qnil) { %type_error(swig::type_name()); } - static Type *v_def = (Type*) malloc(sizeof(Type)); - memset(v_def,0,sizeof(Type)); - return *v_def; + throw std::invalid_argument("bad type"); } } }; template struct traits_as { - static Type* as(VALUE obj, bool throw_error) { + static Type* as(VALUE obj) { Type *v = 0; - int res = (obj ? traits_asptr::asptr(obj, &v) : SWIG_ERROR); + int res = traits_asptr::asptr(obj, &v); if (SWIG_IsOK(res)) { return v; } else { - if (throw_error) throw std::invalid_argument("bad type"); VALUE lastErr = rb_gv_get("$!"); if (lastErr == Qnil) { %type_error(swig::type_name()); } - return 0; + throw std::invalid_argument("bad type"); } } }; template - inline Type as(VALUE obj, bool te = false) { - return traits_as< Type, typename traits< Type >::category >::as(obj, te); + inline Type as(VALUE obj) { + return traits_as< Type, typename traits< Type >::category >::as(obj); } template struct traits_check { static bool check(VALUE obj) { - int res = obj ? asval(obj, (Type *)(0)) : SWIG_ERROR; + int res = asval(obj, (Type *)(0)); return SWIG_IsOK(res) ? true : false; } }; @@ -189,7 +185,7 @@ namespace swig { template struct traits_check { static bool check(VALUE obj) { - int res = obj ? asptr(obj, (Type **)(0)) : SWIG_ERROR; + int res = asptr(obj, (Type **)(0)); return SWIG_IsOK(res) ? true : false; } }; diff --git a/Lib/ruby/rubystdcommon_forward.swg b/Lib/ruby/rubystdcommon_forward.swg new file mode 100644 index 000000000..4120b38e4 --- /dev/null +++ b/Lib/ruby/rubystdcommon_forward.swg @@ -0,0 +1,15 @@ +%fragment("StdTraitsForwardDeclaration","header") +{ +namespace swig { + template struct traits_asptr; + template struct traits_asval; + struct pointer_category; + template struct traits_as; + template struct traits_from; + template struct traits_from_ptr; + template struct noconst_traits; + template swig_type_info* type_info(); + template const char* type_name(); + template VALUE from(const Type& val); +} +} diff --git a/Lib/ruby/rubywstrings.swg b/Lib/ruby/rubywstrings.swg index b6dd937a5..7da6f4bf2 100644 --- a/Lib/ruby/rubywstrings.swg +++ b/Lib/ruby/rubywstrings.swg @@ -1,71 +1,57 @@ /* ----------------------------------------------------------------------------- * rubywstrings.swg * - * Currently, Ruby does not support Unicode or WChar properly, so these - * are still treated as char arrays for now. - * There are other libraries available that add support to this in - * ruby including WString, FXString, etc. - * ----------------------------------------------------------------------------- */ - -/* ------------------------------------------------------------ * utility methods for wchar_t strings * ------------------------------------------------------------ */ -%fragment("SWIG_AsWCharPtrAndSize","header",fragment="",fragment="SWIG_pwchar_descriptor",fragment="SWIG_AsCharPtrAndSize") { +%fragment("SWIG_AsWCharPtrAndSize","header",fragment="",fragment="SWIG_pwchar_descriptor",fragment="SWIG_AsCharPtrAndSize",fragment="SWIG_ruby_wstring_encoding_init") { SWIGINTERN int SWIG_AsWCharPtrAndSize(VALUE obj, wchar_t **cptr, size_t *psize, int *alloc) { - return SWIG_AsCharPtrAndSize( obj, (char**)cptr, psize, alloc); -// VALUE tmp = 0; -// bool ok = false; -// if ( TYPE(obj) == T_STRING ) { -// if (cptr) { -// obj = tmp = SWIG_Unicode_FromObject(obj); -// ok = true; -// } -// } -// if (ok) { -// Py_ssize_t len = PyUnicode_GetSize(obj); -// rb_notimplement(); -// if (cptr) { -// *cptr = %new_array(len + 1, wchar_t); -// SWIG_Unicode_AsWideChar((PyUnicodeObject *)obj, *cptr, len); -// (*cptr)[len] = 0; -// } -// if (psize) *psize = (size_t) len + 1; -// if (alloc) *alloc = cptr ? SWIG_NEWOBJ : 0; -// return SWIG_OK; -// } else { -// swig_type_info* pwchar_descriptor = SWIG_pwchar_descriptor(); -// if (pwchar_descriptor) { -// void * vptr = 0; -// if (SWIG_ConvertPtr(obj, &vptr, pwchar_descriptor, 0) == SWIG_OK) { -// if (cptr) *cptr = (wchar_t *)vptr; -// if (psize) *psize = vptr ? (wcslen((wchar_t *)vptr) + 1) : 0; -// return SWIG_OK; -// } -// } -// } -// return SWIG_TypeError; + rb_encoding* wstr_enc = swig_ruby_wstring_encoding; + + if (TYPE(obj) == T_STRING) { + VALUE rstr = rb_str_conv_enc(obj, rb_enc_get(obj), wstr_enc); + wchar_t* cstr = (wchar_t*) StringValuePtr(rstr); + size_t size = RSTRING_LEN(rstr) / sizeof(wchar_t) + 1; + + if ( RSTRING_LEN(rstr) % sizeof(wchar_t) != 0 ) { + rb_raise(rb_eRuntimeError, + "The length of the byte sequence of converted string is not a multiplier of sizeof(wchar_t). Invalid byte sequence is given. Or invalid SWIG_RUBY_WSTRING_ENCODING is given when compiling this binding."); + } + if (cptr && alloc) { + *alloc = SWIG_NEWOBJ; + *cptr = %new_array(size, wchar_t); + memmove(*cptr, cstr, RSTRING_LEN(rstr)); + } + if (psize) *psize = size; + + return SWIG_OK; + } else { + return SWIG_TypeError; + } } } -%fragment("SWIG_FromWCharPtrAndSize","header",fragment="",fragment="SWIG_pwchar_descriptor",fragment="SWIG_FromCharPtrAndSize") { +%fragment("SWIG_FromWCharPtrAndSize","header",fragment="",fragment="SWIG_pwchar_descriptor",fragment="SWIG_FromCharPtrAndSize",fragment="SWIG_ruby_wstring_encoding_init") { SWIGINTERNINLINE VALUE SWIG_FromWCharPtrAndSize(const wchar_t * carray, size_t size) { - return SWIG_FromCharPtrAndSize( (const char*)carray, size); -// if (carray) { -// if (size > INT_MAX) { -// swig_type_info* pwchar_descriptor = SWIG_pwchar_descriptor(); -// return pwchar_descriptor ? -// SWIG_NewPointerObj(%const_cast(carray,wchar_t *), pwchar_descriptor, 0) : Qnil; -// } else { -// return SWIG_Unicode_FromWideChar(carray, %numeric_cast(size,int)); -// } -// } else { -// return Qnil; -// } + rb_encoding* wstr_enc = swig_ruby_wstring_encoding; + rb_encoding* rb_enc = swig_ruby_internal_encoding; + + if (carray && size <= LONG_MAX/sizeof(wchar_t)) { + VALUE rstr = rb_str_new( (const char*)carray, %numeric_cast(size*sizeof(wchar_t),long) ); + rb_encoding* new_enc = rb_default_internal_encoding(); + + rb_enc_associate(rstr, wstr_enc); + if ( !new_enc ) { + new_enc = rb_enc; + } + return rb_str_conv_enc(rstr, wstr_enc, new_enc); + } else { + return Qnil; + } } } diff --git a/Lib/ruby/std_basic_string.i b/Lib/ruby/std_basic_string.i index 1351177fc..a51333793 100644 --- a/Lib/ruby/std_basic_string.i +++ b/Lib/ruby/std_basic_string.i @@ -55,6 +55,10 @@ SWIGINTERNINLINE VALUE #if !defined(SWIG_STD_WSTRING) +%traits_swigtype(std::basic_string); +%fragment(SWIG_Traits_frag(std::basic_string)); + + %fragment(SWIG_AsPtr_frag(std::basic_string),"header", fragment="SWIG_AsWCharPtrAndSize") { SWIGINTERN int diff --git a/Lib/ruby/std_list.i b/Lib/ruby/std_list.i index 8d4284bbc..5f179cc69 100644 --- a/Lib/ruby/std_list.i +++ b/Lib/ruby/std_list.i @@ -27,6 +27,7 @@ #define %swig_list_methods(Type...) %swig_sequence_methods(Type) #define %swig_list_methods_val(Type...) %swig_sequence_methods_val(Type); +%mixin std::list "Enumerable"; %rename("delete") std::list::__delete__; %rename("reject!") std::list::reject_bang; diff --git a/Lib/ruby/std_multimap.i b/Lib/ruby/std_multimap.i index 3e06ee12c..762a87653 100644 --- a/Lib/ruby/std_multimap.i +++ b/Lib/ruby/std_multimap.i @@ -90,12 +90,11 @@ %extend { VALUE __getitem__(const key_type& key) const { - MultiMap::const_iterator i = self->find(key); - if ( i != self->end() ) + std::pair r = $self->equal_range(key); + if ( r.first != r.second ) { - MultiMap::const_iterator e = $self->upper_bound(key); VALUE ary = rb_ary_new(); - for ( ; i != e; ++i ) + for (MultiMap::const_iterator i = r.first ; i != r.second; ++i ) { rb_ary_push( ary, swig::from( i->second ) ); } diff --git a/Lib/ruby/std_multiset.i b/Lib/ruby/std_multiset.i index 87a7b292a..252ae10d2 100644 --- a/Lib/ruby/std_multiset.i +++ b/Lib/ruby/std_multiset.i @@ -36,7 +36,7 @@ #define %swig_multiset_methods(Set...) %swig_set_methods(Set) - +%mixin std::multiset "Enumerable"; %rename("delete") std::multiset::__delete__; %rename("reject!") std::multiset::reject_bang; diff --git a/Lib/ruby/std_shared_ptr.i b/Lib/ruby/std_shared_ptr.i index df873679c..9742230cc 100644 --- a/Lib/ruby/std_shared_ptr.i +++ b/Lib/ruby/std_shared_ptr.i @@ -1,2 +1,141 @@ #define SWIG_SHARED_PTR_NAMESPACE std %include +%include + + +%fragment("StdSharedPtrTraits","header",fragment="StdTraitsForwardDeclaration") +{ +namespace swig { + /* + Template specialization for functions defined in rubystdcommon.swg. Special handling for shared_ptr + is required as, shared_ptr * is used rather than the usual T *, see shared_ptr.i. + */ + template + struct traits_asptr > { + static int asptr(VALUE obj, std::shared_ptr **val) { + std::shared_ptr *p = 0; + swig_type_info *descriptor = type_info >(); + 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(); + } 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; + } + return res; + } + }; + + template + struct traits_asval > { + static int asval(VALUE obj, std::shared_ptr *val) { + if (val) { + std::shared_ptr ret; + std::shared_ptr *p = &ret; + int res = traits_asptr >::asptr(obj, &p); + if (!SWIG_IsOK(res)) + return res; + *val = ret; + return SWIG_OK; + } else { + return traits_asptr >::asptr(obj, (std::shared_ptr **)(0)); + } + } + }; + + template + struct traits_asval *> { + static int asval(VALUE obj, std::shared_ptr **val) { + if (val) { + typedef typename noconst_traits >::noconst_type noconst_type; + if (*val) { + noconst_type ret; + noconst_type *p = &ret; + int res = traits_asptr::asptr(obj, &p); + if (SWIG_IsOK(res)) + **(const_cast(val)) = ret; + return res; + } else { + noconst_type *p = 0; + int res = traits_asptr::asptr(obj, &p); + if (SWIG_IsOK(res)) + *val = p; + return res; + } + } else { + return traits_asptr >::asptr(obj, (std::shared_ptr **)(0)); + } + } + }; + + template + struct traits_as, pointer_category> { + static std::shared_ptr as(VALUE obj) { + std::shared_ptr ret; + std::shared_ptr *v = &ret; + int res = traits_asptr >::asptr(obj, &v); + if (SWIG_IsOK(res)) { + return ret; + } else { + + VALUE lastErr = rb_gv_get("$!"); + if (lastErr == Qnil) + SWIG_Error(SWIG_TypeError, swig::type_name >()); + throw std::invalid_argument("bad type"); + } + } + }; + + template + struct traits_as *, pointer_category> { + static std::shared_ptr * as(VALUE obj) { + std::shared_ptr *p = 0; + int res = traits_asptr >::asptr(obj, &p); + if (SWIG_IsOK(res)) { + return p; + } else { + + VALUE lastErr = rb_gv_get("$!"); + if (lastErr == Qnil) + SWIG_Error(SWIG_TypeError, swig::type_name *>()); + throw std::invalid_argument("bad type"); + } + } + }; + + template + struct traits_from_ptr > { + static VALUE from(std::shared_ptr *val, int owner = 0) { + if (val && *val) { + return SWIG_NewPointerObj(val, type_info >(), owner); + } else { + return Qnil; + } + } + }; + + /* + The descriptors in the shared_ptr typemaps remove the const qualifier for the SWIG type system. + Remove const likewise here, otherwise SWIG_TypeQuery("std::shared_ptr") will return NULL. + */ + template + struct traits_from > { + static VALUE from(const std::shared_ptr& val) { + std::shared_ptr p = std::const_pointer_cast(val); + return swig::from(p); + } + }; +} +} + +%fragment("StdSharedPtrTraits"); diff --git a/Lib/ruby/std_unordered_map.i b/Lib/ruby/std_unordered_map.i new file mode 100644 index 000000000..c3f60bbba --- /dev/null +++ b/Lib/ruby/std_unordered_map.i @@ -0,0 +1,83 @@ +// +// Maps +// +%include + +%fragment("StdUnorderedMapTraits","header",fragment="StdMapCommonTraits") +{ + namespace swig { + template + inline void + assign(const RubySeq& rubyseq, std::unordered_map *map) { + typedef typename std::unordered_map::value_type value_type; + typename RubySeq::const_iterator it = rubyseq.begin(); + for (;it != rubyseq.end(); ++it) { + map->insert(value_type(it->first, it->second)); + } + } + + template + struct traits_asptr > { + typedef std::unordered_map map_type; + static int asptr(VALUE obj, map_type **val) { + int res = SWIG_ERROR; + if (TYPE(obj) == T_HASH) { + static ID id_to_a = rb_intern("to_a"); + VALUE items = rb_funcall(obj, id_to_a, 0); + res = traits_asptr_stdseq, std::pair >::asptr(items, val); + } else { + map_type *p; + swig_type_info *descriptor = swig::type_info(); + res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; + if (SWIG_IsOK(res) && val) *val = p; + } + return res; + } + }; + + template + struct traits_from > { + typedef std::unordered_map map_type; + typedef typename map_type::const_iterator const_iterator; + typedef typename map_type::size_type size_type; + + static VALUE from(const map_type& map) { + swig_type_info *desc = swig::type_info(); + if (desc && desc->clientdata) { + return SWIG_NewPointerObj(new map_type(map), desc, SWIG_POINTER_OWN); + } else { + size_type size = map.size(); + int rubysize = (size <= (size_type) INT_MAX) ? (int) size : -1; + if (rubysize < 0) { + SWIG_RUBY_THREAD_BEGIN_BLOCK; + rb_raise(rb_eRuntimeError, "map size not valid in Ruby"); + SWIG_RUBY_THREAD_END_BLOCK; + return Qnil; + } + VALUE obj = rb_hash_new(); + for (const_iterator i= map.begin(); i!= map.end(); ++i) { + VALUE key = swig::from(i->first); + VALUE val = swig::from(i->second); + rb_hash_aset(obj, key, val); + } + return obj; + } + } + }; + } +} + +#define %swig_unordered_map_common(Map...) %swig_map_common(Map) +#define %swig_unordered_map_methods(Map...) %swig_map_methods(Map) + +%rename("delete") std::unordered_map::__delete__; +%rename("reject!") std::unordered_map::reject_bang; +%rename("map!") std::unordered_map::map_bang; +%rename("empty?") std::unordered_map::empty; +%rename("include?") std::unordered_map::__contains__ const; +%rename("has_key?") std::unordered_map::has_key const; + +%mixin std::unordered_map "Enumerable"; +%alias std::unordered_map::push "<<"; + +%include diff --git a/Lib/ruby/std_unordered_multimap.i b/Lib/ruby/std_unordered_multimap.i new file mode 100644 index 000000000..b663c1298 --- /dev/null +++ b/Lib/ruby/std_unordered_multimap.i @@ -0,0 +1,100 @@ +/* + Multimaps +*/ +%include + +%fragment("StdUnorderedMultimapTraits","header",fragment="StdMapCommonTraits") +{ + namespace swig { + template + inline void + assign(const RubySeq& rubyseq, std::unordered_multimap *multimap) { + typedef typename std::unordered_multimap::value_type value_type; + typename RubySeq::const_iterator it = rubyseq.begin(); + for (;it != rubyseq.end(); ++it) { + multimap->insert(value_type(it->first, it->second)); + } + } + + template + struct traits_asptr > { + typedef std::unordered_multimap multimap_type; + static int asptr(VALUE obj, std::unordered_multimap **val) { + int res = SWIG_ERROR; + if ( TYPE(obj) == T_HASH ) { + static ID id_to_a = rb_intern("to_a"); + VALUE items = rb_funcall(obj, id_to_a, 0); + return traits_asptr_stdseq, std::pair >::asptr(items, val); + } else { + multimap_type *p; + res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info(),0); + if (SWIG_IsOK(res) && val) *val = p; + } + return res; + } + }; + + template + struct traits_from > { + typedef std::unordered_multimap multimap_type; + typedef typename multimap_type::const_iterator const_iterator; + typedef typename multimap_type::size_type size_type; + + static VALUE from(const multimap_type& multimap) { + swig_type_info *desc = swig::type_info(); + if (desc && desc->clientdata) { + return SWIG_NewPointerObj(new multimap_type(multimap), desc, SWIG_POINTER_OWN); + } else { + size_type size = multimap.size(); + int rubysize = (size <= (size_type) INT_MAX) ? (int) size : -1; + if (rubysize < 0) { + SWIG_RUBY_THREAD_BEGIN_BLOCK; + rb_raise(rb_eRuntimeError, + "multimap_ size not valid in Ruby"); + SWIG_RUBY_THREAD_END_BLOCK; + return Qnil; + } + VALUE obj = rb_hash_new(); + for (const_iterator i= multimap.begin(); i!= multimap.end(); ++i) { + VALUE key = swig::from(i->first); + VALUE val = swig::from(i->second); + + VALUE oldval = rb_hash_aref(obj, key); + if (oldval == Qnil) { + rb_hash_aset(obj, key, val); + } else { + // Multiple values for this key, create array if needed + // and add a new element to it. + VALUE ary; + if (TYPE(oldval) == T_ARRAY) { + ary = oldval; + } else { + ary = rb_ary_new2(2); + rb_ary_push(ary, oldval); + rb_hash_aset(obj, key, ary); + } + rb_ary_push(ary, val); + } + } + return obj; + } + } + }; + } +} + +#define %swig_unordered_multimap_methods(MultiMap...) %swig_multimap_methods(MultiMap) + +%mixin std::unordered_multimap "Enumerable"; + +%rename("delete") std::unordered_multimap::__delete__; +%rename("reject!") std::unordered_multimap::reject_bang; +%rename("map!") std::unordered_multimap::map_bang; +%rename("empty?") std::unordered_multimap::empty; +%rename("include?" ) std::unordered_multimap::__contains__ const; +%rename("has_key?" ) std::unordered_multimap::has_key const; + +%alias std::unordered_multimap::push "<<"; + +%include + diff --git a/Lib/ruby/std_unordered_multiset.i b/Lib/ruby/std_unordered_multiset.i new file mode 100644 index 000000000..181aa212d --- /dev/null +++ b/Lib/ruby/std_unordered_multiset.i @@ -0,0 +1,50 @@ +/* + Multisets +*/ + +%include + +%fragment("StdUnorderedMultisetTraits","header",fragment="StdUnorderedSetTraits") +%{ + namespace swig { + template + inline void + assign(const RubySeq& rubyseq, std::unordered_multiset* seq) { + // seq->insert(rubyseq.begin(), rubyseq.end()); // not used as not always implemented + typedef typename RubySeq::value_type value_type; + typename RubySeq::const_iterator it = rubyseq.begin(); + for (;it != rubyseq.end(); ++it) { + seq->insert(seq->end(),(value_type)(*it)); + } + } + + template + struct traits_asptr > { + static int asptr(VALUE obj, std::unordered_multiset **m) { + return traits_asptr_stdseq >::asptr(obj, m); + } + }; + + template + struct traits_from > { + static VALUE from(const std::unordered_multiset& vec) { + return traits_from_stdseq >::from(vec); + } + }; + } +%} + +#define %swig_unordered_multiset_methods(Set...) %swig_unordered_set_methods(Set) + +%mixin std::unordered_multiset "Enumerable"; + +%rename("delete") std::unordered_multiset::__delete__; +%rename("reject!") std::unordered_multiset::reject_bang; +%rename("map!") std::unordered_multiset::map_bang; +%rename("empty?") std::unordered_multiset::empty; +%rename("include?") std::unordered_multiset::__contains__ const; +%rename("has_key?") std::unordered_multiset::has_key const; + +%alias std::unordered_multiset::push "<<"; + +%include diff --git a/Lib/ruby/std_unordered_set.i b/Lib/ruby/std_unordered_set.i new file mode 100644 index 000000000..3d4494351 --- /dev/null +++ b/Lib/ruby/std_unordered_set.i @@ -0,0 +1,50 @@ +/* + Sets +*/ + +%include + +%fragment("StdUnorderedSetTraits","header",fragment="",fragment="StdSetTraits") +%{ + namespace swig { + template + inline void + assign(const RubySeq& rubyseq, std::unordered_set* seq) { + // seq->insert(rubyseq.begin(), rubyseq.end()); // not used as not always implemented + typedef typename RubySeq::value_type value_type; + typename RubySeq::const_iterator it = rubyseq.begin(); + for (;it != rubyseq.end(); ++it) { + seq->insert(seq->end(),(value_type)(*it)); + } + } + + template + struct traits_asptr > { + static int asptr(VALUE obj, std::unordered_set **s) { + return traits_asptr_stdseq >::asptr(obj, s); + } + }; + + template + struct traits_from > { + static VALUE from(const std::unordered_set& vec) { + return traits_from_stdseq >::from(vec); + } + }; + } +%} + +#define %swig_unordered_set_methods(set...) %swig_set_methods(set) + +%mixin std::unordered_set "Enumerable"; + +%rename("delete") std::unordered_set::__delete__; +%rename("reject!") std::unordered_set::reject_bang; +%rename("map!") std::unordered_set::map_bang; +%rename("empty?") std::unordered_set::empty; +%rename("include?" ) std::unordered_set::__contains__ const; +%rename("has_key?" ) std::unordered_set::has_key const; + +%alias std::unordered_set::push "<<"; + +%include diff --git a/Lib/ruby/std_wstring.i b/Lib/ruby/std_wstring.i index 5ca77c0c8..f2487077b 100644 --- a/Lib/ruby/std_wstring.i +++ b/Lib/ruby/std_wstring.i @@ -1,3 +1,50 @@ +%{ +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAVE_RUBY_ENCODING_H +#include "ruby/encoding.h" +#endif + +/** + * The internal encoding of std::wstring is defined based on + * the size of wchar_t. If it is not appropriate for your library, + * SWIG_RUBY_WSTRING_ENCODING must be given when compiling. + */ +#ifndef SWIG_RUBY_WSTRING_ENCODING + +#if WCHAR_MAX == 0x7fff || WCHAR_MAX == 0xffff +#define SWIG_RUBY_WSTRING_ENCODING "UTF-16LE" +#elif WCHAR_MAX == 0x7fffffff || WCHAR_MAX == 0xffffffff +#define SWIG_RUBY_WSTRING_ENCODING "UTF-32LE" +#else +#error unsupported wchar_t size. SWIG_RUBY_WSTRING_ENCODING must be given. +#endif + +#endif + +/** + * If Encoding.default_internal is nil, this encoding will be used + * when converting from std::wstring to String object in Ruby. + */ +#ifndef SWIG_RUBY_INTERNAL_ENCODING +#define SWIG_RUBY_INTERNAL_ENCODING "UTF-8" +#endif + +static rb_encoding *swig_ruby_wstring_encoding; +static rb_encoding *swig_ruby_internal_encoding; + +#ifdef __cplusplus +} +#endif +%} + +%fragment("SWIG_ruby_wstring_encoding_init", "init") { + swig_ruby_wstring_encoding = rb_enc_find( SWIG_RUBY_WSTRING_ENCODING ); + swig_ruby_internal_encoding = rb_enc_find( SWIG_RUBY_INTERNAL_ENCODING ); +} + %include %include diff --git a/Lib/scilab/boost_shared_ptr.i b/Lib/scilab/boost_shared_ptr.i index b90422a66..d595b4861 100644 --- a/Lib/scilab/boost_shared_ptr.i +++ b/Lib/scilab/boost_shared_ptr.i @@ -14,7 +14,7 @@ %naturalvar SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >; // destructor wrapper customisation -%feature("unref") TYPE +%feature("unref") TYPE //"if (debug_shared) { cout << \"deleting use_count: \" << (*smartarg1).use_count() << \" [\" << (boost::get_deleter(*smartarg1) ? std::string(\"CANNOT BE DETERMINED SAFELY\") : ( (*smartarg1).get() ? (*smartarg1)->getValue() : std::string(\"NULL PTR\") )) << \"]\" << endl << flush; }\n" "(void)arg1; delete smartarg1;" @@ -25,7 +25,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (!argp) { %argument_nullref("$type", $symname, $argnum); @@ -64,7 +64,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SHARED_PTR_DISOWN | %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { tempshared = *%reinterpret_cast(argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *); @@ -109,7 +109,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (!argp) { %argument_nullref("$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { @@ -155,7 +155,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SHARED_PTR_DISOWN | %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { tempshared = *%reinterpret_cast(argp, SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *); @@ -183,7 +183,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (argp) $1 = *(%reinterpret_cast(argp, $<ype)); if (newmem & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(argp, $<ype); @@ -213,7 +213,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { if (argp) tempshared = *%reinterpret_cast(argp, $ltype); @@ -240,7 +240,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (newmem & SWIG_CAST_NEW_MEMORY) { if (argp) tempshared = *%reinterpret_cast(argp, $ltype); @@ -268,7 +268,7 @@ int newmem = 0; res = SWIG_ConvertPtrAndOwn($input, &argp, $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), %convertptr_flags, &newmem); if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); + %argument_fail(res, "$type", $symname, $argnum); } if (argp) tempshared = *%reinterpret_cast(argp, $*ltype); if (newmem & SWIG_CAST_NEW_MEMORY) delete %reinterpret_cast(argp, $*ltype); @@ -288,9 +288,9 @@ %} // Typecheck typemaps -// Note: SWIG_ConvertPtr with void ** parameter set to 0 instead of using SWIG_ConvertPtrAndOwn, so that the casting +// Note: SWIG_ConvertPtr with void ** parameter set to 0 instead of using SWIG_ConvertPtrAndOwn, so that the casting // function is not called thereby avoiding a possible smart pointer copy constructor call when casting up the inheritance chain. -%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) +%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) TYPE CONST, TYPE CONST &, TYPE CONST *, diff --git a/Lib/scilab/scicontainer.swg b/Lib/scilab/scicontainer.swg index 2cc44b8e5..f6078690b 100644 --- a/Lib/scilab/scicontainer.swg +++ b/Lib/scilab/scicontainer.swg @@ -42,7 +42,9 @@ %fragment("SciSequence_Cont", "header", fragment="StdTraits", - fragment="SwigSciIterator_T") + fragment="SwigSciIterator_T", + fragment=SWIG_Traits_Sequence_frag(ptr), + fragment=SWIG_Traits_SequenceItem_frag(ptr)) { namespace swig { @@ -334,8 +336,7 @@ namespace swig %fragment("StdSequenceTraits","header", fragment="StdTraits", - fragment="SciSequence_Cont", - fragment=SWIG_Traits_SequenceItem_frag(ptr)) + fragment="SciSequence_Cont") { namespace swig { template diff --git a/Lib/scilab/scistdcommon.swg b/Lib/scilab/scistdcommon.swg index 63f3ca164..b08fc0307 100644 --- a/Lib/scilab/scistdcommon.swg +++ b/Lib/scilab/scistdcommon.swg @@ -41,7 +41,7 @@ namespace swig { template struct traits_asptr { static int asptr(const SwigSciObject& obj, Type **val) { - Type *p; + Type *p = 0; swig_type_info *descriptor = type_info(); int res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR; if (SWIG_IsOK(res)) { @@ -104,23 +104,21 @@ namespace swig { template struct traits_as { - static Type as(const SwigSciObject& obj, bool throw_error) { + static Type as(const SwigSciObject& obj) { Type v; int res = asval(obj, &v); if (SWIG_IsOK(res)) { return v; } else { - %type_error(swig::type_name()); - if (throw_error) - throw std::invalid_argument("bad type"); - return res; + %type_error(swig::type_name()); + throw std::invalid_argument("bad type"); } } }; template struct traits_as { - static Type as(const SwigSciObject& obj, bool throw_error) { + static Type as(const SwigSciObject& obj) { Type *v = 0; int res = traits_asptr::asptr(obj, &v); if (SWIG_IsOK(res) && v) { @@ -132,36 +130,29 @@ namespace swig { return *v; } } else { - // Uninitialized return value, no Type() constructor required. - static Type *v_def = (Type*) malloc(sizeof(Type)); - %type_error(swig::type_name()); - if (throw_error) - throw std::invalid_argument("bad type"); - memset(v_def,0,sizeof(Type)); - return *v_def; + %type_error(swig::type_name()); + throw std::invalid_argument("bad type"); } } }; template struct traits_as { - static Type* as(const SwigSciObject& obj, bool throw_error) { + static Type* as(const SwigSciObject& obj) { Type *v = 0; int res = traits_asptr::asptr(obj, &v); if (SWIG_IsOK(res)) { return v; } else { - %type_error(swig::type_name()); - if (throw_error) - throw std::invalid_argument("bad type"); - return SWIG_OK; + %type_error(swig::type_name()); + throw std::invalid_argument("bad type"); } } }; template - inline Type as(const SwigSciObject& obj, bool te = false) { - return traits_as::category>::as(obj, te); + inline Type as(const SwigSciObject& obj) { + return traits_as::category>::as(obj); } template diff --git a/Lib/scilab/scitypemaps.swg b/Lib/scilab/scitypemaps.swg index 4cf0da3f1..682d18c44 100644 --- a/Lib/scilab/scitypemaps.swg +++ b/Lib/scilab/scitypemaps.swg @@ -7,7 +7,7 @@ #define SWIG_Object int #define %append_output(obj) if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, obj))) return SWIG_ERROR -#define %set_constant(name, obj) if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, obj))) return SWIG_ERROR // Name is managed by the the function name +#define %set_constant(name, obj) if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, obj))) return SWIG_ERROR // Name is managed by the function name #define %raise(obj, type, desc) SWIG_Scilab_Raise(obj, type, desc) #define %set_output(obj) if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, obj))) return SWIG_ERROR #define %set_varoutput(obj) if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, obj))) return SWIG_ERROR diff --git a/Lib/std/std_unordered_map.i b/Lib/std/std_unordered_map.i index 1cb714821..0d6986497 100644 --- a/Lib/std/std_unordered_map.i +++ b/Lib/std/std_unordered_map.i @@ -1,15 +1,11 @@ // // std::unordered_map -// Work in progress - the code is not compilable yet: -// operator--() and constructor(compare function) not available for unordered_ -// types // - %include %include %define %std_unordered_map_methods_common(unordered_map...) - %std_container_methods(unordered_map); + %std_container_methods_without_reverse_iterators(unordered_map); size_type erase(const key_type& x); size_type count(const key_type& x) const; @@ -22,8 +18,6 @@ } iterator find(const key_type& x); - iterator lower_bound(const key_type& x); - iterator upper_bound(const key_type& x); #endif %enddef @@ -68,7 +62,7 @@ namespace std { - template, + template, class _Pred = std::equal_to< _Key >, class _Alloc = allocator > > class unordered_map { public: @@ -101,26 +95,24 @@ namespace std { } } - %fragment(SWIG_Traits_frag(std::unordered_map< _Key, _Tp, _Compare, _Alloc >), "header", + %fragment(SWIG_Traits_frag(std::unordered_map< _Key, _Tp, _Hash, _Pred, _Alloc >), "header", fragment=SWIG_Traits_frag(std::pair< _Key, _Tp >), - fragment="StdMapTraits") { + fragment="StdUnorderedMapTraits") { namespace swig { - template <> struct traits > { + template <> struct traits > { typedef pointer_category category; static const char* type_name() { - return "std::unordered_map<" #_Key "," #_Tp "," #_Compare "," #_Alloc " >"; + return "std::unordered_map<" #_Key "," #_Tp "," #_Hash "," #_Pred "," #_Alloc " >"; } }; } } - %typemap_traits_ptr(SWIG_TYPECHECK_MAP, std::unordered_map< _Key, _Tp, _Compare, _Alloc >); - - unordered_map( const _Compare& ); + %typemap_traits_ptr(SWIG_TYPECHECK_MAP, std::unordered_map< _Key, _Tp, _Hash, _Pred, _Alloc >); #ifdef %swig_unordered_map_methods // Add swig/language extra methods - %swig_unordered_map_methods(std::unordered_map< _Key, _Tp, _Compare, _Alloc >); + %swig_unordered_map_methods(std::unordered_map< _Key, _Tp, _Hash, _Pred, _Alloc >); #endif %std_unordered_map_methods(unordered_map); diff --git a/Lib/std/std_unordered_multimap.i b/Lib/std/std_unordered_multimap.i index 46b56d88a..6f1be9cfa 100644 --- a/Lib/std/std_unordered_multimap.i +++ b/Lib/std/std_unordered_multimap.i @@ -1,15 +1,11 @@ // // std::unordered_multimap -// Work in progress - the code is not compilable yet: -// operator--() and constructor(compare function) not available for unordered_ -// types // %include - %define %std_unordered_multimap_methods(mmap...) - %std_map_methods_common(mmap); + %std_unordered_map_methods_common(mmap); #ifdef SWIG_EXPORT_ITERATOR_METHODS std::pair equal_range(const key_type& x); @@ -44,7 +40,7 @@ namespace std { - template, + template, class _Pred = std::equal_to< _Key >, class _Alloc = allocator > > class unordered_multimap { public: @@ -63,26 +59,24 @@ namespace std { %traits_swigtype(_Key); %traits_swigtype(_Tp); - %fragment(SWIG_Traits_frag(std::unordered_multimap< _Key, _Tp, _Compare, _Alloc >), "header", + %fragment(SWIG_Traits_frag(std::unordered_multimap< _Key, _Tp, _Hash, _Pred, _Alloc >), "header", fragment=SWIG_Traits_frag(std::pair< _Key, _Tp >), - fragment="StdMultimapTraits") { + fragment="StdUnorderedMultimapTraits") { namespace swig { - template <> struct traits > { + template <> struct traits > { typedef pointer_category category; static const char* type_name() { - return "std::unordered_multimap<" #_Key "," #_Tp "," #_Compare "," #_Alloc " >"; + return "std::unordered_multimap<" #_Key "," #_Tp "," #_Hash "," #_Pred "," #_Alloc " >"; } }; } } - %typemap_traits_ptr(SWIG_TYPECHECK_MULTIMAP, std::unordered_multimap< _Key, _Tp, _Compare, _Alloc >); + %typemap_traits_ptr(SWIG_TYPECHECK_MULTIMAP, std::unordered_multimap< _Key, _Tp, _Hash, _Pred, _Alloc >); - unordered_multimap( const _Compare& ); - #ifdef %swig_unordered_multimap_methods // Add swig/language extra methods - %swig_unordered_multimap_methods(std::unordered_multimap< _Key, _Tp, _Compare, _Alloc >); + %swig_unordered_multimap_methods(std::unordered_multimap< _Key, _Tp, _Hash, _Pred, _Alloc >); #endif %std_unordered_multimap_methods(unordered_multimap); diff --git a/Lib/std/std_unordered_multiset.i b/Lib/std/std_unordered_multiset.i index 725ca2fe7..1817fc24a 100644 --- a/Lib/std/std_unordered_multiset.i +++ b/Lib/std/std_unordered_multiset.i @@ -1,8 +1,5 @@ // // std::unordered_multiset -// Work in progress - the code is not compilable yet: -// operator--() and constructor(compare function) not available for unordered_ -// types // %include @@ -43,7 +40,8 @@ namespace std { //unordered_multiset - template , + template , + class _Compare = std::equal_to< _Key >, class _Alloc = allocator< _Key > > class unordered_multiset { public: @@ -59,26 +57,24 @@ namespace std { %traits_swigtype(_Key); - %fragment(SWIG_Traits_frag(std::unordered_multiset< _Key, _Compare, _Alloc >), "header", + %fragment(SWIG_Traits_frag(std::unordered_multiset< _Key, _Hash, _Compare, _Alloc >), "header", fragment=SWIG_Traits_frag(_Key), - fragment="StdMultisetTraits") { + fragment="StdUnorderedMultisetTraits") { namespace swig { - template <> struct traits > { + template <> struct traits > { typedef pointer_category category; static const char* type_name() { - return "std::unordered_multiset<" #_Key "," #_Compare "," #_Alloc " >"; + return "std::unordered_multiset<" #_Key "," #_Hash "," #_Compare "," #_Alloc " >"; } }; } } - %typemap_traits_ptr(SWIG_TYPECHECK_MULTISET, std::unordered_multiset< _Key, _Compare, _Alloc >); - - unordered_multiset( const _Compare& ); + %typemap_traits_ptr(SWIG_TYPECHECK_MULTISET, std::unordered_multiset< _Key, _Hash, _Compare, _Alloc >); #ifdef %swig_unordered_multiset_methods // Add swig/language extra methods - %swig_unordered_multiset_methods(std::unordered_multiset< _Key, _Compare, _Alloc >); + %swig_unordered_multiset_methods(std::unordered_multiset< _Key, _Hash, _Compare, _Alloc >); #endif %std_unordered_multiset_methods(unordered_multiset); diff --git a/Lib/std/std_unordered_set.i b/Lib/std/std_unordered_set.i index 98e792040..75e955c4b 100644 --- a/Lib/std/std_unordered_set.i +++ b/Lib/std/std_unordered_set.i @@ -1,8 +1,5 @@ // // std::unordered_set -// Work in progress - the code is not compilable yet: -// operator--() and constructor(compare function) not available for unordered_ -// types // %include @@ -110,8 +107,6 @@ namespace std { %typemap_traits_ptr(SWIG_TYPECHECK_SET, std::unordered_set< _Key, _Hash, _Compare, _Alloc >); - unordered_set( const _Compare& ); - #ifdef %swig_unordered_set_methods // Add swig/language extra methods %swig_unordered_set_methods(std::unordered_set< _Key, _Hash, _Compare, _Alloc >); diff --git a/Lib/swig.swg b/Lib/swig.swg index 6f48f0d20..6dc215dcf 100644 --- a/Lib/swig.swg +++ b/Lib/swig.swg @@ -309,11 +309,13 @@ static int NAME(TYPE x) { %define %$classname %$ismember,"match$parentNode$name" %enddef %define %$isnested "match$nested"="1" %enddef + /* ----------------------------------------------------------------------------- - * Include all the warnings labels and macros + * Common includes for warning labels, macros, fragments etc * ----------------------------------------------------------------------------- */ %include +%include /* ----------------------------------------------------------------------------- * Overloading support diff --git a/Lib/swigfragments.swg b/Lib/swigfragments.swg new file mode 100644 index 000000000..63bb6c8f4 --- /dev/null +++ b/Lib/swigfragments.swg @@ -0,0 +1,86 @@ +/* ----------------------------------------------------------------------------- + * swigfragments.swg + * + * Common fragments + * ----------------------------------------------------------------------------- */ + +/* ----------------------------------------------------------------------------- + * Fragments for C header files + * ----------------------------------------------------------------------------- */ + +%fragment("", "header") %{ +#include +%} + +/* Default compiler options for gcc allow long_long but not LLONG_MAX. + * Define SWIG_NO_LLONG_MAX if this added limits support is not wanted. */ +%fragment("", "header") %{ +#include +#if !defined(SWIG_NO_LLONG_MAX) +# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) +# define LLONG_MAX __LONG_LONG_MAX__ +# define LLONG_MIN (-LLONG_MAX - 1LL) +# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) +# endif +#endif +%} + +%fragment("", "header") %{ +#include +%} + +%fragment("", "header") %{ +#include +%} + +%fragment("", "header") %{ +#include +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) +# ifndef snprintf +# define snprintf _snprintf +# endif +#endif +%} + +%fragment("", "header") %{ +#include +#ifdef _MSC_VER +# ifndef strtoull +# define strtoull _strtoui64 +# endif +# ifndef strtoll +# define strtoll _strtoi64 +# endif +#endif +%} + +%fragment("", "header") %{ +#include +#include +#ifndef WCHAR_MIN +# define WCHAR_MIN 0 +#endif +#ifndef WCHAR_MAX +# define WCHAR_MAX 65535 +#endif +%} + +/* ----------------------------------------------------------------------------- + * Fragments for C++ header files + * ----------------------------------------------------------------------------- */ + +%fragment("", "header") %{ +#include +%} + +%fragment("", "header") %{ +#include +%} + +%fragment("", "header") %{ +#include +%} + +%fragment("", "header") %{ +#include +%} diff --git a/Lib/tcl/tclrun.swg b/Lib/tcl/tclrun.swg index f671ba240..408ddac3d 100644 --- a/Lib/tcl/tclrun.swg +++ b/Lib/tcl/tclrun.swg @@ -199,7 +199,7 @@ SWIG_Tcl_PointerTypeFromString(char *c) { return c; } -/* Convert a packed value value */ +/* Convert a packed pointer value */ SWIGRUNTIME int SWIG_Tcl_ConvertPacked(Tcl_Interp *SWIGUNUSEDPARM(interp) , Tcl_Obj *obj, void *ptr, int sz, swig_type_info *ty) { swig_cast_info *tc; diff --git a/Lib/typemaps/fragments.swg b/Lib/typemaps/fragments.swg index 3f33ca98d..aaf948c05 100644 --- a/Lib/typemaps/fragments.swg +++ b/Lib/typemaps/fragments.swg @@ -96,75 +96,6 @@ * common fragments * ------------------------------------------------------------ */ -/* Default compiler options for gcc allow long_long but not LLONG_MAX. - * Define SWIG_NO_LLONG_MAX if this added limits support is not wanted. */ -%fragment("","header") %{ -#include -#if !defined(SWIG_NO_LLONG_MAX) -# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) -# define LLONG_MAX __LONG_LONG_MAX__ -# define LLONG_MIN (-LLONG_MAX - 1LL) -# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) -# endif -#endif -%} - -%fragment("","header") %{ -#include -%} - -%fragment("","header") %{ -#include -#include -#ifndef WCHAR_MIN -# define WCHAR_MIN 0 -#endif -#ifndef WCHAR_MAX -# define WCHAR_MAX 65535 -#endif -%} - -%fragment("","header") %{ -#include -%} - -%fragment("","header") %{ -#include -#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) -# ifndef snprintf -# define snprintf _snprintf -# endif -#endif -%} - -%fragment("","header") %{ -#include -#ifdef _MSC_VER -# ifndef strtoull -# define strtoull _strtoui64 -# endif -# ifndef strtoll -# define strtoll _strtoi64 -# endif -#endif -%} - -%fragment("", "header") %{ -#include -%} - -%fragment("", "header") %{ -#include -%} - -%fragment("", "header") %{ -#include -%} - -%fragment("", "header") %{ -#include -%} - %fragment("SWIG_isfinite","header",fragment=",") %{ /* Getting isfinite working pre C99 across multiple platforms is non-trivial. Users can provide SWIG_isfinite on older platforms. */ #ifndef SWIG_isfinite diff --git a/Lib/typemaps/swigtype.swg b/Lib/typemaps/swigtype.swg index d3633eb49..b21240af8 100644 --- a/Lib/typemaps/swigtype.swg +++ b/Lib/typemaps/swigtype.swg @@ -584,6 +584,9 @@ } #endif +%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) } +%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) } + /* ------------------------------------------------------------ * --- function ptr typemaps --- * ------------------------------------------------------------ */ diff --git a/README b/README index 5510e0ec3..649602048 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ SWIG (Simplified Wrapper and Interface Generator) -Version: 3.0.13 (in progress) +Version: 4.0.0 (in progress) Tagline: SWIG is a compiler that integrates C and C++ with languages including Perl, Python, Tcl, Ruby, PHP, Java, C#, D, Go, Lua, diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index d62d5796f..80fbc033b 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -242,7 +242,7 @@ int SWIG_cparse_template_reduce(int treduce) { * ----------------------------------------------------------------------------- */ static int promote_type(int t) { - if (t <= T_UCHAR || t == T_CHAR) return T_INT; + if (t <= T_UCHAR || t == T_CHAR || t == T_WCHAR) return T_INT; return t; } @@ -257,7 +257,7 @@ static String *yyrename = 0; /* Forward renaming operator */ -static String *resolve_create_node_scope(String *cname); +static String *resolve_create_node_scope(String *cname, int is_class_definition); Hash *Swig_cparse_features(void) { @@ -533,8 +533,19 @@ static void add_symbols(Node *n) { SetFlag(n,"deleted"); SetFlag(n,"feature:ignore"); } + if (SwigType_isrvalue_reference(Getattr(n, "refqualifier"))) { + /* Ignore rvalue ref-qualifiers by default + * Use Getattr instead of GetFlag to handle explicit ignore and explicit not ignore */ + if (!(Getattr(n, "feature:ignore") || Strncmp(symname, "$ignore", 7) == 0)) { + SWIG_WARN_NODE_BEGIN(n); + Swig_warning(WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED, Getfile(n), Getline(n), + "Method with rvalue ref-qualifier %s ignored.\n", Swig_name_decl(n)); + SWIG_WARN_NODE_END(n); + SetFlag(n, "feature:ignore"); + } + } } - if (only_csymbol || GetFlag(n,"feature:ignore") || strncmp(Char(symname),"$ignore",7) == 0) { + if (only_csymbol || GetFlag(n, "feature:ignore") || Strncmp(symname, "$ignore", 7) == 0) { /* Only add to C symbol table and continue */ Swig_symbol_add(0, n); if (!only_csymbol && !GetFlag(n, "feature:ignore")) { @@ -863,32 +874,53 @@ static String *remove_block(Node *kw, const String *inputcode) { return modified_code; } - +/* +#define RESOLVE_DEBUG 1 +*/ static Node *nscope = 0; static Node *nscope_inner = 0; /* Remove the scope prefix from cname and return the base name without the prefix. * The scopes required for the symbol name are resolved and/or created, if required. * For example AA::BB::CC as input returns CC and creates the namespace AA then inner - * namespace BB in the current scope. If cname is found to already exist as a weak symbol - * (forward reference) then the scope might be changed to match, such as when a symbol match - * is made via a using reference. */ -static String *resolve_create_node_scope(String *cname) { + * namespace BB in the current scope. */ +static String *resolve_create_node_scope(String *cname, int is_class_definition) { Symtab *gscope = 0; Node *cname_node = 0; - int skip_lookup = 0; + String *last = Swig_scopename_last(cname); nscope = 0; nscope_inner = 0; - if (Strncmp(cname,"::",2) == 0) - skip_lookup = 1; - - cname_node = skip_lookup ? 0 : Swig_symbol_clookup_no_inherit(cname, 0); + if (Strncmp(cname,"::" ,2) != 0) { + if (is_class_definition) { + /* Only lookup symbols which are in scope via a using declaration but not via a using directive. + For example find y via 'using x::y' but not y via a 'using namespace x'. */ + cname_node = Swig_symbol_clookup_no_inherit(cname, 0); + if (!cname_node) { + Node *full_lookup_node = Swig_symbol_clookup(cname, 0); + if (full_lookup_node) { + /* This finds a symbol brought into scope via both a using directive and a using declaration. */ + Node *last_node = Swig_symbol_clookup_no_inherit(last, 0); + if (last_node == full_lookup_node) + cname_node = last_node; + } + } + } else { + /* For %template, the template needs to be in scope via any means. */ + cname_node = Swig_symbol_clookup(cname, 0); + } + } +#if RESOLVE_DEBUG + if (!cname_node) + Printf(stdout, "symbol does not yet exist (%d): [%s]\n", is_class_definition, cname); + else + Printf(stdout, "symbol does exist (%d): [%s]\n", is_class_definition, cname); +#endif if (cname_node) { /* The symbol has been defined already or is in another scope. - If it is a weak symbol, it needs replacing and if it was brought into the current scope - via a using declaration, the scope needs adjusting appropriately for the new symbol. + If it is a weak symbol, it needs replacing and if it was brought into the current scope, + the scope needs adjusting appropriately for the new symbol. Similarly for defined templates. */ Symtab *symtab = Getattr(cname_node, "sym:symtab"); Node *sym_weak = Getattr(cname_node, "sym:weak"); @@ -896,48 +928,92 @@ static String *resolve_create_node_scope(String *cname) { /* Check if the scope is the current scope */ String *current_scopename = Swig_symbol_qualifiedscopename(0); String *found_scopename = Swig_symbol_qualifiedscopename(symtab); - int len; if (!current_scopename) current_scopename = NewString(""); if (!found_scopename) found_scopename = NewString(""); - len = Len(current_scopename); - if ((len > 0) && (Strncmp(current_scopename, found_scopename, len) == 0)) { - if (Len(found_scopename) > len + 2) { - /* A matching weak symbol was found in non-global scope, some scope adjustment may be required */ - String *new_cname = NewString(Char(found_scopename) + len + 2); /* skip over "::" prefix */ - String *base = Swig_scopename_last(cname); - Printf(new_cname, "::%s", base); - cname = new_cname; - Delete(base); - } else { - /* A matching weak symbol was found in the same non-global local scope, no scope adjustment required */ - assert(len == Len(found_scopename)); + + { + int fail = 1; + List *current_scopes = Swig_scopename_tolist(current_scopename); + List *found_scopes = Swig_scopename_tolist(found_scopename); + Iterator cit = First(current_scopes); + Iterator fit = First(found_scopes); +#if RESOLVE_DEBUG +Printf(stdout, "comparing current: [%s] found: [%s]\n", current_scopename, found_scopename); +#endif + for (; fit.item && cit.item; fit = Next(fit), cit = Next(cit)) { + String *current = cit.item; + String *found = fit.item; +#if RESOLVE_DEBUG + Printf(stdout, " looping %s %s\n", current, found); +#endif + if (Strcmp(current, found) != 0) + break; } - } else { - String *base = Swig_scopename_last(cname); - if (Len(found_scopename) > 0) { - /* A matching weak symbol was found in a different scope to the local scope - probably via a using declaration */ - cname = NewStringf("%s::%s", found_scopename, base); + + if (!cit.item) { + String *subscope = NewString(""); + for (; fit.item; fit = Next(fit)) { + if (Len(subscope) > 0) + Append(subscope, "::"); + Append(subscope, fit.item); + } + if (Len(subscope) > 0) + cname = NewStringf("%s::%s", subscope, last); + else + cname = Copy(last); +#if RESOLVE_DEBUG + Printf(stdout, "subscope to create: [%s] cname: [%s]\n", subscope, cname); +#endif + fail = 0; + Delete(subscope); } else { - /* Either: - 1) A matching weak symbol was found in a different scope to the local scope - this is actually a - symbol with the same name in a different scope which we don't want, so no adjustment required. - 2) A matching weak symbol was found in the global scope - no adjustment required. - */ - cname = Copy(base); + if (is_class_definition) { + if (!fit.item) { + /* It is valid to define a new class with the same name as one forward declared in a parent scope */ + fail = 0; + } else if (Swig_scopename_check(cname)) { + /* Classes defined with scope qualifiers must have a matching forward declaration in matching scope */ + fail = 1; + } else { + /* This may let through some invalid cases */ + fail = 0; + } +#if RESOLVE_DEBUG + Printf(stdout, "scope for class definition, fail: %d\n", fail); +#endif + } else { +#if RESOLVE_DEBUG + Printf(stdout, "no matching base scope for template\n"); +#endif + fail = 1; + } + } + + Delete(found_scopes); + Delete(current_scopes); + + if (fail) { + String *cname_resolved = NewStringf("%s::%s", found_scopename, last); + Swig_error(cparse_file, cparse_line, "'%s' resolves to '%s' and was incorrectly instantiated in scope '%s' instead of within scope '%s'.\n", cname, cname_resolved, current_scopename, found_scopename); + cname = Copy(last); + Delete(cname_resolved); } - Delete(base); } + Delete(current_scopename); Delete(found_scopename); } + } else if (!is_class_definition) { + /* A template instantiation requires a template to be found in scope... fail here too? + Swig_error(cparse_file, cparse_line, "No template found to instantiate '%s' with %%template.\n", cname); + */ } if (Swig_scopename_check(cname)) { Node *ns; String *prefix = Swig_scopename_prefix(cname); - String *base = Swig_scopename_last(cname); if (prefix && (Strncmp(prefix,"::",2) == 0)) { /* I don't think we can use :: global scope to declare classes and hence neither %template. - consider reporting error instead - wsfulton. */ /* Use the global scope */ @@ -947,6 +1023,7 @@ static String *resolve_create_node_scope(String *cname) { gscope = set_scope_to_global(); } if (Len(prefix) == 0) { + String *base = Copy(last); /* Use the global scope, but we need to add a 'global' namespace. */ if (!gscope) gscope = set_scope_to_global(); /* note that this namespace is not the "unnamed" one, @@ -955,6 +1032,7 @@ static String *resolve_create_node_scope(String *cname) { nscope = new_node("namespace"); Setattr(nscope,"symtab", gscope);; nscope_inner = nscope; + Delete(last); return base; } /* Try to locate the scope */ @@ -972,7 +1050,7 @@ static String *resolve_create_node_scope(String *cname) { String *nname = Swig_symbol_qualifiedscopename(nstab); if (tname && (Strcmp(tname,nname) == 0)) { ns = 0; - cname = base; + cname = Copy(last); } Delete(tname); Delete(nname); @@ -980,19 +1058,10 @@ static String *resolve_create_node_scope(String *cname) { if (ns) { /* we will try to create a new node using the namespaces we can find in the scope name */ - List *scopes; + List *scopes = Swig_scopename_tolist(prefix); String *sname; Iterator si; - String *name = NewString(prefix); - scopes = NewList(); - while (name) { - String *base = Swig_scopename_last(name); - String *tprefix = Swig_scopename_prefix(name); - Insert(scopes,0,base); - Delete(base); - Delete(name); - name = tprefix; - } + for (si = First(scopes); si.item; si = Next(si)) { Node *ns1,*ns2; sname = si.item; @@ -1038,12 +1107,13 @@ static String *resolve_create_node_scope(String *cname) { nscope_inner = ns2; if (!nscope) nscope = ns2; } - cname = base; + cname = Copy(last); Delete(scopes); } } Delete(prefix); } + Delete(last); return cname; } @@ -1399,6 +1469,56 @@ static void mark_nodes_as_extend(Node *n) { } } +/* ----------------------------------------------------------------------------- + * add_qualifier_to_declarator() + * + * Normally the qualifier is pushed on to the front of the type. + * Adding a qualifier to a pointer to member function is a special case. + * For example : typedef double (Cls::*pmf)(void) const; + * The qualifier is : q(const). + * The declarator is : m(Cls).f(void). + * We need : m(Cls).q(const).f(void). + * ----------------------------------------------------------------------------- */ + +static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier) { + int is_pointer_to_member_function = 0; + String *decl = Copy(type); + String *poppedtype = NewString(""); + assert(qualifier); + + while (decl) { + if (SwigType_ismemberpointer(decl)) { + String *memberptr = SwigType_pop(decl); + if (SwigType_isfunction(decl)) { + is_pointer_to_member_function = 1; + SwigType_push(decl, qualifier); + SwigType_push(decl, memberptr); + Insert(decl, 0, poppedtype); + Delete(memberptr); + break; + } else { + Append(poppedtype, memberptr); + } + Delete(memberptr); + } else { + String *popped = SwigType_pop(decl); + if (!popped) + break; + Append(poppedtype, popped); + Delete(popped); + } + } + + if (!is_pointer_to_member_function) { + Delete(decl); + decl = Copy(type); + SwigType_push(decl, qualifier); + } + + Delete(poppedtype); + return decl; +} + %} %union { @@ -1409,6 +1529,7 @@ static void mark_nodes_as_extend(Node *n) { String *rawval; int type; String *qualifier; + String *refqualifier; String *bitfield; Parm *throws; String *throwf; @@ -1521,7 +1642,7 @@ static void mark_nodes_as_extend(Node *n) { /* Misc */ %type identifier; -%type initializer cpp_const exception_specification; +%type initializer cpp_const exception_specification cv_ref_qualifier qualifiers_exception_specification; %type storage_class extern_string; %type parms ptail rawparms varargs_parms ; %type templateparameters templateparameterstail; @@ -1537,7 +1658,8 @@ static void mark_nodes_as_extend(Node *n) { %type expr exprnum exprcompound valexpr; %type ename ; %type less_valparms_greater; -%type type_qualifier ; +%type type_qualifier; +%type ref_qualifier; %type type_qualifier_raw; %type idstring idstringopt; %type pragma_lang; @@ -1557,7 +1679,7 @@ static void mark_nodes_as_extend(Node *n) { %type featattr; %type lambda_introducer lambda_body; %type lambda_tail; -%type virt_specifier_seq; +%type virt_specifier_seq virt_specifier_seq_opt; %% @@ -1816,7 +1938,6 @@ constant_directive : CONSTANT identifier EQUAL definetype SEMI { } } - | CONSTANT type declarator def_args SEMI { if (($4.type != T_ERROR) && ($4.type != T_SYMBOL)) { SwigType_push($2,$3.type); @@ -1833,12 +1954,38 @@ constant_directive : CONSTANT identifier EQUAL definetype SEMI { SetFlag($$,"feature:immutable"); add_symbols($$); } else { - if ($4.type == T_ERROR) { - Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value\n"); - } + if ($4.type == T_ERROR) { + Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line, "Unsupported constant value\n"); + } $$ = 0; } } + /* Member function pointers with qualifiers. eg. + %constant short (Funcs::*pmf)(bool) const = &Funcs::F; */ + | CONSTANT type direct_declarator LPAREN parms RPAREN cv_ref_qualifier def_args SEMI { + if (($8.type != T_ERROR) && ($8.type != T_SYMBOL)) { + SwigType_add_function($2, $5); + SwigType_push($2, $7.qualifier); + SwigType_push($2, $3.type); + /* Sneaky callback function trick */ + if (SwigType_isfunction($2)) { + SwigType_add_pointer($2); + } + $$ = new_node("constant"); + Setattr($$, "name", $3.id); + Setattr($$, "type", $2); + Setattr($$, "value", $8.val); + if ($8.rawval) Setattr($$, "rawval", $8.rawval); + Setattr($$, "storage", "%constant"); + SetFlag($$, "feature:immutable"); + add_symbols($$); + } else { + if ($8.type == T_ERROR) { + Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line, "Unsupported constant value\n"); + } + $$ = 0; + } + } | CONSTANT error SEMI { Swig_warning(WARN_PARSE_BAD_VALUE,cparse_file,cparse_line,"Bad constant value (ignored).\n"); $$ = 0; @@ -2640,9 +2787,8 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va tscope = Swig_symbol_current(); /* Get the current scope */ /* If the class name is qualified, we need to create or lookup namespace entries */ - if (!inclass) { - $5 = resolve_create_node_scope($5); - } + $5 = resolve_create_node_scope($5, 0); + if (nscope_inner && Strcmp(nodeType(nscope_inner), "class") == 0) { outer_class = nscope_inner; } @@ -3000,43 +3146,117 @@ c_declaration : c_decl { SetFlag($$,"aliastemplate"); add_symbols($$); } + | cpp_static_assert { + $$ = $1; + } ; /* ------------------------------------------------------------ A C global declaration of some kind (may be variable, function, typedef, etc.) ------------------------------------------------------------ */ -c_decl : storage_class type declarator initializer c_decl_tail { +c_decl : storage_class type declarator cpp_const initializer c_decl_tail { + String *decl = $3.type; $$ = new_node("cdecl"); - if ($4.qualifier) SwigType_push($3.type,$4.qualifier); + if ($4.qualifier) + decl = add_qualifier_to_declarator($3.type, $4.qualifier); + Setattr($$,"refqualifier",$4.refqualifier); Setattr($$,"type",$2); Setattr($$,"storage",$1); Setattr($$,"name",$3.id); + Setattr($$,"decl",decl); + Setattr($$,"parms",$3.parms); + Setattr($$,"value",$5.val); + Setattr($$,"throws",$4.throws); + Setattr($$,"throw",$4.throwf); + Setattr($$,"noexcept",$4.nexcept); + if ($5.val && $5.type) { + /* store initializer type as it might be different to the declared type */ + SwigType *valuetype = NewSwigType($5.type); + if (Len(valuetype) > 0) + Setattr($$,"valuetype",valuetype); + else + Delete(valuetype); + } + if (!$6) { + if (Len(scanner_ccode)) { + String *code = Copy(scanner_ccode); + Setattr($$,"code",code); + Delete(code); + } + } else { + Node *n = $6; + /* Inherit attributes */ + while (n) { + String *type = Copy($2); + Setattr(n,"type",type); + Setattr(n,"storage",$1); + n = nextSibling(n); + Delete(type); + } + } + if ($5.bitfield) { + Setattr($$,"bitfield", $5.bitfield); + } + + if ($3.id) { + /* Look for "::" declarations (ignored) */ + if (Strstr($3.id, "::")) { + /* This is a special case. If the scope name of the declaration exactly + matches that of the declaration, then we will allow it. Otherwise, delete. */ + String *p = Swig_scopename_prefix($3.id); + if (p) { + if ((Namespaceprefix && Strcmp(p, Namespaceprefix) == 0) || + (Classprefix && Strcmp(p, Classprefix) == 0)) { + String *lstr = Swig_scopename_last($3.id); + Setattr($$, "name", lstr); + Delete(lstr); + set_nextSibling($$, $6); + } else { + Delete($$); + $$ = $6; + } + Delete(p); + } else { + Delete($$); + $$ = $6; + } + } else { + set_nextSibling($$, $6); + } + } else { + Swig_error(cparse_file, cparse_line, "Missing symbol name for global declaration\n"); + $$ = 0; + } + + if ($4.qualifier && $1 && Strstr($1, "static")) + Swig_error(cparse_file, cparse_line, "Static function %s cannot have a qualifier.\n", Swig_name_decl($$)); + } + /* Alternate function syntax introduced in C++11: + auto funcName(int x, int y) -> int; */ + | storage_class AUTO declarator cpp_const ARROW cpp_alternate_rettype virt_specifier_seq_opt initializer c_decl_tail { + $$ = new_node("cdecl"); + if ($4.qualifier) SwigType_push($3.type, $4.qualifier); + Setattr($$,"refqualifier",$4.refqualifier); + Setattr($$,"type",$6); + Setattr($$,"storage",$1); + Setattr($$,"name",$3.id); Setattr($$,"decl",$3.type); Setattr($$,"parms",$3.parms); Setattr($$,"value",$4.val); Setattr($$,"throws",$4.throws); Setattr($$,"throw",$4.throwf); Setattr($$,"noexcept",$4.nexcept); - if ($4.val && $4.type) { - /* store initializer type as it might be different to the declared type */ - SwigType *valuetype = NewSwigType($4.type); - if (Len(valuetype) > 0) - Setattr($$,"valuetype",valuetype); - else - Delete(valuetype); - } - if (!$5) { + if (!$9) { if (Len(scanner_ccode)) { String *code = Copy(scanner_ccode); Setattr($$,"code",code); Delete(code); } } else { - Node *n = $5; - /* Inherit attributes */ + Node *n = $9; while (n) { - String *type = Copy($2); + String *type = Copy($6); Setattr(n,"type",type); Setattr(n,"storage",$1); n = nextSibling(n); @@ -3047,10 +3267,7 @@ c_decl : storage_class type declarator initializer c_decl_tail { Setattr($$,"bitfield", $4.bitfield); } - /* Look for "::" declarations (ignored) */ if (Strstr($3.id,"::")) { - /* This is a special case. If the scope name of the declaration exactly - matches that of the declaration, then we will allow it. Otherwise, delete. */ String *p = Swig_scopename_prefix($3.id); if (p) { if ((Namespaceprefix && Strcmp(p, Namespaceprefix) == 0) || @@ -3058,75 +3275,22 @@ c_decl : storage_class type declarator initializer c_decl_tail { String *lstr = Swig_scopename_last($3.id); Setattr($$,"name",lstr); Delete(lstr); - set_nextSibling($$,$5); + set_nextSibling($$, $9); } else { Delete($$); - $$ = $5; + $$ = $9; } Delete(p); } else { Delete($$); - $$ = $5; + $$ = $9; } } else { - set_nextSibling($$,$5); - } - } - /* Alternate function syntax introduced in C++11: - auto funcName(int x, int y) -> int; */ - | storage_class AUTO declarator ARROW cpp_alternate_rettype initializer c_decl_tail { - $$ = new_node("cdecl"); - if ($6.qualifier) SwigType_push($3.type,$6.qualifier); - Setattr($$,"type",$5); - Setattr($$,"storage",$1); - Setattr($$,"name",$3.id); - Setattr($$,"decl",$3.type); - Setattr($$,"parms",$3.parms); - Setattr($$,"value",$6.val); - Setattr($$,"throws",$6.throws); - Setattr($$,"throw",$6.throwf); - Setattr($$,"noexcept",$6.nexcept); - if (!$7) { - if (Len(scanner_ccode)) { - String *code = Copy(scanner_ccode); - Setattr($$,"code",code); - Delete(code); - } - } else { - Node *n = $7; - while (n) { - String *type = Copy($5); - Setattr(n,"type",type); - Setattr(n,"storage",$1); - n = nextSibling(n); - Delete(type); - } - } - if ($6.bitfield) { - Setattr($$,"bitfield", $6.bitfield); + set_nextSibling($$, $9); } - if (Strstr($3.id,"::")) { - String *p = Swig_scopename_prefix($3.id); - if (p) { - if ((Namespaceprefix && Strcmp(p, Namespaceprefix) == 0) || - (Classprefix && Strcmp(p, Classprefix) == 0)) { - String *lstr = Swig_scopename_last($3.id); - Setattr($$,"name",lstr); - Delete(lstr); - set_nextSibling($$,$7); - } else { - Delete($$); - $$ = $7; - } - Delete(p); - } else { - Delete($$); - $$ = $7; - } - } else { - set_nextSibling($$,$7); - } + if ($4.qualifier && $1 && Strstr($1, "static")) + Swig_error(cparse_file, cparse_line, "Static function %s cannot have a qualifier.\n", Swig_name_decl($$)); } ; @@ -3136,27 +3300,28 @@ c_decl_tail : SEMI { $$ = 0; Clear(scanner_ccode); } - | COMMA declarator initializer c_decl_tail { + | COMMA declarator cpp_const initializer c_decl_tail { $$ = new_node("cdecl"); if ($3.qualifier) SwigType_push($2.type,$3.qualifier); + Setattr($$,"refqualifier",$3.refqualifier); Setattr($$,"name",$2.id); Setattr($$,"decl",$2.type); Setattr($$,"parms",$2.parms); - Setattr($$,"value",$3.val); + Setattr($$,"value",$4.val); Setattr($$,"throws",$3.throws); Setattr($$,"throw",$3.throwf); Setattr($$,"noexcept",$3.nexcept); - if ($3.bitfield) { - Setattr($$,"bitfield", $3.bitfield); + if ($4.bitfield) { + Setattr($$,"bitfield", $4.bitfield); } - if (!$4) { + if (!$5) { if (Len(scanner_ccode)) { String *code = Copy(scanner_ccode); Setattr($$,"code",code); Delete(code); } } else { - set_nextSibling($$,$4); + set_nextSibling($$, $5); } } | LBRACE { @@ -3174,33 +3339,8 @@ c_decl_tail : SEMI { } ; -initializer : def_args { - $$ = $1; - $$.qualifier = 0; - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = 0; - } - | type_qualifier def_args { - $$ = $2; - $$.qualifier = $1; - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = 0; - } - | exception_specification def_args { - $$ = $2; - $$.qualifier = 0; - $$.throws = $1.throws; - $$.throwf = $1.throwf; - $$.nexcept = $1.nexcept; - } - | type_qualifier exception_specification def_args { - $$ = $3; - $$.qualifier = $1; - $$.throws = $2.throws; - $$.throwf = $2.throwf; - $$.nexcept = $2.nexcept; +initializer : def_args { + $$ = $1; } ; @@ -3343,7 +3483,7 @@ c_enum_decl : storage_class c_enum_key ename c_enum_inherit LBRACE enumlist RBR Namespaceprefix = Swig_symbol_qualifiedscopename(0); } } - | storage_class c_enum_key ename c_enum_inherit LBRACE enumlist RBRACE declarator initializer c_decl_tail { + | storage_class c_enum_key ename c_enum_inherit LBRACE enumlist RBRACE declarator cpp_const initializer c_decl_tail { Node *n; SwigType *ty = 0; String *unnamed = 0; @@ -3390,8 +3530,8 @@ c_enum_decl : storage_class c_enum_key ename c_enum_inherit LBRACE enumlist RBR SetFlag(n,"unnamedinstance"); Delete(cty); } - if ($10) { - Node *p = $10; + if ($11) { + Node *p = $11; set_nextSibling(n,p); while (p) { SwigType *cty = Copy(ty); @@ -3522,7 +3662,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE { Setattr($$,"prev_symtab",Swig_symbol_current()); /* If the class name is qualified. We need to create or lookup namespace/scope entries */ - scope = resolve_create_node_scope($3); + scope = resolve_create_node_scope($3, 1); /* save nscope_inner to the class - it may be overwritten in nested classes*/ Setattr($$, "nested:innerscope", nscope_inner); Setattr($$, "nested:nscope", nscope); @@ -3899,12 +4039,12 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE { ; cpp_opt_declarators : SEMI { $$ = 0; } - | declarator initializer c_decl_tail { + | declarator cpp_const initializer c_decl_tail { $$ = new_node("cdecl"); Setattr($$,"name",$1.id); Setattr($$,"decl",$1.type); Setattr($$,"parms",$1.parms); - set_nextSibling($$,$3); + set_nextSibling($$, $4); } ; /* ------------------------------------------------------------ @@ -4211,9 +4351,6 @@ cpp_temp_possible: c_decl { | cpp_constructor_decl { $$ = $1; } - | cpp_static_assert { - $$ = $1; - } | cpp_template_decl { $$ = 0; } @@ -4471,7 +4608,6 @@ cpp_member_no_dox : c_declaration { $$ = $1; } default_arguments($$); } | cpp_destructor_decl { $$ = $1; } - | cpp_static_assert { $$ = $1; } | cpp_protection_decl { $$ = $1; } | cpp_swig_directive { $$ = $1; } | cpp_conversion_operator { $$ = $1; } @@ -4557,6 +4693,8 @@ cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end { Setattr($$,"noexcept",$6.nexcept); if ($6.val) Setattr($$,"value",$6.val); + if ($6.qualifier) + Swig_error(cparse_file, cparse_line, "Destructor %s %s cannot have a qualifier.\n", Swig_name_decl($$), SwigType_str($6.qualifier, 0)); add_symbols($$); } @@ -4586,7 +4724,8 @@ cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end { Setattr($$,"decl",decl); Delete(decl); } - + if ($7.qualifier) + Swig_error(cparse_file, cparse_line, "Destructor %s %s cannot have a qualifier.\n", Swig_name_decl($$), SwigType_str($7.qualifier, 0)); add_symbols($$); } ; @@ -4603,6 +4742,7 @@ cpp_conversion_operator : storage_class CONVERSIONOPERATOR type pointer LPAREN p if ($8.qualifier) { SwigType_push($4,$8.qualifier); } + Setattr($$,"refqualifier",$8.refqualifier); Setattr($$,"decl",$4); Setattr($$,"parms",$6); Setattr($$,"conversion_operator","1"); @@ -4620,6 +4760,7 @@ cpp_conversion_operator : storage_class CONVERSIONOPERATOR type pointer LPAREN p if ($8.qualifier) { SwigType_push(decl,$8.qualifier); } + Setattr($$,"refqualifier",$8.refqualifier); Setattr($$,"decl",decl); Setattr($$,"parms",$6); Setattr($$,"conversion_operator","1"); @@ -4637,6 +4778,7 @@ cpp_conversion_operator : storage_class CONVERSIONOPERATOR type pointer LPAREN p if ($8.qualifier) { SwigType_push(decl,$8.qualifier); } + Setattr($$,"refqualifier",$8.refqualifier); Setattr($$,"decl",decl); Setattr($$,"parms",$6); Setattr($$,"conversion_operator","1"); @@ -4656,6 +4798,7 @@ cpp_conversion_operator : storage_class CONVERSIONOPERATOR type pointer LPAREN p if ($9.qualifier) { SwigType_push(decl,$9.qualifier); } + Setattr($$,"refqualifier",$9.refqualifier); Setattr($$,"decl",decl); Setattr($$,"parms",$7); Setattr($$,"conversion_operator","1"); @@ -4672,6 +4815,7 @@ cpp_conversion_operator : storage_class CONVERSIONOPERATOR type pointer LPAREN p if ($7.qualifier) { SwigType_push(t,$7.qualifier); } + Setattr($$,"refqualifier",$7.refqualifier); Setattr($$,"decl",t); Setattr($$,"parms",$5); Setattr($$,"conversion_operator","1"); @@ -4687,7 +4831,8 @@ cpp_catch_decl : CATCH LPAREN parms RPAREN LBRACE { } ; -/* static_assert(bool, const char*); */ +/* static_assert(bool, const char*); (C++11) + * static_assert(bool); (C++17) */ cpp_static_assert : STATIC_ASSERT LPAREN { skip_balanced('(',')'); $$ = 0; @@ -4741,6 +4886,9 @@ cpp_swig_directive: pragma_directive { $$ = $1; } cpp_end : cpp_const SEMI { Clear(scanner_ccode); $$.val = 0; + $$.qualifier = $1.qualifier; + $$.refqualifier = $1.refqualifier; + $$.bitfield = 0; $$.throws = $1.throws; $$.throwf = $1.throwf; $$.nexcept = $1.nexcept; @@ -4748,6 +4896,9 @@ cpp_end : cpp_const SEMI { | cpp_const EQUAL default_delete SEMI { Clear(scanner_ccode); $$.val = $3.val; + $$.qualifier = $1.qualifier; + $$.refqualifier = $1.refqualifier; + $$.bitfield = 0; $$.throws = $1.throws; $$.throwf = $1.throwf; $$.nexcept = $1.nexcept; @@ -4755,6 +4906,9 @@ cpp_end : cpp_const SEMI { | cpp_const LBRACE { skip_balanced('{','}'); $$.val = 0; + $$.qualifier = $1.qualifier; + $$.refqualifier = $1.refqualifier; + $$.bitfield = 0; $$.throws = $1.throws; $$.throwf = $1.throwf; $$.nexcept = $1.nexcept; @@ -4765,6 +4919,7 @@ cpp_vend : cpp_const SEMI { Clear(scanner_ccode); $$.val = 0; $$.qualifier = $1.qualifier; + $$.refqualifier = $1.refqualifier; $$.bitfield = 0; $$.throws = $1.throws; $$.throwf = $1.throwf; @@ -4774,6 +4929,7 @@ cpp_vend : cpp_const SEMI { Clear(scanner_ccode); $$.val = $3.val; $$.qualifier = $1.qualifier; + $$.refqualifier = $1.refqualifier; $$.bitfield = 0; $$.throws = $1.throws; $$.throwf = $1.throwf; @@ -4783,6 +4939,7 @@ cpp_vend : cpp_const SEMI { skip_balanced('{','}'); $$.val = 0; $$.qualifier = $1.qualifier; + $$.refqualifier = $1.refqualifier; $$.bitfield = 0; $$.throws = $1.throws; $$.throwf = $1.throwf; @@ -5060,6 +5217,28 @@ parameter_declarator : declarator def_args { $$.id = 0; $$.defarg = $1.rawval ? $1.rawval : $1.val; } + /* Member function pointers with qualifiers. eg. + int f(short (Funcs::*parm)(bool) const); */ + | direct_declarator LPAREN parms RPAREN cv_ref_qualifier { + SwigType *t; + $$ = $1; + t = NewStringEmpty(); + SwigType_add_function(t,$3); + if ($5.qualifier) + SwigType_push(t, $5.qualifier); + if (!$$.have_parms) { + $$.parms = $3; + $$.have_parms = 1; + } + if (!$$.type) { + $$.type = t; + } else { + SwigType_push(t, $$.type); + Delete($$.type); + $$.type = t; + } + $$.defarg = 0; + } ; plain_declarator : declarator { @@ -5096,6 +5275,27 @@ plain_declarator : declarator { $$.parms = 0; } } + /* Member function pointers with qualifiers. eg. + int f(short (Funcs::*parm)(bool) const) */ + | direct_declarator LPAREN parms RPAREN cv_ref_qualifier { + SwigType *t; + $$ = $1; + t = NewStringEmpty(); + SwigType_add_function(t, $3); + if ($5.qualifier) + SwigType_push(t, $5.qualifier); + if (!$$.have_parms) { + $$.parms = $3; + $$.have_parms = 1; + } + if (!$$.type) { + $$.type = t; + } else { + SwigType_push(t, $$.type); + Delete($$.type); + $$.type = t; + } + } | empty { $$.type = 0; $$.id = 0; @@ -5103,7 +5303,6 @@ plain_declarator : declarator { } ; - declarator : pointer notso_direct_declarator { $$ = $2; if ($$.type) { @@ -5456,7 +5655,7 @@ direct_declarator : idcolon { } SwigType_add_rvalue_reference($$.type); } - | LPAREN idcolon DSTAR direct_declarator RPAREN { + | LPAREN idcolon DSTAR declarator RPAREN { SwigType *t; $$ = $4; t = NewStringEmpty(); @@ -5466,7 +5665,42 @@ direct_declarator : idcolon { Delete($$.type); } $$.type = t; + } + | LPAREN idcolon DSTAR type_qualifier declarator RPAREN { + SwigType *t; + $$ = $5; + t = NewStringEmpty(); + SwigType_add_memberpointer(t, $2); + SwigType_push(t, $4); + if ($$.type) { + SwigType_push(t, $$.type); + Delete($$.type); } + $$.type = t; + } + | LPAREN idcolon DSTAR abstract_declarator RPAREN { + SwigType *t; + $$ = $4; + t = NewStringEmpty(); + SwigType_add_memberpointer(t, $2); + if ($$.type) { + SwigType_push(t, $$.type); + Delete($$.type); + } + $$.type = t; + } + | LPAREN idcolon DSTAR type_qualifier abstract_declarator RPAREN { + SwigType *t; + $$ = $5; + t = NewStringEmpty(); + SwigType_add_memberpointer(t, $2); + SwigType_push(t, $4); + if ($$.type) { + SwigType_push(t, $$.type); + Delete($$.type); + } + $$.type = t; + } | direct_declarator LBRACKET RBRACKET { SwigType *t; $$ = $1; @@ -5505,7 +5739,7 @@ direct_declarator : idcolon { Delete($$.type); $$.type = t; } - } + } /* User-defined string literals. eg. int operator"" _mySuffix(const char* val, int length) {...} */ /* This produces one S/R conflict. */ @@ -5616,6 +5850,14 @@ abstract_declarator : pointer { $$.parms = 0; $$.have_parms = 0; } + | idcolon DSTAR type_qualifier { + $$.type = NewStringEmpty(); + SwigType_add_memberpointer($$.type, $1); + SwigType_push($$.type, $3); + $$.id = 0; + $$.parms = 0; + $$.have_parms = 0; + } | pointer idcolon DSTAR { SwigType *t = NewStringEmpty(); $$.type = $1; @@ -5693,6 +5935,24 @@ direct_abstract_declarator : direct_abstract_declarator LBRACKET RBRACKET { $$.have_parms = 1; } } + | direct_abstract_declarator LPAREN parms RPAREN cv_ref_qualifier { + SwigType *t; + $$ = $1; + t = NewStringEmpty(); + SwigType_add_function(t,$3); + SwigType_push(t, $5.qualifier); + if (!$$.type) { + $$.type = t; + } else { + SwigType_push(t,$$.type); + Delete($$.type); + $$.type = t; + } + if (!$$.have_parms) { + $$.parms = $3; + $$.have_parms = 1; + } + } | LPAREN parms RPAREN { $$.type = NewStringEmpty(); SwigType_add_function($$.type,$2); @@ -5727,6 +5987,33 @@ pointer : STAR type_qualifier pointer { } ; +/* cv-qualifier plus C++11 ref-qualifier for non-static member functions */ +cv_ref_qualifier : type_qualifier { + $$.qualifier = $1; + $$.refqualifier = 0; + } + | type_qualifier ref_qualifier { + $$.qualifier = $1; + $$.refqualifier = $2; + SwigType_push($$.qualifier, $2); + } + | ref_qualifier { + $$.qualifier = NewStringEmpty(); + $$.refqualifier = $1; + SwigType_push($$.qualifier, $1); + } + ; + +ref_qualifier : AND { + $$ = NewStringEmpty(); + SwigType_add_reference($$); + } + | LAND { + $$ = NewStringEmpty(); + SwigType_add_rvalue_reference($$); + } + ; + type_qualifier : type_qualifier_raw { $$ = NewStringEmpty(); if ($1) SwigType_add_qualifier($$,$1); @@ -5948,6 +6235,7 @@ definetype : { /* scanner_check_typedef(); */ } expr { $$.rawval = NewStringf("%s", $$.val); } $$.qualifier = 0; + $$.refqualifier = 0; $$.bitfield = 0; $$.throws = 0; $$.throwf = 0; @@ -5973,6 +6261,7 @@ deleted_definition : DELETE_KW { $$.rawval = 0; $$.type = T_STRING; $$.qualifier = 0; + $$.refqualifier = 0; $$.bitfield = 0; $$.throws = 0; $$.throwf = 0; @@ -5986,6 +6275,7 @@ explicit_default : DEFAULT { $$.rawval = 0; $$.type = T_STRING; $$.qualifier = 0; + $$.refqualifier = 0; $$.bitfield = 0; $$.throws = 0; $$.throwf = 0; @@ -6191,6 +6481,7 @@ valexpr : exprnum { $$ = $1; } break; } } + $$.type = promote($2.type, $4.type); } | LPAREN expr pointer RPAREN expr %prec CAST { $$ = $5; @@ -6525,6 +6816,14 @@ virt_specifier_seq : OVERRIDE { } ; +virt_specifier_seq_opt : virt_specifier_seq { + $$ = 0; + } + | empty { + $$ = 0; + } + ; + exception_specification : THROW LPAREN parms RPAREN { $$.throws = $3; $$.throwf = NewString("1"); @@ -6540,6 +6839,11 @@ exception_specification : THROW LPAREN parms RPAREN { $$.throwf = 0; $$.nexcept = 0; } + | THROW LPAREN parms RPAREN virt_specifier_seq { + $$.throws = $3; + $$.throwf = NewString("1"); + $$.nexcept = 0; + } | NOEXCEPT virt_specifier_seq { $$.throws = 0; $$.throwf = 0; @@ -6552,25 +6856,34 @@ exception_specification : THROW LPAREN parms RPAREN { } ; -cpp_const : type_qualifier { +qualifiers_exception_specification : cv_ref_qualifier { $$.throws = 0; $$.throwf = 0; $$.nexcept = 0; - $$.qualifier = $1; + $$.qualifier = $1.qualifier; + $$.refqualifier = $1.refqualifier; } | exception_specification { $$ = $1; $$.qualifier = 0; + $$.refqualifier = 0; } - | type_qualifier exception_specification { + | cv_ref_qualifier exception_specification { $$ = $2; - $$.qualifier = $1; + $$.qualifier = $1.qualifier; + $$.refqualifier = $1.refqualifier; + } + ; + +cpp_const : qualifiers_exception_specification { + $$ = $1; } | empty { $$.throws = 0; $$.throwf = 0; $$.nexcept = 0; - $$.qualifier = 0; + $$.qualifier = 0; + $$.refqualifier = 0; } ; @@ -6581,6 +6894,8 @@ ctor_end : cpp_const ctor_initializer SEMI { $$.throws = $1.throws; $$.throwf = $1.throwf; $$.nexcept = $1.nexcept; + if ($1.qualifier) + Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n"); } | cpp_const ctor_initializer LBRACE { skip_balanced('{','}'); @@ -6589,6 +6904,8 @@ ctor_end : cpp_const ctor_initializer SEMI { $$.throws = $1.throws; $$.throwf = $1.throwf; $$.nexcept = $1.nexcept; + if ($1.qualifier) + Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n"); } | LPAREN parms RPAREN SEMI { Clear(scanner_ccode); @@ -6621,6 +6938,8 @@ ctor_end : cpp_const ctor_initializer SEMI { $$.throws = $1.throws; $$.throwf = $1.throwf; $$.nexcept = $1.nexcept; + if ($1.qualifier) + Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n"); } ; diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h index 2d90001b2..c0921530f 100644 --- a/Source/Include/swigwarn.h +++ b/Source/Include/swigwarn.h @@ -153,6 +153,7 @@ #define WARN_TYPE_INCOMPLETE 402 #define WARN_TYPE_ABSTRACT 403 #define WARN_TYPE_REDEFINED 404 +#define WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405 #define WARN_TYPEMAP_SOURCETARGET 450 #define WARN_TYPEMAP_CHARLEAK 451 diff --git a/Source/Modules/allegrocl.cxx b/Source/Modules/allegrocl.cxx index 77f1319c7..f32d34976 100644 --- a/Source/Modules/allegrocl.cxx +++ b/Source/Modules/allegrocl.cxx @@ -1685,285 +1685,6 @@ int ALLEGROCL::top(Node *n) { return SWIG_OK; } -/* very shamelessly 'borrowed' from overload.cxx, which - keeps the below Swig_overload_rank() code to itself. - We don't need a dispatch function in the C++ wrapper - code; we want it over on the lisp side. */ - -#define Swig_overload_rank Allegrocl_swig_overload_rank - -#define MAX_OVERLOAD 256 - -/* Overload "argc" and "argv" */ -// String *argv_template_string; -// String *argc_template_string; - -struct Overloaded { - Node *n; /* Node */ - int argc; /* Argument count */ - ParmList *parms; /* Parameters used for overload check */ - int error; /* Ambiguity error */ -}; - -/* ----------------------------------------------------------------------------- - * Swig_overload_rank() - * - * This function takes an overloaded declaration and creates a list that ranks - * all overloaded methods in an order that can be used to generate a dispatch - * function. - * Slight difference in the way this function is used by scripting languages and - * statically typed languages. The script languages call this method via - * Swig_overload_dispatch() - where wrappers for all overloaded methods are generated, - * however sometimes the code can never be executed. The non-scripting languages - * call this method via Swig_overload_check() for each overloaded method in order - * to determine whether or not the method should be wrapped. Note the slight - * difference when overloading methods that differ by const only. The - * scripting languages will ignore the const method, whereas the non-scripting - * languages ignore the first method parsed. - * ----------------------------------------------------------------------------- */ - -static List *Swig_overload_rank(Node *n, bool script_lang_wrapping) { - Overloaded nodes[MAX_OVERLOAD]; - int nnodes = 0; - Node *o = Getattr(n, "sym:overloaded"); - Node *c; - - if (!o) - return 0; - - c = o; - while (c) { - if (Getattr(c, "error")) { - 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 */ - if (Getattr(c, "wrap:name")) { - nodes[nnodes].n = c; - nodes[nnodes].parms = Getattr(c, "wrap:parms"); - nodes[nnodes].argc = emit_num_required(nodes[nnodes].parms); - nodes[nnodes].error = 0; - nnodes++; - } - c = Getattr(c, "sym:nextSibling"); - } - - /* Sort the declarations by required argument count */ - { - int i, j; - for (i = 0; i < nnodes; i++) { - for (j = i + 1; j < nnodes; j++) { - if (nodes[i].argc > nodes[j].argc) { - Overloaded t = nodes[i]; - nodes[i] = nodes[j]; - nodes[j] = t; - } - } - } - } - - /* Sort the declarations by argument types */ - { - int i, j; - for (i = 0; i < nnodes - 1; i++) { - if (nodes[i].argc == nodes[i + 1].argc) { - for (j = i + 1; (j < nnodes) && (nodes[j].argc == nodes[i].argc); j++) { - Parm *p1 = nodes[i].parms; - Parm *p2 = nodes[j].parms; - int differ = 0; - int num_checked = 0; - while (p1 && p2 && (num_checked < nodes[i].argc)) { - // Printf(stdout,"p1 = '%s', p2 = '%s'\n", Getattr(p1,"type"), Getattr(p2,"type")); - if (checkAttribute(p1, "tmap:in:numinputs", "0")) { - p1 = Getattr(p1, "tmap:in:next"); - continue; - } - if (checkAttribute(p2, "tmap:in:numinputs", "0")) { - p2 = Getattr(p2, "tmap:in:next"); - continue; - } - String *t1 = Getattr(p1, "tmap:typecheck:precedence"); - String *t2 = Getattr(p2, "tmap:typecheck:precedence"); - if ((!t1) && (!nodes[i].error)) { - Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[i].n), Getline(nodes[i].n), - "Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n", - Swig_name_decl(nodes[i].n), SwigType_str(Getattr(p1, "type"), 0)); - nodes[i].error = 1; - } else if ((!t2) && (!nodes[j].error)) { - Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n", - Swig_name_decl(nodes[j].n), SwigType_str(Getattr(p2, "type"), 0)); - nodes[j].error = 1; - } - if (t1 && t2) { - int t1v, t2v; - t1v = atoi(Char(t1)); - t2v = atoi(Char(t2)); - differ = t1v - t2v; - } else if (!t1 && t2) - differ = 1; - else if (t1 && !t2) - differ = -1; - else if (!t1 && !t2) - differ = -1; - num_checked++; - if (differ > 0) { - Overloaded t = nodes[i]; - nodes[i] = nodes[j]; - nodes[j] = t; - break; - } else if ((differ == 0) && (Strcmp(t1, "0") == 0)) { - t1 = Getattr(p1, "ltype"); - if (!t1) { - t1 = SwigType_ltype(Getattr(p1, "type")); - if (Getattr(p1, "tmap:typecheck:SWIGTYPE")) { - SwigType_add_pointer(t1); - } - Setattr(p1, "ltype", t1); - } - t2 = Getattr(p2, "ltype"); - if (!t2) { - t2 = SwigType_ltype(Getattr(p2, "type")); - if (Getattr(p2, "tmap:typecheck:SWIGTYPE")) { - SwigType_add_pointer(t2); - } - Setattr(p2, "ltype", t2); - } - - /* Need subtype check here. If t2 is a subtype of t1, then we need to change the - order */ - - if (SwigType_issubtype(t2, t1)) { - Overloaded t = nodes[i]; - nodes[i] = nodes[j]; - nodes[j] = t; - } - - if (Strcmp(t1, t2) != 0) { - differ = 1; - break; - } - } else if (differ) { - break; - } - if (Getattr(p1, "tmap:in:next")) { - p1 = Getattr(p1, "tmap:in:next"); - } else { - p1 = nextSibling(p1); - } - if (Getattr(p2, "tmap:in:next")) { - p2 = Getattr(p2, "tmap:in:next"); - } else { - p2 = nextSibling(p2); - } - } - if (!differ) { - /* See if declarations differ by const only */ - String *d1 = Getattr(nodes[i].n, "decl"); - String *d2 = Getattr(nodes[j].n, "decl"); - if (d1 && d2) { - String *dq1 = Copy(d1); - String *dq2 = Copy(d2); - if (SwigType_isconst(d1)) { - Delete(SwigType_pop(dq1)); - } - if (SwigType_isconst(d2)) { - Delete(SwigType_pop(dq2)); - } - if (Strcmp(dq1, dq2) == 0) { - - if (SwigType_isconst(d1) && !SwigType_isconst(d2)) { - if (script_lang_wrapping) { - // Swap nodes so that the const method gets ignored (shadowed by the non-const method) - Overloaded t = nodes[i]; - nodes[i] = nodes[j]; - nodes[j] = t; - } - differ = 1; - if (!nodes[j].error) { - if (script_lang_wrapping) { - Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n), - "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n)); - } else { - if (!Getattr(nodes[j].n, "overload:ignore")) { - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), - "using %s instead.\n", Swig_name_decl(nodes[i].n)); - } - } - } - nodes[j].error = 1; - } else if (!SwigType_isconst(d1) && SwigType_isconst(d2)) { - differ = 1; - if (!nodes[j].error) { - if (script_lang_wrapping) { - Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n), - "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n)); - } else { - if (!Getattr(nodes[j].n, "overload:ignore")) { - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), - "using %s instead.\n", Swig_name_decl(nodes[i].n)); - } - } - } - nodes[j].error = 1; - } - } - Delete(dq1); - Delete(dq2); - } - } - if (!differ) { - if (!nodes[j].error) { - if (script_lang_wrapping) { - Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s effectively ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[i].n), Getline(nodes[i].n), - "as it is shadowed by %s.\n", Swig_name_decl(nodes[i].n)); - } else { - if (!Getattr(nodes[j].n, "overload:ignore")) { - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), - "using %s instead.\n", Swig_name_decl(nodes[i].n)); - } - } - nodes[j].error = 1; - } - } - } - } - } - } - List *result = NewList(); - { - int i; - for (i = 0; i < nnodes; i++) { - if (nodes[i].error) - Setattr(nodes[i].n, "overload:ignore", "1"); - Append(result, nodes[i].n); - // Printf(stdout,"[ %d ] %s\n", i, ParmList_errorstr(nodes[i].parms)); - // Swig_print_node(nodes[i].n); - } - } - return result; -} - -/* end shameless borrowing */ - int any_varargs(ParmList *pl) { Parm *p; diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index 423c5a451..7b1fca071 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -2207,37 +2207,6 @@ public: --nesting_depth; } - /* Output the downcast method, if necessary. Note: There's no other really - good place to put this code, since Abstract Base Classes (ABCs) can and should have - downcasts, making the constructorHandler() a bad place (because ABCs don't get to - have constructors emitted.) */ - if (GetFlag(n, "feature:csdowncast")) { - String *downcast_method = Swig_name_member(getNSpace(), proxy_class_name, "SWIGDowncast"); - String *wname = Swig_name_wrapper(downcast_method); - - String *norm_name = SwigType_namestr(Getattr(n, "name")); - - Printf(imclass_class_code, " public final static native %s %s(long cPtrBase, boolean cMemoryOwn);\n", proxy_class_name, downcast_method); - - Wrapper *dcast_wrap = NewWrapper(); - - Printf(dcast_wrap->def, "SWIGEXPORT jobject SWIGSTDCALL %s(JNIEnv *jenv, jclass jcls, jlong jCPtrBase, jboolean cMemoryOwn) {", wname); - Printf(dcast_wrap->code, " Swig::Director *director = (Swig::Director *) 0;\n"); - Printf(dcast_wrap->code, " jobject jresult = (jobject) 0;\n"); - Printf(dcast_wrap->code, " %s *obj = *((%s **)&jCPtrBase);\n", norm_name, norm_name); - Printf(dcast_wrap->code, " if (obj) director = dynamic_cast(obj);\n"); - Printf(dcast_wrap->code, " if (director) jresult = director->swig_get_self(jenv);\n"); - Printf(dcast_wrap->code, " return jresult;\n"); - Printf(dcast_wrap->code, "}\n"); - - Wrapper_print(dcast_wrap, f_wrappers); - DelWrapper(dcast_wrap); - - Delete(norm_name); - Delete(wname); - Delete(downcast_method); - } - if (f_interface) { Printv(f_interface, interface_class_code, "}\n", NIL); addCloseNamespace(nspace, f_interface); @@ -3734,16 +3703,13 @@ public: Printf(code_wrap->code, " %s *obj = (%s *)objarg;\n", smartptr, smartptr); Printf(code_wrap->code, " // Keep a local instance of the smart pointer around while we are using the raw pointer\n"); Printf(code_wrap->code, " // Avoids using smart pointer specific API.\n"); - Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName); - } - else { + Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName); + } else { Printf(code_wrap->code, " %s *obj = (%s *)objarg;\n", norm_name, norm_name); - Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj);\n", dirClassName, dirClassName); + Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj);\n", dirClassName, dirClassName); } - // TODO: if statement not needed?? - Java too - Printf(code_wrap->code, " if (director) {\n"); - Printf(code_wrap->code, " director->swig_connect_director("); + Printf(code_wrap->code, " director->swig_connect_director("); for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) { UpcallData *udata = Getitem(dmethods_seq, i); @@ -3760,7 +3726,6 @@ public: Printf(code_wrap->def, ") {\n"); Printf(code_wrap->code, ");\n"); Printf(imclass_class_code, ");\n"); - Printf(code_wrap->code, " }\n"); Printf(code_wrap->code, "}\n"); Wrapper_print(code_wrap, f_wrappers); @@ -3826,7 +3791,7 @@ public: qualified_return = SwigType_rcaststr(returntype, "c_result"); - if (!is_void && !ignored_method) { + if (!is_void && (!ignored_method || pure_virtual)) { if (!SwigType_isclass(returntype)) { if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); @@ -3935,7 +3900,11 @@ public: } Delete(super_call); } else { - Printf(w->code, " throw Swig::DirectorPureVirtualException(\"%s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name)); + Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"%s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name)); + if (!is_void) + Printf(w->code, "return %s;", qualified_return); + else if (!ignored_method) + Printf(w->code, "return;\n"); } if (!ignored_method) @@ -4102,6 +4071,10 @@ public: Delete(target); // Add any exception specifications to the methods in the director class + if (Getattr(n, "noexcept")) { + Append(w->def, " noexcept"); + Append(declaration, " noexcept"); + } ParmList *throw_parm_list = NULL; if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { int gencomma = 0; @@ -4419,7 +4392,10 @@ public: String *dirclassname = directorClassName(current_class); Wrapper *w = NewWrapper(); - if (Getattr(n, "throw")) { + if (Getattr(n, "noexcept")) { + Printf(f_directors_h, " virtual ~%s() noexcept;\n", dirclassname); + Printf(w->def, "%s::~%s() noexcept {\n", dirclassname, dirclassname); + } else if (Getattr(n, "throw")) { Printf(f_directors_h, " virtual ~%s() throw ();\n", dirclassname); Printf(w->def, "%s::~%s() throw () {\n", dirclassname, dirclassname); } else { diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx index de7afdab1..9a64543c3 100644 --- a/Source/Modules/d.cxx +++ b/Source/Modules/d.cxx @@ -1975,7 +1975,7 @@ public: qualified_return = SwigType_rcaststr(returntype, "c_result"); - if (!is_void && !ignored_method) { + if (!is_void && (!ignored_method || pure_virtual)) { if (!SwigType_isclass(returntype)) { if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); @@ -2077,7 +2077,11 @@ public: } Delete(super_call); } else { - Printf(w->code, " throw Swig::DirectorPureVirtualException(\"%s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name)); + Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"%s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name)); + if (!is_void) + Printf(w->code, "return %s;", qualified_return); + else if (!ignored_method) + Printf(w->code, "return;\n"); } if (!ignored_method) @@ -2217,6 +2221,10 @@ public: Delete(target); // Add any exception specifications to the methods in the director class + if (Getattr(n, "noexcept")) { + Append(w->def, " noexcept"); + Append(declaration, " noexcept"); + } ParmList *throw_parm_list = NULL; if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { int gencomma = 0; @@ -2483,7 +2491,10 @@ public: String *dirclassname = directorClassName(current_class); Wrapper *w = NewWrapper(); - if (Getattr(n, "throw")) { + if (Getattr(n, "noexcept")) { + Printf(f_directors_h, " virtual ~%s() noexcept;\n", dirclassname); + Printf(w->def, "%s::~%s() noexcept {\n", dirclassname, dirclassname); + } else if (Getattr(n, "throw")) { Printf(f_directors_h, " virtual ~%s() throw ();\n", dirclassname); Printf(w->def, "%s::~%s() throw () {\n", dirclassname, dirclassname); } else { @@ -3556,10 +3567,9 @@ private: Printf(code_wrap->def, "SWIGEXPORT void D_%s(void *objarg, void *dobj", connect_name); Printf(code_wrap->code, " %s *obj = (%s *)objarg;\n", norm_name, norm_name); - Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj);\n", dirClassName, dirClassName); + Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj);\n", dirClassName, dirClassName); - Printf(code_wrap->code, " if (director) {\n"); - Printf(code_wrap->code, " director->swig_connect_director(dobj"); + Printf(code_wrap->code, " director->swig_connect_director(dobj"); for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) { UpcallData *udata = Getitem(dmethods_seq, i); @@ -3573,7 +3583,6 @@ private: Printf(code_wrap->def, ") {\n"); Printf(code_wrap->code, ");\n"); Printf(im_dmodule_code, ") %s;\n", connect_name); - Printf(code_wrap->code, " }\n"); Printf(code_wrap->code, "}\n"); Wrapper_print(code_wrap, f_wrappers); diff --git a/Source/Modules/emit.cxx b/Source/Modules/emit.cxx index 7c2607fc8..813a30924 100644 --- a/Source/Modules/emit.cxx +++ b/Source/Modules/emit.cxx @@ -454,7 +454,7 @@ String *emit_action(Node *n) { if (catchlist) { int unknown_catch = 0; int has_varargs = 0; - Printf(eaction, "}\n"); + Printf(eaction, "} "); for (Parm *ep = catchlist; ep; ep = nextSibling(ep)) { String *em = Swig_typemap_lookup("throws", ep, "_e", 0); if (em) { diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx index 884ae906d..916030437 100644 --- a/Source/Modules/go.cxx +++ b/Source/Modules/go.cxx @@ -990,7 +990,7 @@ private: * overname: The overload string for overloaded function. * wname: The SWIG wrapped name--the name of the C function. * base: A list of the names of base classes, in the case where this - * is is a vritual method not defined in the current class. + * is a virtual method not defined in the current class. * parms: The parameters. * result: The result type. * is_static: Whether this is a static method or member. @@ -2806,17 +2806,25 @@ private: return SWIG_NOWRAP; } - String *get = NewString(""); - Printv(get, Swig_cresult_name(), " = ", NULL); - String *rawval = Getattr(n, "rawval"); if (rawval && Len(rawval)) { - if (SwigType_type(type) == T_STRING) { - Printv(get, "(char *)", NULL); + // Based on Swig_VargetToFunction + String *nname = NewStringf("(%s)", rawval); + String *call; + if (SwigType_isclass(type)) { + call = NewStringf("%s", nname); + } else { + call = SwigType_lcaststr(type, nname); } - - Printv(get, rawval, NULL); + String *cres = Swig_cresult(type, Swig_cresult_name(), call); + Setattr(n, "wrap:action", cres); + Delete(nname); + Delete(call); + Delete(cres); } else { + String *get = NewString(""); + Printv(get, Swig_cresult_name(), " = ", NULL); + char quote; if (Getattr(n, "wrappedasconstant")) { quote = '\0'; @@ -2838,12 +2846,13 @@ private: if (quote != '\0') { Printf(get, "%c", quote); } + + Printv(get, ";\n", NULL); + + Setattr(n, "wrap:action", get); + Delete(get); } - Printv(get, ";\n", NULL); - - Setattr(n, "wrap:action", get); - String *sname = Copy(symname); if (class_name) { Append(sname, "_"); @@ -5049,7 +5058,19 @@ private: Printv(w->def, " {\n", NULL); if (SwigType_type(result) != T_VOID) { - Wrapper_add_local(w, "c_result", SwigType_lstr(result, "c_result")); + if (!SwigType_isclass(result)) { + if (!(SwigType_ispointer(result) || SwigType_isreference(result))) { + String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(result, 0)); + Wrapper_add_localv(w, "c_result", SwigType_lstr(result, "c_result"), construct_result, NIL); + Delete(construct_result); + } else { + Wrapper_add_localv(w, "c_result", SwigType_lstr(result, "c_result"), "= 0", NIL); + } + } else { + String *cres = SwigType_lstr(result, "c_result"); + Printf(w->code, "%s;\n", cres); + Delete(cres); + } } if (!is_ignored) { @@ -5483,6 +5504,8 @@ private: *--------------------------------------------------------------------*/ String *buildThrow(Node *n) { + if (Getattr(n, "noexcept")) + return NewString("noexcept"); ParmList *throw_parm_list = Getattr(n, "throws"); if (!throw_parm_list && !Getattr(n, "throw")) return NULL; @@ -6232,9 +6255,9 @@ private: Setattr(undefined_enum_types, t, ret); Delete(tt); } - } else if (SwigType_isfunctionpointer(type) || SwigType_isfunction(type)) { + } else if (SwigType_isfunctionpointer(t) || SwigType_isfunction(t)) { ret = NewString("_swig_fnptr"); - } else if (SwigType_ismemberpointer(type)) { + } else if (SwigType_ismemberpointer(t)) { ret = NewString("_swig_memberptr"); } else if (SwigType_issimple(t)) { Node *cn = classLookup(t); diff --git a/Source/Modules/interface.cxx b/Source/Modules/interface.cxx index f6d4c955b..fee6cd7da 100644 --- a/Source/Modules/interface.cxx +++ b/Source/Modules/interface.cxx @@ -151,12 +151,14 @@ void Swig_interface_propagate_methods(Node *n) { for (Node *child = firstChild(n); child; child = nextSibling(child)) { if (Getattr(child, "interface:owner")) break; // at the end of the list are newly appended methods - if (checkAttribute(child, "name", name)) { - String *decl = SwigType_typedef_resolve_all(Getattr(child, "decl")); - identically_overloaded_method = Strcmp(decl, this_decl_resolved) == 0; - Delete(decl); - if (identically_overloaded_method) - break; + if (Cmp(nodeType(child), "cdecl") == 0) { + if (checkAttribute(child, "name", name)) { + String *decl = SwigType_typedef_resolve_all(Getattr(child, "decl")); + identically_overloaded_method = Strcmp(decl, this_decl_resolved) == 0; + Delete(decl); + if (identically_overloaded_method) + break; + } } } } diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index 6d0c554cb..beb015d89 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -2379,39 +2379,6 @@ public: --nesting_depth; } - /* Output the downcast method, if necessary. Note: There's no other really - good place to put this code, since Abstract Base Classes (ABCs) can and should have - downcasts, making the constructorHandler() a bad place (because ABCs don't get to - have constructors emitted.) */ - if (GetFlag(n, "feature:javadowncast")) { - String *downcast_method = Swig_name_member(getNSpace(), getClassPrefix(), "SWIGDowncast"); - String *jniname = makeValidJniName(downcast_method); - String *wname = Swig_name_wrapper(jniname); - - String *norm_name = SwigType_namestr(Getattr(n, "name")); - - Printf(imclass_class_code, " public final static native %s %s(long cPtrBase, boolean cMemoryOwn);\n", proxy_class_name, downcast_method); - - Wrapper *dcast_wrap = NewWrapper(); - - Printf(dcast_wrap->def, "SWIGEXPORT jobject JNICALL %s(JNIEnv *jenv, jclass jcls, jlong jCPtrBase, jboolean cMemoryOwn) {", wname); - Printf(dcast_wrap->code, " Swig::Director *director = (Swig::Director *) 0;\n"); - Printf(dcast_wrap->code, " jobject jresult = (jobject) 0;\n"); - Printf(dcast_wrap->code, " %s *obj = *((%s **)&jCPtrBase);\n", norm_name, norm_name); - Printf(dcast_wrap->code, " if (obj) director = dynamic_cast(obj);\n"); - Printf(dcast_wrap->code, " if (director) jresult = director->swig_get_self(jenv);\n"); - Printf(dcast_wrap->code, " return jresult;\n"); - Printf(dcast_wrap->code, "}\n"); - - Wrapper_print(dcast_wrap, f_wrappers); - DelWrapper(dcast_wrap); - - Delete(norm_name); - Delete(wname); - Delete(jniname); - Delete(downcast_method); - } - if (f_interface) { Printv(f_interface, interface_class_code, "}\n", NIL); Delete(f_interface); @@ -3895,18 +3862,16 @@ public: Printf(code_wrap->code, " (void)jcls;\n"); Printf(code_wrap->code, " // Keep a local instance of the smart pointer around while we are using the raw pointer\n"); Printf(code_wrap->code, " // Avoids using smart pointer specific API.\n"); - Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName); + Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName); } else { Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", norm_name, norm_name); Printf(code_wrap->code, " (void)jcls;\n"); - Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj);\n", dirClassName, dirClassName); + Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj);\n", dirClassName, dirClassName); } - Printf(code_wrap->code, " if (director) {\n"); - Printf(code_wrap->code, " director->swig_connect_director(jenv, jself, jenv->GetObjectClass(jself), " + Printf(code_wrap->code, " director->swig_connect_director(jenv, jself, jenv->GetObjectClass(jself), " "(jswig_mem_own == JNI_TRUE), (jweak_global == JNI_TRUE));\n"); - Printf(code_wrap->code, " }\n"); Printf(code_wrap->code, "}\n"); Wrapper_print(code_wrap, f_wrappers); @@ -3925,12 +3890,20 @@ public: Printf(code_wrap->def, "SWIGEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jtake_or_release) {\n", jnipackage, jni_imclass_name, changeown_jnimethod_name); - Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", norm_name, norm_name); - Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj);\n", dirClassName, dirClassName); + + if (Len(smartptr)) { + Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", smartptr, smartptr); + Printf(code_wrap->code, " // Keep a local instance of the smart pointer around while we are using the raw pointer\n"); + Printf(code_wrap->code, " // Avoids using smart pointer specific API.\n"); + Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName); + } + else { + Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", norm_name, norm_name); + Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj);\n", dirClassName, dirClassName); + } + Printf(code_wrap->code, " (void)jcls;\n"); - Printf(code_wrap->code, " if (director) {\n"); - Printf(code_wrap->code, " director->swig_java_change_ownership(jenv, jself, jtake_or_release ? true : false);\n"); - Printf(code_wrap->code, " }\n"); + Printf(code_wrap->code, " director->swig_java_change_ownership(jenv, jself, jtake_or_release ? true : false);\n"); Printf(code_wrap->code, "}\n"); Wrapper_print(code_wrap, f_wrappers); @@ -4428,6 +4401,10 @@ public: } } + if (Getattr(n, "noexcept")) { + Append(w->def, " noexcept"); + Append(declaration, " noexcept"); + } if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { int gencomma = 0; @@ -4621,7 +4598,7 @@ public: Printf(directorexcept, "jthrowable $error = jenv->ExceptionOccurred();\n"); Printf(directorexcept, "if ($error) {\n"); Printf(directorexcept, " jenv->ExceptionClear();$directorthrowshandlers\n"); - Printf(directorexcept, " throw Swig::DirectorException(jenv, $error);\n"); + Printf(directorexcept, " Swig::DirectorException::raise(jenv, $error);\n"); Printf(directorexcept, "}\n"); } else { directorexcept = Copy(directorexcept); @@ -4806,7 +4783,10 @@ public: String *dirClassName = directorClassName(current_class); Wrapper *w = NewWrapper(); - if (Getattr(n, "throw")) { + if (Getattr(n, "noexcept")) { + Printf(f_directors_h, " virtual ~%s() noexcept;\n", dirClassName); + Printf(w->def, "%s::~%s() noexcept {\n", dirClassName, dirClassName); + } else if (Getattr(n, "throw")) { Printf(f_directors_h, " virtual ~%s() throw ();\n", dirClassName); Printf(w->def, "%s::~%s() throw () {\n", dirClassName, dirClassName); } else { diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 4e7a7912f..490ee7fd3 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -462,10 +462,10 @@ int JAVASCRIPT::fragmentDirective(Node *n) { // and register them at the emitter. String *section = Getattr(n, "section"); - if (Equal(section, "templates")) { + if (Equal(section, "templates") && !ImportMode) { emitter->registerTemplate(Getattr(n, "value"), Getattr(n, "code")); } else { - Swig_fragment_register(n); + return Language::fragmentDirective(n); } return SWIG_OK; diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 21ea79163..7e55162b0 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -81,7 +81,6 @@ extern int AddExtern; /* import modes */ #define IMPORT_MODE 1 -#define IMPORT_MODULE 2 /* ---------------------------------------------------------------------- * Dispatcher::emit_one() @@ -628,7 +627,8 @@ int Language::constantDirective(Node *n) { * ---------------------------------------------------------------------- */ int Language::fragmentDirective(Node *n) { - Swig_fragment_register(n); + if (!(Getattr(n, "emitonly") && ImportMode)) + Swig_fragment_register(n); return SWIG_OK; } @@ -1952,7 +1952,7 @@ int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_ generation of 'empty' director classes. But this has to be done outside the previous 'for' - an the recursive loop!. + and the recursive loop!. */ if (n == parent) { int len = Len(vm); @@ -2081,7 +2081,7 @@ int Language::classDirectorConstructors(Node *n) { needed, since there is a public constructor already defined. (scottm) This code is needed here to make the director_abstract + - test generate compilable code (Example2 in director_abastract.i). + test generate compilable code (Example2 in director_abstract.i). (mmatus) This is very strange, since swig compiled with gcc3.2.3 doesn't need it here.... @@ -3325,7 +3325,7 @@ Node *Language::classLookup(const SwigType *s) { } if (n) { /* Found a match. Look at the prefix. We only allow - the cases where where we want a proxy class for the particular type */ + the cases where we want a proxy class for the particular type */ bool acceptable_prefix = (Len(prefix) == 0) || // simple type (pass by value) (Strcmp(prefix, "p.") == 0) || // pointer diff --git a/Source/Modules/lua.cxx b/Source/Modules/lua.cxx index 80ea47f3f..08de34976 100644 --- a/Source/Modules/lua.cxx +++ b/Source/Modules/lua.cxx @@ -1755,7 +1755,7 @@ public: * * This is to convert the string of Lua code into a proper string, which can then be * emitted into the C/C++ code. - * Basically is is a lot of search & replacing of odd sequences + * Basically it is a lot of search & replacing of odd sequences * ---------------------------------------------------------------------------- */ void escapeCode(String *str) { @@ -1770,7 +1770,7 @@ public: /* ----------------------------------------------------------------------------- * rawGetCArraysHash(String *name) * - * A small helper to hide impelementation of how CArrays hashes are stored + * A small helper to hide implementation of how CArrays hashes are stored * ---------------------------------------------------------------------------- */ Hash *rawGetCArraysHash(const_String_or_char_ptr name) { diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx index 12b83b2e4..9822b6af7 100644 --- a/Source/Modules/main.cxx +++ b/Source/Modules/main.cxx @@ -38,14 +38,15 @@ int NoExcept = 0; int SwigRuntime = 0; // 0 = no option, 1 = -runtime, 2 = -noruntime /* Suppress warning messages for private inheritance, preprocessor evaluation etc... - WARN_PP_EVALUATION 202 - WARN_PARSE_PRIVATE_INHERIT 309 - WARN_TYPE_ABSTRACT 403 - WARN_LANG_OVERLOAD_CONST 512 - WARN_PARSE_BUILTIN_NAME 321 - WARN_PARSE_REDUNDANT 322 + WARN_PP_EVALUATION 202 + WARN_PARSE_PRIVATE_INHERIT 309 + WARN_PARSE_BUILTIN_NAME 321 + WARN_PARSE_REDUNDANT 322 + WARN_TYPE_ABSTRACT 403 + WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405 + WARN_LANG_OVERLOAD_CONST 512 */ -#define EXTRA_WARNINGS "202,309,403,512,321,322" +#define EXTRA_WARNINGS "202,309,403,405,512,321,322" extern "C" { extern String *ModuleName; diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx index 73dd14f96..15a13f5ec 100644 --- a/Source/Modules/ocaml.cxx +++ b/Source/Modules/ocaml.cxx @@ -1429,9 +1429,19 @@ public: * if the return value is a reference or const reference, a specialized typemap must * handle it, including declaration of c_result ($result). */ - if (!is_void) { - if (!(ignored_method && !pure_virtual)) { - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), NIL); + if (!is_void && (!ignored_method || pure_virtual)) { + if (!SwigType_isclass(returntype)) { + if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { + String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); + Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL); + Delete(construct_result); + } else { + Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL); + } + } else { + String *cres = SwigType_lstr(returntype, "c_result"); + Printf(w->code, "%s;\n", cres); + Delete(cres); } } diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx index b977609a8..e64a0779f 100644 --- a/Source/Modules/octave.cxx +++ b/Source/Modules/octave.cxx @@ -1321,6 +1321,10 @@ public: Delete(target); // Get any exception classes in the throws typemap + if (Getattr(n, "noexcept")) { + Append(w->def, " noexcept"); + Append(declaration, " noexcept"); + } ParmList *throw_parm_list = 0; if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { @@ -1355,11 +1359,19 @@ public: // declare method return value // if the return value is a reference or const reference, a specialized typemap must // handle it, including declaration of c_result ($result). - if (!is_void) { - if (!(ignored_method && !pure_virtual)) { - String *cres = SwigType_lstr(returntype, "c_result"); - Printf(w->code, "%s;\n", cres); - Delete(cres); + if (!is_void && (!ignored_method || pure_virtual)) { + if (!SwigType_isclass(returntype)) { + if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { + String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); + Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL); + Delete(construct_result); + } else { + Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL); + } + } else { + String *cres = SwigType_lstr(returntype, "c_result"); + Printf(w->code, "%s;\n", cres); + Delete(cres); } } diff --git a/Source/Modules/overload.cxx b/Source/Modules/overload.cxx index 330294efd..81d1bb000 100644 --- a/Source/Modules/overload.cxx +++ b/Source/Modules/overload.cxx @@ -231,9 +231,21 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) { } if (!differ) { /* See if declarations differ by const only */ - String *d1 = Getattr(nodes[i].n, "decl"); - String *d2 = Getattr(nodes[j].n, "decl"); - if (d1 && d2) { + String *decl1 = Getattr(nodes[i].n, "decl"); + String *decl2 = Getattr(nodes[j].n, "decl"); + if (decl1 && decl2) { + /* Remove ref-qualifiers. Note that rvalue ref-qualifiers are already ignored and + * it is illegal to overload a function with and without ref-qualifiers. So with + * all the combinations of ref-qualifiers and cv-qualifiers, we just detect + * the cv-qualifier (const) overloading. */ + String *d1 = Copy(decl1); + String *d2 = Copy(decl2); + if (SwigType_isreference(d1) || SwigType_isrvalue_reference(d1)) { + Delete(SwigType_pop(d1)); + } + if (SwigType_isreference(d2) || SwigType_isrvalue_reference(d2)) { + Delete(SwigType_pop(d2)); + } String *dq1 = Copy(d1); String *dq2 = Copy(d2); if (SwigType_isconst(d1)) { diff --git a/Source/Modules/perl5.cxx b/Source/Modules/perl5.cxx index 406568b16..e46761028 100644 --- a/Source/Modules/perl5.cxx +++ b/Source/Modules/perl5.cxx @@ -2090,6 +2090,10 @@ public: Delete(target); // Get any exception classes in the throws typemap + if (Getattr(n, "noexcept")) { + Append(w->def, " noexcept"); + Append(declaration, " noexcept"); + } ParmList *throw_parm_list = 0; if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { @@ -2126,10 +2130,20 @@ public: * handle it, including declaration of c_result ($result). */ if (!is_void) { - if (!(ignored_method && !pure_virtual)) { - String *cres = SwigType_lstr(returntype, "c_result"); - Printf(w->code, "%s;\n", cres); - Delete(cres); + if (!ignored_method || pure_virtual) { + if (!SwigType_isclass(returntype)) { + if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { + String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); + Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL); + Delete(construct_result); + } else { + Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL); + } + } else { + String *cres = SwigType_lstr(returntype, "c_result"); + Printf(w->code, "%s;\n", cres); + Delete(cres); + } } if (!ignored_method) { String *pres = NewStringf("SV *%s", Swig_cresult_name()); @@ -2486,7 +2500,10 @@ public: Delete(mangle); Delete(ptype); - if (Getattr(n, "throw")) { + if (Getattr(n, "noexcept")) { + Printf(f_directors_h, " virtual ~%s() noexcept;\n", DirectorClassName); + Printf(f_directors, "%s::~%s() noexcept {%s}\n\n", DirectorClassName, DirectorClassName, body); + } else if (Getattr(n, "throw")) { Printf(f_directors_h, " virtual ~%s() throw ();\n", DirectorClassName); Printf(f_directors, "%s::~%s() throw () {%s}\n\n", DirectorClassName, DirectorClassName, body); } else { diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 295039ba1..061dc0c22 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -96,6 +96,7 @@ static String *all_cs_entry; static String *pragma_incl; static String *pragma_code; static String *pragma_phpinfo; +static String *pragma_version; static String *s_oowrappers; static String *s_fakeoowrappers; static String *s_phpclasses; @@ -359,6 +360,7 @@ public: /* sub-sections of the php file */ pragma_code = NewStringEmpty(); pragma_incl = NewStringEmpty(); + pragma_version = NULL; /* Initialize the rest of the module */ @@ -515,7 +517,11 @@ public: } else { Printf(s_init, " NULL, /* No MINFO code */\n"); } - Printf(s_init, " NO_VERSION_YET,\n"); + if (Len(pragma_version) > 0) { + Printf(s_init, " \"%s\",\n", pragma_version); + } else { + Printf(s_init, " NO_VERSION_YET,\n"); + } Printf(s_init, " STANDARD_MODULE_PROPERTIES\n"); Printf(s_init, "};\n"); Printf(s_init, "zend_module_entry* SWIG_module_entry = &%s_module_entry;\n\n", module); @@ -1835,7 +1841,7 @@ public: Delete(wrapobj); } } else { - if (non_void_return) { + if (non_void_return || hasargout) { Printf(output, "\t\treturn %s;\n", invoke); } else if (Cmp(invoke, "$r") != 0) { Printf(output, "\t\t%s;\n", invoke); @@ -2007,6 +2013,10 @@ done: if (value) { Printf(pragma_phpinfo, "%s\n", value); } + } else if (Strcmp(type, "version") == 0) { + if (value) { + pragma_version = value; + } } else { Swig_warning(WARN_PHP_UNKNOWN_PRAGMA, input_file, line_number, "Unrecognized pragma <%s>.\n", type); } @@ -2530,6 +2540,10 @@ done: Delete(target); // Get any exception classes in the throws typemap + if (Getattr(n, "noexcept")) { + Append(w->def, " noexcept"); + Append(declaration, " noexcept"); + } ParmList *throw_parm_list = 0; if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { @@ -2565,8 +2579,16 @@ done: * if the return value is a reference or const reference, a specialized typemap must * handle it, including declaration of c_result ($result). */ - if (!is_void) { - if (!(ignored_method && !pure_virtual)) { + if (!is_void && (!ignored_method || pure_virtual)) { + if (!SwigType_isclass(returntype)) { + if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { + String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); + Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL); + Delete(construct_result); + } else { + Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL); + } + } else { String *cres = SwigType_lstr(returntype, "c_result"); Printf(w->code, "%s;\n", cres); Delete(cres); diff --git a/Source/Modules/php5.cxx b/Source/Modules/php5.cxx index bf3ce4fa4..2fa76493e 100644 --- a/Source/Modules/php5.cxx +++ b/Source/Modules/php5.cxx @@ -96,6 +96,7 @@ static String *all_cs_entry; static String *pragma_incl; static String *pragma_code; static String *pragma_phpinfo; +static String *pragma_version; static String *s_oowrappers; static String *s_fakeoowrappers; static String *s_phpclasses; @@ -294,7 +295,7 @@ public: f_runtime = NewStringEmpty(); /* sections of the output file */ - s_init = NewString("/* init section */\n"); + s_init = NewStringEmpty(); r_init = NewString("/* rinit section */\n"); s_shutdown = NewString("/* shutdown section */\n"); r_shutdown = NewString("/* rshutdown section */\n"); @@ -391,6 +392,7 @@ public: /* sub-sections of the php file */ pragma_code = NewStringEmpty(); pragma_incl = NewStringEmpty(); + pragma_version = NULL; /* Initialize the rest of the module */ @@ -528,7 +530,14 @@ public: Printf(s_entry, "/* Every non-class user visible function must have an entry here */\n"); Printf(s_entry, "static zend_function_entry %s_functions[] = {\n", module); + /* Emit all of the code */ + Language::top(n); + + SwigPHP_emit_resource_registrations(); + /* start the init section */ + String * s_init_old = s_init; + s_init = NewString("/* init section */\n"); Append(s_init, "#if ZEND_MODULE_API_NO <= 20090626\n"); Append(s_init, "#undef ZEND_MODULE_BUILD_ID\n"); Append(s_init, "#define ZEND_MODULE_BUILD_ID (char*)\"API\" ZEND_TOSTR(ZEND_MODULE_API_NO) ZEND_BUILD_TS ZEND_BUILD_DEBUG ZEND_BUILD_SYSTEM ZEND_BUILD_EXTRA\n"); @@ -542,7 +551,11 @@ public: Printf(s_init, " PHP_RINIT(%s),\n", module); Printf(s_init, " PHP_RSHUTDOWN(%s),\n", module); Printf(s_init, " PHP_MINFO(%s),\n", module); - Printf(s_init, " NO_VERSION_YET,\n"); + if (Len(pragma_version) > 0) { + Printf(s_init, " \"%s\",\n", pragma_version); + } else { + Printf(s_init, " NO_VERSION_YET,\n"); + } Printf(s_init, " STANDARD_MODULE_PROPERTIES\n"); Printf(s_init, "};\n"); Printf(s_init, "zend_module_entry* SWIG_module_entry = &%s_module_entry;\n\n", module); @@ -562,11 +575,9 @@ public: * things are being called in the wrong order */ Printf(s_init, "#define SWIG_php_minit PHP_MINIT_FUNCTION(%s)\n", module); + Printv(s_init, s_init_old, NIL); + Delete(s_init_old); - /* Emit all of the code */ - Language::top(n); - - SwigPHP_emit_resource_registrations(); // Printv(s_init,s_resourcetypes,NIL); /* We need this after all classes written out by ::top */ Printf(s_oinit, "CG(active_class_entry) = NULL;\n"); @@ -1816,7 +1827,7 @@ public: Delete(wrapobj); } } else { - if (non_void_return) { + if (non_void_return || hasargout) { Printf(output, "\t\treturn %s;\n", invoke); } else if (Cmp(invoke, "$r") != 0) { Printf(output, "\t\t%s;\n", invoke); @@ -1988,6 +1999,10 @@ done: if (value) { Printf(pragma_phpinfo, "%s\n", value); } + } else if (Strcmp(type, "version") == 0) { + if (value) { + pragma_version = value; + } } else { Swig_warning(WARN_PHP_UNKNOWN_PRAGMA, input_file, line_number, "Unrecognized pragma <%s>.\n", type); } @@ -2525,6 +2540,10 @@ done: Delete(target); // Get any exception classes in the throws typemap + if (Getattr(n, "noexcept")) { + Append(w->def, " noexcept"); + Append(declaration, " noexcept"); + } ParmList *throw_parm_list = 0; if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { @@ -2562,8 +2581,16 @@ done: * if the return value is a reference or const reference, a specialized typemap must * handle it, including declaration of c_result ($result). */ - if (!is_void) { - if (!(ignored_method && !pure_virtual)) { + if (!is_void && (!ignored_method || pure_virtual)) { + if (!SwigType_isclass(returntype)) { + if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { + String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); + Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL); + Delete(construct_result); + } else { + Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL); + } + } else { String *cres = SwigType_lstr(returntype, "c_result"); Printf(w->code, "%s;\n", cres); Delete(cres); diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 905f02213..5805fe575 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -183,7 +183,7 @@ static String *getSlot(Node *n = NULL, const char *key = NULL, String *default_s static void printSlot(File *f, String *slotval, const char *slotname, const char *functype = NULL) { String *slotval_override = 0; - if (functype) + if (functype && Strcmp(slotval, "0") == 0) slotval = slotval_override = NewStringf("(%s) %s", functype, slotval); int len = Len(slotval); int fieldwidth = len > 41 ? (len > 61 ? 0 : 61 - len) : 41 - len; @@ -1946,6 +1946,7 @@ public: String *new_value = convertValue(value, Getattr(p, "type")); if (new_value) Printf(doc, "=%s", new_value); + Delete(new_value); } Delete(type_str); Delete(made_name); @@ -2031,9 +2032,9 @@ public: Delete(rname); } else { if (CPlusPlus) { - Printf(doc, "Proxy of C++ %s class.", real_classname); + Printf(doc, "Proxy of C++ %s class.", SwigType_namestr(real_classname)); } else { - Printf(doc, "Proxy of C %s struct.", real_classname); + Printf(doc, "Proxy of C %s struct.", SwigType_namestr(real_classname)); } } } @@ -2044,7 +2045,7 @@ public: String *paramList = make_autodocParmList(n, showTypes); Printf(doc, "__init__("); if (showTypes) - Printf(doc, "%s ", getClassName()); + Printf(doc, "%s ", class_name); if (Len(paramList)) Printf(doc, "self, %s) -> %s", paramList, class_name); else @@ -2055,7 +2056,7 @@ public: case AUTODOC_DTOR: if (showTypes) - Printf(doc, "__del__(%s self)", getClassName()); + Printf(doc, "__del__(%s self)", class_name); else Printf(doc, "__del__(self)"); break; @@ -2109,6 +2110,70 @@ public: return doc; } + /* ------------------------------------------------------------ + * convertIntegerValue() + * + * Check if string v is an integer and can be represented in + * Python. If so, return an appropriate Python representation, + * otherwise (or if we are unsure), return NIL. + * ------------------------------------------------------------ */ + String *convertIntegerValue(String *v, SwigType *resolved_type) { + const char *const s = Char(v); + char *end; + String *result = NIL; + + // Check if this is an integer number in any base. + long value = strtol(s, &end, 0); + if (errno == ERANGE || end == s) + return NIL; + if (*end != '\0') { + // If there is a suffix after the number, we can safely ignore "l" + // and (provided the number is unsigned) "u", and also combinations of + // these, but not anything else. + for (char *p = end; *p != '\0'; ++p) { + switch (*p) { + case 'l': + case 'L': + break; + case 'u': + case 'U': + if (value < 0) + return NIL; + break; + default: + return NIL; + } + } + } + // So now we are certain that we are indeed dealing with an integer + // that has a representation as long given by value. + + if (Cmp(resolved_type, "bool") == 0) + // Allow integers as the default value for a bool parameter. + return NewString(value ? "True" : "False"); + + if (value == 0) + return NewString(SwigType_ispointer(resolved_type) ? "None" : "0"); + + // v may still be octal or hexadecimal: + const char *p = s; + if (*p == '+' || *p == '-') + ++p; + if (*p == '0' && *(p+1) != 'x' && *(p+1) != 'X') { + // This must have been an octal number. This is the only case we + // cannot use in Python directly, since Python 2 and 3 use non- + // compatible representations. + result = NewString(*s == '-' ? "int('-" : "int('"); + String *octal_string = NewStringWithSize(p, (int) (end - p)); + Append(result, octal_string); + Append(result, "', 8)"); + Delete(octal_string); + return result; + } + result = *end == '\0' ? Copy(v) : NewStringWithSize(s, (int) (end - s)); + return result; + } + /* ------------------------------------------------------------ * convertDoubleValue() * @@ -2147,7 +2212,7 @@ public: // Avoid unnecessary string allocation in the common case when we don't // need to remove any suffix. - return *end == '\0' ? v : NewStringWithSize(s, (int)(end - s)); + return *end == '\0' ? Copy(v) : NewStringWithSize(s, (int)(end - s)); } return NIL; @@ -2157,109 +2222,24 @@ public: * convertValue() * * Check if string v can be a Python value literal or a - * constant. Return NIL if it isn't. + * constant. Return an equivalent Python representation, + * or NIL if it isn't, or we are unsure. * ------------------------------------------------------------ */ String *convertValue(String *v, SwigType *type) { const char *const s = Char(v); - char *end; String *result = NIL; - bool fail = false; - SwigType *resolved_type = 0; + SwigType *resolved_type = SwigType_typedef_resolve_all(type); - // Check if this is a number in any base. - long value = strtol(s, &end, 0); - (void) value; - if (end != s) { - if (errno == ERANGE) { - // There was an overflow, we could try representing the value as Python - // long integer literal, but for now don't bother with it. - fail = true; - } else { - if (*end != '\0') { - // If there is a suffix after the number, we can safely ignore any - // combination of "l" and "u", but not anything else (again, stuff like - // "LL" could be handled, but we don't bother to do it currently). - bool seen_long = false; - for (char * p = end; *p != '\0'; ++p) { - switch (*p) { - case 'l': - case 'L': - // Bail out on "LL". - if (seen_long) { - fail = true; - break; - } - seen_long = true; - break; - - case 'u': - case 'U': - break; - - default: - // Except that our suffix could actually be the fractional part of - // a floating point number, so we still have to check for this. - result = convertDoubleValue(v); - } - } - } - - if (!fail) { - // Allow integers as the default value for a bool parameter. - resolved_type = SwigType_typedef_resolve_all(type); - if (Cmp(resolved_type, "bool") == 0) { - result = NewString(value ? "True" : "False"); - } else { - // Deal with the values starting with 0 first as they can be octal or - // hexadecimal numbers or even pointers. - if (s[0] == '0') { - if (Len(v) == 1) { - // This is just a lone 0, but it needs to be represented differently - // in Python depending on whether it's a zero or a null pointer. - if (SwigType_ispointer(resolved_type)) - result = NewString("None"); - else - result = v; - } else if (s[1] == 'x' || s[1] == 'X') { - // This must have been a hex number, we can use it directly in Python, - // so nothing to do here. - } else { - // This must have been an octal number, we have to change its prefix - // to be "0o" in Python 3 only (and as long as we still support Python - // 2.5, this can't be done unconditionally). - if (py3) { - if (end - s > 1) { - result = NewString("0o"); - Append(result, NewStringWithSize(s + 1, (int)(end - s - 1))); - } - } - } - } - - // Avoid unnecessary string allocation in the common case when we don't - // need to remove any suffix. - if (!result) - result = *end == '\0' ? v : NewStringWithSize(s, (int)(end - s)); - } - } - } - } - - // Check if this is a floating point number (notice that it wasn't - // necessarily parsed as a long above, consider e.g. ".123"). - if (!fail && !result) { + result = convertIntegerValue(v, resolved_type); + if (!result) { result = convertDoubleValue(v); if (!result) { - if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0) + if (Strcmp(v, "true") == 0) result = NewString("True"); - else if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0) + else if (Strcmp(v, "false") == 0) result = NewString("False"); - else if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0) { - if (!resolved_type) - resolved_type = SwigType_typedef_resolve_all(type); + else if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0) result = SwigType_ispointer(resolved_type) ? NewString("None") : NewString("0"); - } - // This could also be an enum type, default value of which could be // representable in Python if it doesn't include any scope (which could, // but currently is not, translated). @@ -2267,7 +2247,7 @@ public: Node *lookup = Swig_symbol_clookup(v, 0); if (lookup) { if (Cmp(Getattr(lookup, "nodeType"), "enumitem") == 0) - result = Getattr(lookup, "sym:name"); + result = Copy(Getattr(lookup, "sym:name")); } } } @@ -2314,10 +2294,12 @@ public: if (Getattr(p, "tmap:default")) return false; - if (String *value = Getattr(p, "value")) { - String *type = Getattr(p, "type"); - if (!convertValue(value, type)) + String *value = Getattr(p, "value"); + if (value) { + String *convertedValue = convertValue(value, Getattr(p, "type")); + if (!convertedValue) return false; + Delete(convertedValue); } } @@ -2598,7 +2580,8 @@ public: String *tmp = NewString(""); String *dispatch; - const char *dispatch_code = funpack ? "return %s(self, argc, argv);" : "return %s(self, args);"; + const char *dispatch_code = funpack ? "return %s(self, argc, argv);" : + (builtin_ctor ? "return %s(self, args, NULL);" : "return %s(self, args);"); if (castmode) { dispatch = Swig_overload_dispatch_cast(n, dispatch_code, &maxargs); @@ -2612,7 +2595,8 @@ public: String *symname = Getattr(n, "sym:name"); String *wname = Swig_name_wrapper(symname); - Printv(f->def, linkage, builtin_ctor ? "int " : "PyObject *", wname, "(PyObject *self, PyObject *args) {", NIL); + const char *builtin_kwargs = builtin_ctor ? ", PyObject *SWIGUNUSEDPARM(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"); Printf(tmp, "PyObject *argv[%d] = {0}", maxargs + 1); @@ -2620,9 +2604,14 @@ public: if (!fastunpack) { Wrapper_add_local(f, "ii", "Py_ssize_t ii"); - if (maxargs - (add_self ? 1 : 0) > 0) - Append(f->code, "if (!PyTuple_Check(args)) SWIG_fail;\n"); - Append(f->code, "argc = args ? PyObject_Length(args) : 0;\n"); + + 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"); + } else { + Append(f->code, "argc = args ? PyObject_Length(args) : 0;\n"); + } + if (add_self) Append(f->code, "argv[0] = self;\n"); Printf(f->code, "for (ii = 0; (ii < %d) && (ii < argc); ii++) {\n", add_self ? maxargs - 1 : maxargs); @@ -2645,8 +2634,8 @@ public: if (GetFlag(n, "feature:python:maybecall")) { Append(f->code, "fail:\n"); - Append(f->code, "Py_INCREF(Py_NotImplemented);\n"); - Append(f->code, "return Py_NotImplemented;\n"); + Append(f->code, " Py_INCREF(Py_NotImplemented);\n"); + Append(f->code, " return Py_NotImplemented;\n"); } else { Node *sibl = n; while (Getattr(sibl, "sym:previousSibling")) @@ -2658,7 +2647,7 @@ public: Delete(fulldecl); } while ((sibl = Getattr(sibl, "sym:nextSibling"))); Append(f->code, "fail:\n"); - Printf(f->code, "SWIG_SetErrorMsg(PyExc_NotImplementedError," + Printf(f->code, " SWIG_SetErrorMsg(PyExc_NotImplementedError," "\"Wrong number or type of arguments for overloaded function '%s'.\\n\"" "\n\" Possible C/C++ prototypes are:\\n\"%s);\n", symname, protoTypes); Printf(f->code, "return %s;\n", builtin_ctor ? "-1" : "0"); Delete(protoTypes); @@ -2821,9 +2810,10 @@ public: Append(wname, overname); } + const char *builtin_kwargs = builtin_ctor ? ", PyObject *SWIGUNUSEDPARM(kwargs)" : ""; if (!allow_kwargs || overname) { if (!varargs) { - Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args) {", NIL); + Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL); } else { Printv(f->def, linkage, wrap_return, wname, "__varargs__", "(PyObject *", self_param, ", PyObject *args, PyObject *varargs) {", NIL); } @@ -3019,17 +3009,13 @@ public: Clear(f->def); if (overname) { if (noargs) { - Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", int nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {", NIL); + Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {", NIL); } else { - Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", int nobjs, PyObject **swig_obj) {", NIL); + Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", Py_ssize_t nobjs, PyObject **swig_obj) {", NIL); } Printf(parse_args, "if ((nobjs < %d) || (nobjs > %d)) SWIG_fail;\n", num_required, num_arguments); } else { - if (noargs) { - Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args) {", NIL); - } else { - Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args) {", NIL); - } + Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL); if (onearg && !builtin_ctor) { Printf(parse_args, "if (!args) SWIG_fail;\n"); Append(parse_args, "swig_obj[0] = args;\n"); @@ -3283,10 +3269,17 @@ public: if (need_cleanup) { Printv(f->code, cleanup, NIL); } - if (builtin_ctor) + if (builtin_ctor) { Printv(f->code, " return -1;\n", NIL); - else - Printv(f->code, " return NULL;\n", NIL); + } else { + if (GetFlag(n, "feature:python:maybecall")) { + Append(f->code, " PyErr_Clear();\n"); + Append(f->code, " Py_INCREF(Py_NotImplemented);\n"); + Append(f->code, " return Py_NotImplemented;\n"); + } else { + Printv(f->code, " return NULL;\n", NIL); + } + } if (funpack) { @@ -3323,9 +3316,10 @@ public: DelWrapper(f); f = NewWrapper(); if (funpack) { - Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", int nobjs, PyObject **swig_obj) {", NIL); + // Note: funpack is currently always false for varargs + Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", Py_ssize_t nobjs, PyObject **swig_obj) {", NIL); } else { - Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args) {", NIL); + Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL); } Wrapper_add_local(f, "resultobj", builtin_ctor ? "int resultobj" : "PyObject *resultobj"); Wrapper_add_local(f, "varargs", "PyObject *varargs"); @@ -3435,7 +3429,7 @@ public: closure_name = Copy(wrapper_name); } if (func_type) { - String *s = NewStringf("(%s) %s", func_type, closure_name); + String *s = NewStringf("%s", closure_name); Delete(closure_name); closure_name = s; } @@ -5119,7 +5113,7 @@ public: Printv(f_shadow, tab4, "__swig_destroy__ = ", module, ".", Swig_name_destroy(NSPACE_TODO, symname), "\n", NIL); if (!have_pythonprepend(n) && !have_pythonappend(n)) { if (proxydel) { - Printv(f_shadow, tab4, "__del__ = lambda self: None\n", NIL); + Printv(f_shadow, tab4, "def __del__(self):\n", tab8, "return None\n", NIL); } return SWIG_OK; } @@ -5454,8 +5448,11 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) { Delete(target); // Get any exception classes in the throws typemap + if (Getattr(n, "noexcept")) { + Append(w->def, " noexcept"); + Append(declaration, " noexcept"); + } ParmList *throw_parm_list = 0; - if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { Parm *p; int gencomma = 0; @@ -5489,8 +5486,16 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) { * if the return value is a reference or const reference, a specialized typemap must * handle it, including declaration of c_result ($result). */ - if (!is_void) { - if (!(ignored_method && !pure_virtual)) { + if (!is_void && (!ignored_method || pure_virtual)) { + if (!SwigType_isclass(returntype)) { + if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { + String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); + Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL); + Delete(construct_result); + } else { + Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL); + } + } else { String *cres = SwigType_lstr(returntype, "c_result"); Printf(w->code, "%s;\n", cres); Delete(cres); diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx index 74130aac3..db94ec934 100644 --- a/Source/Modules/r.cxx +++ b/Source/Modules/r.cxx @@ -290,8 +290,6 @@ public: int membervariableHandler(Node *n); int typedefHandler(Node *n); - static List *Swig_overload_rank(Node *n, - bool script_lang_wrapping); int memberfunctionHandler(Node *n) { if (debugMode) @@ -573,7 +571,7 @@ String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) { String *lname; if (!arg && Cmp(Getattr(p, "type"), "void")) { - lname = NewStringf("s_arg%d", i+1); + lname = NewStringf("arg%d", i+1); Setattr(p, "name", lname); } else lname = arg; @@ -616,19 +614,25 @@ String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) { for(i = 0; p; i++) { SwigType *tt = Getattr(p, "type"); SwigType *name = Getattr(p, "name"); + SwigType *swig_parm_name = NewStringf("swigarg_%s", name); String *tm = Getattr(p, "tmap:out"); - Printf(f->def, "%s %s", SwigType_str(tt, 0), name); - if(tm) { - Replaceall(tm, "$1", name); - if (SwigType_isreference(tt)) { - String *tmp = NewString(""); - Append(tmp, "*"); - Append(tmp, name); - Replaceall(tm, tmp, name); + bool isVoidParm = Strcmp(tt, "void") == 0; + if (isVoidParm) + Printf(f->def, "%s", SwigType_str(tt, 0)); + else + Printf(f->def, "%s %s", SwigType_str(tt, 0), swig_parm_name); + if (tm) { + String *lstr = SwigType_lstr(tt, 0); + if (SwigType_isreference(tt) || SwigType_isrvalue_reference(tt)) { + Printf(f->code, "%s = (%s) &%s;\n", Getattr(p, "lname"), lstr, swig_parm_name); + } else if (!isVoidParm) { + Printf(f->code, "%s = (%s) %s;\n", Getattr(p, "lname"), lstr, swig_parm_name); } + Replaceall(tm, "$1", name); Replaceall(tm, "$result", "r_tmp"); replaceRClass(tm, Getattr(p,"type")); Replaceall(tm,"$owner", "R_SWIG_EXTERNAL"); + Delete(lstr); } Printf(setExprElements, "%s\n", tm); @@ -697,10 +701,13 @@ String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) { Printv(f->code, "R_SWIG_popCallbackFunctionData(1);\n", NIL); Printv(f->code, "\n", UnProtectWrapupCode, NIL); - if (SwigType_isreference(rettype)) { + if (SwigType_isreference(rettype)) { Printv(f->code, "return *", Swig_cresult_name(), ";\n", NIL); - } else if(!isVoidType) + } else if (SwigType_isrvalue_reference(rettype)) { + Printv(f->code, "return std::move(*", Swig_cresult_name(), ");\n", NIL); + } else if (!isVoidType) { Printv(f->code, "return ", Swig_cresult_name(), ";\n", NIL); + } Printv(f->code, "\n}\n", NIL); Replaceall(f->code, "SWIG_exception_fail", "SWIG_exception_noreturn"); @@ -709,7 +716,7 @@ String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) { function that handles the scoerceout. We need to check if any of the argument types have an entry in that map. If none do, the ignore and call the function straight. - Otherwise, generate the a marshalling function. + Otherwise, generate a marshalling function. Need to be able to find it in S. Or use an entirely generic one that evaluates the expressions. Handle errors in the evaluation of the function by restoring @@ -1305,260 +1312,6 @@ void R::addAccessor(String *memberName, Wrapper *wrapper, String *name, Printf(stdout, "Adding accessor: %s (%s) => %s\n", memberName, name, tmp); } -#define MAX_OVERLOAD 256 - -struct Overloaded { - Node *n; /* Node */ - int argc; /* Argument count */ - ParmList *parms; /* Parameters used for overload check */ - int error; /* Ambiguity error */ -}; - - -List * R::Swig_overload_rank(Node *n, - bool script_lang_wrapping) { - Overloaded nodes[MAX_OVERLOAD]; - int nnodes = 0; - Node *o = Getattr(n,"sym:overloaded"); - - - if (!o) return 0; - - Node *c = o; - while (c) { - if (Getattr(c,"error")) { - 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 */ - - if (Getattr(c,"wrap:name")) { - nodes[nnodes].n = c; - nodes[nnodes].parms = Getattr(c,"wrap:parms"); - nodes[nnodes].argc = emit_num_required(nodes[nnodes].parms); - nodes[nnodes].error = 0; - nnodes++; - } - c = Getattr(c,"sym:nextSibling"); - } - - /* Sort the declarations by required argument count */ - { - int i,j; - for (i = 0; i < nnodes; i++) { - for (j = i+1; j < nnodes; j++) { - if (nodes[i].argc > nodes[j].argc) { - Overloaded t = nodes[i]; - nodes[i] = nodes[j]; - nodes[j] = t; - } - } - } - } - - /* Sort the declarations by argument types */ - { - int i,j; - for (i = 0; i < nnodes-1; i++) { - if (nodes[i].argc == nodes[i+1].argc) { - for (j = i+1; (j < nnodes) && (nodes[j].argc == nodes[i].argc); j++) { - Parm *p1 = nodes[i].parms; - Parm *p2 = nodes[j].parms; - int differ = 0; - int num_checked = 0; - while (p1 && p2 && (num_checked < nodes[i].argc)) { - if (debugMode) { - Printf(stdout,"p1 = '%s', p2 = '%s'\n", Getattr(p1,"type"), Getattr(p2,"type")); - } - if (checkAttribute(p1,"tmap:in:numinputs","0")) { - p1 = Getattr(p1,"tmap:in:next"); - continue; - } - if (checkAttribute(p2,"tmap:in:numinputs","0")) { - p2 = Getattr(p2,"tmap:in:next"); - continue; - } - String *t1 = Getattr(p1,"tmap:typecheck:precedence"); - String *t2 = Getattr(p2,"tmap:typecheck:precedence"); - if (debugMode) { - Printf(stdout,"t1 = '%s', t2 = '%s'\n", t1, t2); - } - if ((!t1) && (!nodes[i].error)) { - Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[i].n), Getline(nodes[i].n), - "Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n", - Swig_name_decl(nodes[i].n), SwigType_str(Getattr(p1, "type"), 0)); - nodes[i].error = 1; - } else if ((!t2) && (!nodes[j].error)) { - Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n", - Swig_name_decl(nodes[j].n), SwigType_str(Getattr(p2, "type"), 0)); - nodes[j].error = 1; - } - if (t1 && t2) { - int t1v, t2v; - t1v = atoi(Char(t1)); - t2v = atoi(Char(t2)); - differ = t1v-t2v; - } - else if (!t1 && t2) differ = 1; - else if (t1 && !t2) differ = -1; - else if (!t1 && !t2) differ = -1; - num_checked++; - if (differ > 0) { - Overloaded t = nodes[i]; - nodes[i] = nodes[j]; - nodes[j] = t; - break; - } else if ((differ == 0) && (Strcmp(t1,"0") == 0)) { - t1 = Getattr(p1,"ltype"); - if (!t1) { - t1 = SwigType_ltype(Getattr(p1,"type")); - if (Getattr(p1,"tmap:typecheck:SWIGTYPE")) { - SwigType_add_pointer(t1); - } - Setattr(p1,"ltype",t1); - } - t2 = Getattr(p2,"ltype"); - if (!t2) { - t2 = SwigType_ltype(Getattr(p2,"type")); - if (Getattr(p2,"tmap:typecheck:SWIGTYPE")) { - SwigType_add_pointer(t2); - } - Setattr(p2,"ltype",t2); - } - - /* Need subtype check here. If t2 is a subtype of t1, then we need to change the - order */ - - if (SwigType_issubtype(t2,t1)) { - Overloaded t = nodes[i]; - nodes[i] = nodes[j]; - nodes[j] = t; - } - - if (Strcmp(t1,t2) != 0) { - differ = 1; - break; - } - } else if (differ) { - break; - } - if (Getattr(p1,"tmap:in:next")) { - p1 = Getattr(p1,"tmap:in:next"); - } else { - p1 = nextSibling(p1); - } - if (Getattr(p2,"tmap:in:next")) { - p2 = Getattr(p2,"tmap:in:next"); - } else { - p2 = nextSibling(p2); - } - } - if (!differ) { - /* See if declarations differ by const only */ - String *d1 = Getattr(nodes[i].n, "decl"); - String *d2 = Getattr(nodes[j].n, "decl"); - if (d1 && d2) { - String *dq1 = Copy(d1); - String *dq2 = Copy(d2); - if (SwigType_isconst(d1)) { - Delete(SwigType_pop(dq1)); - } - if (SwigType_isconst(d2)) { - Delete(SwigType_pop(dq2)); - } - if (Strcmp(dq1, dq2) == 0) { - - if (SwigType_isconst(d1) && !SwigType_isconst(d2)) { - if (script_lang_wrapping) { - // Swap nodes so that the const method gets ignored (shadowed by the non-const method) - Overloaded t = nodes[i]; - nodes[i] = nodes[j]; - nodes[j] = t; - } - differ = 1; - if (!nodes[j].error) { - if (script_lang_wrapping) { - Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n), - "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n)); - } else { - if (!Getattr(nodes[j].n, "overload:ignore")) { - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), - "using %s instead.\n", Swig_name_decl(nodes[i].n)); - } - } - } - nodes[j].error = 1; - } else if (!SwigType_isconst(d1) && SwigType_isconst(d2)) { - differ = 1; - if (!nodes[j].error) { - if (script_lang_wrapping) { - Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n), - "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n)); - } else { - if (!Getattr(nodes[j].n, "overload:ignore")) { - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), - "using %s instead.\n", Swig_name_decl(nodes[i].n)); - } - } - } - nodes[j].error = 1; - } - } - Delete(dq1); - Delete(dq2); - } - } - if (!differ) { - if (!nodes[j].error) { - if (script_lang_wrapping) { - Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s effectively ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[i].n), Getline(nodes[i].n), - "as it is shadowed by %s.\n", Swig_name_decl(nodes[i].n)); - } else { - if (!Getattr(nodes[j].n, "overload:ignore")) { - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), - "using %s instead.\n", Swig_name_decl(nodes[i].n)); - } - } - nodes[j].error = 1; - } - } - } - } - } - } - List *result = NewList(); - { - int i; - for (i = 0; i < nnodes; i++) { - if (nodes[i].error) - Setattr(nodes[i].n, "overload:ignore", "1"); - Append(result,nodes[i].n); - // Printf(stdout,"[ %d ] %s\n", i, ParmList_errorstr(nodes[i].parms)); - // Swig_print_node(nodes[i].n); - } - } - return result; -} - void R::dispatchFunction(Node *n) { Wrapper *f = NewWrapper(); String *symname = Getattr(n, "sym:name"); diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx index b9ac11546..25988d6fb 100644 --- a/Source/Modules/ruby.cxx +++ b/Source/Modules/ruby.cxx @@ -3112,6 +3112,10 @@ public: Delete(target); // Get any exception classes in the throws typemap + if (Getattr(n, "noexcept")) { + Append(w->def, " noexcept"); + Append(declaration, " noexcept"); + } ParmList *throw_parm_list = 0; if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { @@ -3150,9 +3154,19 @@ public: * if the return value is a reference or const reference, a specialized typemap must * handle it, including declaration of c_result ($result). */ - if (!is_void) { - if (!(ignored_method && !pure_virtual)) { - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), NIL); + if (!is_void && (!ignored_method || pure_virtual)) { + if (!SwigType_isclass(returntype)) { + if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { + String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); + Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL); + Delete(construct_result); + } else { + Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL); + } + } else { + String *cres = SwigType_lstr(returntype, "c_result"); + Printf(w->code, "%s;\n", cres); + Delete(cres); } } diff --git a/Source/Modules/scilab.cxx b/Source/Modules/scilab.cxx index 5997b5876..4fea0ce36 100644 --- a/Source/Modules/scilab.cxx +++ b/Source/Modules/scilab.cxx @@ -18,13 +18,14 @@ static const int SCILAB_VARIABLE_NAME_CHAR_MAX = SCILAB_IDENTIFIER_NAME_CHAR_MAX static const char *usage = (char *) " \ Scilab options (available with -scilab)\n \ - -builder - Generate a Scilab builder script\n \ - -buildercflags - Add to the builder compiler flags\n \ - -builderflagscript - Set the Scilab script to use by builder to configure the build flags\n \ - -builderldflags - Add to the builder linker flags\n \ - -buildersources - Add the (comma separated) files to the builder sources\n \ - -builderverbositylevel - Set the builder verbosity level to (default 0: off, 2: high)\n \ - -gatewayxml - Generate gateway xml with the given \n \ + -builder - Generate a Scilab builder script\n \ + -buildercflags - Add to the builder compiler flags\n \ + -builderflagscript - Set the Scilab script to use by builder to configure the build flags\n \ + -builderldflags - Add to the builder linker flags\n \ + -buildersources - Add the (comma separated) files to the builder sources\n \ + -builderverbositylevel - Set the builder verbosity level to (default 0: off, 2: high)\n \ + -gatewayxml - Generate gateway xml with the given \n \ + -targetversion - Generate for Scilab target (major) version (default: 5)\n \ \n"; @@ -39,6 +40,8 @@ protected: String *variablesCode; + int targetVersion; + bool generateBuilder; File *builderFile; String *builderCode; @@ -71,6 +74,7 @@ public: * ----------------------------------------------------------------------*/ virtual void main(int argc, char *argv[]) { + targetVersion = 5; generateBuilder = false; sourceFileList = NewList(); @@ -95,48 +99,54 @@ public: /* Manage command line arguments */ for (int argIndex = 1; argIndex < argc; argIndex++) { if (argv[argIndex] != NULL) { - if (strcmp(argv[argIndex], "-help") == 0) { - Printf(stdout, "%s\n", usage); - } else if (strcmp(argv[argIndex], "-builder") == 0) { - Swig_mark_arg(argIndex); - generateBuilder = true; - createLoader = false; - } else if (strcmp(argv[argIndex], "-buildersources") == 0) { - if (argv[argIndex + 1] != NULL) { - Swig_mark_arg(argIndex); - char *sourceFile = strtok(argv[argIndex + 1], ","); - while (sourceFile != NULL) { - Insert(sourceFileList, Len(sourceFileList), sourceFile); - sourceFile = strtok(NULL, ","); - } - Swig_mark_arg(argIndex + 1); - } - } else if (strcmp(argv[argIndex], "-buildercflags") == 0) { - Swig_mark_arg(argIndex); - if (argv[argIndex + 1] != NULL) { - Insert(cflags, Len(cflags), argv[argIndex + 1]); - Swig_mark_arg(argIndex + 1); - } - } else if (strcmp(argv[argIndex], "-builderldflags") == 0) { - Swig_mark_arg(argIndex); - if (argv[argIndex + 1] != NULL) { - Insert(ldflags, Len(ldflags), argv[argIndex + 1]); - Swig_mark_arg(argIndex + 1); - } - } else if (strcmp(argv[argIndex], "-builderverbositylevel") == 0) { - Swig_mark_arg(argIndex); - verboseBuildLevel = NewString(argv[argIndex + 1]); - Swig_mark_arg(argIndex + 1); - } else if (strcmp(argv[argIndex], "-builderflagscript") == 0) { - Swig_mark_arg(argIndex); - buildFlagsScript = NewString(argv[argIndex + 1]); - Swig_mark_arg(argIndex + 1); - } else if (strcmp(argv[argIndex], "-gatewayxml") == 0) { - Swig_mark_arg(argIndex); - createGatewayXML = true; - gatewayID = NewString(argv[argIndex + 1]); - Swig_mark_arg(argIndex + 1); - } + if (strcmp(argv[argIndex], "-help") == 0) { + Printf(stdout, "%s\n", usage); + } else if (strcmp(argv[argIndex], "-builder") == 0) { + Swig_mark_arg(argIndex); + generateBuilder = true; + createLoader = false; + } else if (strcmp(argv[argIndex], "-buildersources") == 0) { + if (argv[argIndex + 1] != NULL) { + Swig_mark_arg(argIndex); + char *sourceFile = strtok(argv[argIndex + 1], ","); + while (sourceFile != NULL) { + Insert(sourceFileList, Len(sourceFileList), sourceFile); + sourceFile = strtok(NULL, ","); + } + Swig_mark_arg(argIndex + 1); + } + } else if (strcmp(argv[argIndex], "-buildercflags") == 0) { + Swig_mark_arg(argIndex); + if (argv[argIndex + 1] != NULL) { + Insert(cflags, Len(cflags), argv[argIndex + 1]); + Swig_mark_arg(argIndex + 1); + } + } else if (strcmp(argv[argIndex], "-builderldflags") == 0) { + Swig_mark_arg(argIndex); + if (argv[argIndex + 1] != NULL) { + Insert(ldflags, Len(ldflags), argv[argIndex + 1]); + Swig_mark_arg(argIndex + 1); + } + } else if (strcmp(argv[argIndex], "-builderverbositylevel") == 0) { + Swig_mark_arg(argIndex); + verboseBuildLevel = NewString(argv[argIndex + 1]); + Swig_mark_arg(argIndex + 1); + } else if (strcmp(argv[argIndex], "-builderflagscript") == 0) { + Swig_mark_arg(argIndex); + buildFlagsScript = NewString(argv[argIndex + 1]); + Swig_mark_arg(argIndex + 1); + } else if (strcmp(argv[argIndex], "-gatewayxml") == 0) { + Swig_mark_arg(argIndex); + createGatewayXML = true; + gatewayID = NewString(argv[argIndex + 1]); + Swig_mark_arg(argIndex + 1); + } else if (strcmp(argv[argIndex], "-targetversion") == 0) { + if (argv[argIndex + 1] != NULL) { + Swig_mark_arg(argIndex); + targetVersion = atoi(argv[argIndex + 1]); + Swig_mark_arg(argIndex + 1); + } + } } } @@ -784,57 +794,61 @@ public: /* ----------------------------------------------------------------------- * checkIdentifierName() - * Truncates (and displays a warning) for too long identifier names - * (applies on functions, variables, constants...) - * (Scilab identifiers names are limited to 24 chars max) + * If Scilab target version is lower than 6: + * truncates (and displays a warning) too long member identifier names + * (applies on members of structs, classes...) + * (Scilab 5 identifier names are limited to 24 chars max) * ----------------------------------------------------------------------- */ String *checkIdentifierName(String *name, int char_size_max) { String *scilabIdentifierName; - if (Len(name) > char_size_max) { - scilabIdentifierName = DohNewStringWithSize(name, char_size_max); - Swig_warning(WARN_SCILAB_TRUNCATED_NAME, input_file, line_number, - "Identifier name '%s' exceeds 24 characters and has been truncated to '%s'.\n", name, scilabIdentifierName); - } else + if (targetVersion <= 5) { + if (Len(name) > char_size_max) { + scilabIdentifierName = DohNewStringWithSize(name, char_size_max); + Swig_warning(WARN_SCILAB_TRUNCATED_NAME, input_file, line_number, + "Identifier name '%s' exceeds 24 characters and has been truncated to '%s'.\n", name, scilabIdentifierName); + } else scilabIdentifierName = name; - return scilabIdentifierName; + } else { + scilabIdentifierName = DohNewString(name); + } + return scilabIdentifierName; } /* ----------------------------------------------------------------------- * checkMemberIdentifierName() - * Truncates (and displays a warning) too long member identifier names - * (applies on members of structs, classes...) - * (Scilab identifiers names are limited to 24 chars max) + * If Scilab target version is lower than 6: + * truncates (and displays a warning) too long member identifier names + * (applies on members of structs, classes...) + * (Scilab 5 identifier names are limited to 24 chars max) * ----------------------------------------------------------------------- */ void checkMemberIdentifierName(Node *node, int char_size_max) { + if (targetVersion <= 5) { + String *memberName = Getattr(node, "sym:name"); + Node *containerNode = parentNode(node); + String *containerName = Getattr(containerNode, "sym:name"); + int lenContainerName = Len(containerName); + int lenMemberName = Len(memberName); - String *memberName = Getattr(node, "sym:name"); + if (lenContainerName + lenMemberName + 1 > char_size_max) { + int lenScilabMemberName = char_size_max - lenContainerName - 1; - Node *containerNode = parentNode(node); - String *containerName = Getattr(containerNode, "sym:name"); - - int lenContainerName = Len(containerName); - int lenMemberName = Len(memberName); - - if (lenContainerName + lenMemberName + 1 > char_size_max) { - int lenScilabMemberName = char_size_max - lenContainerName - 1; - - if (lenScilabMemberName > 0) { - String *scilabMemberName = DohNewStringWithSize(memberName, lenScilabMemberName); - Setattr(node, "sym:name", scilabMemberName); - Swig_warning(WARN_SCILAB_TRUNCATED_NAME, input_file, line_number, - "Wrapping functions names for member '%s.%s' will exceed 24 characters, " - "so member name has been truncated to '%s'.\n", containerName, memberName, scilabMemberName); - } else - Swig_error(input_file, line_number, - "Wrapping functions names for member '%s.%s' will exceed 24 characters, " - "please rename the container of member '%s'.\n", containerName, memberName, containerName); + if (lenScilabMemberName > 0) { + String *scilabMemberName = DohNewStringWithSize(memberName, lenScilabMemberName); + Setattr(node, "sym:name", scilabMemberName); + Swig_warning(WARN_SCILAB_TRUNCATED_NAME, input_file, line_number, + "Wrapping functions names for member '%s.%s' will exceed 24 characters, " + "so member name has been truncated to '%s'.\n", containerName, memberName, scilabMemberName); + } else { + Swig_error(input_file, line_number, + "Wrapping functions names for member '%s.%s' will exceed 24 characters, " + "please rename the container of member '%s'.\n", containerName, memberName, containerName); + } + } } } - - /* ----------------------------------------------------------------------- * addHelperFunctions() * ----------------------------------------------------------------------- */ @@ -1013,8 +1027,14 @@ public: Printf(gatewayHeader, "\n"); gatewayHeaderV6 = NewString(""); + Printf(gatewayHeaderV6, "#ifdef __cplusplus\n"); + Printf(gatewayHeaderV6, "extern \"C\" {\n"); + Printf(gatewayHeaderV6, "#endif\n"); Printf(gatewayHeaderV6, "#include \"c_gateway_prototype.h\"\n"); Printf(gatewayHeaderV6, "#include \"addfunction.h\"\n"); + Printf(gatewayHeaderV6, "#ifdef __cplusplus\n"); + Printf(gatewayHeaderV6, "}\n"); + Printf(gatewayHeaderV6, "#endif\n"); Printf(gatewayHeaderV6, "\n"); Printf(gatewayHeaderV6, "#define MODULE_NAME L\"%s\"\n", gatewayLibraryName); Printf(gatewayHeaderV6, "#ifdef __cplusplus\n"); diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index bf8028c29..57125fcbb 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -187,8 +187,10 @@ class TypePass:private Dispatcher { ilist = alist = NewList(); Append(ilist, bcls); } else { - Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' has no name as it is an empty template instantiated with '%%template()'. Ignored.\n", SwigType_namestr(bname)); - Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "The %%template directive must be written before '%s' is used as a base class and be declared with a name.\n", SwigType_namestr(bname)); + if (!GetFlag(bcls, "feature:ignore")) { + Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' has no name as it is an empty template instantiated with '%%template()'. Ignored.\n", SwigType_namestr(bname)); + Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "The %%template directive must be written before '%s' is used as a base class and be declared with a name.\n", SwigType_namestr(bname)); + } } } break; @@ -209,8 +211,10 @@ class TypePass:private Dispatcher { ilist = alist = NewList(); Append(ilist, bcls); } else { - Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' has no name as it is an empty template instantiated with '%%template()'. Ignored.\n", SwigType_namestr(bname)); - Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "The %%template directive must be written before '%s' is used as a base class and be declared with a name.\n", SwigType_namestr(bname)); + if (!GetFlag(bcls, "feature:ignore")) { + Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' has no name as it is an empty template instantiated with '%%template()'. Ignored.\n", SwigType_namestr(bname)); + Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "The %%template directive must be written before '%s' is used as a base class and be declared with a name.\n", SwigType_namestr(bname)); + } } } else { Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' undefined.\n", SwigType_namestr(bname)); @@ -1199,10 +1203,7 @@ class TypePass:private Dispatcher { } else if (Strcmp(ntype, "enum") == 0) { SwigType_typedef_using(Getattr(n, "uname")); } else if (Strcmp(ntype, "template") == 0) { - /* - Printf(stdout, "usingDeclaration template %s --- %s\n", Getattr(n, "name"), Getattr(n, "uname")); SwigType_typedef_using(Getattr(n, "uname")); - */ } } } diff --git a/Source/Modules/utils.cxx b/Source/Modules/utils.cxx index a91ebe098..2964ed3a6 100644 --- a/Source/Modules/utils.cxx +++ b/Source/Modules/utils.cxx @@ -59,7 +59,7 @@ int is_non_virtual_protected_access(Node *n) { // When vtable is empty, the director class does not get emitted, so a check for an empty vtable should be done. // However, vtable is set in Language and so is not yet set when methods in Typepass call clean_overloaded() // which calls is_non_virtual_protected_access. So commented out below. - // Moving the director vtable creation into into Typepass should solve this problem. + // Moving the director vtable creation into Typepass should solve this problem. if (is_member_director_helper(parentNode, n) /* && Getattr(parentNode, "vtable")*/) result = 1; } diff --git a/Source/Preprocessor/cpp.c b/Source/Preprocessor/cpp.c index 12d27c316..491eb8a96 100644 --- a/Source/Preprocessor/cpp.c +++ b/Source/Preprocessor/cpp.c @@ -607,6 +607,23 @@ static List *find_args(String *s, int ismacro, String *macro_name) { skip_tochar(s, '\'', str); c = Getc(s); continue; + } else if (c == '/') { + /* Ensure comments are ignored by eating up the characters */ + c = Getc(s); + if (c == '*') { + while ((c = Getc(s)) != EOF) { + if (c == '*') { + c = Getc(s); + if (c == '/' || c == EOF) + break; + } + } + c = Getc(s); + continue; + } + /* ensure char is available in the stream as this was not a comment*/ + Ungetc(c, s); + c = '/'; } if ((c == ',') && (level == 0)) break; diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c index 9da4e0829..d6e5e0cdc 100644 --- a/Source/Swig/cwrap.c +++ b/Source/Swig/cwrap.c @@ -277,7 +277,7 @@ int Swig_cargs(Wrapper *w, ParmList *p) { SwigType_del_rvalue_reference(tvalue); tycode = SwigType_type(tvalue); if (tycode != T_USER) { - /* plain primitive type, we copy the the def value */ + /* plain primitive type, we copy the def value */ String *lstr = SwigType_lstr(tvalue, defname); defvalue = NewStringf("%s = %s", lstr, qvalue); Delete(lstr); @@ -1024,6 +1024,15 @@ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *clas } } + if (!self && SwigType_isrvalue_reference(Getattr(n, "refqualifier"))) { + String *memory_header = NewString(""); + Setfile(memory_header, Getfile(n)); + Setline(memory_header, Getline(n)); + Swig_fragment_emit(memory_header); + self = NewString("std::move(*this)."); + Delete(memory_header); + } + call = Swig_cmethod_call(explicitcall_name ? explicitcall_name : name, p, self, explicit_qualifier, director_type); cres = Swig_cresult(Getattr(n, "type"), Swig_cresult_name(), call); diff --git a/Source/Swig/error.c b/Source/Swig/error.c index 2c93cfb21..1dde06652 100644 --- a/Source/Swig/error.c +++ b/Source/Swig/error.c @@ -106,13 +106,16 @@ void Swig_warning(int wnum, const_String_or_char_ptr filename, int line, const c } if (warnall || wrn) { String *formatted_filename = format_filename(filename); + String *full_message = NewString(""); if (wnum) { - Printf(stderr, wrn_wnum_fmt, formatted_filename, line, wnum); + Printf(full_message, wrn_wnum_fmt, formatted_filename, line, wnum); } else { - Printf(stderr, wrn_nnum_fmt, formatted_filename, line); + Printf(full_message, wrn_nnum_fmt, formatted_filename, line); } - Printf(stderr, "%s", msg); + Printf(full_message, "%s", msg); + Printv(stderr, full_message, NIL); nwarning++; + Delete(full_message); Delete(formatted_filename); } Delete(out); @@ -128,6 +131,7 @@ void Swig_warning(int wnum, const_String_or_char_ptr filename, int line, const c void Swig_error(const_String_or_char_ptr filename, int line, const char *fmt, ...) { va_list ap; String *formatted_filename = NULL; + String *full_message = NULL; if (silence) return; @@ -136,14 +140,17 @@ void Swig_error(const_String_or_char_ptr filename, int line, const char *fmt, .. va_start(ap, fmt); formatted_filename = format_filename(filename); + full_message = NewString(""); if (line > 0) { - Printf(stderr, err_line_fmt, formatted_filename, line); + Printf(full_message, err_line_fmt, formatted_filename, line); } else { - Printf(stderr, err_eof_fmt, formatted_filename); + Printf(full_message, err_eof_fmt, formatted_filename); } - vPrintf(stderr, fmt, ap); + vPrintf(full_message, fmt, ap); + Printv(stderr, full_message, NIL); va_end(ap); nerrors++; + Delete(full_message); Delete(formatted_filename); } diff --git a/Source/Swig/misc.c b/Source/Swig/misc.c index e3710beac..f209b1170 100644 --- a/Source/Swig/misc.c +++ b/Source/Swig/misc.c @@ -823,10 +823,11 @@ String *Swig_string_emangle(String *s) { /* ----------------------------------------------------------------------------- - * Swig_scopename_prefix() + * Swig_scopename_split() * - * Take a qualified name like "A::B::C" and return the scope name. - * In this case, "A::B". Returns NULL if there is no base. + * Take a qualified name like "A::B::C" and splits off the last name. + * In this case, returns "C" as last and "A::B" as prefix. + * Always returns non NULL for last, but prefix may be NULL if there is no prefix. * ----------------------------------------------------------------------------- */ void Swig_scopename_split(const String *s, String **rprefix, String **rlast) { @@ -882,6 +883,12 @@ void Swig_scopename_split(const String *s, String **rprefix, String **rlast) { } } +/* ----------------------------------------------------------------------------- + * Swig_scopename_prefix() + * + * Take a qualified name like "A::B::C" and return the scope name. + * In this case, "A::B". Returns NULL if there is no base. + * ----------------------------------------------------------------------------- */ String *Swig_scopename_prefix(const String *s) { char *tmp = Char(s); @@ -1067,6 +1074,31 @@ String *Swig_scopename_suffix(const String *s) { } } +/* ----------------------------------------------------------------------------- + * Swig_scopename_tolist() + * + * Take a qualified scope name like "A::B::C" and convert it to a list. + * In this case, return a list of 3 elements "A", "B", "C". + * Returns an empty list if the input is empty. + * ----------------------------------------------------------------------------- */ + +List *Swig_scopename_tolist(const String *s) { + List *scopes = NewList(); + String *name = Len(s) == 0 ? 0 : NewString(s); + + while (name) { + String *last = 0; + String *prefix = 0; + Swig_scopename_split(name, &prefix, &last); + Insert(scopes, 0, last); + Delete(last); + Delete(name); + name = prefix; + } + Delete(name); + return scopes; +} + /* ----------------------------------------------------------------------------- * Swig_scopename_check() * @@ -1117,19 +1149,17 @@ int Swig_scopename_check(const String *s) { * * Printf(stderr,"%(command:sed 's/[a-z]/\U\\1/' <<<)s","hello") -> Hello * ----------------------------------------------------------------------------- */ -#if defined(HAVE_POPEN) -# if defined(_MSC_VER) -# define popen _popen -# define pclose _pclose -# else -extern FILE *popen(const char *command, const char *type); -extern int pclose(FILE *stream); +#if defined(_MSC_VER) +# define popen _popen +# define pclose _pclose +# if !defined(HAVE_POPEN) +# define HAVE_POPEN 1 # endif #else -# if defined(_MSC_VER) -# define HAVE_POPEN 1 -# define popen _popen -# define pclose _pclose +# if !defined(_WIN32) +/* These Posix functions are not ISO C and so are not always defined in stdio.h */ +extern FILE *popen(const char *command, const char *type); +extern int pclose(FILE *stream); # endif #endif @@ -1208,7 +1238,7 @@ String *Swig_string_rstrip(String *s) { String *suffix = NewStringf(fmt, cs+1); int suffix_len = Len(suffix); if (0 == Strncmp(cs+len-suffix_len, suffix, suffix_len)) { - int copy_len = len-suffix_len-(ce+1-cs); + int copy_len = len-suffix_len-(int)(ce+1-cs); ns = NewStringWithSize(ce+1, copy_len); } else { ns = NewString(ce+1); diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c index ce1dbe806..d12770125 100644 --- a/Source/Swig/naming.c +++ b/Source/Swig/naming.c @@ -1681,6 +1681,7 @@ String *Swig_name_str(Node *n) { * "MyNameSpace::MyTemplate::~MyTemplate()" * "MyNameSpace::ABC::ABC(int,double)" * "MyNameSpace::ABC::constmethod(int) const" + * "MyNameSpace::ABC::refqualifiermethod(int) const &" * "MyNameSpace::ABC::variablename" * * ----------------------------------------------------------------------------- */ @@ -1690,11 +1691,22 @@ String *Swig_name_decl(Node *n) { String *decl; qname = Swig_name_str(n); + decl = NewStringf("%s", qname); - if (checkAttribute(n, "kind", "variable")) - decl = NewStringf("%s", qname); - else - decl = NewStringf("%s(%s)%s", qname, ParmList_errorstr(Getattr(n, "parms")), SwigType_isconst(Getattr(n, "decl")) ? " const" : ""); + if (!checkAttribute(n, "kind", "variable")) { + String *d = Getattr(n, "decl"); + Printv(decl, "(", ParmList_errorstr(Getattr(n, "parms")), ")", NIL); + if (SwigType_isfunction(d)) { + SwigType *decl_temp = Copy(d); + SwigType *qualifiers = SwigType_pop_function_qualifiers(decl_temp); + if (qualifiers) { + String *qualifiers_string = SwigType_str(qualifiers, 0); + Printv(decl, " ", qualifiers_string, NIL); + Delete(qualifiers_string); + } + Delete(decl_temp); + } + } Delete(qname); diff --git a/Source/Swig/scanner.c b/Source/Swig/scanner.c index 227a1d00c..f62ddda01 100644 --- a/Source/Swig/scanner.c +++ b/Source/Swig/scanner.c @@ -754,6 +754,10 @@ static int look(Scanner *s) { str_delimiter = 0; return SWIG_TOKEN_STRING; } else { /* Incorrect end delimiter occured */ + if (c == 0) { + Swig_error(cparse_file, cparse_start_line, "Unterminated raw string, started with R\"%s( is not terminated by )%s\"\n", str_delimiter, str_delimiter); + return SWIG_TOKEN_ERROR; + } retract( s, i ); Delete( end_delimiter ); } diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c index a57222745..364329d08 100644 --- a/Source/Swig/stype.c +++ b/Source/Swig/stype.c @@ -44,8 +44,8 @@ * 'z.' = Rvalue reference (&&) * 'a(n).' = Array of size n [n] * 'f(..,..).' = Function with arguments (args) - * 'q(str).' = Qualifier (such as const or volatile) (const, volatile) - * 'm(qual).' = Pointer to member (qual::*) + * 'q(str).' = Qualifier, such as const or volatile (cv-qualifier) + * 'm(cls).' = Pointer to member (cls::*) * * The encoding follows the order that you might describe a type in words. * For example "p.a(200).int" is "A pointer to array of int's" and @@ -62,6 +62,22 @@ * * Replace(t,"q(const).","",DOH_REPLACE_ANY) * + * More examples: + * + * String Encoding C++ Example + * --------------- ----------- + * p.f(bool).r.q(const).long const long & (*)(bool) + * m(Funcs).q(const).f(bool).long long (Funcs::*)(bool) const + * r.q(const).m(Funcs).f(int).long long (Funcs::*const &)(int) + * m(Funcs).z.q(const).f(bool).long long (Funcs::*)(bool) const && + * + * Function decl examples: + * + * f(bool). long a(bool); + * r.f(bool). long b(bool) &; + * z.f(bool). long c(bool) &&; + * z.q(const).f(bool). long d(bool) const &&; + * * For the most part, this module tries to minimize the use of special * characters (*, [, <, etc...) in its type encoding. One reason for this * is that SWIG might be extended to encode data in formats such as XML @@ -372,7 +388,7 @@ SwigType *SwigType_default_create(const SwigType *ty) { * and is very close to the type deduction used in partial template class * specialization matching in that the most specialized type is always chosen. * SWIGTYPE is used as the generic type. The basic idea is to repeatedly call - * this function to find a deduced type unless until nothing matches. + * this function to find a deduced type until nothing matches. * * The type t must have already been converted to the default type via a call to * SwigType_default_create() before calling this function. @@ -528,6 +544,7 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) { String *element = 0; String *nextelement; String *forwardelement; + SwigType *member_function_qualifiers = 0; List *elements; int nelements, i; @@ -560,11 +577,13 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) { forwardelement = 0; } if (SwigType_isqualifier(element)) { - DOH *q = 0; - q = SwigType_parm(element); - Insert(result, 0, " "); - Insert(result, 0, q); - Delete(q); + if (!member_function_qualifiers) { + DOH *q = 0; + q = SwigType_parm(element); + Insert(result, 0, " "); + Insert(result, 0, q); + Delete(q); + } } else if (SwigType_ispointer(element)) { Insert(result, 0, "*"); if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { @@ -580,16 +599,28 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) { Insert(result, 0, "("); Append(result, ")"); } + { + String *next3elements = NewStringEmpty(); + int j; + for (j = i + 1; j < i + 4 && j < nelements; j++) { + Append(next3elements, Getitem(elements, j)); + } + if (SwigType_isfunction(next3elements)) + member_function_qualifiers = SwigType_pop_function_qualifiers(next3elements); + Delete(next3elements); + } Delete(q); } else if (SwigType_isreference(element)) { - Insert(result, 0, "&"); + if (!member_function_qualifiers) + Insert(result, 0, "&"); if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { Insert(result, 0, "("); Append(result, ")"); } } else if (SwigType_isrvalue_reference(element)) { - Insert(result, 0, "&&"); - if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { + if (!member_function_qualifiers) + Insert(result, 0, "&&"); + if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { Insert(result, 0, "("); Append(result, ")"); } @@ -613,6 +644,14 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) { Append(result, ","); } Append(result, ")"); + if (member_function_qualifiers) { + String *p = SwigType_str(member_function_qualifiers, 0); + Append(result, " "); + Append(result, p); + Delete(p); + Delete(member_function_qualifiers); + member_function_qualifiers = 0; + } Delete(parms); } else { if (strcmp(Char(element), "v(...)") == 0) { @@ -645,6 +684,7 @@ SwigType *SwigType_ltype(const SwigType *s) { int nelements, i; int firstarray = 1; int notypeconv = 0; + int ignore_member_function_qualifiers = 0; result = NewStringEmpty(); tc = Copy(s); @@ -671,6 +711,7 @@ SwigType *SwigType_ltype(const SwigType *s) { tc = td; } } + elements = SwigType_split(tc); nelements = Len(elements); @@ -680,14 +721,33 @@ SwigType *SwigType_ltype(const SwigType *s) { /* when we see a function, we need to preserve the following types */ if (SwigType_isfunction(element)) { notypeconv = 1; + ignore_member_function_qualifiers = 0; } - if (SwigType_isqualifier(element)) { - /* Do nothing. Ignore */ + if (ignore_member_function_qualifiers) { + /* cv-qualifiers and ref-qualifiers up until the f() element have already been added */ + } else if (SwigType_isqualifier(element)) { + /* swallow cv-qualifiers */ } else if (SwigType_ispointer(element)) { Append(result, element); firstarray = 0; } else if (SwigType_ismemberpointer(element)) { Append(result, element); + { + String *next3elements = NewStringEmpty(); + int j; + for (j = i + 1; j < i + 4 && j < nelements; j++) { + Append(next3elements, Getitem(elements, j)); + } + if (SwigType_isfunction(next3elements)) { + SwigType *member_function_qualifiers = SwigType_pop_function_qualifiers(next3elements); + /* compilers won't let us cast from a member function without qualifiers to one with qualifiers, so the qualifiers are kept in the ltype */ + if (member_function_qualifiers) + Append(result, member_function_qualifiers); + Delete(member_function_qualifiers); + ignore_member_function_qualifiers = 1; + } + Delete(next3elements); + } firstarray = 0; } else if (SwigType_isreference(element)) { if (notypeconv) { @@ -727,13 +787,14 @@ SwigType *SwigType_ltype(const SwigType *s) { } /* ----------------------------------------------------------------------------- - * SwigType_lstr(DOH *s, DOH *id) + * SwigType_lstr() * * Produces a type-string that is suitable as a lvalue in an expression. * That is, a type that can be freely assigned a value without violating * any C assignment rules. * * - Qualifiers such as 'const' and 'volatile' are stripped. + * Except for member function cv-qualifiers and ref-qualifiers. * - Arrays are converted into a *single* pointer (i.e., * double [][] becomes double *). * - References are converted into a pointer. @@ -763,6 +824,7 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) { String *element = 0; String *nextelement; String *forwardelement; + String *member_function_qualifiers = 0; SwigType *td, *tc = 0; const SwigType *rs; List *elements; @@ -777,7 +839,10 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) { if (SwigType_isconst(s)) { tc = Copy(s); Delete(SwigType_pop(tc)); - rs = tc; + if (SwigType_ismemberpointer(tc)) + rs = s; + else + rs = tc; } else { rs = s; } @@ -816,12 +881,14 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) { forwardelement = 0; } if (SwigType_isqualifier(element)) { - DOH *q = 0; - q = SwigType_parm(element); - Insert(result, 0, " "); - Insert(result, 0, q); - Delete(q); - clear = 0; + if (!member_function_qualifiers) { + DOH *q = 0; + q = SwigType_parm(element); + Insert(result, 0, " "); + Insert(result, 0, q); + Delete(q); + clear = 0; + } } else if (SwigType_ispointer(element)) { Insert(result, 0, "*"); if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { @@ -834,28 +901,42 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) { Insert(result, 0, "::*"); q = SwigType_parm(element); Insert(result, 0, q); - Delete(q); if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { Insert(result, 0, "("); Append(result, ")"); } + { + String *next3elements = NewStringEmpty(); + int j; + for (j = i + 1; j < i + 4 && j < nelements; j++) { + Append(next3elements, Getitem(elements, j)); + } + if (SwigType_isfunction(next3elements)) + member_function_qualifiers = SwigType_pop_function_qualifiers(next3elements); + Delete(next3elements); + } firstarray = 0; + Delete(q); } else if (SwigType_isreference(element)) { - Insert(result, 0, "&"); + if (!member_function_qualifiers) { + Insert(result, 0, "&"); + if (!isfunction) + isreference = 1; + } if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { Insert(result, 0, "("); Append(result, ")"); } - if (!isfunction) - isreference = 1; } else if (SwigType_isrvalue_reference(element)) { - Insert(result, 0, "&&"); + if (!member_function_qualifiers) { + Insert(result, 0, "&&"); + if (!isfunction) + isreference = 1; + } if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { Insert(result, 0, "("); Append(result, ")"); } - if (!isfunction) - isreference = 1; clear = 0; } else if (SwigType_isarray(element)) { DOH *size; @@ -885,6 +966,15 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) { } Append(result, ")"); Delete(parms); + if (member_function_qualifiers) { + String *p = SwigType_str(member_function_qualifiers, 0); + Append(result, " "); + Append(result, p); + Delete(p); + Delete(member_function_qualifiers); + member_function_qualifiers = 0; + clear = 0; + } isfunction = 1; } else { String *bs = SwigType_namestr(element); diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index cc17a3fd5..bca2a51df 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -136,6 +136,7 @@ extern "C" { extern SwigType *SwigType_add_function(SwigType *t, ParmList *parms); extern SwigType *SwigType_add_template(SwigType *t, ParmList *parms); extern SwigType *SwigType_pop_function(SwigType *t); + extern SwigType *SwigType_pop_function_qualifiers(SwigType *t); extern ParmList *SwigType_function_parms(const SwigType *t, Node *file_line_node); extern List *SwigType_split(const SwigType *t); extern String *SwigType_pop(SwigType *t); @@ -326,6 +327,7 @@ extern int ParmList_is_compactdefargs(ParmList *p); extern String *Swig_scopename_last(const String *s); extern String *Swig_scopename_first(const String *s); extern String *Swig_scopename_suffix(const String *s); + extern List *Swig_scopename_tolist(const String *s); extern int Swig_scopename_check(const String *s); extern String *Swig_string_lower(String *s); extern String *Swig_string_upper(String *s); diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c index c548a0670..965a84472 100644 --- a/Source/Swig/symbol.c +++ b/Source/Swig/symbol.c @@ -599,7 +599,7 @@ void Swig_symbol_cadd(const_String_or_char_ptr name, Node *n) { Setattr(ccurrent, name, n); } - /* Multiple entries in the C symbol table. We append to to the symbol table */ + /* Multiple entries in the C symbol table. We append to the symbol table */ if (append) { Node *fn, *pn = 0; cn = Getattr(ccurrent, name); diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index 8970c719d..c0f5397c1 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -61,13 +61,44 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper static Hash *typemaps; +/* ----------------------------------------------------------------------------- + * typemap_identifier_fix() + * + * Create a type that can be used as a hash key lookup independent of the various + * ways a template parameter list can be defined. This is achieved by fully + * resolving the template parameters. + * + * This is a copy and modification of feature_identifier_fix in parser.y. + * ----------------------------------------------------------------------------- */ + +static SwigType *typemap_identifier_fix(const SwigType *s) { + String *tp = SwigType_istemplate_templateprefix(s); + if (tp) { + String *ts, *ta, *tq, *tr; + ts = SwigType_templatesuffix(s); + ta = SwigType_templateargs(s); + tq = Swig_symbol_type_qualify(ta, 0); + tr = SwigType_typedef_resolve_all(ta); + Append(tp,tr); + Append(tp,ts); + Delete(ts); + Delete(ta); + Delete(tq); + Delete(tr); + return tp; + } else { + return NewString(s); + } +} + static Hash *get_typemap(const SwigType *type) { Hash *tm = 0; SwigType *dtype = 0; SwigType *hashtype; if (SwigType_istemplate(type)) { - String *ty = Swig_symbol_template_deftype(type, 0); + SwigType *rty = typemap_identifier_fix(type); + String *ty = Swig_symbol_template_deftype(rty, 0); dtype = Swig_symbol_type_qualify(ty, 0); type = dtype; Delete(ty); @@ -88,7 +119,7 @@ static void set_typemap(const SwigType *type, Hash **tmhash) { Hash *new_tm = 0; assert(*tmhash == 0); if (SwigType_istemplate(type)) { - SwigType *rty = SwigType_typedef_resolve_all(type); + SwigType *rty = typemap_identifier_fix(type); String *ty = Swig_symbol_template_deftype(rty, 0); String *tyq = Swig_symbol_type_qualify(ty, 0); hashtype = SwigType_remove_global_scope_prefix(tyq); @@ -733,6 +764,7 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type SwigType *oldctype = ctype; ctype = SwigType_typedef_resolve(ctype_unstripped); Delete(oldctype); + Delete(ctype_unstripped); ctype_unstripped = Copy(ctype); } } diff --git a/Source/Swig/typeobj.c b/Source/Swig/typeobj.c index b2832b6a9..7a0626c29 100644 --- a/Source/Swig/typeobj.c +++ b/Source/Swig/typeobj.c @@ -43,12 +43,12 @@ * All type constructors are denoted by a trailing '.': * * 'p.' = Pointer (*) - * 'r.' = Reference (&) - * 'z.' = Rvalue reference (&&) + * 'r.' = Reference or ref-qualifier (&) + * 'z.' = Rvalue reference or ref-qualifier (&&) * 'a(n).' = Array of size n [n] * 'f(..,..).' = Function with arguments (args) - * 'q(str).' = Qualifier (such as const or volatile) (const, volatile) - * 'm(qual).' = Pointer to member (qual::*) + * 'q(str).' = Qualifier, such as const or volatile (cv-qualifier) + * 'm(cls).' = Pointer to member (cls::*) * * The complete type representation for varargs is: * 'v(...)' @@ -183,9 +183,10 @@ SwigType *SwigType_del_element(SwigType *t) { * SwigType_pop() * * Pop one type element off the type. - * Example: t in: q(const).p.Integer - * t out: p.Integer - * result: q(const). + * For example: + * t in: q(const).p.Integer + * t out: p.Integer + * result: q(const). * ----------------------------------------------------------------------------- */ SwigType *SwigType_pop(SwigType *t) { @@ -771,7 +772,6 @@ SwigType *SwigType_array_type(const SwigType *ty) { * Functions * * SwigType_add_function() - * SwigType_del_function() * SwigType_isfunction() * SwigType_pop_function() * @@ -795,14 +795,36 @@ SwigType *SwigType_add_function(SwigType *t, ParmList *parms) { return t; } +/* ----------------------------------------------------------------------------- + * SwigType_pop_function() + * + * Pop and return the function from the input type leaving the function's return + * type, if any. + * For example: + * t in: q(const).f().p. + * t out: p. + * result: q(const).f(). + * ----------------------------------------------------------------------------- */ + SwigType *SwigType_pop_function(SwigType *t) { SwigType *f = 0; SwigType *g = 0; char *c = Char(t); - if (strncmp(c, "q(", 2) == 0) { + if (strncmp(c, "r.", 2) == 0 || strncmp(c, "z.", 2) == 0) { + /* Remove ref-qualifier */ f = SwigType_pop(t); c = Char(t); } + if (strncmp(c, "q(", 2) == 0) { + /* Remove cv-qualifier */ + String *qual = SwigType_pop(t); + if (f) { + SwigType_push(qual, f); + Delete(f); + } + f = qual; + c = Char(t); + } if (strncmp(c, "f(", 2)) { printf("Fatal error. SwigType_pop_function applied to non-function.\n"); abort(); @@ -814,14 +836,55 @@ SwigType *SwigType_pop_function(SwigType *t) { return g; } +/* ----------------------------------------------------------------------------- + * SwigType_pop_function_qualifiers() + * + * Pop and return the function qualifiers from the input type leaving the rest of + * function declaration. Returns NULL if no qualifiers. + * For example: + * t in: r.q(const).f().p. + * t out: f().p. + * result: r.q(const) + * ----------------------------------------------------------------------------- */ + +SwigType *SwigType_pop_function_qualifiers(SwigType *t) { + SwigType *qualifiers = 0; + char *c = Char(t); + if (strncmp(c, "r.", 2) == 0 || strncmp(c, "z.", 2) == 0) { + /* Remove ref-qualifier */ + String *qual = SwigType_pop(t); + qualifiers = qual; + c = Char(t); + } + if (strncmp(c, "q(", 2) == 0) { + /* Remove cv-qualifier */ + String *qual = SwigType_pop(t); + if (qualifiers) { + SwigType_push(qual, qualifiers); + Delete(qualifiers); + } + qualifiers = qual; + c = Char(t); + } + assert(strncmp(c, "f(", 2) == 0); + + return qualifiers; +} + int SwigType_isfunction(const SwigType *t) { char *c; if (!t) { return 0; } c = Char(t); + if (strncmp(c, "r.", 2) == 0 || strncmp(c, "z.", 2) == 0) { + /* Might be a function with a ref-qualifier, skip over */ + c += 2; + if (!*c) + return 0; + } if (strncmp(c, "q(", 2) == 0) { - /* Might be a 'const' function. Try to skip over the 'const' */ + /* Might be a function with a cv-qualifier, skip over */ c = strchr(c, '.'); if (c) c++; diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c index e11fc781a..409e28f35 100644 --- a/Source/Swig/typesys.c +++ b/Source/Swig/typesys.c @@ -42,10 +42,15 @@ * "name" - Scope name * "qname" - Fully qualified typename * "typetab" - Type table containing typenames and typedef information + * For a given key in the typetab table, the value is a fully + * qualified name if not pointing to itself. * "symtab" - Hash table of symbols defined in a scope * "inherit" - List of inherited scopes * "parent" - Parent scope * + * The contents of these tables can be viewed for debugging using the -debug-typedef + * option which calls SwigType_print_scope(). + * * Typedef information is stored in the "typetab" hash table. For example, * if you have these declarations: * @@ -53,8 +58,7 @@ * typedef A B; * typedef B *C; * - * typetab is built as follows: - * + * typetab in scope '' contains: * "A" : "int" * "B" : "A" * "C" : "p.B" @@ -67,31 +71,76 @@ * ---> a(40).p.p.A (B --> A) * ---> a(40).p.p.int (A --> int) * + * + * Using declarations are stored in the "typetab" hash table. For example, + * + * namespace NN { + * struct SS {}; + * } + * namespace N { + * struct S {}; + * using NN::SS; + * } + * using N::S; + * + * typetab in scope '' contains: + * "S" : "N::S" + * + * and typetab in scope 'N' contains: + * "SS" : "NN::SS" + * "S" : "S" + * + * * For inheritance, SWIG tries to resolve types back to the base class. For instance, if * you have this: * - * class Foo { - * public: - * typedef int Integer; - * }; + * class Foo { + * public: + * typedef int Integer; + * }; + * struct Bar : public Foo { + * void blah(Integer x); + * }; * - * class Bar : public Foo { - * void blah(Integer x); - * }; + * In this case typetab in scope '' contains: + * "Foo" : "Foo" + * "Bar" : "Bar" + * and scope 'Foo' contains: + * "Integer" : "int" + * and scope 'Bar' inherits from 'Foo' but is empty (observe that blah is not a scope or typedef) * * The argument type of Bar::blah will be set to Foo::Integer. * + * + * The scope-inheritance mechanism is used to manage C++ using directives. + * + * namespace XX { + * class CC {}; + * } + * namespace X { + * class C {}; + * using namespace XX; + * } + * using namespace X; + * + * typetab in scope '' inherits from 'X' + * typetab in scope 'X' inherits from 'XX' and contains: + * "C" : "C" + * typetab in scope 'XX' contains: + * "CC" : "CC" + * + * * The scope-inheritance mechanism is used to manage C++ namespace aliases. * For example, if you have this: * - * namespace Foo { - * typedef int Integer; - * } + * namespace Foo { + * typedef int Integer; + * } * - * namespace F = Foo; + * namespace F = Foo; * - * In this case, "F::" is defined as a scope that "inherits" from Foo. Internally, - * "F::" will merely be an empty scope that refers to Foo. SWIG will never + * In this case, F is defined as a scope that "inherits" from Foo. Internally, + * F will merely be an empty scope that points to Foo. SWIG will never * place new type information into a namespace alias---attempts to do so * will generate a warning message (in the parser) and will place information into * Foo instead. @@ -166,6 +215,7 @@ void SwigType_typesystem_init() { * ----------------------------------------------------------------------------- */ int SwigType_typedef(const SwigType *type, const_String_or_char_ptr name) { + /* Printf(stdout, "typedef %s %s\n", type, name); */ if (Getattr(current_typetab, name)) return -1; /* Already defined */ if (Strcmp(type, name) == 0) { /* Can't typedef a name to itself */ @@ -248,10 +298,26 @@ void SwigType_new_scope(const_String_or_char_ptr name) { ttab = NewHash(); Setattr(s, "typetab", ttab); - /* Build fully qualified name and */ + /* Build fully qualified name */ qname = SwigType_scope_name(s); +#if 1 + { + /* TODO: only do with templates? What happens with non-templates with code below? */ + String *stripped_qname; + stripped_qname = SwigType_remove_global_scope_prefix(qname); + /* Use fully qualified name for hash key without unary scope prefix, qname may contain unary scope */ + Setattr(scopes, stripped_qname, s); + Setattr(s, "qname", qname); + /* + Printf(stdout, "SwigType_new_scope stripped %s %s\n", qname, stripped_qname); + */ + Delete(stripped_qname); + } +#else + Printf(stdout, "SwigType_new_scope %s\n", qname); Setattr(scopes, qname, s); Setattr(s, "qname", qname); +#endif Delete(qname); current_scope = s; @@ -418,12 +484,14 @@ static Typetab *SwigType_find_scope(Typetab *s, const SwigType *nameprefix) { Typetab *s_orig = s; String *nnameprefix = 0; static int check_parent = 1; + int is_template = 0; if (Getmark(s)) return 0; Setmark(s, 1); - if (SwigType_istemplate(nameprefix)) { + is_template = SwigType_istemplate(nameprefix); + if (is_template) { nnameprefix = SwigType_typedef_resolve_all(nameprefix); nameprefix = nnameprefix; } @@ -437,10 +505,12 @@ static Typetab *SwigType_find_scope(Typetab *s, const SwigType *nameprefix) { } else { full = NewString(nameprefix); } - if (Getattr(scopes, full)) { - s = Getattr(scopes, full); - } else { - s = 0; + s = Getattr(scopes, full); + if (!s && is_template) { + /* try look up scope with all the unary scope operators within the template parameter list removed */ + SwigType *full_stripped = SwigType_remove_global_scope_prefix(full); + s = Getattr(scopes, full_stripped); + Delete(full_stripped); } Delete(full); if (s) { @@ -541,8 +611,11 @@ static SwigType *_typedef_resolve(Typetab *s, String *base, int look_parent) { /* ----------------------------------------------------------------------------- * template_parameters_resolve() * - * For use with templates only. The template parameters are resolved. If none - * of the parameters can be resolved, zero is returned. + * For use with templates only. Attempts to resolve one template parameter. + * + * If one of the template parameters can be resolved, the type is returned with + * just the one parameter resolved and the remaining parameters left as is. + * If none of the template parameters can be resolved, zero is returned. * ----------------------------------------------------------------------------- */ static String *template_parameters_resolve(const String *base) { @@ -574,14 +647,15 @@ static String *template_parameters_resolve(const String *base) { if ((i + 1) < sz) Append(type, ","); } - Append(type, ")>"); - Append(type, suffix); - Delete(suffix); - Delete(tparms); - if (!rep) { + if (rep) { + Append(type, ")>"); + Append(type, suffix); + } else { Delete(type); type = 0; } + Delete(suffix); + Delete(tparms); return type; } @@ -592,6 +666,17 @@ static SwigType *typedef_resolve(Typetab *s, String *base) { /* ----------------------------------------------------------------------------- * SwigType_typedef_resolve() + * + * Given a type declaration, this function looks to reduce/resolve the type via a + * typedef (including via C++ using declarations). + * + * If it is able to find a typedef, the resolved type is returned. If no typedef + * is found NULL is returned. The type name is resolved in the current scope. + * The type returned is not always fully qualified for the global scope, it is + * valid for use in the current scope. If the current scope is global scope, a + * fully qualified type should be returned. + * + * Some additional notes are in Doc/Manual/Extending.html. * ----------------------------------------------------------------------------- */ /* #define SWIG_DEBUG */ @@ -718,6 +803,25 @@ SwigType *SwigType_typedef_resolve(const SwigType *t) { } } + if (!type && SwigType_istemplate(base)) { + String *tprefix = SwigType_templateprefix(base); + String *rtprefix = SwigType_typedef_resolve(tprefix); + /* We're looking for a using declaration on the template prefix to resolve the template prefix + * in another scope. Using declaration do not have template parameters. */ + if (rtprefix && !SwigType_istemplate(rtprefix)) { + String *tsuffix = SwigType_templatesuffix(base); + String *targs = SwigType_templateargs(base); + type = NewString(rtprefix); + newtype = 1; + Append(type, targs); + Append(type, tsuffix); + Delete(targs); + Delete(tsuffix); + Delete(rtprefix); + } + Delete(tprefix); + } + if (type && (Equal(base, type))) { if (newtype) Delete(type); @@ -911,6 +1015,9 @@ SwigType *SwigType_typedef_resolve_all(const SwigType *t) { return Copy(r); } +#ifdef SWIG_DEBUG + Printf(stdout, "SwigType_typedef_resolve_all start ... %s\n", t); +#endif /* Recursively resolve the typedef */ r = NewString(t); while ((n = SwigType_typedef_resolve(r))) { @@ -931,6 +1038,9 @@ SwigType *SwigType_typedef_resolve_all(const SwigType *t) { Delete(key); Delete(rr); } +#ifdef SWIG_DEBUG + Printf(stdout, "SwigType_typedef_resolve_all end === %s => %s\n", t, r); +#endif return r; } @@ -938,8 +1048,17 @@ SwigType *SwigType_typedef_resolve_all(const SwigType *t) { /* ----------------------------------------------------------------------------- * SwigType_typedef_qualified() * - * Given a type declaration, this function tries to fully qualify it according to - * typedef scope rules. + * Given a type declaration, this function tries to fully qualify it so that the + * resulting type can be used in the global scope. The type name is resolved in + * the current scope. + * + * It provides a fully qualified name, not necessarily a fully expanded name. + * When a using declaration or using directive is found the type may not be fully + * expanded, but it will be resolved and fully qualified for use in the global scope. + * + * This function is for looking up scopes to qualify a type. It does not resolve + * C typedefs, it just qualifies them. See SwigType_typedef_resolve for resolving. + * * If the unary scope operator (::) is used as a prefix to the type to denote global * scope, it is left in place. * ----------------------------------------------------------------------------- */ @@ -1000,20 +1119,14 @@ SwigType *SwigType_typedef_qualified(const SwigType *t) { out of the current scope */ Typetab *cs = current_scope; - while (cs) { - String *qs = SwigType_scope_name(cs); - if (Len(qs)) { - Append(qs, "::"); - } - Append(qs, e); - if (Getattr(scopes, qs)) { + if (cs) { + Typetab *found_scope = SwigType_find_scope(cs, e); + if (found_scope) { + String *qs = SwigType_scope_name(found_scope); Clear(e); Append(e, qs); Delete(qs); - break; } - Delete(qs); - cs = Getattr(cs, "parent"); } } } @@ -1029,10 +1142,6 @@ SwigType *SwigType_typedef_qualified(const SwigType *t) { Parm *p; List *parms; ty = Swig_symbol_template_deftype(e, current_symtab); - /* - String *dt = Swig_symbol_template_deftype(e, current_symtab); - ty = Swig_symbol_type_qualify(dt, 0); - */ e = ty; parms = SwigType_parmlist(e); tprefix = SwigType_templateprefix(e); @@ -1099,9 +1208,6 @@ SwigType *SwigType_typedef_qualified(const SwigType *t) { Delete(tprefix); Delete(qprefix); Delete(parms); - /* - Delete(dt); - */ } Append(result, e); Delete(ty); @@ -1181,7 +1287,7 @@ int SwigType_typedef_using(const_String_or_char_ptr name) { String *defined_name = 0; - /* Printf(stdout,"using %s\n", name); */ + /* Printf(stdout, "using %s\n", name); */ if (!Swig_scopename_check(name)) return -1; /* Not properly qualified */ diff --git a/Tools/nuget-install.cmd b/Tools/nuget-install.cmd index 08caea7e0..eec7f8787 100644 --- a/Tools/nuget-install.cmd +++ b/Tools/nuget-install.cmd @@ -1,5 +1,4 @@ rem Workaround 'nuget install' not being reliable by retrying a few times - @echo off rem initiate the retry number set errorCode=1 @@ -13,6 +12,7 @@ rem problem? IF ERRORLEVEL %errorCode% GOTO :RETRY rem everything is fine! +@echo Installed nuget, retries: %reTryNumber% GOTO :EXIT :RETRY diff --git a/Tools/travis-linux-install.sh b/Tools/travis-linux-install.sh index 2510a791f..4a958dfb8 100755 --- a/Tools/travis-linux-install.sh +++ b/Tools/travis-linux-install.sh @@ -3,108 +3,113 @@ set -e # exit on failure (same as -o errexit) lsb_release -a -sudo apt-get -qq update +travis_retry sudo apt-get -qq update if [[ "$CC" == gcc-5 ]]; then - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test - sudo apt-get -qq update - sudo apt-get install -qq g++-5 + travis_retry sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + travis_retry sudo apt-get -qq update + travis_retry sudo apt-get install -qq g++-5 elif [[ "$CC" == gcc-6 ]]; then - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test - sudo apt-get -qq update - sudo apt-get install -qq g++-6 + travis_retry sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + travis_retry sudo apt-get -qq update + travis_retry sudo apt-get install -qq g++-6 fi -sudo apt-get -qq install libboost-dev +travis_retry sudo apt-get -qq install libboost-dev WITHLANG=$SWIGLANG case "$SWIGLANG" in "") ;; "csharp") - sudo apt-get -qq install mono-devel + travis_retry sudo apt-get -qq install mono-devel ;; "d") - wget http://downloads.dlang.org/releases/2014/dmd_2.066.0-0_amd64.deb - sudo dpkg -i dmd_2.066.0-0_amd64.deb + 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 ;; "go") ;; "javascript") case "$ENGINE" in "node") - sudo add-apt-repository -y ppa:chris-lea/node.js - sudo apt-get -qq update - sudo apt-get install -qq nodejs rlwrap - sudo npm install -g node-gyp + travis_retry sudo apt-get install -qq nodejs node-gyp ;; "jsc") - sudo apt-get install -qq libwebkitgtk-dev + travis_retry sudo apt-get install -qq libwebkitgtk-dev ;; "v8") - sudo apt-get install -qq libv8-dev + travis_retry sudo apt-get install -qq libv8-dev ;; esac ;; "guile") - sudo apt-get -qq install guile-2.0-dev + travis_retry sudo apt-get -qq install guile-2.0-dev ;; "lua") if [[ -z "$VER" ]]; then - sudo apt-get -qq install lua5.2 liblua5.2-dev + travis_retry sudo apt-get -qq install lua5.2 liblua5.2-dev else - sudo add-apt-repository -y ppa:ubuntu-cloud-archive/mitaka-staging - sudo apt-get -qq update - sudo apt-get -qq install lua${VER} liblua${VER}-dev + travis_retry sudo add-apt-repository -y ppa:ubuntu-cloud-archive/mitaka-staging + travis_retry sudo apt-get -qq update + travis_retry sudo apt-get -qq install lua${VER} liblua${VER}-dev fi ;; "ocaml") # configure also looks for ocamldlgen, but this isn't packaged. But it isn't used by default so this doesn't matter. - sudo apt-get -qq install ocaml ocaml-findlib + travis_retry sudo apt-get -qq install ocaml ocaml-findlib ;; "octave") if [[ -z "$VER" ]]; then - sudo apt-get -qq install liboctave-dev + travis_retry sudo apt-get -qq install liboctave-dev else - sudo add-apt-repository -y ppa:kwwette/octaves - sudo apt-get -qq update - sudo apt-get -qq install liboctave${VER}-dev + # 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 ;; "php5") - sudo apt-get -qq install php5-cli php5-dev + travis_retry sudo apt-get -qq install php5-cli php5-dev ;; "php") - sudo add-apt-repository -y ppa:ondrej/php - sudo apt-get -qq update - sudo apt-get -qq install php$VER-cli php$VER-dev + travis_retry sudo add-apt-repository -y ppa:ondrej/php + travis_retry sudo apt-get -qq update + travis_retry sudo apt-get -qq install php$VER-cli php$VER-dev ;; "python") - pip install pep8 + pip install --user pep8 if [[ "$PY3" ]]; then - sudo apt-get install -qq python3-dev + travis_retry sudo apt-get install -qq python3-dev fi WITHLANG=$SWIGLANG$PY3 if [[ "$VER" ]]; then - sudo add-apt-repository -y ppa:fkrull/deadsnakes - sudo apt-get -qq update - sudo apt-get -qq install python${VER}-dev + travis_retry sudo add-apt-repository -y ppa:fkrull/deadsnakes + travis_retry sudo apt-get -qq update + travis_retry sudo apt-get -qq install python${VER}-dev WITHLANG=$SWIGLANG$PY3=$SWIGLANG$VER fi ;; "r") - sudo apt-get -qq install r-base + travis_retry sudo apt-get -qq install r-base ;; "ruby") if [[ "$VER" ]]; then - rvm install $VER + travis_retry rvm install $VER fi ;; "scilab") - sudo apt-get -qq install scilab + travis_retry sudo apt-get -qq install scilab ;; "tcl") - sudo apt-get -qq install tcl-dev + travis_retry sudo apt-get -qq install tcl-dev ;; esac diff --git a/Tools/travis-osx-install.sh b/Tools/travis-osx-install.sh index 85183722b..42cc33bb2 100755 --- a/Tools/travis-osx-install.sh +++ b/Tools/travis-osx-install.sh @@ -3,28 +3,28 @@ set -e # exit on failure (same as -o errexit) sw_vers -brew update -brew list -# brew install pcre # Travis Xcode-7.3 has pcre -# brew install boost +travis_retry brew update +travis_retry brew list +# travis_retry brew install pcre # Travis Xcode-7.3 has pcre +# travis_retry brew install boost WITHLANG=$SWIGLANG case "$SWIGLANG" in "csharp") - brew install mono + travis_retry brew install mono ;; "guile") - Tools/brew-install guile + travis_retry Tools/brew-install guile ;; "lua") - brew install lua + travis_retry brew install lua ;; "python") WITHLANG=$SWIGLANG$PY3 if [[ "$PY3" ]]; then - brew install python3 - brew list -v python3 + travis_retry brew install python3 + travis_retry brew list -v python3 fi ;; esac diff --git a/appveyor.yml b/appveyor.yml index d7be4a3d5..74b1c045d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,6 +3,9 @@ platform: - x64 environment: + global: + MAKEJOBS: 2 + matrix: - SWIGLANG: csharp VSVER: 12 @@ -15,64 +18,99 @@ environment: VER: 27 - SWIGLANG: python VSVER: 14 - VER: 35 + VER: 36 PY3: 1 + - SWIGLANG: python + OSVARIANT: cygwin + - SWIGLANG: python + OSVARIANT: mingw install: - date /T & time /T -- set PATH=C:\cygwin\bin;%PATH% -- set CYGWIN=nodosfilewarning -- git clone -q --depth=1 --single-branch --branch cccl-1.0 git://github.com/swig/cccl.git C:\cccl-1.0 -- bash -c "cp C:/cccl-1.0/cccl /usr/bin" - ps: >- - If ($env:Platform -Match "x86") { + if ($env:Platform -eq "x86") { $env:PCRE_PLATFORM="Win32" $env:JAVA_HOME="C:/Program Files (x86)/Java/jdk1.8.0" $env:VCVARS_PLATFORM="x86" $env:LANG_PLATFORM="" - } Else { + $env:CYGWINBIN="C:\cygwin\bin" + $env:CYGWINSETUP="C:/cygwin/setup-x86.exe" + $env:MSYSBIN="C:\msys64\usr\bin" + $env:MINGWBIN="C:\msys64\mingw32\bin" + $env:MBITS="32" + $env:MARCH="i686" + } else { $env:PCRE_PLATFORM="x64" $env:JAVA_HOME="C:/Program Files/Java/jdk1.8.0" $env:VCVARS_PLATFORM="amd64" $env:LANG_PLATFORM="-x64" + $env:CYGWINBIN="C:\cygwin64\bin" + $env:CYGWINSETUP="C:/cygwin64/setup-x86_64.exe" + $env:MSYSBIN="C:\msys64\usr\bin" + $env:MINGWBIN="C:\msys64\mingw64\bin" + $env:MBITS="64" + $env:MARCH="x86_64" } -- ps: $env:VSCOMNTOOLS=(Get-Content ("env:VS" + "$env:VSVER" + "0COMNTOOLS")) -- echo "Using Visual Studio %VSVER%.0 at %VSCOMNTOOLS%" -- call "%VSCOMNTOOLS%\..\..\VC\vcvarsall.bat" %VCVARS_PLATFORM% -- Tools\nuget-install.cmd pcre -Verbosity detailed -Version 8.33.0.1 -OutputDirectory C:\pcre -- set PCRE_ROOT=C:/pcre/pcre.8.33.0.1/build/native -- set PATH=C:\Python%VER%%LANG_PLATFORM%;%PATH% -- python -V +- ps: >- + if (!$env:OSVARIANT) { + $env:PATH="$env:CYGWINBIN;$env:PATH" + $env:CYGWIN="nodosfilewarning" + $env:VSCOMNTOOLS=(Get-Content ("env:VS" + "$env:VSVER" + "0COMNTOOLS")) + $env:CC="cccl" + $env:CXX="cccl" + } elseif ($env:OSVARIANT -eq "cygwin") { + $env:PATH="$env:CYGWINBIN;$env:PATH" + $env:CYGWIN="nodosfilewarning" + $env:CC="gcc" + $env:CXX="g++" + } elseif ($env:OSVARIANT -eq "mingw") { + $env:PATH="$env:MSYSBIN;$env:MINGWBIN;$env:PATH" + $env:MSYSTEM="MINGW$env:MBITS" + $env:CC="$env:MARCH-w64-mingw32-gcc" + $env:CXX="$env:MARCH-w64-mingw32-g++" + } +- if "%OSVARIANT%"=="" bash -c "cd /usr/bin && curl --retry 15 -s -L https://github.com/swig/cccl/archive/cccl-1.0.tar.gz | tar -xz --strip 1 cccl-cccl-1.0/cccl" +- if "%OSVARIANT%"=="" echo Using Visual Studio %VSVER%.0 at %VSCOMNTOOLS% +- if "%OSVARIANT%"=="" call "%VSCOMNTOOLS%\..\..\VC\vcvarsall.bat" %VCVARS_PLATFORM% +- if "%OSVARIANT%"=="" Tools\nuget-install.cmd pcre -Verbosity quiet -Version 8.33.0.1 -OutputDirectory C:\pcre +- if "%OSVARIANT%"=="" set PCRE_ROOT=C:/pcre/pcre.8.33.0.1/build/native +- if "%OSVARIANT%"=="" set PATH=C:\Python%VER%%LANG_PLATFORM%;%PATH% +- if "%OSVARIANT%"=="" bash -c "which cl.exe" +- if "%OSVARIANT%"=="" bash -c "cl.exe /? 2>&1 | head -n 1" +- if "%OSVARIANT%"=="" bash -c "which csc.exe" +- if "%OSVARIANT%"=="" bash -c "csc.exe /? | head -n 1" +- if "%OSVARIANT%"=="cygwin" %CYGWINSETUP% --quiet-mode --packages python-devel,libpcre-devel,libboost-devel > cygwin-install.txt || bash -c "cat cygwin-install.txt" +- if "%OSVARIANT%"=="mingw" bash -c "pacman --noconfirm --sync mingw%MBITS%/mingw-w64-%MARCH%-pcre mingw%MBITS%/mingw-w64-%MARCH%-boost" +- bash -c "which $CC" +- bash -c "which $CXX" +- bash -c "$CC --version | head -n 1" +- bash -c "$CXX --version | head -n 1" - bash -c "which python" - bash -c "python -V" -- bash -c "which cl.exe" -- bash -c "cl.exe /? 2>&1 | head -n 2" -- bash -c "which csc.exe" -- bash -c "csc.exe /? | head -n 2" -- bash -c "which cccl" -- bash -c "cccl --version" -- make --version +- bash -c "make --version | head -n 2" +- pwd +- echo MAKEJOBS=%MAKEJOBS% - uname -a build_script: - set CCCL_OPTIONS=--cccl-muffle /W3 - set CHECK_OPTIONS=CSHARPOPTIONS=-platform:%Platform% # Open dummy file descriptor to fix error on cygwin: ./configure: line 560: 0: Bad file descriptor -- bash -c "exec 0- - If ("$env:SWIGLANG$env:VER" -Match "python27") { - $env:CCCL_OPTIONS="$env:CCCL_OPTIONS /wd4717" - } - .\swig.exe -version +- if not "%OSVARIANT%"=="" CCache\ccache-swig -V - bash -c "file ./swig.exe" -- bash -c "time make -k check-%SWIGLANG%-version" +- bash -c "make check-%SWIGLANG%-version" - bash -c "time make -k check-%SWIGLANG%-examples %CHECK_OPTIONS%" -- bash -c "time make -k check-%SWIGLANG%-test-suite %CHECK_OPTIONS%" +- bash -c "time make -k check-%SWIGLANG%-test-suite -j%MAKEJOBS% %CHECK_OPTIONS%" # Do not build on tags (GitHub only) skip_tags: true + +#on_finish: # Display RDP connection information +# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) diff --git a/configure.ac b/configure.ac index 4b60190f2..d7876d890 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script. dnl The macros which aren't shipped with the autotools are stored in the dnl Tools/config directory in .m4 files. -AC_INIT([swig],[3.0.13],[http://www.swig.org]) +AC_INIT([swig],[4.0.0],[http://www.swig.org]) dnl NB: When this requirement is increased to 2.60 or later, AC_PROG_SED dnl definition below can be removed @@ -280,7 +280,7 @@ fi AC_MSG_RESULT($RPATH) # LINKFORSHARED are the flags passed to the $(CC) command that links -# the a few executables -- this is only needed for a few systems +# a few executables -- this is only needed for a few systems AC_MSG_CHECKING(LINKFORSHARED) if test -z "$LINKFORSHARED" @@ -615,8 +615,11 @@ else PYVER=0 else AC_MSG_CHECKING(for Python os.name) - PYOSNAME=`($PYTHON -c "import sys, os; sys.stdout.write(os.name)")` + PYOSNAME=`($PYTHON -c "import sys, os; sys.stdout.write(os.name)") 2>/dev/null` AC_MSG_RESULT($PYOSNAME) + AC_MSG_CHECKING(for Python path separator) + PYSEPARATOR=`($PYTHON -c "import sys, os; sys.stdout.write(os.sep)") 2>/dev/null` + AC_MSG_RESULT($PYSEPARATOR) fi fi @@ -628,8 +631,8 @@ else PYEPREFIX=`($PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)") 2>/dev/null` AC_MSG_RESULT($PYEPREFIX) - if test x"$PYOSNAME" = x"nt"; then - # Windows installations are quite different to posix installations + if test x"$PYOSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\"; then + # Windows installations are quite different to posix installations (MinGW path separator is a forward slash) PYPREFIX=`echo "$PYPREFIX" | sed -e 's,\\\\,/,g'` # Forward slashes are easier to use and even work on Windows most of the time PYTHON_SO=.pyd @@ -657,7 +660,7 @@ else # Need to do this hack since autoconf replaces __file__ with the name of the configure file filehack="file__" - PYVERSION=`($PYTHON -c "import sys,string,operator,os.path; sys.stdout.write(operator.getitem(os.path.split(operator.getitem(os.path.split(string.__$filehack),0)),1))")` + PYVERSION=`($PYTHON -c "import sys,string,operator,os.path; sys.stdout.write(operator.getitem(os.path.split(operator.getitem(os.path.split(string.__$filehack),0)),1))") 2>/dev/null` AC_MSG_RESULT($PYVERSION) # Find the directory for libraries this is necessary to deal with @@ -745,7 +748,7 @@ else PYVER=0 fi if test "x$PY3BIN" = xyes; then - if test x"$PYOSNAME" = x"nt" -a $PYVER -ge 3; then + if test x"$PYOSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\" -a $PYVER -ge 3; then PYTHON3="$PYTHON" else for py_ver in 3 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0 ""; do @@ -774,10 +777,13 @@ else if test $PYVER -ge 3; then AC_MSG_CHECKING(for Python 3.x os.name) - PY3OSNAME=`($PYTHON3 -c "import sys, os; sys.stdout.write(os.name)")` + PY3OSNAME=`($PYTHON3 -c "import sys, os; sys.stdout.write(os.name)") 2>/dev/null` AC_MSG_RESULT($PY3OSNAME) + AC_MSG_CHECKING(for Python 3.x path separator) + PYSEPARATOR=`($PYTHON3 -c "import sys, os; sys.stdout.write(os.sep)") 2>/dev/null` + AC_MSG_RESULT($PYSEPARATOR) - if test x"$PY3OSNAME" = x"nt"; then + if test x"$PY3OSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\"; then # Windows installations are quite different to posix installations # There is no python-config to use AC_MSG_CHECKING(for Python 3.x prefix) @@ -828,7 +834,7 @@ else # Need to do this hack since autoconf replaces __file__ with the name of the configure file filehack="file__" - PY3VERSION=`($PYTHON3 -c "import string,operator,os.path; print(operator.getitem(os.path.split(operator.getitem(os.path.split(string.__$filehack),0)),1))")` + PY3VERSION=`($PYTHON3 -c "import string,operator,os.path; print(operator.getitem(os.path.split(operator.getitem(os.path.split(string.__$filehack),0)),1))") 2>/dev/null` AC_MSG_RESULT($PY3VERSION) # Find the directory for libraries this is necessary to deal with @@ -2271,14 +2277,14 @@ else if test -z "$CSHARPCOMPILERBIN" ; then case $host in *-*-cygwin* | *-*-mingw*) - # prefer Mono gmcs (.NET 2.0) over mcs (.NET 1.1) - note mcs-1.2.3 has major pinvoke bug - AC_CHECK_PROGS(CSHARPCOMPILER, csc mono-csc gmcs mcs cscc) + # prefer unified Mono mcs compiler (not to be confused with the ancient .NET 1 mcs) over older/alternative names. + AC_CHECK_PROGS(CSHARPCOMPILER, csc mcs mono-csc gmcs cscc) if test -n "$CSHARPCOMPILER" && test "$CSHARPCOMPILER" = "csc" ; then AC_MSG_CHECKING(whether csc is the Microsoft CSharp compiler) csc 2>/dev/null | grep "C#" > /dev/null || CSHARPCOMPILER="" if test -z "$CSHARPCOMPILER" ; then AC_MSG_RESULT(no) - AC_CHECK_PROGS(CSHARPCOMPILER, mono-csc gmcs mcs cscc) + AC_CHECK_PROGS(CSHARPCOMPILER, mcs mono-csc gmcs cscc) else AC_MSG_RESULT(yes) fi