summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorDominik Picheta <dominikpicheta@gmail.com>2016-04-04 12:06:42 +0100
committerDominik Picheta <dominikpicheta@gmail.com>2016-04-04 12:06:42 +0100
commit436b0031736b7b569f18a90c67e62a483716037a (patch)
treed938d5efd6ea4125c9f5d543ccca7489e637a4cb /lib
parenta70e6b3fde7c251aff68243de1c7adcebc3c67e3 (diff)
parentfbedb6c65514e394f163a68dd530d19d310afadf (diff)
downloadNim-436b0031736b7b569f18a90c67e62a483716037a.tar.gz
Merge branch 'devel' of github.com:nim-lang/Nim into devel
Diffstat (limited to 'lib')
-rw-r--r--lib/core/locks.nim3
-rw-r--r--lib/core/rlocks.nim1
-rw-r--r--lib/posix/posix.nim13
-rw-r--r--lib/pure/collections/chains.nim44
-rw-r--r--lib/pure/mersenne.nim28
-rw-r--r--lib/pure/net.nim4
-rw-r--r--lib/pure/parseutils.nim41
-rw-r--r--lib/pure/strutils.nim18
-rw-r--r--lib/system.nim1
-rw-r--r--lib/system/dyncalls.nim25
-rw-r--r--lib/system/syslocks.nim61
11 files changed, 188 insertions, 51 deletions
diff --git a/lib/core/locks.nim b/lib/core/locks.nim
index 66e0ab520..fbe9c8acf 100644
--- a/lib/core/locks.nim
+++ b/lib/core/locks.nim
@@ -9,6 +9,7 @@
 
 ## This module contains Nim's support for locks and condition vars.
 
+const insideRLocksModule = false
 include "system/syslocks"
 
 type
@@ -63,4 +64,4 @@ template withLock*(a: Lock, body: untyped) =
     try:
       body
     finally:
-      a.release()
\ No newline at end of file
+      a.release()
diff --git a/lib/core/rlocks.nim b/lib/core/rlocks.nim
index 14f04592b..4710d6cf1 100644
--- a/lib/core/rlocks.nim
+++ b/lib/core/rlocks.nim
@@ -9,6 +9,7 @@
 
 ## This module contains Nim's support for reentrant locks.
 
+const insideRLocksModule = true
 include "system/syslocks"
 
 type
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim
index 4c7b817cb..e932d2845 100644
--- a/lib/posix/posix.nim
+++ b/lib/posix/posix.nim
@@ -35,6 +35,15 @@ const
   hasSpawnH = not defined(haiku) # should exist for every Posix system nowadays
   hasAioH = defined(linux)
 
+when defined(linux):
+  # On Linux:
+  # timer_{create,delete,settime,gettime},
+  # clock_{getcpuclockid, getres, gettime, nanosleep, settime} lives in librt
+  {.passL: "-lrt".}
+when defined(solaris):
+  # On Solaris hstrerror lives in libresolv
+  {.passL: "-lresolv".}
+
 when false:
   const
     C_IRUSR = 0c000400 ## Read by owner.
@@ -2309,9 +2318,9 @@ proc strftime*(a1: cstring, a2: int, a3: cstring,
            a4: var Tm): int {.importc, header: "<time.h>".}
 proc strptime*(a1, a2: cstring, a3: var Tm): cstring {.importc, header: "<time.h>".}
 proc time*(a1: var Time): Time {.importc, header: "<time.h>".}
