minor tz tuneups and portability fix
Paul Eggert
eggert at twinsun.com
Mon Jan 15 06:37:20 UTC 1996
Here are some proposed very minor code tuneups for the tz code.
While accumulating these I noticed a portability bug in localtime.c;
the expression `(t < 0) ? 0 : ((time_t) 1 << bits)' yields undefined
results if time_t is unsigned, since `bits' is the number of bits in
a time_t in that case. The patch below fixes this bug as part of the tuneups.
===================================================================
RCS file: RCS/tzfile.h,v
retrieving revision 1995.3
retrieving revision 1995.3.1.1
diff -c -r1995.3 -r1995.3.1.1
*** tzfile.h 1995/03/11 17:55:58 1995.3
--- tzfile.h 1996/01/15 06:22:59 1995.3.1.1
***************
*** 153,159 ****
** that will probably do.
*/
! #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
#ifndef USG
--- 153,159 ----
** that will probably do.
*/
! #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
#ifndef USG
===================================================================
RCS file: RCS/difftime.c,v
retrieving revision 1994.8
retrieving revision 1994.8.1.1
diff -c -r1994.8 -r1994.8.1.1
*** difftime.c 1994/12/09 04:33:32 1994.8
--- difftime.c 1996/01/15 06:22:59 1994.8.1.1
***************
*** 43,51 ****
/*
** Repair delta overflow.
*/
! hibit = 1;
! while ((hibit <<= 1) > 0)
! continue;
/*
** The following expression rounds twice, which means
** the result may not be the closest to the true answer.
--- 43,49 ----
/*
** Repair delta overflow.
*/
! hibit = (~ (time_t) 0) << (TYPE_BIT(time_t) - 1);
/*
** The following expression rounds twice, which means
** the result may not be the closest to the true answer.
***************
*** 65,74 ****
** This problem occurs only with very large differences.
** It's too painful to fix this portably.
** We are not alone in this problem;
! ** many C compilers round twice when converting
** large unsigned types to small floating types,
** so if time_t is unsigned the "return delta" above
! ** has the same double-rounding problem.
*/
return delta - 2 * (long_double) hibit;
}
--- 63,72 ----
** This problem occurs only with very large differences.
** It's too painful to fix this portably.
** We are not alone in this problem;
! ** some C compilers round twice when converting
** large unsigned types to small floating types,
** so if time_t is unsigned the "return delta" above
! ** has the same double-rounding problem with those compilers.
*/
return delta - 2 * (long_double) hibit;
}
===================================================================
RCS file: RCS/localtime.c,v
retrieving revision 1995.7
retrieving revision 1995.7.1.1
diff -c -r1995.7 -r1995.7.1.1
*** localtime.c 1995/10/30 15:32:46 1995.7
--- localtime.c 1996/01/15 06:22:59 1995.7.1.1
***************
*** 1163,1175 ****
tmp->tm_hour = (int) (rem / SECSPERHOUR);
rem = rem % SECSPERHOUR;
tmp->tm_min = (int) (rem / SECSPERMIN);
! tmp->tm_sec = (int) (rem % SECSPERMIN);
! if (hit)
! /*
! ** A positive leap second requires a special
! ** representation. This uses "... ??:59:60" et seq.
! */
! tmp->tm_sec += hit;
tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
if (tmp->tm_wday < 0)
tmp->tm_wday += DAYSPERWEEK;
--- 1163,1173 ----
tmp->tm_hour = (int) (rem / SECSPERHOUR);
rem = rem % SECSPERHOUR;
tmp->tm_min = (int) (rem / SECSPERMIN);
! /*
! ** A positive leap second requires a special
! ** representation. This uses "... ??:59:60" et seq.
! */
! tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
if (tmp->tm_wday < 0)
tmp->tm_wday += DAYSPERWEEK;
***************
*** 1344,1358 ****
/*
** Calculate the number of magnitude bits in a time_t
** (this works regardless of whether time_t is
! ** signed or unsigned, though lint complains if unsigned).
*/
! for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
! continue;
/*
** If time_t is signed, then 0 is the median value,
! ** if time_t is unsigned, then 1 << bits is median.
*/
! t = (t < 0) ? 0 : ((time_t) 1 << bits);
for ( ; ; ) {
(*funcp)(&t, offset, &mytm);
dir = tmcomp(&mytm, &yourtm);
--- 1342,1355 ----
/*
** Calculate the number of magnitude bits in a time_t
** (this works regardless of whether time_t is
! ** signed or unsigned).
*/
! bits = TYPE_BIT(time_t) - TYPE_SIGNED(time_t);
/*
** If time_t is signed, then 0 is the median value,
! ** if time_t is unsigned, then 1 << (bits - 1) is median.
*/
! t = TYPE_SIGNED(time_t) ? 0 : ((time_t) 1 << (TYPE_BIT(time_t) - 1));
for ( ; ; ) {
(*funcp)(&t, offset, &mytm);
dir = tmcomp(&mytm, &yourtm);
More information about the tz
mailing list