Added system.program_results for controlling the exit code of the program under normal circumstances

Implemented operators like +=, -=, etc for ordinals, floats and string

Programs using the UnitTest module will now report the number of failed tests as the exit code of test runs (0 for successful run)
This commit is contained in:
Zahary Karadjov 2011-11-10 04:10:03 +02:00
commit 489340658e
5 changed files with 58 additions and 13 deletions

View file

@ -707,13 +707,13 @@ proc genMainProc(m: BModule) =
CommonMainBody & "}$n" CommonMainBody & "}$n"
PosixCMain = "int main(int argc, char** args, char** env) {$n" & PosixCMain = "int main(int argc, char** args, char** env) {$n" &
" cmdLine = args;$n" & " cmdCount = argc;$n" & " gEnv = env;$n" & " cmdLine = args;$n" & " cmdCount = argc;$n" & " gEnv = env;$n" &
" NimMain();$n" & " return 0;$n" & "}$n" " NimMain();$n" & " return nim_program_result;$n" & "}$n"
WinNimMain = "N_CDECL(void, NimMain)(void) {$n" & WinNimMain = "N_CDECL(void, NimMain)(void) {$n" &
CommonMainBody & "}$n" CommonMainBody & "}$n"
WinCMain = "N_STDCALL(int, WinMain)(HINSTANCE hCurInstance, $n" & WinCMain = "N_STDCALL(int, WinMain)(HINSTANCE hCurInstance, $n" &
" HINSTANCE hPrevInstance, $n" & " HINSTANCE hPrevInstance, $n" &
" LPSTR lpCmdLine, int nCmdShow) {$n" & " LPSTR lpCmdLine, int nCmdShow) {$n" &
" NimMain();$n" & " return 0;$n" & "}$n" " NimMain();$n" & " return nim_program_result;$n" & "}$n"
WinNimDllMain = "N_LIB_EXPORT N_CDECL(void, NimMain)(void) {$n" & WinNimDllMain = "N_LIB_EXPORT N_CDECL(void, NimMain)(void) {$n" &
CommonMainBody & "}$n" CommonMainBody & "}$n"
WinCDllMain = WinCDllMain =

View file

@ -331,6 +331,8 @@ typedef long long int NI64;
typedef unsigned int NU32; typedef unsigned int NU32;
#endif #endif
extern NI nim_program_result;
typedef float NF32; typedef float NF32;
typedef double NF64; typedef double NF64;
typedef double NF; typedef double NF;

View file

@ -20,12 +20,14 @@ import
macros, terminal macros, terminal
type type
TestStatus* = enum OK, FAILED TTestStatus* = enum OK, FAILED
# ETestFailed* = object of ESynch TOutputLevel* = enum PRINT_ALL, PRINT_FAILURES, PRINT_NONE
var var
# XXX: These better be thread-local # XXX: These better be thread-local
AbortOnError* = false AbortOnError* = false
OutputLevel* = PRINT_ALL
checkpoints: seq[string] = @[] checkpoints: seq[string] = @[]
template TestSetupIMPL*: stmt = nil template TestSetupIMPL*: stmt = nil
@ -36,20 +38,25 @@ proc shouldRun(testName: string): bool =
template suite*(name: expr, body: stmt): stmt = template suite*(name: expr, body: stmt): stmt =
block: block:
template setup(setupBody: stmt): stmt = template setup*(setupBody: stmt): stmt =
template TestSetupIMPL: stmt = setupBody template TestSetupIMPL: stmt = setupBody
template teardown(teardownBody: stmt): stmt = template teardown*(teardownBody: stmt): stmt =
template TestTeardownIMPL: stmt = teardownBody template TestTeardownIMPL: stmt = teardownBody
body body
proc printStatus*(s: TestStatus, name: string) = proc testDone(name: string, s: TTestStatus) =
if s == FAILED:
program_result += 1
if OutputLevel != PRINT_NONE and (OutputLevel == PRINT_ALL or s == FAILED):
var color = (if s == OK: fgGreen else: fgRed) var color = (if s == OK: fgGreen else: fgRed)
styledEcho styleBright, color, "[", $s, "] ", fgWhite, name, "\n" styledEcho styleBright, color, "[", $s, "] ", fgWhite, name, "\n"
template test*(name: expr, body: stmt): stmt = template test*(name: expr, body: stmt): stmt =
bind shouldRun, checkPoints bind shouldRun, checkpoints, testDone
if shouldRun(name): if shouldRun(name):
checkpoints = @[] checkpoints = @[]
var TestStatusIMPL = OK var TestStatusIMPL = OK
@ -60,7 +67,7 @@ template test*(name: expr, body: stmt): stmt =
finally: finally:
TestTeardownIMPL() TestTeardownIMPL()
printStatus(TestStatusIMPL, name) testDone name, TestStatusIMPL
proc checkpoint*(msg: string) = proc checkpoint*(msg: string) =
checkpoints.add(msg) checkpoints.add(msg)
@ -85,6 +92,8 @@ macro check*(conditions: stmt): stmt =
result = getAst(rewrite(e, e.lineinfo, e.toStrLit)) result = getAst(rewrite(e, e.lineinfo, e.toStrLit))
echo conditions.lispRepr
case conditions.kind case conditions.kind
of nnkCall, nnkCommand, nnkMacroStmt: of nnkCall, nnkCommand, nnkMacroStmt:
case conditions[1].kind case conditions[1].kind
@ -124,7 +133,7 @@ macro check*(conditions: stmt): stmt =
result = standardRewrite(conditions[1]) result = standardRewrite(conditions[1])
else: else:
error conditions.lineinfo & ": Malformed check statement" error conditions.lineinfo & ": Malformed check statement:"
template require*(conditions: stmt): stmt = template require*(conditions: stmt): stmt =
block: block:

