 -- Module: util.cmdargs

     This module provides a wrapper for SRFI-37's args-fold.

 -- Macro: let-cmdargs args ((opt-spec ...) (operand-spec ...)) body ...

     Binds variables to command line arguments ARGS with respect to OPT-SPEC and OPERAND-SPEC, and then BODY ... are evaluated.

     ARGS is a list contains command line arguments.

     OPT-SPECs specify how to process command line options. This must be one of the following form:

     (TYPE (OPTION ...))

     (TYPE (OPTION ...) CONVERTER)

     (TYPE (OPTION ...) DEFAULT CONVERTER)

     (TYPE (OPTION ...) >> VARNAME)

     (TYPE (OPTION ...) CONVERTER >> VARNAME)

     (TYPE (OPTION ...) DEFAULT CONVERTER >> VARNAME)

          The first type of forms are for binding.

          Available TYPEs are:

            * ? for an option without an argument

            * : for an option with an optional argument. If the argument is not specified, #t is passed as the argument.

            * = for an option with a required argument

            * * for an option with a multiply specifiable required argument. The result is accumlated into a list.

          OPTIONs are the names of the options; Each of them must be character, string, or symbol (Characters and single letter strings and symbols are for short option, the others are for long option).

          The value is initialized to DEFAULT. If omitted, it become '() for * type option, or #f for the others. If a corresponding option is given, its value is converted with CONVERTER and binds the variable whose name is that of the last one of OPTIONs. CONVERTER defaults to values, and is not applied to DEFAULT. If VARNAME is specified, the value binds it alternatively.

     (TYPE (OPTIONS ...) => CALLBACK)

          The second form is useful for side effects. If the option is given, CALLBACK is called with the argument for the option.

          Available TYPEs here are ?, :, and = (no *).

     (else FORMALS BODY ...)

          When an unrecognized option is given, this form is called with four arguments: the name of the option, the argument, an operand list, and an association list represents command line options have been parsed. The keys in the alist are normalized to the variable name to be bound. FORMALS is formal parameter list for callback procedure. To continue the processing, this callback must return an operand list and an option association list. This clause must appear as the last clause of OPTSPEC. If omitted, unrecognized option simply causes an error.

     Having parsed command line options, operands bind variables in the same manner as let-optionals*. The format of OPERAND-SPEC is the same as that of let-optionals*.

          ;; tr(1)
          (let-cmdargs (cdr args)
              (((? (C) >> complement?)
                (? (c) >> complement-byte?)
                (? (d) >> delete?)
                (? (s) >> squeeze?)
                (? (u) >> unbuffered?))
               ((string1 #f)
                (string2 #f)))
            ...)

 -- Macro: parse-cmdargs args (opt-spec ...)

     Parses command line arguments ARGS and then returns an operand list and a procedure that accepts a name of option and returns corresponding value, or causes an error for unrecognized option names. OPT-SPEC has the same format as that of let-cmdargs.

          ;; gosh(1) 0.8.11
          (receive (files opt) (parse-cmdargs
          			 ((? (V) => (lambda _ (show-version) (exit 0)))
          			  (? (h) => (lambda _ (show-help) (exit 0)))
          			  (? (b) >> batch-mode?)
          			  (? (i) not >> batch-mode?)
          			  (? (q) >> read-init-file?)
          			  (* (I) >> I-files)
          			  (* (A) >> A-files)
          			  (* (u) >> u-modules)
          			  (* (l) >> l-files)
          			  (* (L) >> L-files)
          			  (* (e) >> e-exprs)
          			  (* (E) >> E-exprs)
          			  (* (p) (one-of '("time")) >> profile)
          			  (* (F) >> features)
          			  (* (f) (one-of '("case-fold"
          					   "load-verbose"
          					   "no-inline"
          					   "no-inline-constants"
          					   "no-inline-globals"
          					   "no-inline-locals"
          					   "no-source-info"
          					   "test"))
          			     >> flags)))
            (debug-print (opt 'flags))
            ...)

 -- Macro: define/cmdargs args (opt-spec ...) operand

     Parses command line arguments ARGS and define variables that have corresponding option values. The variable named OPERAND is defined to operand value. OPT-SPEC has the same format as let-cmdargs.

          ;; date (1)
          (define/cmdargs *argv*
            ((= (d date) "now")
             (= (f file))
             (= (r reference))
             (? (R rfc-2822))
             (= (rfc-3339))
             (= (s set))
             (? (u utc universal))
             (? (help)
                 => (lambda _ (show-help) (exit 0)))
             (? (version)
                 => (lambda _ (show-version) (exit 0))))
            args)

 -- Procedure: !number x
 -- Procedure: !integer x
 -- Procedure: !flonum x
 -- Procedure: !symbol x
 -- Procedure: !string x
 -- Procedure: !sexp x
 -- Procedure: one-of xs &optional converter

     Useful functions for CONVERTER. !number, etc. convert the string argument to such that type, or if the argument is #t, then return it as is. If the conversion failed, an error will be signaled.

     One-of returns a procedure which accepts one argument, and return the result value of application of CONVERTER to the argument if XS contains it, otherwise signals an error. CONVERTER defaults to values.