scc

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

commit 47b81d4c6f906155f23054757a85c829aff80c40
parent a64383b5e55ca6d2da9cf4039bd8926222a7d9b9
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date:   Thu, 28 May 2026 10:19:01 +0200

cc1: Don't add addional spaces in macro arguments

Cpp was adding spajce between tokens composing a macro argument.
This space was needed to avoid undesired concatenations between
adjancents tokens, like for example identifiers, but it was breaking
some cases of the stringize operator because it wan adding spaces
in the string where they were not in the macro argument. The scc
tokenizer does not preserves spaces, and this makes a bit difficult
to know when to insert spaces for this case, so the simpler solution
is just to add a new variable that stores the last space seen in
the tokenizer, and lets the caller to manage it as desired because
the majority of the code doesn't matter about it.

Diffstat:
Msrc/cmd/scc-cc/cc1/cc1.h | 2+-
Msrc/cmd/scc-cc/cc1/cpp.c | 15++++++++++++---
Msrc/cmd/scc-cc/cc1/lex.c | 10+++++-----
Mtests/cc/execute/scc-tests.lst | 2+-
4 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/src/cmd/scc-cc/cc1/cc1.h b/src/cmd/scc-cc/cc1/cc1.h @@ -553,7 +553,7 @@ Arch *i386_sysv(void); */ extern struct yystype yylval; extern char yytext[]; -extern int yytoken; +extern int yytoken, yyspace; extern unsigned short yylen; extern int disexpand, disstring; extern unsigned cppctx; diff --git a/src/cmd/scc-cc/cc1/cpp.c b/src/cmd/scc-cc/cc1/cpp.c @@ -362,15 +362,24 @@ expandarg(char *arg, char *def, char *curdef, char *buf, int bufsiz) } } else { addinput(IPARAM, arg, FAIL); - for (siz = 0; next() != EOFTOK; siz += yylen+1) { + for (siz = 0; ; siz += yylen) { + yyspace = '\0'; + if (next() == EOFTOK) + break; if (yylen > bufsiz-2) { siz = -1; break; } + + if (yyspace) { + *buf++ = ' '; + bufsiz--; + siz++; + } + memcpy(buf, yytext, yylen); - bufsiz -= yylen + 1; + bufsiz -= yylen; buf += yylen; - *buf++ = ' '; } delinput(); diff --git a/src/cmd/scc-cc/cc1/lex.c b/src/cmd/scc-cc/cc1/lex.c @@ -20,7 +20,7 @@ int yytoken; struct yystype yylval; char yytext[STRINGSIZ+3]; unsigned short yylen; -int lexmode = CCMODE; +int yyspace, lexmode = CCMODE; unsigned lineno; char filenam[FILENAME_MAX]; @@ -1024,19 +1024,19 @@ skipspaces(void) for (;;) { switch (c = *input->p) { - case '\n': - if (lexmode == CPPMODE) - goto return_byte; - ++input->p; case '\0': if (!moreinput()) return EOF; break; + case '\n': case ' ': case '\t': case '\v': case '\r': case '\f': + yyspace = c; + if (c == '\n' && lexmode == CPPMODE) + goto return_byte; ++input->p; break; default: diff --git a/tests/cc/execute/scc-tests.lst b/tests/cc/execute/scc-tests.lst @@ -190,7 +190,7 @@ 0197-cppcomment.c 0198-nullcpp.c 0199-voidpcast.c -0200-cpp.c [TODO] +0200-cpp.c 0201-cpp.c 0202-variadic.c 0203-comment.c