emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r108928: Do not require float-time's


From: Paul Eggert
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r108928: Do not require float-time's arg to fit in time_t (Bug#11825).
Date: Fri, 06 Jul 2012 18:57:42 -0700
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 108928
committer: Paul Eggert <address@hidden>
branch nick: trunk
timestamp: Fri 2012-07-06 18:57:42 -0700
message:
  Do not require float-time's arg to fit in time_t (Bug#11825).
  
  This works better on hosts where time_t is unsigned, and where
  float-time is applied to the (negative) difference between two times.
  * editfns.c (decode_time_components): Last arg is now double *,
  not int *, and means to store all the result as a double, without
  worrying about whether the seconds part fits in time_t.
  All callers changed.
  (lisp_time_argument): Remove last int * arg, as it's no longer needed.
  All callers changed.
  (Ffloat_time): Do not fail merely because the specified time falls
  outside of time_t range.
modified:
  src/ChangeLog
  src/editfns.c
  src/fileio.c
  src/systime.h
  src/undo.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2012-07-07 01:03:46 +0000
+++ b/src/ChangeLog     2012-07-07 01:57:42 +0000
@@ -1,3 +1,17 @@
+2012-07-07  Paul Eggert  <address@hidden>
+
+       Do not require float-time's arg to fit in time_t (Bug#11825).
+       This works better on hosts where time_t is unsigned, and where
+       float-time is applied to the (negative) difference between two times.
+       * editfns.c (decode_time_components): Last arg is now double *,
+       not int *, and means to store all the result as a double, without
+       worrying about whether the seconds part fits in time_t.
+       All callers changed.
+       (lisp_time_argument): Remove last int * arg, as it's no longer needed.
+       All callers changed.
+       (Ffloat_time): Do not fail merely because the specified time falls
+       outside of time_t range.
+
 2012-07-07  Glenn Morris  <address@hidden>
 
        * s/darwin.h (HAVE_RES_INIT, HAVE_LIBRESOLV):

=== modified file 'src/editfns.c'
--- a/src/editfns.c     2012-07-06 05:07:44 +0000
+++ b/src/editfns.c     2012-07-07 01:57:42 +0000
@@ -1521,16 +1521,20 @@
 }
 
 /* From the time components HIGH, LOW, USEC and PSEC taken from a Lisp
-   list, generate the corresponding EMACS_TIME value *RESULT, and
-   if RESULT_PSEC is not null store into *RESULT_PSEC the
-   (nonnegative) difference in picoseconds between the input time and
-   the returned time.  Return nonzero if successful.  */
+   list, generate the corresponding time value.
+
+   If RESULT is not null, store into *RESULT the converted time;
+   this can fail if the converted time does not fit into EMACS_TIME.
+   If *DRESULT is not null, store into *DRESULT the number of
+   seconds since the start of the POSIX Epoch.
+
+   Return nonzero if successful.  */
 int
 decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
-                       Lisp_Object psec, EMACS_TIME *result, int *result_psec)
+                       Lisp_Object psec,
+                       EMACS_TIME *result, double *dresult)
 {
   EMACS_INT hi, lo, us, ps;
-  time_t sec;
   if (! (INTEGERP (high) && INTEGERP (low)
         && INTEGERP (usec) && INTEGERP (psec)))
     return 0;
@@ -1548,27 +1552,38 @@
   us = us % 1000000 + 1000000 * (us % 1000000 < 0);
   lo &= (1 << 16) - 1;
 
-  /* Check for overflow in the highest-order component.  */
-  if (! ((TYPE_SIGNED (time_t) ? TIME_T_MIN >> 16 <= hi : 0 <= hi)
-        && hi <= TIME_T_MAX >> 16))
-    return 0;
-
-  sec = hi;
-  EMACS_SET_SECS_NSECS (*result, (sec << 16) + lo, us * 1000 + ps / 1000);
-  if (result_psec)
-    *result_psec = ps % 1000;
+  if (result)
+    {
+      if ((TYPE_SIGNED (time_t) ? TIME_T_MIN >> 16 <= hi : 0 <= hi)
+         && hi <= TIME_T_MAX >> 16)
+       {
+         /* Return the greatest representable time that is not greater
+            than the requested time.  */
+         time_t sec = hi;
+         EMACS_SET_SECS_NSECS (*result, (sec << 16) + lo,
+                               us * 1000 + ps / 1000);
+       }
+      else
+       {
+         /* Overflow in the highest-order component.  */
+         return 0;
+       }
+    }
+
+  if (dresult)
+    *dresult = (us * 1e6 + ps) / 1e12 + lo + hi * 65536.0;
+
   return 1;
 }
 
 /* Decode a Lisp list SPECIFIED_TIME that represents a time.
    If SPECIFIED_TIME is nil, use the current time.
-   Round the time down to the nearest EMACS_TIME value, and
-   if PPSEC is not null store into *PPSEC the (nonnegative) difference in
-   picoseconds between the input time and the returned time.
+
+   Round the time down to the nearest EMACS_TIME value.
    Return seconds since the Epoch.
    Signal an error if unsuccessful.  */
 EMACS_TIME
