diff options
Diffstat (limited to 'src/pkg/fmt/print.go')
-rw-r--r-- | src/pkg/fmt/print.go | 85 |
1 files changed, 42 insertions, 43 deletions
diff --git a/src/pkg/fmt/print.go b/src/pkg/fmt/print.go index 4e14fdaa4..7fca6afe4 100644 --- a/src/pkg/fmt/print.go +++ b/src/pkg/fmt/print.go @@ -256,9 +256,9 @@ func Sprintln(a ...interface{}) string { // Get the i'th arg of the struct value. // If the arg itself is an interface, return a value for // the thing inside the interface, not the interface itself. -func getField(v *reflect.StructValue, i int) reflect.Value { +func getField(v reflect.Value, i int) reflect.Value { val := v.Field(i) - if i, ok := val.(*reflect.InterfaceValue); ok { + if i := val; i.Kind() == reflect.Interface { if inter := i.Interface(); inter != nil { return reflect.NewValue(inter) } @@ -278,11 +278,6 @@ func parsenum(s string, start, end int) (num int, isnum bool, newi int) { return } -// Reflection values like reflect.FuncValue implement this method. We use it for %p. -type uintptrGetter interface { - Get() uintptr -} - func (p *pp) unknownType(v interface{}) { if v == nil { p.buf.Write(nilAngleBytes) @@ -394,6 +389,8 @@ func (p *pp) fmtUint64(v uint64, verb int, goSyntax bool, value interface{}) { p.fmt.integer(int64(v), 16, unsigned, ldigits) case 'X': p.fmt.integer(int64(v), 16, unsigned, udigits) + case 'U': + p.fmtUnicode(int64(v)) default: p.badVerb(verb, value) } @@ -520,12 +517,14 @@ func (p *pp) fmtBytes(v []byte, verb int, goSyntax bool, depth int, value interf } func (p *pp) fmtPointer(field interface{}, value reflect.Value, verb int, goSyntax bool) { - v, ok := value.(uintptrGetter) - if !ok { // reflect.PtrValue is a uintptrGetter, so failure means it's not a pointer at all. + var u uintptr + switch value.Kind() { + case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer: + u = value.Pointer() + default: p.badVerb(verb, field) return } - u := v.Get() if goSyntax { p.add('(') p.buf.WriteString(reflect.Typeof(field).String()) @@ -534,7 +533,7 @@ func (p *pp) fmtPointer(field interface{}, value reflect.Value, verb int, goSynt if u == 0 { p.buf.Write(nilBytes) } else { - p.fmt0x64(uint64(v.Get()), true) + p.fmt0x64(uint64(u), true) } p.add(')') } else { @@ -657,35 +656,35 @@ func (p *pp) printField(field interface{}, verb int, plus, goSyntax bool, depth value := reflect.NewValue(field) BigSwitch: - switch f := value.(type) { - case *reflect.BoolValue: - p.fmtBool(f.Get(), verb, field) - case *reflect.IntValue: - p.fmtInt64(f.Get(), verb, field) - case *reflect.UintValue: - p.fmtUint64(uint64(f.Get()), verb, goSyntax, field) - case *reflect.FloatValue: + switch f := value; f.Kind() { + case reflect.Bool: + p.fmtBool(f.Bool(), verb, field) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + p.fmtInt64(f.Int(), verb, field) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + p.fmtUint64(uint64(f.Uint()), verb, goSyntax, field) + case reflect.Float32, reflect.Float64: if f.Type().Size() == 4 { - p.fmtFloat32(float32(f.Get()), verb, field) + p.fmtFloat32(float32(f.Float()), verb, field) } else { - p.fmtFloat64(float64(f.Get()), verb, field) + p.fmtFloat64(float64(f.Float()), verb, field) } - case *reflect.ComplexValue: + case reflect.Complex64, reflect.Complex128: if f.Type().Size() == 8 { - p.fmtComplex64(complex64(f.Get()), verb, field) + p.fmtComplex64(complex64(f.Complex()), verb, field) } else { - p.fmtComplex128(complex128(f.Get()), verb, field) + p.fmtComplex128(complex128(f.Complex()), verb, field) } - case *reflect.StringValue: - p.fmtString(f.Get(), verb, goSyntax, field) - case *reflect.MapValue: + case reflect.String: + p.fmtString(f.String(), verb, goSyntax, field) + case reflect.Map: if goSyntax { p.buf.WriteString(f.Type().String()) p.buf.WriteByte('{') } else { p.buf.Write(mapBytes) } - keys := f.Keys() + keys := f.MapKeys() for i, key := range keys { if i > 0 { if goSyntax { @@ -696,20 +695,20 @@ BigSwitch: } p.printField(key.Interface(), verb, plus, goSyntax, depth+1) p.buf.WriteByte(':') - p.printField(f.Elem(key).Interface(), verb, plus, goSyntax, depth+1) + p.printField(f.MapIndex(key).Interface(), verb, plus, goSyntax, depth+1) } if goSyntax { p.buf.WriteByte('}') } else { p.buf.WriteByte(']') } - case *reflect.StructValue: + case reflect.Struct: if goSyntax { p.buf.WriteString(reflect.Typeof(field).String()) } p.add('{') v := f - t := v.Type().(*reflect.StructType) + t := v.Type() for i := 0; i < v.NumField(); i++ { if i > 0 { if goSyntax { @@ -727,9 +726,9 @@ BigSwitch: p.printField(getField(v, i).Interface(), verb, plus, goSyntax, depth+1) } p.buf.WriteByte('}') - case *reflect.InterfaceValue: + case reflect.Interface: value := f.Elem() - if value == nil { + if !value.IsValid() { if goSyntax { p.buf.WriteString(reflect.Typeof(field).String()) p.buf.Write(nilParenBytes) @@ -739,9 +738,9 @@ BigSwitch: } else { return p.printField(value.Interface(), verb, plus, goSyntax, depth+1) } - case reflect.ArrayOrSliceValue: + case reflect.Array, reflect.Slice: // Byte slices are special. - if f.Type().(reflect.ArrayOrSliceType).Elem().Kind() == reflect.Uint8 { + if f.Type().Elem().Kind() == reflect.Uint8 { // We know it's a slice of bytes, but we also know it does not have static type // []byte, or it would have been caught above. Therefore we cannot convert // it directly in the (slightly) obvious way: f.Interface().([]byte); it doesn't have @@ -751,7 +750,7 @@ BigSwitch: // if reflection could help a little more. bytes := make([]byte, f.Len()) for i := range bytes { - bytes[i] = byte(f.Elem(i).(*reflect.UintValue).Get()) + bytes[i] = byte(f.Index(i).Uint()) } p.fmtBytes(bytes, verb, goSyntax, depth, field) return verb == 's' @@ -770,24 +769,24 @@ BigSwitch: p.buf.WriteByte(' ') } } - p.printField(f.Elem(i).Interface(), verb, plus, goSyntax, depth+1) + p.printField(f.Index(i).Interface(), verb, plus, goSyntax, depth+1) } if goSyntax { p.buf.WriteByte('}') } else { p.buf.WriteByte(']') } - case *reflect.PtrValue: - v := f.Get() + case reflect.Ptr: + v := f.Pointer() // pointer to array or slice or struct? ok at top level // but not embedded (avoid loops) if v != 0 && depth == 0 { - switch a := f.Elem().(type) { - case reflect.ArrayOrSliceValue: + switch a := f.Elem(); a.Kind() { + case reflect.Array, reflect.Slice: p.buf.WriteByte('&') p.printField(a.Interface(), verb, plus, goSyntax, depth+1) break BigSwitch - case *reflect.StructValue: + case reflect.Struct: p.buf.WriteByte('&') p.printField(a.Interface(), verb, plus, goSyntax, depth+1) break BigSwitch @@ -811,7 +810,7 @@ BigSwitch: break } p.fmt0x64(uint64(v), true) - case uintptrGetter: + case reflect.Chan, reflect.Func, reflect.UnsafePointer: p.fmtPointer(field, value, verb, goSyntax) default: p.unknownType(f) |