chickadee » qobischeme-ui » define-command

(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]*]]