Author: Armin Rigo <[email protected]>
Branch: cffi-1.0
Changeset: r1804:fff6ae4c61b2
Date: 2015-04-24 16:00 +0200
http://bitbucket.org/cffi/cffi/changeset/fff6ae4c61b2/

Log:    Enums, first complete passing tests

diff --git a/_cffi1/_cffi_include.h b/_cffi1/_cffi_include.h
--- a/_cffi1/_cffi_include.h
+++ b/_cffi1/_cffi_include.h
@@ -161,6 +161,13 @@
 
 #define _cffi_array_len(array)   (sizeof(array) / sizeof((array)[0]))
 
+#define _cffi_prim_int(size, sign)                                      \
+    ((size) == 1 ? ((sign) ? _CFFI_PRIM_INT8  : _CFFI_PRIM_UINT8)  :    \
+     (size) == 2 ? ((sign) ? _CFFI_PRIM_INT16 : _CFFI_PRIM_UINT16) :    \
+     (size) == 4 ? ((sign) ? _CFFI_PRIM_INT32 : _CFFI_PRIM_UINT32) :    \
+     (size) == 8 ? ((sign) ? _CFFI_PRIM_INT64 : _CFFI_PRIM_UINT64) :    \
+     0)
+
 
 static int _cffi_init(void)
 {
diff --git a/_cffi1/parse_c_type.h b/_cffi1/parse_c_type.h
--- a/_cffi1/parse_c_type.h
+++ b/_cffi1/parse_c_type.h
@@ -90,7 +90,7 @@
 
 struct _cffi_enum_s {
     const char *name;
-    int size_and_sign;
+    int type_prim;    /* _CFFI_PRIM_xxx */
 };
 
 struct _cffi_typename_s {
diff --git a/_cffi1/realize_c_type.c b/_cffi1/realize_c_type.c
--- a/_cffi1/realize_c_type.c
+++ b/_cffi1/realize_c_type.c
@@ -360,6 +360,18 @@
         break;
     }
 
+    case _CFFI_OP_ENUM:
+    {
+        const struct _cffi_enum_s *e;
+
+        e = &builder->ctx.enums[_CFFI_GETARG(op)];
+        x = all_primitives[e->type_prim];
+        if (x == NULL)
+            x = build_primitive_type(e->type_prim);
+        Py_XINCREF(x);
+        break;
+    }
+
     case _CFFI_OP_FUNCTION:
     {
         PyObject *fargs;
diff --git a/_cffi1/recompiler.py b/_cffi1/recompiler.py
--- a/_cffi1/recompiler.py
+++ b/_cffi1/recompiler.py
@@ -550,13 +550,13 @@
 
     def _generate_cpy_anonymous_decl(self, tp, name):
         if isinstance(tp, model.EnumType):
-            self._generate_cpy_enum_decl(tp, name, '')
+            self._generate_cpy_enum_decl(tp)
         else:
             self._struct_decl(tp, name, 'typedef_' + name)
 
     def _generate_cpy_anonymous_ctx(self, tp, name):
         if isinstance(tp, model.EnumType):
-            self._generate_cpy_enum_ctx(tp, name, '')
+            self._enum_ctx(tp, name)
         else:
             self._struct_ctx(tp, name, 'typedef_' + name)
 
@@ -589,15 +589,19 @@
         is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type()
         self._generate_cpy_const(is_int, name, tp)
 
+    def _generate_const_int_ctx(self, name):
+        self._lsts["global"].append(
+            '  { "%s", _cffi_const_%s, _CFFI_OP(_CFFI_OP_CONSTANT_INT, 0) },' %
+            (name, name))
+
     def _generate_cpy_constant_ctx(self, tp, name):
-        is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type()
-        if not is_int:
+        if isinstance(tp, model.PrimitiveType) and tp.is_integer_type():
+            self._generate_const_int_ctx(name)
+        else:
             type_index = self._typesdict[tp]
             type_op = '_CFFI_OP(_CFFI_OP_CONSTANT, %d)' % type_index
-        else:
-            type_op = '_CFFI_OP(_CFFI_OP_CONSTANT_INT, 0)'
-        self._lsts["global"].append(
-            '  { "%s", _cffi_const_%s, %s },' % (name, name, type_op))
+            self._lsts["global"].append(
+                '  { "%s", _cffi_const_%s, %s },' % (name, name, type_op))
 
     # ----------
     # enums
@@ -605,6 +609,29 @@
     def _generate_cpy_enum_collecttype(self, tp, name):
         self._do_collect_type(tp)
 
+    def _generate_cpy_enum_decl(self, tp, name=None):
+        for enumerator in tp.enumerators:
+            self._generate_cpy_const(True, enumerator)
+
+    def _enum_ctx(self, tp, cname):
+        for enumerator in tp.enumerators:
+            self._generate_const_int_ctx(enumerator)
+        if cname is not None:
+            size = "sizeof(%s)" % cname
+            signed = "((%s)-1) <= 0" % cname
+            prim = "_cffi_prim_int(%s, %s)" % (size, signed)
+        else:
+            size = xxxx
+        self._lsts["enum"].append(
+            '  { "%s", %s },' % (tp.name, prim))
+
+    def _generate_cpy_enum_ctx(self, tp, name):
+        if tp.has_c_name():
+            cname = tp.get_c_name('')
+        else:
+            cname = None
+        self._enum_ctx(tp, cname)
+
     # ----------
     # macros: for now only for integers
 
diff --git a/_cffi1/test_recompiler.py b/_cffi1/test_recompiler.py
--- a/_cffi1/test_recompiler.py
+++ b/_cffi1/test_recompiler.py
@@ -264,16 +264,20 @@
         ffi2.typeof("void(*)(struct foo_s*)"))
 
 def test_verify_enum():
-    py.test.skip("in-progress")
     ffi = FFI()
-    ffi.cdef("""enum e1 { B1, A1, ... };""")
+    ffi.cdef("""enum e1 { B1, A1, ... }; enum e2 { B2, A2, ... };""")
     lib = verify(ffi, 'test_verify_enum',
-                 "enum e1 { A1, B1, C1=%d };" % sys.maxint)
+                 "enum e1 { A1, B1, C1=%d };" % sys.maxint +
+                 "enum e2 { A2, B2, C2 };")
     ffi.typeof("enum e1")
