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