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