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 <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
111 #define TYPE_SIGNED(t) ((t) -1 < 0)
113 /* Bound on length of the string representing an integer value of type t.
114 Subtract one for the sign bit if t is signed;
115 302 / 1000 is log10 (2) rounded up;
116 add one for integer division truncation;
117 add one more for a minus sign if t is signed. */
118 #define INT_STRLEN_BOUND(t) \
119 ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 100 + 1 + TYPE_SIGNED (t))
121 #define TM_YEAR_BASE 1900
124 /* Nonzero if YEAR is a leap year (every 4 years,
125 except every 100th isn't, and every 400th is). */
126 # define __isleap(year) \
127 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
132 # define gmtime_r __gmtime_r
133 # define localtime_r __localtime_r
134 extern int __tz_compute
__P ((time_t timer
, const struct tm
*tm
));
135 # define tzname __tzname
136 # define tzset __tzset
138 # if ! HAVE_LOCALTIME_R
139 # if ! HAVE_TM_GMTOFF
140 /* Approximate gmtime_r as best we can in its absence. */
141 # define gmtime_r my_gmtime_r
142 static struct tm
*gmtime_r
__P ((const time_t *, struct tm
*));
148 struct tm
*l
= gmtime (t
);
154 # endif /* ! HAVE_TM_GMTOFF */
156 /* Approximate localtime_r as best we can in its absence. */
157 # define localtime_r my_localtime_r
158 static struct tm
*localtime_r
__P ((const time_t *, struct tm
*));
164 struct tm
*l
= localtime (t
);
170 # endif /* ! HAVE_LOCALTIME_R */
171 #endif /* ! defined (_LIBC) */
174 #if !defined (memset) && !defined (HAVE_MEMSET) && !defined (_LIBC)
175 /* Some systems lack the `memset' function and we don't want to
176 introduce additional dependencies. */
177 static const char spaces
[16] = " ";
178 static const char zeroes
[16] = "0000000000000000";
180 # define memset_space(P, Len) \
186 int _this = _len > 16 ? 16 : _len; \
187 memcpy ((P), spaces, _this); \
194 # define memset_zero(P, Len) \
200 int _this = _len > 16 ? 16 : _len; \
201 memcpy ((P), zeroes, _this); \
208 # define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
209 # define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
216 int _delta = width - _n; \
217 int _incr = _n + (_delta > 0 ? _delta : 0); \
218 if (i + _incr >= maxsize) \
225 memset_zero (p, _delta); \
227 memset_space (p, _delta); \
238 memcpy_lowcase (p, (s), _n); \
239 else if (to_uppcase) \
240 memcpy_uppcase (p, (s), _n); \
242 memcpy ((PTR) p, (PTR) (s), _n))
247 # define TOUPPER(Ch) toupper (Ch)
248 # define TOLOWER(Ch) tolower (Ch)
250 # define TOUPPER(Ch) (islower (Ch) ? toupper (Ch) : (Ch))
251 # define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
253 /* We don't use `isdigit' here since the locale dependent
254 interpretation is not what we want here. We only need to accept
255 the arabic digits in the ASCII range. One day there is perhaps a
256 more reliable way to accept other sets of digits. */
257 #define ISDIGIT(Ch) ((unsigned int) (Ch) - '0' <= 9)
259 static char *memcpy_lowcase
__P ((char *dest
, const char *src
, size_t len
));
262 memcpy_lowcase (dest
, src
, len
)
268 dest
[len
] = TOLOWER (src
[len
]);
272 static char *memcpy_uppcase
__P ((char *dest
, const char *src
, size_t len
));
275 memcpy_uppcase (dest
, src
, len
)
281 dest
[len
] = TOUPPER (src
[len
]);
287 /* Yield the difference between *A and *B,
288 measured in seconds, ignoring leap seconds. */
289 static int tm_diff
__P ((const struct tm
*, const struct tm
*));
295 /* Compute intervening leap days correctly even if year is negative.
296 Take care to avoid int overflow in leap day calculations,
297 but it's OK to assume that A and B are close to each other. */
298 int a4
= (a
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (a
->tm_year
& 3);
299 int b4
= (b
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (b
->tm_year
& 3);
300 int a100
= a4
/ 25 - (a4
% 25 < 0);
301 int b100
= b4
/ 25 - (b4
% 25 < 0);
302 int a400
= a100
>> 2;
303 int b400
= b100
>> 2;
304 int intervening_leap_days
= (a4
- b4
) - (a100
- b100
) + (a400
- b400
);
305 int years
= a
->tm_year
- b
->tm_year
;
306 int days
= (365 * years
+ intervening_leap_days
307 + (a
->tm_yday
- b
->tm_yday
));
308 return (60 * (60 * (24 * days
+ (a
->tm_hour
- b
->tm_hour
))
309 + (a
->tm_min
- b
->tm_min
))
310 + (a
->tm_sec
- b
->tm_sec
));
312 #endif /* ! HAVE_TM_GMTOFF */
316 /* The number of days from the first day of the first ISO week of this
317 year to the year day YDAY with week day WDAY. ISO weeks start on
318 Monday; the first ISO week has the year's first Thursday. YDAY may
319 be as small as YDAY_MINIMUM. */
320 #define ISO_WEEK_START_WDAY 1 /* Monday */
321 #define ISO_WEEK1_WDAY 4 /* Thursday */
322 #define YDAY_MINIMUM (-366)
323 static int iso_week_days
__P ((int, int));
328 iso_week_days (yday
, wday
)
332 /* Add enough to the first operand of % to make it nonnegative. */
333 int big_enough_multiple_of_7
= (-YDAY_MINIMUM
/ 7 + 2) * 7;
335 - (yday
- wday
+ ISO_WEEK1_WDAY
+ big_enough_multiple_of_7
) % 7
336 + ISO_WEEK1_WDAY
- ISO_WEEK_START_WDAY
);
341 static char const weekday_name
[][10] =
343 "Sunday", "Monday", "Tuesday", "Wednesday",
344 "Thursday", "Friday", "Saturday"
346 static char const month_name
[][10] =
348 "January", "February", "March", "April", "May", "June",
349 "July", "August", "September", "October", "November", "December"
354 #if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
355 /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
356 Work around this bug by copying *tp before it might be munged. */
357 size_t _strftime_copytm
__P ((char *, size_t, const char *,
360 strftime (s
, maxsize
, format
, tp
)
368 return _strftime_copytm (s
, maxsize
, format
, &tmcopy
);
373 # define strftime(S, Maxsize, Format, Tp) \
374 _strftime_copytm (S, Maxsize, Format, Tp)
378 /* Write information from TP into S according to the format
379 string FORMAT, writing no more that MAXSIZE characters
380 (including the terminating '\0') and returning number of
381 characters written. If S is NULL, nothing will be written
382 anywhere, so to determine how many characters would be
383 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
385 strftime (s
, maxsize
, format
, tp
)
391 int hour12
= tp
->tm_hour
;
393 const char *const a_wkday
= _NL_CURRENT (LC_TIME
, ABDAY_1
+ tp
->tm_wday
);
394 const char *const f_wkday
= _NL_CURRENT (LC_TIME
, DAY_1
+ tp
->tm_wday
);
395 const char *const a_month
= _NL_CURRENT (LC_TIME
, ABMON_1
+ tp
->tm_mon
);
396 const char *const f_month
= _NL_CURRENT (LC_TIME
, MON_1
+ tp
->tm_mon
);
397 const char *const ampm
= _NL_CURRENT (LC_TIME
,
398 hour12
> 11 ? PM_STR
: AM_STR
);
399 size_t aw_len
= strlen (a_wkday
);
400 size_t am_len
= strlen (a_month
);
401 size_t ap_len
= strlen (ampm
);
403 const char *const f_wkday
= weekday_name
[tp
->tm_wday
];
404 const char *const f_month
= month_name
[tp
->tm_mon
];
405 const char *const a_wkday
= f_wkday
;
406 const char *const a_month
= f_month
;
407 const char *const ampm
= "AMPM" + 2 * (hour12
> 11);
412 size_t wkday_len
= strlen (f_wkday
);
413 size_t month_len
= strlen (f_month
);
421 #if !defined _LIBC && HAVE_TM_ZONE
422 /* XXX We have some problems here. First, the string pointed to by
423 tm_zone is dynamically allocated while loading the zone data. But
424 when another zone is loaded since the information in TP were
425 computed this would be a stale pointer.
426 The second problem is the POSIX test suite which assumes setting
427 the environment variable TZ to a new value before calling strftime()
428 will influence the result (the %Z format) even if the information in
429 TP is computed with a totally different time zone. --drepper@gnu */
430 zone
= (const char *) tp
->tm_zone
;
433 /* POSIX.1 8.1.1 requires that whenever strftime() is called, the
434 time zone names contained in the external variable `tzname' shall
435 be set as if the tzset() function had been called. */
440 if (!(zone
&& *zone
) && tp
->tm_isdst
>= 0)
441 zone
= tzname
[tp
->tm_isdst
];
444 zone
= ""; /* POSIX.2 requires the empty string here. */
446 zonelen
= strlen (zone
);
451 if (hour12
== 0) hour12
= 12;
453 for (f
= format
; *f
!= '\0'; ++f
)
455 int pad
; /* Padding for number ('-', '_', or 0). */
456 int modifier
; /* Field modifier ('E', 'O', or 0). */
457 int digits
; /* Max digits for numeric format. */
458 int number_value
; /* Numeric value to be printed. */
459 int negative_number
; /* 1 if the number is negative. */
462 char buf
[1 + (sizeof (int) < sizeof (time_t)
463 ? INT_STRLEN_BOUND (time_t)
464 : INT_STRLEN_BOUND (int))];
477 case '\a': case '\b': case '\t': case '\n':
478 case '\v': case '\f': case '\r':
479 case ' ': case '!': case '"': case '#': case '&': case'\'':
480 case '(': case ')': case '*': case '+': case ',': case '-':
481 case '.': case '/': case '0': case '1': case '2': case '3':
482 case '4': case '5': case '6': case '7': case '8': case '9':
483 case ':': case ';': case '<': case '=': case '>': case '?':
484 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
485 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
486 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
487 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
488 case 'Y': case 'Z': case '[': case'\\': case ']': case '^':
489 case '_': case 'a': case 'b': case 'c': case 'd': case 'e':
490 case 'f': case 'g': case 'h': case 'i': case 'j': case 'k':
491 case 'l': case 'm': case 'n': case 'o': case 'p': case 'q':
492 case 'r': case 's': case 't': case 'u': case 'v': case 'w':
493 case 'x': case 'y': case 'z': case '{': case '|': case '}':
495 /* The C Standard requires these 98 characters (plus '%') to
496 be in the basic execution character set. None of these
497 characters can start a multibyte sequence, so they need
498 not be analyzed further. */
503 /* Copy this multibyte sequence until we reach its end, find
504 an error, or come back to the initial shift state. */
506 mbstate_t mbstate
= mbstate_zero
;
511 size_t bytes
= mbrlen (f
+ len
, (size_t) -1, &mbstate
);
516 if (bytes
== (size_t) -2 || bytes
== (size_t) -1)
524 while (! mbsinit (&mbstate
));
531 #else /* ! DO_MULTIBYTE */
533 /* Either multibyte encodings are not supported, or they are
534 safe for formats, so any non-'%' byte can be copied through. */
541 #endif /* ! DO_MULTIBYTE */
543 /* Check for flags that can modify a format. */
549 /* This influences the number formats. */
556 /* This changes textual output. */
570 /* As a GNU extension we allow to specify the field width. */
580 while (ISDIGIT (*f
));
583 /* Check for modifiers. */
596 /* Now do the specified format. */
599 #define DO_NUMBER(d, v) \
600 digits = width == -1 ? d : width; \
601 number_value = v; goto do_number
602 #define DO_NUMBER_SPACEPAD(d, v) \
603 digits = width == -1 ? d : width; \
604 number_value = v; goto do_number_spacepad
620 cpy (aw_len
, a_wkday
);
631 cpy (wkday_len
, f_wkday
);
635 case 'h': /* POSIX.2 extension. */
638 cpy (am_len
, a_month
);
649 cpy (month_len
, f_month
);
656 if (! (modifier
== 'E'
657 && *(subfmt
= _NL_CURRENT (LC_TIME
, ERA_D_T_FMT
)) != '\0'))
658 subfmt
= _NL_CURRENT (LC_TIME
, D_T_FMT
);
660 subfmt
= "%a %b %e %H:%M:%S %Y";
666 size_t len
= strftime (NULL
, maxsize
- i
, subfmt
, tp
);
667 if (len
== 0 && *subfmt
)
669 add (len
, strftime (p
, maxsize
- i
, subfmt
, tp
));
672 while (old_start
< p
)
674 *old_start
= TOUPPER (*old_start
);
680 case 'C': /* POSIX.2 extension. */
683 #if HAVE_STRUCT_ERA_ENTRY
686 struct era_entry
*era
= _nl_get_era_entry (tp
);
689 size_t len
= strlen (era
->name_fmt
);
690 cpy (len
, era
->name_fmt
);
696 int year
= tp
->tm_year
+ TM_YEAR_BASE
;
697 DO_NUMBER (1, year
/ 100 - (year
% 100 < 0));
704 if (! (modifier
== 'E'
705 && *(subfmt
= _NL_CURRENT (LC_TIME
, ERA_D_FMT
)) != '\0'))
706 subfmt
= _NL_CURRENT (LC_TIME
, D_FMT
);
710 case 'D': /* POSIX.2 extension. */
720 DO_NUMBER (2, tp
->tm_mday
);
722 case 'e': /* POSIX.2 extension. */
726 DO_NUMBER_SPACEPAD (2, tp
->tm_mday
);
728 /* All numeric formats set DIGITS and NUMBER_VALUE and then
729 jump to one of these two labels. */
732 /* Force `_' flag unless overwritten by `0' flag. */
737 /* Format the number according to the MODIFIER flag. */
740 if (modifier
== 'O' && 0 <= number_value
)
742 /* Get the locale specific alternate representation of
743 the number NUMBER_VALUE. If none exist NULL is returned. */
744 const char *cp
= _nl_get_alt_digit (number_value
);
748 size_t digitlen
= strlen (cp
);
758 unsigned int u
= number_value
;
760 bufp
= buf
+ sizeof (buf
);
761 negative_number
= number_value
< 0;
767 *--bufp
= u
% 10 + '0';
768 while ((u
/= 10) != 0);
771 do_number_sign_and_padding
:
777 int padding
= digits
- (buf
+ sizeof (buf
) - bufp
);
781 while (0 < padding
--)
786 bufp
+= negative_number
;
787 while (0 < padding
--)
794 cpy (buf
+ sizeof (buf
) - bufp
, bufp
);
802 DO_NUMBER (2, tp
->tm_hour
);
808 DO_NUMBER (2, hour12
);
810 case 'k': /* GNU extension. */
814 DO_NUMBER_SPACEPAD (2, tp
->tm_hour
);
816 case 'l': /* GNU extension. */
820 DO_NUMBER_SPACEPAD (2, hour12
);
826 DO_NUMBER (3, 1 + tp
->tm_yday
);
832 DO_NUMBER (2, tp
->tm_min
);
838 DO_NUMBER (2, tp
->tm_mon
+ 1);
840 case 'n': /* POSIX.2 extension. */
857 case 'R': /* GNU extension. */
861 case 'r': /* POSIX.2 extension. */
863 if (*(subfmt
= _NL_CURRENT (LC_TIME
, T_FMT_AMPM
)) == '\0')
865 subfmt
= "%I:%M:%S %p";
872 DO_NUMBER (2, tp
->tm_sec
);
874 case 's': /* GNU extension. */
882 /* Generate string value for T using time_t arithmetic;
883 this works even if sizeof (long) < sizeof (time_t). */
885 bufp
= buf
+ sizeof (buf
);
886 negative_number
= t
< 0;
897 /* Adjust if division truncates to minus infinity. */
898 if (0 < -1 % 10 && d
< 0)
910 goto do_number_sign_and_padding
;
917 if (! (modifier
== 'E'
918 && *(subfmt
= _NL_CURRENT (LC_TIME
, ERA_T_FMT
)) != '\0'))
919 subfmt
= _NL_CURRENT (LC_TIME
, T_FMT
);
923 case 'T': /* POSIX.2 extension. */
927 case 't': /* POSIX.2 extension. */
931 case 'u': /* POSIX.2 extension. */
932 DO_NUMBER (1, (tp
->tm_wday
- 1 + 7) % 7 + 1);
938 DO_NUMBER (2, (tp
->tm_yday
- tp
->tm_wday
+ 7) / 7);
941 case 'g': /* GNU extension. */
942 case 'G': /* GNU extension. */
946 int year
= tp
->tm_year
+ TM_YEAR_BASE
;
947 int days
= iso_week_days (tp
->tm_yday
, tp
->tm_wday
);
951 /* This ISO week belongs to the previous year. */
953 days
= iso_week_days (tp
->tm_yday
+ (365 + __isleap (year
)),
958 int d
= iso_week_days (tp
->tm_yday
- (365 + __isleap (year
)),
962 /* This ISO week belongs to the next year. */
971 DO_NUMBER (2, (year
% 100 + 100) % 100);
977 DO_NUMBER (2, days
/ 7 + 1);
985 DO_NUMBER (2, (tp
->tm_yday
- (tp
->tm_wday
- 1 + 7) % 7 + 7) / 7);
991 DO_NUMBER (1, tp
->tm_wday
);
994 #if HAVE_STRUCT_ERA_ENTRY
997 struct era_entry
*era
= _nl_get_era_entry (tp
);
1000 subfmt
= strchr (era
->name_fmt
, '\0') + 1;
1005 if (modifier
== 'O')
1008 DO_NUMBER (1, tp
->tm_year
+ TM_YEAR_BASE
);
1011 #if HAVE_STRUCT_ERA_ENTRY
1012 if (modifier
== 'E')
1014 struct era_entry
*era
= _nl_get_era_entry (tp
);
1017 int delta
= tp
->tm_year
- era
->start_date
[0];
1018 DO_NUMBER (1, (era
->offset
1019 + (era
->direction
== '-' ? -delta
: delta
)));
1023 DO_NUMBER (2, (tp
->tm_year
% 100 + 100) % 100);
1031 cpy (zonelen
, zone
);
1034 case 'z': /* GNU extension. */
1035 if (tp
->tm_isdst
< 0)
1041 diff
= tp
->tm_gmtoff
;
1050 if (lt
== (time_t) -1)
1052 /* mktime returns -1 for errors, but -1 is also a
1053 valid time_t value. Check whether an error really
1056 localtime_r (<
, &tm
);
1058 if ((ltm
.tm_sec
^ tm
.tm_sec
)
1059 | (ltm
.tm_min
^ tm
.tm_min
)
1060 | (ltm
.tm_hour
^ tm
.tm_hour
)
1061 | (ltm
.tm_mday
^ tm
.tm_mday
)
1062 | (ltm
.tm_mon
^ tm
.tm_mon
)
1063 | (ltm
.tm_year
^ tm
.tm_year
))
1067 if (! gmtime_r (<
, >m
))
1070 diff
= tm_diff (<m
, >m
);
1082 DO_NUMBER (4, (diff
/ 60) * 100 + diff
% 60);
1085 case '\0': /* GNU extension: % at end of format. */
1089 /* Unknown format; output the format, including the '%',
1090 since this is most likely the right thing to do if a
1091 multibyte string has been misparsed. */
1095 for (flen
= 1; f
[1 - flen
] != '%'; flen
++)
1097 cpy (flen
, &f
[1 - flen
]);