diff options
-rwxr-xr-x | build.bat | 2 | ||||
-rwxr-xr-x | compiler/ccgtypes.nim | 7 | ||||
-rwxr-xr-x | compiler/extccomp.nim | 33 | ||||
-rwxr-xr-x | koch.nim | 8 | ||||
-rwxr-xr-x | lib/pure/strutils.nim | 46 | ||||
-rwxr-xr-x | todo.txt | 1 | ||||
-rwxr-xr-x | tools/niminst/buildbat.tmpl (renamed from tools/buildbat.tmpl) | 4 | ||||
-rwxr-xr-x | tools/niminst/buildsh.tmpl (renamed from tools/buildsh.tmpl) | 4 | ||||
-rwxr-xr-x | tools/niminst/deinstall.tmpl (renamed from tools/deinstall.tmpl) | 0 | ||||
-rwxr-xr-x | tools/niminst/inno.tmpl (renamed from tools/inno.tmpl) | 0 | ||||
-rwxr-xr-x | tools/niminst/install.tmpl (renamed from tools/install.tmpl) | 0 | ||||
-rwxr-xr-x | tools/niminst/niminst.nim (renamed from tools/niminst.nim) | 40 | ||||
-rwxr-xr-x | web/news.txt | 3 |
13 files changed, 102 insertions, 46 deletions
diff --git a/build.bat b/build.bat index 7a46fe5fc..89cb78135 100755 --- a/build.bat +++ b/build.bat @@ -2,7 +2,7 @@ REM Generated by niminst SET CC=gcc SET LINKER=gcc -SET COMP_FLAGS=-w -O3 -fno-strict-aliasing +SET COMP_FLAGS= -w -O3 -fno-strict-aliasing SET LINK_FLAGS= REM call the compiler: diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 6bbb33b4f..b4cd77c2b 100755 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -46,13 +46,6 @@ proc mangleName(s: PSym): PRope = app(result, toRope(mangle(s.name.s))) app(result, "_") app(result, toRope(s.id)) - when false: - # deactivated to make mapping file smaller which is currently only used - # for the list of generated C files - if optGenMapping in gGlobalOptions: - if s.owner != nil: - appf(gMapping, "r\"$1.$2\": $3$n", - [toRope(s.owner.Name.s), toRope(s.name.s), result]) s.loc.r = result proc getTypeName(typ: PType): PRope = diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index c355d2624..eaaf4a578 100755 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -294,9 +294,9 @@ const pcc(), ucc(), icc(), - gpp() ] + gpp()] -const +const hExt* = "h" var @@ -336,7 +336,7 @@ proc setCC*(ccname: string) = defineSymbol(CC[ccompiler].name) proc addOpt(dest: var string, src: string) = - if len(dest) == 0 or dest[len(dest) - 1 + 0] != ' ': add(dest, " ") + if len(dest) == 0 or dest[len(dest)-1] != ' ': add(dest, " ") add(dest, src) proc addLinkOption*(option: string) = @@ -456,6 +456,16 @@ proc CFileSpecificOptions(cfilename: string): string = var key = trunk & ".always" if existsConfigVar(key): addOpt(result, getConfigVar(key)) +proc getCompileOptions: string = + result = CFileSpecificOptions("__dummy__") + +proc getLinkOptions: string = + result = linkOptions + for linkedLib in items(cLinkedLibs): + result.add(cc[ccompiler].linkLibCmd % linkedLib.quoteIfContainsWhite) + for libDir in items(cLibs): + result.add cc[ccompiler].linkDirCmd, libDir.quoteIfContainsWhite + proc getCompileCFileCmd*(cfilename: string, isExternal = false): string = var c = ccompiler var options = CFileSpecificOptions(cfilename) @@ -566,11 +576,7 @@ proc CallCCompiler*(projectfile: string) = if not noAbsolutePaths(): exefile = joinPath(splitFile(projectFile).dir, exefile) exefile = quoteIfContainsWhite(exefile) - for linkedLib in items(cLinkedLibs): - linkOptions.add(cc[c].linkLibCmd % linkedLib.quoteIfContainsWhite) - for libDir in items(cLibs): - linkOptions.add cc[c].linkDirCmd, libDir.quoteIfContainsWhite - + let linkOptions = getLinkOptions() linkCmd = quoteIfContainsWhite(linkCmd % ["builddll", builddll, "buildgui", buildgui, "options", linkOptions, "objfiles", objfiles, "exefile", exefile, "nimrod", getPrefixDir(), "lib", libpath]) @@ -599,6 +605,15 @@ proc writeMapping*(gSymbolMapping: PRope) = var code = toRope("[C_Files]\n") app(code, genMappingFiles(toCompile)) app(code, genMappingFiles(externalToCompile)) - appf(code, "[Symbols]$n$1", [gSymbolMapping]) + app(code, "\n[C_Compiler]\nFlags=") + app(code, strutils.escape(getCompileOptions())) + + app(code, "\n[Linker]\nFlags=") + app(code, strutils.escape(getLinkOptions())) + + app(code, "\n[Environment]\nlibpath=") + app(code, strutils.escape(libpath)) + + appf(code, "\n[Symbols]$n$1", [gSymbolMapping]) WriteRope(code, joinPath(gProjectPath, "mapping.txt")) diff --git a/koch.nim b/koch.nim index aed49c8d9..907db46c9 100755 --- a/koch.nim +++ b/koch.nim @@ -62,11 +62,11 @@ proc tryExec(cmd: string): bool = result = execShellCmd(cmd) == 0 proc csource(args: string) = - exec("nimrod cc $1 -r tools/niminst --var:version=$2 csource compiler/nimrod.ini $1" % + exec("nimrod cc $1 -r tools/niminst/niminst --var:version=$2 csource compiler/nimrod.ini $1" % [args, NimrodVersion]) proc zip(args: string) = - exec("nimrod cc -r tools/niminst --var:version=$# zip compiler/nimrod.ini" % + exec("nimrod cc -r tools/niminst/niminst --var:version=$# zip compiler/nimrod.ini" % NimrodVersion) proc buildTool(toolname, args: string) = @@ -75,9 +75,9 @@ proc buildTool(toolname, args: string) = proc inno(args: string) = # make sure we have generated the c2nim and niminst executables: - buildTool("tools/niminst", args) + buildTool("tools/niminst/niminst", args) buildTool("compiler/c2nim/c2nim", args) - exec("tools" / "niminst --var:version=$# inno compiler/nimrod" % + exec("tools" / "niminst" / "niminst --var:version=$# inno compiler/nimrod" % NimrodVersion) proc install(args: string) = diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 8d6caeea5..f4a82a0a3 100755 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -676,6 +676,31 @@ proc replace*(s: string, sub, by: char): string {.noSideEffect, else: result[i] = s[i] inc(i) +proc replaceWord*(s, sub: string, by = ""): string {.noSideEffect, + rtl, extern: "nsuReplaceStr".} = + ## Replaces `sub` in `s` by the string `by`. Each occurance of `sub` + ## has to be surrounded by word boundaries (comparable to ``\\w`` in + ## regular expressions), otherwise it is not replaced. + const wordChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'} + var a {.noinit.}: TSkipTable + result = "" + preprocessSub(sub, a) + var i = 0 + while true: + var j = findAux(s, sub, i, a) + if j < 0: break + # word boundary? + if (j == 0 or s[j-1] notin wordChars) and + (j+sub.len >= s.len or s[j+sub.len] notin wordChars): + add result, substr(s, i, j - 1) + add result, by + i = j + len(sub) + else: + add result, substr(s, i, j) + i = j + 1 + # copy the rest: + add result, substr(s, i) + proc delete*(s: var string, first, last: int) {.noSideEffect, rtl, extern: "nsuDelete".} = ## Deletes in `s` the characters at position `first` .. `last`. This modifies @@ -960,6 +985,9 @@ proc findNormalized(x: string, inArray: openarray[string]): int = # security hole... return -1 +proc invalidFormatString() {.noinline.} = + raise newException(EInvalidValue, "invalid format string") + proc addf*(s: var string, formatstr: string, a: openarray[string]) {. noSideEffect, rtl, extern: "nsuAddf".} = ## The same as ``add(s, formatstr % a)``, but more efficient. @@ -971,6 +999,7 @@ proc addf*(s: var string, formatstr: string, a: openarray[string]) {. case formatstr[i+1] # again we use the fact that strings # are zero-terminated here of '#': + if num >% a.high: invalidFormatString() add s, a[num] inc i, 2 inc num @@ -985,26 +1014,25 @@ proc addf*(s: var string, formatstr: string, a: openarray[string]) {. while formatstr[i] in Digits: j = j * 10 + ord(formatstr[i]) - ord('0') inc(i) - if not negative: - add s, a[j - 1] - else: - add s, a[a.len - j] + let idx = if not negative: j-1 else: a.len-j + if idx >% a.high: invalidFormatString() + add s, a[idx] of '{': var j = i+1 while formatstr[j] notin {'\0', '}'}: inc(j) var x = findNormalized(substr(formatstr, i+2, j-1), a) if x >= 0 and x < high(a): add s, a[x+1] - else: raise newException(EInvalidValue, "invalid format string") + else: invalidFormatString() i = j+1 of 'a'..'z', 'A'..'Z', '\128'..'\255', '_': var j = i+1 while formatstr[j] in PatternChars: inc(j) var x = findNormalized(substr(formatstr, i+1, j-1), a) if x >= 0 and x < high(a): add s, a[x+1] - else: raise newException(EInvalidValue, "invalid format string") + else: invalidFormatString() i = j else: - raise newException(EInvalidValue, "invalid format string") + invalidFormatString() else: add s, formatstr[i] inc(i) @@ -1076,3 +1104,7 @@ when isMainModule: doAssert "$animal eats $food." % ["animal", "The cat", "food", "fish"] == "The cat eats fish." + doAssert "-ld a-ldz -ld".replaceWord("-ld") == " a-ldz " + doAssert "-lda-ldz -ld abc".replaceWord("-ld") == "-lda-ldz abc" + + diff --git a/todo.txt b/todo.txt index ec0c283db..bb6070b26 100755 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,7 @@ version 0.8.14 ============== +- improve niminst - fix line info in assertions version 0.9.0 diff --git a/tools/buildbat.tmpl b/tools/niminst/buildbat.tmpl index a20559a90..49a004213 100755 --- a/tools/buildbat.tmpl +++ b/tools/niminst/buildbat.tmpl @@ -3,8 +3,8 @@ # result = "@echo off\nREM Generated by niminst\n" SET CC=gcc SET LINKER=gcc -SET COMP_FLAGS=-w -O3 -fno-strict-aliasing -SET LINK_FLAGS= +SET COMP_FLAGS=?{c.ccompiler.flags} +SET LINK_FLAGS=?{c.linker.flags} REM call the compiler: diff --git a/tools/buildsh.tmpl b/tools/niminst/buildsh.tmpl index 8893f4da0..f931ed911 100755 --- a/tools/buildsh.tmpl +++ b/tools/niminst/buildsh.tmpl @@ -5,8 +5,8 @@ # "# To regenerate run ``niminst csource`` or ``koch csource``\n" CC="gcc" LINKER="gcc" -COMP_FLAGS="-w -O3 -fno-strict-aliasing" -LINK_FLAGS="" +COMP_FLAGS="?{c.ccompiler.flags}" +LINK_FLAGS="?{c.linker.flags}" # add(result, "# platform detection\n") ucpu=`uname -m` uos=`uname` diff --git a/tools/deinstall.tmpl b/tools/niminst/deinstall.tmpl index 61141f78e..61141f78e 100755 --- a/tools/deinstall.tmpl +++ b/tools/niminst/deinstall.tmpl diff --git a/tools/inno.tmpl b/tools/niminst/inno.tmpl index df1460e42..df1460e42 100755 --- a/tools/inno.tmpl +++ b/tools/niminst/inno.tmpl diff --git a/tools/install.tmpl b/tools/niminst/install.tmpl index 9dea6887b..9dea6887b 100755 --- a/tools/install.tmpl +++ b/tools/niminst/install.tmpl diff --git a/tools/niminst.nim b/tools/niminst/niminst.nim index 02e501a26..ee078fc0f 100755 --- a/tools/niminst.nim +++ b/tools/niminst/niminst.nim @@ -49,8 +49,9 @@ type cat: array[TFileCategory, seq[string]] binPaths, authors, oses, cpus: seq[string] cfiles: array[1..maxOS, array[1..maxCPU, seq[string]]] - ccompiler, innosetup: tuple[path, flags: string] + ccompiler, linker, innosetup: tuple[path, flags: string] name, displayName, version, description, license, infile, outdir: string + libpath: string innoSetupFlag, installScript, uninstallScript: bool vars: PStringTable app: TAppType @@ -69,6 +70,7 @@ proc initConfigData(c: var TConfigData) = c.oses = @[] c.cpus = @[] c.ccompiler = ("", "") + c.linker = ("", "") c.innosetup = ("", "") c.name = "" c.displayName = "" @@ -78,6 +80,7 @@ proc initConfigData(c: var TConfigData) = c.infile = "" c.outdir = "" c.nimrodArgs = "" + c.libpath = "" c.innoSetupFlag = false c.installScript = false c.uninstallScript = false @@ -255,6 +258,7 @@ proc parseIniFile(c: var TConfigData) = of "unixbin": filesOnly(p, k.key, v, c.cat[fcUnixBin]) of "innosetup": pathFlags(p, k.key, v, c.innoSetup) of "ccompiler": pathFlags(p, k.key, v, c.ccompiler) + of "linker": pathFlags(p, k.key, v, c.linker) else: quit(errorStr(p, "invalid section: " & section)) of cfgOption: quit(errorStr(p, "syntax error")) @@ -268,26 +272,36 @@ proc parseIniFile(c: var TConfigData) = # ------------------------- generate source based installation --------------- proc readCFiles(c: var TConfigData, osA, cpuA: int) = - var cfg: TCfgParser - var cfilesSection = false + var p: TCfgParser var f = splitFile(c.infile).dir / "mapping.txt" c.cfiles[osA][cpuA] = @[] var input = newFileStream(f, fmRead) + var section = "" if input != nil: - open(cfg, input, f) + open(p, input, f) while true: - var k = next(cfg) + var k = next(p) case k.kind of cfgEof: break of cfgSectionStart: - if cfilesSection: break - cfilesSection = cmpIgnoreStyle(k.section, "cfiles") == 0 - of cfgKeyValuePair: nil + section = normalize(k.section) + of cfgKeyValuePair: + case section + of "ccompiler": pathFlags(p, k.key, k.value, c.ccompiler) + of "linker": + pathFlags(p, k.key, k.value, c.linker) + # HACK: we conditionally add ``-lm -ldl``, so remove them from the + # linker flags: + c.linker.flags = c.linker.flags.replaceWord("-lm").replaceWord( + "-ldl").strip + else: + if cmpIgnoreStyle(k.key, "libpath") == 0: + c.libpath = k.value of cfgOption: - if cfilesSection and cmpIgnoreStyle(k.key, "file") == 0: + if section == "cfiles" and cmpIgnoreStyle(k.key, "file") == 0: add(c.cfiles[osA][cpuA], k.value) - of cfgError: quit(errorStr(cfg, k.msg)) - close(cfg) + of cfgError: quit(errorStr(p, k.msg)) + close(p) else: quit("Cannot open: " & f) @@ -321,7 +335,7 @@ proc removeDuplicateFiles(c: var TConfigData) = c.cfiles[osA][cpuA][i] = orig proc srcdist(c: var TConfigData) = - for x in walkFiles("lib/*.h"): + for x in walkFiles(c.libpath / "lib/*.h"): CopyFile(dest="build" / extractFilename(x), source=x) for osA in 1..c.oses.len: for cpuA in 1..c.cpus.len: @@ -380,7 +394,7 @@ when haveZipLib: addFile(z, proj / buildShFile, buildShFile) addFile(z, proj / installShFile, installShFile) addFile(z, proj / deinstallShFile, deinstallShFile) - for f in walkFiles("lib/*.h"): + for f in walkFiles(c.libpath / "lib/*.h"): addFile(z, proj / "build" / extractFilename(f), f) for osA in 1..c.oses.len: for cpuA in 1..c.cpus.len: diff --git a/web/news.txt b/web/news.txt index 925271921..3ab7ac751 100755 --- a/web/news.txt +++ b/web/news.txt @@ -129,7 +129,8 @@ Library Additions - Slicing as implemented by the system module now supports *splicing*. - Added explicit channels for thread communication. - Added ``matchers`` module for email address etc. matching. -- Added ``strutils.unindent``, ``strutils.countLines``. +- Added ``strutils.unindent``, ``strutils.countLines``, + ``strutils.replaceWord``. - Added ``system.slurp`` for easy resource embedding. - Added ``system.running`` for threads. - Added ``system.programResult``. |