commit 748f54bc4e52a7ed33079759f71f2025a4de8405
parent 5b7040998d5b60b95e827094a4412973fb7db862
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Thu, 16 Jun 2016 11:43:08 +0200
Merge remote-tracking branch 'origin/master'
Diffstat:
6 files changed, 185 insertions(+), 121 deletions(-)
diff --git a/Makefile b/Makefile
@@ -10,7 +10,7 @@ ARCHS = z80 i386-sysv amd64-sysv qbe
all:
for i in $(DIRS); \
do \
- (cd $$i && $(MAKE) -e -$(MAKEFLAGS)); \
+ (cd $$i && $(MAKE) -e); \
done
cp -f cc1/cc1 bin/cc1
cp -f cc2/cc2 bin/cc2
@@ -19,14 +19,14 @@ all:
multi:
for i in $(ARCHS); \
do \
- $(MAKE) -$(MAKEFLAGS) $$i || exit; \
+ $(MAKE) $$i || exit; \
done
$(ARCHS):
for i in cc1 cc2; \
do \
(cd $$i; \
- ARCH=$@ $(MAKE) -e -$(MAKEFLAGS) clean; \
+ ARCH=$@ $(MAKE) -e clean; \
ARCH=$@ $(MAKE) -e $$i || exit); \
done
ln -f cc1/cc1 bin/cc1-$@
@@ -49,13 +49,13 @@ uninstall:
clean:
for i in $(DIRS); \
do \
- (cd $$i && $(MAKE) -$(MAKEFLAGS) $@ || exit); \
+ (cd $$i && $(MAKE) $@ || exit); \
done
multi-clean:
for i in $(ARCHS); \
do \
- ARCH=$$i $(MAKE) -e -$(MAKEFLAGS) clean || exit; \
+ ARCH=$$i $(MAKE) -e clean || exit; \
done
distclean: multi-clean
diff --git a/cc1/Makefile b/cc1/Makefile
@@ -14,7 +14,7 @@ all: cc1
$(OBJS): cc1.h ../inc/cc.h ../inc/sizes.h arch/$(ARCH)/arch.h
../lib/libcc.a:
- cd ../lib && $(MAKE) -e -$(MAKEFLAGS)
+ cd ../lib && $(MAKE) -e
cc1: $(OBJS) ../lib/libcc.a
$(CC) $(SCC_LDFLAGS) $(OBJS) ../lib/libcc.a -o $@
diff --git a/cc1/main.c b/cc1/main.c
@@ -18,11 +18,11 @@ jmp_buf recover;
static char *output;
int onlycpp;
+extern int failure;
+
static void
clean(void)
{
- extern int failure;
-
if (failure && output)
remove(output);
}
@@ -98,5 +98,5 @@ main(int argc, char *argv[])
decl();
}
- return 0;
+ return failure;
}
diff --git a/cc2/Makefile b/cc2/Makefile
@@ -21,7 +21,7 @@ main.o: error.h
$(OBJS): cc2.h ../inc/sizes.h
../lib/libcc.a:
- cd ../lib && $(MAKE) -e -$(MAKEFLAGS)
+ cd ../lib && $(MAKE) -e
cc2: $(OBJS) ../lib/libcc.a
$(CC) $(SCC_LDFLAGS) $(OBJS) ../lib/libcc.a -o $@
diff --git a/driver/posix/Makefile b/driver/posix/Makefile
@@ -10,7 +10,7 @@ all: scc
$(OBJS): ../../inc/cc.h
../../lib/libcc.a:
- cd ../../lib && $(MAKE) -e -$(MAKEFLAGS)
+ cd ../../lib && $(MAKE) -e
scc: $(OBJS) ../../lib/libcc.a
$(CC) $(SCC_LDFLAGS) $(OBJS) ../../lib/libcc.a -o $@
diff --git a/driver/posix/scc.c b/driver/posix/scc.c
@@ -14,8 +14,6 @@
#include "../../inc/arg.h"
#include "../../inc/cc.h"
-#define NARGS 64
-
enum {
CC1,
TEEIR,
@@ -25,38 +23,53 @@ enum {
TEEAS,
AS,
LD,
+ STRIP,
LAST_TOOL,
};
static struct tool {
- char cmd[PATH_MAX];
- char *args[NARGS];
- char bin[16];
- char *outfile;
- int nargs, in, out, error;
- pid_t pid;
+ char cmd[PATH_MAX];
+ char **args;
+ char bin[16];
+ char *outfile;
+ int nparams, nargs, in, out, init, error;
+ pid_t pid;
} tools[] = {
- [CC1] = { .bin = "cc1", .cmd = PREFIX "/libexec/scc/", },
- [TEEIR] = { .bin = "tee", .cmd = "tee", },
- [CC2] = { .bin = "cc2", .cmd = PREFIX "/libexec/scc/", },
- [TEEQBE] = { .bin = "tee", .cmd = "tee", },
- [QBE] = { .bin = "qbe", .cmd = "qbe", },
- [TEEAS] = { .bin = "tee", .cmd = "tee", },
- [AS] = { .bin = "as", .cmd = "as", },
- [LD] = { .bin = "gcc", .cmd = "gcc", }, /* TODO replace with ld */
+ [CC1] = { .bin = "cc1", .cmd = PREFIX "/libexec/scc/", },
+ [TEEIR] = { .bin = "tee", .cmd = "tee", },
+ [CC2] = { .bin = "cc2", .cmd = PREFIX "/libexec/scc/", },
+ [TEEQBE] = { .bin = "tee", .cmd = "tee", },
+ [QBE] = { .bin = "qbe", .cmd = "qbe", },
+ [TEEAS] = { .bin = "tee", .cmd = "tee", },
+ [AS] = { .bin = "as", .cmd = "as", },
+ [LD] = { .bin = "gcc", .cmd = "gcc", }, /* TODO use ld */
+ [STRIP] = { .bin = "strip", .cmd = "strip", },
+};
+
+struct objects {
+ char **f;
+ int n;
};
char *argv0;
static char *arch;
-static char *tmpobjs[NARGS - 2];
-static int nobjs;
-static int Eflag, Sflag, kflag;
+static struct objects objtmp, objout;
+static int Eflag, Sflag, cflag, kflag, sflag;
+
+static void
+cleanobjects(void)
+{
+ int i;
+
+ for (i = 0; i < objtmp.n; ++i)
+ unlink(objtmp.f[i]);
+}
static void
terminate(void)
{
struct tool *t;
- int tool, failed;
+ int tool, failed = -1;
for (tool = 0; tool < LAST_TOOL; ++tool) {
t = &tools[tool];
@@ -70,6 +83,38 @@ terminate(void)
}
}
+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)
+{
+ struct tool *t = &tools[tool];
+
+ if (t->nargs < 1)
+ t->nargs = 1;
+
+ t->args = newitem(t->args, t->nargs++, arg);
+}
+
+static void
+setargv0(int tool, char *arg)
+{
+ struct tool *t = &tools[tool];
+
+ if (t->nargs > 0)
+ t->args[0] = arg;
+ else
+ t->args = newitem(t->args, t->nargs++, arg);
+}
+
static int
inittool(int tool)
{
@@ -77,39 +122,43 @@ inittool(int tool)
size_t binln;
int n;
- if (!t->args[0]) {
- switch (tool) {
- case CC1:
- case CC2:
- binln = strlen(t->bin);
- if (arch) {
- n = snprintf(t->bin + binln,
- sizeof(t->bin) - binln,
- "-%s", arch);
- if (n < 0 || n >= sizeof(t->bin))
- die("scc: target tool bin too long");
- binln = strlen(t->bin);
- }
+ if (t->init)
+ return tool;
- if (strlen(t->cmd) + binln + 1 > sizeof(t->cmd))
- die("scc: target tool path too long");
- strcat(t->cmd, t->bin);
- break;
- case AS:
- t->nargs = 2;
- t->args[1] = "-o";
- break;
- case LD:
- t->nargs = 2;
- t->args[1] = "-o";
- break;
- default:
- break;
+ switch (tool) {
+ case CC1: /* FALLTHROUGH */
+ case CC2:
+ binln = strlen(t->bin);
+ if (arch) {
+ n = snprintf(t->bin + binln,
+ sizeof(t->bin) - binln,
+ "-%s", arch);
+ if (n < 0 || n >= sizeof(t->bin))
+ die("scc: target tool bin too long");
+ binln = strlen(t->bin);
}
- t->args[0] = t->bin;
+ if (strlen(t->cmd) + binln + 1 > sizeof(t->cmd))
+ die("scc: target tool path too long");
+ strcat(t->cmd, t->bin);
+ break;
+ case LD:
+ addarg(tool, "-o");
+ if (!t->outfile)
+ t->outfile = xstrdup("a.out");
+ addarg(tool, t->outfile);
+ break;
+ case AS:
+ addarg(tool, "-o");
+ break;
+ default:
+ break;
}
+ setargv0(tool, t->bin);
+ t->nparams = t->nargs;
+ t->init = 1;
+
return tool;
}
@@ -142,63 +191,64 @@ outfilename(char *path, char *ext)
return new;
}
-static void
-addarg(int tool, char *arg) {
- struct tool *t = &tools[tool];
-
- if (!(t->nargs < NARGS - 2)) /* 2: argv0, NULL terminator */
- die("scc: too many parameters given");
-
- t->args[++t->nargs] = arg;
-}
-
static int
settool(int tool, char *infile, int nexttool)
{
struct tool *t = &tools[tool];
- int fds[2];
- static int fdin;
+ int i, fds[2];
+ static int fdin = -1;
switch (tool) {
case TEEIR:
t->outfile = outfilename(infile, "ir");
- t->args[1] = t->outfile;
+ addarg(tool, t->outfile);
break;
case TEEQBE:
t->outfile = outfilename(infile, "qbe");
- t->args[1] = t->outfile;
+ addarg(tool, t->outfile);
break;
case TEEAS:
t->outfile = outfilename(infile, "as");
- t->args[1] = t->outfile;
+ addarg(tool, t->outfile);
break;
case AS:
t->outfile = outfilename(infile, "o");
- t->args[2] = t->outfile;
+ addarg(tool, t->outfile);
break;
case LD:
- if (!t->outfile)
- t->outfile = xstrdup("a.out");
- t->args[2] = t->outfile;
+ for (i = 0; i < objtmp.n; ++i)
+ addarg(tool, xstrdup(objtmp.f[i]));
+ for (i = 0; i < objout.n; ++i)
+ addarg(tool, xstrdup(objout.f[i]));
+ break;
+ case STRIP:
+ if (cflag || kflag) {
+ for (i = 0; i < objout.n; ++i)
+ addarg(tool, xstrdup(objout.f[i]));
+ }
+ if (!cflag && tools[LD].outfile)
+ addarg(tool, tools[LD].outfile);
break;
default:
break;
}
- if (fdin) {
+ if (fdin > -1) {
t->in = fdin;
- fdin = 0;
- } else {
- t->args[t->nargs + 1] = infile;
+ fdin = -1;
+ } else if (infile) {
+ addarg(tool, xstrdup(infile));
}
- if (nexttool < LAST_TOOL && tool != AS) {
+ if (nexttool < LAST_TOOL) {
if (pipe(fds))
die("scc: pipe: %s", strerror(errno));
t->out = fds[1];
fdin = fds[0];
}
+ addarg(tool, NULL);
+
return tool;
}
@@ -211,22 +261,23 @@ spawn(int tool)
case -1:
die("scc: %s: %s", t->bin, strerror(errno));
case 0:
- if (t->out)
+ if (t->out > -1)
dup2(t->out, 1);
- if (t->in)
+ if (t->in > -1)
dup2(t->in, 0);
execvp(t->cmd, t->args);
fprintf(stderr, "scc: execvp %s: %s\n",
t->cmd, strerror(errno));
_exit(1);
default:
- if (t->in)
+ if (t->in > -1)
close(t->in);
- if (t->out)
+ if (t->out > -1)
close(t->out);
break;
}
}
+
static int
toolfor(char *file)
{
@@ -252,7 +303,7 @@ static void
validatetools(void)
{
struct tool *t;
- int tool, st;
+ int i, tool, st;
for (tool = 0; tool < LAST_TOOL; ++tool) {
t = &tools[tool];
if (t->pid) {
@@ -261,38 +312,23 @@ validatetools(void)
t->error = 1;
exit(-1);
}
- free(t->outfile);
- t->outfile = NULL;
+ 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;
}
}
}
static void
-linkobjs(void)
-{
- int i;
-
- settool(inittool(LD), NULL, LAST_TOOL);
-
- for (i = 0; tmpobjs[i] && i < nobjs; ++i)
- addarg(LD, tmpobjs[i]);
-
- spawn(LD);
- validatetools();
-
- if (kflag)
- return;
-
- for (i = 0; i < nobjs; ++i)
- unlink(tmpobjs[i]);
-}
-
-static void
build(char *file)
{
- int tool = toolfor(file), nexttool, argfile = (tool == LD) ? 1 : 0;
+ int tool = toolfor(file), nexttool;
+ struct objects *objs = (tool == LD || cflag || kflag) ?
+ &objout : &objtmp;
for (; tool < LAST_TOOL; tool = nexttool) {
switch (tool) {
@@ -321,13 +357,8 @@ build(char *file)
nexttool = Sflag ? LAST_TOOL : AS;
break;
case AS:
- nexttool = LD;
+ nexttool = LAST_TOOL;
break;
- case LD: /* FALLTHROUGH */
- if (argfile)
- addarg(LD, file);
- else
- tmpobjs[nobjs++] = xstrdup(tools[AS].outfile);
default:
nexttool = LAST_TOOL;
continue;
@@ -337,12 +368,14 @@ build(char *file)
}
validatetools();
+
+ objs->f = newitem(objs->f, objs->n++, outfilename(file, "o"));
}
static void
usage(void)
{
- die("usage: %s [-E|-kS] [-w] [-m arch] [-o binout]\n"
+ die("usage: %s [-E|-kS] [-w] [-m arch] [-c] [-o binout] [-s]\n"
" [-D macro[=val]]... [-I dir]... file...", argv0);
}
@@ -366,17 +399,35 @@ main(int argc, char *argv[])
addarg(CC1, "-I");
addarg(CC1, EARGF(usage()));
break;
+ case 'L':
+ addarg(LD, "-L");
+ addarg(LD, EARGF(usage()));
+ break;
case 'S':
Sflag = 1;
break;
+ case 'U':
+ addarg(CC1, "-U");
+ addarg(CC1, EARGF(usage()));
+ break;
+ case 'c':
+ cflag = 1;
+ break;
case 'k':
kflag = 1;
break;
+ case 'l':
+ addarg(LD, "-l");
+ addarg(LD, EARGF(usage()));
+ break;
case 'm':
arch = EARGF(usage());
break;
case 'o':
- tools[LD].outfile = EARGF(usage());
+ tools[LD].outfile = xstrdup(EARGF(usage()));
+ break;
+ case 's':
+ sflag = 1;
break;
case 'w':
addarg(CC1, "-w");
@@ -398,8 +449,21 @@ main(int argc, char *argv[])
for (; *argv; ++argv)
build(*argv);
- if (!(Eflag || Sflag))
- linkobjs();
+ if (Eflag || Sflag)
+ return 0;
+
+ if (!cflag) {
+ spawn(settool(inittool(LD), NULL, LAST_TOOL));
+ validatetools();
+ }
+
+ if (sflag) {
+ spawn(settool(inittool(STRIP), NULL, LAST_TOOL));
+ validatetools();
+ }
+
+ if (!kflag)
+ cleanobjects();
return 0;
}