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