1 /* Copyright (C) 1991-1999, 2000, 2001, 2003 Free Software Foundation, Inc.
3 NOTE: The canonical source of this file is maintained with the GNU C Library.
4 Bugs can be reported to bug-glibc@prep.ai.mit.edu.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation,
18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 # define HAVE_LIMITS_H 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
33 # define MULTIBYTE_IS_FORMAT_SAFE 1
34 # define STDC_HEADERS 1
35 # include "../locale/localeinfo.h"
38 #if defined emacs && !defined HAVE_BCOPY
39 # define HAVE_MEMCPY 1
43 #include <sys/types.h> /* Some systems define `time_t' here. */
45 #ifdef TIME_WITH_SYS_TIME
46 # include <sys/time.h>
49 # ifdef HAVE_SYS_TIME_H
50 # include <sys/time.h>
56 extern char *tzname[];
59 /* Do multibyte processing if multibytes are supported, unless
60 multibyte sequences are safe in formats. Multibyte sequences are
61 safe if they cannot contain byte sequences that look like format
62 conversion specifications. The GNU C Library uses UTF8 multibyte
63 encoding, which is safe for formats, but strftime.c can be used
64 with other C libraries that use unsafe encodings. */
65 #define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
71 /* Simulate mbrlen with mblen as best we can. */
72 # define mbstate_t int
73 # define mbrlen(s, n, ps) mblen (s, n)
74 # define mbsinit(ps) (*(ps) == 0)
76 static const mbstate_t mbstate_zero;
89 # define memcpy(d, s, n) bcopy ((s), (d), (n))
95 # define CHAR_T wchar_t
96 # define UCHAR_T unsigned int
97 # define L_(Str) L##Str
98 # define NLW(Sym) _NL_W##Sym
100 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
101 # define STRLEN(s) __wcslen (s)
105 # define UCHAR_T unsigned char
107 # define NLW(Sym) Sym
109 # if !defined STDC_HEADERS && !defined HAVE_MEMCPY
110 # define MEMCPY(d, s, n) bcopy ((s), (d), (n))
112 # define MEMCPY(d, s, n) memcpy ((d), (s), (n))
114 # define STRLEN(s) strlen (s)
117 # define MEMPCPY(d, s, n) __mempcpy (d, s, n)
119 # ifndef HAVE_MEMPCPY
120 # define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n)))
126 # if defined __GNUC__ || (defined __STDC__ && __STDC__)
127 # define __P(args) args
129 # define __P(args) ()
131 #endif /* Not __P. */
149 #define TYPE_SIGNED(t) ((t) -1 < 0)
151 /* Bound on length of the string representing an integer value of type t.
152 Subtract one for the sign bit if t is signed;
153 302 / 1000 is log10 (2) rounded up;
154 add one for integer division truncation;
155 add one more for a minus sign if t is signed. */
156 #define INT_STRLEN_BOUND(t) \
157 ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 + 1 + TYPE_SIGNED (t))
159 #define TM_YEAR_BASE 1900
162 /* Nonzero if YEAR is a leap year (every 4 years,
163 except every 100th isn't, and every 400th is). */
164 # define __isleap(year) \
165 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
170 # define my_strftime_gmtime_r __gmtime_r
171 # define my_strftime_localtime_r __localtime_r
172 # define tzname __tzname
173 # define tzset __tzset
176 /* If we're a strftime substitute in a GNU program, then prefer gmtime
177 to gmtime_r, since many gmtime_r implementations are buggy.
178 Similarly for localtime_r. */
180 # if ! HAVE_TM_GMTOFF
181 static struct tm *my_strftime_gmtime_r __P ((const time_t *, struct tm *));
183 my_strftime_gmtime_r (t, tp)
187 struct tm *l = gmtime (t);
194 static struct tm *my_strftime_localtime_r __P ((const time_t *, struct tm *));
196 my_strftime_localtime_r (t, tp)
200 struct tm *l = localtime (t);
206 # endif /* ! HAVE_TM_GMTOFF */
207 #endif /* ! defined _LIBC */
210 #if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
211 /* Some systems lack the `memset' function and we don't want to
212 introduce additional dependencies. */
213 /* The SGI compiler reportedly barfs on the trailing null
214 if we use a string constant as the initializer. 28 June 1997, rms. */
215 static const CHAR_T spaces[16] = /* " " */
217 L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),
218 L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' ')
220 static const CHAR_T zeroes[16] = /* "0000000000000000" */
222 L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),
223 L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0')
226 # define memset_space(P, Len) \
232 int _this = _len > 16 ? 16 : _len; \
233 (P) = MEMPCPY ((P), spaces, _this * sizeof (CHAR_T)); \
239 # define memset_zero(P, Len) \
245 int _this = _len > 16 ? 16 : _len; \
246 (P) = MEMPCPY ((P), zeroes, _this * sizeof (CHAR_T)); \
253 # define memset_space(P, Len) (wmemset ((P), L' ', (Len)), (P) += (Len))
254 # define memset_zero(P, Len) (wmemset ((P), L'0', (Len)), (P) += (Len))
256 # define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
257 # define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
265 int _delta = width - _n; \
266 int _incr = _n + (_delta > 0 ? _delta : 0); \
267 if ((size_t) _incr >= maxsize - i) \
273 if (pad == L_('0')) \
274 memset_zero (p, _delta); \
276 memset_space (p, _delta); \
287 memcpy_lowcase (p, (s), _n LOCALE_ARG); \
288 else if (to_uppcase) \
289 memcpy_uppcase (p, (s), _n LOCALE_ARG); \
291 MEMCPY ((PTR) p, (const PTR) (s), _n))
294 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
295 # undef __mbsrtowcs_l
296 # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
298 # define widen(os, ws, l) \
301 const char *__s = os; \
302 memset (&__st, '\0', sizeof (__st)); \
303 l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
304 ws = (wchar_t *) alloca ((l + 1) * sizeof (wchar_t)); \
305 (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
310 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
311 /* We use this code also for the extended locale handling where the
312 function gets as an additional argument the locale which has to be
313 used. To access the values we have to redefine the _NL_CURRENT
315 # define strftime __strftime_l
316 # define wcsftime __wcsftime_l
318 # define _NL_CURRENT(category, item) \
319 (current->values[_NL_ITEM_INDEX (item)].string)
320 # define LOCALE_PARAM , loc
321 # define LOCALE_ARG , loc
322 # define LOCALE_PARAM_DECL __locale_t loc;
323 # define LOCALE_PARAM_PROTO , __locale_t loc
324 # define HELPER_LOCALE_ARG , current
326 # define LOCALE_PARAM
327 # define LOCALE_PARAM_PROTO
329 # define LOCALE_PARAM_DECL
331 # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
333 # define HELPER_LOCALE_ARG
338 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
339 # define TOUPPER(Ch, L) __towupper_l (Ch, L)
340 # define TOLOWER(Ch, L) __towlower_l (Ch, L)
342 # define TOUPPER(Ch, L) towupper (Ch)
343 # define TOLOWER(Ch, L) towlower (Ch)
347 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
348 # define TOUPPER(Ch, L) __toupper_l (Ch, L)
349 # define TOLOWER(Ch, L) __tolower_l (Ch, L)
351 # define TOUPPER(Ch, L) toupper (Ch)
352 # define TOLOWER(Ch, L) tolower (Ch)
355 # define TOUPPER(Ch, L) (islower (Ch) ? toupper (Ch) : (Ch))
356 # define TOLOWER(Ch, L) (isupper (Ch) ? tolower (Ch) : (Ch))
359 /* We don't use `isdigit' here since the locale dependent
360 interpretation is not what we want here. We only need to accept
361 the arabic digits in the ASCII range. One day there is perhaps a
362 more reliable way to accept other sets of digits. */
363 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
365 static CHAR_T *memcpy_lowcase __P ((CHAR_T *dest, const CHAR_T *src,
366 size_t len LOCALE_PARAM_PROTO));
369 memcpy_lowcase (dest, src, len LOCALE_PARAM)
376 dest[len] = TOLOWER ((UCHAR_T) src[len], loc);
380 static CHAR_T *memcpy_uppcase __P ((CHAR_T *dest, const CHAR_T *src,
381 size_t len LOCALE_PARAM_PROTO));
384 memcpy_uppcase (dest, src, len LOCALE_PARAM)
391 dest[len] = TOUPPER ((UCHAR_T) src[len], loc);
397 /* Yield the difference between *A and *B,
398 measured in seconds, ignoring leap seconds. */
399 # define tm_diff ftime_tm_diff
400 static int tm_diff __P ((const struct tm *, const struct tm *));
406 /* Compute intervening leap days correctly even if year is negative.
407 Take care to avoid int overflow in leap day calculations,
408 but it's OK to assume that A and B are close to each other. */
409 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
410 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
411 int a100 = a4 / 25 - (a4 % 25 < 0);
412 int b100 = b4 / 25 - (b4 % 25 < 0);
413 int a400 = a100 >> 2;
414 int b400 = b100 >> 2;
415 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
416 int years = a->tm_year - b->tm_year;
417 int days = (365 * years + intervening_leap_days
418 + (a->tm_yday - b->tm_yday));
419 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
420 + (a->tm_min - b->tm_min))
421 + (a->tm_sec - b->tm_sec));
423 #endif /* ! HAVE_TM_GMTOFF */
427 /* The number of days from the first day of the first ISO week of this
428 year to the year day YDAY with week day WDAY. ISO weeks start on
429 Monday; the first ISO week has the year's first Thursday. YDAY may
430 be as small as YDAY_MINIMUM. */
431 #define ISO_WEEK_START_WDAY 1 /* Monday */
432 #define ISO_WEEK1_WDAY 4 /* Thursday */
433 #define YDAY_MINIMUM (-366)
434 static int iso_week_days __P ((int, int));
439 iso_week_days (yday, wday)
443 /* Add enough to the first operand of % to make it nonnegative. */
444 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
446 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
447 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
451 #if !(defined _NL_CURRENT || HAVE_STRFTIME)
452 static CHAR_T const weekday_name[][10] =
454 L_("Sunday"), L_("Monday"), L_("Tuesday"), L_("Wednesday"),
455 L_("Thursday"), L_("Friday"), L_("Saturday")
457 static CHAR_T const month_name[][10] =
459 L_("January"), L_("February"), L_("March"), L_("April"), L_("May"),
460 L_("June"), L_("July"), L_("August"), L_("September"), L_("October"),
461 L_("November"), L_("December")
466 /* When compiling this file, GNU applications can #define my_strftime
467 to a symbol (typically nstrftime) to get an extended strftime with
468 extra arguments UT and NS. Emacs is a special case for now, but
469 this Emacs-specific code can be removed once Emacs's config.h
470 defines my_strftime. */
471 #if defined emacs && !defined my_strftime
472 # define my_strftime nstrftime
476 # define extra_args , ut, ns
477 # define extra_args_spec int ut; int ns;
478 # define extra_args_spec_iso , int ut, int ns
481 # define my_strftime wcsftime
482 # define nl_get_alt_digit _nl_get_walt_digit
484 # define my_strftime strftime
485 # define nl_get_alt_digit _nl_get_alt_digit
488 # define extra_args_spec
489 # define extra_args_spec_iso
490 /* We don't have this information in general. */
495 #if ! defined _LIBC && ! HAVE_RUN_TZSET_TEST
496 /* Solaris 2.5.x and 2.6 tzset sometimes modify the storage returned
497 by localtime. On such systems, we must use the tzset and localtime
498 wrappers to work around the bug. */
499 "you must run the autoconf test for a working tzset function"
503 /* Write information from TP into S according to the format
504 string FORMAT, writing no more that MAXSIZE characters
505 (including the terminating '\0') and returning number of
506 characters written. If S is NULL, nothing will be written
507 anywhere, so to determine how many characters would be
508 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
510 my_strftime (s, maxsize, format, tp extra_args LOCALE_PARAM)
513 const CHAR_T *format;
518 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
519 struct locale_data *const current = loc->__locales[LC_TIME];
522 int hour12 = tp->tm_hour;
524 /* We cannot make the following values variables since we must delay
525 the evaluation of these values until really needed since some
526 expressions might not be valid in every situation. The `struct tm'
527 might be generated by a strptime() call that initialized
528 only a few elements. Dereference the pointers only if the format
529 requires this. Then it is ok to fail if the pointers are invalid. */
531 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
533 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
535 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
537 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
539 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
540 ? NLW(PM_STR) : NLW(AM_STR)))
542 # define aw_len STRLEN (a_wkday)
543 # define am_len STRLEN (a_month)
544 # define ap_len STRLEN (ampm)
547 # define f_wkday (weekday_name[tp->tm_wday])
548 # define f_month (month_name[tp->tm_mon])
549 # define a_wkday f_wkday
550 # define a_month f_month
551 # define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
562 #if DO_MULTIBYTE && !defined COMPILE_WIDE
563 const char *format_end = NULL;
568 /* The POSIX test suite assumes that setting
569 the environment variable TZ to a new value before calling strftime()
570 will influence the result (the %Z format) even if the information in
571 TP is computed with a totally different time zone.
572 This is bogus: though POSIX allows bad behavior like this,
573 POSIX does not require it. Do the right thing instead. */
574 zone = (const char *) tp->tm_zone;
579 if (! (zone && *zone))
584 /* POSIX.1 requires that local time zone information be used as
585 though strftime called tzset. */
598 for (f = format; *f != '\0'; ++f)
600 int pad = 0; /* Padding for number ('-', '_', or 0). */
601 int modifier; /* Field modifier ('E', 'O', or 0). */
602 int digits; /* Max digits for numeric format. */
603 int number_value; /* Numeric value to be printed. */
604 int negative_number; /* 1 if the number is negative. */
605 const CHAR_T *subfmt;
607 CHAR_T buf[1 + (sizeof (int) < sizeof (time_t)
608 ? INT_STRLEN_BOUND (time_t)
609 : INT_STRLEN_BOUND (int))];
616 #if DO_MULTIBYTE && !defined COMPILE_WIDE
622 case L_('\b'): case L_('\t'): case L_('\n'):
623 case L_('\v'): case L_('\f'): case L_('\r'):
624 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
625 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
626 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
627 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
628 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
629 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
630 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
631 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
632 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
633 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
634 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
635 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
636 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
637 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
638 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
639 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
640 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
641 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
643 /* The C Standard requires these 98 characters (plus '%') to
644 be in the basic execution character set. None of these
645 characters can start a multibyte sequence, so they need
646 not be analyzed further. */
651 /* Copy this multibyte sequence until we reach its end, find
652 an error, or come back to the initial shift state. */
654 mbstate_t mbstate = mbstate_zero;
659 format_end = f + strlen (f) + 1;
660 fsize = format_end - f;
664 size_t bytes = mbrlen (f + len, fsize - len, &mbstate);
669 if (bytes == (size_t) -2)
671 len += strlen (f + len);
675 if (bytes == (size_t) -1)
683 while (! mbsinit (&mbstate));
691 #else /* ! DO_MULTIBYTE */
693 /* Either multibyte encodings are not supported, they are
694 safe for formats, so any non-'%' byte can be copied through,
695 or this is the wide character version. */
702 #endif /* ! DO_MULTIBYTE */
704 /* Check for flags that can modify a format. */
709 /* This influences the number formats. */
716 /* This changes textual output. */
730 /* As a GNU extension we allow to specify the field width. */
736 if (width > INT_MAX / 10
737 || (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10))
738 /* Avoid overflow. */
743 width += *f - L_('0');
747 while (ISDIGIT (*f));
750 /* Check for modifiers. */
763 /* Now do the specified format. */
767 #define DO_NUMBER(d, v) \
768 digits = d > width ? d : width; \
769 number_value = v; goto do_number
770 #define DO_NUMBER_SPACEPAD(d, v) \
771 digits = d > width ? d : width; \
772 number_value = v; goto do_number_spacepad
788 #if defined _NL_CURRENT || !HAVE_STRFTIME
789 cpy (aw_len, a_wkday);
792 goto underlying_strftime;
803 #if defined _NL_CURRENT || !HAVE_STRFTIME
804 cpy (STRLEN (f_wkday), f_wkday);
807 goto underlying_strftime;
819 #if defined _NL_CURRENT || !HAVE_STRFTIME
820 cpy (am_len, a_month);
823 goto underlying_strftime;
834 #if defined _NL_CURRENT || !HAVE_STRFTIME
835 cpy (STRLEN (f_month), f_month);
838 goto underlying_strftime;
842 if (modifier == L_('O'))
845 if (! (modifier == 'E'
847 (const CHAR_T *) _NL_CURRENT (LC_TIME,
850 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
853 goto underlying_strftime;
855 subfmt = L_("%a %b %e %H:%M:%S %Y");
861 CHAR_T *old_start = p;
862 size_t len = my_strftime (NULL, (size_t) -1, subfmt,
863 tp extra_args LOCALE_ARG);
864 add (len, my_strftime (p, maxsize - i, subfmt,
865 tp extra_args LOCALE_ARG));
868 while (old_start < p)
870 *old_start = TOUPPER ((UCHAR_T) *old_start, loc);
876 #if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
879 /* The relevant information is available only via the
880 underlying strftime implementation, so use that. */
883 char ubuf[1024]; /* enough for any single format in practice */
885 /* Make sure we're calling the actual underlying strftime.
886 In some cases, config.h contains something like
887 "#define strftime rpl_strftime". */
898 len = strftime (ubuf, sizeof ubuf, ufmt, tp);
899 if (len == 0 && ubuf[0] != '\0')
907 if (modifier == L_('O'))
909 if (modifier == L_('E'))
911 #if HAVE_STRUCT_ERA_ENTRY
912 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
916 size_t len = __wcslen (era->era_wname);
917 cpy (len, era->era_wname);
919 size_t len = strlen (era->era_name);
920 cpy (len, era->era_name);
926 goto underlying_strftime;
932 int year = tp->tm_year + TM_YEAR_BASE;
933 DO_NUMBER (1, year / 100 - (year % 100 < 0));
937 if (modifier == L_('O'))
940 if (! (modifier == L_('E')
942 (const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT)))
944 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
948 goto underlying_strftime;
956 subfmt = L_("%m/%d/%y");
960 if (modifier == L_('E'))
963 DO_NUMBER (2, tp->tm_mday);
966 if (modifier == L_('E'))
969 DO_NUMBER_SPACEPAD (2, tp->tm_mday);
971 /* All numeric formats set DIGITS and NUMBER_VALUE and then
972 jump to one of these two labels. */
975 /* Force `_' flag unless overridden by `0' or `-' flag. */
976 if (pad != L_('0') && pad != L_('-'))
980 /* Format the number according to the MODIFIER flag. */
982 if (modifier == L_('O') && 0 <= number_value)
985 /* Get the locale specific alternate representation of
986 the number NUMBER_VALUE. If none exist NULL is returned. */
987 const CHAR_T *cp = nl_get_alt_digit (number_value
992 size_t digitlen = STRLEN (cp);
1001 goto underlying_strftime;
1006 unsigned int u = number_value;
1008 bufp = buf + sizeof (buf) / sizeof (buf[0]);
1009 negative_number = number_value < 0;
1011 if (negative_number)
1015 *--bufp = u % 10 + L_('0');
1016 while ((u /= 10) != 0);
1019 do_number_sign_and_padding:
1020 if (negative_number)
1025 int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
1032 if ((size_t) padding >= maxsize - i)
1036 memset_space (p, padding);
1038 width = width > padding ? width - padding : 0;
1042 if ((size_t) digits >= maxsize - i)
1045 if (negative_number)
1055 memset_zero (p, padding);
1062 cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
1068 subfmt = L_("%Y-%m-%d");
1072 if (modifier == L_('E'))
1075 DO_NUMBER (2, tp->tm_hour);
1078 if (modifier == L_('E'))
1081 DO_NUMBER (2, hour12);
1083 case L_('k'): /* GNU extension. */
1084 if (modifier == L_('E'))
1087 DO_NUMBER_SPACEPAD (2, tp->tm_hour);
1089 case L_('l'): /* GNU extension. */
1090 if (modifier == L_('E'))
1093 DO_NUMBER_SPACEPAD (2, hour12);
1096 if (modifier == L_('E'))
1099 DO_NUMBER (3, 1 + tp->tm_yday);
1102 if (modifier == L_('E'))
1105 DO_NUMBER (2, tp->tm_min);
1108 if (modifier == L_('E'))
1111 DO_NUMBER (2, tp->tm_mon + 1);
1114 case L_('N'): /* GNU extension. */
1115 if (modifier == L_('E'))
1121 /* Take an explicit width less than 9 as a precision. */
1123 for (j = width; j < 9; j++)
1127 DO_NUMBER (9, number_value);
1131 add (1, *p = L_('\n'));
1136 #if !defined _NL_CURRENT && HAVE_STRFTIME
1137 format_char = L_('p');
1147 #if defined _NL_CURRENT || !HAVE_STRFTIME
1151 goto underlying_strftime;
1155 subfmt = L_("%H:%M");
1159 #if !defined _NL_CURRENT && HAVE_STRFTIME
1160 goto underlying_strftime;
1163 if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME,
1167 subfmt = L_("%I:%M:%S %p");
1172 if (modifier == L_('E'))
1175 DO_NUMBER (2, tp->tm_sec);
1177 case L_('s'): /* GNU extension. */
1185 /* Generate string value for T using time_t arithmetic;
1186 this works even if sizeof (long) < sizeof (time_t). */
1188 bufp = buf + sizeof (buf) / sizeof (buf[0]);
1189 negative_number = t < 0;
1196 if (negative_number)
1200 /* Adjust if division truncates to minus infinity. */
1201 if (0 < -1 % 10 && d < 0)
1208 *--bufp = d + L_('0');
1213 goto do_number_sign_and_padding;
1217 if (modifier == L_('O'))
1220 if (! (modifier == L_('E')
1222 (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT)))
1224 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
1228 goto underlying_strftime;
1234 subfmt = L_("%H:%M:%S");
1238 add (1, *p = L_('\t'));
1242 DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
1245 if (modifier == L_('E'))
1248 DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
1253 if (modifier == L_('E'))
1256 int year = tp->tm_year + TM_YEAR_BASE;
1257 int days = iso_week_days (tp->tm_yday, tp->tm_wday);
1261 /* This ISO week belongs to the previous year. */
1263 days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
1268 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
1272 /* This ISO week belongs to the next year. */
1281 DO_NUMBER (2, (year % 100 + 100) % 100);
1284 DO_NUMBER (1, year);
1287 DO_NUMBER (2, days / 7 + 1);
1292 if (modifier == L_('E'))
1295 DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
1298 if (modifier == L_('E'))
1301 DO_NUMBER (1, tp->tm_wday);
1304 if (modifier == 'E')
1306 #if HAVE_STRUCT_ERA_ENTRY
1307 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1310 # ifdef COMPILE_WIDE
1311 subfmt = era->era_wformat;
1313 subfmt = era->era_format;
1319 goto underlying_strftime;
1323 if (modifier == L_('O'))
1326 DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
1329 if (modifier == L_('E'))
1331 #if HAVE_STRUCT_ERA_ENTRY
1332 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1335 int delta = tp->tm_year - era->start_date[0];
1336 DO_NUMBER (1, (era->offset
1337 + delta * era->absolute_direction));
1341 goto underlying_strftime;
1345 DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
1355 /* The tzset() call might have changed the value. */
1356 if (!(zone && *zone) && tp->tm_isdst >= 0)
1357 zone = tzname[tp->tm_isdst];
1364 /* The zone string is always given in multibyte form. We have
1365 to transform it first. */
1368 widen (zone, wczone, len);
1372 cpy (strlen (zone), zone);
1377 if (tp->tm_isdst < 0)
1383 diff = tp->tm_gmtoff;
1396 if (lt == (time_t) -1)
1398 /* mktime returns -1 for errors, but -1 is also a
1399 valid time_t value. Check whether an error really
1403 if (! my_strftime_localtime_r (<, &tm)
1404 || ((ltm.tm_sec ^ tm.tm_sec)
1405 | (ltm.tm_min ^ tm.tm_min)
1406 | (ltm.tm_hour ^ tm.tm_hour)
1407 | (ltm.tm_mday ^ tm.tm_mday)
1408 | (ltm.tm_mon ^ tm.tm_mon)
1409 | (ltm.tm_year ^ tm.tm_year)))
1413 if (! my_strftime_gmtime_r (<, >m))
1416 diff = tm_diff (<m, >m);
1422 add (1, *p = L_('-'));
1426 add (1, *p = L_('+'));
1429 DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
1432 case L_('\0'): /* GNU extension: % at end of format. */
1436 /* Unknown format; output the format, including the '%',
1437 since this is most likely the right thing to do if a
1438 multibyte string has been misparsed. */
1442 for (flen = 1; f[1 - flen] != L_('%'); flen++)
1444 cpy (flen, &f[1 - flen]);
1450 if (p && maxsize != 0)
1455 libc_hidden_def (my_strftime)
1460 /* For Emacs we have a separate interface which corresponds to the normal
1461 strftime function plus the ut argument, but without the ns argument. */
1463 emacs_strftimeu (s, maxsize, format, tp, ut)
1467 const struct tm *tp;
1470 return my_strftime (s, maxsize, format, tp, ut, 0);