shithub: scc

Download patch

ref: 7954fd897af0f78b514d09ed801cafafee4e8df5
parent: 8cd311e6ab6c87983620397b63d120957d540d3c
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Apr 5 16:44:58 EDT 2022

cc1: Add type parameter to addinput()

Addinput() had a complex logic based in the received parameters to
decide what action should be taken. This logic was hard from the
external caller and it created confusing situations, that joined
to the fact that was not clear who was the owner of the memory
made everything a bit complex. This patch solves the problem adding
a type parameter and moving ownership of memory inside addinput()
which is responsible to allocate memory now.

--- a/src/cmd/cc/cc1/cc1.h
+++ b/src/cmd/cc/cc1/cc1.h
@@ -397,6 +397,7 @@
 
 struct macro {
 	Symbol *sym;
+	char *fname;
 	char **arglist;
 	char *buffer;
 	char *def;
@@ -459,7 +460,7 @@
 extern int next(void);
 extern void expect(int tok);
 extern void discard(void);
-extern int addinput(char *, Macro *, char *, int);
+extern int addinput(int, void *, int);
 extern void delinput(void);
 extern void setsafe(int type);
 extern void setloc(char *fname, unsigned line);
@@ -532,7 +533,6 @@
 extern int onlycpp, onlyheader;
 extern unsigned curctx;
 extern Symbol *curfun, *zero, *one;
-extern char *infile;
 extern unsigned lineno;
 extern char filenam[];
 extern char *architecture;
--- a/src/cmd/cc/cc1/cpp.c
+++ b/src/cmd/cc/cc1/cpp.c
@@ -22,6 +22,7 @@
 void
 defdefine(char *name, char *val, char *source)
 {
+	char buffer[INPUTSIZ+1];
 	char *def, *fmt = "#define %s %s\n";
 	Symbol *sym = &(Symbol) {
 		.name = name,
@@ -31,12 +32,18 @@
 
 	if (!val)
 		val = "";
-	def = xmalloc(strlen(fmt) + strlen(name) + strlen(val));
-	sprintf(def, fmt, name, val);
+	if (strlen(fmt) + strlen(name) + strlen(val) > INPUTSIZ) {
+		errorp("macro definition '%s' too big", name);
+		return;
+	}
+
+	sprintf(buffer, fmt, name, val);
 	mp = newmacro(sym);
+	mp->buffer = buffer;
+	mp->fname = source;
 
 	lineno = ++ncmdlines;
-	addinput(source, mp, def, FAIL);
+	addinput(IMACRO, mp, FAIL);
 	cpp();
 	delinput();
 }
@@ -177,8 +184,7 @@
 	int siz, n;
 	char *s = buf;
 
-	addinput(filenam, NULL, xstrdup(arg), FAIL);
-
+	addinput(IPARAM, arg, FAIL);
 	for (siz = 0; next() != EOFTOK; siz += yylen+1) {
 		if (yylen > bufsiz-2) {
 			siz = -1;
@@ -336,6 +342,7 @@
 		return 0;
 
 	mp = newmacro(sym);
+	mp->fname = filenam;
 	mp->buffer = buffer;
 	mp->bufsiz = INPUTSIZ-1;
 
@@ -355,11 +362,9 @@
 	elen = copymacro(mp);
 
 substitute:
-	mp->buffer = NULL;
-	mp->bufsiz = 0;
 	buffer[elen] = '\0';
 	DBG("MACRO '%s' expanded to :'%s'", mp->sym->name, buffer);
-	addinput(filenam, mp, xstrdup(buffer), FAIL);
+	addinput(IMACRO, mp, FAIL);
 
 	return 1;
 }
@@ -533,7 +538,7 @@
 	memcpy(path+dirlen, file, filelen);
 	path[dirlen + filelen] = '\0';
 
-	return addinput(path, NULL, NULL, NOFAIL);
+	return addinput(IFILE, path, NOFAIL);
 }
 
 static char *
--- a/src/cmd/cc/cc1/lex.c
+++ b/src/cmd/cc/cc1/lex.c
@@ -65,12 +65,12 @@
 }
 
 int
-addinput(char *fname, Macro *mp, char *buffer, int fail)
+addinput(int type, void *arg, int fail)
 {
 	FILE *fp;
-	char *extp;
-	unsigned flags;
+	char *extp, *fname, *buffer, *infile;;
 	int infileln;
+	Macro *mp;
 	Symbol *sym;
 	Input *newip, *curip = input;
 
@@ -77,55 +77,72 @@
 	if (curip)
 		curip->lineno = lineno;
 
-	if (mp) {
-		/* this is a macro expansion */
+	switch (type) {
+	case IMACRO:
 		fp = NULL;
+		mp = arg;
 		sym = mp->sym;
-		DBG("MACRO: %s expanded to '%s'", sym->name, buffer);
+		fname = mp->fname;
+		buffer = mp->buffer;
 		hide(sym);
-		flags = IMACRO;
-	} else if (buffer) {
-		/* this is a macro parameter */
+		DBG("INPUT: macro %s expanded to '%s'", sym->name, buffer);
+		break;
+	case IPARAM:
 		fp = NULL;
-		DBG("MACRO parameter '%s'", buffer);
-		flags = IPARAM;
-	} else if (fname) {
-		/* a new file */
+		mp = NULL;
+		buffer = arg;
+		fname = filenam;
+		DBG("INPUT: macro parameter '%s'", buffer);
+		break;
+	case IFILE:
+		fname = arg;
+		mp = NULL;
+		buffer = NULL;
+
 		if ((fp = fopen(fname, "r")) == NULL) {
 			if (!fail)
 				return 0;
 			die("cc1: %s: %s", fname, strerror(errno));
 		}
-		flags = IFILE;
 		if (curip && onlyheader) {
+			infile = curip->filenam;
 			infileln = strlen(infile);
 			if (extp = strrchr(infile, '.'))
 				infileln -= strlen(extp);
+			/* TODO: is this C99? */
 			printf("%.*s.o: %s %s\n",
 			       infileln, infile, infile, fname);
 		}
 		lineno = 0;
-	} else {
-		/* reading from stdin */
+		DBG("INPUT: file input '%s'", fname);
+		break;
+	case ISTDIN:
 		fp = stdin;
+		mp = NULL;
 		fname = "<stdin>";
-		flags = ISTDIN;
+		buffer = NULL;
 		lineno = 0;
+		DBG("INPUT: file input 'stdin'");
+		break;
+	default:
+		abort();
 	}
 
 	if (!buffer) {
 		buffer = xmalloc(INPUTSIZ);
 		buffer[0] = '\0';
+	} else {
+		buffer = xstrdup(buffer);
 	}
 
 	newip = xmalloc(sizeof(*newip));
 	newip->next = curip;
 	newip->macro = mp;
-	newip->lineno = lineno;
 	newip->p = newip->begin = newip->line = buffer;
 	newip->filenam = NULL;
+	newip->lineno = 0;
 	newip->fp = fp;
-	newip->flags = flags;
+	newip->flags = type;
 	input = newip;
 
 	setloc(fname, lineno);
@@ -139,12 +156,22 @@
 
 	switch (ip->flags & ITYPE) {
 	case IFILE:
+		DBG("INPUT: file finished '%s'", ip->filenam);
 		if (fclose(ip->fp))
 			die("cc1: %s: %s", ip->filenam, strerror(errno));
 		break;
 	case IMACRO:
+		DBG("INPUT: macro %s finished", ip->macro->sym->name);
 		unhide(ip->macro->sym);
 		break;
+	case IPARAM:
+		DBG("INPUT: macro param finished");
+		break;
+	case ISTDIN:
+		DBG("INPUT: stdin finished");
+		break;
+	default:
+		abort();
 	}
 
 	input = ip->next;
--- a/src/cmd/cc/cc1/main.c
+++ b/src/cmd/cc/cc1/main.c
@@ -8,7 +8,7 @@
 #include <scc/scc.h>
 #include "cc1.h"
 
-char *argv0, *infile;
+char *argv0;
 
 int warnings;
 jmp_buf recover;
@@ -91,8 +91,10 @@
 	for (i = 0; i < uflags.n; ++i)
 		undefmacro(uflags.s[i]);
 
-	infile = (*argv) ? *argv : "<stdin>";
-	addinput(*argv, NULL, NULL, FAIL);
+	if (*argv)
+		addinput(IFILE, *argv, FAIL);
+	else
+		addinput(ISTDIN, NULL, FAIL);
 
 	if (onlycpp || onlyheader) {
 		outcpp();