.
[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, (const 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 _strftime_copytm
461 #endif
462
463
464 /* Write information from TP into S according to the format
465    string FORMAT, writing no more that MAXSIZE characters
466    (including the terminating '\0') and returning number of
467    characters written.  If S is NULL, nothing will be written
468    anywhere, so to determine how many characters would be
469    written, use NULL for S and (size_t) UINT_MAX for MAXSIZE.  */
470 size_t
471 my_strftime (s, maxsize, format, tp ut_argument)
472       CHAR_T *s;
473       size_t maxsize;
474       const CHAR_T *format;
475       const struct tm *tp;
476       ut_argument_spec
477 {
478   int hour12 = tp->tm_hour;
479 #ifdef _NL_CURRENT
480   /* We cannot make the following values variables since we must delay
481      the evaluation of these values until really needed since some
482      expressions might not be valid in every situation.  The `struct tm'
483      might be generated by a strptime() call that initialized
484      only a few elements.  Dereference the pointers only if the format
485      requires this.  Then it is ok to fail if the pointers are invalid.  */
486 # define a_wkday \
487   ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
488 # define f_wkday \
489   ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
490 # define a_month \
491   ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
492 # define f_month \
493   ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
494 # define ampm \
495   ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11                    \
496                                  ? NLW(PM_STR) : NLW(AM_STR)))
497
498 # define aw_len STRLEN (a_wkday)
499 # define am_len STRLEN (a_month)
500 # define ap_len STRLEN (ampm)
501 #else
502 # if !HAVE_STRFTIME
503 #  define f_wkday (weekday_name[tp->tm_wday])
504 #  define f_month (month_name[tp->tm_mon])
505 #  define a_wkday f_wkday
506 #  define a_month f_month
507 #  define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
508
509   size_t aw_len = 3;
510   size_t am_len = 3;
511   size_t ap_len = 2;
512 # endif
513 #endif
514   const char *zone;
515   size_t i = 0;
516   CHAR_T *p = s;
517   const CHAR_T *f;
518 #if DO_MULTIBYTE && !defined COMPILE_WIDE
519   const char *format_end = NULL;
520 #endif
521
522   zone = NULL;
523 #if HAVE_TM_ZONE
524   /* The POSIX test suite assumes that setting
525      the environment variable TZ to a new value before calling strftime()
526      will influence the result (the %Z format) even if the information in
527      TP is computed with a totally different time zone.
528      This is bogus: though POSIX allows bad behavior like this,
529      POSIX does not require it.  Do the right thing instead.  */
530   zone = (const char *) tp->tm_zone;
531 #endif
532 #if HAVE_TZNAME
533   if (ut)
534     {
535       if (! (zone && *zone))
536         zone = "GMT";
537     }
538   else
539     {
540       /* POSIX.1 8.1.1 requires that whenever strftime() is called, the
541          time zone names contained in the external variable `tzname' shall
542          be set as if the tzset() function had been called.  */
543 # if HAVE_TZSET
544       tzset ();
545 # endif
546     }
547 #endif
548
549   if (hour12 > 12)
550     hour12 -= 12;
551   else
552     if (hour12 == 0)
553       hour12 = 12;
554
555   for (f = format; *f != '\0'; ++f)
556     {
557       int pad = 0;              /* Padding for number ('-', '_', or 0).  */
558       int modifier;             /* Field modifier ('E', 'O', or 0).  */
559       int digits;               /* Max digits for numeric format.  */
560       int number_value;         /* Numeric value to be printed.  */
561       int negative_number;      /* 1 if the number is negative.  */
562       const CHAR_T *subfmt;
563       CHAR_T *bufp;
564       CHAR_T buf[1 + (sizeof (int) < sizeof (time_t)
565                       ? INT_STRLEN_BOUND (time_t)
566                       : INT_STRLEN_BOUND (int))];
567       int width = -1;
568       int to_lowcase = 0;
569       int to_uppcase = 0;
570       int change_case = 0;
571       int format_char;
572
573 #if DO_MULTIBYTE && !defined COMPILE_WIDE
574       switch (*f)
575         {
576         case L_('%'):
577           break;
578
579         case L_('\b'): case L_('\t'): case L_('\n'):
580         case L_('\v'): case L_('\f'): case L_('\r'):
581         case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
582         case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
583         case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
584         case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
585         case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
586         case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
587         case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
588         case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
589         case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
590         case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
591         case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
592         case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
593         case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
594         case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
595         case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
596         case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
597         case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
598         case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
599         case L_('~'):
600           /* The C Standard requires these 98 characters (plus '%') to
601              be in the basic execution character set.  None of these
602              characters can start a multibyte sequence, so they need
603              not be analyzed further.  */
604           add (1, *p = *f);
605           continue;
606
607         default:
608           /* Copy this multibyte sequence until we reach its end, find
609              an error, or come back to the initial shift state.  */
610           {
611             mbstate_t mbstate = mbstate_zero;
612             size_t len = 0;
613             size_t fsize;
614
615             if (! format_end)
616               format_end = f + strlen (f) + 1;
617             fsize = format_end - f;
618
619             do
620               {
621                 size_t bytes = mbrlen (f + len, fsize - len, &mbstate);
622
623                 if (bytes == 0)
624                   break;
625
626                 if (bytes == (size_t) -2)
627                   {
628                     len += strlen (f + len);
629                     break;
630                   }
631
632                 if (bytes == (size_t) -1)
633                   {
634                     len++;
635                     break;
636                   }
637
638                 len += bytes;
639               }
640             while (! mbsinit (&mbstate));
641
642             cpy (len, f);
643             f += len - 1;
644             continue;
645           }
646         }
647
648 #else /* ! DO_MULTIBYTE */
649
650       /* Either multibyte encodings are not supported, they are
651          safe for formats, so any non-'%' byte can be copied through,
652          or this is the wide character version.  */
653       if (*f != L_('%'))
654         {
655           add (1, *p = *f);
656           continue;
657         }
658
659 #endif /* ! DO_MULTIBYTE */
660
661       /* Check for flags that can modify a format.  */
662       while (1)
663         {
664           switch (*++f)
665             {
666               /* This influences the number formats.  */
667             case L_('_'):
668             case L_('-'):
669             case L_('0'):
670               pad = *f;
671               continue;
672
673               /* This changes textual output.  */
674             case L_('^'):
675               to_uppcase = 1;
676               continue;
677             case L_('#'):
678               change_case = 1;
679               continue;
680
681             default:
682               break;
683             }
684           break;
685         }
686
687       /* As a GNU extension we allow to specify the field width.  */
688       if (ISDIGIT (*f))
689         {
690           width = 0;
691           do
692             {
693               width *= 10;
694               width += *f - L_('0');
695               ++f;
696             }
697           while (ISDIGIT (*f));
698         }
699
700       /* Check for modifiers.  */
701       switch (*f)
702         {
703         case L_('E'):
704         case L_('O'):
705           modifier = *f++;
706           break;
707
708         default:
709           modifier = 0;
710           break;
711         }
712
713       /* Now do the specified format.  */
714       format_char = *f;
715       switch (format_char)
716         {
717 #define DO_NUMBER(d, v) \
718           digits = width == -1 ? d : width;                                   \
719           number_value = v; goto do_number
720 #define DO_NUMBER_SPACEPAD(d, v) \
721           digits = width == -1 ? d : width;                                   \
722           number_value = v; goto do_number_spacepad
723
724         case L_('%'):
725           if (modifier != 0)
726             goto bad_format;
727           add (1, *p = *f);
728           break;
729
730         case L_('a'):
731           if (modifier != 0)
732             goto bad_format;
733           if (change_case)
734             {
735               to_uppcase = 1;
736               to_lowcase = 0;
737             }
738 #if defined _NL_CURRENT || !HAVE_STRFTIME
739           cpy (aw_len, a_wkday);
740           break;
741 #else
742           goto underlying_strftime;
743 #endif
744
745         case 'A':
746           if (modifier != 0)
747             goto bad_format;
748           if (change_case)
749             {
750               to_uppcase = 1;
751               to_lowcase = 0;
752             }
753 #if defined _NL_CURRENT || !HAVE_STRFTIME
754           cpy (STRLEN (f_wkday), f_wkday);
755           break;
756 #else
757           goto underlying_strftime;
758 #endif
759
760         case L_('b'):
761         case L_('h'):           /* POSIX.2 extension.  */
762           if (change_case)
763             {
764               to_uppcase = 1;
765               to_lowcase = 0;
766             }
767           if (modifier != 0)
768             goto bad_format;
769 #if defined _NL_CURRENT || !HAVE_STRFTIME
770           cpy (am_len, a_month);
771           break;
772 #else
773           goto underlying_strftime;
774 #endif
775
776         case L_('B'):
777           if (modifier != 0)
778             goto bad_format;
779           if (change_case)
780             {
781               to_uppcase = 1;
782               to_lowcase = 0;
783             }
784 #if defined _NL_CURRENT || !HAVE_STRFTIME
785           cpy (STRLEN (f_month), f_month);
786           break;
787 #else
788           goto underlying_strftime;
789 #endif
790
791         case L_('c'):
792           if (modifier == L_('O'))
793             goto bad_format;
794 #ifdef _NL_CURRENT
795           if (! (modifier == 'E'
796                  && (*(subfmt =
797                        (const CHAR_T *) _NL_CURRENT (LC_TIME,
798                                                      NLW(ERA_D_T_FMT)))
799                      != '\0')))
800             subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
801 #else
802 # if HAVE_STRFTIME
803           goto underlying_strftime;
804 # else
805           subfmt = L_("%a %b %e %H:%M:%S %Y");
806 # endif
807 #endif
808
809         subformat:
810           {
811             CHAR_T *old_start = p;
812             size_t len = my_strftime (NULL, (size_t) -1, subfmt,
813                                       tp ut_argument);
814             add (len, my_strftime (p, maxsize - i, subfmt,
815                                    tp ut_argument));
816
817             if (to_uppcase)
818               while (old_start < p)
819                 {
820                   *old_start = TOUPPER ((UCHAR_T) *old_start);
821                   ++old_start;
822                 }
823           }
824           break;
825
826 #if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
827         underlying_strftime:
828           {
829             /* The relevant information is available only via the
830                underlying strftime implementation, so use that.  */
831             char ufmt[4];
832             char *u = ufmt;
833             char ubuf[1024]; /* enough for any single format in practice */
834             size_t len;
835             /* Make sure we're calling the actual underlying strftime.
836                In some cases, config.h contains something like
837                "#define strftime rpl_strftime".  */
838 # ifdef strftime
839 #  undef strftime
840             size_t strftime ();
841 # endif
842
843             *u++ = '%';
844             if (modifier != 0)
845               *u++ = modifier;
846             *u++ = format_char;
847             *u = '\0';
848             len = strftime (ubuf, sizeof ubuf, ufmt, tp);
849             if (len == 0 && ubuf[0] != '\0')
850               return 0;
851             cpy (len, ubuf);
852           }
853           break;
854 #endif
855
856         case L_('C'):           /* POSIX.2 extension.  */
857           if (modifier == L_('O'))
858             goto bad_format;
859           if (modifier == L_('E'))
860             {
861 #if HAVE_STRUCT_ERA_ENTRY
862               struct era_entry *era = _nl_get_era_entry (tp);
863               if (era)
864                 {
865 # ifdef COMPILE_WIDE
866                   size_t len = __wcslen (era->era_wname);
867                   cpy (len, era->era_wname);
868 # else
869                   size_t len = strlen (era->era_name);
870                   cpy (len, era->era_name);
871 # endif
872                   break;
873                 }
874 #else
875 # if HAVE_STRFTIME
876               goto underlying_strftime;
877 # endif
878 #endif
879             }
880
881           {
882             int year = tp->tm_year + TM_YEAR_BASE;
883             DO_NUMBER (1, year / 100 - (year % 100 < 0));
884           }
885
886         case L_('x'):
887           if (modifier == L_('O'))
888             goto bad_format;
889 #ifdef _NL_CURRENT
890           if (! (modifier == L_('E')
891                  && (*(subfmt =
892                        (const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT)))
893                      != L_('\0'))))
894             subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
895           goto subformat;
896 #else
897 # if HAVE_STRFTIME
898           goto underlying_strftime;
899 # else
900           /* Fall through.  */
901 # endif
902 #endif
903         case L_('D'):           /* POSIX.2 extension.  */
904           if (modifier != 0)
905             goto bad_format;
906           subfmt = L_("%m/%d/%y");
907           goto subformat;
908
909         case L_('d'):
910           if (modifier == L_('E'))
911             goto bad_format;
912
913           DO_NUMBER (2, tp->tm_mday);
914
915         case L_('e'):           /* POSIX.2 extension.  */
916           if (modifier == L_('E'))
917             goto bad_format;
918
919           DO_NUMBER_SPACEPAD (2, tp->tm_mday);
920
921           /* All numeric formats set DIGITS and NUMBER_VALUE and then
922              jump to one of these two labels.  */
923
924         do_number_spacepad:
925           /* Force `_' flag unless overwritten by `0' flag.  */
926           if (pad != L_('0'))
927             pad = L_('_');
928
929         do_number:
930           /* Format the number according to the MODIFIER flag.  */
931
932           if (modifier == L_('O') && 0 <= number_value)
933             {
934 #ifdef _NL_CURRENT
935               /* Get the locale specific alternate representation of
936                  the number NUMBER_VALUE.  If none exist NULL is returned.  */
937 # ifdef COMPILE_WIDE
938               const wchar_t *cp = _nl_get_walt_digit (number_value);
939 # else
940               const char *cp = _nl_get_alt_digit (number_value);
941 # endif
942
943               if (cp != NULL)
944                 {
945                   size_t digitlen = STRLEN (cp);
946                   if (digitlen != 0)
947                     {
948                       cpy (digitlen, cp);
949                       break;
950                     }
951                 }
952 #else
953 # if HAVE_STRFTIME
954               goto underlying_strftime;
955 # endif
956 #endif
957             }
958           {
959             unsigned int u = number_value;
960
961             bufp = buf + sizeof (buf) / sizeof (buf[0]);
962             negative_number = number_value < 0;
963
964             if (negative_number)
965               u = -u;
966
967             do
968               *--bufp = u % 10 + L_('0');
969             while ((u /= 10) != 0);
970           }
971
972         do_number_sign_and_padding:
973           if (negative_number)
974             *--bufp = L_('-');
975
976           if (pad != L_('-'))
977             {
978               int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
979                                       - bufp);
980
981               if (pad == L_('_'))
982                 {
983                   while (0 < padding--)
984                     *--bufp = L_(' ');
985                 }
986               else
987                 {
988                   bufp += negative_number;
989                   while (0 < padding--)
990                     *--bufp = L_('0');
991                   if (negative_number)
992                     *--bufp = L_('-');
993                 }
994             }
995
996           cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
997           break;
998
999         case L_('F'):
1000           if (modifier != 0)
1001             goto bad_format;
1002           subfmt = L_("%Y-%m-%d");
1003           goto subformat;
1004
1005         case L_('H'):
1006           if (modifier == L_('E'))
1007             goto bad_format;
1008
1009           DO_NUMBER (2, tp->tm_hour);
1010
1011         case L_('I'):
1012           if (modifier == L_('E'))
1013             goto bad_format;
1014
1015           DO_NUMBER (2, hour12);
1016
1017         case L_('k'):           /* GNU extension.  */
1018           if (modifier == L_('E'))
1019             goto bad_format;
1020
1021           DO_NUMBER_SPACEPAD (2, tp->tm_hour);
1022
1023         case L_('l'):           /* GNU extension.  */
1024           if (modifier == L_('E'))
1025             goto bad_format;
1026
1027           DO_NUMBER_SPACEPAD (2, hour12);
1028
1029         case L_('j'):
1030           if (modifier == L_('E'))
1031             goto bad_format;
1032
1033           DO_NUMBER (3, 1 + tp->tm_yday);
1034
1035         case L_('M'):
1036           if (modifier == L_('E'))
1037             goto bad_format;
1038
1039           DO_NUMBER (2, tp->tm_min);
1040
1041         case L_('m'):
1042           if (modifier == L_('E'))
1043             goto bad_format;
1044
1045           DO_NUMBER (2, tp->tm_mon + 1);
1046
1047         case L_('n'):           /* POSIX.2 extension.  */
1048           add (1, *p = L_('\n'));
1049           break;
1050
1051         case L_('P'):
1052           to_lowcase = 1;
1053 #if !defined _NL_CURRENT && HAVE_STRFTIME
1054           format_char = L_('p');
1055 #endif
1056           /* FALLTHROUGH */
1057
1058         case L_('p'):
1059           if (change_case)
1060             {
1061               to_uppcase = 0;
1062               to_lowcase = 1;
1063             }
1064 #if defined _NL_CURRENT || !HAVE_STRFTIME
1065           cpy (ap_len, ampm);
1066           break;
1067 #else
1068           goto underlying_strftime;
1069 #endif
1070
1071         case L_('R'):           /* GNU extension.  */
1072           subfmt = L_("%H:%M");
1073           goto subformat;
1074
1075         case L_('r'):           /* POSIX.2 extension.  */
1076 #ifdef _NL_CURRENT
1077           if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME,
1078                                                        NLW(T_FMT_AMPM)))
1079               == L_('\0'))
1080 #endif
1081             subfmt = L_("%I:%M:%S %p");
1082           goto subformat;
1083
1084         case L_('S'):
1085           if (modifier == L_('E'))
1086             goto bad_format;
1087
1088           DO_NUMBER (2, tp->tm_sec);
1089
1090         case L_('s'):           /* GNU extension.  */
1091           {
1092             struct tm ltm;
1093             time_t t;
1094
1095             ltm = *tp;
1096             t = mktime (&ltm);
1097
1098             /* Generate string value for T using time_t arithmetic;
1099                this works even if sizeof (long) < sizeof (time_t).  */
1100
1101             bufp = buf + sizeof (buf) / sizeof (buf[0]);
1102             negative_number = t < 0;
1103
1104             do
1105               {
1106                 int d = t % 10;
1107                 t /= 10;
1108
1109                 if (negative_number)
1110                   {
1111                     d = -d;
1112
1113                     /* Adjust if division truncates to minus infinity.  */
1114                     if (0 < -1 % 10 && d < 0)
1115                       {
1116                         t++;
1117                         d += 10;
1118                       }
1119                   }
1120
1121                 *--bufp = d + L_('0');
1122               }
1123             while (t != 0);
1124
1125             digits = 1;
1126             goto do_number_sign_and_padding;
1127           }
1128
1129         case L_('X'):
1130           if (modifier == L_('O'))
1131             goto bad_format;
1132 #ifdef _NL_CURRENT
1133           if (! (modifier == L_('E')
1134                  && (*(subfmt =
1135                        (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT)))
1136                      != L_('\0'))))
1137             subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
1138           goto subformat;
1139 #else
1140 # if HAVE_STRFTIME
1141           goto underlying_strftime;
1142 # else
1143           /* Fall through.  */
1144 # endif
1145 #endif
1146         case L_('T'):           /* POSIX.2 extension.  */
1147           subfmt = L_("%H:%M:%S");
1148           goto subformat;
1149
1150         case L_('t'):           /* POSIX.2 extension.  */
1151           add (1, *p = L_('\t'));
1152           break;
1153
1154         case L_('u'):           /* POSIX.2 extension.  */
1155           DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
1156
1157         case L_('U'):
1158           if (modifier == L_('E'))
1159             goto bad_format;
1160
1161           DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
1162
1163         case L_('V'):
1164         case L_('g'):           /* GNU extension.  */
1165         case L_('G'):           /* GNU extension.  */
1166           if (modifier == L_('E'))
1167             goto bad_format;
1168           {
1169             int year = tp->tm_year + TM_YEAR_BASE;
1170             int days = iso_week_days (tp->tm_yday, tp->tm_wday);
1171
1172             if (days < 0)
1173               {
1174                 /* This ISO week belongs to the previous year.  */
1175                 year--;
1176                 days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
1177                                       tp->tm_wday);
1178               }
1179             else
1180               {
1181                 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
1182                                        tp->tm_wday);
1183                 if (0 <= d)
1184                   {
1185                     /* This ISO week belongs to the next year.  */
1186                     year++;
1187                     days = d;
1188                   }
1189               }
1190
1191             switch (*f)
1192               {
1193               case L_('g'):
1194                 DO_NUMBER (2, (year % 100 + 100) % 100);
1195
1196               case L_('G'):
1197                 DO_NUMBER (1, year);
1198
1199               default:
1200                 DO_NUMBER (2, days / 7 + 1);
1201               }
1202           }
1203
1204         case L_('W'):
1205           if (modifier == L_('E'))
1206             goto bad_format;
1207
1208           DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
1209
1210         case L_('w'):
1211           if (modifier == L_('E'))
1212             goto bad_format;
1213
1214           DO_NUMBER (1, tp->tm_wday);
1215
1216         case L_('Y'):
1217           if (modifier == 'E')
1218             {
1219 #if HAVE_STRUCT_ERA_ENTRY
1220               struct era_entry *era = _nl_get_era_entry (tp);
1221               if (era)
1222                 {
1223 # ifdef COMPILE_WIDE
1224                   subfmt = era->era_wformat;
1225 # else
1226                   subfmt = era->era_format;
1227 # endif
1228                   goto subformat;
1229                 }
1230 #else
1231 # if HAVE_STRFTIME
1232               goto underlying_strftime;
1233 # endif
1234 #endif
1235             }
1236           if (modifier == L_('O'))
1237             goto bad_format;
1238           else
1239             DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
1240
1241         case L_('y'):
1242           if (modifier == L_('E'))
1243             {
1244 #if HAVE_STRUCT_ERA_ENTRY
1245               struct era_entry *era = _nl_get_era_entry (tp);
1246               if (era)
1247                 {
1248                   int delta = tp->tm_year - era->start_date[0];
1249                   DO_NUMBER (1, (era->offset
1250                                  + delta * era->absolute_direction));
1251                 }
1252 #else
1253 # if HAVE_STRFTIME
1254               goto underlying_strftime;
1255 # endif
1256 #endif
1257             }
1258           DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
1259
1260         case L_('Z'):
1261           if (change_case)
1262             {
1263               to_uppcase = 0;
1264               to_lowcase = 1;
1265             }
1266
1267 #if HAVE_TZNAME
1268           /* The tzset() call might have changed the value.  */
1269           if (!(zone && *zone) && tp->tm_isdst >= 0)
1270             zone = tzname[tp->tm_isdst];
1271 #endif
1272           if (! zone)
1273             zone = "";          /* POSIX.2 requires the empty string here.  */
1274
1275 #ifdef COMPILE_WIDE
1276           {
1277             /* The zone string is always given in multibyte form.  We have
1278                to transform it first.  */
1279             wchar_t *wczone;
1280             size_t len;
1281             widen (zone, wczone, len);
1282             cpy (len, wczone);
1283           }
1284 #else
1285           cpy (strlen (zone), zone);
1286 #endif
1287           break;
1288
1289         case L_('z'):           /* GNU extension.  */
1290           if (tp->tm_isdst < 0)
1291             break;
1292
1293           {
1294             int diff;
1295 #if HAVE_TM_GMTOFF
1296             diff = tp->tm_gmtoff;
1297 #else
1298             if (ut)
1299               diff = 0;
1300             else
1301               {
1302                 struct tm gtm;
1303                 struct tm ltm;
1304                 time_t lt;
1305
1306                 ltm = *tp;
1307                 lt = mktime (&ltm);
1308
1309                 if (lt == (time_t) -1)
1310                   {
1311                     /* mktime returns -1 for errors, but -1 is also a
1312                        valid time_t value.  Check whether an error really
1313                        occurred.  */
1314                     struct tm tm;
1315
1316                     if (! my_strftime_localtime_r (&lt, &tm)
1317                         || ((ltm.tm_sec ^ tm.tm_sec)
1318                             | (ltm.tm_min ^ tm.tm_min)
1319                             | (ltm.tm_hour ^ tm.tm_hour)
1320                             | (ltm.tm_mday ^ tm.tm_mday)
1321                             | (ltm.tm_mon ^ tm.tm_mon)
1322                             | (ltm.tm_year ^ tm.tm_year)))
1323                       break;
1324                   }
1325
1326                 if (! my_strftime_gmtime_r (&lt, &gtm))
1327                   break;
1328
1329                 diff = tm_diff (&ltm, &gtm);
1330               }
1331 #endif
1332
1333             if (diff < 0)
1334               {
1335                 add (1, *p = L_('-'));
1336                 diff = -diff;
1337               }
1338             else
1339               add (1, *p = L_('+'));
1340
1341             diff /= 60;
1342             DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
1343           }
1344
1345         case L_('\0'):          /* GNU extension: % at end of format.  */
1346             --f;
1347             /* Fall through.  */
1348         default:
1349           /* Unknown format; output the format, including the '%',
1350              since this is most likely the right thing to do if a
1351              multibyte string has been misparsed.  */
1352         bad_format:
1353           {
1354             int flen;
1355             for (flen = 1; f[1 - flen] != L_('%'); flen++)
1356               continue;
1357             cpy (flen, &f[1 - flen]);
1358           }
1359           break;
1360         }
1361     }
1362
1363   if (p && maxsize != 0)
1364     *p = L_('\0');
1365   return i;
1366 }
1367
1368
1369 #ifdef emacs
1370 /* For Emacs we have a separate interface which corresponds to the normal
1371    strftime function and does not have the extra information whether the
1372    TP arguments comes from a `gmtime' call or not.  */
1373 size_t
1374 emacs_strftime (s, maxsize, format, tp)
1375       char *s;
1376       size_t maxsize;
1377       const char *format;
1378       const struct tm *tp;
1379 {
1380   return my_strftime (s, maxsize, format, tp, 0);
1381 }
1382 #endif