More changes. Mostly to the would-be class library
This commit is contained in:
parent
577f20c990
commit
63a26c6dbe
3 changed files with 641 additions and 4 deletions
|
|
@ -879,13 +879,13 @@ SWIGINTERN int SWIG_Lua_class_tostring(lua_State* L)
|
|||
unsigned long userData = (unsigned long)lua_touserdata(L,1); /* get the userdata address for later */
|
||||
lua_getmetatable(L,1); /* get the meta table */
|
||||
assert(lua_istable(L,-1)); /* just in case */
|
||||
|
||||
|
||||
lua_getfield(L, -1, ".type");
|
||||
const char* className = lua_tostring(L, -1);
|
||||
|
||||
|
||||
char output[256];
|
||||
sprintf(output, "<%s userdata: %lX>", className, userData);
|
||||
|
||||
snprintf(output, 255, "<%s userdata: %lX>", className, userData);
|
||||
|
||||
lua_pushstring(L, (const char*)output);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -1123,8 +1123,37 @@ SWIGINTERN void SWIG_Lua_class_register_instance(lua_State* L,swig_lua_class* c
|
|||
|
||||
SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss)
|
||||
{
|
||||
assert(lua_istable(L,-1)); /* This is table(module or namespace) where class will be added */
|
||||
SWIG_Lua_class_register_instance(L,clss);
|
||||
SWIG_Lua_class_register_static(L,clss);
|
||||
|
||||
/* Add links from static part to instance part and vice versa */
|
||||
/* [SWIG registry] [Module]
|
||||
* "MyClass" ----> [MyClass metatable] <===== "MyClass" -+> [static part]
|
||||
* ".get" ----> ... | | getmetatable()----|
|
||||
* ".set" ----> ... | | |
|
||||
* ".static" --------------)----------------/ [static part metatable]
|
||||
* | ".get" --> ...
|
||||
* | ".set" --> ....
|
||||
* |=============================== ".instance"
|
||||
*/
|
||||
int begin = lua_gettop(L);
|
||||
lua_pushstring(L,clss->cls_static.name);
|
||||
lua_rawget(L,-2); /* get class static table */
|
||||
assert(lua_istable(L,-1));
|
||||
lua_getmetatable(L,-1);
|
||||
assert(lua_istable(L,-1)); /* get class static metatable */
|
||||
lua_pushstring(L,".instance"); /* prepare key */
|
||||
|
||||
SWIG_Lua_get_class_metatable(L,clss->fqname); /* get class metatable */
|
||||
assert(lua_istable(L,-1));
|
||||
lua_pushstring(L,".static"); /* prepare key */
|
||||
lua_pushvalue(L, -4); /* push static class TABLE */
|
||||
assert(lua_istable(L,-1));
|
||||
lua_rawset(L,-3); /* assign static class table(!NOT metatable) as ".static" member of class metatable */
|
||||
lua_rawset(L,-3); /* assign class metatable as ".instance" member of class static METATABLE */
|
||||
lua_pop(L,2);
|
||||
assert(lua_gettop(L) == begin);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
@ -1351,4 +1380,147 @@ SWIG_Lua_dostring(lua_State *L, const char* str) {
|
|||
}
|
||||
#endif
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* runtime class manipulation
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#if ((SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUA) && (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC))
|
||||
/* Set of functions that allow manipulating class bindings from C/C++ and from lua
|
||||
*/
|
||||
|
||||
SWIGINTERN bool
|
||||
SWIG_Lua_metaclass_add_table(lua_State *L, int metatable_index, const char *class_name, const char *metatable_name,
|
||||
const char *metaclass_name)
|
||||
{
|
||||
/* Table to add new field must be on to of the stack */
|
||||
assert(lua_istable(L,-1));
|
||||
lua_pushstring(L,metaclass_name);
|
||||
lua_pushvalue(L,metatable_index);
|
||||
lua_pushstring(L,metatable_name);
|
||||
lua_rawget(L,-2);
|
||||
if(!lua_istable(L,-1)) {
|
||||
SWIG_Lua_pushferrstring(L,"Class %s metatable is corrupt. Table %s is missing or not a table", class_name, metatable_name);
|
||||
return false;
|
||||
}
|
||||
lua_rawset(L,-2);
|
||||
return true;
|
||||
}
|
||||
|
||||
SWIGRUNTIME int
|
||||
SWIG_Lua_get_class_metaclass(lua_State *L)
|
||||
{
|
||||
/* One argument:
|
||||
* - SWIG name of class as string
|
||||
* - or instance of class
|
||||
* - or class entry point in module
|
||||
* metaclass( "MyClass<int,double>" )
|
||||
* metaclass( myvar_of_type_MyClass_int_double )
|
||||
* metaclass( module.MyClass_int_double )
|
||||
*/
|
||||
const char *class_name = 0;
|
||||
int metatable_index = 0;
|
||||
int static_metatable_index = 0;
|
||||
int static_table_index = 0;
|
||||
int answer_index = 0;
|
||||
SWIG_check_num_args("SWIG_Lua_metaclass", 1, 1);
|
||||
lua_checkstack(L,15);
|
||||
if(lua_type(L,1) == LUA_TSTRING) { // class name is given
|
||||
class_name = lua_tostring(L,1);
|
||||
SWIG_Lua_get_class_registry(L); /* get the registry */
|
||||
assert(lua_istable(L,-1));
|
||||
lua_pushvalue(L,1);
|
||||
lua_rawget(L,-2); /* get class metatable */
|
||||
if(!lua_istable(L,-1)) {
|
||||
SWIG_Lua_pushferrstring(L,"There is no registered class with name %s", class_name );
|
||||
SWIG_fail
|
||||
}
|
||||
metatable_index = lua_gettop(L);
|
||||
} else if(lua_isuserdata(L,1)) { // class instance is given
|
||||
/* We don't check that class is registered in SWIG because it can be user-created-in-lua class */
|
||||
lua_getmetatable(L,1);
|
||||
if(!lua_istable(L,-1)) {
|
||||
SWIG_Lua_pushferrstring(L,"Userdata is passed, but it is not SWIG-wrapped class. There is no metatable.");
|
||||
SWIG_fail;
|
||||
}
|
||||
metatable_index = lua_gettop(L);
|
||||
lua_getfield(L,-1,".type");
|
||||
if(lua_type(L,-1) != LUA_TSTRING) {
|
||||
SWIG_Lua_pushferrstring(L,"Userdata is passed, but it is not SWIG-wrapped class. Metatable has different structure.");
|
||||
SWIG_fail;
|
||||
}
|
||||
class_name = lua_tostring(L,-1);
|
||||
} else { // class entry is given. Well, it is supposed to be a class entry :)
|
||||
lua_getmetatable(L,1); /* get metatable */
|
||||
if(!lua_istable(L,-1)) {
|
||||
SWIG_Lua_pushferrstring(L, "Table is passed but it is not SWIG class entry point. There is no metatable");
|
||||
SWIG_fail;
|
||||
}
|
||||
lua_getfield(L,-1, ".instance"); /* get class metatable */
|
||||
if(lua_isnil(L,-1)) {
|
||||
SWIG_Lua_pushferrstring(L, "Table is passed but it is not SWIG class entry point. Metatable has different structure.");
|
||||
SWIG_fail;
|
||||
}
|
||||
metatable_index = lua_gettop(L);
|
||||
lua_getfield(L,-1,".type");
|
||||
if(lua_type(L,-1) != LUA_TSTRING) {
|
||||
SWIG_Lua_pushferrstring(L,"Userdata is passed, but it is not SWIG-wrapped class. Metatable has different structure.");
|
||||
SWIG_fail;
|
||||
}
|
||||
class_name = lua_tostring(L,-1);
|
||||
}
|
||||
|
||||
/* Get static table */
|
||||
lua_getfield(L,metatable_index,".static");
|
||||
assert(!lua_isnil(L,-1));
|
||||
static_table_index = lua_gettop(L);
|
||||
/* Get static metatable */
|
||||
lua_getmetatable(L,-1);
|
||||
assert(!lua_isnil(L,-1));
|
||||
static_metatable_index = lua_gettop(L);
|
||||
/* This will be our answer */
|
||||
lua_newtable(L);
|
||||
answer_index = lua_gettop(L);
|
||||
/* Adding instance member manipulators
|
||||
* .bases can't be edited
|
||||
*/
|
||||
if(!SWIG_Lua_metaclass_add_table(L,metatable_index,class_name, ".fn", "methods") )
|
||||
SWIG_fail;
|
||||
if(!SWIG_Lua_metaclass_add_table(L,metatable_index,class_name, ".get", "getters") )
|
||||
SWIG_fail;
|
||||
if(!SWIG_Lua_metaclass_add_table(L,metatable_index,class_name, ".set", "setters") )
|
||||
SWIG_fail;
|
||||
/* Adding static members manipulators */
|
||||
if(!SWIG_Lua_metaclass_add_table(L,static_metatable_index,class_name, ".get", "static_getters") )
|
||||
SWIG_fail;
|
||||
if(!SWIG_Lua_metaclass_add_table(L,static_metatable_index,class_name, ".set", "static_setters") )
|
||||
SWIG_fail;
|
||||
lua_pushstring(L, "static_methods");
|
||||
lua_pushvalue(L, static_table_index);
|
||||
lua_rawset(L,-3);
|
||||
|
||||
lua_pushstring(L, "static_constants");
|
||||
lua_pushvalue(L, static_table_index);
|
||||
lua_rawset(L,-3);
|
||||
|
||||
assert(lua_gettop(L) == answer_index);
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Creates new class in lua. Must inherit existing SWIG class */
|
||||
SWIGRUNTIME int
|
||||
SWIG_Lua_new_class(lua_State *L) {
|
||||
SWIG_check_num_args("SWIG_Lua_new_class", 1, 1);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
lua_error(L);
|
||||
return 0;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ------------------------------ end luarun.swg ------------------------------ */
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ SWIGEXPORT int SWIG_init(lua_State* L) /* default Lua action */
|
|||
/* add a global fn */
|
||||
SWIG_Lua_add_function(L,"swig_type",SWIG_Lua_type);
|
||||
SWIG_Lua_add_function(L,"swig_equals",SWIG_Lua_equal);
|
||||
SWIG_Lua_add_function(L,"swig_new_class",SWIG_Lua_new_class);
|
||||
SWIG_Lua_add_function(L,"swig_metaclass",SWIG_Lua_get_class_metaclass);
|
||||
#endif
|
||||
|
||||
#if (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC)
|
||||
|
|
|
|||
|
|
@ -393,6 +393,8 @@ public:
|
|||
/* Get the module name */
|
||||
module = Getattr(n, "name");
|
||||
|
||||
/* Some global settings */
|
||||
director_language = 1;
|
||||
/* Get the output file name */
|
||||
String *outfile = Getattr(n, "outfile");
|
||||
|
||||
|
|
@ -1767,6 +1769,467 @@ public:
|
|||
return SWIG_OK;
|
||||
}
|
||||
|
||||
#if 0
|
||||
virtual int classDirectorMethod(Node *n, Node *parent, String *super) {
|
||||
int is_void = 0;
|
||||
int is_pointer = 0;
|
||||
String *decl = Getattr(n, "decl");
|
||||
String *name = Getattr(n, "name");
|
||||
String *classname = Getattr(parent, "sym:name");
|
||||
String *c_classname = Getattr(parent, "name");
|
||||
String *symname = Getattr(n, "sym:name");
|
||||
String *declaration = NewString("");
|
||||
ParmList *l = Getattr(n, "parms");
|
||||
Wrapper *w = NewWrapper();
|
||||
String *tm;
|
||||
String *wrap_args = NewString("");
|
||||
String *returntype = Getattr(n, "type");
|
||||
String *value = Getattr(n, "value");
|
||||
String *storage = Getattr(n, "storage");
|
||||
bool pure_virtual = false;
|
||||
int status = SWIG_OK;
|
||||
int idx;
|
||||
bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
|
||||
|
||||
if (Cmp(storage, "virtual") == 0) {
|
||||
if (Cmp(value, "0") == 0) {
|
||||
pure_virtual = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* determine if the method returns a pointer */
|
||||
is_pointer = SwigType_ispointer_return(decl);
|
||||
is_void = (!Cmp(returntype, "void") && !is_pointer);
|
||||
|
||||
/* virtual method definition */
|
||||
String *target;
|
||||
String *pclassname = NewStringf("SwigDirector_%s", classname);
|
||||
String *qualified_name = NewStringf("%s::%s", pclassname, name);
|
||||
SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type");
|
||||
target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
|
||||
Printf(w->def, "%s", target);
|
||||
Delete(qualified_name);
|
||||
Delete(target);
|
||||
/* header declaration */
|
||||
target = Swig_method_decl(rtype, decl, name, l, 0, 1);
|
||||
Printf(declaration, " virtual %s", target);
|
||||
Delete(target);
|
||||
|
||||
// Get any exception classes in the throws typemap
|
||||
ParmList *throw_parm_list = 0;
|
||||
|
||||
if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
|
||||
Parm *p;
|
||||
int gencomma = 0;
|
||||
|
||||
Append(w->def, " throw(");
|
||||
Append(declaration, " throw(");
|
||||
|
||||
if (throw_parm_list)
|
||||
Swig_typemap_attach_parms("throws", throw_parm_list, 0);
|
||||
for (p = throw_parm_list; p; p = nextSibling(p)) {
|
||||
if (Getattr(p, "tmap:throws")) {
|
||||
if (gencomma++) {
|
||||
Append(w->def, ", ");
|
||||
Append(declaration, ", ");
|
||||
}
|
||||
String *str = SwigType_str(Getattr(p, "type"), 0);
|
||||
Append(w->def, str);
|
||||
Append(declaration, str);
|
||||
Delete(str);
|
||||
}
|
||||
}
|
||||
|
||||
Append(w->def, ")");
|
||||
Append(declaration, ")");
|
||||
}
|
||||
|
||||
Append(w->def, " {");
|
||||
Append(declaration, ";\n");
|
||||
|
||||
/* declare method return value
|
||||
* if the return value is a reference or const reference, a specialized typemap must
|
||||
* handle it, including declaration of c_result ($result).
|
||||
*/
|
||||
if (!is_void) {
|
||||
if (!(ignored_method && !pure_virtual)) {
|
||||
String *cres = SwigType_lstr(returntype, "c_result");
|
||||
Printf(w->code, "%s;\n", cres);
|
||||
Delete(cres);
|
||||
}
|
||||
}
|
||||
|
||||
if (builtin) {
|
||||
Printv(w->code, "PyObject *self = NULL;\n", NIL);
|
||||
Printv(w->code, "(void)self;\n", NIL);
|
||||
}
|
||||
|
||||
if (ignored_method) {
|
||||
if (!pure_virtual) {
|
||||
if (!is_void)
|
||||
Printf(w->code, "return ");
|
||||
String *super_call = Swig_method_call(super, l);
|
||||
Printf(w->code, "%s;\n", super_call);
|
||||
Delete(super_call);
|
||||
} else {
|
||||
Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
|
||||
SwigType_namestr(name));
|
||||
}
|
||||
} else {
|
||||
/* attach typemaps to arguments (C/C++ -> Python) */
|
||||
String *arglist = NewString("");
|
||||
String *parse_args = NewString("");
|
||||
|
||||
Swig_director_parms_fixup(l);
|
||||
|
||||
/* remove the wrapper 'w' since it was producing spurious temps */
|
||||
Swig_typemap_attach_parms("in", l, 0);
|
||||
Swig_typemap_attach_parms("directorin", l, 0);
|
||||
Swig_typemap_attach_parms("directorargout", l, w);
|
||||
|
||||
Parm *p;
|
||||
char source[256];
|
||||
|
||||
int outputs = 0;
|
||||
if (!is_void)
|
||||
outputs++;
|
||||
|
||||
/* build argument list and type conversion string */
|
||||
idx = 0;
|
||||
p = l;
|
||||
int use_parse = 0;
|
||||
while (p) {
|
||||
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
|
||||
p = Getattr(p, "tmap:in:next");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* old style? caused segfaults without the p!=0 check
|
||||
in the for() condition, and seems dangerous in the
|
||||
while loop as well.
|
||||
while (Getattr(p, "tmap:ignore")) {
|
||||
p = Getattr(p, "tmap:ignore:next");
|
||||
}
|
||||
*/
|
||||
|
||||
if (Getattr(p, "tmap:directorargout") != 0)
|
||||
outputs++;
|
||||
|
||||
String *pname = Getattr(p, "name");
|
||||
String *ptype = Getattr(p, "type");
|
||||
|
||||
Putc(',', arglist);
|
||||
if ((tm = Getattr(p, "tmap:directorin")) != 0) {
|
||||
String *parse = Getattr(p, "tmap:directorin:parse");
|
||||
if (!parse) {
|
||||
sprintf(source, "obj%d", idx++);
|
||||
String *input = NewString(source);
|
||||
Setattr(p, "emit:directorinput", input);
|
||||
Replaceall(tm, "$input", input);
|
||||
Delete(input);
|
||||
Replaceall(tm, "$owner", "0");
|
||||
/* Wrapper_add_localv(w, source, "swig::SwigVar_PyObject", source, "= 0", NIL); */
|
||||
Printv(wrap_args, "swig::SwigVar_PyObject ", source, ";\n", NIL);
|
||||
|
||||
Printv(wrap_args, tm, "\n", NIL);
|
||||
Printv(arglist, "(PyObject *)", source, NIL);
|
||||
Putc('O', parse_args);
|
||||
} else {
|
||||
use_parse = 1;
|
||||
Append(parse_args, parse);
|
||||
Setattr(p, "emit:directorinput", pname);
|
||||
Replaceall(tm, "$input", pname);
|
||||
Replaceall(tm, "$owner", "0");
|
||||
if (Len(tm) == 0)
|
||||
Append(tm, pname);
|
||||
Append(arglist, tm);
|
||||
}
|
||||
p = Getattr(p, "tmap:directorin:next");
|
||||
continue;
|
||||
} else if (Cmp(ptype, "void")) {
|
||||
/* special handling for pointers to other C++ director classes.
|
||||
* ideally this would be left to a typemap, but there is currently no
|
||||
* way to selectively apply the dynamic_cast<> to classes that have
|
||||
* directors. in other words, the type "SwigDirector_$1_lname" only exists
|
||||
* for classes with directors. we avoid the problem here by checking
|
||||
* module.wrap::directormap, but it's not clear how to get a typemap to
|
||||
* do something similar. perhaps a new default typemap (in addition
|
||||
* to SWIGTYPE) called DIRECTORTYPE?
|
||||
*/
|
||||
if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) {
|
||||
Node *module = Getattr(parent, "module");
|
||||
Node *target = Swig_directormap(module, ptype);
|
||||
sprintf(source, "obj%d", idx++);
|
||||
String *nonconst = 0;
|
||||
/* strip pointer/reference --- should move to Swig/stype.c */
|
||||
String *nptype = NewString(Char(ptype) + 2);
|
||||
/* name as pointer */
|
||||
String *ppname = Copy(pname);
|
||||
if (SwigType_isreference(ptype)) {
|
||||
Insert(ppname, 0, "&");
|
||||
}
|
||||
/* if necessary, cast away const since Python doesn't support it! */
|
||||
if (SwigType_isconst(nptype)) {
|
||||
nonconst = NewStringf("nc_tmp_%s", pname);
|
||||
String *nonconst_i = NewStringf("= const_cast< %s >(%s)", SwigType_lstr(ptype, 0), ppname);
|
||||
Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL);
|
||||
Delete(nonconst_i);
|
||||
Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
|
||||
"Target language argument '%s' discards const in director method %s::%s.\n",
|
||||
SwigType_str(ptype, pname), SwigType_namestr(c_classname), SwigType_namestr(name));
|
||||
} else {
|
||||
nonconst = Copy(ppname);
|
||||
}
|
||||
Delete(nptype);
|
||||
Delete(ppname);
|
||||
String *mangle = SwigType_manglestr(ptype);
|
||||
if (target) {
|
||||
String *director = NewStringf("director_%s", mangle);
|
||||
Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
|
||||
Wrapper_add_localv(w, source, "swig::SwigVar_PyObject", source, "= 0", NIL);
|
||||
Printf(wrap_args, "%s = SWIG_DIRECTOR_CAST(%s);\n", director, nonconst);
|
||||
Printf(wrap_args, "if (!%s) {\n", director);
|
||||
Printf(wrap_args, "%s = SWIG_InternalNewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
|
||||
Append(wrap_args, "} else {\n");
|
||||
Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director);
|
||||
Printf(wrap_args, "Py_INCREF((PyObject *)%s);\n", source);
|
||||
Append(wrap_args, "}\n");
|
||||
Delete(director);
|
||||
Printv(arglist, source, NIL);
|
||||
} else {
|
||||
Wrapper_add_localv(w, source, "swig::SwigVar_PyObject", source, "= 0", NIL);
|
||||
Printf(wrap_args, "%s = SWIG_InternalNewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
|
||||
//Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n",
|
||||
// source, nonconst, base);
|
||||
Printv(arglist, source, NIL);
|
||||
}
|
||||
Putc('O', parse_args);
|
||||
Delete(mangle);
|
||||
Delete(nonconst);
|
||||
} else {
|
||||
Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
|
||||
"Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0),
|
||||
SwigType_namestr(c_classname), SwigType_namestr(name));
|
||||
status = SWIG_NOWRAP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
p = nextSibling(p);
|
||||
}
|
||||
|
||||
/* add the method name as a PyString */
|
||||
String *pyname = Getattr(n, "sym:name");
|
||||
|
||||
int allow_thread = threads_enable(n);
|
||||
|
||||
if (allow_thread) {
|
||||
thread_begin_block(n, w->code);
|
||||
Append(w->code, "{\n");
|
||||
}
|
||||
|
||||
/* wrap complex arguments to PyObjects */
|
||||
Printv(w->code, wrap_args, NIL);
|
||||
|
||||
/* pass the method call on to the Python object */
|
||||
if (dirprot_mode() && !is_public(n)) {
|
||||
Printf(w->code, "swig_set_inner(\"%s\", true);\n", name);
|
||||
}
|
||||
|
||||
|
||||
Append(w->code, "if (!swig_get_self()) {\n");
|
||||
Printf(w->code, " Swig::DirectorException::raise(\"'self' uninitialized, maybe you forgot to call %s.__init__.\");\n", classname);
|
||||
Append(w->code, "}\n");
|
||||
Append(w->code, "#if defined(SWIG_PYTHON_DIRECTOR_VTABLE)\n");
|
||||
Printf(w->code, "const size_t swig_method_index = %d;\n", director_method_index++);
|
||||
Printf(w->code, "const char * const swig_method_name = \"%s\";\n", pyname);
|
||||
|
||||
Append(w->code, "PyObject* method = swig_get_method(swig_method_index, swig_method_name);\n");
|
||||
if (Len(parse_args) > 0) {
|
||||
if (use_parse || !modernargs) {
|
||||
Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallFunction(method, (char *)\"(%s)\" %s);\n", Swig_cresult_name(), parse_args, arglist);
|
||||
} else {
|
||||
Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallFunctionObjArgs(method %s, NULL);\n", Swig_cresult_name(), arglist);
|
||||
}
|
||||
} else {
|
||||
if (modernargs) {
|
||||
Append(w->code, "swig::SwigVar_PyObject args = PyTuple_New(0);\n");
|
||||
Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_Call(method, (PyObject*) args, NULL);\n", Swig_cresult_name());
|
||||
} else {
|
||||
Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallFunction(method, NULL, NULL);\n", Swig_cresult_name());
|
||||
}
|
||||
}
|
||||
Append(w->code, "#else\n");
|
||||
if (Len(parse_args) > 0) {
|
||||
if (use_parse || !modernargs) {
|
||||
Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallMethod(swig_get_self(), (char *)\"%s\", (char *)\"(%s)\" %s);\n", Swig_cresult_name(), pyname, parse_args, arglist);
|
||||
} else {
|
||||
Printf(w->code, "swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar((char *)\"%s\");\n", pyname);
|
||||
Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name %s, NULL);\n", Swig_cresult_name(), arglist);
|
||||
}
|
||||
} else {
|
||||
if (!modernargs) {
|
||||
Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallMethod(swig_get_self(), (char *) \"%s\", NULL);\n", Swig_cresult_name(), pyname);
|
||||
} else {
|
||||
Printf(w->code, "swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar((char *)\"%s\");\n", pyname);
|
||||
Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name, NULL);\n", Swig_cresult_name());
|
||||
}
|
||||
}
|
||||
Append(w->code, "#endif\n");
|
||||
|
||||
if (dirprot_mode() && !is_public(n))
|
||||
Printf(w->code, "swig_set_inner(\"%s\", false);\n", name);
|
||||
|
||||
/* exception handling */
|
||||
tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0);
|
||||
if (!tm) {
|
||||
tm = Getattr(n, "feature:director:except");
|
||||
if (tm)
|
||||
tm = Copy(tm);
|
||||
}
|
||||
Printf(w->code, "if (!%s) {\n", Swig_cresult_name());
|
||||
Append(w->code, " PyObject *error = PyErr_Occurred();\n");
|
||||
if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
|
||||
Replaceall(tm, "$error", "error");
|
||||
Printv(w->code, Str(tm), "\n", NIL);
|
||||
} else {
|
||||
Append(w->code, " if (error) {\n");
|
||||
Printf(w->code, " Swig::DirectorMethodException::raise(\"Error detected when calling '%s.%s'\");\n", classname, pyname);
|
||||
Append(w->code, " }\n");
|
||||
}
|
||||
Append(w->code, "}\n");
|
||||
Delete(tm);
|
||||
|
||||
/*
|
||||
* Python method may return a simple object, or a tuple.
|
||||
* for in/out aruments, we have to extract the appropriate PyObjects from the tuple,
|
||||
* then marshal everything back to C/C++ (return value and output arguments).
|
||||
*
|
||||
*/
|
||||
|
||||
/* marshal return value and other outputs (if any) from PyObject to C/C++ type */
|
||||
|
||||
String *cleanup = NewString("");
|
||||
String *outarg = NewString("");
|
||||
|
||||
if (outputs > 1) {
|
||||
Wrapper_add_local(w, "output", "PyObject *output");
|
||||
Printf(w->code, "if (!PyTuple_Check(%s)) {\n", Swig_cresult_name());
|
||||
Printf(w->code, " Swig::DirectorTypeMismatchException::raise(\"Python method %s.%sfailed to return a tuple.\");\n", classname, pyname);
|
||||
Append(w->code, "}\n");
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
|
||||
/* marshal return value */
|
||||
if (!is_void) {
|
||||
tm = Swig_typemap_lookup("directorout", n, Swig_cresult_name(), w);
|
||||
if (tm != 0) {
|
||||
if (outputs > 1) {
|
||||
Printf(w->code, "output = PyTuple_GetItem(%s, %d);\n", Swig_cresult_name(), idx++);
|
||||
Replaceall(tm, "$input", "output");
|
||||
} else {
|
||||
Replaceall(tm, "$input", Swig_cresult_name());
|
||||
}
|
||||
char temp[24];
|
||||
sprintf(temp, "%d", idx);
|
||||
Replaceall(tm, "$argnum", temp);
|
||||
|
||||
/* TODO check this */
|
||||
if (Getattr(n, "wrap:disown")) {
|
||||
Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
|
||||
} else {
|
||||
Replaceall(tm, "$disown", "0");
|
||||
}
|
||||
if (Getattr(n, "tmap:directorout:implicitconv")) {
|
||||
Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
|
||||
}
|
||||
Replaceall(tm, "$result", "c_result");
|
||||
Printv(w->code, tm, "\n", NIL);
|
||||
Delete(tm);
|
||||
} else {
|
||||
Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
|
||||
"Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(returntype, 0), SwigType_namestr(c_classname),
|
||||
SwigType_namestr(name));
|
||||
status = SWIG_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* marshal outputs */
|
||||
for (p = l; p;) {
|
||||
if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
|
||||
if (outputs > 1) {
|
||||
Printf(w->code, "output = PyTuple_GetItem(%s, %d);\n", Swig_cresult_name(), idx++);
|
||||
Replaceall(tm, "$result", "output");
|
||||
} else {
|
||||
Replaceall(tm, "$result", Swig_cresult_name());
|
||||
}
|
||||
Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
|
||||
Printv(w->code, tm, "\n", NIL);
|
||||
p = Getattr(p, "tmap:directorargout:next");
|
||||
} else {
|
||||
p = nextSibling(p);
|
||||
}
|
||||
}
|
||||
|
||||
/* any existing helper functions to handle this? */
|
||||
if (allow_thread) {
|
||||
Append(w->code, "}\n");
|
||||
thread_end_block(n, w->code);
|
||||
}
|
||||
|
||||
Delete(parse_args);
|
||||
Delete(arglist);
|
||||
Delete(cleanup);
|
||||
Delete(outarg);
|
||||
}
|
||||
|
||||
if (!is_void) {
|
||||
if (!(ignored_method && !pure_virtual)) {
|
||||
String *rettype = SwigType_str(returntype, 0);
|
||||
if (!SwigType_isreference(returntype)) {
|
||||
Printf(w->code, "return (%s) c_result;\n", rettype);
|
||||
} else {
|
||||
Printf(w->code, "return (%s) *c_result;\n", rettype);
|
||||
}
|
||||
Delete(rettype);
|
||||
}
|
||||
}
|
||||
|
||||
Append(w->code, "}\n");
|
||||
|
||||
// We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
|
||||
String *inline_extra_method = NewString("");
|
||||
if (dirprot_mode() && !is_public(n) && !pure_virtual) {
|
||||
Printv(inline_extra_method, declaration, NIL);
|
||||
String *extra_method_name = NewStringf("%sSwigPublic", name);
|
||||
Replaceall(inline_extra_method, name, extra_method_name);
|
||||
Replaceall(inline_extra_method, ";\n", " {\n ");
|
||||
if (!is_void)
|
||||
Printf(inline_extra_method, "return ");
|
||||
String *methodcall = Swig_method_call(super, l);
|
||||
Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
|
||||
Delete(methodcall);
|
||||
Delete(extra_method_name);
|
||||
}
|
||||
|
||||
/* emit the director method */
|
||||
if (status == SWIG_OK) {
|
||||
if (!Getattr(n, "defaultargs")) {
|
||||
Replaceall(w->code, "$symname", symname);
|
||||
Wrapper_print(w, f_directors);
|
||||
Printv(f_directors_h, declaration, NIL);
|
||||
Printv(f_directors_h, inline_extra_method, NIL);
|
||||
}
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
Delete(wrap_args);
|
||||
Delete(pclassname);
|
||||
DelWrapper(w);
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* TODO: REMOVE
|
||||
virtual int namespaceDeclaration(Node *n) {
|
||||
// Register namespace
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue