[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