Subject: bug#7325: new test failure due to non-portability of printf formats like %05.3s

From: Jim Meyering <[email-masked]>
Date: Thu, 11 Nov 2010 12:49:10 +0100

Paul Eggert wrote:

> On 11/10/2010 01:04 AM, Jim Meyering wrote:
>> +      /* %.X   => precision defaults to 9
>> +         %.5X  => precision is 5
>> +         %#.X  => precision is determined by fstimeprec
>> +         %#.3X => precision is 3 (specified overrides "#")  */
>
> How about something like this instead?
>
>   %.X => precision is 9 (until POSIX goes sub-nanosecond :-)
>   %.5X => precision is 5
>   %.*X => precision determined by fstimeprec
>
> Then there's no reason for the "overrides" case.

Good idea.  I prefer that.

>From 26e466e056462448e81536d9a96499fbe1f725ef Mon Sep 17 00:00:00 2001
From: Jim Meyering <[email-masked]>
Date: Wed, 10 Nov 2010 12:28:30 +0100
Subject: [PATCH] stat: default to precision=9; now %.*X uses variable

---
 src/stat.c |   13 +++++++++++--
 1 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/stat.c b/src/stat.c
index ae7ce02..7ceb9c1 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -550,18 +550,26 @@ out_epoch_sec (char *pformat, size_t prefix_len, struct stat const *statbuf,
       sec_prefix_len = dot - pformat;
       pformat[prefix_len] = '\0';

+      /* %.X   => precision defaults to 9
+         %.5X  => precision is 5
+         %.*X  => precision is determined by fstimeprec */
+
       if (ISDIGIT (dot[1]))
         {
           long int lprec = strtol (dot + 1, NULL, 10);
           precision = (lprec <= INT_MAX ? lprec : INT_MAX);
         }
-      else
+      else if (dot[1] == '*')
         {
           static struct fstimeprec *tab;
           if (! tab)
             tab = fstimeprec_alloc ();
           precision = fstimeprec (tab, statbuf);
         }
+      else
+        {
+          precision = 9;
+        }

       if (precision && ISDIGIT (dot[-1]))
         {
@@ -1061,7 +1069,8 @@ print_it (char const *format, char const *filename,
             char const *fmt_char = b + len + 1;
             fmt_char += strspn (fmt_char, digits);
             if (*fmt_char == '.')
-              fmt_char += 1 + strspn (fmt_char + 1, digits);
+              fmt_char += 1 + (fmt_char[1] == '*'
+                               ? 1 : strspn (fmt_char + 1, digits));
             len = fmt_char - (b + 1);
             unsigned int fmt_code = *fmt_char;
             memcpy (dest, b, len + 1);
--
1.7.3.2.4.g60aa9