1 /* Copyright (C) 2002, 2004 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, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 # define USE_IN_EXTENDED_LOCALE_MODEL 1
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)))
141 #define TYPE_SIGNED(t) ((t) -1 < 0)
143 /* Bound on length of the string representing an integer value of type t.
144 Subtract one for the sign bit if t is signed;
145 302 / 1000 is log10 (2) rounded up;
146 add one for integer division truncation;
147 add one more for a minus sign if t is signed. */
148 #define INT_STRLEN_BOUND(t) \
149 ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 + 1 + TYPE_SIGNED (t))
151 #define TM_YEAR_BASE 1900
154 /* Nonzero if YEAR is a leap year (every 4 years,
155 except every 100th isn't, and every 400th is). */
156 # define __isleap(year) \
157 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
162 # define tzname __tzname
163 # define tzset __tzset
167 /* Portable standalone applications should supply a "time_r.h" that
168 declares a POSIX-compliant localtime_r, for the benefit of older
169 implementations that lack localtime_r or have a nonstandard one.
170 Similarly for gmtime_r. See the gnulib time_r module for one way
171 to implement this. */
174 # undef __localtime_r
175 # define __gmtime_r gmtime_r
176 # define __localtime_r localtime_r
180 #if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
181 /* Some systems lack the `memset' function and we don't want to
182 introduce additional dependencies. */
183 /* The SGI compiler reportedly barfs on the trailing null
184 if we use a string constant as the initializer. 28 June 1997, rms. */
185 static const CHAR_T spaces
[16] = /* " " */
187 L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),
188 L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' ')
190 static const CHAR_T zeroes
[16] = /* "0000000000000000" */
192 L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),
193 L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0')
196 # define memset_space(P, Len) \
202 int _this = _len > 16 ? 16 : _len; \
203 (P) = MEMPCPY ((P), spaces, _this * sizeof (CHAR_T)); \
209 # define memset_zero(P, Len) \
215 int _this = _len > 16 ? 16 : _len; \
216 (P) = MEMPCPY ((P), zeroes, _this * sizeof (CHAR_T)); \
223 # define memset_space(P, Len) (wmemset ((P), L' ', (Len)), (P) += (Len))
224 # define memset_zero(P, Len) (wmemset ((P), L'0', (Len)), (P) += (Len))
226 # define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
227 # define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
235 int _delta = width - _n; \
236 int _incr = _n + (_delta > 0 ? _delta : 0); \
237 if ((size_t) _incr >= maxsize - i) \
243 if (pad == L_('0')) \
244 memset_zero (p, _delta); \
246 memset_space (p, _delta); \
257 memcpy_lowcase (p, (s), _n LOCALE_ARG); \
258 else if (to_uppcase) \
259 memcpy_uppcase (p, (s), _n LOCALE_ARG); \
261 MEMCPY ((PTR) p, (const PTR) (s), _n))
264 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
265 # undef __mbsrtowcs_l
266 # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
268 # define widen(os, ws, l) \
271 const char *__s = os; \
272 memset (&__st, '\0', sizeof (__st)); \
273 l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
274 ws = alloca ((l + 1) * sizeof (wchar_t)); \
275 (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
280 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
281 /* We use this code also for the extended locale handling where the
282 function gets as an additional argument the locale which has to be
283 used. To access the values we have to redefine the _NL_CURRENT
285 # define strftime __strftime_l
286 # define wcsftime __wcsftime_l
288 # define _NL_CURRENT(category, item) \
289 (current->values[_NL_ITEM_INDEX (item)].string)
290 # define LOCALE_PARAM , loc
291 # define LOCALE_ARG , loc
292 # define LOCALE_PARAM_DECL __locale_t loc;
293 # define LOCALE_PARAM_PROTO , __locale_t loc
294 # define HELPER_LOCALE_ARG , current
296 # define LOCALE_PARAM
297 # define LOCALE_PARAM_PROTO
299 # define LOCALE_PARAM_DECL
301 # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
303 # define HELPER_LOCALE_ARG
308 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
309 # define TOUPPER(Ch, L) __towupper_l (Ch, L)
310 # define TOLOWER(Ch, L) __towlower_l (Ch, L)
312 # define TOUPPER(Ch, L) towupper (Ch)
313 # define TOLOWER(Ch, L) towlower (Ch)
317 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
318 # define TOUPPER(Ch, L) __toupper_l (Ch, L)
319 # define TOLOWER(Ch, L) __tolower_l (Ch, L)
321 # define TOUPPER(Ch, L) toupper (Ch)
322 # define TOLOWER(Ch, L) tolower (Ch)
325 # define TOUPPER(Ch, L) (islower (Ch) ? toupper (Ch) : (Ch))
326 # define TOLOWER(Ch, L) (isupper (Ch) ? tolower (Ch) : (Ch))
329 /* We don't use `isdigit' here since the locale dependent
330 interpretation is not what we want here. We only need to accept
331 the arabic digits in the ASCII range. One day there is perhaps a
332 more reliable way to accept other sets of digits. */
333 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
335 static CHAR_T
*memcpy_lowcase (CHAR_T
*dest
, const CHAR_T
*src
,
336 size_t len LOCALE_PARAM_PROTO
) __THROW
;
339 memcpy_lowcase (dest
, src
, len LOCALE_PARAM
)
346 dest
[len
] = TOLOWER ((UCHAR_T
) src
[len
], loc
);
350 static CHAR_T
*memcpy_uppcase (CHAR_T
*dest
, const CHAR_T
*src
,
351 size_t len LOCALE_PARAM_PROTO
) __THROW
;
354 memcpy_uppcase (dest
, src
, len LOCALE_PARAM
)
361 dest
[len
] = TOUPPER ((UCHAR_T
) src
[len
], loc
);
367 /* Yield the difference between *A and *B,
368 measured in seconds, ignoring leap seconds. */
369 # define tm_diff ftime_tm_diff
370 static int tm_diff (const struct tm
*, const struct tm
*) __THROW
;
376 /* Compute intervening leap days correctly even if year is negative.
377 Take care to avoid int overflow in leap day calculations,
378 but it's OK to assume that A and B are close to each other. */
379 int a4
= (a
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (a
->tm_year
& 3);
380 int b4
= (b
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (b
->tm_year
& 3);
381 int a100
= a4
/ 25 - (a4
% 25 < 0);
382 int b100
= b4
/ 25 - (b4
% 25 < 0);
383 int a400
= a100
>> 2;
384 int b400
= b100
>> 2;
385 int intervening_leap_days
= (a4
- b4
) - (a100
- b100
) + (a400
- b400
);
386 int years
= a
->tm_year
- b
->tm_year
;
387 int days
= (365 * years
+ intervening_leap_days
388 + (a
->tm_yday
- b
->tm_yday
));
389 return (60 * (60 * (24 * days
+ (a
->tm_hour
- b
->tm_hour
))
390 + (a
->tm_min
- b
->tm_min
))
391 + (a
->tm_sec
- b
->tm_sec
));
393 #endif /* ! HAVE_TM_GMTOFF */
397 /* The number of days from the first day of the first ISO week of this
398 year to the year day YDAY with week day WDAY. ISO weeks start on
399 Monday; the first ISO week has the year's first Thursday. YDAY may
400 be as small as YDAY_MINIMUM. */
401 #define ISO_WEEK_START_WDAY 1 /* Monday */
402 #define ISO_WEEK1_WDAY 4 /* Thursday */
403 #define YDAY_MINIMUM (-366)
404 static int iso_week_days (int, int) __THROW
;
409 iso_week_days (yday
, wday
)
413 /* Add enough to the first operand of % to make it nonnegative. */
414 int big_enough_multiple_of_7
= (-YDAY_MINIMUM
/ 7 + 2) * 7;
416 - (yday
- wday
+ ISO_WEEK1_WDAY
+ big_enough_multiple_of_7
) % 7
417 + ISO_WEEK1_WDAY
- ISO_WEEK_START_WDAY
);
421 #if !(defined _NL_CURRENT || HAVE_STRFTIME)
422 static CHAR_T
const weekday_name
[][10] =
424 L_("Sunday"), L_("Monday"), L_("Tuesday"), L_("Wednesday"),
425 L_("Thursday"), L_("Friday"), L_("Saturday")
427 static CHAR_T
const month_name
[][10] =
429 L_("January"), L_("February"), L_("March"), L_("April"), L_("May"),
430 L_("June"), L_("July"), L_("August"), L_("September"), L_("October"),
431 L_("November"), L_("December")
437 # define my_strftime emacs_strftimeu
438 # define ut_argument , ut
439 # define ut_argument_spec int ut;
440 # define ut_argument_spec_iso , int ut
443 # define my_strftime wcsftime
444 # define nl_get_alt_digit _nl_get_walt_digit
446 # define my_strftime strftime
447 # define nl_get_alt_digit _nl_get_alt_digit
450 # define ut_argument_spec
451 # define ut_argument_spec_iso
452 /* We don't have this information in general. */
456 #if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
457 /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
458 Work around this bug by copying *tp before it might be munged. */
459 size_t _strftime_copytm (char *, size_t, const char *,
460 const struct tm
* ut_argument_spec_iso
) __THROW
;
462 my_strftime (s
, maxsize
, format
, tp ut_argument
)
465 const CHAR_T
*format
;
471 return _strftime_copytm (s
, maxsize
, format
, &tmcopy ut_argument
);
474 # define my_strftime _strftime_copytm
478 /* Write information from TP into S according to the format
479 string FORMAT, writing no more that MAXSIZE characters
480 (including the terminating '\0') and returning number of
481 characters written. If S is NULL, nothing will be written
482 anywhere, so to determine how many characters would be
483 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
485 my_strftime (s
, maxsize
, format
, tp ut_argument LOCALE_PARAM
)
488 const CHAR_T
*format
;
493 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
494 struct locale_data
*const current
= loc
->__locales
[LC_TIME
];
497 int hour12
= tp
->tm_hour
;
499 /* We cannot make the following values variables since we must delay
500 the evaluation of these values until really needed since some
501 expressions might not be valid in every situation. The `struct tm'
502 might be generated by a strptime() call that initialized
503 only a few elements. Dereference the pointers only if the format
504 requires this. Then it is ok to fail if the pointers are invalid. */
506 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
508 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
510 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
512 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
514 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
515 ? NLW(PM_STR) : NLW(AM_STR)))
517 # define aw_len STRLEN (a_wkday)
518 # define am_len STRLEN (a_month)
519 # define ap_len STRLEN (ampm)
522 # define f_wkday (weekday_name[tp->tm_wday])
523 # define f_month (month_name[tp->tm_mon])
524 # define a_wkday f_wkday
525 # define a_month f_month
526 # define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
537 #if DO_MULTIBYTE && !defined COMPILE_WIDE
538 const char *format_end
= NULL
;
543 /* The POSIX test suite assumes that setting
544 the environment variable TZ to a new value before calling strftime()
545 will influence the result (the %Z format) even if the information in
546 TP is computed with a totally different time zone.
547 This is bogus: though POSIX allows bad behavior like this,
548 POSIX does not require it. Do the right thing instead. */
549 zone
= (const char *) tp
->tm_zone
;
554 if (! (zone
&& *zone
))
559 /* POSIX.1 requires that local time zone information is used as
560 though strftime called tzset. */
573 for (f
= format
; *f
!= '\0'; ++f
)
575 int pad
= 0; /* Padding for number ('-', '_', or 0). */
576 int modifier
; /* Field modifier ('E', 'O', or 0). */
577 int digits
; /* Max digits for numeric format. */
578 int number_value
; /* Numeric value to be printed. */
579 int negative_number
; /* 1 if the number is negative. */
580 const CHAR_T
*subfmt
;
582 CHAR_T buf
[1 + (sizeof (int) < sizeof (time_t)
583 ? INT_STRLEN_BOUND (time_t)
584 : INT_STRLEN_BOUND (int))];
591 #if DO_MULTIBYTE && !defined COMPILE_WIDE
597 case L_('\b'): case L_('\t'): case L_('\n'):
598 case L_('\v'): case L_('\f'): case L_('\r'):
599 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
600 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
601 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
602 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
603 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
604 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
605 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
606 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
607 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
608 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
609 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
610 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
611 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
612 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
613 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
614 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
615 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
616 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
618 /* The C Standard requires these 98 characters (plus '%') to
619 be in the basic execution character set. None of these
620 characters can start a multibyte sequence, so they need
621 not be analyzed further. */
626 /* Copy this multibyte sequence until we reach its end, find
627 an error, or come back to the initial shift state. */
629 mbstate_t mbstate
= mbstate_zero
;
634 format_end
= f
+ strlen (f
) + 1;
635 fsize
= format_end
- f
;
639 size_t bytes
= mbrlen (f
+ len
, fsize
- len
, &mbstate
);
644 if (bytes
== (size_t) -2)
646 len
+= strlen (f
+ len
);
650 if (bytes
== (size_t) -1)
658 while (! mbsinit (&mbstate
));
666 #else /* ! DO_MULTIBYTE */
668 /* Either multibyte encodings are not supported, they are
669 safe for formats, so any non-'%' byte can be copied through,
670 or this is the wide character version. */
677 #endif /* ! DO_MULTIBYTE */
679 /* Check for flags that can modify a format. */
684 /* This influences the number formats. */
691 /* This changes textual output. */
705 /* As a GNU extension we allow to specify the field width. */
711 if (width
> INT_MAX
/ 10
712 || (width
== INT_MAX
/ 10 && *f
- L_('0') > INT_MAX
% 10))
713 /* Avoid overflow. */
718 width
+= *f
- L_('0');
722 while (ISDIGIT (*f
));
725 /* Check for modifiers. */
738 /* Now do the specified format. */
742 #define DO_NUMBER(d, v) \
743 digits = d > width ? d : width; \
744 number_value = v; goto do_number
745 #define DO_NUMBER_SPACEPAD(d, v) \
746 digits = d > width ? d : width; \
747 number_value = v; goto do_number_spacepad
763 #if defined _NL_CURRENT || !HAVE_STRFTIME
764 cpy (aw_len
, a_wkday
);
767 goto underlying_strftime
;
778 #if defined _NL_CURRENT || !HAVE_STRFTIME
779 cpy (STRLEN (f_wkday
), f_wkday
);
782 goto underlying_strftime
;
794 #if defined _NL_CURRENT || !HAVE_STRFTIME
795 cpy (am_len
, a_month
);
798 goto underlying_strftime
;
809 #if defined _NL_CURRENT || !HAVE_STRFTIME
810 cpy (STRLEN (f_month
), f_month
);
813 goto underlying_strftime
;
817 if (modifier
== L_('O'))
820 if (! (modifier
== 'E'
822 (const CHAR_T
*) _NL_CURRENT (LC_TIME
,
825 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(D_T_FMT
));
828 goto underlying_strftime
;
830 subfmt
= L_("%a %b %e %H:%M:%S %Y");
836 CHAR_T
*old_start
= p
;
837 size_t len
= my_strftime (NULL
, (size_t) -1, subfmt
,
838 tp ut_argument LOCALE_ARG
);
839 add (len
, my_strftime (p
, maxsize
- i
, subfmt
,
840 tp ut_argument LOCALE_ARG
));
843 while (old_start
< p
)
845 *old_start
= TOUPPER ((UCHAR_T
) *old_start
, loc
);
851 #if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
854 /* The relevant information is available only via the
855 underlying strftime implementation, so use that. */
858 char ubuf
[1024]; /* enough for any single format in practice */
860 /* Make sure we're calling the actual underlying strftime.
861 In some cases, config.h contains something like
862 "#define strftime rpl_strftime". */
873 len
= strftime (ubuf
, sizeof ubuf
, ufmt
, tp
);
874 if (len
== 0 && ubuf
[0] != '\0')
882 if (modifier
== L_('O'))
884 if (modifier
== L_('E'))
886 #if HAVE_STRUCT_ERA_ENTRY
887 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
891 size_t len
= __wcslen (era
->era_wname
);
892 cpy (len
, era
->era_wname
);
894 size_t len
= strlen (era
->era_name
);
895 cpy (len
, era
->era_name
);
901 goto underlying_strftime
;
907 int year
= tp
->tm_year
+ TM_YEAR_BASE
;
908 DO_NUMBER (1, year
/ 100 - (year
% 100 < 0));
912 if (modifier
== L_('O'))
915 if (! (modifier
== L_('E')
917 (const CHAR_T
*)_NL_CURRENT (LC_TIME
, NLW(ERA_D_FMT
)))
919 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(D_FMT
));
923 goto underlying_strftime
;
931 subfmt
= L_("%m/%d/%y");
935 if (modifier
== L_('E'))
938 DO_NUMBER (2, tp
->tm_mday
);
941 if (modifier
== L_('E'))
944 DO_NUMBER_SPACEPAD (2, tp
->tm_mday
);
946 /* All numeric formats set DIGITS and NUMBER_VALUE and then
947 jump to one of these two labels. */
950 /* Force `_' flag unless overwritten by `0' or '-' flag. */
951 if (pad
!= L_('0') && pad
!= L_('-'))
955 /* Format the number according to the MODIFIER flag. */
957 if (modifier
== L_('O') && 0 <= number_value
)
960 /* Get the locale specific alternate representation of
961 the number NUMBER_VALUE. If none exist NULL is returned. */
962 const CHAR_T
*cp
= nl_get_alt_digit (number_value
967 size_t digitlen
= STRLEN (cp
);
976 goto underlying_strftime
;
981 unsigned int u
= number_value
;
983 bufp
= buf
+ sizeof (buf
) / sizeof (buf
[0]);
984 negative_number
= number_value
< 0;
990 *--bufp
= u
% 10 + L_('0');
991 while ((u
/= 10) != 0);
994 do_number_sign_and_padding
:
1000 int padding
= digits
- (buf
+ (sizeof (buf
) / sizeof (buf
[0]))
1007 if ((size_t) padding
>= maxsize
- i
)
1011 memset_space (p
, padding
);
1013 width
= width
> padding
? width
- padding
: 0;
1017 if ((size_t) digits
>= maxsize
- i
)
1020 if (negative_number
)
1030 memset_zero (p
, padding
);
1037 cpy (buf
+ sizeof (buf
) / sizeof (buf
[0]) - bufp
, bufp
);
1043 subfmt
= L_("%Y-%m-%d");
1047 if (modifier
== L_('E'))
1050 DO_NUMBER (2, tp
->tm_hour
);
1053 if (modifier
== L_('E'))
1056 DO_NUMBER (2, hour12
);
1058 case L_('k'): /* GNU extension. */
1059 if (modifier
== L_('E'))
1062 DO_NUMBER_SPACEPAD (2, tp
->tm_hour
);
1064 case L_('l'): /* GNU extension. */
1065 if (modifier
== L_('E'))
1068 DO_NUMBER_SPACEPAD (2, hour12
);
1071 if (modifier
== L_('E'))
1074 DO_NUMBER (3, 1 + tp
->tm_yday
);
1077 if (modifier
== L_('E'))
1080 DO_NUMBER (2, tp
->tm_min
);
1083 if (modifier
== L_('E'))
1086 DO_NUMBER (2, tp
->tm_mon
+ 1);
1089 add (1, *p
= L_('\n'));
1094 #if !defined _NL_CURRENT && HAVE_STRFTIME
1095 format_char
= L_('p');
1105 #if defined _NL_CURRENT || !HAVE_STRFTIME
1109 goto underlying_strftime
;
1113 subfmt
= L_("%H:%M");
1117 #if !defined _NL_CURRENT && HAVE_STRFTIME
1118 goto underlying_strftime
;
1121 if (*(subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
,
1125 subfmt
= L_("%I:%M:%S %p");
1130 if (modifier
== L_('E'))
1133 DO_NUMBER (2, tp
->tm_sec
);
1135 case L_('s'): /* GNU extension. */
1143 /* Generate string value for T using time_t arithmetic;
1144 this works even if sizeof (long) < sizeof (time_t). */
1146 bufp
= buf
+ sizeof (buf
) / sizeof (buf
[0]);
1147 negative_number
= t
< 0;
1154 if (negative_number
)
1158 /* Adjust if division truncates to minus infinity. */
1159 if (0 < -1 % 10 && d
< 0)
1166 *--bufp
= d
+ L_('0');
1171 goto do_number_sign_and_padding
;
1175 if (modifier
== L_('O'))
1178 if (! (modifier
== L_('E')
1180 (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(ERA_T_FMT
)))
1182 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(T_FMT
));
1186 goto underlying_strftime
;
1192 subfmt
= L_("%H:%M:%S");
1196 add (1, *p
= L_('\t'));
1200 DO_NUMBER (1, (tp
->tm_wday
- 1 + 7) % 7 + 1);
1203 if (modifier
== L_('E'))
1206 DO_NUMBER (2, (tp
->tm_yday
- tp
->tm_wday
+ 7) / 7);
1211 if (modifier
== L_('E'))
1214 int year
= tp
->tm_year
+ TM_YEAR_BASE
;
1215 int days
= iso_week_days (tp
->tm_yday
, tp
->tm_wday
);
1219 /* This ISO week belongs to the previous year. */
1221 days
= iso_week_days (tp
->tm_yday
+ (365 + __isleap (year
)),
1226 int d
= iso_week_days (tp
->tm_yday
- (365 + __isleap (year
)),
1230 /* This ISO week belongs to the next year. */
1239 DO_NUMBER (2, (year
% 100 + 100) % 100);
1242 DO_NUMBER (1, year
);
1245 DO_NUMBER (2, days
/ 7 + 1);
1250 if (modifier
== L_('E'))
1253 DO_NUMBER (2, (tp
->tm_yday
- (tp
->tm_wday
- 1 + 7) % 7 + 7) / 7);
1256 if (modifier
== L_('E'))
1259 DO_NUMBER (1, tp
->tm_wday
);
1262 if (modifier
== 'E')
1264 #if HAVE_STRUCT_ERA_ENTRY
1265 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
1268 # ifdef COMPILE_WIDE
1269 subfmt
= era
->era_wformat
;
1271 subfmt
= era
->era_format
;
1277 goto underlying_strftime
;
1281 if (modifier
== L_('O'))
1284 DO_NUMBER (1, tp
->tm_year
+ TM_YEAR_BASE
);
1287 if (modifier
== L_('E'))
1289 #if HAVE_STRUCT_ERA_ENTRY
1290 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
1293 int delta
= tp
->tm_year
- era
->start_date
[0];
1294 DO_NUMBER (1, (era
->offset
1295 + delta
* era
->absolute_direction
));
1299 goto underlying_strftime
;
1303 DO_NUMBER (2, (tp
->tm_year
% 100 + 100) % 100);
1313 /* The tzset() call might have changed the value. */
1314 if (!(zone
&& *zone
) && tp
->tm_isdst
>= 0)
1315 zone
= tzname
[tp
->tm_isdst
];
1322 /* The zone string is always given in multibyte form. We have
1323 to transform it first. */
1326 widen (zone
, wczone
, len
);
1330 cpy (strlen (zone
), zone
);
1335 if (tp
->tm_isdst
< 0)
1341 diff
= tp
->tm_gmtoff
;
1354 if (lt
== (time_t) -1)
1356 /* mktime returns -1 for errors, but -1 is also a
1357 valid time_t value. Check whether an error really
1361 if (! __localtime_r (<
, &tm
)
1362 || ((ltm
.tm_sec
^ tm
.tm_sec
)
1363 | (ltm
.tm_min
^ tm
.tm_min
)
1364 | (ltm
.tm_hour
^ tm
.tm_hour
)
1365 | (ltm
.tm_mday
^ tm
.tm_mday
)
1366 | (ltm
.tm_mon
^ tm
.tm_mon
)
1367 | (ltm
.tm_year
^ tm
.tm_year
)))
1371 if (! __gmtime_r (<
, >m
))
1374 diff
= tm_diff (<m
, >m
);
1380 add (1, *p
= L_('-'));
1384 add (1, *p
= L_('+'));
1387 DO_NUMBER (4, (diff
/ 60) * 100 + diff
% 60);
1390 case L_('\0'): /* GNU extension: % at end of format. */
1394 /* Unknown format; output the format, including the '%',
1395 since this is most likely the right thing to do if a
1396 multibyte string has been misparsed. */
1400 for (flen
= 1; f
[1 - flen
] != L_('%'); flen
++)
1402 cpy (flen
, &f
[1 - flen
]);
1408 if (p
&& maxsize
!= 0)
1413 libc_hidden_def (my_strftime
)
1418 /* For Emacs we have a separate interface which corresponds to the normal
1419 strftime function and does not have the extra information whether the
1420 TP arguments comes from a `gmtime' call or not. */
1422 emacs_strftime (s
, maxsize
, format
, tp
)
1426 const struct tm
*tp
;
1428 return my_strftime (s
, maxsize
, format
, tp
, 0);
1432 #if defined _LIBC && !defined COMPILE_WIDE
1433 weak_alias (__strftime_l
, strftime_l
)