Merge branch 'bigbreak' of github.com:Araq/Nimrod into bigbreak
This commit is contained in:
commit
59e5f3533b
21 changed files with 145 additions and 68 deletions
|
|
@ -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 =
|
||||||
|
|
|
||||||
|
|
@ -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 =
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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!
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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]
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
|
||||||
|
|
@ -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)
|
|
||||||
|
|
||||||
|
|
@ -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")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 =
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,8 @@ proc addEscaped*(result: var string, s: string) =
|
||||||
of '>': result.add(">")
|
of '>': result.add(">")
|
||||||
of '&': result.add("&")
|
of '&': result.add("&")
|
||||||
of '"': result.add(""")
|
of '"': result.add(""")
|
||||||
|
of '\'': result.add("'")
|
||||||
|
of '/': result.add("/")
|
||||||
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 =
|
||||||
## ``>`` ``>``
|
## ``>`` ``>``
|
||||||
## ``&`` ``&``
|
## ``&`` ``&``
|
||||||
## ``"`` ``"``
|
## ``"`` ``"``
|
||||||
|
## ``'`` ``'``
|
||||||
|
## ``/`` ``/``
|
||||||
## ------------ -------------------
|
## ------------ -------------------
|
||||||
result = newStringOfCap(s.len)
|
result = newStringOfCap(s.len)
|
||||||
addEscaped(result, s)
|
addEscaped(result, s)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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.},
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue