aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/strconv
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2015-10-31 00:59:47 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2015-10-31 00:59:47 +0000
commitaf146490bb04205107cb23e301ec7a8ff927b5fc (patch)
tree13beeaed3698c61903fe93fb1ce70bd9b18d4e7f /libgo/go/strconv
parent725e1be3406315d9bcc8195d7eef0a7082b3c7cc (diff)
downloadgcc-af146490bb04205107cb23e301ec7a8ff927b5fc.zip
gcc-af146490bb04205107cb23e301ec7a8ff927b5fc.tar.gz
gcc-af146490bb04205107cb23e301ec7a8ff927b5fc.tar.bz2
runtime: Remove now unnecessary pad field from ParFor.
It is not needed due to the removal of the ctx field. Reviewed-on: https://go-review.googlesource.com/16525 From-SVN: r229616
Diffstat (limited to 'libgo/go/strconv')
-rw-r--r--libgo/go/strconv/atof.go2
-rw-r--r--libgo/go/strconv/atoi.go40
-rw-r--r--libgo/go/strconv/atoi_test.go83
-rw-r--r--libgo/go/strconv/decimal.go117
-rw-r--r--libgo/go/strconv/doc.go57
-rw-r--r--libgo/go/strconv/example_test.go338
-rw-r--r--libgo/go/strconv/extfloat.go2
-rw-r--r--libgo/go/strconv/ftoa.go108
-rw-r--r--libgo/go/strconv/ftoa_test.go1
-rw-r--r--libgo/go/strconv/isprint.go89
-rw-r--r--libgo/go/strconv/itoa.go58
-rw-r--r--libgo/go/strconv/itoa_test.go1
-rw-r--r--libgo/go/strconv/quote_example_test.go35
13 files changed, 686 insertions, 245 deletions
diff --git a/libgo/go/strconv/atof.go b/libgo/go/strconv/atof.go
index beaa68d..a4f4862 100644
--- a/libgo/go/strconv/atof.go
+++ b/libgo/go/strconv/atof.go
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Package strconv implements conversions to and from string representations
-// of basic data types.
package strconv
// decimal to binary floating point conversion.
diff --git a/libgo/go/strconv/atoi.go b/libgo/go/strconv/atoi.go
index 9ecec5a..965e3a2 100644
--- a/libgo/go/strconv/atoi.go
+++ b/libgo/go/strconv/atoi.go
@@ -36,13 +36,7 @@ const intSize = 32 << (^uint(0) >> 63)
// IntSize is the size in bits of an int or uint value.
const IntSize = intSize
-// Return the first number n such that n*base >= 1<<64.
-func cutoff64(base int) uint64 {
- if base < 2 {
- return 0
- }
- return (1<<64-1)/uint64(base) + 1
-}
+const maxUint64 = (1<<64 - 1)
// ParseUint is like ParseInt but for unsigned numbers.
func ParseUint(s string, base int, bitSize int) (n uint64, err error) {
@@ -52,7 +46,7 @@ func ParseUint(s string, base int, bitSize int) (n uint64, err error) {
bitSize = int(IntSize)
}
- s0 := s
+ i := 0
switch {
case len(s) < 1:
err = ErrSyntax
@@ -65,14 +59,15 @@ func ParseUint(s string, base int, bitSize int) (n uint64, err error) {
// Look for octal, hex prefix.
switch {
case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
- base = 16
- s = s[2:]
- if len(s) < 1 {
+ if len(s) < 3 {
err = ErrSyntax
goto Error
}
+ base = 16
+ i = 2
case s[0] == '0':
base = 8
+ i = 1
default:
base = 10
}
@@ -82,11 +77,20 @@ func ParseUint(s string, base int, bitSize int) (n uint64, err error) {
goto Error
}
- n = 0
- cutoff = cutoff64(base)
+ // Cutoff is the smallest number such that cutoff*base > maxUint64.
+ // Use compile-time constants for common cases.
+ switch base {
+ case 10:
+ cutoff = maxUint64/10 + 1
+ case 16:
+ cutoff = maxUint64/16 + 1
+ default:
+ cutoff = maxUint64/uint64(base) + 1
+ }
+
maxVal = 1<<uint(bitSize) - 1
- for i := 0; i < len(s); i++ {
+ for ; i < len(s); i++ {
var v byte
d := s[i]
switch {
@@ -101,7 +105,7 @@ func ParseUint(s string, base int, bitSize int) (n uint64, err error) {
err = ErrSyntax
goto Error
}
- if int(v) >= base {
+ if v >= byte(base) {
n = 0
err = ErrSyntax
goto Error
@@ -109,7 +113,7 @@ func ParseUint(s string, base int, bitSize int) (n uint64, err error) {
if n >= cutoff {
// n*base overflows
- n = 1<<64 - 1
+ n = maxUint64
err = ErrRange
goto Error
}
@@ -118,7 +122,7 @@ func ParseUint(s string, base int, bitSize int) (n uint64, err error) {
n1 := n + uint64(v)
if n1 < n || n1 > maxVal {
// n+v overflows
- n = 1<<64 - 1
+ n = maxUint64
err = ErrRange
goto Error
}
@@ -128,7 +132,7 @@ func ParseUint(s string, base int, bitSize int) (n uint64, err error) {
return n, nil
Error:
- return n, &NumError{"ParseUint", s0, err}
+ return n, &NumError{"ParseUint", s, err}
}
// ParseInt interprets a string s in the given base (2 to 36) and
diff --git a/libgo/go/strconv/atoi_test.go b/libgo/go/strconv/atoi_test.go
index 9407573..bd6a6a0 100644
--- a/libgo/go/strconv/atoi_test.go
+++ b/libgo/go/strconv/atoi_test.go
@@ -33,12 +33,16 @@ var atoui64tests = []atoui64Test{
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},
@@ -77,28 +81,61 @@ var atoi64tests = []atoi64Test{
{"-9223372036854775809", -1 << 63, ErrRange},
}
-var btoi64tests = []atoi64Test{
- {"", 0, ErrSyntax},
- {"0", 0, nil},
- {"-0", 0, nil},
- {"1", 1, nil},
- {"-1", -1, nil},
- {"12345", 12345, nil},
- {"-12345", -12345, nil},
- {"012345", 012345, nil},
- {"-012345", -012345, nil},
- {"0x12345", 0x12345, nil},
- {"-0X12345", -0x12345, nil},
- {"12345x", 0, ErrSyntax},
- {"-12345x", 0, ErrSyntax},
- {"98765432100", 98765432100, nil},
- {"-98765432100", -98765432100, nil},
- {"9223372036854775807", 1<<63 - 1, nil},
- {"-9223372036854775807", -(1<<63 - 1), nil},
- {"9223372036854775808", 1<<63 - 1, ErrRange},
- {"-9223372036854775808", -1 << 63, nil},
- {"9223372036854775809", 1<<63 - 1, ErrRange},
- {"-9223372036854775809", -1 << 63, ErrRange},
+type btoi64Test struct {
+ in string
+ base int
+ out int64
+ err error
+}
+
+var btoi64tests = []btoi64Test{
+ {"", 0, 0, ErrSyntax},
+ {"0", 0, 0, nil},
+ {"-0", 0, 0, nil},
+ {"1", 0, 1, nil},
+ {"-1", 0, -1, nil},
+ {"12345", 0, 12345, nil},
+ {"-12345", 0, -12345, nil},
+ {"012345", 0, 012345, nil},
+ {"-012345", 0, -012345, nil},
+ {"0x12345", 0, 0x12345, nil},
+ {"-0X12345", 0, -0x12345, nil},
+ {"12345x", 0, 0, ErrSyntax},
+ {"-12345x", 0, 0, ErrSyntax},
+ {"98765432100", 0, 98765432100, nil},
+ {"-98765432100", 0, -98765432100, nil},
+ {"9223372036854775807", 0, 1<<63 - 1, nil},
+ {"-9223372036854775807", 0, -(1<<63 - 1), nil},
+ {"9223372036854775808", 0, 1<<63 - 1, ErrRange},
+ {"-9223372036854775808", 0, -1 << 63, nil},
+ {"9223372036854775809", 0, 1<<63 - 1, ErrRange},
+ {"-9223372036854775809", 0, -1 << 63, ErrRange},
+
+ // other bases
+ {"g", 17, 16, nil},
+ {"10", 25, 25, nil},
+ {"holycow", 35, (((((17*35+24)*35+21)*35+34)*35+12)*35+24)*35 + 32, nil},
+ {"holycow", 36, (((((17*36+24)*36+21)*36+34)*36+12)*36+24)*36 + 32, nil},
+
+ // base 2
+ {"0", 2, 0, nil},
+ {"-1", 2, -1, nil},
+ {"1010", 2, 10, nil},
+ {"1000000000000000", 2, 1 << 15, nil},
+ {"111111111111111111111111111111111111111111111111111111111111111", 2, 1<<63 - 1, nil},
+ {"1000000000000000000000000000000000000000000000000000000000000000", 2, 1<<63 - 1, ErrRange},
+ {"-1000000000000000000000000000000000000000000000000000000000000000", 2, -1 << 63, nil},
+ {"-1000000000000000000000000000000000000000000000000000000000000001", 2, -1 << 63, ErrRange},
+
+ // base 8
+ {"-10", 8, -8, nil},
+ {"57635436545", 8, 057635436545, nil},
+ {"100000000", 8, 1 << 24, nil},
+
+ // base 16
+ {"10", 16, 16, nil},
+ {"-123456789abcdef", 16, -0x123456789abcdef, nil},
+ {"7fffffffffffffff", 16, 1<<63 - 1, nil},
}
type atoui32Test struct {
@@ -234,7 +271,7 @@ func TestParseInt64(t *testing.T) {
func TestParseInt64Base(t *testing.T) {
for i := range btoi64tests {
test := &btoi64tests[i]
- out, err := ParseInt(test.in, 0, 64)
+ 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)
diff --git a/libgo/go/strconv/decimal.go b/libgo/go/strconv/decimal.go
index 4260128..5252d6e 100644
--- a/libgo/go/strconv/decimal.go
+++ b/libgo/go/strconv/decimal.go
@@ -12,7 +12,7 @@
package strconv
type decimal struct {
- d [800]byte // digits
+ d [800]byte // digits, big-endian representation
nd int // number of digits used
dp int // decimal point
neg bool
@@ -102,16 +102,17 @@ func (a *decimal) Assign(v uint64) {
}
// Maximum shift that we can do in one pass without overflow.
-// Signed int has 31 bits, and we have to be able to accommodate 9<<k.
-const maxShift = 27
+// A uint has 32 or 64 bits, and we have to be able to accommodate 9<<k.
+const uintSize = 32 << (^uint(0) >> 63)
+const maxShift = uintSize - 4
-// Binary shift right (* 2) by k bits. k <= maxShift to avoid overflow.
+// Binary shift right (/ 2) by k bits. k <= maxShift to avoid overflow.
func rightShift(a *decimal, k uint) {
r := 0 // read pointer
w := 0 // write pointer
// Pick up enough leading digits to cover first shift.
- n := 0
+ var n uint
for ; n>>k == 0; r++ {
if r >= a.nd {
if n == 0 {
@@ -125,14 +126,14 @@ func rightShift(a *decimal, k uint) {
}
break
}
- c := int(a.d[r])
+ c := uint(a.d[r])
n = n*10 + c - '0'
}
a.dp -= r - 1
// Pick up a digit, put down a digit.
for ; r < a.nd; r++ {
- c := int(a.d[r])
+ c := uint(a.d[r])
dig := n >> k
n -= dig << k
a.d[w] = byte(dig + '0')
@@ -169,50 +170,84 @@ func rightShift(a *decimal, k uint) {
type leftCheat struct {
delta int // number of new digits
- cutoff string // minus one digit if original < a.
+ cutoff string // minus one digit if original < a.
}
var leftcheats = []leftCheat{
// Leading digits of 1/2^i = 5^i.
// 5^23 is not an exact 64-bit floating point number,
// so have to use bc for the math.
+ // Go up to 60 to be large enough for 32bit and 64bit platforms.
/*
- seq 27 | sed 's/^/5^/' | bc |
- awk 'BEGIN{ print "\tleftCheat{ 0, \"\" }," }
+ seq 60 | sed 's/^/5^/' | bc |
+ awk 'BEGIN{ print "\t{ 0, \"\" }," }
{
log2 = log(2)/log(10)
- printf("\tleftCheat{ %d, \"%s\" },\t// * %d\n",
+ printf("\t{ %d, \"%s\" },\t// * %d\n",
int(log2*NR+1), $0, 2**NR)
}'
*/
{0, ""},
- {1, "5"}, // * 2
- {1, "25"}, // * 4
- {1, "125"}, // * 8
- {2, "625"}, // * 16
- {2, "3125"}, // * 32
- {2, "15625"}, // * 64
- {3, "78125"}, // * 128
- {3, "390625"}, // * 256
- {3, "1953125"}, // * 512
- {4, "9765625"}, // * 1024
- {4, "48828125"}, // * 2048
- {4, "244140625"}, // * 4096
- {4, "1220703125"}, // * 8192
- {5, "6103515625"}, // * 16384
- {5, "30517578125"}, // * 32768
- {5, "152587890625"}, // * 65536
- {6, "762939453125"}, // * 131072
- {6, "3814697265625"}, // * 262144
- {6, "19073486328125"}, // * 524288
- {7, "95367431640625"}, // * 1048576
- {7, "476837158203125"}, // * 2097152
- {7, "2384185791015625"}, // * 4194304
- {7, "11920928955078125"}, // * 8388608
- {8, "59604644775390625"}, // * 16777216
- {8, "298023223876953125"}, // * 33554432
- {8, "1490116119384765625"}, // * 67108864
- {9, "7450580596923828125"}, // * 134217728
+ {1, "5"}, // * 2
+ {1, "25"}, // * 4
+ {1, "125"}, // * 8
+ {2, "625"}, // * 16
+ {2, "3125"}, // * 32
+ {2, "15625"}, // * 64
+ {3, "78125"}, // * 128
+ {3, "390625"}, // * 256
+ {3, "1953125"}, // * 512
+ {4, "9765625"}, // * 1024
+ {4, "48828125"}, // * 2048
+ {4, "244140625"}, // * 4096
+ {4, "1220703125"}, // * 8192
+ {5, "6103515625"}, // * 16384
+ {5, "30517578125"}, // * 32768
+ {5, "152587890625"}, // * 65536
+ {6, "762939453125"}, // * 131072
+ {6, "3814697265625"}, // * 262144
+ {6, "19073486328125"}, // * 524288
+ {7, "95367431640625"}, // * 1048576
+ {7, "476837158203125"}, // * 2097152
+ {7, "2384185791015625"}, // * 4194304
+ {7, "11920928955078125"}, // * 8388608
+ {8, "59604644775390625"}, // * 16777216
+ {8, "298023223876953125"}, // * 33554432
+ {8, "1490116119384765625"}, // * 67108864
+ {9, "7450580596923828125"}, // * 134217728
+ {9, "37252902984619140625"}, // * 268435456
+ {9, "186264514923095703125"}, // * 536870912
+ {10, "931322574615478515625"}, // * 1073741824
+ {10, "4656612873077392578125"}, // * 2147483648
+ {10, "23283064365386962890625"}, // * 4294967296
+ {10, "116415321826934814453125"}, // * 8589934592
+ {11, "582076609134674072265625"}, // * 17179869184
+ {11, "2910383045673370361328125"}, // * 34359738368
+ {11, "14551915228366851806640625"}, // * 68719476736
+ {12, "72759576141834259033203125"}, // * 137438953472
+ {12, "363797880709171295166015625"}, // * 274877906944
+ {12, "1818989403545856475830078125"}, // * 549755813888
+ {13, "9094947017729282379150390625"}, // * 1099511627776
+ {13, "45474735088646411895751953125"}, // * 2199023255552
+ {13, "227373675443232059478759765625"}, // * 4398046511104
+ {13, "1136868377216160297393798828125"}, // * 8796093022208
+ {14, "5684341886080801486968994140625"}, // * 17592186044416
+ {14, "28421709430404007434844970703125"}, // * 35184372088832
+ {14, "142108547152020037174224853515625"}, // * 70368744177664
+ {15, "710542735760100185871124267578125"}, // * 140737488355328
+ {15, "3552713678800500929355621337890625"}, // * 281474976710656
+ {15, "17763568394002504646778106689453125"}, // * 562949953421312
+ {16, "88817841970012523233890533447265625"}, // * 1125899906842624
+ {16, "444089209850062616169452667236328125"}, // * 2251799813685248
+ {16, "2220446049250313080847263336181640625"}, // * 4503599627370496
+ {16, "11102230246251565404236316680908203125"}, // * 9007199254740992
+ {17, "55511151231257827021181583404541015625"}, // * 18014398509481984
+ {17, "277555756156289135105907917022705078125"}, // * 36028797018963968
+ {17, "1387778780781445675529539585113525390625"}, // * 72057594037927936
+ {18, "6938893903907228377647697925567626953125"}, // * 144115188075855872
+ {18, "34694469519536141888238489627838134765625"}, // * 288230376151711744
+ {18, "173472347597680709441192448139190673828125"}, // * 576460752303423488
+ {19, "867361737988403547205962240695953369140625"}, // * 1152921504606846976
}
// Is the leading prefix of b lexicographically less than s?
@@ -228,7 +263,7 @@ func prefixIsLessThan(b []byte, s string) bool {
return false
}
-// Binary shift left (/ 2) by k bits. k <= maxShift to avoid overflow.
+// Binary shift left (* 2) by k bits. k <= maxShift to avoid overflow.
func leftShift(a *decimal, k uint) {
delta := leftcheats[k].delta
if prefixIsLessThan(a.d[0:a.nd], leftcheats[k].cutoff) {
@@ -237,11 +272,11 @@ func leftShift(a *decimal, k uint) {
r := a.nd // read index
w := a.nd + delta // write index
- n := 0
// Pick up a digit, put down a digit.
+ var n uint
for r--; r >= 0; r-- {
- n += (int(a.d[r]) - '0') << k
+ n += (uint(a.d[r]) - '0') << k
quo := n / 10
rem := n - 10*quo
w--
diff --git a/libgo/go/strconv/doc.go b/libgo/go/strconv/doc.go
new file mode 100644
index 0000000..7bc1e27
--- /dev/null
+++ b/libgo/go/strconv/doc.go
@@ -0,0 +1,57 @@
+// Copyright 2015 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 implements conversions to and from string representations
+// of basic data types.
+//
+// Numeric Conversions
+//
+// The most common numeric conversions are Atoi (string to int) and Itoa (int to string).
+//
+// i, err := strconv.Atoi("-42")
+// s := strconv.Itoa(-42)
+//
+// These assume decimal and the Go int type.
+//
+// ParseBool, ParseFloat, ParseInt, and ParseUint convert strings to values:
+//
+// b, err := strconv.ParseBool("true")
+// f, err := strconv.ParseFloat("3.1415", 64)
+// i, err := strconv.ParseInt("-42", 10, 64)
+// u, err := strconv.ParseUint("42", 10, 64)
+//
+// The parse functions return the widest type (float64, int64, and uint64),
+// but if the size argument specifies a narrower width the result can be
+// converted to that narrower type without data loss:
+//
+// s := "2147483647" // biggest int32
+// i64, err := strconv.ParseInt(s, 10, 32)
+// ...
+// i := int32(i64)
+//
+// 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)
+//
+// AppendBool, AppendFloat, AppendInt, and AppendUint are similar but
+// append the formatted value to a destination slice.
+//
+// String Conversions
+//
+// Quote and QuoteToASCII convert strings to quoted Go string literals.
+// The latter guarantees that the result is an ASCII string, by escaping
+// any non-ASCII Unicode with \u:
+//
+// q := Quote("Hello, 世界")
+// q := QuoteToASCII("Hello, 世界")
+//
+// QuoteRune and QuoteRuneToASCII are similar but accept runes and
+// return quoted Go rune literals.
+//
+// Unquote and UnquoteChar unquote Go string and rune literals.
+//
+package strconv
diff --git a/libgo/go/strconv/example_test.go b/libgo/go/strconv/example_test.go
new file mode 100644
index 0000000..01fbbc0
--- /dev/null
+++ b/libgo/go/strconv/example_test.go
@@ -0,0 +1,338 @@
+// Copyright 2015 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_test
+
+import (
+ "fmt"
+ "log"
+ "strconv"
+)
+
+func ExampleAppendBool() {
+ b := []byte("bool:")
+ b = strconv.AppendBool(b, true)
+ fmt.Println(string(b))
+
+ // Output:
+ // bool:true
+}
+
+func ExampleAppendFloat() {
+ b32 := []byte("float32:")
+ b32 = strconv.AppendFloat(b32, 3.1415926535, 'E', -1, 32)
+ fmt.Println(string(b32))
+
+ b64 := []byte("float64:")
+ b64 = strconv.AppendFloat(b64, 3.1415926535, 'E', -1, 64)
+ fmt.Println(string(b64))
+
+ // Output:
+ // float32:3.1415927E+00
+ // float64:3.1415926535E+00
+}
+
+func ExampleAppendInt() {
+ b10 := []byte("int (base 10):")
+ b10 = strconv.AppendInt(b10, -42, 10)
+ fmt.Println(string(b10))
+
+ b16 := []byte("int (base 16):")
+ b16 = strconv.AppendInt(b16, -42, 16)
+ fmt.Println(string(b16))
+
+ // Output:
+ // int (base 10):-42
+ // int (base 16):-2a
+}
+
+func ExampleAppendQuote() {
+ b := []byte("quote:")
+ b = strconv.AppendQuote(b, `"Fran & Freddie's Diner"`)
+ fmt.Println(string(b))
+
+ // Output:
+ // quote:"\"Fran & Freddie's Diner\""
+}
+
+func ExampleAppendQuoteRune() {
+ b := []byte("rune:")
+ b = strconv.AppendQuoteRune(b, '☺')
+ fmt.Println(string(b))
+
+ // Output:
+ // rune:'☺'
+}
+
+func ExampleAppendQuoteRuneToASCII() {
+ b := []byte("rune (ascii):")
+ b = strconv.AppendQuoteRuneToASCII(b, '☺')
+ fmt.Println(string(b))
+
+ // Output:
+ // rune (ascii):'\u263a'
+}
+
+func ExampleAppendQuoteToASCII() {
+ b := []byte("quote (ascii):")
+ b = strconv.AppendQuoteToASCII(b, `"Fran & Freddie's Diner"`)
+ fmt.Println(string(b))
+
+ // Output:
+ // quote (ascii):"\"Fran & Freddie's Diner\""
+}
+
+func ExampleAppendUint() {
+ b10 := []byte("uint (base 10):")
+ b10 = strconv.AppendUint(b10, 42, 10)
+ fmt.Println(string(b10))
+
+ b16 := []byte("uint (base 16):")
+ b16 = strconv.AppendUint(b16, 42, 16)
+ fmt.Println(string(b16))
+
+ // Output:
+ // uint (base 10):42
+ // uint (base 16):2a
+}
+
+func ExampleAtoi() {
+ v := "10"
+ if s, err := strconv.Atoi(v); err == nil {
+ fmt.Printf("%T, %v", s, s)
+ }
+
+ // Output:
+ // int, 10
+}
+
+func ExampleCanBackquote() {
+ fmt.Println(strconv.CanBackquote("Fran & Freddie's Diner ☺"))
+ fmt.Println(strconv.CanBackquote("`can't backquote this`"))
+
+ // Output:
+ // true
+ // false
+}
+
+func ExampleFormatBool() {
+ v := true
+ s := strconv.FormatBool(v)
+ fmt.Printf("%T, %v\n", s, s)
+
+ // Output:
+ // string, true
+}
+
+func ExampleFormatFloat() {
+ v := 3.1415926535
+
+ s32 := strconv.FormatFloat(v, 'E', -1, 32)
+ fmt.Printf("%T, %v\n", s32, s32)
+
+ s64 := strconv.FormatFloat(v, 'E', -1, 64)
+ fmt.Printf("%T, %v\n", s64, s64)
+
+ // Output:
+ // string, 3.1415927E+00
+ // string, 3.1415926535E+00
+}
+
+func ExampleFormatInt() {
+ v := int64(-42)
+
+ s10 := strconv.FormatInt(v, 10)
+ fmt.Printf("%T, %v\n", s10, s10)
+
+ s16 := strconv.FormatInt(v, 16)
+ fmt.Printf("%T, %v\n", s16, s16)
+
+ // Output:
+ // string, -42
+ // string, -2a
+}
+
+func ExampleFormatUint() {
+ v := uint64(42)
+
+ s10 := strconv.FormatUint(v, 10)
+ fmt.Printf("%T, %v\n", s10, s10)
+
+ s16 := strconv.FormatUint(v, 16)
+ fmt.Printf("%T, %v\n", s16, s16)
+
+ // Output:
+ // string, 42
+ // string, 2a
+}
+
+func ExampleIsPrint() {
+ c := strconv.IsPrint('\u263a')
+ fmt.Println(c)
+
+ bel := strconv.IsPrint('\007')
+ fmt.Println(bel)
+
+ // Output:
+ // true
+ // false
+}
+
+func ExampleItoa() {
+ i := 10
+ s := strconv.Itoa(i)
+ fmt.Printf("%T, %v\n", s, s)
+
+ // Output:
+ // string, 10
+}
+
+func ExampleParseBool() {
+ v := "true"
+ if s, err := strconv.ParseBool(v); err == nil {
+ fmt.Printf("%T, %v\n", s, s)
+ }
+
+ // Output:
+ // bool, true
+}
+
+func ExampleParseFloat() {
+ v := "3.1415926535"
+ if s, err := strconv.ParseFloat(v, 32); err == nil {
+ fmt.Printf("%T, %v\n", s, s)
+ }
+ if s, err := strconv.ParseFloat(v, 64); err == nil {
+ fmt.Printf("%T, %v\n", s, s)
+ }
+
+ // Output:
+ // float64, 3.1415927410125732
+ // float64, 3.1415926535
+}
+
+func ExampleParseInt() {
+ v32 := "-354634382"
+ if s, err := strconv.ParseInt(v32, 10, 32); err == nil {
+ fmt.Printf("%T, %v\n", s, s)
+ }
+ if s, err := strconv.ParseInt(v32, 16, 32); err == nil {
+ fmt.Printf("%T, %v\n", s, s)
+ }
+
+ v64 := "-3546343826724305832"
+ if s, err := strconv.ParseInt(v64, 10, 64); err == nil {
+ fmt.Printf("%T, %v\n", s, s)
+ }
+ if s, err := strconv.ParseInt(v64, 16, 64); err == nil {
+ fmt.Printf("%T, %v\n", s, s)
+ }
+
+ // Output:
+ // int64, -354634382
+ // int64, -3546343826724305832
+}
+
+func ExampleParseUint() {
+ v := "42"
+ if s, err := strconv.ParseUint(v, 10, 32); err == nil {
+ fmt.Printf("%T, %v\n", s, s)
+ }
+ if s, err := strconv.ParseUint(v, 10, 64); err == nil {
+ fmt.Printf("%T, %v\n", s, s)
+ }
+
+ // Output:
+ // uint64, 42
+ // uint64, 42
+}
+
+func ExampleQuote() {
+ s := strconv.Quote(`"Fran & Freddie's Diner ☺"`)
+ fmt.Println(s)
+
+ // Output:
+ // "\"Fran & Freddie's Diner\t☺\""
+}
+
+func ExampleQuoteRune() {
+ s := strconv.QuoteRune('☺')
+ fmt.Println(s)
+
+ // Output:
+ // '☺'
+}
+
+func ExampleQuoteRuneToASCII() {
+ s := strconv.QuoteRuneToASCII('☺')
+ fmt.Println(s)
+
+ // Output:
+ // '\u263a'
+}
+
+func ExampleQuoteToASCII() {
+ s := strconv.QuoteToASCII(`"Fran & Freddie's Diner ☺"`)
+ fmt.Println(s)
+
+ // Output:
+ // "\"Fran & Freddie's Diner\t\u263a\""
+}
+
+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'`)
+
+ // 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'") = ☺
+}
+
+func ExampleUnquoteChar() {
+ v, mb, t, err := strconv.UnquoteChar(`\"Fran & Freddie's Diner\"`, '"')
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Println("value:", string(v))
+ fmt.Println("multibyte:", mb)
+ fmt.Println("tail:", t)
+
+ // Output:
+ // value: "
+ // multibyte: false
+ // tail: Fran & Freddie's Diner\"
+}
+
+func ExampleNumError() {
+ str := "Not a number"
+ if _, err := strconv.ParseFloat(str, 64); err != nil {
+ e := err.(*strconv.NumError)
+ fmt.Println("Func:", e.Func)
+ fmt.Println("Num:", e.Num)
+ fmt.Println("Err:", e.Err)
+ fmt.Println(err)
+ }
+
+ // Output:
+ // Func: ParseFloat
+ // Num: Not a number
+ // Err: invalid syntax
+ // strconv.ParseFloat: parsing "Not a number": invalid syntax
+}
diff --git a/libgo/go/strconv/extfloat.go b/libgo/go/strconv/extfloat.go
index bed8b16..019b4ee 100644
--- a/libgo/go/strconv/extfloat.go
+++ b/libgo/go/strconv/extfloat.go
@@ -256,7 +256,7 @@ var uint64pow10 = [...]uint64{
}
// AssignDecimal sets f to an approximate value mantissa*10^exp. It
-// returns true if the value represented by f is guaranteed to be the
+// reports whether the value represented by f is guaranteed to be the
// best approximation of d after being rounded to a float64 or
// float32 depending on flt.
func (f *extFloat) AssignDecimal(mantissa uint64, exp10 int, neg bool, trunc bool, flt *floatInfo) (ok bool) {
diff --git a/libgo/go/strconv/ftoa.go b/libgo/go/strconv/ftoa.go
index 1a9c41b..468c37f 100644
--- a/libgo/go/strconv/ftoa.go
+++ b/libgo/go/strconv/ftoa.go
@@ -47,7 +47,7 @@ func FormatFloat(f float64, fmt byte, prec, bitSize int) string {
// AppendFloat appends the string form of the floating-point number f,
// as generated by FormatFloat, to dst and returns the extended buffer.
-func AppendFloat(dst []byte, f float64, fmt byte, prec int, bitSize int) []byte {
+func AppendFloat(dst []byte, f float64, fmt byte, prec, bitSize int) []byte {
return genericFtoa(dst, f, fmt, prec, bitSize)
}
@@ -119,7 +119,7 @@ func genericFtoa(dst []byte, val float64, fmt byte, prec, bitSize int) []byte {
// Precision for shortest representation mode.
switch fmt {
case 'e', 'E':
- prec = digs.nd - 1
+ prec = max(digs.nd-1, 0)
case 'f':
prec = max(digs.nd-digs.dp, 0)
case 'g', 'G':
@@ -223,9 +223,8 @@ func formatDigits(dst []byte, shortest bool, neg bool, digs decimalSlice, prec i
return append(dst, '%', fmt)
}
-// Round d (= mant * 2^exp) to the shortest number of digits
-// that will let the original floating point value be precisely
-// reconstructed. Size is original floating point size (64 or 32).
+// roundShortest rounds d (= mant * 2^exp) to the shortest number of digits
+// that will let the original floating point value be precisely reconstructed.
func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) {
// If mantissa is zero, the number is zero; stop now.
if mant == 0 {
@@ -348,14 +347,13 @@ func fmtE(dst []byte, neg bool, d decimalSlice, prec int, fmt byte) []byte {
if prec > 0 {
dst = append(dst, '.')
i := 1
- m := d.nd + prec + 1 - max(d.nd, prec+1)
- for i < m {
- dst = append(dst, d.d[i])
- i++
+ m := min(d.nd, prec+1)
+ if i < m {
+ dst = append(dst, d.d[i:m]...)
+ i = m
}
- for i <= prec {
+ for ; i <= prec; i++ {
dst = append(dst, '0')
- i++
}
}
@@ -373,27 +371,16 @@ func fmtE(dst []byte, neg bool, d decimalSlice, prec int, fmt byte) []byte {
}
dst = append(dst, ch)
- // dddd
- var buf [3]byte
- i := len(buf)
- for exp >= 10 {
- i--
- buf[i] = byte(exp%10 + '0')
- exp /= 10
+ // dd or ddd
+ switch {
+ case exp < 10:
+ dst = append(dst, '0', byte(exp)+'0')
+ case exp < 100:
+ dst = append(dst, byte(exp/10)+'0', byte(exp%10)+'0')
+ default:
+ dst = append(dst, byte(exp/100)+'0', byte(exp/10)%10+'0', byte(exp%10)+'0')
}
- // exp < 10
- i--
- buf[i] = byte(exp + '0')
- switch i {
- case 0:
- dst = append(dst, buf[0], buf[1], buf[2])
- case 1:
- dst = append(dst, buf[1], buf[2])
- case 2:
- // leading zeroes
- dst = append(dst, '0', buf[2])
- }
return dst
}
@@ -406,11 +393,9 @@ func fmtF(dst []byte, neg bool, d decimalSlice, prec int) []byte {
// integer, padded with zeros as needed.
if d.dp > 0 {
- var i int
- for i = 0; i < d.dp && i < d.nd; i++ {
- dst = append(dst, d.d[i])
- }
- for ; i < d.dp; i++ {
+ m := min(d.nd, d.dp)
+ dst = append(dst, d.d[:m]...)
+ for ; m < d.dp; m++ {
dst = append(dst, '0')
}
} else {
@@ -432,39 +417,34 @@ func fmtF(dst []byte, neg bool, d decimalSlice, prec int) []byte {
return dst
}
-// %b: -ddddddddp+ddd
+// %b: -ddddddddp±ddd
func fmtB(dst []byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte {
- var buf [50]byte
- w := len(buf)
- exp -= int(flt.mantbits)
- esign := byte('+')
- if exp < 0 {
- esign = '-'
- exp = -exp
- }
- n := 0
- for exp > 0 || n < 1 {
- n++
- w--
- buf[w] = byte(exp%10 + '0')
- exp /= 10
+ // sign
+ if neg {
+ dst = append(dst, '-')
}
- w--
- buf[w] = esign
- w--
- buf[w] = 'p'
- n = 0
- for mant > 0 || n < 1 {
- n++
- w--
- buf[w] = byte(mant%10 + '0')
- mant /= 10
+
+ // mantissa
+ dst, _ = formatBits(dst, mant, 10, false, true)
+
+ // p
+ dst = append(dst, 'p')
+
+ // ±exponent
+ exp -= int(flt.mantbits)
+ if exp >= 0 {
+ dst = append(dst, '+')
}
- if neg {
- w--
- buf[w] = '-'
+ dst, _ = formatBits(dst, uint64(exp), 10, exp < 0, true)
+
+ return dst
+}
+
+func min(a, b int) int {
+ if a < b {
+ return a
}
- return append(dst, buf[w:]...)
+ return b
}
func max(a, b int) int {
diff --git a/libgo/go/strconv/ftoa_test.go b/libgo/go/strconv/ftoa_test.go
index 39b8615..1b4dcd9 100644
--- a/libgo/go/strconv/ftoa_test.go
+++ b/libgo/go/strconv/ftoa_test.go
@@ -227,6 +227,7 @@ func BenchmarkAppendFloatNegExp(b *testing.B) { benchmarkAppendFloat(b, -5.11e-
func BenchmarkAppendFloatBig(b *testing.B) {
benchmarkAppendFloat(b, 123456789123456789123456789, 'g', -1, 64)
}
+func BenchmarkAppendFloatBinaryExp(b *testing.B) { benchmarkAppendFloat(b, -1, 'b', -1, 64) }
func BenchmarkAppendFloat32Integer(b *testing.B) { benchmarkAppendFloat(b, 33909, 'g', -1, 32) }
func BenchmarkAppendFloat32ExactFraction(b *testing.B) { benchmarkAppendFloat(b, 3.375, 'g', -1, 32) }
diff --git a/libgo/go/strconv/isprint.go b/libgo/go/strconv/isprint.go
index 80738ed..0cf363c 100644
--- a/libgo/go/strconv/isprint.go
+++ b/libgo/go/strconv/isprint.go
@@ -7,7 +7,7 @@
package strconv
-// (468+138+67)*2 + (326)*4 = 2650 bytes
+// (470+136+73)*2 + (342)*4 = 2726 bytes
var isPrint16 = []uint16{
0x0020, 0x007e,
@@ -26,8 +26,8 @@ var isPrint16 = []uint16{
0x0800, 0x082d,
0x0830, 0x085b,
0x085e, 0x085e,
- 0x08a0, 0x08b2,
- 0x08e4, 0x098c,
+ 0x08a0, 0x08b4,
+ 0x08e3, 0x098c,
0x098f, 0x0990,
0x0993, 0x09b2,
0x09b6, 0x09b9,
@@ -51,6 +51,7 @@ var isPrint16 = []uint16{
0x0ad0, 0x0ad0,
0x0ae0, 0x0ae3,
0x0ae6, 0x0af1,
+ 0x0af9, 0x0af9,
0x0b01, 0x0b0c,
0x0b0f, 0x0b10,
0x0b13, 0x0b39,
@@ -73,7 +74,7 @@ var isPrint16 = []uint16{
0x0be6, 0x0bfa,
0x0c00, 0x0c39,
0x0c3d, 0x0c4d,
- 0x0c55, 0x0c59,
+ 0x0c55, 0x0c5a,
0x0c60, 0x0c63,
0x0c66, 0x0c6f,
0x0c78, 0x0cb9,
@@ -84,7 +85,7 @@ var isPrint16 = []uint16{
0x0d01, 0x0d3a,
0x0d3d, 0x0d4e,
0x0d57, 0x0d57,
- 0x0d60, 0x0d63,
+ 0x0d5f, 0x0d63,
0x0d66, 0x0d75,
0x0d79, 0x0d7f,
0x0d82, 0x0d96,
@@ -117,7 +118,8 @@ var isPrint16 = []uint16{
0x1318, 0x135a,
0x135d, 0x137c,
0x1380, 0x1399,
- 0x13a0, 0x13f4,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
0x1400, 0x169c,
0x16a0, 0x16f8,
0x1700, 0x1714,
@@ -167,9 +169,9 @@ var isPrint16 = []uint16{
0x2030, 0x205e,
0x2070, 0x2071,
0x2074, 0x209c,
- 0x20a0, 0x20bd,
+ 0x20a0, 0x20be,
0x20d0, 0x20f0,
- 0x2100, 0x2189,
+ 0x2100, 0x218b,
0x2190, 0x23fa,
0x2400, 0x2426,
0x2440, 0x244a,
@@ -177,6 +179,7 @@ var isPrint16 = []uint16{
0x2b76, 0x2b95,
0x2b98, 0x2bb9,
0x2bbd, 0x2bd1,
+ 0x2bec, 0x2bef,
0x2c00, 0x2cf3,
0x2cf9, 0x2d27,
0x2d2d, 0x2d2d,
@@ -193,19 +196,19 @@ var isPrint16 = []uint16{
0x3131, 0x31ba,
0x31c0, 0x31e3,
0x31f0, 0x4db5,
- 0x4dc0, 0x9fcc,
+ 0x4dc0, 0x9fd5,
0xa000, 0xa48c,
0xa490, 0xa4c6,
0xa4d0, 0xa62b,
0xa640, 0xa6f7,
0xa700, 0xa7ad,
- 0xa7b0, 0xa7b1,
+ 0xa7b0, 0xa7b7,
0xa7f7, 0xa82b,
0xa830, 0xa839,
0xa840, 0xa877,
0xa880, 0xa8c4,
0xa8ce, 0xa8d9,
- 0xa8e0, 0xa8fb,
+ 0xa8e0, 0xa8fd,
0xa900, 0xa953,
0xa95f, 0xa97c,
0xa980, 0xa9d9,
@@ -217,9 +220,8 @@ var isPrint16 = []uint16{
0xab01, 0xab06,
0xab09, 0xab0e,
0xab11, 0xab16,
- 0xab20, 0xab5f,
- 0xab64, 0xab65,
- 0xabc0, 0xabed,
+ 0xab20, 0xab65,
+ 0xab70, 0xabed,
0xabf0, 0xabf9,
0xac00, 0xd7a3,
0xd7b0, 0xd7c6,
@@ -234,8 +236,7 @@ var isPrint16 = []uint16{
0xfd92, 0xfdc7,
0xfdf0, 0xfdfd,
0xfe00, 0xfe19,
- 0xfe20, 0xfe2d,
- 0xfe30, 0xfe6b,
+ 0xfe20, 0xfe6b,
0xfe70, 0xfefc,
0xff01, 0xffbe,
0xffc2, 0xffc7,
@@ -370,8 +371,6 @@ var isNotPrint16 = []uint16{
0x318f,
0x321f,
0x32ff,
- 0xa69e,
- 0xa78f,
0xa9ce,
0xa9ff,
0xab27,
@@ -418,12 +417,13 @@ var isPrint32 = []uint32{
0x01083c, 0x01083c,
0x01083f, 0x01089e,
0x0108a7, 0x0108af,
- 0x010900, 0x01091b,
+ 0x0108e0, 0x0108f5,
+ 0x0108fb, 0x01091b,
0x01091f, 0x010939,
0x01093f, 0x01093f,
0x010980, 0x0109b7,
- 0x0109be, 0x0109bf,
- 0x010a00, 0x010a06,
+ 0x0109bc, 0x0109cf,
+ 0x0109d2, 0x010a06,
0x010a0c, 0x010a33,
0x010a38, 0x010a3a,
0x010a3f, 0x010a47,
@@ -438,6 +438,9 @@ var isPrint32 = []uint32{
0x010b99, 0x010b9c,
0x010ba9, 0x010baf,
0x010c00, 0x010c48,
+ 0x010c80, 0x010cb2,
+ 0x010cc0, 0x010cf2,
+ 0x010cfa, 0x010cff,
0x010e60, 0x010e7e,
0x011000, 0x01104d,
0x011052, 0x01106f,
@@ -446,19 +449,19 @@ var isPrint32 = []uint32{
0x0110f0, 0x0110f9,
0x011100, 0x011143,
0x011150, 0x011176,
- 0x011180, 0x0111c8,
- 0x0111cd, 0x0111cd,
- 0x0111d0, 0x0111da,
- 0x0111e1, 0x0111f4,
+ 0x011180, 0x0111cd,
+ 0x0111d0, 0x0111f4,
0x011200, 0x01123d,
+ 0x011280, 0x0112a9,
0x0112b0, 0x0112ea,
0x0112f0, 0x0112f9,
- 0x011301, 0x01130c,
+ 0x011300, 0x01130c,
0x01130f, 0x011310,
0x011313, 0x011339,
0x01133c, 0x011344,
0x011347, 0x011348,
0x01134b, 0x01134d,
+ 0x011350, 0x011350,
0x011357, 0x011357,
0x01135d, 0x011363,
0x011366, 0x01136c,
@@ -466,17 +469,22 @@ var isPrint32 = []uint32{
0x011480, 0x0114c7,
0x0114d0, 0x0114d9,
0x011580, 0x0115b5,
- 0x0115b8, 0x0115c9,
+ 0x0115b8, 0x0115dd,
0x011600, 0x011644,
0x011650, 0x011659,
0x011680, 0x0116b7,
0x0116c0, 0x0116c9,
+ 0x011700, 0x011719,
+ 0x01171d, 0x01172b,
+ 0x011730, 0x01173f,
0x0118a0, 0x0118f2,
0x0118ff, 0x0118ff,
0x011ac0, 0x011af8,
- 0x012000, 0x012398,
+ 0x012000, 0x012399,
0x012400, 0x012474,
+ 0x012480, 0x012543,
0x013000, 0x01342e,
+ 0x014400, 0x014646,
0x016800, 0x016a38,
0x016a40, 0x016a69,
0x016a6e, 0x016a6f,
@@ -497,7 +505,7 @@ var isPrint32 = []uint32{
0x01d000, 0x01d0f5,
0x01d100, 0x01d126,
0x01d129, 0x01d172,
- 0x01d17b, 0x01d1dd,
+ 0x01d17b, 0x01d1e8,
0x01d200, 0x01d245,
0x01d300, 0x01d356,
0x01d360, 0x01d371,
@@ -508,7 +516,8 @@ var isPrint32 = []uint32{
0x01d50d, 0x01d546,
0x01d54a, 0x01d6a5,
0x01d6a8, 0x01d7cb,
- 0x01d7ce, 0x01d7ff,
+ 0x01d7ce, 0x01da8b,
+ 0x01da9b, 0x01daaf,
0x01e800, 0x01e8c4,
0x01e8c7, 0x01e8d6,
0x01ee00, 0x01ee24,
@@ -530,13 +539,7 @@ var isPrint32 = []uint32{
0x01f210, 0x01f23a,
0x01f240, 0x01f248,
0x01f250, 0x01f251,
- 0x01f300, 0x01f32c,
- 0x01f330, 0x01f37d,
- 0x01f380, 0x01f3ce,
- 0x01f3d4, 0x01f3f7,
- 0x01f400, 0x01f54a,
- 0x01f550, 0x01f642,
- 0x01f645, 0x01f6cf,
+ 0x01f300, 0x01f6d0,
0x01f6e0, 0x01f6ec,
0x01f6f0, 0x01f6f3,
0x01f700, 0x01f773,
@@ -546,9 +549,13 @@ var isPrint32 = []uint32{
0x01f850, 0x01f859,
0x01f860, 0x01f887,
0x01f890, 0x01f8ad,
+ 0x01f910, 0x01f918,
+ 0x01f980, 0x01f984,
+ 0x01f9c0, 0x01f9c0,
0x020000, 0x02a6d6,
0x02a700, 0x02b734,
0x02b740, 0x02b81d,
+ 0x02b820, 0x02cea1,
0x02f800, 0x02fa1d,
0x0e0100, 0x0e01ef,
}
@@ -562,12 +569,18 @@ var isNotPrint32 = []uint16{ // add 0x10000 to each entry
0x0809,
0x0836,
0x0856,
+ 0x08f3,
0x0a04,
0x0a14,
0x0a18,
0x10bd,
0x1135,
+ 0x11e0,
0x1212,
+ 0x1287,
+ 0x1289,
+ 0x128e,
+ 0x129e,
0x1304,
0x1329,
0x1331,
@@ -589,6 +602,7 @@ var isNotPrint32 = []uint16{ // add 0x10000 to each entry
0xd53f,
0xd545,
0xd551,
+ 0xdaa0,
0xee04,
0xee20,
0xee23,
@@ -618,7 +632,6 @@ var isNotPrint32 = []uint16{ // add 0x10000 to each entry
0xf0c0,
0xf0d0,
0xf12f,
- 0xf4ff,
0xf57a,
0xf5a4,
}
diff --git a/libgo/go/strconv/itoa.go b/libgo/go/strconv/itoa.go
index 67f17d8..e6f6303 100644
--- a/libgo/go/strconv/itoa.go
+++ b/libgo/go/strconv/itoa.go
@@ -40,9 +40,7 @@ func AppendUint(dst []byte, i uint64, base int) []byte {
}
const (
- digits = "0123456789abcdefghijklmnopqrstuvwxyz"
- digits01 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
- digits10 = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999"
+ digits = "0123456789abcdefghijklmnopqrstuvwxyz"
)
var shifts = [len(digits) + 1]uint{
@@ -74,23 +72,34 @@ func formatBits(dst []byte, u uint64, base int, neg, append_ bool) (d []byte, s
// convert bits
if base == 10 {
- // common case: use constants for / and % because
- // the compiler can optimize it into a multiply+shift,
- // and unroll loop
- for u >= 100 {
- i -= 2
- q := u / 100
- j := uintptr(u - q*100)
- a[i+1] = digits01[j]
- a[i+0] = digits10[j]
- u = q
+ // common case: use constants for / because
+ // the compiler can optimize it into a multiply+shift
+
+ if ^uintptr(0)>>32 == 0 {
+ for u > uint64(^uintptr(0)) {
+ q := u / 1e9
+ us := uintptr(u - q*1e9) // us % 1e9 fits into a uintptr
+ for j := 9; j > 0; j-- {
+ i--
+ qs := us / 10
+ a[i] = byte(us - qs*10 + '0')
+ us = qs
+ }
+ u = q
+ }
}
- if u >= 10 {
+
+ // u guaranteed to fit into a uintptr
+ us := uintptr(u)
+ for us >= 10 {
i--
- q := u / 10
- a[i] = digits[uintptr(u-q*10)]
- u = q
+ q := us / 10
+ a[i] = byte(us - q*10 + '0')
+ us = q
}
+ // u < 10
+ i--
+ a[i] = byte(us + '0')
} else if s := shifts[base]; s > 0 {
// base is power of 2: use shifts and masks instead of / and %
@@ -101,21 +110,24 @@ func formatBits(dst []byte, u uint64, base int, neg, append_ bool) (d []byte, s
a[i] = digits[uintptr(u)&m]
u >>= s
}
+ // u < base
+ i--
+ a[i] = digits[uintptr(u)]
} else {
// general case
b := uint64(base)
for u >= b {
i--
- a[i] = digits[uintptr(u%b)]
- u /= b
+ q := u / b
+ a[i] = digits[uintptr(u-q*b)]
+ u = q
}
+ // u < base
+ i--
+ a[i] = digits[uintptr(u)]
}
- // u < base
- i--
- a[i] = digits[uintptr(u)]
-
// add sign, if any
if neg {
i--
diff --git a/libgo/go/strconv/itoa_test.go b/libgo/go/strconv/itoa_test.go
index e0213ae..48dc03e 100644
--- a/libgo/go/strconv/itoa_test.go
+++ b/libgo/go/strconv/itoa_test.go
@@ -51,6 +51,7 @@ var itob64tests = []itob64Test{
{-0x123456789abcdef, 16, "-123456789abcdef"},
{1<<63 - 1, 16, "7fffffffffffffff"},
{1<<63 - 1, 2, "111111111111111111111111111111111111111111111111111111111111111"},
+ {-1 << 63, 2, "-1000000000000000000000000000000000000000000000000000000000000000"},
{16, 17, "g"},
{25, 25, "10"},
diff --git a/libgo/go/strconv/quote_example_test.go b/libgo/go/strconv/quote_example_test.go
deleted file mode 100644
index 405a57e..0000000
--- a/libgo/go/strconv/quote_example_test.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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.
-
-package strconv_test
-
-import (
- "fmt"
- "strconv"
-)
-
-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 := `cafe\u0301`
- // If the string doesn't have quotes, it can't be unquoted.
- test(s) // invalid syntax
- test("`" + s + "`")
- test(`"` + s + `"`)
-
- test(`'\u00e9'`)
-
- // Output:
- // Unquote("cafe\\u0301"): invalid syntax
- // Unquote("`cafe\\u0301`") = cafe\u0301
- // Unquote("\"cafe\\u0301\"") = café
- // Unquote("'\\u00e9'") = é
-}