Merge branch 'bigbreak' of github.com:Araq/Nimrod into bigbreak

This commit is contained in:
Dominik Picheta 2014-09-14 13:11:35 +01:00
commit 59e5f3533b
21 changed files with 145 additions and 68 deletions

View file

@ -949,7 +949,7 @@ proc liftLambdas*(fn: PSym, body: PNode): PNode =
discard transformOuterProcBody(o, body, initIter(fn)) discard transformOuterProcBody(o, body, initIter(fn))
result = ex result = ex
finishEnvironments(o) finishEnvironments(o)
#if fn.name.s == "cbOuter": #if fn.name.s == "parseLong":
# echo rendertree(result, {renderIds}) # echo rendertree(result, {renderIds})
proc liftLambdasForTopLevel*(module: PSym, body: PNode): PNode = proc liftLambdasForTopLevel*(module: PSym, body: PNode): PNode =

View file

@ -56,6 +56,7 @@ proc lowerTupleUnpacking*(n: PNode; owner: PSym): PNode =
result.add newAsgnStmt(newSymNode(temp), value) result.add newAsgnStmt(newSymNode(temp), value)
for i in 0 .. n.len-3: for i in 0 .. n.len-3:
if n.sons[i].kind == nkSym: v.addVar(n.sons[i])
result.add newAsgnStmt(n.sons[i], newTupleAccess(value, i)) result.add newAsgnStmt(n.sons[i], newTupleAccess(value, i))
proc createObj*(owner: PSym, info: TLineInfo): PType = proc createObj*(owner: PSym, info: TLineInfo): PType =

View file

@ -442,7 +442,7 @@ type
TNoteKinds* = set[TNoteKind] TNoteKinds* = set[TNoteKind]
TFileInfo*{.final.} = object TFileInfo*{.final.} = object
fullPath*: string # This is a canonical full filesystem path fullPath: string # This is a canonical full filesystem path
projPath*: string # This is relative to the project's root projPath*: string # This is relative to the project's root
shortName*: string # short name of the module shortName*: string # short name of the module
quotedName*: PRope # cached quoted short name for codegen quotedName*: PRope # cached quoted short name for codegen

View file

@ -188,8 +188,9 @@ proc getPrefixDir*(): string =
result = splitPath(getAppDir()).head result = splitPath(getAppDir()).head
proc canonicalizePath*(path: string): string = proc canonicalizePath*(path: string): string =
result = path.expandFilename #result = path.expandFilename
when not FileSystemCaseSensitive: result = result.toLower when not FileSystemCaseSensitive: result = path.toLower
else: result = path
proc shortenDir*(dir: string): string = proc shortenDir*(dir: string): string =
## returns the interesting part of a dir ## returns the interesting part of a dir

View file

@ -110,7 +110,7 @@ template styleCheckDef*(info: TLineInfo; s: PSym) =
template styleCheckDef*(s: PSym) = template styleCheckDef*(s: PSym) =
styleCheckDef(s.info, s, s.kind) styleCheckDef(s.info, s, s.kind)
proc styleCheckUse*(info: TLineInfo; s: PSym) = proc styleCheckUseImpl(info: TLineInfo; s: PSym) =
if info.fileIndex < 0: return if info.fileIndex < 0: return
# we simply convert it to what it looks like in the definition # we simply convert it to what it looks like in the definition
# for consistency # for consistency
@ -138,3 +138,7 @@ proc styleCheckUse*(info: TLineInfo; s: PSym) =
system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x)
gSourceFiles[info.fileIndex].dirty = true gSourceFiles[info.fileIndex].dirty = true
#if newName == "File": writeStackTrace() #if newName == "File": writeStackTrace()
template styleCheckUse*(info: TLineInfo; s: PSym) =
when defined(nimfix):
if gStyleCheck != StyleCheck.None: styleCheckUseImpl(info, s)

View file

@ -354,7 +354,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
def = semExprWithType(c, a.sons[length-1], {efAllowDestructor}) def = semExprWithType(c, a.sons[length-1], {efAllowDestructor})
if typ != nil: if typ != nil:
if typ.isMetaType: if typ.isMetaType:
def = inferWithMetaType(c, typ, def) def = inferWithMetatype(c, typ, def)
typ = def.typ typ = def.typ
else: else:
# BUGFIX: ``fitNode`` is needed here! # BUGFIX: ``fitNode`` is needed here!

