1#include "libc.h"
2#include "locale_impl.h"
3#include <locale.h>
4#include <time.h>
5#include <wchar.h>
6
7const char* __strftime_fmt_1(char (*s)[100], size_t* l, int f, const struct tm* tm, locale_t loc);
8
9size_t __wcsftime_l(wchar_t* restrict s, size_t n, const wchar_t* restrict f,
10                    const struct tm* restrict tm, locale_t loc) {
11    size_t l, k;
12    char buf[100];
13    wchar_t wbuf[100];
14    wchar_t* p;
15    const char* t_mb;
16    const wchar_t* t;
17    int plus;
18    unsigned long width;
19    for (l = 0; l < n; f++) {
20        if (!*f) {
21            s[l] = 0;
22            return l;
23        }
24        if (*f != '%') {
25            s[l++] = *f;
26            continue;
27        }
28        f++;
29        if ((plus = (*f == '+')))
30            f++;
31        width = wcstoul(f, &p, 10);
32        if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') {
33            if (!width && p != f)
34                width = 1;
35        } else {
36            width = 0;
37        }
38        f = p;
39        if (*f == 'E' || *f == 'O')
40            f++;
41        t_mb = __strftime_fmt_1(&buf, &k, *f, tm, loc);
42        if (!t_mb)
43            break;
44        k = mbstowcs(wbuf, t_mb, sizeof wbuf / sizeof *wbuf);
45        if (k == (size_t)-1)
46            return 0;
47        t = wbuf;
48        if (width) {
49            for (; *t == '+' || *t == '-' || (*t == '0' && t[1]); t++, k--)
50                ;
51            width--;
52            if (plus && tm->tm_year >= 10000 - 1900)
53                s[l++] = '+';
54            else if (tm->tm_year < -1900)
55                s[l++] = '-';
56            else
57                width++;
58            for (; width > k && l < n; width--)
59                s[l++] = '0';
60        }
61        if (k >= n - l)
62            k = n - l;
63        wmemcpy(s + l, t, k);
64        l += k;
65    }
66    if (n) {
67        if (l == n)
68            l = n - 1;
69        s[l] = 0;
70    }
71    return 0;
72}
73
74size_t wcsftime(wchar_t* restrict wcs, size_t n, const wchar_t* restrict f,
75                const struct tm* restrict tm) {
76    return __wcsftime_l(wcs, n, f, tm, CURRENT_LOCALE);
77}
78
79weak_alias(__wcsftime_l, wcsftime_l);
80