scc

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

commit 52b6ff8b2915bb64d194191dfdeda6539e71fa8f
parent d07fbdefdfa111ca1c6d61104c7f69adcf54baac
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