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