aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-11-30 18:41:06 +0100
committerlemon <lsof@mailbox.org>2025-11-30 18:41:06 +0100
commiteb81938b26ae463e299bbf3c735cd0b2df2fae0d (patch)
treeb075ce18e788b5abccbf5759356f1131eb154939
parent8a66609df9b96ed293b7f27910993135be76b14d (diff)
driver: add -run option like tcc
convenient for quick testing
-rwxr-xr-xbootstrap.sh4
-rw-r--r--main.c100
2 files changed, 80 insertions, 24 deletions
diff --git a/bootstrap.sh b/bootstrap.sh
index 56f0477..e4acdc4 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -1,11 +1,11 @@
#!/bin/env sh
-set -euo pipefail
+set -eo pipefail
cc=gcc
cflags="-std=c11"
src=$(grep -o '\([_A-Za-z0-9/]\)\+\.c' < Makefile)
X() {
- echo "> $@" | sed -s 's/\([^ ]\+\.c \?\)\{10\}$/.../'
+ echo "> $@" | ([ x"$V" == x1 ] && cat || sed -s 's/\([^ ]\+\.c \?\)\{10\}$/.../')
$@
}
echo "== Stage 0 (compiling with $cc) =="
diff --git a/main.c b/main.c
index 5b6a2e4..05890c0 100644
--- a/main.c
+++ b/main.c
@@ -4,6 +4,7 @@
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <signal.h>
#include <unistd.h>
struct option ccopt;
@@ -78,10 +79,14 @@ withext(const char *path, const char *ext)
len = strlen(file);
else
len = oext - file - 1;
- res = alloc(&globarena, len + 1 + strlen(ext) + 1, 1);
+ res = alloc(&globarena, len + 1 + (ext ? strlen(ext) + 1 : 0), 1);
memcpy(res, file, len);
- res[len] = '.';
- memcpy(res + len + 1, ext, strlen(ext));
+ if (ext) {
+ res[len] = '.';
+ memcpy(res + len + 1, ext, strlen(ext));
+ } else {
+ res[len] = 0;
+ }
return res;
}
@@ -91,9 +96,10 @@ static struct task {
const char *targ;
const char *inf[64];
enum inft inft[64];
+ char **runargs;
vec_of(const char *) linkargs;
int ninf;
- bool verbose;
+ bool verbose, run;
} task;
static void prihelp(void);
@@ -111,6 +117,10 @@ optparse(char **args)
task.inft[task.ninf] = ft ? ft : ftdetect(arg-1);
++task.ninf;
ft = IFTauto;
+ if (task.run) {
+ task.runargs = args+1;
+ return;
+ }
continue;
}
if (!strcmp(arg, "help") || !strcmp(arg, "h") || !strcmp(arg, "-help")) {
@@ -160,6 +170,12 @@ optparse(char **args)
task.outft = OFTobj;
} else if (!strcmp(arg, "E")) {
task.outft = OFTc;
+ } else if (!strcmp(arg, "run")) {
+ task.run = 1;
+ if (task.ninf > 0) {
+ task.runargs = args+1;
+ return;
+ }
} else if (*arg == 'g') {
/* TODO debug info */
} else if (*arg == 'I') {
@@ -183,7 +199,7 @@ optparse(char **args)
if (!task.out) {
switch (task.outft) {
case OFTdll:
- case OFTexe: task.out = "a.out"; break;
+ case OFTexe: if (!task.run) task.out = "a.out"; break;
case OFTasm: task.out = withext(*task.inf, "s"); break;
case OFTobj: task.out = withext(*task.inf, "o"); break;
case OFTc: break;
@@ -230,13 +246,15 @@ tempfile(const char *path, const char *ext)
static int cc1(const char *out, const char *in);
-static const char *tempobj[arraylength(task.inf)];
+static const char *tempobj[arraylength(task.inf)], *tempout;
static void
mktemps(void) {
for (int i = 0; i < task.ninf; ++i) {
if (task.inft[i] == IFTc)
tempobj[i] = tempfile(task.inf[i], "o");
}
+ if (!task.out)
+ task.out = tempout = tempfile(task.ninf > 1 ? "run" : withext(task.inf[0], NULL), NULL);
}
static void
cleantemps(void)
@@ -244,6 +262,13 @@ cleantemps(void)
for (int i = 0; i < task.ninf; ++i) {
if (tempobj[i]) unlink(tempobj[i]);
}
+ if (tempout)
+ unlink(tempout);
+}
+static void
+sigcleantemps(int _)
+{
+ cleantemps();
}
static void
@@ -270,7 +295,10 @@ compileobjs(void)
} else if (task.inft[i] == IFTobj) {
} else assert(!"not obj");
}
- if (!ccopt.dbg.any) atexit(cleantemps);
+ if (!ccopt.dbg.any) {
+ atexit(cleantemps);
+ signal(SIGINT, sigcleantemps);
+ }
}
static int
@@ -325,21 +353,29 @@ dolink(void)
return WEXITSTATUS(wstat);
}
-static void
-prihelp(void)
+static int
+dorun(void)
{
- pfmt("Usage: antcc [options] file...\n\n"
- "Options:\n"
- " -help \tPrint this help message\n"
- " -std=<..> \tSet C standard\n"
- " -pedantic \tWarnings for strict standards compliance\n"
- " -d{pailrm} \tDebug options\n"
- " -o <file> \tPlace the output into <file>\n"
- " -v \tVerbose output\n"
- " -c \tEmit object file but do not link\n"
- " -fpie \tEmit code for position independent executable\n"
- " -fpic \tEmit position independent code\n"
- );
+ if (task.verbose) {
+ efmt("> exec %s", task.out);
+ for (char **s = task.runargs; *s; ++s)
+ efmt(" %s", *s);
+ efmt("\n");
+ }
+ pid_t p;
+ if ((p = fork()) < 0) {
+ error(NULL, "fork(): %s\n", strerror(errno));
+ exit(1);
+ } else if (p == 0) {
+ if (!execv(task.out, task.runargs - 1)) {
+ error(NULL, "execv(): %s\n", strerror(errno));
+ exit(1);
+ }
+ }
+ int wstat;
+ waitpid(p, &wstat, 0);
+ if (!WIFEXITED(wstat)) return 127;
+ return WEXITSTATUS(wstat);
}
#include <fcntl.h> /* open */
@@ -390,7 +426,10 @@ driver(void)
} else if (task.outft == OFTexe || task.outft == OFTdll) {
compileobjs();
if (ccopt.dbg.any) return 0;
- return dolink();
+ if (!task.run) return dolink();
+ int st = dolink();
+ if (st == 0) st = dorun();
+ return st;
}
assert(0);
}
@@ -429,6 +468,23 @@ sysinclpaths(void)
addinclpath(paths[i]);
}
+static void
+prihelp(void)
+{
+ pfmt("Usage: antcc [options] file...\n\n"
+ "Options:\n"
+ " -help \tPrint this help message\n"
+ " -std=<..> \tSet C standard\n"
+ " -pedantic \tWarnings for strict standards compliance\n"
+ " -d{pailrm} \tDebug options\n"
+ " -o <file> \tPlace the output into <file>\n"
+ " -v \tVerbose output\n"
+ " -c \tEmit object file but do not link\n"
+ " -fpie \tEmit code for position independent executable\n"
+ " -fpic \tEmit position independent code\n"
+ );
+}
+
int
main(int argc, char **argv)
{