summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xdoc/lib.txt36
-rwxr-xr-xlib/devel/httpserver.nim4
-rwxr-xr-xlib/impure/db_mysql.nim158
-rwxr-xr-xlib/impure/db_postgres.nim82
-rwxr-xr-xlib/impure/dialogs.nim2
-rwxr-xr-xlib/impure/web.nim7
-rwxr-xr-xlib/newwrap/cairo/cairo.nim2
-rwxr-xr-xlib/pure/parseutils.nim7
-rwxr-xr-xlib/pure/re.nim2
-rwxr-xr-xlib/pure/unicode.nim2
-rwxr-xr-xrod/nimrod.ini11
-rwxr-xr-xweb/nimrod.ini4
-rwxr-xr-xweb/question.txt9
13 files changed, 214 insertions, 112 deletions
diff --git a/doc/lib.txt b/doc/lib.txt
index d523bf559..3252a2c73 100755
--- a/doc/lib.txt
+++ b/doc/lib.txt
@@ -5,7 +5,7 @@ Nimrod Standard Library
 :Author: Andreas Rumpf
 :Version: |nimrodversion|
 
-..
+.. contents::
 
   "The good thing about reinventing the wheel is that you can get a round one."
 
@@ -43,6 +43,9 @@ String handling
   string into uppercase, splitting a string into substrings, searching for
   substrings, replacing substrings.
 
+* `parseutils <parseutils.html>`
+  This module contains helpers for parsing tokens, numbers, identifiers, etc.
+
 * `strtabs <strtabs.html>`_
   The ``strtabs`` module implements an efficient hash table that is a mapping
   from strings to strings. Supports a case-sensitive, case-insensitive and
@@ -59,6 +62,11 @@ String handling
 * `pegs <pegs.html>`_
   This module contains procedures and operators for handling PEGs.
 
+* `ropes <ropes.html>`_
+  This module contains support for a *rope* data type.
+  Ropes can represent very long strings efficiently; especially concatenation
+  is done in O(1) instead of O(n).
+
 
 Generic Operating System Services
 ---------------------------------
@@ -106,6 +114,19 @@ Internet Protocols and Support
 * `cgi <cgi.html>`_
   This module implements helpers for CGI applictions. 
 
+* `sockets <sockets.html>`
+  This module implements a simple portable type-safe sockets layer.
+
+* `browsers <browsers.html>`
+  This module implements procs for opening URLs with the user's default 
+  browser.
+  
+* `httpserver <httpserver.html>`
+  This module implements a simple HTTP server.
+  
+* `httpclient <httpclient.html>`
+  This module implements a simple HTTP client. 
+
 
 Parsers
 -------
@@ -174,6 +195,19 @@ Impure libraries
   web like loading the contents of a web page from an URL.
 
 
+Database support
+----------------
+
+* `db_postgres <db_postgres.html>`_
+  A higher level PostgreSQL database wrapper. The same interface is implemented
+  for other databases too.
+ 
+* `db_mysql <db_mysql.html>`_
+  A higher level mySQL database wrapper. The same interface is implemented
+  for other databases too.
+
+
+
 Wrappers
 ========
 
diff --git a/lib/devel/httpserver.nim b/lib/devel/httpserver.nim
index be317c952..61d95cc2e 100755
--- a/lib/devel/httpserver.nim
+++ b/lib/devel/httpserver.nim
@@ -174,7 +174,7 @@ proc acceptRequest(client: TSocket) =
       executeCgi(client, path, query, meth)
 
 type
-  TServer* = object
+  TServer* = object       ## contains the current server state
     socket: TSocket
     port: TPort
     client*: TSocket      ## the socket to write the file data to
@@ -187,6 +187,7 @@ proc open*(s: var TServer, port = TPort(0)) =
   if s.socket == InvalidSocket: OSError()
   bindAddr(s.socket)
   listen(s.socket)
+  
   s.port = getSockName(s.socket)
   s.client = InvalidSocket
   s.path = ""
