aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2010-02-15 22:42:49 -0800
committerIan Lance Taylor <iant@golang.org>2010-02-15 22:42:49 -0800
commit115066fd14d0257112beab8cc09ca5d7f214ab6c (patch)
tree61fe6cb879b53128507f9aa3c1cb50b3e70a1c6a
parentfba50ee5ede4866a621b90355fb466e7634c3325 (diff)
downloadgo-115066fd14d0257112beab8cc09ca5d7f214ab6c.tar.gz
go-115066fd14d0257112beab8cc09ca5d7f214ab6c.zip
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
-rw-r--r--src/pkg/fmt/print.go8
-rw-r--r--src/pkg/fmt/stringer_test.go61
2 files changed, 65 insertions, 4 deletions
diff --git a/src/pkg/fmt/print.go b/src/pkg/fmt/print.go
index e4840b940b..b2af9da1cb 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 0000000000..369f610b2b
--- /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\"")
+}