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