support for multiple modules of the same name; niminst supports 'platforms'; minor bugfixes

This commit is contained in:
Araq 2013-09-24 16:07:07 +02:00
commit 8b5aa221ad
14 changed files with 132 additions and 48 deletions

View file

@ -1210,7 +1210,7 @@ proc writeHeader(m: BModule) =
writeRope(result, m.filename) writeRope(result, m.filename)
proc getCFile(m: BModule): string = proc getCFile(m: BModule): string =
result = changeFileExt(completeCFilePath(m.cfilename), cExt) result = changeFileExt(completeCFilePath(m.cfilename.withPackageName), cExt)
proc myOpenCached(module: PSym, rd: PRodReader): PPassContext = proc myOpenCached(module: PSym, rd: PRodReader): PPassContext =
assert optSymbolFiles in gGlobalOptions assert optSymbolFiles in gGlobalOptions

View file

@ -162,10 +162,11 @@ var
gNestedEvals: int # count the recursive calls to ``evalAux`` to prevent gNestedEvals: int # count the recursive calls to ``evalAux`` to prevent
# endless recursion # endless recursion
proc evalWhile(c: PEvalContext, n: PNode): PNode = proc evalWhile(c: PEvalContext, n: PNode): PNode =
while true: while true:
evalX(n.sons[0], {}) evalX(n.sons[0], {})
if getOrdValue(result) == 0: break if getOrdValue(result) == 0:
result = emptyNode; break
result = evalAux(c, n.sons[1], {}) result = evalAux(c, n.sons[1], {})
case result.kind case result.kind
of nkBreakStmt: of nkBreakStmt:
@ -304,7 +305,7 @@ proc allocSlot(c: PStackFrame; sym: PSym): int =
setLen(c.slots, max(result+1, c.slots.len)) setLen(c.slots, max(result+1, c.slots.len))
proc setSlot(c: PStackFrame, sym: PSym, val: PNode) = proc setSlot(c: PStackFrame, sym: PSym, val: PNode) =
assert sym.owner == c.prc assert sym.owner == c.prc or sfFromGeneric in sym.flags
let idx = allocSlot(c, sym) let idx = allocSlot(c, sym)
c.slots[idx] = val c.slots[idx] = val
@ -377,7 +378,7 @@ proc evalVariable(c: PStackFrame, sym: PSym, flags: TEvalFlags): PNode =
#result = emptyNode #result = emptyNode
proc evalGlobalVar(c: PEvalContext, s: PSym, flags: TEvalFlags): PNode = proc evalGlobalVar(c: PEvalContext, s: PSym, flags: TEvalFlags): PNode =
if sfCompileTime in s.flags or c.mode == emRepl: if sfCompileTime in s.flags or c.mode == emRepl or s.kind == skForVar:
result = IdNodeTableGet(c.globals, s) result = IdNodeTableGet(c.globals, s)
if result != nil: if result != nil:
if not aliasNeeded(result, flags): if not aliasNeeded(result, flags):
@ -549,7 +550,9 @@ proc evalSym(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
of skProc, skConverter, skMacro, skType: of skProc, skConverter, skMacro, skType:
result = n result = n
#result = s.getBody #result = s.getBody
of skVar, skLet, skForVar, skTemp, skResult: of skForVar:
result = evalGlobalVar(c, s, flags)
of skVar, skLet, skTemp, skResult:
if sfGlobal notin s.flags: if sfGlobal notin s.flags:
result = evalVariable(c.tos, s, flags) result = evalVariable(c.tos, s, flags)
else: else:
@ -1396,7 +1399,7 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
of nkChckRangeF, nkChckRange64, nkChckRange: result = evalRangeChck(c, n) of nkChckRangeF, nkChckRange64, nkChckRange: result = evalRangeChck(c, n)
of nkStringToCString: result = evalConvStrToCStr(c, n) of nkStringToCString: result = evalConvStrToCStr(c, n)
of nkCStringToString: result = evalConvCStrToStr(c, n) of nkCStringToString: result = evalConvCStrToStr(c, n)
of nkStmtListExpr, nkStmtList, nkModule: of nkStmtListExpr, nkStmtList:
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
result = evalAux(c, n.sons[i], flags) result = evalAux(c, n.sons[i], flags)
case result.kind case result.kind
@ -1455,7 +1458,7 @@ proc evalConstExprAux*(p: PEvalContext, module, prc: PSym, e: PNode): PNode =
proc setupMacroParam(x: PNode): PNode = proc setupMacroParam(x: PNode): PNode =
result = x result = x
if result.kind == nkHiddenStdConv: result = result.sons[1] if result.kind in {nkHiddenSubConv, nkHiddenStdConv}: result = result.sons[1]
proc evalMacroCall(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode = proc evalMacroCall(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode =
# XXX GlobalError() is ugly here, but I don't know a better solution for now # XXX GlobalError() is ugly here, but I don't know a better solution for now

View file

@ -298,13 +298,13 @@ const
gpp()] gpp()]
const const
hExt* = "h" hExt* = ".h"
var var
cCompiler* = ccGcc # the used compiler cCompiler* = ccGcc # the used compiler
cExt* = "c" # extension of generated C/C++ files cExt* = ".c" # extension of generated C/C++ files
# (can be changed to .cpp later) # (can be changed to .cpp later)
cIncludes*: seq[string] = @[] # directories to search for included files cIncludes*: seq[string] = @[] # directories to search for included files
cLibs*: seq[string] = @[] # directories to search for lib files cLibs*: seq[string] = @[] # directories to search for lib files
@ -518,7 +518,7 @@ proc footprint(filename: string): TCrc32 =
getCompileCFileCmd(filename, true) getCompileCFileCmd(filename, true)
proc externalFileChanged(filename: string): bool = proc externalFileChanged(filename: string): bool =
var crcFile = toGeneratedFile(filename, "crc") var crcFile = toGeneratedFile(filename.withPackageName, "crc")
var currentCrc = int(footprint(filename)) var currentCrc = int(footprint(filename))
var f: TFile var f: TFile
if open(f, crcFile, fmRead): if open(f, crcFile, fmRead):

View file

@ -1,8 +1,16 @@
[Project] [Project]
Name: "Nimrod" Name: "Nimrod"
Version: "$version" Version: "$version"
OS: "windows;linux;macosx;solaris;freebsd;netbsd;openbsd" Platforms: """
CPU: "i386;amd64;powerpc64;arm" # ;sparc windows: i386;amd64
linux: i386;amd64;powerpc64;arm;sparc;mips
macosx: i386;amd64;powerpc64
solaris: i386;amd64;sparc
freebsd: i386;amd64
netbsd: i386;amd64
openbsd: i386;amd64
haiku: i386;amd64
"""
Authors: "Andreas Rumpf" Authors: "Andreas Rumpf"
Description: """This is the Nimrod Compiler. Nimrod is a new statically typed, Description: """This is the Nimrod Compiler. Nimrod is a new statically typed,

View file

@ -208,7 +208,19 @@ proc removeTrailingDirSep*(path: string): string =
proc getGeneratedPath: string = proc getGeneratedPath: string =
result = if nimcacheDir.len > 0: nimcacheDir else: gProjectPath.shortenDir / result = if nimcacheDir.len > 0: nimcacheDir else: gProjectPath.shortenDir /
genSubDir genSubDir
proc withPackageName*(path: string): string =
var x = path
while true:
x = parentDir(x)
if x.len == 0: break
case x.normalize
of "lib", "src", "source", "package", "pckg", "library": discard
else:
let (path, file, ext) = path.splitFile
return (path / (x & '_' & file)) & ext
result = path
proc toGeneratedFile*(path, ext: string): string = proc toGeneratedFile*(path, ext: string): string =
## converts "/home/a/mymodule.nim", "rod" to "/home/a/nimcache/mymodule.rod" ## converts "/home/a/mymodule.nim", "rod" to "/home/a/nimcache/mymodule.rod"
var (head, tail) = splitPath(path) var (head, tail) = splitPath(path)

View file

@ -1440,7 +1440,7 @@ proc parseSection(p: var TParser, kind: TNodeKind,
skipComment(p, result) skipComment(p, result)
while sameInd(p): while sameInd(p):
case p.tok.tokType case p.tok.tokType
of tkSymbol, tkAccent: of tkSymbol, tkAccent, tkParLe:
var a = defparser(p) var a = defparser(p)
skipComment(p, a) skipComment(p, a)
addSon(result, a) addSon(result, a)

View file

@ -818,7 +818,7 @@ proc checkDep(fileIdx: int32): TReasonForRecompile =
gMods[fileIdx].reason = rrNone # we need to set it here to avoid cycles gMods[fileIdx].reason = rrNone # we need to set it here to avoid cycles
result = rrNone result = rrNone
var r: PRodReader = nil var r: PRodReader = nil
var rodfile = toGeneratedFile(filename, RodExt) var rodfile = toGeneratedFile(filename.withPackageName, RodExt)
r = newRodReader(rodfile, crc, fileIdx) r = newRodReader(rodfile, crc, fileIdx)
if r == nil: if r == nil:
result = (if ExistsFile(rodfile): rrRodInvalid else: rrRodDoesNotExist) result = (if ExistsFile(rodfile): rrRodInvalid else: rrRodDoesNotExist)

View file

@ -421,7 +421,8 @@ proc addStmt(w: PRodWriter, n: PNode) =
proc writeRod(w: PRodWriter) = proc writeRod(w: PRodWriter) =
processStacks(w, true) processStacks(w, true)
var f: TFile var f: TFile
if not open(f, completeGeneratedFilePath(changeFileExt(w.filename, "rod")), if not open(f, completeGeneratedFilePath(changeFileExt(
w.filename.withPackageName, RodExt)),
fmWrite): fmWrite):
#echo "couldn't write rod file for: ", w.filename #echo "couldn't write rod file for: ", w.filename
return return

View file

@ -890,7 +890,7 @@ proc evalStaticExpr*(module: PSym, e: PNode, prc: PSym): PNode =
proc setupMacroParam(x: PNode): PNode = proc setupMacroParam(x: PNode): PNode =
result = x result = x
if result.kind == nkHiddenStdConv: result = result.sons[1] if result.kind in {nkHiddenSubConv, nkHiddenStdConv}: result = result.sons[1]
proc evalMacroCall(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode = proc evalMacroCall(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode =
# XXX GlobalError() is ugly here, but I don't know a better solution for now # XXX GlobalError() is ugly here, but I don't know a better solution for now

View file

@ -104,11 +104,12 @@ exprStmt = simpleExpr
| IND{=} 'except' exprList ':' stmt | IND{=} 'except' exprList ':' stmt
| IND{=} 'else' ':' stmt )* | IND{=} 'else' ':' stmt )*
))? ))?
importStmt = 'import' optInd expr moduleName = expr ('as' expr)?
((comma expr)* importStmt = 'import' optInd moduleName
((comma moduleName)*
/ 'except' optInd (expr ^+ comma)) / 'except' optInd (expr ^+ comma))
includeStmt = 'include' optInd expr ^+ comma includeStmt = 'include' optInd expr ^+ comma
fromStmt = 'from' expr 'import' optInd expr (comma expr)* fromStmt = 'from' moduleName 'import' optInd expr (comma expr)*
returnStmt = 'return' optInd expr? returnStmt = 'return' optInd expr?
raiseStmt = 'raise' optInd expr? raiseStmt = 'raise' optInd expr?
yieldStmt = 'yield' optInd expr? yieldStmt = 'yield' optInd expr?

View file

@ -2018,11 +2018,11 @@ Example:
The `when`:idx: statement is almost identical to the ``if`` statement with some The `when`:idx: statement is almost identical to the ``if`` statement with some
exceptions: exceptions:
* Each ``expr`` has to be a constant expression (of type ``bool``). * Each condition (``expr``) has to be a constant expression (of type ``bool``).
* The statements do not open a new scope. * The statements do not open a new scope.
* The statements that belong to the expression that evaluated to true are * The statements that belong to the expression that evaluated to true are
translated by the compiler, the other statements are not checked for translated by the compiler, the other statements are not checked for
semantics! However, each ``expr`` is checked for semantics. semantics! However, each condition is checked for semantics.
The ``when`` statement enables conditional compilation techniques. As The ``when`` statement enables conditional compilation techniques. As
a special syntactic extension, the ``when`` construct is also available a special syntactic extension, the ``when`` construct is also available
@ -2268,7 +2268,7 @@ A `table constructor`:idx: is syntactic sugar for an array constructor:
{"key1": "value1", "key2", "key3": "value2"} {"key1": "value1", "key2", "key3": "value2"}
# is the same as: # is the same as:
[("key1", "value1"), ("key2", "value2"), ("key3", "value")] [("key1", "value1"), ("key2", "value2"), ("key3", "value2")]
The empty table can be written ``{:}`` (in contrast to the empty set The empty table can be written ``{:}`` (in contrast to the empty set
@ -2565,9 +2565,6 @@ Overloading of the subscript operator
------------------------------------- -------------------------------------
The ``[]`` subscript operator for arrays/openarrays/sequences can be overloaded. The ``[]`` subscript operator for arrays/openarrays/sequences can be overloaded.
Overloading support is only possible if the first parameter has no type that
already supports the built-in ``[]`` notation. Currently the compiler
does not check this restriction.
Multi-methods Multi-methods
@ -3301,13 +3298,11 @@ Specifically, the type class will be matched if:
a) all of the expressions within the body can be compiled for the tested type a) all of the expressions within the body can be compiled for the tested type
b) all statically evaluatable boolean expressions in the body must be true b) all statically evaluatable boolean expressions in the body must be true
Please note that the `is` operator allows you to easily verify the precise type Please note that the ``is`` operator allows you to easily verify the precise type
signatures of the required operations, but since type inference and default signatures of the required operations, but since type inference and default
parameters are still applied in the provided block, it's also possible to encode parameters are still applied in the provided block, it's also possible to encode
usage protocols that doesn't reveal implementation details. usage protocols that doesn't reveal implementation details.
.. code-block:: nimrod
Much like generics, the user defined type classes will be instantiated exactly Much like generics, the user defined type classes will be instantiated exactly
once for each tested type and any static code included within them will also be once for each tested type and any static code included within them will also be
executed once. executed once.
@ -3327,7 +3322,7 @@ from the proc body. This is usually used with the ``auto`` type class:
The return type will be treated as additional generic param and can be The return type will be treated as additional generic param and can be
explicitly specified at call sites as any other generic param. explicitly specified at call sites as any other generic param.
Future versions of nimrod may also support overloading based on the return type Future versions of Nimrod 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.
@ -3398,8 +3393,9 @@ templates:
The "types" of templates can be the symbols ``expr`` (stands for *expression*), The "types" of templates can be the symbols ``expr`` (stands for *expression*),
``stmt`` (stands for *statement*) or ``typedesc`` (stands for *type ``stmt`` (stands for *statement*) or ``typedesc`` (stands for *type
description*). These are no real types, they just help the compiler parsing. description*). These are "meta types", they can only be used in certain
Real types can be used too; this implies that expressions are expected. contexts. Real types can be used too; this implies that expressions are
expected.
Ordinary vs immediate templates Ordinary vs immediate templates
@ -3868,7 +3864,7 @@ values inside containers and so on. For example, here is how one can create
a type-safe wrapper for the unsafe `printf` function from C: a type-safe wrapper for the unsafe `printf` function from C:
.. code-block:: nimrod .. code-block:: nimrod
macro safePrintF(formatString: string{lit}, args: vararg[expr]): expr = macro safePrintF(formatString: string{lit}, args: varargs[expr]): expr =
var i = 0 var i = 0
for c in formatChars(formatString): for c in formatChars(formatString):
var expectedType = case c var expectedType = case c
@ -4196,10 +4192,10 @@ implemented with term rewriting:
template optP2{p(x, y, false)}(x, y: expr): expr = x - y template optP2{p(x, y, false)}(x, y: expr): expr = x - y
Example: hoisting Example: Hoisting
----------------- -----------------
The following example how some form of hoisting can be implemented: The following example shows how some form of hoisting can be implemented:
.. code-block:: nimrod .. code-block:: nimrod
import pegs import pegs
@ -4267,7 +4263,7 @@ optimization for types that have copying semantics:
var t: TTable var t: TTable
# overloading resolution ensures that the optimized []= is called here: # overloading resolution ensures that the optimized []= is called here:
t["abc"] = "xyz" t[f()] = g()
@ -4326,6 +4322,36 @@ module name followed by an ``except`` to prevent some symbols to be imported:
echo "$1" % "abc" echo "$1" % "abc"
Module names in imports
~~~~~~~~~~~~~~~~~~~~~~~
A module alias can be introduced via the ``as`` keyword:
.. code-block:: nimrod
import strutils as su, sequtils as qu
echo su.format("$1", "lalelu")
The original module name is then not accessible. The
notations ``path/to/module`` or ``path.to.module`` or ``"path/to/module"``
can be used to refer to a module in subdirectories:
.. code-block:: nimrod
import lib.pure.strutils, lib/pure/os, "lib/pure/times"
Note that the module name is still ``strutils`` and not ``lib.pure.strutils``
and so one **cannot** do:
.. code-block:: nimrod
import lib.pure.strutils
echo lib.pure.strutils
Likewise the following does not make sense as the name is ``strutils`` already:
.. code-block:: nimrod
import lib.pure.strutils as strutils
From import statement From import statement
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
@ -5085,9 +5111,9 @@ string expressions in general:
proc getDllName: string = proc getDllName: string =
result = "mylib.dll" result = "mylib.dll"
if ExistsFile(result): return if existsFile(result): return
result = "mylib2.dll" result = "mylib2.dll"
if ExistsFile(result): return if existsFile(result): return
quit("could not load dynamic library") quit("could not load dynamic library")
proc myImport(s: cstring) {.cdecl, importc, dynlib: getDllName().} proc myImport(s: cstring) {.cdecl, importc, dynlib: getDllName().}

View file

@ -38,7 +38,7 @@ type
nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange, nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange,
nnkStringToCString, nnkCStringToString, nnkAsgn, nnkStringToCString, nnkCStringToString, nnkAsgn,
nnkFastAsgn, nnkGenericParams, nnkFormalParams, nnkOfInherit, nnkFastAsgn, nnkGenericParams, nnkFormalParams, nnkOfInherit,
nnkModule, nnkProcDef, nnkMethodDef, nnkConverterDef, nnkImportAs, nnkProcDef, nnkMethodDef, nnkConverterDef,
nnkMacroDef, nnkTemplateDef, nnkIteratorDef, nnkOfBranch, nnkMacroDef, nnkTemplateDef, nnkIteratorDef, nnkOfBranch,
nnkElifBranch, nnkExceptBranch, nnkElse, nnkElifBranch, nnkExceptBranch, nnkElse,
nnkAsmStmt, nnkPragma, nnkPragmaBlock, nnkIfStmt, nnkWhenStmt, nnkAsmStmt, nnkPragma, nnkPragmaBlock, nnkIfStmt, nnkWhenStmt,

View file

@ -1,6 +1,8 @@
version 0.9.4 version 0.9.4
============= =============
- change search path algorithm to care about packages
- XXX how can 'lib_system' ever be generated?
- new VM: - new VM:
- implement the glue to replace evals.nim - implement the glue to replace evals.nim
- implement missing magics - implement missing magics
@ -20,7 +22,6 @@ version 0.9.4
Bugs Bugs
==== ====
- 'quote' without 'do' doesn't work
- compilation of niminst takes way too long. looks like a regression - compilation of niminst takes way too long. looks like a regression
- simple closure iterator doesn't work - simple closure iterator doesn't work
- docgen: sometimes effects are listed twice - docgen: sometimes effects are listed twice
@ -46,6 +47,7 @@ version 0.9.x
* test libffi on windows * test libffi on windows
* test: times.format with the FFI * test: times.format with the FFI
- document NimMain and check whether it works for threading - document NimMain and check whether it works for threading
- 'quote' without 'do' doesn't work: parser/grammar issue; could be supported
version 0.9.X version 0.9.X
@ -125,7 +127,7 @@ GC
CGEN CGEN
==== ====
- codegen should use "NIM_CAST" macro and respect aliasing rules for GCC - codegen should use "NIM_CAST" macro and respect aliasing rules for GCC
- ``restrict`` pragma + backend support; computed goto support - ``restrict`` pragma + backend support
- 'const' objects including case objects - 'const' objects including case objects

View file

@ -1,7 +1,7 @@
# #
# #
# The Nimrod Installation Generator # The Nimrod Installation Generator
# (c) Copyright 2012 Andreas Rumpf # (c) Copyright 2013 Andreas Rumpf
# #
# See the file "copying.txt", included in this # See the file "copying.txt", included in this
# distribution, for details about the copyright. # distribution, for details about the copyright.
@ -52,10 +52,12 @@ type
cat: array[TFileCategory, seq[string]] cat: array[TFileCategory, seq[string]]
binPaths, authors, oses, cpus: seq[string] binPaths, authors, oses, cpus: seq[string]
cfiles: array[1..maxOS, array[1..maxCPU, seq[string]]] cfiles: array[1..maxOS, array[1..maxCPU, seq[string]]]
platforms: array[1..maxOS, array[1..maxCPU, bool]]
ccompiler, linker, innosetup: tuple[path, flags: string] ccompiler, linker, innosetup: tuple[path, flags: string]
name, displayName, version, description, license, infile, outdir: string name, displayName, version, description, license, infile, outdir: string
libpath: string libpath: string
innoSetupFlag, installScript, uninstallScript: bool innoSetupFlag, installScript, uninstallScript: bool
explicitPlatforms: bool
vars: PStringTable vars: PStringTable
app: TAppType app: TAppType
nimrodArgs: string nimrodArgs: string
@ -126,7 +128,7 @@ const
Version = "0.9" Version = "0.9"
Usage = "niminst - Nimrod Installation Generator Version " & version & """ Usage = "niminst - Nimrod Installation Generator Version " & version & """
(c) 2012 Andreas Rumpf (c) 2013 Andreas Rumpf
Usage: Usage:
niminst [options] command[;command2...] ini-file[.ini] [compile_options] niminst [options] command[;command2...] ini-file[.ini] [compile_options]
Command: Command:
@ -221,6 +223,23 @@ proc yesno(p: var TCfgParser, v: string): bool =
result = false result = false
else: quit(errorStr(p, "unknown value; use: yes|no")) else: quit(errorStr(p, "unknown value; use: yes|no"))
proc incl(s: var seq[string], x: string): int =
for i in 0.. <s.len:
if cmpIgnoreStyle(s[i], x) == 0: return i
s.add(x)
result = s.len-1
proc platforms(c: var TConfigData, v: string) =
for line in splitLines(v):
let p = line.find(": ")
if p <= 1: continue
let os = line.substr(0, p-1).strip
let cpus = line.substr(p+1).strip
c.oses.add(os)
for cpu in cpus.split(';'):
let cpuIdx = c.cpus.incl(cpu)
c.platforms[c.oses.len][cpuIdx+1] = true
proc parseIniFile(c: var TConfigData) = proc parseIniFile(c: var TConfigData) =
var var
p: TCfgParser p: TCfgParser
@ -244,8 +263,19 @@ proc parseIniFile(c: var TConfigData) =
of "name": c.name = v of "name": c.name = v
of "displayname": c.displayName = v of "displayname": c.displayName = v
of "version": c.version = v of "version": c.version = v
of "os": c.oses = split(v, {';'}) of "os":
of "cpu": c.cpus = split(v, {';'}) c.oses = split(v, {';'})
if c.explicitPlatforms:
quit(errorStr(p, "you cannot have both 'platforms' and 'os'"))
of "cpu":
c.cpus = split(v, {';'})
if c.explicitPlatforms:
quit(errorStr(p, "you cannot have both 'platforms' and 'cpu'"))
of "platforms":
platforms(c, v)
c.explicitPlatforms = true
if c.cpus.len > 0 or c.oses.len > 0:
quit(errorStr(p, "you cannot have both 'platforms' and 'os'"))
of "authors": c.authors = split(v, {';'}) of "authors": c.authors = split(v, {';'})
of "description": c.description = v of "description": c.description = v
of "app": of "app":
@ -409,6 +439,7 @@ proc srcdist(c: var TConfigData) =
let osname = c.oses[osA-1] let osname = c.oses[osA-1]
if osname.cmpIgnoreStyle("windows") == 0: winIndex = osA-1 if osname.cmpIgnoreStyle("windows") == 0: winIndex = osA-1
for cpuA in 1..c.cpus.len: for cpuA in 1..c.cpus.len:
if c.explicitPlatforms and not c.platforms[osA][cpuA]: continue
let cpuname = c.cpus[cpuA-1] let cpuname = c.cpus[cpuA-1]
if cpuname.cmpIgnoreStyle("i386") == 0: intel32Index = cpuA-1 if cpuname.cmpIgnoreStyle("i386") == 0: intel32Index = cpuA-1
elif cpuname.cmpIgnoreStyle("amd64") == 0: intel64Index = cpuA-1 elif cpuname.cmpIgnoreStyle("amd64") == 0: intel64Index = cpuA-1