* fontset.c (free_realized_fontset): Mark unreachable code with if (0).
[emacs.git] / src / strftime.c
blob5a0923e372334403848027b0940039391319ac48
1 /* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2 2001, 2002, 2003, 2004, 2005, 2006, 2007
3 Free Software Foundation, Inc.
5 NOTE: The canonical source of this file is maintained with gnulib.
6 Bugs can be reported to bug-gnulib@gnu.org.
8 This file is part of the GNU Emacs.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation; either version 2, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public
21 License along with the GNU C Library; see the file COPYING. If not,
22 write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 Boston, MA 02110-1301, USA. */
25 #ifdef HAVE_CONFIG_H
26 # include <config.h>
27 #endif
29 #ifdef _LIBC
30 # define HAVE_LIMITS_H 1
31 # define HAVE_MBLEN 1
32 # define HAVE_MBRLEN 1
33 # define HAVE_STRUCT_ERA_ENTRY 1
34 # define HAVE_TM_GMTOFF 1
35 # define HAVE_TM_ZONE 1
36 # define HAVE_TZNAME 1
37 # define HAVE_TZSET 1
38 # define MULTIBYTE_IS_FORMAT_SAFE 1
39 # define STDC_HEADERS 1
40 # include "../locale/localeinfo.h"
41 #endif
43 #include <ctype.h>
44 #include <sys/types.h> /* Some systems define `time_t' here. */
46 #ifdef TIME_WITH_SYS_TIME
47 # include <sys/time.h>
48 # include <time.h>
49 #else
50 # ifdef HAVE_SYS_TIME_H
51 # include <sys/time.h>
52 # else
53 # include <time.h>
54 # endif
55 #endif
56 #if HAVE_TZNAME
57 #ifndef USE_CRT_DLL
58 extern char *tzname[];
59 #endif
60 #endif
62 /* Do multibyte processing if multibytes are supported, unless
63 multibyte sequences are safe in formats. Multibyte sequences are
64 safe if they cannot contain byte sequences that look like format
65 conversion specifications. The GNU C Library uses UTF8 multibyte
66 encoding, which is safe for formats, but strftime.c can be used
67 with other C libraries that use unsafe encodings. */
68 #define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
70 #if DO_MULTIBYTE
71 # if HAVE_MBRLEN
72 # include <wchar.h>
73 # ifdef HAVE_SYS__MBSTATE_T_H /* previously tested __hpux */
74 # include <sys/_mbstate_t.h>
75 # endif
76 # if !defined (mbsinit) && !defined (HAVE_MBSINIT)
77 # define mbsinit(ps) 1
78 # endif /* !defined (mbsinit) && !defined (HAVE_MBSINIT) */
79 # else
80 /* Simulate mbrlen with mblen as best we can. */
81 # define mbstate_t int
82 # define mbrlen(s, n, ps) mblen (s, n)
83 # define mbsinit(ps) (*(ps) == 0)
84 # endif
85 static const mbstate_t mbstate_zero;
86 #endif
88 #ifdef HAVE_LIMITS_H
89 # include <limits.h>
90 #endif
92 #ifdef STDC_HEADERS
93 # include <stddef.h>
94 # include <stdlib.h>
95 # include <string.h>
96 #else
97 # ifndef HAVE_MEMCPY
98 # define memcpy(d, s, n) bcopy ((s), (d), (n))
99 # endif
100 #endif
102 #ifdef COMPILE_WIDE
103 # include <endian.h>
104 # define CHAR_T wchar_t
105 # define UCHAR_T unsigned int
106 # define L_(Str) L##Str
107 # define NLW(Sym) _NL_W##Sym
109 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
110 # define STRLEN(s) __wcslen (s)
112 #else
113 # define CHAR_T char
114 # define UCHAR_T unsigned char
115 # define L_(Str) Str
116 # define NLW(Sym) Sym
118 # if !defined STDC_HEADERS && !defined HAVE_MEMCPY
119 # define MEMCPY(d, s, n) bcopy ((s), (d), (n))
120 # else
121 # define MEMCPY(d, s, n) memcpy ((d), (s), (n))
122 # endif
123 # define STRLEN(s) strlen (s)
125 # ifdef _LIBC
126 # define MEMPCPY(d, s, n) __mempcpy (d, s, n)
127 # else
128 # ifndef HAVE_MEMPCPY
129 # define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n)))
130 # endif
131 # endif
132 #endif
134 #ifndef PTR
135 # ifdef __STDC__
136 # define PTR void *
137 # else
138 # define PTR char *
139 # endif
140 #endif
142 #ifndef CHAR_BIT
143 # define CHAR_BIT 8
144 #endif
146 #ifndef NULL
147 # define NULL 0
148 #endif
150 #define TYPE_SIGNED(t) ((t) -1 < 0)
152 /* Bound on length of the string representing an integer value of type t.
153 Subtract one for the sign bit if t is signed;
154 302 / 1000 is log10 (2) rounded up;
155 add one for integer division truncation;
156 add one more for a minus sign if t is signed. */
157 #define INT_STRLEN_BOUND(t) \
158 ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 + 1 + TYPE_SIGNED (t))
160 #define TM_YEAR_BASE 1900
162 #ifndef __isleap
163 /* Nonzero if YEAR is a leap year (every 4 years,
164 except every 100th isn't, and every 400th is). */
165 # define __isleap(year) \
166 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
167 #endif
170 #ifdef _LIBC
171 # define my_strftime_gmtime_r __gmtime_r
172 # define my_strftime_localtime_r __localtime_r
173 # define tzname __tzname
174 # define tzset __tzset
175 #else
177 /* If we're a strftime substitute in a GNU program, then prefer gmtime
178 to gmtime_r, since many gmtime_r implementations are buggy.
179 Similarly for localtime_r. */
181 # if ! HAVE_TM_GMTOFF
182 static struct tm *
183 my_strftime_gmtime_r (const time_t *t, struct tm *tp)
185 struct tm *l = gmtime (t);
186 if (! l)
187 return 0;
188 *tp = *l;
189 return tp;
192 static struct tm *
193 my_strftime_localtime_r (const time_t *t, struct tm *tp)
195 struct tm *l = localtime (t);
196 if (! l)
197 return 0;
198 *tp = *l;
199 return tp;
201 # endif /* ! HAVE_TM_GMTOFF */
202 #endif /* ! defined _LIBC */
205 #if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
206 /* Some systems lack the `memset' function and we don't want to
207 introduce additional dependencies. */
208 /* The SGI compiler reportedly barfs on the trailing null
209 if we use a string constant as the initializer. 28 June 1997, rms. */
210 static const CHAR_T spaces[16] = /* " " */
212 L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),
213 L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' ')
215 static const CHAR_T zeroes[16] = /* "0000000000000000" */
217 L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),
218 L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0')
221 # define memset_space(P, Len) \
222 do { \
223 int _len = (Len); \
225 do \
227 int _this = _len > 16 ? 16 : _len; \
228 (P) = MEMPCPY ((P), spaces, _this * sizeof (CHAR_T)); \
229 _len -= _this; \
231 while (_len > 0); \
232 } while (0)
234 # define memset_zero(P, Len) \
235 do { \
236 int _len = (Len); \
238 do \
240 int _this = _len > 16 ? 16 : _len; \
241 (P) = MEMPCPY ((P), zeroes, _this * sizeof (CHAR_T)); \
242 _len -= _this; \
244 while (_len > 0); \
245 } while (0)
246 #else
247 # ifdef COMPILE_WIDE
248 # define memset_space(P, Len) (wmemset ((P), L' ', (Len)), (P) += (Len))
249 # define memset_zero(P, Len) (wmemset ((P), L'0', (Len)), (P) += (Len))
250 # else
251 # define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
252 # define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
253 # endif
254 #endif
256 #define add(n, f) \
257 do \
259 int _n = (n); \
260 int _delta = width - _n; \
261 int _incr = _n + (_delta > 0 ? _delta : 0); \
262 if ((size_t) _incr >= maxsize - i) \
263 return 0; \
264 if (p) \
266 if (_delta > 0) \
268 if (pad == L_('0')) \
269 memset_zero (p, _delta); \
270 else \
271 memset_space (p, _delta); \
273 f; \
274 p += _n; \
276 i += _incr; \
277 } while (0)
279 #define cpy(n, s) \
280 add ((n), \
281 if (to_lowcase) \
282 memcpy_lowcase (p, (s), _n LOCALE_ARG); \
283 else if (to_uppcase) \
284 memcpy_uppcase (p, (s), _n LOCALE_ARG); \
285 else \
286 MEMCPY ((PTR) p, (const PTR) (s), _n))
288 #ifdef COMPILE_WIDE
289 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
290 # undef __mbsrtowcs_l
291 # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
292 # endif
293 # define widen(os, ws, l) \
295 mbstate_t __st; \
296 const char *__s = os; \
297 memset (&__st, '\0', sizeof (__st)); \
298 l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
299 ws = (wchar_t *) alloca ((l + 1) * sizeof (wchar_t)); \
300 (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
302 #endif
305 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
306 /* We use this code also for the extended locale handling where the
307 function gets as an additional argument the locale which has to be
308 used. To access the values we have to redefine the _NL_CURRENT
309 macro. */
310 # define strftime __strftime_l
311 # define wcsftime __wcsftime_l
312 # undef _NL_CURRENT
313 # define _NL_CURRENT(category, item) \
314 (current->values[_NL_ITEM_INDEX (item)].string)
315 # define LOCALE_ARG , loc
316 # define LOCALE_PARAM_DECL , __locale_t loc
317 # define HELPER_LOCALE_ARG , current
318 #else
319 # define LOCALE_ARG
320 # define LOCALE_PARAM_DECL
321 # ifdef _LIBC
322 # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
323 # else
324 # define HELPER_LOCALE_ARG
325 # endif
326 #endif
328 #ifdef COMPILE_WIDE
329 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
330 # define TOUPPER(Ch, L) __towupper_l (Ch, L)
331 # define TOLOWER(Ch, L) __towlower_l (Ch, L)
332 # else
333 # define TOUPPER(Ch, L) towupper (Ch)
334 # define TOLOWER(Ch, L) towlower (Ch)
335 # endif
336 #else
337 # ifdef _LIBC
338 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
339 # define TOUPPER(Ch, L) __toupper_l (Ch, L)
340 # define TOLOWER(Ch, L) __tolower_l (Ch, L)
341 # else
342 # define TOUPPER(Ch, L) toupper (Ch)
343 # define TOLOWER(Ch, L) tolower (Ch)
344 # endif
345 # else
346 # define TOUPPER(Ch, L) (islower (Ch) ? toupper (Ch) : (Ch))
347 # define TOLOWER(Ch, L) (isupper (Ch) ? tolower (Ch) : (Ch))
348 # endif
349 #endif
350 /* We don't use `isdigit' here since the locale dependent
351 interpretation is not what we want here. We only need to accept
352 the arabic digits in the ASCII range. One day there is perhaps a
353 more reliable way to accept other sets of digits. */
354 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
356 static CHAR_T *
357 memcpy_lowcase (CHAR_T *dest, const CHAR_T *src, size_t len LOCALE_PARAM_DECL)
359 while (len-- > 0)
360 dest[len] = TOLOWER ((UCHAR_T) src[len], loc);
361 return dest;
364 static CHAR_T *
365 memcpy_uppcase (CHAR_T *dest, const CHAR_T *src, size_t len LOCALE_PARAM_DECL)
367 while (len-- > 0)
368 dest[len] = TOUPPER ((UCHAR_T) src[len], loc);
369 return dest;
373 #if ! HAVE_TM_GMTOFF
374 /* Yield the difference between *A and *B,
375 measured in seconds, ignoring leap seconds. */
376 # define tm_diff ftime_tm_diff
377 static int
378 tm_diff (const struct tm *a, const struct tm *b)
380 /* Compute intervening leap days correctly even if year is negative.
381 Take care to avoid int overflow in leap day calculations,
382 but it's OK to assume that A and B are close to each other. */
383 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
384 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
385 int a100 = a4 / 25 - (a4 % 25 < 0);
386 int b100 = b4 / 25 - (b4 % 25 < 0);
387 int a400 = a100 >> 2;
388 int b400 = b100 >> 2;
389 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
390 int years = a->tm_year - b->tm_year;
391 int days = (365 * years + intervening_leap_days
392 + (a->tm_yday - b->tm_yday));
393 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
394 + (a->tm_min - b->tm_min))
395 + (a->tm_sec - b->tm_sec));
397 #endif /* ! HAVE_TM_GMTOFF */
401 /* The number of days from the first day of the first ISO week of this
402 year to the year day YDAY with week day WDAY. ISO weeks start on
403 Monday; the first ISO week has the year's first Thursday. YDAY may
404 be as small as YDAY_MINIMUM. */
405 #define ISO_WEEK_START_WDAY 1 /* Monday */
406 #define ISO_WEEK1_WDAY 4 /* Thursday */
407 #define YDAY_MINIMUM (-366)
408 static int iso_week_days (int, int);
409 #ifdef __GNUC__
410 __inline__
411 #endif
412 static int
413 iso_week_days (int yday, int wday)
415 /* Add enough to the first operand of % to make it nonnegative. */
416 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
417 return (yday
418 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
419 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
423 #if !(defined _NL_CURRENT || HAVE_STRFTIME)
424 static CHAR_T const weekday_name[][10] =
426 L_("Sunday"), L_("Monday"), L_("Tuesday"), L_("Wednesday"),
427 L_("Thursday"), L_("Friday"), L_("Saturday")
429 static CHAR_T const month_name[][10] =
431 L_("January"), L_("February"), L_("March"), L_("April"), L_("May"),
432 L_("June"), L_("July"), L_("August"), L_("September"), L_("October"),
433 L_("November"), L_("December")
435 #endif
438 /* When compiling this file, GNU applications can #define my_strftime
439 to a symbol (typically nstrftime) to get an extended strftime with
440 extra arguments UT and NS. */
442 #ifdef my_strftime
443 # define extra_args , ut, ns
444 # define extra_args_spec , int ut, int ns
445 #else
446 # ifdef COMPILE_WIDE
447 # define my_strftime wcsftime
448 # define nl_get_alt_digit _nl_get_walt_digit
449 # else
450 # define my_strftime strftime
451 # define nl_get_alt_digit _nl_get_alt_digit
452 # endif
453 # define extra_args
454 # define extra_args_spec
455 /* We don't have this information in general. */
456 # define ut 0
457 # define ns 0
458 #endif
460 #if !defined _LIBC && !defined(WINDOWSNT) && HAVE_TZNAME && HAVE_TZSET
461 /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
462 Work around this bug by copying *tp before it might be munged. */
463 size_t
464 _strftime_copytm (CHAR_T *s, size_t maxsize, const CHAR_T *format,
465 const struct tm *tp extra_args_spec LOCALE_PARAM_DECL);
466 size_t
467 my_strftime (CHAR_T *s, size_t maxsize, const CHAR_T *format,
468 const struct tm *tp extra_args_spec)
470 struct tm tmcopy;
471 tmcopy = *tp;
472 return _strftime_copytm (s, maxsize, format, &tmcopy extra_args);
474 # undef my_strftime
475 # define my_strftime _strftime_copytm
476 #endif
479 /* Write information from TP into S according to the format
480 string FORMAT, writing no more that MAXSIZE characters
481 (including the terminating '\0') and returning number of
482 characters written. If S is NULL, nothing will be written
483 anywhere, so to determine how many characters would be
484 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
485 size_t
486 my_strftime (CHAR_T *s, size_t maxsize, const CHAR_T *format,
487 const struct tm *tp extra_args_spec LOCALE_PARAM_DECL)
489 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
490 struct locale_data *const current = loc->__locales[LC_TIME];
491 #endif
493 int hour12 = tp->tm_hour;
494 #ifdef _NL_CURRENT
495 /* We cannot make the following values variables since we must delay
496 the evaluation of these values until really needed since some
497 expressions might not be valid in every situation. The `struct tm'
498 might be generated by a strptime() call that initialized
499 only a few elements. Dereference the pointers only if the format
500 requires this. Then it is ok to fail if the pointers are invalid. */
501 # define a_wkday \
502 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
503 # define f_wkday \
504 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
505 # define a_month \
506 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
507 # define f_month \
508 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
509 # define ampm \
510 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
511 ? NLW(PM_STR) : NLW(AM_STR)))
513 # define aw_len STRLEN (a_wkday)
514 # define am_len STRLEN (a_month)
515 # define ap_len STRLEN (ampm)
516 #else
517 # if !HAVE_STRFTIME
518 # define f_wkday (weekday_name[tp->tm_wday])
519 # define f_month (month_name[tp->tm_mon])
520 # define a_wkday f_wkday
521 # define a_month f_month
522 # define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
524 size_t aw_len = 3;
525 size_t am_len = 3;
526 size_t ap_len = 2;
527 # endif
528 #endif
529 const char *zone;
530 size_t i = 0;
531 CHAR_T *p = s;
532 const CHAR_T *f;
533 #if DO_MULTIBYTE && !defined COMPILE_WIDE
534 const char *format_end = NULL;
535 #endif
537 zone = NULL;
538 #if HAVE_TM_ZONE
539 /* The POSIX test suite assumes that setting
540 the environment variable TZ to a new value before calling strftime()
541 will influence the result (the %Z format) even if the information in
542 TP is computed with a totally different time zone.
543 This is bogus: though POSIX allows bad behavior like this,
544 POSIX does not require it. Do the right thing instead. */
545 zone = (const char *) tp->tm_zone;
546 #endif
547 #if HAVE_TZNAME
548 if (ut)
550 if (! (zone && *zone))
551 zone = "GMT";
553 else
555 /* POSIX.1 requires that local time zone information be used as
556 though strftime called tzset. */
557 # if HAVE_TZSET
558 tzset ();
559 # endif
561 #endif
563 if (hour12 > 12)
564 hour12 -= 12;
565 else
566 if (hour12 == 0)
567 hour12 = 12;
569 for (f = format; *f != '\0'; ++f)
571 int pad = 0; /* Padding for number ('-', '_', or 0). */
572 int modifier; /* Field modifier ('E', 'O', or 0). */
573 int digits; /* Max digits for numeric format. */
574 int number_value; /* Numeric value to be printed. */
575 int negative_number; /* 1 if the number is negative. */
576 const CHAR_T *subfmt;
577 CHAR_T *bufp;
578 CHAR_T buf[1 + (sizeof (int) < sizeof (time_t)
579 ? INT_STRLEN_BOUND (time_t)
580 : INT_STRLEN_BOUND (int))];
581 int width = -1;
582 int to_lowcase = 0;
583 int to_uppcase = 0;
584 int change_case = 0;
585 int format_char;
587 #if DO_MULTIBYTE && !defined COMPILE_WIDE
588 switch (*f)
590 case L_('%'):
591 break;
593 case L_('\b'): case L_('\t'): case L_('\n'):
594 case L_('\v'): case L_('\f'): case L_('\r'):
595 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
596 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
597 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
598 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
599 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
600 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
601 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
602 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
603 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
604 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
605 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
606 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
607 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
608 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
609 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
610 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
611 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
612 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
613 case L_('~'):
614 /* The C Standard requires these 98 characters (plus '%') to
615 be in the basic execution character set. None of these
616 characters can start a multibyte sequence, so they need
617 not be analyzed further. */
618 add (1, *p = *f);
619 continue;
621 default:
622 /* Copy this multibyte sequence until we reach its end, find
623 an error, or come back to the initial shift state. */
625 mbstate_t mbstate = mbstate_zero;
626 size_t len = 0;
627 size_t fsize;
629 if (! format_end)
630 format_end = f + strlen (f) + 1;
631 fsize = format_end - f;
635 size_t bytes = mbrlen (f + len, fsize - len, &mbstate);
637 if (bytes == 0)
638 break;
640 if (bytes == (size_t) -2)
642 len += strlen (f + len);
643 break;
646 if (bytes == (size_t) -1)
648 len++;
649 break;
652 len += bytes;
654 while (! mbsinit (&mbstate));
656 cpy (len, f);
657 f += len - 1;
658 continue;
662 #else /* ! DO_MULTIBYTE */
664 /* Either multibyte encodings are not supported, they are
665 safe for formats, so any non-'%' byte can be copied through,
666 or this is the wide character version. */
667 if (*f != L_('%'))
669 add (1, *p = *f);
670 continue;
673 #endif /* ! DO_MULTIBYTE */
675 /* Check for flags that can modify a format. */
676 while (1)
678 switch (*++f)
680 /* This influences the number formats. */
681 case L_('_'):
682 case L_('-'):
683 case L_('0'):
684 pad = *f;
685 continue;
687 /* This changes textual output. */
688 case L_('^'):
689 to_uppcase = 1;
690 continue;
691 case L_('#'):
692 change_case = 1;
693 continue;
695 default:
696 break;
698 break;
701 /* As a GNU extension we allow to specify the field width. */
702 if (ISDIGIT (*f))
704 width = 0;
707 if (width > INT_MAX / 10
708 || (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10))
709 /* Avoid overflow. */
710 width = INT_MAX;
711 else
713 width *= 10;
714 width += *f - L_('0');
716 ++f;
718 while (ISDIGIT (*f));
721 /* Check for modifiers. */
722 switch (*f)
724 case L_('E'):
725 case L_('O'):
726 modifier = *f++;
727 break;
729 default:
730 modifier = 0;
731 break;
734 /* Now do the specified format. */
735 format_char = *f;
736 switch (format_char)
738 #define DO_NUMBER(d, v) \
739 digits = d > width ? d : width; \
740 number_value = v; goto do_number
741 #define DO_NUMBER_SPACEPAD(d, v) \
742 digits = d > width ? d : width; \
743 number_value = v; goto do_number_spacepad
745 case L_('%'):
746 if (modifier != 0)
747 goto bad_format;
748 add (1, *p = *f);
749 break;
751 case L_('a'):
752 if (modifier != 0)
753 goto bad_format;
754 if (change_case)
756 to_uppcase = 1;
757 to_lowcase = 0;
759 #if defined _NL_CURRENT || !HAVE_STRFTIME
760 cpy (aw_len, a_wkday);
761 break;
762 #else
763 goto underlying_strftime;
764 #endif
766 case 'A':
767 if (modifier != 0)
768 goto bad_format;
769 if (change_case)
771 to_uppcase = 1;
772 to_lowcase = 0;
774 #if defined _NL_CURRENT || !HAVE_STRFTIME
775 cpy (STRLEN (f_wkday), f_wkday);
776 break;
777 #else
778 goto underlying_strftime;
779 #endif
781 case L_('b'):
782 case L_('h'):
783 if (change_case)
785 to_uppcase = 1;
786 to_lowcase = 0;
788 if (modifier != 0)
789 goto bad_format;
790 #if defined _NL_CURRENT || !HAVE_STRFTIME
791 cpy (am_len, a_month);
792 break;
793 #else
794 goto underlying_strftime;
795 #endif
797 case L_('B'):
798 if (modifier != 0)
799 goto bad_format;
800 if (change_case)
802 to_uppcase = 1;
803 to_lowcase = 0;
805 #if defined _NL_CURRENT || !HAVE_STRFTIME
806 cpy (STRLEN (f_month), f_month);
807 break;
808 #else
809 goto underlying_strftime;
810 #endif
812 case L_('c'):
813 if (modifier == L_('O'))
814 goto bad_format;
815 #ifdef _NL_CURRENT
816 if (! (modifier == 'E'
817 && (*(subfmt =
818 (const CHAR_T *) _NL_CURRENT (LC_TIME,
819 NLW(ERA_D_T_FMT)))
820 != '\0')))
821 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
822 #else
823 # if HAVE_STRFTIME
824 goto underlying_strftime;
825 # else
826 subfmt = L_("%a %b %e %H:%M:%S %Y");
827 # endif
828 #endif
830 subformat:
832 CHAR_T *old_start = p;
833 size_t len = my_strftime (NULL, (size_t) -1, subfmt,
834 tp extra_args LOCALE_ARG);
835 add (len, my_strftime (p, maxsize - i, subfmt,
836 tp extra_args LOCALE_ARG));
838 if (to_uppcase)
839 while (old_start < p)
841 *old_start = TOUPPER ((UCHAR_T) *old_start, loc);
842 ++old_start;
845 break;
847 #if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
848 underlying_strftime:
850 /* The relevant information is available only via the
851 underlying strftime implementation, so use that. */
852 char ufmt[4];
853 char *u = ufmt;
854 char ubuf[1024]; /* enough for any single format in practice */
855 size_t len;
856 /* Make sure we're calling the actual underlying strftime.
857 In some cases, config.h contains something like
858 "#define strftime rpl_strftime". */
859 # ifdef strftime
860 # undef strftime
861 size_t strftime ();
862 # endif
864 #ifdef STRFTIME_NO_POSIX2
865 /* Some system libraries do not support the POSIX.2 extensions.
866 In those cases, convert %h to %b, and strip modifiers. */
867 modifier = 0;
868 if (format_char == 'h')
869 format_char = 'b';
870 #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_('O'))
886 goto bad_format;
887 if (modifier == L_('E'))
889 #if HAVE_STRUCT_ERA_ENTRY
890 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
891 if (era)
893 # ifdef COMPILE_WIDE
894 size_t len = __wcslen (era->era_wname);
895 cpy (len, era->era_wname);
896 # else
897 size_t len = strlen (era->era_name);
898 cpy (len, era->era_name);
899 # endif
900 break;
902 #else
903 # if HAVE_STRFTIME
904 goto underlying_strftime;
905 # endif
906 #endif
910 int year = tp->tm_year + TM_YEAR_BASE;
911 DO_NUMBER (1, year / 100 - (year % 100 < 0));
914 case L_('x'):
915 if (modifier == L_('O'))
916 goto bad_format;
917 #ifdef _NL_CURRENT
918 if (! (modifier == L_('E')
919 && (*(subfmt =
920 (const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT)))
921 != L_('\0'))))
922 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
923 goto subformat;
924 #else
925 # if HAVE_STRFTIME
926 goto underlying_strftime;
927 # else
928 /* Fall through. */
929 # endif
930 #endif
931 case L_('D'):
932 if (modifier != 0)
933 goto bad_format;
934 subfmt = L_("%m/%d/%y");
935 goto subformat;
937 case L_('d'):
938 if (modifier == L_('E'))
939 goto bad_format;
941 DO_NUMBER (2, tp->tm_mday);
943 case L_('e'):
944 if (modifier == L_('E'))
945 goto bad_format;
947 DO_NUMBER_SPACEPAD (2, tp->tm_mday);
949 /* All numeric formats set DIGITS and NUMBER_VALUE and then
950 jump to one of these two labels. */
952 do_number_spacepad:
953 /* Force `_' flag unless overridden by `0' or `-' flag. */
954 if (pad != L_('0') && pad != L_('-'))
955 pad = L_('_');
957 do_number:
958 /* Format the number according to the MODIFIER flag. */
960 if (modifier == L_('O') && 0 <= number_value)
962 #ifdef _NL_CURRENT
963 /* Get the locale specific alternate representation of
964 the number NUMBER_VALUE. If none exist NULL is returned. */
965 const CHAR_T *cp = nl_get_alt_digit (number_value
966 HELPER_LOCALE_ARG);
968 if (cp != NULL)
970 size_t digitlen = STRLEN (cp);
971 if (digitlen != 0)
973 cpy (digitlen, cp);
974 break;
977 #else
978 # if HAVE_STRFTIME
979 goto underlying_strftime;
980 # endif
981 #endif
984 unsigned int u = number_value;
986 bufp = buf + sizeof (buf) / sizeof (buf[0]);
987 negative_number = number_value < 0;
989 if (negative_number)
990 u = -u;
993 *--bufp = u % 10 + L_('0');
994 while ((u /= 10) != 0);
997 do_number_sign_and_padding:
998 if (negative_number)
999 *--bufp = L_('-');
1001 if (pad != L_('-'))
1003 int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
1004 - bufp);
1006 if (padding > 0)
1008 if (pad == L_('_'))
1010 if ((size_t) padding >= maxsize - i)
1011 return 0;
1013 if (p)
1014 memset_space (p, padding);
1015 i += padding;
1016 width = width > padding ? width - padding : 0;
1018 else
1020 if ((size_t) digits >= maxsize - i)
1021 return 0;
1023 if (negative_number)
1025 ++bufp;
1027 if (p)
1028 *p++ = L_('-');
1029 ++i;
1032 if (p)
1033 memset_zero (p, padding);
1034 i += padding;
1035 width = 0;
1040 cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
1041 break;
1043 case L_('F'):
1044 if (modifier != 0)
1045 goto bad_format;
1046 subfmt = L_("%Y-%m-%d");
1047 goto subformat;
1049 case L_('H'):
1050 if (modifier == L_('E'))
1051 goto bad_format;
1053 DO_NUMBER (2, tp->tm_hour);
1055 case L_('I'):
1056 if (modifier == L_('E'))
1057 goto bad_format;
1059 DO_NUMBER (2, hour12);
1061 case L_('k'): /* GNU extension. */
1062 if (modifier == L_('E'))
1063 goto bad_format;
1065 DO_NUMBER_SPACEPAD (2, tp->tm_hour);
1067 case L_('l'): /* GNU extension. */
1068 if (modifier == L_('E'))
1069 goto bad_format;
1071 DO_NUMBER_SPACEPAD (2, hour12);
1073 case L_('j'):
1074 if (modifier == L_('E'))
1075 goto bad_format;
1077 DO_NUMBER (3, 1 + tp->tm_yday);
1079 case L_('M'):
1080 if (modifier == L_('E'))
1081 goto bad_format;
1083 DO_NUMBER (2, tp->tm_min);
1085 case L_('m'):
1086 if (modifier == L_('E'))
1087 goto bad_format;
1089 DO_NUMBER (2, tp->tm_mon + 1);
1091 #ifndef _LIBC
1092 case L_('N'): /* GNU extension. */
1093 if (modifier == L_('E'))
1094 goto bad_format;
1096 number_value = ns;
1097 if (width != -1)
1099 /* Take an explicit width less than 9 as a precision. */
1100 int j;
1101 for (j = width; j < 9; j++)
1102 number_value /= 10;
1105 DO_NUMBER (9, number_value);
1106 #endif
1108 case L_('n'):
1109 add (1, *p = L_('\n'));
1110 break;
1112 case L_('P'):
1113 to_lowcase = 1;
1114 #if !defined _NL_CURRENT && HAVE_STRFTIME
1115 format_char = L_('p');
1116 #endif
1117 /* FALLTHROUGH */
1119 case L_('p'):
1120 if (change_case)
1122 to_uppcase = 0;
1123 to_lowcase = 1;
1125 #if defined _NL_CURRENT || !HAVE_STRFTIME
1126 cpy (ap_len, ampm);
1127 break;
1128 #else
1129 goto underlying_strftime;
1130 #endif
1132 case L_('R'):
1133 subfmt = L_("%H:%M");
1134 goto subformat;
1136 case L_('r'):
1137 #ifdef _NL_CURRENT
1138 if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME,
1139 NLW(T_FMT_AMPM)))
1140 == L_('\0'))
1141 #endif
1142 subfmt = L_("%I:%M:%S %p");
1143 goto subformat;
1145 case L_('S'):
1146 if (modifier == L_('E'))
1147 goto bad_format;
1149 DO_NUMBER (2, tp->tm_sec);
1151 case L_('s'): /* GNU extension. */
1153 struct tm ltm;
1154 time_t t;
1156 ltm = *tp;
1157 t = mktime (&ltm);
1159 /* Generate string value for T using time_t arithmetic;
1160 this works even if sizeof (long) < sizeof (time_t). */
1162 bufp = buf + sizeof (buf) / sizeof (buf[0]);
1163 negative_number = t < 0;
1167 int d = t % 10;
1168 t /= 10;
1170 if (negative_number)
1172 d = -d;
1174 /* Adjust if division truncates to minus infinity. */
1175 if (0 < -1 % 10 && d < 0)
1177 t++;
1178 d += 10;
1182 *--bufp = d + L_('0');
1184 while (t != 0);
1186 digits = 1;
1187 goto do_number_sign_and_padding;
1190 case L_('X'):
1191 if (modifier == L_('O'))
1192 goto bad_format;
1193 #ifdef _NL_CURRENT
1194 if (! (modifier == L_('E')
1195 && (*(subfmt =
1196 (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT)))
1197 != L_('\0'))))
1198 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
1199 goto subformat;
1200 #else
1201 # if HAVE_STRFTIME
1202 goto underlying_strftime;
1203 # else
1204 /* Fall through. */
1205 # endif
1206 #endif
1207 case L_('T'):
1208 subfmt = L_("%H:%M:%S");
1209 goto subformat;
1211 case L_('t'):
1212 add (1, *p = L_('\t'));
1213 break;
1215 case L_('u'):
1216 DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
1218 case L_('U'):
1219 if (modifier == L_('E'))
1220 goto bad_format;
1222 DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
1224 case L_('V'):
1225 case L_('g'):
1226 case L_('G'):
1227 if (modifier == L_('E'))
1228 goto bad_format;
1230 int year = tp->tm_year + TM_YEAR_BASE;
1231 int days = iso_week_days (tp->tm_yday, tp->tm_wday);
1233 if (days < 0)
1235 /* This ISO week belongs to the previous year. */
1236 year--;
1237 days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
1238 tp->tm_wday);
1240 else
1242 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
1243 tp->tm_wday);
1244 if (0 <= d)
1246 /* This ISO week belongs to the next year. */
1247 year++;
1248 days = d;
1252 switch (*f)
1254 case L_('g'):
1255 DO_NUMBER (2, (year % 100 + 100) % 100);
1257 case L_('G'):
1258 DO_NUMBER (1, year);
1260 default:
1261 DO_NUMBER (2, days / 7 + 1);
1265 case L_('W'):
1266 if (modifier == L_('E'))
1267 goto bad_format;
1269 DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
1271 case L_('w'):
1272 if (modifier == L_('E'))
1273 goto bad_format;
1275 DO_NUMBER (1, tp->tm_wday);
1277 case L_('Y'):
1278 if (modifier == 'E')
1280 #if HAVE_STRUCT_ERA_ENTRY
1281 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1282 if (era)
1284 # ifdef COMPILE_WIDE
1285 subfmt = era->era_wformat;
1286 # else
1287 subfmt = era->era_format;
1288 # endif
1289 goto subformat;
1291 #else
1292 # if HAVE_STRFTIME
1293 goto underlying_strftime;
1294 # endif
1295 #endif
1297 if (modifier == L_('O'))
1298 goto bad_format;
1299 else
1300 DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
1302 case L_('y'):
1303 if (modifier == L_('E'))
1305 #if HAVE_STRUCT_ERA_ENTRY
1306 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1307 if (era)
1309 int delta = tp->tm_year - era->start_date[0];
1310 DO_NUMBER (1, (era->offset
1311 + delta * era->absolute_direction));
1313 #else
1314 # if HAVE_STRFTIME
1315 goto underlying_strftime;
1316 # endif
1317 #endif
1319 DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
1321 case L_('Z'):
1322 if (change_case)
1324 to_uppcase = 0;
1325 to_lowcase = 1;
1328 #if HAVE_TZNAME
1329 /* The tzset() call might have changed the value. */
1330 if (!(zone && *zone) && tp->tm_isdst >= 0)
1331 zone = tzname[tp->tm_isdst];
1332 #endif
1333 if (! zone)
1334 zone = "";
1336 #ifdef COMPILE_WIDE
1338 /* The zone string is always given in multibyte form. We have
1339 to transform it first. */
1340 wchar_t *wczone;
1341 size_t len;
1342 widen (zone, wczone, len);
1343 cpy (len, wczone);
1345 #else
1346 cpy (strlen (zone), zone);
1347 #endif
1348 break;
1350 case L_('z'):
1351 if (tp->tm_isdst < 0)
1352 break;
1355 int diff;
1356 #if HAVE_TM_GMTOFF
1357 diff = tp->tm_gmtoff;
1358 #else
1359 if (ut)
1360 diff = 0;
1361 else
1363 struct tm gtm;
1364 struct tm ltm;
1365 time_t lt;
1367 ltm = *tp;
1368 lt = mktime (&ltm);
1370 if (lt == (time_t) -1)
1372 /* mktime returns -1 for errors, but -1 is also a
1373 valid time_t value. Check whether an error really
1374 occurred. */
1375 struct tm tm;
1377 if (! my_strftime_localtime_r (&lt, &tm)
1378 || ((ltm.tm_sec ^ tm.tm_sec)
1379 | (ltm.tm_min ^ tm.tm_min)
1380 | (ltm.tm_hour ^ tm.tm_hour)
1381 | (ltm.tm_mday ^ tm.tm_mday)
1382 | (ltm.tm_mon ^ tm.tm_mon)
1383 | (ltm.tm_year ^ tm.tm_year)))
1384 break;
1387 if (! my_strftime_gmtime_r (&lt, &gtm))
1388 break;
1390 diff = tm_diff (&ltm, &gtm);
1392 #endif
1394 if (diff < 0)
1396 add (1, *p = L_('-'));
1397 diff = -diff;
1399 else
1400 add (1, *p = L_('+'));
1402 diff /= 60;
1403 DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
1406 case L_('\0'): /* GNU extension: % at end of format. */
1407 --f;
1408 /* Fall through. */
1409 default:
1410 /* Unknown format; output the format, including the '%',
1411 since this is most likely the right thing to do if a
1412 multibyte string has been misparsed. */
1413 bad_format:
1415 int flen;
1416 for (flen = 1; f[1 - flen] != L_('%'); flen++)
1417 continue;
1418 cpy (flen, &f[1 - flen]);
1420 break;
1424 if (p && maxsize != 0)
1425 *p = L_('\0');
1426 return i;
1428 #ifdef _LIBC
1429 libc_hidden_def (my_strftime)
1430 #endif
1433 #ifdef emacs
1434 #undef ut
1435 /* For Emacs we have a separate interface which corresponds to the normal
1436 strftime function plus the ut argument, but without the ns argument. */
1437 size_t
1438 emacs_strftimeu (char *s, size_t maxsize, const char *format,
1439 const struct tm *tp, int ut)
1441 return my_strftime (s, maxsize, format, tp, ut, 0);
1443 #endif