From e78d9f4c76156121aeb176c7b3edeaf987e9e9e5 Mon Sep 17 00:00:00 2001 From: flywind Date: Sat, 26 Dec 2020 22:29:02 +0800 Subject: [PATCH 1/2] fix nim js cmp fails at CT --- lib/system.nim | 10 ++-------- lib/system/jssys.nim | 7 ++++++- tests/misc/tstrtabs.nim | 20 ++++++++++++++++++++ tests/stdlib/tstring.nim | 36 +++++++++++++++++++++--------------- 4 files changed, 49 insertions(+), 24 deletions(-) create mode 100644 tests/misc/tstrtabs.nim diff --git a/lib/system.nim b/lib/system.nim index 85ef15e08f48..fb008dc452fd 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2394,14 +2394,8 @@ when notJSnotNims: """.} when defined(js): - when not defined(nimscript): - include "system/jssys" - include "system/reprjs" - else: - proc cmp(x, y: string): int = - if x == y: return 0 - if x < y: return -1 - return 1 + include "system/jssys" + include "system/reprjs" when defined(js) or defined(nimscript): proc addInt*(result: var string; x: int64) = diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 8865558fe553..7848a435e38a 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -341,7 +341,12 @@ proc cmpStrings(a, b: string): int {.asmNoStackFrame, compilerproc.} = """ proc cmp(x, y: string): int = - return cmpStrings(x, y) + when nimvm: + if x == y: result = 0 + elif x < y: result = -1 + else: result = 1 + else: + result = cmpStrings(x, y) proc eqStrings(a, b: string): bool {.asmNoStackFrame, compilerproc.} = asm """ diff --git a/tests/misc/tstrtabs.nim b/tests/misc/tstrtabs.nim new file mode 100644 index 000000000000..2f7eda9f7ae9 --- /dev/null +++ b/tests/misc/tstrtabs.nim @@ -0,0 +1,20 @@ +discard """ + targets: "c cpp js" +""" + +import std/strtabs + +proc fun()= + let ret = newStringTable(modeCaseSensitive) + ret["foo"] = "bar" + + doAssert $ret == "{foo: bar}" + + let b = ret["foo"] + doAssert b == "bar" + +proc main()= + static: fun() + fun() + +main() diff --git a/tests/stdlib/tstring.nim b/tests/stdlib/tstring.nim index ff3d41b49287..4d5a15940e9c 100644 --- a/tests/stdlib/tstring.nim +++ b/tests/stdlib/tstring.nim @@ -1,16 +1,14 @@ discard """ - output: '''OK -@[@[], @[], @[], @[], @[]] -''' + targets: "c cpp js" """ + const characters = "abcdefghijklmnopqrstuvwxyz" const numbers = "1234567890" -var s: string - proc test_string_slice() = # test "slice of length == len(characters)": # replace characters completely by numbers + var s: string s = characters s[0..^1] = numbers doAssert s == numbers @@ -51,11 +49,13 @@ proc test_string_slice() = s[2..0] = numbers doAssert s == "ab1234567890cdefghijklmnopqrstuvwxyz" - # bug #6223 - doAssertRaises(IndexDefect): - discard s[0..999] + when nimvm: + discard + else: + # bug #6223 + doAssertRaises(IndexDefect): + discard s[0..999] - echo("OK") proc test_string_cmp() = let world = "hello\0world" @@ -76,9 +76,6 @@ proc test_string_cmp() = doAssert cmp(world, hello) > 0 doAssert cmp(world, goodbye) > 0 -test_string_slice() -test_string_cmp() - #-------------------------- # bug #7816 @@ -87,9 +84,9 @@ import sequtils proc tester[T](x: T) = let test = toSeq(0..4).map(i => newSeq[int]()) - echo test + doAssert $test == "@[@[], @[], @[], @[], @[]]" + -tester(1) # #14497 func reverse*(a: string): string = @@ -97,4 +94,13 @@ func reverse*(a: string): string = for i in 0 ..< a.len div 2: swap(result[i], result[^(i + 1)]) -doAssert reverse("hello") == "olleh" + +proc main() = + test_string_slice() + test_string_cmp() + + tester(1) + doAssert reverse("hello") == "olleh" + +static: main() +main() From 38ffc8be415c78977ec1eb21c6a6b3668c9631d7 Mon Sep 17 00:00:00 2001 From: flywind Date: Wed, 31 Mar 2021 21:10:12 +0800 Subject: [PATCH 2/2] fix --- lib/impure/re.nim | 20 ++++++++++++++++++-- tests/stdlib/tre.nim | 9 ++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/lib/impure/re.nim b/lib/impure/re.nim index 0c96876b914b..4ba5e20ec258 100644 --- a/lib/impure/re.nim +++ b/lib/impure/re.nim @@ -199,6 +199,18 @@ proc findBounds*(s: string, pattern: Regex, ## `(-1,0)` is returned. result = findBounds(cstring(s), pattern, matches, start, s.len) +proc findBoundsImpl(buf: cstring, pattern: Regex, + start = 0, bufSize = 0, flags = 0): tuple[first, last: int] = + var rtarray = initRtArray[cint](3) + let rawMatches = rtarray.getRawData + let res = pcre.exec(pattern.h, pattern.e, buf, bufSize.cint, start.cint, flags.int32, + cast[ptr cint](rawMatches), 3) + + if res < 0'i32: + result = (-1, 0) + else: + result = (int(rawMatches[0]), int(rawMatches[1]-1)) + proc findBounds*(buf: cstring, pattern: Regex, start = 0, bufSize: int): tuple[first, last: int] = ## returns the `first` and `last` position of `pattern` in `buf`, @@ -433,12 +445,16 @@ proc replace*(s: string, sub: Regex, by = ""): string = doAssert "var1=key; var2=key2".replace(re"(\w+)=(\w+)", "?") == "?; ?" result = "" var prev = 0 + var flags = int32(0) while prev < s.len: - var match = findBounds(s, sub, prev) + var match = findBoundsImpl(s.cstring, sub, prev, s.len, flags) + flags = 0 if match.first < 0: break add(result, substr(s, prev, match.first-1)) add(result, by) - if match.last + 1 == prev: break + if match.first > match.last: + # 0-len match + flags = pcre.NOTEMPTY_ATSTART prev = match.last + 1 add(result, substr(s, prev)) diff --git a/tests/stdlib/tre.nim b/tests/stdlib/tre.nim index ea1b5af32cc3..2857c6c9e587 100644 --- a/tests/stdlib/tre.nim +++ b/tests/stdlib/tre.nim @@ -99,10 +99,13 @@ proc testAll() = accum.add($x) doAssert(accum == @["a","b","c"]) - block: - # bug #9306 + block: # bug #9306 doAssert replace("bar", re"^", "foo") == "foobar" - doAssert replace("foo", re"", "-") == "-foo" doAssert replace("foo", re"$", "bar") == "foobar" + + block: # bug #9437 + doAssert replace("foo", re"", "-") == "-f-o-o-" + doAssert replace("ooo", re"o", "-") == "---" + testAll()