summaryrefslogtreecommitdiff
path: root/libgo/go/fmt
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2011-01-21 18:19:03 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2011-01-21 18:19:03 +0000
commit48080209fa53b6ea88c86e9f445c431b4cd1e47b (patch)
tree27d8768fb1d25696d3c40b42535eb5e073c278da /libgo/go/fmt
parentbff898fbbe4358a4b7e337852df4d6043e0bd3f5 (diff)
downloadgcc-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.go9
-rw-r--r--libgo/go/fmt/fmt_test.go132
-rw-r--r--libgo/go/fmt/format.go44
-rw-r--r--libgo/go/fmt/print.go78
-rw-r--r--libgo/go/fmt/scan.go54
-rw-r--r--libgo/go/fmt/scan_test.go86
-rw-r--r--libgo/go/fmt/stringer_test.go4
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)) }