Support ${ # ## % %% }.
This commit is contained in:
parent
1e51c5cbd1
commit
8ca428c7f2
6
check.sh
6
check.sh
|
@ -69,6 +69,12 @@ tests="
|
|||
60-function
|
||||
60-subst
|
||||
|
||||
70-hash.sh
|
||||
70-hash-hash.sh
|
||||
70-percent.sh
|
||||
70-percent-percent.sh
|
||||
70-percent-space.sh
|
||||
|
||||
100-sed
|
||||
100-sed-once
|
||||
100-sed-global
|
||||
|
|
17
gash/peg.scm
17
gash/peg.scm
|
@ -225,9 +225,13 @@
|
|||
dollar < '$'
|
||||
literal <-- backslash? (!ws !amp !tick !dollar !pipe !semi !par !nl !sp !rbrace !io-op !dq !sq .)+
|
||||
variable <-- dollar ('$' / '#' / '*' / '?' / '@' / [0-9] / identifier / lbrace identifier rbrace)
|
||||
variable-and-or <- dollar lbrace (variable-or / variable-and ) rbrace
|
||||
variable-and-or <- dollar lbrace (variable-or / variable-and / variable-hash-hash / variable-hash / variable-percent-percent / variable-percent ) rbrace
|
||||
variable-and <-- identifier plus rhs
|
||||
variable-or <-- identifier minus rhs
|
||||
variable-hash <-- identifier hash rhs
|
||||
variable-hash-hash <-- identifier hash hash rhs
|
||||
variable-percent <-- identifier percent rhs
|
||||
variable-percent-percent <-- identifier percent percent rhs
|
||||
delim <- singlequotes / doublequotes / substitution
|
||||
sq < [']
|
||||
dq < [\"]
|
||||
|
@ -248,6 +252,8 @@
|
|||
rbrace < [}]
|
||||
plus < [+]
|
||||
minus < '-'
|
||||
hash < '#'
|
||||
percent < '%'
|
||||
par < lpar / rpar
|
||||
nl < '\n'
|
||||
sp < '\t' / ' ' / (escaped-nl sp*)
|
||||
|
@ -351,19 +357,20 @@
|
|||
|
||||
(('brace-group o) `(brace-group ,(transform o)))
|
||||
(('file-name o) `(file-name ,(transform o)))
|
||||
|
||||
(_ ast)))
|
||||
|
||||
|
||||
(define (remove-shell-comments s)
|
||||
(define (remove-line-comments s)
|
||||
(string-join (map
|
||||
(lambda (s)
|
||||
(let* ((n (string-index s #\#)))
|
||||
(if n (string-pad-right s (string-length s) #\space 0 n)
|
||||
(let ((n (string-index s #\#)))
|
||||
(if (and n (zero? n)) (string-pad-right s (string-length s) #\space 0 n)
|
||||
s)))
|
||||
(string-split s #\newline)) "\n"))
|
||||
|
||||
(define (parse-string string)
|
||||
(let* ((pt ((compose parse- remove-shell-comments) string))
|
||||
(let* ((pt ((compose parse- remove-line-comments) string))
|
||||
(foo (when (> %debug-level 1) (display "tree:\n") (pretty-print pt)))
|
||||
(flat (flatten pt))
|
||||
(foo (when (> %debug-level 0) (display "flat:\n") (pretty-print flat)))
|
||||
|
|
|
@ -91,14 +91,16 @@
|
|||
(else (lambda () #t))))
|
||||
(exec (append-map glob args)))
|
||||
|
||||
(define (glob pattern)
|
||||
(define (glob? pattern)
|
||||
(and (string? pattern) (string-match "\\?|\\*" pattern)))
|
||||
(define (glob2regex pattern)
|
||||
(define (glob? pattern)
|
||||
(and (string? pattern) (string-match "\\?|\\*" pattern)))
|
||||
|
||||
(define* (glob->regex pattern #:key (begin "^") (end "$"))
|
||||
(let* ((pattern (regexp-substitute/global #f "\\." pattern 'pre "\\." 'post))
|
||||
(pattern (regexp-substitute/global #f "\\?" pattern 'pre "." 'post))
|
||||
(pattern (regexp-substitute/global #f "\\*" pattern 'pre ".*" 'post)))
|
||||
(make-regexp (string-append "^" pattern "$"))))
|
||||
(make-regexp (string-append begin pattern end))))
|
||||
|
||||
(define (glob pattern)
|
||||
(define (glob-match regex path) ;; pattern path -> bool
|
||||
(regexp-match? (regexp-exec regex path)))
|
||||
(define (glob- pattern file-names)
|
||||
|
@ -107,7 +109,7 @@
|
|||
(append-map (lambda (file-name)
|
||||
(map (cut string-append (if (string=? "/" file-name) "" file-name) "/" <>)
|
||||
(filter (conjoin (negate (cut string-prefix? "." <>))
|
||||
(cute glob-match (glob2regex pattern) <>))
|
||||
(cute glob-match (glob->regex pattern) <>))
|
||||
(or (scandir file-name) '()))))
|
||||
file-names)))
|
||||
(cond
|
||||
|
@ -285,3 +287,57 @@
|
|||
|
||||
(define (file-name o)
|
||||
o)
|
||||
|
||||
(define (regexp-exec-non-greedy regexp string)
|
||||
(let ((max (string-length string)))
|
||||
(let loop ((size 1))
|
||||
(and (<= size max)
|
||||
(or (regexp-exec regexp (substring string 0 size))
|
||||
(loop (1+ size)))))))
|
||||
|
||||
(define (regexp-exec-non-greedy-reverse regexp string)
|
||||
(let ((max (string-length string)))
|
||||
(let loop ((start (1- max)))
|
||||
(and (>= start 0)
|
||||
(or (regexp-exec regexp (substring string start))
|
||||
(loop (1- start)))))))
|
||||
|
||||
(define (variable-hash name pattern)
|
||||
(let ((value (variable name))
|
||||
(glob? (glob? pattern)))
|
||||
(if glob? (let* ((regexp (glob->regex pattern #:end ""))
|
||||
(match (regexp-exec-non-greedy regexp value)))
|
||||
(if match (string-drop value (match:end match))
|
||||
value))
|
||||
(if (string-prefix? pattern value) (string-drop value (string-length pattern))
|
||||
value))))
|
||||
|
||||
(define (variable-hash-hash name pattern)
|
||||
(let ((value (variable name))
|
||||
(glob? (glob? pattern)))
|
||||
(if glob? (let* ((regexp (glob->regex pattern #:end ""))
|
||||
(match (regexp-exec regexp value)))
|
||||
(if match (string-drop value (match:end match))
|
||||
value))
|
||||
(if (string-prefix? pattern value) (string-drop value (string-length pattern))
|
||||
value))))
|
||||
|
||||
(define (variable-percent name pattern)
|
||||
(let ((value (variable name))
|
||||
(glob? (glob? pattern)))
|
||||
(if glob? (let* ((regexp (glob->regex pattern #:begin ""))
|
||||
(match (regexp-exec-non-greedy-reverse regexp value)))
|
||||
(if match (substring value 0 (- (string-length value) (match:end match)))
|
||||
value))
|
||||
(if (string-suffix? pattern value) (substring value 0 (string-length pattern))
|
||||
value))))
|
||||
|
||||
(define (variable-percent-percent name pattern)
|
||||
(let ((value (variable name))
|
||||
(glob? (glob? pattern)))
|
||||
(if glob? (let* ((regexp (glob->regex pattern #:begin ""))
|
||||
(match (regexp-exec regexp value)))
|
||||
(if match (substring value 0 (match:start match))
|
||||
value))
|
||||
(if (string-suffix? pattern value) (substring value 0 (string-length pattern))
|
||||
value))))
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
file=dir/sub/name.ext
|
||||
echo ${file##*/}
|
|
@ -0,0 +1 @@
|
|||
name.ext
|
|
@ -0,0 +1,2 @@
|
|||
file=dir/sub/name.ext
|
||||
echo ${file#*/}
|
|
@ -0,0 +1 @@
|
|||
sub/name.ext
|
|
@ -0,0 +1,2 @@
|
|||
file=dir/sub/name.ext
|
||||
echo ${file%%/*}
|
|
@ -0,0 +1 @@
|
|||
dir
|
|
@ -0,0 +1,2 @@
|
|||
args="--prefix=/usr "
|
||||
echo ${args% *}/
|
|
@ -0,0 +1 @@
|
|||
--prefix=/usr/
|
|
@ -0,0 +1,2 @@
|
|||
file=dir/sub/name.ext
|
||||
echo ${file%/*}
|
|
@ -0,0 +1 @@
|
|||
dir/sub
|
Loading…
Reference in New Issue