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 Library.
4 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
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
26 # define HAVE_LIMITS_H 1
28 # define HAVE_MBRLEN 1
29 # define HAVE_STRUCT_ERA_ENTRY 1
30 # define HAVE_TM_GMTOFF 1
31 # define HAVE_TM_ZONE 1
32 # define HAVE_TZNAME 1
34 # define MULTIBYTE_IS_FORMAT_SAFE 1
35 # define STDC_HEADERS 1
36 # include <ansidecl.h>
37 # include "../locale/localeinfo.h"
41 #include <sys/types.h> /* Some systems define `time_t' here. */
43 #ifdef TIME_WITH_SYS_TIME
44 # include <sys/time.h>
47 # ifdef HAVE_SYS_TIME_H
48 # include <sys/time.h>
54 extern char *tzname
[];
57 /* Do multibyte processing if multibytes are supported, unless
58 multibyte sequences are safe in formats. Multibyte sequences are
59 safe if they cannot contain byte sequences that look like format
60 conversion specifications. The GNU C Library uses UTF8 multibyte
61 encoding, which is safe for formats, but strftime.c can be used
62 with other C libraries that use unsafe encodings. */
63 #define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
69 /* Simulate mbrlen with mblen as best we can. */
70 # define mbstate_t int
71 # define mbrlen(s, n, ps) mblen (s, n)
72 # define mbsinit(ps) (*(ps) == 0)
74 static const mbstate_t mbstate_zero
;
86 # define memcpy(d, s, n) bcopy ((s), (d), (n))
90 # if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
91 # define __P(args) args
113 #define TYPE_SIGNED(t) ((t) -1 < 0)
115 /* Bound on length of the string representing an integer value of type t.
116 Subtract one for the sign bit if t is signed;
117 302 / 1000 is log10 (2) rounded up;
118 add one for integer division truncation;
119 add one more for a minus sign if t is signed. */
120 #define INT_STRLEN_BOUND(t) \
121 ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 100 + 1 + TYPE_SIGNED (t))
123 #define TM_YEAR_BASE 1900
126 /* Nonzero if YEAR is a leap year (every 4 years,
127 except every 100th isn't, and every 400th is). */
128 # define __isleap(year) \
129 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
134 # define gmtime_r __gmtime_r
135 # define localtime_r __localtime_r
136 extern int __tz_compute
__P ((time_t timer
, const struct tm
*tm
));
137 # define tzname __tzname
138 # define tzset __tzset
140 # if ! HAVE_LOCALTIME_R
141 # if ! HAVE_TM_GMTOFF
142 /* Approximate gmtime_r as best we can in its absence. */
143 # define gmtime_r my_gmtime_r
144 static struct tm
*gmtime_r
__P ((const time_t *, struct tm
*));
150 struct tm
*l
= gmtime (t
);
156 # endif /* ! HAVE_TM_GMTOFF */
158 /* Approximate localtime_r as best we can in its absence. */
159 # define localtime_r my_localtime_r
160 static struct tm
*localtime_r
__P ((const time_t *, struct tm
*));
166 struct tm
*l
= localtime (t
);
172 # endif /* ! HAVE_LOCALTIME_R */
173 #endif /* ! defined (_LIBC) */
176 #if !defined (memset) && !defined (HAVE_MEMSET) && !defined (_LIBC)
177 /* Some systems lack the `memset' function and we don't want to
178 introduce additional dependencies. */
179 static const char spaces
[16] = " ";
180 static const char zeroes
[16] = "0000000000000000";
182 # define memset_space(P, Len) \
188 int _this = _len > 16 ? 16 : _len; \
189 memcpy ((P), spaces, _this); \
196 # define memset_zero(P, Len) \
202 int _this = _len > 16 ? 16 : _len; \
203 memcpy ((P), zeroes, _this); \
210 # define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
211 # define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
218 int _delta = width - _n; \
219 int _incr = _n + (_delta > 0 ? _delta : 0); \
220 if (i + _incr >= maxsize) \
227 memset_zero (p, _delta); \
229 memset_space (p, _delta); \
240 memcpy_lowcase (p, (s), _n); \
241 else if (to_uppcase) \
242 memcpy_uppcase (p, (s), _n); \
244 memcpy ((PTR) p, (PTR) (s), _n))
249 # define TOUPPER(Ch) toupper (Ch)
250 # define TOLOWER(Ch) tolower (Ch)
252 # define TOUPPER(Ch) (islower (Ch) ? toupper (Ch) : (Ch))
253 # define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
255 /* We don't use `isdigit' here since the locale dependent
256 interpretation is not what we want here. We only need to accept
257 the arabic digits in the ASCII range. One day there is perhaps a
258 more reliable way to accept other sets of digits. */
259 #define ISDIGIT(Ch) ((unsigned int) (Ch) - '0' <= 9)
261 static char *memcpy_lowcase
__P ((char *dest
, const char *src
, size_t len
));
264 memcpy_lowcase (dest
, src
, len
)
270 dest
[len
] = TOLOWER (src
[len
]);
274 static char *memcpy_uppcase
__P ((char *dest
, const char *src
, size_t len
));
277 memcpy_uppcase (dest
, src
, len
)
283 dest
[len
] = TOUPPER (src
[len
]);
288 /* Yield the difference between *A and *B,
289 measured in seconds, ignoring leap seconds. */
290 static int tm_diff
__P ((const struct tm
*, const struct tm
*));
296 /* Compute intervening leap days correctly even if year is negative.
297 Take care to avoid int overflow in leap day calculations,
298 but it's OK to assume that A and B are close to each other. */
299 int a4
= (a
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (a
->tm_year
& 3);
300 int b4
= (b
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (b
->tm_year
& 3);
301 int a100
= a4
/ 25 - (a4
% 25 < 0);
302 int b100
= b4
/ 25 - (b4
% 25 < 0);
303 int a400
= a100
>> 2;
304 int b400
= b100
>> 2;
305 int intervening_leap_days
= (a4
- b4
) - (a100
- b100
) + (a400
- b400
);
306 int years
= a
->tm_year
- b
->tm_year
;
307 int days
= (365 * years
+ intervening_leap_days
308 + (a
->tm_yday
- b
->tm_yday
));
309 return (60 * (60 * (24 * days
+ (a
->tm_hour
- b
->tm_hour
))
310 + (a
->tm_min
- b
->tm_min
))
311 + (a
->tm_sec
- b
->tm_sec
));
313 #endif /* ! HAVE_TM_GMTOFF */
317 /* The number of days from the first day of the first ISO week of this
318 year to the year day YDAY with week day WDAY. ISO weeks start on
319 Monday; the first ISO week has the year's first Thursday. YDAY may
320 be as small as YDAY_MINIMUM. */
321 #define ISO_WEEK_START_WDAY 1 /* Monday */
322 #define ISO_WEEK1_WDAY 4 /* Thursday */
323 #define YDAY_MINIMUM (-366)
324 static int iso_week_days
__P ((int, int));
329 iso_week_days (yday
, wday
)
333 /* Add enough to the first operand of % to make it nonnegative. */
334 int big_enough_multiple_of_7
= (-YDAY_MINIMUM
/ 7 + 2) * 7;
336 - (yday
- wday
+ ISO_WEEK1_WDAY
+ big_enough_multiple_of_7
) % 7
337 + ISO_WEEK1_WDAY
- ISO_WEEK_START_WDAY
);
342 static char const weekday_name
[][10] =
344 "Sunday", "Monday", "Tuesday", "Wednesday",
345 "Thursday", "Friday", "Saturday"
347 static char const month_name
[][10] =
349 "January", "February", "March", "April", "May", "June",
350 "July", "August", "September", "October", "November", "December"
355 #if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
356 /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
357 Work around this bug by copying *tp before it might be munged. */
358 size_t _strftime_copytm
__P ((char *, size_t, const char *,
361 strftime (s
, maxsize
, format
, tp
)
369 return _strftime_copytm (s
, maxsize
, format
, &tmcopy
);
374 # define strftime(S, Maxsize, Format, Tp) \
375 _strftime_copytm (S, Maxsize, Format, Tp)
379 /* Write information from TP into S according to the format
380 string FORMAT, writing no more that MAXSIZE characters
381 (including the terminating '\0') and returning number of
382 characters written. If S is NULL, nothing will be written
383 anywhere, so to determine how many characters would be
384 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
386 strftime (s
, maxsize
, format
, tp
)
392 int hour12
= tp
->tm_hour
;
394 const char *const a_wkday
= _NL_CURRENT (LC_TIME
, ABDAY_1
+ tp
->tm_wday
);
395 const char *const f_wkday
= _NL_CURRENT (LC_TIME
, DAY_1
+ tp
->tm_wday
);
396 const char *const a_month
= _NL_CURRENT (LC_TIME
, ABMON_1
+ tp
->tm_mon
);
397 const char *const f_month
= _NL_CURRENT (LC_TIME
, MON_1
+ tp
->tm_mon
);
398 const char *const ampm
= _NL_CURRENT (LC_TIME
,
399 hour12
> 11 ? PM_STR
: AM_STR
);
400 size_t aw_len
= strlen (a_wkday
);
401 size_t am_len
= strlen (a_month
);
402 size_t ap_len
= strlen (ampm
);
404 const char *const f_wkday
= weekday_name
[tp
->tm_wday
];
405 const char *const f_month
= month_name
[tp
->tm_mon
];
406 const char *const a_wkday
= f_wkday
;
407 const char *const a_month
= f_month
;
408 const char *const ampm
= "AMPM" + 2 * (hour12
> 11);
413 size_t wkday_len
= strlen (f_wkday
);
414 size_t month_len
= strlen (f_month
);
422 #if !defined _LIBC && HAVE_TM_ZONE
423 /* XXX We have some problems here. First, the string pointed to by
424 tm_zone is dynamically allocated while loading the zone data. But
425 when another zone is loaded since the information in TP were
426 computed this would be a stale pointer.
427 The second problem is the POSIX test suite which assumes setting
428 the environment variable TZ to a new value before calling strftime()
429 will influence the result (the %Z format) even if the information in
430 TP is computed with a totally different time zone. --drepper@gnu */
431 zone
= (const char *) tp
->tm_zone
;
434 /* POSIX.1 8.1.1 requires that whenever strftime() is called, the
435 time zone names contained in the external variable `tzname' shall
436 be set as if the tzset() function had been called. */
441 if (!(zone
&& *zone
) && tp
->tm_isdst
>= 0)
442 zone
= tzname
[tp
->tm_isdst
];
445 zone
= ""; /* POSIX.2 requires the empty string here. */
447 zonelen
= strlen (zone
);
452 if (hour12
== 0) hour12
= 12;
454 for (f
= format
; *f
!= '\0'; ++f
)
456 int pad
; /* Padding for number ('-', '_', or 0). */
457 int modifier
; /* Field modifier ('E', 'O', or 0). */
458 int digits
; /* Max digits for numeric format. */
459 int number_value
; /* Numeric value to be printed. */
460 int negative_number
; /* 1 if the number is negative. */
463 char buf
[1 + (sizeof (int) < sizeof (time_t)
464 ? INT_STRLEN_BOUND (time_t)
465 : 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. */
567 /* As a GNU extension we allow to specify the field width. */
577 while (ISDIGIT (*f
));
580 /* Check for modifiers. */
593 /* Now do the specified format. */
596 #define DO_NUMBER(d, v) \
597 digits = d; number_value = v; goto do_number
598 #define DO_NUMBER_SPACEPAD(d, v) \
599 digits = d; number_value = v; goto do_number_spacepad
610 cpy (aw_len
, a_wkday
);
616 cpy (wkday_len
, f_wkday
);
620 case 'h': /* POSIX.2 extension. */
623 cpy (am_len
, a_month
);
629 cpy (month_len
, f_month
);
636 if (! (modifier
== 'E'
637 && *(subfmt
= _NL_CURRENT (LC_TIME
, ERA_D_T_FMT
)) != '\0'))
638 subfmt
= _NL_CURRENT (LC_TIME
, D_T_FMT
);
640 subfmt
= "%a %b %e %H:%M:%S %Y";
646 size_t len
= strftime (NULL
, maxsize
- i
, subfmt
, tp
);
647 if (len
== 0 && *subfmt
)
649 add (len
, strftime (p
, maxsize
- i
, subfmt
, tp
));
652 while (old_start
< p
)
654 *old_start
= TOUPPER (*old_start
);
660 case 'C': /* POSIX.2 extension. */
663 #if HAVE_STRUCT_ERA_ENTRY
666 struct era_entry
*era
= _nl_get_era_entry (tp
);
669 size_t len
= strlen (era
->name_fmt
);
670 cpy (len
, era
->name_fmt
);
676 int year
= tp
->tm_year
+ TM_YEAR_BASE
;
677 DO_NUMBER (1, year
/ 100 - (year
% 100 < 0));
684 if (! (modifier
== 'E'
685 && *(subfmt
= _NL_CURRENT (LC_TIME
, ERA_D_FMT
)) != '\0'))
686 subfmt
= _NL_CURRENT (LC_TIME
, D_FMT
);
690 case 'D': /* POSIX.2 extension. */
700 DO_NUMBER (2, tp
->tm_mday
);
702 case 'e': /* POSIX.2 extension. */
706 DO_NUMBER_SPACEPAD (2, tp
->tm_mday
);
708 /* All numeric formats set DIGITS and NUMBER_VALUE and then
709 jump to one of these two labels. */
712 /* Force `_' flag unless overwritten by `0' flag. */
717 /* Format the number according to the MODIFIER flag. */
720 if (modifier
== 'O' && 0 <= number_value
)
722 /* Get the locale specific alternate representation of
723 the number NUMBER_VALUE. If none exist NULL is returned. */
724 const char *cp
= _nl_get_alt_digit (number_value
);
728 size_t digitlen
= strlen (cp
);
738 unsigned int u
= number_value
;
740 bufp
= buf
+ sizeof (buf
);
741 negative_number
= number_value
< 0;
747 *--bufp
= u
% 10 + '0';
748 while ((u
/= 10) != 0);
751 do_number_sign_and_padding
:
757 int padding
= digits
- (buf
+ sizeof (buf
) - bufp
);
761 while (0 < padding
--)
766 bufp
+= negative_number
;
767 while (0 < padding
--)
774 cpy (buf
+ sizeof (buf
) - bufp
, bufp
);
782 DO_NUMBER (2, tp
->tm_hour
);
788 DO_NUMBER (2, hour12
);
790 case 'k': /* GNU extension. */
794 DO_NUMBER_SPACEPAD (2, tp
->tm_hour
);
796 case 'l': /* GNU extension. */
800 DO_NUMBER_SPACEPAD (2, hour12
);
806 DO_NUMBER (3, 1 + tp
->tm_yday
);
812 DO_NUMBER (2, tp
->tm_min
);
818 DO_NUMBER (2, tp
->tm_mon
+ 1);
820 case 'n': /* POSIX.2 extension. */
832 case 'R': /* GNU extension. */
836 case 'r': /* POSIX.2 extension. */
838 if (*(subfmt
= _NL_CURRENT (LC_TIME
, T_FMT_AMPM
)) == '\0')
840 subfmt
= "%I:%M:%S %p";
847 DO_NUMBER (2, tp
->tm_sec
);
849 case 's': /* GNU extension. */
857 /* Generate string value for T using time_t arithmetic;
858 this works even if sizeof (long) < sizeof (time_t). */
860 bufp
= buf
+ sizeof (buf
);
861 negative_number
= t
< 0;
872 /* Adjust if division truncates to minus infinity. */
873 if (0 < -1 % 10 && d
< 0)
885 goto do_number_sign_and_padding
;
892 if (! (modifier
== 'E'
893 && *(subfmt
= _NL_CURRENT (LC_TIME
, ERA_T_FMT
)) != '\0'))
894 subfmt
= _NL_CURRENT (LC_TIME
, T_FMT
);
898 case 'T': /* POSIX.2 extension. */
902 case 't': /* POSIX.2 extension. */
906 case 'u': /* POSIX.2 extension. */
907 DO_NUMBER (1, (tp
->tm_wday
- 1 + 7) % 7 + 1);
913 DO_NUMBER (2, (tp
->tm_yday
- tp
->tm_wday
+ 7) / 7);
916 case 'g': /* GNU extension. */
917 case 'G': /* GNU extension. */
921 int year
= tp
->tm_year
+ TM_YEAR_BASE
;
922 int days
= iso_week_days (tp
->tm_yday
, tp
->tm_wday
);
926 /* This ISO week belongs to the previous year. */
928 days
= iso_week_days (tp
->tm_yday
+ (365 + __isleap (year
)),
933 int d
= iso_week_days (tp
->tm_yday
- (365 + __isleap (year
)),
937 /* This ISO week belongs to the next year. */
946 DO_NUMBER (2, (year
% 100 + 100) % 100);
952 DO_NUMBER (2, days
/ 7 + 1);
960 DO_NUMBER (2, (tp
->tm_yday
- (tp
->tm_wday
- 1 + 7) % 7 + 7) / 7);
966 DO_NUMBER (1, tp
->tm_wday
);
969 #if HAVE_STRUCT_ERA_ENTRY
972 struct era_entry
*era
= _nl_get_era_entry (tp
);
975 subfmt
= strchr (era
->name_fmt
, '\0') + 1;
983 DO_NUMBER (1, tp
->tm_year
+ TM_YEAR_BASE
);
986 #if HAVE_STRUCT_ERA_ENTRY
989 struct era_entry
*era
= _nl_get_era_entry (tp
);
992 int delta
= tp
->tm_year
- era
->start_date
[0];
993 DO_NUMBER (1, (era
->offset
994 + (era
->direction
== '-' ? -delta
: delta
)));
998 DO_NUMBER (2, (tp
->tm_year
% 100 + 100) % 100);
1001 cpy (zonelen
, zone
);
1004 case 'z': /* GNU extension. */
1005 if (tp
->tm_isdst
< 0)
1011 diff
= tp
->tm_gmtoff
;
1020 if (lt
== (time_t) -1)
1022 /* mktime returns -1 for errors, but -1 is also a
1023 valid time_t value. Check whether an error really
1026 localtime_r (<
, &tm
);
1028 if ((ltm
.tm_sec
^ tm
.tm_sec
)
1029 | (ltm
.tm_min
^ tm
.tm_min
)
1030 | (ltm
.tm_hour
^ tm
.tm_hour
)
1031 | (ltm
.tm_mday
^ tm
.tm_mday
)
1032 | (ltm
.tm_mon
^ tm
.tm_mon
)
1033 | (ltm
.tm_year
^ tm
.tm_year
))
1037 if (! gmtime_r (<
, >m
))
1040 diff
= tm_diff (<m
, >m
);
1052 DO_NUMBER (4, (diff
/ 60) * 100 + diff
% 60);
1055 case '\0': /* GNU extension: % at end of format. */
1059 /* Unknown format; output the format, including the '%',
1060 since this is most likely the right thing to do if a
1061 multibyte string has been misparsed. */
1065 for (flen
= 1; f
[1 - flen
] != '%'; flen
++)
1067 cpy (flen
, &f
[1 - flen
]);