diff --git a/src/fmt/fmt_test.go b/src/fmt/fmt_test.go index cc4c71cb09d..be7299cdbc4 100644 --- a/src/fmt/fmt_test.go +++ b/src/fmt/fmt_test.go @@ -48,11 +48,6 @@ func TestFmtInterface(t *testing.T) { } } -const ( - b32 uint32 = 1<<32 - 1 - b64 uint64 = 1<<64 - 1 -) - var ( NaN = math.NaN() posInf = math.Inf(1) @@ -319,23 +314,47 @@ var fmtTests = []struct { {"%-10v", nil, " "}, // integers - {"%d", 12345, "12345"}, - {"%d", -12345, "-12345"}, + {"%d", uint(12345), "12345"}, + {"%d", int(-12345), "-12345"}, + {"%d", ^uint8(0), "255"}, + {"%d", ^uint16(0), "65535"}, + {"%d", ^uint32(0), "4294967295"}, + {"%d", ^uint64(0), "18446744073709551615"}, + {"%d", int8(-1 << 7), "-128"}, + {"%d", int16(-1 << 15), "-32768"}, + {"%d", int32(-1 << 31), "-2147483648"}, + {"%d", int64(-1 << 63), "-9223372036854775808"}, + {"%.d", 0, ""}, + {"%.0d", 0, ""}, + {"% d", 12345, " 12345"}, + {"%+d", 12345, "+12345"}, + {"%+d", -12345, "-12345"}, + {"%b", 7, "111"}, + {"%b", -6, "-110"}, + {"%b", ^uint32(0), "11111111111111111111111111111111"}, + {"%b", ^uint64(0), "1111111111111111111111111111111111111111111111111111111111111111"}, + {"%o", 01234, "1234"}, + {"%#o", 01234, "01234"}, + {"%o", ^uint32(0), "37777777777"}, + {"%o", ^uint64(0), "1777777777777777777777"}, + {"%#X", 0, "0X0"}, + {"%x", 0x12abcdef, "12abcdef"}, + {"%X", 0x12abcdef, "12ABCDEF"}, + {"%x", ^uint32(0), "ffffffff"}, + {"%X", ^uint64(0), "FFFFFFFFFFFFFFFF"}, + {"%.20b", 7, "00000000000000000111"}, {"%10d", 12345, " 12345"}, {"%10d", -12345, " -12345"}, {"%+10d", 12345, " +12345"}, {"%010d", 12345, "0000012345"}, {"%010d", -12345, "-000012345"}, - {"%-10d", 12345, "12345 "}, - {"%010.3d", 1, " 001"}, - {"%010.3d", -1, " -001"}, - {"%+d", 12345, "+12345"}, - {"%+d", -12345, "-12345"}, - {"%+d", 0, "+0"}, - {"% d", 0, " 0"}, - {"% d", 12345, " 12345"}, - {"%.0d", 0, ""}, - {"%.d", 0, ""}, + {"%20.8d", 1234, " 00001234"}, + {"%20.8d", -1234, " -00001234"}, + {"%-20.8d", 1234, "00001234 "}, + {"%-20.8d", -1234, "-00001234 "}, + {"%-#20.8x", 0x1234abc, "0x01234abc "}, + {"%-#20.8X", 0x1234abc, "0X01234ABC "}, + {"%-#20.8o", 01234, "00001234 "}, // unicode format {"%U", 0, "U+0000"}, @@ -453,25 +472,6 @@ var fmtTests = []struct { {"%-08G", complex(NaN, NaN), "(NaN +NaN i)"}, // old test/fmt_test.go - {"%d", 1234, "1234"}, - {"%d", -1234, "-1234"}, - {"%d", uint(1234), "1234"}, - {"%d", uint32(b32), "4294967295"}, - {"%d", uint64(b64), "18446744073709551615"}, - {"%o", 01234, "1234"}, - {"%#o", 01234, "01234"}, - {"%o", uint32(b32), "37777777777"}, - {"%o", uint64(b64), "1777777777777777777777"}, - {"%x", 0x1234abcd, "1234abcd"}, - {"%#x", 0x1234abcd, "0x1234abcd"}, - {"%x", b32 - 0x1234567, "fedcba98"}, - {"%X", 0x1234abcd, "1234ABCD"}, - {"%X", b32 - 0x1234567, "FEDCBA98"}, - {"%#X", 0, "0X0"}, - {"%x", b64, "ffffffffffffffff"}, - {"%b", 7, "111"}, - {"%b", b64, "1111111111111111111111111111111111111111111111111111111111111111"}, - {"%b", -6, "-110"}, {"%e", 1.0, "1.000000e+00"}, {"%e", 1234.5678e3, "1.234568e+06"}, {"%e", 1234.5678e-8, "1.234568e-05"}, @@ -498,15 +498,6 @@ var fmtTests = []struct { {"%G", -7.0, "-7"}, {"%G", -1e-9, "-1E-09"}, {"%G", float32(-1e-9), "-1E-09"}, - {"%20.8d", 1234, " 00001234"}, - {"%20.8d", -1234, " -00001234"}, - {"%20d", 1234, " 1234"}, - {"%-20.8d", 1234, "00001234 "}, - {"%-20.8d", -1234, "-00001234 "}, - {"%-#20.8x", 0x1234abc, "0x01234abc "}, - {"%-#20.8X", 0x1234abc, "0X01234ABC "}, - {"%-#20.8o", 01234, "00001234 "}, - {"%.20b", 7, "00000000000000000111"}, {"%20.5s", "qwertyuiop", " qwert"}, {"%.5s", "qwertyuiop", "qwert"}, {"%-20.5s", "qwertyuiop", "qwert "}, @@ -822,11 +813,11 @@ var fmtTests = []struct { {"%0.100f", -1.0, zeroFill("-1.", 100, "")}, // Used to panic: integer function didn't look at f.prec, f.unicode, f.width or sign. - {"%#.80x", 42, "0x0000000000000000000000000000000000000000000000000000000000000000000000000000002a"}, - {"%.65d", -44, "-00000000000000000000000000000000000000000000000000000000000000044"}, - {"%+.65d", 44, "+00000000000000000000000000000000000000000000000000000000000000044"}, - {"% .65d", 44, " 00000000000000000000000000000000000000000000000000000000000000044"}, - {"% +.65d", 44, "+00000000000000000000000000000000000000000000000000000000000000044"}, + {"%#.65x", 42, zeroFill("0x", 65, "2a")}, + {"%.65d", -42, zeroFill("-", 65, "42")}, + {"%+.65d", 42, zeroFill("+", 65, "42")}, + {"% .65d", 42, zeroFill(" ", 65, "42")}, + {"% +.65d", 42, zeroFill("+", 65, "42")}, // Comparison of padding rules with C printf. /* diff --git a/src/fmt/format.go b/src/fmt/format.go index 1c612c12180..648da8a6a31 100644 --- a/src/fmt/format.go +++ b/src/fmt/format.go @@ -190,17 +190,16 @@ func (f *fmt) fmt_unicode(u uint64) { f.zero = oldZero } -// integer; interprets prec but not wid. Once formatted, result is sent to pad() -// and then flags are cleared. -func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) { +// fmt_integer formats signed and unsigned integers. +func (f *fmt) fmt_integer(u uint64, base int, isSigned bool, digits string) { // precision of 0 and value of 0 means "print nothing" - if f.precPresent && f.prec == 0 && a == 0 { + if f.precPresent && f.prec == 0 && u == 0 { return } - negative := signedness == signed && a < 0 + negative := isSigned && int64(u) < 0 if negative { - a = -a + u = -u } var buf []byte = f.intbuf[0:] @@ -233,45 +232,43 @@ func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) { } } - // format a into buf, ending at buf[i]. (printing is easier right-to-left.) - // a is made into unsigned ua. we could make things - // marginally faster by splitting the 32-bit case out into a separate - // block but it's not worth the duplication, so ua has 64 bits. + // Because printing is easier right-to-left: format u into buf, ending at buf[i]. + // We could make things marginally faster by splitting the 32-bit case out + // into a separate block but it's not worth the duplication, so u has 64 bits. i := len(buf) - ua := uint64(a) - // use constants for the division and modulo for more efficient code. - // switch cases ordered by popularity. + // Use constants for the division and modulo for more efficient code. + // Switch cases ordered by popularity. switch base { case 10: - for ua >= 10 { + for u >= 10 { i-- - next := ua / 10 - buf[i] = byte('0' + ua - next*10) - ua = next + next := u / 10 + buf[i] = byte('0' + u - next*10) + u = next } case 16: - for ua >= 16 { + for u >= 16 { i-- - buf[i] = digits[ua&0xF] - ua >>= 4 + buf[i] = digits[u&0xF] + u >>= 4 } case 8: - for ua >= 8 { + for u >= 8 { i-- - buf[i] = byte('0' + ua&7) - ua >>= 3 + buf[i] = byte('0' + u&7) + u >>= 3 } case 2: - for ua >= 2 { + for u >= 2 { i-- - buf[i] = byte('0' + ua&1) - ua >>= 1 + buf[i] = byte('0' + u&1) + u >>= 1 } default: panic("fmt: unknown base; can't happen") } i-- - buf[i] = digits[ua] + buf[i] = digits[u] for i > 0 && prec > len(buf)-i { i-- buf[i] = '0' diff --git a/src/fmt/print.go b/src/fmt/print.go index bc244d9c815..0064ab37347 100644 --- a/src/fmt/print.go +++ b/src/fmt/print.go @@ -338,68 +338,42 @@ func (p *pp) fmtBool(v bool, verb rune) { } } -func (p *pp) fmtInt64(v int64, verb rune) { - switch verb { - case 'b': - p.fmt.integer(v, 2, signed, ldigits) - case 'c': - p.fmt.fmt_c(uint64(v)) - case 'd', 'v': - p.fmt.integer(v, 10, signed, ldigits) - case 'o': - p.fmt.integer(v, 8, signed, ldigits) - case 'q': - if 0 <= v && v <= utf8.MaxRune { - p.fmt.fmt_qc(uint64(v)) - } else { - p.badVerb(verb) - } - case 'x': - p.fmt.integer(v, 16, signed, ldigits) - case 'U': - p.fmt.fmt_unicode(uint64(v)) - case 'X': - p.fmt.integer(v, 16, signed, udigits) - default: - p.badVerb(verb) - } -} - // fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x or // not, as requested, by temporarily setting the sharp flag. func (p *pp) fmt0x64(v uint64, leading0x bool) { sharp := p.fmt.sharp p.fmt.sharp = leading0x - p.fmt.integer(int64(v), 16, unsigned, ldigits) + p.fmt.fmt_integer(v, 16, unsigned, ldigits) p.fmt.sharp = sharp } -func (p *pp) fmtUint64(v uint64, verb rune) { +// fmtInteger formats a signed or unsigned integer. +func (p *pp) fmtInteger(v uint64, isSigned bool, verb rune) { switch verb { - case 'b': - p.fmt.integer(int64(v), 2, unsigned, ldigits) - case 'c': - p.fmt.fmt_c(v) - case 'd': - p.fmt.integer(int64(v), 10, unsigned, ldigits) case 'v': - if p.fmt.sharpV { + if p.fmt.sharpV && !isSigned { p.fmt0x64(v, true) } else { - p.fmt.integer(int64(v), 10, unsigned, ldigits) + p.fmt.fmt_integer(v, 10, isSigned, ldigits) } + case 'd': + p.fmt.fmt_integer(v, 10, isSigned, ldigits) + case 'b': + p.fmt.fmt_integer(v, 2, isSigned, ldigits) case 'o': - p.fmt.integer(int64(v), 8, unsigned, ldigits) + p.fmt.fmt_integer(v, 8, isSigned, ldigits) + case 'x': + p.fmt.fmt_integer(v, 16, isSigned, ldigits) + case 'X': + p.fmt.fmt_integer(v, 16, isSigned, udigits) + case 'c': + p.fmt.fmt_c(v) case 'q': - if 0 <= v && v <= utf8.MaxRune { + if v <= utf8.MaxRune { p.fmt.fmt_qc(v) } else { p.badVerb(verb) } - case 'x': - p.fmt.integer(int64(v), 16, unsigned, ldigits) - case 'X': - p.fmt.integer(int64(v), 16, unsigned, udigits) case 'U': p.fmt.fmt_unicode(v) default: @@ -489,7 +463,7 @@ func (p *pp) fmtBytes(v []byte, verb rune, typeString string) { if i > 0 { p.buf.WriteByte(' ') } - p.fmt.integer(int64(c), 10, unsigned, ldigits) + p.fmt.fmt_integer(uint64(c), 10, unsigned, ldigits) } p.buf.WriteByte(']') } @@ -538,7 +512,7 @@ func (p *pp) fmtPointer(value reflect.Value, verb rune) { case 'p': p.fmt0x64(uint64(u), !p.fmt.sharp) case 'b', 'o', 'd', 'x', 'X': - p.fmtUint64(uint64(u), verb) + p.fmtInteger(uint64(u), unsigned, verb) default: p.badVerb(verb) } @@ -657,27 +631,27 @@ func (p *pp) printArg(arg interface{}, verb rune) { case complex128: p.fmtComplex(f, 128, verb) case int: - p.fmtInt64(int64(f), verb) + p.fmtInteger(uint64(f), signed, verb) case int8: - p.fmtInt64(int64(f), verb) + p.fmtInteger(uint64(f), signed, verb) case int16: - p.fmtInt64(int64(f), verb) + p.fmtInteger(uint64(f), signed, verb) case int32: - p.fmtInt64(int64(f), verb) + p.fmtInteger(uint64(f), signed, verb) case int64: - p.fmtInt64(f, verb) + p.fmtInteger(uint64(f), signed, verb) case uint: - p.fmtUint64(uint64(f), verb) + p.fmtInteger(uint64(f), unsigned, verb) case uint8: - p.fmtUint64(uint64(f), verb) + p.fmtInteger(uint64(f), unsigned, verb) case uint16: - p.fmtUint64(uint64(f), verb) + p.fmtInteger(uint64(f), unsigned, verb) case uint32: - p.fmtUint64(uint64(f), verb) + p.fmtInteger(uint64(f), unsigned, verb) case uint64: - p.fmtUint64(f, verb) + p.fmtInteger(f, unsigned, verb) case uintptr: - p.fmtUint64(uint64(f), verb) + p.fmtInteger(uint64(f), unsigned, verb) case string: p.fmtString(f, verb) case []byte: @@ -737,9 +711,9 @@ BigSwitch: case reflect.Bool: p.fmtBool(f.Bool(), verb) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - p.fmtInt64(f.Int(), verb) + p.fmtInteger(uint64(f.Int()), signed, verb) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - p.fmtUint64(f.Uint(), verb) + p.fmtInteger(f.Uint(), unsigned, verb) case reflect.Float32: p.fmtFloat(f.Float(), 32, verb) case reflect.Float64: