From 07f76c3ef94d13efcb861f92b19d1cfd56214bb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20D=C3=B6ring?= Date: Mon, 15 Oct 2018 19:20:24 +0200 Subject: [PATCH 1/7] fix compiler crash --- compiler/vmgen.nim | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index ea0fb35ff3..ff1dd391fb 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -182,7 +182,10 @@ const HighRegisterPressure = 40 proc bestEffort(c: PCtx): TLineInfo = - (if c.prc == nil: c.module.info else: c.prc.sym.info) + if c.prc != nil and c.prc.sym != nil: + c.prc.sym.info + else: + c.module.info proc getTemp(cc: PCtx; tt: PType): TRegister = let typ = tt.skipTypesOrNil({tyStatic}) From f84bf45f17d2ec441ea455bd0387d11e4124654f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20D=C3=B6ring?= Date: Thu, 18 Oct 2018 08:34:15 +0200 Subject: [PATCH 2/7] set code owner --- compiler/sizealignoffsetimpl.nim | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/compiler/sizealignoffsetimpl.nim b/compiler/sizealignoffsetimpl.nim index dcff992a18..bc2fe9ad3d 100644 --- a/compiler/sizealignoffsetimpl.nim +++ b/compiler/sizealignoffsetimpl.nim @@ -1,3 +1,12 @@ +# +# +# The Nim Compiler +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# +## code owner: Arne Döring +## e-mail: arne.doering@gmx.net proc align(address, alignment: BiggestInt): BiggestInt = result = (address + (alignment - 1)) and not (alignment - 1) From bab9e0020a49ab9e5aa00d4d8761e3465075241d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20D=C3=B6ring?= Date: Thu, 25 Oct 2018 13:42:04 +0200 Subject: [PATCH 3/7] fixes #5549 --- compiler/ccgstmts.nim | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 5ebe0323d1..9015c57a58 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -509,7 +509,7 @@ proc genWhileStmt(p: BProc, t: PNode) = # for closure support weird loop bodies are generated: if loopBody.len == 2 and loopBody.sons[0].kind == nkEmpty: loopBody = loopBody.sons[1] - genComputedGoto(p, loopBody) # TODO foobar + genComputedGoto(p, loopBody) else: p.breakIdx = startBlock(p, "while (1) {$n") p.blocks[p.breakIdx].isLoop = true @@ -874,15 +874,15 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) = discard pop(p.nestedTryStmts) - if not catchAllPresent and t[^1].kind == nkFinally: - # finally requires catch all presence - startBlock(p, "catch (...) {$n") - genSimpleBlock(p, t[^1][0]) - line(p, cpsStmts, ~"throw;$n") - endBlock(p) - if t[^1].kind == nkFinally: - genSimpleBlock(p, t[^1][0]) + if catchAllPresent: + genSimpleBlock(p, t[^1][0]) + else: + # finally requires catch all presence + startBlock(p, "catch (...) {$n") + genSimpleBlock(p, t[^1][0]) + line(p, cpsStmts, ~"throw;$n") + endBlock(p) proc genTry(p: BProc, t: PNode, d: var TLoc) = # code to generate: From cf3d206b9e0c4afea9944954199cc2b7dabe1c69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20D=C3=B6ring?= Date: Tue, 30 Oct 2018 16:35:48 +0100 Subject: [PATCH 4/7] undo try break --- compiler/ccgstmts.nim | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 9015c57a58..3665a7e85d 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -875,15 +875,16 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) = discard pop(p.nestedTryStmts) if t[^1].kind == nkFinally: - if catchAllPresent: - genSimpleBlock(p, t[^1][0]) - else: + # c++ does not have finally, therefore code needs to be generated twice + if not catchAllPresent: # finally requires catch all presence startBlock(p, "catch (...) {$n") - genSimpleBlock(p, t[^1][0]) + genStmts(p, t[^1][0]) line(p, cpsStmts, ~"throw;$n") endBlock(p) + genSimpleBlock(p, t[^1][0]) + proc genTry(p: BProc, t: PNode, d: var TLoc) = # code to generate: # From e6531216339655cd5bf9537afca3e493e4a8e0b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20D=C3=B6ring?= Date: Tue, 30 Oct 2018 17:13:02 +0100 Subject: [PATCH 5/7] fixes #9557 --- lib/pure/strutils.nim | 66 ++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index e266275cf8..5fedfa57e1 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -149,8 +149,8 @@ proc isAlphaAscii*(s: string): bool {.noSideEffect, procvar, ## in `s`. runnableExamples: doAssert isAlphaAscii("fooBar") == true - doAssert isAlphaAscii("fooBar1") == false - doAssert isAlphaAscii("foo Bar") == false + doAssert isAlphaAscii("fooBar1") == false + doAssert isAlphaAscii("foo Bar") == false isImpl isAlphaAscii proc isAlphaNumeric*(s: string): bool {.noSideEffect, procvar, @@ -164,7 +164,7 @@ proc isAlphaNumeric*(s: string): bool {.noSideEffect, procvar, ## in `s`. runnableExamples: doAssert isAlphaNumeric("fooBar") == true - doAssert isAlphaNumeric("fooBar") == true + doAssert isAlphaNumeric("fooBar") == true doAssert isAlphaNumeric("foo Bar") == false isImpl isAlphaNumeric @@ -179,7 +179,7 @@ proc isDigit*(s: string): bool {.noSideEffect, procvar, ## in `s`. runnableExamples: doAssert isDigit("1908") == true - doAssert isDigit("fooBar1") == false + doAssert isDigit("fooBar1") == false isImpl isDigit proc isSpaceAscii*(s: string): bool {.noSideEffect, procvar, @@ -191,7 +191,7 @@ proc isSpaceAscii*(s: string): bool {.noSideEffect, procvar, ## characters and there is at least one character in `s`. runnableExamples: doAssert isSpaceAscii(" ") == true - doAssert isSpaceAscii("") == false + doAssert isSpaceAscii("") == false isImpl isSpaceAscii template isCaseImpl(s, charProc, skipNonAlpha) = @@ -420,7 +420,7 @@ proc toOctal*(c: char): string {.noSideEffect, rtl, extern: "nsuToOctal".} = ## The resulting string may not have a leading zero. Its length is always ## exactly 3. runnableExamples: - doAssert toOctal('!') == "041" + doAssert toOctal('!') == "041" result = newString(3) var val = ord(c) for i in countdown(2, 0): @@ -933,7 +933,7 @@ proc intToStr*(x: int, minchars: Positive = 1): string {.noSideEffect, ## achieved by adding leading zeros. runnableExamples: doAssert intToStr(1984) == "1984" - doAssert intToStr(1984, 6) == "001984" + doAssert intToStr(1984, 6) == "001984" result = $abs(x) for i in 1 .. minchars - len(result): result = '0' & result @@ -1525,6 +1525,8 @@ proc rfind*(s, sub: string, start: int = -1): int {.noSideEffect.} = ## backwards to 0. ## ## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned. + if sub.len == 0: + return -1 let realStart = if start == -1: s.len else: start for i in countdown(realStart-sub.len, 0): for j in 0..sub.len-1: @@ -1632,11 +1634,7 @@ proc replace*(s, sub: string, by = ""): string {.noSideEffect, result = "" let subLen = sub.len if subLen == 0: - for c in s: - add result, by - add result, c - add result, by - return + result = s elif subLen == 1: # when the pattern is a single char, we use a faster # char-based search that doesn't need a skip table: @@ -1691,21 +1689,22 @@ proc replaceWord*(s, sub: string, by = ""): string {.noSideEffect, initSkipTable(a, sub) var i = 0 let last = s.high - let sublen = max(sub.len, 1) - while true: - var j = find(a, s, sub, i, last) - if j < 0: break - # word boundary? - if (j == 0 or s[j-1] notin wordChars) and - (j+sub.len >= s.len or s[j+sub.len] notin wordChars): - add result, substr(s, i, j - 1) - add result, by - i = j + sublen - else: - add result, substr(s, i, j) - i = j + 1 - # copy the rest: - add result, substr(s, i) + let sublen = sub.len + if sublen > 0: + while true: + var j = find(a, s, sub, i, last) + if j < 0: break + # word boundary? + if (j == 0 or s[j-1] notin wordChars) and + (j+sub.len >= s.len or s[j+sub.len] notin wordChars): + add result, substr(s, i, j - 1) + add result, by + i = j + sublen + else: + add result, substr(s, i, j) + i = j + 1 + # copy the rest: + add result, substr(s, i) proc multiReplace*(s: string, replacements: varargs[(string, string)]): string {.noSideEffect.} = ## Same as replace, but specialized for doing multiple replacements in a single @@ -1722,15 +1721,18 @@ proc multiReplace*(s: string, replacements: varargs[(string, string)]): string { result = newStringOfCap(s.len) var i = 0 var fastChk: set[char] = {} - for tup in replacements: fastChk.incl(tup[0][0]) # Include first character of all replacements + for sub, by in replacements.items: + if sub.len > 0: + # Include first character of all replacements + fastChk.incl sub[0] while i < s.len: block sIteration: # Assume most chars in s are not candidates for any replacement operation if s[i] in fastChk: - for tup in replacements: - if s.continuesWith(tup[0], i): - add result, tup[1] - inc(i, tup[0].len) + for sub, by in replacements.items: + if sub.len > 0 and s.continuesWith(sub[0], i): + add result, by + inc(i, sub.len) break sIteration # No matching replacement found # copy current character from s From 84db658eb4cf8f1d8ed8dd5c890257c1ce067362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20D=C3=B6ring?= Date: Wed, 31 Oct 2018 10:44:44 +0100 Subject: [PATCH 6/7] fix typo --- lib/pure/strutils.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 5fedfa57e1..1285f0e1c4 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -1730,7 +1730,7 @@ proc multiReplace*(s: string, replacements: varargs[(string, string)]): string { # Assume most chars in s are not candidates for any replacement operation if s[i] in fastChk: for sub, by in replacements.items: - if sub.len > 0 and s.continuesWith(sub[0], i): + if sub.len > 0 and s.continuesWith(sub, i): add result, by inc(i, sub.len) break sIteration From 80843373ba2e944b4b3b76d01264cbdfe70588ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20D=C3=B6ring?= Date: Wed, 31 Oct 2018 14:29:40 +0100 Subject: [PATCH 7/7] changelog entry --- changelog.md | 2 ++ lib/pure/strutils.nim | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 21b7b16a07..10c6663126 100644 --- a/changelog.md +++ b/changelog.md @@ -55,6 +55,8 @@ proc enumToString*(enums: openArray[enum]): string = slightly. The `dumpLisp` macro in this module now outputs an indented proper Lisp, devoid of commas. +- In `strutils` empty strings now no longer matched as substrings anymore. + ### Language additions - Vm suport for float32<->int32 and float64<->int64 casts was added. diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 1285f0e1c4..d3d2fe8a07 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -2614,7 +2614,7 @@ when isMainModule: doAssert "-lda-ldz -ld abc".replaceWord("-ld") == "-lda-ldz abc" doAssert "-lda-ldz -ld abc".replaceWord("") == "-lda-ldz -ld abc" - doAssert "oo".replace("", "abc") == "abcoabcoabc" + doAssert "oo".replace("", "abc") == "oo" type MyEnum = enum enA, enB, enC, enuD, enE doAssert parseEnum[MyEnum]("enu_D") == enuD