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