scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

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:
Mcc1/cpp.c | 25+++++++++++++++++++++----
Mcc1/lex.c | 1+
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;