* 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:
parent
cd65ef0056
commit
e80be6173d
4 changed files with 111 additions and 53 deletions
|
|
@ -47,12 +47,14 @@ proc parseHex*(s: string, number: var int, start = 0; maxLen = 0): int {.
|
|||
## discard parseHex("0x38", value)
|
||||
## assert value == -200
|
||||
##
|
||||
## If 'maxLen==0' the length of the hexadecimal number has no
|
||||
## upper bound. Not more than ```maxLen`` characters are parsed.
|
||||
## If ``maxLen == 0`` the length of the hexadecimal number has no upper bound.
|
||||
## Else no more than ``start + maxLen`` characters are parsed, up to the
|
||||
## length of the string.
|
||||
var i = start
|
||||
var foundDigit = false
|
||||
let last = if maxLen == 0: s.len else: i+maxLen
|
||||
if i+1 < last and s[i] == '0' and (s[i+1] == 'x' or s[i+1] == 'X'): inc(i, 2)
|
||||
# get last index based on minimum `start + maxLen` or `s.len`
|
||||
let last = min(s.len, if maxLen == 0: s.len else: i+maxLen)
|
||||
if i+1 < last and s[i] == '0' and (s[i+1] in {'x', 'X'}): inc(i, 2)
|
||||
elif i < last and s[i] == '#': inc(i)
|
||||
while i < last:
|
||||
case s[i]
|
||||
|
|
@ -70,14 +72,20 @@ proc parseHex*(s: string, number: var int, start = 0; maxLen = 0): int {.
|
|||
inc(i)
|
||||
if foundDigit: result = i-start
|
||||
|
||||
proc parseOct*(s: string, number: var int, start = 0): int {.
|
||||
proc parseOct*(s: string, number: var int, start = 0, maxLen = 0): int {.
|
||||
rtl, extern: "npuParseOct", noSideEffect.} =
|
||||
## parses an octal number and stores its value in ``number``. Returns
|
||||
## Parses an octal number and stores its value in ``number``. Returns
|
||||
## the number of the parsed characters or 0 in case of an error.
|
||||
##
|
||||
## If ``maxLen == 0`` the length of the octal number has no upper bound.
|
||||
## Else no more than ``start + maxLen`` characters are parsed, up to the
|
||||
## length of the string.
|
||||
var i = start
|
||||
var foundDigit = false
|
||||
if i+1 < s.len and s[i] == '0' and (s[i+1] == 'o' or s[i+1] == 'O'): inc(i, 2)
|
||||
while i < s.len:
|
||||
# get last index based on minimum `start + maxLen` or `s.len`
|
||||
let last = min(s.len, if maxLen == 0: s.len else: i+maxLen)
|
||||
if i+1 < last and s[i] == '0' and (s[i+1] in {'o', 'O'}): inc(i, 2)
|
||||
while i < last:
|
||||
case s[i]
|
||||
of '_': discard
|
||||
of '0'..'7':
|
||||
|
|
@ -87,14 +95,20 @@ proc parseOct*(s: string, number: var int, start = 0): int {.
|
|||
inc(i)
|
||||
if foundDigit: result = i-start
|
||||
|
||||
proc parseBin*(s: string, number: var int, start = 0): int {.
|
||||
proc parseBin*(s: string, number: var int, start = 0, maxLen = 0): int {.
|
||||
rtl, extern: "npuParseBin", noSideEffect.} =
|
||||
## parses an binary number and stores its value in ``number``. Returns
|
||||
## Parses an binary number and stores its value in ``number``. Returns
|
||||
## the number of the parsed characters or 0 in case of an error.
|
||||
##
|
||||
## If ``maxLen == 0`` the length of the binary number has no upper bound.
|
||||
## Else no more than ``start + maxLen`` characters are parsed, up to the
|
||||
## length of the string.
|
||||
var i = start
|
||||
var foundDigit = false
|
||||
if i+1 < s.len and s[i] == '0' and (s[i+1] == 'b' or s[i+1] == 'B'): inc(i, 2)
|
||||
while i < s.len:
|
||||
# get last index based on minimum `start + maxLen` or `s.len`
|
||||
let last = min(s.len, if maxLen == 0: s.len else: i+maxLen)
|
||||
if i+1 < last and s[i] == '0' and (s[i+1] in {'b', 'B'}): inc(i, 2)
|
||||
while i < last:
|
||||
case s[i]
|
||||
of '_': discard
|
||||
of '0'..'1':
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue