From 115066fd14d0257112beab8cc09ca5d7f214ab6c Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 15 Feb 2010 22:42:49 -0800 Subject: [PATCH] Fix printing of named floating point types. Try to avoid infinite recursion if String fails due to printing a bad type. Add test for String method with named basic types. R=r CC=golang-dev https://golang.org/cl/207102 --- src/pkg/fmt/print.go | 8 ++--- src/pkg/fmt/stringer_test.go | 61 ++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 src/pkg/fmt/stringer_test.go diff --git a/src/pkg/fmt/print.go b/src/pkg/fmt/print.go index e4840b940bb..b2af9da1cb4 100644 --- a/src/pkg/fmt/print.go +++ b/src/pkg/fmt/print.go @@ -412,7 +412,7 @@ func getFloat32(a interface{}) (val float32, ok bool) { } } // Must be a renamed floating-point type. - switch f := a.(type) { + switch f := reflect.NewValue(a).(type) { case *reflect.Float32Value: return float32(f.Get()), true case *reflect.FloatValue: @@ -434,7 +434,7 @@ func getFloat64(a interface{}) (val float64, ok bool) { } } // Must be a renamed floating-point type. - switch f := a.(type) { + switch f := reflect.NewValue(a).(type) { case *reflect.Float64Value: return float64(f.Get()), true case *reflect.FloatValue: @@ -476,7 +476,7 @@ func (p *pp) unknownType(v interface{}) { } func (p *pp) printField(field interface{}, plus, sharp bool, depth int) (was_string bool) { - if field != nil { + if field != nil && depth >= 0 { switch { default: if stringer, ok := field.(Stringer); ok { @@ -948,7 +948,7 @@ func (p *pp) doprintf(format string, a []interface{}) { p.buf.WriteString(reflect.Typeof(field).String()) p.buf.WriteByte('=') } - p.printField(field, false, false, 0) + p.printField(field, false, false, -1) p.buf.WriteByte(')') } } diff --git a/src/pkg/fmt/stringer_test.go b/src/pkg/fmt/stringer_test.go new file mode 100644 index 00000000000..369f610b2b2 --- /dev/null +++ b/src/pkg/fmt/stringer_test.go @@ -0,0 +1,61 @@ +// Copyright 2010 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 fmt_test + +import ( + . "fmt" + "testing" +) + +type TI int +type TI8 int8 +type TI16 int16 +type TI32 int32 +type TI64 int64 +type TU uint +type TU8 uint8 +type TU16 uint16 +type TU32 uint32 +type TU64 uint64 +type TUI uintptr +type TF float +type TF32 float32 +type TF64 float64 +type TB bool +type TS string + +func (v TI) String() string { return Sprintf("I: %d", v) } +func (v TI8) String() string { return Sprintf("I8: %d", v) } +func (v TI16) String() string { return Sprintf("I16: %d", v) } +func (v TI32) String() string { return Sprintf("I32: %d", v) } +func (v TI64) String() string { return Sprintf("I64: %d", v) } +func (v TU) String() string { return Sprintf("U: %d", v) } +func (v TU8) String() string { return Sprintf("U8: %d", v) } +func (v TU16) String() string { return Sprintf("U16: %d", v) } +func (v TU32) String() string { return Sprintf("U32: %d", v) } +func (v TU64) String() string { return Sprintf("U64: %d", v) } +func (v TUI) String() string { return Sprintf("UI: %d", v) } +func (v TF) String() string { return Sprintf("F: %f", v) } +func (v TF32) String() string { return Sprintf("F32: %f", v) } +func (v TF64) String() string { return Sprintf("F64: %f", v) } +func (v TB) String() string { return Sprintf("B: %t", v) } +func (v TS) String() string { return Sprintf("S: %q", v) } + +func check(t *testing.T, got, want string) { + if got != want { + t.Error(got, "!=", want) + } +} + +func TestStringer(t *testing.T) { + s := Sprintf("%v %v %v %v %v", TI(0), TI8(1), TI16(2), TI32(3), TI64(4)) + check(t, s, "I: 0 I8: 1 I16: 2 I32: 3 I64: 4") + s = Sprintf("%v %v %v %v %v %v", TU(5), TU8(6), TU16(7), TU32(8), TU64(9), TUI(10)) + check(t, s, "U: 5 U8: 6 U16: 7 U32: 8 U64: 9 UI: 10") + s = Sprintf("%v %v %v", TF(1.0), TF32(2.0), TF64(3.0)) + check(t, s, "F: 1.000000 F32: 2.000000 F64: 3.000000") + s = Sprintf("%v %v", TB(true), TS("x")) + check(t, s, "B: true S: \"x\"") +}