Merge branch 'devel' into araq-overloading-symmetry

This commit is contained in:
Andreas Rumpf
2018-02-03 07:58:31 +01:00
21 changed files with 301 additions and 244 deletions

View File

@@ -10,7 +10,7 @@
# abstract syntax tree + symbol table
import
msgs, hashes, nversion, options, strutils, securehash, ropes, idents,
msgs, hashes, nversion, options, strutils, sha1, ropes, idents,
intsets, idgen
type

View File

@@ -11,7 +11,7 @@
import
ast, astalgo, hashes, trees, platform, magicsys, extccomp, options, intsets,
nversion, nimsets, msgs, securehash, bitsets, idents, types,
nversion, nimsets, msgs, sha1, bitsets, idents, types,
ccgutils, os, ropes, math, passes, rodread, wordrecg, treetab, cgmeth,
condsyms, rodutils, renderer, idgen, cgendata, ccgmerge, semfold, aliases,
lowerings, semparallel, tables, sets, ndi

View File

@@ -14,7 +14,7 @@
import
ropes, os, strutils, osproc, platform, condsyms, options, msgs,
securehash, streams
sha1, streams
#from debuginfo import writeDebugInfo

View File

@@ -9,7 +9,7 @@
## Module that implements ``gorge`` for the compiler.
import msgs, securehash, os, osproc, streams, strutils, options
import msgs, sha1, os, osproc, streams, strutils, options
proc readOutput(p: Process): (string, int) =
result[0] = ""

View File

@@ -11,7 +11,7 @@
import
intsets, strutils, os, ast, astalgo, msgs, options, idents, rodread, lookups,
semdata, passes, renderer, modulepaths
semdata, passes, renderer, modulepaths, sigmatch
proc evalImport*(c: PContext, n: PNode): PNode
proc evalFrom*(c: PContext, n: PNode): PNode
@@ -149,7 +149,7 @@ proc myImportModule(c: PContext, n: PNode): PSym =
localError(n.info, errGenerated, "A module cannot import itself")
if sfDeprecated in result.flags:
message(n.info, warnDeprecated, result.name.s)
#suggestSym(n.info, result, false)
suggestSym(n.info, result, c.graph.usageSym, false)
proc impMod(c: PContext; it: PNode) =
let m = myImportModule(c, it)

View File

@@ -31,7 +31,7 @@ implements the required case distinction.
import
ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp, options,
nversion, nimsets, msgs, securehash, bitsets, idents, types, os,
nversion, nimsets, msgs, sha1, bitsets, idents, types, os,
times, ropes, math, passes, ccgutils, wordrecg, renderer, rodread, rodutils,
intsets, cgmeth, lowerings
@@ -2284,11 +2284,17 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
r.kind = resExpr
of nkFloatLit..nkFloat64Lit:
let f = n.floatVal
if f != f: r.res = rope"NaN"
elif f == 0.0: r.res = rope"0.0"
elif f == 0.5 * f:
if f > 0.0: r.res = rope"Infinity"
else: r.res = rope"-Infinity"
case classify(f)
of fcNaN:
r.res = rope"NaN"
of fcNegZero:
r.res = rope"-0.0"
of fcZero:
r.res = rope"0.0"
of fcInf:
r.res = rope"Infinity"
of fcNegInf:
r.res = rope"-Infinity"
else: r.res = rope(f.toStrMaxPrecision)
r.kind = resExpr
of nkCallKinds:

View File

@@ -10,7 +10,7 @@
## Implements the module handling, including the caching of modules.
import
ast, astalgo, magicsys, securehash, rodread, msgs, cgendata, sigmatch, options,
ast, astalgo, magicsys, sha1, rodread, msgs, cgendata, sigmatch, options,
idents, os, lexer, idgen, passes, syntaxes, llstream, modulegraphs
when false:

View File

@@ -90,7 +90,7 @@
import
os, options, strutils, nversion, ast, astalgo, msgs, platform, condsyms,
ropes, idents, securehash, idgen, types, rodutils, memfiles, tables
ropes, idents, sha1, idgen, types, rodutils, memfiles, tables
type
TReasonForRecompile* = enum ## all the reasons that can trigger recompilation

