Merge branch 'master' into C

This commit is contained in:
Vadim Zeitlin 2016-09-15 01:30:49 +02:00
commit f919896306
209 changed files with 3791 additions and 2243 deletions

View file

@ -9,8 +9,12 @@ matrix:
env: SWIGLANG=
- os: linux
env: SWIGLANG= SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
sudo: required
dist: trusty
- os: linux
env: SWIGLANG= SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP14=1
env: SWIGLANG= SWIG_CC=gcc-6 SWIG_CXX=g++-6
sudo: required
dist: trusty
- compiler: gcc
os: linux
env: SWIGLANG=csharp
@ -20,6 +24,11 @@ matrix:
- compiler: gcc
os: linux
env: SWIGLANG=go
- compiler: gcc
os: linux
env: SWIGLANG=go VER=1.5
sudo: required
dist: trusty
- compiler: gcc
os: linux
env: SWIGLANG=guile
@ -38,6 +47,11 @@ matrix:
- compiler: gcc
os: linux
env: SWIGLANG=lua
- compiler: gcc
os: linux
env: SWIGLANG=lua VER=5.3
sudo: required
dist: trusty
- compiler: gcc
os: linux
env: SWIGLANG=octave SWIGJOBS=-j2 # 3.2
@ -77,6 +91,9 @@ matrix:
- compiler: gcc
os: linux
env: SWIGLANG=python PY3=3 VER=3.5
- compiler: gcc
os: linux
env: SWIGLANG=python SWIG_FEATURES=-builtin VER=2.6
- compiler: gcc
os: linux
env: SWIGLANG=python SWIG_FEATURES=-builtin
@ -86,6 +103,9 @@ matrix:
- compiler: gcc
os: linux
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.5
- compiler: gcc
os: linux
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.5 SWIGOPTPY3=
- compiler: gcc
os: linux
env: SWIGLANG=python SWIG_FEATURES=-O
@ -109,10 +129,28 @@ matrix:
env: SWIGLANG=tcl
- os: linux
env: SWIGLANG=csharp 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
dist: trusty
- os: linux
env: SWIGLANG=python 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=java SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
sudo: required
dist: trusty
- os: linux
env: SWIGLANG=python SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
sudo: required
dist: trusty
- os: osx
env: SWIGLANG= SWIG_CC=gcc-4.2 SWIG_CXX=g++-4.2
- compiler: clang

View file

@ -1,8 +1,8 @@
*** ANNOUNCE: SWIG 3.0.9 (in progress) ***
*** ANNOUNCE: SWIG 3.0.11 (in progress) ***
http://www.swig.org
We're pleased to announce SWIG-3.0.9, the latest SWIG release.
We're pleased to announce SWIG-3.0.11, 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.9.tar.gz
http://prdownloads.sourceforge.net/swig/swig-3.0.11.tar.gz
A Windows version is also available at
http://prdownloads.sourceforge.net/swig/swigwin-3.0.9.zip
http://prdownloads.sourceforge.net/swig/swigwin-3.0.11.zip
Please report problems with this release to the swig-devel mailing list,
details at http://www.swig.org/mail.html.

View file

@ -130,6 +130,7 @@ static void failed(void)
exit(1);
}
args_add_prefix(orig_args, p);
free(p);
}
if (ccache_verbose) {
@ -490,7 +491,9 @@ static void find_hash(ARGS *args)
/* also include the hash of the compiler name - as some compilers
use hard links and behave differently depending on the real name */
if (st.st_nlink > 1) {
hash_string(str_basename(args->argv[0]));
char *path = str_basename(args->argv[0]);
hash_string(path);
free(path);
}
hash_int(st.st_size);
@ -523,6 +526,7 @@ static void find_hash(ARGS *args)
input_base, tmp_string(),
i_extension);
x_asprintf(&path_stderr, "%s/tmp.cpp_stderr.%s", temp_dir, tmp_string());
free(input_base);
if (!direct_i_file) {
/* run cpp on the input file to obtain the .i */
@ -781,6 +785,7 @@ static void find_compiler(int argc, char **argv)
/* support user override of the compiler */
if ((path=getenv("CCACHE_CC"))) {
free(base);
base = x_strdup(path);
}
@ -791,8 +796,10 @@ static void find_compiler(int argc, char **argv)
stats_update(STATS_COMPILER);
cc_log("could not find compiler (%s)\n", base);
perror(base);
free(base);
exit(1);
}
free(base);
}
@ -1076,6 +1083,7 @@ static void process_args(int argc, char **argv)
if (strlen(p) < 2) {
cc_log("badly formed dependency file %s\n", output_file);
stats_update(STATS_ARGS);
free(default_depfile_name);
failed();
return;
}
@ -1093,6 +1101,7 @@ static void process_args(int argc, char **argv)
strcat(default_depfile_name, ".d");
args_add(stripped_args, "-MF");
args_add(stripped_args, default_depfile_name);
free(default_depfile_name);
}
if (!dependency_target_specified) {
@ -1117,6 +1126,7 @@ static void process_args(int argc, char **argv)
exit(1);
}
args_add_prefix(stripped_args, p);
free(p);
}
}
@ -1305,6 +1315,7 @@ static void setup_uncached_err(void)
if (putenv(buf) == -1) {
cc_log("putenv failed\n");
close(uncached_fd);
stats_update(STATS_ERROR);
failed();
}

View file

@ -20,7 +20,9 @@
#include <sys/wait.h>
#include <sys/mman.h>
#else
#define _WIN32_WINNT 0x0500
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
#include <windows.h>
#include <shlobj.h>
#endif

View file

@ -267,6 +267,7 @@ char *find_executable(const char *name, const char *exclude_name)
}
free(fname);
}
free(path);
return NULL;
#endif

View file

@ -138,7 +138,10 @@ static void stats_update_size(enum stats stat, size_t size, size_t numfiles)
memset(counters, 0, sizeof(counters));
if (lock_fd(fd) != 0) return;
if (lock_fd(fd) != 0) {
close(fd);
return;
}
/* read in the old stats */
stats_read_fd(fd, counters);

View file

@ -281,6 +281,7 @@ int unify_hash(const char *fname)
fd = open(fname, O_RDONLY|O_BINARY);
if (fd == -1 || fstat(fd, &st) != 0) {
cc_log("Failed to open preprocessor output %s\n", fname);
if (fd != -1) close(fd);
stats_update(STATS_PREPROCESSOR);
return -1;
}
@ -289,12 +290,12 @@ int unify_hash(const char *fname)
lines in preprocessor output. I have seen lines of over
100k in length, so this is well worth it */
map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
if (map == (char *)-1) {
cc_log("Failed to mmap %s\n", fname);
stats_update(STATS_PREPROCESSOR);
return -1;
}
close(fd);
/* pass it through the unifier */
unify((unsigned char *)map, st.st_size);

View file

