S390: Optimize strnlen and wcsnlen.
[glibc.git] / time / strftime_l.c
blobb48ef340342817840e5dc22c4223493654e9a344
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 (a, b)
370 const struct tm *a;
371 const struct tm *b;
373 /* Compute intervening leap days correctly even if year is negative.
374 Take care to avoid int overflow in leap day calculations,
375 but it's OK to assume that A and B are close to each other. */
376 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
377 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
378 int a100 = a4 / 25 - (a4 % 25 < 0);
379 int b100 = b4 / 25 - (b4 % 25 < 0);
380 int a400 = a100 >> 2;
381 int b400 = b100 >> 2;
382 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
383 int years = a->tm_year - b->tm_year;
384 int days = (365 * years + intervening_leap_days
385 + (a->tm_yday - b->tm_yday));
386 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
387 + (a->tm_min - b->tm_min))
388 + (a->tm_sec - b->tm_sec));
390 #endif /* ! HAVE_TM_GMTOFF */
394 /* The number of days from the first day of the first ISO week of this
395 year to the year day YDAY with week day WDAY. ISO weeks start on
396 Monday; the first ISO week has the year's first Thursday. YDAY may
397 be as small as YDAY_MINIMUM. */
398 #define ISO_WEEK_START_WDAY 1 /* Monday */
399 #define ISO_WEEK1_WDAY 4 /* Thursday */
400 #define YDAY_MINIMUM (-366)
401 static int iso_week_days (int, int) __THROW;
402 #ifdef __GNUC__
403 __inline__
404 #endif
405 static int
406 iso_week_days (yday, wday)
407 int yday;
408 int wday;
410 /* Add enough to the first operand of % to make it nonnegative. */
411 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
412 return (yday
413 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
414 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
418 #if !(defined _NL_CURRENT || HAVE_STRFTIME)
419 static CHAR_T const weekday_name[][10] =
421 L_("Sunday"), L_("Monday"), L_("Tuesday"), L_("Wednesday"),
422 L_("Thursday"), L_("Friday"), L_("Saturday")
424 static CHAR_T const month_name[][10] =
426 L_("January"), L_("February"), L_("March"), L_("April"), L_("May"),
427 L_("June"), L_("July"), L_("August"), L_("September"), L_("October"),
428 L_("November"), L_("December")
430 #endif
433 #ifdef emacs
434 # define my_strftime emacs_strftimeu
435 # define ut_argument , ut
436 # define ut_argument_spec int ut;
437 # define ut_argument_spec_iso , int ut
438 #else
439 # ifdef COMPILE_WIDE
440 # define my_strftime wcsftime
441 # define nl_get_alt_digit _nl_get_walt_digit
442 # else
443 # define my_strftime strftime
444 # define nl_get_alt_digit _nl_get_alt_digit
445 # endif
446 # define ut_argument
447 # define ut_argument_spec
448 # define ut_argument_spec_iso
449 /* We don't have this information in general. */
450 # define ut 0
451 #endif
453 static size_t __strftime_internal (CHAR_T *, size_t, const CHAR_T *,
454 const struct tm *, bool *
455 ut_argument_spec_iso
456 LOCALE_PARAM_PROTO) __THROW;
458 /* Write information from TP into S according to the format
459 string FORMAT, writing no more that MAXSIZE characters
460 (including the terminating '\0') and returning number of
461 characters written. If S is NULL, nothing will be written
462 anywhere, so to determine how many characters would be
463 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
465 size_t
466 my_strftime (s, maxsize, format, tp ut_argument LOCALE_PARAM)
467 CHAR_T *s;
468 size_t maxsize;
469 const CHAR_T *format;
470 const struct tm *tp;
471 ut_argument_spec
472 LOCALE_PARAM_DECL
474 #if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
475 /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
476 Work around this bug by copying *tp before it might be munged. */
477 struct tm tmcopy;
478 tmcopy = *tp;
479 tp = &tmcopy;
480 #endif
481 bool tzset_called = false;
482 return __strftime_internal (s, maxsize, format, tp, &tzset_called
483 ut_argument LOCALE_ARG);
485 #ifdef _LIBC
486 libc_hidden_def (my_strftime)
487 #endif
489 static size_t
490 __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
491 LOCALE_PARAM)
492 CHAR_T *s;
493 size_t maxsize;
494 const CHAR_T *format;
495 const struct tm *tp;
496 bool *tzset_called;
497 ut_argument_spec
498 LOCALE_PARAM_DECL
500 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
501 struct __locale_data *const current = loc->__locales[LC_TIME];
502 #endif
504 int hour12 = tp->tm_hour;
505 #ifdef _NL_CURRENT
506 /* We cannot make the following values variables since we must delay
507 the evaluation of these values until really needed since some
508 expressions might not be valid in every situation. The `struct tm'
509 might be generated by a strptime() call that initialized
510 only a few elements. Dereference the pointers only if the format
511 requires this. Then it is ok to fail if the pointers are invalid. */
512 # define a_wkday \
513 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
514 # define f_wkday \
515 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
516 # define a_month \
517 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
518 # define f_month \
519 ((const CHAR_T *) _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 (weekday_name[tp->tm_wday])
530 # define f_month (month_name[tp->tm_mon])
531 # define a_wkday f_wkday
532 # define a_month f_month
533 # define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
535 size_t aw_len = 3;
536 size_t am_len = 3;
537 size_t ap_len = 2;
538 # endif
539 #endif
540 const char *zone;
541 size_t i = 0;
542 CHAR_T *p = s;
543 const CHAR_T *f;
544 #if DO_MULTIBYTE && !defined COMPILE_WIDE
545 const char *format_end = NULL;
546 #endif
548 zone = NULL;
549 #if HAVE_TM_ZONE
550 /* The POSIX test suite assumes that setting
551 the environment variable TZ to a new value before calling strftime()
552 will influence the result (the %Z format) even if the information in
553 TP is computed with a totally different time zone.
554 This is bogus: though POSIX allows bad behavior like this,
555 POSIX does not require it. Do the right thing instead. */
556 zone = (const char *) tp->tm_zone;
557 #endif
558 #if HAVE_TZNAME
559 if (ut)
561 if (! (zone && *zone))
562 zone = "GMT";
564 #endif
566 if (hour12 > 12)
567 hour12 -= 12;
568 else
569 if (hour12 == 0)
570 hour12 = 12;
572 for (f = format; *f != '\0'; ++f)
574 int pad = 0; /* Padding for number ('-', '_', or 0). */
575 int modifier; /* Field modifier ('E', 'O', or 0). */
576 int digits; /* Max digits for numeric format. */
577 int number_value; /* Numeric value to be printed. */
578 int negative_number; /* 1 if the number is negative. */
579 const CHAR_T *subfmt;
580 CHAR_T *bufp;
581 CHAR_T buf[1 + (sizeof (int) < sizeof (time_t)
582 ? INT_STRLEN_BOUND (time_t)
583 : INT_STRLEN_BOUND (int))];
584 int width = -1;
585 int to_lowcase = 0;
586 int to_uppcase = 0;
587 int change_case = 0;
588 int format_char;
590 #if DO_MULTIBYTE && !defined COMPILE_WIDE
591 switch (*f)
593 case L_('%'):
594 break;
596 case L_('\b'): case L_('\t'): case L_('\n'):
597 case L_('\v'): case L_('\f'): case L_('\r'):
598 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
599 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
600 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
601 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
602 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
603 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
604 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
605 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
606 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
607 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
608 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
609 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
610 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
611 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
612 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
613 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
614 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
615 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
616 case L_('~'):
617 /* The C Standard requires these 98 characters (plus '%') to
618 be in the basic execution character set. None of these
619 characters can start a multibyte sequence, so they need
620 not be analyzed further. */
621 add (1, *p = *f);
622 continue;
624 default:
625 /* Copy this multibyte sequence until we reach its end, find
626 an error, or come back to the initial shift state. */
628 mbstate_t mbstate = mbstate_zero;
629 size_t len = 0;
630 size_t fsize;
632 if (! format_end)
633 format_end = f + strlen (f) + 1;
634 fsize = format_end - f;
638 size_t bytes = mbrlen (f + len, fsize - len, &mbstate);
640 if (bytes == 0)
641 break;
643 if (bytes == (size_t) -2)
645 len += strlen (f + len);
646 break;
649 if (bytes == (size_t) -1)
651 len++;
652 break;
655 len += bytes;
657 while (! mbsinit (&mbstate));
659 cpy (len, f);
660 f += len - 1;
661 continue;
665 #else /* ! DO_MULTIBYTE */
667 /* Either multibyte encodings are not supported, they are
668 safe for formats, so any non-'%' byte can be copied through,
669 or this is the wide character version. */
670 if (*f != L_('%'))
672 add (1, *p = *f);
673 continue;
676 #endif /* ! DO_MULTIBYTE */
678 /* Check for flags that can modify a format. */
679 while (1)
681 switch (*++f)
683 /* This influences the number formats. */
684 case L_('_'):
685 case L_('-'):
686 case L_('0'):
687 pad = *f;
688 continue;
690 /* This changes textual output. */
691 case L_('^'):
692 to_uppcase = 1;
693 continue;
694 case L_('#'):
695 change_case = 1;
696 continue;
698 default:
699 break;
701 break;
704 /* As a GNU extension we allow to specify the field width. */
705 if (ISDIGIT (*f))
707 width = 0;
710 if (width > INT_MAX / 10
711 || (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10))
712 /* Avoid overflow. */
713 width = INT_MAX;
714 else
716 width *= 10;
717 width += *f - L_('0');
719 ++f;
721 while (ISDIGIT (*f));
724 /* Check for modifiers. */
725 switch (*f)
727 case L_('E'):
728 case L_('O'):
729 modifier = *f++;
730 break;
732 default:
733 modifier = 0;
734 break;
737 /* Now do the specified format. */
738 format_char = *f;
739 switch (format_char)
741 #define DO_NUMBER(d, v) \
742 digits = d > width ? d : width; \
743 number_value = v; goto do_number
744 #define DO_NUMBER_SPACEPAD(d, v) \
745 digits = d > width ? d : width; \
746 number_value = v; goto do_number_spacepad
748 case L_('%'):
749 if (modifier != 0)
750 goto bad_format;
751 add (1, *p = *f);
752 break;
754 case L_('a'):
755 if (modifier != 0)
756 goto bad_format;
757 if (change_case)
759 to_uppcase = 1;
760 to_lowcase = 0;
762 #if defined _NL_CURRENT || !HAVE_STRFTIME
763 cpy (aw_len, a_wkday);
764 break;
765 #else
766 goto underlying_strftime;
767 #endif
769 case 'A':
770 if (modifier != 0)
771 goto bad_format;
772 if (change_case)
774 to_uppcase = 1;
775 to_lowcase = 0;
777 #if defined _NL_CURRENT || !HAVE_STRFTIME
778 cpy (STRLEN (f_wkday), f_wkday);
779 break;
780 #else
781 goto underlying_strftime;
782 #endif
784 case L_('b'):
785 case L_('h'):
786 if (change_case)
788 to_uppcase = 1;
789 to_lowcase = 0;
791 if (modifier != 0)
792 goto bad_format;
793 #if defined _NL_CURRENT || !HAVE_STRFTIME
794 cpy (am_len, a_month);
795 break;
796 #else
797 goto underlying_strftime;
798 #endif
800 case L_('B'):
801 if (modifier != 0)
802 goto bad_format;
803 if (change_case)
805 to_uppcase = 1;
806 to_lowcase = 0;
808 #if defined _NL_CURRENT || !HAVE_STRFTIME
809 cpy (STRLEN (f_month), f_month);
810 break;
811 #else
812 goto underlying_strftime;
813 #endif
815 case L_('c'):
816 if (modifier == L_('O'))
817 goto bad_format;
818 #ifdef _NL_CURRENT
819 if (! (modifier == 'E'
820 && (*(subfmt =
821 (const CHAR_T *) _NL_CURRENT (LC_TIME,
822 NLW(ERA_D_T_FMT)))
823 != '\0')))
824 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
825 #else
826 # if HAVE_STRFTIME
827 goto underlying_strftime;
828 # else
829 subfmt = L_("%a %b %e %H:%M:%S %Y");
830 # endif
831 #endif
833 subformat:
835 CHAR_T *old_start = p;
836 size_t len = __strftime_internal (NULL, (size_t) -1, subfmt,
837 tp, tzset_called ut_argument
838 LOCALE_ARG);
839 add (len, __strftime_internal (p, maxsize - i, subfmt,
840 tp, tzset_called ut_argument
841 LOCALE_ARG));
843 if (to_uppcase)
844 while (old_start < p)
846 *old_start = TOUPPER ((UCHAR_T) *old_start, loc);
847 ++old_start;
850 break;
852 #if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
853 underlying_strftime:
855 /* The relevant information is available only via the
856 underlying strftime implementation, so use that. */
857 char ufmt[4];
858 char *u = ufmt;
859 char ubuf[1024]; /* enough for any single format in practice */
860 size_t len;
861 /* Make sure we're calling the actual underlying strftime.
862 In some cases, config.h contains something like
863 "#define strftime rpl_strftime". */
864 # ifdef strftime
865 # undef strftime
866 size_t strftime ();
867 # endif
869 *u++ = '%';
870 if (modifier != 0)
871 *u++ = modifier;
872 *u++ = format_char;
873 *u = '\0';
874 len = strftime (ubuf, sizeof ubuf, ufmt, tp);
875 if (len == 0 && ubuf[0] != '\0')
876 return 0;
877 cpy (len, ubuf);
879 break;
880 #endif
882 case L_('C'):
883 if (modifier == L_('E'))
885 #if HAVE_STRUCT_ERA_ENTRY
886 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
887 if (era)
889 # ifdef COMPILE_WIDE
890 size_t len = __wcslen (era->era_wname);
891 cpy (len, era->era_wname);
892 # else
893 size_t len = strlen (era->era_name);
894 cpy (len, era->era_name);
895 # endif
896 break;
898 #else
899 # if HAVE_STRFTIME
900 goto underlying_strftime;
901 # endif
902 #endif
906 int year = tp->tm_year + TM_YEAR_BASE;
907 DO_NUMBER (1, year / 100 - (year % 100 < 0));
910 case L_('x'):
911 if (modifier == L_('O'))
912 goto bad_format;
913 #ifdef _NL_CURRENT
914 if (! (modifier == L_('E')
915 && (*(subfmt =
916 (const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT)))
917 != L_('\0'))))
918 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
919 goto subformat;
920 #else
921 # if HAVE_STRFTIME
922 goto underlying_strftime;
923 # else
924 /* Fall through. */
925 # endif
926 #endif
927 case L_('D'):
928 if (modifier != 0)
929 goto bad_format;
930 subfmt = L_("%m/%d/%y");
931 goto subformat;
933 case L_('d'):
934 if (modifier == L_('E'))
935 goto bad_format;
937 DO_NUMBER (2, tp->tm_mday);
939 case L_('e'):
940 if (modifier == L_('E'))
941 goto bad_format;
943 DO_NUMBER_SPACEPAD (2, tp->tm_mday);
945 /* All numeric formats set DIGITS and NUMBER_VALUE and then
946 jump to one of these two labels. */
948 do_number_spacepad:
949 /* Force `_' flag unless overwritten by `0' or '-' flag. */
950 if (pad != L_('0') && pad != L_('-'))
951 pad = L_('_');
953 do_number:
954 /* Format the number according to the MODIFIER flag. */
956 if (modifier == L_('O') && 0 <= number_value)
958 #ifdef _NL_CURRENT
959 /* Get the locale specific alternate representation of
960 the number NUMBER_VALUE. If none exist NULL is returned. */
961 const CHAR_T *cp = nl_get_alt_digit (number_value
962 HELPER_LOCALE_ARG);
964 if (cp != NULL)
966 size_t digitlen = STRLEN (cp);
967 if (digitlen != 0)
969 cpy (digitlen, cp);
970 break;
973 #else
974 # if HAVE_STRFTIME
975 goto underlying_strftime;
976 # endif
977 #endif
980 unsigned int u = number_value;
982 bufp = buf + sizeof (buf) / sizeof (buf[0]);
983 negative_number = number_value < 0;
985 if (negative_number)
986 u = -u;
989 *--bufp = u % 10 + L_('0');
990 while ((u /= 10) != 0);
993 do_number_sign_and_padding:
994 if (negative_number)
995 *--bufp = L_('-');
997 if (pad != L_('-'))
999 int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
1000 - bufp);
1002 if (padding > 0)
1004 if (pad == L_('_'))
1006 if ((size_t) padding >= maxsize - i)
1007 return 0;
1009 if (p)
1010 memset_space (p, padding);
1011 i += padding;
1012 width = width > padding ? width - padding : 0;
1014 else
1016 if ((size_t) digits >= maxsize - i)
1017 return 0;
1019 if (negative_number)
1021 ++bufp;
1023 if (p)
1024 *p++ = L_('-');
1025 ++i;
1028 if (p)
1029 memset_zero (p, padding);
1030 i += padding;
1031 width = 0;
1036 cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
1037 break;
1039 case L_('F'):
1040 if (modifier != 0)
1041 goto bad_format;
1042 subfmt = L_("%Y-%m-%d");
1043 goto subformat;
1045 case L_('H'):
1046 if (modifier == L_('E'))
1047 goto bad_format;
1049 DO_NUMBER (2, tp->tm_hour);
1051 case L_('I'):
1052 if (modifier == L_('E'))
1053 goto bad_format;
1055 DO_NUMBER (2, hour12);
1057 case L_('k'): /* GNU extension. */
1058 if (modifier == L_('E'))
1059 goto bad_format;
1061 DO_NUMBER_SPACEPAD (2, tp->tm_hour);
1063 case L_('l'): /* GNU extension. */
1064 if (modifier == L_('E'))
1065 goto bad_format;
1067 DO_NUMBER_SPACEPAD (2, hour12);
1069 case L_('j'):
1070 if (modifier == L_('E'))
1071 goto bad_format;
1073 DO_NUMBER (3, 1 + tp->tm_yday);
1075 case L_('M'):
1076 if (modifier == L_('E'))
1077 goto bad_format;
1079 DO_NUMBER (2, tp->tm_min);
1081 case L_('m'):
1082 if (modifier == L_('E'))
1083 goto bad_format;
1085 DO_NUMBER (2, tp->tm_mon + 1);
1087 case L_('n'):
1088 add (1, *p = L_('\n'));
1089 break;
1091 case L_('P'):
1092 to_lowcase = 1;
1093 #if !defined _NL_CURRENT && HAVE_STRFTIME
1094 format_char = L_('p');
1095 #endif
1096 /* FALLTHROUGH */
1098 case L_('p'):
1099 if (change_case)
1101 to_uppcase = 0;
1102 to_lowcase = 1;
1104 #if defined _NL_CURRENT || !HAVE_STRFTIME
1105 cpy (ap_len, ampm);
1106 break;
1107 #else
1108 goto underlying_strftime;
1109 #endif
1111 case L_('R'):
1112 subfmt = L_("%H:%M");
1113 goto subformat;
1115 case L_('r'):
1116 #if !defined _NL_CURRENT && HAVE_STRFTIME
1117 goto underlying_strftime;
1118 #else
1119 # ifdef _NL_CURRENT
1120 if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME,
1121 NLW(T_FMT_AMPM)))
1122 == L_('\0'))
1123 # endif
1124 subfmt = L_("%I:%M:%S %p");
1125 goto subformat;
1126 #endif
1128 case L_('S'):
1129 if (modifier == L_('E'))
1130 goto bad_format;
1132 DO_NUMBER (2, tp->tm_sec);
1134 case L_('s'): /* GNU extension. */
1136 struct tm ltm;
1137 time_t t;
1139 ltm = *tp;
1140 t = mktime (&ltm);
1142 /* Generate string value for T using time_t arithmetic;
1143 this works even if sizeof (long) < sizeof (time_t). */
1145 bufp = buf + sizeof (buf) / sizeof (buf[0]);
1146 negative_number = t < 0;
1150 int d = t % 10;
1151 t /= 10;
1153 if (negative_number)
1155 d = -d;
1157 /* Adjust if division truncates to minus infinity. */
1158 if (0 < -1 % 10 && d < 0)
1160 t++;
1161 d += 10;
1165 *--bufp = d + L_('0');
1167 while (t != 0);
1169 digits = 1;
1170 goto do_number_sign_and_padding;
1173 case L_('X'):
1174 if (modifier == L_('O'))
1175 goto bad_format;
1176 #ifdef _NL_CURRENT
1177 if (! (modifier == L_('E')
1178 && (*(subfmt =
1179 (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT)))
1180 != L_('\0'))))
1181 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
1182 goto subformat;
1183 #else
1184 # if HAVE_STRFTIME
1185 goto underlying_strftime;
1186 # else
1187 /* Fall through. */
1188 # endif
1189 #endif
1190 case L_('T'):
1191 subfmt = L_("%H:%M:%S");
1192 goto subformat;
1194 case L_('t'):
1195 add (1, *p = L_('\t'));
1196 break;
1198 case L_('u'):
1199 DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
1201 case L_('U'):
1202 if (modifier == L_('E'))
1203 goto bad_format;
1205 DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
1207 case L_('V'):
1208 case L_('g'):
1209 case L_('G'):
1210 if (modifier == L_('E'))
1211 goto bad_format;
1213 int year = tp->tm_year + TM_YEAR_BASE;
1214 int days = iso_week_days (tp->tm_yday, tp->tm_wday);
1216 if (days < 0)
1218 /* This ISO week belongs to the previous year. */
1219 year--;
1220 days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
1221 tp->tm_wday);
1223 else
1225 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
1226 tp->tm_wday);
1227 if (0 <= d)
1229 /* This ISO week belongs to the next year. */
1230 year++;
1231 days = d;
1235 switch (*f)
1237 case L_('g'):
1238 DO_NUMBER (2, (year % 100 + 100) % 100);
1240 case L_('G'):
1241 DO_NUMBER (1, year);
1243 default:
1244 DO_NUMBER (2, days / 7 + 1);
1248 case L_('W'):
1249 if (modifier == L_('E'))
1250 goto bad_format;
1252 DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
1254 case L_('w'):
1255 if (modifier == L_('E'))
1256 goto bad_format;
1258 DO_NUMBER (1, tp->tm_wday);
1260 case L_('Y'):
1261 if (modifier == 'E')
1263 #if HAVE_STRUCT_ERA_ENTRY
1264 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1265 if (era)
1267 # ifdef COMPILE_WIDE
1268 subfmt = era->era_wformat;
1269 # else
1270 subfmt = era->era_format;
1271 # endif
1272 goto subformat;
1274 #else
1275 # if HAVE_STRFTIME
1276 goto underlying_strftime;
1277 # endif
1278 #endif
1280 if (modifier == L_('O'))
1281 goto bad_format;
1282 else
1283 DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
1285 case L_('y'):
1286 if (modifier == L_('E'))
1288 #if HAVE_STRUCT_ERA_ENTRY
1289 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1290 if (era)
1292 int delta = tp->tm_year - era->start_date[0];
1293 DO_NUMBER (1, (era->offset
1294 + delta * era->absolute_direction));
1296 #else
1297 # if HAVE_STRFTIME
1298 goto underlying_strftime;
1299 # endif
1300 #endif
1302 DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
1304 case L_('Z'):
1305 if (change_case)
1307 to_uppcase = 0;
1308 to_lowcase = 1;
1311 #if HAVE_TZNAME
1312 /* The tzset() call might have changed the value. */
1313 if (!(zone && *zone) && tp->tm_isdst >= 0)
1315 /* POSIX.1 requires that local time zone information is used as
1316 though strftime called tzset. */
1317 # if HAVE_TZSET
1318 if (!*tzset_called)
1320 tzset ();
1321 *tzset_called = true;
1323 # endif
1324 zone = tzname[tp->tm_isdst];
1326 #endif
1327 if (! zone)
1328 zone = "";
1330 #ifdef COMPILE_WIDE
1332 /* The zone string is always given in multibyte form. We have
1333 to transform it first. */
1334 wchar_t *wczone;
1335 size_t len;
1336 widen (zone, wczone, len);
1337 cpy (len, wczone);
1339 #else
1340 cpy (strlen (zone), zone);
1341 #endif
1342 break;
1344 case L_('z'):
1345 if (tp->tm_isdst < 0)
1346 break;
1349 int diff;
1350 #if HAVE_TM_GMTOFF
1351 diff = tp->tm_gmtoff;
1352 #else
1353 if (ut)
1354 diff = 0;
1355 else
1357 struct tm gtm;
1358 struct tm ltm;
1359 time_t lt;
1361 /* POSIX.1 requires that local time zone information is used as
1362 though strftime called tzset. */
1363 # if HAVE_TZSET
1364 if (!*tzset_called)
1366 tzset ();
1367 *tzset_called = true;
1369 # endif
1371 ltm = *tp;
1372 lt = mktime (&ltm);
1374 if (lt == (time_t) -1)
1376 /* mktime returns -1 for errors, but -1 is also a
1377 valid time_t value. Check whether an error really
1378 occurred. */
1379 struct tm tm;
1381 if (! __localtime_r (&lt, &tm)
1382 || ((ltm.tm_sec ^ tm.tm_sec)
1383 | (ltm.tm_min ^ tm.tm_min)
1384 | (ltm.tm_hour ^ tm.tm_hour)
1385 | (ltm.tm_mday ^ tm.tm_mday)
1386 | (ltm.tm_mon ^ tm.tm_mon)
1387 | (ltm.tm_year ^ tm.tm_year)))
1388 break;
1391 if (! __gmtime_r (&lt, &gtm))
1392 break;
1394 diff = tm_diff (&ltm, &gtm);
1396 #endif
1398 if (diff < 0)
1400 add (1, *p = L_('-'));
1401 diff = -diff;
1403 else
1404 add (1, *p = L_('+'));
1406 diff /= 60;
1407 DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
1410 case L_('\0'): /* GNU extension: % at end of format. */
1411 --f;
1412 /* Fall through. */
1413 default:
1414 /* Unknown format; output the format, including the '%',
1415 since this is most likely the right thing to do if a
1416 multibyte string has been misparsed. */
1417 bad_format:
1419 int flen;
1420 for (flen = 1; f[1 - flen] != L_('%'); flen++)
1421 continue;
1422 cpy (flen, &f[1 - flen]);
1424 break;
1428 if (p && maxsize != 0)
1429 *p = L_('\0');
1430 return i;
1434 #ifdef emacs
1435 /* For Emacs we have a separate interface which corresponds to the normal
1436 strftime function and does not have the extra information whether the
1437 TP arguments comes from a `gmtime' call or not. */
1438 size_t
1439 emacs_strftime (s, maxsize, format, tp)
1440 char *s;
1441 size_t maxsize;
1442 const char *format;
1443 const struct tm *tp;
1445 return my_strftime (s, maxsize, format, tp, 0);
1447 #endif
1449 #if defined _LIBC && !defined COMPILE_WIDE
1450 weak_alias (__strftime_l, strftime_l)
1451 #endif