timespec-add, timespec-sub: new modules
authorPaul Eggert <eggert@cs.ucla.edu>
Thu, 30 Jun 2011 22:17:31 +0000 (15:17 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Thu, 30 Jun 2011 22:24:37 +0000 (15:24 -0700)
* lib/timespec.h (timespec_add, timespec_sub): New decls.
* lib/timespec-add.c, lib/timespec-sub.c:
* modules/timespec-add, modules/timespec-sub: New files.

ChangeLog
lib/timespec-add.c [new file with mode: 0644]
lib/timespec-sub.c [new file with mode: 0644]
lib/timespec.h
modules/timespec-add [new file with mode: 0644]
modules/timespec-sub [new file with mode: 0644]

index d20588f..2369b42 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2011-06-30  Paul Eggert  <eggert@cs.ucla.edu>
 
+       timespec-add, timespec-sub: new modules
+       * lib/timespec.h (timespec_add, timespec_sub): New decls.
+       * lib/timespec-add.c, lib/timespec-sub.c:
+       * modules/timespec-add, modules/timespec-sub: New files.
+
        dtotimespec: new module
        * lib/timespec.h (dtotimespec): New decl.
        * lib/dtotimespec.c, modules/dtotimespec: New files.
diff --git a/lib/timespec-add.c b/lib/timespec-add.c
new file mode 100644 (file)
index 0000000..813dadb
--- /dev/null
@@ -0,0 +1,71 @@
+/* Add two struct timespec values.
+
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   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/>.  */
+
+/* Written by Paul Eggert.  */
+
+/* Return the sum of two timespec values A and B.  On overflow, return
+   an extremal value.  This assumes 0 <= tv_nsec <= 999999999.  */
+
+#include <config.h>
+#include "timespec.h"
+
+#include "intprops.h"
+
+struct timespec
+timespec_add (struct timespec a, struct timespec b)
+{
+  struct timespec r;
+  time_t rs = a.tv_sec;
+  time_t bs = b.tv_sec;
+  int ns = a.tv_nsec + b.tv_nsec;
+  int nsd = ns - 1000000000;
+  int rns = ns;
+
+  if (0 <= nsd)
+    {
+      rns = nsd;
+      if (rs == TYPE_MAXIMUM (time_t))
+        {
+          if (0 <= bs)
+            goto high_overflow;
+          bs++;
+        }
+      else
+        rs++;
+    }
+
+  if (INT_ADD_OVERFLOW (rs, bs))
+    {
+      if (rs < 0)
+        {
+          rs = TYPE_MINIMUM (time_t);
+          rns = 0;
+        }
+      else
+        {
+        high_overflow:
+          rs = TYPE_MAXIMUM (time_t);
+          rns = 999999999;
+        }
+    }
+  else
+    rs += bs;
+
+  r.tv_sec = rs;
+  r.tv_nsec = rns;
+  return r;
+}
diff --git a/lib/timespec-sub.c b/lib/timespec-sub.c
new file mode 100644 (file)
index 0000000..679d0db
--- /dev/null
@@ -0,0 +1,72 @@
+/* Subtract two struct timespec values.
+
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   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/>.  */
+
+/* Written by Paul Eggert.  */
+
+/* Return the difference between two timespec values A and B.  On
+   overflow, return an extremal value.  This assumes 0 <= tv_nsec <=
+   999999999.  */
+
+#include <config.h>
+#include <config.h>
+#include "timespec.h"
+
+#include "intprops.h"
+
+struct timespec
+timespec_sub (struct timespec a, struct timespec b)
+{
+  struct timespec r;
+  time_t rs = a.tv_sec;
+  time_t bs = b.tv_sec;
+  int ns = a.tv_nsec - b.tv_nsec;
+  int rns = ns;
+
+  if (ns < 0)
+    {
+      rns = ns + 1000000000;
+      if (rs == TYPE_MINIMUM (time_t))
+        {
+          if (bs <= 0)
+            goto low_overflow;
+          bs--;
+        }
+      else
+        rs--;
+    }
+
+  if (INT_SUBTRACT_OVERFLOW (rs, bs))
+    {
+      if (rs < 0)
+        {
+        low_overflow:
+          rs = TYPE_MINIMUM (time_t);
+          rns = 0;
+        }
+      else
+        {
+          rs = TYPE_MAXIMUM (time_t);
+          rns = 999999999;
+        }
+    }
+  else
+    rs -= bs;
+
+  r.tv_sec = rs;
+  r.tv_nsec = rns;
+  return r;
+}
index 191cf06..acf815c 100644 (file)
@@ -65,6 +65,8 @@ timespec_sign (struct timespec a)
   return a.tv_sec < 0 ? -1 : a.tv_sec || a.tv_nsec;
 }
 
+struct timespec timespec_add (struct timespec, struct timespec);
+struct timespec timespec_sub (struct timespec, struct timespec);
 struct timespec dtotimespec (double);
 
 /* Return an approximation to A, of type 'double'.  */
diff --git a/modules/timespec-add b/modules/timespec-add
new file mode 100644 (file)
index 0000000..c7ca395
--- /dev/null
@@ -0,0 +1,25 @@
+Description:
+Add timespec values.
+
+Files:
+lib/timespec-add.c
+
+Depends-on:
+intprops
+timespec
+
+configure.ac:
+
+Makefile.am:
+lib_SOURCES += timespec-add.c
+
+Include:
+"timespec.h"
+
+Link:
+
+License:
+GPL
+
+Maintainer:
+Paul Eggert, Jim Meyering
diff --git a/modules/timespec-sub b/modules/timespec-sub
new file mode 100644 (file)
index 0000000..3ec70b3
--- /dev/null
@@ -0,0 +1,25 @@
+Description:
+Subtract timespec values.
+
+Files:
+lib/timespec-sub.c
+
+Depends-on:
+intprops
+timespec
+
+configure.ac:
+
+Makefile.am:
+lib_SOURCES += timespec-sub.c
+
+Include:
+"timespec.h"
+
+Link:
+
+License:
+GPL
+
+Maintainer:
+Paul Eggert, Jim Meyering