polymorphism patch merge
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@4435 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
85a9996858
commit
bd40a83f1c
15 changed files with 2007 additions and 15 deletions
|
|
@ -1,6 +1,24 @@
|
|||
Version 1.3.18 (In progress)
|
||||
============================
|
||||
|
||||
03/06/2003: mrose (Mark Rose)
|
||||
Merged the cross-language polymorphism patch. When enabled, C++
|
||||
"proxy" classes (called directors) for each specified C++ class.
|
||||
Directors pass method calls from C++ to Python, similar to the way
|
||||
the usual proxy (shadow) classes pass method calls from Python to
|
||||
C++. Together, these two types of proxies allow C++ classes that
|
||||
are extended in Python to behave just like ordinary C++ classes and
|
||||
be used in C++ like native objects.
|
||||
|
||||
This feature is still very experimental and is disabled by default.
|
||||
To enable director support, specify '-fdirectors' on the SWIG command
|
||||
line or in the SWIG_FEATURES environment variable. In the interface
|
||||
file, add %feature("director") to generate directors for all classes
|
||||
that have virtual methods.
|
||||
|
||||
See http://stm.lbl.gov/~tm2/swig/ProxyDoc.html for more details.
|
||||
|
||||
|
||||
03/03/2003: beazley
|
||||
Fixed a small glitch in typemap local variable replacement. If you had
|
||||
a typemap like this:
|
||||
|
|
|
|||
183
SWIG/Lib/python/director.swg
Normal file
183
SWIG/Lib/python/director.swg
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
/***********************************************************************
|
||||
* director.swg
|
||||
*
|
||||
* This file contains support for director classes that proxy
|
||||
* method calls from C++ to Python extensions.
|
||||
*
|
||||
* Author : Mark Rose (mrose@stm.lbl.gov)
|
||||
************************************************************************/
|
||||
|
||||
%insert(runtime) %{
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <string>
|
||||
|
||||
/* base class for director exceptions */
|
||||
class SWIG_DIRECTOR_EXCEPTION {
|
||||
protected:
|
||||
std::string _msg;
|
||||
public:
|
||||
SWIG_DIRECTOR_EXCEPTION(const char* msg="") {
|
||||
}
|
||||
const char *getMessage() { return _msg.c_str(); }
|
||||
virtual ~SWIG_DIRECTOR_EXCEPTION() { }
|
||||
};
|
||||
|
||||
/* type mismatch in the return value from a python method call */
|
||||
class SWIG_DIRECTOR_TYPE_MISMATCH: public SWIG_DIRECTOR_EXCEPTION {
|
||||
public:
|
||||
SWIG_DIRECTOR_TYPE_MISMATCH(const char* msg="") {
|
||||
_msg = "Swig director type mismatch: ";
|
||||
_msg += msg;
|
||||
PyErr_SetString(PyExc_TypeError, msg);
|
||||
}
|
||||
};
|
||||
|
||||
/* any python exception that occurs during a director method call */
|
||||
class SWIG_DIRECTOR_METHOD_EXCEPTION: public SWIG_DIRECTOR_EXCEPTION { };
|
||||
|
||||
/* simple thread abstraction for pthreads or win32 */
|
||||
#ifdef __THREAD__
|
||||
#define __PTHREAD__
|
||||
#if defined(_WIN32) || defined(__WIN32__)
|
||||
#define pthread_mutex_lock EnterCriticalSection
|
||||
#define pthread_mutex_unlock LeaveCriticalSection
|
||||
#define pthread_mutex_t CRITICAL_SECTION
|
||||
#define MUTEX_INIT(var) CRITICAL_SECTION var
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#define MUTEX_INIT(var) pthread_mutex_t var = PTHREAD_MUTEX_INITIALIZER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* director base class */
|
||||
class __DIRECTOR__ {
|
||||
private:
|
||||
/* pointer to the wrapped python object */
|
||||
PyObject* _self;
|
||||
/* flag indicating whether the object is owned by python or c++ */
|
||||
mutable int _disown;
|
||||
/* shared flag for breaking recursive director calls */
|
||||
static int _up;
|
||||
|
||||
#ifdef __PTHREAD__
|
||||
/* locks for sharing the _up flag in a threaded environment */
|
||||
static pthread_mutex_t _mutex_up;
|
||||
static int _mutex_active;
|
||||
static pthread_t _mutex_thread;
|
||||
#endif
|
||||
|
||||
/* decrement the reference count of the wrapped python object */
|
||||
void __decref() const {
|
||||
assert(_self);
|
||||
if (_disown) {
|
||||
Py_DECREF(_self);
|
||||
}
|
||||
}
|
||||
|
||||
/* reset the _up flag once the routing direction has been determined */
|
||||
#ifdef __PTHREAD__
|
||||
void __clear_up() const {
|
||||
__DIRECTOR__::_up = 0;
|
||||
__DIRECTOR__::_mutex_active = 0;
|
||||
pthread_mutex_unlock(&_mutex_up);
|
||||
}
|
||||
#else
|
||||
void __clear_up() const {
|
||||
__DIRECTOR__::_up = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
/* the default constructor should not be called */
|
||||
__DIRECTOR__() {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* wrap a python object, optionally taking ownership */
|
||||
__DIRECTOR__(PyObject* self, int disown): _self(self), _disown(disown) {
|
||||
__incref();
|
||||
}
|
||||
|
||||
/* discard our reference at destruction */
|
||||
virtual ~__DIRECTOR__() {
|
||||
__decref();
|
||||
}
|
||||
|
||||
/* return a pointer to the wrapped python object */
|
||||
PyObject *__get_self() const {
|
||||
return _self;
|
||||
}
|
||||
|
||||
|
||||
/* get the _up flag to determine if the method call should be routed
|
||||
* to the c++ base class or through the wrapped python object
|
||||
*/
|
||||
#ifdef __PTHREAD__
|
||||
int __get_up() const {
|
||||
if (__DIRECTOR__::_mutex_active) {
|
||||
if (pthread_equal(__DIRECTOR__::_mutex_thread, pthread_self())) {
|
||||
int up = _up;
|
||||
__clear_up();
|
||||
return up;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int __get_up() const {
|
||||
int up = _up;
|
||||
_up = 0;
|
||||
return up;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set the _up flag if the next method call should be directed to
|
||||
* the c++ base class rather than the wrapped python object
|
||||
*/
|
||||
#ifdef __PTHREAD__
|
||||
void __set_up() const {
|
||||
pthread_mutex_lock(&__DIRECTOR__::_mutex_up);
|
||||
__DIRECTOR__::_mutex_thread = pthread_self();
|
||||
__DIRECTOR__::_mutex_active = 1;
|
||||
__DIRECTOR__::_up = 1;
|
||||
}
|
||||
#else
|
||||
void __set_up() const {
|
||||
__DIRECTOR__::_up = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* acquire ownership of the wrapped python object (the sense of "disown"
|
||||
* is from python) */
|
||||
void __disown() const {
|
||||
assert(_self);
|
||||
if (!_disown) {
|
||||
_disown=1;
|
||||
__incref();
|
||||
}
|
||||
}
|
||||
|
||||
/* increase the reference count of the wrapped python object */
|
||||
void __incref() const {
|
||||
assert(_self);
|
||||
if (_disown) {
|
||||
Py_INCREF(_self);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
int __DIRECTOR__::_up = 0;
|
||||
|
||||
#ifdef __PTHREAD__
|
||||
MUTEX_INIT(__DIRECTOR__::_mutex_up);
|
||||
pthread_t __DIRECTOR__::_mutex_thread;
|
||||
int __DIRECTOR__::_mutex_active = 0;
|
||||
#endif
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
%}
|
||||
|
||||
|
|
@ -22,6 +22,126 @@
|
|||
* standard typemaps
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Inverse argument typemaps are for marshaling C/C++ parameters to call Python
|
||||
* methods from C++ proxy wrapper classes.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* --- Inverse arguments --- */
|
||||
|
||||
/* Primitive datatypes. These only supply a parse code to PyObject_CallMethod */
|
||||
|
||||
%typemap(inv,parse="i") int "";
|
||||
%typemap(inv,parse="h") short "";
|
||||
%typemap(inv,parse="l") long "";
|
||||
%typemap(inv,parse="b") signed char "";
|
||||
%typemap(inv,parse="f") float "";
|
||||
%typemap(inv,parse="d") double "";
|
||||
%typemap(inv,parse="s") char* "";
|
||||
%typemap(inv,parse="i") bool "";
|
||||
|
||||
%typemap(inv,parse="l") unsigned int, unsigned short, unsigned long, unsigned char "(long) $1_name";
|
||||
|
||||
%typemap(inv) long long
|
||||
"$input = PyLong_FromLongLong($1_name);";
|
||||
%typemap(inv) unsigned long long
|
||||
"$input = PyLong_FromUnsignedLongLong($1_name);";
|
||||
|
||||
%typemap(inv, parse="l") int *INV, long* INV,
|
||||
unsigned int *INV, unsigned long *INV,
|
||||
short *INV, unsigned short *INV,
|
||||
char *INV, unsigned char *INV
|
||||
"(long) *$1_name";
|
||||
%typemap(inv, parse="f") float *INV "*$1_name";
|
||||
%typemap(inv, parse="d") double *INV "*$1_name";
|
||||
|
||||
%typemap(inv, parse="O") PyObject* "";
|
||||
|
||||
/*
|
||||
%typemap(inv, parse="s") SWIGTYPE {
|
||||
{
|
||||
$&1_ltype resultptr;
|
||||
resultptr = new $1_ltype(($1_ltype &) $1);
|
||||
$result = SWIG_NewPointerObj((void *) resultptr, $&1_descriptor, 1);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* no can do... see python.cxx
|
||||
%typemap(inv) DIRECTORTYPE * {
|
||||
{
|
||||
__DIRECTOR__$1_ltype proxy = dynamic_cast<__DIRECTOR__$1_ltype>($1_name);
|
||||
if (!proxy) {
|
||||
$input = SWIG_NewPointerObj((void *) $1_name, $1_descriptor, 0);
|
||||
} else {
|
||||
$input = proxy->__get_self();
|
||||
}
|
||||
assert($input);
|
||||
}
|
||||
}
|
||||
%typemap(inv) SWIGTYPE * {
|
||||
$input = SWIG_NewPointerObj((void *) $1_name, $1_descriptor, 0);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
%typemap(inv, parse="s") void "0";
|
||||
*/
|
||||
/*
|
||||
%typemap(inv) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] {
|
||||
$input = SWIG_NewPointerObj((void *) $1_name, $1_descriptor, $owner);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/* --- Outverse arguments --- */
|
||||
|
||||
%define OUTV_TYPEMAP(type, converter)
|
||||
%typemap(argoutv) type *OUTV
|
||||
"*$result = (type) converter($input);
|
||||
if (PyErr_Occurred()) throw SWIG_DIRECTOR_TYPE_MISMATCH(\"Error converting Python object using converter\");";
|
||||
%typemap(outv) type
|
||||
"$result = (type) converter($input);
|
||||
if (PyErr_Occurred()) throw SWIG_DIRECTOR_TYPE_MISMATCH(\"Error converting Python object using converter\");";
|
||||
%typemap(outv) type &OUTV = type
|
||||
%enddef
|
||||
|
||||
OUTV_TYPEMAP(char, PyInt_AsLong);
|
||||
OUTV_TYPEMAP(unsigned char, PyInt_AsLong);
|
||||
OUTV_TYPEMAP(short, PyInt_AsLong);
|
||||
OUTV_TYPEMAP(unsigned short, PyInt_AsLong);
|
||||
OUTV_TYPEMAP(int, PyInt_AsLong);
|
||||
OUTV_TYPEMAP(unsigned int, PyInt_AsLong);
|
||||
OUTV_TYPEMAP(long, PyInt_AsLong);
|
||||
OUTV_TYPEMAP(unsigned long, PyInt_AsLong);
|
||||
OUTV_TYPEMAP(long long, PyLong_AsLongLong);
|
||||
OUTV_TYPEMAP(unsigned long long, PyLong_AsUnsignedLongLong);
|
||||
OUTV_TYPEMAP(float, PyFloat_AsDouble);
|
||||
OUTV_TYPEMAP(double, PyFloat_AsDouble);
|
||||
OUTV_TYPEMAP(bool, PyInt_AsLong);
|
||||
OUTV_TYPEMAP(PyObject *, );
|
||||
OUTV_TYPEMAP(char *, PyString_AsString);
|
||||
|
||||
|
||||
%typemap(outv) SWIGTYPE *,
|
||||
SWIGTYPE &,
|
||||
SWIGTYPE []
|
||||
"if ((SWIG_ConvertPtr($input,(void **) &$result, $descriptor,SWIG_POINTER_EXCEPTION | $disown )) == -1) throw SWIG_DIRECTOR_TYPE_MISMATCH(\"Pointer conversion failed.\");";
|
||||
|
||||
%typemap(outv) void * "if ((SWIG_ConvertPtr($input,(void **) &$result, 0, SWIG_POINTER_EXCEPTION | $disown )) == -1) throw SWIG_DIRECTOR_TYPE_MISMATCH(\"Pointer conversion failed.\");";
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* End of C++ proxy wrapper typemaps.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/* --- Input arguments --- */
|
||||
|
||||
/* Primitive datatypes. These only supply a parse code to PyTuple_ParseArgs */
|
||||
|
|
@ -495,6 +615,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
%typecheck(SWIG_TYPECHECK_POINTER) PyObject *
|
||||
{
|
||||
$1 = ($input != 0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
* Exception handling
|
||||
* ------------------------------------------------------------ */
|
||||
|
|
|
|||
|
|
@ -64,6 +64,47 @@ SwigComplex_AsComplexDouble(PyObject *o)
|
|||
%typemap(out) const Complex & {
|
||||
$result = PyComplex_FromDoubles($1->real(), $1->imag());
|
||||
}
|
||||
|
||||
// C++ proxy class typemaps
|
||||
|
||||
%typemap(inv) complex<T> {
|
||||
$input = PyComplex_FromDoubles($1_name.real(), $1_name.imag());
|
||||
}
|
||||
|
||||
%typemap(inv) const complex<T> & {
|
||||
$inupt = PyComplex_FromDoubles($1_name->real(), $1_name->imag());
|
||||
}
|
||||
|
||||
%typemap(outv) complex<T> {
|
||||
if (PyComplex_Check($input)) {
|
||||
$result = std::complex<T>(PyComplex_RealAsDouble($input),
|
||||
PyComplex_ImagAsDouble($input));
|
||||
} else if (PyFloat_Check($input)) {
|
||||
$result = std::complex<T>(PyFloat_AsDouble($input), 0);
|
||||
} else if (PyInt_Check($input)) {
|
||||
$result = std::complex<T>(PyInt_AsLong($input), 0);
|
||||
}
|
||||
else {
|
||||
throw SWIG_DIRECTOR_TYPE_MISMATCH("Expected a complex");
|
||||
}
|
||||
}
|
||||
|
||||
%typemap(outv) const complex<T>& (std::complex<T> temp) {
|
||||
if (PyComplex_Check($input)) {
|
||||
temp = std::complex<T>(PyComplex_RealAsDouble($input),
|
||||
PyComplex_ImagAsDouble($input));
|
||||
$result = &temp;
|
||||
} else if (PyFloat_Check($input)) {
|
||||
temp = std::complex<T>(PyFloat_AsDouble($input), 0);
|
||||
$result = &temp;
|
||||
} else if (PyInt_Check($input)) {
|
||||
temp = std::complex<T>(PyInt_AsLong($input), 0);
|
||||
$result = &temp;
|
||||
} else {
|
||||
throw SWIG_DIRECTOR_TYPE_MISMATCH("Expected a complex");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
%enddef
|
||||
|
||||
|
|
|
|||
|
|
@ -50,5 +50,26 @@ namespace std {
|
|||
%typemap(out) const string & {
|
||||
$result = PyString_FromStringAndSize($1->data(),$1->size());
|
||||
}
|
||||
|
||||
%typemap(inv, parse="s") string, const string &, string & "$1_name.c_str()";
|
||||
|
||||
%typemap(inv, parse="s") string *, const string * "$1_name->c_str()";
|
||||
|
||||
%typemap(outv) string {
|
||||
if (PyString_Check($input))
|
||||
$result = std::string(PyString_AsString($input));
|
||||
else
|
||||
throw SWIG_DIRECTOR_TYPE_MISMATCH("string expected");
|
||||
}
|
||||
|
||||
%typemap(outv) const string & (std::string temp) {
|
||||
if (PyString_Check($input)) {
|
||||
temp = std::string(PyString_AsString($input));
|
||||
$result = &temp;
|
||||
} else {
|
||||
throw SWIG_DIRECTOR_TYPE_MISMATCH("string expected");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,6 +106,31 @@ namespace std {
|
|||
SWIG_fail;
|
||||
}
|
||||
}
|
||||
%typemap(outv) vector<T> (std::vector<T>* v) {
|
||||
if (PyTuple_Check($input) || PyList_Check($input)) {
|
||||
unsigned int size = (PyTuple_Check($input) ?
|
||||
PyTuple_Size($input) :
|
||||
PyList_Size($input));
|
||||
$result = std::vector<T >(size);
|
||||
for (unsigned int i=0; i<size; i++) {
|
||||
T* x;
|
||||
PyObject* o = PySequence_GetItem($input,i);
|
||||
if ((SWIG_ConvertPtr(o,(void **) &x,
|
||||
$descriptor(T *),0)) != -1) {
|
||||
(($type &)$result)[i] = *x;
|
||||
Py_DECREF(o);
|
||||
} else {
|
||||
Py_DECREF(o);
|
||||
throw SWIG_DIRECTOR_TYPE_MISMATCH("vector<" #T "> expected");
|
||||
}
|
||||
}
|
||||
} else if (SWIG_ConvertPtr($input,(void **) &v,
|
||||
$&descriptor,1) != -1){
|
||||
$result = *v;
|
||||
} else {
|
||||
throw SWIG_DIRECTOR_TYPE_MISMATCH("vector<" #T "> expected");
|
||||
}
|
||||
}
|
||||
%typemap(in) const vector<T>& (std::vector<T> temp,
|
||||
std::vector<T>* v),
|
||||
const vector<T>* (std::vector<T> temp,
|
||||
|
|
@ -138,6 +163,35 @@ namespace std {
|
|||
SWIG_fail;
|
||||
}
|
||||
}
|
||||
%typemap(outv) const vector<T>& (std::vector<T> temp,
|
||||
std::vector<T>* v),
|
||||
const vector<T>* (std::vector<T> temp,
|
||||
std::vector<T>* v) {
|
||||
if (PyTuple_Check($input) || PyList_Check($input)) {
|
||||
unsigned int size = (PyTuple_Check($input) ?
|
||||
PyTuple_Size($input) :
|
||||
PyList_Size($input));
|
||||
temp = std::vector<T >(size);
|
||||
$result = &temp;
|
||||
for (unsigned int i=0; i<size; i++) {
|
||||
T* x;
|
||||
PyObject* o = PySequence_GetItem($input,i);
|
||||
if ((SWIG_ConvertPtr(o,(void **) &x,
|
||||
$descriptor(T *),0)) != -1) {
|
||||
temp[i] = *x;
|
||||
Py_DECREF(o);
|
||||
} else {
|
||||
Py_DECREF(o);
|
||||
throw SWIG_DIRECTOR_TYPE_MISMATCH("vector<" #T "> expected");
|
||||
}
|
||||
}
|
||||
} else if (SWIG_ConvertPtr($input,(void **) &v,
|
||||
$descriptor,1) != -1){
|
||||
$result = v;
|
||||
} else {
|
||||
throw SWIG_DIRECTOR_TYPE_MISMATCH("vector<" #T "> expected");
|
||||
}
|
||||
}
|
||||
%typemap(out) vector<T> {
|
||||
$result = PyTuple_New($1.size());
|
||||
for (unsigned int i=0; i<$1.size(); i++) {
|
||||
|
|
@ -147,6 +201,15 @@ namespace std {
|
|||
$descriptor(T *), 1));
|
||||
}
|
||||
}
|
||||
%typemap(inv) vector<T> {
|
||||
$input = PyTuple_New($1.size());
|
||||
for (unsigned int i=0; i<$1.size(); i++) {
|
||||
T* ptr = new T((($1_type &)$1)[i]);
|
||||
PyTuple_SetItem($input,i,
|
||||
SWIG_NewPointerObj((void *) ptr,
|
||||
$descriptor(T *), 1));
|
||||
}
|
||||
}
|
||||
%typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
|
||||
/* native sequence? */
|
||||
if (PyTuple_Check($input) || PyList_Check($input)) {
|
||||
|
|
@ -323,6 +386,31 @@ namespace std {
|
|||
SWIG_fail;
|
||||
}
|
||||
}
|
||||
%typemap(outv) vector<T> (std::vector<T>* v) {
|
||||
if (PyTuple_Check($input) || PyList_Check($input)) {
|
||||
unsigned int size = (PyTuple_Check($input) ?
|
||||
PyTuple_Size($input) :
|
||||
PyList_Size($input));
|
||||
$result = std::vector<T >(size);
|
||||
for (unsigned int i=0; i<size; i++) {
|
||||
T x;
|
||||
PyObject* o = PySequence_GetItem($input,i);
|
||||
if ((SWIG_ConvertPtr(o,(void **) &x,
|
||||
$descriptor(T),0)) != -1) {
|
||||
(($type &)$result)[i] = x;
|
||||
Py_DECREF(o);
|
||||
} else {
|
||||
Py_DECREF(o);
|
||||
throw SWIG_DIRECTOR_TYPE_MISMATCH("vector<" #T "> expected");
|
||||
}
|
||||
}
|
||||
} else if (SWIG_ConvertPtr($input,(void **) &v,
|
||||
$&descriptor,1) != -1){
|
||||
$result = *v;
|
||||
} else {
|
||||
throw SWIG_DIRECTOR_TYPE_MISMATCH("vector<" #T "> expected");
|
||||
}
|
||||
}
|
||||
%typemap(in) const vector<T>& (std::vector<T> temp,
|
||||
std::vector<T>* v),
|
||||
const vector<T>* (std::vector<T> temp,
|
||||
|
|
@ -355,6 +443,35 @@ namespace std {
|
|||
SWIG_fail;
|
||||
}
|
||||
}
|
||||
%typemap(outv) const vector<T>& (std::vector<T> temp,
|
||||
std::vector<T>* v),
|
||||
const vector<T>* (std::vector<T> temp,
|
||||
std::vector<T>* v) {
|
||||
if (PyTuple_Check($input) || PyList_Check($input)) {
|
||||
unsigned int size = (PyTuple_Check($input) ?
|
||||
PyTuple_Size($input) :
|
||||
PyList_Size($input));
|
||||
temp = std::vector<T >(size);
|
||||
$result = &temp;
|
||||
for (unsigned int i=0; i<size; i++) {
|
||||
T x;
|
||||
PyObject* o = PySequence_GetItem($input,i);
|
||||
if ((SWIG_ConvertPtr(o,(void **) &x,
|
||||
$descriptor(T),0)) != -1) {
|
||||
temp[i] = x;
|
||||
Py_DECREF(o);
|
||||
} else {
|
||||
Py_DECREF(o);
|
||||
throw SWIG_DIRECTOR_TYPE_MISMATCH("vector<" #T "> expected");
|
||||
}
|
||||
}
|
||||
} else if (SWIG_ConvertPtr($input,(void **) &v,
|
||||
$descriptor,1) != -1){
|
||||
$result = v;
|
||||
} else {
|
||||
throw SWIG_DIRECTOR_TYPE_MISMATCH("vector<" #T "> expected");
|
||||
}
|
||||
}
|
||||
%typemap(out) vector<T> {
|
||||
$result = PyTuple_New($1.size());
|
||||
for (unsigned int i=0; i<$1.size(); i++) {
|
||||
|
|
@ -364,6 +481,15 @@ namespace std {
|
|||
$descriptor(T), 0));
|
||||
}
|
||||
}
|
||||
%typemap(inv) vector<T> {
|
||||
$input = PyTuple_New($1_name.size());
|
||||
for (unsigned int i=0; i<$1_name.size(); i++) {
|
||||
T ptr = (($1_type &)$1)[i];
|
||||
PyTuple_SetItem($input,i,
|
||||
SWIG_NewPointerObj((void *) ptr,
|
||||
$descriptor(T), 0));
|
||||
}
|
||||
}
|
||||
%typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
|
||||
/* native sequence? */
|
||||
if (PyTuple_Check($input) || PyList_Check($input)) {
|
||||
|
|
@ -537,6 +663,29 @@ namespace std {
|
|||
SWIG_fail;
|
||||
}
|
||||
}
|
||||
%typemap(outv) vector<T> (std::vector<T>* v) {
|
||||
if (PyTuple_Check($input) || PyList_Check($input)) {
|
||||
unsigned int size = (PyTuple_Check($input) ?
|
||||
PyTuple_Size($input) :
|
||||
PyList_Size($input));
|
||||
$result = std::vector<T >(size);
|
||||
for (unsigned int i=0; i<size; i++) {
|
||||
PyObject* o = PySequence_GetItem($input,i);
|
||||
if (CHECK(o)) {
|
||||
(($type &)$result)[i] = (T)(CONVERT_FROM(o));
|
||||
Py_DECREF(o);
|
||||
} else {
|
||||
Py_DECREF(o);
|
||||
throw SWIG_DIRECTOR_TYPE_MISMATCH("vector<" #T "> expected");
|
||||
}
|
||||
}
|
||||
} else if (SWIG_ConvertPtr($input,(void **) &v,
|
||||
$&descriptor,1) != -1){
|
||||
$result = *v;
|
||||
} else {
|
||||
throw SWIG_DIRECTOR_TYPE_MISMATCH("vector<" #T "> expected");
|
||||
}
|
||||
}
|
||||
%typemap(in) const vector<T>& (std::vector<T> temp,
|
||||
std::vector<T>* v),
|
||||
const vector<T>* (std::vector<T> temp,
|
||||
|
|
@ -567,12 +716,45 @@ namespace std {
|
|||
SWIG_fail;
|
||||
}
|
||||
}
|
||||
%typemap(outv) const vector<T>& (std::vector<T> temp,
|
||||
std::vector<T>* v),
|
||||
const vector<T>* (std::vector<T> temp,
|
||||
std::vector<T>* v) {
|
||||
if (PyTuple_Check($input) || PyList_Check($input)) {
|
||||
unsigned int size = (PyTuple_Check($input) ?
|
||||
PyTuple_Size($input) :
|
||||
PyList_Size($input));
|
||||
temp = std::vector<T >(size);
|
||||
$result = &temp;
|
||||
for (unsigned int i=0; i<size; i++) {
|
||||
PyObject* o = PySequence_GetItem($input,i);
|
||||
if (CHECK(o)) {
|
||||
temp[i] = (T)(CONVERT_FROM(o));
|
||||
Py_DECREF(o);
|
||||
} else {
|
||||
Py_DECREF(o);
|
||||
throw SWIG_DIRECTOR_TYPE_MISMATCH("vector<" #T "> expected");
|
||||
}
|
||||
}
|
||||
} else if (SWIG_ConvertPtr($input,(void **) &v,
|
||||
$descriptor,1) != -1){
|
||||
$result = v;
|
||||
} else {
|
||||
throw SWIG_DIRECTOR_TYPE_MISMATCH("vector<" #T "> expected");
|
||||
}
|
||||
}
|
||||
%typemap(out) vector<T> {
|
||||
$result = PyTuple_New($1.size());
|
||||
for (unsigned int i=0; i<$1.size(); i++)
|
||||
PyTuple_SetItem($result,i,
|
||||
CONVERT_TO((($1_type &)$1)[i]));
|
||||
}
|
||||
%typemap(inv) vector<T> {
|
||||
$input = PyTuple_New($1_name.size());
|
||||
for (unsigned int i=0; i<$1_name.size(); i++)
|
||||
PyTuple_SetItem($input,i,
|
||||
CONVERT_TO((($1_type &)$1_name)[i]));
|
||||
}
|
||||
%typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
|
||||
/* native sequence? */
|
||||
if (PyTuple_Check($input) || PyList_Check($input)) {
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@
|
|||
#define WARN_TYPEMAP_VAR_UNDEF 466
|
||||
#define WARN_TYPEMAP_TYPECHECK 467
|
||||
#define WARN_TYPEMAP_THROW 468
|
||||
#define WARN_TYPEMAP_INV_UNDEF 469
|
||||
|
||||
/* -- General code generation -- */
|
||||
|
||||
|
|
@ -156,6 +157,8 @@
|
|||
#define WARN_LANG_OVERLOAD_KEYWORD 511
|
||||
#define WARN_LANG_OVERLOAD_CONST 512
|
||||
#define WARN_LANG_CLASS_UNNAMED 513
|
||||
#define WARN_LANG_DIRECTOR_VDESTRUCT 514
|
||||
#define WARN_LANG_DISCARD_CONST 515
|
||||
|
||||
/* -- Reserved (600-799) -- */
|
||||
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@ Language::Language() {
|
|||
classtypes = NewHash();
|
||||
overloading = 0;
|
||||
multiinput = 0;
|
||||
directors = 0;
|
||||
}
|
||||
|
||||
Language::~Language() {
|
||||
|
|
@ -1292,6 +1293,265 @@ int Language::typedefHandler(Node *) {
|
|||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDirectorMethod()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::classDirectorMethod(Node *n, Node *parent, String* super) {
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDirectorConstructor()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::classDirectorConstructor(Node *n) {
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDirectorDefaultConstructor()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::classDirectorDefaultConstructor(Node *n) {
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::tagDirectorBases()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::tagDirectorBases(Node *n) {
|
||||
List* bl;
|
||||
if (Getattr(n, "directorBase")) return SWIG_OK;
|
||||
if (Getattr(n, "hasVirtual") == 0) return SWIG_OK;
|
||||
Setattr(n, "directorBase", "1");
|
||||
bl = Getattr(n, "bases");
|
||||
if (bl) {
|
||||
Node* bi;
|
||||
for (bi = Firstitem(bl); bi; bi = Nextitem(bl)) {
|
||||
tagDirectorBases(bi);
|
||||
}
|
||||
}
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::unrollVirtualMethods()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::unrollVirtualMethods(Node *n,
|
||||
Node *parent,
|
||||
Hash *vm,
|
||||
int default_director,
|
||||
int &virtual_destructor,
|
||||
int &has_virtual) {
|
||||
int only_virtual = (Getattr(parent, "director:nonvirtual") == 0);
|
||||
int top = (n == parent);
|
||||
has_virtual = 0;
|
||||
Node *ni;
|
||||
String *type;
|
||||
String *nodeType;
|
||||
String *cdecl;
|
||||
String *storage;
|
||||
String *classname;
|
||||
String *decl;
|
||||
// default_director < 0 turns off director generation for this class and all its superclasses
|
||||
if (default_director >= 0) {
|
||||
if (Getattr(n, "feature:director")) default_director = 1;
|
||||
if (Getattr(n, "feature:nodirector")) default_director = -1;
|
||||
}
|
||||
classname = Getattr(n, "name");
|
||||
for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
|
||||
nodeType = Getattr(ni, "nodeType");
|
||||
storage = Getattr(ni, "storage");
|
||||
cdecl = Getattr(ni, "cdecl");
|
||||
decl = Getattr(ni, "decl");
|
||||
if (!Cmp(nodeType, "cdecl") && SwigType_isfunction(decl)) {
|
||||
int is_virtual = storage && !Cmp(storage, "virtual");
|
||||
if (is_virtual) has_virtual = 1;
|
||||
String* access = Getattr(ni, "access");
|
||||
if (!access || !Cmp(access, "public")) {
|
||||
if (!only_virtual || is_virtual) {
|
||||
String *method_id;
|
||||
String *name = Getattr(ni, "name");
|
||||
method_id = NewStringf("%s|%s", name, decl);
|
||||
int director = default_director;
|
||||
if (director >= 0) {
|
||||
if (Getattr(ni, "feature:director")) director = 1;
|
||||
if (Getattr(ni, "feature:nodirector")) director = 0;
|
||||
}
|
||||
if ((director == 1) && !Getattr(vm, method_id)) {
|
||||
String *fqname = NewString("");
|
||||
Printf(fqname, "%s::%s", classname, name);
|
||||
Hash *item = NewHash();
|
||||
Setattr(item, "fqName", fqname);
|
||||
Setattr(item, "methodNode", ni);
|
||||
Setattr(vm, method_id, item);
|
||||
Delete(fqname);
|
||||
Delete(item);
|
||||
}
|
||||
Delete(method_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!Cmp(nodeType, "destructor")) {
|
||||
if (storage && !Cmp(storage, "virtual")) {
|
||||
virtual_destructor = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
List* bl = Getattr(n, "bases");
|
||||
if (bl) {
|
||||
Node* bi;
|
||||
for (bi = Firstitem(bl); bi; bi = Nextitem(bl)) {
|
||||
int virtual_base = 0;
|
||||
unrollVirtualMethods(bi, parent, vm, default_director, virtual_destructor, virtual_base);
|
||||
if (virtual_base) {
|
||||
has_virtual = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (has_virtual) {
|
||||
Setattr(n, "hasVirtual", "1");
|
||||
}
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDirectorDisown()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::classDirectorDisown(Node *n) {
|
||||
Node *disown = NewHash();
|
||||
String *mrename;
|
||||
String *symname = Getattr(n,"sym:name");
|
||||
mrename = Swig_name_disown(symname); //Getattr(n, "name"));
|
||||
String *type = NewString(ClassType);
|
||||
String *name = NewString("self");
|
||||
SwigType_add_pointer(type);
|
||||
Parm *p = NewParm(type, name);
|
||||
Delete(name);
|
||||
Delete(type);
|
||||
type = NewString("void");
|
||||
String *action = NewString("");
|
||||
Printv(action, "{\n",
|
||||
"__DIRECTOR__ *director = dynamic_cast<__DIRECTOR__*>(arg1);\n",
|
||||
"if (director) director->__disown();\n",
|
||||
"}\n",
|
||||
NULL);
|
||||
Setattr(disown, "wrap:action", action);
|
||||
Setattr(disown,"name", mrename);
|
||||
Setattr(disown,"sym:name", mrename);
|
||||
Setattr(disown,"type",type);
|
||||
Setattr(disown,"parms", p);
|
||||
Delete(action);
|
||||
Delete(mrename);
|
||||
Delete(type);
|
||||
Delete(p);
|
||||
|
||||
functionWrapper(disown);
|
||||
Delete(disown);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDirectorConstructors()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::classDirectorConstructors(Node *n) {
|
||||
Node *ni;
|
||||
String *nodeType;
|
||||
int constructor = 0;
|
||||
for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
|
||||
nodeType = Getattr(ni, "nodeType");
|
||||
if (!Cmp(nodeType, "constructor")) {
|
||||
classDirectorConstructor(ni);
|
||||
constructor = 1;
|
||||
}
|
||||
}
|
||||
if (!constructor) {
|
||||
classDirectorDefaultConstructor(n);
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDirectorMethods()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::classDirectorMethods(Node *n) {
|
||||
Node *vtable = Getattr(n, "vtable");
|
||||
Node *item;
|
||||
String *key;
|
||||
for (key = Firstkey(vtable); key != 0; key = Nextkey(vtable)) {
|
||||
item = Getattr(vtable, key);
|
||||
String *method = Getattr(item, "methodNode");
|
||||
String *fqname = Getattr(item, "fqName");
|
||||
if (classDirectorMethod(method, n, fqname) == SWIG_OK) {
|
||||
Setattr(item, "director", "1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDirectorInit()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::classDirectorInit(Node *n) {
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDirectorEnd()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::classDirectorEnd(Node *n) {
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDirector()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::classDirector(Node *n) {
|
||||
Node *module = Getattr(n,"module");
|
||||
String *classtype = Getattr(n, "classtype");
|
||||
Hash *directormap = 0;
|
||||
if (module) {
|
||||
directormap = Getattr(module, "wrap:directormap");
|
||||
if (directormap == 0) {
|
||||
directormap = NewHash();
|
||||
Setattr(module, "wrap:directormap", directormap);
|
||||
}
|
||||
}
|
||||
Hash* vtable = NewHash();
|
||||
int virtual_destructor = 0;
|
||||
int has_virtual = 0;
|
||||
unrollVirtualMethods(n, n, vtable, 0, virtual_destructor, has_virtual);
|
||||
if (Len(vtable) > 0) {
|
||||
if (!virtual_destructor) {
|
||||
String *classtype = Getattr(n, "classtype");
|
||||
Swig_warning(WARN_LANG_DIRECTOR_VDESTRUCT, input_file, line_number,
|
||||
"Director base class %s has no virtual destructor.\n",
|
||||
classtype);
|
||||
}
|
||||
Setattr(n, "vtable", vtable);
|
||||
tagDirectorBases(n);
|
||||
classDirectorInit(n);
|
||||
classDirectorConstructors(n);
|
||||
classDirectorMethods(n);
|
||||
classDirectorEnd(n);
|
||||
if (directormap != 0) {
|
||||
Setattr(directormap, classtype, n);
|
||||
}
|
||||
}
|
||||
Delete(vtable);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDeclaration()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
|
@ -1339,6 +1599,12 @@ int Language::classDeclaration(Node *n) {
|
|||
}
|
||||
Setattr(n,"classtype", SwigType_namestr(ClassType));
|
||||
|
||||
/*
|
||||
if (CPlusPlus) {
|
||||
classDirector(n);
|
||||
}
|
||||
*/
|
||||
|
||||
InClass = 1;
|
||||
CurrentClass = n;
|
||||
|
||||
|
|
@ -1349,10 +1615,14 @@ int Language::classDeclaration(Node *n) {
|
|||
}
|
||||
|
||||
/* Call classHandler() here */
|
||||
if (!ImportMode)
|
||||
if (!ImportMode) {
|
||||
if (CPlusPlus && directorsEnabled()) {
|
||||
classDirector(n);
|
||||
}
|
||||
classHandler(n);
|
||||
else
|
||||
} else {
|
||||
Language::classHandler(n);
|
||||
}
|
||||
|
||||
InClass = 0;
|
||||
CurrentClass = 0;
|
||||
|
|
@ -1399,6 +1669,12 @@ int Language::classHandler(Node *n) {
|
|||
destructorHandler(CurrentClass);
|
||||
}
|
||||
}
|
||||
|
||||
/* emit director disown method */
|
||||
if (Getattr(n, "vtable")) {
|
||||
classDirectorDisown(n);
|
||||
}
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1816,6 +2092,30 @@ void Language::allow_multiple_input(int val) {
|
|||
multiinput = val;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Language::allow_directors()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void Language::allow_directors(int val) {
|
||||
directors = val;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Language::directorsEnabled()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
int Language::directorsEnabled() const {
|
||||
return directors;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Language::is_smart_pointer()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
int Language::is_smart_pointer() const {
|
||||
return SmartPointer;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Language::is_wrapping_class()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ static char *usage = (char*)"\
|
|||
-swiglib - Report location of SWIG library and exit\n\
|
||||
-v - Run in verbose mode\n\
|
||||
-fcompact - Compile in compact mode\n\
|
||||
-fdirectors - Enable C++ directors\n\
|
||||
-fvirtual - Compile in virtual elimination mode\n\
|
||||
-small - Compile in virtual elimination & compact mode\n\
|
||||
-version - Print SWIG version number\n\
|
||||
|
|
@ -189,6 +190,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
int dump_classes = 0;
|
||||
int werror = 0;
|
||||
int depend = 0;
|
||||
int directors = 0;
|
||||
|
||||
DOH *libfiles = 0;
|
||||
DOH *cpps = 0 ;
|
||||
|
|
@ -285,6 +287,9 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
} else if (strcmp(temp, "-small") == 0) {
|
||||
Wrapper_compact_print_mode_set(1);
|
||||
Wrapper_virtual_elimination_mode_set(1);
|
||||
} else if (strcmp(temp, "-fdirectors") == 0) {
|
||||
directors = 1;
|
||||
lang->allow_directors();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -324,6 +329,10 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
Wrapper_compact_print_mode_set(1);
|
||||
Wrapper_virtual_elimination_mode_set(1);
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-fdirectors") == 0) {
|
||||
directors = 1;
|
||||
lang->allow_directors();
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i],"-c") == 0) {
|
||||
NoInclude=1;
|
||||
Preprocessor_define((DOH *) "SWIG_NOINCLUDE 1", 0);
|
||||
|
|
@ -534,6 +543,9 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
if (lang_config) {
|
||||
Printf(fs,"\n%%include \"%s\"\n", lang_config);
|
||||
}
|
||||
if (directors) {
|
||||
Printf(fs,"\n%%include \"director.swg\"\n");
|
||||
}
|
||||
Printf(fs,"%%include \"%s\"\n", Swig_last_file());
|
||||
for (i = 0; i < Len(libfiles); i++) {
|
||||
Printf(fs,"\n%%include \"%s\"\n", Getitem(libfiles,i));
|
||||
|
|
@ -631,8 +643,15 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
} else {
|
||||
Setattr(top,"outfile", NewStringf("%s_wrap.c", Swig_file_basename(input_file)));
|
||||
}
|
||||
Setattr(top,"outfile_h", NewStringf("%s_wrap.h", Swig_file_basename(input_file)));
|
||||
} else {
|
||||
char *header = strdup(outfile_name);
|
||||
char *ext = header + strlen(header);
|
||||
while (ext > header && *ext != '.') ext--;
|
||||
if (*ext == '.') *ext = 0;
|
||||
Setattr(top,"outfile", outfile_name);
|
||||
Setattr(top,"outfile_h", NewStringf("%s.h", header));
|
||||
free(header);
|
||||
}
|
||||
if (contracts) {
|
||||
Swig_contracts(top);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -178,23 +178,48 @@ public:
|
|||
virtual int functionWrapper(Node *n);
|
||||
virtual int nativeWrapper(Node *n);
|
||||
|
||||
/* C++ director class generation */
|
||||
virtual int classDirector(Node *n);
|
||||
virtual int classDirectorInit(Node *n);
|
||||
virtual int classDirectorEnd(Node *n);
|
||||
virtual int tagDirectorBases(Node *n);
|
||||
virtual int unrollVirtualMethods(Node *n,
|
||||
Node *parent,
|
||||
Hash *vm,
|
||||
int default_director,
|
||||
int &virtual_destructor,
|
||||
int &has_virtual);
|
||||
virtual int classDirectorConstructor(Node *n);
|
||||
virtual int classDirectorDefaultConstructor(Node *n);
|
||||
virtual int classDirectorMethod(Node *n, Node *parent, String *super);
|
||||
virtual int classDirectorConstructors(Node *n);
|
||||
virtual int classDirectorMethods(Node *n);
|
||||
virtual int classDirectorDisown(Node *n);
|
||||
|
||||
/* Miscellaneous */
|
||||
|
||||
virtual int validIdentifier(String *s); /* valid identifier? */
|
||||
virtual int addSymbol(String *s, Node *n); /* Add symbol */
|
||||
virtual Node *symbolLookup(String *s); /* Symbol lookup */
|
||||
virtual Node *classLookup(SwigType *s); /* Class lookup */
|
||||
|
||||
/* Allow director related code generation */
|
||||
void allow_directors(int val = 1);
|
||||
|
||||
/* Return true if directors are enabled */
|
||||
int directorsEnabled() const;
|
||||
|
||||
|
||||
protected:
|
||||
/* Patch C++ pass-by-value */
|
||||
static void patch_parms(Parm *p);
|
||||
|
||||
/* Allow overloaded functions */
|
||||
void allow_overloading(int val = 1);
|
||||
|
||||
/* Allow multiple-input typemaps */
|
||||
void allow_multiple_input(int val = 1);
|
||||
|
||||
/* Allow overloaded functions */
|
||||
void allow_overloading(int val = 1);
|
||||
|
||||
/* Wrapping class query */
|
||||
int is_wrapping_class();
|
||||
|
||||
|
|
@ -210,11 +235,16 @@ public:
|
|||
/* Fully qualified type name to use */
|
||||
String *getClassType() const;
|
||||
|
||||
/* Return true if the current method is part of a smart-pointer */
|
||||
int is_smart_pointer() const;
|
||||
|
||||
private:
|
||||
Hash *symbols;
|
||||
Hash *classtypes;
|
||||
int overloading;
|
||||
int multiinput;
|
||||
int directors;
|
||||
|
||||
};
|
||||
|
||||
extern int SWIG_main(int, char **, Language *);
|
||||
|
|
|
|||
|
|
@ -341,13 +341,17 @@ Swig_cconstructor_call(String_or_char *name) {
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
String *
|
||||
Swig_cppconstructor_call(String_or_char *name, ParmList *parms) {
|
||||
Swig_cppconstructor_base_call(String_or_char *name, ParmList *parms, int skip_self, int disown) {
|
||||
String *func;
|
||||
String *nname;
|
||||
int i = 0;
|
||||
int comma = 0;
|
||||
Parm *p = parms;
|
||||
SwigType *pt;
|
||||
if (skip_self) {
|
||||
if (p) p = nextSibling(p);
|
||||
i++;
|
||||
}
|
||||
nname = SwigType_namestr(name);
|
||||
func = NewString("");
|
||||
Printf(func,"new %s(", nname);
|
||||
|
|
@ -363,11 +367,29 @@ Swig_cppconstructor_call(String_or_char *name, ParmList *parms) {
|
|||
}
|
||||
p = nextSibling(p);
|
||||
}
|
||||
if (disown >= 0) {
|
||||
if (comma) Printf(func, ",");
|
||||
Printf(func, "%d", disown);
|
||||
}
|
||||
Printf(func,")");
|
||||
Delete(nname);
|
||||
return func;
|
||||
}
|
||||
|
||||
String *
|
||||
Swig_cppconstructor_call(String_or_char *name, ParmList *parms) {
|
||||
return Swig_cppconstructor_base_call(name, parms, 0, -1);
|
||||
}
|
||||
|
||||
String *
|
||||
Swig_cppconstructor_nodirector_call(String_or_char *name, ParmList *parms) {
|
||||
return Swig_cppconstructor_base_call(name, parms, 1, -1);
|
||||
}
|
||||
|
||||
String *
|
||||
Swig_cppconstructor_director_call(String_or_char *name, ParmList *parms) {
|
||||
return Swig_cppconstructor_base_call(name, parms, 0, 0);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_cdestructor_call()
|
||||
|
|
@ -473,7 +495,7 @@ Swig_MethodToFunction(Node *n, String *classname, int flags) {
|
|||
name = Getattr(n,"name");
|
||||
qualifier = Getattr(n,"qualifier");
|
||||
parms = CopyParmList(nonvoid_parms(Getattr(n,"parms")));
|
||||
|
||||
|
||||
type = NewString(classname);
|
||||
if (qualifier) {
|
||||
SwigType_push(type,qualifier);
|
||||
|
|
@ -524,6 +546,62 @@ Swig_MethodToFunction(Node *n, String *classname, int flags) {
|
|||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_methodclass()
|
||||
*
|
||||
* This function returns the class node for a given method or class.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
Node*
|
||||
Swig_methodclass(Node *n) {
|
||||
Node* type = Getattr(n, "nodeType");
|
||||
if (!Cmp(type, "class")) return n;
|
||||
return Getattr(n, "parentNode");
|
||||
}
|
||||
|
||||
int
|
||||
Swig_directorbase(Node *n) {
|
||||
Node *classNode = Swig_methodclass(n);
|
||||
return (classNode && (Getattr(classNode, "directorBase") != 0));
|
||||
}
|
||||
|
||||
int
|
||||
Swig_directorclass(Node *n) {
|
||||
Node *classNode = Swig_methodclass(n);
|
||||
return (Getattr(classNode, "vtable") != 0);
|
||||
}
|
||||
|
||||
int
|
||||
Swig_directormethod(Node *n) {
|
||||
Node *classNode = Swig_methodclass(n);
|
||||
if (classNode) {
|
||||
Node *vtable = Getattr(classNode, "vtable");
|
||||
if (vtable) {
|
||||
String *name = Getattr(n, "name");
|
||||
String *decl = Getattr(n, "decl");
|
||||
String *method_id = NewStringf("%s|%s", name, decl);
|
||||
Hash *item = Getattr(vtable, method_id);
|
||||
Delete(method_id);
|
||||
if (item) {
|
||||
return (Getattr(item, "director") != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Node *
|
||||
Swig_directormap(Node *module, String *type) {
|
||||
int is_void = !Cmp(type, "void");
|
||||
if (!is_void && module) {
|
||||
String* base = SwigType_base(type);
|
||||
Node *directormap = Getattr(module, "wrap:directormap");
|
||||
if (directormap) return Getattr(directormap, base);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_ConstructorToFunction()
|
||||
*
|
||||
|
|
@ -537,10 +615,17 @@ Swig_ConstructorToFunction(Node *n, String *classname, int cplus, int flags)
|
|||
SwigType *type;
|
||||
String *membername;
|
||||
String *mangled;
|
||||
Node *classNode;
|
||||
int use_director;
|
||||
|
||||
classNode = Swig_methodclass(n);
|
||||
use_director = Swig_directorclass(n);
|
||||
|
||||
membername = Swig_name_construct(classname);
|
||||
mangled = Swig_name_mangle(membername);
|
||||
|
||||
parms = CopyParmList(nonvoid_parms(Getattr(n,"parms")));
|
||||
|
||||
type = NewString(classname);
|
||||
SwigType_add_pointer(type);
|
||||
|
||||
|
|
@ -558,7 +643,27 @@ Swig_ConstructorToFunction(Node *n, String *classname, int cplus, int flags)
|
|||
Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cfunction_call(mangled,parms)));
|
||||
} else {
|
||||
if (cplus) {
|
||||
Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cppconstructor_call(classname,parms)));
|
||||
/* if a C++ director class exists, create it rather than the original class */
|
||||
if (use_director) {
|
||||
Node *parent = Swig_methodclass(n);
|
||||
String *name = Getattr(parent, "sym:name");
|
||||
String* directorname = NewStringf("__DIRECTOR__%s", name);
|
||||
String* action = NewString("");
|
||||
/* if Python class has been subclassed, create a director instance.
|
||||
* otherwise, just create a normal instance.
|
||||
*/
|
||||
Printv(action, "if (arg1 != Py_None) { // subclassed\n",
|
||||
Swig_cresult(type, "result", Swig_cppconstructor_director_call(directorname, parms)),
|
||||
"} else {\n",
|
||||
Swig_cresult(type, "result", Swig_cppconstructor_nodirector_call(classname, parms)),
|
||||
"}\n",
|
||||
NULL);
|
||||
Setattr(n, "wrap:action", action);
|
||||
Delete(action);
|
||||
Delete(directorname);
|
||||
} else {
|
||||
Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cppconstructor_call(classname,parms)));
|
||||
}
|
||||
} else {
|
||||
Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cconstructor_call(classname)));
|
||||
}
|
||||
|
|
@ -583,7 +688,8 @@ Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags)
|
|||
{
|
||||
SwigType *type;
|
||||
Parm *p;
|
||||
|
||||
Node *classNode;
|
||||
|
||||
type = NewString(classname);
|
||||
SwigType_add_pointer(type);
|
||||
p = NewParm(type,"self");
|
||||
|
|
@ -606,7 +712,9 @@ Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags)
|
|||
Delete(mangled);
|
||||
} else {
|
||||
if (cplus) {
|
||||
Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cppdestructor_call()));
|
||||
String* action = NewString("");
|
||||
Printf(action, "%s;\n", Swig_cppdestructor_call());
|
||||
Setattr(n,"wrap:action", action);
|
||||
} else {
|
||||
Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cdestructor_call()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -341,6 +341,40 @@ String *Swig_name_destroy(const String_or_char *classname) {
|
|||
return r;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_name_disown()
|
||||
*
|
||||
* Returns the name of the accessor function used to disown an object.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
String *Swig_name_disown(const String_or_char *classname) {
|
||||
String *r;
|
||||
String *f;
|
||||
String *rclassname;
|
||||
char *cname;
|
||||
rclassname = SwigType_namestr(classname);
|
||||
r = NewString("");
|
||||
if (!naming_hash) naming_hash = NewHash();
|
||||
f = Getattr(naming_hash,"disown");
|
||||
if (!f) {
|
||||
Append(r,"disown_%c");
|
||||
} else {
|
||||
Append(r,f);
|
||||
}
|
||||
|
||||
cname = Char(rclassname);
|
||||
if ((strncmp(cname,"struct ", 7) == 0) ||
|
||||
((strncmp(cname,"class ", 6) == 0)) ||
|
||||
((strncmp(cname,"union ", 6) == 0))) {
|
||||
cname = strchr(cname, ' ')+1;
|
||||
}
|
||||
Replace(r,"%c",cname, DOH_REPLACE_ANY);
|
||||
Delete(rclassname);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_name_object_set()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -347,6 +347,7 @@ SwigType_function_parms(SwigType *t) {
|
|||
return firstp;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* SwigType_add_template()
|
||||
*
|
||||
|
|
@ -561,6 +562,7 @@ String *SwigType_parm(SwigType *t) {
|
|||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* SwigType_ispointer()
|
||||
* SwigType_ispointer_return()
|
||||
* SwigType_isarray()
|
||||
* SwigType_isreference()
|
||||
* SwigType_isfunction()
|
||||
|
|
@ -584,6 +586,30 @@ int SwigType_ispointer(SwigType *t) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int SwigType_ispointer_return(SwigType *t) {
|
||||
char* c;
|
||||
int idx;
|
||||
if (!t) return 0;
|
||||
c = Char(t);
|
||||
idx = strlen(c)-4;
|
||||
if (idx >= 0) {
|
||||
return (strcmp(c+idx, ").p.") == 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SwigType_isreference_return(SwigType *t) {
|
||||
char* c;
|
||||
int idx;
|
||||
if (!t) return 0;
|
||||
c = Char(t);
|
||||
idx = strlen(c)-4;
|
||||
if (idx >= 0) {
|
||||
return (strcmp(c+idx, ").r.") == 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SwigType_ismemberpointer(SwigType *t) {
|
||||
char *c;
|
||||
if (!t) return 0;
|
||||
|
|
|
|||
|
|
@ -213,8 +213,10 @@ extern String *SwigType_lcaststr(SwigType *s, const String_or_char *id);
|
|||
extern String *SwigType_manglestr(SwigType *t);
|
||||
extern SwigType *SwigType_ltype(SwigType *t);
|
||||
extern int SwigType_ispointer(SwigType *t);
|
||||
extern int SwigType_ispointer_return(SwigType *t);
|
||||
extern int SwigType_ismemberpointer(SwigType *t);
|
||||
extern int SwigType_isreference(SwigType *t);
|
||||
extern int SwigType_isreference_return(SwigType *t);
|
||||
extern int SwigType_isarray(SwigType *t);
|
||||
extern int SwigType_isfunction(SwigType *t);
|
||||
extern int SwigType_isqualifier(SwigType *t);
|
||||
|
|
@ -378,6 +380,7 @@ extern String *Swig_name_set(const String_or_char *vname);
|
|||
extern String *Swig_name_construct(const String_or_char *classname);
|
||||
extern String *Swig_name_copyconstructor(const String_or_char *classname);
|
||||
extern String *Swig_name_destroy(const String_or_char *classname);
|
||||
extern String *Swig_name_disown(const String_or_char *classname);
|
||||
|
||||
/* --- parameterized rename functions --- */
|
||||
|
||||
|
|
@ -443,6 +446,13 @@ extern int Swig_VarsetToFunction(Node *n);
|
|||
#define CWRAP_EXTEND 0x01
|
||||
#define CWRAP_SMART_POINTER 0x02
|
||||
|
||||
/* --- Director Helpers --- */
|
||||
extern Node *Swig_methodclass(Node *n);
|
||||
extern int Swig_directorbase(Node *n);
|
||||
extern int Swig_directorclass(Node *n);
|
||||
extern int Swig_directormethod(Node *n);
|
||||
extern Node *Swig_directormap(Node *n, String *type);
|
||||
|
||||
/* --- Legacy Typemap API (somewhat simplified, ha!) --- */
|
||||
|
||||
extern void Swig_typemap_init();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue