Source file src/pkg/fmt/format.go
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 nByte = 65 // %b of an int64, plus a sign. 14 15 ldigits = "0123456789abcdef" 16 udigits = "0123456789ABCDEF" 17 ) 18 19 const ( 20 signed = true 21 unsigned = false 22 ) 23 24 var padZeroBytes = make([]byte, nByte) 25 var padSpaceBytes = make([]byte, nByte) 26 27 var newline = []byte{'\n'} 28 29 func 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. 38 type 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 56 func (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 70 func (f *fmt) init(buf *buffer) { 71 f.buf = buf 72 f.clearflags() 73 } 74 75 // Compute left and right padding widths (only one will be non-zero). 76 func (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 // Generate n bytes of padding. 99 func (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 // Append b to f.buf, padded on left (w > 0) or right (w < 0 or f.minus) 111 // clear flags afterwards. 112 func (f *fmt) pad(b []byte) { 113 var padding []byte 114 var left, right int 115 if f.widPresent && f.wid != 0 { 116 padding, left, right = f.computePadding(len(b)) 117 } 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 // append s to buf, padded on left (w > 0) or right (w < 0 or f.minus). 128 // clear flags afterwards. 129 func (f *fmt) padString(s string) { 130 var padding []byte 131 var left, right int 132 if f.widPresent && f.wid != 0 { 133 padding, left, right = f.computePadding(utf8.RuneCountInString(s)) 134 } 135 if left > 0 { 136 f.writePadding(left, padding) 137 } 138 f.buf.WriteString(s) 139 if right > 0 { 140 f.writePadding(right, padding) 141 } 142 } 143 144 func putint(buf []byte, base, val uint64, digits string) int { 145 i := len(buf) - 1 146 for val >= base { 147 buf[i] = digits[val%base] 148 i-- 149 val /= base 150 } 151 buf[i] = digits[val] 152 return i - 1 153 } 154 155 var ( 156 trueBytes = []byte("true") 157 falseBytes = []byte("false") 158 ) 159 160 // fmt_boolean formats a boolean. 161 func (f *fmt) fmt_boolean(v bool) { 162 if v { 163 f.pad(trueBytes) 164 } else { 165 f.pad(falseBytes) 166 } 167 } 168 169 // integer; interprets prec but not wid. Once formatted, result is sent to pad() 170 // and then flags are cleared. 171 func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) { 172 // precision of 0 and value of 0 means "print nothing" 173 if f.precPresent && f.prec == 0 && a == 0 { 174 return 175 } 176 177 var buf []byte = f.intbuf[0:] 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(f.intbuf) 201 ua := uint64(a) 202 for ua >= base { 203 i-- 204 buf[i] = digits[ua%base] 205 ua /= base 206 } 207 i-- 208 buf[i] = digits[ua] 209 for i > 0 && prec > nByte-i { 210 i-- 211 buf[i] = '0' 212 } 213 214 // Various prefixes: 0x, -, etc. 215 if f.sharp { 216 switch base { 217 case 8: 218 if buf[i] != '0' { 219 i-- 220 buf[i] = '0' 221 } 222 case 16: 223 i-- 224 buf[i] = 'x' + digits[10] - 'a' 225 i-- 226 buf[i] = '0' 227 } 228 } 229 if f.unicode { 230 i-- 231 buf[i] = '+' 232 i-- 233 buf[i] = 'U' 234 } 235 236 if negative { 237 i-- 238 buf[i] = '-' 239 } else if f.plus { 240 i-- 241 buf[i] = '+' 242 } else if f.space { 243 i-- 244 buf[i] = ' ' 245 } 246 247 // If we want a quoted char for %#U, move the data up to make room. 248 if f.unicode && f.uniQuote && a >= 0 && a <= utf8.MaxRune && strconv.IsPrint(rune(a)) { 249 runeWidth := utf8.RuneLen(rune(a)) 250 width := 1 + 1 + runeWidth + 1 // space, quote, rune, quote 251 copy(buf[i-width:], buf[i:]) // guaranteed to have enough room. 252 i -= width 253 // Now put " 'x'" at the end. 254 j := len(buf) - width 255 buf[j] = ' ' 256 j++ 257 buf[j] = '\'' 258 j++ 259 utf8.EncodeRune(buf[j:], rune(a)) 260 j += runeWidth 261 buf[j] = '\'' 262 } 263 264 f.pad(buf[i:]) 265 } 266 267 // truncate truncates the string to the specified precision, if present. 268 func (f *fmt) truncate(s string) string { 269 if f.precPresent && f.prec < utf8.RuneCountInString(s) { 270 n := f.prec 271 for i := range s { 272 if n == 0 { 273 s = s[:i] 274 break 275 } 276 n-- 277 } 278 } 279 return s 280 } 281 282 // fmt_s formats a string. 283 func (f *fmt) fmt_s(s string) { 284 s = f.truncate(s) 285 f.padString(s) 286 } 287 288 // fmt_sx formats a string as a hexadecimal encoding of its bytes. 289 func (f *fmt) fmt_sx(s, digits string) { 290 // TODO: Avoid buffer by pre-padding. 291 var b []byte 292 for i := 0; i < len(s); i++ { 293 if i > 0 && f.space { 294 b = append(b, ' ') 295 } 296 v := s[i] 297 b = append(b, digits[v>>4], digits[v&0xF]) 298 } 299 f.pad(b) 300 } 301 302 // fmt_q formats a string as a double-quoted, escaped Go string constant. 303 func (f *fmt) fmt_q(s string) { 304 s = f.truncate(s) 305 var quoted string 306 if f.sharp && strconv.CanBackquote(s) { 307 quoted = "`" + s + "`" 308 } else { 309 if f.plus { 310 quoted = strconv.QuoteToASCII(s) 311 } else { 312 quoted = strconv.Quote(s) 313 } 314 } 315 f.padString(quoted) 316 } 317 318 // fmt_qc formats the integer as a single-quoted, escaped Go character constant. 319 // If the character is not valid Unicode, it will print '\ufffd'. 320 func (f *fmt) fmt_qc(c int64) { 321 var quoted []byte 322 if f.plus { 323 quoted = strconv.AppendQuoteRuneToASCII(f.intbuf[0:0], rune(c)) 324 } else { 325 quoted = strconv.AppendQuoteRune(f.intbuf[0:0], rune(c)) 326 } 327 f.pad(quoted) 328 } 329 330 // floating-point 331 332 func doPrec(f *fmt, def int) int { 333 if f.precPresent { 334 return f.prec 335 } 336 return def 337 } 338 339 // formatFloat formats a float64; it is an efficient equivalent to f.pad(strconv.FormatFloat()...). 340 func (f *fmt) formatFloat(v float64, verb byte, prec, n int) { 341 // We leave one byte at the beginning of f.intbuf for a sign if needed, 342 // and make it a space, which we might be able to use. 343 f.intbuf[0] = ' ' 344 slice := strconv.AppendFloat(f.intbuf[0:1], v, verb, prec, n) 345 // Add a plus sign or space to the floating-point string representation if missing and required. 346 // The formatted number starts at slice[1]. 347 switch slice[1] { 348 case '-', '+': 349 // We're set; drop the leading space. 350 slice = slice[1:] 351 default: 352 // There's no sign, but we might need one. 353 if f.plus { 354 slice[0] = '+' 355 } else if f.space { 356 // space is already there 357 } else { 358 slice = slice[1:] 359 } 360 } 361 f.pad(slice) 362 } 363 364 // fmt_e64 formats a float64 in the form -1.23e+12. 365 func (f *fmt) fmt_e64(v float64) { f.formatFloat(v, 'e', doPrec(f, 6), 64) } 366 367 // fmt_E64 formats a float64 in the form -1.23E+12. 368 func (f *fmt) fmt_E64(v float64) { f.formatFloat(v, 'E', doPrec(f, 6), 64) } 369 370 // fmt_f64 formats a float64 in the form -1.23. 371 func (f *fmt) fmt_f64(v float64) { f.formatFloat(v, 'f', doPrec(f, 6), 64) } 372 373 // fmt_g64 formats a float64 in the 'f' or 'e' form according to size. 374 func (f *fmt) fmt_g64(v float64) { f.formatFloat(v, 'g', doPrec(f, -1), 64) } 375 376 // fmt_g64 formats a float64 in the 'f' or 'E' form according to size. 377 func (f *fmt) fmt_G64(v float64) { f.formatFloat(v, 'G', doPrec(f, -1), 64) } 378 379 // fmt_fb64 formats a float64 in the form -123p3 (exponent is power of 2). 380 func (f *fmt) fmt_fb64(v float64) { f.formatFloat(v, 'b', 0, 64) } 381 382 // float32 383 // cannot defer to float64 versions 384 // because it will get rounding wrong in corner cases. 385 386 // fmt_e32 formats a float32 in the form -1.23e+12. 387 func (f *fmt) fmt_e32(v float32) { f.formatFloat(float64(v), 'e', doPrec(f, 6), 32) } 388 389 // fmt_E32 formats a float32 in the form -1.23E+12. 390 func (f *fmt) fmt_E32(v float32) { f.formatFloat(float64(v), 'E', doPrec(f, 6), 32) } 391 392 // fmt_f32 formats a float32 in the form -1.23. 393 func (f *fmt) fmt_f32(v float32) { f.formatFloat(float64(v), 'f', doPrec(f, 6), 32) } 394 395 // fmt_g32 formats a float32 in the 'f' or 'e' form according to size. 396 func (f *fmt) fmt_g32(v float32) { f.formatFloat(float64(v), 'g', doPrec(f, -1), 32) } 397 398 // fmt_G32 formats a float32 in the 'f' or 'E' form according to size. 399 func (f *fmt) fmt_G32(v float32) { f.formatFloat(float64(v), 'G', doPrec(f, -1), 32) } 400 401 // fmt_fb32 formats a float32 in the form -123p3 (exponent is power of 2). 402 func (f *fmt) fmt_fb32(v float32) { f.formatFloat(float64(v), 'b', 0, 32) } 403 404 // fmt_c64 formats a complex64 according to the verb. 405 func (f *fmt) fmt_c64(v complex64, verb rune) { 406 f.buf.WriteByte('(') 407 r := real(v) 408 for i := 0; ; i++ { 409 switch verb { 410 case 'e': 411 f.fmt_e32(r) 412 case 'E': 413 f.fmt_E32(r) 414 case 'f': 415 f.fmt_f32(r) 416 case 'g': 417 f.fmt_g32(r) 418 case 'G': 419 f.fmt_G32(r) 420 } 421 if i != 0 { 422 break 423 } 424 f.plus = true 425 r = imag(v) 426 } 427 f.buf.Write(irparenBytes) 428 } 429 430 // fmt_c128 formats a complex128 according to the verb. 431 func (f *fmt) fmt_c128(v complex128, verb rune) { 432 f.buf.WriteByte('(') 433 r := real(v) 434 for i := 0; ; i++ { 435 switch verb { 436 case 'e': 437 f.fmt_e64(r) 438 case 'E': 439 f.fmt_E64(r) 440 case 'f': 441 f.fmt_f64(r) 442 case 'g': 443 f.fmt_g64(r) 444 case 'G': 445 f.fmt_G64(r) 446 } 447 if i != 0 { 448 break 449 } 450 f.plus = true 451 r = imag(v) 452 } 453 f.buf.Write(irparenBytes) 454 }