The command-line-parser Library

The command-line-parser library provides a facility to parse the command line. It exports two modules:

  • command-line-parser - Main API module
  • option-parser-protocol - For extending the API

Quick Start

Let’s say you want to parse a command line that looks like this:

frob --name=zoo --debug -r a -r b -r c --choice=foo one two three

The “frob” command accepts a --name argument that takes a value, a boolean --debug (or --nodebug) a -r argument that may be repeated, and then at least one positional argument (here “one”, “two”, and “three”). Here’s how to create a parser for the frob command:

let parser = make(<command-line-parser>, min-positional-options: 1);
add-option(parser,
           make(<parameter-option>,
                names: #("name"),
                help: "A name"));
add-option(parser,
           make(<flag-option>,
                names: #("debug"),
                negative-names: #("nodebug"),
                default: #f,
                help: "Enable or disable debugging"));
add-option(parser,
           make(<repeated-parameter-option>,
                names: #("r"),
                variable: "RAD",  // shows up in --help output
                help: "Free radicals"));
add-option(parser,
           make(<choice-option>,
                names: #("choice"),
                choices: #("foo", "bar", "baz"),
                default: "foo"));

There are additional option classes not shown here. See the reference section for more info.

Now parse the command line:

block ()
  parse-command-line(parser, application-arguments(),
                     description: "The most excellent Frobber.");
exception (ex :: <help-requested>)
  exit-application(0);
exception (ex :: <usage-error>)
  exit-application(2);
end;

And to access the option values:

let debug? :: <boolean> = get-option-value(parser, "debug");
let name :: false-or(<string>) = get-option-value(parser, "name");
let dash-r :: <deque> = get-option-value(parser, "r");
let choice :: <string> = get-option-value(parser, "choice");
let args :: <sequence> = positional-options(parser);

Reference

The command-line-parser Module

<command-line-parser> Open Class

Encapsulates a set of command-line options.

Superclasses:

<object>

Init-Keywords:
  • provide-help-option? – A boolean specifying whether the parser should automatically add the default help option. By default, help may be requested via --help or -h. If #f, no help option will be added to the parser, and you must explicitly handle any request for help yourself.
  • help-option – A <flag-option> that will be added to the parser as the option that signals a request for help. The main purpose of this init keyword is to make it possible to use something other than --help and -h to request help. This keyword has no effect if provide-help-option? is #f.
  • min-positional-options – The minimum number of positional (unnamed) options. An <integer>, defaulting to zero. If fewer positional options than this are supplied, <usage-error> is signaled.
  • max-positional-options – The maximum number of positional (unnamed) options. An <integer>, defaulting to $maximum-integer. If more positional options than this are supplied, <usage-error> is signaled.
<command-line-parser-error> Open Class

Superclass of all errors signaled by this library.

Superclasses:<format-string-condition>, <error>
<usage-error> Open Class

Signaled when a command-line cannot be parsed.

Superclasses:<command-line-parser-error>
Discussion:This is commonly handled by calling exit-application(2) since the error has already been displayed on *standard-error*.
<help-requested> Sealed Class

Signaled when help was explicitly requested via the help option, usually --help.

Superclasses:<usage-error>
Discussion:This is commonly handled by calling exit-application(0) since the command-line synopsis has already been displayed on *standard-output*.
add-option Function

Add an option to a command-line parser.

Signature:

add-option (parser option) => ()

Parameters:
Discussion:

If any of the option names specified are already used by other options then <command-line-parser-error> is signaled.

parse-command-line Function

Parses the command line in argv and side-effects parser accordingly.

Signature:

parse-command-line (parser argv) => ()

Parameters:
Discussion:

By default, the --help flag is handled automatically by displaying the usage string, the description, and calling print-synopsis(parser, *standard-output*). Then <help-requested> is signaled and the caller should handle it, perhaps by calling exit-application(0).

If argv isn’t a valid set of options as described by the parser then <usage-error> is signaled and the caller should handle it, perhaps by calling exit-application(2).

See Quick Start for an example.

print-synopsis Open Generic function

Display a synopsis of the command line described by parser on stream.

Signature:

print-synopsis (parser stream) => ()

