[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