diff options
Diffstat (limited to 'libgo/go/strconv')
-rw-r--r-- | libgo/go/strconv/atof.go | 2 | ||||
-rw-r--r-- | libgo/go/strconv/atoi.go | 40 | ||||
-rw-r--r-- | libgo/go/strconv/atoi_test.go | 83 | ||||
-rw-r--r-- | libgo/go/strconv/decimal.go | 117 | ||||
-rw-r--r-- | libgo/go/strconv/doc.go | 57 | ||||
-rw-r--r-- | libgo/go/strconv/example_test.go | 338 | ||||
-rw-r--r-- | libgo/go/strconv/extfloat.go | 2 | ||||
-rw-r--r-- | libgo/go/strconv/ftoa.go | 108 | ||||
-rw-r--r-- | libgo/go/strconv/ftoa_test.go | 1 | ||||
-rw-r--r-- | libgo/go/strconv/isprint.go | 89 | ||||
-rw-r--r-- | libgo/go/strconv/itoa.go | 58 | ||||
-rw-r--r-- | libgo/go/strconv/itoa_test.go | 1 | ||||
-rw-r--r-- | libgo/go/strconv/quote_example_test.go | 35 |
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'") = é -} |