Author: Armin Rigo <[email protected]>
Branch:
Changeset: r577:b09373197403
Date: 2012-07-04 06:01 +0200
http://bitbucket.org/cffi/cffi/changeset/b09373197403/
Log: Test and fix: you keep learning about the C syntax.
diff --git a/cffi/cparser.py b/cffi/cparser.py
--- a/cffi/cparser.py
+++ b/cffi/cparser.py
@@ -145,7 +145,7 @@
def _get_type_pointer(self, type, const=False):
if isinstance(type, model.RawFunctionType):
- return model.FunctionPtrType(type.args, type.result, type.ellipsis)
+ return type.as_function_pointer()
if const:
return model.ConstPointerType(type)
return model.PointerType(type)
diff --git a/cffi/model.py b/cffi/model.py
--- a/cffi/model.py
+++ b/cffi/model.py
@@ -102,6 +102,9 @@
raise api.CDefError("cannot render the type %r: it is a function "
"type, not a pointer-to-function type" % (self,))
+ def as_function_pointer(self):
+ return FunctionPtrType(self.args, self.result, self.ellipsis)
+
class FunctionPtrType(BaseFunctionType):
@@ -111,6 +114,8 @@
def prepare_backend_type(self, ffi):
args = [ffi._get_cached_btype(self.result)]
for tp in self.args:
+ if isinstance(tp, RawFunctionType):
+ tp = tp.as_function_pointer()
args.append(ffi._get_cached_btype(tp))
return args
diff --git a/testing/backend_tests.py b/testing/backend_tests.py
--- a/testing/backend_tests.py
+++ b/testing/backend_tests.py
@@ -1018,3 +1018,16 @@
f = ffi.callback("int(*)(int)", cb)
a = ffi.new("int(*[5])(int)", [f, f])
assert a[1](42) == 43
+
+ def test_callback_as_function_argument(self):
+ # In C, function arguments can be declared with a function type,
+ # which is automatically replaced with the ptr-to-function type.
+ ffi = FFI(backend=self.Backend())
+ def cb(a, b):
+ return chr(ord(a) + ord(b))
+ f = ffi.callback("char cb(char, char)", cb)
+ assert f('A', chr(1)) == 'B'
+ def g(callback):
+ return callback('A', chr(1))
+ g = ffi.callback("char g(char cb(char, char))", g)
+ assert g(f) == 'B'
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit