Add more libm tests (fabs, fdim, fma, fmax, fmin, fmod).
[glibc.git] / time / strftime_l.c
blob26829cf7bd639fab74c306ee26b4484ba74767f2
1 /* Copyright (C) 2002-2015 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 Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 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 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
22 #ifdef _LIBC
23 # define USE_IN_EXTENDED_LOCALE_MODEL 1
24 # define HAVE_LIMITS_H 1
25 # define HAVE_MBLEN 1
26 # define HAVE_MBRLEN 1
27 # define HAVE_STRUCT_ERA_ENTRY 1
28 # define HAVE_TM_GMTOFF 1
29 # define HAVE_TM_ZONE 1
30 # define HAVE_TZNAME 1
31 # define HAVE_TZSET 1
32 # define HAVE_STRFTIME 0
33 # define MULTIBYTE_IS_FORMAT_SAFE 1
34 # define STDC_HEADERS 1
35 # include "../locale/localeinfo.h"
36 #endif
38 #if defined emacs && !defined HAVE_BCOPY
39 # define HAVE_MEMCPY 1
40 #endif
42 #include <ctype.h>
43 #include <sys/types.h> /* Some systems define `time_t' here. */
45 #ifdef TIME_WITH_SYS_TIME
46 # include <sys/time.h>
47 # include <time.h>
48 #else
49 # ifdef HAVE_SYS_TIME_H
50 # include <sys/time.h>
51 # else
52 # include <time.h>
53 # endif
54 #endif
55 #if HAVE_TZNAME
56 extern char *tzname[];
57 #endif
59 /* Do multibyte processing if multibytes are supported, unless
60 multibyte sequences are safe in formats. Multibyte sequences are
61 safe if they cannot contain byte sequences that look like format
62 conversion specifications. The GNU C Library uses UTF8 multibyte
63 encoding, which is safe for formats, but strftime.c can be used
64 with other C libraries that use unsafe encodings. */
65 #define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
67 #if DO_MULTIBYTE
68 # if HAVE_MBRLEN
69 # include <wchar.h>
70 # else
71 /* Simulate mbrlen with mblen as best we can. */
72 # define mbstate_t int
73 # define mbrlen(s, n, ps) mblen (s, n)
74 # define mbsinit(ps) (*(ps) == 0)
75 # endif
76 static const mbstate_t mbstate_zero;
77 #endif
79 #if HAVE_LIMITS_H
80 # include <limits.h>
81 #endif
83 #if STDC_HEADERS
84 # include <stddef.h>
85 # include <stdlib.h>
86 # include <string.h>
87 # include <stdbool.h>
88 #else
89 # ifndef HAVE_MEMCPY
90 # define memcpy(d, s, n) bcopy ((s), (d), (n))
91 # endif
92 #endif
94 #ifdef COMPILE_WIDE
95 # include <endian.h>
96 # define CHAR_T wchar_t
97 # define UCHAR_T unsigned int
98 # define L_(Str) L##Str
99 # define NLW(Sym) _NL_W##Sym
101 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
102 # define STRLEN(s) __wcslen (s)
104 #else
105 # define CHAR_T char
106 # define UCHAR_T unsigned char
107 # define L_(Str) Str
108 # define NLW(Sym) Sym
110 # if !defined STDC_HEADERS && !defined HAVE_MEMCPY
111 # define MEMCPY(d, s, n) bcopy ((s), (d), (n))
112 # else
113 # define MEMCPY(d, s, n) memcpy ((d), (s), (n))
114 # endif
115 # define STRLEN(s) strlen (s)
117 # ifdef _LIBC
118 # define MEMPCPY(d, s, n) __mempcpy (d, s, n)
119 # else
120 # ifndef HAVE_MEMPCPY
121 # define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n)))
122 # endif
123 # endif
124 #endif
126 #ifndef PTR
127 # define PTR void *
128 #endif
130 #ifndef CHAR_BIT
131 # define CHAR_BIT 8
132 #endif
134 #ifndef NULL
135 # define NULL 0
136 #endif
138 #define TYPE_SIGNED(t) ((t) -1 < 0)
140 /* Bound on length of the string representing an integer value of type t.
141 Subtract one for the sign bit if t is signed;
142 302 / 1000 is log10 (2) rounded up;
143 add one for integer division truncation;
144 add one more for a minus sign if t is signed. */
145 #define INT_STRLEN_BOUND(t) \
146 ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 + 1 + TYPE_SIGNED (t))
148 #define TM_YEAR_BASE 1900
150 #ifndef __isleap
151 /* Nonzero if YEAR is a leap year (every 4 years,
152 except every 100th isn't, and every 400th is). */
153 # define __isleap(year) \
154 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
155 #endif
158 #ifdef _LIBC
159 # define tzname __tzname
160 # define tzset __tzset
161 #endif
163 #if !HAVE_TM_GMTOFF
164 /* Portable standalone applications should supply a "time_r.h" that
165 declares a POSIX-compliant localtime_r, for the benefit of older
166 implementations that lack localtime_r or have a nonstandard one.
167 Similarly for gmtime_r. See the gnulib time_r module for one way
168 to implement this. */
169 # include "time_r.h"
170 # undef __gmtime_r
171 # undef __localtime_r
172 # define __gmtime_r gmtime_r
173 # define __localtime_r localtime_r
174 #endif
177 #if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
178 /* Some systems lack the `memset' function and we don't want to
179 introduce additional dependencies. */
180 /* The SGI compiler reportedly barfs on the trailing null
181 if we use a string constant as the initializer. 28 June 1997, rms. */
182 static const CHAR_T spaces[16] = /* " " */
184 L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),
185 L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' ')
187 static const CHAR_T zeroes[16] = /* "0000000000000000" */
189 L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),
190 L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0')
193 # define memset_space(P, Len) \
194 do { \
195 int _len = (Len); \
197 do \
199 int _this = _len > 16 ? 16 : _len; \
200 (P) = MEMPCPY ((P), spaces, _this * sizeof (CHAR_T)); \
201 _len -= _this; \
203 while (_len > 0); \
204 } while (0)
206 # define memset_zero(P, Len) \
207 do { \
208 int _len = (Len); \
210 do \
212 int _this = _len > 16 ? 16 : _len; \
213 (P) = MEMPCPY ((P), zeroes, _this * sizeof (CHAR_T)); \
214 _len -= _this; \
216 while (_len > 0); \
217 } while (0)
218 #else
219 # ifdef COMPILE_WIDE
220 # define memset_space(P, Len) (wmemset ((P), L' ', (Len)), (P) += (Len))
221 # define memset_zero(P, Len) (wmemset ((P), L'0', (Len)), (P) += (Len))
222 # else
223 # define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
224 # define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
225 # endif
226 #endif
228 #define add(n, f) \
229 do \
231 int _n = (n); \
232 int _delta = width - _n; \
233 int _incr = _n + (_delta > 0 ? _delta : 0); \
234 if ((size_t) _incr >= maxsize - i) \
235 return 0; \
236 if (p) \
238 if (_delta > 0) \
240 if (pad == L_('0')) \
241 memset_zero (p, _delta); \
242 else \
243 memset_space (p, _delta); \
245 f; \
246 p += _n; \
248 i += _incr; \
249 } while (0)
251 #define cpy(n, s) \
252 add ((n), \
253 if (to_lowcase) \
254 memcpy_lowcase (p, (s), _n LOCALE_ARG); \
255 else if (to_uppcase) \
256 memcpy_uppcase (p, (s), _n LOCALE_ARG); \
257 else \
258 MEMCPY ((PTR) p, (const PTR) (s), _n))
260 #ifdef COMPILE_WIDE
261 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
262 # undef __mbsrtowcs_l
263 # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
264 # endif
265 # define widen(os, ws, l) \
267 mbstate_t __st; \
268 const char *__s = os; \
269 memset (&__st, '\0', sizeof (__st)); \
270 l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
271 ws = alloca ((l + 1) * sizeof (wchar_t)); \
272 (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
274 #endif
277 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
278 /* We use this code also for the extended locale handling where the
279 function gets as an additional argument the locale which has to be
280 used. To access the values we have to redefine the _NL_CURRENT
281 macro. */
282 # define strftime __strftime_l
283 # define wcsftime __wcsftime_l
284 # undef _NL_CURRENT
285 # define _NL_CURRENT(category, item) \
286 (current->values[_NL_ITEM_INDEX (item)].string)
287 # define LOCALE_PARAM , loc
288 # define LOCALE_ARG , loc
289 # define LOCALE_PARAM_DECL __locale_t loc;
290 # define LOCALE_PARAM_PROTO , __locale_t loc
291 # define HELPER_LOCALE_ARG , current
292 #else
293 # define LOCALE_PARAM
294 # define LOCALE_PARAM_PROTO
295 # define LOCALE_ARG
296 # define LOCALE_PARAM_DECL
297 # ifdef _LIBC
298 # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
299 # else
300 # define HELPER_LOCALE_ARG
301 # endif
302 #endif
304 #ifdef COMPILE_WIDE
305 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
306 # define TOUPPER(Ch, L) __towupper_l (Ch, L)
307 # define TOLOWER(Ch, L) __towlower_l (Ch, L)
308 # else
309 # define TOUPPER(Ch, L) towupper (Ch)
310 # define TOLOWER(Ch, L) towlower (Ch)
311 # endif
312 #else
313 # ifdef _LIBC
314 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
315 # define TOUPPER(Ch, L) __toupper_l (Ch, L)
316 # define TOLOWER(Ch, L) __tolower_l (Ch, L)
317 # else
318 # define TOUPPER(Ch, L) toupper (Ch)
319 # define TOLOWER(Ch, L) tolower (Ch)
320 # endif
321 # else
322 # define TOUPPER(Ch, L) (islower (Ch) ? toupper (Ch) : (Ch))
323 # define TOLOWER(Ch, L) (isupper (Ch) ? tolower (Ch) : (Ch))
324 # endif
325 #endif
326 /* We don't use `isdigit' here since the locale dependent
327 interpretation is not what we want here. We only need to accept
328 the arabic digits in the ASCII range. One day there is perhaps a
329 more reliable way to accept other sets of digits. */
330 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
332 static CHAR_T *memcpy_lowcase (CHAR_T *dest, const CHAR_T *src,
333 size_t len LOCALE_PARAM_PROTO) __THROW;
335 static CHAR_T *
336 memcpy_lowcase (dest, src, len LOCALE_PARAM)
337 CHAR_T *dest;
338 const CHAR_T *src;
339 size_t len;
340 LOCALE_PARAM_DECL
342 while (len-- > 0)
343 dest[len] = TOLOWER ((UCHAR_T) src[len], loc);
344 return dest;
347 static CHAR_T *memcpy_uppcase (CHAR_T *dest, const CHAR_T *src,
348 size_t len LOCALE_PARAM_PROTO) __THROW;
350 static CHAR_T *
351 memcpy_uppcase (dest, src, len LOCALE_PARAM)
352 CHAR_T *dest;
353 const CHAR_T *src;
354 size_t len;
355 LOCALE_PARAM_DECL
357 while (len-- > 0)
358 dest[len] = TOUPPER ((UCHAR_T) src[len], loc);
359 return dest;
363 #if ! HAVE_TM_GMTOFF
364 /* Yield the difference between *A and *B,
365 measured in seconds, ignoring leap seconds. */
366 # define tm_diff ftime_tm_diff
367 static int tm_diff (const struct tm *, const struct tm *) __THROW;
368 static int
369 tm_diff (const struct tm *a, const struct tm *b)
371 /* Compute intervening leap days correctly even if year is negative.
372 Take care to avoid int overflow in leap day calculations,
373 but it's OK to assume that A and B are close to each other. */
374 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
375 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
376 int a100 = a4 / 25 - (a4 % 25 < 0);
377 int b100 = b4 / 25 - (b4 % 25 < 0);
378 int a400 = a100 >> 2;
379 int b400 = b100 >> 2;
380 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
381 int years = a->tm_year - b->tm_year;
382 int days = (365 * years + intervening_leap_days
383 + (a->tm_yday - b->tm_yday));
384 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
385 + (a->tm_min - b->tm_min))
386 + (a->tm_sec - b->tm_sec));
388 #endif /* ! HAVE_TM_GMTOFF */
392 /* The number of days from the first day of the first ISO week of this
393 year to the year day YDAY with week day WDAY. ISO weeks start on
394 Monday; the first ISO week has the year's first Thursday. YDAY may
395 be as small as YDAY_MINIMUM. */
396 #define ISO_WEEK_START_WDAY 1 /* Monday */
397 #define ISO_WEEK1_WDAY 4 /* Thursday */
398 #define YDAY_MINIMUM (-366)
399 static int iso_week_days (int, int) __THROW;
400 #ifdef __GNUC__
401 __inline__
402 #endif
403 static int
404 iso_week_days (int yday, int wday)
406 /* Add enough to the first operand of % to make it nonnegative. */
407 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
408 return (yday
409 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
410 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
414 #if !(defined _NL_CURRENT || HAVE_STRFTIME)
415 static CHAR_T const weekday_name[][10] =
417 L_("Sunday"), L_("Monday"), L_("Tuesday"), L_("Wednesday"),
418 L_("Thursday"), L_("Friday"), L_("Saturday")
420 static CHAR_T const month_name[][10] =
422 L_("January"), L_("February"), L_("March"), L_("April"), L_("May"),
423 L_("June"), L_("July"), L_("August"), L_("September"), L_("October"),
424 L_("November"), L_("December")
426 #endif
429 #ifdef emacs
430 # define my_strftime emacs_strftimeu
431 # define ut_argument , ut
432 # define ut_argument_spec int ut;
433 # define ut_argument_spec_iso , int ut
434 #else
435 # ifdef COMPILE_WIDE
436 # define my_strftime wcsftime
437 # define nl_get_alt_digit _nl_get_walt_digit
438 # else
439 # define my_strftime strftime
440 # define nl_get_alt_digit _nl_get_alt_digit
441 # endif
442 # define ut_argument
443 # define ut_argument_spec
444 # define ut_argument_spec_iso
445 /* We don't have this information in general. */
446 # define ut 0
447 #endif
449 static size_t __strftime_internal (CHAR_T *, size_t, const CHAR_T *,
450 const struct tm *, bool *
451 ut_argument_spec_iso
452 LOCALE_PARAM_PROTO) __THROW;
454 /* Write information from TP into S according to the format
455 string FORMAT, writing no more that MAXSIZE characters
456 (including the terminating '\0') and returning number of
457 characters written. If S is NULL, nothing will be written
458 anywhere, so to determine how many characters would be
459 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
461 size_t
462 my_strftime (s, maxsize, format, tp ut_argument LOCALE_PARAM)
463 CHAR_T *s;
464 size_t maxsize;
465 const CHAR_T *format;
466 const struct tm *tp;
467 ut_argument_spec
468 LOCALE_PARAM_DECL
470 #if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
471 /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
472 Work around this bug by copying *tp before it might be munged. */
473 struct tm tmcopy;
474 tmcopy = *tp;
475 tp = &tmcopy;
476 #endif
477 bool tzset_called = false;
478 return __strftime_internal (s, maxsize, format, tp, &tzset_called
479 ut_argument LOCALE_ARG);
481 #ifdef _LIBC
482 libc_hidden_def (my_strftime)
483 #endif
485 static size_t
486 __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
487 LOCALE_PARAM)
488 CHAR_T *s;
489 size_t maxsize;
490 const CHAR_T *format;
491 const struct tm *tp;
492 bool *tzset_called;
493 ut_argument_spec
494 LOCALE_PARAM_DECL
496 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
497 struct __locale_data *const current = loc->__locales[LC_TIME];
498 #endif
500 int hour12 = tp->tm_hour;
501 #ifdef _NL_CURRENT
502 /* We cannot make the following values variables since we must delay
503 the evaluation of these values until really needed since some
504 expressions might not be valid in every situation. The `struct tm'
505 might be generated by a strptime() call that initialized
506 only a few elements. Dereference the pointers only if the format
507 requires this. Then it is ok to fail if the pointers are invalid. */
508 # define a_wkday \
509 ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \
510 ? "?" : _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday)))
511 # define f_wkday \
512 ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \
513 ? "?" : _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday)))
514 # define a_month \
515 ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \
516 ? "?" : _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon)))
517 # define f_month \
518 ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \
519 ? "?" : _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon)))
520 # define ampm \
521 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
522 ? NLW(PM_STR) : NLW(AM_STR)))
524 # define aw_len STRLEN (a_wkday)
525 # define am_len STRLEN (a_month)
526 # define ap_len STRLEN (ampm)
527 #else
528 # if !HAVE_STRFTIME
529 # define f_wkday (tp->tm_wday < 0 || tp->tm_wday > 6 \
530 ? "?" : weekday_name[tp->tm_wday])
531 # define f_month (tp->tm_mon < 0 || tp->tm_mon > 11 \
532 ? "?" : month_name[tp->tm_mon])
533 # define a_wkday f_wkday
534 # define a_month f_month
535 # define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
537 size_t aw_len = 3;
538 size_t am_len = 3;
539 size_t ap_len = 2;
540 # endif
541 #endif
542 const char *zone;
543 size_t i = 0;
544 CHAR_T *p = s;
545 const CHAR_T *f;
546 #if DO_MULTIBYTE && !defined COMPILE_WIDE
547 const char *format_end = NULL;
548 #endif
550 zone = NULL;
551 #if HAVE_TM_ZONE
552 /* The POSIX test suite assumes that setting
553 the environment variable TZ to a new value before calling strftime()
554 will influence the result (the %Z format) even if the information in
555 TP is computed with a totally different time zone.
556 This is bogus: though POSIX allows bad behavior like this,
557 POSIX does not require it. Do the right thing instead. */
558 zone = (const char *) tp->tm_zone;
559 #endif
560 #if HAVE_TZNAME
561 if (ut)
563 if (! (zone && *zone))
564 zone = "GMT";
566 #endif
568 if (hour12 > 12)
569 hour12 -= 12;
570 else
571 if (hour12 == 0)
572 hour12 = 12;
574 for (f = format; *f != '\0'; ++f)
576 int pad = 0; /* Padding for number ('-', '_', or 0). */
577 int modifier; /* Field modifier ('E', 'O', or 0). */
578 int digits; /* Max digits for numeric format. */
579 int number_value; /* Numeric value to be printed. */
580 int negative_number; /* 1 if the number is negative. */
581 const CHAR_T *subfmt;
582 CHAR_T *bufp;
583 CHAR_T buf[1 + (sizeof (int) < sizeof (time_t)
584 ? INT_STRLEN_BOUND (time_t)
585 : INT_STRLEN_BOUND (int))];
586 int width = -1;
587 int to_lowcase = 0;
588 int to_uppcase = 0;
589 int change_case = 0;
590 int format_char;
592 #if DO_MULTIBYTE && !defined COMPILE_WIDE
593 switch (*f)
595 case L_('%'):
596 break;
598 case L_('\b'): case L_('\t'): case L_('\n'):
599 case L_('\v'): case L_('\f'): case L_('\r'):
600 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
601 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
602 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
603 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
604 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
605 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
606 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
607 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
608 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
609 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
610 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
611 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
612 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
613 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
614 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
615 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
616 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
617 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
618 case L_('~'):
619 /* The C Standard requires these 98 characters (plus '%') to
620 be in the basic execution character set. None of these
621 characters can start a multibyte sequence, so they need
622 not be analyzed further. */
623 add (1, *p = *f);
624 continue;
626 default:
627 /* Copy this multibyte sequence until we reach its end, find
628 an error, or come back to the initial shift state. */
630 mbstate_t mbstate = mbstate_zero;
631 size_t len = 0;
632 size_t fsize;
634 if (! format_end)
635 format_end = f + strlen (f) + 1;
636 fsize = format_end - f;
640 size_t bytes = mbrlen (f + len, fsize - len, &mbstate);
642 if (bytes == 0)
643 break;
645 if (bytes == (size_t) -2)
647 len += strlen (f + len);
648 break;
651 if (bytes == (size_t) -1)
653 len++;
654 break;
657 len += bytes;
659 while (! mbsinit (&mbstate));
661 cpy (len, f);
662 f += len - 1;
663 continue;
667 #else /* ! DO_MULTIBYTE */
669 /* Either multibyte encodings are not supported, they are
670 safe for formats, so any non-'%' byte can be copied through,
671 or this is the wide character version. */
672 if (*f != L_('%'))
674 add (1, *p = *f);
675 continue;
678 #endif /* ! DO_MULTIBYTE */
680 /* Check for flags that can modify a format. */
681 while (1)
683 switch (*++f)
685 /* This influences the number formats. */
686 case L_('_'):
687 case L_('-'):
688 case L_('0'):
689 pad = *f;
690 continue;
692 /* This changes textual output. */
693 case L_('^'):
694 to_uppcase = 1;
695 continue;
696 case L_('#'):
697 change_case = 1;
698 continue;
700 default:
701 break;
703 break;
706 /* As a GNU extension we allow to specify the field width. */
707 if (ISDIGIT (*f))
709 width = 0;
712 if (width > INT_MAX / 10
713 || (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10))
714 /* Avoid overflow. */
715 width = INT_MAX;
716 else
718 width *= 10;
719 width += *f - L_('0');
721 ++f;
723 while (ISDIGIT (*f));
726 /* Check for modifiers. */
727 switch (*f)
729 case L_('E'):
730 case L_('O'):
731 modifier = *f++;
732 break;
734 default:
735 modifier = 0;
736 break;
739 /* Now do the specified format. */
740 format_char = *f;
741 switch (format_char)
743 #define DO_NUMBER(d, v) \
744 digits = d > width ? d : width; \
745 number_value = v; goto do_number
746 #define DO_NUMBER_SPACEPAD(d, v) \
747 digits = d > width ? d : width; \
748 number_value = v; goto do_number_spacepad
750 case L_('%'):
751 if (modifier != 0)
752 goto bad_format;
753 add (1, *p = *f);
754 break;
756 case L_('a'):
757 if (modifier != 0)
758 goto bad_format;
759 if (change_case)
761 to_uppcase = 1;
762 to_lowcase = 0;
764 #if defined _NL_CURRENT || !HAVE_STRFTIME
765 cpy (aw_len, a_wkday);
766 break;
767 #else
768 goto underlying_strftime;
769 #endif
771 case 'A':
772 if (modifier != 0)
773 goto bad_format;
774 if (change_case)
776 to_uppcase = 1;
777 to_lowcase = 0;
779 #if defined _NL_CURRENT || !HAVE_STRFTIME
780 cpy (STRLEN (f_wkday), f_wkday);
781 break;
782 #else
783 goto underlying_strftime;
784 #endif
786 case L_('b'):
787 case L_('h'):
788 if (change_case)
790 to_uppcase = 1;
791 to_lowcase = 0;
793 if (modifier != 0)
794 goto bad_format;
795 #if defined _NL_CURRENT || !HAVE_STRFTIME
796 cpy (am_len, a_month);
797 break;
798 #else
799 goto underlying_strftime;
800 #endif
802 case L_('B'):
803 if (modifier != 0)
804 goto bad_format;
805 if (change_case)
807 to_uppcase = 1;
808 to_lowcase = 0;
810 #if defined _NL_CURRENT || !HAVE_STRFTIME
811 cpy (STRLEN (f_month), f_month);
812 break;
813 #else
814 goto underlying_strftime;
815 #endif
817 case L_('c'):
818 if (modifier == L_('O'))
819 goto bad_format;
820 #ifdef _NL_CURRENT
821 if (! (modifier == 'E'
822 && (*(subfmt =
823 (const CHAR_T *) _NL_CURRENT (LC_TIME,
824 NLW(ERA_D_T_FMT)))
825 != '\0')))
826 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
827 #else
828 # if HAVE_STRFTIME
829 goto underlying_strftime;
830 # else
831 subfmt = L_("%a %b %e %H:%M:%S %Y");
832 # endif
833 #endif
835 subformat:
837 CHAR_T *old_start = p;
838 size_t len = __strftime_internal (NULL, (size_t) -1, subfmt,
839 tp, tzset_called ut_argument
840 LOCALE_ARG);
841 add (len, __strftime_internal (p, maxsize - i, subfmt,
842 tp, tzset_called ut_argument
843 LOCALE_ARG));
845 if (to_uppcase)
846 while (old_start < p)
848 *old_start = TOUPPER ((UCHAR_T) *old_start, loc);
849 ++old_start;
852 break;
854 #if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
855 underlying_strftime:
857 /* The relevant information is available only via the
858 underlying strftime implementation, so use that. */
859 char ufmt[4];
860 char *u = ufmt;
861 char ubuf[1024]; /* enough for any single format in practice */
862 size_t len;
863 /* Make sure we're calling the actual underlying strftime.
864 In some cases, config.h contains something like
865 "#define strftime rpl_strftime". */
866 # ifdef strftime
867 # undef strftime
868 size_t strftime ();
869 # endif
871 *u++ = '%';
872 if (modifier != 0)
873 *u++ = modifier;
874 *u++ = format_char;
875 *u = '\0';
876 len = strftime (ubuf, sizeof ubuf, ufmt, tp);
877 if (len == 0 && ubuf[0] != '\0')
878 return 0;
879 cpy (len, ubuf);
881 break;
882 #endif
884 case L_('C'):
885 if (modifier == L_('E'))
887 #if HAVE_STRUCT_ERA_ENTRY
888 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
889 if (era)
891 # ifdef COMPILE_WIDE
892 size_t len = __wcslen (era->era_wname);
893 cpy (len, era->era_wname);
894 # else
895 size_t len = strlen (era->era_name);
896 cpy (len, era->era_name);
897 # endif
898 break;
900 #else
901 # if HAVE_STRFTIME
902 goto underlying_strftime;
903 # endif
904 #endif
908 int year = tp->tm_year + TM_YEAR_BASE;
909 DO_NUMBER (1, year / 100 - (year % 100 < 0));
912 case L_('x'):
913 if (modifier == L_('O'))
914 goto bad_format;
915 #ifdef _NL_CURRENT
916 if (! (modifier == L_('E')
917 && (*(subfmt =
918 (const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT)))
919 != L_('\0'))))
920 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
921 goto subformat;
922 #else
923 # if HAVE_STRFTIME
924 goto underlying_strftime;
925 # else
926 /* Fall through. */
927 # endif
928 #endif
929 case L_('D'):
930 if (modifier != 0)
931 goto bad_format;
932 subfmt = L_("%m/%d/%y");
933 goto subformat;
935 case L_('d'):
936 if (modifier == L_('E'))
937 goto bad_format;
939 DO_NUMBER (2, tp->tm_mday);
941 case L_('e'):
942 if (modifier == L_('E'))
943 goto bad_format;
945 DO_NUMBER_SPACEPAD (2, tp->tm_mday);
947 /* All numeric formats set DIGITS and NUMBER_VALUE and then
948 jump to one of these two labels. */
950 do_number_spacepad:
951 /* Force `_' flag unless overwritten by `0' or '-' flag. */
952 if (pad != L_('0') && pad != L_('-'))
953 pad = L_('_');
955 do_number:
956 /* Format the number according to the MODIFIER flag. */
958 if (modifier == L_('O') && 0 <= number_value)
960 #ifdef _NL_CURRENT
961 /* Get the locale specific alternate representation of
962 the number NUMBER_VALUE. If none exist NULL is returned. */
963 const CHAR_T *cp = nl_get_alt_digit (number_value
964 HELPER_LOCALE_ARG);
966 if (cp != NULL)
968 size_t digitlen = STRLEN (cp);
969 if (digitlen != 0)
971 cpy (digitlen, cp);
972 break;
975 #else
976 # if HAVE_STRFTIME
977 goto underlying_strftime;
978 # endif
979 #endif
982 unsigned int u = number_value;
984 bufp = buf + sizeof (buf) / sizeof (buf[0]);
985 negative_number = number_value < 0;
987 if (negative_number)
988 u = -u;
991 *--bufp = u % 10 + L_('0');
992 while ((u /= 10) != 0);
995 do_number_sign_and_padding:
996 if (negative_number)
997 *--bufp = L_('-');
999 if (pad != L_('-'))
1001 int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
1002 - bufp);
1004 if (padding > 0)
1006 if (pad == L_('_'))
1008 if ((size_t) padding >= maxsize - i)
1009 return 0;
1011 if (p)
1012 memset_space (p, padding);
1013 i += padding;
1014 width = width > padding ? width - padding : 0;
1016 else
1018 if ((size_t) digits >= maxsize - i)
1019 return 0;
1021 if (negative_number)
1023 ++bufp;
1025 if (p)
1026 *p++ = L_('-');
1027 ++i;
1030 if (p)
1031 memset_zero (p, padding);
1032 i += padding;
1033 width = 0;
1038 cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
1039 break;
1041 case L_('F'):
1042 if (modifier != 0)
1043 goto bad_format;
1044 subfmt = L_("%Y-%m-%d");
1045 goto subformat;
1047 case L_('H'):
1048 if (modifier == L_('E'))
1049 goto bad_format;
1051 DO_NUMBER (2, tp->tm_hour);
1053 case L_('I'):
1054 if (modifier == L_('E'))
1055 goto bad_format;
1057 DO_NUMBER (2, hour12);
1059 case L_('k'): /* GNU extension. */
1060 if (modifier == L_('E'))
1061 goto bad_format;
1063 DO_NUMBER_SPACEPAD (2, tp->tm_hour);
1065 case L_('l'): /* GNU extension. */
1066 if (modifier == L_('E'))
1067 goto bad_format;
1069 DO_NUMBER_SPACEPAD (2, hour12);
1071 case L_('j'):
1072 if (modifier == L_('E'))
1073 goto bad_format;
1075 DO_NUMBER (3, 1 + tp->tm_yday);
1077 case L_('M'):
1078 if (modifier == L_('E'))
1079 goto bad_format;
1081 DO_NUMBER (2, tp->tm_min);
1083 case L_('m'):
1084 if (modifier == L_('E'))
1085 goto bad_format;
1087 DO_NUMBER (2, tp->tm_mon + 1);
1089 case L_('n'):
1090 add (1, *p = L_('\n'));
1091 break;
1093 case L_('P'):
1094 to_lowcase = 1;
1095 #if !defined _NL_CURRENT && HAVE_STRFTIME
1096 format_char = L_('p');
1097 #endif
1098 /* FALLTHROUGH */
1100 case L_('p'):
1101 if (change_case)
1103 to_uppcase = 0;
1104 to_lowcase = 1;
1106 #if defined _NL_CURRENT || !HAVE_STRFTIME
1107 cpy (ap_len, ampm);
1108 break;
1109 #else
1110 goto underlying_strftime;
1111 #endif
1113 case L_('R'):
1114 subfmt = L_("%H:%M");
1115 goto subformat;
1117 case L_('r'):
1118 #if !defined _NL_CURRENT && HAVE_STRFTIME
1119 goto underlying_strftime;
1120 #else
1121 # ifdef _NL_CURRENT
1122 if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME,
1123 NLW(T_FMT_AMPM)))
1124 == L_('\0'))
1125 # endif
1126 subfmt = L_("%I:%M:%S %p");
1127 goto subformat;
1128 #endif
1130 case L_('S'):
1131 if (modifier == L_('E'))
1132 goto bad_format;
1134 DO_NUMBER (2, tp->tm_sec);
1136 case L_('s'): /* GNU extension. */
1138 struct tm ltm;
1139 time_t t;
1141 ltm = *tp;
1142 t = mktime (&ltm);
1144 /* Generate string value for T using time_t arithmetic;
1145 this works even if sizeof (long) < sizeof (time_t). */
1147 bufp = buf + sizeof (buf) / sizeof (buf[0]);
1148 negative_number = t < 0;
1152 int d = t % 10;
1153 t /= 10;
1155 if (negative_number)
1157 d = -d;
1159 /* Adjust if division truncates to minus infinity. */
1160 if (0 < -1 % 10 && d < 0)
1162 t++;
1163 d += 10;
1167 *--bufp = d + L_('0');
1169 while (t != 0);
1171 digits = 1;
1172 goto do_number_sign_and_padding;
1175 case L_('X'):
1176 if (modifier == L_('O'))
1177 goto bad_format;
1178 #ifdef _NL_CURRENT
1179 if (! (modifier == L_('E')
1180 && (*(subfmt =
1181 (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT)))
1182 != L_('\0'))))
1183 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
1184 goto subformat;
1185 #else
1186 # if HAVE_STRFTIME
1187 goto underlying_strftime;
1188 # else
1189 /* Fall through. */
1190 # endif
1191 #endif
1192 case L_('T'):
1193 subfmt = L_("%H:%M:%S");
1194 goto subformat;
1196 case L_('t'):
1197 add (1, *p = L_('\t'));
1198 break;
1200 case L_('u'):
1201 DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
1203 case L_('U'):
1204 if (modifier == L_('E'))
1205 goto bad_format;
1207 DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
1209 case L_('V'):
1210 case L_('g'):
1211 case L_('G'):
1212 if (modifier == L_('E'))
1213 goto bad_format;
1215 int year = tp->tm_year + TM_YEAR_BASE;
1216 int days = iso_week_days (tp->tm_yday, tp->tm_wday);
1218 if (days < 0)
1220 /* This ISO week belongs to the previous year. */
1221 year--;
1222 days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
1223 tp->tm_wday);
1225 else
1227 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
1228 tp->tm_wday);
1229 if (0 <= d)
1231 /* This ISO week belongs to the next year. */
1232 year++;
1233 days = d;
1237 switch (*f)
1239 case L_('g'):
1240 DO_NUMBER (2, (year % 100 + 100) % 100);
1242 case L_('G'):
1243 DO_NUMBER (1, year);
1245 default:
1246 DO_NUMBER (2, days / 7 + 1);
1250 case L_('W'):
1251 if (modifier == L_('E'))
1252 goto bad_format;
1254 DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
1256 case L_('w'):
1257 if (modifier == L_('E'))
1258 goto bad_format;
1260 DO_NUMBER (1, tp->tm_wday);
1262 case L_('Y'):
1263 if (modifier == 'E')
1265 #if HAVE_STRUCT_ERA_ENTRY
1266 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1267 if (era)
1269 # ifdef COMPILE_WIDE
1270 subfmt = era->era_wformat;
1271 # else
1272 subfmt = era->era_format;
1273 # endif
1274 goto subformat;
1276 #else
1277 # if HAVE_STRFTIME
1278 goto underlying_strftime;
1279 # endif
1280 #endif
1282 if (modifier == L_('O'))
1283 goto bad_format;
1284 else
1285 DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
1287 case L_('y'):
1288 if (modifier == L_('E'))
1290 #if HAVE_STRUCT_ERA_ENTRY
1291 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1292 if (era)
1294 int delta = tp->tm_year - era->start_date[0];
1295 DO_NUMBER (1, (era->offset
1296 + delta * era->absolute_direction));
1298 #else
1299 # if HAVE_STRFTIME
1300 goto underlying_strftime;
1301 # endif
1302 #endif
1304 DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
1306 case L_('Z'):
1307 if (change_case)
1309 to_uppcase = 0;
1310 to_lowcase = 1;
1313 #if HAVE_TZNAME
1314 /* The tzset() call might have changed the value. */
1315 if (!(zone && *zone) && tp->tm_isdst >= 0)
1317 /* POSIX.1 requires that local time zone information is used as
1318 though strftime called tzset. */
1319 # if HAVE_TZSET
1320 if (!*tzset_called)
1322 tzset ();
1323 *tzset_called = true;
1325 # endif
1326 zone = tp->tm_isdst <= 1 ? tzname[tp->tm_isdst] : "?";
1328 #endif
1329 if (! zone)
1330 zone = "";
1332 #ifdef COMPILE_WIDE
1334 /* The zone string is always given in multibyte form. We have
1335 to transform it first. */
1336 wchar_t *wczone;
1337 size_t len;
1338 widen (zone, wczone, len);
1339 cpy (len, wczone);
1341 #else
1342 cpy (strlen (zone), zone);
1343 #endif
1344 break;
1346 case L_('z'):
1347 if (tp->tm_isdst < 0)
1348 break;
1351 int diff;
1352 #if HAVE_TM_GMTOFF
1353 diff = tp->tm_gmtoff;
1354 #else
1355 if (ut)
1356 diff = 0;
1357 else
1359 struct tm gtm;
1360 struct tm ltm;
1361 time_t lt;
1363 /* POSIX.1 requires that local time zone information is used as
1364 though strftime called tzset. */
1365 # if HAVE_TZSET
1366 if (!*tzset_called)
1368 tzset ();
1369 *tzset_called = true;
1371 # endif
1373 ltm = *tp;
1374 lt = mktime (&ltm);
1376 if (lt == (time_t) -1)
1378 /* mktime returns -1 for errors, but -1 is also a
1379 valid time_t value. Check whether an error really
1380 occurred. */
1381 struct tm tm;
1383 if (! __localtime_r (&lt, &tm)
1384 || ((ltm.tm_sec ^ tm.tm_sec)
1385 | (ltm.tm_min ^ tm.tm_min)
1386 | (ltm.tm_hour ^ tm.tm_hour)
1387 | (ltm.tm_mday ^ tm.tm_mday)
1388 | (ltm.tm_mon ^ tm.tm_mon)
1389 | (ltm.tm_year ^ tm.tm_year)))
1390 break;
1393 if (! __gmtime_r (&lt, &gtm))
1394 break;
1396 diff = tm_diff (&ltm, &gtm);
1398 #endif
1400 if (diff < 0)
1402 add (1, *p = L_('-'));
1403 diff = -diff;
1405 else
1406 add (1, *p = L_('+'));
1408 diff /= 60;
1409 DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
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 (p && maxsize != 0)
1431 *p = L_('\0');
1432 return i;
1436 #ifdef emacs
1437 /* For Emacs we have a separate interface which corresponds to the normal
1438 strftime function and does not have the extra information whether the
1439 TP arguments comes from a `gmtime' call or not. */
1440 size_t
1441 emacs_strftime (s, maxsize, format, tp)
1442 char *s;
1443 size_t maxsize;
1444 const char *format;
1445 const struct tm *tp;
1447 return my_strftime (s, maxsize, format, tp, 0);
1449 #endif
1451 #if defined _LIBC && !defined COMPILE_WIDE
1452 weak_alias (__strftime_l, strftime_l)
1453 #endif