******************************* The command-line-parser Library ******************************* .. current-library:: command-line-parser .. current-module:: command-line-parser .. contents:: Contents :local: 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 Overview ======== Here's a quick list of features to get a sense of what's available: * Various option types * :class:`` for simple ``--boolean`` flags. * :class:`` for ``--foo=bar`` options. * :class:`` options may be repeated: ``-r a -r b`` * :class:`` in which the value is optional: ``--foo`` or ``--foo bar`` * :class:`` fills a table with key/value pairs, for example: ``-Dk1=v1 -Dk2=v2`` * :class:`` the value may be chosen from a predefined set. * :class:`` to receive positional arguments. * Automatic and extensible conversion of arguments to other types. For example, an option with ``type: `` is automatically converted to integer by the parser. * Subcommands * Automatic usage and ``--help`` generation. * A convenient and readable syntax for creating the command line. * Extensibility. Add your own argument converters with :gf:`parse-option-value` or create entirely new option types. Quick Start =========== The best way to build a command line parser is with :macro:`command-line-definer`, since it is far more concise and readable than building one "by hand" with ``make(, options: ...)``. It also provides convenient methods to retrieve command-line option values rather than accessing them by name, with strings. .. note:: :macro:`command-line-definer` does not currently support subcommands. If you need subcommands you will have to build the parser by hand for now. 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`` option that takes a value, a boolean ``--debug`` (or ``--nodebug``) a repeatable ``-r`` option, a ``--choice`` option that accepts one of several values, and then at least one positional argument (here "one", "two", and "three"). Here's what that parser looks like: .. code-block:: dylan define command-line () option frob-name :: , names: #("name"), help: "Name of the frob", kind: ; option frob-debug? :: , names: #("debug"), negative-names: #("nodebug"), help: "Enable or disable debugging", kind: ; // This is the default. option frob-radicals :: , names: #("r"), kind: , variable: "RAD", // Makes --help show "-r RAD" help: "Free radicals"; option frob-choice :: , names: #("choice"), choices: #("foo", "bar", "baz"), default: "foo", help: "Your choice"; option frob-filenames :: , names: #("filenames"), kind: , repeated?: #t, help: "One or more filenames"; end command-line; Now parse the command line: .. code-block:: dylan block () let cmd = make(, help: "frob things"); parse-command-line(cmd, application-arguments()); // Now execute your main program code with cmd containing // the parsed argument values. frob(cmd); exception (err :: ) // This condition is signaled by parse-command-line and also if // your own code calls abort-command(). format-err("%s", err); exit-application(err.exit-status); end; To access the option values simply read the ```` slot values. Assuming ``cmd`` is the command parsed above: .. code-block:: dylan for (file in cmd.frob-filenames) if (cmd.frob-debug?) format-out(...); end; ...more... end; Of course, it is also possible to make a command line parser without the macro above, but doing so is much more verbose and requires accessing the option values by calling ``get-option-value(cmd, "option-name")``. Briefly, just call :drm:`make`, like this: .. code-block:: dylan let cmd = make(, help: "a most excellent program", options: list(make(, names: #("name"), help: "provide a name"), ..., make(, names: #("filenames"), repeated?: #t, help: "one or more filenames")), subcommands: list(make(, ...))); parse-command-line(cmd, application-arguments()); let filenames = get-option-value(cmd, "filenames"); ...etc... Reference ========= The command-line-parser Module ------------------------------ .. class:: :abstract: :sealed: Abstract superclass of :class:`` and :class:``. :keyword options: A sequence of :class:`