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
|