parent
0c4bd65e8d
commit
c04f305bf7
4 changed files with 132 additions and 104 deletions
|
|
@ -16,29 +16,24 @@ import std/private/strimpl
|
||||||
|
|
||||||
|
|
||||||
when defined(js):
|
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".} =
|
func startsWith*(s, prefix: cstring): bool {.rtl, extern: "csuStartsWith".} =
|
||||||
## Returns true if `s` starts with `prefix`.
|
## Returns true if `s` starts with `prefix`.
|
||||||
##
|
##
|
||||||
## If `prefix == ""` true is returned.
|
|
||||||
##
|
|
||||||
## JS backend uses native `String.prototype.startsWith`.
|
## JS backend uses native `String.prototype.startsWith`.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
assert startsWith(cstring"Hello, Nimion", cstring"Hello")
|
assert startsWith(cstring"Hello, Nimion", cstring"Hello")
|
||||||
assert not startsWith(cstring"Hello, Nimion", cstring"Nimion")
|
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
|
var i = 0
|
||||||
while true:
|
while true:
|
||||||
if prefix[i] == '\0': return true
|
if prefix[i] == '\0': return true
|
||||||
|
|
@ -48,13 +43,17 @@ else:
|
||||||
func endsWith*(s, suffix: cstring): bool {.rtl, extern: "csuEndsWith".} =
|
func endsWith*(s, suffix: cstring): bool {.rtl, extern: "csuEndsWith".} =
|
||||||
## Returns true if `s` ends with `suffix`.
|
## Returns true if `s` ends with `suffix`.
|
||||||
##
|
##
|
||||||
## If `suffix == ""` true is returned.
|
|
||||||
##
|
|
||||||
## JS backend uses native `String.prototype.endsWith`.
|
## JS backend uses native `String.prototype.endsWith`.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
assert endsWith(cstring"Hello, Nimion", cstring"Nimion")
|
assert endsWith(cstring"Hello, Nimion", cstring"Nimion")
|
||||||
assert not endsWith(cstring"Hello, Nimion", cstring"Hello")
|
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
|
let slen = s.len
|
||||||
var i = 0
|
var i = 0
|
||||||
var j = slen - len(suffix)
|
var j = slen - len(suffix)
|
||||||
|
|
@ -75,6 +74,12 @@ else:
|
||||||
## > 0 if a > b
|
## > 0 if a > b
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
assert cmpIgnoreStyle(cstring"hello", cstring"H_e_L_Lo") == 0
|
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 i = 0
|
||||||
var j = 0
|
var j = 0
|
||||||
while true:
|
while true:
|
||||||
|
|
@ -98,7 +103,12 @@ else:
|
||||||
assert cmpIgnoreCase(cstring"hello", cstring"HeLLo") == 0
|
assert cmpIgnoreCase(cstring"hello", cstring"HeLLo") == 0
|
||||||
assert cmpIgnoreCase(cstring"echo", cstring"hello") < 0
|
assert cmpIgnoreCase(cstring"echo", cstring"hello") < 0
|
||||||
assert cmpIgnoreCase(cstring"yellow", 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
|
var i = 0
|
||||||
while true:
|
while true:
|
||||||
var aa = toLowerAscii(a[i])
|
var aa = toLowerAscii(a[i])
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ when defined(nimVmExportFixed):
|
||||||
|
|
||||||
include "system/inclrtl"
|
include "system/inclrtl"
|
||||||
import std/private/since
|
import std/private/since
|
||||||
from std/private/strimpl import cmpIgnoreStyleImpl, cmpIgnoreCaseImpl
|
from std/private/strimpl import cmpIgnoreStyleImpl, cmpIgnoreCaseImpl, startsWithImpl, endsWithImpl
|
||||||
|
|
||||||
|
|
||||||
const
|
const
|
||||||
|
|
@ -1530,11 +1530,7 @@ func startsWith*(s, prefix: string): bool {.rtl, extern: "nsuStartsWith".} =
|
||||||
let a = "abracadabra"
|
let a = "abracadabra"
|
||||||
doAssert a.startsWith("abra") == true
|
doAssert a.startsWith("abra") == true
|
||||||
doAssert a.startsWith("bra") == false
|
doAssert a.startsWith("bra") == false
|
||||||
var i = 0
|
startsWithImpl(s, prefix)
|
||||||
while true:
|
|
||||||
if i >= prefix.len: return true
|
|
||||||
if i >= s.len or s[i] != prefix[i]: return false
|
|
||||||
inc(i)
|
|
||||||
|
|
||||||
func endsWith*(s: string, suffix: char): bool {.inline.} =
|
func endsWith*(s: string, suffix: char): bool {.inline.} =
|
||||||
## Returns true if `s` ends with `suffix`.
|
## Returns true if `s` ends with `suffix`.
|
||||||
|
|
@ -1562,12 +1558,7 @@ func endsWith*(s, suffix: string): bool {.rtl, extern: "nsuEndsWith".} =
|
||||||
let a = "abracadabra"
|
let a = "abracadabra"
|
||||||
doAssert a.endsWith("abra") == true
|
doAssert a.endsWith("abra") == true
|
||||||
doAssert a.endsWith("dab") == false
|
doAssert a.endsWith("dab") == false
|
||||||
var i = 0
|
endsWithImpl(s, suffix)
|
||||||
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
|
|
||||||
|
|
||||||
func continuesWith*(s, substr: string, start: Natural): bool {.rtl,
|
func continuesWith*(s, substr: string, start: Natural): bool {.rtl,
|
||||||
extern: "nsuContinuesWith".} =
|
extern: "nsuContinuesWith".} =
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,13 @@ func toLowerAscii*(c: char): char {.inline.} =
|
||||||
else:
|
else:
|
||||||
result = c
|
result = c
|
||||||
|
|
||||||
template firstCharCaseSensitiveImpl(a, b: typed, aLen, bLen: int) =
|
template firstCharCaseSensitiveImpl[T: string | cstring](a, b: T, aLen, bLen: int) =
|
||||||
if aLen == 0 or bLen == 0:
|
if aLen == 0 or bLen == 0:
|
||||||
return aLen - bLen
|
return aLen - bLen
|
||||||
if a[0] != b[0]: return ord(a[0]) - ord(b[0])
|
if a[0] != b[0]: return ord(a[0]) - ord(b[0])
|
||||||
|
|
||||||
template cmpIgnoreStyleImpl*(a, b: typed, firstCharCaseSensitive: static bool = false) =
|
template cmpIgnoreStyleImpl*[T: string | cstring](a, b: T,
|
||||||
# a, b are string or cstring
|
firstCharCaseSensitive: static bool = false) =
|
||||||
let aLen = a.len
|
let aLen = a.len
|
||||||
let bLen = b.len
|
let bLen = b.len
|
||||||
var i = 0
|
var i = 0
|
||||||
|
|
@ -37,8 +37,8 @@ template cmpIgnoreStyleImpl*(a, b: typed, firstCharCaseSensitive: static bool =
|
||||||
inc i
|
inc i
|
||||||
inc j
|
inc j
|
||||||
|
|
||||||
template cmpIgnoreCaseImpl*(a, b: typed, firstCharCaseSensitive: static bool = false) =
|
template cmpIgnoreCaseImpl*[T: string | cstring](a, b: T,
|
||||||
# a, b are string or cstring
|
firstCharCaseSensitive: static bool = false) =
|
||||||
let aLen = a.len
|
let aLen = a.len
|
||||||
let bLen = b.len
|
let bLen = b.len
|
||||||
var i = 0
|
var i = 0
|
||||||
|
|
@ -51,3 +51,22 @@ template cmpIgnoreCaseImpl*(a, b: typed, firstCharCaseSensitive: static bool = f
|
||||||
if result != 0: return
|
if result != 0: return
|
||||||
inc i
|
inc i
|
||||||
result = aLen - bLen
|
result = aLen - bLen
|
||||||
|
|
||||||
|
template startsWithImpl*[T: string | cstring](s, prefix: T) =
|
||||||
|
let prefixLen = prefix.len
|
||||||
|
let sLen = s.len
|
||||||
|
var i = 0
|
||||||
|
while true:
|
||||||
|
if i >= prefixLen: return true
|
||||||
|
if i >= sLen or s[i] != prefix[i]: return false
|
||||||
|
inc(i)
|
||||||
|
|
||||||
|
template endsWithImpl*[T: string | cstring](s, suffix: T) =
|
||||||
|
let suffixLen = suffix.len
|
||||||
|
let sLen = s.len
|
||||||
|
var i = 0
|
||||||
|
var j = sLen - suffixLen
|
||||||
|
while i+j >= 0 and i+j < sLen:
|
||||||
|
if s[i+j] != suffix[i]: return false
|
||||||
|
inc(i)
|
||||||
|
if i >= suffixLen: return true
|
||||||
|
|
|
||||||
|
|
@ -2,21 +2,25 @@ discard """
|
||||||
targets: "c cpp js"
|
targets: "c cpp js"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import cstrutils
|
import std/cstrutils
|
||||||
|
|
||||||
|
|
||||||
block tcstrutils:
|
proc main() =
|
||||||
let s = cstring "abcdef"
|
let s = cstring "abcdef"
|
||||||
doAssert s.startsWith("a")
|
doAssert s.startsWith("a")
|
||||||
doAssert not s.startsWith("b")
|
doAssert not s.startsWith("b")
|
||||||
doAssert s.endsWith("f")
|
doAssert s.endsWith("f")
|
||||||
doAssert not s.endsWith("a")
|
doAssert not s.endsWith("a")
|
||||||
|
doAssert s.startsWith("")
|
||||||
|
doAssert s.endsWith("")
|
||||||
|
|
||||||
let a = cstring "abracadabra"
|
let a = cstring "abracadabra"
|
||||||
doAssert a.startsWith("abra")
|
doAssert a.startsWith("abra")
|
||||||
doAssert not a.startsWith("bra")
|
doAssert not a.startsWith("bra")
|
||||||
doAssert a.endsWith("abra")
|
doAssert a.endsWith("abra")
|
||||||
doAssert not a.endsWith("dab")
|
doAssert not a.endsWith("dab")
|
||||||
|
doAssert a.startsWith("")
|
||||||
|
doAssert a.endsWith("")
|
||||||
|
|
||||||
doAssert cmpIgnoreCase(cstring "FooBar", "foobar") == 0
|
doAssert cmpIgnoreCase(cstring "FooBar", "foobar") == 0
|
||||||
doAssert cmpIgnoreCase(cstring "bar", "Foo") < 0
|
doAssert cmpIgnoreCase(cstring "bar", "Foo") < 0
|
||||||
|
|
@ -28,3 +32,7 @@ block tcstrutils:
|
||||||
doAssert cmpIgnoreCase(cstring "", cstring "") == 0
|
doAssert cmpIgnoreCase(cstring "", cstring "") == 0
|
||||||
doAssert cmpIgnoreCase(cstring "", cstring "Hello") < 0
|
doAssert cmpIgnoreCase(cstring "", cstring "Hello") < 0
|
||||||
doAssert cmpIgnoreCase(cstring "wind", cstring "") > 0
|
doAssert cmpIgnoreCase(cstring "wind", cstring "") > 0
|
||||||
|
|
||||||
|
|
||||||
|
static: main()
|
||||||
|
main()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue