From 5e9ce88dafbaa0bf72a7c7c3ce11a8d827ab3200 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Mon, 28 Sep 2015 14:34:36 -0700 Subject: [PATCH 01/14] implement bitsize pragma for bitfields --- compiler/ast.nim | 1 + compiler/ccgtypes.nim | 2 ++ compiler/pragmas.nim | 7 ++++++- compiler/wordrecg.nim | 2 ++ tests/pragmas/tbitsize.nim | 7 +++++++ 5 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tests/pragmas/tbitsize.nim diff --git a/compiler/ast.nim b/compiler/ast.nim index 4001e896e3..9db5a4e34f 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -784,6 +784,7 @@ type tab*: TStrTable # interface table for modules of skLet, skVar, skField, skForVar: guard*: PSym + bitsize*: BiggestInt else: nil magic*: TMagic typ*: PType diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 84d02d1da6..1ed9ce1139 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -441,6 +441,8 @@ proc genRecordFieldsAux(m: BModule, n: PNode, elif fieldType.kind == tySequence: # we need to use a weak dependency here for trecursive_table. addf(result, "$1 $2;$n", [getTypeDescWeak(m, field.loc.t, check), sname]) + elif field.bitsize != 0: + addf(result, "$1 $2:$3;$n", [getTypeDescAux(m, field.loc.t, check), sname, rope($field.bitsize)]) else: # don't use fieldType here because we need the # tyGenericInst for C++ template support diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 1c51251fe7..ba05b2792a 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -56,7 +56,7 @@ const wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked, wBorrow, wGcSafe} fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern, - wImportCpp, wImportObjC, wError, wGuard} + wImportCpp, wImportObjC, wError, wGuard, wBitsize} varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, wMagic, wHeader, wDeprecated, wCompilerproc, wDynlib, wExtern, wImportCpp, wImportObjC, wError, wNoInit, wCompileTime, wGlobal, @@ -844,6 +844,11 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, if sym == nil: pragmaLockStmt(c, it) elif sym.typ == nil: invalidPragma(it) else: sym.typ.lockLevel = pragmaLocks(c, it) + of wBitsize: + if sym == nil or sym.kind != skField or it.kind != nkExprColonExpr: + invalidPragma(it) + else: + sym.bitsize = expectIntLit(c, it) of wGuard: if sym == nil or sym.kind notin {skVar, skLet, skField}: invalidPragma(it) diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index 23f012ea50..d1e5438f3d 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -82,6 +82,7 @@ type wStdIn, wStdOut, wStdErr, wInOut, wByCopy, wByRef, wOneWay, + wBitsize, TSpecialWords* = set[TSpecialWord] @@ -168,6 +169,7 @@ const "stdin", "stdout", "stderr", "inout", "bycopy", "byref", "oneway", + "bitsize", ] proc findStr*(a: openArray[string], s: string): int = diff --git a/tests/pragmas/tbitsize.nim b/tests/pragmas/tbitsize.nim new file mode 100644 index 0000000000..d2c646ef74 --- /dev/null +++ b/tests/pragmas/tbitsize.nim @@ -0,0 +1,7 @@ +type + bits* = object + flag* {.bitsize: 1.}: cint + opts* {.bitsize: 4.}: cint + +var b: bits +echo b.flag From 0679340b52e521306c3d5dc44ba94d7eaacdb662 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Tue, 29 Sep 2015 14:39:20 -0700 Subject: [PATCH 02/14] switch to bitsize:int --- compiler/ast.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 9db5a4e34f..25958f580b 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -784,7 +784,7 @@ type tab*: TStrTable # interface table for modules of skLet, skVar, skField, skForVar: guard*: PSym - bitsize*: BiggestInt + bitsize*: int else: nil magic*: TMagic typ*: PType From fa404dc532f61b78bd0e714c121b41ba8fc15ca7 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Tue, 29 Sep 2015 14:53:34 -0700 Subject: [PATCH 03/14] better assertions for bitfield behavior --- tests/pragmas/tbitsize.nim | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tests/pragmas/tbitsize.nim b/tests/pragmas/tbitsize.nim index d2c646ef74..b9b478a7f1 100644 --- a/tests/pragmas/tbitsize.nim +++ b/tests/pragmas/tbitsize.nim @@ -1,7 +1,18 @@ type bits* = object - flag* {.bitsize: 1.}: cint + flag* {.bitsize: 1.}: cuint opts* {.bitsize: 4.}: cint -var b: bits -echo b.flag +var + b: bits + +assert b.flag == 0 +b.flag = 1 +assert b.flag == 1 +b.flag = 2 +assert b.flag == 0 + +b.opts = 7 +assert b.opts == 7 +b.opts = 9 +assert b.opts == -7 From 700b63ad895eaa4004d681e6a23cc382dd3600ca Mon Sep 17 00:00:00 2001 From: Adam Strzelecki Date: Wed, 30 Sep 2015 12:38:18 +0200 Subject: [PATCH 04/14] Use new #? filter prefix in various places This silences deprecation warnings and prevent collision with UNIX shebang. --- examples/filterex.nim | 2 +- tests/template/sunset.tmpl | 2 +- tools/niminst/buildbat.tmpl | 2 +- tools/niminst/buildsh.tmpl | 2 +- tools/niminst/deinstall.tmpl | 2 +- tools/niminst/inno.tmpl | 2 +- tools/niminst/install.tmpl | 2 +- tools/niminst/makefile.tmpl | 2 +- tools/niminst/nsis.tmpl | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/filterex.nim b/examples/filterex.nim index d9bfb67822..0839452544 100644 --- a/examples/filterex.nim +++ b/examples/filterex.nim @@ -1,4 +1,4 @@ -#! stdtmpl | standard +#? stdtmpl | standard #proc generateHTMLPage(title, currentTab, content: string, # tabs: openArray[string]): string = # result = "" diff --git a/tests/template/sunset.tmpl b/tests/template/sunset.tmpl index 6475bac4ec..465b12a5ea 100644 --- a/tests/template/sunset.tmpl +++ b/tests/template/sunset.tmpl @@ -1,4 +1,4 @@ -#! stdtmpl +#? stdtmpl #proc sunsetTemplate*(current, ticker, content: string, # tabs: openarray[array[0..1, string]]): string = # result = "" diff --git a/tools/niminst/buildbat.tmpl b/tools/niminst/buildbat.tmpl index 2c6a2b5a80..2a8da144d2 100644 --- a/tools/niminst/buildbat.tmpl +++ b/tools/niminst/buildbat.tmpl @@ -1,4 +1,4 @@ -#! stdtmpl(subsChar='?') | standard +#? stdtmpl(subsChar='?') | standard #proc generateBuildBatchScript(c: ConfigData, winIndex, cpuIndex: int): string = # result = "@echo off\nREM Generated by niminst\n" SET CC=gcc diff --git a/tools/niminst/buildsh.tmpl b/tools/niminst/buildsh.tmpl index 52da351bee..463a1ad527 100644 --- a/tools/niminst/buildsh.tmpl +++ b/tools/niminst/buildsh.tmpl @@ -1,4 +1,4 @@ -#! stdtmpl(subsChar='?') | standard +#? stdtmpl(subsChar='?') | standard #proc generateBuildShellScript(c: ConfigData): string = # result = "#! /bin/sh\n# Generated from niminst\n" & # "# Template is in tools/niminst/buildsh.tmpl\n" & diff --git a/tools/niminst/deinstall.tmpl b/tools/niminst/deinstall.tmpl index c4717a2579..7349abcb43 100644 --- a/tools/niminst/deinstall.tmpl +++ b/tools/niminst/deinstall.tmpl @@ -1,4 +1,4 @@ -#! stdtmpl(subsChar='?') | standard +#? stdtmpl(subsChar='?') | standard #proc generateDeinstallScript(c: ConfigData): string = # result = "#! /bin/sh\n# Generated by niminst\n" # var proj = c.name.toLower diff --git a/tools/niminst/inno.tmpl b/tools/niminst/inno.tmpl index 4acf0557c8..ef2da8a755 100644 --- a/tools/niminst/inno.tmpl +++ b/tools/niminst/inno.tmpl @@ -1,4 +1,4 @@ -#! stdtmpl | standard +#? stdtmpl | standard #proc generateInnoSetup(c: ConfigData): string = # result = "" ; Default Template for NimInst diff --git a/tools/niminst/install.tmpl b/tools/niminst/install.tmpl index 3ec42c2874..14d88e07df 100644 --- a/tools/niminst/install.tmpl +++ b/tools/niminst/install.tmpl @@ -1,4 +1,4 @@ -#! stdtmpl(subsChar = '?') | standard +#? stdtmpl(subsChar = '?') | standard #proc generateInstallScript(c: ConfigData): string = # result = "#! /bin/sh\n# Generated by niminst\n" # var proj = c.name.toLower diff --git a/tools/niminst/makefile.tmpl b/tools/niminst/makefile.tmpl index 8ab3b89d15..6615ddc022 100644 --- a/tools/niminst/makefile.tmpl +++ b/tools/niminst/makefile.tmpl @@ -1,4 +1,4 @@ -#! stdtmpl(subsChar='?') | standard +#? stdtmpl(subsChar='?') | standard #proc generateMakefile(c: ConfigData): string = # result = "# Generated from niminst\n" & # "# Template is in tools/niminst/makefile.tmpl\n" & diff --git a/tools/niminst/nsis.tmpl b/tools/niminst/nsis.tmpl index 843a8cf440..abf4623887 100644 --- a/tools/niminst/nsis.tmpl +++ b/tools/niminst/nsis.tmpl @@ -1,4 +1,4 @@ -#! stdtmpl(subsChar='?') | standard +#? stdtmpl(subsChar='?') | standard #proc generateNsisSetup(c: ConfigData): string = # result = "; NSIS script generated by niminst\n" & # "; To regenerate run ``niminst nsis`` or ``koch nsis``\n" From 8450ee9d5998e12158b590120321760a8f4b85d9 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Wed, 30 Sep 2015 11:42:50 -0700 Subject: [PATCH 05/14] ensure generated c-code matches --- tests/pragmas/tbitsize.nim | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/pragmas/tbitsize.nim b/tests/pragmas/tbitsize.nim index b9b478a7f1..7a44944d24 100644 --- a/tests/pragmas/tbitsize.nim +++ b/tests/pragmas/tbitsize.nim @@ -1,3 +1,7 @@ +discard """ +ccodeCheck: "\\i @'unsigned int flag:1;' .*" +""" + type bits* = object flag* {.bitsize: 1.}: cuint From 8c8646773024ea740c4c9f090619ddaf61bc16f0 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Wed, 30 Sep 2015 12:29:32 -0700 Subject: [PATCH 06/14] document new bitsize pragma --- doc/manual/pragmas.txt | 18 ++++++++++++++++++ web/news.txt | 2 ++ 2 files changed, 20 insertions(+) diff --git a/doc/manual/pragmas.txt b/doc/manual/pragmas.txt index 68a88f865a..f89194c9ad 100644 --- a/doc/manual/pragmas.txt +++ b/doc/manual/pragmas.txt @@ -531,6 +531,24 @@ Implementation Specific Pragmas This section describes additional pragmas that the current Nim implementation supports but which should not be seen as part of the language specification. +Bitsize pragma +-------------- + +The ``bitsize`` pragma is for object field members. It declares the field as +a bitfield in C/C++. + +.. code-block:: Nim + type + mybitfield = object + flag {.bitsize:1.}: cuint + +generates: + +.. code-block:: C + struct mybitfield { + unsigned int flag:1; + }; + Volatile pragma --------------- diff --git a/web/news.txt b/web/news.txt index cfa40c65ca..33ceac49e4 100644 --- a/web/news.txt +++ b/web/news.txt @@ -108,6 +108,8 @@ News - The compiler finally considers symbol binding rules in templates and generics for overloaded ``[]``, ``[]=``, ``{}``, ``{}=`` operators (issue `#2599 `_). + - The compiler now supports a `bitsize pragma `_ + for constructing bitfields. Language Additions From 9f33baf51b24049f8ead63a8dd7a58db6ef0e490 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Wed, 30 Sep 2015 19:02:23 -0700 Subject: [PATCH 07/14] add afterRunEvent callback to execProcesses --- lib/pure/osproc.nim | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index bc73f7119d..c23126be91 100644 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -248,7 +248,8 @@ proc countProcessors*(): int {.rtl, extern: "nosp$1".} = proc execProcesses*(cmds: openArray[string], options = {poStdErrToStdOut, poParentStreams}, n = countProcessors(), - beforeRunEvent: proc(idx: int) = nil): int + beforeRunEvent: proc(idx: int) = nil, + afterRunEvent: proc(idx: int, p: Process) = nil): int {.rtl, extern: "nosp$1", tags: [ExecIOEffect, TimeEffect, ReadEnvEffect, RootEffect]} = ## executes the commands `cmds` in parallel. Creates `n` processes @@ -278,6 +279,7 @@ proc execProcesses*(cmds: openArray[string], err.add("\n") echo(err) result = max(waitForExit(q[r]), result) + if afterRunEvent != nil: afterRunEvent(r, q[r]) if q[r] != nil: close(q[r]) if beforeRunEvent != nil: beforeRunEvent(i) @@ -291,6 +293,7 @@ proc execProcesses*(cmds: openArray[string], if not running(q[r]): #echo(outputStream(q[r]).readLine()) result = max(waitForExit(q[r]), result) + if afterRunEvent != nil: afterRunEvent(r, q[r]) if q[r] != nil: close(q[r]) if beforeRunEvent != nil: beforeRunEvent(i) @@ -299,6 +302,7 @@ proc execProcesses*(cmds: openArray[string], if i > high(cmds): break for j in 0..m-1: result = max(waitForExit(q[j]), result) + if afterRunEvent != nil: afterRunEvent(j, q[j]) if q[j] != nil: close(q[j]) else: for i in 0..high(cmds): @@ -306,6 +310,7 @@ proc execProcesses*(cmds: openArray[string], beforeRunEvent(i) var p = startProcess(cmds[i], options=options + {poEvalCommand}) result = max(waitForExit(p), result) + if afterRunEvent != nil: afterRunEvent(i, p) close(p) proc select*(readfds: var seq[Process], timeout = 500): int {.benign.} From ded5753292d837d2b4390caa64d3ebe8c8babc7c Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Wed, 30 Sep 2015 19:05:37 -0700 Subject: [PATCH 08/14] remove "rerun with --parallelBuild:1" message and show error inline --- compiler/extccomp.nim | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 29aa03c94c..ac645f307c 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -14,7 +14,7 @@ import lists, ropes, os, strutils, osproc, platform, condsyms, options, msgs, - securehash + securehash, streams type TSystemCC* = enum @@ -672,6 +672,12 @@ proc callCCompiler*(projectfile: string) = var prettyCmds: TStringSeq = @[] let prettyCb = proc (idx: int) = echo prettyCmds[idx] + let runCb = proc (idx: int, p: Process) = + let exitCode = p.peekExitCode + if exitCode != 0: + echo p.outputStream.readAll + rawMessage(errGenerated, "execution of an external compiler program '" & + cmds[idx] & "' failed with exit code: " & $exitCode) compileCFile(toCompile, script, cmds, prettyCmds, false) compileCFile(externalToCompile, script, cmds, prettyCmds, true) if optCompileOnly notin gGlobalOptions: @@ -682,22 +688,17 @@ proc callCCompiler*(projectfile: string) = res = execWithEcho(cmds[i]) if res != 0: rawMessage(errExecutionOfProgramFailed, cmds[i]) elif optListCmd in gGlobalOptions or gVerbosity > 1: - res = execProcesses(cmds, {poEchoCmd, poUsePath, poParentStreams}, - gNumberOfProcessors) + res = execProcesses(cmds, {poEchoCmd, poStdErrToStdOut, poUsePath, poParentStreams}, + gNumberOfProcessors, afterRunEvent=runCb) elif gVerbosity == 1: - res = execProcesses(cmds, {poUsePath, poParentStreams}, - gNumberOfProcessors, prettyCb) + res = execProcesses(cmds, {poStdErrToStdOut, poUsePath, poParentStreams}, + gNumberOfProcessors, prettyCb, afterRunEvent=runCb) else: - res = execProcesses(cmds, {poUsePath, poParentStreams}, - gNumberOfProcessors) + res = execProcesses(cmds, {poStdErrToStdOut, poUsePath, poParentStreams}, + gNumberOfProcessors, afterRunEvent=runCb) if res != 0: if gNumberOfProcessors <= 1: rawMessage(errExecutionOfProgramFailed, cmds.join()) - else: - rawMessage(errGenerated, - " execution of an external compiler program failed: " & - cmds.join() & "; " & - "rerun with --parallelBuild:1 to see the error message") if optNoLinking notin gGlobalOptions: # call the linker: var it = PStrEntry(toLink.head) From b093c0abd095468330e83da4a145d5fa9447a824 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Wed, 30 Sep 2015 19:32:09 -0700 Subject: [PATCH 09/14] show full compiler output with reNimcCrash --- tests/testament/tester.nim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/testament/tester.nim b/tests/testament/tester.nim index 3961f15c40..e52988682b 100644 --- a/tests/testament/tester.nim +++ b/tests/testament/tester.nim @@ -213,6 +213,8 @@ proc compilerOutputTests(test: TTest, given: var TSpec, expected: TSpec; expectedmsg = expected.nimout givenmsg = given.nimout.strip nimoutCheck(test, expectedmsg, given) + else: + givenmsg = given.nimout.strip if given.err == reSuccess: inc(r.passed) r.addResult(test, expectedmsg, givenmsg, given.err) From d6b7f0ad9e7a07cdd8295083e1c737a7bf0c6305 Mon Sep 17 00:00:00 2001 From: JamesP Date: Thu, 1 Oct 2015 15:02:46 +1000 Subject: [PATCH 10/14] add assertion for zero denominator --- lib/pure/rationals.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pure/rationals.nim b/lib/pure/rationals.nim index 60d09c71ac..79dc6de168 100644 --- a/lib/pure/rationals.nim +++ b/lib/pure/rationals.nim @@ -20,6 +20,7 @@ type Rational*[T] = object proc initRational*[T](num, den: T): Rational[T] = ## Create a new rational number. + assert(den != 0, "a denominator of zero value is invalid") result.num = num result.den = den From 2f4cc4efce714f036018107f73cf1f5db40cbffd Mon Sep 17 00:00:00 2001 From: JamesP Date: Thu, 1 Oct 2015 15:07:23 +1000 Subject: [PATCH 11/14] add a few type checks to limit type to SomeInteger (adding a compund type to the Rational type definition made it too difficult to define new variables using integer literals) --- lib/pure/rationals.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pure/rationals.nim b/lib/pure/rationals.nim index 79dc6de168..7d9241412a 100644 --- a/lib/pure/rationals.nim +++ b/lib/pure/rationals.nim @@ -18,7 +18,7 @@ type Rational*[T] = object ## a rational number, consisting of a numerator and denominator num*, den*: T -proc initRational*[T](num, den: T): Rational[T] = +proc initRational*[T:SomeInteger](num, den: T): Rational[T] = ## Create a new rational number. assert(den != 0, "a denominator of zero value is invalid") result.num = num @@ -34,7 +34,7 @@ proc `$`*[T](x: Rational[T]): string = ## Turn a rational number into a string. result = $x.num & "/" & $x.den -proc toRational*[T](x: T): Rational[T] = +proc toRational*[T:SomeInteger](x: T): Rational[T] = ## Convert some integer `x` to a rational number. result.num = x result.den = 1 @@ -48,7 +48,7 @@ proc toInt*[T](x: Rational[T]): int = ## `x` does not contain an integer value. x.num div x.den -proc reduce*[T](x: var Rational[T]) = +proc reduce*[T:SomeInteger](x: var Rational[T]) = ## Reduce rational `x`. let common = gcd(x.num, x.den) if x.den > 0: From ce18b85d2cfa89a148c9530ac654605475f19a73 Mon Sep 17 00:00:00 2001 From: JamesP Date: Thu, 1 Oct 2015 20:32:49 +1000 Subject: [PATCH 12/14] add two test: zero denominator assert fail, float type compile failure --- tests/rational/trat_float.nim | 9 +++++++++ tests/rational/trat_init.nim | 10 ++++++++++ 2 files changed, 19 insertions(+) create mode 100644 tests/rational/trat_float.nim create mode 100644 tests/rational/trat_init.nim diff --git a/tests/rational/trat_float.nim b/tests/rational/trat_float.nim new file mode 100644 index 0000000000..24797c4a01 --- /dev/null +++ b/tests/rational/trat_float.nim @@ -0,0 +1,9 @@ +discard """ + file: "trat_float.nim" + line: "9,19" + errormsg: '''type mismatch: got''' +""" +import rationals +var + # this fails - no floats as num or den + r = initRational(1.0'f, 1.0'f) diff --git a/tests/rational/trat_init.nim b/tests/rational/trat_init.nim new file mode 100644 index 0000000000..df29ff6e33 --- /dev/null +++ b/tests/rational/trat_init.nim @@ -0,0 +1,10 @@ +discard """ + file: "trat_init.nim" + exitcode: "1" +""" +import rationals +var + z = Rational[int](num: 0, den: 1) + o = initRational(num=1, den=1) + a = initRational(1, 2) + r = initRational(1, 0) # this fails - no zero denominator From 08843c6673056a37747642abf61f44c5c923be45 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Thu, 1 Oct 2015 13:16:18 -0700 Subject: [PATCH 13/14] remove echo() from compiler --- compiler/extccomp.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index ac645f307c..3882bdd036 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -675,9 +675,9 @@ proc callCCompiler*(projectfile: string) = let runCb = proc (idx: int, p: Process) = let exitCode = p.peekExitCode if exitCode != 0: - echo p.outputStream.readAll rawMessage(errGenerated, "execution of an external compiler program '" & - cmds[idx] & "' failed with exit code: " & $exitCode) + cmds[idx] & "' failed with exit code: " & $exitCode & "\n\n" & + p.outputStream.readAll.strip) compileCFile(toCompile, script, cmds, prettyCmds, false) compileCFile(externalToCompile, script, cmds, prettyCmds, true) if optCompileOnly notin gGlobalOptions: From 437603a8128a3ad40fef4ee39b7f24bdb96032c1 Mon Sep 17 00:00:00 2001 From: Hans Raaf Date: Fri, 2 Oct 2015 13:54:55 +0200 Subject: [PATCH 14/14] Added ReadIOEffect because thats what happens on OSX. --- lib/pure/ospaths.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/pure/ospaths.nim b/lib/pure/ospaths.nim index 99f6bcd4de..dcc7101939 100644 --- a/lib/pure/ospaths.nim +++ b/lib/pure/ospaths.nim @@ -496,7 +496,7 @@ when defined(nimdoc) and not declared(os): proc existsFile(x: string): bool = discard when declared(getEnv) or defined(nimscript): - proc getHomeDir*(): string {.rtl, extern: "nos$1", tags: [ReadEnvEffect].} = + proc getHomeDir*(): string {.rtl, extern: "nos$1", tags: [ReadEnvEffect, ReadIOEffect].} = ## Returns the home directory of the current user. ## ## This proc is wrapped by the expandTilde proc for the convenience of @@ -504,7 +504,7 @@ when declared(getEnv) or defined(nimscript): when defined(windows): return string(getEnv("USERPROFILE")) & "\\" else: return string(getEnv("HOME")) & "/" - proc getConfigDir*(): string {.rtl, extern: "nos$1", tags: [ReadEnvEffect].} = + proc getConfigDir*(): string {.rtl, extern: "nos$1", tags: [ReadEnvEffect, ReadIOEffect].} = ## Returns the config directory of the current user for applications. when defined(windows): return string(getEnv("APPDATA")) & "\\" else: return string(getEnv("HOME")) & "/.config/" @@ -515,7 +515,7 @@ when declared(getEnv) or defined(nimscript): when defined(windows): return string(getEnv("TEMP")) & "\\" else: return "/tmp/" - proc expandTilde*(path: string): string {.tags: [ReadEnvEffect].} = + proc expandTilde*(path: string): string {.tags: [ReadEnvEffect, ReadIOEffect].} = ## Expands a path starting with ``~/`` to a full path. ## ## If `path` starts with the tilde character and is followed by `/` or `\\` @@ -545,7 +545,7 @@ when declared(getEnv) or defined(nimscript): yield substr(s, first, last-1) inc(last) - proc findExe*(exe: string): string {.tags: [ReadDirEffect, ReadEnvEffect].} = + proc findExe*(exe: string): string {.tags: [ReadDirEffect, ReadEnvEffect, ReadIOEffect].} = ## Searches for `exe` in the current working directory and then ## in directories listed in the ``PATH`` environment variable. ## Returns "" if the `exe` cannot be found. On DOS-like platforms, `exe`