summary refs log tree commit diff stats
path: root/lib/pure
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pure')
-rw-r--r--lib/pure/cstrutils.nim180
-rw-r--r--lib/pure/strutils.nim15
2 files changed, 98 insertions, 97 deletions
diff --git a/lib/pure/cstrutils.nim b/lib/pure/cstrutils.nim
index 390aac00b..cdef7c804 100644
--- a/lib/pure/cstrutils.nim
+++ b/lib/pure/cstrutils.nim
@@ -16,93 +16,103 @@ import std/private/strimpl
 
 
 when defined(js):
-  func startsWith*(s, prefix: cstring): bool {.importjs: "#.startsWith(#)".}
+  func jsStartsWith(s, prefix: cstring): bool {.importjs: "#.startsWith(#)".}
+  func jsEndsWith(s, suffix: cstring): bool {.importjs: "#.endsWith(#)".}
 
-  func endsWith*(s, suffix: cstring): bool {.importjs: "#.endsWith(#)".}
 
-  func cmpIgnoreStyle*(a, b: cstring): int =
-    cmpIgnoreStyleImpl(a, b)
-
-  func cmpIgnoreCase*(a, b: cstring): int =
-    cmpIgnoreCaseImpl(a, b)
-
-  # JS string has more operations that might warrant its own module:
-  # https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
-else:
-  func startsWith*(s, prefix: cstring): bool {.rtl, extern: "csuStartsWith".} =
-    ## Returns true if `s` starts with `prefix`.
-    ##
-    ## If `prefix == ""` true is returned.
-    ## 
-    ## JS backend uses native `String.prototype.startsWith`.
-    runnableExamples:
-      assert startsWith(cstring"Hello, Nimion", cstring"Hello")
-      assert not startsWith(cstring"Hello, Nimion", cstring"Nimion")
-
-    var i = 0
-    while true:
-      if prefix[i] == '\0': return true
-      if s[i] != prefix[i]: return false
-      inc(i)
+func startsWith*(s, prefix: cstring): bool {.rtl, extern: "csuStartsWith".} =
+  ## Returns true if `s` starts with `prefix`.
+  ## 
+  ## JS backend uses native `String.prototype.startsWith`.
+  runnableExamples:
+    assert startsWith(cstring"Hello, Nimion", cstring"Hello")
+    assert not startsWith(cstring"Hello, Nimion", cstring"Nimion")
+    assert startsWith(cstring"Hello", cstring"")
+  when nimvm:
+    startsWithImpl(s, prefix)
+  else:
+    when defined(js):
+      result = jsStartsWith(s, prefix)
+    else:
+      var i = 0
+      while true:
+        if prefix[i] == '\0': return true
+        if s[i] != prefix[i]: return false
+        inc(i)
 
-  func endsWith*(s, suffix: cstring): bool {.rtl, extern: "csuEndsWith".} =
-    ## Returns true if `s` ends with `suffix`.
-    ##
-    ## If `suffix == ""` true is returned.
-    ##
-    ## JS backend uses native `String.prototype.endsWith`.
-    runnableExamples:
-      assert endsWith(cstring"Hello, Nimion", cstring"Nimion")
-      assert not endsWith(cstring"Hello, Nimion", cstring"Hello")
+func endsWith*(s, suffix: cstring): bool {.rtl, extern: "csuEndsWith".} =
+  ## Returns true if `s` ends with `suffix`.
+  ##
+  ## JS backend uses native `String.prototype.endsWith`.
+  runnableExamples:
+    assert endsWith(cstring"Hello, Nimion", cstring"Nimion")
+    assert not endsWith(cstring"Hello, Nimion", cstring"Hello")
+    assert endsWith(cstring"Hello", cstring"")
+  when nimvm:
+    endsWithImpl(s, suffix)
+  else:
+    when defined(js):
+      result = jsEndsWith(s, suffix)
+    else:
+      let slen = s.len
+      var i = 0
+      var j = slen - len(suffix)
+      while i+j <% slen:
+        if s[i+j] != suffix[i]: return false
+        inc(i)
+      if suffix[i] == '\0': return true
 
