shithub: scc

Download patch

ref: be49f37bb7908872c0b9b1bee44bfde99ba73f13
parent: 41247e13bc2d5f5a142e7524d39e494f5b391ad5
parent: f5b786d721fb88f375f21b40678c046d3732e8ca
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Jun 20 10:01:45 EDT 2016

Merge remote-tracking branch 'origin/master'

--- a/cc1/error.c
+++ b/cc1/error.c
@@ -24,10 +24,8 @@
 	putc('\n', stderr);
 
 	if (flag < 0) {
-		if (!failure) {
-			failure = 1;
+		if (!failure)
 			fclose(stdout);
-		}
 		failure = 1;
 		if (++nerrors == MAXERRNUM) {
 			fputs("too many errors\n", stderr);
--- a/cc1/main.c
+++ b/cc1/main.c
@@ -15,7 +15,8 @@
 int warnings;
 jmp_buf recover;
 
-static char *output;
+static char *base, *output;
+static struct items uflags;
 int onlycpp;
 
 extern int failure;
@@ -30,8 +31,11 @@
 static void
 usage(void)
 {
-	die("usage: %s [-E] [-D macro[=value]] ... [-I dir] [-w] [-d]"
-	    "[-o output] [input]", argv0);
+	die(!strcmp(base, "cpp") ?
+	    "usage: cpp [-wd] [-D def[=val]]... [-U def]... [-I dir]... "
+	    "[input]" :
+	    "usage: cc1 [-Ewd] [-D def[=val]]... [-U def]... [-I dir]... "
+	    "[-o output] [input]");
 }
 
 int
@@ -38,55 +42,54 @@
 main(int argc, char *argv[])
 {
 	char *base;
-	static char *uvec[NR_USWITCHES], **umacro = uvec;
+	int i;
 
 	atexit(clean);
 	icpp();
 
+	/* if run as cpp, only run the preprocessor */
+	if ((base = strrchr(argv0, '/')))
+		++base;
+	else
+		base = argv0;
+
 	ARGBEGIN {
-	case 'w':
-		warnings = 1;
+	case 'D':
+		defmacro(EARGF(usage()));
 		break;
 	case 'E':
 		onlycpp = 1;
 		break;
-	case 'D':
-		defmacro(EARGF(usage()));
+	case 'I':
+		incdir(EARGF(usage()));
 		break;
 	case 'U':
-		if (umacro == &uvec[NR_USWITCHES])
-			die("too many -U switches");
-		*umacro++ = EARGF(usage());
+		uflags.s = newitem(uflags.s, uflags.n++, EARGF(usage()));
 		break;
 	case 'd':
 		DBGON();
 		break;
-	case 'I':
-		incdir(EARGF(usage()));
-		break;
 	case 'o':
 		output = EARGF(usage());
 		break;
+	case 'w':
+		warnings = 1;
+		break;
 	default:
 		usage();
 	} ARGEND
 
-	for (umacro = uvec; *umacro; umacro++)
-		undefmacro(*umacro);
-
 	if (argc > 1)
 		usage();
 
-	/* if run as cpp, only run the preprocessor */
-	if ((base = strrchr(argv0, '/')))
-		++base;
-	else
-		base = argv0;
+	if (output && !freopen(output, "w", stdout))
+		die("error opening output: %s", strerror(errno));
+
 	if (!strcmp(base, "cpp"))
 		onlycpp = 1;
 
-	if (output && !freopen(output, "w", stdout))
-		die("error opening output: %s", strerror(errno));
+	for (i = 0; i < uflags.n; ++i)
+		undefmacro(uflags.s[i]);
 
 	ilex(*argv);
 	if (onlycpp) {
--- a/driver/posix/scc.c
+++ b/driver/posix/scc.c
@@ -32,7 +32,7 @@
 	char **args;
 	char   bin[16];
 	char  *outfile;
-	int    nparams, nargs, in, out, init, error;
+	int    nparams, nargs, in, out, init;
 	pid_t  pid;
 } tools[] = {
 	[CC1]    = { .bin = "cc1",   .cmd = PREFIX "/libexec/scc/", },
@@ -46,53 +46,24 @@
 	[STRIP]  = { .bin = "strip", .cmd = "strip", },
 };
 
-struct objects {
-	char **f;
-	int n;
-};
-
 char *argv0;
-static char *arch;
-static struct objects objtmp, objout;
+static char *arch, *outfile;
+static struct items objtmp, objout;
 static int Eflag, Sflag, cflag, kflag, sflag;
 
-static void
-cleanobjects(void)
-{
-	int i;
+extern int failure;
 
-	for (i = 0; i < objtmp.n; ++i)
-		unlink(objtmp.f[i]);
-}
-
 static void
 terminate(void)
 {
-	struct tool *t;
-	int tool, failed = -1;
+	int i;
 
-	for (tool = 0; tool < LAST_TOOL; ++tool) {
-		t = &tools[tool];
-		if (t->pid) {
-			kill(t->pid, SIGTERM);
-			if (t->error)
-				failed = tool;
-			if (tool >= failed && t->outfile)
-				unlink(t->outfile);
-		}
+	if (!kflag) {
+		for (i = 0; i < objtmp.n; ++i)
+			unlink(objtmp.s[i]);
 	}
 }
 
-static char **
-newitem(char **array, int num, char *item)
-{
-	char **ar = xrealloc(array, (num + 1) * sizeof(char **));
-
-	ar[num] = item;
-
-	return ar;
-}
-
 static void
 addarg(int tool, char *arg)
 {
@@ -144,8 +115,7 @@
 		break;
 	case LD:
 		addarg(tool, "-o");
-		if (!t->outfile)
-			t->outfile = xstrdup("a.out");
+		t->outfile = outfile ? outfile : xstrdup("a.out");
 		addarg(tool, t->outfile);
 		break;
 	case AS:
@@ -212,19 +182,19 @@
 		addarg(tool, t->outfile);
 		break;
 	case AS:
-		t->outfile = outfilename(infile, "o");
+		t->outfile = outfile ? outfile : outfilename(infile, "o");
 		addarg(tool, t->outfile);
 		break;
 	case LD:
 		for (i = 0; i < objtmp.n; ++i)
-			addarg(tool, xstrdup(objtmp.f[i]));
+			addarg(tool, xstrdup(objtmp.s[i]));
 		for (i = 0; i < objout.n; ++i)
-			addarg(tool, xstrdup(objout.f[i]));
+			addarg(tool, xstrdup(objout.s[i]));
 		break;
 	case STRIP:
 		if (cflag || kflag) {
 			for (i = 0; i < objout.n; ++i)
-				addarg(tool, xstrdup(objout.f[i]));
+				addarg(tool, xstrdup(objout.s[i]));
 		}
 		if (!cflag && tools[LD].outfile)
 			addarg(tool, tools[LD].outfile);
@@ -236,8 +206,10 @@
 	if (fdin > -1) {
 		t->in = fdin;
 		fdin = -1;
-	} else if (infile) {
-		addarg(tool, xstrdup(infile));
+	} else {
+		t->in = -1;
+		if (infile)
+			addarg(tool, xstrdup(infile));
 	}
 
 	if (nexttool < LAST_TOOL) {
@@ -245,6 +217,8 @@
 			die("scc: pipe: %s", strerror(errno));
 		t->out = fds[1];
 		fdin = fds[0];
+	} else {
+		t->out = -1;
 	}
 
 	addarg(tool, NULL);
@@ -299,28 +273,30 @@
 	die("scc: do not recognize filetype of %s", file);
 }
 
-static void
+static int
 validatetools(void)
 {
 	struct tool *t;
-	int i, tool, st;
+	int i, tool, st, failed = LAST_TOOL;
+
 	for (tool = 0; tool < LAST_TOOL; ++tool) {
 		t = &tools[tool];
 		if (t->pid) {
 			if (waitpid(t->pid, &st, 0) < 0 ||
 			    !WIFEXITED(st) || WEXITSTATUS(st) != 0) {
-				t->error = 1;
-				exit(-1);
+				failure = 1;
+				failed = tool;
 			}
+			if (tool >= failed && t->outfile)
+				unlink(t->outfile);
 			for (i = t->nparams; i < t->nargs; ++i)
 				free(t->args[i]);
 			t->nargs = t->nparams;
 			t->pid = 0;
-			t->error = 0;
-			t->in = -1;
-			t->out = -1;
 		}
 	}
+
+	return failed == LAST_TOOL;
 }
 
 static void
@@ -327,7 +303,7 @@
 build(char *file)
 {
 	int tool = toolfor(file), nexttool;
-	struct objects *objs = (tool == LD || cflag || kflag) ?
+	struct items *objs = (tool == LD || cflag || kflag) ?
 	                       &objout : &objtmp;
 
 	for (; tool < LAST_TOOL; tool = nexttool) {
@@ -367,16 +343,22 @@
 		spawn(settool(inittool(tool), file, nexttool));
 	}
 
-	validatetools();
-
-	objs->f = newitem(objs->f, objs->n++, outfilename(file, "o"));
+	if (validatetools())
+		objs->s = newitem(objs->s, objs->n++, outfilename(file, "o"));
 }
 
 static void
 usage(void)
 {
-	die("usage: %s [-E|-kS] [-w] [-m arch] [-c] [-o binout] [-s]\n"
-	    "       [-D macro[=val]]... [-I dir]... file...", argv0);
+	die("usage: scc [-D def[=val]]... [-U def]... [-I dir]... "
+	    "[-L dir]... [-l dir]...\n"
+	    "           [-ksw] [-m arch] [-E|-S] [-o outfile] file...\n"
+	    "       scc [-D def[=val]]... [-U def]... [-I dir]... "
+	    "[-L dir]... [-l dir]...\n"
+	    "           [-ksw] [-m arch] [-E|-S] -c file...\n"
+	    "       scc [-D def[=val]]... [-U def]... [-I dir]... "
+	    "[-L dir]... [-l dir]...\n"
+	    "           [-ksw] [-m arch] -c -o outfile file");
 }
 
 int
@@ -424,7 +406,7 @@
 		arch = EARGF(usage());
 		break;
 	case 'o':
-		tools[LD].outfile = xstrdup(EARGF(usage()));
+		outfile = xstrdup(EARGF(usage()));
 		break;
 	case 's':
 		sflag = 1;
@@ -440,19 +422,16 @@
 		usage();
 	} ARGEND
 
-	if (Eflag && (Sflag || kflag))
+	if (Eflag && (Sflag || kflag) || argc > 1 && cflag && outfile || !argc)
 		usage();
 
-	if (!argc)
-		die("scc: fatal error: no input file");
-
 	for (; *argv; ++argv)
 		build(*argv);
 
 	if (Eflag || Sflag)
-		return 0;
+		return failure;
 
-	if (!cflag) {
+	if (!cflag && !failure) {
 		spawn(settool(inittool(LD), NULL, LAST_TOOL));
 		validatetools();
 	}
@@ -462,8 +441,5 @@
 		validatetools();
 	}
 
-	if (!kflag)
-		cleanobjects();
-
-	return 0;
+	return failure;
 }
--- a/inc/cc.h
+++ b/inc/cc.h
@@ -1,4 +1,6 @@
 /* See LICENSE file for copyright and license details. */
+#include <sys/types.h>
+
 #ifndef NDEBUG
 extern int debug;
 #define DBG(fmt, ...) dbg(fmt, __VA_ARGS__)
@@ -12,8 +14,14 @@
 #define PREFIX "/usr/local/"
 #endif
 
+struct items {
+	char **s;
+	int n;
+};
+
 extern void die(const char *fmt, ...);
 extern void dbg(const char *fmt, ...);
+extern char **newitem(char **array, int num, char *item);
 extern void *xmalloc(size_t size);
 extern void *xcalloc(size_t nmemb, size_t size);
 extern char *xstrdup(const char *s);
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -2,7 +2,7 @@
 .POSIX:
 include ../config.mk
 
-OBJS = die.o xcalloc.o xmalloc.o xrealloc.o xstrdup.o debug.o
+OBJS = debug.o die.o newitem.o xcalloc.o xmalloc.o xrealloc.o xstrdup.o
 
 all: libcc.a
 
--- /dev/null
+++ b/lib/newitem.c
@@ -1,0 +1,12 @@
+#include "../inc/cc.h"
+
+char **
+newitem(char **array, int num, char *item)
+{
+	char **ar = xrealloc(array, (num + 1) * sizeof(char **));
+
+	ar[num] = item;
+
+	return ar;
+}
+