shithub: scc

Download patch

ref: b17cc0af133dcaeb60d742159836cae7d0d431f7
parent: e1bc6c3a19ded30fb1affa8dceaeec7d5c0a0951
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sun Oct 31 05:47:30 EDT 2021

cc1: Disable escape() while parsing #define

When the expansion part of a #define was parsed the code
was applying the same escape rules than when it parses
normal C code. The result of this was that strings were
escaped in the definition of the macro, so any embedded
and escaped " would be expanded without the escape sequence.
This change disables escape for strings when a define is
parsed, but cc2-qbe is still passing an unescape string
to qbe.

--- a/src/cmd/cc/cc1/cc1.h
+++ b/src/cmd/cc/cc1/cc1.h
@@ -514,7 +514,7 @@
 extern char yytext[];
 extern int yytoken;
 extern unsigned short yylen;
-extern int disexpand;
+extern int disexpand, disescape;
 extern unsigned cppctx;
 extern Input *input;
 extern int lexmode, namespace;
--- a/src/cmd/cc/cc1/cpp.c
+++ b/src/cmd/cc/cc1/cpp.c
@@ -19,6 +19,7 @@
 
 unsigned cppctx;
 int disexpand;
+int disescape;
 
 void
 defdefine(char *macro, char *val, char *source)
@@ -379,6 +380,7 @@
 	if (cppoff)
 		return;
 
+	disescape = 1;
 	namespace = NS_CPP;
 	next();
 
@@ -400,6 +402,7 @@
 		goto delete;
 	if (n > 0 && !args[n-1])  /* it is a variadic function */
 		--n;
+
 	sprintf(buff, "%02d#", n);
 	if (!getdefs(args, n, buff+3, LINESIZ-3))
 		goto delete;
@@ -761,6 +764,7 @@
 		errorp("trailing characters after preprocessor directive");
 
 error:
+	disescape = 0;
 	disexpand = 0;
 	lexmode = CCMODE;
 	namespace = ns;
--- a/src/cmd/cc/cc1/lex.c
+++ b/src/cmd/cc/cc1/lex.c
@@ -543,16 +543,28 @@
 string(void)
 {
 	char *bp = yytext;
-	int c;
+	int c, esc;
 
 	*bp++ = '"';
-	for (++input->p; (c = *input->p) != '"'; ++input->p) {
+	esc = 0;
+	for (++input->p; ; ++input->p) {
+		c = *input->p;
+
+		if (c == '"' && !esc)
+			break;
+
 		if (c == '\0') {
 			errorp("missing terminating '\"' character");
 			break;
 		}
-		if (c == '\\')
-			c = escape();
+		if (c != '\\') {
+			esc = 0;
+		} else {
+			if (!disescape)
+				c = escape();
+			else
+				esc = 1;
+		}
 		if (bp == &yytext[STRINGSIZ+1]) {
 			for (++input->p; *input->p != '"'; ++input->p) {
 				if (*input->p == '\\')