libgo: Update to Go 1.3 release.
[official-gcc.git] / libgo / go / fmt / fmt_test.go
blob8e6923119de80ff72a401a6103756a44566a212b
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.
5 package fmt_test
7 import (
8 "bytes"
9 . "fmt"
10 "io"
11 "math"
12 "runtime"
13 "strings"
14 "testing"
15 "time"
16 "unicode"
19 type (
20 renamedBool bool
21 renamedInt int
22 renamedInt8 int8
23 renamedInt16 int16
24 renamedInt32 int32
25 renamedInt64 int64
26 renamedUint uint
27 renamedUint8 uint8
28 renamedUint16 uint16
29 renamedUint32 uint32
30 renamedUint64 uint64
31 renamedUintptr uintptr
32 renamedString string
33 renamedBytes []byte
34 renamedFloat32 float32
35 renamedFloat64 float64
36 renamedComplex64 complex64
37 renamedComplex128 complex128
40 func TestFmtInterface(t *testing.T) {
41 var i1 interface{}
42 i1 = "abc"
43 s := Sprintf("%s", i1)
44 if s != "abc" {
45 t.Errorf(`Sprintf("%%s", empty("abc")) = %q want %q`, s, "abc")
49 const b32 uint32 = 1<<32 - 1
50 const b64 uint64 = 1<<64 - 1
52 var array = [5]int{1, 2, 3, 4, 5}
53 var iarray = [4]interface{}{1, "hello", 2.5, nil}
54 var slice = array[:]
55 var islice = iarray[:]
57 type A struct {
58 i int
59 j uint
60 s string
61 x []int
64 type I int
66 func (i I) String() string { return Sprintf("<%d>", int(i)) }
68 type B struct {
69 I I
70 j int
73 type C struct {
74 i int
78 type F int
80 func (f F) Format(s State, c rune) {
81 Fprintf(s, "<%c=F(%d)>", c, int(f))
84 type G int
86 func (g G) GoString() string {
87 return Sprintf("GoString(%d)", int(g))
90 type S struct {
91 F F // a struct field that Formats
92 G G // a struct field that GoStrings
95 type SI struct {
96 I interface{}
99 // P is a type with a String method with pointer receiver for testing %p.
100 type P int
102 var pValue P
104 func (p *P) String() string {
105 return "String(p)"
108 var barray = [5]renamedUint8{1, 2, 3, 4, 5}
109 var bslice = barray[:]
111 var b byte
113 var fmtTests = []struct {
114 fmt string
115 val interface{}
116 out string
118 {"%d", 12345, "12345"},
119 {"%v", 12345, "12345"},
120 {"%t", true, "true"},
122 // basic string
123 {"%s", "abc", "abc"},
124 {"%x", "abc", "616263"},
125 {"%x", "xyz", "78797a"},
126 {"%X", "xyz", "78797A"},
127 {"%q", "abc", `"abc"`},
129 // basic bytes
130 {"%s", []byte("abc"), "abc"},
131 {"%x", []byte("abc"), "616263"},
132 {"% x", []byte("abc\xff"), "61 62 63 ff"},
133 {"%#x", []byte("abc\xff"), "0x610x620x630xff"},
134 {"%#X", []byte("abc\xff"), "0X610X620X630XFF"},
135 {"%# x", []byte("abc\xff"), "0x61 0x62 0x63 0xff"},
136 {"%# X", []byte("abc\xff"), "0X61 0X62 0X63 0XFF"},
137 {"% X", []byte("abc\xff"), "61 62 63 FF"},
138 {"%x", []byte("xyz"), "78797a"},
139 {"%X", []byte("xyz"), "78797A"},
140 {"%q", []byte("abc"), `"abc"`},
142 // escaped strings
143 {"%#q", `abc`, "`abc`"},
144 {"%#q", `"`, "`\"`"},
145 {"1 %#q", `\n`, "1 `\\n`"},
146 {"2 %#q", "\n", `2 "\n"`},
147 {"%q", `"`, `"\""`},
148 {"%q", "\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`},
149 {"%q", "abc\xffdef", `"abc\xffdef"`},
150 {"%q", "\u263a", `"☺"`},
151 {"%+q", "\u263a", `"\u263a"`},
152 {"%q", "\U0010ffff", `"\U0010ffff"`},
154 // escaped characters
155 {"%q", 'x', `'x'`},
156 {"%q", 0, `'\x00'`},
157 {"%q", '\n', `'\n'`},
158 {"%q", '\u0e00', `'\u0e00'`}, // not a printable rune.
159 {"%q", '\U000c2345', `'\U000c2345'`}, // not a printable rune.
160 {"%q", int64(0x7FFFFFFF), `%!q(int64=2147483647)`},
161 {"%q", uint64(0xFFFFFFFF), `%!q(uint64=4294967295)`},
162 {"%q", '"', `'"'`},
163 {"%q", '\'', `'\''`},
164 {"%q", "\u263a", `"☺"`},
165 {"%+q", "\u263a", `"\u263a"`},
167 // width
168 {"%5s", "abc", " abc"},
169 {"%2s", "\u263a", " ☺"},
170 {"%-5s", "abc", "abc "},
171 {"%-8q", "abc", `"abc" `},
172 {"%05s", "abc", "00abc"},
173 {"%08q", "abc", `000"abc"`},
174 {"%5s", "abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"},
175 {"%.5s", "abcdefghijklmnopqrstuvwxyz", "abcde"},
176 {"%.5s", "日本語日本語", "日本語日本"},
177 {"%.5s", []byte("日本語日本語"), "日本語日本"},
178 {"%.5q", "abcdefghijklmnopqrstuvwxyz", `"abcde"`},
179 {"%.3q", "日本語日本語", `"日本語"`},
180 {"%.3q", []byte("日本語日本語"), `"日本語"`},
181 {"%10.1q", "日本語日本語", ` "日"`},
182 {"%10v", nil, " <nil>"},
183 {"%-10v", nil, "<nil> "},
185 // integers
186 {"%d", 12345, "12345"},
187 {"%d", -12345, "-12345"},
188 {"%10d", 12345, " 12345"},
189 {"%10d", -12345, " -12345"},
190 {"%+10d", 12345, " +12345"},
191 {"%010d", 12345, "0000012345"},
192 {"%010d", -12345, "-000012345"},
193 {"%-10d", 12345, "12345 "},
194 {"%010.3d", 1, " 001"},
195 {"%010.3d", -1, " -001"},
196 {"%+d", 12345, "+12345"},
197 {"%+d", -12345, "-12345"},
198 {"%+d", 0, "+0"},
199 {"% d", 0, " 0"},
200 {"% d", 12345, " 12345"},
201 {"%.0d", 0, ""},
202 {"%.d", 0, ""},
204 // unicode format
205 {"%U", 0x1, "U+0001"},
206 {"%U", uint(0x1), "U+0001"},
207 {"%.8U", 0x2, "U+00000002"},
208 {"%U", 0x1234, "U+1234"},
209 {"%U", 0x12345, "U+12345"},
210 {"%10.6U", 0xABC, " U+000ABC"},
211 {"%-10.6U", 0xABC, "U+000ABC "},
212 {"%U", '\n', `U+000A`},
213 {"%#U", '\n', `U+000A`},
214 {"%U", 'x', `U+0078`},
215 {"%#U", 'x', `U+0078 'x'`},
216 {"%U", '\u263a', `U+263A`},
217 {"%#U", '\u263a', `U+263A '☺'`},
219 // floats
220 {"%+.3e", 0.0, "+0.000e+00"},
221 {"%+.3e", 1.0, "+1.000e+00"},
222 {"%+.3f", -1.0, "-1.000"},
223 {"%+.3F", -1.0, "-1.000"},
224 {"%+.3F", float32(-1.0), "-1.000"},
225 {"%+07.2f", 1.0, "+001.00"},
226 {"%+07.2f", -1.0, "-001.00"},
227 {"%+10.2f", +1.0, " +1.00"},
228 {"%+10.2f", -1.0, " -1.00"},
229 {"% .3E", -1.0, "-1.000E+00"},
230 {"% .3e", 1.0, " 1.000e+00"},
231 {"%+.3g", 0.0, "+0"},
232 {"%+.3g", 1.0, "+1"},
233 {"%+.3g", -1.0, "-1"},
234 {"% .3g", -1.0, "-1"},
235 {"% .3g", 1.0, " 1"},
236 {"%b", float32(1.0), "8388608p-23"},
237 {"%b", 1.0, "4503599627370496p-52"},
239 // complex values
240 {"%+.3e", 0i, "(+0.000e+00+0.000e+00i)"},
241 {"%+.3f", 0i, "(+0.000+0.000i)"},
242 {"%+.3g", 0i, "(+0+0i)"},
243 {"%+.3e", 1 + 2i, "(+1.000e+00+2.000e+00i)"},
244 {"%+.3f", 1 + 2i, "(+1.000+2.000i)"},
245 {"%+.3g", 1 + 2i, "(+1+2i)"},
246 {"%.3e", 0i, "(0.000e+00+0.000e+00i)"},
247 {"%.3f", 0i, "(0.000+0.000i)"},
248 {"%.3F", 0i, "(0.000+0.000i)"},
249 {"%.3F", complex64(0i), "(0.000+0.000i)"},
250 {"%.3g", 0i, "(0+0i)"},
251 {"%.3e", 1 + 2i, "(1.000e+00+2.000e+00i)"},
252 {"%.3f", 1 + 2i, "(1.000+2.000i)"},
253 {"%.3g", 1 + 2i, "(1+2i)"},
254 {"%.3e", -1 - 2i, "(-1.000e+00-2.000e+00i)"},
255 {"%.3f", -1 - 2i, "(-1.000-2.000i)"},
256 {"%.3g", -1 - 2i, "(-1-2i)"},
257 {"% .3E", -1 - 2i, "(-1.000E+00-2.000E+00i)"},
258 {"%+.3g", complex64(1 + 2i), "(+1+2i)"},
259 {"%+.3g", complex128(1 + 2i), "(+1+2i)"},
260 {"%b", complex64(1 + 2i), "(8388608p-23+8388608p-22i)"},
261 {"%b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"},
263 // erroneous formats
264 {"", 2, "%!(EXTRA int=2)"},
265 {"%d", "hello", "%!d(string=hello)"},
267 // old test/fmt_test.go
268 {"%d", 1234, "1234"},
269 {"%d", -1234, "-1234"},
270 {"%d", uint(1234), "1234"},
271 {"%d", uint32(b32), "4294967295"},
272 {"%d", uint64(b64), "18446744073709551615"},
273 {"%o", 01234, "1234"},
274 {"%#o", 01234, "01234"},
275 {"%o", uint32(b32), "37777777777"},
276 {"%o", uint64(b64), "1777777777777777777777"},
277 {"%x", 0x1234abcd, "1234abcd"},
278 {"%#x", 0x1234abcd, "0x1234abcd"},
279 {"%x", b32 - 0x1234567, "fedcba98"},
280 {"%X", 0x1234abcd, "1234ABCD"},
281 {"%X", b32 - 0x1234567, "FEDCBA98"},
282 {"%#X", 0, "0X0"},
283 {"%x", b64, "ffffffffffffffff"},
284 {"%b", 7, "111"},
285 {"%b", b64, "1111111111111111111111111111111111111111111111111111111111111111"},
286 {"%b", -6, "-110"},
287 {"%e", 1.0, "1.000000e+00"},
288 {"%e", 1234.5678e3, "1.234568e+06"},
289 {"%e", 1234.5678e-8, "1.234568e-05"},
290 {"%e", -7.0, "-7.000000e+00"},
291 {"%e", -1e-9, "-1.000000e-09"},
292 {"%f", 1234.5678e3, "1234567.800000"},
293 {"%f", 1234.5678e-8, "0.000012"},
294 {"%f", -7.0, "-7.000000"},
295 {"%f", -1e-9, "-0.000000"},
296 {"%g", 1234.5678e3, "1.2345678e+06"},
297 {"%g", float32(1234.5678e3), "1.2345678e+06"},
298 {"%g", 1234.5678e-8, "1.2345678e-05"},
299 {"%g", -7.0, "-7"},
300 {"%g", -1e-9, "-1e-09"},
301 {"%g", float32(-1e-9), "-1e-09"},
302 {"%E", 1.0, "1.000000E+00"},
303 {"%E", 1234.5678e3, "1.234568E+06"},
304 {"%E", 1234.5678e-8, "1.234568E-05"},
305 {"%E", -7.0, "-7.000000E+00"},
306 {"%E", -1e-9, "-1.000000E-09"},
307 {"%G", 1234.5678e3, "1.2345678E+06"},
308 {"%G", float32(1234.5678e3), "1.2345678E+06"},
309 {"%G", 1234.5678e-8, "1.2345678E-05"},
310 {"%G", -7.0, "-7"},
311 {"%G", -1e-9, "-1E-09"},
312 {"%G", float32(-1e-9), "-1E-09"},
313 {"%c", 'x', "x"},
314 {"%c", 0xe4, "ä"},
315 {"%c", 0x672c, "本"},
316 {"%c", '日', "日"},
317 {"%20.8d", 1234, " 00001234"},
318 {"%20.8d", -1234, " -00001234"},
319 {"%20d", 1234, " 1234"},
320 {"%-20.8d", 1234, "00001234 "},
321 {"%-20.8d", -1234, "-00001234 "},
322 {"%-#20.8x", 0x1234abc, "0x01234abc "},
323 {"%-#20.8X", 0x1234abc, "0X01234ABC "},
324 {"%-#20.8o", 01234, "00001234 "},
325 {"%.20b", 7, "00000000000000000111"},
326 {"%20.5s", "qwertyuiop", " qwert"},
327 {"%.5s", "qwertyuiop", "qwert"},
328 {"%-20.5s", "qwertyuiop", "qwert "},
329 {"%20c", 'x', " x"},
330 {"%-20c", 'x', "x "},
331 {"%20.6e", 1.2345e3, " 1.234500e+03"},
332 {"%20.6e", 1.2345e-3, " 1.234500e-03"},
333 {"%20e", 1.2345e3, " 1.234500e+03"},
334 {"%20e", 1.2345e-3, " 1.234500e-03"},
335 {"%20.8e", 1.2345e3, " 1.23450000e+03"},
336 {"%20f", 1.23456789e3, " 1234.567890"},
337 {"%20f", 1.23456789e-3, " 0.001235"},
338 {"%20f", 12345678901.23456789, " 12345678901.234568"},
339 {"%-20f", 1.23456789e3, "1234.567890 "},
340 {"%20.8f", 1.23456789e3, " 1234.56789000"},
341 {"%20.8f", 1.23456789e-3, " 0.00123457"},
342 {"%g", 1.23456789e3, "1234.56789"},
343 {"%g", 1.23456789e-3, "0.00123456789"},
344 {"%g", 1.23456789e20, "1.23456789e+20"},
345 {"%20e", math.Inf(1), " +Inf"},
346 {"%-20f", math.Inf(-1), "-Inf "},
347 {"%20g", math.NaN(), " NaN"},
349 // arrays
350 {"%v", array, "[1 2 3 4 5]"},
351 {"%v", iarray, "[1 hello 2.5 <nil>]"},
352 {"%v", barray, "[1 2 3 4 5]"},
353 {"%v", &array, "&[1 2 3 4 5]"},
354 {"%v", &iarray, "&[1 hello 2.5 <nil>]"},
355 {"%v", &barray, "&[1 2 3 4 5]"},
357 // slices
358 {"%v", slice, "[1 2 3 4 5]"},
359 {"%v", islice, "[1 hello 2.5 <nil>]"},
360 {"%v", bslice, "[1 2 3 4 5]"},
361 {"%v", &slice, "&[1 2 3 4 5]"},
362 {"%v", &islice, "&[1 hello 2.5 <nil>]"},
363 {"%v", &bslice, "&[1 2 3 4 5]"},
365 // complexes with %v
366 {"%v", 1 + 2i, "(1+2i)"},
367 {"%v", complex64(1 + 2i), "(1+2i)"},
368 {"%v", complex128(1 + 2i), "(1+2i)"},
370 // structs
371 {"%v", A{1, 2, "a", []int{1, 2}}, `{1 2 a [1 2]}`},
372 {"%+v", A{1, 2, "a", []int{1, 2}}, `{i:1 j:2 s:a x:[1 2]}`},
374 // +v on structs with Stringable items
375 {"%+v", B{1, 2}, `{I:<1> j:2}`},
376 {"%+v", C{1, B{2, 3}}, `{i:1 B:{I:<2> j:3}}`},
378 // other formats on Stringable items
379 {"%s", I(23), `<23>`},
380 {"%q", I(23), `"<23>"`},
381 {"%x", I(23), `3c32333e`},
382 {"%#x", I(23), `0x3c0x320x330x3e`},
383 {"%# x", I(23), `0x3c 0x32 0x33 0x3e`},
384 {"%d", I(23), `23`}, // Stringer applies only to string formats.
386 // go syntax
387 {"%#v", A{1, 2, "a", []int{1, 2}}, `fmt_test.A{i:1, j:0x2, s:"a", x:[]int{1, 2}}`},
388 {"%#v", &b, "(*uint8)(0xPTR)"},
389 {"%#v", TestFmtInterface, "(func(*testing.T))(0xPTR)"},
390 {"%#v", make(chan int), "(chan int)(0xPTR)"},
391 {"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"},
392 {"%#v", 1000000000, "1000000000"},
393 {"%#v", map[string]int{"a": 1}, `map[string]int{"a":1}`},
394 {"%#v", map[string]B{"a": {1, 2}}, `map[string]fmt_test.B{"a":fmt_test.B{I:1, j:2}}`},
395 {"%#v", []string{"a", "b"}, `[]string{"a", "b"}`},
396 {"%#v", SI{}, `fmt_test.SI{I:interface {}(nil)}`},
397 {"%#v", []int(nil), `[]int(nil)`},
398 {"%#v", []int{}, `[]int{}`},
399 {"%#v", array, `[5]int{1, 2, 3, 4, 5}`},
400 {"%#v", &array, `&[5]int{1, 2, 3, 4, 5}`},
401 {"%#v", iarray, `[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
402 {"%#v", &iarray, `&[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
403 {"%#v", map[int]byte(nil), `map[int]uint8(nil)`},
404 {"%#v", map[int]byte{}, `map[int]uint8{}`},
405 {"%#v", "foo", `"foo"`},
406 {"%#v", barray, `[5]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
407 {"%#v", bslice, `[]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
408 {"%#v", []byte(nil), "[]byte(nil)"},
409 {"%#v", []int32(nil), "[]int32(nil)"},
411 // slices with other formats
412 {"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`},
413 {"%x", []int{1, 2, 15}, `[1 2 f]`},
414 {"%d", []int{1, 2, 15}, `[1 2 15]`},
415 {"%d", []byte{1, 2, 15}, `[1 2 15]`},
416 {"%q", []string{"a", "b"}, `["a" "b"]`},
418 // renamings
419 {"%v", renamedBool(true), "true"},
420 {"%d", renamedBool(true), "%!d(fmt_test.renamedBool=true)"},
421 {"%o", renamedInt(8), "10"},
422 {"%d", renamedInt8(-9), "-9"},
423 {"%v", renamedInt16(10), "10"},
424 {"%v", renamedInt32(-11), "-11"},
425 {"%X", renamedInt64(255), "FF"},
426 {"%v", renamedUint(13), "13"},
427 {"%o", renamedUint8(14), "16"},
428 {"%X", renamedUint16(15), "F"},
429 {"%d", renamedUint32(16), "16"},
430 {"%X", renamedUint64(17), "11"},
431 {"%o", renamedUintptr(18), "22"},
432 {"%x", renamedString("thing"), "7468696e67"},
433 {"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`},
434 {"%q", renamedBytes([]byte("hello")), `"hello"`},
435 {"%x", []renamedUint8{'a', 'b', 'c'}, "616263"},
436 {"%s", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "hello"},
437 {"%q", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, `"hello"`},
438 {"%v", renamedFloat32(22), "22"},
439 {"%v", renamedFloat64(33), "33"},
440 {"%v", renamedComplex64(3 + 4i), "(3+4i)"},
441 {"%v", renamedComplex128(4 - 3i), "(4-3i)"},
443 // Formatter
444 {"%x", F(1), "<x=F(1)>"},
445 {"%x", G(2), "2"},
446 {"%+v", S{F(4), G(5)}, "{F:<v=F(4)> G:5}"},
448 // GoStringer
449 {"%#v", G(6), "GoString(6)"},
450 {"%#v", S{F(7), G(8)}, "fmt_test.S{F:<v=F(7)>, G:GoString(8)}"},
452 // %T
453 {"%T", (4 - 3i), "complex128"},
454 {"%T", renamedComplex128(4 - 3i), "fmt_test.renamedComplex128"},
455 {"%T", intVal, "int"},
456 {"%6T", &intVal, " *int"},
457 {"%10T", nil, " <nil>"},
458 {"%-10T", nil, "<nil> "},
460 // %p
461 {"p0=%p", new(int), "p0=0xPTR"},
462 {"p1=%s", &pValue, "p1=String(p)"}, // String method...
463 {"p2=%p", &pValue, "p2=0xPTR"}, // ... not called with %p
464 {"p3=%p", (*int)(nil), "p3=0x0"},
465 {"p4=%#p", new(int), "p4=PTR"},
467 // %p on non-pointers
468 {"%p", make(chan int), "0xPTR"},
469 {"%p", make(map[int]int), "0xPTR"},
470 {"%p", make([]int, 1), "0xPTR"},
471 {"%p", 27, "%!p(int=27)"}, // not a pointer at all
473 // %q on pointers
474 {"%q", (*int)(nil), "%!q(*int=<nil>)"},
475 {"%q", new(int), "%!q(*int=0xPTR)"},
477 // %v on pointers formats 0 as <nil>
478 {"%v", (*int)(nil), "<nil>"},
479 {"%v", new(int), "0xPTR"},
481 // %d etc. pointers use specified base.
482 {"%d", new(int), "PTR_d"},
483 {"%o", new(int), "PTR_o"},
484 {"%x", new(int), "PTR_x"},
486 // %d on Stringer should give integer if possible
487 {"%s", time.Time{}.Month(), "January"},
488 {"%d", time.Time{}.Month(), "1"},
490 // erroneous things
491 {"%s %", "hello", "hello %!(NOVERB)"},
492 {"%s %.2", "hello", "hello %!(NOVERB)"},
493 {"%d", "hello", "%!d(string=hello)"},
494 {"no args", "hello", "no args%!(EXTRA string=hello)"},
495 {"%s", nil, "%!s(<nil>)"},
496 {"%T", nil, "<nil>"},
497 {"%-1", 100, "%!(NOVERB)%!(EXTRA int=100)"},
499 // The "<nil>" show up because maps are printed by
500 // first obtaining a list of keys and then looking up
501 // each key. Since NaNs can be map keys but cannot
502 // be fetched directly, the lookup fails and returns a
503 // zero reflect.Value, which formats as <nil>.
504 // This test is just to check that it shows the two NaNs at all.
505 {"%v", map[float64]int{math.NaN(): 1, math.NaN(): 2}, "map[NaN:<nil> NaN:<nil>]"},
507 // Used to crash because nByte didn't allow for a sign.
508 {"%b", int64(-1 << 63), zeroFill("-1", 63, "")},
510 // Used to panic.
511 {"%0100d", 1, zeroFill("", 100, "1")},
512 {"%0100d", -1, zeroFill("-", 99, "1")},
513 {"%0.100f", 1.0, zeroFill("1.", 100, "")},
514 {"%0.100f", -1.0, zeroFill("-1.", 100, "")},
516 // Comparison of padding rules with C printf.
518 C program:
519 #include <stdio.h>
521 char *format[] = {
522 "[%.2f]",
523 "[% .2f]",
524 "[%+.2f]",
525 "[%7.2f]",
526 "[% 7.2f]",
527 "[%+7.2f]",
528 "[%07.2f]",
529 "[% 07.2f]",
530 "[%+07.2f]",
533 int main(void) {
534 int i;
535 for(i = 0; i < 9; i++) {
536 printf("%s: ", format[i]);
537 printf(format[i], 1.0);
538 printf(" ");
539 printf(format[i], -1.0);
540 printf("\n");
544 Output:
545 [%.2f]: [1.00] [-1.00]
546 [% .2f]: [ 1.00] [-1.00]
547 [%+.2f]: [+1.00] [-1.00]
548 [%7.2f]: [ 1.00] [ -1.00]
549 [% 7.2f]: [ 1.00] [ -1.00]
550 [%+7.2f]: [ +1.00] [ -1.00]
551 [%07.2f]: [0001.00] [-001.00]
552 [% 07.2f]: [ 001.00] [-001.00]
553 [%+07.2f]: [+001.00] [-001.00]
555 {"%.2f", 1.0, "1.00"},
556 {"%.2f", -1.0, "-1.00"},
557 {"% .2f", 1.0, " 1.00"},
558 {"% .2f", -1.0, "-1.00"},
559 {"%+.2f", 1.0, "+1.00"},
560 {"%+.2f", -1.0, "-1.00"},
561 {"%7.2f", 1.0, " 1.00"},
562 {"%7.2f", -1.0, " -1.00"},
563 {"% 7.2f", 1.0, " 1.00"},
564 {"% 7.2f", -1.0, " -1.00"},
565 {"%+7.2f", 1.0, " +1.00"},
566 {"%+7.2f", -1.0, " -1.00"},
567 {"%07.2f", 1.0, "0001.00"},
568 {"%07.2f", -1.0, "-001.00"},
569 {"% 07.2f", 1.0, " 001.00"},
570 {"% 07.2f", -1.0, "-001.00"},
571 {"%+07.2f", 1.0, "+001.00"},
572 {"%+07.2f", -1.0, "-001.00"},
574 // Complex numbers: exhaustively tested in TestComplexFormatting.
575 {"%7.2f", 1 + 2i, "( 1.00 +2.00i)"},
576 {"%+07.2f", -1 - 2i, "(-001.00-002.00i)"},
577 // Zero padding does not apply to infinities.
578 {"%020f", math.Inf(-1), " -Inf"},
579 {"%020f", math.Inf(+1), " +Inf"},
580 {"% 020f", math.Inf(-1), " -Inf"},
581 {"% 020f", math.Inf(+1), " Inf"},
582 {"%+020f", math.Inf(-1), " -Inf"},
583 {"%+020f", math.Inf(+1), " +Inf"},
584 {"%20f", -1.0, " -1.000000"},
585 // Make sure we can handle very large widths.
586 {"%0100f", -1.0, zeroFill("-", 99, "1.000000")},
588 // Complex fmt used to leave the plus flag set for future entries in the array
589 // causing +2+0i and +3+0i instead of 2+0i and 3+0i.
590 {"%v", []complex64{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
591 {"%v", []complex128{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
593 // Incomplete format specification caused crash.
594 {"%.", 3, "%!.(int=3)"},
596 // Used to panic with out-of-bounds for very large numeric representations.
597 // nByte is set to handle one bit per uint64 in %b format, with a negative number.
598 // See issue 6777.
599 {"%#064x", 1, zeroFill("0x", 64, "1")},
600 {"%#064x", -1, zeroFill("-0x", 63, "1")},
601 {"%#064b", 1, zeroFill("", 64, "1")},
602 {"%#064b", -1, zeroFill("-", 63, "1")},
603 {"%#064o", 1, zeroFill("", 64, "1")},
604 {"%#064o", -1, zeroFill("-", 63, "1")},
605 {"%#064d", 1, zeroFill("", 64, "1")},
606 {"%#064d", -1, zeroFill("-", 63, "1")},
607 // Test that we handle the crossover above the size of uint64
608 {"%#072x", 1, zeroFill("0x", 72, "1")},
609 {"%#072x", -1, zeroFill("-0x", 71, "1")},
610 {"%#072b", 1, zeroFill("", 72, "1")},
611 {"%#072b", -1, zeroFill("-", 71, "1")},
612 {"%#072o", 1, zeroFill("", 72, "1")},
613 {"%#072o", -1, zeroFill("-", 71, "1")},
614 {"%#072d", 1, zeroFill("", 72, "1")},
615 {"%#072d", -1, zeroFill("-", 71, "1")},
617 // Padding for complex numbers. Has been bad, then fixed, then bad again.
618 {"%+10.2f", +104.66 + 440.51i, "( +104.66 +440.51i)"},
619 {"%+10.2f", -104.66 + 440.51i, "( -104.66 +440.51i)"},
620 {"%+10.2f", +104.66 - 440.51i, "( +104.66 -440.51i)"},
621 {"%+10.2f", -104.66 - 440.51i, "( -104.66 -440.51i)"},
622 {"%+010.2f", +104.66 + 440.51i, "(+000104.66+000440.51i)"},
623 {"%+010.2f", -104.66 + 440.51i, "(-000104.66+000440.51i)"},
624 {"%+010.2f", +104.66 - 440.51i, "(+000104.66-000440.51i)"},
625 {"%+010.2f", -104.66 - 440.51i, "(-000104.66-000440.51i)"},
628 // zeroFill generates zero-filled strings of the specified width. The length
629 // of the suffix (but not the prefix) is compensated for in the width calculation.
630 func zeroFill(prefix string, width int, suffix string) string {
631 return prefix + strings.Repeat("0", width-len(suffix)) + suffix
634 func TestSprintf(t *testing.T) {
635 for _, tt := range fmtTests {
636 s := Sprintf(tt.fmt, tt.val)
637 if i := strings.Index(tt.out, "PTR"); i >= 0 {
638 pattern := "PTR"
639 chars := "0123456789abcdefABCDEF"
640 switch {
641 case strings.HasPrefix(tt.out[i:], "PTR_d"):
642 pattern = "PTR_d"
643 chars = chars[:10]
644 case strings.HasPrefix(tt.out[i:], "PTR_o"):
645 pattern = "PTR_o"
646 chars = chars[:8]
647 case strings.HasPrefix(tt.out[i:], "PTR_x"):
648 pattern = "PTR_x"
650 j := i
651 for ; j < len(s); j++ {
652 c := s[j]
653 if !strings.ContainsRune(chars, rune(c)) {
654 break
657 s = s[0:i] + pattern + s[j:]
659 if s != tt.out {
660 if _, ok := tt.val.(string); ok {
661 // Don't requote the already-quoted strings.
662 // It's too confusing to read the errors.
663 t.Errorf("Sprintf(%q, %q) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out)
664 } else {
665 t.Errorf("Sprintf(%q, %v) = %q want %q", tt.fmt, tt.val, s, tt.out)
671 // TestComplexFormatting checks that a complex always formats to the same
672 // thing as if done by hand with two singleton prints.
673 func TestComplexFormatting(t *testing.T) {
674 var yesNo = []bool{true, false}
675 var signs = []float64{1, 0, -1}
676 for _, plus := range yesNo {
677 for _, zero := range yesNo {
678 for _, space := range yesNo {
679 for _, char := range "fFeEgG" {
680 realFmt := "%"
681 if zero {
682 realFmt += "0"
684 if space {
685 realFmt += " "
687 if plus {
688 realFmt += "+"
690 realFmt += "10.2"
691 realFmt += string(char)
692 // Imaginary part always has a sign, so force + and ignore space.
693 imagFmt := "%"
694 if zero {
695 imagFmt += "0"
697 imagFmt += "+"
698 imagFmt += "10.2"
699 imagFmt += string(char)
700 for _, realSign := range signs {
701 for _, imagSign := range signs {
702 one := Sprintf(realFmt, complex(realSign, imagSign))
703 two := Sprintf("("+realFmt+imagFmt+"i)", realSign, imagSign)
704 if one != two {
705 t.Error(f, one, two)
715 type SE []interface{} // slice of empty; notational compactness.
717 var reorderTests = []struct {
718 fmt string
719 val SE
720 out string
722 {"%[1]d", SE{1}, "1"},
723 {"%[2]d", SE{2, 1}, "1"},
724 {"%[2]d %[1]d", SE{1, 2}, "2 1"},
725 {"%[2]*[1]d", SE{2, 5}, " 2"},
726 {"%6.2f", SE{12.0}, " 12.00"}, // Explicit version of next line.
727 {"%[3]*.[2]*[1]f", SE{12.0, 2, 6}, " 12.00"},
728 {"%[1]*.[2]*[3]f", SE{6, 2, 12.0}, " 12.00"},
729 {"%10f", SE{12.0}, " 12.000000"},
730 {"%[1]*[3]f", SE{10, 99, 12.0}, " 12.000000"},
731 {"%.6f", SE{12.0}, "12.000000"}, // Explicit version of next line.
732 {"%.[1]*[3]f", SE{6, 99, 12.0}, "12.000000"},
733 {"%6.f", SE{12.0}, " 12"}, // // Explicit version of next line; empty precision means zero.
734 {"%[1]*.[3]f", SE{6, 3, 12.0}, " 12"},
735 // An actual use! Print the same arguments twice.
736 {"%d %d %d %#[1]o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015"},
738 // Erroneous cases.
739 {"%[d", SE{2, 1}, "%!d(BADINDEX)"},
740 {"%]d", SE{2, 1}, "%!](int=2)d%!(EXTRA int=1)"},
741 {"%[]d", SE{2, 1}, "%!d(BADINDEX)"},
742 {"%[-3]d", SE{2, 1}, "%!d(BADINDEX)"},
743 {"%[99]d", SE{2, 1}, "%!d(BADINDEX)"},
744 {"%[3]", SE{2, 1}, "%!(NOVERB)"},
745 {"%[1].2d", SE{5, 6}, "%!d(BADINDEX)"},
746 {"%[1]2d", SE{2, 1}, "%!d(BADINDEX)"},
747 {"%3.[2]d", SE{7}, "%!d(BADINDEX)"},
748 {"%.[2]d", SE{7}, "%!d(BADINDEX)"},
749 {"%d %d %d %#[1]o %#o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015 %!o(MISSING)"},
750 {"%[5]d %[2]d %d", SE{1, 2, 3}, "%!d(BADINDEX) 2 3"},
751 {"%d %[3]d %d", SE{1, 2}, "1 %!d(BADINDEX) 2"}, // Erroneous index does not affect sequence.
754 func TestReorder(t *testing.T) {
755 for _, tt := range reorderTests {
756 s := Sprintf(tt.fmt, tt.val...)
757 if s != tt.out {
758 t.Errorf("Sprintf(%q, %v) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out)
759 } else {
764 func BenchmarkSprintfEmpty(b *testing.B) {
765 b.RunParallel(func(pb *testing.PB) {
766 for pb.Next() {
767 Sprintf("")
772 func BenchmarkSprintfString(b *testing.B) {
773 b.RunParallel(func(pb *testing.PB) {
774 for pb.Next() {
775 Sprintf("%s", "hello")
780 func BenchmarkSprintfInt(b *testing.B) {
781 b.RunParallel(func(pb *testing.PB) {
782 for pb.Next() {
783 Sprintf("%d", 5)
788 func BenchmarkSprintfIntInt(b *testing.B) {
789 b.RunParallel(func(pb *testing.PB) {
790 for pb.Next() {
791 Sprintf("%d %d", 5, 6)
796 func BenchmarkSprintfPrefixedInt(b *testing.B) {
797 b.RunParallel(func(pb *testing.PB) {
798 for pb.Next() {
799 Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6)
804 func BenchmarkSprintfFloat(b *testing.B) {
805 b.RunParallel(func(pb *testing.PB) {
806 for pb.Next() {
807 Sprintf("%g", 5.23184)
812 func BenchmarkManyArgs(b *testing.B) {
813 b.RunParallel(func(pb *testing.PB) {
814 var buf bytes.Buffer
815 for pb.Next() {
816 buf.Reset()
817 Fprintf(&buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world")
822 var mallocBuf bytes.Buffer
824 // gccgo numbers are different because gccgo does not have escape
825 // analysis yet.
826 var mallocTest = []struct {
827 count int
828 desc string
829 fn func()
831 {5, `Sprintf("")`, func() { Sprintf("") }},
832 {5, `Sprintf("xxx")`, func() { Sprintf("xxx") }},
833 {5, `Sprintf("%x")`, func() { Sprintf("%x", 7) }},
834 {5, `Sprintf("%s")`, func() { Sprintf("%s", "hello") }},
835 {5, `Sprintf("%x %x")`, func() { Sprintf("%x %x", 7, 112) }},
836 // For %g we use a float32, not float64, to guarantee passing the argument
837 // does not need to allocate memory to store the result in a pointer-sized word.
838 {20, `Sprintf("%g")`, func() { Sprintf("%g", float32(3.14159)) }},
839 {5, `Fprintf(buf, "%x %x %x")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%x %x %x", 7, 8, 9) }},
840 {5, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }},
843 var _ bytes.Buffer
845 func TestCountMallocs(t *testing.T) {
846 if testing.Short() {
847 t.Skip("skipping malloc count in short mode")
849 if runtime.GOMAXPROCS(0) > 1 {
850 t.Skip("skipping; GOMAXPROCS>1")
852 for _, mt := range mallocTest {
853 mallocs := testing.AllocsPerRun(100, mt.fn)
854 if got, max := mallocs, float64(mt.count); got > max {
855 t.Errorf("%s: got %v allocs, want <=%v", mt.desc, got, max)
860 type flagPrinter struct{}
862 func (*flagPrinter) Format(f State, c rune) {
863 s := "%"
864 for i := 0; i < 128; i++ {
865 if f.Flag(i) {
866 s += string(i)
869 if w, ok := f.Width(); ok {
870 s += Sprintf("%d", w)
872 if p, ok := f.Precision(); ok {
873 s += Sprintf(".%d", p)
875 s += string(c)
876 io.WriteString(f, "["+s+"]")
879 var flagtests = []struct {
880 in string
881 out string
883 {"%a", "[%a]"},
884 {"%-a", "[%-a]"},
885 {"%+a", "[%+a]"},
886 {"%#a", "[%#a]"},
887 {"% a", "[% a]"},
888 {"%0a", "[%0a]"},
889 {"%1.2a", "[%1.2a]"},
890 {"%-1.2a", "[%-1.2a]"},
891 {"%+1.2a", "[%+1.2a]"},
892 {"%-+1.2a", "[%+-1.2a]"},
893 {"%-+1.2abc", "[%+-1.2a]bc"},
894 {"%-1.2abc", "[%-1.2a]bc"},
897 func TestFlagParser(t *testing.T) {
898 var flagprinter flagPrinter
899 for _, tt := range flagtests {
900 s := Sprintf(tt.in, &flagprinter)
901 if s != tt.out {
902 t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out)
907 func TestStructPrinter(t *testing.T) {
908 var s struct {
909 a string
910 b string
911 c int
913 s.a = "abc"
914 s.b = "def"
915 s.c = 123
916 var tests = []struct {
917 fmt string
918 out string
920 {"%v", "{abc def 123}"},
921 {"%+v", "{a:abc b:def c:123}"},
923 for _, tt := range tests {
924 out := Sprintf(tt.fmt, s)
925 if out != tt.out {
926 t.Errorf("Sprintf(%q, &s) = %q, want %q", tt.fmt, out, tt.out)
931 // presentInMap checks map printing using substrings so we don't depend on the
932 // print order.
933 func presentInMap(s string, a []string, t *testing.T) {
934 for i := 0; i < len(a); i++ {
935 loc := strings.Index(s, a[i])
936 if loc < 0 {
937 t.Errorf("map print: expected to find %q in %q", a[i], s)
939 // make sure the match ends here
940 loc += len(a[i])
941 if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') {
942 t.Errorf("map print: %q not properly terminated in %q", a[i], s)
947 func TestMapPrinter(t *testing.T) {
948 m0 := make(map[int]string)
949 s := Sprint(m0)
950 if s != "map[]" {
951 t.Errorf("empty map printed as %q not %q", s, "map[]")
953 m1 := map[int]string{1: "one", 2: "two", 3: "three"}
954 a := []string{"1:one", "2:two", "3:three"}
955 presentInMap(Sprintf("%v", m1), a, t)
956 presentInMap(Sprint(m1), a, t)
959 func TestEmptyMap(t *testing.T) {
960 const emptyMapStr = "map[]"
961 var m map[string]int
962 s := Sprint(m)
963 if s != emptyMapStr {
964 t.Errorf("nil map printed as %q not %q", s, emptyMapStr)
966 m = make(map[string]int)
967 s = Sprint(m)
968 if s != emptyMapStr {
969 t.Errorf("empty map printed as %q not %q", s, emptyMapStr)
973 // TestBlank checks that Sprint (and hence Print, Fprint) puts spaces in the
974 // right places, that is, between arg pairs in which neither is a string.
975 func TestBlank(t *testing.T) {
976 got := Sprint("<", 1, ">:", 1, 2, 3, "!")
977 expect := "<1>:1 2 3!"
978 if got != expect {
979 t.Errorf("got %q expected %q", got, expect)
983 // TestBlankln checks that Sprintln (and hence Println, Fprintln) puts spaces in
984 // the right places, that is, between all arg pairs.
985 func TestBlankln(t *testing.T) {
986 got := Sprintln("<", 1, ">:", 1, 2, 3, "!")
987 expect := "< 1 >: 1 2 3 !\n"
988 if got != expect {
989 t.Errorf("got %q expected %q", got, expect)
993 // TestFormatterPrintln checks Formatter with Sprint, Sprintln, Sprintf.
994 func TestFormatterPrintln(t *testing.T) {
995 f := F(1)
996 expect := "<v=F(1)>\n"
997 s := Sprint(f, "\n")
998 if s != expect {
999 t.Errorf("Sprint wrong with Formatter: expected %q got %q", expect, s)
1001 s = Sprintln(f)
1002 if s != expect {
1003 t.Errorf("Sprintln wrong with Formatter: expected %q got %q", expect, s)
1005 s = Sprintf("%v\n", f)
1006 if s != expect {
1007 t.Errorf("Sprintf wrong with Formatter: expected %q got %q", expect, s)
1011 func args(a ...interface{}) []interface{} { return a }
1013 var startests = []struct {
1014 fmt string
1015 in []interface{}
1016 out string
1018 {"%*d", args(4, 42), " 42"},
1019 {"%.*d", args(4, 42), "0042"},
1020 {"%*.*d", args(8, 4, 42), " 0042"},
1021 {"%0*d", args(4, 42), "0042"},
1022 {"%-*d", args(4, 42), "42 "},
1024 // erroneous
1025 {"%*d", args(nil, 42), "%!(BADWIDTH)42"},
1026 {"%.*d", args(nil, 42), "%!(BADPREC)42"},
1027 {"%*d", args(5, "foo"), "%!d(string= foo)"},
1028 {"%*% %d", args(20, 5), "% 5"},
1029 {"%*", args(4), "%!(NOVERB)"},
1030 {"%*d", args(int32(4), 42), "%!(BADWIDTH)42"},
1033 func TestWidthAndPrecision(t *testing.T) {
1034 for _, tt := range startests {
1035 s := Sprintf(tt.fmt, tt.in...)
1036 if s != tt.out {
1037 t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out)
1042 // Panic is a type that panics in String.
1043 type Panic struct {
1044 message interface{}
1047 // Value receiver.
1048 func (p Panic) GoString() string {
1049 panic(p.message)
1052 // Value receiver.
1053 func (p Panic) String() string {
1054 panic(p.message)
1057 // PanicF is a type that panics in Format.
1058 type PanicF struct {
1059 message interface{}
1062 // Value receiver.
1063 func (p PanicF) Format(f State, c rune) {
1064 panic(p.message)
1067 var panictests = []struct {
1068 fmt string
1069 in interface{}
1070 out string
1072 // String
1073 {"%s", (*Panic)(nil), "<nil>"}, // nil pointer special case
1074 {"%s", Panic{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"},
1075 {"%s", Panic{3}, "%!s(PANIC=3)"},
1076 // GoString
1077 {"%#v", (*Panic)(nil), "<nil>"}, // nil pointer special case
1078 {"%#v", Panic{io.ErrUnexpectedEOF}, "%!v(PANIC=unexpected EOF)"},
1079 {"%#v", Panic{3}, "%!v(PANIC=3)"},
1080 // Format
1081 {"%s", (*PanicF)(nil), "<nil>"}, // nil pointer special case
1082 {"%s", PanicF{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"},
1083 {"%s", PanicF{3}, "%!s(PANIC=3)"},
1086 func TestPanics(t *testing.T) {
1087 for _, tt := range panictests {
1088 s := Sprintf(tt.fmt, tt.in)
1089 if s != tt.out {
1090 t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out)
1095 // recurCount tests that erroneous String routine doesn't cause fatal recursion.
1096 var recurCount = 0
1098 type Recur struct {
1099 i int
1100 failed *bool
1103 func (r *Recur) String() string {
1104 if recurCount++; recurCount > 10 {
1105 *r.failed = true
1106 return "FAIL"
1108 // This will call badVerb. Before the fix, that would cause us to recur into
1109 // this routine to print %!p(value). Now we don't call the user's method
1110 // during an error.
1111 return Sprintf("recur@%p value: %d", r, r.i)
1114 func TestBadVerbRecursion(t *testing.T) {
1115 failed := false
1116 r := &Recur{3, &failed}
1117 Sprintf("recur@%p value: %d\n", &r, r.i)
1118 if failed {
1119 t.Error("fail with pointer")
1121 failed = false
1122 r = &Recur{4, &failed}
1123 Sprintf("recur@%p, value: %d\n", r, r.i)
1124 if failed {
1125 t.Error("fail with value")
1129 func TestIsSpace(t *testing.T) {
1130 // This tests the internal isSpace function.
1131 // IsSpace = isSpace is defined in export_test.go.
1132 for i := rune(0); i <= unicode.MaxRune; i++ {
1133 if IsSpace(i) != unicode.IsSpace(i) {
1134 t.Errorf("isSpace(%U) = %v, want %v", i, IsSpace(i), unicode.IsSpace(i))
1139 func TestNilDoesNotBecomeTyped(t *testing.T) {
1140 type A struct{}
1141 type B struct{}
1142 var a *A = nil
1143 var b B = B{}
1144 got := Sprintf("%s %s %s %s %s", nil, a, nil, b, nil)
1145 const expect = "%!s(<nil>) %!s(*fmt_test.A=<nil>) %!s(<nil>) {} %!s(<nil>)"
1146 if got != expect {
1147 t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got)