shithub: mc

Download patch

ref: f59920b9d0a977ddb735bf792c11ac44da46d93c
parent: 18386e4095db52452505a6855117ca80a349be60
author: Ori Bernstein <[email protected]>
date: Thu Apr 30 16:05:56 EDT 2015

Rework the option parsing api a bit.

--- a/libstd/optparse.myr
+++ b/libstd/optparse.myr
@@ -10,12 +10,24 @@
 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 @@
 		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 @@
 
 	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 @@
 	-> 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
@@ -136,4 +139,25 @@
 	ctx.argidx = i
 	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
+		-> ""
+	;;
 }
--- a/mbld/main.myr
+++ b/mbld/main.myr
@@ -19,8 +19,20 @@
 	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 @@
 		| ('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")
--- a/mbldwrap.sh
+++ b/mbldwrap.sh
@@ -6,7 +6,7 @@
 
 # this should be a bourne compatible shell script.
 if test -f mbld/mbld; then
-	./mbld/mbld $@
+	mbld $@
 else
 	./bootstrap.sh
 fi