fix(skipPrefixes): fix erroneous strip of 0b in hex numbers (#120)

* fix(skipPrefixes): fix erroneous strip of 0b in hex numbers

* refactor(skipPrefixes): normalize radix checks

* feat(stint): add tests for bin, oct, hex string conversions

* fix(stint): fix cast

* fix(stint): fix typo

* fix(stint): alternative format

* feat(stint): add test

* fix(stint): fix stint width in test
This commit is contained in:
G 2022-10-03 12:15:45 +02:00 committed by GitHub
parent d1acb42743
commit f36623998f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 85 additions and 18 deletions

View File

@ -218,17 +218,20 @@ func skipPrefixes(current_idx: var int, str: string, radix: range[2..16]) {.inli
doAssert current_idx == 0, "skipPrefixes only works for prefixes (position 0 and 1 of the string)"
if str[0] == '0':
if str[1] in {'x', 'X'}:
if radix != 16:
if radix == 16:
current_idx = 2
else:
raise newException(ValueError,"Parsing mismatch, 0x prefix is only valid for a hexadecimal number (base 16)")
current_idx = 2
elif str[1] in {'o', 'O'}:
if radix != 8:
if radix == 8:
current_idx = 2
else:
raise newException(ValueError, "Parsing mismatch, 0o prefix is only valid for an octal number (base 8)")
current_idx = 2
elif str[1] in {'b', 'B'}:
if radix != 2:
raise newException(ValueError, "Parsing mismatch, 0b prefix is only valid for a binary number (base 2)")
current_idx = 2
if radix == 2:
current_idx = 2
elif radix != 16:
raise newException(ValueError, "Parsing mismatch, 0b prefix is only valid for a binary number (base 2) or as first byte of a hexadecimal number (base 16)")
func nextNonBlank(current_idx: var int, s: string) {.inline.} =
## Move the current index, skipping white spaces and "_" characters.

View File

@ -7,7 +7,7 @@
#
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import ../stint, unittest, strutils, math, test_helpers, tables
import ../stint, unittest, strutils, math, test_helpers, tables, std/strformat
template nativeStuint(chk, nint: untyped, bits: int) =
chk $(nint.stuint(bits)) == $(nint)
@ -1090,23 +1090,79 @@ proc main() =
check: a == b
check: -123456789'i64 == cast[int64](a)
test "Creation from binary strings":
block:
for i in 0..255:
let a = fmt("{i:#b}").parse(StInt[64], radix = 2)
let b = i.stint(64)
check: a == b
check: int64(i) == cast[int64](a)
block:
for i in 0..255:
let a = fmt("{i:#b}").parse(StUint[64], radix = 2)
let b = i.stuint(64)
check: a == b
check: uint64(i) == cast[uint64](a)
block:
let a = "0b1111111111111111".parse(StInt[16], 2)
let b = (-1'i16).stint(16)
check: a == b
check: -1'i16 == cast[int16](a)
test "Creation from octal strings":
block:
for i in 0..255:
let a = fmt("{i:#o}").parse(StInt[64], radix = 8)
let b = i.stint(64)
check: a == b
check: int64(i) == cast[int64](a)
block:
for i in 0..255:
let a = fmt("{i:#o}").parse(StUint[64], radix = 8)
let b = i.stuint(64)
check: a == b
check: uint64(i) == cast[uint64](a)
block:
let a = "0o177777".parse(StInt[16], 8)
let b = (-1'i16).stint(16)
check: a == b
check: -1'i16 == cast[int16](a)
test "Creation from hex strings":
block:
let a = "0xFF".parse(StInt[64], radix = 16)
let b = 255.stint(64)
for i in 0..255:
let a = fmt("{i:#x}").parse(StInt[64], radix = 16)
let aUppercase = fmt("{i:#X}").parse(StInt[64], radix = 16)
let b = i.stint(64)
check: a == b
check: 255'i64 == cast[int64](a)
check: a == aUppercase
check: a == b
check: int64(i) == cast[int64](a)
block:
let a = "0xFF".parse(StUint[64], radix = 16)
let b = 255.stuint(64)
for i in 0..255:
let a = fmt("{i:#x}").parse(StUint[64], radix = 16)
let aUppercase = fmt("{i:#X}").parse(StUint[64], radix = 16)
let b = i.stuint(64)
check: a == b
check: 255'u64 == cast[uint64](a)
check: a == aUppercase
check: a == b
check: uint64(i) == cast[uint64](a)
let a2 = hexToUint[64]("0xFF")
check: a == a2
let a2 = hexToUint[64](fmt("{i:#x}"))
let a3 = hexToUint[64](fmt("{i:#X}"))
check: a == a2
check: a == a3
block:
let a = "0xFFFF".parse(StInt[16], 16)
@ -1115,6 +1171,14 @@ proc main() =
check: a == b
check: -1'i16 == cast[int16](a)
block:
let a = "0b1234abcdef".parse(StInt[64], 16)
let b = "0x0b1234abcdef".parse(StInt[64], 16)
let c = 0x0b1234abcdef.stint(64)
check: a == b
check: a == c
test "Conversion to decimal strings":
block:
let a = 1234567891234567890.stint(128)