[pypy-commit] cffi cpy-extension: Good, we can now declare array fields without specifying the length,
arigo
noreply at buildbot.pypy.org
Wed Jun 13 22:01:13 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: cpy-extension
Changeset: r314:61cbe88492c3
Date: 2012-06-13 22:01 +0200
http://bitbucket.org/cffi/cffi/changeset/61cbe88492c3/
Log: Good, we can now declare array fields without specifying the length,
and let verify() fill that in.
diff --git a/cffi/model.py b/cffi/model.py
--- a/cffi/model.py
+++ b/cffi/model.py
@@ -119,6 +119,9 @@
self.item = item
self.length = length
+ def resolve_length(self, newlength):
+ return ArrayType(self.item, newlength)
+
def get_c_name(self, replace_with=''):
if self.length is None:
brackets = '[]'
@@ -158,20 +161,44 @@
if self.fixedlayout is None:
lst = zip(self.fldnames, fldtypes, self.fldbitsize)
ffi._backend.complete_struct_or_union(BType, lst, self)
+ #
else:
fieldofs, fieldsize, totalsize, totalalignment = self.fixedlayout
- for fname, ftype, fsize in zip(self.fldnames, fldtypes, fieldsize):
- if ffi.sizeof(ftype) != fsize:
- from .ffiplatform import VerificationError
- raise VerificationError, (
+ for i in range(len(self.fldnames)):
+ fsize = fieldsize[i]
+ ftype = self.fldtypes[i]
+ #
+ if isinstance(ftype, ArrayType) and ftype.length is None:
+ # fix the length to match the total size
+ BItemType = ffi._get_cached_btype(ftype.item)
+ nlen, nrest = divmod(fsize, ffi.sizeof(BItemType))
+ if nrest != 0:
+ self._verification_error(
+ "field '%s.%s' has a bogus size?" % (
+ self.name, self.fldnames[i]))
+ ftype = ftype.resolve_length(nlen)
+ self.fldtypes = (self.fldtypes[:i] + (ftype,) +
+ self.fldtypes[i+1:])
+ BArrayType = ffi._get_cached_btype(ftype)
+ fldtypes = (fldtypes[:i] + (BArrayType,) +
+ fldtypes[i+1:])
+ continue
+ #
+ bitemsize = ffi.sizeof(fldtypes[i])
+ if bitemsize != fsize:
+ self._verification_error(
"field '%s.%s' is declared as %d bytes, but is "
- "really %d bytes" % (self.name, fname,
- ffi.sizeof(ftype), fsize))
+ "really %d bytes" % (self.name, self.fldnames[i],
+ bitemsize, fsize))
lst = zip(self.fldnames, fldtypes, self.fldbitsize, fieldofs)
ffi._backend.complete_struct_or_union(BType, lst, self,
totalsize, totalalignment)
return BType
+ def _verification_error(self, msg):
+ from .ffiplatform import VerificationError
+ raise VerificationError(msg)
+
class StructType(StructOrUnion):
kind = 'struct'
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -220,9 +220,8 @@
assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int')
def test_struct_array_guess_length():
- py.test.skip("in-progress")
ffi = FFI()
- ffi.cdef("struct foo_s { int a[]; ...; };")
+ ffi.cdef("struct foo_s { int a[]; ...; };") # <= no declared length
ffi.verify("struct foo_s { int x; int a[17]; int y; };")
assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int')
s = ffi.new("struct foo_s")
More information about the pypy-commit
mailing list