Merge branch 'master' into directorargout_and_java_typemaps

This commit is contained in:
Andrey Starodubtsev 2016-11-02 18:12:38 +03:00
commit 3e449ea05f
68 changed files with 2861 additions and 2151 deletions

View file

@ -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

View file

@ -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.

View file

@ -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-&gt;x + A-&gt;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&gt;
<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 */
&lt;local-declaration&gt; &lt;local-declaration&gt;
... results; /* return value from function call */ ... results; /* return value from function call */
&lt;binding locals to parameters&gt; &lt;binding locals to parameters&gt;
try { try {
result = function-name(local0, local1, ..., localN); result = function-name(local0, local1, ..., localN);
&lt;convert and bind result to lresult&gt; &lt;convert and bind result to lresult&gt;
return lresult; return lresult;
catch (...) { catch (...) {
return (int)0; return (int)0;
} }
</pre> </pre>
</div> </div>

View file

@ -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 &lt;typename... BaseClasses&gt; class ClassName : public BaseClasses... { template &lt;typename... BaseClasses&gt; class ClassName : public BaseClasses... {
public: public:
ClassName (BaseClasses &amp;&amp;... baseClasses) : BaseClasses(baseClasses)... {} ClassName (BaseClasses &amp;&amp;... 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>

View file

@ -1021,18 +1021,18 @@ 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 &lt; 0) { if (arg1 &lt; 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>
</div> </div>
@ -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) { } catch (std::out_of_range e) {
SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, e.what()); SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, e.what());
return ; 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 &amp;_e) {
{
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentException, (&amp;_e)-&gt;what(), NULL);
return ;
} }
catch(std::out_of_range &amp;_e) { }
{
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentException, (&amp;_e)-&gt;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 &amp;b, bool flag); virtual void BaseBoolMethod(Base const &amp;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(&amp;element); container.setElement(&amp;element);
cout &lt;&lt; "element.value: " &lt;&lt; container.getElement()-&gt;value &lt;&lt; endl; cout &lt;&lt; "element.value: " &lt;&lt; container.getElement()-&gt;value &lt;&lt; endl;
</pre> </pre>
</div> </div>

View file

@ -51,9 +51,9 @@ is a simple example:
<pre> <pre>
%contract sqrt(double x) { %contract sqrt(double x) {
require: require:
x &gt;= 0; x &gt;= 0;
ensure: ensure:
sqrt &gt;= 0; sqrt &gt;= 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 &gt; 0; x &gt; 0;
ensure: ensure:
bar &gt; 0; bar &gt; 0;
} }
%contract Foo::Foo(int a) { %contract Foo::Foo(int a) {
require: require:
a &gt; 0; a &gt; 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 &gt; 0; x &gt; 0;
} }
%contract Spam::bar(int, int y) { %contract Spam::bar(int, int y) {
require: require:
y &gt; 0; y &gt; 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

View file

@ -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>

View file

@ -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);

View file

@ -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 &lt; 10; i++) { for (i = 0; i &lt; 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

View file

@ -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(&amp;argc, &amp;argv); gtk_init(&amp;argc, &amp;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, &amp;exampleModule); example_initialize(context, &amp;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>

View file

@ -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 &lt; 10; i++) { for (i = 0; i &lt; 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&lt;int&gt;; %template(vectori) vector&lt;int&gt;;
%template(vectord) vector&lt;double&gt;; %template(vectord) vector&lt;double&gt;;
}; };
</pre> </pre>
</div> </div>
@ -1554,19 +1554,19 @@ To illustrate the use of this library, consider the following functions:
#include &lt;numeric&gt; #include &lt;numeric&gt;
double average(std::vector&lt;int&gt; v) { double average(std::vector&lt;int&gt; 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&lt;double&gt; half(const std::vector&lt;double&gt;&amp; v) { std::vector&lt;double&gt; half(const std::vector&lt;double&gt;&amp; v) {
std::vector&lt;double&gt; w(v); std::vector&lt;double&gt; w(v);
for (unsigned int i=0; i&lt;w.size(); i++) for (unsigned int i=0; i&lt;w.size(); i++)
w[i] /= 2.0; w[i] /= 2.0;
return w; return w;
} }
void halve_in_place(std::vector&lt;double&gt;&amp; v) { void halve_in_place(std::vector&lt;double&gt;&amp; v) {
std::transform(v.begin(),v.end(),v.begin(), std::transform(v.begin(),v.end(),v.begin(),
std::bind2nd(std::divides&lt;double&gt;(),2.0)); std::bind2nd(std::divides&lt;double&gt;(),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&lt;int&gt;; %template(IntVector) vector&lt;int&gt;;
%template(DoubleVector) vector&lt;double&gt;; %template(DoubleVector) vector&lt;double&gt;;
} }
// 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&lt;int&gt;; %template(IntVector) vector&lt;int&gt;;
} }
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&amp; e) { } catch (std::out_of_range&amp; e) {
SWIG_exception(SWIG_IndexError,const_cast&lt;char*&gt;(e.what())); SWIG_exception(SWIG_IndexError,const_cast&lt;char*&gt;(e.what()));
} }
} }
</pre> </pre>
</div> </div>

View file

@ -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&amp; v) const {return Test (x+v.x);} Test operator+ (const Test&amp; v) const {return Test (x+v.x);}
// length squared // length squared
float lengthSquared (void) const {return this-&gt;dot (*this);} float lengthSquared (void) const {return this-&gt;dot (*this);}
static float distance (const Test&amp; a, const Test&amp; b){return(a-b).length();} static float distance (const Test&amp; a, const Test&amp; b){return(a-b).length();}
inline Test parallelComponent (const Test&amp; unitBasis) const { inline Test parallelComponent (const Test&amp; unitBasis) const {
return unitBasis * projection; return unitBasis * projection;
} }
Test setYtoZero (void) const {return Test (this-&gt;x);} Test setYtoZero (void) const {return Test (this-&gt;x);}
static const Test zero; static const Test zero;
}; };
inline Test operator* (float s, const Test&amp; v) {return v*s;}
inline Test operator* (float s, const Test&amp; v) {return v*s;} inline std::ostream&amp; operator&lt;&lt; (std::ostream&amp; o, const Test&amp; v)
{
return o &lt;&lt; "(" &lt;&lt; v.x &lt;&lt; ")";
}
inline Test RandomUnitVectorOnXZPlane (void)
inline std::ostream&amp; operator&lt;&lt; (std::ostream&amp; o, const Test&amp; v) {
{ return RandomVectorInUnitRadiusSphere().setYtoZero().normalize();
return o &lt;&lt; "(" &lt;&lt; v.x &lt;&lt; ")"; }
}
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

