summary refs log tree commit diff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2013-11-12 22:56:13 +0100
committerLudovic Courtès <ludo@gnu.org>2013-11-13 00:29:05 +0100
commit56b943de6e61f41d6ebd2dfa65ff886cdfd83759 (patch)
tree3669027822242116653430944897e0a27ca58f55
parentbe0f611208b4e6d730991267f69f9effe703e32f (diff)
downloadguix-56b943de6e61f41d6ebd2dfa65ff886cdfd83759.tar.gz
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.
-rw-r--r--guix/utils.scm24
-rw-r--r--tests/utils.scm8
2 files changed, 32 insertions, 0 deletions
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 <ludo@gnu.org>
+;;; Copyright © 2013 Mark H Weaver <mhw@netris.org>
 ;;;
 ;;; 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))))