*** ./lib/mktime.c.ORIG Tue May 24 10:31:25 2016
--- ./lib/mktime.c Tue May 24 10:31:32 2016
***************
*** 17,29 ****
License along with the GNU C Library; if not, see
. */
! /* Define this to 1 to have a standalone program to test this implementation of
mktime. */
! #ifndef DEBUG_MKTIME
! # define DEBUG_MKTIME 0
! #endif
! #if !defined _LIBC && !DEBUG_MKTIME
# include
#endif
--- 17,27 ----
License along with the GNU C Library; if not, see
. */
! /* Define this to have a standalone program to test this implementation of
mktime. */
! /* #define DEBUG_MKTIME 1 */
! #ifndef _LIBC
# include
#endif
***************
*** 37,112 ****
#include
#include
- #include
! #include
! #include
! #if DEBUG_MKTIME
# include
# include
- # include
/* Make it work even if the system's libc has its own mktime routine. */
# undef mktime
# define mktime my_mktime
! #endif
! /* A signed type that can represent an integer number of years
! multiplied by three times the number of seconds in a year. It is
! needed when converting a tm_year value times the number of seconds
! in a year. The factor of three comes because these products need
! to be subtracted from each other, and sometimes with an offset
! added to them, without worrying about overflow.
! Much of the code uses long_int to represent time_t values, to
! lessen the hassle of dealing with platforms where time_t is
! unsigned, and because long_int should suffice to represent all
! time_t values that mktime can generate even on platforms where
! time_t is excessively wide. */
! #if INT_MAX <= LONG_MAX / 3 / 366 / 24 / 60 / 60
typedef long int long_int;
#else
typedef long long int long_int;
#endif
! verify (INT_MAX <= TYPE_MAXIMUM (long_int) / 3 / 366 / 24 / 60 / 60);
/* Shift A right by B bits portably, by dividing A by 2**B and
! truncating towards minus infinity. B should be in the range 0 <= B
! <= LONG_INT_BITS - 2, where LONG_INT_BITS is the number of useful
! bits in a long_int. LONG_INT_BITS is at least 32.
ISO C99 says that A >> B is implementation-defined if A < 0. Some
implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
right in the usual way when A < 0, so SHR falls back on division if
ordinary A >> B doesn't seem to be the usual signed shift. */
! static long_int
! shr (long_int a, int b)
! {
! long_int one = 1;
! return (-one >> 1 == -1
! ? a >> b
! : a / (one << b) - (a % (one << b) < 0));
! }
! /* Bounds for the intersection of time_t and long_int. */
! static long_int const mktime_min
! = ((TYPE_SIGNED (time_t) && TYPE_MINIMUM (time_t) < TYPE_MINIMUM (long_int))
! ? TYPE_MINIMUM (long_int) : TYPE_MINIMUM (time_t));
! static long_int const mktime_max
! = (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (time_t)
! ? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (time_t));
! verify (TYPE_IS_INTEGER (time_t));
#define EPOCH_YEAR 1970
#define TM_YEAR_BASE 1900
! verify (TM_YEAR_BASE % 100 == 0);
! /* Is YEAR + TM_YEAR_BASE a leap year? */
! static bool
leapyear (long_int year)
{
/* Don't add YEAR to TM_YEAR_BASE, as that might overflow.
--- 35,148 ----
#include
#include
! #include /* For the real memcpy prototype. */
! #if defined DEBUG_MKTIME && DEBUG_MKTIME
# include
# include
/* Make it work even if the system's libc has its own mktime routine. */
# undef mktime
# define mktime my_mktime
! #endif /* DEBUG_MKTIME */
! /* Some of the code in this file assumes that signed integer overflow
! silently wraps around. This assumption can't easily be programmed
! around, nor can it be checked for portably at compile-time or
! easily eliminated at run-time.
! Define WRAPV to 1 if the assumption is valid and if
! #pragma GCC optimize ("wrapv")
! does not trigger GCC bug 51793
! .
! Otherwise, define it to 0; this forces the use of slower code that,
! while not guaranteed by the C Standard, works on all production
! platforms that we know about. */
! #ifndef WRAPV
! # if (((__GNUC__ == 4 && 4 <= __GNUC_MINOR__) || 4 < __GNUC__) \
! && defined __GLIBC__)
! # pragma GCC optimize ("wrapv")
! # define WRAPV 1
! # else
! # define WRAPV 0
! # endif
! #endif
! /* Verify a requirement at compile-time (unlike assert, which is runtime). */
! #define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
!
! /* A signed type that is at least one bit wider than int. */
! #if INT_MAX <= LONG_MAX / 2
typedef long int long_int;
#else
typedef long long int long_int;
#endif
! verify (long_int_is_wide_enough, INT_MAX == INT_MAX * (long_int) 2 / 2);
/* Shift A right by B bits portably, by dividing A by 2**B and
! truncating towards minus infinity. A and B should be free of side
! effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
! INT_BITS is the number of useful bits in an int. GNU code can
! assume that INT_BITS is at least 32.
ISO C99 says that A >> B is implementation-defined if A < 0. Some
implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
right in the usual way when A < 0, so SHR falls back on division if
ordinary A >> B doesn't seem to be the usual signed shift. */
+ #define SHR(a, b) \
+ ((-1 >> 1 == -1 \
+ && (long_int) -1 >> 1 == -1 \
+ && ((time_t) -1 >> 1 == -1 || ! TYPE_SIGNED (time_t))) \
+ ? (a) >> (b) \
+ : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
! /* The extra casts in the following macros work around compiler bugs,
! e.g., in Cray C 5.0.3.0. */
! /* True if the arithmetic type T is an integer type. bool counts as
! an integer. */
! #define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)
! /* True if negative values of the signed integer type T use two's
! complement, or if T is an unsigned integer type. */
! #define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1)
! /* True if the arithmetic type T is signed. */
! #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+ /* The maximum and minimum values for the integer type T. These
+ macros have undefined behavior if T is signed and has padding bits.
+ If this is a problem for you, please let us know how to fix it for
+ your host. */
+ #define TYPE_MINIMUM(t) \
+ ((t) (! TYPE_SIGNED (t) \
+ ? (t) 0 \
+ : ~ TYPE_MAXIMUM (t)))
+ #define TYPE_MAXIMUM(t) \
+ ((t) (! TYPE_SIGNED (t) \
+ ? (t) -1 \
+ : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
+
+ #ifndef TIME_T_MIN
+ # define TIME_T_MIN TYPE_MINIMUM (time_t)
+ #endif
+ #ifndef TIME_T_MAX
+ # define TIME_T_MAX TYPE_MAXIMUM (time_t)
+ #endif
+ #define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1)
+
+ verify (time_t_is_integer, TYPE_IS_INTEGER (time_t));
+ verify (twos_complement_arithmetic,
+ (TYPE_TWOS_COMPLEMENT (int)
+ && TYPE_TWOS_COMPLEMENT (long_int)
+ && TYPE_TWOS_COMPLEMENT (time_t)));
+
#define EPOCH_YEAR 1970
#define TM_YEAR_BASE 1900
! verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0);
! /* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */
! static int
leapyear (long_int year)
{
/* Don't add YEAR to TM_YEAR_BASE, as that might overflow.
***************
*** 130,138 ****
};
! #ifdef _LIBC
! typedef time_t mktime_offset_t;
! #else
/* Portable standalone applications should supply a that
declares a POSIX-compliant localtime_r, for the benefit of older
implementations that lack localtime_r or have a nonstandard one.
--- 166,172 ----
};
! #ifndef _LIBC
/* Portable standalone applications should supply a that
declares a POSIX-compliant localtime_r, for the benefit of older
implementations that lack localtime_r or have a nonstandard one.
***************
*** 143,151 ****
# include "mktime-internal.h"
#endif
! /* Do the values A and B differ according to the rules for tm_isdst?
! A and B differ if one is zero and the other positive. */
! static bool
isdst_differ (int a, int b)
{
return (!a != !b) && (0 <= a) && (0 <= b);
--- 177,185 ----
# include "mktime-internal.h"
#endif
! /* Return 1 if the values A and B differ according to the rules for
! tm_isdst: A and B differ if one is zero and the other positive. */
! static int
isdst_differ (int a, int b)
{
return (!a != !b) && (0 <= a) && (0 <= b);
***************
*** 156,220 ****
were not adjusted between the time stamps.
The YEAR values uses the same numbering as TP->tm_year. Values
! need not be in the usual range. However, YEAR1 must not overflow
! when multiplied by three times the number of seconds in a year, and
! likewise for YDAY1 and three times the number of seconds in a day. */
! static long_int
ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1,
int year0, int yday0, int hour0, int min0, int sec0)
{
! verify (-1 / 2 == 0);
/* Compute intervening leap days correctly even if year is negative.
Take care to avoid integer overflow here. */
! int a4 = shr (year1, 2) + shr (TM_YEAR_BASE, 2) - ! (year1 & 3);
! int b4 = shr (year0, 2) + shr (TM_YEAR_BASE, 2) - ! (year0 & 3);
int a100 = a4 / 25 - (a4 % 25 < 0);
int b100 = b4 / 25 - (b4 % 25 < 0);
! int a400 = shr (a100, 2);
! int b400 = shr (b100, 2);
int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
! /* Compute the desired time without overflowing. */
! long_int years = year1 - year0;
! long_int days = 365 * years + yday1 - yday0 + intervening_leap_days;
! long_int hours = 24 * days + hour1 - hour0;
! long_int minutes = 60 * hours + min1 - min0;
! long_int seconds = 60 * minutes + sec1 - sec0;
return seconds;
}
! /* Return the average of A and B, even if A + B would overflow.
! Round toward positive infinity. */
! static long_int
! long_int_avg (long_int a, long_int b)
{
! return shr (a, 1) + shr (b, 1) + ((a | b) & 1);
}
/* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC),
! assuming that T corresponds to *TP and that no clock adjustments
occurred between *TP and the desired time.
! Although T and the returned value are of type long_int,
! they represent time_t values and must be in time_t range.
! If TP is null, return a value not equal to T; this avoids false matches.
! YEAR and YDAY must not be so large that multiplying them by three times the
! number of seconds in a year (or day, respectively) would overflow long_int.
! If the returned value would be out of range, yield the minimal or
! maximal in-range value, except do not yield a value equal to T. */
! static long_int
guess_time_tm (long_int year, long_int yday, int hour, int min, int sec,
! long_int t, const struct tm *tp)
{
if (tp)
{
! long_int result;
! long_int d = ydhms_diff (year, yday, hour, min, sec,
! tp->tm_year, tp->tm_yday,
! tp->tm_hour, tp->tm_min, tp->tm_sec);
! if (! INT_ADD_WRAPV (t, d, &result))
! return result;
}
/* Overflow occurred one way or another. Return the nearest result
--- 190,293 ----
were not adjusted between the time stamps.
The YEAR values uses the same numbering as TP->tm_year. Values
! need not be in the usual range. However, YEAR1 must not be less
! than 2 * INT_MIN or greater than 2 * INT_MAX.
! The result may overflow. It is the caller's responsibility to
! detect overflow. */
!
! static time_t
ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1,
int year0, int yday0, int hour0, int min0, int sec0)
{
! verify (C99_integer_division, -1 / 2 == 0);
/* Compute intervening leap days correctly even if year is negative.
Take care to avoid integer overflow here. */
! int a4 = SHR (year1, 2) + SHR (TM_YEAR_BASE, 2) - ! (year1 & 3);
! int b4 = SHR (year0, 2) + SHR (TM_YEAR_BASE, 2) - ! (year0 & 3);
int a100 = a4 / 25 - (a4 % 25 < 0);
int b100 = b4 / 25 - (b4 % 25 < 0);
! int a400 = SHR (a100, 2);
! int b400 = SHR (b100, 2);
int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
! /* Compute the desired time in time_t precision. Overflow might
! occur here. */
! time_t tyear1 = year1;
! time_t years = tyear1 - year0;
! time_t days = 365 * years + yday1 - yday0 + intervening_leap_days;
! time_t hours = 24 * days + hour1 - hour0;
! time_t minutes = 60 * hours + min1 - min0;
! time_t seconds = 60 * minutes + sec1 - sec0;
return seconds;
}
! /* Return the average of A and B, even if A + B would overflow. */
! static time_t
! time_t_avg (time_t a, time_t b)
{
! return SHR (a, 1) + SHR (b, 1) + (a & b & 1);
}
+ /* Return 1 if A + B does not overflow. If time_t is unsigned and if
+ B's top bit is set, assume that the sum represents A - -B, and
+ return 1 if the subtraction does not wrap around. */
+ static int
+ time_t_add_ok (time_t a, time_t b)
+ {
+ if (! TYPE_SIGNED (time_t))
+ {
+ time_t sum = a + b;
+ return (sum < a) == (TIME_T_MIDPOINT <= b);
+ }
+ else if (WRAPV)
+ {
+ time_t sum = a + b;
+ return (sum < a) == (b < 0);
+ }
+ else
+ {
+ time_t avg = time_t_avg (a, b);
+ return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2;
+ }
+ }
+
+ /* Return 1 if A + B does not overflow. */
+ static int
+ time_t_int_add_ok (time_t a, int b)
+ {
+ verify (int_no_wider_than_time_t, INT_MAX <= TIME_T_MAX);
+ if (WRAPV)
+ {
+ time_t sum = a + b;
+ return (sum < a) == (b < 0);
+ }
+ else
+ {
+ int a_odd = a & 1;
+ time_t avg = SHR (a, 1) + (SHR (b, 1) + (a_odd & b));
+ return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2;
+ }
+ }
+
/* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC),
! assuming that *T corresponds to *TP and that no clock adjustments
occurred between *TP and the desired time.
! If TP is null, return a value not equal to *T; this avoids false matches.
! If overflow occurs, yield the minimal or maximal value, except do not
! yield a value equal to *T. */
! static time_t
guess_time_tm (long_int year, long_int yday, int hour, int min, int sec,
! const time_t *t, const struct tm *tp)
{
if (tp)
{
! time_t d = ydhms_diff (year, yday, hour, min, sec,
! tp->tm_year, tp->tm_yday,
! tp->tm_hour, tp->tm_min, tp->tm_sec);
! if (time_t_add_ok (*t, d))
! return *t + d;
}
/* Overflow occurred one way or another. Return the nearest result
***************
*** 222,272 ****
if the actual difference is nonzero, as that would cause a false
match; and don't oscillate between two values, as that would
confuse the spring-forward gap detector. */
! return (t < long_int_avg (mktime_min, mktime_max)
! ? (t <= mktime_min + 1 ? t + 1 : mktime_min)
! : (mktime_max - 1 <= t ? t - 1 : mktime_max));
}
- /* Use CONVERT to convert T to a struct tm value in *TM. T must be in
- range for time_t. Return TM if successful, NULL if T is out of
- range for CONVERT. */
- static struct tm *
- convert_time (struct tm *(*convert) (const time_t *, struct tm *),
- long_int t, struct tm *tm)
- {
- time_t x = t;
- return convert (&x, tm);
- }
-
/* Use CONVERT to convert *T to a broken down time in *TP.
If *T is out of range for conversion, adjust it so that
! it is the nearest in-range value and then convert that.
! A value is in range if it fits in both time_t and long_int. */
static struct tm *
ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
! long_int *t, struct tm *tp)
{
! struct tm *r;
! if (*t < mktime_min)
! *t = mktime_min;
! else if (mktime_max < *t)
! *t = mktime_max;
! r = convert_time (convert, *t, tp);
if (!r && *t)
{
! long_int bad = *t;
! long_int ok = 0;
! /* BAD is a known unconvertible value, and OK is a known good one.
Use binary search to narrow the range between BAD and OK until
they differ by 1. */
! while (true)
{
! long_int mid = long_int_avg (ok, bad);
! if (mid != ok && mid != bad)
! break;
! r = convert_time (convert, mid, tp);
if (r)
ok = mid;
else
--- 295,326 ----
if the actual difference is nonzero, as that would cause a false
match; and don't oscillate between two values, as that would
confuse the spring-forward gap detector. */
! return (*t < TIME_T_MIDPOINT
! ? (*t <= TIME_T_MIN + 1 ? *t + 1 : TIME_T_MIN)
! : (TIME_T_MAX - 1 <= *t ? *t - 1 : TIME_T_MAX));
}
/* Use CONVERT to convert *T to a broken down time in *TP.
If *T is out of range for conversion, adjust it so that
! it is the nearest in-range value and then convert that. */
static struct tm *
ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
! time_t *t, struct tm *tp)
{
! struct tm *r = convert (t, tp);
if (!r && *t)
{
! time_t bad = *t;
! time_t ok = 0;
! /* BAD is a known unconvertible time_t, and OK is a known good one.
Use binary search to narrow the range between BAD and OK until
they differ by 1. */
! while (bad != ok + (bad < 0 ? -1 : 1))
{
! time_t mid = *t = time_t_avg (ok, bad);
! r = convert (t, tp);
if (r)
ok = mid;
else
***************
*** 277,283 ****
{
/* The last conversion attempt failed;
revert to the most recent successful attempt. */
! r = convert_time (convert, ok, tp);
}
}
--- 331,338 ----
{
/* The last conversion attempt failed;
revert to the most recent successful attempt. */
! *t = ok;
! r = convert (t, tp);
}
}
***************
*** 284,289 ****
--- 339,345 ----
return r;
}
+
/* Convert *TP to a time_t value, inverting
the monotonic and mostly-unit-linear conversion function CONVERT.
Use *OFFSET to keep track of a guess at the offset of the result,
***************
*** 293,301 ****
time_t
__mktime_internal (struct tm *tp,
struct tm *(*convert) (const time_t *, struct tm *),
! mktime_offset_t *offset)
{
! long_int t, gt, t0, t1, t2, dt;
struct tm tm;
/* The maximum number of probes (calls to CONVERT) should be enough
--- 349,357 ----
time_t
__mktime_internal (struct tm *tp,
struct tm *(*convert) (const time_t *, struct tm *),
! time_t *offset)
{
! time_t t, gt, t0, t1, t2;
struct tm tm;
/* The maximum number of probes (calls to CONVERT) should be enough
***************
*** 325,331 ****
long_int year = lyear_requested + mon_years;
/* The other values need not be in range:
! the remaining code handles overflows correctly. */
/* Calculate day of year from year, month, and day of month.
The result need not be in range. */
--- 381,389 ----
long_int year = lyear_requested + mon_years;
/* The other values need not be in range:
! the remaining code handles minor overflows correctly,
! assuming int and time_t arithmetic wraps around.
! Major overflows are caught at the end. */
/* Calculate day of year from year, month, and day of month.
The result need not be in range. */
***************
*** 335,341 ****
long_int lmday = mday;
long_int yday = mon_yday + lmday;
! int negative_offset_guess;
int sec_requested = sec;
--- 393,399 ----
long_int lmday = mday;
long_int yday = mon_yday + lmday;
! time_t guessed_offset = *offset;
int sec_requested = sec;
***************
*** 352,365 ****
/* Invert CONVERT by probing. First assume the same offset as last
time. */
- INT_SUBTRACT_WRAPV (0, *offset, &negative_offset_guess);
t0 = ydhms_diff (year, yday, hour, min, sec,
! EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, negative_offset_guess);
/* Repeatedly use the error to improve the guess. */
for (t = t1 = t2 = t0, dst2 = 0;
! (gt = guess_time_tm (year, yday, hour, min, sec, t,
ranged_convert (convert, &t, &tm)),
t != gt);
t1 = t2, t2 = t, t = gt, dst2 = tm.tm_isdst != 0)
--- 410,480 ----
/* Invert CONVERT by probing. First assume the same offset as last
time. */
t0 = ydhms_diff (year, yday, hour, min, sec,
! EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, - guessed_offset);
+ if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
+ {
+ /* time_t isn't large enough to rule out overflows, so check
+ for major overflows. A gross check suffices, since if t0
+ has overflowed, it is off by a multiple of TIME_T_MAX -
+ TIME_T_MIN + 1. So ignore any component of the difference
+ that is bounded by a small value. */
+
+ /* Approximate log base 2 of the number of time units per
+ biennium. A biennium is 2 years; use this unit instead of
+ years to avoid integer overflow. For example, 2 average
+ Gregorian years are 2 * 365.2425 * 24 * 60 * 60 seconds,
+ which is 63113904 seconds, and rint (log2 (63113904)) is
+ 26. */
+ int ALOG2_SECONDS_PER_BIENNIUM = 26;
+ int ALOG2_MINUTES_PER_BIENNIUM = 20;
+ int ALOG2_HOURS_PER_BIENNIUM = 14;
+ int ALOG2_DAYS_PER_BIENNIUM = 10;
+ int LOG2_YEARS_PER_BIENNIUM = 1;
+
+ int approx_requested_biennia =
+ (SHR (year_requested, LOG2_YEARS_PER_BIENNIUM)
+ - SHR (EPOCH_YEAR - TM_YEAR_BASE, LOG2_YEARS_PER_BIENNIUM)
+ + SHR (mday, ALOG2_DAYS_PER_BIENNIUM)
+ + SHR (hour, ALOG2_HOURS_PER_BIENNIUM)
+ + SHR (min, ALOG2_MINUTES_PER_BIENNIUM)
+ + (LEAP_SECONDS_POSSIBLE
+ ? 0
+ : SHR (sec, ALOG2_SECONDS_PER_BIENNIUM)));
+
+ int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM);
+ int diff = approx_biennia - approx_requested_biennia;
+ int approx_abs_diff = diff < 0 ? -1 - diff : diff;
+
+ /* IRIX 4.0.5 cc miscalculates TIME_T_MIN / 3: it erroneously
+ gives a positive value of 715827882. Setting a variable
+ first then doing math on it seems to work.
+ (ghazi@caip.rutgers.edu) */
+ time_t time_t_max = TIME_T_MAX;
+ time_t time_t_min = TIME_T_MIN;
+ time_t overflow_threshold =
+ (time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM;
+
+ if (overflow_threshold < approx_abs_diff)
+ {
+ /* Overflow occurred. Try repairing it; this might work if
+ the time zone offset is enough to undo the overflow. */
+ time_t repaired_t0 = -1 - t0;
+ approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM);
+ diff = approx_biennia - approx_requested_biennia;
+ approx_abs_diff = diff < 0 ? -1 - diff : diff;
+ if (overflow_threshold < approx_abs_diff)
+ return -1;
+ guessed_offset += repaired_t0 - t0;
+ t0 = repaired_t0;
+ }
+ }
+
/* Repeatedly use the error to improve the guess. */
for (t = t1 = t2 = t0, dst2 = 0;
! (gt = guess_time_tm (year, yday, hour, min, sec, &t,
ranged_convert (convert, &t, &tm)),
t != gt);
t1 = t2, t2 = t, t = gt, dst2 = tm.tm_isdst != 0)
***************
*** 416,457 ****
for (delta = stride; delta < delta_bound; delta += stride)
for (direction = -1; direction <= 1; direction += 2)
! {
! long_int ot;
! if (! INT_ADD_WRAPV (t, delta * direction, &ot))
! {
! struct tm otm;
! ranged_convert (convert, &ot, &otm);
! if (! isdst_differ (isdst, otm.tm_isdst))
! {
! /* We found the desired tm_isdst.
! Extrapolate back to the desired time. */
! t = guess_time_tm (year, yday, hour, min, sec, ot, &otm);
! ranged_convert (convert, &t, &tm);
! goto offset_found;
! }
! }
! }
}
offset_found:
! /* Set *OFFSET to the low-order bits of T - T0 - NEGATIVE_OFFSET_GUESS.
! This is just a heuristic to speed up the next mktime call, and
! correctness is unaffected if integer overflow occurs here. */
! INT_SUBTRACT_WRAPV (t, t0, &dt);
! INT_SUBTRACT_WRAPV (dt, negative_offset_guess, offset);
if (LEAP_SECONDS_POSSIBLE && sec_requested != tm.tm_sec)
{
/* Adjust time to reflect the tm_sec requested, not the normalized value.
Also, repair any damage from a false match due to a leap second. */
! long_int sec_adjustment = sec == 0 && tm.tm_sec == 60;
! sec_adjustment -= sec;
! sec_adjustment += sec_requested;
! if (INT_ADD_WRAPV (t, sec_adjustment, &t)
! || ! (mktime_min <= t && t <= mktime_max)
! || ! convert_time (convert, t, &tm))
return -1;
}
*tp = tm;
--- 531,569 ----
for (delta = stride; delta < delta_bound; delta += stride)
for (direction = -1; direction <= 1; direction += 2)
! if (time_t_int_add_ok (t, delta * direction))
! {
! time_t ot = t + delta * direction;
! struct tm otm;
! ranged_convert (convert, &ot, &otm);
! if (! isdst_differ (isdst, otm.tm_isdst))
! {
! /* We found the desired tm_isdst.
! Extrapolate back to the desired time. */
! t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm);
! ranged_convert (convert, &t, &tm);
! goto offset_found;
! }
! }
}
offset_found:
! *offset = guessed_offset + t - t0;
if (LEAP_SECONDS_POSSIBLE && sec_requested != tm.tm_sec)
{
/* Adjust time to reflect the tm_sec requested, not the normalized value.
Also, repair any damage from a false match due to a leap second. */
! int sec_adjustment = (sec == 0 && tm.tm_sec == 60) - sec;
! if (! time_t_int_add_ok (t, sec_requested))
return -1;
+ t1 = t + sec_requested;
+ if (! time_t_int_add_ok (t1, sec_adjustment))
+ return -1;
+ t2 = t1 + sec_adjustment;
+ if (! convert (&t2, &tm))
+ return -1;
+ t = t2;
}
*tp = tm;
***************
*** 459,465 ****
}
! static mktime_offset_t localtime_offset;
/* Convert *TP to a time_t value. */
time_t
--- 571,581 ----
}
! /* FIXME: This should use a signed type wide enough to hold any UTC
! offset in seconds. 'int' should be good enough for GNU code. We
! can't fix this unilaterally though, as other modules invoke
! __mktime_internal. */
! static time_t localtime_offset;
/* Convert *TP to a time_t value. */
time_t
***************
*** 484,490 ****
libc_hidden_weak (timelocal)
#endif
! #if DEBUG_MKTIME
static int
not_equal_tm (const struct tm *a, const struct tm *b)
--- 600,606 ----
libc_hidden_weak (timelocal)
#endif
! #if defined DEBUG_MKTIME && DEBUG_MKTIME
static int
not_equal_tm (const struct tm *a, const struct tm *b)
***************
*** 536,549 ****
time_t tk, tl, tl1;
char trailer;
- /* Sanity check, plus call tzset. */
- tl = 0;
- if (! localtime (&tl))
- {
- printf ("localtime (0) fails\n");
- status = 1;
- }
-
if ((argc == 3 || argc == 4)
&& (sscanf (argv[1], "%d-%d-%d%c",
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer)
--- 652,657 ----
***************
*** 557,563 ****
tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]);
tmk = tm;
tl = mktime (&tmk);
! lt = localtime_r (&tl, &tml);
printf ("mktime returns %ld == ", (long int) tl);
print_tm (&tmk);
printf ("\n");
--- 665,676 ----
tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]);
tmk = tm;
tl = mktime (&tmk);
! lt = localtime (&tl);
! if (lt)
! {
! tml = *lt;
! lt = &tml;
! }
printf ("mktime returns %ld == ", (long int) tl);
print_tm (&tmk);
printf ("\n");
***************
*** 572,587 ****
if (argc == 4)
for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
{
! lt = localtime_r (&tl, &tml);
if (lt)
{
! tmk = tml;
tk = mktime (&tmk);
status |= check_result (tk, tmk, tl, &tml);
}
else
{
! printf ("localtime_r (%ld) yields 0\n", (long int) tl);
status = 1;
}
tl1 = tl + by;
--- 685,700 ----
if (argc == 4)
for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
{
! lt = localtime (&tl);
if (lt)
{
! tmk = tml = *lt;
tk = mktime (&tmk);
status |= check_result (tk, tmk, tl, &tml);
}
else
{
! printf ("localtime (%ld) yields 0\n", (long int) tl);
status = 1;
}
tl1 = tl + by;
***************
*** 592,607 ****
for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
{
/* Null benchmark. */
! lt = localtime_r (&tl, &tml);
if (lt)
{
! tmk = tml;
tk = tl;
status |= check_result (tk, tmk, tl, &tml);
}
else
{
! printf ("localtime_r (%ld) yields 0\n", (long int) tl);
status = 1;
}
tl1 = tl + by;
--- 705,720 ----
for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
{
/* Null benchmark. */
! lt = localtime (&tl);
if (lt)
{
! tmk = tml = *lt;
tk = tl;
status |= check_result (tk, tmk, tl, &tml);
}
else
{
! printf ("localtime (%ld) yields 0\n", (long int) tl);
status = 1;
}
tl1 = tl + by;