add robust -nortti implementation
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@7000 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
58db22803e
commit
1a129db676
2 changed files with 69 additions and 17 deletions
|
|
@ -24,29 +24,59 @@
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Use -DSWIG_DIRECTOR_NORTTI if you prefer to avoid the use of RTTI
|
Use -DSWIG_DIRECTOR_NORTTI if you prefer to avoid the use of the
|
||||||
and dynamic_cast<>. But be aware that directors could stop working
|
native C++ RTTI and dynamic_cast<>. But be aware that directors
|
||||||
when using this option.
|
could stop working when using this option.
|
||||||
*/
|
*/
|
||||||
|
#ifdef SWIG_DIRECTOR_NORTTI
|
||||||
|
/*
|
||||||
|
When we don't use the native C++ RTTI, we implement a minimal one
|
||||||
|
only for Directors.
|
||||||
|
*/
|
||||||
|
# ifndef SWIG_DIRECTOR_RTDIR
|
||||||
|
# define SWIG_DIRECTOR_RTDIR
|
||||||
|
#include <map>
|
||||||
|
namespace Swig {
|
||||||
|
class Director;
|
||||||
|
static std::map<void*,Director*>& get_rtdir_map() {
|
||||||
|
static std::map<void*,Director*> rtdir_map;
|
||||||
|
return rtdir_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void set_rtdir(void *vptr, Director *rtdir) {
|
||||||
|
get_rtdir_map()[vptr] = rtdir;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Director *get_rtdir(void *vptr) {
|
||||||
|
std::map<void*,Director*>::const_iterator pos = get_rtdir_map().find(vptr);
|
||||||
|
Director *rtdir = (pos != get_rtdir_map().end()) ? pos->second : 0;
|
||||||
|
return rtdir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif /* SWIG_DIRECTOR_RTDIR */
|
||||||
|
|
||||||
|
# define SWIG_DIRECTOR_CAST(Arg) Swig::get_rtdir(static_cast<void*>(Arg))
|
||||||
|
# define SWIG_DIRECTOR_RGTR(Arg1, Arg2) Swig::set_rtdir(static_cast<void*>(Arg1), Arg2)
|
||||||
|
|
||||||
#if defined(SWIG_DIRECTOR_NORTTI)
|
|
||||||
# define SWIG_DIRECTOR_CAST(arg) (Swig::Director*)(arg)
|
|
||||||
#else
|
#else
|
||||||
# define SWIG_DIRECTOR_CAST(arg) dynamic_cast<Swig::Director*>(arg)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
# define SWIG_DIRECTOR_CAST(Arg) dynamic_cast<Swig::Director*>(Arg)
|
||||||
|
# define SWIG_DIRECTOR_RGTR(Arg1, Arg2)
|
||||||
|
|
||||||
|
#endif /* SWIG_DIRECTOR_NORTTI */
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
struct swig_type_info;
|
struct swig_type_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Swig {
|
namespace Swig {
|
||||||
|
|
||||||
/* base class for director exceptions */
|
/* base class for director exceptions */
|
||||||
class DirectorException {
|
class DirectorException {
|
||||||
protected:
|
protected:
|
||||||
std::string swig_msg;
|
std::string swig_msg;
|
||||||
public:
|
public:
|
||||||
DirectorException(const char* /* msg */ ="") {
|
DirectorException(const char* msg ="") : swig_msg(msg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *getMessage() const {
|
const char *getMessage() const {
|
||||||
|
|
@ -69,7 +99,13 @@ namespace Swig {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* any python exception that occurs during a director method call */
|
/* any python exception that occurs during a director method call */
|
||||||
class DirectorMethodException : public Swig::DirectorException {};
|
class DirectorMethodException : public Swig::DirectorException {
|
||||||
|
public:
|
||||||
|
DirectorMethodException(const char* msg = "")
|
||||||
|
: DirectorException(msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/* attempt to call a pure virtual method via a director method */
|
/* attempt to call a pure virtual method via a director method */
|
||||||
class DirectorPureVirtualException : public Swig::DirectorException {};
|
class DirectorPureVirtualException : public Swig::DirectorException {};
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ Python Options (available with -python)\n\
|
||||||
-keyword - Use keyword arguments\n\
|
-keyword - Use keyword arguments\n\
|
||||||
-classic - Use classic classes only\n\
|
-classic - Use classic classes only\n\
|
||||||
-cppcast - Enable new C++ casting operators, useful for debugging\n\
|
-cppcast - Enable new C++ casting operators, useful for debugging\n\
|
||||||
-nortti - Disable the use of RTTI, useful (sometimes) with directors\n\
|
-nortti - Disable the use of the native C++ RTTI with directors\n\
|
||||||
-modern - Use modern python features only, without compatibility code\n\
|
-modern - Use modern python features only, without compatibility code\n\
|
||||||
-apply - Use apply() in proxy classes\n\
|
-apply - Use apply() in proxy classes\n\
|
||||||
-new_vwm - New value wrapper mode, use only when everything else fails \n\
|
-new_vwm - New value wrapper mode, use only when everything else fails \n\
|
||||||
|
|
@ -1404,7 +1404,12 @@ public:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Emit the function call */
|
/* Emit the function call */
|
||||||
|
Printf(f->code, "try {\n");
|
||||||
emit_action(n,f);
|
emit_action(n,f);
|
||||||
|
Printf(f->code, "} catch (Swig::DirectorException& e) {\n");
|
||||||
|
Printf(f->code, " SWIG_Python_AddErrMesg(e.getMessage(), 1);\n");
|
||||||
|
Printf(f->code, " SWIG_fail;\n");
|
||||||
|
Printf(f->code, "}\n");
|
||||||
|
|
||||||
/* This part below still needs cleanup */
|
/* This part below still needs cleanup */
|
||||||
|
|
||||||
|
|
@ -1760,7 +1765,9 @@ public:
|
||||||
String *basetype = Getattr(parent, "classtype");
|
String *basetype = Getattr(parent, "classtype");
|
||||||
String *target = Swig_method_decl(decl, classname, parms, 0, 0);
|
String *target = Swig_method_decl(decl, classname, parms, 0, 0);
|
||||||
call = Swig_csuperclass_call(0, basetype, superparms);
|
call = Swig_csuperclass_call(0, basetype, superparms);
|
||||||
Printf(w->def, "%s::%s: %s, Swig::Director(self) { }", classname, target, call);
|
Printf(w->def, "%s::%s: %s, Swig::Director(self) { \n", classname, target, call);
|
||||||
|
Printf(w->def, " SWIG_DIRECTOR_RGTR((%s *)this, this); \n", basetype);
|
||||||
|
Printf(w->def, "}\n");
|
||||||
Delete(target);
|
Delete(target);
|
||||||
Wrapper_print(w, f_directors);
|
Wrapper_print(w, f_directors);
|
||||||
Delete(call);
|
Delete(call);
|
||||||
|
|
@ -1787,11 +1794,14 @@ public:
|
||||||
* ------------------------------------------------------------ */
|
* ------------------------------------------------------------ */
|
||||||
|
|
||||||
int classDirectorDefaultConstructor(Node *n) {
|
int classDirectorDefaultConstructor(Node *n) {
|
||||||
String *classname;
|
String *classname = Swig_class_name(n);
|
||||||
classname = Swig_class_name(n);
|
|
||||||
{
|
{
|
||||||
|
Node *parent = Swig_methodclass(n);
|
||||||
|
String *basetype = Getattr(parent, "classtype");
|
||||||
Wrapper *w = NewWrapper();
|
Wrapper *w = NewWrapper();
|
||||||
Printf(w->def, "SwigDirector_%s::SwigDirector_%s(PyObject* self) : Swig::Director(self) { }", classname, classname);
|
Printf(w->def, "SwigDirector_%s::SwigDirector_%s(PyObject* self) : Swig::Director(self) { \n", classname, classname);
|
||||||
|
Printf(w->def, " SWIG_DIRECTOR_RGTR((%s *)this, this); \n", basetype);
|
||||||
|
Printf(w->def, "}\n");
|
||||||
Wrapper_print(w, f_directors);
|
Wrapper_print(w, f_directors);
|
||||||
DelWrapper(w);
|
DelWrapper(w);
|
||||||
}
|
}
|
||||||
|
|
@ -2775,13 +2785,19 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
|
||||||
if (!tm) {
|
if (!tm) {
|
||||||
tm = Getattr(n, "feature:director:except");
|
tm = Getattr(n, "feature:director:except");
|
||||||
}
|
}
|
||||||
|
Printf(w->code, "if (result == NULL) {\n");
|
||||||
|
Printf(w->code, " PyObject *error = PyErr_Occurred();\n");
|
||||||
if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
|
if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
|
||||||
Printf(w->code, "if (result == NULL) {\n");
|
|
||||||
Printf(w->code, " PyObject *error = PyErr_Occurred();\n");
|
|
||||||
Replaceall(tm, "$error", "error");
|
Replaceall(tm, "$error", "error");
|
||||||
Printv(w->code, Str(tm), "\n", NIL);
|
Printv(w->code, Str(tm), "\n", NIL);
|
||||||
Printf(w->code, "}\n");
|
} else {
|
||||||
|
Printf(w->code, " if (error != NULL) {\n");
|
||||||
|
Printf(w->code, " throw Swig::DirectorMethodException(\"Swig director error detected when calling %s.%s.\\n\");\n",
|
||||||
|
classname, pyname);
|
||||||
|
Printf(w->code, " }\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Printf(w->code, "}\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Python method may return a simple object, or a tuple.
|
* Python method may return a simple object, or a tuple.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue