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