Merge branch 'master' into directorargout_and_java_typemaps
This commit is contained in:
commit
3e449ea05f
68 changed files with 2861 additions and 2151 deletions
97
.travis.yml
97
.travis.yml
|
|
@ -4,9 +4,16 @@ matrix:
|
||||||
- compiler: clang
|
- compiler: clang
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=
|
env: SWIGLANG=
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=
|
env: SWIGLANG=
|
||||||
|
- compiler: gcc
|
||||||
|
os: linux
|
||||||
|
env: SWIGLANG=
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- os: linux
|
- os: linux
|
||||||
env: SWIGLANG= SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
env: SWIGLANG= SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
||||||
sudo: required
|
sudo: required
|
||||||
|
|
@ -18,12 +25,18 @@ matrix:
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=csharp
|
env: SWIGLANG=csharp
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=d
|
env: SWIGLANG=d
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=go
|
env: SWIGLANG=go
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=go VER=1.5
|
env: SWIGLANG=go VER=1.5
|
||||||
|
|
@ -32,21 +45,31 @@ matrix:
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=guile
|
env: SWIGLANG=guile
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=java
|
env: SWIGLANG=java
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=javascript ENGINE=node
|
env: SWIGLANG=javascript ENGINE=node
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=javascript ENGINE=jsc
|
env: SWIGLANG=javascript ENGINE=jsc
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=javascript ENGINE=v8
|
env: SWIGLANG=javascript ENGINE=v8
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=lua
|
env: SWIGLANG=lua
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=lua VER=5.3
|
env: SWIGLANG=lua VER=5.3
|
||||||
|
|
@ -64,69 +87,118 @@ matrix:
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=perl5
|
env: SWIGLANG=perl5
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=php
|
env: SWIGLANG=php
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=python VER=2.4
|
env: SWIGLANG=python VER=2.4
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=python VER=2.5
|
env: SWIGLANG=python VER=2.5
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=python VER=2.6
|
env: SWIGLANG=python VER=2.6
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=python # 2.7
|
env: SWIGLANG=python # 2.7
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=python PY3=3 # 3.2
|
env: SWIGLANG=python PY3=3 VER=3.2
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=python PY3=3 VER=3.3
|
env: SWIGLANG=python PY3=3 VER=3.3
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=python PY3=3 VER=3.4
|
env: SWIGLANG=python PY3=3 VER=3.4
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=python PY3=3 VER=3.5
|
env: SWIGLANG=python PY3=3 VER=3.5
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=python SWIG_FEATURES=-builtin VER=2.6
|
env: SWIGLANG=python SWIG_FEATURES=-builtin VER=2.6
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=python SWIG_FEATURES=-builtin
|
env: SWIGLANG=python SWIG_FEATURES=-builtin
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3
|
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.4
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.5
|
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.5
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.5 SWIGOPTPY3=
|
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.5 SWIGOPTPY3=
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=python SWIG_FEATURES=-O
|
env: SWIGLANG=python SWIG_FEATURES=-O
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=python SWIG_FEATURES=-classic
|
env: SWIGLANG=python SWIG_FEATURES=-classic
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=r
|
env: SWIGLANG=r
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=ruby
|
env: SWIGLANG=ruby VER=1.9.3
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
|
- compiler: gcc
|
||||||
|
os: linux
|
||||||
|
env: SWIGLANG=ruby VER=2.0.0
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=ruby VER=2.3.0
|
env: SWIGLANG=ruby VER=2.3.0
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=scilab
|
env: SWIGLANG=scilab
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=tcl
|
env: SWIGLANG=tcl
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
- os: linux
|
- os: linux
|
||||||
env: SWIGLANG=csharp SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
env: SWIGLANG=csharp SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
|
||||||
sudo: required
|
sudo: required
|
||||||
|
|
@ -151,8 +223,9 @@ matrix:
|
||||||
env: SWIGLANG=python SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
env: SWIGLANG=python SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
- os: osx
|
- compiler: gcc
|
||||||
env: SWIGLANG= SWIG_CC=gcc-4.2 SWIG_CXX=g++-4.2
|
os: osx
|
||||||
|
env: SWIGLANG=
|
||||||
- compiler: clang
|
- compiler: clang
|
||||||
os: osx
|
os: osx
|
||||||
env: SWIGLANG=
|
env: SWIGLANG=
|
||||||
|
|
@ -162,6 +235,9 @@ matrix:
|
||||||
- compiler: clang
|
- compiler: clang
|
||||||
os: osx
|
os: osx
|
||||||
env: SWIGLANG=go
|
env: SWIGLANG=go
|
||||||
|
- compiler: clang
|
||||||
|
os: osx
|
||||||
|
env: SWIGLANG=guile
|
||||||
- compiler: clang
|
- compiler: clang
|
||||||
os: osx
|
os: osx
|
||||||
env: SWIGLANG=java
|
env: SWIGLANG=java
|
||||||
|
|
@ -192,14 +268,14 @@ matrix:
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=ocaml
|
env: SWIGLANG=ocaml
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
# Not quite working yet
|
# Not quite working yet
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
os: linux
|
os: linux
|
||||||
env: SWIGLANG=python SWIG_FEATURES=-O
|
env: SWIGLANG=python SWIG_FEATURES=-O
|
||||||
# brew install guile fails on Travis as OSX 10.9 is too old now, default osx_image needs changing
|
sudo: required
|
||||||
- compiler: clang
|
dist: trusty
|
||||||
os: osx
|
|
||||||
env: SWIGLANG=guile
|
|
||||||
before_install:
|
before_install:
|
||||||
- date -u
|
- date -u
|
||||||
- uname -a
|
- uname -a
|
||||||
|
|
@ -240,6 +316,3 @@ script:
|
||||||
- echo 'Cleaning...' && echo -en 'travis_fold:start:script.3\\r'
|
- echo 'Cleaning...' && echo -en 'travis_fold:start:script.3\\r'
|
||||||
- make check-maintainer-clean && ../../configure $CONFIGOPTS
|
- make check-maintainer-clean && ../../configure $CONFIGOPTS
|
||||||
- echo -en 'travis_fold:end:script.3\\r'
|
- echo -en 'travis_fold:end:script.3\\r'
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,38 @@ See the RELEASENOTES file for a summary of changes in each release.
|
||||||
Version 3.0.11 (in progress)
|
Version 3.0.11 (in progress)
|
||||||
============================
|
============================
|
||||||
|
|
||||||
|
2016-10-30: myd7349
|
||||||
|
[C#] Patch #740 Add std_array.i for C# for wrapping std::array.
|
||||||
|
|
||||||
|
Patch also enhances std::vector<std::wstring> C# wrappers with additional functions
|
||||||
|
(Contains, IndexOf, LastIndexOf and Remove).
|
||||||
|
|
||||||
|
2016-10-30: tobilau
|
||||||
|
[Java] Fix wrappers for wstring parameters in director methods to cleanup local
|
||||||
|
ref after director callback has finished.
|
||||||
|
|
||||||
|
2016-10-23: wsfulton
|
||||||
|
[C#] Add missing csdirectorin VOID_INT_PTR and csdirectorout VOID_INT_PTR typemaps.
|
||||||
|
|
||||||
|
2016-10-23: jiulongw
|
||||||
|
Patch #781 - Fix wrapping of C compound expressions containing char constants
|
||||||
|
in quotes such as:
|
||||||
|
|
||||||
|
#define H_SUPPRESS_SCALING_MAGIC (('s'<<24) | ('u'<<16) | ('p'<<8) | 'p')
|
||||||
|
|
||||||
|
enum DifferentTypes {
|
||||||
|
typecharcompound='A'+1,
|
||||||
|
typecharcompound2='B' << 2
|
||||||
|
};
|
||||||
|
|
||||||
|
2016-10-13: wsfulton
|
||||||
|
[Python] Issue #808 - fix Python pickling and metaclass for builtin wrappers.
|
||||||
|
|
||||||
|
The metaclass (SwigPyObjectType) for SWIG objects was not defined in
|
||||||
|
a way that let importlib successfully import the Python wrappers.
|
||||||
|
The pickle module previously failed to pickle objects because it couldn't
|
||||||
|
determine what module the SWIG wrapped objects were in.
|
||||||
|
|
||||||
2016-09-29: wsfulton
|
2016-09-29: wsfulton
|
||||||
[Allegrocl, CFFI, GO, Javascript, Ocaml, R, Scilab]
|
[Allegrocl, CFFI, GO, Javascript, Ocaml, R, Scilab]
|
||||||
Add missing support for the "ret" typemap in a few target languages.
|
Add missing support for the "ret" typemap in a few target languages.
|
||||||
|
|
|
||||||
|
|
@ -280,39 +280,39 @@ actual function.
|
||||||
|
|
||||||
<div class="code">example_wrap.i
|
<div class="code">example_wrap.i
|
||||||
<pre>
|
<pre>
|
||||||
... lots of SWIG internals ...
|
... lots of SWIG internals ...
|
||||||
|
|
||||||
EXPORT int ACL___fact__SWIG_0 (char *larg1) {
|
EXPORT int ACL___fact__SWIG_0 (char *larg1) {
|
||||||
int lresult = (int)0 ;
|
int lresult = (int)0 ;
|
||||||
char *arg1 = (char *) 0 ;
|
char *arg1 = (char *) 0 ;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
arg1 = larg1;
|
arg1 = larg1;
|
||||||
try {
|
try {
|
||||||
result = (int)fact(arg1);
|
result = (int)fact(arg1);
|
||||||
|
|
||||||
lresult = result;
|
lresult = result;
|
||||||
return lresult;
|
return lresult;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
return (int)0;
|
return (int)0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EXPORT int ACL___fact__SWIG_1 (int larg1) {
|
EXPORT int ACL___fact__SWIG_1 (int larg1) {
|
||||||
int lresult = (int)0 ;
|
int lresult = (int)0 ;
|
||||||
int arg1 ;
|
int arg1 ;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
arg1 = larg1;
|
arg1 = larg1;
|
||||||
try {
|
try {
|
||||||
result = (int)fact(arg1);
|
result = (int)fact(arg1);
|
||||||
|
|
||||||
lresult = result;
|
lresult = result;
|
||||||
return lresult;
|
return lresult;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
return (int)0;
|
return (int)0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -324,7 +324,7 @@ what is generated when parsing C code:
|
||||||
|
|
||||||
<div class="targetlang">
|
<div class="targetlang">
|
||||||
<pre>
|
<pre>
|
||||||
...
|
...
|
||||||
|
|
||||||
(swig-in-package ())
|
(swig-in-package ())
|
||||||
|
|
||||||
|
|
@ -688,10 +688,10 @@ char *xxx();
|
||||||
%include "foo.h"
|
%include "foo.h"
|
||||||
|
|
||||||
namespace car {
|
namespace car {
|
||||||
...
|
...
|
||||||
namespace tires {
|
namespace tires {
|
||||||
int do_something(int n);
|
int do_something(int n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1209,8 +1209,8 @@ class schema.
|
||||||
<div class="code">synonyms.h
|
<div class="code">synonyms.h
|
||||||
<pre>
|
<pre>
|
||||||
class A {
|
class A {
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef A Foo;
|
typedef A Foo;
|
||||||
|
|
@ -1336,70 +1336,70 @@ float xxx(A *inst, int x); /* return x + A->x + A->y */
|
||||||
<div class="code">overload_wrap.cxx
|
<div class="code">overload_wrap.cxx
|
||||||
<pre>
|
<pre>
|
||||||
EXPORT void ACL___delete_A__SWIG_0 (A *larg1) {
|
EXPORT void ACL___delete_A__SWIG_0 (A *larg1) {
|
||||||
A *arg1 = (A *) 0 ;
|
A *arg1 = (A *) 0 ;
|
||||||
|
|
||||||
arg1 = larg1;
|
arg1 = larg1;
|
||||||
try {
|
try {
|
||||||
delete arg1;
|
delete arg1;
|
||||||
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EXPORT float ACL___xxx__SWIG_0 (int larg1, int larg2) {
|
EXPORT float ACL___xxx__SWIG_0 (int larg1, int larg2) {
|
||||||
float lresult = (float)0 ;
|
float lresult = (float)0 ;
|
||||||
int arg1 ;
|
int arg1 ;
|
||||||
int arg2 ;
|
int arg2 ;
|
||||||
float result;
|
float result;
|
||||||
|
|
||||||
arg1 = larg1;
|
arg1 = larg1;
|
||||||
arg2 = larg2;
|
arg2 = larg2;
|
||||||
try {
|
try {
|
||||||
result = (float)xxx(arg1,arg2);
|
result = (float)xxx(arg1,arg2);
|
||||||
|
|
||||||
lresult = result;
|
lresult = result;
|
||||||
return lresult;
|
return lresult;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
return (float)0;
|
return (float)0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EXPORT float ACL___xxx__SWIG_1 (int larg1) {
|
EXPORT float ACL___xxx__SWIG_1 (int larg1) {
|
||||||
float lresult = (float)0 ;
|
float lresult = (float)0 ;
|
||||||
int arg1 ;
|
int arg1 ;
|
||||||
float result;
|
float result;
|
||||||
|
|
||||||
arg1 = larg1;
|
arg1 = larg1;
|
||||||
try {
|
try {
|
||||||
result = (float)xxx(arg1);
|
result = (float)xxx(arg1);
|
||||||
|
|
||||||
lresult = result;
|
lresult = result;
|
||||||
return lresult;
|
return lresult;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
return (float)0;
|
return (float)0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EXPORT float ACL___xxx__SWIG_2 (A *larg1, int larg2) {
|
EXPORT float ACL___xxx__SWIG_2 (A *larg1, int larg2) {
|
||||||
float lresult = (float)0 ;
|
float lresult = (float)0 ;
|
||||||
A *arg1 = (A *) 0 ;
|
A *arg1 = (A *) 0 ;
|
||||||
int arg2 ;
|
int arg2 ;
|
||||||
float result;
|
float result;
|
||||||
|
|
||||||
arg1 = larg1;
|
arg1 = larg1;
|
||||||
arg2 = larg2;
|
arg2 = larg2;
|
||||||
try {
|
try {
|
||||||
result = (float)xxx(arg1,arg2);
|
result = (float)xxx(arg1,arg2);
|
||||||
|
|
||||||
lresult = result;
|
lresult = result;
|
||||||
return lresult;
|
return lresult;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
return (float)0;
|
return (float)0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1675,21 +1675,21 @@ opoverload>
|
||||||
<pre>
|
<pre>
|
||||||
return-val wrapper-name(parm0, parm1, ..., parmN)
|
return-val wrapper-name(parm0, parm1, ..., parmN)
|
||||||
{
|
{
|
||||||
return-val lresult; /* return value from wrapper */
|
return-val lresult; /* return value from wrapper */
|
||||||
<local-declaration>
|
<local-declaration>
|
||||||
... results; /* return value from function call */
|
... results; /* return value from function call */
|
||||||
|
|
||||||
<binding locals to parameters>
|
<binding locals to parameters>
|
||||||
|
|
||||||
try {
|
try {
|
||||||
result = function-name(local0, local1, ..., localN);
|
result = function-name(local0, local1, ..., localN);
|
||||||
|
|
||||||
<convert and bind result to lresult>
|
<convert and bind result to lresult>
|
||||||
|
|
||||||
return lresult;
|
return lresult;
|
||||||
catch (...) {
|
catch (...) {
|
||||||
return (int)0;
|
return (int)0;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -457,10 +457,10 @@ This kind of initialization is handled by SWIG.
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
class SomeClass {
|
class SomeClass {
|
||||||
public:
|
public:
|
||||||
SomeClass() {}
|
SomeClass() {}
|
||||||
explicit SomeClass(int new_value) : value(new_value) {}
|
explicit SomeClass(int new_value) : value(new_value) {}
|
||||||
|
|
||||||
int value = 5;
|
int value = 5;
|
||||||
};
|
};
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
|
|
@ -688,7 +688,7 @@ initializers) with some limitations. The following code is correctly parsed:</p>
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
template <typename... BaseClasses> class ClassName : public BaseClasses... {
|
template <typename... BaseClasses> class ClassName : public BaseClasses... {
|
||||||
public:
|
public:
|
||||||
ClassName (BaseClasses &&... baseClasses) : BaseClasses(baseClasses)... {}
|
ClassName (BaseClasses &&... baseClasses) : BaseClasses(baseClasses)... {}
|
||||||
}
|
}
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
|
|
@ -818,7 +818,7 @@ reachable by the current thread can be defined as:</p>
|
||||||
|
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
struct A {
|
struct A {
|
||||||
static thread_local int val;
|
static thread_local int val;
|
||||||
};
|
};
|
||||||
thread_local int global_val;
|
thread_local int global_val;
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
@ -858,8 +858,8 @@ For example, the C++ compiler will not compile any code which attempts to use an
|
||||||
|
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
struct NoInt {
|
struct NoInt {
|
||||||
void f(double i);
|
void f(double i);
|
||||||
void f(int) = delete;
|
void f(int) = delete;
|
||||||
};
|
};
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1021,17 +1021,17 @@ Now let's analyse the generated code to gain a fuller understanding of the typem
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
SWIGEXPORT void SWIGSTDCALL CSharp_positivesonly(int jarg1) {
|
SWIGEXPORT void SWIGSTDCALL CSharp_positivesonly(int jarg1) {
|
||||||
int arg1 ;
|
int arg1 ;
|
||||||
|
|
||||||
arg1 = (int)jarg1;
|
arg1 = (int)jarg1;
|
||||||
|
|
||||||
if (arg1 < 0) {
|
if (arg1 < 0) {
|
||||||
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException,
|
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException,
|
||||||
"only positive numbers accepted", "number");
|
"only positive numbers accepted", "number");
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
positivesonly(arg1);
|
positivesonly(arg1);
|
||||||
|
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
@ -1155,18 +1155,17 @@ The generated unmanaged code this time catches the C++ exception and converts it
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
SWIGEXPORT void SWIGSTDCALL CSharp_negativesonly(int jarg1) {
|
SWIGEXPORT void SWIGSTDCALL CSharp_negativesonly(int jarg1) {
|
||||||
int arg1 ;
|
int arg1 ;
|
||||||
|
|
||||||
arg1 = (int)jarg1;
|
arg1 = (int)jarg1;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
negativesonly(arg1);
|
negativesonly(arg1);
|
||||||
|
|
||||||
} catch (std::out_of_range e) {
|
|
||||||
SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, e.what());
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
} catch (std::out_of_range e) {
|
||||||
|
SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, e.what());
|
||||||
|
return ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1221,19 +1220,18 @@ SWIG generates a try catch block with the throws typemap code in the catch handl
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
SWIGEXPORT void SWIGSTDCALL CSharp_evensonly(int jarg1) {
|
SWIGEXPORT void SWIGSTDCALL CSharp_evensonly(int jarg1) {
|
||||||
int arg1 ;
|
int arg1 ;
|
||||||
|
|
||||||
arg1 = (int)jarg1;
|
arg1 = (int)jarg1;
|
||||||
try {
|
try {
|
||||||
evensonly(arg1);
|
evensonly(arg1);
|
||||||
|
}
|
||||||
|
catch(std::out_of_range &_e) {
|
||||||
|
{
|
||||||
|
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentException, (&_e)->what(), NULL);
|
||||||
|
return ;
|
||||||
}
|
}
|
||||||
catch(std::out_of_range &_e) {
|
}
|
||||||
{
|
|
||||||
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentException, (&_e)->what(), NULL);
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1643,20 +1641,20 @@ SWIGEXPORT void SWIGSTDCALL CSharp_Base_director_connect(void *objarg,
|
||||||
|
|
||||||
class SwigDirector_Base : public Base, public Swig::Director {
|
class SwigDirector_Base : public Base, public Swig::Director {
|
||||||
public:
|
public:
|
||||||
SwigDirector_Base();
|
SwigDirector_Base();
|
||||||
virtual unsigned int UIntMethod(unsigned int x);
|
virtual unsigned int UIntMethod(unsigned int x);
|
||||||
virtual ~SwigDirector_Base();
|
virtual ~SwigDirector_Base();
|
||||||
virtual void BaseBoolMethod(Base const &b, bool flag);
|
virtual void BaseBoolMethod(Base const &b, bool flag);
|
||||||
|
|
||||||
typedef unsigned int (SWIGSTDCALL* SWIG_Callback0_t)(unsigned int);
|
typedef unsigned int (SWIGSTDCALL* SWIG_Callback0_t)(unsigned int);
|
||||||
typedef void (SWIGSTDCALL* SWIG_Callback1_t)(void *, unsigned int);
|
typedef void (SWIGSTDCALL* SWIG_Callback1_t)(void *, unsigned int);
|
||||||
void swig_connect_director(SWIG_Callback0_t callbackUIntMethod,
|
void swig_connect_director(SWIG_Callback0_t callbackUIntMethod,
|
||||||
SWIG_Callback1_t callbackBaseBoolMethod);
|
SWIG_Callback1_t callbackBaseBoolMethod);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SWIG_Callback0_t swig_callbackUIntMethod;
|
SWIG_Callback0_t swig_callbackUIntMethod;
|
||||||
SWIG_Callback1_t swig_callbackBaseBoolMethod;
|
SWIG_Callback1_t swig_callbackBaseBoolMethod;
|
||||||
void swig_init_callbacks();
|
void swig_init_callbacks();
|
||||||
};
|
};
|
||||||
|
|
||||||
void SwigDirector_Base::swig_connect_director(SWIG_Callback0_t callbackUIntMethod,
|
void SwigDirector_Base::swig_connect_director(SWIG_Callback0_t callbackUIntMethod,
|
||||||
|
|
@ -1940,10 +1938,10 @@ and usage from C++
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
Container container;
|
Container container;
|
||||||
Element element(20);
|
Element element(20);
|
||||||
container.setElement(&element);
|
container.setElement(&element);
|
||||||
cout << "element.value: " << container.getElement()->value << endl;
|
cout << "element.value: " << container.getElement()->value << endl;
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,9 +51,9 @@ is a simple example:
|
||||||
<pre>
|
<pre>
|
||||||
%contract sqrt(double x) {
|
%contract sqrt(double x) {
|
||||||
require:
|
require:
|
||||||
x >= 0;
|
x >= 0;
|
||||||
ensure:
|
ensure:
|
||||||
sqrt >= 0;
|
sqrt >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
@ -106,20 +106,20 @@ The <tt>%contract</tt> directive can also be applied to class methods and constr
|
||||||
<pre>
|
<pre>
|
||||||
%contract Foo::bar(int x, int y) {
|
%contract Foo::bar(int x, int y) {
|
||||||
require:
|
require:
|
||||||
x > 0;
|
x > 0;
|
||||||
ensure:
|
ensure:
|
||||||
bar > 0;
|
bar > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
%contract Foo::Foo(int a) {
|
%contract Foo::Foo(int a) {
|
||||||
require:
|
require:
|
||||||
a > 0;
|
a > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Foo {
|
class Foo {
|
||||||
public:
|
public:
|
||||||
Foo(int);
|
Foo(int);
|
||||||
int bar(int, int);
|
int bar(int, int);
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -133,7 +133,7 @@ Thus, any contract that you specified for a base class will also be attached to
|
||||||
<pre>
|
<pre>
|
||||||
class Spam : public Foo {
|
class Spam : public Foo {
|
||||||
public:
|
public:
|
||||||
int bar(int,int); // Gets contract defined for Foo::bar(int,int)
|
int bar(int,int); // Gets contract defined for Foo::bar(int,int)
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -146,22 +146,22 @@ In addition to this, separate contracts can be applied to both the base class an
|
||||||
<pre>
|
<pre>
|
||||||
%contract Foo::bar(int x, int) {
|
%contract Foo::bar(int x, int) {
|
||||||
require:
|
require:
|
||||||
x > 0;
|
x > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
%contract Spam::bar(int, int y) {
|
%contract Spam::bar(int, int y) {
|
||||||
require:
|
require:
|
||||||
y > 0;
|
y > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Foo {
|
class Foo {
|
||||||
public:
|
public:
|
||||||
int bar(int,int); // Gets Foo::bar contract.
|
int bar(int,int); // Gets Foo::bar contract.
|
||||||
};
|
};
|
||||||
|
|
||||||
class Spam : public Foo {
|
class Spam : public Foo {
|
||||||
public:
|
public:
|
||||||
int bar(int,int); // Gets Foo::bar and Spam::bar contract
|
int bar(int,int); // Gets Foo::bar and Spam::bar contract
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -225,7 +225,7 @@ function can be used in contracts. For example:
|
||||||
|
|
||||||
%contract move(SomeObject *, int direction, in) {
|
%contract move(SomeObject *, int direction, in) {
|
||||||
require:
|
require:
|
||||||
check_direction(direction);
|
check_direction(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UP 1
|
#define UP 1
|
||||||
|
|
@ -246,7 +246,7 @@ Alternatively, it can be used in typemaps and other directives. For example:
|
||||||
%aggregate_check(int, check_direction, UP, DOWN, RIGHT, LEFT);
|
%aggregate_check(int, check_direction, UP, DOWN, RIGHT, LEFT);
|
||||||
|
|
||||||
%typemap(check) int direction {
|
%typemap(check) int direction {
|
||||||
if (!check_direction($1)) SWIG_exception(SWIG_ValueError, "Bad direction");
|
if (!check_direction($1)) SWIG_exception(SWIG_ValueError, "Bad direction");
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UP 1
|
#define UP 1
|
||||||
|
|
|
||||||
|
|
@ -56,12 +56,12 @@ handler. For example, you can specify the following:
|
||||||
|
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
%exception {
|
%exception {
|
||||||
try {
|
try {
|
||||||
$action
|
$action
|
||||||
}
|
}
|
||||||
catch (RangeError) {
|
catch (RangeError) {
|
||||||
... handle error ...
|
... handle error ...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
|
|
@ -71,13 +71,13 @@ How the exception is handled depends on the target language, for example, Python
|
||||||
|
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
%exception {
|
%exception {
|
||||||
try {
|
try {
|
||||||
$action
|
$action
|
||||||
}
|
}
|
||||||
catch (RangeError) {
|
catch (RangeError) {
|
||||||
PyErr_SetString(PyExc_IndexError,"index out-of-bounds");
|
PyErr_SetString(PyExc_IndexError,"index out-of-bounds");
|
||||||
SWIG_fail;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
|
|
@ -341,12 +341,12 @@ to specific declaration name. For example:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%exception allocate {
|
%exception allocate {
|
||||||
try {
|
try {
|
||||||
$action
|
$action
|
||||||
}
|
}
|
||||||
catch (MemoryError) {
|
catch (MemoryError) {
|
||||||
croak("Out of memory");
|
croak("Out of memory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -364,12 +364,12 @@ an exception handler for a specific class, you might write this:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%exception Object::allocate {
|
%exception Object::allocate {
|
||||||
try {
|
try {
|
||||||
$action
|
$action
|
||||||
}
|
}
|
||||||
catch (MemoryError) {
|
catch (MemoryError) {
|
||||||
croak("Out of memory");
|
croak("Out of memory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -386,12 +386,12 @@ in the specified class as well as for identically named functions appearing in d
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%exception Object::allocate(int) {
|
%exception Object::allocate(int) {
|
||||||
try {
|
try {
|
||||||
$action
|
$action
|
||||||
}
|
}
|
||||||
catch (MemoryError) {
|
catch (MemoryError) {
|
||||||
croak("Out of memory");
|
croak("Out of memory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -410,21 +410,21 @@ to attach exceptions to specific parts of a header file. For example:
|
||||||
|
|
||||||
// Define a few exception handlers for specific declarations
|
// Define a few exception handlers for specific declarations
|
||||||
%exception Object::allocate(int) {
|
%exception Object::allocate(int) {
|
||||||
try {
|
try {
|
||||||
$action
|
$action
|
||||||
}
|
}
|
||||||
catch (MemoryError) {
|
catch (MemoryError) {
|
||||||
croak("Out of memory");
|
croak("Out of memory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
%exception Object::getitem {
|
%exception Object::getitem {
|
||||||
try {
|
try {
|
||||||
$action
|
$action
|
||||||
}
|
}
|
||||||
catch (RangeError) {
|
catch (RangeError) {
|
||||||
croak("Index out of range");
|
croak("Index out of range");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
...
|
...
|
||||||
// Read a raw header file
|
// Read a raw header file
|
||||||
|
|
@ -560,17 +560,17 @@ common scripting language exceptions in a portable manner. For example :</p>
|
||||||
%include exception.i
|
%include exception.i
|
||||||
|
|
||||||
%exception {
|
%exception {
|
||||||
try {
|
try {
|
||||||
$action
|
$action
|
||||||
} catch(RangeError) {
|
} catch(RangeError) {
|
||||||
SWIG_exception(SWIG_ValueError, "Range Error");
|
SWIG_exception(SWIG_ValueError, "Range Error");
|
||||||
} catch(DivisionByZero) {
|
} catch(DivisionByZero) {
|
||||||
SWIG_exception(SWIG_DivisionByZero, "Division by zero");
|
SWIG_exception(SWIG_DivisionByZero, "Division by zero");
|
||||||
} catch(OutOfMemory) {
|
} catch(OutOfMemory) {
|
||||||
SWIG_exception(SWIG_MemoryError, "Out of memory");
|
SWIG_exception(SWIG_MemoryError, "Out of memory");
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
SWIG_exception(SWIG_RuntimeError,"Unknown exception");
|
SWIG_exception(SWIG_RuntimeError,"Unknown exception");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
@ -611,8 +611,8 @@ example, consider a function like this:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
Foo *blah() {
|
Foo *blah() {
|
||||||
Foo *f = new Foo();
|
Foo *f = new Foo();
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -771,12 +771,12 @@ using the <tt>%feature</tt> directive. For example:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%feature("except") Object::allocate {
|
%feature("except") Object::allocate {
|
||||||
try {
|
try {
|
||||||
$action
|
$action
|
||||||
}
|
}
|
||||||
catch (MemoryError) {
|
catch (MemoryError) {
|
||||||
croak("Out of memory");
|
croak("Out of memory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
%feature("new","1") *::copy;
|
%feature("new","1") *::copy;
|
||||||
|
|
@ -811,10 +811,10 @@ are defined. For example:
|
||||||
<pre>
|
<pre>
|
||||||
/* Define a global exception handler */
|
/* Define a global exception handler */
|
||||||
%feature("except") {
|
%feature("except") {
|
||||||
try {
|
try {
|
||||||
$action
|
$action
|
||||||
}
|
}
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|
||||||
... bunch of declarations ...
|
... bunch of declarations ...
|
||||||
|
|
@ -867,11 +867,11 @@ In the following example, <tt>MyExceptionClass</tt> is the name of the Java clas
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%feature("except", throws="MyExceptionClass") Object::method {
|
%feature("except", throws="MyExceptionClass") Object::method {
|
||||||
try {
|
try {
|
||||||
$action
|
$action
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
... code to throw a MyExceptionClass Java exception ...
|
... code to throw a MyExceptionClass Java exception ...
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -993,21 +993,21 @@ To clarify, let's consider the <tt>except</tt> feature again (<tt>%exception</tt
|
||||||
<pre>
|
<pre>
|
||||||
// Define global exception handler
|
// Define global exception handler
|
||||||
%feature("except") {
|
%feature("except") {
|
||||||
try {
|
try {
|
||||||
$action
|
$action
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
croak("Unknown C++ exception");
|
croak("Unknown C++ exception");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define exception handler for all clone methods to log the method calls
|
// Define exception handler for all clone methods to log the method calls
|
||||||
%feature("except") *::clone() {
|
%feature("except") *::clone() {
|
||||||
try {
|
try {
|
||||||
logger.info("$action");
|
logger.info("$action");
|
||||||
$action
|
$action
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
croak("Unknown C++ exception");
|
croak("Unknown C++ exception");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
... initial set of class declarations with clone methods ...
|
... initial set of class declarations with clone methods ...
|
||||||
|
|
@ -1165,14 +1165,14 @@ in the Python module. You might use <tt>%feature</tt> to rewrite proxy/shadow cl
|
||||||
%feature("shadow") Foo::bar(int) %{
|
%feature("shadow") Foo::bar(int) %{
|
||||||
def bar(*args):
|
def bar(*args):
|
||||||
if len(args) == 3:
|
if len(args) == 3:
|
||||||
return apply(examplec.Foo_bar_id,args)
|
return apply(examplec.Foo_bar_id,args)
|
||||||
return apply(examplec.Foo_bar,args)
|
return apply(examplec.Foo_bar,args)
|
||||||
%}
|
%}
|
||||||
|
|
||||||
class Foo {
|
class Foo {
|
||||||
public:
|
public:
|
||||||
int bar(int x);
|
int bar(int x);
|
||||||
int bar(int x, double y);
|
int bar(int x, double y);
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -229,8 +229,9 @@ void foo(SomeClass arg) {
|
||||||
|
|
||||||
%newobject bar();
|
%newobject bar();
|
||||||
SomeClass *bar();
|
SomeClass *bar();
|
||||||
%}</pre></div>
|
%}
|
||||||
<p>The code generated for <tt>foo()</tt> and <tt>bar()</tt> looks like this:</p>
|
</pre></div>
|
||||||
|
<p>The code generated for <tt>foo()</tt> and <tt>bar()</tt> looks like this:</p>
|
||||||
<div class="targetlang"><pre>
|
<div class="targetlang"><pre>
|
||||||
SomeClass foo() {
|
SomeClass foo() {
|
||||||
return new SomeClass(example_im.foo(), false);
|
return new SomeClass(example_im.foo(), false);
|
||||||
|
|
|
||||||
|
|
@ -772,8 +772,8 @@ low-level <tt>%feature</tt> directive. For example:
|
||||||
...
|
...
|
||||||
class Foo {
|
class Foo {
|
||||||
public:
|
public:
|
||||||
Object *getitem(int index) throws(badindex);
|
Object *getitem(int index) throws(badindex);
|
||||||
...
|
...
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -826,7 +826,7 @@ transformed. For example, suppose you are wrapping a class like this:
|
||||||
<pre>
|
<pre>
|
||||||
class Foo {
|
class Foo {
|
||||||
public:
|
public:
|
||||||
virtual int *bar(int x);
|
virtual int *bar(int x);
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1381,14 +1381,14 @@ List *l = (some list);
|
||||||
Iterator i;
|
Iterator i;
|
||||||
|
|
||||||
for (i = First(l); i.item; i = Next(i)) {
|
for (i = First(l); i.item; i = Next(i)) {
|
||||||
Printf(stdout,"%s\n", i.item);
|
Printf(stdout,"%s\n", i.item);
|
||||||
}
|
}
|
||||||
|
|
||||||
Hash *h = (some hash);
|
Hash *h = (some hash);
|
||||||
Iterator j;
|
Iterator j;
|
||||||
|
|
||||||
for (j = First(j); j.item; j= Next(j)) {
|
for (j = First(j); j.item; j= Next(j)) {
|
||||||
Printf(stdout,"%s : %s\n", j.key, j.item);
|
Printf(stdout,"%s : %s\n", j.key, j.item);
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1517,7 +1517,7 @@ common to see small code fragments of code generated using code like this:
|
||||||
String *s = NewString("");
|
String *s = NewString("");
|
||||||
Printf(s,"Hello\n");
|
Printf(s,"Hello\n");
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
Printf(s,"%d\n", i);
|
Printf(s,"%d\n", i);
|
||||||
}
|
}
|
||||||
...
|
...
|
||||||
/* Print string into a file */
|
/* Print string into a file */
|
||||||
|
|
@ -1674,10 +1674,10 @@ Since parse tree nodes are just hash tables, attributes are accessed using the <
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
int functionHandler(Node *n) {
|
int functionHandler(Node *n) {
|
||||||
String *name = Getattr(n,"name");
|
String *name = Getattr(n,"name");
|
||||||
String *symname = Getattr(n,"sym:name");
|
String *symname = Getattr(n,"sym:name");
|
||||||
SwigType *type = Getattr(n,"type");
|
SwigType *type = Getattr(n,"type");
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1703,8 +1703,8 @@ A quick way to check the value of an attribute is to use the <tt>checkAttribute(
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
if (checkAttribute(n,"storage","virtual")) {
|
if (checkAttribute(n,"storage","virtual")) {
|
||||||
/* n is virtual */
|
/* n is virtual */
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1750,17 +1750,17 @@ Calls can be nested if necessary. Here is an example that shows how the functio
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
int variableHandler(Node *n) {
|
int variableHandler(Node *n) {
|
||||||
Swig_save("variableHandler",n,"type","sym:name",NIL);
|
Swig_save("variableHandler",n,"type","sym:name",NIL);
|
||||||
String *symname = Getattr(n,"sym:name");
|
String *symname = Getattr(n,"sym:name");
|
||||||
SwigType *type = Getattr(n,"type");
|
SwigType *type = Getattr(n,"type");
|
||||||
...
|
...
|
||||||
Append(symname,"_global"); // Change symbol name
|
Append(symname,"_global"); // Change symbol name
|
||||||
SwigType_add_pointer(type); // Add pointer
|
SwigType_add_pointer(type); // Add pointer
|
||||||
...
|
...
|
||||||
generate wrappers
|
generate wrappers
|
||||||
...
|
...
|
||||||
Swig_restore(n); // Restore original values
|
Swig_restore(n); // Restore original values
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2375,10 +2375,10 @@ code like this:
|
||||||
Parm *parms;
|
Parm *parms;
|
||||||
Parm *p;
|
Parm *p;
|
||||||
for (p = parms; p; p = nextSibling(p)) {
|
for (p = parms; p; p = nextSibling(p)) {
|
||||||
SwigType *type = Getattr(p,"type");
|
SwigType *type = Getattr(p,"type");
|
||||||
String *name = Getattr(p,"name");
|
String *name = Getattr(p,"name");
|
||||||
String *value = Getattr(p,"value");
|
String *value = Getattr(p,"value");
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2650,19 +2650,19 @@ insert some code like this:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
void main(int argc, char *argv[]) {
|
void main(int argc, char *argv[]) {
|
||||||
... command line options ...
|
... command line options ...
|
||||||
|
|
||||||
/* Set language-specific subdirectory in SWIG library */
|
/* Set language-specific subdirectory in SWIG library */
|
||||||
SWIG_library_directory("python");
|
SWIG_library_directory("python");
|
||||||
|
|
||||||
/* Set language-specific preprocessing symbol */
|
/* Set language-specific preprocessing symbol */
|
||||||
Preprocessor_define("SWIGPYTHON 1", 0);
|
Preprocessor_define("SWIGPYTHON 1", 0);
|
||||||
|
|
||||||
/* Set language-specific configuration file */
|
/* Set language-specific configuration file */
|
||||||
SWIG_config_file("python.swg");
|
SWIG_config_file("python.swg");
|
||||||
|
|
||||||
/* Set typemap language (historical) */
|
/* Set typemap language (historical) */
|
||||||
SWIG_typemap_lang("python");
|
SWIG_typemap_lang("python");
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2721,26 +2721,26 @@ An outline of <tt>top()</tt> might be as follows:
|
||||||
<pre>
|
<pre>
|
||||||
int Python::top(Node *n) {
|
int Python::top(Node *n) {
|
||||||
|
|
||||||
/* Get the module name */
|
/* Get the module name */
|
||||||
String *module = Getattr(n,"name");
|
String *module = Getattr(n,"name");
|
||||||
|
|
||||||
/* Get the output file name */
|
/* Get the output file name */
|
||||||
String *outfile = Getattr(n,"outfile");
|
String *outfile = Getattr(n,"outfile");
|
||||||
|
|
||||||
/* Initialize I/O (see next section) */
|
/* Initialize I/O (see next section) */
|
||||||
...
|
...
|
||||||
|
|
||||||
/* Output module initialization code */
|
/* Output module initialization code */
|
||||||
...
|
...
|
||||||
|
|
||||||
/* Emit code for children */
|
/* Emit code for children */
|
||||||
Language::top(n);
|
Language::top(n);
|
||||||
|
|
||||||
...
|
...
|
||||||
/* Cleanup files */
|
/* Cleanup files */
|
||||||
...
|
...
|
||||||
|
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2777,62 +2777,62 @@ such as:
|
||||||
<pre>
|
<pre>
|
||||||
class PYTHON : public Language {
|
class PYTHON : public Language {
|
||||||
protected:
|
protected:
|
||||||
/* General DOH objects used for holding the strings */
|
/* General DOH objects used for holding the strings */
|
||||||
File *f_begin;
|
File *f_begin;
|
||||||
File *f_runtime;
|
File *f_runtime;
|
||||||
File *f_header;
|
File *f_header;
|
||||||
File *f_wrappers;
|
File *f_wrappers;
|
||||||
File *f_init;
|
File *f_init;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
...
|
...
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int Python::top(Node *n) {
|
int Python::top(Node *n) {
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
/* Initialize I/O */
|
/* Initialize I/O */
|
||||||
f_begin = NewFile(outfile, "w", SWIG_output_files());
|
f_begin = NewFile(outfile, "w", SWIG_output_files());
|
||||||
if (!f_begin) {
|
if (!f_begin) {
|
||||||
FileErrorDisplay(outfile);
|
FileErrorDisplay(outfile);
|
||||||
SWIG_exit(EXIT_FAILURE);
|
SWIG_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
f_runtime = NewString("");
|
f_runtime = NewString("");
|
||||||
f_init = NewString("");
|
f_init = NewString("");
|
||||||
f_header = NewString("");
|
f_header = NewString("");
|
||||||
f_wrappers = NewString("");
|
f_wrappers = NewString("");
|
||||||
|
|
||||||
/* Register file targets with the SWIG file handler */
|
/* Register file targets with the SWIG file handler */
|
||||||
Swig_register_filebyname("begin", f_begin);
|
Swig_register_filebyname("begin", f_begin);
|
||||||
Swig_register_filebyname("header", f_header);
|
Swig_register_filebyname("header", f_header);
|
||||||
Swig_register_filebyname("wrapper", f_wrappers);
|
Swig_register_filebyname("wrapper", f_wrappers);
|
||||||
Swig_register_filebyname("runtime", f_runtime);
|
Swig_register_filebyname("runtime", f_runtime);
|
||||||
Swig_register_filebyname("init", f_init);
|
Swig_register_filebyname("init", f_init);
|
||||||
|
|
||||||
/* Output module initialization code */
|
/* Output module initialization code */
|
||||||
Swig_banner(f_begin);
|
Swig_banner(f_begin);
|
||||||
...
|
...
|
||||||
|
|
||||||
/* Emit code for children */
|
/* Emit code for children */
|
||||||
Language::top(n);
|
Language::top(n);
|
||||||
|
|
||||||
...
|
...
|
||||||
/* Write all to the file */
|
/* Write all to the file */
|
||||||
Dump(f_runtime, f_begin);
|
Dump(f_runtime, f_begin);
|
||||||
Dump(f_header, f_begin);
|
Dump(f_header, f_begin);
|
||||||
Dump(f_wrappers, f_begin);
|
Dump(f_wrappers, f_begin);
|
||||||
Wrapper_pretty_print(f_init, f_begin);
|
Wrapper_pretty_print(f_init, f_begin);
|
||||||
|
|
||||||
/* Cleanup files */
|
/* Cleanup files */
|
||||||
Delete(f_runtime);
|
Delete(f_runtime);
|
||||||
Delete(f_header);
|
Delete(f_header);
|
||||||
Delete(f_wrappers);
|
Delete(f_wrappers);
|
||||||
Delete(f_init);
|
Delete(f_init);
|
||||||
Delete(f_begin);
|
Delete(f_begin);
|
||||||
|
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -300,34 +300,34 @@ extern bool example_initialize(JSGlobalContextRef context);
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
// Initialize GTK+
|
// Initialize GTK+
|
||||||
gtk_init(&argc, &argv);
|
gtk_init(&argc, &argv);
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
// Create a browser instance
|
// Create a browser instance
|
||||||
WebKitWebView *webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
|
WebKitWebView *webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
|
||||||
WebFrame *webframe = webkit_web_view_get_main_frame(webView);
|
WebFrame *webframe = webkit_web_view_get_main_frame(webView);
|
||||||
JSGlobalContextRef context = webkit_web_frame_get_global_context(webFrame);
|
JSGlobalContextRef context = webkit_web_frame_get_global_context(webFrame);
|
||||||
JSObjectRef global = JSContextGetGlobalObject(context);
|
JSObjectRef global = JSContextGetGlobalObject(context);
|
||||||
|
|
||||||
JSObjectRef exampleModule;
|
JSObjectRef exampleModule;
|
||||||
example_initialize(context, &exampleModule);
|
example_initialize(context, &exampleModule);
|
||||||
JSStringRef jsName = JSStringCreateWithUTF8CString("example");
|
JSStringRef jsName = JSStringCreateWithUTF8CString("example");
|
||||||
JSObjectSetProperty(context, global, jsName, exampleModule, kJSPropertyAttributeReadOnly, NULL);
|
JSObjectSetProperty(context, global, jsName, exampleModule, kJSPropertyAttributeReadOnly, NULL);
|
||||||
JSStringRelease(jsName);
|
JSStringRelease(jsName);
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
// Load a web page into the browser instance
|
// Load a web page into the browser instance
|
||||||
webkit_web_view_load_uri(webView, "http://www.webkitgtk.org/");
|
webkit_web_view_load_uri(webView, "http://www.webkitgtk.org/");
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
// Run the main GTK+ event loop
|
// Run the main GTK+ event loop
|
||||||
gtk_main();
|
gtk_main();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}</pre>
|
}</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -218,13 +218,13 @@ interface is as follows:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
struct name {
|
struct name {
|
||||||
name(); // Create pointer object
|
name(); // Create pointer object
|
||||||
~name(); // Delete pointer object
|
~name(); // Delete pointer object
|
||||||
void assign(type value); // Assign value
|
void assign(type value); // Assign value
|
||||||
type value(); // Get value
|
type value(); // Get value
|
||||||
type *cast(); // Cast the pointer to original type
|
type *cast(); // Cast the pointer to original type
|
||||||
static name *frompointer(type *); // Create class wrapper from existing
|
static name *frompointer(type *); // Create class wrapper from existing
|
||||||
// pointer
|
// pointer
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -384,10 +384,10 @@ function like this:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
void print_array(double x[10]) {
|
void print_array(double x[10]) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
printf("[%d] = %g\n", i, x[i]);
|
printf("[%d] = %g\n", i, x[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -436,13 +436,13 @@ interface is as follows:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
struct name {
|
struct name {
|
||||||
name(int nelements); // Create an array
|
name(int nelements); // Create an array
|
||||||
~name(); // Delete array
|
~name(); // Delete array
|
||||||
type getitem(int index); // Return item
|
type getitem(int index); // Return item
|
||||||
void setitem(int index, type value); // Set item
|
void setitem(int index, type value); // Set item
|
||||||
type *cast(); // Cast to original type
|
type *cast(); // Cast to original type
|
||||||
static name *frompointer(type *); // Create class wrapper from
|
static name *frompointer(type *); // Create class wrapper from
|
||||||
// existing pointer
|
// existing pointer
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -874,9 +874,9 @@ If you have a function that allocates memory like this,
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
char *foo() {
|
char *foo() {
|
||||||
char *result = (char *) malloc(...);
|
char *result = (char *) malloc(...);
|
||||||
...
|
...
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -919,16 +919,16 @@ implementation:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
void get_path(char *s) {
|
void get_path(char *s) {
|
||||||
// Potential buffer overflow---uh, oh.
|
// Potential buffer overflow---uh, oh.
|
||||||
sprintf(s,"%s/%s", base_directory, sub_directory);
|
sprintf(s,"%s/%s", base_directory, sub_directory);
|
||||||
}
|
}
|
||||||
...
|
...
|
||||||
// Somewhere else in the C program
|
// Somewhere else in the C program
|
||||||
{
|
{
|
||||||
char path[1024];
|
char path[1024];
|
||||||
...
|
...
|
||||||
get_path(path);
|
get_path(path);
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1236,8 +1236,8 @@ returned in a parameter of type <tt>char **</tt>. For example:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
void foo(char **s) {
|
void foo(char **s) {
|
||||||
*s = (char *) malloc(64);
|
*s = (char *) malloc(64);
|
||||||
sprintf(*s, "Hello world\n");
|
sprintf(*s, "Hello world\n");
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1284,10 +1284,10 @@ returned in two parameters of type <tt>char **</tt> and <tt>int *</tt>. For exa
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
void foo(char **s, int *sz) {
|
void foo(char **s, int *sz) {
|
||||||
*s = (char *) malloc(64);
|
*s = (char *) malloc(64);
|
||||||
*sz = 64;
|
*sz = 64;
|
||||||
// Write some binary data
|
// Write some binary data
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1337,7 +1337,7 @@ You could wrap it with a function like this:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
void my_get_data(char **result, int *len) {
|
void my_get_data(char **result, int *len) {
|
||||||
*result = get_data(len);
|
*result = get_data(len);
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1503,8 +1503,8 @@ instantiate different versions of <tt>vector</tt> for the types that you want to
|
||||||
%include "std_vector.i"
|
%include "std_vector.i"
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
%template(vectori) vector<int>;
|
%template(vectori) vector<int>;
|
||||||
%template(vectord) vector<double>;
|
%template(vectord) vector<double>;
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1554,19 +1554,19 @@ To illustrate the use of this library, consider the following functions:
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
double average(std::vector<int> v) {
|
double average(std::vector<int> v) {
|
||||||
return std::accumulate(v.begin(),v.end(),0.0)/v.size();
|
return std::accumulate(v.begin(),v.end(),0.0)/v.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<double> half(const std::vector<double>& v) {
|
std::vector<double> half(const std::vector<double>& v) {
|
||||||
std::vector<double> w(v);
|
std::vector<double> w(v);
|
||||||
for (unsigned int i=0; i<w.size(); i++)
|
for (unsigned int i=0; i<w.size(); i++)
|
||||||
w[i] /= 2.0;
|
w[i] /= 2.0;
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
void halve_in_place(std::vector<double>& v) {
|
void halve_in_place(std::vector<double>& v) {
|
||||||
std::transform(v.begin(),v.end(),v.begin(),
|
std::transform(v.begin(),v.end(),v.begin(),
|
||||||
std::bind2nd(std::divides<double>(),2.0));
|
std::bind2nd(std::divides<double>(),2.0));
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1585,8 +1585,8 @@ To wrap with SWIG, you might write the following:
|
||||||
%include "std_vector.i"
|
%include "std_vector.i"
|
||||||
// Instantiate templates used by example
|
// Instantiate templates used by example
|
||||||
namespace std {
|
namespace std {
|
||||||
%template(IntVector) vector<int>;
|
%template(IntVector) vector<int>;
|
||||||
%template(DoubleVector) vector<double>;
|
%template(DoubleVector) vector<double>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include the header file with above prototypes
|
// Include the header file with above prototypes
|
||||||
|
|
@ -1645,7 +1645,7 @@ make sure you include the appropriate <tt>using</tt> or typedef directives. For
|
||||||
%include "std_vector.i"
|
%include "std_vector.i"
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
%template(IntVector) vector<int>;
|
%template(IntVector) vector<int>;
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
@ -2011,11 +2011,11 @@ For example:
|
||||||
<pre>
|
<pre>
|
||||||
%include "exception.i"
|
%include "exception.i"
|
||||||
%exception std::vector::getitem {
|
%exception std::vector::getitem {
|
||||||
try {
|
try {
|
||||||
$action
|
$action
|
||||||
} catch (std::out_of_range& e) {
|
} catch (std::out_of_range& e) {
|
||||||
SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what()));
|
SWIG_exception(SWIG_IndexError,const_cast<char*>(e.what()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -134,17 +134,16 @@ typedef int days;
|
||||||
|
|
||||||
struct bar {
|
struct bar {
|
||||||
short p, q;
|
short p, q;
|
||||||
char a, b;
|
char a, b;
|
||||||
int *z[1000];
|
int *z[1000];
|
||||||
struct bar * n;
|
struct bar * n;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bar * my_struct;
|
struct bar * my_struct;
|
||||||
|
|
||||||
struct foo {
|
struct foo {
|
||||||
int a;
|
int a;
|
||||||
struct foo * b[100];
|
struct foo * b[100];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int pointer_func(void (*ClosureFun)( void* _fun, void* _data, void* _evt ), int p);
|
int pointer_func(void (*ClosureFun)( void* _fun, void* _data, void* _evt ), int p);
|
||||||
|
|
@ -436,44 +435,41 @@ Various features which were available for C headers can also be used
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
namespace OpenDemo {
|
namespace OpenDemo {
|
||||||
class Test
|
class Test
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
float x;
|
float x;
|
||||||
// constructors
|
// constructors
|
||||||
Test (void) {x = 0;}
|
Test (void) {x = 0;}
|
||||||
Test (float X) {x = X;}
|
Test (float X) {x = X;}
|
||||||
|
|
||||||
// vector addition
|
// vector addition
|
||||||
Test operator+ (const Test& v) const {return Test (x+v.x);}
|
Test operator+ (const Test& v) const {return Test (x+v.x);}
|
||||||
|
|
||||||
// length squared
|
// length squared
|
||||||
float lengthSquared (void) const {return this->dot (*this);}
|
float lengthSquared (void) const {return this->dot (*this);}
|
||||||
|
|
||||||
static float distance (const Test& a, const Test& b){return(a-b).length();}
|
static float distance (const Test& a, const Test& b){return(a-b).length();}
|
||||||
|
|
||||||
inline Test parallelComponent (const Test& unitBasis) const {
|
inline Test parallelComponent (const Test& unitBasis) const {
|
||||||
return unitBasis * projection;
|
return unitBasis * projection;
|
||||||
}
|
}
|
||||||
|
|
||||||
Test setYtoZero (void) const {return Test (this->x);}
|
Test setYtoZero (void) const {return Test (this->x);}
|
||||||
|
|
||||||
static const Test zero;
|
static const Test zero;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline Test operator* (float s, const Test& v) {return v*s;}
|
||||||
|
|
||||||
inline Test operator* (float s, const Test& v) {return v*s;}
|
inline std::ostream& operator<< (std::ostream& o, const Test& v)
|
||||||
|
{
|
||||||
|
return o << "(" << v.x << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Test RandomUnitVectorOnXZPlane (void)
|
||||||
inline std::ostream& operator<< (std::ostream& o, const Test& v)
|
{
|
||||||
{
|
return RandomVectorInUnitRadiusSphere().setYtoZero().normalize();
|
||||||
return o << "(" << v.x << ")";
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Test RandomUnitVectorOnXZPlane (void)
|
|
||||||
{
|
|
||||||
return RandomVectorInUnitRadiusSphere().setYtoZero().normalize();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</pre></div>
|
</pre></div>
|
||||||
<p>The interface used is: </p>
|
<p>The interface used is: </p>
|
||||||
|
|
@ -778,10 +774,10 @@ The module also handles strutcures and #define constants as shown
|
||||||
</p>
|
</p>
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
struct bar {
|
struct bar {
|
||||||
short x, y;
|
short x, y;
|
||||||
char a, b;
|
char a, b;
|
||||||
int *z[1000];
|
int *z[1000];
|
||||||
struct bar * n;
|
struct bar * n;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define max 1000
|
#define max 1000
|
||||||
|
|
|
||||||
|
|
@ -521,9 +521,9 @@ Enums are exported into a class table. For example, given some enums:
|
||||||
<div class="code"><pre>%module example
|
<div class="code"><pre>%module example
|
||||||
enum Days { SUNDAY = 0, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };
|
enum Days { SUNDAY = 0, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };
|
||||||
struct Test {
|
struct Test {
|
||||||
enum { TEST1 = 10, TEST2 = 20 };
|
enum { TEST1 = 10, TEST2 = 20 };
|
||||||
#ifdef __cplusplus // There are no static members in C
|
#ifdef __cplusplus // There are no static members in C
|
||||||
static const int ICONST = 12;
|
static const int ICONST = 12;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
@ -645,12 +645,12 @@ Like the pointer in the previous section, this is held as a userdata. However, a
|
||||||
<tt>const</tt> members of a structure are read-only. Data members can also be forced to be read-only using the immutable directive. As with other immutables, setting attempts will be cause an error. For example:
|
<tt>const</tt> members of a structure are read-only. Data members can also be forced to be read-only using the immutable directive. As with other immutables, setting attempts will be cause an error. For example:
|
||||||
</p>
|
</p>
|
||||||
<div class="code"><pre>struct Foo {
|
<div class="code"><pre>struct Foo {
|
||||||
...
|
...
|
||||||
%immutable;
|
%immutable;
|
||||||
int x; // Read-only members
|
int x; // Read-only members
|
||||||
char *name;
|
char *name;
|
||||||
%mutable;
|
%mutable;
|
||||||
...
|
...
|
||||||
};
|
};
|
||||||
</pre></div>
|
</pre></div>
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -661,11 +661,11 @@ When a member of a structure is itself a structure, it is handled as a pointer.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code"><pre>struct Foo {
|
<div class="code"><pre>struct Foo {
|
||||||
int a;
|
int a;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Bar {
|
struct Bar {
|
||||||
Foo f;
|
Foo f;
|
||||||
};
|
};
|
||||||
</pre></div>
|
</pre></div>
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -695,8 +695,8 @@ Because the pointer points inside the structure, you can modify the contents and
|
||||||
For eLua with the <tt>-eluac</tt> option, structure manipulation has to be performed with specific structure functions generated by SWIG. Let's say you have the following structure definition:
|
For eLua with the <tt>-eluac</tt> option, structure manipulation has to be performed with specific structure functions generated by SWIG. Let's say you have the following structure definition:
|
||||||
</p>
|
</p>
|
||||||
<div class="code"><pre>struct data {
|
<div class="code"><pre>struct data {
|
||||||
int x, y;
|
int x, y;
|
||||||
double z;
|
double z;
|
||||||
};
|
};
|
||||||
|
|
||||||
> --From eLua
|
> --From eLua
|
||||||
|
|
@ -749,8 +749,8 @@ Class data members are accessed in the same manner as C structures. Static class
|
||||||
</p>
|
</p>
|
||||||
<div class="targetlang"><pre>class Spam {
|
<div class="targetlang"><pre>class Spam {
|
||||||
public:
|
public:
|
||||||
static void foo();
|
static void foo();
|
||||||
static int bar;
|
static int bar;
|
||||||
};
|
};
|
||||||
</pre></div>
|
</pre></div>
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -871,9 +871,9 @@ Similarly, if you have a class like this,
|
||||||
</p>
|
</p>
|
||||||
<div class="code"><pre>class Foo {
|
<div class="code"><pre>class Foo {
|
||||||
public:
|
public:
|
||||||
Foo();
|
Foo();
|
||||||
Foo(const Foo &);
|
Foo(const Foo &);
|
||||||
...
|
...
|
||||||
};
|
};
|
||||||
</pre></div>
|
</pre></div>
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1090,13 +1090,14 @@ public:
|
||||||
Now we extend it with some new code
|
Now we extend it with some new code
|
||||||
</p>
|
</p>
|
||||||
<div class="code"><pre>%extend Complex {
|
<div class="code"><pre>%extend Complex {
|
||||||
const char *__str__() {
|
const char *__str__() {
|
||||||
static char tmp[1024];
|
static char tmp[1024];
|
||||||
sprintf(tmp,"Complex(%g,%g)", $self->re(),$self->im());
|
sprintf(tmp,"Complex(%g,%g)", $self->re(),$self->im());
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
bool operator==(const Complex& c)
|
bool operator==(const Complex& c) {
|
||||||
{ return ($self->re()==c.re() && $self->im()==c.im());}
|
return ($self->re()==c.re() && $self->im()==c.im());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</pre></div>
|
</pre></div>
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1123,9 +1124,9 @@ Extend works with both C and C++ code, on classes and structs. It does not modif
|
||||||
<p> If you have a function that allocates memory like this,</p>
|
<p> If you have a function that allocates memory like this,</p>
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>char *foo() {
|
<pre>char *foo() {
|
||||||
char *result = (char *) malloc(...);
|
char *result = (char *) malloc(...);
|
||||||
...
|
...
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1154,12 +1155,12 @@ char *foo();
|
||||||
|
|
||||||
template<class T1, class T2>
|
template<class T1, class T2>
|
||||||
struct pair {
|
struct pair {
|
||||||
typedef T1 first_type;
|
typedef T1 first_type;
|
||||||
typedef T2 second_type;
|
typedef T2 second_type;
|
||||||
T1 first;
|
T1 first;
|
||||||
T2 second;
|
T2 second;
|
||||||
pair();
|
pair();
|
||||||
pair(const T1&, const T2&);
|
pair(const T1&, const T2&);
|
||||||
~pair();
|
~pair();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1183,9 +1184,9 @@ Obviously, there is more to template wrapping than shown in this example. More d
|
||||||
In certain C++ programs, it is common to use classes that have been wrapped by so-called "smart pointers." Generally, this involves the use of a template class that implements operator->() like this:
|
In certain C++ programs, it is common to use classes that have been wrapped by so-called "smart pointers." Generally, this involves the use of a template class that implements operator->() like this:
|
||||||
</p>
|
</p>
|
||||||
<div class="code"><pre>template<class T> class SmartPtr {
|
<div class="code"><pre>template<class T> class SmartPtr {
|
||||||
...
|
...
|
||||||
T *operator->();
|
T *operator->();
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
</pre></div>
|
</pre></div>
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1193,8 +1194,8 @@ Then, if you have a class like this,
|
||||||
</p>
|
</p>
|
||||||
<div class="code"><pre>class Foo {
|
<div class="code"><pre>class Foo {
|
||||||
public:
|
public:
|
||||||
int x;
|
int x;
|
||||||
int bar();
|
int bar();
|
||||||
};
|
};
|
||||||
</pre></div>
|
</pre></div>
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1564,17 +1565,17 @@ Received an integer : 6
|
||||||
<p>However for more complex functions which use input/output parameters or arrays, you will need to make use of <typemaps.i>, which contains typemaps for these situations. For example, consider these functions:</p>
|
<p>However for more complex functions which use input/output parameters or arrays, you will need to make use of <typemaps.i>, which contains typemaps for these situations. For example, consider these functions:</p>
|
||||||
|
|
||||||
<div class="code"><pre>void add(int x, int y, int *result) {
|
<div class="code"><pre>void add(int x, int y, int *result) {
|
||||||
*result = x + y;
|
*result = x + y;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sub(int *x1, int *y1) {
|
int sub(int *x1, int *y1) {
|
||||||
return *x1-*y1;
|
return *x1-*y1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(int *sx, int *sy) {
|
void swap(int *sx, int *sy) {
|
||||||
int t=*sx;
|
int t=*sx;
|
||||||
*sx=*sy;
|
*sx=*sy;
|
||||||
*sy=t;
|
*sy=t;
|
||||||
}
|
}
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
|
|
@ -1739,7 +1740,7 @@ ptr=nil -- the iMath* will be GC'ed as normal
|
||||||
<div class="indent">
|
<div class="indent">
|
||||||
This is the standard function used for converting a Lua userdata to a void*. It takes the value at the given index in the Lua state and converts it to a userdata. It will then provide the necessary type checks, confirming that the pointer is compatible with the type given in 'type'. Then finally setting '*ptr' to the pointer.
|
This is the standard function used for converting a Lua userdata to a void*. It takes the value at the given index in the Lua state and converts it to a userdata. It will then provide the necessary type checks, confirming that the pointer is compatible with the type given in 'type'. Then finally setting '*ptr' to the pointer.
|
||||||
If flags is set to SWIG_POINTER_DISOWN, this is will clear any ownership flag set on the object.<br>
|
If flags is set to SWIG_POINTER_DISOWN, this is will clear any ownership flag set on the object.<br>
|
||||||
The returns a value which can be checked with the macro SWIG_IsOK()
|
This returns a value which can be checked with the macro SWIG_IsOK()
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p><tt>void SWIG_NewPointerObj(lua_State* L,void* ptr,swig_type_info *type,int own);</tt></p>
|
<p><tt>void SWIG_NewPointerObj(lua_State* L,void* ptr,swig_type_info *type,int own);</tt></p>
|
||||||
|
|
|
||||||
|
|
@ -36,12 +36,12 @@ Example interface file:
|
||||||
/* define a macro for the struct creation */
|
/* define a macro for the struct creation */
|
||||||
%define handle_ptr(TYPE,NAME)
|
%define handle_ptr(TYPE,NAME)
|
||||||
%typemap(argout) TYPE *NAME{
|
%typemap(argout) TYPE *NAME{
|
||||||
Scheme_Object *o = SWIG_NewStructFromPtr($1, $*1_mangle);
|
Scheme_Object *o = SWIG_NewStructFromPtr($1, $*1_mangle);
|
||||||
SWIG_APPEND_VALUE(o);
|
SWIG_APPEND_VALUE(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
%typemap(in,numinputs=0) TYPE *NAME (TYPE temp) {
|
%typemap(in,numinputs=0) TYPE *NAME (TYPE temp) {
|
||||||
$1 = &temp;
|
$1 = &temp;
|
||||||
}
|
}
|
||||||
%enddef
|
%enddef
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ More information can be found at <a href="http://www.gnu.org/software/octave/">O
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
This chapter is intended to give an introduction to using the module. You should also read the SWIG documentation that is not specific to Octave.
|
This chapter is intended to give an introduction to using the module. You should also read the SWIG documentation that is not specific to Octave.
|
||||||
Also, there are a dozen or so examples in the Examples/octave directory, and hundreds in the test suite (Examples/test-suite and Examples/test-suite/octave).
|
Also, there are a dozen or so examples in the Examples/octave directory, and hundreds in the test suite (Examples/test-suite and Examples/test-suite/octave).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -314,7 +314,7 @@ swigexample.SUNDAY=0
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Given a wrapping of the <file.h> interface:
|
C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Given a wrapping of the <file.h> interface:
|
||||||
C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Given a wrapping of the <file.h> interface:
|
C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Given a wrapping of the <file.h> interface:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code"><pre>%module swigexample
|
<div class="code"><pre>%module swigexample
|
||||||
|
|
@ -663,10 +663,10 @@ For example, function templates can be instantiated as follows:
|
||||||
|
|
||||||
<div class="code"><pre>%module swigexample
|
<div class="code"><pre>%module swigexample
|
||||||
%inline {
|
%inline {
|
||||||
template<class __scalar>
|
template<class __scalar>
|
||||||
__scalar mul(__scalar a,__scalar b) {
|
__scalar mul(__scalar a,__scalar b) {
|
||||||
return a*b;
|
return a*b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
%include <std_complex.i>
|
%include <std_complex.i>
|
||||||
%template(mul) mul<std::complex<double> >
|
%template(mul) mul<std::complex<double> >
|
||||||
|
|
|
||||||
|
|
@ -940,12 +940,12 @@ example:
|
||||||
%inline %{
|
%inline %{
|
||||||
/* C-style cast */
|
/* C-style cast */
|
||||||
Bar *FooToBar(Foo *f) {
|
Bar *FooToBar(Foo *f) {
|
||||||
return (Bar *) f;
|
return (Bar *) f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* C++-style cast */
|
/* C++-style cast */
|
||||||
Foo *BarToFoo(Bar *b) {
|
Foo *BarToFoo(Bar *b) {
|
||||||
return dynamic_cast<Foo*>(b);
|
return dynamic_cast<Foo*>(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
Foo *IncrFoo(Foo *f, int i) {
|
Foo *IncrFoo(Foo *f, int i) {
|
||||||
|
|
@ -1020,12 +1020,12 @@ can also be forced to be read-only using the <tt>%immutable</tt> directive. For
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
struct Foo {
|
struct Foo {
|
||||||
...
|
...
|
||||||
%immutable;
|
%immutable;
|
||||||
int x; /* Read-only members */
|
int x; /* Read-only members */
|
||||||
char *name;
|
char *name;
|
||||||
%mutable;
|
%mutable;
|
||||||
...
|
...
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1045,7 +1045,7 @@ Array members are normally wrapped as read-only. For example,
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
struct Foo {
|
struct Foo {
|
||||||
int x[50];
|
int x[50];
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1076,11 +1076,11 @@ When structure members are wrapped, they are handled as pointers. For example,
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
struct Foo {
|
struct Foo {
|
||||||
...
|
...
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Bar {
|
struct Bar {
|
||||||
Foo f;
|
Foo f;
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1222,9 +1222,9 @@ void foo(char *c); // Stays 'foo' (not renamed)
|
||||||
|
|
||||||
class Spam {
|
class Spam {
|
||||||
public:
|
public:
|
||||||
void foo(int); // Becomes 'foo_i'
|
void foo(int); // Becomes 'foo_i'
|
||||||
void foo(double); // Becomes 'foo_d'
|
void foo(double); // Becomes 'foo_d'
|
||||||
...
|
...
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1380,7 +1380,7 @@ example:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
void add(int x, int y, int *result) {
|
void add(int x, int y, int *result) {
|
||||||
*result = x + y;
|
*result = x + y;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1392,7 +1392,7 @@ or perhaps
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
int sub(int *x, int *y) {
|
int sub(int *x, int *y) {
|
||||||
return *x+*y;
|
return *x+*y;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1456,7 +1456,7 @@ If a function mutates one of its parameters like this,
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
void negate(int *x) {
|
void negate(int *x) {
|
||||||
*x = -(*x);
|
*x = -(*x);
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1614,7 +1614,7 @@ class DoubleArray {
|
||||||
}
|
}
|
||||||
// Destroy an array
|
// Destroy an array
|
||||||
~DoubleArray() {
|
~DoubleArray() {
|
||||||
delete ptr;
|
delete ptr;
|
||||||
}
|
}
|
||||||
// Return the length of the array
|
// Return the length of the array
|
||||||
int length() {
|
int length() {
|
||||||
|
|
@ -2173,11 +2173,11 @@ reference to be used as a char ** datatype.
|
||||||
int i = 0,len = 0;
|
int i = 0,len = 0;
|
||||||
/* Figure out how many elements we have */
|
/* Figure out how many elements we have */
|
||||||
while ($1[len])
|
while ($1[len])
|
||||||
len++;
|
len++;
|
||||||
svs = (SV **) malloc(len*sizeof(SV *));
|
svs = (SV **) malloc(len*sizeof(SV *));
|
||||||
for (i = 0; i < len ; i++) {
|
for (i = 0; i < len ; i++) {
|
||||||
svs[i] = sv_newmortal();
|
svs[i] = sv_newmortal();
|
||||||
sv_setpv((SV*)svs[i],$1[i]);
|
sv_setpv((SV*)svs[i],$1[i]);
|
||||||
};
|
};
|
||||||
myav = av_make(len,svs);
|
myav = av_make(len,svs);
|
||||||
free(svs);
|
free(svs);
|
||||||
|
|
@ -2188,20 +2188,20 @@ reference to be used as a char ** datatype.
|
||||||
|
|
||||||
// Now a few test functions
|
// Now a few test functions
|
||||||
%inline %{
|
%inline %{
|
||||||
int print_args(char **argv) {
|
int print_args(char **argv) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (argv[i]) {
|
while (argv[i]) {
|
||||||
printf("argv[%d] = %s\n", i,argv[i]);
|
printf("argv[%d] = %s\n", i,argv[i]);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a char ** list
|
// Returns a char ** list
|
||||||
char **get_args() {
|
char **get_args() {
|
||||||
static char *values[] = { "Dave", "Mike", "Susan", "John", "Michelle", 0};
|
static char *values[] = { "Dave", "Mike", "Susan", "John", "Michelle", 0};
|
||||||
return &values[0];
|
return &values[0];
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
@ -2349,10 +2349,10 @@ For example:
|
||||||
|
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
%typemap(memberin) int [ANY] {
|
%typemap(memberin) int [ANY] {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < $1_dim0; i++) {
|
for (i = 0; i < $1_dim0; i++) {
|
||||||
$1[i] = $input[i];
|
$1[i] = $input[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
|
|
@ -2477,7 +2477,9 @@ is usually accessed as follows:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
Foo *f;
|
Foo *f;
|
||||||
if (SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, 0) == -1) return NULL;
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, 0))) {
|
||||||
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
||||||
|
}
|
||||||
|
|
||||||
SV *sv = sv_newmortal();
|
SV *sv = sv_newmortal();
|
||||||
SWIG_MakePtr(sv, f, SWIGTYPE_p_Foo, 0);
|
SWIG_MakePtr(sv, f, SWIGTYPE_p_Foo, 0);
|
||||||
|
|
@ -2492,7 +2494,9 @@ variable <tt>$1_descriptor</tt>. For example:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%typemap(in) Foo * {
|
%typemap(in) Foo * {
|
||||||
if ((SWIG_ConvertPtr($input,(void **) &$1, $1_descriptor,0)) == -1) return NULL;
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 0))) {
|
||||||
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2505,7 +2509,9 @@ For example:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%typemap(in) Foo * {
|
%typemap(in) Foo * {
|
||||||
if ((SWIG_ConvertPtr($input,(void **) &$1, $descriptor(Foo *), 0)) == -1) return NULL;
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $descriptor(Foo *), 0))) {
|
||||||
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2997,9 +3003,9 @@ low-level helper functions. For example, this code now seems to work:
|
||||||
<pre>
|
<pre>
|
||||||
my $a =
|
my $a =
|
||||||
[[1,0,0,0],
|
[[1,0,0,0],
|
||||||
[0,1,0,0],
|
[0,1,0,0],
|
||||||
[0,0,1,0],
|
[0,0,1,0],
|
||||||
[0,0,0,1]];
|
[0,0,0,1]];
|
||||||
set_transform($im, $a);
|
set_transform($im, $a);
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -995,7 +995,7 @@ require("mymodule.php");
|
||||||
|
|
||||||
class MyFoo extends Foo {
|
class MyFoo extends Foo {
|
||||||
function one() {
|
function one() {
|
||||||
print "one from php\n";
|
print "one from php\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
|
||||||
|
|
@ -225,16 +225,16 @@ For example:
|
||||||
%define ARRAYHELPER(type,name)
|
%define ARRAYHELPER(type,name)
|
||||||
%inline %{
|
%inline %{
|
||||||
type *new_ ## name (int nitems) {
|
type *new_ ## name (int nitems) {
|
||||||
return (type *) malloc(sizeof(type)*nitems);
|
return (type *) malloc(sizeof(type)*nitems);
|
||||||
}
|
}
|
||||||
void delete_ ## name(type *t) {
|
void delete_ ## name(type *t) {
|
||||||
free(t);
|
free(t);
|
||||||
}
|
}
|
||||||
type name ## _get(type *t, int index) {
|
type name ## _get(type *t, int index) {
|
||||||
return t[index];
|
return t[index];
|
||||||
}
|
}
|
||||||
void name ## _set(type *t, int index, type val) {
|
void name ## _set(type *t, int index, type val) {
|
||||||
t[index] = val;
|
t[index] = val;
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
%enddef
|
%enddef
|
||||||
|
|
@ -334,7 +334,7 @@ if you write code like this,
|
||||||
%{
|
%{
|
||||||
#ifdef NEED_BLAH
|
#ifdef NEED_BLAH
|
||||||
int blah() {
|
int blah() {
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
%}
|
%}
|
||||||
|
|
@ -358,11 +358,11 @@ file. For example:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%extend Foo {
|
%extend Foo {
|
||||||
void bar() {
|
void bar() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("I'm in bar\n");
|
printf("I'm in bar\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -375,11 +375,11 @@ to actually go into the wrapper file, prefix the preprocessor directives with <t
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%extend Foo {
|
%extend Foo {
|
||||||
void bar() {
|
void bar() {
|
||||||
%#ifdef DEBUG
|
%#ifdef DEBUG
|
||||||
printf("I'm in bar\n");
|
printf("I'm in bar\n");
|
||||||
%#endif
|
%#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1262,12 +1262,12 @@ consider writing some helper functions instead. For example:
|
||||||
%inline %{
|
%inline %{
|
||||||
/* C-style cast */
|
/* C-style cast */
|
||||||
Bar *FooToBar(Foo *f) {
|
Bar *FooToBar(Foo *f) {
|
||||||
return (Bar *) f;
|
return (Bar *) f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* C++-style cast */
|
/* C++-style cast */
|
||||||
Foo *BarToFoo(Bar *b) {
|
Foo *BarToFoo(Bar *b) {
|
||||||
return dynamic_cast<Foo*>(b);
|
return dynamic_cast<Foo*>(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
Foo *IncrFoo(Foo *f, int i) {
|
Foo *IncrFoo(Foo *f, int i) {
|
||||||
|
|
@ -1355,12 +1355,12 @@ can also be forced to be read-only using the <tt>%immutable</tt> directive. For
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
struct Foo {
|
struct Foo {
|
||||||
...
|
...
|
||||||
%immutable;
|
%immutable;
|
||||||
int x; /* Read-only members */
|
int x; /* Read-only members */
|
||||||
char *name;
|
char *name;
|
||||||
%mutable;
|
%mutable;
|
||||||
...
|
...
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1427,11 +1427,11 @@ pointer. For example, suppose you have two structures like this:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
struct Foo {
|
struct Foo {
|
||||||
int a;
|
int a;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Bar {
|
struct Bar {
|
||||||
Foo f;
|
Foo f;
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1525,9 +1525,8 @@ suppose you have a class like this:
|
||||||
<pre>
|
<pre>
|
||||||
class Spam {
|
class Spam {
|
||||||
public:
|
public:
|
||||||
static void foo();
|
static void foo();
|
||||||
static int bar;
|
static int bar;
|
||||||
|
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1904,10 +1903,10 @@ submodules or packages. For example, if you have a file like this,
|
||||||
%module example
|
%module example
|
||||||
|
|
||||||
namespace foo {
|
namespace foo {
|
||||||
int fact(int n);
|
int fact(int n);
|
||||||
struct Vector {
|
struct Vector {
|
||||||
double x,y,z;
|
double x,y,z;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1976,13 +1975,13 @@ For example:
|
||||||
|
|
||||||
template<class T1, class T2>
|
template<class T1, class T2>
|
||||||
struct pair {
|
struct pair {
|
||||||
typedef T1 first_type;
|
typedef T1 first_type;
|
||||||
typedef T2 second_type;
|
typedef T2 second_type;
|
||||||
T1 first;
|
T1 first;
|
||||||
T2 second;
|
T2 second;
|
||||||
pair();
|
pair();
|
||||||
pair(const T1&, const T2&);
|
pair(const T1&, const T2&);
|
||||||
~pair();
|
~pair();
|
||||||
};
|
};
|
||||||
|
|
||||||
%template(pairii) pair<int,int>;
|
%template(pairii) pair<int,int>;
|
||||||
|
|
@ -2037,9 +2036,9 @@ that implements <tt>operator->()</tt> like this:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
template<class T> class SmartPtr {
|
template<class T> class SmartPtr {
|
||||||
...
|
...
|
||||||
T *operator->();
|
T *operator->();
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2052,8 +2051,8 @@ Then, if you have a class like this,
|
||||||
<pre>
|
<pre>
|
||||||
class Foo {
|
class Foo {
|
||||||
public:
|
public:
|
||||||
int x;
|
int x;
|
||||||
int bar();
|
int bar();
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2154,9 +2153,9 @@ have a class like this
|
||||||
<pre>
|
<pre>
|
||||||
class Foo {
|
class Foo {
|
||||||
public:
|
public:
|
||||||
int x;
|
int x;
|
||||||
int spam(int);
|
int spam(int);
|
||||||
...
|
...
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -2749,10 +2748,10 @@ change the ownership of an object. For instance, consider code like this:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
class Node {
|
class Node {
|
||||||
Object *value;
|
Object *value;
|
||||||
public:
|
public:
|
||||||
void set_value(Object *v) { value = v; }
|
void set_value(Object *v) { value = v; }
|
||||||
...
|
...
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3319,16 +3318,16 @@ functions. Just use the <tt>%inline</tt> directive. For example:
|
||||||
%inline %{
|
%inline %{
|
||||||
/* Note: double[4][4] is equivalent to a pointer to an array double (*)[4] */
|
/* Note: double[4][4] is equivalent to a pointer to an array double (*)[4] */
|
||||||
double (*new_mat44())[4] {
|
double (*new_mat44())[4] {
|
||||||
return (double (*)[4]) malloc(16*sizeof(double));
|
return (double (*)[4]) malloc(16*sizeof(double));
|
||||||
}
|
}
|
||||||
void free_mat44(double (*x)[4]) {
|
void free_mat44(double (*x)[4]) {
|
||||||
free(x);
|
free(x);
|
||||||
}
|
}
|
||||||
void mat44_set(double x[4][4], int i, int j, double v) {
|
void mat44_set(double x[4][4], int i, int j, double v) {
|
||||||
x[i][j] = v;
|
x[i][j] = v;
|
||||||
}
|
}
|
||||||
double mat44_get(double x[4][4], int i, int j) {
|
double mat44_get(double x[4][4], int i, int j) {
|
||||||
return x[i][j];
|
return x[i][j];
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
@ -3374,12 +3373,12 @@ void set_transform(Image *im, double x[4][4]);
|
||||||
/* Rewrite the high level interface to set_transform */
|
/* Rewrite the high level interface to set_transform */
|
||||||
%pythoncode %{
|
%pythoncode %{
|
||||||
def set_transform(im,x):
|
def set_transform(im,x):
|
||||||
a = new_mat44()
|
a = new_mat44()
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
for j in range(4):
|
for j in range(4):
|
||||||
mat44_set(a,i,j,x[i][j])
|
mat44_set(a,i,j,x[i][j])
|
||||||
_example.set_transform(im,a)
|
_example.set_transform(im,a)
|
||||||
free_mat44(a)
|
free_mat44(a)
|
||||||
%}
|
%}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3529,11 +3528,11 @@ proxy, just before the return statement.
|
||||||
// Add python code to bar()
|
// Add python code to bar()
|
||||||
|
|
||||||
%feature("pythonprepend") Foo::bar(int) %{
|
%feature("pythonprepend") Foo::bar(int) %{
|
||||||
#do something before C++ call
|
#do something before C++ call
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%feature("pythonappend") Foo::bar(int) %{
|
%feature("pythonappend") Foo::bar(int) %{
|
||||||
#do something after C++ call
|
#do something after C++ call
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -3558,11 +3557,11 @@ SWIG version 1.3.28 you can use the directive forms
|
||||||
// Add python code to bar()
|
// Add python code to bar()
|
||||||
|
|
||||||
%pythonprepend Foo::bar(int) %{
|
%pythonprepend Foo::bar(int) %{
|
||||||
#do something before C++ call
|
#do something before C++ call
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%pythonappend Foo::bar(int) %{
|
%pythonappend Foo::bar(int) %{
|
||||||
#do something after C++ call
|
#do something after C++ call
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -3587,11 +3586,11 @@ as it will then get attached to all the overloaded C++ methods. For example:
|
||||||
// Add python code to bar()
|
// Add python code to bar()
|
||||||
|
|
||||||
%pythonprepend Foo::bar %{
|
%pythonprepend Foo::bar %{
|
||||||
#do something before C++ call
|
#do something before C++ call
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%pythonappend Foo::bar %{
|
%pythonappend Foo::bar %{
|
||||||
#do something after C++ call
|
#do something after C++ call
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -3625,22 +3624,22 @@ Here is a simple example:
|
||||||
%}
|
%}
|
||||||
|
|
||||||
struct Vector {
|
struct Vector {
|
||||||
double x,y,z;
|
double x,y,z;
|
||||||
};
|
};
|
||||||
|
|
||||||
%extend Vector {
|
%extend Vector {
|
||||||
char *__str__() {
|
char *__str__() {
|
||||||
static char tmp[1024];
|
static char tmp[1024];
|
||||||
sprintf(tmp,"Vector(%g,%g,%g)", $self->x,$self->y,$self->z);
|
sprintf(tmp,"Vector(%g,%g,%g)", $self->x,$self->y,$self->z);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
Vector(double x, double y, double z) {
|
Vector(double x, double y, double z) {
|
||||||
Vector *v = (Vector *) malloc(sizeof(Vector));
|
Vector *v = (Vector *) malloc(sizeof(Vector));
|
||||||
v->x = x;
|
v->x = x;
|
||||||
v->y = y;
|
v->y = y;
|
||||||
v->z = z;
|
v->z = z;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3666,13 +3665,13 @@ For example, if you wanted to overload a Python operator, you might do this:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%extend Vector {
|
%extend Vector {
|
||||||
Vector __add__(Vector *other) {
|
Vector __add__(Vector *other) {
|
||||||
Vector v;
|
Vector v;
|
||||||
v.x = $self->x + other->x;
|
v.x = $self->x + other->x;
|
||||||
v.y = $self->y + other->y;
|
v.y = $self->y + other->y;
|
||||||
v.z = $self->z + other->z;
|
v.z = $self->z + other->z;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3716,8 +3715,8 @@ or a NULL pointer perhaps). Here is a simple example of how you might handle th
|
||||||
%exception malloc {
|
%exception malloc {
|
||||||
$action
|
$action
|
||||||
if (!result) {
|
if (!result) {
|
||||||
PyErr_SetString(PyExc_MemoryError,"Not enough memory");
|
PyErr_SetString(PyExc_MemoryError,"Not enough memory");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void *malloc(size_t nbytes);
|
void *malloc(size_t nbytes);
|
||||||
|
|
@ -3746,11 +3745,11 @@ that. For example:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%exception {
|
%exception {
|
||||||
$action
|
$action
|
||||||
if (err_occurred()) {
|
if (err_occurred()) {
|
||||||
PyErr_SetString(PyExc_RuntimeError, err_message());
|
PyErr_SetString(PyExc_RuntimeError, err_message());
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3766,25 +3765,26 @@ C++ exceptions are also easy to handle. For example, you can write code like th
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%exception getitem {
|
%exception getitem {
|
||||||
try {
|
try {
|
||||||
$action
|
$action
|
||||||
} catch (std::out_of_range &e) {
|
} catch (std::out_of_range &e) {
|
||||||
PyErr_SetString(PyExc_IndexError, const_cast<char*>(e.what()));
|
PyErr_SetString(PyExc_IndexError, const_cast<char*>(e.what()));
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Base {
|
class Base {
|
||||||
public:
|
public:
|
||||||
Foo *getitem(int index); // Exception handled added
|
Foo *getitem(int index); // Exception handled added
|
||||||
...
|
...
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
When raising a Python exception from C, use the <tt>PyErr_SetString()</tt>
|
When raising a Python exception from C, use the <tt>PyErr_SetString()</tt>
|
||||||
function as shown above. The following exception types can be used as the first argument.
|
function as shown above followed by <tt>SWIG_fail</tt>.
|
||||||
|
The following exception types can be used as the first argument.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
|
|
@ -3818,6 +3818,13 @@ PyExc_ZeroDivisionError
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<tt>SWIG_fail</tt> is a C macro which when called within the context of SWIG wrapper function,
|
||||||
|
will jump to the error handler code. This will call any cleanup code (freeing any temp variables)
|
||||||
|
and then return from the wrapper function so that the Python interpreter can raise the Python exception.
|
||||||
|
This macro should always be called after setting a Python error in code snippets, such as typemaps and <tt>%exception</tt>, that are ultimately generated into the wrapper function.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The language-independent <tt>exception.i</tt> library file can also be used
|
The language-independent <tt>exception.i</tt> library file can also be used
|
||||||
to raise exceptions. See the <a href="Library.html#Library">SWIG Library</a> chapter.
|
to raise exceptions. See the <a href="Library.html#Library">SWIG Library</a> chapter.
|
||||||
|
|
@ -3844,7 +3851,7 @@ example:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
void add(int x, int y, int *result) {
|
void add(int x, int y, int *result) {
|
||||||
*result = x + y;
|
*result = x + y;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3856,7 +3863,7 @@ or perhaps
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
int sub(int *x, int *y) {
|
int sub(int *x, int *y) {
|
||||||
return *x-*y;
|
return *x-*y;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3921,7 +3928,7 @@ If a function mutates one of its parameters like this,
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
void negate(int *x) {
|
void negate(int *x) {
|
||||||
*x = -(*x);
|
*x = -(*x);
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -4417,7 +4424,7 @@ You can refine this by supplying an optional parameter name. For example:
|
||||||
$1 = (int) PyLong_AsLong($input);
|
$1 = (int) PyLong_AsLong($input);
|
||||||
if ($1 < 0) {
|
if ($1 < 0) {
|
||||||
PyErr_SetString(PyExc_ValueError,"Expected a nonnegative value.");
|
PyErr_SetString(PyExc_ValueError,"Expected a nonnegative value.");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
%inline %{
|
%inline %{
|
||||||
|
|
@ -4457,8 +4464,8 @@ Typemaps can also be defined for groups of consecutive arguments. For example:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%typemap(in) (char *str, int len) {
|
%typemap(in) (char *str, int len) {
|
||||||
$1 = PyString_AsString($input);
|
$1 = PyString_AsString($input);
|
||||||
$2 = PyString_Size($input);
|
$2 = PyString_Size($input);
|
||||||
};
|
};
|
||||||
|
|
||||||
int count(char c, char *str, int len);
|
int count(char c, char *str, int len);
|
||||||
|
|
@ -4750,18 +4757,18 @@ object to be used as a <tt>char **</tt> object.
|
||||||
$1 = (char **) malloc((size+1)*sizeof(char *));
|
$1 = (char **) malloc((size+1)*sizeof(char *));
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
PyObject *o = PyList_GetItem($input,i);
|
PyObject *o = PyList_GetItem($input,i);
|
||||||
if (PyString_Check(o))
|
if (PyString_Check(o)) {
|
||||||
$1[i] = PyString_AsString(PyList_GetItem($input,i));
|
$1[i] = PyString_AsString(PyList_GetItem($input,i));
|
||||||
else {
|
} else {
|
||||||
PyErr_SetString(PyExc_TypeError,"list must contain strings");
|
|
||||||
free($1);
|
free($1);
|
||||||
return NULL;
|
PyErr_SetString(PyExc_TypeError,"list must contain strings");
|
||||||
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$1[i] = 0;
|
$1[i] = 0;
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(PyExc_TypeError,"not a list");
|
PyErr_SetString(PyExc_TypeError,"not a list");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4773,12 +4780,12 @@ object to be used as a <tt>char **</tt> object.
|
||||||
// Now a test function
|
// Now a test function
|
||||||
%inline %{
|
%inline %{
|
||||||
int print_args(char **argv) {
|
int print_args(char **argv) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (argv[i]) {
|
while (argv[i]) {
|
||||||
printf("argv[%d] = %s\n", i,argv[i]);
|
printf("argv[%d] = %s\n", i,argv[i]);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
@ -4849,18 +4856,18 @@ previous example:
|
||||||
$2 = (char **) malloc(($1+1)*sizeof(char *));
|
$2 = (char **) malloc(($1+1)*sizeof(char *));
|
||||||
for (i = 0; i < $1; i++) {
|
for (i = 0; i < $1; i++) {
|
||||||
PyObject *o = PyList_GetItem($input,i);
|
PyObject *o = PyList_GetItem($input,i);
|
||||||
if (PyString_Check(o))
|
if (PyString_Check(o)) {
|
||||||
$2[i] = PyString_AsString(PyList_GetItem($input,i));
|
$2[i] = PyString_AsString(PyList_GetItem($input,i));
|
||||||
else {
|
} else {
|
||||||
PyErr_SetString(PyExc_TypeError,"list must contain strings");
|
|
||||||
free($2);
|
free($2);
|
||||||
return NULL;
|
PyErr_SetString(PyExc_TypeError,"list must contain strings");
|
||||||
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$2[i] = 0;
|
$2[i] = 0;
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(PyExc_TypeError,"not a list");
|
PyErr_SetString(PyExc_TypeError,"not a list");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4995,7 +5002,7 @@ no meaningful input value), an additional typemap can be written. For example:
|
||||||
|
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
%typemap(in,numinputs=0) double *OutValue(double temp) {
|
%typemap(in,numinputs=0) double *OutValue(double temp) {
|
||||||
$1 = &temp;
|
$1 = &temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
@ -5038,12 +5045,12 @@ This too, can be handled used typemaps as follows :
|
||||||
if (PyTuple_Check($input)) {
|
if (PyTuple_Check($input)) {
|
||||||
if (!PyArg_ParseTuple($input,"dddd",temp,temp+1,temp+2,temp+3)) {
|
if (!PyArg_ParseTuple($input,"dddd",temp,temp+1,temp+2,temp+3)) {
|
||||||
PyErr_SetString(PyExc_TypeError,"tuple must have 4 elements");
|
PyErr_SetString(PyExc_TypeError,"tuple must have 4 elements");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
$1 = &temp[0];
|
$1 = &temp[0];
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(PyExc_TypeError,"expected a tuple.");
|
PyErr_SetString(PyExc_TypeError,"expected a tuple.");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5077,22 +5084,22 @@ arrays of different sizes. To do this, you might write a typemap as follows:
|
||||||
%typemap(in) double[ANY](double temp[$1_dim0]) {
|
%typemap(in) double[ANY](double temp[$1_dim0]) {
|
||||||
int i;
|
int i;
|
||||||
if (!PySequence_Check($input)) {
|
if (!PySequence_Check($input)) {
|
||||||
PyErr_SetString(PyExc_TypeError,"Expecting a sequence");
|
PyErr_SetString(PyExc_TypeError,"Expecting a sequence");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
if (PyObject_Length($input) != $1_dim0) {
|
if (PyObject_Length($input) != $1_dim0) {
|
||||||
PyErr_SetString(PyExc_ValueError,"Expecting a sequence with $1_dim0 elements");
|
PyErr_SetString(PyExc_ValueError,"Expecting a sequence with $1_dim0 elements");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
for (i =0; i < $1_dim0; i++) {
|
for (i =0; i < $1_dim0; i++) {
|
||||||
PyObject *o = PySequence_GetItem($input,i);
|
PyObject *o = PySequence_GetItem($input,i);
|
||||||
if (!PyFloat_Check(o)) {
|
if (!PyFloat_Check(o)) {
|
||||||
Py_XDECREF(o);
|
Py_XDECREF(o);
|
||||||
PyErr_SetString(PyExc_ValueError,"Expecting a sequence of floats");
|
PyErr_SetString(PyExc_ValueError,"Expecting a sequence of floats");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
temp[i] = PyFloat_AsDouble(o);
|
temp[i] = PyFloat_AsDouble(o);
|
||||||
Py_DECREF(o);
|
Py_DECREF(o);
|
||||||
}
|
}
|
||||||
$1 = &temp[0];
|
$1 = &temp[0];
|
||||||
}
|
}
|
||||||
|
|
@ -5123,32 +5130,32 @@ to use a helper function instead. This will greatly reduce the amount of wrappe
|
||||||
static int convert_darray(PyObject *input, double *ptr, int size) {
|
static int convert_darray(PyObject *input, double *ptr, int size) {
|
||||||
int i;
|
int i;
|
||||||
if (!PySequence_Check(input)) {
|
if (!PySequence_Check(input)) {
|
||||||
PyErr_SetString(PyExc_TypeError,"Expecting a sequence");
|
PyErr_SetString(PyExc_TypeError,"Expecting a sequence");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (PyObject_Length(input) != size) {
|
if (PyObject_Length(input) != size) {
|
||||||
PyErr_SetString(PyExc_ValueError,"Sequence size mismatch");
|
PyErr_SetString(PyExc_ValueError,"Sequence size mismatch");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
for (i =0; i < size; i++) {
|
for (i =0; i < size; i++) {
|
||||||
PyObject *o = PySequence_GetItem(input,i);
|
PyObject *o = PySequence_GetItem(input,i);
|
||||||
if (!PyFloat_Check(o)) {
|
if (!PyFloat_Check(o)) {
|
||||||
Py_XDECREF(o);
|
Py_XDECREF(o);
|
||||||
PyErr_SetString(PyExc_ValueError,"Expecting a sequence of floats");
|
PyErr_SetString(PyExc_ValueError,"Expecting a sequence of floats");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ptr[i] = PyFloat_AsDouble(o);
|
ptr[i] = PyFloat_AsDouble(o);
|
||||||
Py_DECREF(o);
|
Py_DECREF(o);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%typemap(in) double [ANY](double temp[$1_dim0]) {
|
%typemap(in) double [ANY](double temp[$1_dim0]) {
|
||||||
if (!convert_darray($input,temp,$1_dim0)) {
|
if (!convert_darray($input,temp,$1_dim0)) {
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
$1 = &temp[0];
|
$1 = &temp[0];
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -5201,8 +5208,9 @@ is usually accessed as follows:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
Foo *f;
|
Foo *f;
|
||||||
if (SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, SWIG_POINTER_EXCEPTION) == -1)
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, 0))) {
|
||||||
return NULL;
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
||||||
|
}
|
||||||
|
|
||||||
PyObject *obj;
|
PyObject *obj;
|
||||||
obj = SWIG_NewPointerObj(f, SWIGTYPE_p_Foo, 0);
|
obj = SWIG_NewPointerObj(f, SWIGTYPE_p_Foo, 0);
|
||||||
|
|
@ -5217,8 +5225,9 @@ variable <tt>$1_descriptor</tt>. For example:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%typemap(in) Foo * {
|
%typemap(in) Foo * {
|
||||||
if ((SWIG_ConvertPtr($input,(void **) &$1, $1_descriptor,SWIG_POINTER_EXCEPTION)) == -1)
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 0))) {
|
||||||
return NULL;
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -5231,9 +5240,9 @@ For example:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%typemap(in) Foo * {
|
%typemap(in) Foo * {
|
||||||
if ((SWIG_ConvertPtr($input,(void **) &$1, $descriptor(Foo *),
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $descriptor(Foo *), 0))) {
|
||||||
SWIG_POINTER_EXCEPTION)) == -1)
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
||||||
return NULL;
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -5442,7 +5451,7 @@ resulting in
|
||||||
<div class="targetlang">
|
<div class="targetlang">
|
||||||
<pre>
|
<pre>
|
||||||
def function_name(*args, **kwargs):
|
def function_name(*args, **kwargs):
|
||||||
"""
|
"""
|
||||||
function_name(x, y, foo=None, bar=None) -> bool
|
function_name(x, y, foo=None, bar=None) -> bool
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
|
|
|
||||||
|
|
@ -1357,16 +1357,16 @@ SWIG generates the following code:
|
||||||
<pre>
|
<pre>
|
||||||
/* C mode */
|
/* C mode */
|
||||||
void foo_set(char *value) {
|
void foo_set(char *value) {
|
||||||
if (foo) free(foo);
|
if (foo) free(foo);
|
||||||
foo = (char *) malloc(strlen(value)+1);
|
foo = (char *) malloc(strlen(value)+1);
|
||||||
strcpy(foo,value);
|
strcpy(foo,value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* C++ mode. When -c++ option is used */
|
/* C++ mode. When -c++ option is used */
|
||||||
void foo_set(char *value) {
|
void foo_set(char *value) {
|
||||||
if (foo) delete [] foo;
|
if (foo) delete [] foo;
|
||||||
foo = new char[strlen(value)+1];
|
foo = new char[strlen(value)+1];
|
||||||
strcpy(foo,value);
|
strcpy(foo,value);
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1381,8 +1381,8 @@ exactly like you want. For example:
|
||||||
<pre>
|
<pre>
|
||||||
%inline %{
|
%inline %{
|
||||||
void set_foo(char *value) {
|
void set_foo(char *value) {
|
||||||
strncpy(foo,value, 50);
|
strncpy(foo,value, 50);
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1538,10 +1538,10 @@ a few simple assist functions like this:
|
||||||
<pre>
|
<pre>
|
||||||
%inline %{
|
%inline %{
|
||||||
void a_set(int i, int j, int val) {
|
void a_set(int i, int j, int val) {
|
||||||
a[i][j] = val;
|
a[i][j] = val;
|
||||||
}
|
}
|
||||||
int a_get(int i, int j) {
|
int a_get(int i, int j) {
|
||||||
return a[i][j];
|
return a[i][j];
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
@ -1558,11 +1558,11 @@ some helper functions in your interface. For example:
|
||||||
%inline %{
|
%inline %{
|
||||||
/* Create any sort of [size] array */
|
/* Create any sort of [size] array */
|
||||||
int *int_array(int size) {
|
int *int_array(int size) {
|
||||||
return (int *) malloc(size*sizeof(int));
|
return (int *) malloc(size*sizeof(int));
|
||||||
}
|
}
|
||||||
/* Create a two-dimension array [size][10] */
|
/* Create a two-dimension array [size][10] */
|
||||||
int (*int_array_10(int size))[10] {
|
int (*int_array_10(int size))[10] {
|
||||||
return (int (*)[10]) malloc(size*10*sizeof(int));
|
return (int (*)[10]) malloc(size*10*sizeof(int));
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
@ -1587,10 +1587,10 @@ code:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
char *pathname_get() {
|
char *pathname_get() {
|
||||||
return pathname;
|
return pathname;
|
||||||
}
|
}
|
||||||
void pathname_set(char *value) {
|
void pathname_set(char *value) {
|
||||||
strncpy(pathname,value,256);
|
strncpy(pathname,value,256);
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2521,12 +2521,12 @@ Occasionally, a structure will contain data members that are themselves structur
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
typedef struct Foo {
|
typedef struct Foo {
|
||||||
int x;
|
int x;
|
||||||
} Foo;
|
} Foo;
|
||||||
|
|
||||||
typedef struct Bar {
|
typedef struct Bar {
|
||||||
int y;
|
int y;
|
||||||
Foo f; /* struct member */
|
Foo f; /* struct member */
|
||||||
} Bar;
|
} Bar;
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2540,10 +2540,10 @@ The accessors to the member variable as a pointer are effectively wrapped as fol
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
Foo *Bar_f_get(Bar *b) {
|
Foo *Bar_f_get(Bar *b) {
|
||||||
return &b->f;
|
return &b->f;
|
||||||
}
|
}
|
||||||
void Bar_f_set(Bar *b, Foo *value) {
|
void Bar_f_set(Bar *b, Foo *value) {
|
||||||
b->f = *value;
|
b->f = *value;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2588,7 +2588,7 @@ is a structure or class. For instance, if you had a structure like this,
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
struct Foo {
|
struct Foo {
|
||||||
WORD w;
|
WORD w;
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2843,10 +2843,10 @@ double Vector_magnitude(Vector *v) {
|
||||||
typedef struct Vector {
|
typedef struct Vector {
|
||||||
double x,y,z;
|
double x,y,z;
|
||||||
%extend {
|
%extend {
|
||||||
Vector(int,int,int); // This calls new_Vector()
|
Vector(int,int,int); // This calls new_Vector()
|
||||||
~Vector(); // This calls delete_Vector()
|
~Vector(); // This calls delete_Vector()
|
||||||
double magnitude(); // This will call Vector_magnitude()
|
double magnitude(); // This will call Vector_magnitude()
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
} Vector;
|
} Vector;
|
||||||
</pre>
|
</pre>
|
||||||
|
|
@ -3083,7 +3083,7 @@ in terms of high-level accessor functions such as this,
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
double Vector_x_get(Vector *v) {
|
double Vector_x_get(Vector *v) {
|
||||||
return v->x;
|
return v->x;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3100,15 +3100,15 @@ the following function is generated instead:
|
||||||
static int
|
static int
|
||||||
_wrap_Vector_x_get(ClientData clientData, Tcl_Interp *interp,
|
_wrap_Vector_x_get(ClientData clientData, Tcl_Interp *interp,
|
||||||
int objc, Tcl_Obj *CONST objv[]) {
|
int objc, Tcl_Obj *CONST objv[]) {
|
||||||
struct Vector *arg1 ;
|
struct Vector *arg1 ;
|
||||||
double result ;
|
double result ;
|
||||||
|
|
||||||
if (SWIG_GetArgs(interp, objc, objv,"p:Vector_x_get self ",&arg0,
|
if (SWIG_GetArgs(interp, objc, objv,"p:Vector_x_get self ",&arg0,
|
||||||
SWIGTYPE_p_Vector) == TCL_ERROR)
|
SWIGTYPE_p_Vector) == TCL_ERROR)
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
result = (double ) (arg1->x);
|
result = (double ) (arg1->x);
|
||||||
Tcl_SetObjResult(interp,Tcl_NewDoubleObj((double) result));
|
Tcl_SetObjResult(interp,Tcl_NewDoubleObj((double) result));
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3183,23 +3183,23 @@ the wrapper file is as shown:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%begin %{
|
%begin %{
|
||||||
... code in begin section ...
|
... code in begin section ...
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%runtime %{
|
%runtime %{
|
||||||
... code in runtime section ...
|
... code in runtime section ...
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%header %{
|
%header %{
|
||||||
... code in header section ...
|
... code in header section ...
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%wrapper %{
|
%wrapper %{
|
||||||
... code in wrapper section ...
|
... code in wrapper section ...
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%init %{
|
%init %{
|
||||||
... code in init section ...
|
... code in init section ...
|
||||||
%}
|
%}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -443,14 +443,15 @@ The example below shows this for a C function returning 2 values and a result:
|
||||||
int divide(int n, int d, int *OUTPUT, int *OUTPUT);
|
int divide(int n, int d, int *OUTPUT, int *OUTPUT);
|
||||||
|
|
||||||
%{
|
%{
|
||||||
int divide(int n, int d, int q*, int *r) {
|
int divide(int n, int d, int q*, int *r) {
|
||||||
if (d != 0) {
|
if (d != 0) {
|
||||||
*q = n / d;
|
*q = n / d;
|
||||||
*r = n % d;
|
*r = n % d;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else {
|
||||||
else return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
%}
|
%}
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -837,8 +837,8 @@ access constants in procedure bodies. For example:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
proc blah {} {
|
proc blah {} {
|
||||||
global FOO
|
global FOO
|
||||||
bar $FOO
|
bar $FOO
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -865,7 +865,7 @@ its actual value or a symbolic identifier name. For example:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
proc blah {} {
|
proc blah {} {
|
||||||
bar FOO
|
bar FOO
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -949,12 +949,12 @@ example:
|
||||||
%inline %{
|
%inline %{
|
||||||
/* C-style cast */
|
/* C-style cast */
|
||||||
Bar *FooToBar(Foo *f) {
|
Bar *FooToBar(Foo *f) {
|
||||||
return (Bar *) f;
|
return (Bar *) f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* C++-style cast */
|
/* C++-style cast */
|
||||||
Foo *BarToFoo(Bar *b) {
|
Foo *BarToFoo(Bar *b) {
|
||||||
return dynamic_cast<Foo*>(b);
|
return dynamic_cast<Foo*>(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
Foo *IncrFoo(Foo *f, int i) {
|
Foo *IncrFoo(Foo *f, int i) {
|
||||||
|
|
@ -1028,12 +1028,12 @@ can also be forced to be read-only using the <tt>%immutable</tt> directive. For
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
struct Foo {
|
struct Foo {
|
||||||
...
|
...
|
||||||
%immutable;
|
%immutable;
|
||||||
int x; /* Read-only members */
|
int x; /* Read-only members */
|
||||||
char *name;
|
char *name;
|
||||||
%mutable;
|
%mutable;
|
||||||
...
|
...
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1100,11 +1100,11 @@ pointer. For example, suppose you have two structures like this:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
struct Foo {
|
struct Foo {
|
||||||
int a;
|
int a;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Bar {
|
struct Bar {
|
||||||
Foo f;
|
Foo f;
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1302,9 +1302,8 @@ To illustrate, suppose you have a class like this:
|
||||||
<pre>
|
<pre>
|
||||||
class Spam {
|
class Spam {
|
||||||
public:
|
public:
|
||||||
static void foo();
|
static void foo();
|
||||||
static int bar;
|
static int bar;
|
||||||
|
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1662,10 +1661,10 @@ submodules or packages. For example, if you have a file like this,
|
||||||
%module example
|
%module example
|
||||||
|
|
||||||
namespace foo {
|
namespace foo {
|
||||||
int fact(int n);
|
int fact(int n);
|
||||||
struct Vector {
|
struct Vector {
|
||||||
double x,y,z;
|
double x,y,z;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1731,12 +1730,12 @@ For example:
|
||||||
|
|
||||||
template<class T1, class T2>
|
template<class T1, class T2>
|
||||||
struct pair {
|
struct pair {
|
||||||
typedef T1 first_type;
|
typedef T1 first_type;
|
||||||
typedef T2 second_type;
|
typedef T2 second_type;
|
||||||
T1 first;
|
T1 first;
|
||||||
T2 second;
|
T2 second;
|
||||||
pair();
|
pair();
|
||||||
pair(const T1&, const T2&);
|
pair(const T1&, const T2&);
|
||||||
~pair();
|
~pair();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1776,9 +1775,9 @@ that implements <tt>operator->()</tt> like this:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
template<class T> class SmartPtr {
|
template<class T> class SmartPtr {
|
||||||
...
|
...
|
||||||
T *operator->();
|
T *operator->();
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1791,8 +1790,8 @@ Then, if you have a class like this,
|
||||||
<pre>
|
<pre>
|
||||||
class Foo {
|
class Foo {
|
||||||
public:
|
public:
|
||||||
int x;
|
int x;
|
||||||
int bar();
|
int bar();
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1874,9 +1873,9 @@ have a class like this
|
||||||
<pre>
|
<pre>
|
||||||
class Foo {
|
class Foo {
|
||||||
public:
|
public:
|
||||||
int x;
|
int x;
|
||||||
int spam(int);
|
int spam(int);
|
||||||
...
|
...
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -2065,10 +2064,10 @@ change the ownership of an object. For instance, consider code like this:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
class Node {
|
class Node {
|
||||||
Object *value;
|
Object *value;
|
||||||
public:
|
public:
|
||||||
void set_value(Object *v) { value = v; }
|
void set_value(Object *v) { value = v; }
|
||||||
...
|
...
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2125,7 +2124,7 @@ example:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
void add(int x, int y, int *result) {
|
void add(int x, int y, int *result) {
|
||||||
*result = x + y;
|
*result = x + y;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2137,7 +2136,7 @@ or perhaps
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
int sub(int *x, int *y) {
|
int sub(int *x, int *y) {
|
||||||
return *x+*y;
|
return *x+*y;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2198,7 +2197,7 @@ If a function mutates one of its parameters like this,
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
void negate(int *x) {
|
void negate(int *x) {
|
||||||
*x = -(*x);
|
*x = -(*x);
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2328,7 +2327,7 @@ class DoubleArray {
|
||||||
}
|
}
|
||||||
// Destroy an array
|
// Destroy an array
|
||||||
~DoubleArray() {
|
~DoubleArray() {
|
||||||
delete ptr;
|
delete ptr;
|
||||||
}
|
}
|
||||||
// Return the length of the array
|
// Return the length of the array
|
||||||
int length() {
|
int length() {
|
||||||
|
|
@ -2797,36 +2796,36 @@ used as a <tt>char **</tt> object.
|
||||||
|
|
||||||
// This tells SWIG to treat char ** as a special case
|
// This tells SWIG to treat char ** as a special case
|
||||||
%typemap(in) char ** {
|
%typemap(in) char ** {
|
||||||
Tcl_Obj **listobjv;
|
Tcl_Obj **listobjv;
|
||||||
int nitems;
|
int nitems;
|
||||||
int i;
|
int i;
|
||||||
if (Tcl_ListObjGetElements(interp, $input, &nitems, &listobjv) == TCL_ERROR) {
|
if (Tcl_ListObjGetElements(interp, $input, &nitems, &listobjv) == TCL_ERROR) {
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
$1 = (char **) malloc((nitems+1)*sizeof(char *));
|
$1 = (char **) malloc((nitems+1)*sizeof(char *));
|
||||||
for (i = 0; i < nitems; i++) {
|
for (i = 0; i < nitems; i++) {
|
||||||
$1[i] = Tcl_GetStringFromObj(listobjv[i],0);
|
$1[i] = Tcl_GetStringFromObj(listobjv[i],0);
|
||||||
}
|
}
|
||||||
$1[i] = 0;
|
$1[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This gives SWIG some cleanup code that will get called after the function call
|
// This gives SWIG some cleanup code that will get called after the function call
|
||||||
%typemap(freearg) char ** {
|
%typemap(freearg) char ** {
|
||||||
if ($1) {
|
if ($1) {
|
||||||
free($1);
|
free($1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now a test functions
|
// Now a test functions
|
||||||
%inline %{
|
%inline %{
|
||||||
int print_args(char **argv) {
|
int print_args(char **argv) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (argv[i]) {
|
while (argv[i]) {
|
||||||
printf("argv[%d] = %s\n", i,argv[i]);
|
printf("argv[%d] = %s\n", i,argv[i]);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
%include "tclsh.i"
|
%include "tclsh.i"
|
||||||
|
|
||||||
|
|
@ -2855,21 +2854,21 @@ function argument. For example :
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
// A typemap defining how to return an argument by appending it to the result
|
// A typemap defining how to return an argument by appending it to the result
|
||||||
%typemap(argout) double *outvalue {
|
%typemap(argout) double *outvalue {
|
||||||
Tcl_Obj *o = Tcl_NewDoubleObj($1);
|
Tcl_Obj *o = Tcl_NewDoubleObj($1);
|
||||||
Tcl_ListObjAppendElement(interp,$result,o);
|
Tcl_ListObjAppendElement(interp,$result,o);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A typemap telling SWIG to ignore an argument for input
|
// A typemap telling SWIG to ignore an argument for input
|
||||||
// However, we still need to pass a pointer to the C function
|
// However, we still need to pass a pointer to the C function
|
||||||
%typemap(in,numinputs=0) double *outvalue (double temp) {
|
%typemap(in,numinputs=0) double *outvalue (double temp) {
|
||||||
$1 = &temp;
|
$1 = &temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now a function returning two values
|
// Now a function returning two values
|
||||||
int mypow(double a, double b, double *outvalue) {
|
int mypow(double a, double b, double *outvalue) {
|
||||||
if ((a < 0) || (b < 0)) return -1;
|
if ((a < 0) || (b < 0)) return -1;
|
||||||
*outvalue = pow(a,b);
|
*outvalue = pow(a,b);
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
|
|
@ -2992,7 +2991,7 @@ work)
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%typemap(out) int, short, long {
|
%typemap(out) int, short, long {
|
||||||
Tcl_SetIntObj($result,(int) $1);
|
Tcl_SetIntObj($result,(int) $1);
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3004,10 +3003,10 @@ work)
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%typemap(in) float, double {
|
%typemap(in) float, double {
|
||||||
double temp;
|
double temp;
|
||||||
if (Tcl_GetDoubleFromObj(interp, $input, &temp) == TCL_ERROR)
|
if (Tcl_GetDoubleFromObj(interp, $input, &temp) == TCL_ERROR)
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
$1 = ($1_ltype) temp;
|
$1 = ($1_ltype) temp;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3017,7 +3016,7 @@ work)
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%typemap(out) float, double {
|
%typemap(out) float, double {
|
||||||
Tcl_SetDoubleObj($result, $1);
|
Tcl_SetDoubleObj($result, $1);
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3029,9 +3028,8 @@ work)
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%typemap(in) char * {
|
%typemap(in) char * {
|
||||||
int len;
|
int len;
|
||||||
$1 = Tcl_GetStringFromObj(interp, &len);
|
$1 = Tcl_GetStringFromObj(interp, &len);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3090,7 +3088,9 @@ is usually accessed as follows:
|
||||||
<div class="indent">
|
<div class="indent">
|
||||||
<pre>
|
<pre>
|
||||||
Foo *f;
|
Foo *f;
|
||||||
if (SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, 0) == -1) return NULL;
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, 0))) {
|
||||||
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
||||||
|
}
|
||||||
|
|
||||||
Tcl_Obj *;
|
Tcl_Obj *;
|
||||||
obj = SWIG_NewPointerObj(f, SWIGTYPE_p_Foo, 0);
|
obj = SWIG_NewPointerObj(f, SWIGTYPE_p_Foo, 0);
|
||||||
|
|
@ -3105,7 +3105,9 @@ variable <tt>$1_descriptor</tt>. For example:
|
||||||
<div class="indent">
|
<div class="indent">
|
||||||
<pre>
|
<pre>
|
||||||
%typemap(in) Foo * {
|
%typemap(in) Foo * {
|
||||||
if ((SWIG_ConvertPtr($input,(void **) &$1, $1_descriptor,0)) == -1) return NULL;
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 0))) {
|
||||||
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3118,7 +3120,9 @@ For example:
|
||||||
<div class="indent">
|
<div class="indent">
|
||||||
<pre>
|
<pre>
|
||||||
%typemap(in) Foo * {
|
%typemap(in) Foo * {
|
||||||
if ((SWIG_ConvertPtr($input,(void **) &$1, $descriptor(Foo *), 0)) == -1) return NULL;
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $descriptor(Foo *), 0))) {
|
||||||
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -126,16 +126,16 @@ example:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
List make_list(const char *s, ...) {
|
List make_list(const char *s, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
List x;
|
List x;
|
||||||
...
|
...
|
||||||
va_start(ap, s);
|
va_start(ap, s);
|
||||||
while (s) {
|
while (s) {
|
||||||
x.append(s);
|
x.append(s);
|
||||||
s = va_arg(ap, const char *);
|
s = va_arg(ap, const char *);
|
||||||
}
|
}
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -188,12 +188,12 @@ In contrast, suppose you attempted to make some kind of wrapper around
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
int wrap_printf(const char *fmt, ...) {
|
int wrap_printf(const char *fmt, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap,fmt);
|
va_start(ap,fmt);
|
||||||
...
|
...
|
||||||
printf(fmt,ap);
|
printf(fmt,ap);
|
||||||
...
|
...
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -471,15 +471,15 @@ like this:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
wrap_printf() {
|
wrap_printf() {
|
||||||
char *arg1;
|
char *arg1;
|
||||||
void *arg2;
|
void *arg2;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
arg1 = "%s";
|
arg1 = "%s";
|
||||||
arg2 = (void *) PyString_AsString(arg2obj);
|
arg2 = (void *) PyString_AsString(arg2obj);
|
||||||
...
|
...
|
||||||
result = printf(arg1,arg2);
|
result = printf(arg1,arg2);
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -517,7 +517,7 @@ like this:
|
||||||
argc = PyTuple_Size(varargs);
|
argc = PyTuple_Size(varargs);
|
||||||
if (argc > 10) {
|
if (argc > 10) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Too many arguments");
|
PyErr_SetString(PyExc_ValueError, "Too many arguments");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
PyObject *pyobj = PyTuple_GetItem(varargs, i);
|
PyObject *pyobj = PyTuple_GetItem(varargs, i);
|
||||||
|
|
@ -525,16 +525,16 @@ like this:
|
||||||
%#if PY_VERSION_HEX>=0x03000000
|
%#if PY_VERSION_HEX>=0x03000000
|
||||||
PyObject *pystr;
|
PyObject *pystr;
|
||||||
if (!PyUnicode_Check(pyobj)) {
|
if (!PyUnicode_Check(pyobj)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
pystr = PyUnicode_AsUTF8String(pyobj);
|
pystr = PyUnicode_AsUTF8String(pyobj);
|
||||||
str = strdup(PyBytes_AsString(pystr));
|
str = strdup(PyBytes_AsString(pystr));
|
||||||
Py_XDECREF(pystr);
|
Py_XDECREF(pystr);
|
||||||
%#else
|
%#else
|
||||||
if (!PyString_Check(pyobj)) {
|
if (!PyString_Check(pyobj)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
str = PyString_AsString(pyobj);
|
str = PyString_AsString(pyobj);
|
||||||
%#endif
|
%#endif
|
||||||
|
|
@ -626,23 +626,23 @@ example. For example:
|
||||||
of strings */
|
of strings */
|
||||||
|
|
||||||
%typemap(in) (...) {
|
%typemap(in) (...) {
|
||||||
char **argv;
|
char **argv;
|
||||||
int argc;
|
int argc;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
argc = PyTuple_Size(varargs);
|
argc = PyTuple_Size(varargs);
|
||||||
argv = (char **) malloc(sizeof(char *)*(argc+1));
|
argv = (char **) malloc(sizeof(char *)*(argc+1));
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
PyObject *o = PyTuple_GetItem(varargs,i);
|
PyObject *o = PyTuple_GetItem(varargs,i);
|
||||||
if (!PyString_Check(o)) {
|
if (!PyString_Check(o)) {
|
||||||
PyErr_SetString(PyExc_ValueError,"Expected a string");
|
free(argv);
|
||||||
free(argv);
|
PyErr_SetString(PyExc_ValueError,"Expected a string");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
argv[i] = PyString_AsString(o);
|
argv[i] = PyString_AsString(o);
|
||||||
}
|
}
|
||||||
argv[i] = NULL;
|
argv[i] = NULL;
|
||||||
$1 = (void *) argv;
|
$1 = (void *) argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rewrite the function call, using libffi */
|
/* Rewrite the function call, using libffi */
|
||||||
|
|
@ -676,11 +676,11 @@ example. For example:
|
||||||
&ffi_type_uint, types) == FFI_OK) {
|
&ffi_type_uint, types) == FFI_OK) {
|
||||||
ffi_call(&cif, (void (*)()) execlp, &result, values);
|
ffi_call(&cif, (void (*)()) execlp, &result, values);
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
|
|
||||||
free(types);
|
free(types);
|
||||||
free(values);
|
free(values);
|
||||||
free(arg3);
|
free(arg3);
|
||||||
return NULL;
|
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
|
||||||
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
free(types);
|
free(types);
|
||||||
free(values);
|
free(values);
|
||||||
|
|
@ -744,8 +744,8 @@ As a more extreme example of libffi, here is some code that attempts to wrap <tt
|
||||||
argv[i].type = VT_POINTER;
|
argv[i].type = VT_POINTER;
|
||||||
argv[i].val.pvalue = (void *) PyString_AsString(o);
|
argv[i].val.pvalue = (void *) PyString_AsString(o);
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(PyExc_ValueError,"Unsupported argument type");
|
|
||||||
free(argv);
|
free(argv);
|
||||||
|
PyErr_SetString(PyExc_ValueError,"Unsupported argument type");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -793,11 +793,11 @@ As a more extreme example of libffi, here is some code that attempts to wrap <tt
|
||||||
&ffi_type_uint, types) == FFI_OK) {
|
&ffi_type_uint, types) == FFI_OK) {
|
||||||
ffi_call(&cif, (void (*)()) printf, &result, values);
|
ffi_call(&cif, (void (*)()) printf, &result, values);
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
|
|
||||||
free(types);
|
free(types);
|
||||||
free(values);
|
free(values);
|
||||||
free(args);
|
free(args);
|
||||||
return NULL;
|
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
|
||||||
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
free(types);
|
free(types);
|
||||||
free(values);
|
free(values);
|
||||||
|
|
@ -912,12 +912,12 @@ and it fully supports classes much like the <tt>%rename</tt> directive. For exa
|
||||||
|
|
||||||
class Foo {
|
class Foo {
|
||||||
public:
|
public:
|
||||||
virtual void bar(char *arg, ...); // gets varargs above
|
virtual void bar(char *arg, ...); // gets varargs above
|
||||||
};
|
};
|
||||||
|
|
||||||
class Spam: public Foo {
|
class Spam: public Foo {
|
||||||
public:
|
public:
|
||||||
virtual void bar(char *arg, ...); // gets varargs above
|
virtual void bar(char *arg, ...); // gets varargs above
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -952,9 +952,9 @@ are placed in <tt>arg2</tt>, <tt>arg3</tt>, and so forth. For example:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%feature("action") Foo::bar {
|
%feature("action") Foo::bar {
|
||||||
...
|
...
|
||||||
result = arg1->bar(arg2, arg3, etc.);
|
result = arg1->bar(arg2, arg3, etc.);
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -987,10 +987,10 @@ you might structure your interface like this:
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%typemap(const char *fmt, ...) {
|
%typemap(const char *fmt, ...) {
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
%feature("action") traceprintf {
|
%feature("action") traceprintf {
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Include some header file with traceprintf in it */
|
/* Include some header file with traceprintf in it */
|
||||||
|
|
@ -1011,7 +1011,7 @@ to control this:
|
||||||
<pre>
|
<pre>
|
||||||
#ifdef USE_LIBFFI
|
#ifdef USE_LIBFFI
|
||||||
%feature("action") printf {
|
%feature("action") printf {
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_OTHERFFI
|
#ifdef USE_OTHERFFI
|
||||||
|
|
|
||||||
|
|
@ -112,16 +112,16 @@ suppress a warning for a method in a class hierarchy, you could do this:
|
||||||
%warnfilter(501) Object::foo;
|
%warnfilter(501) Object::foo;
|
||||||
class Object {
|
class Object {
|
||||||
public:
|
public:
|
||||||
int foo(int);
|
int foo(int);
|
||||||
int foo(double); // Silently ignored
|
int foo(double); // Silently ignored
|
||||||
...
|
...
|
||||||
};
|
};
|
||||||
|
|
||||||
class Derived : public Object {
|
class Derived : public Object {
|
||||||
public:
|
public:
|
||||||
int foo(int);
|
int foo(int);
|
||||||
int foo(double); // Silently ignored
|
int foo(double); // Silently ignored
|
||||||
...
|
...
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -136,7 +136,7 @@ Warnings can be suppressed for an entire class by supplying a class name. For e
|
||||||
|
|
||||||
class Object {
|
class Object {
|
||||||
public:
|
public:
|
||||||
... // All 501 warnings ignored in class
|
... // All 501 warnings ignored in class
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -259,7 +259,7 @@ Warning messages can be associated with typemaps using the
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
%typemap(in, warning="901:You are really going to regret this usage of $1_type $1_name") blah * {
|
%typemap(in, warning="901:You are really going to regret this usage of $1_type $1_name") blah * {
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
PyObject *o = PyTuple_GetItem(varargs,i);
|
PyObject *o = PyTuple_GetItem(varargs,i);
|
||||||
if (!PyString_Check(o)) {
|
if (!PyString_Check(o)) {
|
||||||
PyErr_SetString(PyExc_ValueError,"Expected a string");
|
PyErr_SetString(PyExc_ValueError,"Expected a string");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
argv[i] = PyString_AsString(o);
|
argv[i] = PyString_AsString(o);
|
||||||
}
|
}
|
||||||
|
|
@ -58,11 +58,11 @@
|
||||||
&ffi_type_uint, types) == FFI_OK) {
|
&ffi_type_uint, types) == FFI_OK) {
|
||||||
ffi_call(&cif, (void (*)()) execlp, &result, values);
|
ffi_call(&cif, (void (*)()) execlp, &result, values);
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
|
|
||||||
free(types);
|
free(types);
|
||||||
free(values);
|
free(values);
|
||||||
free(arg3);
|
free(arg3);
|
||||||
return NULL;
|
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
|
||||||
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
free(types);
|
free(types);
|
||||||
free(values);
|
free(values);
|
||||||
|
|
@ -107,9 +107,9 @@ int execlp(const char *path, const char *arg1, ...);
|
||||||
argv[i].type = VT_POINTER;
|
argv[i].type = VT_POINTER;
|
||||||
argv[i].val.pvalue = (void *) PyString_AsString(o);
|
argv[i].val.pvalue = (void *) PyString_AsString(o);
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(PyExc_ValueError,"Unsupported argument type");
|
|
||||||
free(argv);
|
free(argv);
|
||||||
return NULL;
|
PyErr_SetString(PyExc_ValueError,"Unsupported argument type");
|
||||||
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,11 +157,11 @@ int execlp(const char *path, const char *arg1, ...);
|
||||||
&ffi_type_uint, types) == FFI_OK) {
|
&ffi_type_uint, types) == FFI_OK) {
|
||||||
ffi_call(&cif, (void (*)()) printf, &result, values);
|
ffi_call(&cif, (void (*)()) printf, &result, values);
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
|
|
||||||
free(types);
|
free(types);
|
||||||
free(values);
|
free(values);
|
||||||
free(args);
|
free(args);
|
||||||
return NULL;
|
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
|
||||||
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
free(types);
|
free(types);
|
||||||
free(values);
|
free(values);
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ extern int gcdmain(int argc, char *argv[]);
|
||||||
PyObject *utf8str;
|
PyObject *utf8str;
|
||||||
if (!PyUnicode_Check($input)) {
|
if (!PyUnicode_Check($input)) {
|
||||||
PyErr_SetString(PyExc_ValueError,"Expected a string");
|
PyErr_SetString(PyExc_ValueError,"Expected a string");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
utf8str = PyUnicode_AsUTF8String($input);
|
utf8str = PyUnicode_AsUTF8String($input);
|
||||||
PyBytes_AsStringAndSize(utf8str, &cstr, &len);
|
PyBytes_AsStringAndSize(utf8str, &cstr, &len);
|
||||||
|
|
@ -79,7 +79,7 @@ extern int gcdmain(int argc, char *argv[]);
|
||||||
%#else
|
%#else
|
||||||
if (!PyString_Check($input)) {
|
if (!PyString_Check($input)) {
|
||||||
PyErr_SetString(PyExc_ValueError,"Expected a string");
|
PyErr_SetString(PyExc_ValueError,"Expected a string");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
$1 = PyString_AsString($input);
|
$1 = PyString_AsString($input);
|
||||||
$2 = (int)PyString_Size($input);
|
$2 = (int)PyString_Size($input);
|
||||||
|
|
|
||||||
|
|
@ -203,6 +203,7 @@ CPP_TEST_CASES += \
|
||||||
director_thread \
|
director_thread \
|
||||||
director_unroll \
|
director_unroll \
|
||||||
director_using \
|
director_using \
|
||||||
|
director_void \
|
||||||
director_wombat \
|
director_wombat \
|
||||||
disown \
|
disown \
|
||||||
dynamic_cast \
|
dynamic_cast \
|
||||||
|
|
@ -259,7 +260,6 @@ CPP_TEST_CASES += \
|
||||||
langobj \
|
langobj \
|
||||||
li_attribute \
|
li_attribute \
|
||||||
li_attribute_template \
|
li_attribute_template \
|
||||||
li_boost_array \
|
|
||||||
li_boost_shared_ptr \
|
li_boost_shared_ptr \
|
||||||
li_boost_shared_ptr_bits \
|
li_boost_shared_ptr_bits \
|
||||||
li_boost_shared_ptr_template \
|
li_boost_shared_ptr_template \
|
||||||
|
|
@ -487,6 +487,7 @@ CPP_TEST_CASES += \
|
||||||
typemap_array_qualifiers \
|
typemap_array_qualifiers \
|
||||||
typemap_delete \
|
typemap_delete \
|
||||||
typemap_directorout \
|
typemap_directorout \
|
||||||
|
typemap_documentation \
|
||||||
typemap_global_scope \
|
typemap_global_scope \
|
||||||
typemap_manyargs \
|
typemap_manyargs \
|
||||||
typemap_namespace \
|
typemap_namespace \
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
%module cpp11_li_std_array
|
%module cpp11_li_std_array
|
||||||
|
|
||||||
#if defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGJAVA)
|
#if defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGJAVA) || defined(SWIGCSHARP)
|
||||||
|
|
||||||
%{
|
%{
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
|
||||||
|
|
@ -22,5 +22,28 @@ public:
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%{
|
%{
|
||||||
int StaticMemberTest::static_int;
|
int StaticMemberTest::static_int = 99;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
struct StaticBase {
|
||||||
|
static int statty;
|
||||||
|
virtual ~StaticBase() {}
|
||||||
|
};
|
||||||
|
struct StaticDerived : StaticBase {
|
||||||
|
static int statty;
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
%{
|
||||||
|
int StaticBase::statty = 11;
|
||||||
|
int StaticDerived::statty = 111;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
#ifdef SWIGPYTHON_BUILTIN
|
||||||
|
bool is_python_builtin() { return true; }
|
||||||
|
#else
|
||||||
|
bool is_python_builtin() { return false; }
|
||||||
|
#endif
|
||||||
%}
|
%}
|
||||||
|
|
|
||||||
82
Examples/test-suite/csharp/cpp11_li_std_array_runme.cs
Normal file
82
Examples/test-suite/csharp/cpp11_li_std_array_runme.cs
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
// This test tests all the methods in the C# collection wrapper
|
||||||
|
using System;
|
||||||
|
using cpp11_li_std_arrayNamespace;
|
||||||
|
|
||||||
|
public class cpp11_li_std_array_runme
|
||||||
|
{
|
||||||
|
private static ArrayInt6 ToArray6(int[] a)
|
||||||
|
{
|
||||||
|
if (a.Length != 6)
|
||||||
|
throw new Exception("a is incorrect size");
|
||||||
|
return new ArrayInt6(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void compareContainers(ArrayInt6 actual, int[] expected)
|
||||||
|
{
|
||||||
|
if (actual.Count != expected.Length)
|
||||||
|
throw new Exception("Sizes are different: " + actual.Count + " " + expected.Length);
|
||||||
|
for (int i=0; i<actual.Count; ++i)
|
||||||
|
{
|
||||||
|
int actualValue = actual[i];
|
||||||
|
int expectedValue = expected[i];
|
||||||
|
if (actualValue != expectedValue)
|
||||||
|
throw new Exception("Value is wrong for element " + i + ". Expected " + expectedValue + " got: " + actualValue);
|
||||||
|
}
|
||||||
|
if (actual.IsEmpty)
|
||||||
|
throw new Exception("ai should not be empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Main()
|
||||||
|
{
|
||||||
|
ArrayInt6 ai = new ArrayInt6();
|
||||||
|
compareContainers(ai, new int[] { 0, 0, 0, 0, 0, 0 });
|
||||||
|
|
||||||
|
int[] vals = { 10, 20, 30, 40, 50, 60 };
|
||||||
|
for (int i = 0; i < ai.Count; ++i)
|
||||||
|
ai[i] = vals[i];
|
||||||
|
compareContainers(ai, vals);
|
||||||
|
|
||||||
|
// Check return
|
||||||
|
compareContainers(cpp11_li_std_array.arrayOutVal(), new int[] { -2, -1, 0, 0, 1, 2 });
|
||||||
|
compareContainers(cpp11_li_std_array.arrayOutConstRef(), new int[] { -2, -1, 0, 0, 1, 2 });
|
||||||
|
compareContainers(cpp11_li_std_array.arrayOutRef(), new int[] { -2, -1, 0, 0, 1, 2 });
|
||||||
|
compareContainers(cpp11_li_std_array.arrayOutPtr(), new int[] { -2, -1, 0, 0, 1, 2 });
|
||||||
|
|
||||||
|
// Check passing arguments
|
||||||
|
ai = cpp11_li_std_array.arrayInVal(ToArray6(new int[] { 9, 8, 7, 6, 5, 4 }));
|
||||||
|
compareContainers(ai, new int[] { 90, 80, 70, 60, 50, 40 });
|
||||||
|
|
||||||
|
ai = cpp11_li_std_array.arrayInConstRef(ToArray6(new int[] { 9, 8, 7, 6, 5, 4 }));
|
||||||
|
compareContainers(ai, new int[] { 90, 80, 70, 60, 50, 40 });
|
||||||
|
|
||||||
|
ai = new ArrayInt6(ToArray6(new int[] { 9, 8, 7, 6, 5, 4 }));
|
||||||
|
cpp11_li_std_array.arrayInRef(ai);
|
||||||
|
compareContainers(ai, new int[] { 90, 80, 70, 60, 50, 40 });
|
||||||
|
|
||||||
|
ai = new ArrayInt6(ToArray6(new int[] { 9, 8, 7, 6, 5, 4 }));
|
||||||
|
cpp11_li_std_array.arrayInPtr(ai);
|
||||||
|
compareContainers(ai, new int[] { 90, 80, 70, 60, 50, 40 });
|
||||||
|
|
||||||
|
// fill
|
||||||
|
ai.Fill(111);
|
||||||
|
compareContainers(ai, new int[] { 111, 111, 111, 111, 111, 111 });
|
||||||
|
|
||||||
|
// out of range errors
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ai[ai.Count] = 0;
|
||||||
|
throw new Exception("Out of range exception not caught");
|
||||||
|
}
|
||||||
|
catch (ArgumentOutOfRangeException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ai[-1] = 0;
|
||||||
|
throw new Exception("Out of range exception not caught");
|
||||||
|
}
|
||||||
|
catch (ArgumentOutOfRangeException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
83
Examples/test-suite/csharp/director_void_runme.cs
Normal file
83
Examples/test-suite/csharp/director_void_runme.cs
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
using System;
|
||||||
|
using director_voidNamespace;
|
||||||
|
|
||||||
|
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();
|
||||||
|
{
|
||||||
|
DirectorVoidPointer dvp = new DirectorVoidPointer(5);
|
||||||
|
int x = caller.callVirtualIn(dvp, 6);
|
||||||
|
if (x != 106)
|
||||||
|
throw new Exception("Fail1 should be 106, got " + x);
|
||||||
|
global::System.IntPtr ptr = dvp.nonVirtualVoidPtrOut();
|
||||||
|
x = Caller.VoidToInt(ptr);
|
||||||
|
if (x != 106)
|
||||||
|
throw new Exception("Fail2 should be 106, got " + x);
|
||||||
|
x = Caller.VoidToInt(dvp.voidPtrOut());
|
||||||
|
if (x != 106)
|
||||||
|
throw new Exception("Fail3 should be 106, got " + x);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
DirectorVoidPointer dvp = new director_void_VoidPointer(5);
|
||||||
|
int x = caller.callVirtualIn(dvp, 6);
|
||||||
|
if (x != 12)
|
||||||
|
throw new Exception("Fail1 should be 12, got " + x);
|
||||||
|
global::System.IntPtr ptr = dvp.nonVirtualVoidPtrOut();
|
||||||
|
x = Caller.VoidToInt(ptr);
|
||||||
|
if (x != 25)
|
||||||
|
throw new Exception("Fail2 should be 25, got " + x);
|
||||||
|
x = Caller.VoidToInt(dvp.voidPtrOut());
|
||||||
|
if (x != 1234)
|
||||||
|
throw new Exception("Fail3 should be 1234, got " + x);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
DirectorVoidPointer dvp = new DirectorVoidPointer(10);
|
||||||
|
int x = caller.callVirtualOut(dvp);
|
||||||
|
if (x != 10)
|
||||||
|
throw new Exception("Bad1 should be 10, got " + x);
|
||||||
|
global::System.IntPtr ptr = dvp.nonVirtualVoidPtrOut();
|
||||||
|
x = dvp.nonVirtualVoidPtrIn(ptr);
|
||||||
|
if (x != 110)
|
||||||
|
throw new Exception("Bad2 should be 110, got " + x);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
DirectorVoidPointer dvp = new director_void_VoidPointer(10);
|
||||||
|
int x = caller.callVirtualOut(dvp);
|
||||||
|
if (x != 1234)
|
||||||
|
throw new Exception("Bad3 should be 1234, got " + x);
|
||||||
|
global::System.IntPtr ptr = dvp.nonVirtualVoidPtrOut();
|
||||||
|
x = dvp.nonVirtualVoidPtrIn(ptr);
|
||||||
|
if (x != 1334)
|
||||||
|
throw new Exception("Bad4 should be 1334, got " + x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class director_void_VoidPointer : DirectorVoidPointer {
|
||||||
|
public director_void_VoidPointer(int num) : base(num*num) {
|
||||||
|
}
|
||||||
|
public override int voidPtrIn(global::System.IntPtr p) {
|
||||||
|
return Caller.VoidToInt(p) * 2;
|
||||||
|
}
|
||||||
|
public override global::System.IntPtr voidPtrOut() {
|
||||||
|
setNewValue(1234);
|
||||||
|
return nonVirtualVoidPtrOut();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -405,6 +405,10 @@ public class runme {
|
||||||
if (enum_thorough_typesafe.repeatTest(repeat.llast).swigValue != 3) throw new Exception("repeatTest 5 failed");
|
if (enum_thorough_typesafe.repeatTest(repeat.llast).swigValue != 3) throw new Exception("repeatTest 5 failed");
|
||||||
if (enum_thorough_typesafe.repeatTest(repeat.end).swigValue != 3) throw new Exception("repeatTest 6 failed");
|
if (enum_thorough_typesafe.repeatTest(repeat.end).swigValue != 3) throw new Exception("repeatTest 6 failed");
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
if (enum_thorough_typesafe.enumWithMacroTest(enumWithMacro.ABCD).swigValue != (('A' << 24) | ('B' << 16) | ('C' << 8) | 'D')) throw new Exception("enumWithMacroTest 1 failed");
|
||||||
|
if (enum_thorough_typesafe.enumWithMacroTest(enumWithMacro.ABCD2).swigValue != enum_thorough_typesafe.enumWithMacroTest(enumWithMacro.ABCD).swigValue) throw new Exception("enumWithMacroTest 2 failed");
|
||||||
|
}
|
||||||
// different types
|
// different types
|
||||||
{
|
{
|
||||||
if (enum_thorough_typesafe.differentTypesTest(DifferentTypes.typeint).swigValue != 10) throw new Exception("differentTypes 1 failed");
|
if (enum_thorough_typesafe.differentTypesTest(DifferentTypes.typeint).swigValue != 10) throw new Exception("differentTypes 1 failed");
|
||||||
|
|
@ -413,6 +417,8 @@ public class runme {
|
||||||
if (enum_thorough_typesafe.differentTypesTest(DifferentTypes.typeboolfalse).swigValue != 0) throw new Exception("differentTypes 4 failed");
|
if (enum_thorough_typesafe.differentTypesTest(DifferentTypes.typeboolfalse).swigValue != 0) throw new Exception("differentTypes 4 failed");
|
||||||
if (enum_thorough_typesafe.differentTypesTest(DifferentTypes.typechar).swigValue != (int)'C') throw new Exception("differentTypes 5 failed");
|
if (enum_thorough_typesafe.differentTypesTest(DifferentTypes.typechar).swigValue != (int)'C') throw new Exception("differentTypes 5 failed");
|
||||||
if (enum_thorough_typesafe.differentTypesTest(DifferentTypes.typedefaultint).swigValue != (int)'D') throw new Exception("differentTypes 6 failed");
|
if (enum_thorough_typesafe.differentTypesTest(DifferentTypes.typedefaultint).swigValue != (int)'D') throw new Exception("differentTypes 6 failed");
|
||||||
|
if (enum_thorough_typesafe.differentTypesTest(DifferentTypes.typecharcompound).swigValue != (int)'A' + 1) throw new Exception("differentTypes 7 failed");
|
||||||
|
if (enum_thorough_typesafe.differentTypesTest(DifferentTypes.typecharcompound2).swigValue != (int)'B' << 2) throw new Exception("differentTypes 8 failed");
|
||||||
|
|
||||||
int global_enum = enum_thorough_typesafe.global_typeint;
|
int global_enum = enum_thorough_typesafe.global_typeint;
|
||||||
if (enum_thorough_typesafe.globalDifferentTypesTest(global_enum) != 10) throw new Exception("global differentTypes 1 failed");
|
if (enum_thorough_typesafe.globalDifferentTypesTest(global_enum) != 10) throw new Exception("global differentTypes 1 failed");
|
||||||
|
|
@ -426,6 +432,10 @@ public class runme {
|
||||||
if (enum_thorough_typesafe.globalDifferentTypesTest(global_enum) != 'C') throw new Exception("global differentTypes 5 failed");
|
if (enum_thorough_typesafe.globalDifferentTypesTest(global_enum) != 'C') throw new Exception("global differentTypes 5 failed");
|
||||||
global_enum = enum_thorough_typesafe.global_typedefaultint;
|
global_enum = enum_thorough_typesafe.global_typedefaultint;
|
||||||
if (enum_thorough_typesafe.globalDifferentTypesTest(global_enum) != 'D') throw new Exception("global differentTypes 6 failed");
|
if (enum_thorough_typesafe.globalDifferentTypesTest(global_enum) != 'D') throw new Exception("global differentTypes 6 failed");
|
||||||
|
global_enum = enum_thorough_typesafe.global_typecharcompound;
|
||||||
|
if (enum_thorough_typesafe.globalDifferentTypesTest(global_enum) != (int)'A' + 1) throw new Exception("global differentTypes 7 failed");
|
||||||
|
global_enum = enum_thorough_typesafe.global_typecharcompound2;
|
||||||
|
if (enum_thorough_typesafe.globalDifferentTypesTest(global_enum) != (int)'B' << 2) throw new Exception("global differentTypes 8 failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
47
Examples/test-suite/director_void.i
Normal file
47
Examples/test-suite/director_void.i
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
%module(directors="1") director_void
|
||||||
|
|
||||||
|
%warnfilter(SWIGWARN_TYPEMAP_DIRECTOROUT_PTR) voidPtrOut;
|
||||||
|
|
||||||
|
%feature("director") DirectorVoidPointer;
|
||||||
|
|
||||||
|
#if defined(SWIGCSHARP)
|
||||||
|
%apply void *VOID_INT_PTR { void * }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
class DirectorVoidPointer {
|
||||||
|
int *ptr;
|
||||||
|
public:
|
||||||
|
DirectorVoidPointer(int val) : ptr(new int(val)) {}
|
||||||
|
virtual ~DirectorVoidPointer() { delete ptr; }
|
||||||
|
|
||||||
|
virtual void * voidPtrOut() { return ptr; }
|
||||||
|
virtual int voidPtrIn(void *p) {
|
||||||
|
return nonVirtualVoidPtrIn(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setNewValue(int val) {
|
||||||
|
delete ptr;
|
||||||
|
ptr = new int(val);
|
||||||
|
}
|
||||||
|
void *nonVirtualVoidPtrOut() { return ptr; }
|
||||||
|
int nonVirtualVoidPtrIn(void *p) {
|
||||||
|
int val = *(int *)p;
|
||||||
|
setNewValue(val + 100);
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Caller {
|
||||||
|
int callVirtualIn(DirectorVoidPointer *d, int num) {
|
||||||
|
return d->voidPtrIn(&num);
|
||||||
|
}
|
||||||
|
int callVirtualOut(DirectorVoidPointer *d) {
|
||||||
|
return *(int *)d->voidPtrOut();
|
||||||
|
}
|
||||||
|
static int VoidToInt(void *p) {
|
||||||
|
return *(int *)p;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
@ -569,6 +569,17 @@ repeat repeatTest(repeat e) { return e; }
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
namespace EnumWithMacro {
|
||||||
|
#define PACK(C1,C2,C3,C4) ((C1<<24)|(C2<<16)|(C3<<8)|C4)
|
||||||
|
typedef enum {
|
||||||
|
ABCD = PACK('A','B','C','D'),
|
||||||
|
ABCD2 = ABCD
|
||||||
|
} enumWithMacro;
|
||||||
|
enumWithMacro enumWithMacroTest(enumWithMacro e) { return e; }
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
namespace DifferentSpace {
|
namespace DifferentSpace {
|
||||||
enum DifferentTypes {
|
enum DifferentTypes {
|
||||||
|
|
@ -577,7 +588,9 @@ enum DifferentTypes {
|
||||||
typebooltrue = true,
|
typebooltrue = true,
|
||||||
typebooltwo,
|
typebooltwo,
|
||||||
typechar = 'C',
|
typechar = 'C',
|
||||||
typedefaultint
|
typedefaultint,
|
||||||
|
typecharcompound='A'+1,
|
||||||
|
typecharcompound2='B' << 2
|
||||||
};
|
};
|
||||||
DifferentTypes differentTypesTest(DifferentTypes n) { return n; }
|
DifferentTypes differentTypesTest(DifferentTypes n) { return n; }
|
||||||
|
|
||||||
|
|
@ -587,7 +600,9 @@ enum {
|
||||||
global_typebooltrue = true,
|
global_typebooltrue = true,
|
||||||
global_typebooltwo,
|
global_typebooltwo,
|
||||||
global_typechar = 'C',
|
global_typechar = 'C',
|
||||||
global_typedefaultint
|
global_typedefaultint,
|
||||||
|
global_typecharcompound='A'+1,
|
||||||
|
global_typecharcompound2='B' << 2
|
||||||
};
|
};
|
||||||
int globalDifferentTypesTest(int n) { return n; }
|
int globalDifferentTypesTest(int n) { return n; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
%module exception_classname
|
%module exception_classname
|
||||||
|
|
||||||
%warnfilter(SWIGWARN_RUBY_WRONG_NAME);
|
%warnfilter(SWIGWARN_RUBY_WRONG_NAME);
|
||||||
#ifdef SWIGPHP
|
#if defined(SWIGPHP) || defined(SWIGD)
|
||||||
%rename(ExceptionClass) Exception;
|
%rename(ExceptionClass) Exception;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ public class smart_pointer_ignore_runme {
|
||||||
|
|
||||||
public static void main(String argv[]) {
|
public static void main(String argv[]) {
|
||||||
DerivedPtr d = smart_pointer_ignore.makeDerived();
|
DerivedPtr d = smart_pointer_ignore.makeDerived();
|
||||||
d.base();
|
d.baseMethod();
|
||||||
d.derived();
|
d.derivedMethod();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
||||||
%module li_boost_array
|
|
||||||
|
|
||||||
#if defined(SWIGPYTHON) || defined(SWIGRUBY)
|
|
||||||
|
|
||||||
// Hack to use the std::array support for boost::array.
|
|
||||||
// Is limited as it currently exposes some 'using' bugs in SWIG though.
|
|
||||||
// For example, the type system fails to see that pointers to std::array
|
|
||||||
// and pointers to boost::array are the same.
|
|
||||||
|
|
||||||
%{
|
|
||||||
#if __cplusplus >= 201103 || (defined(_MSC_VER) && _MSC_VER >= 1900)
|
|
||||||
// Use C++11 array as this is unfortunately sometimes included by <algorithm>
|
|
||||||
#include <array>
|
|
||||||
namespace boost {
|
|
||||||
using std::array;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#include <boost/array.hpp>
|
|
||||||
namespace std {
|
|
||||||
using boost::array;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
%}
|
|
||||||
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>;
|
|
||||||
|
|
||||||
%inline %{
|
|
||||||
boost::array<int, 6> arrayOutVal() {
|
|
||||||
const signed char carray[] = { -2, -1, 0, 0, 1, 2 };
|
|
||||||
boost::array<int, 6> myarray;
|
|
||||||
for (size_t i=0; i<6; ++i) {
|
|
||||||
myarray[i] = carray[i];
|
|
||||||
}
|
|
||||||
return myarray;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::array<int, 6> & arrayOutRef() {
|
|
||||||
static boost::array<int, 6> a = { -2, -1, 0, 0, 1, 2 };
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::array<int, 6> & arrayOutConstRef() {
|
|
||||||
static boost::array<int, 6> a = { -2, -1, 0, 0, 1, 2 };
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::array<int, 6> * arrayOutPtr() {
|
|
||||||
static boost::array<int, 6> a = { -2, -1, 0, 0, 1, 2 };
|
|
||||||
return &a;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::array<int, 6> arrayInVal(boost::array<int, 6> myarray) {
|
|
||||||
for (boost::array<int, 6>::iterator it = myarray.begin(); it!=myarray.end(); ++it) {
|
|
||||||
*it *= 10;
|
|
||||||
}
|
|
||||||
return myarray;
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::array<int, 6> & arrayInConstRef(const boost::array<int, 6> & myarray) {
|
|
||||||
static boost::array<int, 6> a = myarray;
|
|
||||||
for (boost::array<int, 6>::iterator it = a.begin(); it!=a.end(); ++it) {
|
|
||||||
*it *= 10;
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
void arrayInRef(boost::array<int, 6> & myarray) {
|
|
||||||
for (boost::array<int, 6>::iterator it = myarray.begin(); it!=myarray.end(); ++it) {
|
|
||||||
*it *= 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void arrayInPtr(boost::array<int, 6> * myarray) {
|
|
||||||
for (boost::array<int, 6>::iterator it = myarray->begin(); it!=myarray->end(); ++it) {
|
|
||||||
*it *= 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
%}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -50,7 +50,7 @@ namespace test {
|
||||||
PyComplex_ImagAsDouble($input));
|
PyComplex_ImagAsDouble($input));
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(PyExc_TypeError,"Expected test_complex.\n");
|
PyErr_SetString(PyExc_TypeError,"Expected test_complex.\n");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
%typemap(freearg) test::test_complex * {
|
%typemap(freearg) test::test_complex * {
|
||||||
|
|
@ -242,7 +242,7 @@ namespace Split {
|
||||||
$1 = PyInt_AsLong($input);
|
$1 = PyInt_AsLong($input);
|
||||||
if ($1 < 0) {
|
if ($1 < 0) {
|
||||||
PyErr_SetString(PyExc_ValueError,"domain error\n");
|
PyErr_SetString(PyExc_ValueError,"domain error\n");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,11 @@ require "tests.php";
|
||||||
require "cpp_static.php";
|
require "cpp_static.php";
|
||||||
|
|
||||||
// New functions
|
// New functions
|
||||||
check::functions(array(staticfunctiontest_static_func,staticfunctiontest_static_func_2,staticfunctiontest_static_func_3));
|
check::functions(array(staticfunctiontest_static_func,staticfunctiontest_static_func_2,staticfunctiontest_static_func_3,is_python_builtin));
|
||||||
// New classes
|
// New classes
|
||||||
check::classes(array(StaticMemberTest,StaticFunctionTest));
|
check::classes(array(StaticMemberTest,StaticFunctionTest,cpp_static,StaticBase,StaticDerived));
|
||||||
// New vars
|
// New vars
|
||||||
check::globals(array(staticmembertest_static_int));
|
check::globals(array(staticmembertest_static_int,staticbase_statty,staticderived_statty));
|
||||||
|
|
||||||
check::done();
|
check::done();
|
||||||
?>
|
?>
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
// Expressions - runtime tests check the type for any necessary type promotions of the expressions
|
// Expressions - runtime tests check the type for any necessary type promotions of the expressions
|
||||||
|
|
||||||
#define INT_AND_BOOL 0xFF & true
|
#define INT_AND_BOOL 0xFF & true
|
||||||
//#define INT_AND_CHAR 0xFF & 'A' /* FIXME compile error */
|
#define INT_AND_CHAR 0xFF & 'A'
|
||||||
#define INT_AND_INT 0xFF & 2
|
#define INT_AND_INT 0xFF & 2
|
||||||
#define INT_AND_UINT 0xFF & 2u
|
#define INT_AND_UINT 0xFF & 2u
|
||||||
#define INT_AND_LONG 0xFF & 2l
|
#define INT_AND_LONG 0xFF & 2l
|
||||||
|
|
@ -60,8 +60,7 @@
|
||||||
#define INT_AND_ULLONG 0xFF & 2ull
|
#define INT_AND_ULLONG 0xFF & 2ull
|
||||||
|
|
||||||
#define BOOL_AND_BOOL true & true // Note integral promotion to type int
|
#define BOOL_AND_BOOL true & true // Note integral promotion to type int
|
||||||
//#define CHAR_AND_CHAR 'A' & 'B' // Note integral promotion to type int
|
#define CHAR_AND_CHAR 'A' & 'B' // Note integral promotion to type int
|
||||||
/* FIXME ABOVE */
|
|
||||||
|
|
||||||
|
|
||||||
#define EXPR_MULTIPLY 0xFF * 2
|
#define EXPR_MULTIPLY 0xFF * 2
|
||||||
|
|
@ -88,6 +87,9 @@
|
||||||
#define EXPR_LOR 0xFF || 1
|
#define EXPR_LOR 0xFF || 1
|
||||||
#define EXPR_CONDITIONAL true ? 2 : 2.2
|
#define EXPR_CONDITIONAL true ? 2 : 2.2
|
||||||
|
|
||||||
|
#define EXPR_CHAR_COMPOUND_ADD 'A' + 12
|
||||||
|
#define EXPR_CHAR_COMPOUND_LSHIFT 'B' << 6
|
||||||
|
#define H_SUPPRESS_SCALING_MAGIC (('s'<<24) | ('u'<<16) | ('p'<<8) | 'p')
|
||||||
|
|
||||||
/// constant assignment in enum
|
/// constant assignment in enum
|
||||||
#if defined(SWIGCSHARP)
|
#if defined(SWIGCSHARP)
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ CPP_TEST_CASES += \
|
||||||
python_docstring \
|
python_docstring \
|
||||||
python_nondynamic \
|
python_nondynamic \
|
||||||
python_overload_simple_cast \
|
python_overload_simple_cast \
|
||||||
|
python_pickle \
|
||||||
python_pythoncode \
|
python_pythoncode \
|
||||||
python_richcompare \
|
python_richcompare \
|
||||||
python_strict_unicode \
|
python_strict_unicode \
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,31 @@ else:
|
||||||
StaticFunctionTest().static_func()
|
StaticFunctionTest().static_func()
|
||||||
StaticFunctionTest().static_func_2(1)
|
StaticFunctionTest().static_func_2(1)
|
||||||
StaticFunctionTest().static_func_3(1, 2)
|
StaticFunctionTest().static_func_3(1, 2)
|
||||||
StaticMemberTest.static_int = 10
|
|
||||||
if not StaticMemberTest.static_int == 10:
|
if is_python_builtin():
|
||||||
raise RuntimeError("static_int not 10")
|
if not StaticMemberTest.static_int == 99: raise RuntimeError("static_int not 99")
|
||||||
|
StaticMemberTest.static_int = 10
|
||||||
|
if not StaticMemberTest.static_int == 10: raise RuntimeError("static_int not 10")
|
||||||
|
|
||||||
|
if not StaticBase.statty == 11: raise RuntimeError("statty not 11")
|
||||||
|
if not StaticDerived.statty == 111: raise RuntimeError("statty not 111")
|
||||||
|
StaticBase.statty = 22
|
||||||
|
StaticDerived.statty = 222
|
||||||
|
if not StaticBase.statty == 22: raise RuntimeError("statty not 22")
|
||||||
|
if not StaticDerived.statty == 222: raise RuntimeError("statty not 222")
|
||||||
|
|
||||||
|
# Restore
|
||||||
|
StaticMemberTest.static_int = 99
|
||||||
|
StaticBase.statty = 11
|
||||||
|
StaticDerived.statty = 111
|
||||||
|
|
||||||
|
if not cvar.StaticMemberTest_static_int == 99: raise RuntimeError("cvar static_int not 99")
|
||||||
|
cvar.StaticMemberTest_static_int = 10
|
||||||
|
if not cvar.StaticMemberTest_static_int == 10: raise RuntimeError("cvar static_int not 10")
|
||||||
|
|
||||||
|
if not cvar.StaticBase_statty == 11: raise RuntimeError("cvar statty not 11")
|
||||||
|
if not cvar.StaticDerived_statty == 111: raise RuntimeError("cvar statty not 111")
|
||||||
|
cvar.StaticBase_statty = 22
|
||||||
|
cvar.StaticDerived_statty = 222
|
||||||
|
if not cvar.StaticBase_statty == 22: raise RuntimeError("cvar statty not 22")
|
||||||
|
if not cvar.StaticDerived_statty == 222: raise RuntimeError("cvar statty not 222")
|
||||||
|
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
from li_boost_array import *
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def failed(a, b, msg):
|
|
||||||
raise RuntimeError, msg + " " + str(list(a)) + " " + str(list(b))
|
|
||||||
|
|
||||||
|
|
||||||
def compare_sequences(a, b):
|
|
||||||
if len(a) != len(b):
|
|
||||||
failed(a, b, "different sizes")
|
|
||||||
for i in range(len(a)):
|
|
||||||
if a[i] != b[i]:
|
|
||||||
failed(a, b, "elements are different")
|
|
||||||
|
|
||||||
def compare_containers(pythonlist, swigarray):
|
|
||||||
compare_sequences(pythonlist, swigarray)
|
|
||||||
|
|
||||||
ps = [0, 1, 2, 3, 4, 5]
|
|
||||||
|
|
||||||
ai = ArrayInt6(ps)
|
|
||||||
|
|
||||||
compare_containers(ps, ai)
|
|
||||||
|
|
||||||
# Modify content
|
|
||||||
for i in range(len(ps)):
|
|
||||||
ps[i] = (ps[i] + 1) * 10
|
|
||||||
ai[i] = (ai[i] + 1) * 10
|
|
||||||
compare_containers(ps, ai)
|
|
||||||
|
|
||||||
# Empty
|
|
||||||
ai = ArrayInt6()
|
|
||||||
compare_containers([0, 0, 0, 0, 0, 0], ai)
|
|
||||||
|
|
||||||
# Check return
|
|
||||||
compare_containers(arrayOutVal(), [-2, -1, 0, 0, 1, 2])
|
|
||||||
compare_containers(arrayOutConstRef(), [-2, -1, 0, 0, 1, 2])
|
|
||||||
#compare_containers(arrayOutRef(), [-2, -1, 0, 0, 1, 2])
|
|
||||||
#compare_containers(arrayOutPtr(), [-2, -1, 0, 0, 1, 2])
|
|
||||||
|
|
||||||
# Check passing arguments
|
|
||||||
ai = arrayInVal([9, 8, 7, 6, 5, 4])
|
|
||||||
compare_containers(ai, [90, 80, 70, 60, 50, 40])
|
|
||||||
|
|
||||||
ai = arrayInConstRef([9, 8, 7, 6, 5, 4])
|
|
||||||
compare_containers(ai, [90, 80, 70, 60, 50, 40])
|
|
||||||
|
|
||||||
#ai = ArrayInt6([9, 8, 7, 6, 5, 4])
|
|
||||||
#arrayInRef(ai)
|
|
||||||
#compare_containers(ai, [90, 80, 70, 60, 50, 40])
|
|
||||||
|
|
||||||
#ai = ArrayInt6([9, 8, 7, 6, 5, 4])
|
|
||||||
#arrayInPtr(ai)
|
|
||||||
#compare_containers(ai, [90, 80, 70, 60, 50, 40])
|
|
||||||
|
|
||||||
35
Examples/test-suite/python/python_pickle_runme.py
Normal file
35
Examples/test-suite/python/python_pickle_runme.py
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
import python_pickle
|
||||||
|
|
||||||
|
import pickle
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def is_new_style_class(cls):
|
||||||
|
return hasattr(cls, "__class__")
|
||||||
|
|
||||||
|
def check(p):
|
||||||
|
msg = p.msg
|
||||||
|
if msg != "hi there":
|
||||||
|
raise RuntimeError("Bad, got: " + msg)
|
||||||
|
|
||||||
|
if not is_new_style_class(python_pickle.PickleMe):
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
python_pickle.cvar.debug = False
|
||||||
|
|
||||||
|
p = python_pickle.PickleMe("hi there")
|
||||||
|
check(p)
|
||||||
|
|
||||||
|
r = p.__reduce__()
|
||||||
|
if python_pickle.cvar.debug:
|
||||||
|
print "__reduce__ returned:", r
|
||||||
|
pickle_string = pickle.dumps(p)
|
||||||
|
newp = pickle.loads(pickle_string)
|
||||||
|
check(newp)
|
||||||
|
|
||||||
|
# Not yet working... some crash and others are not producing a sensible "can't be pickled" error
|
||||||
|
#nfp = python_pickle.NotForPickling("no no")
|
||||||
|
#print nfp.__reduce__()
|
||||||
|
#pickle_string = pickle.dumps(nfp)
|
||||||
|
#print pickle_string
|
||||||
|
#newp = pickle.loads(pickle_string)
|
||||||
|
#print newp.msg
|
||||||
20
Examples/test-suite/python/typemap_documentation_runme.py
Normal file
20
Examples/test-suite/python/typemap_documentation_runme.py
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import typemap_documentation
|
||||||
|
|
||||||
|
f = typemap_documentation.Foo()
|
||||||
|
f.x = 55
|
||||||
|
b = typemap_documentation.Bar()
|
||||||
|
b.y = 44
|
||||||
|
|
||||||
|
if 55 != typemap_documentation.GrabVal(f):
|
||||||
|
raise RuntimeError("bad value")
|
||||||
|
|
||||||
|
try:
|
||||||
|
typemap_documentation.GrabVal(b)
|
||||||
|
raise RuntimeError("unexpected exception")
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if 55 != typemap_documentation.GrabValFooBar(f):
|
||||||
|
raise RuntimeError("bad f value")
|
||||||
|
if 44 != typemap_documentation.GrabValFooBar(b):
|
||||||
|
raise RuntimeError("bad b value")
|
||||||
|
|
@ -2,6 +2,12 @@
|
||||||
|
|
||||||
%module python_builtin
|
%module python_builtin
|
||||||
|
|
||||||
|
%{
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||||
|
#endif
|
||||||
|
%}
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
#ifdef SWIGPYTHON_BUILTIN
|
#ifdef SWIGPYTHON_BUILTIN
|
||||||
bool is_python_builtin() { return true; }
|
bool is_python_builtin() { return true; }
|
||||||
|
|
@ -156,12 +162,12 @@ void Dealloc2Destroyer(PyObject *v) {
|
||||||
%feature("python:slot", "sq_length", functype="lenfunc") SimpleArray::__len__;
|
%feature("python:slot", "sq_length", functype="lenfunc") SimpleArray::__len__;
|
||||||
%inline %{
|
%inline %{
|
||||||
class SimpleArray {
|
class SimpleArray {
|
||||||
size_t size;
|
Py_ssize_t size;
|
||||||
int numbers[5];
|
int numbers[5];
|
||||||
public:
|
public:
|
||||||
SimpleArray(size_t size) : size(size) {
|
SimpleArray(Py_ssize_t size) : size(size) {
|
||||||
for (size_t x = 0; x<size; ++x)
|
for (Py_ssize_t x = 0; x<size; ++x)
|
||||||
numbers[x] = x*10;
|
numbers[x] = (int)x*10;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_ssize_t __len__() {
|
Py_ssize_t __len__() {
|
||||||
|
|
@ -192,7 +198,7 @@ void Dealloc2Destroyer(PyObject *v) {
|
||||||
if (ii > jj)
|
if (ii > jj)
|
||||||
throw std::invalid_argument("getitem i should not be larger than j");
|
throw std::invalid_argument("getitem i should not be larger than j");
|
||||||
SimpleArray n(jj-ii);
|
SimpleArray n(jj-ii);
|
||||||
for (size_t x = 0; x<size; ++x)
|
for (Py_ssize_t x = 0; x<size; ++x)
|
||||||
n.numbers[x] = numbers[x+ii];
|
n.numbers[x] = numbers[x+ii];
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
56
Examples/test-suite/python_pickle.i
Normal file
56
Examples/test-suite/python_pickle.i
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
%module python_pickle
|
||||||
|
|
||||||
|
|
||||||
|
%include <std_string.i>
|
||||||
|
|
||||||
|
%extend PickleMe {
|
||||||
|
#if 0
|
||||||
|
// Note: %pythoncode can't be used with -builtin
|
||||||
|
%pythoncode %{
|
||||||
|
def __reduce__(self):
|
||||||
|
print "In Python __reduce__"
|
||||||
|
return (type(self), (self.msg, ))
|
||||||
|
%}
|
||||||
|
#else
|
||||||
|
// Equivalent to Python code above
|
||||||
|
PyObject *__reduce__() {
|
||||||
|
if (debug)
|
||||||
|
std::cout << "In C++ __reduce__" << std::endl;
|
||||||
|
PyObject *args = PyTuple_New(1);
|
||||||
|
PyTuple_SetItem(args, 0, SWIG_From_std_string(self->msg));
|
||||||
|
|
||||||
|
swig_type_info *ty = SWIGTYPE_p_PickleMe;
|
||||||
|
SwigPyClientData *data = (SwigPyClientData *)ty->clientdata;
|
||||||
|
#if defined(SWIGPYTHON_BUILTIN)
|
||||||
|
PyObject *callable = (PyObject *)data->pytype;
|
||||||
|
#else
|
||||||
|
PyObject *callable = data->klass;
|
||||||
|
#endif
|
||||||
|
Py_INCREF(callable);
|
||||||
|
|
||||||
|
PyObject *ret = PyTuple_New(2);
|
||||||
|
PyTuple_SetItem(ret, 0, callable);
|
||||||
|
PyTuple_SetItem(ret, 1, args);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
bool debug = false;
|
||||||
|
|
||||||
|
struct PickleMe {
|
||||||
|
std::string msg;
|
||||||
|
PickleMe(const std::string& msg) : msg(msg) {
|
||||||
|
if (debug)
|
||||||
|
std::cout << "In C++ constructor " << " [" << msg << "]" << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NotForPickling {
|
||||||
|
std::string msg;
|
||||||
|
NotForPickling(const std::string& msg) : msg(msg) {}
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
argc = PyTuple_Size(varargs);
|
argc = PyTuple_Size(varargs);
|
||||||
if (argc > 10) {
|
if (argc > 10) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Too many arguments");
|
PyErr_SetString(PyExc_ValueError, "Too many arguments");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
PyObject *pyobj = PyTuple_GetItem(varargs, i);
|
PyObject *pyobj = PyTuple_GetItem(varargs, i);
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
PyObject *pystr;
|
PyObject *pystr;
|
||||||
if (!PyUnicode_Check(pyobj)) {
|
if (!PyUnicode_Check(pyobj)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
pystr = PyUnicode_AsUTF8String(pyobj);
|
pystr = PyUnicode_AsUTF8String(pyobj);
|
||||||
str = strdup(PyBytes_AsString(pystr));
|
str = strdup(PyBytes_AsString(pystr));
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
%#else
|
%#else
|
||||||
if (!PyString_Check(pyobj)) {
|
if (!PyString_Check(pyobj)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
str = PyString_AsString(pyobj);
|
str = PyString_AsString(pyobj);
|
||||||
%#endif
|
%#endif
|
||||||
|
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
#!/usr/bin/env ruby
|
|
||||||
#
|
|
||||||
# Put description here
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
require 'swig_assert'
|
|
||||||
|
|
||||||
require 'li_boost_array'
|
|
||||||
|
|
||||||
include Li_boost_array
|
|
||||||
|
|
||||||
|
|
||||||
def failed(a, b, msg)
|
|
||||||
raise RuntimeError, "#{msg} #{a} #{b}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def compare_sequences(a, b)
|
|
||||||
if a.size != b.size
|
|
||||||
failed(a, b, "different sizes")
|
|
||||||
end
|
|
||||||
for i in 0..a.size-1
|
|
||||||
failed(a, b, "elements are different:") if a[i] != b[i]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def compare_containers(rubyarray, swigarray)
|
|
||||||
compare_sequences(rubyarray, swigarray)
|
|
||||||
end
|
|
||||||
|
|
||||||
ps = [0, 1, 2, 3, 4, 5]
|
|
||||||
|
|
||||||
ai = ArrayInt6.new(ps)
|
|
||||||
|
|
||||||
compare_containers(ps, ai)
|
|
||||||
|
|
||||||
# Modify content
|
|
||||||
for i in 0..ps.size-1
|
|
||||||
ps[i] = ps[i] * 10
|
|
||||||
ai[i] = ai[i] * 10
|
|
||||||
end
|
|
||||||
compare_containers(ps, ai)
|
|
||||||
|
|
||||||
# Empty
|
|
||||||
ai = ArrayInt6.new()
|
|
||||||
|
|
||||||
# Check return
|
|
||||||
compare_containers(arrayOutVal(), [-2, -1, 0, 0, 1, 2])
|
|
||||||
compare_containers(arrayOutConstRef(), [-2, -1, 0, 0, 1, 2])
|
|
||||||
#compare_containers(arrayOutRef(), [-2, -1, 0, 0, 1, 2])
|
|
||||||
#compare_containers(arrayOutPtr(), [-2, -1, 0, 0, 1, 2])
|
|
||||||
|
|
||||||
# Check passing arguments
|
|
||||||
ai = arrayInVal([9, 8, 7, 6, 5, 4])
|
|
||||||
compare_containers(ai, [90, 80, 70, 60, 50, 40])
|
|
||||||
|
|
||||||
ai = arrayInConstRef([9, 8, 7, 6, 5, 4])
|
|
||||||
compare_containers(ai, [90, 80, 70, 60, 50, 40])
|
|
||||||
|
|
||||||
#ai = ArrayInt6.new([9, 8, 7, 6, 5, 4])
|
|
||||||
#arrayInRef(ai)
|
|
||||||
#compare_containers(ai, [90, 80, 70, 60, 50, 40])
|
|
||||||
|
|
||||||
#ai = ArrayInt6.new([9, 8, 7, 6, 5, 4])
|
|
||||||
#arrayInPtr(ai)
|
|
||||||
#compare_containers(ai, [90, 80, 70, 60, 50, 40])
|
|
||||||
|
|
||||||
|
|
@ -6,12 +6,12 @@
|
||||||
%inline %{
|
%inline %{
|
||||||
class Base {
|
class Base {
|
||||||
public:
|
public:
|
||||||
void base() {}
|
void baseMethod() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Derived : public Base {
|
class Derived : public Base {
|
||||||
public:
|
public:
|
||||||
void derived() {}
|
void derivedMethod() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|
|
||||||
50
Examples/test-suite/typemap_documentation.i
Normal file
50
Examples/test-suite/typemap_documentation.i
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
%module typemap_documentation
|
||||||
|
|
||||||
|
// A place for checking that documented typemaps are working.
|
||||||
|
// The UTL languages are the only ones that are consistent enough to support these generic typemap functions.
|
||||||
|
// These are in the Typemaps.html chapter.
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
class Foo {
|
||||||
|
public:
|
||||||
|
int x;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Bar {
|
||||||
|
public:
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
#if defined(SWIGUTL)
|
||||||
|
%typemap(in) Foo * {
|
||||||
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 0))) {
|
||||||
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
int GrabVal(Foo *f) {
|
||||||
|
return f->x;
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(SWIGUTL)
|
||||||
|
%typemap(in) Foo * {
|
||||||
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 0))) {
|
||||||
|
Bar *temp;
|
||||||
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &temp, $descriptor(Bar *), 0))) {
|
||||||
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo or Bar");
|
||||||
|
}
|
||||||
|
$1 = (Foo *)temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
int GrabValFooBar(Foo *f) {
|
||||||
|
return f->x;
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
@ -860,7 +860,8 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
|
||||||
global::System.IntPtr ret = $imcall;$excode
|
global::System.IntPtr ret = $imcall;$excode
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
%typemap(csdirectorin) void *VOID_INT_PTR "$iminput"
|
||||||
|
%typemap(csdirectorout) void *VOID_INT_PTR "$cscall"
|
||||||
|
|
||||||
/* Typemaps used for the generation of proxy and type wrapper class code */
|
/* Typemaps used for the generation of proxy and type wrapper class code */
|
||||||
%typemap(csbase) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
|
%typemap(csbase) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
|
||||||
|
|
|
||||||
227
Lib/csharp/std_array.i
Normal file
227
Lib/csharp/std_array.i
Normal file
|
|
@ -0,0 +1,227 @@
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* std_array.i
|
||||||
|
*
|
||||||
|
* SWIG typemaps for std::array<T, N>
|
||||||
|
* C# implementation
|
||||||
|
* The C# wrapper is made to look and feel like a C# System.Collections.Generic.IReadOnlyList<> collection.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
%{
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <stdexcept>
|
||||||
|
%}
|
||||||
|
|
||||||
|
%include <std_common.i>
|
||||||
|
|
||||||
|
|
||||||
|
%define SWIG_STD_ARRAY_INTERNAL(T, N)
|
||||||
|
%typemap(csinterfaces) std::array< T, N > "global::System.IDisposable, global::System.Collections.IEnumerable\n , global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)>\n";
|
||||||
|
%typemap(cscode) std::array< T, N > %{
|
||||||
|
public $csclassname(global::System.Collections.ICollection c) : this() {
|
||||||
|
if (c == null)
|
||||||
|
throw new global::System.ArgumentNullException("c");
|
||||||
|
int end = global::System.Math.Min(this.Count, c.Count);
|
||||||
|
int i = 0;
|
||||||
|
foreach ($typemap(cstype, T) elem in c) {
|
||||||
|
if (i >= end)
|
||||||
|
break;
|
||||||
|
this[i++] = elem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Count {
|
||||||
|
get {
|
||||||
|
return (int)size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public $typemap(cstype, T) this[int index] {
|
||||||
|
get {
|
||||||
|
return getitem(index);
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
setitem(index, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEmpty {
|
||||||
|
get {
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CopyTo($typemap(cstype, T)[] array)
|
||||||
|
{
|
||||||
|
CopyTo(0, array, 0, this.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CopyTo($typemap(cstype, T)[] array, int arrayIndex)
|
||||||
|
{
|
||||||
|
CopyTo(0, array, arrayIndex, this.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CopyTo(int index, $typemap(cstype, T)[] array, int arrayIndex, int count)
|
||||||
|
{
|
||||||
|
if (array == null)
|
||||||
|
throw new global::System.ArgumentNullException("array");
|
||||||
|
if (index < 0)
|
||||||
|
throw new global::System.ArgumentOutOfRangeException("index", "Value is less than zero");
|
||||||
|
if (arrayIndex < 0)
|
||||||
|
throw new global::System.ArgumentOutOfRangeException("arrayIndex", "Value is less than zero");
|
||||||
|
if (count < 0)
|
||||||
|
throw new global::System.ArgumentOutOfRangeException("count", "Value is less than zero");
|
||||||
|
if (array.Rank > 1)
|
||||||
|
throw new global::System.ArgumentException("Multi dimensional array.", "array");
|
||||||
|
if (index+count > this.Count || arrayIndex+count > array.Length)
|
||||||
|
throw new global::System.ArgumentException("Number of elements to copy is too large.");
|
||||||
|
for (int i=0; i<count; i++)
|
||||||
|
array.SetValue(getitemcopy(index+i), arrayIndex+i);
|
||||||
|
}
|
||||||
|
|
||||||
|
global::System.Collections.Generic.IEnumerator<$typemap(cstype, T)> global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)>.GetEnumerator() {
|
||||||
|
return new $csclassnameEnumerator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() {
|
||||||
|
return new $csclassnameEnumerator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public $csclassnameEnumerator GetEnumerator() {
|
||||||
|
return new $csclassnameEnumerator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type-safe enumerator
|
||||||
|
/// Note that the IEnumerator documentation requires an InvalidOperationException to be thrown
|
||||||
|
/// whenever the collection is modified. This has been done for changes in the size of the
|
||||||
|
/// collection but not when one of the elements of the collection is modified as it is a bit
|
||||||
|
/// tricky to detect unmanaged code that modifies the collection under our feet.
|
||||||
|
public sealed class $csclassnameEnumerator : global::System.Collections.IEnumerator
|
||||||
|
, global::System.Collections.Generic.IEnumerator<$typemap(cstype, T)>
|
||||||
|
{
|
||||||
|
private $csclassname collectionRef;
|
||||||
|
private int currentIndex;
|
||||||
|
private object currentObject;
|
||||||
|
private int currentSize;
|
||||||
|
|
||||||
|
public $csclassnameEnumerator($csclassname collection) {
|
||||||
|
collectionRef = collection;
|
||||||
|
currentIndex = -1;
|
||||||
|
currentObject = null;
|
||||||
|
currentSize = collectionRef.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type-safe iterator Current
|
||||||
|
public $typemap(cstype, T) Current {
|
||||||
|
get {
|
||||||
|
if (currentIndex == -1)
|
||||||
|
throw new global::System.InvalidOperationException("Enumeration not started.");
|
||||||
|
if (currentIndex > currentSize - 1)
|
||||||
|
throw new global::System.InvalidOperationException("Enumeration finished.");
|
||||||
|
if (currentObject == null)
|
||||||
|
throw new global::System.InvalidOperationException("Collection modified.");
|
||||||
|
return ($typemap(cstype, T))currentObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type-unsafe IEnumerator.Current
|
||||||
|
object global::System.Collections.IEnumerator.Current {
|
||||||
|
get {
|
||||||
|
return Current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveNext() {
|
||||||
|
int size = collectionRef.Count;
|
||||||
|
bool moveOkay = (currentIndex+1 < size) && (size == currentSize);
|
||||||
|
if (moveOkay) {
|
||||||
|
currentIndex++;
|
||||||
|
currentObject = collectionRef[currentIndex];
|
||||||
|
} else {
|
||||||
|
currentObject = null;
|
||||||
|
}
|
||||||
|
return moveOkay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset() {
|
||||||
|
currentIndex = -1;
|
||||||
|
currentObject = null;
|
||||||
|
if (collectionRef.Count != currentSize) {
|
||||||
|
throw new global::System.InvalidOperationException("Collection modified.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose() {
|
||||||
|
currentIndex = -1;
|
||||||
|
currentObject = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef size_t size_type;
|
||||||
|
typedef ptrdiff_t difference_type;
|
||||||
|
typedef T value_type;
|
||||||
|
typedef value_type* pointer;
|
||||||
|
typedef const value_type* const_pointer;
|
||||||
|
typedef value_type& reference;
|
||||||
|
typedef const value_type& const_reference;
|
||||||
|
|
||||||
|
array();
|
||||||
|
array(const array &other);
|
||||||
|
|
||||||
|
size_type size() const;
|
||||||
|
bool empty() const;
|
||||||
|
|
||||||
|
%rename(Fill) fill;
|
||||||
|
void fill(const value_type& val);
|
||||||
|
|
||||||
|
%rename(Swap) swap;
|
||||||
|
void swap(array& other);
|
||||||
|
|
||||||
|
%extend {
|
||||||
|
T getitemcopy(int index) throw (std::out_of_range) {
|
||||||
|
if (index>=0 && index<(int)$self->size())
|
||||||
|
return (*$self)[index];
|
||||||
|
else
|
||||||
|
throw std::out_of_range("index");
|
||||||
|
}
|
||||||
|
const_reference getitem(int index) throw (std::out_of_range) {
|
||||||
|
if (index>=0 && index<(int)$self->size())
|
||||||
|
return (*$self)[index];
|
||||||
|
else
|
||||||
|
throw std::out_of_range("index");
|
||||||
|
}
|
||||||
|
void setitem(int index, const_reference val) throw (std::out_of_range) {
|
||||||
|
if (index>=0 && index<(int)$self->size())
|
||||||
|
(*$self)[index] = val;
|
||||||
|
else
|
||||||
|
throw std::out_of_range("index");
|
||||||
|
}
|
||||||
|
void Reverse() {
|
||||||
|
std::reverse($self->begin(), $self->end());
|
||||||
|
}
|
||||||
|
void Reverse(int index, int count) throw (std::out_of_range, std::invalid_argument) {
|
||||||
|
if (index < 0)
|
||||||
|
throw std::out_of_range("index");
|
||||||
|
if (count < 0)
|
||||||
|
throw std::out_of_range("count");
|
||||||
|
if (index >= (int)$self->size()+1 || index+count > (int)$self->size())
|
||||||
|
throw std::invalid_argument("invalid range");
|
||||||
|
std::reverse($self->begin()+index, $self->begin()+index+count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
|
||||||
|
%csmethodmodifiers std::array::empty "private"
|
||||||
|
%csmethodmodifiers std::array::getitemcopy "private"
|
||||||
|
%csmethodmodifiers std::array::getitem "private"
|
||||||
|
%csmethodmodifiers std::array::setitem "private"
|
||||||
|
%csmethodmodifiers std::array::size "private"
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template<class T, size_t N> class array {
|
||||||
|
SWIG_STD_ARRAY_INTERNAL(T, N)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -398,4 +398,5 @@ SWIG_STD_VECTOR_ENHANCED(unsigned long long)
|
||||||
SWIG_STD_VECTOR_ENHANCED(float)
|
SWIG_STD_VECTOR_ENHANCED(float)
|
||||||
SWIG_STD_VECTOR_ENHANCED(double)
|
SWIG_STD_VECTOR_ENHANCED(double)
|
||||||
SWIG_STD_VECTOR_ENHANCED(std::string) // also requires a %include <std_string.i>
|
SWIG_STD_VECTOR_ENHANCED(std::string) // also requires a %include <std_string.i>
|
||||||
|
SWIG_STD_VECTOR_ENHANCED(std::wstring) // also requires a %include <std_wstring.i>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,16 +60,15 @@ class wstring;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%typemap(directorin,descriptor="Ljava/lang/String;") wstring %{
|
%typemap(directorin,descriptor="Ljava/lang/String;") wstring %{
|
||||||
{
|
|
||||||
jsize $1_len = $1.length();
|
jsize $1_len = $1.length();
|
||||||
jchar *conv_buf = new jchar[$1_len];
|
jchar *$1_conv_buf = new jchar[$1_len];
|
||||||
for (jsize i = 0; i < $1_len; ++i) {
|
for (jsize i = 0; i < $1_len; ++i) {
|
||||||
conv_buf[i] = (jchar)$1[i];
|
$1_conv_buf[i] = (jchar)$1[i];
|
||||||
}
|
}
|
||||||
$input = jenv->NewString(conv_buf, $1_len);
|
$input = jenv->NewString($1_conv_buf, $1_len);
|
||||||
delete [] conv_buf;
|
Swig::LocalRefGuard $1_refguard(jenv, $input);
|
||||||
}
|
delete [] $1_conv_buf;
|
||||||
Swig::LocalRefGuard $1_refguard(jenv, $input); %}
|
%}
|
||||||
|
|
||||||
%typemap(out) wstring
|
%typemap(out) wstring
|
||||||
%{jsize $1_len = $1.length();
|
%{jsize $1_len = $1.length();
|
||||||
|
|
@ -139,16 +138,15 @@ Swig::LocalRefGuard $1_refguard(jenv, $input); %}
|
||||||
jenv->ReleaseStringChars($input, $1_pstr); %}
|
jenv->ReleaseStringChars($input, $1_pstr); %}
|
||||||
|
|
||||||
%typemap(directorin,descriptor="Ljava/lang/String;") const wstring & %{
|
%typemap(directorin,descriptor="Ljava/lang/String;") const wstring & %{
|
||||||
{
|
|
||||||
jsize $1_len = $1.length();
|
jsize $1_len = $1.length();
|
||||||
jchar *conv_buf = new jchar[$1_len];
|
jchar *$1_conv_buf = new jchar[$1_len];
|
||||||
for (jsize i = 0; i < $1_len; ++i) {
|
for (jsize i = 0; i < $1_len; ++i) {
|
||||||
conv_buf[i] = (jchar)($1)[i];
|
$1_conv_buf[i] = (jchar)($1)[i];
|
||||||
}
|
}
|
||||||
$input = jenv->NewString(conv_buf, $1_len);
|
$input = jenv->NewString($1_conv_buf, $1_len);
|
||||||
delete [] conv_buf;
|
Swig::LocalRefGuard $1_refguard(jenv, $input);
|
||||||
}
|
delete [] $1_conv_buf;
|
||||||
Swig::LocalRefGuard $1_refguard(jenv, $input); %}
|
%}
|
||||||
|
|
||||||
%typemap(out) const wstring &
|
%typemap(out) const wstring &
|
||||||
%{jsize $1_len = $1->length();
|
%{jsize $1_len = $1->length();
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@
|
||||||
* Global variables - add the variable to PHP
|
* Global variables - add the variable to PHP
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
%typemap(varinit) char *,
|
%typemap(varinit) char *
|
||||||
char []
|
|
||||||
{
|
{
|
||||||
zval *z_var;
|
zval *z_var;
|
||||||
MAKE_STD_ZVAL(z_var);
|
MAKE_STD_ZVAL(z_var);
|
||||||
|
|
@ -20,6 +19,16 @@
|
||||||
zend_hash_add(&EG(symbol_table), (char*)"$1", sizeof("$1"), (void *)&z_var, sizeof(zval *), NULL);
|
zend_hash_add(&EG(symbol_table), (char*)"$1", sizeof("$1"), (void *)&z_var, sizeof(zval *), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%typemap(varinit) char []
|
||||||
|
{
|
||||||
|
zval *z_var;
|
||||||
|
MAKE_STD_ZVAL(z_var);
|
||||||
|
z_var->type = IS_STRING;
|
||||||
|
z_var->value.str.val = estrdup($1);
|
||||||
|
z_var->value.str.len = strlen($1);
|
||||||
|
zend_hash_add(&EG(symbol_table), (char*)"$1", sizeof("$1"), (void *)&z_var, sizeof(zval *), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
%typemap(varinit) int,
|
%typemap(varinit) int,
|
||||||
unsigned int,
|
unsigned int,
|
||||||
unsigned short,
|
unsigned short,
|
||||||
|
|
@ -95,10 +104,7 @@
|
||||||
zval *z_var;
|
zval *z_var;
|
||||||
MAKE_STD_ZVAL(z_var);
|
MAKE_STD_ZVAL(z_var);
|
||||||
z_var->type = IS_STRING;
|
z_var->type = IS_STRING;
|
||||||
if ($1) {
|
ZVAL_STRINGL(z_var,(char*)$1, $1_dim0, 1);
|
||||||
/* varinit char [ANY] */
|
|
||||||
ZVAL_STRINGL(z_var,(char*)$1, $1_dim0, 1);
|
|
||||||
}
|
|
||||||
zend_hash_add(&EG(symbol_table), (char*)"$1", sizeof("$1"), (void*)&z_var, sizeof(zval *), NULL);
|
zend_hash_add(&EG(symbol_table), (char*)"$1", sizeof("$1"), (void*)&z_var, sizeof(zval *), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -164,9 +164,13 @@ SwigPyStaticVar_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGINTERN int
|
SWIGINTERN int
|
||||||
SwigPyObjectType_setattro(PyTypeObject *type, PyObject *name, PyObject *value) {
|
SwigPyObjectType_setattro(PyObject *typeobject, PyObject *name, PyObject *value) {
|
||||||
PyObject *attribute;
|
PyObject *attribute;
|
||||||
|
PyTypeObject *type;
|
||||||
descrsetfunc local_set;
|
descrsetfunc local_set;
|
||||||
|
|
||||||
|
assert(PyType_Check(typeobject));
|
||||||
|
type = (PyTypeObject *)typeobject;
|
||||||
attribute = _PyType_Lookup(type, name);
|
attribute = _PyType_Lookup(type, name);
|
||||||
if (attribute != NULL) {
|
if (attribute != NULL) {
|
||||||
/* Implement descriptor functionality, if any */
|
/* Implement descriptor functionality, if any */
|
||||||
|
|
@ -276,6 +280,95 @@ SwigPyStaticVar_Type(void) {
|
||||||
return &staticvar_type;
|
return &staticvar_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWIGINTERN PyTypeObject*
|
||||||
|
SwigPyObjectType(void) {
|
||||||
|
static char swigpyobjecttype_doc[] = "Metaclass for SWIG wrapped types";
|
||||||
|
static PyTypeObject swigpyobjecttype_type;
|
||||||
|
static int type_init = 0;
|
||||||
|
if (!type_init) {
|
||||||
|
const PyTypeObject tmp = {
|
||||||
|
#if PY_VERSION_HEX >= 0x03000000
|
||||||
|
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||||
|
#else
|
||||||
|
PyObject_HEAD_INIT(&PyType_Type)
|
||||||
|
0, /* ob_size */
|
||||||
|
#endif
|
||||||
|
"SwigPyObjectType", /* tp_name */
|
||||||
|
PyType_Type.tp_basicsize, /* tp_basicsize */
|
||||||
|
0, /* tp_itemsize */
|
||||||
|
0, /* tp_dealloc */
|
||||||
|
0, /* tp_print */
|
||||||
|
0, /* tp_getattr */
|
||||||
|
0, /* tp_setattr */
|
||||||
|
0, /* tp_compare */
|
||||||
|
0, /* tp_repr */
|
||||||
|
0, /* tp_as_number */
|
||||||
|
0, /* tp_as_sequence */
|
||||||
|
0, /* tp_as_mapping */
|
||||||
|
0, /* tp_hash */
|
||||||
|
0, /* tp_call */
|
||||||
|
0, /* tp_str */
|
||||||
|
0, /* tp_getattro */
|
||||||
|
SwigPyObjectType_setattro, /* tp_setattro */
|
||||||
|
0, /* tp_as_buffer */
|
||||||
|
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_CLASS, /* tp_flags */
|
||||||
|
swigpyobjecttype_doc, /* tp_doc */
|
||||||
|
0, /* tp_traverse */
|
||||||
|
0, /* tp_clear */
|
||||||
|
0, /* tp_richcompare */
|
||||||
|
0, /* tp_weaklistoffset */
|
||||||
|
0, /* tp_iter */
|
||||||
|
0, /* tp_iternext */
|
||||||
|
0, /* tp_methods */
|
||||||
|
0, /* tp_members */
|
||||||
|
0, /* tp_getset */
|
||||||
|
0, /* tp_base */
|
||||||
|
0, /* tp_dict */
|
||||||
|
0, /* tp_descr_get */
|
||||||
|
0, /* tp_descr_set */
|
||||||
|
0, /* tp_dictoffset */
|
||||||
|
0, /* tp_init */
|
||||||
|
0, /* tp_alloc */
|
||||||
|
0, /* tp_new */
|
||||||
|
0, /* tp_free */
|
||||||
|
0, /* tp_is_gc */
|
||||||
|
0, /* tp_bases */
|
||||||
|
0, /* tp_mro */
|
||||||
|
0, /* tp_cache */
|
||||||
|
0, /* tp_subclasses */
|
||||||
|
0, /* tp_weaklist */
|
||||||
|
#if PY_VERSION_HEX >= 0x02030000
|
||||||
|
0, /* tp_del */
|
||||||
|
#endif
|
||||||
|
#if PY_VERSION_HEX >= 0x02060000
|
||||||
|
0, /* tp_version_tag */
|
||||||
|
#endif
|
||||||
|
#if PY_VERSION_HEX >= 0x03040000
|
||||||
|
0, /* tp_finalize */
|
||||||
|
#endif
|
||||||
|
#ifdef COUNT_ALLOCS
|
||||||
|
0, /* tp_allocs */
|
||||||
|
0, /* tp_frees */
|
||||||
|
0, /* tp_maxalloc */
|
||||||
|
#if PY_VERSION_HEX >= 0x02050000
|
||||||
|
0, /* tp_prev */
|
||||||
|
#endif
|
||||||
|
0 /* tp_next */
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
swigpyobjecttype_type = tmp;
|
||||||
|
type_init = 1;
|
||||||
|
swigpyobjecttype_type.tp_base = &PyType_Type;
|
||||||
|
#if PY_VERSION_HEX < 0x02020000
|
||||||
|
swigpyobjecttype_type.ob_type = &PyType_Type;
|
||||||
|
#else
|
||||||
|
if (PyType_Ready(&swigpyobjecttype_type) < 0)
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return &swigpyobjecttype_type;
|
||||||
|
}
|
||||||
|
|
||||||
SWIGINTERN PyGetSetDescrObject *
|
SWIGINTERN PyGetSetDescrObject *
|
||||||
SwigPyStaticVar_new_getset(PyTypeObject *type, PyGetSetDef *getset) {
|
SwigPyStaticVar_new_getset(PyTypeObject *type, PyGetSetDef *getset) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -374,13 +374,13 @@ SWIG_init(void) {
|
||||||
static PyGetSetDef thisown_getset_def = {
|
static PyGetSetDef thisown_getset_def = {
|
||||||
(char *)"thisown", SwigPyBuiltin_GetterClosure, SwigPyBuiltin_SetterClosure, NULL, &thisown_getset_closure
|
(char *)"thisown", SwigPyBuiltin_GetterClosure, SwigPyBuiltin_SetterClosure, NULL, &thisown_getset_closure
|
||||||
};
|
};
|
||||||
PyObject *metatype_args;
|
|
||||||
PyTypeObject *builtin_pytype;
|
PyTypeObject *builtin_pytype;
|
||||||
int builtin_base_count;
|
int builtin_base_count;
|
||||||
swig_type_info *builtin_basetype;
|
swig_type_info *builtin_basetype;
|
||||||
PyObject *tuple;
|
PyObject *tuple;
|
||||||
PyGetSetDescrObject *static_getset;
|
PyGetSetDescrObject *static_getset;
|
||||||
PyTypeObject *metatype;
|
PyTypeObject *metatype;
|
||||||
|
PyTypeObject *swigpyobject;
|
||||||
SwigPyClientData *cd;
|
SwigPyClientData *cd;
|
||||||
PyObject *public_interface, *public_symbol;
|
PyObject *public_interface, *public_symbol;
|
||||||
PyObject *this_descr;
|
PyObject *this_descr;
|
||||||
|
|
@ -395,14 +395,9 @@ SWIG_init(void) {
|
||||||
(void)static_getset;
|
(void)static_getset;
|
||||||
(void)self;
|
(void)self;
|
||||||
|
|
||||||
/* metatype is used to implement static member variables. */
|
/* Metaclass is used to implement static member variables */
|
||||||
metatype_args = Py_BuildValue("(s(O){})", "SwigPyObjectType", &PyType_Type);
|
metatype = SwigPyObjectType();
|
||||||
assert(metatype_args);
|
|
||||||
metatype = (PyTypeObject *) PyType_Type.tp_call((PyObject *) &PyType_Type, metatype_args, NULL);
|
|
||||||
assert(metatype);
|
assert(metatype);
|
||||||
Py_DECREF(metatype_args);
|
|
||||||
metatype->tp_setattro = (setattrofunc) &SwigPyObjectType_setattro;
|
|
||||||
assert(PyType_Ready(metatype) >= 0);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Fix SwigMethods to carry the callback ptrs when needed */
|
/* Fix SwigMethods to carry the callback ptrs when needed */
|
||||||
|
|
@ -420,13 +415,15 @@ SWIG_init(void) {
|
||||||
SWIG_InitializeModule(0);
|
SWIG_InitializeModule(0);
|
||||||
|
|
||||||
#ifdef SWIGPYTHON_BUILTIN
|
#ifdef SWIGPYTHON_BUILTIN
|
||||||
|
swigpyobject = SwigPyObject_TypeOnce();
|
||||||
|
|
||||||
SwigPyObject_stype = SWIG_MangledTypeQuery("_p_SwigPyObject");
|
SwigPyObject_stype = SWIG_MangledTypeQuery("_p_SwigPyObject");
|
||||||
assert(SwigPyObject_stype);
|
assert(SwigPyObject_stype);
|
||||||
cd = (SwigPyClientData*) SwigPyObject_stype->clientdata;
|
cd = (SwigPyClientData*) SwigPyObject_stype->clientdata;
|
||||||
if (!cd) {
|
if (!cd) {
|
||||||
SwigPyObject_stype->clientdata = &SwigPyObject_clientdata;
|
SwigPyObject_stype->clientdata = &SwigPyObject_clientdata;
|
||||||
SwigPyObject_clientdata.pytype = SwigPyObject_TypeOnce();
|
SwigPyObject_clientdata.pytype = swigpyobject;
|
||||||
} else if (SwigPyObject_TypeOnce()->tp_basicsize != cd->pytype->tp_basicsize) {
|
} else if (swigpyobject->tp_basicsize != cd->pytype->tp_basicsize) {
|
||||||
PyErr_SetString(PyExc_RuntimeError, "Import error: attempted to load two incompatible swig-generated modules.");
|
PyErr_SetString(PyExc_RuntimeError, "Import error: attempted to load two incompatible swig-generated modules.");
|
||||||
# if PY_VERSION_HEX >= 0x03000000
|
# if PY_VERSION_HEX >= 0x03000000
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
|
|
@ -78,4 +78,7 @@ extern "C" {
|
||||||
#define SWIG_WARN_NODE_END(Node) \
|
#define SWIG_WARN_NODE_END(Node) \
|
||||||
if (wrnfilter) Swig_warnfilter(wrnfilter,0); \
|
if (wrnfilter) Swig_warnfilter(wrnfilter,0); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define COMPOUND_EXPR_VAL(dtype) \
|
||||||
|
((dtype).type == T_CHAR || (dtype).type == T_WCHAR ? (dtype).rawval : (dtype).val)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -5828,7 +5828,7 @@ definetype : { /* scanner_check_typedef(); */ } expr {
|
||||||
if ($$.type == T_STRING) {
|
if ($$.type == T_STRING) {
|
||||||
$$.rawval = NewStringf("\"%(escape)s\"",$$.val);
|
$$.rawval = NewStringf("\"%(escape)s\"",$$.val);
|
||||||
} else if ($$.type != T_CHAR && $$.type != T_WSTRING && $$.type != T_WCHAR) {
|
} else if ($$.type != T_CHAR && $$.type != T_WSTRING && $$.type != T_WCHAR) {
|
||||||
$$.rawval = 0;
|
$$.rawval = NewStringf("%s", $$.val);
|
||||||
}
|
}
|
||||||
$$.qualifier = 0;
|
$$.qualifier = 0;
|
||||||
$$.bitfield = 0;
|
$$.bitfield = 0;
|
||||||
|
|
@ -6095,81 +6095,81 @@ exprnum : NUM_INT { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
exprcompound : expr PLUS expr {
|
exprcompound : expr PLUS expr {
|
||||||
$$.val = NewStringf("%s+%s",$1.val,$3.val);
|
$$.val = NewStringf("%s+%s", COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
|
||||||
$$.type = promote($1.type,$3.type);
|
$$.type = promote($1.type,$3.type);
|
||||||
}
|
}
|
||||||
| expr MINUS expr {
|
| expr MINUS expr {
|
||||||
$$.val = NewStringf("%s-%s",$1.val,$3.val);
|
$$.val = NewStringf("%s-%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
|
||||||
$$.type = promote($1.type,$3.type);
|
$$.type = promote($1.type,$3.type);
|
||||||
}
|
}
|
||||||
| expr STAR expr {
|
| expr STAR expr {
|
||||||
$$.val = NewStringf("%s*%s",$1.val,$3.val);
|
$$.val = NewStringf("%s*%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
|
||||||
$$.type = promote($1.type,$3.type);
|
$$.type = promote($1.type,$3.type);
|
||||||
}
|
}
|
||||||
| expr SLASH expr {
|
| expr SLASH expr {
|
||||||
$$.val = NewStringf("%s/%s",$1.val,$3.val);
|
$$.val = NewStringf("%s/%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
|
||||||
$$.type = promote($1.type,$3.type);
|
$$.type = promote($1.type,$3.type);
|
||||||
}
|
}
|
||||||
| expr MODULO expr {
|
| expr MODULO expr {
|
||||||
$$.val = NewStringf("%s%%%s",$1.val,$3.val);
|
$$.val = NewStringf("%s%%%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
|
||||||
$$.type = promote($1.type,$3.type);
|
$$.type = promote($1.type,$3.type);
|
||||||
}
|
}
|
||||||
| expr AND expr {
|
| expr AND expr {
|
||||||
$$.val = NewStringf("%s&%s",$1.val,$3.val);
|
$$.val = NewStringf("%s&%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
|
||||||
$$.type = promote($1.type,$3.type);
|
$$.type = promote($1.type,$3.type);
|
||||||
}
|
}
|
||||||
| expr OR expr {
|
| expr OR expr {
|
||||||
$$.val = NewStringf("%s|%s",$1.val,$3.val);
|
$$.val = NewStringf("%s|%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
|
||||||
$$.type = promote($1.type,$3.type);
|
$$.type = promote($1.type,$3.type);
|
||||||
}
|
}
|
||||||
| expr XOR expr {
|
| expr XOR expr {
|
||||||
$$.val = NewStringf("%s^%s",$1.val,$3.val);
|
$$.val = NewStringf("%s^%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
|
||||||
$$.type = promote($1.type,$3.type);
|
$$.type = promote($1.type,$3.type);
|
||||||
}
|
}
|
||||||
| expr LSHIFT expr {
|
| expr LSHIFT expr {
|
||||||
$$.val = NewStringf("%s << %s",$1.val,$3.val);
|
$$.val = NewStringf("%s << %s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
|
||||||
$$.type = promote_type($1.type);
|
$$.type = promote_type($1.type);
|
||||||
}
|
}
|
||||||
| expr RSHIFT expr {
|
| expr RSHIFT expr {
|
||||||
$$.val = NewStringf("%s >> %s",$1.val,$3.val);
|
$$.val = NewStringf("%s >> %s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
|
||||||
$$.type = promote_type($1.type);
|
$$.type = promote_type($1.type);
|
||||||
}
|
}
|
||||||
| expr LAND expr {
|
| expr LAND expr {
|
||||||
$$.val = NewStringf("%s&&%s",$1.val,$3.val);
|
$$.val = NewStringf("%s&&%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
|
||||||
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
|
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
|
||||||
}
|
}
|
||||||
| expr LOR expr {
|
| expr LOR expr {
|
||||||
$$.val = NewStringf("%s||%s",$1.val,$3.val);
|
$$.val = NewStringf("%s||%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
|
||||||
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
|
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
|
||||||
}
|
}
|
||||||
| expr EQUALTO expr {
|
| expr EQUALTO expr {
|
||||||
$$.val = NewStringf("%s==%s",$1.val,$3.val);
|
$$.val = NewStringf("%s==%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
|
||||||
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
|
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
|
||||||
}
|
}
|
||||||
| expr NOTEQUALTO expr {
|
| expr NOTEQUALTO expr {
|
||||||
$$.val = NewStringf("%s!=%s",$1.val,$3.val);
|
$$.val = NewStringf("%s!=%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
|
||||||
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
|
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
|
||||||
}
|
}
|
||||||
/* Sadly this causes 2 reduce-reduce conflicts with templates. FIXME resolve these.
|
/* Sadly this causes 2 reduce-reduce conflicts with templates. FIXME resolve these.
|
||||||
| expr GREATERTHAN expr {
|
| expr GREATERTHAN expr {
|
||||||
$$.val = NewStringf("%s > %s", $1.val, $3.val);
|
$$.val = NewStringf("%s > %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
|
||||||
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
|
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
|
||||||
}
|
}
|
||||||
| expr LESSTHAN expr {
|
| expr LESSTHAN expr {
|
||||||
$$.val = NewStringf("%s < %s", $1.val, $3.val);
|
$$.val = NewStringf("%s < %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
|
||||||
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
|
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
| expr GREATERTHANOREQUALTO expr {
|
| expr GREATERTHANOREQUALTO expr {
|
||||||
$$.val = NewStringf("%s >= %s", $1.val, $3.val);
|
$$.val = NewStringf("%s >= %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
|
||||||
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
|
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
|
||||||
}
|
}
|
||||||
| expr LESSTHANOREQUALTO expr {
|
| expr LESSTHANOREQUALTO expr {
|
||||||
$$.val = NewStringf("%s <= %s", $1.val, $3.val);
|
$$.val = NewStringf("%s <= %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
|
||||||
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
|
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
|
||||||
}
|
}
|
||||||
| expr QUESTIONMARK expr COLON expr %prec QUESTIONMARK {
|
| expr QUESTIONMARK expr COLON expr %prec QUESTIONMARK {
|
||||||
$$.val = NewStringf("%s?%s:%s", $1.val, $3.val, $5.val);
|
$$.val = NewStringf("%s?%s:%s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3), COMPOUND_EXPR_VAL($5));
|
||||||
/* This may not be exactly right, but is probably good enough
|
/* This may not be exactly right, but is probably good enough
|
||||||
* for the purposes of parsing constant expressions. */
|
* for the purposes of parsing constant expressions. */
|
||||||
$$.type = promote($3.type, $5.type);
|
$$.type = promote($3.type, $5.type);
|
||||||
|
|
@ -6187,7 +6187,7 @@ exprcompound : expr PLUS expr {
|
||||||
$$.type = $2.type;
|
$$.type = $2.type;
|
||||||
}
|
}
|
||||||
| LNOT expr {
|
| LNOT expr {
|
||||||
$$.val = NewStringf("!%s",$2.val);
|
$$.val = NewStringf("!%s",COMPOUND_EXPR_VAL($2));
|
||||||
$$.type = T_INT;
|
$$.type = T_INT;
|
||||||
}
|
}
|
||||||
| type LPAREN {
|
| type LPAREN {
|
||||||
|
|
|
||||||
|
|
@ -2809,29 +2809,39 @@ private:
|
||||||
String *get = NewString("");
|
String *get = NewString("");
|
||||||
Printv(get, Swig_cresult_name(), " = ", NULL);
|
Printv(get, Swig_cresult_name(), " = ", NULL);
|
||||||
|
|
||||||
char quote;
|
String *rawval = Getattr(n, "rawval");
|
||||||
if (Getattr(n, "wrappedasconstant")) {
|
if (rawval && Len(rawval)) {
|
||||||
quote = '\0';
|
if (SwigType_type(type) == T_STRING) {
|
||||||
} else if (SwigType_type(type) == T_CHAR) {
|
Printv(get, "(char *)", NULL);
|
||||||
quote = '\'';
|
}
|
||||||
} else if (SwigType_type(type) == T_STRING) {
|
|
||||||
Printv(get, "(char *)", NULL);
|
Printv(get, rawval, NULL);
|
||||||
quote = '"';
|
|
||||||
} else {
|
} else {
|
||||||
quote = '\0';
|
char quote;
|
||||||
}
|
if (Getattr(n, "wrappedasconstant")) {
|
||||||
|
quote = '\0';
|
||||||
|
} else if (SwigType_type(type) == T_CHAR) {
|
||||||
|
quote = '\'';
|
||||||
|
} else if (SwigType_type(type) == T_STRING) {
|
||||||
|
Printv(get, "(char *)", NULL);
|
||||||
|
quote = '"';
|
||||||
|
} else {
|
||||||
|
quote = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
if (quote != '\0') {
|
if (quote != '\0') {
|
||||||
Printf(get, "%c", quote);
|
Printf(get, "%c", quote);
|
||||||
}
|
}
|
||||||
|
|
||||||
Printv(get, Getattr(n, "value"), NULL);
|
Printv(get, Getattr(n, "value"), NULL);
|
||||||
|
|
||||||
if (quote != '\0') {
|
if (quote != '\0') {
|
||||||
Printf(get, "%c", quote);
|
Printf(get, "%c", quote);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Printv(get, ";\n", NULL);
|
Printv(get, ";\n", NULL);
|
||||||
|
|
||||||
Setattr(n, "wrap:action", get);
|
Setattr(n, "wrap:action", get);
|
||||||
|
|
||||||
String *sname = Copy(symname);
|
String *sname = Copy(symname);
|
||||||
|
|
|
||||||
|
|
@ -3339,6 +3339,8 @@ public:
|
||||||
Printf(builtin_closures_code, "%s /* defines %s */\n\n", closure_decl, closure_name);
|
Printf(builtin_closures_code, "%s /* defines %s */\n\n", closure_decl, closure_name);
|
||||||
SetFlag(builtin_closures, closure_name);
|
SetFlag(builtin_closures, closure_name);
|
||||||
Delete(closure_decl);
|
Delete(closure_decl);
|
||||||
|
} else {
|
||||||
|
closure_name = Copy(wrapper_name);
|
||||||
}
|
}
|
||||||
if (func_type) {
|
if (func_type) {
|
||||||
String *s = NewStringf("(%s) %s", func_type, closure_name);
|
String *s = NewStringf("(%s) %s", func_type, closure_name);
|
||||||
|
|
@ -3923,8 +3925,14 @@ public:
|
||||||
String *pmname = SwigType_manglestr(pname);
|
String *pmname = SwigType_manglestr(pname);
|
||||||
String *templ = NewStringf("SwigPyBuiltin_%s", mname);
|
String *templ = NewStringf("SwigPyBuiltin_%s", mname);
|
||||||
int funpack = modernargs && fastunpack;
|
int funpack = modernargs && fastunpack;
|
||||||
|
static String *tp_new = NewString("PyType_GenericNew");
|
||||||
|
|
||||||
Printv(f_init, " SwigPyBuiltin_SetMetaType(builtin_pytype, metatype);\n", NIL);
|
Printv(f_init, " SwigPyBuiltin_SetMetaType(builtin_pytype, metatype);\n", NIL);
|
||||||
|
|
||||||
|
// We can’t statically initialize a structure member with a function defined in another C module
|
||||||
|
// So this is done in the initialization function instead, see https://docs.python.org/2/extending/newtypes.html
|
||||||
|
Printf(f_init, " builtin_pytype->tp_new = %s;\n", getSlot(n, "feature:python:tp_new", tp_new));
|
||||||
|
|
||||||
Printv(f_init, " builtin_base_count = 0;\n", NIL);
|
Printv(f_init, " builtin_base_count = 0;\n", NIL);
|
||||||
List *baselist = Getattr(n, "bases");
|
List *baselist = Getattr(n, "bases");
|
||||||
if (baselist) {
|
if (baselist) {
|
||||||
|
|
@ -4062,7 +4070,6 @@ public:
|
||||||
|
|
||||||
static String *tp_basicsize = NewStringf("sizeof(SwigPyObject)");
|
static String *tp_basicsize = NewStringf("sizeof(SwigPyObject)");
|
||||||
static String *tp_dictoffset_default = NewString("offsetof(SwigPyObject, dict)");
|
static String *tp_dictoffset_default = NewString("offsetof(SwigPyObject, dict)");
|
||||||
static String *tp_new = NewString("PyType_GenericNew");
|
|
||||||
static String *tp_hash = NewString("SwigPyObject_hash");
|
static String *tp_hash = NewString("SwigPyObject_hash");
|
||||||
String *tp_as_number = NewStringf("&%s_type.as_number", templ);
|
String *tp_as_number = NewStringf("&%s_type.as_number", templ);
|
||||||
String *tp_as_sequence = NewStringf("&%s_type.as_sequence", templ);
|
String *tp_as_sequence = NewStringf("&%s_type.as_sequence", templ);
|
||||||
|
|
@ -4123,7 +4130,7 @@ public:
|
||||||
printSlot(f, getSlot(n, "feature:python:tp_dictoffset", tp_dictoffset_default), "tp_dictoffset", "Py_ssize_t");
|
printSlot(f, getSlot(n, "feature:python:tp_dictoffset", tp_dictoffset_default), "tp_dictoffset", "Py_ssize_t");
|
||||||
printSlot(f, getSlot(n, "feature:python:tp_init", tp_init), "tp_init", "initproc");
|
printSlot(f, getSlot(n, "feature:python:tp_init", tp_init), "tp_init", "initproc");
|
||||||
printSlot(f, getSlot(n, "feature:python:tp_alloc"), "tp_alloc", "allocfunc");
|
printSlot(f, getSlot(n, "feature:python:tp_alloc"), "tp_alloc", "allocfunc");
|
||||||
printSlot(f, getSlot(n, "feature:python:tp_new", tp_new), "tp_new", "newfunc");
|
printSlot(f, getSlot(), "tp_new", "newfunc");
|
||||||
printSlot(f, getSlot(n, "feature:python:tp_free"), "tp_free", "freefunc");
|
printSlot(f, getSlot(n, "feature:python:tp_free"), "tp_free", "freefunc");
|
||||||
printSlot(f, getSlot(n, "feature:python:tp_is_gc"), "tp_is_gc", "inquiry");
|
printSlot(f, getSlot(n, "feature:python:tp_is_gc"), "tp_is_gc", "inquiry");
|
||||||
printSlot(f, getSlot(n, "feature:python:tp_bases"), "tp_bases", "PyObject *");
|
printSlot(f, getSlot(n, "feature:python:tp_bases"), "tp_bases", "PyObject *");
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -e # exit on failure
|
set -e # exit on failure (same as -o errexit)
|
||||||
|
|
||||||
lsb_release -a
|
lsb_release -a
|
||||||
sudo apt-get -qq update
|
sudo apt-get -qq update
|
||||||
|
|
@ -51,7 +51,7 @@ case "$SWIGLANG" in
|
||||||
;;
|
;;
|
||||||
"lua")
|
"lua")
|
||||||
if [[ -z "$VER" ]]; then
|
if [[ -z "$VER" ]]; then
|
||||||
sudo apt-get -qq install lua5.1 liblua5.1-dev
|
sudo apt-get -qq install lua5.2 liblua5.2-dev
|
||||||
else
|
else
|
||||||
sudo add-apt-repository -y ppa:ubuntu-cloud-archive/mitaka-staging
|
sudo add-apt-repository -y ppa:ubuntu-cloud-archive/mitaka-staging
|
||||||
sudo apt-get -qq update
|
sudo apt-get -qq update
|
||||||
|
|
@ -72,16 +72,10 @@ case "$SWIGLANG" in
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
"php")
|
"php")
|
||||||
sudo apt-get install php5-cli php5-dev
|
sudo apt-get -qq install php5-cli php5-dev
|
||||||
;;
|
;;
|
||||||
"python")
|
"python")
|
||||||
git clone https://github.com/jcrocholl/pep8.git
|
sudo apt-get -qq install pep8
|
||||||
(
|
|
||||||
cd pep8
|
|
||||||
git checkout tags/1.5.7
|
|
||||||
python ./setup.py build
|
|
||||||
sudo python ./setup.py install
|
|
||||||
)
|
|
||||||
if [[ "$PY3" ]]; then
|
if [[ "$PY3" ]]; then
|
||||||
sudo apt-get install -qq python3-dev
|
sudo apt-get install -qq python3-dev
|
||||||
fi
|
fi
|
||||||
|
|
@ -105,6 +99,8 @@ case "$SWIGLANG" in
|
||||||
sudo apt-get -qq install scilab
|
sudo apt-get -qq install scilab
|
||||||
;;
|
;;
|
||||||
"tcl")
|
"tcl")
|
||||||
sudo apt-get -qq install tcl8.4-dev
|
sudo apt-get -qq install tcl-dev
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
set +e # turn off exit on failure (same as +o errexit)
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -e # exit on failure
|
set -e # exit on failure (same as -o errexit)
|
||||||
|
|
||||||
sw_vers
|
sw_vers
|
||||||
brew update
|
brew update
|
||||||
brew list
|
brew list
|
||||||
brew install pcre
|
# brew install pcre # Travis Xcode-7.3 has pcre
|
||||||
# brew install boost
|
# brew install boost
|
||||||
|
|
||||||
WITHLANG=$SWIGLANG
|
WITHLANG=$SWIGLANG
|
||||||
|
|
||||||
case "$SWIGLANG" in
|
case "$SWIGLANG" in
|
||||||
"csharp")
|
"csharp")
|
||||||
brew install https://s3.amazonaws.com/travisbuilds.swig.org/mono.rb
|
brew install mono
|
||||||
;;
|
;;
|
||||||
"guile")
|
"guile")
|
||||||
Tools/brew-install guile
|
Tools/brew-install guile
|
||||||
|
|
@ -28,3 +28,6 @@ case "$SWIGLANG" in
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# Workaround for https://github.com/travis-ci/travis-ci/issues/6522
|
||||||
|
set +e # turn off exit on failure (same as +o errexit)
|
||||||
|
|
|
||||||
10
appveyor.yml
10
appveyor.yml
|
|
@ -5,16 +5,16 @@ platform:
|
||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
- SWIGLANG: csharp
|
- SWIGLANG: csharp
|
||||||
VSVER: 14
|
VSVER: 12
|
||||||
- SWIGLANG: csharp
|
- SWIGLANG: csharp
|
||||||
VSVER: 12
|
VSVER: 14
|
||||||
- SWIGLANG: java
|
- SWIGLANG: java
|
||||||
VSVER: 12
|
VSVER: 14
|
||||||
- SWIGLANG: python
|
- SWIGLANG: python
|
||||||
VSVER: 12
|
VSVER: 14
|
||||||
VER: 27
|
VER: 27
|
||||||
- SWIGLANG: python
|
- SWIGLANG: python
|
||||||
VSVER: 12
|
VSVER: 14
|
||||||
VER: 35
|
VER: 35
|
||||||
PY3: 1
|
PY3: 1
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue