summary refs log tree commit diff
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
parent03f9609ad9a8118b48bef7869e48c3afaae5f6ce (diff)
downloadguix-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.
-rw-r--r--distro/base.scm10
-rw-r--r--guix/build/utils.scm73
2 files changed, 48 insertions, 35 deletions
diff --git a/distro/base.scm b/distro/base.scm
index e85b927fc3..d193b4a169 100644
--- a/distro/base.scm
+++ b/distro/base.scm
@@ -132,11 +132,11 @@ code.")
                              ;; `libguile-readline.so' & co. are in the
                              ;; loader's search path.
                              (substitute* "libguile/dynl.c"
-                                          ("lt_dlinit.*$" match)
-                                          (format #f
-                                                  "  ~a~%  lt_dladdsearchdir(\"~a/lib\");~%"
-                                                  match
-                                                  (assoc-ref outputs "out"))))
+                                          (("lt_dlinit.*$" match)
+                                           (format #f
+                                                   "  ~a~%  lt_dladdsearchdir(\"~a/lib\");~%"
+                                                   match
+                                                   (assoc-ref outputs "out")))))
                            %standard-phases)))
    (inputs `(("patch/snarf"
               ,(search-path %load-path "distro/guile-1.8-cpp-4.5.patch"))
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: