summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gnu/build/linux-modules.scm4
-rw-r--r--guix/glob.scm51
-rw-r--r--tests/glob.scm12
3 files changed, 41 insertions, 26 deletions
diff --git a/gnu/build/linux-modules.scm b/gnu/build/linux-modules.scm
index e97c9c95f17..87d2e98edf9 100644
--- a/gnu/build/linux-modules.scm
+++ b/gnu/build/linux-modules.scm
@@ -329,7 +329,7 @@ The modules corresponding to these aliases can then be found using
329list of alias/module pairs where each alias is a glob pattern as like the 329list of alias/module pairs where each alias is a glob pattern as like the
330result of: 330result of:
331 331
332 (compile-glob-pattern \"scsi:t-0x01*\") 332 (string->compiled-sglob \"scsi:t-0x01*\")
333 333
334and each module is a module name like \"snd_hda_intel\"." 334and each module is a module name like \"snd_hda_intel\"."
335 (define (comment? str) 335 (define (comment? str)
@@ -354,7 +354,7 @@ and each module is a module name like \"snd_hda_intel\"."
354 (line 354 (line
355 (match (tokenize line) 355 (match (tokenize line)
356 (("alias" alias module) 356 (("alias" alias module)
357 (loop (alist-cons (compile-glob-pattern alias) module 357 (loop (alist-cons (string->compiled-sglob alias) module
358 aliases))) 358 aliases)))
359 (() ;empty line 359 (() ;empty line
360 (loop aliases))))))) 360 (loop aliases)))))))
diff --git a/guix/glob.scm b/guix/glob.scm
index 29c335ca1df..a9fc7448021 100644
--- a/guix/glob.scm
+++ b/guix/glob.scm
@@ -18,7 +18,9 @@
18 18
19(define-module (guix glob) 19(define-module (guix glob)
20 #:use-module (ice-9 match) 20 #:use-module (ice-9 match)
21 #:export (compile-glob-pattern 21 #:export (string->sglob
22 compile-sglob
23 string->compiled-sglob
22 glob-match?)) 24 glob-match?))
23 25
24;;; Commentary: 26;;; Commentary:
@@ -37,9 +39,9 @@
37 (lst 39 (lst
38 `(set ,@lst)))) 40 `(set ,@lst))))
39 41
40(define (compile-glob-pattern str) 42(define (string->sglob str)
41 "Return an sexp that represents the compiled form of STR, a glob pattern 43 "Return an sexp, called an \"sglob\", that represents the compiled form of
42such as \"foo*\" or \"foo??bar\"." 44STR, a glob pattern such as \"foo*\" or \"foo??bar\"."
43 (define flatten 45 (define flatten
44 (match-lambda 46 (match-lambda
45 (((? string? str)) str) 47 (((? string? str)) str)
@@ -83,9 +85,33 @@ such as \"foo*\" or \"foo??bar\"."
83 ((chr . rest) 85 ((chr . rest)
84 (loop rest (cons chr pending) brackets result))))) 86 (loop rest (cons chr pending) brackets result)))))
85 87
88(define (compile-sglob sglob)
89 "Compile SGLOB into a more efficient representation."
90 (if (string? sglob)
91 sglob
92 (let loop ((sglob sglob)
93 (result '()))
94 (match sglob
95 (()
96 (reverse result))
97 (('? . rest)
98 (loop rest (cons char-set:full result)))
99 ((('range start end) . rest)
100 (loop rest (cons (ucs-range->char-set
101 (char->integer start)
102 (+ 1 (char->integer end)))
103 result)))
104 ((('set . chars) . rest)
105 (loop rest (cons (list->char-set chars) result)))
106 ((head . rest)
107 (loop rest (cons head result)))))))
108
109(define string->compiled-sglob
110 (compose compile-sglob string->sglob))
111
86(define (glob-match? pattern str) 112(define (glob-match? pattern str)
87 "Return true if STR matches PATTERN, a compiled glob pattern as returned by 113 "Return true if STR matches PATTERN, a compiled glob pattern as returned by
88'compile-glob-pattern'." 114'compile-sglob'."
89 (let loop ((pattern pattern) 115 (let loop ((pattern pattern)
90 (str str)) 116 (str str))
91 (match pattern 117 (match pattern
@@ -101,21 +127,10 @@ such as \"foo*\" or \"foo??bar\"."
101 (index (loop rest 127 (index (loop rest
102 (string-drop str 128 (string-drop str
103 (+ index (string-length suffix))))))) 129 (+ index (string-length suffix)))))))
104 (('? . rest) 130 (((? char-set? cs) . rest)
105 (and (>= (string-length str) 1)
106 (loop rest (string-drop str 1))))
107 ((('range start end) . rest)
108 (and (>= (string-length str) 1)
109 (let ((chr (string-ref str 0)))
110 (and (char-set-contains? (ucs-range->char-set
111 (char->integer start)
112 (+ 1 (char->integer end)))
113 chr)
114 (loop rest (string-drop str 1))))))
115 ((('set . chars) . rest)
116 (and (>= (string-length str) 1) 131 (and (>= (string-length str) 1)
117 (let ((chr (string-ref str 0))) 132 (let ((chr (string-ref str 0)))
118 (and (char-set-contains? (list->char-set chars) chr) 133 (and (char-set-contains? cs chr)
119 (loop rest (string-drop str 1)))))) 134 (loop rest (string-drop str 1))))))
120 ((prefix . rest) 135 ((prefix . rest)
121 (and (string-prefix? prefix str) 136 (and (string-prefix? prefix str)
diff --git a/tests/glob.scm b/tests/glob.scm
index 71e2d3fce07..31340697899 100644
--- a/tests/glob.scm
+++ b/tests/glob.scm
@@ -23,14 +23,14 @@
23 23
24(test-begin "glob") 24(test-begin "glob")
25 25
26(define-syntax test-compile-glob-pattern 26(define-syntax test-string->sglob
27 (syntax-rules (=>) 27 (syntax-rules (=>)
28 ((_ pattern => result rest ...) 28 ((_ pattern => result rest ...)
29 (begin 29 (begin
30 (test-equal (format #f "compile-glob-pattern, ~s" pattern) 30 (test-equal (format #f "string->sglob, ~s" pattern)
31 result 31 result
32 (compile-glob-pattern pattern)) 32 (string->sglob pattern))
33 (test-compile-glob-pattern rest ...))) 33 (test-string->sglob rest ...)))
34 ((_) 34 ((_)
35 #t))) 35 #t)))
36 36
@@ -39,14 +39,14 @@
39 ((_ (pattern-string matches strings ... (and not others ...)) rest ...) 39 ((_ (pattern-string matches strings ... (and not others ...)) rest ...)
40 (begin 40 (begin
41 (test-assert (format #f "glob-match? ~s" pattern-string) 41 (test-assert (format #f "glob-match? ~s" pattern-string)
42 (let ((pattern (compile-glob-pattern pattern-string))) 42 (let ((pattern (string->compiled-sglob pattern-string)))
43 (and (glob-match? pattern strings) ... 43 (and (glob-match? pattern strings) ...
44 (not (glob-match? pattern others)) ...))) 44 (not (glob-match? pattern others)) ...)))
45 (test-glob-match rest ...))) 45 (test-glob-match rest ...)))
46 ((_) 46 ((_)
47 #t))) 47 #t)))
48 48
49(test-compile-glob-pattern 49(test-string->sglob
50 "foo" => "foo" 50 "foo" => "foo"
51 "?foo*" => '(? "foo" *) 51 "?foo*" => '(? "foo" *)
52 "foo[1-5]" => '("foo" (range #\1 #\5)) 52 "foo[1-5]" => '("foo" (range #\1 #\5))