summary refs log tree commit diff stats
path: root/lib/system
diff options
context:
space:
mode:
authormetagn <metagngn@gmail.com>2022-09-01 19:10:00 +0300
committerGitHub <noreply@github.com>2022-09-01 18:10:00 +0200
commita95b6391fd353074daf2dbfed4d73e8d57f314ca (patch)
tree74b60b45b1f58010b3cadda3becf1bc79eb01cbd /lib/system
parent1f838d9af1a80580d08815ad6a11a8e7b2945c80 (diff)
downloadNim-a95b6391fd353074daf2dbfed4d73e8d57f314ca.tar.gz
support cstring in `case` (#20130)
* implement case for cstring

for now just converts to string on C backend

* custom implementation for cstring

* remove leftover

* revert even more

* add nil + fix packages weird variant literal bug

* update docs
Diffstat (limited to 'lib/system')
-rw-r--r--lib/system/strmantle.nim23
1 files changed, 23 insertions, 0 deletions
diff --git a/lib/system/strmantle.nim b/lib/system/strmantle.nim
index 9cf4f9e55..feaac7817 100644
--- a/lib/system/strmantle.nim
+++ b/lib/system/strmantle.nim
@@ -43,6 +43,29 @@ proc hashString(s: string): int {.compilerproc.} =
   h = h + h shl 15
   result = cast[int](h)
 
+proc eqCstrings(a, b: cstring): bool {.inline, compilerproc.} =
+  if pointer(a) == pointer(b): result = true
+  elif a.isNil or b.isNil: result = false
+  else: result = c_strcmp(a, b) == 0
+
+proc hashCstring(s: cstring): int {.compilerproc.} =
+  # the compiler needs exactly the same hash function!
+  # this used to be used for efficient generation of cstring case statements
+  if s.isNil: return 0
+  var h : uint = 0
+  var i = 0
+  while true:
+    let c = s[i]
+    if c == '\0': break
+    h = h + uint(c)
+    h = h + h shl 10
+    h = h xor (h shr 6)
+    inc i
+  h = h + h shl 3
+  h = h xor (h shr 11)
+  h = h + h shl 15
+  result = cast[int](h)
+
 proc c_strtod(buf: cstring, endptr: ptr cstring): float64 {.
   importc: "strtod", header: "<stdlib.h>", noSideEffect.}