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
759
760
761 if depth > 0 && value.IsValid() && value.CanInterface() &&
762 (value.Type().NumMethod() > 0 || verb == 'w') {
763 arg := value.Interface()
764 if p.handleMethods(arg, value, verb) {
765 return
766 }
767 }
768
769 switch f := value; value.Kind() {
770 case reflect.Invalid:
771 if depth == 0 {
772 p.buf.writeString(invReflectString)
773 } else {
774 switch verb {
775 case 'v':
776 p.buf.writeString(nilAngleString)
777 default:
778 p.badVerb(nil, value, verb)
779 }
780 }
781 case reflect.Bool:
782 p.fmtBool(nil, value, f.Bool(), verb)
783 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
784 p.fmtInteger(nil, value, uint64(f.Int()), signed, verb)
785 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
786 p.fmtInteger(nil, value, f.Uint(), unsigned, verb)
787 case reflect.Float32:
788 p.fmtFloat(nil, value, f.Float(), 32, verb)
789 case reflect.Float64:
790 p.fmtFloat(nil, value, f.Float(), 64, verb)
791 case reflect.Complex64:
792 p.fmtComplex(nil, value, f.Complex(), 64, verb)
793 case reflect.Complex128:
794 p.fmtComplex(nil, value, f.Complex(), 128, verb)
795 case reflect.String:
796 p.fmtString(nil, value, f.String(), verb)
797 case reflect.Map:
798 if p.fmt.sharpV {
799 p.buf.writeString(f.Type().String())
800 if f.IsNil() {
801 p.buf.writeString(nilParenString)
802 return
803 }
804 p.buf.writeByte('{')
805 } else {
806 p.buf.writeString(mapString)
807 }
808 sorted := fmtsort.Sort(f)
809 for i, m := range sorted {
810 if i > 0 {
811 if p.fmt.sharpV {
812 p.buf.writeString(commaSpaceString)
813 } else {
814 p.buf.writeByte(' ')
815 }
816 }
817 p.printValue(m.Key, verb, depth+1)
818 p.buf.writeByte(':')
819 p.printValue(m.Value, verb, depth+1)
820 }
821 if p.fmt.sharpV {
822 p.buf.writeByte('}')
823 } else {
824 p.buf.writeByte(']')
825 }
826 case reflect.Struct:
827 if p.fmt.sharpV {
828 p.buf.writeString(f.Type().String())
829 }
830 p.buf.writeByte('{')
831 for i := 0; i < f.NumField(); i++ {
832 if i > 0 {
833 if p.fmt.sharpV {
834 p.buf.writeString(commaSpaceString)
835 } else {
836 p.buf.writeByte(' ')
837 }
838 }
839 if p.fmt.plusV || p.fmt.sharpV {
840 if name := f.Type().Field(i).Name; name != "" {
841 p.buf.writeString(name)
842 p.buf.writeByte(':')
843 }
844 }
845 p.printValue(getField(f, i), verb, depth+1)
846 }
847 p.buf.writeByte('}')
848 case reflect.Interface:
849 value := f.Elem()
850 if !value.IsValid() {
851 if p.fmt.sharpV {
852 p.buf.writeString(f.Type().String())
853 p.buf.writeString(nilParenString)
854 } else {
855 p.buf.writeString(nilAngleString)
856 }
857 } else {
858 p.printValue(value, verb, depth+1)
859 }
860 case reflect.Array, reflect.Slice:
861 switch verb {
862 case 's', 'q', 'x', 'X':
863
864 t := f.Type()
865 if t.Elem().Kind() == reflect.Uint8 {
866 var bytes []byte
867 if f.Kind() == reflect.Slice || f.CanAddr() {
868 bytes = f.Bytes()
869 } else {
870
871
872
873 bytes = make([]byte, f.Len())
874 for i := range bytes {
875 bytes[i] = byte(f.Index(i).Uint())
876 }
877 }
878 p.fmtBytes(bytes, verb, t.String())
879 return
880 }
881 }
882 if p.fmt.sharpV {
883 p.buf.writeString(f.Type().String())
884 if f.Kind() == reflect.Slice && f.IsNil() {
885 p.buf.writeString(nilParenString)
886 return
887 }
888 p.buf.writeByte('{')
889 for i := 0; i < f.Len(); i++ {
890 if i > 0 {
891 p.buf.writeString(commaSpaceString)
892 }
893 p.printValue(f.Index(i), verb, depth+1)
894 }
895 p.buf.writeByte('}')
896 } else {
897 p.buf.writeByte('[')
898 for i := 0; i < f.Len(); i++ {
899 if i > 0 {
900 p.buf.writeByte(' ')
901 }
902 p.printValue(f.Index(i), verb, depth+1)
903 }
904 p.buf.writeByte(']')
905 }
906 case reflect.Pointer:
907
908
909 if depth == 0 && f.UnsafePointer() != nil {
910 switch a := f.Elem(); a.Kind() {
911 case reflect.Array, reflect.Slice, reflect.Struct, reflect.Map:
912 p.buf.writeByte('&')
913 p.printValue(a, verb, depth+1)
914 return
915 }
916 }
917 fallthrough
918 case reflect.Chan, reflect.Func, reflect.UnsafePointer:
919 p.fmtPointer(nil, f, verb)
920 default:
921 p.unknownType(f)
922 }
923 }
924
925
926 func intFromArg(a []any, argNum int) (num int, isInt bool, newArgNum int) {
927 newArgNum = argNum
928 if argNum < len(a) {
929 num, isInt = a[argNum].(int)
930 if !isInt {
931
932 switch v := reflect.ValueOf(a[argNum]); v.Kind() {
933 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
934 n := v.Int()
935 if int64(int(n)) == n {
936 num = int(n)
937 isInt = true
938 }
939 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
940 n := v.Uint()
941 if int64(n) >= 0 && uint64(int(n)) == n {
942 num = int(n)
943 isInt = true
944 }
945 default:
946
947 }
948 }
949 newArgNum = argNum + 1
950 if tooLarge(num) {
951 num = 0
952 isInt = false
953 }
954 }
955 return
956 }
957
958
959
960
961
962
963
964 func parseArgNumber(format string) (index int, wid int, ok bool) {
965
966 if len(format) < 3 {
967 return 0, 1, false
968 }
969
970
971 for i := 1; i < len(format); i++ {
972 if format[i] == ']' {
973 width, ok, newi := parsenum(format, 1, i)
974 if !ok || newi != i {
975 return 0, i + 1, false
976 }
977 return width - 1, i + 1, true
978 }
979 }
980 return 0, 1, false
981 }
982
983
984
985
986 func (p *pp) argNumber(argNum int, format string, i int, numArgs int) (newArgNum, newi int, found bool) {
987 if len(format) <= i || format[i] != '[' {
988 return argNum, i, false
989 }
990 p.reordered = true
991 index, wid, ok := parseArgNumber(format[i:])
992 if ok && 0 <= index && index < numArgs {
993 return index, i + wid, true
994 }
995 p.goodArgNum = false
996 return argNum, i + wid, ok
997 }
998
999 func (p *pp) badArgNum(verb rune) {
1000 p.buf.writeString(percentBangString)
1001 p.buf.writeRune(verb)
1002 p.buf.writeString(badIndexString)
1003 }
1004
1005 func (p *pp) missingArg(verb rune) {
1006 p.buf.writeString(percentBangString)
1007 p.buf.writeRune(verb)
1008 p.buf.writeString(missingString)
1009 }
1010
1011 func (p *pp) doPrintf(format string, a []any) {
1012 end := len(format)
1013 argNum := 0
1014 afterIndex := false
1015 p.reordered = false
1016 formatLoop:
1017 for i := 0; i < end; {
1018 p.goodArgNum = true
1019 lasti := i
1020 for i < end && format[i] != '%' {
1021 i++
1022 }
1023 if i > lasti {
1024 p.buf.writeString(format[lasti:i])
1025 }
1026 if i >= end {
1027
1028 break
1029 }
1030
1031
1032 i++
1033
1034
1035 p.fmt.clearflags()
1036 simpleFormat:
1037 for ; i < end; i++ {
1038 c := format[i]
1039 switch c {
1040 case '#':
1041 p.fmt.sharp = true
1042 case '0':
1043 p.fmt.zero = true
1044 case '+':
1045 p.fmt.plus = true
1046 case '-':
1047 p.fmt.minus = true
1048 case ' ':
1049 p.fmt.space = true
1050 default:
1051
1052
1053 if 'a' <= c && c <= 'z' && argNum < len(a) {
1054 switch c {
1055 case 'w':
1056 p.wrappedErrs = append(p.wrappedErrs, argNum)
1057 fallthrough
1058 case 'v':
1059
1060 p.fmt.sharpV = p.fmt.sharp
1061 p.fmt.sharp = false
1062
1063 p.fmt.plusV = p.fmt.plus
1064 p.fmt.plus = false
1065 }
1066 p.printArg(a[argNum], rune(c))
1067 argNum++
1068 i++
1069 continue formatLoop
1070 }
1071
1072 break simpleFormat
1073 }
1074 }
1075
1076
1077 argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
1078
1079
1080 if i < end && format[i] == '*' {
1081 i++
1082 p.fmt.wid, p.fmt.widPresent, argNum = intFromArg(a, argNum)
1083
1084 if !p.fmt.widPresent {
1085 p.buf.writeString(badWidthString)
1086 }
1087
1088
1089
1090 if p.fmt.wid < 0 {
1091 p.fmt.wid = -p.fmt.wid
1092 p.fmt.minus = true
1093 p.fmt.zero = false
1094 }
1095 afterIndex = false
1096 } else {
1097 p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end)
1098 if afterIndex && p.fmt.widPresent {
1099 p.goodArgNum = false
1100 }
1101 }
1102
1103
1104 if i+1 < end && format[i] == '.' {
1105 i++
1106 if afterIndex {
1107 p.goodArgNum = false
1108 }
1109 argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
1110 if i < end && format[i] == '*' {
1111 i++
1112 p.fmt.prec, p.fmt.precPresent, argNum = intFromArg(a, argNum)
1113
1114 if p.fmt.prec < 0 {
1115 p.fmt.prec = 0
1116 p.fmt.precPresent = false
1117 }
1118 if !p.fmt.precPresent {
1119 p.buf.writeString(badPrecString)
1120 }
1121 afterIndex = false
1122 } else {
1123 p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i, end)
1124 if !p.fmt.precPresent {
1125 p.fmt.prec = 0
1126 p.fmt.precPresent = true
1127 }
1128 }
1129 }
1130
1131 if !afterIndex {
1132 argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
1133 }
1134
1135 if i >= end {
1136 p.buf.writeString(noVerbString)
1137 break
1138 }
1139
1140 verb, size := utf8.DecodeRuneInString(format[i:])
1141 i += size
1142
1143 switch {
1144 case verb == '%':
1145 p.buf.writeByte('%')
1146 case !p.goodArgNum:
1147 p.badArgNum(verb)
1148 case argNum >= len(a):
1149 p.missingArg(verb)
1150 case verb == 'w':
1151 p.wrappedErrs = append(p.wrappedErrs, argNum)
1152 fallthrough
1153 case verb == 'v':
1154
1155 p.fmt.sharpV = p.fmt.sharp
1156 p.fmt.sharp = false
1157
1158 p.fmt.plusV = p.fmt.plus
1159 p.fmt.plus = false
1160 fallthrough
1161 default:
1162 p.printArg(a[argNum], verb)
1163 argNum++
1164 }
1165 }
1166
1167
1168
1169
1170 if !p.reordered && argNum < len(a) {
1171 p.fmt.clearflags()
1172 p.buf.writeString(extraString)
1173 for i, arg := range a[argNum:] {
1174 if i > 0 {
1175 p.buf.writeString(commaSpaceString)
1176 }
1177 if arg == nil {
1178 p.buf.writeString(nilAngleString)
1179 } else {
1180 p.buf.writeString(reflect.TypeOf(arg).String())
1181 p.buf.writeByte('=')
1182 p.printArg(arg, 'v')
1183 }
1184 }
1185 p.buf.writeByte(')')
1186 }
1187 }
1188
1189 func (p *pp) doPrint(a []any) {
1190 prevString := false
1191 for argNum, arg := range a {
1192 isString := arg != nil && reflect.TypeOf(arg).Kind() == reflect.String
1193
1194 if argNum > 0 && !isString && !prevString {
1195 p.buf.writeByte(' ')
1196 }
1197 p.printArg(arg, 'v')
1198 prevString = isString
1199 }
1200 }
1201
1202
1203
1204 func (p *pp) doPrintln(a []any) {
1205 for argNum, arg := range a {
1206 if argNum > 0 {
1207 p.buf.writeByte(' ')
1208 }
1209 p.printArg(arg, 'v')
1210 }
1211 p.buf.writeByte('\n')
1212 }
1213
View as plain text