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.
4 5 package fmt
6 7 import (
8 "io"
9 "os"
10 "strconv"
11 "sync"
12 "unicode/utf8"
13 )
14 15 // Strings for use with buffer.WriteString.
16 // This is less overhead than using buffer.Write with byte arrays.
17 const (
18 commaSpaceString = ", "
19 nilAngleString = "<nil>"
20 nilParenString = "(nil)"
21 nilString = "nil"
22 mapString = "map["
23 percentBangString = "%!"
24 missingString = "(MISSING)"
25 badIndexString = "(BADINDEX)"
26 panicString = "(PANIC="
27 extraString = "%!(EXTRA "
28 badWidthString = "%!(BADWIDTH)"
29 badPrecString = "%!(BADPREC)"
30 noVerbString = "%!(NOVERB)"
31 )
32 33 // State represents the printer state passed to custom formatters.
34 // It provides access to the [io.Writer] interface plus information about
35 // the flags and options for the operand's format specifier.
36 type State interface {
37 // Write is the function to call to emit formatted output to be printed.
38 Write(b []byte) (n int, err error)
39 // Width returns the value of the width option and whether it has been set.
40 Width() (wid int, ok bool)
41 // Precision returns the value of the precision option and whether it has been set.
42 Precision() (prec int, ok bool)
43 44 // Flag reports whether the flag c, a character, has been set.
45 Flag(c int) bool
46 }
47 48 // Formatter is implemented by any value that has a Format method.
49 // The implementation controls how [State] and rune are interpreted,
50 // and may call [Sprint] or [Fprint](f) etc. to generate its output.
51 type Formatter interface {
52 Format(f State, verb rune)
53 }
54 55 // Stringer is implemented by any value that has a String method,
56 // which defines the “native” format for that value.
57 // The String method is used to print values passed as an operand
58 // to any format that accepts a string or to an unformatted printer
59 // such as [Print].
60 type Stringer interface {
61 String() string
62 }
63 64 // GoStringer is implemented by any value that has a GoString method,
65 // which defines the Go syntax for that value.
66 // The GoString method is used to print values passed as an operand
67 // to a %#v format.
68 type GoStringer interface {
69 GoString() string
70 }
71 72 // FormatString returns a string representing the fully qualified formatting
73 // directive captured by the [State], followed by the argument verb. ([State] does not
74 // itself contain the verb.) The result has a leading percent sign followed by any
75 // flags, the width, and the precision. Missing flags, width, and precision are
76 // omitted. This function allows a [Formatter] to reconstruct the original
77 // directive triggering the call to Format.
78 func FormatString(state State, verb rune) []byte {
79 var tmp [16]byte // Use a local buffer.
80 b := append(tmp[:0], '%')
81 for _, c := range " +-#0" { // All known flags
82 if state.Flag(int(c)) { // The argument is an int for historical reasons.
83 b = append(b, byte(c))
84 }
85 }
86 if w, ok := state.Width(); ok {
87 b = strconv.AppendInt(b, int64(w), 10)
88 }
89 if p, ok := state.Precision(); ok {
90 b = append(b, '.')
91 b = strconv.AppendInt(b, int64(p), 10)
92 }
93 b = utf8.AppendRune(b, verb)
94 return []byte(b)
95 }
96 97 // Use simple []byte instead of bytes.Buffer to avoid large dependency.
98 type buffer []byte
99 100 func (b *buffer) write(p []byte) {
101 *b = append(*b, p...)
102 }
103 104 func (b *buffer) writeString(s []byte) {
105 *b = append(*b, s...)
106 }
107 108 func (b *buffer) writeByte(c byte) {
109 *b = append(*b, c)
110 }
111 112 func (b *buffer) writeRune(r rune) {
113 *b = utf8.AppendRune(*b, r)
114 }
115 116 // pp is used to store a printer's state and is reused with sync.Pool to avoid allocations.
117 type pp struct {
118 buf buffer
119 120 // arg holds the current item, as an interface{}.
121 arg any
122 123 // fmt is used to format basic items such as integers or strings.
124 fmt fmt
125 126 // reordered records whether the format string used argument reordering.
127 reordered bool
128 // goodArgNum records whether the most recent reordering directive was valid.
129 goodArgNum bool
130 // panicking is set by catchPanic to avoid infinite panic, recover, panic, ... recursion.
131 panicking bool
132 // erroring is set when printing an error string to guard against calling handleMethods.
133 erroring bool
134 // wrapErrs is set when the format string may contain a %w verb.
135 wrapErrs bool
136 // wrappedErrs records the targets of the %w verb.
137 wrappedErrs []int
138 }
139 140 var ppFree = sync.Pool{
141 New: func() any { return &pp{} },
142 }
143 144 // newPrinter allocates a new pp struct or grabs a cached one.
145 func newPrinter() *pp {
146 p := ppFree.Get().(*pp)
147 p.panicking = false
148 p.erroring = false
149 p.wrapErrs = false
150 p.fmt.init(&p.buf)
151 return p
152 }
153 154 // free saves used pp structs in ppFree; avoids an allocation per invocation.
155 func (p *pp) free() {
156 // Proper usage of a sync.Pool requires each entry to have approximately
157 // the same memory cost. To obtain this property when the stored type
158 // contains a variably-sized buffer, we add a hard limit on the maximum
159 // buffer to place back in the pool. If the buffer is larger than the
160 // limit, we drop the buffer and recycle just the printer.
161 //
162 // See https://golang.org/issue/23199.
163 if cap(p.buf) > 64*1024 {
164 p.buf = nil
165 } else {
166 // Zero the backing array before reuse. With string=[]byte,
167 // callers may still hold slices pointing at this memory.
168 // Zeroing makes stale reads return empty bytes rather than
169 // silently aliasing new content.
170 b := p.buf[:cap(p.buf)]
171 for i := range b {
172 b[i] = 0
173 }
174 p.buf = p.buf[:0]
175 }
176 if cap(p.wrappedErrs) > 8 {
177 p.wrappedErrs = nil
178 }
179 180 p.arg = nil
181 p.wrappedErrs = p.wrappedErrs[:0]
182 ppFree.Put(p)
183 }
184 185 func (p *pp) Width() (wid int, ok bool) { return p.fmt.wid, p.fmt.widPresent }
186 187 func (p *pp) Precision() (prec int, ok bool) { return p.fmt.prec, p.fmt.precPresent }
188 189 func (p *pp) Flag(b int) bool {
190 switch b {
191 case '-':
192 return p.fmt.minus
193 case '+':
194 return p.fmt.plus || p.fmt.plusV
195 case '#':
196 return p.fmt.sharp || p.fmt.sharpV
197 case ' ':
198 return p.fmt.space
199 case '0':
200 return p.fmt.zero
201 }
202 return false
203 }
204 205 // Write implements [io.Writer] so we can call [Fprintf] on a pp (through [State]), for
206 // recursive use in custom verbs.
207 func (p *pp) Write(b []byte) (ret int, err error) {
208 p.buf.write(b)
209 return len(b), nil
210 }
211 212 // WriteString implements [io.StringWriter] so that we can call [io.WriteString]
213 // on a pp (through state), for efficiency.
214 func (p *pp) WriteString(s []byte) (ret int, err error) {
215 p.buf.writeString(s)
216 return len(s), nil
217 }
218 219 // These routines end in 'f' and take a format string.
220 221 // Fprintf formats according to a format specifier and writes to w.
222 // It returns the number of bytes written and any write error encountered.
223 func Fprintf(w io.Writer, format []byte, a ...any) (n int, err error) {
224 p := newPrinter()
225 p.doPrintf(format, a)
226 n, err = w.Write(p.buf)
227 p.free()
228 return
229 }
230 231 // Printf formats according to a format specifier and writes to standard output.
232 // It returns the number of bytes written and any write error encountered.
233 func Printf(format []byte, a ...any) (n int, err error) {
234 return Fprintf(os.Stdout, format, a...)
235 }
236 237 // Sprintf formats according to a format specifier and returns the resulting string.
238 func Sprintf(format []byte, a ...any) []byte {
239 p := newPrinter()
240 p.doPrintf(format, a)
241 s := copyBuf(p.buf)
242 p.free()
243 return s
244 }
245 246 // Appendf formats according to a format specifier, appends the result to the byte
247 // slice, and returns the updated slice.
248 func Appendf(b []byte, format []byte, a ...any) []byte {
249 p := newPrinter()
250 p.doPrintf(format, a)
251 b = append(b, p.buf...)
252 p.free()
253 return b
254 }
255 256 // These routines do not take a format string
257 258 // Fprint formats using the default formats for its operands and writes to w.
259 // Spaces are added between operands when neither is a string.
260 // It returns the number of bytes written and any write error encountered.
261 func Fprint(w io.Writer, a ...any) (n int, err error) {
262 p := newPrinter()
263 p.doPrint(a)
264 n, err = w.Write(p.buf)
265 p.free()
266 return
267 }
268 269 // Print formats using the default formats for its operands and writes to standard output.
270 // Spaces are added between operands when neither is a string.
271 // It returns the number of bytes written and any write error encountered.
272 func Print(a ...any) (n int, err error) {
273 return Fprint(os.Stdout, a...)
274 }
275 276 // Sprint formats using the default formats for its operands and returns the resulting string.
277 // Spaces are added between operands when neither is a string.
278 func Sprint(a ...any) []byte {
279 p := newPrinter()
280 p.doPrint(a)
281 s := copyBuf(p.buf)
282 p.free()
283 return s
284 }
285 286 // Append formats using the default formats for its operands, appends the result to
287 // the byte slice, and returns the updated slice.
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 // These routines end in 'ln', do not take a format string,
297 // always add spaces between operands, and add a newline
298 // after the last operand.
299 300 // Fprintln formats using the default formats for its operands and writes to w.
301 // Spaces are always added between operands and a newline is appended.
302 // It returns the number of bytes written and any write error encountered.
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 // Println formats using the default formats for its operands and writes to standard output.
312 // Spaces are always added between operands and a newline is appended.
313 // It returns the number of bytes written and any write error encountered.
314 func Println(a ...any) (n int, err error) {
315 return Fprintln(os.Stdout, a...)
316 }
317 318 // Sprintln formats using the default formats for its operands and returns the resulting string.
319 // Spaces are always added between operands and a newline is appended.
320 func Sprintln(a ...any) []byte {
321 p := newPrinter()
322 p.doPrintln(a)
323 s := copyBuf(p.buf)
324 p.free()
325 return s
326 }
327 328 // copyBuf returns an owned copy of b. With string=[]byte, returning a
329 // slice that shares backing storage with a pooled buffer causes silent
330 // corruption when the pool recycles the buffer.
331 func copyBuf(b []byte) []byte {
332 if len(b) == 0 {
333 return nil
334 }
335 c := make([]byte, len(b))
336 copy(c, b)
337 return c
338 }
339 340 // Appendln formats using the default formats for its operands, appends the result
341 // to the byte slice, and returns the updated slice. Spaces are always added
342 // between operands and a newline is appended.
343 func Appendln(b []byte, a ...any) []byte {
344 p := newPrinter()
345 p.doPrintln(a)
346 b = append(b, p.buf...)
347 p.free()
348 return b
349 }
350 351 // tooLarge reports whether the magnitude of the integer is
352 // too large to be used as a formatting width or precision.
353 func tooLarge(x int) bool {
354 const max int = 1e6
355 return x > max || x < -max
356 }
357 358 // parsenum converts ASCII to integer. num is 0 (and isnum is false) if no number present.
359 func parsenum(s []byte, start, end int) (num int, isnum bool, newi int) {
360 if start >= end {
361 return 0, false, end
362 }
363 for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ {
364 if tooLarge(num) {
365 return 0, false, end // Overflow; crazy long number most likely.
366 }
367 num = num*10 + int(s[newi]-'0')
368 isnum = true
369 }
370 return
371 }
372 373 func (p *pp) unknownType(v any) {
374 p.buf.writeByte('?')
375 }
376 377 func (p *pp) badVerb(verb rune) {
378 p.erroring = true
379 p.buf.writeString(percentBangString)
380 p.buf.writeRune(verb)
381 p.buf.writeByte('(')
382 switch {
383 case p.arg != nil:
384 p.buf.writeString("?")
385 p.buf.writeByte('=')
386 p.printArg(p.arg, 'v')
387 default:
388 p.buf.writeString(nilAngleString)
389 }
390 p.buf.writeByte(')')
391 p.erroring = false
392 }
393 394 func (p *pp) fmtBool(v bool, verb rune) {
395 switch verb {
396 case 't', 'v':
397 p.fmt.fmtBoolean(v)
398 default:
399 p.badVerb(verb)
400 }
401 }
402 403 // fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x or
404 // not, as requested, by temporarily setting the sharp flag.
405 func (p *pp) fmt0x64(v uint64, leading0x bool) {
406 sharp := p.fmt.sharp
407 p.fmt.sharp = leading0x
408 p.fmt.fmtInteger(v, 16, unsigned, 'v', ldigits)
409 p.fmt.sharp = sharp
410 }
411 412 // fmtInteger formats a signed or unsigned integer.
413 func (p *pp) fmtInteger(v uint64, isSigned bool, verb rune) {
414 switch verb {
415 case 'v':
416 if p.fmt.sharpV && !isSigned {
417 p.fmt0x64(v, true)
418 } else {
419 p.fmt.fmtInteger(v, 10, isSigned, verb, ldigits)
420 }
421 case 'd':
422 p.fmt.fmtInteger(v, 10, isSigned, verb, ldigits)
423 case 'b':
424 p.fmt.fmtInteger(v, 2, isSigned, verb, ldigits)
425 case 'o', 'O':
426 p.fmt.fmtInteger(v, 8, isSigned, verb, ldigits)
427 case 'x':
428 p.fmt.fmtInteger(v, 16, isSigned, verb, ldigits)
429 case 'X':
430 p.fmt.fmtInteger(v, 16, isSigned, verb, udigits)
431 case 'c':
432 p.fmt.fmtC(v)
433 case 'q':
434 p.fmt.fmtQc(v)
435 case 'U':
436 p.fmt.fmtUnicode(v)
437 default:
438 p.badVerb(verb)
439 }
440 }
441 442 // fmtFloat formats a float. The default precision for each verb
443 // is specified as last argument in the call to fmt_float.
444 func (p *pp) fmtFloat(v float64, size int, verb rune) {
445 switch verb {
446 case 'v':
447 p.fmt.fmtFloat(v, size, 'g', -1)
448 case 'b', 'g', 'G', 'x', 'X':
449 p.fmt.fmtFloat(v, size, verb, -1)
450 case 'f', 'e', 'E':
451 p.fmt.fmtFloat(v, size, verb, 6)
452 case 'F':
453 p.fmt.fmtFloat(v, size, 'f', 6)
454 default:
455 p.badVerb(verb)
456 }
457 }
458 459 // fmtComplex formats a complex number v with
460 // r = real(v) and j = imag(v) as (r+ji) using
461 // fmtFloat for r and j formatting.
462 func (p *pp) fmtComplex(re, im float64, size int, verb rune) {
463 panic("moxie: complex numbers not supported")
464 }
465 466 func (p *pp) fmtString(v []byte, verb rune) {
467 switch verb {
468 case 'v':
469 if p.fmt.sharpV {
470 p.fmt.fmtQ(v)
471 } else {
472 p.fmt.fmtS(v)
473 }
474 case 's':
475 p.fmt.fmtS(v)
476 case 'x':
477 p.fmt.fmtSx(v, ldigits)
478 case 'X':
479 p.fmt.fmtSx(v, udigits)
480 case 'q':
481 p.fmt.fmtQ(v)
482 default:
483 p.badVerb(verb)
484 }
485 }
486 487 func (p *pp) fmtBytes(v []byte, verb rune, typeString []byte) {
488 // []byte IS string in moxie. Always print as UTF-8 content.
489 p.fmt.fmtBs(v)
490 }
491 492 func (p *pp) catchPanic(arg any, verb rune, method []byte) {
493 if err := recover(); err != nil {
494 // If it's a nil pointer, just say "<nil>". The likeliest causes are a
495 // Stringer that fails to guard against nil or a nil pointer for a
496 // value receiver, and in either case, "<nil>" is a nice result.
497 if p.arg == nil {
498 p.buf.writeString(nilAngleString)
499 return
500 }
501 // Otherwise print a concise panic message. Most of the time the panic
502 // value will print itself nicely.
503 if p.panicking {
504 // Nested panics; the recursion in printArg cannot succeed.
505 panic(err)
506 }
507 508 oldFlags := p.fmt.fmtFlags
509 // For this output we want default behavior.
510 p.fmt.clearflags()
511 512 p.buf.writeString(percentBangString)
513 p.buf.writeRune(verb)
514 p.buf.writeString(panicString)
515 p.buf.writeString(method)
516 p.buf.writeString(" method: ")
517 p.panicking = true
518 p.printArg(err, 'v')
519 p.panicking = false
520 p.buf.writeByte(')')
521 522 p.fmt.fmtFlags = oldFlags
523 }
524 }
525 526 func (p *pp) handleMethods(verb rune) (handled bool) {
527 if p.erroring {
528 return
529 }
530 if verb == 'w' {
531 // It is invalid to use %w other than with Errorf or with a non-error arg.
532 _, ok := p.arg.(error)
533 if !ok || !p.wrapErrs {
534 p.badVerb(verb)
535 return true
536 }
537 // If the arg is a Formatter, pass 'v' as the verb to it.
538 verb = 'v'
539 }
540 541 // Is it a Formatter?
542 if formatter, ok := p.arg.(Formatter); ok {
543 handled = true
544 defer p.catchPanic(p.arg, verb, "Format")
545 formatter.Format(p, verb)
546 return
547 }
548 549 // If we're doing Go syntax and the argument knows how to supply it, take care of it now.
550 if p.fmt.sharpV {
551 if stringer, ok := p.arg.(GoStringer); ok {
552 handled = true
553 defer p.catchPanic(p.arg, verb, "GoString")
554 // Print the result of GoString unadorned.
555 p.fmt.fmtS(stringer.GoString())
556 return
557 }
558 } else {
559 // If a string is acceptable according to the format, see if
560 // the value satisfies one of the string-valued interfaces.
561 // Println etc. set verb to %v, which is "stringable".
562 switch verb {
563 case 'v', 's', 'x', 'X', 'q':
564 // Is it an error or Stringer?
565 // The duplication in the bodies is necessary:
566 // setting handled and deferring catchPanic
567 // must happen before calling the method.
568 switch v := p.arg.(type) {
569 case error:
570 handled = true
571 defer p.catchPanic(p.arg, verb, "Error")
572 p.fmtString(v.Error(), verb)
573 return
574 575 case Stringer:
576 handled = true
577 defer p.catchPanic(p.arg, verb, "String")
578 p.fmtString(v.String(), verb)
579 return
580 }
581 }
582 }
583 return false
584 }
585 586 func (p *pp) printArg(arg any, verb rune) {
587 p.arg = arg
588 589 if arg == nil {
590 switch verb {
591 case 'T', 'v':
592 p.fmt.padString(nilAngleString)
593 default:
594 p.badVerb(verb)
595 }
596 return
597 }
598 599 // Special processing considerations.
600 // %T (the value's type) and %p (its address) are special; we always do them first.
601 switch verb {
602 case 'T':
603 p.fmt.fmtS("?")
604 return
605 case 'p':
606 p.fmt.fmtS("(pointer)")
607 return
608 }
609 610 // Some types can be done without reflection.
611 switch f := arg.(type) {
612 case bool:
613 p.fmtBool(f, verb)
614 case float32:
615 p.fmtFloat(float64(f), 32, verb)
616 case float64:
617 p.fmtFloat(f, 64, verb)
618 // complex64, complex128 cases removed — not supported in moxie
619 case int:
620 p.fmtInteger(uint64(f), signed, verb)
621 case int8:
622 p.fmtInteger(uint64(f), signed, verb)
623 case int16:
624 p.fmtInteger(uint64(f), signed, verb)
625 case int64:
626 p.fmtInteger(uint64(f), signed, verb)
627 case uint:
628 p.fmtInteger(uint64(f), unsigned, verb)
629 case uint8:
630 p.fmtInteger(uint64(f), unsigned, verb)
631 case uint16:
632 p.fmtInteger(uint64(f), unsigned, verb)
633 case uint64:
634 p.fmtInteger(f, unsigned, verb)
635 case []byte:
636 p.fmtBytes(f, verb, "[]byte")
637 default:
638 // If the type is not simple, it might have methods.
639 if !p.handleMethods(verb) {
640 p.unknownType(f)
641 }
642 }
643 }
644 645 // intFromArg gets the argNumth element of a. On return, isInt reports whether the argument has integer type.
646 func intFromArg(a []any, argNum int) (num int, isInt bool, newArgNum int) {
647 newArgNum = argNum
648 if argNum < len(a) {
649 num, isInt = a[argNum].(int) // Almost always OK.
650 newArgNum = argNum + 1
651 if tooLarge(num) {
652 num = 0
653 isInt = false
654 }
655 }
656 return
657 }
658 659 // parseArgNumber returns the value of the bracketed number, minus 1
660 // (explicit argument numbers are one-indexed but we want zero-indexed).
661 // The opening bracket is known to be present at format[0].
662 // The returned values are the index, the number of bytes to consume
663 // up to the closing paren, if present, and whether the number parsed
664 // ok. The bytes to consume will be 1 if no closing paren is present.
665 func parseArgNumber(format []byte) (index int, wid int, ok bool) {
666 // There must be at least 3 bytes: [n].
667 if len(format) < 3 {
668 return 0, 1, false
669 }
670 671 // Find closing bracket.
672 for i := 1; i < len(format); i++ {
673 if format[i] == ']' {
674 width, ok, newi := parsenum(format, 1, i)
675 if !ok || newi != i {
676 return 0, i + 1, false
677 }
678 return width - 1, i + 1, true // arg numbers are one-indexed and skip paren.
679 }
680 }
681 return 0, 1, false
682 }
683 684 // argNumber returns the next argument to evaluate, which is either the value of the passed-in
685 // argNum or the value of the bracketed integer that begins format[i:]. It also returns
686 // the new value of i, that is, the index of the next byte of the format to process.
687 func (p *pp) argNumber(argNum int, format []byte, i int, numArgs int) (newArgNum, newi int, found bool) {
688 if len(format) <= i || format[i] != '[' {
689 return argNum, i, false
690 }
691 p.reordered = true
692 index, wid, ok := parseArgNumber(format[i:])
693 if ok && 0 <= index && index < numArgs {
694 return index, i + wid, true
695 }
696 p.goodArgNum = false
697 return argNum, i + wid, ok
698 }
699 700 func (p *pp) badArgNum(verb rune) {
701 p.buf.writeString(percentBangString)
702 p.buf.writeRune(verb)
703 p.buf.writeString(badIndexString)
704 }
705 706 func (p *pp) missingArg(verb rune) {
707 p.buf.writeString(percentBangString)
708 p.buf.writeRune(verb)
709 p.buf.writeString(missingString)
710 }
711 712 func (p *pp) doPrintf(format []byte, a []any) {
713 end := len(format)
714 argNum := 0 // we process one argument per non-trivial format
715 afterIndex := false // previous item in format was an index like [3].
716 p.reordered = false
717 formatLoop:
718 for i := 0; i < end; {
719 p.goodArgNum = true
720 lasti := i
721 for i < end && format[i] != '%' {
722 i++
723 }
724 if i > lasti {
725 p.buf.writeString(format[lasti:i])
726 }
727 if i >= end {
728 // done processing format string
729 break
730 }
731 732 // Process one verb
733 i++
734 735 // Do we have flags?
736 p.fmt.clearflags()
737 simpleFormat:
738 for ; i < end; i++ {
739 c := format[i]
740 switch c {
741 case '#':
742 p.fmt.sharp = true
743 case '0':
744 p.fmt.zero = true
745 case '+':
746 p.fmt.plus = true
747 case '-':
748 p.fmt.minus = true
749 case ' ':
750 p.fmt.space = true
751 default:
752 // Fast path for common case of ascii lower case simple verbs
753 // without precision or width or argument indices.
754 if 'a' <= c && c <= 'z' && argNum < len(a) {
755 switch c {
756 case 'w':
757 p.wrappedErrs = append(p.wrappedErrs, argNum)
758 p.fmt.sharpV = p.fmt.sharp
759 p.fmt.sharp = false
760 p.fmt.plusV = p.fmt.plus
761 p.fmt.plus = false
762 case 'v':
763 // Go syntax
764 p.fmt.sharpV = p.fmt.sharp
765 p.fmt.sharp = false
766 // Struct-field syntax
767 p.fmt.plusV = p.fmt.plus
768 p.fmt.plus = false
769 }
770 p.printArg(a[argNum], rune(c))
771 argNum++
772 i++
773 continue formatLoop
774 }
775 // Format is more complex than simple flags and a verb or is malformed.
776 break simpleFormat
777 }
778 }
779 780 // Do we have an explicit argument index?
781 argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
782 783 // Do we have width?
784 if i < end && format[i] == '*' {
785 i++
786 p.fmt.wid, p.fmt.widPresent, argNum = intFromArg(a, argNum)
787 788 if !p.fmt.widPresent {
789 p.buf.writeString(badWidthString)
790 }
791 792 // We have a negative width, so take its value and ensure
793 // that the minus flag is set
794 if p.fmt.wid < 0 {
795 p.fmt.wid = -p.fmt.wid
796 p.fmt.minus = true
797 p.fmt.zero = false // Do not pad with zeros to the right.
798 }
799 afterIndex = false
800 } else {
801 p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end)
802 if afterIndex && p.fmt.widPresent { // "%[3]2d"
803 p.goodArgNum = false
804 }
805 }
806 807 // Do we have precision?
808 if i+1 < end && format[i] == '.' {
809 i++
810 if afterIndex { // "%[3].2d"
811 p.goodArgNum = false
812 }
813 argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
814 if i < end && format[i] == '*' {
815 i++
816 p.fmt.prec, p.fmt.precPresent, argNum = intFromArg(a, argNum)
817 // Negative precision arguments don't make sense
818 if p.fmt.prec < 0 {
819 p.fmt.prec = 0
820 p.fmt.precPresent = false
821 }
822 if !p.fmt.precPresent {
823 p.buf.writeString(badPrecString)
824 }
825 afterIndex = false
826 } else {
827 p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i, end)
828 if !p.fmt.precPresent {
829 p.fmt.prec = 0
830 p.fmt.precPresent = true
831 }
832 }
833 }
834 835 if !afterIndex {
836 argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
837 }
838 839 if i >= end {
840 p.buf.writeString(noVerbString)
841 break
842 }
843 844 verb, size := rune(format[i]), 1
845 if verb >= utf8.RuneSelf {
846 verb, size = utf8.DecodeRuneInString(format[i:])
847 }
848 i += size
849 850 switch {
851 case verb == '%': // Percent does not absorb operands and ignores f.wid and f.prec.
852 p.buf.writeByte('%')
853 case !p.goodArgNum:
854 p.badArgNum(verb)
855 case argNum >= len(a): // No argument left over to print for the current verb.
856 p.missingArg(verb)
857 case verb == 'w':
858 p.wrappedErrs = append(p.wrappedErrs, argNum)
859 p.fmt.sharpV = p.fmt.sharp
860 p.fmt.sharp = false
861 p.fmt.plusV = p.fmt.plus
862 p.fmt.plus = false
863 p.printArg(a[argNum], verb)
864 argNum++
865 case verb == 'v':
866 // Go syntax
867 p.fmt.sharpV = p.fmt.sharp
868 p.fmt.sharp = false
869 // Struct-field syntax
870 p.fmt.plusV = p.fmt.plus
871 p.fmt.plus = false
872 p.printArg(a[argNum], verb)
873 argNum++
874 default:
875 p.printArg(a[argNum], verb)
876 argNum++
877 }
878 }
879 880 // Check for extra arguments unless the call accessed the arguments
881 // out of order, in which case it's too expensive to detect if they've all
882 // been used and arguably OK if they're not.
883 if !p.reordered && argNum < len(a) {
884 p.fmt.clearflags()
885 p.buf.writeString(extraString)
886 for i, arg := range a[argNum:] {
887 if i > 0 {
888 p.buf.writeString(commaSpaceString)
889 }
890 if arg == nil {
891 p.buf.writeString(nilAngleString)
892 } else {
893 p.buf.writeString("?")
894 p.buf.writeByte('=')
895 p.printArg(arg, 'v')
896 }
897 }
898 p.buf.writeByte(')')
899 }
900 }
901 902 func (p *pp) doPrint(a []any) {
903 prevString := false
904 for argNum, arg := range a {
905 _, isString := arg.([]byte)
906 // Add a space between two non-string arguments.
907 if argNum > 0 && !isString && !prevString {
908 p.buf.writeByte(' ')
909 }
910 p.printArg(arg, 'v')
911 prevString = isString
912 }
913 }
914 915 // doPrintln is like doPrint but always adds a space between arguments
916 // and a newline after the last argument.
917 func (p *pp) doPrintln(a []any) {
918 for argNum, arg := range a {
919 if argNum > 0 {
920 p.buf.writeByte(' ')
921 }
922 p.printArg(arg, 'v')
923 }
924 p.buf.writeByte('\n')
925 }
926