summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--guix/utils.scm28
-rw-r--r--tests/utils.scm10
2 files changed, 38 insertions, 0 deletions
diff --git a/guix/utils.scm b/guix/utils.scm
index 3cbed2fd0f..0b09affffd 100644
--- a/guix/utils.scm
+++ b/guix/utils.scm
@@ -60,6 +60,7 @@
             version-compare
             version>?
             package-name->name+version
+            string-tokenize*
             file-extension
             call-with-temporary-output-file
             fold2))
@@ -471,6 +472,33 @@ introduce the version part."
   (let ((dot (string-rindex file #\.)))
     (and dot (substring file (+ 1 dot) (string-length file)))))
 
+(define (string-tokenize* string separator)
+  "Return the list of substrings of STRING separated by SEPARATOR.  This is
+like `string-tokenize', but SEPARATOR is a string."
+  (define (index string what)
+    (let loop ((string string)
+               (offset 0))
+      (cond ((string-null? string)
+             #f)
+            ((string-prefix? what string)
+             offset)
+            (else
+             (loop (string-drop string 1) (+ 1 offset))))))
+
+  (define len
+    (string-length separator))
+
+  (let loop ((string string)
+             (result  '()))
+    (cond ((index string separator)
+           =>
+           (lambda (offset)
+             (loop (string-drop string (+ offset len))
+                   (cons (substring string 0 offset)
+                         result))))
+          (else
+           (reverse (cons string result))))))
+
 (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 fa7d7b03fd..97547a6d62 100644
--- a/tests/utils.scm
+++ b/tests/utils.scm
@@ -64,6 +64,16 @@
            ("nixpkgs" "1.0pre22125_a28fe19")
            ("gtk2" "2.38.0"))))
 
+(test-equal "string-tokenize*"
+  '(("foo")
+    ("foo" "bar" "baz")
+    ("foo" "bar" "")
+    ("foo" "bar" "baz"))
+  (list (string-tokenize* "foo" ":")
+        (string-tokenize* "foo;bar;baz" ";")
+        (string-tokenize* "foo!bar!" "!")
+        (string-tokenize* "foo+-+bar+-+baz" "+-+")))
+
 (test-equal "fold2, 1 list"
     (list (reverse (iota 5))
           (map - (reverse (iota 5))))