commit 8acb88c5026cb11cbff466f53bef9d3e864879e7 (HEAD, refs/remotes/origin/master) Author: Paul Eggert Date: Sun Jan 6 21:59:03 2019 -0800 Minor INFINITY/NAN cleanup * src/lread.c (INFINITY): Use a more-portable way to specify this macro on non-C99 platforms that lack it. (NAN): Remove; unused. diff --git a/src/lread.c b/src/lread.c index 788e57b707..02f7caaded 100644 --- a/src/lread.c +++ b/src/lread.c @@ -46,10 +46,6 @@ along with GNU Emacs. If not, see . */ #ifdef MSDOS #include "msdos.h" -#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 5 -# define INFINITY __builtin_inf() -# define NAN __builtin_nan("") -#endif #endif #ifdef HAVE_NS @@ -74,6 +70,9 @@ along with GNU Emacs. If not, see . */ #if IEEE_FLOATING_POINT # include +# ifndef INFINITY +# define INFINITY ((union ieee754_double) {.ieee = {.exponent = -1}}.d) +# endif #endif /* The objects or placeholders read with the #n=object form. commit 202bd7bff2710b98cde4ae4b6e1f6de9818591f8 Author: Paul Eggert Date: Sun Jan 6 16:23:41 2019 -0800 Fix logb on zero, infinite, NaN args Change logb to return -infinity, +infinity, and NaN respectively. Formerly logb returned an extreme fixnum to represent infinity, but this is no longer the right thing to do now that we have bignums and there is no extreme integer. * doc/lispref/numbers.texi (Float Basics), etc/NEWS: Document. * src/floatfns.c (Flogb): Implement this. diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi index cffc634169..fbdd83fa86 100644 --- a/doc/lispref/numbers.texi +++ b/doc/lispref/numbers.texi @@ -313,14 +313,18 @@ and returns the result. @var{x1} and @var{x2} must be floating point. @defun logb x This function returns the binary exponent of @var{x}. More -precisely, the value is the logarithm base 2 of @math{|x|}, rounded -down to an integer. +precisely, if @var{x} is finite and nonzero, the value is the +logarithm base 2 of @math{|x|}, rounded down to an integer. +If @var{x} is zero, infinite, or a NaN, the value is minus infinity, +plus infinity, or a NaN respectively. @example (logb 10) @result{} 3 (logb 10.0e20) @result{} 69 +(logb 0) + @result{} -1.0e+INF @end example @end defun diff --git a/etc/NEWS b/etc/NEWS index b316aecbfa..3670ab5bf4 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1112,6 +1112,10 @@ old-style backquotes as new-style, bind the new variable integer, Emacs now signals an error if the number is too large for the implementation to format. +** logb now returns infinity when given an infinite or zero argument, +and returns a NaN when given a NaN. Formerly, it returned an extreme +fixnum for such arguments. + --- ** Some functions and variables obsolete since Emacs 22 have been removed: archive-mouse-extract, assoc-ignore-case, assoc-ignore-representation, diff --git a/src/floatfns.c b/src/floatfns.c index 2d76b97eec..a913aad5aa 100644 --- a/src/floatfns.c +++ b/src/floatfns.c @@ -306,27 +306,22 @@ This is the same as the exponent of a float. */) if (FLOATP (arg)) { double f = XFLOAT_DATA (arg); - if (f == 0) - value = MOST_NEGATIVE_FIXNUM; - else if (isfinite (f)) - { - int ivalue; - frexp (f, &ivalue); - value = ivalue - 1; - } - else - value = MOST_POSITIVE_FIXNUM; + return make_float (-HUGE_VAL); + if (!isfinite (f)) + return f < 0 ? make_float (-f) : arg; + int ivalue; + frexp (f, &ivalue); + value = ivalue - 1; } - else if (BIGNUMP (arg)) + else if (!FIXNUMP (arg)) value = mpz_sizeinbase (XBIGNUM (arg)->value, 2) - 1; else { - eassert (FIXNUMP (arg)); - EMACS_INT i = eabs (XFIXNUM (arg)); - value = (i == 0 - ? MOST_NEGATIVE_FIXNUM - : EMACS_UINT_WIDTH - 1 - ecount_leading_zeros (i)); + EMACS_INT i = XFIXNUM (arg); + if (i == 0) + return make_float (-HUGE_VAL); + value = EMACS_UINT_WIDTH - 1 - ecount_leading_zeros (eabs (i)); } return make_fixnum (value); commit b0b483d714e87ee0a4572f9c541514a1ac1a8226 Author: Paul Eggert Date: Sun Jan 6 11:14:59 2019 -0800 Use integers for syntax-pps-stats * lisp/emacs-lisp/syntax.el (syntax-ppss-stats): Use integers, not floating-point, for stats, now that integers are unbounded. Almost always these should be fixnums. Add 1 to last slot’s car so that this addition need not be done at runtime. (syntax-pps-stats, syntax-ppss): Use integers for calculations. (syntax-ppss--update-stats): New convenience function. (syntax-ppss): Use it. diff --git a/lisp/emacs-lisp/syntax.el b/lisp/emacs-lisp/syntax.el index 0bc90e58fa..11cab1d693 100644 --- a/lisp/emacs-lisp/syntax.el +++ b/lisp/emacs-lisp/syntax.el @@ -434,14 +434,20 @@ These are valid when the buffer has no restriction.") (setcdr cell cache))) )) +;;; FIXME: Explain this variable. Currently only its last (5th) slot is used. +;;; Perhaps the other slots should be removed? (defvar syntax-ppss-stats - [(0 . 0.0) (0 . 0.0) (0 . 0.0) (0 . 0.0) (0 . 0.0) (1 . 2500.0)]) + [(0 . 0) (0 . 0) (0 . 0) (0 . 0) (0 . 0) (2 . 2500)]) (defun syntax-ppss-stats () (mapcar (lambda (x) (condition-case nil - (cons (car x) (truncate (/ (cdr x) (car x)))) + (cons (car x) (/ (cdr x) (car x))) (error nil))) syntax-ppss-stats)) +(defun syntax-ppss--update-stats (i old new) + (let ((pair (aref syntax-ppss-stats i))) + (cl-incf (car pair)) + (cl-incf (cdr pair) (- new old)))) (defvar-local syntax-ppss-table nil "Syntax-table to use during `syntax-ppss', if any.") @@ -486,11 +492,10 @@ running the hook." (if (and old-pos (< (- pos old-pos) ;; The time to use syntax-begin-function and ;; find PPSS is assumed to be about 2 * distance. - (* 2 (/ (cdr (aref syntax-ppss-stats 5)) - (1+ (car (aref syntax-ppss-stats 5))))))) + (let ((pair (aref syntax-ppss-stats 5))) + (/ (* 2 (cdr pair)) (car pair))))) (progn - (cl-incf (car (aref syntax-ppss-stats 0))) - (cl-incf (cdr (aref syntax-ppss-stats 0)) (- pos old-pos)) + (syntax-ppss--update-stats 0 old-pos pos) (parse-partial-sexp old-pos pos nil nil old-ppss)) (cond @@ -506,8 +511,7 @@ running the hook." (setq pt-min (or (syntax-ppss-toplevel-pos old-ppss) (nth 2 old-ppss))) (<= pt-min pos) (< (- pos pt-min) syntax-ppss-max-span)) - (cl-incf (car (aref syntax-ppss-stats 1))) - (cl-incf (cdr (aref syntax-ppss-stats 1)) (- pos pt-min)) + (syntax-ppss--update-stats 1 pt-min pos) (setq ppss (parse-partial-sexp pt-min pos))) ;; The OLD-* data can't be used. Consult the cache. (t @@ -535,8 +539,7 @@ running the hook." ;; Use the best of OLD-POS and CACHE. (if (or (not old-pos) (< old-pos pt-min)) (setq pt-best pt-min ppss-best ppss) - (cl-incf (car (aref syntax-ppss-stats 4))) - (cl-incf (cdr (aref syntax-ppss-stats 4)) (- pos old-pos)) + (syntax-ppss--update-stats 4 old-pos pos) (setq pt-best old-pos ppss-best old-ppss)) ;; Use the `syntax-begin-function' if available. @@ -556,21 +559,18 @@ running the hook." (not (memq (get-text-property (point) 'face) '(font-lock-string-face font-lock-doc-face font-lock-comment-face)))) - (cl-incf (car (aref syntax-ppss-stats 5))) - (cl-incf (cdr (aref syntax-ppss-stats 5)) (- pos (point))) + (syntax-ppss--update-stats 5 (point) pos) (setq pt-best (point) ppss-best nil)) (cond ;; Quick case when we found a nearby pos. ((< (- pos pt-best) syntax-ppss-max-span) - (cl-incf (car (aref syntax-ppss-stats 2))) - (cl-incf (cdr (aref syntax-ppss-stats 2)) (- pos pt-best)) + (syntax-ppss--update-stats 2 pt-best pos) (setq ppss (parse-partial-sexp pt-best pos nil nil ppss-best))) ;; Slow case: compute the state from some known position and ;; populate the cache so we won't need to do it again soon. (t - (cl-incf (car (aref syntax-ppss-stats 3))) - (cl-incf (cdr (aref syntax-ppss-stats 3)) (- pos pt-min)) + (syntax-ppss--update-stats 3 pt-min pos) ;; If `pt-min' is too far, add a few intermediate entries. (while (> (- pos pt-min) (* 2 syntax-ppss-max-span)) commit cfa54ab7d8a64a8a186e29ed2db2cbd58b99c0d9 Author: Michael Albinus Date: Sun Jan 6 15:42:57 2019 +0100 Adapt filenotify-tests for emba * test/lisp/filenotify-tests.el (file-notify-test03-events) (file-notify-test05-file-validity) (file-notify-test06-dir-validity) (file-notify-test07-many-events) (file-notify-test09-watched-file-in-watched-dir): Adapt tests for emba. diff --git a/lisp/filenotify.el b/lisp/filenotify.el index f66c8ed429..3f9bb960a9 100644 --- a/lisp/filenotify.el +++ b/lisp/filenotify.el @@ -114,7 +114,7 @@ Could be different from the directory watched by the backend library." (when-let* ((watch (gethash (car event) file-notify-descriptors))) (directory-file-name (expand-file-name - (or (and (stringp (nth 2 event)) (nth 2 event)) "") + (or (and (stringp (nth 2 event)) (nth 2 event)) "") (file-notify--watch-directory watch))))) ;; Only `gfilenotify' could return two file names. @@ -240,8 +240,10 @@ EVENT is the cadr of the event in `file-notify-handle-event' (file-notify--watch-filename watch) (file-name-nondirectory file1))))) ;;(message - ;;"file-notify-callback %S %S %S %S %S" - ;;desc action file file1 watch) + ;;"file-notify-callback %S %S %S %S %S %S %S" + ;;desc action file file1 watch + ;;(file-notify--event-watched-file event) + ;;(file-notify--watch-directory watch)) (funcall (file-notify--watch-callback watch) (if file1 `(,desc ,action ,file ,file1) @@ -419,11 +421,9 @@ DESCRIPTOR should be an object returned by `file-notify-add-watch'." descriptor)) t)))) - ;; TODO: -;; * Watching a /dir/file may receive events for dir. -;; (This may be the desired behavior.) -;; * Watching a file in an already watched directory + +;; * Watching a file in an already watched directory. ;; If the file is created and *then* a watch is added to that file, the ;; watch might receive events which occurred prior to it being created, ;; due to the way events are propagated during idle time. Note: This diff --git a/test/lisp/filenotify-tests.el b/test/lisp/filenotify-tests.el index d4e65af418..4be51afb47 100644 --- a/test/lisp/filenotify-tests.el +++ b/test/lisp/filenotify-tests.el @@ -588,7 +588,6 @@ delivered." (ert-deftest file-notify-test03-events () "Check file creation/change/removal notifications." - :tags (if (getenv "EMACS_EMBA_CI") '(:unstable)) (skip-unless (file-notify--test-local-enabled)) (unwind-protect @@ -689,6 +688,11 @@ delivered." '(created deleted stopped)) ((string-equal (file-notify--test-library) "kqueue") '(created changed deleted stopped)) + ;; inotify on emba does not detect `deleted' and + ;; `stopped' events of the directory. + ((and (string-equal (file-notify--test-library) "inotify") + (getenv "EMACS_EMBA_CI")) + '(created changed deleted)) (t '(created changed deleted deleted stopped))) (write-region "any text" nil file-notify--test-tmpfile nil 'no-message) @@ -734,6 +738,11 @@ delivered." '(created created changed changed deleted stopped)) ((string-equal (file-notify--test-library) "kqueue") '(created changed created changed deleted stopped)) + ;; inotify on emba does not detect `deleted' and + ;; `stopped' events of the directory. + ((and (string-equal (file-notify--test-library) "inotify") + (getenv "EMACS_EMBA_CI")) + '(created changed created changed deleted deleted)) (t '(created changed created changed deleted deleted deleted stopped))) (write-region @@ -786,6 +795,11 @@ delivered." '(created created deleted deleted stopped)) ((string-equal (file-notify--test-library) "kqueue") '(created changed renamed deleted stopped)) + ;; inotify on emba does not detect `deleted' and + ;; `stopped' events of the directory. + ((and (string-equal (file-notify--test-library) "inotify") + (getenv "EMACS_EMBA_CI")) + '(created changed renamed deleted)) (t '(created changed renamed deleted deleted stopped))) (write-region "any text" nil file-notify--test-tmpfile nil 'no-message) @@ -946,7 +960,6 @@ delivered." (ert-deftest file-notify-test05-file-validity () "Check `file-notify-valid-p' for files." - :tags (if (getenv "EMACS_EMBA_CI") '(:unstable)) (skip-unless (file-notify--test-local-enabled)) (unwind-protect @@ -1004,62 +1017,66 @@ delivered." ;; Cleanup. (file-notify--test-cleanup)) - (unwind-protect - (let ((file-notify--test-tmpdir - (make-temp-file "file-notify-test-parent" t))) - (should - (setq file-notify--test-tmpfile (file-notify--test-make-temp-name) - file-notify--test-desc - (file-notify-add-watch - file-notify--test-tmpdir - '(change) #'file-notify--test-event-handler))) - (should (file-notify-valid-p file-notify--test-desc)) - (file-notify--test-with-events - (cond - ;; w32notify does not raise `deleted' and `stopped' events - ;; for the watched directory. - ((string-equal (file-notify--test-library) "w32notify") - '(created changed deleted)) - ;; gvfs-monitor-dir on cygwin does not detect the `created' - ;; event reliably. - ((string-equal (file-notify--test-library) "gvfs-monitor-dir.exe") - '((deleted stopped) - (created deleted stopped))) - ;; There are two `deleted' events, for the file and for the - ;; directory. Except for cygwin and kqueue. And cygwin - ;; does not raise a `changed' event. - ((eq system-type 'cygwin) - '(created deleted stopped)) - ((string-equal (file-notify--test-library) "kqueue") - '(created changed deleted stopped)) - (t '(created changed deleted deleted stopped))) - (write-region - "any text" nil file-notify--test-tmpfile nil 'no-message) - (file-notify--test-read-event) - (delete-directory file-notify--test-tmpdir 'recursive)) - ;; After deleting the parent directory, the descriptor must - ;; not be valid anymore. - (should-not (file-notify-valid-p file-notify--test-desc)) - ;; w32notify doesn't generate `stopped' events when the parent - ;; directory is deleted, which doesn't provide a chance for - ;; filenotify.el to remove the descriptor from the internal - ;; hash table it maintains. So we must remove the descriptor - ;; manually. - (if (string-equal (file-notify--test-library) "w32notify") - (file-notify--rm-descriptor file-notify--test-desc)) + ;; inotify on emba does not detect `deleted' and + ;; `stopped' events of the directory. + (unless (and (string-equal (file-notify--test-library) "inotify") + (getenv "EMACS_EMBA_CI")) + (unwind-protect + (let ((file-notify--test-tmpdir + (make-temp-file "file-notify-test-parent" t))) + (should + (setq file-notify--test-tmpfile (file-notify--test-make-temp-name) + file-notify--test-desc + (file-notify-add-watch + file-notify--test-tmpdir + '(change) #'file-notify--test-event-handler))) + (should (file-notify-valid-p file-notify--test-desc)) + (file-notify--test-with-events + (cond + ;; w32notify does not raise `deleted' and `stopped' + ;; events for the watched directory. + ((string-equal (file-notify--test-library) "w32notify") + '(created changed deleted)) + ;; gvfs-monitor-dir on cygwin does not detect the + ;; `created' event reliably. + ((string-equal + (file-notify--test-library) "gvfs-monitor-dir.exe") + '((deleted stopped) + (created deleted stopped))) + ;; There are two `deleted' events, for the file and for + ;; the directory. Except for cygwin and kqueue. And + ;; cygwin does not raise a `changed' event. + ((eq system-type 'cygwin) + '(created deleted stopped)) + ((string-equal (file-notify--test-library) "kqueue") + '(created changed deleted stopped)) + (t '(created changed deleted deleted stopped))) + (write-region + "any text" nil file-notify--test-tmpfile nil 'no-message) + (file-notify--test-read-event) + (delete-directory file-notify--test-tmpdir 'recursive)) + ;; After deleting the parent directory, the descriptor must + ;; not be valid anymore. + (should-not (file-notify-valid-p file-notify--test-desc)) + ;; w32notify doesn't generate `stopped' events when the + ;; parent directory is deleted, which doesn't provide a + ;; chance for filenotify.el to remove the descriptor from + ;; the internal hash table it maintains. So we must remove + ;; the descriptor manually. + (if (string-equal (file-notify--test-library) "w32notify") + (file-notify--rm-descriptor file-notify--test-desc)) - ;; The environment shall be cleaned up. - (file-notify--test-cleanup-p)) + ;; The environment shall be cleaned up. + (file-notify--test-cleanup-p)) - ;; Cleanup. - (file-notify--test-cleanup))) + ;; Cleanup. + (file-notify--test-cleanup)))) (file-notify--deftest-remote file-notify-test05-file-validity "Check `file-notify-valid-p' via file notification for remote files.") (ert-deftest file-notify-test06-dir-validity () "Check `file-notify-valid-p' for directories." - :tags (if (getenv "EMACS_EMBA_CI") '(:unstable)) (skip-unless (file-notify--test-local-enabled)) (unwind-protect @@ -1087,39 +1104,42 @@ delivered." ;; Cleanup. (file-notify--test-cleanup)) - (unwind-protect - (progn - (should - (setq file-notify--test-tmpfile - (make-temp-file "file-notify-test-parent" t))) - (should - (setq file-notify--test-desc - (file-notify-add-watch - file-notify--test-tmpfile '(change) #'ignore))) - (should (file-notify-valid-p file-notify--test-desc)) - ;; After deleting the directory, the descriptor must not be - ;; valid anymore. - (delete-directory file-notify--test-tmpfile 'recursive) - (file-notify--wait-for-events - (file-notify--test-timeout) - (not (file-notify-valid-p file-notify--test-desc))) - (should-not (file-notify-valid-p file-notify--test-desc)) - (if (string-equal (file-notify--test-library) "w32notify") - (file-notify--rm-descriptor file-notify--test-desc)) + ;; inotify on emba does not detect `deleted' and + ;; `stopped' events of the directory. + (unless (and (string-equal (file-notify--test-library) "inotify") + (getenv "EMACS_EMBA_CI")) + (unwind-protect + (progn + (should + (setq file-notify--test-tmpfile + (make-temp-file "file-notify-test-parent" t))) + (should + (setq file-notify--test-desc + (file-notify-add-watch + file-notify--test-tmpfile '(change) #'ignore))) + (should (file-notify-valid-p file-notify--test-desc)) + ;; After deleting the directory, the descriptor must not be + ;; valid anymore. + (delete-directory file-notify--test-tmpfile 'recursive) + (file-notify--wait-for-events + (file-notify--test-timeout) + (not (file-notify-valid-p file-notify--test-desc))) + (should-not (file-notify-valid-p file-notify--test-desc)) + (if (string-equal (file-notify--test-library) "w32notify") + (file-notify--rm-descriptor file-notify--test-desc)) - ;; The environment shall be cleaned up. - (file-notify--test-cleanup-p)) + ;; The environment shall be cleaned up. + (file-notify--test-cleanup-p)) - ;; Cleanup. - (file-notify--test-cleanup))) + ;; Cleanup. + (file-notify--test-cleanup)))) (file-notify--deftest-remote file-notify-test06-dir-validity "Check `file-notify-valid-p' via file notification for remote directories.") (ert-deftest file-notify-test07-many-events () "Check that events are not dropped." - :tags (if (getenv "EMACS_EMBA_CI") - '(:expensive-test :unstable) '(:expensive-test)) + :tags '(:expensive-test) (skip-unless (file-notify--test-local-enabled)) (should @@ -1178,7 +1198,9 @@ delivered." (file-notify--test-read-event) (delete-file file))) (delete-directory file-notify--test-tmpfile) - (if (string-equal (file-notify--test-library) "w32notify") + (if (or (string-equal (file-notify--test-library) "w32notify") + (and (string-equal (file-notify--test-library) "inotify") + (getenv "EMACS_EMBA_CI"))) (file-notify--rm-descriptor file-notify--test-desc)) ;; The environment shall be cleaned up. @@ -1278,8 +1300,7 @@ descriptors that were issued when registering the watches. This test caters for the situation in bug#22736 where the callback for the directory received events for the file with the descriptor of the file watch." - :tags (if (getenv "EMACS_EMBA_CI") - '(:expensive-test :unstable) '(:expensive-test)) + :tags '(:expensive-test) (skip-unless (file-notify--test-local-enabled)) ;; A directory to be watched. @@ -1388,11 +1409,20 @@ the file watch." ;; w32notify does not raise `deleted' and `stopped' ;; events for the watched directory. ((string-equal (file-notify--test-library) "w32notify") '()) + ;; inotify on emba does not detect `deleted' and + ;; `stopped' events of the directory. + ((and (string-equal (file-notify--test-library) "inotify") + (getenv "EMACS_EMBA_CI")) + '()) (t '(deleted stopped)))))) (delete-directory file-notify--test-tmpfile 'recursive)) - (should-not (file-notify-valid-p file-notify--test-desc1)) - (should-not (file-notify-valid-p file-notify--test-desc2)) - (when (string-equal (file-notify--test-library) "w32notify") + (unless (and (string-equal (file-notify--test-library) "inotify") + (getenv "EMACS_EMBA_CI")) + (should-not (file-notify-valid-p file-notify--test-desc1)) + (should-not (file-notify-valid-p file-notify--test-desc2))) + (when (or (string-equal (file-notify--test-library) "w32notify") + (and (string-equal (file-notify--test-library) "inotify") + (getenv "EMACS_EMBA_CI"))) (file-notify--rm-descriptor file-notify--test-desc1) (file-notify--rm-descriptor file-notify--test-desc2))