mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-18 21:40:32 +00:00
Merge branch 'devel' of github.com:nim-lang/Nim into devel
This commit is contained in:
@@ -1202,18 +1202,30 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||
# we skip this step here:
|
||||
if not p.module.compileToCpp:
|
||||
if handleConstExpr(p, e, d): return
|
||||
var tmp: TLoc
|
||||
var t = e.typ.skipTypes(abstractInst)
|
||||
getTemp(p, t, tmp)
|
||||
let isRef = t.kind == tyRef
|
||||
var r = rdLoc(tmp)
|
||||
if isRef:
|
||||
rawGenNew(p, tmp, nil)
|
||||
t = t.lastSon.skipTypes(abstractInst)
|
||||
r = "(*$1)" % [r]
|
||||
gcUsage(e)
|
||||
|
||||
# check if we need to construct the object in a temporary
|
||||
var useTemp =
|
||||
isRef or
|
||||
(d.k notin {locTemp,locLocalVar,locGlobalVar,locParam,locField}) or
|
||||
(isPartOf(d.lode, e) != arNo)
|
||||
|
||||
var tmp: TLoc
|
||||
var r: Rope
|
||||
if useTemp:
|
||||
getTemp(p, t, tmp)
|
||||
r = rdLoc(tmp)
|
||||
if isRef:
|
||||
rawGenNew(p, tmp, nil)
|
||||
t = t.lastSon.skipTypes(abstractInst)
|
||||
r = "(*$1)" % [r]
|
||||
gcUsage(e)
|
||||
else:
|
||||
constructLoc(p, tmp)
|
||||
else:
|
||||
constructLoc(p, tmp)
|
||||
resetLoc(p, d)
|
||||
r = rdLoc(d)
|
||||
discard getTypeDesc(p.module, t)
|
||||
let ty = getUniqueType(t)
|
||||
for i in 1 ..< e.len:
|
||||
@@ -1227,15 +1239,19 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||
genFieldCheck(p, it.sons[2], r, field)
|
||||
add(tmp2.r, ".")
|
||||
add(tmp2.r, field.loc.r)
|
||||
tmp2.k = locTemp
|
||||
if useTemp:
|
||||
tmp2.k = locTemp
|
||||
tmp2.storage = if isRef: OnHeap else: OnStack
|
||||
else:
|
||||
tmp2.k = d.k
|
||||
tmp2.storage = if isRef: OnHeap else: d.storage
|
||||
tmp2.lode = it.sons[1]
|
||||
tmp2.storage = if isRef: OnHeap else: OnStack
|
||||
expr(p, it.sons[1], tmp2)
|
||||
|
||||
if d.k == locNone:
|
||||
d = tmp
|
||||
else:
|
||||
genAssignment(p, d, tmp, {})
|
||||
if useTemp:
|
||||
if d.k == locNone:
|
||||
d = tmp
|
||||
else:
|
||||
genAssignment(p, d, tmp, {})
|
||||
|
||||
proc lhsDoesAlias(a, b: PNode): bool =
|
||||
for y in b:
|
||||
|
||||
@@ -70,7 +70,7 @@ __clang__
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable: 4005 4100 4101 4189 4191 4200 4244 4293 4296 4309)
|
||||
# pragma warning(disable: 4310 4365 4456 4477 4514 4574 4611 4668 4702 4706)
|
||||
# pragma warning(disable: 4710 4711 4774 4800 4820 4996 4090 4297)
|
||||
# pragma warning(disable: 4710 4711 4774 4800 4809 4820 4996 4090 4297)
|
||||
#endif
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
@@ -324,12 +324,12 @@ proc mget*[T](future: FutureVar[T]): var T =
|
||||
## Future has not been finished.
|
||||
result = Future[T](future).value
|
||||
|
||||
proc finished*[T](future: Future[T] | FutureVar[T]): bool =
|
||||
proc finished*(future: FutureBase | FutureVar): bool =
|
||||
## Determines whether ``future`` has completed.
|
||||
##
|
||||
## ``True`` may indicate an error or a value. Use ``failed`` to distinguish.
|
||||
when future is FutureVar[T]:
|
||||
result = (Future[T](future)).finished
|
||||
when future is FutureVar:
|
||||
result = (FutureBase(future)).finished
|
||||
else:
|
||||
result = future.finished
|
||||
|
||||
|
||||
@@ -32,6 +32,12 @@ template createCb(retFutureSym, iteratorNameSym,
|
||||
try:
|
||||
if not nameIterVar.finished:
|
||||
var next = nameIterVar()
|
||||
# Continue while the yielded future is already finished.
|
||||
while (not next.isNil) and next.finished:
|
||||
next = nameIterVar()
|
||||
if nameIterVar.finished:
|
||||
break
|
||||
|
||||
if next == nil:
|
||||
if not retFutureSym.finished:
|
||||
let msg = "Async procedure ($1) yielded `nil`, are you await'ing a " &
|
||||
|
||||
@@ -413,7 +413,7 @@ proc isIpAddress*(address_str: string): bool {.tags: [].} =
|
||||
|
||||
when defineSsl:
|
||||
CRYPTO_malloc_init()
|
||||
SslLibraryInit()
|
||||
doAssert SslLibraryInit() == 1
|
||||
SslLoadErrorStrings()
|
||||
ErrLoadBioStrings()
|
||||
OpenSSL_add_all_algorithms()
|
||||
|
||||
@@ -672,7 +672,10 @@ template walkCommon(pattern: string, filter) =
|
||||
if dotPos < 0 or idx >= ff.len or ff[idx] == '.' or
|
||||
pattern[dotPos+1] == '*':
|
||||
yield splitFile(pattern).dir / extractFilename(ff)
|
||||
if findNextFile(res, f) == 0'i32: break
|
||||
if findNextFile(res, f) == 0'i32:
|
||||
let errCode = getLastError()
|
||||
if errCode == ERROR_NO_MORE_FILES: break
|
||||
else: raiseOSError(errCode.OSErrorCode)
|
||||
else: # here we use glob
|
||||
var
|
||||
f: Glob
|
||||
@@ -782,7 +785,10 @@ iterator walkDir*(dir: string; relative=false): tuple[kind: PathComponent, path:
|
||||
let xx = if relative: extractFilename(getFilename(f))
|
||||
else: dir / extractFilename(getFilename(f))
|
||||
yield (k, xx)
|
||||
if findNextFile(h, f) == 0'i32: break
|
||||
if findNextFile(h, f) == 0'i32:
|
||||
let errCode = getLastError()
|
||||
if errCode == ERROR_NO_MORE_FILES: break
|
||||
else: raiseOSError(errCode.OSErrorCode)
|
||||
else:
|
||||
var d = opendir(dir)
|
||||
if d != nil:
|
||||
|
||||
@@ -129,8 +129,8 @@ type
|
||||
## The ``times`` module only supplies implementations for the systems local time and UTC.
|
||||
## The members ``zoneInfoFromUtc`` and ``zoneInfoFromTz`` should not be accessed directly
|
||||
## and are only exported so that ``Timezone`` can be implemented by other modules.
|
||||
zoneInfoFromUtc*: proc (time: Time): ZonedTime {.nimcall, tags: [], raises: [], benign .}
|
||||
zoneInfoFromTz*: proc (adjTime: Time): ZonedTime {.nimcall, tags: [], raises: [], benign .}
|
||||
zoneInfoFromUtc*: proc (time: Time): ZonedTime {.tags: [], raises: [], benign.}
|
||||
zoneInfoFromTz*: proc (adjTime: Time): ZonedTime {.tags: [], raises: [], benign.}
|
||||
name*: string ## The name of the timezone, f.ex 'Europe/Stockholm' or 'Etc/UTC'. Used for checking equality.
|
||||
## Se also: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||
ZonedTime* = object ## Represents a zooned instant in time that is not associated with any calendar.
|
||||
|
||||
@@ -406,7 +406,8 @@ proc setStdIoUnbuffered() =
|
||||
|
||||
when declared(stdout):
|
||||
proc echoBinSafe(args: openArray[string]) {.compilerProc.} =
|
||||
when not defined(windows):
|
||||
# flockfile deadlocks some versions of Android 5.x.x
|
||||
when not defined(windows) and not defined(android):
|
||||
proc flockfile(f: File) {.importc, noDecl.}
|
||||
proc funlockfile(f: File) {.importc, noDecl.}
|
||||
flockfile(stdout)
|
||||
@@ -415,7 +416,7 @@ when declared(stdout):
|
||||
const linefeed = "\n" # can be 1 or more chars
|
||||
discard c_fwrite(linefeed.cstring, linefeed.len, 1, stdout)
|
||||
discard c_fflush(stdout)
|
||||
when not defined(windows):
|
||||
when not defined(windows) and not defined(android):
|
||||
funlockfile(stdout)
|
||||
|
||||
{.pop.}
|
||||
|
||||
@@ -386,8 +386,7 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
|
||||
kdigits, fdigits = 0
|
||||
exponent: int
|
||||
integer: uint64
|
||||
fraction: uint64
|
||||
frac_exponent= 0
|
||||
frac_exponent = 0
|
||||
exp_sign = 1
|
||||
first_digit = -1
|
||||
has_sign = false
|
||||
@@ -480,7 +479,8 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
|
||||
|
||||
# if integer is representable in 53 bits: fast path
|
||||
# max fast path integer is 1<<53 - 1 or 8999999999999999 (16 digits)
|
||||
if kdigits + fdigits <= 16 and first_digit <= 8:
|
||||
let digits = kdigits + fdigits
|
||||
if digits <= 15 or (digits <= 16 and first_digit <= 8):
|
||||
# max float power of ten with set bits above the 53th bit is 10^22
|
||||
if abs_exponent <= 22:
|
||||
if exp_negative:
|
||||
@@ -504,6 +504,7 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
|
||||
result = i - start
|
||||
i = start
|
||||
# re-parse without error checking, any error should be handled by the code above.
|
||||
if s[i] == '.': i.inc
|
||||
while s[i] in {'0'..'9','+','-'}:
|
||||
if ti < maxlen:
|
||||
t[ti] = s[i]; inc(ti)
|
||||
|
||||
@@ -686,6 +686,7 @@ const
|
||||
ERROR_FILE_NOT_FOUND* = 2
|
||||
ERROR_PATH_NOT_FOUND* = 3
|
||||
ERROR_ACCESS_DENIED* = 5
|
||||
ERROR_NO_MORE_FILES* = 18
|
||||
ERROR_HANDLE_EOF* = 38
|
||||
ERROR_BAD_ARGUMENTS* = 165
|
||||
|
||||
|
||||
@@ -8,6 +8,17 @@
|
||||
#
|
||||
|
||||
## OpenSSL support
|
||||
##
|
||||
## When OpenSSL is dynamically linked, the wrapper provides partial forward and backward
|
||||
## compatibility for OpenSSL versions above and below 1.1.0
|
||||
##
|
||||
## OpenSSL can be also statically linked using dynlibOverride:ssl for OpenSSL >= 1.1.0
|
||||
##
|
||||
## Build and test examples:
|
||||
##
|
||||
## .. code-block::
|
||||
## ./bin/nim c -d:ssl -p:. -r tests/untestable/tssl.nim
|
||||
## ./bin/nim c -d:ssl -p:. --dynlibOverride:ssl --passL:-lcrypto --passL:-lssl -r tests/untestable/tssl.nim
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
|
||||
@@ -25,8 +36,8 @@ when useWinVersion:
|
||||
|
||||
from winlean import SocketHandle
|
||||
else:
|
||||
const
|
||||
versions = "(|.38|.39|.41|.43|.10|.1.0.2|.1.0.1|.1.0.0|.0.9.9|.0.9.8)"
|
||||
const versions = "(.1.1|.38|.39|.41|.43|.10|.1.0.2|.1.0.1|.1.0.0|.0.9.9|.0.9.8|)"
|
||||
|
||||
when defined(macosx):
|
||||
const
|
||||
DLLSSLName = "libssl" & versions & ".dylib"
|
||||
@@ -140,6 +151,7 @@ const
|
||||
SSL_OP_NO_SSLv2* = 0x01000000
|
||||
SSL_OP_NO_SSLv3* = 0x02000000
|
||||
SSL_OP_NO_TLSv1* = 0x04000000
|
||||
SSL_OP_NO_TLSv1_1* = 0x08000000
|
||||
SSL_OP_ALL* = 0x000FFFFF
|
||||
SSL_VERIFY_NONE* = 0x00000000
|
||||
SSL_VERIFY_PEER* = 0x00000001
|
||||
@@ -191,16 +203,39 @@ const
|
||||
|
||||
proc TLSv1_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.}
|
||||
|
||||
when compileOption("dynlibOverride", "ssl"):
|
||||
proc SSL_library_init*(): cint {.cdecl, dynlib: DLLSSLName, importc, discardable.}
|
||||
proc SSL_load_error_strings*() {.cdecl, dynlib: DLLSSLName, importc.}
|
||||
proc SSLv23_client_method*(): PSSL_METHOD {.cdecl, dynlib: DLLSSLName, importc.}
|
||||
# TLS_method(), TLS_server_method(), TLS_client_method() are introduced in 1.1.0
|
||||
# and support SSLv3, TLSv1, TLSv1.1 and TLSv1.2
|
||||
# SSLv23_method(), SSLv23_server_method(), SSLv23_client_method() are removed in 1.1.0
|
||||
|
||||
proc SSLv23_method*(): PSSL_METHOD {.cdecl, dynlib: DLLSSLName, importc.}
|
||||
when compileOption("dynlibOverride", "ssl"):
|
||||
# Static linking
|
||||
proc OPENSSL_init_ssl*(opts: uint64, settings: uint8): cint {.cdecl, dynlib: DLLSSLName, importc, discardable.}
|
||||
proc SSL_library_init*(): cint {.discardable.} =
|
||||
## Initialize SSL using OPENSSL_init_ssl for OpenSSL >= 1.1.0
|
||||
return OPENSSL_init_ssl(0.uint64, 0.uint8)
|
||||
|
||||
proc TLS_method*(): PSSL_METHOD {.cdecl, dynlib: DLLSSLName, importc.}
|
||||
proc SSLv23_method*(): PSSL_METHOD =
|
||||
TLS_method()
|
||||
|
||||
proc SSLv23_client_method*(): PSSL_METHOD {.cdecl, dynlib: DLLSSLName, importc.}
|
||||
proc SSLv2_method*(): PSSL_METHOD {.cdecl, dynlib: DLLSSLName, importc.}
|
||||
proc SSLv3_method*(): PSSL_METHOD {.cdecl, dynlib: DLLSSLName, importc.}
|
||||
|
||||
template OpenSSL_add_all_algorithms*() = discard
|
||||
|
||||
proc OpenSSL_version_num(): culong {.cdecl, dynlib: DLLSSLName, importc.}
|
||||
|
||||
proc getOpenSSLVersion*(): culong =
|
||||
## Return OpenSSL version as unsigned long
|
||||
OpenSSL_version_num()
|
||||
|
||||
proc SSL_load_error_strings*() =
|
||||
## Removed from OpenSSL 1.1.0
|
||||
# This proc prevents breaking existing code calling SslLoadErrorStrings
|
||||
# Static linking against OpenSSL < 1.1.0 is not supported
|
||||
discard
|
||||
|
||||
else:
|
||||
# Here we're trying to stay compatible with openssl 1.0.* and 1.1.*. Some
|
||||
# symbols are loaded dynamically and we don't use them if not found.
|
||||
@@ -223,38 +258,58 @@ else:
|
||||
if not dl.isNil:
|
||||
result = symAddr(dl, name)
|
||||
|
||||
proc loadPSSLMethod(method1, method2: string): PSSL_METHOD =
|
||||
## Load <method1> from OpenSSL if available, otherwise <method2>
|
||||
let m1 = cast[proc(): PSSL_METHOD {.cdecl, gcsafe.}](sslSym(method1))
|
||||
if not m1.isNil:
|
||||
return m1()
|
||||
cast[proc(): PSSL_METHOD {.cdecl, gcsafe.}](sslSym(method2))()
|
||||
|
||||
proc SSL_library_init*(): cint {.discardable.} =
|
||||
let theProc = cast[proc(): cint {.cdecl.}](sslSym("SSL_library_init"))
|
||||
if not theProc.isNil: result = theProc()
|
||||
## Initialize SSL using OPENSSL_init_ssl for OpenSSL >= 1.1.0 otherwise
|
||||
## SSL_library_init
|
||||
let theProc = cast[proc(opts: uint64, settings: uint8): cint {.cdecl.}](sslSym("OPENSSL_init_ssl"))
|
||||
if not theProc.isNil:
|
||||
return theProc(0, 0)
|
||||
let olderProc = cast[proc(): cint {.cdecl.}](sslSym("SSL_library_init"))
|
||||
if not olderProc.isNil: result = olderProc()
|
||||
|
||||
proc SSL_load_error_strings*() =
|
||||
let theProc = cast[proc() {.cdecl.}](sslSym("SSL_load_error_strings"))
|
||||
if not theProc.isNil: theProc()
|
||||
|
||||
proc SSLv23_client_method*(): PSSL_METHOD =
|
||||
let theProc = cast[proc(): PSSL_METHOD {.cdecl, gcsafe.}](sslSym("SSLv23_client_method"))
|
||||
if not theProc.isNil: result = theProc()
|
||||
else: result = TLSv1_method()
|
||||
loadPSSLMethod("SSLv23_client_method", "TLS_client_method")
|
||||
|
||||
proc SSLv23_method*(): PSSL_METHOD =
|
||||
let theProc = cast[proc(): PSSL_METHOD {.cdecl, gcsafe.}](sslSym("SSLv23_method"))
|
||||
if not theProc.isNil: result = theProc()
|
||||
else: result = TLSv1_method()
|
||||
loadPSSLMethod("SSLv23_method", "TLS_method")
|
||||
|
||||
proc SSLv2_method*(): PSSL_METHOD =
|
||||
let theProc = cast[proc(): PSSL_METHOD {.cdecl, gcsafe.}](sslSym("SSLv2_method"))
|
||||
if not theProc.isNil: result = theProc()
|
||||
else: result = TLSv1_method()
|
||||
loadPSSLMethod("SSLv2_method", "TLS_method")
|
||||
|
||||
proc SSLv3_method*(): PSSL_METHOD =
|
||||
let theProc = cast[proc(): PSSL_METHOD {.cdecl, gcsafe.}](sslSym("SSLv3_method"))
|
||||
if not theProc.isNil: result = theProc()
|
||||
else: result = TLSv1_method()
|
||||
loadPSSLMethod("SSLv3_method", "TLS_method")
|
||||
|
||||
proc TLS_method*(): PSSL_METHOD =
|
||||
loadPSSLMethod("TLS_method", "SSLv23_method")
|
||||
|
||||
proc TLS_client_method*(): PSSL_METHOD =
|
||||
loadPSSLMethod("TLS_client_method", "SSLv23_client_method")
|
||||
|
||||
proc TLS_server_method*(): PSSL_METHOD =
|
||||
loadPSSLMethod("TLS_server_method", "SSLv23_server_method")
|
||||
|
||||
proc OpenSSL_add_all_algorithms*() =
|
||||
let theProc = cast[proc() {.cdecl.}](sslSym("OPENSSL_add_all_algorithms_conf"))
|
||||
if not theProc.isNil: theProc()
|
||||
|
||||
proc getOpenSSLVersion*(): culong =
|
||||
## Return OpenSSL version as unsigned long or 0 if not available
|
||||
let theProc = cast[proc(): culong {.cdecl.}](sslSym("OpenSSL_version_num"))
|
||||
result =
|
||||
if theProc.isNil: 0.culong
|
||||
else: theProc()
|
||||
|
||||
proc ERR_load_BIO_strings*(){.cdecl, dynlib: DLLUtilName, importc.}
|
||||
|
||||
proc SSL_new*(context: SslCtx): SslPtr{.cdecl, dynlib: DLLSSLName, importc.}
|
||||
|
||||
15
tests/async/t6100.nim
Normal file
15
tests/async/t6100.nim
Normal file
@@ -0,0 +1,15 @@
|
||||
discard """
|
||||
file: "t6100.nim"
|
||||
exitcode: 0
|
||||
output: "10000000"
|
||||
"""
|
||||
import asyncdispatch
|
||||
|
||||
let done = newFuture[int]()
|
||||
done.complete(1)
|
||||
|
||||
proc asyncSum: Future[int] {.async.} =
|
||||
for _ in 1..10_000_000:
|
||||
result += await done
|
||||
|
||||
echo waitFor asyncSum()
|
||||
@@ -1,61 +1,7 @@
|
||||
discard """
|
||||
exitcode: 0
|
||||
disabled: "windows"
|
||||
output: '''
|
||||
b failure
|
||||
Async traceback:
|
||||
tasync_traceback.nim(97) tasync_traceback
|
||||
asyncmacro.nim(395) a
|
||||
asyncmacro.nim(34) a_continue
|
||||
## Resumes an async procedure
|
||||
tasync_traceback.nim(95) aIter
|
||||
asyncmacro.nim(395) b
|
||||
asyncmacro.nim(34) b_continue
|
||||
## Resumes an async procedure
|
||||
tasync_traceback.nim(92) bIter
|
||||
#[
|
||||
tasync_traceback.nim(97) tasync_traceback
|
||||
asyncmacro.nim(395) a
|
||||
asyncmacro.nim(43) a_continue
|
||||
## Resumes an async procedure
|
||||
asyncfutures.nim(211) callback=
|
||||
asyncfutures.nim(190) addCallback
|
||||
asyncfutures.nim(53) callSoon
|
||||
asyncmacro.nim(34) a_continue
|
||||
## Resumes an async procedure
|
||||
asyncmacro.nim(0) aIter
|
||||
asyncfutures.nim(304) read
|
||||
]#
|
||||
Exception message: b failure
|
||||
Exception type:
|
||||
|
||||
bar failure
|
||||
Async traceback:
|
||||
tasync_traceback.nim(113) tasync_traceback
|
||||
asyncdispatch.nim(1492) waitFor
|
||||
asyncdispatch.nim(1496) poll
|
||||
## Processes asynchronous completion events
|
||||
asyncdispatch.nim(1262) runOnce
|
||||
asyncdispatch.nim(183) processPendingCallbacks
|
||||
## Executes pending callbacks
|
||||
asyncmacro.nim(34) bar_continue
|
||||
## Resumes an async procedure
|
||||
tasync_traceback.nim(108) barIter
|
||||
#[
|
||||
tasync_traceback.nim(113) tasync_traceback
|
||||
asyncdispatch.nim(1492) waitFor
|
||||
asyncdispatch.nim(1496) poll
|
||||
## Processes asynchronous completion events
|
||||
asyncdispatch.nim(1262) runOnce
|
||||
asyncdispatch.nim(183) processPendingCallbacks
|
||||
## Executes pending callbacks
|
||||
asyncmacro.nim(34) foo_continue
|
||||
## Resumes an async procedure
|
||||
asyncmacro.nim(0) fooIter
|
||||
asyncfutures.nim(304) read
|
||||
]#
|
||||
Exception message: bar failure
|
||||
Exception type:'''
|
||||
output: "Matched"
|
||||
"""
|
||||
import asyncdispatch
|
||||
|
||||
@@ -87,6 +33,8 @@ import asyncdispatch
|
||||
# tasync_traceback.nim(21) a
|
||||
# tasync_traceback.nim(18) b
|
||||
|
||||
var result = ""
|
||||
|
||||
proc b(): Future[int] {.async.} =
|
||||
if true:
|
||||
raise newException(OSError, "b failure")
|
||||
@@ -98,8 +46,8 @@ let aFut = a()
|
||||
try:
|
||||
discard waitFor aFut
|
||||
except Exception as exc:
|
||||
echo exc.msg
|
||||
echo()
|
||||
result.add(exc.msg & "\n")
|
||||
result.add("\n")
|
||||
|
||||
# From #6803
|
||||
proc bar(): Future[string] {.async.} =
|
||||
@@ -110,7 +58,69 @@ proc bar(): Future[string] {.async.} =
|
||||
proc foo(): Future[string] {.async.} = return await bar()
|
||||
|
||||
try:
|
||||
echo waitFor(foo())
|
||||
result.add(waitFor(foo()) & "\n")
|
||||
except Exception as exc:
|
||||
echo exc.msg
|
||||
echo()
|
||||
result.add(exc.msg & "\n")
|
||||
result.add("\n")
|
||||
|
||||
# Use re to parse the result
|
||||
import re
|
||||
const expected = """
|
||||
b failure
|
||||
Async traceback:
|
||||
tasync_traceback\.nim\(\d+?\)\s+?tasync_traceback
|
||||
asyncmacro\.nim\(\d+?\)\s+?a
|
||||
asyncmacro\.nim\(\d+?\)\s+?a_continue
|
||||
## Resumes an async procedure
|
||||
tasync_traceback\.nim\(\d+?\)\s+?aIter
|
||||
asyncmacro\.nim\(\d+?\)\s+?b
|
||||
asyncmacro\.nim\(\d+?\)\s+?b_continue
|
||||
## Resumes an async procedure
|
||||
tasync_traceback\.nim\(\d+?\)\s+?bIter
|
||||
#\[
|
||||
tasync_traceback\.nim\(\d+?\)\s+?tasync_traceback
|
||||
asyncmacro\.nim\(\d+?\)\s+?a
|
||||
asyncmacro\.nim\(\d+?\)\s+?a_continue
|
||||
## Resumes an async procedure
|
||||
asyncmacro\.nim\(\d+?\)\s+?aIter
|
||||
asyncfutures\.nim\(\d+?\)\s+?read
|
||||
\]#
|
||||
Exception message: b failure
|
||||
Exception type:
|
||||
|
||||
bar failure
|
||||
Async traceback:
|
||||
tasync_traceback\.nim\(\d+?\)\s+?tasync_traceback
|
||||
asyncdispatch\.nim\(\d+?\)\s+?waitFor
|
||||
asyncdispatch\.nim\(\d+?\)\s+?poll
|
||||
## Processes asynchronous completion events
|
||||
asyncdispatch\.nim\(\d+?\)\s+?runOnce
|
||||
asyncdispatch\.nim\(\d+?\)\s+?processPendingCallbacks
|
||||
## Executes pending callbacks
|
||||
asyncmacro\.nim\(\d+?\)\s+?bar_continue
|
||||
## Resumes an async procedure
|
||||
tasync_traceback\.nim\(\d+?\)\s+?barIter
|
||||
#\[
|
||||
tasync_traceback\.nim\(\d+?\)\s+?tasync_traceback
|
||||
asyncdispatch\.nim\(\d+?\)\s+?waitFor
|
||||
asyncdispatch\.nim\(\d+?\)\s+?poll
|
||||
## Processes asynchronous completion events
|
||||
asyncdispatch\.nim\(\d+?\)\s+?runOnce
|
||||
asyncdispatch\.nim\(\d+?\)\s+?processPendingCallbacks
|
||||
## Executes pending callbacks
|
||||
asyncmacro\.nim\(\d+?\)\s+?foo_continue
|
||||
## Resumes an async procedure
|
||||
asyncmacro\.nim\(\d+?\)\s+?fooIter
|
||||
asyncfutures\.nim\(\d+?\)\s+?read
|
||||
\]#
|
||||
Exception message: bar failure
|
||||
Exception type:
|
||||
"""
|
||||
|
||||
if result.match(re(expected)):
|
||||
echo("Matched")
|
||||
else:
|
||||
echo("Not matched!")
|
||||
echo()
|
||||
echo(result)
|
||||
quit(QuitFailure)
|
||||
|
||||
@@ -18,8 +18,8 @@ var fs = newFutureStream[int]()
|
||||
|
||||
proc alpha() {.async.} =
|
||||
for i in 0 .. 5:
|
||||
await sleepAsync(1000)
|
||||
await fs.write(i)
|
||||
await sleepAsync(1000)
|
||||
|
||||
echo("Done")
|
||||
fs.complete()
|
||||
|
||||
@@ -48,5 +48,11 @@ doAssert "2.71828182845904523536028747".parseFloat ==
|
||||
2.71828182845904523536028747
|
||||
doAssert 0.00097656250000000021684043449710088680149056017398834228515625 ==
|
||||
"0.00097656250000000021684043449710088680149056017398834228515625".parseFloat
|
||||
doAssert 0.00998333 == ".00998333".parseFloat
|
||||
doAssert 0.00128333 == ".00128333".parseFloat
|
||||
doAssert 999999999999999.0 == "999999999999999.0".parseFloat
|
||||
doAssert 9999999999999999.0 == "9999999999999999.0".parseFloat
|
||||
doAssert 0.999999999999999 == ".999999999999999".parseFloat
|
||||
doAssert 0.9999999999999999 == ".9999999999999999".parseFloat
|
||||
|
||||
echo("passed all tests.")
|
||||
|
||||
@@ -15,7 +15,8 @@ discard """
|
||||
(y: 678, x: 123)
|
||||
(y: 678, x: 123)
|
||||
(y: 0, x: 123)
|
||||
(y: 678, x: 123)'''
|
||||
(y: 678, x: 123)
|
||||
(y: 123, x: 678)'''
|
||||
"""
|
||||
|
||||
type
|
||||
@@ -75,3 +76,7 @@ when true:
|
||||
echo b # (y: 0, x: 123)
|
||||
b=B(y: 678, x: 123)
|
||||
echo b # (y: 678, x: 123)
|
||||
b=B(y: b.x, x: b.y)
|
||||
echo b # (y: 123, x: 678)
|
||||
|
||||
GC_fullCollect()
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
discard """
|
||||
output: '''42
|
||||
Foo'''
|
||||
"""
|
||||
|
||||
type TFoo{.exportc.} = object
|
||||
x:int
|
||||
|
||||
@@ -48,3 +53,5 @@ type NamedGraphic = object of Graphic2
|
||||
|
||||
var ngr = NamedGraphic(kind: Koo, radius: 6.9, name: "Foo")
|
||||
echo ngr.name
|
||||
|
||||
GC_fullCollect()
|
||||
|
||||
@@ -281,6 +281,30 @@ suite "ttimes":
|
||||
test "parseTest":
|
||||
runTimezoneTests()
|
||||
|
||||
test "dynamic timezone":
|
||||
proc staticOffset(offset: int): Timezone =
|
||||
proc zoneInfoFromTz(adjTime: Time): ZonedTime =
|
||||
result.isDst = false
|
||||
result.utcOffset = offset
|
||||
result.adjTime = adjTime
|
||||
|
||||
proc zoneInfoFromUtc(time: Time): ZonedTime =
|
||||
result.isDst = false
|
||||
result.utcOffset = offset
|
||||
result.adjTime = fromUnix(time.toUnix - offset)
|
||||
|
||||
result.name = ""
|
||||
result.zoneInfoFromTz = zoneInfoFromTz
|
||||
result.zoneInfoFromUtc = zoneInfoFromUtc
|
||||
|
||||
let tz = staticOffset(-9000)
|
||||
let dt = initDateTime(1, mJan, 2000, 12, 00, 00, tz)
|
||||
check dt.utcOffset == -9000
|
||||
check dt.isDst == false
|
||||
check $dt == "2000-01-01T12:00:00+02:30"
|
||||
check $dt.utc == "2000-01-01T09:30:00+00:00"
|
||||
check $dt.utc.inZone(tz) == $dt
|
||||
|
||||
test "isLeapYear":
|
||||
check isLeapYear(2016)
|
||||
check (not isLeapYear(2015))
|
||||
|
||||
36
tests/untestable/tssl.nim
Normal file
36
tests/untestable/tssl.nim
Normal file
@@ -0,0 +1,36 @@
|
||||
#
|
||||
# Nim - SSL integration tests
|
||||
# (c) Copyright 2017 Nim contributors
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
## Warning: this test performs external networking.
|
||||
##
|
||||
## Test with:
|
||||
## ./bin/nim c -d:ssl -p:. -r tests/untestable/tssl.nim
|
||||
## ./bin/nim c -d:ssl -p:. --dynlibOverride:ssl --passL:-lcrypto --passL:-lssl -r tests/untestable/tssl.nim
|
||||
## The compilation is expected to succeed with any new/old version of OpenSSL,
|
||||
## both with dynamic and static linking.
|
||||
## The "howsmyssl" test is known to fail with OpenSSL < 1.1 due to insecure
|
||||
## cypher suites being used.
|
||||
|
||||
import httpclient, os
|
||||
from strutils import contains, toHex
|
||||
|
||||
from openssl import getOpenSSLVersion
|
||||
|
||||
when isMainModule:
|
||||
echo "version: 0x" & $getOpenSSLVersion().toHex()
|
||||
|
||||
let client = newHttpClient()
|
||||
# hacky SSL check
|
||||
const url = "https://www.howsmyssl.com"
|
||||
let report = client.getContent(url)
|
||||
if not report.contains(">Probably Okay</span>"):
|
||||
let fn = getTempDir() / "sslreport.html"
|
||||
echo "SSL CHECK ERROR, see " & fn
|
||||
writeFile(fn, report)
|
||||
quit(1)
|
||||
|
||||
echo "done"
|
||||
Reference in New Issue
Block a user