Commit d482c163 authored by Rob Pike's avatar Rob Pike

fmt.Print*: reimplement to switch on type first.

This shortens, simplifies and regularizes the code significantly.
(Improvements to reflect could make another step.)
Passes all.bash.

One semantic change occurs: The String() method changes
behavior. It used to run only for string formats such as %s and %q.
Instead, it now runs whenever the item has the method and the
result is then processed by the format as a string. Besides the
regularization, this has three effects:

	1) width is honored for String() items
	2) %x works for String() items
	3) implementations of String that merely recur will recur forever

Regarding point 3, example from the updated documentation:
	type X int
	func (x X) String() string { return Sprintf("%d", x) }
should cast the value before recurring:
	func (x X) String() string { return Sprintf("%d", int(x)) }

R=rsc
CC=golang-dev
https://golang.org/cl/1613045
parent 43b3a247
...@@ -13,6 +13,29 @@ import ( ...@@ -13,6 +13,29 @@ import (
"testing" "testing"
) )
type (
renamedBool bool
renamedInt int
renamedInt8 int8
renamedInt16 int16
renamedInt32 int32
renamedInt64 int64
renamedUint uint
renamedUint8 uint8
renamedUint16 uint16
renamedUint32 uint32
renamedUint64 uint64
renamedUintptr uintptr
renamedString string
renamedBytes []byte
renamedFloat float
renamedFloat32 float32
renamedFloat64 float64
renamedComplex complex
renamedComplex64 complex64
renamedComplex128 complex128
)
func TestFmtInterface(t *testing.T) { func TestFmtInterface(t *testing.T) {
var i1 interface{} var i1 interface{}
i1 = "abc" i1 = "abc"
...@@ -43,7 +66,7 @@ type A struct { ...@@ -43,7 +66,7 @@ type A struct {
type I int type I int
func (i I) String() string { return Sprintf("<%d>", i) } func (i I) String() string { return Sprintf("<%d>", int(i)) }
type B struct { type B struct {
i I i I
...@@ -58,6 +81,10 @@ type C struct { ...@@ -58,6 +81,10 @@ type C struct {
var b byte var b byte
var fmttests = []fmtTest{ var fmttests = []fmtTest{
fmtTest{"%d", 12345, "12345"},
fmtTest{"%v", 12345, "12345"},
fmtTest{"%t", true, "true"},
// basic string // basic string
fmtTest{"%s", "abc", "abc"}, fmtTest{"%s", "abc", "abc"},
fmtTest{"%x", "abc", "616263"}, fmtTest{"%x", "abc", "616263"},
...@@ -245,7 +272,10 @@ var fmttests = []fmtTest{ ...@@ -245,7 +272,10 @@ var fmttests = []fmtTest{
fmtTest{"%+v", C{1, B{2, 3}}, `{i:1 B:{i:<2> j:3}}`}, fmtTest{"%+v", C{1, B{2, 3}}, `{i:1 B:{i:<2> j:3}}`},
// q on Stringable items // q on Stringable items
fmtTest{"%s", I(23), `<23>`},
fmtTest{"%q", I(23), `"<23>"`}, fmtTest{"%q", I(23), `"<23>"`},
fmtTest{"%x", I(23), `3c32333e`},
fmtTest{"%d", I(23), `%d(string=<23>)`},
// %p on non-pointers // %p on non-pointers
fmtTest{"%p", make(chan int), "PTR"}, fmtTest{"%p", make(chan int), "PTR"},
...@@ -260,6 +290,30 @@ var fmttests = []fmtTest{ ...@@ -260,6 +290,30 @@ var fmttests = []fmtTest{
fmtTest{"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"}, fmtTest{"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"},
fmtTest{"%#v", 1000000000, "1000000000"}, fmtTest{"%#v", 1000000000, "1000000000"},
// renamings
fmtTest{"%v", renamedBool(true), "true"},
fmtTest{"%d", renamedBool(true), "%d(fmt_test.renamedBool=true)"},
fmtTest{"%o", renamedInt(8), "10"},
fmtTest{"%d", renamedInt8(-9), "-9"},
fmtTest{"%v", renamedInt16(10), "10"},
fmtTest{"%v", renamedInt32(-11), "-11"},
fmtTest{"%X", renamedInt64(255), "FF"},
fmtTest{"%v", renamedUint(13), "13"},
fmtTest{"%o", renamedUint8(14), "16"},
fmtTest{"%X", renamedUint16(15), "F"},
fmtTest{"%d", renamedUint32(16), "16"},
fmtTest{"%X", renamedUint64(17), "11"},
fmtTest{"%o", renamedUintptr(18), "22"},
fmtTest{"%x", renamedString("thing"), "7468696e67"},
// TODO: It would be nice if this one worked, but it's hard.
// fmtTest{"%q", renamedBytes([]byte("hello")), `"hello"`},
fmtTest{"%v", renamedFloat(11), "11"},
fmtTest{"%v", renamedFloat32(22), "22"},
fmtTest{"%v", renamedFloat64(33), "33"},
fmtTest{"%v", renamedComplex(7 + .2i), "(7+0.2i)"},
fmtTest{"%v", renamedComplex64(3 + 4i), "(3+4i)"},
fmtTest{"%v", renamedComplex128(4 - 3i), "(4-3i)"},
// erroneous things // erroneous things
fmtTest{"%d", "hello", "%d(string=hello)"}, fmtTest{"%d", "hello", "%d(string=hello)"},
fmtTest{"no args", "hello", "no args?(extra string=hello)"}, fmtTest{"no args", "hello", "no args?(extra string=hello)"},
......
...@@ -234,87 +234,6 @@ func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) { ...@@ -234,87 +234,6 @@ func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) {
f.pad(buf[i:]) f.pad(buf[i:])
} }
// fmt_d64 formats an int64 in decimal.
func (f *fmt) fmt_d64(v int64) { f.integer(v, 10, signed, ldigits) }
// fmt_d32 formats an int32 in decimal.
func (f *fmt) fmt_d32(v int32) { f.integer(int64(v), 10, signed, ldigits) }
// fmt_d formats an int in decimal.
func (f *fmt) fmt_d(v int) { f.integer(int64(v), 10, signed, ldigits) }
// fmt_ud64 formats a uint64 in decimal.
func (f *fmt) fmt_ud64(v uint64) { f.integer(int64(v), 10, unsigned, ldigits) }
// fmt_ud32 formats a uint32 in decimal.
func (f *fmt) fmt_ud32(v uint32) { f.integer(int64(v), 10, unsigned, ldigits) }
// fmt_ud formats a uint in decimal.
func (f *fmt) fmt_ud(v uint) { f.integer(int64(v), 10, unsigned, ldigits) }
// fmt_x64 formats an int64 in hexadecimal.
func (f *fmt) fmt_x64(v int64) { f.integer(v, 16, signed, ldigits) }
// fmt_x32 formats an int32 in hexadecimal.
func (f *fmt) fmt_x32(v int32) { f.integer(int64(v), 16, signed, ldigits) }
// fmt_x formats an int in hexadecimal.
func (f *fmt) fmt_x(v int) { f.integer(int64(v), 16, signed, ldigits) }
// fmt_ux64 formats a uint64 in hexadecimal.
func (f *fmt) fmt_ux64(v uint64) { f.integer(int64(v), 16, unsigned, ldigits) }
// fmt_ux32 formats a uint32 in hexadecimal.
func (f *fmt) fmt_ux32(v uint32) { f.integer(int64(v), 16, unsigned, ldigits) }
// fmt_ux formats a uint in hexadecimal.
func (f *fmt) fmt_ux(v uint) { f.integer(int64(v), 16, unsigned, ldigits) }
// fmt_X64 formats an int64 in upper case hexadecimal.
func (f *fmt) fmt_X64(v int64) { f.integer(v, 16, signed, udigits) }
// fmt_X32 formats an int32 in upper case hexadecimal.
func (f *fmt) fmt_X32(v int32) { f.integer(int64(v), 16, signed, udigits) }
// fmt_X formats an int in upper case hexadecimal.
func (f *fmt) fmt_X(v int) { f.integer(int64(v), 16, signed, udigits) }
// fmt_uX64 formats a uint64 in upper case hexadecimal.
func (f *fmt) fmt_uX64(v uint64) { f.integer(int64(v), 16, unsigned, udigits) }
// fmt_uX32 formats a uint32 in upper case hexadecimal.
func (f *fmt) fmt_uX32(v uint32) { f.integer(int64(v), 16, unsigned, udigits) }
// fmt_uX formats a uint in upper case hexadecimal.
func (f *fmt) fmt_uX(v uint) { f.integer(int64(v), 16, unsigned, udigits) }
// fmt_o64 formats an int64 in octal.
func (f *fmt) fmt_o64(v int64) { f.integer(v, 8, signed, ldigits) }
// fmt_o32 formats an int32 in octal.
func (f *fmt) fmt_o32(v int32) { f.integer(int64(v), 8, signed, ldigits) }
// fmt_o formats an int in octal.
func (f *fmt) fmt_o(v int) { f.integer(int64(v), 8, signed, ldigits) }
// fmt_uo64 formats a uint64 in octal.
func (f *fmt) fmt_uo64(v uint64) { f.integer(int64(v), 8, unsigned, ldigits) }
// fmt_uo32 formats a uint32 in octal.
func (f *fmt) fmt_uo32(v uint32) { f.integer(int64(v), 8, unsigned, ldigits) }
// fmt_uo formats a uint in octal.
func (f *fmt) fmt_uo(v uint) { f.integer(int64(v), 8, unsigned, ldigits) }
// fmt_b64 formats an int64 in binary.
func (f *fmt) fmt_b64(v int64) { f.integer(v, 2, signed, ldigits) }
// fmt_ub64 formats a uint64 in binary.
func (f *fmt) fmt_ub64(v uint64) { f.integer(int64(v), 2, unsigned, ldigits) }
// fmt_c formats a Unicode character.
func (f *fmt) fmt_c(v int) { f.padString(string(v)) }
// fmt_s formats a string. // fmt_s formats a string.
func (f *fmt) fmt_s(s string) { func (f *fmt) fmt_s(s string) {
if f.precPresent { if f.precPresent {
...@@ -422,14 +341,13 @@ func (f *fmt) fmt_G32(v float32) { f.plusSpace(strconv.Ftoa32(v, 'G', doPrec(f, ...@@ -422,14 +341,13 @@ func (f *fmt) fmt_G32(v float32) { f.plusSpace(strconv.Ftoa32(v, 'G', doPrec(f,
// fmt_fb32 formats a float32 in the form -123p3 (exponent is power of 2). // fmt_fb32 formats a float32 in the form -123p3 (exponent is power of 2).
func (f *fmt) fmt_fb32(v float32) { f.padString(strconv.Ftoa32(v, 'b', 0)) } func (f *fmt) fmt_fb32(v float32) { f.padString(strconv.Ftoa32(v, 'b', 0)) }
// fmt_c64 formats a complex64 according to its fmt_x argument. // fmt_c64 formats a complex64 according to the verb.
// TODO pass in a method rather than a byte when the compilers mature. func (f *fmt) fmt_c64(v complex64, verb int) {
func (f *fmt) fmt_c64(v complex64, fmt_x byte) {
f.buf.WriteByte('(') f.buf.WriteByte('(')
r := real(v) r := real(v)
f.preserveFlags = true f.preserveFlags = true
for i := 0; ; i++ { for i := 0; ; i++ {
switch fmt_x { switch verb {
case 'e': case 'e':
f.fmt_e32(r) f.fmt_e32(r)
case 'E': case 'E':
...@@ -451,14 +369,13 @@ func (f *fmt) fmt_c64(v complex64, fmt_x byte) { ...@@ -451,14 +369,13 @@ func (f *fmt) fmt_c64(v complex64, fmt_x byte) {
f.buf.Write(irparenBytes) f.buf.Write(irparenBytes)
} }
// fmt_c128 formats a complex128 according to its fmt_x argument. // fmt_c128 formats a complex128 according to the verb.
// TODO pass in a method rather than a byte when the compilers mature. func (f *fmt) fmt_c128(v complex128, verb int) {
func (f *fmt) fmt_c128(v complex128, fmt_x byte) {
f.buf.WriteByte('(') f.buf.WriteByte('(')
r := real(v) r := real(v)
f.preserveFlags = true f.preserveFlags = true
for i := 0; ; i++ { for i := 0; ; i++ {
switch fmt_x { switch verb {
case 'e': case 'e':
f.fmt_e64(r) f.fmt_e64(r)
case 'E': case 'E':
......
...@@ -75,16 +75,23 @@ ...@@ -75,16 +75,23 @@
can be used for fine control of formatting. can be used for fine control of formatting.
If an operand implements method String() string that method If an operand implements method String() string that method
will be used for %v, %s, or Print etc. will be used to conver the object to a string, which will then
be formatted as required by the verb (if any). To avoid
recursion in cases such as
type X int
func (x X) String() string { return Sprintf("%d", x) }
cast the value before recurring:
func (x X) String() string { return Sprintf("%d", int(x)) }
Scanning: Scanning:
An analogous set of functions scans formatted text to yield An analogous set of functions scans formatted text to yield
values. Scan and Scanln read from os.Stdin; Fscan and values. Scan, Scanf and Scanln read from os.Stdin; Fscan,
Fscanln read from a specified os.Reader; Sscan and Sscanln Fscanf and Fscanln read from a specified os.Reader; Sscan,
read from an argument string. Sscanln, Fscanln and Sscanln Sscanf and Sscanln read from an argument string. Sscanln,
stop scanning at a newline and require that the items be Fscanln and Sscanln stop scanning at a newline and require that
followed by one; the other routines treat newlines as spaces. the items be followed by one; the other routines treat newlines
as spaces.
Scanf, Fscanf, and Sscanf parse the arguments according to a Scanf, Fscanf, and Sscanf parse the arguments according to a
format string, analogous to that of Printf. For example, "%x" format string, analogous to that of Printf. For example, "%x"
...@@ -134,8 +141,6 @@ import ( ...@@ -134,8 +141,6 @@ import (
// Some constants in the form of bytes, to avoid string overhead. // Some constants in the form of bytes, to avoid string overhead.
// Needlessly fastidious, I suppose. // Needlessly fastidious, I suppose.
var ( var (
trueBytes = []byte("true")
falseBytes = []byte("false")
commaSpaceBytes = []byte(", ") commaSpaceBytes = []byte(", ")
nilAngleBytes = []byte("<nil>") nilAngleBytes = []byte("<nil>")
nilParenBytes = []byte("(nil)") nilParenBytes = []byte("(nil)")
...@@ -144,6 +149,7 @@ var ( ...@@ -144,6 +149,7 @@ var (
missingBytes = []byte("missing") missingBytes = []byte("missing")
extraBytes = []byte("?(extra ") extraBytes = []byte("?(extra ")
irparenBytes = []byte("i)") irparenBytes = []byte("i)")
bytesBytes = []byte("[]byte{")
) )
// State represents the printer state passed to custom formatters. // State represents the printer state passed to custom formatters.
...@@ -184,14 +190,6 @@ type GoStringer interface { ...@@ -184,14 +190,6 @@ type GoStringer interface {
GoString() string GoString() string
} }
// getter is implemented by any value that has a Get() method,
// which means the object contains a pointer. Used by %p.
type getter interface {
Get() uintptr
}
const allocSize = 32
type pp struct { type pp struct {
n int n int
buf bytes.Buffer buf bytes.Buffer
...@@ -262,7 +260,7 @@ func (p *pp) Write(b []byte) (ret int, err os.Error) { ...@@ -262,7 +260,7 @@ func (p *pp) Write(b []byte) (ret int, err os.Error) {
// Fprintf formats according to a format specifier and writes to w. // Fprintf formats according to a format specifier and writes to w.
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, error os.Error) { func Fprintf(w io.Writer, format string, a ...interface{}) (n int, error os.Error) {
p := newPrinter() p := newPrinter()
p.doprintf(format, a) p.doPrintf(format, a)
n64, error := p.buf.WriteTo(w) n64, error := p.buf.WriteTo(w)
p.free() p.free()
return int(n64), error return int(n64), error
...@@ -277,7 +275,7 @@ func Printf(format string, a ...interface{}) (n int, errno os.Error) { ...@@ -277,7 +275,7 @@ func Printf(format string, a ...interface{}) (n int, errno os.Error) {
// Sprintf formats according to a format specifier and returns the resulting string. // Sprintf formats according to a format specifier and returns the resulting string.
func Sprintf(format string, a ...interface{}) string { func Sprintf(format string, a ...interface{}) string {
p := newPrinter() p := newPrinter()
p.doprintf(format, a) p.doPrintf(format, a)
s := p.buf.String() s := p.buf.String()
p.free() p.free()
return s return s
...@@ -289,7 +287,7 @@ func Sprintf(format string, a ...interface{}) string { ...@@ -289,7 +287,7 @@ func Sprintf(format string, a ...interface{}) string {
// Spaces are added between operands when neither is a string. // Spaces are added between operands when neither is a string.
func Fprint(w io.Writer, a ...interface{}) (n int, error os.Error) { func Fprint(w io.Writer, a ...interface{}) (n int, error os.Error) {
p := newPrinter() p := newPrinter()
p.doprint(a, false, false) p.doPrint(a, false, false)
n64, error := p.buf.WriteTo(w) n64, error := p.buf.WriteTo(w)
p.free() p.free()
return int(n64), error return int(n64), error
...@@ -306,7 +304,7 @@ func Print(a ...interface{}) (n int, errno os.Error) { ...@@ -306,7 +304,7 @@ func Print(a ...interface{}) (n int, errno os.Error) {
// Spaces are added between operands when neither is a string. // Spaces are added between operands when neither is a string.
func Sprint(a ...interface{}) string { func Sprint(a ...interface{}) string {
p := newPrinter() p := newPrinter()
p.doprint(a, false, false) p.doPrint(a, false, false)
s := p.buf.String() s := p.buf.String()
p.free() p.free()
return s return s
...@@ -320,7 +318,7 @@ func Sprint(a ...interface{}) string { ...@@ -320,7 +318,7 @@ func Sprint(a ...interface{}) string {
// Spaces are always added between operands and a newline is appended. // Spaces are always added between operands and a newline is appended.
func Fprintln(w io.Writer, a ...interface{}) (n int, error os.Error) { func Fprintln(w io.Writer, a ...interface{}) (n int, error os.Error) {
p := newPrinter() p := newPrinter()
p.doprint(a, true, true) p.doPrint(a, true, true)
n64, error := p.buf.WriteTo(w) n64, error := p.buf.WriteTo(w)
p.free() p.free()
return int(n64), error return int(n64), error
...@@ -337,7 +335,7 @@ func Println(a ...interface{}) (n int, errno os.Error) { ...@@ -337,7 +335,7 @@ func Println(a ...interface{}) (n int, errno os.Error) {
// Spaces are always added between operands and a newline is appended. // Spaces are always added between operands and a newline is appended.
func Sprintln(a ...interface{}) string { func Sprintln(a ...interface{}) string {
p := newPrinter() p := newPrinter()
p.doprint(a, true, true) p.doPrint(a, true, true)
s := p.buf.String() s := p.buf.String()
p.free() p.free()
return s return s
...@@ -357,225 +355,277 @@ func getField(v *reflect.StructValue, i int) reflect.Value { ...@@ -357,225 +355,277 @@ func getField(v *reflect.StructValue, i int) reflect.Value {
return val return val
} }
// Getters for the fields of the argument structure. // Convert ASCII to integer. n is 0 (and got is false) if no number present.
func parsenum(s string, start, end int) (num int, isnum bool, newi int) {
func getBool(a interface{}) (val bool, ok bool) { if start >= end {
// Is it a regular bool type? return 0, false, end
if b, ok := a.(bool); ok {
return b, true
} }
// Must be a renamed bool type. for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ {
if b, ok := reflect.NewValue(a).(*reflect.BoolValue); ok { num = num*10 + int(s[newi]-'0')
return b.Get(), true isnum = true
} }
return return
} }
func getInt(a interface{}) (val int64, signed, ok bool) { // Reflection values like reflect.FuncValue implement this method. We use it for %p.
// Is it a predeclared integer type? type uintptrGetter interface {
switch i := a.(type) { Get() uintptr
case int: }
return int64(i), true, true
case int8: func (p *pp) unknownType(v interface{}) {
return int64(i), true, true if v == nil {
case int16: p.buf.Write(nilAngleBytes)
return int64(i), true, true
case int32:
return int64(i), true, true
case int64:
return i, true, true
case uint:
return int64(i), false, true
case uint8:
return int64(i), false, true
case uint16:
return int64(i), false, true
case uint32:
return int64(i), false, true
case uint64:
return int64(i), false, true
case uintptr:
return int64(i), false, true
}
// Must be a renamed integer type.
switch i := reflect.NewValue(a).(type) {
case *reflect.IntValue:
return int64(i.Get()), true, true
case *reflect.Int8Value:
return int64(i.Get()), true, true
case *reflect.Int16Value:
return int64(i.Get()), true, true
case *reflect.Int32Value:
return int64(i.Get()), true, true
case *reflect.Int64Value:
return i.Get(), true, true
case *reflect.UintValue:
return int64(i.Get()), false, true
case *reflect.Uint8Value:
return int64(i.Get()), false, true
case *reflect.Uint16Value:
return int64(i.Get()), false, true
case *reflect.Uint32Value:
return int64(i.Get()), false, true
case *reflect.Uint64Value:
return int64(i.Get()), false, true
case *reflect.UintptrValue:
return int64(i.Get()), false, true
}
return return
}
p.buf.WriteByte('?')
p.buf.WriteString(reflect.Typeof(v).String())
p.buf.WriteByte('?')
} }
func getString(a interface{}) (val string, ok bool) { func (p *pp) badVerb(verb int, val interface{}) {
if a == nil { p.add('%')
return "<nil>", ok p.add(verb)
p.add('(')
if val == nil {
p.buf.Write(nilAngleBytes)
} else {
p.buf.WriteString(reflect.Typeof(val).String())
p.add('=')
p.printField(val, 'v', false, false, 0)
} }
// Is it a regular string or []byte type? p.add(')')
switch s := a.(type) { }
case string:
return s, true func (p *pp) fmtBool(v bool, verb int, value interface{}) {
case []byte: switch verb {
return string(s), true case 't', 'v':
p.fmt.fmt_boolean(v)
default:
p.badVerb(verb, value)
} }
// Must be a renamed string or []byte type. }
v := reflect.NewValue(a)
if s, ok := v.(*reflect.StringValue); ok { // fmtC formats a rune for the 'c' format.
return s.Get(), true func (p *pp) fmtC(c int64) {
rune := int(c) // Check for overflow.
if int64(rune) != c {
rune = utf8.RuneError
} }
if bytes, ok := v.Interface().([]byte); ok { w := utf8.EncodeRune(rune, p.runeBuf[0:utf8.UTFMax])
return string(bytes), true p.fmt.pad(p.runeBuf[0:w])
}
func (p *pp) fmtInt64(v int64, verb int, value interface{}) {
switch verb {
case 'b':
p.fmt.integer(v, 2, signed, ldigits)
case 'c':
p.fmtC(v)
case 'd', 'v':
p.fmt.integer(v, 10, signed, ldigits)
case 'o':
p.fmt.integer(v, 8, signed, ldigits)
case 'x':
p.fmt.integer(v, 16, signed, ldigits)
case 'X':
p.fmt.integer(v, 16, signed, udigits)
default:
p.badVerb(verb, value)
} }
return
} }
var floatBits = reflect.Typeof(float(0)).Size() * 8 // fmt_sharpHex64 formats a uint64 in hexadecimal and prefixes it with 0x by
// temporarily turning on the sharp flag.
func (p *pp) fmt0x64(v uint64) {
sharp := p.fmt.sharp
p.fmt.sharp = true // turn on 0x
p.fmt.integer(int64(v), 16, unsigned, ldigits)
p.fmt.sharp = sharp
}
func getFloat32(a interface{}) (val float32, ok bool) { func (p *pp) fmtUint64(v uint64, verb int, sharp bool, value interface{}) {
// Is it a regular floating-point type? switch verb {
switch f := a.(type) { case 'b':
case float32: p.fmt.integer(int64(v), 2, unsigned, ldigits)
return f, true case 'c':
case float: p.fmtC(int64(v))
if floatBits == 32 { case 'd':
return float32(f), true p.fmt.integer(int64(v), 10, unsigned, ldigits)
} case 'v':
} if sharp {
// Must be a renamed floating-point type. p.fmt0x64(v)
switch f := reflect.NewValue(a).(type) { } else {
case *reflect.Float32Value: p.fmt.integer(int64(v), 10, unsigned, ldigits)
return float32(f.Get()), true
case *reflect.FloatValue:
if floatBits == 32 {
return float32(f.Get()), true
} }
case 'o':
p.fmt.integer(int64(v), 8, unsigned, ldigits)
case 'x':
p.fmt.integer(int64(v), 16, unsigned, ldigits)
case 'X':
p.fmt.integer(int64(v), 16, unsigned, udigits)
default:
p.badVerb(verb, value)
} }
return
} }
func getFloat64(a interface{}) (val float64, ok bool) { var floatBits = reflect.Typeof(float(0)).Size() * 8
// Is it a regular floating-point type?
switch f := a.(type) { func (p *pp) fmtFloat32(v float32, verb int, value interface{}) {
case float64: switch verb {
return f, true case 'b':
case float: p.fmt.fmt_fb32(v)
if floatBits == 64 { case 'e':
return float64(f), true p.fmt.fmt_e32(v)
} case 'E':
} p.fmt.fmt_E32(v)
// Must be a renamed floating-point type. case 'f':
switch f := reflect.NewValue(a).(type) { p.fmt.fmt_f32(v)
case *reflect.Float64Value: case 'g', 'v':
return float64(f.Get()), true p.fmt.fmt_g32(v)
case *reflect.FloatValue: case 'G':
if floatBits == 64 { p.fmt.fmt_G32(v)
return float64(f.Get()), true default:
p.badVerb(verb, value)
} }
}
func (p *pp) fmtFloat64(v float64, verb int, value interface{}) {
switch verb {
case 'b':
p.fmt.fmt_fb64(v)
case 'e':
p.fmt.fmt_e64(v)
case 'E':
p.fmt.fmt_E64(v)
case 'f':
p.fmt.fmt_f64(v)
case 'g', 'v':
p.fmt.fmt_g64(v)
case 'G':
p.fmt.fmt_G64(v)
default:
p.badVerb(verb, value)
} }
return
} }
var complexBits = reflect.Typeof(complex(0i)).Size() * 8 var complexBits = reflect.Typeof(complex(0i)).Size() * 8
func getComplex64(a interface{}) (val complex64, ok bool) { func (p *pp) fmtComplex64(v complex64, verb int, value interface{}) {
// Is it a regular complex type? switch verb {
switch c := a.(type) { case 'e', 'E', 'f', 'F', 'g', 'G':
case complex64: p.fmt.fmt_c64(v, verb)
return c, true case 'v':
case complex: p.fmt.fmt_c64(v, 'g')
if complexBits == 64 { default:
return complex64(c), true p.badVerb(verb, value)
} }
}
func (p *pp) fmtComplex128(v complex128, verb int, value interface{}) {
switch verb {
case 'e', 'E', 'f', 'F', 'g', 'G':
p.fmt.fmt_c128(v, verb)
case 'v':
p.fmt.fmt_c128(v, 'g')
default:
p.badVerb(verb, value)
} }
// Must be a renamed complex type. }
switch c := reflect.NewValue(a).(type) {
case *reflect.Complex64Value: func (p *pp) fmtString(v string, verb int, sharp bool, value interface{}) {
return complex64(c.Get()), true switch verb {
case *reflect.ComplexValue: case 'v':
if complexBits == 64 { if sharp {
return complex64(c.Get()), true p.fmt.fmt_q(v)
} else {
p.fmt.fmt_s(v)
} }
case 's':
p.fmt.fmt_s(v)
case 'x':
p.fmt.fmt_sx(v)
case 'X':
p.fmt.fmt_sX(v)
case 'q':
p.fmt.fmt_q(v)
default:
p.badVerb(verb, value)
} }
return
} }
func getComplex128(a interface{}) (val complex128, ok bool) { func (p *pp) fmtBytes(v []byte, verb int, sharp bool, depth int, value interface{}) {
// Is it a regular complex type? if verb == 'v' {
switch c := a.(type) { if p.fmt.sharp {
case complex128: p.buf.Write(bytesBytes)
return c, true } else {
case complex: p.buf.WriteByte('[')
if complexBits == 128 {
return complex128(c), true
} }
for i, c := range v {
if i > 0 {
if p.fmt.sharp {
p.buf.Write(commaSpaceBytes)
} else {
p.buf.WriteByte(' ')
} }
// Must be a renamed complex type.
switch c := reflect.NewValue(a).(type) {
case *reflect.Complex128Value:
return complex128(c.Get()), true
case *reflect.ComplexValue:
if complexBits == 128 {
return complex128(c.Get()), true
} }
p.printField(c, 'v', p.fmt.plus, p.fmt.sharp, depth+1)
}
if sharp {
p.buf.WriteByte('}')
} else {
p.buf.WriteByte(']')
} }
return return
}
// Convert ASCII to integer. n is 0 (and got is false) if no number present.
func parsenum(s string, start, end int) (num int, isnum bool, newi int) {
if start >= end {
return 0, false, end
} }
for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ { s := string(v)
num = num*10 + int(s[newi]-'0') switch verb {
isnum = true case 's':
p.fmt.fmt_s(s)
case 'x':
p.fmt.fmt_sx(s)
case 'X':
p.fmt.fmt_sX(s)
case 'q':
p.fmt.fmt_q(s)
default:
p.badVerb(verb, value)
} }
return
} }
type uintptrGetter interface { func (p *pp) fmtUintptrGetter(field interface{}, value reflect.Value, verb int, sharp bool) bool {
Get() uintptr v, ok := value.(uintptrGetter)
} if !ok {
return false
func (p *pp) unknownType(v interface{}) {
if v == nil {
p.buf.Write(nilAngleBytes)
return
} }
p.buf.WriteByte('?') u := v.Get()
p.buf.WriteString(reflect.Typeof(v).String()) if sharp {
p.buf.WriteByte('?') p.add('(')
p.buf.WriteString(reflect.Typeof(field).String())
p.add(')')
p.add('(')
if u == 0 {
p.buf.Write(nilBytes)
} else {
p.fmt0x64(uint64(v.Get()))
}
p.add(')')
} else {
p.fmt0x64(uint64(u))
}
return true
} }
func (p *pp) printField(field interface{}, plus, sharp bool, depth int) (was_string bool) { func (p *pp) printField(field interface{}, verb int, plus, sharp bool, depth int) (was_string bool) {
if field != nil && depth >= 0 { if field != nil {
switch { switch {
default: default:
if stringer, ok := field.(Stringer); ok { if stringer, ok := field.(Stringer); ok {
p.buf.WriteString(stringer.String()) p.printField(stringer.String(), verb, plus, sharp, depth)
return false // this value is not a string return false // this value is not a string
} }
case sharp: case sharp:
if stringer, ok := field.(GoStringer); ok { if stringer, ok := field.(GoStringer); ok {
p.buf.WriteString(stringer.GoString()) p.printField(stringer.GoString(), verb, plus, sharp, depth)
return false // this value is not a string return false // this value is not a string
} }
} }
...@@ -584,83 +634,139 @@ func (p *pp) printField(field interface{}, plus, sharp bool, depth int) (was_str ...@@ -584,83 +634,139 @@ func (p *pp) printField(field interface{}, plus, sharp bool, depth int) (was_str
// Some types can be done without reflection. // Some types can be done without reflection.
switch f := field.(type) { switch f := field.(type) {
case bool: case bool:
p.fmt.fmt_boolean(f) p.fmtBool(f, verb, field)
return false
case float32:
p.fmt.fmt_g32(f)
return false
case float64:
p.fmt.fmt_g64(f)
return false return false
case float: case float:
if floatBits == 32 { if floatBits == 32 {
p.fmt.fmt_g32(float32(f)) p.fmtFloat32(float32(f), verb, field)
} else { } else {
p.fmt.fmt_g64(float64(f)) p.fmtFloat64(float64(f), verb, field)
} }
return false return false
case complex64: case float32:
p.fmt.fmt_c64(f, 'g') p.fmtFloat32(f, verb, field)
return false return false
case complex128: case float64:
p.fmt.fmt_c128(f, 'g') p.fmtFloat64(f, verb, field)
return false return false
case complex: case complex:
if complexBits == 64 { if complexBits == 64 {
p.fmt.fmt_c64(complex64(f), 'g') p.fmtComplex64(complex64(f), verb, field)
} else { } else {
p.fmt.fmt_c128(complex128(f), 'g') p.fmtComplex128(complex128(f), verb, field)
} }
return false return false
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr: case complex64:
v, signed, ok := getInt(field) p.fmtComplex64(complex64(f), verb, field)
if !ok { return false
// cannot happen, but print something to be sure case complex128:
p.unknownType(f) p.fmtComplex128(f, verb, field)
} else { return false
if signed { case int:
p.fmt.fmt_d64(v) p.fmtInt64(int64(f), verb, field)
} else { return false
if sharp { case int8:
p.fmt.sharp = true // turn on 0x p.fmtInt64(int64(f), verb, field)
p.fmt.fmt_ux64(uint64(v)) return false
} else { case int16:
p.fmt.fmt_ud64(uint64(v)) p.fmtInt64(int64(f), verb, field)
} return false
} case int32:
} p.fmtInt64(int64(f), verb, field)
return false
case int64:
p.fmtInt64(f, verb, field)
return false
case uint:
p.fmtUint64(uint64(f), verb, sharp, field)
return false
case uint8:
p.fmtUint64(uint64(f), verb, sharp, field)
return false
case uint16:
p.fmtUint64(uint64(f), verb, sharp, field)
return false
case uint32:
p.fmtUint64(uint64(f), verb, sharp, field)
return false
case uint64:
p.fmtUint64(f, verb, sharp, field)
return false
case uintptr:
p.fmtUint64(uint64(f), verb, sharp, field)
return false return false
case string: case string:
if sharp { p.fmtString(f, verb, sharp, field)
p.fmt.fmt_q(f) return verb == 's' || verb == 'v'
case []byte:
p.fmtBytes(f, verb, sharp, depth, field)
return verb == 's'
}
if field == nil {
if verb == 'v' {
p.buf.Write(nilAngleBytes)
} else { } else {
p.fmt.fmt_s(f) p.badVerb(verb, field)
} }
return true return false
} }
value := reflect.NewValue(field)
// Need to use reflection // Need to use reflection
// Special case for reflection values that know how to print with %p.
if verb == 'p' && p.fmtUintptrGetter(field, value, verb, sharp) {
return false
}
BigSwitch: BigSwitch:
switch f := reflect.NewValue(field).(type) { switch f := value.(type) {
case *reflect.BoolValue: case *reflect.BoolValue:
p.fmt.fmt_boolean(f.Get()) p.fmtBool(f.Get(), verb, field)
case *reflect.Float32Value: case *reflect.IntValue:
p.fmt.fmt_g32(f.Get()) p.fmtInt64(int64(f.Get()), verb, field)
case *reflect.Float64Value: case *reflect.Int8Value:
p.fmt.fmt_g64(f.Get()) p.fmtInt64(int64(f.Get()), verb, field)
case *reflect.Int16Value:
p.fmtInt64(int64(f.Get()), verb, field)
case *reflect.Int32Value:
p.fmtInt64(int64(f.Get()), verb, field)
case *reflect.Int64Value:
p.fmtInt64(f.Get(), verb, field)
case *reflect.UintValue:
p.fmtUint64(uint64(f.Get()), verb, sharp, field)
case *reflect.Uint8Value:
p.fmtUint64(uint64(f.Get()), verb, sharp, field)
case *reflect.Uint16Value:
p.fmtUint64(uint64(f.Get()), verb, sharp, field)
case *reflect.Uint32Value:
p.fmtUint64(uint64(f.Get()), verb, sharp, field)
case *reflect.Uint64Value:
p.fmtUint64(f.Get(), verb, sharp, field)
case *reflect.UintptrValue:
p.fmtUint64(uint64(f.Get()), verb, sharp, field)
case *reflect.FloatValue: case *reflect.FloatValue:
if floatBits == 32 { if floatBits == 32 {
p.fmt.fmt_g32(float32(f.Get())) p.fmtFloat32(float32(f.Get()), verb, field)
} else { } else {
p.fmt.fmt_g64(float64(f.Get())) p.fmtFloat64(float64(f.Get()), verb, field)
} }
case *reflect.StringValue: case *reflect.Float32Value:
if sharp { p.fmtFloat64(float64(f.Get()), verb, field)
p.fmt.fmt_q(f.Get()) case *reflect.Float64Value:
p.fmtFloat64(f.Get(), verb, field)
case *reflect.ComplexValue:
if complexBits == 64 {
p.fmtComplex64(complex64(f.Get()), verb, field)
} else { } else {
p.fmt.fmt_s(f.Get()) p.fmtComplex128(complex128(f.Get()), verb, field)
was_string = true
} }
case *reflect.Complex64Value:
p.fmtComplex64(f.Get(), verb, field)
case *reflect.Complex128Value:
p.fmtComplex128(f.Get(), verb, field)
case *reflect.StringValue:
p.fmtString(f.Get(), verb, sharp, field)
case *reflect.MapValue: case *reflect.MapValue:
if sharp { if sharp {
p.buf.WriteString(f.Type().String()) p.buf.WriteString(f.Type().String())
...@@ -677,9 +783,9 @@ BigSwitch: ...@@ -677,9 +783,9 @@ BigSwitch:
p.buf.WriteByte(' ') p.buf.WriteByte(' ')
} }
} }
p.printField(key.Interface(), plus, sharp, depth+1) p.printField(key.Interface(), verb, plus, sharp, depth+1)
p.buf.WriteByte(':') p.buf.WriteByte(':')
p.printField(f.Elem(key).Interface(), plus, sharp, depth+1) p.printField(f.Elem(key).Interface(), verb, plus, sharp, depth+1)
} }
if sharp { if sharp {
p.buf.WriteByte('}') p.buf.WriteByte('}')
...@@ -708,7 +814,7 @@ BigSwitch: ...@@ -708,7 +814,7 @@ BigSwitch:
p.buf.WriteByte(':') p.buf.WriteByte(':')
} }
} }
p.printField(getField(v, i).Interface(), plus, sharp, depth+1) p.printField(getField(v, i).Interface(), verb, plus, sharp, depth+1)
} }
p.buf.WriteByte('}') p.buf.WriteByte('}')
case *reflect.InterfaceValue: case *reflect.InterfaceValue:
...@@ -721,7 +827,7 @@ BigSwitch: ...@@ -721,7 +827,7 @@ BigSwitch:
p.buf.Write(nilAngleBytes) p.buf.Write(nilAngleBytes)
} }
} else { } else {
return p.printField(value.Interface(), plus, sharp, depth+1) return p.printField(value.Interface(), verb, plus, sharp, depth+1)
} }
case reflect.ArrayOrSliceValue: case reflect.ArrayOrSliceValue:
if sharp { if sharp {
...@@ -738,7 +844,7 @@ BigSwitch: ...@@ -738,7 +844,7 @@ BigSwitch:
p.buf.WriteByte(' ') p.buf.WriteByte(' ')
} }
} }
p.printField(f.Elem(i).Interface(), plus, sharp, depth+1) p.printField(f.Elem(i).Interface(), verb, plus, sharp, depth+1)
} }
if sharp { if sharp {
p.buf.WriteByte('}') p.buf.WriteByte('}')
...@@ -753,11 +859,11 @@ BigSwitch: ...@@ -753,11 +859,11 @@ BigSwitch:
switch a := f.Elem().(type) { switch a := f.Elem().(type) {
case reflect.ArrayOrSliceValue: case reflect.ArrayOrSliceValue:
p.buf.WriteByte('&') p.buf.WriteByte('&')
p.printField(a.Interface(), plus, sharp, depth+1) p.printField(a.Interface(), verb, plus, sharp, depth+1)
break BigSwitch break BigSwitch
case *reflect.StructValue: case *reflect.StructValue:
p.buf.WriteByte('&') p.buf.WriteByte('&')
p.printField(a.Interface(), plus, sharp, depth+1) p.printField(a.Interface(), verb, plus, sharp, depth+1)
break BigSwitch break BigSwitch
} }
} }
...@@ -769,8 +875,7 @@ BigSwitch: ...@@ -769,8 +875,7 @@ BigSwitch:
if v == 0 { if v == 0 {
p.buf.Write(nilBytes) p.buf.Write(nilBytes)
} else { } else {
p.fmt.sharp = true p.fmt0x64(uint64(v))
p.fmt.fmt_ux64(uint64(v))
} }
p.buf.WriteByte(')') p.buf.WriteByte(')')
break break
...@@ -779,47 +884,19 @@ BigSwitch: ...@@ -779,47 +884,19 @@ BigSwitch:
p.buf.Write(nilAngleBytes) p.buf.Write(nilAngleBytes)
break break
} }
p.fmt.sharp = true // turn 0x on p.fmt0x64(uint64(v))
p.fmt.fmt_ux64(uint64(v))
case uintptrGetter: case uintptrGetter:
v := f.Get() if p.fmtUintptrGetter(field, value, verb, sharp) {
if sharp {
p.buf.WriteByte('(')
p.buf.WriteString(reflect.Typeof(field).String())
p.buf.WriteByte(')')
p.buf.WriteByte('(')
if v == 0 {
p.buf.Write(nilBytes)
} else {
p.fmt.sharp = true
p.fmt.fmt_ux64(uint64(v))
}
p.buf.WriteByte(')')
} else {
p.fmt.sharp = true // turn 0x on
p.fmt.fmt_ux64(uint64(f.Get()))
}
default:
v, signed, ok := getInt(field)
if ok {
if signed {
p.fmt.fmt_d64(v)
} else {
if sharp {
p.fmt.sharp = true // turn on 0x
p.fmt.fmt_ux64(uint64(v))
} else {
p.fmt.fmt_ud64(uint64(v))
}
}
break break
} }
p.unknownType(f) p.unknownType(f)
default:
p.unknownType(f)
} }
return false return false
} }
func (p *pp) doprintf(format string, a []interface{}) { func (p *pp) doPrintf(format string, a []interface{}) {
end := len(format) - 1 end := len(format) - 1
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; {
...@@ -875,222 +952,28 @@ func (p *pp) doprintf(format string, a []interface{}) { ...@@ -875,222 +952,28 @@ func (p *pp) doprintf(format string, a []interface{}) {
field := a[fieldnum] field := a[fieldnum]
fieldnum++ fieldnum++
// Try formatter except for %T, // %T is special; we always do it here.
// which is special and handled internally. if c == 'T' {
if field != nil && c != 'T' {
if formatter, ok := field.(Formatter); ok {
formatter.Format(p, c)
continue
}
}
switch c {
// bool
case 't':
if v, ok := getBool(field); ok {
if v {
p.buf.Write(trueBytes)
} else {
p.buf.Write(falseBytes)
}
} else {
goto badtype
}
// int
case 'b':
if v, signed, ok := getInt(field); ok {
if signed {
p.fmt.fmt_b64(v)
} else {
p.fmt.fmt_ub64(uint64(v))
}
} else if v, ok := getFloat32(field); ok {
p.fmt.fmt_fb32(v)
} else if v, ok := getFloat64(field); ok {
p.fmt.fmt_fb64(v)
} else {
goto badtype
}
case 'c':
if v, _, ok := getInt(field); ok {
p.fmt.fmt_c(int(v))
} else {
goto badtype
}
case 'd':
if v, signed, ok := getInt(field); ok {
if signed {
p.fmt.fmt_d64(v)
} else {
p.fmt.fmt_ud64(uint64(v))
}
} else {
goto badtype
}
case 'o':
if v, signed, ok := getInt(field); ok {
if signed {
p.fmt.fmt_o64(v)
} else {
p.fmt.fmt_uo64(uint64(v))
}
} else {
goto badtype
}
case 'x':
if v, signed, ok := getInt(field); ok {
if signed {
p.fmt.fmt_x64(v)
} else {
p.fmt.fmt_ux64(uint64(v))
}
} else if v, ok := getString(field); ok {
p.fmt.fmt_sx(v)
} else {
goto badtype
}
case 'X':
if v, signed, ok := getInt(field); ok {
if signed {
p.fmt.fmt_X64(v)
} else {
p.fmt.fmt_uX64(uint64(v))
}
} else if v, ok := getString(field); ok {
p.fmt.fmt_sX(v)
} else {
goto badtype
}
// float/complex
case 'e':
if v, ok := getFloat32(field); ok {
p.fmt.fmt_e32(v)
} else if v, ok := getFloat64(field); ok {
p.fmt.fmt_e64(v)
} else if v, ok := getComplex64(field); ok {
p.fmt.fmt_c64(v, 'e')
} else if v, ok := getComplex128(field); ok {
p.fmt.fmt_c128(v, 'e')
} else {
goto badtype
}
case 'E':
if v, ok := getFloat32(field); ok {
p.fmt.fmt_E32(v)
} else if v, ok := getFloat64(field); ok {
p.fmt.fmt_E64(v)
} else if v, ok := getComplex64(field); ok {
p.fmt.fmt_c64(v, 'E')
} else if v, ok := getComplex128(field); ok {
p.fmt.fmt_c128(v, 'E')
} else {
goto badtype
}
case 'f':
if v, ok := getFloat32(field); ok {
p.fmt.fmt_f32(v)
} else if v, ok := getFloat64(field); ok {
p.fmt.fmt_f64(v)
} else if v, ok := getComplex64(field); ok {
p.fmt.fmt_c64(v, 'f')
} else if v, ok := getComplex128(field); ok {
p.fmt.fmt_c128(v, 'f')
} else {
goto badtype
}
case 'g':
if v, ok := getFloat32(field); ok {
p.fmt.fmt_g32(v)
} else if v, ok := getFloat64(field); ok {
p.fmt.fmt_g64(v)
} else if v, ok := getComplex64(field); ok {
p.fmt.fmt_c64(v, 'g')
} else if v, ok := getComplex128(field); ok {
p.fmt.fmt_c128(v, 'g')
} else {
goto badtype
}
case 'G':
if v, ok := getFloat32(field); ok {
p.fmt.fmt_G32(v)
} else if v, ok := getFloat64(field); ok {
p.fmt.fmt_G64(v)
} else if v, ok := getComplex64(field); ok {
p.fmt.fmt_c64(v, 'G')
} else if v, ok := getComplex128(field); ok {
p.fmt.fmt_c128(v, 'G')
} else {
goto badtype
}
// string
case 's':
if field != nil {
// if object implements String, use the result.
if stringer, ok := field.(Stringer); ok {
p.fmt.fmt_s(stringer.String())
break
}
}
if v, ok := getString(field); ok {
p.fmt.fmt_s(v)
} else {
goto badtype
}
case 'q':
if field != nil {
// if object implements String, use the result.
if stringer, ok := field.(Stringer); ok {
p.fmt.fmt_q(stringer.String())
break
}
}
if v, ok := getString(field); ok {
p.fmt.fmt_q(v)
} else {
goto badtype
}
// pointer, including addresses of reference types.
case 'p':
switch v := reflect.NewValue(field).(type) {
case getter:
p.fmt.fmt_s("0x")
p.fmt.fmt_uX64(uint64(v.Get()))
default:
goto badtype
}
// arbitrary value; do your best
case 'v':
plus, sharp := p.fmt.plus, p.fmt.sharp
p.fmt.plus = false
p.fmt.sharp = false
p.printField(field, plus, sharp, 0)
// the value's type // the value's type
case 'T':
if field == nil { if field == nil {
p.buf.Write(nilAngleBytes) p.buf.Write(nilAngleBytes)
break break
} }
p.buf.WriteString(reflect.Typeof(field).String()) p.buf.WriteString(reflect.Typeof(field).String())
continue
}
default: // Try Formatter (except for %T).
badtype:
p.buf.WriteByte('%')
p.add(c)
p.buf.WriteByte('(')
if field != nil { if field != nil {
p.buf.WriteString(reflect.Typeof(field).String()) if formatter, ok := field.(Formatter); ok {
p.buf.WriteByte('=') formatter.Format(p, c)
continue
} }
p.printField(field, false, false, -1)
p.buf.WriteByte(')')
} }
p.printField(field, c, p.fmt.plus, p.fmt.sharp, 0)
} }
if fieldnum < len(a) { if fieldnum < len(a) {
p.buf.Write(extraBytes) p.buf.Write(extraBytes)
for ; fieldnum < len(a); fieldnum++ { for ; fieldnum < len(a); fieldnum++ {
...@@ -1099,7 +982,7 @@ func (p *pp) doprintf(format string, a []interface{}) { ...@@ -1099,7 +982,7 @@ func (p *pp) doprintf(format string, a []interface{}) {
p.buf.WriteString(reflect.Typeof(field).String()) p.buf.WriteString(reflect.Typeof(field).String())
p.buf.WriteByte('=') p.buf.WriteByte('=')
} }
p.printField(field, false, false, 0) p.printField(field, 'v', false, false, 0)
if fieldnum+1 < len(a) { if fieldnum+1 < len(a) {
p.buf.Write(commaSpaceBytes) p.buf.Write(commaSpaceBytes)
} }
...@@ -1108,7 +991,7 @@ func (p *pp) doprintf(format string, a []interface{}) { ...@@ -1108,7 +991,7 @@ func (p *pp) doprintf(format string, a []interface{}) {
} }
} }
func (p *pp) doprint(a []interface{}, addspace, addnewline bool) { func (p *pp) doPrint(a []interface{}, addspace, addnewline bool) {
prev_string := false prev_string := false
for fieldnum := 0; fieldnum < len(a); fieldnum++ { for fieldnum := 0; fieldnum < len(a); fieldnum++ {
// always add spaces if we're doing println // always add spaces if we're doing println
...@@ -1119,7 +1002,7 @@ func (p *pp) doprint(a []interface{}, addspace, addnewline bool) { ...@@ -1119,7 +1002,7 @@ func (p *pp) doprint(a []interface{}, addspace, addnewline bool) {
p.buf.WriteByte(' ') p.buf.WriteByte(' ')
} }
} }
prev_string = p.printField(field, false, false, 0) prev_string = p.printField(field, 'v', false, false, 0)
} }
if addnewline { if addnewline {
p.buf.WriteByte('\n') p.buf.WriteByte('\n')
......
...@@ -34,29 +34,6 @@ type ScanfMultiTest struct { ...@@ -34,29 +34,6 @@ type ScanfMultiTest struct {
err string err string
} }
type (
renamedBool bool
renamedInt int
renamedInt8 int8
renamedInt16 int16
renamedInt32 int32
renamedInt64 int64
renamedUint uint
renamedUint8 uint8
renamedUint16 uint16
renamedUint32 uint32
renamedUint64 uint64
renamedUintptr uintptr
renamedString string
renamedBytes []byte
renamedFloat float
renamedFloat32 float32
renamedFloat64 float64
renamedComplex complex
renamedComplex64 complex64
renamedComplex128 complex128
)
var ( var (
boolVal bool boolVal bool
intVal int intVal int
...@@ -122,7 +99,7 @@ func (x *Xs) Scan(state ScanState, verb int) os.Error { ...@@ -122,7 +99,7 @@ func (x *Xs) Scan(state ScanState, verb int) os.Error {
if err != nil { if err != nil {
return err return err
} }
if !testing.MustCompile(string(verb) + "+").MatchString(tok) { if !testing.MustCompile("^" + string(verb) + "+$").MatchString(tok) {
return os.ErrorString("syntax error for xs") return os.ErrorString("syntax error for xs")
} }
*x = Xs(tok) *x = Xs(tok)
......
...@@ -26,21 +26,21 @@ type TF64 float64 ...@@ -26,21 +26,21 @@ type TF64 float64
type TB bool type TB bool
type TS string type TS string
func (v TI) String() string { return Sprintf("I: %d", v) } func (v TI) String() string { return Sprintf("I: %d", int(v)) }
func (v TI8) String() string { return Sprintf("I8: %d", v) } func (v TI8) String() string { return Sprintf("I8: %d", int8(v)) }
func (v TI16) String() string { return Sprintf("I16: %d", v) } func (v TI16) String() string { return Sprintf("I16: %d", int16(v)) }
func (v TI32) String() string { return Sprintf("I32: %d", v) } func (v TI32) String() string { return Sprintf("I32: %d", int32(v)) }
func (v TI64) String() string { return Sprintf("I64: %d", v) } func (v TI64) String() string { return Sprintf("I64: %d", int64(v)) }
func (v TU) String() string { return Sprintf("U: %d", v) } func (v TU) String() string { return Sprintf("U: %d", uint(v)) }
func (v TU8) String() string { return Sprintf("U8: %d", v) } func (v TU8) String() string { return Sprintf("U8: %d", uint8(v)) }
func (v TU16) String() string { return Sprintf("U16: %d", v) } func (v TU16) String() string { return Sprintf("U16: %d", uint16(v)) }
func (v TU32) String() string { return Sprintf("U32: %d", v) } func (v TU32) String() string { return Sprintf("U32: %d", uint32(v)) }
func (v TU64) String() string { return Sprintf("U64: %d", v) } func (v TU64) String() string { return Sprintf("U64: %d", uint64(v)) }
func (v TUI) String() string { return Sprintf("UI: %d", v) } func (v TUI) String() string { return Sprintf("UI: %d", uintptr(v)) }
func (v TF) String() string { return Sprintf("F: %f", v) } func (v TF) String() string { return Sprintf("F: %f", float(v)) }
func (v TF32) String() string { return Sprintf("F32: %f", v) } func (v TF32) String() string { return Sprintf("F32: %f", float32(v)) }
func (v TF64) String() string { return Sprintf("F64: %f", v) } func (v TF64) String() string { return Sprintf("F64: %f", float64(v)) }
func (v TB) String() string { return Sprintf("B: %t", v) } func (v TB) String() string { return Sprintf("B: %t", bool(v)) }
func (v TS) String() string { return Sprintf("S: %q", string(v)) } func (v TS) String() string { return Sprintf("S: %q", string(v)) }
func check(t *testing.T, got, want string) { func check(t *testing.T, got, want string) {
......
...@@ -10,7 +10,7 @@ import "fmt" ...@@ -10,7 +10,7 @@ import "fmt"
type T int type T int
func (t T) String() string { return fmt.Sprintf("T%d", t) } func (t T) String() string { return fmt.Sprintf("T%d", int(t)) }
const ( const (
A T = 1 << (1 << iota) A T = 1 << (1 << iota)
......
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