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