Source file
src/fmt/fmt_test.go
1
2
3
4
5 package fmt_test
6
7 import (
8 "bytes"
9 . "fmt"
10 "internal/race"
11 "io"
12 "math"
13 "reflect"
14 "strings"
15 "testing"
16 "time"
17 "unicode"
18 )
19
20 type (
21 renamedBool bool
22 renamedInt int
23 renamedInt8 int8
24 renamedInt16 int16
25 renamedInt32 int32
26 renamedInt64 int64
27 renamedUint uint
28 renamedUint8 uint8
29 renamedUint16 uint16
30 renamedUint32 uint32
31 renamedUint64 uint64
32 renamedUintptr uintptr
33 renamedString string
34 renamedBytes []byte
35 renamedFloat32 float32
36 renamedFloat64 float64
37 renamedComplex64 complex64
38 renamedComplex128 complex128
39 )
40
41 func TestFmtInterface(t *testing.T) {
42 var i1 any
43 i1 = "abc"
44 s := Sprintf("%s", i1)
45 if s != "abc" {
46 t.Errorf(`Sprintf("%%s", empty("abc")) = %q want %q`, s, "abc")
47 }
48 }
49
50 var (
51 NaN = math.NaN()
52 posInf = math.Inf(1)
53 negInf = math.Inf(-1)
54
55 intVar = 0
56
57 array = [5]int{1, 2, 3, 4, 5}
58 iarray = [4]any{1, "hello", 2.5, nil}
59 slice = array[:]
60 islice = iarray[:]
61 )
62
63 type A struct {
64 i int
65 j uint
66 s string
67 x []int
68 }
69
70 type I int
71
72 func (i I) String() string { return Sprintf("<%d>", int(i)) }
73
74 type B struct {
75 I I
76 j int
77 }
78
79 type C struct {
80 i int
81 B
82 }
83
84 type F int
85
86 func (f F) Format(s State, c rune) {
87 Fprintf(s, "<%c=F(%d)>", c, int(f))
88 }
89
90 type G int
91
92 func (g G) GoString() string {
93 return Sprintf("GoString(%d)", int(g))
94 }
95
96 type S struct {
97 F F
98 G G
99 }
100
101 type SI struct {
102 I any
103 }
104
105
106 type P int
107
108 var pValue P
109
110 func (p *P) String() string {
111 return "String(p)"
112 }
113
114
115 type Fn func() int
116
117 func (fn Fn) String() string { return "String(fn)" }
118
119 var fnValue Fn
120
121
122 type U struct {
123 u func() string
124 fn Fn
125 }
126
127 var barray = [5]renamedUint8{1, 2, 3, 4, 5}
128 var bslice = barray[:]
129
130 type byteStringer byte
131
132 func (byteStringer) String() string {
133 return "X"
134 }
135
136 var byteStringerSlice = []byteStringer{'h', 'e', 'l', 'l', 'o'}
137
138 type byteFormatter byte
139
140 func (byteFormatter) Format(f State, _ rune) {
141 Fprint(f, "X")
142 }
143
144 var byteFormatterSlice = []byteFormatter{'h', 'e', 'l', 'l', 'o'}
145
146 type writeStringFormatter string
147
148 func (sf writeStringFormatter) Format(f State, c rune) {
149 if sw, ok := f.(io.StringWriter); ok {
150 sw.WriteString("***" + string(sf) + "***")
151 }
152 }
153
154 var fmtTests = []struct {
155 fmt string
156 val any
157 out string
158 }{
159 {"%d", 12345, "12345"},
160 {"%v", 12345, "12345"},
161 {"%t", true, "true"},
162
163
164 {"%s", "abc", "abc"},
165 {"%q", "abc", `"abc"`},
166 {"%x", "abc", "616263"},
167 {"%x", "\xff\xf0\x0f\xff", "fff00fff"},
168 {"%X", "\xff\xf0\x0f\xff", "FFF00FFF"},
169 {"%x", "", ""},
170 {"% x", "", ""},
171 {"%#x", "", ""},
172 {"%# x", "", ""},
173 {"%x", "xyz", "78797a"},
174 {"%X", "xyz", "78797A"},
175 {"% x", "xyz", "78 79 7a"},
176 {"% X", "xyz", "78 79 7A"},
177 {"%#x", "xyz", "0x78797a"},
178 {"%#X", "xyz", "0X78797A"},
179 {"%# x", "xyz", "0x78 0x79 0x7a"},
180 {"%# X", "xyz", "0X78 0X79 0X7A"},
181
182
183 {"%s", []byte("abc"), "abc"},
184 {"%s", [3]byte{'a', 'b', 'c'}, "abc"},
185 {"%s", &[3]byte{'a', 'b', 'c'}, "&abc"},
186 {"%q", []byte("abc"), `"abc"`},
187 {"%x", []byte("abc"), "616263"},
188 {"%x", []byte("\xff\xf0\x0f\xff"), "fff00fff"},
189 {"%X", []byte("\xff\xf0\x0f\xff"), "FFF00FFF"},
190 {"%x", []byte(""), ""},
191 {"% x", []byte(""), ""},
192 {"%#x", []byte(""), ""},
193 {"%# x", []byte(""), ""},
194 {"%x", []byte("xyz"), "78797a"},
195 {"%X", []byte("xyz"), "78797A"},
196 {"% x", []byte("xyz"), "78 79 7a"},
197 {"% X", []byte("xyz"), "78 79 7A"},
198 {"%#x", []byte("xyz"), "0x78797a"},
199 {"%#X", []byte("xyz"), "0X78797A"},
200 {"%# x", []byte("xyz"), "0x78 0x79 0x7a"},
201 {"%# X", []byte("xyz"), "0X78 0X79 0X7A"},
202
203
204 {"%q", "", `""`},
205 {"%#q", "", "``"},
206 {"%q", "\"", `"\""`},
207 {"%#q", "\"", "`\"`"},
208 {"%q", "`", `"` + "`" + `"`},
209 {"%#q", "`", `"` + "`" + `"`},
210 {"%q", "\n", `"\n"`},
211 {"%#q", "\n", `"\n"`},
212 {"%q", `\n`, `"\\n"`},
213 {"%#q", `\n`, "`\\n`"},
214 {"%q", "abc", `"abc"`},
215 {"%#q", "abc", "`abc`"},
216 {"%q", "日本語", `"日本語"`},
217 {"%+q", "日本語", `"\u65e5\u672c\u8a9e"`},
218 {"%#q", "日本語", "`日本語`"},
219 {"%#+q", "日本語", "`日本語`"},
220 {"%q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
221 {"%+q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
222 {"%#q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
223 {"%#+q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
224 {"%q", "☺", `"☺"`},
225 {"% q", "☺", `"☺"`},
226 {"%+q", "☺", `"\u263a"`},
227 {"%#q", "☺", "`☺`"},
228 {"%#+q", "☺", "`☺`"},
229 {"%10q", "⌘", ` "⌘"`},
230 {"%+10q", "⌘", ` "\u2318"`},
231 {"%-10q", "⌘", `"⌘" `},
232 {"%+-10q", "⌘", `"\u2318" `},
233 {"%010q", "⌘", `0000000"⌘"`},
234 {"%+010q", "⌘", `00"\u2318"`},
235 {"%-010q", "⌘", `"⌘" `},
236 {"%+-010q", "⌘", `"\u2318" `},
237 {"%#8q", "\n", ` "\n"`},
238 {"%#+8q", "\r", ` "\r"`},
239 {"%#-8q", "\t", "` ` "},
240 {"%#+-8q", "\b", `"\b" `},
241 {"%q", "abc\xffdef", `"abc\xffdef"`},
242 {"%+q", "abc\xffdef", `"abc\xffdef"`},
243 {"%#q", "abc\xffdef", `"abc\xffdef"`},
244 {"%#+q", "abc\xffdef", `"abc\xffdef"`},
245
246 {"%q", "\U0010ffff", `"\U0010ffff"`},
247 {"%+q", "\U0010ffff", `"\U0010ffff"`},
248 {"%#q", "\U0010ffff", "``"},
249 {"%#+q", "\U0010ffff", "``"},
250
251 {"%q", string(rune(0x110000)), `"�"`},
252 {"%+q", string(rune(0x110000)), `"\ufffd"`},
253 {"%#q", string(rune(0x110000)), "`�`"},
254 {"%#+q", string(rune(0x110000)), "`�`"},
255
256
257 {"%c", uint('x'), "x"},
258 {"%c", 0xe4, "ä"},
259 {"%c", 0x672c, "本"},
260 {"%c", '日', "日"},
261 {"%.0c", '⌘', "⌘"},
262 {"%3c", '⌘', " ⌘"},
263 {"%-3c", '⌘', "⌘ "},
264 {"%c", uint64(0x100000000), "\ufffd"},
265
266 {"%c", '\U00000e00', "\u0e00"},
267 {"%c", '\U0010ffff', "\U0010ffff"},
268
269 {"%c", -1, "�"},
270 {"%c", 0xDC80, "�"},
271 {"%c", rune(0x110000), "�"},
272 {"%c", int64(0xFFFFFFFFF), "�"},
273 {"%c", uint64(0xFFFFFFFFF), "�"},
274
275
276 {"%q", uint(0), `'\x00'`},
277 {"%+q", uint(0), `'\x00'`},
278 {"%q", '"', `'"'`},
279 {"%+q", '"', `'"'`},
280 {"%q", '\'', `'\''`},
281 {"%+q", '\'', `'\''`},
282 {"%q", '`', "'`'"},
283 {"%+q", '`', "'`'"},
284 {"%q", 'x', `'x'`},
285 {"%+q", 'x', `'x'`},
286 {"%q", 'ÿ', `'ÿ'`},
287 {"%+q", 'ÿ', `'\u00ff'`},
288 {"%q", '\n', `'\n'`},
289 {"%+q", '\n', `'\n'`},
290 {"%q", '☺', `'☺'`},
291 {"%+q", '☺', `'\u263a'`},
292 {"% q", '☺', `'☺'`},
293 {"%.0q", '☺', `'☺'`},
294 {"%10q", '⌘', ` '⌘'`},
295 {"%+10q", '⌘', ` '\u2318'`},
296 {"%-10q", '⌘', `'⌘' `},
297 {"%+-10q", '⌘', `'\u2318' `},
298 {"%010q", '⌘', `0000000'⌘'`},
299 {"%+010q", '⌘', `00'\u2318'`},
300 {"%-010q", '⌘', `'⌘' `},
301 {"%+-010q", '⌘', `'\u2318' `},
302
303 {"%q", '\U00000e00', `'\u0e00'`},
304 {"%q", '\U0010ffff', `'\U0010ffff'`},
305
306 {"%q", int32(-1), `'�'`},
307 {"%q", 0xDC80, `'�'`},
308 {"%q", rune(0x110000), `'�'`},
309 {"%q", int64(0xFFFFFFFFF), `'�'`},
310 {"%q", uint64(0xFFFFFFFFF), `'�'`},
311
312
313 {"%5s", "abc", " abc"},
314 {"%5s", []byte("abc"), " abc"},
315 {"%2s", "\u263a", " ☺"},
316 {"%2s", []byte("\u263a"), " ☺"},
317 {"%-5s", "abc", "abc "},
318 {"%-5s", []byte("abc"), "abc "},
319 {"%05s", "abc", "00abc"},
320 {"%05s", []byte("abc"), "00abc"},
321 {"%5s", "abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"},
322 {"%5s", []byte("abcdefghijklmnopqrstuvwxyz"), "abcdefghijklmnopqrstuvwxyz"},
323 {"%.5s", "abcdefghijklmnopqrstuvwxyz", "abcde"},
324 {"%.5s", []byte("abcdefghijklmnopqrstuvwxyz"), "abcde"},
325 {"%.0s", "日本語日本語", ""},
326 {"%.0s", []byte("日本語日本語"), ""},
327 {"%.5s", "日本語日本語", "日本語日本"},
328 {"%.5s", []byte("日本語日本語"), "日本語日本"},
329 {"%.10s", "日本語日本語", "日本語日本語"},
330 {"%.10s", []byte("日本語日本語"), "日本語日本語"},
331 {"%08q", "abc", `000"abc"`},
332 {"%08q", []byte("abc"), `000"abc"`},
333 {"%-8q", "abc", `"abc" `},
334 {"%-8q", []byte("abc"), `"abc" `},
335 {"%.5q", "abcdefghijklmnopqrstuvwxyz", `"abcde"`},
336 {"%.5q", []byte("abcdefghijklmnopqrstuvwxyz"), `"abcde"`},
337 {"%.5x", "abcdefghijklmnopqrstuvwxyz", "6162636465"},
338 {"%.5x", []byte("abcdefghijklmnopqrstuvwxyz"), "6162636465"},
339 {"%.3q", "日本語日本語", `"日本語"`},
340 {"%.3q", []byte("日本語日本語"), `"日本語"`},
341 {"%.1q", "日本語", `"日"`},
342 {"%.1q", []byte("日本語"), `"日"`},
343 {"%.1x", "日本語", "e6"},
344 {"%.1X", []byte("日本語"), "E6"},
345 {"%10.1q", "日本語日本語", ` "日"`},
346 {"%10.1q", []byte("日本語日本語"), ` "日"`},
347 {"%10v", nil, " <nil>"},
348 {"%-10v", nil, "<nil> "},
349
350
351 {"%d", uint(12345), "12345"},
352 {"%d", int(-12345), "-12345"},
353 {"%d", ^uint8(0), "255"},
354 {"%d", ^uint16(0), "65535"},
355 {"%d", ^uint32(0), "4294967295"},
356 {"%d", ^uint64(0), "18446744073709551615"},
357 {"%d", int8(-1 << 7), "-128"},
358 {"%d", int16(-1 << 15), "-32768"},
359 {"%d", int32(-1 << 31), "-2147483648"},
360 {"%d", int64(-1 << 63), "-9223372036854775808"},
361 {"%.d", 0, ""},
362 {"%.0d", 0, ""},
363 {"%6.0d", 0, " "},
364 {"%06.0d", 0, " "},
365 {"% d", 12345, " 12345"},
366 {"%+d", 12345, "+12345"},
367 {"%+d", -12345, "-12345"},
368 {"%b", 7, "111"},
369 {"%b", -6, "-110"},
370 {"%#b", 7, "0b111"},
371 {"%#b", -6, "-0b110"},
372 {"%b", ^uint32(0), "11111111111111111111111111111111"},
373 {"%b", ^uint64(0), "1111111111111111111111111111111111111111111111111111111111111111"},
374 {"%b", int64(-1 << 63), zeroFill("-1", 63, "")},
375 {"%o", 01234, "1234"},
376 {"%o", -01234, "-1234"},
377 {"%#o", 01234, "01234"},
378 {"%#o", -01234, "-01234"},
379 {"%O", 01234, "0o1234"},
380 {"%O", -01234, "-0o1234"},
381 {"%o", ^uint32(0), "37777777777"},
382 {"%o", ^uint64(0), "1777777777777777777777"},
383 {"%#X", 0, "0X0"},
384 {"%x", 0x12abcdef, "12abcdef"},
385 {"%X", 0x12abcdef, "12ABCDEF"},
386 {"%x", ^uint32(0), "ffffffff"},
387 {"%X", ^uint64(0), "FFFFFFFFFFFFFFFF"},
388 {"%.20b", 7, "00000000000000000111"},
389 {"%10d", 12345, " 12345"},
390 {"%10d", -12345, " -12345"},
391 {"%+10d", 12345, " +12345"},
392 {"%010d", 12345, "0000012345"},
393 {"%010d", -12345, "-000012345"},
394 {"%20.8d", 1234, " 00001234"},
395 {"%20.8d", -1234, " -00001234"},
396 {"%020.8d", 1234, " 00001234"},
397 {"%020.8d", -1234, " -00001234"},
398 {"%-20.8d", 1234, "00001234 "},
399 {"%-20.8d", -1234, "-00001234 "},
400 {"%-#20.8x", 0x1234abc, "0x01234abc "},
401 {"%-#20.8X", 0x1234abc, "0X01234ABC "},
402 {"%-#20.8o", 01234, "00001234 "},
403
404
405 {"%068d", 1, zeroFill("", 68, "1")},
406 {"%068d", -1, zeroFill("-", 67, "1")},
407 {"%#.68x", 42, zeroFill("0x", 68, "2a")},
408 {"%.68d", -42, zeroFill("-", 68, "42")},
409 {"%+.68d", 42, zeroFill("+", 68, "42")},
410 {"% .68d", 42, zeroFill(" ", 68, "42")},
411 {"% +.68d", 42, zeroFill("+", 68, "42")},
412
413
414 {"%U", 0, "U+0000"},
415 {"%U", -1, "U+FFFFFFFFFFFFFFFF"},
416 {"%U", '\n', `U+000A`},
417 {"%#U", '\n', `U+000A`},
418 {"%+U", 'x', `U+0078`},
419 {"%# U", 'x', `U+0078 'x'`},
420 {"%#.2U", 'x', `U+0078 'x'`},
421 {"%U", '\u263a', `U+263A`},
422 {"%#U", '\u263a', `U+263A '☺'`},
423 {"%U", '\U0001D6C2', `U+1D6C2`},
424 {"%#U", '\U0001D6C2', `U+1D6C2 '𝛂'`},
425 {"%#14.6U", '⌘', " U+002318 '⌘'"},
426 {"%#-14.6U", '⌘', "U+002318 '⌘' "},
427 {"%#014.6U", '⌘', " U+002318 '⌘'"},
428 {"%#-014.6U", '⌘', "U+002318 '⌘' "},
429 {"%.68U", uint(42), zeroFill("U+", 68, "2A")},
430 {"%#.68U", '日', zeroFill("U+", 68, "65E5") + " '日'"},
431
432
433 {"%+.3e", 0.0, "+0.000e+00"},
434 {"%+.3e", 1.0, "+1.000e+00"},
435 {"%+.3x", 0.0, "+0x0.000p+00"},
436 {"%+.3x", 1.0, "+0x1.000p+00"},
437 {"%+.3f", -1.0, "-1.000"},
438 {"%+.3F", -1.0, "-1.000"},
439 {"%+.3F", float32(-1.0), "-1.000"},
440 {"%+07.2f", 1.0, "+001.00"},
441 {"%+07.2f", -1.0, "-001.00"},
442 {"%-07.2f", 1.0, "1.00 "},
443 {"%-07.2f", -1.0, "-1.00 "},
444 {"%+-07.2f", 1.0, "+1.00 "},
445 {"%+-07.2f", -1.0, "-1.00 "},
446 {"%-+07.2f", 1.0, "+1.00 "},
447 {"%-+07.2f", -1.0, "-1.00 "},
448 {"%+10.2f", +1.0, " +1.00"},
449 {"%+10.2f", -1.0, " -1.00"},
450 {"% .3E", -1.0, "-1.000E+00"},
451 {"% .3e", 1.0, " 1.000e+00"},
452 {"% .3X", -1.0, "-0X1.000P+00"},
453 {"% .3x", 1.0, " 0x1.000p+00"},
454 {"%+.3g", 0.0, "+0"},
455 {"%+.3g", 1.0, "+1"},
456 {"%+.3g", -1.0, "-1"},
457 {"% .3g", -1.0, "-1"},
458 {"% .3g", 1.0, " 1"},
459 {"%b", float32(1.0), "8388608p-23"},
460 {"%b", 1.0, "4503599627370496p-52"},
461
462 {"%#g", 1e-323, "1.00000e-323"},
463 {"%#g", -1.0, "-1.00000"},
464 {"%#g", 1.1, "1.10000"},
465 {"%#g", 123456.0, "123456."},
466 {"%#g", 1234567.0, "1.234567e+06"},
467 {"%#g", 1230000.0, "1.23000e+06"},
468 {"%#g", 1000000.0, "1.00000e+06"},
469 {"%#.0f", 1.0, "1."},
470 {"%#.0e", 1.0, "1.e+00"},
471 {"%#.0x", 1.0, "0x1.p+00"},
472 {"%#.0g", 1.0, "1."},
473 {"%#.0g", 1100000.0, "1.e+06"},
474 {"%#.4f", 1.0, "1.0000"},
475 {"%#.4e", 1.0, "1.0000e+00"},
476 {"%#.4x", 1.0, "0x1.0000p+00"},
477 {"%#.4g", 1.0, "1.000"},
478 {"%#.4g", 100000.0, "1.000e+05"},
479 {"%#.4g", 1.234, "1.234"},
480 {"%#.4g", 0.1234, "0.1234"},
481 {"%#.4g", 1.23, "1.230"},
482 {"%#.4g", 0.123, "0.1230"},
483 {"%#.4g", 1.2, "1.200"},
484 {"%#.4g", 0.12, "0.1200"},
485 {"%#.4g", 10.2, "10.20"},
486 {"%#.4g", 0.0, "0.000"},
487 {"%#.4g", 0.012, "0.01200"},
488 {"%#.0f", 123.0, "123."},
489 {"%#.0e", 123.0, "1.e+02"},
490 {"%#.0x", 123.0, "0x1.p+07"},
491 {"%#.0g", 123.0, "1.e+02"},
492 {"%#.4f", 123.0, "123.0000"},
493 {"%#.4e", 123.0, "1.2300e+02"},
494 {"%#.4x", 123.0, "0x1.ec00p+06"},
495 {"%#.4g", 123.0, "123.0"},
496 {"%#.4g", 123000.0, "1.230e+05"},
497 {"%#9.4g", 1.0, " 1.000"},
498
499 {"%#b", 1.0, "4503599627370496p-52"},
500
501 {"%.4b", float32(1.0), "8388608p-23"},
502 {"%.4b", -1.0, "-4503599627370496p-52"},
503
504 {"%.68f", 1.0, zeroFill("1.", 68, "")},
505 {"%.68f", -1.0, zeroFill("-1.", 68, "")},
506
507 {"%f", posInf, "+Inf"},
508 {"%.1f", negInf, "-Inf"},
509 {"% f", NaN, " NaN"},
510 {"%20f", posInf, " +Inf"},
511 {"% 20F", posInf, " Inf"},
512 {"% 20e", negInf, " -Inf"},
513 {"% 20x", negInf, " -Inf"},
514 {"%+20E", negInf, " -Inf"},
515 {"%+20X", negInf, " -Inf"},
516 {"% +20g", negInf, " -Inf"},
517 {"%+-20G", posInf, "+Inf "},
518 {"%20e", NaN, " NaN"},
519 {"%20x", NaN, " NaN"},
520 {"% +20E", NaN, " +NaN"},
521 {"% +20X", NaN, " +NaN"},
522 {"% -20g", NaN, " NaN "},
523 {"%+-20G", NaN, "+NaN "},
524
525 {"%+020e", posInf, " +Inf"},
526 {"%+020x", posInf, " +Inf"},
527 {"%-020f", negInf, "-Inf "},
528 {"%-020E", NaN, "NaN "},
529 {"%-020X", NaN, "NaN "},
530
531
532 {"%.f", 0i, "(0+0i)"},
533 {"% .f", 0i, "( 0+0i)"},
534 {"%+.f", 0i, "(+0+0i)"},
535 {"% +.f", 0i, "(+0+0i)"},
536 {"%+.3e", 0i, "(+0.000e+00+0.000e+00i)"},
537 {"%+.3x", 0i, "(+0x0.000p+00+0x0.000p+00i)"},
538 {"%+.3f", 0i, "(+0.000+0.000i)"},
539 {"%+.3g", 0i, "(+0+0i)"},
540 {"%+.3e", 1 + 2i, "(+1.000e+00+2.000e+00i)"},
541 {"%+.3x", 1 + 2i, "(+0x1.000p+00+0x1.000p+01i)"},
542 {"%+.3f", 1 + 2i, "(+1.000+2.000i)"},
543 {"%+.3g", 1 + 2i, "(+1+2i)"},
544 {"%.3e", 0i, "(0.000e+00+0.000e+00i)"},
545 {"%.3x", 0i, "(0x0.000p+00+0x0.000p+00i)"},
546 {"%.3f", 0i, "(0.000+0.000i)"},
547 {"%.3F", 0i, "(0.000+0.000i)"},
548 {"%.3F", complex64(0i), "(0.000+0.000i)"},
549 {"%.3g", 0i, "(0+0i)"},
550 {"%.3e", 1 + 2i, "(1.000e+00+2.000e+00i)"},
551 {"%.3x", 1 + 2i, "(0x1.000p+00+0x1.000p+01i)"},
552 {"%.3f", 1 + 2i, "(1.000+2.000i)"},
553 {"%.3g", 1 + 2i, "(1+2i)"},
554 {"%.3e", -1 - 2i, "(-1.000e+00-2.000e+00i)"},
555 {"%.3x", -1 - 2i, "(-0x1.000p+00-0x1.000p+01i)"},
556 {"%.3f", -1 - 2i, "(-1.000-2.000i)"},
557 {"%.3g", -1 - 2i, "(-1-2i)"},
558 {"% .3E", -1 - 2i, "(-1.000E+00-2.000E+00i)"},
559 {"% .3X", -1 - 2i, "(-0X1.000P+00-0X1.000P+01i)"},
560 {"%+.3g", 1 + 2i, "(+1+2i)"},
561 {"%+.3g", complex64(1 + 2i), "(+1+2i)"},
562 {"%#g", 1 + 2i, "(1.00000+2.00000i)"},
563 {"%#g", 123456 + 789012i, "(123456.+789012.i)"},
564 {"%#g", 1e-10i, "(0.00000+1.00000e-10i)"},
565 {"%#g", -1e10 - 1.11e100i, "(-1.00000e+10-1.11000e+100i)"},
566 {"%#.0f", 1.23 + 1.0i, "(1.+1.i)"},
567 {"%#.0e", 1.23 + 1.0i, "(1.e+00+1.e+00i)"},
568 {"%#.0x", 1.23 + 1.0i, "(0x1.p+00+0x1.p+00i)"},
569 {"%#.0g", 1.23 + 1.0i, "(1.+1.i)"},
570 {"%#.0g", 0 + 100000i, "(0.+1.e+05i)"},
571 {"%#.0g", 1230000 + 0i, "(1.e+06+0.i)"},
572 {"%#.4f", 1 + 1.23i, "(1.0000+1.2300i)"},
573 {"%#.4e", 123 + 1i, "(1.2300e+02+1.0000e+00i)"},
574 {"%#.4x", 123 + 1i, "(0x1.ec00p+06+0x1.0000p+00i)"},
575 {"%#.4g", 123 + 1.23i, "(123.0+1.230i)"},
576 {"%#12.5g", 0 + 100000i, "( 0.0000 +1.0000e+05i)"},
577 {"%#12.5g", 1230000 - 0i, "( 1.2300e+06 +0.0000i)"},
578 {"%b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"},
579 {"%b", complex64(1 + 2i), "(8388608p-23+8388608p-22i)"},
580
581 {"%#b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"},
582
583 {"%.4b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"},
584 {"%.4b", complex64(1 + 2i), "(8388608p-23+8388608p-22i)"},
585
586 {"%f", complex(posInf, posInf), "(+Inf+Infi)"},
587 {"%f", complex(negInf, negInf), "(-Inf-Infi)"},
588 {"%f", complex(NaN, NaN), "(NaN+NaNi)"},
589 {"%.1f", complex(posInf, posInf), "(+Inf+Infi)"},
590 {"% f", complex(posInf, posInf), "( Inf+Infi)"},
591 {"% f", complex(negInf, negInf), "(-Inf-Infi)"},
592 {"% f", complex(NaN, NaN), "( NaN+NaNi)"},
593 {"%8e", complex(posInf, posInf), "( +Inf +Infi)"},
594 {"%8x", complex(posInf, posInf), "( +Inf +Infi)"},
595 {"% 8E", complex(posInf, posInf), "( Inf +Infi)"},
596 {"% 8X", complex(posInf, posInf), "( Inf +Infi)"},
597 {"%+8f", complex(negInf, negInf), "( -Inf -Infi)"},
598 {"% +8g", complex(negInf, negInf), "( -Inf -Infi)"},
599 {"% -8G", complex(NaN, NaN), "( NaN +NaN i)"},
600 {"%+-8b", complex(NaN, NaN), "(+NaN +NaN i)"},
601
602 {"%08f", complex(posInf, posInf), "( +Inf +Infi)"},
603 {"%-08g", complex(negInf, negInf), "(-Inf -Inf i)"},
604 {"%-08G", complex(NaN, NaN), "(NaN +NaN i)"},
605
606
607 {"%e", 1.0, "1.000000e+00"},
608 {"%e", 1234.5678e3, "1.234568e+06"},
609 {"%e", 1234.5678e-8, "1.234568e-05"},
610 {"%e", -7.0, "-7.000000e+00"},
611 {"%e", -1e-9, "-1.000000e-09"},
612 {"%f", 1234.5678e3, "1234567.800000"},
613 {"%f", 1234.5678e-8, "0.000012"},
614 {"%f", -7.0, "-7.000000"},
615 {"%f", -1e-9, "-0.000000"},
616 {"%g", 1234.5678e3, "1.2345678e+06"},
617 {"%g", float32(1234.5678e3), "1.2345678e+06"},
618 {"%g", 1234.5678e-8, "1.2345678e-05"},
619 {"%g", -7.0, "-7"},
620 {"%g", -1e-9, "-1e-09"},
621 {"%g", float32(-1e-9), "-1e-09"},
622 {"%E", 1.0, "1.000000E+00"},
623 {"%E", 1234.5678e3, "1.234568E+06"},
624 {"%E", 1234.5678e-8, "1.234568E-05"},
625 {"%E", -7.0, "-7.000000E+00"},
626 {"%E", -1e-9, "-1.000000E-09"},
627 {"%G", 1234.5678e3, "1.2345678E+06"},
628 {"%G", float32(1234.5678e3), "1.2345678E+06"},
629 {"%G", 1234.5678e-8, "1.2345678E-05"},
630 {"%G", -7.0, "-7"},
631 {"%G", -1e-9, "-1E-09"},
632 {"%G", float32(-1e-9), "-1E-09"},
633 {"%20.5s", "qwertyuiop", " qwert"},
634 {"%.5s", "qwertyuiop", "qwert"},
635 {"%-20.5s", "qwertyuiop", "qwert "},
636 {"%20c", 'x', " x"},
637 {"%-20c", 'x', "x "},
638 {"%20.6e", 1.2345e3, " 1.234500e+03"},
639 {"%20.6e", 1.2345e-3, " 1.234500e-03"},
640 {"%20e", 1.2345e3, " 1.234500e+03"},
641 {"%20e", 1.2345e-3, " 1.234500e-03"},
642 {"%20.8e", 1.2345e3, " 1.23450000e+03"},
643 {"%20f", 1.23456789e3, " 1234.567890"},
644 {"%20f", 1.23456789e-3, " 0.001235"},
645 {"%20f", 12345678901.23456789, " 12345678901.234568"},
646 {"%-20f", 1.23456789e3, "1234.567890 "},
647 {"%20.8f", 1.23456789e3, " 1234.56789000"},
648 {"%20.8f", 1.23456789e-3, " 0.00123457"},
649 {"%g", 1.23456789e3, "1234.56789"},
650 {"%g", 1.23456789e-3, "0.00123456789"},
651 {"%g", 1.23456789e20, "1.23456789e+20"},
652
653
654 {"%v", array, "[1 2 3 4 5]"},
655 {"%v", iarray, "[1 hello 2.5 <nil>]"},
656 {"%v", barray, "[1 2 3 4 5]"},
657 {"%v", &array, "&[1 2 3 4 5]"},
658 {"%v", &iarray, "&[1 hello 2.5 <nil>]"},
659 {"%v", &barray, "&[1 2 3 4 5]"},
660
661
662 {"%v", slice, "[1 2 3 4 5]"},
663 {"%v", islice, "[1 hello 2.5 <nil>]"},
664 {"%v", bslice, "[1 2 3 4 5]"},
665 {"%v", &slice, "&[1 2 3 4 5]"},
666 {"%v", &islice, "&[1 hello 2.5 <nil>]"},
667 {"%v", &bslice, "&[1 2 3 4 5]"},
668
669
670 {"%b", [3]byte{65, 66, 67}, "[1000001 1000010 1000011]"},
671 {"%c", [3]byte{65, 66, 67}, "[A B C]"},
672 {"%d", [3]byte{65, 66, 67}, "[65 66 67]"},
673 {"%o", [3]byte{65, 66, 67}, "[101 102 103]"},
674 {"%U", [3]byte{65, 66, 67}, "[U+0041 U+0042 U+0043]"},
675 {"%v", [3]byte{65, 66, 67}, "[65 66 67]"},
676 {"%v", [1]byte{123}, "[123]"},
677 {"%012v", []byte{}, "[]"},
678 {"%#012v", []byte{}, "[]byte{}"},
679 {"%6v", []byte{1, 11, 111}, "[ 1 11 111]"},
680 {"%06v", []byte{1, 11, 111}, "[000001 000011 000111]"},
681 {"%-6v", []byte{1, 11, 111}, "[1 11 111 ]"},
682 {"%-06v", []byte{1, 11, 111}, "[1 11 111 ]"},
683 {"%#v", []byte{1, 11, 111}, "[]byte{0x1, 0xb, 0x6f}"},
684 {"%#6v", []byte{1, 11, 111}, "[]byte{ 0x1, 0xb, 0x6f}"},
685 {"%#06v", []byte{1, 11, 111}, "[]byte{0x000001, 0x00000b, 0x00006f}"},
686 {"%#-6v", []byte{1, 11, 111}, "[]byte{0x1 , 0xb , 0x6f }"},
687 {"%#-06v", []byte{1, 11, 111}, "[]byte{0x1 , 0xb , 0x6f }"},
688
689 {"% v", []byte{1, 11, 111}, "[ 1 11 111]"},
690 {"%+v", [3]byte{1, 11, 111}, "[1 11 111]"},
691 {"%# -6v", []byte{1, 11, 111}, "[]byte{ 0x1 , 0xb , 0x6f }"},
692 {"%#+-6v", [3]byte{1, 11, 111}, "[3]uint8{0x1 , 0xb , 0x6f }"},
693
694 {"% d", []byte{1, 11, 111}, "[ 1 11 111]"},
695 {"%+d", [3]byte{1, 11, 111}, "[+1 +11 +111]"},
696 {"%# -6d", []byte{1, 11, 111}, "[ 1 11 111 ]"},
697 {"%#+-6d", [3]byte{1, 11, 111}, "[+1 +11 +111 ]"},
698
699
700 {"%v", 1.2345678, "1.2345678"},
701 {"%v", float32(1.2345678), "1.2345678"},
702
703
704 {"%v", 1 + 2i, "(1+2i)"},
705 {"%v", complex64(1 + 2i), "(1+2i)"},
706
707
708 {"%v", A{1, 2, "a", []int{1, 2}}, `{1 2 a [1 2]}`},
709 {"%+v", A{1, 2, "a", []int{1, 2}}, `{i:1 j:2 s:a x:[1 2]}`},
710
711
712 {"%+v", B{1, 2}, `{I:<1> j:2}`},
713 {"%+v", C{1, B{2, 3}}, `{i:1 B:{I:<2> j:3}}`},
714
715
716 {"%s", I(23), `<23>`},
717 {"%q", I(23), `"<23>"`},
718 {"%x", I(23), `3c32333e`},
719 {"%#x", I(23), `0x3c32333e`},
720 {"%# x", I(23), `0x3c 0x32 0x33 0x3e`},
721
722 {"%d", I(23), `23`},
723
724 {"%s", reflect.ValueOf(I(23)), `<23>`},
725
726
727 {"%#v", A{1, 2, "a", []int{1, 2}}, `fmt_test.A{i:1, j:0x2, s:"a", x:[]int{1, 2}}`},
728 {"%#v", new(byte), "(*uint8)(0xPTR)"},
729 {"%#v", make(chan int), "(chan int)(0xPTR)"},
730 {"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"},
731 {"%#v", 1000000000, "1000000000"},
732 {"%#v", map[string]int{"a": 1}, `map[string]int{"a":1}`},
733 {"%#v", map[string]B{"a": {1, 2}}, `map[string]fmt_test.B{"a":fmt_test.B{I:1, j:2}}`},
734 {"%#v", []string{"a", "b"}, `[]string{"a", "b"}`},
735 {"%#v", SI{}, `fmt_test.SI{I:interface {}(nil)}`},
736 {"%#v", []int(nil), `[]int(nil)`},
737 {"%#v", []int{}, `[]int{}`},
738 {"%#v", array, `[5]int{1, 2, 3, 4, 5}`},
739 {"%#v", &array, `&[5]int{1, 2, 3, 4, 5}`},
740 {"%#v", iarray, `[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
741 {"%#v", &iarray, `&[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
742 {"%#v", map[int]byte(nil), `map[int]uint8(nil)`},
743 {"%#v", map[int]byte{}, `map[int]uint8{}`},
744 {"%#v", "foo", `"foo"`},
745 {"%#v", barray, `[5]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
746 {"%#v", bslice, `[]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
747 {"%#v", []int32(nil), "[]int32(nil)"},
748 {"%#v", 1.2345678, "1.2345678"},
749 {"%#v", float32(1.2345678), "1.2345678"},
750
751
752 {"%v", TestFmtInterface, "0xPTR"},
753 {"%v", reflect.ValueOf(TestFmtInterface), "0xPTR"},
754 {"%v", G.GoString, "0xPTR"},
755 {"%v", reflect.ValueOf(G.GoString), "0xPTR"},
756 {"%v", G(23).GoString, "0xPTR"},
757 {"%v", reflect.ValueOf(G(23).GoString), "0xPTR"},
758 {"%v", reflect.ValueOf(G(23)).Method(0), "0xPTR"},
759 {"%v", Fn.String, "0xPTR"},
760 {"%v", reflect.ValueOf(Fn.String), "0xPTR"},
761 {"%v", fnValue, "String(fn)"},
762 {"%v", reflect.ValueOf(fnValue), "String(fn)"},
763 {"%v", [1]Fn{fnValue}, "[String(fn)]"},
764 {"%v", reflect.ValueOf([1]Fn{fnValue}), "[String(fn)]"},
765 {"%v", fnValue.String, "0xPTR"},
766 {"%v", reflect.ValueOf(fnValue.String), "0xPTR"},
767 {"%v", reflect.ValueOf(fnValue).Method(0), "0xPTR"},
768 {"%v", U{}.u, "<nil>"},
769 {"%v", reflect.ValueOf(U{}.u), "<nil>"},
770 {"%v", reflect.ValueOf(U{}).Field(0), "<nil>"},
771 {"%v", U{fn: fnValue}.fn, "String(fn)"},
772 {"%v", reflect.ValueOf(U{fn: fnValue}.fn), "String(fn)"},
773 {"%v", reflect.ValueOf(U{fn: fnValue}).Field(1), "<nil>"},
774
775
776 {"%#v", TestFmtInterface, "(func(*testing.T))(0xPTR)"},
777 {"%#v", reflect.ValueOf(TestFmtInterface), "(func(*testing.T))(0xPTR)"},
778 {"%#v", G.GoString, "(func(fmt_test.G) string)(0xPTR)"},
779 {"%#v", reflect.ValueOf(G.GoString), "(func(fmt_test.G) string)(0xPTR)"},
780 {"%#v", G(23).GoString, "(func() string)(0xPTR)"},
781 {"%#v", reflect.ValueOf(G(23).GoString), "(func() string)(0xPTR)"},
782 {"%#v", reflect.ValueOf(G(23)).Method(0), "(func() string)(0xPTR)"},
783 {"%#v", Fn.String, "(func(fmt_test.Fn) string)(0xPTR)"},
784 {"%#v", reflect.ValueOf(Fn.String), "(func(fmt_test.Fn) string)(0xPTR)"},
785 {"%#v", fnValue, "(fmt_test.Fn)(nil)"},
786 {"%#v", reflect.ValueOf(fnValue), "(fmt_test.Fn)(nil)"},
787 {"%#v", [1]Fn{fnValue}, "[1]fmt_test.Fn{(fmt_test.Fn)(nil)}"},
788 {"%#v", reflect.ValueOf([1]Fn{fnValue}), "[1]fmt_test.Fn{(fmt_test.Fn)(nil)}"},
789 {"%#v", fnValue.String, "(func() string)(0xPTR)"},
790 {"%#v", reflect.ValueOf(fnValue.String), "(func() string)(0xPTR)"},
791 {"%#v", reflect.ValueOf(fnValue).Method(0), "(func() string)(0xPTR)"},
792 {"%#v", U{}.u, "(func() string)(nil)"},
793 {"%#v", reflect.ValueOf(U{}.u), "(func() string)(nil)"},
794 {"%#v", reflect.ValueOf(U{}).Field(0), "(func() string)(nil)"},
795 {"%#v", U{fn: fnValue}.fn, "(fmt_test.Fn)(nil)"},
796 {"%#v", reflect.ValueOf(U{fn: fnValue}.fn), "(fmt_test.Fn)(nil)"},
797 {"%#v", reflect.ValueOf(U{fn: fnValue}).Field(1), "(fmt_test.Fn)(nil)"},
798
799
800 {"%#v", 1.0, "1"},
801 {"%#v", 1000000.0, "1e+06"},
802 {"%#v", float32(1.0), "1"},
803 {"%#v", float32(1000000.0), "1e+06"},
804
805
806 {"%#v", []byte(nil), "[]byte(nil)"},
807 {"%#v", []uint8(nil), "[]byte(nil)"},
808 {"%#v", []byte{}, "[]byte{}"},
809 {"%#v", []uint8{}, "[]byte{}"},
810 {"%#v", reflect.ValueOf([]byte{}), "[]uint8{}"},
811 {"%#v", reflect.ValueOf([]uint8{}), "[]uint8{}"},
812 {"%#v", &[]byte{}, "&[]uint8{}"},
813 {"%#v", &[]byte{}, "&[]uint8{}"},
814 {"%#v", [3]byte{}, "[3]uint8{0x0, 0x0, 0x0}"},
815 {"%#v", [3]uint8{}, "[3]uint8{0x0, 0x0, 0x0}"},
816
817
818 {"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`},
819 {"%x", []int{1, 2, 15}, `[1 2 f]`},
820 {"%d", []int{1, 2, 15}, `[1 2 15]`},
821 {"%d", []byte{1, 2, 15}, `[1 2 15]`},
822 {"%q", []string{"a", "b"}, `["a" "b"]`},
823 {"% 02x", []byte{1}, "01"},
824 {"% 02x", []byte{1, 2, 3}, "01 02 03"},
825
826
827 {"%2x", []byte{}, " "},
828 {"%#2x", []byte{}, " "},
829 {"% 02x", []byte{}, "00"},
830 {"%# 02x", []byte{}, "00"},
831 {"%-2x", []byte{}, " "},
832 {"%-02x", []byte{}, " "},
833 {"%8x", []byte{0xab}, " ab"},
834 {"% 8x", []byte{0xab}, " ab"},
835 {"%#8x", []byte{0xab}, " 0xab"},
836 {"%# 8x", []byte{0xab}, " 0xab"},
837 {"%08x", []byte{0xab}, "000000ab"},
838 {"% 08x", []byte{0xab}, "000000ab"},
839 {"%#08x", []byte{0xab}, "00000xab"},
840 {"%# 08x", []byte{0xab}, "00000xab"},
841 {"%10x", []byte{0xab, 0xcd}, " abcd"},
842 {"% 10x", []byte{0xab, 0xcd}, " ab cd"},
843 {"%#10x", []byte{0xab, 0xcd}, " 0xabcd"},
844 {"%# 10x", []byte{0xab, 0xcd}, " 0xab 0xcd"},
845 {"%010x", []byte{0xab, 0xcd}, "000000abcd"},
846 {"% 010x", []byte{0xab, 0xcd}, "00000ab cd"},
847 {"%#010x", []byte{0xab, 0xcd}, "00000xabcd"},
848 {"%# 010x", []byte{0xab, 0xcd}, "00xab 0xcd"},
849 {"%-10X", []byte{0xab}, "AB "},
850 {"% -010X", []byte{0xab}, "AB "},
851 {"%#-10X", []byte{0xab, 0xcd}, "0XABCD "},
852 {"%# -010X", []byte{0xab, 0xcd}, "0XAB 0XCD "},
853
854 {"%2x", "", " "},
855 {"%#2x", "", " "},
856 {"% 02x", "", "00"},
857 {"%# 02x", "", "00"},
858 {"%-2x", "", " "},
859 {"%-02x", "", " "},
860 {"%8x", "\xab", " ab"},
861 {"% 8x", "\xab", " ab"},
862 {"%#8x", "\xab", " 0xab"},
863 {"%# 8x", "\xab", " 0xab"},
864 {"%08x", "\xab", "000000ab"},
865 {"% 08x", "\xab", "000000ab"},
866 {"%#08x", "\xab", "00000xab"},
867 {"%# 08x", "\xab", "00000xab"},
868 {"%10x", "\xab\xcd", " abcd"},
869 {"% 10x", "\xab\xcd", " ab cd"},
870 {"%#10x", "\xab\xcd", " 0xabcd"},
871 {"%# 10x", "\xab\xcd", " 0xab 0xcd"},
872 {"%010x", "\xab\xcd", "000000abcd"},
873 {"% 010x", "\xab\xcd", "00000ab cd"},
874 {"%#010x", "\xab\xcd", "00000xabcd"},
875 {"%# 010x", "\xab\xcd", "00xab 0xcd"},
876 {"%-10X", "\xab", "AB "},
877 {"% -010X", "\xab", "AB "},
878 {"%#-10X", "\xab\xcd", "0XABCD "},
879 {"%# -010X", "\xab\xcd", "0XAB 0XCD "},
880
881
882 {"%v", renamedBool(true), "true"},
883 {"%d", renamedBool(true), "%!d(fmt_test.renamedBool=true)"},
884 {"%o", renamedInt(8), "10"},
885 {"%d", renamedInt8(-9), "-9"},
886 {"%v", renamedInt16(10), "10"},
887 {"%v", renamedInt32(-11), "-11"},
888 {"%X", renamedInt64(255), "FF"},
889 {"%v", renamedUint(13), "13"},
890 {"%o", renamedUint8(14), "16"},
891 {"%X", renamedUint16(15), "F"},
892 {"%d", renamedUint32(16), "16"},
893 {"%X", renamedUint64(17), "11"},
894 {"%o", renamedUintptr(18), "22"},
895 {"%x", renamedString("thing"), "7468696e67"},
896 {"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`},
897 {"%q", renamedBytes([]byte("hello")), `"hello"`},
898 {"%x", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "68656c6c6f"},
899 {"%X", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "68656C6C6F"},
900 {"%s", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "hello"},
901 {"%q", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, `"hello"`},
902 {"%v", renamedFloat32(22), "22"},
903 {"%v", renamedFloat64(33), "33"},
904 {"%v", renamedComplex64(3 + 4i), "(3+4i)"},
905 {"%v", renamedComplex128(4 - 3i), "(4-3i)"},
906
907
908 {"%x", F(1), "<x=F(1)>"},
909 {"%x", G(2), "2"},
910 {"%+v", S{F(4), G(5)}, "{F:<v=F(4)> G:5}"},
911
912
913 {"%#v", G(6), "GoString(6)"},
914 {"%#v", S{F(7), G(8)}, "fmt_test.S{F:<v=F(7)>, G:GoString(8)}"},
915
916
917 {"%T", byte(0), "uint8"},
918 {"%T", reflect.ValueOf(nil), "reflect.Value"},
919 {"%T", (4 - 3i), "complex128"},
920 {"%T", renamedComplex128(4 - 3i), "fmt_test.renamedComplex128"},
921 {"%T", intVar, "int"},
922 {"%6T", &intVar, " *int"},
923 {"%10T", nil, " <nil>"},
924 {"%-10T", nil, "<nil> "},
925
926
927 {"%p", (*int)(nil), "0x0"},
928 {"%#p", (*int)(nil), "0"},
929 {"%p", &intVar, "0xPTR"},
930 {"%#p", &intVar, "PTR"},
931 {"%p", &array, "0xPTR"},
932 {"%p", &slice, "0xPTR"},
933 {"%8.2p", (*int)(nil), " 0x00"},
934 {"%-20.16p", &intVar, "0xPTR "},
935
936 {"%p", make(chan int), "0xPTR"},
937 {"%p", make(map[int]int), "0xPTR"},
938 {"%p", func() {}, "0xPTR"},
939 {"%p", 27, "%!p(int=27)"},
940 {"%p", nil, "%!p(<nil>)"},
941 {"%#p", nil, "%!p(<nil>)"},
942
943 {"%b", &intVar, "PTR_b"},
944 {"%d", &intVar, "PTR_d"},
945 {"%o", &intVar, "PTR_o"},
946 {"%x", &intVar, "PTR_x"},
947 {"%X", &intVar, "PTR_X"},
948
949 {"%v", nil, "<nil>"},
950 {"%#v", nil, "<nil>"},
951 {"%v", (*int)(nil), "<nil>"},
952 {"%#v", (*int)(nil), "(*int)(nil)"},
953 {"%v", &intVar, "0xPTR"},
954 {"%#v", &intVar, "(*int)(0xPTR)"},
955 {"%8.2v", (*int)(nil), " <nil>"},
956 {"%-20.16v", &intVar, "0xPTR "},
957
958 {"%s", &pValue, "String(p)"},
959 {"%p", &pValue, "0xPTR"},
960
961
962 {"%s", time.Time{}.Month(), "January"},
963 {"%d", time.Time{}.Month(), "1"},
964
965
966 {"", nil, "%!(EXTRA <nil>)"},
967 {"", 2, "%!(EXTRA int=2)"},
968 {"no args", "hello", "no args%!(EXTRA string=hello)"},
969 {"%s %", "hello", "hello %!(NOVERB)"},
970 {"%s %.2", "hello", "hello %!(NOVERB)"},
971 {"%017091901790959340919092959340919017929593813360", 0, "%!(NOVERB)%!(EXTRA int=0)"},
972 {"%184467440737095516170v", 0, "%!(NOVERB)%!(EXTRA int=0)"},
973
974 {"%010.2", "12345", "%!(NOVERB)%!(EXTRA string=12345)"},
975
976
977 {"%v", map[float64]int{NaN: 1, NaN: 1}, "map[NaN:1 NaN:1]"},
978
979
980
1023 {"%.2f", 1.0, "1.00"},
1024 {"%.2f", -1.0, "-1.00"},
1025 {"% .2f", 1.0, " 1.00"},
1026 {"% .2f", -1.0, "-1.00"},
1027 {"%+.2f", 1.0, "+1.00"},
1028 {"%+.2f", -1.0, "-1.00"},
1029 {"%7.2f", 1.0, " 1.00"},
1030 {"%7.2f", -1.0, " -1.00"},
1031 {"% 7.2f", 1.0, " 1.00"},
1032 {"% 7.2f", -1.0, " -1.00"},
1033 {"%+7.2f", 1.0, " +1.00"},
1034 {"%+7.2f", -1.0, " -1.00"},
1035 {"% +7.2f", 1.0, " +1.00"},
1036 {"% +7.2f", -1.0, " -1.00"},
1037 {"%07.2f", 1.0, "0001.00"},
1038 {"%07.2f", -1.0, "-001.00"},
1039 {"% 07.2f", 1.0, " 001.00"},
1040 {"% 07.2f", -1.0, "-001.00"},
1041 {"%+07.2f", 1.0, "+001.00"},
1042 {"%+07.2f", -1.0, "-001.00"},
1043 {"% +07.2f", 1.0, "+001.00"},
1044 {"% +07.2f", -1.0, "-001.00"},
1045
1046
1047 {"%7.2f", 1 + 2i, "( 1.00 +2.00i)"},
1048 {"%+07.2f", -1 - 2i, "(-001.00-002.00i)"},
1049
1050
1051 {"%0-5s", "abc", "abc "},
1052 {"%-05.1f", 1.0, "1.0 "},
1053
1054
1055
1056 {"%06v", []any{+10.0, 10}, "[000010 000010]"},
1057 {"%06v", []any{-10.0, 10}, "[-00010 000010]"},
1058 {"%06v", []any{+10.0 + 10i, 10}, "[(000010+00010i) 000010]"},
1059 {"%06v", []any{-10.0 + 10i, 10}, "[(-00010+00010i) 000010]"},
1060
1061
1062 {"%03.6v", []any{1, 2.0, "x"}, "[000001 002 00x]"},
1063 {"%03.0v", []any{0, 2.0, "x"}, "[ 002 000]"},
1064
1065
1066
1067 {"%v", []complex64{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
1068 {"%v", []complex128{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
1069
1070
1071 {"%.", 3, "%!.(int=3)"},
1072
1073
1074 {"%+10.2f", +104.66 + 440.51i, "( +104.66 +440.51i)"},
1075 {"%+10.2f", -104.66 + 440.51i, "( -104.66 +440.51i)"},
1076 {"%+10.2f", +104.66 - 440.51i, "( +104.66 -440.51i)"},
1077 {"%+10.2f", -104.66 - 440.51i, "( -104.66 -440.51i)"},
1078 {"%+010.2f", +104.66 + 440.51i, "(+000104.66+000440.51i)"},
1079 {"%+010.2f", -104.66 + 440.51i, "(-000104.66+000440.51i)"},
1080 {"%+010.2f", +104.66 - 440.51i, "(+000104.66-000440.51i)"},
1081 {"%+010.2f", -104.66 - 440.51i, "(-000104.66-000440.51i)"},
1082
1083
1084 {"%v", byteStringerSlice, "[X X X X X]"},
1085 {"%s", byteStringerSlice, "hello"},
1086 {"%q", byteStringerSlice, "\"hello\""},
1087 {"%x", byteStringerSlice, "68656c6c6f"},
1088 {"%X", byteStringerSlice, "68656C6C6F"},
1089 {"%#v", byteStringerSlice, "[]fmt_test.byteStringer{0x68, 0x65, 0x6c, 0x6c, 0x6f}"},
1090
1091
1092 {"%v", byteFormatterSlice, "[X X X X X]"},
1093 {"%s", byteFormatterSlice, "hello"},
1094 {"%q", byteFormatterSlice, "\"hello\""},
1095 {"%x", byteFormatterSlice, "68656c6c6f"},
1096 {"%X", byteFormatterSlice, "68656C6C6F"},
1097
1098 {"%#v", byteFormatterSlice, "[]fmt_test.byteFormatter{X, X, X, X, X}"},
1099
1100
1101 {"%s", writeStringFormatter(""), "******"},
1102 {"%s", writeStringFormatter("xyz"), "***xyz***"},
1103 {"%s", writeStringFormatter("⌘/⌘"), "***⌘/⌘***"},
1104
1105
1106
1107
1108 {"%v", reflect.ValueOf(A{}).Field(0).String(), "<int Value>"},
1109 {"%v", reflect.ValueOf(A{}).Field(0), "0"},
1110
1111
1112 {"%s", reflect.ValueOf("hello"), "hello"},
1113 {"%q", reflect.ValueOf("hello"), `"hello"`},
1114 {"%#04x", reflect.ValueOf(256), "0x0100"},
1115
1116
1117 {"%v", reflect.Value{}, "<invalid reflect.Value>"},
1118 {"%v", &reflect.Value{}, "<invalid Value>"},
1119 {"%v", SI{reflect.Value{}}, "{<invalid Value>}"},
1120
1121
1122 {"%☠", nil, "%!☠(<nil>)"},
1123 {"%☠", any(nil), "%!☠(<nil>)"},
1124 {"%☠", int(0), "%!☠(int=0)"},
1125 {"%☠", uint(0), "%!☠(uint=0)"},
1126 {"%☠", []byte{0, 1}, "[%!☠(uint8=0) %!☠(uint8=1)]"},
1127 {"%☠", []uint8{0, 1}, "[%!☠(uint8=0) %!☠(uint8=1)]"},
1128 {"%☠", [1]byte{0}, "[%!☠(uint8=0)]"},
1129 {"%☠", [1]uint8{0}, "[%!☠(uint8=0)]"},
1130 {"%☠", "hello", "%!☠(string=hello)"},
1131 {"%☠", 1.2345678, "%!☠(float64=1.2345678)"},
1132 {"%☠", float32(1.2345678), "%!☠(float32=1.2345678)"},
1133 {"%☠", 1.2345678 + 1.2345678i, "%!☠(complex128=(1.2345678+1.2345678i))"},
1134 {"%☠", complex64(1.2345678 + 1.2345678i), "%!☠(complex64=(1.2345678+1.2345678i))"},
1135 {"%☠", &intVar, "%!☠(*int=0xPTR)"},
1136 {"%☠", make(chan int), "%!☠(chan int=0xPTR)"},
1137 {"%☠", func() {}, "%!☠(func()=0xPTR)"},
1138 {"%☠", reflect.ValueOf(renamedInt(0)), "%!☠(fmt_test.renamedInt=0)"},
1139 {"%☠", SI{renamedInt(0)}, "{%!☠(fmt_test.renamedInt=0)}"},
1140 {"%☠", &[]any{I(1), G(2)}, "&[%!☠(fmt_test.I=1) %!☠(fmt_test.G=2)]"},
1141 {"%☠", SI{&[]any{I(1), G(2)}}, "{%!☠(*[]interface {}=&[1 2])}"},
1142 {"%☠", reflect.Value{}, "<invalid reflect.Value>"},
1143 {"%☠", map[float64]int{NaN: 1}, "map[%!☠(float64=NaN):%!☠(int=1)]"},
1144 }
1145
1146
1147
1148 func zeroFill(prefix string, width int, suffix string) string {
1149 return prefix + strings.Repeat("0", width-len(suffix)) + suffix
1150 }
1151
1152 func TestSprintf(t *testing.T) {
1153 for _, tt := range fmtTests {
1154 s := Sprintf(tt.fmt, tt.val)
1155 i := strings.Index(tt.out, "PTR")
1156 if i >= 0 && i < len(s) {
1157 var pattern, chars string
1158 switch {
1159 case strings.HasPrefix(tt.out[i:], "PTR_b"):
1160 pattern = "PTR_b"
1161 chars = "01"
1162 case strings.HasPrefix(tt.out[i:], "PTR_o"):
1163 pattern = "PTR_o"
1164 chars = "01234567"
1165 case strings.HasPrefix(tt.out[i:], "PTR_d"):
1166 pattern = "PTR_d"
1167 chars = "0123456789"
1168 case strings.HasPrefix(tt.out[i:], "PTR_x"):
1169 pattern = "PTR_x"
1170 chars = "0123456789abcdef"
1171 case strings.HasPrefix(tt.out[i:], "PTR_X"):
1172 pattern = "PTR_X"
1173 chars = "0123456789ABCDEF"
1174 default:
1175 pattern = "PTR"
1176 chars = "0123456789abcdefABCDEF"
1177 }
1178 p := s[:i] + pattern
1179 for j := i; j < len(s); j++ {
1180 if !strings.ContainsRune(chars, rune(s[j])) {
1181 p += s[j:]
1182 break
1183 }
1184 }
1185 s = p
1186 }
1187 if s != tt.out {
1188 if _, ok := tt.val.(string); ok {
1189
1190
1191 t.Errorf("Sprintf(%q, %q) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out)
1192 } else {
1193 t.Errorf("Sprintf(%q, %v) = %q want %q", tt.fmt, tt.val, s, tt.out)
1194 }
1195 }
1196 }
1197 }
1198
1199
1200
1201 func TestComplexFormatting(t *testing.T) {
1202 var yesNo = []bool{true, false}
1203 var values = []float64{1, 0, -1, posInf, negInf, NaN}
1204 for _, plus := range yesNo {
1205 for _, zero := range yesNo {
1206 for _, space := range yesNo {
1207 for _, char := range "fFeEgG" {
1208 realFmt := "%"
1209 if zero {
1210 realFmt += "0"
1211 }
1212 if space {
1213 realFmt += " "
1214 }
1215 if plus {
1216 realFmt += "+"
1217 }
1218 realFmt += "10.2"
1219 realFmt += string(char)
1220
1221 imagFmt := "%"
1222 if zero {
1223 imagFmt += "0"
1224 }
1225 imagFmt += "+"
1226 imagFmt += "10.2"
1227 imagFmt += string(char)
1228 for _, realValue := range values {
1229 for _, imagValue := range values {
1230 one := Sprintf(realFmt, complex(realValue, imagValue))
1231 two := Sprintf("("+realFmt+imagFmt+"i)", realValue, imagValue)
1232 if one != two {
1233 t.Error(f, one, two)
1234 }
1235 }
1236 }
1237 }
1238 }
1239 }
1240 }
1241 }
1242
1243 type SE []any
1244
1245 var reorderTests = []struct {
1246 fmt string
1247 val SE
1248 out string
1249 }{
1250 {"%[1]d", SE{1}, "1"},
1251 {"%[2]d", SE{2, 1}, "1"},
1252 {"%[2]d %[1]d", SE{1, 2}, "2 1"},
1253 {"%[2]*[1]d", SE{2, 5}, " 2"},
1254 {"%6.2f", SE{12.0}, " 12.00"},
1255 {"%[3]*.[2]*[1]f", SE{12.0, 2, 6}, " 12.00"},
1256 {"%[1]*.[2]*[3]f", SE{6, 2, 12.0}, " 12.00"},
1257 {"%10f", SE{12.0}, " 12.000000"},
1258 {"%[1]*[3]f", SE{10, 99, 12.0}, " 12.000000"},
1259 {"%.6f", SE{12.0}, "12.000000"},
1260 {"%.[1]*[3]f", SE{6, 99, 12.0}, "12.000000"},
1261 {"%6.f", SE{12.0}, " 12"},
1262 {"%[1]*.[3]f", SE{6, 3, 12.0}, " 12"},
1263
1264 {"%d %d %d %#[1]o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015"},
1265
1266
1267 {"%[d", SE{2, 1}, "%!d(BADINDEX)"},
1268 {"%]d", SE{2, 1}, "%!](int=2)d%!(EXTRA int=1)"},
1269 {"%[]d", SE{2, 1}, "%!d(BADINDEX)"},
1270 {"%[-3]d", SE{2, 1}, "%!d(BADINDEX)"},
1271 {"%[99]d", SE{2, 1}, "%!d(BADINDEX)"},
1272 {"%[3]", SE{2, 1}, "%!(NOVERB)"},
1273 {"%[1].2d", SE{5, 6}, "%!d(BADINDEX)"},
1274 {"%[1]2d", SE{2, 1}, "%!d(BADINDEX)"},
1275 {"%3.[2]d", SE{7}, "%!d(BADINDEX)"},
1276 {"%.[2]d", SE{7}, "%!d(BADINDEX)"},
1277 {"%d %d %d %#[1]o %#o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015 %!o(MISSING)"},
1278 {"%[5]d %[2]d %d", SE{1, 2, 3}, "%!d(BADINDEX) 2 3"},
1279 {"%d %[3]d %d", SE{1, 2}, "1 %!d(BADINDEX) 2"},
1280 {"%.[]", SE{}, "%!](BADINDEX)"},
1281 {"%.-3d", SE{42}, "%!-(int=42)3d"},
1282 {"%2147483648d", SE{42}, "%!(NOVERB)%!(EXTRA int=42)"},
1283 {"%-2147483648d", SE{42}, "%!(NOVERB)%!(EXTRA int=42)"},
1284 {"%.2147483648d", SE{42}, "%!(NOVERB)%!(EXTRA int=42)"},
1285 }
1286
1287 func TestReorder(t *testing.T) {
1288 for _, tt := range reorderTests {
1289 s := Sprintf(tt.fmt, tt.val...)
1290 if s != tt.out {
1291 t.Errorf("Sprintf(%q, %v) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out)
1292 }
1293 }
1294 }
1295
1296 func BenchmarkSprintfPadding(b *testing.B) {
1297 b.RunParallel(func(pb *testing.PB) {
1298 for pb.Next() {
1299 _ = Sprintf("%16f", 1.0)
1300 }
1301 })
1302 }
1303
1304 func BenchmarkSprintfEmpty(b *testing.B) {
1305 b.RunParallel(func(pb *testing.PB) {
1306 for pb.Next() {
1307 _ = Sprintf("")
1308 }
1309 })
1310 }
1311
1312 func BenchmarkSprintfString(b *testing.B) {
1313 b.RunParallel(func(pb *testing.PB) {
1314 for pb.Next() {
1315 _ = Sprintf("%s", "hello")
1316 }
1317 })
1318 }
1319
1320 func BenchmarkSprintfTruncateString(b *testing.B) {
1321 b.RunParallel(func(pb *testing.PB) {
1322 for pb.Next() {
1323 _ = Sprintf("%.3s", "日本語日本語日本語日本語")
1324 }
1325 })
1326 }
1327
1328 func BenchmarkSprintfTruncateBytes(b *testing.B) {
1329 var bytes any = []byte("日本語日本語日本語日本語")
1330 b.RunParallel(func(pb *testing.PB) {
1331 for pb.Next() {
1332 _ = Sprintf("%.3s", bytes)
1333 }
1334 })
1335 }
1336
1337 func BenchmarkSprintfSlowParsingPath(b *testing.B) {
1338 b.RunParallel(func(pb *testing.PB) {
1339 for pb.Next() {
1340 _ = Sprintf("%.v", nil)
1341 }
1342 })
1343 }
1344
1345 func BenchmarkSprintfQuoteString(b *testing.B) {
1346 b.RunParallel(func(pb *testing.PB) {
1347 for pb.Next() {
1348 _ = Sprintf("%q", "日本語日本語日本語")
1349 }
1350 })
1351 }
1352
1353 func BenchmarkSprintfInt(b *testing.B) {
1354 b.RunParallel(func(pb *testing.PB) {
1355 for pb.Next() {
1356 _ = Sprintf("%d", 5)
1357 }
1358 })
1359 }
1360
1361 func BenchmarkSprintfIntInt(b *testing.B) {
1362 b.RunParallel(func(pb *testing.PB) {
1363 for pb.Next() {
1364 _ = Sprintf("%d %d", 5, 6)
1365 }
1366 })
1367 }
1368
1369 func BenchmarkSprintfPrefixedInt(b *testing.B) {
1370 b.RunParallel(func(pb *testing.PB) {
1371 for pb.Next() {
1372 _ = Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6)
1373 }
1374 })
1375 }
1376
1377 func BenchmarkSprintfFloat(b *testing.B) {
1378 b.RunParallel(func(pb *testing.PB) {
1379 for pb.Next() {
1380 _ = Sprintf("%g", 5.23184)
1381 }
1382 })
1383 }
1384
1385 func BenchmarkSprintfComplex(b *testing.B) {
1386 b.RunParallel(func(pb *testing.PB) {
1387 for pb.Next() {
1388 _ = Sprintf("%f", 5.23184+5.23184i)
1389 }
1390 })
1391 }
1392
1393 func BenchmarkSprintfBoolean(b *testing.B) {
1394 b.RunParallel(func(pb *testing.PB) {
1395 for pb.Next() {
1396 _ = Sprintf("%t", true)
1397 }
1398 })
1399 }
1400
1401 func BenchmarkSprintfHexString(b *testing.B) {
1402 b.RunParallel(func(pb *testing.PB) {
1403 for pb.Next() {
1404 _ = Sprintf("% #x", "0123456789abcdef")
1405 }
1406 })
1407 }
1408
1409 func BenchmarkSprintfHexBytes(b *testing.B) {
1410 data := []byte("0123456789abcdef")
1411 b.RunParallel(func(pb *testing.PB) {
1412 for pb.Next() {
1413 _ = Sprintf("% #x", data)
1414 }
1415 })
1416 }
1417
1418 func BenchmarkSprintfBytes(b *testing.B) {
1419 data := []byte("0123456789abcdef")
1420 b.RunParallel(func(pb *testing.PB) {
1421 for pb.Next() {
1422 _ = Sprintf("%v", data)
1423 }
1424 })
1425 }
1426
1427 func BenchmarkSprintfStringer(b *testing.B) {
1428 stringer := I(12345)
1429 b.RunParallel(func(pb *testing.PB) {
1430 for pb.Next() {
1431 _ = Sprintf("%v", stringer)
1432 }
1433 })
1434 }
1435
1436 func BenchmarkSprintfStructure(b *testing.B) {
1437 s := &[]any{SI{12345}, map[int]string{0: "hello"}}
1438 b.RunParallel(func(pb *testing.PB) {
1439 for pb.Next() {
1440 _ = Sprintf("%#v", s)
1441 }
1442 })
1443 }
1444
1445 func BenchmarkManyArgs(b *testing.B) {
1446 b.RunParallel(func(pb *testing.PB) {
1447 var buf bytes.Buffer
1448 for pb.Next() {
1449 buf.Reset()
1450 Fprintf(&buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world")
1451 }
1452 })
1453 }
1454
1455 func BenchmarkFprintInt(b *testing.B) {
1456 var buf bytes.Buffer
1457 for i := 0; i < b.N; i++ {
1458 buf.Reset()
1459 Fprint(&buf, 123456)
1460 }
1461 }
1462
1463 func BenchmarkFprintfBytes(b *testing.B) {
1464 data := []byte(string("0123456789"))
1465 var buf bytes.Buffer
1466 for i := 0; i < b.N; i++ {
1467 buf.Reset()
1468 Fprintf(&buf, "%s", data)
1469 }
1470 }
1471
1472 func BenchmarkFprintIntNoAlloc(b *testing.B) {
1473 var x any = 123456
1474 var buf bytes.Buffer
1475 for i := 0; i < b.N; i++ {
1476 buf.Reset()
1477 Fprint(&buf, x)
1478 }
1479 }
1480
1481 var mallocBuf bytes.Buffer
1482 var mallocPointer *int
1483
1484 var mallocTest = []struct {
1485 count int
1486 desc string
1487 fn func()
1488 }{
1489 {0, `Sprintf("")`, func() { _ = Sprintf("") }},
1490 {1, `Sprintf("xxx")`, func() { _ = Sprintf("xxx") }},
1491 {0, `Sprintf("%x")`, func() { _ = Sprintf("%x", 7) }},
1492 {1, `Sprintf("%x")`, func() { _ = Sprintf("%x", 1<<16) }},
1493 {3, `Sprintf("%80000s")`, func() { _ = Sprintf("%80000s", "hello") }},
1494 {1, `Sprintf("%s")`, func() { _ = Sprintf("%s", "hello") }},
1495 {1, `Sprintf("%x %x")`, func() { _ = Sprintf("%x %x", 7, 112) }},
1496 {1, `Sprintf("%g")`, func() { _ = Sprintf("%g", float32(3.14159)) }},
1497 {0, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }},
1498 {0, `Fprintf(buf, "%x")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%x", 7) }},
1499 {0, `Fprintf(buf, "%x")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%x", 1<<16) }},
1500 {1, `Fprintf(buf, "%x")`, func() { mallocBuf.Reset(); i := 1 << 16; Fprintf(&mallocBuf, "%x", i) }},
1501 {4, `Fprintf(buf, "%v")`, func() { mallocBuf.Reset(); s := []int{1, 2}; Fprintf(&mallocBuf, "%v", s) }},
1502 {1, `Fprintf(buf, "%v")`, func() { mallocBuf.Reset(); type P struct{ x, y int }; Fprintf(&mallocBuf, "%v", P{1, 2}) }},
1503 {2, `Fprintf(buf, "%80000s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%80000s", "hello") }},
1504
1505 {0, `Fprintf(buf, "%x %x %x")`, func() {
1506 mallocBuf.Reset()
1507 Fprintf(&mallocBuf, "%x %x %x", mallocPointer, mallocPointer, mallocPointer)
1508 }},
1509 }
1510
1511 var _ bytes.Buffer
1512
1513 func TestCountMallocs(t *testing.T) {
1514 switch {
1515 case testing.Short():
1516 t.Skip("skipping malloc count in short mode")
1517 case race.Enabled:
1518 t.Skip("skipping malloc count under race detector")
1519 }
1520 for _, mt := range mallocTest {
1521 mallocs := testing.AllocsPerRun(100, mt.fn)
1522 if got, max := mallocs, float64(mt.count); got > max {
1523 t.Errorf("%s: got %v allocs, want <=%v", mt.desc, got, max)
1524 }
1525 }
1526 }
1527
1528 type flagPrinter struct{}
1529
1530 func (flagPrinter) Format(f State, c rune) {
1531 s := "%"
1532 for i := 0; i < 128; i++ {
1533 if f.Flag(i) {
1534 s += string(rune(i))
1535 }
1536 }
1537 if w, ok := f.Width(); ok {
1538 s += Sprintf("%d", w)
1539 }
1540 if p, ok := f.Precision(); ok {
1541 s += Sprintf(".%d", p)
1542 }
1543 s += string(c)
1544 io.WriteString(f, "["+s+"]")
1545 }
1546
1547 var flagtests = []struct {
1548 in string
1549 out string
1550 }{
1551 {"%a", "[%a]"},
1552 {"%-a", "[%-a]"},
1553 {"%+a", "[%+a]"},
1554 {"%#a", "[%#a]"},
1555 {"% a", "[% a]"},
1556 {"%0a", "[%0a]"},
1557 {"%1.2a", "[%1.2a]"},
1558 {"%-1.2a", "[%-1.2a]"},
1559 {"%+1.2a", "[%+1.2a]"},
1560 {"%-+1.2a", "[%+-1.2a]"},
1561 {"%-+1.2abc", "[%+-1.2a]bc"},
1562 {"%-1.2abc", "[%-1.2a]bc"},
1563 {"%-0abc", "[%-0a]bc"},
1564 }
1565
1566 func TestFlagParser(t *testing.T) {
1567 var flagprinter flagPrinter
1568 for _, tt := range flagtests {
1569 s := Sprintf(tt.in, &flagprinter)
1570 if s != tt.out {
1571 t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out)
1572 }
1573 }
1574 }
1575
1576 func TestStructPrinter(t *testing.T) {
1577 type T struct {
1578 a string
1579 b string
1580 c int
1581 }
1582 var s T
1583 s.a = "abc"
1584 s.b = "def"
1585 s.c = 123
1586 var tests = []struct {
1587 fmt string
1588 out string
1589 }{
1590 {"%v", "{abc def 123}"},
1591 {"%+v", "{a:abc b:def c:123}"},
1592 {"%#v", `fmt_test.T{a:"abc", b:"def", c:123}`},
1593 }
1594 for _, tt := range tests {
1595 out := Sprintf(tt.fmt, s)
1596 if out != tt.out {
1597 t.Errorf("Sprintf(%q, s) = %#q, want %#q", tt.fmt, out, tt.out)
1598 }
1599
1600 out = Sprintf(tt.fmt, &s)
1601 if out != "&"+tt.out {
1602 t.Errorf("Sprintf(%q, &s) = %#q, want %#q", tt.fmt, out, "&"+tt.out)
1603 }
1604 }
1605 }
1606
1607 func TestSlicePrinter(t *testing.T) {
1608 slice := []int{}
1609 s := Sprint(slice)
1610 if s != "[]" {
1611 t.Errorf("empty slice printed as %q not %q", s, "[]")
1612 }
1613 slice = []int{1, 2, 3}
1614 s = Sprint(slice)
1615 if s != "[1 2 3]" {
1616 t.Errorf("slice: got %q expected %q", s, "[1 2 3]")
1617 }
1618 s = Sprint(&slice)
1619 if s != "&[1 2 3]" {
1620 t.Errorf("&slice: got %q expected %q", s, "&[1 2 3]")
1621 }
1622 }
1623
1624
1625
1626 func presentInMap(s string, a []string, t *testing.T) {
1627 for i := 0; i < len(a); i++ {
1628 loc := strings.Index(s, a[i])
1629 if loc < 0 {
1630 t.Errorf("map print: expected to find %q in %q", a[i], s)
1631 }
1632
1633 loc += len(a[i])
1634 if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') {
1635 t.Errorf("map print: %q not properly terminated in %q", a[i], s)
1636 }
1637 }
1638 }
1639
1640 func TestMapPrinter(t *testing.T) {
1641 m0 := make(map[int]string)
1642 s := Sprint(m0)
1643 if s != "map[]" {
1644 t.Errorf("empty map printed as %q not %q", s, "map[]")
1645 }
1646 m1 := map[int]string{1: "one", 2: "two", 3: "three"}
1647 a := []string{"1:one", "2:two", "3:three"}
1648 presentInMap(Sprintf("%v", m1), a, t)
1649 presentInMap(Sprint(m1), a, t)
1650
1651 if !strings.HasPrefix(Sprint(&m1), "&") {
1652 t.Errorf("no initial & for address of map")
1653 }
1654 presentInMap(Sprintf("%v", &m1), a, t)
1655 presentInMap(Sprint(&m1), a, t)
1656 }
1657
1658 func TestEmptyMap(t *testing.T) {
1659 const emptyMapStr = "map[]"
1660 var m map[string]int
1661 s := Sprint(m)
1662 if s != emptyMapStr {
1663 t.Errorf("nil map printed as %q not %q", s, emptyMapStr)
1664 }
1665 m = make(map[string]int)
1666 s = Sprint(m)
1667 if s != emptyMapStr {
1668 t.Errorf("empty map printed as %q not %q", s, emptyMapStr)
1669 }
1670 }
1671
1672
1673
1674 func TestBlank(t *testing.T) {
1675 got := Sprint("<", 1, ">:", 1, 2, 3, "!")
1676 expect := "<1>:1 2 3!"
1677 if got != expect {
1678 t.Errorf("got %q expected %q", got, expect)
1679 }
1680 }
1681
1682
1683
1684 func TestBlankln(t *testing.T) {
1685 got := Sprintln("<", 1, ">:", 1, 2, 3, "!")
1686 expect := "< 1 >: 1 2 3 !\n"
1687 if got != expect {
1688 t.Errorf("got %q expected %q", got, expect)
1689 }
1690 }
1691
1692
1693 func TestFormatterPrintln(t *testing.T) {
1694 f := F(1)
1695 expect := "<v=F(1)>\n"
1696 s := Sprint(f, "\n")
1697 if s != expect {
1698 t.Errorf("Sprint wrong with Formatter: expected %q got %q", expect, s)
1699 }
1700 s = Sprintln(f)
1701 if s != expect {
1702 t.Errorf("Sprintln wrong with Formatter: expected %q got %q", expect, s)
1703 }
1704 s = Sprintf("%v\n", f)
1705 if s != expect {
1706 t.Errorf("Sprintf wrong with Formatter: expected %q got %q", expect, s)
1707 }
1708 }
1709
1710 func args(a ...any) []any { return a }
1711
1712 var startests = []struct {
1713 fmt string
1714 in []any
1715 out string
1716 }{
1717 {"%*d", args(4, 42), " 42"},
1718 {"%-*d", args(4, 42), "42 "},
1719 {"%*d", args(-4, 42), "42 "},
1720 {"%-*d", args(-4, 42), "42 "},
1721 {"%.*d", args(4, 42), "0042"},
1722 {"%*.*d", args(8, 4, 42), " 0042"},
1723 {"%0*d", args(4, 42), "0042"},
1724
1725 {"%0*d", args(uint(4), 42), "0042"},
1726 {"%0*d", args(uint64(4), 42), "0042"},
1727 {"%0*d", args('\x04', 42), "0042"},
1728 {"%0*d", args(uintptr(4), 42), "0042"},
1729
1730
1731 {"%*d", args(nil, 42), "%!(BADWIDTH)42"},
1732 {"%*d", args(int(1e7), 42), "%!(BADWIDTH)42"},
1733 {"%*d", args(int(-1e7), 42), "%!(BADWIDTH)42"},
1734 {"%.*d", args(nil, 42), "%!(BADPREC)42"},
1735 {"%.*d", args(-1, 42), "%!(BADPREC)42"},
1736 {"%.*d", args(int(1e7), 42), "%!(BADPREC)42"},
1737 {"%.*d", args(uint(1e7), 42), "%!(BADPREC)42"},
1738 {"%.*d", args(uint64(1<<63), 42), "%!(BADPREC)42"},
1739 {"%.*d", args(uint64(1<<64-1), 42), "%!(BADPREC)42"},
1740 {"%*d", args(5, "foo"), "%!d(string= foo)"},
1741 {"%*% %d", args(20, 5), "% 5"},
1742 {"%*", args(4), "%!(NOVERB)"},
1743 }
1744
1745 func TestWidthAndPrecision(t *testing.T) {
1746 for i, tt := range startests {
1747 s := Sprintf(tt.fmt, tt.in...)
1748 if s != tt.out {
1749 t.Errorf("#%d: %q: got %q expected %q", i, tt.fmt, s, tt.out)
1750 }
1751 }
1752 }
1753
1754
1755 type PanicS struct {
1756 message any
1757 }
1758
1759
1760 func (p PanicS) String() string {
1761 panic(p.message)
1762 }
1763
1764
1765 type PanicGo struct {
1766 message any
1767 }
1768
1769
1770 func (p PanicGo) GoString() string {
1771 panic(p.message)
1772 }
1773
1774
1775 type PanicF struct {
1776 message any
1777 }
1778
1779
1780 func (p PanicF) Format(f State, c rune) {
1781 panic(p.message)
1782 }
1783
1784 var panictests = []struct {
1785 fmt string
1786 in any
1787 out string
1788 }{
1789
1790 {"%s", (*PanicS)(nil), "<nil>"},
1791 {"%s", PanicS{io.ErrUnexpectedEOF}, "%!s(PANIC=String method: unexpected EOF)"},
1792 {"%s", PanicS{3}, "%!s(PANIC=String method: 3)"},
1793
1794 {"%#v", (*PanicGo)(nil), "<nil>"},
1795 {"%#v", PanicGo{io.ErrUnexpectedEOF}, "%!v(PANIC=GoString method: unexpected EOF)"},
1796 {"%#v", PanicGo{3}, "%!v(PANIC=GoString method: 3)"},
1797
1798 {"%#v", []any{PanicGo{3}, PanicGo{3}}, "[]interface {}{%!v(PANIC=GoString method: 3), %!v(PANIC=GoString method: 3)}"},
1799
1800 {"%s", (*PanicF)(nil), "<nil>"},
1801 {"%s", PanicF{io.ErrUnexpectedEOF}, "%!s(PANIC=Format method: unexpected EOF)"},
1802 {"%s", PanicF{3}, "%!s(PANIC=Format method: 3)"},
1803 }
1804
1805 func TestPanics(t *testing.T) {
1806 for i, tt := range panictests {
1807 s := Sprintf(tt.fmt, tt.in)
1808 if s != tt.out {
1809 t.Errorf("%d: %q: got %q expected %q", i, tt.fmt, s, tt.out)
1810 }
1811 }
1812 }
1813
1814
1815 var recurCount = 0
1816
1817 type Recur struct {
1818 i int
1819 failed *bool
1820 }
1821
1822 func (r *Recur) String() string {
1823 if recurCount++; recurCount > 10 {
1824 *r.failed = true
1825 return "FAIL"
1826 }
1827
1828
1829
1830 return Sprintf("recur@%p value: %d", r, r.i)
1831 }
1832
1833 func TestBadVerbRecursion(t *testing.T) {
1834 failed := false
1835 r := &Recur{3, &failed}
1836 _ = Sprintf("recur@%p value: %d\n", &r, r.i)
1837 if failed {
1838 t.Error("fail with pointer")
1839 }
1840 failed = false
1841 r = &Recur{4, &failed}
1842 _ = Sprintf("recur@%p, value: %d\n", r, r.i)
1843 if failed {
1844 t.Error("fail with value")
1845 }
1846 }
1847
1848 func TestIsSpace(t *testing.T) {
1849
1850
1851 for i := rune(0); i <= unicode.MaxRune; i++ {
1852 if IsSpace(i) != unicode.IsSpace(i) {
1853 t.Errorf("isSpace(%U) = %v, want %v", i, IsSpace(i), unicode.IsSpace(i))
1854 }
1855 }
1856 }
1857
1858 func hideFromVet(s string) string { return s }
1859
1860 func TestNilDoesNotBecomeTyped(t *testing.T) {
1861 type A struct{}
1862 type B struct{}
1863 var a *A = nil
1864 var b B = B{}
1865 got := Sprintf(hideFromVet("%s %s %s %s %s"), nil, a, nil, b, nil)
1866 const expect = "%!s(<nil>) %!s(*fmt_test.A=<nil>) %!s(<nil>) {} %!s(<nil>)"
1867 if got != expect {
1868 t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got)
1869 }
1870 }
1871
1872 var formatterFlagTests = []struct {
1873 in string
1874 val any
1875 out string
1876 }{
1877
1878 {"%a", flagPrinter{}, "[%a]"},
1879 {"%-a", flagPrinter{}, "[%-a]"},
1880 {"%+a", flagPrinter{}, "[%+a]"},
1881 {"%#a", flagPrinter{}, "[%#a]"},
1882 {"% a", flagPrinter{}, "[% a]"},
1883 {"%0a", flagPrinter{}, "[%0a]"},
1884 {"%1.2a", flagPrinter{}, "[%1.2a]"},
1885 {"%-1.2a", flagPrinter{}, "[%-1.2a]"},
1886 {"%+1.2a", flagPrinter{}, "[%+1.2a]"},
1887 {"%-+1.2a", flagPrinter{}, "[%+-1.2a]"},
1888 {"%-+1.2abc", flagPrinter{}, "[%+-1.2a]bc"},
1889 {"%-1.2abc", flagPrinter{}, "[%-1.2a]bc"},
1890 {"%-0abc", flagPrinter{}, "[%-0a]bc"},
1891
1892
1893 {"%a", [1]flagPrinter{}, "[[%a]]"},
1894 {"%-a", [1]flagPrinter{}, "[[%-a]]"},
1895 {"%+a", [1]flagPrinter{}, "[[%+a]]"},
1896 {"%#a", [1]flagPrinter{}, "[[%#a]]"},
1897 {"% a", [1]flagPrinter{}, "[[% a]]"},
1898 {"%0a", [1]flagPrinter{}, "[[%0a]]"},
1899 {"%1.2a", [1]flagPrinter{}, "[[%1.2a]]"},
1900 {"%-1.2a", [1]flagPrinter{}, "[[%-1.2a]]"},
1901 {"%+1.2a", [1]flagPrinter{}, "[[%+1.2a]]"},
1902 {"%-+1.2a", [1]flagPrinter{}, "[[%+-1.2a]]"},
1903 {"%-+1.2abc", [1]flagPrinter{}, "[[%+-1.2a]]bc"},
1904 {"%-1.2abc", [1]flagPrinter{}, "[[%-1.2a]]bc"},
1905 {"%-0abc", [1]flagPrinter{}, "[[%-0a]]bc"},
1906
1907
1908 {"%v", flagPrinter{}, "[%v]"},
1909 {"%-v", flagPrinter{}, "[%-v]"},
1910 {"%+v", flagPrinter{}, "[%+v]"},
1911 {"%#v", flagPrinter{}, "[%#v]"},
1912 {"% v", flagPrinter{}, "[% v]"},
1913 {"%0v", flagPrinter{}, "[%0v]"},
1914 {"%1.2v", flagPrinter{}, "[%1.2v]"},
1915 {"%-1.2v", flagPrinter{}, "[%-1.2v]"},
1916 {"%+1.2v", flagPrinter{}, "[%+1.2v]"},
1917 {"%-+1.2v", flagPrinter{}, "[%+-1.2v]"},
1918 {"%-+1.2vbc", flagPrinter{}, "[%+-1.2v]bc"},
1919 {"%-1.2vbc", flagPrinter{}, "[%-1.2v]bc"},
1920 {"%-0vbc", flagPrinter{}, "[%-0v]bc"},
1921
1922
1923 {"%v", [1]flagPrinter{}, "[[%v]]"},
1924 {"%-v", [1]flagPrinter{}, "[[%-v]]"},
1925 {"%+v", [1]flagPrinter{}, "[[%+v]]"},
1926 {"%#v", [1]flagPrinter{}, "[1]fmt_test.flagPrinter{[%#v]}"},
1927 {"% v", [1]flagPrinter{}, "[[% v]]"},
1928 {"%0v", [1]flagPrinter{}, "[[%0v]]"},
1929 {"%1.2v", [1]flagPrinter{}, "[[%1.2v]]"},
1930 {"%-1.2v", [1]flagPrinter{}, "[[%-1.2v]]"},
1931 {"%+1.2v", [1]flagPrinter{}, "[[%+1.2v]]"},
1932 {"%-+1.2v", [1]flagPrinter{}, "[[%+-1.2v]]"},
1933 {"%-+1.2vbc", [1]flagPrinter{}, "[[%+-1.2v]]bc"},
1934 {"%-1.2vbc", [1]flagPrinter{}, "[[%-1.2v]]bc"},
1935 {"%-0vbc", [1]flagPrinter{}, "[[%-0v]]bc"},
1936 }
1937
1938 func TestFormatterFlags(t *testing.T) {
1939 for _, tt := range formatterFlagTests {
1940 s := Sprintf(tt.in, tt.val)
1941 if s != tt.out {
1942 t.Errorf("Sprintf(%q, %T) = %q, want %q", tt.in, tt.val, s, tt.out)
1943 }
1944 }
1945 }
1946
1947 func TestParsenum(t *testing.T) {
1948 testCases := []struct {
1949 s string
1950 start, end int
1951 num int
1952 isnum bool
1953 newi int
1954 }{
1955 {"a123", 0, 4, 0, false, 0},
1956 {"1234", 1, 1, 0, false, 1},
1957 {"123a", 0, 4, 123, true, 3},
1958 {"12a3", 0, 4, 12, true, 2},
1959 {"1234", 0, 4, 1234, true, 4},
1960 {"1a234", 1, 3, 0, false, 1},
1961 }
1962 for _, tt := range testCases {
1963 num, isnum, newi := Parsenum(tt.s, tt.start, tt.end)
1964 if num != tt.num || isnum != tt.isnum || newi != tt.newi {
1965 t.Errorf("parsenum(%q, %d, %d) = %d, %v, %d, want %d, %v, %d", tt.s, tt.start, tt.end, num, isnum, newi, tt.num, tt.isnum, tt.newi)
1966 }
1967 }
1968 }
1969
1970
1971
1972
1973 const (
1974 appendResult = "hello world, 23"
1975 hello = "hello "
1976 )
1977
1978 func TestAppendf(t *testing.T) {
1979 b := make([]byte, 100)
1980 b = b[:copy(b, hello)]
1981 got := Appendf(b, "world, %d", 23)
1982 if string(got) != appendResult {
1983 t.Fatalf("Appendf returns %q not %q", got, appendResult)
1984 }
1985 if &b[0] != &got[0] {
1986 t.Fatalf("Appendf allocated a new slice")
1987 }
1988 }
1989
1990 func TestAppend(t *testing.T) {
1991 b := make([]byte, 100)
1992 b = b[:copy(b, hello)]
1993 got := Append(b, "world", ", ", 23)
1994 if string(got) != appendResult {
1995 t.Fatalf("Append returns %q not %q", got, appendResult)
1996 }
1997 if &b[0] != &got[0] {
1998 t.Fatalf("Append allocated a new slice")
1999 }
2000 }
2001
2002 func TestAppendln(t *testing.T) {
2003 b := make([]byte, 100)
2004 b = b[:copy(b, hello)]
2005 got := Appendln(b, "world,", 23)
2006 if string(got) != appendResult+"\n" {
2007 t.Fatalf("Appendln returns %q not %q", got, appendResult+"\n")
2008 }
2009 if &b[0] != &got[0] {
2010 t.Fatalf("Appendln allocated a new slice")
2011 }
2012 }
2013
View as plain text