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.
This commit is contained in:
Ludovic Courtès 2013-11-12 22:56:13 +01:00
parent be0f611208
commit 56b943de6e
2 changed files with 32 additions and 0 deletions

View File

@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2013 Mark H Weaver <mhw@netris.org>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
;;; ;;;
@ -62,6 +63,7 @@
guile-version>? guile-version>?
package-name->name+version package-name->name+version
string-tokenize* string-tokenize*
string-replace-substring
file-extension file-extension
file-sans-extension file-sans-extension
call-with-temporary-output-file call-with-temporary-output-file
@ -387,6 +389,28 @@ like `string-tokenize', but SEPARATOR is a string."
(else (else
(reverse (cons string result)))))) (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) (define (call-with-temporary-output-file proc)
"Call PROC with a name of a temporary file and open output port to that "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 file; close the file and delete it when leaving the dynamic extent of this

View File

@ -82,6 +82,14 @@
(string-tokenize* "foo!bar!" "!") (string-tokenize* "foo!bar!" "!")
(string-tokenize* "foo+-+bar+-+baz" "+-+"))) (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" (test-equal "fold2, 1 list"
(list (reverse (iota 5)) (list (reverse (iota 5))
(map - (reverse (iota 5)))) (map - (reverse (iota 5))))