scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

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:
Msrc/cmd/cc/cc1/cc1.h | 2+-
Msrc/cmd/cc/cc1/cpp.c | 4++++
Msrc/cmd/cc/cc1/lex.c | 20++++++++++++++++----
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 == '\\')