summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
authorSilvan Mosberger <contact@infinisil.com>2020-10-20 22:12:52 +0200
committerGitHub <noreply@github.com>2020-10-20 22:12:52 +0200
commita2fe9a7abc68c5356ed7167bd9aae7ea201f2435 (patch)
treecdec1969619434d3eb4e6b4cfefe16962eb509b5 /lib
parent6a94d64c101b977792cb7d1213855f4c20e5e838 (diff)
parentd7464ab4bbb83694587bb2e217c032e0a6c0fd98 (diff)
downloadnixpkgs-a2fe9a7abc68c5356ed7167bd9aae7ea201f2435.tar
nixpkgs-a2fe9a7abc68c5356ed7167bd9aae7ea201f2435.tar.gz
nixpkgs-a2fe9a7abc68c5356ed7167bd9aae7ea201f2435.tar.bz2
nixpkgs-a2fe9a7abc68c5356ed7167bd9aae7ea201f2435.tar.lz
nixpkgs-a2fe9a7abc68c5356ed7167bd9aae7ea201f2435.tar.xz
nixpkgs-a2fe9a7abc68c5356ed7167bd9aae7ea201f2435.tar.zst
nixpkgs-a2fe9a7abc68c5356ed7167bd9aae7ea201f2435.zip
Merge pull request #100953 from AtnNn/splitStrings
Implement splitString using builtins.split
Diffstat (limited to 'lib')
-rw-r--r--lib/strings.nix35
-rw-r--r--lib/tests/misc.nix14
2 files changed, 28 insertions, 21 deletions
diff --git a/lib/strings.nix b/lib/strings.nix
index 9fa9f023561..d81e46a1763 100644
--- a/lib/strings.nix
+++ b/lib/strings.nix
@@ -315,6 +315,16 @@ rec {
   */
   escapeNixString = s: escape ["$"] (builtins.toJSON s);
 
+  /* Turn a string into an exact regular expression
+
+     Type: string -> string
+
+     Example:
+       escapeRegex "[^a-z]*"
+       => "\\[\\^a-z]\\*"
+  */
+  escapeRegex = escape (stringToCharacters "\\[{()^$?*+|.");
+
   /* Quotes a string if it can't be used as an identifier directly.
 
      Type: string -> string
@@ -386,8 +396,6 @@ rec {
   /* Cut a string with a separator and produces a list of strings which
      were separated by this separator.
 
-     NOTE: this function is not performant and should never be used.
-
      Example:
        splitString "." "foo.bar.baz"
        => [ "foo" "bar" "baz" ]
@@ -396,26 +404,11 @@ rec {
   */
   splitString = _sep: _s:
     let
-      sep = addContextFrom _s _sep;
-      s = addContextFrom _sep _s;
-      sepLen = stringLength sep;
-      sLen = stringLength s;
-      lastSearch = sLen - sepLen;
-      startWithSep = startAt:
-        substring startAt sepLen s == sep;
-
-      recurse = index: startAt:
-        let cutUntil = i: [(substring startAt (i - startAt) s)]; in
-        if index <= lastSearch then
-          if startWithSep index then
-            let restartAt = index + sepLen; in
-            cutUntil index ++ recurse restartAt restartAt
-          else
-            recurse (index + 1) startAt
-        else
-          cutUntil sLen;
+      sep = builtins.unsafeDiscardStringContext _sep;
+      s = builtins.unsafeDiscardStringContext _s;
+      splits = builtins.filter builtins.isString (builtins.split (escapeRegex sep) s);
     in
-      recurse 0 0;
+      map (v: addContextFrom _sep (addContextFrom _s v)) splits;
 
   /* Return a string without the specified prefix, if the prefix matches.
 
diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix
index 3a6db53c276..6175f15819a 100644
--- a/lib/tests/misc.nix
+++ b/lib/tests/misc.nix
@@ -154,6 +154,20 @@ runTests {
     expected = [ "2001" "db8" "0" "0042" "" "8a2e" "370" "" ];
   };
 
+  testSplitStringsRegex = {
+    expr = strings.splitString "\\[{}]()^$?*+|." "A\\[{}]()^$?*+|.B";
+    expected = [ "A" "B" ];
+  };
+
+  testSplitStringsDerivation = {
+    expr = take 3  (strings.splitString "/" (derivation {
+      name = "name";
+      builder = "builder";
+      system = "system";
+    }));
+    expected = ["" "nix" "store"];
+  };
+
   testSplitVersionSingle = {
     expr = versions.splitVersion "1";
     expected = [ "1" ];