summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAman Gupta <aman@tmm1.net>2015-10-06 11:06:41 -0700
committerAman Gupta <aman@tmm1.net>2015-10-06 11:06:41 -0700
commiteea8d604d07aae569843ebccc5bd7791cff40567 (patch)
treedbb652a24acbf0dfd28e2921f72b0d92fe4a858d
parenta01fd5e93f58a2bf9dea4f577218b8ff7d874bbf (diff)
parent2e413d3186455bf92ee9bae04304cb34cf1f2557 (diff)
downloadNim-eea8d604d07aae569843ebccc5bd7791cff40567.tar.gz
Merge remote-tracking branch 'origin/devel' into fix-test-failures
-rwxr-xr-xbootstrap.sh7
-rw-r--r--compiler/ccgexprs.nim68
-rw-r--r--compiler/installer.ini3
-rw-r--r--compiler/magicsys.nim38
-rw-r--r--compiler/modules.nim7
-rw-r--r--compiler/pragmas.nim18
-rw-r--r--compiler/vm.nim25
-rw-r--r--compiler/wordrecg.nim5
-rw-r--r--config/nim.cfg2
-rw-r--r--doc/lib.txt38
-rw-r--r--doc/manual/types.txt5
-rw-r--r--install.sh.template9
-rw-r--r--koch.nim9
-rw-r--r--lib/deprecated/core/unsigned.nim (renamed from lib/core/unsigned.nim)0
-rw-r--r--lib/deprecated/pure/actors.nim (renamed from lib/pure/actors.nim)0
-rw-r--r--lib/deprecated/pure/actors.nim.cfg (renamed from lib/pure/actors.nim.cfg)0
-rw-r--r--lib/deprecated/pure/asyncio.nim (renamed from lib/pure/asyncio.nim)0
-rw-r--r--lib/deprecated/pure/ftpclient.nim (renamed from lib/pure/ftpclient.nim)4
-rw-r--r--lib/deprecated/pure/parseopt.nim (renamed from lib/pure/parseopt.nim)0
-rw-r--r--lib/deprecated/pure/parseurl.nim (renamed from lib/pure/parseurl.nim)0
-rw-r--r--lib/deprecated/pure/rawsockets.nim14
-rw-r--r--lib/deprecated/pure/sockets.nim (renamed from lib/pure/sockets.nim)2
-rw-r--r--lib/pure/asyncdispatch.nim34
-rw-r--r--lib/pure/asyncnet.nim11
-rw-r--r--lib/pure/collections/critbits.nim8
-rw-r--r--lib/pure/httpclient.nim8
-rw-r--r--lib/pure/nativesockets.nim (renamed from lib/pure/rawsockets.nim)50
-rw-r--r--lib/pure/net.nim8
-rw-r--r--lib/pure/rationals.nim62
-rw-r--r--lib/pure/strtabs.nim6
-rw-r--r--lib/pure/strutils.nim22
-rw-r--r--lib/system/nimscript.nim3
-rw-r--r--lib/windows/winlean.nim2
-rw-r--r--tests/async/tasyncawait.nim6
-rw-r--r--tests/async/tasyncconnect.nim2
-rw-r--r--tests/async/tasynceverror.nim4
-rw-r--r--tests/ccgbugs/twrong_discriminant_check.nim30
-rw-r--r--tests/cpp/tnativesockets.nim (renamed from tests/cpp/trawsockets.nim)2
-rw-r--r--tests/macros/tgensym.nim4
-rw-r--r--tests/modules/texport.nim2
-rw-r--r--web/news.txt3
41 files changed, 358 insertions, 163 deletions
diff --git a/bootstrap.sh b/bootstrap.sh
index ade74a9aa..7f19c2440 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -12,8 +12,11 @@ cd ".."
 
 ./bin/nim c koch
 ./koch boot -d:release
+./koch geninstall
 
-cp -f install.sh.template install.sh
-chmod +x install.sh
+set +x
+
+echo
+echo 'Install Nim using "./install.sh <dir>" or "sudo ./install.sh <dir>".'
 
 exit 0
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 32fc76470..6d69dafa5 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -747,6 +747,17 @@ proc genTupleElem(p: BProc, e: PNode, d: var TLoc) =
   addf(r, ".Field$1", [rope(i)])
   putIntoDest(p, d, ty.sons[i], r, a.s)
 
+proc lookupFieldAgain(p: BProc, ty: PType; field: PSym; r: var Rope): PSym =
+  var ty = ty
+  assert r != nil
+  while ty != nil:
+    assert(ty.kind in {tyTuple, tyObject})
+    result = lookupInRecord(ty.n, field.name)
+    if result != nil: break
+    if not p.module.compileToCpp: add(r, ".Sup")
+    ty = getUniqueType(ty.sons[0])
+  if result == nil: internalError(field.info, "genCheckedRecordField")
+
 proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
   var a: TLoc
   var ty = genRecordFieldAux(p, e, d, a)
@@ -758,15 +769,7 @@ proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
     addf(r, ".Field$1", [rope(f.position)])
     putIntoDest(p, d, f.typ, r, a.s)
   else:
-    var field: PSym = nil
-    while ty != nil:
-      if ty.kind notin {tyTuple, tyObject}:
-        internalError(e.info, "genRecordField")
-      field = lookupInRecord(ty.n, f.name)
-      if field != nil: break
-      if not p.module.compileToCpp: add(r, ".Sup")
-      ty = getUniqueType(ty.sons[0])
-    if field == nil: internalError(e.info, "genRecordField 2 ")
+    let field = lookupFieldAgain(p, ty, f, r)
     if field.loc.r == nil: internalError(e.info, "genRecordField 3")
     addf(r, ".$1", [field.loc.r])
     putIntoDest(p, d, field.typ, r, a.s)
@@ -774,7 +777,8 @@ proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
 
 proc genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc)
 
-proc genFieldCheck(p: BProc, e: PNode, obj: Rope, field: PSym) =
+proc genFieldCheck(p: BProc, e: PNode, obj: Rope, field: PSym;
+                   origTy: PType) =
   var test, u, v: TLoc
   for i in countup(1, sonsLen(e) - 1):
     var it = e.sons[i]
@@ -786,8 +790,12 @@ proc genFieldCheck(p: BProc, e: PNode, obj: Rope, field: PSym) =
     assert(disc.kind == nkSym)
     initLoc(test, locNone, it.typ, OnStack)
     initLocExpr(p, it.sons[1], u)
-    initLoc(v, locExpr, disc.typ, OnUnknown)
-    v.r = "$1.$2" % [obj, disc.sym.loc.r]
+    var o = obj
+    let d = lookupFieldAgain(p, origTy, disc.sym, o)
+    initLoc(v, locExpr, d.typ, OnUnknown)
+    v.r = o
+    v.r.add(".")
+    v.r.add(d.loc.r)
     genInExprAux(p, it, u, v, test)
     let id = nodeTableTestOrSet(p.module.dataCache,
                                newStrNode(nkStrLit, field.name.s), gBackendId)
@@ -804,25 +812,14 @@ proc genFieldCheck(p: BProc, e: PNode, obj: Rope, field: PSym) =
 
 proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
   if optFieldCheck in p.options:
-    var
-      a: TLoc
-      f, field: PSym
-      ty: PType
-      r: Rope
-    ty = genRecordFieldAux(p, e.sons[0], d, a)
-    r = rdLoc(a)
-    f = e.sons[0].sons[1].sym
-    field = nil
-    while ty != nil:
-      assert(ty.kind in {tyTuple, tyObject})
-      field = lookupInRecord(ty.n, f.name)
-      if field != nil: break
-      if not p.module.compileToCpp: add(r, ".Sup")
-      ty = getUniqueType(ty.sons[0])
-    if field == nil: internalError(e.info, "genCheckedRecordField")
+    var a: TLoc
+    let ty = genRecordFieldAux(p, e.sons[0], d, a)
+    var r = rdLoc(a)
+    let f = e.sons[0].sons[1].sym
+    let field = lookupFieldAgain(p, ty, f, r)
     if field.loc.r == nil:
       internalError(e.info, "genCheckedRecordField") # generate the checks:
-    genFieldCheck(p, e, r, field)
+    genFieldCheck(p, e, r, field, ty)
     add(r, rfmt(nil, ".$1", field.loc.r))
     putIntoDest(p, d, field.typ, r, a.s)
   else:
@@ -1150,20 +1147,15 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
   else:
     constructLoc(p, tmp)
   discard getTypeDesc(p.module, t)
+  let ty = getUniqueType(t)
   for i in 1 .. <e.len:
     let it = e.sons[i]
     var tmp2: TLoc
     tmp2.r = r
-    var field: PSym = nil
-    var ty = getUniqueType(t)
-    while ty != nil:
-      field = lookupInRecord(ty.n, it.sons[0].sym.name)
-      if field != nil: break
-      if not p.module.compileToCpp: add(tmp2.r, ".Sup")
-      ty = getUniqueType(ty.sons[0])
-    if field == nil or field.loc.r == nil: internalError(e.info, "genObjConstr")
+    let field = lookupFieldAgain(p, ty, it.sons[0].sym, tmp2.r)
+    if field.loc.r == nil: internalError(e.info, "genObjConstr")
     if it.len == 3 and optFieldCheck in p.options:
-      genFieldCheck(p, it.sons[2], tmp2.r, field)
+      genFieldCheck(p, it.sons[2], tmp2.r, field, ty)
     add(tmp2.r, ".")
     add(tmp2.r, field.loc.r)
     tmp2.k = locTemp
diff --git a/compiler/installer.ini b/compiler/installer.ini
index c8af38886..729c13503 100644
--- a/compiler/installer.ini
+++ b/compiler/installer.ini
@@ -115,6 +115,9 @@ Files: "lib/posix/*.nim"
 Files: "lib/js/*.nim"
 Files: "lib/packages/docutils/*.nim"
 
+Files: "lib/deprecated/core/*.nim"
+Files: "lib/deprecated/pure/*.nim"
+Files: "lib/deprecated/pure/*.cfg"
 
 [Other]
 Files: "examples/*.nim"
diff --git a/compiler/magicsys.nim b/compiler/magicsys.nim
index 98a4b08bf..40e0728ae 100644
--- a/compiler/magicsys.nim
+++ b/compiler/magicsys.nim
@@ -14,22 +14,14 @@ import
 
 var systemModule*: PSym
 
-proc registerSysType*(t: PType)
-  # magic symbols in the system module:
-proc getSysType*(kind: TTypeKind): PType
-proc getCompilerProc*(name: string): PSym
-proc registerCompilerProc*(s: PSym)
-proc finishSystem*(tab: TStrTable)
-proc getSysSym*(name: string): PSym
-# implementation
-
 var
   gSysTypes: array[TTypeKind, PType]
   compilerprocs: TStrTable
+  exposed: TStrTable
 
 proc nilOrSysInt*: PType = gSysTypes[tyInt]
 
-proc registerSysType(t: PType) =
+proc registerSysType*(t: PType) =
   if gSysTypes[t.kind] == nil: gSysTypes[t.kind] = t
 
 proc newSysType(kind: TTypeKind, size: int): PType =
@@ -37,7 +29,7 @@ proc newSysType(kind: TTypeKind, size: int): PType =
   result.size = size
   result.align = size.int16
 
-proc getSysSym(name: string): PSym =
+proc getSysSym*(name: string): PSym =
   result = strTableGet(systemModule.tab, getIdent(name))
   if result == nil:
     rawMessage(errSystemNeeds, name)
@@ -61,7 +53,7 @@ proc getSysMagic*(name: string, m: TMagic): PSym =
 proc sysTypeFromName*(name: string): PType =
   result = getSysSym(name).typ
 
-proc getSysType(kind: TTypeKind): PType =
+proc getSysType*(kind: TTypeKind): PType =
   result = gSysTypes[kind]
   if result == nil:
     case kind
@@ -97,6 +89,7 @@ var
 proc resetSysTypes* =
   systemModule = nil
   initStrTable(compilerprocs)
+  initStrTable(exposed)
   for i in low(gSysTypes)..high(gSysTypes):
     gSysTypes[i] = nil
 
@@ -163,8 +156,8 @@ proc setIntLitType*(result: PNode) =
       result.typ = getSysType(tyInt64)
   else: internalError(result.info, "invalid int size")
 
-proc getCompilerProc(name: string): PSym =
-  var ident = getIdent(name, hashIgnoreStyle(name))
+proc getCompilerProc*(name: string): PSym =
+  let ident = getIdent(name)
   result = strTableGet(compilerprocs, ident)
   if result == nil:
     result = strTableGet(rodCompilerprocs, ident)
@@ -173,9 +166,22 @@ proc getCompilerProc(name: string): PSym =
       if result.kind == skStub: loadStub(result)
       if result.kind == skAlias: result = result.owner
 
-proc registerCompilerProc(s: PSym) =
+proc registerCompilerProc*(s: PSym) =
   strTableAdd(compilerprocs, s)
 
-proc finishSystem(tab: TStrTable) = discard
+proc registerNimScriptSymbol*(s: PSym) =
+  # Nimscript symbols must be al unique:
+  let conflict = strTableGet(exposed, s.name)
+  if conflict == nil:
+    strTableAdd(exposed, s)
+  else:
+    localError(s.info, "symbol conflicts with other .exportNims symbol at: " &
+      $conflict.info)
+
+proc getNimScriptSymbol*(name: string): PSym =
+  strTableGet(exposed, getIdent(name))
+
+proc resetNimScriptSymbols*() = initStrTable(exposed)
 
 initStrTable(compilerprocs)
+initStrTable(exposed)
diff --git a/compiler/modules.nim b/compiler/modules.nim
index 85c99c4ec..3893d377e 100644
--- a/compiler/modules.nim
+++ b/compiler/modules.nim
@@ -78,6 +78,13 @@ proc resetModule*(fileIdx: int32) =
   if fileIdx <% cgendata.gModules.len:
     cgendata.gModules[fileIdx] = nil
 
+proc resetModule*(module: PSym) =
+  let conflict = getModule(module.position.int32)
+  if conflict == nil: return
+  doAssert conflict == module
+  resetModule(module.position.int32)
+  initStrTable(module.tab)
+
 proc resetAllModules* =
   for i in 0..gCompiledModules.high:
     if gCompiledModules[i] != nil:
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index ba05b2792..79d7884fa 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -25,18 +25,19 @@ const
     wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
     wAsmNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wCodegenDecl,
     wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe,
-    wOverride, wConstructor}
+    wOverride, wConstructor, wExportNims}
   converterPragmas* = procPragmas
   methodPragmas* = procPragmas+{wBase}
   templatePragmas* = {wImmediate, wDeprecated, wError, wGensym, wInject, wDirty,
-    wDelegator}
+    wDelegator, wExportNims}
   macroPragmas* = {FirstCallConv..LastCallConv, wImmediate, wImportc, wExportc,
     wNodecl, wMagic, wNosideeffect, wCompilerproc, wDeprecated, wExtern,
-    wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wDelegator}
+    wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wDelegator,
+    wExportNims}
   iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideeffect, wSideeffect,
     wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern,
     wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wRaises,
