1 /* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 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 Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 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 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
24 # define HAVE_LIMITS_H 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
32 # define MULTIBYTE_IS_FORMAT_SAFE 1
33 # define STDC_HEADERS 1
34 # include "../locale/localeinfo.h"
38 #include <sys/types.h> /* Some systems define `time_t' here. */
40 #ifdef TIME_WITH_SYS_TIME
41 # include <sys/time.h>
44 # ifdef HAVE_SYS_TIME_H
45 # include <sys/time.h>
51 extern char *tzname[];
54 /* Do multibyte processing if multibytes are supported, unless
55 multibyte sequences are safe in formats. Multibyte sequences are
56 safe if they cannot contain byte sequences that look like format
57 conversion specifications. The GNU C Library uses UTF8 multibyte
58 encoding, which is safe for formats, but strftime.c can be used
59 with other C libraries that use unsafe encodings. */
60 #define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
66 /* Simulate mbrlen with mblen as best we can. */
67 # define mbstate_t int
68 # define mbrlen(s, n, ps) mblen (s, n)
69 # define mbsinit(ps) (*(ps) == 0)
71 static const mbstate_t mbstate_zero;
84 # define memcpy(d, s, n) bcopy ((s), (d), (n))
89 # if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
90 # define __P(args) args
112 #define TYPE_SIGNED(t) ((t) -1 < 0)
114 /* Bound on length of the string representing an integer value of type t.
115 Subtract one for the sign bit if t is signed;
116 302 / 1000 is log10 (2) rounded up;
117 add one for integer division truncation;
118 add one more for a minus sign if t is signed. */
119 #define INT_STRLEN_BOUND(t) \
120 ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 100 + 1 + TYPE_SIGNED (t))
122 #define TM_YEAR_BASE 1900
125 /* Nonzero if YEAR is a leap year (every 4 years,
126 except every 100th isn't, and every 400th is). */
127 # define __isleap(year) \
128 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
133 # define gmtime_r __gmtime_r
134 # define localtime_r __localtime_r
135 extern int __tz_compute __P ((time_t timer, const struct tm *tm));
136 # define tzname __tzname
137 # define tzset __tzset
139 # if ! HAVE_LOCALTIME_R
140 # if ! HAVE_TM_GMTOFF
141 /* Approximate gmtime_r as best we can in its absence. */
142 # define gmtime_r my_gmtime_r
143 static struct tm *gmtime_r __P ((const time_t *, struct tm *));
149 struct tm *l = gmtime (t);
155 # endif /* ! HAVE_TM_GMTOFF */
157 /* Approximate localtime_r as best we can in its absence. */
158 # define localtime_r my_ftime_localtime_r
159 static struct tm *localtime_r __P ((const time_t *, struct tm *));
165 struct tm *l = localtime (t);
171 # endif /* ! HAVE_LOCALTIME_R */
172 #endif /* ! defined (_LIBC) */
175 #if !defined (memset) && !defined (HAVE_MEMSET) && !defined (_LIBC)
176 /* Some systems lack the `memset' function and we don't want to
177 introduce additional dependencies. */
178 static const char spaces[16] = " ";
179 static const char zeroes[16] = "0000000000000000";
181 # define memset_space(P, Len) \
187 int _this = _len > 16 ? 16 : _len; \
188 memcpy ((P), spaces, _this); \
195 # define memset_zero(P, Len) \
201 int _this = _len > 16 ? 16 : _len; \
202 memcpy ((P), zeroes, _this); \
209 # define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
210 # define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
217 int _delta = width - _n; \
218 int _incr = _n + (_delta > 0 ? _delta : 0); \
219 if (i + _incr >= maxsize) \
226 memset_zero (p, _delta); \
228 memset_space (p, _delta); \
239 memcpy_lowcase (p, (s), _n); \
240 else if (to_uppcase) \
241 memcpy_uppcase (p, (s), _n); \
243 memcpy ((PTR) p, (PTR) (s), _n))
248 # define TOUPPER(Ch) toupper (Ch)
249 # define TOLOWER(Ch) tolower (Ch)
251 # define TOUPPER(Ch) (islower (Ch) ? toupper (Ch) : (Ch))
252 # define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
254 /* We don't use `isdigit' here since the locale dependent
255 interpretation is not what we want here. We only need to accept
256 the arabic digits in the ASCII range. One day there is perhaps a
257 more reliable way to accept other sets of digits. */
258 #define ISDIGIT(Ch) ((unsigned int) (Ch) - '0' <= 9)
260 static char *memcpy_lowcase __P ((char *dest, const char *src, size_t len));
263 memcpy_lowcase (dest, src, len)
269 dest[len] = TOLOWER (src[len]);
273 static char *memcpy_uppcase __P ((char *dest, const char *src, size_t len));
276 memcpy_uppcase (dest, src, len)
282 dest[len] = TOUPPER (src[len]);
288 /* Yield the difference between *A and *B,
289 measured in seconds, ignoring leap seconds. */
290 # define tm_diff ftime_tm_diff
291 static int tm_diff __P ((const struct tm *, const struct tm *));
297 /* Compute intervening leap days correctly even if year is negative.
298 Take care to avoid int overflow in leap day calculations,
299 but it's OK to assume that A and B are close to each other. */
300 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
301 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
302 int a100 = a4 / 25 - (a4 % 25 < 0);
303 int b100 = b4 / 25 - (b4 % 25 < 0);
304 int a400 = a100 >> 2;
305 int b400 = b100 >> 2;
306 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
307 int years = a->tm_year - b->tm_year;
308 int days = (365 * years + intervening_leap_days
309 + (a->tm_yday - b->tm_yday));
310 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
311 + (a->tm_min - b->tm_min))
312 + (a->tm_sec - b->tm_sec));
314 #endif /* ! HAVE_TM_GMTOFF */
318 /* The number of days from the first day of the first ISO week of this
319 year to the year day YDAY with week day WDAY. ISO weeks start on
320 Monday; the first ISO week has the year's first Thursday. YDAY may
321 be as small as YDAY_MINIMUM. */
322 #define ISO_WEEK_START_WDAY 1 /* Monday */
323 #define ISO_WEEK1_WDAY 4 /* Thursday */
324 #define YDAY_MINIMUM (-366)
325 static int iso_week_days __P ((int, int));
330 iso_week_days (yday, wday)
334 /* Add enough to the first operand of % to make it nonnegative. */
335 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
337 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
338 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
343 static char const weekday_name[][10] =
345 "Sunday", "Monday", "Tuesday", "Wednesday",
346 "Thursday", "Friday", "Saturday"
348 static char const month_name[][10] =
350 "January", "February", "March", "April", "May", "June",
351 "July", "August", "September", "October", "November", "December"
356 #if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
357 /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
358 Work around this bug by copying *tp before it might be munged. */
359 size_t _strftime_copytm __P ((char *, size_t, const char *,
362 strftime (s, maxsize, format, tp)
370 return _strftime_copytm (s, maxsize, format, &tmcopy);
375 # define strftime(S, Maxsize, Format, Tp) \
376 _strftime_copytm (S, Maxsize, Format, Tp)
380 /* Write information from TP into S according to the format
381 string FORMAT, writing no more that MAXSIZE characters
382 (including the terminating '\0') and returning number of
383 characters written. If S is NULL, nothing will be written
384 anywhere, so to determine how many characters would be
385 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
387 strftime (s, maxsize, format, tp)
393 int hour12 = tp->tm_hour;
395 const char *const a_wkday = _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday);
396 const char *const f_wkday = _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday);
397 const char *const a_month = _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon);
398 const char *const f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon);
399 const char *const ampm = _NL_CURRENT (LC_TIME,
400 hour12 > 11 ? PM_STR : AM_STR);
401 size_t aw_len = strlen (a_wkday);
402 size_t am_len = strlen (a_month);
403 size_t ap_len = strlen (ampm);
405 const char *const f_wkday = weekday_name[tp->tm_wday];
406 const char *const f_month = month_name[tp->tm_mon];
407 const char *const a_wkday = f_wkday;
408 const char *const a_month = f_month;
409 const char *const ampm = "AMPM" + 2 * (hour12 > 11);
414 size_t wkday_len = strlen (f_wkday);
415 size_t month_len = strlen (f_month);
423 #if !defined _LIBC && HAVE_TM_ZONE
424 /* XXX We have some problems here. First, the string pointed to by
425 tm_zone is dynamically allocated while loading the zone data. But
426 when another zone is loaded since the information in TP were
427 computed this would be a stale pointer.
428 The second problem is the POSIX test suite which assumes setting
429 the environment variable TZ to a new value before calling strftime()
430 will influence the result (the %Z format) even if the information in
431 TP is computed with a totally different time zone. --drepper@gnu */
432 zone = (const char *) tp->tm_zone;
435 /* POSIX.1 8.1.1 requires that whenever strftime() is called, the
436 time zone names contained in the external variable `tzname' shall
437 be set as if the tzset() function had been called. */
442 if (!(zone && *zone) && tp->tm_isdst >= 0)
443 zone = tzname[tp->tm_isdst];
446 zone = ""; /* POSIX.2 requires the empty string here. */
448 zonelen = strlen (zone);
453 if (hour12 == 0) hour12 = 12;
455 for (f = format; *f != '\0'; ++f)
457 int pad; /* Padding for number ('-', '_', or 0). */
458 int modifier; /* Field modifier ('E', 'O', or 0). */
459 int digits; /* Max digits for numeric format. */
460 int number_value; /* Numeric value to be printed. */
461 int negative_number; /* 1 if the number is negative. */
464 char buf[1 + (sizeof (int) < sizeof (time_t)
465 ? INT_STRLEN_BOUND (time_t)
466 : INT_STRLEN_BOUND (int))];
479 case '\a': case '\b': case '\t': case '\n':
480 case '\v': case '\f': case '\r':
481 case ' ': case '!': case '"': case '#': case '&': case'\'':
482 case '(': case ')': case '*': case '+': case ',': case '-':
483 case '.': case '/': case '0': case '1': case '2': case '3':
484 case '4': case '5': case '6': case '7': case '8': case '9':
485 case ':': case ';': case '<': case '=': case '>': case '?':
486 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
487 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
488 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
489 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
490 case 'Y': case 'Z': case '[': case'\\': case ']': case '^':
491 case '_': case 'a': case 'b': case 'c': case 'd': case 'e':
492 case 'f': case 'g': case 'h': case 'i': case 'j': case 'k':
493 case 'l': case 'm': case 'n': case 'o': case 'p': case 'q':
494 case 'r': case 's': case 't': case 'u': case 'v': case 'w':
495 case 'x': case 'y': case 'z': case '{': case '|': case '}':
497 /* The C Standard requires these 98 characters (plus '%') to
498 be in the basic execution character set. None of these
499 characters can start a multibyte sequence, so they need
500 not be analyzed further. */
505 /* Copy this multibyte sequence until we reach its end, find
506 an error, or come back to the initial shift state. */
508 mbstate_t mbstate = mbstate_zero;
513 size_t bytes = mbrlen (f + len, (size_t) -1, &mbstate);
518 if (bytes == (size_t) -2 || bytes == (size_t) -1)
526 while (! mbsinit (&mbstate));
533 #else /* ! DO_MULTIBYTE */
535 /* Either multibyte encodings are not supported, or they are
536 safe for formats, so any non-'%' byte can be copied through. */
543 #endif /* ! DO_MULTIBYTE */
545 /* Check for flags that can modify a format. */
551 /* This influences the number formats. */
558 /* This changes textual output. */
572 /* As a GNU extension we allow to specify the field width. */
582 while (ISDIGIT (*f));
585 /* Check for modifiers. */
598 /* Now do the specified format. */
601 #define DO_NUMBER(d, v) \
602 digits = width == -1 ? d : width; \
603 number_value = v; goto do_number
604 #define DO_NUMBER_SPACEPAD(d, v) \
605 digits = width == -1 ? d : width; \
606 number_value = v; goto do_number_spacepad
622 cpy (aw_len, a_wkday);
633 cpy (wkday_len, f_wkday);
637 case 'h': /* POSIX.2 extension. */
640 cpy (am_len, a_month);
651 cpy (month_len, f_month);
658 if (! (modifier == 'E'
659 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT)) != '\0'))
660 subfmt = _NL_CURRENT (LC_TIME, D_T_FMT);
662 subfmt = "%a %b %e %H:%M:%S %Y";
668 size_t len = strftime (NULL, maxsize - i, subfmt, tp);
669 if (len == 0 && *subfmt)
671 add (len, strftime (p, maxsize - i, subfmt, tp));
674 while (old_start < p)
676 *old_start = TOUPPER (*old_start);
682 case 'C': /* POSIX.2 extension. */
685 #if HAVE_STRUCT_ERA_ENTRY
688 struct era_entry *era = _nl_get_era_entry (tp);
691 size_t len = strlen (era->name_fmt);
692 cpy (len, era->name_fmt);
698 int year = tp->tm_year + TM_YEAR_BASE;
699 DO_NUMBER (1, year / 100 - (year % 100 < 0));
706 if (! (modifier == 'E'
707 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_FMT)) != '\0'))
708 subfmt = _NL_CURRENT (LC_TIME, D_FMT);
712 case 'D': /* POSIX.2 extension. */
722 DO_NUMBER (2, tp->tm_mday);
724 case 'e': /* POSIX.2 extension. */
728 DO_NUMBER_SPACEPAD (2, tp->tm_mday);
730 /* All numeric formats set DIGITS and NUMBER_VALUE and then
731 jump to one of these two labels. */
734 /* Force `_' flag unless overwritten by `0' flag. */
739 /* Format the number according to the MODIFIER flag. */
742 if (modifier == 'O' && 0 <= number_value)
744 /* Get the locale specific alternate representation of
745 the number NUMBER_VALUE. If none exist NULL is returned. */
746 const char *cp = _nl_get_alt_digit (number_value);
750 size_t digitlen = strlen (cp);
760 unsigned int u = number_value;
762 bufp = buf + sizeof (buf);
763 negative_number = number_value < 0;
769 *--bufp = u % 10 + '0';
770 while ((u /= 10) != 0);
773 do_number_sign_and_padding:
779 int padding = digits - (buf + sizeof (buf) - bufp);
783 while (0 < padding--)
788 bufp += negative_number;
789 while (0 < padding--)
796 cpy (buf + sizeof (buf) - bufp, bufp);
804 DO_NUMBER (2, tp->tm_hour);
810 DO_NUMBER (2, hour12);
812 case 'k': /* GNU extension. */
816 DO_NUMBER_SPACEPAD (2, tp->tm_hour);
818 case 'l': /* GNU extension. */
822 DO_NUMBER_SPACEPAD (2, hour12);
828 DO_NUMBER (3, 1 + tp->tm_yday);
834 DO_NUMBER (2, tp->tm_min);
840 DO_NUMBER (2, tp->tm_mon + 1);
842 case 'n': /* POSIX.2 extension. */
859 case 'R': /* GNU extension. */
863 case 'r': /* POSIX.2 extension. */
865 if (*(subfmt = _NL_CURRENT (LC_TIME, T_FMT_AMPM)) == '\0')
867 subfmt = "%I:%M:%S %p";
874 DO_NUMBER (2, tp->tm_sec);
876 case 's': /* GNU extension. */
884 /* Generate string value for T using time_t arithmetic;
885 this works even if sizeof (long) < sizeof (time_t). */
887 bufp = buf + sizeof (buf);
888 negative_number = t < 0;
899 /* Adjust if division truncates to minus infinity. */
900 if (0 < -1 % 10 && d < 0)
912 goto do_number_sign_and_padding;
919 if (! (modifier == 'E'
920 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_T_FMT)) != '\0'))
921 subfmt = _NL_CURRENT (LC_TIME, T_FMT);
925 case 'T': /* POSIX.2 extension. */
929 case 't': /* POSIX.2 extension. */
933 case 'u': /* POSIX.2 extension. */
934 DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
940 DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
943 case 'g': /* GNU extension. */
944 case 'G': /* GNU extension. */
948 int year = tp->tm_year + TM_YEAR_BASE;
949 int days = iso_week_days (tp->tm_yday, tp->tm_wday);
953 /* This ISO week belongs to the previous year. */
955 days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
960 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
964 /* This ISO week belongs to the next year. */
973 DO_NUMBER (2, (year % 100 + 100) % 100);
979 DO_NUMBER (2, days / 7 + 1);
987 DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
993 DO_NUMBER (1, tp->tm_wday);
996 #if HAVE_STRUCT_ERA_ENTRY
999 struct era_entry *era = _nl_get_era_entry (tp);
1002 subfmt = strchr (era->name_fmt, '\0') + 1;
1007 if (modifier == 'O')
1010 DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
1013 #if HAVE_STRUCT_ERA_ENTRY
1014 if (modifier == 'E')
1016 struct era_entry *era = _nl_get_era_entry (tp);
1019 int delta = tp->tm_year - era->start_date[0];
1020 DO_NUMBER (1, (era->offset
1021 + (era->direction == '-' ? -delta : delta)));
1025 DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
1033 cpy (zonelen, zone);
1036 case 'z': /* GNU extension. */
1037 if (tp->tm_isdst < 0)
1043 diff = tp->tm_gmtoff;
1052 if (lt == (time_t) -1)
1054 /* mktime returns -1 for errors, but -1 is also a
1055 valid time_t value. Check whether an error really
1058 localtime_r (<, &tm);
1060 if ((ltm.tm_sec ^ tm.tm_sec)
1061 | (ltm.tm_min ^ tm.tm_min)
1062 | (ltm.tm_hour ^ tm.tm_hour)
1063 | (ltm.tm_mday ^ tm.tm_mday)
1064 | (ltm.tm_mon ^ tm.tm_mon)
1065 | (ltm.tm_year ^ tm.tm_year))
1069 if (! gmtime_r (<, >m))
1072 diff = tm_diff (<m, >m);
1084 DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
1087 case '\0': /* GNU extension: % at end of format. */
1091 /* Unknown format; output the format, including the '%',
1092 since this is most likely the right thing to do if a
1093 multibyte string has been misparsed. */
1097 for (flen = 1; f[1 - flen] != '%'; flen++)
1099 cpy (flen, &f[1 - flen]);