mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
fmt: normalize processing of format string
The old loop was a bit odd; change it to be more regular.
This also enables a diagnostic for Printf("%", 3): %!(NOVERB)
R=rsc, Kyle C
CC=golang-dev
https://golang.org/cl/3749044
This commit is contained in:
parent
d71d08af5a
commit
c0332fc93f
2 changed files with 16 additions and 12 deletions
|
|
@ -381,11 +381,13 @@ var fmttests = []fmtTest{
|
||||||
{"%p", 27, "%!p(int=27)"}, // not a pointer at all
|
{"%p", 27, "%!p(int=27)"}, // not a pointer at all
|
||||||
|
|
||||||
// erroneous things
|
// erroneous things
|
||||||
|
{"%s %", "hello", "hello %!(NOVERB)"},
|
||||||
|
{"%s %.2", "hello", "hello %!(NOVERB)"},
|
||||||
{"%d", "hello", "%!d(string=hello)"},
|
{"%d", "hello", "%!d(string=hello)"},
|
||||||
{"no args", "hello", "no args%!(EXTRA string=hello)"},
|
{"no args", "hello", "no args%!(EXTRA string=hello)"},
|
||||||
{"%s", nil, "%!s(<nil>)"},
|
{"%s", nil, "%!s(<nil>)"},
|
||||||
{"%T", nil, "<nil>"},
|
{"%T", nil, "<nil>"},
|
||||||
{"%-1", 100, "%!1(int=100)"},
|
{"%-1", 100, "%!(NOVERB)%!(EXTRA int=100)"},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSprintf(t *testing.T) {
|
func TestSprintf(t *testing.T) {
|
||||||
|
|
@ -638,7 +640,7 @@ var startests = []starTest{
|
||||||
{"%.*d", args(nil, 42), "%!(BADPREC)42"},
|
{"%.*d", args(nil, 42), "%!(BADPREC)42"},
|
||||||
{"%*d", args(5, "foo"), "%!d(string= foo)"},
|
{"%*d", args(5, "foo"), "%!d(string= foo)"},
|
||||||
{"%*% %d", args(20, 5), "% 5"},
|
{"%*% %d", args(20, 5), "% 5"},
|
||||||
{"%*", args(4), "%!(BADWIDTH)%!*(int=4)"},
|
{"%*", args(4), "%!(NOVERB)"},
|
||||||
{"%*d", args(int32(4), 42), "%!(BADWIDTH)42"},
|
{"%*d", args(int32(4), 42), "%!(BADWIDTH)42"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -655,7 +657,7 @@ func TestWidthAndPrecision(t *testing.T) {
|
||||||
for _, tt := range startests {
|
for _, tt := range startests {
|
||||||
s := sprintf[len(tt.in)](tt.fmt, tt.in)
|
s := sprintf[len(tt.in)](tt.fmt, tt.in)
|
||||||
if s != tt.out {
|
if s != tt.out {
|
||||||
t.Errorf("got %q expected %q", s, tt.out)
|
t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ var (
|
||||||
bytesBytes = []byte("[]byte{")
|
bytesBytes = []byte("[]byte{")
|
||||||
widthBytes = []byte("%!(BADWIDTH)")
|
widthBytes = []byte("%!(BADWIDTH)")
|
||||||
precBytes = []byte("%!(BADPREC)")
|
precBytes = []byte("%!(BADPREC)")
|
||||||
|
noVerbBytes = []byte("%!(NOVERB)")
|
||||||
)
|
)
|
||||||
|
|
||||||
// State represents the printer state passed to custom formatters.
|
// State represents the printer state passed to custom formatters.
|
||||||
|
|
@ -821,19 +822,16 @@ func intFromArg(a []interface{}, end, i, fieldnum int) (num int, isInt bool, new
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pp) doPrintf(format string, a []interface{}) {
|
func (p *pp) doPrintf(format string, a []interface{}) {
|
||||||
end := len(format) - 1
|
end := len(format)
|
||||||
fieldnum := 0 // we process one field per non-trivial format
|
fieldnum := 0 // we process one field per non-trivial format
|
||||||
for i := 0; i <= end; {
|
for i := 0; i < end; {
|
||||||
c, w := utf8.DecodeRuneInString(format[i:])
|
c, w := utf8.DecodeRuneInString(format[i:])
|
||||||
if c != '%' || i == end {
|
if c != '%' {
|
||||||
if w == 1 {
|
p.buf.WriteRune(c)
|
||||||
p.buf.WriteByte(byte(c))
|
|
||||||
} else {
|
|
||||||
p.buf.WriteString(format[i : i+w])
|
|
||||||
}
|
|
||||||
i += w
|
i += w
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
// Process one verb
|
||||||
i++
|
i++
|
||||||
// flags and widths
|
// flags and widths
|
||||||
p.fmt.clearflags()
|
p.fmt.clearflags()
|
||||||
|
|
@ -855,7 +853,7 @@ func (p *pp) doPrintf(format string, a []interface{}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// do we have width?
|
// do we have width?
|
||||||
if format[i] == '*' {
|
if i < end && format[i] == '*' {
|
||||||
p.fmt.wid, p.fmt.widPresent, i, fieldnum = intFromArg(a, end, i, fieldnum)
|
p.fmt.wid, p.fmt.widPresent, i, fieldnum = intFromArg(a, end, i, fieldnum)
|
||||||
if !p.fmt.widPresent {
|
if !p.fmt.widPresent {
|
||||||
p.buf.Write(widthBytes)
|
p.buf.Write(widthBytes)
|
||||||
|
|
@ -874,6 +872,10 @@ func (p *pp) doPrintf(format string, a []interface{}) {
|
||||||
p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i+1, end)
|
p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i+1, end)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if i >= end {
|
||||||
|
p.buf.Write(noVerbBytes)
|
||||||
|
continue
|
||||||
|
}
|
||||||
c, w = utf8.DecodeRuneInString(format[i:])
|
c, w = utf8.DecodeRuneInString(format[i:])
|
||||||
i += w
|
i += w
|
||||||
// percent is special - absorbs no operand
|
// percent is special - absorbs no operand
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue