From 4043787150772987ca8e377b2d488dae6b5d8a8b Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 8 Sep 2005 08:09:16 +0000 Subject: [BZ #1033, BZ #1061] 2005-07-11 Derek R. Price [BZ #1061] * sysdeps/generic/glob.c (glob): Only a 0 return from getlogin_r means success, according to POSIX 1003.2. 2005-06-23 Paul Eggert [BZ #1033] * time/mktime.c: Import from gnulib. The following macros are now consistent with other gnulib code. This does not change mktime's behavior. (TYPE_IS_INTEGER): New macro. (time_t_is_integer): Use it. (TYPE_TWOS_COMPLEMENT): New macro. (twos_complement_arithmetic): Use it. (TYPE_ONES_COMPLEMENT): New macro. (TYPE_MINIMUM, TYPE_MAXIMUM): Now supports signed-magnitude. mktime doesn't use this, but the code now matches other gnulib code. (ranged_convert): Pacify GCC 4.0 in a different way, which generates a few bytes less code. (ranged_convert, __mktime_internal): When calling a function via a pointer P, use P () rather than (*P) (), as we now assume C89 or better. --- time/mktime.c | 60 +++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 20 deletions(-) (limited to 'time') diff --git a/time/mktime.c b/time/mktime.c index 258eec6..5a326d1 100644 --- a/time/mktime.c +++ b/time/mktime.c @@ -62,13 +62,38 @@ ? (a) >> (b) \ : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0)) -/* The extra casts work around common compiler bugs. */ +/* 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. */ #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. - 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))) + +/* 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)))) #ifndef TIME_T_MIN # define TIME_T_MIN TYPE_MINIMUM (time_t) @@ -81,8 +106,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, (time_t) 0.5 == 0); -verify (twos_complement_arithmetic, -1 == ~1 + 1); +verify (time_t_is_integer, TYPE_IS_INTEGER (time_t)); +verify (twos_complement_arithmetic, TYPE_TWOS_COMPLEMENT (int)); /* 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. */ @@ -204,14 +229,12 @@ static struct tm * ranged_convert (struct tm *(*convert) (const time_t *, struct tm *), time_t *t, struct tm *tp) { - struct tm *r; + struct tm *r = convert (t, tp); - if (! (r = (*convert) (t, tp)) && *t) + if (!r && *t) { time_t bad = *t; time_t ok = 0; - /* Initialize to make the compiler happy. */ - struct tm tm = { 0, }; /* 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 @@ -221,11 +244,9 @@ ranged_convert (struct tm *(*convert) (const time_t *, struct tm *), time_t mid = *t = (bad < 0 ? bad + ((ok - bad) >> 1) : ok + ((bad - ok) >> 1)); - if ((r = (*convert) (t, tp))) - { - tm = *r; - ok = mid; - } + r = convert (t, tp); + if (r) + ok = mid; else bad = mid; } @@ -235,8 +256,7 @@ ranged_convert (struct tm *(*convert) (const time_t *, struct tm *), /* The last conversion attempt failed; revert to the most recent successful attempt. */ *t = ok; - *tp = tm; - r = tp; + r = convert (t, tp); } } @@ -465,7 +485,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; } -- cgit v1.1