summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Worth <cworth@cworth.org>2010-05-11 12:30:09 -0700
committerCarl Worth <cworth@cworth.org>2010-05-11 12:30:09 -0700
commitc6d5af335121f6027cc46ef9c5aa77aa4e5906ca (patch)
tree67f4d76defb0631c8c1b7828bcf50b5caa2873e4
parent49206ef4c8adba5427e9d9b5e0dfc11345262890 (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.y31
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;
+}
+