add support for multi-inheritance at the python side and performance tunings
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@7819 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
253d0dd65a
commit
42277fcfd7
9 changed files with 426 additions and 174 deletions
|
|
@ -1,6 +1,69 @@
|
|||
Version 1.3.28 (unreleased)
|
||||
===========================
|
||||
|
||||
11/07/2005: mmatus
|
||||
|
||||
[Python] Adding proper support for multi-inheritance in
|
||||
the python side, ie, if you have two C++ wrapped class, Foo
|
||||
and Bar, now:
|
||||
|
||||
class MyPythonClass(Foo,Bar):
|
||||
....
|
||||
|
||||
will properly work, even with directors, and the
|
||||
deallocation of Foo.this and Bar.this will follow
|
||||
correctly. Before, since a class can only have one 'this'
|
||||
instance (not as in C++), only the last base class was
|
||||
properly deletted, or detected with directors.
|
||||
|
||||
Now the self.this element can be a list, which will
|
||||
contain the C++ instance pointers for all the base
|
||||
classes.
|
||||
|
||||
- Now the 'this' pointer is responsible for deallocating
|
||||
the C++ instance, and the __del__ method is not emitted
|
||||
unless the user preppend/append some code to it.
|
||||
|
||||
- Swig now can detect memory leaks, ie, if you still
|
||||
use the non-shadow module, and type something like
|
||||
|
||||
import _example
|
||||
f = _example.new_Foo()
|
||||
|
||||
and forgot to call _example.delete_Foo(f), then swig
|
||||
will tell you that there is a memory leak.
|
||||
|
||||
Otherwise, if you always use the shadow module, probably
|
||||
you will never ever see this warning unless there is
|
||||
something wrong inside the swig wrapping code.
|
||||
|
||||
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
If you overloaded the __del__ method, and call the base
|
||||
one without a try block, as in
|
||||
|
||||
class MyClass(SwigClass):
|
||||
|
||||
def __del__(self):
|
||||
<your code here>
|
||||
SwigClass.__del__(self)
|
||||
|
||||
python could complain that the method SwigClass.__del__ is
|
||||
undefined. Try to use instead:
|
||||
|
||||
def __del__(self):
|
||||
<your code here>
|
||||
try: SwigClass.__del__(self)
|
||||
except: pass
|
||||
|
||||
or simply
|
||||
|
||||
def __del__(self):
|
||||
<your code here>
|
||||
|
||||
|
||||
|
||||
11/02/2005: mmatus
|
||||
|
||||
[Python] Adding more fun to STL/STD containers, now you
|
||||
|
|
@ -84,7 +147,7 @@ Version 1.3.28 (unreleased)
|
|||
In general the sequence method __iter__ will call
|
||||
'iterator()', returning the native C++ iterator, but in
|
||||
maps it will call 'key_iterator()', maintaining
|
||||
backcompatibilty.
|
||||
backward compatibility.
|
||||
|
||||
Hence, for std::maps, you can play then with the native
|
||||
C++ iterator, which value is a (key, value) pair, by
|
||||
|
|
@ -153,12 +216,12 @@ Version 1.3.28 (unreleased)
|
|||
|
||||
- With this change, and the other ones in the
|
||||
PySwigObject type, which now carries the thisown and
|
||||
swig_type_info pointer, the generated code shoudl be as
|
||||
swig_type_info pointer, the generated code should be as
|
||||
fast as boost::Python and/or the other python wrappers
|
||||
based in pure Python/C API calls.
|
||||
|
||||
As a reference, the profiletest_runme.py example, which
|
||||
does a simple call function many times:
|
||||
does a simple call function many times, such as this code:
|
||||
|
||||
import profiletest
|
||||
|
||||
|
|
@ -172,14 +235,20 @@ Version 1.3.28 (unreleased)
|
|||
produces the following times
|
||||
|
||||
nomodern modern
|
||||
swig-1.3.26 25.9s 7.6s
|
||||
swig-CVS 3.4s 3.3s
|
||||
swig-1.3.26 19.70s 5.98s
|
||||
swig-CVS 0.99s 0.98s
|
||||
|
||||
|
||||
Clearly, there is a large improvement for the python
|
||||
'nomodern' mode. Still, the 'modern' mode is around
|
||||
twice faster than before.
|
||||
6 times faster than before. For the same test, but
|
||||
using the non-shadow version of the module, we get
|
||||
|
||||
_profiletest (non-shadow)
|
||||
swig-1.3.26 0.80s
|
||||
swig-CVS 0.60s
|
||||
|
||||
Hence, now the proxy overhead is almost insignificant.
|
||||
|
||||
|
||||
10/31/2005: mmatus
|
||||
|
|
@ -204,7 +273,7 @@ Version 1.3.28 (unreleased)
|
|||
print self.this.own()
|
||||
>>> True
|
||||
|
||||
- Support for iterartors in STL/STD containers, for example, if you have
|
||||
- Support for iterators in STL/STD containers, for example, if you have
|
||||
|
||||
%template<set_string> std::set<std::string>;
|
||||
|
||||
|
|
@ -375,7 +444,7 @@ Version 1.3.28 (unreleased)
|
|||
|
||||
- uniform the names for the setter and getter methods in
|
||||
perl,tcl,ruby and python, so, the attribute.i library
|
||||
can work accross them.
|
||||
can work across them.
|
||||
|
||||
- see the li_attribute.i test-case or the library file
|
||||
|
||||
|
|
@ -388,7 +457,7 @@ Version 1.3.28 (unreleased)
|
|||
|
||||
10/24/2005: mmatus
|
||||
|
||||
- Perl uses now the unified typemap libray.
|
||||
- Perl uses now the unified typemap library.
|
||||
|
||||
- Changes in ruby to use the $track option in typemaps.
|
||||
|
||||
|
|
@ -439,7 +508,7 @@ Version 1.3.28 (unreleased)
|
|||
perl5/perlstrings.swg
|
||||
|
||||
|
||||
The rest fo the files, such as carray.i, are mostly one
|
||||
The rest of the files, such as carray.i, are mostly one
|
||||
line files that include the proper typemap library
|
||||
version.
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,12 @@
|
|||
|
||||
class Foo {
|
||||
public:
|
||||
virtual ~Foo() {}
|
||||
virtual std::string ping() { return "Foo::ping()"; }
|
||||
virtual std::string pong() { return "Foo::pong();" + ping(); }
|
||||
virtual ~Foo() {}
|
||||
virtual std::string ping() { return "Foo::ping()"; }
|
||||
virtual std::string pong() { return "Foo::pong();" + ping(); }
|
||||
|
||||
static Foo* get_self(Foo *self) {return self;}
|
||||
|
||||
};
|
||||
|
||||
%}
|
||||
|
|
@ -18,9 +21,12 @@
|
|||
|
||||
class Foo {
|
||||
public:
|
||||
virtual ~Foo() {}
|
||||
virtual std::string ping() { return "Foo::ping()"; }
|
||||
virtual std::string pong() { return "Foo::pong();" + ping(); }
|
||||
virtual ~Foo();
|
||||
virtual std::string ping();
|
||||
virtual std::string pong();
|
||||
|
||||
static Foo* get_self(Foo *self);
|
||||
|
||||
};
|
||||
|
||||
%{
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ b = director_basic.Bar(3)
|
|||
d = director_basic.MyClass()
|
||||
c = PyClass()
|
||||
|
||||
cc = PyClass.get_self(c)
|
||||
dd = PyClass.get_self(d)
|
||||
cc = director_basic.MyClass_get_self(c)
|
||||
dd = director_basic.MyClass_get_self(d)
|
||||
|
||||
bc = cc.cmethod(b)
|
||||
bd = dd.cmethod(b)
|
||||
|
|
@ -51,3 +51,40 @@ if bc.x != 34:
|
|||
if bd.x != 16:
|
||||
raise RuntimeError
|
||||
|
||||
|
||||
|
||||
class PyMulti(director_basic.Foo, director_basic.MyClass):
|
||||
def __init__(self):
|
||||
director_basic.Foo.__init__(self)
|
||||
director_basic.MyClass.__init__(self)
|
||||
pass
|
||||
|
||||
|
||||
def vmethod(self, b):
|
||||
b.x += 31
|
||||
return b
|
||||
|
||||
|
||||
def ping(self):
|
||||
return "PyFoo::ping()"
|
||||
|
||||
a = 0
|
||||
for i in range(0,100):
|
||||
pymult = PyMulti()
|
||||
pymult.pong()
|
||||
del pymult
|
||||
|
||||
|
||||
|
||||
pymult = PyMulti()
|
||||
|
||||
|
||||
|
||||
|
||||
p1 = director_basic.Foo_get_self(pymult)
|
||||
p2 = director_basic.MyClass_get_self(pymult)
|
||||
|
||||
p1.ping()
|
||||
p2.vmethod(bc)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ from director_finalizer import *
|
|||
class MyFoo(Foo):
|
||||
def __del__(self):
|
||||
self.orStatus(2)
|
||||
Foo.__del__(self)
|
||||
try: Foo.__del__(self)
|
||||
except: pass
|
||||
|
||||
|
||||
resetStatus()
|
||||
|
|
|
|||
|
|
@ -4,3 +4,6 @@ a = A()
|
|||
b = B()
|
||||
|
||||
b.acquire(a)
|
||||
|
||||
if a.this.own():
|
||||
raise RuntimeError
|
||||
|
|
|
|||
|
|
@ -1,27 +1,29 @@
|
|||
import _profiletest
|
||||
import profiletest
|
||||
|
||||
a = profiletest.A()
|
||||
b = profiletest.B()
|
||||
fn = b.fn
|
||||
i = 50000
|
||||
while i:
|
||||
a = b.fn(a) #1
|
||||
a = b.fn(a) #2
|
||||
a = b.fn(a) #3
|
||||
a = b.fn(a) #4
|
||||
a = b.fn(a) #5
|
||||
a = b.fn(a) #6
|
||||
a = b.fn(a) #7
|
||||
a = b.fn(a) #8
|
||||
a = b.fn(a) #9
|
||||
a = b.fn(a) #10
|
||||
a = b.fn(a) #1
|
||||
a = b.fn(a) #2
|
||||
a = b.fn(a) #3
|
||||
a = b.fn(a) #4
|
||||
a = b.fn(a) #5
|
||||
a = b.fn(a) #6
|
||||
a = b.fn(a) #7
|
||||
a = b.fn(a) #8
|
||||
a = b.fn(a) #9
|
||||
a = b.fn(a) #20
|
||||
a = fn(a) #1
|
||||
a = fn(a) #2
|
||||
a = fn(a) #3
|
||||
a = fn(a) #4
|
||||
a = fn(a) #5
|
||||
a = fn(a) #6
|
||||
a = fn(a) #7
|
||||
a = fn(a) #8
|
||||
a = fn(a) #9
|
||||
a = fn(a) #10
|
||||
a = fn(a) #1
|
||||
a = fn(a) #2
|
||||
a = fn(a) #3
|
||||
a = fn(a) #4
|
||||
a = fn(a) #5
|
||||
a = fn(a) #6
|
||||
a = fn(a) #7
|
||||
a = fn(a) #8
|
||||
a = fn(a) #9
|
||||
a = fn(a) #20
|
||||
i -= 1
|
||||
|
|
|
|||
54
SWIG/Examples/test-suite/python/profiletestc_runme.py
Normal file
54
SWIG/Examples/test-suite/python/profiletestc_runme.py
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import _profiletest
|
||||
#import profiletest
|
||||
|
||||
pa = _profiletest.new_A()
|
||||
pb = _profiletest.new_B()
|
||||
fn = _profiletest.B_fn
|
||||
destroy = _profiletest.delete_A
|
||||
i = 50000
|
||||
a = pa
|
||||
while i:
|
||||
a = fn(pb,a) #1
|
||||
destroy(a)
|
||||
a = fn(pb,a) #2
|
||||
destroy(a)
|
||||
a = fn(pb,a) #3
|
||||
destroy(a)
|
||||
a = fn(pb,a) #4
|
||||
destroy(a)
|
||||
a = fn(pb,a) #5
|
||||
destroy(a)
|
||||
a = fn(pb,a) #6
|
||||
destroy(a)
|
||||
a = fn(pb,a) #7
|
||||
destroy(a)
|
||||
a = fn(pb,a) #8
|
||||
destroy(a)
|
||||
a = fn(pb,a) #9
|
||||
destroy(a)
|
||||
a = fn(pb,a) #10
|
||||
destroy(a)
|
||||
a = fn(pb,a) #1
|
||||
destroy(a)
|
||||
a = fn(pb,a) #2
|
||||
destroy(a)
|
||||
a = fn(pb,a) #3
|
||||
destroy(a)
|
||||
a = fn(pb,a) #4
|
||||
destroy(a)
|
||||
a = fn(pb,a) #5
|
||||
destroy(a)
|
||||
a = fn(pb,a) #6
|
||||
destroy(a)
|
||||
a = fn(pb,a) #7
|
||||
destroy(a)
|
||||
a = fn(pb,a) #8
|
||||
destroy(a)
|
||||
a = fn(pb,a) #9
|
||||
destroy(a)
|
||||
a = fn(pb,a) #20
|
||||
destroy(a)
|
||||
i -= 1
|
||||
|
||||
_profiletest.delete_A(pa)
|
||||
_profiletest.delete_B(pb)
|
||||
|
|
@ -49,7 +49,9 @@ SWIG_Python_ErrorType(int code) {
|
|||
|
||||
SWIGINTERNINLINE PyObject *
|
||||
SWIG_Python_ExceptionType(swig_type_info *desc) {
|
||||
return (desc && desc->clientdata ? (PyObject *)(desc->clientdata) : PyExc_RuntimeError);
|
||||
PySwigClientData *data = desc ? (PySwigClientData *) desc->clientdata : 0;
|
||||
PyObject *klass = data ? data->klass : 0;
|
||||
return (klass ? klass : PyExc_RuntimeError);
|
||||
}
|
||||
|
||||
SWIGINTERN void
|
||||
|
|
|
|||
|
|
@ -59,15 +59,19 @@ extern "C" {
|
|||
|
||||
|
||||
/* PySwigObject */
|
||||
typedef struct {
|
||||
PyObject *klass;
|
||||
PyObject *newargs;
|
||||
PyObject *destroy;
|
||||
} PySwigClientData;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
void *ptr;
|
||||
swig_type_info *ty;
|
||||
int own;
|
||||
PyObject *next;
|
||||
} PySwigObject;
|
||||
|
||||
|
||||
|
||||
|
||||
SWIGRUNTIME PyObject *
|
||||
|
|
@ -108,13 +112,14 @@ SWIGRUNTIME PyObject *
|
|||
PySwigObject_repr(PySwigObject *v)
|
||||
{
|
||||
const char *name = SWIG_TypePrettyName(v->ty);
|
||||
PyObject *hex = PySwigObject_hex(v);
|
||||
if (name) {
|
||||
return PyString_FromFormat("<Swig Object of type '%s' at 0x%s>", name, PyString_AsString(hex));
|
||||
} else {
|
||||
return PyString_FromFormat("<Swig Object at 0x%s>", PyString_AsString(hex));
|
||||
}
|
||||
PyObject *hex = PySwigObject_hex(v);
|
||||
PyObject *repr = PyString_FromFormat("<Swig Object of type '%s' at 0x%s>", name, PyString_AsString(hex));
|
||||
Py_DECREF(hex);
|
||||
if (v->next) {
|
||||
PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next);
|
||||
PyString_ConcatAndDel(&repr,nrep);
|
||||
}
|
||||
return repr;
|
||||
}
|
||||
|
||||
SWIGRUNTIME int
|
||||
|
|
@ -130,7 +135,6 @@ PySwigObject_print(PySwigObject *v, FILE *fp, int SWIGUNUSED flags)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
SWIGRUNTIME PyObject *
|
||||
PySwigObject_str(PySwigObject *v)
|
||||
{
|
||||
|
|
@ -158,47 +162,106 @@ PySwigObject_Check(PyObject *op) {
|
|||
SWIGRUNTIME void
|
||||
PySwigObject_dealloc(PyObject *v)
|
||||
{
|
||||
if (PySwigObject_Check(v)) {
|
||||
PySwigObject *self = (PySwigObject *) v;
|
||||
if (self->own) {
|
||||
PySwigObject *sobj = (PySwigObject *) v;
|
||||
PyObject *next = sobj->next;
|
||||
if (sobj->own) {
|
||||
/*
|
||||
Well, somebody forgot to call delete, or we have a
|
||||
multi-inheritance case. Hence, we need to call
|
||||
Class.__destroy__(this).
|
||||
*/
|
||||
swig_type_info *ty = sobj->ty;
|
||||
PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0;
|
||||
PyObject *destroy = data ? data->destroy : 0;
|
||||
if (destroy) {
|
||||
PyObject *args = PyTuple_New(1);
|
||||
PyTuple_SetItem(args,0,v);
|
||||
PyObject_Call(destroy, args, NULL);
|
||||
Py_DECREF(args);
|
||||
} else {
|
||||
const char *name = SWIG_TypePrettyName(ty);
|
||||
PyObject *wrn = PyString_FromFormat("swig/python detected a memory leak of type '%s'.", name);
|
||||
PyErr_Warn(PyExc_RuntimeWarning, PyString_AsString(wrn));
|
||||
Py_DECREF(wrn);
|
||||
}
|
||||
}
|
||||
}
|
||||
Py_XDECREF(next);
|
||||
v->ob_type->tp_free(v);
|
||||
}
|
||||
|
||||
|
||||
SWIGINTERN PyObject*
|
||||
PySwigObject_disown(PySwigObject *self)
|
||||
SWIGRUNTIME PyObject*
|
||||
PySwigObject_append(PyObject* v, PyObject* next)
|
||||
{
|
||||
self->own = 0;
|
||||
PySwigObject *sobj = (PySwigObject *) v;
|
||||
if (!PySwigObject_Check(next))
|
||||
return NULL;
|
||||
|
||||
sobj->next = next;
|
||||
Py_INCREF(next);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
SWIGINTERN PyObject*
|
||||
PySwigObject_acquire(PySwigObject *self)
|
||||
SWIGRUNTIME PyObject*
|
||||
PySwigObject_next(PyObject* v)
|
||||
{
|
||||
self->own = 1;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
PySwigObject *sobj = (PySwigObject *) v;
|
||||
PyObject *obj = sobj->next ? sobj->next : Py_None;
|
||||
|
||||
SWIGINTERN PyObject*
|
||||
PySwigObject_own(PySwigObject *self)
|
||||
{
|
||||
PyObject *obj = self->own ? Py_True : Py_False;
|
||||
Py_INCREF(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
SWIGINTERN PyObject*
|
||||
PySwigObject_disown(PyObject *v)
|
||||
{
|
||||
PySwigObject *sobj = (PySwigObject *)v;
|
||||
sobj->own = 0;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
SWIGINTERN PyObject*
|
||||
PySwigObject_acquire(PyObject *v)
|
||||
{
|
||||
PySwigObject *sobj = (PySwigObject *)v;
|
||||
sobj->own = 1;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
SWIGINTERN PyObject*
|
||||
PySwigObject_own(PyObject *v, PyObject *args)
|
||||
{
|
||||
PyObject *val = 0;
|
||||
if (!PyArg_UnpackTuple(args, "own", 0, 1, &val)) {
|
||||
return NULL;
|
||||
} else {
|
||||
PySwigObject *sobj = (PySwigObject *)v;
|
||||
PyObject *obj = sobj->own ? Py_True : Py_False;
|
||||
if (val) {
|
||||
if (PyObject_IsTrue(val)) {
|
||||
PySwigObject_acquire(v);
|
||||
} else {
|
||||
PySwigObject_disown(v);
|
||||
}
|
||||
}
|
||||
Py_INCREF(obj);
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
SWIGRUNTIME PyTypeObject*
|
||||
PySwigObject_type(void) {
|
||||
static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer";
|
||||
static PyMethodDef
|
||||
swigobject_methods[] = {
|
||||
{"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, "release ownership of the pointer"},
|
||||
{"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, "aquire ownership of the pointer"},
|
||||
{"own", (PyCFunction)PySwigObject_own, METH_NOARGS, "return ownership status of the pointer"},
|
||||
{"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, "releases ownership of the pointer"},
|
||||
{"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, "aquires ownership of the pointer"},
|
||||
{"own", (PyCFunction)PySwigObject_own, METH_VARARGS, "returns/sets ownership of the pointer"},
|
||||
{"append", (PyCFunction)PySwigObject_append, METH_O, "appends another 'this' object"},
|
||||
{"next", (PyCFunction)PySwigObject_next, METH_NOARGS, "returns the next 'this' object"},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
|
@ -312,13 +375,14 @@ PySwigObject_type(void) {
|
|||
SWIGRUNTIME PyObject *
|
||||
PySwigObject_New(void *ptr, swig_type_info *ty, int own)
|
||||
{
|
||||
PySwigObject *self = PyObject_NEW(PySwigObject, PySwigObject_type());
|
||||
if (self) {
|
||||
self->ptr = ptr;
|
||||
self->ty = ty;
|
||||
self->own = own;
|
||||
PySwigObject *sobj = PyObject_NEW(PySwigObject, PySwigObject_type());
|
||||
if (sobj) {
|
||||
sobj->ptr = ptr;
|
||||
sobj->ty = ty;
|
||||
sobj->own = own;
|
||||
sobj->next = 0;
|
||||
}
|
||||
return (PyObject *)self;
|
||||
return (PyObject *)sobj;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
@ -390,8 +454,8 @@ SWIGRUNTIME void
|
|||
PySwigPacked_dealloc(PyObject *v)
|
||||
{
|
||||
if (PySwigPacked_Check(v)) {
|
||||
PySwigPacked *self = (PySwigPacked *) v;
|
||||
free(self->pack);
|
||||
PySwigPacked *sobj = (PySwigPacked *) v;
|
||||
free(sobj->pack);
|
||||
}
|
||||
v->ob_type->tp_free(v);
|
||||
}
|
||||
|
|
@ -476,17 +540,17 @@ PySwigPacked_type(void) {
|
|||
SWIGRUNTIME PyObject *
|
||||
PySwigPacked_New(void *ptr, size_t size, swig_type_info *ty)
|
||||
{
|
||||
PySwigPacked *self = PyObject_NEW(PySwigPacked, PySwigPacked_type());
|
||||
if (self == NULL) {
|
||||
PySwigPacked *sobj = PyObject_NEW(PySwigPacked, PySwigPacked_type());
|
||||
if (sobj == NULL) {
|
||||
return NULL;
|
||||
} else {
|
||||
void *pack = malloc(size);
|
||||
if (pack) {
|
||||
memcpy(pack, ptr, size);
|
||||
self->pack = pack;
|
||||
self->ty = ty;
|
||||
self->size = size;
|
||||
return (PyObject *) self;
|
||||
sobj->pack = pack;
|
||||
sobj->ty = ty;
|
||||
sobj->size = size;
|
||||
return (PyObject *) sobj;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -496,10 +560,10 @@ SWIGRUNTIMEINLINE swig_type_info *
|
|||
PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size)
|
||||
{
|
||||
if (PySwigPacked_Check(obj)) {
|
||||
PySwigPacked *self = (PySwigPacked *)obj;
|
||||
if (self->size != size) return 0;
|
||||
memcpy(ptr, self->pack, size);
|
||||
return self->ty;
|
||||
PySwigPacked *sobj = (PySwigPacked *)obj;
|
||||
if (sobj->size != size) return 0;
|
||||
memcpy(ptr, sobj->pack, size);
|
||||
return sobj->ty;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -519,24 +583,13 @@ SWIG_This()
|
|||
|
||||
/* #define SWIG_PYTHON_SLOW_GETSET_THIS */
|
||||
|
||||
/* Convert a pointer value */
|
||||
SWIGRUNTIME int
|
||||
SWIG_Python_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags) {
|
||||
swig_type_info *to = 0;
|
||||
const char *desc = 0;
|
||||
int newref = 0;
|
||||
PyObject *pyobj = 0;
|
||||
void *vptr = 0;
|
||||
PySwigObject *sobj = 0;
|
||||
|
||||
if (!obj) return SWIG_ERROR;
|
||||
if (obj == Py_None) {
|
||||
*ptr = 0;
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
if (!(PySwigObject_Check(obj))) {
|
||||
pyobj = obj;
|
||||
SWIGRUNTIMEINLINE PySwigObject *
|
||||
SWIG_Python_GetSwigThis(PyObject *pyobj)
|
||||
{
|
||||
if (PySwigObject_Check(pyobj)) {
|
||||
return (PySwigObject *) pyobj;
|
||||
} else {
|
||||
PyObject *obj = 0;
|
||||
#ifndef SWIG_PYTHON_SLOW_GETSET_THIS
|
||||
if (PyInstance_Check(pyobj)) {
|
||||
obj = _PyInstance_Lookup(pyobj, SWIG_This());
|
||||
|
|
@ -549,45 +602,60 @@ SWIG_Python_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags)
|
|||
obj = PyObject_GetAttr(pyobj,SWIG_This());
|
||||
}
|
||||
}
|
||||
Py_XINCREF(obj);
|
||||
#else
|
||||
obj = PyObject_GetAttr(pyobj,SWIG_This());
|
||||
#endif
|
||||
if (!obj) goto type_error;
|
||||
if (!PySwigObject_Check(obj)) {
|
||||
Py_DECREF(obj);
|
||||
goto type_error;
|
||||
#endif
|
||||
if (PyErr_Occurred()) {
|
||||
obj = 0;
|
||||
PyErr_Clear();
|
||||
}
|
||||
newref = 1;
|
||||
}
|
||||
sobj = (PySwigObject *) obj;
|
||||
vptr = sobj->ptr;
|
||||
to = sobj->ty;
|
||||
desc = (const char *) to->name;
|
||||
if (newref) { newref = 0; Py_DECREF(obj); }
|
||||
|
||||
if (ty) {
|
||||
if (to == ty) {
|
||||
/* no type cast needed */
|
||||
*ptr = vptr;
|
||||
} else {
|
||||
swig_cast_info *tc = SWIG_TypeCheck(desc,ty);
|
||||
if (!tc) goto type_error;
|
||||
*ptr = SWIG_TypeCast(tc,vptr);
|
||||
}
|
||||
} else {
|
||||
*ptr = vptr;
|
||||
return obj && PySwigObject_Check(obj) ? (PySwigObject *) obj : 0;
|
||||
}
|
||||
if ((pyobj) && (flags & SWIG_POINTER_DISOWN)) {
|
||||
sobj->own = 0;
|
||||
}
|
||||
return SWIG_OK;
|
||||
|
||||
type_error:
|
||||
PyErr_Clear();
|
||||
return SWIG_ERROR;
|
||||
}
|
||||
|
||||
/* Convert a pointer value */
|
||||
SWIGRUNTIME int
|
||||
SWIG_Python_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags) {
|
||||
if (!obj) return SWIG_ERROR;
|
||||
if (obj == Py_None) {
|
||||
*ptr = 0;
|
||||
return SWIG_OK;
|
||||
} else {
|
||||
PySwigObject *sobj = SWIG_Python_GetSwigThis(obj);
|
||||
while (sobj) {
|
||||
void *vptr = sobj->ptr;
|
||||
if (ty) {
|
||||
swig_type_info *to = sobj->ty;
|
||||
if (to == ty) {
|
||||
/* no type cast needed */
|
||||
*ptr = vptr;
|
||||
break;
|
||||
} else {
|
||||
swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
|
||||
if (!tc) {
|
||||
sobj = (PySwigObject *)sobj->next;
|
||||
} else {
|
||||
*ptr = SWIG_TypeCast(tc,vptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
*ptr = vptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sobj) {
|
||||
if (flags & SWIG_POINTER_DISOWN) {
|
||||
sobj->own = 0;
|
||||
}
|
||||
return SWIG_OK;
|
||||
} else {
|
||||
return SWIG_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SWIGRUNTIME int
|
||||
SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) {
|
||||
if (!PyCFunction_Check(obj)) {
|
||||
|
|
@ -640,19 +708,34 @@ SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *t
|
|||
* Create a new pointer object
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#define SWIG_NewClientData(obj) SWIG_Python_NewClientData(obj)
|
||||
#define SWIG_NewClientData(obj) PySwigClientData_New(obj)
|
||||
|
||||
SWIGRUNTIMEINLINE void *
|
||||
SWIG_Python_NewClientData(PyObject* obj)
|
||||
PySwigClientData_New(PyObject* obj)
|
||||
{
|
||||
PySwigClientData *data = (PySwigClientData *)malloc(sizeof(PySwigClientData));
|
||||
data->klass = 0;
|
||||
data->newargs = 0;
|
||||
data->destroy = 0;
|
||||
|
||||
if (PyClass_Check(obj)) {
|
||||
Py_INCREF(obj);
|
||||
return obj;
|
||||
data->klass = obj;
|
||||
data->newargs = obj;
|
||||
Py_INCREF(data->newargs);
|
||||
} else {
|
||||
PyObject *args = PyTuple_New(1);
|
||||
PyTuple_SetItem(args, 0, obj);
|
||||
return args;
|
||||
data->klass = obj;
|
||||
data->newargs = PyTuple_New(1);
|
||||
PyTuple_SetItem(data->newargs, 0, obj);
|
||||
}
|
||||
if (data->klass) {
|
||||
static PyObject* SWIG_STATIC_POINTER(destroystr) = PyString_FromString("__destroy__");
|
||||
data->destroy = PyObject_GetAttr(data->klass, destroystr);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Clear();
|
||||
data->destroy = 0;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -660,15 +743,14 @@ SWIG_Python_NewClientData(PyObject* obj)
|
|||
and set the 'this' attribute.
|
||||
*/
|
||||
|
||||
|
||||
SWIGRUNTIME PyObject*
|
||||
SWIG_Python_NewShadowInstance(PyObject *obj, PyObject *swig_this)
|
||||
SWIGRUNTIMEINLINE PyObject*
|
||||
SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this)
|
||||
{
|
||||
PyObject *inst = 0;
|
||||
if (!PyClass_Check(obj)) {
|
||||
if (!PyClass_Check(data->klass)) {
|
||||
static PyObject* SWIG_STATIC_POINTER(fnew) =
|
||||
PyObject_GetAttrString((PyObject*)&PyBaseObject_Type, "__new__");
|
||||
inst = PyObject_Call(fnew, obj, NULL);
|
||||
inst = PyObject_Call(fnew, data->newargs, NULL);
|
||||
if (inst) {
|
||||
#ifndef SWIG_PYTHON_SLOW_GETSET_THIS
|
||||
PyObject **dictptr = _PyObject_GetDictPtr(inst);
|
||||
|
|
@ -677,17 +759,17 @@ SWIG_Python_NewShadowInstance(PyObject *obj, PyObject *swig_this)
|
|||
if (dict == NULL) {
|
||||
dict = PyDict_New();
|
||||
*dictptr = dict;
|
||||
PyDict_SetItem(dict, SWIG_This(), swig_this);
|
||||
}
|
||||
PyDict_SetItem(dict, SWIG_This(), swig_this);
|
||||
}
|
||||
}
|
||||
#else
|
||||
PyObject_SetAttr(inst, SWIG_This(), swig_this);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
PyObject *dict = PyDict_New();
|
||||
PyDict_SetItem(dict,SWIG_This(), swig_this);
|
||||
inst = PyInstance_NewRaw(obj, dict);
|
||||
PyDict_SetItem(dict, SWIG_This(), swig_this);
|
||||
inst = PyInstance_NewRaw(data->newargs, dict);
|
||||
Py_DECREF(dict);
|
||||
}
|
||||
return inst;
|
||||
|
|
@ -696,30 +778,26 @@ SWIG_Python_NewShadowInstance(PyObject *obj, PyObject *swig_this)
|
|||
|
||||
SWIGRUNTIME PyObject *
|
||||
SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) {
|
||||
PyObject *robj = 0;
|
||||
int own = (flags & SWIG_POINTER_OWN);
|
||||
int shadow = !(flags & SWIG_POINTER_NOSHADOW);
|
||||
if (!type) {
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "Swig: null type passed to NewPointerObj");
|
||||
}
|
||||
return robj;
|
||||
}
|
||||
if (!ptr) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
robj = PySwigObject_New((void *) ptr, type, own);
|
||||
if (!robj || (robj == Py_None)) return robj;
|
||||
if (shadow && type->clientdata) {
|
||||
PyObject *inst = SWIG_Python_NewShadowInstance((PyObject *)type->clientdata, robj);
|
||||
if (inst) {
|
||||
Py_DECREF(robj);
|
||||
robj = inst;
|
||||
} else if (!type) {
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "Swig: null type passed to NewPointerObj");
|
||||
}
|
||||
return NULL;
|
||||
} else {
|
||||
PyObject *robj = PySwigObject_New((void *) ptr, type, (flags & SWIG_POINTER_OWN));
|
||||
PySwigClientData *clientdata = (PySwigClientData *)type->clientdata;
|
||||
if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) {
|
||||
PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj);
|
||||
if (inst) {
|
||||
Py_DECREF(robj);
|
||||
robj = inst;
|
||||
}
|
||||
}
|
||||
return robj;
|
||||
}
|
||||
return robj;
|
||||
}
|
||||
|
||||
/* Create a new array object */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue