commit 5be4f0b476ad9297dc857497a4df41e1d2006bac
parent 72b2248a62c38bcc2203c12f2462cbb7491be5be
Author: Quentin Rameau <quinq@fifth.space>
Date: Sat, 2 Jul 2016 11:11:23 +0200
[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.
Diffstat:
M | driver/posix/scc.c | | | 71 | ++++++++++++++++++++++++++++++++++++++++++++++++++--------------------- |
1 file changed, 50 insertions(+), 21 deletions(-)
diff --git a/driver/posix/scc.c b/driver/posix/scc.c
@@ -200,12 +200,6 @@ settool(int tool, char *infile, int nexttool)
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 @@ validatetools(void)
!WIFEXITED(st) || WEXITSTATUS(st) != 0) {
failure = 1;
failed = tool;
+ unlink(objfile);
free(objfile);
objfile = NULL;
}
@@ -317,12 +312,10 @@ validatetools(void)
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,8 +354,39 @@ build(char *file)
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
@@ -382,6 +406,9 @@ usage(void)
int
main(int argc, char *argv[])
{
+ struct items linkchain = { .n = 0, };
+ int link;
+
atexit(terminate);
arch = getenv("ARCH");
@@ -421,8 +448,8 @@ main(int argc, char *argv[])
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,23 +469,25 @@ main(int argc, char *argv[])
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])
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();
}