strptime.c revision 1.1 1 1.1 mrg /* $NetBSD: strptime.c,v 1.1 1997/04/23 01:18:06 mrg Exp $ */
2 1.1 mrg
3 1.1 mrg /*
4 1.1 mrg * Copyright (c) 1994 Powerdog Industries. All rights reserved.
5 1.1 mrg *
6 1.1 mrg * Redistribution and use in source and binary forms, without
7 1.1 mrg * modification, are permitted provided that the following conditions
8 1.1 mrg * are met:
9 1.1 mrg * 1. Redistributions of source code must retain the above copyright
10 1.1 mrg * notice, this list of conditions and the following disclaimer.
11 1.1 mrg * 2. Redistributions in binary form must reproduce the above copyright
12 1.1 mrg * notice, this list of conditions and the following disclaimer
13 1.1 mrg * in the documentation and/or other materials provided with the
14 1.1 mrg * distribution.
15 1.1 mrg * 3. All advertising materials mentioning features or use of this
16 1.1 mrg * software must display the following acknowledgement:
17 1.1 mrg * This product includes software developed by Powerdog Industries.
18 1.1 mrg * 4. The name of Powerdog Industries may not be used to endorse or
19 1.1 mrg * promote products derived from this software without specific prior
20 1.1 mrg * written permission.
21 1.1 mrg *
22 1.1 mrg * THIS SOFTWARE IS PROVIDED BY POWERDOG INDUSTRIES ``AS IS'' AND ANY
23 1.1 mrg * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 1.1 mrg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 1.1 mrg * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE POWERDOG INDUSTRIES BE
26 1.1 mrg * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 1.1 mrg * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 1.1 mrg * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29 1.1 mrg * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 1.1 mrg * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31 1.1 mrg * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
32 1.1 mrg * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 1.1 mrg */
34 1.1 mrg
35 1.1 mrg #ifndef lint
36 1.1 mrg #if 0
37 1.1 mrg static char copyright[] =
38 1.1 mrg "@(#) Copyright (c) 1994 Powerdog Industries. All rights reserved.";
39 1.1 mrg static char sccsid[] = "@(#)strptime.c 0.1 (Powerdog) 94/03/27";
40 1.1 mrg #else
41 1.1 mrg static char rcsid[] = "$NetBSD: strptime.c,v 1.1 1997/04/23 01:18:06 mrg Exp $";
42 1.1 mrg #endif
43 1.1 mrg #endif /* not lint */
44 1.1 mrg
45 1.1 mrg #include <sys/localedef.h>
46 1.1 mrg #include <locale.h>
47 1.1 mrg #include <time.h>
48 1.1 mrg #include <ctype.h>
49 1.1 mrg #include <string.h>
50 1.1 mrg
51 1.1 mrg char *
52 1.1 mrg strptime(const char *buf, const char *fmt, struct tm *tm)
53 1.1 mrg {
54 1.1 mrg const char *ptr;
55 1.1 mrg char c;
56 1.1 mrg int i, len;
57 1.1 mrg
58 1.1 mrg ptr = fmt;
59 1.1 mrg while (*ptr != 0) {
60 1.1 mrg if (*buf == 0)
61 1.1 mrg break;
62 1.1 mrg
63 1.1 mrg c = *ptr++;
64 1.1 mrg
65 1.1 mrg if (c != '%') {
66 1.1 mrg if (isspace(c))
67 1.1 mrg while (*buf != 0 && isspace(*buf))
68 1.1 mrg buf++;
69 1.1 mrg else if (c != *buf++)
70 1.1 mrg return 0;
71 1.1 mrg continue;
72 1.1 mrg }
73 1.1 mrg
74 1.1 mrg c = *ptr++;
75 1.1 mrg switch (c) {
76 1.1 mrg case 0:
77 1.1 mrg case '%':
78 1.1 mrg if (*buf++ != '%')
79 1.1 mrg return 0;
80 1.1 mrg break;
81 1.1 mrg
82 1.1 mrg case 'c':
83 1.1 mrg buf = strptime(buf, _CurrentTimeLocale->d_t_fmt, tm);
84 1.1 mrg if (buf == 0)
85 1.1 mrg return 0;
86 1.1 mrg break;
87 1.1 mrg
88 1.1 mrg case 'D':
89 1.1 mrg buf = strptime(buf, "%m/%d/%y", tm);
90 1.1 mrg if (buf == 0)
91 1.1 mrg return 0;
92 1.1 mrg break;
93 1.1 mrg
94 1.1 mrg case 'R':
95 1.1 mrg buf = strptime(buf, "%H:%M", tm);
96 1.1 mrg if (buf == 0)
97 1.1 mrg return 0;
98 1.1 mrg break;
99 1.1 mrg
100 1.1 mrg case 'r':
101 1.1 mrg buf = strptime(buf, _CurrentTimeLocale->t_fmt_ampm,tm);
102 1.1 mrg if (buf == 0)
103 1.1 mrg return 0;
104 1.1 mrg break;
105 1.1 mrg
106 1.1 mrg case 'T':
107 1.1 mrg buf = strptime(buf, "%H:%M:%S", tm);
108 1.1 mrg if (buf == 0)
109 1.1 mrg return 0;
110 1.1 mrg break;
111 1.1 mrg
112 1.1 mrg case 'X':
113 1.1 mrg buf = strptime(buf, _CurrentTimeLocale->t_fmt, tm);
114 1.1 mrg if (buf == 0)
115 1.1 mrg return 0;
116 1.1 mrg break;
117 1.1 mrg
118 1.1 mrg case 'x':
119 1.1 mrg buf = strptime(buf, _CurrentTimeLocale->d_fmt, tm);
120 1.1 mrg if (buf == 0)
121 1.1 mrg return 0;
122 1.1 mrg break;
123 1.1 mrg
124 1.1 mrg case 'j':
125 1.1 mrg if (!isdigit(*buf))
126 1.1 mrg return 0;
127 1.1 mrg
128 1.1 mrg for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
129 1.1 mrg i *= 10;
130 1.1 mrg i += *buf - '0';
131 1.1 mrg }
132 1.1 mrg if (i > 366)
133 1.1 mrg return 0;
134 1.1 mrg
135 1.1 mrg tm->tm_yday = i;
136 1.1 mrg break;
137 1.1 mrg
138 1.1 mrg case 'M':
139 1.1 mrg case 'S':
140 1.1 mrg if (*buf == 0 || isspace(*buf))
141 1.1 mrg break;
142 1.1 mrg
143 1.1 mrg if (!isdigit(*buf))
144 1.1 mrg return 0;
145 1.1 mrg
146 1.1 mrg for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
147 1.1 mrg i *= 10;
148 1.1 mrg i += *buf - '0';
149 1.1 mrg }
150 1.1 mrg if (i > 59)
151 1.1 mrg return 0;
152 1.1 mrg
153 1.1 mrg if (c == 'M')
154 1.1 mrg tm->tm_min = i;
155 1.1 mrg else
156 1.1 mrg tm->tm_sec = i;
157 1.1 mrg
158 1.1 mrg if (*buf != 0 && isspace(*buf))
159 1.1 mrg while (*ptr != 0 && !isspace(*ptr))
160 1.1 mrg ptr++;
161 1.1 mrg break;
162 1.1 mrg
163 1.1 mrg case 'H':
164 1.1 mrg case 'I':
165 1.1 mrg case 'k':
166 1.1 mrg case 'l':
167 1.1 mrg if (!isdigit(*buf))
168 1.1 mrg return 0;
169 1.1 mrg
170 1.1 mrg for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
171 1.1 mrg i *= 10;
172 1.1 mrg i += *buf - '0';
173 1.1 mrg }
174 1.1 mrg if (c == 'H' || c == 'k') {
175 1.1 mrg if (i > 23)
176 1.1 mrg return 0;
177 1.1 mrg } else if (i > 11)
178 1.1 mrg return 0;
179 1.1 mrg
180 1.1 mrg tm->tm_hour = i;
181 1.1 mrg
182 1.1 mrg if (*buf != 0 && isspace(*buf))
183 1.1 mrg while (*ptr != 0 && !isspace(*ptr))
184 1.1 mrg ptr++;
185 1.1 mrg break;
186 1.1 mrg
187 1.1 mrg case 'p':
188 1.1 mrg len = strlen(_CurrentTimeLocale->am_pm[0]);
189 1.1 mrg if (strncasecmp(buf, _CurrentTimeLocale->am_pm[0],
190 1.1 mrg len) == 0) {
191 1.1 mrg if (tm->tm_hour > 12)
192 1.1 mrg return 0;
193 1.1 mrg if (tm->tm_hour == 12)
194 1.1 mrg tm->tm_hour = 0;
195 1.1 mrg buf += len;
196 1.1 mrg break;
197 1.1 mrg }
198 1.1 mrg
199 1.1 mrg len = strlen(_CurrentTimeLocale->am_pm[1]);
200 1.1 mrg if (strncasecmp(buf, _CurrentTimeLocale->am_pm[1],
201 1.1 mrg len) == 0) {
202 1.1 mrg if (tm->tm_hour > 12)
203 1.1 mrg return 0;
204 1.1 mrg if (tm->tm_hour != 12)
205 1.1 mrg tm->tm_hour += 12;
206 1.1 mrg buf += len;
207 1.1 mrg break;
208 1.1 mrg }
209 1.1 mrg
210 1.1 mrg return 0;
211 1.1 mrg
212 1.1 mrg case 'A':
213 1.1 mrg case 'a':
214 1.1 mrg for (i = 0; i < 7; i++) {
215 1.1 mrg len = strlen(_CurrentTimeLocale->day[i]);
216 1.1 mrg if (strncasecmp(buf,
217 1.1 mrg _CurrentTimeLocale->day[i],
218 1.1 mrg len) == 0)
219 1.1 mrg break;
220 1.1 mrg
221 1.1 mrg len = strlen(_CurrentTimeLocale->abday[i]);
222 1.1 mrg if (strncasecmp(buf,
223 1.1 mrg _CurrentTimeLocale->abday[i],
224 1.1 mrg len) == 0)
225 1.1 mrg break;
226 1.1 mrg }
227 1.1 mrg if (i == 7)
228 1.1 mrg return 0;
229 1.1 mrg
230 1.1 mrg tm->tm_wday = i;
231 1.1 mrg buf += len;
232 1.1 mrg break;
233 1.1 mrg
234 1.1 mrg case 'd':
235 1.1 mrg case 'e':
236 1.1 mrg if (!isdigit(*buf))
237 1.1 mrg return 0;
238 1.1 mrg
239 1.1 mrg for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
240 1.1 mrg i *= 10;
241 1.1 mrg i += *buf - '0';
242 1.1 mrg }
243 1.1 mrg if (i > 31)
244 1.1 mrg return 0;
245 1.1 mrg
246 1.1 mrg tm->tm_mday = i;
247 1.1 mrg
248 1.1 mrg if (*buf != 0 && isspace(*buf))
249 1.1 mrg while (*ptr != 0 && !isspace(*ptr))
250 1.1 mrg ptr++;
251 1.1 mrg break;
252 1.1 mrg
253 1.1 mrg case 'B':
254 1.1 mrg case 'b':
255 1.1 mrg case 'h':
256 1.1 mrg for (i = 0; i < 12; i++) {
257 1.1 mrg len = strlen(_CurrentTimeLocale->mon[i]);
258 1.1 mrg if (strncasecmp(buf,
259 1.1 mrg _CurrentTimeLocale->mon[i],
260 1.1 mrg len) == 0)
261 1.1 mrg break;
262 1.1 mrg
263 1.1 mrg len = strlen(_CurrentTimeLocale->abmon[i]);
264 1.1 mrg if (strncasecmp(buf,
265 1.1 mrg _CurrentTimeLocale->abmon[i],
266 1.1 mrg len) == 0)
267 1.1 mrg break;
268 1.1 mrg }
269 1.1 mrg if (i == 12)
270 1.1 mrg return 0;
271 1.1 mrg
272 1.1 mrg tm->tm_mon = i;
273 1.1 mrg buf += len;
274 1.1 mrg break;
275 1.1 mrg
276 1.1 mrg case 'm':
277 1.1 mrg if (!isdigit(*buf))
278 1.1 mrg return 0;
279 1.1 mrg
280 1.1 mrg for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
281 1.1 mrg i *= 10;
282 1.1 mrg i += *buf - '0';
283 1.1 mrg }
284 1.1 mrg if (i < 1 || i > 12)
285 1.1 mrg return 0;
286 1.1 mrg
287 1.1 mrg tm->tm_mon = i - 1;
288 1.1 mrg
289 1.1 mrg if (*buf != 0 && isspace(*buf))
290 1.1 mrg while (*ptr != 0 && !isspace(*ptr))
291 1.1 mrg ptr++;
292 1.1 mrg break;
293 1.1 mrg
294 1.1 mrg case 'Y':
295 1.1 mrg case 'y':
296 1.1 mrg if (*buf == 0 || isspace(*buf))
297 1.1 mrg break;
298 1.1 mrg
299 1.1 mrg if (!isdigit(*buf))
300 1.1 mrg return 0;
301 1.1 mrg
302 1.1 mrg for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
303 1.1 mrg i *= 10;
304 1.1 mrg i += *buf - '0';
305 1.1 mrg }
306 1.1 mrg if (c == 'Y')
307 1.1 mrg i -= 1900;
308 1.1 mrg if (i < 0)
309 1.1 mrg return 0;
310 1.1 mrg
311 1.1 mrg tm->tm_year = i;
312 1.1 mrg
313 1.1 mrg if (*buf != 0 && isspace(*buf))
314 1.1 mrg while (*ptr != 0 && !isspace(*ptr))
315 1.1 mrg ptr++;
316 1.1 mrg break;
317 1.1 mrg }
318 1.1 mrg }
319 1.1 mrg
320 1.1 mrg return (char *) buf;
321 1.1 mrg }
322 1.1 mrg
323 1.1 mrg
324