@ -189,9 +189,11 @@ void copy_fd(int fd_in, int fd_out) {
while ((n = gzread(gz_in, buf, sizeof(buf))) > 0) {
if (write(fd_out, buf, n) != n) {
gzclose(gz_in);
fatal("Failed to copy fd");
}
}
gzclose(gz_in);
}
static int _copy_file(const char *src, const char *dest, int mode) {
@ -248,9 +250,11 @@ static int _copy_file(const char *src, const char *dest, int mode) {
}
if (mode == COPY_TO_CACHE) {
gz_out = gzdopen(dup(fd_out), "wb");
int dup_fd_out = dup(fd_out);
gz_out = gzdopen(dup_fd_out, "wb");
if (!gz_out) {
gzclose(gz_in);
close(dup_fd_out);
close(fd_out);
free(tmp_name);
return -1;
@ -459,6 +463,7 @@ int create_cachedirtag(const char *dir)
f = fopen(filename, "w");
if (!f) goto error;
if (fwrite(CACHEDIR_TAG, sizeof(CACHEDIR_TAG)-1, 1, f) != 1) {
fclose(f);
goto error;
}
if (fclose(f)) goto error;
@ -485,7 +490,7 @@ void x_asprintf(char **ptr, const char *format, ...)
}
va_end(ap);
if (!ptr) fatal("out of memory in x_asprintf");
if (!*ptr) fatal("out of memory in x_asprintf");
}
/*

240
CHANGES
View file

@ -3,6 +3,244 @@ SWIG (Simplified Wrapper and Interface Generator)
See the CHANGES.current file for changes in the current version.
See the RELEASENOTES file for a summary of changes in each release.
Version 3.0.10 (12 Jun 2016)
============================
2016-06-06: mromberg
[Python] Patch #698. Add support for -relativeimport for python 2.7, so -py3 is no
longer also required for relative import support.
2016-06-05: mromberg
[Python] Patch #694 - Fix package import regressions introduced in swig-3.0.9.
1) The code in 3.0.9 did not fall back to 'import _foo' if 'import bar._foo' failed
(assuming bar.foo was the main module). Every place _foo is imported now first tries
it from the package where foo was found and if that fails tries _foo as a global module.
2) The separate block of Python code that injected code to pull in the attributes
from _foo when -builtin is used made use of the -py3 switch to either do
'from ._foo import *' or "from _foo import *". This block of code no longer does this
and instead checks the Python version at runtime to switch between the two syntaxes.
In summary, swig-3.0.10 has been modified to ease the creation of wrapper modules
that can be fully made part of a Python package. SWIG no longer
assumes the dynamically linked C module is a global module.
The dynamic module can now be placed into either the same package as the pure Python
module or as a global module. Both locations are used by the Python wrapper to
locate the C module.
However, this could cause a backwards incompatibility with some code
that was relying on the ability of "from package import _module" to
pull attributes out of the package directly. If your code populates a
module (which is also a package) with attributes that are SWIG
generated modules which were not loaded in a conventional way,
swig-3.0.8 and earlier may have worked due to 'from package import
_module' bypassing a real import and pulling your module in as an
attribute. This will no longer work. Since this is not a common (or
even recommended) practice, most folk should not be affected.
*** POTENTIAL INCOMPATIBILITY ***
2016-05-31: wsfulton
Fix #690 - Smart pointer to %ignored class doesn't expose inherited methods.
Regression introduced in swig-3.0.9.
Version 3.0.9 (29 May 2016)
===========================
2016-05-24: mromberg
[Python] Patch #612 - Add support for Python's implicit namespace packages.
2016-05-23: wsfulton
[Ruby] Fix #602 - Error handling regression of opaque pointers introduced
in swig-3.0.8 when C functions explicitly reset a pointer using 'DATA_PTR(self) = 0'.
An ObjectPreviouslyDeleted error was incorrectly thrown when the pointer was used
as a parameter.
2016-05-17: tamuratak
[Ruby] Patch #651 - Correct overloaded function error message when function is
using %newobject.
2016-05-17: aurelj
[Ruby] Patch #582 - add support for docstring option in %module()
2016-05-14: wsfulton
Fix #434 - Passing classes by value as parameters in director methods did not create
a copy of the argument leading to invalid memory accesses if the object was used
after the upcall into the target language. Passing arguments by value shouldn't give
rise to these sorts of memory problems and so the objects are now copied and ownership
of their lifetime is controlled by the target language.
2016-05-07: wsfulton
Fix #611. Fix assertion handling defaultargs when using %extend for a template
class and the extended methods contain default arguments.
2016-05-05: ejulian
[Python] Patch #617. Fix operator/ wrappers.
2016-05-02: wsfulton
Fix #669. Don't issue warning about ignoring base classes when the derived class is
itself ignored.
2016-04-18: ianlancetaylor
[Go] Fix use of goout typemap when calling base method by
forcing the "type" attribute to the value we need.
2016-04-17: ianlancetaylor
[Go] Fixes for Go 1.6: avoid returning Go pointers from
directors that return string values; add a trailing 0 byte
when treating Go string as C char*.
2016-04-06: smarchetto
[Scilab] #552 Make Scilab runtime keep track of pointer types
Instead of a Scilab pointer which has no type, SWIG Scilab maps a
pointer to a structure tlist containing the pointer adress and its type.
2016-04-02: ahnolds
[Python] Apply #598. Fix misleading error message when attempting to read a non-existent
attribute. The previous cryptic error message:
AttributeError: type object 'object' has no attribute '__getattr__'
is now replaced with one mentioning the attribute name, eg:
AttributeError: 'Foo' object has no attribute 'bar'
2016-04-02: derkuci
[Python] Patch #610 to fix #607.
Fix single arguments when using python -builtin -O with %feature("compactdefaultargs")
2016-03-31: wsfulton
Fixes #594. Fix assertion for some languages when wrapping a C++11 enum class that
is private in a class.
Also don't wrap private enums for a few languages that attempted to do so.
2016-03-31: wsfulton
[Java] unsigned long long marshalling improvements when a negative number
is passed from Java to C. A cast to signed long long in the C layer will now
result in the expected value. No change for positive numbers passed to C.
Fixes #623.
2016-03-22: alexwarg
[Lua] #398 Fix lua __getitem + inheritance
The new handling of classes in Lua (not merging methods into the derived classes)
breaks for classes that provide a __getitem function. The __getitem function
prevents method calls to any method defined in a base class. This fix calls
__getitem only if the member is not found using recursive lookup.
2016-03-18: ptomulik
[Python] #563 Stop generating unnecessary _swigconstant helpers.
2016-03-16: richardbeare
[R] #636 Add extra std::vector numeric types
2016-03-14: wsfulton
[Java] Add std_array.i for C++11 std::array support.
2016-03-12: wsfulton
[Java, C#, D] Fix static const char member variables wrappers with %javaconst(1)
%csconst(1) or %dmanifestconst.
This fixes the case when an integer is used as the initializer, such as:
struct W { static const char w = 100; };
Fix generated code parsing enum values using char escape sequences
when these values appear in the Java code (usually when using %javaconst(1))
such as:
enum X { x1 = '\n', x2 = '\1' };
Similarly for static const member char variables such as:
struct Y { static const char y = '\n'; }
Likewise for D and %dmanifestconstant. For C# and %csconst(1), char
values in C# are now hex escaped as C# doesn't support C octal escaping.
2016-03-11: wsfulton
[Java C#] Add support for treating C++ base classes as Java interfaces
instead of Java proxy classes. This enable some sort of support for
multiple inheritance. The implementation is in swiginterface.i and
provides additional macros (see Java.html for full documentation):
%interface(CTYPE)
%interface_impl(CTYPE)
%interface_custom("PROXY", "INTERFACE", CTYPE)
2016-03-01: wsfulton
Add rstrip encoder for use in %rename. This is like the strip encoder but
strips the symbol's suffix instead of the prefix. The example below
will rename SomeThingCls to SomeThing and AnotherThingCls to AnotherThing:
%rename("%(rstrip:[Cls])s") "";
class SomeThingCls {};
struct AnotherThingCls {};
2016-03-01: olly
Fix isfinite() check to work with GCC6. Fixes
https://github.com/swig/swig/issues/615 reported by jplesnik.
2016-02-17: olly
[Python] Add missing keywords 'as' and 'with' to pythonkw.swg.
2016-02-07: kwwette
[Octave] recognise various unary functions
* Use __float__() for numeric conversions, e.g. when calling double()
* Map various unary functions, e.g. abs() to __abs__(), see full list
in section 32.3.10 of manual; only available in Octave 3.8.0 or later
2016-02-07: kwwette
[Octave] export function swig_octave_prereq() for testing Octave version
2016-02-06: pjohangustavsson
[C#] Fix duplicate symbol problems when linking the source generated
from multiple SWIG modules into one shared library for the -namespace
option. The namespace is now mangled into the global PInvoke function
names.
*** POTENTIAL INCOMPATIBILITY ***
2016-01-27: ahnolds
[Python] Added support for differentiating between Python Bytes
and Unicode objects using by defining SWIG_PYTHON_STRICT_BYTE_CHAR
and SWIG_PYTHON_STRICT_UNICODE_WCHAR.
2016-01-27: steeve
[Go] Ensure structs are properly packed between gc and GCC/clang.
2016-01-25: ahnolds
[Python] Support the full Python test suite in -classic mode
* Convert long/unsigned long/long long/unsigned long long to PyInt
rather than PyLong when possible. Certain python functions like
len() require a PyInt when operating on old-style classes.
* Add support for static methods in classic mode, including support
for pythonappend, pythonprepend, and docstrings.
* Removing the use of __swig_getmethods__ for static member methods
since they will always be found by the standard argument lookup
* Fix a bug where the wrong type of exception was caught when
checking for new-style class support
2016-01-23: ahnolds
[Go] Enable support for the Go test-suite on OSX:
* The linker on OSX requires that all symbols (even weak symbols)
are defined at link time. Because the function _cgo_topofstack is
only defined starting in Go version 1.4, we explicitly mark it as
undefined for older versions of Go on OSX.
* Avoid writing empty swigargs structs, since empty structs are not
allowed in extern "C" blocks.
2016-01-12: olly
[Javascript] Look for "nodejs" as well as "node", as it's packaged
as the former on Debian.
2016-01-12: olly
[Javascript] For v8 >= 4.3.0, use V8_MAJOR_VERSION.
Fixes https://github.com/swig/swig/issues/561.
2016-01-10: ahnolds
Improved size_t and ptrdiff_t typemaps to support large values
on platforms where sizeof(size_t) > sizeof(unsigned long) and
sizeof(ptrdiff_t) > sizeof(long).
Version 3.0.8 (31 Dec 2015)
===========================
@ -587,7 +825,7 @@ Version 3.0.3 (30 Dec 2014)
2014-10-21: wsfulton
Fix issue #242 - Use of the "kwargs" feature no longer automatically turns on the
"compactdefaultargs" feature if the target language does not support kwargs.
Only Java and Python support kwargs, so this affects all the other languages.
This change affects all languages except Python and Ruby.
*** POTENTIAL INCOMPATIBILITY ***

View file

@ -2,155 +2,96 @@ Below are the changes for the current release.
See the CHANGES file for changes in older releases.
See the RELEASENOTES file for a summary of changes in each release.
Version 3.0.9 (in progress)
===========================
Version 3.0.11 (in progress)
============================
2016-04-06: smarchetto
[Scilab] #552 Make Scilab runtime keep track of pointer types
Instead of a Scilab pointer which has no type, SWIG Scilab maps a
pointer to a structure tlist containing the pointer adress and its type.
2016-04-02: ahnolds
[Python] Apply #598. Fix misleading error message when attempting to read a non-existent
attribute. The previous cryptic error message:
AttributeError: type object 'object' has no attribute '__getattr__'
is now replaced with one mentioning the attribute name, eg:
AttributeError: 'Foo' object has no attribute 'bar'
2016-04-02: derkuci
[Python] Patch #610 to fix #607.
Fix single arguments when using python -builtin -O with %feature("compactdefaultargs")
2016-03-31: wsfulton
Fixes #594. Fix assertion for some languages when wrapping a C++11 enum class that
is private in a class.
Also don't wrap private enums for a few languages that attempted to do so.
2016-03-31: wsfulton
[Java] unsigned long long marshalling improvements when a negative number
is passed from Java to C. A cast to signed long long in the C layer will now
result in the expected value. No change for positive numbers passed to C.
Fixes #623.
2016-03-22: alexwarg
[Lua] #398 Fix lua __getitem + inheritance
The new handling of classes in Lua (not merging methods into the derived classes)
breaks for classes that provide a __getitem function. The __getitem function
prevents method calls to any method defined in a base class. This fix calls
__getitem only if the member is not found using recursive lookup.
2016-03-18: ptomulik
[Python] #563 Stop generating unnecessary _swigconstant helpers.
2016-03-16: richardbeare
[R] #636 Add extra std::vector numeric types
2016-03-14: wsfulton
[Java] Add std_array.i for C++11 std::array support.
2016-03-12: wsfulton
[Java, C#, D] Fix static const char member variables wrappers with %javaconst(1)
%csconst(1) or %dmanifestconst.
This fixes the case when an integer is used as the initializer, such as:
struct W { static const char w = 100; };
Fix generated code parsing enum values using char escape sequences
when these values appear in the Java code (usually when using %javaconst(1))
such as:
enum X { x1 = '\n', x2 = '\1' };
Similarly for static const member char variables such as:
struct Y { static const char y = '\n'; }
Likewise for D and %dmanifestconstant. For C# and %csconst(1), char
values in C# are now hex escaped as C# doesn't support C octal escaping.
2016-03-11: wsfulton
[Java C#] Add support for treating C++ base classes as Java interfaces
instead of Java proxy classes. This enable some sort of support for
multiple inheritance. The implementation is in swiginterface.i and
provides additional macros (see Java.html for full documentation):
%interface(CTYPE)
%interface_impl(CTYPE)
%interface_custom("PROXY", "INTERFACE", CTYPE)
2016-03-01: wsfulton
Add rstrip encoder for use in %rename. This is like the strip encoder but
strips the symbol's suffix instead of the prefix. The example below
will rename SomeThingCls to SomeThing and AnotherThingCls to AnotherThing:
%rename("%(rstrip:[Cls])s") "";
class SomeThingCls {};
struct AnotherThingCls {};
2016-03-01: olly
Fix isfinite() check to work with GCC6. Fixes
https://github.com/swig/swig/issues/615 reported by jplesnik.
2016-02-17: olly
[Python] Add missing keywords 'as' and 'with' to pythonkw.swg.
2016-02-07: kwwette
[Octave] recognise various unary functions
* Use __float__() for numeric conversions, e.g. when calling double()
* Map various unary functions, e.g. abs() to __abs__(), see full list
in section 32.3.10 of manual; only available in Octave 3.8.0 or later
2016-02-07: kwwette
[Octave] export function swig_octave_prereq() for testing Octave version
2016-02-06: pjohangustavsson
[C#] Fix duplicate symbol problems when linking the source generated
from multiple SWIG modules into one shared library for the -namespace
option. The namespace is now mangled into the global PInvoke function
names.
2016-09-12: xypron
[C#] Patch #786 Keyword rename to be CLS compliant by adding an underscore
suffix instead of an underscore suffix to the C symbol name. Please use an explicit
%rename to rename the symbol with a _ prefix if you want the old symbol name.
*** POTENTIAL INCOMPATIBILITY ***
2016-01-27: ahnolds
[Python] Added support for differentiating between Python Bytes
and Unicode objects using by defining SWIG_PYTHON_STRICT_BYTE_CHAR
and SWIG_PYTHON_STRICT_UNICODE_WCHAR.
2016-09-09: olly
[Python] Fix import handling for Python 2.6 to work in a frozen
application. Fixes #145, reported by Thomas Kluyver.
2016-01-27: steeve
[Go] Ensure structs are properly packed between gc and GCC/clang.
2016-09-02: smarchetto
[Scilab] Pointers are mapped to mlist instead of tlist
(mlist better for scilab overloading)
2016-01-25: ahnolds
[Python] Support the full Python test suite in -classic mode
* Convert long/unsigned long/long long/unsigned long long to PyInt
rather than PyLong when possible. Certain python functions like
len() require a PyInt when operating on old-style classes.
* Add support for static methods in classic mode, including support
for pythonappend, pythonprepend, and docstrings.
* Removing the use of __swig_getmethods__ for static member methods
since they will always be found by the standard argument lookup
* Fix a bug where the wrong type of exception was caught when
checking for new-style class support
2016-09-02: olly
[PHP] Fix "out" typemap for member function pointers and "in"
typemap for char INPUT[ANY].
2016-01-23: ahnolds
[Go] Enable support for the Go test-suite on OSX:
* The linker on OSX requires that all symbols (even weak symbols)
are defined at link time. Because the function _cgo_topofstack is
only defined starting in Go version 1.4, we explicitly mark it as
undefined for older versions of Go on OSX.
* Avoid writing empty swigargs structs, since empty structs are not
allowed in extern "C" blocks.
2016-09-01: wsfulton
[Python] More efficient Python slicing.
Call reserve for container types that support it to avoid repeated
memory reallocations for new slices or slices that grow in size.
2016-01-12: olly
[Javascript] Look for "nodejs" as well as "node", as it's packaged
as the former on Debian.
2016-09-01: wsfulton
[Python] #771 - Make builtin types hashable by default.
Default hash is the underlying C/C++ pointer. This matches up with testing for
equivalence (Py_EQ in SwigPyObject_richcompare) which compares the pointers.
2016-01-12: olly
[Javascript] For v8 >= 4.3.0, use V8_MAJOR_VERSION.
Fixes https://github.com/swig/swig/issues/561.
2016-08-22: wsfulton
[Python] The following builtin slots can be customized like other slots via the
"python:<x>" and "python:slot" features where <x> is the appropriate slot name:
tp_allocs
tp_bases
tp_basicsize
tp_cache
tp_del
tp_dealloc
tp_flags
tp_frees
tp_getset
tp_is_gc
tp_maxalloc
tp_methods
tp_mro
tp_new
tp_next
tp_prev
tp_richcompare
tp_subclasses
tp_weaklist
was_sq_ass_slice
was_sq_slice
2016-01-10: ahnolds
Improved size_t and ptrdiff_t typemaps to support large values
on platforms where sizeof(size_t) > sizeof(unsigned long) and
sizeof(ptrdiff_t) > sizeof(long).
A few documentation improvements for slot customization.
2016-08-09: joequant
[R] Patch #765 Fix extern "C" header includes for C++ code.
2016-08-05: olly
[xml] Fix how the output filename is built to avoid problems when
it contains the embedded strings ".c", ".cpp" or ".cxx".
Fixes #540 reported by djack42.
2016-07-01: wsfulton
Fix corner case of wrapping std::vector of T pointers where a pointer to a pointer of T
also exists in the wrapped code. SF Bug 2359417 (967).
2016-06-26: wkalinin
[Java, C#] Patch #681 Fix seg fault when ignoring nested classes.
2016-06-25: mromberg
[Python] #711 Fix -castmode and conversion of signed and unsigned integer types.
See 2015-12-23 CHANGES entry for details of these improvements when they were
implemented for the default options (ie not using -castmode).
2016-06-25: ahnolds
Patch #730 - Fix %implicitconv for overloaded functions when using
-castmode or -fastdispatch options.
The result is that in all overload cases where there are multiple possibilities
with the same number of arguments, the dispatch function will first check for
exact (aka non implicit) matches, and then subsequently check for implicit
casting matches. This was already happening in the normal dispatch situation,
and in the -fastdispatch case two passes through the candidates were happening,
just with SWIG_POINTER_IMPLICIT_CONV always set. After this patch, it is not set
on the first pass, and then set on the second pass.
2016-06-25: liorgold
Patch #727 - Add support for C++11 type aliasing.

View file

@ -29,7 +29,7 @@
<li><a href="#CPlusPlus11_strongly_typed_enumerations">Strongly typed enumerations</a>
<li><a href="#CPlusPlus11_double_angle_brackets">Double angle brackets</a>
<li><a href="#CPlusPlus11_explicit_conversion_operators">Explicit conversion operators</a>
<li><a href="#CPlusPlus11_alias_templates">Alias templates</a>
<li><a href="#CPlusPlus11_alias_templates">Type alias and alias templates</a>
<li><a href="#CPlusPlus11_unrestricted_unions">Unrestricted unions</a>
<li><a href="#CPlusPlus11_variadic_templates">Variadic templates</a>
<li><a href="#CPlusPlus11_new_string_literals">New string literals</a>
@ -52,7 +52,7 @@
<li><a href="#CPlusPlus11_general_purpose_smart_pointers">General-purpose smart pointers</a>
<li><a href="#CPlusPlus11_extensible_random_number_facility">Extensible random number facility</a>
<li><a href="#CPlusPlus11_wrapper_reference">Wrapper reference</a>
<li><a href="#CPlusPlus11_polymorphous_wrappers_for_function_objects">Polymorphous wrappers for function objects</a>
<li><a href="#CPlusPlus11_polymorphous_wrappers_for_function_objects">Polymorphic wrappers for function objects</a>
<li><a href="#CPlusPlus11_type_traits_for_metaprogramming">Type traits for metaprogramming</a>
<li><a href="#CPlusPlus11_uniform_method_for_computing_return_type_of_function_objects">Uniform method for computing return type of function objects</a>
</ul>
@ -603,9 +603,29 @@ Conversion operators either with or without <tt>explicit</tt> need renaming to a
them available as a normal proxy method.
</p>
<H3><a name="CPlusPlus11_alias_templates">7.2.16 Alias templates</a></H3>
<H3><a name="CPlusPlus11_alias_templates">7.2.16 Type alias and alias templates</a></H3>
<p>
A type alias is a statement of the form:
</p>
<div class="code"><pre>
using PFD = void (*)(double); // New introduced syntax
</pre></div>
<p>
which is equivalent to the old style typedef:
</p>
<div class="code"><pre>
typedef void (*PFD)(double); // The old style
</pre></div>
<p>
SWIG supports type aliasing.
</p>
<p>
The following is an example of an alias template:
@ -632,31 +652,6 @@ example.i:13: Warning 342: The 'using' keyword in template aliasing is not fully
</pre>
</div>
<p>
Similarly for non-template type aliasing:
</p>
<div class="code"><pre>
using PFD = void (*)(double); // New introduced syntax
</pre></div>
<p>
A warning will be issued:
</p>
<div class="shell">
<pre>
example.i:17: Warning 341: The 'using' keyword in type aliasing is not fully supported yet.
</pre>
</div>
<p>The equivalent old style typedefs can be used as a workaround:</p>
<div class="code"><pre>
typedef void (*PFD)(double); // The old style
</pre></div>
<H3><a name="CPlusPlus11_unrestricted_unions">7.2.17 Unrestricted unions</a></H3>
@ -1034,7 +1029,7 @@ Users would need to write their own typemaps if wrapper references are being use
</p>
<H3><a name="CPlusPlus11_polymorphous_wrappers_for_function_objects">7.3.8 Polymorphous wrappers for function objects</a></H3>
<H3><a name="CPlusPlus11_polymorphous_wrappers_for_function_objects">7.3.8 Polymorphic wrappers for function objects</a></H3>
<p>

View file

@ -287,7 +287,7 @@
<li><a href="CPlusPlus11.html#CPlusPlus11_strongly_typed_enumerations">Strongly typed enumerations</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_double_angle_brackets">Double angle brackets</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_explicit_conversion_operators">Explicit conversion operators</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_alias_templates">Alias templates</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_alias_templates">Type alias and alias templates</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_unrestricted_unions">Unrestricted unions</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_variadic_templates">Variadic templates</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_new_string_literals">New string literals</a>
@ -310,7 +310,7 @@
<li><a href="CPlusPlus11.html#CPlusPlus11_general_purpose_smart_pointers">General-purpose smart pointers</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_extensible_random_number_facility">Extensible random number facility</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_wrapper_reference">Wrapper reference</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_polymorphous_wrappers_for_function_objects">Polymorphous wrappers for function objects</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_polymorphous_wrappers_for_function_objects">Polymorphic wrappers for function objects</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_type_traits_for_metaprogramming">Type traits for metaprogramming</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_uniform_method_for_computing_return_type_of_function_objects">Uniform method for computing return type of function objects</a>
</ul>
@ -1529,7 +1529,7 @@
<li><a href="Python.html#Python_builtin_types">Built-in Types</a>
<ul>
<li><a href="Python.html#Python_builtin_limitations">Limitations</a>
<li><a href="Python.html#Python_builtin_overloads">Operator overloads -- use them!</a>
<li><a href="Python.html#Python_builtin_overloads">Operator overloads and slots -- use them!</a>
</ul>
<li><a href="Python.html#Python_nn30">Memory management</a>
<li><a href="Python.html#Python_nn31">Python 2.2 and classic classes</a>
@ -1594,6 +1594,14 @@
<li><a href="Python.html#Python_absrelimports">Absolute and relative imports</a>
<li><a href="Python.html#Python_absimport">Enforcing absolute import semantics</a>
<li><a href="Python.html#Python_importfrominit">Importing from __init__.py</a>
<li><a href="Python.html#Python_implicit_namespace_packages">Implicit Namespace Packages</a>
<li><a href="Python.html#Python_package_search">Searching for the wrapper module</a>
<ul>
<li><a href="Python.html#Python_package_search_both_package_modules">Both modules in the same package</a>
<li><a href="Python.html#Python_package_search_wrapper_split">Split modules</a>
<li><a href="Python.html#Python_package_search_both_global_modules">Both modules are global</a>
<li><a href="Python.html#Python_package_search_static">Statically linked C modules</a>
</ul>
</ul>
<li><a href="Python.html#Python_python3support">Python 3 Support</a>
<ul>
@ -1793,11 +1801,12 @@
<li><a href="Scilab.html#Scilab_wrapping_pointers">Pointers</a>
<ul>
<li><a href="Scilab.html#Scilab_wrapping_pointers_pointer_adresses">Utility functions</a>
<li><a href="Scilab.html#Scilab_wrapping_pointers_null_pointers">Null pointers</a>
<li><a href="Scilab.html#Scilab_wrapping_pointers_null_pointers">Null pointers:</a>
</ul>
<li><a href="Scilab.html#Scilab_wrapping_structs">Structures</a>
<li><a href="Scilab.html#Scilab_wrapping_cpp_classes">C++ classes</a>
<li><a href="Scilab.html#Scilab_wrapping_cpp_inheritance">C++ inheritance</a>
<li><a href="Scilab.html#Scilab_wrapping_cpp_overloading">C++ overloading</a>
<li><a href="Scilab.html#Scilab_wrapping_pointers_references_values_arrays">Pointers, references, values, and arrays</a>
<li><a href="Scilab.html#Scilab_wrapping_cpp_templates">C++ templates</a>
<li><a href="Scilab.html#Scilab_wrapping_cpp_operators">C++ operators</a>
@ -1808,7 +1817,6 @@
<li><a href="Scilab.html#Scilab_typemaps">Type mappings and libraries</a>
<ul>
<li><a href="Scilab.html#Scilab_typemaps_primitive_types">Default primitive type mappings</a>
<li><a href="Scilab.html#Scilab_typemaps_non-primitive_types">Default type mappings for non-primitive types</a>
<li><a href="Scilab.html#Scilab_typemaps_arrays">Arrays</a>
<li><a href="Scilab.html#Scilab_typemaps_pointer-to-pointers">Pointer-to-pointers</a>
<li><a href="Scilab.html#Scilab_typemaps_matrices">Matrices</a>

View file

@ -2534,7 +2534,7 @@ also return a pointer to the base class (<tt>Language</tt>) so that only the int
</p>
<p>
Save the code for your language module in a file named "<tt>python.cxx</tt>" and.
Save the code for your language module in a file named "<tt>python.cxx</tt>" and
place this file in the <tt>Source/Modules</tt> directory of the SWIG distribution.
To ensure that your module is compiled into SWIG along with the other language modules,
modify the file <tt>Source/Modules/Makefile.am</tt> to include the additional source

View file

@ -3359,20 +3359,20 @@ There is more than one macro in order to provide a choice for choosing the Java
</tr>
<tr>
<td><tt>%interface(CTYPE)</tt></td>
<td>Proxy class name is unchanged, interface name has <tt>SwigInterface</tt> added as a suffix for C++ class <tt>CTYPE</tt>.</td>
<td>For C++ class <tt>CTYPE</tt>, proxy class name is unchanged without any suffix added, interface name has <tt>SwigInterface</tt> added as a suffix.</td>
</tr>
<tr>
<td><tt>%interface_impl(CTYPE)</tt></td>
<td>Proxy class name has <tt>SwigImpl</tt> as a suffix, interface name has <tt>SwigInterface</tt> added as a suffix for C++ class <tt>CTYPE</tt>.</td>
<td>For C++ class <tt>CTYPE</tt>, proxy class name has <tt>SwigImpl</tt> added as a suffix, interface name has no added suffix.</td>
</tr>
<tr>
<td><tt>%interface_custom("PROXY", "INTERFACE", CTYPE)</tt></td>
<td>Proxy class name is given by the string <tt>PROXY</tt>, interface name is given by the string <tt>INTERFACE</tt> for C++ class <tt>CTYPE</tt>. The <tt>PROXY</tt> and <tt>INTERFACE</tt> names can use the <a href="SWIG.html#SWIG_advanced_renaming">string formatting functions</a> used in <tt>%rename</tt>.</td>
<td>For C++ class <tt>CTYPE</tt>, proxy class name is given by the string <tt>PROXY</tt>, interface name is given by the string <tt>INTERFACE</tt>. The <tt>PROXY</tt> and <tt>INTERFACE</tt> names can use the <a href="SWIG.html#SWIG_advanced_renaming">string formatting functions</a> used in <tt>%rename</tt>.</td>
</tr>
</table>
<p>
The table below has a few examples showing the resulting proxy and interface names.
The table below has a few examples showing the resulting proxy and interface names for a C++ class called <tt>Base</tt>.
</p>
<table BORDER summary="Java interface macro examples">

View file

@ -41,6 +41,7 @@ check:
# 3) <pre> <tt> <code> elements do not always select a fixed-width font - try installing the
# Courier font to fix - these have been added to style.css.
generate: SWIGDocumentation.html
wkhtmltopdf --version | grep "with patched qt" || (echo "wkhtmltopdf is not the patched qt version and so cannot be used - download it from http://wkhtmltopdf.org/downloads.html" && false)
wkhtmltopdf --margin-top 20mm --margin-bottom 20mm --margin-left 10mm --margin-right 10mm --header-font-size 6 --footer-font-size 6 --header-spacing 6 --footer-spacing 6 --header-center '[doctitle]' --footer-left '[subsection]' --footer-right '[page]' SWIGDocumentation.html SWIGDocumentation.pdf
SWIGDocumentation.html: swightml.book

View file

@ -51,7 +51,7 @@
<li><a href="#Python_builtin_types">Built-in Types</a>
<ul>
<li><a href="#Python_builtin_limitations">Limitations</a>
<li><a href="#Python_builtin_overloads">Operator overloads -- use them!</a>
<li><a href="#Python_builtin_overloads">Operator overloads and slots -- use them!</a>
</ul>
<li><a href="#Python_nn30">Memory management</a>
<li><a href="#Python_nn31">Python 2.2 and classic classes</a>
@ -116,6 +116,14 @@
<li><a href="#Python_absrelimports">Absolute and relative imports</a>
<li><a href="#Python_absimport">Enforcing absolute import semantics</a>
<li><a href="#Python_importfrominit">Importing from __init__.py</a>
<li><a href="#Python_implicit_namespace_packages">Implicit Namespace Packages</a>
<li><a href="#Python_package_search">Searching for the wrapper module</a>
<ul>
<li><a href="#Python_package_search_both_package_modules">Both modules in the same package</a>
<li><a href="#Python_package_search_wrapper_split">Split modules</a>
<li><a href="#Python_package_search_both_global_modules">Both modules are global</a>
<li><a href="#Python_package_search_static">Statically linked C modules</a>
</ul>
</ul>
<li><a href="#Python_python3support">Python 3 Support</a>
<ul>
@ -2434,7 +2442,7 @@ assert(issubclass(B.Derived, A.Base))
</li>
</ul>
<H4><a name="Python_builtin_overloads">36.4.2.2 Operator overloads -- use them!</a></H4>
<H4><a name="Python_builtin_overloads">36.4.2.2 Operator overloads and slots -- use them!</a></H4>
<p>The entire justification for the <tt>-builtin</tt> option is improved
@ -2486,52 +2494,110 @@ automatically converted to python slot operators, refer to the file
<tt>python/pyopers.swig</tt> in the SWIG library.
</p>
<p>There are other very useful python slots that you
may explicitly define using <tt>%feature</tt> directives. For example,
suppose you want to use instances of a wrapped class as keys in a native python
<tt>dict</tt>. That will work as long as you define a hash function for
instances of your class, and use it to define the python <tt>tp_hash</tt>
slot:
<p>
Read about all of the available python slots here:
<a href="http://docs.python.org/c-api/typeobj.html">http://docs.python.org/c-api/typeobj.html</a></p>
<p>
There are two ways to define a python slot function: dispatch to a
statically defined function; or dispatch to a method defined on the
operand.
</p>
<p>
To dispatch to a statically defined function, use %feature("python:&lt;slot&gt;"),
where &lt;slot&gt; is the name of a field in a <tt>PyTypeObject, PyNumberMethods,
PyMappingMethods, PySequenceMethods</tt> or <tt>PyBufferProcs</tt>.
You may override (almost) all of these slots.
</p>
<p>
Let's consider an example setting the <tt>tp_hash</tt> slot for the <tt>MyClass</tt> type.
This is akin to providing a <tt>__hash__</tt> method (for non-builtin types) to make a type hashable.
The hashable type can then for example be added to a Python <tt>dict</tt>.
</p>
<div class="code">
<pre>
%feature("python:slot", "tp_hash", functype="hashfunc") Cheese::cheeseHashFunc;
%feature("python:tp_hash") MyClass "myHashFunc";
class Cheese {
class MyClass {
public:
Cheese (const char *name);
long cheeseHashFunc () const;
long field1;
long field2;
...
};
%{
#if PY_VERSION_HEX &gt;= 0x03020000
static Py_hash_t myHashFunc(PyObject *pyobj)
#else
static long myHashFunc(PyObject *pyobj)
#endif
{
MyClass *cobj;
// Convert pyobj to cobj
return (cobj-&gt;field1 * (cobj-&gt;field2 &lt;&lt; 7));
}
%}
</pre>
</div>
<p>
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 <tt>MyClass</tt>:
</p>
<div class="code">
<pre>
static PyHeapTypeObject SwigPyBuiltin__MyClass_type = {
...
(hashfunc) myHashFunc, /* tp_hash */
...
</pre>
</div>
<p>
NOTE: It is the responsibility of the programmer (that's you!) to ensure
that a statically defined slot function has the correct signature, the <tt>hashfunc</tt>
typedef in this case.
</p>
<p>
If, instead, you want to dispatch to an instance method, you can
use %feature("python:slot"). For example:
</p>
<div class="code">
<pre>
%feature("python:slot", "tp_hash", functype="hashfunc") MyClass::myHashFunc;
#if PY_VERSION_HEX &lt; 0x03020000
#define Py_hash_t long
#endif
class MyClass {
public:
Py_hash_t myHashFunc() const;
...
};
</pre>
</div>
<p>This will allow you to write python code like this:</p>
<p>
NOTE: Some python slots use a method signature which does not
match the signature of SWIG-wrapped methods. For those slots,
SWIG will automatically generate a "closure" function to re-marshal
the arguments before dispatching to the wrapped method. Setting
the "functype" attribute of the feature enables SWIG to generate
the chosen closure function.
</p>
<div class="targetlang">
<pre>
from my MyPackage import Cheese
inventory = {
Cheese("cheddar") : 0,
Cheese("gouda") : 0,
Cheese("camembert") : 0
}
</pre>
</div>
<p>Because you defined the <tt>tp_hash</tt> slot, <tt>Cheese</tt> objects may
be used as hash keys; and when the <tt>cheeseHashFunc</tt> method is invoked
by a python <tt>dict</tt>, it will <b>not</b> go through named method dispatch.
A more detailed discussion about <tt>%feature("python:slot")</tt> can be found
<p>
There is further information on <tt>%feature("python:slot")</tt>
in the file <tt>python/pyopers.swig</tt> in the SWIG library.
You can read about all of the available python slots here:</p>
<p><a href="http://docs.python.org/c-api/typeobj.html">http://docs.python.org/c-api/typeobj.html</a></p>
<p>You may override (almost) all of the slots defined in the <tt>PyTypeObject,
PyNumberMethods, PyMappingMethods, PySequenceMethods</tt>, and <tt>PyBufferProcs</tt>
structs.
</p>
@ -4186,7 +4252,7 @@ also be used to extra binary data from arbitrary pointers.
<p>
C++ default argument code generation is documented in the main
<a href="SWIG.html#SWIGPlus_default_args">Default arguments</a> section.
<a href="SWIGPlus.html#SWIGPlus_default_args">Default arguments</a> section.
There is also an optional Python specific feature that can be used called the <tt>python:cdefaultargs</tt>
<a href="Customization.html#Customization_feature_flags">feature flag</a>.
By default, SWIG attempts to convert C++ default argument values
@ -4891,23 +4957,23 @@ A typemap can be used to handle this case as follows :
// is guaranteed to be a List object by SWIG.
%typemap(argout) double *OutValue {
PyObject *o, *o2, *o3;
o = PyFloat_FromDouble(*$1);
if ((!$result) || ($result == Py_None)) {
$result = o;
} else {
if (!PyTuple_Check($result)) {
PyObject *o2 = $result;
$result = PyTuple_New(1);
PyTuple_SetItem(target,0,o2);
}
o3 = PyTuple_New(1);
PyTuple_SetItem(o3,0,o);
o2 = $result;
$result = PySequence_Concat(o2,o3);
Py_DECREF(o2);
Py_DECREF(o3);
PyObject *o, *o2, *o3;
o = PyFloat_FromDouble(*$1);
if ((!$result) || ($result == Py_None)) {
$result = o;
} else {
if (!PyTuple_Check($result)) {
PyObject *o2 = $result;
$result = PyTuple_New(1);
PyTuple_SetItem($result,0,o2);
}
o3 = PyTuple_New(1);
PyTuple_SetItem(o3,0,o);
o2 = $result;
$result = PySequence_Concat(o2,o3);
Py_DECREF(o2);
Py_DECREF(o3);
}
}
int spam(double a, double b, double *OutValue, double *OutValue);
@ -5520,6 +5586,23 @@ They should be created by other means. Both files (module <tt>*.py</tt> and
directories in order to obtain a desirable package/module hierarchy.
</p>
<p>
Python3 adds another option for packages with
<a href="https://www.python.org/dev/peps/pep-0420/">PEP 0420</a> (implicit
namespace packages). Implicit namespace packages no longer use
__init__.py files. SWIG generated Python modules support implicit
namespace packages. See
<a href="#Python_implicit_namespace_packages">36.11.5 Implicit Namespace
Packages</a> for more information.
</p>
<p>
If you place a SWIG generated module into a Python package then there
are details concerning the way SWIG
<a href="#Python_package_search">searches for the wrapper module</a>
that you may want to familiarize yourself with.
</p>
<p>The way Python defines its modules and packages impacts SWIG users. Some
users may need to use special features such as the <tt>package</tt> option in the
<tt>%module</tt> directive or import related command line options. These are
@ -5679,8 +5762,9 @@ class M2(pkg2.mod3.M3): pass
<p>By default, SWIG would generate <tt>mod2.py</tt> proxy file with
<tt>import</tt> directive as in point 1. This can be changed with the
<tt>-relativeimport</tt> command line option. The <tt>-relativeimport</tt> instructs
SWIG to organize imports as in point 2 (for Python 2.x) or as in point 4 (for
Python 3, that is when the -py3 command line option is enabled). In short, if you have
SWIG to organize imports as in point 2 (for Python < 2.7.0) or as in point 4
for Python 2.7.0 and newer. This is a check done at the time the module is
imported. In short, if you have
<tt>mod2.i</tt> and <tt>mod3.i</tt> as above, then without
<tt>-relativeimport</tt> SWIG will write</p>
@ -5694,22 +5778,17 @@ import pkg1.pkg2.mod3
write</p>
<div class="targetlang">
<pre>
import pkg2.mod3
<pre>
from sys import version_info
if version_info &gt;= (2, 7, 0):
from . import pkg2
import pkg1.pkg2.mod3
else:
import pkg2.mod3
del version_info
</pre>
</div>
<p>if <tt>-py3</tt> is not used, or</p>
<div class="targetlang">
<pre>
from . import pkg2
import pkg1.pkg2.mod3
</pre>
</div>
<p>when <tt>-py3</tt> is used.</p>
<p>You should avoid using relative imports and use absolute ones whenever
possible. There are some cases, however, when relative imports may be
necessary. The first example is, when some (legacy) Python code refers entities
@ -5865,6 +5944,257 @@ class Bar(pkg3.foo.Foo): pass
effect (note, that the Python 2 case also needs the <tt>-relativeimport</tt>
workaround).</p>
<H3><a name="Python_implicit_namespace_packages">36.11.5 Implicit Namespace Packages</a></H3>
<p> Python 3.3 introduced
<a href="https://www.python.org/dev/peps/pep-0420/">PEP 0420</a> which
implements implicit namespace packages. In a nutshell, implicit namespace
packages remove the requirement of an __init__.py file and allow packages
to be split across multiple PATH elements. For example:
</p>
<div class="diagram">
<pre>
/fragment1/pkg1/mod1.py
/fragment2/pkg1/mod2.py
/fragment3/pkg1/mod3.py
</pre>
</div>
<p>If PYTHONPATH is set to "/fragment1:/fragment2:/fragment3", then mod1, mod2
and mod3 will be part of pkg1. This allows for splitting of packages into
separate pieces. This can be useful for SWIG generated wrappers in the
following way.
</p>
<p> Suppose you create a SWIG wrapper for a module called robin. The SWIG
generated code consists of two files robin.py and _robin.so. You wish to
make these modules part of a subpackage (brave.sir). With implicit namespace
packages you can place these files in the following configurations:
</p>
<p>Using PYTHONPATH="/some/path"</p>
<div class="diagram">
<pre>
/some/path/brave/sir/robin.py
/some/path/brave/sir/_robin.so
</pre>
</div>
<p>Using PYTHONPATH="/some/path:/some/other/path"
<div class="diagram">
<pre>
/some/path/brave/sir/robin.py
/some/other/path/brave/sir/_robin.so
</pre>
</div>
<p> Finally suppose that your pure python code is stored in a .zip file or
some other way (database, web service connection, etc). Python can load the
robin.py module using a custom importer. But the _robin.so module will need
to be located on a file system. Implicit namespace packages make this
possible. For example, using PYTHONPATH="/some/path/foo.zip:/some/other/path"
<p> Contents of foo.zip</p>
<div class="diagram">
<pre>
brave/
brave/sir/
brave/sir/robin.py
</pre>
</div>
<p> File system contents</p>
<div class="diagram">
<pre>
/some/other/path/brave/sir/_robin.so
</pre>
</div>
<p>Support for implicit namespace packages was added to python-3.3. The
zipimporter requires python-3.5.1 or newer to work with subpackages.
</p>
<p>
<b>Compatibility Note:</b> Support for implicit namespace packages was added in SWIG-3.0.9.
</p>
<H3><a name="Python_package_search">36.11.6 Searching for the wrapper module</a></H3>
<p>
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
built and linked into a dynamically (or statically) loaded module _foo
(see the <a href="Python.html#Python_nn3">Preliminaries section</a> for details). So, the interface
file really defines two Python modules. How these two modules are loaded is
covered next.
</p>
<p>
The pure Python module needs to load the C/C++ module in order to link
to the wrapped C/C++ methods. To do this it must make some assumptions
about what package the C/C++ module may be located in. The approach the
pure Python module uses to find the C/C++ module is as follows:
</p>
<ol>
<li><p>The pure Python module, foo.py, tries to load the C/C++ module, _foo, from the same package foo.py is
located in. The package name is determined from the <tt>__name__</tt>
attribute given to foo.py by the Python loader that imported
foo.py. If foo.py is not in a package then _foo is loaded
as a global module.</p>
</li>
<li><p>If the above import of _foo results in an ImportError
being thrown, then foo.py makes a final attempt to load _foo
as a global module.</p>
</li>
</ol>
<p>
As an example suppose foo.i is compiled into foo.py and _foo.so. Assuming
/dir is on PYTHONPATH, then the two modules can be installed and used in the
following ways:
</p>
<H4><a name="Python_package_search_both_package_modules">36.11.6.1 Both modules in the same package</a></H4>
<p>Both modules are in one package:</p>
<div class="diagram">
<pre>
/dir/package/foo.py
/dir/package/__init__.py
/dir/package/_foo.so
</pre>
</div>
<p>And imported with</p>
<div class="diagram">
<pre>
from package import foo
</pre>
</div>
<H4><a name="Python_package_search_wrapper_split">36.11.6.2 Split modules</a></H4>
<p>The pure python module is in a package and the C/C++ module is global:</p>
<div class="diagram">
<pre>
/dir/package/foo.py
/dir/package/__init__.py
/dir/_foo.so
</pre>
</div>
<p>And imported with</p>
<div class="diagram">
<pre>
from package import foo
</pre>
</div>
<H4><a name="Python_package_search_both_global_modules">36.11.6.3 Both modules are global</a></H4>
<p>Both modules are global:</p>
<div class="diagram">
<pre>
/dir/foo.py
/dir/_foo.so
</pre>
</div>
<p>And imported with</p>
<div class="diagram">
<pre>
import foo
</pre>
</div>
<p>
If _foo is statically linked into an embedded Python interpreter, then it may or
may not be in a Python package. This depends in the exact way the module was
loaded statically. The above search order will still be used for statically
loaded modules. So, one may place the module either globally or in a package
as desired.
</p>
<H4><a name="Python_package_search_static">36.11.6.4 Statically linked C modules</a></H4>
<p>It is strongly recommended to use dynamically linked modules for the C
portion of your pair of Python modules.
If for some reason you still need
to link the C module of the pair of Python modules generated by SWIG into
your interpreter, then this section provides some details on how this impacts
the pure Python modules ability to locate the other part of the pair.
Please also see the <a href="Python.html#Python_nn8">Static Linking</a> section.
</p>
<p>When Python is extended with C code the Python interpreter needs to be
informed about details of the new C functions that have been linked into
the executable. The code to do this is created by SWIG and is automatically
called in the correct way when the module is dynamically loaded. However
when the code is not dynamically loaded (because it is statically linked)
Then the initialization method for the module created by SWIG is not
called automatically and the Python interpreter has no idea that the
new SWIG C module exists.
</p>
<p>Before Python 3, one could simply call the init method created by SWIG
which would have normally been called when the shared object was dynamically
loaded. The specific name of this method is not given here because statically
linked modules are not encouraged with SWIG
(<a href="Python.html#Python_nn8">Static Linking</a>). However one can find this
init function in the C file generated by SWIG.
</p>
<p>If you are really keen on static linking there are two ways
to initialize the SWIG generated C module with the init method. Which way
you use depends on what version of Python your module is being linked with.
Python 2 and Python 3 treat this init function differently. And the way
they treat it affects how the pure Python module will be able to
locate the C module.
</p>
<p>The details concerning this are covered completly in the documentation
for Python itself. Links to the relavent sections follow:
</p>
<ul>
<li><a href="https://docs.python.org/2/extending/extending.html#methodtable">Extending in python2</a></li>
<li><a href="https://docs.python.org/3.6/extending/extending.html#the-module-s-method-table-and-initialization-function">Extending in python3</a></li>
</ul>
<p>There are two keys things to understand. The first is that in
Python 2 the init() function returns void. In Python 3 the init() function
returns a PyObject * which points to the new module. Secondly, when
you call the init() method manually, you are the Python importer. So, you
determine which package the C module will be located in.
</p>
<p>So, if you are using Python 3 it is important that you follow what is
described in the Python documentation linked above. In particular, you can't
simply call the init() function generated by SWIG and cast the PyObject
pointer it returns over the side. If you do then Python 3 will have no
idea that your C module exists and the pure Python half of your wrapper will
not be able to find it. You need to register your module with the Python
interpreter as described in the Python docs.
</p>
<p>With Python 2 things are somewhat more simple. In this case the init function
returns void. Calling it will register your new C module as a <b>global</b>
module. The pure Python part of the SWIG wrapper will be able to find it
because it tries both the pure Python module it is part of and the global
module. If you wish not to have the statically linked module be a global
module then you will either need to refer to the Python documentation on how
to do this (remember you are now the Python importer) or use dynamic linking.
</p>
<H2><a name="Python_python3support">36.12 Python 3 Support</a></H2>

View file

@ -40,12 +40,12 @@
<li><a href="#Scilab_wrapping_pointers">Pointers</a>
<ul>
<li><a href="#Scilab_wrapping_pointers_pointer_adresses">Utility functions</a>
<li><a href="#Scilab_wrapping_pointers_null_pointers">Null pointers</a>
<li><a href="#Scilab_wrapping_pointers_null_pointers">Null pointers:</a>
</ul>
<li><a href="#Scilab_wrapping_structs">Structures</a>
<li><a href="#Scilab_wrapping_cpp_classes">C++ classes</a>
<li><a href="#Scilab_wrapping_cpp_inheritance">C++ inheritance</a>
<li><a href="#Scilab_wrapping_cpp_overloading">C++ overloading</a></li>
<li><a href="#Scilab_wrapping_cpp_overloading">C++ overloading</a>
<li><a href="#Scilab_wrapping_pointers_references_values_arrays">Pointers, references, values, and arrays</a>
<li><a href="#Scilab_wrapping_cpp_templates">C++ templates</a>
<li><a href="#Scilab_wrapping_cpp_operators">C++ operators</a>
@ -56,7 +56,6 @@
<li><a href="#Scilab_typemaps">Type mappings and libraries</a>
<ul>
<li><a href="#Scilab_typemaps_primitive_types">Default primitive type mappings</a>
<li><a href="#Scilab_typemaps_non-primitive_types">Default type mappings for non-primitive types</a>
<li><a href="#Scilab_typemaps_arrays">Arrays</a>
<li><a href="#Scilab_typemaps_pointer-to-pointers">Pointer-to-pointers</a>
<li><a href="#Scilab_typemaps_matrices">Matrices</a>
@ -764,11 +763,11 @@ Why a native pointer is not mapped to a Scilab pointer (type name: "pointer", ty
<p>
Notes:
</p>
<ul>
<li>type tracking needs the SWIG runtime to be first initialized with the appropriate function (see the <a href="#Scilab_module_initialization">Module initialization</a> section).</li>
<li>for any reason, if a wrapped pointer type is unknown (or if the SWIG runtime is not initialized), SWIG maps it to a Scilab pointer. Also, a Scilab pointer is always accepted as a pointer argument of a wrapped function. The drawaback is that pointer type is lost.</li>
</ul>
</p>
<p>
Following is an example of the wrapping of the C <tt>FILE*</tt> pointer:
@ -854,6 +853,7 @@ ans =
<H4><a name="Scilab_wrapping_pointers_null_pointers">39.3.6.2 Null pointers:</a></H4>
<p>
Using the previous <tt>SWIG_this()</tt> and <tt>SWIG_ptr()</tt>, it is possible to create and check null pointers:
</p>
@ -904,6 +904,7 @@ Several functions are generated:
</ul>
<p>
Usage example:
</p>
@ -963,7 +964,7 @@ ans =
<p>
Note: the pointer to the struct works as described in <a href="Scilab_wrapping_pointers">Pointers</a>. For example, the type of the struct pointer can be get with <tt>typeof</tt>, as following:
<p>
</p>
<div class="targetlang"><pre>
--&gt; example_Init();
@ -1027,7 +1028,7 @@ ans =
<p>
Note: like structs, class pointers are mapped as described in <a href="Scilab_wrapping_pointers">Pointers</a>. Let's give an example which shows that each class pointer type is a new type in Scilab that can be used for example (through <a href="https://help.scilab.org/docs/5.5.2/en_US/overloading.html">overloading</a>) to implement a custom print for the <tt>Point</tt> class:
<p>
</p>
<div class="targetlang"><pre>
--&gt; function %_p_Point_p(p)
@ -1120,27 +1121,26 @@ But we can use either use the <tt>get_perimeter()</tt> function of the parent cl
<H3><a name="Scilab_wrapping_cpp_overloading">39.3.10 C++ overloading</a></H3>
<p>
As explained in <a href="http://www.swig.org/Doc3.0/SWIGPlus.html#SWIGPlus_overloaded_methods">6.15</a> SWIG provides support for overloaded functions and constructors.
As explained in <a href="SWIGPlus.html#SWIGPlus_overloaded_methods">6.15</a> SWIG provides support for overloaded functions and constructors.
</p>
<p>As SWIG knows pointer types, the overloading works also with pointer types, here is is an example with a function <tt>magnify</tt> overloaded for the previous classes <tt>Shape</tt> and <tt>Circle</tt>:
</p>
<p>
<div class="code"><pre>
%module example
void magnify(Square *square, double factor) {
square->size *= factor;
square-&gt;size *= factor;
};
void magnify(Circle *circle, double factor) {
square->radius *= factor;
square-&gt;radius *= factor;
};
</pre></div>
</p>
<p>
<div class="targetlang"><pre>
--&gt; example_Init();
--&gt; c = new_Circle(3);
@ -1157,7 +1157,6 @@ void magnify(Circle *circle, double factor) {
20;
</pre></div>
</p>
<H3><a name="Scilab_wrapping_pointers_references_values_arrays">39.3.11 Pointers, references, values, and arrays</a></H3>

View file

@ -8,7 +8,7 @@
<H1><a name="Sections">SWIG-3.0 Documentation</a></H1>
<p>
Last update : SWIG-3.0.9 (in progress)
Last update : SWIG-3.0.11 (in progress)
</p>
<H2><a name="Sections_Sections">Sections</a></H2>

View file

@ -750,7 +750,7 @@ code : { ... }
<p>
Note that the preprocessor will expand code within the {} delimiters, but not in the last two styles of delimiters,
see <a href="Preprocessor.html#Preprocessor_typemap_delimiters">Preprocessor and Typemaps</a>.
see <a href="Preprocessor.html#Preprocessor_delimiters">Preprocessor and Typemaps</a>.
Here are some examples of valid typemap specifications:
</p>

View file

@ -327,11 +327,11 @@ else
endif
PYTHON_SO = @PYTHON_SO@
# SWIG option for Python
# SWIG option for Python3
ifeq (,$(PY3))
SWIGPYTHON = $(SWIG) -python
SWIGOPTPY3 =
else
SWIGPYTHON = $(SWIG) -python -py3
SWIGOPTPY3 = -py3
endif
PEP8 = @PEP8@
@ -342,7 +342,7 @@ PEP8_FLAGS = --ignore=E402,E501,E30,W291,W391
# ----------------------------------------------------------------
python: $(SRCDIR_SRCS)
$(SWIGPYTHON) $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
$(SWIG) -python $(SWIGOPTPY3) $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(PYTHON_INCLUDE)
$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO)
@ -351,7 +351,7 @@ python: $(SRCDIR_SRCS)
# -----------------------------------------------------------------
python_cpp: $(SRCDIR_SRCS)
$(SWIGPYTHON) -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(SWIG) -python $(SWIGOPTPY3) -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(PYTHON_INCLUDE)
$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO)
@ -367,12 +367,12 @@ TKINTER =
PYTHON_LIBOPTS = $(PYTHON_LINK) @LIBS@ $(TKINTER) $(SYSLIBS)
python_static: $(SRCDIR_SRCS)
$(SWIGPYTHON) -lembed.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
$(SWIG) -python $(SWIGOPTPY3) -lembed.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) \
$(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET)
python_static_cpp: $(SRCDIR_SRCS)
$(SWIGPYTHON) -c++ -lembed.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(SWIG) -python $(SWIGOPTPY3) -c++ -lembed.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) \
$(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET)
@ -429,7 +429,7 @@ python_clean:
##################################################################
# Make sure these locate your Octave installation
OCTAVE = OCTAVE_HISTFILE=/dev/null @OCTAVE@
OCTAVE = @OCTAVE@
OCTAVE_CXX = $(DEFS) @OCTAVE_CPPFLAGS@ @OCTAVE_CXXFLAGS@
# Extra Octave specific dynamic linking options
@ -463,7 +463,7 @@ octave_cpp: $(SRCDIR_SRCS)
# -----------------------------------------------------------------
octave_run:
$(RUNTOOL) $(OCTAVE) $(OCTAVE_SCRIPT) $(RUNPIPE)
OCTAVE_HISTFILE=/dev/null $(RUNTOOL) $(OCTAVE) $(OCTAVE_SCRIPT) $(RUNPIPE)
# -----------------------------------------------------------------
# Version display
@ -587,6 +587,7 @@ JAVASO =@JAVASO@
JAVALDSHARED = @JAVALDSHARED@
JAVACXXSHARED = @JAVACXXSHARED@
JAVACFLAGS = @JAVACFLAGS@
JAVAFLAGS = @JAVAFLAGS@
JAVA = @JAVA@
JAVAC = @JAVAC@ -d .
@ -620,7 +621,7 @@ java_compile: $(SRCDIR_SRCS)
# -----------------------------------------------------------------
java_run:
env LD_LIBRARY_PATH=$$PWD $(RUNTOOL) $(JAVA) $(RUNME) $(RUNPIPE)
env LD_LIBRARY_PATH=$$PWD $(RUNTOOL) $(JAVA) $(JAVAFLAGS) $(RUNME) $(RUNPIPE)
# -----------------------------------------------------------------
# Version display
@ -1670,6 +1671,7 @@ R = R
RCXXSRCS = $(INTERFACE:.i=_wrap.cpp) #Need to use _wrap.cpp for R build system as it does not understand _wrap.cxx
RRSRC = $(INTERFACE:.i=.R)
R_CFLAGS=-fPIC
R_OPT = --slave --quiet --no-save --no-restore
R_SCRIPT=$(SRCDIR)$(RUNME).R
# need to compile .cxx files outside of R build system to make sure that
@ -1702,7 +1704,7 @@ endif
# -----------------------------------------------------------------
r_run:
$(RUNTOOL) $(R) CMD BATCH $(R_SCRIPT) $(RUNPIPE)
$(RUNTOOL) $(R) $(R_OPT) -f $(R_SCRIPT) $(RUNPIPE)
# -----------------------------------------------------------------
# Version display

View file

@ -14,18 +14,19 @@ See the lua code for how they are called
// this adds some lua code directly into the module
// warning: you need the example. prefix if you want it added into the module
// addmittedly this code is a bit tedious, but its a one off effort
// admittedly this code is a bit tedious, but its a one off effort
%luacode {
function example.sort_int2(t)
local len=table.maxn(t) -- the len
-- local len=table.maxn(t) -- the len - maxn deprecated in 5.3
local len=0; for _ in pairs(t) do len=len+1 end
local arr=example.new_int(len)
for i=1,len do
example.int_setitem(arr,i-1,t[i]) -- note: C index is one less then lua indea
example.int_setitem(arr,i-1,t[i]) -- note: C index is one less then lua index
end
example.sort_int(arr,len) -- call the fn
-- copy back
for i=1,len do
t[i]=example.int_getitem(arr,i-1) -- note: C index is one less then lua indea
t[i]=example.int_getitem(arr,i-1) -- note: C index is one less then lua index
end
example.delete_int(arr) -- must delete it
end

View file

@ -10,11 +10,15 @@ import_packages_subdirs = \
from_init3 \
relativeimport1 \
relativeimport2 \
relativeimport3
relativeimport3 \
split_modules \
namespace_pkg
check: build
if test "x$(SRCDIR)" != x; then \
for file in `cd $(SRCDIR) && find . -type f -name __init__.py`; do \
for file in `cd $(SRCDIR) && find . -type f -name "*.py"`; do \
mkdir -p `dirname $$file`; \
cp "${SRCDIR}$$file" "$$file" || exit 1; \
done; \
fi; \
@ -35,7 +39,7 @@ static:
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_clean
if test "x$(SRCDIR)" != x; then \
for file in `cd $(SRCDIR) && find . -type f -name __init__.py`; do \
for file in `cd $(SRCDIR) && find . -type f -name "*.py"`; do \
rm -f "$$file" || exit 1; \
done; \
fi; \

View file

@ -1,2 +1,4 @@
These are actually regression tests for SF bug #1297 (GH issue #7).
See individual READMEs in subdirectories.
The namespace_pkg is an example of python3's namespace packages.
See individual READMEs in subdirectories.

View file

@ -0,0 +1,17 @@
TOP = ../../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
TARGET = robin
INTERFACE = robin.i
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='$(TARGET)' python_clean
rm -rf path1 path2 path3 path4.zip

View file

@ -0,0 +1,25 @@
This is an example (and test) of using swig generated modules in the context
of python3's namespace packages:
https://www.python.org/dev/peps/pep-0420/
Consequently, this example requires python (3.3 or newer) to build and run.
This example creates a simple swig module named robin. The robin.py module
has a companion C module named _robin.so. The robin module is tested in four
ways:
1) As a non-package module (tested by nonpkg.py)
2) With robin.py and _robin.so in the brave package under the path1
subdirectory. (tested by normal.py)
3) With robin.py in path2/brave and _robin.so in path3/brave
(tested by split.py)
4) With robin.py contained in a zip file (path4.zip) as brave/robin.py and
_robin.so found on the filesystem under path3/brave (tested by zipsplit.py)
Note: Using namespace packages with subpackages (such as brave.sir.robin) where
robin.py is located in a zipfile requires python-3.5.1 or newer as
python's zipimporter only worked with packages of depth 1 until then.

View file

@ -0,0 +1,5 @@
# import robin as a module in the global namespace
import robin
assert(robin.run() == "AWAY!")

View file

@ -0,0 +1,7 @@
import sys
# Package brave found under one path
sys.path.insert(0, 'path1')
from brave import robin
assert(robin.run() == "AWAY!")

View file

@ -0,0 +1,45 @@
import sys
import os
import shutil
import zipfile
def copyMods():
dirs = ['path1', 'path2', 'path3']
# Clean out any old package paths
for d in dirs:
if os.path.isdir(d):
shutil.rmtree(d)
for d in dirs:
os.mkdir(d)
os.mkdir(os.path.join(d, 'brave'))
shutil.copy('robin.py', os.path.join('path1', 'brave'))
os.system('cp _robin.* ' + os.path.join('path1', 'brave'))
shutil.copy('robin.py', os.path.join('path2', 'brave'))
os.system('cp _robin.* ' + os.path.join('path3', 'brave'))
mkzip()
def mkzip():
zf = zipfile.ZipFile("path4.zip", "w")
zf.writestr("brave/", b'')
zf.write('robin.py', 'brave/robin.py')
zf.close()
def main():
copyMods()
# Run each test with a separate interpreter
os.system(sys.executable + " nonpkg.py")
os.system(sys.executable + " normal.py")
os.system(sys.executable + " split.py")
os.system(sys.executable + " zipsplit.py")
if __name__ == "__main__":
main()