-    wTags, wLocks, wGcSafe}
+    wTags, wLocks, wGcSafe, wExportNims}
   exprPragmas* = {wLine, wLocks, wNoRewrite}
   stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks,
     wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
@@ -54,15 +55,15 @@ const
     wPure, wHeader, wCompilerproc, wFinal, wSize, wExtern, wShallow,
     wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef,
     wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked,
-    wBorrow, wGcSafe}
+    wBorrow, wGcSafe, wExportNims}
   fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern,
     wImportCpp, wImportObjC, wError, wGuard, wBitsize}
   varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl,
     wMagic, wHeader, wDeprecated, wCompilerproc, wDynlib, wExtern,
     wImportCpp, wImportObjC, wError, wNoInit, wCompileTime, wGlobal,
-    wGensym, wInject, wCodegenDecl, wGuard, wGoto}
+    wGensym, wInject, wCodegenDecl, wGuard, wGoto, wExportNims}
   constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl,
-    wExtern, wImportCpp, wImportObjC, wError, wGensym, wInject}
+    wExtern, wImportCpp, wImportObjC, wError, wGensym, wInject, wExportNims}
   letPragmas* = varPragmas
   procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideeffect,
                       wThread, wRaises, wLocks, wTags, wGcSafe}
@@ -859,6 +860,9 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
           invalidPragma(it)
         else:
           sym.flags.incl sfGoto
+      of wExportNims:
+        if sym == nil: invalidPragma(it)
+        else: magicsys.registerNimScriptSymbol(sym)
       of wInjectStmt:
         if it.kind != nkExprColonExpr:
           localError(it.info, errExprExpected)
diff --git a/compiler/vm.nim b/compiler/vm.nim
index ad4aa1017..ded66d3d0 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -1411,6 +1411,31 @@ proc execute(c: PCtx, start: int): PNode =
   newSeq(tos.slots, c.prc.maxSlots)
   result = rawExecute(c, start, tos).regToNode
 
+proc execProc*(c: PCtx; sym: PSym; args: openArray[PNode]): PNode =
+  if sym.kind in routineKinds:
+    if sym.typ.len-1 != args.len:
+      localError(sym.info,
+        "NimScript: expected $# arguments, but got $#" % [
+        $(sym.typ.len-1), $args.len])
+    else:
+      let start = genProc(c, sym)
+
+      var tos = PStackFrame(prc: sym, comesFrom: 0, next: nil)
+      let maxSlots = sym.offset
+      newSeq(tos.slots, maxSlots)
+
+      # setup parameters:
+      if not isEmptyType(sym.typ.sons[0]) or sym.kind == skMacro:
+        putIntoReg(tos.slots[0], getNullValue(sym.typ.sons[0], sym.info))
+      # XXX We could perform some type checking here.
+      for i in 1.. <sym.typ.len:
+        putIntoReg(tos.slots[i], args[i-1])
+
+      result = rawExecute(c, start, tos).regToNode
+  else:
+    localError(sym.info,
+      "NimScript: attempt to call non-routine: " & sym.name.s)
+
 proc evalStmt*(c: PCtx, n: PNode) =
   let n = transformExpr(c.module, n)
   let start = genStmt(c, n)
diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim
index d1e5438f3..0a0534118 100644
--- a/compiler/wordrecg.nim
+++ b/compiler/wordrecg.nim
@@ -42,7 +42,7 @@ type
     wImmediate, wConstructor, wDestructor, wDelegator, wOverride,
     wImportCpp, wImportObjC,
     wImportCompilerProc,
-    wImportc, wExportc, wIncompleteStruct, wRequiresInit,
+    wImportc, wExportc, wExportNims, wIncompleteStruct, wRequiresInit,
     wAlign, wNodecl, wPure, wSideeffect, wHeader,
     wNosideeffect, wGcSafe, wNoreturn, wMerge, wLib, wDynlib,
     wCompilerproc, wProcVar, wBase,
@@ -126,7 +126,8 @@ const
 
     "immediate", "constructor", "destructor", "delegator", "override",
     "importcpp", "importobjc",
-    "importcompilerproc", "importc", "exportc", "incompletestruct",
+    "importcompilerproc", "importc", "exportc", "exportnims",
+    "incompletestruct",
     "requiresinit", "align", "nodecl", "pure", "sideeffect",
     "header", "nosideeffect", "gcsafe", "noreturn", "merge", "lib", "dynlib",
     "compilerproc", "procvar", "base",
diff --git a/config/nim.cfg b/config/nim.cfg
index bf78c35cc..b8608b3ce 100644
--- a/config/nim.cfg
+++ b/config/nim.cfg
@@ -27,6 +27,8 @@ mips.linux.gcc.linkerexe = "mips-openwrt-linux-gcc"
   cs:partial
 @end
 
+path="$lib/deprecated/core"
+path="$lib/deprecated/pure"
 path="$lib/pure/collections"
 path="$lib/pure/concurrency"
 path="$lib/impure"
diff --git a/doc/lib.txt b/doc/lib.txt
index 868adde89..3dc58eebf 100644
--- a/doc/lib.txt
+++ b/doc/lib.txt
@@ -201,12 +201,6 @@ Internet Protocols and Support
 * `scgi <scgi.html>`_
   This module implements helpers for SCGI applications.
 
-* `sockets <sockets.html>`_
-  This module implements a simple portable type-safe sockets layer.
-
-* `asyncio <asyncio.html>`_
-  This module implements an asynchronous event loop for sockets.
-
 * `browsers <browsers.html>`_
   This module implements procs for opening URLs with the user's default
   browser.
@@ -220,9 +214,6 @@ Internet Protocols and Support
 * `smtp <smtp.html>`_
   This module implement a simple SMTP client.
 
-* `ftpclient <ftpclient.html>`_
-  This module implements an FTP client.
-
 * `cookies <cookies.html>`_
   This module contains helper procs for parsing and generating cookies.
 
@@ -253,7 +244,7 @@ Internet Protocols and Support
   This module implements a high-level sockets API. It will replace the
   ``sockets`` module in the future.
 
-* `rawsockets <rawsockets.html>`_
+* `nativesockets <nativesockets.html>`_
   This module implements a low-level sockets API.
 
 * `selectors <selectors.html>`_
@@ -265,8 +256,6 @@ Parsers
 
 * `parseopt <parseopt.html>`_
   The ``parseopt`` module implements a command line option parser.
-  **Deprecated since version 0.9.3:** Use the `parseopt2
-  <parseopt2.html>`_ module instead.
 
 * `parseopt2 <parseopt2.html>`_
   The ``parseopt2`` module implements a command line option parser. This
@@ -397,6 +386,31 @@ Modules for JS backend
   Declaration of the Document Object Model for the JS backend.
 
 
+Deprecated modules
+------------------
+
+* `asyncio <asyncio.html>`_
+  This module implements an asynchronous event loop for sockets.
+  **Deprecated since version 0.11.2:**
+  Use the `asyncnet <asyncnet.html>`_ together with the
+  `asyncdispatch <asyncdispatch.html>`_ module instead.
+
+* `ftpclient <ftpclient.html>`_
+  This module implements an FTP client.
+  **Deprecated since version 0.11.3:**
+  Use the `asyncftpclient <asyncftpclient.html>`_ module instead.
+
+* `sockets <sockets.html>`_
+  This module implements a simple portable type-safe sockets layer.
+  **Deprecated since version 0.11.2:**
+  Use the `net <net.html>`_ or the `rawsockets <rawsockets.html>`_ module
+  instead.
+
+* `rawsockets <rawsockets.html>`_
+  **Deprecated since version 0.11.4:**
+  This module has been renamed to `nativesockets <nativesockets.html>`_.
+
+
 Impure libraries
 ================
 
