summary refs log tree commit diff stats
path: root/lib/impure
diff options
context:
space:
mode:
Diffstat (limited to 'lib/impure')
-rw-r--r--lib/impure/db_mysql.nim10
-rw-r--r--lib/impure/db_postgres.nim8
-rw-r--r--lib/impure/db_sqlite.nim19
-rw-r--r--lib/impure/graphics.nim2
-rw-r--r--lib/impure/osinfo_posix.nim79
-rw-r--r--lib/impure/osinfo_win.nim414
-rw-r--r--lib/impure/rdstdin.nim102
-rw-r--r--lib/impure/re.nim286
-rw-r--r--lib/impure/ssl.nim2
9 files changed, 307 insertions, 615 deletions
diff --git a/lib/impure/db_mysql.nim b/lib/impure/db_mysql.nim
index 968a2923a..b8180cd87 100644
--- a/lib/impure/db_mysql.nim
+++ b/lib/impure/db_mysql.nim
@@ -16,11 +16,11 @@ type
   TDbConn* = PMySQL    ## encapsulates a database connection
   TRow* = seq[string]  ## a row of a dataset. NULL database values will be
                        ## transformed always to the empty string.
-  EDb* = object of EIO ## exception that is raised if a database error occurs
+  EDb* = object of IOError ## exception that is raised if a database error occurs
 
   TSqlQuery* = distinct string ## an SQL query string
 
-  FDb* = object of FIO ## effect that denotes a database operation
+  FDb* = object of IOEffect ## effect that denotes a database operation
   FReadDb* = object of FDb   ## effect that denotes a read operation
   FWriteDb* = object of FDb  ## effect that denotes a write operation
 
