summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ccgexprs.nim3
-rw-r--r--compiler/msgs.nim2
-rw-r--r--compiler/options.nim27
-rw-r--r--compiler/service.nim1
-rw-r--r--doc/advopt.txt1
-rw-r--r--koch.nim1
-rw-r--r--lib/pure/collections/tables.nim2
-rw-r--r--lib/pure/ftpclient.nim2
-rw-r--r--lib/pure/httpclient.nim3
-rw-r--r--lib/pure/irc.nim2
-rw-r--r--lib/pure/osproc.nim10
-rw-r--r--lib/pure/scgi.nim1
-rw-r--r--lib/pure/selectors.nim1
-rw-r--r--lib/system/debugger.nim2
-rw-r--r--lib/wrappers/sqlite3.nim1
-rw-r--r--tests/assign/tobjasgn.nim17
-rw-r--r--tests/async/tasyncawait.nim1
-rw-r--r--tests/async/tasynciossl.nim4
-rw-r--r--tests/concurrency/tnodeadlocks.nim2
-rw-r--r--tests/dll/client.nim2
-rw-r--r--tests/dll/server.nim2
-rw-r--r--tests/generics/tmetafield.nim2
-rw-r--r--tests/generics/tthread_generic.nim2
-rw-r--r--tests/iter/titer2.nim2
-rw-r--r--tests/js.nim2
-rw-r--r--tests/js/test1.nim1
-rw-r--r--tests/js/test2.nim1
-rw-r--r--tests/js/testmagic.nim1
-rw-r--r--tests/misc/tgtk.nim4
-rw-r--r--tests/misc/tmandelbrot.nim2
-rw-r--r--tests/sets/tsets2.nim1
-rw-r--r--tests/stdlib/tsockets.nim3
-rw-r--r--tests/stdlib/tunidecode.nim2
-rw-r--r--tests/table/ttables.nim1
-rw-r--r--tests/table/ttables2.nim1
-rw-r--r--tests/testament/categories.nim10
-rw-r--r--tests/testament/specs.nim3
-rw-r--r--tests/testament/tester.nim49
-rw-r--r--tests/threads/tthreadanalysis.nim2
-rw-r--r--tests/threads/tthreadanalysis2.nim2
-rw-r--r--tests/threads/tthreadanalysis3.nim2
-rw-r--r--tests/threads/tthreadheapviolation1.nim2
-rw-r--r--tests/types/tillegaltyperecursion.nim2
43 files changed, 123 insertions, 61 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 9702fb25c..49350fa9c 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -1060,6 +1060,8 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
     t = t.sons[0].skipTypes(abstractInst)
     r = ropef("(*$1)", r)
     gcUsage(e)
+  else:
+    constructLoc(p, tmp)
   discard getTypeDesc(p.module, t)
   for i in 1 .. <e.len:
     let it = e.sons[i]
@@ -1082,6 +1084,7 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
     tmp2.s = if isRef: OnHeap else: OnStack
     tmp2.heapRoot = tmp.r
     expr(p, it.sons[1], tmp2)
+
   if d.k == locNone:
     d = tmp
   else:
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index 7ad393b4d..4d471bdac 100644
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -170,7 +170,7 @@ const
     errInvalidNumberOfYieldExpr: "invalid number of \'yield\' expressions", 
     errCannotReturnExpr: "current routine cannot return an expression", 
     errAttemptToRedefine: "redefinition of \'$1\'", 
-    errStmtInvalidAfterReturn: "statement not allowed after \'return\', \'break\' or \'raise\'", 
+    errStmtInvalidAfterReturn: "statement not allowed after \'return\', \'break\', \'raise\' or \'continue'", 
     errStmtExpected: "statement expected", 
     errInvalidLabel: "\'$1\' is no label", 
     errInvalidCmdLineOption: "invalid command line option: \'$1\'", 
diff --git a/compiler/options.nim b/compiler/options.nim
index fa8b77ead..f05354666 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -8,7 +8,7 @@
 #
 
 import
-  os, lists, strutils, strtabs
+  os, lists, strutils, strtabs, osproc, sets
   
 const
   hasTinyCBackend* = defined(tinyc)
@@ -16,6 +16,7 @@ const
   hasFFI* = defined(useFFI)
   newScopeForIf* = true
   useCaas* = not defined(noCaas)
+  noTimeMachine = defined(avoidTimeMachine) and defined(macosx)
 
 type                          # please make sure we have under 32 options
                               # (improves code efficiency a lot!)
