diff options
author | Armin Rigo <arigo@tunes.org> | 2014-03-05 09:19:21 +0100 |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2014-03-05 09:19:21 +0100 |
commit | 8b01a1c68ffdcedb1822967fdd57ccdd7f3cdb0e (patch) | |
tree | 94c839f20ac0acacfd375b70af24d2f7b710cc42 | |
parent | dc7ee4dc153b181165da10d645f6eb32e00de0d4 (diff) | |
download | cffi-8b01a1c68ffdcedb1822967fdd57ccdd7f3cdb0e.tar.gz |
Clean up 'sflags'. It was failing because suddenly passing a value
of 0 as argument was not equivalent to not passing any argument at
all.
-rw-r--r-- | c/_cffi_backend.c | 51 | ||||
-rw-r--r-- | c/test_c.py | 73 |
2 files changed, 74 insertions, 50 deletions
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c index bf675c2..401c91c 100644 --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -3583,10 +3583,40 @@ _add_field(PyObject *interned_fields, PyObject *fname, CTypeDescrObject *ftype, return cf; /* borrowed reference */ } -#define SF_MSVC_BITFIELDS 1 -#define SF_GCC_ARM_BITFIELDS 2 -#define SF_GCC_BIG_ENDIAN 4 -#define SF_PACKED 8 +#define SF_MSVC_BITFIELDS 0x01 +#define SF_GCC_ARM_BITFIELDS 0x02 +#define SF_GCC_X86_BITFIELDS 0x10 + +#define SF_GCC_BIG_ENDIAN 0x04 +#define SF_GCC_LITTLE_ENDIAN 0x40 + +#define SF_PACKED 0x08 + +static int complete_sflags(int sflags) +{ + /* add one of the SF_xxx_BITFIELDS flags if none is specified */ + if (!(sflags & (SF_MSVC_BITFIELDS | SF_GCC_ARM_BITFIELDS | + SF_GCC_X86_BITFIELDS))) { +#ifdef MS_WIN32 + sflags |= SF_MSVC_BITFIELDS; +#else +# ifdef __arm__ + sflags |= SF_GCC_ARM_BITFIELDS; +# else + sflags |= SF_GCC_X86_BITFIELDS; +# endif +#endif + } + /* add one of SF_GCC_xx_ENDIAN if none is specified */ + if (!(sflags & (SF_GCC_BIG_ENDIAN | SF_GCC_LITTLE_ENDIAN))) { + int _check_endian = 1; + if (*(char *)&_check_endian == 0) + sflags |= SF_GCC_BIG_ENDIAN; + else + sflags |= SF_GCC_LITTLE_ENDIAN; + } + return sflags; +} static PyObject *b_complete_struct_or_union(PyObject *self, PyObject *args) { @@ -3598,18 +3628,7 @@ static PyObject *b_complete_struct_or_union(PyObject *self, PyObject *args) int totalalignment = -1; CFieldObject **previous; int prev_bitfield_size, prev_bitfield_free; -#ifdef MS_WIN32 - int sflags = SF_MSVC_BITFIELDS; -#else -# ifdef __arm__ - int sflags = SF_GCC_ARM_BITFIELDS; -# else int sflags = 0; -# endif - int _check_endian = 1; - if (*(char *)&_check_endian == 0) - sflags |= SF_GCC_BIG_ENDIAN; -#endif if (!PyArg_ParseTuple(args, "O!O!|Onii:complete_struct_or_union", &CTypeDescr_Type, &ct, @@ -3617,6 +3636,8 @@ static PyObject *b_complete_struct_or_union(PyObject *self, PyObject *args) &ignored, &totalsize, &totalalignment, &sflags)) return NULL; + sflags = complete_sflags(sflags); + if ((ct->ct_flags & (CT_STRUCT|CT_IS_OPAQUE)) == (CT_STRUCT|CT_IS_OPAQUE)) { is_union = 0; diff --git a/c/test_c.py b/c/test_c.py index 0c62995..1d59192 100644 --- a/c/test_c.py +++ b/c/test_c.py @@ -2897,7 +2897,7 @@ def _test_bitfield_details(flag): ('b1', BInt, 9), ('b2', BUInt, 7), ('c', BChar, -1)], -1, -1, -1, flag) - if flag % 2 == 0: # gcc, any variant + if not (flag & SF_MSVC_BITFIELDS): # gcc, any variant assert typeoffsetof(BStruct, 'c') == (BChar, 3) assert sizeof(BStruct) == 4 else: # msvc @@ -2912,20 +2912,20 @@ def _test_bitfield_details(flag): p.c = b'\x9D' raw = buffer(p)[:] if sys.byteorder == 'little': - if flag == 0 or flag == 2: # gcc, little endian - assert raw == b'A7\xC7\x9D' - elif flag == 1: # msvc + if flag & SF_MSVC_BITFIELDS: assert raw == b'A\x00\x00\x007\xC7\x00\x00\x9D\x00\x00\x00' - elif flag == 4: # gcc, big endian + elif flag & SF_GCC_LITTLE_ENDIAN: + assert raw == b'A7\xC7\x9D' + elif flag & SF_GCC_BIG_ENDIAN: assert raw == b'A\xE3\x9B\x9D' else: raise AssertionError("bad flag") else: - if flag == 0 or flag == 2: # gcc - assert raw == b'A\xC77\x9D' - elif flag == 1: # msvc + if flag & SF_MSVC_BITFIELDS: assert raw == b'A\x00\x00\x00\x00\x00\xC77\x9D\x00\x00\x00' - elif flag == 4: # gcc, big endian + elif flag & SF_GCC_LITTLE_ENDIAN: + assert raw == b'A\xC77\x9D' + elif flag & SF_GCC_BIG_ENDIAN: assert raw == b'A\x9B\xE3\x9D' else: raise AssertionError("bad flag") @@ -2935,18 +2935,15 @@ def _test_bitfield_details(flag): ('', BShort, 9), ('c', BChar, -1)], -1, -1, -1, flag) assert typeoffsetof(BStruct, 'c') == (BChar, 4) - if flag == 0: # gcc - assert sizeof(BStruct) == 5 - assert alignof(BStruct) == 1 - elif flag == 1: # msvc + if flag & SF_MSVC_BITFIELDS: assert sizeof(BStruct) == 6 assert alignof(BStruct) == 2 - elif flag == 2: # gcc ARM - assert sizeof(BStruct) == 6 - assert alignof(BStruct) == 2 - elif flag == 4: # gcc, big endian + elif flag & SF_GCC_X86_BITFIELDS: assert sizeof(BStruct) == 5 assert alignof(BStruct) == 1 + elif flag & SF_GCC_ARM_BITFIELDS: + assert sizeof(BStruct) == 6 + assert alignof(BStruct) == 2 else: raise AssertionError("bad flag") # @@ -2955,37 +2952,43 @@ def _test_bitfield_details(flag): ('', BInt, 0), ('', BInt, 0), ('c', BChar, -1)], -1, -1, -1, flag) - if flag == 0: # gcc - assert typeoffsetof(BStruct, 'c') == (BChar, 4) - assert sizeof(BStruct) == 5 - assert alignof(BStruct) == 1 - elif flag == 1: # msvc + if flag & SF_MSVC_BITFIELDS: assert typeoffsetof(BStruct, 'c') == (BChar, 1) assert sizeof(BStruct) == 2 assert alignof(BStruct) == 1 - elif flag == 2: # gcc ARM - assert typeoffsetof(BStruct, 'c') == (BChar, 4) - assert sizeof(BStruct) == 8 - assert alignof(BStruct) == 4 - elif flag == 4: # gcc, big endian + elif flag & SF_GCC_X86_BITFIELDS: assert typeoffsetof(BStruct, 'c') == (BChar, 4) assert sizeof(BStruct) == 5 assert alignof(BStruct) == 1 + elif flag & SF_GCC_ARM_BITFIELDS: + assert typeoffsetof(BStruct, 'c') == (BChar, 4) + assert sizeof(BStruct) == 8 + assert alignof(BStruct) == 4 else: raise AssertionError("bad flag") -def test_bitfield_as_gcc(): - _test_bitfield_details(flag=0) +SF_MSVC_BITFIELDS = 0x01 +SF_GCC_ARM_BITFIELDS = 0x02 +SF_GCC_X86_BITFIELDS = 0x10 + +SF_GCC_BIG_ENDIAN = 0x04 +SF_GCC_LITTLE_ENDIAN = 0x40 + +SF_PACKED = 0x08 + +def test_bitfield_as_x86_gcc(): + _test_bitfield_details(flag=SF_GCC_X86_BITFIELDS|SF_GCC_LITTLE_ENDIAN) def test_bitfield_as_msvc(): - _test_bitfield_details(flag=1) + _test_bitfield_details(flag=SF_MSVC_BITFIELDS|SF_GCC_LITTLE_ENDIAN) def test_bitfield_as_arm_gcc(): - _test_bitfield_details(flag=2) + _test_bitfield_details(flag=SF_GCC_ARM_BITFIELDS|SF_GCC_LITTLE_ENDIAN) -def test_bitfield_as_big_endian(): - _test_bitfield_details(flag=4) +def test_bitfield_as_ppc_gcc(): + # PowerPC uses the same format as X86, but is big-endian + _test_bitfield_details(flag=SF_GCC_X86_BITFIELDS|SF_GCC_BIG_ENDIAN) def test_struct_array_no_length(): @@ -3161,7 +3164,7 @@ def test_packed(): complete_struct_or_union(BStruct, [('a1', BLong, -1), ('a2', BChar, -1), ('a3', BShort, -1)], - None, -1, -1, 8) # SF_PACKED==8 + None, -1, -1, SF_PACKED) d = BStruct.fields assert len(d) == 3 assert d[0][0] == 'a1' @@ -3190,7 +3193,7 @@ def test_packed_with_bitfields(): complete_struct_or_union, BStruct, [('a1', BLong, 30), ('a2', BChar, 5)], - None, -1, -1, 8) # SF_PACKED==8 + None, -1, -1, SF_PACKED) def test_version(): # this test is here mostly for PyPy |