diff --git a/doc/manual/types.txt b/doc/manual/types.txt
index c9ac6f062..babf3286f 100644
--- a/doc/manual/types.txt
+++ b/doc/manual/types.txt
@@ -490,6 +490,11 @@ to an open array parameter.
 The openarray type cannot be nested: multidimensional openarrays are not
 supported because this is seldom needed and cannot be done efficiently.
 
+.. code-block:: nim
+  proc testOpenArray(x: openArray[int]) = echo repr(x)
+
+  testOpenArray([1,2,3])  # array[]
+  testOpenArray(@[1,2,3]) # seq[]
 
 Varargs
 -------
diff --git a/install.sh.template b/install.sh.template
deleted file mode 100644
index 1292abdab..000000000
--- a/install.sh.template
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-set -e
-set -x
-
-if [ "$1" != "" ]; then
-	exec ./koch install "$1"
-else
-	exec ./koch install
-fi
diff --git a/koch.nim b/koch.nim
index 8992271bf..3d1a22b9c 100644
--- a/koch.nim
+++ b/koch.nim
@@ -41,6 +41,7 @@ Options:
 Possible Commands:
   boot [options]           bootstraps with given command line options
   install [bindir]         installs to given directory; Unix only!
+  geninstall               generate ./install.sh; Unix only!
   clean                    cleans Nim project; removes generated files
   web [options]            generates the website and the full documentation
   website [options]        generates only the website
@@ -127,9 +128,12 @@ proc nsis(args: string) =
   exec(("tools" / "niminst" / "niminst --var:version=$# --var:mingw=mingw$#" &
         " nsis compiler/installer.ini") % [VersionAsString, $(sizeof(pointer)*8)])
 
+proc geninstall(args="") =
+  exec("$# cc -r $# --var:version=$# --var:mingw=none --main:compiler/nim.nim scripts compiler/installer.ini $#" %
+       [findNim(), compileNimInst, VersionAsString, args])
+
 proc install(args: string) =
-  exec("$# cc -r $# --var:version=$# --var:mingw=none --main:compiler/nim.nim scripts compiler/installer.ini" %
-       [findNim(), compileNimInst, VersionAsString])
+  geninstall()
   exec("sh ./install.sh $#" % args)
 
 proc web(args: string) =
@@ -373,6 +377,7 @@ of cmdArgument:
   of "zip": zip(op.cmdLineRest)
   of "xz": xz(op.cmdLineRest)
   of "nsis": nsis(op.cmdLineRest)
+  of "geninstall": geninstall(op.cmdLineRest)
   of "install": install(op.cmdLineRest)
   of "test", "tests": tests(op.cmdLineRest)
   of "update":
diff --git a/lib/core/unsigned.nim b/lib/deprecated/core/unsigned.nim
index 93a29e1c9..93a29e1c9 100644
--- a/lib/core/unsigned.nim
+++ b/lib/deprecated/core/unsigned.nim
diff --git a/lib/pure/actors.nim b/lib/deprecated/pure/actors.nim
index f0791f954..f0791f954 100644
--- a/lib/pure/actors.nim
+++ b/lib/deprecated/pure/actors.nim
diff --git a/lib/pure/actors.nim.cfg b/lib/deprecated/pure/actors.nim.cfg
index c6bb9c545..c6bb9c545 100644
--- a/lib/pure/actors.nim.cfg
+++ b/lib/deprecated/pure/actors.nim.cfg
diff --git a/lib/pure/asyncio.nim b/lib/deprecated/pure/asyncio.nim
index 5fd45b215..5fd45b215 100644
--- a/lib/pure/asyncio.nim
+++ b/lib/deprecated/pure/asyncio.nim
diff --git a/lib/pure/ftpclient.nim b/lib/deprecated/pure/ftpclient.nim
index 229fe4b51..1188c0795 100644
--- a/lib/pure/ftpclient.nim
+++ b/lib/deprecated/pure/ftpclient.nim
@@ -11,7 +11,7 @@ include "system/inclrtl"
 import sockets, strutils, parseutils, times, os, asyncio
 
 from asyncnet import nil
-from rawsockets import nil
+from nativesockets import nil
 from asyncdispatch import PFuture
 ## **Note**: This module is deprecated since version 0.11.3.
 ## You should use the async version of this module
@@ -55,7 +55,7 @@ type
     user*, pass*: string
     address*: string
     when SockType is asyncnet.AsyncSocket:
-      port*: rawsockets.Port
+      port*: nativesockets.Port
     else:
       port*: Port
 
diff --git a/lib/pure/parseopt.nim b/lib/deprecated/pure/parseopt.nim
index 218f5ab81..218f5ab81 100644
--- a/lib/pure/parseopt.nim
+++ b/lib/deprecated/pure/parseopt.nim
diff --git a/lib/pure/parseurl.nim b/lib/deprecated/pure/parseurl.nim
index 6d58e8a73..6d58e8a73 100644
--- a/lib/pure/parseurl.nim
+++ b/lib/deprecated/pure/parseurl.nim
diff --git a/lib/deprecated/pure/rawsockets.nim b/lib/deprecated/pure/rawsockets.nim
new file mode 100644
index 000000000..ee77b232e
--- /dev/null
+++ b/lib/deprecated/pure/rawsockets.nim
@@ -0,0 +1,14 @@
+import nativesockets
+export nativesockets
+
+{.warning: "rawsockets module is deprecated, use nativesockets instead".}
+
+template newRawSocket*(domain, sockType, protocol: cint): expr =
+  {.warning: "newRawSocket is deprecated, use newNativeSocket instead".}
+  newNativeSocket(domain, sockType, protocol)
+
+template newRawSocket*(domain: Domain = AF_INET,
+                       sockType: SockType = SOCK_STREAM,
+                       protocol: Protocol = IPPROTO_TCP): expr =
+  {.warning: "newRawSocket is deprecated, use newNativeSocket instead".}
+  newNativeSocket(domain, sockType, protocol)
diff --git a/lib/pure/sockets.nim b/lib/deprecated/pure/sockets.nim
index 8fa69256b..5d6fa0078 100644
--- a/lib/pure/sockets.nim
+++ b/lib/deprecated/pure/sockets.nim
@@ -9,7 +9,7 @@
 
 ## **Warning:** Since version 0.10.2 this module is deprecated.
 ## Use the `net <net.html>`_ or the
-## `rawsockets <rawsockets.html>`_ module instead.
+## `nativesockets <nativesockets.html>`_ module instead.
 ##
 ## This module implements portable sockets, it supports a mix of different types
 ## of sockets. Sockets are buffered by default meaning that data will be
diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim
index 110bc6d74..7bba6bd89 100644
--- a/lib/pure/asyncdispatch.nim
+++ b/lib/pure/asyncdispatch.nim
@@ -11,7 +11,7 @@ include "system/inclrtl"
 
 import os, oids, tables, strutils, macros, times
 
-import rawsockets, net
+import nativesockets, net
 
 export Port, SocketFlag
 
@@ -475,7 +475,7 @@ when defined(windows) or defined(nimdoc):
                       addr bytesRet, nil, nil) == 0
 
   proc initAll() =
-    let dummySock = newRawSocket()
+    let dummySock = newNativeSocket()
     if not initPointer(dummySock, connectExPtr, WSAID_CONNECTEX):
       raiseOSError(osLastError())
     if not initPointer(dummySock, acceptExPtr, WSAID_ACCEPTEX):
@@ -528,7 +528,7 @@ when defined(windows) or defined(nimdoc):
                   RemoteSockaddr, RemoteSockaddrLength)
 
   proc connect*(socket: AsyncFD, address: string, port: Port,
-    domain = rawsockets.AF_INET): Future[void] =
+    domain = nativesockets.AF_INET): Future[void] =
     ## Connects ``socket`` to server at ``address:port``.
     ##
     ## Returns a ``Future`` which will complete when the connection succeeds
