shithub: scc

Download patch

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