Merge from trunk

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2009-sploving@12733 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Sylvestre Ledru 2011-06-03 20:35:55 +00:00
commit e48855bfbf
60 changed files with 1099 additions and 545 deletions

View file

@ -1,8 +1,8 @@
*** ANNOUNCE: SWIG 2.0.4 (29 March 2011) ***
*** ANNOUNCE: SWIG 2.0.5 (in progress) ***
http://www.swig.org
We're pleased to announce SWIG-2.0.4, the latest SWIG release.
We're pleased to announce SWIG-2.0.5, the latest SWIG release.
What is SWIG?
=============
@ -21,11 +21,11 @@ Availability
============
The release is available for download on Sourceforge at
http://prdownloads.sourceforge.net/swig/swig-2.0.4.tar.gz
http://prdownloads.sourceforge.net/swig/swig-2.0.5.tar.gz
A Windows version is also available at
http://prdownloads.sourceforge.net/swig/swigwin-2.0.4.zip
http://prdownloads.sourceforge.net/swig/swigwin-2.0.5.zip
Please report problems with this release to the swig-devel mailing list,
details at http://www.swig.org/mail.html.

117
CHANGES
View file

@ -3,6 +3,123 @@ SWIG (Simplified Wrapper and Interface Generator)
See the CHANGES.current file for changes in the current version.
See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.4 (21 May 2011)
===========================
2011-05-19: wsfulton
[Guile] Patch #3191625 fixing overloading of integer types.
2011-05-19: wsfulton
[Perl] Patch #3260265 fixing overloading of non-primitive types and integers in
Perl 5.12 and later.
2011-05-19: wsfulton
[Ruby] Fix %import where one of the imported files %include one of the STL include
files such as std_vector.i.
2011-05-17: wsfulton
[Java] Apply #3289851 from Alan Harder to fix memory leak in directors when checking
for pending exceptions.
2011-05-17: wsfulton
[Tcl] Apply #3300072 from Christian Delbaere to fix multiple module loading not
always sharing variables across modules.
2011-05-16: xavier98
[octave] Fix an incompatibility with never versions of Octave. Case on Octave
API >= 40 to handle rename of Octave_map to octave_map.
[octave] Add support for y.__rop__(x) operators when x.__op__(y) doesn't exist.
[octave] Allow global operators to be defined by SWIG-wrapped functions.
[octave] Fix several bugs around module namespaces; add -global, -noglobal,
-globals <name> command line options to the module.
2011-05-14: wsfulton
%varargs when used with a numeric argument used to create an additional argument
which was intended to provide a guaranteed sentinel value. This never worked and now
the additional argument is not generated.
2011-05-13: wsfulton
[python] Additional fixes for python3.2 support.
2011-05-07: szager
[python] Fixed PyGetSetDescr for python3.2.
2011-05-05: wsfulton
[Lua, Python, Tcl] C/C++ prototypes shown in error message when calling an overloaded
method with incorrect arguments improved to show always show fully qualified name
and if a const method.
Also fixed other Lua error messages in generated code which weren't consistently
using the fully qualified C++ name - requested by Gedalia Pasternak.
2011-04-29: szager
Bug 2635919: Convenience method to convert std::map to a python dict.
2011-04-29: szager
[Python] Fixed bug 2811549: return non-const iterators from STL
methods begin(), end(), rbegin(), rend().
2011-04-25: szager
[Python] Fixed bug 1498929: Access to member fields in map elements
2011-04-23: klickverbot
[D] nspace: Correctly generate identifiers for base classes when
not in split proxy mode.
2011-04-13: szager
Fixed bug 3286333: infinite recursion with mutual 'using namespace' clauses.
2011-04-12: szager
Fixed bug 1163440: vararg typemaps.
2011-04-12: szager
Fixed bug #3285386: parse error from 'operator T*&()'. Added operator_pointer_ref
test case to demonstrate.
2011-04-11: szager
[Python] Fixed PyVarObject_HEAD_INIT to eliminate VC++ compiler errors about
static initialization of struct members with pointers.
2011-04-11: wsfulton
[Tcl] Apply patch #3284326 from Colin McDonald to fix some compiler warnings.
2011-04-11: szager
[Python] Fixed PyVarObject_HEAD_INIT to eliminate VC++ compiler errors about
static initialization of struct members with pointers.
2011-04-10: klickverbot
[D] Fixed wrapping of enums that are type char, for example:
enum { X = 'X'; } (this was already in 2.0.3 for C# and Java)
2011-04-10: klickverbot
[D] nspace: Fixed referencing types in the root namespace when
not in split proxy mode.
2011-04-09: szager
[Python] Applied patch #1932484: migrate PyCObject to PyCapsule.
2011-04-09: szager
[Python] Added preprocessor guards for python functions PyUnicode_AsWideChar and
PySlice_GetIndices, which changed signatures in python3.2.
2011-04-07: wsfulton
Fix wrapping of const array typedefs which were generating uncompileable code as
reported by Karl Wette.
2011-04-03: szager
[Python] Fixed the behavior of %pythonnondynamic to conform to the spec in Lib/pyuserdir.swg.
2011-04-03: szager
[Python] Merged in the szager-python-builtin branch, adding the -builtin feature
for python. The -builtin option may provide a significant performance gain
in python wrappers. For full details and limitations, refer to Doc/Manual/Python.html.
A small test suite designed to demonstrate the performance gain is in
Examples/python/performance.
2011-04-01: wsfulton
Add in missing wrappers for friend functions for some target languages, mostly
the non-scripting languages like Java and C#.
Version 2.0.3 (29 March 2011)
=============================

View file

@ -1,81 +1,13 @@
This file contains the changes for the current release.
Below are the changes for the current release.
See the CHANGES file for changes in older releases.
See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.4 (in progress)
Version 2.0.5 (in progress)
===========================
2011-05-05: wsfulton
[Lua, Python, Tcl] C/C++ prototypes shown in error message when calling an overloaded
method with incorrect arguments improved to show always show fully qualified name
and if a const method.
Also fixed other Lua error messages in generated code which weren't consistently
using the fully qualified C++ name - requested by Gedalia Pasternak.
2011-05-30: olly
[PHP] Fix handling of directors when -prefix is used.
2011-04-29: szager
Bug 2635919: Convenience method to convert std::map to a python dict.
2011-05-24: olly
[PHP] Fix handling of methods of classes with a virtual base class (SF#3124665).
2011-04-29: szager
Fixed bug 2811549: return non-const iterators from STL
methods begin(), end(), rbegin(), rend().
2011-04-25: szager
Fixed bug 1498929: Access to member fields in map elements
2011-04-23: klickverbot
[D] nspace: Correctly generate identifiers for base classes when
not in split proxy mode.
2011-04-13: szager
Fixed bug 3286333: infite recursion with mutual 'using namespace' clauses.
2011-04-12: szager
Fixed bug 1163440: vararg typemaps.
2011-04-12: szager
Fixed bug #3285386: parse error from 'operator T*&()'. Added operator_pointer_ref
test case to demonstrate.
2011-04-11: szager
Fixed PyVarObject_HEAD_INIT to eliminate VC++ compiler errors about
static initialization of struct members with pointers.
2011-04-11: wsfulton
[Tcl] Apply patch #3284326 from Colin McDonald to fix some compiler warnings.
2011-04-11: szager
Fixed PyVarObject_HEAD_INIT to eliminate VC++ compiler errors about
static initialization of struct members with pointers.
2011-04-10: klickverbot
[D] Fixed wrapping of enums that are type char, for example:
enum { X = 'X'; } (this was already in 2.0.3 for C# and Java)
2011-04-10: klickverbot
[D] nspace: Fixed referencing types in the root namespace when
not in split proxy mode.
2011-04-09: szager
Applied patch #1932484: migrate PyCObject to PyCapsule.
2011-04-09: szager
Added preprocessor guards for python functions PyUnicode_AsWideChar and
PySlice_GetIndices, which changed signatures in python3.2.
2011-04-07: wsfulton
Fix wrapping of const array typedefs which were generating uncompileable code as
reported by Karl Wette.
2011-04-03: szager
Fixed the behavior of %pythonnondynamic to conform to the spec in Lib/pyuserdir.swg.
2011-04-03: szager
Merged in the szager-python-builtin branch, adding the -builtin feature
for python. The -builtin option may provide a significant performance gain
in python wrappers. For full details and limitations, refer to Doc/Manual/Python.html.
A small test suite designed to demonstrate the performance gain is in
Examples/python/performance.
2011-04-01: wsfulton
Add in missing wrappers for friend functions for some target languages, mostly
the non-scripting languages like Java and C#.

View file

@ -764,6 +764,8 @@
<li><a href="Go.html#Go_templates">Go Templates</a>
<li><a href="Go.html#Go_director_classes">Go Director Classes</a>
<li><a href="Go.html#Go_primitive_type_mappings">Default Go primitive type mappings</a>
<li><a href="#Go_output_arguments">Output arguments</a>
<li><a href="#Go_adding_additional_code">Adding additional go code</a>
</ul>
</ul>
</div>
@ -1332,6 +1334,11 @@
<li><a href="Python.html#Python_nn28">Further details on the Python class interface</a>
<ul>
<li><a href="Python.html#Python_nn29">Proxy classes</a>
<li><a href="Python.html#Python_builtin_types">Built-in Types</a>
<ul>
<li><a href="Python.html#Python_builtin_limitations">Limitations</a>
<li><a href="Python.html#Python_builtin_overloads">Operator overloads -- use them!</a>
</ul>
<li><a href="Python.html#Python_nn30">Memory management</a>
<li><a href="Python.html#Python_nn31">Python 2.2 and classic classes</a>
</ul>
@ -1684,4 +1691,3 @@
</BODY>
</HTML>

View file

@ -2754,15 +2754,16 @@ int Python::top(Node *n) {
<p>
Within SWIG wrappers, there are four main sections. These are (in order)
Within SWIG wrappers, there are five main sections. These are (in order)
</p>
<ul>
<li>runtime: This section has most of the common SWIG runtime code
<li>header: This section holds declarations and inclusions from the .i file
<li>wrapper: This section holds all the wrappering code
<li>begin: This section is a placeholder for users to put code at the beginning of the C/C++ wrapper file.
<li>runtime: This section has most of the common SWIG runtime code.
<li>header: This section holds declarations and inclusions from the .i file.
<li>wrapper: This section holds all the wrappering code.
<li>init: This section holds the module initalisation function
(the entry point for the interpreter)
(the entry point for the interpreter).
</ul>
<p>
Different parts of the SWIG code will fill different sections,

View file

@ -28,6 +28,8 @@
<li><a href="#Go_templates">Go Templates</a>
<li><a href="#Go_director_classes">Go Director Classes</a>
<li><a href="#Go_primitive_type_mappings">Default Go primitive type mappings</a>
<li><a href="#Go_output_arguments">Output arguments</a>
<li><a href="#Go_adding_additional_code">Adding additional go code</a>
</ul>
</ul>
</div>
@ -273,7 +275,7 @@ class.
<p>
SWIG will represent static methods of C++ classes as ordinary Go
functions. SWIG will use names like <tt>ClassName_MethodName</tt>.
functions. SWIG will use names like <tt>ClassNameMethodName</tt>.
SWIG will give static members getter and setter functions with names
like <tt>GetClassName_VarName</tt>.
</p>
@ -289,6 +291,37 @@ to <tt>reinterpret_cast</tt>. This should only be used for very
special cases, such as where C++ would use a <tt>dynamic_cast</tt>.
</p>
<p>Note that C++ pointers to compound objects are represented in go as objects
themselves, not as go pointers. So, for example, if you wrap the following
function:</p>
<div class="code">
<pre>
class MyClass {
int MyMethod();
static MyClass *MyFactoryFunction();
};
</pre>
</div>
<p>You will get go code that looks like this:</p>
<div class="code">
<pre>
type MyClass interface {
Swigcptr() uintptr
SwigIsMyClass()
MyMethod() int
}
MyClassMyFactoryFunction() MyClass {
// swig magic here
}
</pre>
</div>
<p>Note that the factory function does not return a go pointer; it actually
returns a go interface. If the returned pointer can be null, you can check
for this by calling the Swigcptr() method.
</p>
<H4><a name="Go_class_inheritance"></a>21.3.5.1 Go Class Inheritance</H4>
@ -459,5 +492,130 @@ that typemap, or add new values, to control how C/C++ types are mapped
into Go types.
</p>
<H3><a name="Go_output_arguments"></a>21.3.9 Output arguments</H3>
<p>Because of limitations in the way output arguments are processed in swig,
a function with output arguments will not have multiple return values.
Instead, you must pass a pointer into the C++ function to tell it where to
store the ouput value. In go, you supply a slice in the place of the output
argument.</p>
<p>For example, suppose you were trying to wrap the modf() function in the
C math library which splits x into integral and fractional parts (and
returns the integer part in one of its parameters):<p>
<div class="code">
<pre>
double modf(double x, double *ip);
</pre>
</div>
<p>You could wrap it with SWIG as follows:</p>
<div class="code">
<pre>
%include &lt;typemaps.i&gt;
double modf(double x, double *OUTPUT);
</pre>
</div>
<p>or you can use the <code>%apply</code> directive:</p>
<div class="code">
<pre>
%include &lt;typemaps.i&gt;
%apply double *OUTPUT { double *ip };
double modf(double x, double *ip);
</pre>
</div>
<p>In Go you would use it like this:</p>
<div class="code">
<pre>
ptr := []float64{0.0}
fraction := modulename.Modf(5.0, ptr)
</pre>
</div>
<p>Since this is ugly, you may want to wrap the swig-generated API with
some <a href="#Embedded_go_code">additional functions written in go</a> that
hide the ugly details.</p>
<p>There are no <code>char&nbsp;*OUTPUT</code> typemaps. However you can
apply the <code>signed&nbsp;char&nbsp;*</code> typemaps instead:<p>
<div class="code">
<pre>
%include &lt;typemaps.i&gt;
%apply signed char *OUTPUT {char *output};
void f(char *output);
</pre>
</div>
<H3><a name="Go_adding_additional_code"></a>21.3.10 Adding additional go code</H3>
<p>Often the APIs generated by swig are not very natural in go, especially if
there are output arguments. You can
insert additional go wrapping code to add new APIs
with <code>%insert(go_wrapper)</code>, like this:</p>
<div class="code">
<pre>
%include &lt;typemaps.i&gt;
// Change name of what swig generates to Wrapped_modf. This function will
// have the following signature in go:
// func Wrapped_modf(float64, []float64) float64
%rename(wrapped_modf) modf(double x, double *ip);
%apply double *OUTPUT { double *ip };
double modf(double x, double *ip);
%insert(go_wrapper) %{
// The improved go interface to this function, which has two return values,
// in the more natural go idiom:
func Modf(x float64) (fracPart float64, intPart float64) {
ip := []float64{0.0}
fracPart = Wrapped_modf(x, ip)
intPart = ip[0]
return
}
%}
</pre>
</div>
<p>For classes, since swig generates an interface, you can add additional
methods by defining another interface that includes the swig-generated
interface. For example,</p>
<div class="code">
<pre>
%rename(Wrapped_MyClass) MyClass;
%rename(Wrapped_GetAValue) MyClass::GetAValue(int *x);
%apply int *OUTPUT { int *x };
class MyClass {
public:
MyClass();
int AFineMethod(const char *arg); // Swig's wrapping is fine for this one.
bool GetAValue(int *x);
};
%insert(go_wrapper) %{
type MyClass interface {
Wrapped_MyClass
GetAValue() (int, bool)
}
func (arg SwigcptrWrapped_MyClass) GetAValue() (int, bool) {
ip := []int{0}
ok := arg.Wrapped_GetAValue(ip)
return ip[0], ok
}
%}
</pre>
</div>
<p>Of course, if you have to rewrite most of the methods, instead of just a
few, then you might as well define your own struct that includes the
swig-wrapped object, instead of adding methods to the swig-generated object.</p>
<p>This only works if your wrappers do not need to import other go modules.
There is at present no way to insert import statements in the correct place
in swig-generated go. If you need to do that, you must put your go code
in a separate file.</p>
</body>
</html>

View file

@ -43,7 +43,11 @@
<li><a href="#Python_nn28">Further details on the Python class interface</a>
<ul>
<li><a href="#Python_nn29">Proxy classes</a>
<li><a href="#Python_BuiltinClasses">Built-in classes</a>
<li><a href="#Python_builtin_types">Built-in Types</a>
<ul>
<li><a href="#Python_builtin_limitations">Limitations</a>
<li><a href="#Python_builtin_overloads">Operator overloads -- use them!</a>
</ul>
<li><a href="#Python_nn30">Memory management</a>
<li><a href="#Python_nn31">Python 2.2 and classic classes</a>
</ul>
@ -2210,7 +2214,7 @@ unacceptable for a high-performance library. The new <tt>-builtin</tt>
option instructs SWIG to forego the use of proxy classes, and instead
create wrapped types as new built-in Python types. When this option is used,
the following section ("Proxy classes") does not apply. Details on the use of
the <tt>-builtin</tt> option are in the <a href="#Python_BuiltinClasses">Built-in Classes</a>
the <tt>-builtin</tt> option are in the <a href="#Python_builtin_types">Built-in Types</a>
section.
</p>
@ -2303,7 +2307,8 @@ you can attach new Python methods to the class and you can even inherit from it
by Python built-in types until Python 2.2).
</p>
<H3><a name="Python_BuiltinClasses"></a>33.4.2 Built-in Classes</H3>
<H3><a name="Python_builtin_types"></a>33.4.2 Built-in Types</H3>
<p>
The <tt>-builtin</tt> option provides a significant performance improvement
@ -2346,23 +2351,26 @@ please refer to the python documentation:</p>
<p><a href="http://docs.python.org/extending/newtypes.html">http://docs.python.org/extending/newtypes.html</a></p>
<H4>33.4.2.1 Limitations</H4>
<H4><a name="Python_builtin_limitations"></a>33.4.2.1 Limitations</H4>
<p>Use of the <tt>-builtin</tt> option implies a couple of limitations:
<ul>
<li><p>python version support:</p></li>
<ul>
<li>Versions 2.5 and up are fully supported</li>
<li>Versions 2.3 and 2.4 are mostly supported; there are problems with director classes and/or sub-classing a wrapped type in python.</li>
<li>Versions older than 2.3 are not supported.</li>
</ul>
<li><p>Some legacy syntax is no longer supported; in particular:</p></li>
<ul>
<li>The functional interface is no longer exposed. For example, you may no longer call <tt>Whizzo.new_CrunchyFrog()</tt>. Instead, you must use <tt>Whizzo.CrunchyFrog()</tt>.</li>
<li>Static member variables are no longer accessed through the 'cvar' field (e.g., <tt>Dances.cvar.FishSlap</tt>).
They are instead accessed in the idiomatic way (<tt>Dances.FishSlap</tt>).</li>
</ul>
<li><p>Wrapped types may not be raised as python exceptions. Here's why: the python internals expect that all sub-classes of Exception will have this struct layout:</p>
<li><p>python version support:</p>
<ul>
<li>Versions 2.5 and up are fully supported</li>
<li>Versions 2.3 and 2.4 are mostly supported; there are problems with director classes and/or sub-classing a wrapped type in python.</li>
<li>Versions older than 2.3 are not supported.</li>
</ul>
</li>
<li><p>Some legacy syntax is no longer supported; in particular:</p>
<ul>
<li>The functional interface is no longer exposed. For example, you may no longer call <tt>Whizzo.new_CrunchyFrog()</tt>. Instead, you must use <tt>Whizzo.CrunchyFrog()</tt>.</li>
<li>Static member variables are no longer accessed through the 'cvar' field (e.g., <tt>Dances.cvar.FishSlap</tt>).
They are instead accessed in the idiomatic way (<tt>Dances.FishSlap</tt>).</li>
</ul>
</li>
<li><p>Wrapped types may not be raised as python exceptions. Here's why: the python internals expect that all sub-classes of Exception will have this struct layout:</p>
<div class="code">
<pre>
@ -2420,15 +2428,10 @@ class MyPyException (Exception) :
</pre>
</div>
</li>
<li><p>Reverse binary operators (e.g., <tt>__radd__</tt>) are not supported.</p></li>
</ul>
</p>
<p>
To illustrate the last point, if you have a wrapped class called <tt>MyString</tt>,
<li><p>Reverse binary operators (e.g., <tt>__radd__</tt>) are not supported.</p>
<p>To illustrate this point, if you have a wrapped class called <tt>MyString</tt>,
and you want to use instances of <tt>MyString</tt> interchangeably with native python
strings, you can define an <tt>'operator+ (const char*)'</tt> method :
</p>
strings, you can define an <tt>'operator+ (const char*)'</tt> method :</p>
<div class="code">
<pre>
@ -2472,8 +2475,52 @@ episode = "Dead " + mystr
The above code fails, because the first operand -- a native python string --
doesn't know how to add an instance of <tt>MyString</tt> to itself.
</p>
</li>
<li><p>If you have multiple SWIG modules that share type information (<a href="Modules.html#Modules_nn2">more info</a>),
the <tt>-builtin</tt> option requiress a bit of extra discipline to ensure that base classes are initialized before derived classes. Specifically:</p>
<ul>
<li><p>There must be an unambiguous dependency graph for the modules.</p></li>
<li><p>Module dependencies must be explicitly stated with <tt>%import</tt> statements in the SWIG interface file.</p>
</ul>
<p>As an example, suppose module <tt>A</tt> has this interface in <tt>A.i</tt> :</p>
<div class="code"><pre>
%module "A";
class Base {
...
};
</pre></div>
<p>If you want to wrap another module containing a class that inherits from <tt>A</tt>, this is how it would look :</p>
<div class="code"><pre>
%module "B";
%import "A.i"
class Derived : public Base {
...
};
</pre></div>
<p>The <tt>import "A.i"</tt> statement is required, because module <tt>B</tt> depends on module <tt>A</tt>.</p>
<p>As long as you obey these requirements, your python code may import the modules in any order :</p>
<div class="targetlang"><pre>
import B
import A
assert(issubclass(B.Derived, A.Base))
</pre></div>
</li>
</ul>
<H4><a name="Python_builtin_overloads"></a>33.4.2.2 Operator overloads -- use them!</H4>
<H4>33.4.2.2 Operator overloads -- use them!</H4>
<p>The entire justification for the <tt>-builtin</tt> option is improved
performance. To that end, the best way to squeeze maximum performance out
@ -2491,10 +2538,10 @@ slot entries. For example, suppose you have this class:
<pre>
class Twit {
public:
Twit operator+ (const Twit& twit) const;
Twit operator+ (const Twit&amp; twit) const;
// Forward to operator+
Twit add (const Twit& twit) const
Twit add (const Twit&amp; twit) const
{ return *this + twit; }
};
</pre>
@ -2575,6 +2622,7 @@ structs.
<H3><a name="Python_nn30"></a>33.4.3 Memory management</H3>
<p>NOTE: Although this section refers to proxy objects, everything here also applies
when the <tt>-builtin</tt> option is used.</p>
@ -5257,7 +5305,8 @@ all overloaded functions share the same function in SWIG generated proxy class.
</p>
<p>
For detailed usage of function annotation, see PEP 3107.
For detailed usage of function annotation, see
<a href="http://www.python.org/dev/peps/pep-3107/">PEP 3107</a>.
</p>
<H3><a name="Python_nn75"></a>33.12.2 Buffer interface</H3>
@ -5449,7 +5498,8 @@ used to define an abstract base class for your own C++ class:
</pre></div>
<p>
For details of abstract base class, please see PEP 3119.
For details of abstract base class, please see
<a href="http://www.python.org/dev/peps/pep-3119/">PEP 3119</a>.
</p>
</body>

View file

@ -3034,14 +3034,15 @@ output of SWIG is structured first.</p>
<p>
When SWIG creates its output file, it is broken up into four sections
When SWIG creates its output file, it is broken up into five sections
corresponding to runtime code, headers, wrapper functions, and module
initialization code (in that order).
</p>
<ul>
<li><b>Begin section</b>. <br>
A placeholder to put code at the beginning of the C/C++ wrapper file.
A placeholder for users to put code at the beginning of the C/C++ wrapper file.
This is most often used to define preprocessor macros that are used in later sections.
</li>
<li><b>Runtime code</b>. <br>

View file

@ -6,7 +6,7 @@
<body bgcolor="#ffffff">
<H1><a name="Sections"></a>SWIG-2.0 Documentation</H1>
Last update : SWIG-2.0.4 (in progress)
Last update : SWIG-2.0.5 (in progress)
<H2>Sections</H2>

View file

@ -331,33 +331,82 @@ int open(const char *path, int oflags, int mode = 0);
<p>
In this case, <tt>%varargs</tt> is simply providing more specific information about the
extra arguments that might be passed to a function.
If the parameters to a varargs function are of uniform type, <tt>%varargs</tt> can also
If the arguments to a varargs function are of uniform type, <tt>%varargs</tt> can also
accept a numerical argument count as follows:
</p>
<div class="code">
<pre>
%varargs(10,char *arg = NULL) execlp;
%varargs(3, char *str = NULL) execlp;
...
int execlp(const char *path, const char *arg1, ...);
int execlp(const char *path, const char *arg, ...);
</pre>
</div>
<p>
This would wrap <tt>execlp()</tt> as a function that accepted up to 10 optional arguments.
and is effectively seen as:
</p>
<div class="code">
<pre>
int execlp(const char *path, const char *arg,
char *str1 = NULL,
char *str2 = NULL,
char *str3 = NULL);
</pre>
</div>
<p>
This would wrap <tt>execlp()</tt> as a function that accepted up to 3 optional arguments.
Depending on the application, this may be more than enough for practical purposes.
</p>
<p>
Argument replacement is most appropriate in cases where the types of
the extra arguments is uniform and the maximum number of arguments is
known. When replicated argument replacement is used, at least one extra
argument is added to the end of the arguments when making the function call.
This argument serves as a sentinel to make sure the list is properly terminated.
It has the same value as that supplied to the <tt>%varargs</tt> directive.
The handling of <a href="SWIGPlus.html#SWIGPlus_default_args">default arguments</a> can be changed via the
<tt>compactdefaultargs</tt> feature. If this feature is used, for example
</p>
<div class="code">
<pre>
%feature("compactdefaultargs") execlp;
%varargs(3, char *str = NULL) execlp;
...
int execlp(const char *path, const char *arg, ...);
</pre>
</div>
<p>
a call from the target language which does not provide the maximum number of arguments, such as,
<tt>execlp("a", "b", "c")</tt>
will generate C code which includes the missing default values, that is, <tt>execlp("a", "b", "c", NULL, NULL)</tt>.
If <tt>compactdefaultargs</tt> is not used, then the generated code will be
<tt>execlp("a", "b", "c")</tt>. The former is useful for helping providing a sentinel to terminate the argument list.
However, this is not guaranteed, for example when a user passes a non-NULL value for all the parameters.
When using <tt>compactdefaultargs</tt> it is possible to guarantee the NULL sentinel is passed through the,
<tt>numinputs=0</tt> <a href="Typemaps.html#Typemaps_nn26">'in' typemap attribute</a>, naming the <b>last parameter</b>.
For example,
</p>
<div class="code">
<pre>
%feature("compactdefaultargs") execlp;
%varargs(3, char *str = NULL) execlp;
%typemap(in, numinputs=0) char *str3 ""
...
int execlp(const char *path, const char *arg, ...);
</pre>
</div>
<p>
Note that <tt>str3</tt> is the name of the last argument, as we have used <tt>%vargars</tt> with 3.
Now <tt>execlp("a", "b", "c", "d", "e")</tt> will result in an error as one too many arguments has been passed,
as now only 2 additional 'str' arguments can be passed with the 3rd one always using the specified default <tt>NULL</tt>.
</p>
<p>
Argument replacement is most appropriate in cases where the types of
the extra arguments are uniform and the maximum number of arguments are
known.
Argument replacement is not as useful when working with functions that accept
mixed argument types such as <tt>printf()</tt>. Providing general purpose
wrappers to such functions presents special problems (covered shortly).
@ -461,23 +510,36 @@ like this:
<div class="code">
<pre>
%typemap(in) (...)(char *args[10]) {
int i;
int argc;
for (i = 0; i &lt; 10; i++) args[i] = 0;
argc = PyTuple_Size(varargs);
if (argc &gt; 10) {
PyErr_SetString(PyExc_ValueError,"Too many arguments");
int i;
int argc;
for (i = 0; i &lt; 10; i++) args[i] = 0;
argc = PyTuple_Size(varargs);
if (argc &gt; 10) {
PyErr_SetString(PyExc_ValueError, "Too many arguments");
return NULL;
}
for (i = 0; i &lt; argc; i++) {
PyObject *pyobj = PyTuple_GetItem(varargs, i);
char *str = 0;
%#if PY_VERSION_HEX&gt;=0x03000000
PyObject *pystr;
if (!PyUnicode_Check(pyobj)) {
PyErr_SetString(PyExc_ValueError, "Expected a string");
return NULL;
}
for (i = 0; i &lt; argc; i++) {
PyObject *o = PyTuple_GetItem(varargs,i);
if (!PyString_Check(o)) {
PyErr_SetString(PyExc_ValueError,"Expected a string");
return NULL;
}
args[i] = PyString_AsString(o);
pystr = PyUnicode_AsUTF8String(pyobj);
str = PyBytes_AsString(pystr);
Py_XDECREF(pystr);
%#else
if (!PyString_Check(pyobj)) {
PyErr_SetString(PyExc_ValueError, "Expected a string");
return NULL;
}
$1 = (void *) args;
str = PyString_AsString(pyobj);
%#endif
args[i] = str;
}
$1 = (void *) args;
}
</pre>
</div>

View file

@ -118,6 +118,7 @@ CPP_TEST_CASES += \
arrays_global \
arrays_global_twodim \
arrays_scope \
autodoc \
bloody_hell \
bools \
catches \
@ -437,6 +438,7 @@ CPP_TEST_CASES += \
varargs_overload \
virtual_destructor \
virtual_poly \
virtual_vs_nonvirtual_base \
voidtest \
wallkw \
wrapmacro

View file

@ -3,7 +3,7 @@
#######################################################################
LANGUAGE = octave
OCTAVE = @OCTAVE@ -q
OCTAVE = @OCTAVE@ -qf
SCRIPTSUFFIX = _runme.m
srcdir = @srcdir@
top_srcdir = @top_srcdir@

View file

@ -208,3 +208,9 @@ long long ll(long long ull) { return ull; }
}
#endif
%inline %{
int int_object(Spam *s) { return 999; }
int int_object(int c) { return c; }
%}

View file

@ -41,11 +41,11 @@ ok(not($@), '%rename handling');
# exception specifications
eval { default_args::exceptionspec() };
is($@, "ciao", "exceptionspec 1");
like($@, qr/^ciao/, "exceptionspec 1");
eval { default_args::exceptionspec(-1) };
is($@, "ciao", "exceptionspec 2");
like($@, qr/^ciao/, "exceptionspec 2");
eval { default_args::exceptionspec(100) };
is($@, '100', "exceptionspec 3");
like($@, qr/^100/, "exceptionspec 3");
my $ex = new default_args::Except($false);
@ -54,13 +54,13 @@ eval { $ex->exspec(); $hit = 1; };
# a zero was thrown, an exception occured, but $@ is false
is($hit, 0, "exspec 1");
eval { $ex->exspec(-1) };
is($@, "ciao", "exspec 2");
like($@, qr/^ciao/, "exspec 2");
eval { $ex->exspec(100) };
is($@, 100, "exspec 3");
like($@, qr/^100/, "exspec 3");
eval { $ex = default_args::Except->new($true) };
is($@, -1, "Except constructor 1");
like($@, qr/-1/, "Except constructor 1");
eval { $ex = default_args::Except->new($true, -2) };
is($@, -2, "Except constructor 2");
like($@, qr/-2/, "Except constructor 2");
#Default parameters in static class methods
is(default_args::Statics::staticmethod(), 60, "staticmethod 1");

View file

@ -48,7 +48,7 @@ li_std_string::test_reference($stringPtr);
# Check throw exception specification
eval { li_std_string::test_throw() };
is($@, "test_throw message", "Test 5");
like($@, qr/^test_throw message/, "Test 5");
{ local $TODO = "why is the error not a Perl string?";
eval { li_std_string::test_const_reference_throw() };
is($@, "<some kind of string>", "Test 6");

View file

@ -2,7 +2,7 @@
use overload_simple;
use vars qw/$DOWARN/;
use strict;
use Test::More tests => 71;
use Test::More tests => 75;
pass("loaded");
@ -189,3 +189,10 @@ is(overload_simple::fid("3", 3), "fid:intint", "fid:fid(int,int)");
isnt(overload_simple::fbool(0), overload_simple::fbool(1), "fbool(bool)");
is(2, overload_simple::fbool(2), "fbool(int)");
# int and object overload
is(overload_simple::int_object(1), 1, "int_object(1)");
is(overload_simple::int_object(0), 0, "int_object(0)");
is(overload_simple::int_object(undef), 999, "int_object(Spam*)");
is(overload_simple::int_object($s), 999, "int_object(Spam*)");

View file

@ -0,0 +1,11 @@
<?
require "tests.php";
require "virtual_vs_nonvirtual_base.php";
$fail = new SimpleClassFail();
$work = new SimpleClassWork();
check::equal($work->getInner()->get(), $fail->getInner()->get(), "should both be 10");
?>

View file

@ -31,42 +31,41 @@ PY2TO3 = 2to3 -x import
CPP_TEST_CASES += \
argcargvtest \
python_autodoc \
python_append \
callback \
complextest \
director_stl \
director_wstring \
file_test \
iadd \
inout \
input \
inplaceadd \
implicittest \
inout \
inplaceadd \
input \
li_cstring \
li_cwstring \
li_factory \
li_implicit \
li_std_vectora \
li_std_vector_extra \
li_std_map_member \
li_std_multimap \
li_std_pair_extra \
li_std_set \
li_std_stream \
li_std_string_extra \
li_std_vectora \
li_std_vector_extra \
li_std_wstream \
li_std_wstring \
primitive_types \
python_abstractbase \
python_append \
python_kwargs \
python_nondynamic \
python_overload_simple_cast \
python_richcompare \
simutry \
std_containers \
swigobject \
template_matrix \
simutry
template_matrix
# li_std_carray
# director_profile
@ -88,11 +87,12 @@ C_TEST_CASES += \
include $(srcdir)/../common.mk
BUILTIN_BROKEN = \
li_std_string_extra.cpptest \
li_std_wstring.cpptest \
default_constructor.cpptest \
director_exception.cpptest \
exception_order.cpptest \
li_std_string_extra.cpptest \
li_std_wstring.cpptest \
python_abstractbase.cpptest \
threads_exception.cpptest
BUILTIN_NOT_BROKEN = $(filter-out $(BUILTIN_BROKEN),$(NOT_BROKEN_TEST_CASES))

View file

@ -16,3 +16,21 @@ if varargs.test_def("Hello",1) != "Hello":
if varargs.test_def("Hello") != "Hello":
raise RuntimeError, "Failed"
###
if varargs.test_plenty("Hello") != "Hello":
raise RuntimeError, "Failed"
if varargs.test_plenty("Hello", 1) != "Hello":
raise RuntimeError, "Failed"
if varargs.test_plenty("Hello", 1, 2) != "Hello":
raise RuntimeError, "Failed"
try:
varargs.test_plenty("Hello", 1, 2, 3)
raise RuntimeError
except NotImplementedError:
pass
except TypeError:
pass

View file

@ -4,40 +4,61 @@
* chapter of the SWIG manual.
*/
%{
%}
%typemap(in) (...)(char *args[10]) {
int i;
int argc;
for (i = 0; i < 10; i++) args[i] = 0;
argc = PyTuple_Size(varargs);
if (argc > 10) {
PyErr_SetString(PyExc_ValueError,"Too many arguments");
int i;
int argc;
for (i = 0; i < 10; i++) args[i] = 0;
argc = PyTuple_Size(varargs);
if (argc > 10) {
PyErr_SetString(PyExc_ValueError, "Too many arguments");
return NULL;
}
for (i = 0; i < argc; i++) {
PyObject *pyobj = PyTuple_GetItem(varargs, i);
char *str = 0;
%#if PY_VERSION_HEX>=0x03000000
PyObject *pystr;
if (!PyUnicode_Check(pyobj)) {
PyErr_SetString(PyExc_ValueError, "Expected a string");
return NULL;
}
for (i = 0; i < argc; i++) {
PyObject *o = PyTuple_GetItem(varargs,i);
if (!PyString_Check(o)) {
PyErr_SetString(PyExc_ValueError,"Expected a string");
return NULL;
}
args[i] = PyString_AsString(o);
pystr = PyUnicode_AsUTF8String(pyobj);
str = PyBytes_AsString(pystr);
Py_XDECREF(pystr);
%#else
if (!PyString_Check(pyobj)) {
PyErr_SetString(PyExc_ValueError, "Expected a string");
return NULL;
}
$1 = (void *) args;
str = PyString_AsString(pyobj);
%#endif
args[i] = str;
}
$1 = (void *) args;
}
%feature("action") testfunc {
char **args = (char **) arg3;
result = testfunc(arg1, arg2, args[0], args[1], args[2], args[3], args[4],
args[5],args[6],args[7],args[8],args[9], NULL);
char **args = (char **) arg3;
result = testfunc(arg1, arg2, args[0], args[1], args[2], args[3], args[4],
args[5],args[6],args[7],args[8],args[9], NULL);
}
%inline {
char* testfunc (int arg1, double arg2, ...)
{
va_list ap;
char *c;
va_start(ap, arg2);
c = va_arg(ap, char*);
va_end(ap);
return c;
va_list ap;
char *c;
va_start(ap, arg2);
c = va_arg(ap, char*);
va_end(ap);
return c;
}
}
%inline %{
char *doublecheck(char *inputval) { return inputval; }
%}

View file

@ -5,13 +5,25 @@
%warnfilter(SWIGWARN_GO_NAME_CONFLICT); /* Ignoring 'NewName' due to Go name ('NewName') conflict with 'Name' */
%ignore Name::operator=;
%inline %{
struct Name {
Name(const char *n="none") : name(n) {}
Name(const char *n="none") : name(strdup(n ? n : "")) {}
Name(const Name& x) : name(strdup(x.name)) {}
Name& operator= (const Name& x)
{
if (this != &x) {
free(this->name);
this->name = strdup(x.name);
}
return *this;
}
~Name () { free(this->name); }
const char *getName() const { return name; };
Name *getNamePtr() { return this; };
private:
const char *name;
char *name;
};
struct NameWrap {
NameWrap(const char *n="casternone") : name(n) {}

View file

@ -1,14 +1,17 @@
# This is the imports runtime testcase.
proc import {} {
if [ catch { load ./imports_b[info sharedlibextension] imports_b} err_msg ] {
puts stderr "Could not load shared object:\n$err_msg"
exit 1
}
if [ catch { load ./imports_a[info sharedlibextension] imports_a} err_msg ] {
puts stderr "Could not load shared object:\n$err_msg"
exit 1
}
}
if [ catch { load ./imports_b[info sharedlibextension] imports_b} err_msg ] {
puts stderr "Could not load shared object:\n$err_msg"
exit 1
}
if [ catch { load ./imports_a[info sharedlibextension] imports_a} err_msg ] {
puts stderr "Could not load shared object:\n$err_msg"
exit 1
}
import
set x [new_B]
A_hello $x

View file

@ -5,6 +5,7 @@
%varargs(int mode = 0) test_def;
%varargs(int mode = 0) Foo::Foo;
%varargs(int mode = 0) Foo::statictest(const char*fmt, ...);
%varargs(2, int mode = 0) test_plenty(const char*fmt, ...);
%inline %{
char *test(const char *fmt, ...) {
@ -36,4 +37,8 @@ public:
}
};
const char *test_plenty(const char *fmt, ...) {
return fmt;
}
%}

View file

@ -0,0 +1,48 @@
%module virtual_vs_nonvirtual_base;
// Regression test for SF#3124665.
%inline {
class SimpleVirtual
{
public:
virtual int implementMe() = 0;
};
class SimpleNonVirtual
{
public:
int dummy() { return 0; }
};
class SimpleReturnClass
{
public:
SimpleReturnClass(int i) : value(i) {};
int get() const { return value; }
private:
int value;
};
class SimpleClassFail : public SimpleVirtual
{
public:
SimpleClassFail() : inner(10) {}
SimpleReturnClass getInner() { return inner; }
virtual int implementMe() { return 0; }
private:
SimpleReturnClass inner;
};
class SimpleClassWork : public SimpleNonVirtual
{
public:
SimpleClassWork() : inner(10) {}
SimpleReturnClass getInner() { return inner; }
virtual int implementMe() { return 0; }
private:
SimpleReturnClass inner;
};
}

View file

@ -292,18 +292,18 @@ SIMPLE_MAP(unsigned long long, gh_scm2ulong_long, gh_ulong_long2scm, integer);
%typemap (varin, doc="NEW-VALUE is a string") char * {$1 = ($1_ltype)SWIG_scm2str($input);}
%typemap (out, doc="<string>") char * {$result = gh_str02scm((const char *)$1);}
%typemap (varout, doc="<string>") char * {$result = gh_str02scm($1);}
%typemap (in, doc="$NAME is a string") char * *INPUT(char * temp, int must_free = 0) {
%typemap (in, doc="$NAME is a string") char **INPUT(char * temp, int must_free = 0) {
temp = (char *) SWIG_scm2str($input); $1 = &temp;
must_free = 1;
}
%typemap (in,numinputs=0) char * *OUTPUT (char * temp)
%typemap (in,numinputs=0) char **OUTPUT (char * temp)
{$1 = &temp;}
%typemap (argout,doc="$NAME (a string)") char * *OUTPUT
%typemap (argout,doc="$NAME (a string)") char **OUTPUT
{SWIG_APPEND_VALUE(gh_str02scm(*$1));}
%typemap (in) char * *BOTH = char * *INPUT;
%typemap (argout) char * *BOTH = char * *OUTPUT;
%typemap (in) char * *INOUT = char * *INPUT;
%typemap (argout) char * *INOUT = char * *OUTPUT;
%typemap (in) char **BOTH = char **INPUT;
%typemap (argout) char **BOTH = char **OUTPUT;
%typemap (in) char **INOUT = char **INPUT;
%typemap (argout) char **INOUT = char **OUTPUT;
/* SWIG_scm2str makes a malloc'ed copy of the string, so get rid of it after
the function call. */
@ -406,7 +406,7 @@ typedef unsigned long SCM;
const std::size_t &, const std::ptrdiff_t &,
enum SWIGTYPE
{
$1 = SCM_NFALSEP(scm_integer_p($input)) ? 1 : 0;
$1 = SCM_NFALSEP(scm_integer_p($input)) && SCM_NFALSEP(scm_exact_p($input))? 1 : 0;
}
%typecheck(SWIG_TYPECHECK_BOOL)

View file

@ -4,17 +4,17 @@
the complex Constructor method, and the Real and Imag complex
accesor methods.
See the std_complex.i and ccomplex.i for concret examples.
See the std_complex.i and ccomplex.i for concrete examples.
*/
/* the common from conversor */
%define %swig_fromcplx_conv(Type, Real, Imag)
%define %swig_fromcplx_conv(Type, OctConstructor, Real, Imag)
%fragment(SWIG_From_frag(Type),"header")
{
SWIGINTERNINLINE octave_value
SWIG_From(Type)(%ifcplusplus(const Type&, Type) c)
SWIG_From(Type)(const Type& c)
{
return octave_value(Complex(Real(c), Imag(c)));
return octave_value(OctConstructor(Real(c), Imag(c)));
}
}
%enddef
@ -45,7 +45,7 @@
return SWIG_TypeError;
}
}
%swig_fromcplx_conv(Type, Real, Imag);
%swig_fromcplx_conv(Type, Complex, Real, Imag);
%enddef
// the float case
@ -53,7 +53,7 @@
%fragment(SWIG_AsVal_frag(Type),"header",
fragment=SWIG_AsVal_frag(float)) {
SWIGINTERN int
SWIG_AsVal(Type)(PyObject *o, Type *val)
SWIG_AsVal(Type) (const octave_value& ov, Type* val)
{
if (ov.is_complex_scalar()) {
if (val) {
@ -81,7 +81,7 @@
}
}
%swig_fromcplx_conv(Type, Real, Imag);
%swig_fromcplx_conv(Type, FloatComplex, Real, Imag);
%enddef
#define %swig_cplxflt_convn(Type, Constructor, Real, Imag) \
@ -90,6 +90,3 @@
#define %swig_cplxdbl_convn(Type, Constructor, Real, Imag) \
%swig_cplxdbl_conv(Type, Constructor, Real, Imag)

View file

@ -457,22 +457,26 @@ namespace Swig {
rhs.members.clear();
}
void install_global() {
void install_global(bool global_load) {
for (member_map::const_iterator it = members.begin(); it != members.end(); ++it) {
if (it->second.first && it->second.first->method)
bool is_global_op = (it->first.substr(0, strlen(SWIG_op_prefix)) == SWIG_op_prefix);
bool is_func_defined = (it->second.first && it->second.first->method);
if (is_func_defined && (is_global_op || global_load)) {
install_builtin_function(it->second.first->method, it->first,
it->second.first->doc?it->second.first->doc:std::string());
else if (it->second.second.is_defined()) {
it->second.first->doc ? it->second.first->doc : std::string());
}
octave_value global_val = is_global_op ? make_fcn_handle(it->first) : it->second.second;
if (global_val.is_defined() && (is_global_op || global_load)) {
#if OCTAVE_API_VERSION_NUMBER<37
link_to_global_variable(curr_sym_tab->lookup(it->first, true));
#else
symbol_table::varref(it->first);
symbol_table::mark_global(it->first);
#endif
set_global_value(it->first, it->second.second);
set_global_value(it->first, global_val);
#if OCTAVE_API_VERSION_NUMBER<37
octave_swig_type *ost = Swig::swig_value_deref(it->second.second);
octave_swig_type *ost = Swig::swig_value_deref(global_val);
if (ost) {
const char* h = ost->help_text();
if (h) {
@ -715,9 +719,15 @@ namespace Swig {
return outarg(0).string_value();
}
#if OCTAVE_API_VERSION_NUMBER >= 40
virtual octave_map map_value() const {
return octave_map();
}
#else
virtual Octave_map map_value() const {
return Octave_map();
}
#endif
virtual string_vector map_keys() const {
member_map tmp;
@ -769,7 +779,7 @@ namespace Swig {
}
static bool dispatch_global_op(const std::string &symbol, const octave_value_list &args, octave_value &ret) {
// we assume that "op_"-prefixed functions are installed in global namespace
// we assume that SWIG_op_prefix-prefixed functions are installed in global namespace
// (rather than any module namespace).
octave_value fcn = get_global_value(symbol, true);
@ -786,7 +796,7 @@ namespace Swig {
octave_value ret;
if (ost->dispatch_unary_op(std::string("__") + op_name + std::string("__"), ret))
return ret;
std::string symbol = "op_" + ost->swig_type_name() + "_" + op_name;
std::string symbol = SWIG_op_prefix + ost->swig_type_name() + "_" + op_name;
octave_value_list args;
args.append(make_value_hack(x));
if (dispatch_global_op(symbol, args, ret))
@ -803,13 +813,23 @@ namespace Swig {
octave_value ret;
if (lhs_ost && lhs_ost->dispatch_binary_op(std::string("__") + op_name + std::string("__"), rhs, ret))
return ret;
if (rhs_ost) {
if (strlen(op_name) == 2 && (op_name[1] == 't' || op_name[1] == 'e')) {
if (op_name[0] == 'l' && rhs_ost->dispatch_binary_op(std::string("__g") + op_name[1] + std::string("__"), lhs, ret))
return ret;
if (op_name[0] == 'g' && rhs_ost->dispatch_binary_op(std::string("__l") + op_name[1] + std::string("__"), lhs, ret))
return ret;
}
if (rhs_ost->dispatch_binary_op(std::string("__r") + op_name + std::string("__"), lhs, ret))
return ret;
}
std::string symbol;
octave_value_list args;
args.append(make_value_hack(lhs));
args.append(make_value_hack(rhs));
symbol = "op_";
symbol = SWIG_op_prefix;
symbol += lhs_ost ? lhs_ost->swig_type_name() : lhs.type_name();
symbol += "_";
symbol += op_name;
@ -818,7 +838,7 @@ namespace Swig {
if (dispatch_global_op(symbol, args, ret))
return ret;
symbol = "op_";
symbol = SWIG_op_prefix;
symbol += lhs_ost ? lhs_ost->swig_type_name() : lhs.type_name();
symbol += "_";
symbol += op_name;
@ -827,7 +847,7 @@ namespace Swig {
if (dispatch_global_op(symbol, args, ret))
return ret;
symbol = "op_";
symbol = SWIG_op_prefix;
symbol += "any";
symbol += "_";
symbol += op_name;
@ -849,26 +869,32 @@ namespace Swig {
member_map tmp;
load_members(tmp);
os << "{" << std::endl;
indent(os);
os << "{"; newline(os);
increment_indent_level();
for (unsigned int j = 0; j < types.size(); ++j) {
indent(os);
if (types[j].first->clientdata) {
const swig_octave_class *c = (const swig_octave_class *) types[j].first->clientdata;
os << " " << c->name << ", ptr = " << types[j].second.ptr << std::endl;
os << c->name << ", ptr = " << types[j].second.ptr; newline(os);
} else {
os << " " << types[j].first->name << ", ptr = " << types[j].second.ptr << std::endl;
os << types[j].first->name << ", ptr = " << types[j].second.ptr; newline(os);
}
}
for (member_map::const_iterator it = tmp.begin(); it != tmp.end(); ++it) {
indent(os);
if (it->second.first) {
const char *objtype = it->second.first->method ? "method" : "variable";
const char *modifier = (it->second.first->flags &1) ? "static " : (it->second.first->flags &2) ? "global " : "";
os << " " << it->second.first->name << " (" << modifier << objtype << ")" << std::endl;
os << it->second.first->name << " (" << modifier << objtype << ")"; newline(os);
assert(it->second.first->name == it->first);
} else {
os << " " << it->first << std::endl;
os << it->first; newline(os);
}
}
os << "}" << std::endl;
decrement_indent_level();
indent(os);
os << "}"; newline(os);
}
};
@ -923,8 +949,13 @@ namespace Swig {
virtual std::string string_value(bool force = false) const
{ return ptr->string_value(force); }
#if OCTAVE_API_VERSION_NUMBER >= 40
virtual octave_map map_value() const
{ return ptr->map_value(); }
#else
virtual Octave_map map_value() const
{ return ptr->map_value(); }
#endif
virtual string_vector map_keys() const
{ return ptr->map_keys(); }
@ -998,7 +1029,8 @@ namespace Swig {
}
void print(std::ostream &os, bool pr_as_read_syntax = false) const {
os << "swig packed type: name = " << (type ? type->name : std::string()) << ", len = " << buf.size() << std::endl;
indent(os);
os << "swig packed type: name = " << (type ? type->name : std::string()) << ", len = " << buf.size(); newline(os);
}

View file

@ -1,4 +1,5 @@
%insert(runtime) %{
#include <iostream>
#include <octave/oct.h>
#include <octave/parse.h>
#include <octave/ov-fcn-handle.h>
@ -20,6 +21,45 @@ DEFUN_DLD (SWIG_name,args,nargout,SWIG_name_d) {
static bool already_init=false;
if (already_init)
return octave_value_list();
// parse command line
const char* usage="usage: " SWIG_name_d " [-global|-noglobal] [-globals <name>]";
bool global_load=SWIG_global_load;
std::string global_name=SWIG_global_name;
for (int j=0;j<args.length();++j)
if (args(j).is_string()) {
if (args(j).string_value()=="-help") {
std::cout << usage << std::endl;
return octave_value_list();
} else if (args(j).string_value()=="-global") {
global_load = true;
} else if (args(j).string_value()=="-noglobal") {
global_load = false;
} else if (args(j).string_value()=="-globals") {
if (j+1<args.length()&&args(j+1).is_string()) {
global_name = args(j+1).string_value();
++j;
} else {
std::cerr << "error: " SWIG_name_d ": option '-globals' requires an argument." << std::endl;
std::cerr << usage << std::endl;
return octave_value_list();
}
} else {
std::cerr << "error: " SWIG_name_d ": unrecognised argument '" << args(j).string_value() << "'." << std::endl;
std::cerr << usage << std::endl;
return octave_value_list();
}
} else {
std::cerr << "error: " SWIG_name_d ": unrecognised non-string argument." << std::endl;
std::cerr << usage << std::endl;
return octave_value_list();
}
if (!valid_identifier(global_name)) {
std::cerr << "error: " SWIG_name_d ": '" << global_name << "' is not a valid Octave identifier." << std::endl;
return octave_value_list();
}
already_init=true;
octave_swig_ref::register_type();
@ -32,20 +72,13 @@ DEFUN_DLD (SWIG_name,args,nargout,SWIG_name_d) {
install_builtin_function(swig_this,"swig_this",std::string());
install_builtin_function(swig_subclass,"subclass",std::string());
bool global_option=true; // * swig cli option should control this default
for (int j=0;j<args.length();++j)
if (args(j).is_string()&&args(j).string_value()=="noglobal")
global_option=true;
else if (args(j).is_string()&&args(j).string_value()=="noglobal")
global_option=false;
octave_swig_type* cvar_ns=new octave_swig_type;
for (int j=0;swig_globals[j].name;++j)
if (swig_globals[j].get_method)
cvar_ns->assign(swig_globals[j].name,&swig_globals[j]);
octave_swig_type* module_ns=new octave_swig_type(0, 0, 0, true);
module_ns->assign("cvar",Swig::swig_value_ref(cvar_ns));
module_ns->assign(global_name,Swig::swig_value_ref(cvar_ns));
for (int j=0;swig_globals[j].name;++j)
if (swig_globals[j].method)
module_ns->assign(swig_globals[j].name,&swig_globals[j]);
@ -68,8 +101,7 @@ DEFUN_DLD (SWIG_name,args,nargout,SWIG_name_d) {
// the incref is necessary so install_global doesn't destroy module_ns,
// as it would if it installed something with the same name as the module.
module_ns->incref();
if (global_option)
module_ns->install_global();
module_ns->install_global(global_load);
module_ns->decref();
#if OCTAVE_API_VERSION_NUMBER<37

View file

@ -61,7 +61,7 @@
%typemap(out) octave_value_list {
_outp->append($1);
}
%typemap(out,noblock=1) Octave_map {
%typemap(out,noblock=1) octave_map, Octave_map {
$result=$1;
}
%typemap(out,noblock=1) NDArray {

View file

@ -274,8 +274,14 @@ SWIG_Perl_ConvertPtrAndOwn(SWIG_MAYBE_PERL_OBJECT SV *sv, void **ptr, swig_type_
return SWIG_OK;
} else if (SvTYPE(sv) == SVt_RV) { /* Check for NULL pointer */
if (!SvROK(sv)) {
*(ptr) = (void *) 0;
return SWIG_OK;
/* In Perl 5.12 and later, SVt_RV == SVt_IV, so sv could be a valid integer value. */
if (SvIOK(sv)) {
return SWIG_ERROR;
} else {
/* NULL pointer (reference to undef). */
*(ptr) = (void *) 0;
return SWIG_OK;
}
} else {
return SWIG_ERROR;
}

View file

@ -107,13 +107,11 @@ namespace Swig {
}
bool swig_is_overridden_method(char *cname, char *lc_fname) {
zval classname;
zend_class_entry **ce;
zend_function *mptr;
int name_len = strlen(lc_fname);
ZVAL_STRING(&classname, cname, 0);
if (zend_lookup_class(Z_STRVAL_P(&classname), Z_STRLEN_P(&classname), &ce TSRMLS_CC) != SUCCESS) {
if (zend_lookup_class(cname, strlen(cname), &ce TSRMLS_CC) != SUCCESS) {
return false;
}
if (zend_hash_find(&(*ce)->function_table, lc_fname, name_len + 1, (void**) &mptr) != SUCCESS) {

View file

@ -347,7 +347,7 @@
SWIGTYPE [],
SWIGTYPE &
%{
SWIG_SetPointerZval($input, (void *)&$1_name, $1_descriptor, $owner);
SWIG_SetPointerZval($input, (void *)&$1_name, $1_descriptor, ($owner)|2);
%}
%typemap(out, fragment="swig_php_init_member_ptr") SWIGTYPE (CLASS::*)

View file

@ -96,7 +96,6 @@ static ZEND_RSRC_DTOR_FUNC(SWIG_landfill) { (void)rsrc; }
static void
SWIG_ZTS_SetPointerZval(zval *z, void *ptr, swig_type_info *type, int newobject TSRMLS_DC) {
swig_object_wrapper *value=NULL;
/*
* First test for Null pointers. Return those as PHP native NULL
*/
@ -105,12 +104,13 @@ SWIG_ZTS_SetPointerZval(zval *z, void *ptr, swig_type_info *type, int newobject
return;
}
if (type->clientdata) {
swig_object_wrapper *value;
if (! (*(int *)(type->clientdata)))
zend_error(E_ERROR, "Type: %s failed to register with zend",type->name);
value=(swig_object_wrapper *)emalloc(sizeof(swig_object_wrapper));
value->ptr=ptr;
value->newobject=newobject;
if (newobject <= 1) {
value->newobject=(newobject & 1);
if ((newobject & 2) == 0) {
/* Just register the pointer as a resource. */
ZEND_REGISTER_RESOURCE(z, value, *(int *)(type->clientdata));
} else {
@ -119,18 +119,32 @@ SWIG_ZTS_SetPointerZval(zval *z, void *ptr, swig_type_info *type, int newobject
* via the "_cPtr" member. This is currently only used by
* directorin typemaps.
*/
value->newobject = 0;
zval *resource;
zend_class_entry **ce = NULL;
const char *type_name = type->name+3; /* +3 so: _p_Foo -> Foo */
size_t type_name_len;
int result;
const char * p;
/* Namespace__Foo -> Foo */
/* FIXME: ugly and goes wrong for classes with __ in their names. */
while ((p = strstr(type_name, "__")) != NULL) {
type_name = p + 2;
}
type_name_len = strlen(type_name);
MAKE_STD_ZVAL(resource);
ZEND_REGISTER_RESOURCE(resource, value, *(int *)(type->clientdata));
zend_class_entry **ce = NULL;
zval *classname;
MAKE_STD_ZVAL(classname);
/* _p_Foo -> Foo */
ZVAL_STRING(classname, (char*)type->name+3, 1);
/* class names are stored in lowercase */
php_strtolower(Z_STRVAL_PP(&classname), Z_STRLEN_PP(&classname));
if (zend_lookup_class(Z_STRVAL_P(classname), Z_STRLEN_P(classname), &ce TSRMLS_CC) != SUCCESS) {
if (SWIG_PREFIX_LEN > 0) {
char * classname = (char*)emalloc(SWIG_PREFIX_LEN + type_name_len + 1);
strcpy(classname, SWIG_PREFIX);
strcpy(classname + SWIG_PREFIX_LEN, type_name);
result = zend_lookup_class(classname, SWIG_PREFIX_LEN + type_name_len, &ce TSRMLS_CC);
efree(classname);
} else {
result = zend_lookup_class((char *)type_name, type_name_len, &ce TSRMLS_CC);
}
if (result != SUCCESS) {
/* class does not exist */
object_init(z);
} else {
@ -139,7 +153,6 @@ SWIG_ZTS_SetPointerZval(zval *z, void *ptr, swig_type_info *type, int newobject
Z_SET_REFCOUNT_P(z, 1);
Z_SET_ISREF_P(z);
zend_hash_update(HASH_OF(z), (char*)"_cPtr", sizeof("_cPtr"), (void*)&resource, sizeof(zval), NULL);
FREE_ZVAL(classname);
}
return;
}
@ -192,7 +205,7 @@ SWIG_ZTS_ConvertResourcePtr(zval *z, swig_type_info *ty, int flags TSRMLS_DC) {
swig_object_wrapper *value;
void *p;
int type;
char *type_name;
const char *type_name;
value = (swig_object_wrapper *) zend_list_find(z->value.lval, &type);
if ( flags & SWIG_POINTER_DISOWN ) {

View file

@ -285,17 +285,18 @@ SwigPyBuiltin_FunpackSetterClosure (PyObject *obj, PyObject *val, void *closure)
SWIGINTERN void
SwigPyStaticVar_dealloc(PyDescrObject *descr) {
_PyObject_GC_UNTRACK(descr);
Py_XDECREF(descr->d_type);
Py_XDECREF(descr->d_name);
Py_XDECREF(PyDescr_TYPE(descr));
Py_XDECREF(PyDescr_NAME(descr));
PyObject_GC_Del(descr);
}
SWIGINTERN PyObject *
SwigPyStaticVar_repr(PyGetSetDescrObject *descr) {
#if PY_VERSION_HEX >= 0x03000000
return PyUnicode_FromFormat("<class attribute '%S' of type '%s'>", descr->d_name, descr->d_type->tp_name);
return PyUnicode_FromFormat("<class attribute '%S' of type '%s'>", PyDescr_NAME(descr), PyDescr_TYPE(descr)->tp_name);
#else
return PyString_FromFormat("<class attribute '%s' of type '%s'>", PyString_AsString(descr->d_name), descr->d_type->tp_name);
return PyString_FromFormat("<class attribute '%s' of type '%s'>", PyString_AsString(PyDescr_NAME(descr)), PyDescr_TYPE(descr)->tp_name);
#endif
}
@ -303,7 +304,7 @@ SWIGINTERN int
SwigPyStaticVar_traverse(PyObject *self, visitproc visit, void *arg) {
PyDescrObject *descr;
descr = (PyDescrObject *)self;
Py_VISIT((PyObject*) descr->d_type);
Py_VISIT((PyObject*) PyDescr_TYPE(descr));
return 0;
}
@ -312,9 +313,9 @@ SwigPyStaticVar_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *SWIGUNU
if (descr->d_getset->get != NULL)
return descr->d_getset->get(obj, descr->d_getset->closure);
#if PY_VERSION_HEX >= 0x03000000
PyErr_Format(PyExc_AttributeError, "attribute '%.300S' of '%.100s' objects is not readable", descr->d_name, descr->d_type->tp_name);
PyErr_Format(PyExc_AttributeError, "attribute '%.300S' of '%.100s' objects is not readable", PyDescr_NAME(descr), PyDescr_TYPE(descr)->tp_name);
#else
PyErr_Format(PyExc_AttributeError, "attribute '%.300s' of '%.100s' objects is not readable", PyString_AsString(descr->d_name), descr->d_type->tp_name);
PyErr_Format(PyExc_AttributeError, "attribute '%.300s' of '%.100s' objects is not readable", PyString_AsString(PyDescr_NAME(descr)), PyDescr_TYPE(descr)->tp_name);
#endif
return NULL;
}
@ -324,75 +325,13 @@ SwigPyStaticVar_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
if (descr->d_getset->set != NULL)
return descr->d_getset->set(obj, value, descr->d_getset->closure);
#if PY_VERSION_HEX >= 0x03000000
PyErr_Format(PyExc_AttributeError, "attribute '%.300S' of '%.100s' objects is not writable", descr->d_name, descr->d_type->tp_name);
PyErr_Format(PyExc_AttributeError, "attribute '%.300S' of '%.100s' objects is not writable", PyDescr_NAME(descr), PyDescr_TYPE(descr)->tp_name);
#else
PyErr_Format(PyExc_AttributeError, "attribute '%.300s' of '%.100s' objects is not writable", PyString_AsString(descr->d_name), descr->d_type->tp_name);
PyErr_Format(PyExc_AttributeError, "attribute '%.300s' of '%.100s' objects is not writable", PyString_AsString(PyDescr_NAME(descr)), PyDescr_TYPE(descr)->tp_name);
#endif
return -1;
}
SWIGINTERN PyTypeObject SwigPyStaticVar_Type = {
#if PY_VERSION_HEX >= 0x03000000
PyVarObject_HEAD_INIT(&PyType_Type, 0)
#else
PyObject_HEAD_INIT(&PyType_Type)
0,
#endif
"swig_static_var_getset_descriptor",
sizeof(PyGetSetDescrObject),
0,
(destructor)SwigPyStaticVar_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
(reprfunc)SwigPyStaticVar_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_CLASS, /* tp_flags */
0, /* tp_doc */
SwigPyStaticVar_traverse, /* 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 */
(descrgetfunc)SwigPyStaticVar_get, /* tp_descr_get */
(descrsetfunc)SwigPyStaticVar_set, /* 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 */
#endif
#ifdef COUNT_ALLOCS
0,0,0,0 /* tp_alloc -> tp_next */
#endif
};
SWIGINTERN int
SwigPyObjectType_setattro(PyTypeObject *type, PyObject *name, PyObject *value) {
PyObject *attribute;
@ -419,16 +358,96 @@ SwigPyObjectType_setattro(PyTypeObject *type, PyObject *name, PyObject *value) {
return -1;
}
SWIGINTERN PyTypeObject*
SwigPyStaticVar_Type(void) {
static PyTypeObject staticvar_type;
static int type_init = 0;
if (!type_init) {
const PyTypeObject tmp = {
/* PyObject header changed in Python 3 */
#if PY_VERSION_HEX >= 0x03000000
PyVarObject_HEAD_INIT(&PyType_Type, 0)
#else
PyObject_HEAD_INIT(&PyType_Type)
0,
#endif
"swig_static_var_getset_descriptor",
sizeof(PyGetSetDescrObject),
0,
(destructor)SwigPyStaticVar_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
(reprfunc)SwigPyStaticVar_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_CLASS, /* tp_flags */
0, /* tp_doc */
SwigPyStaticVar_traverse, /* 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 */
(descrgetfunc)SwigPyStaticVar_get, /* tp_descr_get */
(descrsetfunc)SwigPyStaticVar_set, /* 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 */
#endif
#ifdef COUNT_ALLOCS
0,0,0,0 /* tp_alloc -> tp_next */
#endif
};
staticvar_type = tmp;
type_init = 1;
#if PY_VERSION_HEX < 0x02020000
staticvar_type.ob_type = &PyType_Type;
#else
if (PyType_Ready(&staticvar_type) < 0)
return NULL;
#endif
}
return &staticvar_type;
}
SWIGINTERN PyGetSetDescrObject *
SwigPyStaticVar_new_getset(PyTypeObject *type, PyGetSetDef *getset) {
PyGetSetDescrObject *descr;
descr = (PyGetSetDescrObject *)PyType_GenericAlloc(&SwigPyStaticVar_Type, 0);
descr = (PyGetSetDescrObject *)PyType_GenericAlloc(SwigPyStaticVar_Type(), 0);
assert(descr);
Py_XINCREF(type);
descr->d_type = type;
descr->d_name = PyString_InternFromString(getset->name);
PyDescr_TYPE(descr) = type;
PyDescr_NAME(descr) = PyString_InternFromString(getset->name);
descr->d_getset = getset;
if (descr->d_name == NULL) {
if (PyDescr_NAME(descr) == NULL) {
Py_DECREF(descr);
descr = NULL;
}

View file

@ -250,7 +250,7 @@ namespace Swig {
std::cerr << "This exception was caught by the SWIG unexpected exception handler." << std::endl
<< "Try using %feature(\"director:except\") to avoid reaching this point." << std::endl
<< std::endl
<< "Exception is being re-thrown, program will like abort/terminate." << std::endl;
<< "Exception is being re-thrown, program will likely abort/terminate." << std::endl;
throw;
}

View file

@ -206,3 +206,8 @@ typedef destructor freefunc;
# define SWIGPY_USE_CAPSULE
# define SWIGPY_CAPSULE_NAME ((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION ".type_pointer_capsule" SWIG_TYPE_TABLE_NAME)
#endif
#if PY_VERSION_HEX < 0x03020000
#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type)
#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name)
#endif

View file

@ -143,7 +143,7 @@ swig_varlink_type(void) {
const PyTypeObject tmp = {
/* PyObject header changed in Python 3 */
#if PY_VERSION_HEX >= 0x03000000
PyVarObject_HEAD_INIT(&PyType_Type, 0)
PyVarObject_HEAD_INIT(NULL, 0)
#else
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
@ -186,11 +186,13 @@ swig_varlink_type(void) {
#endif
};
varlink_type = tmp;
/* for Python 3 we already assigned ob_type in PyVarObject_HEAD_INIT() */
#if PY_VERSION_HEX < 0x03000000
varlink_type.ob_type = &PyType_Type;
#endif
type_init = 1;
#if PY_VERSION_HEX < 0x02020000
varlink_type.ob_type = &PyType_Type;
#else
if (PyType_Ready(&varlink_type) < 0)
return NULL;
#endif
}
return &varlink_type;
}
@ -325,7 +327,16 @@ SWIG_init(void) {
PyObject *m, *d, *md;
#if PY_VERSION_HEX >= 0x03000000
static struct PyModuleDef SWIG_module = {
# if PY_VERSION_HEX >= 0x03020000
PyModuleDef_HEAD_INIT,
# else
{
PyObject_HEAD_INIT(NULL)
NULL, /* m_init */
0, /* m_index */
NULL, /* m_copy */
},
# endif
(char *) SWIG_name,
NULL,
-1,

View file

@ -28,7 +28,7 @@ SWIG_AsVal_dec(bool)(PyObject *obj, bool *val)
/* long */
%fragment(SWIG_From_frag(long),"header") {
%define_as(SWIG_From_dec(long), PyInt_FromLong)
%define_as(SWIG_From_dec(long), PyLong_FromLong)
}
%fragment(SWIG_AsVal_frag(long),"header",
@ -80,7 +80,7 @@ SWIGINTERNINLINE PyObject*
SWIG_From_dec(unsigned long)(unsigned long value)
{
return (value > LONG_MAX) ?
PyLong_FromUnsignedLong(value) : PyInt_FromLong(%numeric_cast(value,long));
PyLong_FromUnsignedLong(value) : PyLong_FromLong(%numeric_cast(value,long));
}
}
@ -139,7 +139,7 @@ SWIGINTERNINLINE PyObject*
SWIG_From_dec(long long)(long long value)
{
return ((value < LONG_MIN) || (value > LONG_MAX)) ?
PyLong_FromLongLong(value) : PyInt_FromLong(%numeric_cast(value,long));
PyLong_FromLongLong(value) : PyLong_FromLong(%numeric_cast(value,long));
}
}
@ -193,7 +193,7 @@ SWIGINTERNINLINE PyObject*
SWIG_From_dec(unsigned long long)(unsigned long long value)
{
return (value > LONG_MAX) ?
PyLong_FromUnsignedLongLong(value) : PyInt_FromLong(%numeric_cast(value,long));
PyLong_FromUnsignedLongLong(value) : PyLong_FromLong(%numeric_cast(value,long));
}
}

View file

@ -1070,6 +1070,7 @@ SWIG_Python_GetSwigThis(PyObject *pyobj)
return (SwigPyObject *) pyobj;
#ifdef SWIGPYTHON_BUILTIN
(void)obj;
# ifdef PyWeakref_CheckProxy
if (PyWeakref_CheckProxy(pyobj)) {
pyobj = PyWeakref_GET_OBJECT(pyobj);

View file

@ -168,10 +168,6 @@
swig::SwigPyIterator* iteritems(PyObject **PYTHON_SELF) {
return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
}
PyObject* asdict() {
return swig::traits_from< Map >::asdict(*self);
}
}
#else
@ -292,14 +288,17 @@
void __setitem__(const key_type& key) {
self->erase(key);
}
}
%extend {
void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) {
(*self)[key] = x;
}
PyObject* asdict() {
return swig::traits_from< Map >::asdict(*self);
}
}
%enddef

View file

@ -34,52 +34,7 @@
*/
namespace swig {
%nodirector GC_VALUE;
// We ignore the constructor so that user can never create a GC_VALUE
// manually
%ignore GC_VALUE::GC_VALUE;
struct GC_VALUE {
VALUE inspect() const;
VALUE to_s() const;
GC_VALUE();
protected:
GC_VALUE( const GC_VALUE& );
~GC_VALUE();
};
%exception GC_VALUE {};
%apply VALUE {GC_VALUE};
// Make sure this is the last typecheck done
%typecheck(999999,noblock=1) GC_VALUE, GC_VALUE&,
const GC_VALUE& { $1 = 1; };
/* For input */
%typemap(in,noblock=1) GC_VALUE* (GC_VALUE r), GC_VALUE& (GC_VALUE r) {
r = $input; $1 = &r;
}
/* For output */
%typemap(out,noblock=1) GC_VALUE {
$result = (VALUE)$1;
}
%typemap(out,noblock=1) GC_VALUE*, GC_VALUE const & {
$result = (VALUE)*$1;
}
%ignore LANGUAGE_OBJ;
typedef GC_VALUE LANGUAGE_OBJ;
}
%{
%fragment("GC_VALUE_definition","header") {
namespace swig {
class GC_VALUE {
protected:
@ -213,7 +168,7 @@ namespace swig {
}
#define GC_VALUE_CMP( op_id, op, cmp, cmpval ) \
%#define GC_VALUE_CMP( op_id, op, cmp, cmpval ) \
bool op( const GC_VALUE& other ) const \
{ \
if ( FIXNUM_P(_obj) && FIXNUM_P(other._obj) ) \
@ -253,14 +208,14 @@ namespace swig {
GC_VALUE_CMP( le_id, operator<=, <=, <= 0 )
GC_VALUE_CMP( gt_id, operator>, > , > 0 )
GC_VALUE_CMP( ge_id, operator>=, >=, >= 0 )
#undef GC_VALUE_CMP
%#undef GC_VALUE_CMP
bool operator!=( const GC_VALUE& other )
{
return !(this->operator==(other));
}
#define GC_VALUE_UNARY( proc_id, op ) \
%#define GC_VALUE_UNARY( proc_id, op ) \
GC_VALUE op() const \
{ \
VALUE ret = Qnil; \
@ -280,9 +235,9 @@ namespace swig {
GC_VALUE_UNARY( pos_id, operator+ )
GC_VALUE_UNARY( neg_id, operator- )
GC_VALUE_UNARY( inv_id, operator~ )
#undef GC_VALUE_BINARY
%#undef GC_VALUE_BINARY
#define GC_VALUE_BINARY( proc_id, op ) \
%#define GC_VALUE_BINARY( proc_id, op ) \
GC_VALUE op( const GC_VALUE& other ) const \
{ \
VALUE ret = Qnil; \
@ -311,7 +266,7 @@ namespace swig {
GC_VALUE_BINARY( lshift_id, operator<< );
GC_VALUE_BINARY( rshift_id, operator>> );
#undef GC_VALUE_BINARY
%#undef GC_VALUE_BINARY
};
@ -345,7 +300,53 @@ namespace swig {
} // namespace swig
%}
} // %fragment(GC_VALUE_definition)
namespace swig {
%apply VALUE {GC_VALUE};
// Make sure this is the last typecheck done
%typecheck(999999,fragment="GC_VALUE_definition",noblock=1) GC_VALUE, GC_VALUE&,
const GC_VALUE& { $1 = 1; };
/* For input */
%typemap(in,fragment="GC_VALUE_definition",noblock=1) GC_VALUE* (GC_VALUE r), GC_VALUE& (GC_VALUE r) {
r = $input; $1 = &r;
}
/* For output */
%typemap(out,fragment="GC_VALUE_definition",noblock=1) GC_VALUE {
$result = (VALUE)$1;
}
%typemap(out,fragment="GC_VALUE_definition",noblock=1) GC_VALUE*, GC_VALUE const & {
$result = (VALUE)*$1;
}
%nodirector GC_VALUE;
// We ignore the constructor so that user can never create a GC_VALUE
// manually
%ignore GC_VALUE::GC_VALUE;
struct GC_VALUE {
VALUE inspect() const;
VALUE to_s() const;
GC_VALUE();
protected:
GC_VALUE( const GC_VALUE& );
~GC_VALUE();
};
%exception GC_VALUE {};
%ignore LANGUAGE_OBJ;
typedef GC_VALUE LANGUAGE_OBJ;
}
%init {
@ -359,7 +360,7 @@ namespace swig {
// These functions may be invoked as a need of the from(), asval(),
// asptr() and as() template functors, usually used in %typemaps.
//
%fragment(SWIG_Traits_frag(swig::GC_VALUE),"header",fragment="StdTraits") {
%fragment(SWIG_Traits_frag(swig::GC_VALUE),"header",fragment="StdTraits",fragment="GC_VALUE_definition") {
namespace swig {
template <> struct traits<GC_VALUE > {
typedef value_category category;

View file

@ -972,7 +972,8 @@ namespace swig
%fragment("StdSequenceTraits","header",
fragment="StdTraits",
fragment="RubySequence_Cont")
fragment="RubySequence_Cont",
fragment="GC_VALUE_definition")
{
namespace swig {
template <class RubySeq, class Seq>

View file

@ -12,7 +12,7 @@
%include <std_common.i>
%fragment("ConstIterator","header") {
%fragment("ConstIterator","header",fragment="GC_VALUE_definition") {
namespace swig {
struct stop_iteration {
};

View file

@ -200,66 +200,3 @@ namespace swig {
}
}
// Define GC marking template traits for a container type
%define %create_mark_traits(Type)
%{
namespace swig {
template <class T>
struct mark_traits {
typedef typename Type<T >::const_iterator const_iterator;
inline void operator()(const Type<T >& c ) const
{
const_iterator i = c.begin();
const_iterator e = c.end();
for ( ; i != e; ++i )
{
rb_gc_mark( swig::from( &(*i) ) );
}
}
};
// Partial specializations for classes that requires no GC marking
// or a special GC marking algorithm.
template< >
struct mark_traits<bool> {
inline void operator()(const Type<bool >& c ) const {}
};
template< >
struct mark_traits<char> {
inline void operator()(const Type<char >& c ) const {}
};
template< >
struct mark_traits<int> {
inline void operator()(const Type<int >& c ) const {}
};
template< >
struct mark_traits<unsigned> {
inline void operator()(const Type<unsigned >& c ) const {}
};
template< >
struct mark_traits<GC_VALUE> {
typedef Type<GC_VALUE >::const_iterator const_iterator;
inline void operator()(const Type<GC_VALUE >& c ) const {
const_iterator i = c.begin();
const_iterator e = c.end();
for ( ; i != e; ++i )
{
VALUE v = *i;
if ( FIXNUM_P(v) || SPECIAL_CONST_P(v) || SYMBOL_P(v) ||
( BUILTIN_TYPE(v) == T_NONE ) ) continue;
rb_gc_mark( v );
}
}
};
}
%}
%enddef

View file

@ -83,7 +83,7 @@ namespace swig {
}
%fragment("StdFunctors","header",fragment="StdTraits")
%fragment("StdFunctors","header",fragment="StdTraits",fragment="GC_VALUE_definition")
{
namespace swig {

View file

@ -500,12 +500,6 @@ namespace std {
}
}
/* Typemap for variable length arguments sentinel value. Used
by the %varargs directive. */
%typemap(in,numinputs=0) SWIGTYPE *VARARGS_SENTINEL, SWIGTYPE VARARGS_SENTINEL "";
/* -----------------------------------------------------------------------------
* Overloading support
* ----------------------------------------------------------------------------- */

View file

@ -277,7 +277,7 @@ SWIG_Tcl_SetModule(Tcl_Interp *interp, swig_module_info *module) {
/* create a new pointer */
data = SWIG_PackData(buf, &module, sizeof(swig_type_info **));
*data = 0;
Tcl_SetVar(interp, (char *)"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME, buf, 0);
Tcl_SetVar(interp, (char *)"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME, buf, TCL_GLOBAL_ONLY);
}
/* -----------------------------------------------------------------------------*

View file

@ -7,7 +7,7 @@
* ------------------------------------------------------------ */
/*
in Tcl we need to pass the interp value, so, we define the decl/call
In Tcl we need to pass the interp value, so we define the decl/call
macros as needed.
*/
@ -15,13 +15,13 @@
#define SWIG_AS_CALL_ARGS SWIG_TCL_CALL_ARGS_2
/* Include fundamental fragemt definitions */
/* Include fundamental fragment definitions */
%include <typemaps/fragments.swg>
/* Look for user fragments file. */
%include <tclfragments.swg>
/* Tcl fragments for primitve types */
/* Tcl fragments for primitive types */
%include <tclprimtypes.swg>
/* Tcl fragments for char* strings */
@ -32,7 +32,7 @@
* Unified typemap section
* ------------------------------------------------------------ */
/* No director supported in Tcl */
/* No director support in Tcl */
#ifdef SWIG_DIRECTOR_TYPEMAPS
#undef SWIG_DIRECTOR_TYPEMAPS
#endif

View file

@ -22,8 +22,8 @@
which can always be redefined in the swig target language if needed.
The fragments for the following types, however, need to be defined
in the target language always:
The fragments for the following types, however, always need to be
defined in the target language:
long
unsigned long
@ -40,7 +40,7 @@
%typemaps_primitive(CheckCode, Type)
which generate the typemaps for a primitive type with a given
which generates the typemaps for a primitive type with a given
checkcode. It is assumed that the primitive type is 'normalized' and
the corresponding SWIG_AsVal(Type) and SWIG_From(Type) methods are
provided via fragments.

View file

@ -559,11 +559,6 @@
* --- Special typemaps ---
* ------------------------------------------------------------ */
/* VARARGS_SENTINEL typemap. Used by the %varargs directive. */
%typemap(in,numinputs=0) SWIGTYPE *VARARGS_SENTINEL, SWIGTYPE VARARGS_SENTINEL "";
/* DISOWN typemap */
%typemap(in, noblock=1) SWIGTYPE *DISOWN (int res = 0) {

2
README
View file

@ -1,6 +1,6 @@
SWIG (Simplified Wrapper and Interface Generator)
Version: 2.0.4 (in progress)
Version: 2.0.5 (in progress)
Tagline: SWIG is a compiler that integrates C and C++ with languages
including Perl, Python, Tcl, Ruby, PHP, Java, Ocaml, Lua,

View file

@ -4,6 +4,18 @@ and CHANGES files.
Release Notes
=============
SWIG-2.0.4 summary:
- This is mainly a Python oriented release including support for Python
built-in types for superior performance with the new -builtin option.
The -builtin option is especially suitable for performance-critical
libraries and applications that call wrapped methods repeatedly.
See the python-specific chapter of the SWIG manual for more info.
- Python 3.2 support has also been added and various Python bugs have
been fixed.
- Octave 3.4 support has also been added.
- There are also the usual minor generic improvements, as well as bug
fixes and enhancements for D, Guile, Lua, Octave, Perl and Tcl.
SWIG-2.0.3 summary:
- A bug fix release including a couple of fixes for regressions in the
2.0 series.

View file

@ -2627,10 +2627,15 @@ varargs_parms : parms { $$ = $1; }
Swig_error(cparse_file, cparse_line,"Argument count in %%varargs must be positive.\n");
$$ = 0;
} else {
String *name = Getattr($3, "name");
$$ = Copy($3);
Setattr($$,"name","VARARGS_SENTINEL");
for (i = 0; i < n; i++) {
if (name)
Setattr($$, "name", NewStringf("%s%d", name, n));
for (i = 1; i < n; i++) {
p = Copy($3);
name = Getattr(p, "name");
if (name)
Setattr(p, "name", NewStringf("%s%d", name, n-i));
set_nextSibling(p,$$);
Delete($$);
$$ = p;
@ -5019,7 +5024,7 @@ notso_direct_declarator : idcolon {
$$.have_parms = 0;
}
/* This generate a shift-reduce conflict with constructors */
/* This generates a shift-reduce conflict with constructors */
| LPAREN idcolon RPAREN {
$$.id = Char($2);
$$.type = 0;
@ -5330,26 +5335,26 @@ direct_abstract_declarator : direct_abstract_declarator LBRACKET RBRACKET {
pointer : STAR type_qualifier pointer {
$$ = NewStringEmpty();
SwigType_add_pointer($$);
SwigType_push($$,$2);
SwigType_push($$,$3);
Delete($3);
$$ = NewStringEmpty();
SwigType_add_pointer($$);
SwigType_push($$,$2);
SwigType_push($$,$3);
Delete($3);
}
| STAR pointer {
$$ = NewStringEmpty();
SwigType_add_pointer($$);
SwigType_push($$,$2);
Delete($2);
}
}
| STAR type_qualifier {
$$ = NewStringEmpty();
SwigType_add_pointer($$);
SwigType_push($$,$2);
$$ = NewStringEmpty();
SwigType_add_pointer($$);
SwigType_push($$,$2);
}
| STAR {
$$ = NewStringEmpty();
SwigType_add_pointer($$);
$$ = NewStringEmpty();
SwigType_add_pointer($$);
}
;
@ -5377,7 +5382,7 @@ type : rawtype {
}
;
rawtype : type_qualifier type_right {
rawtype : type_qualifier type_right {
$$ = $2;
SwigType_push($$,$1);
}
@ -5395,7 +5400,7 @@ rawtype : type_qualifier type_right {
type_right : primitive_type { $$ = $1;
/* Printf(stdout,"primitive = '%s'\n", $$);*/
}
}
| TYPE_BOOL { $$ = $1; }
| TYPE_VOID { $$ = $1; }
| TYPE_TYPEDEF template_decl { $$ = NewStringf("%s%s",$1,$2); }

View file

@ -3990,7 +3990,7 @@ public:
Printf(w->code, "jenv->%s(Swig::jclass_%s, Swig::director_methids[%s], %s);\n", methop, imclass_name, methid, jupcall_args);
Printf(w->code, "if (jenv->ExceptionOccurred()) return $null;\n");
Printf(w->code, "if (jenv->ExceptionCheck() == JNI_TRUE) return $null;\n");
if (!is_void) {
String *jresult_str = NewString("jresult");

View file

@ -15,9 +15,16 @@ char cvsroot_octave_cxx[] = "$Id$";
#include "swigmod.h"
static bool global_load = true;
static String *global_name = 0;
static String *op_prefix = 0;
static const char *usage = (char *) "\
Octave Options (available with -octave)\n\
[no additional options]\n\
-global - Load all symbols into the global namespace [default]\n\
-globals <name> - Set <name> used to access C global variables [default: 'cvar']\n\
-noglobal - Do not load all symbols into the global namespace\n\
-opprefix <str> - Prefix <str> for global operator functions [default: 'op_']\n\
\n";
@ -65,10 +72,39 @@ public:
if (argv[i]) {
if (strcmp(argv[i], "-help") == 0) {
fputs(usage, stdout);
}
} else if (strcmp(argv[i], "-global") == 0) {
global_load = true;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-noglobal") == 0) {
global_load = false;
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-globals") == 0) {
if (argv[i + 1]) {
global_name = NewString(argv[i + 1]);
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
i++;
} else {
Swig_arg_error();
}
} else if (strcmp(argv[i], "-opprefix") == 0) {
if (argv[i + 1]) {
op_prefix = NewString(argv[i + 1]);
Swig_mark_arg(i);
Swig_mark_arg(i + 1);
i++;
} else {
Swig_arg_error();
}
}
}
}
if (!global_name)
global_name = NewString("cvar");
if (!op_prefix)
op_prefix = NewString("op_");
SWIG_library_directory("octave");
Preprocessor_define("SWIGOCTAVE 1", 0);
SWIG_config_file("octave.swg");
@ -131,6 +167,11 @@ public:
Printf(f_runtime, "#define SWIG_name_d \"%s\"\n", module);
Printf(f_runtime, "#define SWIG_name %s\n", module);
Printf(f_runtime, "\n");
Printf(f_runtime, "#define SWIG_global_load %s\n", global_load ? "true" : "false");
Printf(f_runtime, "#define SWIG_global_name \"%s\"\n", global_name);
Printf(f_runtime, "#define SWIG_op_prefix \"%s\"\n", op_prefix);
if (directorsEnabled()) {
Printf(f_runtime, "#define SWIG_DIRECTORS\n");
Swig_banner(f_directors_h);

View file

@ -328,6 +328,9 @@ public:
if (!prefix)
prefix = NewStringEmpty();
Printf(f_runtime, "#define SWIG_PREFIX \"%s\"\n", prefix);
Printf(f_runtime, "#define SWIG_PREFIX_LEN %lu\n", (unsigned long)Len(prefix));
if (directorsEnabled()) {
Swig_banner(f_directors_h);
Printf(f_directors_h, "\n");
@ -803,8 +806,8 @@ public:
Wrapper_add_local(f, "director", "Swig::Director *director = 0");
Printf(f->code, "director = dynamic_cast<Swig::Director*>(arg1);\n");
Wrapper_add_local(f, "upcall", "bool upcall = false");
Printf(f->code, "upcall = !director->swig_is_overridden_method((char *)\"%s\", (char *)\"%s\");\n",
Swig_class_name(Swig_methodclass(n)), name);
Printf(f->code, "upcall = !director->swig_is_overridden_method((char *)\"%s%s\", (char *)\"%s\");\n",
prefix, Swig_class_name(Swig_methodclass(n)), name);
}
// This generated code may be called:
@ -1655,7 +1658,7 @@ public:
Printf(output, "\t\t$this->%s=%s;\n", SWIG_PTR, invoke);
} else {
String *classname = Swig_class_name(current_class);
Printf(output, "\t\treturn new %s(%s);\n", classname, invoke);
Printf(output, "\t\treturn new %s%s(%s);\n", prefix, classname, invoke);
}
}
} else {
@ -1682,36 +1685,26 @@ public:
if (Cmp(invoke, "$r") != 0)
Printf(output, "\t\t$r=%s;\n", invoke);
if (Len(ret_types) == 1) {
/* If it has an abstract base, then we can't create a new
* base object. */
int hasabstractbase = 0;
Node *bases = Getattr(Swig_methodclass(n), "bases");
if (bases) {
Iterator i = First(bases);
while(i.item) {
if (Getattr(i.item, "abstract")) {
hasabstractbase = 1;
break;
}
i = Next(i);
}
/* If d is abstract we can't create a new wrapper type d. */
Node * d_class = classLookup(d);
int is_abstract = 0;
if (Getattr(d_class, "abstract")) {
is_abstract = 1;
}
if (newobject || !hasabstractbase) {
/*
* _p_Foo -> Foo, _p_ns__Bar -> Bar
* TODO: do this in a more elegant way
*/
if (newobject || !is_abstract) {
Printf(output, "\t\tif (is_resource($r)) {\n");
if (Getattr(classLookup(Getattr(n, "type")), "module")) {
/*
* _p_Foo -> Foo, _p_ns__Bar -> Bar
* TODO: do this in a more elegant way
*/
if (Len(prefix) == 0) {
Printf(output, "\t\t\t$c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));\n");
} else {
Printf(output, "\t\t\t$c='%s'.substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));\n", prefix);
}
Printf(output, "\t\t\tif (!class_exists($c)) {\n");
Printf(output, "\t\t\t\treturn new %s%s($r);\n", prefix, Getattr(classLookup(d), "sym:name"));
Printf(output, "\t\t\t}\n");
Printf(output, "\t\t\treturn new $c($r);\n");
Printf(output, "\t\t\tif (class_exists($c)) return new $c($r);\n");
Printf(output, "\t\t\treturn new %s%s($r);\n", prefix, Getattr(classLookup(d), "sym:name"));
} else {
Printf(output, "\t\t\t$c = new stdClass();\n");
Printf(output, "\t\t\t$c->"SWIG_PTR" = $r;\n");

View file

@ -3233,6 +3233,13 @@ public:
Printf(f_init, " builtin_basetype = SWIG_MangledTypeQuery(\"%s\");\n", base_mname);
Printv(f_init, " if (builtin_basetype && builtin_basetype->clientdata && ((SwigPyClientData*) builtin_basetype->clientdata)->pytype) {\n", NIL);
Printv(f_init, " builtin_bases[builtin_base_count++] = ((SwigPyClientData*) builtin_basetype->clientdata)->pytype;\n", NIL);
Printv(f_init, " } else {\n", NIL);
Printf(f_init, " PyErr_SetString(PyExc_TypeError, \"Could not create type '%s' as base '%s' has not been initialized.\\n\");\n", symname, bname);
Printv(f_init, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
Printv(f_init, " return NULL;\n", NIL);
Printv(f_init, "#else\n", NIL);
Printv(f_init, " return;\n", NIL);
Printv(f_init, "#endif\n", NIL);
Printv(f_init, " }\n", NIL);
Delete(base_name);
Delete(base_mname);
@ -3538,7 +3545,7 @@ public:
Printf(f, "SWIGINTERN SwigPyClientData %s_clientdata = {%s, 0, 0, 0, 0, 0, (PyTypeObject *)&%s_type};\n\n", templ, clientdata_klass, templ);
Printv(f_init, " if (PyType_Ready(builtin_pytype) < 0) {\n", NIL);
Printf(f_init, " PyErr_SetString(PyExc_TypeError, \"Couldn't create type '%s'\");\n", symname);
Printf(f_init, " PyErr_SetString(PyExc_TypeError, \"Could not create type '%s'.\");\n", symname);
Printv(f_init, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
Printv(f_init, " return NULL;\n", NIL);
Printv(f_init, "#else\n", NIL);

5
TODO
View file

@ -198,8 +198,6 @@ PHP
**** Look at moving to using the UTL.
*** Director support.
** When returning wrapped objects via alternate constructors if that
pointer value already exists "out there" as a resource we should
use the same resource, we can't have multiple ref-counted resources
@ -373,6 +371,3 @@ Documentation
*** Perl, Python, Tcl modules.
*** add section for Perl module support for operator overloading
** Add section on WAD.

View file

@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script.
dnl The macros which aren't shipped with the autotools are stored in the
dnl Tools/config directory in .m4 files.
AC_INIT([swig],[2.0.4],[http://www.swig.org])
AC_INIT([swig],[2.0.5],[http://www.swig.org])
dnl NB: When this requirement is increased to 2.60 or later, AC_PROG_SED
dnl definition below can be removed