blob: 5f692b71b42d90fe55c97a8373ee60af76bb850b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
;;; glob.scm: String matching for filenames (a la BASH).
;;; Copyright (C) 1998 Radey Shouman.
;
;Permission to copy this software, to redistribute it, and to use it
;for any purpose is granted, subject to the following restrictions and
;understandings.
;
;1. Any copy made of this software must include this copyright notice
;in full.
;
;2. I have made no warrantee or representation that the operation of
;this software will be error-free, and I am under no obligation to
;provide any services, by way of maintenance, update, or otherwise.
;
;3. In conjunction with products arising from the use of this
;material, there shall be no use of my name in any advertising,
;promotional, or sales literature without prior written consent in
;each case.
;;$Header: /usr/local/cvsroot/slib/glob.scm,v 1.2 1998/09/03 15:34:59 jaffer Exp $
;;$Name: $
(define (glob:match?? pat)
(glob:make-matcher pat char-ci=? char=?))
(define (glob:match-ci?? pat)
(glob:make-matcher pat char-ci<=? char<=?))
(define (glob:make-matcher pat ch=? ch<=?)
(define (match-end str k)
(= k (string-length str)))
(define (match-char ch nxt)
(lambda (str k)
(and (< k (string-length str))
(ch=? ch (string-ref str k))
(nxt str (+ k 1)))))
(define (match-? nxt)
(lambda (str k)
(and (< k (string-length str))
(nxt str (+ k 1)))))
(define (match-set1 chrs)
(let recur ((i 0))
(cond ((= i (string-length chrs))
(lambda (ch) #f))
((and (< (+ i 2) (string-length chrs))
(char=? #\- (string-ref chrs (+ i 1))))
(let ((nxt (recur (+ i 3))))
(lambda (ch)
(or (and (ch<=? ch (string-ref chrs (+ i 2)))
(ch<=? (string-ref chrs i) ch))
(nxt ch)))))
(else
(let ((nxt (recur (+ i 1)))
(chrsi (string-ref chrs i)))
(lambda (ch)
(or (ch=? chrsi ch) (nxt ch))))))))
(define (match-set chrs nxt)
(if (and (positive? (string-length chrs))
(memv (string-ref chrs 0) '(#\^ #\!)))
(let ((pred (match-set1 (substring chrs 1 (string-length chrs)))))
(lambda (str k)
(and (< k (string-length str))
(not (pred (string-ref str k)))
(nxt str (+ k 1)))))
(let ((pred (match-set1 chrs)))
(lambda (str k)
(and (< k (string-length str))
(pred (string-ref str k))
(nxt str (+ k 1)))))))
(define (match-* nxt)
(lambda (str k)
(let loop ((kk (string-length str)))
(and (>= kk k)
(or (nxt str kk)
(loop (- kk 1)))))))
(let ((matcher
(let recur ((i 0))
(if (= i (string-length pat))
match-end
(let ((pch (string-ref pat i)))
(case pch
((#\?)
(let ((nxt (recur (+ i 1))))
(match-? nxt)))
((#\*)
(let ((nxt (recur (+ i 1))))
(match-* nxt)))
((#\[)
(let ((j
(let search ((j (+ i 2)))
(cond
((>= j (string-length pat))
(slib:error 'glob:make-matcher
"unmatched [" pat))
((char=? #\] (string-ref pat j))
(if (and (< (+ j 1) (string-length pat))
(char=? #\] (string-ref pat (+ j 1))))
(+ j 1)
j))
(else (search (+ j 1)))))))
(let ((nxt (recur (+ j 1))))
(match-set (substring pat (+ i 1) j) nxt))))
(else (let ((nxt (recur (+ i 1))))
(match-char pch nxt)))))))))
(lambda (str) (matcher str 0))))
(define filename:match?? glob:match??)
(define filename:match-ci?? glob:match-ci??)
(define (replace-suffix str old new)
(define (cs str)
(let* ((len (string-length str))
(re (- len (string-length old))))
(cond ((string-ci=? old (substring str re len))
(string-append (substring str 0 re) new))
(else
(slib:error 'replace-suffix "suffix doesn't match:"
old str)))))
(if (string? str) (cs str) (map cs str)))
|