ref: a4548bb58265af4da12c28089a828afbecda2d0a
parent: c90d947dd33fb6163430eb47717b6c79db962221
author: Quentin Rameau <quinq@fifth.space>
date: Sat Jul 2 07:11:23 EDT 2016
[driver] keep l flags and operands ordered as given We now supports file operands at any place on the command-line (as stated by POSIX), and we process resulting objects and l-flags as the user wants.
--- a/driver/posix/scc.c
+++ b/driver/posix/scc.c
@@ -200,12 +200,6 @@
t->outfile = xstrdup(objfile);
addarg(tool, t->outfile);
break;
- case LD:
- for (i = 0; i < objtmp.n; ++i)
- addarg(tool, xstrdup(objtmp.s[i]));
- for (i = 0; i < objout.n; ++i)
- addarg(tool, xstrdup(objout.s[i]));
- break;
case STRIP:
if (cflag || kflag) {
for (i = 0; i < objout.n; ++i)
@@ -302,6 +296,7 @@
!WIFEXITED(st) || WEXITSTATUS(st) != 0) {
failure = 1;
failed = tool;
+ unlink(objfile);
free(objfile);
objfile = NULL;
}
@@ -317,12 +312,10 @@
return failed == LAST_TOOL;
}
-static void
-build(char *file)
+static int
+buildfile(char *file, int tool)
{
- int tool = toolfor(file), nexttool;
- struct items *objs = (tool == LD || cflag || kflag) ?
- &objout : &objtmp;
+ int nexttool;
for (; tool < LAST_TOOL; tool = nexttool) {
switch (tool) {
@@ -361,11 +354,42 @@
spawn(settool(inittool(tool), file, nexttool));
}
- if (validatetools())
- newitem(objs, objfile);
+ return validatetools();
}
static void
+build(struct items *chain, int link)
+{
+ int i, tool;
+
+ if (link)
+ inittool(LD);
+
+ for (i = 0; i < chain->n; ++i) {
+ if (!strcmp(chain->s[i], "-l")) {
+ if (link) {
+ addarg(LD, xstrdup(chain->s[i++]));
+ addarg(LD, xstrdup(chain->s[i]));
+ } else {
+ ++i;
+ }
+ continue;
+ }
+ tool = toolfor(chain->s[i]);
+ if (tool == LD) {
+ if (link)
+ addarg(LD, xstrdup(chain->s[i]));
+ continue;
+ }
+ if (buildfile(chain->s[i], tool)) {
+ if (link)
+ addarg(LD, xstrdup(objfile));
+ newitem((!link || kflag) ? &objout : &objtmp, objfile);
+ }
+ }
+}
+
+static void
usage(void)
{
die("usage: scc [-D def[=val]]... [-U def]... [-I dir]... "
@@ -382,6 +406,9 @@
int
main(int argc, char *argv[])
{
+ struct items linkchain = { .n = 0, };
+ int link;
+
atexit(terminate);
arch = getenv("ARCH");
@@ -421,8 +448,8 @@
kflag = 1;
break;
case 'l':
- addarg(LD, "-l");
- addarg(LD, EARGF(usage()));
+ newitem(&linkchain, "-l");
+ newitem(&linkchain, EARGF(usage()));
break;
case 'm':
arch = EARGF(usage());
@@ -442,9 +469,12 @@
break;
default:
usage();
+ } ARGOPERAND {
+ newitem(&linkchain, ARGOP());
} ARGEND
- if (Eflag && (Sflag || kflag) || argc > 1 && cflag && outfile || !argc)
+ if (Eflag && (Sflag || kflag) || linkchain.n == 0 ||
+ linkchain.n > 1 && cflag && outfile)
usage();
if (!(tmpdir = getenv("TMPDIR")) || !tmpdir[0])
@@ -451,14 +481,13 @@
tmpdir = ".";
tmpdirln = strlen(tmpdir);
- for (; *argv; ++argv)
- build(*argv);
+ build(&linkchain, (link = !(Eflag || Sflag || cflag)));
- if (Eflag || Sflag)
+ if (!(link || cflag))
return failure;
- if (!cflag && !failure) {
- spawn(settool(inittool(LD), NULL, LAST_TOOL));
+ if (link && !failure) {
+ spawn(settool(LD, NULL, LAST_TOOL));
validatetools();
}