aboutsummaryrefslogtreecommitdiffstats
path: root/main/musl/1000-implement-strftime-GNU-extension-padding-specifiers-.patch
blob: d943d5bef5ecb54afe5ad13c559b4a1b1b22051d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
From 07285bbc354fa2882b01b01ccec439f3a986e966 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
Date: Tue, 22 Nov 2016 09:17:46 +0200
Subject: [PATCH] implement strftime GNU extension padding specifiers '_', '-'
 and '0'

---
 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.13.0