Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r1471:9cdae12e006f
Date: 2014-03-05 09:19 +0100
http://bitbucket.org/cffi/cffi/changeset/9cdae12e006f/

Log:    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.

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -3583,10 +3583,40 @@
     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 @@
     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 @@
                           &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
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -2897,7 +2897,7 @@
                                        ('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 @@
     p.c = b'\x9D'
     raw = buffer(p)[:]
     if sys.byteorder == 'little':
-        if flag == 0 or flag == 2:  # gcc, little endian
+        if flag & SF_MSVC_BITFIELDS:
+            assert raw == b'A\x00\x00\x007\xC7\x00\x00\x9D\x00\x00\x00'
+        elif flag & SF_GCC_LITTLE_ENDIAN:
             assert raw == b'A7\xC7\x9D'
-        elif flag == 1: # msvc
-            assert raw == b'A\x00\x00\x007\xC7\x00\x00\x9D\x00\x00\x00'
-        elif flag == 4: # gcc, big endian
+        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
+        if flag & SF_MSVC_BITFIELDS:
+            assert raw == b'A\x00\x00\x00\x00\x00\xC77\x9D\x00\x00\x00'
+        elif flag & SF_GCC_LITTLE_ENDIAN:
             assert raw == b'A\xC77\x9D'
-        elif flag == 1: # msvc
-            assert raw == b'A\x00\x00\x00\x00\x00\xC77\x9D\x00\x00\x00'
-        elif flag == 4: # gcc, big endian
+        elif flag & SF_GCC_BIG_ENDIAN:
             assert raw == b'A\x9B\xE3\x9D'
         else:
             raise AssertionError("bad flag")
@@ -2935,18 +2935,15 @@
                                        ('',  BShort, 9),
                                        ('c', BChar, -1)], -1, -1, -1, flag)
     assert typeoffsetof(BStruct, 'c') == (BChar, 4)
-    if flag == 0:   # gcc
+    if flag & SF_MSVC_BITFIELDS:
+        assert sizeof(BStruct) == 6
+        assert alignof(BStruct) == 2
+    elif flag & SF_GCC_X86_BITFIELDS:
         assert sizeof(BStruct) == 5
         assert alignof(BStruct) == 1
-    elif flag == 1: # msvc
+    elif flag & SF_GCC_ARM_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
-        assert sizeof(BStruct) == 5
-        assert alignof(BStruct) == 1
     else:
         raise AssertionError("bad flag")
     #
@@ -2955,37 +2952,43 @@
                                        ('',  BInt, 0),
                                        ('',  BInt, 0),
                                        ('c', BChar, -1)], -1, -1, -1, flag)
-    if flag == 0:    # gcc
+    if flag & SF_MSVC_BITFIELDS:
+        assert typeoffsetof(BStruct, 'c') == (BChar, 1)
+        assert sizeof(BStruct) == 2
+        assert alignof(BStruct) == 1
+    elif flag & SF_GCC_X86_BITFIELDS:
         assert typeoffsetof(BStruct, 'c') == (BChar, 4)
         assert sizeof(BStruct) == 5
         assert alignof(BStruct) == 1
-    elif flag == 1:  # msvc
-        assert typeoffsetof(BStruct, 'c') == (BChar, 1)
-        assert sizeof(BStruct) == 2
-        assert alignof(BStruct) == 1
-    elif flag == 2:  # gcc ARM
+    elif flag & SF_GCC_ARM_BITFIELDS:
         assert typeoffsetof(BStruct, 'c') == (BChar, 4)
         assert sizeof(BStruct) == 8
         assert alignof(BStruct) == 4
-    elif flag == 4:  # gcc, big endian
-        assert typeoffsetof(BStruct, 'c') == (BChar, 4)
-        assert sizeof(BStruct) == 5
-        assert alignof(BStruct) == 1
     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 @@
     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 @@
                    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
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to