Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r195:9d9333df0699
Date: 2014-12-11 12:09 +0000
http://bitbucket.org/cffi/creflect/changeset/9d9333df0699/

Log:    Record which constants were declared as part of an enum

diff --git a/creflect/cparser.py b/creflect/cparser.py
--- a/creflect/cparser.py
+++ b/creflect/cparser.py
@@ -317,11 +317,13 @@
                                           % (tp,))
 
     def add_enum_values_declaration(self, typedecl, values):
+        enumerators = []
         for enumerator in values.enumerators:
+            enumerators.append(enumerator.name)
             self.declarations.append(
                 model.ConstDecl(enumerator.name,
                                 model.QualType(model.int_type)))
-        typedecl.complete = True
+        typedecl.enumerators = enumerators
 
     def parse_constant(self, constant):
         return int(constant.value)   # xxx
diff --git a/creflect/creflect.h b/creflect/creflect.h
--- a/creflect/creflect.h
+++ b/creflect/creflect.h
@@ -64,7 +64,8 @@
     _crx_type_t *(*get_unknown_type)(_CRX_SELF, const char *);
     void (*complete)(_CRX_SELF, _crx_type_t *,
                      size_t, size_t, _crx_field_t[], int);
-    void (*complete_enum)(_CRX_SELF, _crx_type_t *, _crx_type_t *);
+    void (*complete_enum)(_CRX_SELF, _crx_type_t *, _crx_type_t *,
+                          const char *[], int);
     void (*define_type)(_CRX_SELF, const char *, _crx_type_t *, int);
     void (*define_var)(_CRX_SELF, const char *, _crx_type_t *, int,
                        const void *);
diff --git a/creflect/creflect_debug_print.c b/creflect/creflect_debug_print.c
--- a/creflect/creflect_debug_print.c
+++ b/creflect/creflect_debug_print.c
@@ -200,10 +200,15 @@
 }
 
 static void tst_complete_enum(_crx_builder_t *cb, _crx_type_t *t,
-                              _crx_type_t *inttype)
+                              _crx_type_t *inttype,
+                              const char *enumvalues[], int nvalues)
 {
+    int i;
     assert(memcmp(t->text, "ENUM ", 5) == 0);
     printf("%s = %s\n", t->text, inttype->text);
+    for (i = 0; i < nvalues; i++) {
+        printf("| %s\n", enumvalues[i]);
+    }
 }
 
 static void tst_define_type(_crx_builder_t *cb, const char *name,
diff --git a/creflect/model.py b/creflect/model.py
--- a/creflect/model.py
+++ b/creflect/model.py
@@ -741,10 +741,10 @@
 
     def __init__(self, type):
         self.type = type
-        self.complete = False
+        self.enumerators = None
 
     def write_declaration(self, funcblock):
-        if not self.complete or self.type.name is None:
+        if self.enumerators is None or self.type.name is None:
             return     # opaque
         tp = "%s %s" % (self.type.kind, self.type.name)
         block = CodeBlock(funcblock)
@@ -767,7 +767,14 @@
         t1 = self.type.get_type_var(block)
         t2 = block.write_crx_type_var('_CRX_INT_TYPE(cb, %s, _crx_sc_int)' %
                                           (expr,))
-        block.writeline('cb->complete_enum(cb, %s, %s);' % (t1, t2))
+        if len(self.enumerators) == 0:
+            e_var = "0"
+        else:
+            block.writedecl("const char *e[] = { %s };" % (
+                ", ".join(['"%s"' % e for e in self.enumerators]),))
+            e_var = "e"
+        block.writeline('cb->complete_enum(cb, %s, %s, %s, %d);' % (
+            t1, t2, e_var, len(self.enumerators)))
         funcblock.write_subblock(block)
 
 
diff --git a/creflect/test/codegen/enum-003.c b/creflect/test/codegen/enum-003.c
--- a/creflect/test/codegen/enum-003.c
+++ b/creflect/test/codegen/enum-003.c
@@ -15,9 +15,11 @@
 #expect NUMCONST AA = int 0
     }
     {
+        const char *e[] = { "AA" };
         t2 = cb->get_enum_type(cb, "myname_e");
         t3 = _CRX_INT_TYPE(cb, (enum myname_e)-1, _crx_sc_int);
-        cb->complete_enum(cb, t2, t3);
+        cb->complete_enum(cb, t2, t3, e, 1);
 #expect ENUM myname_e = unsigned int
+#expect | AA
     }
 }
diff --git a/creflect/test/codegen/enum-003b.c 
b/creflect/test/codegen/enum-003b.c
--- a/creflect/test/codegen/enum-003b.c
+++ b/creflect/test/codegen/enum-003b.c
@@ -20,9 +20,12 @@
 #expect NUMCONST BB = int 3
     }
     {
+        const char *e[] = { "AA", "BB" };
         t3 = cb->get_enum_type(cb, "myname_e");
         t4 = _CRX_INT_TYPE(cb, (enum myname_e)-1, _crx_sc_int);
-        cb->complete_enum(cb, t3, t4);
+        cb->complete_enum(cb, t3, t4, e, 2);
 #expect ENUM myname_e = unsigned int
+#expect | AA
+#expect | BB
     }
 }
