diff --git a/stew/byteutils.nim b/stew/byteutils.nim index 8d14eeb..4aa214a 100644 --- a/stew/byteutils.nim +++ b/stew/byteutils.nim @@ -25,7 +25,7 @@ else: ##################################### Hex utilities ################################################ proc readHexChar*(c: char): byte - {.raises: [ValueError, Defect], noSideEffect, inline.} = + {.raises: [ValueError], noSideEffect, inline.} = ## Converts an hex char to a byte case c of '0'..'9': result = byte(ord(c) - ord('0')) @@ -42,7 +42,7 @@ template skip0xPrefix(hexStr: openArray[char]): int = func hexToByteArrayImpl( hexStr: openArray[char], output: var openArray[byte], fromIdx, toIdx: int): - int {.raises: [ValueError, Defect].} = + int {.raises: [ValueError].} = var sIdx = skip0xPrefix(hexStr) # Fun with closed intervals doAssert fromIdx >= 0 and @@ -65,7 +65,7 @@ func hexToByteArrayImpl( func hexToByteArray*( hexStr: openArray[char], output: var openArray[byte], fromIdx, toIdx: int) - {.raises: [ValueError, Defect].} = + {.raises: [ValueError].} = ## Read hex-encoded data from `hexStr[mapHex(fromIdx..toIdx)]` and store ## corresponding bytes in `output[fromIdx..toIdx]` where `mapHex` takes into ## account stripped characters. @@ -80,7 +80,7 @@ func hexToByteArray*( discard hexToByteArrayImpl(hexStr, output, fromIdx, toIdx) func hexToByteArray*(hexStr: openArray[char], output: var openArray[byte]) - {.raises: [ValueError, Defect].} = + {.raises: [ValueError].} = ## Read hex-encoded data from `hexStr` and store corresponding bytes in ## `output`. ## @@ -92,7 +92,7 @@ func hexToByteArray*(hexStr: openArray[char], output: var openArray[byte]) hexToByteArray(hexStr, output, 0, output.high) func hexToByteArray*[N: static[int]](hexStr: openArray[char]): array[N, byte] - {.raises: [ValueError, Defect], noinit.}= + {.raises: [ValueError], noinit.}= ## Read hex-encoded data from `hexStr` returning an array of N bytes. ## ## * `0x`/`0X` is stripped if present @@ -103,7 +103,7 @@ func hexToByteArray*[N: static[int]](hexStr: openArray[char]): array[N, byte] hexToByteArray(hexStr, result) func hexToByteArray*(hexStr: openArray[char], N: static int): array[N, byte] - {.raises: [ValueError, Defect], noinit.}= + {.raises: [ValueError], noinit.}= ## Read hex-encoded data from `hexStr` returning an array of N bytes. ## ## * `0x`/`0X` is stripped if present @@ -114,7 +114,7 @@ func hexToByteArray*(hexStr: openArray[char], N: static int): array[N, byte] hexToByteArray(hexStr, result) func hexToByteArrayStrict*(hexStr: openArray[char], output: var openArray[byte]) - {.raises: [ValueError, Defect].} = + {.raises: [ValueError].} = ## Read hex-encoded data from `hexStr` and store corresponding bytes in ## `output`. ## @@ -148,7 +148,7 @@ func hexToByteArrayStrict*(hexStr: openArray[char], N: static int): array[N, byt hexToByteArrayStrict(hexStr, result) func fromHex*[N](A: type array[N, byte], hexStr: string): A - {.raises: [ValueError, Defect], noinit, inline.}= + {.raises: [ValueError], noinit, inline.}= ## Read hex-encoded data from `hexStr` returning an array of N bytes. ## ## * `0x`/`0X` is stripped if present @@ -159,7 +159,7 @@ func fromHex*[N](A: type array[N, byte], hexStr: string): A hexToByteArray(hexStr, result) func hexToPaddedByteArray*[N: static[int]](hexStr: string): array[N, byte] - {.raises: [ValueError, Defect].} = + {.raises: [ValueError].} = ## Read a hex string and store it in a byte array `output`. ## The string may be shorter than the byte array. ## No "endianness" reordering is done. @@ -188,7 +188,7 @@ func hexToPaddedByteArray*[N: static[int]](hexStr: string): array[N, byte] bIdx += shift shr 2 func hexToSeqByte*(hexStr: string): seq[byte] - {.raises: [ValueError, Defect].} = + {.raises: [ValueError].} = ## Read an hex string and store it in a sequence of bytes. No "endianness" reordering is done. if (hexStr.len and 1) == 1: raise (ref ValueError)(msg: "hex string must have even length") diff --git a/stew/ctops.nim b/stew/ctops.nim index a0eb2ec..c9bf43b 100644 --- a/stew/ctops.nim +++ b/stew/ctops.nim @@ -19,9 +19,13 @@ elif sizeof(int) == 4: type AnyItem* = byte|char|int8|uint16|int16|uint32|int32|uint|int +when (NimMajor, NimMinor) < (1, 4): + {.push raises: [Defect].} +else: + {.push raises: [].} + proc isEqual*[A: AnyItem, B: AnyItem](c: typedesc[CT], a: openArray[A], - b: openArray[B]): bool {. - raises: [Defect] .} = + b: openArray[B]): bool = ## Perform constant time comparison of two arrays ``a`` and ``b``. ## ## Please note that it only makes sense to compare arrays of the same length. diff --git a/stew/interval_set.nim b/stew/interval_set.nim index 93cd301..aeb267f 100644 --- a/stew/interval_set.nim +++ b/stew/interval_set.nim @@ -112,7 +112,7 @@ import "."/[results, sorted_set] when (NimMajor, NimMinor) < (1, 4): - {.push raises: [Defect].} + {.push raises: [Defect, CatchableError].} else: {.push raises: [].} diff --git a/stew/keyed_queue.nim b/stew/keyed_queue.nim index 5cf0224..0fd7617 100644 --- a/stew/keyed_queue.nim +++ b/stew/keyed_queue.nim @@ -325,13 +325,17 @@ proc shift*[K,V](rq: var KeyedQueue[K,V]): Result[KeyedQueuePair[K,V],void] = ## ## Using the notation introduced with `rq.append` and `rq.prepend`, the ## item returned and deleted is the *left-most* item. + type T = KeyedQueuePair[K,V] if 0 < rq.tab.len: noKeyError("shift"): let kvp = KeyedQueuePair[K,V]( key: rq.kFirst, data: rq.tab[rq.kFirst].data) rq.shiftImpl - return ok(KeyedQueuePair[K,V](kvp)) + when kvp is T: + return ok(kvp) + else: + return ok(T(kvp)) err() proc shiftKey*[K,V](rq: var KeyedQueue[K,V]): Result[K,void] = @@ -355,13 +359,17 @@ proc pop*[K,V](rq: var KeyedQueue[K,V]): Result[KeyedQueuePair[K,V],void] = ## ## Using the notation introduced with `rq.append` and `rq.prepend`, the ## item returned and deleted is the *right-most* item. + type T = KeyedQueuePair[K,V] if 0 < rq.tab.len: noKeyError("pop"): let kvp = KeyedQueuePair[K,V]( key: rq.kLast, data: rq.tab[rq.kLast].data) rq.popImpl - return ok(KeyedQueuePair[K,V](kvp)) + when kvp is T: + return ok(kvp) + else: + return ok(T(kvp)) err() proc popKey*[K,V](rq: var KeyedQueue[K,V]): Result[K,void] = @@ -450,7 +458,7 @@ proc eq*[K,V](rq: var KeyedQueue[K,V]; key: K): Result[V,void] = return ok(rq.tab[key].data) proc `[]`*[K,V](rq: var KeyedQueue[K,V]; key: K): V - {.gcsafe,raises: [Defect,KeyError].} = + {.gcsafe,raises: [KeyError].} = ## This function provides a simplified version of the `eq()` function with ## table semantics. Note that this finction throws a `KeyError` exception ## unless the argument `key` exists in the queue. diff --git a/stew/keyed_queue/kq_debug.nim b/stew/keyed_queue/kq_debug.nim index e756efa..b6de15e 100644 --- a/stew/keyed_queue/kq_debug.nim +++ b/stew/keyed_queue/kq_debug.nim @@ -31,6 +31,11 @@ type kQVfyPrvNxtExpected kQVfyFirstExpected +when (NimMajor, NimMinor) < (1, 4): + {.push raises: [Defect].} +else: + {.push raises: [].} + # ------------------------------------------------------------------------------ # Public functions, debugging # ------------------------------------------------------------------------------ @@ -50,7 +55,7 @@ proc `$`*[K,V](item: KeyedQueueItem[K,V]): string = "(" & $item.value & ", link[" & $item.prv & "," & $item.kNxt & "])" proc verify*[K,V](rq: var KeyedQueue[K,V]): Result[void,(K,V,KeyedQueueInfo)] - {.gcsafe,raises: [Defect,KeyError].} = + {.gcsafe,raises: [KeyError].} = ## Check for consistency. Returns an error unless the argument ## queue `rq` is consistent. let tabLen = rq.tab.len diff --git a/stew/results.nim b/stew/results.nim index 1e34365..85e08e8 100644 --- a/stew/results.nim +++ b/stew/results.nim @@ -445,7 +445,7 @@ template isOk*(self: Result): bool = self.oResultPrivate template isErr*(self: Result): bool = not self.oResultPrivate when not defined(nimHasEffectsOfs): - template effectsOf(f: untyped) {.pragma.} + template effectsOf(f: untyped) {.pragma, used.} func map*[T0, E, T1]( self: Result[T0, E], f: proc(x: T0): T1): diff --git a/stew/sorted_set.nim b/stew/sorted_set.nim index 88b1906..616bf8e 100644 --- a/stew/sorted_set.nim +++ b/stew/sorted_set.nim @@ -88,7 +88,7 @@ type RbResult[SortedSetItemRef[K,V]] when (NimMajor, NimMinor) < (1, 4): - {.push raises: [Defect].} + {.push raises: [Defect,CatchableError].} else: {.push raises: [].} @@ -301,7 +301,7 @@ proc `$`*[K,V](rc: SortedSetResult[K,V]): string = proc verify*[K,V](sl: var SortedSet[K,V]): Result[void,(SortedSetItemRef[K,V],RbInfo)] - {.gcsafe, raises: [Defect,CatchableError].} = + {.gcsafe.} = ## Checks for consistency, may print an error message. Returns `rbOk` if ## the argument list `sl` is consistent. This function traverses all the ## internal data nodes which might be time consuming. So it would not be diff --git a/stew/sorted_set/rbtree_verify.nim b/stew/sorted_set/rbtree_verify.nim index bf596e8..69ca358 100644 --- a/stew/sorted_set/rbtree_verify.nim +++ b/stew/sorted_set/rbtree_verify.nim @@ -18,11 +18,20 @@ type ## for the equivalent of `a < b` proc(a, b: C): bool {.gcsafe.} - RbPrnFn* = ##\ - ## Handle error message - proc(code: RbInfo; ctxInfo: string) - {.gcsafe, raises: [Defect,CatchableError].} +when (NimMajor, NimMinor) < (1, 4): + type + RbPrnFn* = ##\ + ## Handle error message + proc(code: RbInfo; ctxInfo: string) + {.gcsafe, raises: [Defect,CatchableError].} +else: + type + RbPrnFn* = ##\ + ## Handle error message + proc(code: RbInfo; ctxInfo: string) + {.gcsafe, raises: [].} +type RbDdebug[C,K] = object tree: RbTreeRef[C,K] ## tree, not-Nil node: RbNodeRef[C] ## current node @@ -34,7 +43,7 @@ type msg: string ## collect data when (NimMajor, NimMinor) < (1, 4): - {.push raises: [Defect].} + {.push raises: [Defect, CatchableError].} else: {.push raises: [].} @@ -52,8 +61,7 @@ proc pp[C](n: RbNodeRef[C]): string = result &= "~black" proc doError[C,K](d: var RbDdebug[C,K]; t: RbInfo; s: string): - Result[void,(C,RbInfo)] - {.gcsafe, raises: [Defect,CatchableError].} = + Result[void,(C,RbInfo)] {.gcsafe.} = if not d.pr.isNil: var msg = s & ": <" & d.node.pp & @@ -63,44 +71,44 @@ proc doError[C,K](d: var RbDdebug[C,K]; t: RbInfo; s: string): err((d.node.casket,t)) proc rootIsRed[C,K](d: var RbDdebug[C,K]): Result[void,(C,RbInfo)] - {.gcsafe, raises: [Defect,CatchableError].} = + {.gcsafe.} = d.doError(rbVfyRootIsRed, "Root node is red") proc redNodeRedLinkLeft[C,K](d: var RbDdebug[C,K]): Result[void,(C,RbInfo)] - {.gcsafe, raises: [Defect,CatchableError].} = + {.gcsafe.} = d.doError(rbVfyRedParentRedLeftLink, "Parent node and left link red") proc redNodeRedLinkRight[C,K](d: var RbDdebug[C,K]): Result[void,(C,RbInfo)] - {.gcsafe, raises: [Defect,CatchableError].} = + {.gcsafe.} = d.doError(rbVfyRedParentRedRightLink, "Parent node and right link red") proc redNodeRedLinkBoth[C,K](d: var RbDdebug[C,K]): Result[void,(C,RbInfo)] - {.gcsafe, raises: [Defect,CatchableError].} = + {.gcsafe.} = d.doError(rbVfyRedParentRedBothLinks, "Parent node and both links red") proc linkLeftCompError[C,K](d: var RbDdebug[C,K]): Result[void,(C,RbInfo)] - {.gcsafe, raises: [Defect,CatchableError].} = + {.gcsafe.} = d.doError(rbVfyLeftLinkGtParent, "Left node greater than parent") proc linkRightCompError[C,K](d: var RbDdebug[C,K]): Result[void,(C,RbInfo)] - {.gcsafe, raises: [Defect,CatchableError].} = + {.gcsafe.} = d.doError(rbVfyRightLinkLtParent, "Right node greater than parent") proc linkBothCompError[C,K](d: var RbDdebug[C,K]): Result[void,(C,RbInfo)] - {.gcsafe, raises: [Defect,CatchableError].} = + {.gcsafe.} = d.doError(rbVfyBothLinkCmpParentReversed, "Left node greater than parent greater than right node") proc blackChainLevelError[C,K](d: var RbDdebug[C,K]): Result[void,(C,RbInfo)] - {.gcsafe, raises: [Defect,CatchableError].} = + {.gcsafe.} = d.doError(rbVfyBlackChainLevelMismatch, "Inconsistent length of black node chains") proc subTreeVerify[C,K](d: var RbDdebug[C,K]): Result[void,(C,RbInfo)] - {.gcsafe, raises: [Defect,CatchableError].} = + {.gcsafe.} = let node = d.node doAssert not node.isNil @@ -168,7 +176,7 @@ proc subTreeVerify[C,K](d: var RbDdebug[C,K]): Result[void,(C,RbInfo)] proc rbTreeVerify*[C,K](rbt: RbTreeRef[C,K]; lt: RbLtFn[C] = nil; pr: RbPrnFn = nil): Result[void,(C,RbInfo)] - {.gcsafe, raises: [Defect,CatchableError].} = + {.gcsafe.} = ## Verifies the argument tree `rbt` for ## * No consecutively linked red nodes down the tree ## * Link consisteny: value(leftLink) < value(node) < value(rightLink). This diff --git a/tests/test_ctops.nim b/tests/test_ctops.nim index 4efa8b9..1bd402c 100644 --- a/tests/test_ctops.nim +++ b/tests/test_ctops.nim @@ -9,6 +9,11 @@ import unittest2 import ../stew/ctops +when (NimMajor, NimMinor) < (1, 6): + type DefectEx = AssertionError +else: + type DefectEx = AssertionDefect + suite "Constant-time operations test suite": test "isEqual() test": let @@ -97,17 +102,17 @@ suite "Constant-time operations test suite": CT.isEqual(int64Arr, uint64Arr) == true # Empty arrays - expect(AssertionError): + expect(DefectEx): discard CT.isEqual(emptyArray, emptyArray) - expect(AssertionError): + expect(DefectEx): discard CT.isEqual(emptyArray, emptyString) - expect(AssertionError): + expect(DefectEx): discard CT.isEqual(emptyArray, emptySeq) # Arrays, where T is different type size - expect(AssertionError): + expect(DefectEx): discard CT.isEqual(int8Arr, int16Arr) - expect(AssertionError): + expect(DefectEx): discard CT.isEqual(int16Arr, int32Arr) - expect(AssertionError): + expect(DefectEx): discard CT.isEqual(int8Arr, intArr) diff --git a/tests/test_keyed_queue.nim b/tests/test_keyed_queue.nim index bb677fc..3428f7a 100644 --- a/tests/test_keyed_queue.nim +++ b/tests/test_keyed_queue.nim @@ -17,8 +17,6 @@ import ../stew/keyed_queue/kq_debug const - usedStrutils = newSeq[string]().join(" ") - lruCacheLimit = 10 lruCacheModulo = 13 @@ -50,7 +48,7 @@ let proc `$`(rc: KeyedQueuePair[uint,uint]): string = "(" & $rc.key & "," & $rc.data & ")" -proc `$`(rc: Result[KeyedQueuePair[uint,uint],void]): string = +proc `$`(rc: Result[KeyedQueuePair[uint,uint],void]): string {.used.} = result = "<" if rc.isOk: result &= $rc.value.key & "," & $rc.value.data @@ -136,7 +134,7 @@ proc compileGenericFunctions(rq: var KUQueue) = rq[0] = 0 # so `rq[0]` works discard rq[0] - let ignoreValues = ( + let ignoreValues {.used.} = ( (rq.append(0,0), rq.push(0,0), rq.replace(0,0), rq.prepend(0,0), rq.unshift(0,0), @@ -533,10 +531,13 @@ suite "KeyedQueue: Data queue as LRU cache": c1 = keyList.toLruCache sq = toSeq(c1.q.nextPairs).mapIt(it.key.fromKey) s0 = sq - inx = 5 key = sq[5].toKey - sq.delete(5,5) # delete index 5 in sequence + when (NimMajor, NimMinor) >= (1, 6): + sq.delete(5..5) # delete index 5 in sequence + else: + sq.delete(5, 5) # delete index 5 in sequence + noisy.say &"sq: {s0} {sq}" check c1.q.delete(key).value.key == key diff --git a/tests/test_results.nim b/tests/test_results.nim index 7345981..3358751 100644 --- a/tests/test_results.nim +++ b/tests/test_results.nim @@ -88,12 +88,18 @@ block: doAssert c.isErr # De-reference + when (NimMajor, NimMinor) >= (1, 6): + {.warning[BareExcept]:off.} + try: echo rErr[] doAssert false except: discard + when (NimMajor, NimMinor) >= (1, 6): + {.warning[BareExcept]:on.} + # Comparisons doAssert (rOk == rOk) doAssert (rErr == rErr)