View file

@ -0,0 +1,7 @@
%module robin
%inline %{
const char *run(void) {
return "AWAY!";
}
%}

View file

@ -0,0 +1,17 @@
# These examples rely on namespace packages. Don't
# run them for old python interpreters.
import sys
import os.path
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
print "Testing " + testname + " - namespace packages"
if sys.version_info < (3, 3, 0):
print " Not importing nstest as Python version is < 3.3"
sys.exit(0)
import nstest
print " Finished importing nstest"
nstest.main()

View file

@ -0,0 +1,9 @@
import sys
# Package brave split into two paths.
# path2/brave/robin.py and path3/brave/_robin.so
sys.path.insert(0, 'path2')
sys.path.insert(0, 'path3')
from brave import robin
assert(robin.run() == "AWAY!")

View file

@ -0,0 +1,9 @@
import sys
# Package brave split into two paths.
# brave/robin.py (in path4.zip) and path3/brave/_robin.so
sys.path.insert(0, 'path4.zip')
sys.path.insert(0, 'path3')
from brave import robin
assert(robin.run() == "AWAY!")

View file

@ -0,0 +1,26 @@
TOP = ../../..
LIBS =
subdirs = vanilla vanilla_split
check: build
for s in $(subdirs); do \
(cd $$s && $(MAKE) check); \
done
build:
for s in $(subdirs); do \
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' build); \
done
static:
for s in $(subdirs); do \
(cd $$s && $(MAKE) SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' static); \
done
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_clean
for s in $(subdirs); do \
(cd $$s && $(MAKE) clean); \
done

View file

@ -0,0 +1,7 @@
These examples/tests are for when the SWIG generated wrapper module is split
between two packages. Specifically the pure python part is part of a package
and the C/C++ part is not in any package at all. Historically SWIG has
supported this sort of thing.
vanilla # "plane Jane" module both halves in pkg1
vanilla_split # python 1/2 in pkg1 C 1/2 in global namespace

View file

@ -0,0 +1,18 @@
TOP = ../../../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SWIGOPT =
LIBS =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_run
build:
cd pkg1 && $(MAKE) build
static:
cd pkg1 && $(MAKE) static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='foo' python_clean
cd pkg1 && $(MAKE) -f $(TOP)/../Makefile SRCDIR='$(SRCDIR)' TARGET='foo' python_clean

View file

@ -0,0 +1,18 @@
TOP = ../../../../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SWIGOPT =
LIBS =
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' TARGET='foo' INTERFACE='foo.i' python_cpp
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' TARGET='foo' INTERFACE='foo.i' python_cpp_static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='foo' python_clean

View file

@ -0,0 +1 @@
# killroy was here

View file

@ -0,0 +1,10 @@
%module(package="pkg1") foo
%{
static unsigned count(void)
{
return 3;
}
%}
unsigned count(void);

View file

@ -0,0 +1,10 @@
import os.path
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
print "Testing " + testname + " - split modules"
import pkg1.foo
print " Finished importing pkg1.foo"
assert(pkg1.foo.count() == 3)

View file

@ -0,0 +1,22 @@
TOP = ../../../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SWIGOPT = -outdir pkg1
LIBS =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' TARGET='foo' INTERFACE='foo.i' python_cpp
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' TARGET='foo' INTERFACE='foo.i' python_cpp_static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='foo' python_clean
cd pkg1 && $(MAKE) -f $(TOP)/../Makefile SRCDIR='$(SRCDIR)' TARGET='foo' python_clean

View file

@ -0,0 +1,10 @@
%module(package="pkg1") foo
%{
static unsigned count(void)
{
return 3;
}
%}
unsigned count(void);

View file

@ -0,0 +1 @@
# killroy was here

View file

@ -0,0 +1,10 @@
import os.path
testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
print "Testing " + testname + " - split modules"
import pkg1.foo
print " Finished importing pkg1.foo"
assert(pkg1.foo.count() == 3)

View file

@ -68,6 +68,10 @@ TAscii *DigitsGlobalC;
// Director test
%feature("director");
#if defined(SWIGGO)
%typemap(godirectorout) CharPtr, CCharPtr ""
#endif
%inline %{
struct DirectorTest {
virtual UCharPtr UCharFunction(UCharPtr str) { return str; }

View file

@ -87,7 +87,6 @@ CPP_TEST_BROKEN += \
director_nested_class \
exception_partial_info \
extend_variable \
li_std_vector_ptr \
li_boost_shared_ptr_template \
nested_private \
overload_complicated \
@ -174,7 +173,6 @@ CPP_TEST_CASES += \
director_abstract \
director_alternating \
director_basic \
director_property \
director_binary_string \
director_classes \
director_classic \
@ -189,12 +187,14 @@ CPP_TEST_CASES += \
director_ignore \
director_keywords \
director_namespace_clash \
director_nested \
director_nspace \
director_nspace_director_name_collision \
director_nested \
director_overload \
director_overload2 \
director_pass_by_value \
director_primitives \
director_property \
director_protected \
director_protected_overloaded \
director_redefined \
@ -307,6 +307,7 @@ CPP_TEST_CASES += \
nested_class \
nested_directors \
nested_comment \
nested_ignore \
nested_scope \
nested_template_base \
nested_workaround \
@ -362,6 +363,7 @@ CPP_TEST_CASES += \
smart_pointer_const2 \
smart_pointer_const_overload \
smart_pointer_extend \
smart_pointer_ignore \
smart_pointer_member \
smart_pointer_multi \
smart_pointer_multi_typedef \
@ -402,6 +404,7 @@ CPP_TEST_CASES += \
template_default2 \
template_default_arg \
template_default_arg_overloaded \
template_default_arg_overloaded_extend \
template_default_arg_virtual_destructor \
template_default_class_parms \
template_default_class_parms_typedef \
@ -584,6 +587,7 @@ CPP_STD_TEST_CASES += \
li_std_vector \
li_std_vector_enum \
li_std_vector_member_var\
li_std_vector_ptr \
smart_pointer_inherit \
template_typedef_fnc \
template_type_namespace \
@ -714,7 +718,7 @@ check-cpp: $(CPP_TEST_CASES:=.cpptest)
check-cpp11: $(CPP11_TEST_CASES:=.cpptest)
check-failing-test = \
$(MAKE) -s $1.$2 >/dev/null 2>/dev/null && echo "Failing test $t passed."
$(MAKE) -s $1.$2 >/dev/null 2>/dev/null && echo "Failing test $1 passed."
check-failing:
+-$(foreach t,$(FAILING_C_TESTS),$(call check-failing-test,$t,ctest);)

View file

@ -3,6 +3,9 @@
// %constant and struct
%inline %{
#if defined(_MSC_VER)
#pragma warning(disable : 4190) // warning C4190: 'result' has C-linkage specified, but returns UDT 'Type1' which is incompatible with C
#endif
struct Type1 {
Type1(int val = 0) : val(val) {}
int val;

View file

@ -2,15 +2,6 @@
// Type aliasing seg fault : Github issue #424
%warnfilter(SWIGWARN_CPP11_ALIAS_DECLARATION) Target;
%warnfilter(SWIGWARN_CPP11_ALIAS_DECLARATION) Int;
%warnfilter(SWIGWARN_CPP11_ALIAS_DECLARATION) IntRef;
%warnfilter(SWIGWARN_CPP11_ALIAS_DECLARATION) IntPtrRef;
%warnfilter(SWIGWARN_CPP11_ALIAS_DECLARATION) IntRValueRef;
%warnfilter(SWIGWARN_CPP11_ALIAS_DECLARATION) IntArray;
%warnfilter(SWIGWARN_CPP11_ALIAS_DECLARATION) HalideTargetPtr1;
%warnfilter(SWIGWARN_CPP11_ALIAS_DECLARATION) HalideTargetPtr2;
%inline %{
namespace Halide {
@ -53,14 +44,69 @@ public:
%inline %{
using Int = int;
using IntRef = int&;
using IntPtrRef = int*&;
using IntRValueRef = int&&;
using IntArray = int[];
using HalideTargetPtr1 = Halide::Target*;
namespace Halide {
using HalideTargetPtr2 = Target*;
}
%}
// Define some types
%inline %{
using Int = int;
using IntPtr = Int*;
using IntRef = Int&;
using IntPtrRef = Int*&;
using IntRValueRef = Int&&;
using IntArray = Int[];
%}
// Test that SWIG understands these new types
%callback("%s_cb");
Int mult2(Int x);
%nocallback;
%inline %{
Int mult2(Int x) { return x * 2; }
IntPtr allocate_int() { return new Int(12); }
void free_int(int* ptr) { delete ptr; }
void inplace_mult2(IntRef x) { x *= 2; }
Int read_int(IntPtr ptr) { return *ptr; }
template <typename T> class Pair {
public:
using data_t = T;
data_t a, b;
Pair() : a(), b() { }
Pair(data_t a, data_t b) : a(a), b(b) { }
data_t first() { return a; }
data_t second() { return b; }
};
%}
%template(int_pair) Pair<Int>;
%inline %{
using PairInt = Pair<Int>;
class PairSubclass : public PairInt {
public:
PairSubclass(data_t a, data_t b) : PairInt(a, b) { }
using const_ref_data_t = const data_t&;
};
PairSubclass::data_t plus1(PairSubclass::const_ref_data_t x) { return x + 1; }
%}
// Test function pointers
%inline %{
using callback_t = int(*)(int);
callback_t get_callback() { return mult2; }
int call(callback_t func, int param) { return func(param); }
%}

View file

@ -6,6 +6,12 @@ The primary purpose of this testcase is to ensure that enums used along with the
%inline %{
#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
/* for anonymous enums */
/* dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] */
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
enum SOME_ENUM {ENUM_ONE, ENUM_TWO};
struct StructWithEnums {

View file

@ -0,0 +1,43 @@
using System;
using director_pass_by_valueNamespace;
public class runme
{
private static void WaitForGC()
{
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.Threading.Thread.Sleep(10);
}
static void Main()
{
runme r = new runme();
r.run();
}
void run()
{
Caller caller = new Caller();
caller.call_virtualMethod(new director_pass_by_value_Derived());
{
int countdown = 5;
while (true) {
WaitForGC();
if (--countdown == 0)
break;
};
}
// bug was the passByVal 'global' object was destroyed after the call to virtualMethod had finished.
int ret = runme.passByVal.getVal();
if (ret != 0x12345678)
throw new Exception("Bad return value, got " + ret.ToString("x"));
}
public static PassedByValue passByVal;
}
class director_pass_by_value_Derived : DirectorPassByValueAbstractBase {
public override void virtualMethod(PassedByValue pbv) {
runme.passByVal = pbv;
}
}

View file

@ -0,0 +1,14 @@
%module default_args_c
/* Default arguments for C code */
int foo1(int x = 42 || 3);
int foo43(int x = 42 | 3);
%{
int foo1(int x) {
return x;
}
int foo43(int x) {
return x;
}
%}

View file

@ -0,0 +1,30 @@
%module(directors="1") director_pass_by_value
%director DirectorPassByValueAbstractBase;
%inline %{
class PassedByValue {
int val;
public:
PassedByValue() { val = 0x12345678; }
int getVal() { return val; }
};
int doSomething(int x) {
int yy[256];
yy[0] =0x9876;
return yy[0];
}
class DirectorPassByValueAbstractBase {
public:
virtual void virtualMethod(PassedByValue pbv) = 0;
virtual ~DirectorPassByValueAbstractBase () {}
};
class Caller {
public:
void call_virtualMethod(DirectorPassByValueAbstractBase &f) {
f.virtualMethod(PassedByValue());
}
};
%}

View file

@ -47,6 +47,12 @@
%inline %{
#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
/* for anonymous enums */
/* dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] */
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
enum { AnonEnum1, AnonEnum2 = 100 };
enum { ReallyAnInteger = 200 };
//enum { AnonEnum3, AnonEnum4 } instance;

View file

@ -12,6 +12,12 @@
%inline %{
#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
/* for anonymous enums */
/* dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] */
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
typedef enum {
CSP_ITERATION_FWD,
CSP_ITERATION_BWD = 11

View file

@ -1,4 +0,0 @@
%module xxx
int foo(int x = 42 || 3);

View file

@ -1,3 +0,0 @@
%module xxx
int foo(int x, ...);

View file

@ -0,0 +1,19 @@
%module xxx
// Only non-ignored classes should warn about Ignored base classes
%ignore ActualClass;
%ignore ActualClassNoTemplates;
%{
struct BaseClassNoTemplates {};
%}
%inline %{
template<typename T>
class TemplateClass {};
class ActualClass : public TemplateClass<int> {};
class AktuelKlass : public TemplateClass<int> {};
class ActualClassNoTemplates : public BaseClassNoTemplates {};
class AktuelKlassNoTemplates : public BaseClassNoTemplates {};
%}

View file

@ -0,0 +1,3 @@
cpp_inherit_ignored.i:15: Warning 401: Nothing known about base class 'TemplateClass< int >'. Ignored.
cpp_inherit_ignored.i:15: Warning 401: Maybe you forgot to instantiate 'TemplateClass< int >' using %template.
cpp_inherit_ignored.i:18: Warning 401: Nothing known about base class 'BaseClassNoTemplates'. Ignored.

View file

@ -1,15 +0,0 @@
%module xxx
int foo(int x);
int foo(double x);
class Foo {
public:
int bar(int);
int bar(double);
};
class Spam {
public:
Spam();
Spam(int);
};

View file

@ -1,7 +0,0 @@
%module xxx
class foo {
static const int BAR = 42;
public:
int blah(int x = BAR);
};

View file

@ -1,8 +0,0 @@
%module xxx
template<T> T blah(T x);

View file

@ -4,4 +4,4 @@ template<class T> T blah(T x) { };
%template(iblah) blah<int>;
%template(iiblah) blah<int>;
// The second %template instantiation above should surely be ignored with a warning, but doesn't atm

View file

@ -1,3 +0,0 @@
cpp_using_type_aliasing.i:8: Warning 341: The 'using' keyword in type aliasing is not fully supported yet.
cpp_using_type_aliasing.i:8: Warning 315: Nothing known about 'Okay< int >'.
cpp_using_type_aliasing.i:8: Warning 315: Nothing known about 'Okay< int >'.

View file

@ -1,7 +0,0 @@
%module xxx
#define foo(a,x) a x
#if foo
#endif

View file

@ -1,6 +1,9 @@
%module exception_classname
%warnfilter(SWIGWARN_RUBY_WRONG_NAME);
#ifdef SWIGPHP
%rename(ExceptionClass) Exception;
#endif
%inline %{
class Exception {

View file

@ -40,4 +40,14 @@ func main() {
fmt.Println("got", a, "want", dwant)
panic(a)
}
c2 := go_inout.NewC2()
pm := c2.M()
want = map[string]interface{}{
"ID": float64(1),
}
if !reflect.DeepEqual(*pm, want) {
fmt.Println("for c2.M got", pm, "want", want)
panic(pm)
}
}

View file

@ -1,12 +1,19 @@
package main
import . "./li_std_vector_ptr"
import "fmt"
func check(val1 int, val2 int) {
if val1 != val2 {
panic(fmt.Sprintf("Values are not the same %d %d", val1, val2))
}
}
func main() {
ip1 := MakeIntPtr(11)
ip2 := MakeIntPtr(22)
vi := NewIntPtrVector()
vi.Add(ip1)
vi.Add(ip2)
DisplayVector(vi)
check(GetValueFromVector(vi, 0), 11)
check(GetValueFromVector(vi, 1), 22)
}

View file

@ -23,7 +23,7 @@ struct RetStruct {
// Write a typemap that calls C++ by converting in and out of JSON.
%go_import("encoding/json", "bytes", "encoding/binary")
%go_import("encoding/json", "bytes", "encoding/binary", "reflect", "unsafe")
%insert(go_header)
%{
@ -68,6 +68,26 @@ type In json.Marshaler
}
%}
%typemap(gotype) RetStruct* "*map[string]interface{}"
%typemap(imtype) RetStruct* "*string"
%typemap(out,fragment="AllocateString") RetStruct*
%{
$result = (_gostring_*)malloc(sizeof(_gostring_));
*$result = Swig_AllocateString($1->str.data(), $1->str.length());
%}
%typemap(goout,fragment="CopyString") RetStruct*
%{
defer Swig_free(uintptr(unsafe.Pointer($1)))
var rm map[string]interface{}
if err := json.Unmarshal([]byte(swigCopyString(*$1)), &rm); err != nil {
panic(err)
}
$result = &rm
%}
%inline
%{
@ -87,6 +107,10 @@ struct MyArray {
std::vector<std::string> strings;
};
void* Allocate(int n) {
return new char[n];
}
static uint64_t getuint64(const char* s) {
uint64_t ret = 0;
for (int i = 0; i < 8; i++, s++) {
@ -121,7 +145,12 @@ static void putuint64(std::string *s, size_t off, uint64_t v) {
buf.Write(b[:])
buf.WriteString(s)
}
str := buf.String()
bb := buf.Bytes()
p := Allocate(len(bb))
copy((*[1<<15]byte)(unsafe.Pointer(p))[:len(bb)], bb)
var str string
(*reflect.StringHeader)(unsafe.Pointer(&str)).Data = uintptr(unsafe.Pointer(p))
(*reflect.StringHeader)(unsafe.Pointer(&str)).Len = len(bb)
$result = &str
}
%}
@ -197,3 +226,18 @@ void DoubleArray(MyArray* v) {
}
}
%}
%inline
%{
class C1 {
public:
RetStruct* M() {
RetStruct* r = new RetStruct;
r->str = "{\"ID\":1}";
return r;
}
};
class C2 : public C1 {
};
%}

View file

@ -34,5 +34,5 @@ int inserted_wrapper(int i) { return inserted_header3(i); }
%init %{
// %inserted code %init
int inserted_init_value = inserted_wrapper(0);
int SWIGUNUSED inserted_init_value = inserted_wrapper(0);
%}

View file

@ -5,7 +5,7 @@
LANGUAGE = java
JAVA = @JAVA@
JAVAC = @JAVAC@
JAVAFLAGS = -Xcheck:jni
JAVAFLAGS = @JAVAFLAGS@
SCRIPTSUFFIX = _runme.java
srcdir = @srcdir@

View file

@ -140,7 +140,7 @@ public class director_classes_runme {
Package packag = klass.getPackage();
String simpleName = null;
if (packag != null)
simpleName = fullName.replaceAll(packag.getName() + ".", "");
simpleName = fullName.replaceAll(packag.getName() + "\\.", "");
else
simpleName = fullName;
return simpleName;

View file

@ -0,0 +1,48 @@
import director_pass_by_value.*;
public class director_pass_by_value_runme {
static {
try {
System.loadLibrary("director_pass_by_value");
} 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 WaitForGC() {
System.gc();
System.runFinalization();
try {
java.lang.Thread.sleep(10);
} catch (java.lang.InterruptedException e) {
}
}
public static void main(String argv[]) {
Caller caller = new Caller();
caller.call_virtualMethod(new director_pass_by_value_Derived());
{
int countdown = 5;
while (true) {
WaitForGC();
if (--countdown == 0)
break;
};
}
// bug was the passByVal 'global' object was destroyed after the call to virtualMethod had finished.
int ret = director_pass_by_value_runme.passByVal.getVal();
if (ret != 0x12345678)
throw new RuntimeException("Bad return value, got " + Integer.toHexString(ret));
}
static PassedByValue passByVal;
}
class director_pass_by_value_Derived extends DirectorPassByValueAbstractBase {
public void virtualMethod(PassedByValue pbv) {
director_pass_by_value_runme.passByVal = pbv;
}
}

View file

@ -0,0 +1,19 @@
import smart_pointer_ignore.*;
public class smart_pointer_ignore_runme {
static {
try {
System.loadLibrary("smart_pointer_ignore");
} 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[]) {
DerivedPtr d = smart_pointer_ignore.makeDerived();
d.base();
d.derived();
}
}

View file

@ -25,6 +25,8 @@ namespace boost {
using std::array;
}
%ignore std::array::fill; // Some older versions of boost don't have this function
%include <std_array.i>
%template(ArrayInt6) std::array<int, 6>;

View file

@ -67,7 +67,7 @@ INTEGER bar_getter(Base<INTEGER>& foo) {
// 2nd test - templates with default template parameters
#if defined(SHARED_PTR_WRAPPERS_IMPLEMENTED)
%shared_ptr(Space::BaseDefault<short>)
%shared_ptr(Space::BaseDefault<short, int>)
%shared_ptr(Space::DerivedDefault<short>)
%shared_ptr(Space::DerivedDefault2<short>)

View file

@ -130,3 +130,13 @@ namespace aa {
std::vector< ::aa::Holder > vec1(std::vector< ::aa::Holder > x) { return x; }
%}
#endif
// exercising vectors of strings
%inline %{
std::vector<std::string> RevStringVec (const std::vector<std::string> &In)
{
std::vector<std::string> result(In);
std::reverse(result.begin(), result.end());
return(result);
}
%}

View file

@ -1,4 +1,4 @@
// Bug 2359417
// SF Bug 2359417
%module li_std_vector_ptr
%include "std_vector.i"
@ -15,16 +15,76 @@ double* makeDoublePtr(double v) {
return new double(v);
}
#if 1
// pointer to pointer in the wrappers was preventing a vector of pointers from working
int** makeIntPtrPtr(int* v) {
return new int*(v);
}
#endif
void displayVector(std::vector<int *> vpi) {
cout << "displayVector..." << endl;
for (int i=0; i<vpi.size(); ++i)
for (size_t i=0; i<vpi.size(); ++i)
cout << *vpi[i] << endl;
}
int getValueFromVector(std::vector<int *> vpi, size_t index) {
return *vpi[index];
}
%}
// A not exposed to wrappers
%{
struct A {
int val;
A(int val) : val(val) {}
};
%}
%template(APtrVector) std::vector<A *>;
%inline %{
A *makeA(int val) { return new A(val); }
int getVal(A* a) { return a->val; }
int getVectorValueA(std::vector<A *> vpi, size_t index) {
return vpi[index]->val;
}
%}
// B is fully exposed to wrappers
%inline %{
struct B {
int val;
B(int val = 0) : val(val) {}
};
%}
%template(BPtrVector) std::vector<B *>;
%inline %{
B *makeB(int val) { return new B(val); }
int getVal(B* b) { return b->val; }
int getVectorValueB(std::vector<B *> vpi, size_t index) {
return vpi[index]->val;
}
%}
// C is fully exposed to wrappers (includes code using B **)
%inline %{
struct C {
int val;
C(int val = 0) : val(val) {}
};
%}
%template(CPtrVector) std::vector<C *>;
%inline %{
// pointer to pointer in the wrappers was preventing a vector of pointers from working
C** makeCIntPtrPtr(C* v) {
return new C*(v);
}
C *makeC(int val) { return new C(val); }
int getVal(C* b) { return b->val; }
int getVectorValueC(std::vector<C *> vpi, size_t index) {
return vpi[index]->val;
}
%}

View file

@ -109,7 +109,11 @@ namespace test {
#ifdef SWIGGO
%typemap(gotype) string_class * "string"
%typemap(in) string_class * {
$1 = new string_class($input.p);
char* buf = new char[$input.n + 1];
memcpy(buf, $input.p, $input.n);
buf[$input.n] = '\0';
$1 = new string_class(buf);
delete[] buf;
}
%typemap(freearg) string_class * {
delete $1;

View file

@ -13,6 +13,18 @@ Also tests reported error when a #define placed in a deeply embedded struct/unio
%rename(InUnNamed) OuterStructNamed::Inner_union_named;
#endif
#if defined(SWIG_JAVASCRIPT_V8)
%inline %{
#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
/* for nested C class wrappers compiled as C++ code */
/* dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] */
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
%}
#endif
%inline %{
struct TestStruct {

View file

@ -1,5 +1,17 @@
%module nested_extend_c
#if defined(SWIG_JAVASCRIPT_V8)
%inline %{
#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
/* for nested C class wrappers compiled as C++ code */
/* dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] */
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
%}
#endif
#if !defined(SWIGOCTAVE) && !defined(SWIG_JAVASCRIPT_V8)
%extend hiA {
hiA() {
@ -98,5 +110,9 @@ typedef struct {
static struct {
int i;
} THING;
int useThing() {
return THING.i;
}
%}

View file

@ -0,0 +1,24 @@
%module nested_ignore
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) B::C::D;
%rename($ignore) B::C;
%inline %{
namespace B {
class C {
public:
struct D {
};
};
class E {
public:
typedef C::D D;
};
struct F
{
const E::D foo(){ return E::D(); }
};
}
%}

View file

@ -1,5 +1,17 @@
%module nested_structs
#if defined(SWIG_JAVASCRIPT_V8)
%inline %{
#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
/* for nested C class wrappers compiled as C++ code */
/* dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] */
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
%}
#endif
// bug #491476
%inline %{
struct Outer {

View file

@ -78,6 +78,10 @@ see bottom for a set of possible tests
%rename(OrOperator) operator ||;
#endif
#if defined(SWIGPYTHON)
%feature("python:slot", "tp_str", functype="reprfunc") Op::__str__;
#endif
#ifdef SWIGD
// Due to the way operator overloading is implemented in D1 and D2, the prefix
// increment/decrement operators (D1) resp. the postfix ones (D2) are ignored.
@ -94,8 +98,6 @@ see bottom for a set of possible tests
#include <iso646.h> /* for named logical operator, eg 'operator or' */
#endif
#include <assert.h>
class Op {
public:
int i;
@ -114,11 +116,11 @@ public:
return *this;
}
// +=,-=... are member fns
void operator+=(const Op& o){ i+=o.i;}
void operator-=(const Op& o){ i-=o.i;}
void operator*=(const Op& o){ i*=o.i;}
void operator/=(const Op& o){ i/=o.i;}
void operator%=(const Op& o){ i%=o.i;}
Op &operator+=(const Op& o){ i+=o.i; return *this; }
Op &operator-=(const Op& o){ i-=o.i; return *this; }
Op &operator*=(const Op& o){ i*=o.i; return *this; }
Op &operator/=(const Op& o){ i/=o.i; return *this; }
Op &operator%=(const Op& o){ i%=o.i; return *this; }
// the +,-,*,... are friends
// (just to make life harder)
friend Op operator+(const Op& a,const Op& b){return Op(a.i+b.i);}
@ -250,8 +252,8 @@ public:
%{
#include <assert.h>
#include <stdexcept>
#define ASSERT(X) { if (!(X)) { throw std::runtime_error(#X); } }
void Op::sanity_check()
{
@ -263,66 +265,66 @@ void Op::sanity_check()
Op dd=d; // assignment operator
// test equality
assert(a!=b);
assert(b==c);
assert(a!=d);
assert(d==dd);
ASSERT(a!=b);
ASSERT(b==c);
ASSERT(a!=d);
ASSERT(d==dd);
// test <
assert(a<b);
assert(a<=b);
assert(b<=c);
assert(b>=c);
assert(b>d);
assert(b>=d);
ASSERT(a<b);
ASSERT(a<=b);
ASSERT(b<=c);
ASSERT(b>=c);
ASSERT(b>d);
ASSERT(b>=d);
// test +=
Op e=3;
e+=d;
assert(e==b);
ASSERT(e==b);
e-=c;
assert(e==a);
ASSERT(e==a);
e=Op(1);
e*=b;
assert(e==c);
ASSERT(e==c);
e/=d;
assert(e==d);
ASSERT(e==d);
e%=c;
assert(e==d);
ASSERT(e==d);
// test +
Op f(1),g(1);
assert(f+g==Op(2));
assert(f-g==Op(0));
assert(f*g==Op(1));
assert(f/g==Op(1));
assert(f%g==Op(0));
ASSERT(f+g==Op(2));
ASSERT(f-g==Op(0));
ASSERT(f*g==Op(1));
ASSERT(f/g==Op(1));
ASSERT(f%g==Op(0));
// test unary operators
assert(!a==true);
assert(!b==false);
assert(-a==a);
assert(-b==Op(-5));
ASSERT(!a==true);
ASSERT(!b==false);
ASSERT(-a==a);
ASSERT(-b==Op(-5));
// test []
Op h=3;
assert(h[0]==3);
assert(h[1]==0);
ASSERT(h[0]==3);
ASSERT(h[1]==0);
h[0]=2; // set
assert(h[0]==2);
ASSERT(h[0]==2);
h[1]=2; // ignored
assert(h[0]==2);
assert(h[1]==0);
ASSERT(h[0]==2);
ASSERT(h[1]==0);
// test ()
Op i=3;
assert(i()==3);
assert(i(1)==4);
assert(i(1,2)==6);
ASSERT(i()==3);
ASSERT(i(1)==4);
ASSERT(i(1,2)==6);
// plus add some code to check the __str__ fn
//assert(str(Op(1))=="Op(1)");
//assert(str(Op(-3))=="Op(-3)");
//ASSERT(str(Op(1))=="Op(1)");
//ASSERT(str(Op(-3))=="Op(-3)");
// test ++ and --
Op j(100);
@ -330,36 +332,36 @@ void Op::sanity_check()
{
Op newOp = j++;
int newInt = original++;
assert(j.i == original);
assert(newOp.i == newInt);
ASSERT(j.i == original);
ASSERT(newOp.i == newInt);
}
{
Op newOp = j--;
int newInt = original--;
assert(j.i == original);
assert(newOp.i == newInt);
ASSERT(j.i == original);
ASSERT(newOp.i == newInt);
}
{
Op newOp = ++j;
int newInt = ++original;
assert(j.i == original);
assert(newOp.i == newInt);
ASSERT(j.i == original);
ASSERT(newOp.i == newInt);
}
{
Op newOp = --j;
int newInt = --original;
assert(j.i == original);
assert(newOp.i == newInt);
ASSERT(j.i == original);
ASSERT(newOp.i == newInt);
}
// cast operators
Op k=3;
int check_k = k;
assert (check_k == 3);
ASSERT (check_k == 3);
Op l=4;
double check_l = l;
assert (check_l == 4);
ASSERT (check_l == 4);
}
%}

View file

@ -0,0 +1,20 @@
<?php
require "tests.php";
require "cpp_basic.php";
// New functions
check::functions(array(foo_func1,foo_func2,foo___str__,foosubsub___str__,bar_test,bar_testfoo,get_func1_ptr,get_func2_ptr,test_func_ptr,fl_window_show));
// New classes
check::classes(array(cpp_basic,Foo,FooSub,FooSubSub,Bar,Fl_Window));
// New vars
check::globals(array(foo_num,foo_func_ptr,bar_fptr,bar_fref,bar_fval,bar_cint,bar_global_fptr,bar_global_fref,bar_global_fval));
$f = new Foo(3);
$f->func_ptr = get_func1_ptr();
check::equal(test_func_ptr($f, 7), 2*7*3, "get_func1_ptr() didn't work");
$f->func_ptr = get_func2_ptr();
check::equal(test_func_ptr($f, 7), -7*3, "get_func2_ptr() didn't work");
check::done();
?>

View file

@ -0,0 +1,24 @@
<?php
require "tests.php";
require "director_pass_by_value.php";
$passByVal = null;
class director_pass_by_value_Derived extends DirectorPassByValueAbstractBase {
function virtualMethod($b) {
global $passByVal;
$passByVal = $b;
}
}
# bug was the passByVal global object was destroyed after the call to virtualMethod had finished.
$caller = new Caller();
$caller->call_virtualMethod(new director_pass_by_value_Derived());
$ret = $passByVal->getVal();
if ($ret != 0x12345678) {
check::fail("Bad return value, got " . dechex($ret));
}
check::done();
?>

View file

@ -35,8 +35,9 @@ class check {
foreach($_original_functions[internal] as $func) unset($df[$func]);
// Now chop out any get/set accessors
foreach(array_keys($df) as $func)
if ((GETSET && ereg('_[gs]et$',$func)) || ereg('^new_', $func)
|| ereg('_(alter|get)_newobject$', $func))
if ((GETSET && preg_match('/_[gs]et$/', $func)) ||
preg_match('/^new_/', $func) ||
preg_match('/_(alter|get)_newobject$/', $func))
$extrags[]=$func;
else $extra[]=$func;
// $extra=array_keys($df);
@ -52,7 +53,8 @@ class check {
if (GETSET) {
$_extra=array();
foreach(check::get_extra_functions(false,1) as $global) {
if (ereg('^(.*)_[sg]et$',$global,$match)) $_extra[$match[1]]=1;
if (preg_match('/^(.*)_[sg]et$/', $global, $match))
$_extra[$match[1]] = 1;
}
$extra=array_keys($_extra);
} else {
@ -61,7 +63,8 @@ class check {
$df=array_flip(array_keys($GLOBALS));
foreach($_original_globals as $func) unset($df[$func]);
// MASK xxxx_LOADED__ variables
foreach(array_keys($df) as $func) if (ereg('_LOADED__$',$func)) unset($df[$func]);
foreach(array_keys($df) as $func)
if (preg_match('/_LOADED__$/', $func)) unset($df[$func]);
$extra=array_keys($df);
}
}
@ -185,7 +188,8 @@ class check {
}
function functionref($a,$type,$message) {
if (! eregi("^_[a-f0-9]+$type$",$a)) return check::fail($message);
if (! preg_match("/^_[a-f0-9]+$type$/i", $a))
return check::fail($message);
return TRUE;
}
@ -196,7 +200,8 @@ class check {
function resource($a,$b,$message) {
$resource=trim(check::var_dump($a));
if (! eregi("^resource\([0-9]+\) of type \($b\)",$resource)) return check::fail($message);
if (! preg_match("/^resource\([0-9]+\) of type \($b\)/i", $resource))
return check::fail($message);
return TRUE;
}

View file

@ -102,6 +102,7 @@ ANOTHER_MACRO(int)
void another_macro_checking(void) {
struct Defined d;
d.defined = 10;
(void)d;
thing(10);
stuff(10);
bumpf(10);

View file

@ -58,6 +58,7 @@ CPP_TEST_CASES += \
primitive_types \
python_abstractbase \
python_append \
python_builtin \
python_destructor_exception \
python_director \
python_docstring \

View file

@ -15,11 +15,19 @@ def check(got, expected, expected_builtin=None, skip=False):
def is_new_style_class(cls):
return hasattr(cls, "__class__")
def is_fastproxy(module):
return "new_instancemethod" in module
if not is_new_style_class(A):
# Missing static methods make this hard to test... skip if -classic is
# used!
sys.exit(0)
if is_fastproxy(dir()):
# Detect when -fastproxy is specified and skip test as it changes the function names making it
# hard to test... skip until the number of options are reduced in SWIG-3.1 and autodoc is improved
sys.exit(0)
# skip builtin check - the autodoc is missing, but it probably should not be
skip = True

View file

@ -0,0 +1,32 @@
from cpp11_type_aliasing import *
if get_host_target().bits != 32:
raise RuntimeError("get_host_target().bits should return 32")
if mult2(10) != 20:
raise RuntimeError("mult2(10) should return 20")
int_ptr = allocate_int()
inplace_mult2(int_ptr)
if read_int(int_ptr) != 24:
raise RuntimeError("read_int should return 24")
free_int(int_ptr)
pair = PairSubclass(3, 4)
if pair.first() != 3:
raise RuntimeError("pair.first() should return 3")
if pair.second() != 4:
raise RuntimeError("pair.second() should return 4")
if pair.a != 3:
raise RuntimeError("pair.a should be 3")
if plus1(5) != 6:
raise RuntimeError("plus1(5) should return 6")
if call(mult2_cb, 7) != 14:
raise RuntimeError("call(mult2_cb, 7) should return 14")
if call(get_callback(), 7) != 14:
raise RuntimeError("call(get_callback(), 7) should return 14")

View file

@ -14,4 +14,5 @@ else:
StaticFunctionTest().static_func_2(1)
StaticFunctionTest().static_func_3(1, 2)
StaticMemberTest.static_int = 10
assert StaticMemberTest.static_int == 10
if not StaticMemberTest.static_int == 10:
raise RuntimeError("static_int not 10")

View file

@ -0,0 +1,6 @@
import default_args_c
if default_args_c.foo1() != 1:
raise RuntimeError("failed")
if default_args_c.foo43() != 43:
raise RuntimeError("failed")

View file

@ -0,0 +1,13 @@
import director_pass_by_value
passByVal = None
class director_pass_by_value_Derived(director_pass_by_value.DirectorPassByValueAbstractBase):
def virtualMethod(self, b):
global passByVal
passByVal = b
# bug was the passByVal global object was destroyed after the call to virtualMethod had finished.
director_pass_by_value.Caller().call_virtualMethod(director_pass_by_value_Derived())
ret = passByVal.getVal();
if ret != 0x12345678:
raise RuntimeError("Bad return value, got " + hex(ret))

View file

@ -1,4 +1,5 @@
import exception_classname
a = exception_classname.Exception()
assert a.testfunc() == 42
if a.testfunc() != 42:
raise RuntimeError("Not 42!")

View file

@ -8,9 +8,8 @@ if d.bar() != 2:
raise RuntimeError
if bar_getter(b) != 1:
raise RuntimeError
# Fix reverted in rev 12953
# if bar_getter(d) != 2:
# raise RuntimeError
if bar_getter(d) != 2:
raise RuntimeError
b = BaseDefaultInt()
d = DerivedDefaultInt()
@ -23,8 +22,11 @@ if d2.bar2() != 4:
raise RuntimeError
if bar2_getter(b) != 3:
raise RuntimeError
# Fix reverted in rev 12953
# if bar2_getter(d) != 4:
# raise RuntimeError
# if bar2_getter(d2) != 4:
# raise RuntimeError
# SWIG fix reverted in Subversion rev 12953
# Testcase has now been modified to mask the problem by providing the default parameter 'int' in:
# %shared_ptr(Space::BaseDefault<short, int>)
# If this is not done then d fails to convert to BaseDefault<short>&
if bar2_getter(d) != 4:
raise RuntimeError
if bar2_getter(d2) != 4:
raise RuntimeError

Some files were not shown because too many files have changed in this diff Show more