diff options
-rw-r--r-- | doc/lib.txt | 18 | ||||
-rw-r--r-- | lib/pure/asyncdispatch.nim | 30 | ||||
-rw-r--r-- | lib/pure/asynchttpserver.nim | 75 | ||||
-rw-r--r-- | lib/pure/asyncio.nim | 7 | ||||
-rw-r--r-- | lib/pure/asyncnet.nim | 39 | ||||
-rw-r--r-- | lib/pure/net.nim | 33 | ||||
-rw-r--r-- | lib/pure/parseurl.nim | 8 | ||||
-rw-r--r-- | lib/pure/scgi.nim | 4 | ||||
-rw-r--r-- | lib/pure/sockets.nim | 7 | ||||
-rw-r--r-- | lib/pure/uri.nim | 36 | ||||
-rw-r--r-- | tests/async/tasyncawait.nim | 4 | ||||
-rw-r--r-- | tests/async/tasynciossl.nim | 4 | ||||
-rw-r--r-- | tests/async/tasyncudp.nim | 6 | ||||
-rw-r--r-- | tools/nimweb.nim | 4 | ||||
-rw-r--r-- | web/babelpkglist.nim | 5 | ||||
-rw-r--r-- | web/news.txt | 107 |
16 files changed, 267 insertions, 120 deletions
diff --git a/doc/lib.txt b/doc/lib.txt index aba05c2ba..7d100e1ca 100644 --- a/doc/lib.txt +++ b/doc/lib.txt @@ -18,7 +18,7 @@ low-level interface to a C library. Read this `document <apis.html>`_ for a quick overview of the API design. -The `bottom <#babel>`_ of this page includes a list of 3rd party packages +The `bottom <#nimble>`_ of this page includes a list of 3rd party packages created by the Nim community. These packages are a useful addition to the modules in the standard library. @@ -581,12 +581,12 @@ Scientific computing * `libsvm <libsvm.html>`_ Low level wrapper for `lib svm <http://www.csie.ntu.edu.tw/~cjlin/libsvm/>`_. -Babel +Nimble ==================== -Babel is a package manager for the Nim programming language. -For instructions on how to install Babel packages see -`its README <https://github.com/nim-code/babel#readme>`_. +Nimble is a package manager for the Nim programming language. +For instructions on how to install Nimble packages see +`its README <https://github.com/nim-lang/babel#readme>`_. Official packages ----------------- @@ -598,7 +598,7 @@ compiler. .. raw:: html <div id="officialPkgList"><b>If you are reading this you are missing - babelpkglist.js or have javascript disabled in your browser.</b></div> + nimblepkglist.js or have javascript disabled in your browser.</b></div> Unofficial packages ------------------- @@ -610,7 +610,7 @@ Nim programming language. .. raw:: html <div id="unofficialPkgList"><b>If you are reading this you are missing - babelpkglist.js or have javascript disabled in your browser.</b></div> + nimblepkglist.js or have javascript disabled in your browser.</b></div> - <script type="text/javascript" src="babelpkglist.js"></script> - <script type="text/javascript" src="http://build.nim-lang.org/packages?callback=gotPackageList"></script> + <script type="text/javascript" src="nimblepkglist.js"></script> + <script type="text/javascript" src="http://irclogs.nim-lang.org/packages?callback=gotPackageList"></script> diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index a9a0b0fbe..4bdce9cfb 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -436,12 +436,12 @@ when defined(windows) or defined(nimdoc): if not initPointer(dummySock, getAcceptExSockAddrsPtr, WSAID_GETACCEPTEXSOCKADDRS): raiseOSError(osLastError()) - proc connectEx(s: SocketHandle, name: ptr TSockAddr, namelen: cint, + proc connectEx(s: SocketHandle, name: ptr SockAddr, namelen: cint, lpSendBuffer: pointer, dwSendDataLength: Dword, lpdwBytesSent: PDword, lpOverlapped: POVERLAPPED): bool = if connectExPtr.isNil: raise newException(ValueError, "Need to initialise ConnectEx().") let fun = - cast[proc (s: SocketHandle, name: ptr TSockAddr, namelen: cint, + cast[proc (s: SocketHandle, name: ptr SockAddr, namelen: cint, lpSendBuffer: pointer, dwSendDataLength: Dword, lpdwBytesSent: PDword, lpOverlapped: POVERLAPPED): bool {.stdcall,gcsafe.}](connectExPtr) @@ -464,16 +464,16 @@ when defined(windows) or defined(nimdoc): proc getAcceptExSockaddrs(lpOutputBuffer: pointer, dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength: Dword, - LocalSockaddr: ptr ptr TSockAddr, LocalSockaddrLength: LPInt, - RemoteSockaddr: ptr ptr TSockAddr, RemoteSockaddrLength: LPInt) = + LocalSockaddr: ptr ptr SockAddr, LocalSockaddrLength: LPInt, + RemoteSockaddr: ptr ptr SockAddr, RemoteSockaddrLength: LPInt) = if getAcceptExSockAddrsPtr.isNil: raise newException(ValueError, "Need to initialise getAcceptExSockAddrs().") let fun = cast[proc (lpOutputBuffer: pointer, dwReceiveDataLength, dwLocalAddressLength, - dwRemoteAddressLength: Dword, LocalSockaddr: ptr ptr TSockAddr, - LocalSockaddrLength: LPInt, RemoteSockaddr: ptr ptr TSockAddr, + dwRemoteAddressLength: Dword, LocalSockaddr: ptr ptr SockAddr, + LocalSockaddrLength: LPInt, RemoteSockaddr: ptr ptr SockAddr, RemoteSockaddrLength: LPInt) {.stdcall,gcsafe.}](getAcceptExSockAddrsPtr) fun(lpOutputBuffer, dwReceiveDataLength, dwLocalAddressLength, @@ -489,12 +489,12 @@ when defined(windows) or defined(nimdoc): verifyPresence(socket) var retFuture = newFuture[void]("connect") # Apparently ``ConnectEx`` expects the socket to be initially bound: - var saddr: Tsockaddr_in + var saddr: Sockaddr_in saddr.sin_family = int16(toInt(af)) saddr.sin_port = 0 saddr.sin_addr.s_addr = INADDR_ANY - if bindAddr(socket.SocketHandle, cast[ptr TSockAddr](addr(saddr)), - sizeof(saddr).TSockLen) < 0'i32: + if bindAddr(socket.SocketHandle, cast[ptr SockAddr](addr(saddr)), + sizeof(saddr).SockLen) < 0'i32: raiseOSError(osLastError()) var aiList = getAddrInfo(address, port, af) @@ -516,7 +516,7 @@ when defined(windows) or defined(nimdoc): ) var ret = connectEx(socket.SocketHandle, it.ai_addr, - sizeof(Tsockaddr_in).cint, nil, 0, nil, + sizeof(Sockaddr_in).cint, nil, 0, nil, cast[POVERLAPPED](ol)) if ret: # Request to connect completed immediately. @@ -700,17 +700,17 @@ when defined(windows) or defined(nimdoc): var lpOutputBuf = newString(lpOutputLen) var dwBytesReceived: Dword let dwReceiveDataLength = 0.Dword # We don't want any data to be read. - let dwLocalAddressLength = Dword(sizeof (Tsockaddr_in) + 16) - let dwRemoteAddressLength = Dword(sizeof(Tsockaddr_in) + 16) + let dwLocalAddressLength = Dword(sizeof (Sockaddr_in) + 16) + let dwRemoteAddressLength = Dword(sizeof(Sockaddr_in) + 16) template completeAccept(): stmt {.immediate, dirty.} = var listenSock = socket let setoptRet = setsockopt(clientSock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, addr listenSock, - sizeof(listenSock).TSockLen) + sizeof(listenSock).SockLen) if setoptRet != 0: raiseOSError(osLastError()) - var localSockaddr, remoteSockaddr: ptr TSockAddr + var localSockaddr, remoteSockaddr: ptr SockAddr var localLen, remoteLen: int32 getAcceptExSockaddrs(addr lpOutputBuf[0], dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength, @@ -719,7 +719,7 @@ when defined(windows) or defined(nimdoc): register(clientSock.TAsyncFD) # TODO: IPv6. Check ``sa_family``. http://stackoverflow.com/a/9212542/492186 retFuture.complete( - (address: $inet_ntoa(cast[ptr Tsockaddr_in](remoteSockAddr).sin_addr), + (address: $inet_ntoa(cast[ptr Sockaddr_in](remoteSockAddr).sin_addr), client: clientSock.TAsyncFD) ) diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim index e0f3b6fc2..0b18e6bcc 100644 --- a/lib/pure/asynchttpserver.nim +++ b/lib/pure/asynchttpserver.nim @@ -18,7 +18,7 @@ ## ## .. code-block::nim ## var server = newAsyncHttpServer() -## proc cb(req: TRequest) {.async.} = +## proc cb(req: Request) {.async.} = ## await req.respond(Http200, "Hello World") ## ## asyncCheck server.serve(Port(8080), cb) @@ -27,25 +27,52 @@ import strtabs, asyncnet, asyncdispatch, parseutils, uri, strutils type Request* = object - client*: PAsyncSocket # TODO: Separate this into a Response object? + client*: AsyncSocket # TODO: Separate this into a Response object? reqMethod*: string - headers*: PStringTable + headers*: StringTableRef protocol*: tuple[orig: string, major, minor: int] - url*: TUri + url*: Uri hostname*: string ## The hostname of the client that made the request. body*: string AsyncHttpServer* = ref object - socket: PAsyncSocket + socket: AsyncSocket reuseAddr: bool HttpCode* = enum + Http100 = "100 Continue", + Http101 = "101 Switching Protocols", Http200 = "200 OK", - Http303 = "303 Moved", + Http201 = "201 Created", + Http202 = "202 Accepted", + Http204 = "204 No Content", + Http205 = "205 Reset Content", + Http206 = "206 Partial Content", + Http300 = "300 Multiple Choices", + Http301 = "301 Moved Permanently", + Http302 = "302 Found", + Http303 = "303 See Other", + Http304 = "304 Not Modified", + Http305 = "305 Use Proxy", + Http307 = "307 Temporary Redirect", Http400 = "400 Bad Request", + Http401 = "401 Unauthorized", + Http403 = "403 Forbidden", Http404 = "404 Not Found", + Http405 = "405 Method Not Allowed", + Http406 = "406 Not Acceptable", + Http407 = "407 Proxy Authentication Required", + Http408 = "408 Request Timeout", + Http409 = "409 Conflict", + Http410 = "410 Gone", + Http411 = "411 Length Required", + Http418 = "418 I'm a teapot", Http500 = "500 Internal Server Error", - Http502 = "502 Bad Gateway" + Http501 = "501 Not Implemented", + Http502 = "502 Bad Gateway", + Http503 = "503 Service Unavailable", + Http504 = "504 Gateway Timeout", + Http505 = "505 HTTP Version Not Supported" HttpVersion* = enum HttpVer11, @@ -55,7 +82,7 @@ type THttpCode: HttpCode, THttpVersion: HttpVersion].} proc `==`*(protocol: tuple[orig: string, major, minor: int], - ver: THttpVersion): bool = + ver: HttpVersion): bool = let major = case ver of HttpVer11, HttpVer10: 1 @@ -65,23 +92,23 @@ proc `==`*(protocol: tuple[orig: string, major, minor: int], of HttpVer10: 0 result = protocol.major == major and protocol.minor == minor -proc newAsyncHttpServer*(reuseAddr = true): PAsyncHttpServer = +proc newAsyncHttpServer*(reuseAddr = true): AsyncHttpServer = ## Creates a new ``AsyncHttpServer`` instance. new result result.reuseAddr = reuseAddr -proc addHeaders(msg: var string, headers: PStringTable) = +proc addHeaders(msg: var string, headers: StringTableRef) = for k, v in headers: msg.add(k & ": " & v & "\c\L") -proc sendHeaders*(req: TRequest, headers: PStringTable): Future[void] = +proc sendHeaders*(req: Request, headers: StringTableRef): Future[void] = ## Sends the specified headers to the requesting client. var msg = "" addHeaders(msg, headers) return req.client.send(msg) -proc respond*(req: TRequest, code: THttpCode, - content: string, headers: PStringTable = newStringTable()) {.async.} = +proc respond*(req: Request, code: HttpCode, + content: string, headers = newStringTable()) {.async.} = ## Responds to the request with the specified ``HttpCode``, headers and ## content. ## @@ -92,7 +119,7 @@ proc respond*(req: TRequest, code: THttpCode, msg.addHeaders(customHeaders) await req.client.send(msg & "\c\L" & content) -proc newRequest(): TRequest = +proc newRequest(): Request = result.headers = newStringTable(modeCaseInsensitive) result.hostname = "" result.body = "" @@ -107,20 +134,20 @@ proc parseHeader(line: string): tuple[key, value: string] = proc parseProtocol(protocol: string): tuple[orig: string, major, minor: int] = var i = protocol.skipIgnoreCase("HTTP/") if i != 5: - raise newException(EInvalidValue, "Invalid request protocol. Got: " & + raise newException(ValueError, "Invalid request protocol. Got: " & protocol) result.orig = protocol i.inc protocol.parseInt(result.major, i) i.inc # Skip . i.inc protocol.parseInt(result.minor, i) -proc sendStatus(client: PAsyncSocket, status: string): Future[void] = +proc sendStatus(client: AsyncSocket, status: string): Future[void] = client.send("HTTP/1.1 " & status & "\c\L") -proc processClient(client: PAsyncSocket, address: string, - callback: proc (request: TRequest): +proc processClient(client: AsyncSocket, address: string, + callback: proc (request: Request): Future[void] {.closure, gcsafe.}) {.async.} = - while not client.closed: + while not client.isClosed: # GET /path HTTP/1.1 # Header: val # \n @@ -160,7 +187,7 @@ proc processClient(client: PAsyncSocket, address: string, request.url = parseUri(path) try: request.protocol = protocol.parseProtocol() - except EInvalidValue: + except ValueError: asyncCheck request.respond(Http400, "Invalid request protocol. Got: " & protocol) continue @@ -206,8 +233,8 @@ proc processClient(client: PAsyncSocket, address: string, request.client.close() break -proc serve*(server: PAsyncHttpServer, port: Port, - callback: proc (request: TRequest): Future[void] {.closure,gcsafe.}, +proc serve*(server: AsyncHttpServer, port: Port, + callback: proc (request: Request): Future[void] {.closure,gcsafe.}, address = "") {.async.} = ## Starts the process of listening for incoming HTTP connections on the ## specified address and port. @@ -227,14 +254,14 @@ proc serve*(server: PAsyncHttpServer, port: Port, #echo(f.isNil) #echo(f.repr) -proc close*(server: PAsyncHttpServer) = +proc close*(server: AsyncHttpServer) = ## Terminates the async http server instance. server.socket.close() when isMainModule: proc main = var server = newAsyncHttpServer() - proc cb(req: TRequest) {.async.} = + proc cb(req: Request) {.async.} = #echo(req.reqMethod, " ", req.url) #echo(req.headers) let headers = {"Date": "Tue, 29 Apr 2014 23:40:08 GMT", diff --git a/lib/pure/asyncio.nim b/lib/pure/asyncio.nim index 4c25952a8..d40c3849e 100644 --- a/lib/pure/asyncio.nim +++ b/lib/pure/asyncio.nim @@ -10,6 +10,11 @@ include "system/inclrtl" import sockets, os +## +## **Warning:** This module is deprecated since version 0.10.2. +## Use the brand new `asyncdispatch <asyncdispatch.html>`_ module together +## with the `asyncnet <asyncnet.html>`_ module. + ## This module implements an asynchronous event loop together with asynchronous ## sockets which use this event loop. ## It is akin to Python's asyncore module. Many modules that use sockets @@ -90,6 +95,8 @@ import sockets, os ## var client: Socket ## getSocket(s).accept(client) +{.deprecated.} + when defined(windows): from winlean import TimeVal, SocketHandle, FD_SET, FD_ZERO, TFdSet, FD_ISSET, select diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index fc2722c6f..76b2bc46c 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -69,13 +69,13 @@ type # TODO: I would prefer to just do: # AsyncSocket* {.borrow: `.`.} = distinct Socket. But that doesn't work. AsyncSocketDesc = object - fd*: SocketHandle - closed*: bool ## determines whether this socket has been closed - case isBuffered*: bool ## determines whether this socket is buffered. + fd: SocketHandle + closed: bool ## determines whether this socket has been closed + case isBuffered: bool ## determines whether this socket is buffered. of true: - buffer*: array[0..BufferSize, char] - currPos*: int # current index in buffer - bufLen*: int # current length of buffer + buffer: array[0..BufferSize, char] + currPos: int # current index in buffer + bufLen: int # current length of buffer of false: nil case isSsl: bool of true: @@ -91,7 +91,8 @@ type # TODO: Save AF, domain etc info and reuse it in procs which need it like connect. -proc newSocket(fd: TAsyncFD, isBuff: bool): AsyncSocket = +proc newAsyncSocket*(fd: TAsyncFD, isBuff: bool): AsyncSocket = + ## Creates a new ``AsyncSocket`` based on the supplied params. assert fd != osInvalidSocket.TAsyncFD new(result) result.fd = fd.SocketHandle @@ -102,11 +103,17 @@ proc newSocket(fd: TAsyncFD, isBuff: bool): AsyncSocket = proc newAsyncSocket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, protocol: Protocol = IPPROTO_TCP, buffered = true): AsyncSocket = ## Creates a new asynchronous socket. - result = newSocket(newAsyncRawSocket(domain, typ, protocol), buffered) + ## + ## This procedure will also create a brand new file descriptor for + ## this socket. + result = newAsyncSocket(newAsyncRawSocket(domain, typ, protocol), buffered) proc newAsyncSocket*(domain, typ, protocol: cint, buffered = true): AsyncSocket = ## Creates a new asynchronous socket. - result = newSocket(newAsyncRawSocket(domain, typ, protocol), buffered) + ## + ## This procedure will also create a brand new file descriptor for + ## this socket. + result = newAsyncSocket(newAsyncRawSocket(domain, typ, protocol), buffered) when defined(ssl): proc getSslError(handle: SslPtr, err: cint): cint = @@ -275,7 +282,7 @@ proc acceptAddr*(socket: AsyncSocket, flags = {SocketFlag.SafeDisconn}): retFuture.fail(future.readError) else: let resultTup = (future.read.address, - newSocket(future.read.client, socket.isBuffered)) + newAsyncSocket(future.read.client, socket.isBuffered)) retFuture.complete(resultTup) return retFuture @@ -439,6 +446,18 @@ proc setSockOpt*(socket: AsyncSocket, opt: SOBool, value: bool, var valuei = cint(if value: 1 else: 0) setSockOptInt(socket.fd, cint(level), toCInt(opt), valuei) +proc isSsl*(socket: AsyncSocket): bool = + ## Determines whether ``socket`` is a SSL socket. + socket.isSsl + +proc getFd*(socket: AsyncSocket): SocketHandle = + ## Returns the socket's file descriptor. + return socket.fd + +proc isClosed*(socket: AsyncSocket): bool = + ## Determines whether the socket has been closed. + return socket.closed + when isMainModule: type TestCases = enum diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 28b84eb39..e6fe79740 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -44,21 +44,21 @@ const type SocketImpl* = object ## socket type - fd*: SocketHandle - case isBuffered*: bool # determines whether this socket is buffered. + fd: SocketHandle + case isBuffered: bool # determines whether this socket is buffered. of true: - buffer*: array[0..BufferSize, char] - currPos*: int # current index in buffer - bufLen*: int # current length of buffer + buffer: array[0..BufferSize, char] + currPos: int # current index in buffer + bufLen: int # current length of buffer of false: nil when defined(ssl): - case isSsl*: bool + case isSsl: bool of true: - sslHandle*: SSLPtr - sslContext*: SSLContext - sslNoHandshake*: bool # True if needs handshake. - sslHasPeekChar*: bool - sslPeekChar*: char + sslHandle: SSLPtr + sslContext: SSLContext + sslNoHandshake: bool # True if needs handshake. + sslHasPeekChar: bool + sslPeekChar: char of false: nil Socket* = ref SocketImpl @@ -100,7 +100,8 @@ proc toOSFlags*(socketFlags: set[SocketFlag]): cint = result = result or MSG_PEEK of SocketFlag.SafeDisconn: continue -proc createSocket(fd: SocketHandle, isBuff: bool): Socket = +proc newSocket(fd: SocketHandle, isBuff: bool): Socket = + ## Creates a new socket as specified by the params. assert fd != osInvalidSocket new(result) result.fd = fd @@ -115,7 +116,7 @@ proc newSocket*(domain, typ, protocol: cint, buffered = true): Socket = let fd = newRawSocket(domain, typ, protocol) if fd == osInvalidSocket: raiseOSError(osLastError()) - result = createSocket(fd, buffered) + result = newSocket(fd, buffered) proc newSocket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, protocol: Protocol = IPPROTO_TCP, buffered = true): Socket = @@ -125,7 +126,7 @@ proc newSocket*(domain: Domain = AF_INET, typ: SockType = SOCK_STREAM, let fd = newRawSocket(domain, typ, protocol) if fd == osInvalidSocket: raiseOSError(osLastError()) - result = createSocket(fd, buffered) + result = newSocket(fd, buffered) when defined(ssl): CRYPTO_malloc_init() @@ -937,10 +938,10 @@ proc connect*(socket: Socket, address: string, port = Port(0), timeout: int, doAssert socket.handshake() socket.fd.setBlocking(true) -proc isSSL*(socket: Socket): bool = return socket.isSSL +proc isSsl*(socket: Socket): bool = return socket.isSSL ## Determines whether ``socket`` is a SSL socket. -proc getFD*(socket: Socket): SocketHandle = return socket.fd +proc getFd*(socket: Socket): SocketHandle = return socket.fd ## Returns the socket's file descriptor type diff --git a/lib/pure/parseurl.nim b/lib/pure/parseurl.nim index 32e69b89a..f27cd8c12 100644 --- a/lib/pure/parseurl.nim +++ b/lib/pure/parseurl.nim @@ -7,10 +7,12 @@ # distribution, for details about the copyright. # -## Parses & constructs URLs. +## **Warnings:** This module is deprecated since version 0.10.2. +## Use the `uri <uri.html>`_ module instead. ## -## **Note**: This module will be deprecated in the future and merged into a -## new ``url`` module. +## Parses & constructs URLs. + +{.deprecated.} import strutils diff --git a/lib/pure/scgi.nim b/lib/pure/scgi.nim index 58b37833a..f3e2b583c 100644 --- a/lib/pure/scgi.nim +++ b/lib/pure/scgi.nim @@ -25,6 +25,10 @@ ## ## **Warning:** The API of this module is unstable, and therefore is subject ## to change. +## +## **Warning:** This module only supports the old asynchronous interface. +## You may wish to use the `asynchttpserver <asynchttpserver.html>`_ +## instead for web applications. include "system/inclrtl" diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 79f409179..11eeefcb9 100644 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -7,6 +7,10 @@ # distribution, for details about the copyright. # +## **Warning:** Since version 0.10.2 this module is deprecated. +## Use the `net <net.html>`_ or the +## `rawsockets <rawsockets.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 ## received in ``BufferSize`` (4000) sized chunks, buffering @@ -23,9 +27,6 @@ ## ## Asynchronous sockets are supported, however a better alternative is to use ## the `asyncio <asyncio.html>`_ module. -## -## Since version 0.10.2 this module is deprecated. Use the `net <net.html>`_ -## or the `rawsockets <rawsockets.html>`_ module instead. {.deprecated.} diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim index 2c65d071e..368802dc2 100644 --- a/lib/pure/uri.nim +++ b/lib/pure/uri.nim @@ -19,14 +19,14 @@ type {.deprecated: [TUrl: Url, TUri: Uri].} -proc `$`*(url: TUrl): string {.deprecated.} = - ## **Deprecated since 0.9.6**: Use ``TUri`` instead. +proc `$`*(url: Url): string {.deprecated.} = + ## **Deprecated since 0.9.6**: Use ``Uri`` instead. return string(url) -proc `/`*(a, b: TUrl): TUrl {.deprecated.} = +proc `/`*(a, b: Url): Url {.deprecated.} = ## Joins two URLs together, separating them with / if needed. ## - ## **Deprecated since 0.9.6**: Use ``TUri`` instead. + ## **Deprecated since 0.9.6**: Use ``Uri`` instead. var urlS = $a var bS = $b if urlS == "": return b @@ -36,15 +36,15 @@ proc `/`*(a, b: TUrl): TUrl {.deprecated.} = urlS.add(bS.substr(1)) else: urlS.add(bs) - result = TUrl(urlS) + result = Url(urlS) -proc add*(url: var TUrl, a: TUrl) {.deprecated.} = +proc add*(url: var Url, a: Url) {.deprecated.} = ## Appends url to url. ## - ## **Deprecated since 0.9.6**: Use ``TUri`` instead. + ## **Deprecated since 0.9.6**: Use ``Uri`` instead. url = url / a -proc parseAuthority(authority: string, result: var TUri) = +proc parseAuthority(authority: string, result: var Uri) = var i = 0 var inPort = false while true: @@ -65,7 +65,7 @@ proc parseAuthority(authority: string, result: var TUri) = result.hostname.add(authority[i]) i.inc -proc parsePath(uri: string, i: var int, result: var TUri) = +proc parsePath(uri: string, i: var int, result: var Uri) = i.inc parseUntil(uri, result.path, {'?', '#'}, i) @@ -82,11 +82,11 @@ proc parsePath(uri: string, i: var int, result: var TUri) = i.inc # Skip '#' i.inc parseUntil(uri, result.anchor, {}, i) -proc initUri(): TUri = - result = TUri(scheme: "", username: "", password: "", hostname: "", port: "", +proc initUri(): Uri = + result = Uri(scheme: "", username: "", password: "", hostname: "", port: "", path: "", query: "", anchor: "") -proc parseUri*(uri: string): TUri = +proc parseUri*(uri: string): Uri = ## Parses a URI. result = initUri() @@ -113,7 +113,7 @@ proc parseUri*(uri: string): TUri = var authority = "" i.inc parseUntil(uri, authority, {'/', '?', '#'}, i) if authority == "": - raise newException(EInvalidValue, "Expected authority got nothing.") + raise newException(ValueError, "Expected authority got nothing.") parseAuthority(authority, result) # Path @@ -150,7 +150,7 @@ proc removeDotSegments(path: string): string = result = collection.join("/") if endsWithSlash: result.add '/' -proc merge(base, reference: TUri): string = +proc merge(base, reference: Uri): string = # http://tools.ietf.org/html/rfc3986#section-5.2.3 if base.hostname != "" and base.path == "": '/' & reference.path @@ -161,7 +161,7 @@ proc merge(base, reference: TUri): string = else: base.path[0 .. lastSegment] & reference.path -proc combine*(base: TUri, reference: TUri): TUri = +proc combine*(base: Uri, reference: Uri): Uri = ## Combines a base URI with a reference URI. ## ## This uses the algorithm specified in @@ -216,13 +216,13 @@ proc combine*(base: TUri, reference: TUri): TUri = result.scheme = base.scheme result.anchor = reference.anchor -proc combine*(uris: varargs[TUri]): TUri = +proc combine*(uris: varargs[Uri]): Uri = ## Combines multiple URIs together. result = uris[0] for i in 1 .. <uris.len: result = combine(result, uris[i]) -proc `/`*(x: TUri, path: string): TUri = +proc `/`*(x: Uri, path: string): Uri = ## Concatenates the path specified to the specified URI's path. ## ## Contrary to the ``combine`` procedure you do not have to worry about @@ -251,7 +251,7 @@ proc `/`*(x: TUri, path: string): TUri = result.path.add '/' result.path.add(path) -proc `$`*(u: TUri): string = +proc `$`*(u: Uri): string = ## Returns the string representation of the specified URI object. result = "" if u.scheme.len > 0: diff --git a/tests/async/tasyncawait.nim b/tests/async/tasyncawait.nim index 5165b0f06..13d531387 100644 --- a/tests/async/tasyncawait.nim +++ b/tests/async/tasyncawait.nim @@ -53,9 +53,7 @@ proc createServer(port: TPort) {.async.} = discard server.SocketHandle.listen() while true: - var client = await accept(server) - asyncCheck readMessages(client) - # TODO: Test: readMessages(disp, await disp.accept(server)) + asyncCheck readMessages(await accept(server)) asyncCheck createServer(TPort(10335)) asyncCheck launchSwarm(TPort(10335)) diff --git a/tests/async/tasynciossl.nim b/tests/async/tasynciossl.nim index b0222e4ff..118b9e74d 100644 --- a/tests/async/tasynciossl.nim +++ b/tests/async/tasynciossl.nim @@ -47,7 +47,7 @@ proc serverAccept(s: PAsyncSocket) = proc launchSwarm(disp: var PDispatcher, port: TPort, count: int, buffered = true, useSSL = false) = for i in 1..count: - var client = AsyncSocket() + var client = asyncSocket() when defined(ssl): if useSSL: ctx1.wrapSocket(client) @@ -56,7 +56,7 @@ proc launchSwarm(disp: var PDispatcher, port: TPort, count: int, client.connect("localhost", port) proc createSwarm(port: TPort, buffered = true, useSSL = false) = - var server = AsyncSocket() + var server = asyncSocket() when defined(ssl): if useSSL: ctx.wrapSocket(server) diff --git a/tests/async/tasyncudp.nim b/tests/async/tasyncudp.nim index fd7f3d568..2a7ed40bf 100644 --- a/tests/async/tasyncudp.nim +++ b/tests/async/tasyncudp.nim @@ -42,14 +42,14 @@ proc swarmConnect(s: PAsyncSocket) = proc createClient(disp: var PDispatcher, port: TPort, buffered = true) = currentClient.inc() - var client = AsyncSocket(typ = SOCK_DGRAM, protocol = IPPROTO_UDP, + var client = asyncSocket(typ = SOCK_DGRAM, protocol = IPPROTO_UDP, buffered = buffered) client.handleConnect = swarmConnect disp.register(client) client.connect("localhost", port) proc createServer(port: TPort, buffered = true) = - var server = AsyncSocket(typ = SOCK_DGRAM, protocol = IPPROTO_UDP, + var server = asyncSocket(typ = SOCK_DGRAM, protocol = IPPROTO_UDP, buffered = buffered) server.handleRead = serverRead disp.register(server) @@ -75,4 +75,4 @@ while true: break assert msgCount == messagesToSend * serverCount * swarmSize -echo(msgCount) \ No newline at end of file +echo(msgCount) diff --git a/tools/nimweb.nim b/tools/nimweb.nim index 74f561b52..bbd3776d7 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -396,8 +396,8 @@ proc buildNewsRss(c: var TConfigData, destPath: string) = generateRss(destFilename, parseNewsTitles(srcFilename)) proc buildJS(destPath: string) = - exec("nim js -d:release --out:$1 web/babelpkglist.nim" % - [destPath / "babelpkglist.js"]) + exec("nim js -d:release --out:$1 web/nimblepkglist.nim" % + [destPath / "nimblepkglist.js"]) proc buildWebsite(c: var TConfigData) = const diff --git a/web/babelpkglist.nim b/web/babelpkglist.nim index aeea57a0d..7070f281b 100644 --- a/web/babelpkglist.nim +++ b/web/babelpkglist.nim @@ -41,6 +41,7 @@ proc processContent(content: string) = dot = if desc.high > 0 and desc[desc.high] in endings: "" else: "." listItem = li(a(href=pkgWeb, pkg["name"].str), " ", desc & dot) if pkg["url"].str.startsWith("git://github.com/nimrod-code") or + pkg["url"].str.startsWith("git://github.com/nim-lang") or "official" in pkg["tags"].elems: officialCount.inc officialList.add listItem & "\n" @@ -52,14 +53,14 @@ proc processContent(content: string) = officialPkgListDiv.innerHTML = p("There are currently " & $officialCount & - " official packages in the Babel package repository.") & + " official packages in the Nimble package repository.") & ul(officialList) var unofficialPkgListDiv = document.getElementById("unofficialPkgList") unofficialPkgListDiv.innerHTML = p("There are currently " & $unofficialCount & - " unofficial packages in the Babel package repository.") & + " unofficial packages in the Nimble package repository.") & ul(unofficialList) proc gotPackageList(apiReply: TData) {.exportc.} = diff --git a/web/news.txt b/web/news.txt index f95de759b..d1d23aebd 100644 --- a/web/news.txt +++ b/web/news.txt @@ -6,14 +6,67 @@ News 2014-10-21 Version 0.10.2 released ================================== - This release is the latest release before the release canditates for version - 1.0 roll in. Starting with version 0.10.2 the rename of the language to Nim - is officially complete. As the list of language changes is quite long it's - much more work to update the average Nim project than used to be the case. - However there is a new tool, `nimfix <nimfix.html>`_ to help you - in updating your code from Nimrod to Nim. This tool is unfortunately not - perfect but has been used to update thousands of lines of code successfully. - + This release marks the completion of a very important change to the project: + the official renaming from Nimrod to Nim. Version 0.10.2 contains many language + changes, some of which may break your existing code. For your convenience, we + added a new tool called `nimfix <nimfix.html>`_ that will help you convert your + existing projects so that it works with the latest version of the compiler. + + Progress towards version 1.0 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Although Nim is still pre-1.0, we were able to keep the number of breaking + changes to a minimum so far. Starting with version 1.0, we will not introduce + any breaking changes between major release versions. + One of Nim's goals is to ensure that the compiler is as efficient as possible. + Take a look at the + `latest benchmarks <https://github.com/logicchains/LPATHBench/blob/master/writeup.md>`_, + which show that Nim is consistently near + the top and already nearly as fast as C and C++. Recent developments, such as + the new ``asyncdispatch`` module will allow you to write efficient web server + applications using non-blocking code. Nim now also has a built-in thread pool + for lightweight threading through the use of ``spawn``. + + The unpopular "T" and "P" prefixes on types have been deprecated. Nim also + became more expressive by weakening the distinction between statements and + epxressions. We also added new and searchable forums, a new website, and our + documentation generator ``docgen`` has seen major improvements. + + What's left to be done + ~~~~~~~~~~~~~~~~~~~~~~ + + The 1.0 release is actually very close. There are only a couple of last + things that need to be done: + + * Implementing static[T] properly + * Support for the overloading of the assignment operator + + Of course, the 1.0 release is not an end to the development of Nim. + It is very much the beginning and we will be fleshing out the then + stable language. + + Nimble and other Nim tools + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Outside of the language and the compiler itself many Nim tools have seen + considerable improvements. + + Babel the Nim package manager has been renamed to Nimble. Nimble's purpose + is the installation of packages containing libraries and/or applications + written in Nim. + Even though Nimble is still very young it already is very + functional. It can install packages by name, it does so by accessing a + packages repository which is hosted on a Github repo. Packages can also be + installed via a Git repo URL or Mercurial repo URL. The package repository + is searchable through Nimble. Anyone is free to add their own packages to + the package repository by forking the + `nim-lang/packages <https://github.com/nim-lang/packages>`_ repo and creating + a pull request. Nimble is fully cross-platform and should be fully functional + on all major operating systems. + It is of course completely written in Nim. + + Changelog + ~~~~~~~~~ Changes affecting backwards compatibility ----------------------------------------- @@ -93,7 +146,7 @@ News statement. - There is a new tool, `nimfix <nimfix.html>`_ to help you in updating your code from Nimrod to Nim. - + - The compiler's output has been prettified. Library Additions ----------------- @@ -103,7 +156,41 @@ News - ``system.setupForeignThreadGc`` can be used for better interaction with foreign libraries that create threads and run a Nim callback from these foreign threads. - + - List comprehensions have been implemented as a macro in the ``future`` + module. + - The new Async module (``asyncnet``) now supports SSL. + - The ``smtp`` module now has an async implementation. + - Added module ``asyncfile`` which implements asynchronous file reading + and writing. + - ``osproc.kill`` has been added. + - ``asyncnet`` and ``asynchttpserver`` now support ``SO_REUSEADDR``. + + Bugfixes + -------- + + - ``nil`` and ``NULL`` are now preserved between Nim and databases in the + ``db_*`` modules. + - Fixed issue with OS module in non-unicode mode on Windows. + - Fixed issue with ``x.low`` + (`#1366 <https://github.com/Araq/Nim/issues/1366>`_). + - Fixed tuple unpacking issue inside closure iterators + (`#1067 <https://github.com/Araq/Nim/issues/1067>`_). + - Fixed ENDB compilation issues. + - Many ``asynchttpserver`` fixes. + - Macros can now keep global state across macro calls + (`#903 <https://github.com/Araq/Nim/issues/903>`_). + - ``osproc`` fixes on Windows. + - ``osproc.terminate`` fixed. + - Improvements to exception handling in async procedures. + (`#1487 <https://github.com/Araq/Nim/issues/1487>`_). + - ``try`` now works at compile-time. + - Fixes ``T = ref T`` to be an illegal recursive type. + - Self imports are now disallowed. + - Improved effect inference. + - Fixes for the ``math`` module on Windows. + - User defined pragmas will now work for generics that have + been instantiated in different modules. + - Fixed queue exhaustion bug. 2014-12-09 New website design! ============================== |