Merge remote-tracking branch 'origin/devel' into fix-test-failures

This commit is contained in:
Aman Gupta
2015-10-06 11:06:41 -07:00
41 changed files with 358 additions and 163 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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)

View File

@@ -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:

View File

@@ -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)

View File

@@ -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)

View File

@@ -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",

View File

@@ -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"

View File

@@ -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
================

View File

@@ -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
-------

View File

@@ -1,9 +0,0 @@
#!/bin/sh
set -e
set -x
if [ "$1" != "" ]; then
exec ./koch install "$1"
else
exec ./koch install
fi

View File

@@ -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":

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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 =

View File

@@ -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)

View File

@@ -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):

View File

@@ -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")

View File

@@ -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 = "") {.

View File

@@ -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

View File

@@ -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"

View File

@@ -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"

View File

@@ -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

View File

@@ -18,7 +18,7 @@ const
type
Handle* = int
LONG* = int32
ULONG* = int
ULONG* = int32
PULONG* = ptr int
WINBOOL* = int32
DWORD* = int32

View File

@@ -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):

View File

@@ -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)

View File

@@ -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)

View File

@@ -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()

View File

@@ -2,4 +2,4 @@ discard """
cmd: "nim cpp $file"
"""
import rawsockets
import nativesockets

View File

@@ -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

View File

@@ -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

View File

@@ -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()``