home: hub: zuo

Download patch

ref: a07f857f662ac27dab2a88261b3439552335311e
parent: e9403e777a6fddcd5b496e57d739327eb76c7890
author: Matthew Flatt <mflatt@racket-lang.org>
date: Tue Nov 15 03:11:56 CST 2022

zuo/cmdline: add a `:preamble` option to `command-line`

Closes #10

--- a/lib/zuo/cmdline.zuo
+++ b/lib/zuo/cmdline.zuo
@@ -112,6 +112,7 @@
              (hash-ref accum 'flags-expr)
              (hash-ref accum 'finish (quote-syntax (lambda () (lambda (cmd) cmd))))
              (hash-ref accum 'finish-spec (quote-syntax '(() ())))
+             (hash-ref accum 'preamble #f)
              (hash-ref accum 'usage #f)
              (cons (quote-syntax list) (reverse (hash-ref accum 'help '()))))]
       [(identifier? (car stx))
@@ -150,6 +151,11 @@
             (syntax-error "command-line: bad syntax at `:usage`" all-stx))
           (check-already accum 'usage)
           (loop (cddr stx) #f #f (hash-set accum 'usage (list (quote-syntax check-usage) (cadr stx))))]
+         [(eq? head ':preamble)
+          (unless (pair? (cdr stx))
+            (syntax-error "command-line: bad syntax at `:preamble`" all-stx))
+          (check-already accum 'preamble)
+          (loop (cddr stx) #f #f (hash-set accum 'preamble (list (quote-syntax check-preamble) (cadr stx))))]
          [else (expected-mode stx)])]
       [(not mode)
        (expected-mode stx)]
@@ -170,3 +176,8 @@
   (unless (string? usage)
     (error "command-line: result for `:usage` is not a string" usage))
   usage)
+
+(define (check-preamble preamble)
+  (unless (string? preamble)
+    (error "command-line: result for `:preamble` is not a string" preamble))
+  preamble)
--- a/lib/zuo/private/cmdline-run.zuo
+++ b/lib/zuo/private/cmdline-run.zuo
@@ -3,7 +3,7 @@
 (provide run-cmdline
          flag-parser)
 
-(define (run-cmdline program cmd args flags finish-handler finish-spec usage help-specs)
+(define (run-cmdline program cmd args flags finish-handler finish-spec preamble usage help-specs)
 
   (define (finish cmd args)
     (define expected (+ (length (car finish-spec))
@@ -40,7 +40,7 @@
                                     (loop (append pend-flags (list arg)) args saw cmd))]
            [(or (string=? arg "--help")
                 (string=? arg "-h"))
-            (show-help program finish-spec usage help-specs flags)
+            (show-help program finish-spec preamble usage help-specs flags)
             (exit 0)]
            [(and (> (string-length arg) 2)
                  (= (string-ref arg 0) (char "-"))
@@ -99,7 +99,9 @@
       (handler cmd)
       (error (~a " did not produce a procedure to receive accumulated state"))))
 
-(define (show-help program finish-spec usage help-specs flags)
+(define (show-help program finish-spec preamble usage help-specs flags)
+  (when preamble
+    (displayln preamble))
   (displayln
    (~a "usage: " program " "
        (or usage
--- a/zuo-doc/zuo-lib.scrbl
+++ b/zuo-doc/zuo-lib.scrbl
@@ -18,9 +18,10 @@
 
 @defzuomodule[zuo/cmdline]
 
-@defform[#:literals(:program :usage :args-in :init :multi :once-each :once-any :args)
+@defform[#:literals(:program :preamble :usage :args-in :init :multi :once-each :once-any :args)
          (command-line flag-clause ... args-clause)
          #:grammar ([flag-clause (code:line :program expr)
+                                 (code:line :preamble expr)
                                  (code:line :usage expr)
                                  (code:line :args-in expr)
                                  (code:line :init expr)
@@ -46,8 +47,10 @@
 list of incoming arguments instead of @racket[#:argv] for an incoming
 vector of arguments. The default @racket[:args-in] uses
 @racket[(hash-ref (runtime-env) 'args '())]. Another difference is the
-addition of @racket[:usage], which supplies a usage-options string
-as an alternative to the one inferred from an @racket[:args] clause.
+addition of @racket[:preamble], which supplies a string to be
+shown before a ``usage'' line, and @racket[:usage], which supplies a
+usage-options string as an alternative to the one inferred from an
+@racket[:args] clause.
 
 A more significant difference is that @racketmodname[zuo] does not
 have mutable data structures, so an explicit accumulator must be
@@ -58,7 +61,9 @@
 to receive the accumulated value; either way, the result of the body
 or procedure is a new accumulated value. Finally, the body of an
 @racket[args-clause] must produce a function to receive the
-accumulated value.}
+accumulated value.
+
+@history[#:changed "1.3" @elem{Added @racket[:preamble].}]}
 
 @; ------------------------------------------------------------
 
--- a/zuo.c
+++ b/zuo.c
@@ -3,7 +3,7 @@
    declarations. */
 
 #define ZUO_VERSION 1
-#define ZUO_MINOR_VERSION 2
+#define ZUO_MINOR_VERSION 3
 
 #if defined(_MSC_VER) || defined(__MINGW32__)
 # define ZUO_WINDOWS