From 9fad209177414598f40241f1b2f2c4034b587e2d Mon Sep 17 00:00:00 2001 From: Andrew Chambers Date: Thu, 14 Oct 2021 21:02:47 +1300 Subject: Add arg parsing. --- main.c | 49 +++++++++++++++++++++++++++++++++++++++---------- minias.h | 21 +++++++++++++++++++++ 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/main.c b/main.c index 5851844..64101d2 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,6 @@ #include "minias.h" +#include -/* Output file. */ -static FILE *outf = NULL; /* Parsed assembly */ static AsmLine *allasm = NULL; @@ -27,12 +26,12 @@ static Section *data = NULL; static Section *textrel = NULL; static Section *datarel = NULL; -char *filename = ""; -size_t curlineno = 0; +static char *infilename = ""; +static size_t curlineno = 0; void lfatal(const char *fmt, ...) { va_list ap; - fprintf(stderr, "%s:%ld: ", filename, curlineno); + fprintf(stderr, "%s:%ld: ", infilename, curlineno); va_start(ap, fmt); vwarn(fmt, ap); va_end(ap); @@ -1156,8 +1155,8 @@ static void handlerelocs(void) { } static void out(const void *buf, size_t n) { - fwrite(buf, 1, n, outf); - if (ferror(outf)) + fwrite(buf, 1, n, stdout); + if (ferror(stdout)) fatal("fwrite:"); } @@ -1197,18 +1196,48 @@ static void outelf(void) { continue; out(sections[i].data, sections[i].hdr.sh_size); } - if (fflush(outf) != 0) + if (fflush(stdout) != 0) fatal("fflush:"); } -int main(void) { +static void usage(char *argv0) { + fprintf(stderr, "usage: %s [-o OUT] [input]\n", argv0); + exit(2); +} + +int main(int argc, char *argv[]) { + + char *argv0, *outfname; + + argv0 = argv[0]; + + ARGBEGIN { + case 'o': + outfname = EARGF(usage(argv0)); + if (!freopen(outfname, "w", stdout)) + fatal("unable to open %s:", outfname); + break; + default: + usage(argv[0]); + } + ARGEND + + if (argc >= 2) + usage(argv0); + + if (argc == 1) { + infilename = argv[argc - 1]; + if (!freopen(infilename, "r", stdin)) + fatal("unable to open %s:", infilename); + } + symbols = mkhtab(256); - outf = stdout; allasm = parse(); initsections(); assemble(); fillsymtab(); handlerelocs(); outelf(); + return 0; } \ No newline at end of file diff --git a/minias.h b/minias.h index c16caf0..de6f2c8 100644 --- a/minias.h +++ b/minias.h @@ -342,6 +342,27 @@ AsmLine *parse(void); /* util.c */ +#define ARGBEGIN \ + for (;;) { \ + if (argc > 0) \ + ++argv, --argc; \ + if (argc == 0 || (*argv)[0] != '-') \ + break; \ + if ((*argv)[1] == '-' && !(*argv)[2]) { \ + ++argv, --argc; \ + break; \ + } \ + for (char *opt_ = &(*argv)[1], done_ = 0; !done_ && *opt_; ++opt_) { \ + switch (*opt_) + +#define ARGEND \ + } \ + } + +#define EARGF(x) \ + (done_ = 1, opt_[1] ? ++opt_ : argv[1] ? --argc, \ + *++argv : ((x), abort(), (char *)0)) + void vwarn(const char *fmt, va_list ap); void fatal(const char *fmt, ...); void unreachable(void); -- cgit v1.2.3