1 /* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2 2001, 2002, 2003, 2004, 2005, 2006, 2007
3 Free Software Foundation, Inc.
5 NOTE: The canonical source of this file is maintained with gnulib.
6 Bugs can be reported to bug-gnulib@gnu.org.
8 This file is part of the GNU Emacs.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation; either version 2, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public
21 License along with the GNU C Library; see the file COPYING. If not,
22 write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 Boston, MA 02110-1301, USA. */
30 # define HAVE_LIMITS_H 1
32 # define HAVE_MBRLEN 1
33 # define HAVE_STRUCT_ERA_ENTRY 1
34 # define HAVE_TM_GMTOFF 1
35 # define HAVE_TM_ZONE 1
36 # define HAVE_TZNAME 1
38 # define MULTIBYTE_IS_FORMAT_SAFE 1
39 # define STDC_HEADERS 1
40 # include "../locale/localeinfo.h"
44 #include <sys/types.h> /* Some systems define `time_t' here. */
46 #ifdef TIME_WITH_SYS_TIME
47 # include <sys/time.h>
50 # ifdef HAVE_SYS_TIME_H
51 # include <sys/time.h>
58 extern char *tzname
[];
62 /* Do multibyte processing if multibytes are supported, unless
63 multibyte sequences are safe in formats. Multibyte sequences are
64 safe if they cannot contain byte sequences that look like format
65 conversion specifications. The GNU C Library uses UTF8 multibyte
66 encoding, which is safe for formats, but strftime.c can be used
67 with other C libraries that use unsafe encodings. */
68 #define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
73 # ifdef HAVE_SYS__MBSTATE_T_H /* previously tested __hpux */
74 # include <sys/_mbstate_t.h>
76 # if !defined (mbsinit) && !defined (HAVE_MBSINIT)
77 # define mbsinit(ps) 1
78 # endif /* !defined (mbsinit) && !defined (HAVE_MBSINIT) */
80 /* Simulate mbrlen with mblen as best we can. */
81 # define mbstate_t int
82 # define mbrlen(s, n, ps) mblen (s, n)
83 # define mbsinit(ps) (*(ps) == 0)
85 static const mbstate_t mbstate_zero
;
98 # define memcpy(d, s, n) bcopy ((s), (d), (n))
104 # define CHAR_T wchar_t
105 # define UCHAR_T unsigned int
106 # define L_(Str) L##Str
107 # define NLW(Sym) _NL_W##Sym
109 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
110 # define STRLEN(s) __wcslen (s)
114 # define UCHAR_T unsigned char
116 # define NLW(Sym) Sym
118 # if !defined STDC_HEADERS && !defined HAVE_MEMCPY
119 # define MEMCPY(d, s, n) bcopy ((s), (d), (n))
121 # define MEMCPY(d, s, n) memcpy ((d), (s), (n))
123 # define STRLEN(s) strlen (s)
126 # define MEMPCPY(d, s, n) __mempcpy (d, s, n)
128 # ifndef HAVE_MEMPCPY
129 # define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n)))
150 #define TYPE_SIGNED(t) ((t) -1 < 0)
152 /* Bound on length of the string representing an integer value of type t.
153 Subtract one for the sign bit if t is signed;
154 302 / 1000 is log10 (2) rounded up;
155 add one for integer division truncation;
156 add one more for a minus sign if t is signed. */
157 #define INT_STRLEN_BOUND(t) \
158 ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 + 1 + TYPE_SIGNED (t))
160 #define TM_YEAR_BASE 1900
163 /* Nonzero if YEAR is a leap year (every 4 years,
164 except every 100th isn't, and every 400th is). */
165 # define __isleap(year) \
166 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
171 # define my_strftime_gmtime_r __gmtime_r
172 # define my_strftime_localtime_r __localtime_r
173 # define tzname __tzname
174 # define tzset __tzset
177 /* If we're a strftime substitute in a GNU program, then prefer gmtime
178 to gmtime_r, since many gmtime_r implementations are buggy.
179 Similarly for localtime_r. */
181 # if ! HAVE_TM_GMTOFF
183 my_strftime_gmtime_r (const time_t *t
, struct tm
*tp
)
185 struct tm
*l
= gmtime (t
);
193 my_strftime_localtime_r (const time_t *t
, struct tm
*tp
)
195 struct tm
*l
= localtime (t
);
201 # endif /* ! HAVE_TM_GMTOFF */
202 #endif /* ! defined _LIBC */
205 #if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
206 /* Some systems lack the `memset' function and we don't want to
207 introduce additional dependencies. */
208 /* The SGI compiler reportedly barfs on the trailing null
209 if we use a string constant as the initializer. 28 June 1997, rms. */
210 static const CHAR_T spaces
[16] = /* " " */
212 L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),
213 L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' ')
215 static const CHAR_T zeroes
[16] = /* "0000000000000000" */
217 L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),
218 L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0')
221 # define memset_space(P, Len) \
227 int _this = _len > 16 ? 16 : _len; \
228 (P) = MEMPCPY ((P), spaces, _this * sizeof (CHAR_T)); \
234 # define memset_zero(P, Len) \
240 int _this = _len > 16 ? 16 : _len; \
241 (P) = MEMPCPY ((P), zeroes, _this * sizeof (CHAR_T)); \
248 # define memset_space(P, Len) (wmemset ((P), L' ', (Len)), (P) += (Len))
249 # define memset_zero(P, Len) (wmemset ((P), L'0', (Len)), (P) += (Len))
251 # define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
252 # define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
260 int _delta = width - _n; \
261 int _incr = _n + (_delta > 0 ? _delta : 0); \
262 if ((size_t) _incr >= maxsize - i) \
268 if (pad == L_('0')) \
269 memset_zero (p, _delta); \
271 memset_space (p, _delta); \
282 memcpy_lowcase (p, (s), _n LOCALE_ARG); \
283 else if (to_uppcase) \
284 memcpy_uppcase (p, (s), _n LOCALE_ARG); \
286 MEMCPY ((PTR) p, (const PTR) (s), _n))
289 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
290 # undef __mbsrtowcs_l
291 # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
293 # define widen(os, ws, l) \
296 const char *__s = os; \
297 memset (&__st, '\0', sizeof (__st)); \
298 l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
299 ws = (wchar_t *) alloca ((l + 1) * sizeof (wchar_t)); \
300 (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
305 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
306 /* We use this code also for the extended locale handling where the
307 function gets as an additional argument the locale which has to be
308 used. To access the values we have to redefine the _NL_CURRENT
310 # define strftime __strftime_l
311 # define wcsftime __wcsftime_l
313 # define _NL_CURRENT(category, item) \
314 (current->values[_NL_ITEM_INDEX (item)].string)
315 # define LOCALE_ARG , loc
316 # define LOCALE_PARAM_DECL , __locale_t loc
317 # define HELPER_LOCALE_ARG , current
320 # define LOCALE_PARAM_DECL
322 # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
324 # define HELPER_LOCALE_ARG
329 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
330 # define TOUPPER(Ch, L) __towupper_l (Ch, L)
331 # define TOLOWER(Ch, L) __towlower_l (Ch, L)
333 # define TOUPPER(Ch, L) towupper (Ch)
334 # define TOLOWER(Ch, L) towlower (Ch)
338 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
339 # define TOUPPER(Ch, L) __toupper_l (Ch, L)
340 # define TOLOWER(Ch, L) __tolower_l (Ch, L)
342 # define TOUPPER(Ch, L) toupper (Ch)
343 # define TOLOWER(Ch, L) tolower (Ch)
346 # define TOUPPER(Ch, L) (islower (Ch) ? toupper (Ch) : (Ch))
347 # define TOLOWER(Ch, L) (isupper (Ch) ? tolower (Ch) : (Ch))
350 /* We don't use `isdigit' here since the locale dependent
351 interpretation is not what we want here. We only need to accept
352 the arabic digits in the ASCII range. One day there is perhaps a
353 more reliable way to accept other sets of digits. */
354 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
357 memcpy_lowcase (CHAR_T
*dest
, const CHAR_T
*src
, size_t len LOCALE_PARAM_DECL
)
360 dest
[len
] = TOLOWER ((UCHAR_T
) src
[len
], loc
);
365 memcpy_uppcase (CHAR_T
*dest
, const CHAR_T
*src
, size_t len LOCALE_PARAM_DECL
)
368 dest
[len
] = TOUPPER ((UCHAR_T
) src
[len
], loc
);
374 /* Yield the difference between *A and *B,
375 measured in seconds, ignoring leap seconds. */
376 # define tm_diff ftime_tm_diff
378 tm_diff (const struct tm
*a
, const struct tm
*b
)
380 /* Compute intervening leap days correctly even if year is negative.
381 Take care to avoid int overflow in leap day calculations,
382 but it's OK to assume that A and B are close to each other. */
383 int a4
= (a
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (a
->tm_year
& 3);
384 int b4
= (b
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (b
->tm_year
& 3);
385 int a100
= a4
/ 25 - (a4
% 25 < 0);
386 int b100
= b4
/ 25 - (b4
% 25 < 0);
387 int a400
= a100
>> 2;
388 int b400
= b100
>> 2;
389 int intervening_leap_days
= (a4
- b4
) - (a100
- b100
) + (a400
- b400
);
390 int years
= a
->tm_year
- b
->tm_year
;
391 int days
= (365 * years
+ intervening_leap_days
392 + (a
->tm_yday
- b
->tm_yday
));
393 return (60 * (60 * (24 * days
+ (a
->tm_hour
- b
->tm_hour
))
394 + (a
->tm_min
- b
->tm_min
))
395 + (a
->tm_sec
- b
->tm_sec
));
397 #endif /* ! HAVE_TM_GMTOFF */
401 /* The number of days from the first day of the first ISO week of this
402 year to the year day YDAY with week day WDAY. ISO weeks start on
403 Monday; the first ISO week has the year's first Thursday. YDAY may
404 be as small as YDAY_MINIMUM. */
405 #define ISO_WEEK_START_WDAY 1 /* Monday */
406 #define ISO_WEEK1_WDAY 4 /* Thursday */
407 #define YDAY_MINIMUM (-366)
408 static int iso_week_days (int, int);
413 iso_week_days (int yday
, int wday
)
415 /* Add enough to the first operand of % to make it nonnegative. */
416 int big_enough_multiple_of_7
= (-YDAY_MINIMUM
/ 7 + 2) * 7;
418 - (yday
- wday
+ ISO_WEEK1_WDAY
+ big_enough_multiple_of_7
) % 7
419 + ISO_WEEK1_WDAY
- ISO_WEEK_START_WDAY
);
423 #if !(defined _NL_CURRENT || HAVE_STRFTIME)
424 static CHAR_T
const weekday_name
[][10] =
426 L_("Sunday"), L_("Monday"), L_("Tuesday"), L_("Wednesday"),
427 L_("Thursday"), L_("Friday"), L_("Saturday")
429 static CHAR_T
const month_name
[][10] =
431 L_("January"), L_("February"), L_("March"), L_("April"), L_("May"),
432 L_("June"), L_("July"), L_("August"), L_("September"), L_("October"),
433 L_("November"), L_("December")
438 /* When compiling this file, GNU applications can #define my_strftime
439 to a symbol (typically nstrftime) to get an extended strftime with
440 extra arguments UT and NS. */
443 # define extra_args , ut, ns
444 # define extra_args_spec , int ut, int ns
447 # define my_strftime wcsftime
448 # define nl_get_alt_digit _nl_get_walt_digit
450 # define my_strftime strftime
451 # define nl_get_alt_digit _nl_get_alt_digit
454 # define extra_args_spec
455 /* We don't have this information in general. */
460 #if !defined _LIBC && !defined(WINDOWSNT) && HAVE_TZNAME && HAVE_TZSET
461 /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
462 Work around this bug by copying *tp before it might be munged. */
464 _strftime_copytm (CHAR_T
*s
, size_t maxsize
, const CHAR_T
*format
,
465 const struct tm
*tp extra_args_spec LOCALE_PARAM_DECL
);
467 my_strftime (CHAR_T
*s
, size_t maxsize
, const CHAR_T
*format
,
468 const struct tm
*tp extra_args_spec
)
472 return _strftime_copytm (s
, maxsize
, format
, &tmcopy extra_args
);
475 # define my_strftime _strftime_copytm
479 /* Write information from TP into S according to the format
480 string FORMAT, writing no more that MAXSIZE characters
481 (including the terminating '\0') and returning number of
482 characters written. If S is NULL, nothing will be written
483 anywhere, so to determine how many characters would be
484 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
486 my_strftime (CHAR_T
*s
, size_t maxsize
, const CHAR_T
*format
,
487 const struct tm
*tp extra_args_spec LOCALE_PARAM_DECL
)
489 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
490 struct locale_data
*const current
= loc
->__locales
[LC_TIME
];
493 int hour12
= tp
->tm_hour
;
495 /* We cannot make the following values variables since we must delay
496 the evaluation of these values until really needed since some
497 expressions might not be valid in every situation. The `struct tm'
498 might be generated by a strptime() call that initialized
499 only a few elements. Dereference the pointers only if the format
500 requires this. Then it is ok to fail if the pointers are invalid. */
502 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
504 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
506 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
508 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
510 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
511 ? NLW(PM_STR) : NLW(AM_STR)))
513 # define aw_len STRLEN (a_wkday)
514 # define am_len STRLEN (a_month)
515 # define ap_len STRLEN (ampm)
518 # define f_wkday (weekday_name[tp->tm_wday])
519 # define f_month (month_name[tp->tm_mon])
520 # define a_wkday f_wkday
521 # define a_month f_month
522 # define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
533 #if DO_MULTIBYTE && !defined COMPILE_WIDE
534 const char *format_end
= NULL
;
539 /* The POSIX test suite assumes that setting
540 the environment variable TZ to a new value before calling strftime()
541 will influence the result (the %Z format) even if the information in
542 TP is computed with a totally different time zone.
543 This is bogus: though POSIX allows bad behavior like this,
544 POSIX does not require it. Do the right thing instead. */
545 zone
= (const char *) tp
->tm_zone
;
550 if (! (zone
&& *zone
))
555 /* POSIX.1 requires that local time zone information be used as
556 though strftime called tzset. */
569 for (f
= format
; *f
!= '\0'; ++f
)
571 int pad
= 0; /* Padding for number ('-', '_', or 0). */
572 int modifier
; /* Field modifier ('E', 'O', or 0). */
573 int digits
; /* Max digits for numeric format. */
574 int number_value
; /* Numeric value to be printed. */
575 int negative_number
; /* 1 if the number is negative. */
576 const CHAR_T
*subfmt
;
578 CHAR_T buf
[1 + (sizeof (int) < sizeof (time_t)
579 ? INT_STRLEN_BOUND (time_t)
580 : INT_STRLEN_BOUND (int))];
587 #if DO_MULTIBYTE && !defined COMPILE_WIDE
593 case L_('\b'): case L_('\t'): case L_('\n'):
594 case L_('\v'): case L_('\f'): case L_('\r'):
595 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
596 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
597 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
598 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
599 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
600 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
601 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
602 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
603 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
604 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
605 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
606 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
607 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
608 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
609 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
610 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
611 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
612 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
614 /* The C Standard requires these 98 characters (plus '%') to
615 be in the basic execution character set. None of these
616 characters can start a multibyte sequence, so they need
617 not be analyzed further. */
622 /* Copy this multibyte sequence until we reach its end, find
623 an error, or come back to the initial shift state. */
625 mbstate_t mbstate
= mbstate_zero
;
630 format_end
= f
+ strlen (f
) + 1;
631 fsize
= format_end
- f
;
635 size_t bytes
= mbrlen (f
+ len
, fsize
- len
, &mbstate
);
640 if (bytes
== (size_t) -2)
642 len
+= strlen (f
+ len
);
646 if (bytes
== (size_t) -1)
654 while (! mbsinit (&mbstate
));
662 #else /* ! DO_MULTIBYTE */
664 /* Either multibyte encodings are not supported, they are
665 safe for formats, so any non-'%' byte can be copied through,
666 or this is the wide character version. */
673 #endif /* ! DO_MULTIBYTE */
675 /* Check for flags that can modify a format. */
680 /* This influences the number formats. */
687 /* This changes textual output. */
701 /* As a GNU extension we allow to specify the field width. */
707 if (width
> INT_MAX
/ 10
708 || (width
== INT_MAX
/ 10 && *f
- L_('0') > INT_MAX
% 10))
709 /* Avoid overflow. */
714 width
+= *f
- L_('0');
718 while (ISDIGIT (*f
));
721 /* Check for modifiers. */
734 /* Now do the specified format. */
738 #define DO_NUMBER(d, v) \
739 digits = d > width ? d : width; \
740 number_value = v; goto do_number
741 #define DO_NUMBER_SPACEPAD(d, v) \
742 digits = d > width ? d : width; \
743 number_value = v; goto do_number_spacepad
759 #if defined _NL_CURRENT || !HAVE_STRFTIME
760 cpy (aw_len
, a_wkday
);
763 goto underlying_strftime
;
774 #if defined _NL_CURRENT || !HAVE_STRFTIME
775 cpy (STRLEN (f_wkday
), f_wkday
);
778 goto underlying_strftime
;
790 #if defined _NL_CURRENT || !HAVE_STRFTIME
791 cpy (am_len
, a_month
);
794 goto underlying_strftime
;
805 #if defined _NL_CURRENT || !HAVE_STRFTIME
806 cpy (STRLEN (f_month
), f_month
);
809 goto underlying_strftime
;
813 if (modifier
== L_('O'))
816 if (! (modifier
== 'E'
818 (const CHAR_T
*) _NL_CURRENT (LC_TIME
,
821 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(D_T_FMT
));
824 goto underlying_strftime
;
826 subfmt
= L_("%a %b %e %H:%M:%S %Y");
832 CHAR_T
*old_start
= p
;
833 size_t len
= my_strftime (NULL
, (size_t) -1, subfmt
,
834 tp extra_args LOCALE_ARG
);
835 add (len
, my_strftime (p
, maxsize
- i
, subfmt
,
836 tp extra_args LOCALE_ARG
));
839 while (old_start
< p
)
841 *old_start
= TOUPPER ((UCHAR_T
) *old_start
, loc
);
847 #if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
850 /* The relevant information is available only via the
851 underlying strftime implementation, so use that. */
854 char ubuf
[1024]; /* enough for any single format in practice */
856 /* Make sure we're calling the actual underlying strftime.
857 In some cases, config.h contains something like
858 "#define strftime rpl_strftime". */
864 #ifdef STRFTIME_NO_POSIX2
865 /* Some system libraries do not support the POSIX.2 extensions.
866 In those cases, convert %h to %b, and strip modifiers. */
868 if (format_char
== 'h')
876 len
= strftime (ubuf
, sizeof ubuf
, ufmt
, tp
);
877 if (len
== 0 && ubuf
[0] != '\0')
885 if (modifier
== L_('O'))
887 if (modifier
== L_('E'))
889 #if HAVE_STRUCT_ERA_ENTRY
890 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
894 size_t len
= __wcslen (era
->era_wname
);
895 cpy (len
, era
->era_wname
);
897 size_t len
= strlen (era
->era_name
);
898 cpy (len
, era
->era_name
);
904 goto underlying_strftime
;
910 int year
= tp
->tm_year
+ TM_YEAR_BASE
;
911 DO_NUMBER (1, year
/ 100 - (year
% 100 < 0));
915 if (modifier
== L_('O'))
918 if (! (modifier
== L_('E')
920 (const CHAR_T
*)_NL_CURRENT (LC_TIME
, NLW(ERA_D_FMT
)))
922 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(D_FMT
));
926 goto underlying_strftime
;
934 subfmt
= L_("%m/%d/%y");
938 if (modifier
== L_('E'))
941 DO_NUMBER (2, tp
->tm_mday
);
944 if (modifier
== L_('E'))
947 DO_NUMBER_SPACEPAD (2, tp
->tm_mday
);
949 /* All numeric formats set DIGITS and NUMBER_VALUE and then
950 jump to one of these two labels. */
953 /* Force `_' flag unless overridden by `0' or `-' flag. */
954 if (pad
!= L_('0') && pad
!= L_('-'))
958 /* Format the number according to the MODIFIER flag. */
960 if (modifier
== L_('O') && 0 <= number_value
)
963 /* Get the locale specific alternate representation of
964 the number NUMBER_VALUE. If none exist NULL is returned. */
965 const CHAR_T
*cp
= nl_get_alt_digit (number_value
970 size_t digitlen
= STRLEN (cp
);
979 goto underlying_strftime
;
984 unsigned int u
= number_value
;
986 bufp
= buf
+ sizeof (buf
) / sizeof (buf
[0]);
987 negative_number
= number_value
< 0;
993 *--bufp
= u
% 10 + L_('0');
994 while ((u
/= 10) != 0);
997 do_number_sign_and_padding
:
1003 int padding
= digits
- (buf
+ (sizeof (buf
) / sizeof (buf
[0]))
1010 if ((size_t) padding
>= maxsize
- i
)
1014 memset_space (p
, padding
);
1016 width
= width
> padding
? width
- padding
: 0;
1020 if ((size_t) digits
>= maxsize
- i
)
1023 if (negative_number
)
1033 memset_zero (p
, padding
);
1040 cpy (buf
+ sizeof (buf
) / sizeof (buf
[0]) - bufp
, bufp
);
1046 subfmt
= L_("%Y-%m-%d");
1050 if (modifier
== L_('E'))
1053 DO_NUMBER (2, tp
->tm_hour
);
1056 if (modifier
== L_('E'))
1059 DO_NUMBER (2, hour12
);
1061 case L_('k'): /* GNU extension. */
1062 if (modifier
== L_('E'))
1065 DO_NUMBER_SPACEPAD (2, tp
->tm_hour
);
1067 case L_('l'): /* GNU extension. */
1068 if (modifier
== L_('E'))
1071 DO_NUMBER_SPACEPAD (2, hour12
);
1074 if (modifier
== L_('E'))
1077 DO_NUMBER (3, 1 + tp
->tm_yday
);
1080 if (modifier
== L_('E'))
1083 DO_NUMBER (2, tp
->tm_min
);
1086 if (modifier
== L_('E'))
1089 DO_NUMBER (2, tp
->tm_mon
+ 1);
1092 case L_('N'): /* GNU extension. */
1093 if (modifier
== L_('E'))
1099 /* Take an explicit width less than 9 as a precision. */
1101 for (j
= width
; j
< 9; j
++)
1105 DO_NUMBER (9, number_value
);
1109 add (1, *p
= L_('\n'));
1114 #if !defined _NL_CURRENT && HAVE_STRFTIME
1115 format_char
= L_('p');
1125 #if defined _NL_CURRENT || !HAVE_STRFTIME
1129 goto underlying_strftime
;
1133 subfmt
= L_("%H:%M");
1138 if (*(subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
,
1142 subfmt
= L_("%I:%M:%S %p");
1146 if (modifier
== L_('E'))
1149 DO_NUMBER (2, tp
->tm_sec
);
1151 case L_('s'): /* GNU extension. */
1159 /* Generate string value for T using time_t arithmetic;
1160 this works even if sizeof (long) < sizeof (time_t). */
1162 bufp
= buf
+ sizeof (buf
) / sizeof (buf
[0]);
1163 negative_number
= t
< 0;
1170 if (negative_number
)
1174 /* Adjust if division truncates to minus infinity. */
1175 if (0 < -1 % 10 && d
< 0)
1182 *--bufp
= d
+ L_('0');
1187 goto do_number_sign_and_padding
;
1191 if (modifier
== L_('O'))
1194 if (! (modifier
== L_('E')
1196 (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(ERA_T_FMT
)))
1198 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(T_FMT
));
1202 goto underlying_strftime
;
1208 subfmt
= L_("%H:%M:%S");
1212 add (1, *p
= L_('\t'));
1216 DO_NUMBER (1, (tp
->tm_wday
- 1 + 7) % 7 + 1);
1219 if (modifier
== L_('E'))
1222 DO_NUMBER (2, (tp
->tm_yday
- tp
->tm_wday
+ 7) / 7);
1227 if (modifier
== L_('E'))
1230 int year
= tp
->tm_year
+ TM_YEAR_BASE
;
1231 int days
= iso_week_days (tp
->tm_yday
, tp
->tm_wday
);
1235 /* This ISO week belongs to the previous year. */
1237 days
= iso_week_days (tp
->tm_yday
+ (365 + __isleap (year
)),
1242 int d
= iso_week_days (tp
->tm_yday
- (365 + __isleap (year
)),
1246 /* This ISO week belongs to the next year. */
1255 DO_NUMBER (2, (year
% 100 + 100) % 100);
1258 DO_NUMBER (1, year
);
1261 DO_NUMBER (2, days
/ 7 + 1);
1266 if (modifier
== L_('E'))
1269 DO_NUMBER (2, (tp
->tm_yday
- (tp
->tm_wday
- 1 + 7) % 7 + 7) / 7);
1272 if (modifier
== L_('E'))
1275 DO_NUMBER (1, tp
->tm_wday
);
1278 if (modifier
== 'E')
1280 #if HAVE_STRUCT_ERA_ENTRY
1281 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
1284 # ifdef COMPILE_WIDE
1285 subfmt
= era
->era_wformat
;
1287 subfmt
= era
->era_format
;
1293 goto underlying_strftime
;
1297 if (modifier
== L_('O'))
1300 DO_NUMBER (1, tp
->tm_year
+ TM_YEAR_BASE
);
1303 if (modifier
== L_('E'))
1305 #if HAVE_STRUCT_ERA_ENTRY
1306 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
1309 int delta
= tp
->tm_year
- era
->start_date
[0];
1310 DO_NUMBER (1, (era
->offset
1311 + delta
* era
->absolute_direction
));
1315 goto underlying_strftime
;
1319 DO_NUMBER (2, (tp
->tm_year
% 100 + 100) % 100);
1329 /* The tzset() call might have changed the value. */
1330 if (!(zone
&& *zone
) && tp
->tm_isdst
>= 0)
1331 zone
= tzname
[tp
->tm_isdst
];
1338 /* The zone string is always given in multibyte form. We have
1339 to transform it first. */
1342 widen (zone
, wczone
, len
);
1346 cpy (strlen (zone
), zone
);
1351 if (tp
->tm_isdst
< 0)
1357 diff
= tp
->tm_gmtoff
;
1370 if (lt
== (time_t) -1)
1372 /* mktime returns -1 for errors, but -1 is also a
1373 valid time_t value. Check whether an error really
1377 if (! my_strftime_localtime_r (<
, &tm
)
1378 || ((ltm
.tm_sec
^ tm
.tm_sec
)
1379 | (ltm
.tm_min
^ tm
.tm_min
)
1380 | (ltm
.tm_hour
^ tm
.tm_hour
)
1381 | (ltm
.tm_mday
^ tm
.tm_mday
)
1382 | (ltm
.tm_mon
^ tm
.tm_mon
)
1383 | (ltm
.tm_year
^ tm
.tm_year
)))
1387 if (! my_strftime_gmtime_r (<
, >m
))
1390 diff
= tm_diff (<m
, >m
);
1396 add (1, *p
= L_('-'));
1400 add (1, *p
= L_('+'));
1403 DO_NUMBER (4, (diff
/ 60) * 100 + diff
% 60);
1406 case L_('\0'): /* GNU extension: % at end of format. */
1410 /* Unknown format; output the format, including the '%',
1411 since this is most likely the right thing to do if a
1412 multibyte string has been misparsed. */
1416 for (flen
= 1; f
[1 - flen
] != L_('%'); flen
++)
1418 cpy (flen
, &f
[1 - flen
]);
1424 if (p
&& maxsize
!= 0)
1429 libc_hidden_def (my_strftime
)
1435 /* For Emacs we have a separate interface which corresponds to the normal
1436 strftime function plus the ut argument, but without the ns argument. */
1438 emacs_strftimeu (char *s
, size_t maxsize
, const char *format
,
1439 const struct tm
*tp
, int ut
)
1441 return my_strftime (s
, maxsize
, format
, tp
, ut
, 0);