diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-09-16 15:47:21 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-09-16 15:47:21 +0000 |
commit | adb0401dac41c81571722312d4586b2693f95aa6 (patch) | |
tree | ea2b52e3c258d6b6d9356977c683c7f72a4a5fd5 /libgo/go/strconv | |
parent | 5548ca3540bccbc908a45942896d635ea5f1c23f (diff) | |
download | gcc-adb0401dac41c81571722312d4586b2693f95aa6.zip gcc-adb0401dac41c81571722312d4586b2693f95aa6.tar.gz gcc-adb0401dac41c81571722312d4586b2693f95aa6.tar.bz2 |
Update Go library to r60.
From-SVN: r178910
Diffstat (limited to 'libgo/go/strconv')
-rw-r--r-- | libgo/go/strconv/atob.go | 4 | ||||
-rw-r--r-- | libgo/go/strconv/atob_test.go | 2 | ||||
-rw-r--r-- | libgo/go/strconv/atof.go | 10 | ||||
-rw-r--r-- | libgo/go/strconv/atof_test.go | 3 | ||||
-rw-r--r-- | libgo/go/strconv/atoi.go | 8 | ||||
-rw-r--r-- | libgo/go/strconv/decimal.go | 2 | ||||
-rw-r--r-- | libgo/go/strconv/fp_test.go | 6 | ||||
-rw-r--r-- | libgo/go/strconv/quote.go | 128 | ||||
-rw-r--r-- | libgo/go/strconv/quote_test.go | 81 |
9 files changed, 170 insertions, 74 deletions
diff --git a/libgo/go/strconv/atob.go b/libgo/go/strconv/atob.go index 69fa229..98ce750 100644 --- a/libgo/go/strconv/atob.go +++ b/libgo/go/strconv/atob.go @@ -7,8 +7,8 @@ package strconv import "os" // Atob returns the boolean value represented by the string. -// It accepts 1, t, T, TRUE, true, 0, f, F, FALSE, false. Any other value returns -// an error. +// It accepts 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False. +// Any other value returns an error. func Atob(str string) (value bool, err os.Error) { switch str { case "1", "t", "T", "true", "TRUE", "True": diff --git a/libgo/go/strconv/atob_test.go b/libgo/go/strconv/atob_test.go index 497df5b..541e60d 100644 --- a/libgo/go/strconv/atob_test.go +++ b/libgo/go/strconv/atob_test.go @@ -24,11 +24,13 @@ var atobtests = []atobTest{ {"F", false, nil}, {"FALSE", false, nil}, {"false", false, nil}, + {"False", false, nil}, {"1", true, nil}, {"t", true, nil}, {"T", true, nil}, {"TRUE", true, nil}, {"true", true, nil}, + {"True", true, nil}, } func TestAtob(t *testing.T) { diff --git a/libgo/go/strconv/atof.go b/libgo/go/strconv/atof.go index a91e8bf..38b3805 100644 --- a/libgo/go/strconv/atof.go +++ b/libgo/go/strconv/atof.go @@ -43,11 +43,13 @@ func special(s string) (f float64, ok bool) { switch { case equalIgnoreCase(s, "nan"): return math.NaN(), true - case equalIgnoreCase(s, "-inf"): + case equalIgnoreCase(s, "-inf"), + equalIgnoreCase(s, "-infinity"): return math.Inf(-1), true - case equalIgnoreCase(s, "+inf"): - return math.Inf(1), true - case equalIgnoreCase(s, "inf"): + case equalIgnoreCase(s, "+inf"), + equalIgnoreCase(s, "+infinity"), + equalIgnoreCase(s, "inf"), + equalIgnoreCase(s, "infinity"): return math.Inf(1), true } return diff --git a/libgo/go/strconv/atof_test.go b/libgo/go/strconv/atof_test.go index 6d8396e..0fdd0ea 100644 --- a/libgo/go/strconv/atof_test.go +++ b/libgo/go/strconv/atof_test.go @@ -47,6 +47,9 @@ var atoftests = []atofTest{ {"inf", "+Inf", nil}, {"-Inf", "-Inf", nil}, {"+INF", "+Inf", nil}, + {"-Infinity", "-Inf", nil}, + {"+INFINITY", "+Inf", nil}, + {"Infinity", "+Inf", nil}, // largest float64 {"1.7976931348623157e308", "1.7976931348623157e+308", nil}, diff --git a/libgo/go/strconv/atoi.go b/libgo/go/strconv/atoi.go index f7b8456..5845942 100644 --- a/libgo/go/strconv/atoi.go +++ b/libgo/go/strconv/atoi.go @@ -13,7 +13,6 @@ type NumError struct { func (e *NumError) String() string { return `parsing "` + e.Num + `": ` + e.Error.String() } - func computeIntsize() uint { siz := uint(8) for 1<<siz != 0 { @@ -42,6 +41,8 @@ func cutoff64(base int) uint64 { // digits, err.Error = os.EINVAL; if the value corresponding // to s cannot be represented by a uint64, err.Error = os.ERANGE. func Btoui64(s string, b int) (n uint64, err os.Error) { + var cutoff uint64 + s0 := s switch { case len(s) < 1: @@ -68,12 +69,12 @@ func Btoui64(s string, b int) (n uint64, err os.Error) { } default: - err = os.ErrorString("invalid base " + Itoa(b)) + err = os.NewError("invalid base " + Itoa(b)) goto Error } n = 0 - cutoff := cutoff64(b) + cutoff = cutoff64(b) for i := 0; i < len(s); i++ { var v byte @@ -171,7 +172,6 @@ func Btoi64(s string, base int) (i int64, err os.Error) { // returns its result in an int64. func Atoi64(s string) (i int64, err os.Error) { return Btoi64(s, 10) } - // Atoui is like Atoui64 but returns its result as a uint. func Atoui(s string) (i uint, err os.Error) { i1, e1 := Atoui64(s) diff --git a/libgo/go/strconv/decimal.go b/libgo/go/strconv/decimal.go index 3a5cf1b..783065b 100644 --- a/libgo/go/strconv/decimal.go +++ b/libgo/go/strconv/decimal.go @@ -108,7 +108,7 @@ func newDecimal(i uint64) *decimal { } // Maximum shift that we can do in one pass without overflow. -// Signed int has 31 bits, and we have to be able to accomodate 9<<k. +// Signed int has 31 bits, and we have to be able to accommodate 9<<k. const maxShift = 27 // Binary shift right (* 2) by k bits. k <= maxShift to avoid overflow. diff --git a/libgo/go/strconv/fp_test.go b/libgo/go/strconv/fp_test.go index 34baeee..3096957 100644 --- a/libgo/go/strconv/fp_test.go +++ b/libgo/go/strconv/fp_test.go @@ -28,7 +28,7 @@ func pow2(i int) float64 { // Wrapper around strconv.Atof64. Handles dddddp+ddd (binary exponent) // itself, passes the rest on to strconv.Atof64. func myatof64(s string) (f float64, ok bool) { - a := strings.Split(s, "p", 2) + a := strings.SplitN(s, "p", 2) if len(a) == 2 { n, err := strconv.Atoi64(a[0]) if err != nil { @@ -72,7 +72,7 @@ func myatof64(s string) (f float64, ok bool) { // Wrapper around strconv.Atof32. Handles dddddp+ddd (binary exponent) // itself, passes the rest on to strconv.Atof32. func myatof32(s string) (f float32, ok bool) { - a := strings.Split(s, "p", 2) + a := strings.SplitN(s, "p", 2) if len(a) == 2 { n, err := strconv.Atoi(a[0]) if err != nil { @@ -116,7 +116,7 @@ func TestFp(t *testing.T) { if len(line) == 0 || line[0] == '#' { continue } - a := strings.Split(line, " ", -1) + a := strings.Split(line, " ") if len(a) != 4 { t.Error("testfp.txt:", lineno, ": wrong field count") continue diff --git a/libgo/go/strconv/quote.go b/libgo/go/strconv/quote.go index ed58897..05e49d3 100644 --- a/libgo/go/strconv/quote.go +++ b/libgo/go/strconv/quote.go @@ -14,63 +14,109 @@ import ( const lowerhex = "0123456789abcdef" -// Quote returns a double-quoted Go string literal -// representing s. The returned string s uses Go escape -// sequences (\t, \n, \xFF, \u0100) for control characters -// and non-ASCII characters. -func Quote(s string) string { +func quoteWith(s string, quote byte, ASCIIonly bool) string { var buf bytes.Buffer - buf.WriteByte('"') - for ; len(s) > 0; s = s[1:] { - switch c := s[0]; { - case c == '"': - buf.WriteString(`\"`) - case c == '\\': - buf.WriteString(`\\`) - case ' ' <= c && c <= '~': - buf.WriteString(string(c)) - case c == '\a': + buf.WriteByte(quote) + for width := 0; len(s) > 0; s = s[width:] { + rune := int(s[0]) + width = 1 + if rune >= utf8.RuneSelf { + rune, width = utf8.DecodeRuneInString(s) + } + if width == 1 && rune == utf8.RuneError { + buf.WriteString(`\x`) + buf.WriteByte(lowerhex[s[0]>>4]) + buf.WriteByte(lowerhex[s[0]&0xF]) + continue + } + if rune == int(quote) || rune == '\\' { // always backslashed + buf.WriteByte('\\') + buf.WriteByte(byte(rune)) + continue + } + if ASCIIonly { + if rune <= unicode.MaxASCII && unicode.IsPrint(rune) { + buf.WriteRune(rune) + continue + } + } else if unicode.IsPrint(rune) { + buf.WriteRune(rune) + continue + } + switch rune { + case '\a': buf.WriteString(`\a`) - case c == '\b': + case '\b': buf.WriteString(`\b`) - case c == '\f': + case '\f': buf.WriteString(`\f`) - case c == '\n': + case '\n': buf.WriteString(`\n`) - case c == '\r': + case '\r': buf.WriteString(`\r`) - case c == '\t': + case '\t': buf.WriteString(`\t`) - case c == '\v': + case '\v': buf.WriteString(`\v`) - - case c >= utf8.RuneSelf && utf8.FullRuneInString(s): - r, size := utf8.DecodeRuneInString(s) - if r == utf8.RuneError && size == 1 { - goto EscX - } - s = s[size-1:] // next iteration will slice off 1 more - if r < 0x10000 { + default: + switch { + case rune < ' ': + buf.WriteString(`\x`) + buf.WriteByte(lowerhex[s[0]>>4]) + buf.WriteByte(lowerhex[s[0]&0xF]) + case rune > unicode.MaxRune: + rune = 0xFFFD + fallthrough + case rune < 0x10000: buf.WriteString(`\u`) - for j := uint(0); j < 4; j++ { - buf.WriteByte(lowerhex[(r>>(12-4*j))&0xF]) + for s := 12; s >= 0; s -= 4 { + buf.WriteByte(lowerhex[rune>>uint(s)&0xF]) } - } else { + default: buf.WriteString(`\U`) - for j := uint(0); j < 8; j++ { - buf.WriteByte(lowerhex[(r>>(28-4*j))&0xF]) + for s := 28; s >= 0; s -= 4 { + buf.WriteByte(lowerhex[rune>>uint(s)&0xF]) } } - - default: - EscX: - buf.WriteString(`\x`) - buf.WriteByte(lowerhex[c>>4]) - buf.WriteByte(lowerhex[c&0xF]) } } - buf.WriteByte('"') + buf.WriteByte(quote) return buf.String() + +} + +// 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 +// unicode.IsPrint. +func Quote(s string) string { + return quoteWith(s, '"', false) +} + +// QuoteToASCII 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 +// unicode.IsPrint. +func QuoteToASCII(s string) string { + return quoteWith(s, '"', 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 +// unicode.IsPrint. +func QuoteRune(rune int) string { + // TODO: avoid the allocation here. + return quoteWith(string(rune), '\'', false) +} + +// QuoteRuneToASCII 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 unicode.IsPrint. +func QuoteRuneToASCII(rune int) string { + // TODO: avoid the allocation here. + return quoteWith(string(rune), '\'', true) } // CanBackquote returns whether the string s would be diff --git a/libgo/go/strconv/quote_test.go b/libgo/go/strconv/quote_test.go index 1235fcb..4d615db 100644 --- a/libgo/go/strconv/quote_test.go +++ b/libgo/go/strconv/quote_test.go @@ -11,28 +11,70 @@ import ( ) type quoteTest struct { - in string - out string + in string + out string + ascii string } var quotetests = []quoteTest{ - {"\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`}, - {"\\", `"\\"`}, - {"abc\xffdef", `"abc\xffdef"`}, - {"\u263a", `"\u263a"`}, - {"\U0010ffff", `"\U0010ffff"`}, - {"\x04", `"\x04"`}, + {"\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"`}, } func TestQuote(t *testing.T) { - for i := 0; i < len(quotetests); i++ { - tt := quotetests[i] + for _, tt := range quotetests { if out := Quote(tt.in); out != tt.out { t.Errorf("Quote(%s) = %s, want %s", tt.in, out, tt.out) } } } +func TestQuoteToASCII(t *testing.T) { + for _, tt := range quotetests { + if out := QuoteToASCII(tt.in); out != tt.ascii { + t.Errorf("QuoteToASCII(%s) = %s, want %s", tt.in, out, tt.ascii) + } + } +} + +type quoteRuneTest struct { + in int + out string + ascii 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'`}, +} + +func TestQuoteRune(t *testing.T) { + for _, tt := range quoterunetests { + if out := QuoteRune(tt.in); out != tt.out { + t.Errorf("QuoteRune(%U) = %s, want %s", tt.in, out, tt.out) + } + } +} + +func TestQuoteRuneToASCII(t *testing.T) { + for _, tt := range quoterunetests { + if out := QuoteRuneToASCII(tt.in); out != tt.ascii { + t.Errorf("QuoteRuneToASCII(%U) = %s, want %s", tt.in, out, tt.ascii) + } + } +} + type canBackquoteTest struct { in string out bool @@ -80,15 +122,19 @@ var canbackquotetests = []canBackquoteTest{ } func TestCanBackquote(t *testing.T) { - for i := 0; i < len(canbackquotetests); i++ { - tt := canbackquotetests[i] + for _, tt := range canbackquotetests { if out := CanBackquote(tt.in); out != tt.out { t.Errorf("CanBackquote(%q) = %v, want %v", tt.in, out, tt.out) } } } -var unquotetests = []quoteTest{ +type unQuoteTest struct { + in string + out string +} + +var unquotetests = []unQuoteTest{ {`""`, ""}, {`"a"`, "a"}, {`"abc"`, "abc"}, @@ -146,23 +192,20 @@ var misquoted = []string{ } func TestUnquote(t *testing.T) { - for i := 0; i < len(unquotetests); i++ { - tt := unquotetests[i] + for _, tt := range unquotetests { if out, err := Unquote(tt.in); err != nil && out != tt.out { t.Errorf("Unquote(%#q) = %q, %v want %q, nil", tt.in, out, err, tt.out) } } // run the quote tests too, backward - for i := 0; i < len(quotetests); i++ { - tt := quotetests[i] + for _, tt := range quotetests { if in, err := Unquote(tt.out); in != tt.in { t.Errorf("Unquote(%#q) = %q, %v, want %q, nil", tt.out, in, err, tt.in) } } - for i := 0; i < len(misquoted); i++ { - s := misquoted[i] + for _, s := range misquoted { if out, err := Unquote(s); out != "" || err != os.EINVAL { t.Errorf("Unquote(%#q) = %q, %v want %q, %v", s, out, err, "", os.EINVAL) } |