View file

@ -1135,14 +1135,14 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
of opcParseExprToAst: of opcParseExprToAst:
decodeB(rkNode) decodeB(rkNode)
# c.debug[pc].line.int - countLines(regs[rb].strVal) ? # c.debug[pc].line.int - countLines(regs[rb].strVal) ?
let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFilename, let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFullPath,
c.debug[pc].line.int) c.debug[pc].line.int)
if sonsLen(ast) != 1: if sonsLen(ast) != 1:
globalError(c.debug[pc], errExprExpected, "multiple statements") globalError(c.debug[pc], errExprExpected, "multiple statements")
regs[ra].node = ast.sons[0] regs[ra].node = ast.sons[0]
of opcParseStmtToAst: of opcParseStmtToAst:
decodeB(rkNode) decodeB(rkNode)
let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFilename, let ast = parseString(regs[rb].node.strVal, c.debug[pc].toFullPath,
c.debug[pc].line.int) c.debug[pc].line.int)
regs[ra].node = ast regs[ra].node = ast
of opcCallSite: of opcCallSite:

View file

@ -12,11 +12,11 @@ import ast, types, msgs, osproc, streams, options
proc readOutput(p: Process): string = proc readOutput(p: Process): string =
result = "" result = ""
var output = p.outputStream var output = p.outputStream
discard p.waitForExit
while not output.atEnd: while not output.atEnd:
result.add(output.readLine) result.add(output.readLine)
result.add("\n") result.add("\n")
result.setLen(result.len - "\n".len) result.setLen(result.len - "\n".len)
discard p.waitForExit
proc opGorge*(cmd, input: string): string = proc opGorge*(cmd, input: string): string =
var p = startCmd(cmd) var p = startCmd(cmd)

View file

@ -46,7 +46,6 @@ proc debugInfo(info: TLineInfo): string =
proc codeListing(c: PCtx, result: var string, start=0; last = -1) = proc codeListing(c: PCtx, result: var string, start=0; last = -1) =
# first iteration: compute all necessary labels: # first iteration: compute all necessary labels:
var jumpTargets = initIntSet() var jumpTargets = initIntSet()
let last = if last < 0: c.code.len-1 else: min(last, c.code.len-1) let last = if last < 0: c.code.len-1 else: min(last, c.code.len-1)
for i in start..last: for i in start..last:
let x = c.code[i] let x = c.code[i]

View file

@ -35,3 +35,5 @@ Options:
-r, --run run the compiled program with given arguments -r, --run run the compiled program with given arguments
--advanced show advanced command line switches --advanced show advanced command line switches
-h, --help show this help -h, --help show this help
Note: Even single letter options require the colon: -p:PATH.

View file

@ -138,6 +138,13 @@ from rst to HTML. It also repeats the same operation but places the result in
the ``web/upload`` which can be used to update the website at the ``web/upload`` which can be used to update the website at
http://nim-lang.org. http://nim-lang.org.
By default the documentation will be built in parallel using the number of
available CPU cores. If any documentation build sub commands fail, they will
be rerun in serial fashion so that meaninful error output can be gathered for
inspection. The ``--parallelBuild:n`` switch or configuration option can be
used to force a specific number of parallel jobs or run everything serially
from the start (``n == 1``).
zip command zip command
----------- -----------

View file