+    ffi.typeof("enum e2")
     assert lib.A1 == 0
-    assert lib.B1 == 0
+    assert lib.B1 == 1
+    assert lib.A2 == 0
+    assert lib.B2 == 1
     assert ffi.sizeof("enum e1") == ffi.sizeof("long")
-
+    assert ffi.sizeof("enum e2") == ffi.sizeof("int")
+ 
 def test_dotdotdot_length_of_array_field():
     ffi = FFI()
     ffi.cdef("struct foo_s { int a[...]; int b[...]; };")
@@ -341,3 +345,18 @@
            "typedef struct { int a; long b; } *foo_t;")
     p = ffi.new("foo_t", {'b': 42})
     assert p.b == 42
+
+def test_verify_anonymous_enum_with_typedef():
+    ffi = FFI()
+    ffi.cdef("typedef enum { AA, ... } e1;")
+    lib = verify(ffi, 'test_verify_anonymous_enum_with_typedef1',
+                 "typedef enum { BB, CC, AA } e1;")
+    assert lib.AA == 2
+    assert ffi.sizeof("e1") == ffi.sizeof("int")
+    #
+    ffi = FFI()
+    ffi.cdef("typedef enum { AA=%d } e1;" % sys.maxint)
+    lib = verify(ffi, 'test_verify_anonymous_enum_with_typedef2',
+                 "typedef enum { AA=%d } e1;" % sys.maxint)
+    assert lib.AA == sys.maxint
+    assert ffi.sizeof("e1") == ffi.sizeof("long")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to