ref: 2b9433bff2e1fead347679bcaae825d1c106bc30
dir: /libstd/optparse.myr/
use "alloc.use"
use "die.use"
use "extremum.use"
use "fmt.use"
use "option.use"
use "slpush.use"
use "syswrap.use"
use "types.use"
use "utf.use"
pkg std =
type optctx = struct
/* public variables */
args : byte[:][:]
/* data passed in */
optstr : byte[:]
optargs : 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[:]
;;
const optinit : (optstr: byte[:], optargs : byte[:][:] -> optctx#)
const optnext : (ctx : optctx# -> (char, byte[:]))
const optdone : (ctx : optctx# -> bool)
const optfin : (ctx : optctx# -> byte[:][:])
;;
const optinit = {optstr, optargs
var ctx
ctx = alloc()
ctx.optstr= optstr
ctx.optargs =optargs
ctx.optdone = false
ctx.finished = false
ctx.argidx = 0
ctx.curarg = [][:]
ctx.args = [][:]
next(ctx)
-> ctx
}
const optfin = {ctx
var a
a = ctx.args
free(ctx)
-> a
}
const optnext = {ctx
var c
var arg
(c, ctx.curarg) = striter(ctx.curarg)
match optinfo(ctx, c)
| `None:
fatal(1, "Unexpected argument %c\n", c)
| `Some (true, needed):
/* -arg => '-a' 'rg' */
if ctx.curarg.len > 0
arg = ctx.curarg
ctx.curarg = ctx.curarg[ctx.curarg.len:]
next(ctx)
/* '-a rg' => '-a' 'rg' */
elif ctx.argidx < (ctx.optargs.len - 1)
arg = ctx.optargs[ctx.argidx + 1]
ctx.argidx++
next(ctx)
elif needed
put("Expected argument for %c\n", c)
exit(1)
;;
| `Some (false, _):
arg = ""
if ctx.curarg.len != 0
next(ctx)
;;
;;
-> (c, arg)
}
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)
;;
;;
;;
-> `None
}
const next = {ctx
var i
for i = ctx.argidx + 1; i < ctx.optargs.len; i++
if !ctx.optdone && decode(ctx.optargs[i]) == '-'
goto foundopt
else
ctx.args = slpush(ctx.args, ctx.optargs[i])
;;
;;
ctx.finished = true
-> false
:foundopt
ctx.argidx = i
ctx.curarg = ctx.optargs[i][1:]
-> true
}