diff options
author | Ian Lance Taylor <iant@google.com> | 2016-02-03 21:58:02 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-02-03 21:58:02 +0000 |
commit | f98dd1a338867a408f7c72d73fbad7fe7fc93e3a (patch) | |
tree | 2f8da9862a9c1fe0df138917f997b03439c02773 /libgo/go/strconv | |
parent | b081ed4efc144da0c45a6484aebfd10e0eb9fda3 (diff) | |
download | gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.zip gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.tar.gz gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.tar.bz2 |
libgo: Update to go1.6rc1.
Reviewed-on: https://go-review.googlesource.com/19200
From-SVN: r233110
Diffstat (limited to 'libgo/go/strconv')
-rw-r--r-- | libgo/go/strconv/ftoa.go | 18 | ||||
-rw-r--r-- | libgo/go/strconv/ftoa_test.go | 6 | ||||
-rw-r--r-- | libgo/go/strconv/isprint.go | 20 | ||||
-rw-r--r-- | libgo/go/strconv/itoa.go | 2 | ||||
-rw-r--r-- | libgo/go/strconv/makeisprint.go | 17 | ||||
-rw-r--r-- | libgo/go/strconv/quote.go | 67 | ||||
-rw-r--r-- | libgo/go/strconv/quote_test.go | 88 |
7 files changed, 174 insertions, 44 deletions
diff --git a/libgo/go/strconv/ftoa.go b/libgo/go/strconv/ftoa.go index 468c37f..9ff5d10 100644 --- a/libgo/go/strconv/ftoa.go +++ b/libgo/go/strconv/ftoa.go @@ -286,25 +286,23 @@ func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) { // Now we can figure out the minimum number of digits required. // Walk along until d has distinguished itself from upper and lower. for i := 0; i < d.nd; i++ { - var l, m, u byte // lower, middle, upper digits + l := byte('0') // lower digit if i < lower.nd { l = lower.d[i] - } else { - l = '0' } - m = d.d[i] + m := d.d[i] // middle digit + u := byte('0') // upper digit if i < upper.nd { u = upper.d[i] - } else { - u = '0' } // Okay to round down (truncate) if lower has a different digit - // or if lower is inclusive and is exactly the result of rounding down. - okdown := l != m || (inclusive && l == m && i+1 == lower.nd) + // or if lower is inclusive and is exactly the result of rounding + // down (i.e., and we have reached the final digit of lower). + okdown := l != m || inclusive && i+1 == lower.nd - // Okay to round up if upper has a different digit and - // either upper is inclusive or upper is bigger than the result of rounding up. + // Okay to round up if upper has a different digit and either upper + // is inclusive or upper is bigger than the result of rounding up. okup := m != u && (inclusive || m+1 < u || i+1 < upper.nd) // If it's okay to do either, then round to the nearest one. diff --git a/libgo/go/strconv/ftoa_test.go b/libgo/go/strconv/ftoa_test.go index 1b4dcd9..0b9f0fe 100644 --- a/libgo/go/strconv/ftoa_test.go +++ b/libgo/go/strconv/ftoa_test.go @@ -18,7 +18,7 @@ type ftoaTest struct { s string } -func fdiv(a, b float64) float64 { return a / b } // keep compiler in the dark +func fdiv(a, b float64) float64 { return a / b } const ( below1e23 = 99999999999999974834176 @@ -94,8 +94,8 @@ var ftoatests = []ftoaTest{ {above1e23, 'f', -1, "100000000000000010000000"}, {above1e23, 'g', -1, "1.0000000000000001e+23"}, - {fdiv(5e-304, 1e20), 'g', -1, "5e-324"}, - {fdiv(-5e-304, 1e20), 'g', -1, "-5e-324"}, + {fdiv(5e-304, 1e20), 'g', -1, "5e-324"}, // avoid constant arithmetic + {fdiv(-5e-304, 1e20), 'g', -1, "-5e-324"}, // avoid constant arithmetic {32, 'g', -1, "32"}, {32, 'g', 0, "3e+01"}, diff --git a/libgo/go/strconv/isprint.go b/libgo/go/strconv/isprint.go index 0cf363c..20a02de 100644 --- a/libgo/go/strconv/isprint.go +++ b/libgo/go/strconv/isprint.go @@ -635,3 +635,23 @@ var isNotPrint32 = []uint16{ // add 0x10000 to each entry 0xf57a, 0xf5a4, } + +// isGraphic lists the graphic runes not matched by IsPrint. +var isGraphic = []uint16{ + 0x00a0, + 0x1680, + 0x2000, + 0x2001, + 0x2002, + 0x2003, + 0x2004, + 0x2005, + 0x2006, + 0x2007, + 0x2008, + 0x2009, + 0x200a, + 0x202f, + 0x205f, + 0x3000, +} diff --git a/libgo/go/strconv/itoa.go b/libgo/go/strconv/itoa.go index e6f6303..f50d877 100644 --- a/libgo/go/strconv/itoa.go +++ b/libgo/go/strconv/itoa.go @@ -20,7 +20,7 @@ func FormatInt(i int64, base int) string { return s } -// Itoa is shorthand for FormatInt(i, 10). +// Itoa is shorthand for FormatInt(int64(i), 10). func Itoa(i int) string { return FormatInt(int64(i), 10) } diff --git a/libgo/go/strconv/makeisprint.go b/libgo/go/strconv/makeisprint.go index 588d0a0..5142580 100644 --- a/libgo/go/strconv/makeisprint.go +++ b/libgo/go/strconv/makeisprint.go @@ -174,6 +174,23 @@ func main() { } fmt.Fprintf(&buf, "\t%#04x,\n", r-0x10000) } + fmt.Fprintf(&buf, "}\n\n") + + // The list of graphic but not "printable" runes is short. Just make one easy table. + fmt.Fprintf(&buf, "// isGraphic lists the graphic runes not matched by IsPrint.\n") + fmt.Fprintf(&buf, "var isGraphic = []uint16{\n") + for r := rune(0); r <= unicode.MaxRune; r++ { + if unicode.IsPrint(r) != unicode.IsGraphic(r) { + // Sanity check. + if !unicode.IsGraphic(r) { + log.Fatalf("%U is printable but not graphic\n", r) + } + if r > 0xFFFF { // We expect only 16-bit values. + log.Fatalf("%U too big for isGraphic\n", r) + } + fmt.Fprintf(&buf, "\t%#04x,\n", r) + } + } fmt.Fprintf(&buf, "}\n") data, err := format.Source(buf.Bytes()) diff --git a/libgo/go/strconv/quote.go b/libgo/go/strconv/quote.go index 53d51b5..40d0667 100644 --- a/libgo/go/strconv/quote.go +++ b/libgo/go/strconv/quote.go @@ -12,7 +12,7 @@ import ( const lowerhex = "0123456789abcdef" -func quoteWith(s string, quote byte, ASCIIonly bool) string { +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. buf = append(buf, quote) @@ -38,7 +38,7 @@ func quoteWith(s string, quote byte, ASCIIonly bool) string { buf = append(buf, byte(r)) continue } - } else if IsPrint(r) { + } else if IsPrint(r) || graphicOnly && isInGraphicList(r) { n := utf8.EncodeRune(runeTmp[:], r) buf = append(buf, runeTmp[:n]...) continue @@ -90,7 +90,7 @@ func quoteWith(s string, quote byte, ASCIIonly bool) string { // control characters and non-printable characters as defined by // IsPrint. func Quote(s string) string { - return quoteWith(s, '"', false) + return quoteWith(s, '"', false, false) } // AppendQuote appends a double-quoted Go string literal representing s, @@ -103,7 +103,7 @@ func AppendQuote(dst []byte, s string) []byte { // The returned string uses Go escape sequences (\t, \n, \xFF, \u0100) for // non-ASCII characters and non-printable characters as defined by IsPrint. func QuoteToASCII(s string) string { - return quoteWith(s, '"', true) + return quoteWith(s, '"', true, false) } // AppendQuoteToASCII appends a double-quoted Go string literal representing s, @@ -112,12 +112,25 @@ func AppendQuoteToASCII(dst []byte, s string) []byte { return append(dst, QuoteToASCII(s)...) } +// QuoteToGraphic returns a double-quoted Go string literal representing s. +// The returned string uses Go escape sequences (\t, \n, \xFF, \u0100) for +// non-ASCII characters and non-printable characters as defined by IsGraphic. +func QuoteToGraphic(s string) string { + return quoteWith(s, '"', false, true) +} + +// 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)...) +} + // QuoteRune returns a single-quoted Go character literal representing the -// rune. The returned string uses Go escape sequences (\t, \n, \xFF, \u0100) +// 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) + return quoteWith(string(r), '\'', false, false) } // AppendQuoteRune appends a single-quoted Go character literal representing the rune, @@ -127,12 +140,12 @@ func AppendQuoteRune(dst []byte, r rune) []byte { } // QuoteRuneToASCII returns a single-quoted Go character literal representing -// the rune. The returned string uses Go escape sequences (\t, \n, \xFF, +// the rune. The returned string uses Go escape sequences (\t, \n, \xFF, // \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) + return quoteWith(string(r), '\'', true, false) } // AppendQuoteRuneToASCII appends a single-quoted Go character literal representing the rune, @@ -141,6 +154,21 @@ func AppendQuoteRuneToASCII(dst []byte, r rune) []byte { return append(dst, QuoteRuneToASCII(r)...) } +// QuoteRuneToGraphic returns a single-quoted Go character literal representing +// the rune. The returned string uses Go escape sequences (\t, \n, \xFF, +// \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) +} + +// 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)...) +} + // CanBackquote reports whether the string s can be represented // unchanged as a single-line backquoted string without control // characters other than tab. @@ -453,3 +481,26 @@ func IsPrint(r rune) bool { j := bsearch16(isNotPrint, uint16(r)) return j >= len(isNotPrint) || isNotPrint[j] != uint16(r) } + +// IsGraphic reports whether the rune is defined as a Graphic by Unicode. Such +// characters include letters, marks, numbers, punctuation, symbols, and +// spaces, from categories L, M, N, P, S, and Zs. +func IsGraphic(r rune) bool { + if IsPrint(r) { + return true + } + return isInGraphicList(r) +} + +// isInGraphicList reports whether the rune is in the isGraphic list. This separation +// from IsGraphic allows quoteWith to avoid two calls to IsPrint. +// Should be called only if IsPrint fails. +func isInGraphicList(r rune) bool { + // We know r must fit in 16 bits - see makeisprint.go. + if r > 0xFFFF { + return false + } + rr := uint16(r) + i := bsearch16(isGraphic, rr) + return i < len(isGraphic) && rr == isGraphic[i] +} diff --git a/libgo/go/strconv/quote_test.go b/libgo/go/strconv/quote_test.go index 3bf162f..3e8ec2c 100644 --- a/libgo/go/strconv/quote_test.go +++ b/libgo/go/strconv/quote_test.go @@ -10,7 +10,7 @@ import ( "unicode" ) -// Verify that our isPrint agrees with unicode.IsPrint +// Verify that our IsPrint agrees with unicode.IsPrint. func TestIsPrint(t *testing.T) { n := 0 for r := rune(0); r <= unicode.MaxRune; r++ { @@ -24,19 +24,36 @@ func TestIsPrint(t *testing.T) { } } +// Verify that our IsGraphic agrees with unicode.IsGraphic. +func TestIsGraphic(t *testing.T) { + n := 0 + for r := rune(0); r <= unicode.MaxRune; r++ { + if IsGraphic(r) != unicode.IsGraphic(r) { + t.Errorf("IsGraphic(%U)=%t incorrect", r, IsGraphic(r)) + n++ + if n > 10 { + return + } + } + } +} + type quoteTest struct { - in string - out string - ascii string + in string + out string + ascii string + graphic string } var quotetests = []quoteTest{ - {"\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`, `"\a\b\f\r\n\t\v"`}, - {"\\", `"\\"`, `"\\"`}, - {"abc\xffdef", `"abc\xffdef"`, `"abc\xffdef"`}, - {"\u263a", `"☺"`, `"\u263a"`}, - {"\U0010ffff", `"\U0010ffff"`, `"\U0010ffff"`}, - {"\x04", `"\x04"`, `"\x04"`}, + {"\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`, `"\a\b\f\r\n\t\v"`, `"\a\b\f\r\n\t\v"`}, + {"\\", `"\\"`, `"\\"`, `"\\"`}, + {"abc\xffdef", `"abc\xffdef"`, `"abc\xffdef"`, `"abc\xffdef"`}, + {"\u263a", `"☺"`, `"\u263a"`, `"☺"`}, + {"\U0010ffff", `"\U0010ffff"`, `"\U0010ffff"`, `"\U0010ffff"`}, + {"\x04", `"\x04"`, `"\x04"`, `"\x04"`}, + // Some non-printable but graphic runes. Final column is double-quoted. + {"!\u00a0!\u2000!\u3000!", `"!\u00a0!\u2000!\u3000!"`, `"!\u00a0!\u2000!\u3000!"`, "\"!\u00a0!\u2000!\u3000!\""}, } func TestQuote(t *testing.T) { @@ -61,22 +78,38 @@ func TestQuoteToASCII(t *testing.T) { } } +func TestQuoteToGraphic(t *testing.T) { + for _, tt := range quotetests { + if out := QuoteToGraphic(tt.in); out != tt.graphic { + t.Errorf("QuoteToGraphic(%s) = %s, want %s", tt.in, out, tt.graphic) + } + if out := AppendQuoteToGraphic([]byte("abc"), tt.in); string(out) != "abc"+tt.graphic { + t.Errorf("AppendQuoteToGraphic(%q, %s) = %s, want %s", "abc", tt.in, out, "abc"+tt.graphic) + } + } +} + type quoteRuneTest struct { - in rune - out string - ascii string + in rune + out string + ascii string + graphic string } var quoterunetests = []quoteRuneTest{ - {'a', `'a'`, `'a'`}, - {'\a', `'\a'`, `'\a'`}, - {'\\', `'\\'`, `'\\'`}, - {0xFF, `'ÿ'`, `'\u00ff'`}, - {0x263a, `'☺'`, `'\u263a'`}, - {0xfffd, `'�'`, `'\ufffd'`}, - {0x0010ffff, `'\U0010ffff'`, `'\U0010ffff'`}, - {0x0010ffff + 1, `'�'`, `'\ufffd'`}, - {0x04, `'\x04'`, `'\x04'`}, + {'a', `'a'`, `'a'`, `'a'`}, + {'\a', `'\a'`, `'\a'`, `'\a'`}, + {'\\', `'\\'`, `'\\'`, `'\\'`}, + {0xFF, `'ÿ'`, `'\u00ff'`, `'ÿ'`}, + {0x263a, `'☺'`, `'\u263a'`, `'☺'`}, + {0xfffd, `'�'`, `'\ufffd'`, `'�'`}, + {0x0010ffff, `'\U0010ffff'`, `'\U0010ffff'`, `'\U0010ffff'`}, + {0x0010ffff + 1, `'�'`, `'\ufffd'`, `'�'`}, + {0x04, `'\x04'`, `'\x04'`, `'\x04'`}, + // Some differences between graphic and printable. Note the last column is double-quoted. + {'\u00a0', `'\u00a0'`, `'\u00a0'`, "'\u00a0'"}, + {'\u2000', `'\u2000'`, `'\u2000'`, "'\u2000'"}, + {'\u3000', `'\u3000'`, `'\u3000'`, "'\u3000'"}, } func TestQuoteRune(t *testing.T) { @@ -101,6 +134,17 @@ func TestQuoteRuneToASCII(t *testing.T) { } } +func TestQuoteRuneToGraphic(t *testing.T) { + for _, tt := range quoterunetests { + if out := QuoteRuneToGraphic(tt.in); out != tt.graphic { + t.Errorf("QuoteRuneToGraphic(%U) = %s, want %s", tt.in, out, tt.graphic) + } + if out := AppendQuoteRuneToGraphic([]byte("abc"), tt.in); string(out) != "abc"+tt.graphic { + t.Errorf("AppendQuoteRuneToGraphic(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.graphic) + } + } +} + type canBackquoteTest struct { in string out bool |