OSDN Git Service

Remove the types float and complex.
[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 leaky bucket of reusable pp structures.
78 var ppFree = make(chan *pp, 100)
79
80 // Allocate a new pp struct.  Probably can grab the previous one from ppFree.
81 func newPrinter() *pp {
82         p, ok := <-ppFree
83         if !ok {
84                 p = new(pp)
85         }
86         p.fmt.init(&p.buf)
87         return p
88 }
89
90 // Save used pp structs in ppFree; avoids an allocation per invocation.
91 func (p *pp) free() {
92         // Don't hold on to pp structs with large buffers.
93         if cap(p.buf.Bytes()) > 1024 {
94                 return
95         }
96         p.buf.Reset()
97         _ = ppFree <- p
98 }
99
100 func (p *pp) Width() (wid int, ok bool) { return p.fmt.wid, p.fmt.widPresent }
101
102 func (p *pp) Precision() (prec int, ok bool) { return p.fmt.prec, p.fmt.precPresent }
103
104 func (p *pp) Flag(b int) bool {
105         switch b {
106         case '-':
107                 return p.fmt.minus
108         case '+':
109                 return p.fmt.plus
110         case '#':
111                 return p.fmt.sharp
112         case ' ':
113                 return p.fmt.space
114         case '0':
115                 return p.fmt.zero
116         }
117         return false
118 }
119
120 func (p *pp) add(c int) {
121         p.buf.WriteRune(c)
122 }
123
124 // Implement Write so we can call Fprintf on a pp (through State), for
125 // recursive use in custom verbs.
126 func (p *pp) Write(b []byte) (ret int, err os.Error) {
127         return p.buf.Write(b)
128 }
129
130 // These routines end in 'f' and take a format string.
131
132 // Fprintf formats according to a format specifier and writes to w.
133 // It returns the number of bytes written and any write error encountered.
134 func Fprintf(w io.Writer, format string, a ...interface{}) (n int, error os.Error) {
135         p := newPrinter()
136         p.doPrintf(format, a)
137         n64, error := p.buf.WriteTo(w)
138         p.free()
139         return int(n64), error
140 }
141
142 // Printf formats according to a format specifier and writes to standard output.
143 // It returns the number of bytes written and any write error encountered.
144 func Printf(format string, a ...interface{}) (n int, errno os.Error) {
145         n, errno = Fprintf(os.Stdout, format, a...)
146         return n, errno
147 }
148
149 // Sprintf formats according to a format specifier and returns the resulting string.
150 func Sprintf(format string, a ...interface{}) string {
151         p := newPrinter()
152         p.doPrintf(format, a)
153         s := p.buf.String()
154         p.free()
155         return s
156 }
157
158 // Errorf formats according to a format specifier and returns the string 
159 // converted to an os.ErrorString, which satisfies the os.Error interface.
160 func Errorf(format string, a ...interface{}) os.Error {
161         return os.ErrorString(Sprintf(format, a...))
162 }
163
164 // These routines do not take a format string
165
166 // Fprint formats using the default formats for its operands and writes to w.
167 // Spaces are added between operands when neither is a string.
168 // It returns the number of bytes written and any write error encountered.
169 func Fprint(w io.Writer, a ...interface{}) (n int, error os.Error) {
170         p := newPrinter()
171         p.doPrint(a, false, false)
172         n64, error := p.buf.WriteTo(w)
173         p.free()
174         return int(n64), error
175 }
176
177 // Print formats using the default formats for its operands and writes to standard output.
178 // Spaces are added between operands when neither is a string.
179 // It returns the number of bytes written and any write error encountered.
180 func Print(a ...interface{}) (n int, errno os.Error) {
181         n, errno = Fprint(os.Stdout, a...)
182         return n, errno
183 }
184
185 // Sprint formats using the default formats for its operands and returns the resulting string.
186 // Spaces are added between operands when neither is a string.
187 func Sprint(a ...interface{}) string {
188         p := newPrinter()
189         p.doPrint(a, false, false)
190         s := p.buf.String()
191         p.free()
192         return s
193 }
194
195 // These routines end in 'ln', do not take a format string,
196 // always add spaces between operands, and add a newline
197 // after the last operand.
198
199 // Fprintln formats using the default formats for its operands and writes to w.
200 // Spaces are always added between operands and a newline is appended.
201 // It returns the number of bytes written and any write error encountered.
202 func Fprintln(w io.Writer, a ...interface{}) (n int, error os.Error) {
203         p := newPrinter()
204         p.doPrint(a, true, true)
205         n64, error := p.buf.WriteTo(w)
206         p.free()
207         return int(n64), error
208 }
209
210 // Println formats using the default formats for its operands and writes to standard output.
211 // Spaces are always added between operands and a newline is appended.
212 // It returns the number of bytes written and any write error encountered.
213 func Println(a ...interface{}) (n int, errno os.Error) {
214         n, errno = Fprintln(os.Stdout, a...)
215         return n, errno
216 }
217
218 // Sprintln formats using the default formats for its operands and returns the resulting string.
219 // Spaces are always added between operands and a newline is appended.
220 func Sprintln(a ...interface{}) string {
221         p := newPrinter()
222         p.doPrint(a, true, true)
223         s := p.buf.String()
224         p.free()
225         return s
226 }
227
228
229 // Get the i'th arg of the struct value.
230 // If the arg itself is an interface, return a value for
231 // the thing inside the interface, not the interface itself.
232 func getField(v *reflect.StructValue, i int) reflect.Value {
233         val := v.Field(i)
234         if i, ok := val.(*reflect.InterfaceValue); ok {
235                 if inter := i.Interface(); inter != nil {
236                         return reflect.NewValue(inter)
237                 }
238         }
239         return val
240 }
241
242 // Convert ASCII to integer.  n is 0 (and got is false) if no number present.
243 func parsenum(s string, start, end int) (num int, isnum bool, newi int) {
244         if start >= end {
245                 return 0, false, end
246         }
247         for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ {
248                 num = num*10 + int(s[newi]-'0')
249                 isnum = true
250         }
251         return
252 }
253
254 // Reflection values like reflect.FuncValue implement this method. We use it for %p.
255 type uintptrGetter interface {
256         Get() uintptr
257 }
258
259 func (p *pp) unknownType(v interface{}) {
260         if v == nil {
261                 p.buf.Write(nilAngleBytes)
262                 return
263         }
264         p.buf.WriteByte('?')
265         p.buf.WriteString(reflect.Typeof(v).String())
266         p.buf.WriteByte('?')
267 }
268
269 func (p *pp) badVerb(verb int, val interface{}) {
270         p.add('%')
271         p.add('!')
272         p.add(verb)
273         p.add('(')
274         if val == nil {
275                 p.buf.Write(nilAngleBytes)
276         } else {
277                 p.buf.WriteString(reflect.Typeof(val).String())
278                 p.add('=')
279                 p.printField(val, 'v', false, false, 0)
280         }
281         p.add(')')
282 }
283
284 func (p *pp) fmtBool(v bool, verb int, value interface{}) {
285         switch verb {
286         case 't', 'v':
287                 p.fmt.fmt_boolean(v)
288         default:
289                 p.badVerb(verb, value)
290         }
291 }
292
293 // fmtC formats a rune for the 'c' format.
294 func (p *pp) fmtC(c int64) {
295         rune := int(c) // Check for overflow.
296         if int64(rune) != c {
297                 rune = utf8.RuneError
298         }
299         w := utf8.EncodeRune(p.runeBuf[0:utf8.UTFMax], rune)
300         p.fmt.pad(p.runeBuf[0:w])
301 }
302
303 func (p *pp) fmtInt64(v int64, verb int, value interface{}) {
304         switch verb {
305         case 'b':
306                 p.fmt.integer(v, 2, signed, ldigits)
307         case 'c':
308                 p.fmtC(v)
309         case 'd', 'v':
310                 p.fmt.integer(v, 10, signed, ldigits)
311         case 'o':
312                 p.fmt.integer(v, 8, signed, ldigits)
313         case 'x':
314                 p.fmt.integer(v, 16, signed, ldigits)
315         case 'U':
316                 p.fmtUnicode(v)
317         case 'X':
318                 p.fmt.integer(v, 16, signed, udigits)
319         default:
320                 p.badVerb(verb, value)
321         }
322 }
323
324 // fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x by
325 // temporarily turning on the sharp flag.
326 func (p *pp) fmt0x64(v uint64) {
327         sharp := p.fmt.sharp
328         p.fmt.sharp = true // turn on 0x
329         p.fmt.integer(int64(v), 16, unsigned, ldigits)
330         p.fmt.sharp = sharp
331 }
332
333 // fmtUnicode formats a uint64 in U+1234 form by
334 // temporarily turning on the unicode flag and tweaking the precision.
335 func (p *pp) fmtUnicode(v int64) {
336         precPresent := p.fmt.precPresent
337         prec := p.fmt.prec
338         if !precPresent {
339                 // If prec is already set, leave it alone; otherwise 4 is minimum.
340                 p.fmt.prec = 4
341                 p.fmt.precPresent = true
342         }
343         p.fmt.unicode = true // turn on U+
344         p.fmt.integer(int64(v), 16, unsigned, udigits)
345         p.fmt.unicode = false
346         p.fmt.prec = prec
347         p.fmt.precPresent = precPresent
348 }
349
350 func (p *pp) fmtUint64(v uint64, verb int, goSyntax bool, value interface{}) {
351         switch verb {
352         case 'b':
353                 p.fmt.integer(int64(v), 2, unsigned, ldigits)
354         case 'c':
355                 p.fmtC(int64(v))
356         case 'd':
357                 p.fmt.integer(int64(v), 10, unsigned, ldigits)
358         case 'v':
359                 if goSyntax {
360                         p.fmt0x64(v)
361                 } else {
362                         p.fmt.integer(int64(v), 10, unsigned, ldigits)
363                 }
364         case 'o':
365                 p.fmt.integer(int64(v), 8, unsigned, ldigits)
366         case 'x':
367                 p.fmt.integer(int64(v), 16, unsigned, ldigits)
368         case 'X':
369                 p.fmt.integer(int64(v), 16, unsigned, udigits)
370         default:
371                 p.badVerb(verb, value)
372         }
373 }
374
375 func (p *pp) fmtFloat32(v float32, verb int, value interface{}) {
376         switch verb {
377         case 'b':
378                 p.fmt.fmt_fb32(v)
379         case 'e':
380                 p.fmt.fmt_e32(v)
381         case 'E':
382                 p.fmt.fmt_E32(v)
383         case 'f':
384                 p.fmt.fmt_f32(v)
385         case 'g', 'v':
386                 p.fmt.fmt_g32(v)
387         case 'G':
388                 p.fmt.fmt_G32(v)
389         default:
390                 p.badVerb(verb, value)
391         }
392 }
393
394 func (p *pp) fmtFloat64(v float64, verb int, value interface{}) {
395         switch verb {
396         case 'b':
397                 p.fmt.fmt_fb64(v)
398         case 'e':
399                 p.fmt.fmt_e64(v)
400         case 'E':
401                 p.fmt.fmt_E64(v)
402         case 'f':
403                 p.fmt.fmt_f64(v)
404         case 'g', 'v':
405                 p.fmt.fmt_g64(v)
406         case 'G':
407                 p.fmt.fmt_G64(v)
408         default:
409                 p.badVerb(verb, value)
410         }
411 }
412
413 func (p *pp) fmtComplex64(v complex64, verb int, value interface{}) {
414         switch verb {
415         case 'e', 'E', 'f', 'F', 'g', 'G':
416                 p.fmt.fmt_c64(v, verb)
417         case 'v':
418                 p.fmt.fmt_c64(v, 'g')
419         default:
420                 p.badVerb(verb, value)
421         }
422 }
423
424 func (p *pp) fmtComplex128(v complex128, verb int, value interface{}) {
425         switch verb {
426         case 'e', 'E', 'f', 'F', 'g', 'G':
427                 p.fmt.fmt_c128(v, verb)
428         case 'v':
429                 p.fmt.fmt_c128(v, 'g')
430         default:
431                 p.badVerb(verb, value)
432         }
433 }
434
435 func (p *pp) fmtString(v string, verb int, goSyntax bool, value interface{}) {
436         switch verb {
437         case 'v':
438                 if goSyntax {
439                         p.fmt.fmt_q(v)
440                 } else {
441                         p.fmt.fmt_s(v)
442                 }
443         case 's':
444                 p.fmt.fmt_s(v)
445         case 'x':
446                 p.fmt.fmt_sx(v)
447         case 'X':
448                 p.fmt.fmt_sX(v)
449         case 'q':
450                 p.fmt.fmt_q(v)
451         default:
452                 p.badVerb(verb, value)
453         }
454 }
455
456 func (p *pp) fmtBytes(v []byte, verb int, goSyntax bool, depth int, value interface{}) {
457         if verb == 'v' || verb == 'd' {
458                 if goSyntax {
459                         p.buf.Write(bytesBytes)
460                 } else {
461                         p.buf.WriteByte('[')
462                 }
463                 for i, c := range v {
464                         if i > 0 {
465                                 if goSyntax {
466                                         p.buf.Write(commaSpaceBytes)
467                                 } else {
468                                         p.buf.WriteByte(' ')
469                                 }
470                         }
471                         p.printField(c, 'v', p.fmt.plus, goSyntax, depth+1)
472                 }
473                 if goSyntax {
474                         p.buf.WriteByte('}')
475                 } else {
476                         p.buf.WriteByte(']')
477                 }
478                 return
479         }
480         s := string(v)
481         switch verb {
482         case 's':
483                 p.fmt.fmt_s(s)
484         case 'x':
485                 p.fmt.fmt_sx(s)
486         case 'X':
487                 p.fmt.fmt_sX(s)
488         case 'q':
489                 p.fmt.fmt_q(s)
490         default:
491                 p.badVerb(verb, value)
492         }
493 }
494
495 func (p *pp) fmtPointer(field interface{}, value reflect.Value, verb int, goSyntax bool) {
496         v, ok := value.(uintptrGetter)
497         if !ok { // reflect.PtrValue is a uintptrGetter, so failure means it's not a pointer at all.
498                 p.badVerb(verb, field)
499                 return
500         }
501         u := v.Get()
502         if goSyntax {
503                 p.add('(')
504                 p.buf.WriteString(reflect.Typeof(field).String())
505                 p.add(')')
506                 p.add('(')
507                 if u == 0 {
508                         p.buf.Write(nilBytes)
509                 } else {
510                         p.fmt0x64(uint64(v.Get()))
511                 }
512                 p.add(')')
513         } else {
514                 p.fmt0x64(uint64(u))
515         }
516 }
517
518 var (
519         intBits     = reflect.Typeof(0).Bits()
520         floatBits   = reflect.Typeof(0.0).Bits()
521         complexBits = reflect.Typeof(1i).Bits()
522         uintptrBits = reflect.Typeof(uintptr(0)).Bits()
523 )
524
525 func (p *pp) printField(field interface{}, verb int, plus, goSyntax bool, depth int) (wasString bool) {
526         if field == nil {
527                 if verb == 'T' || verb == 'v' {
528                         p.buf.Write(nilAngleBytes)
529                 } else {
530                         p.badVerb(verb, field)
531                 }
532                 return false
533         }
534
535         // Special processing considerations.
536         // %T (the value's type) and %p (its address) are special; we always do them first.
537         switch verb {
538         case 'T':
539                 p.printField(reflect.Typeof(field).String(), 's', false, false, 0)
540                 return false
541         case 'p':
542                 p.fmtPointer(field, reflect.NewValue(field), verb, goSyntax)
543                 return false
544         }
545         // Is it a Formatter?
546         if formatter, ok := field.(Formatter); ok {
547                 formatter.Format(p, verb)
548                 return false // this value is not a string
549
550         }
551         // Must not touch flags before Formatter looks at them.
552         if plus {
553                 p.fmt.plus = false
554         }
555         // If we're doing Go syntax and the field knows how to supply it, take care of it now.
556         if goSyntax {
557                 p.fmt.sharp = false
558                 if stringer, ok := field.(GoStringer); ok {
559                         // Print the result of GoString unadorned.
560                         p.fmtString(stringer.GoString(), 's', false, field)
561                         return false // this value is not a string
562                 }
563         } else {
564                 // Is it a Stringer?
565                 if stringer, ok := field.(Stringer); ok {
566                         p.printField(stringer.String(), verb, plus, false, depth)
567                         return false // this value is not a string
568                 }
569         }
570
571         // Some types can be done without reflection.
572         switch f := field.(type) {
573         case bool:
574                 p.fmtBool(f, verb, field)
575                 return false
576         case float32:
577                 p.fmtFloat32(f, verb, field)
578                 return false
579         case float64:
580                 p.fmtFloat64(f, verb, field)
581                 return false
582         case complex64:
583                 p.fmtComplex64(complex64(f), verb, field)
584                 return false
585         case complex128:
586                 p.fmtComplex128(f, verb, field)
587                 return false
588         case int:
589                 p.fmtInt64(int64(f), verb, field)
590                 return false
591         case int8:
592                 p.fmtInt64(int64(f), verb, field)
593                 return false
594         case int16:
595                 p.fmtInt64(int64(f), verb, field)
596                 return false
597         case int32:
598                 p.fmtInt64(int64(f), verb, field)
599                 return false
600         case int64:
601                 p.fmtInt64(f, verb, field)
602                 return false
603         case uint:
604                 p.fmtUint64(uint64(f), verb, goSyntax, field)
605                 return false
606         case uint8:
607                 p.fmtUint64(uint64(f), verb, goSyntax, field)
608                 return false
609         case uint16:
610                 p.fmtUint64(uint64(f), verb, goSyntax, field)
611                 return false
612         case uint32:
613                 p.fmtUint64(uint64(f), verb, goSyntax, field)
614                 return false
615         case uint64:
616                 p.fmtUint64(f, verb, goSyntax, field)
617                 return false
618         case uintptr:
619                 p.fmtUint64(uint64(f), verb, goSyntax, field)
620                 return false
621         case string:
622                 p.fmtString(f, verb, goSyntax, field)
623                 return verb == 's' || verb == 'v'
624         case []byte:
625                 p.fmtBytes(f, verb, goSyntax, depth, field)
626                 return verb == 's'
627         }
628
629         // Need to use reflection
630         value := reflect.NewValue(field)
631
632 BigSwitch:
633         switch f := value.(type) {
634         case *reflect.BoolValue:
635                 p.fmtBool(f.Get(), verb, field)
636         case *reflect.IntValue:
637                 p.fmtInt64(f.Get(), verb, field)
638         case *reflect.UintValue:
639                 p.fmtUint64(uint64(f.Get()), verb, goSyntax, field)
640         case *reflect.FloatValue:
641                 if f.Type().Size() == 4 {
642                         p.fmtFloat32(float32(f.Get()), verb, field)
643                 } else {
644                         p.fmtFloat64(float64(f.Get()), verb, field)
645                 }
646         case *reflect.ComplexValue:
647                 if f.Type().Size() == 8 {
648                         p.fmtComplex64(complex64(f.Get()), verb, field)
649                 } else {
650                         p.fmtComplex128(complex128(f.Get()), verb, field)
651                 }
652         case *reflect.StringValue:
653                 p.fmtString(f.Get(), verb, goSyntax, field)
654         case *reflect.MapValue:
655                 if goSyntax {
656                         p.buf.WriteString(f.Type().String())
657                         p.buf.WriteByte('{')
658                 } else {
659                         p.buf.Write(mapBytes)
660                 }
661                 keys := f.Keys()
662                 for i, key := range keys {
663                         if i > 0 {
664                                 if goSyntax {
665                                         p.buf.Write(commaSpaceBytes)
666                                 } else {
667                                         p.buf.WriteByte(' ')
668                                 }
669                         }
670                         p.printField(key.Interface(), verb, plus, goSyntax, depth+1)
671                         p.buf.WriteByte(':')
672                         p.printField(f.Elem(key).Interface(), verb, plus, goSyntax, depth+1)
673                 }
674                 if goSyntax {
675                         p.buf.WriteByte('}')
676                 } else {
677                         p.buf.WriteByte(']')
678                 }
679         case *reflect.StructValue:
680                 if goSyntax {
681                         p.buf.WriteString(reflect.Typeof(field).String())
682                 }
683                 p.add('{')
684                 v := f
685                 t := v.Type().(*reflect.StructType)
686                 for i := 0; i < v.NumField(); i++ {
687                         if i > 0 {
688                                 if goSyntax {
689                                         p.buf.Write(commaSpaceBytes)
690                                 } else {
691                                         p.buf.WriteByte(' ')
692                                 }
693                         }
694                         if plus || goSyntax {
695                                 if f := t.Field(i); f.Name != "" {
696                                         p.buf.WriteString(f.Name)
697                                         p.buf.WriteByte(':')
698                                 }
699                         }
700                         p.printField(getField(v, i).Interface(), verb, plus, goSyntax, depth+1)
701                 }
702                 p.buf.WriteByte('}')
703         case *reflect.InterfaceValue:
704                 value := f.Elem()
705                 if value == nil {
706                         if goSyntax {
707                                 p.buf.WriteString(reflect.Typeof(field).String())
708                                 p.buf.Write(nilParenBytes)
709                         } else {
710                                 p.buf.Write(nilAngleBytes)
711                         }
712                 } else {
713                         return p.printField(value.Interface(), verb, plus, goSyntax, depth+1)
714                 }
715         case reflect.ArrayOrSliceValue:
716                 // Byte slices are special.
717                 if f.Type().(reflect.ArrayOrSliceType).Elem().Kind() == reflect.Uint8 {
718                         // We know it's a slice of bytes, but we also know it does not have static type
719                         // []byte, or it would have been caught above.  Therefore we cannot convert
720                         // it directly in the (slightly) obvious way: f.Interface().([]byte); it doesn't have
721                         // that type, and we can't write an expression of the right type and do a
722                         // conversion because we don't have a static way to write the right type.
723                         // So we build a slice by hand.  This is a rare case but it would be nice
724                         // if reflection could help a little more.
725                         bytes := make([]byte, f.Len())
726                         for i := range bytes {
727                                 bytes[i] = byte(f.Elem(i).(*reflect.UintValue).Get())
728                         }
729                         p.fmtBytes(bytes, verb, goSyntax, depth, field)
730                         return verb == 's'
731                 }
732                 if goSyntax {
733                         p.buf.WriteString(reflect.Typeof(field).String())
734                         p.buf.WriteByte('{')
735                 } else {
736                         p.buf.WriteByte('[')
737                 }
738                 for i := 0; i < f.Len(); i++ {
739                         if i > 0 {
740                                 if goSyntax {
741                                         p.buf.Write(commaSpaceBytes)
742                                 } else {
743                                         p.buf.WriteByte(' ')
744                                 }
745                         }
746                         p.printField(f.Elem(i).Interface(), verb, plus, goSyntax, depth+1)
747                 }
748                 if goSyntax {
749                         p.buf.WriteByte('}')
750                 } else {
751                         p.buf.WriteByte(']')
752                 }
753         case *reflect.PtrValue:
754                 v := f.Get()
755                 // pointer to array or slice or struct?  ok at top level
756                 // but not embedded (avoid loops)
757                 if v != 0 && depth == 0 {
758                         switch a := f.Elem().(type) {
759                         case reflect.ArrayOrSliceValue:
760                                 p.buf.WriteByte('&')
761                                 p.printField(a.Interface(), verb, plus, goSyntax, depth+1)
762                                 break BigSwitch
763                         case *reflect.StructValue:
764                                 p.buf.WriteByte('&')
765                                 p.printField(a.Interface(), verb, plus, goSyntax, depth+1)
766                                 break BigSwitch
767                         }
768                 }
769                 if goSyntax {
770                         p.buf.WriteByte('(')
771                         p.buf.WriteString(reflect.Typeof(field).String())
772                         p.buf.WriteByte(')')
773                         p.buf.WriteByte('(')
774                         if v == 0 {
775                                 p.buf.Write(nilBytes)
776                         } else {
777                                 p.fmt0x64(uint64(v))
778                         }
779                         p.buf.WriteByte(')')
780                         break
781                 }
782                 if v == 0 {
783                         p.buf.Write(nilAngleBytes)
784                         break
785                 }
786                 p.fmt0x64(uint64(v))
787         case uintptrGetter:
788                 p.fmtPointer(field, value, verb, goSyntax)
789         default:
790                 p.unknownType(f)
791         }
792         return false
793 }
794
795 // intFromArg gets the fieldnumth element of a. On return, isInt reports whether the argument has type int.
796 func intFromArg(a []interface{}, end, i, fieldnum int) (num int, isInt bool, newi, newfieldnum int) {
797         newi, newfieldnum = end, fieldnum
798         if i < end && fieldnum < len(a) {
799                 num, isInt = a[fieldnum].(int)
800                 newi, newfieldnum = i+1, fieldnum+1
801         }
802         return
803 }
804
805 func (p *pp) doPrintf(format string, a []interface{}) {
806         end := len(format)
807         fieldnum := 0 // we process one field per non-trivial format
808         for i := 0; i < end; {
809                 lasti := i
810                 for i < end && format[i] != '%' {
811                         i++
812                 }
813                 if i > lasti {
814                         p.buf.WriteString(format[lasti:i])
815                 }
816                 if i >= end {
817                         // done processing format string
818                         break
819                 }
820
821                 // Process one verb
822                 i++
823                 // flags and widths
824                 p.fmt.clearflags()
825         F:
826                 for ; i < end; i++ {
827                         switch format[i] {
828                         case '#':
829                                 p.fmt.sharp = true
830                         case '0':
831                                 p.fmt.zero = true
832                         case '+':
833                                 p.fmt.plus = true
834                         case '-':
835                                 p.fmt.minus = true
836                         case ' ':
837                                 p.fmt.space = true
838                         default:
839                                 break F
840                         }
841                 }
842                 // do we have width?
843                 if i < end && format[i] == '*' {
844                         p.fmt.wid, p.fmt.widPresent, i, fieldnum = intFromArg(a, end, i, fieldnum)
845                         if !p.fmt.widPresent {
846                                 p.buf.Write(widthBytes)
847                         }
848                 } else {
849                         p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end)
850                 }
851                 // do we have precision?
852                 if i < end && format[i] == '.' {
853                         if format[i+1] == '*' {
854                                 p.fmt.prec, p.fmt.precPresent, i, fieldnum = intFromArg(a, end, i+1, fieldnum)
855                                 if !p.fmt.precPresent {
856                                         p.buf.Write(precBytes)
857                                 }
858                         } else {
859                                 p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i+1, end)
860                         }
861                 }
862                 if i >= end {
863                         p.buf.Write(noVerbBytes)
864                         continue
865                 }
866                 c, w := utf8.DecodeRuneInString(format[i:])
867                 i += w
868                 // percent is special - absorbs no operand
869                 if c == '%' {
870                         p.buf.WriteByte('%') // We ignore width and prec.
871                         continue
872                 }
873                 if fieldnum >= len(a) { // out of operands
874                         p.buf.WriteByte('%')
875                         p.add(c)
876                         p.buf.Write(missingBytes)
877                         continue
878                 }
879                 field := a[fieldnum]
880                 fieldnum++
881
882                 goSyntax := c == 'v' && p.fmt.sharp
883                 plus := c == 'v' && p.fmt.plus
884                 p.printField(field, c, plus, goSyntax, 0)
885         }
886
887         if fieldnum < len(a) {
888                 p.buf.Write(extraBytes)
889                 for ; fieldnum < len(a); fieldnum++ {
890                         field := a[fieldnum]
891                         if field != nil {
892                                 p.buf.WriteString(reflect.Typeof(field).String())
893                                 p.buf.WriteByte('=')
894                         }
895                         p.printField(field, 'v', false, false, 0)
896                         if fieldnum+1 < len(a) {
897                                 p.buf.Write(commaSpaceBytes)
898                         }
899                 }
900                 p.buf.WriteByte(')')
901         }
902 }
903
904 func (p *pp) doPrint(a []interface{}, addspace, addnewline bool) {
905         prevString := false
906         for fieldnum := 0; fieldnum < len(a); fieldnum++ {
907                 p.fmt.clearflags()
908                 // always add spaces if we're doing println
909                 field := a[fieldnum]
910                 if fieldnum > 0 {
911                         isString := field != nil && reflect.Typeof(field).Kind() == reflect.String
912                         if addspace || !isString && !prevString {
913                                 p.buf.WriteByte(' ')
914                         }
915                 }
916                 prevString = p.printField(field, 'v', false, false, 0)
917         }
918         if addnewline {
919                 p.buf.WriteByte('\n')
920         }
921 }