diff options
author | Rich Felker <dalias@aerifal.cx> | 2018-02-06 12:31:06 -0500 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2018-02-06 12:31:06 -0500 |
commit | c7f0da4134d4e7f2efd295e7fb738c65c469fbd1 (patch) | |
tree | f28bc3fc1b716d9919a5c48c2fa379b6ea1bd500 /src/time/strftime.c | |
parent | 596207aa38b0db33f222c9924a1310fee3de88b5 (diff) | |
download | musl-c7f0da4134d4e7f2efd295e7fb738c65c469fbd1.zip musl-c7f0da4134d4e7f2efd295e7fb738c65c469fbd1.tar.gz musl-c7f0da4134d4e7f2efd295e7fb738c65c469fbd1.tar.bz2 |
adjust strftime + modifier to match apparent intent of POSIX
it's unclear from the specification whether the word "consumes" in
"consumes more than four bytes to represent a year" refers just to
significant places or includes leading zeros due to field width
padding. however the examples in the rationale indicate that the
latter was the intent. in particular, the year 270 is shown being
formatted by %+5Y as +0270 rather than 00270.
previously '+' prefixing was implemented just by comparing the year
against 10000. instead, count the number of significant digits and
padding bytes to be added, and use the total to determine whether to
apply the '+' prefix.
based on testing by Dennis Wölfing.
Diffstat (limited to 'src/time/strftime.c')
-rw-r--r-- | src/time/strftime.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/src/time/strftime.c b/src/time/strftime.c index 16b3bb2..708875e 100644 --- a/src/time/strftime.c +++ b/src/time/strftime.c @@ -251,15 +251,21 @@ size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const st t = __strftime_fmt_1(&buf, &k, *f, tm, loc, pad); if (!t) break; if (width) { + /* Trim off any sign and leading zeros, then + * count remaining digits to determine behavior + * for the + flag. */ if (*t=='+' || *t=='-') t++, k--; for (; *t=='0' && t[1]-'0'<10U; t++, k--); - width--; - if (plus && tm->tm_year >= 10000-1900) - s[l++] = '+'; - else if (tm->tm_year < -1900) + if (width < k) width = k; + size_t d; + for (d=0; t[d]-'0'<10U; d++); + if (tm->tm_year < -1900) { s[l++] = '-'; - else - width++; + width--; + } else if (plus && d+(width-k) >= (*p=='C'?3:5)) { + s[l++] = '+'; + width--; + } for (; width > k && l < n; width--) s[l++] = '0'; } |