diff --git a/compiler/msgs.nim b/compiler/msgs.nim index c0362693f..2c807806e 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -10,7 +10,7 @@ import std/[strutils, os, tables, terminal, macros, times], std/private/miscdollars, - options, lineinfos, pathutils, strutils2 + options, lineinfos, pathutils import ropes except `%` @@ -24,6 +24,10 @@ template instLoc*(): InstantiationInfo = instantiationInfo(-2, fullPaths = true) template toStdOrrKind(stdOrr): untyped = if stdOrr == stdout: stdOrrStdout else: stdOrrStderr +proc toLowerAscii(a: var string) {.inline.} = + for c in mitems(a): + if isUpperAscii(c): c = char(uint8(c) xor 0b0010_0000'u8) + proc flushDot*(conf: ConfigRef) = ## safe to call multiple times # xxx one edge case not yet handled is when `printf` is called at CT with `compiletimeFFI`. @@ -78,7 +82,7 @@ when defined(nimpretty): proc fileSection*(conf: ConfigRef; fid: FileIndex; a, b: int): string = substr(conf.m.fileInfos[fid.int].fullContent, a, b) -proc canonicalCase(path: var string) = +proc canonicalCase(path: var string) {.inline.} = ## the idea is to only use this for checking whether a path is already in ## the table but otherwise keep the original case when FileSystemCaseSensitive: discard @@ -101,16 +105,13 @@ proc fileInfoIdx*(conf: ConfigRef; filename: AbsoluteFile; isKnownFile: var bool try: canon = canonicalizePath(conf, filename) - when not defined(nimSeqsV2): - shallow(canon.string) except OSError: canon = filename # The compiler uses "filenames" such as `command line` or `stdin` # This flag indicates that we are working with such a path here pseudoPath = true - var canon2: string - forceCopy(canon2, canon.string) # because `canon` may be shallow + var canon2 = canon.string canon2.canonicalCase if conf.m.filenameToIndexTbl.hasKey(canon2): @@ -119,7 +120,6 @@ proc fileInfoIdx*(conf: ConfigRef; filename: AbsoluteFile; isKnownFile: var bool else: isKnownFile = false result = conf.m.fileInfos.len.FileIndex - #echo "ID ", result.int, " ", canon2 conf.m.fileInfos.add(newFileInfo(canon, if pseudoPath: RelativeFile filename else: relativeTo(canon, conf.projectPath))) conf.m.filenameToIndexTbl[canon2] = result diff --git a/compiler/strutils2.nim b/compiler/strutils2.nim deleted file mode 100644 index f44b811c7..000000000 --- a/compiler/strutils2.nim +++ /dev/null @@ -1,57 +0,0 @@ -##[ -internal API for now, subject to modifications and moving around - -string API's focusing on performance, that can be used as building blocks -for other routines. - -Un-necessary allocations are avoided and appropriate algorithms are used at the -expense of code clarity when justified. -]## - -proc dataPointer*[T](a: T): pointer = - ## same as C++ `data` that works with std::string, std::vector etc. - ## Note: safe to use when a.len == 0 but whether the result is nil or not - ## is implementation defined for performance reasons. - # this could be improved with ocmpiler support to avoid the `if`, e.g. in C++ - # `&a[0]` is well defined even if a.size() == 0 - when T is string | seq: - if a.len == 0: nil else: cast[pointer](a[0].unsafeAddr) - elif T is array: - when a.len > 0: a.unsafeAddr - else: nil - elif T is cstring: - cast[pointer](a) - else: static: doAssert false, $T - -proc setLen*(result: var string, n: int, isInit: bool) = - ## when isInit = false, elements are left uninitialized, analog to `{.noinit.}` - ## else, there are 0-initialized. - # xxx placeholder until system.setLen supports this - # to distinguish between algorithms that need 0-initialization vs not; note - # that `setLen` for string is inconsistent with `setLen` for seq. - # likwise with `newString` vs `newSeq`. This should be fixed in `system`. - let n0 = result.len - result.setLen(n) - if isInit and n > n0: - zeroMem(result[n0].addr, n - n0) - -proc forceCopy*(result: var string, a: string) = - ## also forces a copy if `a` is shallow - # the naitve `result = a` would not work if `a` is shallow - let n = a.len - result.setLen n, isInit = false - copyMem(result.dataPointer, a.dataPointer, n) - -proc isUpperAscii(c: char): bool {.inline.} = - # avoids import strutils.isUpperAscii - c in {'A'..'Z'} - -proc toLowerAscii*(a: var string) = - ## optimized and inplace overload of strutils.toLowerAscii - # refs https://github.com/timotheecour/Nim/pull/54 - # this is 10X faster than a naive implementation using a an optimization trick - # that can be adapted in similar contexts. Predictable writes avoid write - # hazards and lead to better machine code, compared to random writes arising - # from: `if c.isUpperAscii: c = ...` - for c in mitems(a): - c = chr(c.ord + (if c.isUpperAscii: (ord('a') - ord('A')) else: 0)) diff --git a/tests/stdlib/tstrutils2.nim b/tests/stdlib/tstrutils2.nim deleted file mode 100644 index 2cb5b8ec4..000000000 --- a/tests/stdlib/tstrutils2.nim +++ /dev/null @@ -1,39 +0,0 @@ -discard """ - matrix: "--gc:refc; --gc:orc" -""" - -import "$lib/.." / compiler/strutils2 -import std/assertions - -block: # setLen - var a = "abc" - a.setLen 0 - a.setLen 3, isInit = false - when defined(gcRefc): # bug #19763 - doAssert a[1] == 'b' - a.setLen 0 - a.setLen 3, isInit = true - doAssert a[1] == '\0' - -block: # forceCopy - var a: string - a = "foo" - when defined(gcRefc): - shallow(a) - var b: string - b = a - doAssert b[0].addr == a[0].addr - var c: string - c.forceCopy a - doAssert c == a - doAssert c[0].addr != a[0].addr - -block: # toLowerAscii - var a = "fooBAr" - a.toLowerAscii - doAssert a == "foobar" - -block: # dataPointer - var a: string - discard a.dataPointer - # doAssert a.dataPointer == nil # not guaranteed