Author: Armin Rigo <[email protected]>
Branch:
Changeset: r132:6ed79bee3ecc
Date: 2014-11-30 23:43 +0100
http://bitbucket.org/cffi/creflect/changeset/6ed79bee3ecc/
Log: fix fix done
diff --git a/creflect/creflect_cdecl.c b/creflect/creflect_cdecl.c
--- a/creflect/creflect_cdecl.c
+++ b/creflect/creflect_cdecl.c
@@ -35,6 +35,7 @@
TOK_UNION,
TOK_UNSIGNED,
TOK_VOID,
+ TOK_VOLATILE,
};
#define NUM_DELAY_SLOTS 5000
@@ -152,6 +153,7 @@
break;
case 'v':
if (tok->size == 4 && !memcmp(p, "void", 4)) tok->kind = TOK_VOID;
+ if (tok->size == 8 && !memcmp(p,"volatile",8)) tok->kind =
TOK_VOLATILE;
break;
}
}
@@ -178,12 +180,13 @@
return result;
}
-static _crx_type_t *parse_complete(token_t *tok);
+static void parse_complete(token_t *tok, _crx_qual_type *result);
static void parse_sequel(token_t *tok, intptr_t ds_end)
{
intptr_t *ds;
- while (tok->kind == TOK_STAR || tok->kind == TOK_CONST) {
+ while (tok->kind == TOK_STAR || tok->kind == TOK_CONST ||
+ tok->kind == TOK_VOLATILE) {
ds = alloc_ds(tok, 1);
if (ds == NULL)
return;
@@ -212,6 +215,7 @@
if (check_for_grouping == 0 && (tok->kind == TOK_STAR ||
tok->kind == TOK_CONST ||
+ tok->kind == TOK_VOLATILE ||
tok->kind == TOK_OPEN_BRACKET)) {
/* just parentheses for grouping */
ds = tok->delay_slots;
@@ -235,12 +239,12 @@
next_token(tok);
break;
}
- _crx_type_t *t1 = parse_complete(tok);
- intptr_t *ds_type = alloc_ds(tok, 1);
+ intptr_t *ds_type = alloc_ds(tok, 2);
if (ds_type == NULL)
return;
- assert(ds_type == ds + 2 + ds[1]);
- *ds_type = (intptr_t)t1;
+ assert(ds_type == ds + 2 + 2 * ds[1]);
+ assert(2 * sizeof(intptr_t) >= sizeof(_crx_qual_type));
+ parse_complete(tok, (_crx_qual_type *)ds_type);
ds[1]++;
if (tok->kind != TOK_COMMA)
break;
@@ -250,7 +254,7 @@
intptr_t *ds_next = alloc_ds(tok, 1);
if (ds_next == NULL)
return;
- assert(ds_next == ds + 2 + ds[1]);
+ assert(ds_next == ds + 2 + 2 * ds[1]);
*ds_next = *jump_slot;
*jump_slot = -(ds - tok->all_delay_slots);
}
@@ -303,11 +307,11 @@
}
}
-static _crx_type_t *fetch_delay_slots(token_t *tok, _crx_type_t *t1,
- intptr_t *delay_slot)
+static void fetch_delay_slots(token_t *tok, _crx_qual_type *result,
+ intptr_t *delay_slot)
{
if (tok->kind == TOK_ERROR)
- return NULL;
+ return;
tok->delay_slots = delay_slot;
while (1) {
intptr_t tok_kind = *delay_slot++;
@@ -317,34 +321,46 @@
}
switch (tok_kind) {
case TOK_END:
- return t1;
+ return; /* done */
case TOK_STAR:
- t1 = tok->cb->get_pointer_type(tok->cb, t1);
+ result->type = tok->cb->get_pointer_type(tok->cb, result->type,
+ result->qualifiers);
+ result->qualifiers = 0;
break;
case TOK_CONST:
- t1 = tok->cb->get_const_type(tok->cb, t1);
+ result->qualifiers |= _CRX_CONST;
+ break;
+ case TOK_VOLATILE:
+ result->qualifiers |= _CRX_VOLATILE;
break;
case TOK_OPEN_BRACKET: /* array */
{
uintptr_t length = (uintptr_t)*delay_slot++;
if (length != (uintptr_t)-1)
- t1 = tok->cb->get_array_type(tok->cb, t1, length);
+ result->type = tok->cb->get_array_type(
+ tok->cb, result->type, length);
else
- t1 = tok->cb->get_incomplete_array_type(tok->cb, t1);
+ result->type = tok->cb->get_incomplete_array_type(
+ tok->cb, result->type);
+ /* result->qualifiers remains unmodified */
break;
}
case TOK_OPEN_PAREN: /* function */
case TOK_DOTDOTDOT: /* function ending with a '...' */
{
intptr_t nbargs = *delay_slot++;
- _crx_type_t **argtypes = (_crx_type_t **)delay_slot;
- delay_slot += nbargs;
+ _crx_type_t *t1;
+ _crx_qual_type *argtypes = (_crx_qual_type *)delay_slot;
+ delay_slot += 2 * nbargs;
if (tok_kind == TOK_DOTDOTDOT)
- t1 = tok->cb->get_ellipsis_function_type(tok->cb, t1,
+ t1 = tok->cb->get_ellipsis_function_type(tok->cb,
+ result->type,
argtypes, nbargs);
else
- t1 = tok->cb->get_function_type(tok->cb, t1, argtypes,
- nbargs, NULL);
+ t1 = tok->cb->get_function_type(tok->cb, result->type,
+ argtypes, nbargs, NULL);
+ result->type = t1;
+ result->qualifiers = 0; /* drop qualifiers on the return type
*/
break;
}
default:
@@ -353,12 +369,23 @@
}
}
-static _crx_type_t *parse_complete(token_t *tok)
+static void parse_complete(token_t *tok, _crx_qual_type *result)
{
_crx_type_t *t1;
- int is_const = (tok->kind == TOK_CONST);
- if (is_const) {
+
+ result->qualifiers = 0;
+ qualifiers:
+ switch (tok->kind) {
+ case TOK_CONST:
+ result->qualifiers |= _CRX_CONST;
next_token(tok);
+ goto qualifiers;
+ case TOK_VOLATILE:
+ result->qualifiers |= _CRX_VOLATILE;
+ next_token(tok);
+ goto qualifiers;
+ default:
+ ;
}
int modifiers_length = 0;
@@ -367,31 +394,41 @@
switch (tok->kind) {
case TOK_SHORT:
- if (modifiers_length != 0)
- return parse_error(tok, "'short' after another 'short' or 'long'");
+ if (modifiers_length != 0) {
+ parse_error(tok, "'short' after another 'short' or 'long'");
+ return;
+ }
modifiers_length--;
next_token(tok);
goto modifiers;
case TOK_LONG:
- if (modifiers_length < 0)
- return parse_error(tok, "'long' after 'short'");
- if (modifiers_length >= 2)
- return parse_error(tok, "'long long long' is too long");
+ if (modifiers_length < 0) {
+ parse_error(tok, "'long' after 'short'");
+ return;
+ }
+ if (modifiers_length >= 2) {
+ parse_error(tok, "'long long long' is too long");
+ return;
+ }
modifiers_length++;
next_token(tok);
goto modifiers;
case TOK_SIGNED:
- if (modifiers_sign)
- return parse_error(tok, "multiple 'signed' or 'unsigned'");
+ if (modifiers_sign) {
+ parse_error(tok, "multiple 'signed' or 'unsigned'");
+ return;
+ }
modifiers_sign++;
next_token(tok);
goto modifiers;
case TOK_UNSIGNED:
- if (modifiers_sign)
- return parse_error(tok, "multiple 'signed' or 'unsigned'");
+ if (modifiers_sign) {
+ parse_error(tok, "multiple 'signed' or 'unsigned'");
+ return;
+ }
modifiers_sign--;
next_token(tok);
goto modifiers;
@@ -410,19 +447,24 @@
case TOK_IDENTIFIER:
case TOK_STRUCT:
case TOK_UNION:
- return parse_error(tok, "invalid combination of types");
+ parse_error(tok, "invalid combination of types");
+ return;
case TOK_DOUBLE:
- if (modifiers_sign != 0 || modifiers_length != 1)
- return parse_error(tok, "invalid combination of types");
+ if (modifiers_sign != 0 || modifiers_length != 1) {
+ parse_error(tok, "invalid combination of types");
+ return;
+ }
next_token(tok);
t1 = tok->cb->get_float_type(tok->cb, sizeof(long double),
"long double");
break;
case TOK_CHAR:
- if (modifiers_length != 0)
- return parse_error(tok, "invalid combination of types");
+ if (modifiers_length != 0) {
+ parse_error(tok, "invalid combination of types");
+ return;
+ }
modifiers_length = -2;
/* fall-through */
case TOK_INT:
@@ -468,12 +510,17 @@
break;
case TOK_IDENTIFIER:
{
+ _crx_qual_type qt2;
char identifier[1024];
- if (tok->size >= 1024)
- return parse_error(tok, "identifier name too long");
+ if (tok->size >= 1024) {
+ parse_error(tok, "identifier name too long");
+ return;
+ }
memcpy(identifier, tok->p, tok->size);
identifier[tok->size] = 0;
- t1 = tok->cb->get_user_type(tok->cb, identifier);
+ qt2 = tok->cb->get_user_type(tok->cb, identifier);
+ t1 = qt2.type;
+ result->qualifiers |= qt2.qualifiers;
break;
}
case TOK_STRUCT:
@@ -482,10 +529,14 @@
char identifier[1024];
int kind = tok->kind;
next_token(tok);
- if (tok->kind != TOK_IDENTIFIER)
- return parse_error(tok, "struct or union name expected");
- if (tok->size >= 1024)
- return parse_error(tok, "struct or union name too long");
+ if (tok->kind != TOK_IDENTIFIER) {
+ parse_error(tok, "struct or union name expected");
+ return;
+ }
+ if (tok->size >= 1024) {
+ parse_error(tok, "struct or union name too long");
+ return;
+ }
memcpy(identifier, tok->p, tok->size);
identifier[tok->size] = 0;
if (kind == TOK_STRUCT)
@@ -495,41 +546,40 @@
break;
}
default:
- return parse_error(tok, "identifier expected");
+ parse_error(tok, "identifier expected");
+ return;
}
next_token(tok);
}
-
- if (is_const) {
- t1 = tok->cb->get_const_type(tok->cb, t1);
- }
+ result->type = t1;
intptr_t *orig = tok->delay_slots;
parse_sequel(tok, TOK_END);
- return fetch_delay_slots(tok, t1, orig);
+ fetch_delay_slots(tok, result, orig);
}
-_crx_type_t *creflect_decl_parser(_crx_builder_t *cb, const char *input,
- const char **error_location)
+const char *creflect_decl_parser(_crx_builder_t *cb, const char *input,
+ _crx_qual_type *result)
{
- _crx_type_t *result;
+ _crx_qual_type qt1;
+ const char *error_location;
token_t token;
+
token.kind = TOK_START;
token.cb = cb;
token.p = input;
- token.error_location = error_location;
+ token.error_location = &error_location;
token.size = 0;
token.delay_slots = token.all_delay_slots;
next_token(&token);
- result = parse_complete(&token);
+ parse_complete(&token, &qt1);
if (token.kind == TOK_END) {
- if (error_location)
- *error_location = NULL;
- return result;
+ *result = qt1;
+ return NULL;
}
else {
parse_error(&token, "unexpected symbol");
- return NULL;
+ return error_location;
}
}
diff --git a/creflect/creflect_cdecl.h b/creflect/creflect_cdecl.h
--- a/creflect/creflect_cdecl.h
+++ b/creflect/creflect_cdecl.h
@@ -4,8 +4,8 @@
#include "creflect.h"
-_crx_type_t *creflect_decl_parser(_crx_builder_t *cb, const char *input,
- const char **error_location);
+const char *creflect_decl_parser(_crx_builder_t *cb, const char *input,
+ _crx_qual_type *result);
#endif /* _CRX_CDECL_H_ */
diff --git a/creflect/creflect_cdecl_main.c b/creflect/creflect_cdecl_main.c
--- a/creflect/creflect_cdecl_main.c
+++ b/creflect/creflect_cdecl_main.c
@@ -3,22 +3,27 @@
#include "creflect_cdecl.h"
#include "creflect_debug_print.h"
+#define ALL_QUAL (_CRX_CONST | _CRX_VOLATILE)
+
+
int main(int argc, char *argv[])
{
- _crx_type_t *t1;
+ _crx_qual_type qt1;
const char *error;
if (argc != 2) {
fprintf(stderr, "Usage: %s 'c_type_declaration'\n", argv[0]);
return 2;
}
- t1 = creflect_decl_parser(&creflect_debug_builder, argv[1], &error);
+ qt1.type = NULL;
+ qt1.qualifiers = -1;
+ error = creflect_decl_parser(&creflect_debug_builder, argv[1], &qt1);
if (error == NULL) {
- assert(t1 != NULL);
- printf("%s\n", creflect_type_text(t1));
+ assert(qt1.type != NULL);
+ assert((qt1.qualifiers & ~ALL_QUAL) == 0);
+ printf("%s\n", show_qualtype1(qt1));
}
else {
- assert(t1 == NULL);
printf("%s\n", argv[1]);
while (error > argv[1]) {
printf(" ");
diff --git a/creflect/creflect_debug_print.c b/creflect/creflect_debug_print.c
--- a/creflect/creflect_debug_print.c
+++ b/creflect/creflect_debug_print.c
@@ -10,11 +10,6 @@
};
-const char *creflect_type_text(_crx_type_t *t1)
-{
- return t1->text;
-}
-
static _crx_type_t *newtype(const char *a)
{
size_t la = strlen(a);
@@ -32,7 +27,7 @@
return t;
}
-static const char *show_qualtype2(_crx_type_t *type, int qualifiers)
+const char *show_qualtype2(_crx_type_t *type, int qualifiers)
{
size_t la = strlen(type->text);
size_t extra = 1;
@@ -52,7 +47,7 @@
return p;
}
-static const char *show_qualtype1(_crx_qual_type qualtype)
+const char *show_qualtype1(_crx_qual_type qualtype)
{
return show_qualtype2(qualtype.type, qualtype.qualifiers);
}
diff --git a/creflect/creflect_debug_print.h b/creflect/creflect_debug_print.h
--- a/creflect/creflect_debug_print.h
+++ b/creflect/creflect_debug_print.h
@@ -5,7 +5,8 @@
extern _crx_builder_t creflect_debug_builder;
-const char *creflect_type_text(_crx_type_t *);
+const char *show_qualtype2(_crx_type_t *type, int qualifiers);
+const char *show_qualtype1(_crx_qual_type qualtype);
#endif /* _CRX_DEBUG_PRINT_H_ */
diff --git a/creflect/test/test_c_decl_parser.py
b/creflect/test/test_c_decl_parser.py
--- a/creflect/test/test_c_decl_parser.py
+++ b/creflect/test/test_c_decl_parser.py
@@ -5,7 +5,7 @@
def setup_module(mod):
creflect_dir = os.path.join(os.path.dirname(__file__), '..')
executable = str(udir.join('c_decl_parser_test'))
- err = os.system("gcc -g -Werror -o '%s'"
+ err = os.system("gcc -g -Wall -Werror -o '%s'"
" '%s/creflect_cdecl.c'"
" '%s/creflect_debug_print.c'"
" '%s/creflect_cdecl_main.c'" % (
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit