summaryrefslogtreecommitdiff
path: root/doc/api/libstd/cli.txt
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2016-10-26 12:35:49 -0700
committerOri Bernstein <ori@eigenstate.org>2016-10-26 12:35:49 -0700
commitc3f691a1ed4011c460bd24dfffa68f43c0a3eb23 (patch)
tree1e421adacc01cf54f862e840196e2568496c3afd /doc/api/libstd/cli.txt
parenta23019f08b895626d073258d5d20fa3479d73731 (diff)
downloadmc-c3f691a1ed4011c460bd24dfffa68f43c0a3eb23.tar.gz
Clean up .gitignore.
Diffstat (limited to 'doc/api/libstd/cli.txt')
-rw-r--r--doc/api/libstd/cli.txt290
1 files changed, 290 insertions, 0 deletions
diff --git a/doc/api/libstd/cli.txt b/doc/api/libstd/cli.txt
new file mode 100644
index 0000000..b850a2a
--- /dev/null
+++ b/doc/api/libstd/cli.txt
@@ -0,0 +1,290 @@
+{
+ title: CLI Parsing
+ description: libstd: CLI Parsing
+}
+
+
+Command Line Parsing
+--------------------
+
+Command line parsing is something that nearly every program needs. This
+section of libstd provides simple command line parsing with autogenerated
+help.
+
+ pkg std =
+ type optdef = struct
+ argdesc : byte[:] /* the description for the usage */
+ minargs : std.size /* the minimum number of positional args */
+ maxargs : std.size /* the maximum number of positional args (0 = unlimited) */
+ noargs : std.bool /* whether we accept args at all */
+ opts : optdesc[:] /* the description of the options */
+ ;;
+ type optdesc = struct
+ opt : char
+ arg : byte[:]
+ desc : byte[:]
+ optional : bool
+ ;;
+ type optparsed = struct
+ opts : (char, byte[:])[:]
+ args : byte[:][:]
+ ;;
+
+ const optparse : (optargs : byte[:][:], def : optdef# -> optparsed)
+ const optusage : (prog : byte[:], def : optdef# -> void)
+ ;;
+
+Syntax
+-------
+
+A command line is composed of a list of words, known as. These arguments may
+be options that the program can act on, known as "flags". These flags may take
+up to one argument. To avoid confusing with the top level arguments, this
+document will refer to them as "values". Anything that is not a flag is a
+"positional argument", or simply an "argument".
+
+In general, the POSIX syntax for arguments is followed, with a few minor
+enhancements. Myrddin program will use the following semantics for command
+line options:
+
+ - Arguments are groupls of flags if they follow a '-'. A flag is any
+ single unicode character, potentially followed by a single value. This
+ value may be optional.
+ - Flags that take values will consume the remainder of the argument as
+ the value. If the remainder of the argument is empty, then the next
+ argument is consumed as the value. For example, `-foo` and `-f oo`
+ are equivalent.
+ - Any flags that do not take arguments may be placed before other
+ flags within the same argument. For example, `-x -y -z` is equivalent
+ to `-xyz`, as long as `-x` and `-y` have no optional arguments.
+ - The first '--' stops flags from being recognized, and treats them
+ as arguments.
+ - Flags may be supplied in any order, intermingled with arguments,
+ and repeated as many times as desired. An unrecognized flag is an
+ error, and will trigger a usage message.
+
+Types
+------
+
+The API provided for command line parsing is relatively declarative, with the
+options specified in a struct passed to the parsing.
+
+ type optdef = struct
+ argdesc : byte[:]
+ minargs : std.size
+ maxargs : std.size
+ noargs : std.bool
+ opts : optdesc[:]
+ ;;
+
+The optdef is the top level structure describing the command line arguments.
+It contains the following fields:
+
+<dl>
+ <dt><code>argdesc</code></dt>
+ <dd>
+ <p>Argdesc is a string describing the positional arguments passed to the
+ program. It doesn't change the way that the arguments are parsed, but is
+ used to document the arguments to the user.</p>
+
+ <p>In general, this should be a summary of any expected argument. If a
+ variable number of them are expected, the argument should be followed
+ with a <code>...</code>.</p>
+
+ <p>For example, a program that takes an output and a list of inputs may
+ provide the following for <code>argdesc</code>:</p>
+
+ <p><code>"output inputs..."</code></p>
+
+ <p>When the help string is generated, the output would look like:</p>
+ <p><code>myprog [-o option] output inputs...</code></p>
+ </dd>
+
+ <dt><code>minargs</code></dt>
+ <dd>
+ <p>This argument limits the minimum number of arguments that the
+ program will accept without error. If at minimum 3 inputs are needed, for
+ example, then this value should be set to 3. This does not count flags,
+ nor does it count the program name.</p>
+ <p> If set to 0, this value is ignored. This is the default value.</p>
+ </dd>
+
+ <dt><code>maxargs</code></dt>
+ <dd>
+ <p>This argument limits the maximum number of arguments that the program
+ will accept without error. If the program takes at most 1 argument, for
+ example, example, then this value should be set to 3. Just like
+ <code>maxargs</code>, this does not count flags or the program name.
+ </p>
+ <p> If set to 0, this value is ignored. This is the default value.</p>
+ </dd>
+
+ <dt><code>noargs</code></dt>
+ <dd>
+ <p>This argument causes the program to reject any arguments at all.</p>
+ </dd>
+ <dt><code>opts</code></dt>
+ <dd><p>This is a list of descriptions of the options that this program
+ takes. This list may be empty, at which point this api still provides a
+ good way of checking that no invalid arguments are passed.</p>
+ </dd>
+</dl>
+
+
+ type optdesc = struct
+ opt : char
+ arg : byte[:]
+ desc : byte[:]
+ optional : bool
+ ;;
+
+This is a description of a command line argument. It contains the following
+fields to be set by the user:
+
+<dl>
+ <dt><code>opt</code></dt>
+ <dd>
+ <p>This is a single unicode character that is used for the option
+ flag.</p>
+ </dd>
+ <dt><code>arg</code></dt>
+ <dd>
+ <p>This is a single word description of the argument. If it is not present
+ or has zero length, this indicates that the flag takes no value.
+ Otherwise, the value is mandatory, unless the <code>optional</code> flag
+ is set.</p>
+ </dd>
+ <dt><code>optional</code></dt>
+ <dd>
+ <p>This is a boolean that allows for the value <code>arg</code> to be
+ optionally omitted when using the flag. It is disabled by default.
+ </p>
+ </dd>
+ <dt><code>desc</code></dt>
+ <dd>
+ <p>This is a short sentence describing <code>arg</code>. It has no
+ semantic effect on the option parsing, and is only used in generating
+ help output for the arguments.
+ </p>
+ </dd>
+</dl>
+
+
+ type optparsed = struct
+ opts : (char, byte[:])[:]
+ args : byte[:][:]
+ prog : byte[:]
+ ;;
+
+This is the final result of parsing the options. The `opts` member contains a
+list of options in the form of `(opt, val)` pairs. The option `opt` will be
+repeated once for every time that the flag `opt` is seen within the command
+line.
+
+If there is no value passed with the flag, then the string will be the empty
+string. Otherwise, it will contain the string passed.
+
+The `args` member contains the arguments, collected for easy iteration, and the
+`prog` member contains the binary name.
+
+Functions
+----------
+
+ const optparse : (optargs : byte[:][:], def : optdef# -> optparsed)
+
+Optparse takes an array `optargs` containing the command line arguments passed
+to the program, as well as an `optdef` pointer describing the expected
+arguments, and spits out out an `optparsed`. The arguments `optargs` are
+expected to contain the program name.
+
+ const optusage : (prog : byte[:], def : optdef# -> void)
+
+
+Optusage takes the string `prog` containing the program name, and an `def`
+containing an `optdef` which describes the arguments to provide help for. It
+prints these out on `stderr` (fd 1), and returns.
+
+
+Examples:
+--------
+
+This example is a trivial one, which parses no flags, and merely
+errors if given any.
+
+ const main = {args
+ var cmd
+
+ cmd = std.optparse(args, &[
+ .argdesc = "vals",
+ ])
+ for arg in cmd.args
+ std.put("arg: {}\n", arg)
+ ;;
+ }
+
+This example shows some more advanced usage, and is extracted from
+mbld.
+
+ const main = {args
+ var dumponly
+ var targname
+ var bintarg
+ var cmd
+ var libpath
+
+ cmd = std.optparse(args, &[
+ .argdesc = "[inputs...]",
+ .opts = [
+ [.opt='t', .desc="list all available targets"],
+ [.opt='T', .arg="tag", .desc="build with specified systag"],
+ [.opt='S', .desc="generate assembly when building"],
+ [.opt='d', .desc="dump debugging information for mbld"],
+ [.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='C', .arg="mc", .desc="compile with 'mc' instead of the default compiler"],
+ [.opt='M', .arg="mu", .desc="merge uses with 'mu' instead of the default muse"],
+ ][:]
+ ])
+ targname = ""
+ tags = [][:]
+ for opt in cmd.opts
+ match opt
+ | ('t', ""): dumponly = true
+ | ('S', ""): bld.opt_genasm = true
+ | ('I', arg): bld.opt_incpaths = std.slpush(bld.opt_incpaths, arg)
+ | ('R', arg): bld.opt_instroot = arg
+ | ('T', tag): tags = std.slpush(tags, tag)
+ | ('b', arg):
+ targname = arg
+ bintarg = true
+ | ('l', arg):
+ targname = arg
+ bintarg = false
+ | ('r', arg):
+ if std.sleq(arg, "none")
+ bld.opt_runtime = ""
+ else
+ bld.opt_runtime = arg
+ ;;
+ /*
+ internal undocumented args; used by compiler suite for
+ building with an uninstalled compiler.
+ */
+ | ('d', arg): bld.opt_debug = true
+ | ('C', arg): bld.opt_mc = arg
+ | ('M', arg): bld.opt_muse = arg
+ | _: std.die("unreachable\n")
+
+ ;;
+ ;;
+
+ for arg in cmd.args
+ /* build stuff */
+ ;;
+ }
+
+
+