From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Paul Eggert Newsgroups: gmane.emacs.devel Subject: Re: master d0c77a1: Remove some assumptions about timestamp format Date: Thu, 27 Sep 2018 18:50:40 -0700 Organization: UCLA Computer Science Department Message-ID: <2cfc5ca3-d661-f431-397a-705682ab17eb@cs.ucla.edu> References: <20180925021527.10418.61555@vcs0.savannah.gnu.org> <20180925021528.9A119204E8@vcs0.savannah.gnu.org> <87bm8lanwu.fsf@gmx.de> <87o9ck6270.fsf@gmx.de> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------88C2B76544E47C490ACDE382" X-Trace: blaine.gmane.org 1538099362 22435 195.159.176.226 (28 Sep 2018 01:49:22 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 28 Sep 2018 01:49:22 +0000 (UTC) User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.0 Cc: emacs-devel@gnu.org To: Michael Albinus Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Sep 28 03:49:18 2018 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1g5hu9-0005iA-5E for ged-emacs-devel@m.gmane.org; Fri, 28 Sep 2018 03:49:17 +0200 Original-Received: from localhost ([::1]:40658 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g5hwF-0003eN-HS for ged-emacs-devel@m.gmane.org; Thu, 27 Sep 2018 21:51:27 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:46561) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g5hvb-0003eH-Ov for emacs-devel@gnu.org; Thu, 27 Sep 2018 21:50:48 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g5hvX-0008Cc-N3 for emacs-devel@gnu.org; Thu, 27 Sep 2018 21:50:47 -0400 Original-Received: from zimbra.cs.ucla.edu ([131.179.128.68]:60444) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1g5hvX-0008Bs-4Q for emacs-devel@gnu.org; Thu, 27 Sep 2018 21:50:43 -0400 Original-Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id E88EA161389; Thu, 27 Sep 2018 18:50:41 -0700 (PDT) Original-Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id ryEvywmEw7iq; Thu, 27 Sep 2018 18:50:40 -0700 (PDT) Original-Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id A80DD1615E8; Thu, 27 Sep 2018 18:50:40 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Original-Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id MZ0F9wZ7vXEv; Thu, 27 Sep 2018 18:50:40 -0700 (PDT) Original-Received: from Penguin.CS.UCLA.EDU (Penguin.CS.UCLA.EDU [131.179.64.200]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 83FDA161389; Thu, 27 Sep 2018 18:50:40 -0700 (PDT) Openpgp: preference=signencrypt Autocrypt: addr=eggert@cs.ucla.edu; prefer-encrypt=mutual; keydata= xsFNBEyAcmQBEADAAyH2xoTu7ppG5D3a8FMZEon74dCvc4+q1XA2J2tBy2pwaTqfhpxxdGA9 Jj50UJ3PD4bSUEgN8tLZ0san47l5XTAFLi2456ciSl5m8sKaHlGdt9XmAAtmXqeZVIYX/UFS 96fDzf4xhEmm/y7LbYEPQdUdxu47xA5KhTYp5bltF3WYDz1Ygd7gx07Auwp7iw7eNvnoDTAl KAl8KYDZzbDNCQGEbpY3efZIvPdeI+FWQN4W+kghy+P6au6PrIIhYraeua7XDdb2LS1en3Ss mE3QjqfRqI/A2ue8JMwsvXe/WK38Ezs6x74iTaqI3AFH6ilAhDqpMnd/msSESNFt76DiO1ZK QMr9amVPknjfPmJISqdhgB1DlEdw34sROf6V8mZw0xfqT6PKE46LcFefzs0kbg4GORf8vjG2 Sf1tk5eU8MBiyN/bZ03bKNjNYMpODDQQwuP84kYLkX2wBxxMAhBxwbDVZudzxDZJ1C2VXujC OJVxq2kljBM9ETYuUGqd75AW2LXrLw6+MuIsHFAYAgRr7+KcwDgBAfwhPBYX34nSSiHlmLC+ KaHLeCLF5ZI2vKm3HEeCTtlOg7xZEONgwzL+fdKo+D6SoC8RRxJKs8a3sVfI4t6CnrQzvJbB n6gxdgCu5i29J1QCYrCYvql2UyFPAK+do99/1jOXT4m2836j1wARAQABzSBQYXVsIEVnZ2Vy dCA8ZWdnZXJ0QGNzLnVjbGEuZWR1PsLBfgQTAQIAKAUCTIByZAIbAwUJEswDAAYLCQgHAwIG FQgCCQoLBBYCAwECH In-Reply-To: <87o9ck6270.fsf@gmx.de> Content-Language: en-US X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 131.179.128.68 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:230099 Archived-At: This is a multi-part message in MIME format. --------------88C2B76544E47C490ACDE382 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit I installed the attached, which should be a win independently of what Tramp needs as it adds support for time-equal, infinite and NaN time values. I hope it's enough for Tramp too in that it can use a NaN (or an infinity) to represent a timestamp that a filesystem can't possibly have. --------------88C2B76544E47C490ACDE382 Content-Type: text/x-patch; name="0001-time-equal-and-time-values-of-infinity-and-NaN.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0001-time-equal-and-time-values-of-infinity-and-NaN.patch" >From a588608988b5fe2c27637ad4c1783a945ea639dd Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 27 Sep 2018 18:28:27 -0700 Subject: [PATCH] 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. --- doc/lispref/os.texi | 11 +++++- etc/NEWS | 8 ++++ src/editfns.c | 58 ++++++++++++++++++++++------- test/lisp/emacs-lisp/timer-tests.el | 8 ++-- 4 files changed, 66 insertions(+), 19 deletions(-) diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index 8481fea806..67b78aea74 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi @@ -1736,17 +1736,26 @@ Time Calculations @defun time-less-p t1 t2 This returns @code{t} if time value @var{t1} is less than time value @var{t2}. +The result is @code{nil} if either argument is a NaN. +@end defun + +@defun time-equal t1 t2 +This returns @code{t} if @var{t1} and @var{t2} are equal time values. +The result is @code{nil} if either argument is a NaN. @end defun @defun time-subtract t1 t2 This returns the time difference @var{t1} @minus{} @var{t2} between -two time values, as a time value. If you need the difference in units +two time values, as a time value. However, the result is a float +if either argument is a float infinity or NaN@. +If you need the difference in units of elapsed seconds, use @code{float-time} (@pxref{Time of Day, float-time}) to convert the result into seconds. @end defun @defun time-add t1 t2 This returns the sum of two time values, as a time value. +However, the result is a float if either argument is a float infinity or NaN@. One argument should represent a time difference rather than a point in time, either as a list or as a single number of elapsed seconds. Here is how to add a number of seconds to a time value: diff --git a/etc/NEWS b/etc/NEWS index 2a609e4027..4dd4260b29 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -951,6 +951,14 @@ like file-attributes that compute file sizes and other attributes, functions like process-id that compute process IDs, and functions like user-uid and group-gid that compute user and group IDs. ++++ +** 'time-add', 'time-subtract', and 'time-less-p' now accept +infinities and NaNs too, and propagate them or return nil like +floating-point operators do. + ++++ +** New function 'time-equal' compares time values for equality. + ** define-minor-mode automatically documents the meaning of ARG. +++ diff --git a/src/editfns.c b/src/editfns.c index ec6e8ba98d..acd80bbf31 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -1589,13 +1589,21 @@ time_subtract (struct lisp_time ta, struct lisp_time tb) } static Lisp_Object -time_arith (Lisp_Object a, Lisp_Object b, - struct lisp_time (*op) (struct lisp_time, struct lisp_time)) +time_arith (Lisp_Object a, Lisp_Object b, bool subtract) { + if (FLOATP (a) && !isfinite (XFLOAT_DATA (a))) + { + double da = XFLOAT_DATA (a); + double db = XFLOAT_DATA (Ffloat_time (b)); + return make_float (subtract ? da - db : da + db); + } + if (FLOATP (b) && !isfinite (XFLOAT_DATA (b))) + return subtract ? make_float (-XFLOAT_DATA (b)) : b; + int alen, blen; struct lisp_time ta = lisp_time_struct (a, &alen); struct lisp_time tb = lisp_time_struct (b, &blen); - struct lisp_time t = op (ta, tb); + struct lisp_time t = (subtract ? time_subtract : time_add) (ta, tb); if (FIXNUM_OVERFLOW_P (t.hi)) time_overflow (); Lisp_Object val = Qnil; @@ -1623,7 +1631,7 @@ A nil value for either argument stands for the current time. See `current-time-string' for the various forms of a time value. */) (Lisp_Object a, Lisp_Object b) { - return time_arith (a, b, time_add); + return time_arith (a, b, false); } 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. See `current-time-string' for the various forms of a time value. */) (Lisp_Object a, Lisp_Object b) { - return time_arith (a, b, time_subtract); + return time_arith (a, b, true); +} + +/* Return negative, 0, positive if a < b, a == b, a > b respectively. + Return positive if either a or b is a NaN; this is good enough + for the current callers. */ +static int +time_cmp (Lisp_Object a, Lisp_Object b) +{ + if ((FLOATP (a) && !isfinite (XFLOAT_DATA (a))) + || (FLOATP (b) && !isfinite (XFLOAT_DATA (b)))) + { + double da = FLOATP (a) ? XFLOAT_DATA (a) : 0; + double db = FLOATP (b) ? XFLOAT_DATA (b) : 0; + return da < db ? -1 : da != db; + } + + int alen, blen; + struct lisp_time ta = lisp_time_struct (a, &alen); + struct lisp_time tb = lisp_time_struct (b, &blen); + return (ta.hi != tb.hi ? (ta.hi < tb.hi ? -1 : 1) + : ta.lo != tb.lo ? (ta.lo < tb.lo ? -1 : 1) + : ta.us != tb.us ? (ta.us < tb.us ? -1 : 1) + : ta.ps < tb.ps ? -1 : ta.ps != tb.ps); } 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. See `current-time-string' for the various forms of a time value. */) (Lisp_Object t1, Lisp_Object t2) { - int t1len, t2len; - struct lisp_time a = lisp_time_struct (t1, &t1len); - struct lisp_time b = lisp_time_struct (t2, &t2len); - return ((a.hi != b.hi ? a.hi < b.hi - : a.lo != b.lo ? a.lo < b.lo - : a.us != b.us ? a.us < b.us - : a.ps < b.ps) - ? Qt : Qnil); + return time_cmp (t1, t2) < 0 ? Qt : Qnil; +} + +DEFUN ("time-equal", Ftime_equal, Stime_equal, 2, 2, 0, + doc: /* Return non-nil if T1 and T2 are equal time values. */) + (Lisp_Object t1, Lisp_Object t2) +{ + return time_cmp (t1, t2) == 0 ? Qt : Qnil; } @@ -5734,6 +5765,7 @@ it to be non-nil. */); defsubr (&Scurrent_time); defsubr (&Stime_add); defsubr (&Stime_subtract); + defsubr (&Stime_equal); defsubr (&Stime_less_p); defsubr (&Sget_internal_run_time); defsubr (&Sformat_time_string); diff --git a/test/lisp/emacs-lisp/timer-tests.el b/test/lisp/emacs-lisp/timer-tests.el index 1d3ba757f6..0e40cdf442 100644 --- a/test/lisp/emacs-lisp/timer-tests.el +++ b/test/lisp/emacs-lisp/timer-tests.el @@ -40,10 +40,8 @@ (should (debug-timer-check)) t)) (ert-deftest timer-test-multiple-of-time () - (should (zerop - (float-time - (time-subtract - (timer-next-integral-multiple-of-time '(0 0 0 1) (1+ (ash 1 53))) - (list (ash 1 (- 53 16)) 1)))))) + (should (time-equal + (timer-next-integral-multiple-of-time '(0 0 0 1) (1+ (ash 1 53))) + (list (ash 1 (- 53 16)) 1)))) ;;; timer-tests.el ends here -- 2.17.1 --------------88C2B76544E47C490ACDE382--