diff options
author | Carl Worth <cworth@cworth.org> | 2010-05-20 15:18:54 -0700 |
---|---|---|
committer | Carl Worth <cworth@cworth.org> | 2010-05-20 15:18:54 -0700 |
commit | d8327e575dd20fe696f3a44ada4bd4001b15db27 (patch) | |
tree | 8dc22fd856ced3eec6436132214ad861ed1a27e2 | |
parent | c10a51ba13272dc48407b885d8684be99bba120d (diff) |
Implement (and add test) for token pasting.
This is *very* easy to implement now that macro arguments are pre-expanded.
-rw-r--r-- | glcpp-parse.y | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/glcpp-parse.y b/glcpp-parse.y index 0691619acf..aa758f7e43 100644 --- a/glcpp-parse.y +++ b/glcpp-parse.y @@ -760,6 +760,8 @@ glcpp_parser_lex (glcpp_parser_t *parser) expansion_node_t *expansion; token_node_t *replacements; int parameter_index; + const char *token; + token_class_t class; /* Who says C can't do efficient tail recursion? */ RECURSE: @@ -779,12 +781,31 @@ glcpp_parser_lex (glcpp_parser_t *parser) expansion->replacements = replacements->next; - if (strcmp (replacements->value, "(") == 0) + token = replacements->value; + + /* Implement token pasting. */ + if (replacements->next && strcmp (replacements->next->value, "##") == 0) { + token_node_t *next_node; + + next_node = replacements->next->next; + + if (next_node == NULL) { + fprintf (stderr, "Error: '##' cannot appear at the end of a macro expansion.\n"); + exit (1); + } + + token = xtalloc_asprintf (parser, "%s%s", + token, next_node->value); + expansion->replacements = next_node->next; + } + + + if (strcmp (token, "(") == 0) return '('; - else if (strcmp (replacements->value, ")") == 0) + else if (strcmp (token, ")") == 0) return ')'; - yylval.str = xtalloc_strdup (parser, replacements->value); + yylval.str = xtalloc_strdup (parser, token); /* Carefully refuse to expand any finalized identifier. */ if (replacements->type == IDENTIFIER_FINALIZED) |