summaryrefslogtreecommitdiff
path: root/c
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2014-01-14 09:06:06 +0100
committerArmin Rigo <arigo@tunes.org>2014-01-14 09:06:06 +0100
commitcaedfd9210778c664494c16ec14540bfba3a9412 (patch)
treef628b55eb5d0aa29372227a9afc036640fe96149 /c
parent598008bfc3a39a69ca00c32b2405524c4740ebea (diff)
downloadcffi-caedfd9210778c664494c16ec14540bfba3a9412.tar.gz
Issue 131: support ffi.cdef("...", packed=True)
Diffstat (limited to 'c')
-rw-r--r--c/_cffi_backend.c5
-rw-r--r--c/test_c.py28
2 files changed, 31 insertions, 2 deletions
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
index 1fa38bc..85fe49d 100644
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -3586,6 +3586,7 @@ _add_field(PyObject *interned_fields, PyObject *fname, CTypeDescrObject *ftype,
#define SF_MSVC_BITFIELDS 1
#define SF_GCC_ARM_BITFIELDS 2
#define SF_GCC_BIG_ENDIAN 4
+#define SF_PACKED 8
static PyObject *b_complete_struct_or_union(PyObject *self, PyObject *args)
{
@@ -3671,8 +3672,8 @@ static PyObject *b_complete_struct_or_union(PyObject *self, PyObject *args)
boffset = 0; /* reset each field at offset 0 */
/* update the total alignment requirement, but skip it if the
- field is an anonymous bitfield */
- falign = get_alignment(ftype);
+ field is an anonymous bitfield or if SF_PACKED */
+ falign = (sflags & SF_PACKED) ? 1 : get_alignment(ftype);
if (falign < 0)
goto error;
diff --git a/c/test_c.py b/c/test_c.py
index 6249260..005a089 100644
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -3148,6 +3148,34 @@ def test_sizeof_sliced_array():
p = newp(BArray, None)
assert sizeof(p[2:9]) == 7 * sizeof(BInt)
+def test_packed():
+ BLong = new_primitive_type("long")
+ BChar = new_primitive_type("char")
+ BShort = new_primitive_type("short")
+ BStruct = new_struct_type("struct foo")
+ complete_struct_or_union(BStruct, [('a1', BLong, -1),
+ ('a2', BChar, -1),
+ ('a3', BShort, -1)],
+ None, -1, -1, 8) # SF_PACKED==8
+ d = BStruct.fields
+ assert len(d) == 3
+ assert d[0][0] == 'a1'
+ assert d[0][1].type is BLong
+ assert d[0][1].offset == 0
+ assert d[0][1].bitshift == -1
+ assert d[0][1].bitsize == -1
+ assert d[1][0] == 'a2'
+ assert d[1][1].type is BChar
+ assert d[1][1].offset == sizeof(BLong)
+ assert d[1][1].bitshift == -1
+ assert d[1][1].bitsize == -1
+ assert d[2][0] == 'a3'
+ assert d[2][1].type is BShort
+ assert d[2][1].offset == sizeof(BLong) + sizeof(BChar)
+ assert d[2][1].bitshift == -1
+ assert d[2][1].bitsize == -1
+ assert sizeof(BStruct) == sizeof(BLong) + sizeof(BChar) + sizeof(BShort)
+ assert alignof(BStruct) == 1
def test_version():
# this test is here mostly for PyPy