1 /* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
3 NOTE: The canonical source of this file is maintained with the GNU C
4 Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software Foundation,
18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 # define HAVE_LIMITS_H 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
33 # define MULTIBYTE_IS_FORMAT_SAFE 1
34 # define STDC_HEADERS 1
35 # include <ansidecl.h>
36 # include "../locale/localeinfo.h"
40 #include <sys/types.h> /* Some systems define `time_t' here. */
42 #ifdef TIME_WITH_SYS_TIME
43 # include <sys/time.h>
46 # ifdef HAVE_SYS_TIME_H
47 # include <sys/time.h>
53 extern char *tzname[];
56 /* Do multibyte processing if multibytes are supported, unless
57 multibyte sequences are safe in formats. Multibyte sequences are
58 safe if they cannot contain byte sequences that look like format
59 conversion specifications. The GNU C Library uses UTF8 multibyte
60 encoding, which is safe for formats, but strftime.c can be used
61 with other C libraries that use unsafe encodings. */
62 #define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
68 /* Simulate mbrlen with mblen as best we can. */
69 # define mbstate_t int
70 # define mbrlen(s, n, ps) mblen (s, n)
71 # define mbsinit(ps) (*(ps) == 0)
73 static const mbstate_t mbstate_zero;
85 # 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_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] = " ";
180 # define memset_space(P, Len) \
186 int _this = _len > 16 ? 16 : _len; \
187 memcpy ((P), spaces, _this); \
194 # define memset_space(P, Len) memset ((P), ' ', (Len))
201 int _delta = width - _n; \
202 int _incr = _n + (_delta > 0 ? _delta : 0); \
203 if (i + _incr >= maxsize) \
208 memset_space (p, _delta); \
218 memcpy_lowcase (p, (s), _n); \
219 else if (to_uppcase) \
220 memcpy_uppcase (p, (s), _n); \
222 memcpy ((PTR) p, (PTR) (s), _n))
227 # define TOUPPER(Ch) toupper (Ch)
228 # define TOLOWER(Ch) tolower (Ch)
230 # define TOUPPER(Ch) (islower (Ch) ? toupper (Ch) : (Ch))
231 # define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
233 /* We don't use `isdigit' here since the locale dependent
234 interpretation is not what we want here. We only need to accept
235 the arabic digits in the ASCII range. One day there is perhaps a
236 more reliable way to accept other sets of digits. */
237 #define ISDIGIT(Ch) ((unsigned int) (Ch) - '0' <= 9)
239 static char *memcpy_lowcase __P ((char *dest, const char *src, size_t len));
242 memcpy_lowcase (dest, src, len)
248 dest[len] = TOLOWER (src[len]);
252 static char *memcpy_uppcase __P ((char *dest, const char *src, size_t len));
255 memcpy_uppcase (dest, src, len)
261 dest[len] = TOUPPER (src[len]);
266 /* Yield the difference between *A and *B,
267 measured in seconds, ignoring leap seconds. */
268 static int tm_diff __P ((const struct tm *, const struct tm *));
274 /* Compute intervening leap days correctly even if year is negative.
275 Take care to avoid int overflow in leap day calculations,
276 but it's OK to assume that A and B are close to each other. */
277 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
278 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
279 int a100 = a4 / 25 - (a4 % 25 < 0);
280 int b100 = b4 / 25 - (b4 % 25 < 0);
281 int a400 = a100 >> 2;
282 int b400 = b100 >> 2;
283 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
284 int years = a->tm_year - b->tm_year;
285 int days = (365 * years + intervening_leap_days
286 + (a->tm_yday - b->tm_yday));
287 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
288 + (a->tm_min - b->tm_min))
289 + (a->tm_sec - b->tm_sec));
291 #endif /* ! HAVE_TM_GMTOFF */
295 /* The number of days from the first day of the first ISO week of this
296 year to the year day YDAY with week day WDAY. ISO weeks start on
297 Monday; the first ISO week has the year's first Thursday. YDAY may
298 be as small as YDAY_MINIMUM. */
299 #define ISO_WEEK_START_WDAY 1 /* Monday */
300 #define ISO_WEEK1_WDAY 4 /* Thursday */
301 #define YDAY_MINIMUM (-366)
302 static int iso_week_days __P ((int, int));
307 iso_week_days (yday, wday)
311 /* Add enough to the first operand of % to make it nonnegative. */
312 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
314 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
315 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
320 static char const weekday_name[][10] =
322 "Sunday", "Monday", "Tuesday", "Wednesday",
323 "Thursday", "Friday", "Saturday"
325 static char const month_name[][10] =
327 "January", "February", "March", "April", "May", "June",
328 "July", "August", "September", "October", "November", "December"
333 #if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
334 /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
335 Work around this bug by copying *tp before it might be munged. */
336 size_t _strftime_copytm __P ((char *, size_t, const char *,
339 strftime (s, maxsize, format, tp)
347 return _strftime_copytm (s, maxsize, format, &tmcopy);
352 # define strftime _strftime_copytm
357 /* Write information from TP into S according to the format
358 string FORMAT, writing no more that MAXSIZE characters
359 (including the terminating '\0') and returning number of
360 characters written. If S is NULL, nothing will be written
361 anywhere, so to determine how many characters would be
362 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
364 strftime (s, maxsize, format, tp)
370 int hour12 = tp->tm_hour;
372 const char *const a_wkday = _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday);
373 const char *const f_wkday = _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday);
374 const char *const a_month = _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon);
375 const char *const f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon);
376 const char *const ampm = _NL_CURRENT (LC_TIME,
377 hour12 > 11 ? PM_STR : AM_STR);
378 size_t aw_len = strlen (a_wkday);
379 size_t am_len = strlen (a_month);
380 size_t ap_len = strlen (ampm);
382 const char *const f_wkday = weekday_name[tp->tm_wday];
383 const char *const f_month = month_name[tp->tm_mon];
384 const char *const a_wkday = f_wkday;
385 const char *const a_month = f_month;
386 const char *const ampm = "AMPM" + 2 * (hour12 > 11);
391 size_t wkday_len = strlen (f_wkday);
392 size_t month_len = strlen (f_month);
400 #if !defined _LIBC && HAVE_TM_ZONE
401 /* XXX We have some problems here. First, the string pointed to by
402 tm_zone is dynamically allocated while loading the zone data. But
403 when another zone is loaded since the information in TP were
404 computed this would be a stale pointer.
405 The second problem is the POSIX test suite which assumes setting
406 the environment variable TZ to a new value before calling strftime()
407 will influence the result (the %Z format) even if the information in
408 TP is computed with a totally different time zone. --drepper@gnu */
409 zone = (const char *) tp->tm_zone;
412 /* POSIX.1 8.1.1 requires that whenever strftime() is called, the
413 time zone names contained in the external variable `tzname' shall
414 be set as if the tzset() function had been called. */
419 if (!(zone && *zone) && tp->tm_isdst >= 0)
420 zone = tzname[tp->tm_isdst];
423 zone = ""; /* POSIX.2 requires the empty string here. */
425 zonelen = strlen (zone);
430 if (hour12 == 0) hour12 = 12;
432 for (f = format; *f != '\0'; ++f)
434 int pad; /* Padding for number ('-', '_', or 0). */
435 int modifier; /* Field modifier ('E', 'O', or 0). */
436 int digits; /* Max digits for numeric format. */
437 int number_value; /* Numeric value to be printed. */
438 int negative_number; /* 1 if the number is negative. */
441 char buf[1 + (sizeof (int) < sizeof (time_t)
442 ? INT_STRLEN_BOUND (time_t)
443 : INT_STRLEN_BOUND (int))];
455 case '\a': case '\b': case '\t': case '\n':
456 case '\v': case '\f': case '\r':
457 case ' ': case '!': case '"': case '#': case '&': case'\'':
458 case '(': case ')': case '*': case '+': case ',': case '-':
459 case '.': case '/': case '0': case '1': case '2': case '3':
460 case '4': case '5': case '6': case '7': case '8': case '9':
461 case ':': case ';': case '<': case '=': case '>': case '?':
462 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
463 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
464 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
465 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
466 case 'Y': case 'Z': case '[': case'\\': case ']': case '^':
467 case '_': case 'a': case 'b': case 'c': case 'd': case 'e':
468 case 'f': case 'g': case 'h': case 'i': case 'j': case 'k':
469 case 'l': case 'm': case 'n': case 'o': case 'p': case 'q':
470 case 'r': case 's': case 't': case 'u': case 'v': case 'w':
471 case 'x': case 'y': case 'z': case '{': case '|': case '}':
473 /* The C Standard requires these 98 characters (plus '%') to
474 be in the basic execution character set. None of these
475 characters can start a multibyte sequence, so they need
476 not be analyzed further. */
481 /* Copy this multibyte sequence until we reach its end, find
482 an error, or come back to the initial shift state. */
484 mbstate_t mbstate = mbstate_zero;
489 size_t bytes = mbrlen (f + len, (size_t) -1, &mbstate);
494 if (bytes == (size_t) -2 || bytes == (size_t) -1)
502 while (! mbsinit (&mbstate));
509 #else /* ! DO_MULTIBYTE */
511 /* Either multibyte encodings are not supported, or they are
512 safe for formats, so any non-'%' byte can be copied through. */
519 #endif /* ! DO_MULTIBYTE */
521 /* Check for flags that can modify a format. */
527 /* This influences the number formats. */
534 /* This changes textual output. */
545 /* As a GNU extension we allow to specify the field width. */
555 while (ISDIGIT (*f));
558 /* Check for modifiers. */
571 /* Now do the specified format. */
574 #define DO_NUMBER(d, v) \
575 digits = d; number_value = v; goto do_number
576 #define DO_NUMBER_SPACEPAD(d, v) \
577 digits = d; number_value = v; goto do_number_spacepad
588 cpy (aw_len, a_wkday);
594 cpy (wkday_len, f_wkday);
598 case 'h': /* POSIX.2 extension. */
601 cpy (am_len, a_month);
607 cpy (month_len, f_month);
614 if (! (modifier == 'E'
615 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT)) != '\0'))
616 subfmt = _NL_CURRENT (LC_TIME, D_T_FMT);
618 subfmt = "%a %b %e %H:%M:%S %Y";
624 size_t len = strftime (NULL, maxsize - i, subfmt, tp);
625 if (len == 0 && *subfmt)
627 add (len, strftime (p, maxsize - i, subfmt, tp));
630 while (old_start < p)
632 *old_start = TOUPPER (*old_start);
638 case 'C': /* POSIX.2 extension. */
641 #if HAVE_STRUCT_ERA_ENTRY
644 struct era_entry *era = _nl_get_era_entry (tp);
647 size_t len = strlen (era->name_fmt);
648 cpy (len, era->name_fmt);
654 int year = tp->tm_year + TM_YEAR_BASE;
655 DO_NUMBER (1, year / 100 - (year % 100 < 0));
662 if (! (modifier == 'E'
663 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_FMT)) != '\0'))
664 subfmt = _NL_CURRENT (LC_TIME, D_FMT);
668 case 'D': /* POSIX.2 extension. */
678 DO_NUMBER (2, tp->tm_mday);
680 case 'e': /* POSIX.2 extension. */
684 DO_NUMBER_SPACEPAD (2, tp->tm_mday);
686 /* All numeric formats set DIGITS and NUMBER_VALUE and then
687 jump to one of these two labels. */
690 /* Force `_' flag unless overwritten by `0' flag. */
695 /* Format the number according to the MODIFIER flag. */
698 if (modifier == 'O' && 0 <= number_value)
700 /* Get the locale specific alternate representation of
701 the number NUMBER_VALUE. If none exist NULL is returned. */
702 const char *cp = _nl_get_alt_digit (number_value);
706 size_t digitlen = strlen (cp);
716 unsigned int u = number_value;
718 bufp = buf + sizeof (buf);
719 negative_number = number_value < 0;
725 *--bufp = u % 10 + '0';
726 while ((u /= 10) != 0);
729 do_number_sign_and_padding:
735 int padding = digits - (buf + sizeof (buf) - bufp);
739 while (0 < padding--)
744 bufp += negative_number;
745 while (0 < padding--)
752 cpy (buf + sizeof (buf) - bufp, bufp);
760 DO_NUMBER (2, tp->tm_hour);
766 DO_NUMBER (2, hour12);
768 case 'k': /* GNU extension. */
772 DO_NUMBER_SPACEPAD (2, tp->tm_hour);
774 case 'l': /* GNU extension. */
778 DO_NUMBER_SPACEPAD (2, hour12);
784 DO_NUMBER (3, 1 + tp->tm_yday);
790 DO_NUMBER (2, tp->tm_min);
796 DO_NUMBER (2, tp->tm_mon + 1);
798 case 'n': /* POSIX.2 extension. */
810 case 'R': /* GNU extension. */
814 case 'r': /* POSIX.2 extension. */
816 if (*(subfmt = _NL_CURRENT (LC_TIME, T_FMT_AMPM)) == '\0')
818 subfmt = "%I:%M:%S %p";
825 DO_NUMBER (2, tp->tm_sec);
827 case 's': /* GNU extension. */
835 /* Generate string value for T using time_t arithmetic;
836 this works even if sizeof (long) < sizeof (time_t). */
838 bufp = buf + sizeof (buf);
839 negative_number = t < 0;
850 /* Adjust if division truncates to minus infinity. */
851 if (0 < -1 % 10 && d < 0)
863 goto do_number_sign_and_padding;
870 if (! (modifier == 'E'
871 && *(subfmt = _NL_CURRENT (LC_TIME, ERA_T_FMT)) != '\0'))
872 subfmt = _NL_CURRENT (LC_TIME, T_FMT);
876 case 'T': /* POSIX.2 extension. */
880 case 't': /* POSIX.2 extension. */
884 case 'u': /* POSIX.2 extension. */
885 DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
891 DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
894 case 'g': /* GNU extension. */
895 case 'G': /* GNU extension. */
899 int year = tp->tm_year + TM_YEAR_BASE;
900 int days = iso_week_days (tp->tm_yday, tp->tm_wday);
904 /* This ISO week belongs to the previous year. */
906 days = iso_week_days (tp->tm_yday + (365 + __isleap (year)),
911 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
915 /* This ISO week belongs to the next year. */
924 DO_NUMBER (2, (year % 100 + 100) % 100);
930 DO_NUMBER (2, days / 7 + 1);
938 DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
944 DO_NUMBER (1, tp->tm_wday);
947 #if HAVE_STRUCT_ERA_ENTRY
950 struct era_entry *era = _nl_get_era_entry (tp);
953 subfmt = strchr (era->name_fmt, '\0') + 1;
961 DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE);
964 #if HAVE_STRUCT_ERA_ENTRY
967 struct era_entry *era = _nl_get_era_entry (tp);
970 int delta = tp->tm_year - era->start_date[0];
971 DO_NUMBER (1, (era->offset
972 + (era->direction == '-' ? -delta : delta)));
976 DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100);
982 case 'z': /* GNU extension. */
983 if (tp->tm_isdst < 0)
989 diff = tp->tm_gmtoff;
998 if (lt == (time_t) -1)
1000 /* mktime returns -1 for errors, but -1 is also a
1001 valid time_t value. Check whether an error really
1004 localtime_r (<, &tm);
1006 if ((ltm.tm_sec ^ tm.tm_sec)
1007 | (ltm.tm_min ^ tm.tm_min)
1008 | (ltm.tm_hour ^ tm.tm_hour)
1009 | (ltm.tm_mday ^ tm.tm_mday)
1010 | (ltm.tm_mon ^ tm.tm_mon)
1011 | (ltm.tm_year ^ tm.tm_year))
1015 if (! gmtime_r (<, >m))
1018 diff = tm_diff (<m, >m);
1030 DO_NUMBER (4, (diff / 60) * 100 + diff % 60);
1033 case '\0': /* GNU extension: % at end of format. */
1037 /* Unknown format; output the format, including the '%',
1038 since this is most likely the right thing to do if a
1039 multibyte string has been misparsed. */
1043 for (flen = 1; f[1 - flen] != '%'; flen++)
1045 cpy (flen, &f[1 - flen]);