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