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