OSDN Git Service

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