shithub: scc

Download patch

ref: 9e00ad1d10ff45677223d724cc9bcd1fbc032f9e
parent: b5a07a8e256269a057c0143c8f61f131d038eb44
author: Roberto E. Vargas Caballero <[email protected]>
date: Sat Oct 3 05:29:55 EDT 2015

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 ''.

--- a/cc1/cpp.c
+++ b/cc1/cpp.c
@@ -154,6 +154,13 @@
 		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 @@
 	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 @@
 			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();
 	}
--- a/cc1/lex.c
+++ b/cc1/lex.c
@@ -525,6 +525,7 @@
 	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;