diff options
author | Araq <rumpf_a@web.de> | 2014-09-10 22:56:26 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2014-09-10 22:56:26 +0200 |
commit | 758d8e11d9a4aa1d15572c246e63ed5ea913aad9 (patch) | |
tree | ef590cbe882efbf66e3f2539178e1094e819af16 /lib/pure | |
parent | 63c9c2877e48b14f8981366d6e110f913a8b604a (diff) | |
parent | 055ed5149fba025f210022acea5a0b31b221b521 (diff) | |
download | Nim-758d8e11d9a4aa1d15572c246e63ed5ea913aad9.tar.gz |
Merge branch 'bigbreak' of https://github.com/Araq/Nimrod into bigbreak
Diffstat (limited to 'lib/pure')
-rw-r--r-- | lib/pure/asyncdispatch.nim | 77 | ||||
-rw-r--r-- | lib/pure/asyncfile.nim | 34 | ||||
-rw-r--r-- | lib/pure/asynchttpserver.nim | 1 | ||||
-rw-r--r-- | lib/pure/asyncio.nim | 1 | ||||
-rw-r--r-- | lib/pure/cgi.nim | 13 |
5 files changed, 60 insertions, 66 deletions
diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index e521b8e64..5363d8862 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -796,6 +796,7 @@ else: else: # FD no longer a part of the selector. Likely been closed # (e.g. socket disconnected). + discard processTimers(p) @@ -972,29 +973,50 @@ template createCb*(retFutureSym, iteratorNameSym, cb() #{.pop.} proc generateExceptionCheck(futSym, - exceptBranch, rootReceiver, fromNode: PNimrodNode): PNimrodNode {.compileTime.} = - if exceptBranch == nil: + tryStmt, rootReceiver, fromNode: PNimrodNode): PNimrodNode {.compileTime.} = + if tryStmt.kind == nnkNilLit: result = rootReceiver else: - if exceptBranch[0].kind == nnkStmtList: - result = newIfStmt( - (newDotExpr(futSym, newIdentNode("failed")), - exceptBranch[0] - ) - ) - else: - expectKind(exceptBranch[1], nnkStmtList) - result = newIfStmt( - (newDotExpr(futSym, newIdentNode("failed")), - newIfStmt( - (infix(newDotExpr(futSym, newIdentNode("error")), "of", exceptBranch[0]), - exceptBranch[1]) - ) - ) - ) + var exceptionChecks: seq[tuple[cond, body: PNimrodNode]] = @[] + let errorNode = newDotExpr(futSym, newIdentNode("error")) + for i in 1 .. <tryStmt.len: + let exceptBranch = tryStmt[i] + if exceptBranch[0].kind == nnkStmtList: + exceptionChecks.add((newIdentNode("true"), exceptBranch[0])) + else: + var exceptIdentCount = 0 + var ifCond: PNimrodNode + for i in 0 .. <exceptBranch.len: + let child = exceptBranch[i] + if child.kind == nnkIdent: + let cond = infix(errorNode, "of", child) + if exceptIdentCount == 0: + ifCond = cond + else: + ifCond = infix(ifCond, "or", cond) + else: + break + exceptIdentCount.inc + + expectKind(exceptBranch[exceptIdentCount], nnkStmtList) + exceptionChecks.add((ifCond, exceptBranch[exceptIdentCount])) + # -> -> else: raise futSym.error + exceptionChecks.add((newIdentNode("true"), + newNimNode(nnkRaiseStmt).add(errorNode))) + # Read the future if there is no error. + # -> else: futSym.read let elseNode = newNimNode(nnkElse, fromNode) elseNode.add newNimNode(nnkStmtList, fromNode) elseNode[0].add rootReceiver + + let ifBody = newStmtList() + ifBody.add newCall(newIdentNode("setCurrentException"), errorNode) + ifBody.add newIfStmt(exceptionChecks) + ifBody.add newCall(newIdentNode("setCurrentException"), newNilLit()) + + result = newIfStmt( + (newDotExpr(futSym, newIdentNode("failed")), ifBody) + ) result.add elseNode template createVar(result: var PNimrodNode, futSymName: string, @@ -1006,11 +1028,11 @@ template createVar(result: var PNimrodNode, futSymName: string, result.add newVarStmt(futSym, asyncProc) # -> var future<x> = y result.add newNimNode(nnkYieldStmt, fromNode).add(futSym) # -> yield future<x> valueReceiver = newDotExpr(futSym, newIdentNode("read")) # -> future<x>.read - result.add generateExceptionCheck(futSym, exceptBranch, rootReceiver, fromNode) + result.add generateExceptionCheck(futSym, tryStmt, rootReceiver, fromNode) proc processBody(node, retFutureSym: PNimrodNode, subTypeIsVoid: bool, - exceptBranch: PNimrodNode): PNimrodNode {.compileTime.} = + tryStmt: PNimrodNode): PNimrodNode {.compileTime.} = #echo(node.treeRepr) result = node case node.kind @@ -1024,7 +1046,7 @@ proc processBody(node, retFutureSym: PNimrodNode, result.add newCall(newIdentNode("complete"), retFutureSym) else: result.add newCall(newIdentNode("complete"), retFutureSym, - node[0].processBody(retFutureSym, subTypeIsVoid, exceptBranch)) + node[0].processBody(retFutureSym, subTypeIsVoid, tryStmt)) result.add newNimNode(nnkReturnStmt, node).add(newNilLit()) return # Don't process the children of this return stmt @@ -1079,7 +1101,7 @@ proc processBody(node, retFutureSym: PNimrodNode, res: PNimrodNode): bool {.compileTime.} = result = false while i < n[0].len: - var processed = processBody(n[0][i], retFutureSym, subTypeIsVoid, n[1]) + var processed = processBody(n[0][i], retFutureSym, subTypeIsVoid, n) if processed.kind != n[0][i].kind or processed.len != n[0][i].len: expectKind(processed, nnkStmtList) expectKind(processed[2][1], nnkElse) @@ -1099,7 +1121,7 @@ proc processBody(node, retFutureSym: PNimrodNode, else: discard for i in 0 .. <result.len: - result[i] = processBody(result[i], retFutureSym, subTypeIsVoid, exceptBranch) + result[i] = processBody(result[i], retFutureSym, subTypeIsVoid, tryStmt) proc getName(node: PNimrodNode): string {.compileTime.} = case node.kind @@ -1193,7 +1215,7 @@ macro async*(prc: stmt): stmt {.immediate.} = result[6] = outerProcBody #echo(treeRepr(result)) - #if prc[0].getName == "getFile": + #if prc[0].getName == "catch": # echo(toStrLit(result)) proc recvLine*(socket: TAsyncFD): Future[string] {.async.} = @@ -1209,6 +1231,8 @@ proc recvLine*(socket: TAsyncFD): Future[string] {.async.} = ## If the socket is disconnected in the middle of a line (before ``\r\L`` ## is read) then line will be set to ``""``. ## The partial line **will be lost**. + ## + ## **Warning**: This assumes that lines are delimited by ``\r\l``. template addNLIfEmpty(): stmt = if result.len == 0: @@ -1221,9 +1245,8 @@ proc recvLine*(socket: TAsyncFD): Future[string] {.async.} = if c.len == 0: return "" if c == "\r": - c = await recv(socket, 1, {SocketFlag.SafeDisconn, SocketFlag.Peek}) - if c.len > 0 and c == "\L": - discard await recv(socket, 1) + c = await recv(socket, 1) + assert c == "\l" addNLIfEmpty() return elif c == "\L": diff --git a/lib/pure/asyncfile.nim b/lib/pure/asyncfile.nim index 6c8a87184..e861c6e48 100644 --- a/lib/pure/asyncfile.nim +++ b/lib/pure/asyncfile.nim @@ -34,26 +34,7 @@ type fd: TAsyncFd offset: int64 -# TODO: These will be nil in other threads? -var - asyncStdin* {.threadvar.}: AsyncFile ## Asynchronous stdin handle - asyncStdout* {.threadvar.}: AsyncFile ## Asynchronous stdout handle - asyncStderr* {.threadvar.}: AsyncFile ## Asynchronous stderr handle - when defined(windows): - asyncStdin = AsyncFile( - fd: getStdHandle(STD_INPUT_HANDLE).TAsyncFd, - offset: 0 - ) - asyncStdout = AsyncFile( - fd: getStdHandle(STD_OUTPUT_HANDLE).TAsyncFd, - offset: 0 - ) - asyncStderr = AsyncFile( - fd: getStdHandle(STD_ERROR_HANDLE).TAsyncFd, - offset: 0 - ) - proc getDesiredAccess(mode: TFileMode): int32 = case mode of fmRead: @@ -73,19 +54,6 @@ when defined(windows): else: CREATE_NEW else: - asyncStdin = AsyncFile( - fd: STDIN_FILENO.TAsyncFd, - offset: 0 - ) - asyncStdout = AsyncFile( - fd: STDOUT_FILENO.TAsyncFd, - offset: 0 - ) - asyncStderr = AsyncFile( - fd: STDERR_FILENO.TAsyncFd, - offset: 0 - ) - proc getPosixFlags(mode: TFileMode): cint = case mode of fmRead: @@ -100,7 +68,7 @@ else: result = O_RDWR result = result or O_NONBLOCK -proc getFileSize*(f: AsyncFile): int64 = +proc getFileSize(f: AsyncFile): int64 = ## Retrieves the specified file's size. when defined(windows): var high: DWord diff --git a/lib/pure/asynchttpserver.nim b/lib/pure/asynchttpserver.nim index 70a865ed5..931a0c15a 100644 --- a/lib/pure/asynchttpserver.nim +++ b/lib/pure/asynchttpserver.nim @@ -183,6 +183,7 @@ proc processClient(client: PAsyncSocket, address: string, # header states otherwise. # In HTTP 1.0 we assume that the connection should not be persistent. # Unless the connection header states otherwise. + discard else: request.client.close() break diff --git a/lib/pure/asyncio.nim b/lib/pure/asyncio.nim index 5e757a03b..3de947dca 100644 --- a/lib/pure/asyncio.nim +++ b/lib/pure/asyncio.nim @@ -247,6 +247,7 @@ proc asyncSockHandleWrite(h: RootRef) = # Apparently the socket cannot be written to. Even though select # just told us that it can be... This used to be an assert. Just # do nothing instead. + discard elif bytesSent != sock.sendBuffer.len: sock.sendBuffer = sock.sendBuffer[bytesSent .. -1] elif bytesSent == sock.sendBuffer.len: diff --git a/lib/pure/cgi.nim b/lib/pure/cgi.nim index b30f8dd33..d5690bf51 100644 --- a/lib/pure/cgi.nim +++ b/lib/pure/cgi.nim @@ -31,7 +31,7 @@ import strutils, os, strtabs, cookies -proc URLencode*(s: string): string = +proc urlEncode*(s: string): string = ## Encodes a value to be HTTP safe: This means that characters in the set ## ``{'A'..'Z', 'a'..'z', '0'..'9', '_'}`` are carried over to the result, ## a space is converted to ``'+'`` and every other character is encoded as @@ -52,7 +52,7 @@ proc handleHexChar(c: char, x: var int) {.inline.} = of 'A'..'F': x = (x shl 4) or (ord(c) - ord('A') + 10) else: assert(false) -proc URLdecode*(s: string): string = +proc urlDecode*(s: string): string = ## Decodes a value from its HTTP representation: This means that a ``'+'`` ## is converted to a space, ``'%xx'`` (where ``xx`` denotes a hexadecimal ## value) is converted to the character with ordinal number ``xx``, and @@ -82,7 +82,7 @@ proc addXmlChar(dest: var string, c: char) {.inline.} = of '\"': add(dest, """) else: add(dest, c) -proc XMLencode*(s: string): string = +proc xmlEncode*(s: string): string = ## Encodes a value to be XML safe: ## * ``"`` is replaced by ``"`` ## * ``<`` is replaced by ``<`` @@ -99,7 +99,8 @@ type methodPost, ## query uses the POST method methodGet ## query uses the GET method -{.deprecated: [TRequestMethod: RequestMethod, ECgi: CgiError].} +{.deprecated: [TRequestMethod: RequestMethod, ECgi: CgiError, + URLencode: urlEncode, XMLencode: xmlEncode, URLdecode: urlDecode].} proc cgiError*(msg: string) {.noreturn.} = ## raises an ECgi exception with message `msg`. @@ -331,9 +332,9 @@ proc setTestData*(keysvalues: varargs[string]) = var i = 0 var query = "" while i < keysvalues.len: - add(query, URLencode(keysvalues[i])) + add(query, urlEncode(keysvalues[i])) add(query, '=') - add(query, URLencode(keysvalues[i+1])) + add(query, urlEncode(keysvalues[i+1])) add(query, '&') inc(i, 2) putEnv("QUERY_STRING", query) |