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