]>
Commit | Line | Data |
---|---|---|
1f2f436a A |
1 | --- strftime.c.orig 2010-06-24 01:11:42.000000000 -0700 |
2 | +++ strftime.c 2010-06-24 11:29:51.000000000 -0700 | |
3 | @@ -25,6 +25,8 @@ static const char elsieid[] = "@(#)strft | |
3d9156a7 A |
4 | #endif /* !defined NOID */ |
5 | #endif /* !defined lint */ | |
6 | ||
7 | +#include "xlocale_private.h" | |
8 | + | |
9 | #include "namespace.h" | |
10 | #include "private.h" | |
11 | ||
1f2f436a A |
12 | @@ -35,18 +37,25 @@ static const char sccsid[] = "@(#)strfti |
13 | __FBSDID("$FreeBSD: src/lib/libc/stdtime/strftime.c,v 1.44 2009/06/09 09:02:58 delphij Exp $"); | |
3d9156a7 A |
14 | |
15 | #include "tzfile.h" | |
16 | +#include <time.h> | |
17 | #include <fcntl.h> | |
18 | #include <sys/stat.h> | |
19 | #include "un-namespace.h" | |
20 | #include "timelocal.h" | |
21 | ||
22 | +#if !BUILDING_VARIANT | |
23 | static char * _add(const char *, char *, const char *); | |
24 | -static char * _conv(int, const char *, char *, const char *); | |
1f2f436a A |
25 | -static char * _fmt(const char *, const struct tm *, char *, const char *, |
26 | - int *); | |
27 | -static char * _yconv(int, int, int, int, char *, const char *); | |
3d9156a7 | 28 | +static char * _conv(int, const char *, char *, const char *, locale_t); |
1f2f436a A |
29 | +static char * _yconv(int, int, int, int, char *, const char *, locale_t); |
30 | +#endif | |
3d9156a7 | 31 | +#define _fmt _st_fmt |
1f2f436a A |
32 | +__private_extern__ char * _fmt(const char *, const struct tm *, char *, const char *, |
33 | + int *, struct lc_time_T *, locale_t); | |
3d9156a7 A |
34 | |
35 | extern char * tzname[]; | |
36 | +__private_extern__ long __darwin_altzone; /* DST timezone offset */ | |
37 | +#define altzone __darwin_altzone | |
38 | +__private_extern__ long _st_get_timezone(void); | |
39 | ||
40 | #ifndef YEAR_2000_NAME | |
41 | #define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS" | |
1f2f436a A |
42 | @@ -62,6 +71,7 @@ extern char * tzname[]; |
43 | #define PAD_SPACE 2 | |
44 | #define PAD_ZERO 3 | |
45 | ||
46 | +#ifndef BUILDING_VARIANT | |
47 | static const char* fmt_padding[][4] = { | |
48 | /* DEFAULT, LESS, SPACE, ZERO */ | |
49 | #define PAD_FMT_MONTHDAY 0 | |
50 | @@ -80,31 +90,36 @@ static const char* fmt_padding[][4] = { | |
51 | #define PAD_FMT_YEAR 3 | |
52 | { "%04d", "%d", "%4d", "%04d" } | |
53 | }; | |
54 | +#endif | |
55 | + | |
56 | +#define USG_COMPAT | |
57 | +#define ALTZONE | |
3d9156a7 A |
58 | |
59 | size_t | |
60 | -strftime(char * __restrict s, size_t maxsize, const char * __restrict format, | |
61 | - const struct tm * __restrict t) | |
62 | +strftime_l(char * __restrict s, size_t maxsize, const char * __restrict format, | |
63 | + const struct tm * __restrict t, locale_t loc) | |
64 | { | |
65 | char * p; | |
66 | int warn; | |
3d9156a7 A |
67 | |
68 | + NORMALIZE_LOCALE(loc); | |
69 | tzset(); | |
70 | warn = IN_NONE; | |
71 | - p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn); | |
3d9156a7 A |
72 | + p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn, __get_current_time_locale(loc), loc); |
73 | #ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU | |
74 | if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) { | |
75 | - (void) fprintf(stderr, "\n"); | |
76 | + (void) fputs("\n", stderr); | |
77 | if (format == NULL) | |
78 | - (void) fprintf(stderr, "NULL strftime format "); | |
79 | - else (void) fprintf(stderr, "strftime format \"%s\" ", | |
80 | + (void) fputs("NULL strftime format ", stderr); | |
81 | + else (void) fprintf_l(stderr, loc, "strftime format \"%s\" ", | |
82 | format); | |
83 | - (void) fprintf(stderr, "yields only two digits of years in "); | |
84 | + (void) fputs("yields only two digits of years in ", stderr); | |
85 | if (warn == IN_SOME) | |
86 | - (void) fprintf(stderr, "some locales"); | |
87 | + (void) fputs("some locales", stderr); | |
88 | else if (warn == IN_THIS) | |
89 | - (void) fprintf(stderr, "the current locale"); | |
90 | - else (void) fprintf(stderr, "all locales"); | |
91 | - (void) fprintf(stderr, "\n"); | |
92 | + (void) fputs("the current locale", stderr); | |
93 | + else (void) fputs("all locales", stderr); | |
94 | + (void) fputs("\n", stderr); | |
95 | } | |
96 | #endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */ | |
97 | if (p == s + maxsize) | |
1f2f436a | 98 | @@ -113,16 +128,25 @@ strftime(char * __restrict s, size_t max |
3d9156a7 A |
99 | return p - s; |
100 | } | |
101 | ||
102 | -static char * | |
103 | -_fmt(format, t, pt, ptlim, warnp) | |
104 | +size_t | |
105 | +strftime(char * __restrict s, size_t maxsize, const char * __restrict format, | |
106 | + const struct tm * __restrict t) | |
107 | +{ | |
108 | + return strftime_l(s, maxsize, format, t, __current_locale()); | |
109 | +} | |
110 | + | |
111 | +#ifndef BUILDING_VARIANT | |
112 | +__private_extern__ char * | |
113 | +_fmt(format, t, pt, ptlim, warnp, tptr, loc) | |
114 | const char * format; | |
115 | const struct tm * const t; | |
116 | char * pt; | |
117 | const char * const ptlim; | |
118 | int * warnp; | |
119 | +struct lc_time_T * tptr; | |
120 | +locale_t loc; | |
121 | { | |
1f2f436a | 122 | int Ealternative, Oalternative, PadIndex; |
3d9156a7 A |
123 | - struct lc_time_T *tptr = __get_current_time_locale(); |
124 | ||
125 | for ( ; *format; ++format) { | |
126 | if (*format == '%') { | |
1f2f436a A |
127 | @@ -163,19 +187,19 @@ label: |
128 | case 'C': | |
129 | /* | |
130 | ** %C used to do a... | |
131 | - ** _fmt("%a %b %e %X %Y", t); | |
132 | + ** _fmt("%a %b %e %X %Y", t, tptr, loc); | |
133 | ** ...whereas now POSIX 1003.2 calls for | |
134 | ** something completely different. | |
3d9156a7 A |
135 | ** (ado, 1993-05-24) |
136 | */ | |
1f2f436a A |
137 | pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0, |
138 | - pt, ptlim); | |
139 | + pt, ptlim, loc); | |
3d9156a7 A |
140 | continue; |
141 | case 'c': | |
142 | { | |
143 | int warn2 = IN_SOME; | |
144 | ||
1f2f436a A |
145 | - pt = _fmt(tptr->c_fmt, t, pt, ptlim, &warn2); |
146 | + pt = _fmt(tptr->c_fmt, t, pt, ptlim, &warn2, tptr, loc); | |
3d9156a7 A |
147 | if (warn2 == IN_ALL) |
148 | warn2 = IN_THIS; | |
149 | if (warn2 > *warnp) | |
1f2f436a | 150 | @@ -183,11 +207,11 @@ label: |
3d9156a7 A |
151 | } |
152 | continue; | |
153 | case 'D': | |
154 | - pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp); | |
155 | + pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp, tptr, loc); | |
156 | continue; | |
157 | case 'd': | |
1f2f436a A |
158 | pt = _conv(t->tm_mday, fmt_padding[PAD_FMT_DAYOFMONTH][PadIndex], |
159 | - pt, ptlim); | |
160 | + pt, ptlim, loc); | |
3d9156a7 A |
161 | continue; |
162 | case 'E': | |
163 | if (Ealternative || Oalternative) | |
1f2f436a | 164 | @@ -213,29 +237,29 @@ label: |
3d9156a7 A |
165 | goto label; |
166 | case 'e': | |
1f2f436a A |
167 | pt = _conv(t->tm_mday, |
168 | - fmt_padding[PAD_FMT_SDAYOFMONTH][PadIndex], pt, ptlim); | |
169 | + fmt_padding[PAD_FMT_SDAYOFMONTH][PadIndex], pt, ptlim, loc); | |
3d9156a7 A |
170 | continue; |
171 | case 'F': | |
172 | - pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp); | |
173 | + pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp, tptr, loc); | |
174 | continue; | |
175 | case 'H': | |
1f2f436a A |
176 | pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_HMS][PadIndex], |
177 | - pt, ptlim); | |
178 | + pt, ptlim, loc); | |
3d9156a7 A |
179 | continue; |
180 | case 'I': | |
181 | pt = _conv((t->tm_hour % 12) ? | |
182 | (t->tm_hour % 12) : 12, | |
1f2f436a A |
183 | - fmt_padding[PAD_FMT_HMS][PadIndex], pt, ptlim); |
184 | + fmt_padding[PAD_FMT_HMS][PadIndex], pt, ptlim, loc); | |
3d9156a7 A |
185 | continue; |
186 | case 'j': | |
1f2f436a A |
187 | pt = _conv(t->tm_yday + 1, |
188 | - fmt_padding[PAD_FMT_DAYOFYEAR][PadIndex], pt, ptlim); | |
189 | + fmt_padding[PAD_FMT_DAYOFYEAR][PadIndex], pt, ptlim, loc); | |
3d9156a7 A |
190 | continue; |
191 | case 'k': | |
192 | /* | |
1f2f436a A |
193 | ** This used to be... |
194 | ** _conv(t->tm_hour % 12 ? | |
195 | - ** t->tm_hour % 12 : 12, 2, ' '); | |
196 | + ** t->tm_hour % 12 : 12, 2, ' ', loc); | |
197 | ** ...and has been changed to the below to | |
198 | ** match SunOS 4.1.1 and Arnold Robbins' | |
199 | ** strftime version 3.0. That is, "%k" and | |
200 | @@ -243,7 +267,7 @@ label: | |
3d9156a7 A |
201 | ** (ado, 1993-05-24) |
202 | */ | |
1f2f436a A |
203 | pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_SHMS][PadIndex], |
204 | - pt, ptlim); | |
205 | + pt, ptlim, loc); | |
3d9156a7 A |
206 | continue; |
207 | #ifdef KITCHEN_SINK | |
208 | case 'K': | |
1f2f436a | 209 | @@ -265,15 +289,15 @@ label: |
3d9156a7 A |
210 | */ |
211 | pt = _conv((t->tm_hour % 12) ? | |
212 | (t->tm_hour % 12) : 12, | |
1f2f436a A |
213 | - fmt_padding[PAD_FMT_SHMS][PadIndex], pt, ptlim); |
214 | + fmt_padding[PAD_FMT_SHMS][PadIndex], pt, ptlim, loc); | |
3d9156a7 A |
215 | continue; |
216 | case 'M': | |
1f2f436a A |
217 | pt = _conv(t->tm_min, fmt_padding[PAD_FMT_HMS][PadIndex], |
218 | - pt, ptlim); | |
219 | + pt, ptlim, loc); | |
3d9156a7 A |
220 | continue; |
221 | case 'm': | |
1f2f436a A |
222 | pt = _conv(t->tm_mon + 1, |
223 | - fmt_padding[PAD_FMT_MONTH][PadIndex], pt, ptlim); | |
224 | + fmt_padding[PAD_FMT_MONTH][PadIndex], pt, ptlim, loc); | |
3d9156a7 A |
225 | continue; |
226 | case 'n': | |
227 | pt = _add("\n", pt, ptlim); | |
1f2f436a | 228 | @@ -285,15 +309,15 @@ label: |
3d9156a7 A |
229 | pt, ptlim); |
230 | continue; | |
231 | case 'R': | |
232 | - pt = _fmt("%H:%M", t, pt, ptlim, warnp); | |
233 | + pt = _fmt("%H:%M", t, pt, ptlim, warnp, tptr, loc); | |
234 | continue; | |
235 | case 'r': | |
236 | pt = _fmt(tptr->ampm_fmt, t, pt, ptlim, | |
237 | - warnp); | |
238 | + warnp, tptr, loc); | |
239 | continue; | |
240 | case 'S': | |
1f2f436a A |
241 | pt = _conv(t->tm_sec, fmt_padding[PAD_FMT_HMS][PadIndex], |
242 | - pt, ptlim); | |
243 | + pt, ptlim, loc); | |
3d9156a7 A |
244 | continue; |
245 | case 's': | |
246 | { | |
1f2f436a | 247 | @@ -305,15 +329,15 @@ label: |
3d9156a7 A |
248 | tm = *t; |
249 | mkt = mktime(&tm); | |
250 | if (TYPE_SIGNED(time_t)) | |
251 | - (void) sprintf(buf, "%ld", | |
252 | + (void) sprintf_l(buf, loc, "%ld", | |
253 | (long) mkt); | |
254 | - else (void) sprintf(buf, "%lu", | |
255 | + else (void) sprintf_l(buf, loc, "%lu", | |
256 | (unsigned long) mkt); | |
257 | pt = _add(buf, pt, ptlim); | |
258 | } | |
259 | continue; | |
260 | case 'T': | |
261 | - pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp); | |
262 | + pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp, tptr, loc); | |
263 | continue; | |
264 | case 't': | |
265 | pt = _add("\t", pt, ptlim); | |
1f2f436a | 266 | @@ -321,7 +345,7 @@ label: |
3d9156a7 A |
267 | case 'U': |
268 | pt = _conv((t->tm_yday + DAYSPERWEEK - | |
269 | t->tm_wday) / DAYSPERWEEK, | |
1f2f436a A |
270 | - fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim); |
271 | + fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim, loc); | |
3d9156a7 A |
272 | continue; |
273 | case 'u': | |
274 | /* | |
1f2f436a | 275 | @@ -332,7 +356,7 @@ label: |
3d9156a7 A |
276 | */ |
277 | pt = _conv((t->tm_wday == 0) ? | |
278 | DAYSPERWEEK : t->tm_wday, | |
279 | - "%d", pt, ptlim); | |
280 | + "%d", pt, ptlim, loc); | |
281 | continue; | |
282 | case 'V': /* ISO 8601 week number */ | |
283 | case 'G': /* ISO 8601 year (four digits) */ | |
1f2f436a | 284 | @@ -413,13 +437,13 @@ label: |
3d9156a7 A |
285 | #endif /* defined XPG4_1994_04_09 */ |
286 | if (*format == 'V') | |
1f2f436a | 287 | pt = _conv(w, fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], |
3d9156a7 A |
288 | - pt, ptlim); |
289 | + pt, ptlim, loc); | |
290 | else if (*format == 'g') { | |
291 | *warnp = IN_ALL; | |
1f2f436a | 292 | pt = _yconv(year, base, 0, 1, |
3d9156a7 A |
293 | - pt, ptlim); |
294 | + pt, ptlim, loc); | |
1f2f436a | 295 | } else pt = _yconv(year, base, 1, 1, |
3d9156a7 A |
296 | - pt, ptlim); |
297 | + pt, ptlim, loc); | |
298 | } | |
299 | continue; | |
300 | case 'v': | |
1f2f436a | 301 | @@ -428,26 +452,26 @@ label: |
3d9156a7 A |
302 | ** "date as dd-bbb-YYYY" |
303 | ** (ado, 1993-05-24) | |
304 | */ | |
305 | - pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp); | |
306 | + pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp, tptr, loc); | |
307 | continue; | |
308 | case 'W': | |
309 | pt = _conv((t->tm_yday + DAYSPERWEEK - | |
310 | (t->tm_wday ? | |
311 | (t->tm_wday - 1) : | |
312 | (DAYSPERWEEK - 1))) / DAYSPERWEEK, | |
1f2f436a A |
313 | - fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim); |
314 | + fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim, loc); | |
3d9156a7 A |
315 | continue; |
316 | case 'w': | |
317 | - pt = _conv(t->tm_wday, "%d", pt, ptlim); | |
318 | + pt = _conv(t->tm_wday, "%d", pt, ptlim, loc); | |
319 | continue; | |
320 | case 'X': | |
321 | - pt = _fmt(tptr->X_fmt, t, pt, ptlim, warnp); | |
322 | + pt = _fmt(tptr->X_fmt, t, pt, ptlim, warnp, tptr, loc); | |
323 | continue; | |
324 | case 'x': | |
325 | { | |
326 | int warn2 = IN_SOME; | |
327 | ||
328 | - pt = _fmt(tptr->x_fmt, t, pt, ptlim, &warn2); | |
329 | + pt = _fmt(tptr->x_fmt, t, pt, ptlim, &warn2, tptr, loc); | |
330 | if (warn2 == IN_ALL) | |
331 | warn2 = IN_THIS; | |
332 | if (warn2 > *warnp) | |
1f2f436a | 333 | @@ -457,11 +481,11 @@ label: |
3d9156a7 A |
334 | case 'y': |
335 | *warnp = IN_ALL; | |
1f2f436a A |
336 | pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1, |
337 | - pt, ptlim); | |
338 | + pt, ptlim, loc); | |
3d9156a7 A |
339 | continue; |
340 | case 'Y': | |
1f2f436a | 341 | pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1, |
3d9156a7 A |
342 | - pt, ptlim); |
343 | + pt, ptlim, loc); | |
344 | continue; | |
345 | case 'Z': | |
346 | #ifdef TM_ZONE | |
1f2f436a A |
347 | @@ -485,9 +509,9 @@ label: |
348 | ||
349 | if (t->tm_isdst < 0) | |
350 | continue; | |
351 | -#ifdef TM_GMTOFF | |
352 | +#if defined(TM_GMTOFF) && !__DARWIN_UNIX03 | |
353 | diff = t->TM_GMTOFF; | |
354 | -#else /* !defined TM_GMTOFF */ | |
355 | +#else /* !defined TM_GMTOFF || __DARWIN_UNIX03 */ | |
356 | /* | |
357 | ** C99 says that the UTC offset must | |
358 | ** be computed by looking only at | |
359 | @@ -509,7 +533,7 @@ label: | |
3d9156a7 A |
360 | */ |
361 | if (t->tm_isdst == 0) | |
362 | #ifdef USG_COMPAT | |
363 | - diff = -timezone; | |
364 | + diff = -_st_get_timezone(); | |
365 | #else /* !defined USG_COMPAT */ | |
366 | continue; | |
367 | #endif /* !defined USG_COMPAT */ | |
1f2f436a A |
368 | @@ -519,7 +543,7 @@ label: |
369 | #else /* !defined ALTZONE */ | |
370 | continue; | |
371 | #endif /* !defined ALTZONE */ | |
372 | -#endif /* !defined TM_GMTOFF */ | |
373 | +#endif /* !defined TM_GMTOFF || __DARWIN_UNIX03 */ | |
374 | if (diff < 0) { | |
375 | sign = "-"; | |
376 | diff = -diff; | |
377 | @@ -529,12 +553,12 @@ label: | |
378 | diff = (diff / MINSPERHOUR) * 100 + | |
379 | (diff % MINSPERHOUR); | |
380 | pt = _conv(diff, | |
381 | - fmt_padding[PAD_FMT_YEAR][PadIndex], pt, ptlim); | |
382 | + fmt_padding[PAD_FMT_YEAR][PadIndex], pt, ptlim, loc); | |
3d9156a7 A |
383 | } |
384 | continue; | |
385 | case '+': | |
386 | pt = _fmt(tptr->date_fmt, t, pt, ptlim, | |
387 | - warnp); | |
388 | + warnp, tptr, loc); | |
389 | continue; | |
1f2f436a A |
390 | case '-': |
391 | if (PadIndex != PAD_DEFAULT) | |
392 | @@ -569,15 +593,16 @@ label: | |
3d9156a7 A |
393 | } |
394 | ||
395 | static char * | |
396 | -_conv(n, format, pt, ptlim) | |
397 | +_conv(n, format, pt, ptlim, loc) | |
398 | const int n; | |
399 | const char * const format; | |
400 | char * const pt; | |
401 | const char * const ptlim; | |
402 | +locale_t loc; | |
403 | { | |
404 | char buf[INT_STRLEN_MAXIMUM(int) + 1]; | |
405 | ||
406 | - (void) sprintf(buf, format, n); | |
407 | + (void) sprintf_l(buf, loc, format, n); | |
408 | return _add(buf, pt, ptlim); | |
409 | } | |
410 | ||
1f2f436a A |
411 | @@ -601,13 +626,14 @@ const char * const ptlim; |
412 | */ | |
413 | ||
414 | static char * | |
415 | -_yconv(a, b, convert_top, convert_yy, pt, ptlim) | |
416 | +_yconv(a, b, convert_top, convert_yy, pt, ptlim, loc) | |
417 | const int a; | |
418 | const int b; | |
419 | const int convert_top; | |
420 | const int convert_yy; | |
421 | char * pt; | |
422 | const char * const ptlim; | |
423 | +locale_t loc; | |
424 | { | |
425 | register int lead; | |
426 | register int trail; | |
427 | @@ -626,9 +652,10 @@ const char * const ptlim; | |
428 | if (convert_top) { | |
429 | if (lead == 0 && trail < 0) | |
430 | pt = _add("-0", pt, ptlim); | |
431 | - else pt = _conv(lead, "%02d", pt, ptlim); | |
432 | + else pt = _conv(lead, "%02d", pt, ptlim, loc); | |
433 | } | |
434 | if (convert_yy) | |
435 | - pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim); | |
436 | + pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim, loc); | |
3d9156a7 A |
437 | return pt; |
438 | } | |
439 | +#endif /* !BUILDING_VARIANT */ |