add better director+exception support

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@7038 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2005-03-07 20:47:55 +00:00
commit ca7159f7e7
9 changed files with 203 additions and 108 deletions

View file

@ -10,10 +10,6 @@
#ifdef __cplusplus
namespace Swig {
/* base class for director exceptions */
DirectorException::~DirectorException() {
}
/* simple thread abstraction for pthreads on win32 */
Director::~Director() {
swig_decref();
@ -27,6 +23,23 @@ namespace Swig {
bool Director::swig_mutex_active = false;
#endif
void UnknownExceptionHandler::handler() {
try {
throw;
} catch (DirectorException& e) {
std::cerr << "Swig Director exception caught: "<< e.getMessage() << std::endl;
} catch (std::exception& e) {
std::cerr << "std::exception caught: "<< e.what() << std::endl;
} catch (...) {
std::cerr << "Unknown exception caught." << std::endl;
}
std::cerr << "This exception was caught by the SWIG unexpected exception handler." << std::endl;
std::cerr << "Try using %feature(\"director:except\") to avoid reaching this point." << std::endl;
std::cerr << "Now your program will probably be terminated, bye." << std::endl;
throw;
}
}
#endif /* __cplusplus */

View file

@ -12,6 +12,20 @@
#ifdef __cplusplus
#include <string>
#include <iostream>
#include <exception>
/*
Use -DSWIG_DIRECTOR_NOUEH if you prefer to avoid the use of the
Undefined Exception Handler provided by swift
*/
#ifndef SWIG_DIRECTOR_NOUEH
#ifndef SWIG_DIRECTOR_UEH
#define SWIG_DIRECTOR_UEH
#endif
#endif
/*
Use -DSWIG_DIRECTOR_STATIC if you prefer to avoid the use of the
@ -69,32 +83,63 @@ extern "C" {
struct swig_type_info;
}
namespace Swig {
namespace Swig {
/* base class for director exceptions */
class DirectorException {
protected:
std::string swig_msg;
public:
DirectorException(const char* msg ="") : swig_msg(msg) {
DirectorException(const char* hdr ="", const char* msg ="")
: swig_msg(hdr) {
swig_msg += msg;
if (!PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, getMessage());
} else {
SWIG_Python_AddErrMesg(getMessage(), 1);
}
}
const char *getMessage() const {
return swig_msg.c_str();
}
virtual ~DirectorException();
static void raise(const char* msg = "")
{
throw DirectorException(msg);
}
};
class UnknownExceptionHandler
{
static void handler();
public:
#ifdef SWIG_DIRECTOR_UEH
std::unexpected_handler old;
UnknownExceptionHandler(std::unexpected_handler nh = handler)
{
old = std::set_unexpected(nh);
}
~UnknownExceptionHandler()
{
std::set_unexpected(old);
}
#endif
};
/* type mismatch in the return value from a python method call */
class DirectorTypeMismatchException : public Swig::DirectorException {
public:
DirectorTypeMismatchException(const char* msg="") {
if (!PyErr_Occurred()) {
swig_msg = "Swig director type mismatch: ";
swig_msg += msg;
PyErr_SetString(PyExc_TypeError, getMessage());
}
DirectorTypeMismatchException(const char* msg="")
: Swig::DirectorException("Swig director type mismatch: ", msg) {
}
static void raise(const char* msg = "")
{
throw DirectorTypeMismatchException(msg);
}
};
@ -102,13 +147,30 @@ namespace Swig {
class DirectorMethodException : public Swig::DirectorException {
public:
DirectorMethodException(const char* msg = "")
: DirectorException(msg)
: DirectorException("Swig director python method error: ", msg)
{
}
static void raise(const char* msg = "")
{
throw DirectorMethodException(msg);
}
};
/* attempt to call a pure virtual method via a director method */
class DirectorPureVirtualException : public Swig::DirectorException {};
class DirectorPureVirtualException : public Swig::DirectorException
{
public:
DirectorPureVirtualException(const char* msg = "")
: DirectorException("Swig director pure virtal method called: ", msg)
{
}
static void raise(const char* msg = "")
{
throw DirectorPureVirtualException(msg);
}
};
/* simple thread abstraction for pthreads on win32 */

View file

@ -76,58 +76,71 @@ swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) {
return 1;
}
SWIGINTERN PyTypeObject varlinktype = {
PyObject_HEAD_INIT(0)
0, /* Number of items in variable part (ob_size) */
(char *)"swigvarlink", /* Type name (tp_name) */
sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */
0, /* Itemsize (tp_itemsize) */
0, /* Deallocator (tp_dealloc) */
(printfunc) swig_varlink_print, /* Print (tp_print) */
(getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */
(setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */
0, /* tp_compare */
(reprfunc) swig_varlink_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
0, /* tp_flags */
0, /* tp_doc */
SWIGINTERN PyTypeObject*
swig_varlink_type() {
static char varlink__doc__[] = "Swig var link object";
static PyTypeObject varlink_type
#if !defined(__cplusplus)
;
static int type_init = 0;
if (!type_init) {
PyTypeObject tmp
#endif
= {
PyObject_HEAD_INIT(&PyType_Type)
0, /* Number of items in variable part (ob_size) */
(char *)"swigvarlink", /* Type name (tp_name) */
sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */
0, /* Itemsize (tp_itemsize) */
0, /* Deallocator (tp_dealloc) */
(printfunc) swig_varlink_print, /* Print (tp_print) */
(getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */
(setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */
0, /* tp_compare */
(reprfunc) swig_varlink_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
0, /* tp_flags */
varlink__doc__, /* tp_doc */
#if PY_VERSION_HEX >= 0x02000000
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_traverse */
0, /* tp_clear */
#endif
#if PY_VERSION_HEX >= 0x02010000
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
#endif
#if PY_VERSION_HEX >= 0x02020000
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */
#endif
#if PY_VERSION_HEX >= 0x02030000
0, /* tp_del */
0, /* tp_del */
#endif
#ifdef COUNT_ALLOCS
0,0,0,0 /* tp_alloc -> tp_next */
0,0,0,0 /* tp_alloc -> tp_next */
#endif
};
};
#if !defined(__cplusplus)
varlink_type = tmp;
type_init = 1;
}
#endif
return &varlink_type;
}
/* Create a variable linking object for use later */
SWIGINTERN PyObject *
SWIG_Python_newvarlink(void) {
swig_varlinkobject *result = PyMem_NEW(swig_varlinkobject,1);
swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type());
if (result) {
varlinktype.ob_type = &PyType_Type; /* Patch varlinktype into a PyType */
result->ob_type = &varlinktype;
result->vars = 0;
result->ob_refcnt = 0;
Py_INCREF((PyObject *) result);
}
return ((PyObject*) result);
}
@ -222,13 +235,15 @@ SWIG_Python_FixMethods(PyMethodDef *methods,
char *ndoc = (char*)malloc(ldoc + lptr + 10);
if (ndoc) {
char *buff = ndoc;
void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue: (void *)(ci->lvalue);
strncpy(buff, methods[i].ml_doc, ldoc);
buff += ldoc;
strncpy(buff, "swig_ptr: ", 10);
buff += 10;
SWIG_PackVoidPtr(buff, ptr, ty->name, lptr);
methods[i].ml_doc = ndoc;
void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0;
if (ptr) {
strncpy(buff, methods[i].ml_doc, ldoc);
buff += ldoc;
strncpy(buff, "swig_ptr: ", 10);
buff += 10;
SWIG_PackVoidPtr(buff, ptr, ty->name, lptr);
methods[i].ml_doc = ndoc;
}
}
}
}

View file

@ -65,7 +65,7 @@
Type *ptr = 0;
int res = $input ? asptr_meth($input, &ptr) : 0;
if (!res || !ptr)
throw Swig::DirectorTypeMismatchException("Error converting Python object using asptr_meth");
Swig::DirectorTypeMismatchException::raise("Error converting Python object when using asptr_meth.");
temp = *ptr;
$result = &temp;
if (res == SWIG_NEWOBJ) delete ptr;
@ -75,7 +75,7 @@
Type *ptr = 0;
int res = $input ? asptr_meth($input, &ptr) : 0;
if (!res || !ptr)
throw Swig::DirectorTypeMismatchException("Error converting Python object using asptr_meth");
Swig::DirectorTypeMismatchException::raise("Error converting Python object when using asptr_meth.");
$result = *ptr;
if (res == SWIG_NEWOBJ) delete ptr;
}
@ -84,7 +84,7 @@
Type *ptr = 0;
int res = $input ? asptr_meth($input, &ptr) : 0;
if (!res || !ptr)
throw Swig::DirectorTypeMismatchException("Error converting Python object using asptr_meth");
Swig::DirectorTypeMismatchException::raise("Error converting Python object when using asptr_meth.");
$result = ptr;
if (res == SWIG_NEWOBJ) {
/* Possible thread/reentrant problem here! */

View file

@ -105,7 +105,7 @@ PySwigObject_long(PySwigObject *v)
}
SWIGRUNTIME PyObject *
PySwigObject_format(PySwigObject *v, const char* fmt)
PySwigObject_format(const char* fmt, PySwigObject *v)
{
PyObject *res = NULL;
PyObject *args = PyTuple_New(1);
@ -123,13 +123,13 @@ PySwigObject_format(PySwigObject *v, const char* fmt)
SWIGRUNTIME PyObject *
PySwigObject_oct(PySwigObject *v)
{
return PySwigObject_format(v,"%o");
return PySwigObject_format("%o",v);
}
SWIGRUNTIME PyObject *
PySwigObject_hex(PySwigObject *v)
{
return PySwigObject_format(v,"%x");
return PySwigObject_format("%x",v);
}
SWIGRUNTIME int
@ -152,8 +152,8 @@ PySwigObject_dealloc(PySwigObject *self)
}
SWIGRUNTIME PyTypeObject*
PySwigObject_GetType() {
static char PySwigObject_Type__doc__[] =
PySwigObject_type() {
static char pyswigobject_type__doc__[] =
"Swig object carries a C/C++ instance pointer";
static PyNumberMethods PySwigObject_as_number = {
@ -185,11 +185,14 @@ PySwigObject_GetType() {
#endif
};
static int type_init = 0;
static PyTypeObject PySwigObject_Type;
static PyTypeObject pyswigobject_type
#if !defined(__cplusplus)
;
static int type_init = 0;
if (!type_init) {
PyTypeObject tmp = {
PyTypeObject tmp
#endif
= {
PyObject_HEAD_INIT(&PyType_Type)
0, /*ob_size*/
"PySwigObject", /*tp_name*/
@ -210,7 +213,7 @@ PySwigObject_GetType() {
(reprfunc)PySwigObject_str, /*tp_str*/
/* Space for future expansion */
0,0,0,0,
PySwigObject_Type__doc__, /* Documentation string */
pyswigobject_type__doc__, /* Documentation string */
#if PY_VERSION_HEX >= 0x02000000
0, /* tp_traverse */
0, /* tp_clear */
@ -229,21 +232,22 @@ PySwigObject_GetType() {
0,0,0,0 /* tp_alloc -> tp_next */
#endif
};
PySwigObject_Type = tmp;
#if !defined(__cplusplus)
pyswigobject_type = tmp;
type_init = 1;
}
return &PySwigObject_Type;
#endif
return &pyswigobject_type;
}
SWIGRUNTIME PyObject *
PySwigObject_FromVoidPtrAndDesc(void *ptr, const char *desc)
{
PySwigObject *self = PyObject_NEW(PySwigObject, PySwigObject_GetType());
if (self == NULL) return NULL;
self->ptr = ptr;
self->desc = desc;
PySwigObject *self = PyObject_NEW(PySwigObject, PySwigObject_type());
if (self) {
self->ptr = ptr;
self->desc = desc;
}
return (PyObject *)self;
}
@ -261,7 +265,7 @@ PySwigObject_GetDesc(PyObject *self)
SWIGRUNTIMEINLINE int
PySwigObject_Check(PyObject *op) {
return ((op)->ob_type == PySwigObject_GetType())
return ((op)->ob_type == PySwigObject_type())
|| (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0);
}
@ -335,14 +339,17 @@ PySwigPacked_dealloc(PySwigPacked *self)
}
SWIGRUNTIME PyTypeObject*
PySwigPacked_GetType() {
static char PySwigPacked_Type__doc__[] =
PySwigPacked_type() {
static char pyswigpacked_type__doc__[] =
"Swig object carries a C/C++ instance pointer";
static int type_init = 0;
static PyTypeObject PySwigPacked_Type;
static PyTypeObject pyswigpacked_type
#if !defined(__cplusplus)
;
static int type_init = 0;
if (!type_init) {
PyTypeObject tmp = {
PyTypeObject tmp
#endif
= {
PyObject_HEAD_INIT(&PyType_Type)
0, /*ob_size*/
"PySwigPacked", /*tp_name*/
@ -363,7 +370,7 @@ PySwigPacked_GetType() {
(reprfunc)PySwigPacked_str, /*tp_str*/
/* Space for future expansion */
0,0,0,0,
PySwigPacked_Type__doc__, /* Documentation string */
pyswigpacked_type__doc__, /* Documentation string */
#if PY_VERSION_HEX >= 0x02000000
0, /* tp_traverse */
0, /* tp_clear */
@ -382,20 +389,18 @@ PySwigPacked_GetType() {
0,0,0,0 /* tp_alloc -> tp_next */
#endif
};
PySwigPacked_Type = tmp;
#if !defined(__cplusplus)
pyswigpacked_type = tmp;
type_init = 1;
}
return &PySwigPacked_Type;
#endif
return &pyswigpacked_type;
}
SWIGRUNTIME PyObject *
PySwigPacked_FromDataAndDesc(void *ptr, size_t size, const char *desc)
{
PySwigPacked *self = PyObject_NEW(PySwigPacked, PySwigPacked_GetType());
PySwigPacked *self = PyObject_NEW(PySwigPacked, PySwigPacked_type());
if (self == NULL) {
return NULL;
} else {
@ -428,7 +433,7 @@ PySwigPacked_GetDesc(PyObject *self)
SWIGRUNTIMEINLINE int
PySwigPacked_Check(PyObject *op) {
return ((op)->ob_type == PySwigPacked_GetType())
return ((op)->ob_type == PySwigPacked_type())
|| (strcmp((op)->ob_type->tp_name,"PySwigPacked") == 0);
}
@ -593,7 +598,6 @@ SWIG_Python_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags)
#endif
type_check:
if (ty) {
tc = SWIG_TypeCheck(c,ty);
if (!tc) goto type_error;
@ -601,7 +605,6 @@ type_check:
} else {
*ptr = vptr;
}
if ((pyobj) && (flags & SWIG_POINTER_DISOWN)) {
PyObject_SetAttrString(pyobj,(char*)"thisown",Py_False);
}

View file

@ -288,13 +288,13 @@
%typemap(directorout) SWIGTYPE ($&ltype argp)
"if (!$input || (SWIG_ConvertPtr($input, (void **)(&argp),
$&descriptor, SWIG_POINTER_EXCEPTION | $disown)) == -1)
throw Swig::DirectorTypeMismatchException(\"Pointer conversion failed.\");
Swig::DirectorTypeMismatchException::raise(\"Pointer conversion failed.\");
$result = *argp;";
%typemap(directorout) SWIGTYPE *, SWIGTYPE &, SWIGTYPE []
"if (!$input || (SWIG_ConvertPtr($input,(void **)(&$result),
$descriptor,SWIG_POINTER_EXCEPTION | $disown )) == -1)
throw Swig::DirectorTypeMismatchException(\"Pointer conversion failed.\");";
Swig::DirectorTypeMismatchException::raise(\"Pointer conversion failed.\");";
/* ------------------------------------------------------------

View file

@ -71,12 +71,12 @@
%typemap(directorargout,fragment=pyfrag) Type *DIRECTOROUT {
if ($input) *$result = SWIG_static_cast(SWIG_arg(as_meth($input)),$type);
if (!$input || PyErr_Occurred())
throw Swig::DirectorTypeMismatchException("Error converting Python object using as_meth");
Swig::DirectorTypeMismatchException::raise("Error converting Python object when using as_meth.");
}
%typemap(directorout,fragment=pyfrag) Type {
if ($input) $result = SWIG_static_cast(SWIG_arg(as_meth($input)),$type);
if (!$input || PyErr_Occurred())
throw Swig::DirectorTypeMismatchException("Error converting Python object using as_meth");
Swig::DirectorTypeMismatchException::raise("Error converting Python object when using as_meth.");
}
%typemap(directorout,fragment=pyfrag,warning="470:Using thread/reentrant unsafe wrapping, consider using a plain '"#Type"' return type instead.") const Type& {
if ($input) {
@ -84,7 +84,7 @@
$result = &temp;
}
if (!$input || PyErr_Occurred())
throw Swig::DirectorTypeMismatchException("Error converting Python object using as_meth");
Swig::DirectorTypeMismatchException::raise("Error converting Python object when using as_meth.");
}
%typemap(directorout,fragment=pyfrag) Type &DIRECTOROUT = Type
%enddef

View file

@ -42,7 +42,7 @@
%typemap(directorout) void * {
if (!$input || (SWIG_ConvertPtr($input,(void **)(&$result),
0, SWIG_POINTER_EXCEPTION | $disown )) == -1)
throw Swig::DirectorTypeMismatchException("Pointer conversion failed.");
Swig::DirectorTypeMismatchException::raise("Pointer conversion failed.");
}