diff options
author | Carl Worth <cworth@cworth.org> | 2010-05-11 12:30:09 -0700 |
---|---|---|
committer | Carl Worth <cworth@cworth.org> | 2010-05-11 12:30:09 -0700 |
commit | c6d5af335121f6027cc46ef9c5aa77aa4e5906ca (patch) | |
tree | 67f4d76defb0631c8c1b7828bcf50b5caa2873e4 | |
parent | 49206ef4c8adba5427e9d9b5e0dfc11345262890 (diff) |
Fix to handle chained #define directives.
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.
-rw-r--r-- | glcpp-parse.y | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/glcpp-parse.y b/glcpp-parse.y index 89dc46497f..a3a661b8be 100644 --- a/glcpp-parse.y +++ b/glcpp-parse.y @@ -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; +} + |