Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4973 | right-hear | 1 | /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ |
2 | #include |
||
3 | #include |
||
4 | |||
5 | #define TM_YEAR_BASE 1900 |
||
6 | |||
7 | static const char *afmt[] = { |
||
8 | "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", |
||
9 | }; |
||
10 | static const char *Afmt[] = { |
||
11 | "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", |
||
12 | "Saturday", |
||
13 | }; |
||
14 | static const char *bfmt[] = { |
||
15 | "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", |
||
16 | "Oct", "Nov", "Dec", |
||
17 | }; |
||
18 | static const char *Bfmt[] = { |
||
19 | "January", "February", "March", "April", "May", "June", "July", |
||
20 | "August", "September", "October", "November", "December", |
||
21 | }; |
||
22 | |||
23 | static size_t gsize; |
||
24 | static char *pt; |
||
25 | |||
26 | static int |
||
27 | _add(const char *str) |
||
28 | { |
||
29 | for (;; ++pt, --gsize) |
||
30 | { |
||
31 | if (!gsize) |
||
32 | return 0; |
||
33 | if (!(*pt = *str++)) |
||
34 | return 1; |
||
35 | } |
||
36 | } |
||
37 | |||
38 | static int |
||
39 | _conv(int n, int digits, char pad) |
||
40 | { |
||
41 | static char buf[10]; |
||
42 | char *p; |
||
43 | |||
44 | for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits) |
||
45 | *p-- = n % 10 + '0'; |
||
46 | while (p > buf && digits-- > 0) |
||
47 | *p-- = pad; |
||
48 | return _add(++p); |
||
49 | } |
||
50 | |||
51 | static size_t |
||
52 | _fmt(const char *format, const struct tm *t) |
||
53 | { |
||
54 | for (; *format; ++format) |
||
55 | { |
||
56 | if (*format == '%') |
||
57 | switch(*++format) |
||
58 | { |
||
59 | case '\0': |
||
60 | --format; |
||
61 | break; |
||
62 | case 'A': |
||
63 | if (t->tm_wday < 0 || t->tm_wday > 6) |
||
64 | return 0; |
||
65 | if (!_add(Afmt[t->tm_wday])) |
||
66 | return 0; |
||
67 | continue; |
||
68 | case 'a': |
||
69 | if (t->tm_wday < 0 || t->tm_wday > 6) |
||
70 | return 0; |
||
71 | if (!_add(afmt[t->tm_wday])) |
||
72 | return 0; |
||
73 | continue; |
||
74 | case 'B': |
||
75 | if (t->tm_mon < 0 || t->tm_mon > 11) |
||
76 | return 0; |
||
77 | if (!_add(Bfmt[t->tm_mon])) |
||
78 | return 0; |
||
79 | continue; |
||
80 | case 'b': |
||
81 | case 'h': |
||
82 | if (t->tm_mon < 0 || t->tm_mon > 11) |
||
83 | return 0; |
||
84 | if (!_add(bfmt[t->tm_mon])) |
||
85 | return 0; |
||
86 | continue; |
||
87 | case 'C': |
||
88 | if (!_fmt("%a %b %e %H:%M:%S %Y", t)) |
||
89 | return 0; |
||
90 | continue; |
||
91 | case 'c': |
||
92 | if (!_fmt("%m/%d/%y %H:%M:%S", t)) |
||
93 | return 0; |
||
94 | continue; |
||
95 | case 'e': |
||
96 | if (!_conv(t->tm_mday, 2, ' ')) |
||
97 | return 0; |
||
98 | continue; |
||
99 | case 'D': |
||
100 | if (!_fmt("%m/%d/%y", t)) |
||
101 | return 0; |
||
102 | continue; |
||
103 | case 'd': |
||
104 | if (!_conv(t->tm_mday, 2, '0')) |
||
105 | return 0; |
||
106 | continue; |
||
107 | case 'H': |
||
108 | if (!_conv(t->tm_hour, 2, '0')) |
||
109 | return 0; |
||
110 | continue; |
||
111 | case 'I': |
||
112 | if (!_conv(t->tm_hour % 12 ? |
||
113 | t->tm_hour % 12 : 12, 2, '0')) |
||
114 | return 0; |
||
115 | continue; |
||
116 | case 'j': |
||
117 | if (!_conv(t->tm_yday + 1, 3, '0')) |
||
118 | return 0; |
||
119 | continue; |
||
120 | case 'k': |
||
121 | if (!_conv(t->tm_hour, 2, ' ')) |
||
122 | return 0; |
||
123 | continue; |
||
124 | case 'l': |
||
125 | if (!_conv(t->tm_hour % 12 ? |
||
126 | t->tm_hour % 12 : 12, 2, ' ')) |
||
127 | return 0; |
||
128 | continue; |
||
129 | case 'M': |
||
130 | if (!_conv(t->tm_min, 2, '0')) |
||
131 | return 0; |
||
132 | continue; |
||
133 | case 'm': |
||
134 | if (!_conv(t->tm_mon + 1, 2, '0')) |
||
135 | return 0; |
||
136 | continue; |
||
137 | case 'n': |
||
138 | if (!_add("\n")) |
||
139 | return 0; |
||
140 | continue; |
||
141 | case 'p': |
||
142 | if (!_add(t->tm_hour >= 12 ? "PM" : "AM")) |
||
143 | return 0; |
||
144 | continue; |
||
145 | case 'R': |
||
146 | if (!_fmt("%H:%M", t)) |
||
147 | return 0; |
||
148 | continue; |
||
149 | case 'r': |
||
150 | if (!_fmt("%I:%M:%S %p", t)) |
||
151 | return 0; |
||
152 | continue; |
||
153 | case 'S': |
||
154 | if (!_conv(t->tm_sec, 2, '0')) |
||
155 | return 0; |
||
156 | continue; |
||
157 | case 'T': |
||
158 | case 'X': |
||
159 | if (!_fmt("%H:%M:%S", t)) |
||
160 | return 0; |
||
161 | continue; |
||
162 | case 't': |
||
163 | if (!_add("\t")) |
||
164 | return 0; |
||
165 | continue; |
||
166 | case 'U': |
||
167 | if (!_conv((t->tm_yday + 7 - t->tm_wday) / 7, |
||
168 | 2, '0')) |
||
169 | return 0; |
||
170 | continue; |
||
171 | case 'W': |
||
172 | if (!_conv((t->tm_yday + 7 - |
||
173 | (t->tm_wday ? (t->tm_wday - 1) : 6)) |
||
174 | / 7, 2, '0')) |
||
175 | return 0; |
||
176 | continue; |
||
177 | case 'w': |
||
178 | if (!_conv(t->tm_wday, 1, '0')) |
||
179 | return 0; |
||
180 | continue; |
||
181 | case 'x': |
||
182 | if (!_fmt("%m/%d/%y", t)) |
||
183 | return 0; |
||
184 | continue; |
||
185 | case 'y': |
||
186 | if (!_conv((t->tm_year + TM_YEAR_BASE) |
||
187 | % 100, 2, '0')) |
||
188 | return 0; |
||
189 | continue; |
||
190 | case 'Y': |
||
191 | if (!_conv(t->tm_year + TM_YEAR_BASE, 4, '0')) |
||
192 | return 0; |
||
193 | continue; |
||
194 | case 'Z': |
||
195 | if (!t->tm_zone || !_add(t->tm_zone)) |
||
196 | return 0; |
||
197 | continue; |
||
198 | case '%': |
||
199 | /* |
||
200 | * X311J/88-090 (4.12.3.5): if conversion char is |
||
201 | * undefined, behavior is undefined. Print out the |
||
202 | * character itself as printf(3) does. |
||
203 | */ |
||
204 | default: |
||
205 | break; |
||
206 | } |
||
207 | if (!gsize--) |
||
208 | return 0; |
||
209 | *pt++ = *format; |
||
210 | } |
||
211 | return gsize; |
||
212 | } |
||
213 | |||
214 | size_t |
||
215 | strftime(char *s, size_t maxsize, const char *format, const struct tm *t) |
||
216 | { |
||
217 | pt = s; |
||
218 | if ((gsize = maxsize) < 1) |
||
219 | return 0; |
||
220 | if (_fmt(format, t)) |
||
221 | { |
||
222 | *pt = '\0'; |
||
223 | return maxsize - gsize; |
||
224 | } |
||
225 | return 0; |
||
226 | }>>>>> |