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