diff options
author | Ludovic Courtès <ludo@gnu.org> | 2012-07-07 16:25:10 +0200 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2012-07-07 16:25:10 +0200 |
commit | 10c87717bd70c9d7e47a13753dc2756a97f00e35 (patch) | |
tree | 0285a8c55f1db2d58a9388e2366201a2cba75c7d /guix/build/utils.scm | |
parent | d767288490c0d2edc1b64fb99994571ddcc08f0f (diff) | |
download | gnu-guix-10c87717bd70c9d7e47a13753dc2756a97f00e35.tar gnu-guix-10c87717bd70c9d7e47a13753dc2756a97f00e35.tar.gz |
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.
Diffstat (limited to 'guix/build/utils.scm')
-rw-r--r-- | guix/build/utils.scm | 40 |
1 files changed, 39 insertions, 1 deletions
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 @@ alist-cons-before alist-cons-after alist-replace - substitute)) + substitute + substitute*)) ;;; @@ -175,6 +176,43 @@ MATCH OUTPUT-PORT)." (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) |