]> git.saurik.com Git - apple/libc.git/blob - stdtime/FreeBSD/strptime.c.patch
Libc-391.4.1.tar.gz
[apple/libc.git] / stdtime / FreeBSD / strptime.c.patch
1 --- strptime.c.orig 2004-11-25 11:38:45.000000000 -0800
2 +++ strptime.c 2005-02-24 01:09:32.000000000 -0800
3 @@ -61,6 +61,8 @@
4 #endif /* not lint */
5 __FBSDID("$FreeBSD: src/lib/libc/stdtime/strptime.c,v 1.35 2003/11/17 04:19:15 nectar Exp $");
6
7 +#include "xlocale_private.h"
8 +
9 #include "namespace.h"
10 #include <time.h>
11 #include <ctype.h>
12 @@ -72,19 +74,19 @@
13 #include "libc_private.h"
14 #include "timelocal.h"
15
16 -static char * _strptime(const char *, const char *, struct tm *, int *);
17 +static char * _strptime(const char *, const char *, struct tm *, int *, locale_t);
18
19 #define asizeof(a) (sizeof (a) / sizeof ((a)[0]))
20
21 static char *
22 -_strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp)
23 +_strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp, locale_t loc)
24 {
25 char c;
26 const char *ptr;
27 int i,
28 len;
29 int Ealternative, Oalternative;
30 - struct lc_time_T *tptr = __get_current_time_locale();
31 + struct lc_time_T *tptr = __get_current_time_locale(loc);
32
33 ptr = fmt;
34 while (*ptr != 0) {
35 @@ -94,8 +96,8 @@
36 c = *ptr++;
37
38 if (c != '%') {
39 - if (isspace((unsigned char)c))
40 - while (*buf != 0 && isspace((unsigned char)*buf))
41 + if (isspace_l((unsigned char)c, loc))
42 + while (*buf != 0 && isspace_l((unsigned char)*buf, loc))
43 buf++;
44 else if (c != *buf++)
45 return 0;
46 @@ -114,18 +116,18 @@
47 break;
48
49 case '+':
50 - buf = _strptime(buf, tptr->date_fmt, tm, GMTp);
51 + buf = _strptime(buf, tptr->date_fmt, tm, GMTp, loc);
52 if (buf == 0)
53 return 0;
54 break;
55
56 case 'C':
57 - if (!isdigit((unsigned char)*buf))
58 + if (!isdigit_l((unsigned char)*buf, loc))
59 return 0;
60
61 /* XXX This will break for 3-digit centuries. */
62 len = 2;
63 - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
64 + for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) {
65 i *= 10;
66 i += *buf - '0';
67 len--;
68 @@ -137,13 +139,13 @@
69 break;
70
71 case 'c':
72 - buf = _strptime(buf, tptr->c_fmt, tm, GMTp);
73 + buf = _strptime(buf, tptr->c_fmt, tm, GMTp, loc);
74 if (buf == 0)
75 return 0;
76 break;
77
78 case 'D':
79 - buf = _strptime(buf, "%m/%d/%y", tm, GMTp);
80 + buf = _strptime(buf, "%m/%d/%y", tm, GMTp, loc);
81 if (buf == 0)
82 return 0;
83 break;
84 @@ -161,47 +163,47 @@
85 goto label;
86
87 case 'F':
88 - buf = _strptime(buf, "%Y-%m-%d", tm, GMTp);
89 + buf = _strptime(buf, "%Y-%m-%d", tm, GMTp, loc);
90 if (buf == 0)
91 return 0;
92 break;
93
94 case 'R':
95 - buf = _strptime(buf, "%H:%M", tm, GMTp);
96 + buf = _strptime(buf, "%H:%M", tm, GMTp, loc);
97 if (buf == 0)
98 return 0;
99 break;
100
101 case 'r':
102 - buf = _strptime(buf, tptr->ampm_fmt, tm, GMTp);
103 + buf = _strptime(buf, tptr->ampm_fmt, tm, GMTp, loc);
104 if (buf == 0)
105 return 0;
106 break;
107
108 case 'T':
109 - buf = _strptime(buf, "%H:%M:%S", tm, GMTp);
110 + buf = _strptime(buf, "%H:%M:%S", tm, GMTp, loc);
111 if (buf == 0)
112 return 0;
113 break;
114
115 case 'X':
116 - buf = _strptime(buf, tptr->X_fmt, tm, GMTp);
117 + buf = _strptime(buf, tptr->X_fmt, tm, GMTp, loc);
118 if (buf == 0)
119 return 0;
120 break;
121
122 case 'x':
123 - buf = _strptime(buf, tptr->x_fmt, tm, GMTp);
124 + buf = _strptime(buf, tptr->x_fmt, tm, GMTp, loc);
125 if (buf == 0)
126 return 0;
127 break;
128
129 case 'j':
130 - if (!isdigit((unsigned char)*buf))
131 + if (!isdigit_l((unsigned char)*buf, loc))
132 return 0;
133
134 len = 3;
135 - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
136 + for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) {
137 i *= 10;
138 i += *buf - '0';
139 len--;
140 @@ -214,14 +216,14 @@
141
142 case 'M':
143 case 'S':
144 - if (*buf == 0 || isspace((unsigned char)*buf))
145 + if (*buf == 0 || isspace_l((unsigned char)*buf, loc))
146 break;
147
148 - if (!isdigit((unsigned char)*buf))
149 + if (!isdigit_l((unsigned char)*buf, loc))
150 return 0;
151
152 len = 2;
153 - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
154 + for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) {
155 i *= 10;
156 i += *buf - '0';
157 len--;
158 @@ -237,8 +239,8 @@
159 tm->tm_sec = i;
160 }
161
162 - if (*buf != 0 && isspace((unsigned char)*buf))
163 - while (*ptr != 0 && !isspace((unsigned char)*ptr))
164 + if (*buf != 0 && isspace_l((unsigned char)*buf, loc))
165 + while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc))
166 ptr++;
167 break;
168
169 @@ -254,11 +256,11 @@
170 * XXX The %l specifier may gobble one too many
171 * digits if used incorrectly.
172 */
173 - if (!isdigit((unsigned char)*buf))
174 + if (!isdigit_l((unsigned char)*buf, loc))
175 return 0;
176
177 len = 2;
178 - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
179 + for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) {
180 i *= 10;
181 i += *buf - '0';
182 len--;
183 @@ -271,8 +273,8 @@
184
185 tm->tm_hour = i;
186
187 - if (*buf != 0 && isspace((unsigned char)*buf))
188 - while (*ptr != 0 && !isspace((unsigned char)*ptr))
189 + if (*buf != 0 && isspace_l((unsigned char)*buf, loc))
190 + while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc))
191 ptr++;
192 break;
193
194 @@ -282,7 +284,7 @@
195 * specifiers.
196 */
197 len = strlen(tptr->am);
198 - if (strncasecmp(buf, tptr->am, len) == 0) {
199 + if (strncasecmp_l(buf, tptr->am, len, loc) == 0) {
200 if (tm->tm_hour > 12)
201 return 0;
202 if (tm->tm_hour == 12)
203 @@ -292,7 +294,7 @@
204 }
205
206 len = strlen(tptr->pm);
207 - if (strncasecmp(buf, tptr->pm, len) == 0) {
208 + if (strncasecmp_l(buf, tptr->pm, len, loc) == 0) {
209 if (tm->tm_hour > 12)
210 return 0;
211 if (tm->tm_hour != 12)
212 @@ -307,12 +309,12 @@
213 case 'a':
214 for (i = 0; i < asizeof(tptr->weekday); i++) {
215 len = strlen(tptr->weekday[i]);
216 - if (strncasecmp(buf, tptr->weekday[i],
217 - len) == 0)
218 + if (strncasecmp_l(buf, tptr->weekday[i],
219 + len, loc) == 0)
220 break;
221 len = strlen(tptr->wday[i]);
222 - if (strncasecmp(buf, tptr->wday[i],
223 - len) == 0)
224 + if (strncasecmp_l(buf, tptr->wday[i],
225 + len, loc) == 0)
226 break;
227 }
228 if (i == asizeof(tptr->weekday))
229 @@ -330,11 +332,11 @@
230 * point to calculate a real value, so just check the
231 * range for now.
232 */
233 - if (!isdigit((unsigned char)*buf))
234 + if (!isdigit_l((unsigned char)*buf, loc))
235 return 0;
236
237 len = 2;
238 - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
239 + for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) {
240 i *= 10;
241 i += *buf - '0';
242 len--;
243 @@ -342,13 +344,13 @@
244 if (i > 53)
245 return 0;
246
247 - if (*buf != 0 && isspace((unsigned char)*buf))
248 - while (*ptr != 0 && !isspace((unsigned char)*ptr))
249 + if (*buf != 0 && isspace_l((unsigned char)*buf, loc))
250 + while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc))
251 ptr++;
252 break;
253
254 case 'w':
255 - if (!isdigit((unsigned char)*buf))
256 + if (!isdigit_l((unsigned char)*buf, loc))
257 return 0;
258
259 i = *buf - '0';
260 @@ -357,8 +359,8 @@
261
262 tm->tm_wday = i;
263
264 - if (*buf != 0 && isspace((unsigned char)*buf))
265 - while (*ptr != 0 && !isspace((unsigned char)*ptr))
266 + if (*buf != 0 && isspace_l((unsigned char)*buf, loc))
267 + while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc))
268 ptr++;
269 break;
270
271 @@ -372,11 +374,11 @@
272 * XXX The %e specifier may gobble one too many
273 * digits if used incorrectly.
274 */
275 - if (!isdigit((unsigned char)*buf))
276 + if (!isdigit_l((unsigned char)*buf, loc))
277 return 0;
278
279 len = 2;
280 - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
281 + for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) {
282 i *= 10;
283 i += *buf - '0';
284 len--;
285 @@ -386,8 +388,8 @@
286
287 tm->tm_mday = i;
288
289 - if (*buf != 0 && isspace((unsigned char)*buf))
290 - while (*ptr != 0 && !isspace((unsigned char)*ptr))
291 + if (*buf != 0 && isspace_l((unsigned char)*buf, loc))
292 + while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc))
293 ptr++;
294 break;
295
296 @@ -398,19 +400,19 @@
297 if (Oalternative) {
298 if (c == 'B') {
299 len = strlen(tptr->alt_month[i]);
300 - if (strncasecmp(buf,
301 + if (strncasecmp_l(buf,
302 tptr->alt_month[i],
303 - len) == 0)
304 + len, loc) == 0)
305 break;
306 }
307 } else {
308 len = strlen(tptr->month[i]);
309 - if (strncasecmp(buf, tptr->month[i],
310 - len) == 0)
311 + if (strncasecmp_l(buf, tptr->month[i],
312 + len, loc) == 0)
313 break;
314 len = strlen(tptr->mon[i]);
315 - if (strncasecmp(buf, tptr->mon[i],
316 - len) == 0)
317 + if (strncasecmp_l(buf, tptr->mon[i],
318 + len, loc) == 0)
319 break;
320 }
321 }
322 @@ -422,11 +424,11 @@
323 break;
324
325 case 'm':
326 - if (!isdigit((unsigned char)*buf))
327 + if (!isdigit_l((unsigned char)*buf, loc))
328 return 0;
329
330 len = 2;
331 - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
332 + for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) {
333 i *= 10;
334 i += *buf - '0';
335 len--;
336 @@ -436,8 +438,8 @@
337
338 tm->tm_mon = i - 1;
339
340 - if (*buf != 0 && isspace((unsigned char)*buf))
341 - while (*ptr != 0 && !isspace((unsigned char)*ptr))
342 + if (*buf != 0 && isspace_l((unsigned char)*buf, loc))
343 + while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc))
344 ptr++;
345 break;
346
347 @@ -450,7 +452,7 @@
348
349 sverrno = errno;
350 errno = 0;
351 - n = strtol(buf, &cp, 10);
352 + n = strtol_l(buf, &cp, 10, loc);
353 if (errno == ERANGE || (long)(t = n) != n) {
354 errno = sverrno;
355 return 0;
356 @@ -464,14 +466,14 @@
357
358 case 'Y':
359 case 'y':
360 - if (*buf == 0 || isspace((unsigned char)*buf))
361 + if (*buf == 0 || isspace_l((unsigned char)*buf, loc))
362 break;
363
364 - if (!isdigit((unsigned char)*buf))
365 + if (!isdigit_l((unsigned char)*buf, loc))
366 return 0;
367
368 len = (c == 'Y') ? 4 : 2;
369 - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
370 + for (i = 0; len && *buf != 0 && isdigit_l((unsigned char)*buf, loc); buf++) {
371 i *= 10;
372 i += *buf - '0';
373 len--;
374 @@ -485,8 +487,8 @@
375
376 tm->tm_year = i;
377
378 - if (*buf != 0 && isspace((unsigned char)*buf))
379 - while (*ptr != 0 && !isspace((unsigned char)*ptr))
380 + if (*buf != 0 && isspace_l((unsigned char)*buf, loc))
381 + while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc))
382 ptr++;
383 break;
384
385 @@ -495,7 +497,7 @@
386 const char *cp;
387 char *zonestr;
388
389 - for (cp = buf; *cp && isupper((unsigned char)*cp); ++cp) {/*empty*/}
390 + for (cp = buf; *cp && isupper_l((unsigned char)*cp, loc); ++cp) {/*empty*/}
391 if (cp - buf) {
392 zonestr = alloca(cp - buf + 1);
393 strncpy(zonestr, buf, cp - buf);
394 @@ -528,7 +530,25 @@
395 int gmt;
396
397 gmt = 0;
398 - ret = _strptime(buf, fmt, tm, &gmt);
399 + ret = _strptime(buf, fmt, tm, &gmt, __current_locale());
400 + if (ret && gmt) {
401 + time_t t = timegm(tm);
402 + localtime_r(&t, tm);
403 + }
404 +
405 + return (ret);
406 +}
407 +
408 +char *
409 +strptime_l(const char * __restrict buf, const char * __restrict fmt,
410 + struct tm * __restrict tm, locale_t loc)
411 +{
412 + char *ret;
413 + int gmt;
414 +
415 + NORMALIZE_LOCALE(loc);
416 + gmt = 0;
417 + ret = _strptime(buf, fmt, tm, &gmt, loc);
418 if (ret && gmt) {
419 time_t t = timegm(tm);
420 localtime_r(&t, tm);