diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-01-21 18:19:03 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-01-21 18:19:03 +0000 |
commit | 48080209fa53b6ea88c86e9f445c431b4cd1e47b (patch) | |
tree | 27d8768fb1d25696d3c40b42535eb5e073c278da /libgo/go/fmt | |
parent | bff898fbbe4358a4b7e337852df4d6043e0bd3f5 (diff) | |
download | gcc-48080209fa53b6ea88c86e9f445c431b4cd1e47b.tar.gz |
Remove the types float and complex.
Update to current version of Go library.
Update testsuite for removed types.
* go-lang.c (go_langhook_init): Omit float_type_size when calling
go_create_gogo.
* go-c.h: Update declaration of go_create_gogo.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@169098 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/go/fmt')
-rw-r--r-- | libgo/go/fmt/doc.go | 9 | ||||
-rw-r--r-- | libgo/go/fmt/fmt_test.go | 132 | ||||
-rw-r--r-- | libgo/go/fmt/format.go | 44 | ||||
-rw-r--r-- | libgo/go/fmt/print.go | 78 | ||||
-rw-r--r-- | libgo/go/fmt/scan.go | 54 | ||||
-rw-r--r-- | libgo/go/fmt/scan_test.go | 86 | ||||
-rw-r--r-- | libgo/go/fmt/stringer_test.go | 4 |
7 files changed, 233 insertions, 174 deletions
diff --git a/libgo/go/fmt/doc.go b/libgo/go/fmt/doc.go index 06dc730089d..191bf68b13b 100644 --- a/libgo/go/fmt/doc.go +++ b/libgo/go/fmt/doc.go @@ -26,6 +26,7 @@ %o base 8 %x base 16, with lower-case letters for a-f %X base 16, with upper-case letters for A-F + %U unicode format: U+1234; same as "U+%x" with 4 digits default Floating-point and complex constituents: %e scientific notation, e.g. -1234.456e+78 %E scientific notation, e.g. -1234.456E+78 @@ -35,7 +36,8 @@ String and slice of bytes: %s the uninterpreted bytes of the string or slice %q a double-quoted string safely escaped with Go syntax - %x base 16 notation with two characters per byte + %x base 16, lower-case, two characters per byte + %X base 16, upper-case, two characters per byte Pointer: %p base 16 notation, with leading 0x @@ -58,7 +60,7 @@ 0X for hex (%#X); suppress 0x for %p (%#p); print a raw (backquoted) string if possible for %q (%#q) ' ' (space) leave a space for elided sign in numbers (% d); - put spaces between bytes printing strings or slices in hex (% x) + put spaces between bytes printing strings or slices in hex (% x, % X) 0 pad with leading zeros rather than spaces For each Printf-like function, there is also a Print function @@ -126,8 +128,7 @@ %p is not implemented %T is not implemented - %e %E %f %F %g %g are all equivalent and scan any floating - point or complex value + %e %E %f %F %g %g are all equivalent and scan any floating point or complex value %s and %v on strings scan a space-delimited token Width is interpreted in the input text (%5s means at most diff --git a/libgo/go/fmt/fmt_test.go b/libgo/go/fmt/fmt_test.go index 2c09e0713b7..3f085b72245 100644 --- a/libgo/go/fmt/fmt_test.go +++ b/libgo/go/fmt/fmt_test.go @@ -28,10 +28,8 @@ type ( renamedUintptr uintptr renamedString string renamedBytes []byte - renamedFloat float renamedFloat32 float32 renamedFloat64 float64 - renamedComplex complex renamedComplex64 complex64 renamedComplex128 complex128 ) @@ -45,11 +43,6 @@ func TestFmtInterface(t *testing.T) { } } -type fmtTest struct { - fmt string - val interface{} - out string -} const b32 uint32 = 1<<32 - 1 const b64 uint64 = 1<<64 - 1 @@ -106,7 +99,11 @@ func (p *P) String() string { var b byte -var fmttests = []fmtTest{ +var fmttests = []struct { + fmt string + val interface{} + out string +}{ {"%d", 12345, "12345"}, {"%v", 12345, "12345"}, {"%t", true, "true"}, @@ -121,7 +118,8 @@ var fmttests = []fmtTest{ // basic bytes {"%s", []byte("abc"), "abc"}, {"%x", []byte("abc"), "616263"}, - {"% x", []byte("abc"), "61 62 63"}, + {"% x", []byte("abc\xff"), "61 62 63 ff"}, + {"% X", []byte("abc\xff"), "61 62 63 FF"}, {"%x", []byte("xyz"), "78797a"}, {"%X", []byte("xyz"), "78797A"}, {"%q", []byte("abc"), `"abc"`}, @@ -160,6 +158,14 @@ var fmttests = []fmtTest{ {"% d", 0, " 0"}, {"% d", 12345, " 12345"}, + // unicode format + {"%U", 0x1, "U+0001"}, + {"%.8U", 0x2, "U+00000002"}, + {"%U", 0x1234, "U+1234"}, + {"%U", 0x12345, "U+12345"}, + {"%10.6U", 0xABC, " U+000ABC"}, + {"%-10.6U", 0xABC, "U+000ABC "}, + // floats {"%+.3e", 0.0, "+0.000e+00"}, {"%+.3e", 1.0, "+1.000e+00"}, @@ -216,31 +222,31 @@ var fmttests = []fmtTest{ {"%b", 7, "111"}, {"%b", b64, "1111111111111111111111111111111111111111111111111111111111111111"}, {"%b", -6, "-110"}, - {"%e", float64(1), "1.000000e+00"}, - {"%e", float64(1234.5678e3), "1.234568e+06"}, - {"%e", float64(1234.5678e-8), "1.234568e-05"}, - {"%e", float64(-7), "-7.000000e+00"}, - {"%e", float64(-1e-9), "-1.000000e-09"}, - {"%f", float64(1234.5678e3), "1234567.800000"}, - {"%f", float64(1234.5678e-8), "0.000012"}, - {"%f", float64(-7), "-7.000000"}, - {"%f", float64(-1e-9), "-0.000000"}, - {"%g", float64(1234.5678e3), "1.2345678e+06"}, + {"%e", 1.0, "1.000000e+00"}, + {"%e", 1234.5678e3, "1.234568e+06"}, + {"%e", 1234.5678e-8, "1.234568e-05"}, + {"%e", -7.0, "-7.000000e+00"}, + {"%e", -1e-9, "-1.000000e-09"}, + {"%f", 1234.5678e3, "1234567.800000"}, + {"%f", 1234.5678e-8, "0.000012"}, + {"%f", -7.0, "-7.000000"}, + {"%f", -1e-9, "-0.000000"}, + {"%g", 1234.5678e3, "1.2345678e+06"}, {"%g", float32(1234.5678e3), "1.2345678e+06"}, - {"%g", float64(1234.5678e-8), "1.2345678e-05"}, - {"%g", float64(-7), "-7"}, - {"%g", float64(-1e-9), "-1e-09"}, + {"%g", 1234.5678e-8, "1.2345678e-05"}, + {"%g", -7.0, "-7"}, + {"%g", -1e-9, "-1e-09"}, {"%g", float32(-1e-9), "-1e-09"}, - {"%E", float64(1), "1.000000E+00"}, - {"%E", float64(1234.5678e3), "1.234568E+06"}, - {"%E", float64(1234.5678e-8), "1.234568E-05"}, - {"%E", float64(-7), "-7.000000E+00"}, - {"%E", float64(-1e-9), "-1.000000E-09"}, - {"%G", float64(1234.5678e3), "1.2345678E+06"}, + {"%E", 1.0, "1.000000E+00"}, + {"%E", 1234.5678e3, "1.234568E+06"}, + {"%E", 1234.5678e-8, "1.234568E-05"}, + {"%E", -7.0, "-7.000000E+00"}, + {"%E", -1e-9, "-1.000000E-09"}, + {"%G", 1234.5678e3, "1.2345678E+06"}, {"%G", float32(1234.5678e3), "1.2345678E+06"}, - {"%G", float64(1234.5678e-8), "1.2345678E-05"}, - {"%G", float64(-7), "-7"}, - {"%G", float64(-1e-9), "-1E-09"}, + {"%G", 1234.5678e-8, "1.2345678E-05"}, + {"%G", -7.0, "-7"}, + {"%G", -1e-9, "-1E-09"}, {"%G", float32(-1e-9), "-1E-09"}, {"%c", 'x', "x"}, {"%c", 0xe4, "รค"}, @@ -265,15 +271,15 @@ var fmttests = []fmtTest{ {"%20e", 1.2345e3, " 1.234500e+03"}, {"%20e", 1.2345e-3, " 1.234500e-03"}, {"%20.8e", 1.2345e3, " 1.23450000e+03"}, - {"%20f", float64(1.23456789e3), " 1234.567890"}, - {"%20f", float64(1.23456789e-3), " 0.001235"}, - {"%20f", float64(12345678901.23456789), " 12345678901.234568"}, - {"%-20f", float64(1.23456789e3), "1234.567890 "}, - {"%20.8f", float64(1.23456789e3), " 1234.56789000"}, - {"%20.8f", float64(1.23456789e-3), " 0.00123457"}, - {"%g", float64(1.23456789e3), "1234.56789"}, - {"%g", float64(1.23456789e-3), "0.00123456789"}, - {"%g", float64(1.23456789e20), "1.23456789e+20"}, + {"%20f", 1.23456789e3, " 1234.567890"}, + {"%20f", 1.23456789e-3, " 0.001235"}, + {"%20f", 12345678901.23456789, " 12345678901.234568"}, + {"%-20f", 1.23456789e3, "1234.567890 "}, + {"%20.8f", 1.23456789e3, " 1234.56789000"}, + {"%20.8f", 1.23456789e-3, " 0.00123457"}, + {"%g", 1.23456789e3, "1234.56789"}, + {"%g", 1.23456789e-3, "0.00123456789"}, + {"%g", 1.23456789e20, "1.23456789e+20"}, {"%20e", math.Inf(1), " +Inf"}, {"%-20f", math.Inf(-1), "-Inf "}, {"%20g", math.NaN(), " NaN"}, @@ -338,10 +344,8 @@ var fmttests = []fmtTest{ {"%x", renamedString("thing"), "7468696e67"}, {"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`}, {"%q", renamedBytes([]byte("hello")), `"hello"`}, - {"%v", renamedFloat(11), "11"}, {"%v", renamedFloat32(22), "22"}, {"%v", renamedFloat64(33), "33"}, - {"%v", renamedComplex(7 + .2i), "(7+0.2i)"}, {"%v", renamedComplex64(3 + 4i), "(3+4i)"}, {"%v", renamedComplex128(4 - 3i), "(4-3i)"}, @@ -355,7 +359,7 @@ var fmttests = []fmtTest{ {"%#v", S{F(7), G(8)}, "fmt_test.S{f:<v=F(7)>, g:GoString(8)}"}, // %T - {"%T", (4 - 3i), "complex"}, + {"%T", (4 - 3i), "complex128"}, {"%T", renamedComplex128(4 - 3i), "fmt_test.renamedComplex128"}, {"%T", intVal, "int"}, {"%6T", &intVal, " *int"}, @@ -372,11 +376,13 @@ var fmttests = []fmtTest{ {"%p", 27, "%!p(int=27)"}, // not a pointer at all // erroneous things + {"%s %", "hello", "hello %!(NOVERB)"}, + {"%s %.2", "hello", "hello %!(NOVERB)"}, {"%d", "hello", "%!d(string=hello)"}, {"no args", "hello", "no args%!(EXTRA string=hello)"}, {"%s", nil, "%!s(<nil>)"}, {"%T", nil, "<nil>"}, - {"%-1", 100, "%!1(int=100)"}, + {"%-1", 100, "%!(NOVERB)%!(EXTRA int=100)"}, } func TestSprintf(t *testing.T) { @@ -428,6 +434,12 @@ func BenchmarkSprintfIntInt(b *testing.B) { } } +func BenchmarkSprintfPrefixedInt(b *testing.B) { + for i := 0; i < b.N; i++ { + Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6) + } +} + func TestCountMallocs(t *testing.T) { mallocs := 0 - runtime.MemStats.Mallocs for i := 0; i < 100; i++ { @@ -474,12 +486,10 @@ func (*flagPrinter) Format(f State, c int) { io.WriteString(f, "["+s+"]") } -type flagTest struct { +var flagtests = []struct { in string out string -} - -var flagtests = []flagTest{ +}{ {"%a", "[%a]"}, {"%-a", "[%-a]"}, {"%+a", "[%+a]"}, @@ -513,11 +523,10 @@ func TestStructPrinter(t *testing.T) { s.a = "abc" s.b = "def" s.c = 123 - type Test struct { + var tests = []struct { fmt string out string - } - var tests = []Test{ + }{ {"%v", "{abc def 123}"}, {"%+v", "{a:abc b:def c:123}"}, } @@ -611,13 +620,11 @@ func TestFormatterPrintln(t *testing.T) { func args(a ...interface{}) []interface{} { return a } -type starTest struct { +var startests = []struct { fmt string in []interface{} out string -} - -var startests = []starTest{ +}{ {"%*d", args(4, 42), " 42"}, {"%.*d", args(4, 42), "0042"}, {"%*.*d", args(8, 4, 42), " 0042"}, @@ -629,24 +636,15 @@ var startests = []starTest{ {"%.*d", args(nil, 42), "%!(BADPREC)42"}, {"%*d", args(5, "foo"), "%!d(string= foo)"}, {"%*% %d", args(20, 5), "% 5"}, - {"%*", args(4), "%!(BADWIDTH)%!*(int=4)"}, + {"%*", args(4), "%!(NOVERB)"}, {"%*d", args(int32(4), 42), "%!(BADWIDTH)42"}, } -// TODO: there's no conversion from []T to ...T, but we can fake it. These -// functions do the faking. We index the table by the length of the param list. -var sprintf = []func(string, []interface{}) string{ - 0: func(f string, i []interface{}) string { return Sprintf(f) }, - 1: func(f string, i []interface{}) string { return Sprintf(f, i[0]) }, - 2: func(f string, i []interface{}) string { return Sprintf(f, i[0], i[1]) }, - 3: func(f string, i []interface{}) string { return Sprintf(f, i[0], i[1], i[2]) }, -} - func TestWidthAndPrecision(t *testing.T) { for _, tt := range startests { - s := sprintf[len(tt.in)](tt.fmt, tt.in) + s := Sprintf(tt.fmt, tt.in...) if s != tt.out { - t.Errorf("got %q expected %q", s, tt.out) + t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out) } } } diff --git a/libgo/go/fmt/format.go b/libgo/go/fmt/format.go index 3ec1cf13943..86057bf693c 100644 --- a/libgo/go/fmt/format.go +++ b/libgo/go/fmt/format.go @@ -49,6 +49,7 @@ type fmt struct { plus bool sharp bool space bool + unicode bool zero bool } @@ -61,6 +62,7 @@ func (f *fmt) clearflags() { f.plus = false f.sharp = false f.space = false + f.unicode = false f.zero = false } @@ -213,6 +215,12 @@ func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) { buf[i] = '0' } } + if f.unicode { + i-- + buf[i] = '+' + i-- + buf[i] = 'U' + } if negative { i-- @@ -255,6 +263,9 @@ func (f *fmt) fmt_sx(s string) { func (f *fmt) fmt_sX(s string) { t := "" for i := 0; i < len(s); i++ { + if i > 0 && f.space { + t += " " + } v := s[i] t += string(udigits[v>>4]) t += string(udigits[v&0xF]) @@ -385,36 +396,3 @@ func (f *fmt) fmt_c128(v complex128, verb int) { } f.buf.Write(irparenBytes) } - -// float -func (x *fmt) f(a float) { - if strconv.FloatSize == 32 { - x.fmt_f32(float32(a)) - } else { - x.fmt_f64(float64(a)) - } -} - -func (x *fmt) e(a float) { - if strconv.FloatSize == 32 { - x.fmt_e32(float32(a)) - } else { - x.fmt_e64(float64(a)) - } -} - -func (x *fmt) g(a float) { - if strconv.FloatSize == 32 { - x.fmt_g32(float32(a)) - } else { - x.fmt_g64(float64(a)) - } -} - -func (x *fmt) fb(a float) { - if strconv.FloatSize == 32 { - x.fmt_fb32(float32(a)) - } else { - x.fmt_fb64(float64(a)) - } -} diff --git a/libgo/go/fmt/print.go b/libgo/go/fmt/print.go index 24b1eb32e00..96029a8789f 100644 --- a/libgo/go/fmt/print.go +++ b/libgo/go/fmt/print.go @@ -26,6 +26,7 @@ var ( bytesBytes = []byte("[]byte{") widthBytes = []byte("%!(BADWIDTH)") precBytes = []byte("%!(BADPREC)") + noVerbBytes = []byte("%!(NOVERB)") ) // State represents the printer state passed to custom formatters. @@ -117,12 +118,7 @@ func (p *pp) Flag(b int) bool { } func (p *pp) add(c int) { - if c < utf8.RuneSelf { - p.buf.WriteByte(byte(c)) - } else { - w := utf8.EncodeRune(c, p.runeBuf[0:]) - p.buf.Write(p.runeBuf[0:w]) - } + p.buf.WriteRune(c) } // Implement Write so we can call Fprintf on a pp (through State), for @@ -300,7 +296,7 @@ func (p *pp) fmtC(c int64) { if int64(rune) != c { rune = utf8.RuneError } - w := utf8.EncodeRune(rune, p.runeBuf[0:utf8.UTFMax]) + w := utf8.EncodeRune(p.runeBuf[0:utf8.UTFMax], rune) p.fmt.pad(p.runeBuf[0:w]) } @@ -316,6 +312,8 @@ func (p *pp) fmtInt64(v int64, verb int, value interface{}) { p.fmt.integer(v, 8, signed, ldigits) case 'x': p.fmt.integer(v, 16, signed, ldigits) + case 'U': + p.fmtUnicode(v) case 'X': p.fmt.integer(v, 16, signed, udigits) default: @@ -323,7 +321,7 @@ func (p *pp) fmtInt64(v int64, verb int, value interface{}) { } } -// fmt_sharpHex64 formats a uint64 in hexadecimal and prefixes it with 0x by +// fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x by // temporarily turning on the sharp flag. func (p *pp) fmt0x64(v uint64) { sharp := p.fmt.sharp @@ -332,6 +330,23 @@ func (p *pp) fmt0x64(v uint64) { p.fmt.sharp = sharp } +// fmtUnicode formats a uint64 in U+1234 form by +// temporarily turning on the unicode flag and tweaking the precision. +func (p *pp) fmtUnicode(v int64) { + precPresent := p.fmt.precPresent + prec := p.fmt.prec + if !precPresent { + // If prec is already set, leave it alone; otherwise 4 is minimum. + p.fmt.prec = 4 + p.fmt.precPresent = true + } + p.fmt.unicode = true // turn on U+ + p.fmt.integer(int64(v), 16, unsigned, udigits) + p.fmt.unicode = false + p.fmt.prec = prec + p.fmt.precPresent = precPresent +} + func (p *pp) fmtUint64(v uint64, verb int, goSyntax bool, value interface{}) { switch verb { case 'b': @@ -558,26 +573,12 @@ func (p *pp) printField(field interface{}, verb int, plus, goSyntax bool, depth case bool: p.fmtBool(f, verb, field) return false - case float: - if floatBits == 32 { - p.fmtFloat32(float32(f), verb, field) - } else { - p.fmtFloat64(float64(f), verb, field) - } - return false case float32: p.fmtFloat32(f, verb, field) return false case float64: p.fmtFloat64(f, verb, field) return false - case complex: - if complexBits == 64 { - p.fmtComplex64(complex64(f), verb, field) - } else { - p.fmtComplex128(complex128(f), verb, field) - } - return false case complex64: p.fmtComplex64(complex64(f), verb, field) return false @@ -802,19 +803,22 @@ func intFromArg(a []interface{}, end, i, fieldnum int) (num int, isInt bool, new } func (p *pp) doPrintf(format string, a []interface{}) { - end := len(format) - 1 + end := len(format) fieldnum := 0 // we process one field per non-trivial format - for i := 0; i <= end; { - c, w := utf8.DecodeRuneInString(format[i:]) - if c != '%' || i == end { - if w == 1 { - p.buf.WriteByte(byte(c)) - } else { - p.buf.WriteString(format[i : i+w]) - } - i += w - continue + for i := 0; i < end; { + lasti := i + for i < end && format[i] != '%' { + i++ + } + if i > lasti { + p.buf.WriteString(format[lasti:i]) } + if i >= end { + // done processing format string + break + } + + // Process one verb i++ // flags and widths p.fmt.clearflags() @@ -836,7 +840,7 @@ func (p *pp) doPrintf(format string, a []interface{}) { } } // do we have width? - if format[i] == '*' { + if i < end && format[i] == '*' { p.fmt.wid, p.fmt.widPresent, i, fieldnum = intFromArg(a, end, i, fieldnum) if !p.fmt.widPresent { p.buf.Write(widthBytes) @@ -855,7 +859,11 @@ func (p *pp) doPrintf(format string, a []interface{}) { p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i+1, end) } } - c, w = utf8.DecodeRuneInString(format[i:]) + if i >= end { + p.buf.Write(noVerbBytes) + continue + } + c, w := utf8.DecodeRuneInString(format[i:]) i += w // percent is special - absorbs no operand if c == '%' { diff --git a/libgo/go/fmt/scan.go b/libgo/go/fmt/scan.go index 41a12d9957d..ebbb17155e4 100644 --- a/libgo/go/fmt/scan.go +++ b/libgo/go/fmt/scan.go @@ -388,9 +388,9 @@ func (s *ss) typeError(field interface{}, expected string) { var complexError = os.ErrorString("syntax error scanning complex number") var boolError = os.ErrorString("syntax error scanning boolean") -// accepts checks the next rune in the input. If it's a byte (sic) in the string, it puts it in the -// buffer and returns true. Otherwise it return false. -func (s *ss) accept(ok string) bool { +// consume reads the next rune in the input and reports whether it is in the ok string. +// If accept is true, it puts the character into the input token. +func (s *ss) consume(ok string, accept bool) bool { if s.wid >= s.maxWid { return false } @@ -400,17 +400,25 @@ func (s *ss) accept(ok string) bool { } for i := 0; i < len(ok); i++ { if int(ok[i]) == rune { - s.buf.WriteRune(rune) - s.wid++ + if accept { + s.buf.WriteRune(rune) + s.wid++ + } return true } } - if rune != EOF { + if rune != EOF && accept { s.UngetRune() } return false } +// accept checks the next rune in the input. If it's a byte (sic) in the string, it puts it in the +// buffer and returns true. Otherwise it return false. +func (s *ss) accept(ok string) bool { + return s.consume(ok, true) +} + // okVerb verifies that the verb is present in the list, setting s.err appropriately if not. func (s *ss) okVerb(verb int, okVerbs, typ string) bool { for _, v := range okVerbs { @@ -460,7 +468,7 @@ const ( // getBase returns the numeric base represented by the verb and its digit string. func (s *ss) getBase(verb int) (base int, digits string) { - s.okVerb(verb, "bdoxXv", "integer") // sets s.err + s.okVerb(verb, "bdoUxXv", "integer") // sets s.err base = 10 digits = decimalDigits switch verb { @@ -470,7 +478,7 @@ func (s *ss) getBase(verb int) (base int, digits string) { case 'o': base = 8 digits = octalDigits - case 'x', 'X': + case 'x', 'X', 'U': base = 16 digits = hexadecimalDigits } @@ -506,7 +514,13 @@ func (s *ss) scanInt(verb int, bitSize int) int64 { } base, digits := s.getBase(verb) s.skipSpace(false) - s.accept(sign) // If there's a sign, it will be left in the token buffer. + if verb == 'U' { + if !s.consume("U", false) || !s.consume("+", false) { + s.errorString("bad unicode format ") + } + } else { + s.accept(sign) // If there's a sign, it will be left in the token buffer. + } tok := s.scanNumber(digits) i, err := strconv.Btoi64(tok, base) if err != nil { @@ -528,6 +542,11 @@ func (s *ss) scanUint(verb int, bitSize int) uint64 { } base, digits := s.getBase(verb) s.skipSpace(false) + if verb == 'U' { + if !s.consume("U", false) || !s.consume("+", false) { + s.errorString("bad unicode format ") + } + } tok := s.scanNumber(digits) i, err := strconv.Btoui64(tok, base) if err != nil { @@ -546,8 +565,16 @@ func (s *ss) scanUint(verb int, bitSize int) uint64 { // we have at least some digits, but Atof will do that. func (s *ss) floatToken() string { s.buf.Reset() + // NaN? + if s.accept("nN") && s.accept("aA") && s.accept("nN") { + return s.buf.String() + } // leading sign? s.accept(sign) + // Inf? + if s.accept("iI") && s.accept("nN") && s.accept("fF") { + return s.buf.String() + } // digits? for s.accept(decimalDigits) { } @@ -613,7 +640,7 @@ func (s *ss) scanComplex(verb int, n int) complex128 { sreal, simag := s.complexTokens() real := s.convertFloat(sreal, n/2) imag := s.convertFloat(simag, n/2) - return cmplx(real, imag) + return complex(real, imag) } // convertString returns the string represented by the next input characters. @@ -745,8 +772,6 @@ func (s *ss) scanOne(verb int, field interface{}) { switch v := field.(type) { case *bool: *v = s.scanBool(verb) - case *complex: - *v = complex(s.scanComplex(verb, int(complexBits))) case *complex64: *v = complex64(s.scanComplex(verb, 64)) case *complex128: @@ -775,11 +800,6 @@ func (s *ss) scanOne(verb int, field interface{}) { *v = uintptr(s.scanUint(verb, uintptrBits)) // Floats are tricky because you want to scan in the precision of the result, not // scan in high precision and convert, in order to preserve the correct error condition. - case *float: - if s.okVerb(verb, floatVerbs, "float") { - s.skipSpace(false) - *v = float(s.convertFloat(s.floatToken(), int(floatBits))) - } case *float32: if s.okVerb(verb, floatVerbs, "float32") { s.skipSpace(false) diff --git a/libgo/go/fmt/scan_test.go b/libgo/go/fmt/scan_test.go index 91939320037..78b9fbb4ab0 100644 --- a/libgo/go/fmt/scan_test.go +++ b/libgo/go/fmt/scan_test.go @@ -8,6 +8,7 @@ import ( "bufio" . "fmt" "io" + "math" "os" "reflect" "regexp" @@ -49,13 +50,11 @@ var ( uint16Val uint16 uint32Val uint32 uint64Val uint64 - floatVal float float32Val float32 float64Val float64 stringVal string stringVal1 string bytesVal []byte - complexVal complex complex64Val complex64 complex128Val complex128 renamedBoolVal renamedBool @@ -72,14 +71,18 @@ var ( renamedUintptrVal renamedUintptr renamedStringVal renamedString renamedBytesVal renamedBytes - renamedFloatVal renamedFloat renamedFloat32Val renamedFloat32 renamedFloat64Val renamedFloat64 - renamedComplexVal renamedComplex renamedComplex64Val renamedComplex64 renamedComplex128Val renamedComplex128 ) +type FloatTest struct { + text string + in float64 + out float64 +} + // Xs accepts any non-empty run of the verb character type Xs string @@ -154,12 +157,12 @@ var scanTests = []ScanTest{ {"30\n", &uint64Val, uint64(30)}, {"255\n", &uint8Val, uint8(255)}, {"32767\n", &int16Val, int16(32767)}, - {"2.3\n", &floatVal, 2.3}, + {"2.3\n", &float64Val, 2.3}, {"2.3e1\n", &float32Val, float32(2.3e1)}, - {"2.3e2\n", &float64Val, float64(2.3e2)}, + {"2.3e2\n", &float64Val, 2.3e2}, {"2.35\n", &stringVal, "2.35"}, {"2345678\n", &bytesVal, []byte("2345678")}, - {"(3.4e1-2i)\n", &complexVal, 3.4e1 - 2i}, + {"(3.4e1-2i)\n", &complex128Val, 3.4e1 - 2i}, {"-3.45e1-3i\n", &complex64Val, complex64(-3.45e1 - 3i)}, {"-.45e1-1e2i\n", &complex128Val, complex128(-.45e1 - 100i)}, {"hello\n", &stringVal, "hello"}, @@ -215,6 +218,8 @@ var scanfTests = []ScanfTest{ {"%o", "075\n", &uintVal, uint(075)}, {"%x", "a75\n", &uintVal, uint(0xa75)}, {"%x", "A75\n", &uintVal, uint(0xa75)}, + {"%U", "U+1234\n", &intVal, int(0x1234)}, + {"%U", "U+4567\n", &uintVal, uint(0x4567)}, // Strings {"%s", "using-%s\n", &stringVal, "using-%s"}, @@ -247,10 +252,8 @@ var scanfTests = []ScanfTest{ {"%d", "113\n", &renamedUintptrVal, renamedUintptr(113)}, {"%s", "114\n", &renamedStringVal, renamedString("114")}, {"%q", "\"1155\"\n", &renamedBytesVal, renamedBytes([]byte("1155"))}, - {"%g", "115.1\n", &renamedFloatVal, renamedFloat(115.1)}, {"%g", "116e1\n", &renamedFloat32Val, renamedFloat32(116e1)}, {"%g", "-11.7e+1", &renamedFloat64Val, renamedFloat64(-11.7e+1)}, - {"%g", "11+5.1i\n", &renamedComplexVal, renamedComplex(11 + 5.1i)}, {"%g", "11+6e1i\n", &renamedComplex64Val, renamedComplex64(11 + 6e1i)}, {"%g", "-11.+7e+1i", &renamedComplex128Val, renamedComplex128(-11. + 7e+1i)}, @@ -279,15 +282,15 @@ var overflowTests = []ScanTest{ {"65536", &uint16Val, 0}, {"1e100", &float32Val, 0}, {"1e500", &float64Val, 0}, - {"(1e100+0i)", &complexVal, 0}, + {"(1e100+0i)", &complex64Val, 0}, {"(1+1e100i)", &complex64Val, 0}, {"(1-1e500i)", &complex128Val, 0}, } var i, j, k int -var f float +var f float64 var s, t string -var c complex +var c complex128 var x, y Xs var multiTests = []ScanfMultiTest{ @@ -298,7 +301,7 @@ var multiTests = []ScanfMultiTest{ {"%2d.%3d", "66.777", args(&i, &j), args(66, 777), ""}, {"%d, %d", "23, 18", args(&i, &j), args(23, 18), ""}, {"%3d22%3d", "33322333", args(&i, &j), args(333, 333), ""}, - {"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), float(2.5)), ""}, + {"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), 2.5), ""}, {"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""}, {"%c%c%c", "2\u50c2X", args(&i, &j, &k), args('2', '\u50c2', 'X'), ""}, @@ -399,6 +402,57 @@ func TestScanOverflow(t *testing.T) { } } +func verifyNaN(str string, t *testing.T) { + var f float64 + var f32 float32 + var f64 float64 + text := str + " " + str + " " + str + n, err := Fscan(strings.NewReader(text), &f, &f32, &f64) + if err != nil { + t.Errorf("got error scanning %q: %s", text, err) + } + if n != 3 { + t.Errorf("count error scanning %q: got %d", text, n) + } + if !math.IsNaN(float64(f)) || !math.IsNaN(float64(f32)) || !math.IsNaN(f64) { + t.Errorf("didn't get NaNs scanning %q: got %g %g %g", text, f, f32, f64) + } +} + +func TestNaN(t *testing.T) { + for _, s := range []string{"nan", "NAN", "NaN"} { + verifyNaN(s, t) + } +} + +func verifyInf(str string, t *testing.T) { + var f float64 + var f32 float32 + var f64 float64 + text := str + " " + str + " " + str + n, err := Fscan(strings.NewReader(text), &f, &f32, &f64) + if err != nil { + t.Errorf("got error scanning %q: %s", text, err) + } + if n != 3 { + t.Errorf("count error scanning %q: got %d", text, n) + } + sign := 1 + if str[0] == '-' { + sign = -1 + } + if !math.IsInf(float64(f), sign) || !math.IsInf(float64(f32), sign) || !math.IsInf(f64, sign) { + t.Errorf("didn't get right Infs scanning %q: got %g %g %g", text, f, f32, f64) + } +} + + +func TestInf(t *testing.T) { + for _, s := range []string{"inf", "+inf", "-inf", "INF", "-INF", "+INF", "Inf", "-Inf", "+Inf"} { + verifyInf(s, t) + } +} + // TODO: there's no conversion from []T to ...T, but we can fake it. These // functions do the faking. We index the table by the length of the param list. var fscanf = []func(io.Reader, string, []interface{}) (int, os.Error){ @@ -472,7 +526,7 @@ func TestScanMultiple(t *testing.T) { t.Errorf("Sscan count error: expected 1: got %d", n) } if err == nil { - t.Errorf("Sscan expected error; got none", err) + t.Errorf("Sscan expected error; got none: %s", err) } if s != "asdf" { t.Errorf("Sscan wrong values: got %q expected \"asdf\"", s) @@ -487,7 +541,7 @@ func TestScanEmpty(t *testing.T) { t.Errorf("Sscan count error: expected 1: got %d", n) } if err == nil { - t.Errorf("Sscan <one item> expected error; got none") + t.Error("Sscan <one item> expected error; got none") } if s1 != "abc" { t.Errorf("Sscan wrong values: got %q expected \"abc\"", s1) @@ -497,7 +551,7 @@ func TestScanEmpty(t *testing.T) { t.Errorf("Sscan count error: expected 0: got %d", n) } if err == nil { - t.Errorf("Sscan <empty> expected error; got none") + t.Error("Sscan <empty> expected error; got none") } // Quoted empty string is OK. n, err = Sscanf(`""`, "%q", &s1) diff --git a/libgo/go/fmt/stringer_test.go b/libgo/go/fmt/stringer_test.go index 815147e1ae6..0ca3f522d62 100644 --- a/libgo/go/fmt/stringer_test.go +++ b/libgo/go/fmt/stringer_test.go @@ -20,7 +20,7 @@ type TU16 uint16 type TU32 uint32 type TU64 uint64 type TUI uintptr -type TF float +type TF float64 type TF32 float32 type TF64 float64 type TB bool @@ -37,7 +37,7 @@ func (v TU16) String() string { return Sprintf("U16: %d", uint16(v)) } func (v TU32) String() string { return Sprintf("U32: %d", uint32(v)) } func (v TU64) String() string { return Sprintf("U64: %d", uint64(v)) } func (v TUI) String() string { return Sprintf("UI: %d", uintptr(v)) } -func (v TF) String() string { return Sprintf("F: %f", float(v)) } +func (v TF) String() string { return Sprintf("F: %f", float64(v)) } func (v TF32) String() string { return Sprintf("F32: %f", float32(v)) } func (v TF64) String() string { return Sprintf("F64: %f", float64(v)) } func (v TB) String() string { return Sprintf("B: %t", bool(v)) } |