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;
83 # define memcpy(d, s, n) bcopy ((s), (d), (n))
87 # if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
88 # define __P(args) args
110 #define TYPE_SIGNED(t) ((t) -1 < 0)
112 /* Bound on length of the string representing an integer value of type t.
113 Subtract one for the sign bit if t is signed;
114 302 / 1000 is log10 (2) rounded up;
115 add one for integer division truncation;
116 add one more for a minus sign if t is signed. */
117 #define INT_STRLEN_BOUND(t) \
118 ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 100 + 1 + TYPE_SIGNED (t))
120 #define TM_YEAR_BASE 1900
123 /* Nonzero if YEAR is a leap year (every 4 years,
124 except every 100th isn't, and every 400th is). */
125 # define __isleap(year) \
126 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
131 # define gmtime_r __gmtime_r
132 # define localtime_r __localtime_r
133 extern int __tz_compute __P ((time_t timer, const struct tm *tm));
134 # define tzname __tzname
135 # define tzset __tzset
137 # if ! HAVE_LOCALTIME_R
138 # if ! HAVE_TM_GMTOFF
139 /* Approximate gmtime_r as best we can in its absence. */
140 # define gmtime_r my_gmtime_r
141 static struct tm *gmtime_r __P ((const time_t *, struct tm *));
147 struct tm *l = gmtime (t);
153 # endif /* ! HAVE_TM_GMTOFF */
155 /* Approximate localtime_r as best we can in its absence. */
156 # define localtime_r my_localtime_r
157 static struct tm *localtime_r __P ((const time_t *, struct tm *));
163 struct tm *l = localtime (t);
169 # endif /* ! HAVE_LOCALTIME_R */
170 #endif /* ! defined (_LIBC) */
173 #if !defined (memset) && !defined (HAVE_MEMSET) && !defined (_LIBC)
174 /* Some systems lack the `memset' function and we don't want to
175 introduce additional dependencies. */
176 static const char spaces[16] = " ";
177 static const char zeroes[16] = "0000000000000000";
179 # define memset_space(P, Len) \
185 int _this = _len > 16 ? 16 : _len; \
186 memcpy ((P), spaces, _this); \
193 # define memset_zero(P, Len) \
199 int _this = _len > 16 ? 16 : _len; \
200 memcpy ((P), zeroes, _this); \
207 # define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
208 # define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
215 int _delta = width - _n; \
216 int _incr = _n + (_delta > 0 ? _delta : 0); \
217 if (i + _incr >= maxsize) \
224 memset_zero (p, _delta); \
226 memset_space (p, _delta); \
237 memcpy_lowcase (p, (s), _n); \
238 else if (to_uppcase) \
239 memcpy_uppcase (p, (s), _n); \
241 memcpy ((PTR) p, (PTR) (s), _n))
246 # define TOUPPER(Ch) toupper (Ch)
247 # define TOLOWER(Ch) tolower (Ch)
249 # define TOUPPER(Ch) (islower (Ch) ? toupper (Ch) : (Ch))
250 # define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
252 /* We don't use `isdigit' here since the locale dependent
253 interpretation is not what we want here. We only need to accept
254 the arabic digits in the ASCII range. One day there is perhaps a
255 more reliable way to accept other sets of digits. */
256 #define ISDIGIT(Ch) ((unsigned int) (Ch) - '0' <= 9)
258 static char *memcpy_lowcase __P ((char *dest, const char *src, size_t len));
261 memcpy_lowcase (dest, src, len)
267 dest[len] = TOLOWER (src[len]);
271 static char *memcpy_uppcase __P ((char *dest, const char *src, size_t len));
274 memcpy_uppcase (dest, src, len)
280 dest[len] = TOUPPER (src[len]);
286 /* Yield the difference between *A and *B,
287 measured in seconds, ignoring leap seconds. */
288 static int tm_diff __P ((const struct tm *, const struct tm *));
294 /* Compute intervening leap days correctly even if year is negative.
295 Take care to avoid int overflow in leap day calculations,
296 but it's OK to assume that A and B are close to each other. */
297 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
298 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
299 int a100 = a4 / 25 - (a4 % 25 < 0);
300 int b100 = b4 / 25 - (b4 % 25 < 0);
301 int a400 = a100 >> 2;
302 int b400 = b100 >> 2;
303 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
304 int years = a->tm_year - b->tm_year;
305 int days = (365 * years + intervening_leap_days
306 + (a->tm_yday - b->tm_yday));
307 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
308 + (a->tm_min - b->tm_min))
309 + (a->tm_sec - b->tm_sec));
311 #endif /* ! HAVE_TM_GMTOFF */
315 /* The number of days from the first day of the first ISO week of this
316 year to the year day YDAY with week day WDAY. ISO weeks start on
317 Monday; the first ISO week has the year's first Thursday. YDAY may
318 be as small as YDAY_MINIMUM. */
319 #define ISO_WEEK_START_WDAY 1 /* Monday */
320 #define ISO_WEEK1_WDAY 4 /* Thursday */
321 #define YDAY_MINIMUM (-366)
322 static int iso_week_days __P ((int, int));
327 iso_week_days (yday, wday)
331 /* Add enough to the first operand of % to make it nonnegative. */
332 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
334 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
335 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
340 static char const weekday_name[][10] =
342 "Sunday", "Monday", "Tuesday", "Wednesday",
343 "Thursday", "Friday", "Saturday"
345 static char const month_name[][10] =
347 "January", "February", "March", "April", "May", "June",
348 "July", "August", "September", "October", "November", "December"
353 #if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
354 /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
355 Work around this bug by copying *tp before it might be munged. */
356 size_t _strftime_copytm __P ((char *, size_t, const char *,
359 strftime (s, maxsize, format, tp)
367 return _strftime_copytm (s, maxsize, format, &tmcopy);
372 # define strftime(S, Maxsize, Format, Tp) \
373 _strftime_copytm (S, Maxsize, Format, Tp)
377 /* Write information from TP into S according to the format
378 string FORMAT, writing no more that MAXSIZE characters
379 (including the terminating '\0') and returning number of
380 characters written. If S is NULL, nothing will be written
381 anywhere, so to determine how many characters would be
382 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
384 strftime (s, maxsize, format, tp)
390 int hour12 = tp->tm_hour;
392 const char *const a_wkday = _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday);
393 const char *const f_wkday = _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday);
394 const char *const a_month = _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon);
395 const char *const f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon);
396 const char *const ampm = _NL_CURRENT (LC_TIME,
397 hour12 > 11 ? PM_STR : AM_STR);
398 size_t aw_len = strlen (a_wkday);
399 size_t am_len = strlen (a_month);
400 size_t ap_len = strlen (ampm);
402 const char *const f_wkday = weekday_name[tp->tm_wday];
403 const char *const f_month = month_name[tp->tm_mon];
404 const char *const a_wkday = f_wkday;
405 const char *const a_month = f_month;
406 const char *const ampm = "AMPM" + 2 * (hour12 > 11);
411 size_t wkday_len = strlen (f_wkday);
412 size_t month_len = strlen (f_month);
420 #if !defined _LIBC && HAVE_TM_ZONE
421 /* XXX We have some problems here. First, the string pointed to by
422 tm_zone is dynamically allocated while loading the zone data. But
423 when another zone is loaded since the information in TP were
424 computed this would be a stale pointer.
425 The second problem is the POSIX test suite which assumes setting
426 the environment variable TZ to a new value before calling strftime()
427 will influence the result (the %Z format) even if the information in
428 TP is computed with a totally different time zone. --drepper@gnu */
429 zone = (const char *) tp->tm_zone;
432 /* POSIX.1 8.1.1 requires that whenever strftime() is called, the
433 time zone names contained in the external variable `tzname' shall
434 be set as if the tzset() function had been called. */
439 if (!(zone && *zone) && tp->tm_isdst >= 0)
440 zone = tzname[tp->tm_isdst];
443 zone = ""; /* POSIX.2 requires the empty string here. */
445 zonelen = strlen (zone);
450 if (hour12 == 0) hour12 = 12;
452 for (f = format; *f != '\0'; ++f)
454 int pad; /* Padding for number ('-', '_', or 0). */
455 int modifier; /* Field modifier ('E', 'O', or 0). */
456 int digits; /* Max digits for numeric format. */
457 int number_value; /* Numeric value to be printed. */
458 int negative_number; /* 1 if the number is negative. */
461 char buf[1 + (sizeof (int) < sizeof (time_t)
462 ? INT_STRLEN_BOUND (time_t)
463 : INT_STRLEN_BOUND (int))];
476 case '\a': case '\b': case '\t': case '\n':
477 case '\v': case '\f': case '\r':
478 case ' ': case '!': case '"': case '#': case '&': case'\'':
479 case '(': case ')': case '*': case '+': case ',': case '-':
480 case '.': case '/': case '0': case '1': case '2': case '3':
481 case '4': case '5': case '6': case '7': case '8': case '9':
482 case ':': case ';': case '<': case '=': case '>': case '?':
483 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
484 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
485 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
486 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
487 case 'Y': case 'Z': case '[': case'\\': case ']': case '^':
488 case '_': case 'a': case 'b': case 'c': case 'd': case 'e':
489 case 'f': case 'g': case 'h': case 'i': case 'j': case 'k':
490 case 'l': case 'm': case 'n': case 'o': case 'p': case 'q':
491 case 'r': case 's': case 't': case 'u': case 'v': case 'w':
492 case 'x': case 'y': case 'z': case '{': case '|': case '}':
494 /* The C Standard requires these 98 characters (plus '%') to
495 be in the basic execution character set. None of these
496 characters can start a multibyte sequence, so they need
497 not be analyzed further. */
502 /* Copy this multibyte sequence until we reach its end, find
503 an error, or come back to the initial shift state. */
505 mbstate_t mbstate = mbstate_zero;
510 size_t bytes = mbrlen (f + len, (size_t) -1, &mbstate);
515 if (bytes == (size_t) -2 || bytes == (size_t) -1)
523 while (! mbsinit (&mbstate));
530 #else /* ! DO_MULTIBYTE */
532 /* Either multibyte encodings are not supported, or they are
533 safe for formats, so any non-'%' byte can be copied through. */
540 #endif /* ! DO_MULTIBYTE */
542 /* Check for flags that can modify a format. */
548 /* This influences the number formats. */
555 /* This changes textual output. */
569 /* As a GNU extension we allow to specify the field width. */
579 while (ISDIGIT (*f));
582 /* Check for modifiers. */
595 /* Now do the specified format. */
598 #define DO_NUMBER(d, v) \
599 digits = width == -1 ? d : width; \
600 number_value = v; goto do_number
601 #define DO_NUMBER_SPACEPAD(d, v) \
602 digits = width == -1 ? d : width; \
603 number_value = v; goto do_number_spacepad
619 cpy (aw_len, a_wkday);
630 cpy (wkday_len, f_wkday);
634 case 'h': /* POSIX.2 extension. */
637 cpy (am_len, a_month);
648 cpy (month_len, f_month);
655 if (! (modifier == 'E'
656 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT)) != '\0'))
657 subfmt = _NL_CURRENT (LC_TIME, D_T_FMT);
659 subfmt = "%a %b %e %H:%M:%S %Y";
665 size_t len = strftime (NULL, maxsize - i, subfmt, tp);
666 if (len == 0 && *subfmt)
668 add (len, strftime (p, maxsize - i, subfmt, tp));
671 while (old_start < p)
673 *old_start = TOUPPER (*old_start);
679 case 'C': /* POSIX.2 extension. */
682 #if HAVE_STRUCT_ERA_ENTRY
685 struct era_entry *era = _nl_get_era_entry (tp);
688 size_t len = strlen (era->name_fmt);
689 cpy (len, era->name_fmt);
695 int year = tp->tm_year + TM_YEAR_BASE;
696 DO_NUMBER (1, year / 100 - (year % 100 < 0));
703 if (! (modifier == 'E'
704 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_FMT)) != '\0'))
705 subfmt = _NL_CURRENT (LC_TIME, D_FMT);
709 case 'D': /* POSIX.2 extension. */
719 DO_NUMBER (2, tp->tm_mday);
721 case 'e': /* POSIX.2 extension. */
725 DO_NUMBER_SPACEPAD (2, tp->tm_mday);
727 /* All numeric formats set DIGITS and NUMBER_VALUE and then
728 jump to one of these two labels. */
731 /* Force `_' flag unless overwritten by `0' flag. */
736 /* Format the number according to the MODIFIER flag. */
739 if (modifier == 'O' && 0 <= number_value)
741 /* Get the locale specific alternate representation of
742 the number NUMBER_VALUE. If none exist NULL is returned. */
743 const char *cp = _nl_get_alt_digit (number_value);
747 size_t digitlen = strlen (cp);
757 unsigned int u = number_value;
759 bufp = buf + sizeof (buf);
760 negative_number = number_value < 0;
766 *--bufp = u % 10 + '0';
767 while ((u /= 10) != 0);
770 do_number_sign_and_padding:
776 int padding = digits - (buf + sizeof (buf) - bufp);
780 while (0 < padding--)
785 bufp += negative_number;
786 while (0 < padding--)
793 cpy (buf + sizeof (buf) - bufp, bufp);
801 DO_NUMBER (2, tp->tm_hour);
807 DO_NUMBER (2, hour12);
809 case 'k': /* GNU extension. */
813 DO_NUMBER_SPACEPAD (2, tp->tm_hour);
815 case 'l': /* GNU extension. */
819 DO_NUMBER_SPACEPAD (2, hour12);
825 DO_NUMBER (3, 1 + tp->tm_yday);
831 DO_NUMBER (2, tp->tm_min);
837 DO_NUMBER (2, tp->tm_mon + 1);
839 case 'n': /* POSIX.2 extension. */
856 case 'R': /* GNU extension. */
860 case 'r': /* POSIX.2 extension. */
862 if (*(subfmt = _NL_CURRENT (LC_TIME, T_FMT_AMPM)) == '\0')
864 subfmt = "%I:%M:%S %p";
871 DO_NUMBER (2, tp->tm_sec);
873 case 's': /* GNU extension. */
881 /* Generate string value for T using time_t arithmetic;
882 this works even if sizeof (long) < sizeof (time_t). */
884 bufp = buf + sizeof (buf);
885 negative_number = t < 0;
896 /* Adjust if division truncates to minus infinity. */
897 if (0 < -1 % 10 && d < 0)
909 goto do_number_sign_and_padding;
916 if (! (modifier == 'E'
917 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_T_FMT)) != '\0'))
918 subfmt = _NL_CURRENT (LC_TIME, T_FMT);
922 case 'T': /* POSIX.2 extension. */
926 case 't': /* POSIX.2 extension. */
930 case 'u': /* POSIX.2 extension. */
931 DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
937 DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
940 case 'g': /* GNU extension. */
941 case 'G': /* GNU extension. */
945 int year = tp->tm_year + TM_YEAR_BASE;
946 int days = iso_week_days (tp->tm_yday, tp->tm_wday);
950 /* This ISO week belongs to the previous year. */
952 days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
957 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
961 /* This ISO week belongs to the next year. */
970 DO_NUMBER (2, (year % 100 + 100) % 100);
976 DO_NUMBER (2, days / 7 + 1);
984 DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
990 DO_NUMBER (1, tp->tm_wday);
993 #if HAVE_STRUCT_ERA_ENTRY
996 struct era_entry *era = _nl_get_era_entry (tp);
999 subfmt = strchr (era->name_fmt, '\0') + 1;
1004 if (modifier == 'O')
1007 DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
1010 #if HAVE_STRUCT_ERA_ENTRY
1011 if (modifier == 'E')
1013 struct era_entry *era = _nl_get_era_entry (tp);
1016 int delta = tp->tm_year - era->start_date[0];
1017 DO_NUMBER (1, (era->offset
1018 + (era->direction == '-' ? -delta : delta)));
1022 DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
1030 cpy (zonelen, zone);
1033 case 'z': /* GNU extension. */
1034 if (tp->tm_isdst < 0)
1040 diff = tp->tm_gmtoff;
1049 if (lt == (time_t) -1)
1051 /* mktime returns -1 for errors, but -1 is also a
1052 valid time_t value. Check whether an error really
1055 localtime_r (<, &tm);
1057 if ((ltm.tm_sec ^ tm.tm_sec)
1058 | (ltm.tm_min ^ tm.tm_min)
1059 | (ltm.tm_hour ^ tm.tm_hour)
1060 | (ltm.tm_mday ^ tm.tm_mday)
1061 | (ltm.tm_mon ^ tm.tm_mon)
1062 | (ltm.tm_year ^ tm.tm_year))
1066 if (! gmtime_r (<, >m))
1069 diff = tm_diff (<m, >m);
1081 DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
1084 case '\0': /* GNU extension: % at end of format. */
1088 /* Unknown format; output the format, including the '%',
1089 since this is most likely the right thing to do if a
1090 multibyte string has been misparsed. */
1094 for (flen = 1; f[1 - flen] != '%'; flen++)
1096 cpy (flen, &f[1 - flen]);