diff options
author | rumpf_a@web.de <> | 2010-01-31 14:33:33 +0100 |
---|---|---|
committer | rumpf_a@web.de <> | 2010-01-31 14:33:33 +0100 |
commit | e22c73fd893447cc59dd854e9680626ed7da01b2 (patch) | |
tree | f287376afd1cad6e2aa573053e0e8f3e586262eb /lib/pure/strutils.nim | |
parent | 262a47887d2578c2eb0c2196ea3191b6a088209f (diff) | |
download | Nim-e22c73fd893447cc59dd854e9680626ed7da01b2.tar.gz |
parseutils added
Diffstat (limited to 'lib/pure/strutils.nim')
-rwxr-xr-x | lib/pure/strutils.nim | 123 |
1 files changed, 9 insertions, 114 deletions
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 292810538..fe70130e5 100755 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -10,6 +10,8 @@ ## This module contains various string utility routines. ## See the module `regexprs` for regular expression support. +import parseutils + {.deadCodeElim: on.} {.push debugger:off .} # the user does not want to trace a part @@ -440,7 +442,7 @@ proc findNormalized(x: string, inArray: openarray[string]): int = while i < high(inArray): if cmpIgnoreStyle(x, inArray[i]) == 0: return i inc(i, 2) # incrementing by 1 would probably result in a - # security whole ... + # security hole ... return -1 proc addf(s: var string, formatstr: string, a: openarray[string]) = @@ -686,56 +688,13 @@ proc toHex(x: BiggestInt, len: int): string = result[j] = HexChars[toU32(x shr shift) and 0xF'i32] shift = shift + 4 -{.push overflowChecks: on.} -# this must be compiled with overflow checking turned on: -proc rawParseInt(s: string, index: var int): BiggestInt = - # index contains the start position at proc entry; end position will be - # an index before the proc returns; index = -1 on error (no number at all) - # the problem here is that integers have an asymmetrical range: there is - # one more valid negative than prositive integer. Thus we perform the - # computation as a negative number and then change the sign at the end. - var - i = index # a local i is more efficient than accessing a var parameter - sign: BiggestInt = -1 - if s[i] == '+': - inc(i) - elif s[i] == '-': - inc(i) - sign = 1 - if s[i] in {'0'..'9'}: - result = 0 - while s[i] in {'0'..'9'}: - result = result * 10 - (ord(s[i]) - ord('0')) - inc(i) - while s[i] == '_': - inc(i) # underscores are allowed and ignored - result = result * sign - if s[i] == '\0': - index = i # store index back - else: - index = -1 # BUGFIX: error! - else: - index = -1 - -{.pop.} # overflowChecks - proc parseInt(s: string): int = - var - index = 0 - res = rawParseInt(s, index) - if index == -1: - raise newException(EInvalidValue, "invalid integer: " & s) - elif (sizeof(int) <= 4) and - ((res < low(int)) or (res > high(int))): - raise newException(EOverflow, "overflow") - else: - result = int(res) # convert to smaller integer type + var L = parseutils.parseInt(s, result, 0) + if L != s.len: raise newException(EInvalidValue, "invalid integer: " & s) proc ParseBiggestInt(s: string): biggestInt = - var index = 0 - result = rawParseInt(s, index) - if index == -1: - raise newException(EInvalidValue, "invalid integer: " & s) + var L = parseutils.parseBiggestInt(s, result, 0) + if L != s.len: raise newException(EInvalidValue, "invalid integer: " & s) proc ParseOctInt*(s: string): int = var i = 0 @@ -769,72 +728,8 @@ proc ParseHexInt(s: string): int = else: raise newException(EInvalidValue, "invalid integer: " & s) proc ParseFloat(s: string): float = - var - esign = 1.0 - sign = 1.0 - i = 0 - exponent: int - flags: int - result = 0.0 - if s[i] == '+': inc(i) - elif s[i] == '-': - sign = -1.0 - inc(i) - if s[i] == 'N' or s[i] == 'n': - if s[i+1] == 'A' or s[i+1] == 'a': - if s[i+2] == 'N' or s[i+2] == 'n': - if s[i+3] == '\0': return NaN - raise newException(EInvalidValue, "invalid float: " & s) - if s[i] == 'I' or s[i] == 'i': - if s[i+1] == 'N' or s[i+1] == 'n': - if s[i+2] == 'F' or s[i+2] == 'f': - if s[i+3] == '\0': return Inf*sign - raise newException(EInvalidValue, "invalid float: " & s) - while s[i] in {'0'..'9'}: - # Read integer part - flags = flags or 1 - result = result * 10.0 + toFloat(ord(s[i]) - ord('0')) - inc(i) - while s[i] == '_': inc(i) - # Decimal? - if s[i] == '.': - var hd = 1.0 - inc(i) - while s[i] in {'0'..'9'}: - # Read fractional part - flags = flags or 2 - result = result * 10.0 + toFloat(ord(s[i]) - ord('0')) - hd = hd * 10.0 - inc(i) - while s[i] == '_': inc(i) - result = result / hd # this complicated way preserves precision - # Again, read integer and fractional part - if flags == 0: - raise newException(EInvalidValue, "invalid float: " & s) - # Exponent? - if s[i] in {'e', 'E'}: - inc(i) - if s[i] == '+': - inc(i) - elif s[i] == '-': - esign = -1.0 - inc(i) - if s[i] notin {'0'..'9'}: - raise newException(EInvalidValue, "invalid float: " & s) - while s[i] in {'0'..'9'}: - exponent = exponent * 10 + ord(s[i]) - ord('0') - inc(i) - while s[i] == '_': inc(i) - # Calculate Exponent - var hd = 1.0 - for j in 1..exponent: - hd = hd * 10.0 - if esign > 0.0: result = result * hd - else: result = result / hd - # Not all characters are read? - if s[i] != '\0': raise newException(EInvalidValue, "invalid float: " & s) - # evaluate sign - result = result * sign + var L = parseutils.parseFloat(s, result, 0) + if L != s.len: raise newException(EInvalidValue, "invalid float: " & s) proc toOct*(x: BiggestInt, len: int): string = ## converts `x` into its octal representation. The resulting string is |