1 /* Copyright (C) 1991-1999, 2000, 2001, 2003, 2004, 2005 Free Software
2 Foundation, Inc.
3
4 NOTE: The canonical source of this file is maintained with the GNU C Library.
5 Bugs can be reported to bug-glibc@prep.ai.mit.edu.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
20
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24
25 #ifdef _LIBC
26 # define HAVE_MBLEN 1
27 # define HAVE_MBRLEN 1
28 # define HAVE_STRUCT_ERA_ENTRY 1
29 # define HAVE_TM_GMTOFF 1
30 # define HAVE_TM_ZONE 1
31 # define HAVE_TZNAME 1
32 # define HAVE_TZSET 1
33 # define MULTIBYTE_IS_FORMAT_SAFE 1
34 # include "../locale/localeinfo.h"
35 #endif
36
37 #include <ctype.h>
38 #include <sys/types.h> /* Some systems define `time_t' here. */
39
40 #ifdef TIME_WITH_SYS_TIME
41 # include <sys/time.h>
42 # include <time.h>
43 #else
44 # ifdef HAVE_SYS_TIME_H
45 # include <sys/time.h>
46 # else
47 # include <time.h>
48 # endif
49 #endif
50 #if HAVE_TZNAME
51 extern char *tzname[];
52 #endif
53
54 /* Do multibyte processing if multibytes are supported, unless
55 multibyte sequences are safe in formats. Multibyte sequences are
56 safe if they cannot contain byte sequences that look like format
57 conversion specifications. The GNU C Library uses UTF8 multibyte
58 encoding, which is safe for formats, but strftime.c can be used
59 with other C libraries that use unsafe encodings. */
60 #define DO_MULTIBYTE (HAVE_MBLEN && HAVE_WCHAR_H && ! MULTIBYTE_IS_FORMAT_SAFE)
61
62 #if DO_MULTIBYTE
63 # if HAVE_MBRLEN
64 # include <wchar.h>
65 # else
66 /* Simulate mbrlen with mblen as best we can. */
67 # define mbstate_t int
68 # define mbrlen(s, n, ps) mblen (s, n)
69 # define mbsinit(ps) (*(ps) == 0)
70 # endif
71 static const mbstate_t mbstate_zero;
72 #endif
73
74 #include <limits.h>
75 #include <stdbool.h>
76 #include <stddef.h>
77 #include <stdlib.h>
78 #include <string.h>
79
80 #ifdef COMPILE_WIDE
81 # include <endian.h>
82 # define CHAR_T wchar_t
83 # define UCHAR_T unsigned int
84 # define L_(Str) L##Str
85 # define NLW(Sym) _NL_W##Sym
86
87 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
88 # define STRLEN(s) __wcslen (s)
89
90 #else
91 # define CHAR_T char
92 # define UCHAR_T unsigned char
93 # define L_(Str) Str
94 # define NLW(Sym) Sym
95
96 # define MEMCPY(d, s, n) memcpy (d, s, n)
97 # define STRLEN(s) strlen (s)
98
99 # ifdef _LIBC
100 # define MEMPCPY(d, s, n) __mempcpy (d, s, n)
101 # else
102 # ifndef HAVE_MEMPCPY
103 # define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n)))
104 # endif
105 # endif
106 #endif
107
108 /* Shift A right by B bits portably, by dividing A by 2**B and
109 truncating towards minus infinity. A and B should be free of side
110 effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
111 INT_BITS is the number of useful bits in an int. GNU code can
112 assume that INT_BITS is at least 32.
113
114 ISO C99 says that A >> B is implementation-defined if A < 0. Some
115 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
116 right in the usual way when A < 0, so SHR falls back on division if
117 ordinary A >> B doesn't seem to be the usual signed shift. */
118 #define SHR(a, b) \
119 (-1 >> 1 == -1 \
120 ? (a) >> (b) \
121 : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
122
123 /* Bound on length of the string representing an integer type or expression T.
124 Subtract 1 for the sign bit if t is signed; log10 (2.0) < 146/485;
125 add 1 for integer division truncation; add 1 more for a minus sign
126 if needed. */
127 #define INT_STRLEN_BOUND(t) \
128 ((sizeof (t) * CHAR_BIT - 1) * 146 / 485 + 2)
129
130 #define TM_YEAR_BASE 1900
131
132 #ifndef __isleap
133 /* Nonzero if YEAR is a leap year (every 4 years,
134 except every 100th isn't, and every 400th is). */
135 # define __isleap(year) \
136 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
137 #endif
138
139
140 #ifdef _LIBC
141 # define tzname __tzname
142 # define tzset __tzset
143 #endif
144
145 #if !HAVE_TM_GMTOFF
146 /* Portable standalone applications should supply a "time_r.h" that
147 declares a POSIX-compliant localtime_r, for the benefit of older
148 implementations that lack localtime_r or have a nonstandard one.
149 See the gnulib time_r module for one way to implement this. */
150 # include "time_r.h"
151 # undef __gmtime_r
152 # undef __localtime_r
153 # define __gmtime_r gmtime_r
154 # define __localtime_r localtime_r
155 #endif
156
157
158 #ifdef COMPILE_WIDE
159 # define memset_space(P, Len) (wmemset (P, L' ', Len), (P) += (Len))
160 # define memset_zero(P, Len) (wmemset (P, L'0', Len), (P) += (Len))
161 #else
162 # define memset_space(P, Len) (memset (P, ' ', Len), (P) += (Len))
163 # define memset_zero(P, Len) (memset (P, '0', Len), (P) += (Len))
164 #endif
165
166 #define add(n, f) \
167 do \
168 { \
169 int _n = (n); \
170 int _delta = width - _n; \
171 int _incr = _n + (_delta > 0 ? _delta : 0); \
172 if ((size_t) _incr >= maxsize - i) \
173 return 0; \
174 if (p) \
175 { \
176 if (_delta > 0) \
177 { \
178 if (pad == L_('0')) \
179 memset_zero (p, _delta); \
180 else \
181 memset_space (p, _delta); \
182 } \
183 f; \
184 p += _n; \
185 } \
186 i += _incr; \
187 } while (0)
188
189 #define cpy(n, s) \
190 add ((n), \
191 if (to_lowcase) \
192 memcpy_lowcase (p, (s), _n LOCALE_ARG); \
193 else if (to_uppcase) \
194 memcpy_uppcase (p, (s), _n LOCALE_ARG); \
195 else \
196 MEMCPY ((void *) p, (void const *) (s), _n))
197
198 #ifdef COMPILE_WIDE
199 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
200 # undef __mbsrtowcs_l
201 # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
202 # endif
203 # define widen(os, ws, l) \
204 { \
205 mbstate_t __st; \
206 const char *__s = os; \
207 memset (&__st, '\0', sizeof (__st)); \
208 l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
209 ws = (wchar_t *) alloca ((l + 1) * sizeof (wchar_t)); \
210 (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
211 }
212 #endif
213
214
215 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
216 /* We use this code also for the extended locale handling where the
217 function gets as an additional argument the locale which has to be
218 used. To access the values we have to redefine the _NL_CURRENT
219 macro. */
220 # define strftime __strftime_l
221 # define wcsftime __wcsftime_l
222 # undef _NL_CURRENT
223 # define _NL_CURRENT(category, item) \
224 (current->values[_NL_ITEM_INDEX (item)].string)
225 # define LOCALE_ARG , loc
226 # define LOCALE_PARAM_PROTO , __locale_t loc
227 # define HELPER_LOCALE_ARG , current
228 #else
229 # define LOCALE_PARAM_PROTO
230 # define LOCALE_ARG
231 # ifdef _LIBC
232 # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
233 # else
234 # define HELPER_LOCALE_ARG
235 # endif
236 #endif
237
238 #ifdef COMPILE_WIDE
239 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
240 # define TOUPPER(Ch, L) __towupper_l (Ch, L)
241 # define TOLOWER(Ch, L) __towlower_l (Ch, L)
242 # else
243 # define TOUPPER(Ch, L) towupper (Ch)
244 # define TOLOWER(Ch, L) towlower (Ch)
245 # endif
246 #else
247 # ifdef _LIBC
248 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
249 # define TOUPPER(Ch, L) __toupper_l (Ch, L)
250 # define TOLOWER(Ch, L) __tolower_l (Ch, L)
251 # else
252 # define TOUPPER(Ch, L) toupper (Ch)
253 # define TOLOWER(Ch, L) tolower (Ch)
254 # endif
255 # else
256 # define TOUPPER(Ch, L) (islower (Ch) ? toupper (Ch) : (Ch))
257 # define TOLOWER(Ch, L) (isupper (Ch) ? tolower (Ch) : (Ch))
258 # endif
259 #endif
260 /* We don't use `isdigit' here since the locale dependent
261 interpretation is not what we want here. We only need to accept
262 the arabic digits in the ASCII range. One day there is perhaps a
263 more reliable way to accept other sets of digits. */
264 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
265
266 static CHAR_T *
memcpy_lowcase(CHAR_T * dest,const CHAR_T * src,size_t len LOCALE_PARAM_PROTO)267 memcpy_lowcase (CHAR_T *dest, const CHAR_T *src,
268 size_t len LOCALE_PARAM_PROTO)
269 {
270 while (len-- > 0)
271 dest[len] = TOLOWER ((UCHAR_T) src[len], loc);
272 return dest;
273 }
274
275 static CHAR_T *
memcpy_uppcase(CHAR_T * dest,const CHAR_T * src,size_t len LOCALE_PARAM_PROTO)276 memcpy_uppcase (CHAR_T *dest, const CHAR_T *src,
277 size_t len LOCALE_PARAM_PROTO)
278 {
279 while (len-- > 0)
280 dest[len] = TOUPPER ((UCHAR_T) src[len], loc);
281 return dest;
282 }
283
284
285 #if ! HAVE_TM_GMTOFF
286 /* Yield the difference between *A and *B,
287 measured in seconds, ignoring leap seconds. */
288 # define tm_diff ftime_tm_diff
289 static int
tm_diff(const struct tm * a,const struct tm * b)290 tm_diff (const struct tm *a, const struct tm *b)
291 {
292 /* Compute intervening leap days correctly even if year is negative.
293 Take care to avoid int overflow in leap day calculations,
294 but it's OK to assume that A and B are close to each other. */
295 int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3);
296 int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3);
297 int a100 = a4 / 25 - (a4 % 25 < 0);
298 int b100 = b4 / 25 - (b4 % 25 < 0);
299 int a400 = SHR (a100, 2);
300 int b400 = SHR (b100, 2);
301 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
302 int years = a->tm_year - b->tm_year;
303 int days = (365 * years + intervening_leap_days
304 + (a->tm_yday - b->tm_yday));
305 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
306 + (a->tm_min - b->tm_min))
307 + (a->tm_sec - b->tm_sec));
308 }
309 #endif /* ! HAVE_TM_GMTOFF */
310
311
312
313 /* The number of days from the first day of the first ISO week of this
314 year to the year day YDAY with week day WDAY. ISO weeks start on
315 Monday; the first ISO week has the year's first Thursday. YDAY may
316 be as small as YDAY_MINIMUM. */
317 #define ISO_WEEK_START_WDAY 1 /* Monday */
318 #define ISO_WEEK1_WDAY 4 /* Thursday */
319 #define YDAY_MINIMUM (-366)
320 #ifdef __GNUC__
321 __inline__
322 #endif
323 static int
iso_week_days(int yday,int wday)324 iso_week_days (int yday, int wday)
325 {
326 /* Add enough to the first operand of % to make it nonnegative. */
327 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
328 return (yday
329 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
330 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
331 }
332
333
334 #if !(defined _NL_CURRENT || HAVE_STRFTIME)
335 static CHAR_T const weekday_name[][10] =
336 {
337 L_("Sunday"), L_("Monday"), L_("Tuesday"), L_("Wednesday"),
338 L_("Thursday"), L_("Friday"), L_("Saturday")
339 };
340 static CHAR_T const month_name[][10] =
341 {
342 L_("January"), L_("February"), L_("March"), L_("April"), L_("May"),
343 L_("June"), L_("July"), L_("August"), L_("September"), L_("October"),
344 L_("November"), L_("December")
345 };
346 #endif
347
348
349 /* When compiling this file, GNU applications can #define my_strftime
350 to a symbol (typically nstrftime) to get an extended strftime with
351 extra arguments UT and NS. Emacs is a special case for now, but
352 this Emacs-specific code can be removed once Emacs's config.h
353 defines my_strftime. */
354 #if defined emacs && !defined my_strftime
355 # define my_strftime nstrftime
356 #endif
357
358 #ifdef my_strftime
359 # define extra_args , ut, ns
360 # define extra_args_spec , int ut, int ns
361 #else
362 # ifdef COMPILE_WIDE
363 # define my_strftime wcsftime
364 # define nl_get_alt_digit _nl_get_walt_digit
365 # else
366 # define my_strftime strftime
367 # define nl_get_alt_digit _nl_get_alt_digit
368 # endif
369 # define extra_args
370 # define extra_args_spec
371 /* We don't have this information in general. */
372 # define ut 0
373 # define ns 0
374 #endif
375
376
377 /* Write information from TP into S according to the format
378 string FORMAT, writing no more that MAXSIZE characters
379 (including the terminating '\0') and returning number of
380 characters written. If S is NULL, nothing will be written
381 anywhere, so to determine how many characters would be
382 written, use NULL for S and (size_t) -1 for MAXSIZE. */
383 size_t
my_strftime(CHAR_T * s,size_t maxsize,const CHAR_T * format,const struct tm * tp extra_args_spec LOCALE_PARAM_PROTO)384 my_strftime (CHAR_T *s, size_t maxsize, const CHAR_T *format,
385 const struct tm *tp extra_args_spec LOCALE_PARAM_PROTO)
386 {
387 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
388 struct locale_data *const current = loc->__locales[LC_TIME];
389 #endif
390
391 int hour12 = tp->tm_hour;
392 #ifdef _NL_CURRENT
393 /* We cannot make the following values variables since we must delay
394 the evaluation of these values until really needed since some
395 expressions might not be valid in every situation. The `struct tm'
396 might be generated by a strptime() call that initialized
397 only a few elements. Dereference the pointers only if the format
398 requires this. Then it is ok to fail if the pointers are invalid. */
399 # define a_wkday \
400 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
401 # define f_wkday \
402 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
403 # define a_month \
404 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
405 # define f_month \
406 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
407 # define ampm \
408 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
409 ? NLW(PM_STR) : NLW(AM_STR)))
410
411 # define aw_len STRLEN (a_wkday)
412 # define am_len STRLEN (a_month)
413 # define ap_len STRLEN (ampm)
414 #else
415 # if !HAVE_STRFTIME
416 # define f_wkday (weekday_name[tp->tm_wday])
417 # define f_month (month_name[tp->tm_mon])
418 # define a_wkday f_wkday
419 # define a_month f_month
420 # define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
421
422 size_t aw_len = 3;
423 size_t am_len = 3;
424 size_t ap_len = 2;
425 # endif
426 #endif
427 const char *zone;
428 size_t i = 0;
429 CHAR_T *p = s;
430 const CHAR_T *f;
431 #if DO_MULTIBYTE && !defined COMPILE_WIDE
432 const char *format_end = NULL;
433 #endif
434
435 #if ! defined _LIBC && ! HAVE_RUN_TZSET_TEST
436 /* Solaris 2.5.x and 2.6 tzset sometimes modify the storage returned
437 by localtime. On such systems, we must either use the tzset and
438 localtime wrappers to work around the bug (which sets
439 HAVE_RUN_TZSET_TEST) or make a copy of the structure. */
440 struct tm copy = *tp;
441 tp = ©
442 #endif
443
444 zone = NULL;
445 #if HAVE_TM_ZONE
446 /* The POSIX test suite assumes that setting
447 the environment variable TZ to a new value before calling strftime()
448 will influence the result (the %Z format) even if the information in
449 TP is computed with a totally different time zone.
450 This is bogus: though POSIX allows bad behavior like this,
451 POSIX does not require it. Do the right thing instead. */
452 zone = (const char *) tp->tm_zone;
453 #endif
454 #if HAVE_TZNAME
455 if (ut)
456 {
457 if (! (zone && *zone))
458 zone = "GMT";
459 }
460 else
461 {
462 /* POSIX.1 requires that local time zone information be used as
463 though strftime called tzset. */
464 # if HAVE_TZSET
465 tzset ();
466 # endif
467 }
468 #endif
469
470 if (hour12 > 12)
471 hour12 -= 12;
472 else
473 if (hour12 == 0)
474 hour12 = 12;
475
476 for (f = format; *f != '\0'; ++f)
477 {
478 int pad = 0; /* Padding for number ('-', '_', or 0). */
479 int modifier; /* Field modifier ('E', 'O', or 0). */
480 int digits; /* Max digits for numeric format. */
481 int number_value; /* Numeric value to be printed. */
482 unsigned int u_number_value; /* (unsigned int) number_value. */
483 bool negative_number; /* 1 if the number is negative. */
484 const CHAR_T *subfmt;
485 CHAR_T *bufp;
486 CHAR_T buf[1 + (sizeof (int) < sizeof (time_t)
487 ? INT_STRLEN_BOUND (time_t)
488 : INT_STRLEN_BOUND (int))];
489 int width = -1;
490 bool to_lowcase = false;
491 bool to_uppcase = false;
492 bool change_case = false;
493 int format_char;
494
495 #if DO_MULTIBYTE && !defined COMPILE_WIDE
496 switch (*f)
497 {
498 case L_('%'):
499 break;
500
501 case L_('\b'): case L_('\t'): case L_('\n'):
502 case L_('\v'): case L_('\f'): case L_('\r'):
503 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
504 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
505 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
506 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
507 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
508 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
509 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
510 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
511 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
512 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
513 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
514 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
515 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
516 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
517 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
518 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
519 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
520 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
521 case L_('~'):
522 /* The C Standard requires these 98 characters (plus '%') to
523 be in the basic execution character set. None of these
524 characters can start a multibyte sequence, so they need
525 not be analyzed further. */
526 add (1, *p = *f);
527 continue;
528
529 default:
530 /* Copy this multibyte sequence until we reach its end, find
531 an error, or come back to the initial shift state. */
532 {
533 mbstate_t mbstate = mbstate_zero;
534 size_t len = 0;
535 size_t fsize;
536
537 if (! format_end)
538 format_end = f + strlen (f) + 1;
539 fsize = format_end - f;
540
541 do
542 {
543 size_t bytes = mbrlen (f + len, fsize - len, &mbstate);
544
545 if (bytes == 0)
546 break;
547
548 if (bytes == (size_t) -2)
549 {
550 len += strlen (f + len);
551 break;
552 }
553
554 if (bytes == (size_t) -1)
555 {
556 len++;
557 break;
558 }
559
560 len += bytes;
561 }
562 while (! mbsinit (&mbstate));
563
564 cpy (len, f);
565 f += len - 1;
566 continue;
567 }
568 }
569
570 #else /* ! DO_MULTIBYTE */
571
572 /* Either multibyte encodings are not supported, they are
573 safe for formats, so any non-'%' byte can be copied through,
574 or this is the wide character version. */
575 if (*f != L_('%'))
576 {
577 add (1, *p = *f);
578 continue;
579 }
580
581 #endif /* ! DO_MULTIBYTE */
582
583 /* Check for flags that can modify a format. */
584 while (1)
585 {
586 switch (*++f)
587 {
588 /* This influences the number formats. */
589 case L_('_'):
590 case L_('-'):
591 case L_('0'):
592 pad = *f;
593 continue;
594
595 /* This changes textual output. */
596 case L_('^'):
597 to_uppcase = true;
598 continue;
599 case L_('#'):
600 change_case = true;
601 continue;
602
603 default:
604 break;
605 }
606 break;
607 }
608
609 /* As a GNU extension we allow to specify the field width. */
610 if (ISDIGIT (*f))
611 {
612 width = 0;
613 do
614 {
615 if (width > INT_MAX / 10
616 || (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10))
617 /* Avoid overflow. */
618 width = INT_MAX;
619 else
620 {
621 width *= 10;
622 width += *f - L_('0');
623 }
624 ++f;
625 }
626 while (ISDIGIT (*f));
627 }
628
629 /* Check for modifiers. */
630 switch (*f)
631 {
632 case L_('E'):
633 case L_('O'):
634 modifier = *f++;
635 break;
636
637 default:
638 modifier = 0;
639 break;
640 }
641
642 /* Now do the specified format. */
643 format_char = *f;
644 switch (format_char)
645 {
646 #define DO_NUMBER(d, v) \
647 digits = d; \
648 number_value = v; goto do_number
649 #define DO_SIGNED_NUMBER(d, negative, v) \
650 digits = d; \
651 negative_number = negative; \
652 u_number_value = v; goto do_signed_number
653 #define DO_NUMBER_SPACEPAD(d, v) \
654 digits = d; \
655 number_value = v; goto do_number_spacepad
656
657 case L_('%'):
658 if (modifier != 0)
659 goto bad_format;
660 add (1, *p = *f);
661 break;
662
663 case L_('a'):
664 if (modifier != 0)
665 goto bad_format;
666 if (change_case)
667 {
668 to_uppcase = true;
669 to_lowcase = false;
670 }
671 #if defined _NL_CURRENT || !HAVE_STRFTIME
672 cpy (aw_len, a_wkday);
673 break;
674 #else
675 goto underlying_strftime;
676 #endif
677
678 case 'A':
679 if (modifier != 0)
680 goto bad_format;
681 if (change_case)
682 {
683 to_uppcase = true;
684 to_lowcase = false;
685 }
686 #if defined _NL_CURRENT || !HAVE_STRFTIME
687 cpy (STRLEN (f_wkday), f_wkday);
688 break;
689 #else
690 goto underlying_strftime;
691 #endif
692
693 case L_('b'):
694 case L_('h'):
695 if (change_case)
696 {
697 to_uppcase = true;
698 to_lowcase = false;
699 }
700 if (modifier != 0)
701 goto bad_format;
702 #if defined _NL_CURRENT || !HAVE_STRFTIME
703 cpy (am_len, a_month);
704 break;
705 #else
706 goto underlying_strftime;
707 #endif
708
709 case L_('B'):
710 if (modifier != 0)
711 goto bad_format;
712 if (change_case)
713 {
714 to_uppcase = true;
715 to_lowcase = false;
716 }
717 #if defined _NL_CURRENT || !HAVE_STRFTIME
718 cpy (STRLEN (f_month), f_month);
719 break;
720 #else
721 goto underlying_strftime;
722 #endif
723
724 case L_('c'):
725 if (modifier == L_('O'))
726 goto bad_format;
727 #ifdef _NL_CURRENT
728 if (! (modifier == 'E'
729 && (*(subfmt =
730 (const CHAR_T *) _NL_CURRENT (LC_TIME,
731 NLW(ERA_D_T_FMT)))
732 != '\0')))
733 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
734 #else
735 # if HAVE_STRFTIME
736 goto underlying_strftime;
737 # else
738 subfmt = L_("%a %b %e %H:%M:%S %Y");
739 # endif
740 #endif
741
742 subformat:
743 {
744 CHAR_T *old_start = p;
745 size_t len = my_strftime (NULL, (size_t) -1, subfmt,
746 tp extra_args LOCALE_ARG);
747 add (len, my_strftime (p, maxsize - i, subfmt,
748 tp extra_args LOCALE_ARG));
749
750 if (to_uppcase)
751 while (old_start < p)
752 {
753 *old_start = TOUPPER ((UCHAR_T) *old_start, loc);
754 ++old_start;
755 }
756 }
757 break;
758
759 #if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
760 underlying_strftime:
761 {
762 /* The relevant information is available only via the
763 underlying strftime implementation, so use that. */
764 char ufmt[5];
765 char *u = ufmt;
766 char ubuf[1024]; /* enough for any single format in practice */
767 size_t len;
768 /* Make sure we're calling the actual underlying strftime.
769 In some cases, config.h contains something like
770 "#define strftime rpl_strftime". */
771 # ifdef strftime
772 # undef strftime
773 size_t strftime ();
774 # endif
775
776 /* The space helps distinguish strftime failure from empty
777 output. */
778 *u++ = ' ';
779 *u++ = '%';
780 if (modifier != 0)
781 *u++ = modifier;
782 *u++ = format_char;
783 *u = '\0';
784 len = strftime (ubuf, sizeof ubuf, ufmt, tp);
785 if (len != 0)
786 cpy (len - 1, ubuf + 1);
787 }
788 break;
789 #endif
790
791 case L_('C'):
792 if (modifier == L_('O'))
793 goto bad_format;
794 if (modifier == L_('E'))
795 {
796 #if HAVE_STRUCT_ERA_ENTRY
797 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
798 if (era)
799 {
800 # ifdef COMPILE_WIDE
801 size_t len = __wcslen (era->era_wname);
802 cpy (len, era->era_wname);
803 # else
804 size_t len = strlen (era->era_name);
805 cpy (len, era->era_name);
806 # endif
807 break;
808 }
809 #else
810 # if HAVE_STRFTIME
811 goto underlying_strftime;
812 # endif
813 #endif
814 }
815
816 {
817 int century = tp->tm_year / 100 + TM_YEAR_BASE / 100;
818 century -= tp->tm_year % 100 < 0 && 0 < century;
819 DO_SIGNED_NUMBER (2, tp->tm_year < - TM_YEAR_BASE, century);
820 }
821
822 case L_('x'):
823 if (modifier == L_('O'))
824 goto bad_format;
825 #ifdef _NL_CURRENT
826 if (! (modifier == L_('E')
827 && (*(subfmt =
828 (const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT)))
829 != L_('\0'))))
830 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
831 goto subformat;
832 #else
833 # if HAVE_STRFTIME
834 goto underlying_strftime;
835 # else
836 /* Fall through. */
837 # endif
838 #endif
839 case L_('D'):
840 if (modifier != 0)
841 goto bad_format;
842 subfmt = L_("%m/%d/%y");
843 goto subformat;
844
845 case L_('d'):
846 if (modifier == L_('E'))
847 goto bad_format;
848
849 DO_NUMBER (2, tp->tm_mday);
850
851 case L_('e'):
852 if (modifier == L_('E'))
853 goto bad_format;
854
855 DO_NUMBER_SPACEPAD (2, tp->tm_mday);
856
857 /* All numeric formats set DIGITS and NUMBER_VALUE (or U_NUMBER_VALUE)
858 and then jump to one of these three labels. */
859
860 do_number_spacepad:
861 /* Force `_' flag unless overridden by `0' or `-' flag. */
862 if (pad != L_('0') && pad != L_('-'))
863 pad = L_('_');
864
865 do_number:
866 /* Format NUMBER_VALUE according to the MODIFIER flag. */
867 negative_number = number_value < 0;
868 u_number_value = number_value;
869
870 do_signed_number:
871 /* Format U_NUMBER_VALUE according to the MODIFIER flag.
872 NEGATIVE_NUMBER is nonzero if the original number was
873 negative; in this case it was converted directly to
874 unsigned int (i.e., modulo (UINT_MAX + 1)) without
875 negating it. */
876 if (modifier == L_('O') && !negative_number)
877 {
878 #ifdef _NL_CURRENT
879 /* Get the locale specific alternate representation of
880 the number. If none exist NULL is returned. */
881 const CHAR_T *cp = nl_get_alt_digit (u_number_value
882 HELPER_LOCALE_ARG);
883
884 if (cp != NULL)
885 {
886 size_t digitlen = STRLEN (cp);
887 if (digitlen != 0)
888 {
889 cpy (digitlen, cp);
890 break;
891 }
892 }
893 #else
894 # if HAVE_STRFTIME
895 goto underlying_strftime;
896 # endif
897 #endif
898 }
899
900 bufp = buf + sizeof (buf) / sizeof (buf[0]);
901
902 if (negative_number)
903 u_number_value = - u_number_value;
904
905 do
906 {
907 *--bufp = u_number_value % 10 + L_('0');
908 u_number_value /= 10;
909 }
910 while (u_number_value != 0);
911
912 do_number_sign_and_padding:
913 if (digits < width)
914 digits = width;
915
916 if (negative_number)
917 *--bufp = L_('-');
918
919 if (pad != L_('-'))
920 {
921 int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
922 - bufp);
923
924 if (padding > 0)
925 {
926 if (pad == L_('_'))
927 {
928 if ((size_t) padding >= maxsize - i)
929 return 0;
930
931 if (p)
932 memset_space (p, padding);
933 i += padding;
934 width = width > padding ? width - padding : 0;
935 }
936 else
937 {
938 if ((size_t) digits >= maxsize - i)
939 return 0;
940
941 if (negative_number)
942 {
943 ++bufp;
944
945 if (p)
946 *p++ = L_('-');
947 ++i;
948 }
949
950 if (p)
951 memset_zero (p, padding);
952 i += padding;
953 width = 0;
954 }
955 }
956 }
957
958 cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
959 break;
960
961 case L_('F'):
962 if (modifier != 0)
963 goto bad_format;
964 subfmt = L_("%Y-%m-%d");
965 goto subformat;
966
967 case L_('H'):
968 if (modifier == L_('E'))
969 goto bad_format;
970
971 DO_NUMBER (2, tp->tm_hour);
972
973 case L_('I'):
974 if (modifier == L_('E'))
975 goto bad_format;
976
977 DO_NUMBER (2, hour12);
978
979 case L_('k'): /* GNU extension. */
980 if (modifier == L_('E'))
981 goto bad_format;
982
983 DO_NUMBER_SPACEPAD (2, tp->tm_hour);
984
985 case L_('l'): /* GNU extension. */
986 if (modifier == L_('E'))
987 goto bad_format;
988
989 DO_NUMBER_SPACEPAD (2, hour12);
990
991 case L_('j'):
992 if (modifier == L_('E'))
993 goto bad_format;
994
995 DO_SIGNED_NUMBER (3, tp->tm_yday < -1, tp->tm_yday + 1U);
996
997 case L_('M'):
998 if (modifier == L_('E'))
999 goto bad_format;
1000
1001 DO_NUMBER (2, tp->tm_min);
1002
1003 case L_('m'):
1004 if (modifier == L_('E'))
1005 goto bad_format;
1006
1007 DO_SIGNED_NUMBER (2, tp->tm_mon < -1, tp->tm_mon + 1U);
1008
1009 #ifndef _LIBC
1010 case L_('N'): /* GNU extension. */
1011 if (modifier == L_('E'))
1012 goto bad_format;
1013
1014 number_value = ns;
1015 if (width != -1)
1016 {
1017 /* Take an explicit width less than 9 as a precision. */
1018 int j;
1019 for (j = width; j < 9; j++)
1020 number_value /= 10;
1021 }
1022
1023 DO_NUMBER (9, number_value);
1024 #endif
1025
1026 case L_('n'):
1027 add (1, *p = L_('\n'));
1028 break;
1029
1030 case L_('P'):
1031 to_lowcase = true;
1032 #if !defined _NL_CURRENT && HAVE_STRFTIME
1033 format_char = L_('p');
1034 #endif
1035 /* FALLTHROUGH */
1036
1037 case L_('p'):
1038 if (change_case)
1039 {
1040 to_uppcase = false;
1041 to_lowcase = true;
1042 }
1043 #if defined _NL_CURRENT || !HAVE_STRFTIME
1044 cpy (ap_len, ampm);
1045 break;
1046 #else
1047 goto underlying_strftime;
1048 #endif
1049
1050 case L_('R'):
1051 subfmt = L_("%H:%M");
1052 goto subformat;
1053
1054 case L_('r'):
1055 #if !defined _NL_CURRENT && HAVE_STRFTIME
1056 goto underlying_strftime;
1057 #else
1058 # ifdef _NL_CURRENT
1059 if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME,
1060 NLW(T_FMT_AMPM)))
1061 == L_('\0'))
1062 # endif
1063 subfmt = L_("%I:%M:%S %p");
1064 goto subformat;
1065 #endif
1066
1067 case L_('S'):
1068 if (modifier == L_('E'))
1069 goto bad_format;
1070
1071 DO_NUMBER (2, tp->tm_sec);
1072
1073 case L_('s'): /* GNU extension. */
1074 {
1075 struct tm ltm;
1076 time_t t;
1077
1078 ltm = *tp;
1079 t = mktime (<m);
1080
1081 /* Generate string value for T using time_t arithmetic;
1082 this works even if sizeof (long) < sizeof (time_t). */
1083
1084 bufp = buf + sizeof (buf) / sizeof (buf[0]);
1085 negative_number = t < 0;
1086
1087 do
1088 {
1089 int d = t % 10;
1090 t /= 10;
1091 *--bufp = (negative_number ? -d : d) + L_('0');
1092 }
1093 while (t != 0);
1094
1095 digits = 1;
1096 goto do_number_sign_and_padding;
1097 }
1098
1099 case L_('X'):
1100 if (modifier == L_('O'))
1101 goto bad_format;
1102 #ifdef _NL_CURRENT
1103 if (! (modifier == L_('E')
1104 && (*(subfmt =
1105 (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT)))
1106 != L_('\0'))))
1107 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
1108 goto subformat;
1109 #else
1110 # if HAVE_STRFTIME
1111 goto underlying_strftime;
1112 # else
1113 /* Fall through. */
1114 # endif
1115 #endif
1116 case L_('T'):
1117 subfmt = L_("%H:%M:%S");
1118 goto subformat;
1119
1120 case L_('t'):
1121 add (1, *p = L_('\t'));
1122 break;
1123
1124 case L_('u'):
1125 DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
1126
1127 case L_('U'):
1128 if (modifier == L_('E'))
1129 goto bad_format;
1130
1131 DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
1132
1133 case L_('V'):
1134 case L_('g'):
1135 case L_('G'):
1136 if (modifier == L_('E'))
1137 goto bad_format;
1138 {
1139 /* YEAR is a leap year if and only if (tp->tm_year + TM_YEAR_BASE)
1140 is a leap year, except that YEAR and YEAR - 1 both work
1141 correctly even when (tp->tm_year + TM_YEAR_BASE) would
1142 overflow. */
1143 int year = (tp->tm_year
1144 + (tp->tm_year < 0
1145 ? TM_YEAR_BASE % 400
1146 : TM_YEAR_BASE % 400 - 400));
1147 int year_adjust = 0;
1148 int days = iso_week_days (tp->tm_yday, tp->tm_wday);
1149
1150 if (days < 0)
1151 {
1152 /* This ISO week belongs to the previous year. */
1153 year_adjust = -1;
1154 days = iso_week_days (tp->tm_yday + (365 + __isleap (year - 1)),
1155 tp->tm_wday);
1156 }
1157 else
1158 {
1159 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
1160 tp->tm_wday);
1161 if (0 <= d)
1162 {
1163 /* This ISO week belongs to the next year. */
1164 year_adjust = 1;
1165 days = d;
1166 }
1167 }
1168
1169 switch (*f)
1170 {
1171 case L_('g'):
1172 {
1173 int yy = (tp->tm_year % 100 + year_adjust) % 100;
1174 DO_NUMBER (2, (0 <= yy
1175 ? yy
1176 : tp->tm_year < -TM_YEAR_BASE - year_adjust
1177 ? -yy
1178 : yy + 100));
1179 }
1180
1181 case L_('G'):
1182 DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE - year_adjust,
1183 (tp->tm_year + (unsigned int) TM_YEAR_BASE
1184 + year_adjust));
1185
1186 default:
1187 DO_NUMBER (2, days / 7 + 1);
1188 }
1189 }
1190
1191 case L_('W'):
1192 if (modifier == L_('E'))
1193 goto bad_format;
1194
1195 DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
1196
1197 case L_('w'):
1198 if (modifier == L_('E'))
1199 goto bad_format;
1200
1201 DO_NUMBER (1, tp->tm_wday);
1202
1203 case L_('Y'):
1204 if (modifier == 'E')
1205 {
1206 #if HAVE_STRUCT_ERA_ENTRY
1207 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1208 if (era)
1209 {
1210 # ifdef COMPILE_WIDE
1211 subfmt = era->era_wformat;
1212 # else
1213 subfmt = era->era_format;
1214 # endif
1215 goto subformat;
1216 }
1217 #else
1218 # if HAVE_STRFTIME
1219 goto underlying_strftime;
1220 # endif
1221 #endif
1222 }
1223 if (modifier == L_('O'))
1224 goto bad_format;
1225 else
1226 DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE,
1227 tp->tm_year + (unsigned int) TM_YEAR_BASE);
1228
1229 case L_('y'):
1230 if (modifier == L_('E'))
1231 {
1232 #if HAVE_STRUCT_ERA_ENTRY
1233 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1234 if (era)
1235 {
1236 int delta = tp->tm_year - era->start_date[0];
1237 DO_NUMBER (1, (era->offset
1238 + delta * era->absolute_direction));
1239 }
1240 #else
1241 # if HAVE_STRFTIME
1242 goto underlying_strftime;
1243 # endif
1244 #endif
1245 }
1246
1247 {
1248 int yy = tp->tm_year % 100;
1249 if (yy < 0)
1250 yy = tp->tm_year < - TM_YEAR_BASE ? -yy : yy + 100;
1251 DO_NUMBER (2, yy);
1252 }
1253
1254 case L_('Z'):
1255 if (change_case)
1256 {
1257 to_uppcase = false;
1258 to_lowcase = true;
1259 }
1260
1261 #if HAVE_TZNAME
1262 /* The tzset() call might have changed the value. */
1263 if (!(zone && *zone) && tp->tm_isdst >= 0)
1264 zone = tzname[tp->tm_isdst != 0];
1265 #endif
1266 if (! zone)
1267 zone = "";
1268
1269 #ifdef COMPILE_WIDE
1270 {
1271 /* The zone string is always given in multibyte form. We have
1272 to transform it first. */
1273 wchar_t *wczone;
1274 size_t len;
1275 widen (zone, wczone, len);
1276 cpy (len, wczone);
1277 }
1278 #else
1279 cpy (strlen (zone), zone);
1280 #endif
1281 break;
1282
1283 case L_('z'):
1284 if (tp->tm_isdst < 0)
1285 break;
1286
1287 {
1288 int diff;
1289 #if HAVE_TM_GMTOFF
1290 diff = tp->tm_gmtoff;
1291 #else
1292 if (ut)
1293 diff = 0;
1294 else
1295 {
1296 struct tm gtm;
1297 struct tm ltm;
1298 time_t lt;
1299
1300 ltm = *tp;
1301 lt = mktime (<m);
1302
1303 if (lt == (time_t) -1)
1304 {
1305 /* mktime returns -1 for errors, but -1 is also a
1306 valid time_t value. Check whether an error really
1307 occurred. */
1308 struct tm tm;
1309
1310 if (! __localtime_r (<, &tm)
1311 || ((ltm.tm_sec ^ tm.tm_sec)
1312 | (ltm.tm_min ^ tm.tm_min)
1313 | (ltm.tm_hour ^ tm.tm_hour)
1314 | (ltm.tm_mday ^ tm.tm_mday)
1315 | (ltm.tm_mon ^ tm.tm_mon)
1316 | (ltm.tm_year ^ tm.tm_year)))
1317 break;
1318 }
1319
1320 if (! __gmtime_r (<, >m))
1321 break;
1322
1323 diff = tm_diff (<m, >m);
1324 }
1325 #endif
1326
1327 if (diff < 0)
1328 {
1329 add (1, *p = L_('-'));
1330 diff = -diff;
1331 }
1332 else
1333 add (1, *p = L_('+'));
1334
1335 diff /= 60;
1336 DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
1337 }
1338
1339 case L_('\0'): /* GNU extension: % at end of format. */
1340 --f;
1341 /* Fall through. */
1342 default:
1343 /* Unknown format; output the format, including the '%',
1344 since this is most likely the right thing to do if a
1345 multibyte string has been misparsed. */
1346 bad_format:
1347 {
1348 int flen;
1349 for (flen = 1; f[1 - flen] != L_('%'); flen++)
1350 continue;
1351 cpy (flen, &f[1 - flen]);
1352 }
1353 break;
1354 }
1355 }
1356
1357 if (p && maxsize != 0)
1358 *p = L_('\0');
1359 return i;
1360 }
1361 #ifdef _LIBC
libc_hidden_def(my_strftime)1362 libc_hidden_def (my_strftime)
1363 #endif
1364
1365
1366 #ifdef emacs
1367 /* For Emacs we have a separate interface which corresponds to the normal
1368 strftime function plus the ut argument, but without the ns argument. */
1369 size_t
1370 emacs_strftimeu (char *s, size_t maxsize, const char *format,
1371 const struct tm *tp, int ut)
1372 {
1373 return my_strftime (s, maxsize, format, tp, ut, 0);
1374 }
1375 #endif
1376