summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-05-25 21:20:26 +0200
committerAraq <rumpf_a@web.de>2014-05-25 21:20:26 +0200
commit04a1555f4aa90eadc4d974a04abbf50d1e8b7134 (patch)
tree2e26496b1158a1b14c8c0bb307c670ea2d100cb5
parentb230303fd6dd1d593aecf792ee8f72552e7e5946 (diff)
parent1d6c05edc399e31919114f2b07519ae79ae1b804 (diff)
downloadNim-04a1555f4aa90eadc4d974a04abbf50d1e8b7134.tar.gz
Merge branch 'devel' of https://github.com/Araq/Nimrod into devel
-rw-r--r--compiler/ccgexprs.nim2
-rw-r--r--compiler/ccgtypes.nim47
-rw-r--r--compiler/ccgutils.nim21
-rw-r--r--compiler/cgen.nim3
-rw-r--r--compiler/jsgen.nim12
-rw-r--r--compiler/main.nim2
-rw-r--r--compiler/nimrod.ini2
-rw-r--r--compiler/rodutils.nim2
-rw-r--r--doc/abstypes.txt152
-rw-r--r--doc/lib.txt2
-rw-r--r--doc/manual.txt85
-rw-r--r--doc/nimrodc.txt2
-rw-r--r--koch.nim4
-rw-r--r--lib/posix/posix.nim4
-rw-r--r--lib/pure/asyncdispatch.nim31
-rw-r--r--lib/pure/asyncnet.nim2
-rw-r--r--lib/pure/collections/queues.nim2
-rw-r--r--lib/pure/future.nim1
-rw-r--r--lib/pure/math.nim21
-rw-r--r--lib/pure/memfiles.nim24
-rw-r--r--lib/pure/nimprof.nim13
-rw-r--r--lib/pure/oids.nim4
-rw-r--r--lib/pure/osproc.nim2
-rw-r--r--lib/pure/selectors.nim80
-rw-r--r--lib/pure/sockets.nim2
-rw-r--r--lib/system/ansi_c.nim3
-rw-r--r--lib/system/excpt.nim10
-rw-r--r--lib/system/sets.nim4
-rw-r--r--lib/windows/windows.nim16
-rw-r--r--lib/wrappers/openssl.nim2
-rw-r--r--tests/async/tasyncawait.nim6
-rw-r--r--tests/ccgbugs/tbug1081.nim17
32 files changed, 294 insertions, 286 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 94a6f4781..39333a80d 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -484,7 +484,7 @@ proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
     opr: array[mUnaryMinusI..mAbsI64, string] = [
       mUnaryMinusI: "((NI$2)-($1))",
       mUnaryMinusI64: "-($1)",
-      mAbsI: "(NI$2)abs($1)",
+      mAbsI: "($1 > 0? ($1) : -($1))",
       mAbsI64: "($1 > 0? ($1) : -($1))"]
   var
     a: TLoc
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index f51e66897..7c11d3e9a 100644
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -11,49 +11,10 @@
 
 # ------------------------- Name Mangling --------------------------------
 
-proc mangleField(name: string): string = 
-  case name[0]
-  of 'a'..'z': 
-    result = ""
-    add(result, chr(ord(name[0]) - ord('a') + ord('A')))
-  of '0'..'9', 'A'..'Z': 
-    result = ""
-    add(result, name[0])
-  else: result = "HEX" & toHex(ord(name[0]), 2)
-  for i in countup(1, len(name) - 1): 
-    case name[i]
-    of 'A'..'Z': 
-      add(result, chr(ord(name[i]) - ord('A') + ord('a')))
-    of '_': 
-      discard
-    of 'a'..'z', '0'..'9': 
-      add(result, name[i])
-    else: 
-      add(result, "HEX")
-      add(result, toHex(ord(name[i]), 2))
-
-proc mangle(name: string): string = 
-  when false:
-    case name[0]
-    of 'a'..'z': 
-      result = ""
-      add(result, chr(ord(name[0]) - ord('a') + ord('A')))
-    of '0'..'9', 'A'..'Z': 
-      result = ""
-      add(result, name[0])
-    else: result = "HEX" & toHex(ord(name[0]), 2)
-  result = ""
-  for i in countup(0, len(name) - 1): 
-    case name[i]
-    of 'A'..'Z': 
-      add(result, chr(ord(name[i]) - ord('A') + ord('a')))
-    of '_': 
-      discard
-    of 'a'..'z', '0'..'9': 
-      add(result, name[i])
-    else: 
-      add(result, "HEX")
-      add(result, toHex(ord(name[i]), 2))
+proc mangleField(name: string): string =
+  result = mangle(name)
+  if name[0] in 'a'..'z':
+    result[0] = name[0].toUpper
 
 proc isKeyword(w: PIdent): bool =
   # nimrod and C++ share some keywords
diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim
index 1d8f0158b..9beb08a21 100644
--- a/compiler/ccgutils.nim
+++ b/compiler/ccgutils.nim
@@ -161,6 +161,27 @@ proc makeSingleLineCString*(s: string): string =
     result.add(c.toCChar)
   result.add('\"')
 
+proc mangle*(name: string): string =
+  result = ""
+  case name[0]
+  of Letters:
+    result.add(name[0].toLower)
+  of Digits:
+    result.add("N" & name[0])
+  else:
+    result = "HEX" & toHex(ord(name[0]), 2)
+  for i in 1..(name.len-1):
+    let c = name[i]
+    case c
+    of 'A'..'Z':
+      add(result, c.toLower)
+    of '_':
+      discard
+    of 'a'..'z', '0'..'9':
+      add(result, c)
+    else:
+      add(result, "HEX" & toHex(ord(c), 2))
+
 proc makeLLVMString*(s: string): PRope = 
   const MaxLineLength = 64
   result = nil
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 8d66d7a3b..198b1187d 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -503,7 +503,8 @@ proc assignLocalVar(p: BProc, s: PSym) =
     if sfRegister in s.flags: app(decl, " register")
     #elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds:
     #  app(decl, " GC_GUARD")
-    if sfVolatile in s.flags or p.nestedTryStmts.len > 0: 
+    if sfVolatile in s.flags or (p.nestedTryStmts.len > 0 and
+                                 gCmd != cmdCompileToCpp):
       app(decl, " volatile")
     appf(decl, " $1;$n", [s.loc.r])
   else:
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index 373a11e9a..6687e2e8e 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -136,18 +136,6 @@ proc mapType(typ: PType): TJSTypeKind =
   of tyProc: result = etyProc
   of tyCString: result = etyString
   
-proc mangle(name: string): string = 
-  result = ""
-  for i in countup(0, len(name) - 1): 
-    case name[i]
-    of 'A'..'Z': 
-      add(result, chr(ord(name[i]) - ord('A') + ord('a')))
-    of '_': 
-      discard
-    of 'a'..'z', '0'..'9': 
-      add(result, name[i])
-    else: add(result, 'X' & toHex(ord(name[i]), 2))
-  
 proc mangleName(s: PSym): PRope = 
   result = s.loc.r
   if result == nil: 
diff --git a/compiler/main.nim b/compiler/main.nim
index f833394f7..b4af49248 100644
--- a/compiler/main.nim
+++ b/compiler/main.nim
@@ -310,7 +310,7 @@ proc mainCommand* =
   of "cpp", "compiletocpp":
     extccomp.cExt = ".cpp"
     gCmd = cmdCompileToCpp
-    if cCompiler == ccGcc: setCC("gpp")
+    if cCompiler == ccGcc: setCC("gcc")
     wantMainModule()
     defineSymbol("cpp")
     commandCompileToC()
diff --git a/compiler/nimrod.ini b/compiler/nimrod.ini
index 0dc44a7c9..8b2353aab 100644
--- a/compiler/nimrod.ini
+++ b/compiler/nimrod.ini
@@ -3,7 +3,7 @@ Name: "Nimrod"
 Version: "$version"
 Platforms: """
   windows: i386;amd64
-  linux: i386;amd64;powerpc64;arm;sparc;mips
+  linux: i386;amd64;powerpc64;arm;sparc;mips;powerpc
   macosx: i386;amd64;powerpc64
   solaris: i386;amd64;sparc
   freebsd: i386;amd64
diff --git a/compiler/rodutils.nim b/compiler/rodutils.nim
index 4433ed4ab..09b92cd8a 100644
--- a/compiler/rodutils.nim
+++ b/compiler/rodutils.nim
@@ -10,7 +10,7 @@
 ## Serialization utilities for the compiler.
 import strutils
 
-proc c_sprintf(buf, frmt: cstring) {.importc: "sprintf", nodecl, varargs.}
+proc c_sprintf(buf, frmt: cstring) {.importc: "sprintf", header: "<stdio.h>", nodecl, varargs.}
 
 proc toStrMaxPrecision*(f: BiggestFloat): string = 
   if f != f:
diff --git a/doc/abstypes.txt b/doc/abstypes.txt
deleted file mode 100644
index c5827745a..000000000
--- a/doc/abstypes.txt
+++ /dev/null
@@ -1,152 +0,0 @@
-==============
-Abstract types
-==============
-
-.. contents::
-
-Abstract types in Nimrod provide a means to model different `units`:idx: of
-a `base type`:idx:.
-
-
-Use case 1: SQL strings
------------------------
-An SQL statement that is passed from Nimrod to an SQL database might be
-modelled as a string. However, using string templates and filling in the
-values is vulnerable to the famous `SQL injection attack`:idx:\:
-
-.. code-block:: nimrod
-  proc query(db: TDbHandle, statement: TSQL) = ...
-
-  var
-    username: string
-
-  db.query("SELECT FROM users WHERE name = '$1'" % username)
-  # Horrible security hole, but the compiler does not mind!
-
-This can be avoided by distinguishing strings that contain SQL from strings
-that don't. Abstract types provide a means to introduce a new string type
-``TSQL`` that is incompatible with ``string``:
-
-.. code-block:: nimrod
-  type
-    TSQL = abstract string
-
-  proc query(db: TDbHandle, statement: TSQL) = ...
-
-  var
-    username: string
-
-  db.query("SELECT FROM users WHERE name = '$1'" % username)
-  # Error at compile time: `query` expects an SQL string!
-
-
-It is an essential property of abstract types that they **do not** imply a
-subtype relation between the abtract type and its base type. Explict type
-conversions from ``string`` to ``TSQL`` are allowed:
-
-.. code-block:: nimrod
-  proc properQuote(s: string): TSQL =
-    # quotes a string properly for an SQL statement
-    ...
-
-  proc `%` (frmt: TSQL, values: openarray[string]): TSQL =
-    # quote each argument:
-    var v = values.each(properQuote)
-    # we need a temporary type for the type conversion :-(
-    type TStrSeq = seq[string]
-    # call strutils.`%`:
-    result = TSQL(string(frmt) % TStrSeq(v))
-
-  db.query("SELECT FROM users WHERE name = $1".TSQL % username)
-
-Now we have compile-time checking against SQL injection attacks.
-Since ``"".TSQL`` is transformed to ``TSQL("")`` no new syntax is needed
-for nice looking ``TSQL`` string literals.
-
-
-
-Use case 2: Money
------------------
-Different currencies should not be mixed in monetary calculations. Abstract
-types are a perfect tool to model different currencies:
-
-.. code-block:: nimrod
-  type
-    TDollar = abstract int
-    TEuro = abstract int
-
-  var
-    d: TDollar
-    e: TEuro
-
-  echo d + 12
-  # Error: cannot add a number with no unit with a ``TDollar``
-
-Unfortunetaly, ``d + 12.TDollar`` is not allowed either,
-because ``+`` is defined for ``int`` (among others), not for ``TDollar``. So
-we define our own ``+`` for dollars:
-
-.. code-block::
-  proc `+` (x, y: TDollar): TDollar =
-    result = TDollar(int(x) + int(y))
-
-It does not make sense to multiply a dollar with a dollar, but with a
-number without unit; and the same holds for division:
-
-.. code-block::
-  proc `*` (x: TDollar, y: int): TDollar =
-    result = TDollar(int(x) * y)
-
-  proc `*` (x: int, y: TDollar): TDollar =
-    result = TDollar(x * int(y))
-
-  proc `div` ...
-
-This quickly gets tedious. The implementations are trivial and the compiler
-should not generate all this code only to optimize it away later - after all
-``+`` for dollars should produce the same binary code as ``+`` for ints.
-The pragma ``borrow`` has been designed to solve this problem; in principle
-it generates the trivial implementation for us:
-
-.. code-block:: nimrod
-  proc `*` (x: TDollar, y: int): TDollar {.borrow.}
-  proc `*` (x: int, y: TDollar): TDollar {.borrow.}
-  proc `div` (x: TDollar, y: int): TDollar {.borrow.}
-
-The ``borrow`` pragma makes the compiler to use the same implementation as
-the proc that deals with the abstract type's base type, so no code is
-generated.
-
-But it seems we still have to repeat all this boilerplate code for
-the ``TEuro`` currency. Fortunately, Nimrod has a template mechanism:
-
-.. code-block:: nimrod
-  template Additive(typ: typeDesc): stmt =
-    proc `+` *(x, y: typ): typ {.borrow.}
-    proc `-` *(x, y: typ): typ {.borrow.}
-
-    # unary operators:
-    proc `+` *(x: typ): typ {.borrow.}
-    proc `-` *(x: typ): typ {.borrow.}
-
-  template Multiplicative(typ, base: typeDesc): stmt =
-    proc `*` *(x: typ, y: base): typ {.borrow.}
-    proc `*` *(x: base, y: typ): typ {.borrow.}
-    proc `div` *(x: typ, y: base): typ {.borrow.}
-    proc `mod` *(x: typ, y: base): typ {.borrow.}
-
-  template Comparable(typ: typeDesc): stmt =
-    proc `<` * (x, y: typ): bool {.borrow.}
-    proc `<=` * (x, y: typ): bool {.borrow.}
-    proc `==` * (x, y: typ): bool {.borrow.}
-
-  template DefineCurrency(typ, base: expr): stmt =
-    type
-      typ* = abstract base
-    Additive(typ)
-    Multiplicative(typ, base)
-    Comparable(typ)
-
-  DefineCurrency(TDollar, int)
-  DefineCurrency(TEuro, int)
-
diff --git a/doc/lib.txt b/doc/lib.txt
index 3ca519c9e..2da753007 100644
--- a/doc/lib.txt
+++ b/doc/lib.txt
@@ -535,7 +535,7 @@ Database support
 * `odbcsql <odbcsql.html>`_
   interface to the ODBC driver.
 * `sphinx <sphinx.html>`_
-  Nimrod wrapper for ``shpinx``.
+  Nimrod wrapper for ``sphinx``.
 
 
 XML Processing
diff --git a/doc/manual.txt b/doc/manual.txt
index 39e2bad2a..a87abab7a 100644
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -123,7 +123,7 @@ This means that all the control structures are recognized by indentation.
 Indentation consists only of spaces; tabulators are not allowed.
 
 The indentation handling is implemented as follows: The lexer annotates the
-following token with the preceeding number of spaces; indentation is not
+following token with the preceding number of spaces; indentation is not
 a separate token. This trick allows parsing of Nimrod with only 1 token of
 lookahead.
 
@@ -617,7 +617,7 @@ Ordinal types
 
 Integers, bool, characters and enumeration types (and subranges of these
 types) belong to ordinal types. For reasons of simplicity of implementation
-the types ``uint`` and ``uint64`` are no ordinal types.
+the types ``uint`` and ``uint64`` are not ordinal types.
 
 
 Pre-defined integer types
@@ -686,7 +686,7 @@ kinds of integer types are used: the smaller type is converted to the larger.
 A `narrowing type conversion`:idx: converts a larger to a smaller type (for
 example ``int32 -> int16``. A `widening type conversion`:idx: converts a 
 smaller type to a larger type (for example ``int16 -> int32``). In Nimrod only
-widening type conversion are *implicit*:
+widening type conversions are *implicit*:
 
 .. code-block:: nimrod
   var myInt16 = 5i16
@@ -965,6 +965,14 @@ stack roots conservatively. One can use the builtin procs ``GC_ref`` and
 ``GC_unref`` to keep the string data alive for the rare cases where it does
 not work.
 
+A `$` proc is defined for cstrings that returns a string. Thus to get a nimrod
+string from a cstring:
+
+.. code-block:: nimrod
+  var str: string = "Hello!"
+  var cstr: cstring = s
+  var newstr: string = $cstr
+
 
 Structured types
 ----------------
@@ -1519,7 +1527,7 @@ Most calling conventions exist only for the Windows 32-bit platform.
 
 Assigning/passing a procedure to a procedural variable is only allowed if one
 of the following conditions hold:
-1) The procedure that is accessed resists in the current module.
+1) The procedure that is accessed resides in the current module.
 2) The procedure is marked with the ``procvar`` pragma (see `procvar pragma`_).
 3) The procedure has a calling convention that differs from ``nimcall``.
 4) The procedure is anonymous.
@@ -1527,8 +1535,8 @@ of the following conditions hold:
 The rules' purpose is to prevent the case that extending a non-``procvar`` 
 procedure with default parameters breaks client code.
 
-The default calling convention is ``nimcall``, unless it is an inner proc (
-a proc inside of a proc). For an inner proc an analysis is performed whether it
+The default calling convention is ``nimcall``, unless it is an inner proc (a
+proc inside of a proc). For an inner proc an analysis is performed whether it
 accesses its environment. If it does so, it has the calling convention
 ``closure``, otherwise it has the calling convention ``nimcall``.
 
@@ -1542,6 +1550,10 @@ of a distinct type that it **does not** imply a subtype relation between it
 and its base type. Explicit type conversions from a distinct type to its
 base type and vice versa are allowed.
 
+
+Modelling currencies
+~~~~~~~~~~~~~~~~~~~~
+
 A distinct type can be used to model different physical `units`:idx: with a
 numerical base type, for example. The following example models currencies.
 
@@ -1649,6 +1661,67 @@ certain builtin operations to be lifted:
 Currently only the dot accessor can be borrowed in this way.
 
 
+Avoiding SQL injection attacks
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+An SQL statement that is passed from Nimrod to an SQL database might be
+modelled as a string. However, using string templates and filling in the
+values is vulnerable to the famous `SQL injection attack`:idx:\:
+
+.. code-block:: nimrod
+  import strutils
+
+  proc query(db: TDbHandle, statement: string) = ...
+
+  var
+    username: string
+
+  db.query("SELECT FROM users WHERE name = '$1'" % username)
+  # Horrible security hole, but the compiler does not mind!
+
+This can be avoided by distinguishing strings that contain SQL from strings
+that don't. Distinct types provide a means to introduce a new string type
+``TSQL`` that is incompatible with ``string``:
+
+.. code-block:: nimrod
+  type
+    TSQL = distinct string
+
+  proc query(db: TDbHandle, statement: TSQL) = ...
+
+  var
+    username: string
+
+  db.query("SELECT FROM users WHERE name = '$1'" % username)
+  # Error at compile time: `query` expects an SQL string!
+
+
+It is an essential property of abstract types that they **do not** imply a
+subtype relation between the abtract type and its base type. Explict type
+conversions from ``string`` to ``TSQL`` are allowed:
+
+.. code-block:: nimrod
+  import strutils, sequtils
+
+  proc properQuote(s: string): TSQL =
+    # quotes a string properly for an SQL statement
+    return TSQL(s)
+
+  proc `%` (frmt: TSQL, values: openarray[string]): TSQL =
+    # quote each argument:
+    let v = values.mapIt(TSQL, properQuote(it))
+    # we need a temporary type for the type conversion :-(
+    type TStrSeq = seq[string]
+    # call strutils.`%`:
+    result = TSQL(string(frmt) % TStrSeq(v))
+
+  db.query("SELECT FROM users WHERE name = '$1'".TSQL % [username])
+
+Now we have compile-time checking against SQL injection attacks.  Since
+``"".TSQL`` is transformed to ``TSQL("")`` no new syntax is needed for nice
+looking ``TSQL`` string literals. The hypothetical ``TSQL`` type actually
+exists in the library as the `TSqlQuery type <db_sqlite.html#TSqlQuery>`_ of
+modules like `db_sqlite <db_sqlite.html>`_.
 
 
 Void type
diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt
index 52e0a6eaf..d1925547e 100644
--- a/doc/nimrodc.txt
+++ b/doc/nimrodc.txt
@@ -167,7 +167,7 @@ might contain some cruft even when dead code elimination is turned on. So
 the final release build should be done with ``--symbolFiles:off``.

 

 Due to the aggregation of C code it is also recommended that each project

-resists in its own directory so that the generated ``nimcache`` directory

+resides in its own directory so that the generated ``nimcache`` directory

 is not shared between different projects.

 

 

diff --git a/koch.nim b/koch.nim
index 79acc7791..4d0ac0254 100644
--- a/koch.nim
+++ b/koch.nim
@@ -152,7 +152,7 @@ proc boot(args: string) =
   copyExe(findStartNimrod(), 0.thVersion)
   for i in 0..2:
     echo "iteration: ", i+1
-    exec i.thVersion & " cc $# $# compiler" / "nimrod.nim" % [bootOptions, args]
+    exec i.thVersion & " c $# $# compiler" / "nimrod.nim" % [bootOptions, args]
     if sameFileContent(output, i.thVersion):
       copyExe(output, finalDest)
       echo "executables are equal: SUCCESS!"
@@ -167,7 +167,7 @@ const
   cleanExt = [
     ".ppu", ".o", ".obj", ".dcu", ".~pas", ".~inc", ".~dsk", ".~dpr",
     ".map", ".tds", ".err", ".bak", ".pyc", ".exe", ".rod", ".pdb", ".idb",
-    ".idx"
+    ".idx", ".ilk"
   ]
   ignore = [
     ".bzrignore", "nimrod", "nimrod.exe", "koch", "koch.exe", ".gitignore"
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim
index e206447cc..cdca826ca 100644
--- a/lib/posix/posix.nim
+++ b/lib/posix/posix.nim
@@ -846,7 +846,7 @@ var
   FE_UPWARD* {.importc, header: "<fenv.h>".}: cint
   FE_DFL_ENV* {.importc, header: "<fenv.h>".}: cint
 
-when not defined(haiku):
+when not defined(haiku) and not defined(OpenBSD):
   var
     MM_HARD* {.importc, header: "<fmtmsg.h>".}: cint
       ## Source of the condition is hardware.
@@ -1816,7 +1816,7 @@ proc feholdexcept*(a1: ptr Tfenv): cint {.importc, header: "<fenv.h>".}
 proc fesetenv*(a1: ptr Tfenv): cint {.importc, header: "<fenv.h>".}
 proc feupdateenv*(a1: ptr Tfenv): cint {.importc, header: "<fenv.h>".}
 
-when not defined(haiku):
+when not defined(haiku) and not defined(OpenBSD):
   proc fmtmsg*(a1: int, a2: cstring, a3: cint,
               a4, a5, a6: cstring): cint {.importc, header: "<fmtmsg.h>".}
 
diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim
index fcf947831..87ee83ad9 100644
--- a/lib/pure/asyncdispatch.nim
+++ b/lib/pure/asyncdispatch.nim
@@ -71,6 +71,11 @@ proc fail*[T](future: PFuture[T], error: ref EBase) =
   future.error = error
   if future.cb != nil:
     future.cb()
+  else:
+    # This is to prevent exceptions from being silently ignored when a future
+    # is discarded.
+    # TODO: This may turn out to be a bad idea.
+    raise error
 
 proc `callback=`*(future: PFutureBase, cb: proc () {.closure,gcsafe.}) =
   ## Sets the callback proc to be called when the future completes.
@@ -532,11 +537,15 @@ when defined(windows) or defined(nimdoc):
     result.TSocketHandle.setBlocking(false)
     register(result)
 
-  proc close*(socket: TAsyncFD) =
+  proc closeSocket*(socket: TAsyncFD) =
     ## Closes a socket and ensures that it is unregistered.
     socket.TSocketHandle.close()
     getGlobalDispatcher().handles.excl(socket)
 
+  proc unregister*(fd: TAsyncFD) =
+    ## Unregisters ``fd``.
+    getGlobalDispatcher().handles.excl(fd)
+
   initAll()
 else:
   import selectors
@@ -581,11 +590,14 @@ else:
     result.TSocketHandle.setBlocking(false)
     register(result)
   
-  proc close*(sock: TAsyncFD) =
+  proc closeSocket*(sock: TAsyncFD) =
     let disp = getGlobalDispatcher()
     sock.TSocketHandle.close()
     disp.selector.unregister(sock.TSocketHandle)
 
+  proc unregister*(fd: TAsyncFD) =
+    getGlobalDispatcher().selector.unregister(fd.TSocketHandle)
+
   proc addRead(sock: TAsyncFD, cb: TCallback) =
     let p = getGlobalDispatcher()
     if sock.TSocketHandle notin p.selector:
@@ -801,8 +813,9 @@ proc generateExceptionCheck(futSym,
     elseNode[0].add rootReceiver
     result.add elseNode
 
-template createVar(futSymName: string, asyncProc: PNimrodNode,
-                   valueReceiver, rootReceiver: expr) {.immediate, dirty.} =
+template createVar(result: var PNimrodNode, futSymName: string,
+                   asyncProc: PNimrodNode,
+                   valueReceiver, rootReceiver: expr) =
   result = newNimNode(nnkStmtList)
   var futSym = genSym(nskVar, "future")
   result.add newVarStmt(futSym, asyncProc) # -> var future<x> = y
@@ -839,7 +852,7 @@ proc processBody(node, retFutureSym: PNimrodNode,
       of nnkCall:
         # await foo(p, x)
         var futureValue: PNimrodNode
-        createVar("future" & $node[1][0].toStrLit, node[1], futureValue,
+        result.createVar("future" & $node[1][0].toStrLit, node[1], futureValue,
                   futureValue)
       else:
         error("Invalid node kind in 'await', got: " & $node[1].kind)
@@ -847,7 +860,7 @@ proc processBody(node, retFutureSym: PNimrodNode,
          node[1][0].ident == !"await":
       # foo await x
       var newCommand = node
-      createVar("future" & $node[0].toStrLit, node[1][1], newCommand[1],
+      result.createVar("future" & $node[0].toStrLit, node[1][1], newCommand[1],
                 newCommand)
 
   of nnkVarSection, nnkLetSection:
@@ -856,7 +869,7 @@ proc processBody(node, retFutureSym: PNimrodNode,
       if node[0][2][0].ident == !"await":
         # var x = await y
         var newVarSection = node # TODO: Should this use copyNimNode?
-        createVar("future" & $node[0][0].ident, node[0][2][1],
+        result.createVar("future" & $node[0][0].ident, node[0][2][1],
           newVarSection[0][2], newVarSection)
     else: discard
   of nnkAsgn:
@@ -865,14 +878,14 @@ proc processBody(node, retFutureSym: PNimrodNode,
       if node[1][0].ident == !"await":
         # x = await y
         var newAsgn = node
-        createVar("future" & $node[0].toStrLit, node[1][1], newAsgn[1], newAsgn)
+        result.createVar("future" & $node[0].toStrLit, node[1][1], newAsgn[1], newAsgn)
     else: discard
   of nnkDiscardStmt:
     # discard await x
     if node[0].kind != nnkEmpty and node[0][0].kind == nnkIdent and
           node[0][0].ident == !"await":
       var newDiscard = node
-      createVar("futureDiscard_" & $toStrLit(node[0][1]), node[0][1],
+      result.createVar("futureDiscard_" & $toStrLit(node[0][1]), node[0][1],
                 newDiscard[0], newDiscard)
   of nnkTryStmt:
     # try: await x; except: ...
diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim
index 9394078c8..d16c85c58 100644
--- a/lib/pure/asyncnet.nim
+++ b/lib/pure/asyncnet.nim
@@ -220,7 +220,7 @@ proc listen*(socket: PAsyncSocket, backlog = SOMAXCONN) =
 
 proc close*(socket: PAsyncSocket) =
   ## Closes the socket.
-  socket.fd.TAsyncFD.close()
+  socket.fd.TAsyncFD.closeSocket()
   # TODO SSL
 
 when isMainModule:
diff --git a/lib/pure/collections/queues.nim b/lib/pure/collections/queues.nim
index 5481272f0..db1d50569 100644
--- a/lib/pure/collections/queues.nim
+++ b/lib/pure/collections/queues.nim
@@ -59,7 +59,7 @@ proc enqueue*[T](q: var TQueue[T], item: T) =
 
 proc dequeue*[T](q: var TQueue[T]): T =
   ## removes and returns the first element of the queue `q`.
-  assert q.count > 0
+  assert q.len > 0
   dec q.count
   result = q.data[q.rd]
   q.rd = (q.rd + 1) and q.mask
diff --git a/lib/pure/future.nim b/lib/pure/future.nim
index e0e4c4176..b7df05207 100644
--- a/lib/pure/future.nim
+++ b/lib/pure/future.nim
@@ -18,7 +18,6 @@ proc createProcType(p, b: PNimrodNode): PNimrodNode {.compileTime.} =
   result = newNimNode(nnkProcTy)
   var formalParams = newNimNode(nnkFormalParams)
 
-  expectKind(b, nnkIdent)
   formalParams.add b
 
   case p.kind
diff --git a/lib/pure/math.nim b/lib/pure/math.nim
index e4aecd272..78ea02cbf 100644
--- a/lib/pure/math.nim
+++ b/lib/pure/math.nim
@@ -135,12 +135,12 @@ proc random*(max: int): int {.gcsafe.}
   ## which initializes the random number generator with a "random"
   ## number, i.e. a tickcount.
 
-when not defined(windows):
-  proc random*(max: float): float {.gcsafe.}
-    ## returns a random number in the range 0..<max. The sequence of
-    ## random number is always the same, unless `randomize` is called
-    ## which initializes the random number generator with a "random"
-    ## number, i.e. a tickcount. This is currently not supported for windows.
+proc random*(max: float): float {.gcsafe.}
+  ## returns a random number in the range 0..<max. The sequence of
+  ## random number is always the same, unless `randomize` is called
+  ## which initializes the random number generator with a "random"
+  ## number, i.e. a tickcount. This has a 16-bit resolution on windows
+  ## and a 48-bit resolution on other platforms.
 
 proc randomize*() {.gcsafe.}
   ## initializes the random number generator with a "random"
@@ -205,7 +205,14 @@ when not defined(JS):
     proc drand48(): float {.importc: "drand48", header: "<stdlib.h>".}
     proc random(max: float): float =
       result = drand48() * max
-    
+  when defined(windows):
+    proc random(max: float): float =
+      # we are hardcodeing this because
+      # importcing macros is extremely problematic
+      # and because the value is publicly documented
+      # on MSDN and very unlikely to change
+      const rand_max = 32767
+      result = (float(rand()) / float(rand_max)) * max
   proc randomize() =
     randomize(cast[int](epochTime()))
 
diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim
index 807f3da43..31fefc6c8 100644
--- a/lib/pure/memfiles.nim
+++ b/lib/pure/memfiles.nim
@@ -74,9 +74,22 @@ proc unmapMem*(f: var TMemFile, p: pointer, size: int) =
 proc open*(filename: string, mode: TFileMode = fmRead,
            mappedSize = -1, offset = 0, newFileSize = -1): TMemFile =
   ## opens a memory mapped file. If this fails, ``EOS`` is raised.
-  ## `newFileSize` can only be set if the file is not opened with ``fmRead``
-  ## access. `mappedSize` and `offset` can be used to map only a slice of
-  ## the file.
+  ## `newFileSize` can only be set if the file does not exist and is opened
+  ## with write access (e.g., with fmReadWrite). `mappedSize` and `offset`
+  ## can be used to map only a slice of the file. Example:
+  ##
+  ## .. code-block:: nimrod
+  ##   var
+  ##     mm, mm_full, mm_half: TMemFile
+  ##
+  ##   mm = memfiles.open("/tmp/test.mmap", mode = fmWrite, newFileSize = 1024)    # Create a new file
+  ##   mm.close()
+  ##
+  ##   # Read the whole file, would fail if newFileSize was set
+  ##   mm_full = memfiles.open("/tmp/test.mmap", mode = fmReadWrite, mappedSize = -1)
+  ##
+  ##   # Read the first 512 bytes
+  ##   mm_half = memfiles.open("/tmp/test.mmap", mode = fmReadWrite, mappedSize = 512)
 
   # The file can be resized only when write mode is used:
   assert newFileSize == -1 or mode != fmRead
@@ -165,8 +178,11 @@ proc open*(filename: string, mode: TFileMode = fmRead,
 
     if newFileSize != -1:
       flags = flags or O_CREAT or O_TRUNC
+      var permissions_mode = S_IRUSR or S_IWUSR
+      result.handle = open(filename, flags, permissions_mode)
+    else:
+      result.handle = open(filename, flags)
 
-    result.handle = open(filename, flags)
     if result.handle == -1:
       # XXX: errno is supposed to be set here
       # Is there an exception that wraps it?
diff --git a/lib/pure/nimprof.nim b/lib/pure/nimprof.nim
index 3d0cc2154..ab7cd1944 100644
--- a/lib/pure/nimprof.nim
+++ b/lib/pure/nimprof.nim
@@ -58,8 +58,9 @@ when not defined(memProfiler):
     ## instruction count measure instead then.
     if intervalInUs <= 0: interval = 0
     else: interval = intervalInUs * 1000 - tickCountCorrection
-  
+
 when withThreads:
+  import locks
   var
     profilingLock: TLock
 
@@ -72,7 +73,7 @@ proc hookAux(st: TStackTrace, costs: int) =
   var last = high(st)
   while last > 0 and isNil(st[last]): dec last
   var h = hash(pointer(st[last])) and high(profileData)
-  
+
   # we use probing for maxChainLen entries and replace the encountered entry
   # with the minimal 'total' value:
   if emptySlots == 0:
@@ -133,7 +134,7 @@ else:
       hookAux(st, 1)
     elif getticks() - t0 > interval:
       hookAux(st, 1)
-      t0 = getticks()  
+      t0 = getticks()
 
 proc getTotal(x: ptr TProfileEntry): int =
   result = if isNil(x): 0 else: x.total
@@ -145,7 +146,7 @@ proc `//`(a, b: int): string =
   result = format("$1/$2 = $3%", a, b, formatFloat(a / b * 100.0, ffDefault, 2))
 
 proc writeProfile() {.noconv.} =
-  when defined(system.TStackTrace): 
+  when defined(system.TStackTrace):
     system.profilerHook = nil
   const filename = "profile_results.txt"
   echo "writing " & filename & "..."
@@ -156,7 +157,7 @@ proc writeProfile() {.noconv.} =
     var entries = 0
     for i in 0..high(profileData):
       if profileData[i] != nil: inc entries
-    
+
     var perProc = initCountTable[string]()
     for i in 0..entries-1:
       var dups = initSet[string]()
@@ -166,7 +167,7 @@ proc writeProfile() {.noconv.} =
         let p = $procname
         if not containsOrIncl(dups, p):
           perProc.inc(p, profileData[i].total)
-    
+
     var sum = 0
     # only write the first 100 entries:
     for i in 0..min(100, entries-1):
diff --git a/lib/pure/oids.nim b/lib/pure/oids.nim
index b3e74d2a1..2843e6c65 100644
--- a/lib/pure/oids.nim
+++ b/lib/pure/oids.nim
@@ -62,9 +62,9 @@ var
 
 proc genOid*(): TOid =
   ## generates a new OID.
-  proc rand(): cint {.importc: "rand", nodecl.}
+  proc rand(): cint {.importc: "rand", header: "<stdlib.h>", nodecl.}
   proc gettime(dummy: ptr cint): cint {.importc: "time", header: "<time.h>".}
-  proc srand(seed: cint) {.importc: "srand", nodecl.}
+  proc srand(seed: cint) {.importc: "srand", header: "<stdlib.h>", nodecl.}
 
   var t = gettime(nil)
   
diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim
index 6e250f9d5..d2ada7014 100644
--- a/lib/pure/osproc.nim
+++ b/lib/pure/osproc.nim
@@ -903,7 +903,7 @@ elif not defined(useNimRtl):
       createStream(p.errStream, p.errHandle, fmRead)
     return p.errStream
 
-  proc csystem(cmd: cstring): cint {.nodecl, importc: "system".}
+  proc csystem(cmd: cstring): cint {.nodecl, importc: "system", header: "<stdlib.h>".}
 
   proc execCmd(command: string): int =
     when defined(linux):
diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim
index f630ba235..3af5f699c 100644
--- a/lib/pure/selectors.nim
+++ b/lib/pure/selectors.nim
@@ -11,9 +11,12 @@
 
 import tables, os, unsigned, hashes
 
-when defined(linux): import posix, epoll
-elif defined(windows): import winlean
-else: import posix
+when defined(linux): 
+  import posix, epoll
+elif defined(windows): 
+  import winlean
+else: 
+  import posix
 
 proc hash*(x: TSocketHandle): THash {.borrow.}
 proc `$`*(x: TSocketHandle): string {.borrow.}
@@ -29,7 +32,36 @@ type
 
   TReadyInfo* = tuple[key: PSelectorKey, events: set[TEvent]]
 
-when defined(linux) or defined(nimdoc):
+when defined(nimdoc):
+  type
+    PSelector* = ref object
+      ## An object which holds file descripters to be checked for read/write
+      ## status.
+      fds: TTable[TSocketHandle, PSelectorKey]
+
+  proc register*(s: PSelector, fd: TSocketHandle, events: set[TEvent],
+                 data: PObject): PSelectorKey {.discardable.} =
+    ## Registers file descriptor ``fd`` to selector ``s`` with a set of TEvent
+    ## ``events``.
+
+  proc update*(s: PSelector, fd: TSocketHandle,
+               events: set[TEvent]): PSelectorKey {.discardable.} =
+    ## Updates the events which ``fd`` wants notifications for.
+
+  proc select*(s: PSelector, timeout: int): seq[TReadyInfo] =
+    ## The ``events`` field of the returned ``key`` contains the original events
+    ## for which the ``fd`` was bound. This is contrary to the ``events`` field
+    ## of the ``TReadyInfo`` tuple which determines which events are ready
+    ## on the ``fd``.
+
+  proc contains*(s: PSelector, fd: TSocketHandle): bool =
+    ## Determines whether selector contains a file descriptor.
+
+  proc `[]`*(s: PSelector, fd: TSocketHandle): PSelectorKey =
+    ## Retrieves the selector key for ``fd``.
+
+
+elif defined(linux):
   type
     PSelector* = ref object
       epollFD: cint
@@ -49,9 +81,10 @@ when defined(linux) or defined(nimdoc):
     ## Registers file descriptor ``fd`` to selector ``s`` with a set of TEvent
     ## ``events``.
     var event = createEventStruct(events, fd)
-    if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fd, addr(event)) != 0:
-      OSError(OSLastError())
-  
+    if events != {}:
+      if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fd, addr(event)) != 0:
+        OSError(OSLastError())
+
     var key = PSelectorKey(fd: fd, events: events, data: data)
   
     s.fds[fd] = key
@@ -61,11 +94,27 @@ when defined(linux) or defined(nimdoc):
       events: set[TEvent]): PSelectorKey {.discardable.} =
     ## Updates the events which ``fd`` wants notifications for.
     if s.fds[fd].events != events:
-      var event = createEventStruct(events, fd)
+      if events == {}:
+        # This fd is idle -- it should not be registered to epoll.
+        # But it should remain a part of this selector instance.
+        # This is to prevent epoll_wait from returning immediately
+        # because its got fds which are waiting for no events and
+        # are therefore constantly ready. (leading to 100% CPU usage).
+        if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fd, nil) != 0:
+          OSError(OSLastError())
+        s.fds[fd].events = events
+      else:
+        var event = createEventStruct(events, fd)
+        if s.fds[fd].events == {}:
+          # This fd is idle. It's not a member of this epoll instance and must
+          # be re-registered.
+          if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fd, addr(event)) != 0:
+            OSError(OSLastError())
+        else:
+          if epoll_ctl(s.epollFD, EPOLL_CTL_MOD, fd, addr(event)) != 0:
+            OSError(OSLastError())
+        s.fds[fd].events = events
       
-      s.fds[fd].events = events
-      if epoll_ctl(s.epollFD, EPOLL_CTL_MOD, fd, addr(event)) != 0:
-        OSError(OSLastError())
       result = s.fds[fd]
   
   proc unregister*(s: PSelector, fd: TSocketHandle): PSelectorKey {.discardable.} =
@@ -123,7 +172,10 @@ when defined(linux) or defined(nimdoc):
     ## Determines whether selector contains a file descriptor.
     if s.fds.hasKey(fd):
       # Ensure the underlying epoll instance still contains this fd.
-      result = epollHasFd(s, fd)
+      if s.fds[fd].events != {}:
+        result = epollHasFd(s, fd)
+      else:
+        result = true
     else:
       return false
 
@@ -131,7 +183,7 @@ when defined(linux) or defined(nimdoc):
     ## Retrieves the selector key for ``fd``.
     return s.fds[fd]
 
-else:
+elif not defined(nimdoc):
   # TODO: kqueue for bsd/mac os x.
   type
     PSelector* = ref object
@@ -230,7 +282,7 @@ proc contains*(s: PSelector, key: PSelectorKey): bool =
   ## the new one may have the same value.
   return key.fd in s and s.fds[key.fd] == key
 
-when isMainModule:
+when isMainModule and not defined(nimdoc):
   # Select()
   import sockets
   type
diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim
index 8d96cbaaf..7b8b3d557 100644
--- a/lib/pure/sockets.nim
+++ b/lib/pure/sockets.nim
@@ -295,7 +295,7 @@ when defined(ssl):
     of protSSLv23:
       newCTX = SSL_CTX_new(SSLv23_method()) # SSlv2,3 and TLS1 support.
     of protSSLv2:
-      when not defined(linux):
+      when not defined(linux) and not defined(OpenBSD):
         newCTX = SSL_CTX_new(SSLv2_method())
       else:
         SSLError()
diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim
index 2d33965e3..5111bc3cf 100644
--- a/lib/system/ansi_c.nim
+++ b/lib/system/ansi_c.nim
@@ -57,6 +57,7 @@ when not defined(SIGINT):
         SIGINT = cint(2)
         SIGSEGV = cint(11)
         SIGTERM = cint(15)
+        SIGPIPE = cint(13)
     else:
       {.error: "SIGABRT not ported to your platform".}
   else:
@@ -66,6 +67,8 @@ when not defined(SIGINT):
       SIGABRT {.importc: "SIGABRT", nodecl.}: cint
       SIGFPE {.importc: "SIGFPE", nodecl.}: cint
       SIGILL {.importc: "SIGILL", nodecl.}: cint
+    when defined(macosx) or defined(linux):
+      var SIGPIPE {.importc: "SIGPIPE", nodecl.}: cint
 
 when defined(macosx):
   when NoFakeVars:
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim
index 2dc134eaf..63a61183f 100644
--- a/lib/system/excpt.nim
+++ b/lib/system/excpt.nim
@@ -298,7 +298,13 @@ when not defined(noSignalHandler):
       elif s == SIGILL: action("SIGILL: Illegal operation.\n")
       elif s == SIGBUS: 
         action("SIGBUS: Illegal storage access. (Attempt to read from nil?)\n")
-      else: action("unknown signal\n")
+      else:
+        block platformSpecificSignal:
+          when defined(SIGPIPE):
+            if s == SIGPIPE:
+              action("SIGPIPE: Pipe closed.\n")
+              break platformSpecificSignal
+          action("unknown signal\n")
 
     # print stack trace and quit
     when hasSomeStackTrace:
@@ -323,6 +329,8 @@ when not defined(noSignalHandler):
     c_signal(SIGFPE, signalHandler)
     c_signal(SIGILL, signalHandler)
     c_signal(SIGBUS, signalHandler)
+    when defined(SIGPIPE):
+      c_signal(SIGPIPE, signalHandler)
 
   registerSignalHandler() # call it in initialization section
 
diff --git a/lib/system/sets.nim b/lib/system/sets.nim
index 043d37533..794c65cb8 100644
--- a/lib/system/sets.nim
+++ b/lib/system/sets.nim
@@ -10,7 +10,7 @@
 # set handling
 
 type
-  TNimSet = array [0..4*2048-1, int8]
+  TNimSet = array [0..4*2048-1, uint8]
 
 proc countBits32(n: int32): int {.compilerproc.} =
   var v = n
@@ -25,4 +25,4 @@ proc countBits64(n: int64): int {.compilerproc.} =
 proc cardSet(s: TNimSet, len: int): int {.compilerproc.} =
   result = 0
   for i in countup(0, len-1):
-    inc(result, countBits32(int32(ze(s[i]))))
+    inc(result, countBits32(int32(s[i])))
diff --git a/lib/windows/windows.nim b/lib/windows/windows.nim
index dd743ffa4..df6ad954b 100644
--- a/lib/windows/windows.nim
+++ b/lib/windows/windows.nim
@@ -62,7 +62,7 @@ type  # BaseTsd.h -- Type definitions for the basic sized types
 

 type  # WinDef.h -- Basic Windows Type Definitions

   # BaseTypes

-  UINT = int32
+  WINUINT* = int32

   ULONG* = int

   PULONG* = ptr int

   USHORT* = int16

@@ -137,7 +137,7 @@ type  # WinDef.h -- Basic Windows Type Definitions
 

   HFILE* = HANDLE

   HCURSOR* = HANDLE # = HICON

-  COLORREF* = int

+  COLORREF* = DWORD

   LPCOLORREF* = ptr COLORREF

 

   POINT* {.final, pure.} = object

@@ -238,7 +238,7 @@ type
   CALTYPE* = int

   CALID* = int

   CCHAR* = char

-  TCOLORREF* = int

+  TCOLORREF* = COLORREF

   WINT* = int32

   PINTEGER* = ptr int32

   PBOOL* = ptr WINBOOL

@@ -19683,7 +19683,7 @@ proc SetSysColors*(cElements: int32, lpaElements: var wINT,
     dynlib: "user32", importc: "SetSysColors".}

 proc DrawFocusRect*(hDC: HDC, lprc: var RECT): WINBOOL{.stdcall,

     dynlib: "user32", importc: "DrawFocusRect".}

-proc FillRect*(hDC: HDC, lprc: RECT, hbr: HBRUSH): int32{.stdcall,

+proc FillRect*(hDC: HDC, lprc: var RECT, hbr: HBRUSH): int32{.stdcall,

     dynlib: "user32", importc: "FillRect".}

 proc FrameRect*(hDC: HDC, lprc: var RECT, hbr: HBRUSH): int32{.stdcall,

     dynlib: "user32", importc: "FrameRect".}

@@ -22758,12 +22758,12 @@ proc LocalDiscard*(hlocMem: HLOCAL): HLOCAL =
 

 # WinGDI.h

 

-proc GetGValue*(rgb: int32): int8 =

-  result = toU8(rgb shr 8'i32)

+discard """proc GetGValue*(rgb: int32): int8 =

+  result = toU8(rgb shr 8'i32)"""

 proc RGB*(r, g, b: int): COLORREF =

   result = toU32(r) or (toU32(g) shl 8) or (toU32(b) shl 16)

 proc RGB*(r, g, b: range[0 .. 255]): COLORREF =

-  result = r or g shl 8 or b shl 16

+  result = toU32(r) or (toU32(g) shl 8) or (toU32(b) shl 16)

 

 proc PALETTERGB*(r, g, b: range[0..255]): COLORREF =

   result = 0x02000000 or RGB(r, g, b)

@@ -23481,7 +23481,7 @@ proc ListView_EnsureVisible(hwndLV: HWND, i, fPartialOK: int32): LRESULT =
                        MAKELPARAM(fPartialOK, 0))

 

 proc ListView_FindItem(wnd: HWND, iStart: int32, lvfi: var LV_FINDINFO): int32 =

-  result = SendMessage(wnd, LVM_FINDITEM, WPARAM(iStart), 
+  result = SendMessage(wnd, LVM_FINDITEM, WPARAM(iStart), 

                        cast[LPARAM](addr(lvfi))).int32

 

 proc ListView_GetBkColor(wnd: HWND): LRESULT =

diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim
index 90c398dce..bbcb2175e 100644
--- a/lib/wrappers/openssl.nim
+++ b/lib/wrappers/openssl.nim
@@ -270,7 +270,7 @@ proc OPENSSL_config*(configName: cstring){.cdecl, dynlib: DLLSSLName, importc.}
 
 when not defined(windows):
   proc CRYPTO_set_mem_functions(a,b,c: pointer){.cdecl, 
-    dynlib: DLLSSLName, importc.}
+    dynlib: DLLUtilName, importc.}
 
 proc CRYPTO_malloc_init*() =
   when not defined(windows):
