...

Source file src/fmt/format.go

Documentation: fmt

		 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  	"strconv"
		 9  	"unicode/utf8"
		10  )
		11  
		12  const (
		13  	ldigits = "0123456789abcdefx"
		14  	udigits = "0123456789ABCDEFX"
		15  )
		16  
		17  const (
		18  	signed	 = true
		19  	unsigned = false
		20  )
		21  
		22  // flags placed in a separate struct for easy clearing.
		23  type fmtFlags struct {
		24  	widPresent	bool
		25  	precPresent bool
		26  	minus			 bool
		27  	plus				bool
		28  	sharp			 bool
		29  	space			 bool
		30  	zero				bool
		31  
		32  	// For the formats %+v %#v, we set the plusV/sharpV flags
		33  	// and clear the plus/sharp flags since %+v and %#v are in effect
		34  	// different, flagless formats set at the top level.
		35  	plusV	bool
		36  	sharpV bool
		37  }
		38  
		39  // A fmt is the raw formatter used by Printf etc.
		40  // It prints into a buffer that must be set up separately.
		41  type fmt struct {
		42  	buf *buffer
		43  
		44  	fmtFlags
		45  
		46  	wid	int // width
		47  	prec int // precision
		48  
		49  	// intbuf is large enough to store %b of an int64 with a sign and
		50  	// avoids padding at the end of the struct on 32 bit architectures.
		51  	intbuf [68]byte
		52  }
		53  
		54  func (f *fmt) clearflags() {
		55  	f.fmtFlags = fmtFlags{}
		56  }
		57  
		58  func (f *fmt) init(buf *buffer) {
		59  	f.buf = buf
		60  	f.clearflags()
		61  }
		62  
		63  // writePadding generates n bytes of padding.
		64  func (f *fmt) writePadding(n int) {
		65  	if n <= 0 { // No padding bytes needed.
		66  		return
		67  	}
		68  	buf := *f.buf
		69  	oldLen := len(buf)
		70  	newLen := oldLen + n
		71  	// Make enough room for padding.
		72  	if newLen > cap(buf) {
		73  		buf = make(buffer, cap(buf)*2+n)
		74  		copy(buf, *f.buf)
		75  	}
		76  	// Decide which byte the padding should be filled with.
		77  	padByte := byte(' ')
		78  	if f.zero {
		79  		padByte = byte('0')
		80  	}
		81  	// Fill padding with padByte.
		82  	padding := buf[oldLen:newLen]
		83  	for i := range padding {
		84  		padding[i] = padByte
		85  	}
		86  	*f.buf = buf[:newLen]
		87  }
		88  
		89  // pad appends b to f.buf, padded on left (!f.minus) or right (f.minus).
		90  func (f *fmt) pad(b []byte) {
		91  	if !f.widPresent || f.wid == 0 {
		92  		f.buf.write(b)
		93  		return
		94  	}
		95  	width := f.wid - utf8.RuneCount(b)
		96  	if !f.minus {
		97  		// left padding
		98  		f.writePadding(width)
		99  		f.buf.write(b)
	 100  	} else {
	 101  		// right padding
	 102  		f.buf.write(b)
	 103  		f.writePadding(width)
	 104  	}
	 105  }
	 106  
	 107  // padString appends s to f.buf, padded on left (!f.minus) or right (f.minus).
	 108  func (f *fmt) padString(s string) {
	 109  	if !f.widPresent || f.wid == 0 {
	 110  		f.buf.writeString(s)
	 111  		return
	 112  	}
	 113  	width := f.wid - utf8.RuneCountInString(s)
	 114  	if !f.minus {
	 115  		// left padding
	 116  		f.writePadding(width)
	 117  		f.buf.writeString(s)
	 118  	} else {
	 119  		// right padding
	 120  		f.buf.writeString(s)
	 121  		f.writePadding(width)
	 122  	}
	 123  }
	 124  
	 125  // fmtBoolean formats a boolean.
	 126  func (f *fmt) fmtBoolean(v bool) {
	 127  	if v {
	 128  		f.padString("true")
	 129  	} else {
	 130  		f.padString("false")
	 131  	}
	 132  }
	 133  
	 134  // fmtUnicode formats a uint64 as "U+0078" or with f.sharp set as "U+0078 'x'".
	 135  func (f *fmt) fmtUnicode(u uint64) {
	 136  	buf := f.intbuf[0:]
	 137  
	 138  	// With default precision set the maximum needed buf length is 18
	 139  	// for formatting -1 with %#U ("U+FFFFFFFFFFFFFFFF") which fits
	 140  	// into the already allocated intbuf with a capacity of 68 bytes.
	 141  	prec := 4
	 142  	if f.precPresent && f.prec > 4 {
	 143  		prec = f.prec
	 144  		// Compute space needed for "U+" , number, " '", character, "'".
	 145  		width := 2 + prec + 2 + utf8.UTFMax + 1
	 146  		if width > len(buf) {
	 147  			buf = make([]byte, width)
	 148  		}
	 149  	}
	 150  
	 151  	// Format into buf, ending at buf[i]. Formatting numbers is easier right-to-left.
	 152  	i := len(buf)
	 153  
	 154  	// For %#U we want to add a space and a quoted character at the end of the buffer.
	 155  	if f.sharp && u <= utf8.MaxRune && strconv.IsPrint(rune(u)) {
	 156  		i--
	 157  		buf[i] = '\''
	 158  		i -= utf8.RuneLen(rune(u))
	 159  		utf8.EncodeRune(buf[i:], rune(u))
	 160  		i--
	 161  		buf[i] = '\''
	 162  		i--
	 163  		buf[i] = ' '
	 164  	}
	 165  	// Format the Unicode code point u as a hexadecimal number.
	 166  	for u >= 16 {
	 167  		i--
	 168  		buf[i] = udigits[u&0xF]
	 169  		prec--
	 170  		u >>= 4
	 171  	}
	 172  	i--
	 173  	buf[i] = udigits[u]
	 174  	prec--
	 175  	// Add zeros in front of the number until requested precision is reached.
	 176  	for prec > 0 {
	 177  		i--
	 178  		buf[i] = '0'
	 179  		prec--
	 180  	}
	 181  	// Add a leading "U+".
	 182  	i--
	 183  	buf[i] = '+'
	 184  	i--
	 185  	buf[i] = 'U'
	 186  
	 187  	oldZero := f.zero
	 188  	f.zero = false
	 189  	f.pad(buf[i:])
	 190  	f.zero = oldZero
	 191  }
	 192  
	 193  // fmtInteger formats signed and unsigned integers.
	 194  func (f *fmt) fmtInteger(u uint64, base int, isSigned bool, verb rune, digits string) {
	 195  	negative := isSigned && int64(u) < 0
	 196  	if negative {
	 197  		u = -u
	 198  	}
	 199  
	 200  	buf := f.intbuf[0:]
	 201  	// The already allocated f.intbuf with a capacity of 68 bytes
	 202  	// is large enough for integer formatting when no precision or width is set.
	 203  	if f.widPresent || f.precPresent {
	 204  		// Account 3 extra bytes for possible addition of a sign and "0x".
	 205  		width := 3 + f.wid + f.prec // wid and prec are always positive.
	 206  		if width > len(buf) {
	 207  			// We're going to need a bigger boat.
	 208  			buf = make([]byte, width)
	 209  		}
	 210  	}
	 211  
	 212  	// Two ways to ask for extra leading zero digits: %.3d or %03d.
	 213  	// If both are specified the f.zero flag is ignored and
	 214  	// padding with spaces is used instead.
	 215  	prec := 0
	 216  	if f.precPresent {
	 217  		prec = f.prec
	 218  		// Precision of 0 and value of 0 means "print nothing" but padding.
	 219  		if prec == 0 && u == 0 {
	 220  			oldZero := f.zero
	 221  			f.zero = false
	 222  			f.writePadding(f.wid)
	 223  			f.zero = oldZero
	 224  			return
	 225  		}
	 226  	} else if f.zero && f.widPresent {
	 227  		prec = f.wid
	 228  		if negative || f.plus || f.space {
	 229  			prec-- // leave room for sign
	 230  		}
	 231  	}
	 232  
	 233  	// Because printing is easier right-to-left: format u into buf, ending at buf[i].
	 234  	// We could make things marginally faster by splitting the 32-bit case out
	 235  	// into a separate block but it's not worth the duplication, so u has 64 bits.
	 236  	i := len(buf)
	 237  	// Use constants for the division and modulo for more efficient code.
	 238  	// Switch cases ordered by popularity.
	 239  	switch base {
	 240  	case 10:
	 241  		for u >= 10 {
	 242  			i--
	 243  			next := u / 10
	 244  			buf[i] = byte('0' + u - next*10)
	 245  			u = next
	 246  		}
	 247  	case 16:
	 248  		for u >= 16 {
	 249  			i--
	 250  			buf[i] = digits[u&0xF]
	 251  			u >>= 4
	 252  		}
	 253  	case 8:
	 254  		for u >= 8 {
	 255  			i--
	 256  			buf[i] = byte('0' + u&7)
	 257  			u >>= 3
	 258  		}
	 259  	case 2:
	 260  		for u >= 2 {
	 261  			i--
	 262  			buf[i] = byte('0' + u&1)
	 263  			u >>= 1
	 264  		}
	 265  	default:
	 266  		panic("fmt: unknown base; can't happen")
	 267  	}
	 268  	i--
	 269  	buf[i] = digits[u]
	 270  	for i > 0 && prec > len(buf)-i {
	 271  		i--
	 272  		buf[i] = '0'
	 273  	}
	 274  
	 275  	// Various prefixes: 0x, -, etc.
	 276  	if f.sharp {
	 277  		switch base {
	 278  		case 2:
	 279  			// Add a leading 0b.
	 280  			i--
	 281  			buf[i] = 'b'
	 282  			i--
	 283  			buf[i] = '0'
	 284  		case 8:
	 285  			if buf[i] != '0' {
	 286  				i--
	 287  				buf[i] = '0'
	 288  			}
	 289  		case 16:
	 290  			// Add a leading 0x or 0X.
	 291  			i--
	 292  			buf[i] = digits[16]
	 293  			i--
	 294  			buf[i] = '0'
	 295  		}
	 296  	}
	 297  	if verb == 'O' {
	 298  		i--
	 299  		buf[i] = 'o'
	 300  		i--
	 301  		buf[i] = '0'
	 302  	}
	 303  
	 304  	if negative {
	 305  		i--
	 306  		buf[i] = '-'
	 307  	} else if f.plus {
	 308  		i--
	 309  		buf[i] = '+'
	 310  	} else if f.space {
	 311  		i--
	 312  		buf[i] = ' '
	 313  	}
	 314  
	 315  	// Left padding with zeros has already been handled like precision earlier
	 316  	// or the f.zero flag is ignored due to an explicitly set precision.
	 317  	oldZero := f.zero
	 318  	f.zero = false
	 319  	f.pad(buf[i:])
	 320  	f.zero = oldZero
	 321  }
	 322  
	 323  // truncateString truncates the string s to the specified precision, if present.
	 324  func (f *fmt) truncateString(s string) string {
	 325  	if f.precPresent {
	 326  		n := f.prec
	 327  		for i := range s {
	 328  			n--
	 329  			if n < 0 {
	 330  				return s[:i]
	 331  			}
	 332  		}
	 333  	}
	 334  	return s
	 335  }
	 336  
	 337  // truncate truncates the byte slice b as a string of the specified precision, if present.
	 338  func (f *fmt) truncate(b []byte) []byte {
	 339  	if f.precPresent {
	 340  		n := f.prec
	 341  		for i := 0; i < len(b); {
	 342  			n--
	 343  			if n < 0 {
	 344  				return b[:i]
	 345  			}
	 346  			wid := 1
	 347  			if b[i] >= utf8.RuneSelf {
	 348  				_, wid = utf8.DecodeRune(b[i:])
	 349  			}
	 350  			i += wid
	 351  		}
	 352  	}
	 353  	return b
	 354  }
	 355  
	 356  // fmtS formats a string.
	 357  func (f *fmt) fmtS(s string) {
	 358  	s = f.truncateString(s)
	 359  	f.padString(s)
	 360  }
	 361  
	 362  // fmtBs formats the byte slice b as if it was formatted as string with fmtS.
	 363  func (f *fmt) fmtBs(b []byte) {
	 364  	b = f.truncate(b)
	 365  	f.pad(b)
	 366  }
	 367  
	 368  // fmtSbx formats a string or byte slice as a hexadecimal encoding of its bytes.
	 369  func (f *fmt) fmtSbx(s string, b []byte, digits string) {
	 370  	length := len(b)
	 371  	if b == nil {
	 372  		// No byte slice present. Assume string s should be encoded.
	 373  		length = len(s)
	 374  	}
	 375  	// Set length to not process more bytes than the precision demands.
	 376  	if f.precPresent && f.prec < length {
	 377  		length = f.prec
	 378  	}
	 379  	// Compute width of the encoding taking into account the f.sharp and f.space flag.
	 380  	width := 2 * length
	 381  	if width > 0 {
	 382  		if f.space {
	 383  			// Each element encoded by two hexadecimals will get a leading 0x or 0X.
	 384  			if f.sharp {
	 385  				width *= 2
	 386  			}
	 387  			// Elements will be separated by a space.
	 388  			width += length - 1
	 389  		} else if f.sharp {
	 390  			// Only a leading 0x or 0X will be added for the whole string.
	 391  			width += 2
	 392  		}
	 393  	} else { // The byte slice or string that should be encoded is empty.
	 394  		if f.widPresent {
	 395  			f.writePadding(f.wid)
	 396  		}
	 397  		return
	 398  	}
	 399  	// Handle padding to the left.
	 400  	if f.widPresent && f.wid > width && !f.minus {
	 401  		f.writePadding(f.wid - width)
	 402  	}
	 403  	// Write the encoding directly into the output buffer.
	 404  	buf := *f.buf
	 405  	if f.sharp {
	 406  		// Add leading 0x or 0X.
	 407  		buf = append(buf, '0', digits[16])
	 408  	}
	 409  	var c byte
	 410  	for i := 0; i < length; i++ {
	 411  		if f.space && i > 0 {
	 412  			// Separate elements with a space.
	 413  			buf = append(buf, ' ')
	 414  			if f.sharp {
	 415  				// Add leading 0x or 0X for each element.
	 416  				buf = append(buf, '0', digits[16])
	 417  			}
	 418  		}
	 419  		if b != nil {
	 420  			c = b[i] // Take a byte from the input byte slice.
	 421  		} else {
	 422  			c = s[i] // Take a byte from the input string.
	 423  		}
	 424  		// Encode each byte as two hexadecimal digits.
	 425  		buf = append(buf, digits[c>>4], digits[c&0xF])
	 426  	}
	 427  	*f.buf = buf
	 428  	// Handle padding to the right.
	 429  	if f.widPresent && f.wid > width && f.minus {
	 430  		f.writePadding(f.wid - width)
	 431  	}
	 432  }
	 433  
	 434  // fmtSx formats a string as a hexadecimal encoding of its bytes.
	 435  func (f *fmt) fmtSx(s, digits string) {
	 436  	f.fmtSbx(s, nil, digits)
	 437  }
	 438  
	 439  // fmtBx formats a byte slice as a hexadecimal encoding of its bytes.
	 440  func (f *fmt) fmtBx(b []byte, digits string) {
	 441  	f.fmtSbx("", b, digits)
	 442  }
	 443  
	 444  // fmtQ formats a string as a double-quoted, escaped Go string constant.
	 445  // If f.sharp is set a raw (backquoted) string may be returned instead
	 446  // if the string does not contain any control characters other than tab.
	 447  func (f *fmt) fmtQ(s string) {
	 448  	s = f.truncateString(s)
	 449  	if f.sharp && strconv.CanBackquote(s) {
	 450  		f.padString("`" + s + "`")
	 451  		return
	 452  	}
	 453  	buf := f.intbuf[:0]
	 454  	if f.plus {
	 455  		f.pad(strconv.AppendQuoteToASCII(buf, s))
	 456  	} else {
	 457  		f.pad(strconv.AppendQuote(buf, s))
	 458  	}
	 459  }
	 460  
	 461  // fmtC formats an integer as a Unicode character.
	 462  // If the character is not valid Unicode, it will print '\ufffd'.
	 463  func (f *fmt) fmtC(c uint64) {
	 464  	r := rune(c)
	 465  	if c > utf8.MaxRune {
	 466  		r = utf8.RuneError
	 467  	}
	 468  	buf := f.intbuf[:0]
	 469  	w := utf8.EncodeRune(buf[:utf8.UTFMax], r)
	 470  	f.pad(buf[:w])
	 471  }
	 472  
	 473  // fmtQc formats an integer as a single-quoted, escaped Go character constant.
	 474  // If the character is not valid Unicode, it will print '\ufffd'.
	 475  func (f *fmt) fmtQc(c uint64) {
	 476  	r := rune(c)
	 477  	if c > utf8.MaxRune {
	 478  		r = utf8.RuneError
	 479  	}
	 480  	buf := f.intbuf[:0]
	 481  	if f.plus {
	 482  		f.pad(strconv.AppendQuoteRuneToASCII(buf, r))
	 483  	} else {
	 484  		f.pad(strconv.AppendQuoteRune(buf, r))
	 485  	}
	 486  }
	 487  
	 488  // fmtFloat formats a float64. It assumes that verb is a valid format specifier
	 489  // for strconv.AppendFloat and therefore fits into a byte.
	 490  func (f *fmt) fmtFloat(v float64, size int, verb rune, prec int) {
	 491  	// Explicit precision in format specifier overrules default precision.
	 492  	if f.precPresent {
	 493  		prec = f.prec
	 494  	}
	 495  	// Format number, reserving space for leading + sign if needed.
	 496  	num := strconv.AppendFloat(f.intbuf[:1], v, byte(verb), prec, size)
	 497  	if num[1] == '-' || num[1] == '+' {
	 498  		num = num[1:]
	 499  	} else {
	 500  		num[0] = '+'
	 501  	}
	 502  	// f.space means to add a leading space instead of a "+" sign unless
	 503  	// the sign is explicitly asked for by f.plus.
	 504  	if f.space && num[0] == '+' && !f.plus {
	 505  		num[0] = ' '
	 506  	}
	 507  	// Special handling for infinities and NaN,
	 508  	// which don't look like a number so shouldn't be padded with zeros.
	 509  	if num[1] == 'I' || num[1] == 'N' {
	 510  		oldZero := f.zero
	 511  		f.zero = false
	 512  		// Remove sign before NaN if not asked for.
	 513  		if num[1] == 'N' && !f.space && !f.plus {
	 514  			num = num[1:]
	 515  		}
	 516  		f.pad(num)
	 517  		f.zero = oldZero
	 518  		return
	 519  	}
	 520  	// The sharp flag forces printing a decimal point for non-binary formats
	 521  	// and retains trailing zeros, which we may need to restore.
	 522  	if f.sharp && verb != 'b' {
	 523  		digits := 0
	 524  		switch verb {
	 525  		case 'v', 'g', 'G', 'x':
	 526  			digits = prec
	 527  			// If no precision is set explicitly use a precision of 6.
	 528  			if digits == -1 {
	 529  				digits = 6
	 530  			}
	 531  		}
	 532  
	 533  		// Buffer pre-allocated with enough room for
	 534  		// exponent notations of the form "e+123" or "p-1023".
	 535  		var tailBuf [6]byte
	 536  		tail := tailBuf[:0]
	 537  
	 538  		hasDecimalPoint := false
	 539  		sawNonzeroDigit := false
	 540  		// Starting from i = 1 to skip sign at num[0].
	 541  		for i := 1; i < len(num); i++ {
	 542  			switch num[i] {
	 543  			case '.':
	 544  				hasDecimalPoint = true
	 545  			case 'p', 'P':
	 546  				tail = append(tail, num[i:]...)
	 547  				num = num[:i]
	 548  			case 'e', 'E':
	 549  				if verb != 'x' && verb != 'X' {
	 550  					tail = append(tail, num[i:]...)
	 551  					num = num[:i]
	 552  					break
	 553  				}
	 554  				fallthrough
	 555  			default:
	 556  				if num[i] != '0' {
	 557  					sawNonzeroDigit = true
	 558  				}
	 559  				// Count significant digits after the first non-zero digit.
	 560  				if sawNonzeroDigit {
	 561  					digits--
	 562  				}
	 563  			}
	 564  		}
	 565  		if !hasDecimalPoint {
	 566  			// Leading digit 0 should contribute once to digits.
	 567  			if len(num) == 2 && num[1] == '0' {
	 568  				digits--
	 569  			}
	 570  			num = append(num, '.')
	 571  		}
	 572  		for digits > 0 {
	 573  			num = append(num, '0')
	 574  			digits--
	 575  		}
	 576  		num = append(num, tail...)
	 577  	}
	 578  	// We want a sign if asked for and if the sign is not positive.
	 579  	if f.plus || num[0] != '+' {
	 580  		// If we're zero padding to the left we want the sign before the leading zeros.
	 581  		// Achieve this by writing the sign out and then padding the unsigned number.
	 582  		if f.zero && f.widPresent && f.wid > len(num) {
	 583  			f.buf.writeByte(num[0])
	 584  			f.writePadding(f.wid - len(num))
	 585  			f.buf.write(num[1:])
	 586  			return
	 587  		}
	 588  		f.pad(num)
	 589  		return
	 590  	}
	 591  	// No sign to show and the number is positive; just print the unsigned number.
	 592  	f.pad(num[1:])
	 593  }
	 594  

View as plain text