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