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