summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-05-01 22:06:57 -0700
committerOri Bernstein <ori@eigenstate.org>2015-05-01 22:07:29 -0700
commitf80db1cc005bd118f5e6910be4fa305290832a54 (patch)
tree41af8e87714e250b4304ddf6d715b89e4aa1b5f8
parentcca9d66940c892e52559bfb2f71dcec92e4ddc46 (diff)
downloadmc-f80db1cc005bd118f5e6910be4fa305290832a54.tar.gz
More improvements in CLI option parsing.
-rw-r--r--libstd/optparse.myr67
-rw-r--r--mbld/main.myr28
2 files changed, 48 insertions, 47 deletions
diff --git a/libstd/optparse.myr b/libstd/optparse.myr
index 7bd0739..697aba5 100644
--- a/libstd/optparse.myr
+++ b/libstd/optparse.myr
@@ -12,8 +12,9 @@ use "utf.use"
pkg std =
type optdef = struct
- argdesc : byte[:]
- opts : optdesc[:]
+ argdesc : byte[:] /* the description for the usage */
+ minargs : std.size /* the minimum number of positional args */
+ opts : optdesc[:] /* the description of the options */
;;
type optdesc = struct
@@ -23,32 +24,50 @@ pkg std =
needed : bool
;;
- type optctx = struct
- /* public variables */
+ type optparsed = struct
+ opts : (char, byte[:])[:]
args : byte[:][:]
+ ;;
+
+ const optparse : (optargs : byte[:][:], def : optdef# -> optparsed)
+;;
- /* data passed in */
- optdef : optdef#
- optargs : byte[:][:]
+type optctx = struct
+ /* public variables */
+ args : byte[:][:]
- /* state */
- optdone : bool /* if we've seen '--', everything's an arg */
- finished : bool /* if we've processed all the optargs */
- argidx : size
- curarg : byte[:]
- ;;
+ /* data passed in */
+ optdef : optdef#
+ optargs : byte[:][:]
- 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)
+ /* state */
+ optdone : bool /* if we've seen '--', everything's an arg */
+ finished : bool /* if we've processed all the optargs */
+ argidx : size
+ curarg : byte[:]
;;
-const optinit = {args, def
+
+const optparse = {args, def
+ var ctx : optctx
+ var parsed
+
+ optinit(&ctx, args, def)
+ while !optdone(&ctx)
+ parsed.opts = slpush(parsed.opts, optnext(&ctx))
+ ;;
+ if ctx.args.len < def.minargs
+ put("error: expected at least %z args, got %z\n", def.minargs, ctx.args.len)
+ optusage(&ctx)
+ exit(1)
+ ;;
+ parsed.args = ctx.args
+ -> parsed
+}
+
+const optinit = {ctx, args, def
var ctx
- ctx = alloc()
ctx.optargs = args
ctx.optdef = def
@@ -63,14 +82,6 @@ const optinit = {args, def
-> ctx
}
-const optfin = {ctx
- var a
-
- a = ctx.args
- free(ctx)
- -> a
-}
-
const optnext = {ctx
var c
var arg
diff --git a/mbld/main.myr b/mbld/main.myr
index 1dea354..2a1dc33 100644
--- a/mbld/main.myr
+++ b/mbld/main.myr
@@ -17,7 +17,7 @@ const main = {args : byte[:][:]
var mt : bld.myrtarg
var targname
var bintarg
- var optctx
+ var cmd
var libpath
var opts
@@ -35,11 +35,10 @@ const main = {args : byte[:][:]
[.opt='d', .desc="dump debugging information for mbld"],
][:]
]
- optctx = std.optinit(args, &opts)
+ cmd = std.optparse(args, &opts)
bld.initopts()
- while !std.optdone(optctx)
- match std.optnext(optctx)
- | ('h', arg): usage(args[0])
+ for opt in cmd.opts
+ match opt
| ('I', arg): bld.opt_incpaths = std.slpush(bld.opt_incpaths, arg)
| ('S', _): bld.opt_genasm = true
| ('R', arg): bld.opt_instroot = arg
@@ -62,7 +61,7 @@ const main = {args : byte[:][:]
| ('d', arg): bld.opt_debug = true
| ('C', arg): bld.opt_mc = arg
| ('M', arg): bld.opt_muse = arg
- | _: std.optusage(optctx)
+ | _: std.die("unreachable\n")
;;
;;
@@ -80,7 +79,7 @@ const main = {args : byte[:][:]
if targname.len != 0
mt = [
.name=targname,
- .inputs=optctx.args,
+ .inputs=cmd.args,
.runtime=bld.opt_runtime,
.incpath=bld.opt_incpaths,
.libdeps=[][:]
@@ -95,11 +94,11 @@ const main = {args : byte[:][:]
bld.load(b)
/*bld.configure()*/
/* default: buildall */
- if optctx.args.len == 0
+ if cmd.args.len == 0
bld.buildall(b)
else
- for cmd in optctx.args
- match cmd
+ for c in cmd.args
+ match c
| "all": bld.buildall(b)
| "gen": bld.genall(b)
| "clean": bld.cleanall(b)
@@ -148,12 +147,3 @@ const findbase = {b, file
-> false
}
-const usage = {prog
- std.put("%s [-h] [-I path] [-l lib] [-b bin] inputs...\n", prog)
- std.put("\t-h\tprint this help\n")
- std.put("\t-b bin\tBuild a binary called 'bin'\n")
- std.put("\t-l lib\tBuild a library called 'name'\n")
- std.put("\t-s script\tUse the linker script 'script' when linking\n")
- std.put("\t-I path\tAdd 'path' to use search path\n")
- std.exit(0)
-}