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