View File

@@ -8,18 +8,22 @@
#
## Serialization utilities for the compiler.
import strutils
import strutils, math
proc c_snprintf(s: cstring; n:uint; frmt: cstring): cint {.importc: "snprintf", header: "<stdio.h>", nodecl, varargs.}
proc toStrMaxPrecision*(f: BiggestFloat, literalPostfix = ""): string =
if f != f:
case classify(f)
of fcNaN:
result = "NAN"
elif f == 0.0:
of fcNegZero:
result = "-0.0" & literalPostfix
of fcZero:
result = "0.0" & literalPostfix
elif f == 0.5 * f:
if f > 0.0: result = "INF"
else: result = "-INF"
of fcInf:
result = "INF"
of fcNegInf:
result = "-INF"
else:
when defined(nimNoArrayToCstringConversion):
result = newString(81)

View File

@@ -13,7 +13,7 @@
import
intsets, os, options, strutils, nversion, ast, astalgo, msgs, platform,
condsyms, ropes, idents, securehash, rodread, passes, idgen,
condsyms, ropes, idents, sha1, rodread, passes, idgen,
rodutils, modulepaths
from modulegraphs import ModuleGraph

View File

@@ -225,6 +225,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
of mDivF64:
if getFloat(b) == 0.0:
if getFloat(a) == 0.0: result = newFloatNodeT(NaN, n)
elif getFloat(b).classify == fcNegZero: result = newFloatNodeT(-Inf, n)
else: result = newFloatNodeT(Inf, n)
else:
result = newFloatNodeT(getFloat(a) / getFloat(b), n)

View File

@@ -593,17 +593,14 @@ proc trackOperand(tracked: PEffects, n: PNode, paramType: PType) =
notNilCheck(tracked, n, paramType)
proc breaksBlock(n: PNode): bool =
case n.kind
of nkStmtList, nkStmtListExpr:
for c in n:
if breaksBlock(c): return true
of nkBreakStmt, nkReturnStmt, nkRaiseStmt:
return true
of nkCallKinds:
if n.sons[0].kind == nkSym and sfNoReturn in n.sons[0].sym.flags:
return true
else:
discard
# sematic check doesn't allow statements after raise, break, return or
# call to noreturn proc, so it is safe to check just the last statements
var it = n
while it.kind in {nkStmtList, nkStmtListExpr} and it.len > 0:
it = it.lastSon
result = it.kind in {nkBreakStmt, nkReturnStmt, nkRaiseStmt} or
it.kind in nkCallKinds and it[0].kind == nkSym and sfNoReturn in it[0].sym.flags
proc trackCase(tracked: PEffects, n: PNode) =
track(tracked, n.sons[0])

View File

@@ -181,11 +181,11 @@ Nim exceptions: `FloatInvalidOpError`:idx:, `FloatDivByZeroError`:idx:,
and `FloatInexactError`:idx:.
These exceptions inherit from the `FloatingPointError`:idx: base class.
Nim provides the pragmas `NaNChecks`:idx: and `InfChecks`:idx: to control
Nim provides the pragmas `nanChecks`:idx: and `infChecks`:idx: to control
whether the IEEE exceptions are ignored or trap a Nim exception:
.. code-block:: nim
{.NanChecks: on, InfChecks: on.}
{.nanChecks: on, infChecks: on.}
var a = 1.0
var b = 0.0
echo b / b # raises FloatInvalidOpError
@@ -195,7 +195,7 @@ In the current implementation ``FloatDivByZeroError`` and ``FloatInexactError``
are never raised. ``FloatOverflowError`` is raised instead of
``FloatDivByZeroError``.
There is also a `floatChecks`:idx: pragma that is a short-cut for the
combination of ``NaNChecks`` and ``InfChecks`` pragmas. ``floatChecks`` are
combination of ``nanChecks`` and ``infChecks`` pragmas. ``floatChecks`` are
turned off as default.
The only operations that are affected by the ``floatChecks`` pragma are

View File

@@ -139,10 +139,15 @@ proc findExe*(exe: string, followSymlinks: bool = true;
## is added the `ExeExts <#ExeExts>`_ file extensions if it has none.
## If the system supports symlinks it also resolves them until it
## meets the actual file. This behavior can be disabled if desired.
for ext in extensions:
result = addFileExt(exe, ext)
if existsFile(result): return
var path = string(getEnv("PATH"))
template checkCurrentDir() =
for ext in extensions:
result = addFileExt(exe, ext)
if existsFile(result): return
when defined(posix):
if '/' in exe: checkCurrentDir()
else:
checkCurrentDir()
let path = string(getEnv("PATH"))
for candidate in split(path, PathSep):
when defined(windows):
var x = (if candidate[0] == '"' and candidate[^1] == '"':
@@ -824,7 +829,7 @@ iterator walkDir*(dir: string; relative=false): tuple[kind: PathComponent, path:
iterator walkDirRec*(dir: string, yieldFilter = {pcFile},
followFilter = {pcDir}): string {.tags: [ReadDirEffect].} =
## Recursively walks over the directory `dir` and yields for each file
## Recursively walks over the directory `dir` and yields for each file
## or directory in `dir`.
## The full path for each file or directory is returned.
## **Warning**:

View File

@@ -1,195 +1,6 @@
#
#
# The Nim Compiler
# (c) Copyright 2015 Nim Contributors
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
import strutils
const Sha1DigestSize = 20
type
Sha1Digest = array[0 .. Sha1DigestSize-1, uint8]
SecureHash* = distinct Sha1Digest
# Copyright (c) 2011, Micael Hildenborg
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Micael Hildenborg nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Ported to Nim by Erik O'Leary
type
Sha1State* = array[0 .. 5-1, uint32]
Sha1Buffer = array[0 .. 80-1, uint32]
template clearBuffer(w: Sha1Buffer, len = 16) =
zeroMem(addr(w), len * sizeof(uint32))
proc init*(result: var Sha1State) =
result[0] = 0x67452301'u32
result[1] = 0xefcdab89'u32
result[2] = 0x98badcfe'u32
result[3] = 0x10325476'u32
result[4] = 0xc3d2e1f0'u32
proc innerHash(state: var Sha1State, w: var Sha1Buffer) =
var
a = state[0]
b = state[1]
c = state[2]
d = state[3]
e = state[4]
var round = 0
template rot(value, bits: uint32): uint32 =
(value shl bits) or (value shr (32u32 - bits))
template sha1(fun, val: uint32) =
let t = rot(a, 5) + fun + e + val + w[round]
e = d
d = c
c = rot(b, 30)
b = a
a = t
template process(body: untyped) =
w[round] = rot(w[round - 3] xor w[round - 8] xor w[round - 14] xor w[round - 16], 1)
body
inc(round)
template wrap(dest, value: untyped) =
let v = dest + value
dest = v
while round < 16:
sha1((b and c) or (not b and d), 0x5a827999'u32)
inc(round)
while round < 20:
process:
sha1((b and c) or (not b and d), 0x5a827999'u32)
while round < 40:
process:
sha1(b xor c xor d, 0x6ed9eba1'u32)
while round < 60:
process:
sha1((b and c) or (b and d) or (c and d), 0x8f1bbcdc'u32)
while round < 80:
process:
sha1(b xor c xor d, 0xca62c1d6'u32)
wrap state[0], a
wrap state[1], b
wrap state[2], c
wrap state[3], d
wrap state[4], e
proc sha1(src: cstring; len: int): Sha1Digest =
#Initialize state
var state: Sha1State
init(state)
#Create w buffer
var w: Sha1Buffer
#Loop through all complete 64byte blocks.
let byteLen = len
let endOfFullBlocks = byteLen - 64
var endCurrentBlock = 0
var currentBlock = 0
while currentBlock <= endOfFullBlocks:
endCurrentBlock = currentBlock + 64
var i = 0
while currentBlock < endCurrentBlock:
w[i] = uint32(src[currentBlock+3]) or
uint32(src[currentBlock+2]) shl 8'u32 or
uint32(src[currentBlock+1]) shl 16'u32 or
uint32(src[currentBlock]) shl 24'u32
currentBlock += 4
inc(i)
innerHash(state, w)
#Handle last and not full 64 byte block if existing
endCurrentBlock = byteLen - currentBlock
clearBuffer(w)
var lastBlockBytes = 0
while lastBlockBytes < endCurrentBlock:
var value = uint32(src[lastBlockBytes + currentBlock]) shl
((3'u32 - uint32(lastBlockBytes and 3)) shl 3)
w[lastBlockBytes shr 2] = w[lastBlockBytes shr 2] or value
inc(lastBlockBytes)
w[lastBlockBytes shr 2] = w[lastBlockBytes shr 2] or (
0x80'u32 shl ((3'u32 - uint32(lastBlockBytes and 3)) shl 3)
)
if endCurrentBlock >= 56:
innerHash(state, w)
clearBuffer(w)
w[15] = uint32(byteLen) shl 3
innerHash(state, w)
# Store hash in result pointer, and make sure we get in in the correct order
# on both endian models.
for i in 0 .. Sha1DigestSize-1:
result[i] = uint8((int(state[i shr 2]) shr ((3-(i and 3)) * 8)) and 255)
proc sha1(src: string): Sha1Digest =
## Calculate SHA1 from input string
sha1(src, src.len)
proc secureHash*(str: string): SecureHash = SecureHash(sha1(str))
proc secureHashFile*(filename: string): SecureHash = secureHash(readFile(filename))
proc `$`*(self: SecureHash): string =
result = ""
for v in Sha1Digest(self):
result.add(toHex(int(v), 2))
proc parseSecureHash*(hash: string): SecureHash =
for i in 0 ..< Sha1DigestSize:
Sha1Digest(result)[i] = uint8(parseHexInt(hash[i*2] & hash[i*2 + 1]))
proc `==`*(a, b: SecureHash): bool =
# Not a constant-time comparison, but that's acceptable in this context
Sha1Digest(a) == Sha1Digest(b)
when isMainModule:
let hash1 = secureHash("a93tgj0p34jagp9[agjp98ajrhp9aej]")
doAssert hash1 == hash1
doAssert parseSecureHash($hash1) == hash1
## This module is a deprecated alias for the ``sha1`` module.
{.deprecated.}
include sha1

195
lib/pure/sha1.nim Normal file
View File

@@ -0,0 +1,195 @@
#
#
# The Nim Compiler
# (c) Copyright 2015 Nim Contributors
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
import strutils
const Sha1DigestSize = 20
type
Sha1Digest = array[0 .. Sha1DigestSize-1, uint8]
SecureHash* = distinct Sha1Digest
# Copyright (c) 2011, Micael Hildenborg
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Micael Hildenborg nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Ported to Nim by Erik O'Leary
type
Sha1State* = array[0 .. 5-1, uint32]
Sha1Buffer = array[0 .. 80-1, uint32]
template clearBuffer(w: Sha1Buffer, len = 16) =
zeroMem(addr(w), len * sizeof(uint32))
proc init*(result: var Sha1State) =
result[0] = 0x67452301'u32
result[1] = 0xefcdab89'u32
result[2] = 0x98badcfe'u32
result[3] = 0x10325476'u32
result[4] = 0xc3d2e1f0'u32
proc innerHash(state: var Sha1State, w: var Sha1Buffer) =
var
a = state[0]
b = state[1]
c = state[2]
d = state[3]
e = state[4]
var round = 0
template rot(value, bits: uint32): uint32 =
(value shl bits) or (value shr (32u32 - bits))
template sha1(fun, val: uint32) =
let t = rot(a, 5) + fun + e + val + w[round]
e = d
d = c
c = rot(b, 30)
b = a
a = t
template process(body: untyped) =
w[round] = rot(w[round - 3] xor w[round - 8] xor w[round - 14] xor w[round - 16], 1)
body
inc(round)
template wrap(dest, value: untyped) =
let v = dest + value
dest = v
while round < 16:
sha1((b and c) or (not b and d), 0x5a827999'u32)
inc(round)
while round < 20:
process:
sha1((b and c) or (not b and d), 0x5a827999'u32)
while round < 40:
process:
sha1(b xor c xor d, 0x6ed9eba1'u32)
while round < 60:
process:
sha1((b and c) or (b and d) or (c and d), 0x8f1bbcdc'u32)
while round < 80:
process:
sha1(b xor c xor d, 0xca62c1d6'u32)
wrap state[0], a
wrap state[1], b
wrap state[2], c
wrap state[3], d
wrap state[4], e
proc sha1(src: cstring; len: int): Sha1Digest =
#Initialize state
var state: Sha1State
init(state)
#Create w buffer
var w: Sha1Buffer
#Loop through all complete 64byte blocks.
let byteLen = len
let endOfFullBlocks = byteLen - 64
var endCurrentBlock = 0
var currentBlock = 0
while currentBlock <= endOfFullBlocks:
endCurrentBlock = currentBlock + 64
var i = 0
while currentBlock < endCurrentBlock:
w[i] = uint32(src[currentBlock+3]) or
uint32(src[currentBlock+2]) shl 8'u32 or
uint32(src[currentBlock+1]) shl 16'u32 or
uint32(src[currentBlock]) shl 24'u32
currentBlock += 4
inc(i)
innerHash(state, w)
#Handle last and not full 64 byte block if existing
endCurrentBlock = byteLen - currentBlock
clearBuffer(w)
var lastBlockBytes = 0
while lastBlockBytes < endCurrentBlock:
var value = uint32(src[lastBlockBytes + currentBlock]) shl
((3'u32 - uint32(lastBlockBytes and 3)) shl 3)
w[lastBlockBytes shr 2] = w[lastBlockBytes shr 2] or value
inc(lastBlockBytes)
w[lastBlockBytes shr 2] = w[lastBlockBytes shr 2] or (
0x80'u32 shl ((3'u32 - uint32(lastBlockBytes and 3)) shl 3)
)
if endCurrentBlock >= 56:
innerHash(state, w)
clearBuffer(w)
w[15] = uint32(byteLen) shl 3
innerHash(state, w)
# Store hash in result pointer, and make sure we get in in the correct order
# on both endian models.
for i in 0 .. Sha1DigestSize-1:
result[i] = uint8((int(state[i shr 2]) shr ((3-(i and 3)) * 8)) and 255)
proc sha1(src: string): Sha1Digest =
## Calculate SHA1 from input string
sha1(src, src.len)
proc secureHash*(str: string): SecureHash = SecureHash(sha1(str))
proc secureHashFile*(filename: string): SecureHash = secureHash(readFile(filename))
proc `$`*(self: SecureHash): string =
result = ""
for v in Sha1Digest(self):
result.add(toHex(int(v), 2))
proc parseSecureHash*(hash: string): SecureHash =
for i in 0 ..< Sha1DigestSize:
Sha1Digest(result)[i] = uint8(parseHexInt(hash[i*2] & hash[i*2 + 1]))
proc `==`*(a, b: SecureHash): bool =
# Not a constant-time comparison, but that's acceptable in this context
Sha1Digest(a) == Sha1Digest(b)
when isMainModule:
let hash1 = secureHash("a93tgj0p34jagp9[agjp98ajrhp9aej]")
doAssert hash1 == hash1
doAssert parseSecureHash($hash1) == hash1

View File

@@ -47,10 +47,16 @@ when not declared(c_fwrite):
# C routine that is used here:
proc c_fread(buf: pointer, size, n: csize, f: File): csize {.
importc: "fread", header: "<stdio.h>", tags: [ReadIOEffect].}
proc c_fseek(f: File, offset: clong, whence: cint): cint {.
importc: "fseek", header: "<stdio.h>", tags: [].}
proc c_ftell(f: File): clong {.
importc: "ftell", header: "<stdio.h>", tags: [].}
when defined(windows):
proc c_fseek(f: File, offset: int64, whence: cint): cint {.
importc: "_fseeki64", header: "<stdio.h>", tags: [].}
proc c_ftell(f: File): int64 {.
importc: "_ftelli64", header: "<stdio.h>", tags: [].}
else:
proc c_fseek(f: File, offset: int64, whence: cint): cint {.
importc: "fseeko", header: "<stdio.h>", tags: [].}
proc c_ftell(f: File): int64 {.
importc: "ftello", header: "<stdio.h>", tags: [].}
proc c_ferror(f: File): cint {.
importc: "ferror", header: "<stdio.h>", tags: [].}
proc c_setvbuf(f: File, buf: pointer, mode: cint, size: csize): cint {.
@@ -210,12 +216,12 @@ proc readAllBuffer(file: File): string =
result.add(buffer)
break
proc rawFileSize(file: File): int =
proc rawFileSize(file: File): int64 =
# this does not raise an error opposed to `getFileSize`
var oldPos = c_ftell(file)
discard c_fseek(file, 0, 2) # seek the end of the file
result = c_ftell(file)
discard c_fseek(file, clong(oldPos), 0)
discard c_fseek(file, oldPos, 0)
proc endOfFile(f: File): bool =
var c = c_fgetc(f)
@@ -223,7 +229,7 @@ proc endOfFile(f: File): bool =
return c < 0'i32
#result = c_feof(f) != 0
proc readAllFile(file: File, len: int): string =
proc readAllFile(file: File, len: int64): string =
# We acquire the filesize beforehand and hope it doesn't change.
# Speeds things up.
result = newString(len)
@@ -363,7 +369,7 @@ proc open(f: var File, filehandle: FileHandle, mode: FileMode): bool =
result = f != nil
proc setFilePos(f: File, pos: int64, relativeTo: FileSeekPos = fspSet) =
if c_fseek(f, clong(pos), cint(relativeTo)) != 0:
if c_fseek(f, pos, cint(relativeTo)) != 0:
raiseEIO("cannot set file position")
proc getFilePos(f: File): int64 =

9
tests/ccgbugs/t7079.nim Normal file
View File

@@ -0,0 +1,9 @@
discard """
action: run
targets: '''c js'''
"""
import math
let x = -0.0
doAssert classify(x) == fcNegZero
doAssert classify(1 / -0.0) == fcNegInf

View File

@@ -1,5 +1,5 @@
import
unittest, osproc, streams, os
unittest, osproc, streams, os, strformat
const STRING_DATA = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
const TEST_FILE = "tests/testdata/string.txt"
@@ -23,3 +23,26 @@ suite "io":
test "file":
check:
readFile(TEST_FILE) == STRING_DATA
proc verifyFileSize(sz: int64) =
# issue 7121, large file size (2-4GB and >4Gb)
const fn = "tmpfile112358"
let size_in_mb = sz div 1_000_000
when defined(windows):
discard execProcess(&"fsutil file createnew {fn} {sz}" )
else:
discard execProcess(&"dd if=/dev/zero of={fn} bs=1000000 count={size_in_mb}")
doAssert os.getFileSize(fn) == sz # Verify OS filesize by string
var f = open(fn)
doAssert f.getFileSize() == sz # Verify file handle filesize
f.close()
os.removeFile(fn)
#disable tests for automatic testers
#for s in [50_000_000'i64, 3_000_000_000, 5_000_000_000]:
# verifyFileSize(s)

View File

@@ -15,7 +15,7 @@ when haveZipLib:
import
os, osproc, strutils, parseopt, parsecfg, strtabs, streams, debcreation,
securehash
sha1
const
maxOS = 20 # max number of OSes

View File

@@ -65,7 +65,7 @@ srcdoc2: "pure/asyncfile;pure/asyncftpclient;pure/lenientops"
srcdoc2: "pure/md5;pure/rationals"
srcdoc2: "posix/posix;pure/distros;pure/oswalkdir"
srcdoc2: "pure/collections/heapqueue"
srcdoc2: "pure/fenv;pure/securehash;impure/rdstdin;pure/strformat"
srcdoc2: "pure/fenv;pure/sha1;impure/rdstdin;pure/strformat"
srcdoc2: "pure/segfaults"
srcdoc2: "pure/basic2d;pure/basic3d;pure/mersenne;pure/coro;pure/httpcore"
srcdoc2: "pure/bitops;pure/nimtracker;pure/punycode;pure/volatile;js/asyncjs"