|
Message-Id: <20170106065959.2161-1-timo.teras@iki.fi> Date: Fri, 6 Jan 2017 08:59:59 +0200 From: Timo Teräs <timo.teras@....fi> To: musl@...ts.openwall.com Cc: Timo Teräs <timo.teras@....fi> Subject: [PATCH v2] implement strftime GNU extension padding specifiers '_', '-' and '0' --- v2: support these specifiers for recursive built format strings such as '%F' src/time/strftime.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/time/strftime.c b/src/time/strftime.c index a3039204..733e4e28 100644 --- a/src/time/strftime.c +++ b/src/time/strftime.c @@ -46,9 +46,9 @@ static int week_num(const struct tm *tm) } const char *__tm_to_tzname(const struct tm *); -size_t __strftime_l(char *restrict, size_t, const char *restrict, const struct tm *restrict, locale_t); +static size_t __strftime_impl(char *restrict, size_t, const char *restrict, const struct tm *restrict, locale_t, int); -const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *tm, locale_t loc) +const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *tm, locale_t loc, int pad) { nl_item item; long long val; @@ -79,15 +79,14 @@ const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm * case 'C': val = (1900LL+tm->tm_year) / 100; goto number; + case 'e': + pad = '_'; case 'd': val = tm->tm_mday; goto number; case 'D': fmt = "%m/%d/%y"; goto recu_strftime; - case 'e': - *l = snprintf(*s, sizeof *s, "%2d", tm->tm_mday); - return *s; case 'F': fmt = "%Y-%m-%d"; goto recu_strftime; @@ -200,7 +199,12 @@ const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm * return 0; } number: - *l = snprintf(*s, sizeof *s, "%0*lld", width, val); + switch (pad) { + case '-': *l = snprintf(*s, sizeof *s, "%lld", val); break; + case '_': *l = snprintf(*s, sizeof *s, "%*lld", width, val); break; + case '0': + default: *l = snprintf(*s, sizeof *s, "%0*lld", width, val); break; + } return *s; nl_strcat: fmt = __nl_langinfo_l(item, loc); @@ -210,18 +214,18 @@ string: nl_strftime: fmt = __nl_langinfo_l(item, loc); recu_strftime: - *l = __strftime_l(*s, sizeof *s, fmt, tm, loc); + *l = __strftime_impl(*s, sizeof *s, fmt, tm, loc, pad); if (!*l) return 0; return *s; } -size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const struct tm *restrict tm, locale_t loc) +static size_t __strftime_impl(char *restrict s, size_t n, const char *restrict f, const struct tm *restrict tm, locale_t loc, int def_pad) { size_t l, k; char buf[100]; char *p; const char *t; - int plus; + int plus, pad; unsigned long width; for (l=0; l<n; f++) { if (!*f) { @@ -233,6 +237,8 @@ size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const st continue; } f++; + pad = def_pad; + if (*f == '-' || *f == '_' || *f == '0') pad = *f++; if ((plus = (*f == '+'))) f++; width = strtoul(f, &p, 10); if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') { @@ -242,7 +248,7 @@ size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const st } f = p; if (*f == 'E' || *f == 'O') f++; - t = __strftime_fmt_1(&buf, &k, *f, tm, loc); + t = __strftime_fmt_1(&buf, &k, *f, tm, loc, pad); if (!t) break; if (width) { for (; *t=='+' || *t=='-' || (*t=='0'&&t[1]); t++, k--); @@ -267,6 +273,11 @@ size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const st return 0; } +size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const struct tm *restrict tm, locale_t loc) +{ + return __strftime_impl(s, n, f, tm, loc, '0'); +} + size_t strftime(char *restrict s, size_t n, const char *restrict f, const struct tm *restrict tm) { return __strftime_l(s, n, f, tm, CURRENT_LOCALE); -- 2.11.0
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.