(SHR): New macro, which is a portable
authorPaul Eggert <eggert@cs.ucla.edu>
Thu, 11 Nov 2004 05:57:27 +0000 (05:57 +0000)
committerPaul Eggert <eggert@cs.ucla.edu>
Thu, 11 Nov 2004 05:57:27 +0000 (05:57 +0000)
substitute for >> that should work even on Crays.
(tm_diff): Use it.

lib/getdate.y
lib/strftime.c

index a4a445d..2f72f04 100644 (file)
 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
 #endif
 
+/* 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       \
+   ? (a) >> (b)                \
+   : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
+
 #define EPOCH_YEAR 1970
 #define TM_YEAR_BASE 1900
 
@@ -734,12 +749,12 @@ tm_diff (struct tm const *a, struct tm const *b)
 {
   /* Compute intervening leap days correctly even if year is negative.
      Take care to avoid int overflow in leap day calculations.  */
-  int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
-  int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
+  int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3);
+  int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 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);
   long int ayear = a->tm_year;
   long int years = ayear - b->tm_year;
index 2ef27c2..e74e35a 100644 (file)
@@ -104,6 +104,21 @@ extern char *tzname[];
 # endif
 #endif
 
+/* 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       \
+   ? (a) >> (b)                \
+   : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
+
 #define TYPE_SIGNED(t) ((t) -1 < 0)
 
 /* Bound on length of the string representing an integer value of type t.
@@ -279,12 +294,12 @@ tm_diff (const struct tm *a, const struct tm *b)
   /* Compute intervening leap days correctly even if year is negative.
      Take care to avoid int overflow in leap day calculations,
      but it's OK to assume that A and B are close to each other.  */
-  int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
-  int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
+  int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3);
+  int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 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);
   int years = a->tm_year - b->tm_year;
   int days = (365 * years + intervening_leap_days