more strictdef fixes for stdlibs (#24535)

This commit is contained in:
ringabout
2024-12-14 02:06:43 +08:00
committed by GitHub
parent be4d19e562
commit d31cce557b
21 changed files with 140 additions and 97 deletions

View File

@@ -34,6 +34,7 @@ func startsWith*(s, prefix: cstring): bool {.rtl, extern: "csuStartsWith".} =
assert startsWith(cstring"Hello", cstring"")
when nimvm:
result = false
startsWithImpl(s, prefix)
else:
when defined(js):
@@ -56,6 +57,7 @@ func endsWith*(s, suffix: cstring): bool {.rtl, extern: "csuEndsWith".} =
assert endsWith(cstring"Hello", cstring"")
when nimvm:
result = false
endsWithImpl(s, suffix)
else:
when defined(js):

View File

@@ -287,7 +287,7 @@ proc getLastModificationTime*(file: string): times.Time {.rtl, extern: "nos$1",
## * `getCreationTime proc`_
## * `fileNewer proc`_
when defined(posix):
var res: Stat
var res: Stat = default(Stat)
if stat(file, res) < 0'i32: raiseOSError(osLastError(), file)
result = res.st_mtim.toTime
else:
@@ -305,7 +305,7 @@ proc getLastAccessTime*(file: string): times.Time {.rtl, extern: "nos$1", noWeir
## * `getCreationTime proc`_
## * `fileNewer proc`_
when defined(posix):
var res: Stat
var res: Stat = default(Stat)
if stat(file, res) < 0'i32: raiseOSError(osLastError(), file)
result = res.st_atim.toTime
else:
@@ -327,7 +327,7 @@ proc getCreationTime*(file: string): times.Time {.rtl, extern: "nos$1", noWeirdT
## * `getLastAccessTime proc`_
## * `fileNewer proc`_
when defined(posix):
var res: Stat
var res: Stat = default(Stat)
if stat(file, res) < 0'i32: raiseOSError(osLastError(), file)
result = res.st_ctim.toTime
else:
@@ -698,7 +698,7 @@ proc sleep*(milsecs: int) {.rtl, extern: "nos$1", tags: [TimeEffect], noWeirdTar
return # fixes #23732
winlean.sleep(int32(milsecs))
else:
var a, b: Timespec
var a, b: Timespec = default(Timespec)
a.tv_sec = posix.Time(milsecs div 1000)
a.tv_nsec = (milsecs mod 1000) * 1000 * 1000
discard posix.nanosleep(a, b)
@@ -714,7 +714,7 @@ proc getFileSize*(file: string): BiggestInt {.rtl, extern: "nos$1",
result = rdFileSize(a)
findClose(resA)
else:
var rawInfo: Stat
var rawInfo: Stat = default(Stat)
if stat(file, rawInfo) < 0'i32:
raiseOSError(osLastError(), file)
rawInfo.st_size
@@ -881,6 +881,7 @@ proc getFileInfo*(path: string, followSymlink = true): FileInfo {.noWeirdTarget.
## See also:
## * `getFileInfo(handle) proc`_
## * `getFileInfo(file) proc`_
result = default(FileInfo)
when defined(windows):
var
handle = openHandle(path, followSymlink)
@@ -892,7 +893,7 @@ proc getFileInfo*(path: string, followSymlink = true): FileInfo {.noWeirdTarget.
rawToFormalFileInfo(rawInfo, path, result)
discard closeHandle(handle)
else:
var rawInfo: Stat
var rawInfo: Stat = default(Stat)
if followSymlink:
if stat(path, rawInfo) < 0'i32:
raiseOSError(osLastError(), path)
@@ -909,7 +910,7 @@ proc sameFileContent*(path1, path2: string): bool {.rtl, extern: "nos$1",
## See also:
## * `sameFile proc`_
var
a, b: File
a, b: File = default(File)
if not open(a, path1): return false
if not open(b, path2):
close(a)

View File

@@ -453,7 +453,7 @@ proc getKeyValPair(c: var CfgParser, kind: CfgEventKind): CfgEvent =
case kind
of cfgOption, cfgKeyValuePair:
result = CfgEvent(kind: kind, key: c.tok.literal.move, value: "")
else: discard
else: result = CfgEvent()
rawGetTok(c, c.tok)
if c.tok.kind in {tkEquals, tkColon}:
rawGetTok(c, c.tok)
@@ -512,7 +512,7 @@ proc loadConfig*(stream: Stream, filename: string = "[stream]"): Config =
var curSection = "" ## Current section,
## the default value of the current section is "",
## which means that the current section is a common
var p: CfgParser
var p: CfgParser = default(CfgParser)
open(p, stream, filename)
while true:
var e = next(p)
@@ -574,7 +574,7 @@ proc writeConfig*(dict: Config, stream: Stream) =
else:
stream.writeLine("[" & section & "]")
for key, value in sectionData.pairs():
var kv, segmentChar: string
var kv, segmentChar: string = ""
if key.len > 1 and key[0] == '-' and key[1] == '-': ## If it is a command key
segmentChar = ":"
if not allCharsInSet(key[2..key.len()-1], SymChars):

View File

@@ -237,13 +237,10 @@ proc initOptParser*(cmdline: seq[string], shortNoVal: set[char] = {},
p = initOptParser(@["--left", "--debug:3", "-l", "-r:2"])
p = initOptParser(@["--left", "--debug:3", "-l", "-r:2"],
shortNoVal = {'l'}, longNoVal = @["left"])
result.pos = 0
result.idx = 0
result.inShortState = false
result.shortNoVal = shortNoVal
result.longNoVal = longNoVal
result.allowWhitespaceAfterColon = allowWhitespaceAfterColon
result = OptParser(pos: 0, idx: 0, inShortState: false,
shortNoVal: shortNoVal, longNoVal: longNoVal,
allowWhitespaceAfterColon: allowWhitespaceAfterColon
)
if cmdline.len != 0:
result.cmds = newSeq[string](cmdline.len)
for i in 0..<cmdline.len:

View File

@@ -105,6 +105,8 @@ proc parseBin*[T: SomeInteger](s: openArray[char], number: var T, maxLen = 0): i
if foundDigit:
number = output
result = i
else:
result = 0
proc parseOct*[T: SomeInteger](s: openArray[char], number: var T, maxLen = 0): int {.noSideEffect.} =
## Parses an octal number and stores its value in ``number``.
@@ -151,6 +153,8 @@ proc parseOct*[T: SomeInteger](s: openArray[char], number: var T, maxLen = 0): i
if foundDigit:
number = output
result = i
else:
result = 0
proc parseHex*[T: SomeInteger](s: openArray[char], number: var T, maxLen = 0): int {.noSideEffect.} =
## Parses a hexadecimal number and stores its value in ``number``.
@@ -225,6 +229,8 @@ proc parseIdent*(s: openArray[char], ident: var string): int =
while i < s.len and s[i] in IdentChars: inc(i)
ident = substr(s.toOpenArray(0, i-1))
result = i
else:
result = 0
proc parseIdent*(s: openArray[char]): string =
## Parses an identifier and returns it or an empty string in
@@ -234,12 +240,13 @@ proc parseIdent*(s: openArray[char]): string =
doAssert parseIdent("Hello World", 1) == "ello"
doAssert parseIdent("Hello World", 5) == ""
doAssert parseIdent("Hello World", 6) == "World"
result = ""
var i = 0
if i < s.len and s[i] in IdentStartChars:
inc(i)
while i < s.len and s[i] in IdentChars: inc(i)
result = substr(s.toOpenArray(0, i - 1))
else:
result = ""
proc parseChar*(s: openArray[char], c: var char): int =
## Parses a single character, stores it in `c` and returns 1.
@@ -254,6 +261,8 @@ proc parseChar*(s: openArray[char], c: var char): int =
if s.len > 0:
c = s[0]
result = 1
else:
result = 0
proc skipWhitespace*(s: openArray[char]): int {.inline.} =
## Skips the whitespace starting at ``s[start]``. Returns the number of
@@ -417,7 +426,7 @@ proc captureBetween*(s: openArray[char], first: char, second = '\0'): string =
result = ""
discard parseUntil(s.toOpenArray(i, s.high), result, if second == '\0': first else: second)
proc integerOutOfRangeError() {.noinline.} =
proc integerOutOfRangeError() {.noinline, noreturn.} =
raise newException(ValueError, "Parsed integer outside of valid range")
# See #6752
@@ -448,6 +457,8 @@ proc rawParseInt(s: openArray[char], b: var BiggestInt): int =
else:
b = b * sign
result = i
else:
result = 0
when defined(js):
{.pop.} # overflowChecks: off
@@ -510,6 +521,8 @@ proc parseSaturatedNatural*(s: openArray[char], b: var int): int {.
inc(i)
while i < s.len and s[i] == '_': inc(i) # underscores are allowed and ignored
result = i
else:
result = 0
proc rawParseUInt(s: openArray[char], b: var BiggestUInt): int =
var
@@ -530,6 +543,8 @@ proc rawParseUInt(s: openArray[char], b: var BiggestUInt): int =
while i < s.len and s[i] == '_': inc(i) # underscores are allowed and ignored
b = res
result = i
else:
result = 0
proc parseBiggestUInt*(s: openArray[char], number: var BiggestUInt): int {.
rtl, extern: "npuParseBiggestUInt", noSideEffect, raises: [ValueError].} =
@@ -632,7 +647,7 @@ func parseSize*(s: openArray[char], size: var int64, alwaysBin=false): int =
const scaleB = [1.0, 1024, 1048576, 1073741824, 1099511627776.0, # 2^(10*idx)
1125899906842624.0, 1152921504606846976.0, # ldexp?
1.180591620717411303424e21, 1.208925819614629174706176e24]
var number: float
var number: float = 0.0
var scale = 1.0
result = parseFloat(s, number)
if number < 0: # While parseFloat accepts negatives ..

View File

@@ -439,7 +439,7 @@ proc parseEntity(my: var XmlParser, dest: var string) =
var pos = my.bufpos+1
my.kind = xmlCharData
if my.buf[pos] == '#':
var r: int
var r: int = 0
inc(pos)
if my.buf[pos] == 'x':
inc(pos)

View File

@@ -25,6 +25,7 @@ proc hasNext*(it: PathIter; x: string): bool =
it.i < x.len
proc next*(it: var PathIter; x: string): (int, int) =
result = (0, 0)
it.prev = it.i
if not it.notFirst and x[it.i] in {DirSep, AltSep}:
# absolute path:
@@ -71,7 +72,7 @@ proc addNormalizePath*(x: string; result: var string; state: var int;
# state: 0th bit set if isAbsolute path. Other bits count
# the number of path components.
var it: PathIter
var it: PathIter = default(PathIter)
it.notFirst = (state shr 1) > 0
if it.notFirst:
while it.i < x.len and x[it.i] in {DirSep, AltSep}: inc it.i

View File

@@ -605,8 +605,7 @@ proc initRand*(seed: int64): Rand =
var r2 = initRand(now.toUnix * 1_000_000_000 + now.nanosecond)
const seedFallback0 = int32.high # arbitrary
let seed = if seed != 0: seed else: seedFallback0 # because 0 is a fixed point
result.a0 = Ui(seed shr 16)
result.a1 = Ui(seed and 0xffff)
result = Rand(a0: Ui(seed shr 16), a1: Ui(seed and 0xffff))
when not defined(nimLegacyRandomInitRand):
# calling `discard next(result)` (even a few times) would still produce
# skewed numbers for the 1st call to `rand()`.
@@ -708,7 +707,8 @@ when not defined(standalone):
if not result.isValid:
result = DefaultRandSeed
else:
var urand: array[sizeof(Rand), byte]
result = default(Rand)
var urand = default(array[sizeof(Rand), byte])
for i in 0 .. 7:
if sysrand.urandom(urand):

View File

@@ -107,7 +107,7 @@ proc insertInCache(s: string, tree: Rope): Rope =
result = newRope(s)
when countCacheMisses: inc(misses)
return
var cmp: int
var cmp: int = 0
t = splay(s, t, cmp)
if cmp == 0:
# We get here if it's already in the Tree
@@ -209,7 +209,7 @@ proc `&`*(a: openArray[Rope]): Rope {.rtl, extern: "nroConcOpenArray".} =
runnableExamples:
let r = &[rope("Hello, "), rope("Nim"), rope("!")]
doAssert $r == "Hello, Nim!"
result = nil
for item in a: result = result & item
proc add*(a: var Rope, b: Rope) {.rtl, extern: "nro$1Rope".} =
@@ -239,7 +239,7 @@ proc `[]`*(r: Rope, i: int): char {.rtl, extern: "nroCharAt".} =
doAssert r[0] == 'H'
doAssert r[7] == 'N'
doAssert r[22] == '\0'
result = '\0'
var x = r
var j = i
if x == nil or i < 0 or i >= r.len: return
@@ -362,7 +362,7 @@ when not defined(js) and not defined(nimscript):
proc equalsFile*(r: Rope, f: File): bool {.rtl, extern: "nro$1File".} =
## Returns true if the contents of the file `f` equal `r`.
var
buf: array[bufSize, char]
buf: array[bufSize, char] = default(array[bufSize, char])
bpos = buf.len
blen = buf.len
@@ -389,7 +389,7 @@ when not defined(js) and not defined(nimscript):
proc equalsFile*(r: Rope, filename: string): bool {.rtl, extern: "nro$1Str".} =
## Returns true if the contents of the file `f` equal `r`. If `f` does not
## exist, false is returned.
var f: File
var f: File = default(File)
result = open(f, filename)
if result:
result = equalsFile(r, f)

View File

@@ -135,6 +135,7 @@ proc variance*(s: RunningStat): float =
proc varianceS*(s: RunningStat): float =
## Computes the current sample variance of `s`.
if s.n > 1: result = s.mom2 / toFloat(s.n - 1)
else: result = 0.0
proc standardDeviation*(s: RunningStat): float =
## Computes the current population standard deviation of `s`.
@@ -167,6 +168,7 @@ proc `+`*(a, b: RunningStat): RunningStat =
##
## Useful when performing parallel analysis of data series
## and needing to re-combine parallel result sets.
result = default(RunningStat)
result.clear()
result.n = a.n + b.n
@@ -317,6 +319,7 @@ proc `+`*(a, b: RunningRegress): RunningRegress =
##
## Useful when performing parallel analysis of data series
## and needing to re-combine parallel result sets
result = default(RunningRegress)
result.clear()
result.x_stats = a.x_stats + b.x_stats
result.y_stats = a.y_stats + b.y_stats

View File

@@ -462,7 +462,7 @@ proc readChar*(s: Stream): char =
doAssert strm.readChar() == '3'
doAssert strm.readChar() == '\x00'
strm.close()
result = '\0'
jsOrVmBlock:
var str = " "
if readDataStr(s, str, 0..0) != 1: result = '\0'
@@ -481,6 +481,7 @@ proc peekChar*(s: Stream): char =
doAssert strm.peekChar() == '\x00'
strm.close()
result = '\0'
when defined(js):
var str = " "
if peekData(s, addr(str), sizeof(result)) != 1: result = '\0'
@@ -509,7 +510,7 @@ proc readBool*(s: Stream): bool =
doAssertRaises(IOError): discard strm.readBool()
strm.close()
var t: byte
var t: byte = byte(0)
read(s, t)
result = t != 0.byte
@@ -536,7 +537,7 @@ proc peekBool*(s: Stream): bool =
doAssert strm.peekBool() == false
strm.close()
var t: byte
var t: byte = byte(0)
peek(s, t)
result = t != 0.byte
@@ -556,7 +557,7 @@ proc readInt8*(s: Stream): int8 =
doAssert strm.readInt8() == 2'i8
doAssertRaises(IOError): discard strm.readInt8()
strm.close()
result = int8(0)
read(s, result)
proc peekInt8*(s: Stream): int8 =
@@ -577,7 +578,7 @@ proc peekInt8*(s: Stream): int8 =
doAssert strm.readInt8() == 1'i8
doAssert strm.peekInt8() == 2'i8
strm.close()
result = int8(0)
peek(s, result)
proc readInt16*(s: Stream): int16 =
@@ -596,7 +597,7 @@ proc readInt16*(s: Stream): int16 =
doAssert strm.readInt16() == 2'i16
doAssertRaises(IOError): discard strm.readInt16()
strm.close()
result = int16(0)
read(s, result)
proc peekInt16*(s: Stream): int16 =
@@ -617,7 +618,7 @@ proc peekInt16*(s: Stream): int16 =
doAssert strm.readInt16() == 1'i16
doAssert strm.peekInt16() == 2'i16
strm.close()
result = int16(0)
peek(s, result)
proc readInt32*(s: Stream): int32 =
@@ -636,7 +637,7 @@ proc readInt32*(s: Stream): int32 =
doAssert strm.readInt32() == 2'i32
doAssertRaises(IOError): discard strm.readInt32()
strm.close()
result = int32(0)
read(s, result)
proc peekInt32*(s: Stream): int32 =
@@ -657,7 +658,7 @@ proc peekInt32*(s: Stream): int32 =
doAssert strm.readInt32() == 1'i32
doAssert strm.peekInt32() == 2'i32
strm.close()
result = int32(0)
peek(s, result)
proc readInt64*(s: Stream): int64 =
@@ -676,7 +677,7 @@ proc readInt64*(s: Stream): int64 =
doAssert strm.readInt64() == 2'i64
doAssertRaises(IOError): discard strm.readInt64()
strm.close()
result = int64(0)
read(s, result)
proc peekInt64*(s: Stream): int64 =
@@ -697,7 +698,7 @@ proc peekInt64*(s: Stream): int64 =
doAssert strm.readInt64() == 1'i64
doAssert strm.peekInt64() == 2'i64
strm.close()
result = int64(0)
peek(s, result)
proc readUint8*(s: Stream): uint8 =
@@ -716,7 +717,7 @@ proc readUint8*(s: Stream): uint8 =
doAssert strm.readUint8() == 2'u8
doAssertRaises(IOError): discard strm.readUint8()
strm.close()
result = uint8(0)
read(s, result)
proc peekUint8*(s: Stream): uint8 =
@@ -737,7 +738,7 @@ proc peekUint8*(s: Stream): uint8 =
doAssert strm.readUint8() == 1'u8
doAssert strm.peekUint8() == 2'u8
strm.close()
result = uint8(0)
peek(s, result)
proc readUint16*(s: Stream): uint16 =
@@ -756,7 +757,7 @@ proc readUint16*(s: Stream): uint16 =
doAssert strm.readUint16() == 2'u16
doAssertRaises(IOError): discard strm.readUint16()
strm.close()
result = uint16(0)
read(s, result)
proc peekUint16*(s: Stream): uint16 =
@@ -777,7 +778,7 @@ proc peekUint16*(s: Stream): uint16 =
doAssert strm.readUint16() == 1'u16
doAssert strm.peekUint16() == 2'u16
strm.close()
result = uint16(0)
peek(s, result)
proc readUint32*(s: Stream): uint32 =
@@ -797,7 +798,7 @@ proc readUint32*(s: Stream): uint32 =
doAssert strm.readUint32() == 2'u32
doAssertRaises(IOError): discard strm.readUint32()
strm.close()
result = uint32(0)
read(s, result)
proc peekUint32*(s: Stream): uint32 =
@@ -818,7 +819,7 @@ proc peekUint32*(s: Stream): uint32 =
doAssert strm.readUint32() == 1'u32
doAssert strm.peekUint32() == 2'u32
strm.close()
result = uint32(0)
peek(s, result)
proc readUint64*(s: Stream): uint64 =
@@ -837,7 +838,7 @@ proc readUint64*(s: Stream): uint64 =
doAssert strm.readUint64() == 2'u64
doAssertRaises(IOError): discard strm.readUint64()
strm.close()
result = uint64(0)
read(s, result)
proc peekUint64*(s: Stream): uint64 =
@@ -858,7 +859,7 @@ proc peekUint64*(s: Stream): uint64 =
doAssert strm.readUint64() == 1'u64
doAssert strm.peekUint64() == 2'u64
strm.close()
result = uint64(0)
peek(s, result)
proc readFloat32*(s: Stream): float32 =
@@ -877,7 +878,7 @@ proc readFloat32*(s: Stream): float32 =
doAssert strm.readFloat32() == 2'f32
doAssertRaises(IOError): discard strm.readFloat32()
strm.close()
result = 0.0
read(s, result)
proc peekFloat32*(s: Stream): float32 =
@@ -898,7 +899,7 @@ proc peekFloat32*(s: Stream): float32 =
doAssert strm.readFloat32() == 1'f32
doAssert strm.peekFloat32() == 2'f32
strm.close()
result = 0.0
peek(s, result)
proc readFloat64*(s: Stream): float64 =
@@ -917,7 +918,7 @@ proc readFloat64*(s: Stream): float64 =
doAssert strm.readFloat64() == 2'f64
doAssertRaises(IOError): discard strm.readFloat64()
strm.close()
result = 0.0
read(s, result)
proc peekFloat64*(s: Stream): float64 =
@@ -938,7 +939,7 @@ proc peekFloat64*(s: Stream): float64 =
doAssert strm.readFloat64() == 1'f64
doAssert strm.peekFloat64() == 2'f64
strm.close()
result = 0.0
peek(s, result)
proc readStrPrivate(s: Stream, length: int, str: var string) =
@@ -1139,7 +1140,7 @@ iterator lines*(s: Stream): string =
doAssert lines == @["The first line", "the second line", "the third line"]
strm.close()
var line: string
var line: string = ""
while s.readLine(line):
yield line
@@ -1436,8 +1437,9 @@ proc newFileStream*(filename: string, mode: FileMode = fmRead,
## the third line
removeFile("somefile.txt")
var f: File
var f: File = default(File)
if open(f, filename, mode, bufSize): result = newFileStream(f)
else: result = nil
proc openFileStream*(filename: string, mode: FileMode = fmRead,
bufSize: int = -1): owned FileStream =
@@ -1467,7 +1469,7 @@ proc openFileStream*(filename: string, mode: FileMode = fmRead,
except:
stderr.write getCurrentExceptionMsg()
var f: File
var f: File = default(File)
if open(f, filename, mode, bufSize):
return newFileStream(f)
else:

View File

@@ -440,9 +440,7 @@ proc parseStandardFormatSpecifier*(s: string; start = 0;
## should support the standard format specifiers. If `ignoreUnknownSuffix` is true,
## an unknown suffix after the `type` field is not an error.
const alignChars = {'<', '>', '^'}
result.fill = ' '
result.align = '\0'
result.sign = '-'
result = StandardFormatSpecifier(fill: ' ', align: '\0', sign: '-')
var i = start
if i + 1 < s.len and s[i+1] in alignChars:
result.fill = s[i]
@@ -707,7 +705,7 @@ proc strformatImpl(f: string; openChar, closeChar: char,
if i == f.len:
missingCloseChar
var x: NimNode
var x: NimNode = nil
try:
x = parseExpr(subexpr)
except ValueError as e:

View File

@@ -486,7 +486,7 @@ macro scanTuple*(input: untyped; pattern: static[string]; matcherTypes: varargs[
var
p = 0
userMatches = 0
arguments: seq[NimNode]
arguments: seq[NimNode] = @[]
result = newStmtList()
template addVar(typ: string) =
let varIdent = ident("temp" & $arguments.len)
@@ -531,7 +531,7 @@ template hasNxt*(input: string; idx: int): bool = idx < input.len
#template prepare*(input: string): int = 0
template success*(x: int): bool = x != 0
template nxt*(input: string; idx, step: int = 1) = inc(idx, step)
template nxt*(input: string; idx: int; step: int = 1) = inc(idx, step)
macro scanp*(input, idx: typed; pattern: varargs[untyped]): bool =
## See top level documentation of this module about how ``scanp`` works.

View File

@@ -1643,6 +1643,7 @@ func startsWith*(s, prefix: string): bool {.rtl, extern: "nsuStartsWith".} =
let a = "abracadabra"
doAssert a.startsWith("abra") == true
doAssert a.startsWith("bra") == false
result = false
startsWithImpl(s, prefix)
func endsWith*(s: string, suffix: char): bool {.inline.} =
@@ -1671,6 +1672,7 @@ func endsWith*(s, suffix: string): bool {.rtl, extern: "nsuEndsWith".} =
let a = "abracadabra"
doAssert a.endsWith("abra") == true
doAssert a.endsWith("dab") == false
result = false
endsWithImpl(s, suffix)
func continuesWith*(s, substr: string, start: Natural): bool {.rtl,
@@ -1687,6 +1689,7 @@ func continuesWith*(s, substr: string, start: Natural): bool {.rtl,
doAssert a.continuesWith("ca", 4) == true
doAssert a.continuesWith("ca", 5) == false
doAssert a.continuesWith("dab", 6) == true
result = false
var i = 0
while true:
if i >= substr.len: return true
@@ -2340,7 +2343,7 @@ func insertSep*(s: string, sep = '_', digits = 3): string {.rtl,
doAssert insertSep("1000000") == "1_000_000"
result = newStringOfCap(s.len)
let hasPrefix = isDigit(s[s.low]) == false
var idx: int
var idx: int = 0
if hasPrefix:
result.add s[s.low]
for i in (s.low + 1)..s.high:
@@ -2445,7 +2448,7 @@ func validIdentifier*(s: string): bool {.rtl, extern: "nsuValidIdentifier".} =
## and is followed by any number of characters of the set `IdentChars`.
runnableExamples:
doAssert "abc_def08".validIdentifier
result = false
if s.len > 0 and s[0] in IdentStartChars:
for i in 1..s.len-1:
if s[i] notin IdentChars: return false

View File

@@ -451,6 +451,7 @@ proc normalize[T: Duration|Time](seconds, nanoseconds: int64): T =
## Normalize a (seconds, nanoseconds) pair and return it as either
## a `Duration` or `Time`. A normalized `Duration|Time` has a
## positive nanosecond part in the range `NanosecondRange`.
result = default(T)
result.seconds = seconds + convert(Nanoseconds, Seconds, nanoseconds)
var nanosecond = nanoseconds mod convert(Seconds, Nanoseconds, 1)
if nanosecond < 0:
@@ -913,8 +914,7 @@ proc abs*(a: Duration): Duration =
proc initTime*(unix: int64, nanosecond: NanosecondRange): Time =
## Create a `Time <#Time>`_ from a unix timestamp and a nanosecond part.
result.seconds = unix
result.nanosecond = nanosecond
result = Time(seconds: unix, nanosecond: nanosecond)
proc nanosecond*(time: Time): NanosecondRange =
## Get the fractional part of a `Time` as the number
@@ -973,7 +973,7 @@ proc toWinTime*(t: Time): int64 =
result = t.seconds * rateDiff + epochDiff + t.nanosecond div 100
proc getTimeImpl(typ: typedesc[Time]): Time =
discard "implemented in the vm"
raiseAssert "implemented in the vm"
proc getTime*(): Time {.tags: [TimeEffect], benign.} =
## Gets the current time as a `Time` with up to nanosecond resolution.
@@ -1249,6 +1249,7 @@ proc zonedTimeFromAdjTime*(zone: Timezone, adjTime: Time): ZonedTime =
proc `$`*(zone: Timezone): string =
## Returns the name of the timezone.
if zone != nil: result = zone.name
else: result = ""
proc `==`*(zone1, zone2: Timezone): bool =
## Two `Timezone`'s are considered equal if their name is equal.
@@ -1338,9 +1339,7 @@ else:
proc localZonedTimeFromTime(time: Time): ZonedTime {.benign.} =
let (offset, dst) = getLocalOffsetAndDst(time.seconds)
result.time = time
result.utcOffset = offset
result.isDst = dst
result = ZonedTime(time: time, utcOffset: offset, isDst: dst)
proc localZonedTimeFromAdjTime(adjTime: Time): ZonedTime {.benign.} =
var adjUnix = adjTime.seconds
@@ -1672,6 +1671,8 @@ proc parseInt(s: string, b: var int, start = 0, maxLen = int.high,
return 0
b = b * sign
result = i - start
else:
result = 0
iterator tokens(f: string): tuple[kind: FormatTokenKind, token: string] =
var i = 0
@@ -1768,8 +1769,7 @@ proc initTimeFormat*(format: string): TimeFormat =
runnableExamples:
let f = initTimeFormat("yyyy-MM-dd")
doAssert "2000-01-01" == "2000-01-01".parse(f).format(f)
result.formatStr = format
result.patterns = @[]
result = TimeFormat(formatStr: format, patterns: @[])
for kind, token in format.tokens:
case kind
of tkLiteral:
@@ -2368,29 +2368,33 @@ proc initTimeInterval*(nanoseconds, microseconds, milliseconds,
let dt = dateTime(2000, mJan, 01, 12, 00, 00, 00, utc())
doAssert $(dt + day) == "2000-01-02T12:00:00Z"
doAssert initTimeInterval(hours = 24) != initTimeInterval(days = 1)
result.nanoseconds = nanoseconds
result.microseconds = microseconds
result.milliseconds = milliseconds
result.seconds = seconds
result.minutes = minutes
result.hours = hours
result.days = days
result.weeks = weeks
result.months = months
result.years = years
result = TimeInterval(
nanoseconds: nanoseconds,
microseconds: microseconds,
milliseconds: milliseconds,
seconds: seconds,
minutes: minutes,
hours: hours,
days: days,
weeks: weeks,
months: months,
years: years
)
proc `+`*(ti1, ti2: TimeInterval): TimeInterval =
## Adds two `TimeInterval` objects together.
result.nanoseconds = ti1.nanoseconds + ti2.nanoseconds
result.microseconds = ti1.microseconds + ti2.microseconds
result.milliseconds = ti1.milliseconds + ti2.milliseconds
result.seconds = ti1.seconds + ti2.seconds
result.minutes = ti1.minutes + ti2.minutes
result.hours = ti1.hours + ti2.hours
result.days = ti1.days + ti2.days
result.weeks = ti1.weeks + ti2.weeks
result.months = ti1.months + ti2.months
result.years = ti1.years + ti2.years
result = TimeInterval(
nanoseconds: ti1.nanoseconds + ti2.nanoseconds,
microseconds: ti1.microseconds + ti2.microseconds,
milliseconds: ti1.milliseconds + ti2.milliseconds,
seconds: ti1.seconds + ti2.seconds,
minutes: ti1.minutes + ti2.minutes,
hours: ti1.hours + ti2.hours,
days: ti1.days + ti2.days,
weeks: ti1.weeks + ti2.weeks,
months: ti1.months + ti2.months,
years: ti1.years + ti2.years
)
proc `-`*(ti: TimeInterval): TimeInterval =
## Reverses a time interval
@@ -2457,6 +2461,7 @@ proc between*(startDt, endDt: DateTime): TimeInterval =
doAssert between(a, b) == ti
doAssert between(a, b) == -between(b, a)
result = default(TimeInterval)
if startDt.timezone != endDt.timezone:
return between(startDt.utc, endDt.utc)
elif endDt < startDt:
@@ -2556,7 +2561,7 @@ proc toParts*(ti: TimeInterval): TimeIntervalParts =
var tp = toParts(initTimeInterval(years = 1, nanoseconds = 123))
doAssert tp[Years] == 1
doAssert tp[Nanoseconds] == 123
result = default(TimeIntervalParts)
var index = 0
for name, value in fieldPairs(ti):
result[index.TimeUnit()] = value

View File

@@ -336,7 +336,7 @@ since (1, 1):
genericParamsImpl(T2)
proc hasClosureImpl(n: NimNode): bool = discard "see compiler/vmops.nim"
proc hasClosureImpl(n: NimNode): bool = raiseAssert "see compiler/vmops.nim"
proc hasClosure*(fn: NimNode): bool {.since: (1, 5, 1).} =
## Returns true if the func/proc/etc `fn` has `closure`.

View File

@@ -545,6 +545,8 @@ proc isLower*(c: Rune): bool {.rtl, extern: "nuc$1".} =
p = binarySearch(c, toUpperSinglets, len(toUpperSinglets) div 2, 2)
if p >= 0 and c == toUpperSinglets[p]:
return true
else:
return false
proc isUpper*(c: Rune): bool {.rtl, extern: "nuc$1".} =
## Returns true if ``c`` is a upper case rune.
@@ -565,6 +567,8 @@ proc isUpper*(c: Rune): bool {.rtl, extern: "nuc$1".} =
p = binarySearch(c, toLowerSinglets, len(toLowerSinglets) div 2, 2)
if p >= 0 and c == toLowerSinglets[p]:
return true
else:
return false
proc isAlpha*(c: Rune): bool {.rtl, extern: "nuc$1".} =
## Returns true if ``c`` is an *alpha* rune (i.e., a letter).
@@ -584,6 +588,8 @@ proc isAlpha*(c: Rune): bool {.rtl, extern: "nuc$1".} =
p = binarySearch(c, alphaSinglets, len(alphaSinglets), 1)
if p >= 0 and c == alphaSinglets[p]:
return true
else:
return false
proc isTitle*(c: Rune): bool {.rtl, extern: "nuc$1".} =
## Returns true if ``c`` is a Unicode titlecase code point.
@@ -608,6 +614,8 @@ proc isWhiteSpace*(c: Rune): bool {.rtl, extern: "nuc$1".} =
var p = binarySearch(c, spaceRanges, len(spaceRanges) div 2, 2)
if p >= 0 and c >= spaceRanges[p] and c <= spaceRanges[p+1]:
return true
else:
return false
proc isCombining*(c: Rune): bool {.rtl, extern: "nuc$1".} =
## Returns true if ``c`` is a Unicode combining code unit.
@@ -898,7 +906,7 @@ proc graphemeLen*(s: openArray[char]; i: Natural): Natural =
doAssert a.graphemeLen(1) == 2 ## ñ
doAssert a.graphemeLen(2) == 1
doAssert a.graphemeLen(4) == 2 ## ó
result = 0
var j = i.int
var r, r2: Rune
if j < s.len:

View File

@@ -146,6 +146,7 @@ func encodeQuery*(query: openArray[(string, string)], usePlus = true,
assert encodeQuery({"a": "1", "b": "2"}) == "a=1&b=2"
assert encodeQuery({"a": "1", "b": ""}) == "a=1&b"
assert encodeQuery({"a": "1", "b": ""}, omitEq = false, sep = ';') == "a=1;b="
result = ""
for elem in query:
# Encode the `key = value` pairs and separate them with 'sep'
if result.len > 0: result.add(sep)

View File

@@ -49,6 +49,7 @@ proc untilElementEnd(x: var XmlParser, result: XmlNode,
result.addNode(parse(x, errors))
proc parse(x: var XmlParser, errors: var seq[string]): XmlNode =
result = nil
case x.kind
of xmlComment:
result = newComment(x.charData)
@@ -105,7 +106,8 @@ proc parseXml*(s: Stream, filename: string,
errors: var seq[string], options: set[XmlParseOption] = {reportComments}): XmlNode =
## Parses the XML from stream ``s`` and returns a ``XmlNode``. Every
## occurred parsing error is added to the ``errors`` sequence.
var x: XmlParser
result = nil
var x: XmlParser = default(XmlParser)
open(x, s, filename, options)
while true:
x.next()

View File

@@ -514,6 +514,7 @@ proc len*(n: XmlNode): int {.inline.} =
f.insert(newElement("second"), 0)
assert len(f) == 2
if n.k == xnElement: result = len(n.s)
else: result = 0
proc kind*(n: XmlNode): XmlNodeKind {.inline.} =
## Returns `n`'s kind.
@@ -663,6 +664,7 @@ proc attrsLen*(n: XmlNode): int {.inline.} =
n.expect xnElement
if not isNil(n.fAttr): result = len(n.fAttr)
else: result = 0
proc attr*(n: XmlNode, name: string): string =
## Finds the first attribute of `n` with a name of `name`.
@@ -734,6 +736,7 @@ proc addIndent(result: var string, indent: int, addNewLines: bool) =
proc addImpl(result: var string, n: XmlNode, indent = 0, indWidth = 2,
addNewLines = true, lastNodeIsText = false) =
proc noWhitespace(n: XmlNode): bool =
result = false
for i in 0 ..< n.len:
if n[i].kind in {xnText, xnVerbatimText, xnEntity}: return true
@@ -841,7 +844,7 @@ proc child*(n: XmlNode, name: string): XmlNode =
f.add newElement("secondSon")
f.add newElement("thirdSon")
assert $(f.child("secondSon")) == "<secondSon />"
result = nil
n.expect xnElement
for i in items(n):
if i.kind == xnElement:

View File

@@ -111,3 +111,5 @@ func find*(s, sub: cstring, start: Natural = 0, last = 0): int =
result = cast[int](found) -% cast[int](s)
else:
result = -1
else:
result = 0