Commit c45c5153 authored by Martin Möhrmann's avatar Martin Möhrmann Committed by Rob Pike

fmt: handle %X like %x for byte type arrays and slices

Treat the verb %X in the same special way as %q, %s and %x
are for arrays and slices with byte type elements.

Modify input for tests so the result of %x and %X is distinct.

Change-Id: I38d227755e98c7fad5e4adc2f603c6873aa910fd
Reviewed-on: https://go-review.googlesource.com/20516
Run-TryBot: Rob Pike <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarRob Pike <r@golang.org>
parent 80f2aff9
......@@ -122,9 +122,11 @@ var bslice = barray[:]
type byteStringer byte
func (byteStringer) String() string { return "X" }
func (byteStringer) String() string {
return "X"
}
var byteStringerSlice = []byteStringer{97, 98, 99, 100}
var byteStringerSlice = []byteStringer{'h', 'e', 'l', 'l', 'o'}
type byteFormatter byte
......@@ -132,7 +134,7 @@ func (byteFormatter) Format(f State, _ rune) {
Fprint(f, "X")
}
var byteFormatterSlice = []byteFormatter{97, 98, 99, 100}
var byteFormatterSlice = []byteFormatter{'h', 'e', 'l', 'l', 'o'}
var fmtTests = []struct {
fmt string
......@@ -706,7 +708,8 @@ var fmtTests = []struct {
{"%x", renamedString("thing"), "7468696e67"},
{"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`},
{"%q", renamedBytes([]byte("hello")), `"hello"`},
{"%x", []renamedUint8{'a', 'b', 'c'}, "616263"},
{"%x", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "68656c6c6f"},
{"%X", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "68656C6C6F"},
{"%s", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "hello"},
{"%q", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, `"hello"`},
{"%v", renamedFloat32(22), "22"},
......@@ -933,19 +936,21 @@ var fmtTests = []struct {
{"%+010.2f", -104.66 - 440.51i, "(-000104.66-000440.51i)"},
// []T where type T is a byte with a Stringer method.
{"%v", byteStringerSlice, "[X X X X]"},
{"%s", byteStringerSlice, "abcd"},
{"%q", byteStringerSlice, "\"abcd\""},
{"%x", byteStringerSlice, "61626364"},
{"%#v", byteStringerSlice, "[]fmt_test.byteStringer{0x61, 0x62, 0x63, 0x64}"},
{"%v", byteStringerSlice, "[X X X X X]"},
{"%s", byteStringerSlice, "hello"},
{"%q", byteStringerSlice, "\"hello\""},
{"%x", byteStringerSlice, "68656c6c6f"},
{"%X", byteStringerSlice, "68656C6C6F"},
{"%#v", byteStringerSlice, "[]fmt_test.byteStringer{0x68, 0x65, 0x6c, 0x6c, 0x6f}"},
// And the same for Formatter.
{"%v", byteFormatterSlice, "[X X X X]"},
{"%s", byteFormatterSlice, "abcd"},
{"%q", byteFormatterSlice, "\"abcd\""},
{"%x", byteFormatterSlice, "61626364"},
{"%v", byteFormatterSlice, "[X X X X X]"},
{"%s", byteFormatterSlice, "hello"},
{"%q", byteFormatterSlice, "\"hello\""},
{"%x", byteFormatterSlice, "68656c6c6f"},
{"%X", byteFormatterSlice, "68656C6C6F"},
// This next case seems wrong, but the docs say the Formatter wins here.
{"%#v", byteFormatterSlice, "[]fmt_test.byteFormatter{X, X, X, X}"},
{"%#v", byteFormatterSlice, "[]fmt_test.byteFormatter{X, X, X, X, X}"},
// reflect.Value handled specially in Go 1.5, making it possible to
// see inside non-exported fields (which cannot be accessed with Interface()).
......
......@@ -894,12 +894,14 @@ BigSwitch:
p.printValue(value, verb, depth+1)
}
case reflect.Array, reflect.Slice:
// Byte slices are special:
// Byte arrays and slices are special:
// - Handle []byte (== []uint8) with fmtBytes.
// - Handle []T, where T is a named byte type, with fmtBytes only
// for the s, q, an x verbs. For other verbs, T might be a
// for the s, q, x and X verbs. For other verbs, T might be a
// Stringer, so we use printValue to print each element.
if typ := f.Type(); typ.Elem().Kind() == reflect.Uint8 && (typ.Elem() == byteType || verb == 's' || verb == 'q' || verb == 'x') {
typ := f.Type()
if typ.Elem().Kind() == reflect.Uint8 &&
(typ.Elem() == byteType || verb == 's' || verb == 'q' || verb == 'x' || verb == 'X') {
var bytes []byte
if f.Kind() == reflect.Slice {
bytes = f.Bytes()
......@@ -918,7 +920,7 @@ BigSwitch:
break
}
if p.fmt.sharpV {
p.buf.WriteString(value.Type().String())
p.buf.WriteString(typ.String())
if f.Kind() == reflect.Slice && f.IsNil() {
p.buf.WriteString(nilParenString)
break
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment