Remove deprecated stuff from stdlib (#14699)
* update to the latest Jester * remove deprecated procs from some stdlib modules * 'criterion' is not maintained anymore and relies on obsolete stuff
This commit is contained in:
parent
8619534293
commit
e7f280bd26
41 changed files with 155 additions and 519 deletions
|
|
@ -367,7 +367,7 @@ A similar thing happens with C code invoking Nim code which returns a
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
|
|
||||||
proc gimme(): cstring {.exportc.} =
|
proc gimme(): cstring {.exportc.} =
|
||||||
result = "Hey there C code! " & $random(100)
|
result = "Hey there C code! " & $rand(100)
|
||||||
|
|
||||||
Since Nim's garbage collector is not aware of the C code, once the
|
Since Nim's garbage collector is not aware of the C code, once the
|
||||||
``gimme`` proc has finished it can reclaim the memory of the ``cstring``.
|
``gimme`` proc has finished it can reclaim the memory of the ``cstring``.
|
||||||
|
|
|
||||||
|
|
@ -996,12 +996,6 @@ macro dumpAstGen*(s: untyped): untyped = echo s.astGenRepr
|
||||||
##
|
##
|
||||||
## Also see ``dumpTree`` and ``dumpLisp``.
|
## Also see ``dumpTree`` and ``dumpLisp``.
|
||||||
|
|
||||||
macro dumpTreeImm*(s: untyped): untyped {.deprecated.} = echo s.treeRepr
|
|
||||||
## Deprecated. Use `dumpTree` instead.
|
|
||||||
|
|
||||||
macro dumpLispImm*(s: untyped): untyped {.deprecated.} = echo s.lispRepr
|
|
||||||
## Deprecated. Use `dumpLisp` instead.
|
|
||||||
|
|
||||||
proc newEmptyNode*(): NimNode {.compileTime, noSideEffect.} =
|
proc newEmptyNode*(): NimNode {.compileTime, noSideEffect.} =
|
||||||
## Create a new empty node.
|
## Create a new empty node.
|
||||||
result = newNimNode(nnkEmpty)
|
result = newNimNode(nnkEmpty)
|
||||||
|
|
|
||||||
|
|
@ -483,13 +483,6 @@ proc multiReplace*(s: string, subs: openArray[
|
||||||
# copy the rest:
|
# copy the rest:
|
||||||
add(result, substr(s, i))
|
add(result, substr(s, i))
|
||||||
|
|
||||||
proc parallelReplace*(s: string, subs: openArray[
|
|
||||||
tuple[pattern: Regex, repl: string]]): string {.deprecated:
|
|
||||||
"Deprecated since v0.18.0: Use ``multiReplace`` instead.".} =
|
|
||||||
## Returns a modified copy of ``s`` with the substitutions in ``subs``
|
|
||||||
## applied in parallel.
|
|
||||||
result = multiReplace(s, subs)
|
|
||||||
|
|
||||||
proc transformFile*(infile, outfile: string,
|
proc transformFile*(infile, outfile: string,
|
||||||
subs: openArray[tuple[pattern: Regex, repl: string]]) =
|
subs: openArray[tuple[pattern: Regex, repl: string]]) =
|
||||||
## reads in the file ``infile``, performs a parallel replacement (calls
|
## reads in the file ``infile``, performs a parallel replacement (calls
|
||||||
|
|
|
||||||
|
|
@ -223,10 +223,6 @@ proc binarySearch*[T](a: openArray[T], key: T): int =
|
||||||
assert binarySearch([0, 1, 4, 2, 3], 4) == 2
|
assert binarySearch([0, 1, 4, 2, 3], 4) == 2
|
||||||
binarySearch(a, key, cmp[T])
|
binarySearch(a, key, cmp[T])
|
||||||
|
|
||||||
proc smartBinarySearch*[T](a: openArray[T], key: T): int {.deprecated:
|
|
||||||
"Deprecated since v0.18.1; Use 'binarySearch'".} =
|
|
||||||
binarySearch(a, key, cmp[T])
|
|
||||||
|
|
||||||
const
|
const
|
||||||
onlySafeCode = true
|
onlySafeCode = true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -285,7 +285,7 @@ when defined(windows) or defined(nimdoc):
|
||||||
new result
|
new result
|
||||||
result.ioPort = createIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 1)
|
result.ioPort = createIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 1)
|
||||||
result.handles = initHashSet[AsyncFD]()
|
result.handles = initHashSet[AsyncFD]()
|
||||||
result.timers.newHeapQueue()
|
result.timers.clear()
|
||||||
result.callbacks = initDeque[proc () {.closure, gcsafe.}](64)
|
result.callbacks = initDeque[proc () {.closure, gcsafe.}](64)
|
||||||
|
|
||||||
var gDisp{.threadvar.}: owned PDispatcher ## Global dispatcher
|
var gDisp{.threadvar.}: owned PDispatcher ## Global dispatcher
|
||||||
|
|
|
||||||
|
|
@ -183,14 +183,6 @@ proc `$`*[T](heap: HeapQueue[T]): string =
|
||||||
result.addQuoted(x)
|
result.addQuoted(x)
|
||||||
result.add("]")
|
result.add("]")
|
||||||
|
|
||||||
proc newHeapQueue*[T](): HeapQueue[T] {.deprecated:
|
|
||||||
"Deprecated since v0.20.0: use 'initHeapQueue' instead.".} =
|
|
||||||
initHeapQueue[T]()
|
|
||||||
|
|
||||||
proc newHeapQueue*[T](heap: var HeapQueue[T]) {.deprecated:
|
|
||||||
"Deprecated since v0.20.0: use 'clear' instead.".} =
|
|
||||||
heap.clear()
|
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
proc toSortedSeq[T](h: HeapQueue[T]): seq[T] =
|
proc toSortedSeq[T](h: HeapQueue[T]): seq[T] =
|
||||||
var tmp = h
|
var tmp = h
|
||||||
|
|
|
||||||
|
|
@ -111,9 +111,7 @@ proc init*[A](s: var HashSet[A], initialSize = defaultInitialSize) =
|
||||||
## * `toHashSet proc <#toHashSet,openArray[A]>`_
|
## * `toHashSet proc <#toHashSet,openArray[A]>`_
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var a: HashSet[int]
|
var a: HashSet[int]
|
||||||
assert(not a.isValid)
|
|
||||||
init(a)
|
init(a)
|
||||||
assert a.isValid
|
|
||||||
|
|
||||||
initImpl(s, initialSize)
|
initImpl(s, initialSize)
|
||||||
|
|
||||||
|
|
@ -647,9 +645,7 @@ proc init*[A](s: var OrderedSet[A], initialSize = defaultInitialSize) =
|
||||||
## * `toOrderedSet proc <#toOrderedSet,openArray[A]>`_
|
## * `toOrderedSet proc <#toOrderedSet,openArray[A]>`_
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var a: OrderedSet[int]
|
var a: OrderedSet[int]
|
||||||
assert(not a.isValid)
|
|
||||||
init(a)
|
init(a)
|
||||||
assert a.isValid
|
|
||||||
|
|
||||||
initImpl(s, initialSize)
|
initImpl(s, initialSize)
|
||||||
|
|
||||||
|
|
@ -923,21 +919,6 @@ iterator pairs*[A](s: OrderedSet[A]): tuple[a: int, b: A] =
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
proc isValid*[A](s: OrderedSet[A]): bool {.deprecated:
|
|
||||||
"Deprecated since v0.20; sets are initialized by default".} =
|
|
||||||
##
|
|
||||||
## Returns `true` if the set has been initialized (with `initHashSet proc
|
|
||||||
## <#initOrderedSet,int>`_ or `init proc <#init,OrderedSet[A],int>`_).
|
|
||||||
##
|
|
||||||
## **Examples:**
|
|
||||||
##
|
|
||||||
## .. code-block ::
|
|
||||||
## proc savePreferences(options: OrderedSet[string]) =
|
|
||||||
## assert options.isValid, "Pass an initialized set!"
|
|
||||||
## # Do stuff here, may crash in release builds!
|
|
||||||
result = s.data.len > 0
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------
|
# -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -945,16 +926,8 @@ proc isValid*[A](s: OrderedSet[A]): bool {.deprecated:
|
||||||
when isMainModule and not defined(release):
|
when isMainModule and not defined(release):
|
||||||
proc testModule() =
|
proc testModule() =
|
||||||
## Internal micro test to validate docstrings and such.
|
## Internal micro test to validate docstrings and such.
|
||||||
block isValidTest: # isValid is deprecated
|
|
||||||
var options: HashSet[string]
|
|
||||||
proc savePreferences(options: HashSet[string]) =
|
|
||||||
assert options.isValid, "Pass an initialized set!"
|
|
||||||
options = initHashSet[string]()
|
|
||||||
options.savePreferences
|
|
||||||
|
|
||||||
block lenTest:
|
block lenTest:
|
||||||
var values: HashSet[int]
|
var values: HashSet[int]
|
||||||
assert(not values.isValid)
|
|
||||||
assert values.len == 0
|
assert values.len == 0
|
||||||
assert values.card == 0
|
assert values.card == 0
|
||||||
|
|
||||||
|
|
@ -1046,16 +1019,8 @@ when isMainModule and not defined(release):
|
||||||
var b = a.map(proc (x: int): string = $x)
|
var b = a.map(proc (x: int): string = $x)
|
||||||
assert b == toHashSet(["1", "2", "3"])
|
assert b == toHashSet(["1", "2", "3"])
|
||||||
|
|
||||||
block isValidTest: # isValid is deprecated
|
|
||||||
var cards: OrderedSet[string]
|
|
||||||
proc saveTarotCards(cards: OrderedSet[string]) =
|
|
||||||
assert cards.isValid, "Pass an initialized set!"
|
|
||||||
cards = initOrderedSet[string]()
|
|
||||||
cards.saveTarotCards
|
|
||||||
|
|
||||||
block lenTest:
|
block lenTest:
|
||||||
var values: OrderedSet[int]
|
var values: OrderedSet[int]
|
||||||
assert(not values.isValid)
|
|
||||||
assert values.len == 0
|
assert values.len == 0
|
||||||
assert values.card == 0
|
assert values.card == 0
|
||||||
|
|
||||||
|
|
@ -1119,7 +1084,7 @@ when isMainModule and not defined(release):
|
||||||
a.init(4)
|
a.init(4)
|
||||||
a.incl(2)
|
a.incl(2)
|
||||||
a.init
|
a.init
|
||||||
assert a.len == 0 and a.isValid
|
assert a.len == 0
|
||||||
a = initOrderedSet[int](4)
|
a = initOrderedSet[int](4)
|
||||||
a.incl(2)
|
a.incl(2)
|
||||||
assert a.len == 1
|
assert a.len == 1
|
||||||
|
|
@ -1128,7 +1093,7 @@ when isMainModule and not defined(release):
|
||||||
b.init(4)
|
b.init(4)
|
||||||
b.incl(2)
|
b.incl(2)
|
||||||
b.init
|
b.init
|
||||||
assert b.len == 0 and b.isValid
|
assert b.len == 0
|
||||||
b = initHashSet[int](4)
|
b = initHashSet[int](4)
|
||||||
b.incl(2)
|
b.incl(2)
|
||||||
assert b.len == 1
|
assert b.len == 1
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ when not defined(testing) and isMainModule and not defined(nimdoc):
|
||||||
|
|
||||||
proc busyLoop() =
|
proc busyLoop() =
|
||||||
while true:
|
while true:
|
||||||
discard random(80)
|
discard rand(80)
|
||||||
os.sleep(100)
|
os.sleep(100)
|
||||||
|
|
||||||
spawn busyLoop()
|
spawn busyLoop()
|
||||||
|
|
|
||||||
|
|
@ -435,7 +435,7 @@ proc `[]=`*(p: MultipartData, name: string,
|
||||||
proc getBoundary(p: MultipartData): string =
|
proc getBoundary(p: MultipartData): string =
|
||||||
if p == nil or p.content.len == 0: return
|
if p == nil or p.content.len == 0: return
|
||||||
while true:
|
while true:
|
||||||
result = $random(int.high)
|
result = $rand(int.high)
|
||||||
for i, entry in p.content:
|
for i, entry in p.content:
|
||||||
if result in entry.content: break
|
if result in entry.content: break
|
||||||
elif i == p.content.high: return
|
elif i == p.content.high: return
|
||||||
|
|
|
||||||
|
|
@ -196,17 +196,6 @@ proc nextPowerOfTwo*(x: int): int {.noSideEffect.} =
|
||||||
result = result or (result shr 1)
|
result = result or (result shr 1)
|
||||||
result += 1 + ord(x <= 0)
|
result += 1 + ord(x <= 0)
|
||||||
|
|
||||||
proc countBits32*(n: int32): int {.noSideEffect, deprecated:
|
|
||||||
"Deprecated since v0.20.0; use 'bitops.countSetBits' instead".} =
|
|
||||||
runnableExamples:
|
|
||||||
doAssert countBits32(7) == 3
|
|
||||||
doAssert countBits32(8) == 1
|
|
||||||
doAssert countBits32(15) == 4
|
|
||||||
doAssert countBits32(16) == 1
|
|
||||||
doAssert countBits32(17) == 2
|
|
||||||
|
|
||||||
bitops.countSetBits(n)
|
|
||||||
|
|
||||||
proc sum*[T](x: openArray[T]): T {.noSideEffect.} =
|
proc sum*[T](x: openArray[T]): T {.noSideEffect.} =
|
||||||
## Computes the sum of the elements in ``x``.
|
## Computes the sum of the elements in ``x``.
|
||||||
##
|
##
|
||||||
|
|
@ -611,13 +600,6 @@ when not defined(js): # C
|
||||||
## echo gamma(4.0) # 6.0
|
## echo gamma(4.0) # 6.0
|
||||||
## echo gamma(11.0) # 3628800.0
|
## echo gamma(11.0) # 3628800.0
|
||||||
## echo gamma(-1.0) # nan
|
## echo gamma(-1.0) # nan
|
||||||
proc tgamma*(x: float32): float32
|
|
||||||
{.deprecated: "Deprecated since v0.19.0; use 'gamma' instead",
|
|
||||||
importc: "tgammaf", header: "<math.h>".}
|
|
||||||
proc tgamma*(x: float64): float64
|
|
||||||
{.deprecated: "Deprecated since v0.19.0; use 'gamma' instead",
|
|
||||||
importc: "tgamma", header: "<math.h>".}
|
|
||||||
## The gamma function
|
|
||||||
proc lgamma*(x: float32): float32 {.importc: "lgammaf", header: "<math.h>".}
|
proc lgamma*(x: float32): float32 {.importc: "lgammaf", header: "<math.h>".}
|
||||||
proc lgamma*(x: float64): float64 {.importc: "lgamma", header: "<math.h>".}
|
proc lgamma*(x: float64): float64 {.importc: "lgamma", header: "<math.h>".}
|
||||||
## Computes the natural log of the gamma function for ``x``.
|
## Computes the natural log of the gamma function for ``x``.
|
||||||
|
|
@ -750,12 +732,6 @@ when not defined(js): # C
|
||||||
## echo trunc(PI) # 3.0
|
## echo trunc(PI) # 3.0
|
||||||
## echo trunc(-1.85) # -1.0
|
## echo trunc(-1.85) # -1.0
|
||||||
|
|
||||||
proc fmod*(x, y: float32): float32 {.deprecated: "Deprecated since v0.19.0; use 'mod' instead",
|
|
||||||
importc: "fmodf", header: "<math.h>".}
|
|
||||||
proc fmod*(x, y: float64): float64 {.deprecated: "Deprecated since v0.19.0; use 'mod' instead",
|
|
||||||
importc: "fmod", header: "<math.h>".}
|
|
||||||
## Computes the remainder of ``x`` divided by ``y``.
|
|
||||||
|
|
||||||
proc `mod`*(x, y: float32): float32 {.importc: "fmodf", header: "<math.h>".}
|
proc `mod`*(x, y: float32): float32 {.importc: "fmodf", header: "<math.h>".}
|
||||||
proc `mod`*(x, y: float64): float64 {.importc: "fmod", header: "<math.h>".}
|
proc `mod`*(x, y: float64): float64 {.importc: "fmod", header: "<math.h>".}
|
||||||
## Computes the modulo operation for float values (the remainder of ``x`` divided by ``y``).
|
## Computes the modulo operation for float values (the remainder of ``x`` divided by ``y``).
|
||||||
|
|
@ -1111,7 +1087,6 @@ when isMainModule and not defined(js) and not windowsCC89:
|
||||||
|
|
||||||
# check gamma function
|
# check gamma function
|
||||||
assert(gamma(5.0) == 24.0) # 4!
|
assert(gamma(5.0) == 24.0) # 4!
|
||||||
assert($tgamma(5.0) == $24.0) # 4!
|
|
||||||
assert(lgamma(1.0) == 0.0) # ln(1.0) == 0.0
|
assert(lgamma(1.0) == 0.0) # ln(1.0) == 0.0
|
||||||
assert(erf(6.0) > erf(5.0))
|
assert(erf(6.0) > erf(5.0))
|
||||||
assert(erfc(6.0) < erfc(5.0))
|
assert(erfc(6.0) < erfc(5.0))
|
||||||
|
|
@ -1133,20 +1108,6 @@ when isMainModule:
|
||||||
doAssert round(-54.652) ==~ -55.0
|
doAssert round(-54.652) ==~ -55.0
|
||||||
doAssert round(-54.352) ==~ -54.0
|
doAssert round(-54.352) ==~ -54.0
|
||||||
doAssert round(0.0) ==~ 0.0
|
doAssert round(0.0) ==~ 0.0
|
||||||
# Round to positive decimal places
|
|
||||||
doAssert round(-547.652, 1) ==~ -547.7
|
|
||||||
doAssert round(547.652, 1) ==~ 547.7
|
|
||||||
doAssert round(-547.652, 2) ==~ -547.65
|
|
||||||
doAssert round(547.652, 2) ==~ 547.65
|
|
||||||
# Round to negative decimal places
|
|
||||||
doAssert round(547.652, -1) ==~ 550.0
|
|
||||||
doAssert round(547.652, -2) ==~ 500.0
|
|
||||||
doAssert round(547.652, -3) ==~ 1000.0
|
|
||||||
doAssert round(547.652, -4) ==~ 0.0
|
|
||||||
doAssert round(-547.652, -1) ==~ -550.0
|
|
||||||
doAssert round(-547.652, -2) ==~ -500.0
|
|
||||||
doAssert round(-547.652, -3) ==~ -1000.0
|
|
||||||
doAssert round(-547.652, -4) ==~ 0.0
|
|
||||||
|
|
||||||
block: # splitDecimal() tests
|
block: # splitDecimal() tests
|
||||||
doAssert splitDecimal(54.674).intpart ==~ 54.0
|
doAssert splitDecimal(54.674).intpart ==~ 54.0
|
||||||
|
|
|
||||||
|
|
@ -233,22 +233,6 @@ proc createNativeSocket*(domain: Domain = AF_INET,
|
||||||
## by child processes.
|
## by child processes.
|
||||||
createNativeSocket(toInt(domain), toInt(sockType), toInt(protocol), inheritable)
|
createNativeSocket(toInt(domain), toInt(sockType), toInt(protocol), inheritable)
|
||||||
|
|
||||||
proc newNativeSocket*(domain: Domain = AF_INET,
|
|
||||||
sockType: SockType = SOCK_STREAM,
|
|
||||||
protocol: Protocol = IPPROTO_TCP): SocketHandle
|
|
||||||
{.deprecated: "deprecated since v0.18.0; use 'createNativeSocket' instead".} =
|
|
||||||
## Creates a new socket; returns `osInvalidSocket` if an error occurs.
|
|
||||||
createNativeSocket(domain, sockType, protocol)
|
|
||||||
|
|
||||||
proc newNativeSocket*(domain: cint, sockType: cint,
|
|
||||||
protocol: cint): SocketHandle
|
|
||||||
{.deprecated: "deprecated since v0.18.0; use 'createNativeSocket' instead".} =
|
|
||||||
## Creates a new socket; returns `osInvalidSocket` if an error occurs.
|
|
||||||
##
|
|
||||||
## Use this overload if one of the enums specified above does
|
|
||||||
## not contain what you need.
|
|
||||||
createNativeSocket(domain, sockType, protocol)
|
|
||||||
|
|
||||||
proc bindAddr*(socket: SocketHandle, name: ptr SockAddr,
|
proc bindAddr*(socket: SocketHandle, name: ptr SockAddr,
|
||||||
namelen: SockLen): cint =
|
namelen: SockLen): cint =
|
||||||
result = bindSocket(socket, name, namelen)
|
result = bindSocket(socket, name, namelen)
|
||||||
|
|
|
||||||
|
|
@ -206,30 +206,6 @@ proc skipRandomNumbers*(s: var Rand) =
|
||||||
s.a0 = s0
|
s.a0 = s0
|
||||||
s.a1 = s1
|
s.a1 = s1
|
||||||
|
|
||||||
proc random*(max: int): int {.benign, deprecated:
|
|
||||||
"Deprecated since v0.18.0; use 'rand' instead".} =
|
|
||||||
while true:
|
|
||||||
let x = next(state)
|
|
||||||
if x < randMax - (randMax mod Ui(max)):
|
|
||||||
return int(x mod uint64(max))
|
|
||||||
|
|
||||||
proc random*(max: float): float {.benign, deprecated:
|
|
||||||
"Deprecated since v0.18.0; use 'rand' instead".} =
|
|
||||||
let x = next(state)
|
|
||||||
when defined(js):
|
|
||||||
result = (float(x) / float(high(uint32))) * max
|
|
||||||
else:
|
|
||||||
let u = (0x3FFu64 shl 52u64) or (x shr 12u64)
|
|
||||||
result = (cast[float](u) - 1.0) * max
|
|
||||||
|
|
||||||
proc random*[T](x: HSlice[T, T]): T {.deprecated:
|
|
||||||
"Deprecated since v0.18.0; use 'rand' instead".} =
|
|
||||||
result = T(random(x.b - x.a)) + x.a
|
|
||||||
|
|
||||||
proc random*[T](a: openArray[T]): T {.deprecated:
|
|
||||||
"Deprecated since v0.18.0; use 'sample' instead".} =
|
|
||||||
result = a[random(a.low..a.len)]
|
|
||||||
|
|
||||||
proc rand*(r: var Rand; max: Natural): int {.benign.} =
|
proc rand*(r: var Rand; max: Natural): int {.benign.} =
|
||||||
## Returns a random integer in the range `0..max` using the given state.
|
## Returns a random integer in the range `0..max` using the given state.
|
||||||
##
|
##
|
||||||
|
|
@ -362,10 +338,6 @@ proc rand*[T: Ordinal or SomeFloat](x: HSlice[T, T]): T =
|
||||||
doAssert rand(1..6) == 6
|
doAssert rand(1..6) == 6
|
||||||
result = rand(state, x)
|
result = rand(state, x)
|
||||||
|
|
||||||
proc rand*[T](r: var Rand; a: openArray[T]): T {.deprecated:
|
|
||||||
"Deprecated since v0.20.0; use 'sample' instead".} =
|
|
||||||
result = a[rand(r, a.low..a.high)]
|
|
||||||
|
|
||||||
proc rand*[T: SomeInteger](t: typedesc[T]): T =
|
proc rand*[T: SomeInteger](t: typedesc[T]): T =
|
||||||
## Returns a random integer in the range `low(T)..high(T)`.
|
## Returns a random integer in the range `low(T)..high(T)`.
|
||||||
##
|
##
|
||||||
|
|
@ -395,10 +367,6 @@ proc rand*[T: SomeInteger](t: typedesc[T]): T =
|
||||||
else:
|
else:
|
||||||
result = cast[T](state.next)
|
result = cast[T](state.next)
|
||||||
|
|
||||||
proc rand*[T](a: openArray[T]): T {.deprecated:
|
|
||||||
"Deprecated since v0.20.0; use 'sample' instead".} =
|
|
||||||
result = a[rand(a.low..a.high)]
|
|
||||||
|
|
||||||
proc sample*[T](r: var Rand; s: set[T]): T =
|
proc sample*[T](r: var Rand; s: set[T]): T =
|
||||||
## Returns a random element from the set ``s`` using the given state.
|
## Returns a random element from the set ``s`` using the given state.
|
||||||
##
|
##
|
||||||
|
|
@ -687,6 +655,6 @@ when isMainModule:
|
||||||
|
|
||||||
|
|
||||||
# don't use causes integer overflow
|
# don't use causes integer overflow
|
||||||
doAssert compiles(random[int](low(int) .. high(int)))
|
doAssert compiles(rand[int](low(int) .. high(int)))
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
|
|
@ -334,22 +334,3 @@ else:
|
||||||
include ioselects/ioselectors_select
|
include ioselects/ioselectors_select
|
||||||
else:
|
else:
|
||||||
include ioselects/ioselectors_poll
|
include ioselects/ioselectors_poll
|
||||||
|
|
||||||
proc register*[T](s: Selector[T], fd: int | SocketHandle,
|
|
||||||
events: set[Event], data: T) {.deprecated: "use registerHandle instead".} =
|
|
||||||
## **Deprecated since v0.18.0:** Use ``registerHandle`` instead.
|
|
||||||
s.registerHandle(fd, events, data)
|
|
||||||
|
|
||||||
proc setEvent*(ev: SelectEvent) {.deprecated: "use trigger instead".} =
|
|
||||||
## Trigger event ``ev``.
|
|
||||||
##
|
|
||||||
## **Deprecated since v0.18.0:** Use ``trigger`` instead.
|
|
||||||
ev.trigger()
|
|
||||||
|
|
||||||
proc update*[T](s: Selector[T], fd: int | SocketHandle,
|
|
||||||
events: set[Event]) {.deprecated: "use updateHandle instead".} =
|
|
||||||
## Update file/socket descriptor ``fd``, registered in selector
|
|
||||||
## ``s`` with new events set ``event``.
|
|
||||||
##
|
|
||||||
## **Deprecated since v0.18.0:** Use ``updateHandle`` instead.
|
|
||||||
s.updateHandle()
|
|
||||||
|
|
|
||||||
|
|
@ -581,8 +581,8 @@ proc initDuration*(nanoseconds, microseconds, milliseconds,
|
||||||
## Create a new `Duration <#Duration>`_.
|
## Create a new `Duration <#Duration>`_.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
let dur = initDuration(seconds = 1, milliseconds = 1)
|
let dur = initDuration(seconds = 1, milliseconds = 1)
|
||||||
doAssert dur.milliseconds == 1
|
doAssert dur.inMilliseconds == 1001
|
||||||
doAssert dur.seconds == 1
|
doAssert dur.inSeconds == 1
|
||||||
|
|
||||||
let seconds = convert(Weeks, Seconds, weeks) +
|
let seconds = convert(Weeks, Seconds, weeks) +
|
||||||
convert(Days, Seconds, days) +
|
convert(Days, Seconds, days) +
|
||||||
|
|
@ -1464,7 +1464,7 @@ type
|
||||||
s, ss
|
s, ss
|
||||||
fff, ffffff, fffffffff
|
fff, ffffff, fffffffff
|
||||||
t, tt
|
t, tt
|
||||||
y, yy, yyy, yyyy, yyyyy
|
yy, yyyy
|
||||||
YYYY
|
YYYY
|
||||||
uuuu
|
uuuu
|
||||||
UUUU
|
UUUU
|
||||||
|
|
@ -1612,11 +1612,8 @@ proc stringToPattern(str: string): FormatPattern =
|
||||||
of "fffffffff": result = fffffffff
|
of "fffffffff": result = fffffffff
|
||||||
of "t": result = t
|
of "t": result = t
|
||||||
of "tt": result = tt
|
of "tt": result = tt
|
||||||
of "y": result = y
|
|
||||||
of "yy": result = yy
|
of "yy": result = yy
|
||||||
of "yyy": result = yyy
|
|
||||||
of "yyyy": result = yyyy
|
of "yyyy": result = yyyy
|
||||||
of "yyyyy": result = yyyyy
|
|
||||||
of "YYYY": result = YYYY
|
of "YYYY": result = YYYY
|
||||||
of "uuuu": result = uuuu
|
of "uuuu": result = uuuu
|
||||||
of "UUUU": result = UUUU
|
of "UUUU": result = UUUU
|
||||||
|
|
@ -1709,20 +1706,14 @@ proc formatPattern(dt: DateTime, pattern: FormatPattern, result: var string,
|
||||||
result.add if dt.hour >= 12: "P" else: "A"
|
result.add if dt.hour >= 12: "P" else: "A"
|
||||||
of tt:
|
of tt:
|
||||||
result.add if dt.hour >= 12: "PM" else: "AM"
|
result.add if dt.hour >= 12: "PM" else: "AM"
|
||||||
of y: # Deprecated
|
|
||||||
result.add $(dt.yearOfEra mod 10)
|
|
||||||
of yy:
|
of yy:
|
||||||
result.add (dt.yearOfEra mod 100).intToStr(2)
|
result.add (dt.yearOfEra mod 100).intToStr(2)
|
||||||
of yyy: # Deprecated
|
|
||||||
result.add (dt.yearOfEra mod 1000).intToStr(3)
|
|
||||||
of yyyy:
|
of yyyy:
|
||||||
let year = dt.yearOfEra
|
let year = dt.yearOfEra
|
||||||
if year < 10000:
|
if year < 10000:
|
||||||
result.add year.intToStr(4)
|
result.add year.intToStr(4)
|
||||||
else:
|
else:
|
||||||
result.add '+' & $year
|
result.add '+' & $year
|
||||||
of yyyyy: # Deprecated
|
|
||||||
result.add (dt.yearOfEra mod 100_000).intToStr(5)
|
|
||||||
of YYYY:
|
of YYYY:
|
||||||
if dt.year < 1:
|
if dt.year < 1:
|
||||||
result.add $(abs(dt.year) + 1)
|
result.add $(abs(dt.year) + 1)
|
||||||
|
|
@ -1933,8 +1924,6 @@ proc parsePattern(input: string, pattern: FormatPattern, i: var int,
|
||||||
i.inc 2
|
i.inc 2
|
||||||
else:
|
else:
|
||||||
result = false
|
result = false
|
||||||
of y, yyy, yyyyy:
|
|
||||||
raiseAssert "Pattern is invalid for parsing: " & $pattern
|
|
||||||
of Lit: doAssert false, "Can't happen"
|
of Lit: doAssert false, "Can't happen"
|
||||||
|
|
||||||
proc toDateTime(p: ParsedTime, zone: Timezone, f: TimeFormat,
|
proc toDateTime(p: ParsedTime, zone: Timezone, f: TimeFormat,
|
||||||
|
|
@ -2631,167 +2620,11 @@ when not defined(js):
|
||||||
else:
|
else:
|
||||||
result = toFloat(int(getClock())) / toFloat(clocksPerSec)
|
result = toFloat(int(getClock())) / toFloat(clocksPerSec)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Deprecations
|
# Deprecations
|
||||||
#
|
#
|
||||||
|
|
||||||
proc countLeapYears*(yearSpan: int): int
|
|
||||||
{.deprecated.} =
|
|
||||||
## Returns the number of leap years spanned by a given number of years.
|
|
||||||
##
|
|
||||||
## **Note:** For leap years, start date is assumed to be 1 AD.
|
|
||||||
## counts the number of leap years up to January 1st of a given year.
|
|
||||||
## Keep in mind that if specified year is a leap year, the leap day
|
|
||||||
## has not happened before January 1st of that year.
|
|
||||||
# Deprecated since v0.20.0
|
|
||||||
(yearSpan - 1) div 4 - (yearSpan - 1) div 100 + (yearSpan - 1) div 400
|
|
||||||
|
|
||||||
proc countDays*(yearSpan: int): int
|
|
||||||
{.deprecated.} =
|
|
||||||
## Returns the number of days spanned by a given number of years.
|
|
||||||
# Deprecated since v0.20.0
|
|
||||||
(yearSpan - 1) * 365 + countLeapYears(yearSpan)
|
|
||||||
|
|
||||||
proc countYears*(daySpan: int): int
|
|
||||||
{.deprecated.} =
|
|
||||||
## Returns the number of years spanned by a given number of days.
|
|
||||||
# Deprecated since v0.20.0
|
|
||||||
((daySpan - countLeapYears(daySpan div 365)) div 365)
|
|
||||||
|
|
||||||
proc countYearsAndDays*(daySpan: int): tuple[years: int, days: int]
|
|
||||||
{.deprecated.} =
|
|
||||||
## Returns the number of years spanned by a given number of days and the
|
|
||||||
## remainder as days.
|
|
||||||
# Deprecated since v0.20.0
|
|
||||||
let days = daySpan - countLeapYears(daySpan div 365)
|
|
||||||
result.years = days div 365
|
|
||||||
result.days = days mod 365
|
|
||||||
|
|
||||||
proc toTimeInterval*(time: Time): TimeInterval
|
|
||||||
{.deprecated: "Use 'between' instead".} =
|
|
||||||
## Converts a Time to a TimeInterval. To be used when diffing times.
|
|
||||||
# Deprecated since version 0.20.0
|
|
||||||
runnableExamples:
|
|
||||||
let a = fromUnix(10)
|
|
||||||
let b = fromUnix(1_500_000_000)
|
|
||||||
let ti = b.toTimeInterval() - a.toTimeInterval()
|
|
||||||
doAssert a + ti == b
|
|
||||||
var dt = time.local
|
|
||||||
initTimeInterval(dt.nanosecond, 0, 0, dt.second, dt.minute, dt.hour,
|
|
||||||
dt.monthday, 0, dt.month.ord - 1, dt.year)
|
|
||||||
|
|
||||||
proc weeks*(dur: Duration): int64
|
|
||||||
{.inline, deprecated: "Use 'inWeeks' instead".} =
|
|
||||||
## Number of whole weeks represented by the duration.
|
|
||||||
# Deprecated since version v0.20.0
|
|
||||||
runnableExamples:
|
|
||||||
let dur = initDuration(weeks = 1, days = 2, hours = 3, minutes = 4)
|
|
||||||
doAssert dur.weeks == 1
|
|
||||||
dur.inWeeks
|
|
||||||
|
|
||||||
proc days*(dur: Duration): int64
|
|
||||||
{.inline, deprecated: "Use 'inDays' instead".} =
|
|
||||||
## Number of whole days represented by the duration.
|
|
||||||
# Deprecated since version v0.20.0
|
|
||||||
runnableExamples:
|
|
||||||
let dur = initDuration(weeks = 1, days = 2, hours = 3, minutes = 4)
|
|
||||||
doAssert dur.days == 9
|
|
||||||
dur.inDays
|
|
||||||
|
|
||||||
proc hours*(dur: Duration): int64
|
|
||||||
{.inline, deprecated: "Use 'inHours' instead".} =
|
|
||||||
## Number of whole hours represented by the duration.
|
|
||||||
# Deprecated since version v0.20.0
|
|
||||||
runnableExamples:
|
|
||||||
let dur = initDuration(days = 1, hours = 2, minutes = 3)
|
|
||||||
doAssert dur.hours == 26
|
|
||||||
dur.inHours
|
|
||||||
|
|
||||||
proc minutes*(dur: Duration): int64
|
|
||||||
{.inline, deprecated: "Use 'inMinutes' instead".} =
|
|
||||||
## Number of whole minutes represented by the duration.
|
|
||||||
# Deprecated since version v0.20.0
|
|
||||||
runnableExamples:
|
|
||||||
let dur = initDuration(days = 1, hours = 2, minutes = 3)
|
|
||||||
doAssert dur.minutes == 1563
|
|
||||||
dur.inMinutes
|
|
||||||
|
|
||||||
proc seconds*(dur: Duration): int64
|
|
||||||
{.inline, deprecated: "Use 'inSeconds' instead".} =
|
|
||||||
## Number of whole seconds represented by the duration.
|
|
||||||
# Deprecated since version v0.20.0
|
|
||||||
runnableExamples:
|
|
||||||
let dur = initDuration(minutes = 10, seconds = 30)
|
|
||||||
doAssert dur.seconds == 630
|
|
||||||
dur.inSeconds
|
|
||||||
|
|
||||||
proc milliseconds*(dur: Duration): int {.inline, deprecated.} =
|
|
||||||
## Number of whole milliseconds represented by the **fractional**
|
|
||||||
## part of the duration.
|
|
||||||
# Deprecated since version v0.20.0
|
|
||||||
runnableExamples:
|
|
||||||
let dur = initDuration(minutes = 5, seconds = 6, milliseconds = 7,
|
|
||||||
microseconds = 8, nanoseconds = 9)
|
|
||||||
doAssert dur.milliseconds == 7
|
|
||||||
result = convert(Nanoseconds, Milliseconds, dur.nanosecond)
|
|
||||||
|
|
||||||
proc microseconds*(dur: Duration): int {.inline, deprecated.} =
|
|
||||||
## Number of whole microseconds represented by the **fractional**
|
|
||||||
## part of the duration.
|
|
||||||
# Deprecated since version v0.20.0
|
|
||||||
runnableExamples:
|
|
||||||
let dur = initDuration(minutes = 5, seconds = 6, milliseconds = 7,
|
|
||||||
microseconds = 8, nanoseconds = 9)
|
|
||||||
doAssert dur.microseconds == 7008
|
|
||||||
result = convert(Nanoseconds, Microseconds, dur.nanosecond)
|
|
||||||
|
|
||||||
proc nanoseconds*(dur: Duration): NanosecondRange {.inline, deprecated.} =
|
|
||||||
## Number of whole microseconds represented by the **fractional**
|
|
||||||
## part of the duration.
|
|
||||||
# Deprecated since version v0.20.0
|
|
||||||
runnableExamples:
|
|
||||||
let dur = initDuration(minutes = 5, seconds = 6, milliseconds = 7,
|
|
||||||
microseconds = 8, nanoseconds = 9)
|
|
||||||
doAssert dur.nanoseconds == 7008009
|
|
||||||
dur.nanosecond
|
|
||||||
|
|
||||||
proc fractional*(dur: Duration): Duration {.inline, deprecated.} =
|
|
||||||
## The fractional part of `dur`, as a duration.
|
|
||||||
# Deprecated since version v0.20.0
|
|
||||||
runnableExamples:
|
|
||||||
let dur = initDuration(minutes = 5, seconds = 6, milliseconds = 7,
|
|
||||||
microseconds = 8, nanoseconds = 9)
|
|
||||||
doAssert dur.fractional == initDuration(milliseconds = 7, microseconds = 8,
|
|
||||||
nanoseconds = 9)
|
|
||||||
initDuration(nanoseconds = dur.nanosecond)
|
|
||||||
|
|
||||||
proc fromSeconds*(since1970: float): Time
|
|
||||||
{.tags: [], raises: [], benign, deprecated: "Use `fromUnixFloat or 'fromUnix' instead".} =
|
|
||||||
## Takes a float which contains the number of seconds since the unix epoch and
|
|
||||||
## returns a time object.
|
|
||||||
# Deprecated since v0.18.0
|
|
||||||
fromUnixFloat(since1970)
|
|
||||||
|
|
||||||
proc fromSeconds*(since1970: int64): Time
|
|
||||||
{.tags: [], raises: [], benign, deprecated: "Use 'fromUnix' instead".} =
|
|
||||||
## Takes an int which contains the number of seconds since the unix epoch and
|
|
||||||
## returns a time object.
|
|
||||||
# Deprecated since v0.18.0
|
|
||||||
fromUnix(since1970)
|
|
||||||
|
|
||||||
proc toSeconds*(time: Time): float
|
|
||||||
{.tags: [], raises: [], benign, deprecated: "Use 'toUnixFloat' or 'toUnix' instead".} =
|
|
||||||
## Returns the time in seconds since the unix epoch, with subsecond resolution.
|
|
||||||
# Deprecated since v0.18.0
|
|
||||||
toUnixFloat(time)
|
|
||||||
|
|
||||||
proc getGMTime*(time: Time): DateTime
|
|
||||||
{.tags: [], raises: [], benign, deprecated: "Use 'utc' instead".} =
|
|
||||||
## Converts the calendar time `time` to broken-down time representation,
|
|
||||||
## expressed in Coordinated Universal Time (UTC).
|
|
||||||
# Deprecated since v0.18.0
|
|
||||||
time.utc
|
|
||||||
|
|
||||||
proc `nanosecond=`*(dt: var DateTime, value: NanosecondRange) {.deprecated: "Deprecated since v1.3.1".} =
|
proc `nanosecond=`*(dt: var DateTime, value: NanosecondRange) {.deprecated: "Deprecated since v1.3.1".} =
|
||||||
dt.nanosecond = value
|
dt.nanosecond = value
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1169,88 +1169,6 @@ proc alignLeft*(s: string, count: Natural, padding = ' '.Rune): string {.
|
||||||
else:
|
else:
|
||||||
result = s
|
result = s
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
# deprecated
|
|
||||||
|
|
||||||
template runeCaseCheck(s, runeProc, skipNonAlpha) =
|
|
||||||
## Common code for rune.isLower and rune.isUpper.
|
|
||||||
if len(s) == 0: return false
|
|
||||||
var
|
|
||||||
i = 0
|
|
||||||
rune: Rune
|
|
||||||
hasAtleastOneAlphaRune = false
|
|
||||||
while i < len(s):
|
|
||||||
fastRuneAt(s, i, rune, doInc = true)
|
|
||||||
if skipNonAlpha:
|
|
||||||
var runeIsAlpha = isAlpha(rune)
|
|
||||||
if not hasAtleastOneAlphaRune:
|
|
||||||
hasAtleastOneAlphaRune = runeIsAlpha
|
|
||||||
if runeIsAlpha and (not runeProc(rune)):
|
|
||||||
return false
|
|
||||||
else:
|
|
||||||
if not runeProc(rune):
|
|
||||||
return false
|
|
||||||
return if skipNonAlpha: hasAtleastOneAlphaRune else: true
|
|
||||||
|
|
||||||
proc isLower*(s: string, skipNonAlpha: bool): bool {.
|
|
||||||
deprecated: "Deprecated since version 0.20 since its semantics are unclear".} =
|
|
||||||
## **Deprecated since version 0.20 since its semantics are unclear**
|
|
||||||
##
|
|
||||||
## Checks whether ``s`` is lower case.
|
|
||||||
##
|
|
||||||
## If ``skipNonAlpha`` is true, returns true if all alphabetical
|
|
||||||
## runes in ``s`` are lower case. Returns false if none of the
|
|
||||||
## runes in ``s`` are alphabetical.
|
|
||||||
##
|
|
||||||
## If ``skipNonAlpha`` is false, returns true only if all runes in
|
|
||||||
## ``s`` are alphabetical and lower case.
|
|
||||||
##
|
|
||||||
## For either value of ``skipNonAlpha``, returns false if ``s`` is
|
|
||||||
## an empty string.
|
|
||||||
runeCaseCheck(s, isLower, skipNonAlpha)
|
|
||||||
|
|
||||||
proc isUpper*(s: string, skipNonAlpha: bool): bool {.
|
|
||||||
deprecated: "Deprecated since version 0.20 since its semantics are unclear".} =
|
|
||||||
## **Deprecated since version 0.20 since its semantics are unclear**
|
|
||||||
##
|
|
||||||
## Checks whether ``s`` is upper case.
|
|
||||||
##
|
|
||||||
## If ``skipNonAlpha`` is true, returns true if all alphabetical
|
|
||||||
## runes in ``s`` are upper case. Returns false if none of the
|
|
||||||
## runes in ``s`` are alphabetical.
|
|
||||||
##
|
|
||||||
## If ``skipNonAlpha`` is false, returns true only if all runes in
|
|
||||||
## ``s`` are alphabetical and upper case.
|
|
||||||
##
|
|
||||||
## For either value of ``skipNonAlpha``, returns false if ``s`` is
|
|
||||||
## an empty string.
|
|
||||||
runeCaseCheck(s, isUpper, skipNonAlpha)
|
|
||||||
|
|
||||||
proc isTitle*(s: string): bool {.noSideEffect, rtl, extern: "nuc$1Str",
|
|
||||||
deprecated: "Deprecated since version 0.20 since its semantics are unclear".} =
|
|
||||||
## **Deprecated since version 0.20 since its semantics are unclear**
|
|
||||||
##
|
|
||||||
## Checks whether or not ``s`` is a unicode title.
|
|
||||||
##
|
|
||||||
## Returns true if the first character in each word inside ``s``
|
|
||||||
## are upper case and there is at least one character in ``s``.
|
|
||||||
if s.len == 0:
|
|
||||||
return false
|
|
||||||
result = true
|
|
||||||
var
|
|
||||||
i = 0
|
|
||||||
rune: Rune
|
|
||||||
var firstRune = true
|
|
||||||
|
|
||||||
while i < len(s) and result:
|
|
||||||
fastRuneAt(s, i, rune, doInc = true)
|
|
||||||
if not rune.isWhiteSpace() and firstRune:
|
|
||||||
result = rune.isUpper() and result
|
|
||||||
firstRune = false
|
|
||||||
elif rune.isWhiteSpace():
|
|
||||||
firstRune = true
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -416,8 +416,7 @@ proc ensureInitialized() =
|
||||||
if formatters.len == 0:
|
if formatters.len == 0:
|
||||||
formatters = @[OutputFormatter(defaultConsoleFormatter())]
|
formatters = @[OutputFormatter(defaultConsoleFormatter())]
|
||||||
|
|
||||||
if not disabledParamFiltering and not testsFilters.isValid:
|
if not disabledParamFiltering:
|
||||||
testsFilters.init()
|
|
||||||
when declared(paramCount):
|
when declared(paramCount):
|
||||||
# Read tests to run from the command line.
|
# Read tests to run from the command line.
|
||||||
for i in 1 .. paramCount():
|
for i in 1 .. paramCount():
|
||||||
|
|
@ -712,7 +711,7 @@ macro expect*(exceptions: varargs[typed], body: untyped): untyped =
|
||||||
## import math, random
|
## import math, random
|
||||||
## proc defectiveRobot() =
|
## proc defectiveRobot() =
|
||||||
## randomize()
|
## randomize()
|
||||||
## case random(1..4)
|
## case rand(1..4)
|
||||||
## of 1: raise newException(OSError, "CANNOT COMPUTE!")
|
## of 1: raise newException(OSError, "CANNOT COMPUTE!")
|
||||||
## of 2: discard parseInt("Hello World!")
|
## of 2: discard parseInt("Hello World!")
|
||||||
## of 3: raise newException(IOError, "I can't do that Dave.")
|
## of 3: raise newException(IOError, "I can't do that Dave.")
|
||||||
|
|
|
||||||
|
|
@ -481,18 +481,10 @@ proc `+=`*[T: SomeInteger](x: var T, y: T) {.
|
||||||
magic: "Inc", noSideEffect.}
|
magic: "Inc", noSideEffect.}
|
||||||
## Increments an integer.
|
## Increments an integer.
|
||||||
|
|
||||||
proc `+=`*[T: enum|bool](x: var T, y: T) {.
|
|
||||||
magic: "Inc", noSideEffect, deprecated: "use `inc` instead".}
|
|
||||||
## **Deprecated since v0.20**: use `inc` instead.
|
|
||||||
|
|
||||||
proc `-=`*[T: SomeInteger](x: var T, y: T) {.
|
proc `-=`*[T: SomeInteger](x: var T, y: T) {.
|
||||||
magic: "Dec", noSideEffect.}
|
magic: "Dec", noSideEffect.}
|
||||||
## Decrements an integer.
|
## Decrements an integer.
|
||||||
|
|
||||||
proc `-=`*[T: enum|bool](x: var T, y: T) {.
|
|
||||||
magic: "Dec", noSideEffect, deprecated: "0.20.0, use `dec` instead".}
|
|
||||||
## **Deprecated since v0.20**: use `dec` instead.
|
|
||||||
|
|
||||||
proc `*=`*[T: SomeInteger](x: var T, y: T) {.
|
proc `*=`*[T: SomeInteger](x: var T, y: T) {.
|
||||||
inline, noSideEffect.} =
|
inline, noSideEffect.} =
|
||||||
## Binary `*=` operator for integers.
|
## Binary `*=` operator for integers.
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ pkg1 "coco", true
|
||||||
pkg1 "combparser"
|
pkg1 "combparser"
|
||||||
pkg1 "compactdict"
|
pkg1 "compactdict"
|
||||||
pkg1 "comprehension", false, "nimble test", "https://github.com/alehander42/comprehension"
|
pkg1 "comprehension", false, "nimble test", "https://github.com/alehander42/comprehension"
|
||||||
pkg1 "criterion"
|
|
||||||
pkg1 "dashing", false, "nim c tests/functional.nim"
|
pkg1 "dashing", false, "nim c tests/functional.nim"
|
||||||
pkg1 "delaunay"
|
pkg1 "delaunay"
|
||||||
pkg1 "docopt"
|
pkg1 "docopt"
|
||||||
|
|
|
||||||
27
tests/ccgbugs2/tinefficient_const_table.nim
Normal file
27
tests/ccgbugs2/tinefficient_const_table.nim
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
discard """
|
||||||
|
output: '''a
|
||||||
|
long
|
||||||
|
list
|
||||||
|
of
|
||||||
|
words'''
|
||||||
|
cmd: r"nim c --hints:on $options -d:release $file"
|
||||||
|
ccodecheck: "! @'genericSeqAssign'"
|
||||||
|
target: "c"
|
||||||
|
"""
|
||||||
|
|
||||||
|
# bug #4354
|
||||||
|
import tables
|
||||||
|
import sets
|
||||||
|
import strutils
|
||||||
|
|
||||||
|
#const FRUITS = ["banana", "apple", "grapes"]
|
||||||
|
#let FRUITS = ["banana", "apple", "grapes"].toHashSet
|
||||||
|
const FRUITS = {"banana":0, "apple":0, "grapes":0}.toTable
|
||||||
|
|
||||||
|
proc main() =
|
||||||
|
let L = "a long list of words".split()
|
||||||
|
for word in L:
|
||||||
|
if word notin FRUITS:
|
||||||
|
echo(word)
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
@ -79,9 +79,8 @@ block hashForHashedSet:
|
||||||
let
|
let
|
||||||
seq1 = "This is the test."
|
seq1 = "This is the test."
|
||||||
seq2 = "the test is This."
|
seq2 = "the test is This."
|
||||||
s1 = seq1.toSet()
|
s1 = seq1.toHashSet()
|
||||||
s2 = seq2.toSet()
|
s2 = seq2.toHashSet()
|
||||||
var hashSeq: seq[Hash] = @[]
|
|
||||||
doAssert s1 == s2
|
doAssert s1 == s2
|
||||||
doAssert hash(s1) == hash(s2)
|
doAssert hash(s1) == hash(s2)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Copyright (C) 2015 Dominik Picheta
|
# Copyright (C) 2015 Dominik Picheta
|
||||||
# MIT License - Look at license.txt for details.
|
# MIT License - Look at license.txt for details.
|
||||||
import net, strtabs, re, tables, parseutils, os, strutils, uri,
|
import net, strtabs, re, tables, os, strutils, uri,
|
||||||
times, mimetypes, asyncnet, asyncdispatch, macros, md5,
|
times, mimetypes, asyncnet, asyncdispatch, macros, md5,
|
||||||
logging, httpcore, asyncfile, macrocache, json, options,
|
logging, httpcore, asyncfile, macrocache, json, options,
|
||||||
strformat
|
strformat
|
||||||
|
|
@ -23,6 +23,7 @@ export SameSite
|
||||||
when useHttpBeast:
|
when useHttpBeast:
|
||||||
import httpbeast except Settings, Request
|
import httpbeast except Settings, Request
|
||||||
import options
|
import options
|
||||||
|
from nativesockets import close
|
||||||
else:
|
else:
|
||||||
import asynchttpserver except Request
|
import asynchttpserver except Request
|
||||||
|
|
||||||
|
|
@ -72,14 +73,14 @@ type
|
||||||
of RouteCode:
|
of RouteCode:
|
||||||
data: ResponseData
|
data: ResponseData
|
||||||
|
|
||||||
const jesterVer = "0.4.0"
|
const jesterVer = "0.4.3"
|
||||||
|
|
||||||
proc toStr(headers: Option[RawHeaders]): string =
|
proc toStr(headers: Option[RawHeaders]): string =
|
||||||
return $newHttpHeaders(headers.get(@({:})))
|
return $newHttpHeaders(headers.get(@({:})))
|
||||||
|
|
||||||
proc createHeaders(headers: RawHeaders): string =
|
proc createHeaders(headers: RawHeaders): string =
|
||||||
result = ""
|
result = ""
|
||||||
if headers != nil:
|
if headers.len > 0:
|
||||||
for header in headers:
|
for header in headers:
|
||||||
let (key, value) = header
|
let (key, value) = header
|
||||||
result.add(key & ": " & value & "\c\L")
|
result.add(key & ": " & value & "\c\L")
|
||||||
|
|
@ -98,22 +99,24 @@ proc unsafeSend(request: Request, content: string) =
|
||||||
|
|
||||||
proc send(
|
proc send(
|
||||||
request: Request, code: HttpCode, headers: Option[RawHeaders], body: string
|
request: Request, code: HttpCode, headers: Option[RawHeaders], body: string
|
||||||
) =
|
): Future[void] =
|
||||||
when useHttpBeast:
|
when useHttpBeast:
|
||||||
let h =
|
let h =
|
||||||
if headers.isNone: ""
|
if headers.isNone: ""
|
||||||
else: headers.get().createHeaders
|
else: headers.get().createHeaders
|
||||||
request.getNativeReq.send(code, body, h)
|
request.getNativeReq.send(code, body, h)
|
||||||
|
var fut = newFuture[void]()
|
||||||
|
complete(fut)
|
||||||
|
return fut
|
||||||
else:
|
else:
|
||||||
# TODO: This may cause issues if we send too fast.
|
return request.getNativeReq.respond(
|
||||||
asyncCheck request.getNativeReq.respond(
|
|
||||||
code, body, newHttpHeaders(headers.get(@({:})))
|
code, body, newHttpHeaders(headers.get(@({:})))
|
||||||
)
|
)
|
||||||
|
|
||||||
proc statusContent(request: Request, status: HttpCode, content: string,
|
proc statusContent(request: Request, status: HttpCode, content: string,
|
||||||
headers: Option[RawHeaders]) =
|
headers: Option[RawHeaders]): Future[void] =
|
||||||
try:
|
try:
|
||||||
send(request, status, headers, content)
|
result = send(request, status, headers, content)
|
||||||
when not defined(release):
|
when not defined(release):
|
||||||
logging.debug(" $1 $2" % [$status, toStr(headers)])
|
logging.debug(" $1 $2" % [$status, toStr(headers)])
|
||||||
except:
|
except:
|
||||||
|
|
@ -174,7 +177,11 @@ proc sendStaticIfExists(
|
||||||
return Http403
|
return Http403
|
||||||
|
|
||||||
let fileSize = getFileSize(p)
|
let fileSize = getFileSize(p)
|
||||||
let mimetype = req.settings.mimes.getMimetype(p.splitFile.ext[1 .. ^1])
|
let ext = p.splitFile.ext
|
||||||
|
let mimetype = req.settings.mimes.getMimetype(
|
||||||
|
if ext.len > 0: ext[1 .. ^1]
|
||||||
|
else: ""
|
||||||
|
)
|
||||||
if fileSize < 10_000_000: # 10 mb
|
if fileSize < 10_000_000: # 10 mb
|
||||||
var file = readFile(p)
|
var file = readFile(p)
|
||||||
|
|
||||||
|
|
@ -183,18 +190,18 @@ proc sendStaticIfExists(
|
||||||
# If the user has a cached version of this file and it matches our
|
# If the user has a cached version of this file and it matches our
|
||||||
# version, let them use it
|
# version, let them use it
|
||||||
if req.headers.hasKey("If-None-Match") and req.headers["If-None-Match"] == hashed:
|
if req.headers.hasKey("If-None-Match") and req.headers["If-None-Match"] == hashed:
|
||||||
req.statusContent(Http304, "", none[RawHeaders]())
|
await req.statusContent(Http304, "", none[RawHeaders]())
|
||||||
else:
|
else:
|
||||||
req.statusContent(Http200, file, some(@({
|
await req.statusContent(Http200, file, some(@({
|
||||||
"Content-Type": mimetype,
|
"Content-Type": mimetype,
|
||||||
"ETag": hashed
|
"ETag": hashed
|
||||||
})))
|
})))
|
||||||
else:
|
else:
|
||||||
let headers = @({
|
let headers = @({
|
||||||
"Content-Type": mimetype,
|
"Content-Type": mimetype,
|
||||||
"Content-Length": $fileSize
|
"Content-Length": $fileSize
|
||||||
})
|
})
|
||||||
req.statusContent(Http200, "", some(headers))
|
await req.statusContent(Http200, "", some(headers))
|
||||||
|
|
||||||
var fileStream = newFutureStream[string]("sendStaticIfExists")
|
var fileStream = newFutureStream[string]("sendStaticIfExists")
|
||||||
var file = openAsync(p, fmRead)
|
var file = openAsync(p, fmRead)
|
||||||
|
|
@ -216,13 +223,22 @@ proc sendStaticIfExists(
|
||||||
# If we get to here then no match could be found.
|
# If we get to here then no match could be found.
|
||||||
return Http404
|
return Http404
|
||||||
|
|
||||||
|
proc close*(request: Request) =
|
||||||
|
## Closes client socket connection.
|
||||||
|
##
|
||||||
|
## Routes using this procedure must enable raw mode.
|
||||||
|
let nativeReq = request.getNativeReq()
|
||||||
|
when useHttpBeast:
|
||||||
|
nativeReq.forget()
|
||||||
|
nativeReq.client.close()
|
||||||
|
|
||||||
proc defaultErrorFilter(error: RouteError): ResponseData =
|
proc defaultErrorFilter(error: RouteError): ResponseData =
|
||||||
case error.kind
|
case error.kind
|
||||||
of RouteException:
|
of RouteException:
|
||||||
let e = error.exc
|
let e = error.exc
|
||||||
let traceback = getStackTrace(e)
|
let traceback = getStackTrace(e)
|
||||||
var errorMsg = e.msg
|
var errorMsg = e.msg
|
||||||
if errorMsg.isNil: errorMsg = "(nil)"
|
if errorMsg.len == 0: errorMsg = "(empty)"
|
||||||
|
|
||||||
let error = traceback & errorMsg
|
let error = traceback & errorMsg
|
||||||
logging.error(error)
|
logging.error(error)
|
||||||
|
|
@ -295,9 +311,11 @@ proc handleFileRequest(
|
||||||
jes.settings.staticDir / cgi.decodeUrl(req.pathInfo)
|
jes.settings.staticDir / cgi.decodeUrl(req.pathInfo)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Verify that this isn't outside our static` dir.
|
# Verify that this isn't outside our static dir.
|
||||||
var status = Http400
|
var status = Http400
|
||||||
if path.splitFile.dir.startsWith(jes.settings.staticDir):
|
let pathDir = path.splitFile.dir / ""
|
||||||
|
let staticDir = jes.settings.staticDir / ""
|
||||||
|
if pathDir.startsWith(staticDir):
|
||||||
if existsDir(path):
|
if existsDir(path):
|
||||||
status = await sendStaticIfExists(
|
status = await sendStaticIfExists(
|
||||||
req,
|
req,
|
||||||
|
|
@ -347,7 +365,7 @@ proc handleRequestSlow(
|
||||||
not dispatchedError and respData.content.len == 0:
|
not dispatchedError and respData.content.len == 0:
|
||||||
respData = await dispatchError(jes, req, initRouteError(respData))
|
respData = await dispatchError(jes, req, initRouteError(respData))
|
||||||
|
|
||||||
statusContent(
|
await statusContent(
|
||||||
req,
|
req,
|
||||||
respData.code,
|
respData.code,
|
||||||
respData.content,
|
respData.content,
|
||||||
|
|
@ -368,7 +386,7 @@ proc handleRequest(jes: Jester, httpReq: NativeRequest): Future[void] =
|
||||||
if likely(jes.matchers.len == 1 and not jes.matchers[0].async):
|
if likely(jes.matchers.len == 1 and not jes.matchers[0].async):
|
||||||
let respData = jes.matchers[0].syncProc(req)
|
let respData = jes.matchers[0].syncProc(req)
|
||||||
if likely(respData.matched):
|
if likely(respData.matched):
|
||||||
statusContent(
|
return statusContent(
|
||||||
req,
|
req,
|
||||||
respData.code,
|
respData.code,
|
||||||
respData.content,
|
respData.content,
|
||||||
|
|
@ -383,6 +401,8 @@ proc handleRequest(jes: Jester, httpReq: NativeRequest): Future[void] =
|
||||||
let respDataFut = dispatchError(jes, req, initRouteError(exc))
|
let respDataFut = dispatchError(jes, req, initRouteError(exc))
|
||||||
return handleRequestSlow(jes, req, respDataFut, true)
|
return handleRequestSlow(jes, req, respDataFut, true)
|
||||||
|
|
||||||
|
assert(not result.isNil, "Expected handleRequest to return a valid future.")
|
||||||
|
|
||||||
proc newSettings*(
|
proc newSettings*(
|
||||||
port = Port(5000), staticDir = getCurrentDir() / "public",
|
port = Port(5000), staticDir = getCurrentDir() / "public",
|
||||||
appName = "", bindAddr = "", reusePort = false,
|
appName = "", bindAddr = "", reusePort = false,
|
||||||
|
|
@ -461,14 +481,19 @@ proc serve*(
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
logging.info("Jester is making jokes at http://0.0.0.0:$1$2" %
|
when defined(windows):
|
||||||
[$self.settings.port, self.settings.appName])
|
logging.info("Jester is making jokes at http://127.0.0.1:$1$2 (all interfaces)" %
|
||||||
|
[$self.settings.port, self.settings.appName])
|
||||||
|
else:
|
||||||
|
logging.info("Jester is making jokes at http://0.0.0.0:$1$2" %
|
||||||
|
[$self.settings.port, self.settings.appName])
|
||||||
|
|
||||||
var jes = self
|
var jes = self
|
||||||
when useHttpBeast:
|
when useHttpBeast:
|
||||||
run(
|
run(
|
||||||
proc (req: httpbeast.Request): Future[void] =
|
proc (req: httpbeast.Request): Future[void] =
|
||||||
result = handleRequest(jes, req),
|
{.gcsafe.}:
|
||||||
|
result = handleRequest(jes, req),
|
||||||
httpbeast.initSettings(self.settings.port, self.settings.bindAddr)
|
httpbeast.initSettings(self.settings.port, self.settings.bindAddr)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
|
@ -484,14 +509,6 @@ proc serve*(
|
||||||
asyncCheck serveFut
|
asyncCheck serveFut
|
||||||
runForever()
|
runForever()
|
||||||
|
|
||||||
template resp*(code: HttpCode,
|
|
||||||
headers: openarray[tuple[key, value: string]],
|
|
||||||
content: string): typed =
|
|
||||||
## Sets ``(code, headers, content)`` as the response.
|
|
||||||
bind TCActionSend, newHttpHeaders
|
|
||||||
result = (TCActionSend, code, headers.newHttpHeaders.some(), content, true)
|
|
||||||
break route
|
|
||||||
|
|
||||||
template setHeader(headers: var Option[RawHeaders], key, value: string): typed =
|
template setHeader(headers: var Option[RawHeaders], key, value: string): typed =
|
||||||
bind isNone
|
bind isNone
|
||||||
if isNone(headers):
|
if isNone(headers):
|
||||||
|
|
@ -509,6 +526,17 @@ template setHeader(headers: var Option[RawHeaders], key, value: string): typed =
|
||||||
# Add key if it doesn't exist.
|
# Add key if it doesn't exist.
|
||||||
headers = some(h & @({key: value}))
|
headers = some(h & @({key: value}))
|
||||||
|
|
||||||
|
template resp*(code: HttpCode,
|
||||||
|
headers: openarray[tuple[key, val: string]],
|
||||||
|
content: string): typed =
|
||||||
|
## Sets ``(code, headers, content)`` as the response.
|
||||||
|
bind TCActionSend
|
||||||
|
result = (TCActionSend, code, none[RawHeaders](), content, true)
|
||||||
|
for header in headers:
|
||||||
|
setHeader(result[2], header[0], header[1])
|
||||||
|
break route
|
||||||
|
|
||||||
|
|
||||||
template resp*(content: string, contentType = "text/html;charset=utf-8"): typed =
|
template resp*(content: string, contentType = "text/html;charset=utf-8"): typed =
|
||||||
## Sets ``content`` as the response; ``Http200`` as the status code
|
## Sets ``content`` as the response; ``Http200`` as the status code
|
||||||
## and ``contentType`` as the Content-Type.
|
## and ``contentType`` as the Content-Type.
|
||||||
|
|
@ -687,7 +715,8 @@ proc daysForward*(days: int): DateTime =
|
||||||
return getTime().utc + initTimeInterval(days = days)
|
return getTime().utc + initTimeInterval(days = days)
|
||||||
|
|
||||||
template setCookie*(name, value: string, expires="",
|
template setCookie*(name, value: string, expires="",
|
||||||
sameSite: SameSite=Lax): typed =
|
sameSite: SameSite=Lax, secure = false,
|
||||||
|
httpOnly = false, domain = "", path = "") =
|
||||||
## Creates a cookie which stores ``value`` under ``name``.
|
## Creates a cookie which stores ``value`` under ``name``.
|
||||||
##
|
##
|
||||||
## The SameSite argument determines the level of CSRF protection that
|
## The SameSite argument determines the level of CSRF protection that
|
||||||
|
|
@ -695,7 +724,7 @@ template setCookie*(name, value: string, expires="",
|
||||||
## should protect you from most vulnerabilities. Note that this is only
|
## should protect you from most vulnerabilities. Note that this is only
|
||||||
## supported by some browsers:
|
## supported by some browsers:
|
||||||
## https://caniuse.com/#feat=same-site-cookie-attribute
|
## https://caniuse.com/#feat=same-site-cookie-attribute
|
||||||
let newCookie = makeCookie(name, value, expires)
|
let newCookie = makeCookie(name, value, expires, domain, path, secure, httpOnly, sameSite)
|
||||||
if isSome(result[2]) and
|
if isSome(result[2]) and
|
||||||
(let headers = result[2].get(); headers.toTable.hasKey("Set-Cookie")):
|
(let headers = result[2].get(); headers.toTable.hasKey("Set-Cookie")):
|
||||||
result[2] = some(headers & @({"Set-Cookie": newCookie}))
|
result[2] = some(headers & @({"Set-Cookie": newCookie}))
|
||||||
|
|
@ -703,9 +732,12 @@ template setCookie*(name, value: string, expires="",
|
||||||
setHeader(result[2], "Set-Cookie", newCookie)
|
setHeader(result[2], "Set-Cookie", newCookie)
|
||||||
|
|
||||||
template setCookie*(name, value: string, expires: DateTime,
|
template setCookie*(name, value: string, expires: DateTime,
|
||||||
sameSite: SameSite=Lax): typed =
|
sameSite: SameSite=Lax, secure = false,
|
||||||
|
httpOnly = false, domain = "", path = "") =
|
||||||
## Creates a cookie which stores ``value`` under ``name``.
|
## Creates a cookie which stores ``value`` under ``name``.
|
||||||
setCookie(name, value, format(expires, "ddd',' dd MMM yyyy HH:mm:ss 'GMT'"))
|
setCookie(name, value,
|
||||||
|
format(expires.utc, "ddd',' dd MMM yyyy HH:mm:ss 'GMT'"),
|
||||||
|
sameSite, secure, httpOnly, domain, path)
|
||||||
|
|
||||||
proc normalizeUri*(uri: string): string =
|
proc normalizeUri*(uri: string): string =
|
||||||
## Remove any trailing ``/``.
|
## Remove any trailing ``/``.
|
||||||
|
|
@ -721,7 +753,10 @@ proc checkAction*(respData: var ResponseData): bool =
|
||||||
of TCActionPass:
|
of TCActionPass:
|
||||||
result = false
|
result = false
|
||||||
of TCActionNothing:
|
of TCActionNothing:
|
||||||
assert(false)
|
raise newException(
|
||||||
|
ValueError,
|
||||||
|
"Missing route action, did you forget to use `resp` in your route?"
|
||||||
|
)
|
||||||
|
|
||||||
proc skipDo(node: NimNode): NimNode {.compiletime.} =
|
proc skipDo(node: NimNode): NimNode {.compiletime.} =
|
||||||
if node.kind == nnkDo:
|
if node.kind == nnkDo:
|
||||||
|
|
@ -764,14 +799,14 @@ proc ctParsePattern(pattern, pathPrefix: string): NimNode {.compiletime.} =
|
||||||
newStrLitNode(node.text),
|
newStrLitNode(node.text),
|
||||||
newIdentNode(if node.optional: "true" else: "false"))
|
newIdentNode(if node.optional: "true" else: "false"))
|
||||||
|
|
||||||
template setDefaultResp*(): typed =
|
template setDefaultResp*() =
|
||||||
# TODO: bindSym this in the 'routes' macro and put it in each route
|
# TODO: bindSym this in the 'routes' macro and put it in each route
|
||||||
bind TCActionNothing, newHttpHeaders
|
bind TCActionNothing, newHttpHeaders
|
||||||
result.action = TCActionNothing
|
result.action = TCActionNothing
|
||||||
result.code = Http200
|
result.code = Http200
|
||||||
result.content = ""
|
result.content = ""
|
||||||
|
|
||||||
template declareSettings(): typed {.dirty.} =
|
template declareSettings() {.dirty.} =
|
||||||
when not declaredInScope(settings):
|
when not declaredInScope(settings):
|
||||||
var settings = newSettings()
|
var settings = newSettings()
|
||||||
|
|
||||||
|
|
@ -1299,7 +1334,7 @@ proc routesEx(name: string, body: NimNode): NimNode =
|
||||||
for branch in exceptionBranches:
|
for branch in exceptionBranches:
|
||||||
stmts.add(newIfStmt(branch))
|
stmts.add(newIfStmt(branch))
|
||||||
errorHandlerProc[6][0][1][^1][1][1][0] = stmts
|
errorHandlerProc[6][0][1][^1][1][1][0] = stmts
|
||||||
if httpCodeBranches.len > 1:
|
if httpCodeBranches.len != 0:
|
||||||
var stmts = newStmtList()
|
var stmts = newStmtList()
|
||||||
for branch in httpCodeBranches:
|
for branch in httpCodeBranches:
|
||||||
stmts.add(newIfStmt(branch))
|
stmts.add(newIfStmt(branch))
|
||||||
|
|
@ -1313,7 +1348,7 @@ proc routesEx(name: string, body: NimNode): NimNode =
|
||||||
# echo toStrLit(result)
|
# echo toStrLit(result)
|
||||||
# echo treeRepr(result)
|
# echo treeRepr(result)
|
||||||
|
|
||||||
macro routes*(body: untyped): typed =
|
macro routes*(body: untyped) =
|
||||||
result = routesEx("match", body)
|
result = routesEx("match", body)
|
||||||
let jesIdent = genSym(nskVar, "jes")
|
let jesIdent = genSym(nskVar, "jes")
|
||||||
let matchIdent = newIdentNode("match")
|
let matchIdent = newIdentNode("match")
|
||||||
|
|
@ -1329,13 +1364,13 @@ macro routes*(body: untyped): typed =
|
||||||
serve(`jesIdent`)
|
serve(`jesIdent`)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro router*(name: untyped, body: untyped): typed =
|
macro router*(name: untyped, body: untyped) =
|
||||||
if name.kind != nnkIdent:
|
if name.kind != nnkIdent:
|
||||||
error("Need an ident.", name)
|
error("Need an ident.", name)
|
||||||
|
|
||||||
routesEx($name.ident, body)
|
routesEx(strVal(name), body)
|
||||||
|
|
||||||
macro settings*(body: untyped): typed =
|
macro settings*(body: untyped) =
|
||||||
#echo(treeRepr(body))
|
#echo(treeRepr(body))
|
||||||
expectKind(body, nnkStmtList)
|
expectKind(body, nnkStmtList)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "0.4.0" # Be sure to update jester.jesterVer too!
|
version = "0.4.3" # Be sure to update jester.jesterVer too!
|
||||||
author = "Dominik Picheta"
|
author = "Dominik Picheta"
|
||||||
description = "A sinatra-like web framework for Nim."
|
description = "A sinatra-like web framework for Nim."
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
@ -13,10 +13,10 @@ skipDirs = @["tests"]
|
||||||
requires "nim >= 0.18.1"
|
requires "nim >= 0.18.1"
|
||||||
|
|
||||||
when not defined(windows):
|
when not defined(windows):
|
||||||
requires "httpbeast >= 0.2.0"
|
requires "httpbeast >= 0.2.2"
|
||||||
|
|
||||||
# For tests
|
# For tests
|
||||||
requires "asynctools"
|
requires "https://github.com/timotheecour/asynctools#pr_fix_compilation"
|
||||||
|
|
||||||
task test, "Runs the test suite.":
|
task test, "Runs the test suite.":
|
||||||
exec "nimble c -y -r tests/tester"
|
exec "nimble c -y -r tests/tester"
|
||||||
|
|
@ -15,7 +15,7 @@ type
|
||||||
proc parsePattern*(pattern: string): Pattern =
|
proc parsePattern*(pattern: string): Pattern =
|
||||||
result = @[]
|
result = @[]
|
||||||
template addNode(result: var Pattern, theT: NodeType, theText: string,
|
template addNode(result: var Pattern, theT: NodeType, theText: string,
|
||||||
isOptional: bool): typed =
|
isOptional: bool) =
|
||||||
block:
|
block:
|
||||||
var newNode: Node
|
var newNode: Node
|
||||||
newNode.typ = theT
|
newNode.typ = theT
|
||||||
|
|
@ -120,7 +120,7 @@ proc match*(pattern: Pattern, s: string):
|
||||||
if s.len != i:
|
if s.len != i:
|
||||||
result.matched = false
|
result.matched = false
|
||||||
|
|
||||||
when true:
|
when isMainModule:
|
||||||
let f = parsePattern("/show/@id/test/@show?/?")
|
let f = parsePattern("/show/@id/test/@show?/?")
|
||||||
doAssert match(f, "/show/12/test/hallo/").matched
|
doAssert match(f, "/show/12/test/hallo/").matched
|
||||||
doAssert match(f, "/show/2131726/test/jjjuuwąąss").matched
|
doAssert match(f, "/show/2131726/test/jjjuuwąąss").matched
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ type
|
||||||
JesterError* = object of Exception
|
JesterError* = object of Exception
|
||||||
|
|
||||||
proc parseUrlQuery*(query: string, result: var Table[string, string])
|
proc parseUrlQuery*(query: string, result: var Table[string, string])
|
||||||
{.deprecated: "use stdlib".} =
|
{.deprecated: "use stdlib cgi/decodeData".} =
|
||||||
var i = 0
|
var i = 0
|
||||||
i = query.skip("?")
|
i = query.skip("?")
|
||||||
while i < query.len()-1:
|
while i < query.len()-1:
|
||||||
|
|
@ -192,4 +192,3 @@ when false:
|
||||||
var r = {:}.newStringTable
|
var r = {:}.newStringTable
|
||||||
parseUrlQuery("FirstName=Mickey", r)
|
parseUrlQuery("FirstName=Mickey", r)
|
||||||
echo r
|
echo r
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ proc reqMethod*(req: Request): HttpMethod =
|
||||||
req.req.httpMethod.get()
|
req.req.httpMethod.get()
|
||||||
else:
|
else:
|
||||||
req.req.reqMethod
|
req.req.reqMethod
|
||||||
|
|
||||||
proc reqMeth*(req: Request): HttpMethod {.deprecated.} =
|
proc reqMeth*(req: Request): HttpMethod {.deprecated.} =
|
||||||
req.reqMethod
|
req.reqMethod
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ proc main =
|
||||||
for ii in 0..50_000:
|
for ii in 0..50_000:
|
||||||
#while true:
|
#while true:
|
||||||
var t = getTime()
|
var t = getTime()
|
||||||
var g = t.getGMTime()
|
var g = t.utc()
|
||||||
#echo isOnStack(addr g)
|
#echo isOnStack(addr g)
|
||||||
|
|
||||||
if i mod 100 == 0:
|
if i mod 100 == 0:
|
||||||
|
|
|
||||||
|
|
@ -447,7 +447,7 @@ proc build_help*(expected: seq[Tparameter_specification] = @[],
|
||||||
|
|
||||||
# First generate the joined version of input parameters in a list.
|
# First generate the joined version of input parameters in a list.
|
||||||
var
|
var
|
||||||
seen = initSet[string]()
|
seen = initHashSet[string]()
|
||||||
prefixes: seq[string] = @[]
|
prefixes: seq[string] = @[]
|
||||||
helps: seq[string] = @[]
|
helps: seq[string] = @[]
|
||||||
for key in keys:
|
for key in keys:
|
||||||
|
|
|
||||||
|
|
@ -486,7 +486,7 @@ when defined(DebugKeys):
|
||||||
activeVehicle.body.setPos mouseToSpace())
|
activeVehicle.body.setPos mouseToSpace())
|
||||||
ingameClient.registerHandler(KeyY, down, proc() =
|
ingameClient.registerHandler(KeyY, down, proc() =
|
||||||
const looloo = ["Asteroid1", "Asteroid2"]
|
const looloo = ["Asteroid1", "Asteroid2"]
|
||||||
addObject(looloo[random(looloo.len)]))
|
addObject(looloo[rand(looloo.len)]))
|
||||||
ingameClient.registerHandler(KeyO, down, proc() =
|
ingameClient.registerHandler(KeyO, down, proc() =
|
||||||
if objects.len == 0:
|
if objects.len == 0:
|
||||||
echo "Objects is empty"
|
echo "Objects is empty"
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ task "release", "release build":
|
||||||
## zip up all the files and such or something useful here
|
## zip up all the files and such or something useful here
|
||||||
|
|
||||||
task "testskel", "create skeleton test dir for testing":
|
task "testskel", "create skeleton test dir for testing":
|
||||||
let dirname = "test-" & $random(5000)
|
let dirname = "test-" & $rand(5000)
|
||||||
removeDir dirName
|
removeDir dirName
|
||||||
createDir dirName/"data/fnt"
|
createDir dirName/"data/fnt"
|
||||||
copyFile "data/fnt/LiberationMono-Regular", dirName/"data/fnt/LiberationMono-Regular.ttf"
|
copyFile "data/fnt/LiberationMono-Regular", dirName/"data/fnt/LiberationMono-Regular.ttf"
|
||||||
|
|
@ -133,7 +133,7 @@ task "download", "download game assets":
|
||||||
else: ## this crashes, dunno why
|
else: ## this crashes, dunno why
|
||||||
var
|
var
|
||||||
z: TZipArchive
|
z: TZipArchive
|
||||||
destDir = getCurrentDir()/("unzip" & $random(5000))
|
destDir = getCurrentDir()/("unzip" & $rand(5000))
|
||||||
if not z.open(path, fmRead):
|
if not z.open(path, fmRead):
|
||||||
echo "Could not open zip, bad download?"
|
echo "Could not open zip, bad download?"
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ proc post*(database: Database, message: Message) =
|
||||||
raise newException(ValueError, "Message has to be less than 140 characters.")
|
raise newException(ValueError, "Message has to be less than 140 characters.")
|
||||||
|
|
||||||
database.db.exec(sql"INSERT INTO Message VALUES (?, ?, ?);", #<2>
|
database.db.exec(sql"INSERT INTO Message VALUES (?, ?, ?);", #<2>
|
||||||
message.username, $message.time.toSeconds().int, message.msg) #<3>
|
message.username, $message.time.toUnix().int, message.msg) #<3>
|
||||||
|
|
||||||
proc follow*(database: Database, follower: User, user: User) =
|
proc follow*(database: Database, follower: User, user: User) =
|
||||||
database.db.exec(sql"INSERT INTO Following VALUES (?, ?);",#<2>
|
database.db.exec(sql"INSERT INTO Following VALUES (?, ?);",#<2>
|
||||||
|
|
@ -90,4 +90,4 @@ proc findMessages*(database: Database, usernames: seq[string],
|
||||||
"ORDER BY time DESC LIMIT " & $limit),
|
"ORDER BY time DESC LIMIT " & $limit),
|
||||||
usernames)
|
usernames)
|
||||||
for row in messages:
|
for row in messages:
|
||||||
result.add(Message(username: row[0], time: fromSeconds(row[1].parseInt), msg: row[2]))
|
result.add(Message(username: row[0], time: fromUnix(row[1].parseInt), msg: row[2]))
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ routes:
|
||||||
redirect(uri("/" & @"target"))
|
redirect(uri("/" & @"target"))
|
||||||
|
|
||||||
post "/login":
|
post "/login":
|
||||||
setCookie("username", @"username", getTime().getGMTime() + 2.hours)
|
setCookie("username", @"username", getTime().utc() + 2.hours)
|
||||||
redirect("/")
|
redirect("/")
|
||||||
|
|
||||||
post "/createMessage":
|
post "/createMessage":
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@
|
||||||
#for message in messages:
|
#for message in messages:
|
||||||
<div>
|
<div>
|
||||||
<a href="/${message.username}">${message.username}</a>
|
<a href="/${message.username}">${message.username}</a>
|
||||||
<span>${message.time.getGMTime().format("HH:mm MMMM d',' yyyy")}</span>
|
<span>${message.time.utc().format("HH:mm MMMM d',' yyyy")}</span>
|
||||||
<h3>${message.msg}</h3>
|
<h3>${message.msg}</h3>
|
||||||
</div>
|
</div>
|
||||||
#end for
|
#end for
|
||||||
|
|
|
||||||
|
|
@ -60,15 +60,15 @@ block tcritbits:
|
||||||
|
|
||||||
|
|
||||||
block testequivalence:
|
block testequivalence:
|
||||||
doAssert(toSet(@[1,2,3]) <= toSet(@[1,2,3,4]), "equivalent or subset")
|
doAssert(toHashSet(@[1,2,3]) <= toHashSet(@[1,2,3,4]), "equivalent or subset")
|
||||||
doAssert(toSet(@[1,2,3]) <= toSet(@[1,2,3]), "equivalent or subset")
|
doAssert(toHashSet(@[1,2,3]) <= toHashSet(@[1,2,3]), "equivalent or subset")
|
||||||
doAssert((not(toSet(@[1,2,3]) <= toSet(@[1,2]))), "equivalent or subset")
|
doAssert((not(toHashSet(@[1,2,3]) <= toHashSet(@[1,2]))), "equivalent or subset")
|
||||||
doAssert(toSet(@[1,2,3]) <= toSet(@[1,2,3,4]), "strict subset")
|
doAssert(toHashSet(@[1,2,3]) <= toHashSet(@[1,2,3,4]), "strict subset")
|
||||||
doAssert((not(toSet(@[1,2,3]) < toSet(@[1,2,3]))), "strict subset")
|
doAssert((not(toHashSet(@[1,2,3]) < toHashSet(@[1,2,3]))), "strict subset")
|
||||||
doAssert((not(toSet(@[1,2,3]) < toSet(@[1,2]))), "strict subset")
|
doAssert((not(toHashSet(@[1,2,3]) < toHashSet(@[1,2]))), "strict subset")
|
||||||
doAssert((not(toSet(@[1,2,3]) == toSet(@[1,2,3,4]))), "==")
|
doAssert((not(toHashSet(@[1,2,3]) == toHashSet(@[1,2,3,4]))), "==")
|
||||||
doAssert(toSet(@[1,2,3]) == toSet(@[1,2,3]), "==")
|
doAssert(toHashSet(@[1,2,3]) == toHashSet(@[1,2,3]), "==")
|
||||||
doAssert((not(toSet(@[1,2,3]) == toSet(@[1,2]))), "==")
|
doAssert((not(toHashSet(@[1,2,3]) == toHashSet(@[1,2]))), "==")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,10 +47,10 @@ test "unittest multiple requires":
|
||||||
require(true)
|
require(true)
|
||||||
|
|
||||||
|
|
||||||
import math, random
|
import random
|
||||||
from strutils import parseInt
|
from strutils import parseInt
|
||||||
proc defectiveRobot() =
|
proc defectiveRobot() =
|
||||||
case random(1..4)
|
case rand(1..4)
|
||||||
of 1: raise newException(OSError, "CANNOT COMPUTE!")
|
of 1: raise newException(OSError, "CANNOT COMPUTE!")
|
||||||
of 2: discard parseInt("Hello World!")
|
of 2: discard parseInt("Hello World!")
|
||||||
of 3: raise newException(IOError, "I can't do that Dave.")
|
of 3: raise newException(IOError, "I can't do that Dave.")
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ block tgetast_typeliar:
|
||||||
error("Assertion failed: " & $(`message`) & "\n" & `line`)
|
error("Assertion failed: " & $(`message`) & "\n" & `line`)
|
||||||
return
|
return
|
||||||
|
|
||||||
macro assertOrReturn(condition: bool): typed =
|
macro assertOrReturn(condition: bool) =
|
||||||
var message : NimNode = newLit(condition.repr)
|
var message : NimNode = newLit(condition.repr)
|
||||||
# echo message
|
# echo message
|
||||||
result = getAst assertOrReturn2(condition, message)
|
result = getAst assertOrReturn2(condition, message)
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ converter int2string(x: int): string = $x
|
||||||
template wrap(body: typed): untyped =
|
template wrap(body: typed): untyped =
|
||||||
body
|
body
|
||||||
|
|
||||||
macro makeProc(): typed =
|
macro makeProc() =
|
||||||
# Make a template tree
|
# Make a template tree
|
||||||
result = quote do:
|
result = quote do:
|
||||||
proc someProc* =
|
proc someProc* =
|
||||||
|
|
|
||||||
|
|
@ -10,4 +10,4 @@ const EXTENSIONMAP = {
|
||||||
"c": @["*.c", "*.h"],
|
"c": @["*.c", "*.h"],
|
||||||
}.toTable()
|
}.toTable()
|
||||||
|
|
||||||
const EXTENSIONS = toSet(concat(toSeq(EXTENSIONMAP.values())))
|
const EXTENSIONS = toHashSet(concat(toSeq(EXTENSIONMAP.values())))
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ line: 11
|
||||||
|
|
||||||
import sets
|
import sets
|
||||||
|
|
||||||
let BUILTIN_NAMES = toSet(["int8", "int16", "int32", "int64"])
|
let BUILTIN_NAMES = toHashSet(["int8", "int16", "int32", "int64"])
|
||||||
|
|
||||||
macro test*(): bool =
|
macro test*(): bool =
|
||||||
echo "int64" notin BUILTIN_NAMES
|
echo "int64" notin BUILTIN_NAMES
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ proc createChangelog(pkgName, version, maintainer: string): string =
|
||||||
addN(" * Initial release.")
|
addN(" * Initial release.")
|
||||||
addN("")
|
addN("")
|
||||||
addN(" -- " & maintainer & " " &
|
addN(" -- " & maintainer & " " &
|
||||||
formatDateTime(getGMTime(getTime()), "+0000"))
|
formatDateTime(utc(getTime()), "+0000"))
|
||||||
|
|
||||||
proc createRules(): string =
|
proc createRules(): string =
|
||||||
## Creates a nim application-agnostic rules file for building deb packages.
|
## Creates a nim application-agnostic rules file for building deb packages.
|
||||||
|
|
|
||||||
|
|
@ -421,7 +421,7 @@ proc generateRss(outputFilename: string, news: seq[TRssItem]) =
|
||||||
output.write(link(href = rssNewsUrl))
|
output.write(link(href = rssNewsUrl))
|
||||||
output.write(id(rssNewsUrl))
|
output.write(id(rssNewsUrl))
|
||||||
|
|
||||||
let now = getGMTime(getTime())
|
let now = utc(getTime())
|
||||||
output.write(updatedDate($now.year, $(int(now.month) + 1), $now.monthday))
|
output.write(updatedDate($now.year, $(int(now.month) + 1), $now.monthday))
|
||||||
|
|
||||||
for rss in news:
|
for rss in news:
|
||||||
|
|
|
||||||
|
|
@ -250,7 +250,7 @@ runForever()
|
||||||
<p>This section lists the companies and individuals that are, very kindly, contributing a
|
<p>This section lists the companies and individuals that are, very kindly, contributing a
|
||||||
monthly amount to help sustain Nim's development. For more details take a
|
monthly amount to help sustain Nim's development. For more details take a
|
||||||
look at the <a href="https://salt.bountysource.com/teams/nim">Bountysource campaign</a>.</p>
|
look at the <a href="https://salt.bountysource.com/teams/nim">Bountysource campaign</a>.</p>
|
||||||
<p class="lastUpdate">Last updated: ${getTime().getGMTime().format("dd/MM/yyyy")}</p>
|
<p class="lastUpdate">Last updated: ${getTime().utc().format("dd/MM/yyyy")}</p>
|
||||||
<dl>
|
<dl>
|
||||||
${generateSponsors(activeSponsors)}
|
${generateSponsors(activeSponsors)}
|
||||||
</dl>
|
</dl>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue