OSDN Git Service

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