@@ -215,6 +216,7 @@ proc next*(s: var TServer) =
     unimplemented(s.client)
 
 proc close*(s: TServer) =
+  ## closes the server (and the socket the server uses).
   close(s.socket)
 
 proc run*(handleRequest: proc (client: TSocket, path, query: string): bool, 
diff --git a/lib/impure/db_mysql.nim b/lib/impure/db_mysql.nim
index 386da0cf7..ee37a88c3 100755
--- a/lib/impure/db_mysql.nim
+++ b/lib/impure/db_mysql.nim
@@ -1,14 +1,25 @@
-# Nimrod mySQL database wrapper
-# (c) 2009 Andreas Rumpf
+#
+#
+#            Nimrod's Runtime Library
+#        (c) Copyright 2010 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## A higher level `mySQL`:idx: database wrapper. The same interface is 
+## implemented for other databases too.
 
 import strutils, mysql
 
 type
-  TDbHandle* = PMySQL
-  TRow* = seq[string]
-  EDb* = object of EIO
-  
-proc dbError(db: TDbHandle) {.noreturn.} = 
+  TDbConn* = PMySQL    ## encapsulates a database connection
+  TRow* = seq[string]  ## a row of a dataset
+  EDb* = object of EIO ## exception that is raised if a database error occurs
+
+  TSqlQuery* = distinct string ## an SQL query string
+ 
+proc dbError(db: TDbConn) {.noreturn.} = 
   ## raises an EDb exception.
   var e: ref EDb
   new(e)
@@ -23,13 +34,13 @@ proc dbError*(msg: string) {.noreturn.} =
   raise e
 
 when false:
-  proc dbQueryOpt*(db: TDbHandle, query: string, args: openarray[string]) =
+  proc dbQueryOpt*(db: TDbConn, query: string, args: openarray[string]) =
     var stmt = mysql_stmt_init(db)
     if stmt == nil: dbError(db)
     if mysql_stmt_prepare(stmt, query, len(query)) != 0: 
       dbError(db)
     var 
-      bind: seq[MYSQL_BIND]
+      binding: seq[MYSQL_BIND]
     discard mysql_stmt_close(stmt)
 
 proc dbQuote(s: string): string =
@@ -49,33 +60,16 @@ proc dbFormat(formatstr: string, args: openarray[string]): string =
     else: 
       add(result, c)
   
-proc dbTryQuery*(db: TDbHandle, query: string, args: openarray[string]): bool =
+proc TryQuery*(db: TDbConn, query: string, args: openarray[string]): bool =
+  ## tries to execute the query and returns true if successful, false otherwise.
   var q = dbFormat(query, args)
   return mysqlRealQuery(db, q, q.len) == 0'i32
 
-proc dbQuery*(db: TDbHandle, query: string, args: openarray[string]) =
+proc Query*(db: TDbConn, query: string, args: openarray[string]) =
+  ## executes the query and raises EDB if not successful.
   var q = dbFormat(query, args)
   if mysqlRealQuery(db, q, q.len) != 0'i32: dbError(db)
-  
-proc dbTryInsertID*(db: TDbHandle, query: string, 
-                    args: openarray[string]): int64 =
-  var q = dbFormat(query, args)
-  if mysqlRealQuery(db, q, q.len) != 0'i32: 
-    result = -1'i64
-  else:
-    result = mysql_insert_id(db)
-  
-proc dbInsertID*(db: TDbHandle, query: string, args: openArray[string]): int64 = 
-  result = dbTryInsertID(db, query, args)
-  if result < 0: dbError(db)
-  
-proc dbQueryAffectedRows*(db: TDbHandle, query: string, 
-                          args: openArray[string]): int64 = 
-  ## runs the query (typically "UPDATE") and returns the
-  ## number of affected rows
-  dbQuery(db, query, args)
-  result = mysql_affected_rows(db)
-  
+    
 proc newRow(L: int): TRow = 
   newSeq(result, L)
   for i in 0..L-1: result[i] = ""
@@ -84,11 +78,32 @@ proc properFreeResult(sqlres: PMYSQL_RES, row: cstringArray) =
   if row != nil:
     while mysqlFetchRow(sqlres) != nil: nil
   mysqlFreeResult(sqlres)
+  
+iterator FastRows*(db: TDbConn, query: string,
+                   args: openarray[string]): TRow =
+  ## executes the query and iterates over the result dataset. This is very 
+  ## fast, but potenially dangerous: If the for-loop-body executes another
+  ## query, the results can be undefined. For Postgres it is safe though.
+  Query(db, query, args)
+  var sqlres = mysqlUseResult(db)
+  if sqlres != nil:
+    var L = int(mysql_num_fields(sqlres))
+    var result = newRow(L)
+    var row: cstringArray
+    while true:
+      row = mysqlFetchRow(sqlres)
+      if row == nil: break
+      for i in 0..L-1: 
+        setLen(result[i], 0)
+        add(result[i], row[i])
+      yield result
+    properFreeResult(sqlres, row)
 
-proc dbGetAllRows*(db: TDbHandle, query: string, 
-                   args: openarray[string]): seq[TRow] =
+proc GetAllRows*(db: TDbConn, query: string, 
+                 args: openarray[string]): seq[TRow] =
+  ## executes the query and returns the whole result dataset.
   result = @[]
-  dbQuery(db, query, args)
+  Query(db, query, args)
   var sqlres = mysqlUseResult(db)
   if sqlres != nil:
     var L = int(mysql_num_fields(sqlres))
@@ -103,43 +118,56 @@ proc dbGetAllRows*(db: TDbHandle, query: string,
       inc(j)
     mysqlFreeResult(sqlres)
 
-iterator dbRows*(db: TDbHandle, query: string, 
-                 args: openarray[string]): TRow =
-  for r in items(dbGetAllRows(db, query, args)): yield r
-  
-iterator dbFastRows*(db: TDbHandle, query: string,
-                     args: openarray[string]): TRow =
-  # this is carefully optimized, so that the memory is reused!
-  dbQuery(db, query, args)
-  var sqlres = mysqlUseResult(db)
-  if sqlres != nil:
-    var L = int(mysql_num_fields(sqlres))
-    var result = newRow(L)
-    var row: cstringArray
-    while true:
-      row = mysqlFetchRow(sqlres)
-      if row == nil: break
-      for i in 0..L-1: 
-        setLen(result[i], 0)
-        add(result[i], row[i])
-      yield result
-    properFreeResult(sqlres, row)
+iterator Rows*(db: TDbConn, query: string, 
+               args: openarray[string]): TRow =
+  ## same as `FastRows`, but slower and safe.
+  for r in items(GetAllRows(db, query, args)): yield r
 
-proc dbGetValue*(db: TDbHandle, query: string, 
-                 args: openarray[string]): string = 
+proc GetValue*(db: TDbConn, query: string, 
+               args: openarray[string]): string = 
+  ## executes the query and returns the result dataset's the first column 
+  ## of the first row. Returns "" if the dataset contains no rows. This uses
+  ## `FastRows`, so it inherits its fragile behaviour.
   result = ""
-  for row in dbFastRows(db, query, args): 
+  for row in FastRows(db, query, args): 
     result = row[0]
     break
 
-proc dbClose*(db: TDbHandle) = 
+proc TryInsertID*(db: TDbConn, query: string, 
+                  args: openarray[string]): int64 =
+  ## executes the query (typically "INSERT") and returns the 
+  ## generated ID for the row or -1 in case of an error.
+  var q = dbFormat(query, args)
+  if mysqlRealQuery(db, q, q.len) != 0'i32: 
+    result = -1'i64
+  else:
+    result = mysql_insert_id(db)
+  
+proc InsertID*(db: TDbConn, query: string, args: openArray[string]): int64 = 
+  ## executes the query (typically "INSERT") and returns the 
+  ## generated ID for the row.
+  result = TryInsertID(db, query, args)
+  if result < 0: dbError(db)
+
+proc QueryAffectedRows*(db: TDbConn, query: string, 
+                        args: openArray[string]): int64 = 
+  ## runs the query (typically "UPDATE") and returns the
+  ## number of affected rows
+  Query(db, query, args)
+  result = mysql_affected_rows(db)
+
+proc Close*(db: TDbConn) = 
+  ## closes the database connection.
   if db != nil: mysqlClose(db)
 
-proc dbOpen*(connection, user, password, database: string): TDbHandle =
+proc Open*(connection, user, password, database: string): TDbConn =
+  ## opens a database connection. Raises `EDb` if the connection could not
+  ## be established.
   result = mysqlInit(nil)
-  if result != nil: 
-    if mysqlRealConnect(result, "", user, password, database, 
-                        0'i32, nil, 0) == nil:
-      dbClose(result)
-      result = nil
+  if result == nil: dbError("could not open database connection") 
+  if mysqlRealConnect(result, "", user, password, database, 
+                      0'i32, nil, 0) == nil:
+    var errmsg = $mysql_error(result)
+    Close(result)
+    dbError(errmsg)
 
diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim
index cac5420d4..3296e688a 100755
--- a/lib/impure/db_postgres.nim
+++ b/lib/impure/db_postgres.nim
@@ -1,20 +1,31 @@
-# Nimrod PostgreSQL database wrapper
-# (c) 2010 Andreas Rumpf
+#
+#
+#            Nimrod's Runtime Library
+#        (c) Copyright 2010 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## A higher level `PostgreSQL`:idx: database wrapper. This interface 
+## is implemented for other databases too.
 
 import strutils, postgres
 
 type
-  TDbConn* = PPGconn  ## encapsulates a database connection
+  TDbConn* = PPGconn   ## encapsulates a database connection
   TRow* = seq[string]  ## a row of a dataset
   EDb* = object of EIO ## exception that is raised if a database error occurs
   
   TSqlQuery* = distinct string ## an SQL query string
   
 proc sql*(query: string): TSqlQuery {.noSideEffect, inline.} =  
-  ## constructs a TSqlQuery from the string `query`: If assertions are turned 
-  ## off, it does nothing. If assertions are turned on, the string is checked
-  ## for SQL security holes. This is supposed to be used as a 
-  ## raw-string-literal modifier: ``sql"update user set counter = counter + 1"``
+  ## constructs a TSqlQuery from the string `query`. This is supposed to be 
+  ## used as a raw-string-literal modifier:
+  ## ``sql"update user set counter = counter + 1"``
+  ##
+  ## If assertions are turned off, it does nothing. If assertions are turned 
+  ## on, later versions will check the string for valid syntax.
   result = TSqlQuery(query)
  
 proc dbError(db: TDbConn) {.noreturn.} = 
@@ -32,8 +43,6 @@ proc dbError*(msg: string) {.noreturn.} =
   raise e
 
 proc dbQuote(s: string): string =
-  #if s.len > 0 and allCharsInSet(s, {'0'..'9'}): result = s
-  #else:
   result = "'"
   for c in items(s):
     if c == '\'': add(result, "''")
@@ -50,15 +59,15 @@ proc dbFormat(formatstr: TSqlQuery, args: openarray[string]): string =
     else: 
       add(result, c)
   
-proc dbTryQuery*(db: TDbConn, query: TSqlQuery, 
-                 args: openarray[string]): bool =
+proc TryQuery*(db: TDbConn, query: TSqlQuery, 
+               args: openarray[string]): bool =
   ## tries to execute the query and returns true if successful, false otherwise.
   var q = dbFormat(query, args)
   var res = PQExec(db, q)
   result = PQresultStatus(res) == PGRES_COMMAND_OK
   PQclear(res)
 
-proc dbQuery*(db: TDbConn, query: TSqlQuery, args: openarray[string]) =
+proc Query*(db: TDbConn, query: TSqlQuery, args: openarray[string]) =
   ## executes the query and raises EDB if not successful.
   var q = dbFormat(query, args)
   var res = PQExec(db, q)
@@ -81,8 +90,8 @@ proc setRow(res: PPGresult, r: var TRow, line, cols: int) =
     var x = PQgetvalue(res, line, col)
     add(r[col], x)
   
-iterator dbFastRows*(db: TDbConn, query: TSqlQuery,
-                     args: openarray[string]): TRow =
+iterator FastRows*(db: TDbConn, query: TSqlQuery,
+                   args: openarray[string]): TRow =
   ## executes the query and iterates over the result dataset. This is very 
   ## fast, but potenially dangerous: If the for-loop-body executes another
   ## query, the results can be undefined. For Postgres it is safe though.
@@ -94,49 +103,48 @@ iterator dbFastRows*(db: TDbConn, query: TSqlQuery,
     yield result
   PQclear(res)
 
-proc dbGetAllRows*(db: TDbConn, query: TSqlQuery, 
-                   args: openarray[string]): seq[TRow] =
+proc GetAllRows*(db: TDbConn, query: TSqlQuery, 
+                 args: openarray[string]): seq[TRow] =
   ## executes the query and returns the whole result dataset.
   result = @[]
-  for r in dbFastRows(db, query, args):
+  for r in FastRows(db, query, args):
     result.add(r)
 
-iterator dbRows*(db: TDbConn, query: TSqlQuery, 
-                 args: openarray[string]): TRow =
-  ## same as `dbFastRows`, but slower and safe.
-  for r in items(dbGetAllRows(db, query, args)): yield r
+iterator Rows*(db: TDbConn, query: TSqlQuery, 
+               args: openarray[string]): TRow =
+  ## same as `FastRows`, but slower and safe.
+  for r in items(GetAllRows(db, query, args)): yield r
 
-proc dbGetValue*(db: TDbConn, query: TSqlQuery, 
-                 args: openarray[string]): string = 
+proc GetValue*(db: TDbConn, query: TSqlQuery, 
+               args: openarray[string]): string = 
   ## executes the query and returns the result dataset's the first column 
-  ## of the first row. Returns "" if the dataset contains no rows. This uses
-  ## `dbFastRows`, so it inherits its fragile behaviour.
+  ## of the first row. Returns "" if the dataset contains no rows.
   var x = PQgetvalue(setupQuery(db, query, args), 0, 0)
   result = if isNil(x): "" else: $x
   
-proc dbTryInsertID*(db: TDbConn, query: TSqlQuery, 
-                    args: openarray[string]): int64 =
+proc TryInsertID*(db: TDbConn, query: TSqlQuery, 
+                  args: openarray[string]): int64 =
   ## executes the query (typically "INSERT") and returns the 
   ## generated ID for the row or -1 in case of an error. For Postgre this adds
   ## ``RETURNING id`` to the query, so it only works if your primary key is
   ## named ``id``. 
-  var val = dbGetValue(db, TSqlQuery(string(query) & " RETURNING id"), args)
+  var val = GetValue(db, TSqlQuery(string(query) & " RETURNING id"), args)
   if val.len > 0:
     result = ParseBiggestInt(val)
   else:
     result = -1
 
-proc dbInsertID*(db: TDbConn, query: TSqlQuery, 
-                 args: openArray[string]): int64 = 
+proc InsertID*(db: TDbConn, query: TSqlQuery, 
+               args: openArray[string]): int64 = 
   ## executes the query (typically "INSERT") and returns the 
   ## generated ID for the row. For Postgre this adds
   ## ``RETURNING id`` to the query, so it only works if your primary key is
   ## named ``id``. 
-  result = dbTryInsertID(db, query, args)
+  result = TryInsertID(db, query, args)
   if result < 0: dbError(db)
   
-proc dbQueryAffectedRows*(db: TDbConn, query: TSqlQuery, 
-                          args: openArray[string]): int64 = 
+proc QueryAffectedRows*(db: TDbConn, query: TSqlQuery, 
+                        args: openArray[string]): int64 = 
   ## executes the query (typically "UPDATE") and returns the
   ## number of affected rows.
   var q = dbFormat(query, args)
@@ -145,12 +153,14 @@ proc dbQueryAffectedRows*(db: TDbConn, query: TSqlQuery,
   result = parseBiggestInt($PQcmdTuples(res))
   PQclear(res)
 
-proc dbClose*(db: TDbConn) = 
+proc Close*(db: TDbConn) = 
   ## closes the database connection.
   if db != nil: PQfinish(db)
 
-proc dbOpen*(connection, user, password, database: string): TDbConn =
-  ## opens a database connection.
+proc Open*(connection, user, password, database: string): TDbConn =
+  ## opens a database connection. Raises `EDb` if the connection could not
+  ## be established.
   result = PQsetdbLogin(nil, nil, nil, nil, database, user, password)
   if PQStatus(result) != CONNECTION_OK: dbError(result) # result = nil
 
+
diff --git a/lib/impure/dialogs.nim b/lib/impure/dialogs.nim
index cf81a3d29..31c8ca0ff 100755
--- a/lib/impure/dialogs.nim
+++ b/lib/impure/dialogs.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nimrod's Runtime Library
-#        (c) Copyright 2009 Andreas Rumpf
+#        (c) Copyright 2010 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
diff --git a/lib/impure/web.nim b/lib/impure/web.nim
index 83d1406af..ba74c285a 100755
--- a/lib/impure/web.nim
+++ b/lib/impure/web.nim
@@ -1,7 +1,7 @@
 #

 #

 #            Nimrod's Runtime Library

-#        (c) Copyright 2009 Andreas Rumpf

+#        (c) Copyright 2010 Andreas Rumpf

 #

 #    See the file "copying.txt", included in this

 #    distribution, for details about the copyright.

@@ -16,6 +16,11 @@
 ##
 ## Currently only requesting URLs is implemented. The implementation depends
 ## on the libcurl library!
+##
+## **Deprecated since version 0.8.0:** Use the httpclient module instead. 
+## 
+
+{.deprecated.}
 
 import libcurl, streams
 
diff --git a/lib/newwrap/cairo/cairo.nim b/lib/newwrap/cairo/cairo.nim
index f23162288..77b2efa7b 100755
--- a/lib/newwrap/cairo/cairo.nim
+++ b/lib/newwrap/cairo/cairo.nim
@@ -50,7 +50,7 @@
 
 when defined(windows): 
   const 
-    LIB_CAIRO* = "cairo.dll"
+    LIB_CAIRO* = "libcairo-2.dll"
 else: 
   const 
     LIB_CAIRO* = "libcairo.so"
diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim
index 0878f87eb..04d2a7973 100755
--- a/lib/pure/parseutils.nim
+++ b/lib/pure/parseutils.nim
@@ -7,7 +7,7 @@
 #    distribution, for details about the copyright.
 #
 
-## Helpers for parsing.
+## This module contains helpers for parsing tokens, numbers, identifiers, etc.
 
 {.deadCodeElim: on.}
 
@@ -25,8 +25,6 @@ template newException(exceptn, message: expr): expr =
 
 const
   Whitespace = {' ', '\t', '\v', '\r', '\l', '\f'}
-  Letters = {'A'..'Z', 'a'..'z'}
-  Digits = {'0'..'9'}
   IdentChars = {'a'..'z', 'A'..'Z', '0'..'9', '_'}
   IdentStartChars = {'a'..'z', 'A'..'Z', '_'}
     ## copied from strutils
@@ -218,6 +216,9 @@ proc parseBiggestFloat*(s: string, number: var biggestFloat, start = 0): int =
   result = i - start
 
 proc parseFloat*(s: string, number: var float, start = 0): int =
+  ## parses a float starting at `start` and stores the value into `number`.
+  ## Result is the number of processed chars or 0 if there occured a parsing
+  ## error.
   var bf: biggestFloat
   result = parseBiggestFloat(s, bf, start)
   number = bf
diff --git a/lib/pure/re.nim b/lib/pure/re.nim
index 1328f5f1f..cef7c85ac 100755
--- a/lib/pure/re.nim
+++ b/lib/pure/re.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nimrod's Runtime Library
-#        (c) Copyright 2009 Andreas Rumpf
+#        (c) Copyright 2010 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim
index 2a53d7660..bebbe56c5 100755
--- a/lib/pure/unicode.nim
+++ b/lib/pure/unicode.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nimrod's Runtime Library
-#        (c) Copyright 2009 Andreas Rumpf
+#        (c) Copyright 2010 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
diff --git a/rod/nimrod.ini b/rod/nimrod.ini
index e1b3d3bb2..7c0e8c565 100755
--- a/rod/nimrod.ini
+++ b/rod/nimrod.ini
@@ -36,6 +36,9 @@ Files: "*.html"
 Files: "*.ini"
 Files: "*.nim"
 
+Files: "icons/nimrod.ico"
+Files: "icons/koch.ico"
+
 Files: "rod/readme.txt"
 Files: "rod/nimrod.ini"
 Files: "rod/nimrod.cfg"
@@ -69,6 +72,14 @@ Files: "lib/wrappers/x11/*.nim"
 Files: "lib/wrappers/zip/*.nim"
 Files: "lib/wrappers/zip/libzip_all.c"
 
+Files: "lib/newwrap/*.nim"
+
+Files: "lib/newwrap/cairo/*.nim"
+Files: "lib/newwrap/gtk/*.nim"
+Files: "lib/newwrap/lua/*.nim"
+Files: "lib/newwrap/sdl/*.nim"
+Files: "lib/newwrap/x11/*.nim"
+
 Files: "lib/windows/*.nim"
 Files: "lib/posix/*.nim"
 Files: "lib/ecmas/*.nim"
diff --git a/web/nimrod.ini b/web/nimrod.ini
index 4920eda06..af2d0c4b7 100755
--- a/web/nimrod.ini
+++ b/web/nimrod.ini
@@ -28,7 +28,9 @@ srcdoc: "pure/complex;pure/times;pure/osproc;pure/pegs;pure/dynlib"
 srcdoc: "pure/parseopt;pure/hashes;pure/strtabs;pure/lexbase"
 srcdoc: "pure/parsecfg;pure/parsexml;pure/parsecsv;pure/parsesql"
 srcdoc: "pure/streams;pure/terminal;pure/cgi;impure/web;pure/unicode"
-srcdoc: "impure/zipfiles;pure/xmlgen;pure/macros"
+srcdoc: "impure/zipfiles;pure/xmlgen;pure/macros;pure/parseutils;pure/browsers"
+srcdoc: "impure/db_postgres;impure/db_mysql;pure/httpserver;pure/httpclient"
+srcdoc: "pure/ropes"
 
 webdoc: "wrappers/libcurl;pure/md5;wrappers/mysql"
 webdoc: "wrappers/sqlite3;wrappers/python;wrappers/tcl"
diff --git a/web/question.txt b/web/question.txt
index cccac2e1b..2012d182f 100755
--- a/web/question.txt
+++ b/web/question.txt
@@ -48,6 +48,15 @@ and a substantial body of other code. Until version 1.0.0 is released, slight
 incompabilities with older versions of the compiler may be introduced.
 
 
+How fast is Nimrod?
+-------------------
+Benchmarks have not been ported yet and support for threads is missing. But in
+the worst case, you can get exactly the same performance as C if you decide to
+write as low-level Nimrod code as C requires you to do. That said the only
+overhead Nimrod has over C is the GC which has been tuned for years (and is 
+significantly faster than the Boehm GC).
+
+
 Compilation
 ===========