diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-12-12 16:29:46 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-12 16:29:46 +0100 |
commit | a1bf9fd2b6525e613899c5dc0380fb80021ee3e7 (patch) | |
tree | d2bdb332c973d2f6d43391369229cc732642c74d | |
parent | a38f35359738534ba856d02f3564d5fbc2dfc822 (diff) | |
parent | 070bcf4cea28a3238089379f5884787b2084b2de (diff) | |
download | Nim-a1bf9fd2b6525e613899c5dc0380fb80021ee3e7.tar.gz |
Merge branch 'devel' into sorted_deduplicate
494 files changed, 2507 insertions, 2655 deletions
diff --git a/.gitignore b/.gitignore index 8cd092639..d736cdf8d 100644 --- a/.gitignore +++ b/.gitignore @@ -66,3 +66,6 @@ testresults/ test.txt /test.ini +tweeter.db +tweeter_test.db +megatest.nim diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 70ff59136..9f536e6c9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -53,9 +53,8 @@ test-windows: <<: *win_set_path_def script: - call ci\deps.bat - - nim c --taintMode:on testament\tester + - nim c testament\tester - testament\tester.exe --pedantic all tags: - windows - fast - diff --git a/.travis.yml b/.travis.yml index 4c3c687e2..abd115701 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,7 +51,7 @@ script: #- nimble install sdl1 #- nimble install jester@#head -y #- nimble install niminst - - nim c --taintMode:on -d:nimCoroutines testament/tester + - nim c -d:nimCoroutines testament/tester - testament/tester --pedantic all -d:nimCoroutines - nim c -o:bin/nimpretty nimpretty/nimpretty.nim - nim c -r nimpretty/tester.nim diff --git a/appveyor.yml b/appveyor.yml index a60831f9d..9c8525d72 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -53,8 +53,8 @@ build_script: # - nimble install opengl -y # - nimble install sdl1 -y # - nimble install jester@#head -y - - nim c --taintMode:on -d:nimCoroutines --os:genode -d:posix --compileOnly testament/tester - - nim c --taintMode:on -d:nimCoroutines testament/tester + - nim c -d:nimCoroutines --os:genode -d:posix --compileOnly testament/tester + - nim c -d:nimCoroutines testament/tester test_script: - testament\tester --pedantic all -d:nimCoroutines diff --git a/changelog.md b/changelog.md index f60c038a4..1772652d6 100644 --- a/changelog.md +++ b/changelog.md @@ -29,6 +29,27 @@ - `osproc.execProcess` now also takes a `workingDir` parameter. +- `options.UnpackError` is no longer a ref type and inherits from `System.Defect` instead of `System.ValueError`. + +- nre's `RegexMatch.{captureBounds,captures}[]` no longer return `Option` or + `nil`/`""`, respectivly. Use the newly added `n in p.captures` method to + check if a group is captured, otherwise you'll recieve an exception. + +- nre's `RegexMatch.{captureBounds,captures}.toTable` no longer accept a + default parameter. Instead uncaptured entries are left empty. Use + `Table.getOrDefault()` if you need defaults. + +- nre's `RegexMatch.captures.{items,toSeq}` now returns an `Option[string]` + instead of a `string`. With the removal of `nil` strings, this is the only + way to indicate a missing match. Inside your loops, instead of `capture == + ""` or `capture == nil`, use `capture.isSome` to check if a capture is + present, and `capture.get` to get its value. + +- nre's `replace()` no longer throws `ValueError` when the replacement string + has missing captures. It instead throws `KeyError` for named captures, and + `IndexError` for un-named captures. This is consistant with + `RegexMatch.{captureBounds,captures}[]`. + #### Breaking changes in the compiler - The compiler now implements the "generic symbol prepass" for `when` statements @@ -66,6 +87,8 @@ proc enumToString*(enums: openArray[enum]): string = is instantiation of generic proc symbol. - Added the parameter ``isSorted`` for the ``sequtils.deduplicate`` proc. +- There is a new stdlib mdoule `std/diff` to compute the famous "diff" + of two texts by line. ### Library changes @@ -93,6 +116,9 @@ proc enumToString*(enums: openArray[enum]): string = - There is a new pragma block `noSideEffect` that works like the `gcsafe` pragma block. - added os.getCurrentProcessId() +- User defined pragmas are now allowed in the pragma blocks +- Pragma blocks are now longer eliminated from the typed AST tree to preserve + pragmas for further analysis by macros ### Language changes diff --git a/compiler/ast.nim b/compiler/ast.nim index 40a05e6bf..5f5f296cb 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -723,10 +723,9 @@ type sons*: TNodeSeq comment*: string - TSymSeq* = seq[PSym] TStrTable* = object # a table[PIdent] of PSym counter*: int - data*: TSymSeq + data*: seq[PSym] # -------------- backend information ------------------------------- TLocKind* = enum @@ -1087,9 +1086,6 @@ proc newSym*(symKind: TSymKind, name: PIdent, owner: PSym, result.id = getID() when debugIds: registerId(result) - #if result.id == 77131: - # writeStacktrace() - # echo name.s proc isMetaType*(t: PType): bool = return t.kind in tyMetaTypes or @@ -1261,6 +1257,9 @@ proc `$`*(x: TLockLevel): string = elif x.ord == UnknownLockLevel.ord: result = "<unknown>" else: result = $int16(x) +proc `$`*(s: PSym): string = + result = s.name.s & "@" & $s.id + proc newType*(kind: TTypeKind, owner: PSym): PType = new(result) result.kind = kind diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index b2671d81e..60eecbdc5 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -507,7 +507,7 @@ proc strTableContains*(t: TStrTable, n: PSym): bool = h = nextTry(h, high(t.data)) result = false -proc strTableRawInsert(data: var TSymSeq, n: PSym) = +proc strTableRawInsert(data: var seq[PSym], n: PSym) = var h: Hash = n.name.h and high(data) if sfImmediate notin n.flags: # fast path: @@ -535,7 +535,7 @@ proc strTableRawInsert(data: var TSymSeq, n: PSym) = data[h] = n if favPos >= 0: swap data[h], data[favPos] -proc symTabReplaceRaw(data: var TSymSeq, prevSym: PSym, newSym: PSym) = +proc symTabReplaceRaw(data: var seq[PSym], prevSym: PSym, newSym: PSym) = assert prevSym.name.h == newSym.name.h var h: Hash = prevSym.name.h and high(data) while data[h] != nil: @@ -549,7 +549,7 @@ proc symTabReplace*(t: var TStrTable, prevSym: PSym, newSym: PSym) = symTabReplaceRaw(t.data, prevSym, newSym) proc strTableEnlarge(t: var TStrTable) = - var n: TSymSeq + var n: seq[PSym] newSeq(n, len(t.data) * GrowthFactor) for i in countup(0, high(t.data)): if t.data[i] != nil: strTableRawInsert(n, t.data[i]) diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index b23cd598e..d177e1f88 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -63,26 +63,6 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc, add(pl, ~");$n") line(p, cpsStmts, pl) -proc isInCurrentFrame(p: BProc, n: PNode): bool = - # checks if `n` is an expression that refers to the current frame; - # this does not work reliably because of forwarding + inlining can break it - case n.kind - of nkSym: - if n.sym.kind in {skVar, skResult, skTemp, skLet} and p.prc != nil: - result = p.prc.id == n.sym.owner.id - of nkDotExpr, nkBracketExpr: - if skipTypes(n.sons[0].typ, abstractInst).kind notin {tyVar,tyLent,tyPtr,tyRef}: - result = isInCurrentFrame(p, n.sons[0]) - of nkHiddenStdConv, nkHiddenSubConv, nkConv: - result = isInCurrentFrame(p, n.sons[1]) - of nkHiddenDeref, nkDerefExpr: - # what about: var x = addr(y); callAsOpenArray(x[])? - # *shrug* ``addr`` is unsafe anyway. - result = false - of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr: - result = isInCurrentFrame(p, n.sons[0]) - else: discard - proc genBoundsCheck(p: BProc; arr, a, b: TLoc) proc openArrayLoc(p: BProc, n: PNode): Rope = diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 59ef05f9c..d00371dd8 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -850,7 +850,6 @@ proc genUncheckedArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) = var a, b: TLoc initLocExpr(p, x, a) initLocExpr(p, y, b) - var ty = skipTypes(a.t, abstractVarRange + abstractPtrs + tyUserTypeClasses) d.inheritLocation(a) putIntoDest(p, d, n, ropecg(p.module, "$1[$2]", rdLoc(a), rdCharLoc(b)), a.storage) @@ -867,15 +866,15 @@ proc genArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) = # semantic pass has already checked for const index expressions if firstOrd(p.config, ty) == 0: if (firstOrd(p.config, b.t) < firstOrd(p.config, ty)) or (lastOrd(p.config, b.t) > lastOrd(p.config, ty)): - linefmt(p, cpsStmts, "if ((NU)($1) > (NU)($2)) #raiseIndexError();$n", + linefmt(p, cpsStmts, "if ((NU)($1) > (NU)($2)) #raiseIndexError2($1, $2);$n", rdCharLoc(b), intLiteral(lastOrd(p.config, ty))) else: - linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseIndexError();$n", + linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseIndexError3($1, $2, $3);$n", rdCharLoc(b), first, intLiteral(lastOrd(p.config, ty))) else: let idx = getOrdValue(y) if idx < firstOrd(p.config, ty) or idx > lastOrd(p.config, ty): - localError(p.config, x.info, "index out of bounds") + localError(p.config, x.info, formatErrorIndexBound(idx, firstOrd(p.config, ty), lastOrd(p.config, ty))) d.inheritLocation(a) putIntoDest(p, d, n, ropecg(p.module, "$1[($2)- $3]", rdLoc(a), rdCharLoc(b), first), a.storage) @@ -884,7 +883,6 @@ proc genCStringElem(p: BProc, n, x, y: PNode, d: var TLoc) = var a, b: TLoc initLocExpr(p, x, a) initLocExpr(p, y, b) - var ty = skipTypes(a.t, abstractVarRange) inheritLocation(d, a) putIntoDest(p, d, n, ropecg(p.module, "$1[$2]", rdLoc(a), rdCharLoc(b)), a.storage) @@ -915,7 +913,7 @@ proc genOpenArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) = initLocExpr(p, x, a) initLocExpr(p, y, b) # emit range check: if optBoundsCheck in p.options: - linefmt(p, cpsStmts, "if ((NU)($1) >= (NU)($2Len_0)) #raiseIndexError();$n", + linefmt(p, cpsStmts, "if ((NU)($1) >= (NU)($2Len_0)) #raiseIndexError2($1,$2Len_0-1);$n", rdLoc(b), rdLoc(a)) # BUGFIX: ``>=`` and not ``>``! inheritLocation(d, a) putIntoDest(p, d, n, @@ -931,11 +929,11 @@ proc genSeqElem(p: BProc, n, x, y: PNode, d: var TLoc) = if optBoundsCheck in p.options: if ty.kind == tyString and (not defined(nimNoZeroTerminator) or optLaxStrings in p.options): linefmt(p, cpsStmts, - "if ((NU)($1) > (NU)$2) #raiseIndexError();$n", + "if ((NU)($1) > (NU)$2) #raiseIndexError2($1,$2);$n", rdLoc(b), lenExpr(p, a)) else: linefmt(p, cpsStmts, - "if ((NU)($1) >= (NU)$2) #raiseIndexError();$n", + "if ((NU)($1) >= (NU)$2) #raiseIndexError2($1,$2-1);$n", rdLoc(b), lenExpr(p, a)) if d.k == locNone: d.storage = OnHeap if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}: @@ -1402,7 +1400,6 @@ proc genArrToSeq(p: BProc, n: PNode, d: var TLoc) = else: var i: TLoc getTemp(p, getSysType(p.module.g.graph, unknownLineInfo(), tyInt), i) - let oldCode = p.s(cpsStmts) linefmt(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n", i.r, L.rope) initLoc(elem, locExpr, lodeTyp elemType(skipTypes(n.typ, abstractInst)), OnHeap) elem.r = ropecg(p.module, "$1$3[$2]", rdLoc(d), rdLoc(i), dataField(p)) @@ -2576,7 +2573,6 @@ proc genConstObjConstr(p: BProc; n: PNode): Rope = proc genConstSimpleList(p: BProc, n: PNode): Rope = var length = sonsLen(n) result = rope("{") - let t = n.typ.skipTypes(abstractInst) for i in countup(0, length - 2): addf(result, "$1,$n", [genNamedConstExpr(p, n.sons[i])]) if length > 0: diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index e83b80b7c..6c33b302d 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -559,7 +559,8 @@ proc genParForStmt(p: BProc, t: PNode) = initLocExpr(p, call.sons[1], rangeA) initLocExpr(p, call.sons[2], rangeB) - lineF(p, cpsStmts, "#pragma omp $4$n" & + # $n at the beginning because of #9710 + lineF(p, cpsStmts, "$n#pragma omp $4$n" & "for ($1 = $2; $1 <= $3; ++$1)", [forLoopVar.loc.rdLoc, rangeA.rdLoc, rangeB.rdLoc, diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 3545edc88..457a6e176 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -16,6 +16,8 @@ import condsyms, rodutils, renderer, idgen, cgendata, ccgmerge, semfold, aliases, lowerings, tables, sets, ndi, lineinfos, pathutils, transf +import system/helpers2 + when not defined(leanCompiler): import semparallel diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index cba07446f..f5014fa8c 100644 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -188,7 +188,7 @@ proc methodDef*(g: ModuleGraph; s: PSym, fromCache: bool) = elif sfBase notin s.flags: message(g.config, s.info, warnUseBase) -proc relevantCol(methods: TSymSeq, col: int): bool = +proc relevantCol(methods: seq[PSym], col: int): bool = # returns true iff the position is relevant var t = methods[0].typ.sons[col].skipTypes(skipPtrs) if t.kind == tyObject: @@ -206,7 +206,7 @@ proc cmpSignatures(a, b: PSym, relevantCols: IntSet): int = if (d != high(int)) and d != 0: return d -proc sortBucket(a: var TSymSeq, relevantCols: IntSet) = +proc sortBucket(a: var seq[PSym], relevantCols: IntSet) = # we use shellsort here; fast and simple var n = len(a) var h = 1 @@ -225,7 +225,7 @@ proc sortBucket(a: var TSymSeq, relevantCols: IntSet) = a[j] = v if h == 1: break -proc genDispatcher(g: ModuleGraph; methods: TSymSeq, relevantCols: IntSet): PSym = +proc genDispatcher(g: ModuleGraph; methods: seq[PSym], relevantCols: IntSet): PSym = var base = lastSon(methods[0].ast).sym result = base var paramLen = sonsLen(base.typ) diff --git a/compiler/commands.nim b/compiler/commands.nim index fa17e9851..b090a09a5 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -480,7 +480,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; of "native", "gdb": incl(conf.globalOptions, optCDebug) conf.options = conf.options + {optLineDir} - {optEndb} - defineSymbol(conf.symbols, "nimTypeNames") # type names are used in gdb pretty printing + #defineSymbol(conf.symbols, "nimTypeNames") # type names are used in gdb pretty printing undefSymbol(conf.symbols, "endb") else: localError(conf, info, "expected endb|gdb but found " & arg) @@ -617,6 +617,14 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; of "run", "r": expectNoArg(conf, switch, arg, pass, info) incl(conf.globalOptions, optRun) + of "errormax": + expectArg(conf, switch, arg, pass, info) + # Note: `nim check` (etc) can overwrite this. + # `0` is meaningless, give it a useful meaning as in clang's -ferror-limit + # If user doesn't set this flag and the code doesn't either, it'd + # have the same effect as errorMax = 1 + let ret = parseInt(arg) + conf.errorMax = if ret == 0: high(int) else: ret of "verbosity": expectArg(conf, switch, arg, pass, info) let verbosity = parseInt(arg) diff --git a/compiler/destroyer.nim b/compiler/destroyer.nim index 51ad26f2c..40af11e70 100644 --- a/compiler/destroyer.nim +++ b/compiler/destroyer.nim @@ -116,7 +116,7 @@ Remarks: Rule 1.2 is not yet implemented because ``sink`` is currently import intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees, - strutils, options, dfa, lowerings, tables, modulegraphs, + strutils, options, dfa, lowerings, tables, modulegraphs, msgs, lineinfos, parampatterns const @@ -127,20 +127,11 @@ type owner: PSym g: ControlFlowGraph jumpTargets: IntSet - tmpObj: PType - tmp: PSym destroys, topLevelVars: PNode - toDropBit: Table[int, PSym] graph: ModuleGraph emptyNode: PNode otherRead: PNode -proc getTemp(c: var Con; typ: PType; info: TLineInfo): PNode = - # XXX why are temps fields in an object here? - let f = newSym(skField, getIdent(c.graph.cache, ":d" & $c.tmpObj.n.len), c.owner, info) - f.typ = typ - rawAddField c.tmpObj, f - result = rawDirectAccess(c.tmp, f) proc isHarmlessVar*(s: PSym; c: Con): bool = # 's' is harmless if it used only once and its @@ -329,22 +320,11 @@ proc genDestroy(c: Con; t: PType; dest: PNode): PNode = proc addTopVar(c: var Con; v: PNode) = c.topLevelVars.add newTree(nkIdentDefs, v, c.emptyNode, c.emptyNode) -proc dropBit(c: var Con; s: PSym): PSym = - result = c.toDropBit.getOrDefault(s.id) - assert result != nil - -proc registerDropBit(c: var Con; s: PSym) = - let result = newSym(skTemp, getIdent(c.graph.cache, s.name.s & "_AliveBit"), c.owner, s.info) - result.typ = getSysType(c.graph, s.info, tyBool) - let trueVal = newIntTypeNode(nkIntLit, 1, result.typ) - c.topLevelVars.add newTree(nkIdentDefs, newSymNode result, c.emptyNode, trueVal) - c.toDropBit[s.id] = result - # generate: - # if not sinkParam_AliveBit: `=destroy`(sinkParam) - let t = s.typ.skipTypes({tyGenericInst, tyAlias, tySink}) - if t.destructor != nil: - c.destroys.add newTree(nkIfStmt, - newTree(nkElifBranch, newSymNode result, genDestroy(c, t, newSymNode s))) +proc getTemp(c: var Con; typ: PType; info: TLineInfo): PNode = + let sym = newSym(skTemp, getIdent(c.graph.cache, ":tmpD"), c.owner, info) + sym.typ = typ + result = newSymNode(sym) + c.addTopVar(result) proc p(n: PNode; c: var Con): PNode @@ -355,16 +335,6 @@ template recurse(n, dest) = proc isSinkParam(s: PSym): bool {.inline.} = result = s.kind == skParam and s.typ.kind == tySink -proc destructiveMoveSink(n: PNode; c: var Con): PNode = - # generate: (chckMove(sinkParam_AliveBit); sinkParam_AliveBit = false; sinkParam) - result = newNodeIT(nkStmtListExpr, n.info, n.typ) - let bit = newSymNode dropBit(c, n.sym) - if optMoveCheck in c.owner.options: - result.add callCodegenProc(c.graph, "chckMove", bit.info, bit) - result.add newTree(nkAsgn, bit, - newIntTypeNode(nkIntLit, 0, getSysType(c.graph, n.info, tyBool))) - result.add n - proc genMagicCall(n: PNode; c: var Con; magicname: string; m: TMagic): PNode = result = newNodeI(nkCall, n.info) result.add(newSymNode(createMagic(c.graph, magicname, m))) @@ -395,6 +365,12 @@ proc destructiveMoveVar(n: PNode; c: var Con): PNode = result.add genWasMoved(n, c) result.add tempAsNode +proc sinkParamIsLastReadCheck(c: var Con, s: PNode) = + assert s.kind == nkSym and s.sym.kind == skParam + if not isLastRead(s, c): + localError(c.graph.config, c.otherRead.info, "sink parameter `" & $s.sym.name.s & + "` is already consumed at " & toFileLineCol(c. graph.config, s.info)) + proc passCopyToSink(n: PNode; c: var Con): PNode = result = newNodeIT(nkStmtListExpr, n.info, n.typ) let tmp = getTemp(c, n.typ, n.info) @@ -411,6 +387,11 @@ proc passCopyToSink(n: PNode; c: var Con): PNode = result.add tmp proc pArg(arg: PNode; c: var Con; isSink: bool): PNode = + template pArgIfTyped(arg_part: PNode): PNode = + # typ is nil if we are in if/case expr branch with noreturn + if arg_part.typ == nil: p(arg_part, c) + else: pArg(arg_part, c, isSink) + if isSink: if arg.kind in nkCallKinds: # recurse but skip the call expression in order to prevent @@ -421,17 +402,53 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode = result.add arg[0] for i in 1..<arg.len: result.add pArg(arg[i], c, i < L and parameters[i].kind == tySink) - elif arg.kind in {nkObjConstr, nkCharLit..nkFloat128Lit}: + elif arg.kind in {nkBracket, nkObjConstr, nkTupleConstr, nkBracket, nkCharLit..nkFloat128Lit}: discard "object construction to sink parameter: nothing to do" result = arg + elif arg.kind == nkSym and isSinkParam(arg.sym): + # Sinked params can be consumed only once. We need to reset the memory + # to disable the destructor which we have not elided + sinkParamIsLastReadCheck(c, arg) + result = destructiveMoveVar(arg, c) elif arg.kind == nkSym and arg.sym.kind in InterestingSyms and isLastRead(arg, c): - # if x is a variable and it its last read we eliminate its - # destructor invokation, but don't. We need to reset its memory - # to disable its destructor which we have not elided: + # it is the last read, can be sinked. We need to reset the memory + # to disable the destructor which we have not elided result = destructiveMoveVar(arg, c) - elif arg.kind == nkSym and isSinkParam(arg.sym): - # mark the sink parameter as used: - result = destructiveMoveSink(arg, c) + elif arg.kind in {nkBlockExpr, nkBlockStmt}: + result = copyNode(arg) + result.add arg[0] + result.add pArg(arg[1], c, isSink) + elif arg.kind == nkStmtListExpr: + result = copyNode(arg) + for i in 0..arg.len-2: + result.add p(arg[i], c) + result.add pArg(arg[^1], c, isSink) + elif arg.kind in {nkIfExpr, nkIfStmt}: + result = copyNode(arg) + for i in 0..<arg.len: + var branch = copyNode(arg[i]) + if arg[i].kind in {nkElifBranch, nkElifExpr}: + branch.add p(arg[i][0], c) + branch.add pArgIfTyped(arg[i][1]) + else: + branch.add pArgIfTyped(arg[i][0]) + result.add branch + elif arg.kind == nkCaseStmt: + result = copyNode(arg) + result.add p(arg[0], c) + for i in 1..<arg.len: + var branch: PNode + if arg[i].kind == nkOfbranch: + branch = arg[i] # of branch conditions are constants + branch[^1] = pArgIfTyped(arg[i][^1]) + elif arg[i].kind in {nkElifBranch, nkElifExpr}: + branch = copyNode(arg[i]) + branch.add p(arg[i][0], c) + branch.add pArgIfTyped(arg[i][1]) + else: + branch = copyNode(arg[i]) + branch.add pArgIfTyped(arg[i][0]) + result.add branch else: # an object that is not temporary but passed to a 'sink' parameter # results in a copy. @@ -440,6 +457,11 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode = result = p(arg, c) proc moveOrCopy(dest, ri: PNode; c: var Con): PNode = + template moveOrCopyIfTyped(ri_part: PNode): PNode = + # typ is nil if we are in if/case expr branch with noreturn + if ri_part.typ == nil: p(ri_part, c) + else: moveOrCopy(dest, ri_part, c) + case ri.kind of nkCallKinds: result = genSink(c, dest.typ, dest, ri) @@ -454,7 +476,7 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode = result.add ri2 of nkBracketExpr: if ri[0].kind == nkSym and isUnpackedTuple(ri[0].sym): - # unpacking of tuple: move out the elements + # unpacking of tuple: move out the elements result = genSink(c, dest.typ, dest, ri) else: result = genCopy(c, dest.typ, dest, ri) @@ -464,6 +486,45 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode = for i in 0..ri.len-2: result.add p(ri[i], c) result.add moveOrCopy(dest, ri[^1], c) + of nkBlockExpr, nkBlockStmt: + result = newNodeI(nkBlockStmt, ri.info) + result.add ri[0] ## add label + result.add moveOrCopy(dest, ri[1], c) + of nkIfExpr, nkIfStmt: + result = newNodeI(nkIfStmt, ri.info) + for i in 0..<ri.len: + var branch = copyNode(ri[i]) + if ri[i].kind in {nkElifBranch, nkElifExpr}: + branch.add p(ri[i][0], c) + branch.add moveOrCopyIfTyped(ri[i][1]) + else: + branch.add moveOrCopyIfTyped(ri[i][0]) + result.add branch + of nkCaseStmt: + result = newNodeI(nkCaseStmt, ri.info) + result.add p(ri[0], c) + for i in 1..<ri.len: + var branch: PNode + if ri[i].kind == nkOfbranch: + branch = ri[i] # of branch conditions are constants + branch[^1] = moveOrCopyIfTyped(ri[i][^1]) + elif ri[i].kind in {nkElifBranch, nkElifExpr}: + branch = copyNode(ri[i]) + branch.add p(ri[i][0], c) + branch.add moveOrCopyIfTyped(ri[i][1]) + else: + branch = copyNode(ri[i]) + branch.add moveOrCopyIfTyped(ri[i][0]) + result.add branch + of nkBracket: + # array constructor + result = genSink(c, dest.typ, dest, ri) + let ri2 = copyTree(ri) + for i in 0..<ri.len: + # everything that is passed to an array constructor is consumed, + # so these all act like 'sink' parameters: + ri2[i] = pArg(ri[i], c, isSink = true) + result.add ri2 of nkObjConstr: result = genSink(c, dest.typ, dest, ri) let ri2 = copyTree(ri) @@ -484,14 +545,17 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode = ri2[i] = pArg(ri[i], c, isSink = true) result.add ri2 of nkSym: - if ri.sym.kind != skParam and isLastRead(ri, c): + if isSinkParam(ri.sym): # Rule 3: `=sink`(x, z); wasMoved(z) + sinkParamIsLastReadCheck(c, ri) var snk = genSink(c, dest.typ, dest, ri) - snk.add p(ri, c) + snk.add ri + result = newTree(nkStmtList, snk, genMagicCall(ri, c, "wasMoved", mWasMoved)) + elif ri.sym.kind != skParam and isLastRead(ri, c): + # Rule 3: `=sink`(x, z); wasMoved(z) + var snk = genSink(c, dest.typ, dest, ri) + snk.add ri result = newTree(nkStmtList, snk, genMagicCall(ri, c, "wasMoved", mWasMoved)) - elif isSinkParam(ri.sym): - result = genSink(c, dest.typ, dest, ri) - result.add destructiveMoveSink(ri, c) else: result = genCopy(c, dest.typ, dest, ri) result.add p(ri, c) @@ -512,14 +576,15 @@ proc p(n: PNode; c: var Con): PNode = if it.kind == nkVarTuple and hasDestructor(ri.typ): let x = lowerTupleUnpacking(c.graph, it, c.owner) result.add p(x, c) - elif it.kind == nkIdentDefs and hasDestructor(it[0].typ) and not isUnpackedTuple(it[0].sym): + elif it.kind == nkIdentDefs and hasDestructor(it[0].typ): for j in 0..L-2: let v = it[j] doAssert v.kind == nkSym # move the variable declaration to the top of the frame: c.addTopVar v # make sure it's destroyed at the end of the proc: - c.destroys.add genDestroy(c, v.typ, v) + if not isUnpackedTuple(it[0].sym): + c.destroys.add genDestroy(c, v.typ, v) if ri.kind != nkEmpty: let r = moveOrCopy(v, ri, c) result.add r @@ -566,12 +631,8 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode = echo "injecting into ", n var c: Con c.owner = owner - c.tmp = newSym(skTemp, getIdent(g.cache, ":d"), owner, n.info) - c.tmpObj = createObj(g, owner, n.info) - c.tmp.typ = c.tmpObj c.destroys = newNodeI(nkStmtList, n.info) c.topLevelVars = newNodeI(nkVarSection, n.info) - c.toDropBit = initTable[int, PSym]() c.graph = g c.emptyNode = newNodeI(nkEmpty, n.info) let cfg = constructCfg(owner, n) @@ -586,10 +647,10 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode = let params = owner.typ.n for i in 1 ..< params.len: let param = params[i].sym - if param.typ.kind == tySink: registerDropBit(c, param) + if param.typ.kind == tySink and hasDestructor(param.typ): + c.destroys.add genDestroy(c, param.typ.skipTypes({tyGenericInst, tyAlias, tySink}), params[i]) + let body = p(n, c) - if c.tmp.typ.n.len > 0: - c.addTopVar(newSymNode c.tmp) result = newNodeI(nkStmtList, n.info) if c.topLevelVars.len > 0: result.add c.topLevelVars diff --git a/compiler/dfa.nim b/compiler/dfa.nim index 415cc4ab3..cd32d95d5 100644 --- a/compiler/dfa.nim +++ b/compiler/dfa.nim @@ -272,7 +272,7 @@ proc genReturn(c: var Con; n: PNode) = c.code.add Instr(n: n, kind: goto, dest: high(int) - c.code.len) const - InterestingSyms = {skVar, skResult, skLet} + InterestingSyms = {skVar, skResult, skLet, skParam} proc genUse(c: var Con; n: PNode) = var n = n diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index 09a1cd436..0f9220102 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -37,18 +37,21 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) = case templ.kind of nkSym: var s = templ.sym - if s.owner.id == c.owner.id: + if s.owner == nil or s.owner.id == c.owner.id: if s.kind == skParam and sfGenSym notin s.flags: handleParam actual.sons[s.position] - elif s.kind == skGenericParam or - s.kind == skType and s.typ != nil and s.typ.kind == tyGenericParam: + elif (s.owner != nil) and (s.kind == skGenericParam or + s.kind == skType and s.typ != nil and s.typ.kind == tyGenericParam): handleParam actual.sons[s.owner.typ.len + s.position - 1] else: internalAssert c.config, sfGenSym in s.flags or s.kind == skType var x = PSym(idTableGet(c.mapping, s)) if x == nil: x = copySym(s) - x.owner = c.genSymOwner + # sem'check needs to set the owner properly later, see bug #9476 + x.owner = nil # c.genSymOwner + #if x.kind == skParam and x.owner.kind == skModule: + # internalAssert c.config, false idTablePut(c.mapping, s, x) result.add newSymNode(x, if c.instLines: actual.info else: templ.info) else: @@ -173,6 +176,7 @@ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym; initIdTable(ctx.mapping) let body = tmpl.getBody + #echo "instantion of ", renderTree(body, {renderIds}) if isAtom(body): result = newNodeI(nkPar, body.info) evalTemplateAux(body, args, ctx, result) @@ -189,5 +193,7 @@ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym; evalTemplateAux(body.sons[i], args, ctx, result) result.flags.incl nfFromTemplate result = wrapInComesFrom(n.info, tmpl, result) + #if ctx.debugActive: + # echo "instantion of ", renderTree(result, {renderIds}) dec(conf.evalTemplateCounter) diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index f3f74ece8..2fe151a1c 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -763,6 +763,32 @@ proc execCmdsInParallel(conf: ConfigRef; cmds: seq[string]; prettyCb: proc (idx: rawMessage(conf, errGenerated, "execution of an external program failed: '$1'" % cmds.join()) +proc linkViaResponseFile(conf: ConfigRef; cmd: string) = + # Extracting the linker.exe here is a bit hacky but the best solution + # given ``buildLib``'s design. + var i = 0 + var last = 0 + if cmd.len > 0 and cmd[0] == '"': + inc i + while i < cmd.len and cmd[i] != '"': inc i + last = i + inc i + else: + while i < cmd.len and cmd[i] != ' ': inc i + last = i + while i < cmd.len and cmd[i] == ' ': inc i + let linkerArgs = conf.projectName & "_" & "linkerArgs.txt" + let args = cmd.substr(i) + # GCC's response files don't support backslashes. Junk. + if conf.cCompiler == ccGcc: + writeFile(linkerArgs, args.replace('\\', '/')) + else: + writeFile(linkerArgs, args) + try: + execLinkCmd(conf, cmd.substr(0, last) & " @" & linkerArgs) + finally: + removeFile(linkerArgs) + proc callCCompiler*(conf: ConfigRef; projectfile: AbsoluteFile) = var linkCmd: string @@ -795,7 +821,13 @@ proc callCCompiler*(conf: ConfigRef; projectfile: AbsoluteFile) = linkCmd = getLinkCmd(conf, projectfile, objfiles) if optCompileOnly notin conf.globalOptions: - execLinkCmd(conf, linkCmd) + if defined(windows) and linkCmd.len > 8_000: + # Windows's command line limit is about 8K (don't laugh...) so C compilers on + # Windows support a feature where the command line can be passed via ``@linkcmd`` + # to them. + linkViaResponseFile(conf, linkCmd) + else: + execLinkCmd(conf, linkCmd) else: linkCmd = "" if optGenScript in conf.globalOptions: diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index a9813f5c5..4d22c4224 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -945,7 +945,7 @@ proc needsNoCopy(p: PProc; y: PNode): bool = else: return (mapType(y.typ) != etyBaseIndex and (skipTypes(y.typ, abstractInst).kind in - {tyRef, tyPtr, tyLent, tyVar, tyCString} + IntegralTypes)) + {tyRef, tyPtr, tyLent, tyVar, tyCString, tyProc} + IntegralTypes)) return true proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) = diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index 874cb4bd0..ddde1be31 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -407,11 +407,8 @@ proc detectCapturedVars(n: PNode; owner: PSym; c: var DetectionPass) = obj.n[0].sym.id = -s.id else: addField(obj, s, c.graph.cache) - # but always return because the rest of the proc is only relevant when - # ow != owner: - return # direct or indirect dependency: - if (innerProc and s.typ.callConv == ccClosure) or interestingVar(s): + elif (innerProc and s.typ.callConv == ccClosure) or interestingVar(s): discard """ proc outer() = var x: int diff --git a/compiler/lookups.nim b/compiler/lookups.nim index 2fb4e5241..db03ac2e0 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -169,7 +169,7 @@ proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope) = getSymRepr(c.config, s)) inc missingImpls elif {sfUsed, sfExported} * s.flags == {}: - if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam}: + if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam, skEnumField}: # XXX: implicit type params are currently skTypes # maybe they can be made skGenericParam as well. if s.typ != nil and tfImplicitTypeParam notin s.typ.flags and diff --git a/compiler/main.nim b/compiler/main.nim index 6afe57d87..4e28ed483 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -266,11 +266,23 @@ proc mainCommand*(graph: ModuleGraph) = var libpaths = newJArray() for dir in conf.searchPaths: libpaths.elems.add(%dir.string) - var dumpdata = % [ + var hints = newJObject() # consider factoring with `listHints` + for a in hintMin..hintMax: + let key = lineinfos.HintsToStr[ord(a) - ord(hintMin)] + hints[key] = %(a in conf.notes) + var warnings = newJObject() + for a in warnMin..warnMax: + let key = lineinfos.WarningsToStr[ord(a) - ord(warnMin)] + warnings[key] = %(a in conf.notes) + + var dumpdata = %[ (key: "version", val: %VersionAsString), (key: "project_path", val: %conf.projectFull.string), (key: "defined_symbols", val: definedSymbols), - (key: "lib_paths", val: libpaths) + (key: "lib_paths", val: %libpaths), + (key: "out", val: %conf.outFile.string), + (key: "hints", val: hints), + (key: "warnings", val: warnings), ] msgWriteln(conf, $dumpdata, {msgStdout, msgSkipHook}) diff --git a/compiler/modulegraphs.nim b/compiler/modulegraphs.nim index d05b301ae..63fa597ff 100644 --- a/compiler/modulegraphs.nim +++ b/compiler/modulegraphs.nim @@ -47,7 +47,7 @@ type doStopCompile*: proc(): bool {.closure.} usageSym*: PSym # for nimsuggest owners*: seq[PSym] - methods*: seq[tuple[methods: TSymSeq, dispatcher: PSym]] # needs serialization! + methods*: seq[tuple[methods: seq[PSym], dispatcher: PSym]] # needs serialization! systemModule*: PSym sysTypes*: array[TTypeKind, PType] compilerprocs*: TStrTable diff --git a/compiler/nim.nim b/compiler/nim.nim index 1c4dbd3be..cbd9d6f39 100644 --- a/compiler/nim.nim +++ b/compiler/nim.nim @@ -9,14 +9,14 @@ when defined(gcc) and defined(windows): when defined(x86): - {.link: "icons/nim.res".} + {.link: "../icons/nim.res".} else: - {.link: "icons/nim_icon.o".} + {.link: "../icons/nim_icon.o".} when defined(amd64) and defined(windows) and defined(vcc): - {.link: "icons/nim-amd64-windows-vcc.res".} + {.link: "../icons/nim-amd64-windows-vcc.res".} when defined(i386) and defined(windows) and defined(vcc): - {.link: "icons/nim-i386-windows-vcc.res".} + {.link: "../icons/nim-i386-windows-vcc.res".} import commands, lexer, condsyms, options, msgs, nversion, nimconf, ropes, diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 3d8e5645b..f67e74f11 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -1111,8 +1111,8 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, else: sym.flags.incl sfUsed of wLiftLocals: discard else: invalidPragma(c, it) - elif sym != nil and sym.kind in {skVar, skLet, skParam, skField, skProc, - skFunc, skConverter, skMethod, skType}: + elif sym == nil or (sym != nil and sym.kind in {skVar, skLet, skParam, + skField, skProc, skFunc, skConverter, skMethod, skType}): n.sons[i] = semCustomPragma(c, it) elif sym != nil: illegalCustomPragma(c, it, sym) @@ -1138,7 +1138,7 @@ proc implicitPragmas*(c: PContext, sym: PSym, n: PNode, internalError(c.config, n.info, "implicitPragmas") inc i popInfoContext(c.config) - if sym.kind in routineKinds: mergePragmas(sym.ast, o) + if sym.kind in routineKinds and sym.ast != nil: mergePragmas(sym.ast, o) if lfExportLib in sym.loc.flags and sfExportc notin sym.flags: localError(c.config, n.info, ".dynlib requires .exportc") diff --git a/compiler/sem.nim b/compiler/sem.nim index 924e53b66..8332af346 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -207,11 +207,12 @@ proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym = if result.kind notin {kind, skTemp}: localError(c.config, n.info, "cannot use symbol of kind '" & $result.kind & "' as a '" & $kind & "'") - if sfGenSym in result.flags and result.kind notin {skTemplate, skMacro, skParam}: - # declarative context, so produce a fresh gensym: - result = copySym(result) - result.ast = n.sym.ast - put(c.p, n.sym, result) + when false: + if sfGenSym in result.flags and result.kind notin {skTemplate, skMacro, skParam}: + # declarative context, so produce a fresh gensym: + result = copySym(result) + result.ast = n.sym.ast + put(c.p, n.sym, result) # when there is a nested proc inside a template, semtmpl # will assign a wrong owner during the first pass over the # template; we must fix it here: see #909 diff --git a/compiler/semasgn.nim b/compiler/semasgn.nim index 3947e4f6c..5d676dc76 100644 --- a/compiler/semasgn.nim +++ b/compiler/semasgn.nim @@ -309,11 +309,15 @@ proc liftBody(c: PContext; typ: PType; kind: TTypeAttachedOp; liftBodyAux(a, typ, body, newSymNode(dest).newDeref, newSymNode(src)) # recursion is handled explicitly, do not register the type based operation # before 'liftBodyAux': - case kind - of attachedAsgn: typ.assignment = result - of attachedSink: typ.sink = result - of attachedDeepCopy: typ.deepCopy = result - of attachedDestructor: typ.destructor = result + if c.config.selectedGC == gcDestructors and + typ.kind in {tySequence, tyString} and body.len == 0: + discard "do not cache it yet" + else: + case kind + of attachedAsgn: typ.assignment = result + of attachedSink: typ.sink = result + of attachedDeepCopy: typ.deepCopy = result + of attachedDestructor: typ.destructor = result var n = newNodeI(nkProcDef, info, bodyPos+1) for i in 0 ..< n.len: n.sons[i] = newNodeI(nkEmpty, info) diff --git a/compiler/semdata.nim b/compiler/semdata.nim index bec4a59a4..735c6f6b1 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -100,8 +100,8 @@ type compilesContextId*: int # > 0 if we are in a ``compiles`` magic compilesContextIdGenerator*: int inGenericInst*: int # > 0 if we are instantiating a generic - converters*: TSymSeq # sequence of converters - patterns*: TSymSeq # sequence of pattern matchers + converters*: seq[PSym] + patterns*: seq[PSym] # sequence of pattern matchers optionStack*: seq[POptionEntry] symMapping*: TIdTable # every gensym'ed symbol needs to be mapped # to some new symbol in a generic instantiation @@ -239,7 +239,7 @@ proc newContext*(graph: ModuleGraph; module: PSym): PContext = result.typesWithOps = @[] result.features = graph.config.features -proc inclSym(sq: var TSymSeq, s: PSym) = +proc inclSym(sq: var seq[PSym], s: PSym) = var L = len(sq) for i in countup(0, L - 1): if sq[i].id == s.id: return diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 08917cb29..ddec457a1 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1083,6 +1083,8 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode = # XXX see the hack in sigmatch.nim ... return s.typ.n elif sfGenSym in s.flags: + # the owner should have been set by now by addParamOrResult + internalAssert c.config, s.owner != nil if c.p.wasForwarded: # gensym'ed parameters that nevertheless have been forward declared # need a special fixup: @@ -2289,6 +2291,8 @@ proc semBlock(c: PContext, n: PNode; flags: TExprFlags): PNode = var labl = newSymG(skLabel, n.sons[0], c) if sfGenSym notin labl.flags: addDecl(c, labl) + elif labl.owner == nil: + labl.owner = c.p.owner n.sons[0] = newSymNode(labl, n.sons[0].info) suggestSym(c.config, n.sons[0].info, labl, c.graph.usageSym) styleCheckDef(c.config, labl) diff --git a/compiler/semfold.nim b/compiler/semfold.nim index 5ec702257..9e7ed5cee 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -15,6 +15,8 @@ import nversion, platform, math, msgs, os, condsyms, idents, renderer, types, commands, magicsys, modulegraphs, strtabs, lineinfos +import system/helpers2 + proc newIntNodeT*(intVal: BiggestInt, n: PNode; g: ModuleGraph): PNode = case skipTypes(n.typ, abstractVarRange).kind of tyInt: @@ -489,11 +491,11 @@ proc foldArrayAccess(m: PSym, n: PNode; g: ModuleGraph): PNode = result = x.sons[int(idx)] if result.kind == nkExprColonExpr: result = result.sons[1] else: - localError(g.config, n.info, "index out of bounds: " & $n) + localError(g.config, n.info, formatErrorIndexBound(idx, sonsLen(x)+1) & $n) of nkBracket: idx = idx - firstOrd(g.config, x.typ) if idx >= 0 and idx < x.len: result = x.sons[int(idx)] - else: localError(g.config, n.info, "index out of bounds: " & $n) + else: localError(g.config, n.info, formatErrorIndexBound(idx, x.len+1) & $n) of nkStrLit..nkTripleStrLit: result = newNodeIT(nkCharLit, x.info, n.typ) if idx >= 0 and idx < len(x.strVal): @@ -501,7 +503,7 @@ proc foldArrayAccess(m: PSym, n: PNode; g: ModuleGraph): PNode = elif idx == len(x.strVal) and optLaxStrings in g.config.options: discard else: - localError(g.config, n.info, "index out of bounds: " & $n) + localError(g.config, n.info, formatErrorIndexBound(idx, len(x.strVal)-1) & $n) else: discard proc foldFieldAccess(m: PSym, n: PNode; g: ModuleGraph): PNode = @@ -626,6 +628,14 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode = # It doesn't matter if the argument is const or not for mLengthArray. # This fixes bug #544. result = newIntNodeT(lengthOrd(g.config, n.sons[1].typ), n, g) + of mSizeOf: + let size = getSize(g.config, n[1].typ) + if size >= 0: + result = newIntNode(nkIntLit, size) + result.info = n.info + result.typ = getSysType(g, n.info, tyInt) + else: + result = nil of mAstToStr: result = newStrNodeT(renderTree(n[1], {renderNoComments}), n, g) of mConStrStr: diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 17f61c7dd..09991048e 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -116,7 +116,7 @@ proc freshGenSyms(n: PNode, owner, orig: PSym, symMap: var TIdTable) = var x = PSym(idTableGet(symMap, s)) if x != nil: n.sym = x - elif s.owner.kind == skPackage: + elif s.owner == nil or s.owner.kind == skPackage: #echo "copied this ", s.name.s x = copySym(s) x.owner = owner diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index df2c084a1..7e61854b8 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -321,8 +321,6 @@ proc semOf(c: PContext, n: PNode): PNode = proc magicsAfterOverloadResolution(c: PContext, n: PNode, flags: TExprFlags): PNode = ## This is the preferred code point to implement magics. - ## This function basically works like a macro, with the difference - ## that it is implemented in the compiler and not on the nimvm. ## ``c`` the current module, a symbol table to a very good approximation ## ``n`` the ast like it would be passed to a real macro ## ``flags`` Some flags for more contextual information on how the diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 48aa75528..aec03b492 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -497,8 +497,10 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = var v = semIdentDef(c, a.sons[j], symkind) styleCheckDef(c.config, v) onDef(a[j].info, v) - if sfGenSym notin v.flags and not isDiscardUnderscore(v): - addInterfaceDecl(c, v) + if sfGenSym notin v.flags: + if not isDiscardUnderscore(v): addInterfaceDecl(c, v) + else: + if v.owner == nil: v.owner = c.p.owner when oKeepVariableNames: if c.inUnrolledContext > 0: v.flags.incl(sfShadowed) else: @@ -573,6 +575,7 @@ proc semConst(c: PContext, n: PNode): PNode = setVarType(c, v, typ) v.ast = def # no need to copy if sfGenSym notin v.flags: addInterfaceDecl(c, v) + elif v.owner == nil: v.owner = getCurrOwner(c) var b = newNodeI(nkConstDef, a.info) if importantComments(c.config): b.comment = a.comment addSon(b, newSymNode(v)) @@ -616,6 +619,7 @@ proc semForVars(c: PContext, n: PNode; flags: TExprFlags): PNode = v.typ = iterBase n.sons[0] = newSymNode(v) if sfGenSym notin v.flags: addForVarDecl(c, v) + elif v.owner == nil: v.owner = getCurrOwner(c) else: localError(c.config, n.info, errWrongNumberOfVariables) elif length-2 != sonsLen(iter): @@ -626,8 +630,9 @@ proc semForVars(c: PContext, n: PNode; flags: TExprFlags): PNode = if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal) v.typ = iter.sons[i] n.sons[i] = newSymNode(v) - if sfGenSym notin v.flags and not isDiscardUnderscore(v): - addForVarDecl(c, v) + if sfGenSym notin v.flags: + if not isDiscardUnderscore(v): addForVarDecl(c, v) + elif v.owner == nil: v.owner = getCurrOwner(c) inc(c.p.nestedLoopCounter) openScope(c) n.sons[length-1] = semExprBranch(c, n.sons[length-1], flags) @@ -922,6 +927,7 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) = s = typsym # add it here, so that recursive types are possible: if sfGenSym notin s.flags: addInterfaceDecl(c, s) + elif s.owner == nil: s.owner = getCurrOwner(c) if name.kind == nkPragmaExpr: a.sons[0].sons[0] = newSymNode(s) @@ -1620,7 +1626,8 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, else: s.typ.callConv = lastOptionEntry(c).defaultCC # add it here, so that recursive procs are possible: - if sfGenSym in s.flags: discard + if sfGenSym in s.flags: + if s.owner == nil: s.owner = getCurrOwner(c) elif kind in OverloadableSyms: if not typeIsDetermined: addInterfaceOverloadableSymAt(c, oldScope, s) @@ -1836,35 +1843,49 @@ proc semMacroDef(c: PContext, n: PNode): PNode = if n.sons[bodyPos].kind == nkEmpty: localError(c.config, n.info, errImplOfXexpected % s.name.s) +proc incMod(c: PContext, n: PNode, it: PNode, includeStmtResult: PNode) = + var f = checkModuleName(c.config, it) + if f != InvalidFileIDX: + if containsOrIncl(c.includedFiles, f.int): + localError(c.config, n.info, errRecursiveDependencyX % toFilename(c.config, f)) + else: + addSon(includeStmtResult, semStmt(c, c.graph.includeFileCallback(c.graph, c.module, f), {})) + excl(c.includedFiles, f.int) + proc evalInclude(c: PContext, n: PNode): PNode = result = newNodeI(nkStmtList, n.info) addSon(result, n) for i in countup(0, sonsLen(n) - 1): - var f = checkModuleName(c.config, n.sons[i]) - if f != InvalidFileIDX: - if containsOrIncl(c.includedFiles, f.int): - localError(c.config, n.info, errRecursiveDependencyX % toFilename(c.config, f)) - else: - addSon(result, semStmt(c, c.graph.includeFileCallback(c.graph, c.module, f), {})) - excl(c.includedFiles, f.int) + var imp: PNode + let it = n.sons[i] + if it.kind == nkInfix and it.len == 3 and it[2].kind == nkBracket: + let sep = it[0] + let dir = it[1] + imp = newNodeI(nkInfix, it.info) + imp.add sep + imp.add dir + imp.add sep # dummy entry, replaced in the loop + for x in it[2]: + imp.sons[2] = x + incMod(c, n, imp, result) + else: + incMod(c, n, it, result) proc setLine(n: PNode, info: TLineInfo) = for i in 0 ..< safeLen(n): setLine(n.sons[i], info) n.info = info proc semPragmaBlock(c: PContext, n: PNode): PNode = + checkSonsLen(n, 2, c.config) let pragmaList = n.sons[0] pragma(c, nil, pragmaList, exprPragmas) - result = semExpr(c, n.sons[1]) - n.sons[1] = result + n[1] = semExpr(c, n[1]) + result = n + result.typ = n[1].typ for i in 0 ..< pragmaList.len: case whichPragma(pragmaList.sons[i]) of wLine: setLine(result, pragmaList.sons[i].info) - of wLocks, wGcSafe, wNosideeffect: - result = n - result.typ = n.sons[1].typ - of wNoRewrite: - incl(result.flags, nfNoRewrite) + of wNoRewrite: incl(result.flags, nfNoRewrite) else: discard proc semStaticStmt(c: PContext, n: PNode): PNode = diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index a011a8fc8..f4ff97ba4 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -90,6 +90,8 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = if sonsLen(v) == 2: strVal = v.sons[1] # second tuple part is the string value if skipTypes(strVal.typ, abstractInst).kind in {tyString, tyCString}: + if not isOrdinalType(v.sons[0].typ): + localError(c.config, v.sons[0].info, errOrdinalTypeExpected) x = getOrdValue(v.sons[0]) # first tuple part is the ordinal else: localError(c.config, strVal.info, errStringLiteralExpected) @@ -99,6 +101,8 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = strVal = v x = counter else: + if not isOrdinalType(v.typ): + localError(c.config, v.info, errOrdinalTypeExpected) x = getOrdValue(v) if i != 1: if x != counter: incl(result.flags, tfEnumHasHoles) @@ -821,7 +825,11 @@ proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) = a.typ = nn.typ addDecl(c, a) else: - if sfGenSym notin param.flags: addDecl(c, param) + if sfGenSym in param.flags: + # bug #XXX, fix the gensym'ed parameters owner: + if param.owner == nil: + param.owner = getCurrOwner(c) + else: addDecl(c, param) template shouldHaveMeta(t) = internalAssert c.config, tfHasMeta in t.flags diff --git a/compiler/vm.nim b/compiler/vm.nim index 7e7ec8903..c8784c3e7 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -413,26 +413,12 @@ proc recSetFlagIsRef(arg: PNode) = arg.sons[i].recSetFlagIsRef proc setLenSeq(c: PCtx; node: PNode; newLen: int; info: TLineInfo) = - # FIXME: this doesn't attempt to solve incomplete - # support of tyPtr, tyRef in VM. let typ = node.typ.skipTypes(abstractInst+{tyRange}-{tyTypeDesc}) - let typeEntry = typ.sons[0].skipTypes(abstractInst+{tyRange}-{tyTypeDesc}) - let typeKind = case typeEntry.kind - of tyUInt..tyUInt64: nkUIntLit - of tyRange, tyEnum, tyBool, tyChar, tyInt..tyInt64: nkIntLit - of tyFloat..tyFloat128: nkFloatLit - of tyString: nkStrLit - of tyObject: nkObjConstr - of tySequence: nkNilLit - of tyProc, tyTuple: nkTupleConstr - else: nkEmpty - let oldLen = node.len setLen(node.sons, newLen) if oldLen < newLen: - # TODO: This is still not correct for tyPtr, tyRef default value for i in oldLen ..< newLen: - node.sons[i] = newNodeI(typeKind, info) + node.sons[i] = getNullValue(typ.sons[0], info, c.config) const errIndexOutOfBounds = "index out of bounds" @@ -458,7 +444,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = #if c.traceActive: when traceCode: echo "PC ", pc, " ", c.code[pc].opcode, " ra ", ra, " rb ", instr.regB, " rc ", instr.regC - # message(c.config, c.debug[pc], warnUser, "Trace") + # message(c.config, c.debug[pc], warnUser, "Trace") case instr.opcode of opcEof: return regs[ra] diff --git a/doc/advopt.txt b/doc/advopt.txt index 7cd72f6c3..60cae7fd0 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -11,8 +11,9 @@ Advanced commands: //buildIndex build an index for the whole documentation //run run the project (with Tiny C backend; buggy!) //genDepend generate a DOT file containing the - module dependency graph + module dependency graph //dump dump all defined conditionals and search paths + see also: --dump.format:json (useful with: ` | jq`) //check checks the project for syntax and semantic Advanced options: @@ -103,6 +104,7 @@ Advanced options: value = number of processors (0 for auto-detect) --incremental:on|off only recompile the changed modules (experimental!) --verbosity:0|1|2|3 set Nim's verbosity level (1 is default) + --errorMax:N stop compilation after N errors; 0 means unlimited --experimental:$1 enable experimental language feature -v, --version show detailed version information diff --git a/doc/contributing.rst b/doc/contributing.rst index a2c95db74..e3ab697d3 100644 --- a/doc/contributing.rst +++ b/doc/contributing.rst @@ -263,17 +263,8 @@ Take advantage of no implicit bool conversion doAssert isValid() == true doAssert isValid() # preferred -.. _immediately_invoked_lambdas: -Immediately invoked lambdas (https://en.wikipedia.org/wiki/Immediately-invoked_function_expression) - -.. code-block:: nim - - let a = (proc (): auto = getFoo())() - let a = block: # preferred - getFoo() - .. _design_for_mcs: -Design with method call syntax (UFCS in other languages) chaining in mind +Design with method call syntax chaining in mind .. code-block:: nim diff --git a/doc/lib.rst b/doc/lib.rst index 46e1f9d19..c0119d36d 100644 --- a/doc/lib.rst +++ b/doc/lib.rst @@ -154,6 +154,10 @@ String handling * `std/wordwrap <wordwrap.html>`_ This module contains an algorithm to wordwrap a Unicode string. +* `std/diff <diff.html>`_ + This module contains an algorithm to compute the famous "diff" + of two texts by line. + Generic Operating System Services --------------------------------- diff --git a/koch.nim b/koch.nim index 9a8d38a79..3f528a1b2 100644 --- a/koch.nim +++ b/koch.nim @@ -79,6 +79,7 @@ template withDir(dir, body) = finally: setCurrentdir(old) +let origDir = getCurrentDir() setCurrentDir(getAppDir()) proc tryExec(cmd: string): bool = @@ -378,9 +379,7 @@ proc winRelease*() = template `|`(a, b): string = (if a.len > 0: a else: b) proc tests(args: string) = - # we compile the tester with taintMode:on to have a basic - # taint mode test :-) - nimexec "cc --taintMode:on --opt:speed testament/tester" + nimexec "cc --opt:speed testament/tester" # Since tests take a long time (on my machine), and we want to defy Murhpys # law - lets make sure the compiler really is freshly compiled! nimexec "c --lib:lib -d:release --opt:speed compiler/nim.nim" @@ -415,6 +414,7 @@ proc temp(args: string) = let nimexec = findNim() exec(nimexec & " c -d:debug --debugger:native " & bootArgs & " " & (d / "compiler" / "nim"), 125) copyExe(output, finalDest) + setCurrentDir(origDir) if programArgs.len > 0: exec(finalDest & " " & programArgs) proc xtemp(cmd: string) = diff --git a/lib/impure/nre.nim b/lib/impure/nre.nim index 58594f054..94dd89db5 100644 --- a/lib/impure/nre.nim +++ b/lib/impure/nre.nim @@ -65,7 +65,7 @@ runnableExamples: let hasVowel = firstVowel.isSome() if hasVowel: let matchBounds = firstVowel.get().captureBounds[-1] - doAssert matchBounds.get().a == 1 + doAssert matchBounds.a == 1 # Type definitions {{{ @@ -167,14 +167,15 @@ type ## - ``"abc".match(re"(?<letter>\w)").get.captures["letter"] == "a"`` ## - ``"abc".match(re"(\w)\w").get.captures[-1] == "ab"`` ## - ## ``captureBounds[]: Option[HSlice[int, int]]`` + ## ``captureBounds[]: HSlice[int, int]`` ## gets the bounds of the given capture according to the same rules as ## the above. If the capture is not filled, then ``None`` is returned. ## The bounds are both inclusive. ## - ## - ``"abc".match(re"(\w)").get.captureBounds[0].get == 0 .. 0`` - ## - ``"abc".match(re"").get.captureBounds[-1].get == 0 .. -1`` - ## - ``"abc".match(re"abc").get.captureBounds[-1].get == 0 .. 2`` + ## - ``"abc".match(re"(\w)").get.captureBounds[0] == 0 .. 0`` + ## - ``0 in "abc".match(re"(\w)").get.captureBounds == true`` + ## - ``"abc".match(re"").get.captureBounds[-1] == 0 .. -1`` + ## - ``"abc".match(re"abc").get.captureBounds[-1] == 0 .. 2`` ## ## ``match: string`` ## the full text of the match. @@ -227,9 +228,10 @@ runnableExamples: doAssert "abc".match(re"(?<letter>\w)").get.captures["letter"] == "a" doAssert "abc".match(re"(\w)\w").get.captures[-1] == "ab" - doAssert "abc".match(re"(\w)").get.captureBounds[0].get == 0 .. 0 - doAssert "abc".match(re"").get.captureBounds[-1].get == 0 .. -1 - doAssert "abc".match(re"abc").get.captureBounds[-1].get == 0 .. 2 + doAssert "abc".match(re"(\w)").get.captureBounds[0] == 0 .. 0 + doAssert 0 in "abc".match(re"(\w)").get.captureBounds == true + doAssert "abc".match(re"").get.captureBounds[-1] == 0 .. -1 + doAssert "abc".match(re"abc").get.captureBounds[-1] == 0 .. 2 # }}} proc getinfo[T](pattern: Regex, opt: cint): T = @@ -269,78 +271,99 @@ proc matchesCrLf(pattern: Regex): bool = # }}} # Capture accessors {{{ -proc captureBounds*(pattern: RegexMatch): CaptureBounds = return CaptureBounds(pattern) +func captureBounds*(pattern: RegexMatch): CaptureBounds = return CaptureBounds(pattern) -proc captures*(pattern: RegexMatch): Captures = return Captures(pattern) +func captures*(pattern: RegexMatch): Captures = return Captures(pattern) -proc `[]`*(pattern: CaptureBounds, i: int): Option[HSlice[int, int]] = +func contains*(pattern: CaptureBounds, i: int): bool = let pattern = RegexMatch(pattern) - if pattern.pcreMatchBounds[i + 1].a != -1: - let bounds = pattern.pcreMatchBounds[i + 1] - return some(int(bounds.a) .. int(bounds.b-1)) - else: - return none(HSlice[int, int]) + pattern.pcreMatchBounds[i + 1].a != -1 + +func contains*(pattern: Captures, i: int): bool = + i in CaptureBounds(pattern) -proc `[]`*(pattern: Captures, i: int): string = +func `[]`*(pattern: CaptureBounds, i: int): HSlice[int, int] = + let pattern = RegexMatch(pattern) + if not (i in pattern.captureBounds): + raise newException(IndexError, "Group '" & $i & "' was not captured") + + let bounds = pattern.pcreMatchBounds[i + 1] + int(bounds.a)..int(bounds.b-1) + +func `[]`*(pattern: Captures, i: int): string = let pattern = RegexMatch(pattern) let bounds = pattern.captureBounds[i] - if bounds.isSome: - let bounds = bounds.get - return pattern.str.substr(bounds.a, bounds.b) - else: - return "" + pattern.str.substr(bounds.a, bounds.b) -proc match*(pattern: RegexMatch): string = +func match*(pattern: RegexMatch): string = return pattern.captures[-1] -proc matchBounds*(pattern: RegexMatch): HSlice[int, int] = - return pattern.captureBounds[-1].get +func matchBounds*(pattern: RegexMatch): HSlice[int, int] = + return pattern.captureBounds[-1] + +func contains*(pattern: CaptureBounds, name: string): bool = + let pattern = RegexMatch(pattern) + let nameToId = pattern.pattern.captureNameToId + if not (name in nameToId): + return false + nameToId[name] in pattern.captureBounds + +func contains*(pattern: Captures, name: string): bool = + name in CaptureBounds(pattern) -proc `[]`*(pattern: CaptureBounds, name: string): Option[HSlice[int, int]] = +func checkNamedCaptured(pattern: RegexMatch, name: string): void = + if not (name in pattern.captureBounds): + raise newException(KeyError, "Group '" & name & "' was not captured") + +func `[]`*(pattern: CaptureBounds, name: string): HSlice[int, int] = let pattern = RegexMatch(pattern) - return pattern.captureBounds[pattern.pattern.captureNameToId.fget(name)] + checkNamedCaptured(pattern, name) + pattern.captureBounds[pattern.pattern.captureNameToId[name]] -proc `[]`*(pattern: Captures, name: string): string = +func `[]`*(pattern: Captures, name: string): string = let pattern = RegexMatch(pattern) - return pattern.captures[pattern.pattern.captureNameToId.fget(name)] + checkNamedCaptured(pattern, name) + return pattern.captures[pattern.pattern.captureNameToId[name]] -template toTableImpl(cond: untyped) {.dirty.} = +template toTableImpl() {.dirty.} = for key in RegexMatch(pattern).pattern.captureNameId.keys: - let nextVal = pattern[key] - if cond: - result[key] = default - else: - result[key] = nextVal + if key in pattern: + result[key] = pattern[key] -proc toTable*(pattern: Captures, default: string = ""): Table[string, string] = +func toTable*(pattern: Captures): Table[string, string] = result = initTable[string, string]() - toTableImpl(nextVal.len == 0) + toTableImpl() -proc toTable*(pattern: CaptureBounds, default = none(HSlice[int, int])): - Table[string, Option[HSlice[int, int]]] = - result = initTable[string, Option[HSlice[int, int]]]() - toTableImpl(nextVal.isNone) +func toTable*(pattern: CaptureBounds): Table[string, HSlice[int, int]] = + result = initTable[string, HSlice[int, int]]() + toTableImpl() -template itemsImpl(cond: untyped) {.dirty.} = +template itemsImpl() {.dirty.} = for i in 0 ..< RegexMatch(pattern).pattern.captureCount: - let nextVal = pattern[i] # done in this roundabout way to avoid multiple yields (potential code # bloat) - let nextYieldVal = if cond: default else: nextVal - yield nextYieldVal + let nextYieldVal = if i in pattern: + some(pattern[i]) + else: + default + yield nextYieldVal -iterator items*(pattern: CaptureBounds, default = none(HSlice[int, int])): Option[HSlice[int, int]] = - itemsImpl(nextVal.isNone) +iterator items*(pattern: CaptureBounds, + default = none(HSlice[int, int])): Option[HSlice[int, int]] = + itemsImpl() -iterator items*(pattern: Captures, default: string = ""): string = - itemsImpl(nextVal.len == 0) +iterator items*(pattern: Captures, + default: Option[string] = none(string)): Option[string] = + itemsImpl() -proc toSeq*(pattern: CaptureBounds, default = none(HSlice[int, int])): seq[Option[HSlice[int, int]]] = +proc toSeq*(pattern: CaptureBounds, + default = none(HSlice[int, int])): seq[Option[HSlice[int, int]]] = accumulateResult(pattern.items(default)) -proc toSeq*(pattern: Captures, default: string = ""): seq[string] = +proc toSeq*(pattern: Captures, + default: Option[string] = none(string)): seq[Option[string]] = accumulateResult(pattern.items(default)) proc `$`*(pattern: RegexMatch): string = @@ -652,7 +675,8 @@ proc split*(str: string, pattern: Regex, maxSplit = -1, start = 0): seq[string] for cap in match.captures: # if there are captures, include them in the result - result.add(cap) + if cap.isSome: + result.add(cap.get) if splits == maxSplit - 1: break @@ -706,7 +730,8 @@ proc replace*(str: string, pattern: Regex, ## - ``$#`` - first capture ## - ``$0`` - full match ## - ## If a given capture is missing, a ``ValueError`` exception is thrown. + ## If a given capture is missing, ``IndexError`` thrown for un-named captures + ## and ``KeyError`` for named captures. replaceImpl(str, pattern, subproc(match)) proc replace*(str: string, pattern: Regex, diff --git a/lib/impure/nre/private/util.nim b/lib/impure/nre/private/util.nim index a3ae84007..f7d8b1d60 100644 --- a/lib/impure/nre/private/util.nim +++ b/lib/impure/nre/private/util.nim @@ -1,17 +1,9 @@ ## INTERNAL FILE FOR USE ONLY BY nre.nim. import tables -proc fget*[K, V](self: Table[K, V], key: K): V = - if self.hasKey(key): - return self[key] - else: - raise newException(KeyError, "Key does not exist in table: " & $key) - const Ident = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'} const StartIdent = Ident - {'0'..'9'} -template checkNil(arg: string): string = arg - template formatStr*(howExpr, namegetter, idgetter): untyped = let how = howExpr var val = newStringOfCap(how.len) @@ -28,7 +20,7 @@ template formatStr*(howExpr, namegetter, idgetter): untyped = i += 2 elif how[i + 1] == '#': var id {.inject.} = lastNum - val.add(checkNil(idgetter)) + val.add(idgetter) lastNum += 1 i += 2 elif how[i + 1] in {'0'..'9'}: @@ -37,7 +29,7 @@ template formatStr*(howExpr, namegetter, idgetter): untyped = while i < how.len and how[i] in {'0'..'9'}: id += (id * 10) + (ord(how[i]) - ord('0')) i += 1 - val.add(checkNil(idgetter)) + val.add(idgetter) lastNum = id + 1 elif how[i + 1] in StartIdent: i += 1 @@ -45,7 +37,7 @@ template formatStr*(howExpr, namegetter, idgetter): untyped = while i < how.len and how[i] in Ident: name.add(how[i]) i += 1 - val.add(checkNil(namegetter)) + val.add(namegetter) elif how[i + 1] == '{': i += 2 var name {.inject.} = "" @@ -53,7 +45,7 @@ template formatStr*(howExpr, namegetter, idgetter): untyped = name.add(how[i]) i += 1 i += 1 - val.add(checkNil(namegetter)) + val.add(namegetter) else: raise newException(Exception, "Syntax error in format string at " & $i) val diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index aef4f1ce6..36319a317 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -1513,8 +1513,217 @@ proc poll*(timeout = 500) = ## `epoll`:idx: or `kqueue`:idx: primitive only once. discard runOnce(timeout) -# Common procedures between current and upcoming asyncdispatch -include includes/asynccommon +template createAsyncNativeSocketImpl(domain, sockType, protocol) = + let handle = newNativeSocket(domain, sockType, protocol) + if handle == osInvalidSocket: + return osInvalidSocket.AsyncFD + handle.setBlocking(false) + when defined(macosx) and not defined(nimdoc): + handle.setSockOptInt(SOL_SOCKET, SO_NOSIGPIPE, 1) + result = handle.AsyncFD + register(result) + +proc createAsyncNativeSocket*(domain: cint, sockType: cint, + protocol: cint): AsyncFD = + createAsyncNativeSocketImpl(domain, sockType, protocol) + +proc createAsyncNativeSocket*(domain: Domain = Domain.AF_INET, + sockType: SockType = SOCK_STREAM, + protocol: Protocol = IPPROTO_TCP): AsyncFD = + createAsyncNativeSocketImpl(domain, sockType, protocol) + +proc newAsyncNativeSocket*(domain: cint, sockType: cint, + protocol: cint): AsyncFD {.deprecated: "use createAsyncNativeSocket instead".} = + createAsyncNativeSocketImpl(domain, sockType, protocol) + +proc newAsyncNativeSocket*(domain: Domain = Domain.AF_INET, + sockType: SockType = SOCK_STREAM, + protocol: Protocol = IPPROTO_TCP): AsyncFD + {.deprecated: "use createAsyncNativeSocket instead".} = + createAsyncNativeSocketImpl(domain, sockType, protocol) + +when defined(windows) or defined(nimdoc): + proc bindToDomain(handle: SocketHandle, domain: Domain) = + # Extracted into a separate proc, because connect() on Windows requires + # the socket to be initially bound. + template doBind(saddr) = + if bindAddr(handle, cast[ptr SockAddr](addr(saddr)), + sizeof(saddr).SockLen) < 0'i32: + raiseOSError(osLastError()) + + if domain == Domain.AF_INET6: + var saddr: Sockaddr_in6 + saddr.sin6_family = uint16(toInt(domain)) + doBind(saddr) + else: + var saddr: Sockaddr_in + saddr.sin_family = uint16(toInt(domain)) + doBind(saddr) + + proc doConnect(socket: AsyncFD, addrInfo: ptr AddrInfo): Future[void] = + let retFuture = newFuture[void]("doConnect") + result = retFuture + + var ol = PCustomOverlapped() + GC_ref(ol) + ol.data = CompletionData(fd: socket, cb: + proc (fd: AsyncFD, bytesCount: Dword, errcode: OSErrorCode) = + if not retFuture.finished: + if errcode == OSErrorCode(-1): + retFuture.complete() + else: + retFuture.fail(newException(OSError, osErrorMsg(errcode))) + ) + + let ret = connectEx(socket.SocketHandle, addrInfo.ai_addr, + cint(addrInfo.ai_addrlen), nil, 0, nil, + cast[POVERLAPPED](ol)) + if ret: + # Request to connect completed immediately. + retFuture.complete() + # We don't deallocate ``ol`` here because even though this completed + # immediately poll will still be notified about its completion and it + # will free ``ol``. + else: + let lastError = osLastError() + if lastError.int32 != ERROR_IO_PENDING: + # With ERROR_IO_PENDING ``ol`` will be deallocated in ``poll``, + # and the future will be completed/failed there, too. + GC_unref(ol) + retFuture.fail(newException(OSError, osErrorMsg(lastError))) +else: + proc doConnect(socket: AsyncFD, addrInfo: ptr AddrInfo): Future[void] = + let retFuture = newFuture[void]("doConnect") + result = retFuture + + proc cb(fd: AsyncFD): bool = + let ret = SocketHandle(fd).getSockOptInt( + cint(SOL_SOCKET), cint(SO_ERROR)) + if ret == 0: + # We have connected. + retFuture.complete() + return true + elif ret == EINTR: + # interrupted, keep waiting + return false + else: + retFuture.fail(newException(OSError, osErrorMsg(OSErrorCode(ret)))) + return true + + let ret = connect(socket.SocketHandle, + addrInfo.ai_addr, + addrInfo.ai_addrlen.Socklen) + if ret == 0: + # Request to connect completed immediately. + retFuture.complete() + else: + let lastError = osLastError() + if lastError.int32 == EINTR or lastError.int32 == EINPROGRESS: + addWrite(socket, cb) + else: + retFuture.fail(newException(OSError, osErrorMsg(lastError))) + +template asyncAddrInfoLoop(addrInfo: ptr AddrInfo, fd: untyped, + protocol: Protocol = IPPROTO_RAW) = + ## Iterates through the AddrInfo linked list asynchronously + ## until the connection can be established. + const shouldCreateFd = not declared(fd) + + when shouldCreateFd: + let sockType = protocol.toSockType() + + var fdPerDomain: array[low(Domain).ord..high(Domain).ord, AsyncFD] + for i in low(fdPerDomain)..high(fdPerDomain): + fdPerDomain[i] = osInvalidSocket.AsyncFD + template closeUnusedFds(domainToKeep = -1) {.dirty.} = + for i, fd in fdPerDomain: + if fd != osInvalidSocket.AsyncFD and i != domainToKeep: + fd.closeSocket() + + var lastException: ref Exception + var curAddrInfo = addrInfo + var domain: Domain + when shouldCreateFd: + var curFd: AsyncFD + else: + var curFd = fd + proc tryNextAddrInfo(fut: Future[void]) {.gcsafe.} = + if fut == nil or fut.failed: + if fut != nil: + lastException = fut.readError() + + while curAddrInfo != nil: + let domainOpt = curAddrInfo.ai_family.toKnownDomain() + if domainOpt.isSome: + domain = domainOpt.unsafeGet() + break + curAddrInfo = curAddrInfo.ai_next + + if curAddrInfo == nil: + freeAddrInfo(addrInfo) + when shouldCreateFd: + closeUnusedFds() + if lastException != nil: + retFuture.fail(lastException) + else: + retFuture.fail(newException( + IOError, "Couldn't resolve address: " & address)) + return + + when shouldCreateFd: + curFd = fdPerDomain[ord(domain)] + if curFd == osInvalidSocket.AsyncFD: + try: + curFd = newAsyncNativeSocket(domain, sockType, protocol) + except: + freeAddrInfo(addrInfo) + closeUnusedFds() + raise getCurrentException() + when defined(windows): + curFd.SocketHandle.bindToDomain(domain) + fdPerDomain[ord(domain)] = curFd + + doConnect(curFd, curAddrInfo).callback = tryNextAddrInfo + curAddrInfo = curAddrInfo.ai_next + else: + freeAddrInfo(addrInfo) + when shouldCreateFd: + closeUnusedFds(ord(domain)) + retFuture.complete(curFd) + else: + retFuture.complete() + + tryNextAddrInfo(nil) + +proc dial*(address: string, port: Port, + protocol: Protocol = IPPROTO_TCP): Future[AsyncFD] = + ## Establishes connection to the specified ``address``:``port`` pair via the + ## specified protocol. The procedure iterates through possible + ## resolutions of the ``address`` until it succeeds, meaning that it + ## seamlessly works with both IPv4 and IPv6. + ## Returns the async file descriptor, registered in the dispatcher of + ## the current thread, ready to send or receive data. + let retFuture = newFuture[AsyncFD]("dial") + result = retFuture + let sockType = protocol.toSockType() + + let aiList = getAddrInfo(address, port, Domain.AF_UNSPEC, sockType, protocol) + asyncAddrInfoLoop(aiList, noFD, protocol) + +proc connect*(socket: AsyncFD, address: string, port: Port, + domain = Domain.AF_INET): Future[void] = + let retFuture = newFuture[void]("connect") + result = retFuture + + when defined(windows): + verifyPresence(socket) + else: + assert getSockDomain(socket.SocketHandle) == domain + + let aiList = getAddrInfo(address, port, domain) + when defined(windows): + socket.SocketHandle.bindToDomain(domain) + asyncAddrInfoLoop(aiList, socket) proc sleepAsync*(ms: int | float): Future[void] = ## Suspends the execution of the current async procedure for the next diff --git a/lib/pure/collections/lists.nim b/lib/pure/collections/lists.nim index 0b3708a7c..15ce5d074 100644 --- a/lib/pure/collections/lists.nim +++ b/lib/pure/collections/lists.nim @@ -140,11 +140,26 @@ proc contains*[T](L: SomeLinkedCollection[T], value: T): bool {.inline.} = ## exist, true otherwise. result = find(L, value) != nil +proc append*[T](L: var SinglyLinkedList[T], + n: SinglyLinkedNode[T]) {.inline.} = + ## appends a node `n` to `L`. Efficiency: O(1). + n.next = nil + if L.tail != nil: + assert(L.tail.next == nil) + L.tail.next = n + L.tail = n + if L.head == nil: L.head = n + +proc append*[T](L: var SinglyLinkedList[T], value: T) {.inline.} = + ## appends a value to `L`. Efficiency: O(1). + append(L, newSinglyLinkedNode(value)) + proc prepend*[T](L: var SinglyLinkedList[T], n: SinglyLinkedNode[T]) {.inline.} = ## prepends a node to `L`. Efficiency: O(1). n.next = L.head L.head = n + if L.tail == nil: L.tail = n proc prepend*[T](L: var SinglyLinkedList[T], value: T) {.inline.} = ## prepends a node to `L`. Efficiency: O(1). diff --git a/lib/pure/collections/sharedstrings.nim b/lib/pure/collections/sharedstrings.nim index 7e9de4b73..b283cd4b1 100644 --- a/lib/pure/collections/sharedstrings.nim +++ b/lib/pure/collections/sharedstrings.nim @@ -12,6 +12,8 @@ type UncheckedCharArray = UncheckedArray[char] +import system/helpers2 + type Buffer = ptr object refcount: int @@ -49,11 +51,11 @@ proc len*(s: SharedString): int = s.len proc `[]`*(s: SharedString; i: Natural): char = if i < s.len: result = s.buffer.data[i+s.first] - else: raise newException(IndexError, "index out of bounds") + else: raise newException(IndexError, formatErrorIndexBound(i, s.len-1)) proc `[]=`*(s: var SharedString; i: Natural; value: char) = if i < s.len: s.buffer.data[i+s.first] = value - else: raise newException(IndexError, "index out of bounds") + else: raise newException(IndexError, formatErrorIndexBound(i, s.len-1)) proc `[]`*(s: SharedString; ab: HSlice[int, int]): SharedString = #incRef(src.buffer) diff --git a/lib/pure/includes/asynccommon.nim b/lib/pure/includes/asynccommon.nim deleted file mode 100644 index 13887acc9..000000000 --- a/lib/pure/includes/asynccommon.nim +++ /dev/null @@ -1,211 +0,0 @@ -template createAsyncNativeSocketImpl(domain, sockType, protocol) = - let handle = newNativeSocket(domain, sockType, protocol) - if handle == osInvalidSocket: - return osInvalidSocket.AsyncFD - handle.setBlocking(false) - when defined(macosx) and not defined(nimdoc): - handle.setSockOptInt(SOL_SOCKET, SO_NOSIGPIPE, 1) - result = handle.AsyncFD - register(result) - -proc createAsyncNativeSocket*(domain: cint, sockType: cint, - protocol: cint): AsyncFD = - createAsyncNativeSocketImpl(domain, sockType, protocol) - -proc createAsyncNativeSocket*(domain: Domain = Domain.AF_INET, - sockType: SockType = SOCK_STREAM, - protocol: Protocol = IPPROTO_TCP): AsyncFD = - createAsyncNativeSocketImpl(domain, sockType, protocol) - -proc newAsyncNativeSocket*(domain: cint, sockType: cint, - protocol: cint): AsyncFD {.deprecated: "use createAsyncNativeSocket instead".} = - createAsyncNativeSocketImpl(domain, sockType, protocol) - -proc newAsyncNativeSocket*(domain: Domain = Domain.AF_INET, - sockType: SockType = SOCK_STREAM, - protocol: Protocol = IPPROTO_TCP): AsyncFD - {.deprecated: "use createAsyncNativeSocket instead".} = - createAsyncNativeSocketImpl(domain, sockType, protocol) - -when defined(windows) or defined(nimdoc): - proc bindToDomain(handle: SocketHandle, domain: Domain) = - # Extracted into a separate proc, because connect() on Windows requires - # the socket to be initially bound. - template doBind(saddr) = - if bindAddr(handle, cast[ptr SockAddr](addr(saddr)), - sizeof(saddr).SockLen) < 0'i32: - raiseOSError(osLastError()) - - if domain == Domain.AF_INET6: - var saddr: Sockaddr_in6 - saddr.sin6_family = uint16(toInt(domain)) - doBind(saddr) - else: - var saddr: Sockaddr_in - saddr.sin_family = uint16(toInt(domain)) - doBind(saddr) - - proc doConnect(socket: AsyncFD, addrInfo: ptr AddrInfo): Future[void] = - let retFuture = newFuture[void]("doConnect") - result = retFuture - - var ol = PCustomOverlapped() - GC_ref(ol) - ol.data = CompletionData(fd: socket, cb: - proc (fd: AsyncFD, bytesCount: Dword, errcode: OSErrorCode) = - if not retFuture.finished: - if errcode == OSErrorCode(-1): - retFuture.complete() - else: - retFuture.fail(newException(OSError, osErrorMsg(errcode))) - ) - - let ret = connectEx(socket.SocketHandle, addrInfo.ai_addr, - cint(addrInfo.ai_addrlen), nil, 0, nil, - cast[POVERLAPPED](ol)) - if ret: - # Request to connect completed immediately. - retFuture.complete() - # We don't deallocate ``ol`` here because even though this completed - # immediately poll will still be notified about its completion and it - # will free ``ol``. - else: - let lastError = osLastError() - if lastError.int32 != ERROR_IO_PENDING: - # With ERROR_IO_PENDING ``ol`` will be deallocated in ``poll``, - # and the future will be completed/failed there, too. - GC_unref(ol) - retFuture.fail(newException(OSError, osErrorMsg(lastError))) -else: - proc doConnect(socket: AsyncFD, addrInfo: ptr AddrInfo): Future[void] = - let retFuture = newFuture[void]("doConnect") - result = retFuture - - proc cb(fd: AsyncFD): bool = - let ret = SocketHandle(fd).getSockOptInt( - cint(SOL_SOCKET), cint(SO_ERROR)) - if ret == 0: - # We have connected. - retFuture.complete() - return true - elif ret == EINTR: - # interrupted, keep waiting - return false - else: - retFuture.fail(newException(OSError, osErrorMsg(OSErrorCode(ret)))) - return true - - let ret = connect(socket.SocketHandle, - addrInfo.ai_addr, - addrInfo.ai_addrlen.Socklen) - if ret == 0: - # Request to connect completed immediately. - retFuture.complete() - else: - let lastError = osLastError() - if lastError.int32 == EINTR or lastError.int32 == EINPROGRESS: - addWrite(socket, cb) - else: - retFuture.fail(newException(OSError, osErrorMsg(lastError))) - -template asyncAddrInfoLoop(addrInfo: ptr AddrInfo, fd: untyped, - protocol: Protocol = IPPROTO_RAW) = - ## Iterates through the AddrInfo linked list asynchronously - ## until the connection can be established. - const shouldCreateFd = not declared(fd) - - when shouldCreateFd: - let sockType = protocol.toSockType() - - var fdPerDomain: array[low(Domain).ord..high(Domain).ord, AsyncFD] - for i in low(fdPerDomain)..high(fdPerDomain): - fdPerDomain[i] = osInvalidSocket.AsyncFD - template closeUnusedFds(domainToKeep = -1) {.dirty.} = - for i, fd in fdPerDomain: - if fd != osInvalidSocket.AsyncFD and i != domainToKeep: - fd.closeSocket() - - var lastException: ref Exception - var curAddrInfo = addrInfo - var domain: Domain - when shouldCreateFd: - var curFd: AsyncFD - else: - var curFd = fd - proc tryNextAddrInfo(fut: Future[void]) {.gcsafe.} = - if fut == nil or fut.failed: - if fut != nil: - lastException = fut.readError() - - while curAddrInfo != nil: - let domainOpt = curAddrInfo.ai_family.toKnownDomain() - if domainOpt.isSome: - domain = domainOpt.unsafeGet() - break - curAddrInfo = curAddrInfo.ai_next - - if curAddrInfo == nil: - freeAddrInfo(addrInfo) - when shouldCreateFd: - closeUnusedFds() - if lastException != nil: - retFuture.fail(lastException) - else: - retFuture.fail(newException( - IOError, "Couldn't resolve address: " & address)) - return - - when shouldCreateFd: - curFd = fdPerDomain[ord(domain)] - if curFd == osInvalidSocket.AsyncFD: - try: - curFd = newAsyncNativeSocket(domain, sockType, protocol) - except: - freeAddrInfo(addrInfo) - closeUnusedFds() - raise getCurrentException() - when defined(windows): - curFd.SocketHandle.bindToDomain(domain) - fdPerDomain[ord(domain)] = curFd - - doConnect(curFd, curAddrInfo).callback = tryNextAddrInfo - curAddrInfo = curAddrInfo.ai_next - else: - freeAddrInfo(addrInfo) - when shouldCreateFd: - closeUnusedFds(ord(domain)) - retFuture.complete(curFd) - else: - retFuture.complete() - - tryNextAddrInfo(nil) - -proc dial*(address: string, port: Port, - protocol: Protocol = IPPROTO_TCP): Future[AsyncFD] = - ## Establishes connection to the specified ``address``:``port`` pair via the - ## specified protocol. The procedure iterates through possible - ## resolutions of the ``address`` until it succeeds, meaning that it - ## seamlessly works with both IPv4 and IPv6. - ## Returns the async file descriptor, registered in the dispatcher of - ## the current thread, ready to send or receive data. - let retFuture = newFuture[AsyncFD]("dial") - result = retFuture - let sockType = protocol.toSockType() - - let aiList = getAddrInfo(address, port, Domain.AF_UNSPEC, sockType, protocol) - asyncAddrInfoLoop(aiList, noFD, protocol) - -proc connect*(socket: AsyncFD, address: string, port: Port, - domain = Domain.AF_INET): Future[void] = - let retFuture = newFuture[void]("connect") - result = retFuture - - when defined(windows): - verifyPresence(socket) - else: - assert getSockDomain(socket.SocketHandle) == domain - - let aiList = getAddrInfo(address, port, domain) - when defined(windows): - socket.SocketHandle.bindToDomain(domain) - asyncAddrInfoLoop(aiList, socket) diff --git a/lib/pure/includes/oserr.nim b/lib/pure/includes/oserr.nim index 72c3f4f49..abd0bf501 100644 --- a/lib/pure/includes/oserr.nim +++ b/lib/pure/includes/oserr.nim @@ -59,7 +59,8 @@ proc raiseOSError*(errorCode: OSErrorCode; additionalInfo = "") {.noinline.} = e.errorCode = errorCode.int32 e.msg = osErrorMsg(errorCode) if additionalInfo.len > 0: - e.msg.add "; Additional info: " + if e.msg[^1] != '\n': e.msg.add '\n' + e.msg.add "Additional info: " e.msg.addQuoted additionalInfo if e.msg == "": e.msg = "unknown OS error" diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index e5345e645..810223d72 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -36,11 +36,12 @@ type size*: int ## size of the memory mapped file when defined(windows): - fHandle: Handle - mapHandle: Handle - wasOpened: bool ## only close if wasOpened + fHandle*: Handle ## **Caution**: Windows specific public field to allow + ## even more low level trickery. + mapHandle*: Handle ## **Caution**: Windows specific public field. + wasOpened*: bool ## **Caution**: Windows specific public field. else: - handle: cint + handle*: cint ## **Caution**: Posix specific public field. proc mapMem*(m: var MemFile, mode: FileMode = fmRead, mappedSize = -1, offset = 0): pointer = @@ -281,6 +282,35 @@ proc flush*(f: var MemFile; attempts: Natural = 3) = if lastErr != EBUSY.OSErrorCode: raiseOSError(lastErr, "error flushing mapping") +when defined(posix) or defined(nimdoc): + proc resize*(f: var MemFile, newFileSize: int) {.raises: [IOError, OSError].} = + ## resize and re-map the file underlying an ``allowRemap MemFile``. + ## **Note**: this assumes the entire file is mapped read-write at offset zero. + ## Also, the value of ``.mem`` will probably change. + ## **Note**: This is not (yet) avaiable on Windows. + when defined(posix): + if f.handle == -1: + raise newException(IOError, + "Cannot resize MemFile opened with allowRemap=false") + if ftruncate(f.handle, newFileSize) == -1: + raiseOSError(osLastError()) + when defined(linux): #Maybe NetBSD, too? + #On Linux this can be over 100 times faster than a munmap,mmap cycle. + proc mremap(old: pointer; oldSize,newSize: csize; flags: cint): pointer {. + importc: "mremap", header: "<sys/mman.h>" .} + let newAddr = mremap(f.mem, csize(f.size), csize(newFileSize), cint(1)) + if newAddr == cast[pointer](MAP_FAILED): + raiseOSError(osLastError()) + else: + if munmap(f.mem, f.size) != 0: + raiseOSError(osLastError()) + let newAddr = mmap(nil, newFileSize, PROT_READ or PROT_WRITE, + MAP_SHARED or MAP_POPULATE, f.handle, 0) + if newAddr == cast[pointer](MAP_FAILED): + raiseOSError(osLastError()) + f.mem = newAddr + f.size = newFileSize + proc close*(f: var MemFile) = ## closes the memory mapped file `f`. All changes are written back to the ## file system, if `f` was opened with write access. diff --git a/lib/pure/options.nim b/lib/pure/options.nim index 12e38d8b5..b827e1aa3 100644 --- a/lib/pure/options.nim +++ b/lib/pure/options.nim @@ -39,17 +39,18 @@ ## ## .. code-block:: nim ## -## try: -## assert("abc".find('c').get() == 2) # Immediately extract the value -## except UnpackError: # If there is no value -## assert false # This will not be reached, because the value is present -## +## let found = "abc".find('c') +## assert found.isSome and found.get() == 2 +## ## The ``get`` operation demonstrated above returns the underlying value, or -## raises ``UnpackError`` if there is no value. There is another option for -## obtaining the value: ``unsafeGet``, but you must only use it when you are -## absolutely sure the value is present (e.g. after checking ``isSome``). If -## you do not care about the tiny overhead that ``get`` causes, you should -## simply never use ``unsafeGet``. +## raises ``UnpackError`` if there is no value. Note that ``UnpackError`` inherits +## from ``system.Defect``, and should therefore never be catched. Instead, rely on +## checking if the option contains a value with ``isSome`` and ``isNone``. +## +## There is another option for obtaining the value: ``unsafeGet``, but you must +## only use it when you are absolutely sure the value is present (e.g. after +## checking ``isSome``). If you do not care about the tiny overhead that ``get`` +## causes, you should simply never use ``unsafeGet``. ## ## How to deal with an absence of a value: ## @@ -61,12 +62,7 @@ ## assert(result == none(int)) ## # It has no value: ## assert(result.isNone) -## -## try: -## echo result.get() -## assert(false) # This will not be reached -## except UnpackError: # Because an exception is raised -## discard + import typetraits type @@ -81,7 +77,7 @@ type val: T has: bool - UnpackError* = ref object of ValueError + UnpackError* = object of Defect proc some*[T](val: T): Option[T] = ## Returns a ``Option`` that has this value. @@ -129,7 +125,7 @@ proc get*[T](self: Option[T]): T = ## Returns contents of the Option. If it is none, then an exception is ## thrown. if self.isNone: - raise UnpackError(msg: "Can't obtain a value from a `none`") + raise newException(UnpackError, "Can't obtain a value from a `none`") self.val proc get*[T](self: Option[T], otherwise: T): T = @@ -143,7 +139,7 @@ proc get*[T](self: var Option[T]): var T = ## Returns contents of the Option. If it is none, then an exception is ## thrown. if self.isNone: - raise UnpackError(msg: "Can't obtain a value from a `none`") + raise newException(UnpackError, "Can't obtain a value from a `none`") return self.val proc map*[T](self: Option[T], callback: proc (input: T)) = diff --git a/lib/pure/subexes.nim b/lib/pure/subexes.nim index d103af710..638e71f04 100644 --- a/lib/pure/subexes.nim +++ b/lib/pure/subexes.nim @@ -17,7 +17,7 @@ from strutils import parseInt, cmpIgnoreStyle, Digits include "system/inclrtl" - +import system/helpers2 proc findNormalized(x: string, inArray: openarray[string]): int = var i = 0 @@ -85,7 +85,7 @@ proc getFormatArg(p: var FormatParser, a: openArray[string]): int = result = parseInt(a[result])-1 else: raiseInvalidFormat("'#', '$', number or identifier expected") - if result >=% a.len: raiseInvalidFormat("index out of bounds: " & $result) + if result >=% a.len: raiseInvalidFormat(formatErrorIndexBound(result, a.len)) p.i = i proc scanDollar(p: var FormatParser, a: openarray[string], s: var string) {. diff --git a/lib/std/diff.nim b/lib/std/diff.nim new file mode 100644 index 000000000..bffce2803 --- /dev/null +++ b/lib/std/diff.nim @@ -0,0 +1,387 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2018 Nim contributors +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module implements an algorithm to compute the +## `diff`:idx: between two sequences of lines. + +# code owner: Arne Döring +# +# This is based on C# code written by Matthias Hertel, http://www.mathertel.de +# +# This Class implements the Difference Algorithm published in +# "An O(ND) Difference Algorithm and its Variations" by Eugene Myers +# Algorithmica Vol. 1 No. 2, 1986, p 251. + +import tables, strutils + +type + Item* = object ## An Item in the list of differences. + startA*: int ## Start Line number in Data A. + startB*: int ## Start Line number in Data B. + deletedA*: int ## Number of changes in Data A. + insertedB*: int ## Number of changes in Data B. + + DiffData = object ## Data on one input file being compared. + data: seq[int] ## Buffer of numbers that will be compared. + modified: seq[bool] ## Array of booleans that flag for modified + ## data. This is the result of the diff. + ## This means deletedA in the first Data or + ## inserted in the second Data. + + Smsrd = object + x, y: int + +# template to avoid a seq copy. Required until ``sink`` parameters are ready. +template newDiffData(initData: seq[int]; L: int): DiffData = + DiffData( + data: initData, + modified: newSeq[bool](L + 2) + ) + +proc len(d: DiffData): int {.inline.} = d.data.len + +proc diffCodes(aText: string; h: var Table[string, int]): DiffData = + ## This function converts all textlines of the text into unique numbers for every unique textline + ## so further work can work only with simple numbers. + ## ``aText`` the input text + ## ``h`` This extern initialized hashtable is used for storing all ever used textlines. + ## ``trimSpace`` ignore leading and trailing space characters + ## Returns a array of integers. + var lastUsedCode = h.len + result.data = newSeq[int]() + for s in aText.splitLines: + if h.contains s: + result.data.add h[s] + else: + inc lastUsedCode + h[s] = lastUsedCode + result.data.add lastUsedCode + result.modified = newSeq[bool](result.data.len + 2) + +proc optimize(data: var DiffData) = + ## If a sequence of modified lines starts with a line that contains the same content + ## as the line that appends the changes, the difference sequence is modified so that the + ## appended line and not the starting line is marked as modified. + ## This leads to more readable diff sequences when comparing text files. + var startPos = 0 + while startPos < data.len: + while startPos < data.len and not data.modified[startPos]: + inc startPos + var endPos = startPos + while endPos < data.len and data.modified[endPos]: + inc endPos + + if endPos < data.len and data.data[startPos] == data.data[endPos]: + data.modified[startPos] = false + data.modified[endPos] = true + else: + startPos = endPos + +proc sms(dataA: var DiffData; lowerA, upperA: int; dataB: DiffData; lowerB, upperB: int; + downVector, upVector: var openArray[int]): Smsrd = + ## This is the algorithm to find the Shortest Middle Snake (sms). + ## ``dataA`` sequence A + ## ``lowerA`` lower bound of the actual range in dataA + ## ``upperA`` upper bound of the actual range in dataA (exclusive) + ## ``dataB`` sequence B + ## ``lowerB`` lower bound of the actual range in dataB + ## ``upperB`` upper bound of the actual range in dataB (exclusive) + ## ``downVector`` a vector for the (0,0) to (x,y) search. Passed as a parameter for speed reasons. + ## ``upVector`` a vector for the (u,v) to (N,M) search. Passed as a parameter for speed reasons. + ## Returns a MiddleSnakeData record containing x,y and u,v. + + let max = dataA.len + dataB.len + 1 + + let downK = lowerA - lowerB # the k-line to start the forward search + let upK = upperA - upperB # the k-line to start the reverse search + + let delta = (upperA - lowerA) - (upperB - lowerB) + let oddDelta = (delta and 1) != 0 + + # The vectors in the publication accepts negative indexes. the vectors implemented here are 0-based + # and are access using a specific offset: upOffset upVector and downOffset for downVector + let downOffset = max - downK + let upOffset = max - upK + + let maxD = ((upperA - lowerA + upperB - lowerB) div 2) + 1 + + downVector[downOffset + downK + 1] = lowerA + upVector[upOffset + upK - 1] = upperA + + for D in 0 .. maxD: + # Extend the forward path. + for k in countUp(downK - D, downK + D, 2): + # find the only or better starting point + var x: int + if k == downK - D: + x = downVector[downOffset + k + 1] # down + else: + x = downVector[downOffset + k - 1] + 1 # a step to the right + if k < downK + D and downVector[downOffset + k + 1] >= x: + x = downVector[downOffset + k + 1] # down + + var y = x - k + + # find the end of the furthest reaching forward D-path in diagonal k. + while x < upperA and y < upperB and dataA.data[x] == dataB.data[y]: + inc x + inc y + + downVector[downOffset + k] = x + + # overlap ? + if oddDelta and upK - D < k and k < upK + D: + if upVector[upOffset + k] <= downVector[downOffset + k]: + return Smsrd(x: downVector[downOffset + k], + y: downVector[downOffset + k] - k) + + # Extend the reverse path. + for k in countUp(upK - D, upK + D, 2): + # find the only or better starting point + var x: int + if k == upK + D: + x = upVector[upOffset + k - 1] # up + else: + x = upVector[upOffset + k + 1] - 1 # left + if k > upK - D and upVector[upOffset + k - 1] < x: + x = upVector[upOffset + k - 1] # up + + var y = x - k + while x > lowerA and y > lowerB and dataA.data[x - 1] == dataB.data[y - 1]: + dec x + dec y + + upVector[upOffset + k] = x + + # overlap ? + if not oddDelta and downK-D <= k and k <= downK+D: + if upVector[upOffset + k] <= downVector[downOffset + k]: + return Smsrd(x: downVector[downOffset + k], + y: downVector[downOffset + k] - k) + + assert false, "the algorithm should never come here." + +proc lcs(dataA: var DiffData; lowerA, upperA: int; dataB: var DiffData; lowerB, upperB: int; + downVector, upVector: var openArray[int]) = + ## This is the divide-and-conquer implementation of the longes common-subsequence (lcs) + ## algorithm. + ## The published algorithm passes recursively parts of the A and B sequences. + ## To avoid copying these arrays the lower and upper bounds are passed while the sequences stay constant. + ## ``dataA`` sequence A + ## ``lowerA`` lower bound of the actual range in dataA + ## ``upperA`` upper bound of the actual range in dataA (exclusive) + ## ``dataB`` sequence B + ## ``lowerB`` lower bound of the actual range in dataB + ## ``upperB`` upper bound of the actual range in dataB (exclusive) + ## ``downVector`` a vector for the (0,0) to (x,y) search. Passed as a parameter for speed reasons. + ## ``upVector`` a vector for the (u,v) to (N,M) search. Passed as a parameter for speed reasons. + + # make mutable copy: + var lowerA = lowerA + var lowerB = lowerB + var upperA = upperA + var upperB = upperB + + # Fast walkthrough equal lines at the start + while lowerA < upperA and lowerB < upperB and dataA.data[lowerA] == dataB.data[lowerB]: + inc lowerA + inc lowerB + + # Fast walkthrough equal lines at the end + while lowerA < upperA and lowerB < upperB and dataA.data[upperA - 1] == dataB.data[upperB - 1]: + dec upperA + dec upperB + + if lowerA == upperA: + # mark as inserted lines. + while lowerB < upperB: + dataB.modified[lowerB] = true + inc lowerB + + elif lowerB == upperB: + # mark as deleted lines. + while lowerA < upperA: + dataA.modified[lowerA] = true + inc lowerA + + else: + # Find the middle snakea and length of an optimal path for A and B + let smsrd = sms(dataA, lowerA, upperA, dataB, lowerB, upperB, downVector, upVector) + # Debug.Write(2, "MiddleSnakeData", String.Format("{0},{1}", smsrd.x, smsrd.y)) + + # The path is from LowerX to (x,y) and (x,y) to UpperX + lcs(dataA, lowerA, smsrd.x, dataB, lowerB, smsrd.y, downVector, upVector) + lcs(dataA, smsrd.x, upperA, dataB, smsrd.y, upperB, downVector, upVector) # 2002.09.20: no need for 2 points + +proc createDiffs(dataA, dataB: DiffData): seq[Item] = + ## Scan the tables of which lines are inserted and deleted, + ## producing an edit script in forward order. + var startA = 0 + var startB = 0 + var lineA = 0 + var lineB = 0 + while lineA < dataA.len or lineB < dataB.len: + if lineA < dataA.len and not dataA.modified[lineA] and + lineB < dataB.len and not dataB.modified[lineB]: + # equal lines + inc lineA + inc lineB + else: + # maybe deleted and/or inserted lines + startA = lineA + startB = lineB + + while lineA < dataA.len and (lineB >= dataB.len or dataA.modified[lineA]): + inc lineA + + while lineB < dataB.len and (lineA >= dataA.len or dataB.modified[lineB]): + inc lineB + + if (startA < lineA) or (startB < lineB): + result.add Item(startA: startA, + startB: startB, + deletedA: lineA - startA, + insertedB: lineB - startB) + + +proc diffInt*(arrayA, arrayB: openArray[int]): seq[Item] = + ## Find the difference in 2 arrays of integers. + ## ``arrayA`` A-version of the numbers (usualy the old one) + ## ``arrayB`` B-version of the numbers (usualy the new one) + ## Returns a array of Items that describe the differences. + + # The A-Version of the data (original data) to be compared. + var dataA = newDiffData(@arrayA, arrayA.len) + + # The B-Version of the data (modified data) to be compared. + var dataB = newDiffData(@arrayB, arrayB.len) + + let max = dataA.len + dataB.len + 1 + ## vector for the (0,0) to (x,y) search + var downVector = newSeq[int](2 * max + 2) + ## vector for the (u,v) to (N,M) search + var upVector = newSeq[int](2 * max + 2) + + lcs(dataA, 0, dataA.len, dataB, 0, dataB.len, downVector, upVector) + result = createDiffs(dataA, dataB) + +proc diffText*(textA, textB: string): seq[Item] = + ## Find the difference in 2 text documents, comparing by textlines. + ## The algorithm itself is comparing 2 arrays of numbers so when comparing 2 text documents + ## each line is converted into a (hash) number. This hash-value is computed by storing all + ## textlines into a common hashtable so i can find dublicates in there, and generating a + ## new number each time a new textline is inserted. + ## ``TextA`` A-version of the text (usualy the old one) + ## ``TextB`` B-version of the text (usualy the new one) + ## ``trimSpace`` When set to true, all leading and trailing whitespace characters are stripped out before the comparation is done. + ## ``ignoreSpace`` When set to true, all whitespace characters are converted to a single space character before the comparation is done. + ## ``ignoreCase`` When set to true, all characters are converted to their lowercase equivivalence before the comparation is done. + ## Returns a seq of Items that describe the differences. + + # prepare the input-text and convert to comparable numbers. + var h = initTable[string, int]() # TextA.len + TextB.len <- probably wrong initial size + # The A-Version of the data (original data) to be compared. + var dataA = diffCodes(textA, h) + + # The B-Version of the data (modified data) to be compared. + var dataB = diffCodes(textB, h) + + h.clear # free up hashtable memory (maybe) + + let max = dataA.len + dataB.len + 1 + ## vector for the (0,0) to (x,y) search + var downVector = newSeq[int](2 * max + 2) + ## vector for the (u,v) to (N,M) search + var upVector = newSeq[int](2 * max + 2) + + lcs(dataA, 0, dataA.len, dataB, 0, dataB.len, downVector, upVector) + + optimize(dataA) + optimize(dataB) + result = createDiffs(dataA, dataB) + +when isMainModule: + + proc testHelper(f: seq[Item]): string = + for it in f: + result.add( + $it.deletedA & "." & $it.insertedB & "." & $it.startA & "." & $it.startB & "*" + ) + + proc main() = + var a, b: string + + stdout.writeLine("Diff Self Test...") + + # test all changes + a = "a,b,c,d,e,f,g,h,i,j,k,l".replace(',', '\n') + b = "0,1,2,3,4,5,6,7,8,9".replace(',', '\n') + assert(testHelper(diffText(a, b)) == + "12.10.0.0*", + "all-changes test failed.") + stdout.writeLine("all-changes test passed.") + # test all same + a = "a,b,c,d,e,f,g,h,i,j,k,l".replace(',', '\n') + b = a + assert(testHelper(diffText(a, b)) == + "", + "all-same test failed.") + stdout.writeLine("all-same test passed.") + + # test snake + a = "a,b,c,d,e,f".replace(',', '\n') + b = "b,c,d,e,f,x".replace(',', '\n') + assert(testHelper(diffText(a, b)) == + "1.0.0.0*0.1.6.5*", + "snake test failed.") + stdout.writeLine("snake test passed.") + + # 2002.09.20 - repro + a = "c1,a,c2,b,c,d,e,g,h,i,j,c3,k,l".replace(',', '\n') + b = "C1,a,C2,b,c,d,e,I1,e,g,h,i,j,C3,k,I2,l".replace(',', '\n') + assert(testHelper(diffText(a, b)) == + "1.1.0.0*1.1.2.2*0.2.7.7*1.1.11.13*0.1.13.15*", + "repro20020920 test failed.") + stdout.writeLine("repro20020920 test passed.") + + # 2003.02.07 - repro + a = "F".replace(',', '\n') + b = "0,F,1,2,3,4,5,6,7".replace(',', '\n') + assert(testHelper(diffText(a, b)) == + "0.1.0.0*0.7.1.2*", + "repro20030207 test failed.") + stdout.writeLine("repro20030207 test passed.") + + # Muegel - repro + a = "HELLO\nWORLD" + b = "\n\nhello\n\n\n\nworld\n" + assert(testHelper(diffText(a, b)) == + "2.8.0.0*", + "repro20030409 test failed.") + stdout.writeLine("repro20030409 test passed.") + + # test some differences + a = "a,b,-,c,d,e,f,f".replace(',', '\n') + b = "a,b,x,c,e,f".replace(',', '\n') + assert(testHelper(diffText(a, b)) == + "1.1.2.2*1.0.4.4*1.0.7.6*", + "some-changes test failed.") + stdout.writeLine("some-changes test passed.") + + # test one change within long chain of repeats + a = "a,a,a,a,a,a,a,a,a,a".replace(',', '\n') + b = "a,a,a,a,-,a,a,a,a,a".replace(',', '\n') + assert(testHelper(diffText(a, b)) == + "0.1.4.4*1.0.9.10*", + "long chain of repeats test failed.") + + stdout.writeLine("End.") + stdout.flushFile + + main() diff --git a/lib/system/chcks.nim b/lib/system/chcks.nim index d3651f659..6f4e8ce37 100644 --- a/lib/system/chcks.nim +++ b/lib/system/chcks.nim @@ -8,6 +8,7 @@ # # Implementation of some runtime checks. +import system/helpers2 proc raiseRangeError(val: BiggestInt) {.compilerproc, noinline.} = when hostOS == "standalone": @@ -15,6 +16,12 @@ proc raiseRangeError(val: BiggestInt) {.compilerproc, noinline.} = else: sysFatal(RangeError, "value out of range: ", $val) +proc raiseIndexError3(i, a, b: int) {.compilerproc, noinline.} = + sysFatal(IndexError, formatErrorIndexBound(i, a, b)) + +proc raiseIndexError2(i, n: int) {.compilerproc, noinline.} = + sysFatal(IndexError, formatErrorIndexBound(i, n)) + proc raiseIndexError() {.compilerproc, noinline.} = sysFatal(IndexError, "index out of bounds") @@ -25,7 +32,7 @@ proc chckIndx(i, a, b: int): int = if i >= a and i <= b: return i else: - raiseIndexError() + raiseIndexError3(i, a, b) proc chckRange(i, a, b: int): int = if i >= a and i <= b: diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index a6da8f5a3..84a1da343 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -454,16 +454,21 @@ when not defined(gcDestructors): shallowCopy(result, e.trace) when defined(nimRequiresNimFrame): - proc stackOverflow() {.noinline.} = + const nimCallDepthLimit {.intdefine.} = 2000 + + proc callDepthLimitReached() {.noinline.} = writeStackTrace() - showErrorMessage("Stack overflow\n") + showErrorMessage("Error: call depth limit reached in a debug build (" & + $nimCallDepthLimit & " function calls). You can change it with " & + "-d:nimCallDepthLimit=<int> but really try to avoid deep " & + "recursions instead.\n") quitOrDebug() proc nimFrame(s: PFrame) {.compilerRtl, inl, exportc: "nimFrame".} = s.calldepth = if framePtr == nil: 0 else: framePtr.calldepth+1 s.prev = framePtr framePtr = s - if s.calldepth == 2000: stackOverflow() + if s.calldepth == nimCallDepthLimit: callDepthLimitReached() else: proc pushFrame(s: PFrame) {.compilerRtl, inl, exportc: "nimFrame".} = # XXX only for backwards compatibility diff --git a/lib/system/helpers2.nim b/lib/system/helpers2.nim new file mode 100644 index 000000000..1c9e7c068 --- /dev/null +++ b/lib/system/helpers2.nim @@ -0,0 +1,5 @@ +template formatErrorIndexBound*[T](i, a, b: T): string = + "index out of bounds: (a:" & $a & ") <= (i:" & $i & ") <= (b:" & $b & ") " + +template formatErrorIndexBound*[T](i, n: T): string = + "index out of bounds: (i:" & $i & ") <= (n:" & $n & ") " diff --git a/testament/backend.nim b/testament/backend.nim index 385f1171c..c2658d6a0 100644 --- a/testament/backend.nim +++ b/testament/backend.nim @@ -20,14 +20,11 @@ var thisCommit: CommitId thisBranch: string -{.experimental.} -proc `()`(cmd: string{lit}): string = cmd.execProcess.string.strip - proc getMachine*(): MachineId = - var name = "hostname"() + var name = execProcess("hostname").string.strip if name.len == 0: - name = when defined(posix): getenv"HOSTNAME".string - else: getenv"COMPUTERNAME".string + name = when defined(posix): getenv("HOSTNAME").string + else: getenv("COMPUTERNAME").string if name.len == 0: quit "cannot determine the machine name" @@ -35,8 +32,8 @@ proc getMachine*(): MachineId = proc getCommit(): CommitId = const commLen = "commit ".len - let hash = "git log -n 1"()[commLen..commLen+10] - thisBranch = "git symbolic-ref --short HEAD"() + let hash = execProcess("git log -n 1").string.strip[commLen..commLen+10] + thisBranch = execProcess("git symbolic-ref --short HEAD").string.strip if hash.len == 0 or thisBranch.len == 0: quit "cannot determine git HEAD" result = CommitId(hash) @@ -45,8 +42,7 @@ var currentCategory: string entries: int -proc writeTestResult*(name, category, target, - action, result, expected, given: string) = +proc writeTestResult*(name, category, target, action, result, expected, given: string) = createDir("testresults") if currentCategory != category: if currentCategory.len > 0: diff --git a/testament/categories.nim b/testament/categories.nim index e1f173c26..a72602217 100644 --- a/testament/categories.nim +++ b/testament/categories.nim @@ -10,6 +10,36 @@ ## Include for the tester that contains test suites that test special features ## of the compiler. +const + specialCategories = [ + "assert", + "async", + "debugger", + "dll", + "examples", + "flags", + "gc", + "io", + "js", + "lib", + "longgc", + "manyloc", + "nimble-all", + "nimble-core", + "nimble-extra", + "niminaction", + "rodfiles", + "threads", + "untestable", + "stdlib", + "testdata", + "nimcache", + "coroutines", + "osproc", + "shouldfail", + "dir with space" + ] + # included from tester.nim # ---------------- ROD file tests --------------------------------------------- @@ -27,7 +57,7 @@ proc delNimCache(filename, options: string) = proc runRodFiles(r: var TResults, cat: Category, options: string) = template test(filename: string, clearCacheFirst=false) = if clearCacheFirst: delNimCache(filename, options) - testSpec r, makeTest(rodfilesDir / filename, options, cat, actionRun) + testSpec r, makeTest(rodfilesDir / filename, options, cat) # test basic recompilation scheme: @@ -97,10 +127,12 @@ proc runBasicDLLTest(c, r: var TResults, cat: Category, options: string) = else: "" - testNoSpec c, makeTest("lib/nimrtl.nim", - options & " --app:lib -d:createNimRtl --threads:on", cat, actionCompile) - testNoSpec c, makeTest("tests/dll/server.nim", - options & " --app:lib -d:useNimRtl --threads:on" & rpath, cat, actionCompile) + var test1 = makeTest("lib/nimrtl.nim", options & " --app:lib -d:createNimRtl --threads:on", cat) + test1.spec.action = actionCompile + testSpec c, test1 + var test2 = makeTest("tests/dll/server.nim", options & " --app:lib -d:useNimRtl --threads:on" & rpath, cat) + test2.spec.action = actionCompile + testSpec c, test2 when defined(Windows): # windows looks in the dir of the exe (yay!): @@ -120,7 +152,7 @@ proc runBasicDLLTest(c, r: var TResults, cat: Category, options: string) = safeCopyFile("lib" / nimrtlDll, "tests/dll" / nimrtlDll) testSpec r, makeTest("tests/dll/client.nim", options & " -d:useNimRtl --threads:on" & rpath, - cat, actionRun) + cat) proc dllTests(r: var TResults, cat: Category, options: string) = # dummy compile result: @@ -138,32 +170,32 @@ proc dllTests(r: var TResults, cat: Category, options: string) = proc gcTests(r: var TResults, cat: Category, options: string) = template testWithNone(filename: untyped) = testSpec r, makeTest("tests/gc" / filename, options & - " --gc:none", cat, actionRun) + " --gc:none", cat) testSpec r, makeTest("tests/gc" / filename, options & - " -d:release --gc:none", cat, actionRun) + " -d:release --gc:none", cat) template testWithoutMs(filename: untyped) = - testSpec r, makeTest("tests/gc" / filename, options, cat, actionRun) + testSpec r, makeTest("tests/gc" / filename, options, cat) testSpec r, makeTest("tests/gc" / filename, options & - " -d:release", cat, actionRun) + " -d:release", cat) testSpec r, makeTest("tests/gc" / filename, options & - " -d:release -d:useRealtimeGC", cat, actionRun) + " -d:release -d:useRealtimeGC", cat) template testWithoutBoehm(filename: untyped) = testWithoutMs filename testSpec r, makeTest("tests/gc" / filename, options & - " --gc:markAndSweep", cat, actionRun) + " --gc:markAndSweep", cat) testSpec r, makeTest("tests/gc" / filename, options & - " -d:release --gc:markAndSweep", cat, actionRun) + " -d:release --gc:markAndSweep", cat) template test(filename: untyped) = testWithoutBoehm filename when not defined(windows) and not defined(android): # AR: cannot find any boehm.dll on the net, right now, so disabled # for windows: testSpec r, makeTest("tests/gc" / filename, options & - " --gc:boehm", cat, actionRun) + " --gc:boehm", cat) testSpec r, makeTest("tests/gc" / filename, options & - " -d:release --gc:boehm", cat, actionRun) + " -d:release --gc:boehm", cat) testWithoutBoehm "foreign_thr" test "gcemscripten" @@ -196,17 +228,18 @@ proc longGCTests(r: var TResults, cat: Category, options: string) = var c = initResults() # According to ioTests, this should compile the file - testNoSpec c, makeTest("tests/realtimeGC/shared", options, cat, actionCompile) - testC r, makeTest("tests/realtimeGC/cmain", cOptions, cat, actionRun) - testSpec r, makeTest("tests/realtimeGC/nmain", options & "--threads: on", cat, actionRun) + testSpec c, makeTest("tests/realtimeGC/shared", options, cat) + # ^- why is this not appended to r? Should this be discarded? + testC r, makeTest("tests/realtimeGC/cmain", cOptions, cat), actionRun + testSpec r, makeTest("tests/realtimeGC/nmain", options & "--threads: on", cat) # ------------------------- threading tests ----------------------------------- proc threadTests(r: var TResults, cat: Category, options: string) = template test(filename: untyped) = - testSpec r, makeTest(filename, options, cat, actionRun) - testSpec r, makeTest(filename, options & " -d:release", cat, actionRun) - testSpec r, makeTest(filename, options & " --tlsEmulation:on", cat, actionRun) + testSpec r, makeTest(filename, options, cat) + testSpec r, makeTest(filename, options & " -d:release", cat) + testSpec r, makeTest(filename, options & " --tlsEmulation:on", cat) for t in os.walkFiles("tests/threads/t*.nim"): test(t) @@ -229,16 +262,16 @@ proc asyncTests(r: var TResults, cat: Category, options: string) = # ------------------------- debugger tests ------------------------------------ proc debuggerTests(r: var TResults, cat: Category, options: string) = - testNoSpec r, makeTest("tools/nimgrep", options & " --debugger:on", cat) + var t = makeTest("tools/nimgrep", options & " --debugger:on", cat) + t.spec.action = actionCompile + testSpec r, t # ------------------------- JS tests ------------------------------------------ proc jsTests(r: var TResults, cat: Category, options: string) = template test(filename: untyped) = - testSpec r, makeTest(filename, options & " -d:nodejs", cat, - actionRun), targetJS - testSpec r, makeTest(filename, options & " -d:nodejs -d:release", cat, - actionRun), targetJS + testSpec r, makeTest(filename, options & " -d:nodejs", cat), {targetJS} + testSpec r, makeTest(filename, options & " -d:nodejs -d:release", cat), {targetJS} for t in os.walkFiles("tests/js/t*.nim"): test(t) @@ -259,14 +292,14 @@ proc jsTests(r: var TResults, cat: Category, options: string) = proc testNimInAction(r: var TResults, cat: Category, options: string) = let options = options & " --nilseqs:on" - template test(filename: untyped, action: untyped) = - testSpec r, makeTest(filename, options, cat, action) + template test(filename: untyped) = + testSpec r, makeTest(filename, options, cat) template testJS(filename: untyped) = - testSpec r, makeTest(filename, options, cat, actionCompile), targetJS + testSpec r, makeTest(filename, options, cat), {targetJS} template testCPP(filename: untyped) = - testSpec r, makeTest(filename, options, cat, actionCompile), targetCPP + testSpec r, makeTest(filename, options, cat), {targetCPP} let tests = [ "niminaction/Chapter1/various1", @@ -298,39 +331,43 @@ proc testNimInAction(r: var TResults, cat: Category, options: string) = # edit when making a conscious breaking change, also please try to make your # commit message clear and notify me so I can easily compile an errata later. const refHashes = @[ - "51afdfa84b3ca3d810809d6c4e5037ba", "30f07e4cd5eaec981f67868d4e91cfcf", - "d14e7c032de36d219c9548066a97e846", "2e40bfd5daadb268268727da91bb4e81", - "c5d3853ed0aba04bf6d35ba28a98dca0", "058603145ff92d46c009006b06e5b228", - "7b94a029b94ddb7efafddd546c965ff6", "586d74514394e49f2370dfc01dd9e830", - "13febc363ed82585f2a60de40ddfefda", "c11a013db35e798f44077bc0763cc86d", - "3e32e2c5e9a24bd13375e1cd0467079c", "0b9fe7ba159623d49ae60db18a15037c", - "b2dd5293d7f784824bbf9792c6fb51ad", "4c19d8d9026bfe151b31d7007fa3c237", - "9415c6a568cfceed08da8378e95b5cd5", "da520038c153f4054cb8cc5faa617714", - "e6c6e061b6f77b2475db6fec7abfb7f4", "9a8fe78c588d08018843b64b57409a02", - "8b5d28e985c0542163927d253a3e4fc9", "783299b98179cc725f9c46b5e3b5381f", - "bc523f9a9921299090bac1af6c958e73", "80f9c3e594a798225046e8a42e990daf" + "51afdfa84b3ca3d810809d6c4e5037ba", + "30f07e4cd5eaec981f67868d4e91cfcf", + "d14e7c032de36d219c9548066a97e846", + "b335635562ff26ec0301bdd86356ac0c", + "6c4add749fbf50860e2f523f548e6b0e", + "76de5833a7cc46f96b006ce51179aeb1", + "705eff79844e219b47366bd431658961", + "a1e87b881c5eb161553d119be8b52f64", + "2d706a6ec68d2973ec7e733e6d5dce50", + "c11a013db35e798f44077bc0763cc86d", + "3e32e2c5e9a24bd13375e1cd0467079c", + "a5452722b2841f0c1db030cf17708955", + "dc6c45eb59f8814aaaf7aabdb8962294", + "69d208d281a2e7bffd3eaf4bab2309b1", + "ec05666cfb60211bedc5e81d4c1caf3d", + "da520038c153f4054cb8cc5faa617714", + "59906c8cd819cae67476baa90a36b8c1", + "9a8fe78c588d08018843b64b57409a02", + "8b5d28e985c0542163927d253a3e4fc9", + "783299b98179cc725f9c46b5e3b5381f", + "1a2b3fba1187c68d6a9bfa66854f3318", + "80f9c3e594a798225046e8a42e990daf" ] for i, test in tests: let filename = "tests" / test.addFileExt("nim") let testHash = getMD5(readFile(filename).string) doAssert testHash == refHashes[i], "Nim in Action test " & filename & " was changed." - # Run the tests. for testfile in tests: - test "tests/" & testfile & ".nim", actionCompile - + test "tests/" & testfile & ".nim" let jsFile = "tests/niminaction/Chapter8/canvas/canvas_test.nim" testJS jsFile - let cppFile = "tests/niminaction/Chapter8/sfml/sfml_test.nim" testCPP cppFile - # ------------------------- manyloc ------------------------------------------- -#proc runSpecialTests(r: var TResults, options: string) = -# for t in ["lib/packages/docutils/highlite"]: -# testSpec(r, t, options) proc findMainFile(dir: string): string = # finds the file belonging to ".nim.cfg"; if there is no such file @@ -354,27 +391,32 @@ proc manyLoc(r: var TResults, cat: Category, options: string) = if dir.endsWith"named_argument_bug": continue let mainfile = findMainFile(dir) if mainfile != "": - testNoSpec r, makeTest(mainfile, options, cat) + var test = makeTest(mainfile, options, cat) + test.spec.action = actionCompile + testSpec r, test proc compileExample(r: var TResults, pattern, options: string, cat: Category) = for test in os.walkFiles(pattern): - testNoSpec r, makeTest(test, options, cat) + var test = makeTest(test, options, cat) + test.spec.action = actionCompile + testSpec r, test proc testStdlib(r: var TResults, pattern, options: string, cat: Category) = - for test in os.walkFiles(pattern): - let name = extractFilename(test) + for testFile in os.walkFiles(pattern): + let name = extractFilename(testFile) if name notin disabledFiles: - let contents = readFile(test).string - if contents.contains("when isMainModule"): - testSpec r, makeTest(test, options, cat, actionRunNoSpec) - else: - testNoSpec r, makeTest(test, options, cat, actionCompile) + let contents = readFile(testFile).string + var testObj = makeTest(testFile, options, cat) + if "when isMainModule" notin contents: + testObj.spec.action = actionCompile + testSpec r, testObj # ----------------------------- nimble ---------------------------------------- -type PackageFilter = enum - pfCoreOnly - pfExtraOnly - pfAll +type + PackageFilter = enum + pfCoreOnly + pfExtraOnly + pfAll var nimbleDir = getEnv("NIMBLE_DIR").string if nimbleDir.len == 0: nimbleDir = getHomeDir() / ".nimble" @@ -404,7 +446,6 @@ proc getPackageDir(package: string): string = iterator listPackages(filter: PackageFilter): tuple[name, url: string] = let packageList = parseFile(packageIndex) - for package in packageList.items(): let name = package["name"].str @@ -458,24 +499,99 @@ proc testNimblePackages(r: var TResults, cat: Category, filter: PackageFilter) = # ---------------------------------------------------------------------------- -const AdditionalCategories = ["debugger", "examples", "lib"] +const AdditionalCategories = ["debugger", "examples", "lib", "megatest"] proc `&.?`(a, b: string): string = # candidate for the stdlib? result = if b.startswith(a): b else: a & b -#proc `&?.`(a, b: string): string = # not used - # candidate for the stdlib? - #result = if a.endswith(b): a else: a & b - proc processSingleTest(r: var TResults, cat: Category, options, test: string) = let test = "tests" & DirSep &.? cat.string / test let target = if cat.string.normalize == "js": targetJS else: targetC + if existsFile(test): + testSpec r, makeTest(test, options, cat), {target} + else: + echo "[Warning] - ", test, " test does not exist" + +proc isJoinableSpec(spec: TSpec): bool = + result = not spec.sortoutput and + spec.action == actionRun and + not fileExists(spec.file.changeFileExt("cfg")) and + not fileExists(parentDir(spec.file) / "nim.cfg") and + spec.cmd.len == 0 and + spec.err != reDisabled and + not spec.unjoinable and + spec.exitCode == 0 and + spec.input.len == 0 and + spec.nimout.len == 0 and + spec.outputCheck != ocSubstr and + spec.ccodeCheck.len == 0 and + (spec.targets == {} or spec.targets == {targetC}) + +proc norm(s: var string) = + while true: + let tmp = s.replace("\n\n", "\n") + if tmp == s: break + s = tmp + s = s.strip + +proc runJoinedTest(r: var TResults, cat: Category, testsDir: string) = + ## returs a list of tests that have problems + var specs: seq[TSpec] = @[] + + for kind, dir in walkDir(testsDir): + assert testsDir.startsWith(testsDir) + let cat = dir[testsDir.len .. ^1] + if kind == pcDir and cat notin specialCategories: + for file in os.walkFiles(testsDir / cat / "t*.nim"): + let spec = parseSpec(file) + if isJoinableSpec(spec): + specs.add spec + + echo "joinable specs: ", specs.len + + var megatest: string + for runSpec in specs: + megatest.add "import r\"" + megatest.add runSpec.file + megatest.add "\"\n" + + writeFile("megatest.nim", megatest) + + const args = ["c", "-d:testing", "--listCmd", "megatest.nim"] + var (buf, exitCode) = execCmdEx2(command = "nim", args = args, options = {poStdErrToStdOut, poUsePath}, input = "") + if exitCode != 0: + echo buf + quit("megatest compilation failed") + + (buf, exitCode) = execCmdEx("./megatest") + if exitCode != 0: + echo buf + quit("megatest execution failed") + + norm buf + writeFile("outputGotten.txt", buf) + var outputExpected = "" + for i, runSpec in specs: + outputExpected.add runSpec.output.strip + outputExpected.add '\n' + norm outputExpected + + if buf != outputExpected: + writeFile("outputExpected.txt", outputExpected) + discard execShellCmd("diff -uNdr outputExpected.txt outputGotten.txt") + echo "output different!" + quit 1 + else: + echo "output OK" + removeFile("outputGotten.txt") + removeFile("megatest.nim") + #testSpec r, makeTest("megatest", options, cat) - if existsFile(test): testSpec r, makeTest(test, options, cat), target - else: echo "[Warning] - ", test, " test does not exist" +# --------------------------------------------------------------------------- -proc processCategory(r: var TResults, cat: Category, options: string) = +proc processCategory(r: var TResults, cat: Category, options, testsDir: string, + runJoinableTests: bool) = case cat.string.normalize of "rodfiles": when false: @@ -524,10 +640,17 @@ proc processCategory(r: var TResults, cat: Category, options: string) = of "untestable": # We can't test it because it depends on a third party. discard # TODO: Move untestable tests to someplace else, i.e. nimble repo. + of "megatest": + runJoinedTest(r, cat, testsDir) else: var testsRun = 0 for name in os.walkFiles("tests" & DirSep &.? cat.string / "t*.nim"): - testSpec r, makeTest(name, options, cat) + var test = makeTest(name, options, cat) + if runJoinableTests or not isJoinableSpec(test.spec) or cat.string in specialCategories: + discard "run the test" + else: + test.spec.err = reJoined + testSpec r, test inc testsRun if testsRun == 0: echo "[Warning] - Invalid category specified \"", cat.string, "\", no tests were run" diff --git a/testament/specs.nim b/testament/specs.nim index 86fc8bed4..df12db543 100644 --- a/testament/specs.nim +++ b/testament/specs.nim @@ -9,21 +9,21 @@ import parseutils, strutils, os, osproc, streams, parsecfg - var compilerPrefix* = "compiler" / "nim" let isTravis* = existsEnv("TRAVIS") let isAppVeyor* = existsEnv("APPVEYOR") -proc cmdTemplate*(): string = - compilerPrefix & " $target --hints:on -d:testing --nimblePath:tests/deps $options $file" - type TTestAction* = enum actionRun = "run" actionCompile = "compile" actionReject = "reject" - actionRunNoSpec = "runNoSpec" + + TOutputCheck* = enum + ocIgnore = "ignore" + ocEqual = "equal" + ocSubstr = "substr" TResultEnum* = enum reNimcCrash, # nim compiler seems to have crashed @@ -38,8 +38,10 @@ type reExeNotFound, reInstallFailed # package installation failed reBuildFailed # package building failed - reIgnored, # test is ignored + reDisabled, # test is disabled + reJoined, # test is disabled because it was joined into the megatest reSuccess # test was successful + reInvalidSpec # test had problems to parse the spec TTarget* = enum targetC = "C" @@ -51,7 +53,9 @@ type action*: TTestAction file*, cmd*: string input*: string - outp*: string + outputCheck*: TOutputCheck + sortoutput*: bool + output*: string line*, column*: int tfile*: string tline*, tcolumn*: int @@ -60,9 +64,16 @@ type ccodeCheck*: string maxCodeSize*: int err*: TResultEnum - substr*, sortoutput*: bool targets*: set[TTarget] nimout*: string + parseErrors*: string # when the spec definition is invalid, this is not empty. + unjoinable*: bool + +proc getCmd*(s: TSpec): string = + if s.cmd.len == 0: + result = compilerPrefix & " $target --hints:on -d:testing --nimblePath:tests/deps $options $file" + else: + result = s.cmd const targetToExt*: array[TTarget, string] = ["c", "cpp", "m", "js"] @@ -91,33 +102,6 @@ proc extractSpec(filename: string): string = when not defined(nimhygiene): {.pragma: inject.} -template parseSpecAux(fillResult: untyped) = - var ss = newStringStream(extractSpec(filename)) - var p {.inject.}: CfgParser - open(p, ss, filename, 1) - while true: - var e {.inject.} = next(p) - case e.kind - of cfgEof: break - of cfgSectionStart, cfgOption, cfgError: - echo ignoreMsg(p, e) - of cfgKeyValuePair: - fillResult - close(p) - -proc specDefaults*(result: var TSpec) = - result.msg = "" - result.outp = "" - result.nimout = "" - result.ccodeCheck = "" - result.cmd = cmdTemplate() - result.line = 0 - result.column = 0 - result.tfile = "" - result.tline = 0 - result.tcolumn = 0 - result.maxCodeSize = 0 - proc parseTargets*(value: string): set[TTarget] = for v in value.normalize.splitWhitespace: case v @@ -127,81 +111,134 @@ proc parseTargets*(value: string): set[TTarget] = of "js": result.incl(targetJS) else: echo "target ignored: " & v +proc addLine*(self: var string; a: string) = + self.add a + self.add "\n" + +proc addLine*(self: var string; a,b: string) = + self.add a + self.add b + self.add "\n" + proc parseSpec*(filename: string): TSpec = - specDefaults(result) result.file = filename - parseSpecAux: - case normalize(e.key) - of "action": - case e.value.normalize - of "compile": result.action = actionCompile - of "run": result.action = actionRun - of "reject": result.action = actionReject - else: echo ignoreMsg(p, e) - of "file": result.file = e.value - of "line": discard parseInt(e.value, result.line) - of "column": discard parseInt(e.value, result.column) - of "tfile": result.tfile = e.value - of "tline": discard parseInt(e.value, result.tline) - of "tcolumn": discard parseInt(e.value, result.tcolumn) - of "output": - result.action = actionRun - result.outp = e.value - of "input": - result.input = e.value - of "outputsub": - result.action = actionRun - result.outp = e.value - result.substr = true - of "sortoutput": - result.sortoutput = parseCfgBool(e.value) - of "exitcode": - discard parseInt(e.value, result.exitCode) - result.action = actionRun - of "msg": - result.msg = e.value - if result.action != actionRun: - result.action = actionCompile - of "errormsg", "errmsg": - result.msg = e.value - result.action = actionReject - of "nimout": - result.nimout = e.value - of "disabled": - case e.value.normalize - of "y", "yes", "true", "1", "on": result.err = reIgnored - of "n", "no", "false", "0", "off": discard - of "win", "windows": - when defined(windows): result.err = reIgnored - of "linux": - when defined(linux): result.err = reIgnored - of "bsd": - when defined(bsd): result.err = reIgnored - of "macosx": - when defined(macosx): result.err = reIgnored - of "unix": - when defined(unix): result.err = reIgnored - of "posix": - when defined(posix): result.err = reIgnored - of "travis": - if isTravis: result.err = reIgnored - of "appveyor": - if isAppVeyor: result.err = reIgnored - else: - raise newException(ValueError, "cannot interpret as a bool: " & e.value) - of "cmd": - if e.value.startsWith("nim "): - result.cmd = compilerPrefix & e.value[3..^1] + let specStr = extractSpec(filename) + var ss = newStringStream(specStr) + var p: CfgParser + open(p, ss, filename, 1) + while true: + var e = next(p) + case e.kind + of cfgKeyValuePair: + case normalize(e.key) + of "action": + case e.value.normalize + of "compile": + result.action = actionCompile + of "run": + result.action = actionRun + of "reject": + result.action = actionReject + else: + result.parseErrors.addLine "cannot interpret as action: ", e.value + of "file": + if result.msg.len == 0 and result.nimout.len == 0: + result.parseErrors.addLine "errormsg or msg needs to be specified before file" + result.file = e.value + of "line": + if result.msg.len == 0 and result.nimout.len == 0: + result.parseErrors.addLine "errormsg, msg or nimout needs to be specified before line" + discard parseInt(e.value, result.line) + of "column": + if result.msg.len == 0 and result.nimout.len == 0: + result.parseErrors.addLine "errormsg or msg needs to be specified before column" + discard parseInt(e.value, result.column) + of "tfile": + result.tfile = e.value + of "tline": + discard parseInt(e.value, result.tline) + of "tcolumn": + discard parseInt(e.value, result.tcolumn) + of "output": + result.outputCheck = ocEqual + result.output = strip(e.value) + of "input": + result.input = e.value + of "outputsub": + result.outputCheck = ocSubstr + result.output = strip(e.value) + of "sortoutput": + try: + result.sortoutput = parseCfgBool(e.value) + except: + result.parseErrors.addLine getCurrentExceptionMsg() + of "exitcode": + discard parseInt(e.value, result.exitCode) + result.action = actionRun + of "msg": + result.msg = e.value + if result.action != actionRun: + result.action = actionCompile + of "errormsg", "errmsg": + result.msg = e.value + result.action = actionReject + of "nimout": + result.nimout = e.value + of "joinable": + result.unjoinable = not parseCfgBool(e.value) + of "disabled": + case e.value.normalize + of "y", "yes", "true", "1", "on": result.err = reDisabled + of "n", "no", "false", "0", "off": discard + of "win", "windows": + when defined(windows): result.err = reDisabled + of "linux": + when defined(linux): result.err = reDisabled + of "bsd": + when defined(bsd): result.err = reDisabled + of "macosx": + when defined(macosx): result.err = reDisabled + of "unix": + when defined(unix): result.err = reDisabled + of "posix": + when defined(posix): result.err = reDisabled + of "travis": + if isTravis: result.err = reDisabled + of "appveyor": + if isAppVeyor: result.err = reDisabled + else: + result.parseErrors.addLine "cannot interpret as a bool: ", e.value + of "cmd": + if e.value.startsWith("nim "): + result.cmd = compilerPrefix & e.value[3..^1] + else: + result.cmd = e.value + of "ccodecheck": + result.ccodeCheck = e.value + of "maxcodesize": + discard parseInt(e.value, result.maxCodeSize) + of "target", "targets": + for v in e.value.normalize.splitWhitespace: + case v + of "c": + result.targets.incl(targetC) + of "cpp", "c++": + result.targets.incl(targetCpp) + of "objc": + result.targets.incl(targetObjC) + of "js": + result.targets.incl(targetJS) + else: + result.parseErrors.addLine "cannot interpret as a target: ", e.value else: - result.cmd = e.value - of "ccodecheck": result.ccodeCheck = e.value - of "maxcodesize": discard parseInt(e.value, result.maxCodeSize) - of "target", "targets": - for v in e.value.normalize.splitWhitespace: - case v - of "c": result.targets.incl(targetC) - of "cpp", "c++": result.targets.incl(targetCpp) - of "objc": result.targets.incl(targetObjC) - of "js": result.targets.incl(targetJS) - else: echo ignoreMsg(p, e) - else: echo ignoreMsg(p, e) + result.parseErrors.addLine "invalid key for test spec: ", e.key + + of cfgSectionStart: + result.parseErrors.addLine "section ignored: ", e.section + of cfgOption: + result.parseErrors.addLine "command ignored: ", e.key & ": " & e.value + of cfgError: + result.parseErrors.addLine e.msg + of cfgEof: + break + close(p) diff --git a/testament/tester.nim b/testament/tester.nim index 59c0171b4..6d9e05aa9 100644 --- a/testament/tester.nim +++ b/testament/tester.nim @@ -15,6 +15,7 @@ import algorithm, compiler/nodejs, times, sets, md5 var useColors = true +var backendLogging = true const resultsFile = "testresults.html" @@ -27,6 +28,7 @@ Command: c|cat|category <category> run all the tests of a certain category r|run <test> run single test file html generate $1 from the database + stats generate statistics about test cases Arguments: arguments are passed to the compiler Options: @@ -35,7 +37,8 @@ Options: --targets:"c c++ js objc" run tests for specified targets (default: all) --nim:path use a particular nim executable (default: compiler/nim) --directory:dir Change to directory dir before reading the tests or doing anything else. - --colors:on|off turn messagescoloring on|off + --colors:on|off Turn messagescoloring on|off. + --backendLogging:on|off Disable or enable backend logging. By default turned on. """ % resultsFile type @@ -48,7 +51,7 @@ type name: string cat: Category options: string - action: TTestAction + spec: TSpec startTime: float # ---------------------------------------------------------------------------- @@ -113,7 +116,7 @@ proc nimcacheDir(filename, options: string, target: TTarget): string = proc callCompiler(cmdTemplate, filename, options: string, target: TTarget, extraOptions=""): TSpec = let nimcache = nimcacheDir(filename, options, target) - let options = options & " " & ("--nimCache:" & nimcache).quoteShell & extraOptions + let options = options & " " & quoteShell("--nimCache:" & nimcache) & extraOptions let c = parseCmdLine(cmdTemplate % ["target", targetToCmd[target], "options", options, "file", filename.quoteShell, "filedir", filename.getFileDir()]) @@ -138,7 +141,7 @@ proc callCompiler(cmdTemplate, filename, options: string, close(p) result.msg = "" result.file = "" - result.outp = "" + result.output = "" result.line = 0 result.column = 0 result.tfile = "" @@ -170,7 +173,7 @@ proc callCCompiler(cmdTemplate, filename, options: string, result.nimout = "" result.msg = "" result.file = "" - result.outp = "" + result.output = "" result.line = -1 while outp.readLine(x.TaintedString) or running(p): result.nimout.add(x & "\n") @@ -219,18 +222,21 @@ proc addResult(r: var TResults, test: TTest, target: TTarget, let name = test.name.extractFilename & " " & $target & test.options let duration = epochTime() - test.startTime let durationStr = duration.formatFloat(ffDecimal, precision = 8).align(11) - backend.writeTestResult(name = name, - category = test.cat.string, - target = $target, - action = $test.action, - result = $success, - expected = expected, - given = given) + if backendLogging: + backend.writeTestResult(name = name, + category = test.cat.string, + target = $target, + action = $test.spec.action, + result = $success, + expected = expected, + given = given) r.data.addf("$#\t$#\t$#\t$#", name, expected, given, $success) if success == reSuccess: maybeStyledEcho fgGreen, "PASS: ", fgCyan, alignLeft(name, 60), fgBlue, " (", durationStr, " secs)" - elif success == reIgnored: + elif success == reDisabled: maybeStyledEcho styleDim, fgYellow, "SKIP: ", styleBright, fgCyan, name + elif success == reJoined: + maybeStyledEcho styleDim, fgYellow, "JOINED: ", styleBright, fgCyan, name else: maybeStyledEcho styleBright, fgRed, "FAIL: ", fgCyan, name maybeStyledEcho styleBright, fgCyan, "Test \"", test.name, "\"", " in category \"", test.cat.string, "\"" @@ -240,11 +246,11 @@ proc addResult(r: var TResults, test: TTest, target: TTarget, maybeStyledEcho fgYellow, "Gotten:" maybeStyledEcho styleBright, given, "\n" - if existsEnv("APPVEYOR"): + if backendLogging and existsEnv("APPVEYOR"): let (outcome, msg) = if success == reSuccess: ("Passed", "") - elif success == reIgnored: + elif success in {reDisabled, reJoined}: ("Skipped", "") else: ("Failed", "Failure: " & $success & "\nExpected:\n" & expected & "\n\n" & "Gotten:\n" & given) @@ -328,11 +334,6 @@ proc nimoutCheck(test: TTest; expectedNimout: string; given: var TSpec) = given.err = reMsgsDiffer return -proc makeDeterministic(s: string): string = - var x = splitLines(s) - sort(x, system.cmp) - result = join(x, "\n") - proc compilerOutputTests(test: TTest, target: TTarget, given: var TSpec, expected: TSpec; r: var TResults) = var expectedmsg: string = "" @@ -350,75 +351,58 @@ proc compilerOutputTests(test: TTest, target: TTarget, given: var TSpec, if given.err == reSuccess: inc(r.passed) r.addResult(test, target, expectedmsg, givenmsg, given.err) -proc testSpec(r: var TResults, test: TTest, target = targetC) = - let tname = test.name.addFileExt(".nim") - var expected: TSpec - if test.action != actionRunNoSpec: - expected = parseSpec(tname) - if test.action == actionRun and expected.action == actionCompile: - expected.action = actionRun - else: - specDefaults expected - expected.action = actionRunNoSpec - - if expected.err == reIgnored: - r.addResult(test, target, "", "", reIgnored) +proc testSpec(r: var TResults, test: TTest, targets: set[TTarget] = {}) = + var expected = test.spec + if expected.parseErrors.len > 0: + # targetC is a lie, but parameter is required + r.addResult(test, targetC, "", expected.parseErrors, reInvalidSpec) + inc(r.total) + return + if expected.err in {reDisabled, reJoined}: + # targetC is a lie, but parameter is required + r.addResult(test, targetC, "", "", expected.err) inc(r.skipped) inc(r.total) return - - if getEnv("NIM_COMPILE_TO_CPP", "false").string == "true" and target == targetC and expected.targets == {}: - expected.targets.incl(targetCpp) - elif expected.targets == {}: - expected.targets.incl(target) - + expected.targets.incl targets + # still no target specified at all + if expected.targets == {}: + if getEnv("NIM_COMPILE_TO_CPP", "false").string == "true": + expected.targets = {targetCpp} + else: + expected.targets = {targetC} for target in expected.targets: inc(r.total) - if target notin targets: - r.addResult(test, target, "", "", reIgnored) - inc(r.skipped) - continue - case expected.action of actionCompile: - var given = callCompiler(expected.cmd, test.name, test.options, target, + var given = callCompiler(expected.getCmd, test.name, test.options, target, extraOptions=" --stdout --hint[Path]:off --hint[Processing]:off") compilerOutputTests(test, target, given, expected, r) - of actionRun, actionRunNoSpec: + of actionRun: # In this branch of code "early return" pattern is clearer than deep # nested conditionals - the empty rows in between to clarify the "danger" - var given = callCompiler(expected.cmd, test.name, test.options, + var given = callCompiler(expected.getCmd, test.name, test.options, target) - - # echo "expected.cmd: ", expected.cmd - # echo "nimout: ", given.nimout - # echo "outp: ", given.outp - # echo "msg: ", given.msg - # echo "err: ", given.err - if given.err != reSuccess: r.addResult(test, target, "", given.msg, given.err) continue - let isJsTarget = target == targetJS var exeFile: string if isJsTarget: - let (_, file, _) = splitFile(tname) - exeFile = nimcacheDir(test.name, test.options, target) / file & ".js" + let file = test.name.lastPathPart.changeFileExt("js") + exeFile = nimcacheDir(test.name, test.options, target) / file else: - exeFile = changeFileExt(tname, ExeExt) + exeFile = changeFileExt(test.name, ExeExt) if not existsFile(exeFile): - r.addResult(test, target, expected.outp, "executable not found", reExeNotFound) + r.addResult(test, target, expected.output, "executable not found", reExeNotFound) continue let nodejs = if isJsTarget: findNodeJs() else: "" if isJsTarget and nodejs == "": - r.addResult(test, target, expected.outp, "nodejs binary not in PATH", + r.addResult(test, target, expected.output, "nodejs binary not in PATH", reExeNotFound) continue - - var exeCmd: string var args: seq[string] if isJsTarget: @@ -426,55 +410,44 @@ proc testSpec(r: var TResults, test: TTest, target = targetC) = args.add exeFile else: exeCmd = exeFile - var (buf, exitCode) = execCmdEx2(exeCmd, args, options = {poStdErrToStdOut}, input = expected.input) - # Treat all failure codes from nodejs as 1. Older versions of nodejs used # to return other codes, but for us it is sufficient to know that it's not 0. if exitCode != 0: exitCode = 1 - - let bufB = if expected.sortoutput: makeDeterministic(strip(buf.string)) - else: strip(buf.string) - let expectedOut = strip(expected.outp) - + let bufB = + if expected.sortoutput: + var x = splitLines(strip(buf.string)) + sort(x, system.cmp) + join(x, "\n") + else: + strip(buf.string) if exitCode != expected.exitCode: r.addResult(test, target, "exitcode: " & $expected.exitCode, "exitcode: " & $exitCode & "\n\nOutput:\n" & bufB, reExitCodesDiffer) continue - - if bufB != expectedOut and expected.action != actionRunNoSpec: - if not (expected.substr and expectedOut in bufB): - given.err = reOutputsDiffer - r.addResult(test, target, expected.outp, bufB, reOutputsDiffer) - continue - + if (expected.outputCheck == ocEqual and expected.output != bufB) or + (expected.outputCheck == ocSubstr and expected.output notin bufB): + given.err = reOutputsDiffer + r.addResult(test, target, expected.output, bufB, reOutputsDiffer) + continue compilerOutputTests(test, target, given, expected, r) continue - of actionReject: - var given = callCompiler(expected.cmd, test.name, test.options, + var given = callCompiler(expected.getCmd, test.name, test.options, target) cmpMsgs(r, expected, given, test, target) continue -proc testNoSpec(r: var TResults, test: TTest, target = targetC) = - # does not extract the spec because the file is not supposed to have any - #let tname = test.name.addFileExt(".nim") - inc(r.total) - let given = callCompiler(cmdTemplate(), test.name, test.options, target) - r.addResult(test, target, "", given.msg, given.err) - if given.err == reSuccess: inc(r.passed) - -proc testC(r: var TResults, test: TTest) = +proc testC(r: var TResults, test: TTest, action: TTestAction) = # runs C code. Doesn't support any specs, just goes by exit code. let tname = test.name.addFileExt(".c") inc(r.total) maybeStyledEcho "Processing ", fgCyan, extractFilename(tname) - var given = callCCompiler(cmdTemplate(), test.name & ".c", test.options, targetC) + var given = callCCompiler(getCmd(TSpec()), test.name & ".c", test.options, targetC) if given.err != reSuccess: r.addResult(test, targetC, "", given.msg, given.err) - elif test.action == actionRun: + elif action == actionRun: let exeFile = changeFileExt(test.name, ExeExt) var (_, exitCode) = execCmdEx(exeFile, options = {poStdErrToStdOut, poUsePath}) if exitCode != 0: given.err = reExitCodesDiffer @@ -485,7 +458,6 @@ proc testExec(r: var TResults, test: TTest) = inc(r.total) let (outp, errC) = execCmdEx(test.options.strip()) var given: TSpec - specDefaults(given) if errC == 0: given.err = reSuccess else: @@ -495,11 +467,12 @@ proc testExec(r: var TResults, test: TTest) = if given.err == reSuccess: inc(r.passed) r.addResult(test, targetC, "", given.msg, given.err) -proc makeTest(test, options: string, cat: Category, action = actionCompile, - env: string = ""): TTest = - # start with 'actionCompile', will be overwritten in the spec: - result = TTest(cat: cat, name: test, options: options, - action: action, startTime: epochTime()) +proc makeTest(test, options: string, cat: Category): TTest = + result.cat = cat + result.name = test + result.options = options + result.spec = parseSpec(addFileExt(test, ".nim")) + result.startTime = epochTime() when defined(windows): const @@ -512,10 +485,7 @@ else: include categories -# proc runCaasTests(r: var TResults) = -# for test, output, status, mode in caasTestsRunner(): -# r.addResult(test, "", output & "-> " & $mode, -# if status: reSuccess else: reOutputsDiffer) +const testsDir = "tests" & DirSep proc main() = os.putenv "NIMTEST_COLOR", "never" @@ -524,10 +494,8 @@ proc main() = backend.open() var optPrintResults = false var optFailing = false - var targetsStr = "" - var p = initOptParser() p.next() while p.kind == cmdLongoption: @@ -538,26 +506,38 @@ proc main() = of "targets": targetsStr = p.val.string targets = parseTargets(targetsStr) - of "nim": compilerPrefix = p.val.string + of "nim": + compilerPrefix = addFileExt(p.val.string, ExeExt) of "directory": setCurrentDir(p.val.string) of "colors": - if p.val.string == "on": + case p.val.string: + of "on": useColors = true - elif p.val.string == "off": + of "off": useColors = false else: quit Usage + of "backendlogging": + case p.val.string: + of "on": + backendLogging = true + of "off": + backendLogging = false + else: + quit Usage else: quit Usage p.next() - if p.kind != cmdArgument: quit Usage + if p.kind != cmdArgument: + quit Usage var action = p.key.string.normalize p.next() var r = initResults() case action of "all": - let testsDir = "tests" & DirSep + #processCategory(r, Category"megatest", p.cmdLineRest.string, testsDir, runJoinableTests = false) + var myself = quoteShell(findExe("testament" / "tester")) if targetsStr.len > 0: myself &= " " & quoteShell("--targets:" & targetsStr) @@ -570,14 +550,21 @@ proc main() = assert testsDir.startsWith(testsDir) let cat = dir[testsDir.len .. ^1] if kind == pcDir and cat notin ["testdata", "nimcache"]: - cmds.add(myself & " cat " & quoteShell(cat) & rest) + cmds.add(myself & " pcat " & quoteShell(cat) & rest) for cat in AdditionalCategories: - cmds.add(myself & " cat " & quoteShell(cat) & rest) + cmds.add(myself & " pcat " & quoteShell(cat) & rest) quit osproc.execProcesses(cmds, {poEchoCmd, poStdErrToStdOut, poUsePath, poParentStreams}) of "c", "cat", "category": var cat = Category(p.key) p.next - processCategory(r, cat, p.cmdLineRest.string) + processCategory(r, cat, p.cmdLineRest.string, testsDir, runJoinableTests = true) + of "pcat": + # 'pcat' is used for running a category in parallel. Currently the only + # difference is that we don't want to run joinable tests here as they + # are covered by the 'megatest' category. + var cat = Category(p.key) + p.next + processCategory(r, cat, p.cmdLineRest.string, testsDir, runJoinableTests = false) of "r", "run": let (dir, file) = splitPath(p.key.string) let (_, subdir) = splitPath(dir) diff --git a/testament/tests/shouldfail/tcolumn.nim b/testament/tests/shouldfail/tcolumn.nim index f4046d58d..89482e673 100644 --- a/testament/tests/shouldfail/tcolumn.nim +++ b/testament/tests/shouldfail/tcolumn.nim @@ -1,7 +1,7 @@ discard """ +errormsg: "undeclared identifier: 'undeclared'" line: 8 column: 7 -errormsg: "undeclared identifier: 'undeclared'" """ # test should fail because the line directive is wrong diff --git a/testament/tests/shouldfail/terrormsg.nim b/testament/tests/shouldfail/terrormsg.nim index 61c08d93d..dbbdf5021 100644 --- a/testament/tests/shouldfail/terrormsg.nim +++ b/testament/tests/shouldfail/terrormsg.nim @@ -1,7 +1,7 @@ discard """ +errormsg: "wrong error message" line: 8 column: 6 -errormsg: "wrong error message" """ # test should fail because the line directive is wrong diff --git a/testament/tests/shouldfail/tfile.nim b/testament/tests/shouldfail/tfile.nim index 07a526c68..a6c2ad359 100644 --- a/testament/tests/shouldfail/tfile.nim +++ b/testament/tests/shouldfail/tfile.nim @@ -1,6 +1,6 @@ discard """ -file: "notthisfile.nim" errmsg: "undeclared identifier: 'undefined'" +file: "notthisfile.nim" """ echo undefined diff --git a/testament/tests/shouldfail/tline.nim b/testament/tests/shouldfail/tline.nim index 963e44fc7..f7a09875c 100644 --- a/testament/tests/shouldfail/tline.nim +++ b/testament/tests/shouldfail/tline.nim @@ -1,7 +1,7 @@ discard """ +errormsg: "undeclared identifier: 'undeclared'" line: 9 column: 6 -errormsg: "undeclared identifier: 'undeclared'" """ # test should fail because the line directive is wrong diff --git a/tests/ambsym/tambsym.nim b/tests/ambsym/tambsym.nim index d9115e16d..bd0f41717 100644 --- a/tests/ambsym/tambsym.nim +++ b/tests/ambsym/tambsym.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "ambiguous identifier" file: "tambsym.nim" line: 11 - errormsg: "ambiguous identifier" """ # Test ambiguous symbols @@ -11,5 +11,3 @@ var v: TExport #ERROR_MSG ambiguous identifier v = y - - diff --git a/tests/ambsym/tambsym2.nim b/tests/ambsym/tambsym2.nim index 8e288e73a..747f1a086 100644 --- a/tests/ambsym/tambsym2.nim +++ b/tests/ambsym/tambsym2.nim @@ -1,5 +1,4 @@ discard """ - file: "tambsym2.nim" output: "7" """ # Test overloading of procs with locals @@ -20,5 +19,3 @@ m.len = 7 m.data = "1234" x(m, 5) #OUT 7 - - diff --git a/tests/ambsym/tambsym3.nim b/tests/ambsym/tambsym3.nim index b25dadfd6..0558517bd 100644 --- a/tests/ambsym/tambsym3.nim +++ b/tests/ambsym/tambsym3.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "ambiguous identifier" file: "tambsym3.nim" line: 11 - errormsg: "ambiguous identifier" """ # Test ambiguous symbols @@ -11,5 +11,3 @@ var v = mDec #ERROR_MSG ambiguous identifier writeLine(stdout, ord(v)) - - diff --git a/tests/ambsym/tambsys.nim b/tests/ambsym/tambsys.nim index 67522d7c9..aa740c38f 100644 --- a/tests/ambsym/tambsys.nim +++ b/tests/ambsym/tambsys.nim @@ -1,5 +1,4 @@ discard """ - file: "tambsys.nim" output: "" """ # Test ambiguous symbols @@ -9,5 +8,3 @@ import mambsys1, mambsys2 var v: mambsys1.TExport mambsys2.foo(3) #OUT - - diff --git a/tests/array/tarray.nim b/tests/array/tarray.nim index 8551d324c..2a371b788 100644 --- a/tests/array/tarray.nim +++ b/tests/array/tarray.nim @@ -1,7 +1,5 @@ discard """ - file: "tarray.nim" - output: -''' +output: ''' [4, 5, 6] [16, 25, 36] @@ -30,6 +28,7 @@ dflfdjkl__abcdefgasfsgdfgsgdfggsdfasdfsafewfkljdsfajsdf kgdchlfniambejop fjpmholcibdgeakn ''' +joinable: false """ block tarray: @@ -358,7 +357,7 @@ block troofregression: echo testStr[testStr.len - 8 .. testStr.len - 1] & "__" & testStr[0 .. testStr.len - pred(rot)] var - instructions = readFile(getAppDir() / "troofregression2.txt").split(',') + instructions = readFile(parentDir(currentSourcePath) / "troofregression2.txt").split(',') programs = "abcdefghijklmnop" proc dance(dancers: string): string = diff --git a/tests/array/tarraycons.nim b/tests/array/tarraycons.nim index 9f09fd405..b6ebe55c8 100644 --- a/tests/array/tarraycons.nim +++ b/tests/array/tarraycons.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "invalid order in array constructor" file: "tarraycons.nim" line: 14 - errormsg: "invalid order in array constructor" """ type @@ -19,6 +19,3 @@ const ] echo myMapping[eC][1] - - - diff --git a/tests/array/tarraycons_ptr_generic2.nim b/tests/array/tarraycons_ptr_generic2.nim index fce7af669..f6ed32b58 100644 --- a/tests/array/tarraycons_ptr_generic2.nim +++ b/tests/array/tarraycons_ptr_generic2.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "type mismatch: got <ptr Hard[system.string]> but expected 'Book[system.string]'" file: "tarraycons_ptr_generic2.nim" line: 17 - errormsg: "type mismatch: got <ptr Hard[system.string]> but expected 'Book[system.string]'" """ type diff --git a/tests/assert/tassert.nim b/tests/assert/tassert.nim index b5f2fb715..99929f080 100644 --- a/tests/assert/tassert.nim +++ b/tests/assert/tassert.nim @@ -1,5 +1,4 @@ discard """ - file: "tassert.nim" outputsub: "assertion failure!this shall be always written" exitcode: "1" """ @@ -19,5 +18,3 @@ finally: system.write(stdout, "this shall be always written") assert(false) #OUT assertion failure!this shall be always written - - diff --git a/tests/assign/tassign.nim b/tests/assign/tassign.nim index cb03b5004..b421802ae 100644 --- a/tests/assign/tassign.nim +++ b/tests/assign/tassign.nim @@ -1,5 +1,4 @@ discard """ - file: "tassign.nim" output: ''' TEMP=C:\Programs\xyz\bin diff --git a/tests/assign/tvariantasgn.nim b/tests/assign/tvariantasgn.nim index 46cc23dd1..2278957ac 100644 --- a/tests/assign/tvariantasgn.nim +++ b/tests/assign/tvariantasgn.nim @@ -1,7 +1,7 @@ discard """ - file: "tvariantasgn.nim" output: "came here" """ + #BUG type TAnyKind = enum @@ -26,5 +26,3 @@ nr.intVal = 78 # s = nr # works nr = s # fails! echo "came here" - - diff --git a/tests/async/t7192.nim b/tests/async/t7192.nim index c380f93e1..9ac0e07c0 100644 --- a/tests/async/t7192.nim +++ b/tests/async/t7192.nim @@ -9,6 +9,6 @@ import asyncdispatch proc testCallback() = echo "testCallback()" -when isMainModule: +when true: callSoon(testCallback) poll() diff --git a/tests/async/t7758.nim b/tests/async/t7758.nim index 102a4ce4c..ce4df1fc9 100644 --- a/tests/async/t7758.nim +++ b/tests/async/t7758.nim @@ -1,7 +1,3 @@ -discard """ - file: "t7758.nim" - exitcode: 0 -""" import asyncdispatch proc task() {.async.} = @@ -16,4 +12,4 @@ proc main() = doAssert counter <= 4 -for i in 0 .. 10: main() \ No newline at end of file +for i in 0 .. 10: main() diff --git a/tests/async/tasyncRecvLine.nim b/tests/async/tasyncRecvLine.nim index 679831b27..a13a171c3 100644 --- a/tests/async/tasyncRecvLine.nim +++ b/tests/async/tasyncRecvLine.nim @@ -1,6 +1,5 @@ discard """ - file: "tasyncRecvLine.nim" - output: ''' +output: ''' Hello World Hello World ''' diff --git a/tests/async/tasync_gcunsafe.nim b/tests/async/tasync_gcunsafe.nim index f4e2cdcf2..55b66aaef 100644 --- a/tests/async/tasync_gcunsafe.nim +++ b/tests/async/tasync_gcunsafe.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "'anotherGCSafeAsyncProcIter' is not GC-safe as it calls 'asyncGCUnsafeProc'" cmd: "nim c --threads:on $file" file: "asyncmacro.nim" - errormsg: "'anotherGCSafeAsyncProcIter' is not GC-safe as it calls 'asyncGCUnsafeProc'" """ assert compileOption("threads"), "this test will not do anything useful without --threads:on" diff --git a/tests/async/tasyncall.nim b/tests/async/tasyncall.nim index 3e30e8ba8..3c318dbf7 100644 --- a/tests/async/tasyncall.nim +++ b/tests/async/tasyncall.nim @@ -1,5 +1,4 @@ discard """ - file: "tasyncall.nim" exitcode: 0 """ import times, sequtils diff --git a/tests/async/tasyncawait.nim b/tests/async/tasyncawait.nim index e7a2ec1d9..fcb48a1f5 100644 --- a/tests/async/tasyncawait.nim +++ b/tests/async/tasyncawait.nim @@ -1,5 +1,4 @@ discard """ - file: "tasyncawait.nim" output: "5000" """ import asyncdispatch, nativesockets, net, strutils, os diff --git a/tests/async/tasyncconnect.nim b/tests/async/tasyncconnect.nim index 3dac379b2..f63a87990 100644 --- a/tests/async/tasyncconnect.nim +++ b/tests/async/tasyncconnect.nim @@ -1,7 +1,6 @@ discard """ - file: "tasyncconnect.nim" - exitcode: 1 outputsub: "Error: unhandled exception: Connection refused" + exitcode: 1 """ import diff --git a/tests/async/tasyncdial.nim b/tests/async/tasyncdial.nim index fa81235fe..815520294 100644 --- a/tests/async/tasyncdial.nim +++ b/tests/async/tasyncdial.nim @@ -1,5 +1,4 @@ discard """ - file: "tasyncdial.nim" output: ''' OK AF_INET OK AF_INET6 diff --git a/tests/async/tasyncexceptions.nim b/tests/async/tasyncexceptions.nim index 7aa1d7fb0..de61c099d 100644 --- a/tests/async/tasyncexceptions.nim +++ b/tests/async/tasyncexceptions.nim @@ -1,7 +1,6 @@ discard """ - file: "tasyncexceptions.nim" - exitcode: 1 outputsub: "Error: unhandled exception: foobar" + exitcode: 1 """ import asyncdispatch @@ -28,7 +27,7 @@ proc serve() {.async.} = var fut = await accept() await processClient(fut) -when isMainModule: +when true: proc main = var fut = serve() fut.callback = diff --git a/tests/async/tasyncfile.nim b/tests/async/tasyncfile.nim index c7b71a2f7..d95850c31 100644 --- a/tests/async/tasyncfile.nim +++ b/tests/async/tasyncfile.nim @@ -1,10 +1,9 @@ discard """ - output: '''13 +output: ''' +13 hello humans! 13 ''' - file: "tasyncfile.nim" - exitcode: 0 """ import asyncfile, asyncdispatch, os @@ -54,8 +53,7 @@ proc main() {.async.} = # Issue #7347 block: - let appDir = getAppDir() - var file = openAsync(appDir & DirSep & "hello.txt") + var file = openAsync( parentDir(currentSourcePath) / "hello.txt") echo file.getFileSize() echo await file.readAll() echo file.getFilePos() diff --git a/tests/async/tasyncrecursion.nim b/tests/async/tasyncrecursion.nim index 1aeebe9b4..7c12dbb0e 100644 --- a/tests/async/tasyncrecursion.nim +++ b/tests/async/tasyncrecursion.nim @@ -1,6 +1,5 @@ discard """ - file: "tasyncrecursion.nim" - output: "50005000" +output: "50005000" """ import asyncdispatch @@ -16,7 +15,7 @@ proc asyncRecursionTest*(): Future[int] {.async.} = inc(result, await asyncRecursionCycle(i)) inc(i) -when isMainModule: +when true: setGlobalDispatcher(newDispatcher()) var i = waitFor asyncRecursionTest() echo i diff --git a/tests/async/tasyncsend4757.nim b/tests/async/tasyncsend4757.nim index 752bb3e75..a87c5df95 100644 --- a/tests/async/tasyncsend4757.nim +++ b/tests/async/tasyncsend4757.nim @@ -1,6 +1,5 @@ discard """ - file: "tasyncsend4754.nim" - output: "Finished" +output: "Finished" """ import asyncdispatch, asyncnet diff --git a/tests/async/tasyncssl.nim b/tests/async/tasyncssl.nim index 212260922..88a5eb32e 100644 --- a/tests/async/tasyncssl.nim +++ b/tests/async/tasyncssl.nim @@ -1,5 +1,4 @@ discard """ - file: "tasyncssl.nim" cmd: "nim $target --hints:on --define:ssl $options $file" output: "500" disabled: "windows" diff --git a/tests/async/tasynctry.nim b/tests/async/tasynctry.nim index 0fe9efdc1..b13c57951 100644 --- a/tests/async/tasynctry.nim +++ b/tests/async/tasynctry.nim @@ -1,7 +1,5 @@ discard """ - file: "tasynctry.nim" - exitcode: 0 - output: ''' +output: ''' Generic except: Test Specific except Multiple idents in except diff --git a/tests/async/tawaitsemantics.nim b/tests/async/tawaitsemantics.nim index 98fb5dfd5..67903cc5e 100644 --- a/tests/async/tawaitsemantics.nim +++ b/tests/async/tawaitsemantics.nim @@ -1,7 +1,5 @@ discard """ - file: "tawaitsemantics.nim" - exitcode: 0 - output: ''' +output: ''' Error can be caught using yield Infix `or` raises Infix `and` raises diff --git a/tests/async/tfuturestream.nim b/tests/async/tfuturestream.nim index 69ad80f47..b5772d5ac 100644 --- a/tests/async/tfuturestream.nim +++ b/tests/async/tfuturestream.nim @@ -1,7 +1,5 @@ discard """ - file: "tfuturestream.nim" - exitcode: 0 - output: ''' +output: ''' 0 1 2 @@ -70,4 +68,4 @@ waitFor testCompletion() # echo("Finished") -# waitFor omega() \ No newline at end of file +# waitFor omega() diff --git a/tests/async/tioselectors.nim b/tests/async/tioselectors.nim index 7a8986644..be6d3a167 100644 --- a/tests/async/tioselectors.nim +++ b/tests/async/tioselectors.nim @@ -1,5 +1,4 @@ discard """ - file: "tioselectors.nim" output: "All tests passed!" """ import selectors diff --git a/tests/async/tnewasyncudp.nim b/tests/async/tnewasyncudp.nim index b442c0524..7dbd5a3d0 100644 --- a/tests/async/tnewasyncudp.nim +++ b/tests/async/tnewasyncudp.nim @@ -1,5 +1,4 @@ discard """ - file: "tnewasyncudp.nim" output: "5000" """ import asyncdispatch, nativesockets, net, strutils, os diff --git a/tests/async/tpendingcheck.nim b/tests/async/tpendingcheck.nim index 825acb613..a5537d8cb 100644 --- a/tests/async/tpendingcheck.nim +++ b/tests/async/tpendingcheck.nim @@ -1,6 +1,4 @@ discard """ - file: "tpendingcheck.nim" - exitcode: 0 output: "" """ @@ -18,4 +16,3 @@ while not f.finished: f.read doAssert(not hasPendingOperations()) - diff --git a/tests/async/twinasyncrw.nim b/tests/async/twinasyncrw.nim index 94193e921..64c5d6c26 100644 --- a/tests/async/twinasyncrw.nim +++ b/tests/async/twinasyncrw.nim @@ -1,5 +1,4 @@ discard """ - file: "twinasyncrw.nim" output: "5000" """ when defined(windows): diff --git a/tests/benchmark.nim b/tests/benchmark.nim deleted file mode 100644 index 69c9a3927..000000000 --- a/tests/benchmark.nim +++ /dev/null @@ -1,47 +0,0 @@ -# -# -# Nim Benchmark tool -# (c) Copyright 2012 Dominik Picheta -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## This program runs benchmarks -import osproc, os, times, json - -type - TBenchResult = tuple[file: string, success: bool, time: float] - -proc compileBench(file: string) = - ## Compiles ``file``. - doAssert(execCmdEx("nim c -d:release " & file).exitCode == QuitSuccess) - -proc runBench(file: string): TBenchResult = - ## Runs ``file`` and returns info on how long it took to run. - var start = epochTime() - if execCmdEx(file.addFileExt(ExeExt)).exitCode == QuitSuccess: - var t = epochTime() - start - result = (file, true, t) - else: result = (file, false, -1.0) - -proc genOutput(benches: seq[TBenchResult]): PJsonNode = - result = newJObject() - for i in benches: - if i.success: - result[i.file.extractFilename] = newJFloat(i.time) - else: - result[i.file.extractFilename] = newJNull() - -proc doBench(): seq[TBenchResult] = - result = @[] - for i in walkFiles("tests/benchmarks/*.nim"): - echo(i.extractFilename) - compileBench(i) - result.add(runBench(i)) - -when isMainModule: - var b = doBench() - var output = genOutput(b) - writeFile("benchmarkResults.json", pretty(output)) - diff --git a/tests/benchmarks/fannkuch.nim b/tests/benchmarks/fannkuch.nim deleted file mode 100644 index c87295092..000000000 --- a/tests/benchmarks/fannkuch.nim +++ /dev/null @@ -1,69 +0,0 @@ -import os -import strutils - -proc fannkuch(n: int): int = - var - count: seq[int] - maxFlips = 0 - m = n-1 - r = n - check = 0 - perm1: seq[int] - perm: seq[int] - - newSeq(count, n+1) - newSeq(perm1, n) - newSeq(perm, n) - for i in 0 .. n-1: - count[i] = i+1 - perm1[i] = i - perm[i] = i - count[n] = n+1 - - while true: - if check < 30: - for i in items(perm1): - write(stdout, $(i+1)) - echo("") - inc(check) - - while r != 1: - count[r-1] = r - dec (r) - - if perm1[0] != 0 and perm1[m] != m: - # perm = perm1 - # The above line is between 3 and 4 times slower than the loop below! - for i in 0 .. n-1: - perm[i] = perm1[i] - var flipsCount = 0 - var k = perm[0] - while k != 0: - for i in 0 .. (k div 2): - swap(perm[i], perm[k-i]) - inc(flipsCount) - k = perm[0] - - if flipsCount > maxFlips: - maxFlips = flipsCount - - block makePerm: - while r != n: - var tmp = perm1[0] - # # perm1.delete (0) - # # perm1.insert (tmp, r) - # # The above is about twice as slow as the following: - # moveMem (addr (perm1[0]), addr (perm1[1]), r * sizeof (int)) - # The call to moveMem is about 50% slower than the loop below! - for i in 0 .. r-1: - perm1[i] = perm1[i+1] - perm1[r] = tmp - - dec(count[r]) - if count[r] > 0: - break makePerm - inc(r) - return maxFlips - -var n = 10 -echo("Pfannkuchen(" & $n & ") = " & $fannkuch(n)) diff --git a/tests/benchmarks/quicksort.nim b/tests/benchmarks/quicksort.nim deleted file mode 100644 index 114321492..000000000 --- a/tests/benchmarks/quicksort.nim +++ /dev/null @@ -1,54 +0,0 @@ -import os -import strutils - -# Generate some pseudo-random data -var seed: tuple[s1, s2, s3: int32] = (2'i32, 8'i32, 16'i32) - -proc random(): int32 = - seed = (((((((seed[0] and 0x0007_FFFF'i32) shl 13'i32) xor seed[0]) shr - 19'i32) and 0x0000_1FFF'i32) xor - ((seed[0] and 0x000F_FFFE'i32) shl 12'i32)), - - ((((((seed[1] and 0x3FFF_FFFF'i32) shl 2'i32) xor seed[1]) shr - 25'i32) and 0x0000_007F'i32) xor - ((seed[1] and 0x0FFF_FFF8'i32) shl 4'i32)), - - ((((((seed[2] and 0x1FFF_FFFF'i32) shl 3'i32) xor seed[2]) shr - 11'i32) and 0x001F_FFFF'i32) xor - ((seed[2] and 0x0000_7FF0'i32) shl 17'i32))) - return seed[0] xor seed[1] xor seed[2] - -var n = 9999999 - -var data: seq[int32] -newSeq(data, n) -for i in 0 .. data.high(): - data[i] = random() - - -proc `$`(d: seq[int32]): string = - result = "[ " - for i in items(d): - result.addSep(", ", 2) - result.add($(i and 0xFFFF_FFFF'i64)) - result.add(" ]") - -# Sort the data -proc sort(start, stop: int) = - if stop <= start+1: - return - - var j = start - for i in start..stop-2: - if data[i] <% data[stop-1]: - swap(data[i], data[j]) - inc(j) - swap(data[j], data[stop-1]) - - sort(start, j) - sort(j+1, stop) - -sort(0, data.len) -echo(data[n div 2 - 1] and 0xFFFF_FFFF'i64, ", ", - data[n div 2] and 0xFFFF_FFFF'i64, ", ", - data[n div 2 + 1] and 0xFFFF_FFFF'i64) diff --git a/tests/bind/tbind.nim b/tests/bind/tbind.nim index 6fcf95433..49c37ae2e 100644 --- a/tests/bind/tbind.nim +++ b/tests/bind/tbind.nim @@ -1,7 +1,5 @@ discard """ - file: "tbind.nim" - output: -''' +output: ''' 3 1 1 diff --git a/tests/bind/tbind2.nim b/tests/bind/tbind2.nim index 799b14381..fc2eeda1a 100644 --- a/tests/bind/tbind2.nim +++ b/tests/bind/tbind2.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "ambiguous call" file: "tbind2.nim" line: 12 - errormsg: "ambiguous call" """ # Test the new ``bind`` keyword for templates @@ -12,6 +12,3 @@ template tempBind(x, y): untyped = (bind p1(x, y)) #ERROR_MSG ambiguous call echo tempBind(1'i8, 2'i8) - - - diff --git a/tests/bind/tdatabind.nim b/tests/bind/tdatabind.nim index 124faee6f..f6455749c 100644 --- a/tests/bind/tdatabind.nim +++ b/tests/bind/tdatabind.nim @@ -74,7 +74,7 @@ proc propertyBind*[T](p1: var TProperty[T], p2: var TProperty[T]) = proc `->`[T](p1: var TProperty[T], p2: var TProperty[T]) = propertyBind(p2,p1) -when isMainModule: +when true: # Initial value testing var myProp = newProperty(5) diff --git a/tests/bind/tinvalidbindtypedesc.nim b/tests/bind/tinvalidbindtypedesc.nim index ecdd12603..4bcd4e39d 100644 --- a/tests/bind/tinvalidbindtypedesc.nim +++ b/tests/bind/tinvalidbindtypedesc.nim @@ -1,6 +1,6 @@ discard """ - line: 10 errormsg: "type mismatch: got <type float, string>" + line: 10 """ proc foo(T: typedesc; some: T) = @@ -8,4 +8,3 @@ proc foo(T: typedesc; some: T) = foo int, 4 foo float, "bad" - diff --git a/tests/bind/tnicerrorforsymchoice.nim b/tests/bind/tnicerrorforsymchoice.nim index 8c3a99c97..f16b323de 100644 --- a/tests/bind/tnicerrorforsymchoice.nim +++ b/tests/bind/tnicerrorforsymchoice.nim @@ -1,6 +1,6 @@ discard """ - line: 18 errormsg: "type mismatch: got <proc (s: TScgi: ScgiState or AsyncScgiState) | proc (client: AsyncSocket, headers: StringTableRef, input: string){.noSideEffect, gcsafe, locks: 0.}>" + line: 18 """ #bug #442 diff --git a/tests/borrow/tinvalidborrow.nim b/tests/borrow/tinvalidborrow.nim index 9ab9e8d64..89aa4e2e8 100644 --- a/tests/borrow/tinvalidborrow.nim +++ b/tests/borrow/tinvalidborrow.nim @@ -1,6 +1,6 @@ discard """ - line: 11 errormsg: "no symbol to borrow from found" + line: 11 """ # bug #516 @@ -14,4 +14,3 @@ var d, e: TAtom echo( $(d == e) ) - diff --git a/tests/caas/absurd_nesting.nim b/tests/caas/absurd_nesting.nim deleted file mode 100644 index 136d65cc7..000000000 --- a/tests/caas/absurd_nesting.nim +++ /dev/null @@ -1,29 +0,0 @@ -# Tries to test the full ownership path generated by idetools. - -proc lev1(t1: string) = - var temp = t1 - for i in 0..len(temp)-1: - temp[i] = chr(int(temp[i]) + 1) - - proc lev2(t2: string) = - var temp = t2 - for i in 0..len(temp)-1: - temp[i] = chr(int(temp[i]) + 1) - - proc lev3(t3: string) = - var temp = t3 - for i in 0..len(temp)-1: - temp[i] = chr(int(temp[i]) + 1) - - proc lev4(t4: string) = - var temp = t4 - for i in 0..len(temp)-1: - temp[i] = chr(int(temp[i]) + 1) - - echo temp & "(lev4)" - lev4(temp & "(lev3)") - lev3(temp & "(lev2)") - lev2(temp & "(lev1)") - -when isMainModule: - lev1("abcd") diff --git a/tests/caas/absurd_nesting.txt b/tests/caas/absurd_nesting.txt deleted file mode 100644 index 986e34836..000000000 --- a/tests/caas/absurd_nesting.txt +++ /dev/null @@ -1,29 +0,0 @@ -absurd_nesting.nim - -> c --verbosity:0 --hints:on -SuccessX - -> idetools --track:$TESTNIM,6,6 --def $SILENT -skVar\tabsurd_nesting.lev1.temp\tstring - -> idetools --track:$TESTNIM,21,13 --def $SILENT -skVar\tabsurd_nesting.lev1.lev2.lev3.lev4.temp\tstring - -> idetools --track:$TESTNIM,6,27 --def $SILENT -skForVar\tabsurd_nesting.lev1.i\tint - -> idetools --track:$TESTNIM,21,33 --def $SILENT -skForVar\tabsurd_nesting.lev1.lev1.lev3.lev4.i\tint - -> idetools --track:$TESTNIM,24,8 --def $SILENT -skProc\tabsurd_nesting.lev1.lev1.lev3.lev4\tproc \(string\) - -> idetools --track:$TESTNIM,4,13 --def $SILENT -skParam\tabsurd_nesting.lev1.t1\tstring - -> idetools --track:$TESTNIM,4,13 --def $SILENT -skParam\tabsurd_nesting.lev1.t1\tstring - -> idetools --track:$TESTNIM,19,19 --def $SILENT -skParam\tabsurd_nesting.lev1.lev2.lev3.lev4.t4\tstring - diff --git a/tests/caas/basic-recompile.txt b/tests/caas/basic-recompile.txt deleted file mode 100644 index 620e0c059..000000000 --- a/tests/caas/basic-recompile.txt +++ /dev/null @@ -1,10 +0,0 @@ -main.nim -> c --verbosity:0 --hints:on -SuccessX -# The "Processing" string will be found always in proc mode since each -# compilation command will generate it. We need to test it only in Caas mode to -# verify the server is not recompiling again the file. -CaasRun > c --verbosity:0 --hints:on -CaasRun ! Processing -CaasRun SuccessX - diff --git a/tests/caas/compile-suggest.txt b/tests/caas/compile-suggest.txt deleted file mode 100644 index 378320014..000000000 --- a/tests/caas/compile-suggest.txt +++ /dev/null @@ -1,7 +0,0 @@ -main.nim -> c --verbosity:0 --hints:on -SuccessX -> idetools --trackDirty:main_dirty.nim,$TESTNIM,12,7 --suggest $SILENT -skField\tx -skField\ty - diff --git a/tests/caas/compile-then-def.txt b/tests/caas/compile-then-def.txt deleted file mode 100644 index 72ba46b04..000000000 --- a/tests/caas/compile-then-def.txt +++ /dev/null @@ -1,11 +0,0 @@ -main.nim -> c --verbosity:0 --hints:on -SuccessX - -> idetools --track:$TESTNIM,5,18 --def --verbosity:0 --hints:on -strutils.toUpper -! SuccessX - -> idetools --track:$TESTNIM,5,18 --def --verbosity:0 --hints:on -strutils.toUpper -! SuccessX diff --git a/tests/caas/completion_dot_syntax.txt b/tests/caas/completion_dot_syntax.txt deleted file mode 100644 index 4a975e5df..000000000 --- a/tests/caas/completion_dot_syntax.txt +++ /dev/null @@ -1,9 +0,0 @@ -completion_dot_syntax_main.nim -> idetools --track:$TESTNIM,24,15 --def -def\tskProc\t$MODULE.echoRemainingDollars -> idetools --trackDirty:completion_dot_syntax_dirty.nim,$TESTNIM,25,12 --suggest -sug\tskProc\techoRemainingDollars -# The suggestion should not mention the other echoRemaining* variants. -!echoRemainingEuros -!echoRemainingBugs - diff --git a/tests/caas/completion_dot_syntax_dirty.nim b/tests/caas/completion_dot_syntax_dirty.nim deleted file mode 100644 index 6237c4e79..000000000 --- a/tests/caas/completion_dot_syntax_dirty.nim +++ /dev/null @@ -1,25 +0,0 @@ -import strutils - -# Verifies if the --suggestion switch differentiates types for dot notation. - -type - TDollar = distinct int - TEuro = distinct int - -proc echoRemainingDollars(amount: TDollar) = - echo "You have $1 dollars" % [$int(amount)] - -proc echoRemainingEuros(amount: TEuro) = - echo "You have $1 euros" % [$int(amount)] - -proc echoRemainingBugs() = - echo "You still have bugs" - -proc main = - var - d: TDollar - e: TEuro - d = TDollar(23) - e = TEuro(32) - d.echoRemainingDollars() - e.echoRemai diff --git a/tests/caas/completion_dot_syntax_main.nim b/tests/caas/completion_dot_syntax_main.nim deleted file mode 100644 index 0be8c7f4f..000000000 --- a/tests/caas/completion_dot_syntax_main.nim +++ /dev/null @@ -1,24 +0,0 @@ -import strutils - -# Verifies if the --suggestion switch differentiates types for dot notation. - -type - TDollar = distinct int - TEuro = distinct int - -proc echoRemainingDollars(amount: TDollar) = - echo "You have $1 dollars" % [$int(amount)] - -proc echoRemainingEuros(amount: TEuro) = - echo "You have $1 euros" % [$int(amount)] - -proc echoRemainingBugs() = - echo "You still have bugs" - -proc main = - var - d: TDollar - e: TEuro - d = TDollar(23) - e = TEuro(32) - d.echoRemainingDollars() diff --git a/tests/caas/def-def-compile.txt b/tests/caas/def-def-compile.txt deleted file mode 100644 index 21d5ea962..000000000 --- a/tests/caas/def-def-compile.txt +++ /dev/null @@ -1,12 +0,0 @@ -main.nim -> idetools --track:$TESTNIM,5,18 --def --verbosity:0 --hints:on -strutils.toUpper -! SuccessX - -> idetools --track:$TESTNIM,5,18 --def --verbosity:0 --hints:on -strutils.toUpper -! SuccessX - -> c --verbosity:0 --hints:on -SuccessX - diff --git a/tests/caas/def-then-compile.txt b/tests/caas/def-then-compile.txt deleted file mode 100644 index 2214bf02c..000000000 --- a/tests/caas/def-then-compile.txt +++ /dev/null @@ -1,8 +0,0 @@ -main.nim -> idetools --track:$TESTNIM,5,18 --def --verbosity:0 --hints:on -strutils.toUpper -! SuccessX - -> c --verbosity:0 --hints:on -SuccessX - diff --git a/tests/caas/forward_declarations.nim b/tests/caas/forward_declarations.nim deleted file mode 100644 index 177d82f20..000000000 --- a/tests/caas/forward_declarations.nim +++ /dev/null @@ -1,15 +0,0 @@ -# This example shows that idetools returns an empty signature for a forward -# declared proc in proc/symproc runs, but correctly returns the full signature -# in caas mode. - -proc echoHello(text: string) - -proc testForward() = - echo "T" - echoHello("T") - -proc echoHello(text: string) = - echo "Hello Mr." & text - -when isMainModule: - testForward() diff --git a/tests/caas/forward_declarations.txt b/tests/caas/forward_declarations.txt deleted file mode 100644 index b1695b9c7..000000000 --- a/tests/caas/forward_declarations.txt +++ /dev/null @@ -1,9 +0,0 @@ -forward_declarations.nim - -> idetools --track:$TESTNIM,9,5 --def $SILENT -skProc -proc \(string\) - -> idetools --track:$TESTNIM,5,9 --def $SILENT -skProc -proc \(string\) diff --git a/tests/caas/forward_usages.txt b/tests/caas/forward_usages.txt deleted file mode 100644 index 05ef517dc..000000000 --- a/tests/caas/forward_usages.txt +++ /dev/null @@ -1,17 +0,0 @@ -forward_declarations.nim - -> c --verbosity:0 --hints:on -SuccessX - -# None of the following return three instances of the echoHello proc, the first -# being the forward declaration, the second being the usage inside testForward, -# and the third being the actual implementation. - -> idetools --track:$TESTNIM,5,5 --usages $SILENT -skProc.*\n.*skProc.*\n.*skProc - -> idetools --track:$TESTNIM,9,5 --usages $SILENT -skProc.*\n.*skProc.*\n.*skProc - -> idetools --track:$TESTNIM,11,5 --usages $SILENT -skProc.*\n.*skProc.*\n.*skProc diff --git a/tests/caas/idetools_api.nim b/tests/caas/idetools_api.nim deleted file mode 100644 index 281e562d7..000000000 --- a/tests/caas/idetools_api.nim +++ /dev/null @@ -1,84 +0,0 @@ -import unicode, sequtils, macros, re - -proc test_enums() = - var o: Tfile - if o.open("files " & "test.txt", fmWrite): - o.write("test") - o.close() - -proc test_iterators(filename = "tests.nim") = - let - input = readFile(filename) - letters = toSeq(runes(string(input))) - for letter in letters: echo int(letter) - -const SOME_SEQUENCE = @[1, 2] -type - bad_string = distinct string - TPerson = object of TObject - name*: bad_string - age: int - -proc adder(a, b: int): int = - result = a + b - -type - PExpr = ref object of TObject ## abstract base class for an expression - PLiteral = ref object of PExpr - x: int - PPlusExpr = ref object of PExpr - a, b: PExpr - -# watch out: 'eval' relies on dynamic binding -method eval(e: PExpr): int = - # override this base method - quit "to override!" - -method eval(e: PLiteral): int = e.x -method eval(e: PPlusExpr): int = eval(e.a) + eval(e.b) - -proc newLit(x: int): PLiteral = PLiteral(x: x) -proc newPlus(a, b: PExpr): PPlusExpr = PPlusExpr(a: a, b: b) - -echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4))) - -proc findVowelPosition(text: string) = - var found = -1 - block loops: - for i, letter in pairs(text): - for j in ['a', 'e', 'i', 'o', 'u']: - if letter == j: - found = i - break loops # leave both for-loops - echo found - -findVowelPosition("Zerg") # should output 1, position of vowel. - -macro expect*(exceptions: varargs[expr], body: stmt): stmt {.immediate.} = - ## Expect docstrings - let exp = callsite() - template expectBody(errorTypes, lineInfoLit: expr, - body: stmt): NimNode {.dirty.} = - try: - body - assert false - except errorTypes: - nil - - var body = exp[exp.len - 1] - - var errorTypes = newNimNode(nnkBracket) - for i in countup(1, exp.len - 2): - errorTypes.add(exp[i]) - - result = getAst(expectBody(errorTypes, exp.lineinfo, body)) - -proc err = - raise newException(EArithmetic, "some exception") - -proc testMacro() = - expect(EArithmetic): - err() - -testMacro() -let notAModule = re"(\w+)=(.*)" diff --git a/tests/caas/idetools_api.txt b/tests/caas/idetools_api.txt deleted file mode 100644 index 035590dc3..000000000 --- a/tests/caas/idetools_api.txt +++ /dev/null @@ -1,59 +0,0 @@ -idetools_api.nim -> c --verbosity:0 --hints:on -SuccessX -> idetools --track:$TESTNIM,4,11 --def $SILENT -def\tskType\tsystem.TFile\tTFile -> idetools --track:$TESTNIM,5,7 --def $SILENT -def\tskProc\tsystem.Open\tproc \(var TFile, string, TFileMode, int\): bool -> idetools --track:$TESTNIM,5,21 --def $SILENT -def\tskProc\tsystem.\&\tproc \(string, string\): string\{.noSideEffect.\} -> idetools --track:$TESTNIM,5,38 --def $SILENT -def\tskEnumField\tsystem.TFileMode.fmWrite\tTFileMode -> idetools --track:$TESTNIM,7,6 --def $SILENT -def\tskProc\tsystem.Close\tproc \(TFile\) -> idetools --track:$TESTNIM,12,23 --def $SILENT -def\tskIterator\tunicode.runes\titerator \(string\): TRune -> idetools --track:$TESTNIM,12,15 --def $SILENT -def\tskTemplate\tsequtils.toSeq\tproc \(expr\): expr -> idetools --track:$TESTNIM,15,7 --def $SILENT - -# ProcRun mode will fail the next line, because the type is returned empty. -def\tskConst\t$MODULE.SOME_SEQUENCE\tseq\[int\]\t -> idetools --track:$TESTNIM,15,23 --def $SILENT -def\tskProc\tsystem.@\tproc \(array\[IDX, T\]\): seq\[T\]\{.noSideEffect.\} -> idetools --track:$TESTNIM,17,3 --def $SILENT - -# ProcRun mode will fail the next line, because the type is returned empty. -def\tskType\t$MODULE.bad_string\tbad_string\t -> idetools --track:$TESTNIM,11,24 --def $SILENT -def\tskParam\t$MODULE.test_iterators.filename\tstring -> idetools --track:$TESTNIM,6,5 --def $SILENT -def\tskVar\t$MODULE.test_enums.o\tTFile -> idetools --track:$TESTNIM,12,34 --def $SILENT -def\tskLet\t$MODULE.test_iterators.input\tTaintedString -> idetools --track:$TESTNIM,13,35 --def $SILENT -def\tskForVar\t$MODULE.test_iterators.letter\tTRune -> idetools --track:$TESTNIM,23,3 --def $SILENT -def\tskResult\t$MODULE.adder.result\tint -> idetools --track:$TESTNIM,19,6 --def $SILENT - -# ProcRun mode will fail the next line, because the type is returned empty. -def\tskField\t$MODULE.TPerson.name\tbad_string\t - -> idetools --track:$TESTNIM,43,7 --def $SILENT -def\tskMethod\t$MODULE.eval\tproc \(PPlusExpr\): int\t - -> idetools --track:$TESTNIM,47,8 --def $SILENT -def\tskLabel\t$MODULE.findVowelPosition.loops\t\t -# For some reason the use of the label with break displaces its position. -> idetools --track:$TESTNIM,52,16 --def $SILENT -def\tskLabel\t$MODULE.findVowelPosition.loops\t\t - -# Displaced macro usage by one character. -> idetools --track:$TESTNIM,80,2 --def $SILENT -def\tskMacro\t$MODULE.expect\tproc \(varargs\[expr\], stmt\): stmt\t - -# The syntax for extended raw string literals should not be returned as module -# but as the proc re() inside the re module. -> idetools --track:$TESTNIM,84,17 --def $SILENT -!def\tskModule diff --git a/tests/caas/imported.nim b/tests/caas/imported.nim deleted file mode 100644 index a4bc5c0e6..000000000 --- a/tests/caas/imported.nim +++ /dev/null @@ -1,3 +0,0 @@ -proc `+++`*(a,b: string): string = - return a & " " & b - diff --git a/tests/caas/issue_416_template_shift.nim b/tests/caas/issue_416_template_shift.nim deleted file mode 100644 index d52f611d6..000000000 --- a/tests/caas/issue_416_template_shift.nim +++ /dev/null @@ -1,17 +0,0 @@ -import unicode, sequtils - -proc test() = - let input = readFile("weird.nim") - for letter in runes(string(input)): - echo int(letter) - -when 1 > 0: - proc failtest() = - let - input = readFile("weird.nim") - letters = toSeq(runes(string(input))) - for letter in letters: - echo int(letter) - -when isMainModule: - test() diff --git a/tests/caas/issue_416_template_shift.txt b/tests/caas/issue_416_template_shift.txt deleted file mode 100644 index e911c1360..000000000 --- a/tests/caas/issue_416_template_shift.txt +++ /dev/null @@ -1,14 +0,0 @@ -issue_416_template_shift.nim -> c --verbosity:0 --hints:on -SuccessX -> idetools --track:$TESTNIM,12,28 --def $SILENT -def\tskType\tsystem.string\tstring -> idetools --track:$TESTNIM,12,35 --def $SILENT -def\tskLet\t$MODULE.failtest.input\tTaintedString - -# The following fail because they seem shifted one column to the right. -> idetools --track:$TESTNIM,12,16 --def $SILENT -def\tskTemplate\tsequtils.toSeq\tproc \(expr\): expr -> idetools --track:$TESTNIM,12,22 --def $SILENT -def\tskIterator\tunicode.runes\titerator \(string\): TRune - diff --git a/tests/caas/issue_452_export_shift.nim b/tests/caas/issue_452_export_shift.nim deleted file mode 100644 index 46cff6241..000000000 --- a/tests/caas/issue_452_export_shift.nim +++ /dev/null @@ -1,8 +0,0 @@ -const - VERSION_STR1* = "0.5.0" ## Idetools shifts this one column. - VERSION_STR2 = "0.5.0" ## This one is ok. - VERSION_STR3* = "0.5.0" ## Bad. - VERSION_STR4 = "0.5.0" ## Ok. - -proc forward1*(): string = result = "" -proc forward2(): string = result = "" diff --git a/tests/caas/issue_452_export_shift.txt b/tests/caas/issue_452_export_shift.txt deleted file mode 100644 index 4676ed71e..000000000 --- a/tests/caas/issue_452_export_shift.txt +++ /dev/null @@ -1,11 +0,0 @@ -issue_452_export_shift.nim -> c --verbosity:0 --hints:on -SuccessX -> idetools --track:$TESTNIM,2,2 --def $SILENT -def\tskConst\t$MODULE.VERSION_STR1\tstring -> idetools --track:$TESTNIM,3,2 --def $SILENT -def\tskConst\t$MODULE.VERSION_STR2\tstring -> idetools --track:$TESTNIM,7,5 --def $SILENT -def\tskProc\t$MODULE.forward1\tproc \(\): string\t -> idetools --track:$TESTNIM,8,5 --def $SILENT -def\tskProc\t$MODULE.forward2\tproc \(\): string\t diff --git a/tests/caas/issue_477_dynamic_dispatch.nim b/tests/caas/issue_477_dynamic_dispatch.nim deleted file mode 100644 index 6e6b21ef0..000000000 --- a/tests/caas/issue_477_dynamic_dispatch.nim +++ /dev/null @@ -1,19 +0,0 @@ -type - TThing = object of TObject - TUnit = object of TThing - x: int - -method collide(a, b: TThing) {.inline.} = - quit "to override!" - -method collide(a: TThing, b: TUnit) {.inline.} = - echo "collide1" - -method collide(a: TUnit, b: TThing) {.inline.} = - echo "collide2" - -var - a, b: TUnit - -when isMainModule: - collide(a, b) # output: 2 diff --git a/tests/caas/issue_477_dynamic_dispatch.txt b/tests/caas/issue_477_dynamic_dispatch.txt deleted file mode 100644 index 12fd750de..000000000 --- a/tests/caas/issue_477_dynamic_dispatch.txt +++ /dev/null @@ -1,5 +0,0 @@ -issue_477_dynamic_dispatch.nim -> c --run -SuccessX -> idetools --track:issue_477_dynamic_dispatch.nim,19,5 --def $SILENT -def\tskMethod\tissue_477_dynamic_dispatch.collide\tproc \(TUnit, TThing\)\{.inline.\} diff --git a/tests/caas/its_full_of_procs.nim b/tests/caas/its_full_of_procs.nim deleted file mode 100644 index 8f8b66764..000000000 --- a/tests/caas/its_full_of_procs.nim +++ /dev/null @@ -1,29 +0,0 @@ -import unicode, sequtils - -# This example shows that idetools returns proc as signature for everything -# which can be called. While a clever person would use the second column to -# differentiate between procs, methods and others, why does the output contain -# incorrect information? - -type - TThing = object of TObject - TUnit = object of TThing - x: int - -method collide(a, b: TThing) {.inline.} = - quit "to override!" - -method collide(a: TThing, b: TUnit) {.inline.} = - echo "1" - -method collide(a: TUnit, b: TThing) {.inline.} = - echo "2" - -var - a, b: TUnit - -let - input = readFile("its_full_of_procs.nim") - letters = toSeq(runes(string(input))) - -collide(a, b) # output: 2 diff --git a/tests/caas/its_full_of_procs.txt b/tests/caas/its_full_of_procs.txt deleted file mode 100644 index 31a2d3baa..000000000 --- a/tests/caas/its_full_of_procs.txt +++ /dev/null @@ -1,20 +0,0 @@ -its_full_of_procs.nim - -> idetools --track:$TESTNIM,26,15 --def $SILENT -skProc -proc \( - -> idetools --track:$TESTNIM,27,21 --def $SILENT -skIterator -iterator \( -!proc \( - -> idetools --track:$TESTNIM,29,0 --def $SILENT -skMethod -method \( -!proc \( - -> idetools --track:$TESTNIM,27,15 --def $SILENT -skTemplate -template \( -!proc \( diff --git a/tests/caas/main.nim b/tests/caas/main.nim deleted file mode 100644 index fafeff93b..000000000 --- a/tests/caas/main.nim +++ /dev/null @@ -1,7 +0,0 @@ -import imported, strutils - -proc main = - var t1 = "text" - var t2 = t1.toUpper - echo(t1 +++ t2) - diff --git a/tests/caas/main_dirty.nim b/tests/caas/main_dirty.nim deleted file mode 100644 index 95fb6c624..000000000 --- a/tests/caas/main_dirty.nim +++ /dev/null @@ -1,14 +0,0 @@ -import imported, strutils - -type - TFoo = object - x: int - y: string - -proc main = - var t1 = "text" - var t2 = t1.toUpper - var foo = TFoo(x: 10, y: "test") - foo. - echo(t1 +++ t2) - diff --git a/tests/caas/suggest-compile.txt b/tests/caas/suggest-compile.txt deleted file mode 100644 index a322908ac..000000000 --- a/tests/caas/suggest-compile.txt +++ /dev/null @@ -1,13 +0,0 @@ -main.nim -# This example shows how the suggest feature can be used on a partial file -# using the --trackDirty switch. -> idetools --trackDirty:main_dirty.nim,$TESTNIM,12,7 --suggest $SILENT -skField\tx -skField\ty -# Repeating the query in caas should work always and retrieve same output. -CaasRun > idetools --trackDirty:main_dirty.nim,$TESTNIM,12,7 --suggest $SILENT -CaasRun skField\tx -CaasRun skField\ty -> c --verbosity:0 --hints:on -SuccessX - diff --git a/tests/caas/suggest-invalid-source.txt b/tests/caas/suggest-invalid-source.txt deleted file mode 100644 index 7f8f1213d..000000000 --- a/tests/caas/suggest-invalid-source.txt +++ /dev/null @@ -1,26 +0,0 @@ -main_dirty.nim -# A variant of the suggest-compile.txt, instead of using a "base" correct -# source, this one uses the "broken" main_dirty.nim which won't compile. The -# test tries to stress idetools to still provide a valid answer if possible, -# and at least provide the same output with repeated queries rather than dying -# after the first compilation error. - -# The first query should work and provide valid suggestions. -> idetools --track:$TESTNIM,12,6 --suggest $SILENT -skField\tx -skField\ty - -# Repeating the query should work too. -> idetools --track:$TESTNIM,12,6 --suggest $SILENT -skField\tx -skField\ty - -# Expect now a compilation failure. -> c -!SuccessX -invalid indentation - -# Repeating suggestions *after broken compilation* should work too. -> idetools --track:$TESTNIM,12,6 --suggest $SILENT -skField\tx -skField\ty diff --git a/tests/casestmt/t7699.nim b/tests/casestmt/t7699.nim index ea08388eb..1354551c1 100644 --- a/tests/casestmt/t7699.nim +++ b/tests/casestmt/t7699.nim @@ -1,6 +1,6 @@ discard """ - line: 13 errormsg: "case statement cannot work on enums with holes for computed goto" + line: 13 """ type diff --git a/tests/casestmt/tcaseexpr1.nim b/tests/casestmt/tcaseexpr1.nim index 24543f1b8..4fdac8191 100644 --- a/tests/casestmt/tcaseexpr1.nim +++ b/tests/casestmt/tcaseexpr1.nim @@ -1,13 +1,17 @@ discard """ - file: "tcaseexpr1.nim" - - line: 29 errormsg: "type mismatch: got <string> but expected 'int'" + line: 33 + file: "tcaseexpr1.nim" - line: 23 errormsg: "not all cases are covered" + line: 27 + file: "tcaseexpr1.nim" """ +# NOTE: This spec is wrong. Spec doesn't support multiple error +# messages. The first one is simply overridden by the second one. +# This just has never been noticed. + type E = enum A, B, C @@ -27,4 +31,3 @@ var t1 = case x: var t2 = case x: of A: 10 of B, C: "23" - diff --git a/tests/casestmt/tcaseoverlaprange.nim b/tests/casestmt/tcaseoverlaprange.nim index 3527c9385..e9651c69f 100644 --- a/tests/casestmt/tcaseoverlaprange.nim +++ b/tests/casestmt/tcaseoverlaprange.nim @@ -1,6 +1,6 @@ discard """ - line: 13 errormsg: "duplicate case label" + line: 13 """ type diff --git a/tests/casestmt/tcaseoverlaprange2.nim b/tests/casestmt/tcaseoverlaprange2.nim index 4a9479a5f..4a1cb3ea6 100644 --- a/tests/casestmt/tcaseoverlaprange2.nim +++ b/tests/casestmt/tcaseoverlaprange2.nim @@ -1,6 +1,6 @@ discard """ - line: 13 errormsg: "duplicate case label" + line: 13 """ diff --git a/tests/casestmt/tcasestmt.nim b/tests/casestmt/tcasestmt.nim index 333700197..465080e84 100644 --- a/tests/casestmt/tcasestmt.nim +++ b/tests/casestmt/tcasestmt.nim @@ -1,6 +1,5 @@ discard """ - file: "tcasestmt.nim" - output: +output: ''' Not found! Found! @@ -226,4 +225,4 @@ block tcasestm: "invalid Y".quit(3) true else: raise newException(ValueError, "Invalid") - )) \ No newline at end of file + )) diff --git a/tests/ccgbugs/t8616.nim b/tests/ccgbugs/t8616.nim index 54068652a..5fd940d3b 100644 --- a/tests/ccgbugs/t8616.nim +++ b/tests/ccgbugs/t8616.nim @@ -1,4 +1,4 @@ import pkg8616 / scheduler -when isMainModule: +when true: init() diff --git a/tests/ccgbugs/t8781.nim b/tests/ccgbugs/t8781.nim index 1fa8ec8a5..884c6962a 100644 --- a/tests/ccgbugs/t8781.nim +++ b/tests/ccgbugs/t8781.nim @@ -18,7 +18,7 @@ type of false: region: float -when isMainModule: +when true: let r = 1.5 let a = TypeOne(animatedU: true, animated: false, diff --git a/tests/ccgbugs/tcgbug.nim b/tests/ccgbugs/tcgbug.nim index ffaa91ff3..eda475d4f 100644 --- a/tests/ccgbugs/tcgbug.nim +++ b/tests/ccgbugs/tcgbug.nim @@ -1,6 +1,6 @@ discard """ - file: "tcgbug.nim" - output: '''success +output: ''' +success M1 M2 ''' """ @@ -74,5 +74,5 @@ proc newMyObjectRef(kind: MyKind, val: string): MyObjectRef = of M2: result.b = parseFloat(val) of M3: result.c = val - -echo newMyObject(M1, "2").kind, " ", newMyObjectRef(M2, "3").kind \ No newline at end of file + +echo newMyObject(M1, "2").kind, " ", newMyObjectRef(M2, "3").kind diff --git a/tests/ccgbugs/tconstobj.nim b/tests/ccgbugs/tconstobj.nim deleted file mode 100644 index 51cf661ee..000000000 --- a/tests/ccgbugs/tconstobj.nim +++ /dev/null @@ -1,16 +0,0 @@ -discard """ - output: '''(FirstName: "James", LastName: "Franco")''' -""" - -# bug #1547 -import tables - -type Person* = object - FirstName*: string - LastName*: string - -let people = { - "001": Person(FirstName: "James", LastName: "Franco") -}.toTable() - -echo people["001"] diff --git a/tests/ccgbugs/tgeneric_closure.nim b/tests/ccgbugs/tgeneric_closure.nim index bb3b924b9..9f3c5b446 100644 --- a/tests/ccgbugs/tgeneric_closure.nim +++ b/tests/ccgbugs/tgeneric_closure.nim @@ -15,7 +15,7 @@ type proc mult(x:int, y:var int) = y = 2 * x -when isMainModule: +when true: var input = 1 var output = 0 diff --git a/tests/ccgbugs/tgeneric_smallobj_asgn_opt.nim b/tests/ccgbugs/tgeneric_smallobj_asgn_opt.nim index 919dc3fc1..3788b9985 100644 --- a/tests/ccgbugs/tgeneric_smallobj_asgn_opt.nim +++ b/tests/ccgbugs/tgeneric_smallobj_asgn_opt.nim @@ -1,5 +1,5 @@ discard """ - output: '''false''' + output: "done generic smallobj asgn opt" """ # bug #5402 @@ -23,4 +23,5 @@ proc newListOfContainers[T](): ListOfContainers[T] = result.list = initDoublyLinkedList[Container[T]]() let q = newListOfContainers[int64]() -echo q.contains(123) +if not q.contains(123): + echo "done generic smallobj asgn opt" diff --git a/tests/ccgbugs/tmarkerproc_regression.nim b/tests/ccgbugs/tmarkerproc_regression.nim index 99b38e3ec..3b606b834 100644 --- a/tests/ccgbugs/tmarkerproc_regression.nim +++ b/tests/ccgbugs/tmarkerproc_regression.nim @@ -1,5 +1,5 @@ discard """ - output: "done" + output: "done markerproc regression" """ type @@ -42,6 +42,6 @@ proc main = let expected = $i & "some longer text here " & $i if a[i].ver.string != expected: quit "bug!" - echo "done" + echo "done markerproc regression" main() diff --git a/tests/ccgbugs/tmissingbracket.nim b/tests/ccgbugs/tmissingbracket.nim index d54983860..468e13366 100644 --- a/tests/ccgbugs/tmissingbracket.nim +++ b/tests/ccgbugs/tmissingbracket.nim @@ -1,6 +1,8 @@ discard """ - output: '''Subobject test called -5''' +output: ''' +Subobject test called +5 +''' """ type @@ -49,4 +51,3 @@ var a: SubObject a.test() echo a.t - diff --git a/tests/ccgbugs/tmissinginit.nim b/tests/ccgbugs/tmissinginit.nim index b4087008a..8806a2f21 100644 --- a/tests/ccgbugs/tmissinginit.nim +++ b/tests/ccgbugs/tmissinginit.nim @@ -27,4 +27,4 @@ echo bug()[0] echo bug()[0] echo bug()[0] -when isMainModule: test() +test() diff --git a/tests/ccgbugs/tobjconstr_bad_aliasing.nim b/tests/ccgbugs/tobjconstr_bad_aliasing.nim index ea51ecacb..9f6045364 100644 --- a/tests/ccgbugs/tobjconstr_bad_aliasing.nim +++ b/tests/ccgbugs/tobjconstr_bad_aliasing.nim @@ -22,5 +22,4 @@ proc dosomething(): seq[TThing] = result = @[TThing(data: 10, children: result)] -when isMainModule: - echo($dosomething()[0]) +echo($dosomething()[0]) diff --git a/tests/clearmsg/tconsttypemismatch.nim b/tests/clearmsg/tconsttypemismatch.nim index edf480348..727bfbffb 100644 --- a/tests/clearmsg/tconsttypemismatch.nim +++ b/tests/clearmsg/tconsttypemismatch.nim @@ -1,8 +1,7 @@ discard """ + errormsg: "type mismatch" file: "tconsttypemismatch.nim" line: 7 - errormsg: "type mismatch" """ # bug #2252 const foo: int = 1000 / 30 - diff --git a/tests/clearmsg/tmacroerrorproc.nim b/tests/clearmsg/tmacroerrorproc.nim index cd9b15e25..86726af72 100644 --- a/tests/clearmsg/tmacroerrorproc.nim +++ b/tests/clearmsg/tmacroerrorproc.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "Expected a node of kind nnkCharLit, got nnkCommand" file: "tmacroerrorproc.nim" line: 13 - errormsg: "Expected a node of kind nnkCharLit, got nnkCommand" """ # issue #4915 import macros diff --git a/tests/closure/tclosure.nim b/tests/closure/tclosure.nim index c213d6a4b..cfef4193a 100644 --- a/tests/closure/tclosure.nim +++ b/tests/closure/tclosure.nim @@ -33,6 +33,7 @@ foo88 11 @[1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1] ''' +joinable: false """ diff --git a/tests/closure/tinvalidclosure.nim b/tests/closure/tinvalidclosure.nim index 4e5f61f06..b2d8bd28d 100644 --- a/tests/closure/tinvalidclosure.nim +++ b/tests/closure/tinvalidclosure.nim @@ -1,6 +1,6 @@ discard """ - line: 12 errormsg: "type mismatch: got <proc (x: int){.gcsafe, locks: 0.}>" + line: 12 """ proc ugh[T](x: T) {.nimcall.} = diff --git a/tests/closure/tinvalidclosure2.nim b/tests/closure/tinvalidclosure2.nim index 845559309..2d58f0215 100644 --- a/tests/closure/tinvalidclosure2.nim +++ b/tests/closure/tinvalidclosure2.nim @@ -1,6 +1,6 @@ discard """ - line: 10 errormsg: "illegal capture 'A'" + line: 10 """ proc outer() = diff --git a/tests/closure/tinvalidclosure3.nim b/tests/closure/tinvalidclosure3.nim index 31c4976f8..0cbdaf39e 100644 --- a/tests/closure/tinvalidclosure3.nim +++ b/tests/closure/tinvalidclosure3.nim @@ -1,6 +1,6 @@ discard """ - line: 9 errormsg: "illegal capture 'x'" + line: 9 """ proc outer(arg: string) = @@ -9,4 +9,4 @@ proc outer(arg: string) = echo "inner", x inner() -outer("abc") \ No newline at end of file +outer("abc") diff --git a/tests/closure/tnested.nim b/tests/closure/tnested.nim index f8d69011a..dbbe9ba58 100644 --- a/tests/closure/tnested.nim +++ b/tests/closure/tnested.nim @@ -1,6 +1,5 @@ discard """ - file: "tnested.nim" - output: ''' +output: ''' foo88 23 24foo 88 foo88 diff --git a/tests/cnstseq/tcnstseq.nim b/tests/cnstseq/tcnstseq.nim index e044b9f3f..5679a6e37 100644 --- a/tests/cnstseq/tcnstseq.nim +++ b/tests/cnstseq/tcnstseq.nim @@ -1,6 +1,5 @@ discard """ - file: "tcnstseq.nim" - output: ''' +output: ''' AngelikaAnneAnnaAnkaAnja AngelikaAnneAnnaAnkaAnja AngelikaAnneAnnaAnkaAnja diff --git a/tests/collections/tcollections.nim b/tests/collections/tcollections.nim index ff6673bba..2f8cfece7 100644 --- a/tests/collections/tcollections.nim +++ b/tests/collections/tcollections.nim @@ -1,7 +1,5 @@ discard """ - file: "tcollections.nim" - output: ''' -''' + output: "" """ import deques, sequtils diff --git a/tests/collections/tsets.nim b/tests/collections/thashsets.nim index cd4401511..cd4401511 100644 --- a/tests/collections/tsets.nim +++ b/tests/collections/thashsets.nim diff --git a/tests/collections/ttables.nim b/tests/collections/ttables.nim index 4d11f56f2..6798e5731 100644 --- a/tests/collections/ttables.nim +++ b/tests/collections/ttables.nim @@ -1,16 +1,16 @@ discard """ - file: "ttables.nim" - output: ''' -done +output: ''' +done tableadds And we get here 1 2 3 ''' +joinable: false """ import hashes, sequtils, tables - +# test should not be joined because it takes too long. block tableadds: proc main = var tab = newTable[string, string]() @@ -18,7 +18,7 @@ block tableadds: tab.add "key", "value " & $i main() - echo "done" + echo "done tableadds" block tcounttable: @@ -142,7 +142,7 @@ block tindexby: tbl2.add("bar", elem1) tbl2.add("baz", elem2) doAssert indexBy(@[elem1,elem2], proc(x: TElem): string = x.bar) == tbl2, "element table" - + block tableconstr: # Test if the new table constructor syntax works: diff --git a/tests/compilerapi/tcompilerapi.nim b/tests/compilerapi/tcompilerapi.nim index 30007eff0..2a7db04eb 100644 --- a/tests/compilerapi/tcompilerapi.nim +++ b/tests/compilerapi/tcompilerapi.nim @@ -15,7 +15,7 @@ import std / [os] proc main() = let std = findNimStdLibCompileTime() - var intr = createInterpreter("myscript.nim", [std, getAppDir()]) + var intr = createInterpreter("myscript.nim",[std, parentDir(currentSourcePath)]) intr.implementRoutine("*", "exposed", "addFloats", proc (a: VmArgs) = setResult(a, getFloat(a, 0) + getFloat(a, 1) + getFloat(a, 2)) ) @@ -51,4 +51,3 @@ block issue9180: evalString("echo 10+1") evalString("echo 10+2") - diff --git a/tests/concepts/tconcepts.nim b/tests/concepts/tconcepts.nim index dec1dafe0..d0bc76c20 100644 --- a/tests/concepts/tconcepts.nim +++ b/tests/concepts/tconcepts.nim @@ -1,6 +1,5 @@ discard """ - file: "tconcepts.nim" - output: ''' +output: ''' 10 20 int @@ -378,53 +377,53 @@ block tvectorspace: block tstack: template reject(e) = static: assert(not compiles(e)) - + type ArrayStack = object data: seq[int] - + proc push(s: var ArrayStack, item: int) = s.data.add item - + proc pop(s: var ArrayStack): int = return s.data.pop() - + type Stack[T] = concept var s s.push(T) s.pop() is T - + type ValueType = T const ValueTypeName = T.name.toUpperAscii - + proc genericAlgorithm[T](s: var Stack[T], y: T) = static: echo "INFERRED ", T.name echo "VALUE TYPE ", s.ValueType.name echo "VALUE TYPE NAME ", s.ValueTypeName - + s.push(y) echo s.pop - + proc implicitGeneric(s: var Stack): auto = static: echo "IMPLICIT INFERRED ", s.T.name, " ", Stack.T.name echo "IMPLICIT VALUE TYPE ", s.ValueType.name, " ", Stack.ValueType.name echo "IMPLICIT VALUE TYPE NAME ", s.ValueTypeName, " ", Stack.ValueTypeName - + return s.pop() - + var s = ArrayStack(data: @[]) - + s.push 10 s.genericAlgorithm 20 echo s.implicitGeneric - + reject s.genericAlgorithm "x" reject s.genericAlgorithm 1.0 reject "str".implicitGeneric reject implicitGeneric(10) - + import libs/[trie_database, trie] diff --git a/tests/concepts/texplain.nim b/tests/concepts/texplain.nim index 5c8e02440..ac0c972f5 100644 --- a/tests/concepts/texplain.nim +++ b/tests/concepts/texplain.nim @@ -63,8 +63,8 @@ texplain.nim(92, 5) NestedConcept: concept predicate failed expression: f(y) ''' - line: 138 errormsg: "type mismatch: got <MatchingType>" + line: 138 """ @@ -136,4 +136,3 @@ static: # finally, provide multiple nested explanations for failed matching # of regular concepts, even when the explain pragma is not used f(y) - diff --git a/tests/concepts/trandomvars.nim b/tests/concepts/trandomvars.nim index db41aa901..1f04b9ecf 100644 --- a/tests/concepts/trandomvars.nim +++ b/tests/concepts/trandomvars.nim @@ -41,7 +41,8 @@ proc lift1[A, B](f: proc(a: A): B, r: RandomVar[A]): ClosureVar[B] = return inner -when isMainModule: + +proc main() = proc sq(x: float): float = x * x let @@ -59,3 +60,4 @@ when isMainModule: echo rng.sample(u) echo rng.sample(t) +main() diff --git a/tests/concepts/trandom_vars.nim b/tests/concepts/trandomvars2.nim index 861e876a7..861e876a7 100644 --- a/tests/concepts/trandom_vars.nim +++ b/tests/concepts/trandomvars2.nim diff --git a/tests/constr/tconstr1.nim b/tests/constr/tconstr1.nim index b9cf5d00b..a169bf453 100644 --- a/tests/constr/tconstr1.nim +++ b/tests/constr/tconstr1.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "type mismatch" file: "tconstr1.nim" line: 25 - errormsg: "type mismatch" """ # Test array, record constructors @@ -26,5 +26,3 @@ const otherThings = [ # the same (s: "hi", x: 69, y: 45, z: 0.0, chars: {'a', 'b', 'c'}), (s: "hi", x: 69, y: 45, z: 1.0, chars: {'a'})] - - diff --git a/tests/constr/tconstr2.nim b/tests/constr/tconstr2.nim index b16be6c50..2557d7db9 100644 --- a/tests/constr/tconstr2.nim +++ b/tests/constr/tconstr2.nim @@ -1,5 +1,4 @@ discard """ - file: "tconstr2.nim" output: "69" """ # Test array, record constructors @@ -19,8 +18,5 @@ const (s: "hi", x: 69, y: 45, z: 0.0, chars: {'a', 'b', 'c'}), (s: "hi", x: 69, y: 45, z: 1.0, chars: {'a'})] -write(stdout, things[0].x) +writeLine(stdout, things[0].x) #OUT 69 - - - diff --git a/tests/constraints/tconstraints.nim b/tests/constraints/tconstraints.nim index 3c9fdc354..3ca01cfd5 100644 --- a/tests/constraints/tconstraints.nim +++ b/tests/constraints/tconstraints.nim @@ -1,6 +1,6 @@ discard """ - line: 16 errormsg: "type mismatch: got <int literal(232)>" + line: 16 """ proc myGenericProc[T: object|tuple|ptr|ref|distinct](x: T): string = @@ -14,5 +14,3 @@ var assert myGenericProc(x) == "(x: 0, y: 0)" assert myGenericProc(232) == "232" - - diff --git a/tests/constructors/t5965_1.nim b/tests/constructors/t5965_1.nim index 9f947f859..abf07b21c 100644 --- a/tests/constructors/t5965_1.nim +++ b/tests/constructors/t5965_1.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "incorrect object construction syntax" file: "t5965_1.nim" line: 10 - errormsg: "incorrect object construction syntax" """ type Foo = object diff --git a/tests/constructors/t5965_2.nim b/tests/constructors/t5965_2.nim index a3f7174c9..e04f1b715 100644 --- a/tests/constructors/t5965_2.nim +++ b/tests/constructors/t5965_2.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "incorrect object construction syntax" file: "t5965_2.nim" line: 10 - errormsg: "incorrect object construction syntax" """ type Foo = object diff --git a/tests/controlflow/tblock1.nim b/tests/controlflow/tblock1.nim index e3a780dfe..70c844513 100644 --- a/tests/controlflow/tblock1.nim +++ b/tests/controlflow/tblock1.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "undeclared identifier: \'ha\'" file: "tblock1.nim" line: 14 - errormsg: "undeclared identifier: \'ha\'" """ # check for forward label and # for failure when label is not declared @@ -14,5 +14,3 @@ proc main = break ha #ERROR main() - - diff --git a/tests/controlflow/tcontrolflow.nim b/tests/controlflow/tcontrolflow.nim index 9019e55b2..258f3f50d 100644 --- a/tests/controlflow/tcontrolflow.nim +++ b/tests/controlflow/tcontrolflow.nim @@ -85,13 +85,13 @@ block tnestif: if x == 0: write(stdout, "i == 0") if y == 0: - write(stdout, x) + writeLine(stdout, x) else: - write(stdout, y) + writeLine(stdout, y) elif x == 1: - write(stdout, "i == 1") + writeLine(stdout, "i == 1") elif x == 2: - write(stdout, "i == 2") + writeLine(stdout, "i == 2") else: - write(stdout, "looks like Python") + writeLine(stdout, "looks like Python") #OUT i == 2 diff --git a/tests/controlflow/tstatret.nim b/tests/controlflow/tstatret.nim index 8f43c5d8f..e0f816c7d 100644 --- a/tests/controlflow/tstatret.nim +++ b/tests/controlflow/tstatret.nim @@ -1,12 +1,9 @@ discard """ + errormsg: "unreachable statement after 'return' statement or '{.noReturn.}' proc" file: "tstatret.nim" line: 9 - errormsg: "unreachable statement after 'return' statement or '{.noReturn.}' proc" """ # no statement after return proc main() = return echo("huch?") #ERROR_MSG statement not allowed after - - - diff --git a/tests/converter/tconverter_unique_ptr.nim b/tests/converter/tconverter_unique_ptr.nim index 25b001d52..23c1a3d96 100644 --- a/tests/converter/tconverter_unique_ptr.nim +++ b/tests/converter/tconverter_unique_ptr.nim @@ -1,6 +1,5 @@ discard """ - file: "tconverter_unique_ptr.nim" targets: "c cpp" output: "" """ @@ -34,7 +33,7 @@ proc `=`*(m: var MySeq, m2: MySeq) = `=destroy`(m) m.len = m2.len - let bytes = m.len.int * sizeof(float) + let bytes = m.len.int * sizeof(float) if bytes > 0: m.data = cast[ptr UncheckedArray[float]](allocShared(bytes)) copyMem(m.data, m2.data, bytes) @@ -59,7 +58,7 @@ proc `[]`*(m: var MySeq; i: MyLen): var float {.inline.} = proc `[]=`*(m: var MySeq; i: MyLen, val: float) {.inline.} = m.data[i.int] = val -proc setTo(s: var MySeq, val: float) = +proc setTo(s: var MySeq, val: float) = for i in 0..<s.len.int: s.data[i] = val @@ -112,7 +111,7 @@ doAssert pu[0] == 2.0 doAssert: pu2[0] == 2.0 ##----------------------------------------------------------------------------------------- -## Bugs #9735 and #9736 +## Bugs #9735 and #9736 type ConstPtr*[T] = object ## This pointer makes it impossible to change underlying value diff --git a/tests/converter/tconverter_with_constraint.nim b/tests/converter/tconverter_with_constraint.nim index 793264434..ce5135586 100644 --- a/tests/converter/tconverter_with_constraint.nim +++ b/tests/converter/tconverter_with_constraint.nim @@ -1,8 +1,8 @@ discard """ + errormsg: "type mismatch: got <int>" file: "tconverter_with_constraint.nim" line: 20 - errormsg: "type mismatch: got <int>" """ type @@ -10,11 +10,11 @@ type converter to_mytype(m: int{lit}): MyType = m.MyType - + proc myproc(m: MyType) = echo m.int, ".MyType" -myproc(1) # call by literal is ok +myproc(1) # call by literal is ok var x: int = 12 -myproc(x) # should fail \ No newline at end of file +myproc(x) # should fail diff --git a/tests/deprecated/tnoannot.nim b/tests/deprecated/tnoannot.nim index 9cc5c7e06..ac168952e 100644 --- a/tests/deprecated/tnoannot.nim +++ b/tests/deprecated/tnoannot.nim @@ -1,6 +1,6 @@ discard """ - line: 7 errormsg: "annotation to deprecated not supported here" + line: 7 """ var foo* {.deprecated.} = 42 diff --git a/tests/deps/jester-#head/jester/patterns.nim b/tests/deps/jester-#head/jester/patterns.nim index 52b0d3a15..c827fbc7f 100644 --- a/tests/deps/jester-#head/jester/patterns.nim +++ b/tests/deps/jester-#head/jester/patterns.nim @@ -120,7 +120,7 @@ proc match*(pattern: Pattern, s: string): if s.len != i: result.matched = false -when isMainModule: +when true: let f = parsePattern("/show/@id/test/@show?/?") doAssert match(f, "/show/12/test/hallo/").matched doAssert match(f, "/show/2131726/test/jjjuuwąąss").matched diff --git a/tests/deps/jester-#head/jester/private/utils.nim b/tests/deps/jester-#head/jester/private/utils.nim index 66f0b37a6..16dce61fe 100644 --- a/tests/deps/jester-#head/jester/private/utils.nim +++ b/tests/deps/jester-#head/jester/private/utils.nim @@ -188,7 +188,7 @@ when not declared(normalizePath) and not declared(normalizedPath): result = path normalizePath(result) -when isMainModule: +when false: var r = {:}.newStringTable parseUrlQuery("FirstName=Mickey", r) echo r diff --git a/tests/deps/zip-0.2.1/zip/zipfiles.nim b/tests/deps/zip-0.2.1/zip/zipfiles.nim index ca1979488..274587df9 100644 --- a/tests/deps/zip-0.2.1/zip/zipfiles.nim +++ b/tests/deps/zip-0.2.1/zip/zipfiles.nim @@ -186,7 +186,7 @@ proc extractAll*(z: var ZipArchive, dest: string) = createDir(dest / file[0..file.rfind("/")]) extractFile(z, file, dest / file) -when not defined(testing) and isMainModule: +when not defined(testing) and true: var zip: ZipArchive if not zip.open("nim-0.11.0.zip"): raise newException(IOError, "opening zip failed") diff --git a/tests/destructor/tmatrix.nim b/tests/destructor/tmatrix.nim index a16bfa37b..b89b41a4c 100644 --- a/tests/destructor/tmatrix.nim +++ b/tests/destructor/tmatrix.nim @@ -52,6 +52,8 @@ proc matrix*(m, n: int, s: float): Matrix = for i in 0 ..< m * n: result.data[i] = s +proc len(m: Matrix): int = m.n * m.m + proc `[]`*(m: Matrix, i, j: int): float {.inline.} = ## Get a single element. m.data[i * m.n + j] @@ -67,24 +69,26 @@ proc `[]=`*(m: var Matrix, i, j: int, s: float) = proc `-`*(m: sink Matrix): Matrix = ## Unary minus result = m - for i in 0 ..< m.m: - for j in 0 ..< m.n: - result[i, j] = -m[i, j] + for i in 0 ..< result.m: + for j in 0 ..< result.n: + result[i, j] = -result[i, j] proc `+`*(a: sink Matrix; b: Matrix): Matrix = ## ``C = A + B`` - assert(b.m == a.m and b.n == a.n, "Matrix dimensions must agree.") + doAssert(b.m == a.m and b.n == a.n, "Matrix dimensions must agree.") + doAssert(a.len == b.len) # non destructive use before sink is ok result = a - for i in 0 ..< a.m: - for j in 0 ..< a.n: - result[i, j] = a[i, j] + b[i, j] + for i in 0 ..< result.m: + for j in 0 ..< result.n: + result[i, j] = result[i, j] + b[i, j] proc `-`*(a: sink Matrix; b: Matrix): Matrix = ## ``C = A - B`` assert(b.m == a.m and b.n == a.n, "Matrix dimensions must agree.") + doAssert(a.len == b.len) # non destructive use before sink is ok result = a - for i in 0 ..< a.m: - for j in 0 ..< a.n: + for i in 0 ..< result.m: + for j in 0 ..< result.n: result[i, j] = a[i, j] - b[i, j] proc info = diff --git a/tests/destructor/tmove_objconstr.nim b/tests/destructor/tmove_objconstr.nim index 26cc682b5..875f78283 100644 --- a/tests/destructor/tmove_objconstr.nim +++ b/tests/destructor/tmove_objconstr.nim @@ -36,7 +36,7 @@ proc pointlessWrapper(s: string): Data = proc main = var x = pointlessWrapper"test" -when isMainModule: +when true: main() # bug #985 @@ -109,7 +109,19 @@ proc myfunc(x, y: int): (MySeqNonCopyable, MySeqNonCopyable) = proc myfunc2(x, y: int): tuple[a: MySeqNonCopyable, b:int, c:MySeqNonCopyable] = var cc = newMySeq(y, 5.0) - (a: newMySeq(x, 1.0), b:0, c: cc) + (a: case x: + of 1: + let (z1, z2) = myfunc(x,y) + z2 + elif x > 5: raise newException(ValueError, "new error") + else: newMySeq(x, 1.0), + b: 0, + c: block: + var tmp = if y > 0: move(cc) else: newMySeq(1, 3.0) + tmp[0] = 5 + tmp + ) + let (seq1, seq2) = myfunc(2, 3) doAssert seq1.len == 2 @@ -122,4 +134,35 @@ doAssert seq3.len == 2 doAssert seq3[0] == 1.0 var seq4, seq5: MySeqNonCopyable -(seq4, i, seq5) = myfunc2(2, 3) \ No newline at end of file +(seq4, i, seq5) = myfunc2(2, 3) + +seq4 = block: + var tmp = newMySeq(4, 1.0) + tmp[0] = 3.0 + tmp + +doAssert seq4[0] == 3.0 + +import macros + +seq4 = + if i > 0: newMySeq(2, 5.0) + elif i < -100: raise newException(ValueError, "Parse Error") + else: newMySeq(2, 3.0) + +seq4 = + case (char) i: + of 'A', {'W'..'Z'}: newMySeq(2, 5.0) + of 'B': quit(-1) + else: + let (x1, x2, x3) = myfunc2(2, 3) + x3 + + +#------------------------------------------------------------ +#-- Move into array constructor +#------------------------------------------------------------ + +var ii = 1 +let arr2 = [newMySeq(2, 5.0), if i > 1: newMySeq(3, 1.0) else: newMySeq(0, 0.0)] +var seqOfSeq2 = @[newMySeq(2, 5.0), newMySeq(3, 1.0)] diff --git a/tests/destructor/turn_destroy_into_finalizer.nim b/tests/destructor/turn_destroy_into_finalizer.nim index f5b705593..1409c1c57 100644 --- a/tests/destructor/turn_destroy_into_finalizer.nim +++ b/tests/destructor/turn_destroy_into_finalizer.nim @@ -1,5 +1,6 @@ discard """ - output: '''true''' + output: "turn_destroy_into_finalizer works" + joinable: false """ type @@ -17,6 +18,9 @@ proc main = for i in 1..50_000: new(r) r.id = i - echo destroyed > 30_000 + if destroyed > 30_000: + echo "turn_destroy_into_finalizer works" + else: + echo "turn_destroy_into_finalizer failed: ", destroyed main() diff --git a/tests/discard/tdiscardable.nim b/tests/discard/tdiscardable.nim index a3dd966a0..81e17866a 100644 --- a/tests/discard/tdiscardable.nim +++ b/tests/discard/tdiscardable.nim @@ -1,10 +1,13 @@ discard """ output: ''' +tdiscardable 1 1 ''' """ +echo "tdiscardable" + # Test the discardable pragma proc p(x, y: int): int {.discardable.} = diff --git a/tests/discard/tillegaldiscard.nim b/tests/discard/tillegaldiscard.nim index 5e1a3f03e..757f4e727 100644 --- a/tests/discard/tillegaldiscard.nim +++ b/tests/discard/tillegaldiscard.nim @@ -1,6 +1,6 @@ discard """ - line: 9 errormsg: "illegal discard" + line: 9 """ proc pop[T](arg: T): T = diff --git a/tests/discard/tneedsdiscard.nim b/tests/discard/tneedsdiscard.nim index 8d59e7fec..7d2997b3f 100644 --- a/tests/discard/tneedsdiscard.nim +++ b/tests/discard/tneedsdiscard.nim @@ -1,6 +1,6 @@ discard """ - line: 10 errormsg: '''expression 'open(f, "arg.txt", fmRead, -1)' is of type 'bool' and has to be discarded; start of expression here: tneedsdiscard.nim(7, 2)''' + line: 10 """ proc p = diff --git a/tests/discard/tneedsdiscard_in_for.nim b/tests/discard/tneedsdiscard_in_for.nim index 5658f4ba2..499b06009 100644 --- a/tests/discard/tneedsdiscard_in_for.nim +++ b/tests/discard/tneedsdiscard_in_for.nim @@ -1,6 +1,6 @@ discard """ - line: 22 errormsg: '''expression 'premultiply(app.gradient[i])' is of type 'Rgba8' and has to be discarded''' + line: 22 """ # bug #9076 diff --git a/tests/distinct/tdistinct.nim b/tests/distinct/tdistinct.nim index 52728fc2b..70e586ded 100644 --- a/tests/distinct/tdistinct.nim +++ b/tests/distinct/tdistinct.nim @@ -1,9 +1,11 @@ discard """ output: ''' +tdistinct 25 ''' """ +echo "tdistinct" block tborrowdot: type @@ -18,8 +20,6 @@ block tborrowdot: bb.a = 90 bb.s = "abc" - - block tcurrncy: template Additive(typ: untyped) = proc `+`(x, y: typ): typ {.borrow.} @@ -53,8 +53,6 @@ block tcurrncy: DefineCurrency(TEuro, int) echo($( 12.TDollar + 13.TDollar )) #OUT 25 - - block tconsts: # bug #2641 diff --git a/tests/distinct/tnil.nim b/tests/distinct/tnil.nim index 16de38f60..5bdb97f37 100644 --- a/tests/distinct/tnil.nim +++ b/tests/distinct/tnil.nim @@ -1,6 +1,6 @@ discard """ - file: "tnil.nim" - output: '''1 +output: ''' +1 0 0 ''' diff --git a/tests/effects/teffects1.nim b/tests/effects/teffects1.nim index ef76c9130..767845cb4 100644 --- a/tests/effects/teffects1.nim +++ b/tests/effects/teffects1.nim @@ -1,6 +1,6 @@ discard """ - file: "system.nim" errormsg: "can raise an unlisted exception: ref IOError" + file: "system.nim" """ type @@ -17,4 +17,3 @@ proc lier(): int {.raises: [IO2Error].} = proc forw: int = raise newException(IOError, "arg") - diff --git a/tests/effects/teffects2.nim b/tests/effects/teffects2.nim index 0fa789869..e4b50aba5 100644 --- a/tests/effects/teffects2.nim +++ b/tests/effects/teffects2.nim @@ -1,6 +1,6 @@ discard """ - line: 19 errormsg: "can raise an unlisted exception: ref IOError" + line: 19 """ type @@ -17,4 +17,3 @@ proc lier(): int {.raises: [IOError].} = proc forw: int = raise newException(IOError, "arg") - diff --git a/tests/effects/teffects3.nim b/tests/effects/teffects3.nim index cbd11f722..ee5470c47 100644 --- a/tests/effects/teffects3.nim +++ b/tests/effects/teffects3.nim @@ -1,6 +1,6 @@ discard """ - line: 18 errormsg: "type mismatch" + line: 18 """ type @@ -16,4 +16,3 @@ proc raiser(): int {.tags: [TObj, WriteIoEffect].} = var o: TObjB o.fn = raiser - diff --git a/tests/effects/teffects4.nim b/tests/effects/teffects4.nim index 0025c10c5..88cc0efa9 100644 --- a/tests/effects/teffects4.nim +++ b/tests/effects/teffects4.nim @@ -1,6 +1,6 @@ discard """ - line: 23 errormsg: "type mismatch" + line: 23 """ type @@ -21,4 +21,3 @@ proc raiser(): int = var o: TObjB o.fn = raiser - diff --git a/tests/effects/tgcsafe.nim b/tests/effects/tgcsafe.nim index d146794b6..ff207df59 100644 --- a/tests/effects/tgcsafe.nim +++ b/tests/effects/tgcsafe.nim @@ -1,6 +1,6 @@ discard """ - line: 17 errormsg: "'mainUnsafe' is not GC-safe" + line: 17 cmd: "nim $target --hints:on --threads:on $options $file" """ diff --git a/tests/effects/tsidee1.nim b/tests/effects/tsidee1.nim index e486d32e7..ca6816561 100644 --- a/tests/effects/tsidee1.nim +++ b/tests/effects/tsidee1.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "\'SideEffectLyer\' can have side effects" file: "tsidee1.nim" line: 12 - errormsg: "\'SideEffectLyer\' can have side effects" """ var @@ -13,6 +13,3 @@ proc SideEffectLyer(x, y: int): int {.noSideEffect.} = #ERROR_MSG 'SideEffectLye return x + y + dontcare(x) echo SideEffectLyer(1, 3) - - - diff --git a/tests/effects/tsidee2.nim b/tests/effects/tsidee2.nim index 5ed541300..b2e5f3379 100644 --- a/tests/effects/tsidee2.nim +++ b/tests/effects/tsidee2.nim @@ -1,5 +1,4 @@ discard """ - file: "tsidee2.nim" output: "5" """ @@ -12,6 +11,3 @@ proc SideEffectLyer(x, y: int): int {.noSideEffect.} = return x + y + dontcare(x) echo SideEffectLyer(1, 3) #OUT 5 - - - diff --git a/tests/effects/tsidee3.nim b/tests/effects/tsidee3.nim index e15fbc3d1..c3801ba28 100644 --- a/tests/effects/tsidee3.nim +++ b/tests/effects/tsidee3.nim @@ -1,5 +1,4 @@ discard """ - file: "tsidee3.nim" output: "5" """ @@ -12,6 +11,3 @@ proc noSideEffect(x, y: int, p: proc (a: int): int {.noSideEffect.}): int {.noSi return x + y + dontcare(x) echo noSideEffect(1, 3, dontcare) #OUT 5 - - - diff --git a/tests/effects/tsidee4.nim b/tests/effects/tsidee4.nim index ecc79580c..d6c192cbf 100644 --- a/tests/effects/tsidee4.nim +++ b/tests/effects/tsidee4.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "'noSideEffect' can have side effects" file: "tsidee4.nim" line: 12 - errormsg: "'noSideEffect' can have side effects" """ var @@ -13,5 +13,3 @@ proc noSideEffect(x, y: int, p: proc (a: int): int {.noSideEffect.}): int {.noSi return x + y + dontcare(x) echo noSideEffect(1, 3, dontcare) #ERROR_MSG type mismatch - - diff --git a/tests/enum/tenumitems.nim b/tests/enum/tenumitems.nim index 6d13dd162..76f368f8a 100644 --- a/tests/enum/tenumitems.nim +++ b/tests/enum/tenumitems.nim @@ -1,9 +1,7 @@ discard """ - line: 7 errormsg: "attempting to call routine: 'items'" + line: 7 """ type a = enum b,c,d a.items() - - diff --git a/tests/errmsgs/t6483.nim b/tests/errmsgs/t6483.nim index 59ea6d7e2..0e977b36d 100644 --- a/tests/errmsgs/t6483.nim +++ b/tests/errmsgs/t6483.nim @@ -16,7 +16,7 @@ type variables: seq[VarItem] children: seq[VarScope] -when isMainModule: +when true: var scope1 = VarScope( variables: newSeq[VarItem](), children: newSeq[VarScope]() diff --git a/tests/errmsgs/t8339.nim b/tests/errmsgs/t8339.nim index f0a97658a..720e080c0 100644 --- a/tests/errmsgs/t8339.nim +++ b/tests/errmsgs/t8339.nim @@ -1,6 +1,6 @@ discard """ - line: 8 errormsg: "type mismatch: got <seq[int]> but expected 'seq[float]'" + line: 8 """ import sequtils diff --git a/tests/errmsgs/t9908_01.nim b/tests/errmsgs/t9908_01.nim new file mode 100644 index 000000000..b9d37b67b --- /dev/null +++ b/tests/errmsgs/t9908_01.nim @@ -0,0 +1,10 @@ +discard """ +errormsg: "ordinal type expected" +line: 10 +""" + +# https://github.com/nim-lang/Nim/issues/9908 + +type + X = enum + a = ("a", "b") diff --git a/tests/errmsgs/t9908_02.nim b/tests/errmsgs/t9908_02.nim new file mode 100644 index 000000000..7ff3d1ff7 --- /dev/null +++ b/tests/errmsgs/t9908_02.nim @@ -0,0 +1,10 @@ +discard """ +errormsg: "ordinal type expected" +line: 10 +""" + +# https://github.com/nim-lang/Nim/pull/9909#issuecomment-445519287 + +type + E = enum + myVal = 80.9 diff --git a/tests/errmsgs/tproper_stacktrace.nim b/tests/errmsgs/tproper_stacktrace.nim index 134946651..c0090a595 100644 --- a/tests/errmsgs/tproper_stacktrace.nim +++ b/tests/errmsgs/tproper_stacktrace.nim @@ -66,7 +66,7 @@ template verifyStackTrace*(expectedStackTrace: string, body: untyped) = -when isMainModule: +when true: # <-- Align with line 70 in the text editor block: proc bar() = diff --git a/tests/errmsgs/treportunused.nim b/tests/errmsgs/treportunused.nim index 929da8843..c74fea46f 100644 --- a/tests/errmsgs/treportunused.nim +++ b/tests/errmsgs/treportunused.nim @@ -12,10 +12,10 @@ treportunused.nim(27, 5) Hint: 's9' is declared but not used [XDeclaredButNotUse treportunused.nim(21, 10) Hint: 's3' is declared but not used [XDeclaredButNotUsed] treportunused.nim(28, 6) Hint: 's10' is declared but not used [XDeclaredButNotUsed] ''' +action: compile """ # bug #9764 - iterator s1(a:string): int = discard iterator s2(): int = discard template s3(): untyped = 123 diff --git a/tests/exception/tcontinuexc.nim b/tests/exception/tcontinuexc.nim index 2a05da9c0..b7560a605 100644 --- a/tests/exception/tcontinuexc.nim +++ b/tests/exception/tcontinuexc.nim @@ -1,5 +1,4 @@ discard """ - file: "tcontinuexc.nim" outputsub: "ECcaught" exitcode: "1" """ @@ -25,6 +24,3 @@ finally: echo "caught" #OUT ECcaught - - - diff --git a/tests/exception/texceptionbreak.nim b/tests/exception/texceptionbreak.nim index 00dd8ed9f..6548192c6 100644 --- a/tests/exception/texceptionbreak.nim +++ b/tests/exception/texceptionbreak.nim @@ -1,5 +1,4 @@ discard """ - file: "tnestedbreak.nim" output: "1\n2\n3\n4" """ diff --git a/tests/exception/texcsub.nim b/tests/exception/texcsub.nim index 02125d2c0..463e95613 100644 --- a/tests/exception/texcsub.nim +++ b/tests/exception/texcsub.nim @@ -1,5 +1,4 @@ discard """ - file: "texcsub.nim" output: "caught!" """ # Test inheritance for exception matching: @@ -12,6 +11,3 @@ except: echo "wtf!?" #OUT caught! - - - diff --git a/tests/exception/tfinally.nim b/tests/exception/tfinally.nim index 7a218b444..c5b1dd841 100644 --- a/tests/exception/tfinally.nim +++ b/tests/exception/tfinally.nim @@ -1,6 +1,6 @@ discard """ - file: "tfinally.nim" - output: '''came + output: ''' +came here 3 msg1 @@ -59,4 +59,4 @@ try: except: echo "except2" finally: - echo "finally2" \ No newline at end of file + echo "finally2" diff --git a/tests/exception/tfinally2.nim b/tests/exception/tfinally2.nim index f1acf2774..dae1a468a 100644 --- a/tests/exception/tfinally2.nim +++ b/tests/exception/tfinally2.nim @@ -1,9 +1,10 @@ discard """ - file: "tfinally2.nim" - output: '''A +output: ''' +A B C -D''' +D +''' """ # Test break in try statement: @@ -24,7 +25,4 @@ proc main: int = finally: echo("D") -discard main() #OUT ABCD - - - +discard main() diff --git a/tests/exception/tfinally3.nim b/tests/exception/tfinally3.nim index 6098672a2..9053d397d 100644 --- a/tests/exception/tfinally3.nim +++ b/tests/exception/tfinally3.nim @@ -1,7 +1,8 @@ discard """ - file: "tfinally3.nim" - outputsub: '''false -Within finally->try''' + outputsub: ''' +false +Within finally->try +''' exitCode: 1 """ # Test break in try statement: diff --git a/tests/exception/tfinally4.nim b/tests/exception/tfinally4.nim index 3aa707ff6..feaf1bc96 100644 --- a/tests/exception/tfinally4.nim +++ b/tests/exception/tfinally4.nim @@ -1,5 +1,4 @@ discard """ - file: "tfinally4.nim" output: "B1\nA1\n1\nB1\nB2\ncatch\nA1\n1\nB1\nA1\nA2\n2\nB1\nB2\ncatch\nA1\nA2\n0\nB1\nA1\n1\nB1\nB2\nA1\n1\nB1\nA1\nA2\n2\nB1\nB2\nA1\nA2\n3" """ diff --git a/tests/exception/tnestedreturn.nim b/tests/exception/tnestedreturn.nim index bf26f4903..acb83d2c8 100644 --- a/tests/exception/tnestedreturn.nim +++ b/tests/exception/tnestedreturn.nim @@ -1,6 +1,5 @@ discard """ targets: "c cpp" - file: "tnestedreturn.nim" output: "A\nB\nC\n" """ diff --git a/tests/exception/tnestedreturn2.nim b/tests/exception/tnestedreturn2.nim index 79523a883..167d09b96 100644 --- a/tests/exception/tnestedreturn2.nim +++ b/tests/exception/tnestedreturn2.nim @@ -1,5 +1,4 @@ discard """ - file: "tnestedreturn2.nim" outputsub: "Error: unhandled exception: Problem [OSError]" exitcode: "1" """ diff --git a/tests/exception/treraise.nim b/tests/exception/treraise.nim index b2a11d34f..17a38aa53 100644 --- a/tests/exception/treraise.nim +++ b/tests/exception/treraise.nim @@ -1,5 +1,4 @@ discard """ - file: "treraise.nim" outputsub: "Error: unhandled exception: bla [ESomeOtherErr]" exitcode: "1" """ @@ -19,6 +18,3 @@ except ESomething: echo("Error happened") except: raise - - - diff --git a/tests/exception/tunhandledexc.nim b/tests/exception/tunhandledexc.nim index f0fa2bf27..6ca311d38 100644 --- a/tests/exception/tunhandledexc.nim +++ b/tests/exception/tunhandledexc.nim @@ -1,7 +1,6 @@ discard """ - file: "tunhandledexc.nim" cmd: "nim $target -d:release $options $file" - outputsub: '''tunhandledexc.nim(16) genErrors + outputsub: '''tunhandledexc.nim(15) genErrors Error: unhandled exception: bla [ESomeOtherErr]''' exitcode: "1" """ diff --git a/tests/exception/twrongexc.nim b/tests/exception/twrongexc.nim index b224d4c83..9c656f3d9 100644 --- a/tests/exception/twrongexc.nim +++ b/tests/exception/twrongexc.nim @@ -1,5 +1,4 @@ discard """ - file: "twrongexc.nim" outputsub: "Error: unhandled exception: [ValueError]" exitcode: "1" """ @@ -7,7 +6,3 @@ try: raise newException(ValueError, "") except OverflowError: echo("Error caught") - - - - diff --git a/tests/exprs/texprstmt.nim b/tests/exprs/texprstmt.nim index 6c9759cf5..742670cc1 100644 --- a/tests/exprs/texprstmt.nim +++ b/tests/exprs/texprstmt.nim @@ -1,6 +1,6 @@ discard """ - line: 10 errormsg: "expression 'result[1 .. BackwardsIndex(1)]' is of type 'string' and has to be discarded" + line: 10 """ # bug #578 diff --git a/tests/exprs/tstmtexp.nim b/tests/exprs/tstmtexp.nim index 0fb835bc6..75d8dd081 100644 --- a/tests/exprs/tstmtexp.nim +++ b/tests/exprs/tstmtexp.nim @@ -1,9 +1,8 @@ discard """ + errormsg: "expression '5' is of type 'int literal(5)' and has to be discarded" file: "tstmtexp.nim" line: 8 - errormsg: "expression '5' is of type 'int literal(5)' and has to be discarded" """ # Test 3 1+4 - diff --git a/tests/flags/tgenscript.nim b/tests/flags/tgenscript.nim index 989ca8bcb..bf83ab972 100644 --- a/tests/flags/tgenscript.nim +++ b/tests/flags/tgenscript.nim @@ -1,5 +1,4 @@ discard """ - file: "tgenscript.nim" target: "c" action: compile """ diff --git a/tests/float/tfloat1.nim b/tests/float/tfloat1.nim index ed99260ea..54d49a7c1 100644 --- a/tests/float/tfloat1.nim +++ b/tests/float/tfloat1.nim @@ -1,5 +1,4 @@ discard """ - file: "tfloat1.nim" outputsub: "Error: unhandled exception: FPU operation caused an overflow [FloatOverflowError]" exitcode: "1" """ @@ -11,5 +10,3 @@ var x = 0.8 var y = 0.0 echo x / y #OUT Error: unhandled exception: FPU operation caused an overflow - - diff --git a/tests/float/tfloat2.nim b/tests/float/tfloat2.nim index b84120fba..130c71087 100644 --- a/tests/float/tfloat2.nim +++ b/tests/float/tfloat2.nim @@ -1,5 +1,4 @@ discard """ - file: "tfloat2.nim" outputsub: "Error: unhandled exception: FPU operation caused a NaN result [FloatInvalidOpError]" exitcode: "1" """ @@ -11,5 +10,3 @@ var x = 0.0 var y = 0.0 echo x / y #OUT Error: unhandled exception: FPU operation caused a NaN result - - diff --git a/tests/float/tfloat3.nim b/tests/float/tfloat3.nim index a14c6c396..215470cfc 100644 --- a/tests/float/tfloat3.nim +++ b/tests/float/tfloat3.nim @@ -1,15 +1,15 @@ discard """ - file: "tfloat3.nim" - output: "Nim 3.4368930843, 0.3299290698 C double: 3.4368930843, 0.3299290698" + output: ''' +Nim 3.4368930843, 0.3299290698 +C double: 3.4368930843, 0.3299290698''' """ import math, strutils {.emit: """ void printFloats(void) { - double y = 1.234567890123456789; - - printf("C double: %.10f, %.10f ", exp(y), cos(y)); + double y = 1.234567890123456789; + printf("C double: %.10f, %.10f\n", exp(y), cos(y)); } """.} @@ -17,8 +17,5 @@ proc c_printf(frmt: cstring) {.importc: "printf", header: "<stdio.h>", varargs.} proc printFloats {.importc, nodecl.} var x: float = 1.234567890123456789 -c_printf("Nim %.10f, %.10f ", exp(x), cos(x)) +c_printf("Nim %.10f, %.10f\n", exp(x), cos(x)) printFloats() - - - diff --git a/tests/float/tfloat4.nim b/tests/float/tfloat4.nim index 68df56be8..56280111c 100644 --- a/tests/float/tfloat4.nim +++ b/tests/float/tfloat4.nim @@ -1,8 +1,7 @@ discard """ - file: "tfloat4.nim" output: "passed all tests." - exitcode: 0 """ + import math, strutils proc c_sprintf(buf, fmt: cstring) {.importc:"sprintf", header: "<stdio.h>", varargs.} diff --git a/tests/float/tfloat5.nim b/tests/float/tfloat5.nim index aa7dc6c53..0708838fc 100644 --- a/tests/float/tfloat5.nim +++ b/tests/float/tfloat5.nim @@ -1,9 +1,10 @@ discard """ - file: "tfloat5.nim" - output: '''0 : 0.0 +output: ''' 0 : 0.0 0 : 0.0 -0 : 0.0''' +0 : 0.0 +0 : 0.0 +''' """ import parseutils diff --git a/tests/float/tfloat6.nim b/tests/float/tfloat6.nim index 8e043a658..c4cd6e932 100644 --- a/tests/float/tfloat6.nim +++ b/tests/float/tfloat6.nim @@ -1,12 +1,13 @@ discard """ - file: "tfloat6.nim" - output: '''1e-06 : 1e-06 + output: ''' +1e-06 : 1e-06 1e-06 : 1e-06 0.001 : 0.001 1e-06 : 1e-06 1e-06 : 1e-06 10.000001 : 10.000001 -100.000001 : 100.000001''' +100.000001 : 100.000001 +''' disabled: "windows" """ diff --git a/tests/float/tfloat7.nim b/tests/float/tfloat7.nim index 5fd0d43d9..a6d7af10b 100644 --- a/tests/float/tfloat7.nim +++ b/tests/float/tfloat7.nim @@ -1,12 +1,13 @@ discard """ - file: "tfloat6.nim" - output: '''passed. +output: ''' passed. passed. passed. passed. passed. -passed.''' +passed. +passed. +''' """ import strutils diff --git a/tests/float/tfloatnan.nim b/tests/float/tfloatnan.nim index aa288d342..29937a862 100644 --- a/tests/float/tfloatnan.nim +++ b/tests/float/tfloatnan.nim @@ -1,6 +1,6 @@ discard """ - file: "tfloatnan.nim" - output: '''Nim: nan +output: ''' +Nim: nan Nim: nan (float) Nim: nan (double) ''' diff --git a/tests/float/tissue5821.nim b/tests/float/tissue5821.nim index e8aa4a1d9..c4f561f09 100644 --- a/tests/float/tissue5821.nim +++ b/tests/float/tissue5821.nim @@ -1,7 +1,7 @@ discard """ - file: "tissue5821.nim" - output: '''''' +output: "ok" """ + proc main(): void = let a: float32 = 47.11'f32 doAssert a == 47.11'f32 @@ -10,4 +10,6 @@ proc main(): void = doAssert b != 10.123402823e+38'f64 doAssert b == 10.234402823e+38'f64 -main() \ No newline at end of file + echo "ok" + +main() diff --git a/tests/generics/t6137.nim b/tests/generics/t6137.nim index 639675f35..abf02a756 100644 --- a/tests/generics/t6137.nim +++ b/tests/generics/t6137.nim @@ -1,7 +1,6 @@ discard """ - action: "reject" - line: 29 errormsg: "\'vectFunc\' doesn't have a concrete type, due to unspecified generic parameters." + line: 28 """ type diff --git a/tests/generics/t7141.nim b/tests/generics/t7141.nim index 8a128d828..b1e9cbf43 100644 --- a/tests/generics/t7141.nim +++ b/tests/generics/t7141.nim @@ -1,7 +1,6 @@ discard """ - action: "reject" - line: 7 errormsg: "cannot instantiate: \'T\'" + line: 6 """ proc foo[T](x: T) = diff --git a/tests/generics/t8270.nim b/tests/generics/t8270.nim index 707e981fa..1e731d1d4 100644 --- a/tests/generics/t8270.nim +++ b/tests/generics/t8270.nim @@ -1,6 +1,6 @@ discard """ - line: 6 errormsg: "cannot instantiate: \'T\'" + line: 6 """ proc m[T](x: T): int = discard diff --git a/tests/generics/tbintre2.nim b/tests/generics/tbintre2.nim deleted file mode 100644 index eb46b5157..000000000 --- a/tests/generics/tbintre2.nim +++ /dev/null @@ -1,31 +0,0 @@ -discard """ - file: "tbintre2.nim" - output: "helloworld99110223" -""" -# Same test, but check module boundaries - -import tbintree - -var - root: PBinaryTree[string] - x = newNode("hello") -add(root, x) -add(root, "world") -if find(root, "world"): - for str in items(root): - stdout.write(str) -else: - stdout.writeLine("BUG") - -var - r2: PBinaryTree[int] -add(r2, newNode(110)) -add(r2, 223) -add(r2, 99) -for y in items(r2): - stdout.write(y) - -#OUT helloworld99110223 - - - diff --git a/tests/generics/tbintree.nim b/tests/generics/tbintree.nim index 13163f764..a1a13c7b5 100644 --- a/tests/generics/tbintree.nim +++ b/tests/generics/tbintree.nim @@ -1,6 +1,9 @@ discard """ - file: "tbintree.nim" - output: "helloworld99110223" + output: '''hello +world +99 +110 +223''' """ type TBinaryTree[T] = object # TBinaryTree is a generic type with @@ -82,7 +85,7 @@ proc debug[T](a: PBinaryTree[T]) = echo a.data debug(a.ri) -when isMainModule: +when true: var root: PBinaryTree[string] x = newNode("hello") @@ -90,9 +93,9 @@ when isMainModule: add(root, "world") if find(root, "world"): for str in items(root): - stdout.write(str) + echo(str) else: - stdout.writeLine("BUG") + echo("BUG") var r2: PBinaryTree[int] @@ -100,8 +103,4 @@ when isMainModule: add(r2, 223) add(r2, 99) for y in items(r2): - stdout.write(y) - -#OUT helloworld99110223 - - + echo(y) diff --git a/tests/generics/texplicitgeneric1.nim b/tests/generics/texplicitgeneric1.nim index ac0197c1a..16f4f7330 100644 --- a/tests/generics/texplicitgeneric1.nim +++ b/tests/generics/texplicitgeneric1.nim @@ -1,5 +1,4 @@ discard """ - file: "texplicitgeneric1.nim" output: "Key: 12 value: 12Key: 13 value: 13 Key: A value: 12 Key: B value: 13" """ # test explicit type instantiation @@ -34,5 +33,4 @@ c.add('B', "13") for k, v in items(c): stdout.write(" Key: ", $k, " value: ", v) - - +stdout.write "\n" diff --git a/tests/generics/texplicitgeneric2.nim b/tests/generics/texplicitgeneric2.nim index c4af17b7b..573b10ae8 100644 --- a/tests/generics/texplicitgeneric2.nim +++ b/tests/generics/texplicitgeneric2.nim @@ -33,3 +33,4 @@ c.add('B', "13") for k, v in items(c): stdout.write(" Key: ", $k, " value: ", v) +stdout.write "\n" diff --git a/tests/generics/tgeneric0.nim b/tests/generics/tgeneric0.nim index 6698ecec0..3a35ebaba 100644 --- a/tests/generics/tgeneric0.nim +++ b/tests/generics/tgeneric0.nim @@ -1,6 +1,7 @@ discard """ output: ''' -100 0 +100 +0 ''' """ @@ -72,7 +73,7 @@ block tgeneric1: proc print[T](heap: PBinHeap[T]) = for i in countup(0, heap.last): - stdout.write($heap.heap[i].data, " ") + stdout.write($heap.heap[i].data, "\n") var heap: PBinHeap[int] diff --git a/tests/generics/tgeneric3.nim b/tests/generics/tgeneric3.nim index 34b415446..4cb12f91b 100644 --- a/tests/generics/tgeneric3.nim +++ b/tests/generics/tgeneric3.nim @@ -430,55 +430,50 @@ iterator keys* [T,D] (n: PNode[T,D]): T = i = Path[level].Xi inc(i) - -when isMainModule: - - proc test() = - var oldvalue: int - var root = internalPut[int, int](nil, 312, 312, oldvalue) - var someOtherRoot = internalPut[string, int](nil, "312", 312, oldvalue) - var it1 = internalFind(root, 312) - echo it1.value - - for i in 1..1_000_000: - root = internalPut(root, i, i, oldvalue) - - var cnt = 0 - oldvalue = -1 - when true : # code compiles, when this or the other when is switched to false - for k in root.keys : - if k <= oldvalue : - echo k - oldvalue = k - inc(cnt) - echo cnt +proc test() = + var oldvalue: int + var root = internalPut[int, int](nil, 312, 312, oldvalue) + var someOtherRoot = internalPut[string, int](nil, "312", 312, oldvalue) + var it1 = internalFind(root, 312) + echo it1.value + + for i in 1..1_000_000: + root = internalPut(root, i, i, oldvalue) + + var cnt = 0 + oldvalue = -1 + when true : # code compiles, when this or the other when is switched to false + for k in root.keys : + if k <= oldvalue : + echo k + oldvalue = k + inc(cnt) + echo cnt + when true : + cnt = 0 + VisitAll(root, proc(key, val: int) = inc(cnt)) + echo cnt when true : - cnt = 0 - VisitAll(root, proc(key, val: int) = inc(cnt)) - echo cnt - when true : - root = VisitAll(root, proc(key: int, value: var int): bool = - return key mod 2 == 0 ) - cnt = 0 - oldvalue = -1 - VisitAll(root, proc(key: int, value: int) {.closure.} = - if key <= oldvalue : - echo key - oldvalue = key - inc(cnt) ) - echo cnt root = VisitAll(root, proc(key: int, value: var int): bool = - return key mod 2 != 0 ) - cnt = 0 - oldvalue = -1 - VisitAll(root, proc(key: int, value: int) {.closure.} = - if key <= oldvalue : - echo "error ", key - oldvalue = key - inc(cnt) ) - echo cnt - #traceTree(root) - - - - test() + return key mod 2 == 0 ) + cnt = 0 + oldvalue = -1 + VisitAll(root, proc(key: int, value: int) {.closure.} = + if key <= oldvalue : + echo key + oldvalue = key + inc(cnt) ) + echo cnt + root = VisitAll(root, proc(key: int, value: var int): bool = + return key mod 2 != 0 ) + cnt = 0 + oldvalue = -1 + VisitAll(root, proc(key: int, value: int) {.closure.} = + if key <= oldvalue : + echo "error ", key + oldvalue = key + inc(cnt) ) + echo cnt + #traceTree(root) + +test() diff --git a/tests/generics/tgenericprocvar.nim b/tests/generics/tgenericprocvar.nim index dca9c8538..7935d90c2 100644 --- a/tests/generics/tgenericprocvar.nim +++ b/tests/generics/tgenericprocvar.nim @@ -34,3 +34,4 @@ proc test(data: seq[int], value: int): seq[int] = for x in items(test(@[1,2,3], 2)): stdout.write(x) +stdout.write "\n" diff --git a/tests/generics/tgenerics_issues.nim b/tests/generics/tgenerics_issues.nim index c215ea2c2..a1d464b97 100644 --- a/tests/generics/tgenerics_issues.nim +++ b/tests/generics/tgenerics_issues.nim @@ -24,12 +24,11 @@ G:0,1:0.1 G:0,1:0.1 H:1:0.1 ''' +joinable: false """ - import macros, sequtils, sets, sugar, tables, typetraits - block t88: type BaseClass[V] = object of RootObj diff --git a/tests/generics/tgenerics_various.nim b/tests/generics/tgenerics_various.nim index 5e18995f5..9e6186534 100644 --- a/tests/generics/tgenerics_various.nim +++ b/tests/generics/tgenerics_various.nim @@ -5,12 +5,11 @@ direct generic generic ''' +joinable: false """ - import algorithm, sugar, sequtils, typetraits, asyncdispatch - block tconfusing_arrow: type Deck = object value: int diff --git a/tests/generics/tgenericvariant.nim b/tests/generics/tgenericvariant.nim index 73c8af825..5ba3a2e7c 100644 --- a/tests/generics/tgenericvariant.nim +++ b/tests/generics/tgenericvariant.nim @@ -26,9 +26,11 @@ proc safeReadLine(): TMaybe[string] = if r == "": return Nothing[string]() else: return Just(r) -when isMainModule: +proc main() = var Test = Just("Test") echo(Test.value) var mSomething = safeReadLine() echo(mSomething.value) mSomething = safeReadLine() + +main() diff --git a/tests/generics/toverloading_typedesc.nim b/tests/generics/toverloading_typedesc.nim index 94f4d860d..5ab700828 100644 --- a/tests/generics/toverloading_typedesc.nim +++ b/tests/generics/toverloading_typedesc.nim @@ -10,7 +10,7 @@ type LBar = object -when isMainModule: +when true: doAssert FBar.new() == 3 proc new(_: typedesc[LFoo]): int = 0 diff --git a/tests/generics/tparser_generator.nim b/tests/generics/tparser_generator.nim index 01ddd29b8..8f8fea382 100644 --- a/tests/generics/tparser_generator.nim +++ b/tests/generics/tparser_generator.nim @@ -1,6 +1,7 @@ discard """ output: '''Match failed: spam Match failed: ham''' +joinable: false """ # bug #6220 @@ -397,19 +398,18 @@ template grammar*[K](Kind, Text, Symbol: typedesc; default: K, code: untyped): t template grammar*[K](Kind: typedesc; default: K, code: untyped): typed {.hint[XDeclaredButNotUsed]: off.} = grammar(Kind, string, char, default, code) -when isMainModule: - block: - type DummyKind = enum dkDefault - grammar(DummyKind, string, char, dkDefault): - let rule = token("h[a]+m") + ignore(token(r"\s+")) + (literal("eggs") / literal("beans")) - var text = "ham beans" - discard rule.parse(text) - - var recursive = newRule() - recursive -> (literal("(") + recursive + literal(")")) / token(r"\d+") - for test in ["spam", "57", "(25)", "((25))"]: - discard recursive.parse(test) - - let repeated = +literal("spam") + ?literal("ham") + *literal("salami") - for test in ["ham", "spam", "spamspamspam" , "spamham", "spamsalami", "spamsalamisalami"]: - discard repeated.parse(test) +block: + type DummyKind = enum dkDefault + grammar(DummyKind, string, char, dkDefault): + let rule = token("h[a]+m") + ignore(token(r"\s+")) + (literal("eggs") / literal("beans")) + var text = "ham beans" + discard rule.parse(text) + + var recursive = newRule() + recursive -> (literal("(") + recursive + literal(")")) / token(r"\d+") + for test in ["spam", "57", "(25)", "((25))"]: + discard recursive.parse(test) + + let repeated = +literal("spam") + ?literal("ham") + *literal("salami") + for test in ["ham", "spam", "spamspamspam" , "spamham", "spamsalami", "spamsalamisalami"]: + discard repeated.parse(test) diff --git a/tests/generics/trtree.nim b/tests/generics/trtree.nim index 321b31df6..6ec1c8f6f 100644 --- a/tests/generics/trtree.nim +++ b/tests/generics/trtree.nim @@ -2,8 +2,11 @@ discard """ output: '''1 [2, 3, 4, 7] [0, 0]''' target: "c" + joinable: false """ +# don't join because the code is too messy. + # Nim RTree and R*Tree implementation # S. Salewski, 06-JAN-2018 @@ -589,70 +592,68 @@ proc delete*[M, D: Dim; RT, LT](t: RTree[M, D, RT, LT]; leaf: L[D, RT, LT]): boo t.root.parent = nil return true -when isMainModule: - - var t = [4, 1, 3, 2] - var xt = 7 - sortPlus(t, xt, system.cmp, SortOrder.Ascending) - echo xt, " ", t - - type - RSE = L[2, int, int] - RSeq = seq[RSE] - - proc rseq_search(rs: RSeq; rse: RSE): seq[int] = - result = newSeq[int]() - for i in rs: - if intersect(i.b, rse.b): - result.add(i.l) - - proc rseq_delete(rs: var RSeq; rse: RSE): bool = - for i in 0 .. rs.high: - if rs[i] == rse: - #rs.delete(i) - rs[i] = rs[rs.high] - rs.setLen(rs.len - 1) - return true - - import random, algorithm - - proc test(n: int) = - var b: Box[2, int] - echo center(b) - var x1, x2, y1, y2: int - var t = newRStarTree[8, 2, int, int]() - #var t = newRTree[8, 2, int, int]() - var rs = newSeq[RSE]() - for i in 0 .. 5: - for i in 0 .. n - 1: - x1 = rand(1000) - y1 = rand(1000) - x2 = x1 + rand(25) - y2 = y1 + rand(25) - b = [(x1, x2), (y1, y2)] - let el: L[2, int, int] = (b, i + 7) - t.insert(el) - rs.add(el) - - for i in 0 .. (n div 4): - let j = rand(rs.high) - var el = rs[j] - assert t.delete(el) - assert rs.rseq_delete(el) - - for i in 0 .. n - 1: - x1 = rand(1000) - y1 = rand(1000) - x2 = x1 + rand(100) - y2 = y1 + rand(100) - b = [(x1, x2), (y1, y2)] - let el: L[2, int, int] = (b, i) - let r = search(t, b) - let r2 = rseq_search(rs, el) - assert r.len == r2.len - assert r.sorted(system.cmp) == r2.sorted(system.cmp) - - test(1500) - - # 651 lines +var t = [4, 1, 3, 2] +var xt = 7 +sortPlus(t, xt, system.cmp, SortOrder.Ascending) +echo xt, " ", t + +type + RSE = L[2, int, int] + RSeq = seq[RSE] + +proc rseq_search(rs: RSeq; rse: RSE): seq[int] = + result = newSeq[int]() + for i in rs: + if intersect(i.b, rse.b): + result.add(i.l) + +proc rseq_delete(rs: var RSeq; rse: RSE): bool = + for i in 0 .. rs.high: + if rs[i] == rse: + #rs.delete(i) + rs[i] = rs[rs.high] + rs.setLen(rs.len - 1) + return true + +import random, algorithm + +proc test(n: int) = + var b: Box[2, int] + echo center(b) + var x1, x2, y1, y2: int + var t = newRStarTree[8, 2, int, int]() + #var t = newRTree[8, 2, int, int]() + var rs = newSeq[RSE]() + for i in 0 .. 5: + for i in 0 .. n - 1: + x1 = rand(1000) + y1 = rand(1000) + x2 = x1 + rand(25) + y2 = y1 + rand(25) + b = [(x1, x2), (y1, y2)] + let el: L[2, int, int] = (b, i + 7) + t.insert(el) + rs.add(el) + + for i in 0 .. (n div 4): + let j = rand(rs.high) + var el = rs[j] + assert t.delete(el) + assert rs.rseq_delete(el) + + for i in 0 .. n - 1: + x1 = rand(1000) + y1 = rand(1000) + x2 = x1 + rand(100) + y2 = y1 + rand(100) + b = [(x1, x2), (y1, y2)] + let el: L[2, int, int] = (b, i) + let r = search(t, b) + let r2 = rseq_search(rs, el) + assert r.len == r2.len + assert r.sorted(system.cmp) == r2.sorted(system.cmp) + +test(1500) + +# 651 lines diff --git a/tests/generics/tthread_generic.nim b/tests/generics/tthread_generic.nim index f2e9cafa9..2af5a7615 100644 --- a/tests/generics/tthread_generic.nim +++ b/tests/generics/tthread_generic.nim @@ -26,7 +26,7 @@ proc `@||->`*[T](fn: proc(): T {.thread.}, proc `||->`*[T](fn: proc(): T{.thread.}, callback: proc(val: T){.thread.}) = discard fn @||-> callback -when isMainModule: +when true: import os proc testFunc(): int {.thread.} = return 1 diff --git a/tests/generics/twrong_floatlit_type.nim b/tests/generics/twrong_floatlit_type.nim index c1830cd5a..04bacc0d9 100644 --- a/tests/generics/twrong_floatlit_type.nim +++ b/tests/generics/twrong_floatlit_type.nim @@ -108,7 +108,7 @@ proc `/`*[S](a, b: Vector2D[S]): Vector2D[S] = proc vec[S](x, y: S): Vector2D[S] = Vector2D[S](x: x, y: y) -if isMainModule: +if true: # Comment out this let, and the program will fail to # compile with a type mismatch, as expected. diff --git a/tests/global/t5958.nim b/tests/global/t5958.nim index 5abcad4a9..9b7642363 100644 --- a/tests/global/t5958.nim +++ b/tests/global/t5958.nim @@ -1,6 +1,6 @@ discard """ - line: 9 errormsg: "undeclared identifier: 'a'" + line: 9 """ static: diff --git a/tests/implicit/timplicit.nim b/tests/implicit/timplicit.nim index 70f14db53..bb701249c 100644 --- a/tests/implicit/timplicit.nim +++ b/tests/implicit/timplicit.nim @@ -6,6 +6,7 @@ discard """ 4 2 88 +timplicit done ''' """ @@ -43,4 +44,6 @@ block: var indirect = p x.indirect(44) - echo x[] \ No newline at end of file + echo x[] + + echo "timplicit done" diff --git a/tests/iter/tcountup.nim b/tests/iter/tcountup.nim index 1559041aa..f93f1536e 100644 --- a/tests/iter/tcountup.nim +++ b/tests/iter/tcountup.nim @@ -1,14 +1,9 @@ discard """ - file: "tcountup.nim" output: "0123456789" """ -# Test new countup and unary < +# Test new countup -for i in 0 .. < 10'i64: +for i in 0 ..< 10'i64: stdout.write(i) - -#OUT 0123456789 - - - +echo "\n" diff --git a/tests/iter/titer10.nim b/tests/iter/titer10.nim index 6a6afc780..9c76b62e1 100644 --- a/tests/iter/titer10.nim +++ b/tests/iter/titer10.nim @@ -23,7 +23,7 @@ when true: for val in sortable: yield val - when isMainModule: + when true: proc main = for val in byDistance([2, 3, 5, 1], 3): echo val diff --git a/tests/iter/titer11.nim b/tests/iter/titer11.nim index 6c410e945..c4c7d4a16 100644 --- a/tests/iter/titer11.nim +++ b/tests/iter/titer11.nim @@ -1,6 +1,6 @@ discard """ - file: "titer11.nim" - output: '''[ +output: ''' +[ 1 2 3 diff --git a/tests/iter/titer3.nim b/tests/iter/titer3.nim index cc603fd85..9dcfd7be5 100644 --- a/tests/iter/titer3.nim +++ b/tests/iter/titer3.nim @@ -1,5 +1,4 @@ discard """ - file: "titer3.nim" output: '''1231 4 6 diff --git a/tests/iter/titer4.nim b/tests/iter/titer4.nim index 9b52f8055..912883a63 100644 --- a/tests/iter/titer4.nim +++ b/tests/iter/titer4.nim @@ -1,10 +1,8 @@ discard """ + errormsg: "iterator within for loop context expected" file: "titer4.nim" line: 7 - errormsg: "iterator within for loop context expected" """ # implicit items/pairs, but not if we have 3 for loop vars: for x, y, z in {'a'..'z'}: #ERROR_MSG iterator within for loop context expected nil - - diff --git a/tests/iter/titer5.nim b/tests/iter/titer5.nim index bbd50fcb1..cb691ffdb 100644 --- a/tests/iter/titer5.nim +++ b/tests/iter/titer5.nim @@ -1,5 +1,4 @@ discard """ - file: "titer5.nim" output: "abcxyz" """ # Test method call syntax for iterators: @@ -11,6 +10,4 @@ for x in lines.split(): stdout.write(x) #OUT abcxyz - - - +stdout.write "\n" diff --git a/tests/iter/titer6.nim b/tests/iter/titer6.nim index b7c8fee80..69a10d868 100644 --- a/tests/iter/titer6.nim +++ b/tests/iter/titer6.nim @@ -1,5 +1,4 @@ discard """ - file: "titer6.nim" output: "000" """ # Test iterator with more than 1 yield statement @@ -33,5 +32,4 @@ proc wordWrap2(s: string, maxLineWidth = 80, for word, isSep in tokenize2(s, seps): var w = 0 - - +stdout.write "\n" diff --git a/tests/iter/titer7.nim b/tests/iter/titer7.nim index c2bd9b9cb..9cba3038d 100644 --- a/tests/iter/titer7.nim +++ b/tests/iter/titer7.nim @@ -45,9 +45,9 @@ proc square(x:int): int = let list = @[1,2,3,4,5,6,7,8,9] echo ("--- evens") -for item in list / isEven : echo(item) +for item in list / isEven: echo(item) echo ("--- squares") -for item in list >> square : echo(item) +for item in list >> square: echo(item) #echo ("--- squares of evens, only") # next line doesn't compile. Generic types are not inferred #for item in list />> (isEven, square) : echo(item) diff --git a/tests/iter/tconcat.nim b/tests/iter/titerconcat.nim index 477ac5e26..477ac5e26 100644 --- a/tests/iter/tconcat.nim +++ b/tests/iter/titerconcat.nim diff --git a/tests/iter/titervaropenarray.nim b/tests/iter/titervaropenarray.nim index 9eea085e3..701f652df 100644 --- a/tests/iter/titervaropenarray.nim +++ b/tests/iter/titervaropenarray.nim @@ -1,5 +1,4 @@ discard """ - file: "titer2.nim" output: "123" """ # Try to break the transformation pass: @@ -11,3 +10,5 @@ iterator iterAndZero(a: var openArray[int]): int = var x = [[1, 2, 3], [4, 5, 6]] for y in iterAndZero(x[0]): write(stdout, $y) #OUT 123 + +write stdout, "\n" diff --git a/tests/iter/treciter.nim b/tests/iter/treciter.nim index dacdbdfd7..7b61326f4 100644 --- a/tests/iter/treciter.nim +++ b/tests/iter/treciter.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "recursive dependency: \'myrec\'" file: "treciter.nim" line: 9 - errormsg: "recursive dependency: \'myrec\'" """ # Test that an error message occurs for a recursive iterator @@ -10,5 +10,3 @@ iterator myrec(n: int): int = yield x for x in myrec(10): echo x - - diff --git a/tests/iter/twrongiter.nim b/tests/iter/twrongiter.nim index 33394219b..577b8c4f1 100644 --- a/tests/iter/twrongiter.nim +++ b/tests/iter/twrongiter.nim @@ -1,6 +1,6 @@ discard """ -line: 12 errormsg: "type mismatch" +line: 12 """ proc first(it: iterator(): int): seq[int] = diff --git a/tests/js/t7224.nim b/tests/js/t7224.nim index 2d7ee1336..be9d0ae9c 100644 --- a/tests/js/t7224.nim +++ b/tests/js/t7224.nim @@ -7,7 +7,7 @@ t7224.ccc, line: 15 t7224.ddd, line: 12 ''' """ - + proc ddd() = raise newException(IOError, "didn't do stuff") @@ -22,5 +22,6 @@ proc aaa() = try: aaa() + except IOError as e: echo getStackTrace(e) diff --git a/tests/js/tvarargs.nim b/tests/js/tvarargs.nim index b8c532767..8d57af58d 100644 --- a/tests/js/tvarargs.nim +++ b/tests/js/tvarargs.nim @@ -11,5 +11,5 @@ type var console* {.importc.}: Console -when isMainModule: +when true: console.log "Hello, world" diff --git a/tests/let/tlet.nim b/tests/let/tlet.nim index 6703ba254..25d7b9bf7 100644 --- a/tests/let/tlet.nim +++ b/tests/let/tlet.nim @@ -1,6 +1,6 @@ discard """ - line: "10" errormsg: "'name' cannot be assigned to" + line: "10" """ echo("What's your name? ") @@ -8,4 +8,3 @@ let name = readLine(stdin) while name == "": echo("Please tell me your name: ") name = readLine(stdin) - diff --git a/tests/let/tlet2.nim b/tests/let/tlet2.nim index 2df15fa5c..63e7d6128 100644 --- a/tests/let/tlet2.nim +++ b/tests/let/tlet2.nim @@ -1,6 +1,6 @@ discard """ - line: "13" errormsg: "type mismatch: got <int literal(8), int literal(5), int, int>" + line: "13" """ proc divmod(a, b: int, res, remainder: var int) = @@ -13,4 +13,3 @@ let divmod(8, 5, x, y) # modifies x and y echo(x) echo(y) - diff --git a/tests/lexer/tind1.nim b/tests/lexer/tind1.nim index ffbde48fd..2185c3074 100644 --- a/tests/lexer/tind1.nim +++ b/tests/lexer/tind1.nim @@ -1,6 +1,6 @@ discard """ - line: 24 errormsg: "invalid indentation" + line: 24 """ import macros diff --git a/tests/lexer/tinvalidintegerliteral1.nim b/tests/lexer/tinvalidintegerliteral1.nim index 08ab82a22..6bf7624f3 100644 --- a/tests/lexer/tinvalidintegerliteral1.nim +++ b/tests/lexer/tinvalidintegerliteral1.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "invalid number" file: "tinvalidintegerliteral1.nim" line: 7 - errormsg: "invalid number" """ echo 0b diff --git a/tests/lexer/tinvalidintegerliteral2.nim b/tests/lexer/tinvalidintegerliteral2.nim index bc8793e4e..eb6efc131 100644 --- a/tests/lexer/tinvalidintegerliteral2.nim +++ b/tests/lexer/tinvalidintegerliteral2.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "invalid number" file: "tinvalidintegerliteral2.nim" line: 7 - errormsg: "invalid number" """ echo 0x diff --git a/tests/lexer/tinvalidintegerliteral3.nim b/tests/lexer/tinvalidintegerliteral3.nim index 9c2fe69df..e09cda54a 100644 --- a/tests/lexer/tinvalidintegerliteral3.nim +++ b/tests/lexer/tinvalidintegerliteral3.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "0O5 is an invalid int literal; For octal literals use the '0o' prefix." file: "tinvalidintegerliteral3.nim" line: 7 - errormsg: "0O5 is an invalid int literal; For octal literals use the '0o' prefix." """ echo 0O5 diff --git a/tests/lexer/tmissingnl.nim b/tests/lexer/tmissingnl.nim index 095d9570e..dc939bcd2 100644 --- a/tests/lexer/tmissingnl.nim +++ b/tests/lexer/tmissingnl.nim @@ -1,10 +1,9 @@ discard """ + errormsg: "invalid indentation" file: "tmissingnl.nim" line: 7 - errormsg: "invalid indentation" """ import strutils let s: seq[int] = @[0, 1, 2, 3, 4, 5, 6] #s[1..3] = @[] - diff --git a/tests/lexer/tstrlits.nim b/tests/lexer/tstrlits.nim index d13baf7ff..8e8250a5b 100644 --- a/tests/lexer/tstrlits.nim +++ b/tests/lexer/tstrlits.nim @@ -1,5 +1,4 @@ discard """ - file: "tstrlits.nim" output: "a\"\"long string\"\"\"\"\"abc\"def_'2'●𝌆𝌆A" """ # Test the new different string literals @@ -17,8 +16,4 @@ const stdout.write(rawQuote) stdout.write(tripleEmpty) stdout.write(raw) -stdout.write(escaped) -#OUT a""long string"""""abc"def_'2'●𝌆𝌆A - - - +stdout.writeLine(escaped) diff --git a/tests/lexer/tunderscores.nim b/tests/lexer/tunderscores.nim index f64f36977..1896a2898 100644 --- a/tests/lexer/tunderscores.nim +++ b/tests/lexer/tunderscores.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "invalid token: trailing underscore" file: "tunderscores.nim" line: 8 - errormsg: "invalid token: trailing underscore" """ # Bug #502670 @@ -9,6 +9,3 @@ var ef_ = 3 #ERROR_MSG invalid token: _ var a__b = 1 var c___d = 2 echo(ab, cd, ef_) - - - diff --git a/tests/macros/tmacro4.nim b/tests/macros/tmacro4.nim index 164afaeb7..7c2839aba 100644 --- a/tests/macros/tmacro4.nim +++ b/tests/macros/tmacro4.nim @@ -11,7 +11,7 @@ macro test_macro*(s: string, n: untyped): untyped = add(ass, newIdentNode("str")) add(ass, newStrLitNode("after")) add(result, ass) -when isMainModule: +when true: var str: string = "before" test_macro(str): var i : integer = 123 diff --git a/tests/macros/tmacrogenerics.nim b/tests/macros/tmacrogenerics.nim index e4acdc321..bb562cacb 100644 --- a/tests/macros/tmacrogenerics.nim +++ b/tests/macros/tmacrogenerics.nim @@ -1,5 +1,4 @@ discard """ - file: "tmacrogenerics.nim" nimout: ''' instantiation 1 with None and None instantiation 2 with None and None diff --git a/tests/macros/tgensym.nim b/tests/macros/tmacrogensym.nim index 1237b8bf7..1237b8bf7 100644 --- a/tests/macros/tgensym.nim +++ b/tests/macros/tmacrogensym.nim diff --git a/tests/macros/tquotewords.nim b/tests/macros/tquotewords.nim index fa00ba9de..e718d25f9 100644 --- a/tests/macros/tquotewords.nim +++ b/tests/macros/tquotewords.nim @@ -1,5 +1,4 @@ discard """ - file: "tquotewords.nim" output: "thisanexample" """ # Test an idea I recently had: diff --git a/tests/macros/trecmacro.nim b/tests/macros/trecmacro.nim index 69ebe3da3..d804178bc 100644 --- a/tests/macros/trecmacro.nim +++ b/tests/macros/trecmacro.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "recursive dependency: 'dump'" file: "trecmacro.nim" line: 8 - errormsg: "recursive dependency: 'dump'" """ macro dump(n: untyped): untyped = diff --git a/tests/macros/tsametype.nim b/tests/macros/tsametype.nim index 865fb4cb8..5219a3767 100644 --- a/tests/macros/tsametype.nim +++ b/tests/macros/tsametype.nim @@ -9,6 +9,7 @@ true false true false''' +joinable: false """ import macros diff --git a/tests/macros/tstringinterp.nim b/tests/macros/tstringinterp.nim index 305f40ac5..74c73599b 100644 --- a/tests/macros/tstringinterp.nim +++ b/tests/macros/tstringinterp.nim @@ -1,5 +1,4 @@ discard """ - file: "tstringinterp.nim" output: "Hello Alice, 64 | Hello Bob, 10$" """ @@ -71,3 +70,4 @@ var s2 = formatStyleInterpolation"Hello ${bob}, ${sum(alice.len, bob.len, 2)}$$" write(stdout, s1 & " | " & s2) +write(stdout, "\n") diff --git a/tests/magics/tmagics.nim b/tests/magics/tmagics.nim index 841de56a5..fa138320c 100644 --- a/tests/magics/tmagics.nim +++ b/tests/magics/tmagics.nim @@ -8,20 +8,21 @@ true false true ''' +joinable: false """ block tlowhigh: type myEnum = enum e1, e2, e3, e4, e5 var a: array[myEnum, int] - + for i in low(a) .. high(a): a[i] = 0 - + proc sum(a: openarray[int]): int = result = 0 for i in low(a)..high(a): inc(result, a[i]) - + doAssert sum([1, 2, 3, 4]) == 10 diff --git a/tests/manyloc/argument_parser/argument_parser.nim b/tests/manyloc/argument_parser/argument_parser.nim index d42842f93..9a37ef8c9 100644 --- a/tests/manyloc/argument_parser/argument_parser.nim +++ b/tests/manyloc/argument_parser/argument_parser.nim @@ -486,7 +486,7 @@ proc echo_help*(expected: seq[Tparameter_specification] = @[], echo line -when isMainModule: +when true: # Simply tests code embedded in docs. let parsed_param1 = new_parsed_parameter(PK_FLOAT, 3.41) diff --git a/tests/manyloc/argument_parser/ex_wget.nim b/tests/manyloc/argument_parser/ex_wget.nim index 625a6f595..ebbf1933f 100644 --- a/tests/manyloc/argument_parser/ex_wget.nim +++ b/tests/manyloc/argument_parser/ex_wget.nim @@ -81,7 +81,7 @@ proc process_commandline(): Tcommandline_results = echo "Will use progress type $1" % [result.options[PARAM_PROGRESS[0]].str_val] -when isMainModule: +when true: let args = process_commandline() for param in args.positional_parameters: echo "Downloading $1" % param.str_val diff --git a/tests/manyloc/keineschweine/dependencies/genpacket/genpacket.nim b/tests/manyloc/keineschweine/dependencies/genpacket/genpacket.nim index 3026cc4b9..fe9909750 100644 --- a/tests/manyloc/keineschweine/dependencies/genpacket/genpacket.nim +++ b/tests/manyloc/keineschweine/dependencies/genpacket/genpacket.nim @@ -252,7 +252,7 @@ template forwardPacketT*(typeName: expr): stmt {.dirty, immediate.} = proc `pack typeName`*(p: var typeName; s: PStream) = writeData(s, addr p, sizeof(p)) -when isMainModule: +when true: type SomeEnum = enum A = 0'i8, diff --git a/tests/manyloc/keineschweine/dependencies/genpacket/genpacket_enet.nim b/tests/manyloc/keineschweine/dependencies/genpacket/genpacket_enet.nim index dccbe61ba..b36b49823 100644 --- a/tests/manyloc/keineschweine/dependencies/genpacket/genpacket_enet.nim +++ b/tests/manyloc/keineschweine/dependencies/genpacket/genpacket_enet.nim @@ -244,7 +244,7 @@ template forwardPacketT*(typeName: untyped; underlyingType: untyped) {.dirty.} = #writeData(s, addr p, sizeof(p)) buffer.write(underlyingType(ord)) -when isMainModule: +when false: type SomeEnum = enum A = 0'i8, diff --git a/tests/manyloc/keineschweine/dependencies/genpacket/macro_dsl.nim b/tests/manyloc/keineschweine/dependencies/genpacket/macro_dsl.nim index 33d2a7177..3341f42c2 100644 --- a/tests/manyloc/keineschweine/dependencies/genpacket/macro_dsl.nim +++ b/tests/manyloc/keineschweine/dependencies/genpacket/macro_dsl.nim @@ -50,7 +50,7 @@ macro `?`(a: untyped): untyped = result = ($a[1].ident)[0].lit ## echo(?F,?a,?t,?t,?y) -when isMainModule: +when false: macro foo(x: untyped) = result = newNimNode(nnkStmtList) result.add(newNimNode(nnkCall).und(!!"echo", "Hello thar".lit)) diff --git a/tests/manyloc/keineschweine/dependencies/genpacket/streams_enh.nim b/tests/manyloc/keineschweine/dependencies/genpacket/streams_enh.nim index 5a1dffc93..ad0d20f1c 100644 --- a/tests/manyloc/keineschweine/dependencies/genpacket/streams_enh.nim +++ b/tests/manyloc/keineschweine/dependencies/genpacket/streams_enh.nim @@ -24,7 +24,7 @@ proc writeLEStr*(s: PStream, str: string) = s.write(str.len.int16) s.write(str) -when isMainModule: +when true: var testStream = newStringStream() testStream.writeLEStr("Hello") diff --git a/tests/manyloc/keineschweine/dependencies/nake/nake.nim b/tests/manyloc/keineschweine/dependencies/nake/nake.nim index 5341c1079..83569e30e 100644 --- a/tests/manyloc/keineschweine/dependencies/nake/nake.nim +++ b/tests/manyloc/keineschweine/dependencies/nake/nake.nim @@ -50,7 +50,7 @@ template withDir*(dir: string; body: stmt): stmt = body cd(curDir) -when isMainModule: +when true: if not existsFile("nakefile.nim"): echo "No nakefile.nim found. Current working dir is ", getCurrentDir() quit 1 diff --git a/tests/manyloc/keineschweine/enet_server/enet_server.nim b/tests/manyloc/keineschweine/enet_server/enet_server.nim index eae7c034e..3bb259386 100644 --- a/tests/manyloc/keineschweine/enet_server/enet_server.nim +++ b/tests/manyloc/keineschweine/enet_server/enet_server.nim @@ -102,7 +102,7 @@ handlers[HZoneJoinReq] = proc(client: PClient; buffer: PBuffer) = -when isMainModule: +when true: import parseopt, matchers, os, json diff --git a/tests/manyloc/keineschweine/keineschweine.nim b/tests/manyloc/keineschweine/keineschweine.nim index 04fec2788..b6fd3cc19 100644 --- a/tests/manyloc/keineschweine/keineschweine.nim +++ b/tests/manyloc/keineschweine/keineschweine.nim @@ -663,7 +663,7 @@ proc mainRender() = proc readyMainState() = specInputClient.setActive() -when isMainModule: +when true: import parseopt localPlayer = newPlayer() diff --git a/tests/manyloc/keineschweine/lib/estreams.nim b/tests/manyloc/keineschweine/lib/estreams.nim index 00a55c626..99cbb63d1 100644 --- a/tests/manyloc/keineschweine/lib/estreams.nim +++ b/tests/manyloc/keineschweine/lib/estreams.nim @@ -106,7 +106,7 @@ proc readChar*(buffer: PBuffer): char {.inline.} = return readInt8(buffer).char proc readBool*(buffer: PBuffer): bool {.inline.} = return readInt8(buffer).bool -when isMainModule: +when false: var b = newBuffer(100) var str = "hello there" b.write str diff --git a/tests/manyloc/keineschweine/lib/map_filter.nim b/tests/manyloc/keineschweine/lib/map_filter.nim index f3f1df190..acb58c60e 100644 --- a/tests/manyloc/keineschweine/lib/map_filter.nim +++ b/tests/manyloc/keineschweine/lib/map_filter.nim @@ -17,7 +17,7 @@ template unless*(condition: untyped; body: untyped) {.dirty.} = if not condition: body -when isMainModule: +when false: proc dumpSeq[T](x: seq[T]) = for index, item in x.pairs: echo index, " ", item diff --git a/tests/manyloc/keineschweine/lib/sg_packets.nim b/tests/manyloc/keineschweine/lib/sg_packets.nim index f3a0e8925..9a5aa5496 100644 --- a/tests/manyloc/keineschweine/lib/sg_packets.nim +++ b/tests/manyloc/keineschweine/lib/sg_packets.nim @@ -92,7 +92,7 @@ defPacket(DsMsg, tuple[msg: string]) let HVerifyClient* = 'v' defPacket(SdVerifyClient, tuple[session: ScLogin]) -when isMainModule: +when true: var buf = newBuffer(100) var m = toMd5("hello there") diff --git a/tests/manyloc/keineschweine/lib/zlib_helpers.nim b/tests/manyloc/keineschweine/lib/zlib_helpers.nim index 076475964..895f41759 100644 --- a/tests/manyloc/keineschweine/lib/zlib_helpers.nim +++ b/tests/manyloc/keineschweine/lib/zlib_helpers.nim @@ -20,7 +20,7 @@ proc uncompress*(source: string, destLen: var int): string = echo "Error occurred: ", res -when isMainModule: +when true: import strutils var r = compress("Hello") echo repr(r) diff --git a/tests/manyloc/keineschweine/server/old_dirserver.nim b/tests/manyloc/keineschweine/server/old_dirserver.nim index 202dc6fe7..cfb0b0377 100644 --- a/tests/manyloc/keineschweine/server/old_dirserver.nim +++ b/tests/manyloc/keineschweine/server/old_dirserver.nim @@ -156,7 +156,7 @@ proc poll*(timeout: int = 250) = echo("Write ", c, " result: ", res, " data: ", repr(c.outputBuf.data)) c.outputBuf.flush() -when isMainModule: +when true: import parseopt, matchers, strutils var cfgFile = "dirserver_settings.json" for kind, key, val in getOpt(): diff --git a/tests/manyloc/keineschweine/server/old_sg_server.nim b/tests/manyloc/keineschweine/server/old_sg_server.nim index bddc74c6d..d046df9dd 100644 --- a/tests/manyloc/keineschweine/server/old_sg_server.nim +++ b/tests/manyloc/keineschweine/server/old_sg_server.nim @@ -141,7 +141,7 @@ proc poll*(timeout: int = 250) = echo("Write ", c, " result: ", res, " data: ", c.outputBuf.data) c.outputBuf.flush() -when isMainModule: +when true: import parseopt, matchers, strutils var zoneCfgFile = "./server_settings.json" for kind, key, val in getOpt(): diff --git a/tests/manyloc/nake/nake.nim b/tests/manyloc/nake/nake.nim index ff3c10a17..ebcf21d19 100644 --- a/tests/manyloc/nake/nake.nim +++ b/tests/manyloc/nake/nake.nim @@ -50,7 +50,7 @@ template withDir*(dir: string; body: untyped) = body cd(curDir) -when isMainModule: +when true: if not existsFile("nakefile.nim"): echo "No nakefile.nim found. Current working dir is ", getCurrentDir() quit 1 diff --git a/tests/metatype/tmatrix1.nim b/tests/metatype/tmatrix1.nim index 0f325a17b..15913499f 100644 --- a/tests/metatype/tmatrix1.nim +++ b/tests/metatype/tmatrix1.nim @@ -8,10 +8,10 @@ type TMatrix2x2*[T] = TMatrixNM[range[0..1], range[0..1], T] TMatrix3x3*[T] = TMatrixNM[range[0..2], range[0..2], T] -proc test*[T] (matrix: TMatrix2x2[T]) = +proc test*[T](matrix: TMatrix2x2[T]) = echo "wrong proc called" -proc test*[T] (matrix: TMatrix3x3[T]) = +proc test*[T](matrix: TMatrix3x3[T]) = echo "right proc called" var matrix: TMatrix3x3[float] diff --git a/tests/metatype/ttypeclasses.nim b/tests/metatype/tmeta_typeclasses.nim index 720527088..720527088 100644 --- a/tests/metatype/ttypeclasses.nim +++ b/tests/metatype/tmeta_typeclasses.nim diff --git a/tests/metatype/tmatrix.nim b/tests/metatype/tmetatypematrix.nim index 4fd32a932..4cd0aa49f 100644 --- a/tests/metatype/tmatrix.nim +++ b/tests/metatype/tmetatypematrix.nim @@ -1,5 +1,4 @@ discard """ - file: "tmatrix.nim" output: "111" """ # Test overloading of [] with multiple indices @@ -44,5 +43,4 @@ for i in 0..w-1: for i in 0..w-1: stdout.write(m[i,i]) #OUT 111 - - +stdout.write "\n" diff --git a/tests/metatype/tstaticparams.nim b/tests/metatype/tstaticparams.nim index ad6aa6589..09d505f94 100644 --- a/tests/metatype/tstaticparams.nim +++ b/tests/metatype/tstaticparams.nim @@ -1,5 +1,4 @@ discard """ - file: "tstaticparams.nim" output: "abracadabra\ntest\n3\n15\n4\n2\nfloat\n3\nfloat\nyin\nyang\n2\n4\n4\n2\n3" """ @@ -140,7 +139,7 @@ dontBind1 bb_2 dontBind2 bb_1 dontBind2 bb_2 -# https://github.com/nim-lang/Nim/issues/4524 +# https://github.com/nim-lang/Nim/issues/4524 const size* = 2 @@ -172,4 +171,3 @@ echo inSize([ [1, 2, 3], [4, 5, 6] ]) - diff --git a/tests/method/tmethod.nim b/tests/method/tmethod.nim index 0cfe24c70..005294d64 100644 --- a/tests/method/tmethod.nim +++ b/tests/method/tmethod.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "\'method\' needs a parameter that has an object type" file: "tmethod.nim" line: 7 - errormsg: "\'method\' needs a parameter that has an object type" """ method m(i: int): int = diff --git a/tests/method/tmultim.nim b/tests/method/tmultim.nim index 310502c56..7023e18bf 100644 --- a/tests/method/tmultim.nim +++ b/tests/method/tmultim.nim @@ -4,9 +4,12 @@ collide: unit, thing collide: unit, thing collide: thing, unit collide: thing, thing -collide: unit, thing | collide: unit, thing | collide: thing, unit | +collide: unit, thing | +collide: unit, thing | +collide: thing, unit | do nothing ''' + joinable: false """ @@ -55,10 +58,10 @@ method collide(a, b: Thing) {.base, inline.} = quit "to override!" method collide[T](a: Thing, b: Unit[T]) {.inline.} = - write stdout, "collide: thing, unit | " + echo "collide: thing, unit |" method collide[T](a: Unit[T], b: Thing) {.inline.} = - write stdout, "collide: unit, thing | " + echo "collide: unit, thing |" proc test(a, b: Thing) {.inline.} = collide(a, b) @@ -69,7 +72,6 @@ var collide(bbb, Thing(ccc)) test(bbb, ccc) collide(aaa, bbb) -echo "" diff --git a/tests/misc/t99bott.nim b/tests/misc/t99bott.nim index 62ccfbe16..f60023818 100644 --- a/tests/misc/t99bott.nim +++ b/tests/misc/t99bott.nim @@ -1,9 +1,9 @@ discard """ + errormsg: "cannot evaluate at compile time: bn" file: "t99bott.nim" line: 26 - errormsg: "cannot evaluate at compile time: bn" - disabled: false """ + ## 99 Bottles of Beer ## http://www.99-bottles-of-beer.net/ ## Nim version @@ -30,7 +30,3 @@ for bn in countdown(99, 1): echo "No more bottles of beer on the wall, no more bottles of beer." echo "Go to the store and buy some more, 99 bottles of beer on the wall." - - - - diff --git a/tests/misc/tack.nim b/tests/misc/tack.nim index a0afab9e8..458395ef6 100644 --- a/tests/misc/tack.nim +++ b/tests/misc/tack.nim @@ -1,5 +1,4 @@ discard """ - file: "tack.nim" output: "125" """ # the Ackermann function @@ -17,5 +16,4 @@ proc ack(x, y: int): int = # echo(ack(0, 0)) write(stdout, ack(3, 4)) #OUT 125 - - +write stdout, "\n" diff --git a/tests/misc/tbug511622.nim b/tests/misc/tbug511622.nim index a5360423d..4b30e96e6 100644 --- a/tests/misc/tbug511622.nim +++ b/tests/misc/tbug511622.nim @@ -1,5 +1,4 @@ discard """ - file: "tbug511622.nim" output: "3" """ import StrUtils, Math @@ -11,6 +10,3 @@ proc FibonacciA(n: int): int64 = return int64((pow(p, fn) + pow(q, fn)) / sqrt(5.0)) echo FibonacciA(4) #OUT 3 - - - diff --git a/tests/misc/tcmdline.nim b/tests/misc/tcmdline.nim index 2c4768716..71e1301ca 100644 --- a/tests/misc/tcmdline.nim +++ b/tests/misc/tcmdline.nim @@ -1,5 +1,6 @@ discard """ outputsub: "Number of parameters: 0" +joinable: false """ # Test the command line diff --git a/tests/misc/temit.nim b/tests/misc/temit.nim index c83235659..ee7455d4c 100644 --- a/tests/misc/temit.nim +++ b/tests/misc/temit.nim @@ -1,5 +1,4 @@ discard """ - file: "temit.nim" output: "509" """ # Test the new ``emit`` pragma: @@ -14,7 +13,3 @@ proc embedsC() = {.emit: """printf("%d\n", cvariable + (int)`nimVar`);""".} embedsC() - - - - diff --git a/tests/misc/tevents.nim b/tests/misc/tevents.nim index caf674084..045c9fc5b 100644 --- a/tests/misc/tevents.nim +++ b/tests/misc/tevents.nim @@ -1,8 +1,9 @@ discard """ -file: "tevents.nim" -output: '''HandlePrintEvent: Output -> Handled print event +output: ''' +HandlePrintEvent: Output -> Handled print event HandlePrintEvent2: Output -> printing for ME -HandlePrintEvent2: Output -> printing for ME''' +HandlePrintEvent2: Output -> printing for ME +''' """ import events @@ -45,4 +46,3 @@ ee.emit(obj.printEvent, eventargs) obj.printEvent.removeHandler(handleprintevent2) ee.emit(obj.printEvent, eventargs) - diff --git a/tests/misc/tgenconstraints.nim b/tests/misc/tgenconstraints.nim index 6e8fdc738..829da5173 100644 --- a/tests/misc/tgenconstraints.nim +++ b/tests/misc/tgenconstraints.nim @@ -1,8 +1,8 @@ discard """ + errormsg: "cannot instantiate T2" file: "tgenconstraints.nim" line: 25 disabled: true - errormsg: "cannot instantiate T2" """ type @@ -29,4 +29,3 @@ proc bar(x: int|TNumber): T1[type(x)] {.discardable.} = bar "test" bar 100 bar 1.1 - diff --git a/tests/misc/thallo.nim b/tests/misc/thallo.nim index 6f9d49121..7172a6b46 100644 --- a/tests/misc/thallo.nim +++ b/tests/misc/thallo.nim @@ -11,7 +11,7 @@ type TMyEnum = enum meA, meB, meC, meD -when isMainModule: +when true: {.hint: "this is the main file".} proc fac[T](x: T): T = @@ -84,5 +84,5 @@ for i in 2..6: for j in countdown(i+4, 2): echo(fac(i * j)) -when isMainModule: +when true: {.hint: "this is the main file".} diff --git a/tests/misc/thintoff.nim b/tests/misc/thintoff.nim deleted file mode 100644 index 95318ce9b..000000000 --- a/tests/misc/thintoff.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - file: "thintoff.nim" - output: "0" -""" - -{.hint[XDeclaredButNotUsed]: off.} -var - x: int - -echo x #OUT 0 - - diff --git a/tests/misc/tinc.nim b/tests/misc/tinc.nim index 7819775e3..91f6223e2 100644 --- a/tests/misc/tinc.nim +++ b/tests/misc/tinc.nim @@ -1,12 +1,8 @@ discard """ + errormsg: "type mismatch: got <int>" file: "tinc.nim" line: 8 - errormsg: "type mismatch: got <int>" """ var x = 0 inc(x+1) - - - - diff --git a/tests/misc/tinit.nim b/tests/misc/tinit.nim index 02607909b..207cb17e8 100644 --- a/tests/misc/tinit.nim +++ b/tests/misc/tinit.nim @@ -1,5 +1,4 @@ discard """ - file: "tinit.nim" output: "Hello from module! Hello from main module!" """ # Test the new init section in modules @@ -8,5 +7,3 @@ import minit write(stdout, "Hello from main module!\n") #OUT Hello from module! Hello from main module! - - diff --git a/tests/misc/tinout.nim b/tests/misc/tinout.nim index 46af2f5de..bae0fb185 100644 --- a/tests/misc/tinout.nim +++ b/tests/misc/tinout.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "type mismatch: got <int literal(3)>" file: "tinout.nim" line: 12 - errormsg: "type mismatch: got <int literal(3)>" """ # Test in out checking for parameters @@ -12,5 +12,3 @@ proc b() = abc(3) #ERROR b() - - diff --git a/tests/misc/tinvalidarrayaccess.nim b/tests/misc/tinvalidarrayaccess.nim index 03105b41b..57ad38b85 100644 --- a/tests/misc/tinvalidarrayaccess.nim +++ b/tests/misc/tinvalidarrayaccess.nim @@ -1,14 +1,21 @@ discard """ - errormsg: "index out of bounds" - line: 11 + errormsg: "index out of bounds: (a:0) <= (i:2) <= (b:1) " + line: 18 """ +block: + try: + let a = @[1,2] + echo a[3] + except Exception as e: + doAssert e.msg == "index out of bounds: (i:3) <= (n:1) " -type TTestArr = array[0..1, int16] -var f: TTestArr -f[0] = 30 -f[1] = 40 -f[2] = 50 -f[3] = 60 +block: + type TTestArr = array[0..1, int16] + var f: TTestArr + f[0] = 30 + f[1] = 40 + f[2] = 50 + f[3] = 60 -echo(repr(f)) + echo(repr(f)) diff --git a/tests/misc/tinvalidarrayaccess2.nim b/tests/misc/tinvalidarrayaccess2.nim new file mode 100644 index 000000000..86d349457 --- /dev/null +++ b/tests/misc/tinvalidarrayaccess2.nim @@ -0,0 +1,16 @@ +discard """ + errormsg: "index out of bounds: (a:0) <= (i:3) <= (b:1) " + line: 9 +""" + +# Note: merge in tinvalidarrayaccess.nim pending https://github.com/nim-lang/Nim/issues/9906 + +let a = [1,2] +echo a[3] + +when false: + # TOOD: this case is not yet handled, giving: "index out of bounds" + proc fun()= + let a = @[1,2] + echo a[3] + static: fun() diff --git a/tests/misc/tinvalidnewseq.nim b/tests/misc/tinvalidnewseq.nim index 66e9388ef..dec00fd4a 100644 --- a/tests/misc/tinvalidnewseq.nim +++ b/tests/misc/tinvalidnewseq.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "type mismatch: got <array[0..6, string], int literal(7)>" file: "tinvalidnewseq.nim" line: 15 - errormsg: "type mismatch: got <array[0..6, string], int literal(7)>" """ import re, strutils @@ -22,6 +22,3 @@ var r: TUrl r = parseUrl(r"http://google.com/search?var=bleahdhsad") echo(r.domain) - - - diff --git a/tests/misc/tissue710.nim b/tests/misc/tissue710.nim index e2cca0024..ec125b840 100644 --- a/tests/misc/tissue710.nim +++ b/tests/misc/tissue710.nim @@ -1,7 +1,7 @@ discard """ + errorMsg: "attempting to call routine: '||'" file: "tissue710.nim" line: 8 - errorMsg: "attempting to call routine: '||'" """ var sum = 0 for x in 3..1000: diff --git a/tests/misc/tnew.nim b/tests/misc/tnew.nim index 02282dd4a..2d9a64461 100644 --- a/tests/misc/tnew.nim +++ b/tests/misc/tnew.nim @@ -3,6 +3,7 @@ outputsub: ''' Simple tree node allocation worked! Simple cycle allocation worked! ''' +joinable: false """ # Test the implementation of the new operator diff --git a/tests/misc/tnoinst.nim b/tests/misc/tnoinst.nim index 25ebe8dfc..85db1e8e7 100644 --- a/tests/misc/tnoinst.nim +++ b/tests/misc/tnoinst.nim @@ -1,6 +1,6 @@ discard """ - line: 12 errormsg: "instantiate 'notConcrete' explicitly" + line: 12 disabled: "true" """ @@ -14,4 +14,3 @@ proc wrap[T]() = wrap[int]() - diff --git a/tests/misc/tnolen.nim b/tests/misc/tnolen.nim index 2831e5048..e0e8025d4 100644 --- a/tests/misc/tnolen.nim +++ b/tests/misc/tnolen.nim @@ -1,9 +1,8 @@ discard """ - line: 8 errormsg: "type mismatch: got <int literal(3)>" + line: 8 """ # please finally disallow Len(3) echo len(3) - diff --git a/tests/misc/tnot.nim b/tests/misc/tnot.nim index 5c268981e..a3669705b 100644 --- a/tests/misc/tnot.nim +++ b/tests/misc/tnot.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "type mismatch" file: "tnot.nim" line: 14 - errormsg: "type mismatch" """ # BUG: following compiles, but should not: diff --git a/tests/misc/tparseopt.nim b/tests/misc/tparseopt.nim index 651689398..cbed5d476 100644 --- a/tests/misc/tparseopt.nim +++ b/tests/misc/tparseopt.nim @@ -1,5 +1,4 @@ discard """ - file: "tparseopt.nim" output: ''' parseopt first round diff --git a/tests/misc/tpos.nim b/tests/misc/tpos.nim index bedb62e62..f7607d643 100644 --- a/tests/misc/tpos.nim +++ b/tests/misc/tpos.nim @@ -1,5 +1,4 @@ discard """ - file: "tpos.nim" output: "6" """ # test this particular function @@ -30,6 +29,5 @@ proc mypos(sub, s: string, start: int = 0): int = var sub = "hello" var s = "world hello" write(stdout, mypos(sub, s)) +write stdout, "\n" #OUT 6 - - diff --git a/tests/misc/tradix.nim b/tests/misc/tradix.nim index 5009dfcfb..5be89530f 100644 --- a/tests/misc/tradix.nim +++ b/tests/misc/tradix.nim @@ -1,5 +1,6 @@ discard """ output: ''' +start tradix.nim false false false @@ -29,6 +30,8 @@ false ## We use a radix tree with node compression. ## There are two node kinds: +echo "start tradix.nim" + const BitsPerUnit = 8*sizeof(int) type @@ -126,7 +129,7 @@ proc excl*(r: PRadixNode, a: ByteAddress): bool = proc addLeaf(r: var PRadixNode, a: int): bool = if r == nil: # a linear node: - var x = cast[ptr TRadixNodeLinear](alloc(sizeof(TRadixNodeLinear))) + var x = cast[ptr TRadixNodeLinear](alloc0(sizeof(TRadixNodeLinear))) x.kind = rnLeafLinear x.len = 1'i8 x.keys[0] = toU8(a) @@ -162,7 +165,7 @@ proc addInner(r: var PRadixNode, a: int, d: int): bool = var k = a shr d and 0xff if r == nil: # a linear node: - var x = cast[ptr TRadixNodeLinear](alloc(sizeof(TRadixNodeLinear))) + var x = cast[ptr TRadixNodeLinear](alloc0(sizeof(TRadixNodeLinear))) x.kind = rnLinear x.len = 1'i8 x.keys[0] = toU8(k) @@ -246,99 +249,3 @@ proc main() = for x in elements(r): echo(x) main() - - -when false: - proc traverse(r: PRadixNode, prefix: int, d: int) = - if r == nil: return - case r.kind - of rnLeafBits: - assert(d == 0) - var x = cast[ptr TRadixNodeLeafBits](r) - # iterate over any bit: - for i in 0..high(x.b): - if x.b[i] != 0: # test all bits for zero - for j in 0..BitsPerUnit-1: - if testBit(x.b[i], j): - visit(prefix or i*BitsPerUnit+j) - of rnLeafLinear: - assert(d == 0) - var x = cast[ptr TRadixNodeLeafLinear](r) - for i in 0..ze(x.len)-1: - visit(prefix or ze(x.keys[i])) - of rnFull: - var x = cast[ptr TRadixNodeFull](r) - for i in 0..high(r.b): - if r.b[i] != nil: - traverse(r.b[i], prefix or (i shl d), d-8) - of rnLinear: - var x = cast[ptr TRadixNodeLinear](r) - for i in 0..ze(x.len)-1: - traverse(x.vals[i], prefix or (ze(x.keys[i]) shl d), d-8) - - type - TRadixIter {.final.} = object - r: PRadixNode - p: int - x: int - - proc init(i: var TRadixIter, r: PRadixNode) = - i.r = r - i.x = 0 - i.p = 0 - - proc nextr(i: var TRadixIter): PRadixNode = - if i.r == nil: return nil - case i.r.kind - of rnFull: - var r = cast[ptr TRadixNodeFull](i.r) - while i.x <= high(r.b): - if r.b[i.x] != nil: - i.p = i.x - return r.b[i.x] - inc(i.x) - of rnLinear: - var r = cast[ptr TRadixNodeLinear](i.r) - if i.x < ze(r.len): - i.p = ze(r.keys[i.x]) - result = r.vals[i.x] - inc(i.x) - else: assert(false) - - proc nexti(i: var TRadixIter): int = - result = -1 - case i.r.kind - of rnLeafBits: - var r = cast[ptr TRadixNodeLeafBits](i.r) - # iterate over any bit: - for i in 0..high(r.b): - if x.b[i] != 0: # test all bits for zero - for j in 0..BitsPerUnit-1: - if testBit(x.b[i], j): - visit(prefix or i*BitsPerUnit+j) - of rnLeafLinear: - var r = cast[ptr TRadixNodeLeafLinear](i.r) - if i.x < ze(r.len): - result = ze(r.keys[i.x]) - inc(i.x) - - iterator elements(r: PRadixNode): ByteAddress {.inline.} = - var - a, b, c, d: TRadixIter - init(a, r) - while true: - var x = nextr(a) - if x != nil: - init(b, x) - while true: - var y = nextr(b) - if y != nil: - init(c, y) - while true: - var z = nextr(c) - if z != nil: - init(d, z) - while true: - var q = nexti(d) - if q != -1: - yield a.p shl 24 or b.p shl 16 or c.p shl 8 or q diff --git a/tests/misc/trawstr.nim b/tests/misc/trawstr.nim index 55e508acc..aa41071d5 100644 --- a/tests/misc/trawstr.nim +++ b/tests/misc/trawstr.nim @@ -1,12 +1,10 @@ discard """ + errormsg: "closing \" expected" file: "trawstr.nim" line: 10 - errormsg: "closing \" expected" """ # Test the new raw strings: const xxx = r"This is a raw string!" yyy = "This not\" #ERROR - - diff --git a/tests/misc/tshadow_magic_type.nim b/tests/misc/tshadow_magic_type.nim index 6f9716bb9..3176a4596 100644 --- a/tests/misc/tshadow_magic_type.nim +++ b/tests/misc/tshadow_magic_type.nim @@ -26,7 +26,6 @@ proc lrange*(key: string): TRedisList = foo.str = key result = @[foo] -when isMainModule: - var p = lrange("mylist") - for i in items(p): - echo(i.str) +var p = lrange("mylist") +for i in items(p): + echo(i.str) diff --git a/tests/misc/tsimtych.nim b/tests/misc/tsimtych.nim index 037172bd5..74a6ad4c0 100644 --- a/tests/misc/tsimtych.nim +++ b/tests/misc/tsimtych.nim @@ -1,12 +1,10 @@ discard """ + errormsg: "type mismatch: got <bool> but expected \'string\'" file: "tsimtych.nim" line: 10 - errormsg: "type mismatch: got <bool> but expected \'string\'" """ # Test 2 # Simple type checking var a: string a = false #ERROR - - diff --git a/tests/misc/tsizeof2.nim b/tests/misc/tsizeof2.nim index 4252142d7..130f28e21 100644 --- a/tests/misc/tsizeof2.nim +++ b/tests/misc/tsizeof2.nim @@ -13,3 +13,5 @@ echo i # bug #9868 proc foo(a: SomeInteger): array[sizeof(a), byte] = discard + +discard foo(1) diff --git a/tests/misc/tslices.nim b/tests/misc/tslices.nim index 388a46509..d063c5ebf 100644 --- a/tests/misc/tslices.nim +++ b/tests/misc/tslices.nim @@ -1,6 +1,6 @@ discard """ - file: "tslices.nim" - output: '''456456 +output: ''' +456456 456456 456456 Zugr5nd @@ -56,4 +56,3 @@ echo mystr var s = "abcdef" s[1 .. ^2] = "xyz" assert s == "axyzf" - diff --git a/tests/misc/tsortdev.nim b/tests/misc/tsortdev.nim index f360d9646..0b2a4f3e8 100644 --- a/tests/misc/tsortdev.nim +++ b/tests/misc/tsortdev.nim @@ -1,5 +1,5 @@ discard """ - output: "done" + output: "done tsortdev" """ import algorithm, strutils @@ -55,5 +55,4 @@ proc main() = for i in 0..1_000: main() -echo "done" - +echo "done tsortdev" diff --git a/tests/misc/tstrange.nim b/tests/misc/tstrange.nim index fee0f44e4..82a82d267 100644 --- a/tests/misc/tstrange.nim +++ b/tests/misc/tstrange.nim @@ -1,8 +1,9 @@ discard """ - file: "tstrange.nim" - output: '''hallo40 +output: ''' +hallo40 1 -2''' +2 +''' """ # test for extremely strange bug @@ -25,4 +26,3 @@ write(stdout, ack(5, 4)) let h=3 for x in 0.. <h.int: echo x - diff --git a/tests/misc/tvarious1.nim b/tests/misc/tvarious1.nim index 595c77919..9c0b541db 100644 --- a/tests/misc/tvarious1.nim +++ b/tests/misc/tvarious1.nim @@ -1,6 +1,6 @@ discard """ - file: "tlenopenarray.nim" - output: '''1 +output: ''' +1 0 Whopie 12 diff --git a/tests/misc/tvarnums.nim b/tests/misc/tvarnums.nim index 5daa2c4b8..39269b4c0 100644 --- a/tests/misc/tvarnums.nim +++ b/tests/misc/tvarnums.nim @@ -1,5 +1,4 @@ discard """ - file: "tvarnums.nim" output: "Success!" """ # Test variable length binary integers @@ -138,5 +137,3 @@ tm(low(int32)) tm(high(int32)) writeLine(stdout, "Success!") #OUT Success! - - diff --git a/tests/modules/m9627/a.nim b/tests/modules/m9627/a.nim new file mode 100644 index 000000000..0dd32430e --- /dev/null +++ b/tests/modules/m9627/a.nim @@ -0,0 +1 @@ +var a = 10 diff --git a/tests/modules/m9627/b.nim b/tests/modules/m9627/b.nim new file mode 100644 index 000000000..2806a78ed --- /dev/null +++ b/tests/modules/m9627/b.nim @@ -0,0 +1 @@ +var b = 9 diff --git a/tests/modules/t9627.nim b/tests/modules/t9627.nim new file mode 100644 index 000000000..daba46374 --- /dev/null +++ b/tests/modules/t9627.nim @@ -0,0 +1,7 @@ +discard """ + output: "109" +""" + +include m9627 / [a, b] + +echo a, b diff --git a/tests/modules/timportexcept.nim b/tests/modules/timportexcept.nim index 93a7fd642..40b748088 100644 --- a/tests/modules/timportexcept.nim +++ b/tests/modules/timportexcept.nim @@ -1,10 +1,9 @@ discard """ - line: 9 errormsg: "undeclared identifier: '%'" + line: 9 """ import strutils except `%` # doesn't work echo "$1" % "abc" - diff --git a/tests/modules/tmismatchedvisibility.nim b/tests/modules/tmismatchedvisibility.nim index 2e8636d1e..4bf244807 100644 --- a/tests/modules/tmismatchedvisibility.nim +++ b/tests/modules/tmismatchedvisibility.nim @@ -1,6 +1,6 @@ discard """ - line: 8 errormsg: "public implementation 'tmismatchedvisibility.foo(a: int)[declared in tmismatchedvisibility.nim(6, 5)]' has non-public forward declaration in " + line: 8 """ proc foo(a: int): int diff --git a/tests/modules/tnamspc.nim b/tests/modules/tnamspc.nim index 2f488644c..93ce71568 100644 --- a/tests/modules/tnamspc.nim +++ b/tests/modules/tnamspc.nim @@ -1,12 +1,10 @@ discard """ + errormsg: "undeclared identifier: \'global\'" file: "tnamspc.nim" line: 10 - errormsg: "undeclared identifier: \'global\'" """ # Test17 - test correct handling of namespaces import mnamspc1 global = 9 #ERROR - - diff --git a/tests/modules/tnotuniquename.nim b/tests/modules/tnotuniquename.nim index 2d8ce4869..403c8a47e 100644 --- a/tests/modules/tnotuniquename.nim +++ b/tests/modules/tnotuniquename.nim @@ -1,6 +1,6 @@ discard """ - file: "tnotuniquename/mnotuniquename.nim" errormsg: "module names need to be unique per Nimble package" + file: "tnotuniquename/mnotuniquename.nim" """ import mnotuniquename diff --git a/tests/modules/tnotuniquename2.nim b/tests/modules/tnotuniquename2.nim index 8e486d19f..7aa4de515 100644 --- a/tests/modules/tnotuniquename2.nim +++ b/tests/modules/tnotuniquename2.nim @@ -1,6 +1,6 @@ discard """ - file: "tnotuniquename/mnotuniquename.nim" errormsg: "module names need to be unique per Nimble package" + file: "tnotuniquename/mnotuniquename.nim" """ import mnotuniquename diff --git a/tests/modules/topaque.nim b/tests/modules/topaque.nim index 84e2388bc..94ff8ff25 100644 --- a/tests/modules/topaque.nim +++ b/tests/modules/topaque.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "undeclared field: \'buffer\'" file: "topaque.nim" line: 16 - errormsg: "undeclared field: \'buffer\'" """ # Test the new opaque types @@ -14,5 +14,3 @@ var L.filename = "ha" L.line = 34 L.buffer[0] = '\0' #ERROR_MSG undeclared field: 'buffer' - - diff --git a/tests/modules/trecinca.nim b/tests/modules/trecinca.nim index 7a74d7a46..56798dedd 100644 --- a/tests/modules/trecinca.nim +++ b/tests/modules/trecinca.nim @@ -1,12 +1,10 @@ discard """ + errormsg: "recursive dependency: 'trecincb.nim'" file: "trecincb.nim" line: 9 - errormsg: "recursive dependency: 'trecincb.nim'" """ # Test recursive includes include trecincb echo "trecina" - - diff --git a/tests/modules/trecincb.nim b/tests/modules/trecincb.nim index 1d3eb5503..30a5d7800 100644 --- a/tests/modules/trecincb.nim +++ b/tests/modules/trecincb.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "recursive dependency: 'trecincb.nim'" file: "trecincb.nim" line: 9 - errormsg: "recursive dependency: 'trecincb.nim'" """ # Test recursive includes @@ -9,5 +9,3 @@ discard """ include trecincb echo "trecinb" - - diff --git a/tests/modules/trecmod.nim b/tests/modules/trecmod.nim index 5f053bcae..43e510e87 100644 --- a/tests/modules/trecmod.nim +++ b/tests/modules/trecmod.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "recursive module dependency detected" file: "mrecmod.nim" line: 1 - errormsg: "recursive module dependency detected" disabled: true """ # recursive module diff --git a/tests/modules/tselfimport.nim b/tests/modules/tselfimport.nim index ddb3a5b09..7e50bef7c 100644 --- a/tests/modules/tselfimport.nim +++ b/tests/modules/tselfimport.nim @@ -1,9 +1,8 @@ discard """ + errormsg: "A module cannot import itself" file: "tselfimport.nim" line: 7 - errormsg: "A module cannot import itself" """ import strutils as su # guard against regression import tselfimport #ERROR echo("Hello World") - diff --git a/tests/namedparams/tnamedparams.nim b/tests/namedparams/tnamedparams.nim index 8799e8a15..d0774f0d8 100644 --- a/tests/namedparams/tnamedparams.nim +++ b/tests/namedparams/tnamedparams.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "type mismatch: got <input: string, filename: string, line: int literal(1), col: int literal(23)>" file: "tnamedparams.nim" line: 8 - errormsg: "type mismatch: got <input: string, filename: string, line: int literal(1), col: int literal(23)>" """ import pegs @@ -10,6 +10,3 @@ discard parsePeg( filename = "filename", line = 1, col = 23) - - - diff --git a/tests/niminaction/Chapter2/explicit_discard.nim b/tests/niminaction/Chapter2/explicit_discard.nim index 3e94c335b..9a3b4407e 100644 --- a/tests/niminaction/Chapter2/explicit_discard.nim +++ b/tests/niminaction/Chapter2/explicit_discard.nim @@ -1,7 +1,7 @@ discard """ - line: 7 errormsg: "has to be discarded" + line: 7 """ proc myProc(name: string): string = "Hello " & name -myProc("Dominik") \ No newline at end of file +myProc("Dominik") diff --git a/tests/niminaction/Chapter2/no_def_eq.nim b/tests/niminaction/Chapter2/no_def_eq.nim index 77f0a7dd8..b9d62e036 100644 --- a/tests/niminaction/Chapter2/no_def_eq.nim +++ b/tests/niminaction/Chapter2/no_def_eq.nim @@ -1,6 +1,6 @@ discard """ - line: 16 errormsg: "type mismatch" + line: 16 """ type @@ -13,4 +13,4 @@ type let dog: Dog = Dog(name: "Fluffy") let cat: Cat = Cat(name: "Fluffy") -echo(dog == cat) \ No newline at end of file +echo(dog == cat) diff --git a/tests/niminaction/Chapter2/no_iterator.nim b/tests/niminaction/Chapter2/no_iterator.nim index 331d69480..555fac21a 100644 --- a/tests/niminaction/Chapter2/no_iterator.nim +++ b/tests/niminaction/Chapter2/no_iterator.nim @@ -1,7 +1,7 @@ discard """ - line: 6 errormsg: "type mismatch" + line: 6 """ for i in 5: - echo i \ No newline at end of file + echo i diff --git a/tests/niminaction/Chapter2/no_seq_type.nim b/tests/niminaction/Chapter2/no_seq_type.nim index 493be270a..f1494124b 100644 --- a/tests/niminaction/Chapter2/no_seq_type.nim +++ b/tests/niminaction/Chapter2/no_seq_type.nim @@ -1,6 +1,6 @@ discard """ - line: 6 errormsg: "cannot infer the type of the sequence" + line: 6 """ -var list = @[] \ No newline at end of file +var list = @[] diff --git a/tests/niminaction/Chapter2/resultreject.nim b/tests/niminaction/Chapter2/resultreject.nim index de59af7d9..87c84bf0a 100644 --- a/tests/niminaction/Chapter2/resultreject.nim +++ b/tests/niminaction/Chapter2/resultreject.nim @@ -1,13 +1,13 @@ discard """ - line: 27 errormsg: "has to be discarded" + line: 27 """ # Page 35. proc implicit: string = "I will be returned" - + proc discarded: string = discard "I will not be returned" @@ -16,7 +16,7 @@ proc explicit: string = proc resultVar: string = result = "I will be returned" - + proc resultVar2: string = result = "" result.add("I will be ") @@ -30,4 +30,4 @@ doAssert implicit() == "I will be returned" doAssert discarded() == nil doAssert explicit() == "I will be returned" doAssert resultVar() == "I will be returned" -doAssert resultVar2() == "I will be returned" \ No newline at end of file +doAssert resultVar2() == "I will be returned" diff --git a/tests/niminaction/Chapter3/ChatApp/src/protocol.nim b/tests/niminaction/Chapter3/ChatApp/src/protocol.nim index af515861c..4c122d4cc 100644 --- a/tests/niminaction/Chapter3/ChatApp/src/protocol.nim +++ b/tests/niminaction/Chapter3/ChatApp/src/protocol.nim @@ -37,7 +37,7 @@ proc createMessage*(username, message: string): string = "message": %message }) & "\c\l" -when isMainModule: +when true: block: let data = """{"username": "dom", "message": "hello"}""" let parsed = parseMessage(data) diff --git a/tests/niminaction/Chapter3/ChatApp/src/server.nim b/tests/niminaction/Chapter3/ChatApp/src/server.nim index 31da74d16..fbf0e5110 100644 --- a/tests/niminaction/Chapter3/ChatApp/src/server.nim +++ b/tests/niminaction/Chapter3/ChatApp/src/server.nim @@ -79,7 +79,7 @@ proc loop(server: Server, port = 7687) {.async.} = # Check whether this module has been imported as a dependency to another # module, or whether this module is the main module. -when isMainModule: +when true: # Initialise a new server. var server = newServer() echo("Server initialised!") diff --git a/tests/niminaction/Chapter6/WikipediaStats/concurrency.nim b/tests/niminaction/Chapter6/WikipediaStats/concurrency.nim index f20e21f4d..766f07fa5 100644 --- a/tests/niminaction/Chapter6/WikipediaStats/concurrency.nim +++ b/tests/niminaction/Chapter6/WikipediaStats/concurrency.nim @@ -79,5 +79,5 @@ proc readChunks(filename: string, chunksize = 1000000): Stats = file.close() -when isMainModule: +when true: echo readChunks(filename) diff --git a/tests/niminaction/Chapter6/WikipediaStats/concurrency_regex.nim b/tests/niminaction/Chapter6/WikipediaStats/concurrency_regex.nim index dbd635634..19b157926 100644 --- a/tests/niminaction/Chapter6/WikipediaStats/concurrency_regex.nim +++ b/tests/niminaction/Chapter6/WikipediaStats/concurrency_regex.nim @@ -64,5 +64,5 @@ proc readChunks(filename: string, chunksize = 1000000): Stats = file.close() -when isMainModule: +when true: echo readChunks(filename) diff --git a/tests/niminaction/Chapter6/WikipediaStats/naive.nim b/tests/niminaction/Chapter6/WikipediaStats/naive.nim index ce995efaf..687177f74 100644 --- a/tests/niminaction/Chapter6/WikipediaStats/naive.nim +++ b/tests/niminaction/Chapter6/WikipediaStats/naive.nim @@ -29,5 +29,5 @@ proc parse(filename: string): tuple[projectName, pageTitle: string, file.close() -when isMainModule: +when true: echo parse(filename) diff --git a/tests/niminaction/Chapter6/WikipediaStats/parallel_counts.nim b/tests/niminaction/Chapter6/WikipediaStats/parallel_counts.nim index 74857367a..2c4a59d83 100644 --- a/tests/niminaction/Chapter6/WikipediaStats/parallel_counts.nim +++ b/tests/niminaction/Chapter6/WikipediaStats/parallel_counts.nim @@ -70,7 +70,7 @@ proc readPageCounts(filename: string, chunkSize = 1_000_000) = echo("Most popular is: ", mostPopular) -when isMainModule: +when true: const file = "pagecounts-20160101-050000" let filename = getCurrentDir() / file readPageCounts(filename) diff --git a/tests/niminaction/Chapter6/WikipediaStats/sequential_counts.nim b/tests/niminaction/Chapter6/WikipediaStats/sequential_counts.nim index 102dd15d3..f4bae3df5 100644 --- a/tests/niminaction/Chapter6/WikipediaStats/sequential_counts.nim +++ b/tests/niminaction/Chapter6/WikipediaStats/sequential_counts.nim @@ -32,7 +32,7 @@ proc readPageCounts(filename: string) = echo("Most popular is: ", mostPopular) -when isMainModule: +when true: const file = "pagecounts-20160101-050000" let filename = getCurrentDir() / file readPageCounts(filename) diff --git a/tests/niminaction/Chapter7/Tweeter/src/views/user.nim b/tests/niminaction/Chapter7/Tweeter/src/views/user.nim index f3791b493..18f3713b3 100644 --- a/tests/niminaction/Chapter7/Tweeter/src/views/user.nim +++ b/tests/niminaction/Chapter7/Tweeter/src/views/user.nim @@ -40,7 +40,7 @@ </div> #end proc # -#when isMainModule: +#when true: # echo renderUser(User(username: "d0m96<>", following: @[])) # echo renderMessages(@[ # Message(username: "d0m96", time: getTime(), msg: "Hello World!"), diff --git a/tests/niminaction/Chapter7/Tweeter/tests/database_test.nim b/tests/niminaction/Chapter7/Tweeter/tests/database_test.nim index da69a004c..a3cab4cba 100644 --- a/tests/niminaction/Chapter7/Tweeter/tests/database_test.nim +++ b/tests/niminaction/Chapter7/Tweeter/tests/database_test.nim @@ -4,7 +4,7 @@ outputsub: "All tests finished successfully!" import database, os, times -when isMainModule: +when true: removeFile("tweeter_test.db") var db = newDatabase("tweeter_test.db") db.setup() diff --git a/tests/notnil/tnotnil.nim b/tests/notnil/tnotnil.nim index aff3f8959..c33b6fcac 100644 --- a/tests/notnil/tnotnil.nim +++ b/tests/notnil/tnotnil.nim @@ -1,6 +1,6 @@ discard """ - line: 13 errormsg: "type mismatch" + line: 13 """ {.experimental: "notnil".} type diff --git a/tests/objects/tobjconstr.nim b/tests/objects/tobjconstr.nim index 7238d10c7..1e4d89d68 100644 --- a/tests/objects/tobjconstr.nim +++ b/tests/objects/tobjconstr.nim @@ -1,14 +1,15 @@ discard """ - output: '''(k: kindA, a: (x: "abc", z: [1, 1, 3]), method: ()) -(k: kindA, a: (x: "abc", z: [1, 2, 3]), method: ()) -(k: kindA, a: (x: "abc", z: [1, 3, 3]), method: ()) -(k: kindA, a: (x: "abc", z: [1, 4, 3]), method: ()) -(k: kindA, a: (x: "abc", z: [1, 5, 3]), method: ()) -(k: kindA, a: (x: "abc", z: [1, 6, 3]), method: ()) -(k: kindA, a: (x: "abc", z: [1, 7, 3]), method: ()) -(k: kindA, a: (x: "abc", z: [1, 8, 3]), method: ()) -(k: kindA, a: (x: "abc", z: [1, 9, 3]), method: ()) -(k: kindA, a: (x: "abc", z: [1, 10, 3]), method: ()) + output: ''' +(k: kindA, a: (x: "abc", z: @[1, 1, 3]), method: ()) +(k: kindA, a: (x: "abc", z: @[1, 2, 3]), method: ()) +(k: kindA, a: (x: "abc", z: @[1, 3, 3]), method: ()) +(k: kindA, a: (x: "abc", z: @[1, 4, 3]), method: ()) +(k: kindA, a: (x: "abc", z: @[1, 5, 3]), method: ()) +(k: kindA, a: (x: "abc", z: @[1, 6, 3]), method: ()) +(k: kindA, a: (x: "abc", z: @[1, 7, 3]), method: ()) +(k: kindA, a: (x: "abc", z: @[1, 8, 3]), method: ()) +(k: kindA, a: (x: "abc", z: @[1, 9, 3]), method: ()) +(k: kindA, a: (x: "abc", z: @[1, 10, 3]), method: ()) (y: 0, x: 123) (y: 678, x: 123) (z: 89, y: 0, x: 128) @@ -16,7 +17,8 @@ discard """ (y: 678, x: 123) (y: 0, x: 123) (y: 678, x: 123) -(y: 123, x: 678)''' +(y: 123, x: 678) +''' """ type @@ -32,13 +34,6 @@ type a: TArg `method`: TEmpty # bug #1791 -proc `$`[T](s: seq[T]): string = - result = "[" - for i, x in s: - if i > 0: result.add(", ") - result.add($x) - result.add("]") - proc main() = for i in 1..10: let d = TDummy(k: kindA, a: TArg(x: "abc", z: @[1,i,3]), `method`: TEmpty()) diff --git a/tests/objects/tobjpragma.nim b/tests/objects/tobjpragma.nim index 0a6cc893b..789b3ec4e 100644 --- a/tests/objects/tobjpragma.nim +++ b/tests/objects/tobjpragma.nim @@ -1,13 +1,14 @@ discard """ - file: "tobjpragma.nim" - output: '''2 + output: ''' +2 3 9 257 1 2 -3''' - disabled: "true" +3 +''' +disabled: "true" """ # Disabled since some versions of GCC ignore the 'packed' attribute diff --git a/tests/objects/toop1.nim b/tests/objects/toop1.nim index f4880e3c6..f22ddaf62 100644 --- a/tests/objects/toop1.nim +++ b/tests/objects/toop1.nim @@ -1,5 +1,4 @@ discard """ - file: "toop1.nim" output: "34[]o 5" """ # Test the stuff in the tutorial diff --git a/tests/objvariant/tadrdisc.nim b/tests/objvariant/tadrdisc.nim index 258fb42f3..a68dddf66 100644 --- a/tests/objvariant/tadrdisc.nim +++ b/tests/objvariant/tadrdisc.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "type mismatch: got <TKind>" file: "tadrdisc.nim" line: 20 - errormsg: "type mismatch: got <TKind>" """ # Test that the address of a dicriminants cannot be taken diff --git a/tests/objvariant/temptycaseobj.nim b/tests/objvariant/temptycaseobj.nim index 53171e054..2b2c40514 100644 --- a/tests/objvariant/temptycaseobj.nim +++ b/tests/objvariant/temptycaseobj.nim @@ -1,6 +1,6 @@ discard """ - line: 11 errormsg: "identifier expected, but got 'keyword of'" + line: 11 """ type @@ -10,5 +10,3 @@ type of enA: of enU: x, y: int of enO: a, b: string - - diff --git a/tests/objvariant/tvariantstack.nim b/tests/objvariant/tvariantstack.nim index 0cdde5a20..31a0d8b82 100644 --- a/tests/objvariant/tvariantstack.nim +++ b/tests/objvariant/tvariantstack.nim @@ -1,6 +1,5 @@ discard """ - file: "tvariantstack.nim" - output: "came here" +output: "came here" """ #BUG type diff --git a/tests/openarray/t8259.nim b/tests/openarray/t8259.nim index 40ff2b2f1..c07576997 100644 --- a/tests/openarray/t8259.nim +++ b/tests/openarray/t8259.nim @@ -1,6 +1,6 @@ discard """ - line: 6 errormsg: "invalid type: 'openarray[int]' for result" + line: 6 """ proc foo(a: openArray[int]):auto = a diff --git a/tests/openarray/topena1.nim b/tests/openarray/topena1.nim index 0dbc5506a..ed3a0cedb 100644 --- a/tests/openarray/topena1.nim +++ b/tests/openarray/topena1.nim @@ -1,12 +1,9 @@ discard """ + errormsg: "invalid type" file: "topena1.nim" line: 9 - errormsg: "invalid type" """ # Tests a special bug var x: ref openarray[string] #ERROR_MSG invalid type - - - diff --git a/tests/openarray/topenarrayrepr.nim b/tests/openarray/topenarrayrepr.nim index d276756bc..3784d4bbb 100644 --- a/tests/openarray/topenarrayrepr.nim +++ b/tests/openarray/topenarrayrepr.nim @@ -1,5 +1,4 @@ discard """ - file: "topenarrayrepr.nim" output: "5 - [1]" """ type @@ -12,6 +11,3 @@ proc Bar(n: int, m: openarray[int64]) = echo($n & " - " & repr(m)) Foo(5, Bar) #OUT 5 - [1] - - - diff --git a/tests/openarray/topenlen.nim b/tests/openarray/topenlen.nim index fec8e87b7..83d58ac5c 100644 --- a/tests/openarray/topenlen.nim +++ b/tests/openarray/topenlen.nim @@ -1,5 +1,4 @@ discard """ - file: "topenlen.nim" output: "7" """ # Tests a special bug @@ -14,5 +13,3 @@ proc p(a, b: openarray[string]): int = discard choose(["sh", "-c", $p([""], ["a"])]) echo($p(["", "ha", "abc"], ["xyz"])) #OUT 7 - - diff --git a/tests/openarray/tptrarrayderef.nim b/tests/openarray/tptrarrayderef.nim index 1e73be108..5c63f6f98 100644 --- a/tests/openarray/tptrarrayderef.nim +++ b/tests/openarray/tptrarrayderef.nim @@ -1,5 +1,4 @@ discard """ - file: "tptrarrayderef.nim" output: "OK" """ @@ -15,7 +14,7 @@ var proc mutate[T](arr:openarray[T], brr: openArray[T]) = for i in 0..arr.len-1: doAssert(arr[i] == brr[i]) - + mutate(arr, arr) #bug #2240 @@ -46,9 +45,9 @@ proc getFilledBuffer(sz: int): ref seq[char] = s[] = newSeq[char](sz) fillBuffer(s[]) return s - + let aa = getFilledBuffer(3) for i in 0..aa[].len-1: doAssert(aa[i] == chr(i)) - -echo "OK" \ No newline at end of file + +echo "OK" diff --git a/tests/osproc/ta_out.nim b/tests/osproc/ta_out.nim index 318a27d59..01b78eb11 100644 --- a/tests/osproc/ta_out.nim +++ b/tests/osproc/ta_out.nim @@ -1,14 +1,18 @@ discard """ output: ''' +start ta_out to stdout to stdout to stderr to stderr to stdout to stdout +end ta_out ''' """ +echo "start ta_out" + # This file is prefixed with an "a", because other tests # depend on it and it must be compiled first. stdout.writeLine("to stdout") @@ -25,3 +29,5 @@ stdout.writeLine("to stdout") stdout.flushFile() stdout.writeLine("to stdout") stdout.flushFile() + +echo "end ta_out" diff --git a/tests/osproc/texecps.nim b/tests/osproc/texecps.nim index 887d79bfb..10715fa0f 100644 --- a/tests/osproc/texecps.nim +++ b/tests/osproc/texecps.nim @@ -1,8 +1,3 @@ -discard """ - file: "texecps.nim" - output: "" -""" - import osproc, streams, strutils, os const NumberOfProcesses = 13 @@ -14,8 +9,7 @@ proc execCb(idx: int, p: Process) = if exitCode < len(gResults): gResults[exitCode] = p.outputStream.readAll.strip -when isMainModule: - +when true: if paramCount() == 0: gResults = newSeq[string](NumberOfProcesses) var checks = newSeq[string](NumberOfProcesses) diff --git a/tests/osproc/texitcode.nim b/tests/osproc/texitcode.nim index 6dc5508b5..558017716 100644 --- a/tests/osproc/texitcode.nim +++ b/tests/osproc/texitcode.nim @@ -1,5 +1,4 @@ discard """ - file: "texitcode.nim" output: "" """ diff --git a/tests/osproc/tstderr.nim b/tests/osproc/tstderr.nim index 7a39522a3..55b11eba5 100644 --- a/tests/osproc/tstderr.nim +++ b/tests/osproc/tstderr.nim @@ -1,10 +1,15 @@ discard """ - output: '''-------------------------------------- + output: ''' +start tstderr +-------------------------------------- to stderr to stderr -------------------------------------- ''' """ + +echo "start tstderr" + import osproc, os, streams const filename = "ta_out".addFileExt(ExeExt) diff --git a/tests/osproc/tstdin.nim b/tests/osproc/tstdin.nim index 9b49ed786..8579680ab 100644 --- a/tests/osproc/tstdin.nim +++ b/tests/osproc/tstdin.nim @@ -1,5 +1,4 @@ discard """ - file: "tstdin.nim" output: "10" """ import osproc, os, streams diff --git a/tests/osproc/tstdout.nim b/tests/osproc/tstdout.nim index 0cb5bd9c0..e3ed3986a 100644 --- a/tests/osproc/tstdout.nim +++ b/tests/osproc/tstdout.nim @@ -1,11 +1,13 @@ discard """ output: '''-------------------------------------- +start ta_out to stdout to stdout to stderr to stderr to stdout to stdout +end ta_out -------------------------------------- ''' """ diff --git a/tests/osproc/tworkingdir.nim b/tests/osproc/tworkingdir.nim index 7d58d5ae6..3a3c1b6ab 100644 --- a/tests/osproc/tworkingdir.nim +++ b/tests/osproc/tworkingdir.nim @@ -1,5 +1,4 @@ discard """ - file: "tworkingdir.nim" output: "" """ diff --git a/tests/overflw/toverflw.nim b/tests/overflw/toverflw.nim index 20bc56a53..aef597e6c 100644 --- a/tests/overflw/toverflw.nim +++ b/tests/overflw/toverflw.nim @@ -1,8 +1,6 @@ discard """ - file: "toverflw.nim" output: "ok" cmd: "nim $target -d:release $options $file" - """ # Tests nim's ability to detect overflows diff --git a/tests/overflw/toverflw2.nim b/tests/overflw/toverflw2.nim index 75bd4cdf5..91b900ca4 100644 --- a/tests/overflw/toverflw2.nim +++ b/tests/overflw/toverflw2.nim @@ -1,10 +1,7 @@ discard """ - file: "toverflw2.nim" outputsub: "Error: unhandled exception: over- or underflow [OverflowError]" exitcode: "1" """ var a : int32 = 2147483647 var b : int32 = 2147483647 var c = a + b - - diff --git a/tests/overflw/tovfint.nim b/tests/overflw/tovfint.nim index f775d2e1c..5c440a540 100644 --- a/tests/overflw/tovfint.nim +++ b/tests/overflw/tovfint.nim @@ -1,5 +1,4 @@ discard """ - file: "tovfint.nim" output: "works!" """ # this tests the new overflow literals @@ -19,5 +18,3 @@ else: write(stdout, "broken!\n") #OUT works! - - diff --git a/tests/overload/toverl.nim b/tests/overload/toverl.nim index 807b643a4..64257be77 100644 --- a/tests/overload/toverl.nim +++ b/tests/overload/toverl.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "redefinition of \'TNone\'" file: "toverl.nim" line: 11 - errormsg: "redefinition of \'TNone\'" """ # Test for overloading @@ -9,5 +9,3 @@ type TNone {.exportc: "_NONE", final.} = object proc TNone(a, b: int) = nil #ERROR_MSG attempt to redefine 'TNone' - - diff --git a/tests/overload/toverload_issues.nim b/tests/overload/toverload_issues.nim index 7980f51a9..fe1603a44 100644 --- a/tests/overload/toverload_issues.nim +++ b/tests/overload/toverload_issues.nim @@ -119,28 +119,24 @@ template test(loopCount: int, testBody: untyped): typed = test(loopCount, 0, testBody) echo "done extraI passed 0" -when isMainModule: - var - loops = 0 - - test 0, 0: - loops += 1 - echo "test 0 complete, loops=", loops - - test 1, 1.0: - loops += 1 - echo "test 1.0 complete, loops=", loops - - when true: - # when true we get the following compile time error: - # b.nim(35, 6) Error: expression 'loops += 1' has no type (or is ambiguous) - loops = 0 - test 2: - loops += 1 - echo "test no extra complete, loops=", loops +var + loops = 0 +test 0, 0: + loops += 1 +echo "test 0 complete, loops=", loops +test 1, 1.0: + loops += 1 +echo "test 1.0 complete, loops=", loops +when true: + # when true we get the following compile time error: + # b.nim(35, 6) Error: expression 'loops += 1' has no type (or is ambiguous) + loops = 0 + test 2: + loops += 1 + echo "test no extra complete, loops=", loops # bug #2229 type diff --git a/tests/parallel/tarray_of_channels.nim b/tests/parallel/tarray_of_channels.nim index e2a682bd5..5139920ea 100644 --- a/tests/parallel/tarray_of_channels.nim +++ b/tests/parallel/tarray_of_channels.nim @@ -34,5 +34,5 @@ proc main = sync() for ix in 1..3: channels[ix].close() -when isMainModule: +when true: main() diff --git a/tests/parallel/tgc_unsafe.nim b/tests/parallel/tgc_unsafe.nim index a4d96cd73..baf0dc24a 100644 --- a/tests/parallel/tgc_unsafe.nim +++ b/tests/parallel/tgc_unsafe.nim @@ -28,5 +28,5 @@ proc main = sync() for ix in 1..3: channels[ix].close() -when isMainModule: +when true: main() diff --git a/tests/parallel/tgc_unsafe2.nim b/tests/parallel/tgc_unsafe2.nim index 40bfbdadb..40af728fb 100644 --- a/tests/parallel/tgc_unsafe2.nim +++ b/tests/parallel/tgc_unsafe2.nim @@ -1,10 +1,10 @@ discard """ + errormsg: "'consumer' is not GC-safe as it calls 'track'" line: 28 nimout: '''tgc_unsafe2.nim(22, 6) Warning: 'trick' is not GC-safe as it accesses 'global' which is a global using GC'ed memory [GcUnsafe2] tgc_unsafe2.nim(26, 6) Warning: 'track' is not GC-safe as it calls 'trick' [GcUnsafe2] tgc_unsafe2.nim(28, 6) Error: 'consumer' is not GC-safe as it calls 'track' ''' - errormsg: "'consumer' is not GC-safe as it calls 'track'" """ import threadpool @@ -35,5 +35,5 @@ proc main = sync() for ix in 1..3: channels[ix].close() -when isMainModule: +when true: main() diff --git a/tests/parallel/tmissing_deepcopy.nim b/tests/parallel/tmissing_deepcopy.nim index 45fdf0f8f..694eb77db 100644 --- a/tests/parallel/tmissing_deepcopy.nim +++ b/tests/parallel/tmissing_deepcopy.nim @@ -36,6 +36,6 @@ proc update = for i in 0 .. people.high: spawn people[i].greet() -when isMainModule: +when true: setup() update() diff --git a/tests/parallel/tsimple_array_checks.nim b/tests/parallel/tsimple_array_checks.nim index ee9508074..5d6e87efe 100644 --- a/tests/parallel/tsimple_array_checks.nim +++ b/tests/parallel/tsimple_array_checks.nim @@ -59,5 +59,5 @@ proc maino = maino() # Doesn't work outside a proc -when isMainModule: +when true: main() diff --git a/tests/parallel/tsysspawnbadarg.nim b/tests/parallel/tsysspawnbadarg.nim index 2d3ffd241..a8f1ed401 100644 --- a/tests/parallel/tsysspawnbadarg.nim +++ b/tests/parallel/tsysspawnbadarg.nim @@ -1,6 +1,6 @@ discard """ - line: 9 errormsg: "'spawn' takes a call expression" + line: 9 cmd: "nim $target --threads:on $options $file" """ diff --git a/tests/parallel/twrong_refcounts.nim b/tests/parallel/twrong_refcounts.nim index 57e0588a0..ac428762d 100644 --- a/tests/parallel/twrong_refcounts.nim +++ b/tests/parallel/twrong_refcounts.nim @@ -48,6 +48,6 @@ proc update = # --- -when isMainModule: +when true: setup() update() diff --git a/tests/parser/tdomulttest.nim b/tests/parser/tdomulttest.nim index 418192ac8..9e1afd034 100644 --- a/tests/parser/tdomulttest.nim +++ b/tests/parser/tdomulttest.nim @@ -1,14 +1,14 @@ discard """ - file: "tdomulttest.nim" output: "555\ntest\nmulti lines\n99999999\nend" - disabled: true """ + proc foo(bar, baz: proc (x: int): int) = echo bar(555) echo baz(99999999) foo do (x: int) -> int: return x + do (x: int) -> int: echo("test") echo("multi lines") diff --git a/tests/parser/tinvcolonlocation1.nim b/tests/parser/tinvcolonlocation1.nim index 2fddab2f8..7fca5deb7 100644 --- a/tests/parser/tinvcolonlocation1.nim +++ b/tests/parser/tinvcolonlocation1.nim @@ -1,8 +1,8 @@ discard """ + errormsg: "expected: ':', but got: 'echo'" file: "tinvcolonlocation1.nim" line: 8 column: 7 - errormsg: "expected: ':', but got: 'echo'" """ try #<- missing ':' echo "try" diff --git a/tests/parser/tinvcolonlocation2.nim b/tests/parser/tinvcolonlocation2.nim index 4251598b9..e3de393b8 100644 --- a/tests/parser/tinvcolonlocation2.nim +++ b/tests/parser/tinvcolonlocation2.nim @@ -1,8 +1,8 @@ discard """ + errormsg: "expected: ':', but got: 'keyword finally'" file: "tinvcolonlocation2.nim" line: 11 column: 8 - errormsg: "expected: ':', but got: 'keyword finally'" """ try: echo "try" diff --git a/tests/parser/tinvcolonlocation3.nim b/tests/parser/tinvcolonlocation3.nim index a8db658eb..46252f24e 100644 --- a/tests/parser/tinvcolonlocation3.nim +++ b/tests/parser/tinvcolonlocation3.nim @@ -1,8 +1,8 @@ discard """ + errormsg: "expected: ':', but got: 'echo'" file: "tinvcolonlocation3.nim" line: 12 column: 7 - errormsg: "expected: ':', but got: 'echo'" """ try: echo "try" diff --git a/tests/parser/tinvwhen.nim b/tests/parser/tinvwhen.nim index 99701bdf5..7a47f69a4 100644 --- a/tests/parser/tinvwhen.nim +++ b/tests/parser/tinvwhen.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "invalid indentation" file: "tinvwhen.nim" line: 11 - errormsg: "invalid indentation" """ # This was parsed even though it should not! @@ -11,5 +11,3 @@ proc getcwd(buf: cstring, buflen: cint): cstring when defined(unix): {.importc: "getcwd", header: "<unistd.h>".} #ERROR_MSG invalid indentation elif defined(windows): {.importc: "getcwd", header: "<direct.h>"} else: {.error: "os library not ported to your OS. Please help!".} - - diff --git a/tests/parser/toprprec.nim b/tests/parser/toprprec.nim index 1acd381e7..363ad1c18 100644 --- a/tests/parser/toprprec.nim +++ b/tests/parser/toprprec.nim @@ -1,5 +1,4 @@ discard """ - file: "toprprec.nim" output: "done" """ # Test operator precedence: diff --git a/tests/parser/ttupleunpack.nim b/tests/parser/ttupleunpack.nim index aaa06f9f4..c7ab9ea15 100644 --- a/tests/parser/ttupleunpack.nim +++ b/tests/parser/ttupleunpack.nim @@ -1,9 +1,3 @@ -discard """ - file: "ttupleunpack.nim" - output: "" - exitcode: 0 -""" - proc returnsTuple(): (int, int, int) = (4, 2, 3) proc main2 = diff --git a/tests/pragmas/t6448.nim b/tests/pragmas/t6448.nim index 61e4a35d9..a1bd747a0 100644 --- a/tests/pragmas/t6448.nim +++ b/tests/pragmas/t6448.nim @@ -1,6 +1,6 @@ discard """ - line: 9 errormsg: '''ambiguous call; both foobar.async''' + line: 9 """ import foobar @@ -9,7 +9,7 @@ import asyncdispatch, macros proc bar() {.async.} = echo 42 -proc foo() {.async.} = +proc foo() {.async.} = await bar() asyncCheck foo() diff --git a/tests/pragmas/t8741.nim b/tests/pragmas/t8741.nim index 41f2f9e8a..c132c3543 100644 --- a/tests/pragmas/t8741.nim +++ b/tests/pragmas/t8741.nim @@ -1,6 +1,6 @@ discard """ - line: 9 errormsg: "cannot attach a custom pragma to 'a'" + line: 9 """ for a {.gensym, inject.} in @[1,2,3]: diff --git a/tests/pragmas/tcustom_pragma.nim b/tests/pragmas/tcustom_pragma.nim index ae0f39631..0bc4d2f18 100644 --- a/tests/pragmas/tcustom_pragma.nim +++ b/tests/pragmas/tcustom_pragma.nim @@ -174,3 +174,25 @@ type var foo: Something foo.cardinal = north doAssert foo.b.hasCustomPragma(thingy) == true + + +proc myproc(s: string): int = + {.thingy.}: + s.len + +doAssert myproc("123") == 3 + +let xx = compiles: + proc myproc_bad(s: string): int = + {.not_exist.}: + s.len +doAssert: xx == false + + +macro checkSym(s: typed{nkSym}): untyped = + let body = s.getImpl.body + doAssert body[1].kind == nnkPragmaBlock + doAssert body[1][0].kind == nnkPragma + doAssert body[1][0][0] == bindSym"thingy" + +checkSym(myproc) \ No newline at end of file diff --git a/tests/pragmas/tused.nim b/tests/pragmas/tused.nim index 83c62b7bb..7616c1215 100644 --- a/tests/pragmas/tused.nim +++ b/tests/pragmas/tused.nim @@ -1,11 +1,13 @@ discard """ nimout: ''' compile start -tused.nim(15, 8) Hint: 'tused.echoSub(a: int, b: int)[declared in tused.nim(15, 7)]' is declared but not used [XDeclaredButNotUsed] +tused.nim(17, 8) Hint: 'tused.echoSub(a: int, b: int)[declared in tused.nim(17, 7)]' is declared but not used [XDeclaredButNotUsed] compile end''' output: "8\n8" + joinable: false """ +# not joinable because paths in nimout differ when imported static: echo "compile start" @@ -31,5 +33,11 @@ block: implementArithOpsNew(int) echoAdd 3, 5 +# issue #9896 +type + MyEnum {.used.} = enum + Val1, Val2, Val3 + + static: echo "compile end" diff --git a/tests/pragmas/tuserpragma2.nim b/tests/pragmas/tuserpragma2.nim index bf8844e66..ce16c4649 100644 --- a/tests/pragmas/tuserpragma2.nim +++ b/tests/pragmas/tuserpragma2.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "can raise an unlisted exception: ref Exception" file: "tuserpragma2.nim" line: 11 - errormsg: "can raise an unlisted exception: ref Exception" """ # bug #7216 diff --git a/tests/proc/tprocredef.nim b/tests/proc/tprocredef.nim index 4ec771510..0cd6ec770 100644 --- a/tests/proc/tprocredef.nim +++ b/tests/proc/tprocredef.nim @@ -1,9 +1,8 @@ discard """ + errormsg: "redefinition of \'foo\'" file: "tprocredef.nim" line: 8 - errormsg: "redefinition of \'foo\'" """ proc foo(a: int, b: string) = discard proc foo(a: int, b: string) = discard - diff --git a/tests/range/tsubrange.nim b/tests/range/tsubrange.nim index 914e7c6e7..f778c55eb 100644 --- a/tests/range/tsubrange.nim +++ b/tests/range/tsubrange.nim @@ -1,6 +1,6 @@ discard """ - line: 20 errormsg: "cannot convert 60 to TRange" + line: 20 """ type @@ -18,4 +18,3 @@ p y const myConst: TRange = 60 - diff --git a/tests/range/tsubrange2.nim b/tests/range/tsubrange2.nim index 7097faed2..e0fb71c5f 100644 --- a/tests/range/tsubrange2.nim +++ b/tests/range/tsubrange2.nim @@ -1,5 +1,4 @@ discard """ - file: "tsubrange2.nim" outputsub: "value out of range: 50 [RangeError]" exitcode: "1" """ @@ -14,4 +13,3 @@ var r: TRange y = 50 p y - diff --git a/tests/range/tsubrange3.nim b/tests/range/tsubrange3.nim index f5bb2f161..d3aae87df 100644 --- a/tests/range/tsubrange3.nim +++ b/tests/range/tsubrange3.nim @@ -1,5 +1,4 @@ discard """ - file: "tsubrange.nim" outputsub: "value out of range: 50 [RangeError]" exitcode: "1" """ diff --git a/tests/rational/trat_float.nim b/tests/rational/trat_float.nim index 24797c4a0..663973bf9 100644 --- a/tests/rational/trat_float.nim +++ b/tests/rational/trat_float.nim @@ -1,7 +1,7 @@ discard """ + errormsg: '''type mismatch: got''' file: "trat_float.nim" line: "9,19" - errormsg: '''type mismatch: got''' """ import rationals var diff --git a/tests/realtimeGC/shared.nim b/tests/realtimeGC/shared.nim index 2d1dd6c3c..1abe42089 100644 --- a/tests/realtimeGC/shared.nim +++ b/tests/realtimeGC/shared.nim @@ -1,5 +1,6 @@ discard """ - cmd: "nim $target --debuginfo --hints:on --app:lib $options $file" +cmd: "nim $target --debuginfo --hints:on --app:lib $options $file" +action: compile """ import strutils diff --git a/tests/seq/tseq.nim b/tests/seq/tseq.nim index 1cb94b308..6a28bc8e6 100644 --- a/tests/seq/tseq.nim +++ b/tests/seq/tseq.nim @@ -203,3 +203,4 @@ block ttoseq: stdout.write(x) var y: type("a b c".split) y = "xzy" + stdout.write("\n") diff --git a/tests/sets/t2669.nim b/tests/sets/t2669.nim index 6b8eb0f54..0a92818fa 100644 --- a/tests/sets/t2669.nim +++ b/tests/sets/t2669.nim @@ -1,6 +1,6 @@ discard """ -line: 6 errormsg: "cannot convert 6 to range 1..5(int8)" +line: 6 """ var c: set[range[1i8..5i8]] = {1i8, 2i8, 6i8} diff --git a/tests/sets/tsets.nim b/tests/sets/tsets.nim index 13a5f54e6..bde25cf81 100644 --- a/tests/sets/tsets.nim +++ b/tests/sets/tsets.nim @@ -1,7 +1,8 @@ discard """ - file: "tsets.nim" - output: '''Ha ein F ist in s! -false''' +output: ''' +Ha ein F ist in s! +false +''' """ # Test the handling of sets diff --git a/tests/statictypes/t9255.nim b/tests/statictypes/t9255.nim index bc8df6656..86bc8c7f1 100644 --- a/tests/statictypes/t9255.nim +++ b/tests/statictypes/t9255.nim @@ -8,6 +8,6 @@ type mismatch: got <static[proc (a0: int): string{.noSideEffect, gcsafe, locks: macro fun(a: static float): untyped = discard -when isMainModule: +when true: proc bar(a0: int): string = discard fun(bar) diff --git a/tests/stdlib/nre/captures.nim b/tests/stdlib/nre/captures.nim index 31de71154..bd5e83ecc 100644 --- a/tests/stdlib/nre/captures.nim +++ b/tests/stdlib/nre/captures.nim @@ -9,16 +9,16 @@ suite "captures": test "capture bounds are correct": let ex1 = re("([0-9])") check("1 23".find(ex1).matchBounds == 0 .. 0) - check("1 23".find(ex1).captureBounds[0].get == 0 .. 0) + check("1 23".find(ex1).captureBounds[0] == 0 .. 0) check("1 23".find(ex1, 1).matchBounds == 2 .. 2) check("1 23".find(ex1, 3).matchBounds == 3 .. 3) let ex2 = re("()()()()()()()()()()([0-9])") - check("824".find(ex2).captureBounds[0].get == 0 .. -1) - check("824".find(ex2).captureBounds[10].get == 0 .. 0) + check("824".find(ex2).captureBounds[0] == 0 .. -1) + check("824".find(ex2).captureBounds[10] == 0 .. 0) let ex3 = re("([0-9]+)") - check("824".find(ex3).captureBounds[0].get == 0 .. 2) + check("824".find(ex3).captureBounds[0] == 0 .. 2) test "named captures": let ex1 = "foobar".find(re("(?<foo>foo)(?<bar>bar)")) @@ -26,13 +26,19 @@ suite "captures": check(ex1.captures["bar"] == "bar") let ex2 = "foo".find(re("(?<foo>foo)(?<bar>bar)?")) + check("foo" in ex2.captureBounds) check(ex2.captures["foo"] == "foo") - check(ex2.captures["bar"] == "") + check(not ("bar" in ex2.captures)) + expect KeyError: + discard ex2.captures["bar"] test "named capture bounds": let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?")) - check(ex1.captureBounds["foo"] == some(0..2)) - check(ex1.captureBounds["bar"] == none(Slice[int])) + check("foo" in ex1.captureBounds) + check(ex1.captureBounds["foo"] == 0..2) + check(not ("bar" in ex1.captures)) + expect KeyError: + discard ex1.captures["bar"] test "capture count": let ex1 = re("(?<foo>foo)(?<bar>bar)?") @@ -41,19 +47,18 @@ suite "captures": test "named capture table": let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?")) - check(ex1.captures.toTable == {"foo" : "foo", "bar" : ""}.toTable()) - check(ex1.captureBounds.toTable == {"foo" : some(0..2), "bar" : none(Slice[int])}.toTable()) - check(ex1.captures.toTable("") == {"foo" : "foo", "bar" : ""}.toTable()) + check(ex1.captures.toTable == {"foo" : "foo"}.toTable()) + check(ex1.captureBounds.toTable == {"foo" : 0..2}.toTable()) let ex2 = "foobar".find(re("(?<foo>foo)(?<bar>bar)?")) check(ex2.captures.toTable == {"foo" : "foo", "bar" : "bar"}.toTable()) test "capture sequence": let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?")) - check(ex1.captures.toSeq == @["foo", ""]) + check(ex1.captures.toSeq == @[some("foo"), none(string)]) check(ex1.captureBounds.toSeq == @[some(0..2), none(Slice[int])]) - check(ex1.captures.toSeq("") == @["foo", ""]) + check(ex1.captures.toSeq(some("")) == @[some("foo"), some("")]) let ex2 = "foobar".find(re("(?<foo>foo)(?<bar>bar)?")) - check(ex2.captures.toSeq == @["foo", "bar"]) + check(ex2.captures.toSeq == @[some("foo"), some("bar")]) diff --git a/tests/stdlib/nre/match.nim b/tests/stdlib/nre/match.nim index 38ee5214b..06b69fd04 100644 --- a/tests/stdlib/nre/match.nim +++ b/tests/stdlib/nre/match.nim @@ -10,9 +10,9 @@ suite "match": check("abc".match(re"(\w)").captures[0] == "a") check("abc".match(re"(?<letter>\w)").captures["letter"] == "a") check("abc".match(re"(\w)\w").captures[-1] == "ab") - check("abc".match(re"(\w)").captureBounds[0].get == 0 .. 0) - check("abc".match(re"").captureBounds[-1].get == 0 .. -1) - check("abc".match(re"abc").captureBounds[-1].get == 0 .. 2) + check("abc".match(re"(\w)").captureBounds[0] == 0 .. 0) + check("abc".match(re"").captureBounds[-1] == 0 .. -1) + check("abc".match(re"abc").captureBounds[-1] == 0 .. 2) test "match test cases": check("123".match(re"").matchBounds == 0 .. -1) diff --git a/tests/stdlib/nre/replace.nim b/tests/stdlib/nre/replace.nim index b762271a2..812a7f384 100644 --- a/tests/stdlib/nre/replace.nim +++ b/tests/stdlib/nre/replace.nim @@ -16,5 +16,7 @@ suite "replace": check("123".replace(re"(?<foo>\d)(\d)", "${foo}$#$#") == "1123") test "replacing missing captures should throw instead of segfaulting": - discard "ab".replace(re"(a)|(b)", "$1$2") - discard "b".replace(re"(a)?(b)", "$1$2") + expect IndexError: discard "ab".replace(re"(a)|(b)", "$1$2") + expect IndexError: discard "b".replace(re"(a)?(b)", "$1$2") + expect KeyError: discard "b".replace(re"(a)?", "${foo}") + expect KeyError: discard "b".replace(re"(?<foo>a)?", "${foo}") diff --git a/tests/stdlib/t8925.nim b/tests/stdlib/t8925.nim index d3dc1ea86..dbf55fd88 100644 --- a/tests/stdlib/t8925.nim +++ b/tests/stdlib/t8925.nim @@ -1,6 +1,6 @@ discard """ - file: "strscans.nim" errormsg: "type mismatch between pattern '$i' (position: 1) and HourRange var 'hour'" + file: "strscans.nim" """ import strscans diff --git a/tests/stdlib/tbitops.nim b/tests/stdlib/tbitops.nim index 8301256c4..d8c6da1d4 100644 --- a/tests/stdlib/tbitops.nim +++ b/tests/stdlib/tbitops.nim @@ -1,5 +1,4 @@ discard """ - file: "tbitops.nim" output: "OK" """ import bitops diff --git a/tests/stdlib/tbitops2.nim b/tests/stdlib/tbitops2.nim index 31952316c..e8c7318be 100644 --- a/tests/stdlib/tbitops2.nim +++ b/tests/stdlib/tbitops2.nim @@ -1,5 +1,4 @@ discard """ - file: "tbitops.nim" output: "OK" """ import bitops diff --git a/tests/stdlib/tcgi.nim b/tests/stdlib/tcgi.nim index 23b8b82ca..bc177125e 100644 --- a/tests/stdlib/tcgi.nim +++ b/tests/stdlib/tcgi.nim @@ -1,9 +1,3 @@ -discard """ - action: run - file: tcgi.nim - output: "[Suite] Test cgi module" -""" - import unittest import cgi, strtabs diff --git a/tests/stdlib/tjsonmacro.nim b/tests/stdlib/tjsonmacro.nim index bf0bb3ea7..33332447b 100644 --- a/tests/stdlib/tjsonmacro.nim +++ b/tests/stdlib/tjsonmacro.nim @@ -1,10 +1,9 @@ discard """ - file: "tjsonmacro.nim" output: "" """ import json, strutils, options, tables -when isMainModule: +when true: # Tests inspired by own use case (with some additional tests). # This should succeed. type diff --git a/tests/stdlib/tjsonmacro_reject.nim b/tests/stdlib/tjsonmacro_reject.nim index 00506449f..ada365d7d 100644 --- a/tests/stdlib/tjsonmacro_reject.nim +++ b/tests/stdlib/tjsonmacro_reject.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "Use a named tuple instead of: (string, float)" file: "tjsonmacro_reject.nim" line: 11 - errormsg: "Use a named tuple instead of: (string, float)" """ import json @@ -15,4 +15,4 @@ let j = """ {"engine": {"name": "V8", "capacity": 5.5}, model: "Skyline"} """ let parsed = parseJson(j) -echo(to(parsed, Car)) \ No newline at end of file +echo(to(parsed, Car)) diff --git a/tests/stdlib/tjsonmacro_reject2.nim b/tests/stdlib/tjsonmacro_reject2.nim index b01153553..e13dad307 100644 --- a/tests/stdlib/tjsonmacro_reject2.nim +++ b/tests/stdlib/tjsonmacro_reject2.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "The `to` macro does not support ref objects with cycles." file: "tjsonmacro_reject2.nim" line: 10 - errormsg: "The `to` macro does not support ref objects with cycles." """ import json @@ -18,4 +18,4 @@ let data = """ """ let dataParsed = parseJson(data) -let dataDeser = to(dataParsed, Cycle) \ No newline at end of file +let dataDeser = to(dataParsed, Cycle) diff --git a/tests/stdlib/tlists.nim b/tests/stdlib/tlists.nim index b7c7f9f5a..a288af781 100644 --- a/tests/stdlib/tlists.nim +++ b/tests/stdlib/tlists.nim @@ -10,7 +10,8 @@ const block SinglyLinkedListTest1: var L: SinglyLinkedList[int] for d in items(data): L.prepend(d) - assert($L == "[6, 5, 4, 3, 2, 1]") + for d in items(data): L.append(d) + assert($L == "[6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6]") assert(4 in L) diff --git a/tests/stdlib/tmemfiles1.nim b/tests/stdlib/tmemfiles1.nim index a18fba083..21a65369f 100644 --- a/tests/stdlib/tmemfiles1.nim +++ b/tests/stdlib/tmemfiles1.nim @@ -1,7 +1,3 @@ -discard """ - file: "tmemfiles1.nim" - outputsub: "" -""" import memfiles, os var mm: MemFile diff --git a/tests/stdlib/tmemmapstreams.nim b/tests/stdlib/tmemmapstreams.nim index 243574f1a..dd011d777 100644 --- a/tests/stdlib/tmemmapstreams.nim +++ b/tests/stdlib/tmemmapstreams.nim @@ -1,6 +1,6 @@ discard """ - file: "tmemmapstreams.nim" - output: '''Created size: 10 +output: ''' +Created size: 10 Position after writing: 5 Position after writing one char: 6 Peeked data: Hello diff --git a/tests/stdlib/tnativesockets.nim b/tests/stdlib/tnativesockets.nim deleted file mode 100644 index c2738b8a5..000000000 --- a/tests/stdlib/tnativesockets.nim +++ /dev/null @@ -1,11 +0,0 @@ -discard """ -outputsub: "" -""" - -import nativesockets, unittest - -suite "nativesockets": - test "getHostname": - let hostname = getHostname() - check hostname.len > 0 - check hostname.len < 64 diff --git a/tests/stdlib/tospaths.nim b/tests/stdlib/tospaths.nim index 9e2a5605c..bee9bab76 100644 --- a/tests/stdlib/tospaths.nim +++ b/tests/stdlib/tospaths.nim @@ -1,5 +1,4 @@ discard """ - file: "tospaths.nim" output: "" """ # test the ospaths module diff --git a/tests/stdlib/tosproc.nim b/tests/stdlib/tosproc.nim index ac129e709..9d57d4574 100644 --- a/tests/stdlib/tosproc.nim +++ b/tests/stdlib/tosproc.nim @@ -1,5 +1,4 @@ discard """ - file: "tospaths.nim" output: "" """ # test the osproc module diff --git a/tests/stdlib/tparsesql.nim b/tests/stdlib/tparsesql.nim index 126020ed6..8cf8fa848 100644 --- a/tests/stdlib/tparsesql.nim +++ b/tests/stdlib/tparsesql.nim @@ -1,7 +1,3 @@ -discard """ - file: "tparsesql.nim" -""" - import parsesql doAssert $parseSQL("SELECT foo FROM table;") == "select foo from table;" diff --git a/tests/stdlib/tquit.nim b/tests/stdlib/tquit.nim index 4f8d5fb20..1f9283ec4 100644 --- a/tests/stdlib/tquit.nim +++ b/tests/stdlib/tquit.nim @@ -2,6 +2,7 @@ discard """ output: ''' just exiting... ''' +joinable: false """ # Test the new beforeQuit variable: diff --git a/tests/stdlib/tregex.nim b/tests/stdlib/tregex.nim index ae6714de1..21f4e6743 100644 --- a/tests/stdlib/tregex.nim +++ b/tests/stdlib/tregex.nim @@ -1,5 +1,4 @@ discard """ - file: "tregex.nim" output: "key: keyAYes!" """ # Test the new regular expression module @@ -27,5 +26,3 @@ else: echo("Bug!") #OUT key: keyAYes! - - diff --git a/tests/stdlib/trepr.nim b/tests/stdlib/trepr.nim index 18fe7e054..33cb581ef 100644 --- a/tests/stdlib/trepr.nim +++ b/tests/stdlib/trepr.nim @@ -1,5 +1,4 @@ discard """ - file: "trepr.nim" output: "{a, b}{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}" """ @@ -26,4 +25,3 @@ when false: # "a", "b", "c", "d", "e" #] #echo(repr(testseq)) - diff --git a/tests/stdlib/tsqlparser.nim b/tests/stdlib/tsqlparser.nim index 4a7b2f7d7..11ee22e2b 100644 --- a/tests/stdlib/tsqlparser.nim +++ b/tests/stdlib/tsqlparser.nim @@ -6,7 +6,7 @@ discard """ import parsesql, streams, os -var tree = parseSql(newFileStream(getAppDir() / "somesql.sql"), "somesql") +var tree = parseSql(newFileStream(parentDir(currentSourcePath) / "somesql.sql"), "somesql") discard renderSql(tree) echo "true" diff --git a/tests/stdlib/tstdlib_various.nim b/tests/stdlib/tstdlib_various.nim index 7abc9a391..d1723df78 100644 --- a/tests/stdlib/tstdlib_various.nim +++ b/tests/stdlib/tstdlib_various.nim @@ -219,7 +219,7 @@ block tsplit2: block tsqlparser: # Just check that we can parse 'somesql' and render it without crashes. - var tree = parseSql(newFileStream(getAppDir() / "somesql.sql"), "somesql") + var tree = parseSql(newFileStream( parentDir(currentSourcePath) / "somesql.sql"), "somesql") discard renderSql(tree) diff --git a/tests/stdlib/tstreams2.nim b/tests/stdlib/tstreams2.nim index 90102d8e3..70f0bac32 100644 --- a/tests/stdlib/tstreams2.nim +++ b/tests/stdlib/tstreams2.nim @@ -1,5 +1,4 @@ discard """ - file: "tstreams2.nim" output: '''fs is: nil''' """ import streams diff --git a/tests/stdlib/tstreams3.nim b/tests/stdlib/tstreams3.nim index b2c9170e3..e3b395e05 100644 --- a/tests/stdlib/tstreams3.nim +++ b/tests/stdlib/tstreams3.nim @@ -1,5 +1,4 @@ discard """ - file: "tstreams3.nim" output: "threw exception" """ import streams diff --git a/tests/stdlib/tstring.nim b/tests/stdlib/tstring.nim index 660746150..852ff4fb7 100644 --- a/tests/stdlib/tstring.nim +++ b/tests/stdlib/tstring.nim @@ -1,5 +1,4 @@ discard """ - file: "tstring.nim" output: "OK" """ const characters = "abcdefghijklmnopqrstuvwxyz" diff --git a/tests/stdlib/tstrutil.nim b/tests/stdlib/tstrutil.nim index 64b8f8ecc..fffa85bd1 100644 --- a/tests/stdlib/tstrutil.nim +++ b/tests/stdlib/tstrutil.nim @@ -1,5 +1,4 @@ discard """ - file: "tstrutil.nim" output: "ha/home/a1xyz/usr/bin" """ # test the new strutils module diff --git a/tests/stdlib/tsugar.nim b/tests/stdlib/tsugar.nim index a870bf6fe..111ca96a4 100644 --- a/tests/stdlib/tsugar.nim +++ b/tests/stdlib/tsugar.nim @@ -1,5 +1,4 @@ discard """ - file: "tsugar.nim" output: "" """ import sugar diff --git a/tests/stdlib/ttimes.nim b/tests/stdlib/ttimes.nim index 7ebbe61d9..ed87b15ac 100644 --- a/tests/stdlib/ttimes.nim +++ b/tests/stdlib/ttimes.nim @@ -1,8 +1,5 @@ discard """ - file: "ttimes.nim" target: "c js" - output: '''[Suite] ttimes -''' """ import times, strutils, unittest @@ -125,7 +122,7 @@ suite "ttimes": when defined(linux) or defined(macosx): let tz_dir = getEnv("TZDIR", "/usr/share/zoneinfo") const f = "yyyy-MM-dd HH:mm zzz" - + let orig_tz = getEnv("TZ") var tz_cnt = 0 for tz_fn in walkFiles(tz_dir & "/**/*"): @@ -152,7 +149,7 @@ suite "ttimes": check initDateTime(29, mOct, 2017, 01, 00, 00).isDst check initDateTime(29, mOct, 2017, 03, 01, 00).format(f) == "2017-10-29 03:01 +01:00" check (not initDateTime(29, mOct, 2017, 03, 01, 00).isDst) - + check initDateTime(21, mOct, 2017, 01, 00, 00).format(f) == "2017-10-21 01:00 +02:00" test "issue #6520": @@ -170,10 +167,10 @@ suite "ttimes": check diff == initDuration(seconds = 2208986872) test "issue #6465": - putEnv("TZ", "Europe/Stockholm") + putEnv("TZ", "Europe/Stockholm") let dt = parse("2017-03-25 12:00", "yyyy-MM-dd hh:mm") check $(dt + initTimeInterval(days = 1)) == "2017-03-26T12:00:00+02:00" - check $(dt + initDuration(days = 1)) == "2017-03-26T13:00:00+02:00" + check $(dt + initDuration(days = 1)) == "2017-03-26T13:00:00+02:00" test "datetime before epoch": check $fromUnix(-2147483648).utc == "1901-12-13T20:45:52Z" diff --git a/tests/system/helpers/readall_echo.nim b/tests/system/helpers/readall_echo.nim index 79937bf6f..2891ef3ae 100644 --- a/tests/system/helpers/readall_echo.nim +++ b/tests/system/helpers/readall_echo.nim @@ -1,2 +1,2 @@ -when isMainModule: +when true: echo(stdin.readAll) diff --git a/tests/system/t7894.nim b/tests/system/t7894.nim index 27ee3f220..b7ca1eec8 100644 --- a/tests/system/t7894.nim +++ b/tests/system/t7894.nim @@ -1,6 +1,7 @@ discard """ disabled: "travis" disabled: "appveyor" +joinable: false """ # CI integration servers are out of memory for this test diff --git a/tests/system/talloc2.nim b/tests/system/talloc2.nim index e40c3f93c..7e0dec9d3 100644 --- a/tests/system/talloc2.nim +++ b/tests/system/talloc2.nim @@ -1,5 +1,6 @@ discard """ disabled: "windows" +joinable: false """ # appveyor is "out of memory" diff --git a/tests/system/tostring.nim b/tests/system/tostring.nim index 04b37f133..ea4a44417 100644 --- a/tests/system/tostring.nim +++ b/tests/system/tostring.nim @@ -1,5 +1,5 @@ discard """ - output: "" + output: "DONE: tostring.nim" """ doAssert "@[23, 45]" == $(@[23, 45]) @@ -115,3 +115,6 @@ block: var s: string s.addQuoted a2 doAssert s == "\"fo\\\"o2\"" + + +echo "DONE: tostring.nim" diff --git a/tests/system/tparams.nim b/tests/system/tparams.nim index 015530043..dcd620b20 100644 --- a/tests/system/tparams.nim +++ b/tests/system/tparams.nim @@ -1,3 +1,8 @@ +discard """ +joinable: false +""" + +# not joinable because it executes itself with parameters import os import osproc import parseopt2 diff --git a/tests/system/trealloc.nim b/tests/system/trealloc.nim index dc5f712d6..7180b8eda 100644 --- a/tests/system/trealloc.nim +++ b/tests/system/trealloc.nim @@ -1,5 +1,6 @@ discard """ output: '''success''' + joinable: false """ # bug #4818 diff --git a/tests/template/t_otemplates.nim b/tests/template/t_otemplates.nim index 6597bd37a..8d2ac38a6 100644 --- a/tests/template/t_otemplates.nim +++ b/tests/template/t_otemplates.nim @@ -340,6 +340,6 @@ macro tmpl*(body: untyped): untyped = # Run tests -when isMainModule: +when true: include otests echo "Success" diff --git a/tests/template/template_issues.nim b/tests/template/template_issues.nim index 8599b161a..15d6ab2b1 100644 --- a/tests/template/template_issues.nim +++ b/tests/template/template_issues.nim @@ -43,7 +43,7 @@ block t2629: let rst_files = concat(glob_rst(), glob_rst("docs")) - when isMainModule: echo rst_files + when true: echo rst_files block t5417: diff --git a/tests/template/tgensymregression.nim b/tests/template/tgensymregression.nim index 4cc64a831..4194e3e88 100644 --- a/tests/template/tgensymregression.nim +++ b/tests/template/tgensymregression.nim @@ -15,7 +15,7 @@ template mathPerComponent(op: untyped): untyped = mathPerComponent(`***`) # bug #5285 when true: - if isMainModule: + if true: var v1: array[3, float64] var v2: array[3, float64] echo repr(v1 *** v2) diff --git a/tests/template/thygienictempl.nim b/tests/template/thygienictempl.nim index 506f57148..9020c3e28 100644 --- a/tests/template/thygienictempl.nim +++ b/tests/template/thygienictempl.nim @@ -18,5 +18,5 @@ template test_in(a, b, c: untyped): bool {.dirty.} = var result {.gensym.}: bool = false false -when isMainModule: +when true: assert test_in(ret2, "test", str_val) diff --git a/tests/template/tparams_gensymed.nim b/tests/template/tparams_gensymed.nim index da86d63dc..91fa26596 100644 --- a/tests/template/tparams_gensymed.nim +++ b/tests/template/tparams_gensymed.nim @@ -70,3 +70,43 @@ proc genericProc(x: any) = concreteProc(7) # This works genericProc(7) # This doesn't compile + +import tables + +# bug #9476 +proc getTypeInfo*(T: typedesc): pointer = + var dummy: T + getTypeInfo(dummy) + + +macro implementUnary(op: untyped): untyped = + result = newStmtList() + + template defineTable(tableSymbol) = + var tableSymbol = initTable[pointer, pointer]() + let tableSymbol = genSym(nskVar, "registeredProcs") + result.add(getAst(defineTable(tableSymbol))) + + template defineRegisterInstantiation(tableSym, regTemplSym, instSym, op) = + template regTemplSym*(T: typedesc) = + let ti = getTypeInfo(T) + + proc instSym(xOrig: int): int {.gensym, cdecl.} = + let x {.inject.} = xOrig + op + + tableSym[ti] = cast[pointer](instSym) + + let regTemplSymbol = ident("registerInstantiation") + let instSymbol = ident("instantiation") + result.add(getAst(defineRegisterInstantiation( + tableSymbol, regTemplSymbol, instSymbol, op + ))) + + echo result.repr + + +implementUnary(): x*x + +registerInstantiation(int) +registerInstantiation(float) diff --git a/tests/template/ttempl2.nim b/tests/template/ttempl2.nim index aaa2f1344..eb67bea0c 100644 --- a/tests/template/ttempl2.nim +++ b/tests/template/ttempl2.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "undeclared identifier: \'b\'" file: "ttempl2.nim" line: 18 - errormsg: "undeclared identifier: \'b\'" """ template declareInScope(x: untyped, t: typeDesc): untyped {.immediate.} = var x: t @@ -16,4 +16,3 @@ a = 42 # works, `a` is known here declareInNewScope(b, int) b = 42 #ERROR_MSG undeclared identifier: 'b' - diff --git a/tests/template/twrongopensymchoice.nim b/tests/template/twrongopensymchoice.nim index 360c92037..7a2bb48d3 100644 --- a/tests/template/twrongopensymchoice.nim +++ b/tests/template/twrongopensymchoice.nim @@ -20,5 +20,5 @@ proc main = var f = Foo.new() echo f.b -when isMainModule: +when true: main() diff --git a/tests/testament/tshouldfail.nim b/tests/testament/tshouldfail.nim index 02e4bfd80..d35dd99ac 100644 --- a/tests/testament/tshouldfail.nim +++ b/tests/testament/tshouldfail.nim @@ -1,17 +1,31 @@ discard """ -cmd: "testament/tester --directory:testament --colors:off --nim:../compiler/nim category shouldfail" +cmd: "testament/tester --directory:testament --colors:off --backendLogging:off --nim:../compiler/nim category shouldfail" action: compile nimout: ''' FAIL: tccodecheck.nim C +Failure: reCodegenFailure +Expected: +baz FAIL: tcolumn.nim C +Failure: reLinesDiffer FAIL: terrormsg.nim C +Failure: reMsgsDiffer FAIL: texitcode1.nim C +Failure: reExitcodesDiffer FAIL: tfile.nim C +Failure: reFilesDiffer FAIL: tline.nim C +Failure: reLinesDiffer FAIL: tmaxcodesize.nim C +Failure: reCodegenFailure +max allowed size: 1 FAIL: tnimout.nim C +Failure: reMsgsDiffer FAIL: toutput.nim C +Failure: reOutputsDiffer FAIL: toutputsub.nim C +Failure: reOutputsDiffer FAIL: tsortoutput.nim C +Failure: reOutputsDiffer ''' """ diff --git a/tests/threads/t8535.nim b/tests/threads/t8535.nim index a8d69657b..e1b5a1369 100644 --- a/tests/threads/t8535.nim +++ b/tests/threads/t8535.nim @@ -12,5 +12,5 @@ type var foo {.threadvar.}: CircAlloc[1,Job] -when isMainModule: +when true: echo foo.index diff --git a/tests/threads/tthreadanalysis2.nim b/tests/threads/tthreadanalysis2.nim index c1ec3ae39..067e186a8 100644 --- a/tests/threads/tthreadanalysis2.nim +++ b/tests/threads/tthreadanalysis2.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "'threadFunc' is not GC-safe" file: "tthreadanalysis2.nim" line: 37 - errormsg: "'threadFunc' is not GC-safe" cmd: "nim $target --hints:on --threads:on $options $file" """ @@ -49,4 +49,3 @@ proc main = joinThreads(thr) main() - diff --git a/tests/threads/tthreadheapviolation1.nim b/tests/threads/tthreadheapviolation1.nim index 59ecb742c..379bd55e6 100644 --- a/tests/threads/tthreadheapviolation1.nim +++ b/tests/threads/tthreadheapviolation1.nim @@ -1,6 +1,6 @@ discard """ - line: 11 errormsg: "'horrible' is not GC-safe" + line: 11 cmd: "nim $target --hints:on --threads:on $options $file" """ @@ -16,5 +16,3 @@ proc horrible() {.thread.} = createThread[void](t, horrible) joinThread(t) - - diff --git a/tests/trmacros/tdisallowif.nim b/tests/trmacros/tdisallowif.nim index 18dfd1c82..36f60800e 100644 --- a/tests/trmacros/tdisallowif.nim +++ b/tests/trmacros/tdisallowif.nim @@ -1,6 +1,6 @@ discard """ - line: 24 errormsg: "usage of 'disallowIf' is a user-defined error" + line: 24 disabled: true """ diff --git a/tests/tuples/ttuples_various.nim b/tests/tuples/ttuples_various.nim index 36171d5d7..010893ced 100644 --- a/tests/tuples/ttuples_various.nim +++ b/tests/tuples/ttuples_various.nim @@ -121,7 +121,7 @@ block tuple_with_seq: proc g(t: tuple[n:int, xs:seq[int]]) = discard - when isMainModule: + when true: f(@[]) # OK g((1,@[1])) # OK g((0,@[])) # NG diff --git a/tests/tuples/twrongtupleaccess.nim b/tests/tuples/twrongtupleaccess.nim index b1684b097..591716a2e 100644 --- a/tests/tuples/twrongtupleaccess.nim +++ b/tests/tuples/twrongtupleaccess.nim @@ -1,10 +1,9 @@ discard """ + errormsg: "attempting to call undeclared routine: \'setBLAH\'" file: "twrongtupleaccess.nim" line: 9 - errormsg: "attempting to call undeclared routine: \'setBLAH\'" """ # Bugfix var v = (5.0, 10.0) v.setBLAH(10) - diff --git a/tests/typerel/t2plus.nim b/tests/typerel/t2plus.nim index d099eeeb0..4b18b6221 100644 --- a/tests/typerel/t2plus.nim +++ b/tests/typerel/t2plus.nim @@ -16,7 +16,7 @@ proc foldRight[T,U](lst: seq[T], v: U, f: (T, U) -> U): U = proc mean[T: SomeNumber](xs: seq[T]): T = xs.foldRight(0.T, (xBAZ: auto, yBAZ: auto) => xBAZ + yBAZ) / T(xs.len) -when isMainModule: +when true: let x = mean(@[1.float, 2, 3]) echo x diff --git a/tests/typerel/t8172.nim b/tests/typerel/t8172.nim index 8e0b32932..57b788250 100644 --- a/tests/typerel/t8172.nim +++ b/tests/typerel/t8172.nim @@ -1,6 +1,6 @@ discard """ - line: 11 errormsg: "cannot convert array[0..0, string] to varargs[string]" + line: 11 """ proc f(v: varargs[string]) = diff --git a/tests/typerel/temptynode.nim b/tests/typerel/temptynode.nim index df308fbc2..8c71a6092 100644 --- a/tests/typerel/temptynode.nim +++ b/tests/typerel/temptynode.nim @@ -1,6 +1,6 @@ discard """ - line: 16 errormsg: "type mismatch: got <void>" + line: 16 """ # bug #950 diff --git a/tests/typerel/texplicitcmp.nim b/tests/typerel/texplicitcmp.nim index e91ac2ffe..b11aa2f4e 100644 --- a/tests/typerel/texplicitcmp.nim +++ b/tests/typerel/texplicitcmp.nim @@ -24,9 +24,8 @@ proc weird(json_params: Table) = sort(f, system.cmp[int]) outp(f) -when isMainModule: - var t = @[3, 2, 1] - sort(t, system.cmp[int]) - outp(t) - works() - weird(initTable[string, JsonNode]()) +var t = @[3, 2, 1] +sort(t, system.cmp[int]) +outp(t) +works() +weird(initTable[string, JsonNode]()) diff --git a/tests/typerel/tno_int_in_bool_context.nim b/tests/typerel/tno_int_in_bool_context.nim index a4b4237d2..66e9da58a 100644 --- a/tests/typerel/tno_int_in_bool_context.nim +++ b/tests/typerel/tno_int_in_bool_context.nim @@ -1,8 +1,7 @@ discard """ - line: 6 errormsg: "type mismatch: got <int literal(1)> but expected 'bool'" + line: 6 """ if 1: echo "wtf?" - diff --git a/tests/typerel/tnocontains.nim b/tests/typerel/tnocontains.nim index a93db2fc3..8bea8aa56 100644 --- a/tests/typerel/tnocontains.nim +++ b/tests/typerel/tnocontains.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "type mismatch: got <string, string>" file: "tnocontains.nim" line: 10 - errormsg: "type mismatch: got <string, string>" """ # shouldn't compile since it doesn't do what you think it does without diff --git a/tests/typerel/trefs.nim b/tests/typerel/trefs.nim index d4383c562..e9862bd0f 100644 --- a/tests/typerel/trefs.nim +++ b/tests/typerel/trefs.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "type mismatch" file: "trefs.nim" line: 20 - errormsg: "type mismatch" """ # test for ref types (including refs to procs) @@ -18,6 +18,3 @@ var p: TProc p = foo write(stdout, "success!") p = wrongfoo #ERROR_MSG type mismatch - - - diff --git a/tests/typerel/tregionptrs.nim b/tests/typerel/tregionptrs.nim index 9eeded18b..504ec1011 100644 --- a/tests/typerel/tregionptrs.nim +++ b/tests/typerel/tregionptrs.nim @@ -1,6 +1,6 @@ discard """ - line: 16 errormsg: "type mismatch: got <BPtr> but expected 'APtr = ptr[RegionA, int]'" + line: 16 """ type diff --git a/tests/typerel/ttypedesc_as_genericparam1.nim b/tests/typerel/ttypedesc_as_genericparam1.nim index 9ae464842..b7c3e727d 100644 --- a/tests/typerel/ttypedesc_as_genericparam1.nim +++ b/tests/typerel/ttypedesc_as_genericparam1.nim @@ -1,6 +1,6 @@ discard """ - line: 6 errormsg: "type mismatch: got <type int>" + line: 6 """ # bug #3079, #1146 echo repr(int) diff --git a/tests/typerel/ttypedesc_as_genericparam2.nim b/tests/typerel/ttypedesc_as_genericparam2.nim index 0b4281269..ea06606f9 100644 --- a/tests/typerel/ttypedesc_as_genericparam2.nim +++ b/tests/typerel/ttypedesc_as_genericparam2.nim @@ -1,6 +1,6 @@ discard """ - line: 9 errormsg: "'repr' doesn't support 'void' type" + line: 9 """ # bug #2879 diff --git a/tests/typerel/ttypenoval.nim b/tests/typerel/ttypenoval.nim index 720e5d662..c7829f9dd 100644 --- a/tests/typerel/ttypenoval.nim +++ b/tests/typerel/ttypenoval.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "type mismatch: got <type int> but expected 'int'" file: "ttypenoval.nim" line: 38 - errormsg: "type mismatch: got <type int> but expected 'int'" """ # A min-heap. @@ -51,5 +51,3 @@ var newBinHeap(heap, 256) add(heap, 1, 100) print(heap) - - diff --git a/tests/typerel/typredef.nim b/tests/typerel/typredef.nim index 0b6aed875..c502a834c 100644 --- a/tests/typerel/typredef.nim +++ b/tests/typerel/typredef.nim @@ -1,8 +1,7 @@ discard """ + errormsg: "illegal recursion in type \'Uint8\'" file: "typredef.nim" line: 7 - errormsg: "illegal recursion in type \'Uint8\'" """ type Uint8 = Uint8 #ERROR_MSG illegal recursion in type 'Uint8' - diff --git a/tests/types/t6456.nim b/tests/types/t6456.nim index 2d2aad370..19bbc2c02 100644 --- a/tests/types/t6456.nim +++ b/tests/types/t6456.nim @@ -1,6 +1,6 @@ discard """ - line: 6 errormsg: "type \'ptr void\' is not allowed" + line: 6 """ proc foo(x: ptr void) = diff --git a/tests/types/tassignemptytuple.nim b/tests/types/tassignemptytuple.nim index bdfc653a5..9d5a311ba 100644 --- a/tests/types/tassignemptytuple.nim +++ b/tests/types/tassignemptytuple.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "cannot infer the type of the tuple" file: "tassignemptytuple.nim" line: 11 - errormsg: "cannot infer the type of the tuple" """ var diff --git a/tests/types/tillegaltyperecursion.nim b/tests/types/tillegaltyperecursion.nim index 6ead902b7..d8021c06f 100644 --- a/tests/types/tillegaltyperecursion.nim +++ b/tests/types/tillegaltyperecursion.nim @@ -59,7 +59,7 @@ proc Connect*(irc: var TIRC, nick: string, host: string, port: int = 6667) = -when isMainModule: +when true: var irc = initIRC() irc.Connect("AmryBot[Nim]","irc.freenode.net",6667) irc.sendRaw("JOIN #nim") diff --git a/tests/types/tillrec.nim b/tests/types/tillrec.nim index 18757140a..7584282b6 100644 --- a/tests/types/tillrec.nim +++ b/tests/types/tillrec.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "illegal recursion in type \'TIllegal\'" file: "tillrec.nim" line: 13 - errormsg: "illegal recursion in type \'TIllegal\'" """ # test illegal recursive types @@ -13,4 +13,3 @@ type TIllegal {.final.} = object #ERROR_MSG illegal recursion in type 'TIllegal' y: int x: array[0..3, TIllegal] - diff --git a/tests/types/tissues.nim b/tests/types/tissues_types.nim index 97c796302..d3643842e 100644 --- a/tests/types/tissues.nim +++ b/tests/types/tissues_types.nim @@ -9,8 +9,9 @@ ptr Foo (member: "hello world", x: ...) (member: 123.456, x: ...) ''' +joinable: false """ - +# not joinable because it causes out of memory with --gc:boehm import typetraits block t1252: diff --git a/tests/types/tparameterizedparent0.nim b/tests/types/tparameterizedparent0.nim index 1b72a4e21..90e7a9c0c 100644 --- a/tests/types/tparameterizedparent0.nim +++ b/tests/types/tparameterizedparent0.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "inheritance only works with non-final objects" file: "tparameterizedparent0.nim" line: 14 - errormsg: "inheritance only works with non-final objects" """ # bug #5264 type diff --git a/tests/types/tparameterizedparent1.nim b/tests/types/tparameterizedparent1.nim index 24fb9a565..5da8189f4 100644 --- a/tests/types/tparameterizedparent1.nim +++ b/tests/types/tparameterizedparent1.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "inheritance only works with non-final objects" file: "tparameterizedparent1.nim" line: 14 - errormsg: "inheritance only works with non-final objects" """ # bug #5264 type diff --git a/tests/types/tparameterizedparent3.nim b/tests/types/tparameterizedparent3.nim index 58aaf80ea..fcca6453e 100644 --- a/tests/types/tparameterizedparent3.nim +++ b/tests/types/tparameterizedparent3.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "attempt to redefine: 'color'" file: "tparameterizedparent3.nim" line: 13 - errormsg: "attempt to redefine: 'color'" """ # bug #5264 type diff --git a/tests/types/tparameterizedparent4.nim b/tests/types/tparameterizedparent4.nim index a37461bb4..4759d9d9b 100644 --- a/tests/types/tparameterizedparent4.nim +++ b/tests/types/tparameterizedparent4.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "attempt to redefine: 'grain'" file: "tparameterizedparent4.nim" line: 23 - errormsg: "attempt to redefine: 'grain'" """ # bug #5264 type diff --git a/tests/untestable/tssl.nim b/tests/untestable/tssl.nim index 664ad805c..fca6385f8 100644 --- a/tests/untestable/tssl.nim +++ b/tests/untestable/tssl.nim @@ -20,7 +20,7 @@ from strutils import contains, toHex from openssl import getOpenSSLVersion -when isMainModule: +when true: echo "version: 0x" & $getOpenSSLVersion().toHex() let client = newHttpClient() diff --git a/tests/usingstmt/tusingstatement.nim b/tests/usingstmt/tusingstatement.nim index 8585bcc9e..6e4998892 100644 --- a/tests/usingstmt/tusingstatement.nim +++ b/tests/usingstmt/tusingstatement.nim @@ -1,5 +1,4 @@ discard """ - file: "tusingstatement.nim" output: "Using test.Closing test." """ @@ -85,3 +84,5 @@ proc use(r: var TResource) = autoClose(r = openResource("test")): use r + +write stdout, "\n" diff --git a/tests/varres/tnewseq_on_result_vart.nim b/tests/varres/tnewseq_on_result_vart.nim index 18935a1d1..4a700468f 100644 --- a/tests/varres/tnewseq_on_result_vart.nim +++ b/tests/varres/tnewseq_on_result_vart.nim @@ -1,7 +1,7 @@ discard """ - line: 9 errormsg: "address of 'result' may not escape its stack frame" + line: 9 """ # bug #5113 diff --git a/tests/varres/tprevent_forloopvar_mutations.nim b/tests/varres/tprevent_forloopvar_mutations.nim index 15938bb77..43cc04f30 100644 --- a/tests/varres/tprevent_forloopvar_mutations.nim +++ b/tests/varres/tprevent_forloopvar_mutations.nim @@ -1,6 +1,6 @@ discard """ - line: 15 errmsg: "type mismatch: got <int>" + line: 15 nimout: '''type mismatch: got <int> but expected one of: proc inc[T: Ordinal | uint | uint64](x: var T; y = 1) diff --git a/tests/varres/tvarres1.nim b/tests/varres/tvarres1.nim index 5a5247142..e58d7f083 100644 --- a/tests/varres/tvarres1.nim +++ b/tests/varres/tvarres1.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "'bla' escapes its stack frame; context: 'bla'" file: "tvarres1.nim" line: 12 - errormsg: "'bla' escapes its stack frame; context: 'bla'" """ var @@ -14,4 +14,3 @@ proc p(): var int = p() = 45 echo g - diff --git a/tests/varres/tvarres2.nim b/tests/varres/tvarres2.nim index 53a57d882..4ec0bb05b 100644 --- a/tests/varres/tvarres2.nim +++ b/tests/varres/tvarres2.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "expression has no address" file: "tvarres2.nim" line: 11 - errormsg: "expression has no address" """ var @@ -13,4 +13,3 @@ proc p(): var int = p() = 45 echo g - diff --git a/tests/varres/tvarres_via_forwarding.nim b/tests/varres/tvarres_via_forwarding.nim index 8fd3dfcfd..fb7201ad2 100644 --- a/tests/varres/tvarres_via_forwarding.nim +++ b/tests/varres/tvarres_via_forwarding.nim @@ -1,6 +1,6 @@ discard """ - line: 10 errormsg: "'y' escapes its stack frame; context: 'forward(y)'" + line: 10 """ proc forward(x: var int): var int = result = x diff --git a/tests/varres/tvartup.nim b/tests/varres/tvartup.nim index 1957a3e35..a8f15b232 100644 --- a/tests/varres/tvartup.nim +++ b/tests/varres/tvartup.nim @@ -1,5 +1,4 @@ discard """ - file: "tvartup.nim" output: "2 3" """ # Test the new tuple unpacking @@ -9,5 +8,3 @@ proc divmod(a, b: int): tuple[di, mo: int] = var (x, y) = divmod(15, 6) echo x, " ", y - -#OUT 2 3 diff --git a/tests/varres/twrong_parameter.nim b/tests/varres/twrong_parameter.nim index 8a363dd19..58d01fd7e 100644 --- a/tests/varres/twrong_parameter.nim +++ b/tests/varres/twrong_parameter.nim @@ -1,6 +1,6 @@ discard """ - line: 10 errormsg: "'x' is not the first parameter; context: 'x.field[0]'" + line: 10 """ type diff --git a/tests/varstmt/tvardecl.nim b/tests/varstmt/tvardecl.nim index a6b508295..37bc4bad7 100644 --- a/tests/varstmt/tvardecl.nim +++ b/tests/varstmt/tvardecl.nim @@ -1,5 +1,4 @@ discard """ - file: "tvardecl.nim" output: "44" """ # Test the new variable declaration syntax @@ -10,6 +9,4 @@ var a, b: int = 4 write(stdout, a) -write(stdout, b) #OUT 44 - - +writeLine(stdout, b) #OUT 44 diff --git a/tests/vm/t2574.nim b/tests/vm/t2574.nim index 86602aeaf..4332667b4 100644 --- a/tests/vm/t2574.nim +++ b/tests/vm/t2574.nim @@ -1,6 +1,6 @@ discard """ - line: 14 errormsg: "cannot call method eval at compile time" + line: 14 """ type diff --git a/tests/vm/tcastint.nim b/tests/vm/tcastint.nim index f9d42fc54..437342a74 100644 --- a/tests/vm/tcastint.nim +++ b/tests/vm/tcastint.nim @@ -1,5 +1,4 @@ discard """ - file: "tcastint.nim" output: "OK" """ @@ -130,7 +129,7 @@ proc test_float_cast = doAssert(mantissa == 0, $mantissa) # construct 2^N float, where N is integer - let x = -2'i64 + let x = -2'i64 let xx = (x + exp_bias) shl exp_shift let xf = cast[float](xx) doAssert(xf == 0.25, $xf) @@ -151,7 +150,7 @@ proc test_float32_cast = doAssert(mantissa == 0, $mantissa) # construct 2^N float32 where N is integer - let x = 4'i32 + let x = 4'i32 let xx = (x + exp_bias) shl exp_shift let xf = cast[float32](xx) doAssert(xf == 16.0'f32, $xf) diff --git a/tests/vm/tconstobj.nim b/tests/vm/tconstobj.nim index 38fcdd844..021fcb728 100644 --- a/tests/vm/tconstobj.nim +++ b/tests/vm/tconstobj.nim @@ -1,10 +1,12 @@ discard """ - output: '''(name: "hello") -(-1, 0)''' + output: ''' +(name: "hello") +(-1, 0) +(FirstName: "James", LastName: "Franco") +''' """ # bug #2774, bug #3195 - type Foo = object name: string @@ -14,7 +16,6 @@ const fooArray = [ echo fooArray[0] - type Position = object x, y: int @@ -34,3 +35,16 @@ const ] echo offset[1] + +# bug #1547 +import tables + +type Person* = object + FirstName*: string + LastName*: string + +let people = { + "001": Person(FirstName: "James", LastName: "Franco") +}.toTable() + +echo people["001"] diff --git a/tests/vm/tforwardproc.nim b/tests/vm/tforwardproc.nim index 727ac6641..bcd929f0e 100644 --- a/tests/vm/tforwardproc.nim +++ b/tests/vm/tforwardproc.nim @@ -14,4 +14,4 @@ proc initArray(): array[10, int] = for f in 0..<10: result[f] = 3 -when isMainModule: echo repr(someTable) +when true: echo repr(someTable) diff --git a/tests/vm/tmitems.nim b/tests/vm/tmitems_vm.nim index 87835d1cd..87835d1cd 100644 --- a/tests/vm/tmitems.nim +++ b/tests/vm/tmitems_vm.nim diff --git a/tests/vm/tsetlen.nim b/tests/vm/tsetlen.nim new file mode 100644 index 000000000..9fd30f331 --- /dev/null +++ b/tests/vm/tsetlen.nim @@ -0,0 +1,30 @@ +type Foo = object + index: int + +block: + proc fun[T]() = + var foo: T + var n = 10 + + var foos: seq[T] + foos.setLen n + + n.inc + foos.setLen n + + for i in 0 ..< n: + let temp = foos[i] + when T is object: + doAssert temp.index == 0 + when T is ref object: + doAssert temp == nil + doAssert temp == foo + + static: + fun[Foo]() + fun[int]() + fun[float]() + fun[string]() + fun[(int, string)]() + fun[ref Foo]() + fun[seq[int]]() diff --git a/tests/vm/tvmmisc.nim b/tests/vm/tvmmisc.nim index 85de26e39..bd3aa2fcd 100644 --- a/tests/vm/tvmmisc.nim +++ b/tests/vm/tvmmisc.nim @@ -70,7 +70,9 @@ block: # Tests for VM ops block: static: - assert "vm" in getProjectPath() + # for joint test, the project path is different, so I disabled it: + when false: + assert "vm" in getProjectPath() let b = getEnv("UNSETENVVAR") assert b == "" diff --git a/tools/kochdocs.nim b/tools/kochdocs.nim index 7cd13b2ac..03a694449 100644 --- a/tools/kochdocs.nim +++ b/tools/kochdocs.nim @@ -129,6 +129,7 @@ lib/pure/math.nim lib/pure/matchers.nim lib/std/editdistance.nim lib/std/wordwrap.nim +lib/std/diff.nim lib/pure/algorithm.nim lib/pure/stats.nim lib/windows/winlean.nim |