@@ -827,7 +827,7 @@ when defined(windows) or defined(nimdoc):
     verifyPresence(socket)
     var retFuture = newFuture[tuple[address: string, client: AsyncFD]]("acceptAddr")
 
-    var clientSock = newRawSocket()
+    var clientSock = newNativeSocket()
     if clientSock == osInvalidSocket: raiseOSError(osLastError())
 
     const lpOutputLen = 1024
@@ -900,17 +900,17 @@ when defined(windows) or defined(nimdoc):
 
     return retFuture
 
-  proc newAsyncRawSocket*(domain, sockType, protocol: cint): AsyncFD =
+  proc newAsyncNativeSocket*(domain, sockType, protocol: cint): AsyncFD =
     ## Creates a new socket and registers it with the dispatcher implicitly.
-    result = newRawSocket(domain, sockType, protocol).AsyncFD
+    result = newNativeSocket(domain, sockType, protocol).AsyncFD
     result.SocketHandle.setBlocking(false)
     register(result)
 
-  proc newAsyncRawSocket*(domain: Domain = rawsockets.AF_INET,
-               sockType: SockType = SOCK_STREAM,
-               protocol: Protocol = IPPROTO_TCP): AsyncFD =
+  proc newAsyncNativeSocket*(domain: Domain = nativesockets.AF_INET,
+                             sockType: SockType = SOCK_STREAM,
+                             protocol: Protocol = IPPROTO_TCP): AsyncFD =
     ## Creates a new socket and registers it with the dispatcher implicitly.
-    result = newRawSocket(domain, sockType, protocol).AsyncFD
+    result = newNativeSocket(domain, sockType, protocol).AsyncFD
     result.SocketHandle.setBlocking(false)
     register(result)
 
@@ -973,18 +973,18 @@ else:
     var data = PData(fd: fd, readCBs: @[], writeCBs: @[])
     p.selector.register(fd.SocketHandle, {}, data.RootRef)
 
-  proc newAsyncRawSocket*(domain: cint, sockType: cint,
-      protocol: cint): AsyncFD =
-    result = newRawSocket(domain, sockType, protocol).AsyncFD
+  proc newAsyncNativeSocket*(domain: cint, sockType: cint,
+                             protocol: cint): AsyncFD =
+    result = newNativeSocket(domain, sockType, protocol).AsyncFD
     result.SocketHandle.setBlocking(false)
     when defined(macosx):
       result.SocketHandle.setSockOptInt(SOL_SOCKET, SO_NOSIGPIPE, 1)
     register(result)
 
-  proc newAsyncRawSocket*(domain: Domain = AF_INET,
-               sockType: SockType = SOCK_STREAM,
-               protocol: Protocol = IPPROTO_TCP): AsyncFD =
-    result = newRawSocket(domain, sockType, protocol).AsyncFD
+  proc newAsyncNativeSocket*(domain: Domain = AF_INET,
+                             sockType: SockType = SOCK_STREAM,
+                             protocol: Protocol = IPPROTO_TCP): AsyncFD =
+    result = newNativeSocket(domain, sockType, protocol).AsyncFD
     result.SocketHandle.setBlocking(false)
     when defined(macosx):
       result.SocketHandle.setSockOptInt(SOL_SOCKET, SO_NOSIGPIPE, 1)
diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim
index d7a8c3094..6b19a48be 100644
--- a/lib/pure/asyncnet.nim
+++ b/lib/pure/asyncnet.nim
@@ -56,7 +56,7 @@
 ##
 
 import asyncdispatch
-import rawsockets
+import nativesockets
 import net
 import os
 
