From 3023f3aad7fc81e0099d3566cdce62f74a1d53ef Mon Sep 17 00:00:00 2001 From: Marcelo Matus Date: Fri, 1 Oct 2004 21:44:26 +0000 Subject: [PATCH] fix %callback and add %pythoncallback git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@6279 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- SWIG/Source/Modules/lang.cxx | 50 +++++++++++++++------ SWIG/Source/Modules/python.cxx | 82 ++++++++++++++++++++++------------ 2 files changed, 90 insertions(+), 42 deletions(-) diff --git a/SWIG/Source/Modules/lang.cxx b/SWIG/Source/Modules/lang.cxx index deede674e..ffdbb0fd0 100644 --- a/SWIG/Source/Modules/lang.cxx +++ b/SWIG/Source/Modules/lang.cxx @@ -954,7 +954,12 @@ Language::globalfunctionHandler(Node *n) { /* Check for callback mode */ String *cb = Getattr(n,"feature:callback"); if (cb) { - String *cbname = NewStringf(cb,symname); + String *cbname = Getattr(n,"feature:callback:name"); + if (!cbname) { + cbname = NewStringf(cb,symname); + Setattr(n,"feature:callback:name",cbname); + } + callbackfunctionHandler(n); if (Cmp(cbname, symname) == 0) { Delete(cbname); @@ -983,14 +988,20 @@ Language::callbackfunctionHandler(Node *n) { String *name = Getattr(n,"name"); String *parms = Getattr(n,"parms"); String *cb = Getattr(n,"feature:callback"); - String *cbname = NewStringf(cb,symname); + String *cbname = Getattr(n,"feature:callback:name"); + String *calltype= NewStringf("(%s (*)(%s))(%s)", SwigType_str(type,0), ParmList_str(parms), SwigType_namestr(name)); SwigType *cbty = Copy(type); SwigType_add_function(cbty,parms); SwigType_add_pointer(cbty); + if (!cbname) { + cbname = NewStringf(cb,symname); + Setattr(n,"feature:callback:name",cbname); + } + Setattr(n,"sym:name", cbname); Setattr(n,"type", cbty); - Setattr(n,"value", name); + Setattr(n,"value", calltype); constantWrapper(n); Delete(cbname); @@ -1015,7 +1026,7 @@ Language::memberfunctionHandler(Node *n) { SwigType *type = Getattr(n,"type"); String *value = Getattr(n,"value"); ParmList *parms = Getattr(n,"parms"); - String *cb; + String *cb = Getattr(n,"feature:callback"); if (Cmp(storage,"virtual") == 0) { if (Cmp(value,"0") == 0) { @@ -1026,23 +1037,27 @@ Language::memberfunctionHandler(Node *n) { } else { IsVirtual = 0; } - cb = Getattr(n,"feature:callback"); if (cb) { - Node *cb = NewHash(); - String *cbname = NewStringf(cb,symname); - String *cbvalue; + Node *cbn = NewHash(); + String *cbname = Getattr(n,"feature:callback:name"); + if (!cbname) { + cbname = NewStringf(cb,symname); + } + SwigType *cbty = Copy(type); SwigType_add_function(cbty,parms); SwigType_add_memberpointer(cbty,ClassName); - cbvalue = NewStringf("&%s::%s",ClassName,name); - Setattr(cb,"sym:name", cbname); - Setattr(cb,"type", cbty); - Setattr(cb,"value", cbvalue); - Setattr(cb,"name", name); + String *cbvalue = NewStringf("&%s::%s",ClassName,name); + Setattr(cbn,"sym:name", cbname); + Setattr(cbn,"type", cbty); + Setattr(cbn,"value", cbvalue); + Setattr(cbn,"name", name); - memberconstantHandler(n); + memberconstantHandler(cbn); + Setattr(n,"feature:callback:name",Swig_name_member(ClassPrefix, cbname)); Delete(cb); + Delete(cbn); Delete(cbvalue); Delete(cbty); Delete(cbname); @@ -1078,6 +1093,7 @@ Language::staticmemberfunctionHandler(Node *n) { SwigType *type = Getattr(n,"type"); ParmList *parms = Getattr(n,"parms"); String *code = Getattr(n,"code"); + String *cb = Getattr(n,"feature:callback"); String *cname, *mrename; if (!Extend) { @@ -1104,7 +1120,13 @@ Language::staticmemberfunctionHandler(Node *n) { Delete(tmp); Delete(wrap); } + if (cb) { + String *cbname = NewStringf(cb,symname); + Setattr(n,"feature:callback:name", Swig_name_member(ClassPrefix, cbname)); + Setattr(n,"feature:callback:staticname", name); + } Delattr(n,"storage"); + globalfunctionHandler(n); Delete(cname); diff --git a/SWIG/Source/Modules/python.cxx b/SWIG/Source/Modules/python.cxx index 32e84b3be..29464eccd 100644 --- a/SWIG/Source/Modules/python.cxx +++ b/SWIG/Source/Modules/python.cxx @@ -426,6 +426,15 @@ public: } + int functionHandler(Node *n) { + if (checkAttribute(n,"feature:python:callback","1")) { + Setattr(n,"feature:callback","%s_cb_ptr"); + } + + return Language::functionHandler(n); + } + + /* ------------------------------------------------------------ * emitFunctionShadowHelper() * Refactoring some common code out of functionWrapper and @@ -434,7 +443,7 @@ public: * ------------------------------------------------------------ */ void emitFunctionShadowHelper(Node *n, File *f_dest, String *name, int kw) { - if ( ! have_addtofunc(n) ) { + if (checkAttribute(n,"feature:python:callback","1") || ! have_addtofunc(n) ) { /* If there is no addtofunc directive then just assign from the extension module */ Printv(f_dest, "\n", name, " = ", module, ".", name, "\n", NIL); } else { @@ -486,11 +495,20 @@ public: * add_method() * ------------------------------------------------------------ */ - void add_method(String *name, String *function, int kw) { - if (!kw) - Printf(methods,"\t { (char *)\"%s\", %s, METH_VARARGS, NULL },\n", name, function); + void add_method(String *name, String *function, int kw, Node *n = 0) { + if (!kw) + Printf(methods,"\t { (char *)\"%s\", %s, METH_VARARGS, ", name, function); else - Printf(methods,"\t { (char *)\"%s\", (PyCFunction) %s, METH_VARARGS | METH_KEYWORDS, NULL },\n", name, function); + Printf(methods,"\t { (char *)\"%s\", (PyCFunction) %s, METH_VARARGS | METH_KEYWORDS, ", name, function); + + if (n && Getattr(n,"feature:callback")) { + Printf(methods,"\"swig_ptr: %s\"", Getattr(n,"feature:callback:name")); + } else { + Printf(methods,"NULL"); + } + + + Printf(methods,"},\n"); } /* ------------------------------------------------------------ @@ -901,7 +919,7 @@ public: /* Now register the function with the interpreter. */ if (!Getattr(n,"sym:overloaded")) { - add_method(iname, wname, allow_kwargs); + add_method(iname, wname, allow_kwargs, n); /* Create a shadow for this function (if enabled and not in a member function) */ if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { @@ -954,8 +972,13 @@ public: Replaceall(dispatch,"$args","self,args"); Printv(f->code,dispatch,"\n",NIL); - Printf(f->code,"PyErr_SetString(PyExc_TypeError,\"No matching function for overloaded '%s'\");\n", symname); - Printf(f->code,"return NULL;\n"); + if (checkAttribute(n,"feature:python:maybecall","1")) { + Printf(f->code,"Py_INCREF(Py_NotImplemented);\n"); + Printf(f->code,"return Py_NotImplemented;\n"); + } else { + Printf(f->code,"PyErr_SetString(PyExc_NotImplementedError,\"No matching function for overloaded '%s'\");\n", symname); + Printf(f->code,"return NULL;\n"); + } Printv(f->code,"}\n",NIL); Wrapper_print(f,f_wrappers); add_method(symname,wname,0); @@ -999,10 +1022,10 @@ public: Printf(f_shadow_stubs,"%s = %s.%s\n", global_name, module, global_name); } } - if ((shadow) && (!SwigType_ismutable(t))) { - if (!in_class) { - Printf(f_shadow_stubs,"%s = %s.%s\n", iname, global_name, iname); - } + if ((shadow) && (checkAttribute(n,"feature:immutable","1"))) { + if (!in_class) { + Printf(f_shadow_stubs,"%s = %s.%s\n", iname, global_name, iname); + } } wname = Swig_name_wrapper(iname); @@ -1107,7 +1130,9 @@ public: if (!in_class) { Printv(f_shadow,iname, " = ", module, ".", iname, "\n", NIL); } else { - Printv(f_shadow_stubs,iname, " = ", module, ".", iname, "\n", NIL); + if (!(Getattr(n,"feature:python:callback"))) { + Printv(f_shadow_stubs,iname, " = ", module, ".", iname, "\n", NIL); + } } } return SWIG_OK; @@ -1477,6 +1502,10 @@ public: } else { Replaceall(tm, "$input", "result"); } + 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"); @@ -1939,18 +1968,15 @@ public: Delete(pyaction); Printv(f_shadow,pycode,"\n",NIL); } else { - - Printv(f_shadow, tab4, "def ", symname, "(*args", (allow_kwargs ? ", **kwargs" : ""), "): ", NIL); - if ( have_addtofunc(n) ) { - Printv(f_shadow, "\n", NIL); - Printv(f_shadow, tab8, "val = ", funcCallHelper(Swig_name_member(class_name,symname), allow_kwargs), "\n", NIL); - Printv(f_shadow, tab8, addtofunc(n), "\n", NIL); - Printv(f_shadow, tab8, "return val\n", NIL); - } else { - Printv(f_shadow, "return ", funcCallHelper(Swig_name_member(class_name,symname), allow_kwargs), "\n", NIL); - } + Printv(f_shadow, tab4, "def ", symname, "(*args", (allow_kwargs ? ", **kwargs" : ""), "): ", NIL); + if (have_addtofunc(n)) { + Printv(f_shadow, "\n", NIL); + Printv(f_shadow, tab8, "val = ", funcCallHelper(Swig_name_member(class_name,symname), allow_kwargs), "\n", NIL); + Printv(f_shadow, tab8, addtofunc(n), "\n", NIL); + } else { + Printv(f_shadow, "return ", funcCallHelper(Swig_name_member(class_name,symname), allow_kwargs), "\n", NIL); + } } - } } return SWIG_OK; @@ -1982,10 +2008,10 @@ public: Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = lambda x: ", module, ".", Swig_name_member(class_name, symname), "\n", NIL); } if (!classic) { - Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, - " = staticmethod(", module, ".", - Swig_name_member(class_name, symname), ")\n", NIL); - } + Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, + " = staticmethod(", module, ".", + Swig_name_member(class_name, symname), ")\n", NIL); + } } } return SWIG_OK;