[pypy-commit] cffi cffi-1.0: Typenames

arigo noreply at buildbot.pypy.org
Sat Apr 11 09:39:20 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r1694:54d0281c9072
Date: 2015-04-11 09:39 +0200
http://bitbucket.org/cffi/cffi/changeset/54d0281c9072/

Log:	Typenames

diff --git a/new/parse_c_type.c b/new/parse_c_type.c
--- a/new/parse_c_type.c
+++ b/new/parse_c_type.c
@@ -432,6 +432,25 @@
     return -1;
 }
 
+static int search_typename(struct _cffi_type_context_s *ctx,
+                           const char *search, size_t search_len)
+{
+    int left = 0, right = ctx->num_typenames;
+
+    while (left < right) {
+        int middle = (left + right) / 2;
+        const char *src = ctx->typenames[middle].name;
+        int diff = strncmp(src, search, search_len);
+        if (diff == 0 && src[search_len] == '\0')
+            return middle;
+        else if (diff >= 0)
+            right = middle;
+        else
+            left = middle + 1;
+    }
+    return -1;
+}
+
 static int parse_complete(token_t *tok)
 {
  qualifiers:
@@ -557,21 +576,12 @@
             break;
         case TOK_IDENTIFIER:
         {
-            abort();
-#if 0
-            _crx_qual_type qt2;
-            char identifier[1024];
-            if (tok->size >= 1024) {
-                parse_error(tok, "identifier name too long");
-                return;
-            }
-            memcpy(identifier, tok->p, tok->size);
-            identifier[tok->size] = 0;
-            qt2 = tok->cb->get_user_type(tok->cb, identifier);
-            t1 = qt2.type;
-            result->qualifiers |= qt2.qualifiers;
+            int n = search_typename(tok->info->ctx, tok->p, tok->size);
+            if (n < 0)
+                return parse_error(tok, "undefined type name");
+
+            t1 = _CFFI_OP(_CFFI_OP_TYPENAME, n);
             break;
-#endif
         }
         case TOK_STRUCT:
         case TOK_UNION:
diff --git a/new/parse_c_type.h b/new/parse_c_type.h
--- a/new/parse_c_type.h
+++ b/new/parse_c_type.h
@@ -44,7 +44,7 @@
 struct _cffi_constant_s {
     const char *name;
     unsigned long long value;
-    int type_index_or_plain;
+    int type_index;          // -> _cffi_types or _CFFI_PLAIN_*_INT
 };
 #define _CFFI_PLAIN_POSITIVE_INT     (-1)
 #define _CFFI_PLAIN_NONPOSITIVE_INT  (-2)
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
@@ -21,15 +21,25 @@
 struct_names = ["bar_s", "foo", "foo_", "foo_s", "foo_s1", "foo_s12"]
 assert struct_names == sorted(struct_names)
 
+identifier_names = ["id", "id0", "id05", "id05b", "tail"]
+assert identifier_names == sorted(identifier_names)
+
 ctx = ffi.new("struct _cffi_type_context_s *")
-c_names = [ffi.new("char[]", _n) for _n in struct_names]
+c_struct_names = [ffi.new("char[]", _n) for _n in struct_names]
 ctx_structs = ffi.new("struct _cffi_struct_union_s[]", len(struct_names))
 for _i in range(len(struct_names)):
-    ctx_structs[_i].name = c_names[_i]
+    ctx_structs[_i].name = c_struct_names[_i]
 ctx_structs[3].flags = lib.CT_UNION
 ctx.structs_unions = ctx_structs
 ctx.num_structs_unions = len(struct_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)):
+    ctx_identifiers[_i].name = c_identifier_names[_i]
+ctx.typenames = ctx_identifiers
+ctx.num_typenames = len(identifier_names)
+
 
 def parse(input):
     out = ffi.new("_cffi_opcode_t[]", 100)
@@ -83,6 +93,7 @@
 Func = make_getter('FUNCTION')
 FuncEnd = make_getter('FUNCTION_END')
 Struct = make_getter('STRUCT_UNION')
+Typename = make_getter('TYPENAME')
 
 
 def test_simple():
@@ -224,3 +235,11 @@
         else:
             tag = "struct"
         assert parse("%s %s" % (tag, struct_names[i])) == ['->', Struct(i)]
+        assert parse("%s %s*" % (tag, struct_names[i])) == [Struct(i),
+                                                            '->', Pointer(0)]
+
+def test_identifier():
+    for i in range(len(identifier_names)):
+        assert parse("%s" % (identifier_names[i])) == ['->', Typename(i)]
+        assert parse("%s*" % (identifier_names[i])) == [Typename(i),
+                                                        '->', Pointer(0)]


More information about the pypy-commit mailing list