Merge branch 'devel' of github.com:nim-lang/Nim into devel
This commit is contained in:
commit
bea2af7ba2
49 changed files with 379 additions and 254 deletions
|
|
@ -219,20 +219,20 @@ proc processClient(client: AsyncSocket, address: string,
|
|||
else:
|
||||
await client.sendStatus("417 Expectation Failed")
|
||||
|
||||
# Read the body
|
||||
# - Check for Content-length header
|
||||
if request.headers.hasKey("Content-Length"):
|
||||
var contentLength = 0
|
||||
if parseInt(request.headers.getOrDefault("Content-Length"),
|
||||
contentLength) == 0:
|
||||
await request.respond(Http400, "Bad Request. Invalid Content-Length.")
|
||||
continue
|
||||
else:
|
||||
request.body = await client.recv(contentLength)
|
||||
assert request.body.len == contentLength
|
||||
else:
|
||||
await request.respond(Http400, "Bad Request. No Content-Length.")
|
||||
# Read the body
|
||||
# - Check for Content-length header
|
||||
if request.headers.hasKey("Content-Length"):
|
||||
var contentLength = 0
|
||||
if parseInt(request.headers.getOrDefault("Content-Length"),
|
||||
contentLength) == 0:
|
||||
await request.respond(Http400, "Bad Request. Invalid Content-Length.")
|
||||
continue
|
||||
else:
|
||||
request.body = await client.recv(contentLength)
|
||||
assert request.body.len == contentLength
|
||||
else:
|
||||
await request.respond(Http400, "Bad Request. No Content-Length.")
|
||||
continue
|
||||
|
||||
case request.reqMethod
|
||||
of "get", "post", "head", "put", "delete", "trace", "options",
|
||||
|
|
|
|||
|
|
@ -657,7 +657,7 @@ template newSeqWith*(len: int, init: expr): expr =
|
|||
## seq2D[1][0] = true
|
||||
## seq2D[0][1] = true
|
||||
##
|
||||
## import math
|
||||
## import random
|
||||
## var seqRand = newSeqWith(20, random(10))
|
||||
## echo seqRand
|
||||
var result {.gensym.} = newSeq[type(init)](len)
|
||||
|
|
|
|||
|
|
@ -79,6 +79,8 @@ proc advice*(s: var ThreadPoolState): ThreadPoolAdvice =
|
|||
inc s.calls
|
||||
|
||||
when not defined(testing) and isMainModule:
|
||||
import random
|
||||
|
||||
proc busyLoop() =
|
||||
while true:
|
||||
discard random(80)
|
||||
|
|
|
|||
|
|
@ -29,21 +29,17 @@ proc createProcType(p, b: NimNode): NimNode {.compileTime.} =
|
|||
of nnkExprColonExpr:
|
||||
identDefs.add ident[0]
|
||||
identDefs.add ident[1]
|
||||
of nnkIdent:
|
||||
else:
|
||||
identDefs.add newIdentNode("i" & $i)
|
||||
identDefs.add(ident)
|
||||
else:
|
||||
error("Incorrect type list in proc type declaration.")
|
||||
identDefs.add newEmptyNode()
|
||||
formalParams.add identDefs
|
||||
of nnkIdent:
|
||||
else:
|
||||
var identDefs = newNimNode(nnkIdentDefs)
|
||||
identDefs.add newIdentNode("i0")
|
||||
identDefs.add(p)
|
||||
identDefs.add newEmptyNode()
|
||||
formalParams.add identDefs
|
||||
else:
|
||||
error("Incorrect type list in proc type declaration.")
|
||||
|
||||
result.add formalParams
|
||||
result.add newEmptyNode()
|
||||
|
|
|
|||
|
|
@ -79,7 +79,8 @@
|
|||
## constructor should be used for this purpose. However,
|
||||
## currently only basic authentication is supported.
|
||||
|
||||
import net, strutils, uri, parseutils, strtabs, base64, os, mimetypes, math
|
||||
import net, strutils, uri, parseutils, strtabs, base64, os, mimetypes,
|
||||
math, random
|
||||
import asyncnet, asyncdispatch
|
||||
import nativesockets
|
||||
|
||||
|
|
|
|||
|
|
@ -39,8 +39,6 @@ proc fac*(n: int): int {.noSideEffect.} =
|
|||
|
||||
when defined(Posix) and not defined(haiku):
|
||||
{.passl: "-lm".}
|
||||
when not defined(js) and not defined(nimscript):
|
||||
import times
|
||||
|
||||
const
|
||||
PI* = 3.1415926535897932384626433 ## the circle constant PI (Ludolph's number)
|
||||
|
|
@ -119,30 +117,6 @@ proc sum*[T](x: openArray[T]): T {.noSideEffect.} =
|
|||
## If `x` is empty, 0 is returned.
|
||||
for i in items(x): result = result + i
|
||||
|
||||
proc random*(max: int): int {.benign.}
|
||||
## Returns a random number in the range 0..max-1. The sequence of
|
||||
## random number is always the same, unless `randomize` is called
|
||||
## which initializes the random number generator with a "random"
|
||||
## number, i.e. a tickcount.
|
||||
|
||||
proc random*(max: float): float {.benign.}
|
||||
## Returns a random number in the range 0..<max. The sequence of
|
||||
## random number is always the same, unless `randomize` is called
|
||||
## which initializes the random number generator with a "random"
|
||||
## number, i.e. a tickcount. This has a 16-bit resolution on windows
|
||||
## and a 48-bit resolution on other platforms.
|
||||
|
||||
when not defined(nimscript):
|
||||
proc randomize*() {.benign.}
|
||||
## Initializes the random number generator with a "random"
|
||||
## number, i.e. a tickcount. Note: Does nothing for the JavaScript target,
|
||||
## as JavaScript does not support this. Nor does it work for NimScript.
|
||||
|
||||
proc randomize*(seed: int) {.benign.}
|
||||
## Initializes the random number generator with a specific seed.
|
||||
## Note: Does nothing for the JavaScript target,
|
||||
## as JavaScript does not support this.
|
||||
|
||||
{.push noSideEffect.}
|
||||
when not defined(JS):
|
||||
proc sqrt*(x: float32): float32 {.importc: "sqrtf", header: "<math.h>".}
|
||||
|
|
@ -239,57 +213,6 @@ when not defined(JS):
|
|||
proc tgamma*(x: float64): float64 {.importc: "tgamma", header: "<math.h>".}
|
||||
## The gamma function
|
||||
|
||||
# C procs:
|
||||
when defined(vcc) and false:
|
||||
# The "secure" random, available from Windows XP
|
||||
# https://msdn.microsoft.com/en-us/library/sxtz2fa8.aspx
|
||||
# Present in some variants of MinGW but not enough to justify
|
||||
# `when defined(windows)` yet
|
||||
proc rand_s(val: var cuint) {.importc: "rand_s", header: "<stdlib.h>".}
|
||||
# To behave like the normal version
|
||||
proc rand(): cuint = rand_s(result)
|
||||
else:
|
||||
proc srand(seed: cint) {.importc: "srand", header: "<stdlib.h>".}
|
||||
proc rand(): cint {.importc: "rand", header: "<stdlib.h>".}
|
||||
|
||||
when not defined(windows):
|
||||
proc srand48(seed: clong) {.importc: "srand48", header: "<stdlib.h>".}
|
||||
proc drand48(): float {.importc: "drand48", header: "<stdlib.h>".}
|
||||
proc random(max: float): float =
|
||||
result = drand48() * max
|
||||
else:
|
||||
when defined(vcc): # Windows with Visual C
|
||||
proc random(max: float): float =
|
||||
# we are hardcoding this because
|
||||
# importc-ing macros is extremely problematic
|
||||
# and because the value is publicly documented
|
||||
# on MSDN and very unlikely to change
|
||||
# See https://msdn.microsoft.com/en-us/library/296az74e.aspx
|
||||
const rand_max = 4294967295 # UINT_MAX
|
||||
result = (float(rand()) / float(rand_max)) * max
|
||||
proc randomize() = discard
|
||||
proc randomize(seed: int) = discard
|
||||
else: # Windows with another compiler
|
||||
proc random(max: float): float =
|
||||
# we are hardcoding this because
|
||||
# importc-ing macros is extremely problematic
|
||||
# and because the value is publicly documented
|
||||
# on MSDN and very unlikely to change
|
||||
const rand_max = 32767
|
||||
result = (float(rand()) / float(rand_max)) * max
|
||||
|
||||
when not defined(vcc): # the above code for vcc uses `discard` instead
|
||||
# this is either not Windows or is Windows without vcc
|
||||
when not defined(nimscript):
|
||||
proc randomize() =
|
||||
randomize(cast[int](epochTime()))
|
||||
proc randomize(seed: int) =
|
||||
srand(cint(seed)) # rand_s doesn't use srand
|
||||
when declared(srand48): srand48(seed)
|
||||
|
||||
proc random(max: int): int =
|
||||
result = int(rand()) mod max
|
||||
|
||||
proc trunc*(x: float32): float32 {.importc: "truncf", header: "<math.h>".}
|
||||
proc trunc*(x: float64): float64 {.importc: "trunc", header: "<math.h>".}
|
||||
## Truncates `x` to the decimal point
|
||||
|
|
@ -319,17 +242,10 @@ when not defined(JS):
|
|||
## echo fmod(-2.5, 0.3) ## -0.1
|
||||
|
||||
else:
|
||||
proc mathrandom(): float {.importc: "Math.random", nodecl.}
|
||||
proc floor*(x: float32): float32 {.importc: "Math.floor", nodecl.}
|
||||
proc floor*(x: float64): float64 {.importc: "Math.floor", nodecl.}
|
||||
proc ceil*(x: float32): float32 {.importc: "Math.ceil", nodecl.}
|
||||
proc ceil*(x: float64): float64 {.importc: "Math.ceil", nodecl.}
|
||||
proc random(max: int): int =
|
||||
result = int(floor(mathrandom() * float(max)))
|
||||
proc random(max: float): float =
|
||||
result = float(mathrandom() * float(max))
|
||||
proc randomize() = discard
|
||||
proc randomize(seed: int) = discard
|
||||
|
||||
proc sqrt*(x: float32): float32 {.importc: "Math.sqrt", nodecl.}
|
||||
proc sqrt*(x: float64): float64 {.importc: "Math.sqrt", nodecl.}
|
||||
|
|
@ -398,14 +314,6 @@ proc `mod`*[T: float32|float64](x, y: T): T =
|
|||
## echo (4.0 mod -3.1) # -2.2
|
||||
result = if y == 0.0: x else: x - y * (x/y).floor
|
||||
|
||||
proc random*[T](x: Slice[T]): T =
|
||||
## For a slice `a .. b` returns a value in the range `a .. b-1`.
|
||||
result = random(x.b - x.a) + x.a
|
||||
|
||||
proc random*[T](a: openArray[T]): T =
|
||||
## returns a random element from the openarray `a`.
|
||||
result = a[random(a.low..a.len)]
|
||||
|
||||
{.pop.}
|
||||
{.pop.}
|
||||
|
||||
|
|
@ -440,24 +348,6 @@ proc lcm*[T](x, y: T): T =
|
|||
x div gcd(x, y) * y
|
||||
|
||||
when isMainModule and not defined(JS):
|
||||
proc gettime(dummy: ptr cint): cint {.importc: "time", header: "<time.h>".}
|
||||
|
||||
# Verifies random seed initialization.
|
||||
let seed = gettime(nil)
|
||||
randomize(seed)
|
||||
const SIZE = 10
|
||||
var buf : array[0..SIZE, int]
|
||||
# Fill the buffer with random values
|
||||
for i in 0..SIZE-1:
|
||||
buf[i] = random(high(int))
|
||||
# Check that the second random calls are the same for each position.
|
||||
randomize(seed)
|
||||
for i in 0..SIZE-1:
|
||||
assert buf[i] == random(high(int)), "non deterministic random seeding"
|
||||
|
||||
when not defined(testing):
|
||||
echo "random values equal after reseeding"
|
||||
|
||||
# Check for no side effect annotation
|
||||
proc mySqrt(num: float): float {.noSideEffect.} =
|
||||
return sqrt(num)
|
||||
|
|
|
|||
|
|
@ -606,28 +606,31 @@ proc setSockOpt*(socket: Socket, opt: SOBool, value: bool, level = SOL_SOCKET) {
|
|||
var valuei = cint(if value: 1 else: 0)
|
||||
setSockOptInt(socket.fd, cint(level), toCInt(opt), valuei)
|
||||
|
||||
when defined(posix) or defined(nimdoc):
|
||||
when defined(posix) and not defined(nimdoc):
|
||||
proc makeUnixAddr(path: string): Sockaddr_un =
|
||||
result.sun_family = AF_UNIX.toInt
|
||||
if path.len >= Sockaddr_un_path_length:
|
||||
raise newException(ValueError, "socket path too long")
|
||||
copyMem(addr result.sun_path, path.cstring, path.len + 1)
|
||||
|
||||
when defined(posix):
|
||||
proc connectUnix*(socket: Socket, path: string) =
|
||||
## Connects to Unix socket on `path`.
|
||||
## This only works on Unix-style systems: Mac OS X, BSD and Linux
|
||||
var socketAddr = makeUnixAddr(path)
|
||||
if socket.fd.connect(cast[ptr SockAddr](addr socketAddr),
|
||||
sizeof(socketAddr).Socklen) != 0'i32:
|
||||
raiseOSError(osLastError())
|
||||
when not defined(nimdoc):
|
||||
var socketAddr = makeUnixAddr(path)
|
||||
if socket.fd.connect(cast[ptr SockAddr](addr socketAddr),
|
||||
sizeof(socketAddr).Socklen) != 0'i32:
|
||||
raiseOSError(osLastError())
|
||||
|
||||
proc bindUnix*(socket: Socket, path: string) =
|
||||
## Binds Unix socket to `path`.
|
||||
## This only works on Unix-style systems: Mac OS X, BSD and Linux
|
||||
var socketAddr = makeUnixAddr(path)
|
||||
if socket.fd.bindAddr(cast[ptr SockAddr](addr socketAddr),
|
||||
sizeof(socketAddr).Socklen) != 0'i32:
|
||||
raiseOSError(osLastError())
|
||||
when not defined(nimdoc):
|
||||
var socketAddr = makeUnixAddr(path)
|
||||
if socket.fd.bindAddr(cast[ptr SockAddr](addr socketAddr),
|
||||
sizeof(socketAddr).Socklen) != 0'i32:
|
||||
raiseOSError(osLastError())
|
||||
|
||||
when defined(ssl):
|
||||
proc handshake*(socket: Socket): bool
|
||||
|
|
@ -1399,7 +1402,7 @@ proc connect*(socket: Socket, address: string, port = Port(0),
|
|||
if selectWrite(s, timeout) != 1:
|
||||
raise newException(TimeoutError, "Call to 'connect' timed out.")
|
||||
else:
|
||||
when defineSsl:
|
||||
when defineSsl and not defined(nimdoc):
|
||||
if socket.isSSL:
|
||||
socket.fd.setBlocking(true)
|
||||
{.warning[Deprecated]: off.}
|
||||
|
|
|
|||
|
|
@ -15,21 +15,21 @@
|
|||
|
||||
## This is an example of how a configuration file may look like:
|
||||
##
|
||||
## .. include:: doc/mytest.cfg
|
||||
## .. include:: ../../doc/mytest.cfg
|
||||
## :literal:
|
||||
## The file ``examples/parsecfgex.nim`` demonstrates how to use the
|
||||
## configuration file parser:
|
||||
##
|
||||
## .. code-block:: nim
|
||||
## :file: examples/parsecfgex.nim
|
||||
##
|
||||
## :file: ../../examples/parsecfgex.nim
|
||||
##
|
||||
## Examples
|
||||
## --------
|
||||
##
|
||||
## This is an example of a configuration file.
|
||||
##
|
||||
## .. include:: config.ini
|
||||
##
|
||||
##
|
||||
## ::
|
||||
##
|
||||
## charset = "utf-8"
|
||||
## [Package]
|
||||
## name = "hello"
|
||||
|
|
@ -38,11 +38,11 @@
|
|||
## name = "lihf8515"
|
||||
## qq = "10214028"
|
||||
## email = "lihaifeng@wxm.com"
|
||||
##
|
||||
##
|
||||
## Creating a configuration file.
|
||||
## ==============================
|
||||
## .. code-block:: nim
|
||||
##
|
||||
##
|
||||
## import parsecfg
|
||||
## var dict=newConfig()
|
||||
## dict.setSectionKey("","charset","utf-8")
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
## dict.setSectionKey("Author","qq","10214028")
|
||||
## dict.setSectionKey("Author","email","lihaifeng@wxm.com")
|
||||
## dict.writeConfig("config.ini")
|
||||
##
|
||||
##
|
||||
## Reading a configuration file.
|
||||
## =============================
|
||||
## .. code-block:: nim
|
||||
|
|
@ -66,11 +66,11 @@
|
|||
## var qq = dict.getSectionValue("Author","qq")
|
||||
## var email = dict.getSectionValue("Author","email")
|
||||
## echo pname & "\n" & name & "\n" & qq & "\n" & email
|
||||
##
|
||||
##
|
||||
## Modifying a configuration file.
|
||||
## ===============================
|
||||
## .. code-block:: nim
|
||||
##
|
||||
##
|
||||
## import parsecfg
|
||||
## var dict = loadConfig("config.ini")
|
||||
## dict.setSectionKey("Author","name","lhf")
|
||||
|
|
@ -79,7 +79,7 @@
|
|||
## Deleting a section key in a configuration file.
|
||||
## ===============================================
|
||||
## .. code-block:: nim
|
||||
##
|
||||
##
|
||||
## import parsecfg
|
||||
## var dict = loadConfig("config.ini")
|
||||
## dict.delSectionKey("Author","email")
|
||||
|
|
@ -434,7 +434,7 @@ proc loadConfig*(filename: string): Config =
|
|||
## Load the specified configuration file into a new Config instance.
|
||||
var dict = newOrderedTable[string, OrderedTableRef[string, string]]()
|
||||
var curSection = "" ## Current section,
|
||||
## the default value of the current section is "",
|
||||
## the default value of the current section is "",
|
||||
## which means that the current section is a common
|
||||
var p: CfgParser
|
||||
var fileStream = newFileStream(filename, fmRead)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
## document.
|
||||
##
|
||||
## .. code-block:: nim
|
||||
## :file: examples/htmltitle.nim
|
||||
## :file: ../../examples/htmltitle.nim
|
||||
##
|
||||
##
|
||||
## Example 2: Retrieve all HTML links
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
## an HTML document contains.
|
||||
##
|
||||
## .. code-block:: nim
|
||||
## :file: examples/htmlrefs.nim
|
||||
## :file: ../../examples/htmlrefs.nim
|
||||
##
|
||||
|
||||
import
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
## Matching performance is hopefully competitive with optimized regular
|
||||
## expression engines.
|
||||
##
|
||||
## .. include:: ../doc/pegdocs.txt
|
||||
## .. include:: ../../doc/pegdocs.txt
|
||||
##
|
||||
|
||||
include "system/inclrtl"
|
||||
|
|
|
|||
129
lib/pure/random.nim
Normal file
129
lib/pure/random.nim
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
#
|
||||
#
|
||||
# Nim's Runtime Library
|
||||
# (c) Copyright 2016 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
##[Nim's standard random number generator. Based on
|
||||
|
||||
| `http://xoroshiro.di.unimi.it/`_
|
||||
| `http://xoroshiro.di.unimi.it/xoroshiro128plus.c`_
|
||||
]##
|
||||
|
||||
include "system/inclrtl"
|
||||
{.push debugger:off.}
|
||||
|
||||
# XXX Expose RandomGenState
|
||||
when defined(JS):
|
||||
type ui = uint32
|
||||
else:
|
||||
type ui = uint64
|
||||
|
||||
type
|
||||
RandomGenState = object
|
||||
a0, a1: ui
|
||||
|
||||
when defined(JS):
|
||||
var state = RandomGenState(
|
||||
a0: 0x69B4C98Cu32,
|
||||
a1: 0xFED1DD30u32) # global for backwards compatibility
|
||||
else:
|
||||
# racy for multi-threading but good enough for now:
|
||||
var state = RandomGenState(
|
||||
a0: 0x69B4C98CB8530805u64,
|
||||
a1: 0xFED1DD3004688D67CAu64) # global for backwards compatibility
|
||||
|
||||
proc rotl(x, k: ui): ui =
|
||||
result = (x shl k) or (x shr (ui(64) - k))
|
||||
|
||||
proc next(s: var RandomGenState): uint64 =
|
||||
let s0 = s.a0
|
||||
var s1 = s.a1
|
||||
result = s0 + s1
|
||||
s1 = s1 xor s0
|
||||
s.a0 = rotl(s0, 55) xor s1 xor (s1 shl 14) # a, b
|
||||
s.a1 = rotl(s1, 36) # c
|
||||
|
||||
proc skipRandomNumbers(s: var RandomGenState) =
|
||||
## This is the jump function for the generator. It is equivalent
|
||||
## to 2^64 calls to next(); it can be used to generate 2^64
|
||||
## non-overlapping subsequences for parallel computations.
|
||||
when defined(JS):
|
||||
const helper = [0xbeac0467u32, 0xd86b048bu32]
|
||||
else:
|
||||
const helper = [0xbeac0467eba5facbu64, 0xd86b048b86aa9922u64]
|
||||
var
|
||||
s0 = ui 0
|
||||
s1 = ui 0
|
||||
for i in 0..high(helper):
|
||||
for b in 0..< 64:
|
||||
if (helper[i] and (ui(1) shl ui(b))) != 0:
|
||||
s0 = s0 xor s.a0
|
||||
s1 = s1 xor s.a1
|
||||
discard next(s)
|
||||
s.a0 = s0
|
||||
s.a1 = s1
|
||||
|
||||
proc random*(max: int): int {.benign.} =
|
||||
## Returns a random number in the range 0..max-1. The sequence of
|
||||
## random number is always the same, unless `randomize` is called
|
||||
## which initializes the random number generator with a "random"
|
||||
## number, i.e. a tickcount.
|
||||
result = int(next(state) mod uint64(max))
|
||||
|
||||
proc random*(max: float): float {.benign.} =
|
||||
## Returns a random number in the range 0..<max. The sequence of
|
||||
## random number is always the same, unless `randomize` is called
|
||||
## which initializes the random number generator with a "random"
|
||||
## number, i.e. a tickcount.
|
||||
let x = next(state)
|
||||
when defined(JS):
|
||||
result = (float(x) / float(high(uint32))) * max
|
||||
else:
|
||||
let u = (0x3FFu64 shl 52u64) or (x shr 12u64)
|
||||
result = (cast[float](u) - 1.0) * max
|
||||
|
||||
proc random*[T](x: Slice[T]): T =
|
||||
## For a slice `a .. b` returns a value in the range `a .. b-1`.
|
||||
result = random(x.b - x.a) + x.a
|
||||
|
||||
proc random*[T](a: openArray[T]): T =
|
||||
## returns a random element from the openarray `a`.
|
||||
result = a[random(a.low..a.len)]
|
||||
|
||||
proc randomize*(seed: int) {.benign.} =
|
||||
## Initializes the random number generator with a specific seed.
|
||||
state.a0 = ui(seed shr 16)
|
||||
state.a1 = ui(seed and 0xffff)
|
||||
|
||||
when not defined(nimscript):
|
||||
import times
|
||||
|
||||
proc randomize*() {.benign.} =
|
||||
## Initializes the random number generator with a "random"
|
||||
## number, i.e. a tickcount. Note: Does not work for NimScript.
|
||||
when defined(JS):
|
||||
proc getMil(t: Time): int {.importcpp: "getTime", nodecl.}
|
||||
randomize(getMil times.getTime())
|
||||
else:
|
||||
randomize(int times.getTime())
|
||||
|
||||
{.pop.}
|
||||
|
||||
when isMainModule:
|
||||
proc main =
|
||||
var occur: array[1000, int]
|
||||
|
||||
var x = 8234
|
||||
for i in 0..100_000:
|
||||
x = random(len(occur)) # myrand(x)
|
||||
inc occur[x]
|
||||
for i, oc in occur:
|
||||
if oc < 69:
|
||||
doAssert false, "too few occurances of " & $i
|
||||
elif oc > 130:
|
||||
doAssert false, "too many occurances of " & $i
|
||||
main()
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
## Nim support for `substitution expressions`:idx: (`subex`:idx:).
|
||||
##
|
||||
## .. include:: ../doc/subexes.txt
|
||||
## .. include:: ../../doc/subexes.txt
|
||||
##
|
||||
|
||||
{.push debugger:off .} # the user does not want to trace a part
|
||||
|
|
|
|||
|
|
@ -64,8 +64,9 @@ when defined(posix) and not defined(JS):
|
|||
proc posix_gettimeofday(tp: var Timeval, unused: pointer = nil) {.
|
||||
importc: "gettimeofday", header: "<sys/time.h>".}
|
||||
|
||||
var
|
||||
timezone {.importc, header: "<time.h>".}: int
|
||||
when not defined(freebsd) and not defined(netbsd) and not defined(openbsd):
|
||||
var timezone {.importc, header: "<time.h>".}: int
|
||||
var
|
||||
tzname {.importc, header: "<time.h>" .}: array[0..1, cstring]
|
||||
# we also need tzset() to make sure that tzname is initialized
|
||||
proc tzset() {.importc, header: "<time.h>".}
|
||||
|
|
@ -416,18 +417,32 @@ when not defined(JS):
|
|||
|
||||
when not defined(JS):
|
||||
# C wrapper:
|
||||
when defined(freebsd) or defined(netbsd) or defined(openbsd):
|
||||
type
|
||||
StructTM {.importc: "struct tm", final.} = object
|
||||
second {.importc: "tm_sec".},
|
||||
minute {.importc: "tm_min".},
|
||||
hour {.importc: "tm_hour".},
|
||||
monthday {.importc: "tm_mday".},
|
||||
month {.importc: "tm_mon".},
|
||||
year {.importc: "tm_year".},
|
||||
weekday {.importc: "tm_wday".},
|
||||
yearday {.importc: "tm_yday".},
|
||||
isdst {.importc: "tm_isdst".}: cint
|
||||
gmtoff {.importc: "tm_gmtoff".}: clong
|
||||
else:
|
||||
type
|
||||
StructTM {.importc: "struct tm", final.} = object
|
||||
second {.importc: "tm_sec".},
|
||||
minute {.importc: "tm_min".},
|
||||
hour {.importc: "tm_hour".},
|
||||
monthday {.importc: "tm_mday".},
|
||||
month {.importc: "tm_mon".},
|
||||
year {.importc: "tm_year".},
|
||||
weekday {.importc: "tm_wday".},
|
||||
yearday {.importc: "tm_yday".},
|
||||
isdst {.importc: "tm_isdst".}: cint
|
||||
type
|
||||
StructTM {.importc: "struct tm", final.} = object
|
||||
second {.importc: "tm_sec".},
|
||||
minute {.importc: "tm_min".},
|
||||
hour {.importc: "tm_hour".},
|
||||
monthday {.importc: "tm_mday".},
|
||||
month {.importc: "tm_mon".},
|
||||
year {.importc: "tm_year".},
|
||||
weekday {.importc: "tm_wday".},
|
||||
yearday {.importc: "tm_yday".},
|
||||
isdst {.importc: "tm_isdst".}: cint
|
||||
|
||||
TimeInfoPtr = ptr StructTM
|
||||
Clock {.importc: "clock_t".} = distinct int
|
||||
|
||||
|
|
@ -457,24 +472,47 @@ when not defined(JS):
|
|||
const
|
||||
weekDays: array [0..6, WeekDay] = [
|
||||
dSun, dMon, dTue, dWed, dThu, dFri, dSat]
|
||||
TimeInfo(second: int(tm.second),
|
||||
minute: int(tm.minute),
|
||||
hour: int(tm.hour),
|
||||
monthday: int(tm.monthday),
|
||||
month: Month(tm.month),
|
||||
year: tm.year + 1900'i32,
|
||||
weekday: weekDays[int(tm.weekday)],
|
||||
yearday: int(tm.yearday),
|
||||
isDST: tm.isdst > 0,
|
||||
tzname: if local:
|
||||
if tm.isdst > 0:
|
||||
getTzname().DST
|
||||
when defined(freebsd) or defined(netbsd) or defined(openbsd):
|
||||
TimeInfo(second: int(tm.second),
|
||||
minute: int(tm.minute),
|
||||
hour: int(tm.hour),
|
||||
monthday: int(tm.monthday),
|
||||
month: Month(tm.month),
|
||||
year: tm.year + 1900'i32,
|
||||
weekday: weekDays[int(tm.weekday)],
|
||||
yearday: int(tm.yearday),
|
||||
isDST: tm.isdst > 0,
|
||||
tzname: if local:
|
||||
if tm.isdst > 0:
|
||||
getTzname().DST
|
||||
else:
|
||||
getTzname().nonDST
|
||||
else:
|
||||
getTzname().nonDST
|
||||
else:
|
||||
"UTC",
|
||||
timezone: if local: getTimezone() else: 0
|
||||
)
|
||||
"UTC",
|
||||
# BSD stores in `gmtoff` offset east of UTC in seconds,
|
||||
# but posix systems using west of UTC in seconds
|
||||
timezone: if local: -(tm.gmtoff) else: 0
|
||||
)
|
||||
else:
|
||||
TimeInfo(second: int(tm.second),
|
||||
minute: int(tm.minute),
|
||||
hour: int(tm.hour),
|
||||
monthday: int(tm.monthday),
|
||||
month: Month(tm.month),
|
||||
year: tm.year + 1900'i32,
|
||||
weekday: weekDays[int(tm.weekday)],
|
||||
yearday: int(tm.yearday),
|
||||
isDST: tm.isdst > 0,
|
||||
tzname: if local:
|
||||
if tm.isdst > 0:
|
||||
getTzname().DST
|
||||
else:
|
||||
getTzname().nonDST
|
||||
else:
|
||||
"UTC",
|
||||
timezone: if local: getTimezone() else: 0
|
||||
)
|
||||
|
||||
|
||||
proc timeInfoToTM(t: TimeInfo): StructTM =
|
||||
const
|
||||
|
|
@ -564,7 +602,14 @@ when not defined(JS):
|
|||
return ($tzname[0], $tzname[1])
|
||||
|
||||
proc getTimezone(): int =
|
||||
return timezone
|
||||
when defined(freebsd) or defined(netbsd) or defined(openbsd):
|
||||
var a = timec(nil)
|
||||
let lt = localtime(addr(a))
|
||||
# BSD stores in `gmtoff` offset east of UTC in seconds,
|
||||
# but posix systems using west of UTC in seconds
|
||||
return -(lt.gmtoff)
|
||||
else:
|
||||
return timezone
|
||||
|
||||
proc fromSeconds(since1970: float): Time = Time(since1970)
|
||||
|
||||
|
|
|
|||
|
|
@ -310,7 +310,7 @@ macro expect*(exceptions: varargs[expr], body: stmt): stmt {.immediate.} =
|
|||
##
|
||||
## .. code-block:: nim
|
||||
##
|
||||
## import math
|
||||
## import math, random
|
||||
## proc defectiveRobot() =
|
||||
## randomize()
|
||||
## case random(1..4)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue