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

Reply via email to