summaryrefslogtreecommitdiff
path: root/glcpp-parse.y
diff options
context:
space:
mode:
authorCarl Worth <cworth@cworth.org>2010-05-20 15:18:54 -0700
committerCarl Worth <cworth@cworth.org>2010-05-20 15:18:54 -0700
commitd8327e575dd20fe696f3a44ada4bd4001b15db27 (patch)
tree8dc22fd856ced3eec6436132214ad861ed1a27e2 /glcpp-parse.y
parentc10a51ba13272dc48407b885d8684be99bba120d (diff)
Implement (and add test) for token pasting.
This is *very* easy to implement now that macro arguments are pre-expanded.
Diffstat (limited to 'glcpp-parse.y')
-rw-r--r--glcpp-parse.y27
1 files changed, 24 insertions, 3 deletions
diff --git a/glcpp-parse.y b/glcpp-parse.y
index 0691619..aa758f7 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)