1// Copyright 2009 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package fmt_test 6 7import ( 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 21type ( 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 42func 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 51var ( 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 64type A struct { 65 i int 66 j uint 67 s string 68 x []int 69} 70 71type I int 72 73func (i I) String() string { return Sprintf("<%d>", int(i)) } 74 75type B struct { 76 I I 77 j int 78} 79 80type C struct { 81 i int 82 B 83} 84 85type F int 86 87func (f F) Format(s State, c rune) { 88 Fprintf(s, "<%c=F(%d)>", c, int(f)) 89} 90 91type G int 92 93func (g G) GoString() string { 94 return Sprintf("GoString(%d)", int(g)) 95} 96 97type S struct { 98 F F // a struct field that Formats 99 G G // a struct field that GoStrings 100} 101 102type SI struct { 103 I any 104} 105 106// P is a type with a String method with pointer receiver for testing %p. 107type P int 108 109var pValue P 110 111func (p *P) String() string { 112 return "String(p)" 113} 114 115var barray = [5]renamedUint8{1, 2, 3, 4, 5} 116var bslice = barray[:] 117 118type byteStringer byte 119 120func (byteStringer) String() string { 121 return "X" 122} 123 124var byteStringerSlice = []byteStringer{'h', 'e', 'l', 'l', 'o'} 125 126type byteFormatter byte 127 128func (byteFormatter) Format(f State, _ rune) { 129 Fprint(f, "X") 130} 131 132var byteFormatterSlice = []byteFormatter{'h', 'e', 'l', 'l', 'o'} 133 134type writeStringFormatter string 135 136func (sf writeStringFormatter) Format(f State, c rune) { 137 if sw, ok := f.(io.StringWriter); ok { 138 sw.WriteString("***" + string(sf) + "***") 139 } 140} 141 142var 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. 1089func zeroFill(prefix string, width int, suffix string) string { 1090 return prefix + strings.Repeat("0", width-len(suffix)) + suffix 1091} 1092 1093func 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. 1142func 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 1184type SE []any // slice of empty; notational compactness. 1185 1186var 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 1228func 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 1238func BenchmarkSprintfPadding(b *testing.B) { 1239 b.RunParallel(func(pb *testing.PB) { 1240 for pb.Next() { 1241 _ = Sprintf("%16f", 1.0) 1242 } 1243 }) 1244} 1245 1246func BenchmarkSprintfEmpty(b *testing.B) { 1247 b.RunParallel(func(pb *testing.PB) { 1248 for pb.Next() { 1249 _ = Sprintf("") 1250 } 1251 }) 1252} 1253 1254func BenchmarkSprintfString(b *testing.B) { 1255 b.RunParallel(func(pb *testing.PB) { 1256 for pb.Next() { 1257 _ = Sprintf("%s", "hello") 1258 } 1259 }) 1260} 1261 1262func BenchmarkSprintfTruncateString(b *testing.B) { 1263 b.RunParallel(func(pb *testing.PB) { 1264 for pb.Next() { 1265 _ = Sprintf("%.3s", "日本語日本語日本語日本語") 1266 } 1267 }) 1268} 1269 1270func 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 1279func BenchmarkSprintfSlowParsingPath(b *testing.B) { 1280 b.RunParallel(func(pb *testing.PB) { 1281 for pb.Next() { 1282 _ = Sprintf("%.v", nil) 1283 } 1284 }) 1285} 1286 1287func BenchmarkSprintfQuoteString(b *testing.B) { 1288 b.RunParallel(func(pb *testing.PB) { 1289 for pb.Next() { 1290 _ = Sprintf("%q", "日本語日本語日本語") 1291 } 1292 }) 1293} 1294 1295func BenchmarkSprintfInt(b *testing.B) { 1296 b.RunParallel(func(pb *testing.PB) { 1297 for pb.Next() { 1298 _ = Sprintf("%d", 5) 1299 } 1300 }) 1301} 1302 1303func 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 1311func 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 1319func BenchmarkSprintfFloat(b *testing.B) { 1320 b.RunParallel(func(pb *testing.PB) { 1321 for pb.Next() { 1322 _ = Sprintf("%g", 5.23184) 1323 } 1324 }) 1325} 1326 1327func 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 1335func BenchmarkSprintfBoolean(b *testing.B) { 1336 b.RunParallel(func(pb *testing.PB) { 1337 for pb.Next() { 1338 _ = Sprintf("%t", true) 1339 } 1340 }) 1341} 1342 1343func BenchmarkSprintfHexString(b *testing.B) { 1344 b.RunParallel(func(pb *testing.PB) { 1345 for pb.Next() { 1346 _ = Sprintf("% #x", "0123456789abcdef") 1347 } 1348 }) 1349} 1350 1351func 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 1360func 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 1369func 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 1378func 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 1387func 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 1397func 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 1405func 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 1414func 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 1423var mallocBuf bytes.Buffer 1424var mallocPointer *int // A pointer so we know the interface value won't allocate. 1425 1426var 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 1450var _ bytes.Buffer 1451 1452func 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 1469type flagPrinter struct{} 1470 1471func (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 1488var 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 {"%-0abc", "[%-0a]bc"}, 1505} 1506 1507func TestFlagParser(t *testing.T) { 1508 var flagprinter flagPrinter 1509 for _, tt := range flagtests { 1510 s := Sprintf(tt.in, &flagprinter) 1511 if s != tt.out { 1512 t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out) 1513 } 1514 } 1515} 1516 1517func TestStructPrinter(t *testing.T) { 1518 type T struct { 1519 a string 1520 b string 1521 c int 1522 } 1523 var s T 1524 s.a = "abc" 1525 s.b = "def" 1526 s.c = 123 1527 var tests = []struct { 1528 fmt string 1529 out string 1530 }{ 1531 {"%v", "{abc def 123}"}, 1532 {"%+v", "{a:abc b:def c:123}"}, 1533 {"%#v", `fmt_test.T{a:"abc", b:"def", c:123}`}, 1534 } 1535 for _, tt := range tests { 1536 out := Sprintf(tt.fmt, s) 1537 if out != tt.out { 1538 t.Errorf("Sprintf(%q, s) = %#q, want %#q", tt.fmt, out, tt.out) 1539 } 1540 // The same but with a pointer. 1541 out = Sprintf(tt.fmt, &s) 1542 if out != "&"+tt.out { 1543 t.Errorf("Sprintf(%q, &s) = %#q, want %#q", tt.fmt, out, "&"+tt.out) 1544 } 1545 } 1546} 1547 1548func TestSlicePrinter(t *testing.T) { 1549 slice := []int{} 1550 s := Sprint(slice) 1551 if s != "[]" { 1552 t.Errorf("empty slice printed as %q not %q", s, "[]") 1553 } 1554 slice = []int{1, 2, 3} 1555 s = Sprint(slice) 1556 if s != "[1 2 3]" { 1557 t.Errorf("slice: got %q expected %q", s, "[1 2 3]") 1558 } 1559 s = Sprint(&slice) 1560 if s != "&[1 2 3]" { 1561 t.Errorf("&slice: got %q expected %q", s, "&[1 2 3]") 1562 } 1563} 1564 1565// presentInMap checks map printing using substrings so we don't depend on the 1566// print order. 1567func presentInMap(s string, a []string, t *testing.T) { 1568 for i := 0; i < len(a); i++ { 1569 loc := strings.Index(s, a[i]) 1570 if loc < 0 { 1571 t.Errorf("map print: expected to find %q in %q", a[i], s) 1572 } 1573 // make sure the match ends here 1574 loc += len(a[i]) 1575 if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') { 1576 t.Errorf("map print: %q not properly terminated in %q", a[i], s) 1577 } 1578 } 1579} 1580 1581func TestMapPrinter(t *testing.T) { 1582 m0 := make(map[int]string) 1583 s := Sprint(m0) 1584 if s != "map[]" { 1585 t.Errorf("empty map printed as %q not %q", s, "map[]") 1586 } 1587 m1 := map[int]string{1: "one", 2: "two", 3: "three"} 1588 a := []string{"1:one", "2:two", "3:three"} 1589 presentInMap(Sprintf("%v", m1), a, t) 1590 presentInMap(Sprint(m1), a, t) 1591 // Pointer to map prints the same but with initial &. 1592 if !strings.HasPrefix(Sprint(&m1), "&") { 1593 t.Errorf("no initial & for address of map") 1594 } 1595 presentInMap(Sprintf("%v", &m1), a, t) 1596 presentInMap(Sprint(&m1), a, t) 1597} 1598 1599func TestEmptyMap(t *testing.T) { 1600 const emptyMapStr = "map[]" 1601 var m map[string]int 1602 s := Sprint(m) 1603 if s != emptyMapStr { 1604 t.Errorf("nil map printed as %q not %q", s, emptyMapStr) 1605 } 1606 m = make(map[string]int) 1607 s = Sprint(m) 1608 if s != emptyMapStr { 1609 t.Errorf("empty map printed as %q not %q", s, emptyMapStr) 1610 } 1611} 1612 1613// TestBlank checks that Sprint (and hence Print, Fprint) puts spaces in the 1614// right places, that is, between arg pairs in which neither is a string. 1615func TestBlank(t *testing.T) { 1616 got := Sprint("<", 1, ">:", 1, 2, 3, "!") 1617 expect := "<1>:1 2 3!" 1618 if got != expect { 1619 t.Errorf("got %q expected %q", got, expect) 1620 } 1621} 1622 1623// TestBlankln checks that Sprintln (and hence Println, Fprintln) puts spaces in 1624// the right places, that is, between all arg pairs. 1625func TestBlankln(t *testing.T) { 1626 got := Sprintln("<", 1, ">:", 1, 2, 3, "!") 1627 expect := "< 1 >: 1 2 3 !\n" 1628 if got != expect { 1629 t.Errorf("got %q expected %q", got, expect) 1630 } 1631} 1632 1633// TestFormatterPrintln checks Formatter with Sprint, Sprintln, Sprintf. 1634func TestFormatterPrintln(t *testing.T) { 1635 f := F(1) 1636 expect := "<v=F(1)>\n" 1637 s := Sprint(f, "\n") 1638 if s != expect { 1639 t.Errorf("Sprint wrong with Formatter: expected %q got %q", expect, s) 1640 } 1641 s = Sprintln(f) 1642 if s != expect { 1643 t.Errorf("Sprintln wrong with Formatter: expected %q got %q", expect, s) 1644 } 1645 s = Sprintf("%v\n", f) 1646 if s != expect { 1647 t.Errorf("Sprintf wrong with Formatter: expected %q got %q", expect, s) 1648 } 1649} 1650 1651func args(a ...any) []any { return a } 1652 1653var startests = []struct { 1654 fmt string 1655 in []any 1656 out string 1657}{ 1658 {"%*d", args(4, 42), " 42"}, 1659 {"%-*d", args(4, 42), "42 "}, 1660 {"%*d", args(-4, 42), "42 "}, 1661 {"%-*d", args(-4, 42), "42 "}, 1662 {"%.*d", args(4, 42), "0042"}, 1663 {"%*.*d", args(8, 4, 42), " 0042"}, 1664 {"%0*d", args(4, 42), "0042"}, 1665 // Some non-int types for width. (Issue 10732). 1666 {"%0*d", args(uint(4), 42), "0042"}, 1667 {"%0*d", args(uint64(4), 42), "0042"}, 1668 {"%0*d", args('\x04', 42), "0042"}, 1669 {"%0*d", args(uintptr(4), 42), "0042"}, 1670 1671 // erroneous 1672 {"%*d", args(nil, 42), "%!(BADWIDTH)42"}, 1673 {"%*d", args(int(1e7), 42), "%!(BADWIDTH)42"}, 1674 {"%*d", args(int(-1e7), 42), "%!(BADWIDTH)42"}, 1675 {"%.*d", args(nil, 42), "%!(BADPREC)42"}, 1676 {"%.*d", args(-1, 42), "%!(BADPREC)42"}, 1677 {"%.*d", args(int(1e7), 42), "%!(BADPREC)42"}, 1678 {"%.*d", args(uint(1e7), 42), "%!(BADPREC)42"}, 1679 {"%.*d", args(uint64(1<<63), 42), "%!(BADPREC)42"}, // Huge negative (-inf). 1680 {"%.*d", args(uint64(1<<64-1), 42), "%!(BADPREC)42"}, // Small negative (-1). 1681 {"%*d", args(5, "foo"), "%!d(string= foo)"}, 1682 {"%*% %d", args(20, 5), "% 5"}, 1683 {"%*", args(4), "%!(NOVERB)"}, 1684} 1685 1686func TestWidthAndPrecision(t *testing.T) { 1687 for i, tt := range startests { 1688 s := Sprintf(tt.fmt, tt.in...) 1689 if s != tt.out { 1690 t.Errorf("#%d: %q: got %q expected %q", i, tt.fmt, s, tt.out) 1691 } 1692 } 1693} 1694 1695// PanicS is a type that panics in String. 1696type PanicS struct { 1697 message any 1698} 1699 1700// Value receiver. 1701func (p PanicS) String() string { 1702 panic(p.message) 1703} 1704 1705// PanicGo is a type that panics in GoString. 1706type PanicGo struct { 1707 message any 1708} 1709 1710// Value receiver. 1711func (p PanicGo) GoString() string { 1712 panic(p.message) 1713} 1714 1715// PanicF is a type that panics in Format. 1716type PanicF struct { 1717 message any 1718} 1719 1720// Value receiver. 1721func (p PanicF) Format(f State, c rune) { 1722 panic(p.message) 1723} 1724 1725var panictests = []struct { 1726 fmt string 1727 in any 1728 out string 1729}{ 1730 // String 1731 {"%s", (*PanicS)(nil), "<nil>"}, // nil pointer special case 1732 {"%s", PanicS{io.ErrUnexpectedEOF}, "%!s(PANIC=String method: unexpected EOF)"}, 1733 {"%s", PanicS{3}, "%!s(PANIC=String method: 3)"}, 1734 // GoString 1735 {"%#v", (*PanicGo)(nil), "<nil>"}, // nil pointer special case 1736 {"%#v", PanicGo{io.ErrUnexpectedEOF}, "%!v(PANIC=GoString method: unexpected EOF)"}, 1737 {"%#v", PanicGo{3}, "%!v(PANIC=GoString method: 3)"}, 1738 // Issue 18282. catchPanic should not clear fmtFlags permanently. 1739 {"%#v", []any{PanicGo{3}, PanicGo{3}}, "[]interface {}{%!v(PANIC=GoString method: 3), %!v(PANIC=GoString method: 3)}"}, 1740 // Format 1741 {"%s", (*PanicF)(nil), "<nil>"}, // nil pointer special case 1742 {"%s", PanicF{io.ErrUnexpectedEOF}, "%!s(PANIC=Format method: unexpected EOF)"}, 1743 {"%s", PanicF{3}, "%!s(PANIC=Format method: 3)"}, 1744} 1745 1746func TestPanics(t *testing.T) { 1747 for i, tt := range panictests { 1748 s := Sprintf(tt.fmt, tt.in) 1749 if s != tt.out { 1750 t.Errorf("%d: %q: got %q expected %q", i, tt.fmt, s, tt.out) 1751 } 1752 } 1753} 1754 1755// recurCount tests that erroneous String routine doesn't cause fatal recursion. 1756var recurCount = 0 1757 1758type Recur struct { 1759 i int 1760 failed *bool 1761} 1762 1763func (r *Recur) String() string { 1764 if recurCount++; recurCount > 10 { 1765 *r.failed = true 1766 return "FAIL" 1767 } 1768 // This will call badVerb. Before the fix, that would cause us to recur into 1769 // this routine to print %!p(value). Now we don't call the user's method 1770 // during an error. 1771 return Sprintf("recur@%p value: %d", r, r.i) 1772} 1773 1774func TestBadVerbRecursion(t *testing.T) { 1775 failed := false 1776 r := &Recur{3, &failed} 1777 _ = Sprintf("recur@%p value: %d\n", &r, r.i) 1778 if failed { 1779 t.Error("fail with pointer") 1780 } 1781 failed = false 1782 r = &Recur{4, &failed} 1783 _ = Sprintf("recur@%p, value: %d\n", r, r.i) 1784 if failed { 1785 t.Error("fail with value") 1786 } 1787} 1788 1789func TestIsSpace(t *testing.T) { 1790 // This tests the internal isSpace function. 1791 // IsSpace = isSpace is defined in export_test.go. 1792 for i := rune(0); i <= unicode.MaxRune; i++ { 1793 if IsSpace(i) != unicode.IsSpace(i) { 1794 t.Errorf("isSpace(%U) = %v, want %v", i, IsSpace(i), unicode.IsSpace(i)) 1795 } 1796 } 1797} 1798 1799func hideFromVet(s string) string { return s } 1800 1801func TestNilDoesNotBecomeTyped(t *testing.T) { 1802 type A struct{} 1803 type B struct{} 1804 var a *A = nil 1805 var b B = B{} 1806 got := Sprintf(hideFromVet("%s %s %s %s %s"), nil, a, nil, b, nil) 1807 const expect = "%!s(<nil>) %!s(*fmt_test.A=<nil>) %!s(<nil>) {} %!s(<nil>)" 1808 if got != expect { 1809 t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got) 1810 } 1811} 1812 1813var formatterFlagTests = []struct { 1814 in string 1815 val any 1816 out string 1817}{ 1818 // scalar values with the (unused by fmt) 'a' verb. 1819 {"%a", flagPrinter{}, "[%a]"}, 1820 {"%-a", flagPrinter{}, "[%-a]"}, 1821 {"%+a", flagPrinter{}, "[%+a]"}, 1822 {"%#a", flagPrinter{}, "[%#a]"}, 1823 {"% a", flagPrinter{}, "[% a]"}, 1824 {"%0a", flagPrinter{}, "[%0a]"}, 1825 {"%1.2a", flagPrinter{}, "[%1.2a]"}, 1826 {"%-1.2a", flagPrinter{}, "[%-1.2a]"}, 1827 {"%+1.2a", flagPrinter{}, "[%+1.2a]"}, 1828 {"%-+1.2a", flagPrinter{}, "[%+-1.2a]"}, 1829 {"%-+1.2abc", flagPrinter{}, "[%+-1.2a]bc"}, 1830 {"%-1.2abc", flagPrinter{}, "[%-1.2a]bc"}, 1831 {"%-0abc", flagPrinter{}, "[%-0a]bc"}, 1832 1833 // composite values with the 'a' verb 1834 {"%a", [1]flagPrinter{}, "[[%a]]"}, 1835 {"%-a", [1]flagPrinter{}, "[[%-a]]"}, 1836 {"%+a", [1]flagPrinter{}, "[[%+a]]"}, 1837 {"%#a", [1]flagPrinter{}, "[[%#a]]"}, 1838 {"% a", [1]flagPrinter{}, "[[% a]]"}, 1839 {"%0a", [1]flagPrinter{}, "[[%0a]]"}, 1840 {"%1.2a", [1]flagPrinter{}, "[[%1.2a]]"}, 1841 {"%-1.2a", [1]flagPrinter{}, "[[%-1.2a]]"}, 1842 {"%+1.2a", [1]flagPrinter{}, "[[%+1.2a]]"}, 1843 {"%-+1.2a", [1]flagPrinter{}, "[[%+-1.2a]]"}, 1844 {"%-+1.2abc", [1]flagPrinter{}, "[[%+-1.2a]]bc"}, 1845 {"%-1.2abc", [1]flagPrinter{}, "[[%-1.2a]]bc"}, 1846 {"%-0abc", [1]flagPrinter{}, "[[%-0a]]bc"}, 1847 1848 // simple values with the 'v' verb 1849 {"%v", flagPrinter{}, "[%v]"}, 1850 {"%-v", flagPrinter{}, "[%-v]"}, 1851 {"%+v", flagPrinter{}, "[%+v]"}, 1852 {"%#v", flagPrinter{}, "[%#v]"}, 1853 {"% v", flagPrinter{}, "[% v]"}, 1854 {"%0v", flagPrinter{}, "[%0v]"}, 1855 {"%1.2v", flagPrinter{}, "[%1.2v]"}, 1856 {"%-1.2v", flagPrinter{}, "[%-1.2v]"}, 1857 {"%+1.2v", flagPrinter{}, "[%+1.2v]"}, 1858 {"%-+1.2v", flagPrinter{}, "[%+-1.2v]"}, 1859 {"%-+1.2vbc", flagPrinter{}, "[%+-1.2v]bc"}, 1860 {"%-1.2vbc", flagPrinter{}, "[%-1.2v]bc"}, 1861 {"%-0vbc", flagPrinter{}, "[%-0v]bc"}, 1862 1863 // composite values with the 'v' verb. 1864 {"%v", [1]flagPrinter{}, "[[%v]]"}, 1865 {"%-v", [1]flagPrinter{}, "[[%-v]]"}, 1866 {"%+v", [1]flagPrinter{}, "[[%+v]]"}, 1867 {"%#v", [1]flagPrinter{}, "[1]fmt_test.flagPrinter{[%#v]}"}, 1868 {"% v", [1]flagPrinter{}, "[[% v]]"}, 1869 {"%0v", [1]flagPrinter{}, "[[%0v]]"}, 1870 {"%1.2v", [1]flagPrinter{}, "[[%1.2v]]"}, 1871 {"%-1.2v", [1]flagPrinter{}, "[[%-1.2v]]"}, 1872 {"%+1.2v", [1]flagPrinter{}, "[[%+1.2v]]"}, 1873 {"%-+1.2v", [1]flagPrinter{}, "[[%+-1.2v]]"}, 1874 {"%-+1.2vbc", [1]flagPrinter{}, "[[%+-1.2v]]bc"}, 1875 {"%-1.2vbc", [1]flagPrinter{}, "[[%-1.2v]]bc"}, 1876 {"%-0vbc", [1]flagPrinter{}, "[[%-0v]]bc"}, 1877} 1878 1879func TestFormatterFlags(t *testing.T) { 1880 for _, tt := range formatterFlagTests { 1881 s := Sprintf(tt.in, tt.val) 1882 if s != tt.out { 1883 t.Errorf("Sprintf(%q, %T) = %q, want %q", tt.in, tt.val, s, tt.out) 1884 } 1885 } 1886} 1887 1888func TestParsenum(t *testing.T) { 1889 testCases := []struct { 1890 s string 1891 start, end int 1892 num int 1893 isnum bool 1894 newi int 1895 }{ 1896 {"a123", 0, 4, 0, false, 0}, 1897 {"1234", 1, 1, 0, false, 1}, 1898 {"123a", 0, 4, 123, true, 3}, 1899 {"12a3", 0, 4, 12, true, 2}, 1900 {"1234", 0, 4, 1234, true, 4}, 1901 {"1a234", 1, 3, 0, false, 1}, 1902 } 1903 for _, tt := range testCases { 1904 num, isnum, newi := Parsenum(tt.s, tt.start, tt.end) 1905 if num != tt.num || isnum != tt.isnum || newi != tt.newi { 1906 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) 1907 } 1908 } 1909} 1910 1911// Test the various Append printers. The details are well tested above; 1912// here we just make sure the byte slice is updated. 1913 1914const ( 1915 appendResult = "hello world, 23" 1916 hello = "hello " 1917) 1918 1919func TestAppendf(t *testing.T) { 1920 b := make([]byte, 100) 1921 b = b[:copy(b, hello)] 1922 got := Appendf(b, "world, %d", 23) 1923 if string(got) != appendResult { 1924 t.Fatalf("Appendf returns %q not %q", got, appendResult) 1925 } 1926 if &b[0] != &got[0] { 1927 t.Fatalf("Appendf allocated a new slice") 1928 } 1929} 1930 1931func TestAppend(t *testing.T) { 1932 b := make([]byte, 100) 1933 b = b[:copy(b, hello)] 1934 got := Append(b, "world", ", ", 23) 1935 if string(got) != appendResult { 1936 t.Fatalf("Append returns %q not %q", got, appendResult) 1937 } 1938 if &b[0] != &got[0] { 1939 t.Fatalf("Append allocated a new slice") 1940 } 1941} 1942 1943func TestAppendln(t *testing.T) { 1944 b := make([]byte, 100) 1945 b = b[:copy(b, hello)] 1946 got := Appendln(b, "world,", 23) 1947 if string(got) != appendResult+"\n" { 1948 t.Fatalf("Appendln returns %q not %q", got, appendResult+"\n") 1949 } 1950 if &b[0] != &got[0] { 1951 t.Fatalf("Appendln allocated a new slice") 1952 } 1953} 1954