[pypy-commit] cffi cffi-1.0: Unions

arigo noreply at buildbot.pypy.org
Thu Apr 16 15:41:03 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r1734:2137e0acbd73
Date: 2015-04-16 15:41 +0200
http://bitbucket.org/cffi/cffi/changeset/2137e0acbd73/

Log:	Unions

diff --git a/new/realize_c_type.c b/new/realize_c_type.c
--- a/new/realize_c_type.c
+++ b/new/realize_c_type.c
@@ -155,7 +155,18 @@
             Py_INCREF(x);
         }
         else {
-            x = new_struct_or_union_type(s->name, CT_STRUCT);
+            int flags;
+            char *name = alloca(8 + strlen(s->name));
+            if (s->flags & CT_UNION) {
+                strcpy(name, "union ");
+                flags = CT_UNION;
+            }
+            else {
+                strcpy(name, "struct ");
+                flags = CT_STRUCT;
+            }
+            strcat(name, s->name);
+            x = new_struct_or_union_type(name, flags);
             /* We are going to update the "primary" OP_STRUCT_OR_UNION
                slot below, which may be the same or a different one as
                the "current" slot.  If it is a different one, the
diff --git a/new/recompiler.py b/new/recompiler.py
--- a/new/recompiler.py
+++ b/new/recompiler.py
@@ -378,6 +378,9 @@
 
     def _generate_cpy_struct_ctx(self, tp, name):
         type_index = self._typesdict[tp]
+        flags = '0'
+        if isinstance(tp, model.UnionType):
+            flags = 'CT_UNION'
         if tp.fldtypes is not None:
             size_align = ('\n' +
                 '    sizeof(%s %s),\n' % (tp.kind, name) +
@@ -386,9 +389,11 @@
         else:
             size_align = ' -1, -1, -1, 0 /* opaque */ },'
         self._lsts["struct_union"].append(
-            '  { "%s", %d, 0,' % (name, type_index) + size_align)
+            '  { "%s", %d, %s,' % (name, type_index, flags) + size_align)
 
     _generate_cpy_union_collecttype = _generate_cpy_struct_collecttype
+    _generate_cpy_union_decl = _generate_cpy_struct_decl
+    _generate_cpy_union_ctx = _generate_cpy_struct_ctx
 
     # ----------
     # constants, declared with "static const ..."
diff --git a/new/test_parse_c_type.py b/new/test_parse_c_type.py
--- a/new/test_parse_c_type.py
+++ b/new/test_parse_c_type.py
@@ -238,6 +238,12 @@
         assert parse("%s %s*" % (tag, struct_names[i])) == [Struct(i),
                                                             '->', Pointer(0)]
 
+def test_exchanging_struct_union():
+    parse_error("union %s" % (struct_names[0],),
+                "wrong kind of tag: struct vs union", 6)
+    parse_error("struct %s" % (struct_names[3],),
+                "wrong kind of tag: struct vs union", 7)
+
 def test_identifier():
     for i in range(len(identifier_names)):
         assert parse("%s" % (identifier_names[i])) == ['->', Typename(i)]
diff --git a/new/test_recompiler.py b/new/test_recompiler.py
--- a/new/test_recompiler.py
+++ b/new/test_recompiler.py
@@ -160,8 +160,14 @@
 def test_verify_opaque_struct():
     ffi = FFI()
     ffi.cdef("struct foo_s;")
-    lib = verify(ffi, 'test_verify_opaque_struct', "struct foo_s;")
-    ffi.new("struct foo_s **")
+    ffi, lib = verify2(ffi, 'test_verify_opaque_struct', "struct foo_s;")
+    assert ffi.typeof("struct foo_s").cname == "struct foo_s"
+
+def test_verify_opaque_union():
+    ffi = FFI()
+    ffi.cdef("union foo_s;")
+    ffi, lib = verify2(ffi, 'test_verify_opaque_union', "union foo_s;")
+    assert ffi.typeof("union foo_s").cname == "union foo_s"
 
 def test_verify_struct():
     py.test.skip("XXX in-progress:")


More information about the pypy-commit mailing list