Merge branch 'devel' of gh:/Araq/Nimrod into devel

This commit is contained in:
Zahary Karadjov
2014-02-15 20:46:54 +02:00
30 changed files with 240 additions and 76 deletions

View File

@@ -593,7 +593,7 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
proc genDeref(p: BProc, e: PNode, d: var TLoc) =
var a: TLoc
if mapType(e.sons[0].typ) == ctArray:
if mapType(e.sons[0].typ) in {ctArray, ctPtrToArray}:
# XXX the amount of hacks for C's arrays is incredible, maybe we should
# simply wrap them in a struct? --> Losing auto vectorization then?
expr(p, e.sons[0], d)

View File

@@ -185,7 +185,7 @@ proc mapType(typ: PType): TCTypeKind =
of tyPtr, tyVar, tyRef:
var base = skipTypes(typ.sons[0], typedescInst)
case base.kind
of tyOpenArray, tyArrayConstr, tyArray, tyVarargs: result = ctArray
of tyOpenArray, tyArrayConstr, tyArray, tyVarargs: result = ctPtrToArray
else: result = ctPtr
of tyPointer: result = ctPtr
of tySequence: result = ctNimSeq

View File

@@ -41,7 +41,8 @@ type
ctInt, ctInt8, ctInt16, ctInt32, ctInt64,
ctFloat, ctFloat32, ctFloat64, ctFloat128,
ctUInt, ctUInt8, ctUInt16, ctUInt32, ctUInt64,
ctArray, ctStruct, ctPtr, ctNimStr, ctNimSeq, ctProc, ctCString
ctArray, ctPtrToArray, ctStruct, ctPtr, ctNimStr, ctNimSeq, ctProc,
ctCString
TCFileSections* = array[TCFileSection, PRope] # represents a generated C file
TCProcSection* = enum # the sections a generated C proc consists of
cpsLocals, # section of local variables for C proc

View File

@@ -42,17 +42,23 @@ proc compilerMsgHandler(filename: string, line, col: int,
of mwUnsupportedLanguage: k = warnLanguageXNotSupported
globalError(newLineInfo(filename, line, col), k, arg)
proc docgenFindFile(s: string): string {.procvar.} =
result = options.findFile(s)
if result.len == 0:
result = getCurrentDir() / s
if not existsFile(result): result = ""
proc parseRst(text, filename: string,
line, column: int, hasToc: var bool,
rstOptions: TRstParseOptions): PRstNode =
result = rstParse(text, filename, line, column, hasToc, rstOptions,
options.findFile, compilerMsgHandler)
docgenFindFile, compilerMsgHandler)
proc newDocumentor*(filename: string, config: PStringTable): PDoc =
new(result)
initRstGenerator(result[], (if gCmd != cmdRst2tex: outHtml else: outLatex),
options.gConfigVars, filename, {roSupportRawDirective},
options.findFile, compilerMsgHandler)
docgenFindFile, compilerMsgHandler)
result.id = 100
proc dispA(dest: var PRope, xml, tex: string, args: openArray[PRope]) =

View File

