[pypy-commit] cffi linux-only: Progress on test_ffi_nonfull_struct(), but unfinished so far.
arigo
noreply at buildbot.pypy.org
Fri Jun 8 15:50:09 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: linux-only
Changeset: r280:1420a9fb32b8
Date: 2012-06-08 15:49 +0200
http://bitbucket.org/cffi/cffi/changeset/1420a9fb32b8/
Log: Progress on test_ffi_nonfull_struct(), but unfinished so far.
diff --git a/cffi/cparser.py b/cffi/cparser.py
--- a/cffi/cparser.py
+++ b/cffi/cparser.py
@@ -83,6 +83,7 @@
def _declare(self, name, obj):
if name in self._declarations:
raise api.FFIError("multiple declarations of %s" % (name,))
+ assert name != '__dotdotdot__'
self._declarations[name] = obj
def _get_type_pointer(self, type, const=False):
@@ -144,6 +145,8 @@
ident = ' '.join(names)
if ident == 'void':
return model.void_type
+ if ident == '__dotdotdot__':
+ raise api.FFIError('bad usage of "..."')
return model.PrimitiveType(ident)
#
if isinstance(type, pycparser.c_ast.Struct):
@@ -250,10 +253,11 @@
for decl in type.decls:
if (isinstance(decl.type, pycparser.c_ast.IdentifierType) and
''.join(decl.type.names) == '__dotdotdot__'):
- xxxx
# XXX pycparser is inconsistent: 'names' should be a list
# of strings, but is sometimes just one string. Use
# str.join() as a way to cope with both.
+ tp.partial = True
+ continue
if decl.bitsize is None:
bitsize = -1
else:
diff --git a/cffi/model.py b/cffi/model.py
--- a/cffi/model.py
+++ b/cffi/model.py
@@ -26,7 +26,7 @@
except KeyError:
return self.new_backend_type(ffi, *args)
- def verifier_declare(self, verifier, kind, name, f):
+ def verifier_declare(self, verifier, kind, name):
# nothing to see here
pass
@@ -78,9 +78,10 @@
def new_backend_type(self, ffi, result, *args):
return ffi._backend.new_function_type(args, result, self.ellipsis)
- def verifier_declare(self, verifier, kind, name, f):
+ def verifier_declare(self, verifier, kind, name):
if kind == 'function':
- f.write(' { %s = %s; }\n' % (self.get_c_name('result'), name))
+ verifier.write(' { %s = %s; }\n' % (
+ self.get_c_name('result'), name))
class PointerType(BaseType):
@@ -157,17 +158,42 @@
class StructType(StructOrUnion):
kind = 'struct'
+ partial = False
+
+ def check_not_partial(self):
+ if self.partial:
+ from . import ffiplatform
+ raise ffiplatform.VerificationMissing(self.get_c_name())
def get_btype(self, ffi):
+ self.check_not_partial()
return ffi._backend.new_struct_type(self.name)
- def verifier_declare(self, verifier, name, f):
- verifier._write_printf(f, 'BEGIN struct %s size(%%ld)' % self.name,
- 'sizeof(struct %s)' % self.name)
- for decl in decl.decls:
- pass
- #_write_printf(f, 'FIELD ofs(%s) size(%s)')
- verifier._write_printf(f, 'END struct %s' % self.name)
+ def verifier_declare(self, verifier, kind, name):
+ if kind != 'struct':
+ return
+ if self.fldnames is None:
+ assert not self.partial
+ return
+ verifier.write('{')
+ verifier.write('struct __aligncheck__ { char x; struct %s y; };' %
+ self.name)
+ verifier.write('struct %s __test__;' % self.name)
+ verifier.write_printf('BEGIN struct %s' % self.name)
+ verifier.write_printf('SIZE %ld %ld',
+ '(long)sizeof(struct %s)' % self.name,
+ '(long)offsetof(struct __aligncheck__, y)')
+ for fname, ftype, fbitsize in zip(self.fldnames, self.fldtypes,
+ self.fldbitsize):
+ if fbitsize < 0:
+ verifier.write_printf('FIELD ' + fname + ' %ld %ld',
+ '(long)offsetof(struct %s, %s)' %
+ (self.name, fname),
+ '(long)sizeof(__test__.%s)' % fname)
+ else:
+ assert 0, "XXX: bitfield"
+ verifier.write_printf('END')
+ verifier.write('}')
class UnionType(StructOrUnion):
kind = 'union'
diff --git a/cffi/verifier.py b/cffi/verifier.py
--- a/cffi/verifier.py
+++ b/cffi/verifier.py
@@ -3,23 +3,31 @@
class Verifier(object):
- def _write_printf(f, what, *args):
+ def write(self, what):
+ print >> self.f, ' ' + what
+
+ def write_printf(self, what, *args):
+ self.has_printf = True
if not args:
- f.write(' printf("%s\\n");\n' % (what,))
+ print >> self.f, ' printf("%s\\n");' % (what,)
else:
- f.write(' printf("%s\\n", %s);\n' % (what, ', '.join(args)))
+ print >> self.f, ' printf("%s\\n", %s);' % (
+ what, ', '.join(args))
def verify(self, ffi, preamble, **kwargs):
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')
f.write('#include <stdint.h>\n')
f.write('#include <stddef.h>\n')
f.write(preamble + "\n\n")
f.write('int main() {\n')
+ self.f = f
for name, tp in ffi._parser._declarations.iteritems():
kind, realname = name.split(' ', 1)
- tp.verifier_declare(self, kind, realname, f)
+ tp.verifier_declare(self, kind, realname)
+ del self.f
f.write(' return 0;\n')
f.write('}\n')
err = os.system('gcc -Werror -c %s.c -o %s.o' %
diff --git a/testing/test_platform.py b/testing/test_platform.py
deleted file mode 100644
--- a/testing/test_platform.py
+++ /dev/null
@@ -1,19 +0,0 @@
-
-import py
-from cffi import FFI, VerificationMissing
-
-def test_ffi_nonfull_struct():
- py.test.skip("XXX")
- ffi = FFI()
- ffi.cdef("""
- struct sockaddr {
- int sa_family;
- ...;
- };
- """)
- py.test.raises(VerificationMissing, ffi.sizeof, 'struct sockaddr')
- ffi.verify('''
- #include <sys/types.h>
- #include <sys/socket.h>
- ''')
- assert ffi.sizeof('struct sockaddr') == 14 + ffi.sizeof(int)
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -1,5 +1,6 @@
import py
-from cffi import FFI, VerificationError
+from cffi import FFI, VerificationError, VerificationMissing
+
def test_simple_verify():
ffi = FFI()
@@ -21,3 +22,24 @@
ffi = FFI()
ffi.cdef("size_t strlen(const char *s);")
ffi.verify("#include <string.h>")
+
+
+def test_ffi_nonfull_struct():
+ py.test.skip("XXX")
+ ffi = FFI()
+ ffi.cdef("""
+ struct foo_s {
+ int x;
+ ...;
+ };
+ """)
+ py.test.raises(VerificationMissing, ffi.sizeof, 'struct foo_s')
+ py.test.raises(VerificationMissing, ffi.offsetof, 'struct foo_s', 'x')
+ py.test.raises(VerificationMissing, ffi.new, 'struct foo_s')
+ ffi.verify("""
+ struct foo_s {
+ int a, b, x, c, d, e;
+ };
+ """)
+ assert ffi.sizeof('struct foo_s') == 6 * ffi.sizeof(int)
+ assert ffi.offsetof('struct foo_s', 'x') == 2 * ffi.sizeof(int)
More information about the pypy-commit
mailing list