[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Bug-gnulib] Re: GNULIB mktime.c compilation failure on UNICOS 9.0 C
From: |
Mark D. Baushke |
Subject: |
Re: [Bug-gnulib] Re: GNULIB mktime.c compilation failure on UNICOS 9.0 Cray Y-MP EL |
Date: |
Wed, 10 Nov 2004 13:41:48 -0800 |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Paul Eggert <address@hidden> writes:
> Thanks for reporting that. Does the following patch fix things on
> your friend's Cray?
Yes, the patch allows the UNICOS 9.0 Cray Y-MP EL to build the mktime.c
file.
The getdate test program has one problem.
An input of 'Feb. 29, 2096 8 years' to
TZ=UTC ./getdate
generates the result:
> 2104-02-29 00:00:00.000000000
instead of the expected value of:
> Bad format - couldn't convert.
I am guessing this is because all integral numbers on UNICOS are 8
bytes.
Please commit your change to GNULIB.
Thanks,
-- Mark
> 2004-11-10 Paul Eggert <address@hidden>
>
> * mktime.c (SHR): New macro, which is a portable substitute for >>
> that should work even on Crays.
> Problem reported by Mark D. Baushke.
> (TIME_T_MIDPOINT, ydhms_diff, __mktime_internal): Use it.
>
> --- mktime.c.~1.43.~ 2004-10-29 15:55:02 -0700
> +++ mktime.c 2004-11-10 00:16:56 -0800
> @@ -45,6 +45,18 @@
> # define mktime my_mktime
> #endif /* DEBUG */
>
> +/* Divide A by 2**B, truncating towards minus infinity. This is a
> + substitute for A >> B that works portably even if A is negative. A
> + and B should be free of side effects, and 0 <= B <= 30. ISO C99
> + says that A >> B has implementation-defined behavior if A is
> + negative, and some implementations (e.g., UNICOS 9.0 on a Cray Y-MP
> + EL) don't shift right in the usual way, so SHR falls back on
> + division in cases like these. */
> +#define SHR(a, b) \
> + (-1 >> 1 == -1 \
> + ? (a) >> (b) \
> + : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
> +
> /* The extra casts work around common compiler bugs. */
> #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
> /* The outer cast is needed to work around a bug in Cray C 5.0.3.0.
> @@ -59,14 +71,13 @@
> #ifndef TIME_T_MAX
> # define TIME_T_MAX TYPE_MAXIMUM (time_t)
> #endif
> -#define TIME_T_MIDPOINT (((TIME_T_MIN + TIME_T_MAX) >> 1) + 1)
> +#define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1)
>
> /* Verify a requirement at compile-time (unlike assert, which is runtime).
> */
> #define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
>
> verify (time_t_is_integer, (time_t) 0.5 == 0);
> verify (twos_complement_arithmetic, -1 == ~1 + 1);
> -verify (right_shift_propagates_sign, -1 >> 1 == -1);
> /* The code also assumes that signed integer overflow silently wraps
> around, but this assumption can't be stated without causing a
> diagnostic on some hosts. */
> @@ -132,12 +143,12 @@ ydhms_diff (long int year1, long int yda
>
> /* Compute intervening leap days correctly even if year is negative.
> Take care to avoid integer overflow here. */
> - int a4 = (year1 >> 2) + (TM_YEAR_BASE >> 2) - ! (year1 & 3);
> - int b4 = (year0 >> 2) + (TM_YEAR_BASE >> 2) - ! (year0 & 3);
> + 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 = a100 >> 2;
> - int b400 = b100 >> 2;
> + 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
> @@ -321,14 +332,16 @@ __mktime_internal (struct tm *tp,
> int LOG2_YEARS_PER_BIENNIUM = 1;
>
> int approx_requested_biennia =
> - ((year_requested >> LOG2_YEARS_PER_BIENNIUM)
> - - ((EPOCH_YEAR - TM_YEAR_BASE) >> LOG2_YEARS_PER_BIENNIUM)
> - + (mday >> ALOG2_DAYS_PER_BIENNIUM)
> - + (hour >> ALOG2_HOURS_PER_BIENNIUM)
> - + (min >> ALOG2_MINUTES_PER_BIENNIUM)
> - + (LEAP_SECONDS_POSSIBLE ? 0 : sec >> ALOG2_SECONDS_PER_BIENNIUM));
> + (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 = t0 >> ALOG2_SECONDS_PER_BIENNIUM;
> + int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM);
> int diff = approx_biennia - approx_requested_biennia;
> int abs_diff = diff < 0 ? - diff : diff;
>
> @@ -346,7 +359,7 @@ __mktime_internal (struct tm *tp,
> /* 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 = repaired_t0 >> ALOG2_SECONDS_PER_BIENNIUM;
> + approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM);
> diff = approx_biennia - approx_requested_biennia;
> abs_diff = diff < 0 ? - diff : diff;
> if (overflow_threshold < abs_diff)
>
>
> _______________________________________________
> Bug-gnulib mailing list
> address@hidden
> http://lists.gnu.org/mailman/listinfo/bug-gnulib
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (FreeBSD)
iD8DBQFBkosc3x41pRYZE/gRAqIBAJ0QV4hU+G9uOqy4gU5Z2px8Dml+bgCguG8I
99iB08oIelAokCHBnyXSf7Q=
=PKvM
-----END PGP SIGNATURE-----