diff options
author | Armin Rigo <arigo@tunes.org> | 2015-11-02 23:12:06 +0100 |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2015-11-02 23:12:06 +0100 |
commit | 8249cb6f4e628cce17b509cc24ece6425b83497a (patch) | |
tree | 66a16906ac8cf9bf3e8a2747a28fb87bddfedee5 /c/parse_c_type.c | |
parent | 361b5b2a0b736af048c842515bbb4478d8287f80 (diff) | |
download | cffi-8249cb6f4e628cce17b509cc24ece6425b83497a.tar.gz |
Issue #228: "bool" not working in out-of-line FFI objects. Same problem
with all Windows common types. Mostly fixed by moving the list of
common types to C code. The only remaining corner case I can think of
is "FILE", which works only if it was mentioned in the cdef while
building the out-of-line module.
Diffstat (limited to 'c/parse_c_type.c')
-rw-r--r-- | c/parse_c_type.c | 76 |
1 files changed, 55 insertions, 21 deletions
diff --git a/c/parse_c_type.c b/c/parse_c_type.c index 80cd3ff..58c85a8 100644 --- a/c/parse_c_type.c +++ b/c/parse_c_type.c @@ -220,6 +220,8 @@ static int write_ds(token_t *tok, _cffi_opcode_t ds) #define MAX_SSIZE_T (((size_t)-1) >> 1) static int parse_complete(token_t *tok); +static const char *get_common_type(const char *search, size_t search_len); +static int parse_common_type_replacement(token_t *tok, const char *replacement); static int parse_sequel(token_t *tok, int outer) { @@ -442,26 +444,34 @@ static int parse_sequel(token_t *tok, int outer) return _CFFI_GETARG(result); } +static int search_sorted(const char *const *base, + size_t item_size, int array_len, + const char *search, size_t search_len) +{ + int left = 0, right = array_len; + const char *baseptr = (const char *)base; + + while (left < right) { + int middle = (left + right) / 2; + const char *src = *(const char *const *)(baseptr + middle * item_size); + 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; +} -#define MAKE_SEARCH_FUNC(FIELD) \ - static \ - int search_in_##FIELD(const struct _cffi_type_context_s *ctx, \ - const char *search, size_t search_len) \ - { \ - int left = 0, right = ctx->num_##FIELD; \ - \ - while (left < right) { \ - int middle = (left + right) / 2; \ - const char *src = ctx->FIELD[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; \ +#define MAKE_SEARCH_FUNC(FIELD) \ + static \ + int search_in_##FIELD(const struct _cffi_type_context_s *ctx, \ + const char *search, size_t search_len) \ + { \ + return search_sorted(&ctx->FIELD->name, sizeof(*ctx->FIELD), \ + ctx->num_##FIELD, search, search_len); \ } MAKE_SEARCH_FUNC(globals) @@ -715,6 +725,7 @@ static int parse_complete(token_t *tok) break; case TOK_IDENTIFIER: { + const char *replacement; int n = search_in_typenames(tok->info->ctx, tok->p, tok->size); if (n >= 0) { t1 = _CFFI_OP(_CFFI_OP_TYPENAME, n); @@ -725,6 +736,14 @@ static int parse_complete(token_t *tok) t1 = _CFFI_OP(_CFFI_OP_PRIMITIVE, n); break; } + replacement = get_common_type(tok->p, tok->size); + if (replacement != NULL) { + n = parse_common_type_replacement(tok, replacement); + if (n < 0) + return parse_error(tok, "internal error, please report!"); + t1 = _CFFI_OP(_CFFI_OP_NOOP, n); + break; + } return parse_error(tok, "undefined type name"); } case TOK_STRUCT: @@ -770,7 +789,8 @@ static int parse_complete(token_t *tok) static -int parse_c_type(struct _cffi_parse_info_s *info, const char *input) +int parse_c_type_from(struct _cffi_parse_info_s *info, size_t *output_index, + const char *input) { int result; token_t token; @@ -781,12 +801,26 @@ int parse_c_type(struct _cffi_parse_info_s *info, const char *input) token.p = input; token.size = 0; token.output = info->output; - token.output_index = 0; + token.output_index = *output_index; next_token(&token); result = parse_complete(&token); + *output_index = token.output_index; if (token.kind != TOK_END) return parse_error(&token, "unexpected symbol"); return result; } + +static +int parse_c_type(struct _cffi_parse_info_s *info, const char *input) +{ + size_t output_index = 0; + return parse_c_type_from(info, &output_index, input); +} + +static +int parse_common_type_replacement(token_t *tok, const char *replacement) +{ + return parse_c_type_from(tok->info, &tok->output_index, replacement); +} |