View file

@ -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;
}; };
&gt; --From eLua &gt; --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 &amp;); Foo(const Foo &amp;);
... ...
}; };
</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-&gt;re(),$self-&gt;im()); sprintf(tmp,"Complex(%g,%g)", $self-&gt;re(),$self-&gt;im());
return tmp; return tmp;
} }
bool operator==(const Complex&amp; c) bool operator==(const Complex&amp; c) {
{ return ($self-&gt;re()==c.re() &amp;&amp; $self-&gt;im()==c.im());} return ($self-&gt;re()==c.re() &amp;&amp; $self-&gt;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&lt;class T1, class T2&gt; template&lt;class T1, class T2&gt;
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&amp;, const T2&amp;); pair(const T1&amp;, const T2&amp;);
~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-&gt;() 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-&gt;() like this:
</p> </p>
<div class="code"><pre>template&lt;class T&gt; class SmartPtr { <div class="code"><pre>template&lt;class T&gt; class SmartPtr {
... ...
T *operator-&gt;(); T *operator-&gt;();
... ...
} }
</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 &lt;typemaps.i&gt;, 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 &lt;typemaps.i&gt;, 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>

View file

@ -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 = &amp;temp; $1 = &amp;temp;
} }
%enddef %enddef

View file

@ -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 &lt;file.h&gt; interface: C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Given a wrapping of the &lt;file.h&gt; interface:
C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Given a wrapping of the &lt;file.h&gt; interface: C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Given a wrapping of the &lt;file.h&gt; 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&lt;class __scalar&gt; template&lt;class __scalar&gt;
__scalar mul(__scalar a,__scalar b) { __scalar mul(__scalar a,__scalar b) {
return a*b; return a*b;
} }
} }
%include &lt;std_complex.i&gt; %include &lt;std_complex.i&gt;
%template(mul) mul&lt;std::complex&lt;double&gt; &gt; %template(mul) mul&lt;std::complex&lt;double&gt; &gt;

View file

@ -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&lt;Foo*&gt;(b); return dynamic_cast&lt;Foo*&gt;(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 &lt; len ; i++) { for (i = 0; i &lt; 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 &amp;values[0]; return &amp;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 &lt; $1_dim0; i++) { for (i = 0; i &lt; $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 **) &amp;f, SWIGTYPE_p_Foo, 0) == -1) return NULL; if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;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 **) &amp;$1, $1_descriptor,0)) == -1) return NULL; if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;$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 **) &amp;$1, $descriptor(Foo *), 0)) == -1) return NULL; if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;$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>

View file

@ -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>

View file

@ -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>

View file

@ -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&lt;Foo*&gt;(b); return dynamic_cast&lt;Foo*&gt;(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&lt;class T1, class T2&gt; template&lt;class T1, class T2&gt;
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&amp;, const T2&amp;); pair(const T1&amp;, const T2&amp;);
~pair(); ~pair();
}; };
%template(pairii) pair&lt;int,int&gt;; %template(pairii) pair&lt;int,int&gt;;
@ -2037,9 +2036,9 @@ that implements <tt>operator-&gt;()</tt> like this:
<div class="code"> <div class="code">
<pre> <pre>
template&lt;class T&gt; class SmartPtr { template&lt;class T&gt; class SmartPtr {
... ...
T *operator-&gt;(); T *operator-&gt;();
... ...
} }
</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-&gt;x,$self-&gt;y,$self-&gt;z); sprintf(tmp,"Vector(%g,%g,%g)", $self-&gt;x,$self-&gt;y,$self-&gt;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-&gt;x = x; v-&gt;x = x;
v-&gt;y = y; v-&gt;y = y;
v-&gt;z = z; v-&gt;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-&gt;x + other-&gt;x; v.x = $self-&gt;x + other-&gt;x;
v.y = $self-&gt;y + other-&gt;y; v.y = $self-&gt;y + other-&gt;y;
v.z = $self-&gt;z + other-&gt;z; v.z = $self-&gt;z + other-&gt;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 &amp;e) { } catch (std::out_of_range &amp;e) {
PyErr_SetString(PyExc_IndexError, const_cast&lt;char*&gt;(e.what())); PyErr_SetString(PyExc_IndexError, const_cast&lt;char*&gt;(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 &lt; 0) { if ($1 &lt; 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 &lt; size; i++) { for (i = 0; i &lt; 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 &lt; $1; i++) { for (i = 0; i &lt; $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 = &amp;temp; $1 = &amp;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 = &amp;temp[0]; $1 = &amp;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 &lt; $1_dim0; i++) { for (i =0; i &lt; $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 = &amp;temp[0]; $1 = &amp;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 &lt; size; i++) { for (i =0; i &lt; 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 = &amp;temp[0]; $1 = &amp;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 **) &amp;f, SWIGTYPE_p_Foo, SWIG_POINTER_EXCEPTION) == -1) if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;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 **) &amp;$1, $1_descriptor,SWIG_POINTER_EXCEPTION)) == -1) if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;$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 **) &amp;$1, $descriptor(Foo *), if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;$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) -&gt; bool function_name(x, y, foo=None, bar=None) -&gt; bool
Parameters Parameters

View file