@ -596,7 +596,7 @@ Ordinal types
Ordinal types have the following characteristics: Ordinal types have the following characteristics:
- Ordinal types are countable and ordered. This property allows - Ordinal types are countable and ordered. This property allows
the operation of functions as ``Inc``, ``Ord``, ``Dec`` on ordinal types to the operation of functions as ``inc``, ``ord``, ``dec`` on ordinal types to
be defined. be defined.
- Ordinal values have a smallest possible value. Trying to count further - Ordinal values have a smallest possible value. Trying to count further
down than the smallest value gives a checked runtime or static error. down than the smallest value gives a checked runtime or static error.
@ -699,11 +699,11 @@ lowest and highest value of the type:
.. code-block:: nim .. code-block:: nim
type type
TSubrange = range[0..5] Subrange = range[0..5]
``TSubrange`` is a subrange of an integer which can only hold the values 0 ``Subrange`` is a subrange of an integer which can only hold the values 0
to 5. Assigning any other value to a variable of type ``TSubrange`` is a to 5. Assigning any other value to a variable of type ``Subrange`` is a
checked runtime error (or static error if it can be statically checked runtime error (or static error if it can be statically
determined). Assignments from the base type to one of its subrange types determined). Assignments from the base type to one of its subrange types
(and vice versa) are allowed. (and vice versa) are allowed.
@ -791,6 +791,10 @@ turned off as default.
The only operations that are affected by the ``floatChecks`` pragma are The only operations that are affected by the ``floatChecks`` pragma are
the ``+``, ``-``, ``*``, ``/`` operators for floating point types. the ``+``, ``-``, ``*``, ``/`` operators for floating point types.
An implementation should always use the maximum precision available to evaluate
floating pointer values at compile time; this means expressions like
``0.09'f32 + 0.01'f32 == 0.09'f64 + 0.01'f64`` are true.
Boolean type Boolean type
------------ ------------
@ -3675,10 +3679,11 @@ Future versions of Nim may also support overloading based on the return type
of the overloads. In such settings, the expected result type at call sites may of the overloads. In such settings, the expected result type at call sites may
also influence the inferred return type. also influence the inferred return type.
Likewise, if a type class is used in another position where Nim expects a ..
concrete type (e.g. a variable declaration or a type coercion), Nim will try to Likewise, if a type class is used in another position where Nim expects a
infer the concrete type by applying the sane matching algorithm also used in concrete type (e.g. a variable declaration or a type coercion), Nim will try
overload resolution. to infer the concrete type by applying the matching algorithm that also used
in overload resolution.
Symbol lookup in generics Symbol lookup in generics

View file

@ -1,14 +0,0 @@
import zmq
var connection = zmq.open("tcp://localhost:5555", server=false)
echo("Connecting...")
for i in 0..10:
echo("Sending hello...", i)
send(connection, "Hello")
var reply = receive(connection)
echo("Received ...", reply)
close(connection)

View file

@ -1,11 +0,0 @@
import zmq
var connection = zmq.open("tcp://*:5555", server=true)
while True:
var request = receive(connection)
echo("Received: ", request)
send(connection, "World")
close(connection)

View file

