]> git.eshelyaron.com Git - emacs.git/commitdiff
Better distinguish infinite from invalid times
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 9 Feb 2015 00:21:11 +0000 (16:21 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 9 Feb 2015 00:21:44 +0000 (16:21 -0800)
* editfns.c (check_time_validity): New function.
(decode_time_components): Return int, not bool.
Return -1 (not 0) if the time is out of range.
All callers changed.
(lisp_time_struct, lisp_seconds_argument): Distinguish better
between time overflow and invalid time values.

src/ChangeLog
src/editfns.c
src/keyboard.c
src/systime.h

index 56f88f5bec42bfd1f415d11e0a78d1af40e32783..017b8f15e3b6477da505bd238c554c29c0af3991 100644 (file)
@@ -1,3 +1,13 @@
+2015-02-09  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Better distinguish infinite from invalid times
+       * editfns.c (check_time_validity): New function.
+       (decode_time_components): Return int, not bool.
+       Return -1 (not 0) if the time is out of range.
+       All callers changed.
+       (lisp_time_struct, lisp_seconds_argument): Distinguish better
+       between time overflow and invalid time values.
+
 2015-02-08  Paul Eggert  <eggert@cs.ucla.edu>
 
        Minor tweaks to frame_size_history_add
index 7026ccc084ede5eff792ac8271177b2568295e3d..c205ca3688f6d4f15edb035b870ee3dfd725fff2 100644 (file)
@@ -1395,6 +1395,19 @@ invalid_time (void)
   error ("Invalid time specification");
 }
 
+/* Check a return value compatible with that of decode_time_components.  */
+static void
+check_time_validity (int validity)
+{
+  if (validity <= 0)
+    {
+      if (validity < 0)
+       time_overflow ();
+      else
+       invalid_time ();
+    }
+}
+
 /* A substitute for mktime_z on platforms that lack it.  It's not
    thread-safe, but should be good enough for Emacs in typical use.  */
 #ifndef HAVE_TZALLOC
@@ -1698,9 +1711,9 @@ decode_float_time (double t, struct lisp_time *result)
    If *DRESULT is not null, store into *DRESULT the number of
    seconds since the start of the POSIX Epoch.
 
-   Return true if successful, false if the components are of the
-   wrong type or represent a time out of range.  */
-bool
+   Return 1 if successful, 0 if the components are of the
+   wrong type, and -1 if the time is out of range.  */
+int
 decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
                        Lisp_Object psec,
                        struct lisp_time *result, double *dresult)
@@ -1708,17 +1721,17 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
   EMACS_INT hi, lo, us, ps;
   if (! (INTEGERP (high)
         && INTEGERP (usec) && INTEGERP (psec)))
-    return false;
+    return 0;
   if (! INTEGERP (low))
     {
       if (FLOATP (low))
        {
          double t = XFLOAT_DATA (low);
          if (result && ! decode_float_time (t, result))
-           return false;
+           return -1;
          if (dresult)
            *dresult = t;
-         return true;
+         return 1;
        }
       else if (NILP (low))
        {
@@ -1732,10 +1745,10 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
            }
          if (dresult)
            *dresult = now.tv_sec + now.tv_nsec / 1e9;
-         return true;
+         return 1;
        }
       else
-       return false;
+       return 0;
     }
 
   hi = XINT (high);
@@ -1755,7 +1768,7 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
   if (result)
     {
       if (! (MOST_NEGATIVE_FIXNUM <= hi && hi <= MOST_POSITIVE_FIXNUM))
-       return false;
+       return -1;
       result->hi = hi;
       result->lo = lo;
       result->us = us;
@@ -1768,7 +1781,7 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
       *dresult = (us * 1e6 + ps) / 1e12 + lo + dhi * (1 << LO_TIME_BITS);
     }
 
-  return true;
+  return 1;
 }
 
 struct timespec
@@ -1792,8 +1805,8 @@ lisp_time_struct (Lisp_Object specified_time, int *plen)
   Lisp_Object high, low, usec, psec;
   struct lisp_time t;
   int len = disassemble_lisp_time (specified_time, &high, &low, &usec, &psec);
-  if (! (len && decode_time_components (high, low, usec, psec, &t, 0)))
-    invalid_time ();
+  int val = len ? decode_time_components (high, low, usec, psec, &t, 0) : 0;
+  check_time_validity (val);
   *plen = len;
   return t;
 }
@@ -1818,13 +1831,20 @@ lisp_seconds_argument (Lisp_Object specified_time)
 {
   Lisp_Object high, low, usec, psec;
   struct lisp_time t;
-  if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec)
-        && decode_time_components (high, low, make_number (0),
-                                   make_number (0), &t, 0)))
-    invalid_time ();
-  if (! ((TYPE_SIGNED (time_t) ? TIME_T_MIN >> LO_TIME_BITS <= t.hi : 0 <= t.hi)
-        && t.hi <= TIME_T_MAX >> LO_TIME_BITS))
-    time_overflow ();
+
+  int val = disassemble_lisp_time (specified_time, &high, &low, &usec, &psec);
+  if (val != 0)
+    {
+      val = decode_time_components (high, low, make_number (0),
+                                   make_number (0), &t, 0);
+      if (0 < val
+         && ! ((TYPE_SIGNED (time_t)
+                ? TIME_T_MIN >> LO_TIME_BITS <= t.hi
+                : 0 <= t.hi)
+               && t.hi <= TIME_T_MAX >> LO_TIME_BITS))
+       val = -1;
+    }
+  check_time_validity (val);
   return (t.hi << LO_TIME_BITS) + t.lo;
 }
 
index 1176d701f2a16032481d20b0a1c50d6de37c3cd0..ee621923c6779a83f3c9075b79c979b9142408a4 100644 (file)
@@ -4369,19 +4369,18 @@ Lisp_Object pending_funcalls;
 static bool
 decode_timer (Lisp_Object timer, struct timespec *result)
 {
-  Lisp_Object *vector;
+  Lisp_Object *vec;
 
   if (! (VECTORP (timer) && ASIZE (timer) == 9))
     return 0;
-  vector = XVECTOR (timer)->contents;
-  if (! NILP (vector[0]))
+  vec = XVECTOR (timer)->contents;
+  if (! NILP (vec[0]))
     return 0;
-  if (! INTEGERP (vector[2]))
+  if (! INTEGERP (vec[2]))
     return false;
 
   struct lisp_time t;
-  if (! decode_time_components (vector[1], vector[2], vector[3], vector[8],
-                               &t, 0))
+  if (decode_time_components (vec[1], vec[2], vec[3], vec[8], &t, 0) <= 0)
     return false;
   *result = lisp_to_timespec (t);
   return timespec_valid_p (*result);
index 1d3a4ba2914ef3b95b138add768fe2b426a3c179..4787c512aaa4c0eb3e8b8b54b3d215b6e1ac38a1 100644 (file)
@@ -100,8 +100,8 @@ struct lisp_time
 
 /* defined in editfns.c */
 extern Lisp_Object make_lisp_time (struct timespec);
-extern bool decode_time_components (Lisp_Object, Lisp_Object, Lisp_Object,
-                                   Lisp_Object, struct lisp_time *, double *);
+extern int decode_time_components (Lisp_Object, Lisp_Object, Lisp_Object,
+                                  Lisp_Object, struct lisp_time *, double *);
 extern struct timespec lisp_to_timespec (struct lisp_time);
 extern struct timespec lisp_time_argument (Lisp_Object);
 #endif