Add parse bin int, fixes #8018 (#8020)

* clarify `parseHexInt`, `parseOctInt` docstring and exception msgs

* add `parseBinInt` based on `parseutil.parseBin` implementation

Adds a `parseBinInt`, which parses a binary integer string and returns
it as an integer. This is based on the implementation of
`parseutil.parseBin`, removing the unnecessary parts.

* add tests for all `parse(Hex|Oct|Bin)Int` procs

* replace `parse*Int` proc impls by call to parseutil procs

Replaces the `parse(Hex|Oct|Bin)Int` procedure implementation by calls
to the `parseutil` procs, which receive a mutable argument.

Has the main advantage that the empty string as well as a "prefix
only" string, e.g. "0x" counts as an invalid integer.

Also moves the `parseOctInt` proc further up in the file so that all
`parse` procs are below one another.

* replace `var L` by `let L` in `parse` procs

There's no reason for the usage of `var` here.

* add `maxLen` optional arg for `parseutil.parse(Oct|Bin)`

Plus small change to test cases.

* update changelog about `parse*Int` procs

* fix `rejectParse` template in `tstrutils`

* make sure only `s.len` chars are parsed, if `maxLen+start` > s.len

Fixes a previous bug in `parseHex` (and now affected `parseOct` and
`parseBin`), which allowed to set `start + maxLen` to be larger than
the strings length. This resulted in an out of bounds access.

* move `parse*Int` proc change to breaking changes, add double `
This commit is contained in:
Vindaar 2018-06-13 19:32:12 +02:00 • committed by Varriount
commit e80be6173d
4 changed files with 111 additions and 53 deletions

View file

@ -7,6 +7,14 @@ discard """
import
strutils
import macros
template rejectParse(e) =
try:
discard e
raise newException(AssertionError, "This was supposed to fail: $#!" % astToStr(e))
except ValueError: discard
proc testStrip() =
write(stdout, strip(" ha "))
@ -148,7 +156,6 @@ proc testDelete =
delete(s, 0, 0)
assert s == "1236789ABCDEFG"
proc testIsAlphaNumeric =
assert isAlphaNumeric("abcdABC1234") == true
assert isAlphaNumeric("a") == true
@ -203,10 +210,50 @@ proc testCountLines =
assertCountLines("\nabc\n123")
assertCountLines("\nabc\n123\n")
proc testParseInts =
# binary
assert "0b1111".parseBinInt == 15
assert "0B1111".parseBinInt == 15
assert "1111".parseBinInt == 15
assert "1110".parseBinInt == 14
assert "1_1_1_1".parseBinInt == 15
assert "0b1_1_1_1".parseBinInt == 15
rejectParse "".parseBinInt
rejectParse "_".parseBinInt
rejectParse "0b".parseBinInt
rejectParse "0b1234".parseBinInt
# hex
assert "0x72".parseHexInt == 114
assert "0X72".parseHexInt == 114
assert "#72".parseHexInt == 114
assert "72".parseHexInt == 114
assert "FF".parseHexInt == 255
assert "ff".parseHexInt == 255
assert "fF".parseHexInt == 255
assert "0x7_2".parseHexInt == 114
rejectParse "".parseHexInt
rejectParse "_".parseHexInt
rejectParse "0x".parseHexInt
rejectParse "0xFFG".parseHexInt
rejectParse "reject".parseHexInt
# octal
assert "0o17".parseOctInt == 15
assert "0O17".parseOctInt == 15
assert "17".parseOctInt == 15
assert "10".parseOctInt == 8
assert "0o1_0_0".parseOctInt == 64
rejectParse "".parseOctInt
rejectParse "_".parseOctInt
rejectParse "0o".parseOctInt
rejectParse "9".parseOctInt
rejectParse "0o9".parseOctInt
rejectParse "reject".parseOctInt
testDelete()
testFind()
testRFind()
testCountLines()
testParseInts()
assert(insertSep($1000_000) == "1_000_000")
assert(insertSep($232) == "232")