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
5package fmt
6
7import (
8	"math"
9	"strconv"
10	"unicode/utf8"
11)
12
13const (
14	// %b of an int64, plus a sign.
15	// Hex can add 0x and we handle it specially.
16	nByte = 65
17
18	ldigits = "0123456789abcdef"
19	udigits = "0123456789ABCDEF"
20)
21
22const (
23	signed   = true
24	unsigned = false
25)
26
27var padZeroBytes = make([]byte, nByte)
28var padSpaceBytes = make([]byte, nByte)
29
30func init() {
31	for i := 0; i < nByte; i++ {
32		padZeroBytes[i] = '0'
33		padSpaceBytes[i] = ' '
34	}
35}
36
37// flags placed in a separate struct for easy clearing.
38type 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
48
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
54}
55
56// A fmt is the raw formatter used by Printf etc.
57// It prints into a buffer that must be set up separately.
58type fmt struct {
59	intbuf [nByte]byte
60	buf    *buffer
61	// width, precision
62	wid  int
63	prec int
64	fmtFlags
65}
66
67func (f *fmt) clearflags() {
68	f.fmtFlags = fmtFlags{}
69}
70
71func (f *fmt) init(buf *buffer) {
72	f.buf = buf
73	f.clearflags()
74}
75
76// computePadding computes left and right padding widths (only one will be non-zero).
77func (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
83	}
84	w -= width
85	if w > 0 {
86		if left && f.zero {
87			return padZeroBytes, w, 0
88		}
89		if left {
90			return padSpaceBytes, w, 0
91		} else {
92			// can't be zero padding on the right
93			return padSpaceBytes, 0, w
94		}
95	}
96	return
97}
98
99// writePadding generates n bytes of padding.
100func (f *fmt) writePadding(n int, padding []byte) {
101	for n > 0 {
102		m := n
103		if m > nByte {
104			m = nByte
105		}
106		f.buf.Write(padding[0:m])
107		n -= m
108	}
109}
110
111// pad appends b to f.buf, padded on left (w > 0) or right (w < 0 or f.minus).
112func (f *fmt) pad(b []byte) {
113	if !f.widPresent || f.wid == 0 {
114		f.buf.Write(b)
115		return
116	}
117	padding, left, right := f.computePadding(utf8.RuneCount(b))
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// padString appends s to buf, padded on left (w > 0) or right (w < 0 or f.minus).
128func (f *fmt) padString(s string) {
129	if !f.widPresent || f.wid == 0 {
130		f.buf.WriteString(s)
131		return
132	}
133	padding, left, right := f.computePadding(utf8.RuneCountInString(s))
134	if left > 0 {
135		f.writePadding(left, padding)
136	}
137	f.buf.WriteString(s)
138	if right > 0 {
139		f.writePadding(right, padding)
140	}
141}
142
143var (
144	trueBytes  = []byte("true")
145	falseBytes = []byte("false")
146)
147
148// fmt_boolean formats a boolean.
149func (f *fmt) fmt_boolean(v bool) {
150	if v {
151		f.pad(trueBytes)
152	} else {
153		f.pad(falseBytes)
154	}
155}
156
157// integer; interprets prec but not wid.  Once formatted, result is sent to pad()
158// and then flags are cleared.
159func (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
163	}
164
165	negative := signedness == signed && a < 0
166	if negative {
167		a = -a
168	}
169
170	var buf []byte = f.intbuf[0:]
171	if f.widPresent || f.precPresent || f.plus || f.space {
172		width := f.wid + f.prec // Only one will be set, both are positive; this provides the maximum.
173		if base == 16 && f.sharp {
174			// Also adds "0x".
175			width += 2
176		}
177		if f.unicode {
178			// Also adds "U+".
179			width += 2
180			if f.uniQuote {
181				// Also adds " 'x'".
182				width += 1 + 1 + utf8.UTFMax + 1
183			}
184		}
185		if negative || f.plus || f.space {
186			width++
187		}
188		if width > nByte {
189			// We're going to need a bigger boat.
190			buf = make([]byte, width)
191		}
192	}
193
194	// two ways to ask for extra leading zero digits: %.3d or %03d.
195	// apparently the first cancels the second.
196	prec := 0
197	if f.precPresent {
198		prec = f.prec
199		f.zero = false
200	} else if f.zero && f.widPresent && !f.minus && f.wid > 0 {
201		prec = f.wid
202		if negative || f.plus || f.space {
203			prec-- // leave room for sign
204		}
205	}
206
207	// format a into buf, ending at buf[i].  (printing is easier right-to-left.)
208	// a is made into unsigned ua.  we could make things
209	// marginally faster by splitting the 32-bit case out into a separate
210	// block but it's not worth the duplication, so ua has 64 bits.
211	i := len(buf)
212	ua := uint64(a)
213	// use constants for the division and modulo for more efficient code.
214	// switch cases ordered by popularity.
215	switch base {
216	case 10:
217		for ua >= 10 {
218			i--
219			next := ua / 10
220			buf[i] = byte('0' + ua - next*10)
221			ua = next
222		}
223	case 16:
224		for ua >= 16 {
225			i--
226			buf[i] = digits[ua&0xF]
227			ua >>= 4
228		}
229	case 8:
230		for ua >= 8 {
231			i--
232			buf[i] = byte('0' + ua&7)
233			ua >>= 3
234		}
235	case 2:
236		for ua >= 2 {
237			i--
238			buf[i] = byte('0' + ua&1)
239			ua >>= 1
240		}
241	default:
242		panic("fmt: unknown base; can't happen")
243	}
244	i--
245	buf[i] = digits[ua]
246	for i > 0 && prec > len(buf)-i {
247		i--
248		buf[i] = '0'
249	}
250
251	// Various prefixes: 0x, -, etc.
252	if f.sharp {
253		switch base {
254		case 8:
255			if buf[i] != '0' {
256				i--
257				buf[i] = '0'
258			}
259		case 16:
260			i--
261			buf[i] = 'x' + digits[10] - 'a'
262			i--
263			buf[i] = '0'
264		}
265	}
266	if f.unicode {
267		i--
268		buf[i] = '+'
269		i--
270		buf[i] = 'U'
271	}
272
273	if negative {
274		i--
275		buf[i] = '-'
276	} else if f.plus {
277		i--
278		buf[i] = '+'
279	} else if f.space {
280		i--
281		buf[i] = ' '
282	}
283
284	// If we want a quoted char for %#U, move the data up to make room.
285	if f.unicode && f.uniQuote && a >= 0 && a <= utf8.MaxRune && strconv.IsPrint(rune(a)) {
286		runeWidth := utf8.RuneLen(rune(a))
287		width := 1 + 1 + runeWidth + 1 // space, quote, rune, quote
288		copy(buf[i-width:], buf[i:])   // guaranteed to have enough room.
289		i -= width
290		// Now put " 'x'" at the end.
291		j := len(buf) - width
292		buf[j] = ' '
293		j++
294		buf[j] = '\''
295		j++
296		utf8.EncodeRune(buf[j:], rune(a))
297		j += runeWidth
298		buf[j] = '\''
299	}
300
301	f.pad(buf[i:])
302}
303
304// truncate truncates the string to the specified precision, if present.
305func (f *fmt) truncate(s string) string {
306	if f.precPresent && f.prec < utf8.RuneCountInString(s) {
307		n := f.prec
308		for i := range s {
309			if n == 0 {
310				s = s[:i]
311				break
312			}
313			n--
314		}
315	}
316	return s
317}
318
319// fmt_s formats a string.
320func (f *fmt) fmt_s(s string) {
321	s = f.truncate(s)
322	f.padString(s)
323}
324
325// fmt_sbx formats a string or byte slice as a hexadecimal encoding of its bytes.
326func (f *fmt) fmt_sbx(s string, b []byte, digits string) {
327	n := len(b)
328	if b == nil {
329		n = len(s)
330	}
331	x := digits[10] - 'a' + 'x'
332	// TODO: Avoid buffer by pre-padding.
333	var buf []byte
334	for i := 0; i < n; i++ {
335		if i > 0 && f.space {
336			buf = append(buf, ' ')
337		}
338		if f.sharp && (f.space || i == 0) {
339			buf = append(buf, '0', x)
340		}
341		var c byte
342		if b == nil {
343			c = s[i]
344		} else {
345			c = b[i]
346		}
347		buf = append(buf, digits[c>>4], digits[c&0xF])
348	}
349	f.pad(buf)
350}
351
352// fmt_sx formats a string as a hexadecimal encoding of its bytes.
353func (f *fmt) fmt_sx(s, digits string) {
354	if f.precPresent && f.prec < len(s) {
355		s = s[:f.prec]
356	}
357	f.fmt_sbx(s, nil, digits)
358}
359
360// fmt_bx formats a byte slice as a hexadecimal encoding of its bytes.
361func (f *fmt) fmt_bx(b []byte, digits string) {
362	if f.precPresent && f.prec < len(b) {
363		b = b[:f.prec]
364	}
365	f.fmt_sbx("", b, digits)
366}
367
368// fmt_q formats a string as a double-quoted, escaped Go string constant.
369func (f *fmt) fmt_q(s string) {
370	s = f.truncate(s)
371	var quoted string
372	if f.sharp && strconv.CanBackquote(s) {
373		quoted = "`" + s + "`"
374	} else {
375		if f.plus {
376			quoted = strconv.QuoteToASCII(s)
377		} else {
378			quoted = strconv.Quote(s)
379		}
380	}
381	f.padString(quoted)
382}
383
384// fmt_qc formats the integer as a single-quoted, escaped Go character constant.
385// If the character is not valid Unicode, it will print '\ufffd'.
386func (f *fmt) fmt_qc(c int64) {
387	var quoted []byte
388	if f.plus {
389		quoted = strconv.AppendQuoteRuneToASCII(f.intbuf[0:0], rune(c))
390	} else {
391		quoted = strconv.AppendQuoteRune(f.intbuf[0:0], rune(c))
392	}
393	f.pad(quoted)
394}
395
396// floating-point
397
398func doPrec(f *fmt, def int) int {
399	if f.precPresent {
400		return f.prec
401	}
402	return def
403}
404
405// formatFloat formats a float64; it is an efficient equivalent to  f.pad(strconv.FormatFloat()...).
406func (f *fmt) formatFloat(v float64, verb byte, prec, n int) {
407	// Format number, reserving space for leading + sign if needed.
408	num := strconv.AppendFloat(f.intbuf[0:1], v, verb, prec, n)
409	if num[1] == '-' || num[1] == '+' {
410		num = num[1:]
411	} else {
412		num[0] = '+'
413	}
414	// Special handling for infinity, which doesn't look like a number so shouldn't be padded with zeros.
415	if math.IsInf(v, 0) {
416		if f.zero {
417			defer func() { f.zero = true }()
418			f.zero = false
419		}
420	}
421	// num is now a signed version of the number.
422	// If we're zero padding, want the sign before the leading zeros.
423	// Achieve this by writing the sign out and then padding the unsigned number.
424	if f.zero && f.widPresent && f.wid > len(num) {
425		if f.space && v >= 0 {
426			f.buf.WriteByte(' ') // This is what C does: even with zero, f.space means space.
427			f.wid--
428		} else if f.plus || v < 0 {
429			f.buf.WriteByte(num[0])
430			f.wid--
431		}
432		f.pad(num[1:])
433		return
434	}
435	// f.space says to replace a leading + with a space.
436	if f.space && num[0] == '+' {
437		num[0] = ' '
438		f.pad(num)
439		return
440	}
441	// Now we know the sign is attached directly to the number, if present at all.
442	// We want a sign if asked for, if it's negative, or if it's infinity (+Inf vs. -Inf).
443	if f.plus || num[0] == '-' || math.IsInf(v, 0) {
444		f.pad(num)
445		return
446	}
447	// No sign to show and the number is positive; just print the unsigned number.
448	f.pad(num[1:])
449}
450
451// fmt_e64 formats a float64 in the form -1.23e+12.
452func (f *fmt) fmt_e64(v float64) { f.formatFloat(v, 'e', doPrec(f, 6), 64) }
453
454// fmt_E64 formats a float64 in the form -1.23E+12.
455func (f *fmt) fmt_E64(v float64) { f.formatFloat(v, 'E', doPrec(f, 6), 64) }
456
457// fmt_f64 formats a float64 in the form -1.23.
458func (f *fmt) fmt_f64(v float64) { f.formatFloat(v, 'f', doPrec(f, 6), 64) }
459
460// fmt_g64 formats a float64 in the 'f' or 'e' form according to size.
461func (f *fmt) fmt_g64(v float64) { f.formatFloat(v, 'g', doPrec(f, -1), 64) }
462
463// fmt_G64 formats a float64 in the 'f' or 'E' form according to size.
464func (f *fmt) fmt_G64(v float64) { f.formatFloat(v, 'G', doPrec(f, -1), 64) }
465
466// fmt_fb64 formats a float64 in the form -123p3 (exponent is power of 2).
467func (f *fmt) fmt_fb64(v float64) { f.formatFloat(v, 'b', 0, 64) }
468
469// float32
470// cannot defer to float64 versions
471// because it will get rounding wrong in corner cases.
472
473// fmt_e32 formats a float32 in the form -1.23e+12.
474func (f *fmt) fmt_e32(v float32) { f.formatFloat(float64(v), 'e', doPrec(f, 6), 32) }
475
476// fmt_E32 formats a float32 in the form -1.23E+12.
477func (f *fmt) fmt_E32(v float32) { f.formatFloat(float64(v), 'E', doPrec(f, 6), 32) }
478
479// fmt_f32 formats a float32 in the form -1.23.
480func (f *fmt) fmt_f32(v float32) { f.formatFloat(float64(v), 'f', doPrec(f, 6), 32) }
481
482// fmt_g32 formats a float32 in the 'f' or 'e' form according to size.
483func (f *fmt) fmt_g32(v float32) { f.formatFloat(float64(v), 'g', doPrec(f, -1), 32) }
484
485// fmt_G32 formats a float32 in the 'f' or 'E' form according to size.
486func (f *fmt) fmt_G32(v float32) { f.formatFloat(float64(v), 'G', doPrec(f, -1), 32) }
487
488// fmt_fb32 formats a float32 in the form -123p3 (exponent is power of 2).
489func (f *fmt) fmt_fb32(v float32) { f.formatFloat(float64(v), 'b', 0, 32) }
490
491// fmt_c64 formats a complex64 according to the verb.
492func (f *fmt) fmt_c64(v complex64, verb rune) {
493	f.fmt_complex(float64(real(v)), float64(imag(v)), 32, verb)
494}
495
496// fmt_c128 formats a complex128 according to the verb.
497func (f *fmt) fmt_c128(v complex128, verb rune) {
498	f.fmt_complex(real(v), imag(v), 64, verb)
499}
500
501// fmt_complex formats a complex number as (r+ji).
502func (f *fmt) fmt_complex(r, j float64, size int, verb rune) {
503	f.buf.WriteByte('(')
504	oldPlus := f.plus
505	oldSpace := f.space
506	oldWid := f.wid
507	for i := 0; ; i++ {
508		switch verb {
509		case 'b':
510			f.formatFloat(r, 'b', 0, size)
511		case 'e':
512			f.formatFloat(r, 'e', doPrec(f, 6), size)
513		case 'E':
514			f.formatFloat(r, 'E', doPrec(f, 6), size)
515		case 'f', 'F':
516			f.formatFloat(r, 'f', doPrec(f, 6), size)
517		case 'g':
518			f.formatFloat(r, 'g', doPrec(f, -1), size)
519		case 'G':
520			f.formatFloat(r, 'G', doPrec(f, -1), size)
521		}
522		if i != 0 {
523			break
524		}
525		// Imaginary part always has a sign.
526		f.plus = true
527		f.space = false
528		f.wid = oldWid
529		r = j
530	}
531	f.space = oldSpace
532	f.plus = oldPlus
533	f.wid = oldWid
534	f.buf.Write(irparenBytes)
535}
536