[pypy-commit] cffi add-float-dotdotdot: Add support for `typedef float... foo_t`.

maxbelanger noreply at buildbot.pypy.org
Fri Aug 28 10:46:57 CEST 2015


Author: Max Belanger <aeromax at gmail.com>
Branch: add-float-dotdotdot
Changeset: r2259:ec78097f627d
Date: 2015-08-27 17:47 -0700
http://bitbucket.org/cffi/cffi/changeset/ec78097f627d/

Log:	Add support for `typedef float... foo_t`.

diff --git a/cffi/_cffi_include.h b/cffi/_cffi_include.h
--- a/cffi/_cffi_include.h
+++ b/cffi/_cffi_include.h
@@ -214,6 +214,11 @@
      (size) == 8 ? ((sign) ? _CFFI_PRIM_INT64 : _CFFI_PRIM_UINT64) :    \
      _CFFI__UNKNOWN_PRIM)
 
+#define _cffi_prim_float(size)                                          \
+    ((size) == 4 ? _CFFI_PRIM_FLOAT :                                   \
+     (size) == 8 ? _CFFI_PRIM_DOUBLE :                                  \
+     _CFFI__UNKNOWN_PRIM)
+
 #define _cffi_check_int(got, got_nonpos, expected)      \
     ((got_nonpos) == (expected <= 0) &&                 \
      (got) == (unsigned long long)expected)
diff --git a/cffi/cparser.py b/cffi/cparser.py
--- a/cffi/cparser.py
+++ b/cffi/cparser.py
@@ -648,10 +648,18 @@
         assert typenames[-1] == '__dotdotdot__'
         if len(typenames) == 1:
             return model.unknown_type(decl.name)
+
+        result = None
         for t in typenames[:-1]:
-            if t not in ['int', 'short', 'long', 'signed', 'unsigned', 'char']:
+            if t in ('int', 'short', 'long', 'signed', 'unsigned', 'char'):
+                result = model.UnknownIntegerType(decl.name)
+            elif t in ('float', 'double'):
+                result = model.UnknownFloatType(decl.name)
+            else:
                 raise api.FFIError(':%d: bad usage of "..."' % decl.coord.line)
+
         if self._uses_new_feature is None:
             self._uses_new_feature = "'typedef %s... %s'" % (
                 ' '.join(typenames[:-1]), decl.name)
-        return model.UnknownIntegerType(decl.name)
+
+        return result
diff --git a/cffi/model.py b/cffi/model.py
--- a/cffi/model.py
+++ b/cffi/model.py
@@ -35,6 +35,9 @@
     def is_integer_type(self):
         return False
 
+    def is_float_type(self):
+        return False
+
     def get_cached_btype(self, ffi, finishlist, can_delay=False):
         try:
             BType = ffi._cached_btypes[self]
@@ -164,6 +167,20 @@
         raise NotImplementedError("integer type '%s' can only be used after "
                                   "compilation" % self.name)
 
+class UnknownFloatType(BasePrimitiveType):
+    _attrs_ = ('name', )
+
+    def __init__(self, name):
+        self.name = name
+        self.c_name_with_marker = name + '&'
+
+    def is_float_type(self):
+        return True  # for now
+
+    def build_backend_type(self, ffi, finishlist):
+        raise NotImplementedError("float type '%s' can only be used after "
+                                  "compilation" % self.name)
+
 
 class BaseFunctionType(BaseType):
     _attrs_ = ('args', 'result', 'ellipsis')
diff --git a/cffi/recompiler.py b/cffi/recompiler.py
--- a/cffi/recompiler.py
+++ b/cffi/recompiler.py
@@ -468,6 +468,8 @@
             if tp.is_integer_type() and tp.name != '_Bool':
                 converter = '_cffi_to_c_int'
                 extraarg = ', %s' % tp.name
+            elif tp.is_float_type():
+                converter = '_cffi_to_c_float'
             else:
                 converter = '(%s)_cffi_to_c_%s' % (tp.get_c_name(''),
                                                    tp.name.replace(' ', '_'))
@@ -522,6 +524,8 @@
         if isinstance(tp, model.BasePrimitiveType):
             if tp.is_integer_type():
                 return '_cffi_from_c_int(%s, %s)' % (var, tp.name)
+            elif tp.is_float_type():
+                return '_cffi_from_c_double(%s)' % (var, )
             elif tp.name != 'long double':
                 return '_cffi_from_c_%s(%s)' % (tp.name.replace(' ', '_'), var)
             else:
@@ -1107,6 +1111,10 @@
              '         ) <= 0)' % (tp.name, tp.name, tp.name))
         self.cffi_types[index] = CffiOp(OP_PRIMITIVE, s)
 
+    def _emit_bytecode_UnknownFloatType(self, tp, index):
+        s = '_cffi_prim_float(sizeof(%s))' % (tp.name, )
+        self.cffi_types[index] = CffiOp(OP_PRIMITIVE, s)
+
     def _emit_bytecode_RawFunctionType(self, tp, index):
         self.cffi_types[index] = CffiOp(OP_FUNCTION, self._typesdict[tp.result])
         index += 1
diff --git a/testing/cffi1/test_recompiler.py b/testing/cffi1/test_recompiler.py
--- a/testing/cffi1/test_recompiler.py
+++ b/testing/cffi1/test_recompiler.py
@@ -1056,7 +1056,6 @@
     assert lib.nu == 20
 
 def test_some_float_type():
-    py.test.skip("later")
     ffi = FFI()
     ffi.cdef("typedef double... foo_t; foo_t sum(foo_t[]);")
     lib = verify(ffi, 'test_some_float_type', """


More information about the pypy-commit mailing list