aboutsummaryrefslogtreecommitdiff
path: root/time/mktime.c
diff options
context:
space:
mode:
Diffstat (limited to 'time/mktime.c')
-rw-r--r--time/mktime.c73
1 files changed, 25 insertions, 48 deletions
diff --git a/time/mktime.c b/time/mktime.c
index 8f00c72..c6ae56e 100644
--- a/time/mktime.c
+++ b/time/mktime.c
@@ -1,7 +1,7 @@
/* Convert a `struct tm' to a time_t value.
- Copyright (C) 1993-1999, 2002-2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 1993-1999, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Contributed by Paul Eggert <eggert@twinsun.com>.
+ Contributed by Paul Eggert (eggert@twinsun.com).
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -38,11 +38,10 @@
#include <limits.h>
-#include <string.h> /* For the real memcpy prototype. */
-
#if DEBUG
# include <stdio.h>
# include <stdlib.h>
+# include <string.h>
/* Make it work even if the system's libc has its own mktime routine. */
# define mktime my_mktime
#endif /* DEBUG */
@@ -62,38 +61,13 @@
? (a) >> (b) \
: (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
-/* The extra casts in the following macros work around compiler bugs,
- e.g., in Cray C 5.0.3.0. */
-
-/* True if the arithmetic type T is an integer type. bool counts as
- an integer. */
-#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)
-
-/* True if negative values of the signed integer type T use two's
- complement, ones' complement, or signed magnitude representation,
- respectively. Much GNU code assumes two's complement, but some
- people like to be portable to all possible C hosts. */
-#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1)
-#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0)
-#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1)
-
-/* True if the arithmetic type T is signed. */
+/* The extra casts work around common compiler bugs. */
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
-
-/* The maximum and minimum values for the integer type T. These
- macros have undefined behavior if T is signed and has padding bits.
- If this is a problem for you, please let us know how to fix it for
- your host. */
-#define TYPE_MINIMUM(t) \
- ((t) (! TYPE_SIGNED (t) \
- ? (t) 0 \
- : TYPE_SIGNED_MAGNITUDE (t) \
- ? ~ (t) 0 \
- : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))
-#define TYPE_MAXIMUM(t) \
- ((t) (! TYPE_SIGNED (t) \
- ? (t) -1 \
- : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))))
+/* The outer cast is needed to work around a bug in Cray C 5.0.3.0.
+ It is necessary at least when t == time_t. */
+#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
+ ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0))
+#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
#ifndef TIME_T_MIN
# define TIME_T_MIN TYPE_MINIMUM (time_t)
@@ -106,8 +80,8 @@
/* 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, TYPE_IS_INTEGER (time_t));
-verify (twos_complement_arithmetic, TYPE_TWOS_COMPLEMENT (int));
+verify (time_t_is_integer, (time_t) 0.5 == 0);
+verify (twos_complement_arithmetic, -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. */
@@ -216,11 +190,10 @@ guess_time_tm (long int year, long int yday, int hour, int min, int sec,
/* Overflow occurred one way or another. Return the nearest result
that is actually in range, except don't report a zero difference
if the actual difference is nonzero, as that would cause a false
- match; and don't oscillate between two values, as that would
- confuse the spring-forward gap detector. */
+ match. */
return (*t < TIME_T_MIDPOINT
- ? (*t <= TIME_T_MIN + 1 ? *t + 1 : TIME_T_MIN)
- : (TIME_T_MAX - 1 <= *t ? *t - 1 : TIME_T_MAX));
+ ? TIME_T_MIN + (*t == TIME_T_MIN)
+ : TIME_T_MAX - (*t == TIME_T_MAX));
}
/* Use CONVERT to convert *T to a broken down time in *TP.
@@ -230,12 +203,13 @@ static struct tm *
ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
time_t *t, struct tm *tp)
{
- struct tm *r = convert (t, tp);
+ struct tm *r;
- if (!r && *t)
+ if (! (r = (*convert) (t, tp)) && *t)
{
time_t bad = *t;
time_t ok = 0;
+ struct tm tm;
/* BAD is a known unconvertible time_t, and OK is a known good one.
Use binary search to narrow the range between BAD and OK until
@@ -245,9 +219,11 @@ ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
time_t mid = *t = (bad < 0
? bad + ((ok - bad) >> 1)
: ok + ((bad - ok) >> 1));
- r = convert (t, tp);
- if (r)
- ok = mid;
+ if ((r = (*convert) (t, tp)))
+ {
+ tm = *r;
+ ok = mid;
+ }
else
bad = mid;
}
@@ -257,7 +233,8 @@ ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
/* The last conversion attempt failed;
revert to the most recent successful attempt. */
*t = ok;
- r = convert (t, tp);
+ *tp = tm;
+ r = tp;
}
}
@@ -486,7 +463,7 @@ __mktime_internal (struct tm *tp,
t2 = t1 + sec_adjustment;
if (((t1 < t) != (sec_requested < 0))
| ((t2 < t1) != (sec_adjustment < 0))
- | ! convert (&t2, &tm))
+ | ! (*convert) (&t2, &tm))
return -1;
t = t2;
}