aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/strconv
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2016-07-22 18:15:38 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2016-07-22 18:15:38 +0000
commit22b955cca564a9a3a5b8c9d9dd1e295b7943c128 (patch)
treeabdbd898676e1f853fca2d7e031d105d7ebcf676 /libgo/go/strconv
parent9d04a3af4c6491536badf6bde9707c907e4d196b (diff)
downloadgcc-22b955cca564a9a3a5b8c9d9dd1e295b7943c128.zip
gcc-22b955cca564a9a3a5b8c9d9dd1e295b7943c128.tar.gz
gcc-22b955cca564a9a3a5b8c9d9dd1e295b7943c128.tar.bz2
libgo: update to go1.7rc3
Reviewed-on: https://go-review.googlesource.com/25150 From-SVN: r238662
Diffstat (limited to 'libgo/go/strconv')
-rw-r--r--libgo/go/strconv/atob.go2
-rw-r--r--libgo/go/strconv/atof.go13
-rw-r--r--libgo/go/strconv/atof_test.go26
-rw-r--r--libgo/go/strconv/atoi.go14
-rw-r--r--libgo/go/strconv/atoi_test.go2
-rw-r--r--libgo/go/strconv/extfloat.go4
-rw-r--r--libgo/go/strconv/fp_test.go2
-rw-r--r--libgo/go/strconv/ftoa.go2
-rw-r--r--libgo/go/strconv/ftoa_test.go85
-rw-r--r--libgo/go/strconv/isprint.go82
-rw-r--r--libgo/go/strconv/makeisprint.go2
-rw-r--r--libgo/go/strconv/quote.go150
-rw-r--r--libgo/go/strconv/quote_test.go28
13 files changed, 250 insertions, 162 deletions
diff --git a/libgo/go/strconv/atob.go b/libgo/go/strconv/atob.go
index d0cb097..879ceb3 100644
--- a/libgo/go/strconv/atob.go
+++ b/libgo/go/strconv/atob.go
@@ -7,7 +7,7 @@ package strconv
// ParseBool returns the boolean value represented by the string.
// It accepts 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False.
// Any other value returns an error.
-func ParseBool(str string) (value bool, err error) {
+func ParseBool(str string) (bool, error) {
switch str {
case "1", "t", "T", "true", "TRUE", "True":
return true, nil
diff --git a/libgo/go/strconv/atof.go b/libgo/go/strconv/atof.go
index a4f4862..fdcb8b3 100644
--- a/libgo/go/strconv/atof.go
+++ b/libgo/go/strconv/atof.go
@@ -245,7 +245,9 @@ func readFloat(s string) (mantissa uint64, exp int, neg, trunc, ok bool) {
return
}
- exp = dp - ndMant
+ if mantissa != 0 {
+ exp = dp - ndMant
+ }
ok = true
return
@@ -534,11 +536,10 @@ func atof64(s string) (f float64, err error) {
// If s is syntactically well-formed but is more than 1/2 ULP
// away from the largest floating point number of the given size,
// ParseFloat returns f = ±Inf, err.Err = ErrRange.
-func ParseFloat(s string, bitSize int) (f float64, err error) {
+func ParseFloat(s string, bitSize int) (float64, error) {
if bitSize == 32 {
- f1, err1 := atof32(s)
- return float64(f1), err1
+ f, err := atof32(s)
+ return float64(f), err
}
- f1, err1 := atof64(s)
- return f1, err1
+ return atof64(s)
}
diff --git a/libgo/go/strconv/atof_test.go b/libgo/go/strconv/atof_test.go
index ba493321..0a89c3e 100644
--- a/libgo/go/strconv/atof_test.go
+++ b/libgo/go/strconv/atof_test.go
@@ -42,6 +42,30 @@ var atoftests = []atofTest{
{"1e-20", "1e-20", nil},
{"625e-3", "0.625", nil},
+ // zeros
+ {"0", "0", nil},
+ {"0e0", "0", nil},
+ {"-0e0", "-0", nil},
+ {"+0e0", "0", nil},
+ {"0e-0", "0", nil},
+ {"-0e-0", "-0", nil},
+ {"+0e-0", "0", nil},
+ {"0e+0", "0", nil},
+ {"-0e+0", "-0", nil},
+ {"+0e+0", "0", nil},
+ {"0e+01234567890123456789", "0", nil},
+ {"0.00e-01234567890123456789", "0", nil},
+ {"-0e+01234567890123456789", "-0", nil},
+ {"-0.00e-01234567890123456789", "-0", nil},
+ {"0e291", "0", nil}, // issue 15364
+ {"0e292", "0", nil}, // issue 15364
+ {"0e347", "0", nil}, // issue 15364
+ {"0e348", "0", nil}, // issue 15364
+ {"-0e291", "-0", nil},
+ {"-0e292", "-0", nil},
+ {"-0e347", "-0", nil},
+ {"-0e348", "-0", nil},
+
// NaNs
{"nan", "NaN", nil},
{"NaN", "NaN", nil},
@@ -196,7 +220,7 @@ var (
func init() {
// The atof routines return NumErrors wrapping
- // the error and the string. Convert the table above.
+ // the error and the string. Convert the table above.
for i := range atoftests {
test := &atoftests[i]
if test.err != nil {
diff --git a/libgo/go/strconv/atoi.go b/libgo/go/strconv/atoi.go
index 965e3a2..a236de4 100644
--- a/libgo/go/strconv/atoi.go
+++ b/libgo/go/strconv/atoi.go
@@ -39,7 +39,9 @@ const IntSize = intSize
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) {
+func ParseUint(s string, base int, bitSize int) (uint64, error) {
+ var n uint64
+ var err error
var cutoff, maxVal uint64
if bitSize == 0 {
@@ -136,16 +138,16 @@ Error:
}
// ParseInt interprets a string s in the given base (2 to 36) and
-// returns the corresponding value i. If base == 0, the base is
+// 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.
//
// The bitSize argument specifies the integer type
-// that the result must fit into. Bit sizes 0, 8, 16, 32, and 64
+// that the result must fit into. Bit sizes 0, 8, 16, 32, and 64
// correspond to int, int8, int16, int32, and int64.
//
// The errors that ParseInt returns have concrete type *NumError
-// and include err.Num = s. If s is empty or contains invalid
+// and include err.Num = s. If s is empty or contains invalid
// digits, err.Err = ErrSyntax and the returned value is 0;
// if the value corresponding to s cannot be represented by a
// signed integer of the given size, err.Err = ErrRange and the
@@ -195,8 +197,8 @@ func ParseInt(s string, base int, bitSize int) (i int64, err error) {
return n, nil
}
-// Atoi is shorthand for ParseInt(s, 10, 0).
-func Atoi(s string) (i int, err error) {
+// Atoi returns the result of ParseInt(s, 10, 0) converted to type int.
+func Atoi(s string) (int, error) {
i64, err := ParseInt(s, 10, 0)
return int(i64), err
}
diff --git a/libgo/go/strconv/atoi_test.go b/libgo/go/strconv/atoi_test.go
index bd6a6a0..d608505 100644
--- a/libgo/go/strconv/atoi_test.go
+++ b/libgo/go/strconv/atoi_test.go
@@ -196,7 +196,7 @@ var numErrorTests = []numErrorTest{
func init() {
// The atoi routines return NumErrors wrapping
- // the error and the string. Convert the tables above.
+ // the error and the string. Convert the tables above.
for i := range atoui64tests {
test := &atoui64tests[i]
if test.err != nil {
diff --git a/libgo/go/strconv/extfloat.go b/libgo/go/strconv/extfloat.go
index 019b4ee..7033e96 100644
--- a/libgo/go/strconv/extfloat.go
+++ b/libgo/go/strconv/extfloat.go
@@ -311,9 +311,9 @@ func (f *extFloat) AssignDecimal(mantissa uint64, exp10 int, neg bool, trunc boo
var extrabits uint
if f.exp <= denormalExp {
// f.mant * 2^f.exp is smaller than 2^(flt.bias+1).
- extrabits = uint(63 - flt.mantbits + 1 + uint(denormalExp-f.exp))
+ extrabits = 63 - flt.mantbits + 1 + uint(denormalExp-f.exp)
} else {
- extrabits = uint(63 - flt.mantbits)
+ extrabits = 63 - flt.mantbits
}
halfway := uint64(1) << (extrabits - 1)
diff --git a/libgo/go/strconv/fp_test.go b/libgo/go/strconv/fp_test.go
index 6de2f8b..39dd9c4 100644
--- a/libgo/go/strconv/fp_test.go
+++ b/libgo/go/strconv/fp_test.go
@@ -41,7 +41,7 @@ func myatof64(s string) (f float64, ok bool) {
}
v := float64(n)
// We expect that v*pow2(e) fits in a float64,
- // but pow2(e) by itself may not. Be careful.
+ // but pow2(e) by itself may not. Be careful.
if e <= -1000 {
v *= pow2(-1000)
e += 1000
diff --git a/libgo/go/strconv/ftoa.go b/libgo/go/strconv/ftoa.go
index 9ff5d10..8b3d33e 100644
--- a/libgo/go/strconv/ftoa.go
+++ b/libgo/go/strconv/ftoa.go
@@ -23,7 +23,7 @@ var float32info = floatInfo{23, 8, -127}
var float64info = floatInfo{52, 11, -1023}
// FormatFloat converts the floating-point number f to a string,
-// according to the format fmt and precision prec. It rounds the
+// according to the format fmt and precision prec. It rounds the
// result assuming that the original was obtained from a floating-point
// value of bitSize bits (32 for float32, 64 for float64).
//
diff --git a/libgo/go/strconv/ftoa_test.go b/libgo/go/strconv/ftoa_test.go
index 0b9f0fe..1d25242 100644
--- a/libgo/go/strconv/ftoa_test.go
+++ b/libgo/go/strconv/ftoa_test.go
@@ -183,59 +183,50 @@ func TestFtoaRandom(t *testing.T) {
}
}
-func BenchmarkFormatFloatDecimal(b *testing.B) {
- for i := 0; i < b.N; i++ {
- FormatFloat(33909, 'g', -1, 64)
- }
+var ftoaBenches = []struct {
+ name string
+ float float64
+ fmt byte
+ prec int
+ bitSize int
+}{
+ {"Decimal", 33909, 'g', -1, 64},
+ {"Float", 339.7784, 'g', -1, 64},
+ {"Exp", -5.09e75, 'g', -1, 64},
+ {"NegExp", -5.11e-95, 'g', -1, 64},
+
+ {"Big", 123456789123456789123456789, 'g', -1, 64},
+ {"BinaryExp", -1, 'b', -1, 64},
+
+ {"32Integer", 33909, 'g', -1, 32},
+ {"32ExactFraction", 3.375, 'g', -1, 32},
+ {"32Point", 339.7784, 'g', -1, 32},
+ {"32Exp", -5.09e25, 'g', -1, 32},
+ {"32NegExp", -5.11e-25, 'g', -1, 32},
+
+ {"64Fixed1", 123456, 'e', 3, 64},
+ {"64Fixed2", 123.456, 'e', 3, 64},
+ {"64Fixed3", 1.23456e+78, 'e', 3, 64},
+ {"64Fixed4", 1.23456e-78, 'e', 3, 64},
}
func BenchmarkFormatFloat(b *testing.B) {
- for i := 0; i < b.N; i++ {
- FormatFloat(339.7784, 'g', -1, 64)
- }
-}
-
-func BenchmarkFormatFloatExp(b *testing.B) {
- for i := 0; i < b.N; i++ {
- FormatFloat(-5.09e75, 'g', -1, 64)
- }
-}
-
-func BenchmarkFormatFloatNegExp(b *testing.B) {
- for i := 0; i < b.N; i++ {
- FormatFloat(-5.11e-95, 'g', -1, 64)
- }
-}
-
-func BenchmarkFormatFloatBig(b *testing.B) {
- for i := 0; i < b.N; i++ {
- FormatFloat(123456789123456789123456789, 'g', -1, 64)
+ for _, c := range ftoaBenches {
+ b.Run(c.name, func(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ FormatFloat(c.float, c.fmt, c.prec, c.bitSize)
+ }
+ })
}
}
-func benchmarkAppendFloat(b *testing.B, f float64, fmt byte, prec, bitSize int) {
+func BenchmarkAppendFloat(b *testing.B) {
dst := make([]byte, 30)
- for i := 0; i < b.N; i++ {
- AppendFloat(dst[:0], f, fmt, prec, bitSize)
+ for _, c := range ftoaBenches {
+ b.Run(c.name, func(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ AppendFloat(dst[:0], c.float, c.fmt, c.prec, c.bitSize)
+ }
+ })
}
}
-
-func BenchmarkAppendFloatDecimal(b *testing.B) { benchmarkAppendFloat(b, 33909, 'g', -1, 64) }
-func BenchmarkAppendFloat(b *testing.B) { benchmarkAppendFloat(b, 339.7784, 'g', -1, 64) }
-func BenchmarkAppendFloatExp(b *testing.B) { benchmarkAppendFloat(b, -5.09e75, 'g', -1, 64) }
-func BenchmarkAppendFloatNegExp(b *testing.B) { benchmarkAppendFloat(b, -5.11e-95, 'g', -1, 64) }
-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) }
-func BenchmarkAppendFloat32Point(b *testing.B) { benchmarkAppendFloat(b, 339.7784, 'g', -1, 32) }
-func BenchmarkAppendFloat32Exp(b *testing.B) { benchmarkAppendFloat(b, -5.09e25, 'g', -1, 32) }
-func BenchmarkAppendFloat32NegExp(b *testing.B) { benchmarkAppendFloat(b, -5.11e-25, 'g', -1, 32) }
-
-func BenchmarkAppendFloat64Fixed1(b *testing.B) { benchmarkAppendFloat(b, 123456, 'e', 3, 64) }
-func BenchmarkAppendFloat64Fixed2(b *testing.B) { benchmarkAppendFloat(b, 123.456, 'e', 3, 64) }
-func BenchmarkAppendFloat64Fixed3(b *testing.B) { benchmarkAppendFloat(b, 1.23456e+78, 'e', 3, 64) }
-func BenchmarkAppendFloat64Fixed4(b *testing.B) { benchmarkAppendFloat(b, 1.23456e-78, 'e', 3, 64) }
diff --git a/libgo/go/strconv/isprint.go b/libgo/go/strconv/isprint.go
index 20a02de..a30d8d8 100644
--- a/libgo/go/strconv/isprint.go
+++ b/libgo/go/strconv/isprint.go
@@ -7,7 +7,7 @@
package strconv
-// (470+136+73)*2 + (342)*4 = 2726 bytes
+// (462+139+82)*2 + (378)*4 = 2878 bytes
var isPrint16 = []uint16{
0x0020, 0x007e,
@@ -26,8 +26,8 @@ var isPrint16 = []uint16{
0x0800, 0x082d,
0x0830, 0x085b,
0x085e, 0x085e,
- 0x08a0, 0x08b4,
- 0x08e3, 0x098c,
+ 0x08a0, 0x08bd,
+ 0x08d4, 0x098c,
0x098f, 0x0990,
0x0993, 0x09b2,
0x09b6, 0x09b9,
@@ -83,11 +83,9 @@ var isPrint16 = []uint16{
0x0cde, 0x0ce3,
0x0ce6, 0x0cf2,
0x0d01, 0x0d3a,
- 0x0d3d, 0x0d4e,
- 0x0d57, 0x0d57,
- 0x0d5f, 0x0d63,
- 0x0d66, 0x0d75,
- 0x0d79, 0x0d7f,
+ 0x0d3d, 0x0d4f,
+ 0x0d54, 0x0d63,
+ 0x0d66, 0x0d7f,
0x0d82, 0x0d96,
0x0d9a, 0x0dbd,
0x0dc0, 0x0dc6,
@@ -153,11 +151,11 @@ var isPrint16 = []uint16{
0x1b80, 0x1bf3,
0x1bfc, 0x1c37,
0x1c3b, 0x1c49,
- 0x1c4d, 0x1c7f,
+ 0x1c4d, 0x1c88,
0x1cc0, 0x1cc7,
0x1cd0, 0x1cf9,
0x1d00, 0x1df5,
- 0x1dfc, 0x1f15,
+ 0x1dfb, 0x1f15,
0x1f18, 0x1f1d,
0x1f20, 0x1f45,
0x1f48, 0x1f4d,
@@ -172,8 +170,7 @@ var isPrint16 = []uint16{
0x20a0, 0x20be,
0x20d0, 0x20f0,
0x2100, 0x218b,
- 0x2190, 0x23fa,
- 0x2400, 0x2426,
+ 0x2190, 0x2426,
0x2440, 0x244a,
0x2460, 0x2b73,
0x2b76, 0x2b95,
@@ -186,7 +183,7 @@ var isPrint16 = []uint16{
0x2d30, 0x2d67,
0x2d6f, 0x2d70,
0x2d7f, 0x2d96,
- 0x2da0, 0x2e42,
+ 0x2da0, 0x2e44,
0x2e80, 0x2ef3,
0x2f00, 0x2fd5,
0x2ff0, 0x2ffb,
@@ -201,12 +198,11 @@ var isPrint16 = []uint16{
0xa490, 0xa4c6,
0xa4d0, 0xa62b,
0xa640, 0xa6f7,
- 0xa700, 0xa7ad,
- 0xa7b0, 0xa7b7,
+ 0xa700, 0xa7b7,
0xa7f7, 0xa82b,
0xa830, 0xa839,
0xa840, 0xa877,
- 0xa880, 0xa8c4,
+ 0xa880, 0xa8c5,
0xa8ce, 0xa8d9,
0xa8e0, 0xa8fd,
0xa900, 0xa953,
@@ -258,6 +254,8 @@ var isNotPrint16 = []uint16{
0x0590,
0x06dd,
0x083f,
+ 0x08b5,
+ 0x08e2,
0x0984,
0x09a9,
0x09b1,
@@ -294,7 +292,6 @@ var isNotPrint16 = []uint16{
0x0c45,
0x0c49,
0x0c57,
- 0x0c80,
0x0c84,
0x0c8d,
0x0c91,
@@ -354,6 +351,7 @@ var isNotPrint16 = []uint16{
0x1fdc,
0x1ff5,
0x208f,
+ 0x23ff,
0x2bc9,
0x2c2f,
0x2c5f,
@@ -371,6 +369,7 @@ var isNotPrint16 = []uint16{
0x318f,
0x321f,
0x32ff,
+ 0xa7af,
0xa9ce,
0xa9ff,
0xab27,
@@ -392,8 +391,7 @@ var isPrint32 = []uint32{
0x010080, 0x0100fa,
0x010100, 0x010102,
0x010107, 0x010133,
- 0x010137, 0x01018c,
- 0x010190, 0x01019b,
+ 0x010137, 0x01019b,
0x0101a0, 0x0101a0,
0x0101d0, 0x0101fd,
0x010280, 0x01029c,
@@ -406,6 +404,8 @@ var isPrint32 = []uint32{
0x0103c8, 0x0103d5,
0x010400, 0x01049d,
0x0104a0, 0x0104a9,
+ 0x0104b0, 0x0104d3,
+ 0x0104d8, 0x0104fb,
0x010500, 0x010527,
0x010530, 0x010563,
0x01056f, 0x01056f,
@@ -451,7 +451,7 @@ var isPrint32 = []uint32{
0x011150, 0x011176,
0x011180, 0x0111cd,
0x0111d0, 0x0111f4,
- 0x011200, 0x01123d,
+ 0x011200, 0x01123e,
0x011280, 0x0112a9,
0x0112b0, 0x0112ea,
0x0112f0, 0x0112f9,
@@ -466,12 +466,14 @@ var isPrint32 = []uint32{
0x01135d, 0x011363,
0x011366, 0x01136c,
0x011370, 0x011374,
+ 0x011400, 0x01145d,
0x011480, 0x0114c7,
0x0114d0, 0x0114d9,
0x011580, 0x0115b5,
0x0115b8, 0x0115dd,
0x011600, 0x011644,
0x011650, 0x011659,
+ 0x011660, 0x01166c,
0x011680, 0x0116b7,
0x0116c0, 0x0116c9,
0x011700, 0x011719,
@@ -480,6 +482,10 @@ var isPrint32 = []uint32{
0x0118a0, 0x0118f2,
0x0118ff, 0x0118ff,
0x011ac0, 0x011af8,
+ 0x011c00, 0x011c45,
+ 0x011c50, 0x011c6c,
+ 0x011c70, 0x011c8f,
+ 0x011c92, 0x011cb6,
0x012000, 0x012399,
0x012400, 0x012474,
0x012480, 0x012543,
@@ -496,6 +502,9 @@ var isPrint32 = []uint32{
0x016f00, 0x016f44,
0x016f50, 0x016f7e,
0x016f8f, 0x016f9f,
+ 0x016fe0, 0x016fe0,
+ 0x017000, 0x0187ec,
+ 0x018800, 0x018af2,
0x01b000, 0x01b001,
0x01bc00, 0x01bc6a,
0x01bc70, 0x01bc7c,
@@ -518,8 +527,13 @@ var isPrint32 = []uint32{
0x01d6a8, 0x01d7cb,
0x01d7ce, 0x01da8b,
0x01da9b, 0x01daaf,
+ 0x01e000, 0x01e018,
+ 0x01e01b, 0x01e02a,
0x01e800, 0x01e8c4,
0x01e8c7, 0x01e8d6,
+ 0x01e900, 0x01e94a,
+ 0x01e950, 0x01e959,
+ 0x01e95e, 0x01e95f,
0x01ee00, 0x01ee24,
0x01ee27, 0x01ee3b,
0x01ee42, 0x01ee42,
@@ -534,14 +548,14 @@ var isPrint32 = []uint32{
0x01f0b1, 0x01f0f5,
0x01f100, 0x01f10c,
0x01f110, 0x01f16b,
- 0x01f170, 0x01f19a,
+ 0x01f170, 0x01f1ac,
0x01f1e6, 0x01f202,
- 0x01f210, 0x01f23a,
+ 0x01f210, 0x01f23b,
0x01f240, 0x01f248,
0x01f250, 0x01f251,
- 0x01f300, 0x01f6d0,
+ 0x01f300, 0x01f6d2,
0x01f6e0, 0x01f6ec,
- 0x01f6f0, 0x01f6f3,
+ 0x01f6f0, 0x01f6f6,
0x01f700, 0x01f773,
0x01f780, 0x01f7d4,
0x01f800, 0x01f80b,
@@ -549,8 +563,11 @@ var isPrint32 = []uint32{
0x01f850, 0x01f859,
0x01f860, 0x01f887,
0x01f890, 0x01f8ad,
- 0x01f910, 0x01f918,
- 0x01f980, 0x01f984,
+ 0x01f910, 0x01f927,
+ 0x01f930, 0x01f930,
+ 0x01f933, 0x01f94b,
+ 0x01f950, 0x01f95e,
+ 0x01f980, 0x01f991,
0x01f9c0, 0x01f9c0,
0x020000, 0x02a6d6,
0x02a700, 0x02b734,
@@ -565,6 +582,7 @@ var isNotPrint32 = []uint16{ // add 0x10000 to each entry
0x0027,
0x003b,
0x003e,
+ 0x018f,
0x039e,
0x0809,
0x0836,
@@ -585,6 +603,11 @@ var isNotPrint32 = []uint16{ // add 0x10000 to each entry
0x1329,
0x1331,
0x1334,
+ 0x145a,
+ 0x145c,
+ 0x1c09,
+ 0x1c37,
+ 0x1ca8,
0x246f,
0x6a5f,
0x6b5a,
@@ -603,6 +626,9 @@ var isNotPrint32 = []uint16{ // add 0x10000 to each entry
0xd545,
0xd551,
0xdaa0,
+ 0xe007,
+ 0xe022,
+ 0xe025,
0xee04,
0xee20,
0xee23,
@@ -632,8 +658,8 @@ var isNotPrint32 = []uint16{ // add 0x10000 to each entry
0xf0c0,
0xf0d0,
0xf12f,
- 0xf57a,
- 0xf5a4,
+ 0xf91f,
+ 0xf93f,
}
// isGraphic lists the graphic runes not matched by IsPrint.
diff --git a/libgo/go/strconv/makeisprint.go b/libgo/go/strconv/makeisprint.go
index 5142580..0a3e5b2 100644
--- a/libgo/go/strconv/makeisprint.go
+++ b/libgo/go/strconv/makeisprint.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2012 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.
diff --git a/libgo/go/strconv/quote.go b/libgo/go/strconv/quote.go
index 40d0667..becfe1d 100644
--- a/libgo/go/strconv/quote.go
+++ b/libgo/go/strconv/quote.go
@@ -6,15 +6,19 @@
package strconv
-import (
- "unicode/utf8"
-)
+import "unicode/utf8"
const lowerhex = "0123456789abcdef"
func quoteWith(s string, quote byte, ASCIIonly, graphicOnly bool) string {
- var runeTmp [utf8.UTFMax]byte
- buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations.
+ return string(appendQuotedWith(make([]byte, 0, 3*len(s)/2), s, quote, ASCIIonly, graphicOnly))
+}
+
+func quoteRuneWith(r rune, quote byte, ASCIIonly, graphicOnly bool) string {
+ return string(appendQuotedRuneWith(nil, r, quote, ASCIIonly, graphicOnly))
+}
+
+func appendQuotedWith(buf []byte, s string, quote byte, ASCIIonly, graphicOnly bool) []byte {
buf = append(buf, quote)
for width := 0; len(s) > 0; s = s[width:] {
r := rune(s[0])
@@ -28,64 +32,79 @@ func quoteWith(s string, quote byte, ASCIIonly, graphicOnly bool) string {
buf = append(buf, lowerhex[s[0]&0xF])
continue
}
- if r == rune(quote) || r == '\\' { // always backslashed
- buf = append(buf, '\\')
+ buf = appendEscapedRune(buf, r, width, quote, ASCIIonly, graphicOnly)
+ }
+ buf = append(buf, quote)
+ return buf
+}
+
+func appendQuotedRuneWith(buf []byte, r rune, quote byte, ASCIIonly, graphicOnly bool) []byte {
+ buf = append(buf, quote)
+ if !utf8.ValidRune(r) {
+ r = utf8.RuneError
+ }
+ buf = appendEscapedRune(buf, r, utf8.RuneLen(r), quote, ASCIIonly, graphicOnly)
+ buf = append(buf, quote)
+ return buf
+}
+
+func appendEscapedRune(buf []byte, r rune, width int, quote byte, ASCIIonly, graphicOnly bool) []byte {
+ var runeTmp [utf8.UTFMax]byte
+ if r == rune(quote) || r == '\\' { // always backslashed
+ buf = append(buf, '\\')
+ buf = append(buf, byte(r))
+ return buf
+ }
+ if ASCIIonly {
+ if r < utf8.RuneSelf && IsPrint(r) {
buf = append(buf, byte(r))
- continue
+ return buf
}
- if ASCIIonly {
- if r < utf8.RuneSelf && IsPrint(r) {
- buf = append(buf, byte(r))
- continue
+ } else if IsPrint(r) || graphicOnly && isInGraphicList(r) {
+ n := utf8.EncodeRune(runeTmp[:], r)
+ buf = append(buf, runeTmp[:n]...)
+ return buf
+ }
+ switch r {
+ case '\a':
+ buf = append(buf, `\a`...)
+ case '\b':
+ buf = append(buf, `\b`...)
+ case '\f':
+ buf = append(buf, `\f`...)
+ case '\n':
+ buf = append(buf, `\n`...)
+ case '\r':
+ buf = append(buf, `\r`...)
+ case '\t':
+ buf = append(buf, `\t`...)
+ case '\v':
+ buf = append(buf, `\v`...)
+ default:
+ switch {
+ case r < ' ':
+ buf = append(buf, `\x`...)
+ buf = append(buf, lowerhex[byte(r)>>4])
+ buf = append(buf, lowerhex[byte(r)&0xF])
+ case r > utf8.MaxRune:
+ r = 0xFFFD
+ fallthrough
+ case r < 0x10000:
+ buf = append(buf, `\u`...)
+ for s := 12; s >= 0; s -= 4 {
+ buf = append(buf, lowerhex[r>>uint(s)&0xF])
}
- } else if IsPrint(r) || graphicOnly && isInGraphicList(r) {
- n := utf8.EncodeRune(runeTmp[:], r)
- buf = append(buf, runeTmp[:n]...)
- continue
- }
- switch r {
- case '\a':
- buf = append(buf, `\a`...)
- case '\b':
- buf = append(buf, `\b`...)
- case '\f':
- buf = append(buf, `\f`...)
- case '\n':
- buf = append(buf, `\n`...)
- case '\r':
- buf = append(buf, `\r`...)
- case '\t':
- buf = append(buf, `\t`...)
- case '\v':
- buf = append(buf, `\v`...)
default:
- switch {
- case r < ' ':
- buf = append(buf, `\x`...)
- buf = append(buf, lowerhex[s[0]>>4])
- buf = append(buf, lowerhex[s[0]&0xF])
- case r > utf8.MaxRune:
- r = 0xFFFD
- fallthrough
- case r < 0x10000:
- buf = append(buf, `\u`...)
- for s := 12; s >= 0; s -= 4 {
- buf = append(buf, lowerhex[r>>uint(s)&0xF])
- }
- default:
- buf = append(buf, `\U`...)
- for s := 28; s >= 0; s -= 4 {
- buf = append(buf, lowerhex[r>>uint(s)&0xF])
- }
+ buf = append(buf, `\U`...)
+ for s := 28; s >= 0; s -= 4 {
+ buf = append(buf, lowerhex[r>>uint(s)&0xF])
}
}
}
- buf = append(buf, quote)
- return string(buf)
-
+ return buf
}
-// Quote returns a double-quoted Go string literal representing s. The
+// Quote returns a double-quoted Go string literal representing s. The
// returned string uses Go escape sequences (\t, \n, \xFF, \u0100) for
// control characters and non-printable characters as defined by
// IsPrint.
@@ -96,7 +115,7 @@ func Quote(s string) string {
// AppendQuote appends a double-quoted Go string literal representing s,
// as generated by Quote, to dst and returns the extended buffer.
func AppendQuote(dst []byte, s string) []byte {
- return append(dst, Quote(s)...)
+ return appendQuotedWith(dst, s, '"', false, false)
}
// QuoteToASCII returns a double-quoted Go string literal representing s.
@@ -109,7 +128,7 @@ func QuoteToASCII(s string) string {
// AppendQuoteToASCII appends a double-quoted Go string literal representing s,
// as generated by QuoteToASCII, to dst and returns the extended buffer.
func AppendQuoteToASCII(dst []byte, s string) []byte {
- return append(dst, QuoteToASCII(s)...)
+ return appendQuotedWith(dst, s, '"', true, false)
}
// QuoteToGraphic returns a double-quoted Go string literal representing s.
@@ -122,21 +141,20 @@ func QuoteToGraphic(s string) string {
// AppendQuoteToGraphic appends a double-quoted Go string literal representing s,
// as generated by QuoteToGraphic, to dst and returns the extended buffer.
func AppendQuoteToGraphic(dst []byte, s string) []byte {
- return append(dst, QuoteToGraphic(s)...)
+ return appendQuotedWith(dst, s, '"', false, true)
}
// QuoteRune returns a single-quoted Go character literal representing the
// rune. The returned string uses Go escape sequences (\t, \n, \xFF, \u0100)
// for control characters and non-printable characters as defined by IsPrint.
func QuoteRune(r rune) string {
- // TODO: avoid the allocation here.
- return quoteWith(string(r), '\'', false, false)
+ return quoteRuneWith(r, '\'', false, false)
}
// AppendQuoteRune appends a single-quoted Go character literal representing the rune,
// as generated by QuoteRune, to dst and returns the extended buffer.
func AppendQuoteRune(dst []byte, r rune) []byte {
- return append(dst, QuoteRune(r)...)
+ return appendQuotedRuneWith(dst, r, '\'', false, false)
}
// QuoteRuneToASCII returns a single-quoted Go character literal representing
@@ -144,14 +162,13 @@ func AppendQuoteRune(dst []byte, r rune) []byte {
// \u0100) for non-ASCII characters and non-printable characters as defined
// by IsPrint.
func QuoteRuneToASCII(r rune) string {
- // TODO: avoid the allocation here.
- return quoteWith(string(r), '\'', true, false)
+ return quoteRuneWith(r, '\'', true, false)
}
// AppendQuoteRuneToASCII appends a single-quoted Go character literal representing the rune,
// as generated by QuoteRuneToASCII, to dst and returns the extended buffer.
func AppendQuoteRuneToASCII(dst []byte, r rune) []byte {
- return append(dst, QuoteRuneToASCII(r)...)
+ return appendQuotedRuneWith(dst, r, '\'', true, false)
}
// QuoteRuneToGraphic returns a single-quoted Go character literal representing
@@ -159,14 +176,13 @@ func AppendQuoteRuneToASCII(dst []byte, r rune) []byte {
// \u0100) for non-ASCII characters and non-printable characters as defined
// by IsGraphic.
func QuoteRuneToGraphic(r rune) string {
- // TODO: avoid the allocation here.
- return quoteWith(string(r), '\'', false, true)
+ return quoteRuneWith(r, '\'', false, true)
}
// AppendQuoteRuneToGraphic appends a single-quoted Go character literal representing the rune,
// as generated by QuoteRuneToGraphic, to dst and returns the extended buffer.
func AppendQuoteRuneToGraphic(dst []byte, r rune) []byte {
- return append(dst, QuoteRuneToGraphic(r)...)
+ return appendQuotedRuneWith(dst, r, '\'', false, true)
}
// CanBackquote reports whether the string s can be represented
@@ -331,7 +347,7 @@ func UnquoteChar(s string, quote byte) (value rune, multibyte bool, tail string,
// that s quotes. (If s is single-quoted, it would be a Go
// character literal; Unquote returns the corresponding
// one-character string.)
-func Unquote(s string) (t string, err error) {
+func Unquote(s string) (string, error) {
n := len(s)
if n < 2 {
return "", ErrSyntax
diff --git a/libgo/go/strconv/quote_test.go b/libgo/go/strconv/quote_test.go
index 3e8ec2c..10735e3 100644
--- a/libgo/go/strconv/quote_test.go
+++ b/libgo/go/strconv/quote_test.go
@@ -89,6 +89,34 @@ func TestQuoteToGraphic(t *testing.T) {
}
}
+func BenchmarkQuote(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ Quote("\a\b\f\r\n\t\v\a\b\f\r\n\t\v\a\b\f\r\n\t\v")
+ }
+}
+
+func BenchmarkQuoteRune(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ QuoteRune('\a')
+ }
+}
+
+var benchQuoteBuf []byte
+
+func BenchmarkAppendQuote(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ benchQuoteBuf = AppendQuote(benchQuoteBuf[:0], "\a\b\f\r\n\t\v\a\b\f\r\n\t\v\a\b\f\r\n\t\v")
+ }
+}
+
+var benchQuoteRuneBuf []byte
+
+func BenchmarkAppendQuoteRune(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ benchQuoteRuneBuf = AppendQuoteRune(benchQuoteRuneBuf[:0], '\a')
+ }
+}
+
type quoteRuneTest struct {
in rune
out string