Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
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.