diff --git a/changelog.md b/changelog.md index 76da277edb..cf2d4cb170 100644 --- a/changelog.md +++ b/changelog.md @@ -23,6 +23,8 @@ errors. - With `-d:nimPreviewCStringComparisons`, comparsions (`<`, `>`, `<=`, `>=`) between cstrings switch from reference semantics to value semantics like `==` and `!=`. +- `std/parsesql` has been moved to a nimble package, use `nimble` or `atlas` to install it. + ## Standard library additions and changes [//]: # "Additions:" diff --git a/compiler/ast.nim b/compiler/ast.nim index d1d2d127a0..d80589c087 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -819,6 +819,7 @@ type # nodes are compared by structure! counter*: int data*: TNodePairSeq + ignoreTypes*: bool TObjectSeq* = seq[RootRef] TObjectSet* = object @@ -1641,8 +1642,8 @@ proc initObjectSet*(): TObjectSet = result = TObjectSet(counter: 0) newSeq(result.data, StartSize) -proc initNodeTable*(): TNodeTable = - result = TNodeTable(counter: 0) +proc initNodeTable*(ignoreTypes=false): TNodeTable = + result = TNodeTable(counter: 0, ignoreTypes: ignoreTypes) newSeq(result.data, StartSize) proc skipTypes*(t: PType, kinds: TTypeKinds; maxIters: int): PType = diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 4ca34b9d74..d3e215ea56 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -981,7 +981,11 @@ proc genAddr(p: BProc, e: PNode, d: var TLoc) = var a: TLoc = initLocExpr(p, e[0]) if e[0].kind in {nkHiddenStdConv, nkHiddenSubConv, nkConv} and not ignoreConv(e[0]): # addr (conv x) introduces a temp because `conv x` is not a rvalue - putIntoDest(p, d, e, addrLoc(p.config, expressionsNeedsTmp(p, a)), a.storage) + # transform addr ( conv ( x ) ) -> conv ( addr ( x ) ) + var exprLoc: TLoc = initLocExpr(p, e[0][1]) + var tmp = getTemp(p, e.typ, needsInit=false) + putIntoDest(p, tmp, e, cCast(getTypeDesc(p.module, e.typ), addrLoc(p.config, exprLoc))) + putIntoDest(p, d, e, rdLoc(tmp)) else: putIntoDest(p, d, e, addrLoc(p.config, a), a.storage) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 65d216b831..7707d1a248 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -379,7 +379,9 @@ proc useVar(a: PEffects, n: PNode) = # If the variable is explicitly marked as .noinit. do not emit any error a.init.add s.id elif s.id notin a.init: - if s.typ.requiresInit: + if s.kind == skResult and tfRequiresInit in s.typ.flags: + localError(a.config, n.info, "'result' requires explicit initialization") + elif s.typ.requiresInit: message(a.config, n.info, warnProveInit, s.name.s) elif a.leftPartOfAsgn <= 0: if strictDefs in a.c.features: diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index ce8b59f9cd..6c8542b584 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -725,7 +725,7 @@ template isLocalSym(sym: PSym): bool = sym.typ.kind == tyTypeDesc or sfCompileTime in sym.flags) or sym.kind in {skProc, skFunc, skIterator} and - sfGlobal notin sym.flags + sfGlobal notin sym.flags and sym.typ.callConv == ccClosure proc usesLocalVar(n: PNode): bool = case n.kind diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 42efcd2399..9d660a3bec 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -1147,7 +1147,9 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType = let t = newTypeS(tySink, c, result) result = t else: discard - if result.kind == tyRef and c.config.selectedGC in {gcArc, gcOrc, gcAtomicArc}: + if result.kind == tyRef and + c.config.selectedGC in {gcArc, gcOrc, gcAtomicArc} and + tfTriggersCompileTime notin result.flags: result.flags.incl tfHasAsgn proc findEnforcedStaticType(t: PType): PType = diff --git a/compiler/transf.nim b/compiler/transf.nim index 0ed2e10e82..197e073477 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -259,7 +259,8 @@ proc transformBlock(c: PTransf, n: PNode): PNode = var labl: PSym if c.inlining > 0: labl = newLabel(c, n[0]) - c.transCon.mapping[n[0].sym.itemId] = newSymNode(labl) + if n[0].kind != nkEmpty: + c.transCon.mapping[n[0].sym.itemId] = newSymNode(labl) else: labl = if n[0].kind != nkEmpty: @@ -827,12 +828,20 @@ proc transformFor(c: PTransf, n: PNode): PNode = t = formal.ast.typ # better use the type that actually has a destructor. elif t.destructor == nil and arg.typ.destructor != nil: t = arg.typ - # generate a temporary and produce an assignment statement: - var temp = newTemp(c, t, formal.info) - #incl(temp.sym.flags, sfCursor) - addVar(v, temp) - stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, arg, true)) - newC.mapping[formal.itemId] = temp + + if arg.kind in {nkDerefExpr, nkHiddenDeref}: + # optimizes for `[]` # bug #24093 + var temp = newTemp(c, arg[0].typ, formal.info) + addVar(v, temp) + stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, arg[0], true)) + newC.mapping[formal.itemId] = newDeref(temp) + else: + # generate a temporary and produce an assignment statement: + var temp = newTemp(c, t, formal.info) + #incl(temp.sym.flags, sfCursor) + addVar(v, temp) + stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, arg, true)) + newC.mapping[formal.itemId] = temp of paVarAsgn: assert(skipTypes(formal.typ, abstractInst).kind in {tyVar, tyLent}) newC.mapping[formal.itemId] = arg diff --git a/compiler/treetab.nim b/compiler/treetab.nim index 6685c4a899..1fd539f0f2 100644 --- a/compiler/treetab.nim +++ b/compiler/treetab.nim @@ -42,32 +42,37 @@ proc hashTree*(n: PNode): Hash = #echo "hashTree ", result #echo n -proc treesEquivalent(a, b: PNode): bool = +proc treesEquivalent(a, b: PNode; ignoreTypes: bool): bool = if a == b: result = true elif (a != nil) and (b != nil) and (a.kind == b.kind): case a.kind - of nkEmpty, nkNilLit, nkType: result = true + of nkEmpty: result = true of nkSym: result = a.sym.id == b.sym.id of nkIdent: result = a.ident.id == b.ident.id of nkCharLit..nkUInt64Lit: result = a.intVal == b.intVal - of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal + of nkFloatLit..nkFloat64Lit: + result = cast[uint64](a.floatVal) == cast[uint64](b.floatVal) + #result = a.floatVal == b.floatVal of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal + of nkType, nkNilLit: + result = a.typ == b.typ else: if a.len == b.len: for i in 0..= 0: @@ -1182,8 +1189,10 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}, m: TMag of mEqF64: genBinaryABC(c, n, dest, opcEqFloat) of mLeF64: genBinaryABC(c, n, dest, opcLeFloat) of mLtF64: genBinaryABC(c, n, dest, opcLtFloat) - of mLePtr, mLeU: genBinaryABC(c, n, dest, opcLeu) - of mLtPtr, mLtU: genBinaryABC(c, n, dest, opcLtu) + of mLeU: genBinaryABC(c, n, dest, opcLeu) + of mLtU: genBinaryABC(c, n, dest, opcLtu) + of mLePtr, mLtPtr: + globalError(c.config, n.info, "pointer comparisons are not available at compile-time") of mEqProc, mEqRef: genBinaryABC(c, n, dest, opcEqRef) of mXor: genBinaryABC(c, n, dest, opcXor) @@ -1547,8 +1556,7 @@ template cannotEval(c: PCtx; n: PNode) = if c.config.cmd == cmdCheck and c.config.m.errorOutputs != {}: # nim check command with no error outputs doesn't need to cascade here, # includes `tryConstExpr` case which should not continue generating code - localError(c.config, n.info, "cannot evaluate at compile time: " & - n.renderTree) + localError(c.config, n.info, "cannot evaluate at compile time: " & n.renderTree) c.cannotEval = true return globalError(c.config, n.info, "cannot evaluate at compile time: " & @@ -1886,7 +1894,7 @@ proc genCheckedObjAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) = c.freeTemp(objR) proc genArrAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) = - if n[0].typ == nil: + if n[0].typ == nil: globalError(c.config, n.info, "cannot access array with nil type") return diff --git a/doc/manual.md b/doc/manual.md index 9abd0e762c..29006a7536 100644 --- a/doc/manual.md +++ b/doc/manual.md @@ -4062,7 +4062,7 @@ notation. (Thus an operator can have more than two parameters): # Multiply and add result = a * b + c - assert `*+`(3, 4, 6) == `+`(`*`(a, b), c) + assert `*+`(3, 4, 6) == `+`(`*`(3, 4), 6) ``` diff --git a/doc/nimc.md b/doc/nimc.md index 1bc3edc4cf..24a2b3afe1 100644 --- a/doc/nimc.md +++ b/doc/nimc.md @@ -224,6 +224,8 @@ directories (in this order; later files overwrite previous settings): command-line option. +[NimScript files](nims.html) can also be used for configuration. + Command-line settings have priority over configuration file settings. The default build of a project is a `debug build`:idx:. To compile a diff --git a/koch.nim b/koch.nim index dbca93a0d4..48cd2cdcb2 100644 --- a/koch.nim +++ b/koch.nim @@ -13,7 +13,7 @@ const # examples of possible values for repos: Head, ea82b54 NimbleStableCommit = "9207e8b2bbdf66b5a4d1020214cff44d2d30df92" # 0.20.1 AtlasStableCommit = "26cecf4d0cc038d5422fc1aa737eec9c8803a82b" # 0.9 - ChecksumsStableCommit = "f8f6bd34bfa3fe12c64b919059ad856a96efcba0" # 2.0.1 + ChecksumsStableCommit = "0b8e46379c5bc1bf73d8b3011908389c60fb9b98" # 2.0.1 SatStableCommit = "faf1617f44d7632ee9601ebc13887644925dcc01" NimonyStableCommit = "1dbabac403ae32e185ee4c29f006d04e04b50c6d" # unversioned \ diff --git a/lib/pure/asyncfile.nim b/lib/pure/asyncfile.nim index 3825904781..3a57845c22 100644 --- a/lib/pure/asyncfile.nim +++ b/lib/pure/asyncfile.nim @@ -428,7 +428,7 @@ proc write*(f: AsyncFile, data: string): Future[void] = dealloc buffer buffer = nil ) - ol.offset = DWORD(f.offset and 0xffffffff) + ol.offset = cast[DWORD](f.offset and 0xffffffff) ol.offsetHigh = DWORD(f.offset shr 32) f.offset.inc(data.len) diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim index 42d54c8392..3dba087aa8 100644 --- a/lib/pure/collections/sequtils.nim +++ b/lib/pure/collections/sequtils.nim @@ -116,6 +116,11 @@ macro evalOnceAs(expAlias, exp: untyped, newProc(name = genSym(nskTemplate, $expAlias), params = [getType(untyped)], body = val, procType = nnkTemplateDef)) +template unCheckedInc(x) = + {.push overflowChecks: off.} + inc(x) + {.pop.} + func concat*[T](seqs: varargs[seq[T]]): seq[T] = ## Takes several sequences' items and returns them inside a new sequence. ## All sequences must be of the same type. @@ -139,7 +144,7 @@ func concat*[T](seqs: varargs[seq[T]]): seq[T] = for s in items(seqs): for itm in items(s): result[i] = itm - inc(i) + unCheckedInc(i) func addUnique*[T](s: var seq[T], x: sink T) = ## Adds `x` to the container `s` if it is not already present. @@ -170,7 +175,7 @@ func count*[T](s: openArray[T], x: T): int = result = 0 for itm in items(s): if itm == x: - inc result + unCheckedInc result func cycle*[T](s: openArray[T], n: Natural): seq[T] = ## Returns a new sequence with the items of the container `s` repeated @@ -188,7 +193,7 @@ func cycle*[T](s: openArray[T], n: Natural): seq[T] = for x in 0 ..< n: for e in s: result[o] = e - inc o + unCheckedInc o proc repeat*[T](x: T, n: Natural): seq[T] = ## Returns a new sequence with the item `x` repeated `n` times. @@ -321,6 +326,26 @@ func minmax*[T](x: openArray[T], cmp: proc(a, b: T): int): (T, T) {.effectsOf: c elif cmp(result[1], x[i]) < 0: result[1] = x[i] +template findIt*(s, predicate: untyped): int = + ## Iterates through a container and returns the index of the first item that + ## fulfills the predicate, or -1 + ## + ## Unlike the `find`, the predicate needs to be an expression using + ## the `it` variable for testing, like: `findIt([3, 2, 1], it == 2)`. + var + res = -1 + i = 0 + + # We must use items here since both `find` and `anyIt` are defined in terms + # of `items` + # (and not `pairs`) + for it {.inject.} in items(s): + if predicate: + res = i + break + unCheckedInc(i) + res + template zipImpl(s1, s2, retType: untyped): untyped = proc zip*[S, T](s1: openArray[S], s2: openArray[T]): retType = ## Returns a new sequence with a combination of the two input containers. @@ -417,7 +442,7 @@ func distribute*[T](s: seq[T], num: Positive, spread = true): seq[seq[T]] = if extra == 0 or spread == false: # Use an algorithm which overcounts the stride and minimizes reading limits. - if extra > 0: inc(stride) + if extra > 0: unCheckedInc(stride) for i in 0 ..< num: result[i] = newSeq[T]() for g in first ..< min(s.len, first + stride): @@ -429,7 +454,7 @@ func distribute*[T](s: seq[T], num: Positive, spread = true): seq[seq[T]] = last = first + stride if extra > 0: extra -= 1 - inc(last) + unCheckedInc(last) result[i] = newSeq[T]() for g in first ..< last: result[i].add(s[g]) @@ -586,7 +611,7 @@ proc keepIf*[T](s: var seq[T], pred: proc(x: T): bool {.closure.}) s[pos] = move(s[i]) else: shallowCopy(s[pos], s[i]) - inc(pos) + unCheckedInc(pos) setLen(s, pos) func delete*[T](s: var seq[T]; slice: Slice[int]) = @@ -617,8 +642,8 @@ func delete*[T](s: var seq[T]; slice: Slice[int]) = s[i] = move(s[j]) else: s[i].shallowCopy(s[j]) - inc(i) - inc(j) + unCheckedInc(i) + unCheckedInc(j) setLen(s, newLen) when nimvm: defaultImpl() else: @@ -649,8 +674,8 @@ func delete*[T](s: var seq[T]; first, last: Natural) {.deprecated: "use `delete( s[i] = move(s[j]) else: s[i].shallowCopy(s[j]) - inc(i) - inc(j) + unCheckedInc(i) + unCheckedInc(j) setLen(s, newLen) func insert*[T](dest: var seq[T], src: openArray[T], pos = 0) = @@ -681,10 +706,10 @@ func insert*[T](dest: var seq[T], src: openArray[T], pos = 0) = dec(i) dec(j) # Insert items from `dest` into `dest` at `pos` - inc(j) + unCheckedInc(j) for item in src: dest[j] = item - inc(j) + unCheckedInc(j) template filterIt*(s, pred: untyped): untyped = @@ -715,7 +740,7 @@ template filterIt*(s, pred: untyped): untyped = var result = newSeq[typeof(s[0])]() for it {.inject.} in items(s): if pred: result.add(it) - result + move result template keepItIf*(varSeq: seq, pred: untyped) = ## Keeps the items in the passed sequence (must be declared as a `var`) @@ -743,7 +768,7 @@ template keepItIf*(varSeq: seq, pred: untyped) = varSeq[pos] = move(varSeq[i]) else: shallowCopy(varSeq[pos], varSeq[i]) - inc(pos) + unCheckedInc(pos) setLen(varSeq, pos) since (1, 1): @@ -842,12 +867,7 @@ template anyIt*(s, pred: untyped): bool = assert numbers.anyIt(it > 8) == true assert numbers.anyIt(it > 9) == false - var result = false - for it {.inject.} in items(s): - if pred: - result = true - break - result + findIt(s, pred) != -1 template toSeq1(s: not iterator): untyped = # overload for typed but not iterator @@ -875,7 +895,7 @@ template toSeq2(iter: iterator): untyped = var result = newSeq[typeof(iter2)](iter2.len) for x in iter2: result[i] = x - inc i + unCheckedInc i result else: type OutType = typeof(iter2()) @@ -920,7 +940,7 @@ template toSeq*(iter: untyped): untyped = var i = 0 for x in iter2: result[i] = x - inc i + unCheckedInc i result else: var result: seq[typeof(iter)] = @[] diff --git a/lib/pure/parsesql.nim b/lib/pure/parsesql.nim index 7bc6fcdcee..c02b6dddc6 100644 --- a/lib/pure/parsesql.nim +++ b/lib/pure/parsesql.nim @@ -12,6 +12,8 @@ ## ## Unstable API. +{.deprecated: "use `nimble install parsesql` and import `pkg/parsesql` instead".} + import std/[strutils, lexbase] import std/private/decode_helpers diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index c218ac1c53..1a5d4d5d6f 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -74,6 +74,7 @@ import std/parseutils from std/math import pow, floor, log10 from std/algorithm import fill, reverse import std/enumutils +from std/bitops import fastLog2 from std/unicode import toLower, toUpper export toLower, toUpper @@ -2639,37 +2640,35 @@ func formatSize*(bytes: int64, ## * `strformat module`_ for string interpolation and formatting runnableExamples: doAssert formatSize((1'i64 shl 31) + (300'i64 shl 20)) == "2.293GiB" - doAssert formatSize((2.234*1024*1024).int) == "2.234MiB" + doAssert formatSize((2.234*1024*1024).int) == "2.233MiB" doAssert formatSize(4096, includeSpace = true) == "4 KiB" doAssert formatSize(4096, prefix = bpColloquial, includeSpace = true) == "4 kB" doAssert formatSize(4096) == "4KiB" - doAssert formatSize(5_378_934, prefix = bpColloquial, decimalSep = ',') == "5,13MB" + doAssert formatSize(5_378_934, prefix = bpColloquial, decimalSep = ',') == "5,129MB" - const iecPrefixes = ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi"] - const collPrefixes = ["", "k", "M", "G", "T", "P", "E", "Z", "Y"] - var - xb: int64 = bytes - fbytes: float - lastXb: int64 = bytes - matchedIndex = 0 - prefixes: array[9, string] + # It doesn't needs Zi and larger units until we use int72 or larger ints. + const iecPrefixes = ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei"] + const collPrefixes = ["", "k", "M", "G", "T", "P", "E"] + + let lg2 = if bytes == 0: + 0 + else: + when hasWorkingInt64: + fastLog2(bytes) + else: + fastLog2(int32 bytes) + let matchedIndex = lg2 div 10 + # Lower bits that are smaller than 0.001 when `bytes` is converted to a real number and added prefix, are discard. + # Then it is converted to float with round down. + let discardBits = (lg2 div 10 - 1) * 10 + + var prefixes: array[7, string] if prefix == bpColloquial: prefixes = collPrefixes else: prefixes = iecPrefixes - # Iterate through prefixes seeing if value will be greater than - # 0 in each case - for index in 1.. 8) == true doAssert any(anumbers, proc (x: int): bool = return x > 9) == false +block: # findIt + let + numbers = @[1, 4, 5, 8, 9, 7, 4] + anumbers = [1, 4, 5, 8, 9, 7, 4] + len0seq: seq[int] = @[] + doAssert findIt(numbers, it == 4) == 1 + doAssert findIt(numbers, it > 9) == -1 + doAssert findIt(len0seq, true) == -1 + doAssert findIt(anumbers, it > 8) == 4 + doAssert findIt(anumbers, it > 9) == -1 + block: # anyIt let numbers = @[1, 4, 5, 8, 9, 7, 4] diff --git a/tests/stdlib/tstrutils.nim b/tests/stdlib/tstrutils.nim index db9fb80c44..dfa72faf22 100644 --- a/tests/stdlib/tstrutils.nim +++ b/tests/stdlib/tstrutils.nim @@ -789,12 +789,71 @@ bar block: # formatSize disableVm: when hasWorkingInt64: + doAssert formatSize(1024'i64 * 1024 * 1024 * 2 - 1) == "1.999GiB" + doAssert formatSize(1024'i64 * 1024 * 1024 * 2) == "2GiB" doAssert formatSize((1'i64 shl 31) + (300'i64 shl 20)) == "2.293GiB" # <=== bug #8231 - doAssert formatSize((2.234*1024*1024).int) == "2.234MiB" + doAssert formatSize(int64.high) == "7.999EiB" + doAssert formatSize(int64.high div 2 + 1) == "4EiB" + doAssert formatSize(int64.high div 2) == "3.999EiB" + doAssert formatSize(int64.high div 4 + 1) == "2EiB" + doAssert formatSize(int64.high div 4) == "1.999EiB" + doAssert formatSize(int64.high div 8 + 1) == "1EiB" + doAssert formatSize(int64.high div 8) == "1023.999PiB" + doAssert formatSize(int64.high div 16 + 1) == "512PiB" + doAssert formatSize(int64.high div 16) == "511.999PiB" + doAssert formatSize(0) == "0B" + doAssert formatSize(0, includeSpace = true) == "0 B" + doAssert formatSize(1) == "1B" + doAssert formatSize(2) == "2B" + doAssert formatSize(1022) == "1022B" + doAssert formatSize(1023) == "1023B" + doAssert formatSize(1024) == "1KiB" + doAssert formatSize(1025) == "1.001KiB" + doAssert formatSize(1026) == "1.002KiB" + doAssert formatSize(1024 * 2 - 2) == "1.998KiB" + doAssert formatSize(1024 * 2 - 1) == "1.999KiB" + doAssert formatSize(1024 * 2) == "2KiB" + doAssert formatSize(1024 * 2 + 1) == "2.001KiB" + doAssert formatSize(1024 * 2 + 2) == "2.002KiB" + doAssert formatSize(4096 - 1) == "3.999KiB" doAssert formatSize(4096) == "4KiB" + doAssert formatSize(4096 + 1) == "4.001KiB" + doAssert formatSize(1024 * 512 - 1) == "511.999KiB" + doAssert formatSize(1024 * 512) == "512KiB" + doAssert formatSize(1024 * 512 + 1) == "512.001KiB" + doAssert formatSize(1024 * 1024 - 2) == "1023.998KiB" + doAssert formatSize(1024 * 1024 - 1) == "1023.999KiB" + doAssert formatSize(1024 * 1024) == "1MiB" + doAssert formatSize(1024 * 1024 + 1) == "1MiB" + doAssert formatSize(1024 * 1024 + 1023) == "1MiB" + doAssert formatSize(1024 * 1024 + 1024) == "1.001MiB" + doAssert formatSize(1024 * 1024 + 1024 * 2) == "1.002MiB" + doAssert formatSize(1024 * 1024 * 2 - 1) == "1.999MiB" + doAssert formatSize(1024 * 1024 * 2) == "2MiB" + doAssert formatSize(1024 * 1024 * 2 + 1) == "2MiB" + doAssert formatSize(1024 * 1024 * 2 + 1024) == "2.001MiB" + doAssert formatSize(1024 * 1024 * 2 + 1024 * 2) == "2.002MiB" + doAssert formatSize(1024 * 1024 * 4 - 1) == "3.999MiB" + doAssert formatSize(1024 * 1024 * 4) == "4MiB" + doAssert formatSize(1024 * (1024 * 4 + 1)) == "4.001MiB" + doAssert formatSize(1024 * 1024 * 512 - 1025) == "511.998MiB" + doAssert formatSize(1024 * 1024 * 512 - 1) == "511.999MiB" + doAssert formatSize(1024 * 1024 * 512) == "512MiB" + doAssert formatSize(1024 * 1024 * 512 + 1) == "512MiB" + doAssert formatSize(1024 * 1024 * 512 + 1024) == "512.001MiB" + doAssert formatSize(1024 * 1024 * 512 + 1024 * 2) == "512.002MiB" + doAssert formatSize(1024 * 1024 * 1024 - 1) == "1023.999MiB" + doAssert formatSize(1024 * 1024 * 1024) == "1GiB" + doAssert formatSize(1024 * 1024 * 1024 + 1) == "1GiB" + doAssert formatSize(1024 * 1024 * 1025) == "1.001GiB" + doAssert formatSize(1024 * 1024 * 1026) == "1.002GiB" + # != 2.234MiB as (2.234 * 1024 * 1024).int.float / (1024 * 1024) = 2.23399... + # and formatSize round down the value + doAssert formatSize((2.234*1024*1024).int) == "2.233MiB" doAssert formatSize(4096, prefix = bpColloquial, includeSpace = true) == "4 kB" doAssert formatSize(4096, includeSpace = true) == "4 KiB" - doAssert formatSize(5_378_934, prefix = bpColloquial, decimalSep = ',') == "5,13MB" + # (5378934).float / (1024 * 1024) = 5.12975... + doAssert formatSize(5_378_934, prefix = bpColloquial, decimalSep = ',') == "5,129MB" block: # formatEng disableVm: diff --git a/tools/debug/nim-gdb.py b/tools/debug/nim-gdb.py index 59e6ee99ce..2637481aee 100644 --- a/tools/debug/nim-gdb.py +++ b/tools/debug/nim-gdb.py @@ -4,6 +4,18 @@ import re import sys import traceback +# Add compatibility for older GDB versions +if not hasattr(gdb, 'SYMBOL_FUNCTION_DOMAIN'): + gdb.SYMBOL_FUNCTION_DOMAIN = 0 # This is the value used in newer GDB versions + +# Configure demangling for Itanium C++ ABI (which Nim uses) +try: + gdb.execute("set demangle-style gnu-v3") # GNU v3 style handles Itanium mangling + gdb.execute("set print asm-demangle on") + gdb.execute("set print demangle on") +except Exception as e: + gdb.write(f"Warning: Could not configure demangling: {str(e)}\n", gdb.STDERR) + # some feedback that the nim runtime support is loading, isn't a bad # thing at all. gdb.write("Loading Nim Runtime support.\n", gdb.STDERR) @@ -70,12 +82,12 @@ class NimTypeRecognizer: type_map_static = { 'NI': 'system.int', 'NI8': 'int8', 'NI16': 'int16', 'NI32': 'int32', 'NI64': 'int64', - + 'NU': 'uint', 'NU8': 'uint8','NU16': 'uint16', 'NU32': 'uint32', 'NU64': 'uint64', - + 'NF': 'float', 'NF32': 'float32', 'NF64': 'float64', - + 'NIM_BOOL': 'bool', 'NIM_CHAR': 'char', 'NCSTRING': 'cstring', 'NimStringDesc': 'string', 'NimStringV2': 'string' @@ -556,7 +568,7 @@ class NimSeqPrinter: except RuntimeError: inaccessible = True yield "data[{0}]".format(i), "inaccessible" - + ################################################################################ class NimArrayPrinter: