strconv: cleanup variable declarations in ParseUint

Move variable declarations closer to their first uses.

Use an additional string variable s0 for error reporting that references
the original input string. This allows the variable s to be modified.

Change-Id: I4725152490ca1dc10c1161ad8ad2f4ae8933493f
Reviewed-on: https://go-review.googlesource.com/55138
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Reviewed-by: Marvin Stenger <marvin.stenger94@gmail.com>
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Martin Möhrmann 2017-08-13 13:00:33 +02:00
parent 365594ad59
commit de7e5d45df
1 changed files with 26 additions and 26 deletions

View File

@ -46,18 +46,16 @@ const maxUint64 = (1<<64 - 1)
func ParseUint(s string, base int, bitSize int) (uint64, error) {
const fnParseUint = "ParseUint"
var n uint64
var cutoff, maxVal uint64
if bitSize == 0 {
bitSize = int(IntSize)
}
i := 0
switch {
case len(s) == 0:
if len(s) == 0 {
return 0, syntaxError(fnParseUint, s)
}
s0 := s
switch {
case 2 <= base && base <= 36:
// valid base; nothing to do
@ -66,23 +64,24 @@ func ParseUint(s string, base int, bitSize int) (uint64, error) {
switch {
case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
if len(s) < 3 {
return 0, syntaxError(fnParseUint, s)
return 0, syntaxError(fnParseUint, s0)
}
base = 16
i = 2
s = s[2:]
case s[0] == '0':
base = 8
i = 1
s = s[1:]
default:
base = 10
}
default:
return 0, baseError(fnParseUint, s, base)
return 0, baseError(fnParseUint, s0, base)
}
// Cutoff is the smallest number such that cutoff*base > maxUint64.
// Use compile-time constants for common cases.
var cutoff uint64
switch base {
case 10:
cutoff = maxUint64/10 + 1
@ -92,35 +91,36 @@ func ParseUint(s string, base int, bitSize int) (uint64, error) {
cutoff = maxUint64/uint64(base) + 1
}
maxVal = 1<<uint(bitSize) - 1
maxVal := uint64(1)<<uint(bitSize) - 1
for ; i < len(s); i++ {
var v byte
d := s[i]
var n uint64
for _, c := range []byte(s) {
var d byte
switch {
case '0' <= d && d <= '9':
v = d - '0'
case 'a' <= d && d <= 'z':
v = d - 'a' + 10
case 'A' <= d && d <= 'Z':
v = d - 'A' + 10
case '0' <= c && c <= '9':
d = c - '0'
case 'a' <= c && c <= 'z':
d = c - 'a' + 10
case 'A' <= c && c <= 'Z':
d = c - 'A' + 10
default:
return 0, syntaxError(fnParseUint, s)
return 0, syntaxError(fnParseUint, s0)
}
if v >= byte(base) {
return 0, syntaxError(fnParseUint, s)
if d >= byte(base) {
return 0, syntaxError(fnParseUint, s0)
}
if n >= cutoff {
// n*base overflows
return maxVal, rangeError(fnParseUint, s)
return maxVal, rangeError(fnParseUint, s0)
}
n *= uint64(base)
n1 := n + uint64(v)
n1 := n + uint64(d)
if n1 < n || n1 > maxVal {
// n+v overflows
return maxVal, rangeError(fnParseUint, s)
return maxVal, rangeError(fnParseUint, s0)
}
n = n1
}