Author: Armin Rigo <[email protected]>
Branch:
Changeset: r427:9de1d659cad3
Date: 2012-06-17 23:17 +0200
http://bitbucket.org/cffi/cffi/changeset/9de1d659cad3/
Log: Missing case: verify() with a function with varargs.
diff --git a/cffi/verifier.py b/cffi/verifier.py
--- a/cffi/verifier.py
+++ b/cffi/verifier.py
@@ -172,7 +172,7 @@
def convert_expr_from_c(self, tp, var):
if isinstance(tp, model.PrimitiveType):
return '_cffi_from_c_%s(%s)' % (tp.name.replace(' ', '_'), var)
- elif isinstance(tp, model.PointerType):
+ elif isinstance(tp, (model.PointerType, model.FunctionType)):
return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % (
var, self.gettypenum(tp))
elif isinstance(tp, model.ArrayType):
@@ -194,6 +194,12 @@
def generate_cpy_function_decl(self, tp, name):
assert isinstance(tp, model.FunctionType)
+ if tp.ellipsis:
+ # cannot support vararg functions better than this: check for its
+ # exact type (including the fixed arguments), and build it as a
+ # constant function pointer (no CPython wrapper)
+ self._generate_cpy_const(False, name, tp)
+ return
prnt = self.prnt
numargs = len(tp.args)
if numargs == 0:
@@ -205,7 +211,6 @@
prnt('static PyObject *')
prnt('_cffi_f_%s(PyObject *self, PyObject *%s)' % (name, argname))
prnt('{')
- assert not tp.ellipsis # XXX later
#
for i, type in enumerate(tp.args):
prnt(' %s;' % type.get_c_name(' x%d' % i))
@@ -247,6 +252,8 @@
prnt()
def generate_cpy_function_method(self, tp, name):
+ if tp.ellipsis:
+ return
numargs = len(tp.args)
if numargs == 0:
meth = 'METH_NOARGS'
@@ -259,6 +266,8 @@
loading_cpy_function = loaded_noop
def loaded_cpy_function(self, tp, name, module, library):
+ if tp.ellipsis:
+ return
setattr(library, name, getattr(module, name))
# ----------
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -484,3 +484,29 @@
ffi.cdef("typedef ... token_t;")
lib = ffi.verify("typedef struct token_s token_t;")
# assert did not crash, even though 'sizeof(token_t)' is not valid in C.
+
+def test_varargs():
+ ffi = FFI()
+ ffi.cdef("int foo(int x, ...);")
+ lib = ffi.verify("""
+ int foo(int x, ...) {
+ va_list vargs;
+ va_start(vargs, x);
+ x -= va_arg(vargs, int);
+ x -= va_arg(vargs, int);
+ va_end(vargs);
+ return x;
+ }
+ """)
+ assert lib.foo(50, ffi.cast("int", 5), ffi.cast("int", 3)) == 42
+
+def test_varargs_exact():
+ if sys.platform == 'win32':
+ py.test.skip("XXX fixme: only gives warnings")
+ ffi = FFI()
+ ffi.cdef("int foo(int x, ...);")
+ py.test.raises(VerificationError, ffi.verify, """
+ int foo(long long x, ...) {
+ return x;
+ }
+ """)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit