commit 9e00ad1d10ff45677223d724cc9bcd1fbc032f9e
parent b5a07a8e256269a057c0143c8f61f131d038eb44
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Sat, 3 Oct 2015 09:29:55 +0200
Add support for ## preprocessor operator
It is known that current implementation can have some problems
with macros which have @ or $ characters in the definition, or
in the parameters, but it is not a problem for a C program,
because such characters only can apper between "" or ''.
Diffstat:
2 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/cc1/cpp.c b/cc1/cpp.c
@@ -154,6 +154,13 @@ copymacro(char *buffer, char *s, size_t bufsiz, char *arglist[])
if (c != '@') {
if (c == '#')
continue;
+ if (c == '$') {
+ while (bp[-1] == ' ')
+ --bp, ++bufsiz;
+ while (s[1] == ' ')
+ ++s;
+ continue;
+ }
if (bufsiz-- == 0)
goto expansion_too_long;
*bp++ = c;
@@ -285,6 +292,11 @@ getdefs(Symbol *args[NR_MACROARG], int nargs, char *bp, size_t bufsiz)
size_t len;
int prevc = 0, ispar;
+ if (yytoken == '$') {
+ cpperror("'##' cannot appear at either end of a macro expansion");
+ return 0;
+ }
+
for (;;) {
ispar = 0;
if (yytoken == IDEN && nargs >= 0) {
@@ -308,10 +320,15 @@ getdefs(Symbol *args[NR_MACROARG], int nargs, char *bp, size_t bufsiz)
cpperror("too long macro");
return 0;
}
- memcpy(bp, yytext, len);
- bp += len;
- bufsiz -= len;
- if ((prevc = yytoken) != '#')
+ if (yytoken == '$') {
+ *bp++ = '$';
+ --bufsiz;
+ } else {
+ memcpy(bp, yytext, len);
+ bp += len;
+ bufsiz -= len;
+ }
+ if ((prevc = yytoken) != '#')
*bp++ = ' ';
next();
}
diff --git a/cc1/lex.c b/cc1/lex.c
@@ -525,6 +525,7 @@ operator(void)
case '*': t = follow('=', MUL_EQ, '*'); break;
case '/': t = follow('=', DIV_EQ, '/'); break;
case '!': t = follow('=', NE, '!'); break;
+ case '#': t = follow('#', '$', '#'); break;
case '-': t = minus(); break;
case '+': t = plus(); break;
case '.': t = dot(); break;