Copyright 2009 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

package fmt

import (
	
	
)

const (
	ldigits = "0123456789abcdefx"
	udigits = "0123456789ABCDEFX"
)

const (
	signed   = true
	unsigned = false
)
flags placed in a separate struct for easy clearing.
For the formats %+v %#v, we set the plusV/sharpV flags and clear the plus/sharp flags since %+v and %#v are in effect different, flagless formats set at the top level.
A fmt is the raw formatter used by Printf etc. It prints into a buffer that must be set up separately.
type fmt struct {
	buf *buffer

	fmtFlags

	wid  int // width
	prec int // precision
intbuf is large enough to store %b of an int64 with a sign and avoids padding at the end of the struct on 32 bit architectures.
	intbuf [68]byte
}

func ( *fmt) () {
	.fmtFlags = fmtFlags{}
}

func ( *fmt) ( *buffer) {
	.buf = 
	.clearflags()
}
writePadding generates n bytes of padding.
func ( *fmt) ( int) {
	if  <= 0 { // No padding bytes needed.
		return
	}
	 := *.buf
	 := len()
Make enough room for padding.
	if  > cap() {
		 = make(buffer, cap()*2+)
		copy(, *.buf)
Decide which byte the padding should be filled with.
	 := byte(' ')
	if .zero {
		 = byte('0')
Fill padding with padByte.
	 := [:]
	for  := range  {
		[] = 
	}
	*.buf = [:]
}
pad appends b to f.buf, padded on left (!f.minus) or right (f.minus).
func ( *fmt) ( []byte) {
	if !.widPresent || .wid == 0 {
		.buf.write()
		return
	}
	 := .wid - utf8.RuneCount()
left padding
		.writePadding()
		.buf.write()
right padding
		.buf.write()
		.writePadding()
	}
}
padString appends s to f.buf, padded on left (!f.minus) or right (f.minus).
func ( *fmt) ( string) {
	if !.widPresent || .wid == 0 {
		.buf.writeString()
		return
	}
	 := .wid - utf8.RuneCountInString()
left padding
		.writePadding()
		.buf.writeString()
right padding
		.buf.writeString()
		.writePadding()
	}
}
fmtBoolean formats a boolean.
func ( *fmt) ( bool) {
	if  {
		.padString("true")
	} else {
		.padString("false")
	}
}
fmtUnicode formats a uint64 as "U+0078" or with f.sharp set as "U+0078 'x'".
func ( *fmt) ( uint64) {
	 := .intbuf[0:]
With default precision set the maximum needed buf length is 18 for formatting -1 with %#U ("U+FFFFFFFFFFFFFFFF") which fits into the already allocated intbuf with a capacity of 68 bytes.
	 := 4
	if .precPresent && .prec > 4 {
Compute space needed for "U+" , number, " '", character, "'".
		 := 2 +  + 2 + utf8.UTFMax + 1
		if  > len() {
			 = make([]byte, )
		}
	}
Format into buf, ending at buf[i]. Formatting numbers is easier right-to-left.
	 := len()
For %#U we want to add a space and a quoted character at the end of the buffer.
	if .sharp &&  <= utf8.MaxRune && strconv.IsPrint(rune()) {
		--
		[] = '\''
		 -= utf8.RuneLen(rune())
		utf8.EncodeRune([:], rune())
		--
		[] = '\''
		--
		[] = ' '
Format the Unicode code point u as a hexadecimal number.
	for  >= 16 {
		--
		[] = udigits[&0xF]
		--
		 >>= 4
	}
	--
	[] = udigits[]
Add zeros in front of the number until requested precision is reached.
	for  > 0 {
		--
		[] = '0'
		--
Add a leading "U+".
	--
	[] = '+'
	--
	[] = 'U'

	 := .zero
	.zero = false
	.pad([:])
	.zero = 
}
fmtInteger formats signed and unsigned integers.
func ( *fmt) ( uint64,  int,  bool,  rune,  string) {
	 :=  && int64() < 0
	if  {
		 = -
	}

The already allocated f.intbuf with a capacity of 68 bytes is large enough for integer formatting when no precision or width is set.
Account 3 extra bytes for possible addition of a sign and "0x".
		 := 3 + .wid + .prec // wid and prec are always positive.
We're going to need a bigger boat.
			 = make([]byte, )
		}
	}
Two ways to ask for extra leading zero digits: %.3d or %03d. If both are specified the f.zero flag is ignored and padding with spaces is used instead.
	 := 0
	if .precPresent {
Precision of 0 and value of 0 means "print nothing" but padding.
		if  == 0 &&  == 0 {
			 := .zero
			.zero = false
			.writePadding(.wid)
			.zero = 
			return
		}
	} else if .zero && .widPresent {
		 = .wid
		if  || .plus || .space {
			-- // leave room for sign
		}
	}
Because printing is easier right-to-left: format u into buf, ending at buf[i]. We could make things marginally faster by splitting the 32-bit case out into a separate block but it's not worth the duplication, so u has 64 bits.
Use constants for the division and modulo for more efficient code. Switch cases ordered by popularity.
	switch  {
	case 10:
		for  >= 10 {
			--
			 :=  / 10
			[] = byte('0' +  - *10)
			 = 
		}
	case 16:
		for  >= 16 {
			--
			[] = [&0xF]
			 >>= 4
		}
	case 8:
		for  >= 8 {
			--
			[] = byte('0' + &7)
			 >>= 3
		}
	case 2:
		for  >= 2 {
			--
			[] = byte('0' + &1)
			 >>= 1
		}
	default:
		panic("fmt: unknown base; can't happen")
	}
	--
	[] = []
	for  > 0 &&  > len()- {
		--
		[] = '0'
	}
Various prefixes: 0x, -, etc.
	if .sharp {
		switch  {
Add a leading 0b.
			--
			[] = 'b'
			--
			[] = '0'
		case 8:
			if [] != '0' {
				--
				[] = '0'
			}
Add a leading 0x or 0X.
			--
			[] = [16]
			--
			[] = '0'
		}
	}
	if  == 'O' {
		--
		[] = 'o'
		--
		[] = '0'
	}

	if  {
		--
		[] = '-'
	} else if .plus {
		--
		[] = '+'
	} else if .space {
		--
		[] = ' '
	}
Left padding with zeros has already been handled like precision earlier or the f.zero flag is ignored due to an explicitly set precision.
	 := .zero
	.zero = false
	.pad([:])
	.zero = 
}
truncate truncates the string s to the specified precision, if present.
func ( *fmt) ( string) string {
	if .precPresent {
		 := .prec
		for  := range  {
			--
			if  < 0 {
				return [:]
			}
		}
	}
	return 
}
truncate truncates the byte slice b as a string of the specified precision, if present.
func ( *fmt) ( []byte) []byte {
	if .precPresent {
		 := .prec
		for  := 0;  < len(); {
			--
			if  < 0 {
				return [:]
			}
			 := 1
			if [] >= utf8.RuneSelf {
				_,  = utf8.DecodeRune([:])
			}
			 += 
		}
	}
	return 
}
fmtS formats a string.
func ( *fmt) ( string) {
	 = .truncateString()
	.padString()
}
fmtBs formats the byte slice b as if it was formatted as string with fmtS.
func ( *fmt) ( []byte) {
	 = .truncate()
	.pad()
}
fmtSbx formats a string or byte slice as a hexadecimal encoding of its bytes.
func ( *fmt) ( string,  []byte,  string) {
	 := len()
No byte slice present. Assume string s should be encoded.
		 = len()
Set length to not process more bytes than the precision demands.
	if .precPresent && .prec <  {
		 = .prec
Compute width of the encoding taking into account the f.sharp and f.space flag.
	 := 2 * 
	if  > 0 {
Each element encoded by two hexadecimals will get a leading 0x or 0X.
			if .sharp {
				 *= 2
Elements will be separated by a space.
			 +=  - 1
Only a leading 0x or 0X will be added for the whole string.
			 += 2
		}
	} else { // The byte slice or string that should be encoded is empty.
		if .widPresent {
			.writePadding(.wid)
		}
		return
Handle padding to the left.
	if .widPresent && .wid >  && !.minus {
		.writePadding(.wid - )
Write the encoding directly into the output buffer.
	 := *.buf
Add leading 0x or 0X.
		 = append(, '0', [16])
	}
	var  byte
	for  := 0;  < ; ++ {
Separate elements with a space.
			 = append(, ' ')
Add leading 0x or 0X for each element.
				 = append(, '0', [16])
			}
		}
		if  != nil {
			 = [] // Take a byte from the input byte slice.
		} else {
			 = [] // Take a byte from the input string.
Encode each byte as two hexadecimal digits.
		 = append(, [>>4], [&0xF])
	}
Handle padding to the right.
	if .widPresent && .wid >  && .minus {
		.writePadding(.wid - )
	}
}
fmtSx formats a string as a hexadecimal encoding of its bytes.
func ( *fmt) (,  string) {
	.fmtSbx(, nil, )
}
fmtBx formats a byte slice as a hexadecimal encoding of its bytes.
func ( *fmt) ( []byte,  string) {
	.fmtSbx("", , )
}
fmtQ formats a string as a double-quoted, escaped Go string constant. If f.sharp is set a raw (backquoted) string may be returned instead if the string does not contain any control characters other than tab.
func ( *fmt) ( string) {
	 = .truncateString()
	if .sharp && strconv.CanBackquote() {
		.padString("`" +  + "`")
		return
	}
	 := .intbuf[:0]
	if .plus {
		.pad(strconv.AppendQuoteToASCII(, ))
	} else {
		.pad(strconv.AppendQuote(, ))
	}
}
fmtC formats an integer as a Unicode character. If the character is not valid Unicode, it will print '\ufffd'.
func ( *fmt) ( uint64) {
	 := rune()
	if  > utf8.MaxRune {
		 = utf8.RuneError
	}
	 := .intbuf[:0]
	 := utf8.EncodeRune([:utf8.UTFMax], )
	.pad([:])
}
fmtQc formats an integer as a single-quoted, escaped Go character constant. If the character is not valid Unicode, it will print '\ufffd'.
func ( *fmt) ( uint64) {
	 := rune()
	if  > utf8.MaxRune {
		 = utf8.RuneError
	}
	 := .intbuf[:0]
	if .plus {
		.pad(strconv.AppendQuoteRuneToASCII(, ))
	} else {
		.pad(strconv.AppendQuoteRune(, ))
	}
}
fmtFloat formats a float64. It assumes that verb is a valid format specifier for strconv.AppendFloat and therefore fits into a byte.
Explicit precision in format specifier overrules default precision.
	if .precPresent {
		 = .prec
Format number, reserving space for leading + sign if needed.
	 := strconv.AppendFloat(.intbuf[:1], , byte(), , )
	if [1] == '-' || [1] == '+' {
		 = [1:]
	} else {
		[0] = '+'
f.space means to add a leading space instead of a "+" sign unless the sign is explicitly asked for by f.plus.
	if .space && [0] == '+' && !.plus {
		[0] = ' '
Special handling for infinities and NaN, which don't look like a number so shouldn't be padded with zeros.
	if [1] == 'I' || [1] == 'N' {
		 := .zero
Remove sign before NaN if not asked for.
		if [1] == 'N' && !.space && !.plus {
			 = [1:]
		}
		.pad()
		.zero = 
		return
The sharp flag forces printing a decimal point for non-binary formats and retains trailing zeros, which we may need to restore.
	if .sharp &&  != 'b' {
		 := 0
		switch  {
		case 'v', 'g', 'G', 'x':
If no precision is set explicitly use a precision of 6.
			if  == -1 {
				 = 6
			}
		}
Buffer pre-allocated with enough room for exponent notations of the form "e+123" or "p-1023".
		var  [6]byte
		 := [:0]

		 := false
Starting from i = 1 to skip sign at num[0].
		for  := 1;  < len(); ++ {
			switch [] {
			case '.':
				 = true
			case 'p', 'P':
				 = append(, [:]...)
				 = [:]
			case 'e', 'E':
				if  != 'x' &&  != 'X' {
					 = append(, [:]...)
					 = [:]
					break
				}
				fallthrough
			default:
				if [] != '0' {
					 = true
Count significant digits after the first non-zero digit.
				if  {
					--
				}
			}
		}
Leading digit 0 should contribute once to digits.
			if len() == 2 && [1] == '0' {
				--
			}
			 = append(, '.')
		}
		for  > 0 {
			 = append(, '0')
			--
		}
		 = append(, ...)
We want a sign if asked for and if the sign is not positive.
If we're zero padding to the left we want the sign before the leading zeros. Achieve this by writing the sign out and then padding the unsigned number.
		if .zero && .widPresent && .wid > len() {
			.buf.writeByte([0])
			.writePadding(.wid - len())
			.buf.write([1:])
			return
		}
		.pad()
		return
No sign to show and the number is positive; just print the unsigned number.
	.pad([1:])