diff options
| author | Paul Eggert | 2018-09-27 18:28:27 -0700 |
|---|---|---|
| committer | Paul Eggert | 2018-09-27 18:43:54 -0700 |
| commit | 06e2814e1f3a80d247675319d3c438989592fb06 (patch) | |
| tree | a9852c5b278bcb85c4f3e0272848f89c2c511d11 /src | |
| parent | 21fc3227634c720128206980c72080dfc825a3de (diff) | |
| download | emacs-06e2814e1f3a80d247675319d3c438989592fb06.tar.gz emacs-06e2814e1f3a80d247675319d3c438989592fb06.zip | |
time-equal, and time values of infinity and NaN
* doc/lispref/os.texi (Time Calculations):
Document time-equal, and the behavior on NaNs and infinities of
time-less-p, time-add, time-subtract.
* etc/NEWS: Mention the change.
* src/editfns.c (time_arith): Change last arg from function
to bool. All callers changed. Do the right thing with
infinities and NaNs.
(time_cmp): New function, which handlesx infinities and NaNs.
(Ftime_less_p): Use it.
(Ftime_equal): New function.
* test/lisp/emacs-lisp/timer-tests.el (timer-test-multiple-of-time):
Use it.
Diffstat (limited to 'src')
| -rw-r--r-- | src/editfns.c | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/src/editfns.c b/src/editfns.c index ec6e8ba98d6..acd80bbf311 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -1589,13 +1589,21 @@ time_subtract (struct lisp_time ta, struct lisp_time tb) | |||
| 1589 | } | 1589 | } |
| 1590 | 1590 | ||
| 1591 | static Lisp_Object | 1591 | static Lisp_Object |
| 1592 | time_arith (Lisp_Object a, Lisp_Object b, | 1592 | time_arith (Lisp_Object a, Lisp_Object b, bool subtract) |
| 1593 | struct lisp_time (*op) (struct lisp_time, struct lisp_time)) | ||
| 1594 | { | 1593 | { |
| 1594 | if (FLOATP (a) && !isfinite (XFLOAT_DATA (a))) | ||
| 1595 | { | ||
| 1596 | double da = XFLOAT_DATA (a); | ||
| 1597 | double db = XFLOAT_DATA (Ffloat_time (b)); | ||
| 1598 | return make_float (subtract ? da - db : da + db); | ||
| 1599 | } | ||
| 1600 | if (FLOATP (b) && !isfinite (XFLOAT_DATA (b))) | ||
| 1601 | return subtract ? make_float (-XFLOAT_DATA (b)) : b; | ||
| 1602 | |||
| 1595 | int alen, blen; | 1603 | int alen, blen; |
| 1596 | struct lisp_time ta = lisp_time_struct (a, &alen); | 1604 | struct lisp_time ta = lisp_time_struct (a, &alen); |
| 1597 | struct lisp_time tb = lisp_time_struct (b, &blen); | 1605 | struct lisp_time tb = lisp_time_struct (b, &blen); |
| 1598 | struct lisp_time t = op (ta, tb); | 1606 | struct lisp_time t = (subtract ? time_subtract : time_add) (ta, tb); |
| 1599 | if (FIXNUM_OVERFLOW_P (t.hi)) | 1607 | if (FIXNUM_OVERFLOW_P (t.hi)) |
| 1600 | time_overflow (); | 1608 | time_overflow (); |
| 1601 | Lisp_Object val = Qnil; | 1609 | Lisp_Object val = Qnil; |
| @@ -1623,7 +1631,7 @@ A nil value for either argument stands for the current time. | |||
| 1623 | See `current-time-string' for the various forms of a time value. */) | 1631 | See `current-time-string' for the various forms of a time value. */) |
| 1624 | (Lisp_Object a, Lisp_Object b) | 1632 | (Lisp_Object a, Lisp_Object b) |
| 1625 | { | 1633 | { |
| 1626 | return time_arith (a, b, time_add); | 1634 | return time_arith (a, b, false); |
| 1627 | } | 1635 | } |
| 1628 | 1636 | ||
| 1629 | DEFUN ("time-subtract", Ftime_subtract, Stime_subtract, 2, 2, 0, | 1637 | DEFUN ("time-subtract", Ftime_subtract, Stime_subtract, 2, 2, 0, |
| @@ -1633,7 +1641,30 @@ A nil value for either argument stands for the current time. | |||
| 1633 | See `current-time-string' for the various forms of a time value. */) | 1641 | See `current-time-string' for the various forms of a time value. */) |
| 1634 | (Lisp_Object a, Lisp_Object b) | 1642 | (Lisp_Object a, Lisp_Object b) |
| 1635 | { | 1643 | { |
| 1636 | return time_arith (a, b, time_subtract); | 1644 | return time_arith (a, b, true); |
| 1645 | } | ||
| 1646 | |||
| 1647 | /* Return negative, 0, positive if a < b, a == b, a > b respectively. | ||
| 1648 | Return positive if either a or b is a NaN; this is good enough | ||
| 1649 | for the current callers. */ | ||
| 1650 | static int | ||
| 1651 | time_cmp (Lisp_Object a, Lisp_Object b) | ||
| 1652 | { | ||
| 1653 | if ((FLOATP (a) && !isfinite (XFLOAT_DATA (a))) | ||
| 1654 | || (FLOATP (b) && !isfinite (XFLOAT_DATA (b)))) | ||
| 1655 | { | ||
| 1656 | double da = FLOATP (a) ? XFLOAT_DATA (a) : 0; | ||
| 1657 | double db = FLOATP (b) ? XFLOAT_DATA (b) : 0; | ||
| 1658 | return da < db ? -1 : da != db; | ||
| 1659 | } | ||
| 1660 | |||
| 1661 | int alen, blen; | ||
| 1662 | struct lisp_time ta = lisp_time_struct (a, &alen); | ||
| 1663 | struct lisp_time tb = lisp_time_struct (b, &blen); | ||
| 1664 | return (ta.hi != tb.hi ? (ta.hi < tb.hi ? -1 : 1) | ||
| 1665 | : ta.lo != tb.lo ? (ta.lo < tb.lo ? -1 : 1) | ||
| 1666 | : ta.us != tb.us ? (ta.us < tb.us ? -1 : 1) | ||
| 1667 | : ta.ps < tb.ps ? -1 : ta.ps != tb.ps); | ||
| 1637 | } | 1668 | } |
| 1638 | 1669 | ||
| 1639 | DEFUN ("time-less-p", Ftime_less_p, Stime_less_p, 2, 2, 0, | 1670 | DEFUN ("time-less-p", Ftime_less_p, Stime_less_p, 2, 2, 0, |
| @@ -1642,14 +1673,14 @@ A nil value for either argument stands for the current time. | |||
| 1642 | See `current-time-string' for the various forms of a time value. */) | 1673 | See `current-time-string' for the various forms of a time value. */) |
| 1643 | (Lisp_Object t1, Lisp_Object t2) | 1674 | (Lisp_Object t1, Lisp_Object t2) |
| 1644 | { | 1675 | { |
| 1645 | int t1len, t2len; | 1676 | return time_cmp (t1, t2) < 0 ? Qt : Qnil; |
| 1646 | struct lisp_time a = lisp_time_struct (t1, &t1len); | 1677 | } |
| 1647 | struct lisp_time b = lisp_time_struct (t2, &t2len); | 1678 | |
| 1648 | return ((a.hi != b.hi ? a.hi < b.hi | 1679 | DEFUN ("time-equal", Ftime_equal, Stime_equal, 2, 2, 0, |
| 1649 | : a.lo != b.lo ? a.lo < b.lo | 1680 | doc: /* Return non-nil if T1 and T2 are equal time values. */) |
| 1650 | : a.us != b.us ? a.us < b.us | 1681 | (Lisp_Object t1, Lisp_Object t2) |
| 1651 | : a.ps < b.ps) | 1682 | { |
| 1652 | ? Qt : Qnil); | 1683 | return time_cmp (t1, t2) == 0 ? Qt : Qnil; |
| 1653 | } | 1684 | } |
| 1654 | 1685 | ||
| 1655 | 1686 | ||
| @@ -5734,6 +5765,7 @@ it to be non-nil. */); | |||
| 5734 | defsubr (&Scurrent_time); | 5765 | defsubr (&Scurrent_time); |
| 5735 | defsubr (&Stime_add); | 5766 | defsubr (&Stime_add); |
| 5736 | defsubr (&Stime_subtract); | 5767 | defsubr (&Stime_subtract); |
| 5768 | defsubr (&Stime_equal); | ||
| 5737 | defsubr (&Stime_less_p); | 5769 | defsubr (&Stime_less_p); |
| 5738 | defsubr (&Sget_internal_run_time); | 5770 | defsubr (&Sget_internal_run_time); |
| 5739 | defsubr (&Sformat_time_string); | 5771 | defsubr (&Sformat_time_string); |