- (define-command (function-name {arguments}) {expression}+)procedure
Define a commandline application. The grammar for arguments and expressions is given below but it might be easier to look at the example instead. define-command produces error messages which print a usage line and explain why the input is incorrect.
define-command is slightly incompatible with QobiScheme's implementation. It expects arguments to be passed to it directly rather than through a list and it does not require the program name. It also fixes a bug where repeated arguments were provided in the wrong order.
{arguments} ::= {keyword}* {required}* {optional}* [{rest}] {rest} ::= (rest {defaulted-argument}) {optional} ::= (optional {defaulted-argument}) {required} ::= (required {defaulted-argument}) {keyword} ::= (any-number {defaulted-keyword}*) | (at-most-one {defaulted-keyword}*) | (at-least-one {defaulted-keyword}+) | (exactly-one {defaulted-keyword}+) {defaulted-keyword} ::= ({name} {supplied?} {defaulted-argument}*) {defaulted-argument} ::= ({variable} {doc} {type} {default}) {type} ::= integer-argument | real-argument | string-argument
{name} and {doc} are strings. {doc} is only used for documentation. There can't be a {name} "usage" or "help". -usage and -help are created automatically. All of the {variable}s and {supplied?}s must be distinct. All of the {name}s must be distinct.
Note that any-number, at-least-one, rest, and required allow nondefaulted-keywords. This is to keep backward compatibility with QobiScheme but this version encourages using {defaulted-argument}s everywhere for simplicity.
You can define new {type}s as:
(lambda (string) (if (ok? string) (string->value string) (usage {doc})))
An example that should make everything clear:
(define-command (main (exactly-one ("file" file? (file "file" string-argument "")) ("other-file" other-file? (arg1 "pathname" string-argument "") (arg2 "version" real-argument 0))) (at-most-one ("flag" flag?)) (any-number ("more" more? (more "more" string-argument ""))) (at-least-one ("alt" alt? (alt-arg "arg" string-argument ""))) (required (needed "needed" string-argument "")) (optional (maybe "maybe" string-argument "")) (optional (another-maybe "another-maybe" string-argument "")) (rest (everything "everything" string-argument))) (pp (list file? file other-file? arg1 arg2 flag? more? more alt? alt-arg needed maybe another-maybe everything))(newline))
(apply main command-line-arguments)
Without arguments, with incorrect arguments, with -usage, or -help this will print:
usage: csi [-file file|-other-file pathname version] [-flag] [-more more]* [-alt arg]+ needed [maybe [another-maybe [everything]*]]