From 10c87717bd70c9d7e47a13753dc2756a97f00e35 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Sat, 7 Jul 2012 16:25:10 +0200 Subject: utils: Introduce `substitute*', for easier sed-like syntax. * guix/build/utils.scm (let-matches, substitute*): New macros. * distro/base.scm (guile-1.8): Use `substitute*' instead of `substitute'. Remove the #:modules argument. --- guix/build/utils.scm | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'guix') diff --git a/guix/build/utils.scm b/guix/build/utils.scm index 1808c63ce5..19728e6015 100644 --- a/guix/build/utils.scm +++ b/guix/build/utils.scm @@ -28,7 +28,8 @@ (define-module (guix build utils) alist-cons-before alist-cons-after alist-replace - substitute)) + substitute + substitute*)) ;;; @@ -175,6 +176,43 @@ (define (substitute file pattern match-proc) (lambda (key . args) (false-if-exception (delete-file template)))))) + +(define-syntax let-matches + ;; Helper macro for `substitute*'. + (syntax-rules (_) + ((let-matches index match (_ vars ...) body ...) + (let-matches (+ 1 index) match (vars ...) + body ...)) + ((let-matches index match (var vars ...) body ...) + (let ((var (match:substring match index))) + (let-matches (+ 1 index) match (vars ...) + body ...))) + ((let-matches index match () body ...) + (begin body ...)))) + +(define-syntax-rule (substitute* file (regexp whole-match match ...) + 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))))) + + ;;; Local Variables: ;;; eval: (put 'call-with-output-file/atomic 'scheme-indent-function 1) ;;; eval: (put 'with-throw-handler 'scheme-indent-function 1) -- cgit v1.2.3