Define _POSIX_THREAD_PRIORITY_SCHEDULING.
[glibc/pb-stable.git] / time / strftime.c
blobd83020563e32463951ccf0c9b9766389a6f965d3
1 /* Copyright (C) 1991-1999, 2000, 2001, 2002, 2003
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
24 #ifdef _LIBC
25 # define HAVE_LIMITS_H 1
26 # define HAVE_MBLEN 1
27 # define HAVE_MBRLEN 1
28 # define HAVE_STRUCT_ERA_ENTRY 1
29 # define HAVE_TM_GMTOFF 1
30 # define HAVE_TM_ZONE 1
31 # define HAVE_TZNAME 1
32 # define HAVE_TZSET 1
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 #else
88 # ifndef HAVE_MEMCPY
89 # define memcpy(d, s, n) bcopy ((s), (d), (n))
90 # endif
91 #endif
93 #ifdef COMPILE_WIDE
94 # include <endian.h>
95 # define CHAR_T wchar_t
96 # define UCHAR_T unsigned int
97 # define L_(Str) L##Str
98 # define NLW(Sym) _NL_W##Sym
100 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
101 # define STRLEN(s) __wcslen (s)
103 #else
104 # define CHAR_T char
105 # define UCHAR_T unsigned char
106 # define L_(Str) Str
107 # define NLW(Sym) Sym
109 # if !defined STDC_HEADERS && !defined HAVE_MEMCPY
110 # define MEMCPY(d, s, n) bcopy ((s), (d), (n))
111 # else
112 # define MEMCPY(d, s, n) memcpy ((d), (s), (n))
113 # endif
114 # define STRLEN(s) strlen (s)
116 # ifdef _LIBC
117 # define MEMPCPY(d, s, n) __mempcpy (d, s, n)
118 # else
119 # ifndef HAVE_MEMPCPY
120 # define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n)))
121 # endif
122 # endif
123 #endif
125 #ifndef __P
126 # if defined __GNUC__ || (defined __STDC__ && __STDC__)
127 # define __P(args) args
128 # else
129 # define __P(args) ()
130 # endif /* GCC. */
131 #endif /* Not __P. */
133 #ifndef PTR
134 # ifdef __STDC__
135 # define PTR void *
136 # else
137 # define PTR char *
138 # endif
139 #endif
141 #ifndef CHAR_BIT
142 # define CHAR_BIT 8
143 #endif
145 #ifndef NULL
146 # define NULL 0
147 #endif
149 #define TYPE_SIGNED(t) ((t) -1 < 0)
151 /* Bound on length of the string representing an integer value of type t.
152 Subtract one for the sign bit if t is signed;
153 302 / 1000 is log10 (2) rounded up;
154 add one for integer division truncation;
155 add one more for a minus sign if t is signed. */
156 #define INT_STRLEN_BOUND(t) \
157 ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 + 1 + TYPE_SIGNED (t))
159 #define TM_YEAR_BASE 1900
161 #ifndef __isleap
162 /* Nonzero if YEAR is a leap year (every 4 years,
163 except every 100th isn't, and every 400th is). */
164 # define __isleap(year) \
165 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
166 #endif
169 #ifdef _LIBC
170 # define my_strftime_gmtime_r __gmtime_r
171 # define my_strftime_localtime_r __localtime_r
172 # define tzname __tzname
173 # define tzset __tzset
174 #else
176 /* If we're a strftime substitute in a GNU program, then prefer gmtime
177 to gmtime_r, since many gmtime_r implementations are buggy.
178 Similarly for localtime_r. */
180 # if ! HAVE_TM_GMTOFF
181 static struct tm *my_strftime_gmtime_r __P ((const time_t *, struct tm *));
182 static struct tm *
183 my_strftime_gmtime_r (t, tp)
184 const time_t *t;
185 struct tm *tp;
187 struct tm *l = gmtime (t);
188 if (! l)
189 return 0;
190 *tp = *l;
191 return tp;
193 # endif /* ! HAVE_TM_GMTOFF */
195 static struct tm *my_strftime_localtime_r __P ((const time_t *, struct tm *));
196 static struct tm *
197 my_strftime_localtime_r (t, tp)
198 const time_t *t;
199 struct tm *tp;
201 struct tm *l = localtime (t);
202 if (! l)
203 return 0;
204 *tp = *l;
205 return tp;
207 #endif /* ! defined _LIBC */
210 #if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
211 /* Some systems lack the `memset' function and we don't want to
212 introduce additional dependencies. */
213 /* The SGI compiler reportedly barfs on the trailing null
214 if we use a string constant as the initializer. 28 June 1997, rms. */
215 static const CHAR_T spaces[16] = /* " " */
217 L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),
218 L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' ')
220 static const CHAR_T zeroes[16] = /* "0000000000000000" */
222 L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),
223 L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0')
226 # define memset_space(P, Len) \
227 do { \
228 int _len = (Len); \
230 do \
232 int _this = _len > 16 ? 16 : _len; \
233 (P) = MEMPCPY ((P), spaces, _this * sizeof (CHAR_T)); \
234 _len -= _this; \
236 while (_len > 0); \
237 } while (0)
239 # define memset_zero(P, Len) \
240 do { \
241 int _len = (Len); \
243 do \
245 int _this = _len > 16 ? 16 : _len; \
246 (P) = MEMPCPY ((P), zeroes, _this * sizeof (CHAR_T)); \
247 _len -= _this; \
249 while (_len > 0); \
250 } while (0)
251 #else
252 # ifdef COMPILE_WIDE
253 # define memset_space(P, Len) (wmemset ((P), L' ', (Len)), (P) += (Len))
254 # define memset_zero(P, Len) (wmemset ((P), L'0', (Len)), (P) += (Len))
255 # else
256 # define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
257 # define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
258 # endif
259 #endif
261 #define add(n, f) \
262 do \
264 int _n = (n); \
265 int _delta = width - _n; \
266 int _incr = _n + (_delta > 0 ? _delta : 0); \
267 if ((size_t) _incr >= maxsize - i) \
268 return 0; \
269 if (p) \
271 if (_delta > 0) \
273 if (pad == L_('0')) \
274 memset_zero (p, _delta); \
275 else \
276 memset_space (p, _delta); \
278 f; \
279 p += _n; \
281 i += _incr; \
282 } while (0)
284 #define cpy(n, s) \
285 add ((n), \
286 if (to_lowcase) \
287 memcpy_lowcase (p, (s), _n LOCALE_ARG); \
288 else if (to_uppcase) \
289 memcpy_uppcase (p, (s), _n LOCALE_ARG); \
290 else \
291 MEMCPY ((PTR) p, (const PTR) (s), _n))
293 #ifdef COMPILE_WIDE
294 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
295 # undef __mbsrtowcs_l
296 # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
297 # endif
298 # define widen(os, ws, l) \
300 mbstate_t __st; \
301 const char *__s = os; \
302 memset (&__st, '\0', sizeof (__st)); \
303 l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
304 ws = alloca ((l + 1) * sizeof (wchar_t)); \
305 (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
307 #endif
310 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
311 /* We use this code also for the extended locale handling where the
312 function gets as an additional argument the locale which has to be
313 used. To access the values we have to redefine the _NL_CURRENT
314 macro. */
315 # define strftime __strftime_l
316 # define wcsftime __wcsftime_l
317 # undef _NL_CURRENT
318 # define _NL_CURRENT(category, item) \
319 (current->values[_NL_ITEM_INDEX (item)].string)
320 # define LOCALE_PARAM , loc
321 # define LOCALE_ARG , loc
322 # define LOCALE_PARAM_DECL __locale_t loc;
323 # define LOCALE_PARAM_PROTO , __locale_t loc
324 # define HELPER_LOCALE_ARG , current
325 #else
326 # define LOCALE_PARAM
327 # define LOCALE_PARAM_PROTO
328 # define LOCALE_ARG
329 # define LOCALE_PARAM_DECL
330 # ifdef _LIBC
331 # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
332 # else
333 # define HELPER_LOCALE_ARG
334 # endif
335 #endif
337 #ifdef COMPILE_WIDE
338 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
339 # define TOUPPER(Ch, L) __towupper_l (Ch, L)
340 # define TOLOWER(Ch, L) __towlower_l (Ch, L)
341 # else
342 # define TOUPPER(Ch, L) towupper (Ch)
343 # define TOLOWER(Ch, L) towlower (Ch)
344 # endif
345 #else
346 # ifdef _LIBC
347 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
348 # define TOUPPER(Ch, L) __toupper_l (Ch, L)
349 # define TOLOWER(Ch, L) __tolower_l (Ch, L)
350 # else
351 # define TOUPPER(Ch, L) toupper (Ch)
352 # define TOLOWER(Ch, L) tolower (Ch)
353 # endif
354 # else
355 # define TOUPPER(Ch, L) (islower (Ch) ? toupper (Ch) : (Ch))
356 # define TOLOWER(Ch, L) (isupper (Ch) ? tolower (Ch) : (Ch))
357 # endif
358 #endif
359 /* We don't use `isdigit' here since the locale dependent
360 interpretation is not what we want here. We only need to accept
361 the arabic digits in the ASCII range. One day there is perhaps a
362 more reliable way to accept other sets of digits. */
363 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
365 static CHAR_T *memcpy_lowcase __P ((CHAR_T *dest, const CHAR_T *src,
366 size_t len LOCALE_PARAM_PROTO));
368 static CHAR_T *
369 memcpy_lowcase (dest, src, len LOCALE_PARAM)
370 CHAR_T *dest;
371 const CHAR_T *src;
372 size_t len;
373 LOCALE_PARAM_DECL
375 while (len-- > 0)
376 dest[len] = TOLOWER ((UCHAR_T) src[len], loc);
377 return dest;
380 static CHAR_T *memcpy_uppcase __P ((CHAR_T *dest, const CHAR_T *src,
381 size_t len LOCALE_PARAM_PROTO));
383 static CHAR_T *
384 memcpy_uppcase (dest, src, len LOCALE_PARAM)
385 CHAR_T *dest;
386 const CHAR_T *src;
387 size_t len;
388 LOCALE_PARAM_DECL
390 while (len-- > 0)
391 dest[len] = TOUPPER ((UCHAR_T) src[len], loc);
392 return dest;
396 #if ! HAVE_TM_GMTOFF
397 /* Yield the difference between *A and *B,
398 measured in seconds, ignoring leap seconds. */
399 # define tm_diff ftime_tm_diff
400 static int tm_diff __P ((const struct tm *, const struct tm *));
401 static int
402 tm_diff (a, b)
403 const struct tm *a;
404 const struct tm *b;
406 /* Compute intervening leap days correctly even if year is negative.
407 Take care to avoid int overflow in leap day calculations,
408 but it's OK to assume that A and B are close to each other. */
409 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
410 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
411 int a100 = a4 / 25 - (a4 % 25 < 0);
412 int b100 = b4 / 25 - (b4 % 25 < 0);
413 int a400 = a100 >> 2;
414 int b400 = b100 >> 2;
415 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
416 int years = a->tm_year - b->tm_year;
417 int days = (365 * years + intervening_leap_days
418 + (a->tm_yday - b->tm_yday));
419 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
420 + (a->tm_min - b->tm_min))
421 + (a->tm_sec - b->tm_sec));
423 #endif /* ! HAVE_TM_GMTOFF */
427 /* The number of days from the first day of the first ISO week of this
428 year to the year day YDAY with week day WDAY. ISO weeks start on
429 Monday; the first ISO week has the year's first Thursday. YDAY may
430 be as small as YDAY_MINIMUM. */
431 #define ISO_WEEK_START_WDAY 1 /* Monday */
432 #define ISO_WEEK1_WDAY 4 /* Thursday */
433 #define YDAY_MINIMUM (-366)
434 static int iso_week_days __P ((int, int));
435 #ifdef __GNUC__
436 __inline__
437 #endif
438 static int
439 iso_week_days (yday, wday)
440 int yday;
441 int wday;
443 /* Add enough to the first operand of % to make it nonnegative. */
444 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
445 return (yday
446 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
447 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
451 #if !(defined _NL_CURRENT || HAVE_STRFTIME)
452 static CHAR_T const weekday_name[][10] =
454 L_("Sunday"), L_("Monday"), L_("Tuesday"), L_("Wednesday"),
455 L_("Thursday"), L_("Friday"), L_("Saturday")
457 static CHAR_T const month_name[][10] =
459 L_("January"), L_("February"), L_("March"), L_("April"), L_("May"),
460 L_("June"), L_("July"), L_("August"), L_("September"), L_("October"),
461 L_("November"), L_("December")
463 #endif
466 #ifdef emacs
467 # define my_strftime emacs_strftimeu
468 # define ut_argument , ut
469 # define ut_argument_spec int ut;
470 # define ut_argument_spec_iso , int ut
471 #else
472 # ifdef COMPILE_WIDE
473 # define my_strftime wcsftime
474 # define nl_get_alt_digit _nl_get_walt_digit
475 # else
476 # define my_strftime strftime
477 # define nl_get_alt_digit _nl_get_alt_digit
478 # endif
479 # define ut_argument
480 # define ut_argument_spec
481 # define ut_argument_spec_iso
482 /* We don't have this information in general. */
483 # define ut 0
484 #endif
486 #if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
487 /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
488 Work around this bug by copying *tp before it might be munged. */
489 size_t _strftime_copytm __P ((char *, size_t, const char *,
490 const struct tm * ut_argument_spec_iso));
491 size_t
492 my_strftime (s, maxsize, format, tp ut_argument)
493 CHAR_T *s;
494 size_t maxsize;
495 const CHAR_T *format;
496 const struct tm *tp;
497 ut_argument_spec
499 struct tm tmcopy;
500 tmcopy = *tp;
501 return _strftime_copytm (s, maxsize, format, &tmcopy ut_argument);
503 # undef my_strftime
504 # define my_strftime _strftime_copytm
505 #endif
508 /* Write information from TP into S according to the format
509 string FORMAT, writing no more that MAXSIZE characters
510 (including the terminating '\0') and returning number of
511 characters written. If S is NULL, nothing will be written
512 anywhere, so to determine how many characters would be
513 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
514 size_t
515 my_strftime (s, maxsize, format, tp ut_argument LOCALE_PARAM)
516 CHAR_T *s;
517 size_t maxsize;
518 const CHAR_T *format;
519 const struct tm *tp;
520 ut_argument_spec
521 LOCALE_PARAM_DECL
523 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
524 struct locale_data *const current = loc->__locales[LC_TIME];
525 #endif
527 int hour12 = tp->tm_hour;
528 #ifdef _NL_CURRENT
529 /* We cannot make the following values variables since we must delay
530 the evaluation of these values until really needed since some
531 expressions might not be valid in every situation. The `struct tm'
532 might be generated by a strptime() call that initialized
533 only a few elements. Dereference the pointers only if the format
534 requires this. Then it is ok to fail if the pointers are invalid. */
535 # define a_wkday \
536 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
537 # define f_wkday \
538 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
539 # define a_month \
540 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
541 # define f_month \
542 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
543 # define ampm \
544 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
545 ? NLW(PM_STR) : NLW(AM_STR)))
547 # define aw_len STRLEN (a_wkday)
548 # define am_len STRLEN (a_month)
549 # define ap_len STRLEN (ampm)
550 #else
551 # if !HAVE_STRFTIME
552 # define f_wkday (weekday_name[tp->tm_wday])
553 # define f_month (month_name[tp->tm_mon])
554 # define a_wkday f_wkday
555 # define a_month f_month
556 # define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
558 size_t aw_len = 3;
559 size_t am_len = 3;
560 size_t ap_len = 2;
561 # endif
562 #endif
563 const char *zone;
564 size_t i = 0;
565 CHAR_T *p = s;
566 const CHAR_T *f;
567 #if DO_MULTIBYTE && !defined COMPILE_WIDE
568 const char *format_end = NULL;
569 #endif
571 zone = NULL;
572 #if HAVE_TM_ZONE
573 /* The POSIX test suite assumes that setting
574 the environment variable TZ to a new value before calling strftime()
575 will influence the result (the %Z format) even if the information in
576 TP is computed with a totally different time zone.
577 This is bogus: though POSIX allows bad behavior like this,
578 POSIX does not require it. Do the right thing instead. */
579 zone = (const char *) tp->tm_zone;
580 #endif
581 #if HAVE_TZNAME
582 if (ut)
584 if (! (zone && *zone))
585 zone = "GMT";
587 else
589 /* POSIX.1 requires that local time zone information is used as
590 though strftime called tzset. */
591 # if HAVE_TZSET
592 tzset ();
593 # endif
595 #endif
597 if (hour12 > 12)
598 hour12 -= 12;
599 else
600 if (hour12 == 0)
601 hour12 = 12;
603 for (f = format; *f != '\0'; ++f)
605 int pad = 0; /* Padding for number ('-', '_', or 0). */
606 int modifier; /* Field modifier ('E', 'O', or 0). */
607 int digits; /* Max digits for numeric format. */
608 int number_value; /* Numeric value to be printed. */
609 int negative_number; /* 1 if the number is negative. */
610 const CHAR_T *subfmt;
611 CHAR_T *bufp;
612 CHAR_T buf[1 + (sizeof (int) < sizeof (time_t)
613 ? INT_STRLEN_BOUND (time_t)
614 : INT_STRLEN_BOUND (int))];
615 int width = -1;
616 int to_lowcase = 0;
617 int to_uppcase = 0;
618 int change_case = 0;
619 int format_char;
621 #if DO_MULTIBYTE && !defined COMPILE_WIDE
622 switch (*f)
624 case L_('%'):
625 break;
627 case L_('\b'): case L_('\t'): case L_('\n'):
628 case L_('\v'): case L_('\f'): case L_('\r'):
629 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
630 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
631 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
632 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
633 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
634 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
635 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
636 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
637 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
638 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
639 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
640 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
641 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
642 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
643 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
644 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
645 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
646 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
647 case L_('~'):
648 /* The C Standard requires these 98 characters (plus '%') to
649 be in the basic execution character set. None of these
650 characters can start a multibyte sequence, so they need
651 not be analyzed further. */
652 add (1, *p = *f);
653 continue;
655 default:
656 /* Copy this multibyte sequence until we reach its end, find
657 an error, or come back to the initial shift state. */
659 mbstate_t mbstate = mbstate_zero;
660 size_t len = 0;
661 size_t fsize;
663 if (! format_end)
664 format_end = f + strlen (f) + 1;
665 fsize = format_end - f;
669 size_t bytes = mbrlen (f + len, fsize - len, &mbstate);
671 if (bytes == 0)
672 break;
674 if (bytes == (size_t) -2)
676 len += strlen (f + len);
677 break;
680 if (bytes == (size_t) -1)
682 len++;
683 break;
686 len += bytes;
688 while (! mbsinit (&mbstate));
690 cpy (len, f);
691 f += len - 1;
692 continue;
696 #else /* ! DO_MULTIBYTE */
698 /* Either multibyte encodings are not supported, they are
699 safe for formats, so any non-'%' byte can be copied through,
700 or this is the wide character version. */
701 if (*f != L_('%'))
703 add (1, *p = *f);
704 continue;
707 #endif /* ! DO_MULTIBYTE */
709 /* Check for flags that can modify a format. */
710 while (1)
712 switch (*++f)
714 /* This influences the number formats. */
715 case L_('_'):
716 case L_('-'):
717 case L_('0'):
718 pad = *f;
719 continue;
721 /* This changes textual output. */
722 case L_('^'):
723 to_uppcase = 1;
724 continue;
725 case L_('#'):
726 change_case = 1;
727 continue;
729 default:
730 break;
732 break;
735 /* As a GNU extension we allow to specify the field width. */
736 if (ISDIGIT (*f))
738 width = 0;
741 if (width > INT_MAX / 10
742 || (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10))
743 /* Avoid overflow. */
744 width = INT_MAX;
745 else
747 width *= 10;
748 width += *f - L_('0');
750 ++f;
752 while (ISDIGIT (*f));
755 /* Check for modifiers. */
756 switch (*f)
758 case L_('E'):
759 case L_('O'):
760 modifier = *f++;
761 break;
763 default:
764 modifier = 0;
765 break;
768 /* Now do the specified format. */
769 format_char = *f;
770 switch (format_char)
772 #define DO_NUMBER(d, v) \
773 digits = d > width ? d : width; \
774 number_value = v; goto do_number
775 #define DO_NUMBER_SPACEPAD(d, v) \
776 digits = d > width ? d : width; \
777 number_value = v; goto do_number_spacepad
779 case L_('%'):
780 if (modifier != 0)
781 goto bad_format;
782 add (1, *p = *f);
783 break;
785 case L_('a'):
786 if (modifier != 0)
787 goto bad_format;
788 if (change_case)
790 to_uppcase = 1;
791 to_lowcase = 0;
793 #if defined _NL_CURRENT || !HAVE_STRFTIME
794 cpy (aw_len, a_wkday);
795 break;
796 #else
797 goto underlying_strftime;
798 #endif
800 case 'A':
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_wkday), f_wkday);
810 break;
811 #else
812 goto underlying_strftime;
813 #endif
815 case L_('b'):
816 case L_('h'):
817 if (change_case)
819 to_uppcase = 1;
820 to_lowcase = 0;
822 if (modifier != 0)
823 goto bad_format;
824 #if defined _NL_CURRENT || !HAVE_STRFTIME
825 cpy (am_len, a_month);
826 break;
827 #else
828 goto underlying_strftime;
829 #endif
831 case L_('B'):
832 if (modifier != 0)
833 goto bad_format;
834 if (change_case)
836 to_uppcase = 1;
837 to_lowcase = 0;
839 #if defined _NL_CURRENT || !HAVE_STRFTIME
840 cpy (STRLEN (f_month), f_month);
841 break;
842 #else
843 goto underlying_strftime;
844 #endif
846 case L_('c'):
847 if (modifier == L_('O'))
848 goto bad_format;
849 #ifdef _NL_CURRENT
850 if (! (modifier == 'E'
851 && (*(subfmt =
852 (const CHAR_T *) _NL_CURRENT (LC_TIME,
853 NLW(ERA_D_T_FMT)))
854 != '\0')))
855 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
856 #else
857 # if HAVE_STRFTIME
858 goto underlying_strftime;
859 # else
860 subfmt = L_("%a %b %e %H:%M:%S %Y");
861 # endif
862 #endif
864 subformat:
866 CHAR_T *old_start = p;
867 size_t len = my_strftime (NULL, (size_t) -1, subfmt,
868 tp ut_argument LOCALE_ARG);
869 add (len, my_strftime (p, maxsize - i, subfmt,
870 tp ut_argument LOCALE_ARG));
872 if (to_uppcase)
873 while (old_start < p)
875 *old_start = TOUPPER ((UCHAR_T) *old_start, loc);
876 ++old_start;
879 break;
881 #if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
882 underlying_strftime:
884 /* The relevant information is available only via the
885 underlying strftime implementation, so use that. */
886 char ufmt[4];
887 char *u = ufmt;
888 char ubuf[1024]; /* enough for any single format in practice */
889 size_t len;
890 /* Make sure we're calling the actual underlying strftime.
891 In some cases, config.h contains something like
892 "#define strftime rpl_strftime". */
893 # ifdef strftime
894 # undef strftime
895 size_t strftime ();
896 # endif
898 *u++ = '%';
899 if (modifier != 0)
900 *u++ = modifier;
901 *u++ = format_char;
902 *u = '\0';
903 len = strftime (ubuf, sizeof ubuf, ufmt, tp);
904 if (len == 0 && ubuf[0] != '\0')
905 return 0;
906 cpy (len, ubuf);
908 break;
909 #endif
911 case L_('C'):
912 if (modifier == L_('O'))
913 goto bad_format;
914 if (modifier == L_('E'))
916 #if HAVE_STRUCT_ERA_ENTRY
917 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
918 if (era)
920 # ifdef COMPILE_WIDE
921 size_t len = __wcslen (era->era_wname);
922 cpy (len, era->era_wname);
923 # else
924 size_t len = strlen (era->era_name);
925 cpy (len, era->era_name);
926 # endif
927 break;
929 #else
930 # if HAVE_STRFTIME
931 goto underlying_strftime;
932 # endif
933 #endif
937 int year = tp->tm_year + TM_YEAR_BASE;
938 DO_NUMBER (1, year / 100 - (year % 100 < 0));
941 case L_('x'):
942 if (modifier == L_('O'))
943 goto bad_format;
944 #ifdef _NL_CURRENT
945 if (! (modifier == L_('E')
946 && (*(subfmt =
947 (const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT)))
948 != L_('\0'))))
949 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
950 goto subformat;
951 #else
952 # if HAVE_STRFTIME
953 goto underlying_strftime;
954 # else
955 /* Fall through. */
956 # endif
957 #endif
958 case L_('D'):
959 if (modifier != 0)
960 goto bad_format;
961 subfmt = L_("%m/%d/%y");
962 goto subformat;
964 case L_('d'):
965 if (modifier == L_('E'))
966 goto bad_format;
968 DO_NUMBER (2, tp->tm_mday);
970 case L_('e'):
971 if (modifier == L_('E'))
972 goto bad_format;
974 DO_NUMBER_SPACEPAD (2, tp->tm_mday);
976 /* All numeric formats set DIGITS and NUMBER_VALUE and then
977 jump to one of these two labels. */
979 do_number_spacepad:
980 /* Force `_' flag unless overwritten by `0' or '-' flag. */
981 if (pad != L_('0') && pad != L_('-'))
982 pad = L_('_');
984 do_number:
985 /* Format the number according to the MODIFIER flag. */
987 if (modifier == L_('O') && 0 <= number_value)
989 #ifdef _NL_CURRENT
990 /* Get the locale specific alternate representation of
991 the number NUMBER_VALUE. If none exist NULL is returned. */
992 const CHAR_T *cp = nl_get_alt_digit (number_value
993 HELPER_LOCALE_ARG);
995 if (cp != NULL)
997 size_t digitlen = STRLEN (cp);
998 if (digitlen != 0)
1000 cpy (digitlen, cp);
1001 break;
1004 #else
1005 # if HAVE_STRFTIME
1006 goto underlying_strftime;
1007 # endif
1008 #endif
1011 unsigned int u = number_value;
1013 bufp = buf + sizeof (buf) / sizeof (buf[0]);
1014 negative_number = number_value < 0;
1016 if (negative_number)
1017 u = -u;
1020 *--bufp = u % 10 + L_('0');
1021 while ((u /= 10) != 0);
1024 do_number_sign_and_padding:
1025 if (negative_number)
1026 *--bufp = L_('-');
1028 if (pad != L_('-'))
1030 int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
1031 - bufp);
1033 if (padding > 0)
1035 if (pad == L_('_'))
1037 if ((size_t) padding >= maxsize - i)
1038 return 0;
1040 if (p)
1041 memset_space (p, padding);
1042 i += padding;
1043 width = width > padding ? width - padding : 0;
1045 else
1047 if ((size_t) digits >= maxsize - i)
1048 return 0;
1050 if (negative_number)
1052 ++bufp;
1054 if (p)
1055 *p++ = L_('-');
1056 ++i;
1059 if (p)
1060 memset_zero (p, padding);
1061 i += padding;
1062 width = 0;
1067 cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
1068 break;
1070 case L_('F'):
1071 if (modifier != 0)
1072 goto bad_format;
1073 subfmt = L_("%Y-%m-%d");
1074 goto subformat;
1076 case L_('H'):
1077 if (modifier == L_('E'))
1078 goto bad_format;
1080 DO_NUMBER (2, tp->tm_hour);
1082 case L_('I'):
1083 if (modifier == L_('E'))
1084 goto bad_format;
1086 DO_NUMBER (2, hour12);
1088 case L_('k'): /* GNU extension. */
1089 if (modifier == L_('E'))
1090 goto bad_format;
1092 DO_NUMBER_SPACEPAD (2, tp->tm_hour);
1094 case L_('l'): /* GNU extension. */
1095 if (modifier == L_('E'))
1096 goto bad_format;
1098 DO_NUMBER_SPACEPAD (2, hour12);
1100 case L_('j'):
1101 if (modifier == L_('E'))
1102 goto bad_format;
1104 DO_NUMBER (3, 1 + tp->tm_yday);
1106 case L_('M'):
1107 if (modifier == L_('E'))
1108 goto bad_format;
1110 DO_NUMBER (2, tp->tm_min);
1112 case L_('m'):
1113 if (modifier == L_('E'))
1114 goto bad_format;
1116 DO_NUMBER (2, tp->tm_mon + 1);
1118 case L_('n'):
1119 add (1, *p = L_('\n'));
1120 break;
1122 case L_('P'):
1123 to_lowcase = 1;
1124 #if !defined _NL_CURRENT && HAVE_STRFTIME
1125 format_char = L_('p');
1126 #endif
1127 /* FALLTHROUGH */
1129 case L_('p'):
1130 if (change_case)
1132 to_uppcase = 0;
1133 to_lowcase = 1;
1135 #if defined _NL_CURRENT || !HAVE_STRFTIME
1136 cpy (ap_len, ampm);
1137 break;
1138 #else
1139 goto underlying_strftime;
1140 #endif
1142 case L_('R'):
1143 subfmt = L_("%H:%M");
1144 goto subformat;
1146 case L_('r'):
1147 #if !defined _NL_CURRENT && HAVE_STRFTIME
1148 goto underlying_strftime;
1149 #else
1150 # ifdef _NL_CURRENT
1151 if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME,
1152 NLW(T_FMT_AMPM)))
1153 == L_('\0'))
1154 # endif
1155 subfmt = L_("%I:%M:%S %p");
1156 goto subformat;
1157 #endif
1159 case L_('S'):
1160 if (modifier == L_('E'))
1161 goto bad_format;
1163 DO_NUMBER (2, tp->tm_sec);
1165 case L_('s'): /* GNU extension. */
1167 struct tm ltm;
1168 time_t t;
1170 ltm = *tp;
1171 t = mktime (&ltm);
1173 /* Generate string value for T using time_t arithmetic;
1174 this works even if sizeof (long) < sizeof (time_t). */
1176 bufp = buf + sizeof (buf) / sizeof (buf[0]);
1177 negative_number = t < 0;
1181 int d = t % 10;
1182 t /= 10;
1184 if (negative_number)
1186 d = -d;
1188 /* Adjust if division truncates to minus infinity. */
1189 if (0 < -1 % 10 && d < 0)
1191 t++;
1192 d += 10;
1196 *--bufp = d + L_('0');
1198 while (t != 0);
1200 digits = 1;
1201 goto do_number_sign_and_padding;
1204 case L_('X'):
1205 if (modifier == L_('O'))
1206 goto bad_format;
1207 #ifdef _NL_CURRENT
1208 if (! (modifier == L_('E')
1209 && (*(subfmt =
1210 (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT)))
1211 != L_('\0'))))
1212 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
1213 goto subformat;
1214 #else
1215 # if HAVE_STRFTIME
1216 goto underlying_strftime;
1217 # else
1218 /* Fall through. */
1219 # endif
1220 #endif
1221 case L_('T'):
1222 subfmt = L_("%H:%M:%S");
1223 goto subformat;
1225 case L_('t'):
1226 add (1, *p = L_('\t'));
1227 break;
1229 case L_('u'):
1230 DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
1232 case L_('U'):
1233 if (modifier == L_('E'))
1234 goto bad_format;
1236 DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
1238 case L_('V'):
1239 case L_('g'):
1240 case L_('G'):
1241 if (modifier == L_('E'))
1242 goto bad_format;
1244 int year = tp->tm_year + TM_YEAR_BASE;
1245 int days = iso_week_days (tp->tm_yday, tp->tm_wday);
1247 if (days < 0)
1249 /* This ISO week belongs to the previous year. */
1250 year--;
1251 days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
1252 tp->tm_wday);
1254 else
1256 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
1257 tp->tm_wday);
1258 if (0 <= d)
1260 /* This ISO week belongs to the next year. */
1261 year++;
1262 days = d;
1266 switch (*f)
1268 case L_('g'):
1269 DO_NUMBER (2, (year % 100 + 100) % 100);
1271 case L_('G'):
1272 DO_NUMBER (1, year);
1274 default:
1275 DO_NUMBER (2, days / 7 + 1);
1279 case L_('W'):
1280 if (modifier == L_('E'))
1281 goto bad_format;
1283 DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
1285 case L_('w'):
1286 if (modifier == L_('E'))
1287 goto bad_format;
1289 DO_NUMBER (1, tp->tm_wday);
1291 case L_('Y'):
1292 if (modifier == 'E')
1294 #if HAVE_STRUCT_ERA_ENTRY
1295 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1296 if (era)
1298 # ifdef COMPILE_WIDE
1299 subfmt = era->era_wformat;
1300 # else
1301 subfmt = era->era_format;
1302 # endif
1303 goto subformat;
1305 #else
1306 # if HAVE_STRFTIME
1307 goto underlying_strftime;
1308 # endif
1309 #endif
1311 if (modifier == L_('O'))
1312 goto bad_format;
1313 else
1314 DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
1316 case L_('y'):
1317 if (modifier == L_('E'))
1319 #if HAVE_STRUCT_ERA_ENTRY
1320 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1321 if (era)
1323 int delta = tp->tm_year - era->start_date[0];
1324 DO_NUMBER (1, (era->offset
1325 + delta * era->absolute_direction));
1327 #else
1328 # if HAVE_STRFTIME
1329 goto underlying_strftime;
1330 # endif
1331 #endif
1333 DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
1335 case L_('Z'):
1336 if (change_case)
1338 to_uppcase = 0;
1339 to_lowcase = 1;
1342 #if HAVE_TZNAME
1343 /* The tzset() call might have changed the value. */
1344 if (!(zone && *zone) && tp->tm_isdst >= 0)
1345 zone = tzname[tp->tm_isdst];
1346 #endif
1347 if (! zone)
1348 zone = "";
1350 #ifdef COMPILE_WIDE
1352 /* The zone string is always given in multibyte form. We have
1353 to transform it first. */
1354 wchar_t *wczone;
1355 size_t len;
1356 widen (zone, wczone, len);
1357 cpy (len, wczone);
1359 #else
1360 cpy (strlen (zone), zone);
1361 #endif
1362 break;
1364 case L_('z'):
1365 if (tp->tm_isdst < 0)
1366 break;
1369 int diff;
1370 #if HAVE_TM_GMTOFF
1371 diff = tp->tm_gmtoff;
1372 #else
1373 if (ut)
1374 diff = 0;
1375 else
1377 struct tm gtm;
1378 struct tm ltm;
1379 time_t lt;
1381 ltm = *tp;
1382 lt = mktime (&ltm);
1384 if (lt == (time_t) -1)
1386 /* mktime returns -1 for errors, but -1 is also a
1387 valid time_t value. Check whether an error really
1388 occurred. */
1389 struct tm tm;
1391 if (! my_strftime_localtime_r (&lt, &tm)
1392 || ((ltm.tm_sec ^ tm.tm_sec)
1393 | (ltm.tm_min ^ tm.tm_min)
1394 | (ltm.tm_hour ^ tm.tm_hour)
1395 | (ltm.tm_mday ^ tm.tm_mday)
1396 | (ltm.tm_mon ^ tm.tm_mon)
1397 | (ltm.tm_year ^ tm.tm_year)))
1398 break;
1401 if (! my_strftime_gmtime_r (&lt, &gtm))
1402 break;
1404 diff = tm_diff (&ltm, &gtm);
1406 #endif
1408 if (diff < 0)
1410 add (1, *p = L_('-'));
1411 diff = -diff;
1413 else
1414 add (1, *p = L_('+'));
1416 diff /= 60;
1417 DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
1420 case L_('\0'): /* GNU extension: % at end of format. */
1421 --f;
1422 /* Fall through. */
1423 default:
1424 /* Unknown format; output the format, including the '%',
1425 since this is most likely the right thing to do if a
1426 multibyte string has been misparsed. */
1427 bad_format:
1429 int flen;
1430 for (flen = 1; f[1 - flen] != L_('%'); flen++)
1431 continue;
1432 cpy (flen, &f[1 - flen]);
1434 break;
1438 if (p && maxsize != 0)
1439 *p = L_('\0');
1440 return i;
1442 #ifdef _LIBC
1443 libc_hidden_def (my_strftime)
1444 #endif
1447 #ifdef emacs
1448 /* For Emacs we have a separate interface which corresponds to the normal
1449 strftime function and does not have the extra information whether the
1450 TP arguments comes from a `gmtime' call or not. */
1451 size_t
1452 emacs_strftime (s, maxsize, format, tp)
1453 char *s;
1454 size_t maxsize;
1455 const char *format;
1456 const struct tm *tp;
1458 return my_strftime (s, maxsize, format, tp, 0);
1460 #endif