github.com/MangoDowner/go-gm@v0.0.0-20180818020936-8baa2bd4408c/src/fmt/format.go (about) 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 // fmt_boolean formats a boolean. 126 func (f *fmt) fmt_boolean(v bool) { 127 if v { 128 f.padString("true") 129 } else { 130 f.padString("false") 131 } 132 } 133 134 // fmt_unicode formats a uint64 as "U+0078" or with f.sharp set as "U+0078 'x'". 135 func (f *fmt) fmt_unicode(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 // fmt_integer formats signed and unsigned integers. 194 func (f *fmt) fmt_integer(u uint64, base int, isSigned bool, 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 8: 279 if buf[i] != '0' { 280 i-- 281 buf[i] = '0' 282 } 283 case 16: 284 // Add a leading 0x or 0X. 285 i-- 286 buf[i] = digits[16] 287 i-- 288 buf[i] = '0' 289 } 290 } 291 292 if negative { 293 i-- 294 buf[i] = '-' 295 } else if f.plus { 296 i-- 297 buf[i] = '+' 298 } else if f.space { 299 i-- 300 buf[i] = ' ' 301 } 302 303 // Left padding with zeros has already been handled like precision earlier 304 // or the f.zero flag is ignored due to an explicitly set precision. 305 oldZero := f.zero 306 f.zero = false 307 f.pad(buf[i:]) 308 f.zero = oldZero 309 } 310 311 // truncate truncates the string to the specified precision, if present. 312 func (f *fmt) truncate(s string) string { 313 if f.precPresent { 314 n := f.prec 315 for i := range s { 316 n-- 317 if n < 0 { 318 return s[:i] 319 } 320 } 321 } 322 return s 323 } 324 325 // fmt_s formats a string. 326 func (f *fmt) fmt_s(s string) { 327 s = f.truncate(s) 328 f.padString(s) 329 } 330 331 // fmt_sbx formats a string or byte slice as a hexadecimal encoding of its bytes. 332 func (f *fmt) fmt_sbx(s string, b []byte, digits string) { 333 length := len(b) 334 if b == nil { 335 // No byte slice present. Assume string s should be encoded. 336 length = len(s) 337 } 338 // Set length to not process more bytes than the precision demands. 339 if f.precPresent && f.prec < length { 340 length = f.prec 341 } 342 // Compute width of the encoding taking into account the f.sharp and f.space flag. 343 width := 2 * length 344 if width > 0 { 345 if f.space { 346 // Each element encoded by two hexadecimals will get a leading 0x or 0X. 347 if f.sharp { 348 width *= 2 349 } 350 // Elements will be separated by a space. 351 width += length - 1 352 } else if f.sharp { 353 // Only a leading 0x or 0X will be added for the whole string. 354 width += 2 355 } 356 } else { // The byte slice or string that should be encoded is empty. 357 if f.widPresent { 358 f.writePadding(f.wid) 359 } 360 return 361 } 362 // Handle padding to the left. 363 if f.widPresent && f.wid > width && !f.minus { 364 f.writePadding(f.wid - width) 365 } 366 // Write the encoding directly into the output buffer. 367 buf := *f.buf 368 if f.sharp { 369 // Add leading 0x or 0X. 370 buf = append(buf, '0', digits[16]) 371 } 372 var c byte 373 for i := 0; i < length; i++ { 374 if f.space && i > 0 { 375 // Separate elements with a space. 376 buf = append(buf, ' ') 377 if f.sharp { 378 // Add leading 0x or 0X for each element. 379 buf = append(buf, '0', digits[16]) 380 } 381 } 382 if b != nil { 383 c = b[i] // Take a byte from the input byte slice. 384 } else { 385 c = s[i] // Take a byte from the input string. 386 } 387 // Encode each byte as two hexadecimal digits. 388 buf = append(buf, digits[c>>4], digits[c&0xF]) 389 } 390 *f.buf = buf 391 // Handle padding to the right. 392 if f.widPresent && f.wid > width && f.minus { 393 f.writePadding(f.wid - width) 394 } 395 } 396 397 // fmt_sx formats a string as a hexadecimal encoding of its bytes. 398 func (f *fmt) fmt_sx(s, digits string) { 399 f.fmt_sbx(s, nil, digits) 400 } 401 402 // fmt_bx formats a byte slice as a hexadecimal encoding of its bytes. 403 func (f *fmt) fmt_bx(b []byte, digits string) { 404 f.fmt_sbx("", b, digits) 405 } 406 407 // fmt_q formats a string as a double-quoted, escaped Go string constant. 408 // If f.sharp is set a raw (backquoted) string may be returned instead 409 // if the string does not contain any control characters other than tab. 410 func (f *fmt) fmt_q(s string) { 411 s = f.truncate(s) 412 if f.sharp && strconv.CanBackquote(s) { 413 f.padString("`" + s + "`") 414 return 415 } 416 buf := f.intbuf[:0] 417 if f.plus { 418 f.pad(strconv.AppendQuoteToASCII(buf, s)) 419 } else { 420 f.pad(strconv.AppendQuote(buf, s)) 421 } 422 } 423 424 // fmt_c formats an integer as a Unicode character. 425 // If the character is not valid Unicode, it will print '\ufffd'. 426 func (f *fmt) fmt_c(c uint64) { 427 r := rune(c) 428 if c > utf8.MaxRune { 429 r = utf8.RuneError 430 } 431 buf := f.intbuf[:0] 432 w := utf8.EncodeRune(buf[:utf8.UTFMax], r) 433 f.pad(buf[:w]) 434 } 435 436 // fmt_qc formats an integer as a single-quoted, escaped Go character constant. 437 // If the character is not valid Unicode, it will print '\ufffd'. 438 func (f *fmt) fmt_qc(c uint64) { 439 r := rune(c) 440 if c > utf8.MaxRune { 441 r = utf8.RuneError 442 } 443 buf := f.intbuf[:0] 444 if f.plus { 445 f.pad(strconv.AppendQuoteRuneToASCII(buf, r)) 446 } else { 447 f.pad(strconv.AppendQuoteRune(buf, r)) 448 } 449 } 450 451 // fmt_float formats a float64. It assumes that verb is a valid format specifier 452 // for strconv.AppendFloat and therefore fits into a byte. 453 func (f *fmt) fmt_float(v float64, size int, verb rune, prec int) { 454 // Explicit precision in format specifier overrules default precision. 455 if f.precPresent { 456 prec = f.prec 457 } 458 // Format number, reserving space for leading + sign if needed. 459 num := strconv.AppendFloat(f.intbuf[:1], v, byte(verb), prec, size) 460 if num[1] == '-' || num[1] == '+' { 461 num = num[1:] 462 } else { 463 num[0] = '+' 464 } 465 // f.space means to add a leading space instead of a "+" sign unless 466 // the sign is explicitly asked for by f.plus. 467 if f.space && num[0] == '+' && !f.plus { 468 num[0] = ' ' 469 } 470 // Special handling for infinities and NaN, 471 // which don't look like a number so shouldn't be padded with zeros. 472 if num[1] == 'I' || num[1] == 'N' { 473 oldZero := f.zero 474 f.zero = false 475 // Remove sign before NaN if not asked for. 476 if num[1] == 'N' && !f.space && !f.plus { 477 num = num[1:] 478 } 479 f.pad(num) 480 f.zero = oldZero 481 return 482 } 483 // The sharp flag forces printing a decimal point for non-binary formats 484 // and retains trailing zeros, which we may need to restore. 485 if f.sharp && verb != 'b' { 486 digits := 0 487 switch verb { 488 case 'v', 'g', 'G': 489 digits = prec 490 // If no precision is set explicitly use a precision of 6. 491 if digits == -1 { 492 digits = 6 493 } 494 } 495 496 // Buffer pre-allocated with enough room for 497 // exponent notations of the form "e+123". 498 var tailBuf [5]byte 499 tail := tailBuf[:0] 500 501 hasDecimalPoint := false 502 // Starting from i = 1 to skip sign at num[0]. 503 for i := 1; i < len(num); i++ { 504 switch num[i] { 505 case '.': 506 hasDecimalPoint = true 507 case 'e', 'E': 508 tail = append(tail, num[i:]...) 509 num = num[:i] 510 default: 511 digits-- 512 } 513 } 514 if !hasDecimalPoint { 515 num = append(num, '.') 516 } 517 for digits > 0 { 518 num = append(num, '0') 519 digits-- 520 } 521 num = append(num, tail...) 522 } 523 // We want a sign if asked for and if the sign is not positive. 524 if f.plus || num[0] != '+' { 525 // If we're zero padding to the left we want the sign before the leading zeros. 526 // Achieve this by writing the sign out and then padding the unsigned number. 527 if f.zero && f.widPresent && f.wid > len(num) { 528 f.buf.WriteByte(num[0]) 529 f.writePadding(f.wid - len(num)) 530 f.buf.Write(num[1:]) 531 return 532 } 533 f.pad(num) 534 return 535 } 536 // No sign to show and the number is positive; just print the unsigned number. 537 f.pad(num[1:]) 538 }