summaryrefslogtreecommitdiff
path: root/guix/build
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2012-07-07 17:12:04 +0200
committerLudovic Courtès <ludo@gnu.org>2012-07-07 17:12:04 +0200
commit4fa697e932d5634441e4e281ce6879ca3a082a30 (patch)
tree75e39c2138d04c47105e0c378d5ae01801c62a60 /guix/build
parent03f9609ad9a8118b48bef7869e48c3afaae5f6ce (diff)
downloadgnu-guix-4fa697e932d5634441e4e281ce6879ca3a082a30.tar
gnu-guix-4fa697e932d5634441e4e281ce6879ca3a082a30.tar.gz
utils: Change `substitute' and `substitute*' to work with several regexps.
* guix/build/utils.scm (substitute): Change to accept a `pattern+procs' parameter. Iterate over it. (substitute*): Adjust accordingly. * distro/base.scm (guile-1.8): Adjust accordingly.
Diffstat (limited to 'guix/build')
-rw-r--r--guix/build/utils.scm73
1 files changed, 43 insertions, 30 deletions
diff --git a/guix/build/utils.scm b/guix/build/utils.scm
index 19728e6015..3dc7674043 100644
--- a/guix/build/utils.scm
+++ b/guix/build/utils.scm
@@ -147,12 +147,17 @@ An error is raised when no such pair exists."
;;; Text substitution (aka. sed).
;;;
-(define (substitute file pattern match-proc)
- "For each line of FILE that matches PATTERN, a regexp, call (MATCH-PROC
-MATCH OUTPUT-PORT)."
- (let* ((regexp (if (regexp? pattern)
- pattern
- (make-regexp pattern regexp/extended)))
+(define (substitute file pattern+procs)
+ "PATTERN+PROCS is a list of regexp/two-argument procedure. For each line
+of FILE, and for each PATTERN that it matches, call the corresponding PROC
+as (PROC MATCH OUTPUT-PORT)."
+ (let* ((rx+proc (map (match-lambda
+ (((? regexp? pattern) . proc)
+ (cons pattern proc))
+ ((pattern . proc)
+ (cons (make-regexp pattern regexp/extended)
+ proc)))
+ pattern+procs))
(template (string-append file ".XXXXXX"))
(out (mkstemp! template)))
(with-throw-handler #t
@@ -163,13 +168,16 @@ MATCH OUTPUT-PORT)."
(if (eof-object? line)
#t
(begin
- (cond ((regexp-exec regexp line)
- =>
- (lambda (m)
- (match-proc m out)))
- (else
- (display line out)
- (newline out)))
+ (for-each (match-lambda
+ ((regexp . proc)
+ (cond ((regexp-exec regexp line)
+ =>
+ (lambda (m)
+ (proc m out)))
+ (else
+ (display line out)
+ (newline out)))))
+ rx+proc)
(loop (read-line in)))))))
(close out)
(rename-file template file))
@@ -190,27 +198,32 @@ MATCH OUTPUT-PORT)."
((let-matches index match () body ...)
(begin body ...))))
-(define-syntax-rule (substitute* file (regexp whole-match match ...)
- body ...)
+(define-syntax-rule (substitute* file
+ ((regexp match-var ...) body ...)
+ ...)
"Substitute REGEXP in FILE by the string returned by BODY. BODY is
evaluated with each MATCH-VAR bound to the corresponding positional regexp
sub-expression. For example:
- (substitute* file (\"foo([a-z]+)bar(.*)$\" all letters end)
- (string-append \"baz\" letters end))
-
-Here, anytime a line of FILE matches the regexp, ALL is bound to the complete
-match, LETTERS is bound to the first sub-expression, and END is bound to the
-last one. Alternatively, given that `all' is not used, one can write:
-
- (substitute* file (\"foo([a-z]+)bar(.*)$\" _ letters end)
- (string-append \"baz\" letter end))
-
-"
- (substitute file regexp
- (lambda (m p)
- (let-matches 0 m (whole-match match ...)
- (display (begin body ...) p)))))
+ (substitute* file
+ ((\"hello\")
+ \"good morning\\n\")
+ ((\"foo([a-z]+)bar(.*)$\" all letters end)
+ (string-append \"baz\" letter end)))
+
+Here, anytime a line of FILE contains \"hello\", it is replaced by \"good
+morning\". Anytime a line of FILE matches the second regexp, ALL is bound to
+the complete match, LETTERS is bound to the first sub-expression, and END is
+bound to the last one.
+
+When one of the MATCH-VAR is `_', no variable is bound to the corresponding
+match substring."
+ (substitute file
+ (list (cons regexp
+ (lambda (m p)
+ (let-matches 0 m (match-var ...)
+ (display (begin body ...) p))))
+ ...)))
;;; Local Variables: