[backport] run nimpretty on the remaining files

This commit is contained in:
narimiran 2019-09-27 12:30:59 +02:00
commit 5732bb41ef
13 changed files with 457 additions and 414 deletions

View file

@ -23,7 +23,7 @@
when not nimCoroutines and not defined(nimdoc): when not nimCoroutines and not defined(nimdoc):
when defined(noNimCoroutines): when defined(noNimCoroutines):
{.error: "Coroutines can not be used with -d:noNimCoroutines"} {.error: "Coroutines can not be used with -d:noNimCoroutines".}
else: else:
{.error: "Coroutines require -d:nimCoroutines".} {.error: "Coroutines require -d:nimCoroutines".}
@ -75,13 +75,18 @@ elif coroBackend == CORO_BACKEND_UCONTEXT:
Context = ucontext_t Context = ucontext_t
proc getcontext(context: var ucontext_t): int32 {.importc, header: "<ucontext.h>".} proc getcontext(context: var ucontext_t): int32 {.importc,
proc setcontext(context: var ucontext_t): int32 {.importc, header: "<ucontext.h>".} header: "<ucontext.h>".}
proc swapcontext(fromCtx, toCtx: var ucontext_t): int32 {.importc, header: "<ucontext.h>".} proc setcontext(context: var ucontext_t): int32 {.importc,
proc makecontext(context: var ucontext_t, fn: pointer, argc: int32) {.importc, header: "<ucontext.h>", varargs.} header: "<ucontext.h>".}
proc swapcontext(fromCtx, toCtx: var ucontext_t): int32 {.importc,
header: "<ucontext.h>".}
proc makecontext(context: var ucontext_t, fn: pointer, argc: int32) {.importc,
header: "<ucontext.h>", varargs.}
elif coroBackend == CORO_BACKEND_SETJMP: elif coroBackend == CORO_BACKEND_SETJMP:
proc coroExecWithStack*(fn: pointer, stack: pointer) {.noreturn, importc: "narch_$1", fastcall.} proc coroExecWithStack*(fn: pointer, stack: pointer) {.noreturn,
importc: "narch_$1", fastcall.}
when defined(amd64): when defined(amd64):
{.compile: "../arch/x86/amd64.S".} {.compile: "../arch/x86/amd64.S".}
elif defined(i386): elif defined(i386):
@ -105,14 +110,14 @@ elif coroBackend == CORO_BACKEND_SETJMP:
{.error: "Unsupported architecture.".} {.error: "Unsupported architecture.".}
proc setjmp(ctx: var JmpBuf): int {.importc: "narch_$1".} proc setjmp(ctx: var JmpBuf): int {.importc: "narch_$1".}
proc longjmp(ctx: JmpBuf, ret=1) {.importc: "narch_$1".} proc longjmp(ctx: JmpBuf, ret = 1) {.importc: "narch_$1".}
else: else:
# Use setjmp/longjmp implementation provided by the system. # Use setjmp/longjmp implementation provided by the system.
type type
JmpBuf {.importc: "jmp_buf", header: "<setjmp.h>".} = object JmpBuf {.importc: "jmp_buf", header: "<setjmp.h>".} = object
proc setjmp(ctx: var JmpBuf): int {.importc, header: "<setjmp.h>".} proc setjmp(ctx: var JmpBuf): int {.importc, header: "<setjmp.h>".}
proc longjmp(ctx: JmpBuf, ret=1) {.importc, header: "<setjmp.h>".} proc longjmp(ctx: JmpBuf, ret = 1) {.importc, header: "<setjmp.h>".}
type type
Context = JmpBuf Context = JmpBuf
@ -211,7 +216,7 @@ proc switchTo(current, to: CoroutinePtr) =
setFrameState(frame) setFrameState(frame)
GC_setActiveStack(current.stack.bottom) GC_setActiveStack(current.stack.bottom)
proc suspend*(sleepTime: float=0) = proc suspend*(sleepTime: float = 0) =
## Stops coroutine execution and resumes no sooner than after ``sleeptime`` seconds. ## Stops coroutine execution and resumes no sooner than after ``sleeptime`` seconds.
## Until then other coroutines are executed. ## Until then other coroutines are executed.
var current = getCurrent() var current = getCurrent()
@ -242,7 +247,7 @@ proc runCurrentTask() =
suspend(0) # Exit coroutine without returning from coroExecWithStack() suspend(0) # Exit coroutine without returning from coroExecWithStack()
doAssert false doAssert false
proc start*(c: proc(), stacksize: int=defaultStackSize): CoroutineRef {.discardable.} = proc start*(c: proc(), stacksize: int = defaultStackSize): CoroutineRef {.discardable.} =
## Schedule coroutine for execution. It does not run immediately. ## Schedule coroutine for execution. It does not run immediately.
if ctx == nil: if ctx == nil:
initialize() initialize()
@ -251,7 +256,9 @@ proc start*(c: proc(), stacksize: int=defaultStackSize): CoroutineRef {.discarda
when coroBackend == CORO_BACKEND_FIBERS: when coroBackend == CORO_BACKEND_FIBERS:
coro = cast[CoroutinePtr](alloc0(sizeof(Coroutine))) coro = cast[CoroutinePtr](alloc0(sizeof(Coroutine)))
coro.execContext = CreateFiberEx(stacksize, stacksize, coro.execContext = CreateFiberEx(stacksize, stacksize,
FIBER_FLAG_FLOAT_SWITCH, (proc(p: pointer): void {.stdcall.} = runCurrentTask()), nil) FIBER_FLAG_FLOAT_SWITCH,
(proc(p: pointer): void {.stdcall.} = runCurrentTask()),
nil)
coro.stack.size = stacksize coro.stack.size = stacksize
else: else:
coro = cast[CoroutinePtr](alloc0(sizeof(Coroutine) + stacksize)) coro = cast[CoroutinePtr](alloc0(sizeof(Coroutine) + stacksize))
@ -313,7 +320,7 @@ proc run*() =
proc alive*(c: CoroutineRef): bool = c.coro != nil and c.coro.state != CORO_FINISHED proc alive*(c: CoroutineRef): bool = c.coro != nil and c.coro.state != CORO_FINISHED
## Returns ``true`` if coroutine has not returned, ``false`` otherwise. ## Returns ``true`` if coroutine has not returned, ``false`` otherwise.
proc wait*(c: CoroutineRef, interval=0.01) = proc wait*(c: CoroutineRef, interval = 0.01) =
## Returns only after coroutine ``c`` has returned. ``interval`` is time in seconds how often. ## Returns only after coroutine ``c`` has returned. ``interval`` is time in seconds how often.
while alive(c): while alive(c):
suspend(interval) suspend(interval)

View file

@ -147,7 +147,7 @@ when not defined(js):
import os import os
type type
Level* = enum Level* = enum ## \
## Enumeration of logging levels. ## Enumeration of logging levels.
## ##
## Debug messages represent the lowest logging level, and fatal error ## Debug messages represent the lowest logging level, and fatal error
@ -187,8 +187,7 @@ const
"DEBUG", "DEBUG", "INFO", "NOTICE", "WARN", "ERROR", "FATAL", "NONE" "DEBUG", "DEBUG", "INFO", "NOTICE", "WARN", "ERROR", "FATAL", "NONE"
] ## Array of strings representing each logging level. ] ## Array of strings representing each logging level.
defaultFmtStr* = "$levelname " ## \ defaultFmtStr* = "$levelname " ## The default format string.
## The default format string.
verboseFmtStr* = "$levelid, [$datetime] -- $appname: " ## \ verboseFmtStr* = "$levelid, [$datetime] -- $appname: " ## \
## A more verbose format string. ## A more verbose format string.
## ##
@ -255,7 +254,7 @@ when not defined(js):
## * `ConsoleLogger<#ConsoleLogger>`_ ## * `ConsoleLogger<#ConsoleLogger>`_
## * `FileLogger<#FileLogger>`_ ## * `FileLogger<#FileLogger>`_
maxLines: int # maximum number of lines maxLines: int # maximum number of lines
curLine : int curLine: int
baseName: string # initial filename baseName: string # initial filename
baseMode: FileMode # initial file mode baseMode: FileMode # initial file mode
logFiles: int # how many log files already created, e.g. basename.1, basename.2... logFiles: int # how many log files already created, e.g. basename.1, basename.2...
@ -265,7 +264,8 @@ var
level {.threadvar.}: Level ## global log filter level {.threadvar.}: Level ## global log filter
handlers {.threadvar.}: seq[Logger] ## handlers with their own log levels handlers {.threadvar.}: seq[Logger] ## handlers with their own log levels
proc substituteLog*(frmt: string, level: Level, args: varargs[string, `$`]): string = proc substituteLog*(frmt: string, level: Level,
args: varargs[string, `$`]): string =
## Formats a log message at the specified level with the given format string. ## Formats a log message at the specified level with the given format string.
## ##
## The `format variables<#basic-usage-format-strings>`_ present within ## The `format variables<#basic-usage-format-strings>`_ present within
@ -375,7 +375,8 @@ method log*(logger: ConsoleLogger, level: Level, args: varargs[string, `$`]) =
except IOError: except IOError:
discard discard
proc newConsoleLogger*(levelThreshold = lvlAll, fmtStr = defaultFmtStr, useStderr=false): ConsoleLogger = proc newConsoleLogger*(levelThreshold = lvlAll, fmtStr = defaultFmtStr,
useStderr = false): ConsoleLogger =
## Creates a new `ConsoleLogger<#ConsoleLogger>`_. ## Creates a new `ConsoleLogger<#ConsoleLogger>`_.
## ##
## By default, log messages are written to ``stdout``. If ``useStderr`` is ## By default, log messages are written to ``stdout``. If ``useStderr`` is
@ -563,7 +564,7 @@ when not defined(js):
result.fmtStr = fmtStr result.fmtStr = fmtStr
result.maxLines = maxLines result.maxLines = maxLines
result.bufSize = bufSize result.bufSize = bufSize
result.file = open(filename, mode, bufSize=result.bufSize) result.file = open(filename, mode, bufSize = result.bufSize)
result.curLine = 0 result.curLine = 0
result.baseName = filename result.baseName = filename
result.baseMode = mode result.baseMode = mode
@ -616,7 +617,8 @@ when not defined(js):
rotate(logger) rotate(logger)
logger.logFiles.inc logger.logFiles.inc
logger.curLine = 0 logger.curLine = 0
logger.file = open(logger.baseName, logger.baseMode, bufSize = logger.bufSize) logger.file = open(logger.baseName, logger.baseMode,
bufSize = logger.bufSize)
writeLine(logger.file, substituteLog(logger.fmtStr, level, args)) writeLine(logger.file, substituteLog(logger.fmtStr, level, args))
if level in {lvlError, lvlFatal}: flushFile(logger.file) if level in {lvlError, lvlFatal}: flushFile(logger.file)

View file

@ -384,7 +384,7 @@ when not defined(testing) and isMainModule:
test4.b = "ref string test: B" test4.b = "ref string test: B"
testit(test4) testit(test4)
var test5 = @[(0,1),(2,3),(4,5)] var test5 = @[(0, 1), (2, 3), (4, 5)]
testit(test5) testit(test5)
var test6: set[char] = {'A'..'Z', '_'} var test6: set[char] = {'A'..'Z', '_'}

View file

@ -49,7 +49,8 @@ when defined(macosx) and not defined(nimdoc):
type type
Port* = distinct uint16 ## port type Port* = distinct uint16 ## port type
Domain* = enum ## domain, which specifies the protocol family of the Domain* = enum ## \
## domain, which specifies the protocol family of the
## created socket. Other domains than those that are listed ## created socket. Other domains than those that are listed
## here are unsupported. ## here are unsupported.
AF_UNSPEC = 0, ## unspecified domain (can be detected automatically by AF_UNSPEC = 0, ## unspecified domain (can be detected automatically by
@ -223,10 +224,12 @@ proc close*(socket: SocketHandle) =
# TODO: These values should not be discarded. An OSError should be raised. # TODO: These values should not be discarded. An OSError should be raised.
# http://stackoverflow.com/questions/12463473/what-happens-if-you-call-close-on-a-bsd-socket-multiple-times # http://stackoverflow.com/questions/12463473/what-happens-if-you-call-close-on-a-bsd-socket-multiple-times
proc bindAddr*(socket: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint = proc bindAddr*(socket: SocketHandle, name: ptr SockAddr,
namelen: SockLen): cint =
result = bindSocket(socket, name, namelen) result = bindSocket(socket, name, namelen)
proc listen*(socket: SocketHandle, backlog = SOMAXCONN): cint {.tags: [ReadIOEffect].} = proc listen*(socket: SocketHandle, backlog = SOMAXCONN): cint {.tags: [
ReadIOEffect].} =
## Marks ``socket`` as accepting connections. ## Marks ``socket`` as accepting connections.
## ``Backlog`` specifies the maximum length of the ## ``Backlog`` specifies the maximum length of the
## queue of pending connections. ## queue of pending connections.
@ -250,7 +253,8 @@ proc getAddrInfo*(address: string, port: Port, domain: Domain = AF_INET,
# FreeBSD, Haiku don't support AI_V4MAPPED but defines the macro. # FreeBSD, Haiku don't support AI_V4MAPPED but defines the macro.
# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=198092 # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=198092
# https://dev.haiku-os.org/ticket/14323 # https://dev.haiku-os.org/ticket/14323
when not defined(freebsd) and not defined(openbsd) and not defined(netbsd) and not defined(android) and not defined(haiku): when not defined(freebsd) and not defined(openbsd) and not defined(netbsd) and
not defined(android) and not defined(haiku):
if domain == AF_INET6: if domain == AF_INET6:
hints.ai_flags = AI_V4MAPPED hints.ai_flags = AI_V4MAPPED
let socketPort = if sockType == SOCK_RAW: "" else: $port let socketPort = if sockType == SOCK_RAW: "" else: $port

View file

@ -201,7 +201,8 @@ proc writeProfile() {.noconv.} =
let procname = profileData[i].st[ii] let procname = profileData[i].st[ii]
let filename = profileData[i].st.files[ii] let filename = profileData[i].st.files[ii]
if isNil(procname): break if isNil(procname): break
writeLine(f, " ", $filename & ": " & $procname, " ", perProc[$procname] // totalCalls) writeLine(f, " ", $filename & ": " & $procname, " ",
perProc[$procname] // totalCalls)
close(f) close(f)
echo "... done" echo "... done"
else: else:

View file

@ -258,7 +258,7 @@ proc map*[T, R](self: Option[T], callback: proc (input: T): R): Option[R] =
assert $(b.map(isEven)) == "None[bool]" assert $(b.map(isEven)) == "None[bool]"
if self.isSome: if self.isSome:
some[R]( callback(self.val) ) some[R](callback(self.val))
else: else:
none(R) none(R)
@ -273,7 +273,8 @@ proc flatten*[A](self: Option[Option[A]]): Option[A] =
else: else:
none(A) none(A)
proc flatMap*[A, B](self: Option[A], callback: proc (input: A): Option[B]): Option[B] = proc flatMap*[A, B](self: Option[A],
callback: proc (input: A): Option[B]): Option[B] =
## Applies a `callback` function to the value of the `Option` and returns an ## Applies a `callback` function to the value of the `Option` and returns an
## `Option` containing the new value. ## `Option` containing the new value.
## ##

View file

@ -320,7 +320,7 @@ proc backrefIgnoreCase*(index: range[1..MaxSubpatterns]): Peg {.
result = Peg(kind: pkBackRefIgnoreCase, index: index-1) result = Peg(kind: pkBackRefIgnoreCase, index: index-1)
proc backrefIgnoreStyle*(index: range[1..MaxSubpatterns]): Peg {. proc backrefIgnoreStyle*(index: range[1..MaxSubpatterns]): Peg {.
noSideEffect, rtl, extern: "npegs$1".}= noSideEffect, rtl, extern: "npegs$1".} =
## constructs a back reference of the given `index`. `index` starts counting ## constructs a back reference of the given `index`. `index` starts counting
## from 1. Ignores style for matching. ## from 1. Ignores style for matching.
result = Peg(kind: pkBackRefIgnoreStyle, index: index-1) result = Peg(kind: pkBackRefIgnoreStyle, index: index-1)
@ -544,7 +544,7 @@ when not useUnicode:
inc(i) inc(i)
template runeLenAt(s, i): untyped = 1 template runeLenAt(s, i): untyped = 1
proc isAlpha(a: char): bool {.inline.} = return a in {'a'..'z','A'..'Z'} proc isAlpha(a: char): bool {.inline.} = return a in {'a'..'z', 'A'..'Z'}
proc isUpper(a: char): bool {.inline.} = return a in {'A'..'Z'} proc isUpper(a: char): bool {.inline.} = return a in {'A'..'Z'}
proc isLower(a: char): bool {.inline.} = return a in {'a'..'z'} proc isLower(a: char): bool {.inline.} = return a in {'a'..'z'}
proc isTitle(a: char): bool {.inline.} = return false proc isTitle(a: char): bool {.inline.} = return false
@ -796,7 +796,8 @@ template matchOrParse(mopProc: untyped) =
of pkGreedyRepSet: of pkGreedyRepSet:
enter(pkGreedyRepSet, s, p, start) enter(pkGreedyRepSet, s, p, start)
result = 0 result = 0
while start+result < s.len and contains(p.charChoice[], s[start+result]): inc(result) while start+result < s.len and contains(p.charChoice[], s[start+result]):
inc(result)
leave(pkGreedyRepSet, s, p, start, result) leave(pkGreedyRepSet, s, p, start, result)
of pkOption: of pkOption:
enter(pkOption, s, p, start) enter(pkOption, s, p, start)
@ -1278,7 +1279,7 @@ proc parallelReplace*(s: string, subs: varargs[
proc replace*(s: string, sub: Peg, cb: proc( proc replace*(s: string, sub: Peg, cb: proc(
match: int, cnt: int, caps: openArray[string]): string): string {. match: int, cnt: int, caps: openArray[string]): string): string {.
rtl, extern: "npegs$1cb".}= rtl, extern: "npegs$1cb".} =
## Replaces `sub` in `s` by the resulting strings from the callback. ## Replaces `sub` in `s` by the resulting strings from the callback.
## The callback proc receives the index of the current match (starting with 0), ## The callback proc receives the index of the current match (starting with 0),
## the count of captures and an open array with the captures of each match. Examples: ## the count of captures and an open array with the captures of each match. Examples:
@ -1825,7 +1826,7 @@ proc builtin(p: var PegParser): Peg =
of "s": result = charSet({' ', '\9'..'\13'}) of "s": result = charSet({' ', '\9'..'\13'})
of "S": result = charSet({'\1'..'\xff'} - {' ', '\9'..'\13'}) of "S": result = charSet({'\1'..'\xff'} - {' ', '\9'..'\13'})
of "w": result = charSet({'a'..'z', 'A'..'Z', '_', '0'..'9'}) of "w": result = charSet({'a'..'z', 'A'..'Z', '_', '0'..'9'})
of "W": result = charSet({'\1'..'\xff'} - {'a'..'z','A'..'Z','_','0'..'9'}) of "W": result = charSet({'\1'..'\xff'} - {'a'..'z', 'A'..'Z', '_', '0'..'9'})
of "a": result = charSet({'a'..'z', 'A'..'Z'}) of "a": result = charSet({'a'..'z', 'A'..'Z'})
of "A": result = charSet({'\1'..'\xff'} - {'a'..'z', 'A'..'Z'}) of "A": result = charSet({'\1'..'\xff'} - {'a'..'z', 'A'..'Z'})
of "ident": result = pegs.ident of "ident": result = pegs.ident
@ -2168,7 +2169,7 @@ when isMainModule:
assert("Var1=key1;var2=Key2; VAR3". assert("Var1=key1;var2=Key2; VAR3".
replace(peg"{\ident}('='{\ident})* ';'* \s*", replace(peg"{\ident}('='{\ident})* ';'* \s*",
handleMatches)=="var1: 'key1', var2: 'Key2', var3: ''") handleMatches) == "var1: 'key1', var2: 'Key2', var3: ''")
doAssert "test1".match(peg"""{@}$""") doAssert "test1".match(peg"""{@}$""")

View file

@ -48,9 +48,9 @@
from math import FloatClass, sqrt, pow, round from math import FloatClass, sqrt, pow, round
{.push debugger:off .} # the user does not want to trace a part {.push debugger: off.} # the user does not want to trace a part
# of the standard library! # of the standard library!
{.push checks:off, line_dir:off, stack_trace:off.} {.push checks: off, line_dir: off, stack_trace: off.}
type type
RunningStat* = object ## an accumulator for statistical data RunningStat* = object ## an accumulator for statistical data
@ -264,7 +264,7 @@ proc clear*(r: var RunningRegress) =
proc push*(r: var RunningRegress, x, y: float) = proc push*(r: var RunningRegress, x, y: float) =
## pushes two values `x` and `y` for processing ## pushes two values `x` and `y` for processing
r.s_xy += (r.x_stats.mean() - x)*(r.y_stats.mean() - y)* r.s_xy += (r.x_stats.mean() - x)*(r.y_stats.mean() - y) *
toFloat(r.n) / toFloat(r.n + 1) toFloat(r.n) / toFloat(r.n + 1)
r.x_stats.push(x) r.x_stats.push(x)
r.y_stats.push(y) r.y_stats.push(y)
@ -296,7 +296,7 @@ proc correlation*(r: RunningRegress): float =
## computes the current correlation of the two data ## computes the current correlation of the two data
## sets pushed into `r` ## sets pushed into `r`
let t = r.x_stats.standardDeviation() * r.y_stats.standardDeviation() let t = r.x_stats.standardDeviation() * r.y_stats.standardDeviation()
result = r.s_xy / ( toFloat(r.n) * t ) result = r.s_xy / (toFloat(r.n) * t)
proc `+`*(a, b: RunningRegress): RunningRegress = proc `+`*(a, b: RunningRegress): RunningRegress =
## combine two `RunningRegress` objects. ## combine two `RunningRegress` objects.
@ -354,13 +354,13 @@ when isMainModule:
when not defined(cpu32): when not defined(cpu32):
# XXX For some reason on 32bit CPUs these results differ # XXX For some reason on 32bit CPUs these results differ
var rr: RunningRegress var rr: RunningRegress
rr.push(@[0.0,1.0,2.8,3.0,4.0], @[0.0,1.0,2.3,3.0,4.0]) rr.push(@[0.0, 1.0, 2.8, 3.0, 4.0], @[0.0, 1.0, 2.3, 3.0, 4.0])
doAssert(rr.slope() == 0.9695585996955861) doAssert(rr.slope() == 0.9695585996955861)
doAssert(rr.intercept() == -0.03424657534246611) doAssert(rr.intercept() == -0.03424657534246611)
doAssert(rr.correlation() == 0.9905100362239381) doAssert(rr.correlation() == 0.9905100362239381)
var rr1, rr2: RunningRegress var rr1, rr2: RunningRegress
rr1.push(@[0.0,1.0], @[0.0,1.0]) rr1.push(@[0.0, 1.0], @[0.0, 1.0])
rr2.push(@[2.8,3.0,4.0], @[2.3,3.0,4.0]) rr2.push(@[2.8, 3.0, 4.0], @[2.3, 3.0, 4.0])
let rr3 = rr1 + rr2 let rr3 = rr1 + rr2
doAssert(rr3.correlation() == rr.correlation()) doAssert(rr3.correlation() == rr.correlation())
doAssert(clean(rr3.slope()) == clean(rr.slope())) doAssert(clean(rr3.slope()) == clean(rr.slope()))

View file

@ -126,17 +126,17 @@ when defined(windows):
proc terminalWidth*(): int = proc terminalWidth*(): int =
var w: int = 0 var w: int = 0
w = terminalWidthIoctl([ getStdHandle(STD_INPUT_HANDLE), w = terminalWidthIoctl([getStdHandle(STD_INPUT_HANDLE),
getStdHandle(STD_OUTPUT_HANDLE), getStdHandle(STD_OUTPUT_HANDLE),
getStdHandle(STD_ERROR_HANDLE) ] ) getStdHandle(STD_ERROR_HANDLE)])
if w > 0: return w if w > 0: return w
return 80 return 80
proc terminalHeight*(): int = proc terminalHeight*(): int =
var h: int = 0 var h: int = 0
h = terminalHeightIoctl([ getStdHandle(STD_INPUT_HANDLE), h = terminalHeightIoctl([getStdHandle(STD_INPUT_HANDLE),
getStdHandle(STD_OUTPUT_HANDLE), getStdHandle(STD_OUTPUT_HANDLE),
getStdHandle(STD_ERROR_HANDLE) ] ) getStdHandle(STD_ERROR_HANDLE)])
if h > 0: return h if h > 0: return h
return 0 return 0
@ -164,7 +164,7 @@ when defined(windows):
proc setConsoleMode(hConsoleHandle: Handle, dwMode: DWORD): WINBOOL{. proc setConsoleMode(hConsoleHandle: Handle, dwMode: DWORD): WINBOOL{.
stdcall, dynlib: "kernel32", importc: "SetConsoleMode".} stdcall, dynlib: "kernel32", importc: "SetConsoleMode".}
proc getCursorPos(h: Handle): tuple [x,y: int] = proc getCursorPos(h: Handle): tuple [x, y: int] =
var c: CONSOLE_SCREEN_BUFFER_INFO var c: CONSOLE_SCREEN_BUFFER_INFO
if getConsoleScreenBufferInfo(h, addr(c)) == 0: if getConsoleScreenBufferInfo(h, addr(c)) == 0:
raiseOSError(osLastError()) raiseOSError(osLastError())
@ -246,7 +246,7 @@ else:
var cterm = newString(L_ctermid) #Try controlling tty var cterm = newString(L_ctermid) #Try controlling tty
var fd = open(ctermid(cstring(cterm)), O_RDONLY) var fd = open(ctermid(cstring(cterm)), O_RDONLY)
if fd != -1: if fd != -1:
w = terminalWidthIoctl([ int(fd) ]) w = terminalWidthIoctl([int(fd)])
discard close(fd) discard close(fd)
if w > 0: return w if w > 0: return w
var s = getEnv("COLUMNS") #Try standard env var var s = getEnv("COLUMNS") #Try standard env var
@ -264,7 +264,7 @@ else:
var cterm = newString(L_ctermid) # Try controlling tty var cterm = newString(L_ctermid) # Try controlling tty
var fd = open(ctermid(cstring(cterm)), O_RDONLY) var fd = open(ctermid(cstring(cterm)), O_RDONLY)
if fd != -1: if fd != -1:
h = terminalHeightIoctl([ int(fd) ]) h = terminalHeightIoctl([int(fd)])
discard close(fd) discard close(fd)
if h > 0: return h if h > 0: return h
var s = getEnv("LINES") # Try standard env var var s = getEnv("LINES") # Try standard env var
@ -342,7 +342,7 @@ when defined(windows):
else: else:
discard discard
proc cursorUp*(f: File, count=1) = proc cursorUp*(f: File, count = 1) =
## Moves the cursor up by `count` rows. ## Moves the cursor up by `count` rows.
when defined(windows): when defined(windows):
let h = conHandle(f) let h = conHandle(f)
@ -352,7 +352,7 @@ proc cursorUp*(f: File, count=1) =
else: else:
f.write("\e[" & $count & 'A') f.write("\e[" & $count & 'A')
proc cursorDown*(f: File, count=1) = proc cursorDown*(f: File, count = 1) =
## Moves the cursor down by `count` rows. ## Moves the cursor down by `count` rows.
when defined(windows): when defined(windows):
let h = conHandle(f) let h = conHandle(f)
@ -362,7 +362,7 @@ proc cursorDown*(f: File, count=1) =
else: else:
f.write(fmt"{stylePrefix}{count}B") f.write(fmt"{stylePrefix}{count}B")
proc cursorForward*(f: File, count=1) = proc cursorForward*(f: File, count = 1) =
## Moves the cursor forward by `count` columns. ## Moves the cursor forward by `count` columns.
when defined(windows): when defined(windows):
let h = conHandle(f) let h = conHandle(f)
@ -372,7 +372,7 @@ proc cursorForward*(f: File, count=1) =
else: else:
f.write(fmt"{stylePrefix}{count}C") f.write(fmt"{stylePrefix}{count}C")
proc cursorBackward*(f: File, count=1) = proc cursorBackward*(f: File, count = 1) =
## Moves the cursor backward by `count` columns. ## Moves the cursor backward by `count` columns.
when defined(windows): when defined(windows):
let h = conHandle(f) let h = conHandle(f)
@ -556,7 +556,7 @@ type
when defined(windows): when defined(windows):
var defaultForegroundColor, defaultBackgroundColor: int16 = 0xFFFF'i16 # Default to an invalid value 0xFFFF var defaultForegroundColor, defaultBackgroundColor: int16 = 0xFFFF'i16 # Default to an invalid value 0xFFFF
proc setForegroundColor*(f: File, fg: ForegroundColor, bright=false) = proc setForegroundColor*(f: File, fg: ForegroundColor, bright = false) =
## Sets the terminal's foreground color. ## Sets the terminal's foreground color.
when defined(windows): when defined(windows):
let h = conHandle(f) let h = conHandle(f)
@ -585,7 +585,7 @@ proc setForegroundColor*(f: File, fg: ForegroundColor, bright=false) =
if bright: inc(gFG, 60) if bright: inc(gFG, 60)
f.write(ansiStyleCode(gFG)) f.write(ansiStyleCode(gFG))
proc setBackgroundColor*(f: File, bg: BackgroundColor, bright=false) = proc setBackgroundColor*(f: File, bg: BackgroundColor, bright = false) =
## Sets the terminal's background color. ## Sets the terminal's background color.
when defined(windows): when defined(windows):
let h = conHandle(f) let h = conHandle(f)
@ -614,7 +614,7 @@ proc setBackgroundColor*(f: File, bg: BackgroundColor, bright=false) =
if bright: inc(gBG, 60) if bright: inc(gBG, 60)
f.write(ansiStyleCode(gBG)) f.write(ansiStyleCode(gBG))
proc ansiForegroundColorCode*(fg: ForegroundColor, bright=false): string = proc ansiForegroundColorCode*(fg: ForegroundColor, bright = false): string =
var style = ord(fg) var style = ord(fg)
if bright: inc(style, 60) if bright: inc(style, 60)
return ansiStyleCode(style) return ansiStyleCode(style)
@ -825,17 +825,17 @@ template setCursorPos*(x, y: int) = setCursorPos(stdout, x, y)
template setCursorXPos*(x: int) = setCursorXPos(stdout, x) template setCursorXPos*(x: int) = setCursorXPos(stdout, x)
when defined(windows): when defined(windows):
template setCursorYPos*(x: int) = setCursorYPos(stdout, x) template setCursorYPos*(x: int) = setCursorYPos(stdout, x)
template cursorUp*(count=1) = cursorUp(stdout, count) template cursorUp*(count = 1) = cursorUp(stdout, count)
template cursorDown*(count=1) = cursorDown(stdout, count) template cursorDown*(count = 1) = cursorDown(stdout, count)
template cursorForward*(count=1) = cursorForward(stdout, count) template cursorForward*(count = 1) = cursorForward(stdout, count)
template cursorBackward*(count=1) = cursorBackward(stdout, count) template cursorBackward*(count = 1) = cursorBackward(stdout, count)
template eraseLine*() = eraseLine(stdout) template eraseLine*() = eraseLine(stdout)
template eraseScreen*() = eraseScreen(stdout) template eraseScreen*() = eraseScreen(stdout)
template setStyle*(style: set[Style]) = template setStyle*(style: set[Style]) =
setStyle(stdout, style) setStyle(stdout, style)
template setForegroundColor*(fg: ForegroundColor, bright=false) = template setForegroundColor*(fg: ForegroundColor, bright = false) =
setForegroundColor(stdout, fg, bright) setForegroundColor(stdout, fg, bright)
template setBackgroundColor*(bg: BackgroundColor, bright=false) = template setBackgroundColor*(bg: BackgroundColor, bright = false) =
setBackgroundColor(stdout, bg, bright) setBackgroundColor(stdout, bg, bright)
template setForegroundColor*(color: Color) = template setForegroundColor*(color: Color) =
setForegroundColor(stdout, color) setForegroundColor(stdout, color)
@ -883,7 +883,8 @@ proc enableTrueColors*() =
else: else:
term.trueColorIsEnabled = true term.trueColorIsEnabled = true
else: else:
term.trueColorIsSupported = string(getEnv("COLORTERM")).toLowerAscii() in ["truecolor", "24bit"] term.trueColorIsSupported = string(getEnv("COLORTERM")).toLowerAscii() in [
"truecolor", "24bit"]
term.trueColorIsEnabled = term.trueColorIsSupported term.trueColorIsEnabled = term.trueColorIsSupported
proc disableTrueColors*() = proc disableTrueColors*() =
@ -944,5 +945,6 @@ when not defined(testing) and isMainModule:
echo "" echo ""
echo "ordinary text" echo "ordinary text"
stdout.styledWriteLine(fgRed, "red text ", styleBright, "bold red", fgDefault, " bold text") stdout.styledWriteLine(fgRed, "red text ", styleBright, "bold red", fgDefault, " bold text")
stdout.styledWriteLine(bgYellow, "text in yellow bg", styleBright, " bold text in yellow bg", bgDefault, " bold text") stdout.styledWriteLine(bgYellow, "text in yellow bg", styleBright,
" bold text in yellow bg", bgDefault, " bold text")
echo "ordinary text" echo "ordinary text"

View file

@ -435,10 +435,13 @@ const unitWeights: array[FixedTimeUnit, int64] = [
] ]
const DefaultLocale* = DateTimeLocale( const DefaultLocale* = DateTimeLocale(
MMM: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], MMM: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
MMMM: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], "Nov", "Dec"],
MMMM: ["January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"],
ddd: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], ddd: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
dddd: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], dddd: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday",
"Sunday"],
) )
proc convert*[T: SomeInteger](unitFrom, unitTo: FixedTimeUnit, quantity: T): T proc convert*[T: SomeInteger](unitFrom, unitTo: FixedTimeUnit, quantity: T): T
@ -854,21 +857,24 @@ proc `==`*(a, b: Duration): bool {.operator, extern: "ntEqDuration".} =
doAssert d1 == d2 doAssert d1 == d2
eqImpl(a, b) eqImpl(a, b)
proc `*`*(a: int64, b: Duration): Duration {.operator, extern: "ntMulInt64Duration".} = proc `*`*(a: int64, b: Duration): Duration {.operator,
extern: "ntMulInt64Duration".} =
## Multiply a duration by some scalar. ## Multiply a duration by some scalar.
runnableExamples: runnableExamples:
doAssert 5 * initDuration(seconds = 1) == initDuration(seconds = 5) doAssert 5 * initDuration(seconds = 1) == initDuration(seconds = 5)
doAssert 3 * initDuration(minutes = 45) == initDuration(hours = 2, minutes = 15) doAssert 3 * initDuration(minutes = 45) == initDuration(hours = 2, minutes = 15)
normalize[Duration](a * b.seconds, a * b.nanosecond) normalize[Duration](a * b.seconds, a * b.nanosecond)
proc `*`*(a: Duration, b: int64): Duration {.operator, extern: "ntMulDuration".} = proc `*`*(a: Duration, b: int64): Duration {.operator,
extern: "ntMulDuration".} =
## Multiply a duration by some scalar. ## Multiply a duration by some scalar.
runnableExamples: runnableExamples:
doAssert initDuration(seconds = 1) * 5 == initDuration(seconds = 5) doAssert initDuration(seconds = 1) * 5 == initDuration(seconds = 5)
doAssert initDuration(minutes = 45) * 3 == initDuration(hours = 2, minutes = 15) doAssert initDuration(minutes = 45) * 3 == initDuration(hours = 2, minutes = 15)
b * a b * a
proc `div`*(a: Duration, b: int64): Duration {.operator, extern: "ntDivDuration".} = proc `div`*(a: Duration, b: int64): Duration {.operator,
extern: "ntDivDuration".} =
## Integer division for durations. ## Integer division for durations.
runnableExamples: runnableExamples:
doAssert initDuration(seconds = 3) div 2 == doAssert initDuration(seconds = 3) div 2 ==
@ -1304,7 +1310,7 @@ proc getClockStr*(dt = now()): string {.rtl, extern: "nt$1", tags: [TimeEffect].
result = intToStr(dt.hour, 2) & ':' & intToStr(dt.minute, 2) & result = intToStr(dt.hour, 2) & ':' & intToStr(dt.minute, 2) &
':' & intToStr(dt.second, 2) ':' & intToStr(dt.second, 2)
proc toParts* (ti: TimeInterval): TimeIntervalParts = proc toParts*(ti: TimeInterval): TimeIntervalParts =
## Converts a ``TimeInterval`` into an array consisting of its time units, ## Converts a ``TimeInterval`` into an array consisting of its time units,
## starting with nanoseconds and ending with years. ## starting with nanoseconds and ending with years.
## ##
@ -1783,7 +1789,8 @@ proc `$`*(f: TimeFormat): string =
proc raiseParseException(f: TimeFormat, input: string, msg: string) = proc raiseParseException(f: TimeFormat, input: string, msg: string) =
raise newException(TimeParseError, raise newException(TimeParseError,
"Failed to parse '" & input & "' with format '" & $f & "'. " & msg) "Failed to parse '" & input & "' with format '" & $f &
"'. " & msg)
proc parseInt(s: string, b: var int, start = 0, maxLen = int.high, proc parseInt(s: string, b: var int, start = 0, maxLen = int.high,
allowSign = false): int = allowSign = false): int =
@ -1919,7 +1926,8 @@ proc initTimeFormat*(format: string): TimeFormat =
of tkPattern: of tkPattern:
result.patterns.add(stringToPattern(token).byte) result.patterns.add(stringToPattern(token).byte)
proc formatPattern(dt: DateTime, pattern: FormatPattern, result: var string, loc: DateTimeLocale) = proc formatPattern(dt: DateTime, pattern: FormatPattern, result: var string,
loc: DateTimeLocale) =
template yearOfEra(dt: DateTime): int = template yearOfEra(dt: DateTime): int =
if dt.year <= 0: abs(dt.year) + 1 else: dt.year if dt.year <= 0: abs(dt.year) + 1 else: dt.year
@ -2087,7 +2095,7 @@ proc parsePattern(input: string, pattern: FormatPattern, i: var int,
parsed.month = some(month) parsed.month = some(month)
of MMM: of MMM:
result = false result = false
for n,v in loc.MMM: for n, v in loc.MMM:
if input.substr(i, i+v.len-1).cmpIgnoreCase(v) == 0: if input.substr(i, i+v.len-1).cmpIgnoreCase(v) == 0:
result = true result = true
i.inc v.len i.inc v.len
@ -2095,7 +2103,7 @@ proc parsePattern(input: string, pattern: FormatPattern, i: var int,
break break
of MMMM: of MMMM:
result = false result = false
for n,v in loc.MMMM: for n, v in loc.MMMM:
if input.substr(i, i+v.len-1).cmpIgnoreCase(v) == 0: if input.substr(i, i+v.len-1).cmpIgnoreCase(v) == 0:
result = true result = true
i.inc v.len i.inc v.len
@ -2270,7 +2278,8 @@ proc toDateTime(p: ParsedTime, zone: Timezone, f: TimeFormat,
result.utcOffset = p.utcOffset.get() result.utcOffset = p.utcOffset.get()
result = result.toTime.inZone(zone) result = result.toTime.inZone(zone)
proc format*(dt: DateTime, f: TimeFormat, loc: DateTimeLocale = DefaultLocale): string {.raises: [].} = proc format*(dt: DateTime, f: TimeFormat,
loc: DateTimeLocale = DefaultLocale): string {.raises: [].} =
## Format ``dt`` using the format specified by ``f``. ## Format ``dt`` using the format specified by ``f``.
runnableExamples: runnableExamples:
let f = initTimeFormat("yyyy-MM-dd") let f = initTimeFormat("yyyy-MM-dd")
@ -2334,7 +2343,8 @@ template formatValue*(result: var string; value: Time, specifier: string) =
## adapter for ``strformat``. Not intended to be called directly. ## adapter for ``strformat``. Not intended to be called directly.
result.add format(value, specifier) result.add format(value, specifier)
proc parse*(input: string, f: TimeFormat, zone: Timezone = local(), loc: DateTimeLocale = DefaultLocale): DateTime proc parse*(input: string, f: TimeFormat, zone: Timezone = local(),
loc: DateTimeLocale = DefaultLocale): DateTime
{.raises: [TimeParseError, Defect].} = {.raises: [TimeParseError, Defect].} =
## Parses ``input`` as a ``DateTime`` using the format specified by ``f``. ## Parses ``input`` as a ``DateTime`` using the format specified by ``f``.
## If no UTC offset was parsed, then ``input`` is assumed to be specified in ## If no UTC offset was parsed, then ``input`` is assumed to be specified in
@ -2377,7 +2387,8 @@ proc parse*(input: string, f: TimeFormat, zone: Timezone = local(), loc: DateTim
result = toDateTime(parsed, zone, f, input) result = toDateTime(parsed, zone, f, input)
proc parse*(input, f: string, tz: Timezone = local(), loc: DateTimeLocale = DefaultLocale): DateTime proc parse*(input, f: string, tz: Timezone = local(),
loc: DateTimeLocale = DefaultLocale): DateTime
{.raises: [TimeParseError, TimeFormatParseError, Defect].} = {.raises: [TimeParseError, TimeFormatParseError, Defect].} =
## Shorthand for constructing a ``TimeFormat`` and using it to parse ## Shorthand for constructing a ``TimeFormat`` and using it to parse
## ``input`` as a ``DateTime``. ## ``input`` as a ``DateTime``.
@ -2390,7 +2401,8 @@ proc parse*(input, f: string, tz: Timezone = local(), loc: DateTimeLocale = Defa
let dtFormat = initTimeFormat(f) let dtFormat = initTimeFormat(f)
result = input.parse(dtFormat, tz, loc = loc) result = input.parse(dtFormat, tz, loc = loc)
proc parse*(input: string, f: static[string], zone: Timezone = local(), loc: DateTimeLocale = DefaultLocale): proc parse*(input: string, f: static[string], zone: Timezone = local(),
loc: DateTimeLocale = DefaultLocale):
DateTime {.raises: [TimeParseError, Defect].} = DateTime {.raises: [TimeParseError, Defect].} =
## Overload that validates ``f`` at compile time. ## Overload that validates ``f`` at compile time.
const f2 = initTimeFormat(f) const f2 = initTimeFormat(f)
@ -2530,7 +2542,8 @@ when not defined(JS):
when defined(macosx): when defined(macosx):
var a: Timeval var a: Timeval
gettimeofday(a) gettimeofday(a)
result = toBiggestFloat(a.tv_sec.int64) + toBiggestFloat(a.tv_usec)*0.00_0001 result = toBiggestFloat(a.tv_sec.int64) + toBiggestFloat(
a.tv_usec)*0.00_0001
elif defined(posix): elif defined(posix):
var ts: Timespec var ts: Timespec
discard clock_gettime(CLOCK_REALTIME, ts) discard clock_gettime(CLOCK_REALTIME, ts)
@ -2575,7 +2588,7 @@ proc days*(dur: Duration): int64
dur.inDays dur.inDays
proc hours*(dur: Duration): int64 proc hours*(dur: Duration): int64
{.inline,deprecated: "Use `inHours` instead".} = {.inline, deprecated: "Use `inHours` instead".} =
## Number of whole hours represented by the duration. ## Number of whole hours represented by the duration.
## ##
## **Deprecated since version v0.20.0**: Use the `inHours proc ## **Deprecated since version v0.20.0**: Use the `inHours proc
@ -2647,7 +2660,8 @@ proc fractional*(dur: Duration): Duration {.inline, deprecated.} =
runnableExamples: runnableExamples:
let dur = initDuration(minutes = 5, seconds = 6, milliseconds = 7, let dur = initDuration(minutes = 5, seconds = 6, milliseconds = 7,
microseconds = 8, nanoseconds = 9) microseconds = 8, nanoseconds = 9)
doAssert dur.fractional == initDuration(milliseconds = 7, microseconds = 8, nanoseconds = 9) doAssert dur.fractional == initDuration(milliseconds = 7, microseconds = 8,
nanoseconds = 9)
initDuration(nanoseconds = dur.nanosecond) initDuration(nanoseconds = dur.nanosecond)
when not defined(JS): when not defined(JS):

View file

@ -169,7 +169,8 @@ method suiteStarted*(formatter: OutputFormatter, suiteName: string) {.base, gcsa
discard discard
method testStarted*(formatter: OutputFormatter, testName: string) {.base, gcsafe.} = method testStarted*(formatter: OutputFormatter, testName: string) {.base, gcsafe.} =
discard discard
method failureOccurred*(formatter: OutputFormatter, checkpoints: seq[string], stackTrace: string) {.base, gcsafe.} = method failureOccurred*(formatter: OutputFormatter, checkpoints: seq[string],
stackTrace: string) {.base, gcsafe.} =
## ``stackTrace`` is provided only if the failure occurred due to an exception. ## ``stackTrace`` is provided only if the failure occurred due to an exception.
## ``checkpoints`` is never ``nil``. ## ``checkpoints`` is never ``nil``.
discard discard
@ -182,7 +183,7 @@ proc addOutputFormatter*(formatter: OutputFormatter) =
formatters.add(formatter) formatters.add(formatter)
proc delOutputFormatter*(formatter: OutputFormatter) = proc delOutputFormatter*(formatter: OutputFormatter) =
keepIf(formatters, proc (x: OutputFormatter) : bool = keepIf(formatters, proc (x: OutputFormatter): bool =
x != formatter) x != formatter)
proc newConsoleOutputFormatter*(outputLevel: OutputLevel = PRINT_ALL, proc newConsoleOutputFormatter*(outputLevel: OutputLevel = PRINT_ALL,
@ -228,7 +229,8 @@ method suiteStarted*(formatter: ConsoleOutputFormatter, suiteName: string) =
method testStarted*(formatter: ConsoleOutputFormatter, testName: string) = method testStarted*(formatter: ConsoleOutputFormatter, testName: string) =
formatter.isInTest = true formatter.isInTest = true
method failureOccurred*(formatter: ConsoleOutputFormatter, checkpoints: seq[string], stackTrace: string) = method failureOccurred*(formatter: ConsoleOutputFormatter,
checkpoints: seq[string], stackTrace: string) =
if stackTrace.len > 0: if stackTrace.len > 0:
echo stackTrace echo stackTrace
let prefix = if formatter.isInSuite: " " else: "" let prefix = if formatter.isInSuite: " " else: ""
@ -241,14 +243,16 @@ method testEnded*(formatter: ConsoleOutputFormatter, testResult: TestResult) =
if formatter.outputLevel != PRINT_NONE and if formatter.outputLevel != PRINT_NONE and
(formatter.outputLevel == PRINT_ALL or testResult.status == FAILED): (formatter.outputLevel == PRINT_ALL or testResult.status == FAILED):
let prefix = if testResult.suiteName.len > 0: " " else: "" let prefix = if testResult.suiteName.len > 0: " " else: ""
template rawPrint() = echo(prefix, "[", $testResult.status, "] ", testResult.testName) template rawPrint() = echo(prefix, "[", $testResult.status, "] ",
testResult.testName)
when not defined(ECMAScript): when not defined(ECMAScript):
if formatter.colorOutput and not defined(ECMAScript): if formatter.colorOutput and not defined(ECMAScript):
var color = case testResult.status var color = case testResult.status
of OK: fgGreen of OK: fgGreen
of FAILED: fgRed of FAILED: fgRed
of SKIPPED: fgYellow of SKIPPED: fgYellow
styledEcho styleBright, color, prefix, "[", $testResult.status, "] ", resetStyle, testResult.testName styledEcho styleBright, color, prefix, "[", $testResult.status, "] ",
resetStyle, testResult.testName
else: else:
rawPrint() rawPrint()
else: else:
@ -300,7 +304,8 @@ method testStarted*(formatter: JUnitOutputFormatter, testName: string) =
formatter.testStackTrace.setLen(0) formatter.testStackTrace.setLen(0)
formatter.testStartTime = epochTime() formatter.testStartTime = epochTime()
method failureOccurred*(formatter: JUnitOutputFormatter, checkpoints: seq[string], stackTrace: string) = method failureOccurred*(formatter: JUnitOutputFormatter,
checkpoints: seq[string], stackTrace: string) =
## ``stackTrace`` is provided only if the failure occurred due to an exception. ## ``stackTrace`` is provided only if the failure occurred due to an exception.
## ``checkpoints`` is never ``nil``. ## ``checkpoints`` is never ``nil``.
formatter.testErrors.add(checkpoints) formatter.testErrors.add(checkpoints)
@ -310,7 +315,8 @@ method failureOccurred*(formatter: JUnitOutputFormatter, checkpoints: seq[string
method testEnded*(formatter: JUnitOutputFormatter, testResult: TestResult) = method testEnded*(formatter: JUnitOutputFormatter, testResult: TestResult) =
let time = epochTime() - formatter.testStartTime let time = epochTime() - formatter.testStartTime
let timeStr = time.formatFloat(ffDecimal, precision = 8) let timeStr = time.formatFloat(ffDecimal, precision = 8)
formatter.stream.writeLine("\t\t<testcase name=\"$#\" time=\"$#\">" % [xmlEscape(testResult.testName), timeStr]) formatter.stream.writeLine("\t\t<testcase name=\"$#\" time=\"$#\">" % [
xmlEscape(testResult.testName), timeStr])
case testResult.status case testResult.status
of OK: of OK:
discard discard
@ -327,7 +333,8 @@ method testEnded*(formatter: JUnitOutputFormatter, testResult: TestResult) =
var errs = "" var errs = ""
if formatter.testErrors.len > 1: if formatter.testErrors.len > 1:
var startIdx = if formatter.testStackTrace.len > 0: 0 else: 1 var startIdx = if formatter.testStackTrace.len > 0: 0 else: 1
var endIdx = if formatter.testStackTrace.len > 0: formatter.testErrors.len - 2 var endIdx = if formatter.testStackTrace.len > 0:
formatter.testErrors.len - 2
else: formatter.testErrors.len - 1 else: formatter.testErrors.len - 1
for errIdx in startIdx..endIdx: for errIdx in startIdx..endIdx:
@ -336,11 +343,13 @@ method testEnded*(formatter: JUnitOutputFormatter, testResult: TestResult) =
errs.add(xmlEscape(formatter.testErrors[errIdx])) errs.add(xmlEscape(formatter.testErrors[errIdx]))
if formatter.testStackTrace.len > 0: if formatter.testStackTrace.len > 0:
formatter.stream.writeLine("\t\t\t<error message=\"$#\">$#</error>" % [failureMsg, xmlEscape(formatter.testStackTrace)]) formatter.stream.writeLine("\t\t\t<error message=\"$#\">$#</error>" % [
failureMsg, xmlEscape(formatter.testStackTrace)])
if errs.len > 0: if errs.len > 0:
formatter.stream.writeLine("\t\t\t<system-err>$#</system-err>" % errs) formatter.stream.writeLine("\t\t\t<system-err>$#</system-err>" % errs)
else: else:
formatter.stream.writeLine("\t\t\t<failure message=\"$#\">$#</failure>" % [failureMsg, errs]) formatter.stream.writeLine("\t\t\t<failure message=\"$#\">$#</failure>" %
[failureMsg, errs])
formatter.stream.writeLine("\t\t</testcase>") formatter.stream.writeLine("\t\t</testcase>")
@ -355,7 +364,7 @@ proc glob(matcher, filter: string): bool =
if not filter.contains('*'): if not filter.contains('*'):
return matcher == filter return matcher == filter
let beforeAndAfter = filter.split('*', maxsplit=1) let beforeAndAfter = filter.split('*', maxsplit = 1)
if beforeAndAfter.len == 1: if beforeAndAfter.len == 1:
# "foo*" # "foo*"
return matcher.startsWith(beforeAndAfter[0]) return matcher.startsWith(beforeAndAfter[0])
@ -363,7 +372,8 @@ proc glob(matcher, filter: string): bool =
if matcher.len < filter.len - 1: if matcher.len < filter.len - 1:
return false # "12345" should not match "123*345" return false # "12345" should not match "123*345"
return matcher.startsWith(beforeAndAfter[0]) and matcher.endsWith(beforeAndAfter[1]) return matcher.startsWith(beforeAndAfter[0]) and matcher.endsWith(
beforeAndAfter[1])
proc matchFilter(suiteName, testName, filter: string): bool = proc matchFilter(suiteName, testName, filter: string): bool =
if filter == "": if filter == "":
@ -371,14 +381,15 @@ proc matchFilter(suiteName, testName, filter: string): bool =
if testName == filter: if testName == filter:
# corner case for tests containing "::" in their name # corner case for tests containing "::" in their name
return true return true
let suiteAndTestFilters = filter.split("::", maxsplit=1) let suiteAndTestFilters = filter.split("::", maxsplit = 1)
if suiteAndTestFilters.len == 1: if suiteAndTestFilters.len == 1:
# no suite specified # no suite specified
let testFilter = suiteAndTestFilters[0] let testFilter = suiteAndTestFilters[0]
return glob(testName, testFilter) return glob(testName, testFilter)
return glob(suiteName, suiteAndTestFilters[0]) and glob(testName, suiteAndTestFilters[1]) return glob(suiteName, suiteAndTestFilters[0]) and
glob(testName, suiteAndTestFilters[1])
when defined(testing): export matchFilter when defined(testing): export matchFilter
@ -626,7 +637,7 @@ macro check*(conditions: untyped): untyped =
let paramAst = exp[i] let paramAst = exp[i]
if exp[i].kind == nnkIdent: if exp[i].kind == nnkIdent:
result.printOuts.add getAst(print(argStr, paramAst)) result.printOuts.add getAst(print(argStr, paramAst))
if exp[i].kind in nnkCallKinds + { nnkDotExpr, nnkBracketExpr }: if exp[i].kind in nnkCallKinds + {nnkDotExpr, nnkBracketExpr}:
let callVar = newIdentNode(":c" & $counter) let callVar = newIdentNode(":c" & $counter)
result.assigns.add getAst(asgn(callVar, paramAst)) result.assigns.add getAst(asgn(callVar, paramAst))
result.check[i] = callVar result.check[i] = callVar