Daily bump.
[official-gcc.git] / libgo / go / fmt / format.go
blob4d97d1443eda1292c403fd086acf7fc627b1c88a
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.
5 package fmt
7 import (
8 "math"
9 "strconv"
10 "unicode/utf8"
13 const (
14 // %b of an int64, plus a sign.
15 // Hex can add 0x and we handle it specially.
16 nByte = 65
18 ldigits = "0123456789abcdef"
19 udigits = "0123456789ABCDEF"
22 const (
23 signed = true
24 unsigned = false
27 var padZeroBytes = make([]byte, nByte)
28 var padSpaceBytes = make([]byte, nByte)
30 func init() {
31 for i := 0; i < nByte; i++ {
32 padZeroBytes[i] = '0'
33 padSpaceBytes[i] = ' '
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
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
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
67 func (f *fmt) clearflags() {
68 f.fmtFlags = fmtFlags{}
71 func (f *fmt) init(buf *buffer) {
72 f.buf = buf
73 f.clearflags()
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
84 w -= width
85 if w > 0 {
86 if left && f.zero {
87 return padZeroBytes, w, 0
89 if left {
90 return padSpaceBytes, w, 0
91 } else {
92 // can't be zero padding on the right
93 return padSpaceBytes, 0, w
96 return
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
106 f.buf.Write(padding[0:m])
107 n -= m
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
117 padding, left, right := f.computePadding(utf8.RuneCount(b))
118 if left > 0 {
119 f.writePadding(left, padding)
121 f.buf.Write(b)
122 if right > 0 {
123 f.writePadding(right, padding)
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
133 padding, left, right := f.computePadding(utf8.RuneCountInString(s))
134 if left > 0 {
135 f.writePadding(left, padding)
137 f.buf.WriteString(s)
138 if right > 0 {
139 f.writePadding(right, padding)
143 var (
144 trueBytes = []byte("true")
145 falseBytes = []byte("false")
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)
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
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
172 if width > nByte {
173 // We're going to need a bigger boat.
174 buf = make([]byte, width)
178 negative := signedness == signed && a < 0
179 if negative {
180 a = -a
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
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 {
208 next := ua / 10
209 buf[i] = byte('0' + ua - next*10)
210 ua = next
212 case 16:
213 for ua >= 16 {
215 buf[i] = digits[ua&0xF]
216 ua >>= 4
218 case 8:
219 for ua >= 8 {
221 buf[i] = byte('0' + ua&7)
222 ua >>= 3
224 case 2:
225 for ua >= 2 {
227 buf[i] = byte('0' + ua&1)
228 ua >>= 1
230 default:
231 panic("fmt: unknown base; can't happen")
234 buf[i] = digits[ua]
235 for i > 0 && prec > len(buf)-i {
237 buf[i] = '0'
240 // Various prefixes: 0x, -, etc.
241 if f.sharp {
242 switch base {
243 case 8:
244 if buf[i] != '0' {
246 buf[i] = '0'
248 case 16:
250 buf[i] = 'x' + digits[10] - 'a'
252 buf[i] = '0'
255 if f.unicode {
257 buf[i] = '+'
259 buf[i] = 'U'
262 if negative {
264 buf[i] = '-'
265 } else if f.plus {
267 buf[i] = '+'
268 } else if f.space {
270 buf[i] = ' '
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] = ' '
283 buf[j] = '\''
285 utf8.EncodeRune(buf[j:], rune(a))
286 j += runeWidth
287 buf[j] = '\''
290 f.pad(buf[i:])
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
305 return s
308 // fmt_s formats a string.
309 func (f *fmt) fmt_s(s string) {
310 s = f.truncate(s)
311 f.padString(s)
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)
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, ' ')
327 if f.sharp && (f.space || i == 0) {
328 buf = append(buf, '0', x)
330 var c byte
331 if b == nil {
332 c = s[i]
333 } else {
334 c = b[i]
336 buf = append(buf, digits[c>>4], digits[c&0xF])
338 f.pad(buf)
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]
346 f.fmt_sbx(s, nil, digits)
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]
354 f.fmt_sbx("", b, digits)
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)
370 f.padString(quoted)
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))
382 f.pad(quoted)
385 // floating-point
387 func doPrec(f *fmt, def int) int {
388 if f.precPresent {
389 return f.prec
391 return def
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] = '+'
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
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--
421 f.pad(num[1:])
422 return
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
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
436 // No sign to show and the number is positive; just print the unsigned number.
437 f.pad(num[1:])
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) }
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) }
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) }
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) }
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) }
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) }
458 // float32
459 // cannot defer to float64 versions
460 // because it will get rounding wrong in corner cases.
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) }
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) }
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) }
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) }
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) }
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) }
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)
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)
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)
511 if i != 0 {
512 break
514 // Imaginary part always has a sign.
515 f.plus = true
516 f.space = false
517 f.wid = oldWid
518 r = j
520 f.space = oldSpace
521 f.plus = oldPlus
522 f.wid = oldWid
523 f.buf.Write(irparenBytes)