]> Cypherpunks repositories - gostls13.git/commitdiff
fix up %p
authorRob Pike <r@golang.org>
Tue, 22 Dec 2009 20:34:17 +0000 (07:34 +1100)
committerRob Pike <r@golang.org>
Tue, 22 Dec 2009 20:34:17 +0000 (07:34 +1100)
- use an interface {Get()}
- implement Get for maps, slices
- for slices, retrieves the address of the end of the array, which will give the
same value for every slice of the same array.

R=rsc
CC=golang-dev
https://golang.org/cl/179129

src/pkg/fmt/print.go
src/pkg/reflect/value.go

index 044ac1702c48120dbc3f72aef34c106811cd6993..cc2c82cb7e3d8015b973001f4ce0c47b908619aa 100644 (file)
@@ -136,6 +136,12 @@ type GoStringer interface {
        GoString() string
 }
 
+// getter is implemented by any value that has a Get() method,
+// which means the object contains a pointer.  Used by %p.
+type getter interface {
+       Get() uintptr
+}
+
 const allocSize = 32
 
 type pp struct {
@@ -803,12 +809,9 @@ func (p *pp) doprintf(format string, v *reflect.StructValue) {
                // pointer, including addresses of reference types.
                case 'p':
                        switch v := field.(type) {
-                       case *reflect.PtrValue:
+                       case getter:
                                p.fmt.fmt_s("0x")
                                p.fmt.fmt_uX64(uint64(v.Get()))
-                       case *reflect.ChanValue, *reflect.MapValue, *reflect.SliceValue:
-                               p.fmt.fmt_s("0x")
-                               p.fmt.fmt_uX64(uint64(field.Addr()))
                        default:
                                goto badtype
                        }
index bbc66de5e7e3c3192065e2fd7f0bc8c4a18f9c4a..3c77b879c01ea79df0a823c111a9a7056246dcd4 100644 (file)
@@ -567,6 +567,14 @@ func (v *SliceValue) Set(x *SliceValue) {
 // Set sets v to the value x.
 func (v *SliceValue) SetValue(x Value) { v.Set(x.(*SliceValue)) }
 
+// Get returns the uintptr address of the v.Cap()'th element.  This gives
+// the same result for all slices of the same array.
+// It is mainly useful for printing.
+func (v *SliceValue) Get() uintptr {
+       typ := v.typ.(*SliceType)
+       return uintptr(v.addr()) + uintptr(v.Cap())*typ.Elem().Size()
+}
+
 // Slice returns a sub-slice of the slice v.
 func (v *SliceValue) Slice(beg, end int) *SliceValue {
        cap := v.Cap()
@@ -970,6 +978,10 @@ func (v *MapValue) Set(x *MapValue) {
 // Set sets v to the value x.
 func (v *MapValue) SetValue(x Value) { v.Set(x.(*MapValue)) }
 
+// Get returns the uintptr value of v.
+// It is mainly useful for printing.
+func (v *MapValue) Get() uintptr { return *(*uintptr)(v.addr) }
+
 // implemented in ../pkg/runtime/reflect.cgo
 func mapaccess(m, key, val *byte) bool
 func mapassign(m, key, val *byte)