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