@@ -263,6 +264,28 @@ proc toGeneratedFile*(path, ext: string): string =
   result = joinPath([getGeneratedPath(), changeFileExt(tail, ext)])
   #echo "toGeneratedFile(", path, ", ", ext, ") = ", result
 
+when noTimeMachine:
+  var alreadyExcludedDirs = initSet[string]()
+  proc excludeDirFromTimeMachine(dir: string) {.raises: [].} =
+    ## Calls a macosx command on the directory to exclude it from backups.
+    ##
+    ## The macosx tmutil command is invoked to mark the specified path as an
+    ## item to be excluded from time machine backups. If a path already exists
+    ## with files before excluding it, newer files won't be added to the
+    ## directory, but previous files won't be removed from the backup until the
+    ## user deletes that directory.
+    ##
+    ## The whole proc is optional and will ignore all kinds of errors. The only
+    ## way to be sure that it works is to call ``tmutil isexcluded path``.
+    if alreadyExcludedDirs.contains(dir): return
+    alreadyExcludedDirs.incl(dir)
+    try:
+      var p = startProcess("/usr/bin/tmutil", args = ["addexclusion", dir])
+      discard p.waitForExit
+      p.close
+    except E_Base, EOS:
+      discard
+
 proc completeGeneratedFilePath*(f: string, createSubDir: bool = true): string = 
   var (head, tail) = splitPath(f)
   #if len(head) > 0: head = removeTrailingDirSep(shortenDir(head & dirSep))
@@ -270,6 +293,8 @@ proc completeGeneratedFilePath*(f: string, createSubDir: bool = true): string =
   if createSubDir:
     try: 
       createDir(subdir)
+      when noTimeMachine:
+       excludeDirFromTimeMachine(subdir)
     except EOS: 
       writeln(stdout, "cannot create directory: " & subdir)
       quit(1)
diff --git a/compiler/service.nim b/compiler/service.nim
index 42c4aa9f4..2b861e1c7 100644
--- a/compiler/service.nim
+++ b/compiler/service.nim
@@ -84,6 +84,7 @@ proc serve*(action: proc (){.nimcall.}) =
   of "tcp", "":
     when useCaas:
       var server = socket()
+      if server == invalidSocket: osError(osLastError())
       let p = getConfigVar("server.port")
       let port = if p.len > 0: parseInt(p).TPort else: 6000.TPort
       server.bindAddr(port, getConfigVar("server.address"))
diff --git a/doc/advopt.txt b/doc/advopt.txt
index 0ebc85370..f5ff90791 100644
--- a/doc/advopt.txt
+++ b/doc/advopt.txt
@@ -4,6 +4,7 @@ Advanced commands:
   //compileToOC, objc       compile project to Objective C code
   //rst2html                convert a reStructuredText file to HTML
   //rst2tex                 convert a reStructuredText file to TeX
+  //jsondoc                 extract the documentation to a json file
   //buildIndex              build an index for the whole documentation
   //run                     run the project (with Tiny C backend; buggy!)
   //genDepend               generate a DOT file containing the
diff --git a/koch.nim b/koch.nim
index d7da56590..9d59344f2 100644
--- a/koch.nim
+++ b/koch.nim
@@ -53,6 +53,7 @@ Boot options:
                            (not needed on Windows)
   -d:nativeStacktrace      use native stack traces (only for Mac OS X or Linux)
   -d:noCaas                build Nimrod without CAAS support
+  -d:avoidTimeMachine      only for Mac OS X, excludes nimcache dir from backups
 """
 
 proc exe(f: string): string = return addFileExt(f, ExeExt)
diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim
index 412bebeee..cd28f9af0 100644
--- a/lib/pure/collections/tables.nim
+++ b/lib/pure/collections/tables.nim
@@ -196,7 +196,7 @@ proc `==`*[A, B](s, t: TTable[A, B]): bool =
     # to use the slow route here:
     for key, val in s:
       if not hasKey(t, key): return false
-      if mget(t, key) != val: return false
+      if t[key] != val: return false
     return true
   
 proc indexBy*[A, B, C](collection: A, index: proc(x: B): C): TTable[C, B] =
diff --git a/lib/pure/ftpclient.nim b/lib/pure/ftpclient.nim
index f136e0016..3bb55239b 100644
--- a/lib/pure/ftpclient.nim
+++ b/lib/pure/ftpclient.nim
@@ -107,6 +107,7 @@ proc ftpClient*(address: string, port = TPort(21),
   result.isAsync = false
   result.dsockConnected = false
   result.csock = socket()
+  if result.csock == InvalidSocket: osError(osLastError())
 
 proc getDSock(ftp: PFTPClient): TSocket =
   if ftp.isAsync: return ftp.asyncDSock else: return ftp.dsock
@@ -213,6 +214,7 @@ proc pasv(ftp: PFTPClient) =
   ## Negotiate a data connection.
   if not ftp.isAsync:
     ftp.dsock = socket()
+    if ftp.dsock == InvalidSocket: osError(osLastError())
   else:
     ftp.asyncDSock = AsyncSocket()
     ftp.asyncDSock.handleRead =
diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim
index 2a145eb89..be06a7b8e 100644
--- a/lib/pure/httpclient.nim
+++ b/lib/pure/httpclient.nim
@@ -75,7 +75,7 @@
 ## constructor should be used for this purpose. However,
 ## currently only basic authentication is supported.
 
-import sockets, strutils, parseurl, parseutils, strtabs, base64
+import sockets, strutils, parseurl, parseutils, strtabs, base64, os
 import asyncnet, asyncdispatch
 import rawsockets
 
@@ -288,6 +288,7 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "",
   add(headers, "\c\L")
   
   var s = socket()
+  if s == InvalidSocket: osError(osLastError())
   var port = sockets.TPort(80)
   if r.scheme == "https":
     when defined(ssl):
diff --git a/lib/pure/irc.nim b/lib/pure/irc.nim
index 83fb231f6..31a673210 100644
--- a/lib/pure/irc.nim
+++ b/lib/pure/irc.nim
@@ -249,6 +249,7 @@ proc reconnect*(irc: PIRC, timeout = 5000) =
   if secSinceReconnect < timeout:
     sleep(timeout - secSinceReconnect)
   irc.sock = socket()
+  if irc.sock == InvalidSocket: osError(osLastError())
   irc.connect()
   irc.lastReconnect = epochTime()
 
@@ -274,6 +275,7 @@ proc irc*(address: string, port: TPort = 6667.TPort,
   result.messageBuffer = @[]
   result.status = SockIdle
   result.sock = socket()
+  if result.sock == InvalidSocket: osError(osLastError())
 
 proc processLine(irc: PIRC, line: string): TIRCEvent =
   if line.len == 0:
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index 5d6848565..ed83507d4 100644
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -137,6 +137,14 @@ proc startProcess*(command: string,
   ## to `startProcess`. See the documentation of ``TProcessOption`` for the
   ## meaning of these flags. You need to `close` the process when done.
   ##
+  ## Note that you can't pass any `args` if you use the option
+  ## ``poEvalCommand``, which invokes the system shell to run the specified
+  ## `command`. In this situation you have to concatenate manually the contents
+  ## of `args` to `command` carefully escaping/quoting any special characters,
+  ## since it will be passed *as is* to the system shell. Each system/shell may
+  ## feature different escaping rules, so try to avoid this kind of shell
+  ## invokation if possible as it leads to non portable software.
+  ##
   ## Return value: The newly created process object. Nil is never returned,
   ## but ``EOS`` is raised in case of an error.
 
@@ -633,7 +641,7 @@ elif not defined(useNimRtl):
     if poEvalCommand in options:
       sysCommand = "/bin/sh"
       sysArgsRaw = @[sysCommand, "-c", command]
-      assert args.len == 0
+      assert args.len == 0, "`args` has to be empty when using poEvalCommand."
     else:
       sysCommand = command
       sysArgsRaw = @[command]
diff --git a/lib/pure/scgi.nim b/lib/pure/scgi.nim
index 04b77fafe..a6a0faabc 100644
--- a/lib/pure/scgi.nim
+++ b/lib/pure/scgi.nim
@@ -102,6 +102,7 @@ proc open*(s: var TScgiState, port = TPort(4000), address = "127.0.0.1",
   s.input = newString(s.buflen) # will be reused
   
   s.server = socket()
+  if s.server == InvalidSocket: osError(osLastError())
   new(s.client) # Initialise s.client for `next`
   if s.server == InvalidSocket: scgiError("could not open socket")
   #s.server.connect(connectionName, port)
diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim
index a4a7b5afd..f630ba235 100644
--- a/lib/pure/selectors.nim
+++ b/lib/pure/selectors.nim
@@ -238,6 +238,7 @@ when isMainModule:
       sock: TSocket
   
   var sock = socket()
+  if sock == sockets.InvalidSocket: osError(osLastError())
   #sock.setBlocking(false)
   sock.connect("irc.freenode.net", TPort(6667))
   
diff --git a/lib/system/debugger.nim b/lib/system/debugger.nim
index b5cb5e9ba..af7b6d515 100644
--- a/lib/system/debugger.nim
+++ b/lib/system/debugger.nim
@@ -178,7 +178,7 @@ proc hash(data: pointer, size: int): THash =
   while s > 0:
     h = h !& ord(p[i])
     inc(i)
-    cec(s)
+    dec(s)
   result = !$h
 
 proc hashGcHeader(data: pointer): THash =
diff --git a/lib/wrappers/sqlite3.nim b/lib/wrappers/sqlite3.nim
index 8ff1da1d1..586f763ae 100644
--- a/lib/wrappers/sqlite3.nim
+++ b/lib/wrappers/sqlite3.nim
@@ -90,6 +90,7 @@ const
   SQLITE_IGNORE* = 2          # Original from sqlite3.h: 
                               ##define SQLITE_STATIC      ((void(*)(void *))0)
                               ##define SQLITE_TRANSIENT   ((void(*)(void *))-1)
+  SQLITE_DETERMINISTIC* = 0x800
 
 const 
   SQLITE_STATIC* = nil
diff --git a/tests/assign/tobjasgn.nim b/tests/assign/tobjasgn.nim
index 5f411063f..23a31252d 100644
--- a/tests/assign/tobjasgn.nim
+++ b/tests/assign/tobjasgn.nim
@@ -1,16 +1,21 @@
 discard """
