New upstream version 1.9
[debian/gzip] / lib / timespec.h
index 601394b888c421bfae4be3f8107d8ee64e6077f3..eef3030d9c55d798ab3a6f314f40453159b8504b 100644 (file)
@@ -1,6 +1,6 @@
 /* timespec -- System time interface
 
-   Copyright (C) 2000, 2002, 2004-2005, 2007, 2009-2016 Free Software
+   Copyright (C) 2000, 2002, 2004-2005, 2007, 2009-2018 Free Software
    Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
@@ -14,7 +14,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
 
 #if ! defined TIMESPEC_H
 # define TIMESPEC_H
@@ -29,7 +29,13 @@ _GL_INLINE_HEADER_BEGIN
 # define _GL_TIMESPEC_INLINE _GL_INLINE
 #endif
 
-/* Resolution of timespec time stamps (in units per second), and log
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "verify.h"
+
+/* Resolution of timespec timestamps (in units per second), and log
    base 10 of the resolution.  */
 
 enum { TIMESPEC_RESOLUTION = 1000000000 };
@@ -48,7 +54,7 @@ make_timespec (time_t s, long int ns)
 
 /* Return negative, zero, positive if A < B, A == B, A > B, respectively.
 
-   For each time stamp T, this code assumes that either:
+   For each timestamp T, this code assumes that either:
 
      * T.tv_nsec is in the range 0..999999999; or
      * T.tv_sec corresponds to a valid leap second on a host that supports
@@ -56,30 +62,36 @@ make_timespec (time_t s, long int ns)
      * T.tv_sec is the minimum time_t value and T.tv_nsec is -1; or
        T.tv_sec is the maximum time_t value and T.tv_nsec is 2000000000.
        This allows for special struct timespec values that are less or
-       greater than all possible valid time stamps.
+       greater than all possible valid timestamps.
 
    In all these cases, it is safe to subtract two tv_nsec values and
    convert the result to integer without worrying about overflow on
    any platform of interest to the GNU project, since all such
    platforms have 32-bit int or wider.
 
-   Replacing "(int) (a.tv_nsec - b.tv_nsec)" with something like
+   Replacing "a.tv_nsec - b.tv_nsec" with something like
    "a.tv_nsec < b.tv_nsec ? -1 : a.tv_nsec > b.tv_nsec" would cause
    this function to work in some cases where the above assumption is
    violated, but not in all cases (e.g., a.tv_sec==1, a.tv_nsec==-2,
    b.tv_sec==0, b.tv_nsec==999999999) and is arguably not worth the
    extra instructions.  Using a subtraction has the advantage of
    detecting some invalid cases on platforms that detect integer
-   overflow.
-
-   The (int) cast avoids a gcc -Wconversion warning.  */
+   overflow.  */
 
 _GL_TIMESPEC_INLINE int _GL_ATTRIBUTE_PURE
 timespec_cmp (struct timespec a, struct timespec b)
 {
-  return (a.tv_sec < b.tv_sec ? -1
-          : a.tv_sec > b.tv_sec ? 1
-          : (int) (a.tv_nsec - b.tv_nsec));
+  if (a.tv_sec < b.tv_sec)
+    return -1;
+  if (a.tv_sec > b.tv_sec)
+    return 1;
+
+  /* Pacify gcc -Wstrict-overflow (bleeding-edge circa 2017-10-02).  See:
+     http://lists.gnu.org/r/bug-gnulib/2017-10/msg00006.html  */
+  assume (-1 <= a.tv_nsec && a.tv_nsec <= 2 * TIMESPEC_RESOLUTION);
+  assume (-1 <= b.tv_nsec && b.tv_nsec <= 2 * TIMESPEC_RESOLUTION);
+
+  return a.tv_nsec - b.tv_nsec;
 }
 
 /* Return -1, 0, 1, depending on the sign of A.  A.tv_nsec must be
@@ -107,6 +119,10 @@ timespectod (struct timespec a)
 void gettime (struct timespec *);
 int settime (struct timespec const *);
 
+#ifdef __cplusplus
+}
+#endif
+
 _GL_INLINE_HEADER_END
 
 #endif