Merge branch 'master' into C
This commit is contained in:
commit
f919896306
209 changed files with 3791 additions and 2243 deletions
40
.travis.yml
40
.travis.yml
|
|
@ -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
|
||||
|
|
|
|||
8
ANNOUNCE
8
ANNOUNCE
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -267,6 +267,7 @@ char *find_executable(const char *name, const char *exclude_name)
|
|||
}
|
||||
free(fname);
|
||||
}
|
||||
free(path);
|
||||
|
||||
return NULL;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
240
CHANGES
|
|
@ -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 ***
|
||||
|
||||
|
|
|
|||
225
CHANGES.current
225
CHANGES.current
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:<slot>"),
|
||||
where <slot> 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 >= 0x03020000
|
||||
static Py_hash_t myHashFunc(PyObject *pyobj)
|
||||
#else
|
||||
static long myHashFunc(PyObject *pyobj)
|
||||
#endif
|
||||
{
|
||||
MyClass *cobj;
|
||||
// Convert pyobj to cobj
|
||||
return (cobj->field1 * (cobj->field2 << 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 < 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 >= (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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
--> 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>
|
||||
--> 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->size *= factor;
|
||||
};
|
||||
|
||||
void magnify(Circle *circle, double factor) {
|
||||
square->radius *= factor;
|
||||
square->radius *= factor;
|
||||
};
|
||||
</pre></div>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<div class="targetlang"><pre>
|
||||
--> example_Init();
|
||||
--> 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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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; \
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
17
Examples/python/import_packages/namespace_pkg/Makefile
Normal file
17
Examples/python/import_packages/namespace_pkg/Makefile
Normal 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
|
||||
25
Examples/python/import_packages/namespace_pkg/README
Normal file
25
Examples/python/import_packages/namespace_pkg/README
Normal 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.
|
||||
5
Examples/python/import_packages/namespace_pkg/nonpkg.py
Normal file
5
Examples/python/import_packages/namespace_pkg/nonpkg.py
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# import robin as a module in the global namespace
|
||||
|
||||
import robin
|
||||
|
||||
assert(robin.run() == "AWAY!")
|
||||
7
Examples/python/import_packages/namespace_pkg/normal.py
Normal file
7
Examples/python/import_packages/namespace_pkg/normal.py
Normal 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!")
|
||||
45
Examples/python/import_packages/namespace_pkg/nstest.py
Normal file
45
Examples/python/import_packages/namespace_pkg/nstest.py
Normal 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()
|
||||
7
Examples/python/import_packages/namespace_pkg/robin.i
Normal file
7
Examples/python/import_packages/namespace_pkg/robin.i
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
%module robin
|
||||
|
||||
%inline %{
|
||||
const char *run(void) {
|
||||
return "AWAY!";
|
||||
}
|
||||
%}
|
||||
17
Examples/python/import_packages/namespace_pkg/runme.py
Normal file
17
Examples/python/import_packages/namespace_pkg/runme.py
Normal 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()
|
||||
9
Examples/python/import_packages/namespace_pkg/split.py
Normal file
9
Examples/python/import_packages/namespace_pkg/split.py
Normal 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!")
|
||||
|
|
@ -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!")
|
||||
26
Examples/python/import_packages/split_modules/Makefile
Normal file
26
Examples/python/import_packages/split_modules/Makefile
Normal 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
|
||||
7
Examples/python/import_packages/split_modules/README
Normal file
7
Examples/python/import_packages/split_modules/README
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
# killroy was here
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
%module(package="pkg1") foo
|
||||
%{
|
||||
static unsigned count(void)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
%}
|
||||
|
||||
unsigned count(void);
|
||||
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
%module(package="pkg1") foo
|
||||
%{
|
||||
static unsigned count(void)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
%}
|
||||
|
||||
unsigned count(void);
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
# killroy was here
|
||||
|
|
@ -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)
|
||||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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);)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
%}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
43
Examples/test-suite/csharp/director_pass_by_value_runme.cs
Normal file
43
Examples/test-suite/csharp/director_pass_by_value_runme.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
14
Examples/test-suite/default_args_c.i
Normal file
14
Examples/test-suite/default_args_c.i
Normal 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;
|
||||
}
|
||||
%}
|
||||
30
Examples/test-suite/director_pass_by_value.i
Normal file
30
Examples/test-suite/director_pass_by_value.i
Normal 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());
|
||||
}
|
||||
};
|
||||
%}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
%module xxx
|
||||
|
||||
int foo(int x = 42 || 3);
|
||||
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
%module xxx
|
||||
|
||||
int foo(int x, ...);
|
||||
19
Examples/test-suite/errors/cpp_inherit_ignored.i
Normal file
19
Examples/test-suite/errors/cpp_inherit_ignored.i
Normal 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 {};
|
||||
%}
|
||||
3
Examples/test-suite/errors/cpp_inherit_ignored.stderr
Normal file
3
Examples/test-suite/errors/cpp_inherit_ignored.stderr
Normal 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.
|
||||
|
|
@ -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);
|
||||
};
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
%module xxx
|
||||
|
||||
class foo {
|
||||
static const int BAR = 42;
|
||||
public:
|
||||
int blah(int x = BAR);
|
||||
};
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
%module xxx
|
||||
|
||||
template<T> T blah(T x);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 >'.
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
%module xxx
|
||||
|
||||
#define foo(a,x) a x
|
||||
|
||||
#if foo
|
||||
#endif
|
||||
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
%module exception_classname
|
||||
|
||||
%warnfilter(SWIGWARN_RUBY_WRONG_NAME);
|
||||
#ifdef SWIGPHP
|
||||
%rename(ExceptionClass) Exception;
|
||||
#endif
|
||||
|
||||
%inline %{
|
||||
class Exception {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
};
|
||||
%}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
%}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
LANGUAGE = java
|
||||
JAVA = @JAVA@
|
||||
JAVAC = @JAVAC@
|
||||
JAVAFLAGS = -Xcheck:jni
|
||||
JAVAFLAGS = @JAVAFLAGS@
|
||||
SCRIPTSUFFIX = _runme.java
|
||||
|
||||
srcdir = @srcdir@
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
48
Examples/test-suite/java/director_pass_by_value_runme.java
Normal file
48
Examples/test-suite/java/director_pass_by_value_runme.java
Normal 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;
|
||||
}
|
||||
}
|
||||
19
Examples/test-suite/java/smart_pointer_ignore_runme.java
Normal file
19
Examples/test-suite/java/smart_pointer_ignore_runme.java
Normal 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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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>;
|
||||
|
|
|
|||
|
|
@ -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>)
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
%}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
%}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
%}
|
||||
|
||||
|
|
|
|||
24
Examples/test-suite/nested_ignore.i
Normal file
24
Examples/test-suite/nested_ignore.i
Normal 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(); }
|
||||
};
|
||||
}
|
||||
%}
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
%}
|
||||
|
|
|
|||
20
Examples/test-suite/php/cpp_basic_runme.php
Normal file
20
Examples/test-suite/php/cpp_basic_runme.php
Normal 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();
|
||||
?>
|
||||
24
Examples/test-suite/php/director_pass_by_value_runme.php
Normal file
24
Examples/test-suite/php/director_pass_by_value_runme.php
Normal 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();
|
||||
?>
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ CPP_TEST_CASES += \
|
|||
primitive_types \
|
||||
python_abstractbase \
|
||||
python_append \
|
||||
python_builtin \
|
||||
python_destructor_exception \
|
||||
python_director \
|
||||
python_docstring \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
32
Examples/test-suite/python/cpp11_type_aliasing_runme.py
Normal file
32
Examples/test-suite/python/cpp11_type_aliasing_runme.py
Normal 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")
|
||||
|
|
@ -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")
|
||||
|
|
|
|||
6
Examples/test-suite/python/default_args_c_runme.py
Normal file
6
Examples/test-suite/python/default_args_c_runme.py
Normal 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")
|
||||
13
Examples/test-suite/python/director_pass_by_value_runme.py
Normal file
13
Examples/test-suite/python/director_pass_by_value_runme.py
Normal 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))
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import exception_classname
|
||||
|
||||
a = exception_classname.Exception()
|
||||
assert a.testfunc() == 42
|
||||
if a.testfunc() != 42:
|
||||
raise RuntimeError("Not 42!")
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue