diff options
author | Araq <rumpf_a@web.de> | 2017-02-25 11:18:48 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2017-02-25 11:18:48 +0100 |
commit | 1961e444c32903d5046f078630e90716c17dff62 (patch) | |
tree | 21334eb10390c005f162c6a821bd03d91f1e8b4b /lib/pure | |
parent | 667acb06a53a47f47dde29c381df0d4bcbf61b94 (diff) | |
parent | 16aafddee598da750dba378cca5bea0126fdf992 (diff) | |
download | Nim-1961e444c32903d5046f078630e90716c17dff62.tar.gz |
Merge branch 'devel' into feature/async-streams
Diffstat (limited to 'lib/pure')
-rw-r--r-- | lib/pure/algorithm.nim | 2 | ||||
-rw-r--r-- | lib/pure/asynchttpserver.nim | 4 | ||||
-rw-r--r-- | lib/pure/collections/heapqueue.nim | 41 | ||||
-rw-r--r-- | lib/pure/distros.nim | 2 | ||||
-rw-r--r-- | lib/pure/hashes.nim | 10 | ||||
-rw-r--r-- | lib/pure/httpcore.nim | 6 | ||||
-rw-r--r-- | lib/pure/json.nim | 9 | ||||
-rw-r--r-- | lib/pure/logging.nim | 2 | ||||
-rw-r--r-- | lib/pure/os.nim | 6 | ||||
-rw-r--r-- | lib/pure/parseutils.nim | 24 | ||||
-rw-r--r-- | lib/pure/strutils.nim | 4 | ||||
-rw-r--r-- | lib/pure/unittest.nim | 2 |
12 files changed, 74 insertions, 38 deletions
diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim index 739cdc16b..bc39f153b 100644 --- a/lib/pure/algorithm.nim +++ b/lib/pure/algorithm.nim @@ -46,7 +46,7 @@ proc reverse*[T](a: var openArray[T], first, last: Natural) = proc reverse*[T](a: var openArray[T]) = ## reverses the array `a`. - reverse(a, 0, a.high) + reverse(a, 0, max(0, a.high)) proc reversed*[T](a: openArray[T], first: Natural, last: int): seq[T] = ## returns the reverse of the array `a[first..last]`. diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim index a558d9d7e..672eb34a0 100644 --- a/lib/pure/asynchttpserver.nim +++ b/lib/pure/asynchttpserver.nim @@ -31,7 +31,7 @@ ## ## waitFor server.serve(Port(8080), cb) -import tables, asyncnet, asyncdispatch, parseutils, uri, strutils +import tables, asyncnet, asyncdispatch, parseutils, uri, strutils, nativesockets import httpcore export httpcore except parseHeader @@ -241,7 +241,7 @@ proc serve*(server: AsyncHttpServer, port: Port, ## specified address and port. ## ## When a request is made by a client the specified callback will be called. - server.socket = newAsyncSocket() + server.socket = newAsyncSocket(AF_INET6) if server.reuseAddr: server.socket.setSockOpt(OptReuseAddr, true) if server.reusePort: diff --git a/lib/pure/collections/heapqueue.nim b/lib/pure/collections/heapqueue.nim index abe20e556..f86ba1d3f 100644 --- a/lib/pure/collections/heapqueue.nim +++ b/lib/pure/collections/heapqueue.nim @@ -77,8 +77,10 @@ proc pop*[T](heap: var HeapQueue[T]): T = proc del*[T](heap: var HeapQueue[T], index: int) = ## Removes element at `index`, maintaining the heap invariant. swap(seq[T](heap)[^1], seq[T](heap)[index]) - seq[T](heap).setLen(heap.len - 1) - heap.siftup(index) + let newLen = heap.len - 1 + seq[T](heap).setLen(newLen) + if index < newLen: + heap.siftup(index) proc replace*[T](heap: var HeapQueue[T], item: T): T = ## Pop and return the current smallest value, and add the new item. @@ -101,16 +103,19 @@ proc pushpop*[T](heap: var HeapQueue[T], item: T): T = return item when isMainModule: + proc toSortedSeq[T](h: HeapQueue[T]): seq[T] = + var tmp = h + result = @[] + while tmp.len > 0: + result.add(pop(tmp)) + block: # Simple sanity test var heap = newHeapQueue[int]() let data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0] for item in data: push(heap, item) doAssert(heap[0] == 0) - var sort = newSeq[int]() - while heap.len > 0: - sort.add(pop(heap)) - doAssert(sort == @[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + doAssert(heap.toSortedSeq == @[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) block: # Test del var heap = newHeapQueue[int]() @@ -121,11 +126,27 @@ when isMainModule: doAssert(heap[0] == 1) heap.del(seq[int](heap).find(7)) + doAssert(heap.toSortedSeq == @[1, 2, 3, 4, 5, 6, 8, 9]) + heap.del(seq[int](heap).find(5)) + doAssert(heap.toSortedSeq == @[1, 2, 3, 4, 6, 8, 9]) + heap.del(seq[int](heap).find(6)) + doAssert(heap.toSortedSeq == @[1, 2, 3, 4, 8, 9]) + heap.del(seq[int](heap).find(2)) + doAssert(heap.toSortedSeq == @[1, 3, 4, 8, 9]) + + block: # Test del last + var heap = newHeapQueue[int]() + let data = [1, 2, 3] + for item in data: push(heap, item) + + heap.del(2) + doAssert(heap.toSortedSeq == @[1, 2]) - var sort = newSeq[int]() - while heap.len > 0: - sort.add(pop(heap)) - doAssert(sort == @[1, 3, 4, 8, 9]) + heap.del(1) + doAssert(heap.toSortedSeq == @[1]) + + heap.del(0) + doAssert(heap.toSortedSeq == @[]) diff --git a/lib/pure/distros.nim b/lib/pure/distros.nim index ff30f6134..896497630 100644 --- a/lib/pure/distros.nim +++ b/lib/pure/distros.nim @@ -225,7 +225,7 @@ proc foreignDepInstallCmd*(foreignPackageName: string): (string, bool) = else: result = ("<your package manager here> install " & p, true) else: - result = ("brew install " & p, true) + result = ("brew install " & p, false) proc foreignDep*(foreignPackageName: string) = ## Registers 'foreignPackageName' to the internal list of foreign deps. diff --git a/lib/pure/hashes.nim b/lib/pure/hashes.nim index 11af81149..17d1c6442 100644 --- a/lib/pure/hashes.nim +++ b/lib/pure/hashes.nim @@ -127,6 +127,15 @@ proc hash*(x: string): Hash = h = h !& ord(x[i]) result = !$h +proc hash*(x: cstring): Hash = + ## efficient hashing of null-terminated strings + var h: Hash = 0 + var i = 0 + while x[i] != 0.char: + h = h !& ord(x[i]) + inc i + result = !$h + proc hash*(sBuf: string, sPos, ePos: int): Hash = ## efficient hashing of a string buffer, from starting ## position `sPos` to ending position `ePos` @@ -239,6 +248,7 @@ proc hash*[A](x: set[A]): Hash = when isMainModule: doAssert( hash("aa bb aaaa1234") == hash("aa bb aaaa1234", 0, 13) ) + doAssert( hash("aa bb aaaa1234") == hash(cstring("aa bb aaaa1234")) ) doAssert( hashIgnoreCase("aa bb aaaa1234") == hash("aa bb aaaa1234") ) doAssert( hashIgnoreStyle("aa bb aaaa1234") == hashIgnoreCase("aa bb aaaa1234") ) let xx = @['H','e','l','l','o'] diff --git a/lib/pure/httpcore.nim b/lib/pure/httpcore.nim index d7f720f66..aa8f1958d 100644 --- a/lib/pure/httpcore.nim +++ b/lib/pure/httpcore.nim @@ -206,6 +206,8 @@ proc parseHeader*(line: string): tuple[key: string, value: seq[string]] = inc(i) # skip : if i < len(line): i += parseList(line, result.value, i) + elif result.key.len > 0: + result.value = @[""] else: result.value = @[] @@ -318,4 +320,6 @@ when isMainModule: let (key, value) = parseHeader("foobar: ") test = newHttpHeaders() test[key] = value - doAssert test["foobar"] == "" \ No newline at end of file + doAssert test["foobar"] == "" + + doAssert parseHeader("foobar:") == ("foobar", @[""]) \ No newline at end of file diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 5e36a2aa1..c7b581a85 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -952,7 +952,7 @@ proc newIndent(curr, indent: int, ml: bool): int = else: return indent proc nl(s: var string, ml: bool) = - if ml: s.add("\n") + s.add(if ml: "\n" else: " ") proc escapeJson*(s: string; result: var string) = ## Converts a string `s` to its JSON representation. @@ -986,15 +986,14 @@ proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true, lstArr = false, currIndent = 0) = case node.kind of JObject: - if currIndent != 0 and not lstArr: result.nl(ml) - result.indent(currIndent) # Indentation + if lstArr: result.indent(currIndent) # Indentation if node.fields.len > 0: result.add("{") result.nl(ml) # New line var i = 0 for key, val in pairs(node.fields): if i > 0: - result.add(", ") + result.add(",") result.nl(ml) # New Line inc i # Need to indent more than { @@ -1030,7 +1029,7 @@ proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true, result.nl(ml) for i in 0..len(node.elems)-1: if i > 0: - result.add(", ") + result.add(",") result.nl(ml) # New Line toPretty(result, node.elems[i], indent, ml, true, newIndent(currIndent, indent, ml)) diff --git a/lib/pure/logging.nim b/lib/pure/logging.nim index 5544a4b3f..65724f75a 100644 --- a/lib/pure/logging.nim +++ b/lib/pure/logging.nim @@ -46,6 +46,8 @@ ## ## **Warning:** The global list of handlers is a thread var, this means that ## the handlers must be re-added in each thread. +## **Warning:** When logging on disk or console, only error and fatal messages +## are flushed out immediately. Use flushFile() where needed. import strutils, times when not defined(js): diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 4cd3870c7..6bf776a44 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -1002,8 +1002,8 @@ iterator walkDir*(dir: string; relative=false): tuple[kind: PathComponent, path: iterator walkDirRec*(dir: string, filter={pcFile, pcDir}): string {. tags: [ReadDirEffect].} = - ## walks over the directory `dir` and yields for each file in `dir`. The - ## full path for each file is returned. + ## Recursively walks over the directory `dir` and yields for each file in `dir`. + ## The full path for each file is returned. Directories are not returned. ## **Warning**: ## Modifying the directory structure while the iterator ## is traversing may result in undefined behavior! @@ -1185,7 +1185,7 @@ proc createHardlink*(src, dest: string) = proc parseCmdLine*(c: string): seq[string] {. noSideEffect, rtl, extern: "nos$1".} = - ## Splits a command line into several components; + ## Splits a `command line`:idx: into several components; ## This proc is only occasionally useful, better use the `parseopt` module. ## ## On Windows, it uses the following parsing rules diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim index fb7d72182..8d53a0360 100644 --- a/lib/pure/parseutils.nim +++ b/lib/pure/parseutils.nim @@ -250,18 +250,18 @@ proc parseInt*(s: string, number: var int, start = 0): int {. elif result != 0: number = int(res) -# overflowChecks doesn't work with uint64 -proc rawParseUInt(s: string, b: var uint64, start = 0): int = +# overflowChecks doesn't work with BiggestUInt +proc rawParseUInt(s: string, b: var BiggestUInt, start = 0): int = var - res = 0'u64 - prev = 0'u64 + res = 0.BiggestUInt + prev = 0.BiggestUInt i = start if s[i] == '+': inc(i) # Allow if s[i] in {'0'..'9'}: b = 0 while s[i] in {'0'..'9'}: prev = res - res = res * 10 + (ord(s[i]) - ord('0')).uint64 + res = res * 10 + (ord(s[i]) - ord('0')).BiggestUInt if prev > res: return 0 # overflowChecks emulation inc(i) @@ -269,13 +269,13 @@ proc rawParseUInt(s: string, b: var uint64, start = 0): int = b = res result = i - start -proc parseBiggestUInt*(s: string, number: var uint64, start = 0): int {. +proc parseBiggestUInt*(s: string, number: var BiggestUInt, start = 0): int {. rtl, extern: "npuParseBiggestUInt", noSideEffect.} = ## parses an unsigned integer starting at `start` and stores the value ## into `number`. ## Result is the number of processed chars or 0 if there is no integer ## or overflow detected. - var res: uint64 + var res: BiggestUInt # use 'res' for exception safety (don't write to 'number' in case of an # overflow exception): result = rawParseUInt(s, res, start) @@ -287,12 +287,12 @@ proc parseUInt*(s: string, number: var uint, start = 0): int {. ## into `number`. ## Result is the number of processed chars or 0 if there is no integer or ## overflow detected. - var res: uint64 + var res: BiggestUInt result = parseBiggestUInt(s, res, start) - if (sizeof(uint) <= 4) and - (res > 0xFFFF_FFFF'u64): - raise newException(OverflowError, "overflow") - elif result != 0: + when sizeof(BiggestUInt) > sizeof(uint) and sizeof(uint) <= 4: + if res > 0xFFFF_FFFF'u64: + raise newException(OverflowError, "overflow") + if result != 0: number = uint(res) proc parseBiggestFloat*(s: string, number: var BiggestFloat, start = 0): int {. diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 235e66f6a..9c9da92c6 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -898,7 +898,7 @@ proc toHex*(x: BiggestInt, len: Positive): string {.noSideEffect, proc toHex*[T](x: T): string = ## Shortcut for ``toHex(x, T.sizeOf * 2)`` - toHex(x, T.sizeOf * 2) + toHex(BiggestInt(x), T.sizeOf * 2) proc intToStr*(x: int, minchars: Positive = 1): string {.noSideEffect, rtl, extern: "nsuIntToStr".} = @@ -939,7 +939,7 @@ proc parseUInt*(s: string): uint {.noSideEffect, procvar, if L != s.len or L == 0: raise newException(ValueError, "invalid unsigned integer: " & s) -proc parseBiggestUInt*(s: string): uint64 {.noSideEffect, procvar, +proc parseBiggestUInt*(s: string): BiggestUInt {.noSideEffect, procvar, rtl, extern: "nsuParseBiggestUInt".} = ## Parses a decimal unsigned integer value contained in `s`. ## diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index cdca02ed7..01af0f839 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -24,7 +24,7 @@ ## echo "run before each test" ## ## teardown: -## echo "run after each test": +## echo "run after each test" ## ## test "essential truths": ## # give up and stop if this fails |