@ -28,8 +28,9 @@ proc parseCookies*(s: string): StringTableRef =
if s[i] == '\0': break if s[i] == '\0': break
inc(i) # skip ';' inc(i) # skip ';'
proc setCookie*(key, value: string, domain = "", path = "", proc setCookie*(key, value: string, domain = "", path = "",
expires = "", noName = false): string = expires = "", noName = false,
secure = false, httpOnly = false): string =
## Creates a command in the format of ## Creates a command in the format of
## ``Set-Cookie: key=value; Domain=...; ...`` ## ``Set-Cookie: key=value; Domain=...; ...``
result = "" result = ""
@ -38,22 +39,23 @@ proc setCookie*(key, value: string, domain = "", path = "",
if domain != "": result.add("; Domain=" & domain) if domain != "": result.add("; Domain=" & domain)
if path != "": result.add("; Path=" & path) if path != "": result.add("; Path=" & path)
if expires != "": result.add("; Expires=" & expires) if expires != "": result.add("; Expires=" & expires)
if secure: result.add("; secure")
if httpOnly: result.add("; HttpOnly")
proc setCookie*(key, value: string, expires: TimeInfo, proc setCookie*(key, value: string, expires: TimeInfo,
domain = "", path = "", noName = false): string = domain = "", path = "", noName = false,
secure = false, httpOnly = false): string =
## Creates a command in the format of ## Creates a command in the format of
## ``Set-Cookie: key=value; Domain=...; ...`` ## ``Set-Cookie: key=value; Domain=...; ...``
## ##
## **Note:** UTC is assumed as the timezone for ``expires``. ## **Note:** UTC is assumed as the timezone for ``expires``.
return setCookie(key, value, domain, path, return setCookie(key, value, domain, path,
format(expires, "ddd',' dd MMM yyyy HH:mm:ss 'UTC'"), noName) format(expires, "ddd',' dd MMM yyyy HH:mm:ss 'UTC'"),
noname, secure, httpOnly)
when isMainModule: when isMainModule:
var tim = Time(int(getTime()) + 76 * (60 * 60 * 24)) var tim = Time(int(getTime()) + 76 * (60 * 60 * 24))
echo(setCookie("test", "value", tim.getGMTime())) echo(setCookie("test", "value", tim.getGMTime()))
echo parseCookies("uid=1; kp=2") echo parseCookies("uid=1; kp=2")

View file

@ -803,6 +803,36 @@ proc rfind*(s, sub: string, start: int = -1): int {.noSideEffect.} =
if result != -1: return if result != -1: return
return -1 return -1
proc count*(s: string, sub: string, overlapping: bool = false): int {.noSideEffect,
rtl, extern: "nsuCountString".} =
## Count the occurences of a substring `sub` in the string `s`.
## Overlapping occurences of `sub` only count when `overlapping`
## is set to true.
var i = 0
while true:
i = s.find(sub, i)
if i < 0:
break
if overlapping:
inc i
else:
i += sub.len
inc result
proc count*(s: string, sub: char): int {.noSideEffect,
rtl, extern: "nsuCountChar".} =
## Count the occurences of the character `sub` in the string `s`.
for c in s:
if c == sub:
inc result
proc count*(s: string, subs: set[char]): int {.noSideEffect,
rtl, extern: "nsuCountCharSet".} =
## Count the occurences of the group of character `subs` in the string `s`.
for c in s:
if c in subs:
inc result
proc quoteIfContainsWhite*(s: string): string {.deprecated.} = proc quoteIfContainsWhite*(s: string): string {.deprecated.} =
## Returns ``'"' & s & '"'`` if `s` contains a space and does not ## Returns ``'"' & s & '"'`` if `s` contains a space and does not
## start with a quote, else returns `s`. ## start with a quote, else returns `s`.
@ -1356,3 +1386,8 @@ when isMainModule:
doAssert parseEnum[MyEnum]("enu_D") == enuD doAssert parseEnum[MyEnum]("enu_D") == enuD
doAssert parseEnum("invalid enum value", enC) == enC doAssert parseEnum("invalid enum value", enC) == enC
doAssert count("foofoofoo", "foofoo") == 1
doAssert count("foofoofoo", "foofoo", overlapping = true) == 2
doAssert count("foofoofoo", 'f') == 3
doAssert count("foofoofoobar", {'f','b'}) == 4

View file

@ -514,7 +514,7 @@ elif defined(JS):
result.setFullYear(timeInfo.year) result.setFullYear(timeInfo.year)
result.setDate(timeInfo.monthday) result.setDate(timeInfo.monthday)
proc `$`(timeInfo: TimeInfo): string = return $(TimeInfoToTIme(timeInfo)) proc `$`(timeInfo: TimeInfo): string = return $(timeInfoToTime(timeInfo))
proc `$`(time: Time): string = return $time.toLocaleString() proc `$`(time: Time): string = return $time.toLocaleString()
proc `-` (a, b: Time): int64 = proc `-` (a, b: Time): int64 =

View file

@ -154,6 +154,8 @@ proc addEscaped*(result: var string, s: string) =
of '>': result.add("&gt;") of '>': result.add("&gt;")
of '&': result.add("&amp;") of '&': result.add("&amp;")
of '"': result.add("&quot;") of '"': result.add("&quot;")
of '\'': result.add("&#x27;")
of '/': result.add("&#x2F;")
else: result.add(c) else: result.add(c)
proc escape*(s: string): string = proc escape*(s: string): string =
@ -167,6 +169,8 @@ proc escape*(s: string): string =
## ``>`` ``&gt;`` ## ``>`` ``&gt;``
## ``&`` ``&amp;`` ## ``&`` ``&amp;``
## ``"`` ``&quot;`` ## ``"`` ``&quot;``
## ``'`` ``&#x27;``
## ``/`` ``&#x2F;``
## ------------ ------------------- ## ------------ -------------------
result = newStringOfCap(s.len) result = newStringOfCap(s.len)
addEscaped(result, s) addEscaped(result, s)

View file

@ -215,13 +215,13 @@ proc open(f: var File, filename: string,
mode: FileMode = fmRead, mode: FileMode = fmRead,
bufSize: int = -1): bool = bufSize: int = -1): bool =
var p: pointer = fopen(filename, FormatOpen[mode]) var p: pointer = fopen(filename, FormatOpen[mode])
result = (p != nil) if p != nil:
f = cast[File](p) result = true
if bufSize > 0 and bufSize <= high(cint).int: f = cast[File](p)
if setvbuf(f, nil, IOFBF, bufSize.cint) != 0'i32: if bufSize > 0 and bufSize <= high(cint).int:
sysFatal(OutOfMemError, "out of memory") discard setvbuf(f, nil, IOFBF, bufSize.cint)
elif bufSize == 0: elif bufSize == 0:
discard setvbuf(f, nil, IONBF, 0) discard setvbuf(f, nil, IONBF, 0)
proc reopen(f: File, filename: string, mode: FileMode = fmRead): bool = proc reopen(f: File, filename: string, mode: FileMode = fmRead): bool =
var p: pointer = freopen(filename, FormatOpen[mode], f) var p: pointer = freopen(filename, FormatOpen[mode], f)

