summary refs log tree commit diff stats
path: root/lib/pure
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-09-10 22:56:26 +0200
committerAraq <rumpf_a@web.de>2014-09-10 22:56:26 +0200
commit758d8e11d9a4aa1d15572c246e63ed5ea913aad9 (patch)
treeef590cbe882efbf66e3f2539178e1094e819af16 /lib/pure
parent63c9c2877e48b14f8981366d6e110f913a8b604a (diff)
parent055ed5149fba025f210022acea5a0b31b221b521 (diff)
downloadNim-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.nim77
-rw-r--r--lib/pure/asyncfile.nim34
-rw-r--r--lib/pure/asynchttpserver.nim1
-rw-r--r--lib/pure/asyncio.nim1
-rw-r--r--lib/pure/cgi.nim13
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, "&quot;")
   else: add(dest, c)
 
-proc XMLencode*(s: string): string =
+proc xmlEncode*(s: string): string =
   ## Encodes a value to be XML safe:
   ## * ``"`` is replaced by ``&quot;``
   ## * ``<`` is replaced by ``&lt;``
@@ -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)