diff options
author | Ian Lance Taylor <iant@golang.org> | 2018-01-09 01:23:08 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-01-09 01:23:08 +0000 |
commit | 1a2f01efa63036a5104f203a4789e682c0e0915d (patch) | |
tree | 373e15778dc8295354584e1f86915ae493b604ff /libgo/go/strconv | |
parent | 8799df67f2dab88f9fda11739c501780a85575e2 (diff) | |
download | gcc-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.go | 133 | ||||
-rw-r--r-- | libgo/go/strconv/atoi_test.go | 363 | ||||
-rw-r--r-- | libgo/go/strconv/export_test.go | 10 | ||||
-rw-r--r-- | libgo/go/strconv/extfloat.go | 2 | ||||
-rw-r--r-- | libgo/go/strconv/isprint.go | 65 | ||||
-rw-r--r-- | libgo/go/strconv/quote.go | 2 |
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 '"': |