ref: 23bf90a915a0065fe463b2365fea84c273e4ad49
parent: bdad684695b0b1b3078fdd488962044a631c2c22
author: Matthew Flatt <mflatt@racket-lang.org>
date: Tue Oct 17 02:32:33 CDT 2023
Zuo: repair `MAKEFLAGS` handling The previous implementation relied on behavior of GNU Make 4.0, which will add a space to the beginning of `MAKEFLAGS` when it doesn't start with flags. The more general `MAKEFLAGS` convention (e.g, POSIX) doesn't guarantee that, and so better parsing is needed.
--- a/lib/zuo/dry-run.zuo
+++ b/lib/zuo/dry-run.zuo
@@ -9,18 +9,45 @@
(when (and mode (not (eq? mode sym)))
(error (~a "`MAKEFLAGS` specified both " mode " and " sym " modes")))
sym)
+ (define (no-touch mode)
+ (when (eq? mode 'touch)
+ (error "`MAKEFLAGS` indicates touch mode, which is not supported"))
+ mode)
(and a
- (let ([s (cdr a)])
- (let loop ([i 0] [mode #f])
- (cond
- [(or (= i (string-length s))
- (equal? (char " ") (string-ref s i)))
- mode]
- [(equal? (char "n") (string-ref s i))
- (loop (+ i 1) (new-mode mode 'dry-run))]
- [(equal? (char "q") (string-ref s i))
- (loop (+ i 1) (new-mode mode 'question))]
- [(equal? (char "t") (string-ref s i))
- (error "`MAKEFLAGS` has `-t`, but trace mode is not supported")]
- [else
- (loop (+ i 1) mode)])))))
+ (let loop ([l (shell->strings (cdr a))])
+ (and (pair? l)
+ (or
+ ;; If the first argument has only letters, then we
+ ;; assume it represents single-letter flags:
+ (let ([s (car l)])
+ (let loop ([i 0] [mode #f])
+ (cond
+ [(= i (string-length s))
+ (no-touch mode)]
+ [(equal? (char "n") (string-ref s i))
+ (loop (+ i 1) (new-mode mode 'dry-run))]
+ [(equal? (char "q") (string-ref s i))
+ (loop (+ i 1) (new-mode mode 'question))]
+ [(equal? (char "t") (string-ref s i))
+ (loop (+ i 1) (new-mode mode 'touch))]
+ [(and (or (string<? (substring s i (+ i 1)) "a")
+ (string<? "z" (substring s i (+ i 1))))
+ (or (string<? (substring s i (+ i 1)) "A")
+ (string<? "Z" (substring s i (+ i 1)))))
+ ;; doesn't look like single-letter flags
+ #f]
+ [else
+ (loop (+ i 1) mode)])))
+ ;; Otherwise, look for "-n", "-t", and "-q"
+ (let loop ([l l] [mode #f])
+ (cond
+ [(null? l)
+ (no-touch mode)]
+ [(equal? "-n" (car l))
+ (loop (cdr l) (new-mode mode 'dry-run))]
+ [(equal? "-q" (car l))
+ (loop (cdr l) (new-mode mode 'question))]
+ [(equal? "-t" (car l))
+ (loop (cdr l) (new-mode mode 'touch))]
+ [else
+ (loop (cdr l) mode)])))))))