]>
Commit | Line | Data |
---|---|---|
3d9156a7 A |
1 | --- strftime.c.orig 2004-11-25 11:38:45.000000000 -0800 |
2 | +++ strftime.c 2005-02-27 16:07:41.000000000 -0800 | |
3 | @@ -25,6 +25,8 @@ | |
4 | #endif /* !defined NOID */ | |
5 | #endif /* !defined lint */ | |
6 | ||
7 | +#include "xlocale_private.h" | |
8 | + | |
9 | #include "namespace.h" | |
10 | #include "private.h" | |
11 | ||
12 | @@ -35,19 +37,26 @@ | |
13 | __FBSDID("$FreeBSD: src/lib/libc/stdtime/strftime.c,v 1.40 2004/06/14 10:31:52 stefanf Exp $"); | |
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 *); | |
25 | -static char * _fmt(const char *, const struct tm *, char *, const char *, int *); | |
26 | +static char * _conv(int, const char *, char *, const char *, locale_t); | |
27 | +#endif /* !BUILDING_VARIANT */ | |
28 | +#define _fmt _st_fmt | |
29 | +__private_extern__ char *_fmt(const char *, const struct tm *, char *, const char *, int *, struct lc_time_T *, locale_t); | |
30 | ||
31 | size_t strftime(char * __restrict, size_t, const char * __restrict, | |
32 | const struct tm * __restrict); | |
33 | ||
34 | extern char * tzname[]; | |
35 | +__private_extern__ long __darwin_altzone; /* DST timezone offset */ | |
36 | +#define altzone __darwin_altzone | |
37 | +__private_extern__ long _st_get_timezone(void); | |
38 | ||
39 | #ifndef YEAR_2000_NAME | |
40 | #define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS" | |
41 | @@ -60,29 +69,40 @@ | |
42 | #define IN_ALL 3 | |
43 | ||
44 | size_t | |
45 | -strftime(char * __restrict s, size_t maxsize, const char * __restrict format, | |
46 | - const struct tm * __restrict t) | |
47 | +strftime_l(char * __restrict s, size_t maxsize, const char * __restrict format, | |
48 | + const struct tm * __restrict t, locale_t loc) | |
49 | { | |
50 | char * p; | |
51 | int warn; | |
52 | +#if __DARWIN_UNIX03 | |
53 | + struct tm t2; | |
54 | +#endif /* __DARWIN_UNIX03 */ | |
55 | ||
56 | + NORMALIZE_LOCALE(loc); | |
57 | tzset(); | |
58 | warn = IN_NONE; | |
59 | - p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn); | |
60 | +#if __DARWIN_UNIX03 | |
61 | + if (t->tm_isdst >= 0) { | |
62 | + t2 = *t; | |
63 | + t2.tm_gmtoff = t->tm_isdst ? -__darwin_altzone : -_st_get_timezone(); | |
64 | + t = &t2; | |
65 | + } | |
66 | +#endif /* __DARWIN_UNIX03 */ | |
67 | + p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn, __get_current_time_locale(loc), loc); | |
68 | #ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU | |
69 | if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) { | |
70 | - (void) fprintf(stderr, "\n"); | |
71 | + (void) fputs("\n", stderr); | |
72 | if (format == NULL) | |
73 | - (void) fprintf(stderr, "NULL strftime format "); | |
74 | - else (void) fprintf(stderr, "strftime format \"%s\" ", | |
75 | + (void) fputs("NULL strftime format ", stderr); | |
76 | + else (void) fprintf_l(stderr, loc, "strftime format \"%s\" ", | |
77 | format); | |
78 | - (void) fprintf(stderr, "yields only two digits of years in "); | |
79 | + (void) fputs("yields only two digits of years in ", stderr); | |
80 | if (warn == IN_SOME) | |
81 | - (void) fprintf(stderr, "some locales"); | |
82 | + (void) fputs("some locales", stderr); | |
83 | else if (warn == IN_THIS) | |
84 | - (void) fprintf(stderr, "the current locale"); | |
85 | - else (void) fprintf(stderr, "all locales"); | |
86 | - (void) fprintf(stderr, "\n"); | |
87 | + (void) fputs("the current locale", stderr); | |
88 | + else (void) fputs("all locales", stderr); | |
89 | + (void) fputs("\n", stderr); | |
90 | } | |
91 | #endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */ | |
92 | if (p == s + maxsize) | |
93 | @@ -91,16 +111,25 @@ | |
94 | return p - s; | |
95 | } | |
96 | ||
97 | -static char * | |
98 | -_fmt(format, t, pt, ptlim, warnp) | |
99 | +size_t | |
100 | +strftime(char * __restrict s, size_t maxsize, const char * __restrict format, | |
101 | + const struct tm * __restrict t) | |
102 | +{ | |
103 | + return strftime_l(s, maxsize, format, t, __current_locale()); | |
104 | +} | |
105 | + | |
106 | +#ifndef BUILDING_VARIANT | |
107 | +__private_extern__ char * | |
108 | +_fmt(format, t, pt, ptlim, warnp, tptr, loc) | |
109 | const char * format; | |
110 | const struct tm * const t; | |
111 | char * pt; | |
112 | const char * const ptlim; | |
113 | int * warnp; | |
114 | +struct lc_time_T * tptr; | |
115 | +locale_t loc; | |
116 | { | |
117 | int Ealternative, Oalternative; | |
118 | - struct lc_time_T *tptr = __get_current_time_locale(); | |
119 | ||
120 | for ( ; *format; ++format) { | |
121 | if (*format == '%') { | |
122 | @@ -146,13 +175,13 @@ | |
123 | ** (ado, 1993-05-24) | |
124 | */ | |
125 | pt = _conv((t->tm_year + TM_YEAR_BASE) / 100, | |
126 | - "%02d", pt, ptlim); | |
127 | + "%02d", pt, ptlim, loc); | |
128 | continue; | |
129 | case 'c': | |
130 | { | |
131 | int warn2 = IN_SOME; | |
132 | ||
133 | - pt = _fmt(tptr->c_fmt, t, pt, ptlim, warnp); | |
134 | + pt = _fmt(tptr->c_fmt, t, pt, ptlim, warnp, tptr, loc); | |
135 | if (warn2 == IN_ALL) | |
136 | warn2 = IN_THIS; | |
137 | if (warn2 > *warnp) | |
138 | @@ -160,10 +189,10 @@ | |
139 | } | |
140 | continue; | |
141 | case 'D': | |
142 | - pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp); | |
143 | + pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp, tptr, loc); | |
144 | continue; | |
145 | case 'd': | |
146 | - pt = _conv(t->tm_mday, "%02d", pt, ptlim); | |
147 | + pt = _conv(t->tm_mday, "%02d", pt, ptlim, loc); | |
148 | continue; | |
149 | case 'E': | |
150 | if (Ealternative || Oalternative) | |
151 | @@ -188,21 +217,21 @@ | |
152 | Oalternative++; | |
153 | goto label; | |
154 | case 'e': | |
155 | - pt = _conv(t->tm_mday, "%2d", pt, ptlim); | |
156 | + pt = _conv(t->tm_mday, "%2d", pt, ptlim, loc); | |
157 | continue; | |
158 | case 'F': | |
159 | - pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp); | |
160 | + pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp, tptr, loc); | |
161 | continue; | |
162 | case 'H': | |
163 | - pt = _conv(t->tm_hour, "%02d", pt, ptlim); | |
164 | + pt = _conv(t->tm_hour, "%02d", pt, ptlim, loc); | |
165 | continue; | |
166 | case 'I': | |
167 | pt = _conv((t->tm_hour % 12) ? | |
168 | (t->tm_hour % 12) : 12, | |
169 | - "%02d", pt, ptlim); | |
170 | + "%02d", pt, ptlim, loc); | |
171 | continue; | |
172 | case 'j': | |
173 | - pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim); | |
174 | + pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim, loc); | |
175 | continue; | |
176 | case 'k': | |
177 | /* | |
178 | @@ -215,7 +244,7 @@ | |
179 | ** "%l" have been swapped. | |
180 | ** (ado, 1993-05-24) | |
181 | */ | |
182 | - pt = _conv(t->tm_hour, "%2d", pt, ptlim); | |
183 | + pt = _conv(t->tm_hour, "%2d", pt, ptlim, loc); | |
184 | continue; | |
185 | #ifdef KITCHEN_SINK | |
186 | case 'K': | |
187 | @@ -237,13 +266,13 @@ | |
188 | */ | |
189 | pt = _conv((t->tm_hour % 12) ? | |
190 | (t->tm_hour % 12) : 12, | |
191 | - "%2d", pt, ptlim); | |
192 | + "%2d", pt, ptlim, loc); | |
193 | continue; | |
194 | case 'M': | |
195 | - pt = _conv(t->tm_min, "%02d", pt, ptlim); | |
196 | + pt = _conv(t->tm_min, "%02d", pt, ptlim, loc); | |
197 | continue; | |
198 | case 'm': | |
199 | - pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim); | |
200 | + pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim, loc); | |
201 | continue; | |
202 | case 'n': | |
203 | pt = _add("\n", pt, ptlim); | |
204 | @@ -255,14 +284,14 @@ | |
205 | pt, ptlim); | |
206 | continue; | |
207 | case 'R': | |
208 | - pt = _fmt("%H:%M", t, pt, ptlim, warnp); | |
209 | + pt = _fmt("%H:%M", t, pt, ptlim, warnp, tptr, loc); | |
210 | continue; | |
211 | case 'r': | |
212 | pt = _fmt(tptr->ampm_fmt, t, pt, ptlim, | |
213 | - warnp); | |
214 | + warnp, tptr, loc); | |
215 | continue; | |
216 | case 'S': | |
217 | - pt = _conv(t->tm_sec, "%02d", pt, ptlim); | |
218 | + pt = _conv(t->tm_sec, "%02d", pt, ptlim, loc); | |
219 | continue; | |
220 | case 's': | |
221 | { | |
222 | @@ -274,15 +303,15 @@ | |
223 | tm = *t; | |
224 | mkt = mktime(&tm); | |
225 | if (TYPE_SIGNED(time_t)) | |
226 | - (void) sprintf(buf, "%ld", | |
227 | + (void) sprintf_l(buf, loc, "%ld", | |
228 | (long) mkt); | |
229 | - else (void) sprintf(buf, "%lu", | |
230 | + else (void) sprintf_l(buf, loc, "%lu", | |
231 | (unsigned long) mkt); | |
232 | pt = _add(buf, pt, ptlim); | |
233 | } | |
234 | continue; | |
235 | case 'T': | |
236 | - pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp); | |
237 | + pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp, tptr, loc); | |
238 | continue; | |
239 | case 't': | |
240 | pt = _add("\t", pt, ptlim); | |
241 | @@ -290,7 +319,7 @@ | |
242 | case 'U': | |
243 | pt = _conv((t->tm_yday + DAYSPERWEEK - | |
244 | t->tm_wday) / DAYSPERWEEK, | |
245 | - "%02d", pt, ptlim); | |
246 | + "%02d", pt, ptlim, loc); | |
247 | continue; | |
248 | case 'u': | |
249 | /* | |
250 | @@ -301,7 +330,7 @@ | |
251 | */ | |
252 | pt = _conv((t->tm_wday == 0) ? | |
253 | DAYSPERWEEK : t->tm_wday, | |
254 | - "%d", pt, ptlim); | |
255 | + "%d", pt, ptlim, loc); | |
256 | continue; | |
257 | case 'V': /* ISO 8601 week number */ | |
258 | case 'G': /* ISO 8601 year (four digits) */ | |
259 | @@ -380,13 +409,13 @@ | |
260 | #endif /* defined XPG4_1994_04_09 */ | |
261 | if (*format == 'V') | |
262 | pt = _conv(w, "%02d", | |
263 | - pt, ptlim); | |
264 | + pt, ptlim, loc); | |
265 | else if (*format == 'g') { | |
266 | *warnp = IN_ALL; | |
267 | pt = _conv(year % 100, "%02d", | |
268 | - pt, ptlim); | |
269 | + pt, ptlim, loc); | |
270 | } else pt = _conv(year, "%04d", | |
271 | - pt, ptlim); | |
272 | + pt, ptlim, loc); | |
273 | } | |
274 | continue; | |
275 | case 'v': | |
276 | @@ -395,26 +424,26 @@ | |
277 | ** "date as dd-bbb-YYYY" | |
278 | ** (ado, 1993-05-24) | |
279 | */ | |
280 | - pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp); | |
281 | + pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp, tptr, loc); | |
282 | continue; | |
283 | case 'W': | |
284 | pt = _conv((t->tm_yday + DAYSPERWEEK - | |
285 | (t->tm_wday ? | |
286 | (t->tm_wday - 1) : | |
287 | (DAYSPERWEEK - 1))) / DAYSPERWEEK, | |
288 | - "%02d", pt, ptlim); | |
289 | + "%02d", pt, ptlim, loc); | |
290 | continue; | |
291 | case 'w': | |
292 | - pt = _conv(t->tm_wday, "%d", pt, ptlim); | |
293 | + pt = _conv(t->tm_wday, "%d", pt, ptlim, loc); | |
294 | continue; | |
295 | case 'X': | |
296 | - pt = _fmt(tptr->X_fmt, t, pt, ptlim, warnp); | |
297 | + pt = _fmt(tptr->X_fmt, t, pt, ptlim, warnp, tptr, loc); | |
298 | continue; | |
299 | case 'x': | |
300 | { | |
301 | int warn2 = IN_SOME; | |
302 | ||
303 | - pt = _fmt(tptr->x_fmt, t, pt, ptlim, &warn2); | |
304 | + pt = _fmt(tptr->x_fmt, t, pt, ptlim, &warn2, tptr, loc); | |
305 | if (warn2 == IN_ALL) | |
306 | warn2 = IN_THIS; | |
307 | if (warn2 > *warnp) | |
308 | @@ -424,11 +453,11 @@ | |
309 | case 'y': | |
310 | *warnp = IN_ALL; | |
311 | pt = _conv((t->tm_year + TM_YEAR_BASE) % 100, | |
312 | - "%02d", pt, ptlim); | |
313 | + "%02d", pt, ptlim, loc); | |
314 | continue; | |
315 | case 'Y': | |
316 | pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d", | |
317 | - pt, ptlim); | |
318 | + pt, ptlim, loc); | |
319 | continue; | |
320 | case 'Z': | |
321 | #ifdef TM_ZONE | |
322 | @@ -476,7 +505,7 @@ | |
323 | */ | |
324 | if (t->tm_isdst == 0) | |
325 | #ifdef USG_COMPAT | |
326 | - diff = -timezone; | |
327 | + diff = -_st_get_timezone(); | |
328 | #else /* !defined USG_COMPAT */ | |
329 | continue; | |
330 | #endif /* !defined USG_COMPAT */ | |
331 | @@ -494,12 +523,12 @@ | |
332 | pt = _add(sign, pt, ptlim); | |
333 | diff /= 60; | |
334 | pt = _conv((diff/60)*100 + diff%60, | |
335 | - "%04d", pt, ptlim); | |
336 | + "%04d", pt, ptlim, loc); | |
337 | } | |
338 | continue; | |
339 | case '+': | |
340 | pt = _fmt(tptr->date_fmt, t, pt, ptlim, | |
341 | - warnp); | |
342 | + warnp, tptr, loc); | |
343 | continue; | |
344 | case '%': | |
345 | /* | |
346 | @@ -519,15 +548,16 @@ | |
347 | } | |
348 | ||
349 | static char * | |
350 | -_conv(n, format, pt, ptlim) | |
351 | +_conv(n, format, pt, ptlim, loc) | |
352 | const int n; | |
353 | const char * const format; | |
354 | char * const pt; | |
355 | const char * const ptlim; | |
356 | +locale_t loc; | |
357 | { | |
358 | char buf[INT_STRLEN_MAXIMUM(int) + 1]; | |
359 | ||
360 | - (void) sprintf(buf, format, n); | |
361 | + (void) sprintf_l(buf, loc, format, n); | |
362 | return _add(buf, pt, ptlim); | |
363 | } | |
364 | ||
365 | @@ -541,3 +571,4 @@ | |
366 | ++pt; | |
367 | return pt; | |
368 | } | |
369 | +#endif /* !BUILDING_VARIANT */ |