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