libgo: Update to Go 1.3 release.
[official-gcc.git] / libgo / go / fmt / format.go
bloba89c542cfb553cec42e0ca132328375a7d91e129
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 // A fmt is the raw formatter used by Printf etc.
38 // It prints into a buffer that must be set up separately.
39 type fmt struct {
40 intbuf [nByte]byte
41 buf *buffer
42 // width, precision
43 wid int
44 prec int
45 // flags
46 widPresent bool
47 precPresent bool
48 minus bool
49 plus bool
50 sharp bool
51 space bool
52 unicode bool
53 uniQuote bool // Use 'x'= prefix for %U if printable.
54 zero bool
57 func (f *fmt) clearflags() {
58 f.wid = 0
59 f.widPresent = false
60 f.prec = 0
61 f.precPresent = false
62 f.minus = false
63 f.plus = false
64 f.sharp = false
65 f.space = false
66 f.unicode = false
67 f.uniQuote = false
68 f.zero = false
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(len(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 for ua >= base {
204 buf[i] = digits[ua%base]
205 ua /= base
208 buf[i] = digits[ua]
209 for i > 0 && prec > len(buf)-i {
211 buf[i] = '0'
214 // Various prefixes: 0x, -, etc.
215 if f.sharp {
216 switch base {
217 case 8:
218 if buf[i] != '0' {
220 buf[i] = '0'
222 case 16:
224 buf[i] = 'x' + digits[10] - 'a'
226 buf[i] = '0'
229 if f.unicode {
231 buf[i] = '+'
233 buf[i] = 'U'
236 if negative {
238 buf[i] = '-'
239 } else if f.plus {
241 buf[i] = '+'
242 } else if f.space {
244 buf[i] = ' '
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] = ' '
257 buf[j] = '\''
259 utf8.EncodeRune(buf[j:], rune(a))
260 j += runeWidth
261 buf[j] = '\''
264 f.pad(buf[i:])
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
279 return s
282 // fmt_s formats a string.
283 func (f *fmt) fmt_s(s string) {
284 s = f.truncate(s)
285 f.padString(s)
288 // fmt_sbx formats a string or byte slice as a hexadecimal encoding of its bytes.
289 func (f *fmt) fmt_sbx(s string, b []byte, digits string) {
290 n := len(b)
291 if b == nil {
292 n = len(s)
294 x := digits[10] - 'a' + 'x'
295 // TODO: Avoid buffer by pre-padding.
296 var buf []byte
297 for i := 0; i < n; i++ {
298 if i > 0 && f.space {
299 buf = append(buf, ' ')
301 if f.sharp {
302 buf = append(buf, '0', x)
304 var c byte
305 if b == nil {
306 c = s[i]
307 } else {
308 c = b[i]
310 buf = append(buf, digits[c>>4], digits[c&0xF])
312 f.pad(buf)
315 // fmt_sx formats a string as a hexadecimal encoding of its bytes.
316 func (f *fmt) fmt_sx(s, digits string) {
317 f.fmt_sbx(s, nil, digits)
320 // fmt_bx formats a byte slice as a hexadecimal encoding of its bytes.
321 func (f *fmt) fmt_bx(b []byte, digits string) {
322 f.fmt_sbx("", b, digits)
325 // fmt_q formats a string as a double-quoted, escaped Go string constant.
326 func (f *fmt) fmt_q(s string) {
327 s = f.truncate(s)
328 var quoted string
329 if f.sharp && strconv.CanBackquote(s) {
330 quoted = "`" + s + "`"
331 } else {
332 if f.plus {
333 quoted = strconv.QuoteToASCII(s)
334 } else {
335 quoted = strconv.Quote(s)
338 f.padString(quoted)
341 // fmt_qc formats the integer as a single-quoted, escaped Go character constant.
342 // If the character is not valid Unicode, it will print '\ufffd'.
343 func (f *fmt) fmt_qc(c int64) {
344 var quoted []byte
345 if f.plus {
346 quoted = strconv.AppendQuoteRuneToASCII(f.intbuf[0:0], rune(c))
347 } else {
348 quoted = strconv.AppendQuoteRune(f.intbuf[0:0], rune(c))
350 f.pad(quoted)
353 // floating-point
355 func doPrec(f *fmt, def int) int {
356 if f.precPresent {
357 return f.prec
359 return def
362 // formatFloat formats a float64; it is an efficient equivalent to f.pad(strconv.FormatFloat()...).
363 func (f *fmt) formatFloat(v float64, verb byte, prec, n int) {
364 // Format number, reserving space for leading + sign if needed.
365 num := strconv.AppendFloat(f.intbuf[0:1], v, verb, prec, n)
366 if num[1] == '-' || num[1] == '+' {
367 num = num[1:]
368 } else {
369 num[0] = '+'
371 // Special handling for infinity, which doesn't look like a number so shouldn't be padded with zeros.
372 if math.IsInf(v, 0) {
373 if f.zero {
374 defer func() { f.zero = true }()
375 f.zero = false
378 // num is now a signed version of the number.
379 // If we're zero padding, want the sign before the leading zeros.
380 // Achieve this by writing the sign out and then padding the unsigned number.
381 if f.zero && f.widPresent && f.wid > len(num) {
382 if f.space && v >= 0 {
383 f.buf.WriteByte(' ') // This is what C does: even with zero, f.space means space.
384 f.wid--
385 } else if f.plus || v < 0 {
386 f.buf.WriteByte(num[0])
387 f.wid--
389 f.pad(num[1:])
390 return
392 // f.space says to replace a leading + with a space.
393 if f.space && num[0] == '+' {
394 num[0] = ' '
395 f.pad(num)
396 return
398 // Now we know the sign is attached directly to the number, if present at all.
399 // We want a sign if asked for, if it's negative, or if it's infinity (+Inf vs. -Inf).
400 if f.plus || num[0] == '-' || math.IsInf(v, 0) {
401 f.pad(num)
402 return
404 // No sign to show and the number is positive; just print the unsigned number.
405 f.pad(num[1:])
408 // fmt_e64 formats a float64 in the form -1.23e+12.
409 func (f *fmt) fmt_e64(v float64) { f.formatFloat(v, 'e', doPrec(f, 6), 64) }
411 // fmt_E64 formats a float64 in the form -1.23E+12.
412 func (f *fmt) fmt_E64(v float64) { f.formatFloat(v, 'E', doPrec(f, 6), 64) }
414 // fmt_f64 formats a float64 in the form -1.23.
415 func (f *fmt) fmt_f64(v float64) { f.formatFloat(v, 'f', doPrec(f, 6), 64) }
417 // fmt_g64 formats a float64 in the 'f' or 'e' form according to size.
418 func (f *fmt) fmt_g64(v float64) { f.formatFloat(v, 'g', doPrec(f, -1), 64) }
420 // fmt_G64 formats a float64 in the 'f' or 'E' form according to size.
421 func (f *fmt) fmt_G64(v float64) { f.formatFloat(v, 'G', doPrec(f, -1), 64) }
423 // fmt_fb64 formats a float64 in the form -123p3 (exponent is power of 2).
424 func (f *fmt) fmt_fb64(v float64) { f.formatFloat(v, 'b', 0, 64) }
426 // float32
427 // cannot defer to float64 versions
428 // because it will get rounding wrong in corner cases.
430 // fmt_e32 formats a float32 in the form -1.23e+12.
431 func (f *fmt) fmt_e32(v float32) { f.formatFloat(float64(v), 'e', doPrec(f, 6), 32) }
433 // fmt_E32 formats a float32 in the form -1.23E+12.
434 func (f *fmt) fmt_E32(v float32) { f.formatFloat(float64(v), 'E', doPrec(f, 6), 32) }
436 // fmt_f32 formats a float32 in the form -1.23.
437 func (f *fmt) fmt_f32(v float32) { f.formatFloat(float64(v), 'f', doPrec(f, 6), 32) }
439 // fmt_g32 formats a float32 in the 'f' or 'e' form according to size.
440 func (f *fmt) fmt_g32(v float32) { f.formatFloat(float64(v), 'g', doPrec(f, -1), 32) }
442 // fmt_G32 formats a float32 in the 'f' or 'E' form according to size.
443 func (f *fmt) fmt_G32(v float32) { f.formatFloat(float64(v), 'G', doPrec(f, -1), 32) }
445 // fmt_fb32 formats a float32 in the form -123p3 (exponent is power of 2).
446 func (f *fmt) fmt_fb32(v float32) { f.formatFloat(float64(v), 'b', 0, 32) }
448 // fmt_c64 formats a complex64 according to the verb.
449 func (f *fmt) fmt_c64(v complex64, verb rune) {
450 f.fmt_complex(float64(real(v)), float64(imag(v)), 32, verb)
453 // fmt_c128 formats a complex128 according to the verb.
454 func (f *fmt) fmt_c128(v complex128, verb rune) {
455 f.fmt_complex(real(v), imag(v), 64, verb)
458 // fmt_complex formats a complex number as (r+ji).
459 func (f *fmt) fmt_complex(r, j float64, size int, verb rune) {
460 f.buf.WriteByte('(')
461 oldPlus := f.plus
462 oldSpace := f.space
463 oldWid := f.wid
464 for i := 0; ; i++ {
465 switch verb {
466 case 'b':
467 f.formatFloat(r, 'b', 0, size)
468 case 'e':
469 f.formatFloat(r, 'e', doPrec(f, 6), size)
470 case 'E':
471 f.formatFloat(r, 'E', doPrec(f, 6), size)
472 case 'f', 'F':
473 f.formatFloat(r, 'f', doPrec(f, 6), size)
474 case 'g':
475 f.formatFloat(r, 'g', doPrec(f, -1), size)
476 case 'G':
477 f.formatFloat(r, 'G', doPrec(f, -1), size)
479 if i != 0 {
480 break
482 // Imaginary part always has a sign.
483 f.plus = true
484 f.space = false
485 f.wid = oldWid
486 r = j
488 f.space = oldSpace
489 f.plus = oldPlus
490 f.wid = oldWid
491 f.buf.Write(irparenBytes)