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	"strconv"
9	"unicode/utf8"
10)
11
12const (
13	ldigits = "0123456789abcdefx"
14	udigits = "0123456789ABCDEFX"
15)
16
17const (
18	signed   = true
19	unsigned = false
20)
21
22// flags placed in a separate struct for easy clearing.
23type fmtFlags struct {
24	widPresent  bool
25	precPresent bool
26	minus       bool
27	plus        bool
28	sharp       bool
29	space       bool
30	zero        bool
31
32	// For the formats %+v %#v, we set the plusV/sharpV flags
33	// and clear the plus/sharp flags since %+v and %#v are in effect
34	// different, flagless formats set at the top level.
35	plusV  bool
36	sharpV bool
37}
38
39// A fmt is the raw formatter used by Printf etc.
40// It prints into a buffer that must be set up separately.
41type fmt struct {
42	buf *buffer
43
44	fmtFlags
45
46	wid  int // width
47	prec int // precision
48
49	// intbuf is large enough to store %b of an int64 with a sign and
50	// avoids padding at the end of the struct on 32 bit architectures.
51	intbuf [68]byte
52}
53
54func (f *fmt) clearflags() {
55	f.fmtFlags = fmtFlags{}
56	f.wid = 0
57	f.prec = 0
58}
59
60func (f *fmt) init(buf *buffer) {
61	f.buf = buf
62	f.clearflags()
63}
64
65// writePadding generates n bytes of padding.
66func (f *fmt) writePadding(n int) {
67	if n <= 0 { // No padding bytes needed.
68		return
69	}
70	buf := *f.buf
71	oldLen := len(buf)
72	newLen := oldLen + n
73	// Make enough room for padding.
74	if newLen > cap(buf) {
75		buf = make(buffer, cap(buf)*2+n)
76		copy(buf, *f.buf)
77	}
78	// Decide which byte the padding should be filled with.
79	padByte := byte(' ')
80	// Zero padding is allowed only to the left.
81	if f.zero && !f.minus {
82		padByte = byte('0')
83	}
84	// Fill padding with padByte.
85	padding := buf[oldLen:newLen]
86	for i := range padding {
87		padding[i] = padByte
88	}
89	*f.buf = buf[:newLen]
90}
91
92// pad appends b to f.buf, padded on left (!f.minus) or right (f.minus).
93func (f *fmt) pad(b []byte) {
94	if !f.widPresent || f.wid == 0 {
95		f.buf.write(b)
96		return
97	}
98	width := f.wid - utf8.RuneCount(b)
99	if !f.minus {
100		// left padding
101		f.writePadding(width)
102		f.buf.write(b)
103	} else {
104		// right padding
105		f.buf.write(b)
106		f.writePadding(width)
107	}
108}
109
110// padString appends s to f.buf, padded on left (!f.minus) or right (f.minus).
111func (f *fmt) padString(s string) {
112	if !f.widPresent || f.wid == 0 {
113		f.buf.writeString(s)
114		return
115	}
116	width := f.wid - utf8.RuneCountInString(s)
117	if !f.minus {
118		// left padding
119		f.writePadding(width)
120		f.buf.writeString(s)
121	} else {
122		// right padding
123		f.buf.writeString(s)
124		f.writePadding(width)
125	}
126}
127
128// fmtBoolean formats a boolean.
129func (f *fmt) fmtBoolean(v bool) {
130	if v {
131		f.padString("true")
132	} else {
133		f.padString("false")
134	}
135}
136
137// fmtUnicode formats a uint64 as "U+0078" or with f.sharp set as "U+0078 'x'".
138func (f *fmt) fmtUnicode(u uint64) {
139	buf := f.intbuf[0:]
140
141	// With default precision set the maximum needed buf length is 18
142	// for formatting -1 with %#U ("U+FFFFFFFFFFFFFFFF") which fits
143	// into the already allocated intbuf with a capacity of 68 bytes.
144	prec := 4
145	if f.precPresent && f.prec > 4 {
146		prec = f.prec
147		// Compute space needed for "U+" , number, " '", character, "'".
148		width := 2 + prec + 2 + utf8.UTFMax + 1
149		if width > len(buf) {
150			buf = make([]byte, width)
151		}
152	}
153
154	// Format into buf, ending at buf[i]. Formatting numbers is easier right-to-left.
155	i := len(buf)
156
157	// For %#U we want to add a space and a quoted character at the end of the buffer.
158	if f.sharp && u <= utf8.MaxRune && strconv.IsPrint(rune(u)) {
159		i--
160		buf[i] = '\''
161		i -= utf8.RuneLen(rune(u))
162		utf8.EncodeRune(buf[i:], rune(u))
163		i--
164		buf[i] = '\''
165		i--
166		buf[i] = ' '
167	}
168	// Format the Unicode code point u as a hexadecimal number.
169	for u >= 16 {
170		i--
171		buf[i] = udigits[u&0xF]
172		prec--
173		u >>= 4
174	}
175	i--
176	buf[i] = udigits[u]
177	prec--
178	// Add zeros in front of the number until requested precision is reached.
179	for prec > 0 {
180		i--
181		buf[i] = '0'
182		prec--
183	}
184	// Add a leading "U+".
185	i--
186	buf[i] = '+'
187	i--
188	buf[i] = 'U'
189
190	oldZero := f.zero
191	f.zero = false
192	f.pad(buf[i:])
193	f.zero = oldZero
194}
195
196// fmtInteger formats signed and unsigned integers.
197func (f *fmt) fmtInteger(u uint64, base int, isSigned bool, verb rune, digits string) {
198	negative := isSigned && int64(u) < 0
199	if negative {
200		u = -u
201	}
202
203	buf := f.intbuf[0:]
204	// The already allocated f.intbuf with a capacity of 68 bytes
205	// is large enough for integer formatting when no precision or width is set.
206	if f.widPresent || f.precPresent {
207		// Account 3 extra bytes for possible addition of a sign and "0x".
208		width := 3 + f.wid + f.prec // wid and prec are always positive.
209		if width > len(buf) {
210			// We're going to need a bigger boat.
211			buf = make([]byte, width)
212		}
213	}
214
215	// Two ways to ask for extra leading zero digits: %.3d or %03d.
216	// If both are specified the f.zero flag is ignored and
217	// padding with spaces is used instead.
218	prec := 0
219	if f.precPresent {
220		prec = f.prec
221		// Precision of 0 and value of 0 means "print nothing" but padding.
222		if prec == 0 && u == 0 {
223			oldZero := f.zero
224			f.zero = false
225			f.writePadding(f.wid)
226			f.zero = oldZero
227			return
228		}
229	} else if f.zero && !f.minus && f.widPresent { // Zero padding is allowed only to the left.
230		prec = f.wid
231		if negative || f.plus || f.space {
232			prec-- // leave room for sign
233		}
234	}
235
236	// Because printing is easier right-to-left: format u into buf, ending at buf[i].
237	// We could make things marginally faster by splitting the 32-bit case out
238	// into a separate block but it's not worth the duplication, so u has 64 bits.
239	i := len(buf)
240	// Use constants for the division and modulo for more efficient code.
241	// Switch cases ordered by popularity.
242	switch base {
243	case 10:
244		for u >= 10 {
245			i--
246			next := u / 10
247			buf[i] = byte('0' + u - next*10)
248			u = next
249		}
250	case 16:
251		for u >= 16 {
252			i--
253			buf[i] = digits[u&0xF]
254			u >>= 4
255		}
256	case 8:
257		for u >= 8 {
258			i--
259			buf[i] = byte('0' + u&7)
260			u >>= 3
261		}
262	case 2:
263		for u >= 2 {
264			i--
265			buf[i] = byte('0' + u&1)
266			u >>= 1
267		}
268	default:
269		panic("fmt: unknown base; can't happen")
270	}
271	i--
272	buf[i] = digits[u]
273	for i > 0 && prec > len(buf)-i {
274		i--
275		buf[i] = '0'
276	}
277
278	// Various prefixes: 0x, -, etc.
279	if f.sharp {
280		switch base {
281		case 2:
282			// Add a leading 0b.
283			i--
284			buf[i] = 'b'
285			i--
286			buf[i] = '0'
287		case 8:
288			if buf[i] != '0' {
289				i--
290				buf[i] = '0'
291			}
292		case 16:
293			// Add a leading 0x or 0X.
294			i--
295			buf[i] = digits[16]
296			i--
297			buf[i] = '0'
298		}
299	}
300	if verb == 'O' {
301		i--
302		buf[i] = 'o'
303		i--
304		buf[i] = '0'
305	}
306
307	if negative {
308		i--
309		buf[i] = '-'
310	} else if f.plus {
311		i--
312		buf[i] = '+'
313	} else if f.space {
314		i--
315		buf[i] = ' '
316	}
317
318	// Left padding with zeros has already been handled like precision earlier
319	// or the f.zero flag is ignored due to an explicitly set precision.
320	oldZero := f.zero
321	f.zero = false
322	f.pad(buf[i:])
323	f.zero = oldZero
324}
325
326// truncateString truncates the string s to the specified precision, if present.
327func (f *fmt) truncateString(s string) string {
328	if f.precPresent {
329		n := f.prec
330		for i := range s {
331			n--
332			if n < 0 {
333				return s[:i]
334			}
335		}
336	}
337	return s
338}
339
340// truncate truncates the byte slice b as a string of the specified precision, if present.
341func (f *fmt) truncate(b []byte) []byte {
342	if f.precPresent {
343		n := f.prec
344		for i := 0; i < len(b); {
345			n--
346			if n < 0 {
347				return b[:i]
348			}
349			wid := 1
350			if b[i] >= utf8.RuneSelf {
351				_, wid = utf8.DecodeRune(b[i:])
352			}
353			i += wid
354		}
355	}
356	return b
357}
358
359// fmtS formats a string.
360func (f *fmt) fmtS(s string) {
361	s = f.truncateString(s)
362	f.padString(s)
363}
364
365// fmtBs formats the byte slice b as if it was formatted as string with fmtS.
366func (f *fmt) fmtBs(b []byte) {
367	b = f.truncate(b)
368	f.pad(b)
369}
370
371// fmtSbx formats a string or byte slice as a hexadecimal encoding of its bytes.
372func (f *fmt) fmtSbx(s string, b []byte, digits string) {
373	length := len(b)
374	if b == nil {
375		// No byte slice present. Assume string s should be encoded.
376		length = len(s)
377	}
378	// Set length to not process more bytes than the precision demands.
379	if f.precPresent && f.prec < length {
380		length = f.prec
381	}
382	// Compute width of the encoding taking into account the f.sharp and f.space flag.
383	width := 2 * length
384	if width > 0 {
385		if f.space {
386			// Each element encoded by two hexadecimals will get a leading 0x or 0X.
387			if f.sharp {
388				width *= 2
389			}
390			// Elements will be separated by a space.
391			width += length - 1
392		} else if f.sharp {
393			// Only a leading 0x or 0X will be added for the whole string.
394			width += 2
395		}
396	} else { // The byte slice or string that should be encoded is empty.
397		if f.widPresent {
398			f.writePadding(f.wid)
399		}
400		return
401	}
402	// Handle padding to the left.
403	if f.widPresent && f.wid > width && !f.minus {
404		f.writePadding(f.wid - width)
405	}
406	// Write the encoding directly into the output buffer.
407	buf := *f.buf
408	if f.sharp {
409		// Add leading 0x or 0X.
410		buf = append(buf, '0', digits[16])
411	}
412	var c byte
413	for i := 0; i < length; i++ {
414		if f.space && i > 0 {
415			// Separate elements with a space.
416			buf = append(buf, ' ')
417			if f.sharp {
418				// Add leading 0x or 0X for each element.
419				buf = append(buf, '0', digits[16])
420			}
421		}
422		if b != nil {
423			c = b[i] // Take a byte from the input byte slice.
424		} else {
425			c = s[i] // Take a byte from the input string.
426		}
427		// Encode each byte as two hexadecimal digits.
428		buf = append(buf, digits[c>>4], digits[c&0xF])
429	}
430	*f.buf = buf
431	// Handle padding to the right.
432	if f.widPresent && f.wid > width && f.minus {
433		f.writePadding(f.wid - width)
434	}
435}
436
437// fmtSx formats a string as a hexadecimal encoding of its bytes.
438func (f *fmt) fmtSx(s, digits string) {
439	f.fmtSbx(s, nil, digits)
440}
441
442// fmtBx formats a byte slice as a hexadecimal encoding of its bytes.
443func (f *fmt) fmtBx(b []byte, digits string) {
444	f.fmtSbx("", b, digits)
445}
446
447// fmtQ formats a string as a double-quoted, escaped Go string constant.
448// If f.sharp is set a raw (backquoted) string may be returned instead
449// if the string does not contain any control characters other than tab.
450func (f *fmt) fmtQ(s string) {
451	s = f.truncateString(s)
452	if f.sharp && strconv.CanBackquote(s) {
453		f.padString("`" + s + "`")
454		return
455	}
456	buf := f.intbuf[:0]
457	if f.plus {
458		f.pad(strconv.AppendQuoteToASCII(buf, s))
459	} else {
460		f.pad(strconv.AppendQuote(buf, s))
461	}
462}
463
464// fmtC formats an integer as a Unicode character.
465// If the character is not valid Unicode, it will print '\ufffd'.
466func (f *fmt) fmtC(c uint64) {
467	// Explicitly check whether c exceeds utf8.MaxRune since the conversion
468	// of a uint64 to a rune may lose precision that indicates an overflow.
469	r := rune(c)
470	if c > utf8.MaxRune {
471		r = utf8.RuneError
472	}
473	buf := f.intbuf[:0]
474	f.pad(utf8.AppendRune(buf, r))
475}
476
477// fmtQc formats an integer as a single-quoted, escaped Go character constant.
478// If the character is not valid Unicode, it will print '\ufffd'.
479func (f *fmt) fmtQc(c uint64) {
480	r := rune(c)
481	if c > utf8.MaxRune {
482		r = utf8.RuneError
483	}
484	buf := f.intbuf[:0]
485	if f.plus {
486		f.pad(strconv.AppendQuoteRuneToASCII(buf, r))
487	} else {
488		f.pad(strconv.AppendQuoteRune(buf, r))
489	}
490}
491
492// fmtFloat formats a float64. It assumes that verb is a valid format specifier
493// for strconv.AppendFloat and therefore fits into a byte.
494func (f *fmt) fmtFloat(v float64, size int, verb rune, prec int) {
495	// Explicit precision in format specifier overrules default precision.
496	if f.precPresent {
497		prec = f.prec
498	}
499	// Format number, reserving space for leading + sign if needed.
500	num := strconv.AppendFloat(f.intbuf[:1], v, byte(verb), prec, size)
501	if num[1] == '-' || num[1] == '+' {
502		num = num[1:]
503	} else {
504		num[0] = '+'
505	}
506	// f.space means to add a leading space instead of a "+" sign unless
507	// the sign is explicitly asked for by f.plus.
508	if f.space && num[0] == '+' && !f.plus {
509		num[0] = ' '
510	}
511	// Special handling for infinities and NaN,
512	// which don't look like a number so shouldn't be padded with zeros.
513	if num[1] == 'I' || num[1] == 'N' {
514		oldZero := f.zero
515		f.zero = false
516		// Remove sign before NaN if not asked for.
517		if num[1] == 'N' && !f.space && !f.plus {
518			num = num[1:]
519		}
520		f.pad(num)
521		f.zero = oldZero
522		return
523	}
524	// The sharp flag forces printing a decimal point for non-binary formats
525	// and retains trailing zeros, which we may need to restore.
526	if f.sharp && verb != 'b' {
527		digits := 0
528		switch verb {
529		case 'v', 'g', 'G', 'x':
530			digits = prec
531			// If no precision is set explicitly use a precision of 6.
532			if digits == -1 {
533				digits = 6
534			}
535		}
536
537		// Buffer pre-allocated with enough room for
538		// exponent notations of the form "e+123" or "p-1023".
539		var tailBuf [6]byte
540		tail := tailBuf[:0]
541
542		hasDecimalPoint := false
543		sawNonzeroDigit := false
544		// Starting from i = 1 to skip sign at num[0].
545		for i := 1; i < len(num); i++ {
546			switch num[i] {
547			case '.':
548				hasDecimalPoint = true
549			case 'p', 'P':
550				tail = append(tail, num[i:]...)
551				num = num[:i]
552			case 'e', 'E':
553				if verb != 'x' && verb != 'X' {
554					tail = append(tail, num[i:]...)
555					num = num[:i]
556					break
557				}
558				fallthrough
559			default:
560				if num[i] != '0' {
561					sawNonzeroDigit = true
562				}
563				// Count significant digits after the first non-zero digit.
564				if sawNonzeroDigit {
565					digits--
566				}
567			}
568		}
569		if !hasDecimalPoint {
570			// Leading digit 0 should contribute once to digits.
571			if len(num) == 2 && num[1] == '0' {
572				digits--
573			}
574			num = append(num, '.')
575		}
576		for digits > 0 {
577			num = append(num, '0')
578			digits--
579		}
580		num = append(num, tail...)
581	}
582	// We want a sign if asked for and if the sign is not positive.
583	if f.plus || num[0] != '+' {
584		// If we're zero padding to the left we want the sign before the leading zeros.
585		// Achieve this by writing the sign out and then padding the unsigned number.
586		// Zero padding is allowed only to the left.
587		if f.zero && !f.minus && f.widPresent && f.wid > len(num) {
588			f.buf.writeByte(num[0])
589			f.writePadding(f.wid - len(num))
590			f.buf.write(num[1:])
591			return
592		}
593		f.pad(num)
594		return
595	}
596	// No sign to show and the number is positive; just print the unsigned number.
597	f.pad(num[1:])
598}
599