]> Cypherpunks.ru repositories - gostls13.git/commitdiff
fmt.Print*: reimplement to switch on type first.
authorRob Pike <r@golang.org>
Tue, 15 Jun 2010 00:16:35 +0000 (17:16 -0700)
committerRob Pike <r@golang.org>
Tue, 15 Jun 2010 00:16:35 +0000 (17:16 -0700)
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

src/pkg/fmt/fmt_test.go
src/pkg/fmt/format.go
src/pkg/fmt/print.go
src/pkg/fmt/scan_test.go
src/pkg/fmt/stringer_test.go
test/const3.go

index 957ac041fef7263161b3d3b5ac14b0df7178f701..d9bb167dd9015bd8dcbc6ae44c8baa7017f62665 100644 (file)
@@ -13,6 +13,29 @@ import (
        "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) {
        var i1 interface{}
        i1 = "abc"
@@ -43,7 +66,7 @@ type A struct {
 
 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 {
        i I
@@ -58,6 +81,10 @@ type C struct {
 var b byte
 
 var fmttests = []fmtTest{
+       fmtTest{"%d", 12345, "12345"},
+       fmtTest{"%v", 12345, "12345"},
+       fmtTest{"%t", true, "true"},
+
        // basic string
        fmtTest{"%s", "abc", "abc"},
        fmtTest{"%x", "abc", "616263"},
@@ -245,7 +272,10 @@ var fmttests = []fmtTest{
        fmtTest{"%+v", C{1, B{2, 3}}, `{i:1 B:{i:<2> j:3}}`},
 
        // q on Stringable items
+       fmtTest{"%s", I(23), `<23>`},
        fmtTest{"%q", I(23), `"<23>"`},
+       fmtTest{"%x", I(23), `3c32333e`},
+       fmtTest{"%d", I(23), `%d(string=<23>)`},
 
        // %p on non-pointers
        fmtTest{"%p", make(chan int), "PTR"},
@@ -260,6 +290,30 @@ var fmttests = []fmtTest{
        fmtTest{"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"},
        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
        fmtTest{"%d", "hello", "%d(string=hello)"},
        fmtTest{"no args", "hello", "no args?(extra string=hello)"},
index c7a67d3bde325b08a10227fa53b32ee8843c8fa4..62fc9ff1c7cb8be12008132bf612faca53c61cb9 100644 (file)
@@ -234,87 +234,6 @@ func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) {
        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.
 func (f *fmt) fmt_s(s string) {
        if f.precPresent {
@@ -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).
 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.
-// TODO pass in a method rather than a byte when the compilers mature.
-func (f *fmt) fmt_c64(v complex64, fmt_x byte) {
+// fmt_c64 formats a complex64 according to the verb.
+func (f *fmt) fmt_c64(v complex64, verb int) {
        f.buf.WriteByte('(')
        r := real(v)
        f.preserveFlags = true
        for i := 0; ; i++ {
-               switch fmt_x {
+               switch verb {
                case 'e':
                        f.fmt_e32(r)
                case 'E':
@@ -451,14 +369,13 @@ func (f *fmt) fmt_c64(v complex64, fmt_x byte) {
        f.buf.Write(irparenBytes)
 }
 
-// fmt_c128 formats a complex128 according to its fmt_x argument.
-// TODO pass in a method rather than a byte when the compilers mature.
-func (f *fmt) fmt_c128(v complex128, fmt_x byte) {
+// fmt_c128 formats a complex128 according to the verb.
+func (f *fmt) fmt_c128(v complex128, verb int) {
        f.buf.WriteByte('(')
        r := real(v)
        f.preserveFlags = true
        for i := 0; ; i++ {
-               switch fmt_x {
+               switch verb {
                case 'e':
                        f.fmt_e64(r)
                case 'E':
index 7a972d8948604605b8b5230761e5dd0d51aafd16..31bd1f6f734c1124f4ec2d6e74f145725e48efe0 100644 (file)
        can be used for fine control of formatting.
 
        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:
 
        An analogous set of functions scans formatted text to yield
-       values.  Scan and Scanln read from os.Stdin; Fscan and
-       Fscanln read from a specified os.Reader; Sscan and Sscanln
-       read from an argument string.  Sscanln, Fscanln and Sscanln
-       stop scanning at a newline and require that the items be
-       followed by one; the other routines treat newlines as spaces.
+       values.  Scan, Scanf and Scanln read from os.Stdin; Fscan,
+       Fscanf and Fscanln read from a specified os.Reader; Sscan,
+       Sscanf and Sscanln read from an argument string.  Sscanln,
+       Fscanln and Sscanln stop scanning at a newline and require that
+       the items be followed by one; the other routines treat newlines
+       as spaces.
 
        Scanf, Fscanf, and Sscanf parse the arguments according to a
        format string, analogous to that of Printf.  For example, "%x"
@@ -134,8 +141,6 @@ import (
 // Some constants in the form of bytes, to avoid string overhead.
 // Needlessly fastidious, I suppose.
 var (
-       trueBytes       = []byte("true")
-       falseBytes      = []byte("false")
        commaSpaceBytes = []byte(", ")
        nilAngleBytes   = []byte("<nil>")
        nilParenBytes   = []byte("(nil)")
@@ -144,6 +149,7 @@ var (
        missingBytes    = []byte("missing")
        extraBytes      = []byte("?(extra ")
        irparenBytes    = []byte("i)")
+       bytesBytes      = []byte("[]byte{")
 )
 
 // State represents the printer state passed to custom formatters.
@@ -184,14 +190,6 @@ type GoStringer interface {
        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 {
        n       int
        buf     bytes.Buffer
@@ -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.
 func Fprintf(w io.Writer, format string, a ...interface{}) (n int, error os.Error) {
        p := newPrinter()
-       p.doprintf(format, a)
+       p.doPrintf(format, a)
        n64, error := p.buf.WriteTo(w)
        p.free()
        return int(n64), 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.
 func Sprintf(format string, a ...interface{}) string {
        p := newPrinter()
-       p.doprintf(format, a)
+       p.doPrintf(format, a)
        s := p.buf.String()
        p.free()
        return s
@@ -289,7 +287,7 @@ func Sprintf(format string, a ...interface{}) string {
 // Spaces are added between operands when neither is a string.
 func Fprint(w io.Writer, a ...interface{}) (n int, error os.Error) {
        p := newPrinter()
-       p.doprint(a, false, false)
+       p.doPrint(a, false, false)
        n64, error := p.buf.WriteTo(w)
        p.free()
        return int(n64), error
@@ -306,7 +304,7 @@ func Print(a ...interface{}) (n int, errno os.Error) {
 // Spaces are added between operands when neither is a string.
 func Sprint(a ...interface{}) string {
        p := newPrinter()
-       p.doprint(a, false, false)
+       p.doPrint(a, false, false)
        s := p.buf.String()
        p.free()
        return s
@@ -320,7 +318,7 @@ func Sprint(a ...interface{}) string {
 // Spaces are always added between operands and a newline is appended.
 func Fprintln(w io.Writer, a ...interface{}) (n int, error os.Error) {
        p := newPrinter()
-       p.doprint(a, true, true)
+       p.doPrint(a, true, true)
        n64, error := p.buf.WriteTo(w)
        p.free()
        return int(n64), 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.
 func Sprintln(a ...interface{}) string {
        p := newPrinter()
-       p.doprint(a, true, true)
+       p.doPrint(a, true, true)
        s := p.buf.String()
        p.free()
        return s
@@ -357,225 +355,277 @@ func getField(v *reflect.StructValue, i int) reflect.Value {
        return val
 }
 
-// Getters for the fields of the argument structure.
-
-func getBool(a interface{}) (val bool, ok bool) {
-       // Is it a regular bool type?
-       if b, ok := a.(bool); ok {
-               return b, true
+// 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
        }
-       // Must be a renamed bool type.
-       if b, ok := reflect.NewValue(a).(*reflect.BoolValue); ok {
-               return b.Get(), true
+       for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ {
+               num = num*10 + int(s[newi]-'0')
+               isnum = true
        }
        return
 }
 
-func getInt(a interface{}) (val int64, signed, ok bool) {
-       // Is it a predeclared integer type?
-       switch i := a.(type) {
-       case int:
-               return int64(i), true, true
-       case int8:
-               return int64(i), true, true
-       case int16:
-               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
+// Reflection values like reflect.FuncValue implement this method. We use it for %p.
+type uintptrGetter interface {
+       Get() uintptr
+}
+
+func (p *pp) unknownType(v interface{}) {
+       if v == nil {
+               p.buf.Write(nilAngleBytes)
+               return
        }
-       // 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
+       p.buf.WriteByte('?')
+       p.buf.WriteString(reflect.Typeof(v).String())
+       p.buf.WriteByte('?')
+}
+
+func (p *pp) badVerb(verb int, val interface{}) {
+       p.add('%')
+       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)
        }
-       return
+       p.add(')')
 }
 
-func getString(a interface{}) (val string, ok bool) {
-       if a == nil {
-               return "<nil>", ok
+func (p *pp) fmtBool(v bool, verb int, value interface{}) {
+       switch verb {
+       case 't', 'v':
+               p.fmt.fmt_boolean(v)
+       default:
+               p.badVerb(verb, value)
        }
-       // Is it a regular string or []byte type?
-       switch s := a.(type) {
-       case string:
-               return s, true
-       case []byte:
-               return string(s), true
+}
+
+// fmtC formats a rune for the 'c' format.
+func (p *pp) fmtC(c int64) {
+       rune := int(c) // Check for overflow.
+       if int64(rune) != c {
+               rune = utf8.RuneError
        }
-       // Must be a renamed string or []byte type.
-       v := reflect.NewValue(a)
-       if s, ok := v.(*reflect.StringValue); ok {
-               return s.Get(), true
+       w := utf8.EncodeRune(rune, p.runeBuf[0:utf8.UTFMax])
+       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)
        }
-       if bytes, ok := v.Interface().([]byte); ok {
-               return string(bytes), true
+}
+
+// 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 (p *pp) fmtUint64(v uint64, verb int, sharp bool, value interface{}) {
+       switch verb {
+       case 'b':
+               p.fmt.integer(int64(v), 2, unsigned, ldigits)
+       case 'c':
+               p.fmtC(int64(v))
+       case 'd':
+               p.fmt.integer(int64(v), 10, unsigned, ldigits)
+       case 'v':
+               if sharp {
+                       p.fmt0x64(v)
+               } else {
+                       p.fmt.integer(int64(v), 10, unsigned, ldigits)
+               }
+       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
 }
 
 var floatBits = reflect.Typeof(float(0)).Size() * 8
 
-func getFloat32(a interface{}) (val float32, ok bool) {
-       // Is it a regular floating-point type?
-       switch f := a.(type) {
-       case float32:
-               return f, true
-       case float:
-               if floatBits == 32 {
-                       return float32(f), true
-               }
-       }
-       // Must be a renamed floating-point type.
-       switch f := reflect.NewValue(a).(type) {
-       case *reflect.Float32Value:
-               return float32(f.Get()), true
-       case *reflect.FloatValue:
-               if floatBits == 32 {
-                       return float32(f.Get()), true
-               }
+func (p *pp) fmtFloat32(v float32, verb int, value interface{}) {
+       switch verb {
+       case 'b':
+               p.fmt.fmt_fb32(v)
+       case 'e':
+               p.fmt.fmt_e32(v)
+       case 'E':
+               p.fmt.fmt_E32(v)
+       case 'f':
+               p.fmt.fmt_f32(v)
+       case 'g', 'v':
+               p.fmt.fmt_g32(v)
+       case 'G':
+               p.fmt.fmt_G32(v)
+       default:
+               p.badVerb(verb, value)
        }
-       return
 }
 
-func getFloat64(a interface{}) (val float64, ok bool) {
-       // Is it a regular floating-point type?
-       switch f := a.(type) {
-       case float64:
-               return f, true
-       case float:
-               if floatBits == 64 {
-                       return float64(f), true
-               }
-       }
-       // Must be a renamed floating-point type.
-       switch f := reflect.NewValue(a).(type) {
-       case *reflect.Float64Value:
-               return float64(f.Get()), true
-       case *reflect.FloatValue:
-               if floatBits == 64 {
-                       return float64(f.Get()), true
-               }
+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
 
-func getComplex64(a interface{}) (val complex64, ok bool) {
-       // Is it a regular complex type?
-       switch c := a.(type) {
-       case complex64:
-               return c, true
-       case complex:
-               if complexBits == 64 {
-                       return complex64(c), true
-               }
-       }
-       // Must be a renamed complex type.
-       switch c := reflect.NewValue(a).(type) {
-       case *reflect.Complex64Value:
-               return complex64(c.Get()), true
-       case *reflect.ComplexValue:
-               if complexBits == 64 {
-                       return complex64(c.Get()), true
-               }
+func (p *pp) fmtComplex64(v complex64, verb int, value interface{}) {
+       switch verb {
+       case 'e', 'E', 'f', 'F', 'g', 'G':
+               p.fmt.fmt_c64(v, verb)
+       case 'v':
+               p.fmt.fmt_c64(v, 'g')
+       default:
+               p.badVerb(verb, value)
        }
-       return
 }
 
-func getComplex128(a interface{}) (val complex128, ok bool) {
-       // Is it a regular complex type?
-       switch c := a.(type) {
-       case complex128:
-               return c, true
-       case complex:
-               if complexBits == 128 {
-                       return complex128(c), true
-               }
-       }
-       // 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
-               }
+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)
        }
-       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++ {
-               num = num*10 + int(s[newi]-'0')
-               isnum = true
+func (p *pp) fmtString(v string, verb int, sharp bool, value interface{}) {
+       switch verb {
+       case 'v':
+               if sharp {
+                       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
 }
 
-type uintptrGetter interface {
-       Get() uintptr
+func (p *pp) fmtBytes(v []byte, verb int, sharp bool, depth int, value interface{}) {
+       if verb == 'v' {
+               if p.fmt.sharp {
+                       p.buf.Write(bytesBytes)
+               } else {
+                       p.buf.WriteByte('[')
+               }
+               for i, c := range v {
+                       if i > 0 {
+                               if p.fmt.sharp {
+                                       p.buf.Write(commaSpaceBytes)
+                               } else {
+                                       p.buf.WriteByte(' ')
+                               }
+                       }
+                       p.printField(c, 'v', p.fmt.plus, p.fmt.sharp, depth+1)
+               }
+               if sharp {
+                       p.buf.WriteByte('}')
+               } else {
+                       p.buf.WriteByte(']')
+               }
+               return
+       }
+       s := string(v)
+       switch verb {
+       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)
+       }
 }
 
-func (p *pp) unknownType(v interface{}) {
-       if v == nil {
-               p.buf.Write(nilAngleBytes)
-               return
+func (p *pp) fmtUintptrGetter(field interface{}, value reflect.Value, verb int, sharp bool) bool {
+       v, ok := value.(uintptrGetter)
+       if !ok {
+               return false
        }
-       p.buf.WriteByte('?')
-       p.buf.WriteString(reflect.Typeof(v).String())
-       p.buf.WriteByte('?')
+       u := v.Get()
+       if sharp {
+               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) {
-       if field != nil && depth >= 0 {
+func (p *pp) printField(field interface{}, verb int, plus, sharp bool, depth int) (was_string bool) {
+       if field != nil {
                switch {
                default:
                        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
                        }
                case sharp:
                        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
                        }
                }
@@ -584,83 +634,139 @@ func (p *pp) printField(field interface{}, plus, sharp bool, depth int) (was_str
        // Some types can be done without reflection.
        switch f := field.(type) {
        case bool:
-               p.fmt.fmt_boolean(f)
-               return false
-       case float32:
-               p.fmt.fmt_g32(f)
-               return false
-       case float64:
-               p.fmt.fmt_g64(f)
+               p.fmtBool(f, verb, field)
                return false
        case float:
                if floatBits == 32 {
-                       p.fmt.fmt_g32(float32(f))
+                       p.fmtFloat32(float32(f), verb, field)
                } else {
-                       p.fmt.fmt_g64(float64(f))
+                       p.fmtFloat64(float64(f), verb, field)
                }
                return false
-       case complex64:
-               p.fmt.fmt_c64(f, 'g')
+       case float32:
+               p.fmtFloat32(f, verb, field)
                return false
-       case complex128:
-               p.fmt.fmt_c128(f, 'g')
+       case float64:
+               p.fmtFloat64(f, verb, field)
                return false
        case complex:
                if complexBits == 64 {
-                       p.fmt.fmt_c64(complex64(f), 'g')
+                       p.fmtComplex64(complex64(f), verb, field)
                } else {
-                       p.fmt.fmt_c128(complex128(f), 'g')
+                       p.fmtComplex128(complex128(f), verb, field)
                }
                return false
-       case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr:
-               v, signed, ok := getInt(field)
-               if !ok {
-                       // cannot happen, but print something to be sure
-                       p.unknownType(f)
-               } else {
-                       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))
-                               }
-                       }
-               }
+       case complex64:
+               p.fmtComplex64(complex64(f), verb, field)
+               return false
+       case complex128:
+               p.fmtComplex128(f, verb, field)
+               return false
+       case int:
+               p.fmtInt64(int64(f), verb, field)
+               return false
+       case int8:
+               p.fmtInt64(int64(f), verb, field)
+               return false
+       case int16:
+               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
        case string:
-               if sharp {
-                       p.fmt.fmt_q(f)
+               p.fmtString(f, verb, sharp, field)
+               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 {
-                       p.fmt.fmt_s(f)
+                       p.badVerb(verb, field)
                }
-               return true
+               return false
        }
 
+       value := reflect.NewValue(field)
        // 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:
-       switch f := reflect.NewValue(field).(type) {
+       switch f := value.(type) {
        case *reflect.BoolValue:
-               p.fmt.fmt_boolean(f.Get())
-       case *reflect.Float32Value:
-               p.fmt.fmt_g32(f.Get())
-       case *reflect.Float64Value:
-               p.fmt.fmt_g64(f.Get())
+               p.fmtBool(f.Get(), verb, field)
+       case *reflect.IntValue:
+               p.fmtInt64(int64(f.Get()), verb, field)
+       case *reflect.Int8Value:
+               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:
                if floatBits == 32 {
-                       p.fmt.fmt_g32(float32(f.Get()))
+                       p.fmtFloat32(float32(f.Get()), verb, field)
                } else {
-                       p.fmt.fmt_g64(float64(f.Get()))
+                       p.fmtFloat64(float64(f.Get()), verb, field)
                }
-       case *reflect.StringValue:
-               if sharp {
-                       p.fmt.fmt_q(f.Get())
+       case *reflect.Float32Value:
+               p.fmtFloat64(float64(f.Get()), verb, field)
+       case *reflect.Float64Value:
+               p.fmtFloat64(f.Get(), verb, field)
+       case *reflect.ComplexValue:
+               if complexBits == 64 {
+                       p.fmtComplex64(complex64(f.Get()), verb, field)
                } else {
-                       p.fmt.fmt_s(f.Get())
-                       was_string = true
+                       p.fmtComplex128(complex128(f.Get()), verb, field)
                }
+       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:
                if sharp {
                        p.buf.WriteString(f.Type().String())
@@ -677,9 +783,9 @@ BigSwitch:
                                        p.buf.WriteByte(' ')
                                }
                        }
-                       p.printField(key.Interface(), plus, sharp, depth+1)
+                       p.printField(key.Interface(), verb, plus, sharp, depth+1)
                        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 {
                        p.buf.WriteByte('}')
@@ -708,7 +814,7 @@ BigSwitch:
                                        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('}')
        case *reflect.InterfaceValue:
@@ -721,7 +827,7 @@ BigSwitch:
                                p.buf.Write(nilAngleBytes)
                        }
                } else {
-                       return p.printField(value.Interface(), plus, sharp, depth+1)
+                       return p.printField(value.Interface(), verb, plus, sharp, depth+1)
                }
        case reflect.ArrayOrSliceValue:
                if sharp {
@@ -738,7 +844,7 @@ BigSwitch:
                                        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 {
                        p.buf.WriteByte('}')
@@ -753,11 +859,11 @@ BigSwitch:
                        switch a := f.Elem().(type) {
                        case reflect.ArrayOrSliceValue:
                                p.buf.WriteByte('&')
-                               p.printField(a.Interface(), plus, sharp, depth+1)
+                               p.printField(a.Interface(), verb, plus, sharp, depth+1)
                                break BigSwitch
                        case *reflect.StructValue:
                                p.buf.WriteByte('&')
-                               p.printField(a.Interface(), plus, sharp, depth+1)
+                               p.printField(a.Interface(), verb, plus, sharp, depth+1)
                                break BigSwitch
                        }
                }
@@ -769,8 +875,7 @@ BigSwitch:
                        if v == 0 {
                                p.buf.Write(nilBytes)
                        } else {
-                               p.fmt.sharp = true
-                               p.fmt.fmt_ux64(uint64(v))
+                               p.fmt0x64(uint64(v))
                        }
                        p.buf.WriteByte(')')
                        break
@@ -779,47 +884,19 @@ BigSwitch:
                        p.buf.Write(nilAngleBytes)
                        break
                }
-               p.fmt.sharp = true // turn 0x on
-               p.fmt.fmt_ux64(uint64(v))
+               p.fmt0x64(uint64(v))
        case uintptrGetter:
-               v := f.Get()
-               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))
-                               }
-                       }
+               if p.fmtUintptrGetter(field, value, verb, sharp) {
                        break
                }
                p.unknownType(f)
+       default:
+               p.unknownType(f)
        }
        return false
 }
 
-func (p *pp) doprintf(format string, a []interface{}) {
+func (p *pp) doPrintf(format string, a []interface{}) {
        end := len(format) - 1
        fieldnum := 0 // we process one field per non-trivial format
        for i := 0; i <= end; {
@@ -875,222 +952,28 @@ func (p *pp) doprintf(format string, a []interface{}) {
                field := a[fieldnum]
                fieldnum++
 
-               // Try formatter except for %T,
-               // which is special and handled internally.
-               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
-               case 'T':
+               // %T is special; we always do it here.
+               if c == 'T' {
+                       // the value's type
                        if field == nil {
                                p.buf.Write(nilAngleBytes)
                                break
                        }
                        p.buf.WriteString(reflect.Typeof(field).String())
+                       continue
+               }
 
-               default:
-               badtype:
-                       p.buf.WriteByte('%')
-                       p.add(c)
-                       p.buf.WriteByte('(')
-                       if field != nil {
-                               p.buf.WriteString(reflect.Typeof(field).String())
-                               p.buf.WriteByte('=')
+               // Try Formatter (except for %T).
+               if field != nil {
+                       if formatter, ok := field.(Formatter); ok {
+                               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) {
                p.buf.Write(extraBytes)
                for ; fieldnum < len(a); fieldnum++ {
@@ -1099,7 +982,7 @@ func (p *pp) doprintf(format string, a []interface{}) {
                                p.buf.WriteString(reflect.Typeof(field).String())
                                p.buf.WriteByte('=')
                        }
-                       p.printField(field, false, false, 0)
+                       p.printField(field, 'v', false, false, 0)
                        if fieldnum+1 < len(a) {
                                p.buf.Write(commaSpaceBytes)
                        }
@@ -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
        for fieldnum := 0; fieldnum < len(a); fieldnum++ {
                // always add spaces if we're doing println
@@ -1119,7 +1002,7 @@ func (p *pp) doprint(a []interface{}, addspace, addnewline bool) {
                                p.buf.WriteByte(' ')
                        }
                }
-               prev_string = p.printField(field, false, false, 0)
+               prev_string = p.printField(field, 'v', false, false, 0)
        }
        if addnewline {
                p.buf.WriteByte('\n')
index 0ed53e886042efaf8c97afdde14af25de905331e..d876adc9f01d849a90c0f16d8c16d854b6f57b9d 100644 (file)
@@ -34,29 +34,6 @@ type ScanfMultiTest struct {
        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 (
        boolVal              bool
        intVal               int
@@ -122,7 +99,7 @@ func (x *Xs) Scan(state ScanState, verb int) os.Error {
        if err != nil {
                return err
        }
-       if !testing.MustCompile(string(verb) + "+").MatchString(tok) {
+       if !testing.MustCompile("^" + string(verb) + "+$").MatchString(tok) {
                return os.ErrorString("syntax error for xs")
        }
        *x = Xs(tok)
index e4e29bebb85212e518ce2fa49b9de8ea84c46bfe..815147e1ae6ce01b2dee021780dd738abb21b2bc 100644 (file)
@@ -26,21 +26,21 @@ type TF64 float64
 type TB bool
 type TS string
 
-func (v TI) String() string   { return Sprintf("I: %d", v) }
-func (v TI8) String() string  { return Sprintf("I8: %d", v) }
-func (v TI16) String() string { return Sprintf("I16: %d", v) }
-func (v TI32) String() string { return Sprintf("I32: %d", v) }
-func (v TI64) String() string { return Sprintf("I64: %d", v) }
-func (v TU) String() string   { return Sprintf("U: %d", v) }
-func (v TU8) String() string  { return Sprintf("U8: %d", v) }
-func (v TU16) String() string { return Sprintf("U16: %d", v) }
-func (v TU32) String() string { return Sprintf("U32: %d", v) }
-func (v TU64) String() string { return Sprintf("U64: %d", v) }
-func (v TUI) String() string  { return Sprintf("UI: %d", v) }
-func (v TF) String() string   { return Sprintf("F: %f", v) }
-func (v TF32) String() string { return Sprintf("F32: %f", v) }
-func (v TF64) String() string { return Sprintf("F64: %f", v) }
-func (v TB) String() string   { return Sprintf("B: %t", v) }
+func (v TI) String() string   { return Sprintf("I: %d", int(v)) }
+func (v TI8) String() string  { return Sprintf("I8: %d", int8(v)) }
+func (v TI16) String() string { return Sprintf("I16: %d", int16(v)) }
+func (v TI32) String() string { return Sprintf("I32: %d", int32(v)) }
+func (v TI64) String() string { return Sprintf("I64: %d", int64(v)) }
+func (v TU) String() string   { return Sprintf("U: %d", uint(v)) }
+func (v TU8) String() string  { return Sprintf("U8: %d", uint8(v)) }
+func (v TU16) String() string { return Sprintf("U16: %d", uint16(v)) }
+func (v TU32) String() string { return Sprintf("U32: %d", uint32(v)) }
+func (v TU64) String() string { return Sprintf("U64: %d", uint64(v)) }
+func (v TUI) String() string  { return Sprintf("UI: %d", uintptr(v)) }
+func (v TF) String() string   { return Sprintf("F: %f", float(v)) }
+func (v TF32) String() string { return Sprintf("F32: %f", float32(v)) }
+func (v TF64) String() string { return Sprintf("F64: %f", float64(v)) }
+func (v TB) String() string   { return Sprintf("B: %t", bool(v)) }
 func (v TS) String() string   { return Sprintf("S: %q", string(v)) }
 
 func check(t *testing.T, got, want string) {
index d49df2b88ff780dcf27645cdf7c5f1ece9a944fd..dd5c88958d762250b78286e0267f78734a993d14 100644 (file)
@@ -10,7 +10,7 @@ import "fmt"
 
 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 (
        A T = 1 << (1 << iota)