scoutos / prex-0.9.0 / usr / lib / libc / time / strftime.c @ 03e9c04a
History | View | Annotate | Download (6.44 KB)
1 | 03e9c04a | Brad Neuman | /*
|
---|---|---|---|
2 | * Copyright (c) 1989, 1993
|
||
3 | * The Regents of the University of California. All rights reserved.
|
||
4 | *
|
||
5 | * Redistribution and use in source and binary forms, with or without
|
||
6 | * modification, are permitted provided that the following conditions
|
||
7 | * are met:
|
||
8 | * 1. Redistributions of source code must retain the above copyright
|
||
9 | * notice, this list of conditions and the following disclaimer.
|
||
10 | * 2. Redistributions in binary form must reproduce the above copyright
|
||
11 | * notice, this list of conditions and the following disclaimer in the
|
||
12 | * documentation and/or other materials provided with the distribution.
|
||
13 | * 3. Neither the name of the University nor the names of its contributors
|
||
14 | * may be used to endorse or promote products derived from this software
|
||
15 | * without specific prior written permission.
|
||
16 | *
|
||
17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||
27 | * SUCH DAMAGE.
|
||
28 | */
|
||
29 | |||
30 | #include <sys/types.h> |
||
31 | #include <sys/time.h> |
||
32 | #include <tzfile.h> |
||
33 | #include <string.h> |
||
34 | |||
35 | static const char *afmt[] = { |
||
36 | "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", |
||
37 | }; |
||
38 | static const char *Afmt[] = { |
||
39 | "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", |
||
40 | "Saturday",
|
||
41 | }; |
||
42 | static const char *bfmt[] = { |
||
43 | "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", |
||
44 | "Oct", "Nov", "Dec", |
||
45 | }; |
||
46 | static const char *Bfmt[] = { |
||
47 | "January", "February", "March", "April", "May", "June", "July", |
||
48 | "August", "September", "October", "November", "December", |
||
49 | }; |
||
50 | |||
51 | static size_t gsize;
|
||
52 | static char *pt; |
||
53 | static int _add(const char *); |
||
54 | static int _conv(int, int, int); |
||
55 | static int _secs(const struct tm *); |
||
56 | static size_t _fmt(const char *, const struct tm *); |
||
57 | |||
58 | size_t |
||
59 | strftime(s, maxsize, format, t) |
||
60 | char *s;
|
||
61 | size_t maxsize; |
||
62 | const char *format; |
||
63 | const struct tm *t; |
||
64 | { |
||
65 | |||
66 | pt = s; |
||
67 | if ((gsize = maxsize) < 1) |
||
68 | return(0); |
||
69 | if (_fmt(format, t)) {
|
||
70 | *pt = '\0';
|
||
71 | return(maxsize - gsize);
|
||
72 | } |
||
73 | return(0); |
||
74 | } |
||
75 | |||
76 | static size_t
|
||
77 | _fmt(format, t) |
||
78 | const char *format; |
||
79 | const struct tm *t; |
||
80 | { |
||
81 | for (; *format; ++format) {
|
||
82 | if (*format == '%') |
||
83 | switch(*++format) {
|
||
84 | case '\0': |
||
85 | --format; |
||
86 | break;
|
||
87 | case 'A': |
||
88 | if (t->tm_wday < 0 || t->tm_wday > 6) |
||
89 | return(0); |
||
90 | if (!_add(Afmt[t->tm_wday]))
|
||
91 | return(0); |
||
92 | continue;
|
||
93 | case 'a': |
||
94 | if (t->tm_wday < 0 || t->tm_wday > 6) |
||
95 | return(0); |
||
96 | if (!_add(afmt[t->tm_wday]))
|
||
97 | return(0); |
||
98 | continue;
|
||
99 | case 'B': |
||
100 | if (t->tm_mon < 0 || t->tm_mon > 11) |
||
101 | return(0); |
||
102 | if (!_add(Bfmt[t->tm_mon]))
|
||
103 | return(0); |
||
104 | continue;
|
||
105 | case 'b': |
||
106 | case 'h': |
||
107 | if (t->tm_mon < 0 || t->tm_mon > 11) |
||
108 | return(0); |
||
109 | if (!_add(bfmt[t->tm_mon]))
|
||
110 | return(0); |
||
111 | continue;
|
||
112 | case 'C': |
||
113 | if (!_fmt("%a %b %e %H:%M:%S %Y", t)) |
||
114 | return(0); |
||
115 | continue;
|
||
116 | case 'c': |
||
117 | if (!_fmt("%m/%d/%y %H:%M:%S", t)) |
||
118 | return(0); |
||
119 | continue;
|
||
120 | case 'D': |
||
121 | if (!_fmt("%m/%d/%y", t)) |
||
122 | return(0); |
||
123 | continue;
|
||
124 | case 'd': |
||
125 | if (!_conv(t->tm_mday, 2, '0')) |
||
126 | return(0); |
||
127 | continue;
|
||
128 | case 'e': |
||
129 | if (!_conv(t->tm_mday, 2, ' ')) |
||
130 | return(0); |
||
131 | continue;
|
||
132 | case 'H': |
||
133 | if (!_conv(t->tm_hour, 2, '0')) |
||
134 | return(0); |
||
135 | continue;
|
||
136 | case 'I': |
||
137 | if (!_conv(t->tm_hour % 12 ? |
||
138 | t->tm_hour % 12 : 12, 2, '0')) |
||
139 | return(0); |
||
140 | continue;
|
||
141 | case 'j': |
||
142 | if (!_conv(t->tm_yday + 1, 3, '0')) |
||
143 | return(0); |
||
144 | continue;
|
||
145 | case 'k': |
||
146 | if (!_conv(t->tm_hour, 2, ' ')) |
||
147 | return(0); |
||
148 | continue;
|
||
149 | case 'l': |
||
150 | if (!_conv(t->tm_hour % 12 ? |
||
151 | t->tm_hour % 12 : 12, 2, ' ')) |
||
152 | return(0); |
||
153 | continue;
|
||
154 | case 'M': |
||
155 | if (!_conv(t->tm_min, 2, '0')) |
||
156 | return(0); |
||
157 | continue;
|
||
158 | case 'm': |
||
159 | if (!_conv(t->tm_mon + 1, 2, '0')) |
||
160 | return(0); |
||
161 | continue;
|
||
162 | case 'n': |
||
163 | if (!_add("\n")) |
||
164 | return(0); |
||
165 | continue;
|
||
166 | case 'p': |
||
167 | if (!_add(t->tm_hour >= 12 ? "PM" : "AM")) |
||
168 | return(0); |
||
169 | continue;
|
||
170 | case 'R': |
||
171 | if (!_fmt("%H:%M", t)) |
||
172 | return(0); |
||
173 | continue;
|
||
174 | case 'r': |
||
175 | if (!_fmt("%I:%M:%S %p", t)) |
||
176 | return(0); |
||
177 | continue;
|
||
178 | case 'S': |
||
179 | if (!_conv(t->tm_sec, 2, '0')) |
||
180 | return(0); |
||
181 | continue;
|
||
182 | case 's': |
||
183 | if (!_secs(t))
|
||
184 | return(0); |
||
185 | continue;
|
||
186 | case 'T': |
||
187 | case 'X': |
||
188 | if (!_fmt("%H:%M:%S", t)) |
||
189 | return(0); |
||
190 | continue;
|
||
191 | case 't': |
||
192 | if (!_add("\t")) |
||
193 | return(0); |
||
194 | continue;
|
||
195 | case 'U': |
||
196 | if (!_conv((t->tm_yday + 7 - t->tm_wday) / 7, |
||
197 | 2, '0')) |
||
198 | return(0); |
||
199 | continue;
|
||
200 | case 'W': |
||
201 | if (!_conv((t->tm_yday + 7 - |
||
202 | (t->tm_wday ? (t->tm_wday - 1) : 6)) |
||
203 | / 7, 2, '0')) |
||
204 | return(0); |
||
205 | continue;
|
||
206 | case 'w': |
||
207 | if (!_conv(t->tm_wday, 1, '0')) |
||
208 | return(0); |
||
209 | continue;
|
||
210 | case 'x': |
||
211 | if (!_fmt("%m/%d/%y", t)) |
||
212 | return(0); |
||
213 | continue;
|
||
214 | case 'y': |
||
215 | if (!_conv((t->tm_year + TM_YEAR_BASE)
|
||
216 | % 100, 2, '0')) |
||
217 | return(0); |
||
218 | continue;
|
||
219 | case 'Y': |
||
220 | if (!_conv(t->tm_year + TM_YEAR_BASE, 4, '0')) |
||
221 | return(0); |
||
222 | continue;
|
||
223 | /*
|
||
224 | case 'Z':
|
||
225 | if (!t->tm_zone || !_add(t->tm_zone))
|
||
226 | return(0);
|
||
227 | continue;
|
||
228 | */
|
||
229 | case '%': |
||
230 | /*
|
||
231 | * X311J/88-090 (4.12.3.5): if conversion char is
|
||
232 | * undefined, behavior is undefined. Print out the
|
||
233 | * character itself as printf(3) does.
|
||
234 | */
|
||
235 | default:
|
||
236 | break;
|
||
237 | } |
||
238 | if (!gsize--)
|
||
239 | return(0); |
||
240 | *pt++ = *format; |
||
241 | } |
||
242 | return(gsize);
|
||
243 | } |
||
244 | |||
245 | static int |
||
246 | _secs(t) |
||
247 | const struct tm *t; |
||
248 | { |
||
249 | static char buf[15]; |
||
250 | time_t s; |
||
251 | char *p;
|
||
252 | struct tm tmp;
|
||
253 | |||
254 | /* Make a copy, mktime(3) modifies the tm struct. */
|
||
255 | tmp = *t; |
||
256 | s = mktime(&tmp); |
||
257 | for (p = buf + sizeof(buf) - 2; s > 0 && p > buf; s /= 10) |
||
258 | *p-- = s % 10 + '0'; |
||
259 | return(_add(++p));
|
||
260 | } |
||
261 | |||
262 | static int |
||
263 | _conv(n, digits, pad) |
||
264 | int n, digits, pad;
|
||
265 | { |
||
266 | static char buf[10]; |
||
267 | char *p;
|
||
268 | |||
269 | for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits) |
||
270 | *p-- = n % 10 + '0'; |
||
271 | while (p > buf && digits-- > 0) |
||
272 | *p-- = pad; |
||
273 | return(_add(++p));
|
||
274 | } |
||
275 | |||
276 | static int |
||
277 | _add(str) |
||
278 | const char *str; |
||
279 | { |
||
280 | for (;; ++pt, --gsize) {
|
||
281 | if (!gsize)
|
||
282 | return(0); |
||
283 | if (!(*pt = *str++))
|
||
284 | return(1); |
||
285 | } |
||
286 | } |