[pypy-commit] cffi cffi-1.0: Parsing enums

arigo noreply at buildbot.pypy.org
Fri Apr 24 14:33:06 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r1801:e5783fd730ed
Date: 2015-04-24 14:21 +0200
http://bitbucket.org/cffi/cffi/changeset/e5783fd730ed/

Log:	Parsing enums

diff --git a/_cffi1/parse_c_type.c b/_cffi1/parse_c_type.c
--- a/_cffi1/parse_c_type.c
+++ b/_cffi1/parse_c_type.c
@@ -26,6 +26,7 @@
     //TOK__COMPLEX,
     TOK_CONST,
     TOK_DOUBLE,
+    TOK_ENUM,
     TOK_FLOAT,
     //TOK__IMAGINARY,
     TOK_INT,
@@ -150,6 +151,9 @@
     case 'd':
         if (tok->size == 6 && !memcmp(p, "double", 6)) tok->kind = TOK_DOUBLE;
         break;
+    case 'e':
+        if (tok->size == 4 && !memcmp(p, "enum", 4))   tok->kind = TOK_ENUM;
+        break;
     case 'f':
         if (tok->size == 5 && !memcmp(p, "float", 5))  tok->kind = TOK_FLOAT;
         break;
@@ -375,6 +379,7 @@
 MAKE_SEARCH_FUNC(globals)
 MAKE_SEARCH_FUNC(struct_unions)
 MAKE_SEARCH_FUNC(typenames)
+MAKE_SEARCH_FUNC(enums)
 
 #undef MAKE_SEARCH_FUNC
 
@@ -509,6 +514,7 @@
         case TOK_FLOAT:
         case TOK_STRUCT:
         case TOK_UNION:
+        case TOK_ENUM:
             return parse_error(tok, "invalid combination of types");
 
         case TOK_DOUBLE:
@@ -598,6 +604,19 @@
             t1 = _CFFI_OP(_CFFI_OP_STRUCT_UNION, n);
             break;
         }
+        case TOK_ENUM:
+        {
+            next_token(tok);
+            if (tok->kind != TOK_IDENTIFIER)
+                return parse_error(tok, "enum name expected");
+
+            int n = search_in_enums(tok->info->ctx, tok->p, tok->size);
+            if (n < 0)
+                return parse_error(tok, "undefined enum name");
+
+            t1 = _CFFI_OP(_CFFI_OP_ENUM, n);
+            break;
+        }
         default:
             return parse_error(tok, "identifier expected");
         }
diff --git a/_cffi1/test_parse_c_type.py b/_cffi1/test_parse_c_type.py
--- a/_cffi1/test_parse_c_type.py
+++ b/_cffi1/test_parse_c_type.py
@@ -21,6 +21,9 @@
 struct_names = ["bar_s", "foo", "foo_", "foo_s", "foo_s1", "foo_s12"]
 assert struct_names == sorted(struct_names)
 
+enum_names = ["ebar_s", "efoo", "efoo_", "efoo_s", "efoo_s1", "efoo_s12"]
+assert enum_names == sorted(enum_names)
+
 identifier_names = ["id", "id0", "id05", "id05b", "tail"]
 assert identifier_names == sorted(identifier_names)
 
@@ -33,6 +36,13 @@
 ctx.struct_unions = ctx_structs
 ctx.num_struct_unions = len(struct_names)
 
+c_enum_names = [ffi.new("char[]", _n) for _n in enum_names]
+ctx_enums = ffi.new("struct _cffi_enum_s[]", len(enum_names))
+for _i in range(len(enum_names)):
+    ctx_enums[_i].name = c_enum_names[_i]
+ctx.enums = ctx_enums
+ctx.num_enums = len(enum_names)
+
 c_identifier_names = [ffi.new("char[]", _n) for _n in identifier_names]
 ctx_identifiers = ffi.new("struct _cffi_typename_s[]", len(identifier_names))
 for _i in range(len(identifier_names)):
@@ -93,6 +103,7 @@
 Func = make_getter('FUNCTION')
 FuncEnd = make_getter('FUNCTION_END')
 Struct = make_getter('STRUCT_UNION')
+Enum = make_getter('ENUM')
 Typename = make_getter('TYPENAME')
 
 
@@ -197,6 +208,12 @@
         Prim(lib._CFFI_PRIM_CHAR),
         OpenArray(4)]
 
+def test_enum():
+    for i in range(len(enum_names)):
+        assert parse("enum %s" % (enum_names[i],)) == ['->', Enum(i)]
+        assert parse("enum %s*" % (enum_names[i],)) == [Enum(i),
+                                                        '->', Pointer(0)]
+
 def test_error():
     parse_error("short short int", "'short' after another 'short' or 'long'", 6)
     parse_error("long long long", "'long long long' is too long", 10)


More information about the pypy-commit mailing list