Command Line Argument Parsing

The :std/getopt library provides facilities for command line argument parsing.

usage

(import :std/getopt)

Interface

getopt

usage

(getopt <specifier> ...)
=> <parser>

specifier:
 (command id [help: text] <cmd-specifier>)
 <cmd-specifier> ...

cmd-specifier:
 (flag id short [long])
 (option id short [long] [help: text] [value: proc] [default: value])
 (argument id [help: text] [value: proc])
 (optional-argument id [help: text] [value: proc] [default: value])
 (rest-arguments id [help: text] [value: proc])

getopt creates a command line parser, which can be used to parse arguments with getopt-parse.

getopt-parse

usage

(getopt-parse <parser> args)
=> (values cmd-id options)
   options

getopt-parse accepts a parser and a list of string arguments and parses according to the parser specification. If it is parsing a specification with subcommands, it returns two values, the command id and a hash table with the parsed options. Otherwise it just returns the hash table with the parsed options. An exception is raised if parsing the arguments fails.

getopt-error?

usage

(getopt-error? obj)
=> boolean

If parsing fails, then a getopt-error is raised, which can be guarded with getopt-error?.

getopt-display-help

usage

(getopt-display-help <tip> program-name [port = (current-output-port)])


tip:
 <getopt-error>
 <parser>
 <command>

The procedure getopt-display-help can be used to display a help message for a getopt error according to the argument specification.

getopt-display-help-topic

usage

(getopt-display-help-topic <parser> topic program-name [port = (current-output-port)])

The procedure getopt-display-help-topic can be used to display a help page for a subcommand.

getopt?

usage

(getopt? obj)
=> boolean

Returns true if the object is a getopt parser

getopt-object?

usage

(getopt-object? obj)
=> boolean

Returns true if the object is a getopt command or command specifier.

Example

For an example, here is a command line parser for the gxpkg program:

(def (main . args)
  (def install-cmd
    (command 'install help: "install one or more packages"
             (rest-arguments 'pkg help: "package to install")))
  (def uninstall-cmd
    (command 'uninstall help: "uninstall one or more packages"
             (flag 'force "-f" help: "force uninstall even if there are orphaned dependencies")
             (rest-arguments 'pkg help: "package to uninstall")))
  (def update-cmd
    (command 'update help: "update one or more packages"
             (rest-arguments 'pkg help: "package to update; all for all packages")))
  (def link-cmd
    (command 'link help: "link a local development package"
             (argument 'pkg help: "package to link")
             (argument 'src help: "path to package source directory")))
  (def unlink-cmd
    (command 'unlink help: "unlink one or more local development packages"
             (flag 'force "-f" help: "force unlink even if there are orphaned dependencies")
             (rest-arguments 'pkg help: "package to unlink")))
  (def build-cmd
    (command 'build help: "rebuild one or more packages and their dependents"
             (rest-arguments 'pkg help: "package to build; all for all packages")))
  (def clean-cmd
    (command 'clean help: "clean compilation artefacts from one or more packages"
             (rest-arguments 'pkg help: "package to clean")))
  (def list-cmd
    (command 'list help: "list installed packages"))
  (def retag-cmd
    (command 'retag help: "retag installed packages"))
  (def help-cmd
    (command 'help help: "display help; help <command> for command help"
             (optional-argument 'command value: string->symbol)))
  (def gopt
    (getopt install-cmd
            uninstall-cmd
            update-cmd
            link-cmd
            unlink-cmd
            build-cmd
            clean-cmd
            list-cmd
            retag-cmd
            help-cmd))

  (try
   (let ((values cmd opt) (getopt-parse gopt args))
     (let-hash opt
       (case cmd
         ((install)
          (install-pkgs .pkg))
         ((uninstall)
          (uninstall-pkgs .pkg .?force))
         ((update)
          (update-pkgs .pkg))
         ((link)
          (link-pkg .pkg .src))
         ((unlink)
          (unlink-pkgs .pkg .?force))
         ((build)
          (build-pkgs .pkg))
         ((clean)
          (clean-pkgs .pkg))
         ((list)
          (list-pkgs))
         ((retag)
          (retag-pkgs))
         ((help)
          (getopt-display-help-topic gopt .?command "gxkpg")))))
   (catch (getopt-error? exn)
     (getopt-display-help exn "gxpkg" (current-error-port))
     (exit 1))
   (catch (e)
     (display-exception e (current-error-port))
     (exit 2))))