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
diff --git a/src/pkg/fmt/format.go b/src/pkg/fmt/format.go
index 3c9cd0d..ce80116 100644
--- a/src/pkg/fmt/format.go
+++ b/src/pkg/fmt/format.go
@@ -285,18 +285,41 @@
 	f.padString(s)
 }
 
+// fmt_sbx formats a string or byte slice as a hexadecimal encoding of its bytes.
+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.
+	var buf []byte
+	for i := 0; i < n; i++ {
+		if i > 0 && f.space {
+			buf = append(buf, ' ')
+		}
+		if f.sharp {
+			buf = append(buf, '0', x)
+		}
+		var c byte
+		if b == nil {
+			c = s[i]
+		} else {
+			c = b[i]
+		}
+		buf = append(buf, digits[c>>4], digits[c&0xF])
+	}
+	f.pad(buf)
+}
+
 // fmt_sx formats a string as a hexadecimal encoding of its bytes.
 func (f *fmt) fmt_sx(s, digits string) {
-	// TODO: Avoid buffer by pre-padding.
-	var b []byte
-	for i := 0; i < len(s); i++ {
-		if i > 0 && f.space {
-			b = append(b, ' ')
-		}
-		v := s[i]
-		b = append(b, digits[v>>4], digits[v&0xF])
-	}
-	f.pad(b)
+	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.