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