OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / text / message / print.go
1 // Copyright 2017 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 message
6
7 import (
8         "bytes"
9         "fmt" // TODO: consider copying interfaces from package fmt to avoid dependency.
10         "math"
11         "reflect"
12         "unicode/utf8"
13
14         "golang.org/x/text/internal/number"
15         "golang.org/x/text/language"
16         "golang.org/x/text/message/catalog"
17 )
18
19 // Strings for use with buffer.WriteString.
20 // This is less overhead than using buffer.Write with byte arrays.
21 const (
22         commaSpaceString  = ", "
23         nilAngleString    = "<nil>"
24         nilParenString    = "(nil)"
25         nilString         = "nil"
26         mapString         = "map["
27         percentBangString = "%!"
28         missingString     = "(MISSING)"
29         badIndexString    = "(BADINDEX)"
30         panicString       = "(PANIC="
31         extraString       = "%!(EXTRA "
32         badWidthString    = "%!(BADWIDTH)"
33         badPrecString     = "%!(BADPREC)"
34         noVerbString      = "%!(NOVERB)"
35
36         invReflectString = "<invalid reflect.Value>"
37 )
38
39 // printer is used to store a printer's state.
40 // It implements "golang.org/x/text/internal/format".State.
41 type printer struct {
42         // the context for looking up message translations
43         catContext *catalog.Context
44         // the language
45         tag language.Tag
46
47         // buffer for accumulating output.
48         bytes.Buffer
49
50         // retain arguments across calls.
51         args []interface{}
52         // retain current argument number across calls
53         argNum int
54         // arg holds the current item, as an interface{}.
55         arg interface{}
56         // value is used instead of arg for reflect values.
57         value reflect.Value
58
59         // fmt is used to format basic items such as integers or strings.
60         fmt formatInfo
61
62         // reordered records whether the format string used argument reordering.
63         reordered bool
64         // goodArgNum records whether the most recent reordering directive was valid.
65         goodArgNum bool
66         // panicking is set by catchPanic to avoid infinite panic, recover, panic, ... recursion.
67         panicking bool
68         // erroring is set when printing an error string to guard against calling handleMethods.
69         erroring bool
70
71         toDecimal    number.Formatter
72         toScientific number.Formatter
73 }
74
75 func (p *printer) reset() {
76         p.Buffer.Reset()
77         p.argNum = 0
78         p.reordered = false
79         p.panicking = false
80         p.erroring = false
81         p.fmt.init(&p.Buffer)
82 }
83
84 // Language implements "golang.org/x/text/internal/format".State.
85 func (p *printer) Language() language.Tag { return p.tag }
86
87 func (p *printer) Width() (wid int, ok bool) { return p.fmt.wid, p.fmt.widPresent }
88
89 func (p *printer) Precision() (prec int, ok bool) { return p.fmt.prec, p.fmt.precPresent }
90
91 func (p *printer) Flag(b int) bool {
92         switch b {
93         case '-':
94                 return p.fmt.minus
95         case '+':
96                 return p.fmt.plus || p.fmt.plusV
97         case '#':
98                 return p.fmt.sharp || p.fmt.sharpV
99         case ' ':
100                 return p.fmt.space
101         case '0':
102                 return p.fmt.zero
103         }
104         return false
105 }
106
107 // getField gets the i'th field of the struct value.
108 // If the field is itself is an interface, return a value for
109 // the thing inside the interface, not the interface itself.
110 func getField(v reflect.Value, i int) reflect.Value {
111         val := v.Field(i)
112         if val.Kind() == reflect.Interface && !val.IsNil() {
113                 val = val.Elem()
114         }
115         return val
116 }
117
118 // tooLarge reports whether the magnitude of the integer is
119 // too large to be used as a formatting width or precision.
120 func tooLarge(x int) bool {
121         const max int = 1e6
122         return x > max || x < -max
123 }
124
125 // parsenum converts ASCII to integer.  num is 0 (and isnum is false) if no number present.
126 func parsenum(s string, start, end int) (num int, isnum bool, newi int) {
127         if start >= end {
128                 return 0, false, end
129         }
130         for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ {
131                 if tooLarge(num) {
132                         return 0, false, end // Overflow; crazy long number most likely.
133                 }
134                 num = num*10 + int(s[newi]-'0')
135                 isnum = true
136         }
137         return
138 }
139
140 func (p *printer) unknownType(v reflect.Value) {
141         if !v.IsValid() {
142                 p.WriteString(nilAngleString)
143                 return
144         }
145         p.WriteByte('?')
146         p.WriteString(v.Type().String())
147         p.WriteByte('?')
148 }
149
150 func (p *printer) badVerb(verb rune) {
151         p.erroring = true
152         p.WriteString(percentBangString)
153         p.WriteRune(verb)
154         p.WriteByte('(')
155         switch {
156         case p.arg != nil:
157                 p.WriteString(reflect.TypeOf(p.arg).String())
158                 p.WriteByte('=')
159                 p.printArg(p.arg, 'v')
160         case p.value.IsValid():
161                 p.WriteString(p.value.Type().String())
162                 p.WriteByte('=')
163                 p.printValue(p.value, 'v', 0)
164         default:
165                 p.WriteString(nilAngleString)
166         }
167         p.WriteByte(')')
168         p.erroring = false
169 }
170
171 func (p *printer) fmtBool(v bool, verb rune) {
172         switch verb {
173         case 't', 'v':
174                 p.fmt.fmt_boolean(v)
175         default:
176                 p.badVerb(verb)
177         }
178 }
179
180 // fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x or
181 // not, as requested, by temporarily setting the sharp flag.
182 func (p *printer) fmt0x64(v uint64, leading0x bool) {
183         sharp := p.fmt.sharp
184         p.fmt.sharp = leading0x
185         p.fmt.fmt_integer(v, 16, unsigned, ldigits)
186         p.fmt.sharp = sharp
187 }
188
189 // fmtInteger formats a signed or unsigned integer.
190 func (p *printer) fmtInteger(v uint64, isSigned bool, verb rune) {
191         switch verb {
192         case 'v':
193                 if p.fmt.sharpV && !isSigned {
194                         p.fmt0x64(v, true)
195                         return
196                 }
197                 fallthrough
198         case 'd':
199                 if p.fmt.sharp || p.fmt.sharpV {
200                         p.fmt.fmt_integer(v, 10, isSigned, ldigits)
201                 } else {
202                         p.fmtDecimalInt(v, isSigned)
203                 }
204         case 'b':
205                 p.fmt.fmt_integer(v, 2, isSigned, ldigits)
206         case 'o':
207                 p.fmt.fmt_integer(v, 8, isSigned, ldigits)
208         case 'x':
209                 p.fmt.fmt_integer(v, 16, isSigned, ldigits)
210         case 'X':
211                 p.fmt.fmt_integer(v, 16, isSigned, udigits)
212         case 'c':
213                 p.fmt.fmt_c(v)
214         case 'q':
215                 if v <= utf8.MaxRune {
216                         p.fmt.fmt_qc(v)
217                 } else {
218                         p.badVerb(verb)
219                 }
220         case 'U':
221                 p.fmt.fmt_unicode(v)
222         default:
223                 p.badVerb(verb)
224         }
225 }
226
227 // fmtFloat formats a float. The default precision for each verb
228 // is specified as last argument in the call to fmt_float.
229 func (p *printer) fmtFloat(v float64, size int, verb rune) {
230         switch verb {
231         case 'b':
232                 p.fmt.fmt_float(v, size, verb, -1)
233         case 'v':
234                 verb = 'g'
235                 fallthrough
236         case 'g', 'G':
237                 if p.fmt.sharp || p.fmt.sharpV {
238                         p.fmt.fmt_float(v, size, verb, -1)
239                 } else {
240                         p.fmtVariableFloat(v, size)
241                 }
242         case 'e', 'E':
243                 if p.fmt.sharp || p.fmt.sharpV {
244                         p.fmt.fmt_float(v, size, verb, 6)
245                 } else {
246                         p.fmtScientific(v, size, 6)
247                 }
248         case 'f', 'F':
249                 if p.fmt.sharp || p.fmt.sharpV {
250                         p.fmt.fmt_float(v, size, verb, 6)
251                 } else {
252                         p.fmtDecimalFloat(v, size, 6)
253                 }
254         default:
255                 p.badVerb(verb)
256         }
257 }
258
259 func (p *printer) setFlags(f *number.Formatter) {
260         f.Flags &^= number.ElideSign
261         if p.fmt.plus || p.fmt.space {
262                 f.Flags |= number.AlwaysSign
263                 if !p.fmt.plus {
264                         f.Flags |= number.ElideSign
265                 }
266         } else {
267                 f.Flags &^= number.AlwaysSign
268         }
269 }
270
271 func (p *printer) updatePadding(f *number.Formatter) {
272         f.Flags &^= number.PadMask
273         if p.fmt.minus {
274                 f.Flags |= number.PadAfterSuffix
275         } else {
276                 f.Flags |= number.PadBeforePrefix
277         }
278         f.PadRune = ' '
279         f.FormatWidth = uint16(p.fmt.wid)
280 }
281
282 func (p *printer) initDecimal(minFrac, maxFrac int) {
283         f := &p.toDecimal
284         f.MinIntegerDigits = 1
285         f.MaxIntegerDigits = 0
286         f.MinFractionDigits = uint8(minFrac)
287         f.MaxFractionDigits = int16(maxFrac)
288         p.setFlags(f)
289         f.PadRune = 0
290         if p.fmt.widPresent {
291                 if p.fmt.zero {
292                         wid := p.fmt.wid
293                         // Use significant integers for this.
294                         // TODO: this is not the same as width, but so be it.
295                         if f.MinFractionDigits > 0 {
296                                 wid -= 1 + int(f.MinFractionDigits)
297                         }
298                         if p.fmt.plus || p.fmt.space {
299                                 wid--
300                         }
301                         if wid > 0 && wid > int(f.MinIntegerDigits) {
302                                 f.MinIntegerDigits = uint8(wid)
303                         }
304                 }
305                 p.updatePadding(f)
306         }
307 }
308
309 func (p *printer) initScientific(minFrac, maxFrac int) {
310         f := &p.toScientific
311         if maxFrac < 0 {
312                 f.SetPrecision(maxFrac)
313         } else {
314                 f.SetPrecision(maxFrac + 1)
315                 f.MinFractionDigits = uint8(minFrac)
316                 f.MaxFractionDigits = int16(maxFrac)
317         }
318         f.MinExponentDigits = 2
319         p.setFlags(f)
320         f.PadRune = 0
321         if p.fmt.widPresent {
322                 f.Flags &^= number.PadMask
323                 if p.fmt.zero {
324                         f.PadRune = f.Digit(0)
325                         f.Flags |= number.PadAfterPrefix
326                 } else {
327                         f.PadRune = ' '
328                         f.Flags |= number.PadBeforePrefix
329                 }
330                 p.updatePadding(f)
331         }
332 }
333
334 func (p *printer) fmtDecimalInt(v uint64, isSigned bool) {
335         var d number.Decimal
336
337         f := &p.toDecimal
338         if p.fmt.precPresent {
339                 p.setFlags(f)
340                 f.MinIntegerDigits = uint8(p.fmt.prec)
341                 f.MaxIntegerDigits = 0
342                 f.MinFractionDigits = 0
343                 f.MaxFractionDigits = 0
344                 if p.fmt.widPresent {
345                         p.updatePadding(f)
346                 }
347         } else {
348                 p.initDecimal(0, 0)
349         }
350         d.ConvertInt(p.toDecimal.RoundingContext, isSigned, v)
351
352         out := p.toDecimal.Format([]byte(nil), &d)
353         p.Buffer.Write(out)
354 }
355
356 func (p *printer) fmtDecimalFloat(v float64, size, prec int) {
357         var d number.Decimal
358         if p.fmt.precPresent {
359                 prec = p.fmt.prec
360         }
361         p.initDecimal(prec, prec)
362         d.ConvertFloat(p.toDecimal.RoundingContext, v, size)
363
364         out := p.toDecimal.Format([]byte(nil), &d)
365         p.Buffer.Write(out)
366 }
367
368 func (p *printer) fmtVariableFloat(v float64, size int) {
369         prec := -1
370         if p.fmt.precPresent {
371                 prec = p.fmt.prec
372         }
373         var d number.Decimal
374         p.initScientific(0, prec)
375         d.ConvertFloat(p.toScientific.RoundingContext, v, size)
376
377         // Copy logic of 'g' formatting from strconv. It is simplified a bit as
378         // we don't have to mind having prec > len(d.Digits).
379         shortest := prec < 0
380         ePrec := prec
381         if shortest {
382                 prec = len(d.Digits)
383                 ePrec = 6
384         } else if prec == 0 {
385                 prec = 1
386                 ePrec = 1
387         }
388         exp := int(d.Exp) - 1
389         if exp < -4 || exp >= ePrec {
390                 p.initScientific(0, prec)
391
392                 out := p.toScientific.Format([]byte(nil), &d)
393                 p.Buffer.Write(out)
394         } else {
395                 if prec > int(d.Exp) {
396                         prec = len(d.Digits)
397                 }
398                 if prec -= int(d.Exp); prec < 0 {
399                         prec = 0
400                 }
401                 p.initDecimal(0, prec)
402
403                 out := p.toDecimal.Format([]byte(nil), &d)
404                 p.Buffer.Write(out)
405         }
406 }
407
408 func (p *printer) fmtScientific(v float64, size, prec int) {
409         var d number.Decimal
410         if p.fmt.precPresent {
411                 prec = p.fmt.prec
412         }
413         p.initScientific(prec, prec)
414         rc := p.toScientific.RoundingContext
415         d.ConvertFloat(rc, v, size)
416
417         out := p.toScientific.Format([]byte(nil), &d)
418         p.Buffer.Write(out)
419
420 }
421
422 // fmtComplex formats a complex number v with
423 // r = real(v) and j = imag(v) as (r+ji) using
424 // fmtFloat for r and j formatting.
425 func (p *printer) fmtComplex(v complex128, size int, verb rune) {
426         // Make sure any unsupported verbs are found before the
427         // calls to fmtFloat to not generate an incorrect error string.
428         switch verb {
429         case 'v', 'b', 'g', 'G', 'f', 'F', 'e', 'E':
430                 p.WriteByte('(')
431                 p.fmtFloat(real(v), size/2, verb)
432                 // Imaginary part always has a sign.
433                 if math.IsNaN(imag(v)) {
434                         // By CLDR's rules, NaNs do not use patterns or signs. As this code
435                         // relies on AlwaysSign working for imaginary parts, we need to
436                         // manually handle NaNs.
437                         f := &p.toScientific
438                         p.setFlags(f)
439                         p.updatePadding(f)
440                         p.setFlags(f)
441                         nan := f.Symbol(number.SymNan)
442                         extra := 0
443                         if w, ok := p.Width(); ok {
444                                 extra = w - utf8.RuneCountInString(nan) - 1
445                         }
446                         if f.Flags&number.PadAfterNumber == 0 {
447                                 for ; extra > 0; extra-- {
448                                         p.WriteRune(f.PadRune)
449                                 }
450                         }
451                         p.WriteString(f.Symbol(number.SymPlusSign))
452                         p.WriteString(nan)
453                         for ; extra > 0; extra-- {
454                                 p.WriteRune(f.PadRune)
455                         }
456                         p.WriteString("i)")
457                         return
458                 }
459                 oldPlus := p.fmt.plus
460                 p.fmt.plus = true
461                 p.fmtFloat(imag(v), size/2, verb)
462                 p.WriteString("i)") // TODO: use symbol?
463                 p.fmt.plus = oldPlus
464         default:
465                 p.badVerb(verb)
466         }
467 }
468
469 func (p *printer) fmtString(v string, verb rune) {
470         switch verb {
471         case 'v':
472                 if p.fmt.sharpV {
473                         p.fmt.fmt_q(v)
474                 } else {
475                         p.fmt.fmt_s(v)
476                 }
477         case 's':
478                 p.fmt.fmt_s(v)
479         case 'x':
480                 p.fmt.fmt_sx(v, ldigits)
481         case 'X':
482                 p.fmt.fmt_sx(v, udigits)
483         case 'q':
484                 p.fmt.fmt_q(v)
485         default:
486                 p.badVerb(verb)
487         }
488 }
489
490 func (p *printer) fmtBytes(v []byte, verb rune, typeString string) {
491         switch verb {
492         case 'v', 'd':
493                 if p.fmt.sharpV {
494                         p.WriteString(typeString)
495                         if v == nil {
496                                 p.WriteString(nilParenString)
497                                 return
498                         }
499                         p.WriteByte('{')
500                         for i, c := range v {
501                                 if i > 0 {
502                                         p.WriteString(commaSpaceString)
503                                 }
504                                 p.fmt0x64(uint64(c), true)
505                         }
506                         p.WriteByte('}')
507                 } else {
508                         p.WriteByte('[')
509                         for i, c := range v {
510                                 if i > 0 {
511                                         p.WriteByte(' ')
512                                 }
513                                 p.fmt.fmt_integer(uint64(c), 10, unsigned, ldigits)
514                         }
515                         p.WriteByte(']')
516                 }
517         case 's':
518                 p.fmt.fmt_s(string(v))
519         case 'x':
520                 p.fmt.fmt_bx(v, ldigits)
521         case 'X':
522                 p.fmt.fmt_bx(v, udigits)
523         case 'q':
524                 p.fmt.fmt_q(string(v))
525         default:
526                 p.printValue(reflect.ValueOf(v), verb, 0)
527         }
528 }
529
530 func (p *printer) fmtPointer(value reflect.Value, verb rune) {
531         var u uintptr
532         switch value.Kind() {
533         case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
534                 u = value.Pointer()
535         default:
536                 p.badVerb(verb)
537                 return
538         }
539
540         switch verb {
541         case 'v':
542                 if p.fmt.sharpV {
543                         p.WriteByte('(')
544                         p.WriteString(value.Type().String())
545                         p.WriteString(")(")
546                         if u == 0 {
547                                 p.WriteString(nilString)
548                         } else {
549                                 p.fmt0x64(uint64(u), true)
550                         }
551                         p.WriteByte(')')
552                 } else {
553                         if u == 0 {
554                                 p.fmt.padString(nilAngleString)
555                         } else {
556                                 p.fmt0x64(uint64(u), !p.fmt.sharp)
557                         }
558                 }
559         case 'p':
560                 p.fmt0x64(uint64(u), !p.fmt.sharp)
561         case 'b', 'o', 'd', 'x', 'X':
562                 if verb == 'd' {
563                         p.fmt.sharp = true // Print as standard go. TODO: does this make sense?
564                 }
565                 p.fmtInteger(uint64(u), unsigned, verb)
566         default:
567                 p.badVerb(verb)
568         }
569 }
570
571 func (p *printer) catchPanic(arg interface{}, verb rune) {
572         if err := recover(); err != nil {
573                 // If it's a nil pointer, just say "<nil>". The likeliest causes are a
574                 // Stringer that fails to guard against nil or a nil pointer for a
575                 // value receiver, and in either case, "<nil>" is a nice result.
576                 if v := reflect.ValueOf(arg); v.Kind() == reflect.Ptr && v.IsNil() {
577                         p.WriteString(nilAngleString)
578                         return
579                 }
580                 // Otherwise print a concise panic message. Most of the time the panic
581                 // value will print itself nicely.
582                 if p.panicking {
583                         // Nested panics; the recursion in printArg cannot succeed.
584                         panic(err)
585                 }
586
587                 oldFlags := p.fmt.fmtFlags
588                 // For this output we want default behavior.
589                 p.fmt.clearflags()
590
591                 p.WriteString(percentBangString)
592                 p.WriteRune(verb)
593                 p.WriteString(panicString)
594                 p.panicking = true
595                 p.printArg(err, 'v')
596                 p.panicking = false
597                 p.WriteByte(')')
598
599                 p.fmt.fmtFlags = oldFlags
600         }
601 }
602
603 func (p *printer) handleMethods(verb rune) (handled bool) {
604         if p.erroring {
605                 return
606         }
607         // Is it a Formatter?
608         if formatter, ok := p.arg.(fmt.Formatter); ok {
609                 handled = true
610                 defer p.catchPanic(p.arg, verb)
611                 formatter.Format(p, verb)
612                 return
613         }
614
615         // If we're doing Go syntax and the argument knows how to supply it, take care of it now.
616         if p.fmt.sharpV {
617                 if stringer, ok := p.arg.(fmt.GoStringer); ok {
618                         handled = true
619                         defer p.catchPanic(p.arg, verb)
620                         // Print the result of GoString unadorned.
621                         p.fmt.fmt_s(stringer.GoString())
622                         return
623                 }
624         } else {
625                 // If a string is acceptable according to the format, see if
626                 // the value satisfies one of the string-valued interfaces.
627                 // Println etc. set verb to %v, which is "stringable".
628                 switch verb {
629                 case 'v', 's', 'x', 'X', 'q':
630                         // Is it an error or Stringer?
631                         // The duplication in the bodies is necessary:
632                         // setting handled and deferring catchPanic
633                         // must happen before calling the method.
634                         switch v := p.arg.(type) {
635                         case error:
636                                 handled = true
637                                 defer p.catchPanic(p.arg, verb)
638                                 p.fmtString(v.Error(), verb)
639                                 return
640
641                         case fmt.Stringer:
642                                 handled = true
643                                 defer p.catchPanic(p.arg, verb)
644                                 p.fmtString(v.String(), verb)
645                                 return
646                         }
647                 }
648         }
649         return false
650 }
651
652 func (p *printer) printArg(arg interface{}, verb rune) {
653         p.arg = arg
654         p.value = reflect.Value{}
655
656         if arg == nil {
657                 switch verb {
658                 case 'T', 'v':
659                         p.fmt.padString(nilAngleString)
660                 default:
661                         p.badVerb(verb)
662                 }
663                 return
664         }
665
666         // Special processing considerations.
667         // %T (the value's type) and %p (its address) are special; we always do them first.
668         switch verb {
669         case 'T':
670                 p.fmt.fmt_s(reflect.TypeOf(arg).String())
671                 return
672         case 'p':
673                 p.fmtPointer(reflect.ValueOf(arg), 'p')
674                 return
675         }
676
677         // Some types can be done without reflection.
678         switch f := arg.(type) {
679         case bool:
680                 p.fmtBool(f, verb)
681         case float32:
682                 p.fmtFloat(float64(f), 32, verb)
683         case float64:
684                 p.fmtFloat(f, 64, verb)
685         case complex64:
686                 p.fmtComplex(complex128(f), 64, verb)
687         case complex128:
688                 p.fmtComplex(f, 128, verb)
689         case int:
690                 p.fmtInteger(uint64(f), signed, verb)
691         case int8:
692                 p.fmtInteger(uint64(f), signed, verb)
693         case int16:
694                 p.fmtInteger(uint64(f), signed, verb)
695         case int32:
696                 p.fmtInteger(uint64(f), signed, verb)
697         case int64:
698                 p.fmtInteger(uint64(f), signed, verb)
699         case uint:
700                 p.fmtInteger(uint64(f), unsigned, verb)
701         case uint8:
702                 p.fmtInteger(uint64(f), unsigned, verb)
703         case uint16:
704                 p.fmtInteger(uint64(f), unsigned, verb)
705         case uint32:
706                 p.fmtInteger(uint64(f), unsigned, verb)
707         case uint64:
708                 p.fmtInteger(f, unsigned, verb)
709         case uintptr:
710                 p.fmtInteger(uint64(f), unsigned, verb)
711         case string:
712                 p.fmtString(f, verb)
713         case []byte:
714                 p.fmtBytes(f, verb, "[]byte")
715         case reflect.Value:
716                 // Handle extractable values with special methods
717                 // since printValue does not handle them at depth 0.
718                 if f.IsValid() && f.CanInterface() {
719                         p.arg = f.Interface()
720                         if p.handleMethods(verb) {
721                                 return
722                         }
723                 }
724                 p.printValue(f, verb, 0)
725         default:
726                 // If the type is not simple, it might have methods.
727                 if !p.handleMethods(verb) {
728                         // Need to use reflection, since the type had no
729                         // interface methods that could be used for formatting.
730                         p.printValue(reflect.ValueOf(f), verb, 0)
731                 }
732         }
733 }
734
735 // printValue is similar to printArg but starts with a reflect value, not an interface{} value.
736 // It does not handle 'p' and 'T' verbs because these should have been already handled by printArg.
737 func (p *printer) printValue(value reflect.Value, verb rune, depth int) {
738         // Handle values with special methods if not already handled by printArg (depth == 0).
739         if depth > 0 && value.IsValid() && value.CanInterface() {
740                 p.arg = value.Interface()
741                 if p.handleMethods(verb) {
742                         return
743                 }
744         }
745         p.arg = nil
746         p.value = value
747
748         switch f := value; value.Kind() {
749         case reflect.Invalid:
750                 if depth == 0 {
751                         p.WriteString(invReflectString)
752                 } else {
753                         switch verb {
754                         case 'v':
755                                 p.WriteString(nilAngleString)
756                         default:
757                                 p.badVerb(verb)
758                         }
759                 }
760         case reflect.Bool:
761                 p.fmtBool(f.Bool(), verb)
762         case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
763                 p.fmtInteger(uint64(f.Int()), signed, verb)
764         case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
765                 p.fmtInteger(f.Uint(), unsigned, verb)
766         case reflect.Float32:
767                 p.fmtFloat(f.Float(), 32, verb)
768         case reflect.Float64:
769                 p.fmtFloat(f.Float(), 64, verb)
770         case reflect.Complex64:
771                 p.fmtComplex(f.Complex(), 64, verb)
772         case reflect.Complex128:
773                 p.fmtComplex(f.Complex(), 128, verb)
774         case reflect.String:
775                 p.fmtString(f.String(), verb)
776         case reflect.Map:
777                 if p.fmt.sharpV {
778                         p.WriteString(f.Type().String())
779                         if f.IsNil() {
780                                 p.WriteString(nilParenString)
781                                 return
782                         }
783                         p.WriteByte('{')
784                 } else {
785                         p.WriteString(mapString)
786                 }
787                 keys := f.MapKeys()
788                 for i, key := range keys {
789                         if i > 0 {
790                                 if p.fmt.sharpV {
791                                         p.WriteString(commaSpaceString)
792                                 } else {
793                                         p.WriteByte(' ')
794                                 }
795                         }
796                         p.printValue(key, verb, depth+1)
797                         p.WriteByte(':')
798                         p.printValue(f.MapIndex(key), verb, depth+1)
799                 }
800                 if p.fmt.sharpV {
801                         p.WriteByte('}')
802                 } else {
803                         p.WriteByte(']')
804                 }
805         case reflect.Struct:
806                 if p.fmt.sharpV {
807                         p.WriteString(f.Type().String())
808                 }
809                 p.WriteByte('{')
810                 for i := 0; i < f.NumField(); i++ {
811                         if i > 0 {
812                                 if p.fmt.sharpV {
813                                         p.WriteString(commaSpaceString)
814                                 } else {
815                                         p.WriteByte(' ')
816                                 }
817                         }
818                         if p.fmt.plusV || p.fmt.sharpV {
819                                 if name := f.Type().Field(i).Name; name != "" {
820                                         p.WriteString(name)
821                                         p.WriteByte(':')
822                                 }
823                         }
824                         p.printValue(getField(f, i), verb, depth+1)
825                 }
826                 p.WriteByte('}')
827         case reflect.Interface:
828                 value := f.Elem()
829                 if !value.IsValid() {
830                         if p.fmt.sharpV {
831                                 p.WriteString(f.Type().String())
832                                 p.WriteString(nilParenString)
833                         } else {
834                                 p.WriteString(nilAngleString)
835                         }
836                 } else {
837                         p.printValue(value, verb, depth+1)
838                 }
839         case reflect.Array, reflect.Slice:
840                 switch verb {
841                 case 's', 'q', 'x', 'X':
842                         // Handle byte and uint8 slices and arrays special for the above verbs.
843                         t := f.Type()
844                         if t.Elem().Kind() == reflect.Uint8 {
845                                 var bytes []byte
846                                 if f.Kind() == reflect.Slice {
847                                         bytes = f.Bytes()
848                                 } else if f.CanAddr() {
849                                         bytes = f.Slice(0, f.Len()).Bytes()
850                                 } else {
851                                         // We have an array, but we cannot Slice() a non-addressable array,
852                                         // so we build a slice by hand. This is a rare case but it would be nice
853                                         // if reflection could help a little more.
854                                         bytes = make([]byte, f.Len())
855                                         for i := range bytes {
856                                                 bytes[i] = byte(f.Index(i).Uint())
857                                         }
858                                 }
859                                 p.fmtBytes(bytes, verb, t.String())
860                                 return
861                         }
862                 }
863                 if p.fmt.sharpV {
864                         p.WriteString(f.Type().String())
865                         if f.Kind() == reflect.Slice && f.IsNil() {
866                                 p.WriteString(nilParenString)
867                                 return
868                         }
869                         p.WriteByte('{')
870                         for i := 0; i < f.Len(); i++ {
871                                 if i > 0 {
872                                         p.WriteString(commaSpaceString)
873                                 }
874                                 p.printValue(f.Index(i), verb, depth+1)
875                         }
876                         p.WriteByte('}')
877                 } else {
878                         p.WriteByte('[')
879                         for i := 0; i < f.Len(); i++ {
880                                 if i > 0 {
881                                         p.WriteByte(' ')
882                                 }
883                                 p.printValue(f.Index(i), verb, depth+1)
884                         }
885                         p.WriteByte(']')
886                 }
887         case reflect.Ptr:
888                 // pointer to array or slice or struct?  ok at top level
889                 // but not embedded (avoid loops)
890                 if depth == 0 && f.Pointer() != 0 {
891                         switch a := f.Elem(); a.Kind() {
892                         case reflect.Array, reflect.Slice, reflect.Struct, reflect.Map:
893                                 p.WriteByte('&')
894                                 p.printValue(a, verb, depth+1)
895                                 return
896                         }
897                 }
898                 fallthrough
899         case reflect.Chan, reflect.Func, reflect.UnsafePointer:
900                 p.fmtPointer(f, verb)
901         default:
902                 p.unknownType(f)
903         }
904 }
905
906 // intFromArg gets the argNumth element of a. On return, isInt reports whether the argument has integer type.
907 func (p *printer) intFromArg() (num int, isInt bool) {
908         if p.argNum < len(p.args) {
909                 arg := p.args[p.argNum]
910                 num, isInt = arg.(int) // Almost always OK.
911                 if !isInt {
912                         // Work harder.
913                         switch v := reflect.ValueOf(arg); v.Kind() {
914                         case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
915                                 n := v.Int()
916                                 if int64(int(n)) == n {
917                                         num = int(n)
918                                         isInt = true
919                                 }
920                         case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
921                                 n := v.Uint()
922                                 if int64(n) >= 0 && uint64(int(n)) == n {
923                                         num = int(n)
924                                         isInt = true
925                                 }
926                         default:
927                                 // Already 0, false.
928                         }
929                 }
930                 p.argNum++
931                 if tooLarge(num) {
932                         num = 0
933                         isInt = false
934                 }
935         }
936         return
937 }
938
939 // parseArgNumber returns the value of the bracketed number, minus 1
940 // (explicit argument numbers are one-indexed but we want zero-indexed).
941 // The opening bracket is known to be present at format[0].
942 // The returned values are the index, the number of bytes to consume
943 // up to the closing paren, if present, and whether the number parsed
944 // ok. The bytes to consume will be 1 if no closing paren is present.
945 func parseArgNumber(format string) (index int, wid int, ok bool) {
946         // There must be at least 3 bytes: [n].
947         if len(format) < 3 {
948                 return 0, 1, false
949         }
950
951         // Find closing bracket.
952         for i := 1; i < len(format); i++ {
953                 if format[i] == ']' {
954                         width, ok, newi := parsenum(format, 1, i)
955                         if !ok || newi != i {
956                                 return 0, i + 1, false
957                         }
958                         return width - 1, i + 1, true // arg numbers are one-indexed and skip paren.
959                 }
960         }
961         return 0, 1, false
962 }
963
964 // updateArgNumber returns the next argument to evaluate, which is either the value of the passed-in
965 // argNum or the value of the bracketed integer that begins format[i:]. It also returns
966 // the new value of i, that is, the index of the next byte of the format to process.
967 func (p *printer) updateArgNumber(format string, i int) (newi int, found bool) {
968         if len(format) <= i || format[i] != '[' {
969                 return i, false
970         }
971         p.reordered = true
972         index, wid, ok := parseArgNumber(format[i:])
973         if ok && 0 <= index && index < len(p.args) {
974                 p.argNum = index
975                 return i + wid, true
976         }
977         p.goodArgNum = false
978         return i + wid, ok
979 }
980
981 func (p *printer) badArgNum(verb rune) {
982         p.WriteString(percentBangString)
983         p.WriteRune(verb)
984         p.WriteString(badIndexString)
985 }
986
987 func (p *printer) missingArg(verb rune) {
988         p.WriteString(percentBangString)
989         p.WriteRune(verb)
990         p.WriteString(missingString)
991 }
992
993 func (p *printer) doPrintf(format string) {
994         end := len(format)
995         afterIndex := false // previous item in format was an index like [3].
996 formatLoop:
997         for i := 0; i < end; {
998                 p.goodArgNum = true
999                 lasti := i
1000                 for i < end && format[i] != '%' {
1001                         i++
1002                 }
1003                 if i > lasti {
1004                         p.WriteString(format[lasti:i])
1005                 }
1006                 if i >= end {
1007                         // done processing format string
1008                         break
1009                 }
1010
1011                 // Process one verb
1012                 i++
1013
1014                 // Do we have flags?
1015                 p.fmt.clearflags()
1016         simpleFormat:
1017                 for ; i < end; i++ {
1018                         c := format[i]
1019                         switch c {
1020                         case '#':
1021                                 p.fmt.sharp = true
1022                         case '0':
1023                                 p.fmt.zero = !p.fmt.minus // Only allow zero padding to the left.
1024                         case '+':
1025                                 p.fmt.plus = true
1026                         case '-':
1027                                 p.fmt.minus = true
1028                                 p.fmt.zero = false // Do not pad with zeros to the right.
1029                         case ' ':
1030                                 p.fmt.space = true
1031                         default:
1032                                 // Fast path for common case of ascii lower case simple verbs
1033                                 // without precision or width or argument indices.
1034                                 if 'a' <= c && c <= 'z' && p.argNum < len(p.args) {
1035                                         if c == 'v' {
1036                                                 // Go syntax
1037                                                 p.fmt.sharpV = p.fmt.sharp
1038                                                 p.fmt.sharp = false
1039                                                 // Struct-field syntax
1040                                                 p.fmt.plusV = p.fmt.plus
1041                                                 p.fmt.plus = false
1042                                         }
1043                                         p.printArg(p.Arg(p.argNum+1), rune(c))
1044                                         p.argNum++
1045                                         i++
1046                                         continue formatLoop
1047                                 }
1048                                 // Format is more complex than simple flags and a verb or is malformed.
1049                                 break simpleFormat
1050                         }
1051                 }
1052
1053                 // Do we have an explicit argument index?
1054                 i, afterIndex = p.updateArgNumber(format, i)
1055
1056                 // Do we have width?
1057                 if i < end && format[i] == '*' {
1058                         i++
1059                         p.fmt.wid, p.fmt.widPresent = p.intFromArg()
1060
1061                         if !p.fmt.widPresent {
1062                                 p.WriteString(badWidthString)
1063                         }
1064
1065                         // We have a negative width, so take its value and ensure
1066                         // that the minus flag is set
1067                         if p.fmt.wid < 0 {
1068                                 p.fmt.wid = -p.fmt.wid
1069                                 p.fmt.minus = true
1070                                 p.fmt.zero = false // Do not pad with zeros to the right.
1071                         }
1072                         afterIndex = false
1073                 } else {
1074                         p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end)
1075                         if afterIndex && p.fmt.widPresent { // "%[3]2d"
1076                                 p.goodArgNum = false
1077                         }
1078                 }
1079
1080                 // Do we have precision?
1081                 if i+1 < end && format[i] == '.' {
1082                         i++
1083                         if afterIndex { // "%[3].2d"
1084                                 p.goodArgNum = false
1085                         }
1086                         i, afterIndex = p.updateArgNumber(format, i)
1087                         if i < end && format[i] == '*' {
1088                                 i++
1089                                 p.fmt.prec, p.fmt.precPresent = p.intFromArg()
1090                                 // Negative precision arguments don't make sense
1091                                 if p.fmt.prec < 0 {
1092                                         p.fmt.prec = 0
1093                                         p.fmt.precPresent = false
1094                                 }
1095                                 if !p.fmt.precPresent {
1096                                         p.WriteString(badPrecString)
1097                                 }
1098                                 afterIndex = false
1099                         } else {
1100                                 p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i, end)
1101                                 if !p.fmt.precPresent {
1102                                         p.fmt.prec = 0
1103                                         p.fmt.precPresent = true
1104                                 }
1105                         }
1106                 }
1107
1108                 if !afterIndex {
1109                         i, afterIndex = p.updateArgNumber(format, i)
1110                 }
1111
1112                 if i >= end {
1113                         p.WriteString(noVerbString)
1114                         break
1115                 }
1116
1117                 verb, w := utf8.DecodeRuneInString(format[i:])
1118                 i += w
1119
1120                 switch {
1121                 case verb == '%': // Percent does not absorb operands and ignores f.wid and f.prec.
1122                         p.WriteByte('%')
1123                 case !p.goodArgNum:
1124                         p.badArgNum(verb)
1125                 case p.argNum >= len(p.args): // No argument left over to print for the current verb.
1126                         p.missingArg(verb)
1127                 case verb == 'v':
1128                         // Go syntax
1129                         p.fmt.sharpV = p.fmt.sharp
1130                         p.fmt.sharp = false
1131                         // Struct-field syntax
1132                         p.fmt.plusV = p.fmt.plus
1133                         p.fmt.plus = false
1134                         fallthrough
1135                 default:
1136                         p.printArg(p.args[p.argNum], verb)
1137                         p.argNum++
1138                 }
1139         }
1140
1141         // Check for extra arguments, but only if there was at least one ordered
1142         // argument. Note that this behavior is necessarily different from fmt:
1143         // different variants of messages may opt to drop some or all of the
1144         // arguments.
1145         if !p.reordered && p.argNum < len(p.args) && p.argNum != 0 {
1146                 p.fmt.clearflags()
1147                 p.WriteString(extraString)
1148                 for i, arg := range p.args[p.argNum:] {
1149                         if i > 0 {
1150                                 p.WriteString(commaSpaceString)
1151                         }
1152                         if arg == nil {
1153                                 p.WriteString(nilAngleString)
1154                         } else {
1155                                 p.WriteString(reflect.TypeOf(arg).String())
1156                                 p.WriteByte('=')
1157                                 p.printArg(arg, 'v')
1158                         }
1159                 }
1160                 p.WriteByte(')')
1161         }
1162 }
1163
1164 func (p *printer) doPrint(a []interface{}) {
1165         prevString := false
1166         for argNum, arg := range a {
1167                 isString := arg != nil && reflect.TypeOf(arg).Kind() == reflect.String
1168                 // Add a space between two non-string arguments.
1169                 if argNum > 0 && !isString && !prevString {
1170                         p.WriteByte(' ')
1171                 }
1172                 p.printArg(arg, 'v')
1173                 prevString = isString
1174         }
1175 }
1176
1177 // doPrintln is like doPrint but always adds a space between arguments
1178 // and a newline after the last argument.
1179 func (p *printer) doPrintln(a []interface{}) {
1180         for argNum, arg := range a {
1181                 if argNum > 0 {
1182                         p.WriteByte(' ')
1183                 }
1184                 p.printArg(arg, 'v')
1185         }
1186         p.WriteByte('\n')
1187 }