[pypy-commit] cffi linux-only: Finish the (non-partial) struct verification. For now uses
arigo
noreply at buildbot.pypy.org
Tue Jun 12 11:33:50 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: linux-only
Changeset: r283:a88af068780b
Date: 2012-06-12 11:01 +0200
http://bitbucket.org/cffi/cffi/changeset/a88af068780b/
Log: Finish the (non-partial) struct verification. For now uses
'typeof()', which is a gcc extension.
diff --git a/cffi/api.py b/cffi/api.py
--- a/cffi/api.py
+++ b/cffi/api.py
@@ -84,7 +84,7 @@
corresponding Python type: <class 'ffi.CData<...>'>.
It can also be used on 'cdata' instance to get its C type.
"""
- if isinstance(cdecl, (str, unicode)):
+ if isinstance(cdecl, basestring):
try:
return self._parsed_types[cdecl]
except KeyError:
@@ -99,7 +99,7 @@
"""Return the size in bytes of the argument. It can be a
string naming a C type, or a 'cdata' instance.
"""
- if isinstance(cdecl, (str, unicode)):
+ if isinstance(cdecl, basestring):
BType = self.typeof(cdecl)
return self._backend.sizeof(BType)
else:
@@ -109,15 +109,17 @@
"""Return the natural alignment size in bytes of the C type
given as a string.
"""
- BType = self.typeof(cdecl)
- return self._backend.alignof(BType)
+ if isinstance(cdecl, basestring):
+ cdecl = self.typeof(cdecl)
+ return self._backend.alignof(cdecl)
def offsetof(self, cdecl, fieldname):
"""Return the offset of the named field inside the given
structure, which must be given as a C type name.
"""
- BType = self.typeof(cdecl)
- return self._backend.offsetof(BType, fieldname)
+ if isinstance(cdecl, basestring):
+ cdecl = self.typeof(cdecl)
+ return self._backend.offsetof(cdecl, fieldname)
def new(self, cdecl, init=None):
"""Allocate an instance 'x' of the named C type, and return a
diff --git a/cffi/model.py b/cffi/model.py
--- a/cffi/model.py
+++ b/cffi/model.py
@@ -27,7 +27,7 @@
return self.new_backend_type(ffi, *args)
def verifier_declare_typedef(self, verifier, name):
- verifier.write('{ %s = (%s**)0; }' % (
+ verifier.write('__sametype__(%s, %s)' % (
self.get_c_name('** result'), name))
@@ -170,19 +170,37 @@
return ffi._backend.new_struct_type(self.name)
def verifier_declare_struct(self, verifier, name):
+ assert name == self.name
if self.partial:
- self.verifier_decl_partial(verifier, name)
+ self.verifier_decl_partial(verifier)
else:
- self.verifier_decl_notpartial(verifier, name)
+ self.verifier_decl_notpartial(verifier)
- def verifier_decl_notpartial(self, verifier, name):
+ def verifier_decl_notpartial(self, verifier):
if self.fldnames is None: # not partial, but fully opaque:
return # cannot really test even for existence
struct = verifier.ffi._get_cached_btype(self)
- verifier.write('__sameconstant__(sizeof(struct %s), %d)' % (
- name, verifier.ffi.sizeof(struct)))
+ verifier.write('{')
+ verifier.write('struct __aligncheck__ { char x; struct %s y; };' %
+ self.name)
+ verifier.write(
+ '__sameconstant__(sizeof(struct %s), %d)' % (
+ self.name, verifier.ffi.sizeof(struct)))
+ verifier.write(
+ '__sameconstant__(offsetof(struct __aligncheck__, y), %d)' % (
+ verifier.ffi.alignof(struct),))
+ for fname, ftype, fbitsize in zip(self.fldnames, self.fldtypes,
+ self.fldbitsize):
+ if fbitsize >= 0:
+ assert 0, "XXX: bitfield"
+ verifier.write('__sameconstant__(offsetof(struct %s, %s), %d)' % (
+ self.name, fname, verifier.ffi.offsetof(struct, fname)))
+ # XXX gcc only!
+ verifier.write('__sametype__(%s, typeof(((struct %s *)0)->%s))' % (
+ ftype.get_c_name('** result'), self.name, fname))
+ verifier.write('}')
- def verifier_decl_partial(self, verifier, name):
+ def verifier_decl_partial(self, verifier):
assert self.fldnames is not None
verifier.write('{')
verifier.write('struct __aligncheck__ { char x; struct %s y; };' %
diff --git a/cffi/verifier.py b/cffi/verifier.py
--- a/cffi/verifier.py
+++ b/cffi/verifier.py
@@ -21,15 +21,19 @@
tst_file_base = ffiplatform._get_test_file_base()
self.has_printf = False
with open(tst_file_base + '.c', 'w') as f:
- f.write('#include <stdio.h>\n'
- '#include <stdint.h>\n'
- '#include <stddef.h>\n'
- '#include <unistd.h>\n'
- '\n'
- '#define __sameconstant__(x, y) \\\n'
- ' { int result[1-2*((x)-(y))*((x)-(y))]; }\n'
- '\n'
- )
+ f.write("""\
+#include <stdio.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <unistd.h>
+
+#define __sameconstant__(x, y) \\
+ { int result[1-2*((x)-(y))*((x)-(y))]; }
+
+#define __sametype__(ppresult, typename) \\
+ { ppresult = (typename**)0; }
+
+""")
f.write(preamble + "\n\n")
f.write('int main() {\n')
self.f = f
More information about the pypy-commit
mailing list