-    let slen = s.len
-    var i = 0
-    var j = slen - len(suffix)
-    while i+j <% slen:
-      if s[i+j] != suffix[i]: return false
-      inc(i)
-    if suffix[i] == '\0': return true
-
-  func cmpIgnoreStyle*(a, b: cstring): int {.rtl, extern: "csuCmpIgnoreStyle".} =
-    ## Semantically the same as `cmp(normalize($a), normalize($b))`. It
-    ## is just optimized to not allocate temporary strings.  This should
-    ## NOT be used to compare Nim identifier names. use `macros.eqIdent`
-    ## for that. Returns:
-    ##
-    ## .. code-block::
-    ##   0 if a == b
-    ##   < 0 if a < b
-    ##   > 0 if a > b
-    runnableExamples:
-      assert cmpIgnoreStyle(cstring"hello", cstring"H_e_L_Lo") == 0
-    var i = 0
-    var j = 0
-    while true:
-      while a[i] == '_': inc(i)
-      while b[j] == '_': inc(j) # BUGFIX: typo
-      var aa = toLowerAscii(a[i])
-      var bb = toLowerAscii(b[j])
-      result = ord(aa) - ord(bb)
-      if result != 0 or aa == '\0': break
-      inc(i)
-      inc(j)
-
-  func cmpIgnoreCase*(a, b: cstring): int {.rtl, extern: "csuCmpIgnoreCase".} =
-    ## Compares two strings in a case insensitive manner. Returns:
-    ##
-    ## .. code-block::
-    ##   0 if a == b
-    ##   < 0 if a < b
-    ##   > 0 if a > b
-    runnableExamples:
-      assert cmpIgnoreCase(cstring"hello", cstring"HeLLo") == 0
-      assert cmpIgnoreCase(cstring"echo", cstring"hello") < 0
-      assert cmpIgnoreCase(cstring"yellow", cstring"hello") > 0
+func cmpIgnoreStyle*(a, b: cstring): int {.rtl, extern: "csuCmpIgnoreStyle".} =
+  ## Semantically the same as `cmp(normalize($a), normalize($b))`. It
+  ## is just optimized to not allocate temporary strings.  This should
+  ## NOT be used to compare Nim identifier names. use `macros.eqIdent`
+  ## for that. Returns:
+  ##
+  ## .. code-block::
+  ##   0 if a == b
+  ##   < 0 if a < b
+  ##   > 0 if a > b
+  runnableExamples:
+    assert cmpIgnoreStyle(cstring"hello", cstring"H_e_L_Lo") == 0
+  when nimvm:
+    cmpIgnoreStyleImpl(a, b)
+  else:
+    when defined(js):
+      cmpIgnoreStyleImpl(a, b)
+    else:
+      var i = 0
+      var j = 0
+      while true:
+        while a[i] == '_': inc(i)
+        while b[j] == '_': inc(j) # BUGFIX: typo
+        var aa = toLowerAscii(a[i])
+        var bb = toLowerAscii(b[j])
+        result = ord(aa) - ord(bb)
+        if result != 0 or aa == '\0': break
+        inc(i)
+        inc(j)
 
-    var i = 0
-    while true:
-      var aa = toLowerAscii(a[i])
-      var bb = toLowerAscii(b[i])
-      result = ord(aa) - ord(bb)
-      if result != 0 or aa == '\0': break
-      inc(i)
+func cmpIgnoreCase*(a, b: cstring): int {.rtl, extern: "csuCmpIgnoreCase".} =
+  ## Compares two strings in a case insensitive manner. Returns:
+  ##
+  ## .. code-block::
+  ##   0 if a == b
+  ##   < 0 if a < b
+  ##   > 0 if a > b
+  runnableExamples:
+    assert cmpIgnoreCase(cstring"hello", cstring"HeLLo") == 0
+    assert cmpIgnoreCase(cstring"echo", cstring"hello") < 0
+    assert cmpIgnoreCase(cstring"yellow", cstring"hello") > 0
+  when nimvm:
+    cmpIgnoreCaseImpl(a, b)
+  else:
+    when defined(js):
+      cmpIgnoreCaseImpl(a, b)
+    else:
+      var i = 0
+      while true:
+        var aa = toLowerAscii(a[i])
+        var bb = toLowerAscii(b[i])
+        result = ord(aa) - ord(bb)
+        if result != 0 or aa == '\0': break
+        inc(i)
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim
index b1418a3ec..a25df9e42 100644
--- a/lib/pure/strutils.nim
+++ b/lib/pure/strutils.nim
@@ -81,7 +81,7 @@ when defined(nimVmExportFixed):
 
 include "system/inclrtl"
 import std/private/since
-from std/private/strimpl import cmpIgnoreStyleImpl, cmpIgnoreCaseImpl
+from std/private/strimpl import cmpIgnoreStyleImpl, cmpIgnoreCaseImpl, startsWithImpl, endsWithImpl
 
 
 const
@@ -1530,11 +1530,7 @@ func startsWith*(s, prefix: string): bool {.rtl, extern: "nsuStartsWith".} =
     let a = "abracadabra"
     doAssert a.startsWith("abra") == true
     doAssert a.startsWith("bra") == false
-  var i = 0
-  while true:
-    if i >= prefix.len: return true
-    if i >= s.len or s[i] != prefix[i]: return false
-    inc(i)
+  startsWithImpl(s, prefix)
 
 func endsWith*(s: string, suffix: char): bool {.inline.} =
   ## Returns true if `s` ends with `suffix`.
@@ -1562,12 +1558,7 @@ func endsWith*(s, suffix: string): bool {.rtl, extern: "nsuEndsWith".} =
     let a = "abracadabra"
     doAssert a.endsWith("abra") == true
     doAssert a.endsWith("dab") == false
-  var i = 0
-  var j = len(s) - len(suffix)
-  while i+j >= 0 and i+j < s.len:
-    if s[i+j] != suffix[i]: return false
-    inc(i)
-  if i >= suffix.len: return true
+  endsWithImpl(s, suffix)
 
 func continuesWith*(s, substr: string, start: Natural): bool {.rtl,
     extern: "nsuContinuesWith".} =