@@ -229,3 +229,9 @@ proc open*(connection, user, password, database: string): TDbConn {.
     var errmsg = $mysql.error(result)
     db_mysql.close(result)
     dbError(errmsg)
+
+proc setEncoding*(connection: TDbConn, encoding: string): bool {.
+  tags: [FDb].} =
+  ## sets the encoding of a database connection, returns true for 
+  ## success, false for failure.
+  result = mysql.set_character_set(connection, encoding) == 0
\ No newline at end of file
diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim
index 6691c5703..ffb8bbcda 100644
--- a/lib/impure/db_postgres.nim
+++ b/lib/impure/db_postgres.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nim's Runtime Library
-#        (c) Copyright 2014 Andreas Rumpf
+#        (c) Copyright 2015 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -260,3 +260,9 @@ proc open*(connection, user, password, database: string): TDbConn {.
   ## the nim db api.
   result = pqsetdbLogin(nil, nil, nil, nil, database, user, password)
   if pqStatus(result) != CONNECTION_OK: dbError(result) # result = nil
+
+proc setEncoding*(connection: TDbConn, encoding: string): bool {.
+  tags: [FDb].} =
+  ## sets the encoding of a database connection, returns true for 
+  ## success, false for failure.
+  return pqsetClientEncoding(connection, encoding) == 0
\ No newline at end of file
diff --git a/lib/impure/db_sqlite.nim b/lib/impure/db_sqlite.nim
index bc9e0b591..8536ab6f2 100644
--- a/lib/impure/db_sqlite.nim
+++ b/lib/impure/db_sqlite.nim
@@ -48,6 +48,7 @@ proc dbError*(msg: string) {.noreturn.} =
   raise e
 
 proc dbQuote(s: string): string =
+  if s.isNil: return "NULL"
   result = "'"
   for c in items(s):
     if c == '\'': add(result, "''")
@@ -61,7 +62,7 @@ proc dbFormat(formatstr: TSqlQuery, args: varargs[string]): string =
     if c == '?':
       add(result, dbQuote(args[a]))
       inc(a)
-    else: 
+    else:
       add(result, c)
   
 proc tryExec*(db: TDbConn, query: TSqlQuery, 
@@ -191,8 +192,20 @@ proc open*(connection, user, password, database: string): TDbConn {.
     result = db
   else:
     dbError(db)
-   
-when isMainModule:
+
+proc setEncoding*(connection: TDbConn, encoding: string): bool {.
+  tags: [FDb].} =
+  ## sets the encoding of a database connection, returns true for 
+  ## success, false for failure.
+  ##
+  ## Note that the encoding cannot be changed once it's been set.
+  ## According to SQLite3 documentation, any attempt to change 
+  ## the encoding after the database is created will be silently 
+  ## ignored.
+  exec(connection, sql"PRAGMA encoding = ?", [encoding])
+  result = connection.getValue(sql"PRAGMA encoding") == encoding
+
+when not defined(testing) and isMainModule:
   var db = open("db.sql", "", "", "")
   exec(db, sql"create table tbl1(one varchar(10), two smallint)", [])
   exec(db, sql"insert into tbl1 values('hello!',10)", [])
diff --git a/lib/impure/graphics.nim b/lib/impure/graphics.nim
index dfadb46ee..814c0ebe1 100644
--- a/lib/impure/graphics.nim
+++ b/lib/impure/graphics.nim
@@ -499,7 +499,7 @@ template withEvents*(surf: PSurface, event: expr, actions: stmt): stmt {.
 if sdl.init(sdl.INIT_VIDEO) < 0: raiseEGraphics()
 if sdl_ttf.init() < 0: raiseEGraphics()
 
-when isMainModule:
+when not defined(testing) and isMainModule:
   var surf = newScreenSurface(800, 600)
 
   surf.fillSurface(colWhite)
diff --git a/lib/impure/osinfo_posix.nim b/lib/impure/osinfo_posix.nim
index 1baff8c55..0362fca12 100644
--- a/lib/impure/osinfo_posix.nim
+++ b/lib/impure/osinfo_posix.nim
@@ -1,69 +1,10 @@
-import posix, strutils, os
-
-when false:
-  type
-    Tstatfs {.importc: "struct statfs64", 
-              header: "<sys/statfs.h>", final, pure.} = object
-      f_type: int
-      f_bsize: int
-      f_blocks: int
-      f_bfree: int
-      f_bavail: int
-      f_files: int
-      f_ffree: int
-      f_fsid: int
-      f_namelen: int
-
-  proc statfs(path: string, buf: var Tstatfs): int {.
-    importc, header: "<sys/vfs.h>".}
-
-
-proc getSystemVersion*(): string =
-  result = ""
-  
-  var unix_info: TUtsname
-  
-  if uname(unix_info) != 0:
-    os.raiseOSError(osLastError())
-  
-  if $unix_info.sysname == "Linux":
-    # Linux
-    result.add("Linux ")
-
-    result.add($unix_info.release & " ")
-    result.add($unix_info.machine)
-  elif $unix_info.sysname == "Darwin":
-    # Darwin
-    result.add("Mac OS X ")
-    if "10" in $unix_info.release:
-      result.add("v10.6 Snow Leopard")
-    elif "9" in $unix_info.release:
-      result.add("v10.5 Leopard")
-    elif "8" in $unix_info.release:
-      result.add("v10.4 Tiger")
-    elif "7" in $unix_info.release:
-      result.add("v10.3 Panther")
-    elif "6" in $unix_info.release:
-      result.add("v10.2 Jaguar")
-    elif "1.4" in $unix_info.release:
-      result.add("v10.1 Puma")
-    elif "1.3" in $unix_info.release:
-      result.add("v10.0 Cheetah")
-    elif "0" in $unix_info.release:
-      result.add("Server 1.0 Hera")
-  else:
-    result.add($unix_info.sysname & " " & $unix_info.release)
-    
-    
-when false:
-  var unix_info: TUtsname
-  echo(uname(unix_info))
-  echo(unix_info.sysname)
-  echo("8" in $unix_info.release)
-
-  echo(getSystemVersion())
-
-  var stfs: TStatfs
-  echo(statfs("sysinfo_posix.nim", stfs))
-  echo(stfs.f_files)
-  
+#
+#
+#            Nim's Runtime Library
+#        (c) Copyright 2015 Dominik Picheta
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+{.error: "This module has been moved to the 'osinfo' nimble package.".}
diff --git a/lib/impure/osinfo_win.nim b/lib/impure/osinfo_win.nim
index f423a34a3..0362fca12 100644
--- a/lib/impure/osinfo_win.nim
+++ b/lib/impure/osinfo_win.nim
@@ -1,404 +1,10 @@
-# XXX clean up this mess!
-
-import winlean
-
-const
-  INVALID_HANDLE_VALUE = int(- 1) # GetStockObject
-
-type
-  TMEMORYSTATUSEX {.final, pure.} = object
-    dwLength: int32
-    dwMemoryLoad: int32
-    ullTotalPhys: int64
-    ullAvailPhys: int64
-    ullTotalPageFile: int64
-    ullAvailPageFile: int64
-    ullTotalVirtual: int64
-    ullAvailVirtual: int64
-    ullAvailExtendedVirtual: int64
-    
-  SYSTEM_INFO* {.final, pure.} = object
-    wProcessorArchitecture*: int16
-    wReserved*: int16
-    dwPageSize*: int32
-    lpMinimumApplicationAddress*: pointer
-    lpMaximumApplicationAddress*: pointer
-    dwActiveProcessorMask*: int32
-    dwNumberOfProcessors*: int32
-    dwProcessorType*: int32
-    dwAllocationGranularity*: int32
-    wProcessorLevel*: int16
-    wProcessorRevision*: int16
-
-  LPSYSTEM_INFO* = ptr SYSTEM_INFO
-  TSYSTEMINFO* = SYSTEM_INFO
-
-  TMemoryInfo* = object
-    MemoryLoad*: int ## occupied memory, in percent
-    TotalPhysMem*: int64 ## Total Physical memory, in bytes
-    AvailablePhysMem*: int64 ## Available physical memory, in bytes
-    TotalPageFile*: int64 ## The current committed memory limit 
-                          ## for the system or the current process, whichever is smaller, in bytes.
-    AvailablePageFile*: int64 ## The maximum amount of memory the current process can commit, in bytes.
-    TotalVirtualMem*: int64 ## Total virtual memory, in bytes
-    AvailableVirtualMem*: int64 ## Available virtual memory, in bytes
-    
-  TOSVERSIONINFOEX {.final, pure.} = object
-    dwOSVersionInfoSize: int32
-    dwMajorVersion: int32
-    dwMinorVersion: int32
-    dwBuildNumber: int32
-    dwPlatformId: int32
-    szCSDVersion: array[0..127, char]
-    wServicePackMajor: int16
-    wServicePackMinor: int16
-    wSuiteMask: int16
-    wProductType: int8
-    wReserved: char
-    
-  TVersionInfo* = object
-    majorVersion*: int
-    minorVersion*: int
-    buildNumber*: int
-    platformID*: int
-    SPVersion*: string ## Full Service pack version string
-    SPMajor*: int ## Major service pack version
-    SPMinor*: int ## Minor service pack version
-    SuiteMask*: int
-    ProductType*: int
-    
-  TPartitionInfo* = tuple[FreeSpace, TotalSpace: Tfiletime]
-  
-const
-  # SuiteMask - VersionInfo.SuiteMask
-  VER_SUITE_BACKOFFICE* = 0x00000004
-  VER_SUITE_BLADE* = 0x00000400
-  VER_SUITE_COMPUTE_SERVER* = 0x00004000
-  VER_SUITE_DATACENTER* = 0x00000080
-  VER_SUITE_ENTERPRISE* = 0x00000002
-  VER_SUITE_EMBEDDEDNT* = 0x00000040
-  VER_SUITE_PERSONAL* = 0x00000200
-  VER_SUITE_SINGLEUSERTS* = 0x00000100
-  VER_SUITE_SMALLBUSINESS* = 0x00000001
-  VER_SUITE_SMALLBUSINESS_RESTRICTED* = 0x00000020
-  VER_SUITE_STORAGE_SERVER* = 0x00002000
-  VER_SUITE_TERMINAL* = 0x00000010
-  VER_SUITE_WH_SERVER* = 0x00008000
-
-  # ProductType - VersionInfo.ProductType
-  VER_NT_DOMAIN_CONTROLLER* = 0x0000002
-  VER_NT_SERVER* = 0x0000003
-  VER_NT_WORKSTATION* = 0x0000001
-  
-  VER_PLATFORM_WIN32_NT* = 2
-  
-  # Product Info - getProductInfo() - (Remove unused ones ?)
-  PRODUCT_BUSINESS* = 0x00000006
-  PRODUCT_BUSINESS_N* = 0x00000010
-  PRODUCT_CLUSTER_SERVER* = 0x00000012
-  PRODUCT_DATACENTER_SERVER* = 0x00000008
-  PRODUCT_DATACENTER_SERVER_CORE* = 0x0000000C
-  PRODUCT_DATACENTER_SERVER_CORE_V* = 0x00000027
-  PRODUCT_DATACENTER_SERVER_V* = 0x00000025
-  PRODUCT_ENTERPRISE* = 0x00000004
-  PRODUCT_ENTERPRISE_E* = 0x00000046
-  PRODUCT_ENTERPRISE_N* = 0x0000001B
-  PRODUCT_ENTERPRISE_SERVER* = 0x0000000A
-  PRODUCT_ENTERPRISE_SERVER_CORE* = 0x0000000E
-  PRODUCT_ENTERPRISE_SERVER_CORE_V* = 0x00000029
-  PRODUCT_ENTERPRISE_SERVER_IA64* = 0x0000000F
-  PRODUCT_ENTERPRISE_SERVER_V* = 0x00000026
-  PRODUCT_HOME_BASIC* = 0x00000002
-  PRODUCT_HOME_BASIC_E* = 0x00000043
-  PRODUCT_HOME_BASIC_N* = 0x00000005
-  PRODUCT_HOME_PREMIUM* = 0x00000003
-  PRODUCT_HOME_PREMIUM_E* = 0x00000044
-  PRODUCT_HOME_PREMIUM_N* = 0x0000001A
-  PRODUCT_HYPERV* = 0x0000002A
-  PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT* = 0x0000001E
-  PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING* = 0x00000020
-  PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY* = 0x0000001F
-  PRODUCT_PROFESSIONAL* = 0x00000030
-  PRODUCT_PROFESSIONAL_E* = 0x00000045
-  PRODUCT_PROFESSIONAL_N* = 0x00000031
-  PRODUCT_SERVER_FOR_SMALLBUSINESS* = 0x00000018
-  PRODUCT_SERVER_FOR_SMALLBUSINESS_V* = 0x00000023
-  PRODUCT_SERVER_FOUNDATION* = 0x00000021
-  PRODUCT_SMALLBUSINESS_SERVER* = 0x00000009
-  PRODUCT_STANDARD_SERVER* = 0x00000007
-  PRODUCT_STANDARD_SERVER_CORE * = 0x0000000D
-  PRODUCT_STANDARD_SERVER_CORE_V* = 0x00000028
-  PRODUCT_STANDARD_SERVER_V* = 0x00000024
-  PRODUCT_STARTER* = 0x0000000B
-  PRODUCT_STARTER_E* = 0x00000042
-  PRODUCT_STARTER_N* = 0x0000002F
-  PRODUCT_STORAGE_ENTERPRISE_SERVER* = 0x00000017
-  PRODUCT_STORAGE_EXPRESS_SERVER* = 0x00000014
-  PRODUCT_STORAGE_STANDARD_SERVER* = 0x00000015
-  PRODUCT_STORAGE_WORKGROUP_SERVER* = 0x00000016
-  PRODUCT_UNDEFINED* = 0x00000000
-  PRODUCT_ULTIMATE* = 0x00000001
-  PRODUCT_ULTIMATE_E* = 0x00000047
-  PRODUCT_ULTIMATE_N* = 0x0000001C
-  PRODUCT_WEB_SERVER* = 0x00000011
-  PRODUCT_WEB_SERVER_CORE* = 0x0000001D
-  
-  PROCESSOR_ARCHITECTURE_AMD64* = 9 ## x64 (AMD or Intel)
-  PROCESSOR_ARCHITECTURE_IA64* = 6 ## Intel Itanium Processor Family (IPF)
-  PROCESSOR_ARCHITECTURE_INTEL* = 0 ## x86
-  PROCESSOR_ARCHITECTURE_UNKNOWN* = 0xffff ## Unknown architecture.
-  
-  # GetSystemMetrics
-  SM_SERVERR2 = 89 
-  
-proc globalMemoryStatusEx*(lpBuffer: var TMEMORYSTATUSEX){.stdcall, dynlib: "kernel32",
-    importc: "GlobalMemoryStatusEx".}
-    
-proc getMemoryInfo*(): TMemoryInfo =
-  ## Retrieves memory info
-  var statex: TMEMORYSTATUSEX
-  statex.dwLength = sizeof(statex).int32
-
-  globalMemoryStatusEx(statex)
-  result.MemoryLoad = statex.dwMemoryLoad
-  result.TotalPhysMem = statex.ullTotalPhys
-  result.AvailablePhysMem = statex.ullAvailPhys
-  result.TotalPageFile = statex.ullTotalPageFile
-  result.AvailablePageFile = statex.ullAvailPageFile
-  result.TotalVirtualMem = statex.ullTotalVirtual
-  result.AvailableVirtualMem = statex.ullAvailExtendedVirtual
-
-proc getVersionEx*(lpVersionInformation: var TOSVERSIONINFOEX): WINBOOL{.stdcall,
-    dynlib: "kernel32", importc: "GetVersionExA".}
-
-proc getProcAddress*(hModule: int, lpProcName: cstring): pointer{.stdcall,
-    dynlib: "kernel32", importc: "GetProcAddress".}
-
-proc getModuleHandleA*(lpModuleName: cstring): int{.stdcall,
-     dynlib: "kernel32", importc: "GetModuleHandleA".}
-
-proc getVersionInfo*(): TVersionInfo =
-  ## Retrieves operating system info
-  var osvi: TOSVERSIONINFOEX
-  osvi.dwOSVersionInfoSize = sizeof(osvi).int32
-  discard getVersionEx(osvi)
-  result.majorVersion = osvi.dwMajorVersion
-  result.minorVersion = osvi.dwMinorVersion
-  result.buildNumber = osvi.dwBuildNumber
-  result.platformID = osvi.dwPlatformId
-  result.SPVersion = $osvi.szCSDVersion
-  result.SPMajor = osvi.wServicePackMajor
-  result.SPMinor = osvi.wServicePackMinor
-  result.SuiteMask = osvi.wSuiteMask
-  result.ProductType = osvi.wProductType
-
-proc getProductInfo*(majorVersion, minorVersion, SPMajorVersion, 
-                     SPMinorVersion: int): int =
-  ## Retrieves Windows' ProductInfo, this function only works in Vista and 7
-
-  var pGPI = cast[proc (dwOSMajorVersion, dwOSMinorVersion, 
-              dwSpMajorVersion, dwSpMinorVersion: int32, outValue: Pint32)](getProcAddress(
-                getModuleHandleA("kernel32.dll"), "GetProductInfo"))
-                
-  if pGPI != nil:
-    var dwType: int32
-    pGPI(int32(majorVersion), int32(minorVersion), int32(SPMajorVersion), int32(SPMinorVersion), addr(dwType))
-    result = int(dwType)
-  else:
-    return PRODUCT_UNDEFINED
-
-proc getSystemInfo*(lpSystemInfo: LPSYSTEM_INFO){.stdcall, dynlib: "kernel32",
-    importc: "GetSystemInfo".}
-    
-proc getSystemInfo*(): TSYSTEM_INFO =
-  ## Returns the SystemInfo
-
-  # Use GetNativeSystemInfo if it's available
-  var pGNSI = cast[proc (lpSystemInfo: LPSYSTEM_INFO)](getProcAddress(
-                getModuleHandleA("kernel32.dll"), "GetNativeSystemInfo"))
-                
-  var systemi: TSYSTEM_INFO              
-  if pGNSI != nil:
-    pGNSI(addr(systemi))
-  else:
-    getSystemInfo(addr(systemi))
-
-  return systemi
-
-proc getSystemMetrics*(nIndex: int32): int32{.stdcall, dynlib: "user32",
-    importc: "GetSystemMetrics".}
-
-proc `$`*(osvi: TVersionInfo): string =
-  ## Turns a VersionInfo object, into a string
-
-  if osvi.platformID == VER_PLATFORM_WIN32_NT and osvi.majorVersion > 4:
-    result = "Microsoft "
-    
-    var si = getSystemInfo()
-    # Test for the specific product
-    if osvi.majorVersion == 6:
-      if osvi.minorVersion == 0:
-        if osvi.ProductType == VER_NT_WORKSTATION:
-          result.add("Windows Vista ")
-        else: result.add("Windows Server 2008 ")
-      elif osvi.minorVersion == 1:
-        if osvi.ProductType == VER_NT_WORKSTATION:
-          result.add("Windows 7 ")
-        else: result.add("Windows Server 2008 R2 ")
-    
-      var dwType = getProductInfo(osvi.majorVersion, osvi.minorVersion, 0, 0)
-      case dwType
-      of PRODUCT_ULTIMATE:
-        result.add("Ultimate Edition")
-      of PRODUCT_PROFESSIONAL:
-        result.add("Professional")
-      of PRODUCT_HOME_PREMIUM:
-        result.add("Home Premium Edition")
-      of PRODUCT_HOME_BASIC:
-        result.add("Home Basic Edition")
-      of PRODUCT_ENTERPRISE:
-        result.add("Enterprise Edition")
-      of PRODUCT_BUSINESS:
-        result.add("Business Edition")
-      of PRODUCT_STARTER:
-        result.add("Starter Edition")
-      of PRODUCT_CLUSTER_SERVER:
-        result.add("Cluster Server Edition")
-      of PRODUCT_DATACENTER_SERVER:
-        result.add("Datacenter Edition")
-      of PRODUCT_DATACENTER_SERVER_CORE:
-        result.add("Datacenter Edition (core installation)")
-      of PRODUCT_ENTERPRISE_SERVER:
-        result.add("Enterprise Edition")
-      of PRODUCT_ENTERPRISE_SERVER_CORE:
-        result.add("Enterprise Edition (core installation)")
-      of PRODUCT_ENTERPRISE_SERVER_IA64:
-        result.add("Enterprise Edition for Itanium-based Systems")
-      of PRODUCT_SMALLBUSINESS_SERVER:
-        result.add("Small Business Server")
-      of PRODUCT_STANDARD_SERVER:
-        result.add("Standard Edition")
-      of PRODUCT_STANDARD_SERVER_CORE:
-        result.add("Standard Edition (core installation)")
-      of PRODUCT_WEB_SERVER:
-        result.add("Web Server Edition")
-      else:
-        discard
-    # End of Windows 6.*
-
-    if osvi.majorVersion == 5 and osvi.minorVersion == 2:
-      if getSystemMetrics(SM_SERVERR2) != 0:
-        result.add("Windows Server 2003 R2, ")
-      elif (osvi.SuiteMask and VER_SUITE_PERSONAL) != 0: # Not sure if this will work
-        result.add("Windows Storage Server 2003")
-      elif (osvi.SuiteMask and VER_SUITE_WH_SERVER) != 0:
-        result.add("Windows Home Server")
-      elif osvi.ProductType == VER_NT_WORKSTATION and 
-          si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64:
-        result.add("Windows XP Professional x64 Edition")
-      else:
-        result.add("Windows Server 2003, ")
-      
-      # Test for the specific product
-      if osvi.ProductType != VER_NT_WORKSTATION:
-        if ze(si.wProcessorArchitecture) == PROCESSOR_ARCHITECTURE_IA64:
-          if (osvi.SuiteMask and VER_SUITE_DATACENTER) != 0:
-            result.add("Datacenter Edition for Itanium-based Systems")
-          elif (osvi.SuiteMask and VER_SUITE_ENTERPRISE) != 0:
-            result.add("Enterprise Edition for Itanium-based Systems")
-        elif ze(si.wProcessorArchitecture) == PROCESSOR_ARCHITECTURE_AMD64:
-          if (osvi.SuiteMask and VER_SUITE_DATACENTER) != 0:
-            result.add("Datacenter x64 Edition")
-          elif (osvi.SuiteMask and VER_SUITE_ENTERPRISE) != 0:
-            result.add("Enterprise x64 Edition")
-          else:
-            result.add("Standard x64 Edition")
-        else:
-          if (osvi.SuiteMask and VER_SUITE_COMPUTE_SERVER) != 0:
-            result.add("Compute Cluster Edition")
-          elif (osvi.SuiteMask and VER_SUITE_DATACENTER) != 0:
-            result.add("Datacenter Edition")
-          elif (osvi.SuiteMask and VER_SUITE_ENTERPRISE) != 0:
-            result.add("Enterprise Edition")
-          elif (osvi.SuiteMask and VER_SUITE_BLADE) != 0:
-            result.add("Web Edition")
-          else:
-            result.add("Standard Edition")
-    # End of 5.2
-    
-    if osvi.majorVersion == 5 and osvi.minorVersion == 1:
-      result.add("Windows XP ")
-      if (osvi.SuiteMask and VER_SUITE_PERSONAL) != 0:
-        result.add("Home Edition")
-      else:
-        result.add("Professional")
-    # End of 5.1
-    
-    if osvi.majorVersion == 5 and osvi.minorVersion == 0:
-      result.add("Windows 2000 ")
-      if osvi.ProductType == VER_NT_WORKSTATION:
-        result.add("Professional")
-      else:
-        if (osvi.SuiteMask and VER_SUITE_DATACENTER) != 0:
-          result.add("Datacenter Server")
-        elif (osvi.SuiteMask and VER_SUITE_ENTERPRISE) != 0:
-          result.add("Advanced Server")
-        else:
-          result.add("Server")
-    # End of 5.0
-    
-    # Include service pack (if any) and build number.
-    if len(osvi.SPVersion) > 0:
-      result.add(" ")
-      result.add(osvi.SPVersion)
-    
-    result.add(" (build " & $osvi.buildNumber & ")")
-    
-    if osvi.majorVersion >= 6:
-      if ze(si.wProcessorArchitecture) == PROCESSOR_ARCHITECTURE_AMD64:
-        result.add(", 64-bit")
-      elif ze(si.wProcessorArchitecture) == PROCESSOR_ARCHITECTURE_INTEL:
-        result.add(", 32-bit")
-    
-  else:
-    # Windows 98 etc...
-    result = "Unknown version of windows[Kernel version <= 4]"
-    
-
-proc getFileSize*(file: string): BiggestInt =
-  var fileData: TWIN32_FIND_DATA
-
-  when useWinUnicode:
-    var aa = newWideCString(file)
-    var hFile = findFirstFileW(aa, fileData)
-  else:
-    var hFile = findFirstFileA(file, fileData)
-  
-  if hFile == INVALID_HANDLE_VALUE:
-    raise newException(IOError, $getLastError())
-  
-  return fileData.nFileSizeLow
-
-proc getDiskFreeSpaceEx*(lpDirectoryName: cstring, lpFreeBytesAvailableToCaller,
-                         lpTotalNumberOfBytes,
-                         lpTotalNumberOfFreeBytes: var TFiletime): WINBOOL{.
-    stdcall, dynlib: "kernel32", importc: "GetDiskFreeSpaceExA".}
-
-proc getPartitionInfo*(partition: string): TPartitionInfo =
-  ## Retrieves partition info, for example ``partition`` may be ``"C:\"``
-  var freeBytes, totalBytes, totalFreeBytes: TFiletime 
-  discard getDiskFreeSpaceEx(r"C:\", freeBytes, totalBytes, 
-                               totalFreeBytes)
-  return (freeBytes, totalBytes)
-
-when isMainModule:
-  var r = getMemoryInfo()
-  echo("Memory load: ", r.MemoryLoad, "%")
-  
-  var osvi = getVersionInfo()
-  
-  echo($osvi)
-
-  echo(getFileSize(r"osinfo_win.nim") div 1024 div 1024)
-  
-  echo(rdFileTime(getPartitionInfo(r"C:\")[0]))
+#
+#
+#            Nim's Runtime Library
+#        (c) Copyright 2015 Dominik Picheta
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+{.error: "This module has been moved to the 'osinfo' nimble package.".}
diff --git a/lib/impure/rdstdin.nim b/lib/impure/rdstdin.nim
index 07ef13fd9..f4d00979c 100644
--- a/lib/impure/rdstdin.nim
+++ b/lib/impure/rdstdin.nim
@@ -1,21 +1,23 @@
 #
 #
 #            Nim's Runtime Library
-#        (c) Copyright 2012 Andreas Rumpf
+#        (c) Copyright 2015 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
 #
 
 ## This module contains code for reading from `stdin`:idx:. On UNIX the GNU
-## readline library is wrapped and set up to provide default key bindings 
+## readline library is wrapped and set up to provide default key bindings
 ## (e.g. you can navigate with the arrow keys). On Windows ``system.readLine``
-## is used. This suffices because Windows' console already provides the 
+## is used. This suffices because Windows' console already provides the
 ## wanted functionality.
 
+{.deadCodeElim: on.}
+
 when defined(Windows):
   proc readLineFromStdin*(prompt: string): TaintedString {.
-                          tags: [ReadIOEffect, WriteIOEffect].} = 
+                          tags: [ReadIOEffect, WriteIOEffect].} =
     ## Reads a line from stdin.
     stdout.write(prompt)
     result = readLine(stdin)
@@ -31,9 +33,75 @@ when defined(Windows):
     stdout.write(prompt)
     result = readLine(stdin, line)
 
+  import winlean
+
+  const
+    VK_SHIFT* = 16
+    VK_CONTROL* = 17
+    VK_MENU* = 18
+    KEY_EVENT* = 1
+
+  type
+    KEY_EVENT_RECORD = object
+      bKeyDown: WinBool
+      wRepeatCount: uint16
+      wVirtualKeyCode: uint16
+      wVirtualScanCode: uint16
+      unicodeChar: uint16
+      dwControlKeyState: uint32
+    INPUT_RECORD = object
+      eventType*: int16
+      reserved*: int16
+      event*: KEY_EVENT_RECORD
+      safetyBuffer: array[0..5, DWORD]
+
+  proc readConsoleInputW*(hConsoleInput: THANDLE, lpBuffer: var INPUTRECORD,
+                          nLength: uint32,
+                          lpNumberOfEventsRead: var uint32): WINBOOL{.
+      stdcall, dynlib: "kernel32", importc: "ReadConsoleInputW".}
+
+  proc getch(): uint16 =
+    let hStdin = getStdHandle(STD_INPUT_HANDLE)
+    var
+      irInputRecord: INPUT_RECORD
+      dwEventsRead: uint32
+
+    while readConsoleInputW(hStdin, irInputRecord, 1, dwEventsRead) != 0:
+      if irInputRecord.eventType == KEY_EVENT and
+          irInputRecord.event.wVirtualKeyCode notin {VK_SHIFT, VK_MENU, VK_CONTROL}:
+         result = irInputRecord.event.unicodeChar
+         discard readConsoleInputW(hStdin, irInputRecord, 1, dwEventsRead)
+         return result
+
+  from unicode import toUTF8, Rune, runeLenAt
+
+  proc readPasswordFromStdin*(prompt: string, password: var TaintedString):
+                              bool {.tags: [ReadIOEffect, WriteIOEffect].} =
+    ## Reads a `password` from stdin without printing it. `password` must not
+    ## be ``nil``! Returns ``false`` if the end of the file has been reached,
+    ## ``true`` otherwise.
+    password.setLen(0)
+    stdout.write(prompt)
+    while true:
+      let c = getch()
+      case c.char
+      of '\r', chr(0xA):
+        break
+      of '\b':
+        # ensure we delete the whole UTF-8 character:
+        var i = 0
+        var x = 1
+        while i < password.len:
+          x = runeLenAt(password, i)
+          inc i, x
+        password.setLen(password.len - x)
+      else:
+        password.add(toUTF8(c.Rune))
+    stdout.write "\n"
+
 else:
-  import readline, history
-    
+  import readline, history, termios, unsigned
+
   proc readLineFromStdin*(prompt: string): TaintedString {.
                           tags: [ReadIOEffect, WriteIOEffect].} =
     var buffer = readline.readLine(prompt)
@@ -55,8 +123,26 @@ else:
     result = true
 
   # initialization:
-  # disable auto-complete: 
+  # disable auto-complete:
   proc doNothing(a, b: cint): cint {.cdecl, procvar.} = discard
-  
+
   discard readline.bind_key('\t'.ord, doNothing)
 
+  proc readPasswordFromStdin*(prompt: string, password: var TaintedString):
+                              bool {.tags: [ReadIOEffect, WriteIOEffect].} =
+    password.setLen(0)
+    let fd = stdin.getFileHandle()
+    var cur, old: Termios
+    discard fd.tcgetattr(cur.addr)
+    old = cur
+    cur.c_lflag = cur.c_lflag and not Tcflag(ECHO)
+    discard fd.tcsetattr(TCSADRAIN, cur.addr)
+    stdout.write prompt
+    result = stdin.readLine(password)
+    stdout.write "\n"
+    discard fd.tcsetattr(TCSADRAIN, old.addr)
+
+proc readPasswordFromStdin*(prompt: string): TaintedString =
+  ## Reads a password from stdin without printing it.
+  result = TaintedString("")
+  discard readPasswordFromStdin(prompt, result)
diff --git a/lib/impure/re.nim b/lib/impure/re.nim
index 6e3a69c62..fb95610f6 100644
--- a/lib/impure/re.nim
+++ b/lib/impure/re.nim
@@ -7,8 +7,17 @@
 #    distribution, for details about the copyright.
 #
 
-## Regular expression support for Nim. Consider using the pegs module
-## instead.
+## Regular expression support for Nim. Consider using the pegs module instead.
+##
+## There is an alternative regular expressions library with a more unified API:
+## `nre <https://github.com/flaviut/nre>`_. It may be added to the standard
+## library in the future, instead of `re`.
+##
+## **Note:** The 're' proc defaults to the **extended regular expression
+## syntax** which lets you use whitespace freely to make your regexes readable.
+## However, this means to match whitespace ``\s`` or something similar has
+## to be used.
+##
 ## This module is implemented by providing a wrapper around the
 ## `PRCE (Perl-Compatible Regular Expressions) <http://www.pcre.org>`_
 ## C library. This means that your application will depend on the PRCE
@@ -20,52 +29,52 @@
 ##
 
 import
-  pcre, strutils
+  pcre, strutils, rtarrays
 
 const
-  MaxSubpatterns* = 10
+  MaxSubpatterns* = 20
     ## defines the maximum number of subpatterns that can be captured.
-    ## More subpatterns cannot be captured!
+    ## This limit still exists for ``replacef`` and ``parallelReplace``.
 
 type
   RegexFlag* = enum     ## options for regular expressions
     reIgnoreCase = 0,    ## do caseless matching
-    reMultiLine = 1,     ## ``^`` and ``$`` match newlines within data 
+    reMultiLine = 1,     ## ``^`` and ``$`` match newlines within data
     reDotAll = 2,        ## ``.`` matches anything including NL
     reExtended = 3,      ## ignore whitespace and ``#`` comments
     reStudy = 4          ## study the expression (may be omitted if the
                          ## expression will be used only once)
-    
+  
   RegexDesc = object 
-    h: PPcre
-    e: ptr TExtra
-    
+    h: ptr Pcre
+    e: ptr ExtraData
+  
   Regex* = ref RegexDesc ## a compiled regular expression
-    
+
   RegexError* = object of ValueError
     ## is raised if the pattern is no valid regular expression.
 
 {.deprecated: [TRegexFlag: RegexFlag, TRegexDesc: RegexDesc, TRegex: Regex,
     EInvalidRegEx: RegexError].}
 
-proc raiseInvalidRegex(msg: string) {.noinline, noreturn.} = 
+proc raiseInvalidRegex(msg: string) {.noinline, noreturn.} =
   var e: ref RegexError
   new(e)
   e.msg = msg
   raise e
-  
-proc rawCompile(pattern: string, flags: cint): PPcre =
+
+proc rawCompile(pattern: string, flags: cint): ptr Pcre =
   var
     msg: cstring
     offset: cint
   result = pcre.compile(pattern, flags, addr(msg), addr(offset), nil)
   if result == nil:
-    raiseInvalidRegex($msg & "\n" & pattern & "\n" & repeatChar(offset) & "^\n")
+    raiseInvalidRegex($msg & "\n" & pattern & "\n" & spaces(offset) & "^\n")
 
-proc finalizeRegEx(x: Regex) = 
+proc finalizeRegEx(x: Regex) =
   # XXX This is a hack, but PCRE does not export its "free" function properly.
   # Sigh. The hack relies on PCRE's implementation (see ``pcre_get.c``).
-  # Fortunately the implementation is unlikely to change. 
+  # Fortunately the implementation is unlikely to change.
   pcre.free_substring(cast[cstring](x.h))
   if not isNil(x.e):
     pcre.free_substring(cast[cstring](x.e))
@@ -78,15 +87,16 @@ proc re*(s: string, flags = {reExtended, reStudy}): Regex =
   result.h = rawCompile(s, cast[cint](flags - {reStudy}))
   if reStudy in flags:
     var msg: cstring
-    result.e = pcre.study(result.h, 0, msg)
+    result.e = pcre.study(result.h, 0, addr msg)
     if not isNil(msg): raiseInvalidRegex($msg)
 
 proc matchOrFind(s: string, pattern: Regex, matches: var openArray[string],
                  start, flags: cint): cint =
   var
-    rawMatches: array[0..MaxSubpatterns * 3 - 1, cint]
+    rtarray = initRtArray[cint]((matches.len+1)*3)
+    rawMatches = rtarray.getRawData
     res = pcre.exec(pattern.h, pattern.e, s, len(s).cint, start, flags,
-      cast[ptr cint](addr(rawMatches)), MaxSubpatterns * 3)
+      cast[ptr cint](rawMatches), (matches.len+1).cint*3)
   if res < 0'i32: return res
   for i in 1..int(res)-1:
     var a = rawMatches[i * 2]
@@ -94,17 +104,18 @@ proc matchOrFind(s: string, pattern: Regex, matches: var openArray[string],
     if a >= 0'i32: matches[i-1] = substr(s, int(a), int(b)-1)
     else: matches[i-1] = nil
   return rawMatches[1] - rawMatches[0]
-  
+
 proc findBounds*(s: string, pattern: Regex, matches: var openArray[string],
                  start = 0): tuple[first, last: int] =
-  ## returns the starting position and end position of `pattern` in `s` 
+  ## returns the starting position and end position of `pattern` in `s`
   ## and the captured
   ## substrings in the array `matches`. If it does not match, nothing
   ## is written into `matches` and ``(-1,0)`` is returned.
   var
-    rawMatches: array[0..MaxSubpatterns * 3 - 1, cint]
+    rtarray = initRtArray[cint]((matches.len+1)*3)
+    rawMatches = rtarray.getRawData
     res = pcre.exec(pattern.h, pattern.e, s, len(s).cint, start.cint, 0'i32,
-      cast[ptr cint](addr(rawMatches)), MaxSubpatterns * 3)
+      cast[ptr cint](rawMatches), (matches.len+1).cint*3)
   if res < 0'i32: return (-1, 0)
   for i in 1..int(res)-1:
     var a = rawMatches[i * 2]
@@ -112,18 +123,19 @@ proc findBounds*(s: string, pattern: Regex, matches: var openArray[string],
     if a >= 0'i32: matches[i-1] = substr(s, int(a), int(b)-1)
     else: matches[i-1] = nil
   return (rawMatches[0].int, rawMatches[1].int - 1)
-  
-proc findBounds*(s: string, pattern: Regex, 
+
+proc findBounds*(s: string, pattern: Regex,
                  matches: var openArray[tuple[first, last: int]],
                  start = 0): tuple[first, last: int] =
-  ## returns the starting position and end position of ``pattern`` in ``s`` 
-  ## and the captured substrings in the array `matches`. 
+  ## returns the starting position and end position of ``pattern`` in ``s``
+  ## and the captured substrings in the array `matches`.
   ## If it does not match, nothing is written into `matches` and
   ## ``(-1,0)`` is returned.
   var
-    rawMatches: array[0..MaxSubpatterns * 3 - 1, cint]
+    rtarray = initRtArray[cint]((matches.len+1)*3)
+    rawMatches = rtarray.getRawData
     res = pcre.exec(pattern.h, pattern.e, s, len(s).cint, start.cint, 0'i32,
-      cast[ptr cint](addr(rawMatches)), MaxSubpatterns * 3)
+      cast[ptr cint](rawMatches), (matches.len+1).cint*3)
   if res < 0'i32: return (-1, 0)
   for i in 1..int(res)-1:
     var a = rawMatches[i * 2]
@@ -132,37 +144,27 @@ proc findBounds*(s: string, pattern: Regex,
     else: matches[i-1] = (-1,0)
   return (rawMatches[0].int, rawMatches[1].int - 1)
 
-proc findBounds*(s: string, pattern: Regex, 
+proc findBounds*(s: string, pattern: Regex,
                  start = 0): tuple[first, last: int] =
   ## returns the starting position of `pattern` in `s`. If it does not
   ## match, ``(-1,0)`` is returned.
   var
-    rawMatches: array[0..3 - 1, cint]
+    rtarray = initRtArray[cint](3)
+    rawMatches = rtarray.getRawData
     res = pcre.exec(pattern.h, nil, s, len(s).cint, start.cint, 0'i32,
-      cast[ptr cint](addr(rawMatches)), 3)
+      cast[ptr cint](rawMatches), 3)
   if res < 0'i32: return (int(res), 0)
   return (int(rawMatches[0]), int(rawMatches[1]-1))
-  
+
 proc matchOrFind(s: string, pattern: Regex, start, flags: cint): cint =
-  var rawMatches: array [0..MaxSubpatterns * 3 - 1, cint]
+  var
+    rtarray = initRtArray[cint](3)
+    rawMatches = rtarray.getRawData
   result = pcre.exec(pattern.h, pattern.e, s, len(s).cint, start, flags,
-                    cast[ptr cint](addr(rawMatches)), MaxSubpatterns * 3)
+                    cast[ptr cint](rawMatches), 3)
   if result >= 0'i32:
     result = rawMatches[1] - rawMatches[0]
 
-proc match*(s: string, pattern: Regex, matches: var openArray[string],
-           start = 0): bool =
-  ## returns ``true`` if ``s[start..]`` matches the ``pattern`` and
-  ## the captured substrings in the array ``matches``. If it does not
-  ## match, nothing is written into ``matches`` and ``false`` is
-  ## returned.
-  return matchOrFind(s, pattern, matches, start.cint, 
-                     pcre.ANCHORED) == cint(s.len - start)
-
-proc match*(s: string, pattern: Regex, start = 0): bool =
-  ## returns ``true`` if ``s[start..]`` matches the ``pattern``.
-  return matchOrFind(s, pattern, start.cint, pcre.ANCHORED) == cint(s.len-start)
-
 proc matchLen*(s: string, pattern: Regex, matches: var openArray[string],
               start = 0): int =
   ## the same as ``match``, but it returns the length of the match,
@@ -173,18 +175,31 @@ proc matchLen*(s: string, pattern: Regex, matches: var openArray[string],
 proc matchLen*(s: string, pattern: Regex, start = 0): int =
   ## the same as ``match``, but it returns the length of the match,
   ## if there is no match, -1 is returned. Note that a match length
-  ## of zero can happen. 
+  ## of zero can happen.
   return matchOrFind(s, pattern, start.cint, pcre.ANCHORED)
 
+proc match*(s: string, pattern: Regex, start = 0): bool =
+  ## returns ``true`` if ``s[start..]`` matches the ``pattern``.
+  result = matchLen(s, pattern, start) != -1
+
+proc match*(s: string, pattern: Regex, matches: var openArray[string],
+           start = 0): bool =
+  ## returns ``true`` if ``s[start..]`` matches the ``pattern`` and
+  ## the captured substrings in the array ``matches``. If it does not
+  ## match, nothing is written into ``matches`` and ``false`` is
+  ## returned.
+  result = matchLen(s, pattern, matches, start) != -1
+
 proc find*(s: string, pattern: Regex, matches: var openArray[string],
            start = 0): int =
   ## returns the starting position of ``pattern`` in ``s`` and the captured
   ## substrings in the array ``matches``. If it does not match, nothing
   ## is written into ``matches`` and -1 is returned.
   var
-    rawMatches: array[0..MaxSubpatterns * 3 - 1, cint]
+    rtarray = initRtArray[cint]((matches.len+1)*3)
+    rawMatches = rtarray.getRawData
     res = pcre.exec(pattern.h, pattern.e, s, len(s).cint, start.cint, 0'i32,
-      cast[ptr cint](addr(rawMatches)), MaxSubpatterns * 3)
+      cast[ptr cint](rawMatches), (matches.len+1).cint*3)
   if res < 0'i32: return res
   for i in 1..int(res)-1:
     var a = rawMatches[i * 2]
@@ -197,29 +212,33 @@ proc find*(s: string, pattern: Regex, start = 0): int =
   ## returns the starting position of ``pattern`` in ``s``. If it does not
   ## match, -1 is returned.
   var
-    rawMatches: array[0..3 - 1, cint]
+    rtarray = initRtArray[cint](3)
+    rawMatches = rtarray.getRawData
     res = pcre.exec(pattern.h, nil, s, len(s).cint, start.cint, 0'i32,
-      cast[ptr cint](addr(rawMatches)), 3)
+      cast[ptr cint](rawMatches), 3)
   if res < 0'i32: return res
   return rawMatches[0]
-  
-iterator findAll*(s: string, pattern: Regex, start = 0): string = 
+
+iterator findAll*(s: string, pattern: Regex, start = 0): string =
   ## Yields all matching *substrings* of `s` that match `pattern`.
   ##
   ## Note that since this is an iterator you should not modify the string you
   ## are iterating over: bad things could happen.
-  var i = int32(start)
-  var rawMatches: array[0..MaxSubpatterns * 3 - 1, cint]
+  var
+    i = int32(start)
+    rtarray = initRtArray[cint](3)
+    rawMatches = rtarray.getRawData
   while true:
     let res = pcre.exec(pattern.h, pattern.e, s, len(s).cint, i, 0'i32,
-      cast[ptr cint](addr(rawMatches)), MaxSubpatterns * 3)
+      cast[ptr cint](rawMatches), 3)
     if res < 0'i32: break
     let a = rawMatches[0]
     let b = rawMatches[1]
+    if a == b and a == i: break
     yield substr(s, int(a), int(b)-1)
     i = b
 
-proc findAll*(s: string, pattern: Regex, start = 0): seq[string] = 
+proc findAll*(s: string, pattern: Regex, start = 0): seq[string] =
   ## returns all matching *substrings* of `s` that match `pattern`.
   ## If it does not match, @[] is returned.
   accumulateResult(findAll(s, pattern, start))
@@ -227,13 +246,13 @@ proc findAll*(s: string, pattern: Regex, start = 0): seq[string] =
 when not defined(nimhygiene):
   {.pragma: inject.}
 
-template `=~` *(s: string, pattern: Regex): expr = 
-  ## This calls ``match`` with an implicit declared ``matches`` array that 
-  ## can be used in the scope of the ``=~`` call: 
-  ## 
+template `=~` *(s: string, pattern: Regex): expr =
+  ## This calls ``match`` with an implicit declared ``matches`` array that
+  ## can be used in the scope of the ``=~`` call:
+  ##
   ## .. code-block:: nim
   ##
-  ##   if line =~ re"\s*(\w+)\s*\=\s*(\w+)": 
+  ##   if line =~ re"\s*(\w+)\s*\=\s*(\w+)":
   ##     # matches a key=value pair:
   ##     echo("Key: ", matches[0])
   ##     echo("Value: ", matches[1])
@@ -245,9 +264,9 @@ template `=~` *(s: string, pattern: Regex): expr =
   ##   else:
   ##     echo("syntax error")
   ##
-  bind MaxSubPatterns
+  bind MaxSubpatterns
   when not declaredInScope(matches):
-    var matches {.inject.}: array[0..MaxSubpatterns-1, string]
+    var matches {.inject.}: array[MaxSubpatterns, string]
   match(s, pattern, matches)
 
 # ------------------------- more string handling ------------------------------
@@ -271,11 +290,11 @@ proc endsWith*(s: string, suffix: Regex): bool =
     if matchLen(s, suffix, i) == s.len - i: return true
 
 proc replace*(s: string, sub: Regex, by = ""): string =
-  ## Replaces `sub` in `s` by the string `by`. Captures cannot be 
+  ## Replaces `sub` in `s` by the string `by`. Captures cannot be
   ## accessed in `by`. Examples:
   ##
   ## .. code-block:: nim
-  ##   "var1=key; var2=key2".replace(re"(\w+)'='(\w+)")
+  ##   "var1=key; var2=key2".replace(re"(\w+)=(\w+)")
   ##
   ## Results in:
   ##
@@ -291,13 +310,13 @@ proc replace*(s: string, sub: Regex, by = ""): string =
     add(result, by)
     prev = match.last + 1
   add(result, substr(s, prev))
-  
+
 proc replacef*(s: string, sub: Regex, by: string): string =
   ## Replaces `sub` in `s` by the string `by`. Captures can be accessed in `by`
   ## with the notation ``$i`` and ``$#`` (see strutils.`%`). Examples:
   ##
   ## .. code-block:: nim
-  ## "var1=key; var2=key2".replacef(re"(\w+)'='(\w+)", "$1<-$2$2")
+  ##   "var1=key; var2=key2".replacef(re"(\w+)=(\w+)", "$1<-$2$2")
   ##
   ## Results in:
   ##
@@ -305,7 +324,7 @@ proc replacef*(s: string, sub: Regex, by: string): string =
   ##
   ## "var1<-keykey; val2<-key2key2"
   result = ""
-  var caps: array[0..MaxSubpatterns-1, string]
+  var caps: array[MaxSubpatterns, string]
   var prev = 0
   while true:
     var match = findBounds(s, sub, caps, prev)
@@ -316,28 +335,14 @@ proc replacef*(s: string, sub: Regex, by: string): string =
     addf(result, by, caps)
     prev = match.last + 1
   add(result, substr(s, prev))
-  when false:
-    result = ""
-    var i = 0
-    var caps: array[0..MaxSubpatterns-1, string]
-    while i < s.len:
-      var x = matchLen(s, sub, caps, i)
-      if x <= 0:
-        add(result, s[i])
-        inc(i)
-      else:
-        addf(result, by, caps)
-        inc(i, x)
-    # substr the rest:
-    add(result, substr(s, i))
-  
+
 proc parallelReplace*(s: string, subs: openArray[
-                      tuple[pattern: Regex, repl: string]]): string = 
+                      tuple[pattern: Regex, repl: string]]): string =
   ## Returns a modified copy of `s` with the substitutions in `subs`
   ## applied in parallel.
   result = ""
   var i = 0
-  var caps: array[0..MaxSubpatterns-1, string]
+  var caps: array[MaxSubpatterns, string]
   while i < s.len:
     block searchSubs:
       for j in 0..high(subs):
@@ -349,8 +354,8 @@ proc parallelReplace*(s: string, subs: openArray[
       add(result, s[i])
       inc(i)
   # copy the rest:
-  add(result, substr(s, i))  
-  
+  add(result, substr(s, i))
+
 proc transformFile*(infile, outfile: string,
                     subs: openArray[tuple[pattern: Regex, repl: string]]) =
   ## reads in the file `infile`, performs a parallel replacement (calls
@@ -358,7 +363,7 @@ proc transformFile*(infile, outfile: string,
   ## error occurs. This is supposed to be used for quick scripting.
   var x = readFile(infile).string
   writeFile(outfile, x.parallelReplace(subs))
-  
+
 iterator split*(s: string, sep: Regex): string =
   ## Splits the string `s` into substrings.
   ##
@@ -372,64 +377,73 @@ iterator split*(s: string, sep: Regex): string =
   ## Results in:
   ##
   ## .. code-block:: nim
+  ##   ""
   ##   "this"
   ##   "is"
   ##   "an"
   ##   "example"
+  ##   ""
   ##
   var
-    first = 0
-    last = 0
+    first = -1
+    last = -1
   while last < len(s):
     var x = matchLen(s, sep, last)
     if x > 0: inc(last, x)
     first = last
+    if x == 0: inc(last)
     while last < len(s):
-      inc(last)
       x = matchLen(s, sep, last)
-      if x > 0: break
-    if first < last:
+      if x >= 0: break
+      inc(last)
+    if first <= last:
       yield substr(s, first, last-1)
 
 proc split*(s: string, sep: Regex): seq[string] =
   ## Splits the string `s` into substrings.
   accumulateResult(split(s, sep))
-  
-proc escapeRe*(s: string): string = 
-  ## escapes `s` so that it is matched verbatim when used as a regular 
+
+proc escapeRe*(s: string): string =
+  ## escapes `s` so that it is matched verbatim when used as a regular
   ## expression.
   result = ""
   for c in items(s):
     case c
     of 'a'..'z', 'A'..'Z', '0'..'9', '_':
       result.add(c)
-    else: 
+    else:
       result.add("\\x")
       result.add(toHex(ord(c), 2))
-  
+
 const ## common regular expressions
-  reIdentifier* = r"\b[a-zA-Z_]+[a-zA-Z_0-9]*\b"  ## describes an identifier
-  reNatural* = r"\b\d+\b" ## describes a natural number
-  reInteger* = r"\b[-+]?\d+\b" ## describes an integer
-  reHex* = r"\b0[xX][0-9a-fA-F]+\b" ## describes a hexadecimal number
-  reBinary* = r"\b0[bB][01]+\b" ## describes a binary number (example: 0b11101)
-  reOctal* = r"\b0[oO][0-7]+\b" ## describes an octal number (example: 0o777)
-  reFloat* = r"\b[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\b"
+  reIdentifier* {.deprecated.} = r"\b[a-zA-Z_]+[a-zA-Z_0-9]*\b"
+    ## describes an identifier
+  reNatural* {.deprecated.} = r"\b\d+\b"
+    ## describes a natural number
+  reInteger* {.deprecated.} = r"\b[-+]?\d+\b"
+    ## describes an integer
+  reHex* {.deprecated.} = r"\b0[xX][0-9a-fA-F]+\b"
+    ## describes a hexadecimal number
+  reBinary* {.deprecated.} = r"\b0[bB][01]+\b"
+    ## describes a binary number (example: 0b11101)
+  reOctal* {.deprecated.} = r"\b0[oO][0-7]+\b"
+    ## describes an octal number (example: 0o777)
+  reFloat* {.deprecated.} = r"\b[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\b"
     ## describes a floating point number
-  reEmail* = r"\b[a-zA-Z0-9!#$%&'*+/=?^_`{|}~\-]+(?:\. &" &
-             r"[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)" &
-             r"*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+" &
-             r"(?:[a-zA-Z]{2}|com|org|" &
-             r"net|gov|mil|biz|info|mobi|name|aero|jobs|museum)\b"
+  reEmail* {.deprecated.} = r"\b[a-zA-Z0-9!#$%&'*+/=?^_`{|}~\-]+(?:\. &" &
+                            r"[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@" &
+                            r"(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+" &
+                            r"(?:[a-zA-Z]{2}|com|org|net|gov|mil|biz|" &
+                            r"info|mobi|name|aero|jobs|museum)\b"
     ## describes a common email address
-  reURL* = r"\b(http(s)?|ftp|gopher|telnet|file|notes|ms\-help):" &
-           r"((//)|(\\\\))+[\w\d:#@%/;$()~_?\+\-\=\\\.\&]*\b"
+  reURL* {.deprecated.} = r"\b(http(s)?|ftp|gopher|telnet|file|notes|ms-help)" &
+                          r":((//)|(\\\\))+[\w\d:#@%/;$()~_?\+\-\=\\\.\&]*\b"
     ## describes an URL
 
 when isMainModule:
   assert match("(a b c)", re"\( .* \)")
   assert match("WHiLe", re("while", {reIgnoreCase}))
-  
+
   assert "0158787".match(re"\d+")
   assert "ABC 0232".match(re"\w+\s+\d+")
   assert "ABC".match(re"\d+ | \w+")
@@ -438,21 +452,21 @@ when isMainModule:
 
   var pattern = re"[a-z0-9]+\s*=\s*[a-z0-9]+"
   assert matchLen("key1=  cal9", pattern) == 11
-  
+
   assert find("_____abc_______", re"abc") == 5
-  
-  var matches: array[0..5, string]
-  if match("abcdefg", re"c(d)ef(g)", matches, 2): 
+
+  var matches: array[6, string]
+  if match("abcdefg", re"c(d)ef(g)", matches, 2):
     assert matches[0] == "d"
     assert matches[1] == "g"
   else:
     assert false
-  
+
   if "abc" =~ re"(a)bcxyz|(\w+)":
     assert matches[1] == "abc"
   else:
     assert false
-  
+
   if "abc" =~ re"(cba)?.*":
     assert matches[0] == nil
   else: assert false
@@ -460,17 +474,37 @@ when isMainModule:
   if "abc" =~ re"().*":
     assert matches[0] == ""
   else: assert false
-    
+
   assert "var1=key; var2=key2".endsWith(re"\w+=\w+")
   assert("var1=key; var2=key2".replacef(re"(\w+)=(\w+)", "$1<-$2$2") ==
          "var1<-keykey; var2<-key2key2")
   assert("var1=key; var2=key2".replace(re"(\w+)=(\w+)", "$1<-$2$2") ==
          "$1<-$2$2; $1<-$2$2")
 
+  var accum: seq[string] = @[]
   for word in split("00232this02939is39an22example111", re"\d+"):
-    writeln(stdout, word)
+    accum.add(word)
+  assert(accum == @["", "this", "is", "an", "example", ""])
+
+  accum = @[]
+  for word in split("AAA :   : BBB", re"\s*:\s*"):
+    accum.add(word)
+  assert(accum == @["AAA", "", "BBB"])
 
   for x in findAll("abcdef", re"^{.}", 3):
     assert x == "d"
+  accum = @[]
   for x in findAll("abcdef", re".", 3):
-    echo x
+    accum.add(x)
+  assert(accum == @["d", "e", "f"])
+
+  assert("XYZ".find(re"^\d*") == 0)
+  assert("XYZ".match(re"^\d*") == true)
+
+  block:
+    var matches: array[16, string]
+    if match("abcdefghijklmnop", re"(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)(m)(n)(o)(p)", matches):
+      for i in 0..matches.high:
+        assert matches[i] == $chr(i + 'a'.ord)
+    else:
+      assert false
diff --git a/lib/impure/ssl.nim b/lib/impure/ssl.nim
index bb7cfc0d3..d318a1979 100644
--- a/lib/impure/ssl.nim
+++ b/lib/impure/ssl.nim
@@ -82,7 +82,7 @@ proc close*(sock: TSecureSocket) =
     ERR_print_errors_fp(stderr)
     raiseOSError(osLastError())
 
-when isMainModule:
+when not defined(testing) and isMainModule:
   var s: TSecureSocket
   echo connect(s, "smtp.gmail.com", 465)