commit 9e00ad1d10ff45677223d724cc9bcd1fbc032f9e
Author:     Roberto E. Vargas Caballero <[email protected]>
AuthorDate: Sat Oct 3 09:29:55 2015 +0200
Commit:     Roberto E. Vargas Caballero <[email protected]>
CommitDate: Sat Oct 3 09:29:55 2015 +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 ''.

diff --git a/cc1/cpp.c b/cc1/cpp.c
index d7939a8..311b1bb 100644
--- 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
index 6bfbc03..2cd8c58 100644
--- 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;

Reply via email to