Commit ffea835b authored by Rob Pike's avatar Rob Pike

fmt: allow # and x together for strings

Silly and small but easy to be consistent.
To make it worthwhile, I eliminated an allocation when using
%x on a byte slice.

Fixes #4149.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6574046
parent 7014bc64
...@@ -127,6 +127,10 @@ var fmttests = []struct { ...@@ -127,6 +127,10 @@ var fmttests = []struct {
{"%s", []byte("abc"), "abc"}, {"%s", []byte("abc"), "abc"},
{"%x", []byte("abc"), "616263"}, {"%x", []byte("abc"), "616263"},
{"% x", []byte("abc\xff"), "61 62 63 ff"}, {"% x", []byte("abc\xff"), "61 62 63 ff"},
{"%#x", []byte("abc\xff"), "0x610x620x630xff"},
{"%#X", []byte("abc\xff"), "0X610X620X630XFF"},
{"%# x", []byte("abc\xff"), "0x61 0x62 0x63 0xff"},
{"%# X", []byte("abc\xff"), "0X61 0X62 0X63 0XFF"},
{"% X", []byte("abc\xff"), "61 62 63 FF"}, {"% X", []byte("abc\xff"), "61 62 63 FF"},
{"%x", []byte("xyz"), "78797a"}, {"%x", []byte("xyz"), "78797a"},
{"%X", []byte("xyz"), "78797A"}, {"%X", []byte("xyz"), "78797A"},
...@@ -350,10 +354,12 @@ var fmttests = []struct { ...@@ -350,10 +354,12 @@ var fmttests = []struct {
{"%+v", B{1, 2}, `{I:<1> j:2}`}, {"%+v", B{1, 2}, `{I:<1> j:2}`},
{"%+v", C{1, B{2, 3}}, `{i:1 B:{I:<2> j:3}}`}, {"%+v", C{1, B{2, 3}}, `{i:1 B:{I:<2> j:3}}`},
// q on Stringable items // other formats on Stringable items
{"%s", I(23), `<23>`}, {"%s", I(23), `<23>`},
{"%q", I(23), `"<23>"`}, {"%q", I(23), `"<23>"`},
{"%x", I(23), `3c32333e`}, {"%x", I(23), `3c32333e`},
{"%#x", I(23), `0x3c0x320x330x3e`},
{"%# x", I(23), `0x3c 0x32 0x33 0x3e`},
{"%d", I(23), `23`}, // Stringer applies only to string formats. {"%d", I(23), `23`}, // Stringer applies only to string formats.
// go syntax // go syntax
......
...@@ -285,18 +285,41 @@ func (f *fmt) fmt_s(s string) { ...@@ -285,18 +285,41 @@ func (f *fmt) fmt_s(s string) {
f.padString(s) f.padString(s)
} }
// fmt_sx formats a string as a hexadecimal encoding of its bytes. // fmt_sbx formats a string or byte slice as a hexadecimal encoding of its bytes.
func (f *fmt) fmt_sx(s, digits string) { func (f *fmt) fmt_sbx(s string, b []byte, digits string) {
n := len(b)
if b == nil {
n = len(s)
}
x := digits[10] - 'a' + 'x'
// TODO: Avoid buffer by pre-padding. // TODO: Avoid buffer by pre-padding.
var b []byte var buf []byte
for i := 0; i < len(s); i++ { for i := 0; i < n; i++ {
if i > 0 && f.space { if i > 0 && f.space {
b = append(b, ' ') buf = append(buf, ' ')
}
if f.sharp {
buf = append(buf, '0', x)
}
var c byte
if b == nil {
c = s[i]
} else {
c = b[i]
} }
v := s[i] buf = append(buf, digits[c>>4], digits[c&0xF])
b = append(b, digits[v>>4], digits[v&0xF])
} }
f.pad(b) f.pad(buf)
}
// fmt_sx formats a string as a hexadecimal encoding of its bytes.
func (f *fmt) fmt_sx(s, digits string) {
f.fmt_sbx(s, nil, digits)
}
// fmt_bx formats a byte slice as a hexadecimal encoding of its bytes.
func (f *fmt) fmt_bx(b []byte, digits string) {
f.fmt_sbx("", b, digits)
} }
// fmt_q formats a string as a double-quoted, escaped Go string constant. // fmt_q formats a string as a double-quoted, escaped Go string constant.
......
...@@ -569,16 +569,15 @@ func (p *pp) fmtBytes(v []byte, verb rune, goSyntax bool, depth int) { ...@@ -569,16 +569,15 @@ func (p *pp) fmtBytes(v []byte, verb rune, goSyntax bool, depth int) {
} }
return return
} }
s := string(v)
switch verb { switch verb {
case 's': case 's':
p.fmt.fmt_s(s) p.fmt.fmt_s(string(v))
case 'x': case 'x':
p.fmt.fmt_sx(s, ldigits) p.fmt.fmt_bx(v, ldigits)
case 'X': case 'X':
p.fmt.fmt_sx(s, udigits) p.fmt.fmt_bx(v, udigits)
case 'q': case 'q':
p.fmt.fmt_q(s) p.fmt.fmt_q(string(v))
default: default:
p.badVerb(verb) p.badVerb(verb)
} }
......
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