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 // flags placed in a separate struct for easy clearing.
38 type fmtFlags
struct {
46 uniQuote
bool // Use 'x'= prefix for %U if printable.
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.
56 // A fmt is the raw formatter used by Printf etc.
57 // It prints into a buffer that must be set up separately.
67 func (f
*fmt
) clearflags() {
68 f
.fmtFlags
= fmtFlags
{}
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(utf8
.RuneCount(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.
202 // use constants for the division and modulo for more efficient code.
203 // switch cases ordered by popularity.
209 buf
[i
] = byte('0' + ua
- next
*10)
215 buf
[i
] = digits
[ua
&0xF]
221 buf
[i
] = byte('0' + ua
&7)
227 buf
[i
] = byte('0' + ua
&1)
231 panic("fmt: unknown base; can't happen")
235 for i
> 0 && prec
> len(buf
)-i
{
240 // Various prefixes: 0x, -, etc.
250 buf
[i
] = 'x' + digits
[10] - 'a'
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.
279 // Now put " 'x'" at the end.
280 j
:= len(buf
) - width
285 utf8
.EncodeRune(buf
[j
:], rune(a
))
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
) {
308 // fmt_s formats a string.
309 func (f
*fmt
) fmt_s(s
string) {
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) {
320 x
:= digits
[10] - 'a' + 'x'
321 // TODO: Avoid buffer by pre-padding.
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
)
336 buf
= append(buf
, digits
[c
>>4], digits
[c
&0xF])
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
) {
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
) {
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) {
361 if f
.sharp
&& strconv
.CanBackquote(s
) {
362 quoted
= "`" + s
+ "`"
365 quoted
= strconv
.QuoteToASCII(s
)
367 quoted
= strconv
.Quote(s
)
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) {
378 quoted
= strconv
.AppendQuoteRuneToASCII(f
.intbuf
[0:0], rune(c
))
380 quoted
= strconv
.AppendQuoteRune(f
.intbuf
[0:0], rune(c
))
387 func doPrec(f
*fmt
, def
int) int {
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] == '+' {
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) {
406 defer func() { f
.zero
= true }()
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.
417 } else if f
.plus || v
< 0 {
418 f
.buf
.WriteByte(num
[0])
424 // f.space says to replace a leading + with a space.
425 if f
.space
&& num
[0] == '+' {
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) {
436 // No sign to show and the number is positive; just print the unsigned number.
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) }
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
) {
499 f
.formatFloat(r
, 'b', 0, size
)
501 f
.formatFloat(r
, 'e', doPrec(f
, 6), size
)
503 f
.formatFloat(r
, 'E', doPrec(f
, 6), size
)
505 f
.formatFloat(r
, 'f', doPrec(f
, 6), size
)
507 f
.formatFloat(r
, 'g', doPrec(f
, -1), size
)
509 f
.formatFloat(r
, 'G', doPrec(f
, -1), size
)
514 // Imaginary part always has a sign.
523 f
.buf
.Write(irparenBytes
)