@ -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 &amp;b-&gt;f; return &amp;b-&gt;f;
} }
void Bar_f_set(Bar *b, Foo *value) { void Bar_f_set(Bar *b, Foo *value) {
b-&gt;f = *value; b-&gt;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-&gt;x; return v-&gt;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 ",&amp;arg0, if (SWIG_GetArgs(interp, objc, objv,"p:Vector_x_get self ",&amp;arg0,
SWIGTYPE_p_Vector) == TCL_ERROR) SWIGTYPE_p_Vector) == TCL_ERROR)
return TCL_ERROR; return TCL_ERROR;
result = (double ) (arg1-&gt;x); result = (double ) (arg1-&gt;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

View file

@ -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>

View file

@ -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&lt;Foo*&gt;(b); return dynamic_cast&lt;Foo*&gt;(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&lt;class T1, class T2&gt; template&lt;class T1, class T2&gt;
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&amp;, const T2&amp;); pair(const T1&amp;, const T2&amp;);
~pair(); ~pair();
}; };
@ -1776,9 +1775,9 @@ that implements <tt>operator-&gt;()</tt> like this:
<div class="code"> <div class="code">
<pre> <pre>
template&lt;class T&gt; class SmartPtr { template&lt;class T&gt; class SmartPtr {
... ...
T *operator-&gt;(); T *operator-&gt;();
... ...
} }
</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, &amp;nitems, &amp;listobjv) == TCL_ERROR) { if (Tcl_ListObjGetElements(interp, $input, &amp;nitems, &amp;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 &lt; nitems; i++) { for (i = 0; i &lt; 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 = &amp;temp; $1 = &amp;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 &lt; 0) || (b &lt; 0)) return -1; if ((a &lt; 0) || (b &lt; 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, &amp;temp) == TCL_ERROR) if (Tcl_GetDoubleFromObj(interp, $input, &amp;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, &amp;len); $1 = Tcl_GetStringFromObj(interp, &amp;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 **) &amp;f, SWIGTYPE_p_Foo, 0) == -1) return NULL; if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;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 **) &amp;$1, $1_descriptor,0)) == -1) return NULL; if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;$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 **) &amp;$1, $descriptor(Foo *), 0)) == -1) return NULL; if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;$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

View file

@ -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 &gt; 10) { if (argc &gt; 10) {
PyErr_SetString(PyExc_ValueError, "Too many arguments"); PyErr_SetString(PyExc_ValueError, "Too many arguments");
return NULL; SWIG_fail;
} }
for (i = 0; i &lt; argc; i++) { for (i = 0; i &lt; argc; i++) {
PyObject *pyobj = PyTuple_GetItem(varargs, i); PyObject *pyobj = PyTuple_GetItem(varargs, i);
@ -525,16 +525,16 @@ like this:
%#if PY_VERSION_HEX&gt;=0x03000000 %#if PY_VERSION_HEX&gt;=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 &lt; argc; i++) { for (i = 0; i &lt; 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:
&amp;ffi_type_uint, types) == FFI_OK) { &amp;ffi_type_uint, types) == FFI_OK) {
ffi_call(&amp;cif, (void (*)()) execlp, &amp;result, values); ffi_call(&amp;cif, (void (*)()) execlp, &amp;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
&amp;ffi_type_uint, types) == FFI_OK) { &amp;ffi_type_uint, types) == FFI_OK) {
ffi_call(&amp;cif, (void (*)()) printf, &amp;result, values); ffi_call(&amp;cif, (void (*)()) printf, &amp;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-&gt;bar(arg2, arg3, etc.); result = arg1-&gt;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

View file

@ -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>

View file

@ -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);

View file

@ -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);

View file

@ -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 \

View file

@ -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>

View file

@ -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
%} %}

View 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)
{
}
}
}

View 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();
}
}

View file

@ -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");
} }
} }
} }

View 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;
}
};
%}

View file

@ -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; }
} }

View file

@ -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

View file

@ -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();
} }
} }

View file

@ -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

View file

@ -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

View file

@ -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();
?> ?>

View file

@ -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)

View file

@ -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 \

View file

@ -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")

View file

@ -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])

View 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

View 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")

View file

@ -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;
} }

View 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) {}
};
%}

View file

@ -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

View file

@ -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])

View file

@ -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>

View 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;
}
%}

View file

@ -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
View 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)
};
}

View file

@ -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>

View file

@ -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();

View file

@ -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);
} }

View file

@ -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) {

View file

@ -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;

View file

@ -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

View file

@ -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 {

View file

@ -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);

View file

@ -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 *");

View file

@ -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)

View file

@ -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)

View file

@ -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