-  output: '''0
+  output: '''8 5 0 0
 pre test a:test b:1 c:2 haha:3
 assignment test a:test b:1 c:2 haha:3
 '''
 """
 
-type TSomeObj = object of TObject
-  Variable: int
- 
-var a = TSomeObj()
+# bug #1005
+
+type
+  TSomeObj = object of TObject
+    a, b: int
+  PSomeObj = ref object
+    a, b: int
  
-echo a.Variable.`$`
+var a = TSomeObj(a: 8)
+var b = PSomeObj(a: 5)
+echo a.a, " ", b.a, " ", a.b, " ", b.b
 
 # bug #575
 
diff --git a/tests/async/tasyncawait.nim b/tests/async/tasyncawait.nim
index bd722842f..ffceeaee6 100644
--- a/tests/async/tasyncawait.nim
+++ b/tests/async/tasyncawait.nim
@@ -1,6 +1,5 @@
 discard """
   file: "tasyncawait.nim"
-  cmd: "nimrod cc --hints:on $# $#"
   output: "5000"
 """
 import asyncdispatch, rawsockets, net, strutils, os
diff --git a/tests/async/tasynciossl.nim b/tests/async/tasynciossl.nim
index fbed46efb..26c4c587c 100644
--- a/tests/async/tasynciossl.nim
+++ b/tests/async/tasynciossl.nim
@@ -1,6 +1,6 @@
 discard """
   file: "tasynciossl.nim"
-  cmd: "nimrod cc --hints:on --define:ssl $# $#"
+  cmd: "nimrod $target --hints:on --define:ssl $options $file"
   output: "20000"
 """
 import sockets, asyncio, strutils, times
@@ -88,4 +88,4 @@ while true:
     break
 
 assert msgCount == (swarmSize * messagesToSend) * serverCount
-echo(msgCount)
\ No newline at end of file
+echo(msgCount)
diff --git a/tests/concurrency/tnodeadlocks.nim b/tests/concurrency/tnodeadlocks.nim
index 3f27e24f6..d44196039 100644
--- a/tests/concurrency/tnodeadlocks.nim
+++ b/tests/concurrency/tnodeadlocks.nim
@@ -1,6 +1,6 @@
 discard """
   outputsub: "101"
-  cmd: "nimrod cc --hints:on --threads:on $# $#"
+  cmd: "nimrod $target --hints:on --threads:on $options $file"
 """
 
 import os, locks
diff --git a/tests/dll/client.nim b/tests/dll/client.nim
index a78cef1d4..45fa8f639 100644
--- a/tests/dll/client.nim
+++ b/tests/dll/client.nim
@@ -1,6 +1,6 @@
 discard """
   output: "Done"
-  cmd: "nimrod cc --debuginfo --hints:on --define:useNimRtl $# $#"
+  cmd: "nimrod $target --debuginfo --hints:on --define:useNimRtl $options $file"
 """
 
 type
diff --git a/tests/dll/server.nim b/tests/dll/server.nim
index ae2acc893..b2fac9ecc 100644
--- a/tests/dll/server.nim
+++ b/tests/dll/server.nim
@@ -1,5 +1,5 @@
 discard """
-  cmd: "nimrod cc --debuginfo --hints:on --define:useNimRtl --app:lib $# $#"
+  cmd: "nimrod $target --debuginfo --hints:on --define:useNimRtl --app:lib $options $file"
 """
 
 type
diff --git a/tests/generics/tmetafield.nim b/tests/generics/tmetafield.nim
index f2fac8fdd..e1bc43ce3 100644
--- a/tests/generics/tmetafield.nim
+++ b/tests/generics/tmetafield.nim
@@ -1,5 +1,5 @@
 discard """
-  cmd: "nimrod check $# $#"
+  cmd: "nimrod check $options $file"
   errormsg: "'proc' is not a concrete type"
   errormsg: "'Foo' is not a concrete type."
   errormsg: "invalid type: 'TBaseMed'"
diff --git a/tests/generics/tthread_generic.nim b/tests/generics/tthread_generic.nim
index beae4b652..7109bba18 100644
--- a/tests/generics/tthread_generic.nim
+++ b/tests/generics/tthread_generic.nim
@@ -1,5 +1,5 @@
 discard """
-  cmd: "nimrod cc --hints:on --threads:on $# $#"
+  cmd: "nimrod $target --hints:on --threads:on $options $file"
 """
 
 type
diff --git a/tests/iter/titer2.nim b/tests/iter/titer2.nim
index f8967109e..71c7327a7 100644
--- a/tests/iter/titer2.nim
+++ b/tests/iter/titer2.nim
@@ -1,6 +1,6 @@
 discard """
   output: '''true'''
-  cmd: "nimrod cc --gc:none --hints:on --warnings:off $# $#"
+  cmd: "nimrod $target --gc:none --hints:on --warnings:off $options $file"
 """
 
 import hashes
diff --git a/tests/js.nim b/tests/js.nim
index f31bb10d9..becc17834 100644
--- a/tests/js.nim
+++ b/tests/js.nim
@@ -1,5 +1,5 @@
 discard """
-  cmd: "nimrod js --hints:on $# $#"
+  cmd: "nimrod js --hints:on $options $file"
 """
 
 # This file tests the JavaScript generator
diff --git a/tests/js/test1.nim b/tests/js/test1.nim
index 3f3d5f02c..09ba30676 100644
--- a/tests/js/test1.nim
+++ b/tests/js/test1.nim
@@ -1,5 +1,4 @@
 discard """
-  cmd: "nimrod js --hints:on $# $#"
   output: "1261129"
 """
 
diff --git a/tests/js/test2.nim b/tests/js/test2.nim
index 1342ed15d..5a734358c 100644
--- a/tests/js/test2.nim
+++ b/tests/js/test2.nim
@@ -1,5 +1,4 @@
 discard """
-  cmd: "nimrod js --hints:on -r $# $#"
   output: '''foo
 js 3.14'''
 """
diff --git a/tests/js/testmagic.nim b/tests/js/testmagic.nim
index 2c02d24be..5f793ae05 100644
--- a/tests/js/testmagic.nim
+++ b/tests/js/testmagic.nim
@@ -1,5 +1,4 @@
 discard """
-  cmd: "nimrod js --hints:on -r $# $#"
   output: '''true'''
 """
 
diff --git a/tests/misc/tgtk.nim b/tests/misc/tgtk.nim
index 7febb0ab8..82227689d 100644
--- a/tests/misc/tgtk.nim
+++ b/tests/misc/tgtk.nim
@@ -1,4 +1,6 @@
-

+discard """

+  disabled: true

+"""

 import

   gtk2, glib2, atk, gdk2, gdk2pixbuf, libglade2, pango,

   pangoutils

diff --git a/tests/misc/tmandelbrot.nim b/tests/misc/tmandelbrot.nim
index 1e39c8756..bb1b46d89 100644
--- a/tests/misc/tmandelbrot.nim
+++ b/tests/misc/tmandelbrot.nim
@@ -1,5 +1,5 @@
 discard """
-  cmd: "nimrod cc --hints:on -d:release $# $#"
+  cmd: "nimrod $target --hints:on -d:release $options $file"
 """
 
 # -*- nimrod -*-
diff --git a/tests/sets/tsets2.nim b/tests/sets/tsets2.nim
index ac977096b..7f313e14f 100644
--- a/tests/sets/tsets2.nim
+++ b/tests/sets/tsets2.nim
@@ -1,6 +1,5 @@
 discard """
   output: '''true'''
-  cmd: "nimrod cc --hints:on $# $#"
 """
 
 import hashes, sets
diff --git a/tests/stdlib/tsockets.nim b/tests/stdlib/tsockets.nim
index 6078504f5..ff566df74 100644
--- a/tests/stdlib/tsockets.nim
+++ b/tests/stdlib/tsockets.nim
@@ -1,6 +1,7 @@
-import sockets
+import sockets, os
 var s: TSocket
 s = socket()
+if s == InvalidSocket: osError(osLastError())
 
 s.connect("www.google.com", TPort(80))
 
diff --git a/tests/stdlib/tunidecode.nim b/tests/stdlib/tunidecode.nim
index cb6589d60..647858825 100644
--- a/tests/stdlib/tunidecode.nim
+++ b/tests/stdlib/tunidecode.nim
@@ -1,5 +1,5 @@
 discard """
-  cmd: "nimrod cc --hints:on -d:embedUnidecodeTable $# $#"
+  cmd: "nimrod $target --hints:on -d:embedUnidecodeTable $options $file"
   output: "Ausserst"
 """
 
diff --git a/tests/table/ttables.nim b/tests/table/ttables.nim
index 681ff5424..60446b5a3 100644
--- a/tests/table/ttables.nim
+++ b/tests/table/ttables.nim
@@ -1,6 +1,5 @@
 discard """
   output: '''true'''
-  cmd: "nimrod cc --hints:on $# $#"
 """
 
 import hashes, tables
diff --git a/tests/table/ttables2.nim b/tests/table/ttables2.nim
index b88c8dfbf..611f3f8ec 100644
--- a/tests/table/ttables2.nim
+++ b/tests/table/ttables2.nim
@@ -1,6 +1,5 @@
 discard """
   output: '''true'''
-  cmd: "nimrod cc --hints:on $# $#"
 """
 
 import tables
diff --git a/tests/testament/categories.nim b/tests/testament/categories.nim
index 9bb4838e0..faccfed57 100644
--- a/tests/testament/categories.nim
+++ b/tests/testament/categories.nim
@@ -179,10 +179,12 @@ proc jsTests(r: var TResults, cat: Category, options: string) =
     
   for t in os.walkFiles("tests/js/t*.nim"):
     test(t)
-  for testfile in ["texceptions", "texcpt1", "texcsub", "tfinally",
-                   "tfinally2", "tfinally3", "tactiontable", "tmultim1",
-                   "tmultim3", "tmultim4"]:
-    test "tests/run/" & testfile & ".nim"
+  for testfile in ["exception/texceptions", "exception/texcpt1",
+                   "exception/texcsub", "exception/tfinally",
+                   "exception/tfinally2", "exception/tfinally3",
+                   "actiontable/tactiontable", "method/tmultim1",
+                   "method/tmultim3", "method/tmultim4"]:
+    test "tests/" & testfile & ".nim"
 
 # ------------------------- manyloc -------------------------------------------
 #proc runSpecialTests(r: var TResults, options: string) =
diff --git a/tests/testament/specs.nim b/tests/testament/specs.nim
index 65e17a453..225ea1891 100644
--- a/tests/testament/specs.nim
+++ b/tests/testament/specs.nim
@@ -10,7 +10,7 @@
 import parseutils, strutils, os, osproc, streams, parsecfg
 
 const
-  cmdTemplate* = r"nimrod cc --hints:on $# $#"
+  cmdTemplate* = r"nimrod $target --hints:on $options $file"
 
 type
   TTestAction* = enum
@@ -51,6 +51,7 @@ type
 
 const
   targetToExt*: array[TTarget, string] = ["c", "cpp", "m", "js"]
+  targetToCmd*: array[TTarget, string] = ["c", "cpp", "objc", "js"]
 
 when not defined(parseCfgBool):
   # candidate for the stdlib:
diff --git a/tests/testament/tester.nim b/tests/testament/tester.nim
index 6655b1b79..757e54889 100644
--- a/tests/testament/tester.nim
+++ b/tests/testament/tester.nim
@@ -53,8 +53,10 @@ let
   pegSuccess = peg"'Hint: operation successful'.*"
   pegOfInterest = pegLineError / pegOtherError
 
-proc callCompiler(cmdTemplate, filename, options: string): TSpec =
-  let c = parseCmdLine(cmdTemplate % [options, filename])
+proc callCompiler(cmdTemplate, filename, options: string,
+                  target: TTarget): TSpec =
+  let c = parseCmdLine(cmdTemplate % ["target", targetToCmd[target],
+                       "options", options, "file", filename])
   var p = startProcess(command=c[0], args=c[1.. -1],
                        options={poStdErrToStdOut, poUseShell})
   let outp = p.outputStream
@@ -111,10 +113,10 @@ proc addResult(r: var TResults, test: TTest,
   r.data.addf("$#\t$#\t$#\t$#", name, expected, given, $success)
   if success notin {reSuccess, reIgnored}:
     styledEcho styleBright, name, fgRed, " [", $success, "]"
-    styledEcho styleDim, "EXPECTED:"
-    echo expected
-    styledEcho styleDim, "GIVEN:"
-    echo given
+    echo"Expected:"
+    styledEcho styleBright, expected
+    echo"Given:"
+    styledEcho styleBright, given
 
 proc cmpMsgs(r: var TResults, expected, given: TSpec, test: TTest) =
   if strip(expected.msg) notin strip(given.msg):
@@ -152,7 +154,7 @@ proc testSpec(r: var TResults, test: TTest) =
   # major entry point for a single test
   let tname = test.name.addFileExt(".nim")
   inc(r.total)
-  echo extractFilename(tname)
+  styledEcho "Processing ", fgCyan, extractFilename(tname)
   var expected = parseSpec(tname)
   if expected.err == reIgnored:
     r.addResult(test, "", "", reIgnored)
@@ -160,13 +162,15 @@ proc testSpec(r: var TResults, test: TTest) =
   else:
     case expected.action
     of actionCompile:
-      var given = callCompiler(expected.cmd, test.name, test.options)
+      var given = callCompiler(expected.cmd, test.name, test.options,
+                               test.target)
       if given.err == reSuccess:
         codegenCheck(test, expected.ccodeCheck, given)
       r.addResult(test, "", given.msg, given.err)
       if given.err == reSuccess: inc(r.passed)
     of actionRun:
-      var given = callCompiler(expected.cmd, test.name, test.options)
+      var given = callCompiler(expected.cmd, test.name, test.options,
+                               test.target)
       if given.err != reSuccess:
         r.addResult(test, "", given.msg, given.err)
       else:
@@ -176,10 +180,13 @@ proc testSpec(r: var TResults, test: TTest) =
           exeFile = dir / "nimcache" / file & ".js"
         else:
           exeFile = changeFileExt(tname, ExeExt)
-        
         if existsFile(exeFile):
+          if test.target == targetJS and findExe("nodejs") == "":
+            r.addResult(test, expected.outp, "nodejs binary not in PATH",
+                        reExeNotFound)
+            return
           var (buf, exitCode) = execCmdEx(
-            (if test.target==targetJS: "node " else: "") & exeFile)
+            (if test.target == targetJS: "nodejs " else: "") & exeFile)
           if exitCode != expected.ExitCode:
             r.addResult(test, "exitcode: " & $expected.exitCode,
                               "exitcode: " & $exitCode, reExitCodesDiffer)
@@ -194,7 +201,8 @@ proc testSpec(r: var TResults, test: TTest) =
         else:
           r.addResult(test, expected.outp, "executable not found", reExeNotFound)
     of actionReject:
-      var given = callCompiler(expected.cmd, test.name, test.options)
+      var given = callCompiler(expected.cmd, test.name, test.options,
+                               test.target)
       cmpMsgs(r, expected, given, test)
 
 proc testNoSpec(r: var TResults, test: TTest) =
@@ -202,7 +210,7 @@ proc testNoSpec(r: var TResults, test: TTest) =
   let tname = test.name.addFileExt(".nim")
   inc(r.total)
   echo extractFilename(tname)
-  let given = callCompiler(cmdTemplate, test.name, test.options)
+  let given = callCompiler(cmdTemplate, test.name, test.options, test.target)
   r.addResult(test, "", given.msg, given.err)
   if given.err == reSuccess: inc(r.passed)
 
@@ -223,7 +231,7 @@ proc main() =
   os.putenv "NIMTEST_NO_COLOR", "1"
   os.putenv "NIMTEST_OUTPUT_LVL", "PRINT_FAILURES"
 
-  backend.open()  
+  backend.open()
   var optPrintResults = false
   var p = initOptParser()
   p.next()
@@ -238,9 +246,12 @@ proc main() =
   var r = initResults()
   case action
   of "all":
-    for kind, dir in walkDir("tests"):
-      if kind == pcDir and dir notin ["testament", "testdata", "nimcache"]:
-        processCategory(r, Category(dir), p.cmdLineRest.string)
+    let testsDir = "tests" & dirSep
+    for kind, dir in walkDir(testsDir):
+      assert testsDir.startsWith(testsDir)
+      let cat = dir[testsDir.len .. -1]
+      if kind == pcDir and cat notin ["testament", "testdata", "nimcache"]:
+        processCategory(r, Category(cat), p.cmdLineRest.string)
     for a in AdditionalCategories:
       processCategory(r, Category(a), p.cmdLineRest.string)
   of "c", "cat", "category":
@@ -255,11 +266,11 @@ proc main() =
   else:
     quit usage
 
-  if optPrintResults: 
+  if optPrintResults:
     if action == "html": openDefaultBrowser(resultsFile)
     else: echo r, r.data
   backend.close()
-  
+
 if paramCount() == 0:
   quit usage
 main()
diff --git a/tests/threads/tthreadanalysis.nim b/tests/threads/tthreadanalysis.nim
index 3a46cd185..383680d81 100644
--- a/tests/threads/tthreadanalysis.nim
+++ b/tests/threads/tthreadanalysis.nim
@@ -2,7 +2,7 @@ discard """
   outputsub: "101"
   msg: "Warning: write to foreign heap"
   line: 37
-  cmd: "nimrod cc --hints:on --threads:on $# $#"
+  cmd: "nimrod $target --hints:on --threads:on $options $file"
 """
 
 import os
diff --git a/tests/threads/tthreadanalysis2.nim b/tests/threads/tthreadanalysis2.nim
index 07f0e61fd..697e2cb22 100644
--- a/tests/threads/tthreadanalysis2.nim
+++ b/tests/threads/tthreadanalysis2.nim
@@ -2,7 +2,7 @@ discard """
   file: "tthreadanalysis2.nim"
   line: 42
   errormsg: "write to foreign heap"
-  cmd: "nimrod cc --hints:on --threads:on $# $#"
+  cmd: "nimrod $target --hints:on --threads:on $options $file"
 """
 
 import os
diff --git a/tests/threads/tthreadanalysis3.nim b/tests/threads/tthreadanalysis3.nim
index d7a838fec..3c17fe7e2 100644
--- a/tests/threads/tthreadanalysis3.nim
+++ b/tests/threads/tthreadanalysis3.nim
@@ -2,7 +2,7 @@ discard """
   file: "tthreadanalysis3.nim"
   line: 35
   errormsg: "write to foreign heap"
-  cmd: "nimrod cc --hints:on --threads:on $# $#"
+  cmd: "nimrod $target --hints:on --threads:on $options $file"
 """
 
 import os
diff --git a/tests/threads/tthreadheapviolation1.nim b/tests/threads/tthreadheapviolation1.nim
index 7ca6f7928..f3a36e036 100644
--- a/tests/threads/tthreadheapviolation1.nim
+++ b/tests/threads/tthreadheapviolation1.nim
@@ -1,7 +1,7 @@
 discard """
   line: 12
   errormsg: "write to foreign heap"
-  cmd: "nimrod cc --hints:on --threads:on $# $#"
+  cmd: "nimrod $target --hints:on --threads:on $options $file"
 """
 
 var 
diff --git a/tests/types/tillegaltyperecursion.nim b/tests/types/tillegaltyperecursion.nim
index 711f458bf..114e4d08e 100644
--- a/tests/types/tillegaltyperecursion.nim
+++ b/tests/types/tillegaltyperecursion.nim
@@ -1,5 +1,5 @@
 discard """
-  cmd: "nimrod c --threads:on $# $#"
+  cmd: "nimrod $target --threads:on $options $file"
   errormsg: "illegal recursion in type 'TIRC'"
   line: 16
 """