summaryrefslogtreecommitdiff
path: root/c/parse_c_type.c
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2015-11-02 23:12:06 +0100
committerArmin Rigo <arigo@tunes.org>2015-11-02 23:12:06 +0100
commit8249cb6f4e628cce17b509cc24ece6425b83497a (patch)
tree66a16906ac8cf9bf3e8a2747a28fb87bddfedee5 /c/parse_c_type.c
parent361b5b2a0b736af048c842515bbb4478d8287f80 (diff)
downloadcffi-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.c76
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);
+}