github.com/hongwozai/go-src-1.4.3@v0.0.0-20191127132709-dc3fce3dbccb/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 "math" 9 "strconv" 10 "unicode/utf8" 11 ) 12 13 const ( 14 // %b of an int64, plus a sign. 15 // Hex can add 0x and we handle it specially. 16 nByte = 65 17 18 ldigits = "0123456789abcdef" 19 udigits = "0123456789ABCDEF" 20 ) 21 22 const ( 23 signed = true 24 unsigned = false 25 ) 26 27 var padZeroBytes = make([]byte, nByte) 28 var padSpaceBytes = make([]byte, nByte) 29 30 func init() { 31 for i := 0; i < nByte; i++ { 32 padZeroBytes[i] = '0' 33 padSpaceBytes[i] = ' ' 34 } 35 } 36 37 // flags placed in a separate struct for easy clearing. 38 type fmtFlags struct { 39 widPresent bool 40 precPresent bool 41 minus bool 42 plus bool 43 sharp bool 44 space bool 45 unicode bool 46 uniQuote bool // Use 'x'= prefix for %U if printable. 47 zero bool 48 49 // For the formats %+v %#v, we set the plusV/sharpV flags 50 // and clear the plus/sharp flags since %+v and %#v are in effect 51 // different, flagless formats set at the top level. 52 plusV bool 53 sharpV bool 54 } 55 56 // A fmt is the raw formatter used by Printf etc. 57 // It prints into a buffer that must be set up separately. 58 type fmt struct { 59 intbuf [nByte]byte 60 buf *buffer 61 // width, precision 62 wid int 63 prec int 64 fmtFlags 65 } 66 67 func (f *fmt) clearflags() { 68 f.fmtFlags = fmtFlags{} 69 } 70 71 func (f *fmt) init(buf *buffer) { 72 f.buf = buf 73 f.clearflags() 74 } 75 76 // computePadding computes left and right padding widths (only one will be non-zero). 77 func (f *fmt) computePadding(width int) (padding []byte, leftWidth, rightWidth int) { 78 left := !f.minus 79 w := f.wid 80 if w < 0 { 81 left = false 82 w = -w 83 } 84 w -= width 85 if w > 0 { 86 if left && f.zero { 87 return padZeroBytes, w, 0 88 } 89 if left { 90 return padSpaceBytes, w, 0 91 } else { 92 // can't be zero padding on the right 93 return padSpaceBytes, 0, w 94 } 95 } 96 return 97 } 98 99 // writePadding generates n bytes of padding. 100 func (f *fmt) writePadding(n int, padding []byte) { 101 for n > 0 { 102 m := n 103 if m > nByte { 104 m = nByte 105 } 106 f.buf.Write(padding[0:m]) 107 n -= m 108 } 109 } 110 111 // pad appends b to f.buf, padded on left (w > 0) or right (w < 0 or f.minus). 112 func (f *fmt) pad(b []byte) { 113 if !f.widPresent || f.wid == 0 { 114 f.buf.Write(b) 115 return 116 } 117 padding, left, right := f.computePadding(utf8.RuneCount(b)) 118 if left > 0 { 119 f.writePadding(left, padding) 120 } 121 f.buf.Write(b) 122 if right > 0 { 123 f.writePadding(right, padding) 124 } 125 } 126 127 // padString appends s to buf, padded on left (w > 0) or right (w < 0 or f.minus). 128 func (f *fmt) padString(s string) { 129 if !f.widPresent || f.wid == 0 { 130 f.buf.WriteString(s) 131 return 132 } 133 padding, left, right := f.computePadding(utf8.RuneCountInString(s)) 134 if left > 0 { 135 f.writePadding(left, padding) 136 } 137 f.buf.WriteString(s) 138 if right > 0 { 139 f.writePadding(right, padding) 140 } 141 } 142 143 var ( 144 trueBytes = []byte("true") 145 falseBytes = []byte("false") 146 ) 147 148 // fmt_boolean formats a boolean. 149 func (f *fmt) fmt_boolean(v bool) { 150 if v { 151 f.pad(trueBytes) 152 } else { 153 f.pad(falseBytes) 154 } 155 } 156 157 // integer; interprets prec but not wid. Once formatted, result is sent to pad() 158 // and then flags are cleared. 159 func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) { 160 // precision of 0 and value of 0 means "print nothing" 161 if f.precPresent && f.prec == 0 && a == 0 { 162 return 163 } 164 165 var buf []byte = f.intbuf[0:] 166 if f.widPresent { 167 width := f.wid 168 if base == 16 && f.sharp { 169 // Also adds "0x". 170 width += 2 171 } 172 if width > nByte { 173 // We're going to need a bigger boat. 174 buf = make([]byte, width) 175 } 176 } 177 178 negative := signedness == signed && a < 0 179 if negative { 180 a = -a 181 } 182 183 // two ways to ask for extra leading zero digits: %.3d or %03d. 184 // apparently the first cancels the second. 185 prec := 0 186 if f.precPresent { 187 prec = f.prec 188 f.zero = false 189 } else if f.zero && f.widPresent && !f.minus && f.wid > 0 { 190 prec = f.wid 191 if negative || f.plus || f.space { 192 prec-- // leave room for sign 193 } 194 } 195 196 // format a into buf, ending at buf[i]. (printing is easier right-to-left.) 197 // a is made into unsigned ua. we could make things 198 // marginally faster by splitting the 32-bit case out into a separate 199 // block but it's not worth the duplication, so ua has 64 bits. 200 i := len(buf) 201 ua := uint64(a) 202 // use constants for the division and modulo for more efficient code. 203 // switch cases ordered by popularity. 204 switch base { 205 case 10: 206 for ua >= 10 { 207 i-- 208 next := ua / 10 209 buf[i] = byte('0' + ua - next*10) 210 ua = next 211 } 212 case 16: 213 for ua >= 16 { 214 i-- 215 buf[i] = digits[ua&0xF] 216 ua >>= 4 217 } 218 case 8: 219 for ua >= 8 { 220 i-- 221 buf[i] = byte('0' + ua&7) 222 ua >>= 3 223 } 224 case 2: 225 for ua >= 2 { 226 i-- 227 buf[i] = byte('0' + ua&1) 228 ua >>= 1 229 } 230 default: 231 panic("fmt: unknown base; can't happen") 232 } 233 i-- 234 buf[i] = digits[ua] 235 for i > 0 && prec > len(buf)-i { 236 i-- 237 buf[i] = '0' 238 } 239 240 // Various prefixes: 0x, -, etc. 241 if f.sharp { 242 switch base { 243 case 8: 244 if buf[i] != '0' { 245 i-- 246 buf[i] = '0' 247 } 248 case 16: 249 i-- 250 buf[i] = 'x' + digits[10] - 'a' 251 i-- 252 buf[i] = '0' 253 } 254 } 255 if f.unicode { 256 i-- 257 buf[i] = '+' 258 i-- 259 buf[i] = 'U' 260 } 261 262 if negative { 263 i-- 264 buf[i] = '-' 265 } else if f.plus { 266 i-- 267 buf[i] = '+' 268 } else if f.space { 269 i-- 270 buf[i] = ' ' 271 } 272 273 // If we want a quoted char for %#U, move the data up to make room. 274 if f.unicode && f.uniQuote && a >= 0 && a <= utf8.MaxRune && strconv.IsPrint(rune(a)) { 275 runeWidth := utf8.RuneLen(rune(a)) 276 width := 1 + 1 + runeWidth + 1 // space, quote, rune, quote 277 copy(buf[i-width:], buf[i:]) // guaranteed to have enough room. 278 i -= width 279 // Now put " 'x'" at the end. 280 j := len(buf) - width 281 buf[j] = ' ' 282 j++ 283 buf[j] = '\'' 284 j++ 285 utf8.EncodeRune(buf[j:], rune(a)) 286 j += runeWidth 287 buf[j] = '\'' 288 } 289 290 f.pad(buf[i:]) 291 } 292 293 // truncate truncates the string to the specified precision, if present. 294 func (f *fmt) truncate(s string) string { 295 if f.precPresent && f.prec < utf8.RuneCountInString(s) { 296 n := f.prec 297 for i := range s { 298 if n == 0 { 299 s = s[:i] 300 break 301 } 302 n-- 303 } 304 } 305 return s 306 } 307 308 // fmt_s formats a string. 309 func (f *fmt) fmt_s(s string) { 310 s = f.truncate(s) 311 f.padString(s) 312 } 313 314 // fmt_sbx formats a string or byte slice as a hexadecimal encoding of its bytes. 315 func (f *fmt) fmt_sbx(s string, b []byte, digits string) { 316 n := len(b) 317 if b == nil { 318 n = len(s) 319 } 320 x := digits[10] - 'a' + 'x' 321 // TODO: Avoid buffer by pre-padding. 322 var buf []byte 323 for i := 0; i < n; i++ { 324 if i > 0 && f.space { 325 buf = append(buf, ' ') 326 } 327 if f.sharp && (f.space || i == 0) { 328 buf = append(buf, '0', x) 329 } 330 var c byte 331 if b == nil { 332 c = s[i] 333 } else { 334 c = b[i] 335 } 336 buf = append(buf, digits[c>>4], digits[c&0xF]) 337 } 338 f.pad(buf) 339 } 340 341 // fmt_sx formats a string as a hexadecimal encoding of its bytes. 342 func (f *fmt) fmt_sx(s, digits string) { 343 if f.precPresent && f.prec < len(s) { 344 s = s[:f.prec] 345 } 346 f.fmt_sbx(s, nil, digits) 347 } 348 349 // fmt_bx formats a byte slice as a hexadecimal encoding of its bytes. 350 func (f *fmt) fmt_bx(b []byte, digits string) { 351 if f.precPresent && f.prec < len(b) { 352 b = b[:f.prec] 353 } 354 f.fmt_sbx("", b, digits) 355 } 356 357 // fmt_q formats a string as a double-quoted, escaped Go string constant. 358 func (f *fmt) fmt_q(s string) { 359 s = f.truncate(s) 360 var quoted string 361 if f.sharp && strconv.CanBackquote(s) { 362 quoted = "`" + s + "`" 363 } else { 364 if f.plus { 365 quoted = strconv.QuoteToASCII(s) 366 } else { 367 quoted = strconv.Quote(s) 368 } 369 } 370 f.padString(quoted) 371 } 372 373 // fmt_qc formats the integer as a single-quoted, escaped Go character constant. 374 // If the character is not valid Unicode, it will print '\ufffd'. 375 func (f *fmt) fmt_qc(c int64) { 376 var quoted []byte 377 if f.plus { 378 quoted = strconv.AppendQuoteRuneToASCII(f.intbuf[0:0], rune(c)) 379 } else { 380 quoted = strconv.AppendQuoteRune(f.intbuf[0:0], rune(c)) 381 } 382 f.pad(quoted) 383 } 384 385 // floating-point 386 387 func doPrec(f *fmt, def int) int { 388 if f.precPresent { 389 return f.prec 390 } 391 return def 392 } 393 394 // formatFloat formats a float64; it is an efficient equivalent to f.pad(strconv.FormatFloat()...). 395 func (f *fmt) formatFloat(v float64, verb byte, prec, n int) { 396 // Format number, reserving space for leading + sign if needed. 397 num := strconv.AppendFloat(f.intbuf[0:1], v, verb, prec, n) 398 if num[1] == '-' || num[1] == '+' { 399 num = num[1:] 400 } else { 401 num[0] = '+' 402 } 403 // Special handling for infinity, which doesn't look like a number so shouldn't be padded with zeros. 404 if math.IsInf(v, 0) { 405 if f.zero { 406 defer func() { f.zero = true }() 407 f.zero = false 408 } 409 } 410 // num is now a signed version of the number. 411 // If we're zero padding, want the sign before the leading zeros. 412 // Achieve this by writing the sign out and then padding the unsigned number. 413 if f.zero && f.widPresent && f.wid > len(num) { 414 if f.space && v >= 0 { 415 f.buf.WriteByte(' ') // This is what C does: even with zero, f.space means space. 416 f.wid-- 417 } else if f.plus || v < 0 { 418 f.buf.WriteByte(num[0]) 419 f.wid-- 420 } 421 f.pad(num[1:]) 422 return 423 } 424 // f.space says to replace a leading + with a space. 425 if f.space && num[0] == '+' { 426 num[0] = ' ' 427 f.pad(num) 428 return 429 } 430 // Now we know the sign is attached directly to the number, if present at all. 431 // We want a sign if asked for, if it's negative, or if it's infinity (+Inf vs. -Inf). 432 if f.plus || num[0] == '-' || math.IsInf(v, 0) { 433 f.pad(num) 434 return 435 } 436 // No sign to show and the number is positive; just print the unsigned number. 437 f.pad(num[1:]) 438 } 439 440 // fmt_e64 formats a float64 in the form -1.23e+12. 441 func (f *fmt) fmt_e64(v float64) { f.formatFloat(v, 'e', doPrec(f, 6), 64) } 442 443 // fmt_E64 formats a float64 in the form -1.23E+12. 444 func (f *fmt) fmt_E64(v float64) { f.formatFloat(v, 'E', doPrec(f, 6), 64) } 445 446 // fmt_f64 formats a float64 in the form -1.23. 447 func (f *fmt) fmt_f64(v float64) { f.formatFloat(v, 'f', doPrec(f, 6), 64) } 448 449 // fmt_g64 formats a float64 in the 'f' or 'e' form according to size. 450 func (f *fmt) fmt_g64(v float64) { f.formatFloat(v, 'g', doPrec(f, -1), 64) } 451 452 // fmt_G64 formats a float64 in the 'f' or 'E' form according to size. 453 func (f *fmt) fmt_G64(v float64) { f.formatFloat(v, 'G', doPrec(f, -1), 64) } 454 455 // fmt_fb64 formats a float64 in the form -123p3 (exponent is power of 2). 456 func (f *fmt) fmt_fb64(v float64) { f.formatFloat(v, 'b', 0, 64) } 457 458 // float32 459 // cannot defer to float64 versions 460 // because it will get rounding wrong in corner cases. 461 462 // fmt_e32 formats a float32 in the form -1.23e+12. 463 func (f *fmt) fmt_e32(v float32) { f.formatFloat(float64(v), 'e', doPrec(f, 6), 32) } 464 465 // fmt_E32 formats a float32 in the form -1.23E+12. 466 func (f *fmt) fmt_E32(v float32) { f.formatFloat(float64(v), 'E', doPrec(f, 6), 32) } 467 468 // fmt_f32 formats a float32 in the form -1.23. 469 func (f *fmt) fmt_f32(v float32) { f.formatFloat(float64(v), 'f', doPrec(f, 6), 32) } 470 471 // fmt_g32 formats a float32 in the 'f' or 'e' form according to size. 472 func (f *fmt) fmt_g32(v float32) { f.formatFloat(float64(v), 'g', doPrec(f, -1), 32) } 473 474 // fmt_G32 formats a float32 in the 'f' or 'E' form according to size. 475 func (f *fmt) fmt_G32(v float32) { f.formatFloat(float64(v), 'G', doPrec(f, -1), 32) } 476 477 // fmt_fb32 formats a float32 in the form -123p3 (exponent is power of 2). 478 func (f *fmt) fmt_fb32(v float32) { f.formatFloat(float64(v), 'b', 0, 32) } 479 480 // fmt_c64 formats a complex64 according to the verb. 481 func (f *fmt) fmt_c64(v complex64, verb rune) { 482 f.fmt_complex(float64(real(v)), float64(imag(v)), 32, verb) 483 } 484 485 // fmt_c128 formats a complex128 according to the verb. 486 func (f *fmt) fmt_c128(v complex128, verb rune) { 487 f.fmt_complex(real(v), imag(v), 64, verb) 488 } 489 490 // fmt_complex formats a complex number as (r+ji). 491 func (f *fmt) fmt_complex(r, j float64, size int, verb rune) { 492 f.buf.WriteByte('(') 493 oldPlus := f.plus 494 oldSpace := f.space 495 oldWid := f.wid 496 for i := 0; ; i++ { 497 switch verb { 498 case 'b': 499 f.formatFloat(r, 'b', 0, size) 500 case 'e': 501 f.formatFloat(r, 'e', doPrec(f, 6), size) 502 case 'E': 503 f.formatFloat(r, 'E', doPrec(f, 6), size) 504 case 'f', 'F': 505 f.formatFloat(r, 'f', doPrec(f, 6), size) 506 case 'g': 507 f.formatFloat(r, 'g', doPrec(f, -1), size) 508 case 'G': 509 f.formatFloat(r, 'G', doPrec(f, -1), size) 510 } 511 if i != 0 { 512 break 513 } 514 // Imaginary part always has a sign. 515 f.plus = true 516 f.space = false 517 f.wid = oldWid 518 r = j 519 } 520 f.space = oldSpace 521 f.plus = oldPlus 522 f.wid = oldWid 523 f.buf.Write(irparenBytes) 524 }