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 "../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
;
86 # define memcpy(d, s, n) bcopy ((s), (d), (n))
91 # if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
92 # define __P(args) args
114 #define TYPE_SIGNED(t) ((t) -1 < 0)
116 /* Bound on length of the string representing an integer value of type t.
117 Subtract one for the sign bit if t is signed;
118 302 / 1000 is log10 (2) rounded up;
119 add one for integer division truncation;
120 add one more for a minus sign if t is signed. */
121 #define INT_STRLEN_BOUND(t) \
122 ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 100 + 1 + TYPE_SIGNED (t))
124 #define TM_YEAR_BASE 1900
127 /* Nonzero if YEAR is a leap year (every 4 years,
128 except every 100th isn't, and every 400th is). */
129 # define __isleap(year) \
130 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
135 # define gmtime_r __gmtime_r
136 # define localtime_r __localtime_r
137 extern int __tz_compute
__P ((time_t timer
, const struct tm
*tm
));
138 # define tzname __tzname
139 # define tzset __tzset
141 # if ! HAVE_LOCALTIME_R
142 # if ! HAVE_TM_GMTOFF
143 /* Approximate gmtime_r as best we can in its absence. */
144 # define gmtime_r my_gmtime_r
145 static struct tm
*gmtime_r
__P ((const time_t *, struct tm
*));
151 struct tm
*l
= gmtime (t
);
157 # endif /* ! HAVE_TM_GMTOFF */
159 /* Approximate localtime_r as best we can in its absence. */
160 # define localtime_r my_ftime_localtime_r
161 static struct tm
*localtime_r
__P ((const time_t *, struct tm
*));
167 struct tm
*l
= localtime (t
);
173 # endif /* ! HAVE_LOCALTIME_R */
174 #endif /* ! defined (_LIBC) */
177 #if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
178 /* Some systems lack the `memset' function and we don't want to
179 introduce additional dependencies. */
180 /* The SGI compiler reportedly barfs on the trailing null
181 if we use a string constant as the initializer. 28 June 1997, rms. */
182 static const char spaces
[16] = /* " " */
183 { ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' };
184 static const char zeroes
[16] = /* "0000000000000000" */
185 { '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0' };
187 # define memset_space(P, Len) \
193 int _this = _len > 16 ? 16 : _len; \
194 memcpy ((P), spaces, _this); \
201 # define memset_zero(P, Len) \
207 int _this = _len > 16 ? 16 : _len; \
208 memcpy ((P), zeroes, _this); \
215 # define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
216 # define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
223 int _delta = width - _n; \
224 int _incr = _n + (_delta > 0 ? _delta : 0); \
225 if (i + _incr >= maxsize) \
232 memset_zero (p, _delta); \
234 memset_space (p, _delta); \
245 memcpy_lowcase (p, (s), _n); \
246 else if (to_uppcase) \
247 memcpy_uppcase (p, (s), _n); \
249 memcpy ((PTR) p, (PTR) (s), _n))
254 # define TOUPPER(Ch) toupper (Ch)
255 # define TOLOWER(Ch) tolower (Ch)
257 # define TOUPPER(Ch) (islower (Ch) ? toupper (Ch) : (Ch))
258 # define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
260 /* We don't use `isdigit' here since the locale dependent
261 interpretation is not what we want here. We only need to accept
262 the arabic digits in the ASCII range. One day there is perhaps a
263 more reliable way to accept other sets of digits. */
264 #define ISDIGIT(Ch) ((unsigned int) (Ch) - '0' <= 9)
266 static char *memcpy_lowcase
__P ((char *dest
, const char *src
, size_t len
));
269 memcpy_lowcase (dest
, src
, len
)
275 dest
[len
] = TOLOWER (src
[len
]);
279 static char *memcpy_uppcase
__P ((char *dest
, const char *src
, size_t len
));
282 memcpy_uppcase (dest
, src
, len
)
288 dest
[len
] = TOUPPER (src
[len
]);
294 /* Yield the difference between *A and *B,
295 measured in seconds, ignoring leap seconds. */
296 # define tm_diff ftime_tm_diff
297 static int tm_diff
__P ((const struct tm
*, const struct tm
*));
303 /* Compute intervening leap days correctly even if year is negative.
304 Take care to avoid int overflow in leap day calculations,
305 but it's OK to assume that A and B are close to each other. */
306 int a4
= (a
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (a
->tm_year
& 3);
307 int b4
= (b
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (b
->tm_year
& 3);
308 int a100
= a4
/ 25 - (a4
% 25 < 0);
309 int b100
= b4
/ 25 - (b4
% 25 < 0);
310 int a400
= a100
>> 2;
311 int b400
= b100
>> 2;
312 int intervening_leap_days
= (a4
- b4
) - (a100
- b100
) + (a400
- b400
);
313 int years
= a
->tm_year
- b
->tm_year
;
314 int days
= (365 * years
+ intervening_leap_days
315 + (a
->tm_yday
- b
->tm_yday
));
316 return (60 * (60 * (24 * days
+ (a
->tm_hour
- b
->tm_hour
))
317 + (a
->tm_min
- b
->tm_min
))
318 + (a
->tm_sec
- b
->tm_sec
));
320 #endif /* ! HAVE_TM_GMTOFF */
324 /* The number of days from the first day of the first ISO week of this
325 year to the year day YDAY with week day WDAY. ISO weeks start on
326 Monday; the first ISO week has the year's first Thursday. YDAY may
327 be as small as YDAY_MINIMUM. */
328 #define ISO_WEEK_START_WDAY 1 /* Monday */
329 #define ISO_WEEK1_WDAY 4 /* Thursday */
330 #define YDAY_MINIMUM (-366)
331 static int iso_week_days
__P ((int, int));
336 iso_week_days (yday
, wday
)
340 /* Add enough to the first operand of % to make it nonnegative. */
341 int big_enough_multiple_of_7
= (-YDAY_MINIMUM
/ 7 + 2) * 7;
343 - (yday
- wday
+ ISO_WEEK1_WDAY
+ big_enough_multiple_of_7
) % 7
344 + ISO_WEEK1_WDAY
- ISO_WEEK_START_WDAY
);
349 static char const weekday_name
[][10] =
351 "Sunday", "Monday", "Tuesday", "Wednesday",
352 "Thursday", "Friday", "Saturday"
354 static char const month_name
[][10] =
356 "January", "February", "March", "April", "May", "June",
357 "July", "August", "September", "October", "November", "December"
362 #if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
363 /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
364 Work around this bug by copying *tp before it might be munged. */
365 size_t _strftime_copytm
__P ((char *, size_t, const char *,
368 strftime (s
, maxsize
, format
, tp
)
376 return _strftime_copytm (s
, maxsize
, format
, &tmcopy
);
381 # define strftime(S, Maxsize, Format, Tp) \
382 _strftime_copytm (S, Maxsize, Format, Tp)
386 /* Write information from TP into S according to the format
387 string FORMAT, writing no more that MAXSIZE characters
388 (including the terminating '\0') and returning number of
389 characters written. If S is NULL, nothing will be written
390 anywhere, so to determine how many characters would be
391 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
393 strftime (s
, maxsize
, format
, tp
)
399 int hour12
= tp
->tm_hour
;
401 const char *const a_wkday
= _NL_CURRENT (LC_TIME
, ABDAY_1
+ tp
->tm_wday
);
402 const char *const f_wkday
= _NL_CURRENT (LC_TIME
, DAY_1
+ tp
->tm_wday
);
403 const char *const a_month
= _NL_CURRENT (LC_TIME
, ABMON_1
+ tp
->tm_mon
);
404 const char *const f_month
= _NL_CURRENT (LC_TIME
, MON_1
+ tp
->tm_mon
);
405 const char *const ampm
= _NL_CURRENT (LC_TIME
,
406 hour12
> 11 ? PM_STR
: AM_STR
);
407 size_t aw_len
= strlen (a_wkday
);
408 size_t am_len
= strlen (a_month
);
409 size_t ap_len
= strlen (ampm
);
411 const char *const f_wkday
= weekday_name
[tp
->tm_wday
];
412 const char *const f_month
= month_name
[tp
->tm_mon
];
413 const char *const a_wkday
= f_wkday
;
414 const char *const a_month
= f_month
;
415 const char *const ampm
= "AMPM" + 2 * (hour12
> 11);
420 size_t wkday_len
= strlen (f_wkday
);
421 size_t month_len
= strlen (f_month
);
430 /* The POSIX test suite assumes that setting
431 the environment variable TZ to a new value before calling strftime()
432 will influence the result (the %Z format) even if the information in
433 TP is computed with a totally different time zone.
434 This is bogus: though POSIX allows bad behavior like this,
435 POSIX does not require it. Do the right thing instead. */
436 zone
= (const char *) tp
->tm_zone
;
439 /* POSIX.1 8.1.1 requires that whenever strftime() is called, the
440 time zone names contained in the external variable `tzname' shall
441 be set as if the tzset() function had been called. */
446 if (!(zone
&& *zone
) && tp
->tm_isdst
>= 0)
447 zone
= tzname
[tp
->tm_isdst
];
450 zone
= ""; /* POSIX.2 requires the empty string here. */
452 zonelen
= strlen (zone
);
457 if (hour12
== 0) hour12
= 12;
459 for (f
= format
; *f
!= '\0'; ++f
)
461 int pad
; /* Padding for number ('-', '_', or 0). */
462 int modifier
; /* Field modifier ('E', 'O', or 0). */
463 int digits
; /* Max digits for numeric format. */
464 int number_value
; /* Numeric value to be printed. */
465 int negative_number
; /* 1 if the number is negative. */
468 char buf
[1 + (sizeof (int) < sizeof (time_t)
469 ? INT_STRLEN_BOUND (time_t)
470 : INT_STRLEN_BOUND (int))];
483 case '\a': case '\b': case '\t': case '\n':
484 case '\v': case '\f': case '\r':
485 case ' ': case '!': case '"': case '#': case '&': case'\'':
486 case '(': case ')': case '*': case '+': case ',': case '-':
487 case '.': case '/': case '0': case '1': case '2': case '3':
488 case '4': case '5': case '6': case '7': case '8': case '9':
489 case ':': case ';': case '<': case '=': case '>': case '?':
490 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
491 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
492 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
493 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
494 case 'Y': case 'Z': case '[': case'\\': case ']': case '^':
495 case '_': case 'a': case 'b': case 'c': case 'd': case 'e':
496 case 'f': case 'g': case 'h': case 'i': case 'j': case 'k':
497 case 'l': case 'm': case 'n': case 'o': case 'p': case 'q':
498 case 'r': case 's': case 't': case 'u': case 'v': case 'w':
499 case 'x': case 'y': case 'z': case '{': case '|': case '}':
501 /* The C Standard requires these 98 characters (plus '%') to
502 be in the basic execution character set. None of these
503 characters can start a multibyte sequence, so they need
504 not be analyzed further. */
509 /* Copy this multibyte sequence until we reach its end, find
510 an error, or come back to the initial shift state. */
512 mbstate_t mbstate
= mbstate_zero
;
517 size_t bytes
= mbrlen (f
+ len
, (size_t) -1, &mbstate
);
522 if (bytes
== (size_t) -2 || bytes
== (size_t) -1)
530 while (! mbsinit (&mbstate
));
537 #else /* ! DO_MULTIBYTE */
539 /* Either multibyte encodings are not supported, or they are
540 safe for formats, so any non-'%' byte can be copied through. */
547 #endif /* ! DO_MULTIBYTE */
549 /* Check for flags that can modify a format. */
555 /* This influences the number formats. */
562 /* This changes textual output. */
576 /* As a GNU extension we allow to specify the field width. */
586 while (ISDIGIT (*f
));
589 /* Check for modifiers. */
602 /* Now do the specified format. */
605 #define DO_NUMBER(d, v) \
606 digits = width == -1 ? d : width; \
607 number_value = v; goto do_number
608 #define DO_NUMBER_SPACEPAD(d, v) \
609 digits = width == -1 ? d : width; \
610 number_value = v; goto do_number_spacepad
626 cpy (aw_len
, a_wkday
);
637 cpy (wkday_len
, f_wkday
);
641 case 'h': /* POSIX.2 extension. */
644 cpy (am_len
, a_month
);
655 cpy (month_len
, f_month
);
662 if (! (modifier
== 'E'
663 && *(subfmt
= _NL_CURRENT (LC_TIME
, ERA_D_T_FMT
)) != '\0'))
664 subfmt
= _NL_CURRENT (LC_TIME
, D_T_FMT
);
666 subfmt
= "%a %b %e %H:%M:%S %Y";
672 size_t len
= strftime (NULL
, maxsize
- i
, subfmt
, tp
);
673 if (len
== 0 && *subfmt
)
675 add (len
, strftime (p
, maxsize
- i
, subfmt
, tp
));
678 while (old_start
< p
)
680 *old_start
= TOUPPER (*old_start
);
686 case 'C': /* POSIX.2 extension. */
689 #if HAVE_STRUCT_ERA_ENTRY
692 struct era_entry
*era
= _nl_get_era_entry (tp
);
695 size_t len
= strlen (era
->name_fmt
);
696 cpy (len
, era
->name_fmt
);
702 int year
= tp
->tm_year
+ TM_YEAR_BASE
;
703 DO_NUMBER (1, year
/ 100 - (year
% 100 < 0));
710 if (! (modifier
== 'E'
711 && *(subfmt
= _NL_CURRENT (LC_TIME
, ERA_D_FMT
)) != '\0'))
712 subfmt
= _NL_CURRENT (LC_TIME
, D_FMT
);
716 case 'D': /* POSIX.2 extension. */
726 DO_NUMBER (2, tp
->tm_mday
);
728 case 'e': /* POSIX.2 extension. */
732 DO_NUMBER_SPACEPAD (2, tp
->tm_mday
);
734 /* All numeric formats set DIGITS and NUMBER_VALUE and then
735 jump to one of these two labels. */
738 /* Force `_' flag unless overwritten by `0' flag. */
743 /* Format the number according to the MODIFIER flag. */
746 if (modifier
== 'O' && 0 <= number_value
)
748 /* Get the locale specific alternate representation of
749 the number NUMBER_VALUE. If none exist NULL is returned. */
750 const char *cp
= _nl_get_alt_digit (number_value
);
754 size_t digitlen
= strlen (cp
);
764 unsigned int u
= number_value
;
766 bufp
= buf
+ sizeof (buf
);
767 negative_number
= number_value
< 0;
773 *--bufp
= u
% 10 + '0';
774 while ((u
/= 10) != 0);
777 do_number_sign_and_padding
:
783 int padding
= digits
- (buf
+ sizeof (buf
) - bufp
);
787 while (0 < padding
--)
792 bufp
+= negative_number
;
793 while (0 < padding
--)
800 cpy (buf
+ sizeof (buf
) - bufp
, bufp
);
808 DO_NUMBER (2, tp
->tm_hour
);
814 DO_NUMBER (2, hour12
);
816 case 'k': /* GNU extension. */
820 DO_NUMBER_SPACEPAD (2, tp
->tm_hour
);
822 case 'l': /* GNU extension. */
826 DO_NUMBER_SPACEPAD (2, hour12
);
832 DO_NUMBER (3, 1 + tp
->tm_yday
);
838 DO_NUMBER (2, tp
->tm_min
);
844 DO_NUMBER (2, tp
->tm_mon
+ 1);
846 case 'n': /* POSIX.2 extension. */
863 case 'R': /* GNU extension. */
867 case 'r': /* POSIX.2 extension. */
869 if (*(subfmt
= _NL_CURRENT (LC_TIME
, T_FMT_AMPM
)) == '\0')
871 subfmt
= "%I:%M:%S %p";
878 DO_NUMBER (2, tp
->tm_sec
);
880 case 's': /* GNU extension. */
888 /* Generate string value for T using time_t arithmetic;
889 this works even if sizeof (long) < sizeof (time_t). */
891 bufp
= buf
+ sizeof (buf
);
892 negative_number
= t
< 0;
903 /* Adjust if division truncates to minus infinity. */
904 if (0 < -1 % 10 && d
< 0)
916 goto do_number_sign_and_padding
;
923 if (! (modifier
== 'E'
924 && *(subfmt
= _NL_CURRENT (LC_TIME
, ERA_T_FMT
)) != '\0'))
925 subfmt
= _NL_CURRENT (LC_TIME
, T_FMT
);
929 case 'T': /* POSIX.2 extension. */
933 case 't': /* POSIX.2 extension. */
937 case 'u': /* POSIX.2 extension. */
938 DO_NUMBER (1, (tp
->tm_wday
- 1 + 7) % 7 + 1);
944 DO_NUMBER (2, (tp
->tm_yday
- tp
->tm_wday
+ 7) / 7);
947 case 'g': /* GNU extension. */
948 case 'G': /* GNU extension. */
952 int year
= tp
->tm_year
+ TM_YEAR_BASE
;
953 int days
= iso_week_days (tp
->tm_yday
, tp
->tm_wday
);
957 /* This ISO week belongs to the previous year. */
959 days
= iso_week_days (tp
->tm_yday
+ (365 + __isleap (year
)),
964 int d
= iso_week_days (tp
->tm_yday
- (365 + __isleap (year
)),
968 /* This ISO week belongs to the next year. */
977 DO_NUMBER (2, (year
% 100 + 100) % 100);
983 DO_NUMBER (2, days
/ 7 + 1);
991 DO_NUMBER (2, (tp
->tm_yday
- (tp
->tm_wday
- 1 + 7) % 7 + 7) / 7);
997 DO_NUMBER (1, tp
->tm_wday
);
1000 #if HAVE_STRUCT_ERA_ENTRY
1001 if (modifier
== 'E')
1003 struct era_entry
*era
= _nl_get_era_entry (tp
);
1006 subfmt
= strchr (era
->name_fmt
, '\0') + 1;
1011 if (modifier
== 'O')
1014 DO_NUMBER (1, tp
->tm_year
+ TM_YEAR_BASE
);
1017 #if HAVE_STRUCT_ERA_ENTRY
1018 if (modifier
== 'E')
1020 struct era_entry
*era
= _nl_get_era_entry (tp
);
1023 int delta
= tp
->tm_year
- era
->start_date
[0];
1024 DO_NUMBER (1, (era
->offset
1025 + (era
->direction
== '-' ? -delta
: delta
)));
1029 DO_NUMBER (2, (tp
->tm_year
% 100 + 100) % 100);
1037 cpy (zonelen
, zone
);
1040 case 'z': /* GNU extension. */
1041 if (tp
->tm_isdst
< 0)
1047 diff
= tp
->tm_gmtoff
;
1056 if (lt
== (time_t) -1)
1058 /* mktime returns -1 for errors, but -1 is also a
1059 valid time_t value. Check whether an error really
1062 localtime_r (<
, &tm
);
1064 if ((ltm
.tm_sec
^ tm
.tm_sec
)
1065 | (ltm
.tm_min
^ tm
.tm_min
)
1066 | (ltm
.tm_hour
^ tm
.tm_hour
)
1067 | (ltm
.tm_mday
^ tm
.tm_mday
)
1068 | (ltm
.tm_mon
^ tm
.tm_mon
)
1069 | (ltm
.tm_year
^ tm
.tm_year
))
1073 if (! gmtime_r (<
, >m
))
1076 diff
= tm_diff (<m
, >m
);
1088 DO_NUMBER (4, (diff
/ 60) * 100 + diff
% 60);
1091 case '\0': /* GNU extension: % at end of format. */
1095 /* Unknown format; output the format, including the '%',
1096 since this is most likely the right thing to do if a
1097 multibyte string has been misparsed. */
1101 for (flen
= 1; f
[1 - flen
] != '%'; flen
++)
1103 cpy (flen
, &f
[1 - flen
]);