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 (bp *buffer) writeRune(r rune) {
116 *bp = utf8.AppendRune(*bp, 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 = value.Pointer()
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, key := range sorted.Key {
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(key, verb, depth+1)
826 p.buf.writeByte(':')
827 p.printValue(sorted.Value[i], 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 {
876 bytes = f.Bytes()
877 } else if f.CanAddr() {
878 bytes = f.Slice(0, f.Len()).Bytes()
879 } else {
880
881
882
883 bytes = make([]byte, f.Len())
884 for i := range bytes {
885 bytes[i] = byte(f.Index(i).Uint())
886 }
887 }
888 p.fmtBytes(bytes, verb, t.String())
889 return
890 }
891 }
892 if p.fmt.sharpV {
893 p.buf.writeString(f.Type().String())
894 if f.Kind() == reflect.Slice && f.IsNil() {
895 p.buf.writeString(nilParenString)
896 return
897 }
898 p.buf.writeByte('{')
899 for i := 0; i < f.Len(); i++ {
900 if i > 0 {
901 p.buf.writeString(commaSpaceString)
902 }
903 p.printValue(f.Index(i), verb, depth+1)
904 }
905 p.buf.writeByte('}')
906 } else {
907 p.buf.writeByte('[')
908 for i := 0; i < f.Len(); i++ {
909 if i > 0 {
910 p.buf.writeByte(' ')
911 }
912 p.printValue(f.Index(i), verb, depth+1)
913 }
914 p.buf.writeByte(']')
915 }
916 case reflect.Pointer:
917
918
919 if depth == 0 && f.Pointer() != 0 {
920 switch a := f.Elem(); a.Kind() {
921 case reflect.Array, reflect.Slice, reflect.Struct, reflect.Map:
922 p.buf.writeByte('&')
923 p.printValue(a, verb, depth+1)
924 return
925 }
926 }
927 fallthrough
928 case reflect.Chan, reflect.Func, reflect.UnsafePointer:
929 p.fmtPointer(f, verb)
930 default:
931 p.unknownType(f)
932 }
933 }
934
935
936 func intFromArg(a []any, argNum int) (num int, isInt bool, newArgNum int) {
937 newArgNum = argNum
938 if argNum < len(a) {
939 num, isInt = a[argNum].(int)
940 if !isInt {
941
942 switch v := reflect.ValueOf(a[argNum]); v.Kind() {
943 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
944 n := v.Int()
945 if int64(int(n)) == n {
946 num = int(n)
947 isInt = true
948 }
949 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
950 n := v.Uint()
951 if int64(n) >= 0 && uint64(int(n)) == n {
952 num = int(n)
953 isInt = true
954 }
955 default:
956
957 }
958 }
959 newArgNum = argNum + 1
960 if tooLarge(num) {
961 num = 0
962 isInt = false
963 }
964 }
965 return
966 }
967
968
969
970
971
972
973
974 func parseArgNumber(format string) (index int, wid int, ok bool) {
975
976 if len(format) < 3 {
977 return 0, 1, false
978 }
979
980
981 for i := 1; i < len(format); i++ {
982 if format[i] == ']' {
983 width, ok, newi := parsenum(format, 1, i)
984 if !ok || newi != i {
985 return 0, i + 1, false
986 }
987 return width - 1, i + 1, true
988 }
989 }
990 return 0, 1, false
991 }
992
993
994
995
996 func (p *pp) argNumber(argNum int, format string, i int, numArgs int) (newArgNum, newi int, found bool) {
997 if len(format) <= i || format[i] != '[' {
998 return argNum, i, false
999 }
1000 p.reordered = true
1001 index, wid, ok := parseArgNumber(format[i:])
1002 if ok && 0 <= index && index < numArgs {
1003 return index, i + wid, true
1004 }
1005 p.goodArgNum = false
1006 return argNum, i + wid, ok
1007 }
1008
1009 func (p *pp) badArgNum(verb rune) {
1010 p.buf.writeString(percentBangString)
1011 p.buf.writeRune(verb)
1012 p.buf.writeString(badIndexString)
1013 }
1014
1015 func (p *pp) missingArg(verb rune) {
1016 p.buf.writeString(percentBangString)
1017 p.buf.writeRune(verb)
1018 p.buf.writeString(missingString)
1019 }
1020
1021 func (p *pp) doPrintf(format string, a []any) {
1022 end := len(format)
1023 argNum := 0
1024 afterIndex := false
1025 p.reordered = false
1026 formatLoop:
1027 for i := 0; i < end; {
1028 p.goodArgNum = true
1029 lasti := i
1030 for i < end && format[i] != '%' {
1031 i++
1032 }
1033 if i > lasti {
1034 p.buf.writeString(format[lasti:i])
1035 }
1036 if i >= end {
1037
1038 break
1039 }
1040
1041
1042 i++
1043
1044
1045 p.fmt.clearflags()
1046 simpleFormat:
1047 for ; i < end; i++ {
1048 c := format[i]
1049 switch c {
1050 case '#':
1051 p.fmt.sharp = true
1052 case '0':
1053 p.fmt.zero = !p.fmt.minus
1054 case '+':
1055 p.fmt.plus = true
1056 case '-':
1057 p.fmt.minus = true
1058 p.fmt.zero = false
1059 case ' ':
1060 p.fmt.space = true
1061 default:
1062
1063
1064 if 'a' <= c && c <= 'z' && argNum < len(a) {
1065 switch c {
1066 case 'w':
1067 p.wrappedErrs = append(p.wrappedErrs, argNum)
1068 fallthrough
1069 case 'v':
1070
1071 p.fmt.sharpV = p.fmt.sharp
1072 p.fmt.sharp = false
1073
1074 p.fmt.plusV = p.fmt.plus
1075 p.fmt.plus = false
1076 }
1077 p.printArg(a[argNum], rune(c))
1078 argNum++
1079 i++
1080 continue formatLoop
1081 }
1082
1083 break simpleFormat
1084 }
1085 }
1086
1087
1088 argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
1089
1090
1091 if i < end && format[i] == '*' {
1092 i++
1093 p.fmt.wid, p.fmt.widPresent, argNum = intFromArg(a, argNum)
1094
1095 if !p.fmt.widPresent {
1096 p.buf.writeString(badWidthString)
1097 }
1098
1099
1100
1101 if p.fmt.wid < 0 {
1102 p.fmt.wid = -p.fmt.wid
1103 p.fmt.minus = true
1104 p.fmt.zero = false
1105 }
1106 afterIndex = false
1107 } else {
1108 p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end)
1109 if afterIndex && p.fmt.widPresent {
1110 p.goodArgNum = false
1111 }
1112 }
1113
1114
1115 if i+1 < end && format[i] == '.' {
1116 i++
1117 if afterIndex {
1118 p.goodArgNum = false
1119 }
1120 argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
1121 if i < end && format[i] == '*' {
1122 i++
1123 p.fmt.prec, p.fmt.precPresent, argNum = intFromArg(a, argNum)
1124
1125 if p.fmt.prec < 0 {
1126 p.fmt.prec = 0
1127 p.fmt.precPresent = false
1128 }
1129 if !p.fmt.precPresent {
1130 p.buf.writeString(badPrecString)
1131 }
1132 afterIndex = false
1133 } else {
1134 p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i, end)
1135 if !p.fmt.precPresent {
1136 p.fmt.prec = 0
1137 p.fmt.precPresent = true
1138 }
1139 }
1140 }
1141
1142 if !afterIndex {
1143 argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
1144 }
1145
1146 if i >= end {
1147 p.buf.writeString(noVerbString)
1148 break
1149 }
1150
1151 verb, size := rune(format[i]), 1
1152 if verb >= utf8.RuneSelf {
1153 verb, size = utf8.DecodeRuneInString(format[i:])
1154 }
1155 i += size
1156
1157 switch {
1158 case verb == '%':
1159 p.buf.writeByte('%')
1160 case !p.goodArgNum:
1161 p.badArgNum(verb)
1162 case argNum >= len(a):
1163 p.missingArg(verb)
1164 case verb == 'w':
1165 p.wrappedErrs = append(p.wrappedErrs, argNum)
1166 fallthrough
1167 case verb == 'v':
1168
1169 p.fmt.sharpV = p.fmt.sharp
1170 p.fmt.sharp = false
1171
1172 p.fmt.plusV = p.fmt.plus
1173 p.fmt.plus = false
1174 fallthrough
1175 default:
1176 p.printArg(a[argNum], verb)
1177 argNum++
1178 }
1179 }
1180
1181
1182
1183
1184 if !p.reordered && argNum < len(a) {
1185 p.fmt.clearflags()
1186 p.buf.writeString(extraString)
1187 for i, arg := range a[argNum:] {
1188 if i > 0 {
1189 p.buf.writeString(commaSpaceString)
1190 }
1191 if arg == nil {
1192 p.buf.writeString(nilAngleString)
1193 } else {
1194 p.buf.writeString(reflect.TypeOf(arg).String())
1195 p.buf.writeByte('=')
1196 p.printArg(arg, 'v')
1197 }
1198 }
1199 p.buf.writeByte(')')
1200 }
1201 }
1202
1203 func (p *pp) doPrint(a []any) {
1204 prevString := false
1205 for argNum, arg := range a {
1206 isString := arg != nil && reflect.TypeOf(arg).Kind() == reflect.String
1207
1208 if argNum > 0 && !isString && !prevString {
1209 p.buf.writeByte(' ')
1210 }
1211 p.printArg(arg, 'v')
1212 prevString = isString
1213 }
1214 }
1215
1216
1217
1218 func (p *pp) doPrintln(a []any) {
1219 for argNum, arg := range a {
1220 if argNum > 0 {
1221 p.buf.writeByte(' ')
1222 }
1223 p.printArg(arg, 'v')
1224 }
1225 p.buf.writeByte('\n')
1226 }
1227
View as plain text