aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/strconv
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2018-09-24 21:46:21 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-09-24 21:46:21 +0000
commitdd931d9b48647e898dc80927c532ae93cc09e192 (patch)
tree71be2295cd79b8a182f6130611658db8628772d5 /libgo/go/strconv
parent779d8a5ad09b01428726ea5a0e6c87bd9ac3c0e4 (diff)
downloadgcc-dd931d9b48647e898dc80927c532ae93cc09e192.zip
gcc-dd931d9b48647e898dc80927c532ae93cc09e192.tar.gz
gcc-dd931d9b48647e898dc80927c532ae93cc09e192.tar.bz2
libgo: update to Go 1.11
Reviewed-on: https://go-review.googlesource.com/136435 gotools/: * Makefile.am (mostlyclean-local): Run chmod on check-go-dir to make sure it is writable. (check-go-tools): Likewise. (check-vet): Copy internal/objabi to check-vet-dir. * Makefile.in: Rebuild. From-SVN: r264546
Diffstat (limited to 'libgo/go/strconv')
-rw-r--r--libgo/go/strconv/atob.go2
-rw-r--r--libgo/go/strconv/atof_test.go4
-rw-r--r--libgo/go/strconv/doc.go8
-rw-r--r--libgo/go/strconv/example_test.go34
-rw-r--r--libgo/go/strconv/extfloat.go43
-rw-r--r--libgo/go/strconv/ftoa.go7
-rw-r--r--libgo/go/strconv/ftoa_test.go4
-rw-r--r--libgo/go/strconv/isprint.go3
-rw-r--r--libgo/go/strconv/itoa.go30
-rw-r--r--libgo/go/strconv/itoa_test.go12
-rw-r--r--libgo/go/strconv/makeisprint.go3
-rw-r--r--libgo/go/strconv/quote.go8
-rw-r--r--libgo/go/strconv/quote_test.go30
13 files changed, 102 insertions, 86 deletions
diff --git a/libgo/go/strconv/atob.go b/libgo/go/strconv/atob.go
index 879ceb3..0a49500 100644
--- a/libgo/go/strconv/atob.go
+++ b/libgo/go/strconv/atob.go
@@ -17,7 +17,7 @@ func ParseBool(str string) (bool, error) {
return false, syntaxError("ParseBool", str)
}
-// FormatBool returns "true" or "false" according to the value of b
+// FormatBool returns "true" or "false" according to the value of b.
func FormatBool(b bool) string {
if b {
return "true"
diff --git a/libgo/go/strconv/atof_test.go b/libgo/go/strconv/atof_test.go
index 3380b20..cf4d47c 100644
--- a/libgo/go/strconv/atof_test.go
+++ b/libgo/go/strconv/atof_test.go
@@ -137,9 +137,9 @@ var atoftests = []atofTest{
{".e-1", "0", ErrSyntax},
{"1\x00.2", "0", ErrSyntax},
- // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
+ // https://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
{"2.2250738585072012e-308", "2.2250738585072014e-308", nil},
- // http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
+ // https://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
{"2.2250738585072011e-308", "2.225073858507201e-308", nil},
// A very large number (initially wrongly parsed by the fast algorithm).
diff --git a/libgo/go/strconv/doc.go b/libgo/go/strconv/doc.go
index 7bc1e27..cba8984 100644
--- a/libgo/go/strconv/doc.go
+++ b/libgo/go/strconv/doc.go
@@ -32,10 +32,10 @@
//
// FormatBool, FormatFloat, FormatInt, and FormatUint convert values to strings:
//
-// s := strconv.FormatBool(true)
-// s := strconv.FormatFloat(3.1415, 'E', -1, 64)
-// s := strconv.FormatInt(-42, 16)
-// s := strconv.FormatUint(42, 16)
+// s := strconv.FormatBool(true)
+// s := strconv.FormatFloat(3.1415, 'E', -1, 64)
+// s := strconv.FormatInt(-42, 16)
+// s := strconv.FormatUint(42, 16)
//
// AppendBool, AppendFloat, AppendInt, and AppendUint are similar but
// append the formatted value to a destination slice.
diff --git a/libgo/go/strconv/example_test.go b/libgo/go/strconv/example_test.go
index 01fbbc0..5c2e8a9 100644
--- a/libgo/go/strconv/example_test.go
+++ b/libgo/go/strconv/example_test.go
@@ -281,27 +281,23 @@ func ExampleQuoteToASCII() {
}
func ExampleUnquote() {
- test := func(s string) {
- t, err := strconv.Unquote(s)
- if err != nil {
- fmt.Printf("Unquote(%#v): %v\n", s, err)
- } else {
- fmt.Printf("Unquote(%#v) = %v\n", s, t)
- }
- }
-
- s := `\"Fran & Freddie's Diner\t\u263a\"\"`
- // If the string doesn't have quotes, it can't be unquoted.
- test(s) // invalid syntax
- test("`" + s + "`")
- test(`"` + s + `"`)
- test(`'\u263a'`)
+ s, err := strconv.Unquote("You can't unquote a string without quotes")
+ fmt.Printf("%q, %v\n", s, err)
+ s, err = strconv.Unquote("\"The string must be either double-quoted\"")
+ fmt.Printf("%q, %v\n", s, err)
+ s, err = strconv.Unquote("`or backquoted.`")
+ fmt.Printf("%q, %v\n", s, err)
+ s, err = strconv.Unquote("'\u263a'") // single character only allowed in single quotes
+ fmt.Printf("%q, %v\n", s, err)
+ s, err = strconv.Unquote("'\u2639\u2639'")
+ fmt.Printf("%q, %v\n", s, err)
// Output:
- // Unquote("\\\"Fran & Freddie's Diner\\t\\u263a\\\"\\\""): invalid syntax
- // Unquote("`\\\"Fran & Freddie's Diner\\t\\u263a\\\"\\\"`") = \"Fran & Freddie's Diner\t\u263a\"\"
- // Unquote("\"\\\"Fran & Freddie's Diner\\t\\u263a\\\"\\\"\"") = "Fran & Freddie's Diner ☺""
- // Unquote("'\\u263a'") = ☺
+ // "", invalid syntax
+ // "The string must be either double-quoted", <nil>
+ // "or backquoted.", <nil>
+ // "☺", <nil>
+ // "", invalid syntax
}
func ExampleUnquoteChar() {
diff --git a/libgo/go/strconv/extfloat.go b/libgo/go/strconv/extfloat.go
index 7f17bc6..32d3340 100644
--- a/libgo/go/strconv/extfloat.go
+++ b/libgo/go/strconv/extfloat.go
@@ -4,6 +4,10 @@
package strconv
+import (
+ "math/bits"
+)
+
// An extFloat represents an extended floating-point number, with more
// precision than a float64. It does not try to save bits: the
// number represented by the structure is mant*(2^exp), with a negative
@@ -15,7 +19,7 @@ type extFloat struct {
}
// Powers of ten taken from double-conversion library.
-// http://code.google.com/p/double-conversion/
+// https://code.google.com/p/double-conversion/
const (
firstPowerOfTen = -348
stepPowerOfTen = 8
@@ -196,38 +200,15 @@ func (f *extFloat) AssignComputeBounds(mant uint64, exp int, neg bool, flt *floa
// Normalize normalizes f so that the highest bit of the mantissa is
// set, and returns the number by which the mantissa was left-shifted.
-func (f *extFloat) Normalize() (shift uint) {
- mant, exp := f.mant, f.exp
- if mant == 0 {
+func (f *extFloat) Normalize() uint {
+ // bits.LeadingZeros64 would return 64
+ if f.mant == 0 {
return 0
}
- if mant>>(64-32) == 0 {
- mant <<= 32
- exp -= 32
- }
- if mant>>(64-16) == 0 {
- mant <<= 16
- exp -= 16
- }
- if mant>>(64-8) == 0 {
- mant <<= 8
- exp -= 8
- }
- if mant>>(64-4) == 0 {
- mant <<= 4
- exp -= 4
- }
- if mant>>(64-2) == 0 {
- mant <<= 2
- exp -= 2
- }
- if mant>>(64-1) == 0 {
- mant <<= 1
- exp -= 1
- }
- shift = uint(f.exp - exp)
- f.mant, f.exp = mant, exp
- return
+ shift := bits.LeadingZeros64(f.mant)
+ f.mant <<= uint(shift)
+ f.exp -= shift
+ return uint(shift)
}
// Multiply sets f to the product f*g: the result is correctly rounded,
diff --git a/libgo/go/strconv/ftoa.go b/libgo/go/strconv/ftoa.go
index 8b3d33e..a7ccbe6 100644
--- a/libgo/go/strconv/ftoa.go
+++ b/libgo/go/strconv/ftoa.go
@@ -35,10 +35,11 @@ var float64info = floatInfo{52, 11, -1023}
// 'g' ('e' for large exponents, 'f' otherwise), or
// 'G' ('E' for large exponents, 'f' otherwise).
//
-// The precision prec controls the number of digits
-// (excluding the exponent) printed by the 'e', 'E', 'f', 'g', and 'G' formats.
+// The precision prec controls the number of digits (excluding the exponent)
+// printed by the 'e', 'E', 'f', 'g', and 'G' formats.
// For 'e', 'E', and 'f' it is the number of digits after the decimal point.
-// For 'g' and 'G' it is the total number of digits.
+// For 'g' and 'G' it is the maximum number of significant digits (trailing
+// zeros are removed).
// The special precision -1 uses the smallest number of digits
// necessary such that ParseFloat will return f exactly.
func FormatFloat(f float64, fmt byte, prec, bitSize int) string {
diff --git a/libgo/go/strconv/ftoa_test.go b/libgo/go/strconv/ftoa_test.go
index 976bd2c..1d3030b 100644
--- a/libgo/go/strconv/ftoa_test.go
+++ b/libgo/go/strconv/ftoa_test.go
@@ -120,9 +120,9 @@ var ftoatests = []ftoaTest{
{0.5, 'f', 0, "0"},
{1.5, 'f', 0, "2"},
- // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
+ // https://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
{2.2250738585072012e-308, 'g', -1, "2.2250738585072014e-308"},
- // http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
+ // https://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
{2.2250738585072011e-308, 'g', -1, "2.225073858507201e-308"},
// Issue 2625.
diff --git a/libgo/go/strconv/isprint.go b/libgo/go/strconv/isprint.go
index 5837142..f537ba4 100644
--- a/libgo/go/strconv/isprint.go
+++ b/libgo/go/strconv/isprint.go
@@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// DO NOT EDIT. GENERATED BY
-// go run makeisprint.go -output isprint.go
+// Code generated by go run makeisprint.go -output isprint.go; DO NOT EDIT.
package strconv
diff --git a/libgo/go/strconv/itoa.go b/libgo/go/strconv/itoa.go
index 78527c8..8afe7af 100644
--- a/libgo/go/strconv/itoa.go
+++ b/libgo/go/strconv/itoa.go
@@ -4,6 +4,8 @@
package strconv
+import "math/bits"
+
const fastSmalls = true // enable fast path for small integers
// FormatUint returns the string representation of i in the given base,
@@ -55,11 +57,10 @@ func AppendUint(dst []byte, i uint64, base int) []byte {
// small returns the string for an i with 0 <= i < nSmalls.
func small(i int) string {
- off := 0
if i < 10 {
- off = 1
+ return digits[i : i+1]
}
- return smallsString[i*2+off : i*2+2]
+ return smallsString[i*2 : i*2+2]
}
const nSmalls = 100
@@ -79,14 +80,6 @@ const host32bit = ^uint(0)>>32 == 0
const digits = "0123456789abcdefghijklmnopqrstuvwxyz"
-var shifts = [len(digits) + 1]uint{
- 1 << 1: 1,
- 1 << 2: 2,
- 1 << 3: 3,
- 1 << 4: 4,
- 1 << 5: 5,
-}
-
// formatBits computes the string representation of u in the given base.
// If neg is set, u is treated as negative int64 value. If append_ is
// set, the string is appended to dst and the resulting byte slice is
@@ -158,14 +151,17 @@ func formatBits(dst []byte, u uint64, base int, neg, append_ bool) (d []byte, s
a[i] = smallsString[is]
}
- } else if s := shifts[base]; s > 0 {
- // base is power of 2: use shifts and masks instead of / and %
+ } else if isPowerOfTwo(base) {
+ // It is known that base is a power of two and
+ // 2 <= base <= len(digits).
+ // Use shifts and masks instead of / and %.
+ shift := uint(bits.TrailingZeros(uint(base))) & 31
b := uint64(base)
- m := uint(base) - 1 // == 1<<s - 1
+ m := uint(base) - 1 // == 1<<shift - 1
for u >= b {
i--
a[i] = digits[uint(u)&m]
- u >>= s
+ u >>= shift
}
// u < base
i--
@@ -200,3 +196,7 @@ func formatBits(dst []byte, u uint64, base int, neg, append_ bool) (d []byte, s
s = string(a[i:])
return
}
+
+func isPowerOfTwo(x int) bool {
+ return x&(x-1) == 0
+}
diff --git a/libgo/go/strconv/itoa_test.go b/libgo/go/strconv/itoa_test.go
index 89c2de6..b5ee3aa 100644
--- a/libgo/go/strconv/itoa_test.go
+++ b/libgo/go/strconv/itoa_test.go
@@ -200,10 +200,14 @@ func BenchmarkAppendUint(b *testing.B) {
}
func BenchmarkFormatIntSmall(b *testing.B) {
- const smallInt = 42
- for i := 0; i < b.N; i++ {
- s := FormatInt(smallInt, 10)
- BenchSink += len(s)
+ smallInts := []int64{7, 42}
+ for _, smallInt := range smallInts {
+ b.Run(Itoa(int(smallInt)), func(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ s := FormatInt(smallInt, 10)
+ BenchSink += len(s)
+ }
+ })
}
}
diff --git a/libgo/go/strconv/makeisprint.go b/libgo/go/strconv/makeisprint.go
index 0a3e5b2..1a3248f 100644
--- a/libgo/go/strconv/makeisprint.go
+++ b/libgo/go/strconv/makeisprint.go
@@ -139,8 +139,7 @@ func main() {
fmt.Fprintf(&buf, `// Copyright 2013 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.`+"\n\n")
- fmt.Fprintf(&buf, "// DO NOT EDIT. GENERATED BY\n")
- fmt.Fprintf(&buf, "// go run makeisprint.go -output isprint.go\n\n")
+ fmt.Fprintf(&buf, "// Code generated by go run makeisprint.go -output isprint.go; DO NOT EDIT.\n\n")
fmt.Fprintf(&buf, "package strconv\n\n")
fmt.Fprintf(&buf, "// (%d+%d+%d)*2 + (%d)*4 = %d bytes\n\n",
diff --git a/libgo/go/strconv/quote.go b/libgo/go/strconv/quote.go
index 156a510..9b7194a 100644
--- a/libgo/go/strconv/quote.go
+++ b/libgo/go/strconv/quote.go
@@ -237,6 +237,10 @@ func unhex(b byte) (v rune, ok bool) {
// If set to zero, it does not permit either escape and allows both quote characters to appear unescaped.
func UnquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err error) {
// easy cases
+ if len(s) == 0 {
+ err = ErrSyntax
+ return
+ }
switch c := s[0]; {
case c == quote && (quote == '\'' || quote == '"'):
err = ErrSyntax
@@ -385,7 +389,9 @@ func Unquote(s string) (string, error) {
if !contains(s, '\\') && !contains(s, quote) {
switch quote {
case '"':
- return s, nil
+ if utf8.ValidString(s) {
+ return s, nil
+ }
case '\'':
r, size := utf8.DecodeRuneInString(s)
if size == len(s) && (r != utf8.RuneError || size != 1) {
diff --git a/libgo/go/strconv/quote_test.go b/libgo/go/strconv/quote_test.go
index a4b5804..cdc9aaf 100644
--- a/libgo/go/strconv/quote_test.go
+++ b/libgo/go/strconv/quote_test.go
@@ -326,6 +326,36 @@ func TestUnquote(t *testing.T) {
}
}
+// Issue 23685: invalid UTF-8 should not go through the fast path.
+func TestUnquoteInvalidUTF8(t *testing.T) {
+ tests := []struct {
+ in string
+
+ // one of:
+ want string
+ wantErr string
+ }{
+ {in: `"foo"`, want: "foo"},
+ {in: `"foo`, wantErr: "invalid syntax"},
+ {in: `"` + "\xc0" + `"`, want: "\xef\xbf\xbd"},
+ {in: `"a` + "\xc0" + `"`, want: "a\xef\xbf\xbd"},
+ {in: `"\t` + "\xc0" + `"`, want: "\t\xef\xbf\xbd"},
+ }
+ for i, tt := range tests {
+ got, err := Unquote(tt.in)
+ var gotErr string
+ if err != nil {
+ gotErr = err.Error()
+ }
+ if gotErr != tt.wantErr {
+ t.Errorf("%d. Unquote(%q) = err %v; want %q", i, tt.in, err, tt.wantErr)
+ }
+ if tt.wantErr == "" && err == nil && got != tt.want {
+ t.Errorf("%d. Unquote(%q) = %02x; want %02x", i, tt.in, []byte(got), []byte(tt.want))
+ }
+ }
+}
+
func BenchmarkUnquoteEasy(b *testing.B) {
for i := 0; i < b.N; i++ {
Unquote(`"Give me a rock, paper and scissors and I will move the world."`)