Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

lib/args.x

Parse program arguments against a declarative spec.

Primary API

FunctionSummary
Args.from_argvReturns the program arguments that follow argv[0] as Strings.
Args.parseParses args against spec and returns a Map from each row’s name to its value.
Args.usageReturns 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

TypeKindSummary
ArgsenumThe 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).