summaryrefslogtreecommitdiff
path: root/libstd
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-04-30 20:05:56 -0700
committerOri Bernstein <ori@eigenstate.org>2015-04-30 20:05:56 -0700
commit8fb081893f7434b4acc4fba1f2d59fd331d85879 (patch)
treee01c378087960bcfbfd08bfcaea10e861942c11c /libstd
parent4780d158d3ea0b958262d2da00b8272aca39f985 (diff)
downloadmc-8fb081893f7434b4acc4fba1f2d59fd331d85879.tar.gz
Rework the option parsing api a bit.
Diffstat (limited to 'libstd')
-rw-r--r--libstd/optparse.myr74
1 files changed, 49 insertions, 25 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
+ -> ""
+ ;;
+}