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

Reply via email to