Home | History | Annotate | Line # | Download | only in lib
      1 /* Copyright (C) 1991-1999, 2000, 2001, 2003, 2004, 2005 Free Software
      2    Foundation, Inc.
      3 
      4    NOTE: The canonical source of this file is maintained with the GNU C Library.
      5    Bugs can be reported to bug-glibc (at) prep.ai.mit.edu.
      6 
      7    This program is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 2, or (at your option)
     10    any later version.
     11 
     12    This program is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License along
     18    with this program; if not, write to the Free Software Foundation,
     19    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
     20 #include <sys/cdefs.h>
     21 __RCSID("$NetBSD: strftime.c,v 1.2 2016/05/17 14:00:09 christos Exp $");
     22 
     23 
     24 #ifdef HAVE_CONFIG_H
     25 # include <config.h>
     26 #endif
     27 
     28 #ifdef _LIBC
     29 # define HAVE_MBLEN 1
     30 # define HAVE_MBRLEN 1
     31 # define HAVE_STRUCT_ERA_ENTRY 1
     32 # define HAVE_TM_GMTOFF 1
     33 # define HAVE_TM_ZONE 1
     34 # define HAVE_TZNAME 1
     35 # define HAVE_TZSET 1
     36 # define MULTIBYTE_IS_FORMAT_SAFE 1
     37 # include "../locale/localeinfo.h"
     38 #endif
     39 
     40 #include <ctype.h>
     41 #include <sys/types.h>		/* Some systems define `time_t' here.  */
     42 
     43 #ifdef TIME_WITH_SYS_TIME
     44 # include <sys/time.h>
     45 # include <time.h>
     46 #else
     47 # ifdef HAVE_SYS_TIME_H
     48 #  include <sys/time.h>
     49 # else
     50 #  include <time.h>
     51 # endif
     52 #endif
     53 #if HAVE_TZNAME
     54 extern char *tzname[];
     55 #endif
     56 
     57 /* Do multibyte processing if multibytes are supported, unless
     58    multibyte sequences are safe in formats.  Multibyte sequences are
     59    safe if they cannot contain byte sequences that look like format
     60    conversion specifications.  The GNU C Library uses UTF8 multibyte
     61    encoding, which is safe for formats, but strftime.c can be used
     62    with other C libraries that use unsafe encodings.  */
     63 #define DO_MULTIBYTE (HAVE_MBLEN && HAVE_WCHAR_H && ! MULTIBYTE_IS_FORMAT_SAFE)
     64 
     65 #if DO_MULTIBYTE
     66 # if HAVE_MBRLEN
     67 #  include <wchar.h>
     68 # else
     69    /* Simulate mbrlen with mblen as best we can.  */
     70 #  define mbstate_t int
     71 #  define mbrlen(s, n, ps) mblen (s, n)
     72 #  define mbsinit(ps) (*(ps) == 0)
     73 # endif
     74   static const mbstate_t mbstate_zero;
     75 #endif
     76 
     77 #include <limits.h>
     78 #include <stdbool.h>
     79 #include <stddef.h>
     80 #include <stdlib.h>
     81 #include <string.h>
     82 
     83 #ifdef COMPILE_WIDE
     84 # include <endian.h>
     85 # define CHAR_T wchar_t
     86 # define UCHAR_T unsigned int
     87 # define L_(Str) L##Str
     88 # define NLW(Sym) _NL_W##Sym
     89 
     90 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
     91 # define STRLEN(s) __wcslen (s)
     92 
     93 #else
     94 # define CHAR_T char
     95 # define UCHAR_T unsigned char
     96 # define L_(Str) Str
     97 # define NLW(Sym) Sym
     98 
     99 # define MEMCPY(d, s, n) memcpy (d, s, n)
    100 # define STRLEN(s) strlen (s)
    101 
    102 # ifdef _LIBC
    103 #  define MEMPCPY(d, s, n) __mempcpy (d, s, n)
    104 # else
    105 #  ifndef HAVE_MEMPCPY
    106 #   define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n)))
    107 #  endif
    108 # endif
    109 #endif
    110 
    111 /* Shift A right by B bits portably, by dividing A by 2**B and
    112    truncating towards minus infinity.  A and B should be free of side
    113    effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
    114    INT_BITS is the number of useful bits in an int.  GNU code can
    115    assume that INT_BITS is at least 32.
    116 
    117    ISO C99 says that A >> B is implementation-defined if A < 0.  Some
    118    implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
    119    right in the usual way when A < 0, so SHR falls back on division if
    120    ordinary A >> B doesn't seem to be the usual signed shift.  */
    121 #define SHR(a, b)	\
    122   (-1 >> 1 == -1	\
    123    ? (a) >> (b)		\
    124    : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
    125 
    126 /* Bound on length of the string representing an integer type or expression T.
    127    Subtract 1 for the sign bit if t is signed; log10 (2.0) < 146/485;
    128    add 1 for integer division truncation; add 1 more for a minus sign
    129    if needed.  */
    130 #define INT_STRLEN_BOUND(t) \
    131   ((sizeof (t) * CHAR_BIT - 1) * 146 / 485 + 2)
    132 
    133 #define TM_YEAR_BASE 1900
    134 
    135 #ifndef __isleap
    136 /* Nonzero if YEAR is a leap year (every 4 years,
    137    except every 100th isn't, and every 400th is).  */
    138 # define __isleap(year)	\
    139   ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
    140 #endif
    141 
    142 
    143 #ifdef _LIBC
    144 # define tzname __tzname
    145 # define tzset __tzset
    146 #endif
    147 
    148 #if !HAVE_TM_GMTOFF
    149 /* Portable standalone applications should supply a "time_r.h" that
    150    declares a POSIX-compliant localtime_r, for the benefit of older
    151    implementations that lack localtime_r or have a nonstandard one.
    152    See the gnulib time_r module for one way to implement this.  */
    153 # include "time_r.h"
    154 # undef __gmtime_r
    155 # undef __localtime_r
    156 # define __gmtime_r gmtime_r
    157 # define __localtime_r localtime_r
    158 #endif
    159 
    160 
    161 #ifdef COMPILE_WIDE
    162 # define memset_space(P, Len) (wmemset (P, L' ', Len), (P) += (Len))
    163 # define memset_zero(P, Len) (wmemset (P, L'0', Len), (P) += (Len))
    164 #else
    165 # define memset_space(P, Len) (memset (P, ' ', Len), (P) += (Len))
    166 # define memset_zero(P, Len) (memset (P, '0', Len), (P) += (Len))
    167 #endif
    168 
    169 #define add(n, f)							      \
    170   do									      \
    171     {									      \
    172       int _n = (n);							      \
    173       int _delta = width - _n;						      \
    174       int _incr = _n + (_delta > 0 ? _delta : 0);			      \
    175       if ((size_t) _incr >= maxsize - i)				      \
    176 	return 0;							      \
    177       if (p)								      \
    178 	{								      \
    179 	  if (_delta > 0)						      \
    180 	    {								      \
    181 	      if (pad == L_('0'))					      \
    182 		memset_zero (p, _delta);				      \
    183 	      else							      \
    184 		memset_space (p, _delta);				      \
    185 	    }								      \
    186 	  f;								      \
    187 	  p += _n;							      \
    188 	}								      \
    189       i += _incr;							      \
    190     } while (0)
    191 
    192 #define cpy(n, s) \
    193     add ((n),								      \
    194 	 if (to_lowcase)						      \
    195 	   memcpy_lowcase (p, (s), _n LOCALE_ARG);			      \
    196 	 else if (to_uppcase)						      \
    197 	   memcpy_uppcase (p, (s), _n LOCALE_ARG);			      \
    198 	 else								      \
    199 	   MEMCPY ((void *) p, (void const *) (s), _n))
    200 
    201 #ifdef COMPILE_WIDE
    202 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
    203 #  undef __mbsrtowcs_l
    204 #  define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
    205 # endif
    206 # define widen(os, ws, l) \
    207   {									      \
    208     mbstate_t __st;							      \
    209     const char *__s = os;						      \
    210     memset (&__st, '\0', sizeof (__st));				      \
    211     l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc);			      \
    212     ws = (wchar_t *) alloca ((l + 1) * sizeof (wchar_t));		      \
    213     (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc);			      \
    214   }
    215 #endif
    216 
    217 
    218 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
    219 /* We use this code also for the extended locale handling where the
    220    function gets as an additional argument the locale which has to be
    221    used.  To access the values we have to redefine the _NL_CURRENT
    222    macro.  */
    223 # define strftime		__strftime_l
    224 # define wcsftime		__wcsftime_l
    225 # undef _NL_CURRENT
    226 # define _NL_CURRENT(category, item) \
    227   (current->values[_NL_ITEM_INDEX (item)].string)
    228 # define LOCALE_ARG , loc
    229 # define LOCALE_PARAM_PROTO , __locale_t loc
    230 # define HELPER_LOCALE_ARG  , current
    231 #else
    232 # define LOCALE_PARAM_PROTO
    233 # define LOCALE_ARG
    234 # ifdef _LIBC
    235 #  define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
    236 # else
    237 #  define HELPER_LOCALE_ARG
    238 # endif
    239 #endif
    240 
    241 #ifdef COMPILE_WIDE
    242 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
    243 #  define TOUPPER(Ch, L) __towupper_l (Ch, L)
    244 #  define TOLOWER(Ch, L) __towlower_l (Ch, L)
    245 # else
    246 #  define TOUPPER(Ch, L) towupper (Ch)
    247 #  define TOLOWER(Ch, L) towlower (Ch)
    248 # endif
    249 #else
    250 # ifdef _LIBC
    251 #  ifdef USE_IN_EXTENDED_LOCALE_MODEL
    252 #   define TOUPPER(Ch, L) __toupper_l (Ch, L)
    253 #   define TOLOWER(Ch, L) __tolower_l (Ch, L)
    254 #  else
    255 #   define TOUPPER(Ch, L) toupper (Ch)
    256 #   define TOLOWER(Ch, L) tolower (Ch)
    257 #  endif
    258 # else
    259 #  define TOUPPER(Ch, L) (islower (Ch) ? toupper (Ch) : (Ch))
    260 #  define TOLOWER(Ch, L) (isupper (Ch) ? tolower (Ch) : (Ch))
    261 # endif
    262 #endif
    263 /* We don't use `isdigit' here since the locale dependent
    264    interpretation is not what we want here.  We only need to accept
    265    the arabic digits in the ASCII range.  One day there is perhaps a
    266    more reliable way to accept other sets of digits.  */
    267 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
    268 
    269 static CHAR_T *
    270 memcpy_lowcase (CHAR_T *dest, const CHAR_T *src,
    271 		size_t len LOCALE_PARAM_PROTO)
    272 {
    273   while (len-- > 0)
    274     dest[len] = TOLOWER ((UCHAR_T) src[len], loc);
    275   return dest;
    276 }
    277 
    278 static CHAR_T *
    279 memcpy_uppcase (CHAR_T *dest, const CHAR_T *src,
    280 		size_t len LOCALE_PARAM_PROTO)
    281 {
    282   while (len-- > 0)
    283     dest[len] = TOUPPER ((UCHAR_T) src[len], loc);
    284   return dest;
    285 }
    286 
    287 
    288 #if ! HAVE_TM_GMTOFF
    289 /* Yield the difference between *A and *B,
    290    measured in seconds, ignoring leap seconds.  */
    291 # define tm_diff ftime_tm_diff
    292 static int
    293 tm_diff (const struct tm *a, const struct tm *b)
    294 {
    295   /* Compute intervening leap days correctly even if year is negative.
    296      Take care to avoid int overflow in leap day calculations,
    297      but it's OK to assume that A and B are close to each other.  */
    298   int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3);
    299   int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3);
    300   int a100 = a4 / 25 - (a4 % 25 < 0);
    301   int b100 = b4 / 25 - (b4 % 25 < 0);
    302   int a400 = SHR (a100, 2);
    303   int b400 = SHR (b100, 2);
    304   int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
    305   int years = a->tm_year - b->tm_year;
    306   int days = (365 * years + intervening_leap_days
    307 	      + (a->tm_yday - b->tm_yday));
    308   return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
    309 		+ (a->tm_min - b->tm_min))
    310 	  + (a->tm_sec - b->tm_sec));
    311 }
    312 #endif /* ! HAVE_TM_GMTOFF */
    313 
    314 
    315 
    316 /* The number of days from the first day of the first ISO week of this
    317    year to the year day YDAY with week day WDAY.  ISO weeks start on
    318    Monday; the first ISO week has the year's first Thursday.  YDAY may
    319    be as small as YDAY_MINIMUM.  */
    320 #define ISO_WEEK_START_WDAY 1 /* Monday */
    321 #define ISO_WEEK1_WDAY 4 /* Thursday */
    322 #define YDAY_MINIMUM (-366)
    323 #ifdef __GNUC__
    324 __inline__
    325 #endif
    326 static int
    327 iso_week_days (int yday, int wday)
    328 {
    329   /* Add enough to the first operand of % to make it nonnegative.  */
    330   int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
    331   return (yday
    332 	  - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
    333 	  + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
    334 }
    335 
    336 
    337 #if !(defined _NL_CURRENT || HAVE_STRFTIME)
    338 static CHAR_T const weekday_name[][10] =
    339   {
    340     L_("Sunday"), L_("Monday"), L_("Tuesday"), L_("Wednesday"),
    341     L_("Thursday"), L_("Friday"), L_("Saturday")
    342   };
    343 static CHAR_T const month_name[][10] =
    344   {
    345     L_("January"), L_("February"), L_("March"), L_("April"), L_("May"),
    346     L_("June"), L_("July"), L_("August"), L_("September"), L_("October"),
    347     L_("November"), L_("December")
    348   };
    349 #endif
    350 
    351 
    352 /* When compiling this file, GNU applications can #define my_strftime
    353    to a symbol (typically nstrftime) to get an extended strftime with
    354    extra arguments UT and NS.  Emacs is a special case for now, but
    355    this Emacs-specific code can be removed once Emacs's config.h
    356    defines my_strftime.  */
    357 #if defined emacs && !defined my_strftime
    358 # define my_strftime nstrftime
    359 #endif
    360 
    361 #ifdef my_strftime
    362 # define extra_args , ut, ns
    363 # define extra_args_spec , int ut, int ns
    364 #else
    365 # ifdef COMPILE_WIDE
    366 #  define my_strftime wcsftime
    367 #  define nl_get_alt_digit _nl_get_walt_digit
    368 # else
    369 #  define my_strftime strftime
    370 #  define nl_get_alt_digit _nl_get_alt_digit
    371 # endif
    372 # define extra_args
    373 # define extra_args_spec
    374 /* We don't have this information in general.  */
    375 # define ut 0
    376 # define ns 0
    377 #endif
    378 
    379 
    380 /* Write information from TP into S according to the format
    381    string FORMAT, writing no more that MAXSIZE characters
    382    (including the terminating '\0') and returning number of
    383    characters written.  If S is NULL, nothing will be written
    384    anywhere, so to determine how many characters would be
    385    written, use NULL for S and (size_t) -1 for MAXSIZE.  */
    386 size_t
    387 my_strftime (CHAR_T *s, size_t maxsize, const CHAR_T *format,
    388 	     const struct tm *tp extra_args_spec LOCALE_PARAM_PROTO)
    389 {
    390 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
    391   struct locale_data *const current = loc->__locales[LC_TIME];
    392 #endif
    393 
    394   int hour12 = tp->tm_hour;
    395 #ifdef _NL_CURRENT
    396   /* We cannot make the following values variables since we must delay
    397      the evaluation of these values until really needed since some
    398      expressions might not be valid in every situation.  The `struct tm'
    399      might be generated by a strptime() call that initialized
    400      only a few elements.  Dereference the pointers only if the format
    401      requires this.  Then it is ok to fail if the pointers are invalid.  */
    402 # define a_wkday \
    403   ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
    404 # define f_wkday \
    405   ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
    406 # define a_month \
    407   ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
    408 # define f_month \
    409   ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
    410 # define ampm \
    411   ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11		      \
    412 				 ? NLW(PM_STR) : NLW(AM_STR)))
    413 
    414 # define aw_len STRLEN (a_wkday)
    415 # define am_len STRLEN (a_month)
    416 # define ap_len STRLEN (ampm)
    417 #else
    418 # if !HAVE_STRFTIME
    419 #  define f_wkday (weekday_name[tp->tm_wday])
    420 #  define f_month (month_name[tp->tm_mon])
    421 #  define a_wkday f_wkday
    422 #  define a_month f_month
    423 #  define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
    424 
    425   size_t aw_len = 3;
    426   size_t am_len = 3;
    427   size_t ap_len = 2;
    428 # endif
    429 #endif
    430   const char *zone;
    431   size_t i = 0;
    432   CHAR_T *p = s;
    433   const CHAR_T *f;
    434 #if DO_MULTIBYTE && !defined COMPILE_WIDE
    435   const char *format_end = NULL;
    436 #endif
    437 
    438 #if ! defined _LIBC && ! HAVE_RUN_TZSET_TEST
    439   /* Solaris 2.5.x and 2.6 tzset sometimes modify the storage returned
    440      by localtime.  On such systems, we must either use the tzset and
    441      localtime wrappers to work around the bug (which sets
    442      HAVE_RUN_TZSET_TEST) or make a copy of the structure.  */
    443   struct tm copy = *tp;
    444   tp = &copy;
    445 #endif
    446 
    447   zone = NULL;
    448 #if HAVE_TM_ZONE
    449   /* The POSIX test suite assumes that setting
    450      the environment variable TZ to a new value before calling strftime()
    451      will influence the result (the %Z format) even if the information in
    452      TP is computed with a totally different time zone.
    453      This is bogus: though POSIX allows bad behavior like this,
    454      POSIX does not require it.  Do the right thing instead.  */
    455   zone = (const char *) tp->tm_zone;
    456 #endif
    457 #if HAVE_TZNAME
    458   if (ut)
    459     {
    460       if (! (zone && *zone))
    461 	zone = "GMT";
    462     }
    463   else
    464     {
    465       /* POSIX.1 requires that local time zone information be used as
    466 	 though strftime called tzset.  */
    467 # if HAVE_TZSET
    468       tzset ();
    469 # endif
    470     }
    471 #endif
    472 
    473   if (hour12 > 12)
    474     hour12 -= 12;
    475   else
    476     if (hour12 == 0)
    477       hour12 = 12;
    478 
    479   for (f = format; *f != '\0'; ++f)
    480     {
    481       int pad = 0;		/* Padding for number ('-', '_', or 0).  */
    482       int modifier;		/* Field modifier ('E', 'O', or 0).  */
    483       int digits;		/* Max digits for numeric format.  */
    484       int number_value;		/* Numeric value to be printed.  */
    485       unsigned int u_number_value; /* (unsigned int) number_value.  */
    486       bool negative_number;	/* 1 if the number is negative.  */
    487       const CHAR_T *subfmt;
    488       CHAR_T *bufp;
    489       CHAR_T buf[1 + (sizeof (int) < sizeof (time_t)
    490 		      ? INT_STRLEN_BOUND (time_t)
    491 		      : INT_STRLEN_BOUND (int))];
    492       int width = -1;
    493       bool to_lowcase = false;
    494       bool to_uppcase = false;
    495       bool change_case = false;
    496       int format_char;
    497 
    498 #if DO_MULTIBYTE && !defined COMPILE_WIDE
    499       switch (*f)
    500 	{
    501 	case L_('%'):
    502 	  break;
    503 
    504 	case L_('\b'): case L_('\t'): case L_('\n'):
    505 	case L_('\v'): case L_('\f'): case L_('\r'):
    506 	case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
    507 	case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
    508 	case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
    509 	case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
    510 	case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
    511 	case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
    512 	case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
    513 	case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
    514 	case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
    515 	case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
    516 	case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
    517 	case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
    518 	case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
    519 	case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
    520 	case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
    521 	case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
    522 	case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
    523 	case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
    524 	case L_('~'):
    525 	  /* The C Standard requires these 98 characters (plus '%') to
    526 	     be in the basic execution character set.  None of these
    527 	     characters can start a multibyte sequence, so they need
    528 	     not be analyzed further.  */
    529 	  add (1, *p = *f);
    530 	  continue;
    531 
    532 	default:
    533 	  /* Copy this multibyte sequence until we reach its end, find
    534 	     an error, or come back to the initial shift state.  */
    535 	  {
    536 	    mbstate_t mbstate = mbstate_zero;
    537 	    size_t len = 0;
    538 	    size_t fsize;
    539 
    540 	    if (! format_end)
    541 	      format_end = f + strlen (f) + 1;
    542 	    fsize = format_end - f;
    543 
    544 	    do
    545 	      {
    546 		size_t bytes = mbrlen (f + len, fsize - len, &mbstate);
    547 
    548 		if (bytes == 0)
    549 		  break;
    550 
    551 		if (bytes == (size_t) -2)
    552 		  {
    553 		    len += strlen (f + len);
    554 		    break;
    555 		  }
    556 
    557 		if (bytes == (size_t) -1)
    558 		  {
    559 		    len++;
    560 		    break;
    561 		  }
    562 
    563 		len += bytes;
    564 	      }
    565 	    while (! mbsinit (&mbstate));
    566 
    567 	    cpy (len, f);
    568 	    f += len - 1;
    569 	    continue;
    570 	  }
    571 	}
    572 
    573 #else /* ! DO_MULTIBYTE */
    574 
    575       /* Either multibyte encodings are not supported, they are
    576 	 safe for formats, so any non-'%' byte can be copied through,
    577 	 or this is the wide character version.  */
    578       if (*f != L_('%'))
    579 	{
    580 	  add (1, *p = *f);
    581 	  continue;
    582 	}
    583 
    584 #endif /* ! DO_MULTIBYTE */
    585 
    586       /* Check for flags that can modify a format.  */
    587       while (1)
    588 	{
    589 	  switch (*++f)
    590 	    {
    591 	      /* This influences the number formats.  */
    592 	    case L_('_'):
    593 	    case L_('-'):
    594 	    case L_('0'):
    595 	      pad = *f;
    596 	      continue;
    597 
    598 	      /* This changes textual output.  */
    599 	    case L_('^'):
    600 	      to_uppcase = true;
    601 	      continue;
    602 	    case L_('#'):
    603 	      change_case = true;
    604 	      continue;
    605 
    606 	    default:
    607 	      break;
    608 	    }
    609 	  break;
    610 	}
    611 
    612       /* As a GNU extension we allow to specify the field width.  */
    613       if (ISDIGIT (*f))
    614 	{
    615 	  width = 0;
    616 	  do
    617 	    {
    618 	      if (width > INT_MAX / 10
    619 		  || (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10))
    620 		/* Avoid overflow.  */
    621 		width = INT_MAX;
    622 	      else
    623 		{
    624 		  width *= 10;
    625 		  width += *f - L_('0');
    626 		}
    627 	      ++f;
    628 	    }
    629 	  while (ISDIGIT (*f));
    630 	}
    631 
    632       /* Check for modifiers.  */
    633       switch (*f)
    634 	{
    635 	case L_('E'):
    636 	case L_('O'):
    637 	  modifier = *f++;
    638 	  break;
    639 
    640 	default:
    641 	  modifier = 0;
    642 	  break;
    643 	}
    644 
    645       /* Now do the specified format.  */
    646       format_char = *f;
    647       switch (format_char)
    648 	{
    649 #define DO_NUMBER(d, v) \
    650 	  digits = d;							      \
    651 	  number_value = v; goto do_number
    652 #define DO_SIGNED_NUMBER(d, negative, v) \
    653 	  digits = d;							      \
    654 	  negative_number = negative;					      \
    655 	  u_number_value = v; goto do_signed_number
    656 #define DO_NUMBER_SPACEPAD(d, v) \
    657 	  digits = d;							      \
    658 	  number_value = v; goto do_number_spacepad
    659 
    660 	case L_('%'):
    661 	  if (modifier != 0)
    662 	    goto bad_format;
    663 	  add (1, *p = *f);
    664 	  break;
    665 
    666 	case L_('a'):
    667 	  if (modifier != 0)
    668 	    goto bad_format;
    669 	  if (change_case)
    670 	    {
    671 	      to_uppcase = true;
    672 	      to_lowcase = false;
    673 	    }
    674 #if defined _NL_CURRENT || !HAVE_STRFTIME
    675 	  cpy (aw_len, a_wkday);
    676 	  break;
    677 #else
    678 	  goto underlying_strftime;
    679 #endif
    680 
    681 	case 'A':
    682 	  if (modifier != 0)
    683 	    goto bad_format;
    684 	  if (change_case)
    685 	    {
    686 	      to_uppcase = true;
    687 	      to_lowcase = false;
    688 	    }
    689 #if defined _NL_CURRENT || !HAVE_STRFTIME
    690 	  cpy (STRLEN (f_wkday), f_wkday);
    691 	  break;
    692 #else
    693 	  goto underlying_strftime;
    694 #endif
    695 
    696 	case L_('b'):
    697 	case L_('h'):
    698 	  if (change_case)
    699 	    {
    700 	      to_uppcase = true;
    701 	      to_lowcase = false;
    702 	    }
    703 	  if (modifier != 0)
    704 	    goto bad_format;
    705 #if defined _NL_CURRENT || !HAVE_STRFTIME
    706 	  cpy (am_len, a_month);
    707 	  break;
    708 #else
    709 	  goto underlying_strftime;
    710 #endif
    711 
    712 	case L_('B'):
    713 	  if (modifier != 0)
    714 	    goto bad_format;
    715 	  if (change_case)
    716 	    {
    717 	      to_uppcase = true;
    718 	      to_lowcase = false;
    719 	    }
    720 #if defined _NL_CURRENT || !HAVE_STRFTIME
    721 	  cpy (STRLEN (f_month), f_month);
    722 	  break;
    723 #else
    724 	  goto underlying_strftime;
    725 #endif
    726 
    727 	case L_('c'):
    728 	  if (modifier == L_('O'))
    729 	    goto bad_format;
    730 #ifdef _NL_CURRENT
    731 	  if (! (modifier == 'E'
    732 		 && (*(subfmt =
    733 		       (const CHAR_T *) _NL_CURRENT (LC_TIME,
    734 						     NLW(ERA_D_T_FMT)))
    735 		     != '\0')))
    736 	    subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
    737 #else
    738 # if HAVE_STRFTIME
    739 	  goto underlying_strftime;
    740 # else
    741 	  subfmt = L_("%a %b %e %H:%M:%S %Y");
    742 # endif
    743 #endif
    744 
    745 	subformat:
    746 	  {
    747 	    CHAR_T *old_start = p;
    748 	    size_t len = my_strftime (NULL, (size_t) -1, subfmt,
    749 				      tp extra_args LOCALE_ARG);
    750 	    add (len, my_strftime (p, maxsize - i, subfmt,
    751 				   tp extra_args LOCALE_ARG));
    752 
    753 	    if (to_uppcase)
    754 	      while (old_start < p)
    755 		{
    756 		  *old_start = TOUPPER ((UCHAR_T) *old_start, loc);
    757 		  ++old_start;
    758 		}
    759 	  }
    760 	  break;
    761 
    762 #if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
    763 	underlying_strftime:
    764 	  {
    765 	    /* The relevant information is available only via the
    766 	       underlying strftime implementation, so use that.  */
    767 	    char ufmt[5];
    768 	    char *u = ufmt;
    769 	    char ubuf[1024]; /* enough for any single format in practice */
    770 	    size_t len;
    771 	    /* Make sure we're calling the actual underlying strftime.
    772 	       In some cases, config.h contains something like
    773 	       "#define strftime rpl_strftime".  */
    774 # ifdef strftime
    775 #  undef strftime
    776 	    size_t strftime ();
    777 # endif
    778 
    779 	    /* The space helps distinguish strftime failure from empty
    780 	       output.  */
    781 	    *u++ = ' ';
    782 	    *u++ = '%';
    783 	    if (modifier != 0)
    784 	      *u++ = modifier;
    785 	    *u++ = format_char;
    786 	    *u = '\0';
    787 	    len = strftime (ubuf, sizeof ubuf, ufmt, tp);
    788 	    if (len != 0)
    789 	      cpy (len - 1, ubuf + 1);
    790 	  }
    791 	  break;
    792 #endif
    793 
    794 	case L_('C'):
    795 	  if (modifier == L_('O'))
    796 	    goto bad_format;
    797 	  if (modifier == L_('E'))
    798 	    {
    799 #if HAVE_STRUCT_ERA_ENTRY
    800 	      struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
    801 	      if (era)
    802 		{
    803 # ifdef COMPILE_WIDE
    804 		  size_t len = __wcslen (era->era_wname);
    805 		  cpy (len, era->era_wname);
    806 # else
    807 		  size_t len = strlen (era->era_name);
    808 		  cpy (len, era->era_name);
    809 # endif
    810 		  break;
    811 		}
    812 #else
    813 # if HAVE_STRFTIME
    814 	      goto underlying_strftime;
    815 # endif
    816 #endif
    817 	    }
    818 
    819 	  {
    820 	    int century = tp->tm_year / 100 + TM_YEAR_BASE / 100;
    821 	    century -= tp->tm_year % 100 < 0 && 0 < century;
    822 	    DO_SIGNED_NUMBER (2, tp->tm_year < - TM_YEAR_BASE, century);
    823 	  }
    824 
    825 	case L_('x'):
    826 	  if (modifier == L_('O'))
    827 	    goto bad_format;
    828 #ifdef _NL_CURRENT
    829 	  if (! (modifier == L_('E')
    830 		 && (*(subfmt =
    831 		       (const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT)))
    832 		     != L_('\0'))))
    833 	    subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
    834 	  goto subformat;
    835 #else
    836 # if HAVE_STRFTIME
    837 	  goto underlying_strftime;
    838 # else
    839 	  /* Fall through.  */
    840 # endif
    841 #endif
    842 	case L_('D'):
    843 	  if (modifier != 0)
    844 	    goto bad_format;
    845 	  subfmt = L_("%m/%d/%y");
    846 	  goto subformat;
    847 
    848 	case L_('d'):
    849 	  if (modifier == L_('E'))
    850 	    goto bad_format;
    851 
    852 	  DO_NUMBER (2, tp->tm_mday);
    853 
    854 	case L_('e'):
    855 	  if (modifier == L_('E'))
    856 	    goto bad_format;
    857 
    858 	  DO_NUMBER_SPACEPAD (2, tp->tm_mday);
    859 
    860 	  /* All numeric formats set DIGITS and NUMBER_VALUE (or U_NUMBER_VALUE)
    861 	     and then jump to one of these three labels.  */
    862 
    863 	do_number_spacepad:
    864 	  /* Force `_' flag unless overridden by `0' or `-' flag.  */
    865 	  if (pad != L_('0') && pad != L_('-'))
    866 	    pad = L_('_');
    867 
    868 	do_number:
    869 	  /* Format NUMBER_VALUE according to the MODIFIER flag.  */
    870 	  negative_number = number_value < 0;
    871 	  u_number_value = number_value;
    872 
    873 	do_signed_number:
    874 	  /* Format U_NUMBER_VALUE according to the MODIFIER flag.
    875 	     NEGATIVE_NUMBER is nonzero if the original number was
    876 	     negative; in this case it was converted directly to
    877 	     unsigned int (i.e., modulo (UINT_MAX + 1)) without
    878 	     negating it.  */
    879 	  if (modifier == L_('O') && !negative_number)
    880 	    {
    881 #ifdef _NL_CURRENT
    882 	      /* Get the locale specific alternate representation of
    883 		 the number.  If none exist NULL is returned.  */
    884 	      const CHAR_T *cp = nl_get_alt_digit (u_number_value
    885 						   HELPER_LOCALE_ARG);
    886 
    887 	      if (cp != NULL)
    888 		{
    889 		  size_t digitlen = STRLEN (cp);
    890 		  if (digitlen != 0)
    891 		    {
    892 		      cpy (digitlen, cp);
    893 		      break;
    894 		    }
    895 		}
    896 #else
    897 # if HAVE_STRFTIME
    898 	      goto underlying_strftime;
    899 # endif
    900 #endif
    901 	    }
    902 
    903 	  bufp = buf + sizeof (buf) / sizeof (buf[0]);
    904 
    905 	  if (negative_number)
    906 	    u_number_value = - u_number_value;
    907 
    908 	  do
    909 	    {
    910 	      *--bufp = u_number_value % 10 + L_('0');
    911 	      u_number_value /= 10;
    912 	    }
    913 	  while (u_number_value != 0);
    914 
    915 	do_number_sign_and_padding:
    916 	  if (digits < width)
    917 	    digits = width;
    918 
    919 	  if (negative_number)
    920 	    *--bufp = L_('-');
    921 
    922 	  if (pad != L_('-'))
    923 	    {
    924 	      int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
    925 				      - bufp);
    926 
    927 	      if (padding > 0)
    928 		{
    929 		  if (pad == L_('_'))
    930 		    {
    931 		      if ((size_t) padding >= maxsize - i)
    932 			return 0;
    933 
    934 		      if (p)
    935 			memset_space (p, padding);
    936 		      i += padding;
    937 		      width = width > padding ? width - padding : 0;
    938 		    }
    939 		  else
    940 		    {
    941 		      if ((size_t) digits >= maxsize - i)
    942 			return 0;
    943 
    944 		      if (negative_number)
    945 			{
    946 			  ++bufp;
    947 
    948 			  if (p)
    949 			    *p++ = L_('-');
    950 			  ++i;
    951 			}
    952 
    953 		      if (p)
    954 			memset_zero (p, padding);
    955 		      i += padding;
    956 		      width = 0;
    957 		    }
    958 		}
    959 	    }
    960 
    961 	  cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
    962 	  break;
    963 
    964 	case L_('F'):
    965 	  if (modifier != 0)
    966 	    goto bad_format;
    967 	  subfmt = L_("%Y-%m-%d");
    968 	  goto subformat;
    969 
    970 	case L_('H'):
    971 	  if (modifier == L_('E'))
    972 	    goto bad_format;
    973 
    974 	  DO_NUMBER (2, tp->tm_hour);
    975 
    976 	case L_('I'):
    977 	  if (modifier == L_('E'))
    978 	    goto bad_format;
    979 
    980 	  DO_NUMBER (2, hour12);
    981 
    982 	case L_('k'):		/* GNU extension.  */
    983 	  if (modifier == L_('E'))
    984 	    goto bad_format;
    985 
    986 	  DO_NUMBER_SPACEPAD (2, tp->tm_hour);
    987 
    988 	case L_('l'):		/* GNU extension.  */
    989 	  if (modifier == L_('E'))
    990 	    goto bad_format;
    991 
    992 	  DO_NUMBER_SPACEPAD (2, hour12);
    993 
    994 	case L_('j'):
    995 	  if (modifier == L_('E'))
    996 	    goto bad_format;
    997 
    998 	  DO_SIGNED_NUMBER (3, tp->tm_yday < -1, tp->tm_yday + 1U);
    999 
   1000 	case L_('M'):
   1001 	  if (modifier == L_('E'))
   1002 	    goto bad_format;
   1003 
   1004 	  DO_NUMBER (2, tp->tm_min);
   1005 
   1006 	case L_('m'):
   1007 	  if (modifier == L_('E'))
   1008 	    goto bad_format;
   1009 
   1010 	  DO_SIGNED_NUMBER (2, tp->tm_mon < -1, tp->tm_mon + 1U);
   1011 
   1012 #ifndef _LIBC
   1013 	case L_('N'):		/* GNU extension.  */
   1014 	  if (modifier == L_('E'))
   1015 	    goto bad_format;
   1016 
   1017 	  number_value = ns;
   1018 	  if (width != -1)
   1019 	    {
   1020 	      /* Take an explicit width less than 9 as a precision.  */
   1021 	      int j;
   1022 	      for (j = width; j < 9; j++)
   1023 		number_value /= 10;
   1024 	    }
   1025 
   1026 	  DO_NUMBER (9, number_value);
   1027 #endif
   1028 
   1029 	case L_('n'):
   1030 	  add (1, *p = L_('\n'));
   1031 	  break;
   1032 
   1033 	case L_('P'):
   1034 	  to_lowcase = true;
   1035 #if !defined _NL_CURRENT && HAVE_STRFTIME
   1036 	  format_char = L_('p');
   1037 #endif
   1038 	  /* FALLTHROUGH */
   1039 
   1040 	case L_('p'):
   1041 	  if (change_case)
   1042 	    {
   1043 	      to_uppcase = false;
   1044 	      to_lowcase = true;
   1045 	    }
   1046 #if defined _NL_CURRENT || !HAVE_STRFTIME
   1047 	  cpy (ap_len, ampm);
   1048 	  break;
   1049 #else
   1050 	  goto underlying_strftime;
   1051 #endif
   1052 
   1053 	case L_('R'):
   1054 	  subfmt = L_("%H:%M");
   1055 	  goto subformat;
   1056 
   1057 	case L_('r'):
   1058 #if !defined _NL_CURRENT && HAVE_STRFTIME
   1059 	  goto underlying_strftime;
   1060 #else
   1061 # ifdef _NL_CURRENT
   1062 	  if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME,
   1063 						       NLW(T_FMT_AMPM)))
   1064 	      == L_('\0'))
   1065 # endif
   1066 	    subfmt = L_("%I:%M:%S %p");
   1067 	  goto subformat;
   1068 #endif
   1069 
   1070 	case L_('S'):
   1071 	  if (modifier == L_('E'))
   1072 	    goto bad_format;
   1073 
   1074 	  DO_NUMBER (2, tp->tm_sec);
   1075 
   1076 	case L_('s'):		/* GNU extension.  */
   1077 	  {
   1078 	    struct tm ltm;
   1079 	    time_t t;
   1080 
   1081 	    ltm = *tp;
   1082 	    t = mktime (&ltm);
   1083 
   1084 	    /* Generate string value for T using time_t arithmetic;
   1085 	       this works even if sizeof (long) < sizeof (time_t).  */
   1086 
   1087 	    bufp = buf + sizeof (buf) / sizeof (buf[0]);
   1088 	    negative_number = t < 0;
   1089 
   1090 	    do
   1091 	      {
   1092 		int d = t % 10;
   1093 		t /= 10;
   1094 		*--bufp = (negative_number ? -d : d) + L_('0');
   1095 	      }
   1096 	    while (t != 0);
   1097 
   1098 	    digits = 1;
   1099 	    goto do_number_sign_and_padding;
   1100 	  }
   1101 
   1102 	case L_('X'):
   1103 	  if (modifier == L_('O'))
   1104 	    goto bad_format;
   1105 #ifdef _NL_CURRENT
   1106 	  if (! (modifier == L_('E')
   1107 		 && (*(subfmt =
   1108 		       (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT)))
   1109 		     != L_('\0'))))
   1110 	    subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
   1111 	  goto subformat;
   1112 #else
   1113 # if HAVE_STRFTIME
   1114 	  goto underlying_strftime;
   1115 # else
   1116 	  /* Fall through.  */
   1117 # endif
   1118 #endif
   1119 	case L_('T'):
   1120 	  subfmt = L_("%H:%M:%S");
   1121 	  goto subformat;
   1122 
   1123 	case L_('t'):
   1124 	  add (1, *p = L_('\t'));
   1125 	  break;
   1126 
   1127 	case L_('u'):
   1128 	  DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
   1129 
   1130 	case L_('U'):
   1131 	  if (modifier == L_('E'))
   1132 	    goto bad_format;
   1133 
   1134 	  DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
   1135 
   1136 	case L_('V'):
   1137 	case L_('g'):
   1138 	case L_('G'):
   1139 	  if (modifier == L_('E'))
   1140 	    goto bad_format;
   1141 	  {
   1142 	    /* YEAR is a leap year if and only if (tp->tm_year + TM_YEAR_BASE)
   1143 	       is a leap year, except that YEAR and YEAR - 1 both work
   1144 	       correctly even when (tp->tm_year + TM_YEAR_BASE) would
   1145 	       overflow.  */
   1146 	    int year = (tp->tm_year
   1147 			+ (tp->tm_year < 0
   1148 			   ? TM_YEAR_BASE % 400
   1149 			   : TM_YEAR_BASE % 400 - 400));
   1150 	    int year_adjust = 0;
   1151 	    int days = iso_week_days (tp->tm_yday, tp->tm_wday);
   1152 
   1153 	    if (days < 0)
   1154 	      {
   1155 		/* This ISO week belongs to the previous year.  */
   1156 		year_adjust = -1;
   1157 		days = iso_week_days (tp->tm_yday + (365 + __isleap (year - 1)),
   1158 				      tp->tm_wday);
   1159 	      }
   1160 	    else
   1161 	      {
   1162 		int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
   1163 				       tp->tm_wday);
   1164 		if (0 <= d)
   1165 		  {
   1166 		    /* This ISO week belongs to the next year.  */
   1167 		    year_adjust = 1;
   1168 		    days = d;
   1169 		  }
   1170 	      }
   1171 
   1172 	    switch (*f)
   1173 	      {
   1174 	      case L_('g'):
   1175 		{
   1176 		  int yy = (tp->tm_year % 100 + year_adjust) % 100;
   1177 		  DO_NUMBER (2, (0 <= yy
   1178 				 ? yy
   1179 				 : tp->tm_year < -TM_YEAR_BASE - year_adjust
   1180 				 ? -yy
   1181 				 : yy + 100));
   1182 		}
   1183 
   1184 	      case L_('G'):
   1185 		DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE - year_adjust,
   1186 				  (tp->tm_year + (unsigned int) TM_YEAR_BASE
   1187 				   + year_adjust));
   1188 
   1189 	      default:
   1190 		DO_NUMBER (2, days / 7 + 1);
   1191 	      }
   1192 	  }
   1193 
   1194 	case L_('W'):
   1195 	  if (modifier == L_('E'))
   1196 	    goto bad_format;
   1197 
   1198 	  DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
   1199 
   1200 	case L_('w'):
   1201 	  if (modifier == L_('E'))
   1202 	    goto bad_format;
   1203 
   1204 	  DO_NUMBER (1, tp->tm_wday);
   1205 
   1206 	case L_('Y'):
   1207 	  if (modifier == 'E')
   1208 	    {
   1209 #if HAVE_STRUCT_ERA_ENTRY
   1210 	      struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
   1211 	      if (era)
   1212 		{
   1213 # ifdef COMPILE_WIDE
   1214 		  subfmt = era->era_wformat;
   1215 # else
   1216 		  subfmt = era->era_format;
   1217 # endif
   1218 		  goto subformat;
   1219 		}
   1220 #else
   1221 # if HAVE_STRFTIME
   1222 	      goto underlying_strftime;
   1223 # endif
   1224 #endif
   1225 	    }
   1226 	  if (modifier == L_('O'))
   1227 	    goto bad_format;
   1228 	  else
   1229 	    DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE,
   1230 			      tp->tm_year + (unsigned int) TM_YEAR_BASE);
   1231 
   1232 	case L_('y'):
   1233 	  if (modifier == L_('E'))
   1234 	    {
   1235 #if HAVE_STRUCT_ERA_ENTRY
   1236 	      struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
   1237 	      if (era)
   1238 		{
   1239 		  int delta = tp->tm_year - era->start_date[0];
   1240 		  DO_NUMBER (1, (era->offset
   1241 				 + delta * era->absolute_direction));
   1242 		}
   1243 #else
   1244 # if HAVE_STRFTIME
   1245 	      goto underlying_strftime;
   1246 # endif
   1247 #endif
   1248 	    }
   1249 
   1250 	  {
   1251 	    int yy = tp->tm_year % 100;
   1252 	    if (yy < 0)
   1253 	      yy = tp->tm_year < - TM_YEAR_BASE ? -yy : yy + 100;
   1254 	    DO_NUMBER (2, yy);
   1255 	  }
   1256 
   1257 	case L_('Z'):
   1258 	  if (change_case)
   1259 	    {
   1260 	      to_uppcase = false;
   1261 	      to_lowcase = true;
   1262 	    }
   1263 
   1264 #if HAVE_TZNAME
   1265 	  /* The tzset() call might have changed the value.  */
   1266 	  if (!(zone && *zone) && tp->tm_isdst >= 0)
   1267 	    zone = tzname[tp->tm_isdst != 0];
   1268 #endif
   1269 	  if (! zone)
   1270 	    zone = "";
   1271 
   1272 #ifdef COMPILE_WIDE
   1273 	  {
   1274 	    /* The zone string is always given in multibyte form.  We have
   1275 	       to transform it first.  */
   1276 	    wchar_t *wczone;
   1277 	    size_t len;
   1278 	    widen (zone, wczone, len);
   1279 	    cpy (len, wczone);
   1280 	  }
   1281 #else
   1282 	  cpy (strlen (zone), zone);
   1283 #endif
   1284 	  break;
   1285 
   1286 	case L_('z'):
   1287 	  if (tp->tm_isdst < 0)
   1288 	    break;
   1289 
   1290 	  {
   1291 	    int diff;
   1292 #if HAVE_TM_GMTOFF
   1293 	    diff = tp->tm_gmtoff;
   1294 #else
   1295 	    if (ut)
   1296 	      diff = 0;
   1297 	    else
   1298 	      {
   1299 		struct tm gtm;
   1300 		struct tm ltm;
   1301 		time_t lt;
   1302 
   1303 		ltm = *tp;
   1304 		lt = mktime (&ltm);
   1305 
   1306 		if (lt == (time_t) -1)
   1307 		  {
   1308 		    /* mktime returns -1 for errors, but -1 is also a
   1309 		       valid time_t value.  Check whether an error really
   1310 		       occurred.  */
   1311 		    struct tm tm;
   1312 
   1313 		    if (! __localtime_r (&lt, &tm)
   1314 			|| ((ltm.tm_sec ^ tm.tm_sec)
   1315 			    | (ltm.tm_min ^ tm.tm_min)
   1316 			    | (ltm.tm_hour ^ tm.tm_hour)
   1317 			    | (ltm.tm_mday ^ tm.tm_mday)
   1318 			    | (ltm.tm_mon ^ tm.tm_mon)
   1319 			    | (ltm.tm_year ^ tm.tm_year)))
   1320 		      break;
   1321 		  }
   1322 
   1323 		if (! __gmtime_r (&lt, &gtm))
   1324 		  break;
   1325 
   1326 		diff = tm_diff (&ltm, &gtm);
   1327 	      }
   1328 #endif
   1329 
   1330 	    if (diff < 0)
   1331 	      {
   1332 		add (1, *p = L_('-'));
   1333 		diff = -diff;
   1334 	      }
   1335 	    else
   1336 	      add (1, *p = L_('+'));
   1337 
   1338 	    diff /= 60;
   1339 	    DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
   1340 	  }
   1341 
   1342 	case L_('\0'):		/* GNU extension: % at end of format.  */
   1343 	    --f;
   1344 	    /* Fall through.  */
   1345 	default:
   1346 	  /* Unknown format; output the format, including the '%',
   1347 	     since this is most likely the right thing to do if a
   1348 	     multibyte string has been misparsed.  */
   1349 	bad_format:
   1350 	  {
   1351 	    int flen;
   1352 	    for (flen = 1; f[1 - flen] != L_('%'); flen++)
   1353 	      continue;
   1354 	    cpy (flen, &f[1 - flen]);
   1355 	  }
   1356 	  break;
   1357 	}
   1358     }
   1359 
   1360   if (p && maxsize != 0)
   1361     *p = L_('\0');
   1362   return i;
   1363 }
   1364 #ifdef _LIBC
   1365 libc_hidden_def (my_strftime)
   1366 #endif
   1367 
   1368 
   1369 #ifdef emacs
   1370 /* For Emacs we have a separate interface which corresponds to the normal
   1371    strftime function plus the ut argument, but without the ns argument.  */
   1372 size_t
   1373 emacs_strftimeu (char *s, size_t maxsize, const char *format,
   1374 		 const struct tm *tp, int ut)
   1375 {
   1376   return my_strftime (s, maxsize, format, tp, ut, 0);
   1377 }
   1378 #endif
   1379