; This module implements command line handling into options and
; arguments using "--" as separator.

; The module takes effect when loaded, by defining the for symbols:
;
; Constant cmd0 is the program pathname, i.e., (main-args 0)
;
; Constant cmdopts is the arguments before "--", if any, or else an
; empty list.
;
; Constant cmdargs is the arguments after "--", if any, or else all
; arguments except cmd0.
;
; Context option is a hash table of options and their values. This is
; set up by processing the <options> variable, which must be set up
; before loading this module. The options variable is an association
; list that declares option keys with their default values, plus
; perhaps other things (e.g., short descriptions). Example:
;
;     (setf options '( ("-h" nil "Help") ("-n" "200" "Count" ) ))
;
; With the example, the command line processing would pick up any
; "-hX" and "-nY" options in <cmdopts>, then set up <option> so that
; (= (option "-h") "X") and (= (option "-n" "Y")). If "-hX" is
; ommitted, then (= (option "-h") nil), and if "-nY" is ommitted, then
; (= (option "-n") "200").


; Parse command line into program, options and arguments. Note that
; "--" is required for options.
(map constant '(cmd0 cmdopts cmdargs)
     (or (match '(? * "--" *) (main-args))
         (list (main-args 0) '() (1 (main-args)))))

; Set up option hash from the command line or with default values.
; Note: it only includes options mentioned in <options>.
(define option:option nil)
(dolist (op options)
  (let (v (ref (op 0) cmdopts (fn (x y) (starts-with y x)) true))
    (if v (option (op 0) ((length (op 0)) v))
      (op 1) (option (op 0) (op 1)))))
