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