]> Cypherpunks repositories - gostls13.git/commitdiff
fmt: document and fix the handling of precision for strings and byte slices
authorRob Pike <r@golang.org>
Wed, 24 Sep 2014 21:33:30 +0000 (14:33 -0700)
committerRob Pike <r@golang.org>
Wed, 24 Sep 2014 21:33:30 +0000 (14:33 -0700)
Previous behavior was undocumented and inconsistent. Now it is documented
and consistent and measures the input size, since that makes more sense
when talking about %q and %x. For %s the change has no effect.

Fixes #8151.

LGTM=iant
R=golang-codereviews, iant
CC=golang-codereviews
https://golang.org/cl/144540044

src/fmt/doc.go
src/fmt/fmt_test.go
src/fmt/format.go

index b7eaedc11ed2423b7372fa2d18d598b79927b6c6..00dd8d01cd9b2743a7129f02c421c0ddf27edcd0 100644 (file)
                %9.2f  width 9, precision 2
                %9.f   width 9, precision 0
 
-       Width and precision are measured in units of Unicode code points.
-       (This differs from C's printf where the units are numbers
-       of bytes.) Either or both of the flags may be replaced with the
-       character '*', causing their values to be obtained from the next
-       operand, which must be of type int.
+       Width and precision are measured in units of Unicode code points,
+       that is, runes. (This differs from C's printf where the
+       units are always measured in bytes.) Either or both of the flags
+       may be replaced with the character '*', causing their values to be
+       obtained from the next operand, which must be of type int.
 
-       For most values, width is the minimum number of characters to output,
+       For most values, width is the minimum number of runes to output,
        padding the formatted form with spaces if necessary.
-       For strings, precision is the maximum number of characters to output,
-       truncating if necessary.
+
+       For strings, byte slices and byte arrays, however, precision
+       limits the length of the input to be formatted (not the size of
+       the output), truncating if necessary. Normally it is measured in
+       runes, but for these types when formatted with the %x or %X format
+       it is measured in bytes.
 
        For floating-point values, width sets the minimum width of the field and
        precision sets the number of places after the decimal, if appropriate,
index cca0a495ffe47d817bba07210a192b0076883e2d..4586fcf933096c273334bb238a7f847f8a932041 100644 (file)
@@ -194,8 +194,15 @@ var fmtTests = []struct {
        {"%.5s", "日本語日本語", "日本語日本"},
        {"%.5s", []byte("日本語日本語"), "日本語日本"},
        {"%.5q", "abcdefghijklmnopqrstuvwxyz", `"abcde"`},
+       {"%.5x", "abcdefghijklmnopqrstuvwxyz", `6162636465`},
+       {"%.5q", []byte("abcdefghijklmnopqrstuvwxyz"), `"abcde"`},
+       {"%.5x", []byte("abcdefghijklmnopqrstuvwxyz"), `6162636465`},
        {"%.3q", "日本語日本語", `"日本語"`},
        {"%.3q", []byte("日本語日本語"), `"日本語"`},
+       {"%.1q", "日本語", `"日"`},
+       {"%.1q", []byte("日本語"), `"日"`},
+       {"%.1x", "日本語", `e6`},
+       {"%.1X", []byte("日本語"), `E6`},
        {"%10.1q", "日本語日本語", `       "日"`},
        {"%3c", '⌘', "  ⌘"},
        {"%5q", '\u2026', `  '…'`},
index 255167c8f519c1aed11339386e01fa6bdc4efb31..a92f3c2f86412386164fee3e0cb0b3de31c47106 100644 (file)
@@ -340,11 +340,17 @@ func (f *fmt) fmt_sbx(s string, b []byte, digits string) {
 
 // fmt_sx formats a string as a hexadecimal encoding of its bytes.
 func (f *fmt) fmt_sx(s, digits string) {
+       if f.precPresent && f.prec < len(s) {
+               s = s[:f.prec]
+       }
        f.fmt_sbx(s, nil, digits)
 }
 
 // fmt_bx formats a byte slice as a hexadecimal encoding of its bytes.
 func (f *fmt) fmt_bx(b []byte, digits string) {
+       if f.precPresent && f.prec < len(b) {
+               b = b[:f.prec]
+       }
        f.fmt_sbx("", b, digits)
 }