shithub: scc

Download patch

ref: 36f259ae86ef2ab10ef3beeb6bcda9cdec68acfd
parent: e21b9b0779b6daa0e082d059ce6a179f4b454bef
author: Roberto E. Vargas Caballero <[email protected]>
date: Fri Jul 17 20:04:03 EDT 2015

Fix cut/paste in macro expansion

The replacement of the macro invocation by the macro expansion
was wrong, mainly because we must know left length, rigth length,
expansion length and invocation length, but we were using only
one length.

--- a/cc1/cpp.c
+++ b/cc1/cpp.c
@@ -182,22 +182,22 @@
 bool
 expand(char *begin, Symbol *sym)
 {
-	size_t len;
+	size_t total, elen, rlen, llen, ilen;
 	int n, r;
 	char *s = sym->u.s;
 	char *arglist[NR_MACROARG], arguments[INPUTSIZ], buffer[BUFSIZE];
 
-	fprintf(stderr, "macro '%s':%s\n", sym->name, sym->u.s);
 	if (sym == symfile) {
 		sprintf(buffer, "\"%s\"", input->fname);
 		goto print_subs;
 	}
 	if (sym == symline) {
-		r = snprintf(buffer, sizeof(buffer), "%s", input->line);
+		r = snprintf(buffer, sizeof(buffer), "%d", input->nline);
 		if(r == -1 || (size_t)r >= sizeof(buffer)) {
 			error("expansion of macro \"%s\" is too long", sym->name);
 			return 0;
 		}
+		fprintf(stderr, "Expansion of line '%s'\n", buffer);
 		goto print_subs;
 	}
 
@@ -211,17 +211,22 @@
 
 print_subs:
 	fprintf(stderr, "macro '%s' expanded to :'%s'\n", macroname, buffer);
-	len = strlen(buffer);
+	elen = strlen(buffer);        /* expansion lentgh */
+	rlen = strlen(input->p);      /* rigth length */
+	llen = begin - input->line;   /* left length */
+	ilen = input->p - begin;      /* invocation length */
+	total = llen + elen + rlen;
 
-	if (begin - input->line + len >= LINESIZ-1)
+	if (total >= LINESIZ)
 		error("macro expansion too long");
 
 	/* cut macro invocation */
-	memmove(begin, input->p, input->p - begin);
+	memmove(begin, begin + ilen, rlen);
 
 	/* paste macro expansion */
-	memmove(begin + len, begin, len);
-	memcpy(begin, buffer, len);
+	memmove(begin + elen, begin, rlen);
+	memcpy(begin, buffer, elen);
+	input->line[total] = '\0';
 
 	input->p = input->begin = begin;