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