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