From 56b943de6e61f41d6ebd2dfa65ff886cdfd83759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Tue, 12 Nov 2013 22:56:13 +0100 Subject: [PATCH] utils: Add 'string-replace-substring'. * guix/utils.scm (string-replace-substring): New procedure. Based on code by Mark H. Weaver. * tests/utils.scm ("string-replace-substring"): New test. --- guix/utils.scm | 24 ++++++++++++++++++++++++ tests/utils.scm | 8 ++++++++ 2 files changed, 32 insertions(+) diff --git a/guix/utils.scm b/guix/utils.scm index 1f3c0c8ad6..b730340eda 100644 --- a/guix/utils.scm +++ b/guix/utils.scm @@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2012, 2013 Ludovic Courtès +;;; Copyright © 2013 Mark H Weaver ;;; ;;; This file is part of GNU Guix. ;;; @@ -62,6 +63,7 @@ guile-version>? package-name->name+version string-tokenize* + string-replace-substring file-extension file-sans-extension call-with-temporary-output-file @@ -387,6 +389,28 @@ like `string-tokenize', but SEPARATOR is a string." (else (reverse (cons string result)))))) +(define* (string-replace-substring str substr replacement + #:optional + (start 0) + (end (string-length str))) + "Replace all occurrences of SUBSTR in the START--END range of STR by +REPLACEMENT." + (match (string-length substr) + (0 + (error "string-replace-substring: empty substring")) + (substr-length + (let loop ((start start) + (pieces (list (substring str 0 start)))) + (match (string-contains str substr start end) + (#f + (string-concatenate-reverse + (cons (substring str start) pieces))) + (index + (loop (+ index substr-length) + (cons* replacement + (substring str start index) + pieces)))))))) + (define (call-with-temporary-output-file proc) "Call PROC with a name of a temporary file and open output port to that file; close the file and delete it when leaving the dynamic extent of this diff --git a/tests/utils.scm b/tests/utils.scm index 4f6ecc514d..017d9170fa 100644 --- a/tests/utils.scm +++ b/tests/utils.scm @@ -82,6 +82,14 @@ (string-tokenize* "foo!bar!" "!") (string-tokenize* "foo+-+bar+-+baz" "+-+"))) +(test-equal "string-replace-substring" + '("foo BAR! baz" + "/gnu/store/chbouib" + "") + (list (string-replace-substring "foo bar baz" "bar" "BAR!") + (string-replace-substring "/nix/store/chbouib" "/nix/" "/gnu/") + (string-replace-substring "" "foo" "bar"))) + (test-equal "fold2, 1 list" (list (reverse (iota 5)) (map - (reverse (iota 5))))