Source file
src/fmt/print.go
1
2
3
4
5 package fmt
6
7 import (
8 "internal/fmtsort"
9 "io"
10 "os"
11 "reflect"
12 "strconv"
13 "sync"
14 "unicode/utf8"
15 )
16
17
18
19 const (
20 commaSpaceString = ", "
21 nilAngleString = "<nil>"
22 nilParenString = "(nil)"
23 nilString = "nil"
24 mapString = "map["
25 percentBangString = "%!"
26 missingString = "(MISSING)"
27 badIndexString = "(BADINDEX)"
28 panicString = "(PANIC="
29 extraString = "%!(EXTRA "
30 badWidthString = "%!(BADWIDTH)"
31 badPrecString = "%!(BADPREC)"
32 noVerbString = "%!(NOVERB)"
33 invReflectString = "<invalid reflect.Value>"
34 )
35
36
37
38
39 type State interface {
40
41 Write(b []byte) (n int, err error)
42
43 Width() (wid int, ok bool)
44
45 Precision() (prec int, ok bool)
46
47
48 Flag(c int) bool
49 }
50
51
52
53
54 type Formatter interface {
55 Format(f State, verb rune)
56 }
57
58
59
60
61
62
63 type Stringer interface {
64 String() string
65 }
66
67
68
69
70
71 type GoStringer interface {
72 GoString() string
73 }
74
75
76
77
78
79
80
81 func FormatString(state State, verb rune) string {
82 var tmp [16]byte
83 b := append(tmp[:0], '%')
84 for _, c := range " +-#0" {
85 if state.Flag(int(c)) {
86 b = append(b, byte(c))
87 }
88 }
89 if w, ok := state.Width(); ok {
90 b = strconv.AppendInt(b, int64(w), 10)
91 }
92 if p, ok := state.Precision(); ok {
93 b = append(b, '.')
94 b = strconv.AppendInt(b, int64(p), 10)
95 }
96 b = utf8.AppendRune(b, verb)
97 return string(b)
98 }
99
100
101 type buffer []byte
102
103 func (b *buffer) write(p []byte) {
104 *b = append(*b, p...)
105 }
106
107 func (b *buffer) writeString(s string) {
108 *b = append(*b, s...)
109 }
110
111 func (b *buffer) writeByte(c byte) {
112 *b = append(*b, c)
113 }
114
115 func (b *buffer) writeRune(r rune) {
116 *b = utf8.AppendRune(*b, r)
117 }
118
119
120 type pp struct {
121 buf buffer
122
123
124 fmt fmt
125
126
127 reordered bool
128
129 goodArgNum bool
130
131 panicking bool
132
133 erroring bool
134
135 wrapErrs bool
136
137 wrappedErrs []int
138 }
139
140 var ppFree = sync.Pool{
141 New: func() any { return new(pp) },
142 }
143
144
145 func newPrinter() *pp {
146 p := ppFree.Get().(*pp)
147 p.panicking = false
148 p.erroring = false
149 p.wrapErrs = false
150 p.fmt.init(&p.buf)
151 return p
152 }
153
154
155 func (p *pp) free() {
156
157
158
159
160
161
162
163 if cap(p.buf) > 64*1024 {
164 p.buf = nil
165 } else {
166 p.buf = p.buf[:0]
167 }
168 if cap(p.wrappedErrs) > 8 {
169 p.wrappedErrs = nil
170 }
171
172 p.wrappedErrs = p.wrappedErrs[:0]
173 ppFree.Put(p)
174 }
175
176 func (p *pp) Width() (wid int, ok bool) { return p.fmt.wid, p.fmt.widPresent }
177
178 func (p *pp) Precision() (prec int, ok bool) { return p.fmt.prec, p.fmt.precPresent }
179
180 func (p *pp) Flag(b int) bool {
181 switch b {
182 case '-':
183 return p.fmt.minus
184 case '+':
185 return p.fmt.plus || p.fmt.plusV
186 case '#':
187 return p.fmt.sharp || p.fmt.sharpV
188 case ' ':
189 return p.fmt.space
190 case '0':
191 return p.fmt.zero
192 }
193 return false
194 }
195
196
197
198 func (p *pp) Write(b []byte) (ret int, err error) {
199 p.buf.write(b)
200 return len(b), nil
201 }
202
203
204
205 func (p *pp) WriteString(s string) (ret int, err error) {
206 p.buf.writeString(s)
207 return len(s), nil
208 }
209
210
211
212
213
214 func Fprintf(w io.Writer, format string, a ...any) (n int, err error) {
215 p := newPrinter()
216 p.doPrintf(format, a)
217 n, err = w.Write(p.buf)
218 p.free()
219 return
220 }
221
222
223
224 func Printf(format string, a ...any) (n int, err error) {
225 return Fprintf(os.Stdout, format, a...)
226 }
227
228
229 func Sprintf(format string, a ...any) string {
230 p := newPrinter()
231 p.doPrintf(format, a)
232 s := string(p.buf)
233 p.free()
234 return s
235 }
236
237
238
239 func Appendf(b []byte, format string, a ...any) []byte {
240 p := newPrinter()
241 p.doPrintf(format, a)
242 b = append(b, p.buf...)
243 p.free()
244 return b
245 }
246
247
248
249
250
251
252 func Fprint(w io.Writer, a ...any) (n int, err error) {
253 p := newPrinter()
254 p.doPrint(a)
255 n, err = w.Write(p.buf)
256 p.free()
257 return
258 }
259
260
261
262
263 func Print(a ...any) (n int, err error) {
264 return Fprint(os.Stdout, a...)
265 }
266
267
268
269 func Sprint(a ...any) string {
270 p := newPrinter()
271 p.doPrint(a)
272 s := string(p.buf)
273 p.free()
274 return s
275 }
276
277
278
279
280 func Append(b []byte, a ...any) []byte {
281 p := newPrinter()
282 p.doPrint(a)
283 b = append(b, p.buf...)
284 p.free()
285 return b
286 }
287
288
289
290
291
292
293
294
295 func Fprintln(w io.Writer, a ...any) (n int, err error) {
296 p := newPrinter()
297 p.doPrintln(a)
298 n, err = w.Write(p.buf)
299 p.free()
300 return
301 }
302
303
304
305
306 func Println(a ...any) (n int, err error) {
307 return Fprintln(os.Stdout, a...)
308 }
309
310
311
312 func Sprintln(a ...any) string {
313 p := newPrinter()
314 p.doPrintln(a)
315 s := string(p.buf)
316 p.free()
317 return s
318 }
319
320
321
322
323 func Appendln(b []byte, a ...any) []byte {
324 p := newPrinter()
325 p.doPrintln(a)
326 b = append(b, p.buf...)
327 p.free()
328 return b
329 }
330
331
332
333
334 func getField(v reflect.Value, i int) reflect.Value {
335 val := v.Field(i)
336 if val.Kind() == reflect.Interface && !val.IsNil() {
337 val = val.Elem()
338 }
339 return val
340 }
341
342
343
344 func tooLarge(x int) bool {
345 const max int = 1e6
346 return x > max || x < -max
347 }
348
349
350 func parsenum(s string, start, end int) (num int, isnum bool, newi int) {
351 if start >= end {
352 return 0, false, end
353 }
354 for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ {
355 if tooLarge(num) {
356 return 0, false, end
357 }
358 num = num*10 + int(s[newi]-'0')
359 isnum = true
360 }
361 return
362 }
363
364 func (p *pp) unknownType(v reflect.Value) {
365 if !v.IsValid() {
366 p.buf.writeString(nilAngleString)
367 return
368 }
369 p.buf.writeByte('?')
370 p.buf.writeString(v.Type().String())
371 p.buf.writeByte('?')
372 }
373
374 func (p *pp) badVerb(arg any, value reflect.Value, verb rune) {
375 p.erroring = true
376 p.buf.writeString(percentBangString)
377 p.buf.writeRune(verb)
378 p.buf.writeByte('(')
379 switch {
380 case arg != nil:
381 p.buf.writeString(reflect.TypeOf(arg).String())
382 p.buf.writeByte('=')
383 p.printArg(arg, 'v')
384 case value.IsValid():
385 p.buf.writeString(value.Type().String())
386 p.buf.writeByte('=')
387 p.printValue(value, 'v', 0)
388 default:
389 p.buf.writeString(nilAngleString)
390 }
391 p.buf.writeByte(')')
392 p.erroring = false
393 }
394
395 func (p *pp) fmtBool(arg any, value reflect.Value, v bool, verb rune) {
396 switch verb {
397 case 't', 'v':
398 p.fmt.fmtBoolean(v)
399 default:
400 p.badVerb(arg, value, verb)
401 }
402 }
403
404
405
406 func (p *pp) fmt0x64(v uint64, leading0x bool) {
407 sharp := p.fmt.sharp
408 p.fmt.sharp = leading0x
409 p.fmt.fmtInteger(v, 16, unsigned, 'v', ldigits)
410 p.fmt.sharp = sharp
411 }
412
413
414 func (p *pp) fmtInteger(arg any, value reflect.Value, v uint64, isSigned bool, verb rune) {
415 switch verb {
416 case 'v':
417 if p.fmt.sharpV && !isSigned {
418 p.fmt0x64(v, true)
419 } else {
420 p.fmt.fmtInteger(v, 10, isSigned, verb, ldigits)
421 }
422 case 'd':
423 p.fmt.fmtInteger(v, 10, isSigned, verb, ldigits)
424 case 'b':
425 p.fmt.fmtInteger(v, 2, isSigned, verb, ldigits)
426 case 'o', 'O':
427 p.fmt.fmtInteger(v, 8, isSigned, verb, ldigits)
428 case 'x':
429 p.fmt.fmtInteger(v, 16, isSigned, verb, ldigits)
430 case 'X':
431 p.fmt.fmtInteger(v, 16, isSigned, verb, udigits)
432 case 'c':
433 p.fmt.fmtC(v)
434 case 'q':
435 p.fmt.fmtQc(v)
436 case 'U':
437 p.fmt.fmtUnicode(v)
438 default:
439 p.badVerb(arg, value, verb)
440 }
441 }
442
443
444
445 func (p *pp) fmtFloat(arg any, value reflect.Value, v float64, size int, verb rune) {
446 switch verb {
447 case 'v':
448 p.fmt.fmtFloat(v, size, 'g', -1)
449 case 'b', 'g', 'G', 'x', 'X':
450 p.fmt.fmtFloat(v, size, verb, -1)
451 case 'f', 'e', 'E':
452 p.fmt.fmtFloat(v, size, verb, 6)
453 case 'F':
454 p.fmt.fmtFloat(v, size, 'f', 6)
455 default:
456 p.badVerb(arg, value, verb)
457 }
458 }
459
460
461
462
463 func (p *pp) fmtComplex(arg any, value reflect.Value, v complex128, size int, verb rune) {
464
465
466 switch verb {
467 case 'v', 'b', 'g', 'G', 'x', 'X', 'f', 'F', 'e', 'E':
468 oldPlus := p.fmt.plus
469 p.buf.writeByte('(')
470 p.fmtFloat(arg, value, real(v), size/2, verb)
471
472 p.fmt.plus = true
473 p.fmtFloat(arg, value, imag(v), size/2, verb)
474 p.buf.writeString("i)")
475 p.fmt.plus = oldPlus
476 default:
477 p.badVerb(arg, value, verb)
478 }
479 }
480
481 func (p *pp) fmtString(arg any, value reflect.Value, v string, verb rune) {
482 switch verb {
483 case 'v':
484 if p.fmt.sharpV {
485 p.fmt.fmtQ(v)
486 } else {
487 p.fmt.fmtS(v)
488 }
489 case 's':
490 p.fmt.fmtS(v)
491 case 'x':
492 p.fmt.fmtSx(v, ldigits)
493 case 'X':
494 p.fmt.fmtSx(v, udigits)
495 case 'q':
496 p.fmt.fmtQ(v)
497 default:
498 p.badVerb(arg, value, verb)
499 }
500 }
501
502 func (p *pp) fmtBytes(v []byte, verb rune, typeString string) {
503 switch verb {
504 case 'v', 'd':
505 if p.fmt.sharpV {
506 p.buf.writeString(typeString)
507 if v == nil {
508 p.buf.writeString(nilParenString)
509 return
510 }
511 p.buf.writeByte('{')
512 for i, c := range v {
513 if i > 0 {
514 p.buf.writeString(commaSpaceString)
515 }
516 p.fmt0x64(uint64(c), true)
517 }
518 p.buf.writeByte('}')
519 } else {
520 p.buf.writeByte('[')
521 for i, c := range v {
522 if i > 0 {
523 p.buf.writeByte(' ')
524 }
525 p.fmt.fmtInteger(uint64(c), 10, unsigned, verb, ldigits)
526 }
527 p.buf.writeByte(']')
528 }
529 case 's':
530 p.fmt.fmtBs(v)
531 case 'x':
532 p.fmt.fmtBx(v, ldigits)
533 case 'X':
534 p.fmt.fmtBx(v, udigits)
535 case 'q':
536 p.fmt.fmtQ(string(v))
537 default:
538 p.printValue(reflect.ValueOf(v), verb, 0)
539 }
540 }
541
542 func (p *pp) fmtPointer(arg any, value reflect.Value, verb rune) {
543 var u uintptr
544 switch value.Kind() {
545 case reflect.Chan, reflect.Func, reflect.Map, reflect.Pointer, reflect.Slice, reflect.UnsafePointer:
546 u = uintptr(value.UnsafePointer())
547 default:
548 p.badVerb(arg, value, verb)
549 return
550 }
551
552 switch verb {
553 case 'v':
554 if p.fmt.sharpV {
555 p.buf.writeByte('(')
556 p.buf.writeString(value.Type().String())
557 p.buf.writeString(")(")
558 if u == 0 {
559 p.buf.writeString(nilString)
560 } else {
561 p.fmt0x64(uint64(u), true)
562 }
563 p.buf.writeByte(')')
564 } else {
565 if u == 0 {
566 p.fmt.padString(nilAngleString)
567 } else {
568 p.fmt0x64(uint64(u), !p.fmt.sharp)
569 }
570 }
571 case 'p':
572 p.fmt0x64(uint64(u), !p.fmt.sharp)
573 case 'b', 'o', 'd', 'x', 'X':
574 p.fmtInteger(arg, value, uint64(u), unsigned, verb)
575 default:
576 p.badVerb(arg, value, verb)
577 }
578 }
579
580 func (p *pp) catchPanic(arg any, verb rune, method string) {
581 if err := recover(); err != nil {
582
583
584
585 if v := reflect.ValueOf(arg); v.Kind() == reflect.Pointer && v.IsNil() {
586 p.buf.writeString(nilAngleString)
587 return
588 }
589
590
591 if p.panicking {
592
593 panic(err)
594 }
595
596 oldFlags := p.fmt.fmtFlags
597
598 p.fmt.clearflags()
599
600 p.buf.writeString(percentBangString)
601 p.buf.writeRune(verb)
602 p.buf.writeString(panicString)
603 p.buf.writeString(method)
604 p.buf.writeString(" method: ")
605 p.panicking = true
606 p.printArg(err, 'v')
607 p.panicking = false
608 p.buf.writeByte(')')
609
610 p.fmt.fmtFlags = oldFlags
611 }
612 }
613
614 func (p *pp) handleMethods(arg any, value reflect.Value, verb rune) (handled bool) {
615 if p.erroring {
616 return
617 }
618 if verb == 'w' {
619
620 _, ok := arg.(error)
621 if !ok || !p.wrapErrs {
622 p.badVerb(arg, value, verb)
623 return true
624 }
625
626 verb = 'v'
627 }
628
629
630 if formatter, ok := arg.(Formatter); ok {
631 handled = true
632 defer p.catchPanic(arg, verb, "Format")
633 formatter.Format(p, verb)
634 return
635 }
636
637
638 if p.fmt.sharpV {
639 if stringer, ok := arg.(GoStringer); ok {
640 handled = true
641 defer p.catchPanic(arg, verb, "GoString")
642
643 p.fmt.fmtS(stringer.GoString())
644 return
645 }
646 } else {
647
648
649
650 switch verb {
651 case 'v', 's', 'x', 'X', 'q':
652
653
654
655
656 switch v := arg.(type) {
657 case error:
658 handled = true
659 defer p.catchPanic(arg, verb, "Error")
660 p.fmtString(arg, value, v.Error(), verb)
661 return
662
663 case Stringer:
664 handled = true
665 defer p.catchPanic(arg, verb, "String")
666 p.fmtString(arg, value, v.String(), verb)
667 return
668 }
669 }
670 }
671 return false
672 }
673
674 func (p *pp) printArg(arg any, verb rune) {
675 if arg == nil {
676 switch verb {
677 case 'T', 'v':
678 p.fmt.padString(nilAngleString)
679 default:
680 p.badVerb(arg, reflect.Value{}, verb)
681 }
682 return
683 }
684
685
686
687 switch verb {
688 case 'T':
689 p.fmt.fmtS(reflect.TypeOf(arg).String())
690 return
691 case 'p':
692 p.fmtPointer(arg, reflect.ValueOf(arg), 'p')
693 return
694 }
695
696
697 switch f := arg.(type) {
698 case bool:
699 p.fmtBool(arg, reflect.Value{}, f, verb)
700 case float32:
701 p.fmtFloat(arg, reflect.Value{}, float64(f), 32, verb)
702 case float64:
703 p.fmtFloat(arg, reflect.Value{}, f, 64, verb)
704 case complex64:
705 p.fmtComplex(arg, reflect.Value{}, complex128(f), 64, verb)
706 case complex128:
707 p.fmtComplex(arg, reflect.Value{}, f, 128, verb)
708 case int:
709 p.fmtInteger(arg, reflect.Value{}, uint64(f), signed, verb)
710 case int8:
711 p.fmtInteger(arg, reflect.Value{}, uint64(f), signed, verb)
712 case int16:
713 p.fmtInteger(arg, reflect.Value{}, uint64(f), signed, verb)
714 case int32:
715 p.fmtInteger(arg, reflect.Value{}, uint64(f), signed, verb)
716 case int64:
717 p.fmtInteger(arg, reflect.Value{}, uint64(f), signed, verb)
718 case uint:
719 p.fmtInteger(arg, reflect.Value{}, uint64(f), unsigned, verb)
720 case uint8:
721 p.fmtInteger(arg, reflect.Value{}, uint64(f), unsigned, verb)
722 case uint16:
723 p.fmtInteger(arg, reflect.Value{}, uint64(f), unsigned, verb)
724 case uint32:
725 p.fmtInteger(arg, reflect.Value{}, uint64(f), unsigned, verb)
726 case uint64:
727 p.fmtInteger(arg, reflect.Value{}, f, unsigned, verb)
728 case uintptr:
729 p.fmtInteger(arg, reflect.Value{}, uint64(f), unsigned, verb)
730 case string:
731 p.fmtString(arg, reflect.Value{}, f, verb)
732 case []byte:
733 p.fmtBytes(f, verb, "[]byte")
734 case reflect.Value:
735
736
737 if f.IsValid() && f.CanInterface() {
738 arg = f.Interface()
739 if p.handleMethods(arg, reflect.Value{}, verb) {
740 return
741 }
742 }
743 p.printValue(f, verb, 0)
744 default:
745
746 if !p.handleMethods(arg, reflect.Value{}, verb) {
747
748
749 p.printValue(reflect.ValueOf(f), verb, 0)
750 }
751 }
752 }
753
754
755
756 func (p *pp) printValue(value reflect.Value, verb rune, depth int) {
757
758 if depth > 0 && value.IsValid() && value.CanInterface() {
759 arg := value.Interface()
760 if p.handleMethods(arg, value, verb) {
761 return
762 }
763 }
764
765 switch f := value; value.Kind() {
766 case reflect.Invalid:
767 if depth == 0 {
768 p.buf.writeString(invReflectString)
769 } else {
770 switch verb {
771 case 'v':
772 p.buf.writeString(nilAngleString)
773 default:
774 p.badVerb(nil, value, verb)
775 }
776 }
777 case reflect.Bool:
778 p.fmtBool(nil, value, f.Bool(), verb)
779 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
780 p.fmtInteger(nil, value, uint64(f.Int()), signed, verb)
781 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
782 p.fmtInteger(nil, value, f.Uint(), unsigned, verb)
783 case reflect.Float32:
784 p.fmtFloat(nil, value, f.Float(), 32, verb)
785 case reflect.Float64:
786 p.fmtFloat(nil, value, f.Float(), 64, verb)
787 case reflect.Complex64:
788 p.fmtComplex(nil, value, f.Complex(), 64, verb)
789 case reflect.Complex128:
790 p.fmtComplex(nil, value, f.Complex(), 128, verb)
791 case reflect.String:
792 p.fmtString(nil, value, f.String(), verb)
793 case reflect.Map:
794 if p.fmt.sharpV {
795 p.buf.writeString(f.Type().String())
796 if f.IsNil() {
797 p.buf.writeString(nilParenString)
798 return
799 }
800 p.buf.writeByte('{')
801 } else {
802 p.buf.writeString(mapString)
803 }
804 sorted := fmtsort.Sort(f)
805 for i, m := range sorted {
806 if i > 0 {
807 if p.fmt.sharpV {
808 p.buf.writeString(commaSpaceString)
809 } else {
810 p.buf.writeByte(' ')
811 }
812 }
813 p.printValue(m.Key, verb, depth+1)
814 p.buf.writeByte(':')
815 p.printValue(m.Value, verb, depth+1)
816 }
817 if p.fmt.sharpV {
818 p.buf.writeByte('}')
819 } else {
820 p.buf.writeByte(']')
821 }
822 case reflect.Struct:
823 if p.fmt.sharpV {
824 p.buf.writeString(f.Type().String())
825 }
826 p.buf.writeByte('{')
827 for i := 0; i < f.NumField(); i++ {
828 if i > 0 {
829 if p.fmt.sharpV {
830 p.buf.writeString(commaSpaceString)
831 } else {
832 p.buf.writeByte(' ')
833 }
834 }
835 if p.fmt.plusV || p.fmt.sharpV {
836 if name := f.Type().Field(i).Name; name != "" {
837 p.buf.writeString(name)
838 p.buf.writeByte(':')
839 }
840 }
841 p.printValue(getField(f, i), verb, depth+1)
842 }
843 p.buf.writeByte('}')
844 case reflect.Interface:
845 value := f.Elem()
846 if !value.IsValid() {
847 if p.fmt.sharpV {
848 p.buf.writeString(f.Type().String())
849 p.buf.writeString(nilParenString)
850 } else {
851 p.buf.writeString(nilAngleString)
852 }
853 } else {
854 p.printValue(value, verb, depth+1)
855 }
856 case reflect.Array, reflect.Slice:
857 switch verb {
858 case 's', 'q', 'x', 'X':
859
860 t := f.Type()
861 if t.Elem().Kind() == reflect.Uint8 {
862 var bytes []byte
863 if f.Kind() == reflect.Slice || f.CanAddr() {
864 bytes = f.Bytes()
865 } else {
866
867
868
869 bytes = make([]byte, f.Len())
870 for i := range bytes {
871 bytes[i] = byte(f.Index(i).Uint())
872 }
873 }
874 p.fmtBytes(bytes, verb, t.String())
875 return
876 }
877 }
878 if p.fmt.sharpV {
879 p.buf.writeString(f.Type().String())
880 if f.Kind() == reflect.Slice && f.IsNil() {
881 p.buf.writeString(nilParenString)
882 return
883 }
884 p.buf.writeByte('{')
885 for i := 0; i < f.Len(); i++ {
886 if i > 0 {
887 p.buf.writeString(commaSpaceString)
888 }
889 p.printValue(f.Index(i), verb, depth+1)
890 }
891 p.buf.writeByte('}')
892 } else {
893 p.buf.writeByte('[')
894 for i := 0; i < f.Len(); i++ {
895 if i > 0 {
896 p.buf.writeByte(' ')
897 }
898 p.printValue(f.Index(i), verb, depth+1)
899 }
900 p.buf.writeByte(']')
901 }
902 case reflect.Pointer:
903
904
905 if depth == 0 && f.UnsafePointer() != nil {
906 switch a := f.Elem(); a.Kind() {
907 case reflect.Array, reflect.Slice, reflect.Struct, reflect.Map:
908 p.buf.writeByte('&')
909 p.printValue(a, verb, depth+1)
910 return
911 }
912 }
913 fallthrough
914 case reflect.Chan, reflect.Func, reflect.UnsafePointer:
915 p.fmtPointer(nil, f, verb)
916 default:
917 p.unknownType(f)
918 }
919 }
920
921
922 func intFromArg(a []any, argNum int) (num int, isInt bool, newArgNum int) {
923 newArgNum = argNum
924 if argNum < len(a) {
925 num, isInt = a[argNum].(int)
926 if !isInt {
927
928 switch v := reflect.ValueOf(a[argNum]); v.Kind() {
929 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
930 n := v.Int()
931 if int64(int(n)) == n {
932 num = int(n)
933 isInt = true
934 }
935 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
936 n := v.Uint()
937 if int64(n) >= 0 && uint64(int(n)) == n {
938 num = int(n)
939 isInt = true
940 }
941 default:
942
943 }
944 }
945 newArgNum = argNum + 1
946 if tooLarge(num) {
947 num = 0
948 isInt = false
949 }
950 }
951 return
952 }
953
954
955
956
957
958
959
960 func parseArgNumber(format string) (index int, wid int, ok bool) {
961
962 if len(format) < 3 {
963 return 0, 1, false
964 }
965
966
967 for i := 1; i < len(format); i++ {
968 if format[i] == ']' {
969 width, ok, newi := parsenum(format, 1, i)
970 if !ok || newi != i {
971 return 0, i + 1, false
972 }
973 return width - 1, i + 1, true
974 }
975 }
976 return 0, 1, false
977 }
978
979
980
981
982 func (p *pp) argNumber(argNum int, format string, i int, numArgs int) (newArgNum, newi int, found bool) {
983 if len(format) <= i || format[i] != '[' {
984 return argNum, i, false
985 }
986 p.reordered = true
987 index, wid, ok := parseArgNumber(format[i:])
988 if ok && 0 <= index && index < numArgs {
989 return index, i + wid, true
990 }
991 p.goodArgNum = false
992 return argNum, i + wid, ok
993 }
994
995 func (p *pp) badArgNum(verb rune) {
996 p.buf.writeString(percentBangString)
997 p.buf.writeRune(verb)
998 p.buf.writeString(badIndexString)
999 }
1000
1001 func (p *pp) missingArg(verb rune) {
1002 p.buf.writeString(percentBangString)
1003 p.buf.writeRune(verb)
1004 p.buf.writeString(missingString)
1005 }
1006
1007 func (p *pp) doPrintf(format string, a []any) {
1008 end := len(format)
1009 argNum := 0
1010 afterIndex := false
1011 p.reordered = false
1012 formatLoop:
1013 for i := 0; i < end; {
1014 p.goodArgNum = true
1015 lasti := i
1016 for i < end && format[i] != '%' {
1017 i++
1018 }
1019 if i > lasti {
1020 p.buf.writeString(format[lasti:i])
1021 }
1022 if i >= end {
1023
1024 break
1025 }
1026
1027
1028 i++
1029
1030
1031 p.fmt.clearflags()
1032 simpleFormat:
1033 for ; i < end; i++ {
1034 c := format[i]
1035 switch c {
1036 case '#':
1037 p.fmt.sharp = true
1038 case '0':
1039 p.fmt.zero = true
1040 case '+':
1041 p.fmt.plus = true
1042 case '-':
1043 p.fmt.minus = true
1044 case ' ':
1045 p.fmt.space = true
1046 default:
1047
1048
1049 if 'a' <= c && c <= 'z' && argNum < len(a) {
1050 switch c {
1051 case 'w':
1052 p.wrappedErrs = append(p.wrappedErrs, argNum)
1053 fallthrough
1054 case 'v':
1055
1056 p.fmt.sharpV = p.fmt.sharp
1057 p.fmt.sharp = false
1058
1059 p.fmt.plusV = p.fmt.plus
1060 p.fmt.plus = false
1061 }
1062 p.printArg(a[argNum], rune(c))
1063 argNum++
1064 i++
1065 continue formatLoop
1066 }
1067
1068 break simpleFormat
1069 }
1070 }
1071
1072
1073 argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
1074
1075
1076 if i < end && format[i] == '*' {
1077 i++
1078 p.fmt.wid, p.fmt.widPresent, argNum = intFromArg(a, argNum)
1079
1080 if !p.fmt.widPresent {
1081 p.buf.writeString(badWidthString)
1082 }
1083
1084
1085
1086 if p.fmt.wid < 0 {
1087 p.fmt.wid = -p.fmt.wid
1088 p.fmt.minus = true
1089 p.fmt.zero = false
1090 }
1091 afterIndex = false
1092 } else {
1093 p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end)
1094 if afterIndex && p.fmt.widPresent {
1095 p.goodArgNum = false
1096 }
1097 }
1098
1099
1100 if i+1 < end && format[i] == '.' {
1101 i++
1102 if afterIndex {
1103 p.goodArgNum = false
1104 }
1105 argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
1106 if i < end && format[i] == '*' {
1107 i++
1108 p.fmt.prec, p.fmt.precPresent, argNum = intFromArg(a, argNum)
1109
1110 if p.fmt.prec < 0 {
1111 p.fmt.prec = 0
1112 p.fmt.precPresent = false
1113 }
1114 if !p.fmt.precPresent {
1115 p.buf.writeString(badPrecString)
1116 }
1117 afterIndex = false
1118 } else {
1119 p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i, end)
1120 if !p.fmt.precPresent {
1121 p.fmt.prec = 0
1122 p.fmt.precPresent = true
1123 }
1124 }
1125 }
1126
1127 if !afterIndex {
1128 argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
1129 }
1130
1131 if i >= end {
1132 p.buf.writeString(noVerbString)
1133 break
1134 }
1135
1136 verb, size := utf8.DecodeRuneInString(format[i:])
1137 i += size
1138
1139 switch {
1140 case verb == '%':
1141 p.buf.writeByte('%')
1142 case !p.goodArgNum:
1143 p.badArgNum(verb)
1144 case argNum >= len(a):
1145 p.missingArg(verb)
1146 case verb == 'w':
1147 p.wrappedErrs = append(p.wrappedErrs, argNum)
1148 fallthrough
1149 case verb == 'v':
1150
1151 p.fmt.sharpV = p.fmt.sharp
1152 p.fmt.sharp = false
1153
1154 p.fmt.plusV = p.fmt.plus
1155 p.fmt.plus = false
1156 fallthrough
1157 default:
1158 p.printArg(a[argNum], verb)
1159 argNum++
1160 }
1161 }
1162
1163
1164
1165
1166 if !p.reordered && argNum < len(a) {
1167 p.fmt.clearflags()
1168 p.buf.writeString(extraString)
1169 for i, arg := range a[argNum:] {
1170 if i > 0 {
1171 p.buf.writeString(commaSpaceString)
1172 }
1173 if arg == nil {
1174 p.buf.writeString(nilAngleString)
1175 } else {
1176 p.buf.writeString(reflect.TypeOf(arg).String())
1177 p.buf.writeByte('=')
1178 p.printArg(arg, 'v')
1179 }
1180 }
1181 p.buf.writeByte(')')
1182 }
1183 }
1184
1185 func (p *pp) doPrint(a []any) {
1186 prevString := false
1187 for argNum, arg := range a {
1188 isString := arg != nil && reflect.TypeOf(arg).Kind() == reflect.String
1189
1190 if argNum > 0 && !isString && !prevString {
1191 p.buf.writeByte(' ')
1192 }
1193 p.printArg(arg, 'v')
1194 prevString = isString
1195 }
1196 }
1197
1198
1199
1200 func (p *pp) doPrintln(a []any) {
1201 for argNum, arg := range a {
1202 if argNum > 0 {
1203 p.buf.writeByte(' ')
1204 }
1205 p.printArg(arg, 'v')
1206 }
1207 p.buf.writeByte('\n')
1208 }
1209
View as plain text