aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/strconv
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2018-01-09 01:23:08 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-01-09 01:23:08 +0000
commit1a2f01efa63036a5104f203a4789e682c0e0915d (patch)
tree373e15778dc8295354584e1f86915ae493b604ff /libgo/go/strconv
parent8799df67f2dab88f9fda11739c501780a85575e2 (diff)
downloadgcc-1a2f01efa63036a5104f203a4789e682c0e0915d.zip
gcc-1a2f01efa63036a5104f203a4789e682c0e0915d.tar.gz
gcc-1a2f01efa63036a5104f203a4789e682c0e0915d.tar.bz2
libgo: update to Go1.10beta1
Update the Go library to the 1.10beta1 release. Requires a few changes to the compiler for modifications to the map runtime code, and to handle some nowritebarrier cases in the runtime. Reviewed-on: https://go-review.googlesource.com/86455 gotools/: * Makefile.am (go_cmd_vet_files): New variable. (go_cmd_buildid_files, go_cmd_test2json_files): New variables. (s-zdefaultcc): Change from constants to functions. (noinst_PROGRAMS): Add vet, buildid, and test2json. (cgo$(EXEEXT)): Link against $(LIBGOTOOL). (vet$(EXEEXT)): New target. (buildid$(EXEEXT)): New target. (test2json$(EXEEXT)): New target. (install-exec-local): Install all $(noinst_PROGRAMS). (uninstall-local): Uninstasll all $(noinst_PROGRAMS). (check-go-tool): Depend on $(noinst_PROGRAMS). Copy down objabi.go. (check-runtime): Depend on $(noinst_PROGRAMS). (check-cgo-test, check-carchive-test): Likewise. (check-vet): New target. (check): Depend on check-vet. Look at cmd_vet-testlog. (.PHONY): Add check-vet. * Makefile.in: Rebuild. From-SVN: r256365
Diffstat (limited to 'libgo/go/strconv')
-rw-r--r--libgo/go/strconv/atoi.go133
-rw-r--r--libgo/go/strconv/atoi_test.go363
-rw-r--r--libgo/go/strconv/export_test.go10
-rw-r--r--libgo/go/strconv/extfloat.go2
-rw-r--r--libgo/go/strconv/isprint.go65
-rw-r--r--libgo/go/strconv/quote.go2
6 files changed, 404 insertions, 171 deletions
diff --git a/libgo/go/strconv/atoi.go b/libgo/go/strconv/atoi.go
index 66df149..bebed04 100644
--- a/libgo/go/strconv/atoi.go
+++ b/libgo/go/strconv/atoi.go
@@ -16,7 +16,7 @@ var ErrSyntax = errors.New("invalid syntax")
type NumError struct {
Func string // the failing function (ParseBool, ParseInt, ParseUint, ParseFloat)
Num string // the input
- Err error // the reason the conversion failed (ErrRange, ErrSyntax)
+ Err error // the reason the conversion failed (e.g. ErrRange, ErrSyntax, etc.)
}
func (e *NumError) Error() string {
@@ -31,6 +31,14 @@ func rangeError(fn, str string) *NumError {
return &NumError{fn, str, ErrRange}
}
+func baseError(fn, str string, base int) *NumError {
+ return &NumError{fn, str, errors.New("invalid base " + Itoa(base))}
+}
+
+func bitSizeError(fn, str string, bitSize int) *NumError {
+ return &NumError{fn, str, errors.New("invalid bit size " + Itoa(bitSize))}
+}
+
const intSize = 32 << (^uint(0) >> 63)
// IntSize is the size in bits of an int or uint value.
@@ -40,20 +48,14 @@ const maxUint64 = (1<<64 - 1)
// ParseUint is like ParseInt but for unsigned numbers.
func ParseUint(s string, base int, bitSize int) (uint64, error) {
- var n uint64
- var err error
- var cutoff, maxVal uint64
+ const fnParseUint = "ParseUint"
- if bitSize == 0 {
- bitSize = int(IntSize)
+ if len(s) == 0 {
+ return 0, syntaxError(fnParseUint, s)
}
- i := 0
+ s0 := s
switch {
- case len(s) < 1:
- err = ErrSyntax
- goto Error
-
case 2 <= base && base <= 36:
// valid base; nothing to do
@@ -62,25 +64,30 @@ 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 {
- err = ErrSyntax
- goto Error
+ 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:
- err = errors.New("invalid base " + Itoa(base))
- goto Error
+ return 0, baseError(fnParseUint, s0, base)
+ }
+
+ if bitSize == 0 {
+ bitSize = int(IntSize)
+ } else if bitSize < 0 || bitSize > 64 {
+ return 0, bitSizeError(fnParseUint, s0, bitSize)
}
// 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
@@ -90,61 +97,54 @@ 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:
- n = 0
- err = ErrSyntax
- goto Error
+ return 0, syntaxError(fnParseUint, s0)
}
- if v >= byte(base) {
- n = 0
- err = ErrSyntax
- goto Error
+
+ if d >= byte(base) {
+ return 0, syntaxError(fnParseUint, s0)
}
if n >= cutoff {
// n*base overflows
- n = maxUint64
- err = ErrRange
- goto Error
+ return maxVal, rangeError(fnParseUint, s0)
}
n *= uint64(base)
- n1 := n + uint64(v)
+ n1 := n + uint64(d)
if n1 < n || n1 > maxVal {
// n+v overflows
- n = maxUint64
- err = ErrRange
- goto Error
+ return maxVal, rangeError(fnParseUint, s0)
}
n = n1
}
return n, nil
-
-Error:
- return n, &NumError{"ParseUint", s, err}
}
-// ParseInt interprets a string s in the given base (2 to 36) and
-// returns the corresponding value i. If base == 0, the base is
-// implied by the string's prefix: base 16 for "0x", base 8 for
-// "0", and base 10 otherwise.
+// ParseInt interprets a string s in the given base (0, 2 to 36) and
+// bit size (0 to 64) and returns the corresponding value i.
+//
+// If base == 0, the base is implied by the string's prefix:
+// base 16 for "0x", base 8 for "0", and base 10 otherwise.
+// For bases 1, below 0 or above 36 an error is returned.
//
// The bitSize argument specifies the integer type
// that the result must fit into. Bit sizes 0, 8, 16, 32, and 64
// correspond to int, int8, int16, int32, and int64.
+// For a bitSize below 0 or above 64 an error is returned.
//
// The errors that ParseInt returns have concrete type *NumError
// and include err.Num = s. If s is empty or contains invalid
@@ -156,10 +156,6 @@ Error:
func ParseInt(s string, base int, bitSize int) (i int64, err error) {
const fnParseInt = "ParseInt"
- if bitSize == 0 {
- bitSize = int(IntSize)
- }
-
// Empty string bad.
if len(s) == 0 {
return 0, syntaxError(fnParseInt, s)
@@ -183,6 +179,11 @@ func ParseInt(s string, base int, bitSize int) (i int64, err error) {
err.(*NumError).Num = s0
return 0, err
}
+
+ if bitSize == 0 {
+ bitSize = int(IntSize)
+ }
+
cutoff := uint64(1 << uint(bitSize-1))
if !neg && un >= cutoff {
return int64(cutoff - 1), rangeError(fnParseInt, s0)
@@ -200,6 +201,34 @@ func ParseInt(s string, base int, bitSize int) (i int64, err error) {
// Atoi returns the result of ParseInt(s, 10, 0) converted to type int.
func Atoi(s string) (int, error) {
const fnAtoi = "Atoi"
+
+ sLen := len(s)
+ if intSize == 32 && (0 < sLen && sLen < 10) ||
+ intSize == 64 && (0 < sLen && sLen < 19) {
+ // Fast path for small integers that fit int type.
+ s0 := s
+ if s[0] == '-' || s[0] == '+' {
+ s = s[1:]
+ if len(s) < 1 {
+ return 0, &NumError{fnAtoi, s0, ErrSyntax}
+ }
+ }
+
+ n := 0
+ for _, ch := range []byte(s) {
+ ch -= '0'
+ if ch > 9 {
+ return 0, &NumError{fnAtoi, s0, ErrSyntax}
+ }
+ n = n*10 + int(ch)
+ }
+ if s0[0] == '-' {
+ n = -n
+ }
+ return n, nil
+ }
+
+ // Slow path for invalid or big integers.
i64, err := ParseInt(s, 10, 0)
if nerr, ok := err.(*NumError); ok {
nerr.Func = fnAtoi
diff --git a/libgo/go/strconv/atoi_test.go b/libgo/go/strconv/atoi_test.go
index d608505..e2f505a 100644
--- a/libgo/go/strconv/atoi_test.go
+++ b/libgo/go/strconv/atoi_test.go
@@ -6,18 +6,19 @@ package strconv_test
import (
"errors"
+ "fmt"
"reflect"
. "strconv"
"testing"
)
-type atoui64Test struct {
+type parseUint64Test struct {
in string
out uint64
err error
}
-var atoui64tests = []atoui64Test{
+var parseUint64Tests = []parseUint64Test{
{"", 0, ErrSyntax},
{"0", 0, nil},
{"1", 1, nil},
@@ -30,38 +31,45 @@ var atoui64tests = []atoui64Test{
{"18446744073709551620", 1<<64 - 1, ErrRange},
}
-var btoui64tests = []atoui64Test{
- {"", 0, ErrSyntax},
- {"0", 0, nil},
- {"0x", 0, ErrSyntax},
- {"0X", 0, ErrSyntax},
- {"1", 1, nil},
- {"12345", 12345, nil},
- {"012345", 012345, nil},
- {"0x12345", 0x12345, nil},
- {"0X12345", 0x12345, nil},
- {"12345x", 0, ErrSyntax},
- {"0xabcdefg123", 0, ErrSyntax},
- {"123456789abc", 0, ErrSyntax},
- {"98765432100", 98765432100, nil},
- {"18446744073709551615", 1<<64 - 1, nil},
- {"18446744073709551616", 1<<64 - 1, ErrRange},
- {"18446744073709551620", 1<<64 - 1, ErrRange},
- {"0xFFFFFFFFFFFFFFFF", 1<<64 - 1, nil},
- {"0x10000000000000000", 1<<64 - 1, ErrRange},
- {"01777777777777777777777", 1<<64 - 1, nil},
- {"01777777777777777777778", 0, ErrSyntax},
- {"02000000000000000000000", 1<<64 - 1, ErrRange},
- {"0200000000000000000000", 1 << 61, nil},
+type parseUint64BaseTest struct {
+ in string
+ base int
+ out uint64
+ err error
+}
+
+var parseUint64BaseTests = []parseUint64BaseTest{
+ {"", 0, 0, ErrSyntax},
+ {"0", 0, 0, nil},
+ {"0x", 0, 0, ErrSyntax},
+ {"0X", 0, 0, ErrSyntax},
+ {"1", 0, 1, nil},
+ {"12345", 0, 12345, nil},
+ {"012345", 0, 012345, nil},
+ {"0x12345", 0, 0x12345, nil},
+ {"0X12345", 0, 0x12345, nil},
+ {"12345x", 0, 0, ErrSyntax},
+ {"0xabcdefg123", 0, 0, ErrSyntax},
+ {"123456789abc", 0, 0, ErrSyntax},
+ {"98765432100", 0, 98765432100, nil},
+ {"18446744073709551615", 0, 1<<64 - 1, nil},
+ {"18446744073709551616", 0, 1<<64 - 1, ErrRange},
+ {"18446744073709551620", 0, 1<<64 - 1, ErrRange},
+ {"0xFFFFFFFFFFFFFFFF", 0, 1<<64 - 1, nil},
+ {"0x10000000000000000", 0, 1<<64 - 1, ErrRange},
+ {"01777777777777777777777", 0, 1<<64 - 1, nil},
+ {"01777777777777777777778", 0, 0, ErrSyntax},
+ {"02000000000000000000000", 0, 1<<64 - 1, ErrRange},
+ {"0200000000000000000000", 0, 1 << 61, nil},
}
-type atoi64Test struct {
+type parseInt64Test struct {
in string
out int64
err error
}
-var atoi64tests = []atoi64Test{
+var parseInt64Tests = []parseInt64Test{
{"", 0, ErrSyntax},
{"0", 0, nil},
{"-0", 0, nil},
@@ -81,14 +89,14 @@ var atoi64tests = []atoi64Test{
{"-9223372036854775809", -1 << 63, ErrRange},
}
-type btoi64Test struct {
+type parseInt64BaseTest struct {
in string
base int
out int64
err error
}
-var btoi64tests = []btoi64Test{
+var parseInt64BaseTests = []parseInt64BaseTest{
{"", 0, 0, ErrSyntax},
{"0", 0, 0, nil},
{"-0", 0, 0, nil},
@@ -138,13 +146,13 @@ var btoi64tests = []btoi64Test{
{"7fffffffffffffff", 16, 1<<63 - 1, nil},
}
-type atoui32Test struct {
+type parseUint32Test struct {
in string
out uint32
err error
}
-var atoui32tests = []atoui32Test{
+var parseUint32Tests = []parseUint32Test{
{"", 0, ErrSyntax},
{"0", 0, nil},
{"1", 1, nil},
@@ -156,13 +164,13 @@ var atoui32tests = []atoui32Test{
{"4294967296", 1<<32 - 1, ErrRange},
}
-type atoi32Test struct {
+type parseInt32Test struct {
in string
out int32
err error
}
-var atoi32tests = []atoi32Test{
+var parseInt32Tests = []parseInt32Test{
{"", 0, ErrSyntax},
{"0", 0, nil},
{"-0", 0, nil},
@@ -195,86 +203,108 @@ var numErrorTests = []numErrorTest{
}
func init() {
- // The atoi routines return NumErrors wrapping
+ // The parse routines return NumErrors wrapping
// the error and the string. Convert the tables above.
- for i := range atoui64tests {
- test := &atoui64tests[i]
+ for i := range parseUint64Tests {
+ test := &parseUint64Tests[i]
if test.err != nil {
test.err = &NumError{"ParseUint", test.in, test.err}
}
}
- for i := range btoui64tests {
- test := &btoui64tests[i]
+ for i := range parseUint64BaseTests {
+ test := &parseUint64BaseTests[i]
if test.err != nil {
test.err = &NumError{"ParseUint", test.in, test.err}
}
}
- for i := range atoi64tests {
- test := &atoi64tests[i]
+ for i := range parseInt64Tests {
+ test := &parseInt64Tests[i]
if test.err != nil {
test.err = &NumError{"ParseInt", test.in, test.err}
}
}
- for i := range btoi64tests {
- test := &btoi64tests[i]
+ for i := range parseInt64BaseTests {
+ test := &parseInt64BaseTests[i]
if test.err != nil {
test.err = &NumError{"ParseInt", test.in, test.err}
}
}
- for i := range atoui32tests {
- test := &atoui32tests[i]
+ for i := range parseUint32Tests {
+ test := &parseUint32Tests[i]
if test.err != nil {
test.err = &NumError{"ParseUint", test.in, test.err}
}
}
- for i := range atoi32tests {
- test := &atoi32tests[i]
+ for i := range parseInt32Tests {
+ test := &parseInt32Tests[i]
if test.err != nil {
test.err = &NumError{"ParseInt", test.in, test.err}
}
}
}
+func TestParseUint32(t *testing.T) {
+ for i := range parseUint32Tests {
+ test := &parseUint32Tests[i]
+ out, err := ParseUint(test.in, 10, 32)
+ if uint64(test.out) != out || !reflect.DeepEqual(test.err, err) {
+ t.Errorf("ParseUint(%q, 10, 32) = %v, %v want %v, %v",
+ test.in, out, err, test.out, test.err)
+ }
+ }
+}
+
func TestParseUint64(t *testing.T) {
- for i := range atoui64tests {
- test := &atoui64tests[i]
+ for i := range parseUint64Tests {
+ test := &parseUint64Tests[i]
out, err := ParseUint(test.in, 10, 64)
if test.out != out || !reflect.DeepEqual(test.err, err) {
- t.Errorf("Atoui64(%q) = %v, %v want %v, %v",
+ t.Errorf("ParseUint(%q, 10, 64) = %v, %v want %v, %v",
test.in, out, err, test.out, test.err)
}
}
}
func TestParseUint64Base(t *testing.T) {
- for i := range btoui64tests {
- test := &btoui64tests[i]
- out, err := ParseUint(test.in, 0, 64)
+ for i := range parseUint64BaseTests {
+ test := &parseUint64BaseTests[i]
+ out, err := ParseUint(test.in, test.base, 64)
if test.out != out || !reflect.DeepEqual(test.err, err) {
- t.Errorf("ParseUint(%q) = %v, %v want %v, %v",
+ t.Errorf("ParseUint(%q, %v, 64) = %v, %v want %v, %v",
+ test.in, test.base, out, err, test.out, test.err)
+ }
+ }
+}
+
+func TestParseInt32(t *testing.T) {
+ for i := range parseInt32Tests {
+ test := &parseInt32Tests[i]
+ out, err := ParseInt(test.in, 10, 32)
+ if int64(test.out) != out || !reflect.DeepEqual(test.err, err) {
+ t.Errorf("ParseInt(%q, 10 ,32) = %v, %v want %v, %v",
test.in, out, err, test.out, test.err)
}
}
}
func TestParseInt64(t *testing.T) {
- for i := range atoi64tests {
- test := &atoi64tests[i]
+ for i := range parseInt64Tests {
+ test := &parseInt64Tests[i]
out, err := ParseInt(test.in, 10, 64)
if test.out != out || !reflect.DeepEqual(test.err, err) {
- t.Errorf("Atoi64(%q) = %v, %v want %v, %v",
+ t.Errorf("ParseInt(%q, 10, 64) = %v, %v want %v, %v",
test.in, out, err, test.out, test.err)
}
}
}
func TestParseInt64Base(t *testing.T) {
- for i := range btoi64tests {
- test := &btoi64tests[i]
+ for i := range parseInt64BaseTests {
+ test := &parseInt64BaseTests[i]
out, err := ParseInt(test.in, test.base, 64)
if test.out != out || !reflect.DeepEqual(test.err, err) {
- t.Errorf("ParseInt(%q) = %v, %v want %v, %v",
- test.in, out, err, test.out, test.err)
+ t.Errorf("ParseInt(%q, %v, 64) = %v, %v want %v, %v",
+ test.in, test.base, out, err, test.out, test.err)
}
}
}
@@ -282,20 +312,20 @@ func TestParseInt64Base(t *testing.T) {
func TestParseUint(t *testing.T) {
switch IntSize {
case 32:
- for i := range atoui32tests {
- test := &atoui32tests[i]
+ for i := range parseUint32Tests {
+ test := &parseUint32Tests[i]
out, err := ParseUint(test.in, 10, 0)
- if test.out != uint32(out) || !reflect.DeepEqual(test.err, err) {
- t.Errorf("Atoui(%q) = %v, %v want %v, %v",
+ if uint64(test.out) != out || !reflect.DeepEqual(test.err, err) {
+ t.Errorf("ParseUint(%q, 10, 0) = %v, %v want %v, %v",
test.in, out, err, test.out, test.err)
}
}
case 64:
- for i := range atoui64tests {
- test := &atoui64tests[i]
+ for i := range parseUint64Tests {
+ test := &parseUint64Tests[i]
out, err := ParseUint(test.in, 10, 0)
- if test.out != uint64(out) || !reflect.DeepEqual(test.err, err) {
- t.Errorf("Atoui(%q) = %v, %v want %v, %v",
+ if test.out != out || !reflect.DeepEqual(test.err, err) {
+ t.Errorf("ParseUint(%q, 10, 0) = %v, %v want %v, %v",
test.in, out, err, test.out, test.err)
}
}
@@ -305,26 +335,138 @@ func TestParseUint(t *testing.T) {
func TestParseInt(t *testing.T) {
switch IntSize {
case 32:
- for i := range atoi32tests {
- test := &atoi32tests[i]
+ for i := range parseInt32Tests {
+ test := &parseInt32Tests[i]
out, err := ParseInt(test.in, 10, 0)
- if test.out != int32(out) || !reflect.DeepEqual(test.err, err) {
- t.Errorf("Atoi(%q) = %v, %v want %v, %v",
+ if int64(test.out) != out || !reflect.DeepEqual(test.err, err) {
+ t.Errorf("ParseInt(%q, 10, 0) = %v, %v want %v, %v",
test.in, out, err, test.out, test.err)
}
}
case 64:
- for i := range atoi64tests {
- test := &atoi64tests[i]
+ for i := range parseInt64Tests {
+ test := &parseInt64Tests[i]
out, err := ParseInt(test.in, 10, 0)
- if test.out != int64(out) || !reflect.DeepEqual(test.err, err) {
- t.Errorf("Atoi(%q) = %v, %v want %v, %v",
+ if test.out != out || !reflect.DeepEqual(test.err, err) {
+ t.Errorf("ParseInt(%q, 10, 0) = %v, %v want %v, %v",
test.in, out, err, test.out, test.err)
}
}
}
}
+func TestAtoi(t *testing.T) {
+ switch IntSize {
+ case 32:
+ for i := range parseInt32Tests {
+ test := &parseInt32Tests[i]
+ out, err := Atoi(test.in)
+ var testErr error
+ if test.err != nil {
+ testErr = &NumError{"Atoi", test.in, test.err.(*NumError).Err}
+ }
+ if int(test.out) != out || !reflect.DeepEqual(testErr, err) {
+ t.Errorf("Atoi(%q) = %v, %v want %v, %v",
+ test.in, out, err, test.out, testErr)
+ }
+ }
+ case 64:
+ for i := range parseInt64Tests {
+ test := &parseInt64Tests[i]
+ out, err := Atoi(test.in)
+ var testErr error
+ if test.err != nil {
+ testErr = &NumError{"Atoi", test.in, test.err.(*NumError).Err}
+ }
+ if test.out != int64(out) || !reflect.DeepEqual(testErr, err) {
+ t.Errorf("Atoi(%q) = %v, %v want %v, %v",
+ test.in, out, err, test.out, testErr)
+ }
+ }
+ }
+}
+
+func bitSizeErrStub(name string, bitSize int) error {
+ return BitSizeError(name, "0", bitSize)
+}
+
+func baseErrStub(name string, base int) error {
+ return BaseError(name, "0", base)
+}
+
+func noErrStub(name string, arg int) error {
+ return nil
+}
+
+type parseErrorTest struct {
+ arg int
+ errStub func(name string, arg int) error
+}
+
+var parseBitSizeTests = []parseErrorTest{
+ {-1, bitSizeErrStub},
+ {0, noErrStub},
+ {64, noErrStub},
+ {65, bitSizeErrStub},
+}
+
+var parseBaseTests = []parseErrorTest{
+ {-1, baseErrStub},
+ {0, noErrStub},
+ {1, baseErrStub},
+ {2, noErrStub},
+ {36, noErrStub},
+ {37, baseErrStub},
+}
+
+func TestParseIntBitSize(t *testing.T) {
+ for i := range parseBitSizeTests {
+ test := &parseBitSizeTests[i]
+ testErr := test.errStub("ParseInt", test.arg)
+ _, err := ParseInt("0", 0, test.arg)
+ if !reflect.DeepEqual(testErr, err) {
+ t.Errorf("ParseInt(\"0\", 0, %v) = 0, %v want 0, %v",
+ test.arg, err, testErr)
+ }
+ }
+}
+
+func TestParseUintBitSize(t *testing.T) {
+ for i := range parseBitSizeTests {
+ test := &parseBitSizeTests[i]
+ testErr := test.errStub("ParseUint", test.arg)
+ _, err := ParseUint("0", 0, test.arg)
+ if !reflect.DeepEqual(testErr, err) {
+ t.Errorf("ParseUint(\"0\", 0, %v) = 0, %v want 0, %v",
+ test.arg, err, testErr)
+ }
+ }
+}
+
+func TestParseIntBase(t *testing.T) {
+ for i := range parseBaseTests {
+ test := &parseBaseTests[i]
+ testErr := test.errStub("ParseInt", test.arg)
+ _, err := ParseInt("0", test.arg, 0)
+ if !reflect.DeepEqual(testErr, err) {
+ t.Errorf("ParseInt(\"0\", %v, 0) = 0, %v want 0, %v",
+ test.arg, err, testErr)
+ }
+ }
+}
+
+func TestParseUintBase(t *testing.T) {
+ for i := range parseBaseTests {
+ test := &parseBaseTests[i]
+ testErr := test.errStub("ParseUint", test.arg)
+ _, err := ParseUint("0", test.arg, 0)
+ if !reflect.DeepEqual(testErr, err) {
+ t.Errorf("ParseUint(\"0\", %v, 0) = 0, %v want 0, %v",
+ test.arg, err, testErr)
+ }
+ }
+}
+
func TestNumError(t *testing.T) {
for _, test := range numErrorTests {
err := &NumError{
@@ -338,26 +480,67 @@ func TestNumError(t *testing.T) {
}
}
-func BenchmarkAtoi(b *testing.B) {
- for i := 0; i < b.N; i++ {
- ParseInt("12345678", 10, 0)
- }
+func BenchmarkParseInt(b *testing.B) {
+ b.Run("Pos", func(b *testing.B) {
+ benchmarkParseInt(b, 1)
+ })
+ b.Run("Neg", func(b *testing.B) {
+ benchmarkParseInt(b, -1)
+ })
}
-func BenchmarkAtoiNeg(b *testing.B) {
- for i := 0; i < b.N; i++ {
- ParseInt("-12345678", 10, 0)
- }
+type benchCase struct {
+ name string
+ num int64
}
-func BenchmarkAtoi64(b *testing.B) {
- for i := 0; i < b.N; i++ {
- ParseInt("12345678901234", 10, 64)
+func benchmarkParseInt(b *testing.B, neg int) {
+ cases := []benchCase{
+ {"7bit", 1<<7 - 1},
+ {"26bit", 1<<26 - 1},
+ {"31bit", 1<<31 - 1},
+ {"56bit", 1<<56 - 1},
+ {"63bit", 1<<63 - 1},
}
+ for _, cs := range cases {
+ b.Run(cs.name, func(b *testing.B) {
+ s := fmt.Sprintf("%d", cs.num*int64(neg))
+ for i := 0; i < b.N; i++ {
+ out, _ := ParseInt(s, 10, 64)
+ BenchSink += int(out)
+ }
+ })
+ }
+}
+
+func BenchmarkAtoi(b *testing.B) {
+ b.Run("Pos", func(b *testing.B) {
+ benchmarkAtoi(b, 1)
+ })
+ b.Run("Neg", func(b *testing.B) {
+ benchmarkAtoi(b, -1)
+ })
}
-func BenchmarkAtoi64Neg(b *testing.B) {
- for i := 0; i < b.N; i++ {
- ParseInt("-12345678901234", 10, 64)
+func benchmarkAtoi(b *testing.B, neg int) {
+ cases := []benchCase{
+ {"7bit", 1<<7 - 1},
+ {"26bit", 1<<26 - 1},
+ {"31bit", 1<<31 - 1},
+ }
+ if IntSize == 64 {
+ cases = append(cases, []benchCase{
+ {"56bit", 1<<56 - 1},
+ {"63bit", 1<<63 - 1},
+ }...)
+ }
+ for _, cs := range cases {
+ b.Run(cs.name, func(b *testing.B) {
+ s := fmt.Sprintf("%d", cs.num*int64(neg))
+ for i := 0; i < b.N; i++ {
+ out, _ := Atoi(s)
+ BenchSink += out
+ }
+ })
}
}
diff --git a/libgo/go/strconv/export_test.go b/libgo/go/strconv/export_test.go
new file mode 100644
index 0000000..8c03a7f
--- /dev/null
+++ b/libgo/go/strconv/export_test.go
@@ -0,0 +1,10 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package strconv
+
+var (
+ BitSizeError = bitSizeError
+ BaseError = baseError
+)
diff --git a/libgo/go/strconv/extfloat.go b/libgo/go/strconv/extfloat.go
index 7033e96..7f17bc6 100644
--- a/libgo/go/strconv/extfloat.go
+++ b/libgo/go/strconv/extfloat.go
@@ -641,7 +641,7 @@ func (f *extFloat) ShortestDecimal(d *decimalSlice, lower, upper *extFloat) bool
// adjustLastDigit modifies d = x-currentDiff*ε, to get closest to
// d = x-targetDiff*ε, without becoming smaller than x-maxDiff*ε.
// It assumes that a decimal digit is worth ulpDecimal*ε, and that
-// all data is known with a error estimate of ulpBinary*ε.
+// all data is known with an error estimate of ulpBinary*ε.
func adjustLastDigit(d *decimalSlice, currentDiff, targetDiff, maxDiff, ulpDecimal, ulpBinary uint64) bool {
if ulpDecimal < 2*ulpBinary {
// Approximation is too wide.
diff --git a/libgo/go/strconv/isprint.go b/libgo/go/strconv/isprint.go
index a30d8d8..5837142 100644
--- a/libgo/go/strconv/isprint.go
+++ b/libgo/go/strconv/isprint.go
@@ -7,7 +7,7 @@
package strconv
-// (462+139+82)*2 + (378)*4 = 2878 bytes
+// (456+140+86)*2 + (396)*4 = 2948 bytes
var isPrint16 = []uint16{
0x0020, 0x007e,
@@ -25,7 +25,7 @@ var isPrint16 = []uint16{
0x07c0, 0x07fa,
0x0800, 0x082d,
0x0830, 0x085b,
- 0x085e, 0x085e,
+ 0x085e, 0x086a,
0x08a0, 0x08bd,
0x08d4, 0x098c,
0x098f, 0x0990,
@@ -36,7 +36,7 @@ var isPrint16 = []uint16{
0x09cb, 0x09ce,
0x09d7, 0x09d7,
0x09dc, 0x09e3,
- 0x09e6, 0x09fb,
+ 0x09e6, 0x09fd,
0x0a01, 0x0a0a,
0x0a0f, 0x0a10,
0x0a13, 0x0a39,
@@ -51,8 +51,7 @@ var isPrint16 = []uint16{
0x0ad0, 0x0ad0,
0x0ae0, 0x0ae3,
0x0ae6, 0x0af1,
- 0x0af9, 0x0af9,
- 0x0b01, 0x0b0c,
+ 0x0af9, 0x0b0c,
0x0b0f, 0x0b10,
0x0b13, 0x0b39,
0x0b3c, 0x0b44,
@@ -82,8 +81,7 @@ var isPrint16 = []uint16{
0x0cd5, 0x0cd6,
0x0cde, 0x0ce3,
0x0ce6, 0x0cf2,
- 0x0d01, 0x0d3a,
- 0x0d3d, 0x0d4f,
+ 0x0d00, 0x0d4f,
0x0d54, 0x0d63,
0x0d66, 0x0d7f,
0x0d82, 0x0d96,
@@ -154,8 +152,7 @@ var isPrint16 = []uint16{
0x1c4d, 0x1c88,
0x1cc0, 0x1cc7,
0x1cd0, 0x1cf9,
- 0x1d00, 0x1df5,
- 0x1dfb, 0x1f15,
+ 0x1d00, 0x1f15,
0x1f18, 0x1f1d,
0x1f20, 0x1f45,
0x1f48, 0x1f4d,
@@ -167,7 +164,7 @@ var isPrint16 = []uint16{
0x2030, 0x205e,
0x2070, 0x2071,
0x2074, 0x209c,
- 0x20a0, 0x20be,
+ 0x20a0, 0x20bf,
0x20d0, 0x20f0,
0x2100, 0x218b,
0x2190, 0x2426,
@@ -175,7 +172,7 @@ var isPrint16 = []uint16{
0x2460, 0x2b73,
0x2b76, 0x2b95,
0x2b98, 0x2bb9,
- 0x2bbd, 0x2bd1,
+ 0x2bbd, 0x2bd2,
0x2bec, 0x2bef,
0x2c00, 0x2cf3,
0x2cf9, 0x2d27,
@@ -183,17 +180,17 @@ var isPrint16 = []uint16{
0x2d30, 0x2d67,
0x2d6f, 0x2d70,
0x2d7f, 0x2d96,
- 0x2da0, 0x2e44,
+ 0x2da0, 0x2e49,
0x2e80, 0x2ef3,
0x2f00, 0x2fd5,
0x2ff0, 0x2ffb,
0x3001, 0x3096,
0x3099, 0x30ff,
- 0x3105, 0x312d,
+ 0x3105, 0x312e,
0x3131, 0x31ba,
0x31c0, 0x31e3,
0x31f0, 0x4db5,
- 0x4dc0, 0x9fd5,
+ 0x4dc0, 0x9fea,
0xa000, 0xa48c,
0xa490, 0xa4c6,
0xa4d0, 0xa62b,
@@ -254,6 +251,7 @@ var isNotPrint16 = []uint16{
0x0590,
0x06dd,
0x083f,
+ 0x085f,
0x08b5,
0x08e2,
0x0984,
@@ -275,6 +273,7 @@ var isNotPrint16 = []uint16{
0x0ab4,
0x0ac6,
0x0aca,
+ 0x0b00,
0x0b04,
0x0b29,
0x0b31,
@@ -341,7 +340,7 @@ var isNotPrint16 = []uint16{
0x1771,
0x191f,
0x1a5f,
- 0x1cf7,
+ 0x1dfa,
0x1f58,
0x1f5a,
0x1f5c,
@@ -351,7 +350,6 @@ var isNotPrint16 = []uint16{
0x1fdc,
0x1ff5,
0x208f,
- 0x23ff,
0x2bc9,
0x2c2f,
0x2c5f,
@@ -398,7 +396,7 @@ var isPrint32 = []uint32{
0x0102a0, 0x0102d0,
0x0102e0, 0x0102fb,
0x010300, 0x010323,
- 0x010330, 0x01034a,
+ 0x01032d, 0x01034a,
0x010350, 0x01037a,
0x010380, 0x0103c3,
0x0103c8, 0x0103d5,
@@ -481,11 +479,17 @@ var isPrint32 = []uint32{
0x011730, 0x01173f,
0x0118a0, 0x0118f2,
0x0118ff, 0x0118ff,
+ 0x011a00, 0x011a47,
+ 0x011a50, 0x011a83,
+ 0x011a86, 0x011aa2,
0x011ac0, 0x011af8,
0x011c00, 0x011c45,
0x011c50, 0x011c6c,
0x011c70, 0x011c8f,
0x011c92, 0x011cb6,
+ 0x011d00, 0x011d36,
+ 0x011d3a, 0x011d47,
+ 0x011d50, 0x011d59,
0x012000, 0x012399,
0x012400, 0x012474,
0x012480, 0x012543,
@@ -502,10 +506,11 @@ var isPrint32 = []uint32{
0x016f00, 0x016f44,
0x016f50, 0x016f7e,
0x016f8f, 0x016f9f,
- 0x016fe0, 0x016fe0,
+ 0x016fe0, 0x016fe1,
0x017000, 0x0187ec,
0x018800, 0x018af2,
- 0x01b000, 0x01b001,
+ 0x01b000, 0x01b11e,
+ 0x01b170, 0x01b2fb,
0x01bc00, 0x01bc6a,
0x01bc70, 0x01bc7c,
0x01bc80, 0x01bc88,
@@ -553,9 +558,10 @@ var isPrint32 = []uint32{
0x01f210, 0x01f23b,
0x01f240, 0x01f248,
0x01f250, 0x01f251,
- 0x01f300, 0x01f6d2,
+ 0x01f260, 0x01f265,
+ 0x01f300, 0x01f6d4,
0x01f6e0, 0x01f6ec,
- 0x01f6f0, 0x01f6f6,
+ 0x01f6f0, 0x01f6f8,
0x01f700, 0x01f773,
0x01f780, 0x01f7d4,
0x01f800, 0x01f80b,
@@ -563,16 +569,17 @@ var isPrint32 = []uint32{
0x01f850, 0x01f859,
0x01f860, 0x01f887,
0x01f890, 0x01f8ad,
- 0x01f910, 0x01f927,
- 0x01f930, 0x01f930,
- 0x01f933, 0x01f94b,
- 0x01f950, 0x01f95e,
- 0x01f980, 0x01f991,
+ 0x01f900, 0x01f90b,
+ 0x01f910, 0x01f94c,
+ 0x01f950, 0x01f96b,
+ 0x01f980, 0x01f997,
0x01f9c0, 0x01f9c0,
+ 0x01f9d0, 0x01f9e6,
0x020000, 0x02a6d6,
0x02a700, 0x02b734,
0x02b740, 0x02b81d,
0x02b820, 0x02cea1,
+ 0x02ceb0, 0x02ebe0,
0x02f800, 0x02fa1d,
0x0e0100, 0x0e01ef,
}
@@ -605,9 +612,14 @@ var isNotPrint32 = []uint16{ // add 0x10000 to each entry
0x1334,
0x145a,
0x145c,
+ 0x1a9d,
0x1c09,
0x1c37,
0x1ca8,
+ 0x1d07,
+ 0x1d0a,
+ 0x1d3b,
+ 0x1d3e,
0x246f,
0x6a5f,
0x6b5a,
@@ -658,7 +670,6 @@ var isNotPrint32 = []uint16{ // add 0x10000 to each entry
0xf0c0,
0xf0d0,
0xf12f,
- 0xf91f,
0xf93f,
}
diff --git a/libgo/go/strconv/quote.go b/libgo/go/strconv/quote.go
index db57065..156a510 100644
--- a/libgo/go/strconv/quote.go
+++ b/libgo/go/strconv/quote.go
@@ -381,7 +381,7 @@ func Unquote(s string) (string, error) {
return "", ErrSyntax
}
- // Is it trivial? Avoid allocation.
+ // Is it trivial? Avoid allocation.
if !contains(s, '\\') && !contains(s, quote) {
switch quote {
case '"':