diff --git a/tests/async/tasyncawait.nim b/tests/async/tasyncawait.nim
index ffceeaee6..da4952677 100644
--- a/tests/async/tasyncawait.nim
+++ b/tests/async/tasyncawait.nim
@@ -23,19 +23,19 @@ proc launchSwarm(port: TPort) {.async.} =
     await connect(sock, "localhost", port)
     when true:
       await sendMessages(sock)
-      close(sock)
+      closeSocket(sock)
     else:
       # Issue #932: https://github.com/Araq/Nimrod/issues/932
       var msgFut = sendMessages(sock)
       msgFut.callback =
         proc () =
-          close(sock)
+          closeSocket(sock)
 
 proc readMessages(client: TAsyncFD) {.async.} =
   while true:
     var line = await recvLine(client)
     if line == "":
-      close(client)
+      closeSocket(client)
       clientCount.inc
       break
     else:
diff --git a/tests/ccgbugs/tbug1081.nim b/tests/ccgbugs/tbug1081.nim
new file mode 100644
index 000000000..71628feec
--- /dev/null
+++ b/tests/ccgbugs/tbug1081.nim
@@ -0,0 +1,17 @@
+discard """
+  output: '''1
+0
+0
+0'''
+"""
+
+proc `1/1`() = echo(1 div 1)
+template `1/2`() = echo(1 div 2)
+var `1/3` = 1 div 4
+`1/3` = 1 div 3 # oops, 1/3!=1/4
+let `1/4` = 1 div 4
+
+`1/1`()
+`1/2`()
+echo `1/3`
+echo `1/4`