View file

@ -402,6 +402,9 @@ proc `+` *(x, y: int32): int32 {.magic: "AddI", noSideEffect.}
proc `+` *(x, y: int64): int64 {.magic: "AddI64", noSideEffect.} proc `+` *(x, y: int64): int64 {.magic: "AddI64", noSideEffect.}
## Binary `+` operator for an integer. ## Binary `+` operator for an integer.
proc `+=`*[T](x, y: ordinal[T]) {.magic: "Inc", noSideEffect.}
## Increments an ordinal
proc `-` *(x, y: int): int {.magic: "SubI", noSideEffect.} proc `-` *(x, y: int): int {.magic: "SubI", noSideEffect.}
proc `-` *(x, y: int8): int8 {.magic: "SubI", noSideEffect.} proc `-` *(x, y: int8): int8 {.magic: "SubI", noSideEffect.}
proc `-` *(x, y: int16): int16 {.magic: "SubI", noSideEffect.} proc `-` *(x, y: int16): int16 {.magic: "SubI", noSideEffect.}
@ -409,6 +412,9 @@ proc `-` *(x, y: int32): int32 {.magic: "SubI", noSideEffect.}
proc `-` *(x, y: int64): int64 {.magic: "SubI64", noSideEffect.} proc `-` *(x, y: int64): int64 {.magic: "SubI64", noSideEffect.}
## Binary `-` operator for an integer. ## Binary `-` operator for an integer.
proc `-=`*[T](x, y: ordinal[T]) {.magic: "Dec", noSideEffect.}
## Decrements an ordinal
proc `*` *(x, y: int): int {.magic: "MulI", noSideEffect.} proc `*` *(x, y: int): int {.magic: "MulI", noSideEffect.}
proc `*` *(x, y: int8): int8 {.magic: "MulI", noSideEffect.} proc `*` *(x, y: int8): int8 {.magic: "MulI", noSideEffect.}
proc `*` *(x, y: int16): int16 {.magic: "MulI", noSideEffect.} proc `*` *(x, y: int16): int16 {.magic: "MulI", noSideEffect.}
@ -416,6 +422,10 @@ proc `*` *(x, y: int32): int32 {.magic: "MulI", noSideEffect.}
proc `*` *(x, y: int64): int64 {.magic: "MulI64", noSideEffect.} proc `*` *(x, y: int64): int64 {.magic: "MulI64", noSideEffect.}
## Binary `*` operator for an integer. ## Binary `*` operator for an integer.
proc `*=`*[T](x: var ordinal[T], y: ordinal[T]) {.inline noSideEffect.} =
## Binary `*=` operator for oridinals
x = x * y
proc `div` *(x, y: int): int {.magic: "DivI", noSideEffect.} proc `div` *(x, y: int): int {.magic: "DivI", noSideEffect.}
proc `div` *(x, y: int8): int8 {.magic: "DivI", noSideEffect.} proc `div` *(x, y: int8): int8 {.magic: "DivI", noSideEffect.}
proc `div` *(x, y: int16): int16 {.magic: "DivI", noSideEffect.} proc `div` *(x, y: int16): int16 {.magic: "DivI", noSideEffect.}
@ -569,6 +579,22 @@ proc `*` *(x, y: float): float {.magic: "MulF64", noSideEffect.}
proc `/` *(x, y: float): float {.magic: "DivF64", noSideEffect.} proc `/` *(x, y: float): float {.magic: "DivF64", noSideEffect.}
## computes the floating point division ## computes the floating point division
proc `+=` *(x: var float, y:float) {.inline noSideEffect.} =
## Increments in placee a floating point number
x = x + y
proc `-=` *(x: var float, y:float) {.inline noSideEffect.} =
## Decrements in place a floating point number
x = x - y
proc `*=` *(x: var float, y:float) {.inline noSideEffect.} =
## Multiplies in place a floating point number
x = x * y
proc `/=` *(x: var float, y:float) {.inline noSideEffect.} =
## Divides in place a floating point number
x = x / y
proc `==` *(x, y: float): bool {.magic: "EqF64", noSideEffect.} proc `==` *(x, y: float): bool {.magic: "EqF64", noSideEffect.}
proc `<=` *(x, y: float): bool {.magic: "LeF64", noSideEffect.} proc `<=` *(x, y: float): bool {.magic: "LeF64", noSideEffect.}
proc `<` *(x, y: float): bool {.magic: "LtF64", noSideEffect.} proc `<` *(x, y: float): bool {.magic: "LtF64", noSideEffect.}
@ -717,6 +743,8 @@ proc `&` * (x: char, y: string): string {.
proc add*(x: var string, y: char) {.magic: "AppendStrCh", noSideEffect.} proc add*(x: var string, y: char) {.magic: "AppendStrCh", noSideEffect.}
proc add*(x: var string, y: string) {.magic: "AppendStrStr", noSideEffect.} proc add*(x: var string, y: string) {.magic: "AppendStrStr", noSideEffect.}
proc `&=`* (x: var string, y: string) {.magic: "AppendStrStr", noSideEffect.}
type type
TEndian* = enum ## is a type describing the endianness of a processor. TEndian* = enum ## is a type describing the endianness of a processor.
littleEndian, bigEndian littleEndian, bigEndian
@ -1541,6 +1569,11 @@ const
## is the value that should be passed to ``quit`` to indicate ## is the value that should be passed to ``quit`` to indicate
## failure. ## failure.
var program_result* {.exportc: "nim_$1".} = QuitSuccess
## modify this varialbe to specify the exit code of the program
## under normal circumstances. when the program is terminated
## prematurelly using ``quit``, this value is ignored.
proc quit*(errorcode: int = QuitSuccess) {. proc quit*(errorcode: int = QuitSuccess) {.
magic: "Exit", importc: "exit", noDecl, noReturn.} magic: "Exit", importc: "exit", noDecl, noReturn.}
## stops the program immediately; before stopping the program the ## stops the program immediately; before stopping the program the

View file

@ -102,6 +102,7 @@ Library Additions
- Added ``strutils.unindent``, ``strutils.countLines``. - Added ``strutils.unindent``, ``strutils.countLines``.
- Added ``system.slurp`` for easy resource embedding. - Added ``system.slurp`` for easy resource embedding.
- Added ``system.running`` for threads. - Added ``system.running`` for threads.
- Added ``system.program_result``.
- Added ``xmltree.innerText``. - Added ``xmltree.innerText``.
- Added ``os.isAbsolute``, ``os.dynLibFormat``. - Added ``os.isAbsolute``, ``os.dynLibFormat``.
- Added ``parseutils.interpolatedFragments``. - Added ``parseutils.interpolatedFragments``.