@@ -112,8 +112,8 @@ proc newAsyncSocket*(domain: Domain = AF_INET, sockType: SockType = SOCK_STREAM,
   ##
   ## This procedure will also create a brand new file descriptor for
   ## this socket.
-  result = newAsyncSocket(newAsyncRawSocket(domain, sockType, protocol), domain,
-      sockType, protocol, buffered)
+  result = newAsyncSocket(newAsyncNativeSocket(domain, sockType, protocol),
+                          domain, sockType, protocol, buffered)
 
 proc newAsyncSocket*(domain, sockType, protocol: cint,
     buffered = true): AsyncSocket =
@@ -121,8 +121,9 @@ proc newAsyncSocket*(domain, sockType, protocol: cint,
   ##
   ## This procedure will also create a brand new file descriptor for
   ## this socket.
-  result = newAsyncSocket(newAsyncRawSocket(domain, sockType, protocol),
-      Domain(domain), SockType(sockType), Protocol(protocol), buffered)
+  result = newAsyncSocket(newAsyncNativeSocket(domain, sockType, protocol),
+                          Domain(domain), SockType(sockType),
+                          Protocol(protocol), buffered)
 
 when defined(ssl):
   proc getSslError(handle: SslPtr, err: cint): cint =
diff --git a/lib/pure/collections/critbits.nim b/lib/pure/collections/critbits.nim
index 424bcdcca..09b20fd45 100644
--- a/lib/pure/collections/critbits.nim
+++ b/lib/pure/collections/critbits.nim
@@ -123,6 +123,14 @@ proc containsOrIncl*(c: var CritBitTree[void], key: string): bool =
   var n = rawInsert(c, key)
   result = c.count == oldCount
 
+proc inc*(c: var CritBitTree[int]; key: string) =
+  ## counts the 'key'.
+  let oldCount = c.count
+  var n = rawInsert(c, key)
+  if c.count == oldCount:
+    # not a new key:
+    inc n.val
+
 proc incl*(c: var CritBitTree[void], key: string) =
   ## includes `key` in `c`.
   discard rawInsert(c, key)
diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim
index 30b838b7e..a5d4ec1a1 100644
--- a/lib/pure/httpclient.nim
+++ b/lib/pure/httpclient.nim
@@ -81,7 +81,7 @@
 
 import net, strutils, uri, parseutils, strtabs, base64, os, mimetypes, math
 import asyncnet, asyncdispatch
-import rawsockets
+import nativesockets
 
 type
   Response* = tuple[
@@ -764,10 +764,10 @@ proc newConnection(client: AsyncHttpClient, url: Uri) {.async.} =
     let port =
       if url.port == "":
         if url.scheme.toLower() == "https":
-          rawsockets.Port(443)
+          nativesockets.Port(443)
         else:
-          rawsockets.Port(80)
-      else: rawsockets.Port(url.port.parseInt)
+          nativesockets.Port(80)
+      else: nativesockets.Port(url.port.parseInt)
 
     if url.scheme.toLower() == "https":
       when defined(ssl):
diff --git a/lib/pure/rawsockets.nim b/lib/pure/nativesockets.nim
index 1b62913f1..c9e067a3e 100644
--- a/lib/pure/rawsockets.nim
+++ b/lib/pure/nativesockets.nim
@@ -93,8 +93,8 @@ when useWinVersion:
     IOC_IN* = int(-2147483648)
     FIONBIO* = IOC_IN.int32 or ((sizeof(int32) and IOCPARM_MASK) shl 16) or
                              (102 shl 8) or 126
-    rawAfInet = winlean.AF_INET
-    rawAfInet6 = winlean.AF_INET6
+    nativeAfInet = winlean.AF_INET
+    nativeAfInet6 = winlean.AF_INET6
 
   proc ioctlsocket*(s: SocketHandle, cmd: clong,
                    argptr: ptr clong): cint {.
@@ -102,8 +102,8 @@ when useWinVersion:
 else:
   let
     osInvalidSocket* = posix.INVALID_SOCKET
-    rawAfInet = posix.AF_INET
-    rawAfInet6 = posix.AF_INET6
+    nativeAfInet = posix.AF_INET
+    nativeAfInet6 = posix.AF_INET6
 
 proc `==`*(a, b: Port): bool {.borrow.}
   ## ``==`` for ports.
@@ -157,12 +157,14 @@ else:
     result = cint(ord(p))
 
 
-proc newRawSocket*(domain: Domain = AF_INET, sockType: SockType = SOCK_STREAM,
-             protocol: Protocol = IPPROTO_TCP): SocketHandle =
+proc newNativeSocket*(domain: Domain = AF_INET,
+                      sockType: SockType = SOCK_STREAM,
+                      protocol: Protocol = IPPROTO_TCP): SocketHandle =
   ## Creates a new socket; returns `InvalidSocket` if an error occurs.
   socket(toInt(domain), toInt(sockType), toInt(protocol))
 
-proc newRawSocket*(domain: cint, sockType: cint, protocol: cint): SocketHandle =
+proc newNativeSocket*(domain: cint, sockType: cint,
+                      protocol: cint): SocketHandle =
   ## Creates a new socket; returns `InvalidSocket` if an error occurs.
   ##
   ## Use this overload if one of the enums specified above does
@@ -201,7 +203,9 @@ proc getAddrInfo*(address: string, port: Port, domain: Domain = AF_INET,
   hints.ai_family = toInt(domain)
   hints.ai_socktype = toInt(sockType)
   hints.ai_protocol = toInt(protocol)
-  hints.ai_flags = AI_V4MAPPED
+  # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=198092
+  when not defined(freebsd):
+    hints.ai_flags = AI_V4MAPPED
   var gaiResult = getaddrinfo(address, $port, addr(hints), result)
   if gaiResult != 0'i32:
     when useWinVersion:
@@ -229,17 +233,17 @@ proc ntohs*(x: int16): int16 =
   when cpuEndian == bigEndian: result = x
   else: result = (x shr 8'i16) or (x shl 8'i16)
 
-proc htonl*(x: int32): int32 =
+template htonl*(x: int32): expr =
   ## Converts 32-bit integers from host to network byte order. On machines
   ## where the host byte order is the same as network byte order, this is
   ## a no-op; otherwise, it performs a 4-byte swap operation.
-  result = rawsockets.ntohl(x)
+  nativesockets.ntohl(x)
 
-proc htons*(x: int16): int16 =
+template htons*(x: int16): expr =
   ## Converts 16-bit positive integers from host to network byte order.
   ## On machines where the host byte order is the same as network byte
   ## order, this is a no-op; otherwise, it performs a 2-byte swap operation.
-  result = rawsockets.ntohs(x)
+  nativesockets.ntohs(x)
 
 proc getServByName*(name, proto: string): Servent {.tags: [ReadIOEffect].} =
   ## Searches the database from the beginning and finds the first entry for
@@ -280,7 +284,7 @@ proc getHostByAddr*(ip: string): Hostent {.tags: [ReadIOEffect].} =
 
   when useWinVersion:
     var s = winlean.gethostbyaddr(addr(myaddr), sizeof(myaddr).cuint,
-                                  cint(rawsockets.AF_INET))
+                                  cint(AF_INET))
     if s == nil: raiseOSError(osLastError())
   else:
     var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).Socklen,
@@ -330,9 +334,9 @@ proc getSockDomain*(socket: SocketHandle): Domain =
   if getsockname(socket, cast[ptr SockAddr](addr(name)),
                  addr(namelen)) == -1'i32:
     raiseOSError(osLastError())
-  if name.sa_family == rawAfInet:
+  if name.sa_family == nativeAfInet:
     result = AF_INET
-  elif name.sa_family == rawAfInet6:
+  elif name.sa_family == nativeAfInet6:
     result = AF_INET6
   else:
     raiseOSError(osLastError(), "unknown socket family in getSockFamily")
@@ -340,9 +344,9 @@ proc getSockDomain*(socket: SocketHandle): Domain =
 
 proc getAddrString*(sockAddr: ptr SockAddr): string =
   ## return the string representation of address within sockAddr
-  if sockAddr.sa_family == rawAfInet:
+  if sockAddr.sa_family == nativeAfInet:
     result = $inet_ntoa(cast[ptr Sockaddr_in](sockAddr).sin_addr)
-  elif sockAddr.sa_family == rawAfInet6:
+  elif sockAddr.sa_family == nativeAfInet6:
     when not useWinVersion:
       # TODO: Windows
       result = newString(posix.INET6_ADDRSTRLEN)
@@ -368,7 +372,7 @@ proc getSockName*(socket: SocketHandle): Port =
   if getsockname(socket, cast[ptr SockAddr](addr(name)),
                  addr(namelen)) == -1'i32:
     raiseOSError(osLastError())
-  result = Port(rawsockets.ntohs(name.sin_port))
+  result = Port(nativesockets.ntohs(name.sin_port))
 
 proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
   ## returns the socket's local address and port number.
@@ -385,7 +389,8 @@ proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
     if getsockname(socket, cast[ptr SockAddr](addr(name)),
                    addr(namelen)) == -1'i32:
       raiseOSError(osLastError())
-    result = ($inet_ntoa(name.sin_addr), Port(rawsockets.ntohs(name.sin_port)))
+    result = ($inet_ntoa(name.sin_addr),
+              Port(nativesockets.ntohs(name.sin_port)))
   of AF_INET6:
     var name: Sockaddr_in6
     when useWinVersion:
@@ -401,7 +406,7 @@ proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
     if inet_ntop(name.sin6_family.cint,
                  addr name, buf.cstring, sizeof(buf).int32).isNil:
       raiseOSError(osLastError())
-    result = ($buf, Port(rawsockets.ntohs(name.sin6_port)))
+    result = ($buf, Port(nativesockets.ntohs(name.sin6_port)))
   else:
     raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
 
@@ -420,7 +425,8 @@ proc getPeerAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
     if getpeername(socket, cast[ptr SockAddr](addr(name)),
                    addr(namelen)) == -1'i32:
       raiseOSError(osLastError())
-    result = ($inet_ntoa(name.sin_addr), Port(rawsockets.ntohs(name.sin_port)))
+    result = ($inet_ntoa(name.sin_addr),
+              Port(nativesockets.ntohs(name.sin_port)))
   of AF_INET6:
     var name: Sockaddr_in6
     when useWinVersion:
@@ -436,7 +442,7 @@ proc getPeerAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
     if inet_ntop(name.sin6_family.cint,
                  addr name, buf.cstring, sizeof(buf).int32).isNil:
       raiseOSError(osLastError())
-    result = ($buf, Port(rawsockets.ntohs(name.sin6_port)))
+    result = ($buf, Port(nativesockets.ntohs(name.sin6_port)))
   else:
     raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
 
diff --git a/lib/pure/net.nim b/lib/pure/net.nim
index 00a6c0c92..d1016011e 100644
--- a/lib/pure/net.nim
+++ b/lib/pure/net.nim
@@ -10,7 +10,7 @@
 ## This module implements a high-level cross-platform sockets interface.
 
 {.deadCodeElim: on.}
-import rawsockets, os, strutils, unsigned, parseutils, times
+import nativesockets, os, strutils, unsigned, parseutils, times
 export Port, `$`, `==`
 
 const useWinVersion = defined(Windows) or defined(nimdoc)
@@ -145,7 +145,7 @@ proc newSocket*(domain, sockType, protocol: cint, buffered = true): Socket =
   ## Creates a new socket.
   ##
   ## If an error occurs EOS will be raised.
-  let fd = newRawSocket(domain, sockType, protocol)
+  let fd = newNativeSocket(domain, sockType, protocol)
   if fd == osInvalidSocket:
     raiseOSError(osLastError())
   result = newSocket(fd, domain.Domain, sockType.SockType, protocol.Protocol,
@@ -156,7 +156,7 @@ proc newSocket*(domain: Domain = AF_INET, sockType: SockType = SOCK_STREAM,
   ## Creates a new socket.
   ##
   ## If an error occurs EOS will be raised.
-  let fd = newRawSocket(domain, sockType, protocol)
+  let fd = newNativeSocket(domain, sockType, protocol)
   if fd == osInvalidSocket:
     raiseOSError(osLastError())
   result = newSocket(fd, domain, sockType, protocol, buffered)
@@ -354,7 +354,7 @@ proc listen*(socket: Socket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} =
   ## queue of pending connections.
   ##
   ## Raises an EOS error upon failure.
-  if rawsockets.listen(socket.fd, backlog) < 0'i32:
+  if nativesockets.listen(socket.fd, backlog) < 0'i32:
     raiseOSError(osLastError())
 
 proc bindAddr*(socket: Socket, port = Port(0), address = "") {.
diff --git a/lib/pure/rationals.nim b/lib/pure/rationals.nim
index 7d9241412..72c64befc 100644
--- a/lib/pure/rationals.nim
+++ b/lib/pure/rationals.nim
@@ -39,6 +39,63 @@ proc toRational*[T:SomeInteger](x: T): Rational[T] =
   result.num = x
   result.den = 1
 
+proc toRationalSub(x: float, n: int): Rational[int] =
+  var
+    a = 0
+    b, c, d = 1
+  result = 0 // 1   # rational 0
+  while b <= n and d <= n:
+    let ac = (a+c)
+    let bd = (b+d)
+    # scale by 1000 so not overflow for high precision
+    let mediant = (ac/1000) / (bd/1000)
+    if x == mediant:
+      if bd <= n:
+        result.num = ac
+        result.den = bd
+        return result
+      elif d > b:
+        result.num = c
+        result.den = d
+        return result
+      else:
+        result.num = a
+        result.den = b
+        return result
+    elif x > mediant:
+      a = ac
+      b = bd
+    else:
+      c = ac
+      d = bd
+  if (b > n):
+    return initRational(c, d)
+  return initRational(a, b)
+
+proc toRational*(x: float, n: int = high(int)): Rational[int] =
+  ## Calculate the best rational numerator and denominator
+  ## that approximates to `x`, where the denominator is
+  ## smaller than `n` (default is the largest possible
+  ## int to give maximum resolution)
+  ##
+  ## The algorithm is based on the Farey sequence named
+  ## after John Farey
+  ##
+  ## .. code-block:: Nim
+  ##  import math, rationals
+  ##  for i in 1..10:
+  ##    let t = (10 ^ (i+3)).int
+  ##    let x = toRational(PI, t)
+  ##    let newPI = x.num / x.den
+  ##    echo x, " ", newPI, " error: ", PI - newPI, "  ", t
+  if x > 1:
+    result = toRationalSub(1.0/x, n)
+    swap(result.num, result.den)
+  elif x == 1.0:
+    result = 1 // 1
+  else:
+    result = toRationalSub(x, n)
+
 proc toFloat*[T](x: Rational[T]): float =
   ## Convert a rational number `x` to a float.
   x.num / x.den
@@ -288,3 +345,8 @@ when isMainModule:
   assert toRational(5) == 5//1
   assert abs(toFloat(y) - 0.4814814814814815) < 1.0e-7
   assert toInt(z) == 0
+
+  assert toRational(0.98765432) == 12345679 // 12500000
+  assert toRational(0.1, 1000000) == 1 // 10
+  assert toRational(0.9, 1000000) == 9 // 10
+  assert toRational(PI) == 80143857 // 25510582
diff --git a/lib/pure/strtabs.nim b/lib/pure/strtabs.nim
index 86f81aa43..1ce9067a7 100644
--- a/lib/pure/strtabs.nim
+++ b/lib/pure/strtabs.nim
@@ -173,6 +173,9 @@ proc clear*(s: StringTableRef, mode: StringTableMode) =
   s.mode = mode
   s.counter = 0
   s.data.setLen(startSize)
+  for i in 0..<s.data.len:
+    if not isNil(s.data[i].key):
+      s.data[i].key = nil
 
 proc newStringTable*(keyValuePairs: varargs[string],
                      mode: StringTableMode): StringTableRef {.
@@ -248,3 +251,6 @@ when isMainModule:
   x.mget("11") = "23"
   assert x["11"] == "23"
 
+  x.clear(modeCaseInsensitive)
+  x["11"] = "22"
+  assert x["11"] == "22"
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim
index d1c09f43d..eacea72e4 100644
--- a/lib/pure/strutils.nim
+++ b/lib/pure/strutils.nim
@@ -169,7 +169,8 @@ proc cmpIgnoreStyle*(a, b: string): int {.noSideEffect,
     inc(j)
 
 
-proc strip*(s: string, leading = true, trailing = true, chars: set[char] = Whitespace): string
+proc strip*(s: string, leading = true, trailing = true,
+            chars: set[char] = Whitespace): string
   {.noSideEffect, rtl, extern: "nsuStrip".} =
   ## Strips `chars` from `s` and returns the resulting string.
   ##
@@ -504,7 +505,8 @@ proc repeat*(c: char, count: Natural): string {.noSideEffect,
   ##
   ## .. code-block:: nim
   ##   proc tabexpand(indent: int, text: string, tabsize: int = 4) =
-  ##     echo '\t'.repeat(indent div tabsize), ' '.repeat(indent mod tabsize), text
+  ##     echo '\t'.repeat(indent div tabsize), ' '.repeat(indent mod tabsize),
+  ##         text
   ##
   ##   tabexpand(4, "At four")
   ##   tabexpand(5, "At five")
@@ -533,11 +535,13 @@ template spaces*(n: Natural): string =  repeat(' ',n)
   ##   echo text1 & spaces(max(0, width - text1.len)) & "|"
   ##   echo text2 & spaces(max(0, width - text2.len)) & "|"
 
-proc repeatChar*(count: Natural, c: char = ' '): string {.deprecated.} = repeat(c, count)
+proc repeatChar*(count: Natural, c: char = ' '): string {.deprecated.} =
   ## deprecated: use repeat() or spaces()
+  repeat(c, count)
 
-proc repeatStr*(count: Natural, s: string): string {.deprecated.} = repeat(s, count)
+proc repeatStr*(count: Natural, s: string): string {.deprecated.} =
   ## deprecated: use repeat(string, count) or string.repeat(count)
+  repeat(s, count)
 
 proc align*(s: string, count: Natural, padding = ' '): string {.
   noSideEffect, rtl, extern: "nsuAlignString".} =
@@ -850,8 +854,8 @@ proc rfind*(s: string, sub: char, start: int = -1): int {.noSideEffect,
     if sub == s[i]: return i
   return -1
 
-proc count*(s: string, sub: string, overlapping: bool = false): int {.noSideEffect,
-  rtl, extern: "nsuCountString".} =
+proc count*(s: string, sub: string, overlapping: bool = false): int {.
+  noSideEffect, rtl, extern: "nsuCountString".} =
   ## Count the occurrences of a substring `sub` in the string `s`.
   ## Overlapping occurrences of `sub` only count when `overlapping`
   ## is set to true.
@@ -1449,7 +1453,8 @@ proc removeSuffix*(s: var string, chars: set[char] = Newlines) {.
 
   s.setLen(last + 1)
 
-proc removeSuffix*(s: var string, c: char) {.rtl, extern: "nsuRemoveSuffixChar".} =
+proc removeSuffix*(s: var string, c: char) {.
+  rtl, extern: "nsuRemoveSuffixChar".} =
   ## Removes a single character (in-place) from a string.
   ## .. code-block:: nim
   ##   var
@@ -1515,7 +1520,8 @@ when isMainModule:
   doAssert strip("sfoofoofoos", chars = {'s'}) == "foofoofoo"
   doAssert strip("barfoofoofoobar", chars = {'b', 'a', 'r'}) == "foofoofoo"
   doAssert strip("stripme but don't strip this stripme",
-                 chars = {'s', 't', 'r', 'i', 'p', 'm', 'e'}) == " but don't strip this "
+                 chars = {'s', 't', 'r', 'i', 'p', 'm', 'e'}) ==
+                 " but don't strip this "
   doAssert strip("sfoofoofoos", leading = false, chars = {'s'}) == "sfoofoofoo"
   doAssert strip("sfoofoofoos", trailing = false, chars = {'s'}) == "foofoofoos"
 
diff --git a/lib/system/nimscript.nim b/lib/system/nimscript.nim
index a93c65dd4..22430348c 100644
--- a/lib/system/nimscript.nim
+++ b/lib/system/nimscript.nim
@@ -31,7 +31,8 @@ proc moveFile(src, dest: string) {.
   tags: [ReadIOEffect, WriteIOEffect], raises: [OSError].} = builtin
 proc copyFile(src, dest: string) {.
   tags: [ReadIOEffect, WriteIOEffect], raises: [OSError].} = builtin
-proc createDir(dir: string) {.tags: [WriteIOEffect], raises: [OSError].} = builtin
+proc createDir(dir: string) {.tags: [WriteIOEffect], raises: [OSError].} =
+  builtin
 proc getOsError: string = builtin
 proc setCurrentDir(dir: string) = builtin
 proc getCurrentDir(): string = builtin
diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim
index e6a119e15..89d86c62a 100644
--- a/lib/windows/winlean.nim
+++ b/lib/windows/winlean.nim
@@ -18,7 +18,7 @@ const
 type
   Handle* = int
   LONG* = int32
-  ULONG* = int
+  ULONG* = int32
   PULONG* = ptr int
   WINBOOL* = int32
   DWORD* = int32
diff --git a/tests/async/tasyncawait.nim b/tests/async/tasyncawait.nim
index e5895abe1..443f769cd 100644
--- a/tests/async/tasyncawait.nim
+++ b/tests/async/tasyncawait.nim
@@ -2,7 +2,7 @@ discard """
   file: "tasyncawait.nim"
   output: "5000"
 """
-import asyncdispatch, rawsockets, net, strutils, os
+import asyncdispatch, nativesockets, net, strutils, os
 
 var msgCount = 0
 
@@ -18,7 +18,7 @@ proc sendMessages(client: TAsyncFD) {.async.} =
 
 proc launchSwarm(port: TPort) {.async.} =
   for i in 0 .. <swarmSize:
-    var sock = newAsyncRawSocket()
+    var sock = newAsyncNativeSocket()
 
     await connect(sock, "localhost", port)
     await sendMessages(sock)
@@ -38,7 +38,7 @@ proc readMessages(client: TAsyncFD) {.async.} =
         doAssert false
 
 proc createServer(port: TPort) {.async.} =
-  var server = newAsyncRawSocket()
+  var server = newAsyncNativeSocket()
   block:
     var name: Sockaddr_in
     when defined(windows):
diff --git a/tests/async/tasyncconnect.nim b/tests/async/tasyncconnect.nim
index b27a810b8..3dac379b2 100644
--- a/tests/async/tasyncconnect.nim
+++ b/tests/async/tasyncconnect.nim
@@ -19,7 +19,7 @@ when defined(windows) or defined(nimdoc):
     quit("Error: unhandled exception: Connection refused")
 else:
     proc testAsyncConnect() {.async.} =
-        var s = newAsyncRawSocket()
+        var s = newAsyncNativeSocket()
 
         await s.connect(testHost, testPort)
 
diff --git a/tests/async/tasynceverror.nim b/tests/async/tasynceverror.nim
index 2f570344f..22b4fe9a7 100644
--- a/tests/async/tasynceverror.nim
+++ b/tests/async/tasynceverror.nim
@@ -7,7 +7,7 @@ discard """
 import
     asyncdispatch,
     asyncnet,
-    rawsockets,
+    nativesockets,
     os
 
 
@@ -21,7 +21,7 @@ when defined(windows) or defined(nimdoc):
     quit("Error: unhandled exception: Connection reset by peer")
 else:
     proc createListenSocket(host: string, port: Port): TAsyncFD =
-        result = newAsyncRawSocket()
+        result = newAsyncNativeSocket()
 
         SocketHandle(result).setSockOptInt(SOL_SOCKET, SO_REUSEADDR, 1)
 
diff --git a/tests/ccgbugs/twrong_discriminant_check.nim b/tests/ccgbugs/twrong_discriminant_check.nim
new file mode 100644
index 000000000..a802f45ef
--- /dev/null
+++ b/tests/ccgbugs/twrong_discriminant_check.nim
@@ -0,0 +1,30 @@
+discard """
+  output: "(kind: None)"
+"""
+
+when true:
+  # bug #2637
+
+  type
+    OptionKind = enum
+      None,
+      Some
+
+    Option*[T] = object
+      case kind: OptionKind
+      of None:
+        discard
+      of Some:
+        value*: T
+
+  proc none*[T](): Option[T] =
+    Option[T](kind: None)
+
+  proc none*(T: typedesc): Option[T] = none[T]()
+
+
+  proc test(): Option[int] =
+    int.none
+
+  echo test()
+
diff --git a/tests/cpp/trawsockets.nim b/tests/cpp/tnativesockets.nim
index bc129de57..6108380a8 100644
--- a/tests/cpp/trawsockets.nim
+++ b/tests/cpp/tnativesockets.nim
@@ -2,4 +2,4 @@ discard """
   cmd: "nim cpp $file"
 """
 
-import rawsockets
+import nativesockets
diff --git a/tests/macros/tgensym.nim b/tests/macros/tgensym.nim
index b3aef0a2c..a4d1a3606 100644
--- a/tests/macros/tgensym.nim
+++ b/tests/macros/tgensym.nim
@@ -1,6 +1,6 @@
-import rawsockets, asyncdispatch, macros
+import nativesockets, asyncdispatch, macros
 var p = newDispatcher()
-var sock = newAsyncRawSocket()
+var sock = newAsyncNativeSocket()
 
 proc convertReturns(node, retFutureSym: NimNode): NimNode {.compileTime.} =
   case node.kind
diff --git a/tests/modules/texport.nim b/tests/modules/texport.nim
index 0890fb369..a8c217ab8 100644
--- a/tests/modules/texport.nim
+++ b/tests/modules/texport.nim
@@ -5,7 +5,7 @@ discard """
 import mexporta
 
 # bug #1029:
-from rawsockets import accept
+from nativesockets import accept
 
 # B.TMyObject has been imported implicitly here:
 var x: TMyObject
diff --git a/web/news.txt b/web/news.txt
index 33ceac49e..2b6079620 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -9,6 +9,9 @@ News
   Changes affecting backwards compatibility
   -----------------------------------------
 
+  - The ``rawsockets`` module has been renamed to ``nativesockets`` to avoid
+    confusion with TCP/IP raw sockets, so ``newNativeSocket`` should be used
+    instead of ``newRawSocket``.
   - The ``miliseconds`` property of ``times.TimeInterval`` is now ``milliseconds``.
     Code accessing that property is deprecated and code using ``miliseconds``
     during object initialization or as a named parameter of ``initInterval()``