View file

@ -354,7 +354,6 @@ when hostOS == "windows":
addr(t), 0'i32, dummyThreadId) addr(t), 0'i32, dummyThreadId)
if t.sys <= 0: if t.sys <= 0:
raise newException(ResourceExhaustedError, "cannot create thread") raise newException(ResourceExhaustedError, "cannot create thread")
else: else:
proc createThread*[TArg](t: var TThread[TArg], proc createThread*[TArg](t: var TThread[TArg],
tp: proc (arg: TArg) {.thread.}, tp: proc (arg: TArg) {.thread.},

View file

@ -21,6 +21,7 @@ type
nimrodArgs: string nimrodArgs: string
gitCommit: string gitCommit: string
quotations: TTable[string, tuple[quote, author: string]] quotations: TTable[string, tuple[quote, author: string]]
numProcessors: int # Set by parallelBuild:n, only works for values > 0.
TRssItem = object TRssItem = object
year, month, day, title: string year, month, day, title: string
@ -42,6 +43,7 @@ proc initConfigData(c: var TConfigData) =
c.ticker = "" c.ticker = ""
c.vars = newStringTable(modeStyleInsensitive) c.vars = newStringTable(modeStyleInsensitive)
c.gitCommit = "master" c.gitCommit = "master"
c.numProcessors = countProcessors()
# Attempts to obtain the git current commit. # Attempts to obtain the git current commit.
let (output, code) = execCmdEx("git log -n 1 --format=%H") let (output, code) = execCmdEx("git log -n 1 --format=%H")
if code == 0 and output.strip.len == 40: if code == 0 and output.strip.len == 40:
@ -121,6 +123,12 @@ proc parseCmdLine(c: var TConfigData) =
stdout.write(version & "\n") stdout.write(version & "\n")
quit(0) quit(0)
of "o", "output": c.outdir = val of "o", "output": c.outdir = val
of "parallelbuild":
try:
let num = parseInt(val)
if num != 0: c.numProcessors = num
except EInvalidValue:
quit("invalid numeric value for --parallelBuild")
of "var": of "var":
var idx = val.find('=') var idx = val.find('=')
if idx < 0: quit("invalid command line") if idx < 0: quit("invalid command line")
@ -187,6 +195,12 @@ proc parseIniFile(c: var TConfigData) =
of "srcdoc": addFiles(c.srcdoc, "lib", ".nim", split(v, {';'})) of "srcdoc": addFiles(c.srcdoc, "lib", ".nim", split(v, {';'}))
of "srcdoc2": addFiles(c.srcdoc2, "lib", ".nim", split(v, {';'})) of "srcdoc2": addFiles(c.srcdoc2, "lib", ".nim", split(v, {';'}))
of "webdoc": addFiles(c.webdoc, "lib", ".nim", split(v, {';'})) of "webdoc": addFiles(c.webdoc, "lib", ".nim", split(v, {';'}))
of "parallelbuild":
try:
let num = parseInt(v)
if num != 0: c.numProcessors = num
except EInvalidValue:
quit("invalid numeric value for --parallelBuild in config")
else: quit(errorStr(p, "unknown variable: " & k.key)) else: quit(errorStr(p, "unknown variable: " & k.key))
of "quotations": of "quotations":
let vSplit = v.split('-') let vSplit = v.split('-')
@ -215,6 +229,20 @@ proc exec(cmd: string) =
echo(cmd) echo(cmd)
if os.execShellCmd(cmd) != 0: quit("external program failed") if os.execShellCmd(cmd) != 0: quit("external program failed")
proc sexec(cmds: openarray[string]) =
## Serial queue wrapper around exec.
for cmd in cmds: exec(cmd)
proc mexec(cmds: openarray[string], processors: int) =
## Multiprocessor version of exec
if processors < 2:
sexec(cmds)
return
if 0 != execProcesses(cmds, {poStdErrToStdOut, poParentStreams, poEchoCmd}):
echo "external program failed, retrying serial work queue for logs!"
sexec(cmds)
proc buildDocSamples(c: var TConfigData, destPath: string) = proc buildDocSamples(c: var TConfigData, destPath: string) =
## Special case documentation sample proc. ## Special case documentation sample proc.
## ##
@ -229,18 +257,26 @@ proc buildDocSamples(c: var TConfigData, destPath: string) =
proc buildDoc(c: var TConfigData, destPath: string) = proc buildDoc(c: var TConfigData, destPath: string) =
# call nim for the documentation: # call nim for the documentation:
var
commands = newSeq[string](len(c.doc) + len(c.srcdoc) + len(c.srcdoc2))
i = 0
for d in items(c.doc): for d in items(c.doc):
exec("nim rst2html $# --docSeeSrcUrl:$# -o:$# --index:on $#" % commands[i] = "nim rst2html $# --docSeeSrcUrl:$# -o:$# --index:on $#" %
[c.nimrodArgs, c.gitCommit, [c.nimrodArgs, c.gitCommit,
destPath / changeFileExt(splitFile(d).name, "html"), d]) destPath / changeFileExt(splitFile(d).name, "html"), d]
i.inc
for d in items(c.srcdoc): for d in items(c.srcdoc):
exec("nim doc $# --docSeeSrcUrl:$# -o:$# --index:on $#" % commands[i] = "nim doc $# --docSeeSrcUrl:$# -o:$# --index:on $#" %
[c.nimrodArgs, c.gitCommit, [c.nimrodArgs, c.gitCommit,
destPath / changeFileExt(splitFile(d).name, "html"), d]) destPath / changeFileExt(splitFile(d).name, "html"), d]
i.inc
for d in items(c.srcdoc2): for d in items(c.srcdoc2):
exec("nim doc2 $# --docSeeSrcUrl:$# -o:$# --index:on $#" % commands[i] = "nim doc2 $# --docSeeSrcUrl:$# -o:$# --index:on $#" %
[c.nimrodArgs, c.gitCommit, [c.nimrodArgs, c.gitCommit,
destPath / changeFileExt(splitFile(d).name, "html"), d]) destPath / changeFileExt(splitFile(d).name, "html"), d]
i.inc
mexec(commands, c.numProcessors)
exec("nim buildIndex -o:$1/theindex.html $1" % [destPath]) exec("nim buildIndex -o:$1/theindex.html $1" % [destPath])
proc buildPdfDoc(c: var TConfigData, destPath: string) = proc buildPdfDoc(c: var TConfigData, destPath: string) =
@ -264,10 +300,17 @@ proc buildPdfDoc(c: var TConfigData, destPath: string) =
proc buildAddDoc(c: var TConfigData, destPath: string) = proc buildAddDoc(c: var TConfigData, destPath: string) =
# build additional documentation (without the index): # build additional documentation (without the index):
<<<<<<< HEAD
var commands = newSeq[string](c.webdoc.len)
for i, doc in pairs(c.webdoc):
commands[i] = "nimrod doc $# --docSeeSrcUrl:$# -o:$# $#" %
=======
for d in items(c.webdoc): for d in items(c.webdoc):
exec("nim doc $# --docSeeSrcUrl:$# -o:$# $#" % exec("nim doc $# --docSeeSrcUrl:$# -o:$# $#" %
>>>>>>> 0047172274a73c681f619f5cd60aaad7109f694d
[c.nimrodArgs, c.gitCommit, [c.nimrodArgs, c.gitCommit,
destPath / changeFileExt(splitFile(d).name, "html"), d]) destPath / changeFileExt(splitFile(doc).name, "html"), doc]
mexec(commands, c.numProcessors)
proc parseNewsTitles(inputFilename: string): seq[TRssItem] = proc parseNewsTitles(inputFilename: string): seq[TRssItem] =
# parses the file for titles and returns them as TRssItem blocks. # parses the file for titles and returns them as TRssItem blocks.