Commit de7e5d45 authored by Martin Möhrmann's avatar Martin Möhrmann

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/55138Reviewed-by: 's avatarJoe Tsai <thebrokentoaster@gmail.com>
Reviewed-by: 's avatarMarvin Stenger <marvin.stenger94@gmail.com>
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 365594ad
......@@ -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
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment