init checks and 'out' parameters (#14521)
* I don't care about observable stores * enforce explicit initializations * cleaner code for the stdlib * stdlib: use explicit initializations * make tests green * algorithm.nim: set result explicitly * remove out parameters and bring the PR into a mergable state * updated the changelog
This commit is contained in:
parent
a9eee6db65
commit
da29222f86
53 changed files with 355 additions and 257 deletions
|
|
@ -535,9 +535,7 @@ proc copyLineInfo*(arg: NimNode, info: NimNode) {.magic: "NLineInfo", noSideEffe
|
|||
|
||||
proc lineInfoObj*(n: NimNode): LineInfo {.compileTime.} =
|
||||
## Returns ``LineInfo`` of ``n``, using absolute path for ``filename``.
|
||||
result.filename = n.getFile
|
||||
result.line = n.getLine
|
||||
result.column = n.getColumn
|
||||
result = LineInfo(filename: n.getFile, line: n.getLine, column: n.getColumn)
|
||||
|
||||
proc lineInfo*(arg: NimNode): string {.compileTime.} =
|
||||
## Return line info in the form `filepath(line, column)`.
|
||||
|
|
@ -878,12 +876,14 @@ proc treeRepr*(n: NimNode): string {.compileTime, benign.} =
|
|||
## Convert the AST `n` to a human-readable tree-like string.
|
||||
##
|
||||
## See also `repr`, `lispRepr`, and `astGenRepr`.
|
||||
result = ""
|
||||
n.treeTraverse(result, isLisp = false, indented = true)
|
||||
|
||||
proc lispRepr*(n: NimNode; indented = false): string {.compileTime, benign.} =
|
||||
## Convert the AST ``n`` to a human-readable lisp-like string.
|
||||
##
|
||||
## See also ``repr``, ``treeRepr``, and ``astGenRepr``.
|
||||
result = ""
|
||||
n.treeTraverse(result, isLisp = true, indented = indented)
|
||||
|
||||
proc astGenRepr*(n: NimNode): string {.compileTime, benign.} =
|
||||
|
|
@ -1611,6 +1611,7 @@ macro getCustomPragmaVal*(n: typed, cp: typed{nkSym}): untyped =
|
|||
## assert(o.myField.getCustomPragmaVal(serializationKey) == "mf")
|
||||
## assert(o.getCustomPragmaVal(serializationKey) == "mo")
|
||||
## assert(MyObj.getCustomPragmaVal(serializationKey) == "mo")
|
||||
result = nil
|
||||
let pragmaNode = customPragmaNode(n)
|
||||
for p in pragmaNode:
|
||||
if p.kind in nnkPragmaCallKinds and p.len > 0 and p[0].kind == nnkSym and p[0] == cp:
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@ proc binarySearch*[T, K](a: openArray[T], key: K,
|
|||
else:
|
||||
return -1
|
||||
|
||||
result = 0
|
||||
if (len and (len - 1)) == 0:
|
||||
# when `len` is a power of 2, a faster shr can be used.
|
||||
var step = len shr 1
|
||||
|
|
|
|||
|
|
@ -395,6 +395,8 @@ proc firstSetBitNim(x: uint64): int {.inline, noSideEffect.} =
|
|||
if k == 0:
|
||||
k = uint32(v shr 32'u32) and 0xFFFFFFFF'u32
|
||||
result = 32
|
||||
else:
|
||||
result = 0
|
||||
result += firstSetBitNim(k)
|
||||
|
||||
proc fastlog2Nim(x: uint32): int {.inline, noSideEffect.} =
|
||||
|
|
|
|||
|
|
@ -417,7 +417,8 @@ proc relativePath*(path, base: string, sep = DirSep): string {.
|
|||
if not sameRoot(path, base):
|
||||
return path
|
||||
|
||||
var f, b: PathIter
|
||||
var f = default PathIter
|
||||
var b = default PathIter
|
||||
var ff = (0, -1)
|
||||
var bb = (0, -1) # (int, int)
|
||||
result = newStringOfCap(path.len)
|
||||
|
|
@ -1053,6 +1054,7 @@ when defined(windows) or defined(posix) or defined(nintendoswitch):
|
|||
assert quoteShellCommand(["aaa", "", "c d"]) == "aaa \"\" \"c d\""
|
||||
|
||||
# can't use `map` pending https://github.com/nim-lang/Nim/issues/8303
|
||||
result = ""
|
||||
for i in 0..<args.len:
|
||||
if i > 0: result.add " "
|
||||
result.add quoteShell(args[i])
|
||||
|
|
@ -2981,7 +2983,7 @@ proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect], noW
|
|||
setLen(result, L)
|
||||
break
|
||||
elif defined(macosx):
|
||||
var size: cuint32
|
||||
var size = cuint32(0)
|
||||
getExecPath1(nil, size)
|
||||
result = newString(int(size))
|
||||
if getExecPath2(result, size):
|
||||
|
|
|
|||
|
|
@ -249,6 +249,7 @@ proc skipWhitespace*(s: string, start = 0): int {.inline.} =
|
|||
doAssert skipWhitespace(" Hello World", 0) == 1
|
||||
doAssert skipWhitespace("Hello World", 5) == 1
|
||||
doAssert skipWhitespace("Hello World", 5) == 2
|
||||
result = 0
|
||||
while start+result < s.len and s[start+result] in Whitespace: inc(result)
|
||||
|
||||
proc skip*(s, token: string, start = 0): int {.inline.} =
|
||||
|
|
@ -260,6 +261,7 @@ proc skip*(s, token: string, start = 0): int {.inline.} =
|
|||
doAssert skip("2019-01-22", "19", 2) == 2
|
||||
doAssert skip("CAPlow", "CAP", 0) == 3
|
||||
doAssert skip("CAPlow", "cap", 0) == 0
|
||||
result = 0
|
||||
while start+result < s.len and result < token.len and
|
||||
s[result+start] == token[result]:
|
||||
inc(result)
|
||||
|
|
@ -270,6 +272,7 @@ proc skipIgnoreCase*(s, token: string, start = 0): int =
|
|||
runnableExamples:
|
||||
doAssert skipIgnoreCase("CAPlow", "CAP", 0) == 3
|
||||
doAssert skipIgnoreCase("CAPlow", "cap", 0) == 3
|
||||
result = 0
|
||||
while start+result < s.len and result < token.len and
|
||||
toLower(s[result+start]) == toLower(token[result]): inc(result)
|
||||
if result != token.len: result = 0
|
||||
|
|
@ -282,6 +285,7 @@ proc skipUntil*(s: string, until: set[char], start = 0): int {.inline.} =
|
|||
doAssert skipUntil("Hello World", {'W', 'e'}, 0) == 1
|
||||
doAssert skipUntil("Hello World", {'W'}, 0) == 6
|
||||
doAssert skipUntil("Hello World", {'W', 'd'}, 0) == 6
|
||||
result = 0
|
||||
while start+result < s.len and s[result+start] notin until: inc(result)
|
||||
|
||||
proc skipUntil*(s: string, until: char, start = 0): int {.inline.} =
|
||||
|
|
@ -293,6 +297,7 @@ proc skipUntil*(s: string, until: char, start = 0): int {.inline.} =
|
|||
doAssert skipUntil("Hello World", 'o', 4) == 0
|
||||
doAssert skipUntil("Hello World", 'W', 0) == 6
|
||||
doAssert skipUntil("Hello World", 'w', 0) == 11
|
||||
result = 0
|
||||
while start+result < s.len and s[result+start] != until: inc(result)
|
||||
|
||||
proc skipWhile*(s: string, toSkip: set[char], start = 0): int {.inline.} =
|
||||
|
|
@ -302,6 +307,7 @@ proc skipWhile*(s: string, toSkip: set[char], start = 0): int {.inline.} =
|
|||
doAssert skipWhile("Hello World", {'H', 'e'}) == 2
|
||||
doAssert skipWhile("Hello World", {'e'}) == 0
|
||||
doAssert skipWhile("Hello World", {'W', 'o', 'r'}, 6) == 3
|
||||
result = 0
|
||||
while start+result < s.len and s[result+start] in toSkip: inc(result)
|
||||
|
||||
proc parseUntil*(s: string, token: var string, until: set[char],
|
||||
|
|
@ -437,7 +443,7 @@ proc parseBiggestInt*(s: string, number: var BiggestInt, start = 0): int {.
|
|||
var res: BiggestInt
|
||||
doAssert parseBiggestInt("9223372036854775807", res, 0) == 19
|
||||
doAssert res == 9223372036854775807
|
||||
var res: BiggestInt
|
||||
var res = BiggestInt(0)
|
||||
# use 'res' for exception safety (don't write to 'number' in case of an
|
||||
# overflow exception):
|
||||
result = rawParseInt(s, res, start)
|
||||
|
|
@ -455,7 +461,7 @@ proc parseInt*(s: string, number: var int, start = 0): int {.
|
|||
doAssert res == 2019
|
||||
doAssert parseInt("2019", res, 2) == 2
|
||||
doAssert res == 19
|
||||
var res: BiggestInt
|
||||
var res = BiggestInt(0)
|
||||
result = parseBiggestInt(s, res, start)
|
||||
when sizeof(int) <= 4:
|
||||
if res < low(int) or res > high(int):
|
||||
|
|
@ -518,7 +524,7 @@ proc parseBiggestUInt*(s: string, number: var BiggestUInt, start = 0): int {.
|
|||
doAssert res == 12
|
||||
doAssert parseBiggestUInt("1111111111111111111", res, 0) == 19
|
||||
doAssert res == 1111111111111111111'u64
|
||||
var res: BiggestUInt
|
||||
var res = BiggestUInt(0)
|
||||
# use 'res' for exception safety (don't write to 'number' in case of an
|
||||
# overflow exception):
|
||||
result = rawParseUInt(s, res, start)
|
||||
|
|
@ -536,7 +542,7 @@ proc parseUInt*(s: string, number: var uint, start = 0): int {.
|
|||
doAssert res == 3450
|
||||
doAssert parseUInt("3450", res, 2) == 2
|
||||
doAssert res == 50
|
||||
var res: BiggestUInt
|
||||
var res = BiggestUInt(0)
|
||||
result = parseBiggestUInt(s, res, start)
|
||||
when sizeof(BiggestUInt) > sizeof(uint) and sizeof(uint) <= 4:
|
||||
if res > 0xFFFF_FFFF'u64:
|
||||
|
|
@ -563,7 +569,7 @@ proc parseFloat*(s: string, number: var float, start = 0): int {.
|
|||
doAssert res == 32.57
|
||||
doAssert parseFloat("32.57", res, 3) == 2
|
||||
doAssert res == 57.00
|
||||
var bf: BiggestFloat
|
||||
var bf = BiggestFloat(0.0)
|
||||
result = parseBiggestFloat(s, bf, start)
|
||||
if result != 0:
|
||||
number = bf
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ proc next*(it: var PathIter; x: string): (int, int) =
|
|||
it.notFirst = true
|
||||
|
||||
iterator dirs(x: string): (int, int) =
|
||||
var it: PathIter
|
||||
var it = default PathIter
|
||||
while hasNext(it, x): yield next(it, x)
|
||||
|
||||
proc isDot(x: string; bounds: (int, int)): bool =
|
||||
|
|
|
|||
|
|
@ -1103,6 +1103,7 @@ proc parseInt*(s: string): int {.noSideEffect,
|
|||
## If `s` is not a valid integer, `ValueError` is raised.
|
||||
runnableExamples:
|
||||
doAssert parseInt("-0042") == -42
|
||||
result = 0
|
||||
let L = parseutils.parseInt(s, result, 0)
|
||||
if L != s.len or L == 0:
|
||||
raise newException(ValueError, "invalid integer: " & s)
|
||||
|
|
@ -1112,6 +1113,7 @@ proc parseBiggestInt*(s: string): BiggestInt {.noSideEffect,
|
|||
## Parses a decimal integer value contained in `s`.
|
||||
##
|
||||
## If `s` is not a valid integer, `ValueError` is raised.
|
||||
result = BiggestInt(0)
|
||||
let L = parseutils.parseBiggestInt(s, result, 0)
|
||||
if L != s.len or L == 0:
|
||||
raise newException(ValueError, "invalid integer: " & s)
|
||||
|
|
@ -1121,6 +1123,7 @@ proc parseUInt*(s: string): uint {.noSideEffect,
|
|||
## Parses a decimal unsigned integer value contained in `s`.
|
||||
##
|
||||
## If `s` is not a valid integer, `ValueError` is raised.
|
||||
result = uint(0)
|
||||
let L = parseutils.parseUInt(s, result, 0)
|
||||
if L != s.len or L == 0:
|
||||
raise newException(ValueError, "invalid unsigned integer: " & s)
|
||||
|
|
@ -1130,6 +1133,7 @@ proc parseBiggestUInt*(s: string): BiggestUInt {.noSideEffect,
|
|||
## Parses a decimal unsigned integer value contained in `s`.
|
||||
##
|
||||
## If `s` is not a valid integer, `ValueError` is raised.
|
||||
result = BiggestUInt(0)
|
||||
let L = parseutils.parseBiggestUInt(s, result, 0)
|
||||
if L != s.len or L == 0:
|
||||
raise newException(ValueError, "invalid unsigned integer: " & s)
|
||||
|
|
@ -1143,6 +1147,7 @@ proc parseFloat*(s: string): float {.noSideEffect,
|
|||
runnableExamples:
|
||||
doAssert parseFloat("3.14") == 3.14
|
||||
doAssert parseFloat("inf") == 1.0/0
|
||||
result = 0.0
|
||||
let L = parseutils.parseFloat(s, result, 0)
|
||||
if L != s.len or L == 0:
|
||||
raise newException(ValueError, "invalid float: " & s)
|
||||
|
|
@ -1161,6 +1166,7 @@ proc parseBinInt*(s: string): int {.noSideEffect,
|
|||
doAssert a.parseBinInt() == 53
|
||||
doAssert b.parseBinInt() == 7
|
||||
|
||||
result = 0
|
||||
let L = parseutils.parseBin(s, result, 0)
|
||||
if L != s.len or L == 0:
|
||||
raise newException(ValueError, "invalid binary integer: " & s)
|
||||
|
|
@ -1172,6 +1178,7 @@ proc parseOctInt*(s: string): int {.noSideEffect,
|
|||
## If `s` is not a valid oct integer, `ValueError` is raised. `s` can have one
|
||||
## of the following optional prefixes: ``0o``, ``0O``. Underscores within
|
||||
## `s` are ignored.
|
||||
result = 0
|
||||
let L = parseutils.parseOct(s, result, 0)
|
||||
if L != s.len or L == 0:
|
||||
raise newException(ValueError, "invalid oct integer: " & s)
|
||||
|
|
@ -1183,6 +1190,7 @@ proc parseHexInt*(s: string): int {.noSideEffect,
|
|||
## If `s` is not a valid hex integer, `ValueError` is raised. `s` can have one
|
||||
## of the following optional prefixes: ``0x``, ``0X``, ``#``. Underscores
|
||||
## within `s` are ignored.
|
||||
result = 0
|
||||
let L = parseutils.parseHex(s, result, 0)
|
||||
if L != s.len or L == 0:
|
||||
raise newException(ValueError, "invalid hex integer: " & s)
|
||||
|
|
@ -1270,9 +1278,9 @@ macro genEnumStmt(typ: typedesc, argSym: typed, default: typed): untyped =
|
|||
result = nnkCaseStmt.newTree(nnkDotExpr.newTree(argSym,
|
||||
bindSym"nimIdentNormalize"))
|
||||
# stores all processed field strings to give error msg for ambiguous enums
|
||||
var foundFields: seq[string]
|
||||
var fStr: string # string of current field
|
||||
var fNum: BiggestInt # int value of current field
|
||||
var foundFields: seq[string] = @[]
|
||||
var fStr = "" # string of current field
|
||||
var fNum = BiggestInt(0) # int value of current field
|
||||
for f in impl:
|
||||
case f.kind
|
||||
of nnkEmpty: continue # skip first node of `enumTy`
|
||||
|
|
@ -2028,6 +2036,7 @@ proc rfind*(s, sub: string, start: Natural = 0, last = -1): int {.noSideEffect,
|
|||
if sub.len == 0:
|
||||
return -1
|
||||
let last = if last == -1: s.high else: last
|
||||
result = 0
|
||||
for i in countdown(last - sub.len + 1, start):
|
||||
for j in 0..sub.len-1:
|
||||
result = i
|
||||
|
|
@ -2044,6 +2053,7 @@ proc count*(s: string, sub: char): int {.noSideEffect,
|
|||
##
|
||||
## See also:
|
||||
## * `countLines proc<#countLines,string>`_
|
||||
result = 0
|
||||
for c in s:
|
||||
if c == sub: inc result
|
||||
|
||||
|
|
@ -2054,6 +2064,7 @@ proc count*(s: string, subs: set[char]): int {.noSideEffect,
|
|||
## See also:
|
||||
## * `countLines proc<#countLines,string>`_
|
||||
doAssert card(subs) > 0
|
||||
result = 0
|
||||
for c in s:
|
||||
if c in subs: inc result
|
||||
|
||||
|
|
@ -2066,6 +2077,7 @@ proc count*(s: string, sub: string, overlapping: bool = false): int {.
|
|||
## See also:
|
||||
## * `countLines proc<#countLines,string>`_
|
||||
doAssert sub.len > 0
|
||||
result = 0
|
||||
var i = 0
|
||||
while true:
|
||||
i = s.find(sub, i)
|
||||
|
|
@ -2313,7 +2325,7 @@ proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect,
|
|||
case s[i+1]:
|
||||
of 'x':
|
||||
inc i, 2
|
||||
var c: int
|
||||
var c = 0
|
||||
i += parseutils.parseHex(s, c, i, maxLen = 2)
|
||||
result.add(chr(c))
|
||||
dec i, 2
|
||||
|
|
@ -2514,7 +2526,7 @@ proc formatSize*(bytes: int64,
|
|||
xb: int64 = bytes
|
||||
fbytes: float
|
||||
lastXb: int64 = bytes
|
||||
matchedIndex: int
|
||||
matchedIndex = 0
|
||||
prefixes: array[9, string]
|
||||
if prefix == bpColloquial:
|
||||
prefixes = collPrefixes
|
||||
|
|
|
|||
|
|
@ -895,16 +895,16 @@ proc getTime*(): Time {.tags: [TimeEffect], benign.} =
|
|||
millis mod convert(Seconds, Milliseconds, 1).int)
|
||||
result = initTime(seconds, nanos)
|
||||
elif defined(macosx):
|
||||
var a: Timeval
|
||||
var a {.noinit.}: Timeval
|
||||
gettimeofday(a)
|
||||
result = initTime(a.tv_sec.int64,
|
||||
convert(Microseconds, Nanoseconds, a.tv_usec.int))
|
||||
elif defined(posix):
|
||||
var ts: Timespec
|
||||
var ts {.noinit.}: Timespec
|
||||
discard clock_gettime(CLOCK_REALTIME, ts)
|
||||
result = initTime(ts.tv_sec.int64, ts.tv_nsec.int)
|
||||
elif defined(windows):
|
||||
var f: FILETIME
|
||||
var f {.noinit.}: FILETIME
|
||||
getSystemTimeAsFileTime(f)
|
||||
result = fromWinTime(rdFileTime(f))
|
||||
|
||||
|
|
@ -1756,7 +1756,7 @@ proc formatPattern(dt: DateTime, pattern: FormatPattern, result: var string,
|
|||
proc parsePattern(input: string, pattern: FormatPattern, i: var int,
|
||||
parsed: var ParsedTime, loc: DateTimeLocale): bool =
|
||||
template takeInt(allowedWidth: Slice[int], allowSign = false): int =
|
||||
var sv: int
|
||||
var sv = 0
|
||||
var pd = parseInt(input, sv, i, allowedWidth.b, allowSign)
|
||||
if pd < allowedWidth.a:
|
||||
return false
|
||||
|
|
@ -1987,6 +1987,7 @@ proc format*(dt: DateTime, f: TimeFormat,
|
|||
let dt = initDateTime(01, mJan, 2000, 00, 00, 00, utc())
|
||||
doAssert "2000-01-01" == dt.format(f)
|
||||
assertDateTimeInitialized dt
|
||||
result = ""
|
||||
var idx = 0
|
||||
while idx <= f.patterns.high:
|
||||
case f.patterns[idx].FormatPattern
|
||||
|
|
@ -2284,7 +2285,7 @@ proc between*(startDt, endDt: DateTime): TimeInterval =
|
|||
endDate.monthday.dec
|
||||
|
||||
# Years
|
||||
result.years.inc endDate.year - startDate.year - 1
|
||||
result.years = endDate.year - startDate.year - 1
|
||||
if (startDate.month, startDate.monthday) <= (endDate.month, endDate.monthday):
|
||||
result.years.inc
|
||||
startDate.year.inc result.years
|
||||
|
|
@ -2441,6 +2442,7 @@ proc evaluateInterval(dt: DateTime, interval: TimeInterval):
|
|||
var months = interval.years * 12 + interval.months
|
||||
var curYear = dt.year
|
||||
var curMonth = dt.month
|
||||
result = default(tuple[adjDur, absDur: Duration])
|
||||
# Subtracting
|
||||
if months < 0:
|
||||
for mth in countdown(-1 * months, 1):
|
||||
|
|
@ -2562,17 +2564,17 @@ proc epochTime*(): float {.tags: [TimeEffect].} =
|
|||
##
|
||||
## ``getTime`` should generally be preferred over this proc.
|
||||
when defined(macosx):
|
||||
var a: Timeval
|
||||
var a {.noinit.}: Timeval
|
||||
gettimeofday(a)
|
||||
result = toBiggestFloat(a.tv_sec.int64) + toBiggestFloat(
|
||||
a.tv_usec)*0.00_0001
|
||||
elif defined(posix):
|
||||
var ts: Timespec
|
||||
var ts {.noinit.}: Timespec
|
||||
discard clock_gettime(CLOCK_REALTIME, ts)
|
||||
result = toBiggestFloat(ts.tv_sec.int64) +
|
||||
toBiggestFloat(ts.tv_nsec.int64) / 1_000_000_000
|
||||
elif defined(windows):
|
||||
var f: winlean.FILETIME
|
||||
var f {.noinit.}: winlean.FILETIME
|
||||
getSystemTimeAsFileTime(f)
|
||||
var i64 = rdFileTime(f) - epochDiff
|
||||
var secs = i64 div rateDiff
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ macro genericParamsImpl(T: typedesc): untyped =
|
|||
of nnkBracketExpr:
|
||||
for i in 1..<impl.len:
|
||||
let ai = impl[i]
|
||||
var ret: NimNode
|
||||
var ret: NimNode = nil
|
||||
case ai.typeKind
|
||||
of ntyTypeDesc:
|
||||
ret = ai
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ proc runeLen*(s: string): int {.rtl, extern: "nuc$1".} =
|
|||
doAssert a.runeLen == 6
|
||||
## note: a.len == 8
|
||||
|
||||
result = 0
|
||||
var i = 0
|
||||
while i < len(s):
|
||||
if uint(s[i]) <= 127: inc(i)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ const NimStackTraceMsgs = compileOption("stacktraceMsgs")
|
|||
template procName*(): string =
|
||||
## returns current C/C++ function name
|
||||
when defined(c) or defined(cpp):
|
||||
var name {.inject.}: cstring
|
||||
var name {.inject, noinit.}: cstring
|
||||
{.emit: "`name` = __func__;".}
|
||||
$name
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ template getPFrame*(): PFrame =
|
|||
## avoids a function call (unlike `getFrame()`)
|
||||
block:
|
||||
when NimStackTrace:
|
||||
var framePtr {.inject.}: PFrame
|
||||
var framePtr {.inject, noinit.}: PFrame
|
||||
{.emit: "`framePtr` = &FR_;".}
|
||||
framePtr
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ template setFrameMsg*(msg: string, prefix = " ") =
|
|||
## in a given PFrame. Noop unless passing --stacktraceMsgs and --stacktrace
|
||||
when NimStackTrace and NimStackTraceMsgs:
|
||||
block:
|
||||
var fr {.inject.}: PFrame
|
||||
var fr {.inject, noinit.}: PFrame
|
||||
{.emit: "`fr` = &FR_;".}
|
||||
# consider setting a custom upper limit on size (analog to stack overflow)
|
||||
frameMsgBuf.setLen fr.frameMsgLen
|
||||
|
|
|
|||
|
|
@ -1767,6 +1767,7 @@ export iterators
|
|||
proc find*[T, S](a: T, item: S): int {.inline.}=
|
||||
## Returns the first index of `item` in `a` or -1 if not found. This requires
|
||||
## appropriate `items` and `==` operations to work.
|
||||
result = 0
|
||||
for i in items(a):
|
||||
if i == item: return
|
||||
inc(result)
|
||||
|
|
@ -2105,7 +2106,7 @@ when not defined(js):
|
|||
# Linux 64bit system. -- That's because the stack direction is the other
|
||||
# way around.
|
||||
when declared(nimGC_setStackBottom):
|
||||
var locals {.volatile.}: pointer
|
||||
var locals {.volatile, noinit.}: pointer
|
||||
locals = addr(locals)
|
||||
nimGC_setStackBottom(locals)
|
||||
|
||||
|
|
@ -2274,7 +2275,9 @@ when notJSnotNims:
|
|||
of 2: d = uint(cast[ptr uint16](a + uint(n.offset))[])
|
||||
of 4: d = uint(cast[ptr uint32](a + uint(n.offset))[])
|
||||
of 8: d = uint(cast[ptr uint64](a + uint(n.offset))[])
|
||||
else: sysAssert(false, "getDiscriminant: invalid n.typ.size")
|
||||
else:
|
||||
d = 0'u
|
||||
sysAssert(false, "getDiscriminant: invalid n.typ.size")
|
||||
return d
|
||||
|
||||
proc selectBranch(aa: pointer, n: ptr TNimNode): ptr TNimNode =
|
||||
|
|
|
|||
|
|
@ -586,7 +586,8 @@ proc freeBigChunk(a: var MemRegion, c: PBigChunk) =
|
|||
proc getBigChunk(a: var MemRegion, size: int): PBigChunk =
|
||||
sysAssert(size > 0, "getBigChunk 2")
|
||||
var size = size # roundup(size, PageSize)
|
||||
var fl, sl: int
|
||||
var fl = 0
|
||||
var sl = 0
|
||||
mappingSearch(size, fl, sl)
|
||||
sysAssert((size and PageMask) == 0, "getBigChunk: unaligned chunk")
|
||||
result = findSuitableBlock(a, fl, sl)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ proc `$`(x: int): string {.magic: "IntToStr", noSideEffect.}
|
|||
proc `$`(info: InstantiationInfo): string =
|
||||
# The +1 is needed here
|
||||
# instead of overriding `$` (and changing its meaning), consider explicit name.
|
||||
result = ""
|
||||
result.toLocation(info.filename, info.line, info.column+1)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ proc stackSize(stack: ptr GcStack): int {.noinline.} =
|
|||
when nimCoroutines:
|
||||
var pos = stack.pos
|
||||
else:
|
||||
var pos {.volatile.}: pointer
|
||||
var pos {.volatile, noinit.}: pointer
|
||||
pos = addr(pos)
|
||||
|
||||
if pos != nil:
|
||||
|
|
@ -229,6 +229,7 @@ proc stackSize(stack: ptr GcStack): int {.noinline.} =
|
|||
result = 0
|
||||
|
||||
proc stackSize(): int {.noinline.} =
|
||||
result = 0
|
||||
for stack in gch.stack.items():
|
||||
result = result + stack.stackSize()
|
||||
|
||||
|
|
@ -303,7 +304,7 @@ when not defined(useNimRtl):
|
|||
{.pop.}
|
||||
|
||||
proc isOnStack(p: pointer): bool =
|
||||
var stackTop {.volatile.}: pointer
|
||||
var stackTop {.volatile, noinit.}: pointer
|
||||
stackTop = addr(stackTop)
|
||||
var a = cast[ByteAddress](gch.getActiveStack().bottom)
|
||||
var b = cast[ByteAddress](stackTop)
|
||||
|
|
|
|||
|
|
@ -424,12 +424,12 @@ proc write*(f: File, b: bool) {.tags: [WriteIOEffect], benign.} =
|
|||
else: write(f, "false")
|
||||
|
||||
proc write*(f: File, r: float32) {.tags: [WriteIOEffect], benign.} =
|
||||
var buffer: array[65, char]
|
||||
var buffer {.noinit.}: array[65, char]
|
||||
discard writeFloatToBuffer(buffer, r)
|
||||
if c_fprintf(f, "%s", buffer[0].addr) < 0: checkErr(f)
|
||||
|
||||
proc write*(f: File, r: BiggestFloat) {.tags: [WriteIOEffect], benign.} =
|
||||
var buffer: array[65, char]
|
||||
var buffer {.noinit.}: array[65, char]
|
||||
discard writeFloatToBuffer(buffer, r)
|
||||
if c_fprintf(f, "%s", buffer[0].addr) < 0: checkErr(f)
|
||||
|
||||
|
|
@ -591,7 +591,7 @@ when defined(posix) and not defined(nimscript):
|
|||
|
||||
proc open*(f: var File, filename: string,
|
||||
mode: FileMode = fmRead,
|
||||
bufSize: int = -1): bool {.tags: [], raises: [], benign.} =
|
||||
bufSize: int = -1): bool {.tags: [], raises: [], benign.} =
|
||||
## Opens a file named `filename` with given `mode`.
|
||||
##
|
||||
## Default mode is readonly. Returns true if the file could be opened.
|
||||
|
|
@ -605,7 +605,7 @@ proc open*(f: var File, filename: string,
|
|||
# How `fopen` handles opening a directory is not specified in ISO C and
|
||||
# POSIX. We do not want to handle directories as regular files that can
|
||||
# be opened.
|
||||
var res: Stat
|
||||
var res {.noinit.}: Stat
|
||||
if c_fstat(getFileHandle(f2), res) >= 0'i32 and modeIsDir(res.st_mode):
|
||||
close(f2)
|
||||
return false
|
||||
|
|
@ -759,7 +759,7 @@ proc readFile*(filename: string): TaintedString {.tags: [ReadIOEffect], benign.}
|
|||
## Raises an IO exception in case of an error. If you need to call
|
||||
## this inside a compile time macro you can use `staticRead
|
||||
## <system.html#staticRead,string>`_.
|
||||
var f: File
|
||||
var f: File = nil
|
||||
if open(f, filename):
|
||||
try:
|
||||
result = readAll(f)
|
||||
|
|
@ -772,7 +772,7 @@ proc writeFile*(filename, content: string) {.tags: [WriteIOEffect], benign.} =
|
|||
## Opens a file named `filename` for writing. Then writes the
|
||||
## `content` completely to the file and closes the file afterwards.
|
||||
## Raises an IO exception in case of an error.
|
||||
var f: File
|
||||
var f: File = nil
|
||||
if open(f, filename, fmWrite):
|
||||
try:
|
||||
f.write(content)
|
||||
|
|
@ -785,7 +785,7 @@ proc writeFile*(filename: string, content: openArray[byte]) {.since: (1, 1).} =
|
|||
## Opens a file named `filename` for writing. Then writes the
|
||||
## `content` completely to the file and closes the file afterwards.
|
||||
## Raises an IO exception in case of an error.
|
||||
var f: File
|
||||
var f: File = nil
|
||||
if open(f, filename, fmWrite):
|
||||
try:
|
||||
f.writeBuffer(unsafeAddr content[0], content.len)
|
||||
|
|
@ -799,7 +799,7 @@ proc readLines*(filename: string, n: Natural): seq[TaintedString] =
|
|||
## in case of an error. Raises EOF if file does not contain at least `n` lines.
|
||||
## Available at compile time. A line of text may be delimited by ``LF`` or ``CRLF``.
|
||||
## The newline character(s) are not part of the returned strings.
|
||||
var f: File
|
||||
var f: File = nil
|
||||
if open(f, filename):
|
||||
try:
|
||||
result = newSeq[TaintedString](n)
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ proc reprSetAux(result: var string, p: pointer, typ: PNimType) =
|
|||
of 4: u = cast[ptr uint32](p)[]
|
||||
of 8: u = cast[ptr uint64](p)[]
|
||||
else:
|
||||
u = uint64(0)
|
||||
var a = cast[PByteArray](p)
|
||||
for i in 0 .. typ.size*8-1:
|
||||
if (uint(a[i shr 3]) and (1'u shl (i and 7))) != 0:
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ proc countBits64(n: uint64): int {.compilerproc, inline.} =
|
|||
|
||||
proc cardSet(s: NimSet, len: int): int {.compilerproc, inline.} =
|
||||
var i = 0
|
||||
result = 0
|
||||
when defined(x86) or defined(amd64):
|
||||
while i < len - 8:
|
||||
inc(result, countBits64((cast[ptr uint64](s[i].unsafeAddr))[]))
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ proc addFloat*(result: var string; x: float) =
|
|||
when nimvm:
|
||||
result.add $x
|
||||
else:
|
||||
var buffer: array[65, char]
|
||||
var buffer {.noinit.}: array[65, char]
|
||||
let n = writeFloatToBuffer(buffer, x)
|
||||
result.addCstringN(cstring(buffer[0].addr), n)
|
||||
|
||||
|
|
@ -131,8 +131,8 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
|
|||
i = start
|
||||
sign = 1.0
|
||||
kdigits, fdigits = 0
|
||||
exponent: int
|
||||
integer: uint64
|
||||
exponent = 0
|
||||
integer = uint64(0)
|
||||
fracExponent = 0
|
||||
expSign = 1
|
||||
firstDigit = -1
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ proc ord(arg: Utf16Char): int = int(cast[uint16](arg))
|
|||
proc len*(w: WideCString): int =
|
||||
## returns the length of a widestring. This traverses the whole string to
|
||||
## find the binary zero end marker!
|
||||
result = 0
|
||||
while int16(w[result]) != 0'i16: inc result
|
||||
|
||||
const
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue