1 /* Copyright (C) 1991, 92, 93, 94, 95, 96 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 <ansidecl.h>
35 # include "../locale/localeinfo.h"
39 #include <sys/types.h> /* Some systems define `time_t' here. */
41 #ifdef TIME_WITH_SYS_TIME
42 # include <sys/time.h>
45 # ifdef HAVE_SYS_TIME_H
46 # include <sys/time.h>
52 extern char *tzname[];
55 /* Do multibyte processing if multibytes are supported, unless
56 multibyte sequences are safe in formats. Multibyte sequences are
57 safe if they cannot contain byte sequences that look like format
58 conversion specifications. The GNU C Library uses UTF8 multibyte
59 encoding, which is safe for formats, but strftime.c can be used
60 with other C libraries that use unsafe encodings. */
61 #define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
67 /* Simulate mbrlen with mblen as best we can. */
68 # define mbstate_t int
69 # define mbrlen(s, n, ps) mblen (s, n)
70 # define mbsinit(ps) (*(ps) == 0)
72 static const mbstate_t mbstate_zero;
84 # define memcpy(d, s, n) bcopy ((s), (d), (n))
88 #if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
89 #define __P(args) args
107 #define TYPE_SIGNED(t) ((t) -1 < 0)
109 /* Bound on length of the string representing an integer value of type t.
110 Subtract one for the sign bit if t is signed;
111 302 / 1000 is log10 (2) rounded up;
112 add one for integer division truncation;
113 add one more for a minus sign if t is signed. */
114 #define INT_STRLEN_BOUND(t) \
115 ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 100 + 1 + TYPE_SIGNED (t))
117 #define TM_YEAR_BASE 1900
120 /* Nonzero if YEAR is a leap year (every 4 years,
121 except every 100th isn't, and every 400th is). */
122 #define __isleap(year) \
123 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
128 # define gmtime_r __gmtime_r
129 # define localtime_r __localtime_r
130 extern int __tz_compute __P ((time_t timer, const struct tm *tm));
132 # if ! HAVE_LOCALTIME_R
133 # if ! HAVE_TM_GMTOFF
134 /* Approximate gmtime_r as best we can in its absence. */
135 #define gmtime_r my_gmtime_r
136 static struct tm *gmtime_r __P ((const time_t *, struct tm *));
142 struct tm *l = gmtime (t);
148 # endif /* ! HAVE_TM_GMTOFF */
150 /* Approximate localtime_r as best we can in its absence. */
151 #define localtime_r my_localtime_r
152 static struct tm *localtime_r __P ((const time_t *, struct tm *));
158 struct tm *l = localtime (t);
164 # endif /* ! HAVE_LOCALTIME_R */
165 #endif /* ! defined (_LIBC) */
168 #if !defined (memset) && !defined (HAVE_MEMSET) && !defined (_LIBC)
169 /* Some systems lack the `memset' function and we don't want to
170 introduce additional dependencies. */
171 static const char spaces[16] = " ";
173 # define memset_space(P, Len) \
179 int _this = _len > 16 ? 16 : _len; \
180 memcpy ((P), spaces, _this); \
187 # define memset_space(P, Len) memset ((P), ' ', (Len))
194 int _delta = width - _n; \
195 i += _n + (_delta > 0 ? _delta : 0); \
202 memset_space (p, _delta); \
211 memcpy_lowcase (p, (s), _n); \
213 memcpy ((PTR) p, (PTR) (s), _n))
218 # define TOUPPER(Ch) toupper (Ch)
219 # define TOLOWER(Ch) tolower (Ch)
221 # define TOUPPER(Ch) (islower (Ch) ? toupper (Ch) : (Ch))
222 # define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
225 static char *memcpy_lowcase __P ((char *dest, const char *src, size_t len));
228 memcpy_lowcase (dest, src, len)
234 dest[len] = TOLOWER (src[len]);
239 /* Yield the difference between *A and *B,
240 measured in seconds, ignoring leap seconds. */
241 static int tm_diff __P ((const struct tm *, const struct tm *));
247 /* Compute intervening leap days correctly even if year is negative.
248 Take care to avoid int overflow in leap day calculations,
249 but it's OK to assume that A and B are close to each other. */
250 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
251 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
252 int a100 = a4 / 25 - (a4 % 25 < 0);
253 int b100 = b4 / 25 - (b4 % 25 < 0);
254 int a400 = a100 >> 2;
255 int b400 = b100 >> 2;
256 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
257 int years = a->tm_year - b->tm_year;
258 int days = (365 * years + intervening_leap_days
259 + (a->tm_yday - b->tm_yday));
260 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
261 + (a->tm_min - b->tm_min))
262 + (a->tm_sec - b->tm_sec));
264 #endif /* ! HAVE_TM_GMTOFF */
268 /* The number of days from the first day of the first ISO week of this
269 year to the year day YDAY with week day WDAY. ISO weeks start on
270 Monday; the first ISO week has the year's first Thursday. YDAY may
271 be as small as YDAY_MINIMUM. */
272 #define ISO_WEEK_START_WDAY 1 /* Monday */
273 #define ISO_WEEK1_WDAY 4 /* Thursday */
274 #define YDAY_MINIMUM (-366)
275 static int iso_week_days __P ((int, int));
280 iso_week_days (yday, wday)
284 /* Add enough to the first operand of % to make it nonnegative. */
285 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
287 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
288 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
293 static char const weekday_name[][10] =
295 "Sunday", "Monday", "Tuesday", "Wednesday",
296 "Thursday", "Friday", "Saturday"
298 static char const month_name[][10] =
300 "January", "February", "March", "April", "May", "June",
301 "July", "August", "September", "October", "November", "December"
305 /* Write information from TP into S according to the format
306 string FORMAT, writing no more that MAXSIZE characters
307 (including the terminating '\0') and returning number of
308 characters written. If S is NULL, nothing will be written
309 anywhere, so to determine how many characters would be
310 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
312 strftime (s, maxsize, format, tp)
318 int hour12 = tp->tm_hour;
320 const char *const a_wkday = _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday);
321 const char *const f_wkday = _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday);
322 const char *const a_month = _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon);
323 const char *const f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon);
324 const char *const ampm = _NL_CURRENT (LC_TIME,
325 hour12 > 11 ? PM_STR : AM_STR);
326 size_t aw_len = strlen (a_wkday);
327 size_t am_len = strlen (a_month);
328 size_t ap_len = strlen (ampm);
330 const char *const f_wkday = weekday_name[tp->tm_wday];
331 const char *const f_month = month_name[tp->tm_mon];
332 const char *const a_wkday = f_wkday;
333 const char *const a_month = f_month;
334 const char *const ampm = "AMPM" + 2 * (hour12 > 11);
339 size_t wkday_len = strlen (f_wkday);
340 size_t month_len = strlen (f_month);
348 #if !defined _LIBC && HAVE_TM_ZONE
349 /* XXX We have some problems here. First, the string pointed to by
350 tm_zone is dynamically allocated while loading the zone data. But
351 when another zone is loaded since the information in TP were
352 computed this would be a stale pointer.
353 The second problem is the POSIX test suite which assumes setting
354 the environment variable TZ to a new value before calling strftime()
355 will influence the result (the %Z format) even if the information in
356 TP is computed with a totally different time zone. --drepper@gnu */
357 zone = (const char *) tp->tm_zone;
360 /* POSIX.1 8.1.1 requires that whenever strftime() is called, the
361 time zone names contained in the external variable `tzname' shall
362 be set as if the tzset() function had been called. */
367 if (!(zone && *zone) && tp->tm_isdst >= 0)
368 zone = tzname[tp->tm_isdst];
371 zone = ""; /* POSIX.2 requires the empty string here. */
373 zonelen = strlen (zone);
378 if (hour12 == 0) hour12 = 12;
380 for (f = format; *f != '\0'; ++f)
382 int pad; /* Padding for number ('-', '_', or 0). */
383 int modifier; /* Field modifier ('E', 'O', or 0). */
384 int digits; /* Max digits for numeric format. */
385 int number_value; /* Numeric value to be printed. */
386 int negative_number; /* 1 if the number is negative. */
389 char buf[1 + (sizeof (int) < sizeof (time_t)
390 ? INT_STRLEN_BOUND (time_t)
391 : INT_STRLEN_BOUND (int))];
402 case '\a': case '\b': case '\t': case '\n':
403 case '\v': case '\f': case '\r':
404 case ' ': case '!': case '"': case '#': case '&': case'\'':
405 case '(': case ')': case '*': case '+': case ',': case '-':
406 case '.': case '/': case '0': case '1': case '2': case '3':
407 case '4': case '5': case '6': case '7': case '8': case '9':
408 case ':': case ';': case '<': case '=': case '>': case '?':
409 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
410 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
411 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
412 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
413 case 'Y': case 'Z': case '[': case'\\': case ']': case '^':
414 case '_': case 'a': case 'b': case 'c': case 'd': case 'e':
415 case 'f': case 'g': case 'h': case 'i': case 'j': case 'k':
416 case 'l': case 'm': case 'n': case 'o': case 'p': case 'q':
417 case 'r': case 's': case 't': case 'u': case 'v': case 'w':
418 case 'x': case 'y': case 'z': case '{': case '|': case '}':
420 /* The C Standard requires these 98 characters (plus '%') to
421 be in the basic execution character set. None of these
422 characters can start a multibyte sequence, so they need
423 not be analyzed further. */
428 /* Copy this multibyte sequence until we reach its end, find
429 an error, or come back to the initial shift state. */
431 mbstate_t mbstate = mbstate_zero;
436 size_t bytes = mbrlen (f + len, (size_t) -1, &mbstate);
441 if (bytes == (size_t) -2 || bytes == (size_t) -1)
449 while (! mbsinit (&mbstate));
456 #else /* ! DO_MULTIBYTE */
458 /* Either multibyte encodings are not supported, or they are
459 safe for formats, so any non-'%' byte can be copied through. */
466 #endif /* ! DO_MULTIBYTE */
468 /* Check for flags that can modify a number format. */
487 /* As a GNU extension we allow to specify the field width. */
496 while (isdigit (*++f));
499 /* Check for modifiers. */
512 /* Now do the specified format. */
515 #define DO_NUMBER(d, v) \
516 digits = d; number_value = v; goto do_number
517 #define DO_NUMBER_SPACEPAD(d, v) \
518 digits = d; number_value = v; goto do_number_spacepad
529 cpy (aw_len, a_wkday);
535 cpy (wkday_len, f_wkday);
539 case 'h': /* POSIX.2 extension. */
542 cpy (am_len, a_month);
548 cpy (month_len, f_month);
555 if (! (modifier == 'E'
556 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT)) != '\0'))
557 subfmt = _NL_CURRENT (LC_TIME, D_T_FMT);
559 subfmt = "%a %b %e %H:%M:%S %Y";
564 size_t len = strftime (NULL, maxsize - i, subfmt, tp);
565 if (len == 0 && *subfmt)
567 add (len, strftime (p, maxsize - i, subfmt, tp));
571 case 'C': /* POSIX.2 extension. */
574 #if HAVE_STRUCT_ERA_ENTRY
577 struct era_entry *era = _nl_get_era_entry (tp);
580 size_t len = strlen (era->name_fmt);
581 cpy (len, era->name_fmt);
587 int year = tp->tm_year + TM_YEAR_BASE;
588 DO_NUMBER (1, year / 100 - (year % 100 < 0));
595 if (! (modifier == 'E'
596 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_FMT)) != '\0'))
597 subfmt = _NL_CURRENT (LC_TIME, D_FMT);
601 case 'D': /* POSIX.2 extension. */
611 DO_NUMBER (2, tp->tm_mday);
613 case 'e': /* POSIX.2 extension. */
617 DO_NUMBER_SPACEPAD (2, tp->tm_mday);
619 /* All numeric formats set DIGITS and NUMBER_VALUE and then
620 jump to one of these two labels. */
623 /* Force `_' flag unless overwritten by `0' flag. */
628 /* Format the number according to the MODIFIER flag. */
631 if (modifier == 'O' && 0 <= number_value)
633 /* Get the locale specific alternate representation of
634 the number NUMBER_VALUE. If none exist NULL is returned. */
635 const char *cp = _nl_get_alt_digit (number_value);
639 size_t digitlen = strlen (cp);
649 unsigned int u = number_value;
651 bufp = buf + sizeof (buf);
652 negative_number = number_value < 0;
658 *--bufp = u % 10 + '0';
659 while ((u /= 10) != 0);
662 do_number_sign_and_padding:
668 int padding = digits - (buf + sizeof (buf) - bufp);
672 while (0 < padding--)
677 bufp += negative_number;
678 while (0 < padding--)
685 cpy (buf + sizeof (buf) - bufp, bufp);
693 DO_NUMBER (2, tp->tm_hour);
699 DO_NUMBER (2, hour12);
701 case 'k': /* GNU extension. */
705 DO_NUMBER_SPACEPAD (2, tp->tm_hour);
707 case 'l': /* GNU extension. */
711 DO_NUMBER_SPACEPAD (2, hour12);
717 DO_NUMBER (3, 1 + tp->tm_yday);
723 DO_NUMBER (2, tp->tm_min);
729 DO_NUMBER (2, tp->tm_mon + 1);
731 case 'n': /* POSIX.2 extension. */
743 case 'R': /* GNU extension. */
747 case 'r': /* POSIX.2 extension. */
749 if (*(subfmt = _NL_CURRENT (LC_TIME, T_FMT_AMPM)) == '\0')
751 subfmt = "%I:%M:%S %p";
758 DO_NUMBER (2, tp->tm_sec);
760 case 's': /* GNU extension. */
768 /* Generate string value for T using time_t arithmetic;
769 this works even if sizeof (long) < sizeof (time_t). */
771 bufp = buf + sizeof (buf);
772 negative_number = t < 0;
783 /* Adjust if division truncates to minus infinity. */
784 if (0 < -1 % 10 && d < 0)
796 goto do_number_sign_and_padding;
803 if (! (modifier == 'E'
804 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_T_FMT)) != '\0'))
805 subfmt = _NL_CURRENT (LC_TIME, T_FMT);
809 case 'T': /* POSIX.2 extension. */
813 case 't': /* POSIX.2 extension. */
817 case 'u': /* POSIX.2 extension. */
818 DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
824 DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
827 case 'g': /* GNU extension. */
828 case 'G': /* GNU extension. */
832 int year = tp->tm_year + TM_YEAR_BASE;
833 int days = iso_week_days (tp->tm_yday, tp->tm_wday);
837 /* This ISO week belongs to the previous year. */
839 days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
844 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
848 /* This ISO week belongs to the next year. */
857 DO_NUMBER (2, (year % 100 + 100) % 100);
863 DO_NUMBER (2, days / 7 + 1);
871 DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
877 DO_NUMBER (1, tp->tm_wday);
880 #if HAVE_STRUCT_ERA_ENTRY
883 struct era_entry *era = _nl_get_era_entry (tp);
886 subfmt = strchr (era->name_fmt, '\0') + 1;
894 DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
897 #if HAVE_STRUCT_ERA_ENTRY
900 struct era_entry *era = _nl_get_era_entry (tp);
903 int delta = tp->tm_year - era->start_date[0];
904 DO_NUMBER (1, (era->offset
905 + (era->direction == '-' ? -delta : delta)));
909 DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
915 case 'z': /* GNU extension. */
916 if (tp->tm_isdst < 0)
922 diff = tp->tm_gmtoff;
931 if (lt == (time_t) -1)
933 /* mktime returns -1 for errors, but -1 is also a
934 valid time_t value. Check whether an error really
937 localtime_r (<, &tm);
939 if ((ltm.tm_sec ^ tm.tm_sec)
940 | (ltm.tm_min ^ tm.tm_min)
941 | (ltm.tm_hour ^ tm.tm_hour)
942 | (ltm.tm_mday ^ tm.tm_mday)
943 | (ltm.tm_mon ^ tm.tm_mon)
944 | (ltm.tm_year ^ tm.tm_year))
948 if (! gmtime_r (<, >m))
951 diff = tm_diff (<m, >m);
963 DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
966 case '\0': /* GNU extension: % at end of format. */
970 /* Unknown format; output the format, including the '%',
971 since this is most likely the right thing to do if a
972 multibyte string has been misparsed. */
976 for (flen = 1; f[1 - flen] != '%'; flen++)
978 cpy (flen, &f[1 - flen]);