def cython_py2c_conv_function_pointer(t, ts): t = t[1] argnames = [] argcts = [] argdecls = [] argbodys = [] argrtns = [] for n, argt in t[1][2]: argnames.append(n) decl, body, rtn, _ = ts.cython_c2py(n, argt, proxy_name="c_" + n, cached=False) argdecls.append(decl) #argdecls.append("cdef {0} {1}".format(cython_pytype(argt), "c_" + n)) argbodys.append(body) argrtns.append(rtn) argct = ts.cython_ctype(argt) argcts.append(argct) rtnname = 'rtn' rtnprox = 'c_' + rtnname rtncall = 'call_' + rtnname while rtnname in argnames or rtnprox in argnames: rtnname += '_' rtnprox += '_' rtnct = ts.cython_ctype(t[2][2]) argdecls = indent(argdecls) argbodys = indent(argbodys) #rtndecl, rtnbody, rtnrtn = cython_py2c(rtnname, t[2][2], proxy_name=rtnprox) #rtndecl, rtnbody, rtnrtn = cython_py2c(rtnname, t[2][2], proxy_name=rtncall) rtndecl, rtnbody, rtnrtn = ts.cython_py2c(rtncall, t[2][2], proxy_name=rtnprox) if rtndecl is None and rtnbody is None: rtnprox = rtnname rtndecl = indent([rtndecl]) rtnbody = indent([rtnbody]) returns_void = (t[2][2] == 'void') if returns_void: rtnrtn = '' s = ('cdef {rtnct} {{proxy_name}}({arglist}):\n' '{argdecls}\n' '{rtndecl}\n' ' global {{var}}\n' '{argbodys}\n') s += ' {{var}}({pyarglist})\n' if returns_void else \ ' {rtncall} = {{var}}({pyarglist})\n' s += ('{rtnbody}\n' ' return {rtnrtn}\n') arglist = ", ".join(["{0} {1}".format(*x) for x in zip(argcts, argnames)]) pyarglist=", ".join(argrtns) s = s.format(rtnct=rtnct, arglist=arglist, argdecls=argdecls, rtndecl=rtndecl, argbodys=argbodys, rtnprox=rtnprox, pyarglist=pyarglist, rtnbody=rtnbody, rtnrtn=rtnrtn, rtncall=rtncall) return s, False
def cython_c2py_conv_function_pointer(t_, ts): """Wrap function pointers in C/C++ to Python functions.""" t = t_[1] argnames = [] argdecls = [] argbodys = [] argrtns = [] for n, argt in t[1][2]: argnames.append(n) decl, body, rtn = ts.cython_py2c(n, argt, proxy_name="c_" + n) argdecls += decl.split('\n') if isinstance(decl,basestring) else [decl] argbodys += body.split('\n') if isinstance(body,basestring) else [body] argrtns += rtn.split('\n') if isinstance(rtn,basestring) else [rtn] rtnname = 'rtn' rtnprox = 'c_' + rtnname rtncall = 'c_call_' + rtnname while rtnname in argnames or rtnprox in argnames: rtnname += '_' rtnprox += '_' argdecls = indent(argdecls) argbodys = indent(argbodys) rtndecl, rtnbody, rtnrtn, _ = ts.cython_c2py(rtncall, t[2][2], cached=False, proxy_name=rtnprox, existing_name=rtncall) if rtndecl is None and rtnbody is None: rtnprox = rtnname rtndecls = [rtndecl] returns_void = (t[2][2] == 'void') if not returns_void: rtndecls.append("cdef {0} {1}".format(ts.cython_ctype(t[2][2]), rtncall)) rtndecl = indent(rtndecls) rtnbody = indent(rtnbody) s = ('def {{proxy_name}}({arglist}):\n' '{argdecls}\n' '{rtndecl}\n' ' if {{var}} == NULL:\n' ' raise RuntimeError("{{var}} is NULL and may not be ' 'safely called!")\n' '{argbodys}\n') s += ' {{var}}({carglist})\n' if returns_void else \ ' {rtncall} = {{var}}({carglist})\n' s += '{rtnbody}\n' s = s.format(arglist=", ".join(argnames), argdecls=argdecls, cvartypeptr=ts.cython_ctype(t_).format(type_name='cvartype'), argbodys=argbodys, rtndecl=rtndecl, rtnprox=rtnprox, rtncall=rtncall, carglist=", ".join(argrtns), rtnbody=rtnbody) caches = 'if {cache_name} is None:\n' + indent(s) if not returns_void: caches += "\n return {rtnrtn}".format(rtnrtn=rtnrtn) caches += '\n {cache_name} = {proxy_name}\n' return s, s, caches