Fix to handle chained #define directives.
authorCarl Worth <cworth@cworth.org>
Tue, 11 May 2010 19:30:09 +0000 (12:30 -0700)
committerCarl Worth <cworth@cworth.org>
Tue, 11 May 2010 19:30:09 +0000 (12:30 -0700)
The fix is as simple as adding a loop to continue to lookup values
in the hash table until one of the following termination conditions:

1. The token we look up has no definition

2. We get back the original symbol we started with

This second termination condition prevents infinite iteration.

glcpp-parse.y

index 89dc46497f5f09f49b3473edaf1438a0a5b3c977..a3a661b8befcb1d5c9a22abf031c309b8a18b4dc 100644 (file)
@@ -32,6 +32,9 @@
 void
 yyerror (void *scanner, const char *error);
 
+const char *
+_resolve_token (glcpp_parser_t *parser, const char *token);
+
 %}
 
 %parse-param {glcpp_parser_t *parser}
@@ -59,14 +62,7 @@ directive:   DEFINE IDENTIFIER DEFVAL {
 }
 ;
 
-token:         TOKEN {
-       char *value = hash_table_find (parser->defines, $1);
-       if (value)
-               printf ("%s", value);
-       else
-               printf ("%s", $1);
-       free ($1);
-}
+token:         TOKEN { printf ("%s", _resolve_token (parser, $1)); free ($1); }
 ;
 
 %%
@@ -97,3 +93,22 @@ glcpp_parser_fini (glcpp_parser_t *parser)
        yylex_destroy (parser->scanner);
        hash_table_dtor (parser->defines);
 }
+
+const char *
+_resolve_token (glcpp_parser_t *parser, const char *token)
+{
+       const char *orig = token;
+       const char *replacement;
+
+       while (1) {
+               replacement = hash_table_find (parser->defines, token);
+               if (replacement == NULL)
+                       break;
+               token = replacement;
+               if (strcmp (token, orig) == 0)
+                       break;
+       }
+
+       return token;
+}
+