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.
14 // %b of an int64, plus a sign.
15 // Hex can add 0x and we handle it specially.
18 ldigits
= "0123456789abcdef"
19 udigits
= "0123456789ABCDEF"
27 var padZeroBytes
= make([]byte, nByte
)
28 var padSpaceBytes
= make([]byte, nByte
)
31 for i
:= 0; i
< nByte
; i
++ {
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.
53 uniQuote
bool // Use 'x'= prefix for %U if printable.
57 func (f
*fmt
) clearflags() {
71 func (f
*fmt
) init(buf
*buffer
) {
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) {
87 return padZeroBytes
, w
, 0
90 return padSpaceBytes
, w
, 0
92 // can't be zero padding on the right
93 return padSpaceBytes
, 0, w
99 // writePadding generates n bytes of padding.
100 func (f
*fmt
) writePadding(n
int, padding
[]byte) {
106 f
.buf
.Write(padding
[0: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 {
117 padding
, left
, right
:= f
.computePadding(len(b
))
119 f
.writePadding(left
, padding
)
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 {
133 padding
, left
, right
:= f
.computePadding(utf8
.RuneCountInString(s
))
135 f
.writePadding(left
, padding
)
139 f
.writePadding(right
, padding
)
144 trueBytes
= []byte("true")
145 falseBytes
= []byte("false")
148 // fmt_boolean formats a boolean.
149 func (f
*fmt
) fmt_boolean(v
bool) {
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 {
165 var buf
[]byte = f
.intbuf
[0:]
168 if base
== 16 && f
.sharp
{
173 // We're going to need a bigger boat.
174 buf
= make([]byte, width
)
178 negative
:= signedness
== signed
&& a
< 0
183 // two ways to ask for extra leading zero digits: %.3d or %03d.
184 // apparently the first cancels the second.
189 } else if f
.zero
&& f
.widPresent
&& !f
.minus
&& f
.wid
> 0 {
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.
204 buf
[i
] = digits
[ua%base
]
209 for i
> 0 && prec
> len(buf
)-i
{
214 // Various prefixes: 0x, -, etc.
224 buf
[i
] = 'x' + digits
[10] - 'a'
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.
253 // Now put " 'x'" at the end.
254 j
:= len(buf
) - width
259 utf8
.EncodeRune(buf
[j
:], rune(a
))
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
) {
282 // fmt_s formats a string.
283 func (f
*fmt
) fmt_s(s
string) {
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) {
294 x
:= digits
[10] - 'a' + 'x'
295 // TODO: Avoid buffer by pre-padding.
297 for i
:= 0; i
< n
; i
++ {
298 if i
> 0 && f
.space
{
299 buf
= append(buf
, ' ')
302 buf
= append(buf
, '0', x
)
310 buf
= append(buf
, digits
[c
>>4], digits
[c
&0xF])
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) {
329 if f
.sharp
&& strconv
.CanBackquote(s
) {
330 quoted
= "`" + s
+ "`"
333 quoted
= strconv
.QuoteToASCII(s
)
335 quoted
= strconv
.Quote(s
)
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) {
346 quoted
= strconv
.AppendQuoteRuneToASCII(f
.intbuf
[0:0], rune(c
))
348 quoted
= strconv
.AppendQuoteRune(f
.intbuf
[0:0], rune(c
))
355 func doPrec(f
*fmt
, def
int) int {
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] == '+' {
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) {
374 defer func() { f
.zero
= true }()
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.
385 } else if f
.plus || v
< 0 {
386 f
.buf
.WriteByte(num
[0])
392 // f.space says to replace a leading + with a space.
393 if f
.space
&& num
[0] == '+' {
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) {
404 // No sign to show and the number is positive; just print the unsigned number.
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) }
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
) {
467 f
.formatFloat(r
, 'b', 0, size
)
469 f
.formatFloat(r
, 'e', doPrec(f
, 6), size
)
471 f
.formatFloat(r
, 'E', doPrec(f
, 6), size
)
473 f
.formatFloat(r
, 'f', doPrec(f
, 6), size
)
475 f
.formatFloat(r
, 'g', doPrec(f
, -1), size
)
477 f
.formatFloat(r
, 'G', doPrec(f
, -1), size
)
482 // Imaginary part always has a sign.
491 f
.buf
.Write(irparenBytes
)