cmp(x, y: string) now uses memcmp rather than strcmp (#6869) (#6968)

This commit is contained in:
Mathias Stearn 2017-12-24 09:23:17 -05:00 • committed by Andreas Rumpf
commit 6bd3a2826f
3 changed files with 28 additions and 5 deletions

View file

@ -2916,7 +2916,10 @@ when not defined(JS): #and not defined(nimscript):
elif x > y: result = 1 elif x > y: result = 1
else: result = 0 else: result = 0
else: else:
result = int(c_strcmp(x, y)) let minlen = min(x.len, y.len)
result = int(c_memcmp(x.cstring, y.cstring, minlen.csize))
if result == 0:
result = x.len - y.len
when defined(nimscript): when defined(nimscript):
proc readFile*(filename: string): string {.tags: [ReadIOEffect], benign.} proc readFile*(filename: string): string {.tags: [ReadIOEffect], benign.}

View file

@ -24,10 +24,10 @@ proc cmpStrings(a, b: NimString): int {.inline, compilerProc.} =
if a == b: return 0 if a == b: return 0
if a == nil: return -1 if a == nil: return -1
if b == nil: return 1 if b == nil: return 1
when defined(nimNoArrayToCstringConversion): let minlen = min(a.len, b.len)
return c_strcmp(addr a.data, addr b.data) result = c_memcmp(addr a.data, addr b.data, minlen.csize)
else: if result == 0:
return c_strcmp(a.data, b.data) result = a.len - b.len
proc eqStrings(a, b: NimString): bool {.inline, compilerProc.} = proc eqStrings(a, b: NimString): bool {.inline, compilerProc.} =
if a == b: return true if a == b: return true

View file

@ -56,4 +56,24 @@ proc test_string_slice() =
echo("OK") echo("OK")
proc test_string_cmp() =
let world = "hello\0world"
let earth = "hello\0earth"
let short = "hello\0"
let hello = "hello"
let goodbye = "goodbye"
doAssert world == world
doAssert world != earth
doAssert world != short
doAssert world != hello
doAssert world != goodbye
doAssert cmp(world, world) == 0
doAssert cmp(world, earth) > 0
doAssert cmp(world, short) > 0
doAssert cmp(world, hello) > 0
doAssert cmp(world, goodbye) > 0
test_string_slice() test_string_slice()
test_string_cmp()