bug-gnulib
[Top][All Lists]
Advanced

[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-----




reply via email to

[Prev in Thread] Current Thread [Next in Thread]