1 /* Copyright (C) 2002-2015 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
23 # define USE_IN_EXTENDED_LOCALE_MODEL 1
24 # define HAVE_LIMITS_H 1
26 # define HAVE_MBRLEN 1
27 # define HAVE_STRUCT_ERA_ENTRY 1
28 # define HAVE_TM_GMTOFF 1
29 # define HAVE_TM_ZONE 1
30 # define HAVE_TZNAME 1
32 # define HAVE_STRFTIME 0
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
;
90 # define memcpy(d, s, n) bcopy ((s), (d), (n))
96 # define CHAR_T wchar_t
97 # define UCHAR_T unsigned int
98 # define L_(Str) L##Str
99 # define NLW(Sym) _NL_W##Sym
101 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
102 # define STRLEN(s) __wcslen (s)
106 # define UCHAR_T unsigned char
108 # define NLW(Sym) Sym
110 # if !defined STDC_HEADERS && !defined HAVE_MEMCPY
111 # define MEMCPY(d, s, n) bcopy ((s), (d), (n))
113 # define MEMCPY(d, s, n) memcpy ((d), (s), (n))
115 # define STRLEN(s) strlen (s)
118 # define MEMPCPY(d, s, n) __mempcpy (d, s, n)
120 # ifndef HAVE_MEMPCPY
121 # define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n)))
138 #define TYPE_SIGNED(t) ((t) -1 < 0)
140 /* Bound on length of the string representing an integer value of type t.
141 Subtract one for the sign bit if t is signed;
142 302 / 1000 is log10 (2) rounded up;
143 add one for integer division truncation;
144 add one more for a minus sign if t is signed. */
145 #define INT_STRLEN_BOUND(t) \
146 ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 + 1 + TYPE_SIGNED (t))
148 #define TM_YEAR_BASE 1900
151 /* Nonzero if YEAR is a leap year (every 4 years,
152 except every 100th isn't, and every 400th is). */
153 # define __isleap(year) \
154 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
159 # define tzname __tzname
160 # define tzset __tzset
164 /* Portable standalone applications should supply a "time_r.h" that
165 declares a POSIX-compliant localtime_r, for the benefit of older
166 implementations that lack localtime_r or have a nonstandard one.
167 Similarly for gmtime_r. See the gnulib time_r module for one way
168 to implement this. */
171 # undef __localtime_r
172 # define __gmtime_r gmtime_r
173 # define __localtime_r localtime_r
177 #if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
178 /* Some systems lack the `memset' function and we don't want to
179 introduce additional dependencies. */
180 /* The SGI compiler reportedly barfs on the trailing null
181 if we use a string constant as the initializer. 28 June 1997, rms. */
182 static const CHAR_T spaces
[16] = /* " " */
184 L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),
185 L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' ')
187 static const CHAR_T zeroes
[16] = /* "0000000000000000" */
189 L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),
190 L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0')
193 # define memset_space(P, Len) \
199 int _this = _len > 16 ? 16 : _len; \
200 (P) = MEMPCPY ((P), spaces, _this * sizeof (CHAR_T)); \
206 # define memset_zero(P, Len) \
212 int _this = _len > 16 ? 16 : _len; \
213 (P) = MEMPCPY ((P), zeroes, _this * sizeof (CHAR_T)); \
220 # define memset_space(P, Len) (wmemset ((P), L' ', (Len)), (P) += (Len))
221 # define memset_zero(P, Len) (wmemset ((P), L'0', (Len)), (P) += (Len))
223 # define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
224 # define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
232 int _delta = width - _n; \
233 int _incr = _n + (_delta > 0 ? _delta : 0); \
234 if ((size_t) _incr >= maxsize - i) \
240 if (pad == L_('0')) \
241 memset_zero (p, _delta); \
243 memset_space (p, _delta); \
254 memcpy_lowcase (p, (s), _n LOCALE_ARG); \
255 else if (to_uppcase) \
256 memcpy_uppcase (p, (s), _n LOCALE_ARG); \
258 MEMCPY ((PTR) p, (const PTR) (s), _n))
261 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
262 # undef __mbsrtowcs_l
263 # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
265 # define widen(os, ws, l) \
268 const char *__s = os; \
269 memset (&__st, '\0', sizeof (__st)); \
270 l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
271 ws = alloca ((l + 1) * sizeof (wchar_t)); \
272 (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
277 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
278 /* We use this code also for the extended locale handling where the
279 function gets as an additional argument the locale which has to be
280 used. To access the values we have to redefine the _NL_CURRENT
282 # define strftime __strftime_l
283 # define wcsftime __wcsftime_l
285 # define _NL_CURRENT(category, item) \
286 (current->values[_NL_ITEM_INDEX (item)].string)
287 # define LOCALE_PARAM , loc
288 # define LOCALE_ARG , loc
289 # define LOCALE_PARAM_DECL __locale_t loc;
290 # define LOCALE_PARAM_PROTO , __locale_t loc
291 # define HELPER_LOCALE_ARG , current
293 # define LOCALE_PARAM
294 # define LOCALE_PARAM_PROTO
296 # define LOCALE_PARAM_DECL
298 # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
300 # define HELPER_LOCALE_ARG
305 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
306 # define TOUPPER(Ch, L) __towupper_l (Ch, L)
307 # define TOLOWER(Ch, L) __towlower_l (Ch, L)
309 # define TOUPPER(Ch, L) towupper (Ch)
310 # define TOLOWER(Ch, L) towlower (Ch)
314 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
315 # define TOUPPER(Ch, L) __toupper_l (Ch, L)
316 # define TOLOWER(Ch, L) __tolower_l (Ch, L)
318 # define TOUPPER(Ch, L) toupper (Ch)
319 # define TOLOWER(Ch, L) tolower (Ch)
322 # define TOUPPER(Ch, L) (islower (Ch) ? toupper (Ch) : (Ch))
323 # define TOLOWER(Ch, L) (isupper (Ch) ? tolower (Ch) : (Ch))
326 /* We don't use `isdigit' here since the locale dependent
327 interpretation is not what we want here. We only need to accept
328 the arabic digits in the ASCII range. One day there is perhaps a
329 more reliable way to accept other sets of digits. */
330 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
332 static CHAR_T
*memcpy_lowcase (CHAR_T
*dest
, const CHAR_T
*src
,
333 size_t len LOCALE_PARAM_PROTO
) __THROW
;
336 memcpy_lowcase (dest
, src
, len LOCALE_PARAM
)
343 dest
[len
] = TOLOWER ((UCHAR_T
) src
[len
], loc
);
347 static CHAR_T
*memcpy_uppcase (CHAR_T
*dest
, const CHAR_T
*src
,
348 size_t len LOCALE_PARAM_PROTO
) __THROW
;
351 memcpy_uppcase (dest
, src
, len LOCALE_PARAM
)
358 dest
[len
] = TOUPPER ((UCHAR_T
) src
[len
], loc
);
364 /* Yield the difference between *A and *B,
365 measured in seconds, ignoring leap seconds. */
366 # define tm_diff ftime_tm_diff
367 static int tm_diff (const struct tm
*, const struct tm
*) __THROW
;
369 tm_diff (const struct tm
*a
, const struct tm
*b
)
371 /* Compute intervening leap days correctly even if year is negative.
372 Take care to avoid int overflow in leap day calculations,
373 but it's OK to assume that A and B are close to each other. */
374 int a4
= (a
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (a
->tm_year
& 3);
375 int b4
= (b
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (b
->tm_year
& 3);
376 int a100
= a4
/ 25 - (a4
% 25 < 0);
377 int b100
= b4
/ 25 - (b4
% 25 < 0);
378 int a400
= a100
>> 2;
379 int b400
= b100
>> 2;
380 int intervening_leap_days
= (a4
- b4
) - (a100
- b100
) + (a400
- b400
);
381 int years
= a
->tm_year
- b
->tm_year
;
382 int days
= (365 * years
+ intervening_leap_days
383 + (a
->tm_yday
- b
->tm_yday
));
384 return (60 * (60 * (24 * days
+ (a
->tm_hour
- b
->tm_hour
))
385 + (a
->tm_min
- b
->tm_min
))
386 + (a
->tm_sec
- b
->tm_sec
));
388 #endif /* ! HAVE_TM_GMTOFF */
392 /* The number of days from the first day of the first ISO week of this
393 year to the year day YDAY with week day WDAY. ISO weeks start on
394 Monday; the first ISO week has the year's first Thursday. YDAY may
395 be as small as YDAY_MINIMUM. */
396 #define ISO_WEEK_START_WDAY 1 /* Monday */
397 #define ISO_WEEK1_WDAY 4 /* Thursday */
398 #define YDAY_MINIMUM (-366)
399 static int iso_week_days (int, int) __THROW
;
404 iso_week_days (int yday
, int wday
)
406 /* Add enough to the first operand of % to make it nonnegative. */
407 int big_enough_multiple_of_7
= (-YDAY_MINIMUM
/ 7 + 2) * 7;
409 - (yday
- wday
+ ISO_WEEK1_WDAY
+ big_enough_multiple_of_7
) % 7
410 + ISO_WEEK1_WDAY
- ISO_WEEK_START_WDAY
);
414 #if !(defined _NL_CURRENT || HAVE_STRFTIME)
415 static CHAR_T
const weekday_name
[][10] =
417 L_("Sunday"), L_("Monday"), L_("Tuesday"), L_("Wednesday"),
418 L_("Thursday"), L_("Friday"), L_("Saturday")
420 static CHAR_T
const month_name
[][10] =
422 L_("January"), L_("February"), L_("March"), L_("April"), L_("May"),
423 L_("June"), L_("July"), L_("August"), L_("September"), L_("October"),
424 L_("November"), L_("December")
430 # define my_strftime emacs_strftimeu
431 # define ut_argument , ut
432 # define ut_argument_spec int ut;
433 # define ut_argument_spec_iso , int ut
436 # define my_strftime wcsftime
437 # define nl_get_alt_digit _nl_get_walt_digit
439 # define my_strftime strftime
440 # define nl_get_alt_digit _nl_get_alt_digit
443 # define ut_argument_spec
444 # define ut_argument_spec_iso
445 /* We don't have this information in general. */
449 static size_t __strftime_internal (CHAR_T
*, size_t, const CHAR_T
*,
450 const struct tm
*, bool *
452 LOCALE_PARAM_PROTO
) __THROW
;
454 /* Write information from TP into S according to the format
455 string FORMAT, writing no more that MAXSIZE characters
456 (including the terminating '\0') and returning number of
457 characters written. If S is NULL, nothing will be written
458 anywhere, so to determine how many characters would be
459 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
462 my_strftime (s
, maxsize
, format
, tp ut_argument LOCALE_PARAM
)
465 const CHAR_T
*format
;
470 #if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
471 /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
472 Work around this bug by copying *tp before it might be munged. */
477 bool tzset_called
= false;
478 return __strftime_internal (s
, maxsize
, format
, tp
, &tzset_called
479 ut_argument LOCALE_ARG
);
482 libc_hidden_def (my_strftime
)
486 __strftime_internal (s
, maxsize
, format
, tp
, tzset_called ut_argument
490 const CHAR_T
*format
;
496 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
497 struct __locale_data
*const current
= loc
->__locales
[LC_TIME
];
500 int hour12
= tp
->tm_hour
;
502 /* We cannot make the following values variables since we must delay
503 the evaluation of these values until really needed since some
504 expressions might not be valid in every situation. The `struct tm'
505 might be generated by a strptime() call that initialized
506 only a few elements. Dereference the pointers only if the format
507 requires this. Then it is ok to fail if the pointers are invalid. */
509 ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \
510 ? "?" : _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday)))
512 ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \
513 ? "?" : _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday)))
515 ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \
516 ? "?" : _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon)))
518 ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \
519 ? "?" : _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon)))
521 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
522 ? NLW(PM_STR) : NLW(AM_STR)))
524 # define aw_len STRLEN (a_wkday)
525 # define am_len STRLEN (a_month)
526 # define ap_len STRLEN (ampm)
529 # define f_wkday (tp->tm_wday < 0 || tp->tm_wday > 6 \
530 ? "?" : weekday_name[tp->tm_wday])
531 # define f_month (tp->tm_mon < 0 || tp->tm_mon > 11 \
532 ? "?" : month_name[tp->tm_mon])
533 # define a_wkday f_wkday
534 # define a_month f_month
535 # define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
546 #if DO_MULTIBYTE && !defined COMPILE_WIDE
547 const char *format_end
= NULL
;
552 /* The POSIX test suite assumes that setting
553 the environment variable TZ to a new value before calling strftime()
554 will influence the result (the %Z format) even if the information in
555 TP is computed with a totally different time zone.
556 This is bogus: though POSIX allows bad behavior like this,
557 POSIX does not require it. Do the right thing instead. */
558 zone
= (const char *) tp
->tm_zone
;
563 if (! (zone
&& *zone
))
574 for (f
= format
; *f
!= '\0'; ++f
)
576 int pad
= 0; /* Padding for number ('-', '_', or 0). */
577 int modifier
; /* Field modifier ('E', 'O', or 0). */
578 int digits
; /* Max digits for numeric format. */
579 int number_value
; /* Numeric value to be printed. */
580 int negative_number
; /* 1 if the number is negative. */
581 const CHAR_T
*subfmt
;
583 CHAR_T buf
[1 + (sizeof (int) < sizeof (time_t)
584 ? INT_STRLEN_BOUND (time_t)
585 : INT_STRLEN_BOUND (int))];
592 #if DO_MULTIBYTE && !defined COMPILE_WIDE
598 case L_('\b'): case L_('\t'): case L_('\n'):
599 case L_('\v'): case L_('\f'): case L_('\r'):
600 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
601 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
602 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
603 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
604 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
605 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
606 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
607 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
608 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
609 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
610 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
611 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
612 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
613 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
614 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
615 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
616 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
617 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
619 /* The C Standard requires these 98 characters (plus '%') to
620 be in the basic execution character set. None of these
621 characters can start a multibyte sequence, so they need
622 not be analyzed further. */
627 /* Copy this multibyte sequence until we reach its end, find
628 an error, or come back to the initial shift state. */
630 mbstate_t mbstate
= mbstate_zero
;
635 format_end
= f
+ strlen (f
) + 1;
636 fsize
= format_end
- f
;
640 size_t bytes
= mbrlen (f
+ len
, fsize
- len
, &mbstate
);
645 if (bytes
== (size_t) -2)
647 len
+= strlen (f
+ len
);
651 if (bytes
== (size_t) -1)
659 while (! mbsinit (&mbstate
));
667 #else /* ! DO_MULTIBYTE */
669 /* Either multibyte encodings are not supported, they are
670 safe for formats, so any non-'%' byte can be copied through,
671 or this is the wide character version. */
678 #endif /* ! DO_MULTIBYTE */
680 /* Check for flags that can modify a format. */
685 /* This influences the number formats. */
692 /* This changes textual output. */
706 /* As a GNU extension we allow to specify the field width. */
712 if (width
> INT_MAX
/ 10
713 || (width
== INT_MAX
/ 10 && *f
- L_('0') > INT_MAX
% 10))
714 /* Avoid overflow. */
719 width
+= *f
- L_('0');
723 while (ISDIGIT (*f
));
726 /* Check for modifiers. */
739 /* Now do the specified format. */
743 #define DO_NUMBER(d, v) \
744 digits = d > width ? d : width; \
745 number_value = v; goto do_number
746 #define DO_NUMBER_SPACEPAD(d, v) \
747 digits = d > width ? d : width; \
748 number_value = v; goto do_number_spacepad
764 #if defined _NL_CURRENT || !HAVE_STRFTIME
765 cpy (aw_len
, a_wkday
);
768 goto underlying_strftime
;
779 #if defined _NL_CURRENT || !HAVE_STRFTIME
780 cpy (STRLEN (f_wkday
), f_wkday
);
783 goto underlying_strftime
;
795 #if defined _NL_CURRENT || !HAVE_STRFTIME
796 cpy (am_len
, a_month
);
799 goto underlying_strftime
;
810 #if defined _NL_CURRENT || !HAVE_STRFTIME
811 cpy (STRLEN (f_month
), f_month
);
814 goto underlying_strftime
;
818 if (modifier
== L_('O'))
821 if (! (modifier
== 'E'
823 (const CHAR_T
*) _NL_CURRENT (LC_TIME
,
826 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(D_T_FMT
));
829 goto underlying_strftime
;
831 subfmt
= L_("%a %b %e %H:%M:%S %Y");
837 CHAR_T
*old_start
= p
;
838 size_t len
= __strftime_internal (NULL
, (size_t) -1, subfmt
,
839 tp
, tzset_called ut_argument
841 add (len
, __strftime_internal (p
, maxsize
- i
, subfmt
,
842 tp
, tzset_called ut_argument
846 while (old_start
< p
)
848 *old_start
= TOUPPER ((UCHAR_T
) *old_start
, loc
);
854 #if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
857 /* The relevant information is available only via the
858 underlying strftime implementation, so use that. */
861 char ubuf
[1024]; /* enough for any single format in practice */
863 /* Make sure we're calling the actual underlying strftime.
864 In some cases, config.h contains something like
865 "#define strftime rpl_strftime". */
876 len
= strftime (ubuf
, sizeof ubuf
, ufmt
, tp
);
877 if (len
== 0 && ubuf
[0] != '\0')
885 if (modifier
== L_('E'))
887 #if HAVE_STRUCT_ERA_ENTRY
888 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
892 size_t len
= __wcslen (era
->era_wname
);
893 cpy (len
, era
->era_wname
);
895 size_t len
= strlen (era
->era_name
);
896 cpy (len
, era
->era_name
);
902 goto underlying_strftime
;
908 int year
= tp
->tm_year
+ TM_YEAR_BASE
;
909 DO_NUMBER (1, year
/ 100 - (year
% 100 < 0));
913 if (modifier
== L_('O'))
916 if (! (modifier
== L_('E')
918 (const CHAR_T
*)_NL_CURRENT (LC_TIME
, NLW(ERA_D_FMT
)))
920 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(D_FMT
));
924 goto underlying_strftime
;
932 subfmt
= L_("%m/%d/%y");
936 if (modifier
== L_('E'))
939 DO_NUMBER (2, tp
->tm_mday
);
942 if (modifier
== L_('E'))
945 DO_NUMBER_SPACEPAD (2, tp
->tm_mday
);
947 /* All numeric formats set DIGITS and NUMBER_VALUE and then
948 jump to one of these two labels. */
951 /* Force `_' flag unless overwritten by `0' or '-' flag. */
952 if (pad
!= L_('0') && pad
!= L_('-'))
956 /* Format the number according to the MODIFIER flag. */
958 if (modifier
== L_('O') && 0 <= number_value
)
961 /* Get the locale specific alternate representation of
962 the number NUMBER_VALUE. If none exist NULL is returned. */
963 const CHAR_T
*cp
= nl_get_alt_digit (number_value
968 size_t digitlen
= STRLEN (cp
);
977 goto underlying_strftime
;
982 unsigned int u
= number_value
;
984 bufp
= buf
+ sizeof (buf
) / sizeof (buf
[0]);
985 negative_number
= number_value
< 0;
991 *--bufp
= u
% 10 + L_('0');
992 while ((u
/= 10) != 0);
995 do_number_sign_and_padding
:
1001 int padding
= digits
- (buf
+ (sizeof (buf
) / sizeof (buf
[0]))
1008 if ((size_t) padding
>= maxsize
- i
)
1012 memset_space (p
, padding
);
1014 width
= width
> padding
? width
- padding
: 0;
1018 if ((size_t) digits
>= maxsize
- i
)
1021 if (negative_number
)
1031 memset_zero (p
, padding
);
1038 cpy (buf
+ sizeof (buf
) / sizeof (buf
[0]) - bufp
, bufp
);
1044 subfmt
= L_("%Y-%m-%d");
1048 if (modifier
== L_('E'))
1051 DO_NUMBER (2, tp
->tm_hour
);
1054 if (modifier
== L_('E'))
1057 DO_NUMBER (2, hour12
);
1059 case L_('k'): /* GNU extension. */
1060 if (modifier
== L_('E'))
1063 DO_NUMBER_SPACEPAD (2, tp
->tm_hour
);
1065 case L_('l'): /* GNU extension. */
1066 if (modifier
== L_('E'))
1069 DO_NUMBER_SPACEPAD (2, hour12
);
1072 if (modifier
== L_('E'))
1075 DO_NUMBER (3, 1 + tp
->tm_yday
);
1078 if (modifier
== L_('E'))
1081 DO_NUMBER (2, tp
->tm_min
);
1084 if (modifier
== L_('E'))
1087 DO_NUMBER (2, tp
->tm_mon
+ 1);
1090 add (1, *p
= L_('\n'));
1095 #if !defined _NL_CURRENT && HAVE_STRFTIME
1096 format_char
= L_('p');
1106 #if defined _NL_CURRENT || !HAVE_STRFTIME
1110 goto underlying_strftime
;
1114 subfmt
= L_("%H:%M");
1118 #if !defined _NL_CURRENT && HAVE_STRFTIME
1119 goto underlying_strftime
;
1122 if (*(subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
,
1126 subfmt
= L_("%I:%M:%S %p");
1131 if (modifier
== L_('E'))
1134 DO_NUMBER (2, tp
->tm_sec
);
1136 case L_('s'): /* GNU extension. */
1144 /* Generate string value for T using time_t arithmetic;
1145 this works even if sizeof (long) < sizeof (time_t). */
1147 bufp
= buf
+ sizeof (buf
) / sizeof (buf
[0]);
1148 negative_number
= t
< 0;
1155 if (negative_number
)
1159 /* Adjust if division truncates to minus infinity. */
1160 if (0 < -1 % 10 && d
< 0)
1167 *--bufp
= d
+ L_('0');
1172 goto do_number_sign_and_padding
;
1176 if (modifier
== L_('O'))
1179 if (! (modifier
== L_('E')
1181 (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(ERA_T_FMT
)))
1183 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(T_FMT
));
1187 goto underlying_strftime
;
1193 subfmt
= L_("%H:%M:%S");
1197 add (1, *p
= L_('\t'));
1201 DO_NUMBER (1, (tp
->tm_wday
- 1 + 7) % 7 + 1);
1204 if (modifier
== L_('E'))
1207 DO_NUMBER (2, (tp
->tm_yday
- tp
->tm_wday
+ 7) / 7);
1212 if (modifier
== L_('E'))
1215 int year
= tp
->tm_year
+ TM_YEAR_BASE
;
1216 int days
= iso_week_days (tp
->tm_yday
, tp
->tm_wday
);
1220 /* This ISO week belongs to the previous year. */
1222 days
= iso_week_days (tp
->tm_yday
+ (365 + __isleap (year
)),
1227 int d
= iso_week_days (tp
->tm_yday
- (365 + __isleap (year
)),
1231 /* This ISO week belongs to the next year. */
1240 DO_NUMBER (2, (year
% 100 + 100) % 100);
1243 DO_NUMBER (1, year
);
1246 DO_NUMBER (2, days
/ 7 + 1);
1251 if (modifier
== L_('E'))
1254 DO_NUMBER (2, (tp
->tm_yday
- (tp
->tm_wday
- 1 + 7) % 7 + 7) / 7);
1257 if (modifier
== L_('E'))
1260 DO_NUMBER (1, tp
->tm_wday
);
1263 if (modifier
== 'E')
1265 #if HAVE_STRUCT_ERA_ENTRY
1266 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
1269 # ifdef COMPILE_WIDE
1270 subfmt
= era
->era_wformat
;
1272 subfmt
= era
->era_format
;
1278 goto underlying_strftime
;
1282 if (modifier
== L_('O'))
1285 DO_NUMBER (1, tp
->tm_year
+ TM_YEAR_BASE
);
1288 if (modifier
== L_('E'))
1290 #if HAVE_STRUCT_ERA_ENTRY
1291 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
1294 int delta
= tp
->tm_year
- era
->start_date
[0];
1295 DO_NUMBER (1, (era
->offset
1296 + delta
* era
->absolute_direction
));
1300 goto underlying_strftime
;
1304 DO_NUMBER (2, (tp
->tm_year
% 100 + 100) % 100);
1314 /* The tzset() call might have changed the value. */
1315 if (!(zone
&& *zone
) && tp
->tm_isdst
>= 0)
1317 /* POSIX.1 requires that local time zone information is used as
1318 though strftime called tzset. */
1323 *tzset_called
= true;
1326 zone
= tp
->tm_isdst
<= 1 ? tzname
[tp
->tm_isdst
] : "?";
1334 /* The zone string is always given in multibyte form. We have
1335 to transform it first. */
1338 widen (zone
, wczone
, len
);
1342 cpy (strlen (zone
), zone
);
1347 if (tp
->tm_isdst
< 0)
1353 diff
= tp
->tm_gmtoff
;
1363 /* POSIX.1 requires that local time zone information is used as
1364 though strftime called tzset. */
1369 *tzset_called
= true;
1376 if (lt
== (time_t) -1)
1378 /* mktime returns -1 for errors, but -1 is also a
1379 valid time_t value. Check whether an error really
1383 if (! __localtime_r (<
, &tm
)
1384 || ((ltm
.tm_sec
^ tm
.tm_sec
)
1385 | (ltm
.tm_min
^ tm
.tm_min
)
1386 | (ltm
.tm_hour
^ tm
.tm_hour
)
1387 | (ltm
.tm_mday
^ tm
.tm_mday
)
1388 | (ltm
.tm_mon
^ tm
.tm_mon
)
1389 | (ltm
.tm_year
^ tm
.tm_year
)))
1393 if (! __gmtime_r (<
, >m
))
1396 diff
= tm_diff (<m
, >m
);
1402 add (1, *p
= L_('-'));
1406 add (1, *p
= L_('+'));
1409 DO_NUMBER (4, (diff
/ 60) * 100 + diff
% 60);
1412 case L_('\0'): /* GNU extension: % at end of format. */
1416 /* Unknown format; output the format, including the '%',
1417 since this is most likely the right thing to do if a
1418 multibyte string has been misparsed. */
1422 for (flen
= 1; f
[1 - flen
] != L_('%'); flen
++)
1424 cpy (flen
, &f
[1 - flen
]);
1430 if (p
&& maxsize
!= 0)
1437 /* For Emacs we have a separate interface which corresponds to the normal
1438 strftime function and does not have the extra information whether the
1439 TP arguments comes from a `gmtime' call or not. */
1441 emacs_strftime (char *s
, size_t maxsize
, const char *format
,
1442 const struct tm
*tp
)
1444 return my_strftime (s
, maxsize
, format
, tp
, 0);
1448 #if defined _LIBC && !defined COMPILE_WIDE
1449 weak_alias (__strftime_l
, strftime_l
)