-lisp_time_argument (Lisp_Object specified_time, int *ppsec)
+lisp_time_argument (Lisp_Object specified_time)
 {
   EMACS_TIME t;
   if (NILP (specified_time))
@@ -1577,14 +1592,15 @@
     {
       Lisp_Object high, low, usec, psec;
       if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec)
-            && decode_time_components (high, low, usec, psec, &t, ppsec)))
+            && decode_time_components (high, low, usec, psec, &t, 0)))
        error ("Invalid time specification");
     }
   return t;
 }
 
 /* Like lisp_time_argument, except decode only the seconds part,
-   and do not check the subseconds part, and always round down.  */
+   do not allow out-of-range time stamps, do not check the subseconds part,
+   and always round down.  */
 static time_t
 lisp_seconds_argument (Lisp_Object specified_time)
 {
@@ -1616,12 +1632,21 @@
 or (if you need time as a string) `format-time-string'.  */)
   (Lisp_Object specified_time)
 {
-  int psec;
-  EMACS_TIME t = lisp_time_argument (specified_time, &psec);
-  double ps = (1000 * 1000 * 1000 <= INTMAX_MAX / 1000
-              ? EMACS_NSECS (t) * (intmax_t) 1000 + psec
-              : EMACS_NSECS (t) * 1e3 + psec);
-  return make_float (EMACS_SECS (t) + ps / 1e12);
+  double t;
+  if (NILP (specified_time))
+    {
+      EMACS_TIME now;
+      EMACS_GET_TIME (now);
+      t = EMACS_SECS (now) + EMACS_NSECS (now) / 1e9;
+    }
+  else
+    {
+      Lisp_Object high, low, usec, psec;
+      if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec)
+            && decode_time_components (high, low, usec, psec, 0, &t)))
+       error ("Invalid time specification");
+    }
+  return make_float (t);
 }
 
 /* Write information into buffer S of size MAXSIZE, according to the
@@ -1730,7 +1755,7 @@
 usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL)  */)
   (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal)
 {
-  EMACS_TIME t = lisp_time_argument (timeval, 0);
+  EMACS_TIME t = lisp_time_argument (timeval);
   struct tm tm;
 
   CHECK_STRING (format_string);

=== modified file 'src/fileio.c'
--- a/src/fileio.c      2012-07-05 18:35:48 +0000
+++ b/src/fileio.c      2012-07-07 01:57:42 +0000
@@ -3031,7 +3031,7 @@
 {
   Lisp_Object absname, encoded_absname;
   Lisp_Object handler;
-  EMACS_TIME t = lisp_time_argument (timestamp, 0);
+  EMACS_TIME t = lisp_time_argument (timestamp);
 
   absname = Fexpand_file_name (filename, BVAR (current_buffer, directory));
 
@@ -5159,7 +5159,7 @@
 {
   if (!NILP (time_list))
     {
-      current_buffer->modtime = lisp_time_argument (time_list, 0);
+      current_buffer->modtime = lisp_time_argument (time_list);
       current_buffer->modtime_size = -1;
     }
   else

=== modified file 'src/systime.h'
--- a/src/systime.h     2012-06-24 17:21:20 +0000
+++ b/src/systime.h     2012-07-07 01:57:42 +0000
@@ -112,8 +112,8 @@
 /* defined in editfns.c */
 extern Lisp_Object make_lisp_time (EMACS_TIME);
 extern int decode_time_components (Lisp_Object, Lisp_Object, Lisp_Object,
-                                  Lisp_Object, EMACS_TIME *, int *);
-extern EMACS_TIME lisp_time_argument (Lisp_Object, int *);
+                                  Lisp_Object, EMACS_TIME *, double *);
+extern EMACS_TIME lisp_time_argument (Lisp_Object);
 #endif
 
 /* Compare times T1 and T2 for equality, inequality etc.  */

=== modified file 'src/undo.c'
--- a/src/undo.c        2012-06-24 17:39:14 +0000
+++ b/src/undo.c        2012-07-07 01:57:42 +0000
@@ -521,7 +521,7 @@
                      (mod_time, 0,
                       XINT (XCAR (XCDR (XCDR (XCDR (cdr))))) / 1000);
                  else
-                   mod_time = lisp_time_argument (cdr, 0);
+                   mod_time = lisp_time_argument (cdr);
 
                  if (current_buffer->base_buffer)
                    base_buffer = current_buffer->base_buffer;


reply via email to

[Prev in Thread] Current Thread [Next in Thread]