diff --git a/creflect/test/codegen/enum-003c.c 
b/creflect/test/codegen/enum-003c.c
--- a/creflect/test/codegen/enum-003c.c
+++ b/creflect/test/codegen/enum-003c.c
@@ -13,9 +13,11 @@
 #expect NUMCONST AA = int -3
     }
     {
+        const char *e[] = { "AA" };
         t2 = cb->get_enum_type(cb, "myname_e");
         t3 = _CRX_INT_TYPE(cb, (enum myname_e)-1, _crx_sc_int);
-        cb->complete_enum(cb, t2, t3);
+        cb->complete_enum(cb, t2, t3, e, 1);
 #expect ENUM myname_e = int
+#expect | AA
     }
 }
diff --git a/creflect/test/codegen/enum-004.c b/creflect/test/codegen/enum-004.c
--- a/creflect/test/codegen/enum-004.c
+++ b/creflect/test/codegen/enum-004.c
@@ -15,12 +15,14 @@
     {
         foo_t p1;
         char b[sizeof(*p1)];
+        const char *e[] = { "AA" };
         memset(b, -1, sizeof(b));
         p1 = (foo_t)b;
         t2 = cb->get_enum_type(cb, "$$foo_t");
         t3 = _CRX_INT_TYPE(cb, *p1, _crx_sc_int);
-        cb->complete_enum(cb, t2, t3);
+        cb->complete_enum(cb, t2, t3, e, 1);
 #expect ENUM $$foo_t = unsigned int
+#expect | AA
     }
     {
         foo_t *p1;
diff --git a/zeffir/builder.c b/zeffir/builder.c
--- a/zeffir/builder.c
+++ b/zeffir/builder.c
@@ -410,8 +410,8 @@
     return _zef_array_type(cb, ctitem, (size_t)-1, NULL);
 }
 
-static _crx_type_t *_zef_struct_or_union(_crx_builder_t *cb, const char *name,
-                                         int flag, const char *prefix_name)
+static _crx_type_t *_zef_struct_union_enum(_crx_builder_t *cb, const char 
*name,
+                                           int flag, const char *prefix_name)
 {
     if (PyErr_Occurred())
         return NULL;
@@ -448,17 +448,17 @@
 
 static _crx_type_t *zef_get_struct_type(_crx_builder_t *cb, const char *name)
 {
-    return _zef_struct_or_union(cb, name, CT_STRUCT, "struct ");
+    return _zef_struct_union_enum(cb, name, CT_STRUCT, "struct ");
 }
 
 static _crx_type_t *zef_get_union_type(_crx_builder_t *cb, const char *name)
 {
-    return _zef_struct_or_union(cb, name, CT_UNION, "union ");
+    return _zef_struct_union_enum(cb, name, CT_UNION, "union ");
 }
 
 static _crx_type_t *zef_get_enum_type(_crx_builder_t *cb, const char *name)
 {
-    abort();
+    return _zef_struct_union_enum(cb, name, CT_UNKNOWN | CT_IS_ENUM, "enum ");
 }
 
 static _crx_qual_type zef_get_user_type(_crx_builder_t *cb, const char *name)
@@ -738,10 +738,22 @@
     Py_DECREF(interned_fields);
 }
 
-static void zef_complete_enum(_crx_builder_t *cb, _crx_type_t *t,
-                              _crx_type_t *inttype)
+static void zef_complete_enum(_crx_builder_t *cb, _crx_type_t *ct,
+                              _crx_type_t *inttype,
+                              const char *enumvalues[], int nvalues)
 {
-    abort();
+    assert(inttype->ct_flags & (CT_PRIMITIVE_SIGNED | CT_PRIMITIVE_UNSIGNED));
+    assert(ct->ct_flags & CT_IS_ENUM);
+    if (ct->ct_size >= 0) {
+        PyErr_Format(ZefError, "duplicate declaration of the enum '%s'",
+                     ct->ct_name);
+        return;
+    }
+
+    //...
+
+    ct->ct_flags = inttype->ct_flags | CT_IS_ENUM;
+    ct->ct_size = inttype->ct_size;
 }
 
 static void zef_define_type(_crx_builder_t *cb, const char *name,
diff --git a/zeffir/test/enum.crx b/zeffir/test/enum.crx
new file mode 100644
--- /dev/null
+++ b/zeffir/test/enum.crx
@@ -0,0 +1,8 @@
+enum foo_e { AA, BB, CC };
+
+
+// CREFLECT: start
+
+enum foo_e { AA, CC };
+
+// CREFLECT: end
diff --git a/zeffir/test/test_enum.py b/zeffir/test/test_enum.py
new file mode 100644
--- /dev/null
+++ b/zeffir/test/test_enum.py
@@ -0,0 +1,10 @@
+import py
+import support
+
+
+def test_simple_enum():
+    ffi, lib = support.compile_and_open('enum')
+    assert lib.AA == 0
+    assert lib.CC == 2
+    n = int(ffi.cast('enum foo_e', -5))
+    assert n == 2 ** 32 - 5     # unsigned
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to