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