scc

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

commit 80d62938b01ede708d299e338cc0d531475a7efb
parent 9e531db4264918f88e229172edb0d96219ee7aa9
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon,  4 Apr 2022 20:44:57 +0200

cc1: Expand macro parameters in macro expansion

Cc1 was expanding the macro and then rescanning the expanded
string. This change makes parameters to be expanded while
the macro is expanded, which enables correct use of stringfier
and contatenation operator.

Diffstat:
Msrc/cmd/cc/cc1/cc1.h | 5+++--
Msrc/cmd/cc/cc1/cpp.c | 40++++++++++++++++++++++++++++++++--------
Msrc/cmd/cc/cc1/lex.c | 14++++++++++++--
Mtests/cc/execute/scc-tests.lst | 4++--
4 files changed, 49 insertions(+), 14 deletions(-)

diff --git a/src/cmd/cc/cc1/cc1.h b/src/cmd/cc/cc1/cc1.h @@ -31,8 +31,9 @@ enum inputtype { IMACRO = 1 << 0, /* macro expansion type */ IFILE = 1 << 1, /* input file type */ ISTDIN = 1 << 2, /* stdin type */ - IEOF = 1 << 3, /* EOF mark */ - ITYPE = IMACRO | IFILE | ISTDIN, + IPARAM = 1 << 3, /* macro param expansion */ + IEOF = 1 << 4, /* EOF mark */ + ITYPE = IMACRO | IFILE | ISTDIN | IPARAM, }; /* data type letters */ diff --git a/src/cmd/cc/cc1/cpp.c b/src/cmd/cc/cc1/cpp.c @@ -173,12 +173,38 @@ parsepars(struct macroctx *mp) return 1; } -static size_t +static int +expandarg(char *arg, char *buf, int bufsiz) +{ + int siz, n; + char *s = buf; + + addinput(filenam, NULL, xstrdup(arg), FAIL); + + for (siz = 0; next() != EOFTOK; siz += yylen) { + if (yylen > bufsiz-1) { + siz = -1; + break; + } + memcpy(buf, yytext, yylen); + bufsiz -= yylen; + buf += yylen; + } + *buf = '\0'; + + delinput(); + + DBG("MACRO parameter '%s' expanded to '%s'", arg, s); + + return siz; +} + +static int copymacro(struct macroctx *mp) { int delim, c, esc; char *s, *p, *arg, *bp; - size_t size, bufsiz; + int size, bufsiz; bp = mp->buffer; bufsiz = mp->bufsiz; @@ -243,14 +269,12 @@ copymacro(struct macroctx *mp) case '@': /* parameter substitution */ arg = mp->arglist[atoi(++s)]; - s += 2; - - size = strlen(arg); - if (size > bufsiz) + size = expandarg(arg, bp, bufsiz); + if (size < 0) goto expansion_too_long; - memcpy(bp, arg, size); bp += size; bufsiz -= size; + s += 2; break; default: if (bufsiz-- == 0) @@ -270,7 +294,7 @@ expansion_too_long: int expand(Symbol *sym) { - size_t elen; + int elen; int i; struct macroctx macro; char *arglist[NR_MACROARG]; diff --git a/src/cmd/cc/cc1/lex.c b/src/cmd/cc/cc1/lex.c @@ -82,7 +82,12 @@ addinput(char *fname, Symbol *sym, char *buffer, int fail) DBG("MACRO: %s expanded to '%s'", sym->name, buffer); hide(sym); flags = IMACRO; - } else if (fname) { + } else if (buffer) { + /* this is a macro parameter */ + fp = NULL; + DBG("MACRO parameter '%s'", buffer); + flags = IPARAM; + } else if (fname) { /* a new file */ if ((fp = fopen(fname, "r")) == NULL) { if (!fail) @@ -296,7 +301,12 @@ repeat: return 0; if (*input->p == '\0') { - if ((input->flags&ITYPE) == IMACRO) { + int t = input->flags & ITYPE; + if (t == IPARAM) { + input->flags |= IEOF; + return 0; + } + if (t == IMACRO) { wasexpand = 1; input->flags |= IEOF; } diff --git a/tests/cc/execute/scc-tests.lst b/tests/cc/execute/scc-tests.lst @@ -142,7 +142,7 @@ 0149-define.c 0150-define.c 0151-vararg.c [TODO] -0152-cat.c [TODO] +0152-cat.c 0153-cpp_string.c 0154-if_defined.c 0155-struct_compl.c [TODO] @@ -171,7 +171,7 @@ 0178-include.c 0179-sizeof.c [TODO] 0180-incomplete.c -0181-stringize.c [TODO] +0181-stringize.c 0182-voidcast.c 0183-negenum.c 0184-esc_macro.c