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 # 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_ftime_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 /* The SGI compiler reportedly barfs on the trailing null
180 if we use a string constant as the initializer. 28 June 1997, rms. */
181 static const char spaces
[16] = /* " " */
182 { ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' };
183 static const char zeroes
[16] = /* "0000000000000000" */
184 { '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0' };
186 # define memset_space(P, Len) \
192 int _this = _len > 16 ? 16 : _len; \
193 memcpy ((P), spaces, _this); \
200 # define memset_zero(P, Len) \
206 int _this = _len > 16 ? 16 : _len; \
207 memcpy ((P), zeroes, _this); \
214 # define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len))
215 # define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len))
222 int _delta = width - _n; \
223 int _incr = _n + (_delta > 0 ? _delta : 0); \
224 if (i + _incr >= maxsize) \
231 memset_zero (p, _delta); \
233 memset_space (p, _delta); \
244 memcpy_lowcase (p, (s), _n); \
245 else if (to_uppcase) \
246 memcpy_uppcase (p, (s), _n); \
248 memcpy ((PTR) p, (PTR) (s), _n))
253 # define TOUPPER(Ch) toupper (Ch)
254 # define TOLOWER(Ch) tolower (Ch)
256 # define TOUPPER(Ch) (islower (Ch) ? toupper (Ch) : (Ch))
257 # define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
259 /* We don't use `isdigit' here since the locale dependent
260 interpretation is not what we want here. We only need to accept
261 the arabic digits in the ASCII range. One day there is perhaps a
262 more reliable way to accept other sets of digits. */
263 #define ISDIGIT(Ch) ((unsigned int) (Ch) - '0' <= 9)
265 static char *memcpy_lowcase
__P ((char *dest
, const char *src
, size_t len
));
268 memcpy_lowcase (dest
, src
, len
)
274 dest
[len
] = TOLOWER (src
[len
]);
278 static char *memcpy_uppcase
__P ((char *dest
, const char *src
, size_t len
));
281 memcpy_uppcase (dest
, src
, len
)
287 dest
[len
] = TOUPPER (src
[len
]);
293 /* Yield the difference between *A and *B,
294 measured in seconds, ignoring leap seconds. */
295 # define tm_diff ftime_tm_diff
296 static int tm_diff
__P ((const struct tm
*, const struct tm
*));
302 /* Compute intervening leap days correctly even if year is negative.
303 Take care to avoid int overflow in leap day calculations,
304 but it's OK to assume that A and B are close to each other. */
305 int a4
= (a
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (a
->tm_year
& 3);
306 int b4
= (b
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (b
->tm_year
& 3);
307 int a100
= a4
/ 25 - (a4
% 25 < 0);
308 int b100
= b4
/ 25 - (b4
% 25 < 0);
309 int a400
= a100
>> 2;
310 int b400
= b100
>> 2;
311 int intervening_leap_days
= (a4
- b4
) - (a100
- b100
) + (a400
- b400
);
312 int years
= a
->tm_year
- b
->tm_year
;
313 int days
= (365 * years
+ intervening_leap_days
314 + (a
->tm_yday
- b
->tm_yday
));
315 return (60 * (60 * (24 * days
+ (a
->tm_hour
- b
->tm_hour
))
316 + (a
->tm_min
- b
->tm_min
))
317 + (a
->tm_sec
- b
->tm_sec
));
319 #endif /* ! HAVE_TM_GMTOFF */
323 /* The number of days from the first day of the first ISO week of this
324 year to the year day YDAY with week day WDAY. ISO weeks start on
325 Monday; the first ISO week has the year's first Thursday. YDAY may
326 be as small as YDAY_MINIMUM. */
327 #define ISO_WEEK_START_WDAY 1 /* Monday */
328 #define ISO_WEEK1_WDAY 4 /* Thursday */
329 #define YDAY_MINIMUM (-366)
330 static int iso_week_days
__P ((int, int));
335 iso_week_days (yday
, wday
)
339 /* Add enough to the first operand of % to make it nonnegative. */
340 int big_enough_multiple_of_7
= (-YDAY_MINIMUM
/ 7 + 2) * 7;
342 - (yday
- wday
+ ISO_WEEK1_WDAY
+ big_enough_multiple_of_7
) % 7
343 + ISO_WEEK1_WDAY
- ISO_WEEK_START_WDAY
);
348 static char const weekday_name
[][10] =
350 "Sunday", "Monday", "Tuesday", "Wednesday",
351 "Thursday", "Friday", "Saturday"
353 static char const month_name
[][10] =
355 "January", "February", "March", "April", "May", "June",
356 "July", "August", "September", "October", "November", "December"
361 #if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET
362 /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime.
363 Work around this bug by copying *tp before it might be munged. */
364 size_t _strftime_copytm
__P ((char *, size_t, const char *,
367 strftime (s
, maxsize
, format
, tp
)
375 return _strftime_copytm (s
, maxsize
, format
, &tmcopy
);
380 # define strftime(S, Maxsize, Format, Tp) \
381 _strftime_copytm (S, Maxsize, Format, Tp)
385 /* Write information from TP into S according to the format
386 string FORMAT, writing no more that MAXSIZE characters
387 (including the terminating '\0') and returning number of
388 characters written. If S is NULL, nothing will be written
389 anywhere, so to determine how many characters would be
390 written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */
392 strftime (s
, maxsize
, format
, tp
)
398 int hour12
= tp
->tm_hour
;
400 const char *const a_wkday
= _NL_CURRENT (LC_TIME
, ABDAY_1
+ tp
->tm_wday
);
401 const char *const f_wkday
= _NL_CURRENT (LC_TIME
, DAY_1
+ tp
->tm_wday
);
402 const char *const a_month
= _NL_CURRENT (LC_TIME
, ABMON_1
+ tp
->tm_mon
);
403 const char *const f_month
= _NL_CURRENT (LC_TIME
, MON_1
+ tp
->tm_mon
);
404 const char *const ampm
= _NL_CURRENT (LC_TIME
,
405 hour12
> 11 ? PM_STR
: AM_STR
);
406 size_t aw_len
= strlen (a_wkday
);
407 size_t am_len
= strlen (a_month
);
408 size_t ap_len
= strlen (ampm
);
410 const char *const f_wkday
= weekday_name
[tp
->tm_wday
];
411 const char *const f_month
= month_name
[tp
->tm_mon
];
412 const char *const a_wkday
= f_wkday
;
413 const char *const a_month
= f_month
;
414 const char *const ampm
= "AMPM" + 2 * (hour12
> 11);
419 size_t wkday_len
= strlen (f_wkday
);
420 size_t month_len
= strlen (f_month
);
429 /* The POSIX test suite assumes that setting
430 the environment variable TZ to a new value before calling strftime()
431 will influence the result (the %Z format) even if the information in
432 TP is computed with a totally different time zone.
433 This is bogus: though POSIX allows bad behavior like this,
434 POSIX does not require it. Do the right thing instead. */
435 zone
= (const char *) tp
->tm_zone
;
438 /* POSIX.1 8.1.1 requires that whenever strftime() is called, the
439 time zone names contained in the external variable `tzname' shall
440 be set as if the tzset() function had been called. */
445 if (!(zone
&& *zone
) && tp
->tm_isdst
>= 0)
446 zone
= tzname
[tp
->tm_isdst
];
449 zone
= ""; /* POSIX.2 requires the empty string here. */
451 zonelen
= strlen (zone
);
456 if (hour12
== 0) hour12
= 12;
458 for (f
= format
; *f
!= '\0'; ++f
)
460 int pad
; /* Padding for number ('-', '_', or 0). */
461 int modifier
; /* Field modifier ('E', 'O', or 0). */
462 int digits
; /* Max digits for numeric format. */
463 int number_value
; /* Numeric value to be printed. */
464 int negative_number
; /* 1 if the number is negative. */
467 char buf
[1 + (sizeof (int) < sizeof (time_t)
468 ? INT_STRLEN_BOUND (time_t)
469 : INT_STRLEN_BOUND (int))];
482 case '\a': case '\b': case '\t': case '\n':
483 case '\v': case '\f': case '\r':
484 case ' ': case '!': case '"': case '#': case '&': case'\'':
485 case '(': case ')': case '*': case '+': case ',': case '-':
486 case '.': case '/': case '0': case '1': case '2': case '3':
487 case '4': case '5': case '6': case '7': case '8': case '9':
488 case ':': case ';': case '<': case '=': case '>': case '?':
489 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
490 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
491 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
492 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
493 case 'Y': case 'Z': case '[': case'\\': case ']': case '^':
494 case '_': case 'a': case 'b': case 'c': case 'd': case 'e':
495 case 'f': case 'g': case 'h': case 'i': case 'j': case 'k':
496 case 'l': case 'm': case 'n': case 'o': case 'p': case 'q':
497 case 'r': case 's': case 't': case 'u': case 'v': case 'w':
498 case 'x': case 'y': case 'z': case '{': case '|': case '}':
500 /* The C Standard requires these 98 characters (plus '%') to
501 be in the basic execution character set. None of these
502 characters can start a multibyte sequence, so they need
503 not be analyzed further. */
508 /* Copy this multibyte sequence until we reach its end, find
509 an error, or come back to the initial shift state. */
511 mbstate_t mbstate
= mbstate_zero
;
516 size_t bytes
= mbrlen (f
+ len
, (size_t) -1, &mbstate
);
521 if (bytes
== (size_t) -2 || bytes
== (size_t) -1)
529 while (! mbsinit (&mbstate
));
536 #else /* ! DO_MULTIBYTE */
538 /* Either multibyte encodings are not supported, or they are
539 safe for formats, so any non-'%' byte can be copied through. */
546 #endif /* ! DO_MULTIBYTE */
548 /* Check for flags that can modify a format. */
554 /* This influences the number formats. */
561 /* This changes textual output. */
575 /* As a GNU extension we allow to specify the field width. */
585 while (ISDIGIT (*f
));
588 /* Check for modifiers. */
601 /* Now do the specified format. */
604 #define DO_NUMBER(d, v) \
605 digits = width == -1 ? d : width; \
606 number_value = v; goto do_number
607 #define DO_NUMBER_SPACEPAD(d, v) \
608 digits = width == -1 ? d : width; \
609 number_value = v; goto do_number_spacepad
625 cpy (aw_len
, a_wkday
);
636 cpy (wkday_len
, f_wkday
);
640 case 'h': /* POSIX.2 extension. */
643 cpy (am_len
, a_month
);
654 cpy (month_len
, f_month
);
661 if (! (modifier
== 'E'
662 && *(subfmt
= _NL_CURRENT (LC_TIME
, ERA_D_T_FMT
)) != '\0'))
663 subfmt
= _NL_CURRENT (LC_TIME
, D_T_FMT
);
665 subfmt
= "%a %b %e %H:%M:%S %Y";
671 size_t len
= strftime (NULL
, maxsize
- i
, subfmt
, tp
);
672 if (len
== 0 && *subfmt
)
674 add (len
, strftime (p
, maxsize
- i
, subfmt
, tp
));
677 while (old_start
< p
)
679 *old_start
= TOUPPER (*old_start
);
685 case 'C': /* POSIX.2 extension. */
688 #if HAVE_STRUCT_ERA_ENTRY
691 struct era_entry
*era
= _nl_get_era_entry (tp
);
694 size_t len
= strlen (era
->name_fmt
);
695 cpy (len
, era
->name_fmt
);
701 int year
= tp
->tm_year
+ TM_YEAR_BASE
;
702 DO_NUMBER (1, year
/ 100 - (year
% 100 < 0));
709 if (! (modifier
== 'E'
710 && *(subfmt
= _NL_CURRENT (LC_TIME
, ERA_D_FMT
)) != '\0'))
711 subfmt
= _NL_CURRENT (LC_TIME
, D_FMT
);
715 case 'D': /* POSIX.2 extension. */
725 DO_NUMBER (2, tp
->tm_mday
);
727 case 'e': /* POSIX.2 extension. */
731 DO_NUMBER_SPACEPAD (2, tp
->tm_mday
);
733 /* All numeric formats set DIGITS and NUMBER_VALUE and then
734 jump to one of these two labels. */
737 /* Force `_' flag unless overwritten by `0' flag. */
742 /* Format the number according to the MODIFIER flag. */
745 if (modifier
== 'O' && 0 <= number_value
)
747 /* Get the locale specific alternate representation of
748 the number NUMBER_VALUE. If none exist NULL is returned. */
749 const char *cp
= _nl_get_alt_digit (number_value
);
753 size_t digitlen
= strlen (cp
);
763 unsigned int u
= number_value
;
765 bufp
= buf
+ sizeof (buf
);
766 negative_number
= number_value
< 0;
772 *--bufp
= u
% 10 + '0';
773 while ((u
/= 10) != 0);
776 do_number_sign_and_padding
:
782 int padding
= digits
- (buf
+ sizeof (buf
) - bufp
);
786 while (0 < padding
--)
791 bufp
+= negative_number
;
792 while (0 < padding
--)
799 cpy (buf
+ sizeof (buf
) - bufp
, bufp
);
807 DO_NUMBER (2, tp
->tm_hour
);
813 DO_NUMBER (2, hour12
);
815 case 'k': /* GNU extension. */
819 DO_NUMBER_SPACEPAD (2, tp
->tm_hour
);
821 case 'l': /* GNU extension. */
825 DO_NUMBER_SPACEPAD (2, hour12
);
831 DO_NUMBER (3, 1 + tp
->tm_yday
);
837 DO_NUMBER (2, tp
->tm_min
);
843 DO_NUMBER (2, tp
->tm_mon
+ 1);
845 case 'n': /* POSIX.2 extension. */
862 case 'R': /* GNU extension. */
866 case 'r': /* POSIX.2 extension. */
868 if (*(subfmt
= _NL_CURRENT (LC_TIME
, T_FMT_AMPM
)) == '\0')
870 subfmt
= "%I:%M:%S %p";
877 DO_NUMBER (2, tp
->tm_sec
);
879 case 's': /* GNU extension. */
887 /* Generate string value for T using time_t arithmetic;
888 this works even if sizeof (long) < sizeof (time_t). */
890 bufp
= buf
+ sizeof (buf
);
891 negative_number
= t
< 0;
902 /* Adjust if division truncates to minus infinity. */
903 if (0 < -1 % 10 && d
< 0)
915 goto do_number_sign_and_padding
;
922 if (! (modifier
== 'E'
923 && *(subfmt
= _NL_CURRENT (LC_TIME
, ERA_T_FMT
)) != '\0'))
924 subfmt
= _NL_CURRENT (LC_TIME
, T_FMT
);
928 case 'T': /* POSIX.2 extension. */
932 case 't': /* POSIX.2 extension. */
936 case 'u': /* POSIX.2 extension. */
937 DO_NUMBER (1, (tp
->tm_wday
- 1 + 7) % 7 + 1);
943 DO_NUMBER (2, (tp
->tm_yday
- tp
->tm_wday
+ 7) / 7);
946 case 'g': /* GNU extension. */
947 case 'G': /* GNU extension. */
951 int year
= tp
->tm_year
+ TM_YEAR_BASE
;
952 int days
= iso_week_days (tp
->tm_yday
, tp
->tm_wday
);
956 /* This ISO week belongs to the previous year. */
958 days
= iso_week_days (tp
->tm_yday
+ (365 + __isleap (year
)),
963 int d
= iso_week_days (tp
->tm_yday
- (365 + __isleap (year
)),
967 /* This ISO week belongs to the next year. */
976 DO_NUMBER (2, (year
% 100 + 100) % 100);
982 DO_NUMBER (2, days
/ 7 + 1);
990 DO_NUMBER (2, (tp
->tm_yday
- (tp
->tm_wday
- 1 + 7) % 7 + 7) / 7);
996 DO_NUMBER (1, tp
->tm_wday
);
999 #if HAVE_STRUCT_ERA_ENTRY
1000 if (modifier
== 'E')
1002 struct era_entry
*era
= _nl_get_era_entry (tp
);
1005 subfmt
= strchr (era
->name_fmt
, '\0') + 1;
1010 if (modifier
== 'O')
1013 DO_NUMBER (1, tp
->tm_year
+ TM_YEAR_BASE
);
1016 #if HAVE_STRUCT_ERA_ENTRY
1017 if (modifier
== 'E')
1019 struct era_entry
*era
= _nl_get_era_entry (tp
);
1022 int delta
= tp
->tm_year
- era
->start_date
[0];
1023 DO_NUMBER (1, (era
->offset
1024 + (era
->direction
== '-' ? -delta
: delta
)));
1028 DO_NUMBER (2, (tp
->tm_year
% 100 + 100) % 100);
1036 cpy (zonelen
, zone
);
1039 case 'z': /* GNU extension. */
1040 if (tp
->tm_isdst
< 0)
1046 diff
= tp
->tm_gmtoff
;
1055 if (lt
== (time_t) -1)
1057 /* mktime returns -1 for errors, but -1 is also a
1058 valid time_t value. Check whether an error really
1061 localtime_r (<
, &tm
);
1063 if ((ltm
.tm_sec
^ tm
.tm_sec
)
1064 | (ltm
.tm_min
^ tm
.tm_min
)
1065 | (ltm
.tm_hour
^ tm
.tm_hour
)
1066 | (ltm
.tm_mday
^ tm
.tm_mday
)
1067 | (ltm
.tm_mon
^ tm
.tm_mon
)
1068 | (ltm
.tm_year
^ tm
.tm_year
))
1072 if (! gmtime_r (<
, >m
))
1075 diff
= tm_diff (<m
, >m
);
1087 DO_NUMBER (4, (diff
/ 60) * 100 + diff
% 60);
1090 case '\0': /* GNU extension: % at end of format. */
1094 /* Unknown format; output the format, including the '%',
1095 since this is most likely the right thing to do if a
1096 multibyte string has been misparsed. */
1100 for (flen
= 1; f
[1 - flen
] != '%'; flen
++)
1102 cpy (flen
, &f
[1 - flen
]);