summaryrefslogtreecommitdiff
path: root/lib/strftime.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2004-11-11 06:07:57 +0000
committerPaul Eggert <eggert@cs.ucla.edu>2004-11-11 06:07:57 +0000
commit9d8ce0f399c4b173e090ca375e353ecc8fa4c8f9 (patch)
tree3200e2cd05e1d88efb35ff5afef4e8808e798042 /lib/strftime.c
parentd2b4386d2918d43e48e4ea42fcae314af346edd2 (diff)
downloadcoreutils-9d8ce0f399c4b173e090ca375e353ecc8fa4c8f9.tar.xz
Sync from gnulib.
Diffstat (limited to 'lib/strftime.c')
-rw-r--r--lib/strftime.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/lib/strftime.c b/lib/strftime.c
index 2ef27c22a..e74e35a2f 100644
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -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