aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2012-07-06 18:57:42 -0700
committerPaul Eggert2012-07-06 18:57:42 -0700
commit31571fd712d8c1796f7d31739f1b48cf25948d64 (patch)
tree36e8f03e132306f2824b8711827fcd8a6514279a /src
parent4516fbef7207ca23ca72da28d060dad979319310 (diff)
downloademacs-31571fd712d8c1796f7d31739f1b48cf25948d64.tar.gz
emacs-31571fd712d8c1796f7d31739f1b48cf25948d64.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog14
-rw-r--r--src/editfns.c79
-rw-r--r--src/fileio.c4
-rw-r--r--src/systime.h4
-rw-r--r--src/undo.c2
5 files changed, 71 insertions, 32 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 03c92804fb8..435c6d87050 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,17 @@
12012-07-07 Paul Eggert <eggert@cs.ucla.edu>
2
3 Do not require float-time's arg to fit in time_t (Bug#11825).
4 This works better on hosts where time_t is unsigned, and where
5 float-time is applied to the (negative) difference between two times.
6 * editfns.c (decode_time_components): Last arg is now double *,
7 not int *, and means to store all the result as a double, without
8 worrying about whether the seconds part fits in time_t.
9 All callers changed.
10 (lisp_time_argument): Remove last int * arg, as it's no longer needed.
11 All callers changed.
12 (Ffloat_time): Do not fail merely because the specified time falls
13 outside of time_t range.
14
12012-07-07 Glenn Morris <rgm@gnu.org> 152012-07-07 Glenn Morris <rgm@gnu.org>
2 16
3 * s/darwin.h (HAVE_RES_INIT, HAVE_LIBRESOLV): 17 * s/darwin.h (HAVE_RES_INIT, HAVE_LIBRESOLV):
diff --git a/src/editfns.c b/src/editfns.c
index e40bea44e9c..fe119490f3f 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -1521,16 +1521,20 @@ disassemble_lisp_time (Lisp_Object specified_time, Lisp_Object *phigh,
1521} 1521}
1522 1522
1523/* From the time components HIGH, LOW, USEC and PSEC taken from a Lisp 1523/* From the time components HIGH, LOW, USEC and PSEC taken from a Lisp
1524 list, generate the corresponding EMACS_TIME value *RESULT, and 1524 list, generate the corresponding time value.
1525 if RESULT_PSEC is not null store into *RESULT_PSEC the 1525
1526 (nonnegative) difference in picoseconds between the input time and 1526 If RESULT is not null, store into *RESULT the converted time;
1527 the returned time. Return nonzero if successful. */ 1527 this can fail if the converted time does not fit into EMACS_TIME.
1528 If *DRESULT is not null, store into *DRESULT the number of
1529 seconds since the start of the POSIX Epoch.
1530
1531 Return nonzero if successful. */
1528int 1532int
1529decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec, 1533decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
1530 Lisp_Object psec, EMACS_TIME *result, int *result_psec) 1534 Lisp_Object psec,
1535 EMACS_TIME *result, double *dresult)
1531{ 1536{
1532 EMACS_INT hi, lo, us, ps; 1537 EMACS_INT hi, lo, us, ps;
1533 time_t sec;
1534 if (! (INTEGERP (high) && INTEGERP (low) 1538 if (! (INTEGERP (high) && INTEGERP (low)
1535 && INTEGERP (usec) && INTEGERP (psec))) 1539 && INTEGERP (usec) && INTEGERP (psec)))
1536 return 0; 1540 return 0;
@@ -1548,27 +1552,38 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
1548 us = us % 1000000 + 1000000 * (us % 1000000 < 0); 1552 us = us % 1000000 + 1000000 * (us % 1000000 < 0);
1549 lo &= (1 << 16) - 1; 1553 lo &= (1 << 16) - 1;
1550 1554
1551 /* Check for overflow in the highest-order component. */ 1555 if (result)
1552 if (! ((TYPE_SIGNED (time_t) ? TIME_T_MIN >> 16 <= hi : 0 <= hi) 1556 {
1553 && hi <= TIME_T_MAX >> 16)) 1557 if ((TYPE_SIGNED (time_t) ? TIME_T_MIN >> 16 <= hi : 0 <= hi)
1554 return 0; 1558 && hi <= TIME_T_MAX >> 16)
1559 {
1560 /* Return the greatest representable time that is not greater
1561 than the requested time. */
1562 time_t sec = hi;
1563 EMACS_SET_SECS_NSECS (*result, (sec << 16) + lo,
1564 us * 1000 + ps / 1000);
1565 }
1566 else
1567 {
1568 /* Overflow in the highest-order component. */
1569 return 0;
1570 }
1571 }
1572
1573 if (dresult)
1574 *dresult = (us * 1e6 + ps) / 1e12 + lo + hi * 65536.0;
1555 1575
1556 sec = hi;
1557 EMACS_SET_SECS_NSECS (*result, (sec << 16) + lo, us * 1000 + ps / 1000);
1558 if (result_psec)
1559 *result_psec = ps % 1000;
1560 return 1; 1576 return 1;
1561} 1577}
1562 1578
1563/* Decode a Lisp list SPECIFIED_TIME that represents a time. 1579/* Decode a Lisp list SPECIFIED_TIME that represents a time.
1564 If SPECIFIED_TIME is nil, use the current time. 1580 If SPECIFIED_TIME is nil, use the current time.
1565 Round the time down to the nearest EMACS_TIME value, and 1581
1566 if PPSEC is not null store into *PPSEC the (nonnegative) difference in 1582 Round the time down to the nearest EMACS_TIME value.
1567 picoseconds between the input time and the returned time.
1568 Return seconds since the Epoch. 1583 Return seconds since the Epoch.
1569 Signal an error if unsuccessful. */ 1584 Signal an error if unsuccessful. */
1570EMACS_TIME 1585EMACS_TIME
1571lisp_time_argument (Lisp_Object specified_time, int *ppsec) 1586lisp_time_argument (Lisp_Object specified_time)
1572{ 1587{
1573 EMACS_TIME t; 1588 EMACS_TIME t;
1574 if (NILP (specified_time)) 1589 if (NILP (specified_time))
@@ -1577,14 +1592,15 @@ lisp_time_argument (Lisp_Object specified_time, int *ppsec)
1577 { 1592 {
1578 Lisp_Object high, low, usec, psec; 1593 Lisp_Object high, low, usec, psec;
1579 if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec) 1594 if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec)
1580 && decode_time_components (high, low, usec, psec, &t, ppsec))) 1595 && decode_time_components (high, low, usec, psec, &t, 0)))
1581 error ("Invalid time specification"); 1596 error ("Invalid time specification");
1582 } 1597 }
1583 return t; 1598 return t;
1584} 1599}
1585 1600
1586/* Like lisp_time_argument, except decode only the seconds part, 1601/* Like lisp_time_argument, except decode only the seconds part,
1587 and do not check the subseconds part, and always round down. */ 1602 do not allow out-of-range time stamps, do not check the subseconds part,
1603 and always round down. */
1588static time_t 1604static time_t
1589lisp_seconds_argument (Lisp_Object specified_time) 1605lisp_seconds_argument (Lisp_Object specified_time)
1590{ 1606{
@@ -1616,12 +1632,21 @@ If precise time stamps are required, use either `current-time',
1616or (if you need time as a string) `format-time-string'. */) 1632or (if you need time as a string) `format-time-string'. */)
1617 (Lisp_Object specified_time) 1633 (Lisp_Object specified_time)
1618{ 1634{
1619 int psec; 1635 double t;
1620 EMACS_TIME t = lisp_time_argument (specified_time, &psec); 1636 if (NILP (specified_time))
1621 double ps = (1000 * 1000 * 1000 <= INTMAX_MAX / 1000 1637 {
1622 ? EMACS_NSECS (t) * (intmax_t) 1000 + psec 1638 EMACS_TIME now;
1623 : EMACS_NSECS (t) * 1e3 + psec); 1639 EMACS_GET_TIME (now);
1624 return make_float (EMACS_SECS (t) + ps / 1e12); 1640 t = EMACS_SECS (now) + EMACS_NSECS (now) / 1e9;
1641 }
1642 else
1643 {
1644 Lisp_Object high, low, usec, psec;
1645 if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec)
1646 && decode_time_components (high, low, usec, psec, 0, &t)))
1647 error ("Invalid time specification");
1648 }
1649 return make_float (t);
1625} 1650}
1626 1651
1627/* Write information into buffer S of size MAXSIZE, according to the 1652/* 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".
1730usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */) 1755usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */)
1731 (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal) 1756 (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal)
1732{ 1757{
1733 EMACS_TIME t = lisp_time_argument (timeval, 0); 1758 EMACS_TIME t = lisp_time_argument (timeval);
1734 struct tm tm; 1759 struct tm tm;
1735 1760
1736 CHECK_STRING (format_string); 1761 CHECK_STRING (format_string);
diff --git a/src/fileio.c b/src/fileio.c
index 0f6a1d5f799..8f3b9e92257 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3031,7 +3031,7 @@ Use the current time if TIMESTAMP is nil. TIMESTAMP is in the format of
3031{ 3031{
3032 Lisp_Object absname, encoded_absname; 3032 Lisp_Object absname, encoded_absname;
3033 Lisp_Object handler; 3033 Lisp_Object handler;
3034 EMACS_TIME t = lisp_time_argument (timestamp, 0); 3034 EMACS_TIME t = lisp_time_argument (timestamp);
3035 3035
3036 absname = Fexpand_file_name (filename, BVAR (current_buffer, directory)); 3036 absname = Fexpand_file_name (filename, BVAR (current_buffer, directory));
3037 3037
@@ -5159,7 +5159,7 @@ An argument specifies the modification time value to use
5159{ 5159{
5160 if (!NILP (time_list)) 5160 if (!NILP (time_list))
5161 { 5161 {
5162 current_buffer->modtime = lisp_time_argument (time_list, 0); 5162 current_buffer->modtime = lisp_time_argument (time_list);
5163 current_buffer->modtime_size = -1; 5163 current_buffer->modtime_size = -1;
5164 } 5164 }
5165 else 5165 else
diff --git a/src/systime.h b/src/systime.h
index 0f91551239e..938083a5ffc 100644
--- a/src/systime.h
+++ b/src/systime.h
@@ -112,8 +112,8 @@ extern void set_waiting_for_input (EMACS_TIME *);
112/* defined in editfns.c */ 112/* defined in editfns.c */
113extern Lisp_Object make_lisp_time (EMACS_TIME); 113extern Lisp_Object make_lisp_time (EMACS_TIME);
114extern int decode_time_components (Lisp_Object, Lisp_Object, Lisp_Object, 114extern int decode_time_components (Lisp_Object, Lisp_Object, Lisp_Object,
115 Lisp_Object, EMACS_TIME *, int *); 115 Lisp_Object, EMACS_TIME *, double *);
116extern EMACS_TIME lisp_time_argument (Lisp_Object, int *); 116extern EMACS_TIME lisp_time_argument (Lisp_Object);
117#endif 117#endif
118 118
119/* Compare times T1 and T2 for equality, inequality etc. */ 119/* Compare times T1 and T2 for equality, inequality etc. */
diff --git a/src/undo.c b/src/undo.c
index c4ef557a221..bada46563a0 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -521,7 +521,7 @@ Return what remains of the list. */)
521 (mod_time, 0, 521 (mod_time, 0,
522 XINT (XCAR (XCDR (XCDR (XCDR (cdr))))) / 1000); 522 XINT (XCAR (XCDR (XCDR (XCDR (cdr))))) / 1000);
523 else 523 else
524 mod_time = lisp_time_argument (cdr, 0); 524 mod_time = lisp_time_argument (cdr);
525 525
526 if (current_buffer->base_buffer) 526 if (current_buffer->base_buffer)
527 base_buffer = current_buffer->base_buffer; 527 base_buffer = current_buffer->base_buffer;