[pypy-commit] cffi default: in-progress
arigo
noreply at buildbot.pypy.org
Thu Aug 23 18:17:56 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r885:8e0c963ef064
Date: 2012-08-23 17:47 +0200
http://bitbucket.org/cffi/cffi/changeset/8e0c963ef064/
Log: in-progress
diff --git a/cffi/model.py b/cffi/model.py
--- a/cffi/model.py
+++ b/cffi/model.py
@@ -176,6 +176,16 @@
self.fldtypes = fldtypes
self.fldbitsize = fldbitsize
+ def enumfields(self):
+ for name, type, bitsize in zip(self.fldnames, self.fldtypes,
+ self.fldbitsize):
+ if name == '' and isinstance(type, StructOrUnion):
+ # nested anonymous struct/union
+ for result in type.enumfields():
+ yield result
+ else:
+ yield (name, type, bitsize)
+
def finish_backend_type(self, ffi):
BType = self.new_btype(ffi)
ffi._cached_btypes[self] = BType
@@ -201,7 +211,7 @@
if nrest != 0:
self._verification_error(
"field '%s.%s' has a bogus size?" % (
- self.name, self.fldnames[i]))
+ self.name, self.fldnames[i] or '{}'))
ftype = ftype.resolve_length(nlen)
self.fldtypes = (self.fldtypes[:i] + (ftype,) +
self.fldtypes[i+1:])
@@ -214,7 +224,8 @@
if bitemsize != fsize:
self._verification_error(
"field '%s.%s' is declared as %d bytes, but is "
- "really %d bytes" % (self.name, self.fldnames[i],
+ "really %d bytes" % (self.name,
+ self.fldnames[i] or '{}',
bitemsize, fsize))
lst = list(zip(self.fldnames, fldtypes, self.fldbitsize, fieldofs))
ffi._backend.complete_struct_or_union(BType, lst, self,
diff --git a/cffi/vengine_cpy.py b/cffi/vengine_cpy.py
--- a/cffi/vengine_cpy.py
+++ b/cffi/vengine_cpy.py
@@ -363,9 +363,7 @@
prnt('static void %s(%s *p)' % (checkfuncname, cname))
prnt('{')
prnt(' /* only to generate compile-time warnings or errors */')
- for i in range(len(tp.fldnames)):
- fname = tp.fldnames[i]
- ftype = tp.fldtypes[i]
+ for fname, ftype, _ in tp.enumfields():
if (isinstance(ftype, model.PrimitiveType)
and ftype.is_integer_type()):
# accept all integers, but complain on float or double
@@ -388,7 +386,7 @@
prnt(' static Py_ssize_t nums[] = {')
prnt(' sizeof(%s),' % cname)
prnt(' offsetof(struct _cffi_aligncheck, y),')
- for fname in tp.fldnames:
+ for fname, _, _ in tp.enumfields():
prnt(' offsetof(%s, %s),' % (cname, fname))
prnt(' sizeof(((%s *)0)->%s),' % (cname, fname))
prnt(' -1')
@@ -401,7 +399,7 @@
'sizeof(%s) != %d' % (cname, ffi.sizeof(BStruct)),
'offsetof(struct _cffi_aligncheck, y) != %d' % (
ffi.alignof(BStruct),)]
- for fname, ftype in zip(tp.fldnames, tp.fldtypes):
+ for fname, ftype, _ in tp.enumfields():
BField = ffi._get_cached_btype(ftype)
conditions += [
'offsetof(%s, %s) != %d' % (
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -895,3 +895,51 @@
ffi.cdef("struct foo_s { struct { int x; } someone; };")
ffi.verify("struct foo_s { struct { int x; } someone; };")
# assert did not crash
+
+def test_nested_anonymous_struct_exact():
+ ffi = FFI()
+ ffi.cdef("""
+ struct foo_s { struct { int a; char b; }; union { char c, d; }; };
+ """)
+ ffi.verify("""
+ struct foo_s { struct { int a; char b; }; union { char c, d; }; };
+ """)
+ p = ffi.new("struct foo_s *")
+ assert ffi.sizeof(p) == 3 * ffi.sizeof("int") # with alignment
+ p.a = 1234567
+ p.b = 'X'
+ p.c = 'Y'
+ assert p.a == 1234567
+ assert p.b == 'X'
+ assert p.c == 'Y'
+ assert p.d == 'Y'
+
+def test_nested_anonymous_struct_exact():
+ ffi = FFI()
+ ffi.cdef("""
+ struct foo_s { struct { int a; char b; }; union { char c, d; }; };
+ """)
+ ffi.verify("""
+ struct foo_s { struct { int a; char b; }; union { char c, d; }; };
+ """)
+ p = ffi.new("struct foo_s *")
+ assert ffi.sizeof(p[0]) == 3 * ffi.sizeof("int") # with alignment
+ p.a = 1234567
+ p.b = 'X'
+ p.c = 'Y'
+ assert p.a == 1234567
+ assert p.b == 'X'
+ assert p.c == 'Y'
+ assert p.d == 'Y'
+
+def test_nested_anonymous_struct_exact_error():
+ ffi = FFI()
+ ffi.cdef("""
+ struct foo_s { struct { int a; char b; }; union { char c, d; }; };
+ """)
+ py.test.raises(VerificationError, ffi.verify, """
+ struct foo_s { struct { int a; short b; }; union { char c, d; }; };
+ """)
+ py.test.raises(VerificationError, ffi.verify, """
+ struct foo_s { struct { int a; char e, b; }; union { char c, d; }; };
+ """)
More information about the pypy-commit
mailing list