strptime.c revision 1.2 1 1.2 kleink /* $NetBSD: strptime.c,v 1.2 1997/05/06 13:06:48 kleink 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.2 kleink static char rcsid[] = "$NetBSD: strptime.c,v 1.2 1997/05/06 13:06:48 kleink 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.2 kleink char *
52 1.2 kleink strptime(buf, fmt, tm)
53 1.2 kleink const char *buf, *fmt;
54 1.2 kleink struct tm *tm;
55 1.1 mrg {
56 1.1 mrg const char *ptr;
57 1.2 kleink char c;
58 1.2 kleink int i, len;
59 1.1 mrg
60 1.2 kleink ptr = fmt;
61 1.2 kleink while (*ptr != 0) {
62 1.2 kleink if (*buf == 0)
63 1.2 kleink break;
64 1.2 kleink
65 1.2 kleink c = *ptr++;
66 1.2 kleink
67 1.2 kleink if (c != '%') {
68 1.2 kleink if (isspace(c))
69 1.2 kleink while (*buf != 0 && isspace(*buf))
70 1.2 kleink buf++;
71 1.2 kleink else if (c != *buf++)
72 1.2 kleink return (NULL);
73 1.2 kleink continue;
74 1.2 kleink }
75 1.2 kleink
76 1.2 kleink c = *ptr++;
77 1.2 kleink switch (c) {
78 1.2 kleink case 0:
79 1.2 kleink case '%':
80 1.2 kleink if (*buf++ != '%')
81 1.2 kleink return (NULL);
82 1.2 kleink break;
83 1.2 kleink
84 1.2 kleink case 'c':
85 1.2 kleink buf = strptime(buf, _CurrentTimeLocale->d_t_fmt, tm);
86 1.2 kleink if (buf == 0)
87 1.2 kleink return (NULL);
88 1.2 kleink break;
89 1.2 kleink
90 1.2 kleink case 'D':
91 1.2 kleink buf = strptime(buf, "%m/%d/%y", tm);
92 1.2 kleink if (buf == 0)
93 1.2 kleink return (NULL);
94 1.2 kleink break;
95 1.2 kleink
96 1.2 kleink case 'R':
97 1.2 kleink buf = strptime(buf, "%H:%M", tm);
98 1.2 kleink if (buf == 0)
99 1.2 kleink return (NULL);
100 1.2 kleink break;
101 1.2 kleink
102 1.2 kleink case 'r':
103 1.2 kleink buf = strptime(buf, _CurrentTimeLocale->t_fmt_ampm,tm);
104 1.2 kleink if (buf == 0)
105 1.2 kleink return (NULL);
106 1.2 kleink break;
107 1.2 kleink
108 1.2 kleink case 'T':
109 1.2 kleink buf = strptime(buf, "%H:%M:%S", tm);
110 1.2 kleink if (buf == 0)
111 1.2 kleink return (NULL);
112 1.2 kleink break;
113 1.2 kleink
114 1.2 kleink case 'X':
115 1.2 kleink buf = strptime(buf, _CurrentTimeLocale->t_fmt, tm);
116 1.2 kleink if (buf == 0)
117 1.2 kleink return (NULL);
118 1.2 kleink break;
119 1.2 kleink
120 1.2 kleink case 'x':
121 1.2 kleink buf = strptime(buf, _CurrentTimeLocale->d_fmt, tm);
122 1.2 kleink if (buf == 0)
123 1.2 kleink return (NULL);
124 1.2 kleink break;
125 1.2 kleink
126 1.2 kleink case 'j':
127 1.2 kleink if (!isdigit(*buf))
128 1.2 kleink return (NULL);
129 1.2 kleink
130 1.2 kleink for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
131 1.2 kleink i *= 10;
132 1.2 kleink i += *buf - '0';
133 1.2 kleink }
134 1.2 kleink if (i > 366)
135 1.2 kleink return (NULL);
136 1.2 kleink
137 1.2 kleink tm->tm_yday = i;
138 1.2 kleink break;
139 1.2 kleink
140 1.2 kleink case 'M':
141 1.2 kleink case 'S':
142 1.2 kleink if (*buf == 0 || isspace(*buf))
143 1.2 kleink break;
144 1.2 kleink
145 1.2 kleink if (!isdigit(*buf))
146 1.2 kleink return (NULL);
147 1.2 kleink
148 1.2 kleink for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
149 1.2 kleink i *= 10;
150 1.2 kleink i += *buf - '0';
151 1.2 kleink }
152 1.2 kleink if (i > 59)
153 1.2 kleink return (NULL);
154 1.2 kleink
155 1.2 kleink if (c == 'M')
156 1.2 kleink tm->tm_min = i;
157 1.2 kleink else
158 1.2 kleink tm->tm_sec = i;
159 1.2 kleink
160 1.2 kleink if (*buf != 0 && isspace(*buf))
161 1.2 kleink while (*ptr != 0 && !isspace(*ptr))
162 1.2 kleink ptr++;
163 1.2 kleink break;
164 1.2 kleink
165 1.2 kleink case 'H':
166 1.2 kleink case 'I':
167 1.2 kleink case 'k':
168 1.2 kleink case 'l':
169 1.2 kleink if (!isdigit(*buf))
170 1.2 kleink return (NULL);
171 1.2 kleink
172 1.2 kleink for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
173 1.2 kleink i *= 10;
174 1.2 kleink i += *buf - '0';
175 1.2 kleink }
176 1.2 kleink if (c == 'H' || c == 'k') {
177 1.2 kleink if (i > 23)
178 1.2 kleink return (NULL);
179 1.2 kleink } else if (i > 11)
180 1.2 kleink return (NULL);
181 1.2 kleink
182 1.2 kleink tm->tm_hour = i;
183 1.2 kleink
184 1.2 kleink if (*buf != 0 && isspace(*buf))
185 1.2 kleink while (*ptr != 0 && !isspace(*ptr))
186 1.2 kleink ptr++;
187 1.2 kleink break;
188 1.2 kleink
189 1.2 kleink case 'p':
190 1.2 kleink len = strlen(_CurrentTimeLocale->am_pm[0]);
191 1.2 kleink if (strncasecmp(buf, _CurrentTimeLocale->am_pm[0],
192 1.2 kleink len) == 0) {
193 1.2 kleink if (tm->tm_hour > 12)
194 1.2 kleink return (NULL);
195 1.2 kleink if (tm->tm_hour == 12)
196 1.2 kleink tm->tm_hour = 0;
197 1.2 kleink buf += len;
198 1.2 kleink break;
199 1.2 kleink }
200 1.2 kleink
201 1.2 kleink len = strlen(_CurrentTimeLocale->am_pm[1]);
202 1.2 kleink if (strncasecmp(buf, _CurrentTimeLocale->am_pm[1],
203 1.2 kleink len) == 0) {
204 1.2 kleink if (tm->tm_hour > 12)
205 1.2 kleink return (NULL);
206 1.2 kleink if (tm->tm_hour != 12)
207 1.2 kleink tm->tm_hour += 12;
208 1.2 kleink buf += len;
209 1.2 kleink break;
210 1.2 kleink }
211 1.2 kleink
212 1.2 kleink return (NULL);
213 1.2 kleink
214 1.2 kleink case 'A':
215 1.2 kleink case 'a':
216 1.2 kleink for (i = 0; i < 7; i++) {
217 1.2 kleink len = strlen(_CurrentTimeLocale->day[i]);
218 1.2 kleink if (strncasecmp(buf,
219 1.2 kleink _CurrentTimeLocale->day[i],
220 1.2 kleink len) == 0)
221 1.1 mrg break;
222 1.1 mrg
223 1.2 kleink len = strlen(_CurrentTimeLocale->abday[i]);
224 1.2 kleink if (strncasecmp(buf,
225 1.2 kleink _CurrentTimeLocale->abday[i],
226 1.2 kleink len) == 0)
227 1.1 mrg break;
228 1.2 kleink }
229 1.2 kleink if (i == 7)
230 1.2 kleink return (NULL);
231 1.2 kleink
232 1.2 kleink tm->tm_wday = i;
233 1.2 kleink buf += len;
234 1.2 kleink break;
235 1.2 kleink
236 1.2 kleink case 'd':
237 1.2 kleink case 'e':
238 1.2 kleink if (!isdigit(*buf))
239 1.2 kleink return (NULL);
240 1.2 kleink
241 1.2 kleink for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
242 1.2 kleink i *= 10;
243 1.2 kleink i += *buf - '0';
244 1.2 kleink }
245 1.2 kleink if (i > 31)
246 1.2 kleink return (NULL);
247 1.2 kleink
248 1.2 kleink tm->tm_mday = i;
249 1.2 kleink
250 1.2 kleink if (*buf != 0 && isspace(*buf))
251 1.2 kleink while (*ptr != 0 && !isspace(*ptr))
252 1.2 kleink ptr++;
253 1.2 kleink break;
254 1.2 kleink
255 1.2 kleink case 'B':
256 1.2 kleink case 'b':
257 1.2 kleink case 'h':
258 1.2 kleink for (i = 0; i < 12; i++) {
259 1.1 mrg len = strlen(_CurrentTimeLocale->mon[i]);
260 1.2 kleink if (strncasecmp(buf,
261 1.2 kleink _CurrentTimeLocale->mon[i],
262 1.2 kleink len) == 0)
263 1.2 kleink break;
264 1.1 mrg
265 1.1 mrg len = strlen(_CurrentTimeLocale->abmon[i]);
266 1.2 kleink if (strncasecmp(buf,
267 1.2 kleink _CurrentTimeLocale->abmon[i],
268 1.2 kleink len) == 0)
269 1.2 kleink break;
270 1.2 kleink }
271 1.2 kleink if (i == 12)
272 1.2 kleink return (NULL);
273 1.2 kleink
274 1.2 kleink tm->tm_mon = i;
275 1.2 kleink buf += len;
276 1.2 kleink break;
277 1.2 kleink
278 1.2 kleink case 'm':
279 1.2 kleink if (!isdigit(*buf))
280 1.2 kleink return (NULL);
281 1.2 kleink
282 1.2 kleink for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
283 1.2 kleink i *= 10;
284 1.2 kleink i += *buf - '0';
285 1.2 kleink }
286 1.2 kleink if (i < 1 || i > 12)
287 1.2 kleink return (NULL);
288 1.2 kleink
289 1.2 kleink tm->tm_mon = i - 1;
290 1.2 kleink
291 1.2 kleink if (*buf != 0 && isspace(*buf))
292 1.2 kleink while (*ptr != 0 && !isspace(*ptr))
293 1.2 kleink ptr++;
294 1.2 kleink break;
295 1.2 kleink
296 1.2 kleink case 'Y':
297 1.2 kleink case 'y':
298 1.2 kleink if (*buf == 0 || isspace(*buf))
299 1.2 kleink break;
300 1.2 kleink
301 1.2 kleink if (!isdigit(*buf))
302 1.2 kleink return (NULL);
303 1.2 kleink
304 1.2 kleink for (i = 0; *buf != 0 && isdigit(*buf); buf++) {
305 1.2 kleink i *= 10;
306 1.2 kleink i += *buf - '0';
307 1.2 kleink }
308 1.2 kleink if (c == 'Y')
309 1.2 kleink i -= 1900;
310 1.2 kleink if (i < 0)
311 1.2 kleink return (NULL);
312 1.2 kleink
313 1.2 kleink tm->tm_year = i;
314 1.2 kleink
315 1.2 kleink if (*buf != 0 && isspace(*buf))
316 1.2 kleink while (*ptr != 0 && !isspace(*ptr))
317 1.2 kleink ptr++;
318 1.2 kleink break;
319 1.2 kleink }
320 1.2 kleink }
321 1.1 mrg
322 1.2 kleink return ((char *)buf);
323 1.1 mrg }
324