mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-05-04 04:11:58 -07:00
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.
This commit is contained in:
parent
4516fbef72
commit
31571fd712
5 changed files with 71 additions and 32 deletions
|
|
@ -1,3 +1,17 @@
|
|||
2012-07-07 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
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 <rgm@gnu.org>
|
||||
|
||||
* s/darwin.h (HAVE_RES_INIT, HAVE_LIBRESOLV):
|
||||
|
|
|
|||
|
|
@ -1521,16 +1521,20 @@ disassemble_lisp_time (Lisp_Object specified_time, Lisp_Object *phigh,
|
|||
}
|
||||
|
||||
/* 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 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
|
|||
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;
|
||||
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;
|
||||
|
||||
sec = hi;
|
||||
EMACS_SET_SECS_NSECS (*result, (sec << 16) + lo, us * 1000 + ps / 1000);
|
||||
if (result_psec)
|
||||
*result_psec = ps % 1000;
|
||||
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_time_argument (Lisp_Object specified_time, int *ppsec)
|
|||
{
|
||||
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 @@ If precise time stamps are required, use either `current-time',
|
|||
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 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z".
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -3031,7 +3031,7 @@ Use the current time if TIMESTAMP is nil. TIMESTAMP is in the format of
|
|||
{
|
||||
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 @@ An argument specifies the modification time value to use
|
|||
{
|
||||
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
|
||||
|
|
|
|||
|
|
@ -112,8 +112,8 @@ extern void set_waiting_for_input (EMACS_TIME *);
|
|||
/* 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. */
|
||||
|
|
|
|||
|
|
@ -521,7 +521,7 @@ Return what remains of the list. */)
|
|||
(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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue