lib/args.x
Parse program arguments against a declarative spec.
Primary API
| Function | Summary |
|---|---|
Args.from_argv | Returns the program arguments that follow argv[0] as Strings. |
Args.parse | Parses args against spec and returns a Map from each row’s name to its value. |
Args.usage | Returns usage text for spec as Args.parse reads it: a synopsis for program, then each option, then each operand that has help, in spec order. |
Args
Args.from_argv
List Args.from_argv(int argc, char **argv)
Returns the program arguments that follow argv[0] as Strings.
Source: lib/args.x:306
Args.parse
Map Args.parse(List args, List spec)
Parses args against spec and returns a Map from each row’s name
to its value.
Each row of spec is a List. A row that begins with dashed words is
an option spelled by each of them, such as -p --prefix, and named by
its first long spelling without the dashes, or else by its short one. A
row that begins with any other word is an operand of that name. The rest
of a row may hold (value placeholder), which makes an option take a
value; (default value); (help "text") for Args.usage; required;
and repeated.
A long option takes its value as --name value or --name=value, and a
short option as -n value or -nvalue; short flags may share one word.
Operands may appear between options, and -- makes every later word an
operand. Operand rows take operands in spec order, and a repeated
operand takes all that remain.
A flag’s value is the number of times it appeared. A repeated row’s
value is a List of its values. Any other option or operand holds its
last String. A row that was not given holds its default, or else zero
for a flag, an empty List for a repeated row, and a NULL String
otherwise, so every name is present and can be tested for truth.
#include "args.x"
int main(void) {
List spec = %(
(-v --verbose)
(-o --output (value file) (default "a.out"))
(-I (value dir) repeated)
(inputs repeated required));
Map options = Args.parse(%(-vI src -Ilib main.x), spec);
return options["verbose"] == 1 &&
options["output"] == "a.out" &&
options["I"].list().len() == 2 &&
options["inputs"].list().car().str() == "main.x" ? 0 : 1;
}
Raises: <bad-arg> with why and the offending option or operand
for an unknown option, a missing or unexpected value, an unexpected
operand, or a required row that was not given; and with why and the
offending spec entry for a property or word it cannot read.
Source: lib/args.x:232
Args.usage
String Args.usage(String program, List spec)
Returns usage text for spec as Args.parse reads it: a synopsis
for program, then each option, then each operand that has help, in
spec order. Help text starts at column 30, as in x2c help.
Source: lib/args.x:283
Public types
| Type | Kind | Summary |
|---|---|---|
Args | enum | The receiverless owner of Args.parse and the other argument operations. |
Args
typedef enum Args { ARGS_NAMESPACE } Args
The receiverless owner of Args.parse and the other argument
operations.
Source: lib/args.x:19
Design notes
A spec is an ordinary List with one row per option or operand, and the
parse result is a Map from each row’s name to its value, so a script
describes its command line as data and reads the answer by name. Words
are Strings throughout; converting a value to a number is the caller’s
choice. Bad input raises <bad-arg> instead of exiting, so the caller
decides whether to print Args.usage and which status to return.
Tests and examples
make verify (unittest/test-args.x).