OSDN Git Service

738734908079a4eb6a8f2e5ce406a993b3b0f2da
[pf3gnuchains/gcc-fork.git] / libgo / go / fmt / print.go
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package fmt
6
7 import (
8         "bytes"
9         "io"
10         "os"
11         "reflect"
12         "unicode"
13         "utf8"
14 )
15
16 // Some constants in the form of bytes, to avoid string overhead.
17 // Needlessly fastidious, I suppose.
18 var (
19         commaSpaceBytes = []byte(", ")
20         nilAngleBytes   = []byte("<nil>")
21         nilParenBytes   = []byte("(nil)")
22         nilBytes        = []byte("nil")
23         mapBytes        = []byte("map[")
24         missingBytes    = []byte("(MISSING)")
25         panicBytes      = []byte("(PANIC=")
26         extraBytes      = []byte("%!(EXTRA ")
27         irparenBytes    = []byte("i)")
28         bytesBytes      = []byte("[]byte{")
29         widthBytes      = []byte("%!(BADWIDTH)")
30         precBytes       = []byte("%!(BADPREC)")
31         noVerbBytes     = []byte("%!(NOVERB)")
32 )
33
34 // State represents the printer state passed to custom formatters.
35 // It provides access to the io.Writer interface plus information about
36 // the flags and options for the operand's format specifier.
37 type State interface {
38         // Write is the function to call to emit formatted output to be printed.
39         Write(b []byte) (ret int, err os.Error)
40         // Width returns the value of the width option and whether it has been set.
41         Width() (wid int, ok bool)
42         // Precision returns the value of the precision option and whether it has been set.
43         Precision() (prec int, ok bool)
44
45         // Flag returns whether the flag c, a character, has been set.
46         Flag(c int) bool
47 }
48
49 // Formatter is the interface implemented by values with a custom formatter.
50 // The implementation of Format may call Sprintf or Fprintf(f) etc.
51 // to generate its output.
52 type Formatter interface {
53         Format(f State, c int)
54 }
55
56 // Stringer is implemented by any value that has a String method,
57 // which defines the ``native'' format for that value.
58 // The String method is used to print values passed as an operand
59 // to a %s or %v format or to an unformatted printer such as Print.
60 type Stringer interface {
61         String() string
62 }
63
64 // GoStringer is implemented by any value that has a GoString method,
65 // which defines the Go syntax for that value.
66 // The GoString method is used to print values passed as an operand
67 // to a %#v format.
68 type GoStringer interface {
69         GoString() string
70 }
71
72 type pp struct {
73         n         int
74         panicking bool
75         buf       bytes.Buffer
76         runeBuf   [utf8.UTFMax]byte
77         fmt       fmt
78 }
79
80 // A cache holds a set of reusable objects.
81 // The buffered channel holds the currently available objects.
82 // If more are needed, the cache creates them by calling new.
83 type cache struct {
84         saved chan interface{}
85         new   func() interface{}
86 }
87
88 func (c *cache) put(x interface{}) {
89         select {
90         case c.saved <- x:
91                 // saved in cache
92         default:
93                 // discard
94         }
95 }
96
97 func (c *cache) get() interface{} {
98         select {
99         case x := <-c.saved:
100                 return x // reused from cache
101         default:
102                 return c.new()
103         }
104         panic("not reached")
105 }
106
107 func newCache(f func() interface{}) *cache {
108         return &cache{make(chan interface{}, 100), f}
109 }
110
111 var ppFree = newCache(func() interface{} { return new(pp) })
112
113 // Allocate a new pp struct or grab a cached one.
114 func newPrinter() *pp {
115         p := ppFree.get().(*pp)
116         p.panicking = false
117         p.fmt.init(&p.buf)
118         return p
119 }
120
121 // Save used pp structs in ppFree; avoids an allocation per invocation.
122 func (p *pp) free() {
123         // Don't hold on to pp structs with large buffers.
124         if cap(p.buf.Bytes()) > 1024 {
125                 return
126         }
127         p.buf.Reset()
128         ppFree.put(p)
129 }
130
131 func (p *pp) Width() (wid int, ok bool) { return p.fmt.wid, p.fmt.widPresent }
132
133 func (p *pp) Precision() (prec int, ok bool) { return p.fmt.prec, p.fmt.precPresent }
134
135 func (p *pp) Flag(b int) bool {
136         switch b {
137         case '-':
138                 return p.fmt.minus
139         case '+':
140                 return p.fmt.plus
141         case '#':
142                 return p.fmt.sharp
143         case ' ':
144                 return p.fmt.space
145         case '0':
146                 return p.fmt.zero
147         }
148         return false
149 }
150
151 func (p *pp) add(c int) {
152         p.buf.WriteRune(c)
153 }
154
155 // Implement Write so we can call Fprintf on a pp (through State), for
156 // recursive use in custom verbs.
157 func (p *pp) Write(b []byte) (ret int, err os.Error) {
158         return p.buf.Write(b)
159 }
160
161 // These routines end in 'f' and take a format string.
162
163 // Fprintf formats according to a format specifier and writes to w.
164 // It returns the number of bytes written and any write error encountered.
165 func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err os.Error) {
166         p := newPrinter()
167         p.doPrintf(format, a)
168         n64, err := p.buf.WriteTo(w)
169         p.free()
170         return int(n64), err
171 }
172
173 // Printf formats according to a format specifier and writes to standard output.
174 // It returns the number of bytes written and any write error encountered.
175 func Printf(format string, a ...interface{}) (n int, err os.Error) {
176         return Fprintf(os.Stdout, format, a...)
177 }
178
179 // Sprintf formats according to a format specifier and returns the resulting string.
180 func Sprintf(format string, a ...interface{}) string {
181         p := newPrinter()
182         p.doPrintf(format, a)
183         s := p.buf.String()
184         p.free()
185         return s
186 }
187
188 // Errorf formats according to a format specifier and returns the string 
189 // converted to an os.ErrorString, which satisfies the os.Error interface.
190 func Errorf(format string, a ...interface{}) os.Error {
191         return os.NewError(Sprintf(format, a...))
192 }
193
194 // These routines do not take a format string
195
196 // Fprint formats using the default formats for its operands and writes to w.
197 // Spaces are added between operands when neither is a string.
198 // It returns the number of bytes written and any write error encountered.
199 func Fprint(w io.Writer, a ...interface{}) (n int, err os.Error) {
200         p := newPrinter()
201         p.doPrint(a, false, false)
202         n64, err := p.buf.WriteTo(w)
203         p.free()
204         return int(n64), err
205 }
206
207 // Print formats using the default formats for its operands and writes to standard output.
208 // Spaces are added between operands when neither is a string.
209 // It returns the number of bytes written and any write error encountered.
210 func Print(a ...interface{}) (n int, err os.Error) {
211         return Fprint(os.Stdout, a...)
212 }
213
214 // Sprint formats using the default formats for its operands and returns the resulting string.
215 // Spaces are added between operands when neither is a string.
216 func Sprint(a ...interface{}) string {
217         p := newPrinter()
218         p.doPrint(a, false, false)
219         s := p.buf.String()
220         p.free()
221         return s
222 }
223
224 // These routines end in 'ln', do not take a format string,
225 // always add spaces between operands, and add a newline
226 // after the last operand.
227
228 // Fprintln formats using the default formats for its operands and writes to w.
229 // Spaces are always added between operands and a newline is appended.
230 // It returns the number of bytes written and any write error encountered.
231 func Fprintln(w io.Writer, a ...interface{}) (n int, err os.Error) {
232         p := newPrinter()
233         p.doPrint(a, true, true)
234         n64, err := p.buf.WriteTo(w)
235         p.free()
236         return int(n64), err
237 }
238
239 // Println formats using the default formats for its operands and writes to standard output.
240 // Spaces are always added between operands and a newline is appended.
241 // It returns the number of bytes written and any write error encountered.
242 func Println(a ...interface{}) (n int, err os.Error) {
243         return Fprintln(os.Stdout, a...)
244 }
245
246 // Sprintln formats using the default formats for its operands and returns the resulting string.
247 // Spaces are always added between operands and a newline is appended.
248 func Sprintln(a ...interface{}) string {
249         p := newPrinter()
250         p.doPrint(a, true, true)
251         s := p.buf.String()
252         p.free()
253         return s
254 }
255
256 // Get the i'th arg of the struct value.
257 // If the arg itself is an interface, return a value for
258 // the thing inside the interface, not the interface itself.
259 func getField(v reflect.Value, i int) reflect.Value {
260         val := v.Field(i)
261         if i := val; i.Kind() == reflect.Interface {
262                 if inter := i.Interface(); inter != nil {
263                         return reflect.ValueOf(inter)
264                 }
265         }
266         return val
267 }
268
269 // Convert ASCII to integer.  n is 0 (and got is false) if no number present.
270 func parsenum(s string, start, end int) (num int, isnum bool, newi int) {
271         if start >= end {
272                 return 0, false, end
273         }
274         for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ {
275                 num = num*10 + int(s[newi]-'0')
276                 isnum = true
277         }
278         return
279 }
280
281 func (p *pp) unknownType(v interface{}) {
282         if v == nil {
283                 p.buf.Write(nilAngleBytes)
284                 return
285         }
286         p.buf.WriteByte('?')
287         p.buf.WriteString(reflect.TypeOf(v).String())
288         p.buf.WriteByte('?')
289 }
290
291 func (p *pp) badVerb(verb int, val interface{}) {
292         p.add('%')
293         p.add('!')
294         p.add(verb)
295         p.add('(')
296         if val == nil {
297                 p.buf.Write(nilAngleBytes)
298         } else {
299                 p.buf.WriteString(reflect.TypeOf(val).String())
300                 p.add('=')
301                 p.printField(val, 'v', false, false, 0)
302         }
303         p.add(')')
304 }
305
306 func (p *pp) fmtBool(v bool, verb int, value interface{}) {
307         switch verb {
308         case 't', 'v':
309                 p.fmt.fmt_boolean(v)
310         default:
311                 p.badVerb(verb, value)
312         }
313 }
314
315 // fmtC formats a rune for the 'c' format.
316 func (p *pp) fmtC(c int64) {
317         rune := int(c) // Check for overflow.
318         if int64(rune) != c {
319                 rune = utf8.RuneError
320         }
321         w := utf8.EncodeRune(p.runeBuf[0:utf8.UTFMax], rune)
322         p.fmt.pad(p.runeBuf[0:w])
323 }
324
325 func (p *pp) fmtInt64(v int64, verb int, value interface{}) {
326         switch verb {
327         case 'b':
328                 p.fmt.integer(v, 2, signed, ldigits)
329         case 'c':
330                 p.fmtC(v)
331         case 'd', 'v':
332                 p.fmt.integer(v, 10, signed, ldigits)
333         case 'o':
334                 p.fmt.integer(v, 8, signed, ldigits)
335         case 'q':
336                 if 0 <= v && v <= unicode.MaxRune {
337                         p.fmt.fmt_qc(v)
338                 } else {
339                         p.badVerb(verb, value)
340                 }
341         case 'x':
342                 p.fmt.integer(v, 16, signed, ldigits)
343         case 'U':
344                 p.fmtUnicode(v)
345         case 'X':
346                 p.fmt.integer(v, 16, signed, udigits)
347         default:
348                 p.badVerb(verb, value)
349         }
350 }
351
352 // fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x or
353 // not, as requested, by temporarily setting the sharp flag.
354 func (p *pp) fmt0x64(v uint64, leading0x bool) {
355         sharp := p.fmt.sharp
356         p.fmt.sharp = leading0x
357         p.fmt.integer(int64(v), 16, unsigned, ldigits)
358         p.fmt.sharp = sharp
359 }
360
361 // fmtUnicode formats a uint64 in U+1234 form by
362 // temporarily turning on the unicode flag and tweaking the precision.
363 func (p *pp) fmtUnicode(v int64) {
364         precPresent := p.fmt.precPresent
365         sharp := p.fmt.sharp
366         p.fmt.sharp = false
367         prec := p.fmt.prec
368         if !precPresent {
369                 // If prec is already set, leave it alone; otherwise 4 is minimum.
370                 p.fmt.prec = 4
371                 p.fmt.precPresent = true
372         }
373         p.fmt.unicode = true // turn on U+
374         p.fmt.uniQuote = sharp
375         p.fmt.integer(int64(v), 16, unsigned, udigits)
376         p.fmt.unicode = false
377         p.fmt.uniQuote = false
378         p.fmt.prec = prec
379         p.fmt.precPresent = precPresent
380         p.fmt.sharp = sharp
381 }
382
383 func (p *pp) fmtUint64(v uint64, verb int, goSyntax bool, value interface{}) {
384         switch verb {
385         case 'b':
386                 p.fmt.integer(int64(v), 2, unsigned, ldigits)
387         case 'c':
388                 p.fmtC(int64(v))
389         case 'd':
390                 p.fmt.integer(int64(v), 10, unsigned, ldigits)
391         case 'v':
392                 if goSyntax {
393                         p.fmt0x64(v, true)
394                 } else {
395                         p.fmt.integer(int64(v), 10, unsigned, ldigits)
396                 }
397         case 'o':
398                 p.fmt.integer(int64(v), 8, unsigned, ldigits)
399         case 'q':
400                 if 0 <= v && v <= unicode.MaxRune {
401                         p.fmt.fmt_qc(int64(v))
402                 } else {
403                         p.badVerb(verb, value)
404                 }
405         case 'x':
406                 p.fmt.integer(int64(v), 16, unsigned, ldigits)
407         case 'X':
408                 p.fmt.integer(int64(v), 16, unsigned, udigits)
409         case 'U':
410                 p.fmtUnicode(int64(v))
411         default:
412                 p.badVerb(verb, value)
413         }
414 }
415
416 func (p *pp) fmtFloat32(v float32, verb int, value interface{}) {
417         switch verb {
418         case 'b':
419                 p.fmt.fmt_fb32(v)
420         case 'e':
421                 p.fmt.fmt_e32(v)
422         case 'E':
423                 p.fmt.fmt_E32(v)
424         case 'f':
425                 p.fmt.fmt_f32(v)
426         case 'g', 'v':
427                 p.fmt.fmt_g32(v)
428         case 'G':
429                 p.fmt.fmt_G32(v)
430         default:
431                 p.badVerb(verb, value)
432         }
433 }
434
435 func (p *pp) fmtFloat64(v float64, verb int, value interface{}) {
436         switch verb {
437         case 'b':
438                 p.fmt.fmt_fb64(v)
439         case 'e':
440                 p.fmt.fmt_e64(v)
441         case 'E':
442                 p.fmt.fmt_E64(v)
443         case 'f':
444                 p.fmt.fmt_f64(v)
445         case 'g', 'v':
446                 p.fmt.fmt_g64(v)
447         case 'G':
448                 p.fmt.fmt_G64(v)
449         default:
450                 p.badVerb(verb, value)
451         }
452 }
453
454 func (p *pp) fmtComplex64(v complex64, verb int, value interface{}) {
455         switch verb {
456         case 'e', 'E', 'f', 'F', 'g', 'G':
457                 p.fmt.fmt_c64(v, verb)
458         case 'v':
459                 p.fmt.fmt_c64(v, 'g')
460         default:
461                 p.badVerb(verb, value)
462         }
463 }
464
465 func (p *pp) fmtComplex128(v complex128, verb int, value interface{}) {
466         switch verb {
467         case 'e', 'E', 'f', 'F', 'g', 'G':
468                 p.fmt.fmt_c128(v, verb)
469         case 'v':
470                 p.fmt.fmt_c128(v, 'g')
471         default:
472                 p.badVerb(verb, value)
473         }
474 }
475
476 func (p *pp) fmtString(v string, verb int, goSyntax bool, value interface{}) {
477         switch verb {
478         case 'v':
479                 if goSyntax {
480                         p.fmt.fmt_q(v)
481                 } else {
482                         p.fmt.fmt_s(v)
483                 }
484         case 's':
485                 p.fmt.fmt_s(v)
486         case 'x':
487                 p.fmt.fmt_sx(v)
488         case 'X':
489                 p.fmt.fmt_sX(v)
490         case 'q':
491                 p.fmt.fmt_q(v)
492         default:
493                 p.badVerb(verb, value)
494         }
495 }
496
497 func (p *pp) fmtBytes(v []byte, verb int, goSyntax bool, depth int, value interface{}) {
498         if verb == 'v' || verb == 'd' {
499                 if goSyntax {
500                         p.buf.Write(bytesBytes)
501                 } else {
502                         p.buf.WriteByte('[')
503                 }
504                 for i, c := range v {
505                         if i > 0 {
506                                 if goSyntax {
507                                         p.buf.Write(commaSpaceBytes)
508                                 } else {
509                                         p.buf.WriteByte(' ')
510                                 }
511                         }
512                         p.printField(c, 'v', p.fmt.plus, goSyntax, depth+1)
513                 }
514                 if goSyntax {
515                         p.buf.WriteByte('}')
516                 } else {
517                         p.buf.WriteByte(']')
518                 }
519                 return
520         }
521         s := string(v)
522         switch verb {
523         case 's':
524                 p.fmt.fmt_s(s)
525         case 'x':
526                 p.fmt.fmt_sx(s)
527         case 'X':
528                 p.fmt.fmt_sX(s)
529         case 'q':
530                 p.fmt.fmt_q(s)
531         default:
532                 p.badVerb(verb, value)
533         }
534 }
535
536 func (p *pp) fmtPointer(field interface{}, value reflect.Value, verb int, goSyntax bool) {
537         var u uintptr
538         switch value.Kind() {
539         case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
540                 u = value.Pointer()
541         default:
542                 p.badVerb(verb, field)
543                 return
544         }
545         if goSyntax {
546                 p.add('(')
547                 p.buf.WriteString(reflect.TypeOf(field).String())
548                 p.add(')')
549                 p.add('(')
550                 if u == 0 {
551                         p.buf.Write(nilBytes)
552                 } else {
553                         p.fmt0x64(uint64(u), true)
554                 }
555                 p.add(')')
556         } else {
557                 p.fmt0x64(uint64(u), !p.fmt.sharp)
558         }
559 }
560
561 var (
562         intBits     = reflect.TypeOf(0).Bits()
563         floatBits   = reflect.TypeOf(0.0).Bits()
564         complexBits = reflect.TypeOf(1i).Bits()
565         uintptrBits = reflect.TypeOf(uintptr(0)).Bits()
566 )
567
568 func (p *pp) catchPanic(val interface{}, verb int) {
569         if err := recover(); err != nil {
570                 // If it's a nil pointer, just say "<nil>". The likeliest causes are a
571                 // Stringer that fails to guard against nil or a nil pointer for a
572                 // value receiver, and in either case, "<nil>" is a nice result.
573                 if v := reflect.ValueOf(val); v.Kind() == reflect.Ptr && v.IsNil() {
574                         p.buf.Write(nilAngleBytes)
575                         return
576                 }
577                 // Otherwise print a concise panic message. Most of the time the panic
578                 // value will print itself nicely.
579                 if p.panicking {
580                         // Nested panics; the recursion in printField cannot succeed.
581                         panic(err)
582                 }
583                 p.buf.WriteByte('%')
584                 p.add(verb)
585                 p.buf.Write(panicBytes)
586                 p.panicking = true
587                 p.printField(err, 'v', false, false, 0)
588                 p.panicking = false
589                 p.buf.WriteByte(')')
590         }
591 }
592
593 func (p *pp) printField(field interface{}, verb int, plus, goSyntax bool, depth int) (wasString bool) {
594         if field == nil {
595                 if verb == 'T' || verb == 'v' {
596                         p.buf.Write(nilAngleBytes)
597                 } else {
598                         p.badVerb(verb, field)
599                 }
600                 return false
601         }
602
603         // Special processing considerations.
604         // %T (the value's type) and %p (its address) are special; we always do them first.
605         switch verb {
606         case 'T':
607                 p.printField(reflect.TypeOf(field).String(), 's', false, false, 0)
608                 return false
609         case 'p':
610                 p.fmtPointer(field, reflect.ValueOf(field), verb, goSyntax)
611                 return false
612         }
613         // Is it a Formatter?
614         if formatter, ok := field.(Formatter); ok {
615                 defer p.catchPanic(field, verb)
616                 formatter.Format(p, verb)
617                 return false // this value is not a string
618
619         }
620         // Must not touch flags before Formatter looks at them.
621         if plus {
622                 p.fmt.plus = false
623         }
624         // If we're doing Go syntax and the field knows how to supply it, take care of it now.
625         if goSyntax {
626                 p.fmt.sharp = false
627                 if stringer, ok := field.(GoStringer); ok {
628                         defer p.catchPanic(field, verb)
629                         // Print the result of GoString unadorned.
630                         p.fmtString(stringer.GoString(), 's', false, field)
631                         return false // this value is not a string
632                 }
633         } else {
634                 // Is it a Stringer?
635                 if stringer, ok := field.(Stringer); ok {
636                         defer p.catchPanic(field, verb)
637                         p.printField(stringer.String(), verb, plus, false, depth)
638                         return false // this value is not a string
639                 }
640         }
641
642         // Some types can be done without reflection.
643         switch f := field.(type) {
644         case bool:
645                 p.fmtBool(f, verb, field)
646                 return false
647         case float32:
648                 p.fmtFloat32(f, verb, field)
649                 return false
650         case float64:
651                 p.fmtFloat64(f, verb, field)
652                 return false
653         case complex64:
654                 p.fmtComplex64(complex64(f), verb, field)
655                 return false
656         case complex128:
657                 p.fmtComplex128(f, verb, field)
658                 return false
659         case int:
660                 p.fmtInt64(int64(f), verb, field)
661                 return false
662         case int8:
663                 p.fmtInt64(int64(f), verb, field)
664                 return false
665         case int16:
666                 p.fmtInt64(int64(f), verb, field)
667                 return false
668         case int32:
669                 p.fmtInt64(int64(f), verb, field)
670                 return false
671         case int64:
672                 p.fmtInt64(f, verb, field)
673                 return false
674         case uint:
675                 p.fmtUint64(uint64(f), verb, goSyntax, field)
676                 return false
677         case uint8:
678                 p.fmtUint64(uint64(f), verb, goSyntax, field)
679                 return false
680         case uint16:
681                 p.fmtUint64(uint64(f), verb, goSyntax, field)
682                 return false
683         case uint32:
684                 p.fmtUint64(uint64(f), verb, goSyntax, field)
685                 return false
686         case uint64:
687                 p.fmtUint64(f, verb, goSyntax, field)
688                 return false
689         case uintptr:
690                 p.fmtUint64(uint64(f), verb, goSyntax, field)
691                 return false
692         case string:
693                 p.fmtString(f, verb, goSyntax, field)
694                 return verb == 's' || verb == 'v'
695         case []byte:
696                 p.fmtBytes(f, verb, goSyntax, depth, field)
697                 return verb == 's'
698         }
699
700         // Need to use reflection
701         value := reflect.ValueOf(field)
702
703 BigSwitch:
704         switch f := value; f.Kind() {
705         case reflect.Bool:
706                 p.fmtBool(f.Bool(), verb, field)
707         case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
708                 p.fmtInt64(f.Int(), verb, field)
709         case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
710                 p.fmtUint64(uint64(f.Uint()), verb, goSyntax, field)
711         case reflect.Float32, reflect.Float64:
712                 if f.Type().Size() == 4 {
713                         p.fmtFloat32(float32(f.Float()), verb, field)
714                 } else {
715                         p.fmtFloat64(float64(f.Float()), verb, field)
716                 }
717         case reflect.Complex64, reflect.Complex128:
718                 if f.Type().Size() == 8 {
719                         p.fmtComplex64(complex64(f.Complex()), verb, field)
720                 } else {
721                         p.fmtComplex128(complex128(f.Complex()), verb, field)
722                 }
723         case reflect.String:
724                 p.fmtString(f.String(), verb, goSyntax, field)
725         case reflect.Map:
726                 if goSyntax {
727                         p.buf.WriteString(f.Type().String())
728                         p.buf.WriteByte('{')
729                 } else {
730                         p.buf.Write(mapBytes)
731                 }
732                 keys := f.MapKeys()
733                 for i, key := range keys {
734                         if i > 0 {
735                                 if goSyntax {
736                                         p.buf.Write(commaSpaceBytes)
737                                 } else {
738                                         p.buf.WriteByte(' ')
739                                 }
740                         }
741                         p.printField(key.Interface(), verb, plus, goSyntax, depth+1)
742                         p.buf.WriteByte(':')
743                         p.printField(f.MapIndex(key).Interface(), verb, plus, goSyntax, depth+1)
744                 }
745                 if goSyntax {
746                         p.buf.WriteByte('}')
747                 } else {
748                         p.buf.WriteByte(']')
749                 }
750         case reflect.Struct:
751                 if goSyntax {
752                         p.buf.WriteString(reflect.TypeOf(field).String())
753                 }
754                 p.add('{')
755                 v := f
756                 t := v.Type()
757                 for i := 0; i < v.NumField(); i++ {
758                         if i > 0 {
759                                 if goSyntax {
760                                         p.buf.Write(commaSpaceBytes)
761                                 } else {
762                                         p.buf.WriteByte(' ')
763                                 }
764                         }
765                         if plus || goSyntax {
766                                 if f := t.Field(i); f.Name != "" {
767                                         p.buf.WriteString(f.Name)
768                                         p.buf.WriteByte(':')
769                                 }
770                         }
771                         p.printField(getField(v, i).Interface(), verb, plus, goSyntax, depth+1)
772                 }
773                 p.buf.WriteByte('}')
774         case reflect.Interface:
775                 value := f.Elem()
776                 if !value.IsValid() {
777                         if goSyntax {
778                                 p.buf.WriteString(reflect.TypeOf(field).String())
779                                 p.buf.Write(nilParenBytes)
780                         } else {
781                                 p.buf.Write(nilAngleBytes)
782                         }
783                 } else {
784                         return p.printField(value.Interface(), verb, plus, goSyntax, depth+1)
785                 }
786         case reflect.Array, reflect.Slice:
787                 // Byte slices are special.
788                 if f.Type().Elem().Kind() == reflect.Uint8 {
789                         // We know it's a slice of bytes, but we also know it does not have static type
790                         // []byte, or it would have been caught above.  Therefore we cannot convert
791                         // it directly in the (slightly) obvious way: f.Interface().([]byte); it doesn't have
792                         // that type, and we can't write an expression of the right type and do a
793                         // conversion because we don't have a static way to write the right type.
794                         // So we build a slice by hand.  This is a rare case but it would be nice
795                         // if reflection could help a little more.
796                         bytes := make([]byte, f.Len())
797                         for i := range bytes {
798                                 bytes[i] = byte(f.Index(i).Uint())
799                         }
800                         p.fmtBytes(bytes, verb, goSyntax, depth, field)
801                         return verb == 's'
802                 }
803                 if goSyntax {
804                         p.buf.WriteString(reflect.TypeOf(field).String())
805                         p.buf.WriteByte('{')
806                 } else {
807                         p.buf.WriteByte('[')
808                 }
809                 for i := 0; i < f.Len(); i++ {
810                         if i > 0 {
811                                 if goSyntax {
812                                         p.buf.Write(commaSpaceBytes)
813                                 } else {
814                                         p.buf.WriteByte(' ')
815                                 }
816                         }
817                         p.printField(f.Index(i).Interface(), verb, plus, goSyntax, depth+1)
818                 }
819                 if goSyntax {
820                         p.buf.WriteByte('}')
821                 } else {
822                         p.buf.WriteByte(']')
823                 }
824         case reflect.Ptr:
825                 v := f.Pointer()
826                 // pointer to array or slice or struct?  ok at top level
827                 // but not embedded (avoid loops)
828                 if v != 0 && depth == 0 {
829                         switch a := f.Elem(); a.Kind() {
830                         case reflect.Array, reflect.Slice:
831                                 p.buf.WriteByte('&')
832                                 p.printField(a.Interface(), verb, plus, goSyntax, depth+1)
833                                 break BigSwitch
834                         case reflect.Struct:
835                                 p.buf.WriteByte('&')
836                                 p.printField(a.Interface(), verb, plus, goSyntax, depth+1)
837                                 break BigSwitch
838                         }
839                 }
840                 if goSyntax {
841                         p.buf.WriteByte('(')
842                         p.buf.WriteString(reflect.TypeOf(field).String())
843                         p.buf.WriteByte(')')
844                         p.buf.WriteByte('(')
845                         if v == 0 {
846                                 p.buf.Write(nilBytes)
847                         } else {
848                                 p.fmt0x64(uint64(v), true)
849                         }
850                         p.buf.WriteByte(')')
851                         break
852                 }
853                 if v == 0 {
854                         p.buf.Write(nilAngleBytes)
855                         break
856                 }
857                 p.fmt0x64(uint64(v), true)
858         case reflect.Chan, reflect.Func, reflect.UnsafePointer:
859                 p.fmtPointer(field, value, verb, goSyntax)
860         default:
861                 p.unknownType(f)
862         }
863         return false
864 }
865
866 // intFromArg gets the fieldnumth element of a. On return, isInt reports whether the argument has type int.
867 func intFromArg(a []interface{}, end, i, fieldnum int) (num int, isInt bool, newi, newfieldnum int) {
868         newi, newfieldnum = end, fieldnum
869         if i < end && fieldnum < len(a) {
870                 num, isInt = a[fieldnum].(int)
871                 newi, newfieldnum = i+1, fieldnum+1
872         }
873         return
874 }
875
876 func (p *pp) doPrintf(format string, a []interface{}) {
877         end := len(format)
878         fieldnum := 0 // we process one field per non-trivial format
879         for i := 0; i < end; {
880                 lasti := i
881                 for i < end && format[i] != '%' {
882                         i++
883                 }
884                 if i > lasti {
885                         p.buf.WriteString(format[lasti:i])
886                 }
887                 if i >= end {
888                         // done processing format string
889                         break
890                 }
891
892                 // Process one verb
893                 i++
894                 // flags and widths
895                 p.fmt.clearflags()
896         F:
897                 for ; i < end; i++ {
898                         switch format[i] {
899                         case '#':
900                                 p.fmt.sharp = true
901                         case '0':
902                                 p.fmt.zero = true
903                         case '+':
904                                 p.fmt.plus = true
905                         case '-':
906                                 p.fmt.minus = true
907                         case ' ':
908                                 p.fmt.space = true
909                         default:
910                                 break F
911                         }
912                 }
913                 // do we have width?
914                 if i < end && format[i] == '*' {
915                         p.fmt.wid, p.fmt.widPresent, i, fieldnum = intFromArg(a, end, i, fieldnum)
916                         if !p.fmt.widPresent {
917                                 p.buf.Write(widthBytes)
918                         }
919                 } else {
920                         p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end)
921                 }
922                 // do we have precision?
923                 if i < end && format[i] == '.' {
924                         if format[i+1] == '*' {
925                                 p.fmt.prec, p.fmt.precPresent, i, fieldnum = intFromArg(a, end, i+1, fieldnum)
926                                 if !p.fmt.precPresent {
927                                         p.buf.Write(precBytes)
928                                 }
929                         } else {
930                                 p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i+1, end)
931                                 if !p.fmt.precPresent {
932                                         p.fmt.prec = 0
933                                         p.fmt.precPresent = true
934                                 }
935                         }
936                 }
937                 if i >= end {
938                         p.buf.Write(noVerbBytes)
939                         continue
940                 }
941                 c, w := utf8.DecodeRuneInString(format[i:])
942                 i += w
943                 // percent is special - absorbs no operand
944                 if c == '%' {
945                         p.buf.WriteByte('%') // We ignore width and prec.
946                         continue
947                 }
948                 if fieldnum >= len(a) { // out of operands
949                         p.buf.WriteByte('%')
950                         p.add(c)
951                         p.buf.Write(missingBytes)
952                         continue
953                 }
954                 field := a[fieldnum]
955                 fieldnum++
956
957                 goSyntax := c == 'v' && p.fmt.sharp
958                 plus := c == 'v' && p.fmt.plus
959                 p.printField(field, c, plus, goSyntax, 0)
960         }
961
962         if fieldnum < len(a) {
963                 p.buf.Write(extraBytes)
964                 for ; fieldnum < len(a); fieldnum++ {
965                         field := a[fieldnum]
966                         if field != nil {
967                                 p.buf.WriteString(reflect.TypeOf(field).String())
968                                 p.buf.WriteByte('=')
969                         }
970                         p.printField(field, 'v', false, false, 0)
971                         if fieldnum+1 < len(a) {
972                                 p.buf.Write(commaSpaceBytes)
973                         }
974                 }
975                 p.buf.WriteByte(')')
976         }
977 }
978
979 func (p *pp) doPrint(a []interface{}, addspace, addnewline bool) {
980         prevString := false
981         for fieldnum := 0; fieldnum < len(a); fieldnum++ {
982                 p.fmt.clearflags()
983                 // always add spaces if we're doing println
984                 field := a[fieldnum]
985                 if fieldnum > 0 {
986                         isString := field != nil && reflect.TypeOf(field).Kind() == reflect.String
987                         if addspace || !isString && !prevString {
988                                 p.buf.WriteByte(' ')
989                         }
990                 }
991                 prevString = p.printField(field, 'v', false, false, 0)
992         }
993         if addnewline {
994                 p.buf.WriteByte('\n')
995         }
996 }