]> Cypherpunks repositories - gostls13.git/commitdiff
fmt: unify integer formatting
authorMartin Möhrmann <martisch@uos.de>
Fri, 18 Mar 2016 07:24:40 +0000 (08:24 +0100)
committerRob Pike <r@golang.org>
Sun, 20 Mar 2016 12:08:03 +0000 (12:08 +0000)
Deduplicate the verb switch for signed and unsigned integer formatting.

Make names of integer related functions consistent
with names of other fmt functions.

Consolidate basic integer tests.

Change-Id: I0c19c24f1c2c06a3b1a4d7d377dcdac3b36bb0f5
Reviewed-on: https://go-review.googlesource.com/20831
Run-TryBot: Rob Pike <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
src/fmt/fmt_test.go
src/fmt/format.go
src/fmt/print.go

index cc4c71cb09d51a120a21a4348a31cc500f56b46f..be7299cdbc412c121015e402d9ed8d7d396dac8a 100644 (file)
@@ -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, "<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.
        /*
index 1c612c1218069726af2b06ad73a79e4f446d8305..648da8a6a3120694194e6eae5f1144247a91165c 100644 (file)
@@ -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'
index bc244d9c815a81f2d512ffa348a466d5e226d9fa..0064ab373472fb6ea2c880f970b30773a77aa6a2 100644 (file)
@@ -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: