fmt: debugging formats for characters: %+q %#U
%+q uses strconv.Quote[Rune]ToASCII, guaranteeing ASCII-only output.
%#U a quoted character if the rune is printable: 'x'=U+0078; otherwise
it's as before: U+000A.

R=golang-dev, gri, rsc
CC=golang-dev
https://golang.org/cl/4589047
diff --git a/src/pkg/fmt/doc.go b/src/pkg/fmt/doc.go
index 79fe575..35a11e1 100644
--- a/src/pkg/fmt/doc.go
+++ b/src/pkg/fmt/doc.go
@@ -63,11 +63,13 @@
 	number of characters to output, truncating if necessary.
 
 	Other flags:
-		+	always print a sign for numeric values
+		+	always print a sign for numeric values;
+			guarantee ASCII-only output for %q (%+q)
 		-	pad with spaces on the right rather than the left (left-justify the field)
 		#	alternate format: add leading 0 for octal (%#o), 0x for hex (%#x);
 			0X for hex (%#X); suppress 0x for %p (%#p);
-			print a raw (backquoted) string if possible for %q (%#q)
+			print a raw (backquoted) string if possible for %q (%#q);
+			write e.g. U+0078 'x' if the character is printable for %U (%#U).
 		' '	(space) leave a space for elided sign in numbers (% d);
 			put spaces between bytes printing strings or slices in hex (% x, % X)
 		0	pad with leading zeros rather than spaces
diff --git a/src/pkg/fmt/fmt_test.go b/src/pkg/fmt/fmt_test.go
index 122b951..3d255c3 100644
--- a/src/pkg/fmt/fmt_test.go
+++ b/src/pkg/fmt/fmt_test.go
@@ -133,6 +133,7 @@
 	{"%q", "\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`},
 	{"%q", "abc\xffdef", `"abc\xffdef"`},
 	{"%q", "\u263a", `"☺"`},
+	{"%+q", "\u263a", `"\u263a"`},
 	{"%q", "\U0010ffff", `"\U0010ffff"`},
 
 	// escaped characters
@@ -145,6 +146,8 @@
 	{"%q", uint64(0xFFFFFFFF), `%!q(uint64=4294967295)`},
 	{"%q", '"', `'"'`},
 	{"%q", '\'', `'\''`},
+	{"%q", "\u263a", `"☺"`},
+	{"%+q", "\u263a", `"\u263a"`},
 
 	// width
 	{"%5s", "abc", "  abc"},
@@ -187,6 +190,12 @@
 	{"%U", 0x12345, "U+12345"},
 	{"%10.6U", 0xABC, "  U+000ABC"},
 	{"%-10.6U", 0xABC, "U+000ABC  "},
+	{"%U", '\n', `U+000A`},
+	{"%#U", '\n', `U+000A`},
+	{"%U", 'x', `U+0078`},
+	{"%#U", 'x', `U+0078 'x'`},
+	{"%U", '\u263a', `U+263A`},
+	{"%#U", '\u263a', `U+263A '☺'`},
 
 	// floats
 	{"%+.3e", 0.0, "+0.000e+00"},
diff --git a/src/pkg/fmt/format.go b/src/pkg/fmt/format.go
index 5dcfb96..bec55f7 100644
--- a/src/pkg/fmt/format.go
+++ b/src/pkg/fmt/format.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"strconv"
+	"unicode"
 	"utf8"
 )
 
@@ -50,6 +51,7 @@
 	sharp       bool
 	space       bool
 	unicode     bool
+	uniQuote    bool // Use 'x'= prefix for %U if printable.
 	zero        bool
 }
 
@@ -63,6 +65,7 @@
 	f.sharp = false
 	f.space = false
 	f.unicode = false
+	f.uniQuote = false
 	f.zero = false
 }
 
@@ -232,6 +235,24 @@
 		i--
 		buf[i] = ' '
 	}
+
+	// If we want a quoted char for %#U, move the data up to make room.
+	if f.unicode && f.uniQuote && a >= 0 && a <= unicode.MaxRune && unicode.IsPrint(int(a)) {
+		runeWidth := utf8.RuneLen(int(a))
+		width := 1 + 1 + runeWidth + 1 // space, quote, rune, quote
+		copy(buf[i-width:], buf[i:])   // guaranteed to have enough room.
+		i -= width
+		// Now put " 'x'" at the end.
+		j := len(buf) - width
+		buf[j] = ' '
+		j++
+		buf[j] = '\''
+		j++
+		utf8.EncodeRune(buf[j:], int(a))
+		j += runeWidth
+		buf[j] = '\''
+	}
+
 	f.pad(buf[i:])
 }
 
@@ -291,7 +312,11 @@
 	if f.sharp && strconv.CanBackquote(s) {
 		quoted = "`" + s + "`"
 	} else {
-		quoted = strconv.Quote(s)
+		if f.plus {
+			quoted = strconv.QuoteToASCII(s)
+		} else {
+			quoted = strconv.Quote(s)
+		}
 	}
 	f.padString(quoted)
 }
@@ -299,7 +324,12 @@
 // fmt_qc formats the integer as a single-quoted, escaped Go character constant.
 // If the character is not valid Unicode, it will print '\ufffd'.
 func (f *fmt) fmt_qc(c int64) {
-	quoted := strconv.QuoteRune(int(c))
+	var quoted string
+	if f.plus {
+		quoted = strconv.QuoteRuneToASCII(int(c))
+	} else {
+		quoted = strconv.QuoteRune(int(c))
+	}
 	f.padString(quoted)
 }
 
diff --git a/src/pkg/fmt/print.go b/src/pkg/fmt/print.go
index c18a8ea..2b2a719 100644
--- a/src/pkg/fmt/print.go
+++ b/src/pkg/fmt/print.go
@@ -363,6 +363,8 @@
 // temporarily turning on the unicode flag and tweaking the precision.
 func (p *pp) fmtUnicode(v int64) {
 	precPresent := p.fmt.precPresent
+	sharp := p.fmt.sharp
+	p.fmt.sharp = false
 	prec := p.fmt.prec
 	if !precPresent {
 		// If prec is already set, leave it alone; otherwise 4 is minimum.
@@ -370,10 +372,13 @@
 		p.fmt.precPresent = true
 	}
 	p.fmt.unicode = true // turn on U+
+	p.fmt.uniQuote = sharp
 	p.fmt.integer(int64(v), 16, unsigned, udigits)
 	p.fmt.unicode = false
+	p.fmt.uniQuote = false
 	p.fmt.prec = prec
 	p.fmt.precPresent = precPresent
+	p.fmt.sharp = sharp
 }
 
 func (p *pp) fmtUint64(v uint64, verb int, goSyntax bool, value interface{}) {