print.mx raw

   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