Author: Armin Rigo <[email protected]>
Branch: cpy-extension
Changeset: r307:4cbfba2e9feb
Date: 2012-06-13 17:55 +0200
http://bitbucket.org/cffi/cffi/changeset/4cbfba2e9feb/

Log:    Verify full (non-partial) structs too.

diff --git a/cffi/verifier.py b/cffi/verifier.py
--- a/cffi/verifier.py
+++ b/cffi/verifier.py
@@ -212,22 +212,47 @@
     # struct declarations
 
     def generate_cpy_struct_decl(self, tp, name):
-        assert tp.partial    # xxx
         assert name == tp.name
         prnt = self.prnt
         prnt('static PyObject *')
         prnt('_cffi_struct_%s(PyObject *self, PyObject *noarg)' % name)
         prnt('{')
         prnt('  struct _cffi_aligncheck { char x; struct %s y; };' % name)
-        prnt('  static Py_ssize_t nums[] = {')
-        prnt('    sizeof(struct %s),' % name)
-        prnt('    offsetof(struct _cffi_aligncheck, y),')
-        for i in range(len(tp.fldnames)):
-            prnt('    offsetof(struct %s, %s),' % (name, tp.fldnames[i]))
-            prnt('    sizeof(((struct %s *)0)->%s),' % (name, tp.fldnames[i]))
-        prnt('    -1')
-        prnt('  };')
-        prnt('  return _cffi_get_struct_layout(nums);')
+        if tp.partial:
+            prnt('  static Py_ssize_t nums[] = {')
+            prnt('    sizeof(struct %s),' % name)
+            prnt('    offsetof(struct _cffi_aligncheck, y),')
+            for fname in tp.fldnames:
+                prnt('    offsetof(struct %s, %s),' % (name, fname))
+                prnt('    sizeof(((struct %s *)0)->%s),' % (name, fname))
+            prnt('    -1')
+            prnt('  };')
+            prnt('  return _cffi_get_struct_layout(nums);')
+        else:
+            ffi = self.ffi
+            BStruct = ffi._get_cached_btype(tp)
+            conditions = [
+                'sizeof(struct %s) != %d' % (name, ffi.sizeof(BStruct)),
+                'offsetof(struct _cffi_aligncheck, y) != %d' % (
+                    ffi.alignof(BStruct),)]
+            for fname, ftype in zip(tp.fldnames, tp.fldtypes):
+                BField = ffi._get_cached_btype(ftype)
+                conditions += [
+                    'offsetof(struct %s, %s) != %d' % (
+                        name, fname, ffi.offsetof(BStruct, fname)),
+                    'sizeof(((struct %s *)0)->%s) != %d' % (
+                        name, fname, ffi.sizeof(BField))]
+            prnt('  if (%s ||' % conditions[0])
+            for i in range(1, len(conditions)-1):
+                prnt('      %s ||' % conditions[i])
+            prnt('      %s) {' % conditions[-1])
+            prnt('    Py_INCREF(Py_False);')
+            prnt('    return Py_False;')
+            prnt('  }')
+            prnt('  else {')
+            prnt('    Py_INCREF(Py_True);')
+            prnt('    return Py_True;')
+            prnt('  }')
         prnt('}')
         prnt()
         prnt('static void _cffi_check_%s(struct %s *p)' % (name, name))
@@ -256,12 +281,18 @@
         assert name == tp.name
         function = getattr(module, '_cffi_struct_%s' % name)
         layout = function()
-        totalsize = layout[0]
-        totalalignment = layout[1]
-        fieldofs = layout[2::2]
-        fieldsize = layout[3::2]
-        assert len(fieldofs) == len(fieldsize) == len(tp.fldnames)
-        tp.fixedlayout = fieldofs, fieldsize, totalsize, totalalignment
+        if layout is False:
+            raise ffiplatform.VerificationError(
+                "incompatible layout for struct %s" % name)
+        elif layout is True:
+            assert not tp.partial
+        else:
+            totalsize = layout[0]
+            totalalignment = layout[1]
+            fieldofs = layout[2::2]
+            fieldsize = layout[3::2]
+            assert len(fieldofs) == len(fieldsize) == len(tp.fldnames)
+            tp.fixedlayout = fieldofs, fieldsize, totalsize, totalalignment
 
     def loaded_cpy_struct(self, tp, name, module):
         self.ffi._get_cached_btype(tp)   # force 'fixedlayout' to be considered
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -129,7 +129,6 @@
 
 
 def test_ffi_full_struct():
-    py.test.skip("XXX")
     ffi = FFI()
     ffi.cdef("struct foo_s { char x; int y; long *z; };")
     ffi.verify("struct foo_s { char x; int y; long *z; };")
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to