Parameters:
  • parser – An instance of <command-line-parser>.
  • stream – An instance of <stream>.
  • usage (#key) – An instance of <string> or #f. A brief synopsis of the overall command-line syntax. The default is #f, in which case “Usage: <application-name> [options]\n” will be displayed, where <application-name> is the result of calling locator-base(application-name()).
  • description (#key) – An instance of <string> or #f. This is displayed after usage and before the detailed list of options. This is intended to be a sentence or short paragraph.
positional-options Generic function

Returns the sequence of command line arguments that remain after all optional arguments have been consumed.

Signature:

positional-options (parser) => (args :: <sequence>)

Parameters:
Values:
  • #rest results – An instance of <object>.
option-present? Function

Returns #t if this option was supplied on the command line.

Signature:

option-present? (parser name) => (present?)

Parameters:
Values:
Discussion:

If called before parse-command-line has been called on the associated parser, this will always return #f.

get-option-value Function

Retrieves an option from an <command-line-parser> by its long name.

Signature:

get-option-value (parser long-name) => (value)

Parameters:
Values:

Option Classes

<option> Open Primary Abstract Class

Superclass of all other option types.

Superclasses:

<object>

Init-Keywords:
  • names – Names for this option; a sequence of strings. For convenience a single string may also be specified. Strings of length 1 are considered to be short options, i.e., they are prefixed by a single dash on the command line.
  • type

    The kind of value represented by this option. That is, the string passed on the command line will be coerced to this type via the parse-option-parameter generic function. Clients may implement that function for their own types to extend the parser.

    Predefined types include <integer>, subclass(<float>), subclass(<sequence>).

  • help

    A string documenting the option. Displayed in --help output. Some automatic substitutions are performed:

    1. “%default” => the string representation of the default value for the option.
    2. “%app” => the basename of the executable program.
    3. “%%” => “%”
  • variable

    A string to stand in for the option value in --help output. For example, if the option name is --database this might be “URL”, which would display as:

    --database  URL  A database URL.
    
  • default – A default value for the option that will be used if the option isn’t specified by the user.
<flag-option> Sealed Class

Defines a simple flag option, i.e., one that specifies a boolean value.

Superclasses:

<option>

Init-Keywords:
  • negative-names – Same as names, but specifies the negative forms.
Discussion:

They default to #f and exist in both positive and negative forms: “–foo” and “–no-foo”. In the case of conflicting options, the rightmost takes precedence to allow for abuse of the shell’s “alias” command.

For example, a single instance of this class could be used to specify all of the following command-line options:

-q, -v, --quiet, --verbose

<parameter-option> Sealed Class

Defines an option that requires a value be specified.

Superclasses:<option>
Discussion:If the option appears more than once, the rightmost value takes precedence. If the option never appears, these will default to #f.

Examples:

-cred, -c=red, -c = red, --color red, --color=red
<optional-parameter-option> Sealed Class

Similar to <parameter-option>, but the parameter is optional.

Superclasses:<option>
Discussion:The parameter must directly follow the option with no intervening whitespace, or follow an “=” token. The value is #f if the option never appears, #t if the option appears but the parameter does not, and the value of the parameter otherwise.

Examples:

-z, -z3, -z=3, -z = 3, --zip, --zip=3, --zip = 3

Invalid examples:

-z 3, --zip 3, --zip3
<repeated-parameter-option> Sealed Class

Similar to <parameter-option>, but may appear more than once.

Superclasses:<option>
Discussion:The final value is a deque of parameter values in the order they appeared on the command line. It defaults to the empty deque.

Examples:

-wall, -w=all, -w = all, --warnings all, --warnings=all
<choice-option> Sealed Class

Similar to <parameter-option>, but provides a restricted set of values to choose from.

Superclasses:

<parameter-option>

Init-Keywords:
  • choices – A sequence of objects (usually strings). If the value supplied on the command line isn’t one of these objects then <usage-error> is signaled. If you supply a sequence of non-string choices you will also need to supply the test: init keyword since all command-line arguments are strings and won’t compare equal with the default test, =.
  • test – A function to test whether the value supplied on the command line is the same as one of the choices. The default is =. Another commonly used value is string-equal-ic?, to ignore case in the comparison.
Discussion:

Example:

make(<choice-option>,
     names: #("foo"),
     choices: #("a", "b"),
     test: string-equal-ic?)

<keyed-option> Sealed Class

Each occurrence of this type of option defines a key => value mapping.

Superclasses:<option>
Discussion:These are a bit obscure. The best example is gcc’s -D option. The final value is a <string-table> containing each specified key, with one of the following values:
  • #t: The user specified “-Dkey”
  • a string: The user specified “-Dkey=value”

You can read this with element(table, key, default: #f) to get a handy lookup table.

Examples:

-Dkey, -Dkey=value, -D key = value, --define key = value
option-parser-definer Macro

The option-parser-protocol Module

This module exports an API that can be used to extend the existing command line parser without modifying the source in this library. It shouldn’t be common to need this. See the source code for details.