@@ -9,7 +9,7 @@
## This module implements the 'implies' relation for guards.
import ast, astalgo, msgs, magicsys, nimsets, trees, types, renderer
import ast, astalgo, msgs, magicsys, nimsets, trees, types, renderer, idents
const
someEq = {mEqI, mEqI64, mEqF64, mEqEnum, mEqCh, mEqB, mEqRef, mEqProc,
@@ -69,9 +69,23 @@ proc isLetLocation(m: PNode, isApprox: bool): bool =
proc interestingCaseExpr*(m: PNode): bool = isLetLocation(m, true)
proc swapArgs(fact: PNode, newOp: string, m: TMagic): PNode =
proc getMagicOp(name: string, m: TMagic): PSym =
result = newSym(skProc, getIdent(name), nil, unknownLineInfo())
result.magic = m
let
opLe = getMagicOp("<=", mLeI)
opLt = getMagicOp("<", mLtI)
opAnd = getMagicOp("and", mAnd)
opOr = getMagicOp("or", mOr)
opNot = getMagicOp("not", mNot)
opIsNil = getMagicOp("isnil", mIsNil)
opContains = getMagicOp("contains", mInSet)
opEq = getMagicOp("==", mEqI)
proc swapArgs(fact: PNode, newOp: PSym): PNode =
result = newNodeI(nkCall, fact.info, 3)
result.sons[0] = newSymNode(getSysMagic(newOp, m))
result.sons[0] = newSymNode(newOp)
result.sons[1] = fact.sons[2]
result.sons[2] = fact.sons[1]
@@ -82,9 +96,9 @@ proc neg(n: PNode): PNode =
result = n.sons[1]
of someLt:
# not (a < b) == a >= b == b <= a
result = swapArgs(n, "<=", mLeI)
result = swapArgs(n, opLe)
of someLe:
result = swapArgs(n, "<", mLtI)
result = swapArgs(n, opLt)
of mInSet:
if n.sons[1].kind != nkCurly: return nil
let t = n.sons[2].typ.skipTypes(abstractInst)
@@ -110,7 +124,7 @@ proc neg(n: PNode): PNode =
b = n.sons[2].neg
if a != nil and b != nil:
result = newNodeI(nkCall, n.info, 3)
result.sons[0] = newSymNode(getSysMagic("and", mAnd))
result.sons[0] = newSymNode(opAnd)
result.sons[1] = a
result.sons[2] = b
elif a != nil:
@@ -120,12 +134,12 @@ proc neg(n: PNode): PNode =
else:
# leave not (a == 4) as it is
result = newNodeI(nkCall, n.info, 2)
result.sons[0] = newSymNode(getSysMagic("not", mNot))
result.sons[0] = newSymNode(opNot)
result.sons[1] = n
proc buildIsNil(arg: PNode): PNode =
result = newNodeI(nkCall, arg.info, 2)
result.sons[0] = newSymNode(getSysMagic("isNil", mIsNil))
result.sons[0] = newSymNode(opIsNil)
result.sons[1] = arg
proc usefulFact(n: PNode): PNode =
@@ -154,7 +168,7 @@ proc usefulFact(n: PNode): PNode =
b = usefulFact(n.sons[2])
if a != nil and b != nil:
result = newNodeI(nkCall, n.info, 3)
result.sons[0] = newSymNode(getSysMagic("and", mAnd))
result.sons[0] = newSymNode(opAnd)
result.sons[1] = a
result.sons[2] = b
elif a != nil:
@@ -177,7 +191,7 @@ proc usefulFact(n: PNode): PNode =
b = usefulFact(n.sons[2]).neg
if a != nil and b != nil:
result = newNodeI(nkCall, n.info, 3)
result.sons[0] = newSymNode(getSysMagic("and", mAnd))
result.sons[0] = newSymNode(opAnd)
result.sons[1] = a
result.sons[2] = b
result = result.neg
@@ -520,7 +534,7 @@ proc buildOf(it, loc: PNode): PNode =
s.typ = settype(loc)
for i in 0..it.len-2: s.sons[i] = it.sons[i]
result = newNodeI(nkCall, it.info, 3)
result.sons[0] = newSymNode(getSysMagic("contains", mInSet))
result.sons[0] = newSymNode(opContains)
result.sons[1] = s
result.sons[2] = loc
@@ -532,20 +546,20 @@ proc buildElse(n: PNode): PNode =
for j in 0..branch.len-2:
s.add(branch.sons[j])
result = newNodeI(nkCall, n.info, 3)
result.sons[0] = newSymNode(getSysMagic("contains", mInSet))
result.sons[0] = newSymNode(opContains)
result.sons[1] = s
result.sons[2] = n.sons[0]
proc addDiscriminantFact*(m: var TModel, n: PNode) =
var fact = newNodeI(nkCall, n.info, 3)
fact.sons[0] = newSymNode(getSysMagic("==", mEqI))
fact.sons[0] = newSymNode(opEq)
fact.sons[1] = n.sons[0]
fact.sons[2] = n.sons[1]
m.add fact
proc addAsgnFact*(m: var TModel, key, value: PNode) =
var fact = newNodeI(nkCall, key.info, 3)
fact.sons[0] = newSymNode(getSysMagic("==", mEqI))
fact.sons[0] = newSymNode(opEq)
fact.sons[1] = key
fact.sons[2] = value
m.add fact

View File

@@ -32,6 +32,7 @@ proc considerAcc*(n: PNode): PIdent =
of nkSym: id.add(x.sym.name.s)
else: globalError(n.info, errIdentifierExpected, renderTree(n))
result = getIdent(id)
of nkOpenSymChoice, nkClosedSymChoice: result = n.sons[0].sym.name
else:
globalError(n.info, errIdentifierExpected, renderTree(n))

View File

@@ -17,4 +17,6 @@ import:testability
cincludes: "$lib/wrappers/libffi/common"
@end
define:useStdoutAsStdmsg
cs:partial

View File

@@ -120,7 +120,8 @@ proc commonType*(x, y: PType): PType =
if a.kind == tyObject and b.kind == tyObject:
result = commonSuperclass(a, b)
# this will trigger an error later:
if result.isNil: return x
if result.isNil or result == a: return x
if result == b: return y
if k != tyNone:
let r = result
result = newType(k, r.owner)

View File

@@ -84,10 +84,10 @@ proc initVar(a: PEffects, n: PNode) =
proc initVarViaNew(a: PEffects, n: PNode) =
if n.kind != nkSym: return
let s = n.sym
if {tfNeedsInit, tfNotNil} * s.typ.flags == {tfNotNil}:
if {tfNeedsInit, tfNotNil} * s.typ.flags <= {tfNotNil}:
# 'x' is not nil, but that doesn't mean it's not nil children
# are initialized:
initVarViaNew(a, n)
initVar(a, n)
proc useVar(a: PEffects, n: PNode) =
let s = n.sym
@@ -466,8 +466,7 @@ proc track(tracked: PEffects, n: PNode) =
mergeEffects(tracked, effectList.sons[exceptionEffects], n)
mergeTags(tracked, effectList.sons[tagEffects], n)
for i in 1 .. <len(n): trackOperand(tracked, n.sons[i], paramType(op, i))
if a.kind == nkSym and a.sym.magic in {mNew, mNewFinalize,
mNewSeq, mShallowCopy}:
if a.kind == nkSym and a.sym.magic in {mNew, mNewFinalize, mNewSeq}:
# may not look like an assignment, but it is:
initVarViaNew(tracked, n.sons[1])
for i in 0 .. <safeLen(n):
@@ -477,7 +476,6 @@ proc track(tracked: PEffects, n: PNode) =
if warnProveField in gNotes: checkFieldAccess(tracked.guards, n)
of nkTryStmt: trackTryStmt(tracked, n)
of nkPragma: trackPragmaStmt(tracked, n)
of nkMacroDef, nkTemplateDef: discard
of nkAsgn, nkFastAsgn:
track(tracked, n.sons[1])
initVar(tracked, n.sons[0])
@@ -527,7 +525,9 @@ proc track(tracked: PEffects, n: PNode) =
if sfDiscriminant in x.sons[0].sym.flags:
addDiscriminantFact(tracked.guards, x)
setLen(tracked.guards, oldFacts)
of nkTypeSection: discard
of nkTypeSection, nkProcDef, nkConverterDef, nkMethodDef, nkIteratorDef,
nkMacroDef, nkTemplateDef:
discard
else:
for i in 0 .. <safeLen(n): track(tracked, n.sons[i])
@@ -581,22 +581,26 @@ proc setEffectsForProcType*(t: PType, n: PNode) =
if not isNil(tagsSpec):
effects.sons[tagEffects] = tagsSpec
proc initEffects(effects: PNode; s: PSym; t: var TEffects) =
newSeq(effects.sons, effectListLen)
effects.sons[exceptionEffects] = newNodeI(nkArgList, s.info)
effects.sons[tagEffects] = newNodeI(nkArgList, s.info)
t.exc = effects.sons[exceptionEffects]
t.tags = effects.sons[tagEffects]
t.owner = s
t.init = @[]
t.guards = @[]
proc trackProc*(s: PSym, body: PNode) =
var effects = s.typ.n.sons[0]
internalAssert effects.kind == nkEffectList
# effects already computed?
if sfForward in s.flags: return
if effects.len == effectListLen: return
newSeq(effects.sons, effectListLen)
effects.sons[exceptionEffects] = newNodeI(nkArgList, body.info)
effects.sons[tagEffects] = newNodeI(nkArgList, body.info)
var t: TEffects
t.exc = effects.sons[exceptionEffects]
t.tags = effects.sons[tagEffects]
t.owner = s
t.init = @[]
t.guards = @[]
initEffects(effects, s, t)
track(t, body)
if not isEmptyType(s.typ.sons[0]) and tfNeedsInit in s.typ.sons[0].flags and
@@ -619,3 +623,12 @@ proc trackProc*(s: PSym, body: PNode) =
# after the check, use the formal spec:
effects.sons[tagEffects] = tagsSpec
proc trackTopLevelStmt*(module: PSym; n: PNode) =
if n.kind in {nkPragma, nkMacroDef, nkTemplateDef, nkProcDef,
nkTypeSection, nkConverterDef, nkMethodDef, nkIteratorDef}:
return
var effects = newNode(nkEffectList, n.info)
var t: TEffects
initEffects(effects, module, t)
track(t, n)

View File

@@ -153,6 +153,9 @@ proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode =
discard
of nkSym:
result.sym = replaceTypeVarsS(cl, n.sym)
if result.sym.typ.kind == tyEmpty:
# don't add the 'void' field
result = newNode(nkRecList, n.info)
of nkRecWhen:
var branch: PNode = nil # the branch to take
for i in countup(0, sonsLen(n) - 1):

View File

@@ -754,6 +754,7 @@ proc transformStmt*(module: PSym, n: PNode): PNode =
result = processTransf(c, n, module)
result = liftLambdasForTopLevel(module, result)
incl(result.flags, nfTransf)
when useEffectSystem: trackTopLevelStmt(module, result)
proc transformExpr*(module: PSym, n: PNode): PNode =
if nfTransf in n.flags:

View File

@@ -857,7 +857,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
if a.kind != b.kind: return false
of dcEqOrDistinctOf:
while a.kind == tyDistinct: a = a.sons[0]
if a.kind != b.kind: return false
if a.kind != b.kind: return false
case a.kind
of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
tyInt..tyBigNum, tyStmt, tyExpr:

View File

@@ -441,7 +441,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
decodeBImm(nkIntLit)
#assert regs[rb].kind == nkBracket
# also used by mNLen:
regs[ra].intVal = regs[rb].skipMeta.len - imm
regs[ra].intVal = regs[rb].skipMeta.safeLen - imm
of opcLenStr:
decodeBImm(nkIntLit)
if regs[rb].kind == nkNilLit:

View File

@@ -4,10 +4,10 @@
import os, streams, parsexml, strutils
if paramCount() < 1:
if paramCount() < 1:
quit("Usage: htmltitle filename[.html]")
var filename = addFileExt(ParamStr(1), "html")
var filename = addFileExt(paramStr(1), "html")
var s = newFileStream(filename, fmRead)
if s == nil: quit("cannot open the file " & filename)
var x: TXmlParser
@@ -23,13 +23,13 @@ while true:
title.add(x.charData)
x.next()
if x.kind == xmlElementEnd and cmpIgnoreCase(x.elementName, "title") == 0:
Echo("Title: " & title)
echo("Title: " & title)
quit(0) # Success!
else:
echo(x.errorMsgExpected("/title"))
of xmlEof: break # end of file reached
else: nil # ignore other events
else: discard # ignore other events
x.close()
quit("Could not determine title!")

View File

@@ -58,6 +58,15 @@ Boot options:
proc exe(f: string): string = return addFileExt(f, ExeExt)
proc findNim(): string =
var nimrod = "nimrod".exe
result = "bin" / nimrod
if existsFile(result): return
for dir in split(getEnv("PATH"), PathSep):
if existsFile(dir / nimrod): return dir / nimrod
# assume there is a symlink to the exe or something:
return nimrod
proc exec(cmd: string) =
echo(cmd)
if execShellCmd(cmd) != 0: quit("FAILURE")
@@ -70,15 +79,15 @@ const
compileNimInst = "-d:useLibzipSrc tools/niminst/niminst"
proc csource(args: string) =
exec("nimrod cc $1 -r $3 --var:version=$2 csource compiler/nimrod.ini $1" %
[args, NimrodVersion, compileNimInst])
exec("$4 cc $1 -r $3 --var:version=$2 csource compiler/nimrod.ini $1" %
[args, NimrodVersion, compileNimInst, findNim()])
proc zip(args: string) =
exec("nimrod cc -r $2 --var:version=$1 zip compiler/nimrod.ini" %
[NimrodVersion, compileNimInst])
exec("$3 cc -r $2 --var:version=$1 zip compiler/nimrod.ini" %
[NimrodVersion, compileNimInst, findNim()])
proc buildTool(toolname, args: string) =
exec("nimrod cc $# $#" % [args, toolname])
exec("$# cc $# $#" % [findNim(), args, toolname])
copyFile(dest="bin"/ splitFile(toolname).name.exe, source=toolname.exe)
proc inno(args: string) =
@@ -90,13 +99,13 @@ proc inno(args: string) =
NimrodVersion)
proc install(args: string) =
exec("nimrod cc -r $# --var:version=$# scripts compiler/nimrod.ini" %
[compileNimInst, NimrodVersion])
exec("$# cc -r $# --var:version=$# scripts compiler/nimrod.ini" %
[findNim(), compileNimInst, NimrodVersion])
exec("sh ./install.sh $#" % args)
proc web(args: string) =
exec(("nimrod cc -r tools/nimweb.nim web/nimrod --putenv:nimrodversion=$#" &
" --path:$#") % [NimrodVersion, getCurrentDir()])
exec("$# cc -r tools/nimweb.nim web/nimrod --putenv:nimrodversion=$#" %
[findNim(), NimrodVersion])
# -------------- boot ---------------------------------------------------------

