small library to deal with command-line arguments
A library for parsing command-line arguments.
This library is woefully under-documented. See the examples below, and read the source code for details. Here is what a prototypical use looks like:
(defparameter +command-line-spec+ '(((#\b) :type boolean :optional t :documentation "what optional -b flag does") (("check" #\c) :type string :optional t :documentation "a --check or -c flag that takes a string") (("verbose") :type boolean :optional t :documentation "only a verbose --verbose is accepted") (("warn" "warning" #\w) :type boolean :optional t :documentation "multiple spellings possible") (("help" #\h #\?) :type boolean :optional t :documentation "--help -h -?, good practice to have") (("version" #\V) :type boolean :optional t :documentation "--version or -V, you get the idea"))) ;; for the positional arguments, see below :positional-arity and :rest-arity (defun my-program-function (arg1 arg2 rest-args &key b check verbose warn help version) (when help (show-option-help +command-line-spec+ :sort-names t) (uiop:quit)) (when version (show-version) (uiop:quit)) ...) (defun main (args) (handle-command-line ;; the spec as above, or prepared with prepare-command-line-options-specification +command-line-spec+ ;; the function to call with the arguments as parsed 'my-program-function ;; the arguments to parse :command-line args ;; the program name to use in case of an error message :name "my-program" ;; the number of mandatory positional arguments for this command (default: 0) :positional-arity 2 ;; What to do with the rest of the positional arguments. ;; T means pass the list of the rest of the command-line-arguments as one lisp argument. ;; NIL means ignore it. A keyword means pass this rest as a keyword argument. :rest-arity t))
define-command macro may be used to simultaneously define the
following three functions which are useful for defining a function
which may be invoked from the command line. For example, the
following invocation of
FOO results in:
(define-command foo (noun verb &spec +command-line-spec+ &aux scratch) "Usage: foo NOUN VERB [OPTIONS...] Do VERB to NOUN according to OPTIONS." #.(format nil "~%Built with ~a version ~a.~%" (lisp-implementation-type) (lisp-implementation-version)) (declare (verbose)) (when help (show-help-for-foo)) #|...implementation...|#)
: Prints help and option information for FOO to STDOUT and then
The docstring passed to `define-command` becomes the help text printed before options. A second docstring passed as the fourth argument to `define-command` is printed after the options.
: Similar to the
main example above this function is meant to be
used as a
:entry-point. It runs FOO on the command
line arguments by invoking
&body passed to
define-command becomes the body of the FOO
function. The positional required command line arguments become
named arguments to FOO and the command line options passed in
&spec keyword in the argument list become keyword
arguments to FOO. When supplied
:initial-value properties of
command lines become defaults of the corresponding keyword
arguments. When supplied
:action properties of command line
arguments have calls to their actions prepended to the body of the
function. Actions are only called when the keyword argument has a
The macro-expanded prototype for FOO in this example would be the following. (DEFUN FOO (NOUN VERB &KEY B CHECK VERBOSE WARN HELP VERSION &AUX SCRATCH))
For a much more elaborate use, see xcvb — unhappily, XCVB has gone mostly unmaintained since 2012, so the example might not be usefully runnable.
For a fancier take on the same general idea, see Didier Verna's CLON:
CLON has much more features than this library, but is much more complex and slighly less portable.