diff options
author | Ori Bernstein <ori@eigenstate.org> | 2015-04-30 20:05:56 -0700 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2015-04-30 20:05:56 -0700 |
commit | 8fb081893f7434b4acc4fba1f2d59fd331d85879 (patch) | |
tree | e01c378087960bcfbfd08bfcaea10e861942c11c | |
parent | 4780d158d3ea0b958262d2da00b8272aca39f985 (diff) | |
download | mc-8fb081893f7434b4acc4fba1f2d59fd331d85879.tar.gz |
Rework the option parsing api a bit.
-rw-r--r-- | libstd/optparse.myr | 74 | ||||
-rw-r--r-- | mbld/main.myr | 17 | ||||
-rwxr-xr-x | mbldwrap.sh | 2 |
3 files changed, 65 insertions, 28 deletions
diff --git a/libstd/optparse.myr b/libstd/optparse.myr index 8a0d28f..63d87f7 100644 --- a/libstd/optparse.myr +++ b/libstd/optparse.myr @@ -10,12 +10,24 @@ use "types.use" use "utf.use" pkg std = + type optdef = struct + argdesc : byte[:] + opts : optdesc[:] + ;; + + type optdesc = struct + opt : char + arg : byte[:] + desc : byte[:] + needed : bool + ;; + type optctx = struct /* public variables */ args : byte[:][:] /* data passed in */ - optstr : byte[:] + optdef : optdef# optargs : byte[:][:] /* state */ @@ -25,18 +37,19 @@ pkg std = curarg : byte[:] ;; - const optinit : (optstr: byte[:], optargs : byte[:][:] -> optctx#) + const optinit : (optargs : byte[:][:], def : optdef# -> optctx#) const optnext : (ctx : optctx# -> (char, byte[:])) const optdone : (ctx : optctx# -> bool) const optfin : (ctx : optctx# -> byte[:][:]) + const optusage : (ctx : optctx# -> void) ;; -const optinit = {optstr, optargs +const optinit = {args, def var ctx ctx = alloc() - ctx.optstr= optstr - ctx.optargs =optargs + ctx.optargs = args + ctx.optdef = def ctx.optdone = false ctx.finished = false @@ -65,7 +78,12 @@ const optnext = {ctx match optinfo(ctx, c) | `None: - fatal(1, "Unexpected argument '%c'\n", c) + if c == 'h' || c == '?' + optusage(ctx) + exit(0) + else + fatal(1, "unexpected argument '%c'\n", c) + ;; | `Some (true, needed): /* -arg => '-a' 'rg' */ if ctx.curarg.len > 0 @@ -96,25 +114,10 @@ const optdone = {ctx -> ctx.curarg.len == 0 && ctx.finished } -const optinfo = {ctx, arg - var s - var c - - s = ctx.optstr - while s.len != 0 - (c, s) = striter(s) - if c == arg - (c, s) = striter(s) - /* mandatory arg */ - if c == ':' - -> `Some (true, true) - /* optional arg */ - elif c == '?' - -> `Some (true, false) - /* no arg */ - else - -> `Some (false, false) - ;; +const optinfo = {ctx, opt + for o in ctx.optdef.opts + if o.opt == opt + -> `Some (o.arg.len != 0, o.needed) ;; ;; -> `None @@ -137,3 +140,24 @@ const next = {ctx ctx.curarg = ctx.optargs[i][1:] -> true } + +const optusage = {ctx + std.put("usage: %s [-h?]", ctx.optargs[0]) + for o in ctx.optdef.opts + std.put("[-%c%s%s] ", o.opt, sep(o.arg), o.arg) + ;; + std.put("%s\n", ctx.optdef.argdesc) + std.put("\t-h\tprint this help message\n") + std.put("\t-?\tprint this help message\n") + for o in ctx.optdef.opts + std.put("\t%c%s%s\t%s\n", o.opt, sep(o.arg), o.arg, o.desc) + ;; +} + +const sep = {s + if s.len > 0 + -> " " + else + -> "" + ;; +} diff --git a/mbld/main.myr b/mbld/main.myr index 8570feb..9cc9ec4 100644 --- a/mbld/main.myr +++ b/mbld/main.myr @@ -19,8 +19,20 @@ const main = {args : byte[:][:] var bintarg var optctx var libpath + var opts - optctx = std.optinit("hb:l:s:Sr:I:C:A:M:L:R:d", args) + opts = [ + .argdesc = "[inputs...]", + .opts = [ + [.opt= 'I', .arg="inc", .desc="add 'inc' to your include path"], + [.opt= 'R', .arg="root", .desc="install into 'root'"], + [.opt= 'b', .arg="bin", .desc="compile binary named 'bin' from inputs"], + [.opt= 'l', .arg="lib", .desc="compile lib named 'lib' from inputs"], + [.opt= 'r', .arg="rt", .desc="link against runtime 'rt' instead of default"], + [.opt= 'S', .desc = "generate assembly when building"], + ][:] + ] + optctx = std.optinit(args, &opts) bld.initopts() while !std.optdone(optctx) match std.optnext(optctx) @@ -47,7 +59,8 @@ const main = {args : byte[:][:] | ('d', arg): bld.opt_debug = true | ('C', arg): bld.opt_mc = arg | ('M', arg): bld.opt_muse = arg - | _: std.die("got invalid arg\n") + | _: std.optusage(optctx) + ;; ;; if bld.opt_instroot.len > 0 && !std.sleq(bld.opt_instroot, "none") diff --git a/mbldwrap.sh b/mbldwrap.sh index 7200a01..478228a 100755 --- a/mbldwrap.sh +++ b/mbldwrap.sh @@ -6,7 +6,7 @@ export MYR_RT=../rt/_myrrt.o # this should be a bourne compatible shell script. if test -f mbld/mbld; then - ./mbld/mbld $@ + mbld $@ else ./bootstrap.sh fi |