View File

@@ -516,7 +516,7 @@ proc last*(node: PNimrodNode): PNimrodNode {.compileTime.} = node[node.high]
const
RoutineNodes* = {nnkProcDef, nnkMethodDef, nnkDo, nnkLambda}
RoutineNodes* = {nnkProcDef, nnkMethodDef, nnkDo, nnkLambda, nnkIteratorDef}
AtomicNodes* = {nnkNone..nnkNilLit}
CallNodes* = {nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand,
nnkCallStrLit, nnkHiddenCallConv}

View File

@@ -167,7 +167,7 @@ proc asyncSocket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM,
result = newAsyncSocket()
result.socket = socket(domain, typ, protocol, buffered)
result.proto = protocol
if result.socket == InvalidSocket: OSError(OSLastError())
if result.socket == invalidSocket: osError(osLastError())
result.socket.setBlocking(false)
proc toAsyncSocket*(sock: TSocket, state: TInfo = SockConnected): PAsyncSocket =
@@ -357,7 +357,7 @@ proc acceptAddr*(server: PAsyncSocket, client: var PAsyncSocket,
client.sslNeedAccept = false
client.info = SockConnected
if c == InvalidSocket: SocketError(server.socket)
if c == invalidSocket: socketError(server.socket)
c.setBlocking(false) # TODO: Needs to be tested.
# deleg.open is set in ``toDelegate``.
@@ -481,7 +481,7 @@ proc recvLine*(s: PAsyncSocket, line: var TaintedString): bool {.deprecated.} =
of RecvDisconnected:
result = true
of RecvFail:
s.SocketError(async = true)
s.socketError(async = true)
result = false
{.pop.}
@@ -615,11 +615,11 @@ proc poll*(d: PDispatcher, timeout: int = 500): bool =
if d.hasDataBuffered(d.deleVal):
hasDataBufferedCount.inc()
d.handleRead(d.deleVal)
if hasDataBufferedCount > 0: return True
if hasDataBufferedCount > 0: return true
if readDg.len() == 0 and writeDg.len() == 0:
## TODO: Perhaps this shouldn't return if errorDg has something?
return False
return false
if select(readDg, writeDg, errorDg, timeout) != 0:
for i in 0..len(d.delegates)-1:

View File

@@ -67,7 +67,7 @@ when withThreads:
proc hookAux(st: TStackTrace, costs: int) =
# this is quite performance sensitive!
when withThreads: Acquire profilingLock
when withThreads: acquire profilingLock
inc totalCalls
var last = high(st)
while last > 0 and isNil(st[last]): dec last
@@ -106,7 +106,7 @@ proc hookAux(st: TStackTrace, costs: int) =
h = ((5 * h) + 1) and high(profileData)
inc chain
maxChainLen = max(maxChainLen, chain)
when withThreads: Release profilingLock
when withThreads: release profilingLock
when defined(memProfiler):
const

View File

@@ -1037,7 +1037,10 @@ proc execShellCmd*(command: string): int {.rtl, extern: "nos$1",
## the process has finished. To execute a program without having a
## shell involved, use the `execProcess` proc of the `osproc`
## module.
result = c_system(command) shr 8
when defined(linux):
result = c_system(command) shr 8
else:
result = c_system(command)
# Environment handling cannot be put into RTL, because the ``envPairs``
# iterator depends on ``environment``.

View File

@@ -791,7 +791,10 @@ elif not defined(useNimRtl):
proc csystem(cmd: cstring): cint {.nodecl, importc: "system".}
proc execCmd(command: string): int =
result = csystem(command) shr 8
when defined(linux):
result = csystem(command) shr 8
else:
result = csystem(command)
proc createFdSet(fd: var TFdSet, s: seq[PProcess], m: var int) =
FD_ZERO(fd)

View File

@@ -134,6 +134,7 @@ proc gzerror*(thefile: gzFile, errnum: var int32): pbytef{.cdecl, dynlib: libz,
importc: "gzerror".}
proc adler32*(adler: uLong, buf: pbytef, length: uInt): uLong{.cdecl,
dynlib: libz, importc: "adler32".}
## **Warning**: Adler-32 requires at least a few hundred bytes to get rolling.
proc crc32*(crc: uLong, buf: pbytef, length: uInt): uLong{.cdecl, dynlib: libz,
importc: "crc32".}
proc deflateInitu*(strm: var TZStream, level: int32, version: cstring,

View File

@@ -19,5 +19,18 @@ var
new(a)
q(a)
# bug #914
var x = newWideCString("Hello")
echo "success"
# bug #833
type
PFuture*[T] = ref object
value*: T
finished*: bool
cb: proc (future: PFuture[T]) {.closure.}
var k = PFuture[void]()

View File

@@ -4,7 +4,7 @@ type
PMenuItem = ref object
proc createMenuItem*(menu: PMenu, label: string,
action: proc (i: PMenuItem, p: pointer) {.cdecl.}) = nil
action: proc (i: PMenuItem, p: pointer) {.cdecl.}) = discard
var s: PMenu
createMenuItem(s, "Go to definition...",

View File

@@ -0,0 +1,20 @@
#bug #712
import tables
proc test(): TTable[string, string] =
discard
proc test2(): TTable[string, string] =
discard
var x = 5
let blah =
case x
of 5:
test2()
of 2:
test()
else: test()
echo blah.len

35
tests/notnil/tnotnil3.nim Normal file
View File

@@ -0,0 +1,35 @@
discard """
errormsg: "cannot prove 'variable' is not nil"
line: 31
"""
# bug #584
# Testprogram for 'not nil' check
const testWithResult = true
type
A = object
B = object
C = object
a: ref A
b: ref B
proc testNotNil(c: ref C not nil) =
discard
when testWithResult:
proc testNotNilOnResult(): ref C =
new(result)
#result.testNotNil() # Here 'not nil' can't be proved
var variable: ref C
new(variable)
variable.testNotNil() # Here 'not nil' is proved
when testWithResult:
discard testNotNilOnResult()

View File

@@ -3,3 +3,16 @@ import mtempl5
echo templ()
#bug #892
proc parse_to_close(value: string, index: int, open='(', close=')'): int =
discard
# Call parse_to_close
template get_next_ident: stmt =
discard "{something}".parse_to_close(0, open = '{', close = '}')
get_next_ident()
#identifier expected, but found '(open|open|open)'

View File

@@ -9,7 +9,7 @@
## HTML generator for the tester.
import db_sqlite, cgi, backend, strutils
import db_sqlite, cgi, backend, strutils, json
const
TableHeader = """<table border="1">
@@ -114,8 +114,6 @@ proc getCommit(db: TDbConn, c: int): string =
for thisCommit in db.rows(sql"select id from [Commit] order by id desc"):
if commit == 0: result = thisCommit[0]
inc commit
if result.isNil:
quit "cannot determine commit " & $c
proc generateHtml*(filename: string, commit: int) =
const selRow = """select name, category, target, action,
@@ -161,20 +159,48 @@ proc generateHtml*(filename: string, commit: int) =
close(outfile)
proc generateJson*(filename: string, commit: int) =
const selRow = """select count(*),
const
selRow = """select count(*),
sum(result = 'reSuccess'),
sum(result = 'reIgnored')
from TestResult
where [commit] = ? and machine = ?
order by category"""
from TestResult
where [commit] = ? and machine = ?
order by category"""
selDiff = """select A.category || '/' || A.target || '/' || A.name,
A.result,
B.result
from TestResult A
inner join TestResult B
on A.name = B.name and A.category = B.category
where A.[commit] = ? and B.[commit] = ? and A.machine = ?
and A.result != B.result"""
var db = open(connection="testament.db", user="testament", password="",
database="testament")
let lastCommit = db.getCommit(commit)
if lastCommit.isNil:
quit "cannot determine commit " & $commit
let previousCommit = db.getCommit(commit-1)
var outfile = open(filename, fmWrite)
let data = db.getRow(sql(selRow), lastCommit, $backend.getMachine(db))
let machine = $backend.getMachine(db)
let data = db.getRow(sql(selRow), lastCommit, machine)
outfile.writeln("""{"total": $#, "passed": $#, "skipped": $#}""" % data)
outfile.writeln("""{"total": $#, "passed": $#, "skipped": $#""" % data)
if not previousCommit.isNil:
let diff = newJArray()
for row in db.rows(sql(selDiff), previousCommit, lastCommit, machine):
var obj = newJObject()
obj["name"] = %row[0]
obj["old"] = %row[1]
obj["new"] = %row[2]
diff.add obj
outfile.writeln(""", "diff": """)
outfile.writeln(diff.pretty)
outfile.writeln "}"
close(db)
close(outfile)

View File

@@ -4,7 +4,6 @@ version 0.9.4
- fix GC issues
- fix macros\tstringinterp.nim
- test and fix showoff
- fix closure iterators
Bugs

View File

@@ -130,7 +130,7 @@ proc walkDirRecursively(s: var seq[string], root, ext: string) =
if cmpIgnoreCase(ext, splitFile(f).ext) == 0:
add(s, f)
of pcDir: walkDirRecursively(s, f, ext)
of pcLinkToDir: nil
of pcLinkToDir: discard
proc addFiles(s: var seq[string], dir, ext: string, patterns: seq[string]) =
for p in items(patterns):
@@ -153,7 +153,7 @@ proc parseIniFile(c: var TConfigData) =
of cfgSectionStart:
section = normalize(k.section)
case section
of "project", "links", "tabs", "ticker", "documentation", "var": nil
of "project", "links", "tabs", "ticker", "documentation", "var": discard
else: echo("[Warning] Skipping unknown section: " & section)
of cfgKeyValuePair:
@@ -168,7 +168,7 @@ proc parseIniFile(c: var TConfigData) =
of "logo": c.logo = v
of "authors": c.authors = v
else: quit(errorStr(p, "unknown variable: " & k.key))
of "var": nil
of "var": discard
of "links":
let valID = v.split(';')
add(c.links, (k.key.replace('_', ' '), valID[1], valID[0]))
@@ -186,7 +186,7 @@ proc parseIniFile(c: var TConfigData) =
let vSplit = v.split('-')
doAssert vSplit.len == 2
c.quotations[k.key.normalize] = (vSplit[0], vSplit[1])
else: nil
else: discard
of cfgOption: quit(errorStr(p, "syntax error"))
of cfgError: quit(errorStr(p, k.msg))
@@ -211,9 +211,9 @@ proc buildDocSamples(c: var TConfigData, destPath: string) =
## it didn't make much sense to integrate into the existing generic
## documentation builders.
const src = "doc"/"docgen_sample.nim"
Exec("nimrod doc $# -o:$# $#" %
exec("nimrod doc $# -o:$# $#" %
[c.nimrodArgs, destPath / "docgen_sample.html", src])
Exec("nimrod doc2 $# -o:$# $#" %
exec("nimrod doc2 $# -o:$# $#" %
[c.nimrodArgs, destPath / "docgen_sample2.html", src])
proc buildDoc(c: var TConfigData, destPath: string) =