-proc timer_create*(a1: var ClockId, a2: var SigEvent,
+proc timer_create*(a1: ClockId, a2: var SigEvent,
                a3: var Timer): cint {.importc, header: "<time.h>".}
-proc timer_delete*(a1: var Timer): cint {.importc, header: "<time.h>".}
+proc timer_delete*(a1: Timer): cint {.importc, header: "<time.h>".}
 proc timer_gettime*(a1: Timer, a2: var Itimerspec): cint {.
   importc, header: "<time.h>".}
 proc timer_getoverrun*(a1: Timer): cint {.importc, header: "<time.h>".}
diff --git a/lib/pure/collections/chains.nim b/lib/pure/collections/chains.nim
new file mode 100644
index 000000000..6b2ecd272
--- /dev/null
+++ b/lib/pure/collections/chains.nim
@@ -0,0 +1,44 @@
+#
+#
+#            Nim's Runtime Library
+#        (c) Copyright 2016 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## Template based implementation of singly and doubly linked lists.
+## The involved types should have 'prev' or 'next' fields and the
+## list header should have 'head' or 'tail' fields.
+
+template prepend*(header, node) =
+  when compiles(header.head):
+    when compiles(node.prev):
+      if header.head != nil:
+        header.head.prev = node
+    node.next = header.head
+    header.head = node
+  when compiles(header.tail):
+    if header.tail == nil:
+      header.tail = node
+
+template append*(header, node) =
+  when compiles(header.head):
+    if header.head == nil:
+      header.head = node
+  when compiles(header.tail):
+    when compiles(node.prev):
+      node.prev = header.tail
+    if header.tail != nil:
+      header.tail.next = node
+    header.tail = node
+
+template unlink*(header, node) =
+  if node.next != nil:
+    node.next.prev = node.prev
+  if node.prev != nil:
+    node.prev.next = node.next
+  if header.head == node:
+    header.head = node.prev
+  if header.tail == node:
+    header.tail = node.next
diff --git a/lib/pure/mersenne.nim b/lib/pure/mersenne.nim
index ae0845714..afa343086 100644
--- a/lib/pure/mersenne.nim
+++ b/lib/pure/mersenne.nim
@@ -5,29 +5,31 @@ type
 
 {.deprecated: [TMersenneTwister: MersenneTwister].}
 
-proc newMersenneTwister*(seed: int): MersenneTwister =
+proc newMersenneTwister*(seed: uint32): MersenneTwister =
   result.index = 0
-  result.mt[0]= uint32(seed)
+  result.mt[0] = seed
   for i in 1..623'u32:
-    result.mt[i]= (0x6c078965'u32 * (result.mt[i-1] xor (result.mt[i-1] shr 30'u32)) + i)
+    result.mt[i] = (0x6c078965'u32 * (result.mt[i-1] xor (result.mt[i-1] shr 30'u32)) + i)
 
 proc generateNumbers(m: var MersenneTwister) =
   for i in 0..623:
-    var y = (m.mt[i] and 0x80000000'u32) + (m.mt[(i+1) mod 624] and 0x7fffffff'u32)
+    var y = (m.mt[i] and 0x80000000'u32) +
+            (m.mt[(i+1) mod 624] and 0x7fffffff'u32)
     m.mt[i] = m.mt[(i+397) mod 624] xor uint32(y shr 1'u32)
     if (y mod 2'u32) != 0:
-     m.mt[i] = m.mt[i] xor 0x9908b0df'u32
+      m.mt[i] = m.mt[i] xor 0x9908b0df'u32
 
-proc getNum*(m: var MersenneTwister): int =
+proc getNum*(m: var MersenneTwister): uint32 =
+  ## Returns the next pseudo random number ranging from 0 to high(uint32)
   if m.index == 0:
     generateNumbers(m)
-  var y = m.mt[m.index]
-  y = y xor (y shr 11'u32)
-  y = y xor ((7'u32 shl y) and 0x9d2c5680'u32)
-  y = y xor ((15'u32 shl y) and 0xefc60000'u32)
-  y = y xor (y shr 18'u32)
-  m.index = (m.index+1) mod 624
-  return int(y)
+  result = m.mt[m.index]
+  m.index = (m.index + 1) mod m.mt.len
+
+  result = result xor (result shr 11'u32)
+  result = result xor ((7'u32 shl result) and 0x9d2c5680'u32)
+  result = result xor ((15'u32 shl result) and 0xefc60000'u32)
+  result = result xor (result shr 18'u32)
 
 # Test
 when not defined(testing) and isMainModule:
diff --git a/lib/pure/net.nim b/lib/pure/net.nim
index 330682ca9..394bccee3 100644
--- a/lib/pure/net.nim
+++ b/lib/pure/net.nim
@@ -222,9 +222,9 @@ when defined(ssl):
     of protSSLv23:
       newCTX = SSL_CTX_new(SSLv23_method()) # SSlv2,3 and TLS1 support.
     of protSSLv2:
-      raiseSslError("SSLv2 is no longer secure and has been deprecated, use protSSLv3")
+      raiseSslError("SSLv2 is no longer secure and has been deprecated, use protSSLv23")
     of protSSLv3:
-      newCTX = SSL_CTX_new(SSLv3_method())
+      raiseSslError("SSLv3 is no longer secure and has been deprecated, use protSSLv23")
     of protTLSv1:
       newCTX = SSL_CTX_new(TLSv1_method())
 
diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim
index 698bde42a..3e25eba22 100644
--- a/lib/pure/parseutils.nim
+++ b/lib/pure/parseutils.nim
@@ -234,6 +234,47 @@ proc parseInt*(s: string, number: var int, start = 0): int {.
   elif result != 0:
     number = int(res)
 
+# overflowChecks doesn't work with uint64
+proc rawParseUInt(s: string, b: var uint64, start = 0): int =
+  var
+    res = 0'u64
+    prev = 0'u64
+    i = start
+  if s[i] == '+': inc(i) # Allow 
+  if s[i] in {'0'..'9'}:
+    b = 0
+    while s[i] in {'0'..'9'}:
+      prev = res
+      res = res * 10 + (ord(s[i]) - ord('0')).uint64
+      if prev > res:
+        return 0 # overflowChecks emulation
+      inc(i)
+      while s[i] == '_': inc(i) # underscores are allowed and ignored
+    b = res
+    result = i - start
+
+proc parseBiggestUInt*(s: string, number: var uint64, start = 0): int {.
+  rtl, extern: "npuParseBiggestUInt", noSideEffect.} =
+  ## parses an unsigned integer starting at `start` and stores the value into `number`.
+  ## Result is the number of processed chars or 0 if there is no integer or overflow detected.
+  var res: uint64
+  # use 'res' for exception safety (don't write to 'number' in case of an
+  # overflow exception):
+  result = rawParseUInt(s, res, start)
+  number = res
+
+proc parseUInt*(s: string, number: var uint, start = 0): int {.
+  rtl, extern: "npuParseUInt", noSideEffect.} =
+  ## parses an unsigned integer starting at `start` and stores the value into `number`.
+  ## Result is the number of processed chars or 0 if there is no integer or overflow detected.
+  var res: uint64
+  result = parseBiggestUInt(s, res, start)
+  if (sizeof(uint) <= 4) and
+      (res > 0xFFFF_FFFF'u64):
+    raise newException(OverflowError, "overflow")
+  elif result != 0:
+    number = uint(res)
+
 proc parseBiggestFloat*(s: string, number: var BiggestFloat, start = 0): int {.
   magic: "ParseBiggestFloat", importc: "nimParseBiggestFloat", noSideEffect.}
   ## parses a float starting at `start` and stores the value into `number`.
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim
index f2c1e77e1..eebadf4c0 100644
--- a/lib/pure/strutils.nim
+++ b/lib/pure/strutils.nim
@@ -560,6 +560,24 @@ proc parseBiggestInt*(s: string): BiggestInt {.noSideEffect, procvar,
   if L != s.len or L == 0:
     raise newException(ValueError, "invalid integer: " & s)
 
+proc parseUInt*(s: string): uint {.noSideEffect, procvar,
+  rtl, extern: "nsuParseUInt".} =
+  ## Parses a decimal unsigned integer value contained in `s`.
+  ##
+  ## If `s` is not a valid integer, `ValueError` is raised.
+  var L = parseutils.parseUInt(s, result, 0)
+  if L != s.len or L == 0:
+    raise newException(ValueError, "invalid unsigned integer: " & s)
+
+proc parseBiggestUInt*(s: string): uint64 {.noSideEffect, procvar,
+  rtl, extern: "nsuParseBiggestUInt".} =
+  ## Parses a decimal unsigned integer value contained in `s`.
+  ##
+  ## If `s` is not a valid integer, `ValueError` is raised.
+  var L = parseutils.parseBiggestUInt(s, result, 0)
+  if L != s.len or L == 0:
+    raise newException(ValueError, "invalid unsigned integer: " & s)
+
 proc parseFloat*(s: string): float {.noSideEffect, procvar,
   rtl, extern: "nsuParseFloat".} =
   ## Parses a decimal floating point value contained in `s`. If `s` is not
diff --git a/lib/system.nim b/lib/system.nim
index d3b18f9e3..53204306d 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -2877,6 +2877,7 @@ when not defined(JS): #and not defined(nimscript):
   when declared(initAllocator):
     initAllocator()
   when hasThreadSupport:
+    const insideRLocksModule = false
     include "system/syslocks"
     when hostOS != "standalone": include "system/threads"
   elif not defined(nogc) and not defined(nimscript):
diff --git a/lib/system/dyncalls.nim b/lib/system/dyncalls.nim
index 3b3d1f87d..61777e514 100644
--- a/lib/system/dyncalls.nim
+++ b/lib/system/dyncalls.nim
@@ -109,9 +109,30 @@ elif defined(windows) or defined(dos):
   proc nimGetProcAddr(lib: LibHandle, name: cstring): ProcAddr =
     result = getProcAddress(cast[THINSTANCE](lib), name)
     if result != nil: return
-    var decorated: array[250, char]
+    const decorated_length = 250
+    var decorated: array[decorated_length, char]
+    decorated[0] = '_'
+    var m = 1
+    while m < (decorated_length - 5):
+      if name[m - 1] == '\x00': break
+      decorated[m] = name[m - 1]
+      inc(m)
+    decorated[m] = '@'
     for i in countup(0, 50):
-      discard csprintf(decorated, "_%s@%ld", name, i*4)
+      var k = i * 4
+      if k div 100 == 0: 
+        if k div 10 == 0:
+          m = m + 1
+        else:
+          m = m + 2
+      else:
+        m = m + 3
+      decorated[m + 1] = '\x00'
+      while true:
+        decorated[m] = chr(ord('0') + (k %% 10))
+        dec(m)
+        k = k div 10
+        if k == 0: break
       result = getProcAddress(cast[THINSTANCE](lib), decorated)
       if result != nil: return
     procAddrError(name)
diff --git a/lib/system/syslocks.nim b/lib/system/syslocks.nim
index 6dcdfff0d..1695deca1 100644
--- a/lib/system/syslocks.nim
+++ b/lib/system/syslocks.nim
@@ -14,39 +14,41 @@
 when defined(Windows):
   type
     Handle = int
-    SysLock {.final, pure.} = object # CRITICAL_SECTION in WinApi
+
+    SysLock {.importc: "CRITICAL_SECTION",
+              header: "<windows.h>", final, pure.} = object # CRITICAL_SECTION in WinApi
       DebugInfo: pointer
       LockCount: int32
       RecursionCount: int32
       OwningThread: int
       LockSemaphore: int
-      Reserved: int32
+      SpinCount: int
 
     SysCond = Handle
 
   {.deprecated: [THandle: Handle, TSysLock: SysLock, TSysCond: SysCond].}
 
-  proc initSysLock(L: var SysLock) {.stdcall, noSideEffect,
-    dynlib: "kernel32", importc: "InitializeCriticalSection".}
+  proc initSysLock(L: var SysLock) {.importc: "InitializeCriticalSection",
+                                     header: "<windows.h>".}
     ## Initializes the lock `L`.
 
-  proc tryAcquireSysAux(L: var SysLock): int32 {.stdcall, noSideEffect,
-    dynlib: "kernel32", importc: "TryEnterCriticalSection".}
+  proc tryAcquireSysAux(L: var SysLock): int32 {.importc: "TryEnterCriticalSection",
+                                                 header: "<windows.h>".}
     ## Tries to acquire the lock `L`.
 
   proc tryAcquireSys(L: var SysLock): bool {.inline.} =
     result = tryAcquireSysAux(L) != 0'i32
 
-  proc acquireSys(L: var SysLock) {.stdcall, noSideEffect,
-    dynlib: "kernel32", importc: "EnterCriticalSection".}
+  proc acquireSys(L: var SysLock) {.importc: "EnterCriticalSection",
+                                    header: "<windows.h>".}
     ## Acquires the lock `L`.
 
-  proc releaseSys(L: var SysLock) {.stdcall, noSideEffect,
-    dynlib: "kernel32", importc: "LeaveCriticalSection".}
+  proc releaseSys(L: var SysLock) {.importc: "LeaveCriticalSection",
+                                    header: "<windows.h>".}
     ## Releases the lock `L`.
 
-  proc deinitSys(L: var SysLock) {.stdcall, noSideEffect,
-    dynlib: "kernel32", importc: "DeleteCriticalSection".}
+  proc deinitSys(L: var SysLock) {.importc: "DeleteCriticalSection",
+                                   header: "<windows.h>".}
 
   proc createEvent(lpEventAttributes: pointer,
                    bManualReset, bInitialState: int32,
@@ -86,17 +88,16 @@ else:
                           #include <pthread.h>""".} = object
     SysLockType = distinct cint
 
-  proc SysLockType_Reentrant: SysLockType =
-    {.emit: "`result` = PTHREAD_MUTEX_RECURSIVE;".}
-
   proc initSysLock(L: var SysLock, attr: ptr SysLockAttr = nil) {.
     importc: "pthread_mutex_init", header: "<pthread.h>", noSideEffect.}
 
-  proc initSysLockAttr(a: var SysLockAttr) {.
-    importc: "pthread_mutexattr_init", header: "<pthread.h>", noSideEffect.}
-
-  proc setSysLockType(a: var SysLockAttr, t: SysLockType) {.
-    importc: "pthread_mutexattr_settype", header: "<pthread.h>", noSideEffect.}
+  when insideRLocksModule:
+    proc SysLockType_Reentrant: SysLockType =
+      {.emit: "`result` = PTHREAD_MUTEX_RECURSIVE;".}
+    proc initSysLockAttr(a: var SysLockAttr) {.
+      importc: "pthread_mutexattr_init", header: "<pthread.h>", noSideEffect.}
+    proc setSysLockType(a: var SysLockAttr, t: SysLockType) {.
+      importc: "pthread_mutexattr_settype", header: "<pthread.h>", noSideEffect.}
 
   proc acquireSys(L: var SysLock) {.noSideEffect,
     importc: "pthread_mutex_lock", header: "<pthread.h>".}
@@ -111,14 +112,12 @@ else:
   proc deinitSys(L: var SysLock) {.noSideEffect,
     importc: "pthread_mutex_destroy", header: "<pthread.h>".}
 
-  proc initSysCond(cond: var SysCond, cond_attr: pointer = nil) {.
-    importc: "pthread_cond_init", header: "<pthread.h>", noSideEffect.}
-  proc waitSysCond(cond: var SysCond, lock: var SysLock) {.
-    importc: "pthread_cond_wait", header: "<pthread.h>", noSideEffect.}
-  proc signalSysCond(cond: var SysCond) {.
-    importc: "pthread_cond_signal", header: "<pthread.h>", noSideEffect.}
-
-  proc deinitSysCond(cond: var SysCond) {.noSideEffect,
-    importc: "pthread_cond_destroy", header: "<pthread.h>".}
-
-{.pop.}
+  when not insideRLocksModule:
+    proc initSysCond(cond: var SysCond, cond_attr: pointer = nil) {.
+      importc: "pthread_cond_init", header: "<pthread.h>", noSideEffect.}
+    proc waitSysCond(cond: var SysCond, lock: var SysLock) {.
+      importc: "pthread_cond_wait", header: "<pthread.h>", noSideEffect.}
+    proc signalSysCond(cond: var SysCond) {.
+      importc: "pthread_cond_signal", header: "<pthread.h>", noSideEffect.}
+    proc deinitSysCond(cond: var SysCond) {.noSideEffect,
+      importc: "pthread_cond_destroy", header: "<pthread.h>".}