ref: 52b6ff8b2915bb64d194191dfdeda6539e71fa8f
parent: d07fbdefdfa111ca1c6d61104c7f69adcf54baac
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Apr 4 16:44:57 EDT 2022
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.
--- a/src/cmd/cc/cc1/cc1.h
+++ b/src/cmd/cc/cc1/cc1.h
@@ -31,8 +31,9 @@
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 */
--- a/src/cmd/cc/cc1/cpp.c
+++ b/src/cmd/cc/cc1/cpp.c
@@ -173,12 +173,38 @@
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 @@
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 @@
int
expand(Symbol *sym)
{
- size_t elen;
+ int elen;
int i;
struct macroctx macro;
char *arglist[NR_MACROARG];
--- a/src/cmd/cc/cc1/lex.c
+++ b/src/cmd/cc/cc1/lex.c
@@ -82,7 +82,12 @@
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 @@
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;
}
--- 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