1 /* Copyright (C) 1991-2018 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 <https://www.gnu.org/licenses/>. */
19 # define USE_IN_EXTENDED_LOCALE_MODEL 1
20 # define HAVE_STRUCT_ERA_ENTRY 1
21 # define HAVE_TM_GMTOFF 1
22 # define HAVE_TM_ZONE 1
23 # define HAVE_TZNAME 1
25 # include "../locale/localeinfo.h"
29 # include "fprintftime.h"
31 # include "strftime.h"
33 # include "time-internal.h"
39 #if HAVE_TZNAME && !HAVE_DECL_TZNAME
40 extern char *tzname
[];
43 /* Do multibyte processing if multibyte encodings are supported, unless
44 multibyte sequences are safe in formats. Multibyte sequences are
45 safe if they cannot contain byte sequences that look like format
46 conversion specifications. The multibyte encodings used by the
47 C library on the various platforms (UTF-8, GB2312, GBK, CP936,
48 GB18030, EUC-TW, BIG5, BIG5-HKSCS, CP950, EUC-JP, EUC-KR, CP949,
49 SHIFT_JIS, CP932, JOHAB) are safe for formats, because the byte '%'
50 cannot occur in a multibyte character except in the first byte.
52 The DEC-HANYU encoding used on OSF/1 is not safe for formats, but
53 this encoding has never been seen in real-life use, so we ignore
55 #if !(defined __osf__ && 0)
56 # define MULTIBYTE_IS_FORMAT_SAFE 1
58 #define DO_MULTIBYTE (! MULTIBYTE_IS_FORMAT_SAFE)
62 static const mbstate_t mbstate_zero
;
73 # define FALLTHROUGH ((void) 0)
75 # define FALLTHROUGH __attribute__ ((__fallthrough__))
81 # define CHAR_T wchar_t
82 # define UCHAR_T unsigned int
83 # define L_(Str) L##Str
84 # define NLW(Sym) _NL_W##Sym
86 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
87 # define STRLEN(s) __wcslen (s)
91 # define UCHAR_T unsigned char
94 # define ABALTMON_1 _NL_ABALTMON_1
96 # define MEMCPY(d, s, n) memcpy (d, s, n)
97 # define STRLEN(s) strlen (s)
101 /* Shift A right by B bits portably, by dividing A by 2**B and
102 truncating towards minus infinity. A and B should be free of side
103 effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
104 INT_BITS is the number of useful bits in an int. GNU code can
105 assume that INT_BITS is at least 32.
107 ISO C99 says that A >> B is implementation-defined if A < 0. Some
108 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
109 right in the usual way when A < 0, so SHR falls back on division if
110 ordinary A >> B doesn't seem to be the usual signed shift. */
114 : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
116 /* Bound on length of the string representing an integer type or expression T.
117 Subtract 1 for the sign bit if t is signed; log10 (2.0) < 146/485;
118 add 1 for integer division truncation; add 1 more for a minus sign
120 #define INT_STRLEN_BOUND(t) \
121 ((sizeof (t) * CHAR_BIT - 1) * 146 / 485 + 2)
123 #define TM_YEAR_BASE 1900
126 /* Nonzero if YEAR is a leap year (every 4 years,
127 except every 100th isn't, and every 400th is). */
128 # define __isleap(year) \
129 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
134 # define mktime_z(tz, tm) mktime (tm)
135 # define tzname __tzname
136 # define tzset __tzset
140 # define FPRINTFTIME 0
144 # define STREAM_OR_CHAR_T FILE
145 # define STRFTIME_ARG(x) /* empty */
147 # define STREAM_OR_CHAR_T CHAR_T
148 # define STRFTIME_ARG(x) x,
152 # define memset_byte(P, Len, Byte) \
153 do { size_t _i; for (_i = 0; _i < Len; _i++) fputc (Byte, P); } while (0)
154 # define memset_space(P, Len) memset_byte (P, Len, ' ')
155 # define memset_zero(P, Len) memset_byte (P, Len, '0')
156 #elif defined COMPILE_WIDE
157 # define memset_space(P, Len) (wmemset (P, L' ', Len), (P) += (Len))
158 # define memset_zero(P, Len) (wmemset (P, L'0', Len), (P) += (Len))
160 # define memset_space(P, Len) (memset (P, ' ', Len), (P) += (Len))
161 # define memset_zero(P, Len) (memset (P, '0', Len), (P) += (Len))
165 # define advance(P, N)
167 # define advance(P, N) ((P) += (N))
174 size_t _w = (width < 0 ? 0 : width); \
175 size_t _incr = _n < _w ? _w : _n; \
176 if (_incr >= maxsize - i) \
180 if (digits == 0 && _n < _w) \
182 size_t _delta = width - _n; \
183 if (pad == L_('0')) \
184 memset_zero (p, _delta); \
186 memset_space (p, _delta); \
195 # define add1(C) add (1, fputc (C, p))
197 # define add1(C) add (1, *p = C)
206 fwrite_lowcase (p, (s), _n); \
207 else if (to_uppcase) \
208 fwrite_uppcase (p, (s), _n); \
211 /* Ignore the value of fwrite. The caller can determine whether \
212 an error occurred by inspecting ferror (P). All known fwrite \
213 implementations set the stream's error indicator when they \
214 fail due to ENOMEM etc., even though C11 and POSIX.1-2008 do \
215 not require this. */ \
216 fwrite (s, _n, 1, p); \
225 memcpy_lowcase (p, (s), _n LOCALE_ARG); \
226 else if (to_uppcase) \
227 memcpy_uppcase (p, (s), _n LOCALE_ARG); \
229 MEMCPY ((void *) p, (void const *) (s), _n))
233 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
234 # undef __mbsrtowcs_l
235 # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
237 # define widen(os, ws, l) \
240 const char *__s = os; \
241 memset (&__st, '\0', sizeof (__st)); \
242 l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
243 ws = (wchar_t *) alloca ((l + 1) * sizeof (wchar_t)); \
244 (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
249 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
250 /* We use this code also for the extended locale handling where the
251 function gets as an additional argument the locale which has to be
252 used. To access the values we have to redefine the _NL_CURRENT
254 # define strftime __strftime_l
255 # define wcsftime __wcsftime_l
257 # define _NL_CURRENT(category, item) \
258 (current->values[_NL_ITEM_INDEX (item)].string)
259 # define LOCALE_PARAM , locale_t loc
260 # define LOCALE_ARG , loc
261 # define HELPER_LOCALE_ARG , current
263 # define LOCALE_PARAM
266 # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
268 # define HELPER_LOCALE_ARG
273 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
274 # define TOUPPER(Ch, L) __towupper_l (Ch, L)
275 # define TOLOWER(Ch, L) __towlower_l (Ch, L)
277 # define TOUPPER(Ch, L) towupper (Ch)
278 # define TOLOWER(Ch, L) towlower (Ch)
281 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
282 # define TOUPPER(Ch, L) __toupper_l (Ch, L)
283 # define TOLOWER(Ch, L) __tolower_l (Ch, L)
285 # define TOUPPER(Ch, L) toupper (Ch)
286 # define TOLOWER(Ch, L) tolower (Ch)
289 /* We don't use 'isdigit' here since the locale dependent
290 interpretation is not what we want here. We only need to accept
291 the arabic digits in the ASCII range. One day there is perhaps a
292 more reliable way to accept other sets of digits. */
293 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
297 fwrite_lowcase (FILE *fp
, const CHAR_T
*src
, size_t len
)
301 fputc (TOLOWER ((UCHAR_T
) *src
, loc
), fp
);
307 fwrite_uppcase (FILE *fp
, const CHAR_T
*src
, size_t len
)
311 fputc (TOUPPER ((UCHAR_T
) *src
, loc
), fp
);
316 static CHAR_T
*memcpy_lowcase (CHAR_T
*dest
, const CHAR_T
*src
,
317 size_t len LOCALE_PARAM
);
320 memcpy_lowcase (CHAR_T
*dest
, const CHAR_T
*src
, size_t len LOCALE_PARAM
)
323 dest
[len
] = TOLOWER ((UCHAR_T
) src
[len
], loc
);
327 static CHAR_T
*memcpy_uppcase (CHAR_T
*dest
, const CHAR_T
*src
,
328 size_t len LOCALE_PARAM
);
331 memcpy_uppcase (CHAR_T
*dest
, const CHAR_T
*src
, size_t len LOCALE_PARAM
)
334 dest
[len
] = TOUPPER ((UCHAR_T
) src
[len
], loc
);
341 /* Yield the difference between *A and *B,
342 measured in seconds, ignoring leap seconds. */
343 # define tm_diff ftime_tm_diff
344 static int tm_diff (const struct tm
*, const struct tm
*);
346 tm_diff (const struct tm
*a
, const struct tm
*b
)
348 /* Compute intervening leap days correctly even if year is negative.
349 Take care to avoid int overflow in leap day calculations,
350 but it's OK to assume that A and B are close to each other. */
351 int a4
= SHR (a
->tm_year
, 2) + SHR (TM_YEAR_BASE
, 2) - ! (a
->tm_year
& 3);
352 int b4
= SHR (b
->tm_year
, 2) + SHR (TM_YEAR_BASE
, 2) - ! (b
->tm_year
& 3);
353 int a100
= a4
/ 25 - (a4
% 25 < 0);
354 int b100
= b4
/ 25 - (b4
% 25 < 0);
355 int a400
= SHR (a100
, 2);
356 int b400
= SHR (b100
, 2);
357 int intervening_leap_days
= (a4
- b4
) - (a100
- b100
) + (a400
- b400
);
358 int years
= a
->tm_year
- b
->tm_year
;
359 int days
= (365 * years
+ intervening_leap_days
360 + (a
->tm_yday
- b
->tm_yday
));
361 return (60 * (60 * (24 * days
+ (a
->tm_hour
- b
->tm_hour
))
362 + (a
->tm_min
- b
->tm_min
))
363 + (a
->tm_sec
- b
->tm_sec
));
365 #endif /* ! HAVE_TM_GMTOFF */
369 /* The number of days from the first day of the first ISO week of this
370 year to the year day YDAY with week day WDAY. ISO weeks start on
371 Monday; the first ISO week has the year's first Thursday. YDAY may
372 be as small as YDAY_MINIMUM. */
373 #define ISO_WEEK_START_WDAY 1 /* Monday */
374 #define ISO_WEEK1_WDAY 4 /* Thursday */
375 #define YDAY_MINIMUM (-366)
376 static int iso_week_days (int, int);
381 iso_week_days (int yday
, int wday
)
383 /* Add enough to the first operand of % to make it nonnegative. */
384 int big_enough_multiple_of_7
= (-YDAY_MINIMUM
/ 7 + 2) * 7;
386 - (yday
- wday
+ ISO_WEEK1_WDAY
+ big_enough_multiple_of_7
) % 7
387 + ISO_WEEK1_WDAY
- ISO_WEEK_START_WDAY
);
391 /* When compiling this file, GNU applications can #define my_strftime
392 to a symbol (typically nstrftime) to get an extended strftime with
393 extra arguments TZ and NS. */
397 # define my_strftime fprintftime
402 # define extra_args , tz, ns
403 # define extra_args_spec , timezone_t tz, int ns
405 # if defined COMPILE_WIDE
406 # define my_strftime wcsftime
407 # define nl_get_alt_digit _nl_get_walt_digit
409 # define my_strftime strftime
410 # define nl_get_alt_digit _nl_get_alt_digit
413 # define extra_args_spec
414 /* We don't have this information in general. */
419 static size_t __strftime_internal (STREAM_OR_CHAR_T
*, STRFTIME_ARG (size_t)
420 const CHAR_T
*, const struct tm
*,
422 extra_args_spec LOCALE_PARAM
);
424 /* Write information from TP into S according to the format
425 string FORMAT, writing no more that MAXSIZE characters
426 (including the terminating '\0') and returning number of
427 characters written. If S is NULL, nothing will be written
428 anywhere, so to determine how many characters would be
429 written, use NULL for S and (size_t) -1 for MAXSIZE. */
431 my_strftime (STREAM_OR_CHAR_T
*s
, STRFTIME_ARG (size_t maxsize
)
432 const CHAR_T
*format
,
433 const struct tm
*tp extra_args_spec LOCALE_PARAM
)
435 bool tzset_called
= false;
436 return __strftime_internal (s
, STRFTIME_ARG (maxsize
) format
, tp
,
437 false, &tzset_called extra_args LOCALE_ARG
);
439 #if defined _LIBC && ! FPRINTFTIME
440 libc_hidden_def (my_strftime
)
443 /* Just like my_strftime, above, but with two more parameters.
444 UPCASE indicate that the result should be converted to upper case,
445 and *TZSET_CALLED indicates whether tzset has been called here. */
447 __strftime_internal (STREAM_OR_CHAR_T
*s
, STRFTIME_ARG (size_t maxsize
)
448 const CHAR_T
*format
,
449 const struct tm
*tp
, bool upcase
, bool *tzset_called
450 extra_args_spec LOCALE_PARAM
)
452 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
453 struct __locale_data
*const current
= loc
->__locales
[LC_TIME
];
456 size_t maxsize
= (size_t) -1;
459 int hour12
= tp
->tm_hour
;
461 /* We cannot make the following values variables since we must delay
462 the evaluation of these values until really needed since some
463 expressions might not be valid in every situation. The 'struct tm'
464 might be generated by a strptime() call that initialized
465 only a few elements. Dereference the pointers only if the format
466 requires this. Then it is ok to fail if the pointers are invalid. */
468 ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \
469 ? "?" : _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday)))
471 ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \
472 ? "?" : _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday)))
474 ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \
475 ? "?" : _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon)))
477 ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \
478 ? "?" : _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon)))
479 # define a_altmonth \
480 ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \
481 ? "?" : _NL_CURRENT (LC_TIME, NLW(ABALTMON_1) + tp->tm_mon)))
482 # define f_altmonth \
483 ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \
484 ? "?" : _NL_CURRENT (LC_TIME, NLW(ALTMON_1) + tp->tm_mon)))
486 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
487 ? NLW(PM_STR) : NLW(AM_STR)))
489 # define aw_len STRLEN (a_wkday)
490 # define am_len STRLEN (a_month)
491 # define aam_len STRLEN (a_altmonth)
492 # define ap_len STRLEN (ampm)
495 char **tzname_vec
= tzname
;
499 STREAM_OR_CHAR_T
*p
= s
;
501 #if DO_MULTIBYTE && !defined COMPILE_WIDE
502 const char *format_end
= NULL
;
505 #if ! defined _LIBC && ! HAVE_RUN_TZSET_TEST
506 /* Solaris 2.5.x and 2.6 tzset sometimes modify the storage returned
507 by localtime. On such systems, we must either use the tzset and
508 localtime wrappers to work around the bug (which sets
509 HAVE_RUN_TZSET_TEST) or make a copy of the structure. */
510 struct tm copy
= *tp
;
516 /* The POSIX test suite assumes that setting
517 the environment variable TZ to a new value before calling strftime()
518 will influence the result (the %Z format) even if the information in
519 TP is computed with a totally different time zone.
520 This is bogus: though POSIX allows bad behavior like this,
521 POSIX does not require it. Do the right thing instead. */
522 zone
= (const char *) tp
->tm_zone
;
527 if (! (zone
&& *zone
))
533 /* Infer the zone name from *TZ instead of from TZNAME. */
534 tzname_vec
= tz
->tzname_copy
;
537 /* The tzset() call might have changed the value. */
538 if (!(zone
&& *zone
) && tp
->tm_isdst
>= 0)
540 /* POSIX.1 requires that local time zone information be used as
541 though strftime called tzset. */
546 *tzset_called
= true;
549 zone
= tzname_vec
[tp
->tm_isdst
!= 0];
561 for (f
= format
; *f
!= '\0'; ++f
)
563 int pad
= 0; /* Padding for number ('-', '_', or 0). */
564 int modifier
; /* Field modifier ('E', 'O', or 0). */
565 int digits
= 0; /* Max digits for numeric format. */
566 int number_value
; /* Numeric value to be printed. */
567 unsigned int u_number_value
; /* (unsigned int) number_value. */
568 bool negative_number
; /* The number is negative. */
569 bool always_output_a_sign
; /* +/- should always be output. */
570 int tz_colon_mask
; /* Bitmask of where ':' should appear. */
571 const CHAR_T
*subfmt
;
575 + 2 /* for the two colons in a %::z or %:::z time zone */
576 + (sizeof (int) < sizeof (time_t)
577 ? INT_STRLEN_BOUND (time_t)
578 : INT_STRLEN_BOUND (int))];
580 bool to_lowcase
= false;
581 bool to_uppcase
= upcase
;
583 bool change_case
= false;
586 #if DO_MULTIBYTE && !defined COMPILE_WIDE
592 case L_('\b'): case L_('\t'): case L_('\n'):
593 case L_('\v'): case L_('\f'): case L_('\r'):
594 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
595 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
596 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
597 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
598 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
599 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
600 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
601 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
602 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
603 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
604 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
605 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
606 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
607 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
608 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
609 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
610 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
611 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
613 /* The C Standard requires these 98 characters (plus '%') to
614 be in the basic execution character set. None of these
615 characters can start a multibyte sequence, so they need
616 not be analyzed further. */
621 /* Copy this multibyte sequence until we reach its end, find
622 an error, or come back to the initial shift state. */
624 mbstate_t mbstate
= mbstate_zero
;
629 format_end
= f
+ strlen (f
) + 1;
630 fsize
= format_end
- f
;
634 size_t bytes
= mbrlen (f
+ len
, fsize
- len
, &mbstate
);
639 if (bytes
== (size_t) -2)
641 len
+= strlen (f
+ len
);
645 if (bytes
== (size_t) -1)
653 while (! mbsinit (&mbstate
));
661 #else /* ! DO_MULTIBYTE */
663 /* Either multibyte encodings are not supported, they are
664 safe for formats, so any non-'%' byte can be copied through,
665 or this is the wide character version. */
672 #endif /* ! DO_MULTIBYTE */
674 /* Check for flags that can modify a format. */
679 /* This influences the number formats. */
686 /* This changes textual output. */
700 /* As a GNU extension we allow the field width to be specified. */
706 if (width
> INT_MAX
/ 10
707 || (width
== INT_MAX
/ 10 && *f
- L_('0') > INT_MAX
% 10))
708 /* Avoid overflow. */
713 width
+= *f
- L_('0');
717 while (ISDIGIT (*f
));
720 /* Check for modifiers. */
733 /* Now do the specified format. */
737 #define DO_NUMBER(d, v) \
745 #define DO_SIGNED_NUMBER(d, negative, v) \
749 negative_number = negative; \
750 u_number_value = v; \
751 goto do_signed_number; \
755 /* The mask is not what you might think.
756 When the ordinal i'th bit is set, insert a colon
757 before the i'th digit of the time zone representation. */
758 #define DO_TZ_OFFSET(d, mask, v) \
762 tz_colon_mask = mask; \
763 u_number_value = v; \
767 #define DO_NUMBER_SPACEPAD(d, v) \
772 goto do_number_spacepad; \
791 cpy (aw_len
, a_wkday
);
794 goto underlying_strftime
;
806 cpy (STRLEN (f_wkday
), f_wkday
);
809 goto underlying_strftime
;
819 if (modifier
== L_('E'))
822 if (modifier
== L_('O'))
823 cpy (aam_len
, a_altmonth
);
825 cpy (am_len
, a_month
);
828 goto underlying_strftime
;
832 if (modifier
== L_('E'))
840 if (modifier
== L_('O'))
841 cpy (STRLEN (f_altmonth
), f_altmonth
);
843 cpy (STRLEN (f_month
), f_month
);
846 goto underlying_strftime
;
850 if (modifier
== L_('O'))
853 if (! (modifier
== 'E'
855 (const CHAR_T
*) _NL_CURRENT (LC_TIME
,
858 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(D_T_FMT
));
860 goto underlying_strftime
;
865 size_t len
= __strftime_internal (NULL
, STRFTIME_ARG ((size_t) -1)
867 tp
, to_uppcase
, tzset_called
868 extra_args LOCALE_ARG
);
869 add (len
, __strftime_internal (p
,
870 STRFTIME_ARG (maxsize
- i
)
872 tp
, to_uppcase
, tzset_called
873 extra_args LOCALE_ARG
));
877 #if !(defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
880 /* The relevant information is available only via the
881 underlying strftime implementation, so use that. */
884 char ubuf
[1024]; /* enough for any single format in practice */
886 /* Make sure we're calling the actual underlying strftime.
887 In some cases, config.h contains something like
888 "#define strftime rpl_strftime". */
894 /* The space helps distinguish strftime failure from empty
902 len
= strftime (ubuf
, sizeof ubuf
, ufmt
, tp
);
904 cpy (len
- 1, ubuf
+ 1);
910 if (modifier
== L_('E'))
912 #if HAVE_STRUCT_ERA_ENTRY
913 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
917 size_t len
= __wcslen (era
->era_wname
);
918 cpy (len
, era
->era_wname
);
920 size_t len
= strlen (era
->era_name
);
921 cpy (len
, era
->era_name
);
926 goto underlying_strftime
;
931 int century
= tp
->tm_year
/ 100 + TM_YEAR_BASE
/ 100;
932 century
-= tp
->tm_year
% 100 < 0 && 0 < century
;
933 DO_SIGNED_NUMBER (2, tp
->tm_year
< - TM_YEAR_BASE
, century
);
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
));
947 goto underlying_strftime
;
952 subfmt
= L_("%m/%d/%y");
956 if (modifier
== L_('E'))
959 DO_NUMBER (2, tp
->tm_mday
);
962 if (modifier
== L_('E'))
965 DO_NUMBER_SPACEPAD (2, tp
->tm_mday
);
967 /* All numeric formats set DIGITS and NUMBER_VALUE (or U_NUMBER_VALUE)
968 and then jump to one of these labels. */
971 always_output_a_sign
= true;
975 /* Force '_' flag unless overridden by '0' or '-' flag. */
976 if (pad
!= L_('0') && pad
!= L_('-'))
980 /* Format NUMBER_VALUE according to the MODIFIER flag. */
981 negative_number
= number_value
< 0;
982 u_number_value
= number_value
;
985 always_output_a_sign
= false;
989 /* Format U_NUMBER_VALUE according to the MODIFIER flag.
990 NEGATIVE_NUMBER is nonzero if the original number was
991 negative; in this case it was converted directly to
992 unsigned int (i.e., modulo (UINT_MAX + 1)) without
994 if (modifier
== L_('O') && !negative_number
)
997 /* Get the locale specific alternate representation of
998 the number. If none exist NULL is returned. */
999 const CHAR_T
*cp
= nl_get_alt_digit (u_number_value
1004 size_t digitlen
= STRLEN (cp
);
1012 goto underlying_strftime
;
1016 bufp
= buf
+ sizeof (buf
) / sizeof (buf
[0]);
1018 if (negative_number
)
1019 u_number_value
= - u_number_value
;
1023 if (tz_colon_mask
& 1)
1025 tz_colon_mask
>>= 1;
1026 *--bufp
= u_number_value
% 10 + L_('0');
1027 u_number_value
/= 10;
1029 while (u_number_value
!= 0 || tz_colon_mask
!= 0);
1031 do_number_sign_and_padding
:
1035 sign_char
= (negative_number
? L_('-')
1036 : always_output_a_sign
? L_('+')
1046 int padding
= digits
- (buf
+ (sizeof (buf
) / sizeof (buf
[0]))
1047 - bufp
) - !!sign_char
;
1053 if ((size_t) padding
>= maxsize
- i
)
1057 memset_space (p
, padding
);
1059 width
= width
> padding
? width
- padding
: 0;
1065 if ((size_t) digits
>= maxsize
- i
)
1072 memset_zero (p
, padding
);
1084 cpy (buf
+ sizeof (buf
) / sizeof (buf
[0]) - bufp
, bufp
);
1090 subfmt
= L_("%Y-%m-%d");
1094 if (modifier
== L_('E'))
1097 DO_NUMBER (2, tp
->tm_hour
);
1100 if (modifier
== L_('E'))
1103 DO_NUMBER (2, hour12
);
1105 case L_('k'): /* GNU extension. */
1106 if (modifier
== L_('E'))
1109 DO_NUMBER_SPACEPAD (2, tp
->tm_hour
);
1111 case L_('l'): /* GNU extension. */
1112 if (modifier
== L_('E'))
1115 DO_NUMBER_SPACEPAD (2, hour12
);
1118 if (modifier
== L_('E'))
1121 DO_SIGNED_NUMBER (3, tp
->tm_yday
< -1, tp
->tm_yday
+ 1U);
1124 if (modifier
== L_('E'))
1127 DO_NUMBER (2, tp
->tm_min
);
1130 if (modifier
== L_('E'))
1133 DO_SIGNED_NUMBER (2, tp
->tm_mon
< -1, tp
->tm_mon
+ 1U);
1136 case L_('N'): /* GNU extension. */
1137 if (modifier
== L_('E'))
1145 /* Take an explicit width less than 9 as a precision. */
1147 for (j
= width
; j
< 9; j
++)
1151 DO_NUMBER (width
, number_value
);
1161 format_char
= L_('p');
1174 goto underlying_strftime
;
1177 case L_('q'): /* GNU extension. */
1178 DO_SIGNED_NUMBER (1, false, ((tp
->tm_mon
* 11) >> 5) + 1);
1182 subfmt
= L_("%H:%M");
1187 if (*(subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
,
1190 subfmt
= L_("%I:%M:%S %p");
1193 goto underlying_strftime
;
1197 if (modifier
== L_('E'))
1200 DO_NUMBER (2, tp
->tm_sec
);
1202 case L_('s'): /* GNU extension. */
1208 t
= mktime_z (tz
, <m
);
1210 /* Generate string value for T using time_t arithmetic;
1211 this works even if sizeof (long) < sizeof (time_t). */
1213 bufp
= buf
+ sizeof (buf
) / sizeof (buf
[0]);
1214 negative_number
= t
< 0;
1220 *--bufp
= (negative_number
? -d
: d
) + L_('0');
1225 always_output_a_sign
= false;
1226 goto do_number_sign_and_padding
;
1230 if (modifier
== L_('O'))
1233 if (! (modifier
== L_('E')
1235 (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(ERA_T_FMT
)))
1237 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(T_FMT
));
1240 goto underlying_strftime
;
1243 subfmt
= L_("%H:%M:%S");
1251 DO_NUMBER (1, (tp
->tm_wday
- 1 + 7) % 7 + 1);
1254 if (modifier
== L_('E'))
1257 DO_NUMBER (2, (tp
->tm_yday
- tp
->tm_wday
+ 7) / 7);
1262 if (modifier
== L_('E'))
1265 /* YEAR is a leap year if and only if (tp->tm_year + TM_YEAR_BASE)
1266 is a leap year, except that YEAR and YEAR - 1 both work
1267 correctly even when (tp->tm_year + TM_YEAR_BASE) would
1269 int year
= (tp
->tm_year
1271 ? TM_YEAR_BASE
% 400
1272 : TM_YEAR_BASE
% 400 - 400));
1273 int year_adjust
= 0;
1274 int days
= iso_week_days (tp
->tm_yday
, tp
->tm_wday
);
1278 /* This ISO week belongs to the previous year. */
1280 days
= iso_week_days (tp
->tm_yday
+ (365 + __isleap (year
- 1)),
1285 int d
= iso_week_days (tp
->tm_yday
- (365 + __isleap (year
)),
1289 /* This ISO week belongs to the next year. */
1299 int yy
= (tp
->tm_year
% 100 + year_adjust
) % 100;
1300 DO_NUMBER (2, (0 <= yy
1302 : tp
->tm_year
< -TM_YEAR_BASE
- year_adjust
1308 DO_SIGNED_NUMBER (4, tp
->tm_year
< -TM_YEAR_BASE
- year_adjust
,
1309 (tp
->tm_year
+ (unsigned int) TM_YEAR_BASE
1313 DO_NUMBER (2, days
/ 7 + 1);
1318 if (modifier
== L_('E'))
1321 DO_NUMBER (2, (tp
->tm_yday
- (tp
->tm_wday
- 1 + 7) % 7 + 7) / 7);
1324 if (modifier
== L_('E'))
1327 DO_NUMBER (1, tp
->tm_wday
);
1330 if (modifier
== 'E')
1332 #if HAVE_STRUCT_ERA_ENTRY
1333 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
1336 # ifdef COMPILE_WIDE
1337 subfmt
= era
->era_wformat
;
1339 subfmt
= era
->era_format
;
1344 goto underlying_strftime
;
1347 if (modifier
== L_('O'))
1350 DO_SIGNED_NUMBER (4, tp
->tm_year
< -TM_YEAR_BASE
,
1351 tp
->tm_year
+ (unsigned int) TM_YEAR_BASE
);
1354 if (modifier
== L_('E'))
1356 #if HAVE_STRUCT_ERA_ENTRY
1357 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
1360 int delta
= tp
->tm_year
- era
->start_date
[0];
1361 DO_NUMBER (1, (era
->offset
1362 + delta
* era
->absolute_direction
));
1365 goto underlying_strftime
;
1370 int yy
= tp
->tm_year
% 100;
1372 yy
= tp
->tm_year
< - TM_YEAR_BASE
? -yy
: yy
+ 100;
1385 /* The zone string is always given in multibyte form. We have
1386 to transform it first. */
1389 widen (zone
, wczone
, len
);
1393 cpy (strlen (zone
), zone
);
1398 /* :, ::, and ::: are valid only just before 'z'.
1399 :::: etc. are rejected later. */
1400 for (colons
= 1; f
[colons
] == L_(':'); colons
++)
1402 if (f
[colons
] != L_('z'))
1405 goto do_z_conversion
;
1411 if (tp
->tm_isdst
< 0)
1420 diff
= tp
->tm_gmtoff
;
1430 /* POSIX.1 requires that local time zone information be used as
1431 though strftime called tzset. */
1436 *tzset_called
= true;
1441 lt
= mktime_z (tz
, <m
);
1443 if (lt
== (time_t) -1)
1445 /* mktime returns -1 for errors, but -1 is also a
1446 valid time_t value. Check whether an error really
1450 if (! localtime_rz (tz
, <
, &tm
)
1451 || ((ltm
.tm_sec
^ tm
.tm_sec
)
1452 | (ltm
.tm_min
^ tm
.tm_min
)
1453 | (ltm
.tm_hour
^ tm
.tm_hour
)
1454 | (ltm
.tm_mday
^ tm
.tm_mday
)
1455 | (ltm
.tm_mon
^ tm
.tm_mon
)
1456 | (ltm
.tm_year
^ tm
.tm_year
)))
1460 if (! localtime_rz (0, <
, >m
))
1463 diff
= tm_diff (<m
, >m
);
1467 negative_number
= diff
< 0 || (diff
== 0 && *zone
== '-');
1468 hour_diff
= diff
/ 60 / 60;
1469 min_diff
= diff
/ 60 % 60;
1470 sec_diff
= diff
% 60;
1475 DO_TZ_OFFSET (5, 0, hour_diff
* 100 + min_diff
);
1477 case 1: tz_hh_mm
: /* +hh:mm */
1478 DO_TZ_OFFSET (6, 04, hour_diff
* 100 + min_diff
);
1480 case 2: tz_hh_mm_ss
: /* +hh:mm:ss */
1481 DO_TZ_OFFSET (9, 024,
1482 hour_diff
* 10000 + min_diff
* 100 + sec_diff
);
1484 case 3: /* +hh if possible, else +hh:mm, else +hh:mm:ss */
1489 DO_TZ_OFFSET (3, 0, hour_diff
);
1496 case L_('\0'): /* GNU extension: % at end of format. */
1500 /* Unknown format; output the format, including the '%',
1501 since this is most likely the right thing to do if a
1502 multibyte string has been misparsed. */
1506 for (flen
= 1; f
[1 - flen
] != L_('%'); flen
++)
1508 cpy (flen
, &f
[1 - flen
]);
1515 if (p
&& maxsize
!= 0)