Parses a command line according to the specification in the clauses. The program-name-str string is used as the program name for reporting errors when the command-line is ill-formed. The argv-expr must evaluate to a vector of strings, which is typically the value of argv as defined by the MzScheme stand-alone application.
The command-line is disassembled into flags (possibly with flag-specific arguments) followed by (non-flag) arguments. Command-line strings starting with ``-'' or ``+'' are parsed as flags, but arguments to flags are never parsed as flags, and integers and decimal numbers that start with ``-'' or ``+'' are not treated as flags. Non-flag arguments in the command-line must appear after all flags and the flags' arguments. No command-line string past the first non-flag argument is parsed as a flag. The built-in -- flag signals the end of command-line flags; any command-line string past the -- flag is parsed as a non-flag argument.
For defining the command line, each clause has one of the following forms:
flag-spec is one of:
(flags variable
flags is one of:
flag-str
(flag-str
arg-formals is one of:
variable
(variable
(multi flag-spec
A multi, once-each, or once-any clause introduces
a set of command-line flag specifications. The clause tag indicates
how many times the flag can appear on the command line:
)
(once-each flag-spec
)
(once-any flag-spec
)
(help-labels string
)
(args arg-formals body-expr
)
(=> finish-proc-expr arg-help-expr help-proc-expr unknown-proc-expr)
help-str body-expr
)
(flags => handler-expr help-expr)
)
)
(variable
. variable)
A flag specification using => escapes to a more general method of specifying the handler and help strings. In this case, the handler procedure and help string list returned by handler-expr and help-expr are embedded directly in the table for parse-command-line, the procedure used to implement command-line parsing.
A help-labels clause inserts text lines into the help table of command-line flags. Each string in the clause provides a separate line of text.
An args clause can be specified as the last clause. The variables in arg-formals are bound to the leftover command-line strings in the same way that variables are bound to the formals of a lambda expression. Thus, specifying a single variable (without parentheses) collects all of the leftover arguments into a list. The effective arity of the arg-formals specification determines the number of extra command-line arguments that the user can provide, and the names of the variables in arg-formals are used in the help string. When the command-line is parsed, if the number of provided arguments cannot be matched to variables in arg-formals, the exn:user exception is raised. Otherwise, args clause's body-exprs are evaluated to handle the leftover arguments.
Instead of an args clause, the => clause can be used to escape to a more general method of handling the leftover arguments. In this case, the values of the expressions with => are passed on directly as arguments to parse-command-line. The help-proc-expr and unknown-proc-expr expressions are optional.
Example:
(command-line "compile" argv
(once-each
[("-v" "--verbose") "Compile with verbose messages"
(verbose-mode #t)]
[("-p" "--profile") "Compile with profiling"
(profiling-on #t)])
(once-any
[("-o" "--optimize-1") "Compile with optimization level 1"
(optimize-level 1)]
["--optimize-2" "Compile with optimization level 2"
(optimize-level 2)])
(multi
[("-l" "--link-flags") lf ; flag takes one argument
"Add a flag for the linker" "flag"
(link-flags (cons lf (link-flags)))])
(args (filename) ; expects one command-line argument: a filename
filename)) ; return a single filename to compile
Parses a command-line using the specification in table. For an overview of command-line parsing, see the command-line form. The table argument to this procedural form encodes the information in command-line's clauses, except for the args clause. Instead, arguments are handled by the finish-proc procedure, and help information about non-flag arguments is provided in arg-help. In addition, the finish-proc procedure receives information accumulated while parsing flags. The help-proc and unknown-proc arguments allow customization that is not possible with command-line.
When there are no more flags, the finish-proc procedure is called with a list of information accumulated for command-line flags (see below) and the remaining non-flag arguments from the command-line. The arity of the finish-proc procedure determines the number of non-flag arguments accepted and required from the command-line. For example, if finish-proc accepts either two or three arguments, then either one or two non-flag arguments must be provided on the command-line. The finish-proc procedure can have any arity (see section 4.10.1) except 0 or a list of 0s (i.e., the procedure must at least accept one or more arguments).
The arg-help argument is a list of strings identifying the expected (non-flag) command-line arguments, one for each argument. (If an arbitrary number of arguments are allowed, the last string in arg-help represents all of them.)
The help-proc procedure is called with a help string if the -h or --help flag is included on the command line. If an unknown flag is encountered, the unknown-proc procedure is called just like a flag-handling procedure (as described below); it must at least accept one argument (the unknown flag), but it may also accept more arguments. The default help-proc displays the string and exits and the default unknown-proc raises the exn:user exception.
A table is a list of flag specification sets. Each set is represented as a list of two items: a mode symbol and a list of either help strings or flag specifications. A mode symbol is one of 'once-each, 'once-any, 'multi, or 'help-labels, with the same meanings as the corresponding clause tags in command-line. For the 'help-labels mode, a list of help string is provided. For the other modes, a list of flag specifications is provided, where each specification maps a number of flags to a single handler procedure. A specification is a list of three items:
The return value from the handler is added to a list that is eventually passed to finish-proc. If the handler returns void, no value is added onto this list. For all non-void values returned by handlers, the order of the values in the list is the same as the order of the arguments on the command-line.
The following example is the same as the example for command-line, translated to the procedural form:
(parse-command-line "compile" argv
`((once-each
[("-v" "--verbose")
,(lambda (flag) (verbose-mode #t))
("Compile with verbose messages")]
[("-p" "--profile")
,(lambda (flag) (profiling-on #t))
("Compile with profiling")])
(once-any
[("-o" "--optimize-1")
,(lambda (flag) (optimize-level 1))
("Compile with optimization level 1")]
[("--optimize-2")
,(lambda (flag) (optimize-level 2))
("Compile with optimization level 2")])
(multi
[("-l" "--link-flags")
,(lambda (flag lf) (link-flags (cons lf (link-flags))))
("Add a flag for the linker" "flag")]))
(lambda (flag-accum file) file) ; return a single filename to compile
'("filename")) ; expects one command-line argument: a filename