1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
16 // Strings for use with buffer.WriteString.
17 // This is less overhead than using buffer.Write with byte arrays.
19 commaSpaceString
= ", "
20 nilAngleString
= "<nil>"
21 nilParenString
= "(nil)"
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>"
35 // State represents the printer state passed to custom formatters.
36 // It provides access to the io.Writer interface plus information about
37 // the flags and options for the operand's format specifier.
38 type State
interface {
39 // Write is the function to call to emit formatted output to be printed.
40 Write(b
[]byte) (n
int, err error
)
41 // Width returns the value of the width option and whether it has been set.
42 Width() (wid
int, ok
bool)
43 // Precision returns the value of the precision option and whether it has been set.
44 Precision() (prec
int, ok
bool)
46 // Flag reports whether the flag c, a character, has been set.
50 // Formatter is implemented by any value that has a Format method.
51 // The implementation controls how State and rune are interpreted,
52 // and may call Sprint(f) or Fprint(f) etc. to generate its output.
53 type Formatter
interface {
54 Format(f State
, verb rune
)
57 // Stringer is implemented by any value that has a String method,
58 // which defines the ``native'' format for that value.
59 // The String method is used to print values passed as an operand
60 // to any format that accepts a string or to an unformatted printer
62 type Stringer
interface {
66 // GoStringer is implemented by any value that has a GoString method,
67 // which defines the Go syntax for that value.
68 // The GoString method is used to print values passed as an operand
70 type GoStringer
interface {
74 // Use simple []byte instead of bytes.Buffer to avoid large dependency.
77 func (b
*buffer
) write(p
[]byte) {
81 func (b
*buffer
) writeString(s
string) {
85 func (b
*buffer
) writeByte(c
byte) {
89 func (bp
*buffer
) writeRune(r rune
) {
90 if r
< utf8
.RuneSelf
{
91 *bp
= append(*bp
, byte(r
))
97 for n
+utf8
.UTFMax
> cap(b
) {
100 w
:= utf8
.EncodeRune(b
[n
:n
+utf8
.UTFMax
], r
)
104 // pp is used to store a printer's state and is reused with sync.Pool to avoid allocations.
108 // arg holds the current item, as an interface{}.
111 // value is used instead of arg for reflect values.
114 // fmt is used to format basic items such as integers or strings.
117 // reordered records whether the format string used argument reordering.
119 // goodArgNum records whether the most recent reordering directive was valid.
121 // panicking is set by catchPanic to avoid infinite panic, recover, panic, ... recursion.
123 // erroring is set when printing an error string to guard against calling handleMethods.
125 // wrapErrs is set when the format string may contain a %w verb.
127 // wrappedErr records the target of the %w verb.
131 var ppFree
= sync
.Pool
{
132 New
: func() any
{ return new(pp
) },
135 // newPrinter allocates a new pp struct or grabs a cached one.
136 func newPrinter() *pp
{
137 p
:= ppFree
.Get().(*pp
)
145 // free saves used pp structs in ppFree; avoids an allocation per invocation.
146 func (p
*pp
) free() {
147 // Proper usage of a sync.Pool requires each entry to have approximately
148 // the same memory cost. To obtain this property when the stored type
149 // contains a variably-sized buffer, we add a hard limit on the maximum buffer
150 // to place back in the pool.
152 // See https://golang.org/issue/23199
153 if cap(p
.buf
) > 64<<10 {
159 p
.value
= reflect
.Value
{}
164 func (p
*pp
) Width() (wid
int, ok
bool) { return p
.fmt
.wid
, p
.fmt
.widPresent
}
166 func (p
*pp
) Precision() (prec
int, ok
bool) { return p
.fmt
.prec
, p
.fmt
.precPresent
}
168 func (p
*pp
) Flag(b
int) bool {
173 return p
.fmt
.plus || p
.fmt
.plusV
175 return p
.fmt
.sharp || p
.fmt
.sharpV
184 // Implement Write so we can call Fprintf on a pp (through State), for
185 // recursive use in custom verbs.
186 func (p
*pp
) Write(b
[]byte) (ret
int, err error
) {
191 // Implement WriteString so that we can call io.WriteString
192 // on a pp (through state), for efficiency.
193 func (p
*pp
) WriteString(s
string) (ret
int, err error
) {
198 // These routines end in 'f' and take a format string.
200 // Fprintf formats according to a format specifier and writes to w.
201 // It returns the number of bytes written and any write error encountered.
202 func Fprintf(w io
.Writer
, format
string, a
...any
) (n
int, err error
) {
204 p
.doPrintf(format
, a
)
205 n
, err
= w
.Write(p
.buf
)
210 // Printf formats according to a format specifier and writes to standard output.
211 // It returns the number of bytes written and any write error encountered.
212 func Printf(format
string, a
...any
) (n
int, err error
) {
213 return Fprintf(os
.Stdout
, format
, a
...)
216 // Sprintf formats according to a format specifier and returns the resulting string.
217 func Sprintf(format
string, a
...any
) string {
219 p
.doPrintf(format
, a
)
225 // These routines do not take a format string
227 // Fprint formats using the default formats for its operands and writes to w.
228 // Spaces are added between operands when neither is a string.
229 // It returns the number of bytes written and any write error encountered.
230 func Fprint(w io
.Writer
, a
...any
) (n
int, err error
) {
233 n
, err
= w
.Write(p
.buf
)
238 // Print formats using the default formats for its operands and writes to standard output.
239 // Spaces are added between operands when neither is a string.
240 // It returns the number of bytes written and any write error encountered.
241 func Print(a
...any
) (n
int, err error
) {
242 return Fprint(os
.Stdout
, a
...)
245 // Sprint formats using the default formats for its operands and returns the resulting string.
246 // Spaces are added between operands when neither is a string.
247 func Sprint(a
...any
) string {
255 // These routines end in 'ln', do not take a format string,
256 // always add spaces between operands, and add a newline
257 // after the last operand.
259 // Fprintln formats using the default formats for its operands and writes to w.
260 // Spaces are always added between operands and a newline is appended.
261 // It returns the number of bytes written and any write error encountered.
262 func Fprintln(w io
.Writer
, a
...any
) (n
int, err error
) {
265 n
, err
= w
.Write(p
.buf
)
270 // Println formats using the default formats for its operands and writes to standard output.
271 // Spaces are always added between operands and a newline is appended.
272 // It returns the number of bytes written and any write error encountered.
273 func Println(a
...any
) (n
int, err error
) {
274 return Fprintln(os
.Stdout
, a
...)
277 // Sprintln formats using the default formats for its operands and returns the resulting string.
278 // Spaces are always added between operands and a newline is appended.
279 func Sprintln(a
...any
) string {
287 // getField gets the i'th field of the struct value.
288 // If the field is itself is an interface, return a value for
289 // the thing inside the interface, not the interface itself.
290 func getField(v reflect
.Value
, i
int) reflect
.Value
{
292 if val
.Kind() == reflect
.Interface
&& !val
.IsNil() {
298 // tooLarge reports whether the magnitude of the integer is
299 // too large to be used as a formatting width or precision.
300 func tooLarge(x
int) bool {
302 return x
> max || x
< -max
305 // parsenum converts ASCII to integer. num is 0 (and isnum is false) if no number present.
306 func parsenum(s
string, start
, end
int) (num
int, isnum
bool, newi
int) {
310 for newi
= start
; newi
< end
&& '0' <= s
[newi
] && s
[newi
] <= '9'; newi
++ {
312 return 0, false, end
// Overflow; crazy long number most likely.
314 num
= num
*10 + int(s
[newi
]-'0')
320 func (p
*pp
) unknownType(v reflect
.Value
) {
322 p
.buf
.writeString(nilAngleString
)
326 p
.buf
.writeString(v
.Type().String())
330 func (p
*pp
) badVerb(verb rune
) {
332 p
.buf
.writeString(percentBangString
)
333 p
.buf
.writeRune(verb
)
337 p
.buf
.writeString(reflect
.TypeOf(p
.arg
).String())
339 p
.printArg(p
.arg
, 'v')
340 case p
.value
.IsValid():
341 p
.buf
.writeString(p
.value
.Type().String())
343 p
.printValue(p
.value
, 'v', 0)
345 p
.buf
.writeString(nilAngleString
)
351 func (p
*pp
) fmtBool(v
bool, verb rune
) {
360 // fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x or
361 // not, as requested, by temporarily setting the sharp flag.
362 func (p
*pp
) fmt0x64(v
uint64, leading0x
bool) {
364 p
.fmt
.sharp
= leading0x
365 p
.fmt
.fmtInteger(v
, 16, unsigned
, 'v', ldigits
)
369 // fmtInteger formats a signed or unsigned integer.
370 func (p
*pp
) fmtInteger(v
uint64, isSigned
bool, verb rune
) {
373 if p
.fmt
.sharpV
&& !isSigned
{
376 p
.fmt
.fmtInteger(v
, 10, isSigned
, verb
, ldigits
)
379 p
.fmt
.fmtInteger(v
, 10, isSigned
, verb
, ldigits
)
381 p
.fmt
.fmtInteger(v
, 2, isSigned
, verb
, ldigits
)
383 p
.fmt
.fmtInteger(v
, 8, isSigned
, verb
, ldigits
)
385 p
.fmt
.fmtInteger(v
, 16, isSigned
, verb
, ldigits
)
387 p
.fmt
.fmtInteger(v
, 16, isSigned
, verb
, udigits
)
399 // fmtFloat formats a float. The default precision for each verb
400 // is specified as last argument in the call to fmt_float.
401 func (p
*pp
) fmtFloat(v
float64, size
int, verb rune
) {
404 p
.fmt
.fmtFloat(v
, size
, 'g', -1)
405 case 'b', 'g', 'G', 'x', 'X':
406 p
.fmt
.fmtFloat(v
, size
, verb
, -1)
408 p
.fmt
.fmtFloat(v
, size
, verb
, 6)
410 p
.fmt
.fmtFloat(v
, size
, 'f', 6)
416 // fmtComplex formats a complex number v with
417 // r = real(v) and j = imag(v) as (r+ji) using
418 // fmtFloat for r and j formatting.
419 func (p
*pp
) fmtComplex(v complex128
, size
int, verb rune
) {
420 // Make sure any unsupported verbs are found before the
421 // calls to fmtFloat to not generate an incorrect error string.
423 case 'v', 'b', 'g', 'G', 'x', 'X', 'f', 'F', 'e', 'E':
424 oldPlus
:= p
.fmt
.plus
426 p
.fmtFloat(real(v
), size
/2, verb
)
427 // Imaginary part always has a sign.
429 p
.fmtFloat(imag(v
), size
/2, verb
)
430 p
.buf
.writeString("i)")
437 func (p
*pp
) fmtString(v
string, verb rune
) {
448 p
.fmt
.fmtSx(v
, ldigits
)
450 p
.fmt
.fmtSx(v
, udigits
)
458 func (p
*pp
) fmtBytes(v
[]byte, verb rune
, typeString
string) {
462 p
.buf
.writeString(typeString
)
464 p
.buf
.writeString(nilParenString
)
468 for i
, c
:= range v
{
470 p
.buf
.writeString(commaSpaceString
)
472 p
.fmt0x64(uint64(c
), true)
477 for i
, c
:= range v
{
481 p
.fmt
.fmtInteger(uint64(c
), 10, unsigned
, verb
, ldigits
)
488 p
.fmt
.fmtBx(v
, ldigits
)
490 p
.fmt
.fmtBx(v
, udigits
)
492 p
.fmt
.fmtQ(string(v
))
494 p
.printValue(reflect
.ValueOf(v
), verb
, 0)
498 func (p
*pp
) fmtPointer(value reflect
.Value
, verb rune
) {
500 switch value
.Kind() {
501 case reflect
.Chan
, reflect
.Func
, reflect
.Map
, reflect
.Pointer
, reflect
.Slice
, reflect
.UnsafePointer
:
512 p
.buf
.writeString(value
.Type().String())
513 p
.buf
.writeString(")(")
515 p
.buf
.writeString(nilString
)
517 p
.fmt0x64(uint64(u
), true)
522 p
.fmt
.padString(nilAngleString
)
524 p
.fmt0x64(uint64(u
), !p
.fmt
.sharp
)
528 p
.fmt0x64(uint64(u
), !p
.fmt
.sharp
)
529 case 'b', 'o', 'd', 'x', 'X':
530 p
.fmtInteger(uint64(u
), unsigned
, verb
)
536 func (p
*pp
) catchPanic(arg any
, verb rune
, method
string) {
537 if err
:= recover(); err
!= nil {
538 // If it's a nil pointer, just say "<nil>". The likeliest causes are a
539 // Stringer that fails to guard against nil or a nil pointer for a
540 // value receiver, and in either case, "<nil>" is a nice result.
541 if v
:= reflect
.ValueOf(arg
); v
.Kind() == reflect
.Pointer
&& v
.IsNil() {
542 p
.buf
.writeString(nilAngleString
)
545 // Otherwise print a concise panic message. Most of the time the panic
546 // value will print itself nicely.
548 // Nested panics; the recursion in printArg cannot succeed.
552 oldFlags
:= p
.fmt
.fmtFlags
553 // For this output we want default behavior.
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: ")
566 p
.fmt
.fmtFlags
= oldFlags
570 func (p
*pp
) handleMethods(verb rune
) (handled
bool) {
575 // It is invalid to use %w other than with Errorf, more than once,
576 // or with a non-error arg.
577 err
, ok
:= p
.arg
.(error
)
578 if !ok ||
!p
.wrapErrs || p
.wrappedErr
!= nil {
585 // If the arg is a Formatter, pass 'v' as the verb to it.
589 // Is it a Formatter?
590 if formatter
, ok
:= p
.arg
.(Formatter
); ok
{
592 defer p
.catchPanic(p
.arg
, verb
, "Format")
593 formatter
.Format(p
, verb
)
597 // If we're doing Go syntax and the argument knows how to supply it, take care of it now.
599 if stringer
, ok
:= p
.arg
.(GoStringer
); ok
{
601 defer p
.catchPanic(p
.arg
, verb
, "GoString")
602 // Print the result of GoString unadorned.
603 p
.fmt
.fmtS(stringer
.GoString())
607 // If a string is acceptable according to the format, see if
608 // the value satisfies one of the string-valued interfaces.
609 // Println etc. set verb to %v, which is "stringable".
611 case 'v', 's', 'x', 'X', 'q':
612 // Is it an error or Stringer?
613 // The duplication in the bodies is necessary:
614 // setting handled and deferring catchPanic
615 // must happen before calling the method.
616 switch v
:= p
.arg
.(type) {
619 defer p
.catchPanic(p
.arg
, verb
, "Error")
620 p
.fmtString(v
.Error(), verb
)
625 defer p
.catchPanic(p
.arg
, verb
, "String")
626 p
.fmtString(v
.String(), verb
)
634 func (p
*pp
) printArg(arg any
, verb rune
) {
636 p
.value
= reflect
.Value
{}
641 p
.fmt
.padString(nilAngleString
)
648 // Special processing considerations.
649 // %T (the value's type) and %p (its address) are special; we always do them first.
652 p
.fmt
.fmtS(reflect
.TypeOf(arg
).String())
655 p
.fmtPointer(reflect
.ValueOf(arg
), 'p')
659 // Some types can be done without reflection.
660 switch f
:= arg
.(type) {
664 p
.fmtFloat(float64(f
), 32, verb
)
666 p
.fmtFloat(f
, 64, verb
)
668 p
.fmtComplex(complex128(f
), 64, verb
)
670 p
.fmtComplex(f
, 128, verb
)
672 p
.fmtInteger(uint64(f
), signed
, verb
)
674 p
.fmtInteger(uint64(f
), signed
, verb
)
676 p
.fmtInteger(uint64(f
), signed
, verb
)
678 p
.fmtInteger(uint64(f
), signed
, verb
)
680 p
.fmtInteger(uint64(f
), signed
, verb
)
682 p
.fmtInteger(uint64(f
), unsigned
, verb
)
684 p
.fmtInteger(uint64(f
), unsigned
, verb
)
686 p
.fmtInteger(uint64(f
), unsigned
, verb
)
688 p
.fmtInteger(uint64(f
), unsigned
, verb
)
690 p
.fmtInteger(f
, unsigned
, verb
)
692 p
.fmtInteger(uint64(f
), unsigned
, verb
)
696 p
.fmtBytes(f
, verb
, "[]byte")
698 // Handle extractable values with special methods
699 // since printValue does not handle them at depth 0.
700 if f
.IsValid() && f
.CanInterface() {
701 p
.arg
= f
.Interface()
702 if p
.handleMethods(verb
) {
706 p
.printValue(f
, verb
, 0)
708 // If the type is not simple, it might have methods.
709 if !p
.handleMethods(verb
) {
710 // Need to use reflection, since the type had no
711 // interface methods that could be used for formatting.
712 p
.printValue(reflect
.ValueOf(f
), verb
, 0)
717 // printValue is similar to printArg but starts with a reflect value, not an interface{} value.
718 // It does not handle 'p' and 'T' verbs because these should have been already handled by printArg.
719 func (p
*pp
) printValue(value reflect
.Value
, verb rune
, depth
int) {
720 // Handle values with special methods if not already handled by printArg (depth == 0).
721 if depth
> 0 && value
.IsValid() && value
.CanInterface() {
722 p
.arg
= value
.Interface()
723 if p
.handleMethods(verb
) {
730 switch f
:= value
; value
.Kind() {
731 case reflect
.Invalid
:
733 p
.buf
.writeString(invReflectString
)
737 p
.buf
.writeString(nilAngleString
)
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
)
757 p
.fmtString(f
.String(), verb
)
760 p
.buf
.writeString(f
.Type().String())
762 p
.buf
.writeString(nilParenString
)
767 p
.buf
.writeString(mapString
)
769 sorted
:= fmtsort
.Sort(f
)
770 for i
, key
:= range sorted
.Key
{
773 p
.buf
.writeString(commaSpaceString
)
778 p
.printValue(key
, verb
, depth
+1)
780 p
.printValue(sorted
.Value
[i
], verb
, depth
+1)
789 p
.buf
.writeString(f
.Type().String())
792 for i
:= 0; i
< f
.NumField(); i
++ {
795 p
.buf
.writeString(commaSpaceString
)
800 if p
.fmt
.plusV || p
.fmt
.sharpV
{
801 if name
:= f
.Type().Field(i
).Name
; name
!= "" {
802 p
.buf
.writeString(name
)
806 p
.printValue(getField(f
, i
), verb
, depth
+1)
809 case reflect
.Interface
:
811 if !value
.IsValid() {
813 p
.buf
.writeString(f
.Type().String())
814 p
.buf
.writeString(nilParenString
)
816 p
.buf
.writeString(nilAngleString
)
819 p
.printValue(value
, verb
, depth
+1)
821 case reflect
.Array
, reflect
.Slice
:
823 case 's', 'q', 'x', 'X':
824 // Handle byte and uint8 slices and arrays special for the above verbs.
826 if t
.Elem().Kind() == reflect
.Uint8
{
828 if f
.Kind() == reflect
.Slice
{
830 } else if f
.CanAddr() {
831 bytes
= f
.Slice(0, f
.Len()).Bytes()
833 // We have an array, but we cannot Slice() a non-addressable array,
834 // so we build a slice by hand. This is a rare case but it would be nice
835 // if reflection could help a little more.
836 bytes
= make([]byte, f
.Len())
837 for i
:= range bytes
{
838 bytes
[i
] = byte(f
.Index(i
).Uint())
841 p
.fmtBytes(bytes
, verb
, t
.String())
846 p
.buf
.writeString(f
.Type().String())
847 if f
.Kind() == reflect
.Slice
&& f
.IsNil() {
848 p
.buf
.writeString(nilParenString
)
852 for i
:= 0; i
< f
.Len(); i
++ {
854 p
.buf
.writeString(commaSpaceString
)
856 p
.printValue(f
.Index(i
), verb
, depth
+1)
861 for i
:= 0; i
< f
.Len(); i
++ {
865 p
.printValue(f
.Index(i
), verb
, depth
+1)
869 case reflect
.Pointer
:
870 // pointer to array or slice or struct? ok at top level
871 // but not embedded (avoid loops)
872 if depth
== 0 && f
.Pointer() != 0 {
873 switch a
:= f
.Elem(); a
.Kind() {
874 case reflect
.Array
, reflect
.Slice
, reflect
.Struct
, reflect
.Map
:
876 p
.printValue(a
, verb
, depth
+1)
881 case reflect
.Chan
, reflect
.Func
, reflect
.UnsafePointer
:
882 p
.fmtPointer(f
, verb
)
888 // intFromArg gets the argNumth element of a. On return, isInt reports whether the argument has integer type.
889 func intFromArg(a
[]any
, argNum
int) (num
int, isInt
bool, newArgNum
int) {
892 num
, isInt
= a
[argNum
].(int) // Almost always OK.
895 switch v
:= reflect
.ValueOf(a
[argNum
]); v
.Kind() {
896 case reflect
.Int
, reflect
.Int8
, reflect
.Int16
, reflect
.Int32
, reflect
.Int64
:
898 if int64(int(n
)) == n
{
902 case reflect
.Uint
, reflect
.Uint8
, reflect
.Uint16
, reflect
.Uint32
, reflect
.Uint64
, reflect
.Uintptr
:
904 if int64(n
) >= 0 && uint64(int(n
)) == n
{
912 newArgNum
= argNum
+ 1
921 // parseArgNumber returns the value of the bracketed number, minus 1
922 // (explicit argument numbers are one-indexed but we want zero-indexed).
923 // The opening bracket is known to be present at format[0].
924 // The returned values are the index, the number of bytes to consume
925 // up to the closing paren, if present, and whether the number parsed
926 // ok. The bytes to consume will be 1 if no closing paren is present.
927 func parseArgNumber(format
string) (index
int, wid
int, ok
bool) {
928 // There must be at least 3 bytes: [n].
933 // Find closing bracket.
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
940 return width
- 1, i
+ 1, true // arg numbers are one-indexed and skip paren.
946 // argNumber returns the next argument to evaluate, which is either the value of the passed-in
947 // argNum or the value of the bracketed integer that begins format[i:]. It also returns
948 // the new value of i, that is, the index of the next byte of the format to process.
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
954 index
, wid
, ok
:= parseArgNumber(format
[i
:])
955 if ok
&& 0 <= index
&& index
< numArgs
{
956 return index
, i
+ wid
, true
959 return argNum
, i
+ wid
, ok
962 func (p
*pp
) badArgNum(verb rune
) {
963 p
.buf
.writeString(percentBangString
)
964 p
.buf
.writeRune(verb
)
965 p
.buf
.writeString(badIndexString
)
968 func (p
*pp
) missingArg(verb rune
) {
969 p
.buf
.writeString(percentBangString
)
970 p
.buf
.writeRune(verb
)
971 p
.buf
.writeString(missingString
)
974 func (p
*pp
) doPrintf(format
string, a
[]any
) {
976 argNum
:= 0 // we process one argument per non-trivial format
977 afterIndex
:= false // previous item in format was an index like [3].
980 for i
:= 0; i
< end
; {
983 for i
< end
&& format
[i
] != '%' {
987 p
.buf
.writeString(format
[lasti
:i
])
990 // done processing format string
1000 for ; i
< end
; i
++ {
1006 p
.fmt
.zero
= !p
.fmt
.minus
// Only allow zero padding to the left.
1011 p
.fmt
.zero
= false // Do not pad with zeros to the right.
1015 // Fast path for common case of ascii lower case simple verbs
1016 // without precision or width or argument indices.
1017 if 'a' <= c
&& c
<= 'z' && argNum
< len(a
) {
1020 p
.fmt
.sharpV
= p
.fmt
.sharp
1022 // Struct-field syntax
1023 p
.fmt
.plusV
= p
.fmt
.plus
1026 p
.printArg(a
[argNum
], rune(c
))
1031 // Format is more complex than simple flags and a verb or is malformed.
1036 // Do we have an explicit argument index?
1037 argNum
, i
, afterIndex
= p
.argNumber(argNum
, format
, i
, len(a
))
1039 // Do we have width?
1040 if i
< end
&& format
[i
] == '*' {
1042 p
.fmt
.wid
, p
.fmt
.widPresent
, argNum
= intFromArg(a
, argNum
)
1044 if !p
.fmt
.widPresent
{
1045 p
.buf
.writeString(badWidthString
)
1048 // We have a negative width, so take its value and ensure
1049 // that the minus flag is set
1051 p
.fmt
.wid
= -p
.fmt
.wid
1053 p
.fmt
.zero
= false // Do not pad with zeros to the right.
1057 p
.fmt
.wid
, p
.fmt
.widPresent
, i
= parsenum(format
, i
, end
)
1058 if afterIndex
&& p
.fmt
.widPresent
{ // "%[3]2d"
1059 p
.goodArgNum
= false
1063 // Do we have precision?
1064 if i
+1 < end
&& format
[i
] == '.' {
1066 if afterIndex
{ // "%[3].2d"
1067 p
.goodArgNum
= false
1069 argNum
, i
, afterIndex
= p
.argNumber(argNum
, format
, i
, len(a
))
1070 if i
< end
&& format
[i
] == '*' {
1072 p
.fmt
.prec
, p
.fmt
.precPresent
, argNum
= intFromArg(a
, argNum
)
1073 // Negative precision arguments don't make sense
1076 p
.fmt
.precPresent
= false
1078 if !p
.fmt
.precPresent
{
1079 p
.buf
.writeString(badPrecString
)
1083 p
.fmt
.prec
, p
.fmt
.precPresent
, i
= parsenum(format
, i
, end
)
1084 if !p
.fmt
.precPresent
{
1086 p
.fmt
.precPresent
= true
1092 argNum
, i
, afterIndex
= p
.argNumber(argNum
, format
, i
, len(a
))
1096 p
.buf
.writeString(noVerbString
)
1100 verb
, size
:= rune(format
[i
]), 1
1101 if verb
>= utf8
.RuneSelf
{
1102 verb
, size
= utf8
.DecodeRuneInString(format
[i
:])
1107 case verb
== '%': // Percent does not absorb operands and ignores f.wid and f.prec.
1108 p
.buf
.writeByte('%')
1111 case argNum
>= len(a
): // No argument left over to print for the current verb.
1115 p
.fmt
.sharpV
= p
.fmt
.sharp
1117 // Struct-field syntax
1118 p
.fmt
.plusV
= p
.fmt
.plus
1122 p
.printArg(a
[argNum
], verb
)
1127 // Check for extra arguments unless the call accessed the arguments
1128 // out of order, in which case it's too expensive to detect if they've all
1129 // been used and arguably OK if they're not.
1130 if !p
.reordered
&& argNum
< len(a
) {
1132 p
.buf
.writeString(extraString
)
1133 for i
, arg
:= range a
[argNum
:] {
1135 p
.buf
.writeString(commaSpaceString
)
1138 p
.buf
.writeString(nilAngleString
)
1140 p
.buf
.writeString(reflect
.TypeOf(arg
).String())
1141 p
.buf
.writeByte('=')
1142 p
.printArg(arg
, 'v')
1145 p
.buf
.writeByte(')')
1149 func (p
*pp
) doPrint(a
[]any
) {
1151 for argNum
, arg
:= range a
{
1152 isString
:= arg
!= nil && reflect
.TypeOf(arg
).Kind() == reflect
.String
1153 // Add a space between two non-string arguments.
1154 if argNum
> 0 && !isString
&& !prevString
{
1155 p
.buf
.writeByte(' ')
1157 p
.printArg(arg
, 'v')
1158 prevString
= isString
1162 // doPrintln is like doPrint but always adds a space between arguments
1163 // and a newline after the last argument.
1164 func (p
*pp
) doPrintln(a
[]any
) {
1165 for argNum
, arg
:= range a
{
1167 p
.buf
.writeByte(' ')
1169 p
.printArg(arg
, 'v')
1171 p
.buf
.writeByte('\n')