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