[BZ #1033, BZ #1061]
authorRoland McGrath <roland@gnu.org>
Thu, 8 Sep 2005 08:09:16 +0000 (08:09 +0000)
committerRoland McGrath <roland@gnu.org>
Thu, 8 Sep 2005 08:09:16 +0000 (08:09 +0000)
2005-07-11  Derek R. Price  <derek@ximbiot.com>
[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  <eggert@cs.ucla.edu>

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

ChangeLog
time/mktime.c

index a7de34d..b3b320d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2005-07-11  Derek R. Price  <derek@ximbiot.com>
+
+       [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  <eggert@cs.ucla.edu>
+
+       [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.
+
 2005-09-07  Alexandre Oliva  <aoliva@redhat.com>
 
        * timezone/test-tz.c: Update to match tzdata2005m.
index 258eec6..5a326d1 100644 (file)
    ? (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)
 /* 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;
     }