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 }