aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/strconv
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2016-02-03 21:58:02 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2016-02-03 21:58:02 +0000
commitf98dd1a338867a408f7c72d73fbad7fe7fc93e3a (patch)
tree2f8da9862a9c1fe0df138917f997b03439c02773 /libgo/go/strconv
parentb081ed4efc144da0c45a6484aebfd10e0eb9fda3 (diff)
downloadgcc-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.go18
-rw-r--r--libgo/go/strconv/ftoa_test.go6
-rw-r--r--libgo/go/strconv/isprint.go20
-rw-r--r--libgo/go/strconv/itoa.go2
-rw-r--r--libgo/go/strconv/makeisprint.go17
-rw-r--r--libgo/go/strconv/quote.go67
-rw-r--r--libgo/go/strconv/quote_test.go88
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