Author: Armin Rigo <[email protected]>
Branch:
Changeset: r1258:4b188c2ba3f0
Date: 2013-05-30 19:19 +0200
http://bitbucket.org/cffi/cffi/changeset/4b188c2ba3f0/
Log: Improve the tests
diff --git a/testing/test_ffi_backend.py b/testing/test_ffi_backend.py
--- a/testing/test_ffi_backend.py
+++ b/testing/test_ffi_backend.py
@@ -40,26 +40,63 @@
class TestBitfield:
def check(self, source, expected_ofs_y, expected_align, expected_size):
+ ffi = FFI()
+ ffi.cdef("struct s1 { %s };" % source)
+ ctype = ffi.typeof("struct s1")
# verify the information with gcc
if sys.platform != "win32":
ffi1 = FFI()
- ffi1.cdef("static const int Gofs_y, Galign, Gsize;")
+ ffi1.cdef("""
+ static const int Gofs_y, Galign, Gsize;
+ struct s1 *try_with_value(int fieldnum, long long value);
+ """)
+ fnames = [name for name, cfield in ctype.fields
+ if cfield.bitsize > 0]
+ setters = ['case %d: s.%s = value; break;' % iname
+ for iname in enumerate(fnames)]
lib = ffi1.verify("""
struct s1 { %s };
struct sa { char a; struct s1 b; };
#define Gofs_y offsetof(struct s1, y)
#define Galign offsetof(struct sa, b)
#define Gsize sizeof(struct s1)
- """ % source)
+ char *try_with_value(int fieldnum, long long value)
+ {
+ static struct s1 s;
+ memset(&s, 0, sizeof(s));
+ switch (fieldnum) { %s }
+ return &s;
+ }
+ """ % (source, ' '.join(setters)))
assert lib.Gofs_y == expected_ofs_y
assert lib.Galign == expected_align
assert lib.Gsize == expected_size
+ else:
+ lib = None
+ fnames = None
# the real test follows
- ffi = FFI()
- ffi.cdef("struct s1 { %s };" % source)
assert ffi.offsetof("struct s1", "y") == expected_ofs_y
assert ffi.alignof("struct s1") == expected_align
assert ffi.sizeof("struct s1") == expected_size
+ # compare the actual storage of the two
+ for name, cfield in ctype.fields:
+ if cfield.bitsize < 0:
+ continue
+ max_value = (1 << (cfield.bitsize-1)) - 1
+ min_value = -(1 << (cfield.bitsize-1))
+ self._fieldcheck(ffi, lib, fnames, name, 1)
+ self._fieldcheck(ffi, lib, fnames, name, min_value)
+ self._fieldcheck(ffi, lib, fnames, name, max_value)
+
+ def _fieldcheck(self, ffi, lib, fnames, name, value):
+ s = ffi.new("struct s1 *")
+ setattr(s, name, value)
+ assert getattr(s, name) == value
+ raw1 = bytes(ffi.buffer(s))
+ if lib is not None:
+ t = lib.try_with_value(fnames.index(name), value)
+ raw2 = bytes(ffi.buffer(t, len(raw1)))
+ assert raw1 == raw2
def test_bitfield_basic(self):
self.check("int a; int b:9; int c:20; int y;", 8, 4, 12)
@@ -67,11 +104,17 @@
self.check("int a; short b:9; short c:9; int y;", 8, 4, 12)
def test_bitfield_reuse_if_enough_space(self):
+ self.check("int a:2; char y;", 1, 4, 4)
self.check("char a; int b:9; char y;", 3, 4, 4)
self.check("char a; short b:9; char y;", 4, 2, 6)
+ self.check("int a:2; char b:6; char y;", 1, 4, 4)
+ self.check("int a:2; char b:7; char y;", 2, 4, 4)
+ self.check("int a:2; short b:15; char c:2; char y;", 5, 4, 8)
+ self.check("int a:2; char b:1; char c:1; char y;", 1, 4, 4)
def test_bitfield_anonymous_no_align(self):
L = FFI().alignof("long long")
+ self.check("char y; int :1;", 0, 1, 2)
self.check("char x; int z:1; char y;", 2, 4, 4)
self.check("char x; int :1; char y;", 2, 1, 3)
self.check("char x; long long z:48; char y;", 7, L, 8)
@@ -83,5 +126,6 @@
def test_bitfield_zero(self):
L = FFI().alignof("long long")
+ self.check("char y; int :0;", 0, 1, 4)
self.check("char x; int :0; char y;", 4, 1, 5)
self.check("char x; long long :0; char y;", L, 1, L + 1)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit