Author: Armin Rigo <ar...@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)] _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit