[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#7325: new test failure due to non-portability of printf formats like
From: |
Jim Meyering |
Subject: |
bug#7325: new test failure due to non-portability of printf formats like %05.3s |
Date: |
Wed, 03 Nov 2010 22:26:40 +0100 |
Eric Blake wrote:
> On 11/03/2010 12:59 PM, Jim Meyering wrote:
>> Note that coreutils' printf does not accept the '0' modifier in a %s format.
>>
>> $ env printf '%05.3s\n' 23
>> printf: %05.3s: invalid conversion specification
>>
>> That's because POSIX says the "0" modifier applies only to the
>> d, i, o, u, x, X, a, A, e, E, f, F, g, and G conversion specifiers.
>>
>> One solution is to trim off the "0".
>> It's probably a good idea regardless, in case some implementation rejects it.
>>
>> On the other hand, I find the zero-padding you currently get
>> with stat on solaris to be slightly more intuitive.
>
> I agree that %05.3:X resulting in 00023 would be ideal. And I agree
> that we'd have to trim off the 0 modifier before calling the underlying
> printf %s, and thus be responsible for putting in '0' padding ourselves
> rather than relying on printf() padding.
Thanks for confirming.
Here's the patch I'm considering:
diff --git a/src/stat.c b/src/stat.c
index d05a93b..993db48 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -472,6 +472,23 @@ epoch_sec (struct timespec t)
return timetostr (t.tv_sec, str);
}
+/* Convert a LEN-byte FORMAT modifier, e.g., "0009.4", to "9.4".
+ Do it in place and return the new length. */
+static size_t
+sanitize_format_string (char *format, size_t len)
+{
+ char *p = format;
+ char const *end = format + len;
+ while (p < end && *p == '0')
+ p++;
+ if (p == format)
+ return len;
+
+ len -= p - format;
+ memmove (format, p, len);
+ return len;
+}
+
/* Output the number of nanoseconds, ARG.tv_nsec, honoring a
WIDTH.PRECISION format modifier, where PRECISION specifies
how many leading digits(on a field of 9) to print. */
@@ -496,8 +513,25 @@ out_ns (char *pformat, size_t prefix_len, struct timespec
arg)
{
char tmp[INT_BUFSIZE_BOUND (uintmax_t)];
snprintf (tmp, sizeof tmp, "%09lu", ns);
+ /* Handle formats like %5.3:X and %05.3:X, which, with the likes of
+ "023" in TMP, should print " 023" and "00023" respectively.
+ Do not use a format like "%05s" with *printf, since POSIX says
+ the '0' modifier does not apply to the "s" conversion specifier. */
+ size_t new_len = sanitize_format_string (pformat + 1, prefix_len - 1);
+ bool zero_pad = (new_len < prefix_len - 1);
+ prefix_len = new_len + 1;
strcpy (pformat + prefix_len, "s");
- printf (pformat, tmp);
+ char b2[INT_BUFSIZE_BOUND (uintmax_t)];
+ /* Format the result, as usual... */
+ snprintf (b2, sizeof b2, pformat, tmp);
+ /* But if zero-padding is desired, convert leading blanks to zeros. */
+ if (zero_pad)
+ {
+ char *p = b2;
+ while (*p == ' ')
+ *p++ = '0';
+ }
+ fputs (b2, stdout);
}
else
{
diff --git a/tests/misc/stat-nanoseconds b/tests/misc/stat-nanoseconds
index 314f43e..9c06a51 100755
--- a/tests/misc/stat-nanoseconds
+++ b/tests/misc/stat-nanoseconds
@@ -30,7 +30,7 @@ test "$(stat -c %3.3:X k)" = 023 || fail=1
test "$(stat -c %.3:X k)" = 023 || fail=1
test "$(stat -c %03.3:X k)" = 023 || fail=1
test "$(stat -c %-5.3:X k)" = '023 ' || fail=1
-test "$(stat -c %05.3:X k)" = ' 023' || fail=1
-test "$(stat -c %010.3:X k)" = ' 023' || fail=1
+test "$(stat -c %05.3:X k)" = 00023 || fail=1
+test "$(stat -c %010.3:X k)" = 0000000023 || fail=1
Exit $fail
- bug#7325: new test failure due to non-portability of printf formats like %05.3s, Jim Meyering, 2010/11/03
- bug#7325: new test failure due to non-portability of printf formats like %05.3s, Eric Blake, 2010/11/03
- bug#7325: new test failure due to non-portability of printf formats like %05.3s,
Jim Meyering <=
- bug#7325: new test failure due to non-portability of printf formats like %05.3s, Eric Blake, 2010/11/03
- bug#7325: new test failure due to non-portability of printf formats like %05.3s, Paul Eggert, 2010/11/03
- bug#7325: new test failure due to non-portability of printf formats like %05.3s, Jim Meyering, 2010/11/04
- bug#7325: new test failure due to non-portability of printf formats like %05.3s, Jim Meyering, 2010/11/04
- bug#7325: new test failure due to non-portability of printf formats like %05.3s, Paul Eggert, 2010/11/04
- bug#7325: new test failure due to non-portability of printf formats like %05.3s, Jim Meyering, 2010/11/04
- bug#7325: new test failure due to non-portability of printf formats like %05.3s, Jim Meyering, 2010/11/05
- bug#7325: new test failure due to non-portability of printf formats like %05.3s, Paul Eggert, 2010/11/05
- bug#7325: new test failure due to non-portability of printf formats like %05.3s, Pádraig Brady, 2010/11/04
- bug#7325: new test failure due to non-portability of printf formats like %05.3s, Jim Meyering, 2010/11/05