Update.
[platform/upstream/glibc.git] / time / strftime.c
1 /* Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public License as
6    published by the Free Software Foundation; either version 2 of the
7    License, or (at your option) any later version.
8
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13
14    You should have received a copy of the GNU Library General Public
15    License along with the GNU C Library; see the file COPYING.LIB.  If not,
16    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17    Boston, MA 02111-1307, USA.  */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #ifdef _LIBC
24 # define HAVE_LIMITS_H 1
25 # define HAVE_MBLEN 1
26 # define HAVE_MBRLEN 1
27 # define HAVE_STRUCT_ERA_ENTRY 1
28 # define HAVE_TM_GMTOFF 1
29 # define HAVE_TM_ZONE 1
30 # define HAVE_TZNAME 1
31 # define HAVE_TZSET 1
32 # define MULTIBYTE_IS_FORMAT_SAFE 1
33 # define STDC_HEADERS 1
34 # include "../locale/localeinfo.h"
35 #endif
36
37 #if defined emacs && !defined HAVE_BCOPY
38 # define HAVE_MEMCPY 1
39 #endif
40
41 #include <ctype.h>
42 #include <sys/types.h>          /* Some systems define `time_t' here.  */
43
44 #ifdef TIME_WITH_SYS_TIME
45 # include <sys/time.h>
46 # include <time.h>
47 #else
48 # ifdef HAVE_SYS_TIME_H
49 #  include <sys/time.h>
50 # else
51 #  include <time.h>
52 # endif
53 #endif
54 #if HAVE_TZNAME
55 extern char *tzname[];
56 #endif
57
58 /* Do multibyte processing if multibytes are supported, unless
59    multibyte sequences are safe in formats.  Multibyte sequences are
60    safe if they cannot contain byte sequences that look like format
61    conversion specifications.  The GNU C Library uses UTF8 multibyte
62    encoding, which is safe for formats, but strftime.c can be used
63    with other C libraries that use unsafe encodings.  */
64 #define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
65
66 #if DO_MULTIBYTE
67 # if HAVE_MBRLEN
68 #  include <wchar.h>
69 # else
70    /* Simulate mbrlen with mblen as best we can.  */
71 #  define mbstate_t int
72 #  define mbrlen(s, n, ps) mblen (s, n)
73 #  define mbsinit(ps) (*(ps) == 0)
74 # endif
75   static const mbstate_t mbstate_zero;
76 #endif
77
78 #if HAVE_LIMITS_H
79 # include <limits.h>
80 #endif
81
82 #if STDC_HEADERS
83 # include <stddef.h>
84 # include <stdlib.h>
85 # include <string.h>
86 #endif
87
88 #ifdef COMPILE_WIDE
89 # include <endian.h>
90 # define CHAR_T wchar_t
91 # define UCHAR_T unsigned int
92 # define L_(Str) L##Str
93 # 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_('\a'): 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                   /* The wide name is after the single byte name and
838                      format.  */
839                   char *tcp = strchr (era->name_fmt, '\0') + 1;
840                   wchar_t *ws = (wchar_t *) (strchr (tcp, '\0') + 1);
841                   size_t len = wcslen (ws);
842                   cpy (len, ws);
843 # else
844                   size_t len = strlen (era->name_fmt);
845                   cpy (len, era->name_fmt);
846 # endif
847                   break;
848                 }
849 #else
850 # if HAVE_STRFTIME
851               goto underlying_strftime;
852 # endif
853 #endif
854             }
855
856           {
857             int year = tp->tm_year + TM_YEAR_BASE;
858             DO_NUMBER (1, year / 100 - (year % 100 < 0));
859           }
860
861         case L_('x'):
862           if (modifier == L_('O'))
863             goto bad_format;
864 #ifdef _NL_CURRENT
865           if (! (modifier == L_('E')
866                  && (*(subfmt = (CHAR_T *)_NL_CURRENT (LC_TIME,
867                                                        NLW(ERA_D_FMT)))
868                      != L_('\0'))))
869             subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
870           goto subformat;
871 #else
872 # if HAVE_STRFTIME
873           goto underlying_strftime;
874 # else
875           /* Fall through.  */
876 # endif
877 #endif
878         case L_('D'):           /* POSIX.2 extension.  */
879           if (modifier != 0)
880             goto bad_format;
881           subfmt = L_("%m/%d/%y");
882           goto subformat;
883
884         case L_('d'):
885           if (modifier == L_('E'))
886             goto bad_format;
887
888           DO_NUMBER (2, tp->tm_mday);
889
890         case L_('e'):           /* POSIX.2 extension.  */
891           if (modifier == L_('E'))
892             goto bad_format;
893
894           DO_NUMBER_SPACEPAD (2, tp->tm_mday);
895
896           /* All numeric formats set DIGITS and NUMBER_VALUE and then
897              jump to one of these two labels.  */
898
899         do_number_spacepad:
900           /* Force `_' flag unless overwritten by `0' flag.  */
901           if (pad != L_('0'))
902             pad = L_('_');
903
904         do_number:
905           /* Format the number according to the MODIFIER flag.  */
906
907           if (modifier == L_('O') && 0 <= number_value)
908             {
909 #ifdef _NL_CURRENT
910               /* Get the locale specific alternate representation of
911                  the number NUMBER_VALUE.  If none exist NULL is returned.  */
912 # ifdef COMPILE_WIDE
913               const wchar_t *cp = _nl_get_walt_digit (number_value);
914 # else
915               const char *cp = _nl_get_alt_digit (number_value);
916 # endif
917
918               if (cp != NULL)
919                 {
920                   size_t digitlen = STRLEN (cp);
921                   if (digitlen != 0)
922                     {
923                       cpy (digitlen, cp);
924                       break;
925                     }
926                 }
927 #else
928 # if HAVE_STRFTIME
929               goto underlying_strftime;
930 # endif
931 #endif
932             }
933           {
934             unsigned int u = number_value;
935
936             bufp = buf + sizeof (buf) / sizeof (buf[0]);
937             negative_number = number_value < 0;
938
939             if (negative_number)
940               u = -u;
941
942             do
943               *--bufp = u % 10 + L_('0');
944             while ((u /= 10) != 0);
945           }
946
947         do_number_sign_and_padding:
948           if (negative_number)
949             *--bufp = L_('-');
950
951           if (pad != L_('-'))
952             {
953               int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
954                                       - bufp);
955
956               if (pad == L_('_'))
957                 {
958                   while (0 < padding--)
959                     *--bufp = L_(' ');
960                 }
961               else
962                 {
963                   bufp += negative_number;
964                   while (0 < padding--)
965                     *--bufp = L_('0');
966                   if (negative_number)
967                     *--bufp = L_('-');
968                 }
969             }
970
971           cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
972           break;
973
974         case L_('F'):
975           if (modifier != 0)
976             goto bad_format;
977           subfmt = L_("%Y-%m-%d");
978           goto subformat;
979
980         case L_('H'):
981           if (modifier == L_('E'))
982             goto bad_format;
983
984           DO_NUMBER (2, tp->tm_hour);
985
986         case L_('I'):
987           if (modifier == L_('E'))
988             goto bad_format;
989
990           DO_NUMBER (2, hour12);
991
992         case L_('k'):           /* GNU extension.  */
993           if (modifier == L_('E'))
994             goto bad_format;
995
996           DO_NUMBER_SPACEPAD (2, tp->tm_hour);
997
998         case L_('l'):           /* GNU extension.  */
999           if (modifier == L_('E'))
1000             goto bad_format;
1001
1002           DO_NUMBER_SPACEPAD (2, hour12);
1003
1004         case L_('j'):
1005           if (modifier == L_('E'))
1006             goto bad_format;
1007
1008           DO_NUMBER (3, 1 + tp->tm_yday);
1009
1010         case L_('M'):
1011           if (modifier == L_('E'))
1012             goto bad_format;
1013
1014           DO_NUMBER (2, tp->tm_min);
1015
1016         case L_('m'):
1017           if (modifier == L_('E'))
1018             goto bad_format;
1019
1020           DO_NUMBER (2, tp->tm_mon + 1);
1021
1022         case L_('n'):           /* POSIX.2 extension.  */
1023           add (1, *p = L_('\n'));
1024           break;
1025
1026         case L_('P'):
1027           to_lowcase = 1;
1028 #if !defined _NL_CURRENT && HAVE_STRFTIME
1029           format_char = L_('p');
1030 #endif
1031           /* FALLTHROUGH */
1032
1033         case L_('p'):
1034           if (change_case)
1035             {
1036               to_uppcase = 0;
1037               to_lowcase = 1;
1038             }
1039 #if defined _NL_CURRENT || !HAVE_STRFTIME
1040           cpy (ap_len, ampm);
1041           break;
1042 #else
1043           goto underlying_strftime;
1044 #endif
1045
1046         case L_('R'):           /* GNU extension.  */
1047           subfmt = L_("%H:%M");
1048           goto subformat;
1049
1050         case L_('r'):           /* POSIX.2 extension.  */
1051 #ifdef _NL_CURRENT
1052           if (*(subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME,
1053                                                  NLW(T_FMT_AMPM))) == L_('\0'))
1054 #endif
1055             subfmt = L_("%I:%M:%S %p");
1056           goto subformat;
1057
1058         case L_('S'):
1059           if (modifier == L_('E'))
1060             goto bad_format;
1061
1062           DO_NUMBER (2, tp->tm_sec);
1063
1064         case L_('s'):           /* GNU extension.  */
1065           {
1066             struct tm ltm;
1067             time_t t;
1068
1069             ltm = *tp;
1070             t = mktime (&ltm);
1071
1072             /* Generate string value for T using time_t arithmetic;
1073                this works even if sizeof (long) < sizeof (time_t).  */
1074
1075             bufp = buf + sizeof (buf) / sizeof (buf[0]);
1076             negative_number = t < 0;
1077
1078             do
1079               {
1080                 int d = t % 10;
1081                 t /= 10;
1082
1083                 if (negative_number)
1084                   {
1085                     d = -d;
1086
1087                     /* Adjust if division truncates to minus infinity.  */
1088                     if (0 < -1 % 10 && d < 0)
1089                       {
1090                         t++;
1091                         d += 10;
1092                       }
1093                   }
1094
1095                 *--bufp = d + L_('0');
1096               }
1097             while (t != 0);
1098
1099             digits = 1;
1100             goto do_number_sign_and_padding;
1101           }
1102
1103         case L_('X'):
1104           if (modifier == L_('O'))
1105             goto bad_format;
1106 #ifdef _NL_CURRENT
1107           if (! (modifier == L_('E')
1108                  && (*(subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME,
1109                                                         NLW(ERA_T_FMT)))
1110                      != L_('\0'))))
1111             subfmt = (CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
1112           goto subformat;
1113 #else
1114 # if HAVE_STRFTIME
1115           goto underlying_strftime;
1116 # else
1117           /* Fall through.  */
1118 # endif
1119 #endif
1120         case L_('T'):           /* POSIX.2 extension.  */
1121           subfmt = L_("%H:%M:%S");
1122           goto subformat;
1123
1124         case L_('t'):           /* POSIX.2 extension.  */
1125           add (1, *p = L_('\t'));
1126           break;
1127
1128         case L_('u'):           /* POSIX.2 extension.  */
1129           DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
1130
1131         case L_('U'):
1132           if (modifier == L_('E'))
1133             goto bad_format;
1134
1135           DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
1136
1137         case L_('V'):
1138         case L_('g'):           /* GNU extension.  */
1139         case L_('G'):           /* GNU extension.  */
1140           if (modifier == L_('E'))
1141             goto bad_format;
1142           {
1143             int year = tp->tm_year + TM_YEAR_BASE;
1144             int days = iso_week_days (tp->tm_yday, tp->tm_wday);
1145
1146             if (days < 0)
1147               {
1148                 /* This ISO week belongs to the previous year.  */
1149                 year--;
1150                 days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
1151                                       tp->tm_wday);
1152               }
1153             else
1154               {
1155                 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
1156                                        tp->tm_wday);
1157                 if (0 <= d)
1158                   {
1159                     /* This ISO week belongs to the next year.  */
1160                     year++;
1161                     days = d;
1162                   }
1163               }
1164
1165             switch (*f)
1166               {
1167               case L_('g'):
1168                 DO_NUMBER (2, (year % 100 + 100) % 100);
1169
1170               case L_('G'):
1171                 DO_NUMBER (1, year);
1172
1173               default:
1174                 DO_NUMBER (2, days / 7 + 1);
1175               }
1176           }
1177
1178         case L_('W'):
1179           if (modifier == L_('E'))
1180             goto bad_format;
1181
1182           DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
1183
1184         case L_('w'):
1185           if (modifier == L_('E'))
1186             goto bad_format;
1187
1188           DO_NUMBER (1, tp->tm_wday);
1189
1190         case L_('Y'):
1191           if (modifier == 'E')
1192             {
1193 #if HAVE_STRUCT_ERA_ENTRY
1194               struct era_entry *era = _nl_get_era_entry (tp);
1195               if (era)
1196                 {
1197 # ifdef COMPILE_WIDE
1198                   /* The wide name is after the single byte name and
1199                      format.  */
1200                   char *tcp = strchr (era->name_fmt, '\0') + 1;
1201                   subfmt = (wchar_t *) (strchr (tcp, '\0') + 1);
1202                   subfmt = wcschr (subfmt, L'\0') + 1;
1203 # else
1204                   subfmt = strchr (era->name_fmt, '\0') + 1;
1205 # endif
1206                   goto subformat;
1207                 }
1208 #else
1209 # if HAVE_STRFTIME
1210               goto underlying_strftime;
1211 # endif
1212 #endif
1213             }
1214           if (modifier == L_('O'))
1215             goto bad_format;
1216           else
1217             DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
1218
1219         case L_('y'):
1220           if (modifier == L_('E'))
1221             {
1222 #if HAVE_STRUCT_ERA_ENTRY
1223               struct era_entry *era = _nl_get_era_entry (tp);
1224               if (era)
1225                 {
1226                   int delta = tp->tm_year - era->start_date[0];
1227                   DO_NUMBER (1, (era->offset
1228                                  + (era->direction == '-' ? -delta : delta)));
1229                 }
1230 #else
1231 # if HAVE_STRFTIME
1232               goto underlying_strftime;
1233 # endif
1234 #endif
1235             }
1236           DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
1237
1238         case L_('Z'):
1239           if (change_case)
1240             {
1241               to_uppcase = 0;
1242               to_lowcase = 1;
1243             }
1244
1245 #if HAVE_TZNAME
1246           /* The tzset() call might have changed the value.  */
1247           if (!(zone && *zone) && tp->tm_isdst >= 0)
1248             zone = tzname[tp->tm_isdst];
1249 #endif
1250           if (! zone)
1251             zone = "";          /* POSIX.2 requires the empty string here.  */
1252
1253 #ifdef COMPILE_WIDE
1254           {
1255             /* The zone string is always given in multibyte form.  We have
1256                to transform it first.  */
1257             wchar_t *wczone;
1258             size_t len;
1259             widen (zone, wczone, len);
1260             cpy (len, wczone);
1261           }
1262 #else
1263           cpy (strlen (zone), zone);
1264 #endif
1265           break;
1266
1267         case L_('z'):           /* GNU extension.  */
1268           if (tp->tm_isdst < 0)
1269             break;
1270
1271           {
1272             int diff;
1273 #if HAVE_TM_GMTOFF
1274             diff = tp->tm_gmtoff;
1275 #else
1276             if (ut)
1277               diff = 0;
1278             else
1279               {
1280                 struct tm gtm;
1281                 struct tm ltm;
1282                 time_t lt;
1283
1284                 ltm = *tp;
1285                 lt = mktime (&ltm);
1286
1287                 if (lt == (time_t) -1)
1288                   {
1289                     /* mktime returns -1 for errors, but -1 is also a
1290                        valid time_t value.  Check whether an error really
1291                        occurred.  */
1292                     struct tm tm;
1293
1294                     if (! my_strftime_localtime_r (&lt, &tm)
1295                         || ((ltm.tm_sec ^ tm.tm_sec)
1296                             | (ltm.tm_min ^ tm.tm_min)
1297                             | (ltm.tm_hour ^ tm.tm_hour)
1298                             | (ltm.tm_mday ^ tm.tm_mday)
1299                             | (ltm.tm_mon ^ tm.tm_mon)
1300                             | (ltm.tm_year ^ tm.tm_year)))
1301                       break;
1302                   }
1303
1304                 if (! my_strftime_gmtime_r (&lt, &gtm))
1305                   break;
1306
1307                 diff = tm_diff (&ltm, &gtm);
1308               }
1309 #endif
1310
1311             if (diff < 0)
1312               {
1313                 add (1, *p = L_('-'));
1314                 diff = -diff;
1315               }
1316             else
1317               add (1, *p = L_('+'));
1318
1319             diff /= 60;
1320             DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
1321           }
1322
1323         case L_('\0'):          /* GNU extension: % at end of format.  */
1324             --f;
1325             /* Fall through.  */
1326         default:
1327           /* Unknown format; output the format, including the '%',
1328              since this is most likely the right thing to do if a
1329              multibyte string has been misparsed.  */
1330         bad_format:
1331           {
1332             int flen;
1333             for (flen = 1; f[1 - flen] != L_('%'); flen++)
1334               continue;
1335             cpy (flen, &f[1 - flen]);
1336           }
1337           break;
1338         }
1339     }
1340
1341   if (p && maxsize != 0)
1342     *p = L_('\0');
1343   return i;
1344 }
1345
1346
1347 #ifdef emacs
1348 /* For Emacs we have a separate interface which corresponds to the normal
1349    strftime function and does not have the extra information whether the
1350    TP arguments comes from a `gmtime' call or not.  */
1351 size_t
1352 emacs_strftime (s, maxsize, format, tp)
1353       char *s;
1354       size_t maxsize;
1355       const char *format;
1356       const struct tm *tp;
1357 {
1358   return my_strftime (s, maxsize, format, tp, 0);
1359 }
1360 #endif