commit b17cc0af133dcaeb60d742159836cae7d0d431f7
parent e1bc6c3a19ded30fb1affa8dceaeec7d5c0a0951
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Sun, 31 Oct 2021 09:47:30 +0100
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.
Diffstat:
3 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/src/cmd/cc/cc1/cc1.h b/src/cmd/cc/cc1/cc1.h
@@ -514,7 +514,7 @@ extern struct yystype yylval;
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;
diff --git a/src/cmd/cc/cc1/cpp.c b/src/cmd/cc/cc1/cpp.c
@@ -19,6 +19,7 @@ static struct items dirinclude;
unsigned cppctx;
int disexpand;
+int disescape;
void
defdefine(char *macro, char *val, char *source)
@@ -379,6 +380,7 @@ define(void)
if (cppoff)
return;
+ disescape = 1;
namespace = NS_CPP;
next();
@@ -400,6 +402,7 @@ define(void)
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 @@ cpp(void)
errorp("trailing characters after preprocessor directive");
error:
+ disescape = 0;
disexpand = 0;
lexmode = CCMODE;
namespace = ns;
diff --git a/src/cmd/cc/cc1/lex.c b/src/cmd/cc/cc1/lex.c
@@ -543,16 +543,28 @@ static int
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 == '\\')