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"
37 #if defined emacs && !defined HAVE_BCOPY
38 # define HAVE_MEMCPY 1
42 #include <sys/types.h> /* Some systems define `time_t' here. */
44 #ifdef TIME_WITH_SYS_TIME
45 # include <sys/time.h>
48 # ifdef HAVE_SYS_TIME_H
49 # include <sys/time.h>
55 extern char *tzname[];
58 /* Do multibyte processing if multibytes are supported, unless
59 multibyte sequences are safe in formats. Multibyte sequences are
60 safe if they cannot contain byte sequences that look like format
61 conversion specifications. The GNU C Library uses UTF8 multibyte
62 encoding, which is safe for formats, but strftime.c can be used
63 with other C libraries that use unsafe encodings. */
64 #define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
70 /* Simulate mbrlen with mblen as best we can. */
71 # define mbstate_t int
72 # define mbrlen(s, n, ps) mblen (s, n)
73 # define mbsinit(ps) (*(ps) == 0)
75 static const mbstate_t mbstate_zero;
88 # define memcpy(d, s, n) bcopy ((s), (d), (n))
93 # if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
94 # define __P(args) args
116 #define TYPE_SIGNED(t) ((t) -1 < 0)
118 /* Bound on length of the string representing an integer value of type t.
119 Subtract one for the sign bit if t is signed;
120 302 / 1000 is log10 (2) rounded up;
121 add one for integer division truncation;
122 add one more for a minus sign if t is signed. */
123 #define INT_STRLEN_BOUND(t) \
124 ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 100 + 1 + TYPE_SIGNED (t))
126 #define TM_YEAR_BASE 1900
129 /* Nonzero if YEAR is a leap year (every 4 years,
130 except every 100th isn't, and every 400th is). */
131 # define __isleap(year) \
132 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
137 # define gmtime_r __gmtime_r
138 # define localtime_r __localtime_r
139 # define tzname __tzname
140 # define tzset __tzset
142 # if ! HAVE_LOCALTIME_R
143 # if ! HAVE_TM_GMTOFF
144 /* Approximate gmtime_r as best we can in its absence. */
146 # define gmtime_r my_gmtime_r
147 static struct tm *gmtime_r __P ((const time_t *, struct tm *));
153 struct tm *l = gmtime (t);
159 # endif /* ! HAVE_TM_GMTOFF */
161 /* Approximate localtime_r as best we can in its absence. */
163 # define localtime_r my_ftime_localtime_r
164 static struct tm *localtime_r __P ((const time_t *, struct tm *));
170 struct tm *l = localtime (t);
176 # endif /* ! HAVE_LOCALTIME_R */
177 #endif /* ! defined (_LIBC) */
180 #if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
181 /* Some systems lack the `memset' function and we don't want to
182 introduce additional dependencies. */
183 /* The SGI compiler reportedly barfs on the trailing null
184 if we use a string constant as the initializer. 28 June 1997, rms. */
185 static const char spaces[16] = /* " " */
186 { ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' };
187 static const char zeroes[16] = /* "0000000000000000" */
188 { '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0' };
190 # define memset_space(P, Len) \
196 int _this = _len > 16 ? 16 : _len; \
197 memcpy ((P), spaces, _this); \
204 # define memset_zero(P, Len) \
210 int _this = _len > 16 ? 16 : _len; \
211 memcpy ((P), zeroes, _this); \
218 # define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
219 # define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
226 int _delta = width - _n; \
227 int _incr = _n + (_delta > 0 ? _delta : 0); \
228 if (i + _incr >= maxsize) \
235 memset_zero (p, _delta); \
237 memset_space (p, _delta); \
248 memcpy_lowcase (p, (s), _n); \
249 else if (to_uppcase) \
250 memcpy_uppcase (p, (s), _n); \
252 memcpy ((PTR) p, (PTR) (s), _n))
257 # define TOUPPER(Ch) toupper (Ch)
258 # define TOLOWER(Ch) tolower (Ch)
260 # define TOUPPER(Ch) (islower (Ch) ? toupper (Ch) : (Ch))
261 # define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
263 /* We don't use `isdigit' here since the locale dependent
264 interpretation is not what we want here. We only need to accept
265 the arabic digits in the ASCII range. One day there is perhaps a
266 more reliable way to accept other sets of digits. */
267 #define ISDIGIT(Ch) ((unsigned int) (Ch) - '0' <= 9)
269 static char *memcpy_lowcase __P ((char *dest, const char *src, size_t len));
272 memcpy_lowcase (dest, src, len)
278 dest[len] = TOLOWER (src[len]);
282 static char *memcpy_uppcase __P ((char *dest, const char *src, size_t len));
285 memcpy_uppcase (dest, src, len)
291 dest[len] = TOUPPER (src[len]);
297 /* Yield the difference between *A and *B,
298 measured in seconds, ignoring leap seconds. */
299 # define tm_diff ftime_tm_diff
300 static int tm_diff __P ((const struct tm *, const struct tm *));
306 /* Compute intervening leap days correctly even if year is negative.
307 Take care to avoid int overflow in leap day calculations,
308 but it's OK to assume that A and B are close to each other. */
309 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
310 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
311 int a100 = a4 / 25 - (a4 % 25 < 0);
312 int b100 = b4 / 25 - (b4 % 25 < 0);
313 int a400 = a100 >> 2;
314 int b400 = b100 >> 2;
315 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
316 int years = a->tm_year - b->tm_year;
317 int days = (365 * years + intervening_leap_days
318 + (a->tm_yday - b->tm_yday));
319 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
320 + (a->tm_min - b->tm_min))
321 + (a->tm_sec - b->tm_sec));
323 #endif /* ! HAVE_TM_GMTOFF */
327 /* The number of days from the first day of the first ISO week of this
328 year to the year day YDAY with week day WDAY. ISO weeks start on
329 Monday; the first ISO week has the year's first Thursday. YDAY may
330 be as small as YDAY_MINIMUM. */
331 #define ISO_WEEK_START_WDAY 1 /* Monday */
332 #define ISO_WEEK1_WDAY 4 /* Thursday */
333 #define YDAY_MINIMUM (-366)
334 static int iso_week_days __P ((int, int));
339 iso_week_days (yday, wday)
343 /* Add enough to the first operand of % to make it nonnegative. */
344 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
346 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
347 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
352 static char const weekday_name[][10] =
354 "Sunday", "Monday", "Tuesday", "Wednesday",
355 "Thursday", "Friday", "Saturday"
357 static char const month_name[][10] =
359 "January", "February", "March", "April", "May", "June",
360 "July", "August", "September", "October", "November", "December"
365 #if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
366 /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
367 Work around this bug by copying *tp before it might be munged. */
368 size_t _strftime_copytm __P ((char *, size_t, const char *,
371 strftime (s, maxsize, format, tp)
379 return _strftime_copytm (s, maxsize, format, &tmcopy);
384 # define strftime(S, Maxsize, Format, Tp) \
385 _strftime_copytm (S, Maxsize, Format, Tp)
389 /* Write information from TP into S according to the format
390 string FORMAT, writing no more that MAXSIZE characters
391 (including the terminating '\0') and returning number of
392 characters written. If S is NULL, nothing will be written
393 anywhere, so to determine how many characters would be
394 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
396 strftime (s, maxsize, format, tp)
402 int hour12 = tp->tm_hour;
404 const char *const a_wkday = _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday);
405 const char *const f_wkday = _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday);
406 const char *const a_month = _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon);
407 const char *const f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon);
408 const char *const ampm = _NL_CURRENT (LC_TIME,
409 hour12 > 11 ? PM_STR : AM_STR);
410 size_t aw_len = strlen (a_wkday);
411 size_t am_len = strlen (a_month);
412 size_t ap_len = strlen (ampm);
414 const char *const f_wkday = weekday_name[tp->tm_wday];
415 const char *const f_month = month_name[tp->tm_mon];
416 const char *const a_wkday = f_wkday;
417 const char *const a_month = f_month;
418 const char *const ampm = "AMPM" + 2 * (hour12 > 11);
423 size_t wkday_len = strlen (f_wkday);
424 size_t month_len = strlen (f_month);
433 /* The POSIX test suite assumes that setting
434 the environment variable TZ to a new value before calling strftime()
435 will influence the result (the %Z format) even if the information in
436 TP is computed with a totally different time zone.
437 This is bogus: though POSIX allows bad behavior like this,
438 POSIX does not require it. Do the right thing instead. */
439 zone = (const char *) tp->tm_zone;
442 /* POSIX.1 8.1.1 requires that whenever strftime() is called, the
443 time zone names contained in the external variable `tzname' shall
444 be set as if the tzset() function had been called. */
449 if (!(zone && *zone) && tp->tm_isdst >= 0)
450 zone = tzname[tp->tm_isdst];
453 zone = ""; /* POSIX.2 requires the empty string here. */
455 zonelen = strlen (zone);
460 if (hour12 == 0) hour12 = 12;
462 for (f = format; *f != '\0'; ++f)
464 int pad; /* Padding for number ('-', '_', or 0). */
465 int modifier; /* Field modifier ('E', 'O', or 0). */
466 int digits; /* Max digits for numeric format. */
467 int number_value; /* Numeric value to be printed. */
468 int negative_number; /* 1 if the number is negative. */
471 char buf[1 + (sizeof (int) < sizeof (time_t)
472 ? INT_STRLEN_BOUND (time_t)
473 : INT_STRLEN_BOUND (int))];
486 case '\a': case '\b': case '\t': case '\n':
487 case '\v': case '\f': case '\r':
488 case ' ': case '!': case '"': case '#': case '&': case'\'':
489 case '(': case ')': case '*': case '+': case ',': case '-':
490 case '.': case '/': case '0': case '1': case '2': case '3':
491 case '4': case '5': case '6': case '7': case '8': case '9':
492 case ':': case ';': case '<': case '=': case '>': case '?':
493 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
494 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
495 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
496 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
497 case 'Y': case 'Z': case '[': case'\\': case ']': case '^':
498 case '_': case 'a': case 'b': case 'c': case 'd': case 'e':
499 case 'f': case 'g': case 'h': case 'i': case 'j': case 'k':
500 case 'l': case 'm': case 'n': case 'o': case 'p': case 'q':
501 case 'r': case 's': case 't': case 'u': case 'v': case 'w':
502 case 'x': case 'y': case 'z': case '{': case '|': case '}':
504 /* The C Standard requires these 98 characters (plus '%') to
505 be in the basic execution character set. None of these
506 characters can start a multibyte sequence, so they need
507 not be analyzed further. */
512 /* Copy this multibyte sequence until we reach its end, find
513 an error, or come back to the initial shift state. */
515 mbstate_t mbstate = mbstate_zero;
520 size_t bytes = mbrlen (f + len, (size_t) -1, &mbstate);
525 if (bytes == (size_t) -2 || bytes == (size_t) -1)
533 while (! mbsinit (&mbstate));
540 #else /* ! DO_MULTIBYTE */
542 /* Either multibyte encodings are not supported, or they are
543 safe for formats, so any non-'%' byte can be copied through. */
550 #endif /* ! DO_MULTIBYTE */
552 /* Check for flags that can modify a format. */
558 /* This influences the number formats. */
565 /* This changes textual output. */
579 /* As a GNU extension we allow to specify the field width. */
589 while (ISDIGIT (*f));
592 /* Check for modifiers. */
605 /* Now do the specified format. */
608 #define DO_NUMBER(d, v) \
609 digits = width == -1 ? d : width; \
610 number_value = v; goto do_number
611 #define DO_NUMBER_SPACEPAD(d, v) \
612 digits = width == -1 ? d : width; \
613 number_value = v; goto do_number_spacepad
629 cpy (aw_len, a_wkday);
640 cpy (wkday_len, f_wkday);
644 case 'h': /* POSIX.2 extension. */
647 cpy (am_len, a_month);
658 cpy (month_len, f_month);
665 if (! (modifier == 'E'
666 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT)) != '\0'))
667 subfmt = _NL_CURRENT (LC_TIME, D_T_FMT);
669 subfmt = "%a %b %e %H:%M:%S %Y";
675 size_t len = strftime (NULL, maxsize - i, subfmt, tp);
676 if (len == 0 && *subfmt)
678 add (len, strftime (p, maxsize - i, subfmt, tp));
681 while (old_start < p)
683 *old_start = TOUPPER (*old_start);
689 case 'C': /* POSIX.2 extension. */
692 #if HAVE_STRUCT_ERA_ENTRY
695 struct era_entry *era = _nl_get_era_entry (tp);
698 size_t len = strlen (era->name_fmt);
699 cpy (len, era->name_fmt);
705 int year = tp->tm_year + TM_YEAR_BASE;
706 DO_NUMBER (1, year / 100 - (year % 100 < 0));
713 if (! (modifier == 'E'
714 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_FMT)) != '\0'))
715 subfmt = _NL_CURRENT (LC_TIME, D_FMT);
719 case 'D': /* POSIX.2 extension. */
729 DO_NUMBER (2, tp->tm_mday);
731 case 'e': /* POSIX.2 extension. */
735 DO_NUMBER_SPACEPAD (2, tp->tm_mday);
737 /* All numeric formats set DIGITS and NUMBER_VALUE and then
738 jump to one of these two labels. */
741 /* Force `_' flag unless overwritten by `0' flag. */
746 /* Format the number according to the MODIFIER flag. */
749 if (modifier == 'O' && 0 <= number_value)
751 /* Get the locale specific alternate representation of
752 the number NUMBER_VALUE. If none exist NULL is returned. */
753 const char *cp = _nl_get_alt_digit (number_value);
757 size_t digitlen = strlen (cp);
767 unsigned int u = number_value;
769 bufp = buf + sizeof (buf);
770 negative_number = number_value < 0;
776 *--bufp = u % 10 + '0';
777 while ((u /= 10) != 0);
780 do_number_sign_and_padding:
786 int padding = digits - (buf + sizeof (buf) - bufp);
790 while (0 < padding--)
795 bufp += negative_number;
796 while (0 < padding--)
803 cpy (buf + sizeof (buf) - bufp, bufp);
811 DO_NUMBER (2, tp->tm_hour);
817 DO_NUMBER (2, hour12);
819 case 'k': /* GNU extension. */
823 DO_NUMBER_SPACEPAD (2, tp->tm_hour);
825 case 'l': /* GNU extension. */
829 DO_NUMBER_SPACEPAD (2, hour12);
835 DO_NUMBER (3, 1 + tp->tm_yday);
841 DO_NUMBER (2, tp->tm_min);
847 DO_NUMBER (2, tp->tm_mon + 1);
849 case 'n': /* POSIX.2 extension. */
866 case 'R': /* GNU extension. */
870 case 'r': /* POSIX.2 extension. */
872 if (*(subfmt = _NL_CURRENT (LC_TIME, T_FMT_AMPM)) == '\0')
874 subfmt = "%I:%M:%S %p";
881 DO_NUMBER (2, tp->tm_sec);
883 case 's': /* GNU extension. */
891 /* Generate string value for T using time_t arithmetic;
892 this works even if sizeof (long) < sizeof (time_t). */
894 bufp = buf + sizeof (buf);
895 negative_number = t < 0;
906 /* Adjust if division truncates to minus infinity. */
907 if (0 < -1 % 10 && d < 0)
919 goto do_number_sign_and_padding;
926 if (! (modifier == 'E'
927 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_T_FMT)) != '\0'))
928 subfmt = _NL_CURRENT (LC_TIME, T_FMT);
932 case 'T': /* POSIX.2 extension. */
936 case 't': /* POSIX.2 extension. */
940 case 'u': /* POSIX.2 extension. */
941 DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
947 DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
950 case 'g': /* GNU extension. */
951 case 'G': /* GNU extension. */
955 int year = tp->tm_year + TM_YEAR_BASE;
956 int days = iso_week_days (tp->tm_yday, tp->tm_wday);
960 /* This ISO week belongs to the previous year. */
962 days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
967 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
971 /* This ISO week belongs to the next year. */
980 DO_NUMBER (2, (year % 100 + 100) % 100);
986 DO_NUMBER (2, days / 7 + 1);
994 DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
1000 DO_NUMBER (1, tp->tm_wday);
1003 #if HAVE_STRUCT_ERA_ENTRY
1004 if (modifier == 'E')
1006 struct era_entry *era = _nl_get_era_entry (tp);
1009 subfmt = strchr (era->name_fmt, '\0') + 1;
1014 if (modifier == 'O')
1017 DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
1020 #if HAVE_STRUCT_ERA_ENTRY
1021 if (modifier == 'E')
1023 struct era_entry *era = _nl_get_era_entry (tp);
1026 int delta = tp->tm_year - era->start_date[0];
1027 DO_NUMBER (1, (era->offset
1028 + (era->direction == '-' ? -delta : delta)));
1032 DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
1040 cpy (zonelen, zone);
1043 case 'z': /* GNU extension. */
1044 if (tp->tm_isdst < 0)
1050 diff = tp->tm_gmtoff;
1059 if (lt == (time_t) -1)
1061 /* mktime returns -1 for errors, but -1 is also a
1062 valid time_t value. Check whether an error really
1065 localtime_r (<, &tm);
1067 if ((ltm.tm_sec ^ tm.tm_sec)
1068 | (ltm.tm_min ^ tm.tm_min)
1069 | (ltm.tm_hour ^ tm.tm_hour)
1070 | (ltm.tm_mday ^ tm.tm_mday)
1071 | (ltm.tm_mon ^ tm.tm_mon)
1072 | (ltm.tm_year ^ tm.tm_year))
1076 if (! gmtime_r (<, >m))
1079 diff = tm_diff (<m, >m);
1091 DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
1094 case '\0': /* GNU extension: % at end of format. */
1098 /* Unknown format; output the format, including the '%',
1099 since this is most likely the right thing to do if a
1100 multibyte string has been misparsed. */
1104 for (flen = 1; f[1 - flen] != '%'; flen++)
1106 cpy (flen, &f[1 - flen]);