emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] feature/tramp-thread-safe 1488024 2/2: Merge remote-tracki


From: Michael Albinus
Subject: [Emacs-diffs] feature/tramp-thread-safe 1488024 2/2: Merge remote-tracking branch 'origin/master' into feature/tramp-thread-safe
Date: Mon, 5 Nov 2018 08:41:04 -0500 (EST)

branch: feature/tramp-thread-safe
commit 14880247131504e7e0894c79cd71a2744ace70d8
Merge: 80da4fa 294a524
Author: Michael Albinus <address@hidden>
Commit: Michael Albinus <address@hidden>

    Merge remote-tracking branch 'origin/master' into feature/tramp-thread-safe
---
 .gitignore                          |    1 +
 admin/MAINTAINERS                   |    2 +-
 admin/automerge                     |    6 +
 admin/bzrmerge.el                   |  359 ---------
 admin/gitmerge.el                   |   27 +-
 configure.ac                        |   60 +-
 doc/emacs/cmdargs.texi              |   18 +-
 doc/emacs/files.texi                |    9 +-
 doc/emacs/frames.texi               |    4 +
 doc/emacs/mark.texi                 |    3 +-
 doc/emacs/misc.texi                 |    4 +
 doc/emacs/search.texi               |  150 ++--
 doc/emacs/windows.texi              |  127 +--
 doc/emacs/xresources.texi           |    5 +
 doc/lispref/commands.texi           |    3 +
 doc/lispref/control.texi            |  215 +++--
 doc/lispref/display.texi            |    8 +-
 doc/lispref/edebug.texi             |    1 -
 doc/lispref/elisp.texi              |   25 +-
 doc/lispref/frames.texi             |   10 +-
 doc/lispref/functions.texi          |    7 +
 doc/lispref/internals.texi          |  703 +++++++++++++++++
 doc/lispref/loading.texi            |   33 +-
 doc/lispref/os.texi                 |   27 +-
 doc/lispref/processes.texi          |   23 +-
 doc/lispref/sequences.texi          |   20 +-
 doc/lispref/windows.texi            | 1479 +++++++++++++++++++++++++++--------
 doc/man/emacsclient.1               |    1 +
 doc/misc/calc.texi                  |    2 +-
 doc/misc/dired-x.texi               |    4 +-
 doc/misc/efaq.texi                  |   10 +-
 doc/misc/gnus.texi                  |    2 +-
 doc/misc/tramp.texi                 |   34 +-
 etc/NEWS                            |   89 ++-
 etc/NEWS.18                         |    2 +-
 etc/NEWS.26                         |   45 ++
 etc/PROBLEMS                        |   19 +
 lib-src/emacsclient.c               |    3 +
 lib/cdefs.h                         |  514 ++++++++++++
 lib/gnulib.mk.in                    |   12 +
 lib/libc-config.h                   |  174 +++++
 lib/regcomp.c                       |  305 ++++----
 lib/regex.c                         |    2 +-
 lib/regex_internal.c                |  152 ++--
 lib/regex_internal.h                |   20 +-
 lib/regexec.c                       |  363 ++++-----
 lisp/autorevert.el                  |   58 +-
 lisp/cedet/semantic/symref/grep.el  |   10 +-
 lisp/char-fold.el                   |    2 +-
 lisp/cus-edit.el                    |    2 +-
 lisp/cus-start.el                   |    2 +-
 lisp/dired-aux.el                   |   23 +-
 lisp/dired.el                       |    8 +-
 lisp/doc-view.el                    |   43 +-
 lisp/emacs-lisp/autoload.el         |    2 +-
 lisp/emacs-lisp/checkdoc.el         |    5 +-
 lisp/emacs-lisp/cl-generic.el       |    3 +
 lisp/emacs-lisp/derived.el          |    8 +-
 lisp/emacs-lisp/easy-mmode.el       |   62 +-
 lisp/emacs-lisp/easymenu.el         |   28 +-
 lisp/emacs-lisp/edebug.el           |   10 +-
 lisp/emacs-lisp/eieio-core.el       |    6 +-
 lisp/emacs-lisp/lisp-mode.el        |    4 +
 lisp/emacs-lisp/lisp.el             |   12 +-
 lisp/emacs-lisp/package.el          |   63 +-
 lisp/emacs-lisp/pcase.el            |   40 +-
 lisp/emacs-lisp/rx.el               |    2 +-
 lisp/emacs-lisp/smie.el             |    4 +-
 lisp/emacs-lisp/syntax.el           |    4 +-
 lisp/emacs-lisp/timer.el            |   12 +-
 lisp/epg.el                         |    7 +-
 lisp/eshell/em-rebind.el            |    2 +-
 lisp/faces.el                       |   22 +-
 lisp/filenotify.el                  |   13 +-
 lisp/files.el                       |   63 +-
 lisp/filesets.el                    |    2 +-
 lisp/follow.el                      |   45 +-
 lisp/fringe.el                      |   20 +-
 lisp/gnus/gnus-art.el               |    4 +-
 lisp/gnus/gnus-spec.el              |    4 +-
 lisp/gnus/gnus-sum.el               |   15 +-
 lisp/gnus/mm-util.el                |    2 +-
 lisp/gnus/nnir.el                   |   58 +-
 lisp/help-fns.el                    |    2 +-
 lisp/help.el                        |    2 +-
 lisp/image-mode.el                  |   24 +-
 lisp/isearch.el                     |  198 +++--
 lisp/ldefs-boot.el                  |   81 +-
 lisp/mail/rmailsum.el               |    2 +-
 lisp/mail/smtpmail.el               |   57 +-
 lisp/mouse.el                       |   97 ++-
 lisp/net/rcirc.el                   |   38 +-
 lisp/net/sieve-mode.el              |   31 +-
 lisp/net/sieve.el                   |    9 +-
 lisp/net/soap-client.el             |   10 +-
 lisp/net/tramp-compat.el            |    8 +
 lisp/net/tramp-sh.el                |    3 +-
 lisp/net/tramp.el                   |  108 ++-
 lisp/progmodes/cc-cmds.el           |    2 +
 lisp/progmodes/cc-defs.el           |   31 +-
 lisp/progmodes/cc-engine.el         |   19 +-
 lisp/progmodes/cc-fonts.el          |    3 +
 lisp/progmodes/cc-langs.el          |    1 +
 lisp/progmodes/cc-mode.el           |   28 +-
 lisp/progmodes/cperl-mode.el        |    2 +-
 lisp/progmodes/flymake.el           |   54 +-
 lisp/progmodes/gdb-mi.el            |   16 +-
 lisp/progmodes/modula2.el           |   22 +-
 lisp/progmodes/octave.el            |   61 +-
 lisp/progmodes/opascal.el           |   14 +-
 lisp/progmodes/perl-mode.el         |    4 +-
 lisp/progmodes/prolog.el            |   14 +-
 lisp/progmodes/ruby-mode.el         |   75 +-
 lisp/progmodes/sh-script.el         |   18 +-
 lisp/progmodes/xref.el              |    5 +-
 lisp/rect.el                        |   39 +
 lisp/registry.el                    |    2 +-
 lisp/server.el                      |   32 +-
 lisp/simple.el                      |   31 +-
 lisp/subr.el                        |    2 +-
 lisp/textmodes/css-mode.el          |    2 +-
 lisp/textmodes/tex-mode.el          |   22 +-
 lisp/vc/diff-mode.el                |  119 ++-
 lisp/vc/vc-hg.el                    |    4 +-
 lisp/windmove.el                    |    7 +-
 lisp/window.el                      |  112 ++-
 m4/__inline.m4                      |   22 +
 m4/environ.m4                       |   20 +-
 m4/fsusage.m4                       |  352 +++++----
 m4/gnulib-comp.m4                   |   16 +
 m4/manywarnings.m4                  |   79 +-
 m4/socklen.m4                       |   15 +-
 nextstep/templates/Info.plist.in    |    2 +
 src/alloc.c                         |    2 +
 src/buffer.c                        |   22 +-
 src/bytecode.c                      |    1 +
 src/callproc.c                      |   21 +-
 src/conf_post.h                     |    8 +-
 src/data.c                          |    4 +-
 src/dispnew.c                       |    7 +-
 src/eval.c                          |    3 +
 src/fringe.c                        |    8 +
 src/gtkutil.c                       |    3 +-
 src/image.c                         |    2 +-
 src/json.c                          |  102 ++-
 src/keyboard.c                      |    5 +-
 src/lisp.h                          |   39 +-
 src/lread.c                         |    3 +-
 src/minibuf.c                       |   13 +-
 src/nsterm.m                        |   79 +-
 src/thread.c                        |   51 +-
 src/timefns.c                       |  102 ++-
 src/window.c                        |    4 +
 src/xdisp.c                         |   73 +-
 src/xfaces.c                        |   10 +-
 src/xmenu.c                         |    2 +-
 test/lisp/emacs-lisp/pcase-tests.el |    2 +-
 test/lisp/emacs-lisp/timer-tests.el |   20 +
 test/lisp/net/tramp-tests.el        |  131 +++-
 test/src/buffer-tests.el            |   15 +
 test/src/eval-tests.el              |   30 +
 test/src/json-tests.el              |    9 +-
 test/src/thread-tests.el            |    4 +
 163 files changed, 5895 insertions(+), 2549 deletions(-)

diff --git a/.gitignore b/.gitignore
index 26fe4bb..8ab4e8d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -264,6 +264,7 @@ etc/emacs.tmpdesktop
 *.in-h
 _*
 !lib/_Noreturn.h
+!m4/_*.m4
 /bin/
 /BIN/
 /data/
diff --git a/admin/MAINTAINERS b/admin/MAINTAINERS
index 6db1d88..05faa58 100644
--- a/admin/MAINTAINERS
+++ b/admin/MAINTAINERS
@@ -210,8 +210,8 @@ Paul Eggert
 Michael Albinus
        src/inotify.c
         lisp/autorevert.el
-        lisp/files.el (file-name-non-special)
        lisp/eshell/em-tramp.el
+        lisp/files.el (file-name-non-special)
        lisp/net/ange-ftp.el
        lisp/notifications.el
        lisp/shadowfile.el
diff --git a/admin/automerge b/admin/automerge
index e88711f..8bf9817 100755
--- a/admin/automerge
+++ b/admin/automerge
@@ -174,6 +174,12 @@ merge ()
 merge
 
 
+## FIXME it would be better to trap this in gitmerge.
+## NEWS should never be modified, only eg NEWS.26.
+git diff --stat --cached origin/master | grep -q "etc/NEWS " && \
+    die "etc/NEWS has been modified"
+
+
 [ "$build" ] || exit 0
 
 
diff --git a/admin/bzrmerge.el b/admin/bzrmerge.el
deleted file mode 100644
index cedb625..0000000
--- a/admin/bzrmerge.el
+++ /dev/null
@@ -1,359 +0,0 @@
-;;; bzrmerge.el --- help merge one Emacs bzr branch to another
-
-;; Copyright (C) 2010-2018 Free Software Foundation, Inc.
-
-;; Author: Stefan Monnier <address@hidden>
-;; Keywords: maint
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Some usage notes are in admin/notes/bzr.
-
-;;; Code:
-
-(eval-when-compile (require 'cl-lib))
-
-(defvar bzrmerge-skip-regexp
-  "back[- ]?port\\|merge\\|sync\\|re-?generate\\|bump version\\|from trunk\\|\
-Auto-commit"
-  "Regexp matching logs of revisions that might be skipped.
-`bzrmerge-missing' will ask you if it should skip any matches.")
-
-(defconst bzrmerge-buffer "*bzrmerge*"
-  "Working buffer for bzrmerge.")
-
-(defconst bzrmerge-warning-buffer "*bzrmerge warnings*"
-  "Buffer where bzrmerge will display any warnings.")
-
-(defun bzrmerge-merges ()
-  "Return the list of already merged (not yet committed) revisions.
-The list returned is sorted by oldest-first."
-  (with-current-buffer (get-buffer-create bzrmerge-buffer)
-    (erase-buffer)
-    ;; We generally want to make sure we start with a clean tree, but we also
-    ;; want to allow restarts (i.e. with some part of FROM already merged but
-    ;; not yet committed).  Unversioned (unknown) files in the tree
-    ;; are also ok.
-    (call-process "bzr" nil t nil "status" "-v")
-    (goto-char (point-min))
-    (when (re-search-forward "^conflicts:\n" nil t)
-      (user-error "You still have unresolved conflicts"))
-    (let ((merges ())
-          found)
-      (if (not (re-search-forward "^pending merges:\n" nil t))
-          (when (save-excursion
-                  (goto-char (point-min))
-                  (while (and
-                          (re-search-forward "^\\([a-z ]*\\):\n" nil t)
-                          (not
-                           (setq found
-                                 (not (equal "unknown" (match-string 1)))))))
-                  found)
-            (user-error "You still have uncommitted changes"))
-        ;; This is really stupid, but it seems there's no easy way to figure
-        ;; out which revisions have been merged already.  The only info I can
-        ;; find is the "pending merges" from "bzr status -v", which is not
-        ;; very machine-friendly.
-        (while (not (eobp))
-          (skip-chars-forward " ")
-          (push (buffer-substring (point) (line-end-position)) merges)
-          (forward-line 1)))
-      merges)))
-
-(defun bzrmerge-check-match (merge)
-  ;; Make sure the MERGES match the revisions on the FROM branch.
-  ;; Stupidly the best form of MERGES I can find is the one from
-  ;; "bzr status -v" which is very machine non-friendly, so I have
-  ;; to do some fuzzy matching.
-  (let ((author
-         (or
-          (save-excursion
-            (if (re-search-forward "^author: *\\([^<]*[^ ]\\) +<.*"
-                                   nil t)
-                (match-string 1)))
-          (save-excursion
-            (if (re-search-forward
-                 "^committer: *\\([^<]*[^< ]\\) +<" nil t)
-                (match-string 1)))))
-        (timestamp
-         (save-excursion
-           (if (re-search-forward
-                "^timestamp:[^0-9]*\\([-0-9]+\\)" nil t)
-               (match-string 1))))
-        (line1
-         (save-excursion
-           (if (re-search-forward "^message:[ \n]*" nil t)
-               (buffer-substring (point) (line-end-position))))))
-    ;; The `merge' may have a truncated line1 with "...", so get
-    ;; rid of any "..." and then look for a prefix match.
-    (when (string-match "\\.+\\'" merge)
-      (setq merge (substring merge 0 (match-beginning 0))))
-    (or (string-prefix-p
-         merge (concat author " " timestamp " " line1))
-        (string-prefix-p
-         merge (concat author " " timestamp " [merge] " line1)))))
-
-(defun bzrmerge-missing (from merges)
-  "Return the list of revisions that need to be merged.
-MERGES is the revisions already merged but not yet committed.
-Asks about skipping revisions with logs matching `bzrmerge-skip-regexp'.
-The result is of the form (TOMERGE . TOSKIP) where TOMERGE and TOSKIP
-are both lists of revnos, in oldest-first order."
-  (with-current-buffer (get-buffer-create bzrmerge-buffer)
-    (erase-buffer)
-    (call-process "bzr" nil t nil "missing" "--theirs-only"
-                  (expand-file-name from))
-    (let ((revnos ()) (skipped ()))
-      (pop-to-buffer (current-buffer))
-      (goto-char (point-max))
-      (while (re-search-backward 
"^------------------------------------------------------------\nrevno: 
\\([0-9.]+\\).*" nil t)
-        (save-excursion
-          (if merges
-              (while (not (bzrmerge-check-match (pop merges)))
-                (unless merges
-                  (error "Unmatched tip of merged revisions")))
-            (let ((case-fold-search t)
-                  (revno (match-string 1))
-                  (skip nil))
-              (if (string-match "\\." revno)
-                  (error "Unexpected dotted revno!")
-                (setq revno (string-to-number revno)))
-              (re-search-forward "^message:\n")
-              (while (and (not skip)
-                          (re-search-forward bzrmerge-skip-regexp nil t))
-                (let ((str (buffer-substring (line-beginning-position)
-                                             (line-end-position))))
-                  (when (string-match "\\` *" str)
-                    (setq str (substring str (match-end 0))))
-                  (when (string-match "[.!;, ]+\\'" str)
-                    (setq str (substring str 0 (match-beginning 0))))
-                  (let ((help-form (substitute-command-keys "\
-Type `y' to skip this revision,
-`N' to include it and go on to the next revision,
-`n' to not skip, but continue to search this log entry for skip regexps,
-`q' to quit merging.")))
-                    (pcase (save-excursion
-                            (read-char-choice
-                             (format "%s: Skip (y/n/N/q/%s)? " str
-                                     (key-description (vector help-char)))
-                             '(?y ?n ?N ?q)))
-                      (`?y (setq skip t))
-                      (`?q (keyboard-quit))
-                      ;; A single log entry can match skip-regexp multiple
-                      ;; times.  If you are sure you don't want to skip it,
-                      ;; you don't want to be asked multiple times.
-                      (`?N (setq skip 'no))))))
-              (if (eq skip t)
-                  (push revno skipped)
-                (push revno revnos)))))
-        (delete-region (point) (point-max)))
-      (and (or revnos skipped)
-           (cons (nreverse revnos) (nreverse skipped))))))
-
-(defun bzrmerge-resolve (file)
-  (unless (file-exists-p file) (error "Bzrmerge-resolve: Can't find %s" file))
-  (with-demoted-errors
-    (let ((exists (find-buffer-visiting file)))
-      (with-current-buffer (let ((enable-local-variables :safe)
-                                 (enable-local-eval nil))
-                             (find-file-noselect file))
-        (if (buffer-modified-p)
-            (user-error "Unsaved changes in %s" (current-buffer)))
-        (save-excursion
-          (cond
-           ((derived-mode-p 'change-log-mode)
-            ;; Fix up dates before resolving the conflicts.
-            (goto-char (point-min))
-            (let ((diff-auto-refine-mode nil))
-              (while (re-search-forward smerge-begin-re nil t)
-                (smerge-match-conflict)
-                (smerge-ensure-match 3)
-                (let ((start1 (match-beginning 1))
-                      (end1 (match-end 1))
-                      (start3 (match-beginning 3))
-                      (end3 (copy-marker (match-end 3) t)))
-                  (goto-char start3)
-                  (while (re-search-forward change-log-start-entry-re end3 t)
-                    (let* ((str (match-string 0))
-                           (newstr (save-match-data
-                                     (concat (add-log-iso8601-time-string)
-                                             (when (string-match " *\\'" str)
-                                               (match-string 0 str))))))
-                      (replace-match newstr t t)))
-                  ;; change-log-resolve-conflict prefers to put match-1's
-                  ;; elements first (for equal dates), whereas we want to put
-                  ;; match-3's first.
-                  (let ((match3 (buffer-substring start3 end3))
-                        (match1 (buffer-substring start1 end1)))
-                    (delete-region start3 end3)
-                    (goto-char start3)
-                    (insert match1)
-                    (delete-region start1 end1)
-                    (goto-char start1)
-                    (insert match3)))))
-            ;; (pop-to-buffer (current-buffer)) (debug 'before-resolve)
-            ))
-          ;; Try to resolve the conflicts.
-          (cond
-           ((member file '("configure" "lisp/ldefs-boot.el"
-                           "lisp/emacs-lisp/cl-loaddefs.el"))
-            ;; We are in the file's buffer, so names are relative.
-            (call-process "bzr" nil t nil "revert"
-                          (file-name-nondirectory file))
-            (revert-buffer nil 'noconfirm))
-           (t
-            (goto-char (point-max))
-            (while (re-search-backward smerge-begin-re nil t)
-              (save-excursion
-                (ignore-errors
-                  (smerge-match-conflict)
-                  (smerge-resolve))))
-            ;; (when (derived-mode-p 'change-log-mode)
-            ;;   (pop-to-buffer (current-buffer)) (debug 'after-resolve))
-            (save-buffer)))
-          (goto-char (point-min))
-          (prog1 (re-search-forward smerge-begin-re nil t)
-            (unless exists (kill-buffer))))))))
-
-(defun bzrmerge-add-metadata (from endrevno)
-  "Add the metadata for a merge of FROM upto ENDREVNO.
-Does not make other difference."
-  (if (with-temp-buffer
-        (call-process "bzr" nil t nil "status")
-        (goto-char (point-min))
-        (re-search-forward "^conflicts:\n" nil t))
-      (error "Don't know how to add metadata in the presence of conflicts")
-    (call-process "bzr" nil t nil "shelve" "--all"
-                  "-m" "Bzrmerge shelved merge during skipping")
-    (call-process "bzr" nil t nil "revert")
-    (call-process "bzr" nil t nil
-                  "merge" "-r" (format "%s" endrevno) from)
-    (call-process "bzr" nil t nil "revert" ".")
-    (call-process "bzr" nil t nil "unshelve")))
-
-(defvar bzrmerge-already-done nil)
-
-(defun bzrmerge-apply (missing from)
-  (setq from (expand-file-name from))
-  (with-current-buffer (get-buffer-create bzrmerge-buffer)
-    (erase-buffer)
-    (when (equal (cdr bzrmerge-already-done) (list from missing))
-      (setq missing (car bzrmerge-already-done)))
-    (setq bzrmerge-already-done nil)
-    (let ((merge (car missing))
-          (skip (cdr missing))
-          (unsafe nil)
-          beg end)
-      (when (or merge skip)
-        (cond
-         ((and skip (or (null merge) (< (car skip) (car merge))))
-          ;; Do a "skip" (i.e. merge the meta-data only).
-          (setq beg (1- (car skip)))
-          (while (and skip (or (null merge) (< (car skip) (car merge))))
-            (cl-assert (> (car skip) (or end beg)))
-            (setq end (pop skip)))
-          (message "Skipping %s..%s" beg end)
-          (bzrmerge-add-metadata from end))
-
-         (t
-          ;; Do a "normal" merge.
-          (cl-assert (or (null skip) (< (car merge) (car skip))))
-          (setq beg (1- (car merge)))
-          (while (and merge (or (null skip) (< (car merge) (car skip))))
-            (cl-assert (> (car merge) (or end beg)))
-            (setq end (pop merge)))
-          (message "Merging %s..%s" beg end)
-          (if (with-temp-buffer
-                (call-process "bzr" nil t nil "status")
-                (zerop (buffer-size)))
-              (call-process "bzr" nil t nil
-                            "merge" "-r" (format "%s" end) from)
-            ;; Stupidly, "bzr merge --force -r A..B" dos not maintain the
-            ;; metadata properly except when the checkout is clean.
-            (call-process "bzr" nil t nil "merge"
-                          "--force" "-r" (format "%s..%s" beg end) from)
-            ;; The merge did not update the metadata, so force the next time
-            ;; around to update it (as a "skip").
-            (setq unsafe t)
-            (push end skip))
-          (pop-to-buffer (current-buffer))
-          (sit-for 1)
-          ;; (debug 'after-merge)
-          ;; Check the conflicts.
-          ;; FIXME if using the helpful bzr changelog_merge plugin,
-          ;; there are normally no conflicts in ChangeLogs.
-          ;; But we still want the dates fixing, like bzrmerge-resolve does.
-          (let ((conflicted nil)
-                (files ()))
-            (goto-char (point-min))
-            (when (re-search-forward "bzr: ERROR:" nil t)
-              (error "Internal Bazaar error!!"))
-            (while (re-search-forward "^Text conflict in " nil t)
-              (push (buffer-substring (point) (line-end-position)) files))
-            (if (re-search-forward "^\\([0-9]+\\) conflicts encountered" nil t)
-                (if (/= (length files) (string-to-number (match-string 1)))
-                    (setq conflicted t))
-              (if files (setq conflicted t)))
-            (dolist (file files)
-              (if (bzrmerge-resolve file)
-                  (setq conflicted t)))
-            (when conflicted
-              (setq bzrmerge-already-done
-                    (list (cons merge skip) from missing))
-              (if unsafe
-                  ;; FIXME: Obviously, we'd rather make it right rather
-                  ;; than output such a warning.  But I don't know how to add
-                  ;; the metadata to bzr's since the technique used in
-                  ;; bzrmerge-add-metadata does not work when there
-                  ;; are conflicts.
-                  (display-warning 'bzrmerge "Resolve conflicts manually.
-BEWARE!  Important metadata is kept in this Emacs session!
-Do not commit without re-running `M-x bzrmerge' first!"
-                                   :warning bzrmerge-warning-buffer))
-              (user-error "Resolve conflicts manually")))))
-        (cons merge skip)))))
-
-(defun bzrmerge (from)
-  "Merge from branch FROM into `default-directory'."
-  (interactive
-   (list
-    (let ((def
-           (with-temp-buffer
-             (call-process "bzr" nil t nil "info")
-             (goto-char (point-min))
-             (when (re-search-forward "submit branch: *" nil t)
-               (buffer-substring (point) (line-end-position))))))
-      (read-file-name "From branch: " nil nil nil def))))
-  ;; Eg we ran bzrmerge once, it stopped with conflicts, we fixed them
-  ;; and are running it again.
-  (if (get-buffer bzrmerge-warning-buffer)
-      (kill-buffer bzrmerge-warning-buffer))
-  (message "Merging from %s..." from)
-  (require 'vc-bzr)
-  (let ((default-directory (or (vc-bzr-root default-directory)
-                               (error "Not in a Bzr tree"))))
-    ;; First, check the status.
-    (let* ((merges (bzrmerge-merges))
-           ;; OK, we have the status, now check the missing data.
-           (missing (bzrmerge-missing from merges)))
-      (if (not missing)
-          (message "Merging from %s...nothing to merge" from)
-        (while missing
-          (setq missing (bzrmerge-apply missing from)))
-        (message "Merging from %s...done" from)))))
-
-(provide 'bzrmerge)
-;;; bzrmerge.el ends here
diff --git a/admin/gitmerge.el b/admin/gitmerge.el
index a123e03..6dedee8 100644
--- a/admin/gitmerge.el
+++ b/admin/gitmerge.el
@@ -275,6 +275,9 @@ should not be skipped."
        (setq found (cdr skip))))
     found))
 
+(defvar change-log-start-entry-re) ; in add-log, which defines change-log-mode
+(declare-function add-log-iso8601-time-string "add-log" ())
+
 (defun gitmerge-resolve (file)
   "Try to resolve conflicts in FILE with smerge.
 Returns non-nil if conflicts remain."
@@ -323,6 +326,9 @@ Returns non-nil if conflicts remain."
           ;; Try to resolve the conflicts.
           (let (temp)
             (cond
+             ;; FIXME when merging release branch to master, we still
+             ;; need to detect and handle the case where NEWS was modified
+             ;; without a conflict.  We should abort if NEWS gets changed.
              ((and (equal file "etc/NEWS")
                    (ignore-errors
                      (setq temp
@@ -332,18 +338,21 @@ Returns non-nil if conflicts remain."
                    (or noninteractive
                        (y-or-n-p "Try to fix NEWS conflict? ")))
               (let ((relfile (file-name-nondirectory file))
-                    (tempfile (make-temp-file "gitmerge")))
-                (unwind-protect
+                    (patchfile (concat temp "-gitmerge.patch")))
+                (call-process "git" nil `(:file ,patchfile) nil "diff"
+                              (format ":1:%s" file)
+                              (format ":3:%s" file))
+                (if (eq 0 (call-process "patch" patchfile nil nil temp))
                     (progn
-                      (call-process "git" nil `(:file ,tempfile) nil "diff"
-                                    (format ":1:%s" file)
-                                    (format ":3:%s" file))
+                      ;; We intentionally use a non-temporary name for this
+                      ;; file, and only delete it if applied successfully.
+                      (delete-file patchfile)
+                      (call-process "git" nil t nil "add" "--" temp)
                       (call-process "git" nil t nil "reset" "--" relfile)
                       (call-process "git" nil t nil "checkout" "--" relfile)
-                      (revert-buffer nil 'noconfirm)
-                      (call-process "patch" tempfile nil nil temp)
-                      (call-process "git" nil t nil "add" "--" temp))
-                  (delete-file tempfile))))
+                      (revert-buffer nil 'noconfirm))
+                  ;; The conflict markers remain so we return non-nil.
+                  (message "Failed to fix NEWS conflict"))))
              ;; Generated files.
              ((member file '("lisp/ldefs-boot.el"))
               ;; We are in the file's buffer, so names are relative.
diff --git a/configure.ac b/configure.ac
index df91028..4a80eb4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -361,7 +361,7 @@ OPTION_DEFAULT_ON([xft],[don't use XFT for anti aliased 
fonts])
 OPTION_DEFAULT_ON([libotf],[don't use libotf for OpenType font support])
 OPTION_DEFAULT_ON([m17n-flt],[don't use m17n-flt for text shaping])
 
-OPTION_DEFAULT_ON([toolkit-scroll-bars],[don't use Motif or Xaw3d scroll bars])
+OPTION_DEFAULT_ON([toolkit-scroll-bars],[don't use Motif/Xaw3d/GTK toolkit 
scroll bars])
 OPTION_DEFAULT_ON([xaw3d],[don't use Xaw3d])
 OPTION_DEFAULT_ON([xim],[at runtime, default X11 XIM to off])
 AC_ARG_WITH([ns],[AS_HELP_STRING([--with-ns],
@@ -1336,6 +1336,37 @@ else
     ac_link="$ac_link $NON_GCC_LINK_TEST_OPTIONS"
 fi
 
+dnl On some platforms using GNU ld, linking temacs needs -znocombreloc.
+dnl Although this has something to do with dumping, the details are unknown.
+dnl If the flag is used but not needed,
+dnl Emacs should still work (albeit a bit more slowly),
+dnl so use the flag everywhere that it is supported.
+dnl When testing whether the flag works, treat GCC specially
+dnl since it just gives a non-fatal 'unrecognized option'
+dnl if not built to support GNU ld.
+if test "$GCC" = yes; then
+  LDFLAGS_NOCOMBRELOC="-Wl,-znocombreloc"
+else
+  LDFLAGS_NOCOMBRELOC="-znocombreloc"
+fi
+
+AC_CACHE_CHECK([for -znocombreloc], [emacs_cv_znocombreloc],
+  [if test "$CANNOT_DUMP" = "yes"; then
+     emacs_cv_znocombreloc='not needed'
+   else
+     save_LDFLAGS=$LDFLAGS
+     LDFLAGS="$LDFLAGS $LDFLAGS_NOCOMBRELOC"
+     AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],
+       [emacs_cv_znocombreloc=yes], [emacs_cv_znocombreloc=no])
+     LDFLAGS=$save_LDFLAGS
+   fi])
+
+case $emacs_cv_znocombreloc in
+  no*)
+    LDFLAGS_NOCOMBRELOC= ;;
+esac
+
+
 AC_CACHE_CHECK([whether addresses are sanitized],
   [emacs_cv_sanitize_address],
   [AC_COMPILE_IFELSE(
@@ -5176,6 +5207,22 @@ else
 fi
 AC_SUBST(LIBXMENU)
 
+AC_CACHE_CHECK([for struct alignment],
+  [emacs_cv_struct_alignment],
+  [AC_COMPILE_IFELSE(
+     [AC_LANG_PROGRAM([[#include <stddef.h>
+                       struct s { char c; } __attribute__ ((aligned (8)));
+                       struct t { char c; struct s s; };
+                       char verify[offsetof (struct t, s) == 8 ? 1 : -1];
+                     ]])],
+     [emacs_cv_struct_alignment=yes],
+     [emacs_cv_struct_alignment=no])])
+if test "$emacs_cv_struct_alignment" = yes; then
+  AC_DEFINE([HAVE_STRUCT_ATTRIBUTE_ALIGNED], 1,
+    [Define to 1 if 'struct __attribute__ ((aligned (N)))' aligns the
+     structure to an N-byte boundary.])
+fi
+
 if test "${GNU_MALLOC}" = "yes" ; then
   AC_DEFINE(GNU_MALLOC, 1,
            [Define to 1 if you want to use the GNU memory allocator.])
@@ -5346,6 +5393,8 @@ if test x$ac_enable_profiling != x ; then
   esac
 fi
 
+LD_SWITCH_SYSTEM_TEMACS="$LDFLAGS_NOCOMBRELOC $LD_SWITCH_SYSTEM_TEMACS"
+
 AC_SUBST(LD_SWITCH_SYSTEM_TEMACS)
 
 ## Common for all window systems
@@ -5449,6 +5498,15 @@ for opt in XAW3D XPM JPEG TIFF GIF PNG RSVG CAIRO 
IMAGEMAGICK SOUND GPM DBUS \
           *) continue ;;
         esac
       ;;
+      NOTIFY)
+        case $val in
+          *lkqueue*) opt="$opt LIBKQUEUE" ;;
+          *kqueue*) opt="$opt KQUEUE" ;;
+          *inotify*) opt="$opt INOTIFY" ;;
+          *gfile*) opt="$opt GFILENOTIFY" ;;
+          *w32*) opt="$opt W32NOTIFY" ;;
+        esac
+      ;;
     esac
     AS_VAR_APPEND([emacs_config_features], ["$optsep$opt"])
     optsep=' '
diff --git a/doc/emacs/cmdargs.texi b/doc/emacs/cmdargs.texi
index 733919a..2e2767c 100644
--- a/doc/emacs/cmdargs.texi
+++ b/doc/emacs/cmdargs.texi
@@ -305,6 +305,8 @@ not disable loading @file{site-start.el}.
 
 @item --no-site-file
 @opindex --no-site-file
address@hidden -nsl
address@hidden -nsl
 @cindex @file{site-start.el} file, not loading
 Do not load @file{site-start.el} (@pxref{Init File}).  The @samp{-Q}
 option does this too, but other options like @samp{-q} do not.
@@ -323,14 +325,20 @@ Do not display a startup screen.  You can also achieve 
this effect by
 setting the variable @code{inhibit-startup-screen} to address@hidden
 in your initialization file (@pxref{Entering Emacs}).
 
address@hidden --no-x-resources
address@hidden --no-x-resources
address@hidden X resources, not loading
+Do not load X resources.  You can also achieve this effect by setting
+the variable @code{inhibit-x-resources} to @code{t} in your
+initialization file (@pxref{Resources}).
+
 @item -Q
 @opindex -Q
 @itemx --quick
 @opindex --quick
-Start Emacs with minimum customizations.  This is similar to using @samp{-q},
address@hidden, @samp{--no-site-lisp}, and @samp{--no-splash}
-together.  This also stops Emacs from processing X resources by
-setting @code{inhibit-x-resources} to @code{t} (@pxref{Resources}).
+Start Emacs with minimum customizations.  This is similar to using
address@hidden, @samp{--no-site-file}, @samp{--no-site-lisp},
address@hidden, and @samp{--no-splash} together..
 
 @item -daemon
 @opindex -daemon
@@ -373,6 +381,8 @@ Enable expensive correctness checks when dealing with 
dynamically
 loadable modules.  This is intended for module authors that wish to
 verify that their module conforms to the module API requirements.  The
 option makes Emacs abort if a module-related assertion triggers.
address@hidden Dynamic Modules,, Writing Dynamically-Loaded Modules,
+elisp, The GNU Emacs Lisp Reference Manual}.
 @end table
 
 @node Command Example
diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi
index 4d5605e..fd4938d1 100644
--- a/doc/emacs/files.texi
+++ b/doc/emacs/files.texi
@@ -962,10 +962,11 @@ way that, if the file was edited only slightly, you will 
be at
 approximately the same part of the text as before.  But if you have
 made major changes, point may end up in a totally different location.
 
-  Reverting marks the buffer as not modified.  It also clears the
-buffer's undo history (@pxref{Undo}).  Thus, the reversion cannot be
-undone---if you change your mind yet again, you can't use the undo
-commands to bring the reverted changes back.
+  Reverting marks the buffer as not modified.  However, it adds the
+reverted changes as a single modification to the buffer's undo history
+(@pxref{Undo}).  Thus, after reverting, you can type @kbd{C-/} or its
+aliases to bring the reverted changes back, if you happen to change
+your mind.
 
   Some kinds of buffers that are not associated with files, such as
 Dired buffers, can also be reverted.  For them, reverting means
diff --git a/doc/emacs/frames.texi b/doc/emacs/frames.texi
index 9f4c782..6bbaae2 100644
--- a/doc/emacs/frames.texi
+++ b/doc/emacs/frames.texi
@@ -934,6 +934,10 @@ the initial frame, by customizing the variable
 specify colors and fonts don't affect menus and the menu bar, since
 those are drawn by the toolkit and not directly by Emacs.
 
+  Frame appearance and behavior can also be customized through X
+resources (@pxref{X Resources}); these override the parameters of the
+initial frame specified in your init file.
+
   Note that if you are using the desktop library to save and restore
 your sessions, the frames to be restored are recorded in the desktop
 file, together with their parameters.  When these frames are restored,
diff --git a/doc/emacs/mark.texi b/doc/emacs/mark.texi
index 1050587..626f9dd 100644
--- a/doc/emacs/mark.texi
+++ b/doc/emacs/mark.texi
@@ -444,12 +444,13 @@ from point to the end of the buffer.  Commands that act 
this way are
 identified in their own documentation.
 @end itemize
 
address@hidden enabling Transient Mark mode temporarily
   While Transient Mark mode is off, you can activate it temporarily
 using @address@hidden address@hidden or @kbd{C-u C-x C-x}.
 
 @table @kbd
 @item address@hidden address@hidden
address@hidden C-SPC address@hidden, disabling Transient Mark}
address@hidden C-SPC address@hidden, enabling Transient Mark mode temporarily}
 Set the mark at point (like plain @address@hidden) and enable
 Transient Mark mode just once, until the mark is deactivated.  (This
 is not really a separate command; you are using the @address@hidden
diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi
index 236cb07..ab33caf 100644
--- a/doc/emacs/misc.texi
+++ b/doc/emacs/misc.texi
@@ -1966,6 +1966,10 @@ is given by the variable @code{server-name} on the Emacs 
server.  If
 this option is omitted, @command{emacsclient} connects to the first
 server it finds.  (This option is not supported on MS-Windows.)
 
+Alternatively, you can set the @env{EMACS_SOCKET_NAME} environment
+variable to point to the server socket.  (The command-line option
+overrides the environment variable.)
+
 @item -t
 @itemx --tty
 @itemx -nw
diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
index 263c4c5..801e8bb 100644
--- a/doc/emacs/search.texi
+++ b/doc/emacs/search.texi
@@ -99,31 +99,45 @@ text that matches the search string---using the 
@code{isearch} face
 that customize this highlighting.  The current search string is also
 displayed in the echo area.
 
-  If you make a mistake typing the search string, type @key{DEL}.
-Each @key{DEL} cancels the last character of the search string.
address@hidden in Isearch}, for more about dealing with unsuccessful
-search.
address@hidden isearch input item
address@hidden input item, isearch
address@hidden isearch-delete-char
address@hidden DEL @r{(Incremental search)}
+  If you make a mistake typing the search string, type @key{DEL}
+(@code{isearch-delete-char}).  Each @key{DEL} cancels the last input
+item entered during the search.  Emacs records a new @dfn{input item}
+whenever you type a command that changes the search string, the
+position of point, the success or failure of the search, the direction
+of the search, the position of the other end of the current search
+result, or the ``wrappedness'' of the search.  @xref{Error in
+Isearch}, for more about dealing with unsuccessful search.
 
 @cindex exit incremental search
 @cindex incremental search, exiting
address@hidden isearch-exit
address@hidden RET @r{(Incremental search)}
   When you are satisfied with the place you have reached, type
address@hidden  This stops searching, leaving the cursor where the search
-brought it.  Also, any command not specially meaningful in searches
-stops the searching and is then executed.  Thus, typing @kbd{C-a}
-exits the search and then moves to the beginning of the line; typing
-one of the arrow keys exits the search and performs the respective
-movement command; etc.  @key{RET} is necessary only if the next
-command you want to type is a printing character, @key{DEL},
address@hidden, or another character that is special within searches
-(@kbd{C-q}, @kbd{C-w}, @kbd{C-r}, @kbd{C-s}, @kbd{C-y}, @kbd{M-y},
address@hidden, @kbd{M-c}, @kbd{M-e}, and some others described below).
-You can fine-tune the commands that exit the search; see @ref{Not
-Exiting Isearch}.
address@hidden (@code{isearch-exit}).  This stops searching, leaving the
+cursor where the search brought it.  Also, any command not specially
+meaningful in searches stops the searching and is then executed.
+Thus, typing @kbd{C-a} exits the search and then moves to the
+beginning of the line; typing one of the arrow keys exits the search
+and performs the respective movement command; etc.  @key{RET} is
+necessary only if the next command you want to type is a printing
+character, @key{DEL}, @key{RET}, or another character that is special
+within searches (@kbd{C-q}, @kbd{C-w}, @kbd{C-r}, @kbd{C-s},
address@hidden, @kbd{M-y}, @kbd{M-r}, @kbd{M-c}, @kbd{M-e}, and some others
+described below).  You can fine-tune the commands that exit the
+search; see @ref{Not Exiting Isearch}.
 
   As a special exception, entering @key{RET} when the search string is
 empty launches nonincremental search (@pxref{Nonincremental Search}).
 (This can be customized; see @ref{Search Customizations}.)
 
address@hidden isearch-abort
address@hidden isearch-cancel
address@hidden C-g C-g @r{(Incremental Search)}
address@hidden ESC ESC ESC @r{(Incremental Search)}
   To abandon the search and return to the place where you started,
 type @address@hidden @key{ESC} @key{ESC}} (@code{isearch-cancel}) or
 @kbd{C-g C-g} (@code{isearch-abort}).
@@ -146,13 +160,18 @@ matches that begin after it.
 @node Repeat Isearch
 @subsection Repeating Incremental Search
 
address@hidden C-s @r{(Incremental Search)}
address@hidden C-r @r{(Incremental Search)}
address@hidden isearch-repeat-forward
address@hidden isearch-repeat-backward
   Suppose you search forward for @samp{FOO} and find a match, but not
 the one you expected to find: the @samp{FOO} you were aiming for
-occurs later in the buffer.  In this event, type another @kbd{C-s} to
-move to the next occurrence of the search string.  You can repeat this
-any number of times.  If you overshoot, you can cancel some @kbd{C-s}
-characters with @key{DEL}.  Similarly, each @kbd{C-r} in a backward
-incremental search repeats the backward search.
+occurs later in the buffer.  In this event, type another @kbd{C-s}
+(@code{isearch-repeat-forward}) to move to the next occurrence of the
+search string.  You can repeat this any number of times.  If you
+overshoot, you can cancel some @kbd{C-s} commands with @key{DEL}.
+Similarly, each @kbd{C-r} (@code{isearch-repeat-backward}) in a
+backward incremental search repeats the backward search.
 
 @cindex lazy search highlighting
   If you pause for a little while during incremental search, Emacs
@@ -192,12 +211,15 @@ going past the original starting point of the search, it 
changes to
 you have already seen.
 
 @cindex search ring
address@hidden isearch-ring-advance
address@hidden isearch-ring-retreat
 @kindex M-n @r{(Incremental search)}
 @kindex M-p @r{(Incremental search)}
 @vindex search-ring-max
   To reuse earlier search strings, use the @dfn{search ring}.  The
-commands @kbd{M-p} and @kbd{M-n} move through the ring to pick a
-search string to reuse.  These commands leave the selected search ring
+commands @kbd{M-p} (@code{isearch-ring-retreat}) and @kbd{M-n}
+(@code{isearch-ring-advance}) move through the ring to pick a search
+string to reuse.  These commands leave the selected search ring
 element in the minibuffer, where you can edit it.  Type
 @kbd{C-s}/@kbd{C-r} or @key{RET} to accept the string and start
 searching for it.  The number of most recently used search strings
@@ -206,14 +228,16 @@ saved in the search ring is specified by the variable
 
 @cindex incremental search, edit search string
 @cindex interactively edit search string
address@hidden isearch-edit-string
 @kindex M-e @r{(Incremental search)}
 @kindex mouse-1 @r{in the minibuffer (Incremental Search)}
   To edit the current search string in the minibuffer without
-replacing it with items from the search ring, type @kbd{M-e} or click
address@hidden in the minibuffer.  Type @key{RET}, @kbd{C-s} or
address@hidden to finish editing the string and search for it.  Type
address@hidden or @address@hidden to add to the search string characters
-following point from the buffer from which you started the search.
+replacing it with items from the search ring, type @kbd{M-e}
+(@code{isearch-edit-string}) or click @kbd{mouse-1} in the minibuffer.
+Type @key{RET}, @kbd{C-s} or @kbd{C-r} to finish editing the string
+and search for it.  Type @kbd{C-f} or @address@hidden to add to the
+search string characters following point from the buffer from which
+you started the search.
 
 @node Isearch Yank
 @subsection Isearch Yanking
@@ -290,14 +314,15 @@ string that failed to match is highlighted using the face
 @code{isearch-fail}.
 
   At this point, there are several things you can do.  If your string
-was mistyped, you can use @key{DEL} to erase some of it and correct
-it, or you can type @kbd{M-e} and edit it.  If you like the place you
-have found, you can type @key{RET} to remain there.  Or you can type
address@hidden, which removes from the search string the characters that
-could not be found (the @samp{T} in @samp{FOOT}), leaving those that
-were found (the @samp{FOO} in @samp{FOOT}).  A second @kbd{C-g} at
-that point cancels the search entirely, returning point to where it
-was when the search started.
+was mistyped, use @key{DEL} to cancel a previous input item
+(@pxref{Basic Isearch}), @kbd{C-M-w} to erase one character at a time,
+or @kbd{M-e} to edit it.  If you like the place you have found, you
+can type @key{RET} to remain there.  Or you can type @kbd{C-g}, which
+removes from the search string the characters that could not be found
+(the @samp{T} in @samp{FOOT}), leaving those that were found (the
address@hidden in @samp{FOOT}).  A second @kbd{C-g} at that point cancels
+the search entirely, returning point to where it was when the search
+started.
 
 @cindex quitting (in search)
 @kindex C-g @r{(Incremental search)}
@@ -355,17 +380,22 @@ following methods:
 
 @itemize @bullet
 @item
-Type @kbd{C-q}, followed by a non-graphic character or a sequence of
-octal digits.  This adds a character to the search string, similar to
-inserting into a buffer using @kbd{C-q} (@pxref{Inserting Text}).  For
-example, @kbd{C-q C-s} during incremental search adds the
address@hidden character to the search string.
address@hidden isearch-quote-char
address@hidden C-q @r{(Incremental Search)}
+Type @kbd{C-q} (@code{isearch-quote-char}), followed by a non-graphic
+character or a sequence of octal digits.  This adds a character to the
+search string, similar to inserting into a buffer using @kbd{C-q}
+(@pxref{Inserting Text}).  For example, @kbd{C-q C-s} during
+incremental search adds the @samp{control-S} character to the search
+string.
 
 @item
-Type @kbd{C-x 8 @key{RET}}, followed by a Unicode name or code-point
-in hex.  This adds the specified character into the search string,
-similar to the usual @code{insert-char} command (@pxref{Inserting
-Text}).
address@hidden isearch-char-by-name
address@hidden C-x 8 RET @r{(Incremental Search)}
+Type @kbd{C-x 8 @key{RET}} (@code{isearch-char-by-name}), followed by
+a Unicode name or code-point in hex.  This adds the specified
+character into the search string, similar to the usual
address@hidden command (@pxref{Inserting Text}).
 
 @item
 @kindex C-^ @r{(Incremental Search)}
@@ -398,12 +428,20 @@ current buffer afterwards.
 @code{isearch-occur}, which runs @code{occur} with the current search
 string.  @xref{Other Repeating Search, occur}.
 
address@hidden isearch-query-replace
address@hidden isearch-query-replace-regexp
 @kindex M-% @r{(Incremental search)}
-  Typing @kbd{M-%} in incremental search invokes @code{query-replace}
-or @code{query-replace-regexp} (depending on search mode) with the
-current search string used as the string to replace.  A negative
-prefix argument means to replace backward.  @xref{Query Replace}.
-
address@hidden C-M-% @r{(Incremental search)}
+  Typing @kbd{M-%} (@code{isearch-query-replace}) in incremental
+search invokes @code{query-replace} or @code{query-replace-regexp}
+(depending on search mode) with the current search string used as the
+string to replace.  A negative prefix argument means to replace
+backward.  @xref{Query Replace}.  Typing @kbd{C-M-%}
+(@code{isearch-query-replace-regexp}) invokes
address@hidden with the current search string used as the
+regexp to replace.
+
address@hidden isearch-complete
 @kindex M-TAB @r{(Incremental search)}
   Typing @address@hidden in incremental search invokes
 @code{isearch-complete}, which attempts to complete the search string
@@ -609,15 +647,17 @@ Search backward for @var{words}, using a nonincremental 
word search.
 Search the Web for the text in region.
 @end table
 
address@hidden M-s w
 @findex isearch-forward-word
address@hidden isearch-toggle-word
address@hidden M-s w
   To begin a forward incremental word search, type @kbd{M-s w}.  If
 incremental search is not already active, this runs the command
 @code{isearch-forward-word}.  If incremental search is already active
-(whether a forward or backward search), @kbd{M-s w} switches to a word
-search while keeping the direction of the search and the current
-search string unchanged.  You can toggle word search back off by
-typing @kbd{M-s w} again.
+(whether a forward or backward search), @kbd{M-s w} runs the command
address@hidden, which switches to a word search while
+keeping the direction of the search and the current search string
+unchanged.  You can toggle word search back off by typing @kbd{M-s w}
+again.
 
 @findex word-search-forward
 @findex word-search-backward
diff --git a/doc/emacs/windows.texi b/doc/emacs/windows.texi
index 17ce4ad..8cc5144 100644
--- a/doc/emacs/windows.texi
+++ b/doc/emacs/windows.texi
@@ -48,8 +48,8 @@ other windows at all.  However, there are other commands such 
as
 @kbd{C-x 4 b} that select a different window and switch buffers in it.
 Also, all commands that display information in a window, including
 (for example) @kbd{C-h f} (@code{describe-function}) and @kbd{C-x C-b}
-(@code{list-buffers}), work by switching buffers in a nonselected
-window without affecting the selected window.
+(@code{list-buffers}), usually work by displaying buffers in a
+nonselected window without affecting the selected window.
 
   When multiple windows show the same buffer, they can have different
 regions, because they can have different values of point.  However,
@@ -347,11 +347,9 @@ heights of all the windows in the selected frame.
 in response to a user command.  There are several different ways in
 which commands do this.
 
-  Many commands, like @kbd{C-x C-f} (@code{find-file}), display the
-buffer by ``taking over'' the selected window, expecting that the
-user's attention will be diverted to that buffer.  These commands
-usually work by calling @code{switch-to-buffer} internally
-(@pxref{Select Buffer}).
+  Many commands, like @kbd{C-x C-f} (@code{find-file}), by default
+display the buffer by ``taking over'' the selected window, expecting
+that the user's attention will be diverted to that buffer.
 
   Some commands try to display intelligently, trying not to take
 over the selected window, e.g., by splitting off a new window and
@@ -374,10 +372,9 @@ key (@pxref{Pop Up Window}).
 
   Commands with names ending in @code{-other-frame} behave like
 @code{display-buffer}, except that they (i) never display in the
-selected window and (ii) prefer to create a new frame to display the
-desired buffer instead of splitting a window---as though the variable
address@hidden is set to @code{t} (@pxref{Window Choice}).
-Several of these commands are bound in the @kbd{C-x 5} prefix key.
+selected window and (ii) prefer to either create a new frame or use a
+window on some other frame to display the desired buffer.  Several of
+these commands are bound in the @kbd{C-x 5} prefix key.
 
 @menu
 * Window Choice::   How @code{display-buffer} works.
@@ -390,33 +387,61 @@ Several of these commands are bound in the @kbd{C-x 5} 
prefix key.
 
 The @code{display-buffer} command (as well as commands that call it
 internally) chooses a window to display by following the steps given
-below.  @xref{Choosing Window,,Choosing a Window for Display, elisp,
-The Emacs Lisp Reference Manual}, for details about how to alter this
-sequence of steps.
+below.  @xref{Choosing Window,,Choosing a Window for Displaying a
+Buffer, elisp, The Emacs Lisp Reference Manual}, for details about how
+to alter this sequence of steps.
 
 @itemize
address@hidden same-window-buffer-names
address@hidden same-window-regexps
 @item
-First, check if the buffer should be displayed in the selected window
-regardless of other considerations.  You can tell Emacs to do this by
-adding the desired buffer's name to the list
address@hidden, or adding a matching regular
-expression to the list @code{same-window-regexps}.  By default, these
-variables are @code{nil}, so this step is skipped.
+If the buffer should be displayed in the selected window regardless of
+other considerations, reuse the selected window.  By default, this
+step is skipped, but you can tell Emacs not to skip it by adding a
+regular expression matching the buffer's name together with a
+reference to the @code{display-buffer-same-window} action function
+(@pxref{Buffer Display Action Functions,,Action Functions for Buffer
+Display, elisp, The Emacs Lisp Reference Manual}) to the option
address@hidden (@pxref{Choosing Window,,Choosing a Window
+for Displaying a Buffer, elisp, The Emacs Lisp Reference Manual}).
+For example, to display the buffer @file{*scratch*} preferably in the
+selected window write:
+
address@hidden
address@hidden
+(customize-set-variable
+ 'display-buffer-alist
+ '("\\*scratch\\*" (display-buffer-same-window)))
address@hidden group
address@hidden example
+
+By default, @code{display-buffer-alist} is @code{nil}.
 
 @item
 Otherwise, if the buffer is already displayed in an existing window,
-reuse that window.  Normally, only windows on the selected frame
-are considered, but windows on other frames are also reusable if you
-change @code{pop-up-frames} (see below) to @code{t}.
+reuse that window.  Normally, only windows on the selected frame are
+considered, but windows on other frames are also reusable if you use
+the corresponding @code{reusable-frames} action alist entry
+(@pxref{Buffer Display Action Alists,,Action Alists for Buffer
+Display, elisp, The Emacs Lisp Reference Manual}).  See the
+next step for an example of how to do that.
 
address@hidden pop-up-frames
 @item
 Otherwise, optionally create a new frame and display the buffer there.
-By default, this step is skipped.  To enable it, change the variable
address@hidden to a address@hidden value.  The special value
address@hidden means to do this only on graphical displays.
+By default, this step is skipped.  To enable it, change the value of
+the option @code{display-buffer-base-action} (@pxref{Choosing
+Window,,Choosing a Window for Displaying a Buffer, elisp, The Emacs
+Lisp Reference Manual}) as follows:
+
address@hidden
address@hidden
+(customize-set-variable
+ 'display-buffer-base-action
+ '((display-buffer-reuse-window display-buffer-pop-up-frame)
+   (reusable-frames . 0)))
address@hidden group
address@hidden example
+
+This customization will also try to make the preceding step search for
+a reusable window on all visible or iconified frames.
 
 @item
 Otherwise, try to create a new window by splitting a window on the
@@ -436,9 +461,9 @@ window was not split before (to avoid excessive splitting).
 
 @item
 Otherwise, display the buffer in a window previously showing it.
-Normally, only windows on the selected frame are considered, but if
address@hidden is address@hidden the window may be also on another
-frame.
+Normally, only windows on the selected frame are considered, but with
+a suitable @code{reusable-frames} action alist entry (see above) the
+window may be also on another frame.
 
 @item
 Otherwise, display the buffer in an existing window on the selected
@@ -449,41 +474,35 @@ If all the above methods fail for whatever reason, create 
a new frame
 and display the buffer there.
 @end itemize
 
-A more advanced and flexible way to customize the behavior of
address@hidden is by using the option @code{display-buffer-alist}
-mentioned in the next section.
-
 
 @node Temporary Displays
 @subsection Displaying non-editable buffers.
address@hidden pop-up windows
 @cindex temporary windows
 
 Some buffers are shown in windows for perusal rather than for editing.
 Help commands (@pxref{Help}) typically use a buffer called @file{*Help*}
 for that purpose, minibuffer completion (@pxref{Completion}) uses a
-buffer called @file{*Completions*} instead.  Such buffers are usually
+buffer called @file{*Completions*}, etc.  Such buffers are usually
 displayed only for a short period of time.
 
   Normally, Emacs chooses the window for such temporary displays via
address@hidden as described above.  The @file{*Completions*}
-buffer, on the other hand, is normally displayed in a window at the
-bottom of the selected frame, regardless of the number of windows
-already shown on that frame.
address@hidden, as described in the previous subsection.  The
address@hidden buffer, on the other hand, is normally displayed
+in a window at the bottom of the selected frame, regardless of the
+number of windows already shown on that frame.
 
   If you prefer Emacs to display a temporary buffer in a different
-fashion, we recommend customizing the variable
address@hidden (@pxref{Choosing Window,,Choosing a Window
-for Display, elisp, The Emacs Lisp Reference Manual}).  For example,
-to display @file{*Completions*} by splitting a window as described in
-the previous section, use the following form in your initialization
-file (@pxref{Init File}):
+fashion, customize the variable @code{display-buffer-alist}
+(@pxref{Choosing Window,,Choosing a Window for Displaying a Buffer,
+elisp, The Emacs Lisp Reference Manual}) appropriately.  For example,
+to display @file{*Completions*} always below the selected window, use
+the following form in your initialization file (@pxref{Init File}):
 
 @example
 @group
 (customize-set-variable
  'display-buffer-alist
- '(("\\*Completions\\*" display-buffer-pop-up-window)))
+ '(("\\*Completions\\*" display-buffer-below-selected)))
 @end group
 @end example
 
@@ -491,10 +510,10 @@ file (@pxref{Init File}):
   The @file{*Completions*} buffer is also special in the sense that
 Emacs usually tries to make its window just as large as necessary to
 display all of its contents.  To resize windows showing other
-temporary displays like, for example, the @file{*Help*} buffer
-accordingly, turn on the minor mode (@pxref{Minor Modes})
address@hidden (@pxref{Temporary Displays,,Temporary
-Displays, elisp, The Emacs Lisp Reference Manual}).
+temporary displays, like, for example, the @file{*Help*} buffer, turn
+on the minor mode (@pxref{Minor Modes}) @code{temp-buffer-resize-mode}
+(@pxref{Temporary Displays,,Temporary Displays, elisp, The Emacs Lisp
+Reference Manual}).
 
 @vindex temp-buffer-max-height
 @vindex temp-buffer-max-width
@@ -502,7 +521,7 @@ Displays, elisp, The Emacs Lisp Reference Manual}).
 can be controlled by customizing the options
 @code{temp-buffer-max-height} and @code{temp-buffer-max-width}
 (@pxref{Temporary Displays,,Temporary Displays, elisp, The Emacs Lisp
-Reference Manual}) and cannot exceed the size of the containing frame.
+Reference Manual}), and cannot exceed the size of the containing frame.
 
 
 @node Window Convenience
diff --git a/doc/emacs/xresources.texi b/doc/emacs/xresources.texi
index db2c6ff..903090f 100644
--- a/doc/emacs/xresources.texi
+++ b/doc/emacs/xresources.texi
@@ -46,6 +46,11 @@ this file do not take effect immediately, because the X 
server stores
 its own list of resources; to update it, use the command
 @command{xrdb}---for instance, @samp{xrdb ~/.Xdefaults}.
 
+  Settings specified via X resources in general override the
+equivalent settings in Emacs init files (@pxref{Init File}), in
+particular for parameters of the initial frame (@pxref{Frame
+Parameters}).
+
 @cindex registry, setting resources (MS-Windows)
   (MS-Windows systems do not support X resource files; on such systems,
 Emacs looks for X resources in the Windows Registry, first under the
diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index fa64d07..4862789 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -137,6 +137,9 @@ start with a capital, e.g., @code{"use (system-name) 
instead."}); @code{t}; any
 other symbol, which should be an alternative function to use in Lisp
 code.
 
+Generic functions (@pxref{Generic Functions}) cannot be turned into
+commands by adding the @code{interactive} form to them.
+
 @menu
 * Using Interactive::     General rules for @code{interactive}.
 * Interactive Codes::     The standard letter-codes for reading arguments
diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi
index 0f7502f..5cc43c4 100644
--- a/doc/lispref/control.texi
+++ b/doc/lispref/control.texi
@@ -419,64 +419,68 @@ This is not completely equivalent because it can evaluate 
@var{arg1} or
 @node Pattern-Matching Conditional
 @section Pattern-Matching Conditional
 @cindex pcase
address@hidden pattern matching
address@hidden pattern matching, programming style
 
 Aside from the four basic conditional forms, Emacs Lisp also
 has a pattern-matching conditional form, the @code{pcase} macro,
 a hybrid of @code{cond} and @code{cl-case}
 (@pxref{Conditionals,,,cl,Common Lisp Extensions})
 that overcomes their limitations and introduces
-the @dfn{pattern matching} programming style.
-First, the limitations:
+the @dfn{pattern matching programming style}.
+The limitations that @code{pcase} overcomes are:
 
 @itemize
address@hidden The @code{cond} form chooses among alternatives
-by evaluating the predicate @var{condition} of each
-of its clauses (@pxref{Conditionals}).
-The primary limitation is that variables let-bound in @var{condition}
-are not available to the clause's @var{body-forms}.
address@hidden
+The @code{cond} form chooses among alternatives by evaluating the
+predicate @var{condition} of each of its clauses
+(@pxref{Conditionals}).  The primary limitation is that variables
+let-bound in @var{condition} are not available to the clause's
address@hidden
 
 Another annoyance (more an inconvenience than a limitation)
 is that when a series of @var{condition} predicates implement
-equality tests, there is a lot of repeated code.
-For that, why not use @code{cl-case}?
+equality tests, there is a lot of repeated code.  (@code{cl-case}
+solves this inconvenience.)
 
 @item
 The @code{cl-case} macro chooses among alternatives by evaluating
 the equality of its first argument against a set of specific
 values.
-The limitations are two-fold:
+
+Its limitations are two-fold:
 
 @enumerate
address@hidden The equality tests use @code{eql}.
address@hidden The values must be known and written in advance.
address@hidden
+The equality tests use @code{eql}.
address@hidden
+The values must be known and written in advance.
 @end enumerate
 
 @noindent
 These render @code{cl-case} unsuitable for strings or compound
-data structures (e.g., lists or vectors).
-For that, why not use @code{cond}?
-(And here we end up in a circle.)
+data structures (e.g., lists or vectors).  (@code{cond} doesn't have
+these limitations, but it has others, see above.)
 @end itemize
 
 @noindent
 Conceptually, the @code{pcase} macro borrows the first-arg focus
 of @code{cl-case} and the clause-processing flow of @code{cond},
 replacing @var{condition} with a generalization of
-the equality test called @dfn{matching},
+the equality test which is a variant of @dfn{pattern matching},
 and adding facilities so that you can concisely express a
 clause's predicate, and arrange to share let-bindings between
 a clause's predicate and @var{body-forms}.
 
 The concise expression of a predicate is known as a @dfn{pattern}.
-When the predicate, called on the value of the first arg,
-returns address@hidden, the pattern matches the value
-(or sometimes ``the value matches the pattern'').
+When the predicate, called on the value of the first arg, returns
address@hidden, we say that ``the pattern matches the value'' (or
+sometimes ``the value matches the pattern'').
 
 @menu
-* The @code{pcase} macro: pcase Macro.  Plus examples and caveats.
+* The @code{pcase} macro: pcase Macro.  Includes examples and caveats.
 * Extending @code{pcase}: Extending pcase.  Define new kinds of patterns.
-* Backquote-Style Patterns: Backquote Patterns.  Structural matching.
+* Backquote-Style Patterns: Backquote Patterns.  Structural patterns matching.
+* Destructuring with pcase Patterns:: Using pcase patterns to extract 
subfields.
 @end menu
 
 @node pcase Macro
@@ -497,26 +501,30 @@ of the last of @var{body-forms} in the successful clause.
 Otherwise, @code{pcase} evaluates to @code{nil}.
 @end defmac
 
-The rest of this subsection
-describes different forms of core patterns,
-presents some examples,
-and concludes with important caveats on using the
-let-binding facility provided by some pattern forms.
-A core pattern can have the following forms:
address@hidden pcase pattern
+Each @var{pattern} has to be a @dfn{pcase pattern}, which can use
+either one of the core patterns defined below, or one of the patterns
+defined via @code{pcase-defmacro} (@pxref{Extending pcase}).
+
+The rest of this subsection describes different forms of core
+patterns, presents some examples, and concludes with important caveats
+on using the let-binding facility provided by some pattern forms.  A
+core pattern can have the following forms:
 
 @table @code
 
 @item _
 Matches any @var{expval}.
-This is known as @dfn{don't care} or @dfn{wildcard}.
+This is also known as @dfn{don't care} or @dfn{wildcard}.
 
 @item '@var{val}
-Matches if @var{expval} is @code{equal} to @var{val}.
+Matches if @var{expval} equals @var{val}.  The comparison is done as
+if by @code{equal} (@pxref{Equality Predicates}).
 
 @item @var{keyword}
 @itemx @var{integer}
 @itemx @var{string}
-Matches if @var{expval} is @code{equal} to the literal object.
+Matches if @var{expval} equals the literal object.
 This is a special case of @code{'@var{val}}, above,
 possible because literal objects of these types are self-quoting.
 
@@ -528,17 +536,17 @@ Matches any @var{expval}, and additionally let-binds 
@var{symbol} to
 If @var{symbol} is part of a sequencing pattern @var{seqpat}
 (e.g., by using @code{and}, below), the binding is also available to
 the portion of @var{seqpat} following the appearance of @var{symbol}.
-This usage has some caveats (@pxref{pcase-symbol-caveats,,caveats}).
+This usage has some caveats, see @ref{pcase-symbol-caveats,,caveats}.
 
 Two symbols to avoid are @code{t}, which behaves like @code{_}
-(above) and is deprecated, and @code{nil}, which signals error.
+(above) and is deprecated, and @code{nil}, which signals an error.
 Likewise, it makes no sense to bind keyword symbols
 (@pxref{Constant Variables}).
 
 @item (pred @var{function})
 Matches if the predicate @var{function} returns address@hidden
 when called on @var{expval}.
address@hidden can have one of the possible forms:
+the predicate @var{function} can have one of the following forms:
 
 @table @asis
 @item function name (a symbol)
@@ -565,20 +573,17 @@ the actual function call becomes: @address@hidden(= 42 
@var{expval})}}.
 @item (app @var{function} @var{pattern})
 Matches if @var{function} called on @var{expval} returns a
 value that matches @var{pattern}.
address@hidden can take one of the
-forms described for @code{pred}, above.
-Unlike @code{pred}, however,
address@hidden tests the result against @var{pattern},
-rather than against a boolean truth value.
address@hidden can take one of the forms described for @code{pred},
+above.  Unlike @code{pred}, however, @code{app} tests the result
+against @var{pattern}, rather than against a boolean truth value.
 
 @item (guard @var{boolean-expression})
 Matches if @var{boolean-expression} evaluates to address@hidden
 
 @item (let @var{pattern} @var{expr})
-Evaluates @var{expr} to get @var{exprval}
-and matches if @var{exprval} matches @var{pattern}.
-(It is called @code{let} because
address@hidden can bind symbols to values using @var{symbol}.)
+Evaluates @var{expr} to get @var{exprval} and matches if @var{exprval}
+matches @var{pattern}.  (It is called @code{let} because @var{pattern}
+can bind symbols to values using @var{symbol}.)
 @end table
 
 @cindex sequencing pattern
@@ -591,18 +596,16 @@ but instead of processing values, they process 
sub-patterns.
 
 @table @code
 @item (and @address@hidden)
-Attempts to match @address@hidden, in order,
-until one of them fails to match.
-In that case, @code{and} likewise fails to match,
-and the rest of the sub-patterns are not tested.
-If all sub-patterns match, @code{and} matches.
+Attempts to match @address@hidden, in order, until one of them
+fails to match.  In that case, @code{and} likewise fails to match, and
+the rest of the sub-patterns are not tested.  If all sub-patterns
+match, @code{and} matches.
 
 @item (or @var{pattern1} @address@hidden)
 Attempts to match @var{pattern1}, @var{pattern2}, @dots{}, in order,
-until one of them succeeds.
-In that case, @code{or} likewise matches,
-and the rest of the sub-patterns are not tested.
-(Note that there must be at least two sub-patterns.
+until one of them succeeds.  In that case, @code{or} likewise matches,
+and the rest of the sub-patterns are not tested.  (Note that there
+must be at least two sub-patterns.
 Simply @address@hidden(or @var{pattern1})}} signals error.)
 @c Issue: Is this correct and intended?
 @c        Are there exceptions, qualifications?
@@ -1037,12 +1040,11 @@ Both use a single backquote construct 
(@pxref{Backquote}).
 
 This subsection describes @dfn{backquote-style patterns},
 a set of builtin patterns that eases structural matching.
-For background, @xref{Pattern-Matching Conditional}.
+For background, @pxref{Pattern-Matching Conditional}.
 
address@hidden patterns} are a powerful set of
address@hidden pattern extensions (created using @code{pcase-defmacro})
-that make it easy to match @var{expval} against
-specifications of its @emph{structure}.
+Backquote-style patterns are a powerful set of @code{pcase} pattern
+extensions (created using @code{pcase-defmacro}) that make it easy to
+match @var{expval} against specifications of its @emph{structure}.
 
 For example, to match @var{expval} that must be a list of two
 elements whose first element is a specific string and the second
@@ -1166,6 +1168,105 @@ evaluation results:
 (evaluate '(sub 1 2) nil)                 @result{} error
 @end example
 
address@hidden Destructuring with pcase Patterns
address@hidden Destructuring with @code{pcase} Patterns
address@hidden destructuring with pcase patterns
+
+Pcase patterns not only express a condition on the form of the objects
+they can match, but they can also extract sub-fields of those objects.
+For example we can extract 2 elements from a list that is the value of
+the variable @code{my-list} with the following code:
+
address@hidden
+  (pcase my-list
+    (`(add ,x ,y)  (message "Contains %S and %S" x y)))
address@hidden example
+
+This will not only extract @code{x} and @code{y} but will additionally
+test that @code{my-list} is a list containing exactly 3 elements and
+whose first element is the symbol @code{add}.  If any of those tests
+fail, @code{pcase} will immediately return @code{nil} without calling
address@hidden
+
+Extraction of multiple values stored in an object is known as
address@hidden  Using @code{pcase} patterns allows to perform
address@hidden binding}, which is similar to a local binding
+(@pxref{Local Variables}), but gives values to multiple elements of
+a variable by extracting those values from an object of compatible
+structure.
+
+The macros described in this section use @code{pcase} patterns to
+perform destructuring binding.  The condition of the object to be of
+compatible structure means that the object must match the pattern,
+because only then the object's subfields can be extracted.  For
+example:
+
address@hidden
+  (pcase-let ((`(add ,x ,y) my-list))
+    (message "Contains %S and %S" x y))
address@hidden example
+
address@hidden
+does the same as the previous example, except that it directly tries
+to extract @code{x} and @code{y} from @code{my-list} without first
+verifying if @code{my-list} is a list which has the right number of
+elements and has @code{add} as its first element.  The precise
+behavior when the object does not actually match the pattern is
+undefined, although the body will not be silently skipped: either an
+error is signaled or the body is run with some of the variables
+potentially bound to arbitrary values like @code{nil}.
+
+The pcase patterns that are useful for destructuring bindings are
+generally those described in @ref{Backquote Patterns}, since they
+express a specification of the structure of objects that will match.
+
+For an alternative facility for destructuring binding, see
address@hidden
+
address@hidden pcase-let bindings address@hidden
+Perform destructuring binding of variables according to
address@hidden, and then evaluate @var{body}.
+
address@hidden is a list of bindings of the form @address@hidden(@var{pattern}
address@hidden)}}, where @var{exp} is an expression to evaluate and
address@hidden is a @code{pcase} pattern.
+
+All @var{exp}s are evaluated first, after which they are matched
+against their respective @var{pattern}, introducing new variable
+bindings that can then be used inside @var{body}.  The variable
+bindings are produced by destructuring binding of elements of
address@hidden to the values of the corresponding elements of the
+evaluated @var{exp}.
address@hidden defmac
+
address@hidden pcase-let* bindings address@hidden
+Perform destructuring binding of variables according to
address@hidden, and then evaluate @var{body}.
+
address@hidden is a list of bindings of the form @code{(@var{pattern}
address@hidden)}, where @var{exp} is an expression to evaluate and
address@hidden is a @code{pcase} pattern.  The variable bindings are
+produced by destructuring binding of elements of @var{pattern} to the
+values of the corresponding elements of the evaluated @var{exp}.
+
+Unlike @code{pcase-let}, but similarly to @code{let*}, each @var{exp}
+is matched against its corresponding @var{pattern} before processing
+the next element of @var{bindings}, so the variable bindings
+introduced in each one of the @var{bindings} are available in the
address@hidden of the @var{bindings} that follow it, additionally to
+being available in @var{body}.
address@hidden defmac
+
address@hidden pcase-dolist (pattern list) address@hidden
+Execute @var{body} once for each element of @var{list}, on each
+iteration performing a destructuring binding of variables in
address@hidden to the values of the corresponding subfields of the
+element of @var{list}.  The bindings are performed as if by
address@hidden  When @var{pattern} is a simple variable, this ends
+up being equivalent to @code{dolist} (@pxref{Iteration}).
address@hidden defmac
+
+
 @node Iteration
 @section Iteration
 @cindex iteration
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 9a6fb42..b4a4d6c 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -4170,10 +4170,10 @@ Used to indicate continued lines.
 @item @code{right-triangle}, @code{left-triangle}
 The former is used by overlay arrows.  The latter is unused.
 
address@hidden @code{up-arrow}, @code{down-arrow}, @code{top-left-angle} 
@code{top-right-angle}
address@hidden @code{up-arrow}, @code{down-arrow}
 @itemx @code{bottom-left-angle}, @code{bottom-right-angle}
address@hidden @code{top-right-angle}, @code{top-left-angle}
address@hidden @code{left-bracket}, @code{right-bracket}, 
@code{top-right-angle}, @code{top-left-angle}
address@hidden @code{top-left-angle}, @code{top-right-angle}
address@hidden @code{left-bracket}, @code{right-bracket}
 Used to indicate buffer boundaries.
 
 @item @code{filled-rectangle}, @code{hollow-rectangle}
@@ -4181,7 +4181,7 @@ Used to indicate buffer boundaries.
 @itemx @code{vertical-bar}, @code{horizontal-bar}
 Used for different types of fringe cursors.
 
address@hidden @code{empty-line}, @code{exclamation-mark}, 
@code{question-mark}, @code{exclamation-mark}
address@hidden @code{empty-line}, @code{exclamation-mark}, @code{question-mark}
 Not used by core Emacs features.
 @end table
 
diff --git a/doc/lispref/edebug.texi b/doc/lispref/edebug.texi
index b1a6511..2aace03 100644
--- a/doc/lispref/edebug.texi
+++ b/doc/lispref/edebug.texi
@@ -1319,7 +1319,6 @@ succeeds.
 
 @item &define
 @c @kindex &define @r{(Edebug)}
-
 Indicates that the specification is for a defining form.  Edebug's
 definition of a defining form is a form containing one or more code
 forms which are saved and executed later, after the execution of the
diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi
index ec62ffb..5846e31 100644
--- a/doc/lispref/elisp.texi
+++ b/doc/lispref/elisp.texi
@@ -1046,9 +1046,7 @@ Windows
 * Cyclic Window Ordering::  Moving around the existing windows.
 * Buffers and Windows::     Each window displays the contents of a buffer.
 * Switching Buffers::       Higher-level functions for switching to a buffer.
-* Choosing Window::         How to choose a window for displaying a buffer.
-* Display Action Functions:: Subroutines for @code{display-buffer}.
-* Choosing Window Options:: Extra options affecting how buffers are displayed.
+* Displaying Buffers::      Displaying a buffer in a suitable window.
 * Window History::          Each window remembers the buffers displayed in it.
 * Dedicated Windows::       How to avoid displaying another buffer in
                               a specific window.
@@ -1070,6 +1068,18 @@ Windows
                               redisplay going past a certain point,
                               or window configuration changes.
 
+Displaying Buffers
+
+* Choosing Window::         How to choose a window for displaying a buffer.
+* Buffer Display Action Functions:: Support functions for buffer display.
+* Buffer Display Action Alists:: Alists for fine-tuning buffer display
+                              action functions.
+* Choosing Window Options:: Extra options affecting how buffers are displayed.
+* Precedence of Action Functions:: A tutorial explaining the precedence of
+                              buffer display action functions.
+* The Zen of Buffer Display:: How to avoid that buffers get lost in between
+                              windows.
+
 Side Windows
 
 * Displaying Buffers in Side Windows:: An action function for displaying
@@ -1591,9 +1601,18 @@ GNU Emacs Internals
 * Memory Usage::            Info about total size of Lisp objects made so far.
 * C Dialect::               What C variant Emacs is written in.
 * Writing Emacs Primitives::  Writing C code for Emacs.
+* Writing Dynamic Modules::   Writing loadable modules for Emacs.
 * Object Internals::        Data formats of buffers, windows, processes.
 * C Integer Types::         How C integer types are used inside Emacs.
 
+Writing Dynamic Modules
+
+* Module Initialization::
+* Module Functions::
+* Module Values::
+* Module Misc::
+* Module Nonlocal::
+
 Object Internals
 
 * Buffer Internals::        Components of a buffer structure.
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index ba4b931..ad5d0fc 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -3261,11 +3261,11 @@ and should be preferred when specifying a address@hidden
 @code{drag-with-mode-line} parameter.
 
   When a child frame is used for displaying a buffer via
address@hidden (@pxref{Display Action Functions}),
-the frame's @code{auto-hide-function} parameter (@pxref{Frame
-Interaction Parameters}) can be set to a function, in order to
-appropriately deal with the frame when the window displaying the buffer
-shall be quit.
address@hidden (@pxref{Buffer Display Action
+Functions}), the frame's @code{auto-hide-function} parameter
+(@pxref{Frame Interaction Parameters}) can be set to a function, in
+order to appropriately deal with the frame when the window displaying
+the buffer shall be quit.
 
   When a child frame is used during minibuffer interaction, for example,
 to display completions in a separate window, the @code{minibuffer-exit}
diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi
index 3be52d8..69e9919 100644
--- a/doc/lispref/functions.texi
+++ b/doc/lispref/functions.texi
@@ -1350,6 +1350,13 @@ to invoke the other auxiliary or primary methods.
 This allows you to add more methods, distinguished by @var{string},
 for the same specializers and qualifiers.
 @end table
+
+Functions defined using @code{cl-defmethod} cannot be made
+interactive, i.e.@: commands (@pxref{Defining Commands}), by adding
+the @code{interactive} form to them.  If you need a polymorphic
+command, we recommend defining a normal command that calls a
+polymorphic function defined via @code{cl-defgeneric} and
address@hidden
 @end defmac
 
 @cindex dispatch of methods for generic function
diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi
index d42e244..27bfbe8 100644
--- a/doc/lispref/internals.texi
+++ b/doc/lispref/internals.texi
@@ -18,6 +18,7 @@ internal aspects of GNU Emacs that may be of interest to C 
programmers.
 * Memory Usage::        Info about total size of Lisp objects made so far.
 * C Dialect::           What C variant Emacs is written in.
 * Writing Emacs Primitives::   Writing C code for Emacs.
+* Writing Dynamic Modules::    Writing loadable modules for Emacs.
 * Object Internals::    Data formats of buffers, windows, processes.
 * C Integer Types::     How C integer types are used inside Emacs.
 @end menu
@@ -969,6 +970,708 @@ in @file{byte-opt.el} that binds 
@code{side-effect-free-fns} and
 @code{side-effect-and-error-free-fns} so that the compiler optimizer
 knows about it.
 
address@hidden Writing Dynamic Modules
address@hidden Writing Dynamically-Loaded Modules
address@hidden writing emacs modules
address@hidden dynamic modules, writing
+
address@hidden module @acronym{API}
+  This section describes the Emacs module @acronym{API} and how to use
+it as part of writing extension modules for Emacs.  The module
address@hidden is defined in the C programming language, therefore the
+description and the examples in this section assume the module is
+written in address@hidden  For other programming languages, you will need to 
use
+the appropriate bindings, interfaces and facilities for calling C code.
+Emacs C code requires a C99 or later compiler (@pxref{C Dialect}), and
+so the code examples in this section also follow that standard.
+
+Writing a module and integrating it into Emacs comprises the following
+tasks:
+
address@hidden @bullet
address@hidden
+Writing initialization code for the module.
+
address@hidden
+Writing one or more module functions.
+
address@hidden
+Communicating values and objects between Emacs and your module
+functions.
+
address@hidden
+Handling of error conditions and nonlocal exits.
address@hidden itemize
+
address@hidden
+The following subsections describe these tasks and the @acronym{API}
+itself in more detail.
+
+Once your module is written, compile it to produce a shared library,
+according to the conventions of the underlying platform.  Then place
+the shared library in a directory mentioned in @code{load-path}
+(@pxref{Library Search}), where Emacs will find it.
+
+If you wish to verify the conformance of a module to the Emacs dynamic
+module @acronym{API}, invoke Emacs with the @kbd{--module-assertions}
+option.  @xref{Initial Options,,,emacs, The GNU Emacs Manual}.
+
address@hidden
+* Module Initialization::
+* Module Functions::
+* Module Values::
+* Module Misc::
+* Module Nonlocal::
address@hidden menu
+
address@hidden Module Initialization
address@hidden Module Initialization Code
address@hidden module initialization
+
+  Begin your module by including the header file @file{emacs-module.h}
+and defining the GPL compatibility symbol:
+
address@hidden
+#include <emacs-module.h>
+
+int plugin_is_GPL_compatible;
address@hidden example
+
+The @file{emacs-module.h} file is installed into your system's include
+tree as part of the Emacs installation.  Alternatively, you can find
+it in the Emacs source tree.
+
address@hidden initialization function}
+Next, write an initialization function for the module.
+
address@hidden Function int emacs_module_init (struct emacs_runtime 
address@hidden)
+Emacs calls this function when it loads a module.  If a module does
+not export a function named @code{emacs_module_init}, trying to load
+the module will signal an error.  The initialization function should
+return zero if the initialization succeeds, non-zero otherwise.  In
+the latter case, Emacs will signal an error, and the loading of the
+module will fail.  If the user presses @kbd{C-g} during the
+initialization, Emacs ignores the return value of the initialization
+function and quits (@pxref{Quitting}).  (If needed, you can catch user
+quitting inside the initialization function, @pxref{should_quit}.)
+
+The argument @var{runtime} is a pointer to a C @code{struct} that
+includes 2 public fields: @code{size}, which provides the size of the
+structure in bytes; and @code{get_environment}, which provides a
+pointer to a function that allows the module initialization function
+access to the Emacs environment object and its interfaces.
+
+The initialization function should perform whatever initialization is
+required for the module.  In addition, it can perform the following
+tasks:
+
address@hidden @asis
address@hidden compatibility, between modules and Emacs
address@hidden Compatibility verification
+A module can verify that the Emacs executable which loads the module
+is compatible with the module, by comparing the @code{size} member of
+the @var{runtime} structure with the value compiled into the module:
+
address@hidden
+int
+emacs_module_init (struct emacs_runtime *ert)
address@hidden
+  if (ert->size < sizeof (*ert))
+    return 1;
address@hidden
address@hidden example
+
address@hidden
+If the size of the runtime object passed to the module is smaller than
+what it expects, it means the module was compiled for an Emacs version
+newer (later) than the one which attempts to load it, i.e.@: the
+module might be incompatible with the Emacs binary.
+
+In addition, a module can verify the compatibility of the module
address@hidden with what the module expects.  The following sample code
+assumes it is part of the @code{emacs_module_init} function shown
+above:
+
address@hidden
+  emacs_env *env = ert->get_environment (ert);
+  if (env->size < sizeof (*env))
+    return 2;
address@hidden example
+
address@hidden
address@hidden module runtime environment
+This calls the @code{get_environment} function using the pointer
+provided in the @code{runtime} structure to retrieve a pointer to the
address@hidden's @dfn{environment}, a C @code{struct} which also has a
address@hidden field holding the size of the structure in bytes.
+
+Finally, you can write a module that will work with older versions of
+Emacs, by comparing the size of the environment passed by Emacs with
+known sizes, like this:
+
address@hidden
+  emacs_env *env = ert->get_environment (ert);
+  if (env->size >= sizeof (struct emacs_env_26))
+    emacs_version = 26;  /* Emacs 26 or later.  */
+  else if (env->size >= sizeof (struct emacs_env_25))
+    emacs_version = 25;
+  else
+    return 2; /* Unknown or unsupported version.  */
address@hidden example
+
address@hidden
+This works because later Emacs versions always @emph{add} members to
+the environment, never @emph{remove} any members, so the size can only
+grow with new Emacs releases.  Given the version of Emacs, the module
+can use only the parts of the module @acronym{API} that existed in
+that version, since those parts are identical in later versions.
+
+We recommend that modules always perform the compatibility
+verification, unless they do their job entirely in the initialization
+function, and don't access any Lisp objects or use any Emacs functions
+accessible through the environment structure.
+
address@hidden Binding module functions to Lisp symbols
+This gives the module functions names so that Lisp code could call it
+by that name.  We describe how to do this in @ref{Module Functions}
+below.
address@hidden table
address@hidden deftypefn
+
address@hidden Module Functions
address@hidden Writing Module Functions
address@hidden writing module functions
address@hidden module functions
+
+  The main reason for writing an Emacs module is to make additional
+functions available to Lisp programs that load the module.  This
+subsection describes how to write such @dfn{module functions}.
+
+A module function has the following general form and signature:
+
address@hidden Function emacs_value module_func (emacs_env address@hidden, 
ptrdiff_t @var{nargs}, emacs_value address@hidden, void address@hidden)
+The @var{env} argument provides a pointer to the @acronym{API}
+environment, needed to access Emacs objects and functions.  The
address@hidden argument is the required number of arguments, which can be
+zero (see @code{make_function} below for more flexible specification
+of the argument number), and @var{args} is a pointer to the array of
+the function arguments.  The argument @var{data} points to additional
+data required by the function, which was arranged when
address@hidden (see below) was called to create an Emacs
+function from @code{module_func}.
+
+Module functions use the type @code{emacs_value} to communicate Lisp
+objects between Emacs and the module (@pxref{Module Values}).  The
address@hidden, described below and in the following subsections,
+provides facilities for conversion between basic C data types and the
+corresponding @code{emacs_value} objects.
+
+A module function always returns a value.  If the function returns
+normally, the Lisp code which called it will see the Lisp object
+corresponding to the @code{emacs_value} value the function returned.
+However, if the user typed @kbd{C-g}, or if the module function or its
+callees signaled an error or exited nonlocally (@pxref{Module
+Nonlocal}), Emacs will ignore the returned value and quit or throw as
+it does when Lisp code encounters the same situations.
address@hidden deftypefn
+
+After writing your C code for a module function, you should make a
+Lisp function object from it using the @code{make_function} function,
+whose pointer is provided in the environment (recall that the pointer
+to the environment is returned by @code{get_environment}).  This is
+normally done in the module initialization function (@pxref{module
+initialization function}), after verifying the @acronym{API}
+compatibility.
+
address@hidden Function emacs_value make_function (emacs_env address@hidden, 
ptrdiff_t @var{min_arity}, ptrdiff_t @var{max_arity}, subr @var{func}, const 
char address@hidden, void address@hidden)
address@hidden emacs_variadic_function
+This returns an Emacs function created from the C function @var{func},
+whose signature is as described for @code{module_func} above (assumed
+here to be @code{typedef}'ed as @code{subr}).  The arguments
address@hidden and @var{max_arity} specify the minimum and maximum
+number of arguments that @var{func} can accept.  The @var{max_arity}
+argument can have the special value @code{emacs_variadic_function},
+which makes the function accept an unlimited number of arguments, like
+the @code{&rest} keyword in Lisp (@pxref{Argument List}).
+
+The argument @var{data} is a way to arrange for arbitrary additional
+data to be passed to @var{func} when it is called.  Whatever pointer
+is passed to @code{make_function} will be passed unaltered to
address@hidden
+
+The argument @var{docstring} specifies the documentation string for
+the function.  It should be either an @acronym{ASCII} string, or a
+UTF-8 encoded address@hidden string, or a @code{NULL} pointer; in
+the latter case the function will have no documentation.  The
+documentation string can end with a line that specifies the advertised
+calling convention, see @ref{Function Documentation}.
+
+Since every module function must accept the pointer to the environment
+as its first argument, the call to @code{make_function} could be made
+from any module function, but you will normally want to do that from
+the module initialization function, so that all the module functions
+are known to Emacs once the module is loaded.
address@hidden deftypefn
+
+Finally, you should bind the Lisp function to a symbol, so that Lisp
+code could call your function by name.  For that, use the module
address@hidden function @code{intern} (@pxref{intern}) whose pointer is
+also provided in the environment that module functions can access.
+
+Combining the above steps, code that arranges for a C function
address@hidden to be callable as @code{module-func} from Lisp will
+look like this, as part of the module initialization function:
+
address@hidden
+ emacs_env *env = ert->get_environment (ert);
+ emacs_value func = env->make_function (env, min_arity, max_arity,
+                                        module_func, docstring, data);
+ emacs_value symbol = env->intern (env, "module-func");
+ emacs_value args[] = @{symbol, address@hidden;
+ env->funcall (env, env->intern (env, "defalias"), 2, args);
address@hidden example
+
address@hidden
+This makes the symbol @code{module-func} known to Emacs by calling
address@hidden>intern}, then invokes @code{defalias} from Emacs to bind
+the function to that symbol.  Note that it is possible to use
address@hidden instead of @code{defalias}; the differences are described
+in @ref{Defining Functions, defalias}.
+
+Using the module @acronym{API}, it is possible to define more complex
+function and data types: interactive functions, inline functions,
+macros, etc.  However, the resulting C code will be cumbersome and
+hard to read.  Therefore, we recommend that you limit the module code
+which creates functions and data structures to the absolute minimum,
+and leave the rest for a Lisp package that will accompany your module,
+because doing these additional tasks in Lisp is much easier, and will
+produce a much more readable code.  For example, given a module
+function @code{module-func} defined as above, one way of making an
+interactive command @code{module-cmd} based on it is with the
+following simple Lisp wrapper:
+
address@hidden
+(defun module-cmd (&rest args)
+  "Documentation string for the command."
+  (interactive @var{spec})
+  (apply 'module-func args))
address@hidden lisp
+
+The Lisp package which goes with your module could then load the
+module using the @code{module-load} primitive (@pxref{Dynamic
+Modules}) when the package is loaded into Emacs.
+
address@hidden Module Values
address@hidden Conversion Between Lisp and Module Values
address@hidden module values, conversion
+
address@hidden @code{emacs_value} data type
+  With very few exceptions, most modules need to exchange data with
+Lisp programs that call them: accept arguments to module functions and
+return values from module functions.  For this purpose, the module
address@hidden provides the @code{emacs_value} type, which represents
+Emacs Lisp objects communicated via the @acronym{API}; it is the
+functional equivalent of the @code{Lisp_Object} type used in Emacs C
+primitives (@pxref{Writing Emacs Primitives}).  This section describes
+the parts of the module @acronym{API} that allow to create
address@hidden objects corresponding to basic Lisp data types, and
+how to access from C data in @code{emacs_value} objects that
+correspond to Lisp objects.
+
+All of the functions described below are actually @emph{function
+pointers} provided via the pointer to the environment which every
+module function accepts.  Therefore, module code should call these
+functions through the environment pointer, like this:
+
address@hidden
+emacs_env *env;  /* the environment pointer */
+env->some_function (address@hidden);
address@hidden example
+
address@hidden
+The @code{emacs_env} pointer will usually come from the first argument
+to the module function, or from the call to @code{get_environment} if
+you need the environment in the module initialization function.
+
+Most of the functions described below became available in Emacs 25,
+the first Emacs release that supported dynamic modules.  For the few
+functions that became available in later Emacs releases, we mention
+the first Emacs version that supported them.
+
+The following @acronym{API} functions extract values of various C data
+types from @code{emacs_value} objects.  They all raise the
address@hidden error condition (@pxref{Type Predicates})
+if the argument @code{emacs_value} object is not of the type expected
+by the function.  @xref{Module Nonlocal}, for details of how signaling
+errors works in Emacs modules, and how to catch error conditions
+inside the module before they are reported to Emacs.  The
address@hidden function @code{type_of} (@pxref{Module Misc, type_of})
+can be used to obtain the type of a @code{emacs_value} object.
+
address@hidden Function intmax_t extract_integer (emacs_env address@hidden, 
emacs_value @var{arg})
+This function returns the value of a Lisp integer specified by
address@hidden  The C data type of the return value, @code{intmax_t}, is
+the widest integral data type supported by the C compiler, typically
address@hidden@code{long long}}.
address@hidden deftypefn
+
address@hidden Function double extract_float (emacs_env address@hidden, 
emacs_value @var{arg})
+This function returns the value of a Lisp float specified by
address@hidden, as a C @code{double} value.
address@hidden deftypefn
+
address@hidden Function bool copy_string_contents (emacs_env address@hidden, 
emacs_value @var{arg}, char address@hidden, ptrdiff_t address@hidden)
+This function stores the UTF-8 encoded text of a Lisp string specified
+by @var{arg} in the array of @code{char} pointed by @var{buf}, which
+should have enough space to hold at least @address@hidden bytes,
+including the terminating null byte.  The argument @var{len} must not
+be a @code{NULL} pointer, and, when the function is called, it should
+point to a value that specifies the size of @var{buf} in bytes.
+
+If the buffer size specified by @address@hidden is large enough to
+hold the string's text, the function stores in @address@hidden the
+actual number of bytes copied to @var{buf}, including the terminating
+null byte, and returns @code{true}.  If the buffer is too small, the
+function raises the @code{args-out-of-range} error condition, stores
+the required number of bytes in @address@hidden, and returns
address@hidden  @xref{Module Nonlocal}, for how to handle pending error
+conditions.
+
+The argument @var{buf} can be a @code{NULL} pointer, in which case the
+function stores in @address@hidden the number of bytes required for
+storing the contents of @var{arg}, and returns @code{true}.  This is
+how you can determine the size of @var{buf} needed to store a
+particular string: first call @code{copy_string_contents} with
address@hidden as @var{buf}, then allocate enough memory to hold the
+number of bytes stored by the function in @address@hidden, and call
+the function again with address@hidden @var{buf} to actually perform
+the text copying.
address@hidden deftypefn
+
address@hidden Function emacs_value vec_get (emacs_env address@hidden, 
emacs_value @var{vector}, ptrdiff_t @var{index})
+This function returns the element of @var{vector} at @var{index}.  The
address@hidden of the first vector element is zero.  The function raises
+the @code{args-out-of-range} error condition if the value of
address@hidden is invalid.  To extract C data from the value the function
+returns, use the other extraction functions described here, as
+appropriate for the Lisp data type stored in that element of the
+vector.
address@hidden deftypefn
+
address@hidden Function ptrdiff_t vec_size (emacs_env address@hidden, 
emacs_value @var{vector})
+This function returns the number of elements in @var{vector}.
address@hidden deftypefn
+
address@hidden Function void vec_set (emacs_env address@hidden, emacs_value 
@var{vector}, ptrdiff_t @var{index}, emacs_value @var{value})
+This function stores @var{value} in the element of @var{vector} whose
+index is @var{index}.  It raises the @code{args-out-of-range} error
+condition if the value of @var{index} is invalid.
address@hidden deftypefn
+
+The following @acronym{API} functions create @code{emacs_value}
+objects from basic C data types.  They all return the created
address@hidden object.
+
address@hidden Function emacs_value make_integer (emacs_env address@hidden, 
intmax_t @var{n})
+This function takes an integer argument @var{n} and returns the
+corresponding @code{emacs_value} object.  It raises the
address@hidden error condition if the value of @var{n} cannot
+be represented as an Emacs integer, i.e.@: is not inside the limits
+set by @code{most-negative-fixnum} and @code{most-positive-fixnum}
+(@pxref{Integer Basics}).
address@hidden deftypefn
+
address@hidden Function emacs_value make_float (emacs_env address@hidden, 
double @var{d})
+This function takes a @code{double} argument @var{d} and returns the
+corresponding Emacs floating-point value.
address@hidden deftypefn
+
address@hidden Function emacs_value make_string (emacs_env address@hidden, 
const char address@hidden, ptrdiff_t @var{strlen})
+This function creates an Emacs string from C text string pointed by
address@hidden whose length in bytes, not including the terminating null
+byte, is @var{strlen}.  The original string in @var{str} can be either
+an @acronym{ASCII} string or a UTF-8 encoded address@hidden
+string; it can include embedded null bytes, and doesn't have to end in
+a terminating null byte at @address@hidden@var{strlen}]}.  The
+function raises the @code{overflow-error} error condition if
address@hidden is negative or exceeds the maximum length of an Emacs
+string.
address@hidden deftypefn
+
+The @acronym{API} does not provide functions to manipulate Lisp data
+structures, for example, create lists with @code{cons} and @code{list}
+(@pxref{Building Lists}), extract list members with @code{car} and
address@hidden (@pxref{List Elements}), create vectors with @code{vector}
+(@pxref{Vector Functions}), etc.  For these, use @code{intern} and
address@hidden, described in the next subsection, to call the
+corresponding Lisp functions.
+
+Normally, @code{emacs_value} objects have a rather short lifetime: it
+ends when the @code{emacs_env} pointer used for their creation goes
+out of scope.  Occasionally, you may need to create @dfn{global
+references}: @code{emacs_value} objects that live as long as you
+wish.  Use the following two functions to manage such objects.
+
address@hidden Function emacs_value make_global_ref (emacs_env address@hidden, 
emacs_value @var{value})
+This function returns a global reference for @var{value}.
address@hidden deftypefn
+
address@hidden Function void free_global_ref (emacs_env address@hidden, 
emacs_value @var{global_value})
+This function frees the @var{global_value} previously created by
address@hidden  The @var{global_value} is no longer valid
+after the call.  Your module code should pair each call to
address@hidden with the corresponding @code{free_global_ref}.
address@hidden deftypefn
+
address@hidden user pointer, using in module functions
+An alternative to keeping around C data structures that need to be
+passed to module functions later is to create @dfn{user pointer}
+objects.  A user pointer, or @code{user-ptr}, object is a Lisp object
+that encapsulates a C pointer and can have an associated finalizer
+function, which is called when the object is garbage-collected
+(@pxref{Garbage Collection}).  The module @acronym{API} provides
+functions to create and access @code{user-ptr} objects.  These
+functions raise the @code{wrong-type-argument} error condition if they
+are called on @code{emacs_value} that doesn't represent a
address@hidden object.
+
address@hidden Function emacs_value make_user_ptr (emacs_env address@hidden, 
emacs_finalizer @var{fin}, void address@hidden)
+This function creates and returns a @code{user-ptr} object which wraps
+the C pointer @var{ptr}.  The finalizer function @var{fin} can be a
address@hidden pointer (meaning no finalizer), or it can be a function of
+the following signature:
+
address@hidden
+typedef void (*emacs_finalizer) (void address@hidden);
address@hidden example
+
address@hidden
+If @var{fin} is not a @code{NULL} pointer, it will be called with the
address@hidden as the argument when the @code{user-ptr} object is
+garbage-collected.  Don't run any expensive code in a finalizer,
+because GC must finish quickly to keep Emacs responsive.
address@hidden deftypefn
+
address@hidden Function void *get_user_ptr (emacs_env address@hidden, 
emacs_value val)
+This function extracts the C pointer from the Lisp object represented
+by @var{val}.
address@hidden deftypefn
+
address@hidden Function void set_user_ptr (emacs_env address@hidden, 
emacs_value @var{value}, void address@hidden)
+This function sets the C pointer embedded in the @code{user-ptr}
+object represented by @var{value} to @var{ptr}.
address@hidden deftypefn
+
address@hidden Function emacs_finalizer get_user_finalizer (emacs_env 
address@hidden, emacs_value val)
+This function returns the finalizer of the @code{user-ptr} object
+represented by @var{val}, or @code{NULL} if it doesn't have a finalizer.
address@hidden deftypefn
+
address@hidden Function void set_user_finalizer (emacs_env address@hidden, 
emacs_value @var{val}, emacs_finalizer @var{fin})
+This function changes the finalizer of the @code{user-ptr} object
+represented by @var{val} to be @var{fin}.  If @var{fin} is a
address@hidden pointer, the @code{user-ptr} object will have no finalizer.
address@hidden deftypefn
+
address@hidden Module Misc
address@hidden Miscellaneous Convenience Functions for Modules
+
+  This subsection describes a few convenience functions provided by
+the module @acronym{API}.  Like the functions described in previous
+subsections, all of them are actually function pointers, and need to
+be called via the @code{emacs_env} pointer.  Description of functions
+that were introduced after Emacs 25 calls out the first version where
+they became available.
+
address@hidden Function bool eq (emacs_env address@hidden, emacs_value 
@var{val1}, emacs_value @var{val2})
+This function returns @code{true} if the Lisp objects represented by
address@hidden and @var{val2} are identical, @code{false} otherwise.  This
+is the same as the Lisp function @code{eq} (@pxref{Equality
+Predicates}), but avoids the need to intern the objects represented by
+the arguments.
+
+There are no @acronym{API} functions for other equality predicates, so
+you will need to use @code{intern} and @code{funcall}, described
+below, to perform more complex equality tests.
address@hidden deftypefn
+
address@hidden Function bool is_not_nil (emacs_env address@hidden, emacs_value 
@var{val})
+This function tests whether the Lisp object represented by @var{val}
+is address@hidden; it returns @code{true} or @code{false} accordingly.
+
+Note that you could implement an equivalent test by using
address@hidden to get an @code{emacs_value} representing @code{nil},
+then use @code{eq}, described above, to test for equality.  But using
+this function is more convenient.
address@hidden deftypefn
+
address@hidden Function emacs_value type_of (emacs_env address@hidden, 
emacs_value @code{object})
+This function returns the type of @var{object} as a value that
+represents a symbol: @code{string} for a string, @code{integer} for an
+integer, @code{process} for a process, etc.  @xref{Type Predicates}.
+You can use @code{intern} and @code{eq} to compare against known type
+symbols, if your code needs to depend on the object type.
address@hidden deftypefn
+
address@hidden
address@hidden Function emacs_value intern (emacs_env address@hidden, const 
char *name)
+This function returns an interned Emacs symbol whose name is
address@hidden, which should be an @acronym{ASCII} null-terminated string.
+It creates a new symbol if one does not already exist.
+
+Together with @code{funcall}, described below, this function provides
+a means for invoking any Lisp-callable Emacs function, provided that
+its name is a pure @acronym{ASCII} string.  For example, here's how to
+intern a symbol whose name @code{name_str} is address@hidden, by
+calling the more powerful Emacs @code{intern} function
+(@pxref{Creating Symbols}):
+
address@hidden
+emacs_value fintern = env->intern (env, "intern");
+emacs_value sym_name =
+  env->make_string (env, name_str, strlen (name_str));
+emacs_value intern_args[] = @{ sym_name, env->intern (env, "nil") @};
+emacs_value symbol = env->funcall (env, fintern, 2, intern_args);
address@hidden example
+
address@hidden deftypefn
+
address@hidden Function emacs_value funcall (emacs_env address@hidden, 
emacs_value @var{func}, ptrdiff_t @var{nargs}, emacs_value address@hidden)
+This function calls the specified @var{func} passing it @var{nargs}
+arguments from the array pointed to by @var{args}.  The argument
address@hidden can be a function symbol (e.g., returned by @code{intern}
+described above), a module function returned by @code{make_function}
+(@pxref{Module Functions}), a subroutine written in C, etc.  If
address@hidden is zero, @var{args} can be a @code{NULL} pointer.
+
+The function returns the value that @var{func} returned.
address@hidden deftypefn
+
+If your module includes potentially long-running code, it is a good
+idea to check from time to time in that code whether the user wants to
+quit, e.g., by typing @kbd{C-g} (@pxref{Quitting}).  The following
+function, which is available since Emacs 26.1, is provided for that
+purpose.
+
address@hidden
address@hidden Function bool should_quit (emacs_env address@hidden)
+This function returns @code{true} if the user wants to quit.  In that
+case, we recommend that your module function aborts any on-going
+processing and returns as soon as possible.
address@hidden deftypefn
+
address@hidden Module Nonlocal
address@hidden Nonlocal Exits in Modules
address@hidden nonlocal exits, in modules
+
+  Emacs Lisp supports nonlocal exits, whereby program control is
+transfered from one point in a program to another remote point.
address@hidden Exits}.  Thus, Lisp functions called by your module
+might exit nonlocally by calling @code{signal} or @code{throw}, and
+your module functions must handle such nonlocal exits properly.  Such
+handling is needed because C programs will not automatically release
+resources and perform other cleanups in these cases; your module code
+must itself do it.  The module @acronym{API} provides facilities for
+that, described in this subsection.  They are generally available
+since Emacs 25; those of them that became available in later releases
+explicitly call out the first Emacs version where they became part of
+the @acronym{API}.
+
+When some Lisp code called by a module function signals an error or
+throws, the nonlocal exit is trapped, and the pending exit and its
+associated data are stored in the environment.  Whenever a nonlocal
+exit is pending in the environment, any module @acronym{API} function
+called with a pointer to that environment will return immediately
+without any processing (the functions @code{non_local_exit_check},
address@hidden, and @code{non_local_exit_clear} are
+exceptions from this rule).  If your module function then does nothing
+and returns to Emacs, a pending nonlocal exit will cause Emacs to act
+on it: signal an error or throw to the corresponding @code{catch}.
+
+So the simplest ``handling'' of nonlocal exits in module functions is
+to do nothing special and let the rest of your code to run as if
+nothing happened.  However, this can cause two classes of problems:
+
address@hidden @minus
address@hidden
+Your module function might use uninitialized or undefined values,
+since @acronym{API} functions return immediately without producing the
+expected results.
+
address@hidden
+Your module might leak resources, because it might not have the
+opportunity to release them.
address@hidden itemize
+
+Therefore, we recommend that your module functions check for nonlocal
+exit conditions and recover from them, using the functions described
+below.
+
address@hidden Function enum emacs_funcall_exit non_local_exit_check (emacs_env 
address@hidden)
+This function returns the kind of nonlocal exit condition stored in
address@hidden  The possible values are:
+
address@hidden address@hidden, enumeration}
address@hidden @code
address@hidden emacs_funcall_exit_return
+The last @acronym{API} function exited normally.
address@hidden emacs_funcall_exit_signal
+The last @acronym{API} function signaled an error.
address@hidden emacs_funcall_exit_throw
+The last @acronym{API} function exited via @code{throw}.
address@hidden vtable
address@hidden deftypefn
+
address@hidden Function emacs_funcall_exit non_local_exit_get (emacs_env 
address@hidden, emacs_value address@hidden, emacs_value address@hidden)
+This function returns the kind of nonlocal exit condition stored in
address@hidden, like @code{non_local_exit_check} does, but it also returns
+the full information about the nonlocal exit, if any.  If the return
+value is @code{emacs_funcall_exit_signal}, the function stores the
+error symbol in @address@hidden and the error data in
address@hidden@var{data}} (@pxref{Signaling Errors}).  If the return value is
address@hidden, the function stores the @code{catch}
+tag symbol in @address@hidden and the @code{throw} value in
address@hidden@var{data}}.  The function doesn't store anything in memory
+pointed by these arguments when the return value is
address@hidden
address@hidden deftypefn
+
+You should check nonlocal exit conditions where it matters: before you
+allocated some resource or after you allocated a resource that might
+need freeing, or where a failure means further processing is
+impossible or infeasible.
+
+Once your module function detected that a nonlocal exit is pending, it
+can either return to Emacs (after performing the necessary local
+cleanup), or it can attempt to recover from the nonlocal exit.  The
+following @acronym{API} functions will help with these tasks.
+
address@hidden Function void non_local_exit_clear (emacs_env address@hidden)
+This function clears the pending nonlocal exit conditions and data
+from @var{env}.  After calling it, the module @acronym{API} functions
+will work normally.  Use this function if your module function can
+recover from nonlocal exits of the Lisp functions it calls and
+continue, and also before calling any of the following two functions
+(or any other @acronym{API} functions, if you want them to perform
+their intended processing when a nonlocal exit is pending).
address@hidden deftypefn
+
address@hidden Function void non_local_exit_throw (emacs_env address@hidden, 
emacs_value @var{tag}, emacs_value @var{value})
+This function throws to the Lisp @code{catch} symbol represented by
address@hidden, passing it @var{value} as the value to return.  Your module
+function should in general return soon after calling this function.
+One use of this function is when you want to re-throw a non-local exit
+from one of the called @acronym{API} or Lisp functions.
address@hidden deftypefn
+
address@hidden Function void non_local_exit_signal (emacs_env address@hidden, 
emacs_value @var{error}, emacs_value @var{data})
+This function signals the error represented by @var{error} with the
+specified error data @var{data}.  The module function should return
+soon after calling this function.  This function could be useful,
+e.g., for signaling errors from module functions to Emacs.
address@hidden deftypefn
+
+
 @node Object Internals
 @section Object Internals
 @cindex object internals
diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi
index 82c133d..6f15cd9 100644
--- a/doc/lispref/loading.texi
+++ b/doc/lispref/loading.texi
@@ -1139,8 +1139,6 @@ Features}).
 @section Emacs Dynamic Modules
 @cindex dynamic modules
 
address@hidden FIXME: This is intentionally incomplete, as the module 
integration
address@hidden is not yet finished.  To be refined later.
   A @dfn{dynamic Emacs module} is a shared library that provides
 additional functionality for use in Emacs Lisp programs, just like a
 package written in Emacs Lisp would.
@@ -1162,30 +1160,43 @@ Every dynamic module should export a C-callable 
function named
 @code{load} or @code{require} which loads the module.  It should also
 export a symbol named @code{plugin_is_GPL_compatible} to indicate that
 its code is released under the GPL or compatible license; Emacs will
-refuse to load modules that don't export such a symbol.
+signal an error if your program tries to load modules that don't
+export such a symbol.
 
 If a module needs to call Emacs functions, it should do so through the
-API defined and documented in the header file @file{emacs-module.h}
-that is part of the Emacs distribution.
address@hidden (Application Programming Interface) defined and
+documented in the header file @file{emacs-module.h} that is part of
+the Emacs distribution.  @xref{Writing Dynamic Modules}, for details
+of using that API when writing your own modules.
 
 @cindex user-ptr object
address@hidden user pointer object
 Modules can create @code{user-ptr} Lisp objects that embed pointers to
 C struct's defined by the module.  This is useful for keeping around
 complex data structures created by a module, to be passed back to the
 module's functions.  User-ptr objects can also have associated
 @dfn{finalizers} -- functions to be run when the object is GC'ed; this
 is useful for freeing any resources allocated for the underlying data
-structure, such as memory, open file descriptors, etc.
+structure, such as memory, open file descriptors, etc.  @xref{Module
+Values}.
 
 @defun user-ptrp object
 This function returns @code{t} if its argument is a @code{user-ptr}
 object.
 @end defun
 
address@hidden module-load file
+Emacs calls this low-level primitive to load a module from the
+specified @var{file} and perform the necessary initialization of the
+module.  This is the primitive which makes sure the module exports the
address@hidden symbol, calls the module's
address@hidden function, and signals an error if that
+function returns an error indication, or if the use typed @kbd{C-g}
+during the initialization.  If the initialization succeeds,
address@hidden returns @code{t}.  Note that @var{file} must
+already have the proper file-name extension, as this function doesn't
+try looking for files with known extensions, unlike @code{load}.
address@hidden defun
+
 Loadable modules in Emacs are enabled by using the
 @kbd{--with-modules} option at configure time.
-
-If you write your own dynamic modules, you may wish to verify their
-conformance to the Emacs dynamic module API.  Invoking Emacs with the
address@hidden option will help you in this matter.
address@hidden Options,,,emacs, The GNU Emacs Manual}.
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index 64c327c..cb33757 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -112,24 +112,29 @@ activate the packages in the latter case, 
@code{package-activate-all}
 should be called explicitly (e.g., via the @samp{--funcall} option).
 
 @vindex address@hidden, and startup}
address@hidden window-system-initialization-alist
address@hidden window-system-initialization
 @item
 If not running in batch mode, it initializes the window system that
 the variable @code{initial-window-system} specifies (@pxref{Window
-Systems, initial-window-system}).  The initialization function for
-each supported window system is specified by
address@hidden  If the value
-of @code{initial-window-system} is @var{windowsystem}, then the
-appropriate initialization function is defined in the file
address@hidden/@var{windowsystem}-win.el}.  This file should have been
-compiled into the Emacs executable when it was built.
+Systems, initial-window-system}).  The initialization function,
address@hidden, is a @dfn{generic function}
+(@pxref{Generic Functions}) whose actual implementation is different
+for each supported window system.  If the value of
address@hidden is @var{windowsystem}, then the
+appropriate implementation of the initialization function is defined
+in the file @file{term/@var{windowsystem}-win.el}.  This file should
+have been compiled into the Emacs executable when it was built.
 
 @item
 It runs the normal hook @code{before-init-hook}.
 
 @item
-If appropriate, it creates a graphical frame.  This is not done in
-batch (noninteractive) or daemon mode.
+If appropriate, it creates a graphical frame.  As part of creating the
+graphical frame, it initializes the window system specified by
address@hidden and @code{default-frame-alist}
+(@pxref{Initial Parameters}) for the graphical frame, by calling the
address@hidden function for that window system.
+This is not done in batch (noninteractive) or daemon mode.
 
 @item
 It initializes the initial frame's faces, and sets up the menu bar
@@ -1841,7 +1846,7 @@ special object that stores the information about the next 
invocation
 times and the function to invoke.
 
 @defun timerp object
-This predicate function returns address@hidden of @code{object} is a
+This predicate function returns address@hidden if @code{object} is a
 timer.
 @end defun
 
diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi
index e1113e3..d88c7fb 100644
--- a/doc/lispref/processes.texi
+++ b/doc/lispref/processes.texi
@@ -598,8 +598,8 @@ communication is only partially asynchronous: Emacs sends 
data to the
 process only when certain functions are called, and Emacs accepts data
 from the process only while waiting for input or for a time delay.
 
address@hidden pty
address@hidden pipe
address@hidden pty, when to use for subprocess communications
address@hidden pipe, when to use for subprocess communications
   An asynchronous process is controlled either via a @dfn{pty}
 (pseudo-terminal) or a @dfn{pipe}.  The choice of pty or pipe is made
 when creating the process, by default based on the value of the
@@ -609,11 +609,13 @@ Shell mode, because they allow for job control 
(@kbd{C-c}, @kbd{C-z},
 etc.)@: between the process and its children, and because interactive
 programs treat ptys as terminal devices, whereas pipes don't support
 these features.  However, for subprocesses used by Lisp programs for
-internal purposes, it is often better to use a pipe, because pipes are
-more efficient, and because they are immune to stray character
-injections that ptys introduce for large (around 500 byte) messages.
-Also, the total number of ptys is limited on many systems and it is
-good not to waste them.
+internal purposes (i.e., no user interaction with the subprocess is
+required), where significant amounts of data need to be exchanged
+between the subprocess and the Lisp program, it is often better to use
+a pipe, because pipes are more efficient, and because they are immune
+to stray character injections that ptys introduce for large (around
+500 byte) messages.  Also, the total number of ptys is limited on many
+systems, and it is good not to waste them unnecessarily.
 
 @defun make-process &rest args
 This function is the basic low-level primitive for starting
@@ -666,7 +668,9 @@ pipe, or @code{nil} to use the default derived from the 
value of the
 @code{process-connection-type} variable.  This parameter and the value
 of @code{process-connection-type} are ignored if a address@hidden
 value is specified for the @code{:stderr} parameter; in that case, the
-type will always be @code{pipe}.
+type will always be @code{pipe}.  On systems where ptys are not
+available (MS-Windows), this parameter is likewise ignored, and pipes
+are used unconditionally.
 
 @item :noquery @var{query-flag}
 Initialize the process query flag to @var{query-flag}.
@@ -873,7 +877,8 @@ around the call to these functions.
 Note that the value of this variable is ignored when
 @code{make-process} is called with a address@hidden value of the
 @code{:stderr} parameter; in that case, Emacs will communicate with
-the process using pipes.
+the process using pipes.  It is also ignored if ptys are unavailable
+(MS-Windows).
 
 @smallexample
 @group
diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi
index 6a6f4d5..5547160 100644
--- a/doc/lispref/sequences.texi
+++ b/doc/lispref/sequences.texi
@@ -1049,15 +1049,18 @@ that @var{sequence} can be a list, vector or string.  
This is
 primarily useful for side-effects.
 @end defmac
 
address@hidden seq-let arguments sequence address@hidden
address@hidden
address@hidden seq-let var-sequence val-sequence address@hidden
 @cindex sequence destructuring
-  This macro binds the variables defined in @var{arguments} to the
-elements of @var{sequence}.  @var{arguments} can themselves include
-sequences, allowing for nested destructuring.
+  This macro binds the variables defined in @var{var-sequence} to the
+values that are the corresponding elements of @var{val-sequence}.
+This is known as @dfn{destructuring binding}.  The elements of
address@hidden can themselves include sequences, allowing for
+nested destructuring.
 
-The @var{arguments} sequence can also include the @code{&rest} marker
-followed by a variable name to be bound to the rest of
address@hidden
+The @var{var-sequence} sequence can also include the @code{&rest}
+marker followed by a variable name to be bound to the rest of
address@hidden
 
 @example
 @group
@@ -1081,6 +1084,9 @@ followed by a variable name to be bound to the rest of
 @end group
 @result{} [3 4]
 @end example
+
+The @code{pcase} patterns provide an alternative facility for
+destructuring binding, see @ref{Destructuring with pcase Patterns}.
 @end defmac
 
 @defun seq-random-elt sequence
diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index 7cfa5ea..772bcdf 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -25,9 +25,7 @@ is displayed in windows.
 * Cyclic Window Ordering::  Moving around the existing windows.
 * Buffers and Windows::     Each window displays the contents of a buffer.
 * Switching Buffers::       Higher-level functions for switching to a buffer.
-* Choosing Window::         How to choose a window for displaying a buffer.
-* Display Action Functions:: Subroutines for @code{display-buffer}.
-* Choosing Window Options:: Extra options affecting how buffers are displayed.
+* Displaying Buffers::      Displaying a buffer in a suitable window.
 * Window History::          Each window remembers the buffers displayed in it.
 * Dedicated Windows::       How to avoid displaying another buffer in
                               a specific window.
@@ -1542,11 +1540,11 @@ direction as the existing window combination 
(otherwise, a new internal
 window is created anyway).
 
 @item window-size
-This means that @code{display-buffer} makes a new parent window when it
-splits a window and is passed a @code{window-height} or
address@hidden entry in the @var{alist} argument (@pxref{Display
-Action Functions}).  Otherwise, window splitting behaves as for a value
-of @code{nil}.
+This means that @code{display-buffer} makes a new parent window when
+it splits a window and is passed a @code{window-height} or
address@hidden entry in the @var{alist} argument (@pxref{Buffer
+Display Action Functions}).  Otherwise, window splitting behaves as
+for a value of @code{nil}.
 
 @item temp-buffer-resize
 In this case @code{with-temp-buffer-window} makes a new parent window
@@ -1879,7 +1877,7 @@ most recently used one (@pxref{Cyclic Window Ordering}).
 @cindex ordering of windows, cyclic
 @cindex window ordering, cyclic
 
-  When you use the command @kbd{C-x o} (@code{other-window}) to select
+  When you use the command @address@hidden o}} (@code{other-window}) to select
 some other window, it moves through live windows in a specific order.
 For any given configuration of windows, this order never varies.  It
 is called the @dfn{cyclic ordering of windows}.
@@ -1899,7 +1897,7 @@ if omitted or @code{nil}, it defaults to the selected 
window.
 The optional argument @var{minibuf} specifies whether minibuffer windows
 should be included in the cyclic ordering.  Normally, when @var{minibuf}
 is @code{nil}, a minibuffer window is included only if it is currently
-active; this matches the behavior of @kbd{C-x o}.  (Note that a
+active; this matches the behavior of @address@hidden o}}.  (Note that a
 minibuffer window is active as long as its minibuffer is in use; see
 @ref{Minibuffers}).
 
@@ -2083,7 +2081,8 @@ variables in the specified buffer.  However, if the 
optional argument
 @var{keep-margins} is address@hidden, it leaves @var{window}'s display
 margins, fringes and scroll bar settings alone.
 
-When writing an application, you should normally use the higher-level
+When writing an application, you should normally use
address@hidden (@pxref{Choosing Window}) or the higher-level
 functions described in @ref{Switching Buffers}, instead of calling
 @code{set-window-buffer} directly.
 
@@ -2168,7 +2167,6 @@ frame on its terminal, the buffer is replaced anyway.
 @node Switching Buffers
 @section Switching to a Buffer in a Window
 @cindex switching to a buffer
address@hidden displaying a buffer
 
 This section describes high-level functions for switching to a specified
 buffer in some window.  In general, ``switching to a buffer'' means to
@@ -2327,32 +2325,70 @@ unless @var{norecord} is address@hidden
 @end deffn
 
 
address@hidden Displaying Buffers
address@hidden Displaying a Buffer in a Suitable Window
address@hidden buffer display
address@hidden displaying a buffer
+
+This section describes lower-level functions Emacs uses to find or
+create a window for displaying a specified buffer.  The common
+workhorse of these functions is @code{display-buffer} which eventually
+handles all incoming requests for buffer display (@pxref{Choosing
+Window}).
+
+   @code{display-buffer} delegates the task of finding a suitable
+window to so-called action functions (@pxref{Buffer Display Action
+Functions}).  First, @code{display-buffer} compiles a so-called action
+alist---a special association list that action functions can use to
+fine-tune their behavior.  Then it passes that alist on to each action
+function it calls (@pxref{Buffer Display Action Alists}).
+
+   The behavior of @code{display-buffer} is highly customizable.  To
+understand how customizations are used in practice, you may wish to
+study examples illustrating the order of precedence which
address@hidden uses to call action functions (@pxref{Precedence
+of Action Functions}).  To avoid conflicts between Lisp programs
+calling @code{display-buffer} and user customizations of its behavior,
+it may make sense to follow a number of guidelines which are sketched
+in the final part of this section (@pxref{The Zen of Buffer Display}).
+
address@hidden
+* Choosing Window::         How to choose a window for displaying a buffer.
+* Buffer Display Action Functions:: Support functions for buffer display.
+* Buffer Display Action Alists:: Alists for fine-tuning buffer display.
+* Choosing Window Options:: Extra options affecting how buffers are displayed.
+* Precedence of Action Functions:: Examples to explain the precedence of
+                              action functions.
+* The Zen of Buffer Display:: How to avoid that buffers get lost in between
+                              windows.
address@hidden menu
+
+
 @node Choosing Window
address@hidden Choosing a Window for Display
address@hidden Choosing a Window for Displaying a Buffer
 
-  The command @code{display-buffer} flexibly chooses a window for
+The command @code{display-buffer} flexibly chooses a window for
 display, and displays a specified buffer in that window.  It can be
 called interactively, via the key binding @kbd{C-x 4 C-o}.  It is also
 used as a subroutine by many functions and commands, including
 @code{switch-to-buffer} and @code{pop-to-buffer} (@pxref{Switching
 Buffers}).
 
address@hidden buffer display display action
 @cindex display action
address@hidden action function, for @code{display-buffer}
address@hidden action alist, for @code{display-buffer}
   This command performs several complex steps to find a window to
 display in.  These steps are described by means of @dfn{display
-actions}, which have the form @code{(@var{function} . @var{alist})}.
-Here, @var{function} is either a function or a list of functions,
-which we refer to as @dfn{action functions}; @var{alist} is an
-association list, which we refer to as an @dfn{action alist}.
+actions}, which have the form @code{(@var{functions} . @var{alist})}.
+Here, @var{functions} is either a single function or a list of
+functions, referred to as ``action functions'' (@pxref{Buffer Display
+Action Functions}); and @var{alist} is an association list, referred
+to as ``action alist'' (@pxref{Buffer Display Action Alists}).
address@hidden Zen of Buffer Display}, for samples of display actions.
 
   An action function accepts two arguments: the buffer to display and
 an action alist.  It attempts to display the buffer in some window,
 picking or creating a window according to its own criteria.  If
 successful, it returns the window; otherwise, it returns @code{nil}.
address@hidden Action Functions}, for a list of predefined action
-functions.
 
   @code{display-buffer} works by combining display actions from
 several sources, and calling the action functions in turn, until one
@@ -2363,12 +2399,14 @@ value.
 This command makes @var{buffer-or-name} appear in some window, without
 selecting the window or making the buffer current.  The argument
 @var{buffer-or-name} must be a buffer or the name of an existing
-buffer.  The return value is the window chosen to display the buffer.
+buffer.  The return value is the window chosen to display the buffer,
+or @code{nil} if no suitable window was found.
 
 The optional argument @var{action}, if address@hidden, should normally
 be a display action (described above).  @code{display-buffer} builds a
 list of action functions and an action alist, by consolidating display
-actions from the following sources (in order):
+actions from the following sources (in order of their precedence,
+from highest to lowest):
 
 @itemize
 @item
@@ -2388,40 +2426,65 @@ The constant @code{display-buffer-fallback-action}.
 @end itemize
 
 @noindent
-Each action function is called in turn, passing the buffer as the
-first argument and the combined action alist as the second argument,
-until one of the functions returns address@hidden  The caller can
-pass @code{(allow-no-window . t)} as an element of the action alist to
-indicate its readiness to handle the case of not displaying the
-buffer in a window.
+In practice this means that @code{display-buffer} builds a list of all
+action functions specified by these display actions.  The first
+element of this list is the first action function specified by
address@hidden, if any.  Its last element is
address@hidden last action function
+specified by @code{display-buffer-fallback-action}.  Duplicates are
+not removed from this list---hence one and the same action function
+may be called multiple times during one call of @code{display-buffer}.
+
address@hidden calls the action functions specified by this
+list in turn, passing the buffer as the first argument and the
+combined action alist as the second argument, until one of the
+functions returns address@hidden  @xref{Precedence of Action
+Functions}, for examples how display actions specified by different
+sources are processed by @code{display-buffer}.
+
+Note that the second argument is always the list of @emph{all} action
+alist entries specified by the sources named above.  Hence, the first
+element of that list is the first action alist entry specified by
address@hidden, if any.  Its last element is
+the last alist entry of @code{display-buffer-base-action}, if any (the
+action alist of @code{display-buffer-fallback-action} is empty).
+
+Note also, that the combined action alist may contain duplicate
+entries and entries for the same key with different values.  As a
+rule, action functions always use the first association of a key they
+find.  Hence, the association an action function uses is not
+necessarily the association provided by the display action that
+specified that action function,
 
 The argument @var{action} can also have a address@hidden, non-list
 value.  This has the special meaning that the buffer should be
 displayed in a window other than the selected one, even if the
 selected window is already displaying it.  If called interactively
-with a prefix argument, @var{action} is @code{t}.
+with a prefix argument, @var{action} is @code{t}.  Lisp programs
+should always supply a list value.
 
 The optional argument @var{frame}, if address@hidden, specifies which
 frames to check when deciding whether the buffer is already displayed.
-It is equivalent to adding an element @code{(reusable-frames
-. @var{frame})} to the action alist of @var{action}.  @xref{Display
-Action Functions}.
+It is equivalent to adding an element @address@hidden(reusable-frames
+. @var{frame})}} to the action alist of @var{action} (@pxref{Buffer
+Display Action Alists}).  The @var{frame} argument is provided for
+compatibility reasons, Lisp programs should not use it.
 @end deffn
 
 @defvar display-buffer-overriding-action
 The value of this variable should be a display action, which is
 treated with the highest priority by @code{display-buffer}.  The
-default value is empty, i.e., @code{(nil . nil)}.
+default value is an empty display action, i.e., @address@hidden(nil . nil)}}.
 @end defvar
 
 @defopt display-buffer-alist
 The value of this option is an alist mapping conditions to display
 actions.  Each condition may be either a regular expression matching a
 buffer name or a function that takes two arguments: a buffer name and
-the @var{action} argument passed to @code{display-buffer}.  If the name
-of the buffer passed to @code{display-buffer} either matches a regular
-expression in this alist or the function specified by a condition
-returns address@hidden, then @code{display-buffer} uses the
+the @var{action} argument passed to @code{display-buffer}.  If either
+the name of the buffer passed to @code{display-buffer} matches a
+regular expression in this alist, or the function specified by a
+condition returns address@hidden, then @code{display-buffer} uses the
 corresponding display action to display the buffer.
 @end defopt
 
@@ -2437,13 +2500,19 @@ This display action specifies the fallback behavior for
 @end defvr
 
 
address@hidden Display Action Functions
address@hidden Action Functions for @code{display-buffer}
address@hidden Buffer Display Action Functions
address@hidden Action Functions for Buffer Display
address@hidden buffer display action function
address@hidden action function, for buffer display
+
+An @dfn{action function} is a function @code{display-buffer} calls for
+choosing a window to display a buffer.  Action functions take two
+arguments: @var{buffer}, the buffer to display, and @var{alist}, an
+action alist (@pxref{Buffer Display Action Alists}).  They are
+supposed to return a window displaying @var{buffer} if they succeed
+and @code{nil} if they fail.
 
-The following basic action functions are defined in Emacs.  Each of
-these functions takes two arguments: @var{buffer}, the buffer to
-display, and @var{alist}, an action alist.  Each action function
-returns the window if it succeeds, and @code{nil} if it fails.
+   The following basic action functions are defined in Emacs.
 
 @defun display-buffer-same-window buffer alist
 This function tries to display @var{buffer} in the selected window.
@@ -2453,57 +2522,99 @@ to another buffer (@pxref{Dedicated Windows}).  It also 
fails if
 @end defun
 
 @defun display-buffer-reuse-window buffer alist
-This function tries to display @var{buffer} by finding a window
-that is already displaying it.
+This function tries to display @var{buffer} by finding a window that
+is already displaying it.
 
 If @var{alist} has a address@hidden @code{inhibit-same-window} entry,
-the selected window is not eligible for reuse.  If @var{alist}
-contains a @code{reusable-frames} entry, its value determines which
-frames to search for a reusable window:
-
address@hidden @bullet
address@hidden
address@hidden means consider windows on the selected frame.
-(Actually, the last non-minibuffer frame.)
address@hidden
address@hidden means consider windows on all frames.
address@hidden
address@hidden means consider windows on all visible frames.
address@hidden
-0 means consider windows on all visible or iconified frames.
address@hidden
-A frame means consider windows on that frame only.
address@hidden itemize
-
-Note that these meanings differ slightly from those of the
address@hidden argument to @code{next-window} (@pxref{Cyclic Window
-Ordering}).
-
-If @var{alist} contains no @code{reusable-frames} entry, this function
-normally searches just the selected frame; however, if the variable
address@hidden is address@hidden, it searches all frames on the
-current terminal.  @xref{Choosing Window Options}.
-
-If this function chooses a window on another frame, it makes that frame
-visible and, unless @var{alist} contains an @code{inhibit-switch-frame}
-entry (@pxref{Choosing Window Options}), raises that frame if necessary.
+the selected window is not eligible for reuse.  The set of frames to
+search for a window already displaying @var{buffer} can be specified
+with the help of the @code{reusable-frames} action alist entry.  If
address@hidden contains no @code{reusable-frames} entry, this function
+searches just the selected frame.
+
+If this function chooses a window on another frame, it makes that
+frame visible and, unless @var{alist} contains an
address@hidden entry, raises that frame if necessary.
 @end defun
 
 @defun display-buffer-reuse-mode-window buffer alist
 This function tries to display @var{buffer} by finding a window
 that is displaying a buffer in a given mode.
 
-If @var{alist} contains a @code{mode} entry, its value is a major mode
-(a symbol) or a list of major modes.  If @var{alist} contains no
address@hidden entry, the current major mode of @var{buffer} is used.  A
-window is a candidate if it displays a buffer that derives from one of
-the given modes.
+If @var{alist} contains a @code{mode} entry, its value specifes a
+major mode (a symbol) or a list of major modes.  If @var{alist}
+contains no @code{mode} entry, the current major mode of @var{buffer}
+is used instead.  A window is a candidate if it displays a buffer
+whose mode derives from one of the modes specified thusly.
 
-The behavior is also controlled by entries for
+The behavior is also controlled by @var{alist} entries for
 @code{inhibit-same-window}, @code{reusable-frames} and
address@hidden as is done in the function
address@hidden
address@hidden, like @code{display-buffer-reuse-window}
+does.
address@hidden defun
+
address@hidden display-buffer-pop-up-window buffer alist
+This function tries to display @var{buffer} by splitting the largest
+or least recently-used window (usually located on the selected frame).
+It actually performs the split by calling the function specified by
address@hidden (@pxref{Choosing Window
+Options}).
+
+The size of the new window can be adjusted by supplying
address@hidden and @code{window-width} entries in @var{alist}.
+If @var{alist} contains a @code{preserve-size} entry, Emacs will also
+try to preserve the size of the new window during future resize
+operations (@pxref{Preserving Window Sizes}).
+
+This function fails if no window can be split.  More often than not,
+this happens because no window is large enough to allow splitting.
+Setting @code{split-height-threshold} or @code{split-width-threshold}
+to lower values may help in this regard.  Spliting also fails when the
+selected frame has an @code{unsplittable} frame parameter;
address@hidden Parameters}.
address@hidden defun
+
address@hidden display-buffer-in-previous-window buffer alist
+This function tries to display @var{buffer} in a window where it was
+previously displayed.  If @var{alist} has a address@hidden
address@hidden entry, the selected window is not eligible
+for reuse.  If @var{alist} contains a @code{reusable-frames} entry,
+its value determines which frames to search for a suitable window.
 
+If @var{alist} has a @code{previous-window} entry and the window
+specified by that entry is live and not dedicated to another buffer,
+that window will be preferred, even if it never showed @var{buffer}
+before.
address@hidden defun
+
address@hidden display-buffer-use-some-window buffer alist
+This function tries to display @var{buffer} by choosing an existing
+window and displaying the buffer in that window.  It can fail if all
+windows are dedicated to other buffers (@pxref{Dedicated Windows}).
address@hidden defun
+
address@hidden display-buffer-below-selected buffer alist
+This function tries to display @var{buffer} in a window below the
+selected window.  If there is a window below the selected one and that
+window already displays @var{buffer}, it reuses that window.
+
+If there is no such window, this function tries to create a new window
+by splitting the selected one, and displays @var{buffer} there.  It will
+also try to adjust that window's size provided @var{alist} contains a
+suitable @code{window-height} or @code{window-width} entry, see above.
+
+If splitting the selected window fails and there is a non-dedicated
+window below the selected one showing some other buffer, this function
+tries to use that window for showing @var{buffer}.
address@hidden defun
+
address@hidden display-buffer-at-bottom buffer alist
+This function tries to display @var{buffer} in a window at the bottom
+of the selected frame.
+
+This either tries to split the window at the bottom of the frame or
+the frame's root window, or to reuse an existing window at the bottom
+of the selected frame.
 @end defun
 
 @defun display-buffer-pop-up-frame buffer alist
@@ -2511,37 +2622,37 @@ This function creates a new frame, and displays the 
buffer in that
 frame's window.  It actually performs the frame creation by calling
 the function specified in @code{pop-up-frame-function}
 (@pxref{Choosing Window Options}).  If @var{alist} contains a
address@hidden entry, the associated value
-is added to the newly created frame's parameters.
address@hidden entry, the associated value is added to
+the newly created frame's parameters.
 @end defun
 
 @defun display-buffer-in-child-frame buffer alist
 This function tries to display @var{buffer} in a child frame
-(@pxref{Child Frames}) of the selected frame, either reusing an existing
-child frame or by making a new one.  If @var{alist} has a address@hidden
address@hidden entry, the corresponding value is an alist
-of frame parameters to give the new frame.  A @code{parent-frame}
-parameter specifying the selected frame is provided by default.  If the
-child frame should be or become the child of another frame, a
-corresponding entry must be added to @var{alist}.
+(@pxref{Child Frames}) of the selected frame, either reusing an
+existing child frame or by making a new one.  If @var{alist} has a
address@hidden @code{child-frame-parameters} entry, the corresponding
+value is an alist of frame parameters to give the new frame.  A
address@hidden parameter specifying the selected frame is
+provided by default.  If the child frame should become the child of
+another frame, a corresponding entry must be added to @var{alist}.
 
 The appearance of child frames is largely dependent on the parameters
 provided via @var{alist}.  It is advisable to use at least ratios to
 specify the size (@pxref{Size Parameters}) and the position
-(@pxref{Position Parameters}) of the child frame and to add the
address@hidden in order to make sure that the child frame remains
-visible.  For other parameters that should be considered see @ref{Child
-Frames}.
+(@pxref{Position Parameters}) of the child frame, and to add a
address@hidden parameter (@pxref{Frame Interaction Parameters}), in
+order to make sure that the child frame remains visible.  For other
+parameters that should be considered see @ref{Child Frames}.
 @end defun
 
 @defun display-buffer-use-some-frame buffer alist
-This function tries to display @var{buffer} by trying to find a
-frame that meets a predicate (by default any frame other than the
-current frame).
+This function tries to display @var{buffer} by finding a frame that
+meets a predicate (by default any frame other than the selected
+frame).
 
-If this function chooses a window on another frame, it makes that frame
-visible and, unless @var{alist} contains an @code{inhibit-switch-frame}
-entry (@pxref{Choosing Window Options}), raises that frame if necessary.
+If this function chooses a window on another frame, it makes that
+frame visible and, unless @var{alist} contains an
address@hidden entry, raises that frame if necessary.
 
 If @var{alist} has a address@hidden @code{frame-predicate} entry, its
 value is a function taking one argument (a frame), returning
@@ -2549,237 +2660,281 @@ address@hidden if the frame is a candidate; this 
function replaces the
 default predicate.
 
 If @var{alist} has a address@hidden @code{inhibit-same-window} entry,
-the selected window is used; thus if the selected frame has a single
-window, it is not used.
+the selected window is not used; thus if the selected frame has a
+single window, it is not used.
 @end defun
 
address@hidden display-buffer-pop-up-window buffer alist
-This function tries to display @var{buffer} by splitting the largest
-or least recently-used window (typically one on the selected frame).
-It actually performs the split by calling the function specified in
address@hidden (@pxref{Choosing Window
-Options}).
address@hidden display-buffer-no-window buffer alist
+If @var{alist} has a address@hidden @code{allow-no-window} entry, then
+this function does not display @var{buffer} and returns the symbol
address@hidden  This constitutes the only exception to the convention
+that an action function returns either @code{nil} or a window showing
address@hidden  If @var{alist} has no such @code{allow-no-window}
+entry, this function returns @code{nil}.
+
+If this function returns @code{fail}, @code{display-buffer} will skip
+the execution of any further display actions and return @code{nil}
+immediately.  If this function returns @code{nil},
address@hidden will continue with the next display action, if
+any.
 
-The size of the new window can be adjusted by supplying
address@hidden and @code{window-width} entries in @var{alist}.  To
-adjust the window's height, use an entry whose @sc{car} is
address@hidden and whose @sc{cdr} is one of:
+It is assumed that when a caller of @code{display-buffer} specifies a
address@hidden @code{allow-no-window} entry, it is also able to handle
+a @code{nil} return value.
address@hidden defun
+
+Two other action functions are described in their proper
address@hidden (@pxref{Displaying
+Buffers in Side Windows}) and @code{display-buffer-in-atom-window}
+(@pxref{Atomic Windows}).
+
+
address@hidden Buffer Display Action Alists
address@hidden Action Alists for Buffer Display
address@hidden buffer display action alist
address@hidden action alist for buffer display
+
+An @dfn{action alist} is an association list mapping predefined
+symbols recognized by action functions to values these functions are
+supposed to interpret accordingly.  In each call,
address@hidden constructs a new, possibly empty action alist
+and passes that entire list on to any action function it calls.
+
+   By design, action functions are free in their interpretation of
+action alist entries.  In fact, some entries like
address@hidden or @code{previous-window} have a meaning only
+for one or a few action functions, and are ignored by the rest.  Other
+entries, like @code{inhibit-same-window} or @code{window-parameters},
+are supposed to be respected by most action functions, including those
+provided by application programs and external packages.
+
+   In the previous subsection we have described in detail how
+individual action functions interpret the action alist entries they
+care about.  Here we give a reference list of all known action alist
+entries according to their symbols, together with their values and
+action functions (@pxref{Buffer Display Action Functions}) that
+recognize them.  Throughout this list, the terms ``buffer'' will refer
+to the buffer @code{display-buffer} is supposed to display, and
+``value'' refers to the entry's value.
+
address@hidden @code
address@hidden address@hidden, a buffer display action alist entry}
address@hidden inhibit-same-window
+If the value is address@hidden, this signals that the selected window
+must not be used for displaying the buffer.  All action functions that
+(re-)use an existing window should respect this entry.
+
address@hidden address@hidden, a buffer display action alist entry}
address@hidden previous-window
+The value must specify a window that may have displayed the buffer
+previously.  @code{display-buffer-in-previous-window} will give
+preference to such a window provided it is still live and not
+dedicated to another buffer.
+
address@hidden address@hidden, a buffer display action alist entry}
address@hidden mode
+The value is either a major mode or a list of major modes.
address@hidden may reuse a window whenever
+the value specified by this entry matches the major mode of that
+window's buffer.  Other action functions ignore such entries.
+
address@hidden address@hidden, a buffer display action alist entry}
address@hidden frame-predicate
+The value must be a function taking one argument (a frame), supposed
+to return address@hidden if that frame is a candidate for displaying
+the buffer.  This entry is used by
address@hidden
+
address@hidden address@hidden, a buffer display action alist entry}
address@hidden reusable-frames
+The value specifies the frame(s) to search for a window that can be
+reused because it already displays the buffer.  It can be set as
+follows:
 
 @itemize @bullet
 @item
address@hidden means to leave the height of the new window alone.
address@hidden means consider only windows on the selected frame.
+(Actually, the last frame used that is not a minibuffer-only frame.)
address@hidden
address@hidden means consider windows on all frames.
address@hidden
address@hidden means consider windows on all visible frames.
address@hidden
+0 means consider windows on all visible or iconified frames.
address@hidden
+A frame means consider windows on that frame only.
address@hidden itemize
+
+Note that the meaning of @code{nil} differs slightly from that of the
address@hidden argument to @code{next-window} (@pxref{Cyclic Window
+Ordering}).
+
+A major client of this is @code{display-buffer-reuse-window}, but all
+other action functions that try to reuse a window are affected as
+well.
+
address@hidden address@hidden, a buffer display action alist entry}
address@hidden inhibit-switch-frame
+A address@hidden value prevents another frame from being raised or
+selected, if the window chosen by @code{display-buffer} is displayed
+there.  Primarily affected by this are
address@hidden and
address@hidden
address@hidden should be affected as well, but
+there is no guarantee that the window manager will comply.
+
address@hidden address@hidden, a buffer display action alist entry}
address@hidden window-parameters
+The value specifies an alist of window parameters to give the chosen
+window.  All action functions that choose a window should process this
+entry.
+
address@hidden address@hidden, a buffer display action alist entry}
address@hidden window-height
+The value specifies whether and how to adjust the height of the chosen
+window, and can have the following values:
+
address@hidden @bullet
address@hidden
address@hidden means to leave the height of the chosen window alone.
 
 @item
-A number specifies the desired height of the new window.  An integer
-specifies the number of lines of the window.  A floating-point
+A number specifies the desired height of the chosen window.  An
+integer specifies the number of lines of the window.  A floating-point
 number gives the fraction of the window's height with respect to the
 height of the frame's root window.
 
 @item
-If the @sc{cdr} specifies a function, that function is called with one
-argument: the new window.  The function is supposed to adjust the
+If the value specifies a function, that function is called with one
+argument---the chosen window.  The function is supposed to adjust the
 height of the window; its return value is ignored.  Suitable functions
 are @code{shrink-window-if-larger-than-buffer} and
 @code{fit-window-to-buffer}, see @ref{Resizing Windows}.
 @end itemize
 
-To adjust the window's width, use an entry whose @sc{car} is
address@hidden and whose @sc{cdr} is one of:
+All action functions that choose a window should process this entry.
+
address@hidden address@hidden, a buffer display action alist entry}
address@hidden window-width
+This entry is similar to the @code{window-height} entry described
+before, but used to adjust the chosen window's width instead.  The
+value can be one of the following:
 
 @itemize @bullet
 @item
address@hidden means to leave the width of the new window alone.
address@hidden means to leave the width of the chosen window alone.
 
 @item
-A number specifies the desired width of the new window.  An integer
+A number specifies the desired width of the chosen window.  An integer
 specifies the number of columns of the window.  A floating-point
 number gives the fraction of the window's width with respect to the
 width of the frame's root window.
 
 @item
-If the @sc{cdr} specifies a function, that function is called with one
-argument: the new window.  The function is supposed to adjust the width
-of the window; its return value is ignored.
+If the value specifies a function, that function is called with one
+argument---the chosen window.  The function is supposed to adjust the
+width of the window; its return value is ignored.
 @end itemize
 
-If @var{alist} contains a @code{preserve-size} entry, Emacs will try to
-preserve the size of the new window during future resize operations
-(@pxref{Preserving Window Sizes}).  The @sc{cdr} of that entry must be a
-cons cell whose @sc{car}, if address@hidden, means to preserve the width
-of the window and whose @sc{cdr}, if address@hidden, means to preserve
-the height of the window.
-
-This function can fail if no window splitting can be performed for some
-reason (e.g., if the selected frame has an @code{unsplittable} frame
-parameter; @pxref{Buffer Parameters}).
address@hidden defun
-
address@hidden display-buffer-below-selected buffer alist
-This function tries to display @var{buffer} in a window below the
-selected window.  If there is a window below the selected one and that
-window already displays @var{buffer}, it reuses that window.
-
-If there is no such window, this function tries to create a new window
-by splitting the selected one and display @var{buffer} there.  It will
-also adjust that window's size provided @var{alist} contains a suitable
address@hidden or @code{window-width} entry, see above.
-
-If splitting the selected window fails and there is a non-dedicated
-window below the selected one showing some other buffer, it uses that
-window for showing @var{buffer}.
address@hidden defun
-
address@hidden display-buffer-in-previous-window buffer alist
-This function tries to display @var{buffer} in a window previously
-showing it.  If @var{alist} has a address@hidden
address@hidden entry, the selected window is not eligible
-for reuse.  If @var{alist} contains a @code{reusable-frames} entry, its
-value determines which frames to search for a suitable window as with
address@hidden
-
-If @var{alist} has a @code{previous-window} entry, the window
-specified by that entry will override any other window found by the
-methods above, even if that window never showed @var{buffer} before.
address@hidden defun
-
address@hidden display-buffer-at-bottom buffer alist
-This function tries to display @var{buffer} in a window at the bottom
-of the selected frame.
-
-This either splits the window at the bottom of the frame or the
-frame's root window, or reuses an existing window at the bottom of the
-selected frame.
address@hidden defun
-
address@hidden display-buffer-use-some-window buffer alist
-This function tries to display @var{buffer} by choosing an existing
-window and displaying the buffer in that window.  It can fail if all
-windows are dedicated to another buffer (@pxref{Dedicated Windows}).
address@hidden defun
-
address@hidden display-buffer-no-window buffer alist
-If @var{alist} has a address@hidden @code{allow-no-window} entry, then
-this function does not display @code{buffer}.  This allows you to
-override the default action and avoid displaying the buffer.  It is
-assumed that when the caller specifies a address@hidden
address@hidden value it can handle a @code{nil} value returned
-from @code{display-buffer} in this case.
address@hidden defun
-
-If the @var{alist} argument of any of these functions contains a
address@hidden entry, @code{display-buffer} assigns the
-elements of the associated value as window parameters of the chosen
-window.
-
-   To illustrate the use of action functions, consider the following
-example.
-
address@hidden
address@hidden
-(display-buffer
- (get-buffer-create "*foo*")
- '((display-buffer-reuse-window
-    display-buffer-pop-up-window
-    display-buffer-pop-up-frame)
-   (reusable-frames . 0)
-   (window-height . 10) (window-width . 40)))
address@hidden group
address@hidden example
-
address@hidden
-Evaluating the form above will cause @code{display-buffer} to proceed as
-follows: If a buffer called *foo* already appears on a visible or
-iconified frame, it will reuse its window.  Otherwise, it will try to
-pop up a new window or, if that is impossible, a new frame and show the
-buffer there.  If all these steps fail, it will proceed using whatever
address@hidden and
address@hidden prescribe.
-
-   Furthermore, @code{display-buffer} will try to adjust a reused window
-(provided *foo* was put by @code{display-buffer} there before) or a
-popped-up window as follows: If the window is part of a vertical
-combination, it will set its height to ten lines.  Note that if, instead
-of the number 10, we specified the function
address@hidden, @code{display-buffer} would come up with a
-one-line window to fit the empty buffer.  If the window is part of a
-horizontal combination, it sets its width to 40 columns.  Whether a new
-window is vertically or horizontally combined depends on the shape of
-the window split and the values of
address@hidden, @code{split-height-threshold}
-and @code{split-width-threshold} (@pxref{Choosing Window Options}).
-
-   Now suppose we combine this call with a preexisting setup for
address@hidden as follows.
-
address@hidden
address@hidden
-(let ((display-buffer-alist
-       (cons
-        '("\\*foo\\*"
-          (display-buffer-reuse-window display-buffer-below-selected)
-          (reusable-frames)
-          (window-height . 5))
-        display-buffer-alist)))
-  (display-buffer
-   (get-buffer-create "*foo*")
-   '((display-buffer-reuse-window
-      display-buffer-pop-up-window
-      display-buffer-pop-up-frame)
-     (reusable-frames . 0)
-     (window-height . 10) (window-width . 40))))
address@hidden group
address@hidden example
+All action functions that choose a window should process this entry.
+
address@hidden address@hidden, a buffer display action alist entry}
address@hidden preserve-size
+If address@hidden such an entry tells Emacs to preserve the size of
+the window chosen (@pxref{Preserving Window Sizes}).  The value should
+be either @code{(t . nil)} to preserve the width of the window,
address@hidden(nil . t)} to preserve its height or @code{(t . t)} to preserve
+both its width and its height.  All action functions that choose a
+window should process this entry.
+
address@hidden address@hidden, a buffer display action alist entry}
address@hidden pop-up-frame-parameters
+The value specifies an alist of frame parameters to give a new frame,
+if one is created.  @code{display-buffer-pop-up-frame} is its one and
+only addressee.
+
address@hidden address@hidden, a buffer display action alist entry}
address@hidden parent-frame
+The value specifies the parent frame to be used when the buffer is
+displayed on a child frame.  This entry is used only by
address@hidden
+
address@hidden address@hidden, a buffer display action alist entry}
address@hidden child-frame-parameters
+The value specifies an alist of frame parameters to use when the buffer
+is displayed on a child frame.  This entry is used only by
address@hidden
+
address@hidden address@hidden, a buffer display action alist entry}
address@hidden side
+The value denotes the side of the frame or window where a new window
+displaying the buffer shall be created.  This entry is used by
address@hidden to indicate the side of the frame
+where a new side window shall be placed (@pxref{Displaying Buffers in
+Side Windows}).  It is also used by
address@hidden to indicate the side of an
+existing window where the new window shall be located (@pxref{Atomic
+Windows}).
 
address@hidden
-This form will have @code{display-buffer} first try reusing a window
-that shows *foo* on the selected frame.  If there's no such window, it
-will try to split the selected window or, if that is impossible, use the
-window below the selected window.
address@hidden address@hidden, a buffer display action alist entry}
address@hidden slot
+If address@hidden, the value specifies the slot of the side window
+supposed to display the buffer.  This entry is used only by
address@hidden
 
-   If there's no window below the selected one, or the window below the
-selected one is dedicated to its buffer, @code{display-buffer} will
-proceed as described in the previous example.  Note, however, that when
-it tries to adjust the height of any reused or popped-up window, it will
-in any case try to set its number of lines to 5 since that value
-overrides the corresponding specification in the @var{action} argument
-of @code{display-buffer}.
address@hidden address@hidden, a buffer display action alist entry}
address@hidden window
+The value specifies a window that is in some way related to the window
+chosen by @code{display-buffer}.  This entry is currently used by
address@hidden to indicate the window on whose
+side the new window shall be created.
+
address@hidden address@hidden, a buffer display action alist entry}
address@hidden allow-no-window
+If the value is address@hidden, @code{display-buffer} does not
+necessarily have to display the buffer and the caller is prepared to
+accept that.  This entry is not intended for user customizations,
+since there is no guarantee that an arbitrary caller of
address@hidden will be able to handle the case that no window
+will display the buffer.  @code{display-buffer-no-window} is the only
+action function that cares about this entry.
address@hidden table
 
 
 @node Choosing Window Options
address@hidden Additional Options for Displaying Buffers
address@hidden Additional Options for Displaying Buffers
 
-The behavior of the standard display actions of @code{display-buffer}
-(@pxref{Choosing Window}) can be modified by a variety of user
-options.
+The behavior of buffer display actions (@pxref{Choosing Window}) can
+be further modified by the following user options.
 
 @defopt pop-up-windows
 If the value of this variable is address@hidden, @code{display-buffer}
 is allowed to split an existing window to make a new window for
 displaying in.  This is the default.
 
-This variable is provided mainly for backward compatibility.  It is
+This variable is provided for backward compatibility only.  It is
 obeyed by @code{display-buffer} via a special mechanism in
address@hidden, which only calls the action
-function @code{display-buffer-pop-up-window} (@pxref{Display Action
-Functions}) when the value is @code{nil}.  It is not consulted by
address@hidden itself, which the user may specify
-directly in @code{display-buffer-alist} etc.
address@hidden, which calls the action function
address@hidden (@pxref{Buffer Display Action
+Functions}) when the value of this option is address@hidden  It is
+not consulted by @code{display-buffer-pop-up-window} itself, which the
+user may specify directly in @code{display-buffer-alist} etc.
 @end defopt
 
 @defopt split-window-preferred-function
 This variable specifies a function for splitting a window, in order to
 make a new window for displaying a buffer.  It is used by the
 @code{display-buffer-pop-up-window} action function to actually split
-the window (@pxref{Display Action Functions}).
+the window.
 
-The default value is @code{split-window-sensibly}, which is documented
-below.  The value must be a function that takes one argument, a window,
-and return either a new window (which will be used to display the
-desired buffer) or @code{nil} (which means the splitting failed).
+The value must be a function that takes one argument, a window, and
+returns either a new window (which will be used to display the desired
+buffer) or @code{nil} (which means the splitting failed).  The default
+value is @code{split-window-sensibly}, which is documented next.
 @end defopt
 
 @defun split-window-sensibly &optional window
-This function tries to split @var{window}, and return the newly created
+This function tries to split @var{window} and return the newly created
 window.  If @var{window} cannot be split, it returns @code{nil}.  If
 @var{window} is omitted or @code{nil}, it defaults to the selected
 window.
@@ -2790,31 +2945,31 @@ placing the new window below, subject to the 
restriction imposed by
 @code{split-height-threshold} (see below), in addition to any other
 restrictions.  If that fails, it tries to split by placing the new
 window to the right, subject to @code{split-width-threshold} (see
-below).  If that fails, and the window is the only window on its
+below).  If that also fails, and the window is the only window on its
 frame, this function again tries to split and place the new window
 below, disregarding @code{split-height-threshold}.  If this fails as
 well, this function gives up and returns @code{nil}.
 @end defun
 
 @defopt split-height-threshold
-This variable, used by @code{split-window-sensibly}, specifies whether
-to split the window placing the new window below.  If it is an
+This variable specifies whether @code{split-window-sensibly} is
+allowed to split the window placing the new window below.  If it is an
 integer, that means to split only if the original window has at least
 that many lines.  If it is @code{nil}, that means not to split this
 way.
 @end defopt
 
 @defopt split-width-threshold
-This variable, used by @code{split-window-sensibly}, specifies whether
-to split the window placing the new window to the right.  If the value
-is an integer, that means to split only if the original window has at
-least that many columns.  If the value is @code{nil}, that means not
-to split this way.
+This variable specifies whether @code{split-window-sensibly} is
+allowed to split the window placing the new window to the right.  If
+the value is an integer, that means to split only if the original
+window has at least that many columns.  If the value is @code{nil},
+that means not to split this way.
 @end defopt
 
 @defopt even-window-sizes
 This variable, if address@hidden, causes @code{display-buffer} to even
-window sizes whenever it reuses an existing window and that window is
+window sizes whenever it reuses an existing window, and that window is
 adjacent to the selected one.
 
 If its value is @code{width-only}, sizes are evened only if the reused
@@ -2839,9 +2994,9 @@ search any visible or iconified frame, not just the 
selected frame.
 This variable is provided mainly for backward compatibility.  It is
 obeyed by @code{display-buffer} via a special mechanism in
 @code{display-buffer-fallback-action}, which calls the action function
address@hidden (@pxref{Display Action Functions})
-if the value is address@hidden  (This is done before attempting to
-split a window.)  This variable is not consulted by
address@hidden (@pxref{Buffer Display Action
+Functions}) if the value is address@hidden  (This is done before
+attempting to split a window.)  This variable is not consulted by
 @code{display-buffer-pop-up-frame} itself, which the user may specify
 directly in @code{display-buffer-alist} etc.
 @end defopt
@@ -2849,8 +3004,7 @@ directly in @code{display-buffer-alist} etc.
 @defopt pop-up-frame-function
 This variable specifies a function for creating a new frame, in order
 to make a new window for displaying a buffer.  It is used by the
address@hidden action function (@pxref{Display
-Action Functions}).
address@hidden action function.
 
 The value should be a function that takes no arguments and returns a
 frame, or @code{nil} if no frame could be created.  The default value
@@ -2860,30 +3014,670 @@ is a function that creates a frame using the 
parameters specified by
 
 @defopt pop-up-frame-alist
 This variable holds an alist of frame parameters (@pxref{Frame
-Parameters}), which is used by the default function in
+Parameters}), which is used by the function specified by
 @code{pop-up-frame-function} to make a new frame.  The default is
 @code{nil}.
address@hidden defopt
 
address@hidden same-window-buffer-names
-A list of buffer names for buffers that should be displayed in the
-selected window.  If a buffer's name is in this list,
address@hidden handles the buffer by showing it in the selected
-window.
+This option is provided for backward compatibility only.  Note, that
+when @code{display-buffer-pop-up-frame} calls the function specified
+by @code{pop-up-frame-function}, it prepends the value of all
address@hidden action alist entries to
address@hidden so that the values specified by the action
+alist entry effectively override any corresponding values of
address@hidden
+
+Hence, users should set up a @code{pop-up-frame-parameters} action
+alist entry in @code{display-buffer-alist} instead of customizing
address@hidden  Only this will guarantee that the value of
+a parameter specified by the user overrides the value of that
+parameter specified by the caller of @code{display-buffer}.
 @end defopt
 
address@hidden same-window-regexps
-A list of regular expressions that specify buffers that should be
-displayed in the selected window.  If the buffer's name matches any of
-the regular expressions in this list, @code{display-buffer} handles the
-buffer by showing it in the selected window.
address@hidden defopt
+   Many efforts in the design of @code{display-buffer} have been given
+to maintain compatibility with code that uses older options like
address@hidden, @code{pop-up-frames},
address@hidden, @code{same-window-buffer-names} and
address@hidden  Lisp Programs and users should refrain
+from using these options.  Above we already warned against customizing
address@hidden  Here we describe how to convert the
+remaining options to use display actions instead.
+
address@hidden @code
address@hidden pop-up-windows
address@hidden address@hidden, replacement for}
+This variable is @code{t} by default.  Instead of customizing it to
address@hidden and thus telling @code{display-buffer} what not to do, it's
+much better to list in @code{display-buffer-base-action} the action
+functions it should try instead as, for example:
+
address@hidden
address@hidden
+(customize-set-variable
+ 'display-buffer-base-action
+ '((display-buffer-reuse-window display-buffer-same-window
+    display-buffer-in-previous-window
+    display-buffer-use-some-window)))
address@hidden group
address@hidden example
+
address@hidden pop-up-frames
address@hidden address@hidden, replacement for}
+Instead of customizing this variable to @code{t}, customize
address@hidden, for example, as follows:
+
address@hidden
address@hidden
+(customize-set-variable
+ 'display-buffer-base-action
+ '((display-buffer-reuse-window display-buffer-pop-up-frame)
+   (reusable-frames . 0)))
address@hidden group
address@hidden example
+
address@hidden same-window-buffer-names
address@hidden same-window-regexps
address@hidden address@hidden, replacement for}
address@hidden address@hidden, replacement for}
+Instead of adding a buffer name or a regular expression to one of
+these options use a @code{display-buffer-alist} entry for that buffer
+specifying the action function @code{display-buffer-same-window}.
+
address@hidden
address@hidden
+(customize-set-variable
+ 'display-buffer-alist
+ (cons '("\\*foo\\*" (display-buffer-same-window))
+        display-buffer-alist))
address@hidden group
address@hidden example
address@hidden table
+
+
address@hidden Precedence of Action Functions
address@hidden Precedence of Action Functions
address@hidden precedence of buffer display action functions
address@hidden execution order of buffer display action functions
address@hidden buffer display action functions, precedence
+
+From the past subsections we already know that @code{display-buffer}
+must be supplied with a number of display actions (@pxref{Choosing
+Window}) in order to display a buffer.  In a completely uncustomized
+Emacs, these actions are specified by
address@hidden in the following order of
+precedence: Reuse a window, pop up a new window on the same frame, use
+a window previously showing the buffer, use some window and pop up a
+new frame.  (Note that the remaining actions named by
address@hidden are void in an uncustomized
+Emacs).
+
+Consider the following form:
+
address@hidden
+(display-buffer (get-buffer-create "*foo*"))
address@hidden example
+
address@hidden
+Evaluating this form in the buffer @file{*scratch*} of an uncustomized
+Emacs session will usually fail to reuse a window that shows
address@hidden already, but succeed in popping up a new window.
+Evaluating the same form again will now not cause any visible
address@hidden reused the window already showing
address@hidden because that action was applicable and had the highest
+precedence among all applicable actions.
+
+   Popping up a new window will fail if there is not enough space on
+the selected frame.  In an uncustomized Emacs it typically fails when
+there are already two windows on a frame.  For example, if you now
+type @address@hidden 1}} followed by @address@hidden 2}} and evaluate the form
+once more, @file{*foo*} should show up in the lower
address@hidden just used ``some'' window.  If, before
+typing @address@hidden 2}} you had typed @address@hidden o}}, @file{*foo*}
+would have been shown in the upper window because ``some'' window
+stands for the ``least recently used'' window and the selected window
+has been least recently used if and only if it is alone on its frame.
+
+   Let's assume you did not type @address@hidden o}} and @file{*foo*} is
+shown in the lower window.  Type @address@hidden o}} to get there followed
+by @address@hidden left}} and evaluate the form again.  This should
+display @file{*foo*} in the same, lower window because that window had
+already shown @file{*foo*} previously and was therefore chosen instead
+of some other window.
+
+  So far we have only observed the default behavior in an uncustomized
+Emacs session.  To see how this behavior can be customized, let's
+consider the option @code{display-buffer-base-action}.  It provides a
+very coarse customization which conceptually affects the display of
address@hidden buffer.  It can be used to supplement the actions supplied
+by @code{display-buffer-fallback-action} by reordering them or by
+adding actions that are not present there but fit more closely the
+user's editing practice.   However, it can also be used to change the
+default behavior in a more profound way.
+
+   Let's consider a user who, as a rule, prefers to display buffers on
+another frame.  Such a user might provide the following customization:
+
address@hidden
address@hidden
+(customize-set-variable
+ 'display-buffer-base-action
+ '((display-buffer-reuse-window display-buffer-pop-up-frame)
+   (reusable-frames . 0)))
address@hidden group
address@hidden example
+
address@hidden
+This setting will cause @code{display-buffer} to first try to find a
+window showing the buffer on a visible or iconified frame and, if no
+such frame exists, pop up a new frame.  You can observe this behavior
+on a graphical system by typing @address@hidden 1}} in the window showing
address@hidden and evaluating our canonical @code{display-buffer}
+form.  This will usually create (and give focus to) a new frame whose
+root window shows @file{*foo*}.  Iconify that frame and evaluate the
+canonical form again: @code{display-buffer} will reuse the window on
+the new frame (usually raising the frame and giving it focus too).
+
+   Only if creating a new frame fails, @code{display-buffer} will
+apply the actions supplied by @code{display-buffer-fallback-action}
+which means to again try reusing a window, popping up a new window and
+so on.  A trivial way to make frame creation fail is supplied by the
+following form:
+
address@hidden
address@hidden
+(let ((pop-up-frame-function 'ignore))
+  (display-buffer (get-buffer-create "*foo*")))
address@hidden group
address@hidden example
+
address@hidden
+We will forget about that form immediately after observing that it
+fails to create a new frame and uses a fallback action instead.
+
+   Note that @code{display-buffer-reuse-window} appears redundant in
+the customization of @code{display-buffer-base-action} because it is
+already part of @code{display-buffer-fallback-action} and should be
+tried there anyway.  However, that would fail because due to the
+precedence of @code{display-buffer-base-action} over
address@hidden, at that time
address@hidden would have already won the race.
+In fact, this:
+
address@hidden
address@hidden
+(customize-set-variable
+ 'display-buffer-base-action
+ '(display-buffer-pop-up-frame (reusable-frames . 0)))
address@hidden group
address@hidden example
+
address@hidden
+would cause @code{display-buffer} to @emph{always} pop up a new frame
+which is probably not what our user wants.
+
+   So far, we have only shown how @emph{users} can customize the
+default behavior of @code{display-buffer}.  Let us now see how
address@hidden can change the course of @code{display-buffer}.
+The canonical way to do that is to use the @var{action} argument of
address@hidden or a function that calls it, like, for example,
address@hidden (@pxref{Switching Buffers}).
+
+   Suppose an application wants to display @file{*foo*} preferably
+below the selected window (to immediately attract the attention of the
+user to the new window) or, if that fails, in a window at the bottom
+of the frame.  It could do that with a call like this:
+
address@hidden
address@hidden
+(display-buffer
+ (get-buffer-create "*foo*")
+ '((display-buffer-below-selected display-buffer-at-bottom)))
address@hidden group
address@hidden example
+
address@hidden
+In order to see how this new, modified form works, delete any frame
+showing @file{*foo*}, type @address@hidden 1}} followed by @address@hidden 2}} 
in the
+window showing @file{*scratch*}, and subsequently evaluate that form.
address@hidden should split the upper window, and show
address@hidden in the new window.  Alternatively, if after @address@hidden 2}}
+you had typed @address@hidden o}}, @code{display-buffer} would have split the
+window at the bottom instead.
+
+   Suppose now that, before evaluating the new form, you have made the
+selected window as small as possible, for example, by evaluating the
+form @code{(fit-window-to-buffer)} in that window.  In that case,
address@hidden would have failed to split the selected window
+and would have split the frame's root window instead, effectively
+displaying @file{*foo*} at the bottom of the frame.
+
+   In either case, evaluating the new form a second time should reuse
+the window already showing @file{*foo*} since both functions supplied
+by the @var{action} argument try to reuse such a window first.
+
+   By setting the @var{action} argument, an application effectively
+overrules any customization of @code{display-buffer-base-action}.  Our
+user can now either accept the choice of the application, or redouble
+by customizing the option @code{display-buffer-alist} as follows:
+
address@hidden
address@hidden
+(customize-set-variable
+ 'display-buffer-alist
+ '(("\\*foo\\*"
+    (display-buffer-reuse-window display-buffer-pop-up-frame))))
address@hidden group
address@hidden example
+
address@hidden
+Trying this with the new, modified form above in a configuration that
+does not show @file{*foo*} anywhere, will display @file{*foo*} on a
+separate frame, completely ignoring the @var{action} argument of
address@hidden
+
+   Note that we didn't care to specify a @code{reusable-frames} action
+alist entry in our specification of @code{display-buffer-alist}.
address@hidden always takes the first one it finds---in our
+case the one specified by @code{display-buffer-base-action}.  If we
+wanted to use a different specification, for example, to exclude
+iconified frames showing @file{*foo*} from the list of reusable ones,
+we would have to specify that separately, however:
+
address@hidden
address@hidden
+(customize-set-variable
+ 'display-buffer-alist
+ '(("\\*foo\\*"
+    (display-buffer-reuse-window display-buffer-pop-up-frame)
+    (reusable-frames . visible))))
address@hidden group
address@hidden example
+
address@hidden
+If you try this, you will notice that repeated attempts to display
address@hidden will succeed to reuse a frame only if that frame is
+visible.
+
+   The above example would allow the conclusion that users customize
address@hidden for the sole purpose to overrule the
address@hidden argument chosen by applications.  Such a conclusion would
+be incorrect.  @code{display-buffer-alist} is the standard option for
+users to direct the course of display of specific buffers in a
+preferred way regardless of whether the display is also guided by an
address@hidden argument.
+
+   We can, however, reasonably conclude that customizing
address@hidden differs from customizing
address@hidden in two major aspects: it is stronger
+because it overrides the @var{action} argument of
address@hidden, and it allows to explicitly specify the
+affected buffers.  In fact, displaying other buffers is not affected
+in any way by a customization for @file{*foo*}.  For example,
+
address@hidden
+(display-buffer (get-buffer-create "*bar*"))
address@hidden example
+
address@hidden
+continues being governed by the settings of
address@hidden and
address@hidden only.
+
+   We could stop with our examples here but Lisp programs still have
+an ace up their sleeves which they can use to overrule any
+customization of @code{display-buffer-alist}.  It's the variable
address@hidden which they can bind around
address@hidden calls as follows:
+
address@hidden
address@hidden
+(let ((display-buffer-overriding-action
+       '((display-buffer-same-window))))
+  (display-buffer
+   (get-buffer-create "*foo*")
+   '((display-buffer-below-selected display-buffer-at-bottom))))
address@hidden group
address@hidden example
+
address@hidden
+Evaluating this form will usually display @file{*foo*} in the selected
+window regardless of the @var{action} argument and any user
+customizations.  (Usually, an application will not bother to also
+provide an @var{action} argument.  Here it just serves to illustrate
+the fact that it gets overridden.)
+
+It might be illustrative to look at the list of action functions
address@hidden would have tried to display @file{*foo*} with
+the customizations we provided here.  The list (including comments
+explaining who added this and the subsequent elements) is:
+
address@hidden
address@hidden
+(display-buffer-same-window  ;; `display-buffer-overriding-action'
+ display-buffer-reuse-window ;; `display-buffer-alist'
+ display-buffer-pop-up-frame
+ display-buffer-below-selected ;; ACTION argument
+ display-buffer-at-bottom
+ display-buffer-reuse-window ;; `display-buffer-base-action'
+ display-buffer-pop-up-frame
+ display-buffer--maybe-same-window ;; `display-buffer-fallback-action'
+ display-buffer-reuse-window
+ display-buffer--maybe-pop-up-frame-or-window
+ display-buffer-in-previous-window
+ display-buffer-use-some-window
+ display-buffer-pop-up-frame)
address@hidden group
address@hidden example
+
address@hidden
+Note that among the internal functions listed here,
address@hidden is effectively ignored while
address@hidden actually runs
address@hidden
+
+The action alist passed in each function call is:
+
address@hidden
address@hidden
+((reusable-frames . visible)
+ (reusable-frames . 0))
address@hidden group
address@hidden example
+
address@hidden
+which shows that we have used the second specification of
address@hidden above, overriding the specification
+supplied by @code{display-buffer-base-action}.  Suppose our user had
+written that as
+
address@hidden
address@hidden
+(customize-set-variable
+ 'display-buffer-alist
+ '(("\\*foo\\*"
+    (display-buffer-reuse-window display-buffer-pop-up-frame)
+    (inhibit-same-window . t)
+    (reusable-frames . visible))))
address@hidden group
address@hidden example
+
address@hidden
+In this case the @code{inhibit-same-window} alist entry will
+successfully invalidate the @code{display-buffer-same-window}
+specification from @code{display-buffer-overriding-action} and
address@hidden will show @file{*foo*} on another frame.  To
+make @code{display-buffer-overriding-action} more robust in this
+regard, the application would have to specify an appropriate
address@hidden entry too, for example, as follows:
+
address@hidden
address@hidden
+(let ((display-buffer-overriding-action
+       '(display-buffer-same-window (inhibit-same-window . nil))))
+  (display-buffer (get-buffer-create "*foo*")))
address@hidden group
address@hidden example
+
address@hidden
+This last example shows that while the precedence order of action
+functions is fixed, as described in @ref{Choosing Window}, an action
+alist entry specified by a display action ranked lower in that order
+can affect the execution of a higher ranked display action.
+
+
address@hidden The Zen of Buffer Display
address@hidden The Zen of Buffer Display
address@hidden guidelines for buffer display
address@hidden writing buffer display actions
address@hidden buffer display conventions
+
+In its most simplistic form, a frame accommodates always one single
+window that can be used for displaying a buffer.  As a consequence, it
+is always the latest call of @code{display-buffer} that will have
+succeeded in placing its buffer there.
+
+   Since working with such a frame is not very practical, Emacs by
+default allows for more complex frame layouts controlled by the
+default values of the frame size and the @code{split-height-threshold}
+and @code{split-width-threshold} options.  Displaying a buffer not yet
+shown on a frame then either splits the single window on that frame or
+(re-)uses one of its two windows.
+
+   The default behavior is abandoned as soon as the user customizes
+one of these thresholds or manually changes the frame's layout.  The
+default behavior is also abandoned when calling @code{display-buffer}
+with a address@hidden @var{action} argument or the user customizes one
+of the options mentioned in the previous subsections.  Mastering
address@hidden soon may become a frustrating experience due to
+the plethora of applicable display actions and the resulting frame
+layouts.
+
+   However, refraining from using buffer display functions and falling
+back on a split & delete windows metaphor is not a good idea either.
+Buffer display functions give Lisp programs and users a framework to
+reconcile their different needs; no comparable framework exists for
+splitting and deleting windows.  Buffer display functions also allow
+to at least partially restore the layout of a frame when removing a
+buffer from it later (@pxref{Quitting Windows}).
+
+   Below we will give a number of guidelines to redeem the frustration
+mentioned above and thus to avoid literally losing buffers in-between
+the windows of a frame.
+
address@hidden @asis
address@hidden Write display actions without stress
+Writing display actions can be a pain because one has to lump together
+action functions and action alists in one huge list.  (Historical
+reasons prevented us from having @code{display-buffer} support
+separate arguments for these.)  It might help to memorize some basic
+forms like the ones listed below:
+
address@hidden
+'(nil (inhibit-same-window . t))
address@hidden example
+
address@hidden
+specifies an action alist entry only and no action function.  Its sole
+purpose is to inhibit a @code{display-buffer-same-window} function
+specified elsewhere from showing the buffer in the same window, see
+also the last example of the preceding subsection.
+
address@hidden
+'(display-buffer-below-selected)
address@hidden example
+
address@hidden
+on the other hand, specifies one action function and an empty action
+alist.  To combine the effects of the above two specifications one
+would write the form
+
address@hidden
+'(display-buffer-below-selected (inhibit-same-window . t))
address@hidden example
+
address@hidden
+to add another action function one would write
+
address@hidden
address@hidden
+'((display-buffer-below-selected display-buffer-at-bottom)
+  (inhibit-same-window . t))
address@hidden group
address@hidden example
+
address@hidden
+and to add another alist entry one would write
+
address@hidden
address@hidden
+'((display-buffer-below-selected display-buffer-at-bottom)
+  (inhibit-same-window . t)
+  (window-height . fit-window-to-buffer))
address@hidden group
address@hidden example
+
address@hidden
+That last form can be used as @var{action} argument of
address@hidden in the following way:
+
address@hidden
address@hidden
+(display-buffer
+ (get-buffer-create "*foo*")
+ '((display-buffer-below-selected display-buffer-at-bottom)
+   (inhibit-same-window . t)
+   (window-height . fit-window-to-buffer)))
address@hidden group
address@hidden example
+
address@hidden
+In a customization of @code{display-buffer-alist} it would be used as
+follows:
+
address@hidden
address@hidden
+(customize-set-variable
+ 'display-buffer-alist
+ '(("\\*foo\\*"
+    (display-buffer-below-selected display-buffer-at-bottom)
+    (inhibit-same-window . t)
+    (window-height . fit-window-to-buffer))))
address@hidden group
address@hidden example
+
address@hidden
+To add a customization for a second buffer one would then write:
+
address@hidden
address@hidden
+(customize-set-variable
+ 'display-buffer-alist
+ '(("\\*foo\\*"
+    (display-buffer-below-selected display-buffer-at-bottom)
+    (inhibit-same-window . t)
+    (window-height . fit-window-to-buffer))
+   ("\\*bar\\*"
+    (display-buffer-reuse-window display-buffer-pop-up-frame)
+    (reusable-frames . visible))))
address@hidden group
address@hidden example
+
address@hidden Treat each other with respect
address@hidden and @code{display-buffer-base-action} are
+user options---Lisp programs must never set or rebind them.
address@hidden, on the other hand, is
+reserved for applications---who seldom use that option and if they use
+it, then with utmost care.
+
+   Older implementations of @code{display-buffer} frequently caused
+users and applications to fight over the settings of user options like
address@hidden and @code{pop-up-windows} (@pxref{Choosing Window
+Options}).  This was one major reason for redesigning
address@hidden provide a clear framework specifying what
+users and applications should be allowed to do.
+
+   Lisp programs must be prepared that user customizations may
+cause buffers to get displayed in an unexpected way.  They should
+never assume in their subsequent behavior, that the buffer has been
+shown precisely the way they asked for in the @var{action} argument of
address@hidden
+
+   Users should not pose too many and too severe restrictions on how
+arbitrary buffers get displayed.  Otherwise, they will risk to lose
+the characteristics of showing a buffer for a certain purpose.
+Suppose a Lisp program has been written to compare different versions
+of a buffer in two windows side-by-side.  If the customization of
address@hidden prescribes that any such buffer should be
+always shown in or below the selected window, the program will have a
+hard time to set up the desired window configuration via
address@hidden
+
+   To specify a preference for showing an arbitrary buffer, users
+should customize @code{display-buffer-base-action}.  An example of how
+users who prefer working with multiple frames would do that was given
+in the previous subsection.  @code{display-buffer-alist} should be
+reserved for displaying specific buffers in a specific way.
+
address@hidden Consider reusing a window that already shows the buffer
+Generally, it's always a good idea for users and Lisp
+programmers to be prepared for the case that a window already shows
+the buffer in question and to reuse that window.  In the preceding
+subsection we have shown that failing to do so properly may cause
address@hidden to continuously pop up a new frame although a
+frame showing that buffer existed already.  In a few cases only, it
+might be undesirable to reuse a window, for example, when a different
+portion of the buffer should be shown in that window.
+
+   Hence, @code{display-buffer-reuse-window} is one action function
+that should be used as often as possible, both in @var{action}
+arguments and customizations.  An @code{inhibit-same-window} entry in
+the @var{action} argument usually takes care of the most common case
+where reusing a window showing the buffer should be avoided---that
+where the window in question is the selected one.
+
address@hidden Attract focus to the window chosen
+This is a no-brainer for people working with multiple frames---the
+frame showing the buffer will automatically raise and get focus unless
+an @code{inhibit-switch-frame} entry forbids it.  For single frame
+users this task can be considerably more difficult.  In particular,
address@hidden and
address@hidden can become obtrusive in this
+regard.  They split or use a seemingly arbitrary (often the largest or
+least recently used) window, distracting the user's attention.
+
+Some Lisp programs therefore try to choose a window at the bottom of
+the frame, for example, in order to display the buffer in vicinity of
+the minibuffer window where the user is expected to answer a question
+related to the new window.  For non-input related actions
address@hidden might be preferable because the
+selected window usually already has the user's attention.
+
address@hidden Handle subsequent invocations of @code{display-buffer}
address@hidden is not overly well suited for displaying several
+buffers in sequence and making sure that all these buffers are shown
+orderly in the resulting window configuration.  Again, the standard
+action functions @code{display-buffer-pop-up-window} and
address@hidden are not very suited for this
+purpose due to their somewhat chaotic nature in more complex
+configurations.
+
+   To produce a window configuration displaying multiple buffers (or
+different views of one and the same buffer) in one and the same
+display cycle, Lisp programmers will unavoidably have to write
+their own action functions.  A few tricks listed below might help in
+this regard.
+
address@hidden @bullet
address@hidden
+Making windows atomic (@pxref{Atomic Windows}) avoids breaking an
+existing window composition when popping up a new window.
+The new window will pop up outside the composition instead.
+
address@hidden
+Temporarily dedicating windows to their buffers (@pxref{Dedicated
+Windows}) avoids using a window for displaying a different
+buffer.  A non-dedicated window will be used instead.
+
address@hidden
+Calling @code{window-preserve-size} (@pxref{Preserving Window Sizes})
+will try to keep the size of the argument window unchanged when
+popping up a new window.  You have to make sure that another window in
+the same combination can be shrunk instead, though.
+
address@hidden
+Side windows (@pxref{Side Windows}) can be used for displaying
+specific buffers always in a window at the same position of a frame.
+This permits grouping buffers that do not compete for being shown at
+the same time on a frame and showing any such buffer in the same window
+without disrupting the display of other buffers.
+
address@hidden
+Child frames (@pxref{Child Frames}) can be used to display a buffer
+within the screen estate of the selected frame without disrupting that
+frame's window configuration and without the overhead associated with
+full-fledged frames as inflicted by @code{display-buffer-pop-up-frame}.
address@hidden itemize
address@hidden table
 
address@hidden same-window-p buffer-name
-This function returns @code{t} if displaying a buffer
-named @var{buffer-name} with @code{display-buffer} would
-put it in the selected window.
address@hidden defun
 
 @node Window History
 @section Window History
@@ -3202,12 +3996,13 @@ main window is either a ``normal'' live window or 
specifies the area
 containing all the normal windows.
 
    In their most simple form of use, side windows allow to display
-specific buffers always in the same area of a frame.  Hence they can be
-regarded as a generalization of the concept provided by
address@hidden (@pxref{Display Action Functions}) to
-the remaining sides of a frame.  With suitable customizations, however,
-side windows can be also used to provide frame layouts similar to those
-found in so-called integrated development environments (IDEs).
+specific buffers always in the same area of a frame.  Hence they can
+be regarded as a generalization of the concept provided by
address@hidden (@pxref{Buffer Display Action
+Functions}) to the remaining sides of a frame.  With suitable
+customizations, however, side windows can be also used to provide
+frame layouts similar to those found in so-called integrated
+development environments (IDEs).
 
 @menu
 * Displaying Buffers in Side Windows:: An action function for displaying
@@ -3221,9 +4016,9 @@ found in so-called integrated development environments 
(IDEs).
 @node Displaying Buffers in Side Windows
 @subsection Displaying Buffers in Side Windows
 
-The following action function for @code{display-buffer} (@pxref{Display
-Action Functions}) creates or reuses a side window for displaying the
-specified buffer.
+The following action function for @code{display-buffer} (@pxref{Buffer
+Display Action Functions}) creates or reuses a side window for
+displaying the specified buffer.
 
 @defun display-buffer-in-side-window buffer alist
 This function displays @var{buffer} in a side window of the selected
@@ -3263,11 +4058,11 @@ explicitly provided via a @code{window-parameters} 
entry in @var{alist}.
 @end defun
 
 By default, side windows cannot be split via @code{split-window}
-(@pxref{Splitting Windows}).  Also, a side window is not reused or split
-by any buffer display action (@pxref{Display Action Functions}) unless
-it is explicitly specified as target of that action.  Note also that
address@hidden cannot make a side window the only window on
-its frame (@pxref{Deleting Windows}).
+(@pxref{Splitting Windows}).  Also, a side window is not reused or
+split by any buffer display action (@pxref{Buffer Display Action
+Functions}) unless it is explicitly specified as target of that
+action.  Note also that @code{delete-other-windows} cannot make a side
+window the only window on its frame (@pxref{Deleting Windows}).
 
    Once set up, side windows also change the behavior of the commands
 @code{switch-to-prev-buffer} and @code{switch-to-next-buffer}
@@ -3453,9 +4248,9 @@ retain their respective sizes when maximizing the frame, 
the variable
 @xref{Resizing Windows}.
 
    The last form also makes sure that none of the created side windows
-are accessible via @kbd{C-x o} by installing the @code{no-other-window}
+are accessible via @address@hidden o}} by installing the @code{no-other-window}
 parameter for each of these windows.  In addition, it makes sure that
-side windows are not deleted via @kbd{C-x 1} by installing the
+side windows are not deleted via @address@hidden 1}} by installing the
 @code{no-delete-other-windows} parameter for each of these windows.
 
    Since @code{dired} buffers have no fixed names, we use a special
@@ -3547,7 +4342,7 @@ does is to set the @code{window-atom} parameter of each 
descendant of
 
 To create a new atomic window from an existing live window or to add a
 new window to an existing atomic window, the following buffer display
-action function (@pxref{Display Action Functions}) can be used:
+action function (@pxref{Buffer Display Action Functions}) can be used:
 
 @defun display-buffer-in-atom-window buffer alist
 This function tries to display @var{buffer} in a new window that will be
@@ -4212,18 +5007,20 @@ point at the middle, top, and bottom of the window.
 @cindex vertical scroll position
 
    @dfn{Vertical fractional scrolling} means shifting text in a window
-up or down by a specified multiple or fraction of a line.  Each window
-has a @dfn{vertical scroll position}, which is a number, never less than
-zero.  It specifies how far to raise the contents of the window.
-Raising the window contents generally makes all or part of some lines
-disappear off the top, and all or part of some other lines appear at the
-bottom.  The usual value is zero.
+up or down by a specified multiple or fraction of a line.  Emacs uses
+it, for example, on images and screen lines which are taller than the
+window.  Each window has a @dfn{vertical scroll position}, which is a
+number, never less than zero.  It specifies how far to raise the
+contents of the window when displaying them.  Raising the window
+contents generally makes all or part of some lines disappear off the
+top, and all or part of some other lines appear at the bottom.  The
+usual value is zero.
 
    The vertical scroll position is measured in units of the normal line
 height, which is the height of the default font.  Thus, if the value is
-.5, that means the window contents are scrolled up half the normal line
-height.  If it is 3.3, that means the window contents are scrolled up
-somewhat over three times the normal line height.
+.5, that means the window contents will be scrolled up half the normal
+line height.  If it is 3.3, that means the window contents are scrolled
+up somewhat over three times the normal line height.
 
    What fraction of a line the vertical scrolling covers, or how many
 lines, depends on what the lines contain.  A value of .5 could scroll a
diff --git a/doc/man/emacsclient.1 b/doc/man/emacsclient.1
index 5aaa6d1..24ca1c9 100644
--- a/doc/man/emacsclient.1
+++ b/doc/man/emacsclient.1
@@ -94,6 +94,7 @@ open a new Emacs frame on the current terminal
 .TP
 .B \-s, \-\-socket-name=FILENAME
 use socket named FILENAME for communication.
+This can also be specified via the EMACS_SOCKET_NAME environment variable.
 .TP
 .B \-V, \-\-version
 print version information and exit
diff --git a/doc/misc/calc.texi b/doc/misc/calc.texi
index 83807c6..f7b23d3 100644
--- a/doc/misc/calc.texi
+++ b/doc/misc/calc.texi
@@ -35832,7 +35832,7 @@ keystrokes are not listed in this summary.
 @r{       @:      _     @:number       @:        @:-@:number}
 @r{       @:      e     @:number       @:        @:@:1e number}
 @r{       @:      #     @:number       @:        @:@:address@hidden
address@hidden       @:      P     @:(in number)  @:        @:+/-@:}
address@hidden       @:      p     @:(in number)  @:        @:+/-@:}
 @r{       @:      M     @:(in number)  @:        @:mod@:}
 @r{       @:      @@ ' " @:  (in number)@:        @:@:HMS form}
 @r{       @:      h m s @:  (in number)@:        @:@:HMS form}
diff --git a/doc/misc/dired-x.texi b/doc/misc/dired-x.texi
index 36a9cb0..f65542f 100644
--- a/doc/misc/dired-x.texi
+++ b/doc/misc/dired-x.texi
@@ -321,8 +321,8 @@ Default: @code{nil}
 
 @cindex How to make omitting the default in Dired
 If address@hidden, ``uninteresting'' files are not listed.
-Uninteresting files are those whose files whose names match regexp
address@hidden, plus those ending with extensions in
+Uninteresting files are files whose names match regexp
address@hidden, plus files whose names end with extension in
 @code{dired-omit-extensions}.  @kbd{C-x M-o} (@code{dired-omit-mode})
 toggles its value, which is buffer-local.  Put
 
diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi
index 26d9c82..0d4e4ba 100644
--- a/doc/misc/efaq.texi
+++ b/doc/misc/efaq.texi
@@ -3536,7 +3536,7 @@ see @ref{Packages that do not come with Emacs}.
 
 The easiest way to add more features to your Emacs is to use the
 command @kbd{M-x list-packages}.  This contacts the
address@hidden:///elpa.gnu.org, GNU ELPA} (``Emacs Lisp Package Archive'')
address@hidden://elpa.gnu.org, GNU ELPA} (``Emacs Lisp Package Archive'')
 server and fetches the list of additional packages that it offers.
 These are GNU packages that are available for use with Emacs, but are
 distributed separately from Emacs itself, for reasons of space, etc.
@@ -3545,8 +3545,8 @@ available, and then Emacs can automatically download and 
install the
 packages that you select.  @xref{Packages,,, emacs, The GNU Emacs Manual}.
 
 There are other, non-GNU, Emacs Lisp package servers, including:
address@hidden://melpa.org/, MELPA}; and
address@hidden://marmalade-repo.org/, Marmalade}.  To use additional
address@hidden://melpa.org, MELPA}; and
address@hidden://marmalade-repo.org, Marmalade}.  To use additional
 package servers, customize the @code{package-archives} variable.  Be
 aware that installing a package can run arbitrary code, so only add
 sources that you trust.
@@ -3557,8 +3557,8 @@ GNU Emacs sources mailing list}, which is gatewayed to the
 connection between the two can be unreliable) is an official place
 where people can post or announce their extensions to Emacs.
 
-The @uref{http://emacswiki.org, Emacs Wiki} contains pointers to some
-additional extensions.  @uref{http://wikemacs.org, WikEmacs} is an
+The @uref{https://emacswiki.org, Emacs Wiki} contains pointers to some
+additional extensions.  @uref{https://wikemacs.org, WikEmacs} is an
 alternative wiki for Emacs.
 
 @uref{http://www.damtp.cam.ac.uk/user/sje30/emacs/ell.html, The Emacs
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index 2f7d840..fb9113f 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -26194,7 +26194,7 @@ Get the data under @code{key} for message @code{id}.
 If any extra entries are precious, their presence will make the
 registry keep the whole entry forever, even if there are no groups for
 the Message-ID and if the size limit of the registry is reached.  By
-default this is just @code{(marks)} so the custom registry marks are
+default this is just @code{(mark)} so the custom registry marks are
 precious.
 @end defvar
 
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index ff5c0be..614fb86 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -464,7 +464,7 @@ this case it is written as @code{host#port}.
 @cindex @option{plink} method
 
 If your local host runs an SSH client, and the remote host runs an SSH
-server, the most simple remote file name is
+server, the simplest remote file name is
 @address@hidden,user@@host,/path/to/file}}.  The remote file name
 @address@hidden,,}} opens a remote connection to yourself on the
 local host, and is taken often for testing @value{tramp}.
@@ -2459,9 +2459,10 @@ and @code{user@@} parts are optional.
 
 @defvar tramp-file-name-regexp
 This variable keeps a regexp which matches the selected remote file
-name syntax.  However, it is not recommended to use this variable in
-external packages, a call of @code{file-remote-p} is much more
-appropriate.
+name syntax.  Its value changes after every call of
address@hidden  However, it is not recommended to use
+this variable in external packages, a call of @code{file-remote-p} is
+much more appropriate.
 @ifinfo
 @pxref{Magic File Names, , , elisp}
 @end ifinfo
@@ -2537,6 +2538,14 @@ names on that host.
 When the configuration (@pxref{Customizing Completion}) includes user
 names, then the completion lists will account for the user names as well.
 
address@hidden tramp-completion-use-auth-sources
+Results from @code{auth-sources} search (@pxref{Using an
+authentication file}) are added to the completion candidates.  This
+search could be annoying, for example due to a passphrase request of
+the @file{~/.authinfo.gpg} authentication file.  The user option
address@hidden controls, whether such a
+search is performed during completion.
+
 Remote hosts previously visited or hosts whose connections are kept
 persistently (@pxref{Connection caching}) will be included in the
 completion lists.
@@ -2585,9 +2594,9 @@ directory contents.
 @cindex multi-hop, ad-hoc
 @cindex proxy hosts, ad-hoc
 
address@hidden file name syntax can accommodate ad hoc specification of
address@hidden file name syntax can accommodate ad-hoc specification of
 multiple proxies without using @code{tramp-default-proxies-alist}
-configuration setup(@pxref{Multi-hops}).
+configuration setup (@pxref{Multi-hops}).
 
 Each proxy is specified using the same syntax as the remote host
 specification minus the file name part.  Each hop is separated by a
@@ -2600,8 +2609,6 @@ proxy @samp{bird@@bastion} to a remote file on 
@samp{you@@remotehost}:
 @kbd{C-x C-f @address@hidden@@bastion|address@hidden@@address@hidden/path 
@key{RET}}
 @end example
 
-Proxies can take patterns @code{%h} or @code{%u}.
-
 @value{tramp} adds the ad-hoc definitions on the fly to
 @code{tramp-default-proxies-alist} and is available for re-use
 during that Emacs session.  Subsequent @value{tramp} connections to
@@ -2618,6 +2625,17 @@ For ad-hoc definitions to be saved automatically in
 @end lisp
 @end defopt
 
+Ad-hoc proxies can take patterns @code{%h} or @code{%u} like in
address@hidden  The following file name expands
+to user @code{root} on host @code{remotehost}, starting with an
address@hidden session on host @code{remotehost}:
address@hidden@address@hidden|address@hidden@value{postfix}}.
+
+On the other hand, if a trailing hop does not specifiy a host name,
+the host name of the previous hop is reused. Therefore, the following
+file name is equivalent to the previous example:
address@hidden@address@hidden|address@hidden@value{postfix}}.
+
 
 @node Remote processes
 @section Integration with other Emacs packages
diff --git a/etc/NEWS b/etc/NEWS
index d15f909..5d91bc4 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -66,9 +66,6 @@ to reduce differences between developer and production builds.
 This means you can now easily filter several major modes, as well
 as a single mode.
 
----
-*** New toggle 'ibuffer-do-toggle-lock', bound to 'L'.
-
 ** Gnus
 
 +++
@@ -123,12 +120,14 @@ the new version of the file again.)
 * Changes in Emacs 27.1
 
 +++
-** The function 'read-passwd' uses '*' as default character to hide passwords.
+** emacsclient now supports the 'EMACS_SOCKET_NAME' environment variable.
+The behavior is identical to 'EMACS_SERVER_FILE', in that the
+command-line value specified via '--socket-name' will override the
+environment, and the natural default to TMPDIR, then '/tmp', continues
+to apply.
 
----
-** New variable 'xft-ignore-color-fonts'.
-Default t means don't try to load color fonts when using Xft, as they
-often cause crashes.  Set it to nil if you really need those fonts.
++++
+** The function 'read-passwd' uses '*' as default character to hide passwords.
 
 ---
 ** The new option 'tooltip-resize-echo-area' avoids truncating tooltip text
@@ -172,7 +171,7 @@ the data.
 
 +++
 ** The Network Security Manager now allows more fine-grained control
-of what checks to run via the `network-security-protocol-checks'
+of what checks to run via the 'network-security-protocol-checks'
 variable.
 
 +++
@@ -297,6 +296,16 @@ in (info "(emacs) Directory Variables")
 
 * Changes in Specialized Modes and Packages in Emacs 27.1
 
+---
+** Follow mode
+In the current follow group of windows, "ghost" cursors are no longer
+displayed in the non-selected follow windows.  To get the old behavior
+back, customize follow-hide-ghost-cursors to nil.
+
+** Octave mode
+The mode is automatically enabled in files that start with the
+'function' keyword.
+
 ** project.el
 *** New commands project-search and project-query-replace
 
@@ -340,6 +349,13 @@ When no files are marked, all modified files are stashed, 
as before.
 
 *** The new hook 'vc-retrieve-tag-hook' runs after retrieving a tag.
 
+---
+*** 'vc-hg' now invokes 'smerge-mode' when visiting files.
+Code that attempted to invoke 'smerge-mode' when visiting an Hg file
+with conflicts existed in earlier versions of Emacs, but incorrectly
+never detected a conflict due to invalid assumptions about cached
+values.
+
 ** diff-mode
 *** Hunks are now automatically refined by default.
 To disable it, set the new defcustom 'diff-font-lock-refine' to nil.
@@ -356,7 +372,7 @@ shown in the currently selected window.
 ** Comint
 
 +++
-*** 'send-invisible' is now an obsolete alias for `comint-send-invisible'.
+*** 'send-invisible' is now an obsolete alias for 'comint-send-invisible'.
 Also, 'shell-strip-ctrl-m' is declared obsolete.
 
 +++
@@ -391,7 +407,7 @@ facilities to aid more casual SQL developers layout queries 
and
 complex expressions.
 
 *** 'sql-use-indent-support' (default t) enables SQL indention support.
-The `sql-indent' package from ELPA must be installed to get the
+The 'sql-indent' package from ELPA must be installed to get the
 indentation support in 'sql-mode' and 'sql-interactive-mode'.
 
 *** 'sql-mode-hook' and 'sql-interactive-mode-hook' changed.
@@ -420,6 +436,9 @@ This enables more efficient backends.  See the docstring of
 
 ** Package
 
+*** New function 'package-get-version' lets packages query their own version.
+Example use in auctex.el: (defconst auctex-version (package-get-version))
+
 *** New 'package-quickstart' feature.
 When 'package-quickstart' is non-nil, package.el precomputes a big autoloads
 file so that activation of packages can be done much faster, which can speed up
@@ -480,6 +499,11 @@ See the concept index in the Gnus manual for the 
'match-list' entry.
 article(s) to a pre-existing Message buffer, or create a new Message
 buffer with the article(s) attached.
 
+---
+*** New option 'nnir-notmuch-filter-group-names-function'.
+This option controls whether and how to use Gnus search groups as
+'path:' search terms to 'notmuch'.
+
 ** erc
 
 ---
@@ -580,6 +604,14 @@ can now be searched via 'C-s'.
 
 ** Search and Replace
 
+*** lazy-highlight-buffer highlights matches in the full buffer.
+It is useful in combination with lazy-highlight-cleanup customized to nil
+to leave matches highlighted in the whole buffer after exiting isearch.
+Also when lazy-highlight-buffer prepares highlighting in the buffer,
+navigation through the matches without flickering is more smooth.
+lazy-highlight-buffer-max-at-a-time controls the number of matches to
+highlight in one iteration while processing the full buffer.
+
 +++
 *** New isearch bindings.
 
@@ -744,9 +776,25 @@ are obsoleted in GVFS.
 *** Validated passwords are saved by auth-source backends which support this.
 
 +++
+*** During user and host name completion in the minibuffer, results
+from auth-source search are taken into account.  This can be disabled
+by setting user option 'tramp-completion-use-auth-sources' to nil.
+
++++
 *** The user option 'tramp-ignored-file-name-regexp' allows to disable
 Tramp for some look-alike remote file names.
 
++++
+*** For some connection methods, like "su" or "sudo", the host name in
+ad-hoc multi-hop file names must match the previous hop.
+
+** Rcirc
+
+---
+*** New user option 'rcirc-url-max-length'.
+Setting this option to an integer causes URLs displayed in Rcirc
+buffers to be truncated to that many characters.
+
 ** Register
 ---
 *** The return value of method 'register-val-describe' includes the
@@ -836,12 +884,18 @@ UUID at point.
 
 
 ** Interactive automatic highlighting
-
 +++
 *** 'highlight-regexp' can now highlight subexpressions.
 The now command accepts a prefix numeric argument to choose the
 subexpression.
 
+** Mouse display of minor mode menu
+
+---
+*** 'minor-mode-menu-from-indicator' now display full minor mode name.
+When there is no menu for a mode, display the mode name after the
+indicator instead of just the indicator (which is sometimes cryptic).
+
 
 * New Modes and Packages in Emacs 27.1
 
@@ -872,6 +926,9 @@ documentation of the new mode and its commands.
 
 * Incompatible Lisp Changes in Emacs 27.1
 
+** define-fringe-bitmap is always defined, even when Emacs is built
+without any GUI support.
+
 ---
 ** Just loading a theme's file no longer activates the theme's settings.
 Loading a theme with 'M-x load-theme' still activates the theme, as it
@@ -953,14 +1010,6 @@ default-directory-alist, dired-default-directory,
 dired-default-directory-alist, dired-enable-local-variables,
 dired-hack-local-variables, dired-local-variables-file, dired-omit-here-always.
 
-** The function 'display-buffer-in-major-side-window' no longer exists.
-It has been renamed as internal function 'window--make-major-side-window',
-however applications should instead call 'display-buffer-in-side-window'
-(passing the SIDE and SLOT parameters as elements of ALIST).  This approach
-is backwards-compatible with versions of Emacs in which the old function
-exists.  See the node "Displaying Buffers in Side Windows" in the ELisp
-manual for more details.
-
 ** garbage collection no longer treats miscellaneous objects specially;
 they are now allocated like any other pseudovector.  As a result, the
 'garbage-collect' and 'memory-use-count' functions no longer return a
diff --git a/etc/NEWS.18 b/etc/NEWS.18
index ab76c3c..81b1a39 100644
--- a/etc/NEWS.18
+++ b/etc/NEWS.18
@@ -810,7 +810,7 @@ The client/server work only on Berkeley Unix, since they 
use the Berkeley
 sockets mechanism for their communication.
 
 
-* Changes in Lisp programming in Emacs 18.
+* Changes in Lisp programming in Emacs 18
 
 ** Init file changes.
 
diff --git a/etc/NEWS.26 b/etc/NEWS.26
index 94bb45c..dfafe7c 100644
--- a/etc/NEWS.26
+++ b/etc/NEWS.26
@@ -25,18 +25,37 @@ webkit2gtk-4.0 package; version 2.12 or later is required.
 (This change was actually made in Emacs 26.1, but was not called out
 in its NEWS.)
 
++++
+** Installing Emacs now installs the emacs-module.h file.
+The emacs-module.h file is now installed in the system-wide include
+directory as part of the Emacs installation.  This allows to build
+Emacs modules outside of the Emacs source tree.
+
 
 * Startup Changes in Emacs 26.2
 
 
 * Changes in Emacs 26.2
 
+---
+** Emacs is now compliant with the latest version 11.0 of the Unicode Standard.
+
+---
+** New variable 'xft-ignore-color-fonts'.
+Default t means don't try to load color fonts when using Xft, as they
+often cause crashes.  Set it to nil if you really need those fonts.
+
 
 * Editing Changes in Emacs 26.2
 
 
 * Changes in Specialized Modes and Packages in Emacs 26.2
 
+** Ibuffer
+
+---
+*** New toggle 'ibuffer-do-toggle-lock', bound to 'L'.
+
 ** Imenu
 
 ---
@@ -123,6 +142,25 @@ remove 'buffer-switch' from the list of events in
 
 * Lisp Changes in Emacs 26.2
 
++++
+** The new function 'read-answer' accepts either long or short answers
+depending on the new customizable variable 'read-answer-short'.
+
++++
+** New function 'assoc-delete-all'.
+Like 'assq-delete-all', but uses 'equal' for comparison.
+
+---
+** The function 'thing-at-point' behaves as before Emacs 26.1.
+The behavior of 'thing-at-point' when called with argument 'list' has
+changed in Emacs 26.1, in that it didn't consider text inside comments
+and strings as a potential list.  This change is now reverted, and
+'thing-at-point' behaves like it did before Emacs 26.1.
+
+To cater to use cases where comments and strings are to be ignored
+when looking for a list, the function 'list-at-point' now takes an
+optional argument to do so.
+
 
 * Changes in Emacs 26.2 on Non-Free Operating Systems
 
@@ -1391,6 +1429,13 @@ passphrases, but it was also removed from other pinentry 
programs as
 the attack is unrealistic on modern computer systems which don't
 utilize swap memory usually.
 
+** The function 'display-buffer-in-major-side-window' no longer exists.
+It has been renamed as internal function 'window--make-major-side-window',
+however applications should instead call 'display-buffer-in-side-window'
+(passing the SIDE and SLOT parameters as elements of ALIST).  This approach
+is backwards-compatible with versions of Emacs in which the old function
+exists.  See the node "Displaying Buffers in Side Windows" in the ELisp
+manual for more details.
 
 * Lisp Changes in Emacs 26.1
 
diff --git a/etc/PROBLEMS b/etc/PROBLEMS
index eba3420..0cbcca4 100644
--- a/etc/PROBLEMS
+++ b/etc/PROBLEMS
@@ -192,6 +192,18 @@ Upgrading to a newer version of Exceed has been reported 
to prevent
 these crashes.  You should consider switching to a free X server, such
 as Xming or Cygwin/X.
 
+** Emacs crashes with SIGSEGV in XtInitializeWidgetClass.
+
+It crashes on X, but runs fine when called with option "-nw".
+
+This has been observed when Emacs is linked with GNU ld but without passing
+the -z nocombreloc flag.  Emacs normally knows to pass the -z nocombreloc
+flag when needed, so if you come across a situation where the flag is
+necessary but missing, please report it via M-x report-emacs-bug.
+
+On platforms such as Solaris, you can also work around this problem by
+configuring your compiler to use the native linker instead of GNU ld.
+
 ** When Emacs is compiled with Gtk+, closing a display kills Emacs.
 
 There is a long-standing bug in GTK that prevents it from recovering
@@ -2587,6 +2599,13 @@ please call support for your X-server and see if you can 
get a fix.
 If you do, please send it to address@hidden so we can list it here.
 
 
+* Runtime problems specific to macOS
+
+** macOS doesn't come with libxpm, so only XPM3 is supported.
+
+Libxpm is available for macOS as part of the XQuartz project.
+
+
 * Build-time problems
 
 ** Configuration
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c
index 4fe3a58..42b8dd6 100644
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@ -1409,6 +1409,9 @@ set_socket (int no_exit_if_error)
 
 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
   /* Explicit --socket-name argument.  */
+  if (!socket_name)
+    socket_name = egetenv ("EMACS_SOCKET_NAME");
+
   if (socket_name)
     {
       s = set_local_socket (socket_name);
diff --git a/lib/cdefs.h b/lib/cdefs.h
new file mode 100644
index 0000000..2d620cc
--- /dev/null
+++ b/lib/cdefs.h
@@ -0,0 +1,514 @@
+/* Copyright (C) 1992-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef        _SYS_CDEFS_H
+#define        _SYS_CDEFS_H    1
+
+/* We are almost always included from features.h. */
+#ifndef _FEATURES_H
+# include <features.h>
+#endif
+
+/* The GNU libc does not support any K&R compilers or the traditional mode
+   of ISO C compilers anymore.  Check for some of the combinations not
+   anymore supported.  */
+#if defined __GNUC__ && !defined __STDC__
+# error "You need a ISO C conforming compiler to use the glibc headers"
+#endif
+
+/* Some user header file might have defined this before.  */
+#undef __P
+#undef __PMT
+
+#ifdef __GNUC__
+
+/* All functions, except those with callbacks or those that
+   synchronize memory, are leaf functions.  */
+# if __GNUC_PREREQ (4, 6) && !defined _LIBC
+#  define __LEAF , __leaf__
+#  define __LEAF_ATTR __attribute__ ((__leaf__))
+# else
+#  define __LEAF
+#  define __LEAF_ATTR
+# endif
+
+/* GCC can always grok prototypes.  For C++ programs we add throw()
+   to help it optimize the function calls.  But this works only with
+   gcc 2.8.x and egcs.  For gcc 3.2 and up we even mark C functions
+   as non-throwing using a function attribute since programs can use
+   the -fexceptions options for C code as well.  */
+# if !defined __cplusplus && __GNUC_PREREQ (3, 3)
+#  define __THROW      __attribute__ ((__nothrow__ __LEAF))
+#  define __THROWNL    __attribute__ ((__nothrow__))
+#  define __NTH(fct)   __attribute__ ((__nothrow__ __LEAF)) fct
+#  define __NTHNL(fct)  __attribute__ ((__nothrow__)) fct
+# else
+#  if defined __cplusplus && __GNUC_PREREQ (2,8)
+#   define __THROW     throw ()
+#   define __THROWNL   throw ()
+#   define __NTH(fct)  __LEAF_ATTR fct throw ()
+#   define __NTHNL(fct) fct throw ()
+#  else
+#   define __THROW
+#   define __THROWNL
+#   define __NTH(fct)  fct
+#   define __NTHNL(fct) fct
+#  endif
+# endif
+
+#else  /* Not GCC.  */
+
+# if (defined __cplusplus                                              \
+      || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))
+#  define __inline     inline
+# else
+#  define __inline             /* No inline functions.  */
+# endif
+
+# define __THROW
+# define __THROWNL
+# define __NTH(fct)    fct
+
+#endif /* GCC.  */
+
+/* Compilers that are not clang may object to
+       #if defined __clang__ && __has_extension(...)
+   even though they do not need to evaluate the right-hand side of the &&.  */
+#if defined __clang__ && defined __has_extension
+# define __glibc_clang_has_extension(ext) __has_extension (ext)
+#else
+# define __glibc_clang_has_extension(ext) 0
+#endif
+
+/* These two macros are not used in glibc anymore.  They are kept here
+   only because some other projects expect the macros to be defined.  */
+#define __P(args)      args
+#define __PMT(args)    args
+
+/* For these things, GCC behaves the ANSI way normally,
+   and the non-ANSI way under -traditional.  */
+
+#define __CONCAT(x,y)  x ## y
+#define __STRING(x)    #x
+
+/* This is not a typedef so `const __ptr_t' does the right thing.  */
+#define __ptr_t void *
+
+
+/* C++ needs to know that types and declarations are C, not C++.  */
+#ifdef __cplusplus
+# define __BEGIN_DECLS extern "C" {
+# define __END_DECLS   }
+#else
+# define __BEGIN_DECLS
+# define __END_DECLS
+#endif
+
+
+/* Fortify support.  */
+#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
+#define __bos0(ptr) __builtin_object_size (ptr, 0)
+
+#if __GNUC_PREREQ (4,3)
+# define __warndecl(name, msg) \
+  extern void name (void) __attribute__((__warning__ (msg)))
+# define __warnattr(msg) __attribute__((__warning__ (msg)))
+# define __errordecl(name, msg) \
+  extern void name (void) __attribute__((__error__ (msg)))
+#else
+# define __warndecl(name, msg) extern void name (void)
+# define __warnattr(msg)
+# define __errordecl(name, msg) extern void name (void)
+#endif
+
+/* Support for flexible arrays.
+   Headers that should use flexible arrays only if they're "real"
+   (e.g. only if they won't affect sizeof()) should test
+   #if __glibc_c99_flexarr_available.  */
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+# define __flexarr     []
+# define __glibc_c99_flexarr_available 1
+#elif __GNUC_PREREQ (2,97)
+/* GCC 2.97 supports C99 flexible array members as an extension,
+   even when in C89 mode or compiling C++ (any version).  */
+# define __flexarr     []
+# define __glibc_c99_flexarr_available 1
+#elif defined __GNUC__
+/* Pre-2.97 GCC did not support C99 flexible arrays but did have
+   an equivalent extension with slightly different notation.  */
+# define __flexarr     [0]
+# define __glibc_c99_flexarr_available 1
+#else
+/* Some other non-C99 compiler.  Approximate with [1].  */
+# define __flexarr     [1]
+# define __glibc_c99_flexarr_available 0
+#endif
+
+
+/* __asm__ ("xyz") is used throughout the headers to rename functions
+   at the assembly language level.  This is wrapped by the __REDIRECT
+   macro, in order to support compilers that can do this some other
+   way.  When compilers don't support asm-names at all, we have to do
+   preprocessor tricks instead (which don't have exactly the right
+   semantics, but it's the best we can do).
+
+   Example:
+   int __REDIRECT(setpgrp, (__pid_t pid, __pid_t pgrp), setpgid); */
+
+#if defined __GNUC__ && __GNUC__ >= 2
+
+# define __REDIRECT(name, proto, alias) name proto __asm__ (__ASMNAME (#alias))
+# ifdef __cplusplus
+#  define __REDIRECT_NTH(name, proto, alias) \
+     name proto __THROW __asm__ (__ASMNAME (#alias))
+#  define __REDIRECT_NTHNL(name, proto, alias) \
+     name proto __THROWNL __asm__ (__ASMNAME (#alias))
+# else
+#  define __REDIRECT_NTH(name, proto, alias) \
+     name proto __asm__ (__ASMNAME (#alias)) __THROW
+#  define __REDIRECT_NTHNL(name, proto, alias) \
+     name proto __asm__ (__ASMNAME (#alias)) __THROWNL
+# endif
+# define __ASMNAME(cname)  __ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+# define __ASMNAME2(prefix, cname) __STRING (prefix) cname
+
+/*
+#elif __SOME_OTHER_COMPILER__
+
+# define __REDIRECT(name, proto, alias) name proto; \
+       _Pragma("let " #name " = " #alias)
+*/
+#endif
+
+/* GCC has various useful declarations that can be made with the
+   `__attribute__' syntax.  All of the ways we use this do fine if
+   they are omitted for compilers that don't understand it. */
+#if !defined __GNUC__ || __GNUC__ < 2
+# define __attribute__(xyz)    /* Ignore */
+#endif
+
+/* At some point during the gcc 2.96 development the `malloc' attribute
+   for functions was introduced.  We don't want to use it unconditionally
+   (although this would be possible) since it generates warnings.  */
+#if __GNUC_PREREQ (2,96)
+# define __attribute_malloc__ __attribute__ ((__malloc__))
+#else
+# define __attribute_malloc__ /* Ignore */
+#endif
+
+/* Tell the compiler which arguments to an allocation function
+   indicate the size of the allocation.  */
+#if __GNUC_PREREQ (4, 3)
+# define __attribute_alloc_size__(params) \
+  __attribute__ ((__alloc_size__ params))
+#else
+# define __attribute_alloc_size__(params) /* Ignore.  */
+#endif
+
+/* At some point during the gcc 2.96 development the `pure' attribute
+   for functions was introduced.  We don't want to use it unconditionally
+   (although this would be possible) since it generates warnings.  */
+#if __GNUC_PREREQ (2,96)
+# define __attribute_pure__ __attribute__ ((__pure__))
+#else
+# define __attribute_pure__ /* Ignore */
+#endif
+
+/* This declaration tells the compiler that the value is constant.  */
+#if __GNUC_PREREQ (2,5)
+# define __attribute_const__ __attribute__ ((__const__))
+#else
+# define __attribute_const__ /* Ignore */
+#endif
+
+/* At some point during the gcc 3.1 development the `used' attribute
+   for functions was introduced.  We don't want to use it unconditionally
+   (although this would be possible) since it generates warnings.  */
+#if __GNUC_PREREQ (3,1)
+# define __attribute_used__ __attribute__ ((__used__))
+# define __attribute_noinline__ __attribute__ ((__noinline__))
+#else
+# define __attribute_used__ __attribute__ ((__unused__))
+# define __attribute_noinline__ /* Ignore */
+#endif
+
+/* Since version 3.2, gcc allows marking deprecated functions.  */
+#if __GNUC_PREREQ (3,2)
+# define __attribute_deprecated__ __attribute__ ((__deprecated__))
+#else
+# define __attribute_deprecated__ /* Ignore */
+#endif
+
+/* Since version 4.5, gcc also allows one to specify the message printed
+   when a deprecated function is used.  clang claims to be gcc 4.2, but
+   may also support this feature.  */
+#if __GNUC_PREREQ (4,5) || \
+    __glibc_clang_has_extension (__attribute_deprecated_with_message__)
+# define __attribute_deprecated_msg__(msg) \
+        __attribute__ ((__deprecated__ (msg)))
+#else
+# define __attribute_deprecated_msg__(msg) __attribute_deprecated__
+#endif
+
+/* At some point during the gcc 2.8 development the `format_arg' attribute
+   for functions was introduced.  We don't want to use it unconditionally
+   (although this would be possible) since it generates warnings.
+   If several `format_arg' attributes are given for the same function, in
+   gcc-3.0 and older, all but the last one are ignored.  In newer gccs,
+   all designated arguments are considered.  */
+#if __GNUC_PREREQ (2,8)
+# define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x)))
+#else
+# define __attribute_format_arg__(x) /* Ignore */
+#endif
+
+/* At some point during the gcc 2.97 development the `strfmon' format
+   attribute for functions was introduced.  We don't want to use it
+   unconditionally (although this would be possible) since it
+   generates warnings.  */
+#if __GNUC_PREREQ (2,97)
+# define __attribute_format_strfmon__(a,b) \
+  __attribute__ ((__format__ (__strfmon__, a, b)))
+#else
+# define __attribute_format_strfmon__(a,b) /* Ignore */
+#endif
+
+/* The nonnull function attribute marks pointer parameters that
+   must not be NULL.  Do not define __nonnull if it is already defined,
+   for portability when this file is used in Gnulib.  */
+#ifndef __nonnull
+# if __GNUC_PREREQ (3,3)
+#  define __nonnull(params) __attribute__ ((__nonnull__ params))
+# else
+#  define __nonnull(params)
+# endif
+#endif
+
+/* If fortification mode, we warn about unused results of certain
+   function calls which can lead to problems.  */
+#if __GNUC_PREREQ (3,4)
+# define __attribute_warn_unused_result__ \
+   __attribute__ ((__warn_unused_result__))
+# if defined __USE_FORTIFY_LEVEL && __USE_FORTIFY_LEVEL > 0
+#  define __wur __attribute_warn_unused_result__
+# endif
+#else
+# define __attribute_warn_unused_result__ /* empty */
+#endif
+#ifndef __wur
+# define __wur /* Ignore */
+#endif
+
+/* Forces a function to be always inlined.  */
+#if __GNUC_PREREQ (3,2)
+/* The Linux kernel defines __always_inline in stddef.h (283d7573), and
+   it conflicts with this definition.  Therefore undefine it first to
+   allow either header to be included first.  */
+# undef __always_inline
+# define __always_inline __inline __attribute__ ((__always_inline__))
+#else
+# undef __always_inline
+# define __always_inline __inline
+#endif
+
+/* Associate error messages with the source location of the call site rather
+   than with the source location inside the function.  */
+#if __GNUC_PREREQ (4,3)
+# define __attribute_artificial__ __attribute__ ((__artificial__))
+#else
+# define __attribute_artificial__ /* Ignore */
+#endif
+
+/* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
+   inline semantics, unless -fgnu89-inline is used.  Using __GNUC_STDC_INLINE__
+   or __GNUC_GNU_INLINE is not a good enough check for gcc because gcc versions
+   older than 4.3 may define these macros and still not guarantee GNU inlining
+   semantics.
+
+   clang++ identifies itself as gcc-4.2, but has support for GNU inlining
+   semantics, that can be checked fot by using the __GNUC_STDC_INLINE_ and
+   __GNUC_GNU_INLINE__ macro definitions.  */
+#if (!defined __cplusplus || __GNUC_PREREQ (4,3) \
+     || (defined __clang__ && (defined __GNUC_STDC_INLINE__ \
+                              || defined __GNUC_GNU_INLINE__)))
+# if defined __GNUC_STDC_INLINE__ || defined __cplusplus
+#  define __extern_inline extern __inline __attribute__ ((__gnu_inline__))
+#  define __extern_always_inline \
+  extern __always_inline __attribute__ ((__gnu_inline__))
+# else
+#  define __extern_inline extern __inline
+#  define __extern_always_inline extern __always_inline
+# endif
+#endif
+
+#ifdef __extern_always_inline
+# define __fortify_function __extern_always_inline __attribute_artificial__
+#endif
+
+/* GCC 4.3 and above allow passing all anonymous arguments of an
+   __extern_always_inline function to some other vararg function.  */
+#if __GNUC_PREREQ (4,3)
+# define __va_arg_pack() __builtin_va_arg_pack ()
+# define __va_arg_pack_len() __builtin_va_arg_pack_len ()
+#endif
+
+/* It is possible to compile containing GCC extensions even if GCC is
+   run in pedantic mode if the uses are carefully marked using the
+   `__extension__' keyword.  But this is not generally available before
+   version 2.8.  */
+#if !__GNUC_PREREQ (2,8)
+# define __extension__         /* Ignore */
+#endif
+
+/* __restrict is known in EGCS 1.2 and above. */
+#if !__GNUC_PREREQ (2,92)
+# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#  define __restrict   restrict
+# else
+#  define __restrict   /* Ignore */
+# endif
+#endif
+
+/* ISO C99 also allows to declare arrays as non-overlapping.  The syntax is
+     array_name[restrict]
+   GCC 3.1 supports this.  */
+#if __GNUC_PREREQ (3,1) && !defined __GNUG__
+# define __restrict_arr        __restrict
+#else
+# ifdef __GNUC__
+#  define __restrict_arr       /* Not supported in old GCC.  */
+# else
+#  if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#   define __restrict_arr      restrict
+#  else
+/* Some other non-C99 compiler.  */
+#   define __restrict_arr      /* Not supported.  */
+#  endif
+# endif
+#endif
+
+#if __GNUC__ >= 3
+# define __glibc_unlikely(cond)        __builtin_expect ((cond), 0)
+# define __glibc_likely(cond)  __builtin_expect ((cond), 1)
+#else
+# define __glibc_unlikely(cond)        (cond)
+# define __glibc_likely(cond)  (cond)
+#endif
+
+#ifdef __has_attribute
+# define __glibc_has_attribute(attr)   __has_attribute (attr)
+#else
+# define __glibc_has_attribute(attr)   0
+#endif
+
+#if (!defined _Noreturn \
+     && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
+     &&  !__GNUC_PREREQ (4,7))
+# if __GNUC_PREREQ (2,8)
+#  define _Noreturn __attribute__ ((__noreturn__))
+# else
+#  define _Noreturn
+# endif
+#endif
+
+#if __GNUC_PREREQ (8, 0)
+/* Describes a char array whose address can safely be passed as the first
+   argument to strncpy and strncat, as the char array is not necessarily
+   a NUL-terminated string.  */
+# define __attribute_nonstring__ __attribute__ ((__nonstring__))
+#else
+# define __attribute_nonstring__
+#endif
+
+#if (!defined _Static_assert && !defined __cplusplus \
+     && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
+     && (!__GNUC_PREREQ (4, 6) || defined __STRICT_ANSI__))
+# define _Static_assert(expr, diagnostic) \
+    extern int (*__Static_assert_function (void)) \
+      [!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })]
+#endif
+
+/* The #ifndef lets Gnulib avoid including these on non-glibc
+   platforms, where the includes typically do not exist.  */
+#ifndef __WORDSIZE
+# include <bits/wordsize.h>
+# include <bits/long-double.h>
+#endif
+
+#if defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH
+# define __LDBL_COMPAT 1
+# ifdef __REDIRECT
+#  define __LDBL_REDIR1(name, proto, alias) __REDIRECT (name, proto, alias)
+#  define __LDBL_REDIR(name, proto) \
+  __LDBL_REDIR1 (name, proto, __nldbl_##name)
+#  define __LDBL_REDIR1_NTH(name, proto, alias) __REDIRECT_NTH (name, proto, 
alias)
+#  define __LDBL_REDIR_NTH(name, proto) \
+  __LDBL_REDIR1_NTH (name, proto, __nldbl_##name)
+#  define __LDBL_REDIR1_DECL(name, alias) \
+  extern __typeof (name) name __asm (__ASMNAME (#alias));
+#  define __LDBL_REDIR_DECL(name) \
+  extern __typeof (name) name __asm (__ASMNAME ("__nldbl_" #name));
+#  define __REDIRECT_LDBL(name, proto, alias) \
+  __LDBL_REDIR1 (name, proto, __nldbl_##alias)
+#  define __REDIRECT_NTH_LDBL(name, proto, alias) \
+  __LDBL_REDIR1_NTH (name, proto, __nldbl_##alias)
+# endif
+#endif
+#if !defined __LDBL_COMPAT || !defined __REDIRECT
+# define __LDBL_REDIR1(name, proto, alias) name proto
+# define __LDBL_REDIR(name, proto) name proto
+# define __LDBL_REDIR1_NTH(name, proto, alias) name proto __THROW
+# define __LDBL_REDIR_NTH(name, proto) name proto __THROW
+# define __LDBL_REDIR_DECL(name)
+# ifdef __REDIRECT
+#  define __REDIRECT_LDBL(name, proto, alias) __REDIRECT (name, proto, alias)
+#  define __REDIRECT_NTH_LDBL(name, proto, alias) \
+  __REDIRECT_NTH (name, proto, alias)
+# endif
+#endif
+
+/* __glibc_macro_warning (MESSAGE) issues warning MESSAGE.  This is
+   intended for use in preprocessor macros.
+
+   Note: MESSAGE must be a _single_ string; concatenation of string
+   literals is not supported.  */
+#if __GNUC_PREREQ (4,8) || __glibc_clang_prereq (3,5)
+# define __glibc_macro_warning1(message) _Pragma (#message)
+# define __glibc_macro_warning(message) \
+  __glibc_macro_warning1 (GCC warning message)
+#else
+# define __glibc_macro_warning(msg)
+#endif
+
+/* Generic selection (ISO C11) is a C-only feature, available in GCC
+   since version 4.9.  Previous versions do not provide generic
+   selection, even though they might set __STDC_VERSION__ to 201112L,
+   when in -std=c11 mode.  Thus, we must check for !defined __GNUC__
+   when testing __STDC_VERSION__ for generic selection support.
+   On the other hand, Clang also defines __GNUC__, so a clang-specific
+   check is required to enable the use of generic selection.  */
+#if !defined __cplusplus \
+    && (__GNUC_PREREQ (4, 9) \
+       || __glibc_clang_has_extension (c_generic_selections) \
+       || (!defined __GNUC__ && defined __STDC_VERSION__ \
+           && __STDC_VERSION__ >= 201112L))
+# define __HAVE_GENERIC_SELECTION 1
+#else
+# define __HAVE_GENERIC_SELECTION 0
+#endif
+
+#endif  /* sys/cdefs.h */
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index 431d0c0..982d3c5 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -1040,6 +1040,7 @@ gamegroup = @gamegroup@
 gameuser = @gameuser@
 gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7 = 
@gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7@
 gl_GNULIB_ENABLED_2049e887c7e5308faad27b3f894bb8c9 = 
@gl_GNULIB_ENABLED_2049e887c7e5308faad27b3f894bb8c9@
+gl_GNULIB_ENABLED_21ee726a3540c09237a8e70c0baf7467 = 
@gl_GNULIB_ENABLED_21ee726a3540c09237a8e70c0baf7467@
 gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b = 
@gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b@
 gl_GNULIB_ENABLED_37f71b604aa9c54446783d80f42fe547 = 
@gl_GNULIB_ENABLED_37f71b604aa9c54446783d80f42fe547@
 gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31 = 
@gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31@
@@ -1900,6 +1901,17 @@ EXTRA_DIST += inttypes.in.h
 endif
 ## end   gnulib module inttypes-incomplete
 
+## begin gnulib module libc-config
+ifeq (,$(OMIT_GNULIB_MODULE_libc-config))
+
+ifneq (,$(gl_GNULIB_ENABLED_21ee726a3540c09237a8e70c0baf7467))
+
+endif
+EXTRA_DIST += cdefs.h libc-config.h
+
+endif
+## end   gnulib module libc-config
+
 ## begin gnulib module limits-h
 ifeq (,$(OMIT_GNULIB_MODULE_limits-h))
 
diff --git a/lib/libc-config.h b/lib/libc-config.h
new file mode 100644
index 0000000..d7b4093
--- /dev/null
+++ b/lib/libc-config.h
@@ -0,0 +1,174 @@
+/* System definitions for code taken from the GNU C Library
+
+   Copyright 2017-2018 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* Written by Paul Eggert.  */
+
+/* This is intended to be a good-enough substitute for glibc system
+   macros like those defined in <sys/cdefs.h>, so that Gnulib code
+   shared with glibc can do this as the first #include:
+
+     #ifndef _LIBC
+     # include <libc-config.h>
+     #endif
+
+   When compiled as part of glibc this is a no-op; when compiled as
+   part of Gnulib this includes Gnulib's <config.h> and defines macros
+   that glibc library code would normally assume.  */
+
+#include <config.h>
+
+/* On glibc this includes <features.h> and <sys/cdefs.h> and #defines
+   _FEATURES_H, __WORDSIZE, and __set_errno.  On FreeBSD 11 it
+   includes <sys/cdefs.h> which defines __nonnull.  Elsewhere it
+   is harmless.  */
+#include <errno.h>
+
+/* From glibc <errno.h>.  */
+#ifndef __set_errno
+# define __set_errno(val) (errno = (val))
+#endif
+
+/* From glibc <features.h>.  */
+
+#ifndef __GNUC_PREREQ
+# if defined __GNUC__ && defined __GNUC_MINOR__
+#  define __GNUC_PREREQ(maj, min) ((maj) < __GNUC__ + ((min) <= 
__GNUC_MINOR__))
+# else
+#  define __GNUC_PREREQ(maj, min) 0
+# endif
+#endif
+
+#ifndef __glibc_clang_prereq
+# if defined __clang_major__ && defined __clang_minor__
+#  define __glibc_clang_prereq(maj, min) \
+     ((maj) < __clang_major__ + ((min) <= __clang_minor__))
+# else
+#  define __glibc_clang_prereq(maj, min) 0
+# endif
+#endif
+
+
+/* Prepare to include <cdefs.h>, which is our copy of glibc
+   <sys/cdefs.h>.  */
+
+/* Define _FEATURES_H so that <cdefs.h> does not include <features.h>.  */
+#ifndef _FEATURES_H
+# define _FEATURES_H 1
+#endif
+/* Define __WORDSIZE so that <cdefs.h> does not attempt to include
+   nonexistent files.  Make it a syntax error, since Gnulib does not
+   use __WORDSIZE now, and if Gnulib uses it later the syntax error
+   will let us know that __WORDSIZE needs configuring.  */
+#ifndef __WORDSIZE
+# define __WORDSIZE %%%
+#endif
+/* Undef the macros unconditionally defined by our copy of glibc
+   <sys/cdefs.h>, so that they do not clash with any system-defined
+   versions.  */
+#undef _SYS_CDEFS_H
+#undef __ASMNAME
+#undef __ASMNAME2
+#undef __BEGIN_DECLS
+#undef __CONCAT
+#undef __END_DECLS
+#undef __HAVE_GENERIC_SELECTION
+#undef __LDBL_COMPAT
+#undef __LDBL_REDIR
+#undef __LDBL_REDIR1
+#undef __LDBL_REDIR1_DECL
+#undef __LDBL_REDIR1_NTH
+#undef __LDBL_REDIR_DECL
+#undef __LDBL_REDIR_NTH
+#undef __LEAF
+#undef __LEAF_ATTR
+#undef __NTH
+#undef __NTHNL
+#undef __P
+#undef __PMT
+#undef __REDIRECT
+#undef __REDIRECT_LDBL
+#undef __REDIRECT_NTH
+#undef __REDIRECT_NTHNL
+#undef __REDIRECT_NTH_LDBL
+#undef __STRING
+#undef __THROW
+#undef __THROWNL
+#undef __always_inline
+#undef __attribute__
+#undef __attribute_alloc_size__
+#undef __attribute_artificial__
+#undef __attribute_const__
+#undef __attribute_deprecated__
+#undef __attribute_deprecated_msg__
+#undef __attribute_format_arg__
+#undef __attribute_format_strfmon__
+#undef __attribute_malloc__
+#undef __attribute_noinline__
+#undef __attribute_nonstring__
+#undef __attribute_pure__
+#undef __attribute_used__
+#undef __attribute_warn_unused_result__
+#undef __bos
+#undef __bos0
+#undef __errordecl
+#undef __extension__
+#undef __extern_always_inline
+#undef __extern_inline
+#undef __flexarr
+#undef __fortify_function
+#undef __glibc_c99_flexarr_available
+#undef __glibc_clang_has_extension
+#undef __glibc_likely
+#undef __glibc_macro_warning
+#undef __glibc_macro_warning1
+#undef __glibc_unlikely
+#undef __inline
+#undef __ptr_t
+#undef __restrict
+#undef __restrict_arr
+#undef __va_arg_pack
+#undef __va_arg_pack_len
+#undef __warnattr
+#undef __warndecl
+
+/* Include our copy of glibc <sys/cdefs.h>.  */
+#include <cdefs.h>
+
+/* <cdefs.h> __inline is too pessimistic for non-GCC.  */
+#undef __inline
+#ifndef HAVE___INLINE
+# if 199901 <= __STDC_VERSION__ || defined inline
+#  define __inline inline
+# else
+#  define __inline
+# endif
+#endif
+
+
+/* A substitute for glibc <libc-symbols.h>, good enough for Gnulib.  */
+#define attribute_hidden
+#define libc_hidden_proto(name, ...)
+#define libc_hidden_def(name)
+#define libc_hidden_weak(name)
+#define libc_hidden_ver(local, name)
+#define strong_alias(name, aliasname)
+#define weak_alias(name, aliasname)
+
+/* A substitute for glibc <shlib-compat.h>, good enough for Gnulib.  */
+#define SHLIB_COMPAT(lib, introduced, obsoleted) 0
+#define versioned_symbol(lib, local, symbol, version)
diff --git a/lib/regcomp.c b/lib/regcomp.c
index 0e4816c..0b05a63 100644
--- a/lib/regcomp.c
+++ b/lib/regcomp.c
@@ -476,7 +476,7 @@ regcomp (regex_t *_Restrict_ preg, const char *_Restrict_ 
pattern, int cflags)
 
   /* Try to allocate space for the fastmap.  */
   preg->fastmap = re_malloc (char, SBC_MAX);
-  if (BE (preg->fastmap == NULL, 0))
+  if (__glibc_unlikely (preg->fastmap == NULL))
     return REG_ESPACE;
 
   syntax |= (cflags & REG_ICASE) ? RE_ICASE : 0;
@@ -502,7 +502,7 @@ regcomp (regex_t *_Restrict_ preg, const char *_Restrict_ 
pattern, int cflags)
     ret = REG_EPAREN;
 
   /* We have already checked preg->fastmap != NULL.  */
-  if (BE (ret == REG_NOERROR, 1))
+  if (__glibc_likely (ret == REG_NOERROR))
     /* Compute the fastmap now, since regexec cannot modify the pattern
        buffer.  This function never fails in this implementation.  */
     (void) re_compile_fastmap (preg);
@@ -529,10 +529,9 @@ regerror (int errcode, const regex_t *_Restrict_ preg, 
char *_Restrict_ errbuf,
 {
   const char *msg;
   size_t msg_size;
+  int nerrcodes = sizeof __re_error_msgid_idx / sizeof __re_error_msgid_idx[0];
 
-  if (BE (errcode < 0
-         || errcode >= (int) (sizeof (__re_error_msgid_idx)
-                              / sizeof (__re_error_msgid_idx[0])), 0))
+  if (__glibc_unlikely (errcode < 0 || errcode >= nerrcodes))
     /* Only error codes returned by the rest of the code should be passed
        to this routine.  If we are given anything else, or if other regex
        code generates an invalid error code, then the program has a bug.
@@ -543,10 +542,10 @@ regerror (int errcode, const regex_t *_Restrict_ preg, 
char *_Restrict_ errbuf,
 
   msg_size = strlen (msg) + 1; /* Includes the null.  */
 
-  if (BE (errbuf_size != 0, 1))
+  if (__glibc_likely (errbuf_size != 0))
     {
       size_t cpy_size = msg_size;
-      if (BE (msg_size > errbuf_size, 0))
+      if (__glibc_unlikely (msg_size > errbuf_size))
        {
          cpy_size = errbuf_size - 1;
          errbuf[cpy_size] = '\0';
@@ -644,7 +643,7 @@ void
 regfree (regex_t *preg)
 {
   re_dfa_t *dfa = preg->buffer;
-  if (BE (dfa != NULL, 1))
+  if (__glibc_likely (dfa != NULL))
     {
       lock_fini (dfa->lock);
       free_dfa_content (dfa);
@@ -754,7 +753,7 @@ re_compile_internal (regex_t *preg, const char * pattern, 
size_t length,
 
   /* Initialize the dfa.  */
   dfa = preg->buffer;
-  if (BE (preg->allocated < sizeof (re_dfa_t), 0))
+  if (__glibc_unlikely (preg->allocated < sizeof (re_dfa_t)))
     {
       /* If zero allocated, but buffer is non-null, try to realloc
         enough space.  This loses if buffer's address is bogus, but
@@ -769,9 +768,9 @@ re_compile_internal (regex_t *preg, const char * pattern, 
size_t length,
   preg->used = sizeof (re_dfa_t);
 
   err = init_dfa (dfa, length);
-  if (BE (err == REG_NOERROR && lock_init (dfa->lock) != 0, 0))
+  if (__glibc_unlikely (err == REG_NOERROR && lock_init (dfa->lock) != 0))
     err = REG_ESPACE;
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     {
       free_dfa_content (dfa);
       preg->buffer = NULL;
@@ -786,7 +785,7 @@ re_compile_internal (regex_t *preg, const char * pattern, 
size_t length,
 
   err = re_string_construct (&regexp, pattern, length, preg->translate,
                             (syntax & RE_ICASE) != 0, dfa);
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     {
     re_compile_internal_free_return:
       free_workarea_compile (preg);
@@ -801,12 +800,12 @@ re_compile_internal (regex_t *preg, const char * pattern, 
size_t length,
   /* Parse the regular expression, and build a structure tree.  */
   preg->re_nsub = 0;
   dfa->str_tree = parse (&regexp, preg, syntax, &err);
-  if (BE (dfa->str_tree == NULL, 0))
+  if (__glibc_unlikely (dfa->str_tree == NULL))
     goto re_compile_internal_free_return;
 
   /* Analyze the tree and create the nfa.  */
   err = analyze (preg);
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     goto re_compile_internal_free_return;
 
 #ifdef RE_ENABLE_I18N
@@ -822,7 +821,7 @@ re_compile_internal (regex_t *preg, const char * pattern, 
size_t length,
   free_workarea_compile (preg);
   re_string_destruct (&regexp);
 
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     {
       lock_fini (dfa->lock);
       free_dfa_content (dfa);
@@ -864,7 +863,8 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
      calculation below, and for similar doubling calculations
      elsewhere.  And it's <= rather than <, because some of the
      doubling calculations add 1 afterwards.  */
-  if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) / 2 <= pat_len, 0))
+  if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size) / 2
+                       <= pat_len))
     return REG_ESPACE;
 
   dfa->nodes_alloc = pat_len + 1;
@@ -908,7 +908,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
          int i, j, ch;
 
          dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
-         if (BE (dfa->sb_char == NULL, 0))
+         if (__glibc_unlikely (dfa->sb_char == NULL))
            return REG_ESPACE;
 
          /* Set the bits corresponding to single byte chars.  */
@@ -927,7 +927,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
     }
 #endif
 
-  if (BE (dfa->nodes == NULL || dfa->state_table == NULL, 0))
+  if (__glibc_unlikely (dfa->nodes == NULL || dfa->state_table == NULL))
     return REG_ESPACE;
   return REG_NOERROR;
 }
@@ -943,7 +943,7 @@ init_word_char (re_dfa_t *dfa)
   int j;
   int ch = 0;
   dfa->word_ops_used = 1;
-  if (BE (dfa->map_notascii == 0, 1))
+  if (__glibc_likely (dfa->map_notascii == 0))
     {
       /* Avoid uint32_t and uint64_t as some non-GCC platforms lack
         them, an issue when this code is used in Gnulib.  */
@@ -970,7 +970,7 @@ init_word_char (re_dfa_t *dfa)
         goto general_case;
       ch = 128;
 
-      if (BE (dfa->is_utf8, 1))
+      if (__glibc_likely (dfa->is_utf8))
        {
          memset (&dfa->word_char[i], '\0', (SBC_MAX - ch) / 8);
          return;
@@ -1017,7 +1017,7 @@ create_initial_state (re_dfa_t *dfa)
   first = dfa->str_tree->first->node_idx;
   dfa->init_node = first;
   err = re_node_set_init_copy (&init_nodes, dfa->eclosures + first);
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     return err;
 
   /* The back-references which are in initial states can epsilon transit,
@@ -1061,7 +1061,7 @@ create_initial_state (re_dfa_t *dfa)
   /* It must be the first time to invoke acquire_state.  */
   dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0);
   /* We don't check ERR here, since the initial state must not be NULL.  */
-  if (BE (dfa->init_state == NULL, 0))
+  if (__glibc_unlikely (dfa->init_state == NULL))
     return err;
   if (dfa->init_state->has_constraint)
     {
@@ -1073,8 +1073,9 @@ create_initial_state (re_dfa_t *dfa)
                                                         &init_nodes,
                                                         CONTEXT_NEWLINE
                                                         | CONTEXT_BEGBUF);
-      if (BE (dfa->init_state_word == NULL || dfa->init_state_nl == NULL
-             || dfa->init_state_begbuf == NULL, 0))
+      if (__glibc_unlikely (dfa->init_state_word == NULL
+                           || dfa->init_state_nl == NULL
+                           || dfa->init_state_begbuf == NULL))
        return err;
     }
   else
@@ -1181,8 +1182,8 @@ analyze (regex_t *preg)
   dfa->org_indices = re_malloc (Idx, dfa->nodes_alloc);
   dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc);
   dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc);
-  if (BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL
-         || dfa->eclosures == NULL, 0))
+  if (__glibc_unlikely (dfa->nexts == NULL || dfa->org_indices == NULL
+                       || dfa->edests == NULL || dfa->eclosures == NULL))
     return REG_ESPACE;
 
   dfa->subexp_map = re_malloc (Idx, preg->re_nsub);
@@ -1203,17 +1204,17 @@ analyze (regex_t *preg)
     }
 
   ret = postorder (dfa->str_tree, lower_subexps, preg);
-  if (BE (ret != REG_NOERROR, 0))
+  if (__glibc_unlikely (ret != REG_NOERROR))
     return ret;
   ret = postorder (dfa->str_tree, calc_first, dfa);
-  if (BE (ret != REG_NOERROR, 0))
+  if (__glibc_unlikely (ret != REG_NOERROR))
     return ret;
   preorder (dfa->str_tree, calc_next, dfa);
   ret = preorder (dfa->str_tree, link_nfa_nodes, dfa);
-  if (BE (ret != REG_NOERROR, 0))
+  if (__glibc_unlikely (ret != REG_NOERROR))
     return ret;
   ret = calc_eclosure (dfa);
-  if (BE (ret != REG_NOERROR, 0))
+  if (__glibc_unlikely (ret != REG_NOERROR))
     return ret;
 
   /* We only need this during the prune_impossible_nodes pass in regexec.c;
@@ -1222,7 +1223,7 @@ analyze (regex_t *preg)
       || dfa->nbackref)
     {
       dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len);
-      if (BE (dfa->inveclosures == NULL, 0))
+      if (__glibc_unlikely (dfa->inveclosures == NULL))
        return REG_ESPACE;
       ret = calc_inveclosure (dfa);
     }
@@ -1252,7 +1253,7 @@ postorder (bin_tree_t *root, reg_errcode_t (fn (void *, 
bin_tree_t *)),
       do
        {
          reg_errcode_t err = fn (extra, node);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            return err;
          if (node->parent == NULL)
            return REG_NOERROR;
@@ -1274,7 +1275,7 @@ preorder (bin_tree_t *root, reg_errcode_t (fn (void *, 
bin_tree_t *)),
   for (node = root; ; )
     {
       reg_errcode_t err = fn (extra, node);
-      if (BE (err != REG_NOERROR, 0))
+      if (__glibc_unlikely (err != REG_NOERROR))
        return err;
 
       /* Go to the left node, or up and to the right.  */
@@ -1375,7 +1376,8 @@ lower_subexp (reg_errcode_t *err, regex_t *preg, 
bin_tree_t *node)
   cls = create_tree (dfa, NULL, NULL, OP_CLOSE_SUBEXP);
   tree1 = body ? create_tree (dfa, body, cls, CONCAT) : cls;
   tree = create_tree (dfa, op, tree1, CONCAT);
-  if (BE (tree == NULL || tree1 == NULL || op == NULL || cls == NULL, 0))
+  if (__glibc_unlikely (tree == NULL || tree1 == NULL
+                       || op == NULL || cls == NULL))
     {
       *err = REG_ESPACE;
       return NULL;
@@ -1401,7 +1403,7 @@ calc_first (void *extra, bin_tree_t *node)
     {
       node->first = node;
       node->node_idx = re_dfa_add_node (dfa, node->token);
-      if (BE (node->node_idx == -1, 0))
+      if (__glibc_unlikely (node->node_idx == -1))
        return REG_ESPACE;
       if (node->token.type == ANCHOR)
        dfa->nodes[node->node_idx].constraint = node->token.opr.ctx_type;
@@ -1512,11 +1514,11 @@ duplicate_node_closure (re_dfa_t *dfa, Idx 
top_org_node, Idx top_clone_node,
          org_dest = dfa->nexts[org_node];
          re_node_set_empty (dfa->edests + clone_node);
          clone_dest = duplicate_node (dfa, org_dest, constraint);
-         if (BE (clone_dest == -1, 0))
+         if (__glibc_unlikely (clone_dest == -1))
            return REG_ESPACE;
          dfa->nexts[clone_node] = dfa->nexts[org_node];
          ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
-         if (BE (! ok, 0))
+         if (__glibc_unlikely (! ok))
            return REG_ESPACE;
        }
       else if (dfa->edests[org_node].nelem == 0)
@@ -1538,17 +1540,17 @@ duplicate_node_closure (re_dfa_t *dfa, Idx 
top_org_node, Idx top_clone_node,
          if (org_node == root_node && clone_node != org_node)
            {
              ok = re_node_set_insert (dfa->edests + clone_node, org_dest);
-             if (BE (! ok, 0))
+             if (__glibc_unlikely (! ok))
                return REG_ESPACE;
              break;
            }
          /* In case the node has another constraint, append it.  */
          constraint |= dfa->nodes[org_node].constraint;
          clone_dest = duplicate_node (dfa, org_dest, constraint);
-         if (BE (clone_dest == -1, 0))
+         if (__glibc_unlikely (clone_dest == -1))
            return REG_ESPACE;
          ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
-         if (BE (! ok, 0))
+         if (__glibc_unlikely (! ok))
            return REG_ESPACE;
        }
       else /* dfa->edests[org_node].nelem == 2 */
@@ -1564,14 +1566,14 @@ duplicate_node_closure (re_dfa_t *dfa, Idx 
top_org_node, Idx top_clone_node,
              /* There is no such duplicated node, create a new one.  */
              reg_errcode_t err;
              clone_dest = duplicate_node (dfa, org_dest, constraint);
-             if (BE (clone_dest == -1, 0))
+             if (__glibc_unlikely (clone_dest == -1))
                return REG_ESPACE;
              ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
-             if (BE (! ok, 0))
+             if (__glibc_unlikely (! ok))
                return REG_ESPACE;
              err = duplicate_node_closure (dfa, org_dest, clone_dest,
                                            root_node, constraint);
-             if (BE (err != REG_NOERROR, 0))
+             if (__glibc_unlikely (err != REG_NOERROR))
                return err;
            }
          else
@@ -1579,16 +1581,16 @@ duplicate_node_closure (re_dfa_t *dfa, Idx 
top_org_node, Idx top_clone_node,
              /* There is a duplicated node which satisfies the constraint,
                 use it to avoid infinite loop.  */
              ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
-             if (BE (! ok, 0))
+             if (__glibc_unlikely (! ok))
                return REG_ESPACE;
            }
 
          org_dest = dfa->edests[org_node].elems[1];
          clone_dest = duplicate_node (dfa, org_dest, constraint);
-         if (BE (clone_dest == -1, 0))
+         if (__glibc_unlikely (clone_dest == -1))
            return REG_ESPACE;
          ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
-         if (BE (! ok, 0))
+         if (__glibc_unlikely (! ok))
            return REG_ESPACE;
        }
       org_node = org_dest;
@@ -1622,7 +1624,7 @@ static Idx
 duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint)
 {
   Idx dup_idx = re_dfa_add_node (dfa, dfa->nodes[org_idx]);
-  if (BE (dup_idx != -1, 1))
+  if (__glibc_likely (dup_idx != -1))
     {
       dfa->nodes[dup_idx].constraint = constraint;
       dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].constraint;
@@ -1648,7 +1650,7 @@ calc_inveclosure (re_dfa_t *dfa)
       for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx)
        {
          ok = re_node_set_insert_last (dfa->inveclosures + elems[idx], src);
-         if (BE (! ok, 0))
+         if (__glibc_unlikely (! ok))
            return REG_ESPACE;
        }
     }
@@ -1689,7 +1691,7 @@ calc_eclosure (re_dfa_t *dfa)
        continue;
       /* Calculate epsilon closure of 'node_idx'.  */
       err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, true);
-      if (BE (err != REG_NOERROR, 0))
+      if (__glibc_unlikely (err != REG_NOERROR))
        return err;
 
       if (dfa->eclosures[node_idx].nelem == 0)
@@ -1712,7 +1714,7 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, 
Idx node, bool root)
   bool ok;
   bool incomplete = false;
   err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1);
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     return err;
 
   /* This indicates that we are calculating this node now.
@@ -1727,7 +1729,7 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, 
Idx node, bool root)
     {
       err = duplicate_node_closure (dfa, node, node, node,
                                    dfa->nodes[node].constraint);
-      if (BE (err != REG_NOERROR, 0))
+      if (__glibc_unlikely (err != REG_NOERROR))
        return err;
     }
 
@@ -1749,14 +1751,14 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t 
*dfa, Idx node, bool root)
        if (dfa->eclosures[edest].nelem == 0)
          {
            err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false);
-           if (BE (err != REG_NOERROR, 0))
+           if (__glibc_unlikely (err != REG_NOERROR))
              return err;
          }
        else
          eclosure_elem = dfa->eclosures[edest];
        /* Merge the epsilon closure of 'edest'.  */
        err = re_node_set_merge (&eclosure, &eclosure_elem);
-       if (BE (err != REG_NOERROR, 0))
+       if (__glibc_unlikely (err != REG_NOERROR))
          return err;
        /* If the epsilon closure of 'edest' is incomplete,
           the epsilon closure of this node is also incomplete.  */
@@ -1769,7 +1771,7 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, 
Idx node, bool root)
 
   /* An epsilon closure includes itself.  */
   ok = re_node_set_insert (&eclosure, node);
-  if (BE (! ok, 0))
+  if (__glibc_unlikely (! ok))
     return REG_ESPACE;
   if (incomplete && !root)
     dfa->eclosures[node].nelem = 0;
@@ -2139,14 +2141,14 @@ parse (re_string_t *regexp, regex_t *preg, reg_syntax_t 
syntax,
   dfa->syntax = syntax;
   fetch_token (&current_token, regexp, syntax | RE_CARET_ANCHORS_HERE);
   tree = parse_reg_exp (regexp, preg, &current_token, syntax, 0, err);
-  if (BE (*err != REG_NOERROR && tree == NULL, 0))
+  if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL))
     return NULL;
   eor = create_tree (dfa, NULL, NULL, END_OF_RE);
   if (tree != NULL)
     root = create_tree (dfa, tree, eor, CONCAT);
   else
     root = eor;
-  if (BE (eor == NULL || root == NULL, 0))
+  if (__glibc_unlikely (eor == NULL || root == NULL))
     {
       *err = REG_ESPACE;
       return NULL;
@@ -2171,7 +2173,7 @@ parse_reg_exp (re_string_t *regexp, regex_t *preg, 
re_token_t *token,
   bin_tree_t *tree, *branch = NULL;
   bitset_word_t initial_bkref_map = dfa->completed_bkref_map;
   tree = parse_branch (regexp, preg, token, syntax, nest, err);
-  if (BE (*err != REG_NOERROR && tree == NULL, 0))
+  if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL))
     return NULL;
 
   while (token->type == OP_ALT)
@@ -2183,7 +2185,7 @@ parse_reg_exp (re_string_t *regexp, regex_t *preg, 
re_token_t *token,
          bitset_word_t accumulated_bkref_map = dfa->completed_bkref_map;
          dfa->completed_bkref_map = initial_bkref_map;
          branch = parse_branch (regexp, preg, token, syntax, nest, err);
-         if (BE (*err != REG_NOERROR && branch == NULL, 0))
+         if (__glibc_unlikely (*err != REG_NOERROR && branch == NULL))
            {
              if (tree != NULL)
                postorder (tree, free_tree, NULL);
@@ -2194,7 +2196,7 @@ parse_reg_exp (re_string_t *regexp, regex_t *preg, 
re_token_t *token,
       else
        branch = NULL;
       tree = create_tree (dfa, tree, branch, OP_ALT);
-      if (BE (tree == NULL, 0))
+      if (__glibc_unlikely (tree == NULL))
        {
          *err = REG_ESPACE;
          return NULL;
@@ -2219,14 +2221,14 @@ parse_branch (re_string_t *regexp, regex_t *preg, 
re_token_t *token,
   bin_tree_t *tree, *expr;
   re_dfa_t *dfa = preg->buffer;
   tree = parse_expression (regexp, preg, token, syntax, nest, err);
-  if (BE (*err != REG_NOERROR && tree == NULL, 0))
+  if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL))
     return NULL;
 
   while (token->type != OP_ALT && token->type != END_OF_RE
         && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
     {
       expr = parse_expression (regexp, preg, token, syntax, nest, err);
-      if (BE (*err != REG_NOERROR && expr == NULL, 0))
+      if (__glibc_unlikely (*err != REG_NOERROR && expr == NULL))
        {
          if (tree != NULL)
            postorder (tree, free_tree, NULL);
@@ -2267,7 +2269,7 @@ parse_expression (re_string_t *regexp, regex_t *preg, 
re_token_t *token,
     {
     case CHARACTER:
       tree = create_token_tree (dfa, NULL, NULL, token);
-      if (BE (tree == NULL, 0))
+      if (__glibc_unlikely (tree == NULL))
        {
          *err = REG_ESPACE;
          return NULL;
@@ -2282,7 +2284,7 @@ parse_expression (re_string_t *regexp, regex_t *preg, 
re_token_t *token,
              fetch_token (token, regexp, syntax);
              mbc_remain = create_token_tree (dfa, NULL, NULL, token);
              tree = create_tree (dfa, tree, mbc_remain, CONCAT);
-             if (BE (mbc_remain == NULL || tree == NULL, 0))
+             if (__glibc_unlikely (mbc_remain == NULL || tree == NULL))
                {
                  *err = REG_ESPACE;
                  return NULL;
@@ -2294,25 +2296,25 @@ parse_expression (re_string_t *regexp, regex_t *preg, 
re_token_t *token,
 
     case OP_OPEN_SUBEXP:
       tree = parse_sub_exp (regexp, preg, token, syntax, nest + 1, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+      if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL))
        return NULL;
       break;
 
     case OP_OPEN_BRACKET:
       tree = parse_bracket_exp (regexp, dfa, token, syntax, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+      if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL))
        return NULL;
       break;
 
     case OP_BACK_REF:
-      if (!BE (dfa->completed_bkref_map & (1 << token->opr.idx), 1))
+      if (!__glibc_likely (dfa->completed_bkref_map & (1 << token->opr.idx)))
        {
          *err = REG_ESUBREG;
          return NULL;
        }
       dfa->used_bkref_map |= 1 << token->opr.idx;
       tree = create_token_tree (dfa, NULL, NULL, token);
-      if (BE (tree == NULL, 0))
+      if (__glibc_unlikely (tree == NULL))
        {
          *err = REG_ESPACE;
          return NULL;
@@ -2358,7 +2360,7 @@ parse_expression (re_string_t *regexp, regex_t *preg, 
re_token_t *token,
       /* mb_partial and word_char bits should be initialized already
         by peek_token.  */
       tree = create_token_tree (dfa, NULL, NULL, token);
-      if (BE (tree == NULL, 0))
+      if (__glibc_unlikely (tree == NULL))
        {
          *err = REG_ESPACE;
          return NULL;
@@ -2388,7 +2390,8 @@ parse_expression (re_string_t *regexp, regex_t *preg, 
re_token_t *token,
            }
          tree_last = create_token_tree (dfa, NULL, NULL, token);
          tree = create_tree (dfa, tree_first, tree_last, OP_ALT);
-         if (BE (tree_first == NULL || tree_last == NULL || tree == NULL, 0))
+         if (__glibc_unlikely (tree_first == NULL || tree_last == NULL
+                               || tree == NULL))
            {
              *err = REG_ESPACE;
              return NULL;
@@ -2397,7 +2400,7 @@ parse_expression (re_string_t *regexp, regex_t *preg, 
re_token_t *token,
       else
        {
          tree = create_token_tree (dfa, NULL, NULL, token);
-         if (BE (tree == NULL, 0))
+         if (__glibc_unlikely (tree == NULL))
            {
              *err = REG_ESPACE;
              return NULL;
@@ -2412,7 +2415,7 @@ parse_expression (re_string_t *regexp, regex_t *preg, 
re_token_t *token,
 
     case OP_PERIOD:
       tree = create_token_tree (dfa, NULL, NULL, token);
-      if (BE (tree == NULL, 0))
+      if (__glibc_unlikely (tree == NULL))
        {
          *err = REG_ESPACE;
          return NULL;
@@ -2427,7 +2430,7 @@ parse_expression (re_string_t *regexp, regex_t *preg, 
re_token_t *token,
                                 "alnum",
                                 "_",
                                 token->type == OP_NOTWORD, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+      if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL))
        return NULL;
       break;
 
@@ -2437,7 +2440,7 @@ parse_expression (re_string_t *regexp, regex_t *preg, 
re_token_t *token,
                                 "space",
                                 "",
                                 token->type == OP_NOTSPACE, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+      if (__glibc_unlikely (*err != REG_NOERROR && tree == NULL))
        return NULL;
       break;
 
@@ -2463,7 +2466,7 @@ parse_expression (re_string_t *regexp, regex_t *preg, 
re_token_t *token,
     {
       bin_tree_t *dup_tree = parse_dup_op (tree, regexp, dfa, token,
                                           syntax, err);
-      if (BE (*err != REG_NOERROR && dup_tree == NULL, 0))
+      if (__glibc_unlikely (*err != REG_NOERROR && dup_tree == NULL))
        {
          if (tree != NULL)
            postorder (tree, free_tree, NULL);
@@ -2509,13 +2512,14 @@ parse_sub_exp (re_string_t *regexp, regex_t *preg, 
re_token_t *token,
   else
     {
       tree = parse_reg_exp (regexp, preg, token, syntax, nest, err);
-      if (BE (*err == REG_NOERROR && token->type != OP_CLOSE_SUBEXP, 0))
+      if (__glibc_unlikely (*err == REG_NOERROR
+                           && token->type != OP_CLOSE_SUBEXP))
        {
          if (tree != NULL)
            postorder (tree, free_tree, NULL);
          *err = REG_EPAREN;
        }
-      if (BE (*err != REG_NOERROR, 0))
+      if (__glibc_unlikely (*err != REG_NOERROR))
        return NULL;
     }
 
@@ -2523,7 +2527,7 @@ parse_sub_exp (re_string_t *regexp, regex_t *preg, 
re_token_t *token,
     dfa->completed_bkref_map |= 1 << cur_nsub;
 
   tree = create_tree (dfa, tree, NULL, SUBEXP);
-  if (BE (tree == NULL, 0))
+  if (__glibc_unlikely (tree == NULL))
     {
       *err = REG_ESPACE;
       return NULL;
@@ -2556,17 +2560,17 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, 
re_dfa_t *dfa,
              return NULL;
            }
        }
-      if (BE (start != -2, 1))
+      if (__glibc_likely (start != -2))
        {
          /* We treat "{n}" as "{n,n}".  */
          end = ((token->type == OP_CLOSE_DUP_NUM) ? start
                 : ((token->type == CHARACTER && token->opr.c == ',')
                    ? fetch_number (regexp, token, syntax) : -2));
        }
-      if (BE (start == -2 || end == -2, 0))
+      if (__glibc_unlikely (start == -2 || end == -2))
        {
          /* Invalid sequence.  */
-         if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0))
+         if (__glibc_unlikely (!(syntax & RE_INVALID_INTERVAL_ORD)))
            {
              if (token->type == END_OF_RE)
                *err = REG_EBRACE;
@@ -2585,15 +2589,15 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, 
re_dfa_t *dfa,
          return elem;
        }
 
-      if (BE ((end != -1 && start > end)
-             || token->type != OP_CLOSE_DUP_NUM, 0))
+      if (__glibc_unlikely ((end != -1 && start > end)
+                           || token->type != OP_CLOSE_DUP_NUM))
        {
          /* First number greater than second.  */
          *err = REG_BADBR;
          return NULL;
        }
 
-      if (BE (RE_DUP_MAX < (end == -1 ? start : end), 0))
+      if (__glibc_unlikely (RE_DUP_MAX < (end == -1 ? start : end)))
        {
          *err = REG_ESIZE;
          return NULL;
@@ -2607,23 +2611,23 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, 
re_dfa_t *dfa,
 
   fetch_token (token, regexp, syntax);
 
-  if (BE (elem == NULL, 0))
+  if (__glibc_unlikely (elem == NULL))
     return NULL;
-  if (BE (start == 0 && end == 0, 0))
+  if (__glibc_unlikely (start == 0 && end == 0))
     {
       postorder (elem, free_tree, NULL);
       return NULL;
     }
 
   /* Extract "<re>{n,m}" to "<re><re>...<re><re>{0,<m-n>}".  */
-  if (BE (start > 0, 0))
+  if (__glibc_unlikely (start > 0))
     {
       tree = elem;
       for (i = 2; i <= start; ++i)
        {
          elem = duplicate_tree (elem, dfa);
          tree = create_tree (dfa, tree, elem, CONCAT);
-         if (BE (elem == NULL || tree == NULL, 0))
+         if (__glibc_unlikely (elem == NULL || tree == NULL))
            goto parse_dup_op_espace;
        }
 
@@ -2632,7 +2636,7 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, 
re_dfa_t *dfa,
 
       /* Duplicate ELEM before it is marked optional.  */
       elem = duplicate_tree (elem, dfa);
-      if (BE (elem == NULL, 0))
+      if (__glibc_unlikely (elem == NULL))
         goto parse_dup_op_espace;
       old_tree = tree;
     }
@@ -2647,7 +2651,7 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, 
re_dfa_t *dfa,
 
   tree = create_tree (dfa, elem, NULL,
                      (end == -1 ? OP_DUP_ASTERISK : OP_ALT));
-  if (BE (tree == NULL, 0))
+  if (__glibc_unlikely (tree == NULL))
     goto parse_dup_op_espace;
 
   /* This loop is actually executed only when end != -1,
@@ -2658,11 +2662,11 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, 
re_dfa_t *dfa,
       {
        elem = duplicate_tree (elem, dfa);
        tree = create_tree (dfa, tree, elem, CONCAT);
-       if (BE (elem == NULL || tree == NULL, 0))
+       if (__glibc_unlikely (elem == NULL || tree == NULL))
          goto parse_dup_op_espace;
 
        tree = create_tree (dfa, tree, NULL, OP_ALT);
-       if (BE (tree == NULL, 0))
+       if (__glibc_unlikely (tree == NULL))
          goto parse_dup_op_espace;
       }
 
@@ -2717,17 +2721,18 @@ build_range_exp (const reg_syntax_t syntax,
 {
   unsigned int start_ch, end_ch;
   /* Equivalence Classes and Character Classes can't be a range start/end.  */
-  if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
-         || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS,
-         0))
+  if (__glibc_unlikely (start_elem->type == EQUIV_CLASS
+                       || start_elem->type == CHAR_CLASS
+                       || end_elem->type == EQUIV_CLASS
+                       || end_elem->type == CHAR_CLASS))
     return REG_ERANGE;
 
   /* We can handle no multi character collating elements without libc
      support.  */
-  if (BE ((start_elem->type == COLL_SYM
-          && strlen ((char *) start_elem->opr.name) > 1)
-         || (end_elem->type == COLL_SYM
-             && strlen ((char *) end_elem->opr.name) > 1), 0))
+  if (__glibc_unlikely ((start_elem->type == COLL_SYM
+                        && strlen ((char *) start_elem->opr.name) > 1)
+                       || (end_elem->type == COLL_SYM
+                           && strlen ((char *) end_elem->opr.name) > 1)))
     return REG_ECOLLATE;
 
 # ifdef RE_ENABLE_I18N
@@ -2748,7 +2753,8 @@ build_range_exp (const reg_syntax_t syntax,
              ? parse_byte (end_ch, mbcset) : end_elem->opr.wch);
     if (start_wc == WEOF || end_wc == WEOF)
       return REG_ECOLLATE;
-    else if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_wc > end_wc, 0))
+    else if (__glibc_unlikely ((syntax & RE_NO_EMPTY_RANGES)
+                              && start_wc > end_wc))
       return REG_ERANGE;
 
     /* Got valid collation sequence values, add them as a new entry.
@@ -2759,7 +2765,7 @@ build_range_exp (const reg_syntax_t syntax,
     if (mbcset)
       {
        /* Check the space of the arrays.  */
-       if (BE (*range_alloc == mbcset->nranges, 0))
+       if (__glibc_unlikely (*range_alloc == mbcset->nranges))
          {
            /* There is not enough space, need realloc.  */
            wchar_t *new_array_start, *new_array_end;
@@ -2774,7 +2780,8 @@ build_range_exp (const reg_syntax_t syntax,
            new_array_end = re_realloc (mbcset->range_ends, wchar_t,
                                        new_nranges);
 
-           if (BE (new_array_start == NULL || new_array_end == NULL, 0))
+           if (__glibc_unlikely (new_array_start == NULL
+                                 || new_array_end == NULL))
              {
                re_free (new_array_start);
                re_free (new_array_end);
@@ -2834,7 +2841,7 @@ build_collating_symbol (bitset_t sbcset, const unsigned 
char *name)
 # endif /* not RE_ENABLE_I18N */
 {
   size_t name_len = strlen ((const char *) name);
-  if (BE (name_len != 1, 0))
+  if (__glibc_unlikely (name_len != 1))
     return REG_ECOLLATE;
   else
     {
@@ -2969,18 +2976,21 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
 
       /* Equivalence Classes and Character Classes can't be a range
         start/end.  */
-      if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
-             || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS,
-             0))
+      if (__glibc_unlikely (start_elem->type == EQUIV_CLASS
+                           || start_elem->type == CHAR_CLASS
+                           || end_elem->type == EQUIV_CLASS
+                           || end_elem->type == CHAR_CLASS))
        return REG_ERANGE;
 
       /* FIXME: Implement rational ranges here, too.  */
       start_collseq = lookup_collation_sequence_value (start_elem);
       end_collseq = lookup_collation_sequence_value (end_elem);
       /* Check start/end collation sequence values.  */
-      if (BE (start_collseq == UINT_MAX || end_collseq == UINT_MAX, 0))
+      if (__glibc_unlikely (start_collseq == UINT_MAX
+                           || end_collseq == UINT_MAX))
        return REG_ECOLLATE;
-      if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq, 0))
+      if (__glibc_unlikely ((syntax & RE_NO_EMPTY_RANGES)
+                           && start_collseq > end_collseq))
        return REG_ERANGE;
 
       /* Got valid collation sequence values, add them as a new entry.
@@ -2990,7 +3000,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
       if (nrules > 0 || dfa->mb_cur_max > 1)
        {
          /* Check the space of the arrays.  */
-         if (BE (*range_alloc == mbcset->nranges, 0))
+         if (__glibc_unlikely (*range_alloc == mbcset->nranges))
            {
              /* There is not enough space, need realloc.  */
              uint32_t *new_array_start;
@@ -3004,7 +3014,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
              new_array_end = re_realloc (mbcset->range_ends, uint32_t,
                                          new_nranges);
 
-             if (BE (new_array_start == NULL || new_array_end == NULL, 0))
+             if (__glibc_unlikely (new_array_start == NULL
+                                   || new_array_end == NULL))
                return REG_ESPACE;
 
              mbcset->range_starts = new_array_start;
@@ -3068,7 +3079,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
 
          /* Got valid collation sequence, add it as a new entry.  */
          /* Check the space of the arrays.  */
-         if (BE (*coll_sym_alloc == mbcset->ncoll_syms, 0))
+         if (__glibc_unlikely (*coll_sym_alloc == mbcset->ncoll_syms))
            {
              /* Not enough, realloc it.  */
              /* +1 in case of mbcset->ncoll_syms is 0.  */
@@ -3077,7 +3088,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
                 if *alloc == 0.  */
              int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t,
                                                   new_coll_sym_alloc);
-             if (BE (new_coll_syms == NULL, 0))
+             if (__glibc_unlikely (new_coll_syms == NULL))
                return REG_ESPACE;
              mbcset->coll_syms = new_coll_syms;
              *coll_sym_alloc = new_coll_sym_alloc;
@@ -3087,7 +3098,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
        }
       else
        {
-         if (BE (name_len != 1, 0))
+         if (__glibc_unlikely (name_len != 1))
            return REG_ECOLLATE;
          else
            {
@@ -3131,9 +3142,9 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
   mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
 #endif /* RE_ENABLE_I18N */
 #ifdef RE_ENABLE_I18N
-  if (BE (sbcset == NULL || mbcset == NULL, 0))
+  if (__glibc_unlikely (sbcset == NULL || mbcset == NULL))
 #else
-  if (BE (sbcset == NULL, 0))
+  if (__glibc_unlikely (sbcset == NULL))
 #endif /* RE_ENABLE_I18N */
     {
       re_free (sbcset);
@@ -3145,7 +3156,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
     }
 
   token_len = peek_token_bracket (token, regexp, syntax);
-  if (BE (token->type == END_OF_RE, 0))
+  if (__glibc_unlikely (token->type == END_OF_RE))
     {
       *err = REG_BADPAT;
       goto parse_bracket_exp_free_return;
@@ -3160,7 +3171,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
        bitset_set (sbcset, '\n');
       re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
       token_len = peek_token_bracket (token, regexp, syntax);
-      if (BE (token->type == END_OF_RE, 0))
+      if (__glibc_unlikely (token->type == END_OF_RE))
        {
          *err = REG_BADPAT;
          goto parse_bracket_exp_free_return;
@@ -3185,7 +3196,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
       start_elem.type = COLL_SYM;
       ret = parse_bracket_element (&start_elem, regexp, token, token_len, dfa,
                                   syntax, first_round);
-      if (BE (ret != REG_NOERROR, 0))
+      if (__glibc_unlikely (ret != REG_NOERROR))
        {
          *err = ret;
          goto parse_bracket_exp_free_return;
@@ -3198,7 +3209,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
       /* Do not check for ranges if we know they are not allowed.  */
       if (start_elem.type != CHAR_CLASS && start_elem.type != EQUIV_CLASS)
        {
-         if (BE (token->type == END_OF_RE, 0))
+         if (__glibc_unlikely (token->type == END_OF_RE))
            {
              *err = REG_EBRACK;
              goto parse_bracket_exp_free_return;
@@ -3207,7 +3218,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
            {
              re_string_skip_bytes (regexp, token_len); /* Skip '-'.  */
              token_len2 = peek_token_bracket (&token2, regexp, syntax);
-             if (BE (token2.type == END_OF_RE, 0))
+             if (__glibc_unlikely (token2.type == END_OF_RE))
                {
                  *err = REG_EBRACK;
                  goto parse_bracket_exp_free_return;
@@ -3229,7 +3240,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
          end_elem.type = COLL_SYM;
          ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2,
                                       dfa, syntax, true);
-         if (BE (ret != REG_NOERROR, 0))
+         if (__glibc_unlikely (ret != REG_NOERROR))
            {
              *err = ret;
              goto parse_bracket_exp_free_return;
@@ -3249,7 +3260,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
          *err = build_range_exp (syntax, sbcset, &start_elem, &end_elem);
 # endif
 #endif /* RE_ENABLE_I18N */
-         if (BE (*err != REG_NOERROR, 0))
+         if (__glibc_unlikely (*err != REG_NOERROR))
            goto parse_bracket_exp_free_return;
        }
       else
@@ -3262,7 +3273,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
 #ifdef RE_ENABLE_I18N
            case MB_CHAR:
              /* Check whether the array has enough space.  */
-             if (BE (mbchar_alloc == mbcset->nmbchars, 0))
+             if (__glibc_unlikely (mbchar_alloc == mbcset->nmbchars))
                {
                  wchar_t *new_mbchars;
                  /* Not enough, realloc it.  */
@@ -3271,7 +3282,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
                  /* Use realloc since array is NULL if *alloc == 0.  */
                  new_mbchars = re_realloc (mbcset->mbchars, wchar_t,
                                            mbchar_alloc);
-                 if (BE (new_mbchars == NULL, 0))
+                 if (__glibc_unlikely (new_mbchars == NULL))
                    goto parse_bracket_exp_espace;
                  mbcset->mbchars = new_mbchars;
                }
@@ -3284,7 +3295,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
                                        mbcset, &equiv_class_alloc,
 #endif /* RE_ENABLE_I18N */
                                        start_elem.opr.name);
-             if (BE (*err != REG_NOERROR, 0))
+             if (__glibc_unlikely (*err != REG_NOERROR))
                goto parse_bracket_exp_free_return;
              break;
            case COLL_SYM:
@@ -3293,7 +3304,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
                                             mbcset, &coll_sym_alloc,
 #endif /* RE_ENABLE_I18N */
                                             start_elem.opr.name);
-             if (BE (*err != REG_NOERROR, 0))
+             if (__glibc_unlikely (*err != REG_NOERROR))
                goto parse_bracket_exp_free_return;
              break;
            case CHAR_CLASS:
@@ -3303,7 +3314,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
 #endif /* RE_ENABLE_I18N */
                                      (const char *) start_elem.opr.name,
                                      syntax);
-             if (BE (*err != REG_NOERROR, 0))
+             if (__glibc_unlikely (*err != REG_NOERROR))
               goto parse_bracket_exp_free_return;
              break;
            default:
@@ -3311,7 +3322,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
              break;
            }
        }
-      if (BE (token->type == END_OF_RE, 0))
+      if (__glibc_unlikely (token->type == END_OF_RE))
        {
          *err = REG_EBRACK;
          goto parse_bracket_exp_free_return;
@@ -3342,7 +3353,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
       br_token.type = COMPLEX_BRACKET;
       br_token.opr.mbcset = mbcset;
       mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token);
-      if (BE (mbc_tree == NULL, 0))
+      if (__glibc_unlikely (mbc_tree == NULL))
        goto parse_bracket_exp_espace;
       for (sbc_idx = 0; sbc_idx < BITSET_WORDS; ++sbc_idx)
        if (sbcset[sbc_idx])
@@ -3355,12 +3366,12 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
          br_token.type = SIMPLE_BRACKET;
          br_token.opr.sbcset = sbcset;
          work_tree = create_token_tree (dfa, NULL, NULL, &br_token);
-         if (BE (work_tree == NULL, 0))
+         if (__glibc_unlikely (work_tree == NULL))
            goto parse_bracket_exp_espace;
 
          /* Then join them by ALT node.  */
          work_tree = create_tree (dfa, work_tree, mbc_tree, OP_ALT);
-         if (BE (work_tree == NULL, 0))
+         if (__glibc_unlikely (work_tree == NULL))
            goto parse_bracket_exp_espace;
        }
       else
@@ -3379,7 +3390,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, 
re_token_t *token,
       br_token.type = SIMPLE_BRACKET;
       br_token.opr.sbcset = sbcset;
       work_tree = create_token_tree (dfa, NULL, NULL, &br_token);
-      if (BE (work_tree == NULL, 0))
+      if (__glibc_unlikely (work_tree == NULL))
        goto parse_bracket_exp_espace;
     }
   return work_tree;
@@ -3416,7 +3427,7 @@ parse_bracket_element (bracket_elem_t *elem, re_string_t 
*regexp,
   if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS
       || token->type == OP_OPEN_EQUIV_CLASS)
     return parse_bracket_symbol (elem, regexp, token);
-  if (BE (token->type == OP_CHARSET_RANGE, 0) && !accept_hyphen)
+  if (__glibc_unlikely (token->type == OP_CHARSET_RANGE) && !accept_hyphen)
     {
       /* A '-' must only appear as anything but a range indicator before
         the closing bracket.  Everything else is an error.  */
@@ -3511,7 +3522,7 @@ build_equiv_class (bitset_t sbcset, const unsigned char 
*name)
       indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
                                                _NL_COLLATE_INDIRECTMB);
       idx1 = findidx (table, indirect, extra, &cp, -1);
-      if (BE (idx1 == 0 || *cp != '\0', 0))
+      if (__glibc_unlikely (idx1 == 0 || *cp != '\0'))
        /* This isn't a valid character.  */
        return REG_ECOLLATE;
 
@@ -3536,7 +3547,7 @@ build_equiv_class (bitset_t sbcset, const unsigned char 
*name)
            bitset_set (sbcset, ch);
        }
       /* Check whether the array has enough space.  */
-      if (BE (*equiv_class_alloc == mbcset->nequiv_classes, 0))
+      if (__glibc_unlikely (*equiv_class_alloc == mbcset->nequiv_classes))
        {
          /* Not enough, realloc it.  */
          /* +1 in case of mbcset->nequiv_classes is 0.  */
@@ -3545,7 +3556,7 @@ build_equiv_class (bitset_t sbcset, const unsigned char 
*name)
          int32_t *new_equiv_classes = re_realloc (mbcset->equiv_classes,
                                                   int32_t,
                                                   new_equiv_class_alloc);
-         if (BE (new_equiv_classes == NULL, 0))
+         if (__glibc_unlikely (new_equiv_classes == NULL))
            return REG_ESPACE;
          mbcset->equiv_classes = new_equiv_classes;
          *equiv_class_alloc = new_equiv_class_alloc;
@@ -3555,7 +3566,7 @@ build_equiv_class (bitset_t sbcset, const unsigned char 
*name)
   else
 #endif /* _LIBC */
     {
-      if (BE (strlen ((const char *) name) != 1, 0))
+      if (__glibc_unlikely (strlen ((const char *) name) != 1))
        return REG_ECOLLATE;
       bitset_set (sbcset, *name);
     }
@@ -3589,7 +3600,7 @@ build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
 
 #ifdef RE_ENABLE_I18N
   /* Check the space of the arrays.  */
-  if (BE (*char_class_alloc == mbcset->nchar_classes, 0))
+  if (__glibc_unlikely (*char_class_alloc == mbcset->nchar_classes))
     {
       /* Not enough, realloc it.  */
       /* +1 in case of mbcset->nchar_classes is 0.  */
@@ -3597,7 +3608,7 @@ build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
       /* Use realloc since array is NULL if *alloc == 0.  */
       wctype_t *new_char_classes = re_realloc (mbcset->char_classes, wctype_t,
                                               new_char_class_alloc);
-      if (BE (new_char_classes == NULL, 0))
+      if (__glibc_unlikely (new_char_classes == NULL))
        return REG_ESPACE;
       mbcset->char_classes = new_char_classes;
       *char_class_alloc = new_char_class_alloc;
@@ -3607,7 +3618,7 @@ build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
 
 #define BUILD_CHARCLASS_LOOP(ctype_func)       \
   do {                                         \
-    if (BE (trans != NULL, 0))                 \
+    if (__glibc_unlikely (trans != NULL))                      \
       {                                                \
        for (i = 0; i < SBC_MAX; ++i)           \
          if (ctype_func (i))                   \
@@ -3667,14 +3678,14 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE 
trans,
   bin_tree_t *tree;
 
   sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
-  if (BE (sbcset == NULL, 0))
+  if (__glibc_unlikely (sbcset == NULL))
     {
       *err = REG_ESPACE;
       return NULL;
     }
 #ifdef RE_ENABLE_I18N
   mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
-  if (BE (mbcset == NULL, 0))
+  if (__glibc_unlikely (mbcset == NULL))
     {
       re_free (sbcset);
       *err = REG_ESPACE;
@@ -3690,7 +3701,7 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE 
trans,
 #endif /* RE_ENABLE_I18N */
                         class_name, 0);
 
-  if (BE (ret != REG_NOERROR, 0))
+  if (__glibc_unlikely (ret != REG_NOERROR))
     {
       re_free (sbcset);
 #ifdef RE_ENABLE_I18N
@@ -3720,7 +3731,7 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE 
trans,
   br_token.type = SIMPLE_BRACKET;
   br_token.opr.sbcset = sbcset;
   tree = create_token_tree (dfa, NULL, NULL, &br_token);
-  if (BE (tree == NULL, 0))
+  if (__glibc_unlikely (tree == NULL))
     goto build_word_op_espace;
 
 #ifdef RE_ENABLE_I18N
@@ -3732,11 +3743,11 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE 
trans,
       br_token.opr.mbcset = mbcset;
       dfa->has_mb_node = 1;
       mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token);
-      if (BE (mbc_tree == NULL, 0))
+      if (__glibc_unlikely (mbc_tree == NULL))
        goto build_word_op_espace;
       /* Then join them by ALT node.  */
       tree = create_tree (dfa, tree, mbc_tree, OP_ALT);
-      if (BE (mbc_tree != NULL, 1))
+      if (__glibc_likely (mbc_tree != NULL))
        return tree;
     }
   else
@@ -3772,7 +3783,7 @@ fetch_number (re_string_t *input, re_token_t *token, 
reg_syntax_t syntax)
     {
       fetch_token (token, input, syntax);
       c = token->opr.c;
-      if (BE (token->type == END_OF_RE, 0))
+      if (__glibc_unlikely (token->type == END_OF_RE))
        return -2;
       if (token->type == OP_CLOSE_DUP_NUM || c == ',')
        break;
@@ -3822,7 +3833,7 @@ create_token_tree (re_dfa_t *dfa, bin_tree_t *left, 
bin_tree_t *right,
                   const re_token_t *token)
 {
   bin_tree_t *tree;
-  if (BE (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE, 0))
+  if (__glibc_unlikely (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE))
     {
       bin_tree_storage_t *storage = re_malloc (bin_tree_storage_t, 1);
 
diff --git a/lib/regex.c b/lib/regex.c
index 499e1f0..2a86e10 100644
--- a/lib/regex.c
+++ b/lib/regex.c
@@ -18,7 +18,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #ifndef _LIBC
-# include <config.h>
+# include <libc-config.h>
 
 # if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__
 #  pragma GCC diagnostic ignored "-Wsuggest-attribute=pure"
diff --git a/lib/regex_internal.c b/lib/regex_internal.c
index e3ce4ab..f13def3 100644
--- a/lib/regex_internal.c
+++ b/lib/regex_internal.c
@@ -59,7 +59,7 @@ re_string_allocate (re_string_t *pstr, const char *str, Idx 
len, Idx init_len,
   re_string_construct_common (str, len, pstr, trans, icase, dfa);
 
   ret = re_string_realloc_buffers (pstr, init_buf_len);
-  if (BE (ret != REG_NOERROR, 0))
+  if (__glibc_unlikely (ret != REG_NOERROR))
     return ret;
 
   pstr->word_char = dfa->word_char;
@@ -84,7 +84,7 @@ re_string_construct (re_string_t *pstr, const char *str, Idx 
len,
   if (len > 0)
     {
       ret = re_string_realloc_buffers (pstr, len + 1);
-      if (BE (ret != REG_NOERROR, 0))
+      if (__glibc_unlikely (ret != REG_NOERROR))
        return ret;
     }
   pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
@@ -97,14 +97,14 @@ re_string_construct (re_string_t *pstr, const char *str, 
Idx len,
          while (1)
            {
              ret = build_wcs_upper_buffer (pstr);
-             if (BE (ret != REG_NOERROR, 0))
+             if (__glibc_unlikely (ret != REG_NOERROR))
                return ret;
              if (pstr->valid_raw_len >= len)
                break;
              if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max)
                break;
              ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
-             if (BE (ret != REG_NOERROR, 0))
+             if (__glibc_unlikely (ret != REG_NOERROR))
                return ret;
            }
        }
@@ -146,17 +146,18 @@ re_string_realloc_buffers (re_string_t *pstr, Idx 
new_buf_len)
 
       /* Avoid overflow in realloc.  */
       const size_t max_object_size = MAX (sizeof (wint_t), sizeof (Idx));
-      if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) < new_buf_len, 0))
+      if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size)
+                           < new_buf_len))
        return REG_ESPACE;
 
       new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len);
-      if (BE (new_wcs == NULL, 0))
+      if (__glibc_unlikely (new_wcs == NULL))
        return REG_ESPACE;
       pstr->wcs = new_wcs;
       if (pstr->offsets != NULL)
        {
          Idx *new_offsets = re_realloc (pstr->offsets, Idx, new_buf_len);
-         if (BE (new_offsets == NULL, 0))
+         if (__glibc_unlikely (new_offsets == NULL))
            return REG_ESPACE;
          pstr->offsets = new_offsets;
        }
@@ -166,7 +167,7 @@ re_string_realloc_buffers (re_string_t *pstr, Idx 
new_buf_len)
     {
       unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char,
                                           new_buf_len);
-      if (BE (new_mbs == NULL, 0))
+      if (__glibc_unlikely (new_mbs == NULL))
        return REG_ESPACE;
       pstr->mbs = new_mbs;
     }
@@ -230,7 +231,7 @@ build_wcs_buffer (re_string_t *pstr)
       remain_len = end_idx - byte_idx;
       prev_st = pstr->cur_state;
       /* Apply the translation if we need.  */
-      if (BE (pstr->trans != NULL, 0))
+      if (__glibc_unlikely (pstr->trans != NULL))
        {
          int i, ch;
 
@@ -244,17 +245,18 @@ build_wcs_buffer (re_string_t *pstr)
       else
        p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx;
       mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
-      if (BE (mbclen == (size_t) -1 || mbclen == 0
-             || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len), 0))
+      if (__glibc_unlikely (mbclen == (size_t) -1 || mbclen == 0
+                           || (mbclen == (size_t) -2
+                               && pstr->bufs_len >= pstr->len)))
        {
          /* We treat these cases as a singlebyte character.  */
          mbclen = 1;
          wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
-         if (BE (pstr->trans != NULL, 0))
+         if (__glibc_unlikely (pstr->trans != NULL))
            wc = pstr->trans[wc];
          pstr->cur_state = prev_st;
        }
-      else if (BE (mbclen == (size_t) -2, 0))
+      else if (__glibc_unlikely (mbclen == (size_t) -2))
        {
          /* The buffer doesn't have enough space, finish to build.  */
          pstr->cur_state = prev_st;
@@ -317,7 +319,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
          mbclen = __mbrtowc (&wc,
                              ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
                               + byte_idx), remain_len, &pstr->cur_state);
-         if (BE (0 < mbclen && mbclen < (size_t) -2, 1))
+         if (__glibc_likely (0 < mbclen && mbclen < (size_t) -2))
            {
              wchar_t wcu = __towupper (wc);
              if (wcu != wc)
@@ -325,7 +327,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
                  size_t mbcdlen;
 
                  mbcdlen = __wcrtomb (buf, wcu, &prev_st);
-                 if (BE (mbclen == mbcdlen, 1))
+                 if (__glibc_likely (mbclen == mbcdlen))
                    memcpy (pstr->mbs + byte_idx, buf, mbclen);
                  else
                    {
@@ -350,7 +352,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
              pstr->mbs[byte_idx] = ch;
              /* And also cast it to wide char.  */
              pstr->wcs[byte_idx++] = (wchar_t) ch;
-             if (BE (mbclen == (size_t) -1, 0))
+             if (__glibc_unlikely (mbclen == (size_t) -1))
                pstr->cur_state = prev_st;
            }
          else
@@ -372,7 +374,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
       offsets_needed:
        remain_len = end_idx - byte_idx;
        prev_st = pstr->cur_state;
-       if (BE (pstr->trans != NULL, 0))
+       if (__glibc_unlikely (pstr->trans != NULL))
          {
            int i, ch;
 
@@ -386,7 +388,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
        else
          p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx;
        mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
-       if (BE (0 < mbclen && mbclen < (size_t) -2, 1))
+       if (__glibc_likely (0 < mbclen && mbclen < (size_t) -2))
          {
            wchar_t wcu = __towupper (wc);
            if (wcu != wc)
@@ -394,7 +396,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
                size_t mbcdlen;
 
                mbcdlen = __wcrtomb ((char *) buf, wcu, &prev_st);
-               if (BE (mbclen == mbcdlen, 1))
+               if (__glibc_likely (mbclen == mbcdlen))
                  memcpy (pstr->mbs + byte_idx, buf, mbclen);
                else if (mbcdlen != (size_t) -1)
                  {
@@ -444,7 +446,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
            else
              memcpy (pstr->mbs + byte_idx, p, mbclen);
 
-           if (BE (pstr->offsets_needed != 0, 0))
+           if (__glibc_unlikely (pstr->offsets_needed != 0))
              {
                size_t i;
                for (i = 0; i < mbclen; ++i)
@@ -463,17 +465,17 @@ build_wcs_upper_buffer (re_string_t *pstr)
            /* It is an invalid character or '\0'.  Just use the byte.  */
            int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx];
 
-           if (BE (pstr->trans != NULL, 0))
+           if (__glibc_unlikely (pstr->trans != NULL))
              ch = pstr->trans [ch];
            pstr->mbs[byte_idx] = ch;
 
-           if (BE (pstr->offsets_needed != 0, 0))
+           if (__glibc_unlikely (pstr->offsets_needed != 0))
              pstr->offsets[byte_idx] = src_idx;
            ++src_idx;
 
            /* And also cast it to wide char.  */
            pstr->wcs[byte_idx++] = (wchar_t) ch;
-           if (BE (mbclen == (size_t) -1, 0))
+           if (__glibc_unlikely (mbclen == (size_t) -1))
              pstr->cur_state = prev_st;
          }
        else
@@ -508,7 +510,8 @@ re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, 
wint_t *last_wc)
       prev_st = pstr->cur_state;
       mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx,
                          remain_len, &pstr->cur_state);
-      if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 
0))
+      if (__glibc_unlikely (mbclen == (size_t) -2 || mbclen == (size_t) -1
+                           || mbclen == 0))
        {
          /* We treat these cases as a single byte character.  */
          if (mbclen == 0 || remain_len == 0)
@@ -540,7 +543,7 @@ build_upper_buffer (re_string_t *pstr)
   for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx)
     {
       int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx];
-      if (BE (pstr->trans != NULL, 0))
+      if (__glibc_unlikely (pstr->trans != NULL))
        ch = pstr->trans[ch];
       pstr->mbs[char_idx] = toupper (ch);
     }
@@ -576,7 +579,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int 
eflags)
 {
   Idx offset;
 
-  if (BE (pstr->raw_mbs_idx <= idx, 0))
+  if (__glibc_unlikely (pstr->raw_mbs_idx <= idx))
     offset = idx - pstr->raw_mbs_idx;
   else
     {
@@ -598,14 +601,14 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int 
eflags)
       offset = idx;
     }
 
-  if (BE (offset != 0, 1))
+  if (__glibc_likely (offset != 0))
     {
       /* Should the already checked characters be kept?  */
-      if (BE (offset < pstr->valid_raw_len, 1))
+      if (__glibc_likely (offset < pstr->valid_raw_len))
        {
          /* Yes, move them to the front of the buffer.  */
 #ifdef RE_ENABLE_I18N
-         if (BE (pstr->offsets_needed, 0))
+         if (__glibc_unlikely (pstr->offsets_needed))
            {
              Idx low = 0, high = pstr->valid_len, mid;
              do
@@ -677,7 +680,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int 
eflags)
                memmove (pstr->wcs, pstr->wcs + offset,
                         (pstr->valid_len - offset) * sizeof (wint_t));
 #endif /* RE_ENABLE_I18N */
-             if (BE (pstr->mbs_allocated, 0))
+             if (__glibc_unlikely (pstr->mbs_allocated))
                memmove (pstr->mbs, pstr->mbs + offset,
                         pstr->valid_len - offset);
              pstr->valid_len -= offset;
@@ -693,7 +696,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int 
eflags)
          /* No, skip all characters until IDX.  */
          Idx prev_valid_len = pstr->valid_len;
 
-         if (BE (pstr->offsets_needed, 0))
+         if (__glibc_unlikely (pstr->offsets_needed))
            {
              pstr->len = pstr->raw_len - idx + offset;
              pstr->stop = pstr->raw_stop - idx + offset;
@@ -721,7 +724,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int 
eflags)
 #ifdef _LIBC
                  /* We know the wchar_t encoding is UCS4, so for the simple
                     case, ASCII characters, skip the conversion step.  */
-                 if (isascii (*p) && BE (pstr->trans == NULL, 1))
+                 if (isascii (*p) && __glibc_likely (pstr->trans == NULL))
                    {
                      memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
                      /* pstr->valid_len = 0; */
@@ -739,7 +742,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int 
eflags)
                          size_t mbclen;
 
                          const unsigned char *pp = p;
-                         if (BE (pstr->trans != NULL, 0))
+                         if (__glibc_unlikely (pstr->trans != NULL))
                            {
                              int i = mlen < 6 ? mlen : 6;
                              while (--i >= 0)
@@ -769,13 +772,13 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int 
eflags)
                pstr->tip_context
                  = re_string_context_at (pstr, prev_valid_len - 1, eflags);
              else
-               pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0)
+               pstr->tip_context = ((__glibc_unlikely (pstr->word_ops_used != 
0)
                                      && IS_WIDE_WORD_CHAR (wc))
                                     ? CONTEXT_WORD
                                     : ((IS_WIDE_NEWLINE (wc)
                                         && pstr->newline_anchor)
                                        ? CONTEXT_NEWLINE : 0));
-             if (BE (pstr->valid_len, 0))
+             if (__glibc_unlikely (pstr->valid_len))
                {
                  for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx)
                    pstr->wcs[wcs_idx] = WEOF;
@@ -797,7 +800,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int 
eflags)
                                      ? CONTEXT_NEWLINE : 0));
            }
        }
-      if (!BE (pstr->mbs_allocated, 0))
+      if (!__glibc_unlikely (pstr->mbs_allocated))
        pstr->mbs += offset;
     }
   pstr->raw_mbs_idx = idx;
@@ -811,7 +814,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int 
eflags)
       if (pstr->icase)
        {
          reg_errcode_t ret = build_wcs_upper_buffer (pstr);
-         if (BE (ret != REG_NOERROR, 0))
+         if (__glibc_unlikely (ret != REG_NOERROR))
            return ret;
        }
       else
@@ -819,7 +822,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int 
eflags)
     }
   else
 #endif /* RE_ENABLE_I18N */
-    if (BE (pstr->mbs_allocated, 0))
+    if (__glibc_unlikely (pstr->mbs_allocated))
       {
        if (pstr->icase)
          build_upper_buffer (pstr);
@@ -841,7 +844,7 @@ re_string_peek_byte_case (const re_string_t *pstr, Idx idx)
   Idx off;
 
   /* Handle the common (easiest) cases first.  */
-  if (BE (!pstr->mbs_allocated, 1))
+  if (__glibc_likely (!pstr->mbs_allocated))
     return re_string_peek_byte (pstr, idx);
 
 #ifdef RE_ENABLE_I18N
@@ -873,7 +876,7 @@ re_string_peek_byte_case (const re_string_t *pstr, Idx idx)
 static unsigned char
 re_string_fetch_byte_case (re_string_t *pstr)
 {
-  if (BE (!pstr->mbs_allocated, 1))
+  if (__glibc_likely (!pstr->mbs_allocated))
     return re_string_fetch_byte (pstr);
 
 #ifdef RE_ENABLE_I18N
@@ -924,11 +927,11 @@ static unsigned int
 re_string_context_at (const re_string_t *input, Idx idx, int eflags)
 {
   int c;
-  if (BE (idx < 0, 0))
+  if (__glibc_unlikely (idx < 0))
     /* In this case, we use the value stored in input->tip_context,
        since we can't know the character in input->mbs[-1] here.  */
     return input->tip_context;
-  if (BE (idx == input->len, 0))
+  if (__glibc_unlikely (idx == input->len))
     return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
            : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
 #ifdef RE_ENABLE_I18N
@@ -947,7 +950,8 @@ re_string_context_at (const re_string_t *input, Idx idx, 
int eflags)
            return input->tip_context;
        }
       wc = input->wcs[wc_idx];
-      if (BE (input->word_ops_used != 0, 0) && IS_WIDE_WORD_CHAR (wc))
+      if (__glibc_unlikely (input->word_ops_used != 0)
+         && IS_WIDE_WORD_CHAR (wc))
        return CONTEXT_WORD;
       return (IS_WIDE_NEWLINE (wc) && input->newline_anchor
              ? CONTEXT_NEWLINE : 0);
@@ -971,7 +975,8 @@ re_node_set_alloc (re_node_set *set, Idx size)
   set->alloc = size;
   set->nelem = 0;
   set->elems = re_malloc (Idx, size);
-  if (BE (set->elems == NULL, 0) && (MALLOC_0_IS_NONNULL || size != 0))
+  if (__glibc_unlikely (set->elems == NULL)
+      && (MALLOC_0_IS_NONNULL || size != 0))
     return REG_ESPACE;
   return REG_NOERROR;
 }
@@ -983,7 +988,7 @@ re_node_set_init_1 (re_node_set *set, Idx elem)
   set->alloc = 1;
   set->nelem = 1;
   set->elems = re_malloc (Idx, 1);
-  if (BE (set->elems == NULL, 0))
+  if (__glibc_unlikely (set->elems == NULL))
     {
       set->alloc = set->nelem = 0;
       return REG_ESPACE;
@@ -998,7 +1003,7 @@ re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2)
 {
   set->alloc = 2;
   set->elems = re_malloc (Idx, 2);
-  if (BE (set->elems == NULL, 0))
+  if (__glibc_unlikely (set->elems == NULL))
     return REG_ESPACE;
   if (elem1 == elem2)
     {
@@ -1031,7 +1036,7 @@ re_node_set_init_copy (re_node_set *dest, const 
re_node_set *src)
     {
       dest->alloc = dest->nelem;
       dest->elems = re_malloc (Idx, dest->alloc);
-      if (BE (dest->elems == NULL, 0))
+      if (__glibc_unlikely (dest->elems == NULL))
        {
          dest->alloc = dest->nelem = 0;
          return REG_ESPACE;
@@ -1062,7 +1067,7 @@ re_node_set_add_intersect (re_node_set *dest, const 
re_node_set *src1,
     {
       Idx new_alloc = src1->nelem + src2->nelem + dest->alloc;
       Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc);
-      if (BE (new_elems == NULL, 0))
+      if (__glibc_unlikely (new_elems == NULL))
        return REG_ESPACE;
       dest->elems = new_elems;
       dest->alloc = new_alloc;
@@ -1148,7 +1153,7 @@ re_node_set_init_union (re_node_set *dest, const 
re_node_set *src1,
     {
       dest->alloc = src1->nelem + src2->nelem;
       dest->elems = re_malloc (Idx, dest->alloc);
-      if (BE (dest->elems == NULL, 0))
+      if (__glibc_unlikely (dest->elems == NULL))
        return REG_ESPACE;
     }
   else
@@ -1202,13 +1207,13 @@ re_node_set_merge (re_node_set *dest, const re_node_set 
*src)
     {
       Idx new_alloc = 2 * (src->nelem + dest->alloc);
       Idx *new_buffer = re_realloc (dest->elems, Idx, new_alloc);
-      if (BE (new_buffer == NULL, 0))
+      if (__glibc_unlikely (new_buffer == NULL))
        return REG_ESPACE;
       dest->elems = new_buffer;
       dest->alloc = new_alloc;
     }
 
-  if (BE (dest->nelem == 0, 0))
+  if (__glibc_unlikely (dest->nelem == 0))
     {
       dest->nelem = src->nelem;
       memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx));
@@ -1281,9 +1286,9 @@ re_node_set_insert (re_node_set *set, Idx elem)
   Idx idx;
   /* In case the set is empty.  */
   if (set->alloc == 0)
-    return BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1);
+    return __glibc_likely (re_node_set_init_1 (set, elem) == REG_NOERROR);
 
-  if (BE (set->nelem, 0) == 0)
+  if (__glibc_unlikely (set->nelem) == 0)
     {
       /* We already guaranteed above that set->alloc != 0.  */
       set->elems[0] = elem;
@@ -1297,7 +1302,7 @@ re_node_set_insert (re_node_set *set, Idx elem)
       Idx *new_elems;
       set->alloc = set->alloc * 2;
       new_elems = re_realloc (set->elems, Idx, set->alloc);
-      if (BE (new_elems == NULL, 0))
+      if (__glibc_unlikely (new_elems == NULL))
        return false;
       set->elems = new_elems;
     }
@@ -1336,7 +1341,7 @@ re_node_set_insert_last (re_node_set *set, Idx elem)
       Idx *new_elems;
       set->alloc = (set->alloc + 1) * 2;
       new_elems = re_realloc (set->elems, Idx, set->alloc);
-      if (BE (new_elems == NULL, 0))
+      if (__glibc_unlikely (new_elems == NULL))
        return false;
       set->elems = new_elems;
     }
@@ -1403,7 +1408,7 @@ re_node_set_remove_at (re_node_set *set, Idx idx)
 static Idx
 re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
 {
-  if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0))
+  if (__glibc_unlikely (dfa->nodes_len >= dfa->nodes_alloc))
     {
       size_t new_nodes_alloc = dfa->nodes_alloc * 2;
       Idx *new_nexts, *new_indices;
@@ -1414,19 +1419,20 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
       const size_t max_object_size = MAX (sizeof (re_token_t),
                                          MAX (sizeof (re_node_set),
                                               sizeof (Idx)));
-      if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) < new_nodes_alloc, 0))
+      if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size)
+                           < new_nodes_alloc))
        return -1;
 
       new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc);
-      if (BE (new_nodes == NULL, 0))
+      if (__glibc_unlikely (new_nodes == NULL))
        return -1;
       dfa->nodes = new_nodes;
       new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc);
       new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc);
       new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc);
       new_eclosures = re_realloc (dfa->eclosures, re_node_set, 
new_nodes_alloc);
-      if (BE (new_nexts == NULL || new_indices == NULL
-             || new_edests == NULL || new_eclosures == NULL, 0))
+      if (__glibc_unlikely (new_nexts == NULL || new_indices == NULL
+                           || new_edests == NULL || new_eclosures == NULL))
        {
           re_free (new_nexts);
           re_free (new_indices);
@@ -1485,7 +1491,7 @@ re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
   /* Suppress bogus uninitialized-variable warnings.  */
   *err = REG_NOERROR;
 #endif
-  if (BE (nodes->nelem == 0, 0))
+  if (__glibc_unlikely (nodes->nelem == 0))
     {
       *err = REG_NOERROR;
       return NULL;
@@ -1504,7 +1510,7 @@ re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
 
   /* There are no appropriate state in the dfa, create the new one.  */
   new_state = create_ci_newstate (dfa, nodes, hash);
-  if (BE (new_state == NULL, 0))
+  if (__glibc_unlikely (new_state == NULL))
     *err = REG_ESPACE;
 
   return new_state;
@@ -1551,7 +1557,7 @@ re_acquire_state_context (reg_errcode_t *err, const 
re_dfa_t *dfa,
     }
   /* There are no appropriate state in 'dfa', create the new one.  */
   new_state = create_cd_newstate (dfa, nodes, context, hash);
-  if (BE (new_state == NULL, 0))
+  if (__glibc_unlikely (new_state == NULL))
     *err = REG_ESPACE;
 
   return new_state;
@@ -1572,7 +1578,7 @@ register_state (const re_dfa_t *dfa, re_dfastate_t 
*newstate,
 
   newstate->hash = hash;
   err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem);
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     return REG_ESPACE;
   for (i = 0; i < newstate->nodes.nelem; i++)
     {
@@ -1583,12 +1589,12 @@ register_state (const re_dfa_t *dfa, re_dfastate_t 
*newstate,
     }
 
   spot = dfa->state_table + (hash & dfa->state_hash_mask);
-  if (BE (spot->alloc <= spot->num, 0))
+  if (__glibc_unlikely (spot->alloc <= spot->num))
     {
       Idx new_alloc = 2 * spot->num + 2;
       re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *,
                                              new_alloc);
-      if (BE (new_array == NULL, 0))
+      if (__glibc_unlikely (new_array == NULL))
        return REG_ESPACE;
       spot->array = new_array;
       spot->alloc = new_alloc;
@@ -1626,10 +1632,10 @@ create_ci_newstate (const re_dfa_t *dfa, const 
re_node_set *nodes,
   re_dfastate_t *newstate;
 
   newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
-  if (BE (newstate == NULL, 0))
+  if (__glibc_unlikely (newstate == NULL))
     return NULL;
   err = re_node_set_init_copy (&newstate->nodes, nodes);
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     {
       re_free (newstate);
       return NULL;
@@ -1655,7 +1661,7 @@ create_ci_newstate (const re_dfa_t *dfa, const 
re_node_set *nodes,
        newstate->has_constraint = 1;
     }
   err = register_state (dfa, newstate, hash);
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     {
       free_state (newstate);
       newstate = NULL;
@@ -1676,10 +1682,10 @@ create_cd_newstate (const re_dfa_t *dfa, const 
re_node_set *nodes,
   re_dfastate_t *newstate;
 
   newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
-  if (BE (newstate == NULL, 0))
+  if (__glibc_unlikely (newstate == NULL))
     return NULL;
   err = re_node_set_init_copy (&newstate->nodes, nodes);
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     {
       re_free (newstate);
       return NULL;
@@ -1711,7 +1717,7 @@ create_cd_newstate (const re_dfa_t *dfa, const 
re_node_set *nodes,
          if (newstate->entrance_nodes == &newstate->nodes)
            {
              newstate->entrance_nodes = re_malloc (re_node_set, 1);
-             if (BE (newstate->entrance_nodes == NULL, 0))
+             if (__glibc_unlikely (newstate->entrance_nodes == NULL))
                {
                  free_state (newstate);
                  return NULL;
@@ -1731,7 +1737,7 @@ create_cd_newstate (const re_dfa_t *dfa, const 
re_node_set *nodes,
        }
     }
   err = register_state (dfa, newstate, hash);
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     {
       free_state (newstate);
       newstate = NULL;
diff --git a/lib/regex_internal.h b/lib/regex_internal.h
index dd0900b..b0e49cd 100644
--- a/lib/regex_internal.h
+++ b/lib/regex_internal.h
@@ -33,23 +33,7 @@
 #include <stdbool.h>
 #include <stdint.h>
 
-/* Properties of integers.  Although Gnulib has intprops.h, glibc does
-   without for now.  */
-#ifndef _LIBC
-# include "intprops.h"
-#else
-/* True if the real type T is signed.  */
-# define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
-
-/* True if adding the nonnegative Idx values A and B would overflow.
-   If false, set *R to A + B.  A, B, and R may be evaluated more than
-   once, or zero times.  Although this is not a full implementation of
-   Gnulib INT_ADD_WRAPV, it is good enough for glibc regex code.
-   FIXME: This implementation is a fragile stopgap, and this file would
-   be simpler and more robust if intprops.h were migrated into glibc.  */
-# define INT_ADD_WRAPV(a, b, r) \
-   (IDX_MAX - (a) < (b) ? true : (*(r) = (a) + (b), false))
-#endif
+#include <intprops.h>
 
 #ifdef _LIBC
 # include <libc-lock.h>
@@ -132,8 +116,6 @@
 # define RE_ENABLE_I18N
 #endif
 
-#define BE(expr, val) __builtin_expect (expr, val)
-
 /* Number of ASCII characters.  */
 #define ASCII_CHARS 0x80
 
diff --git a/lib/regexec.c b/lib/regexec.c
index 6591311..8b82ea5 100644
--- a/lib/regexec.c
+++ b/lib/regexec.c
@@ -328,9 +328,8 @@ re_search_2_stub (struct re_pattern_buffer *bufp, const 
char *string1,
   Idx len;
   char *s = NULL;
 
-  if (BE ((length1 < 0 || length2 < 0 || stop < 0
-           || INT_ADD_WRAPV (length1, length2, &len)),
-          0))
+  if (__glibc_unlikely ((length1 < 0 || length2 < 0 || stop < 0
+                        || INT_ADD_WRAPV (length1, length2, &len))))
     return -2;
 
   /* Concatenate the strings.  */
@@ -339,7 +338,7 @@ re_search_2_stub (struct re_pattern_buffer *bufp, const 
char *string1,
       {
        s = re_malloc (char, len);
 
-       if (BE (s == NULL, 0))
+       if (__glibc_unlikely (s == NULL))
          return -2;
 #ifdef _LIBC
        memcpy (__mempcpy (s, string1, length1), string2, length2);
@@ -379,11 +378,13 @@ re_search_stub (struct re_pattern_buffer *bufp, const 
char *string, Idx length,
   Idx last_start = start + range;
 
   /* Check for out-of-range.  */
-  if (BE (start < 0 || start > length, 0))
+  if (__glibc_unlikely (start < 0 || start > length))
     return -1;
-  if (BE (length < last_start || (0 <= range && last_start < start), 0))
+  if (__glibc_unlikely (length < last_start
+                       || (0 <= range && last_start < start)))
     last_start = length;
-  else if (BE (last_start < 0 || (range < 0 && start <= last_start), 0))
+  else if (__glibc_unlikely (last_start < 0
+                            || (range < 0 && start <= last_start)))
     last_start = 0;
 
   lock_lock (dfa->lock);
@@ -395,17 +396,17 @@ re_search_stub (struct re_pattern_buffer *bufp, const 
char *string, Idx length,
   if (start < last_start && bufp->fastmap != NULL && !bufp->fastmap_accurate)
     re_compile_fastmap (bufp);
 
-  if (BE (bufp->no_sub, 0))
+  if (__glibc_unlikely (bufp->no_sub))
     regs = NULL;
 
   /* We need at least 1 register.  */
   if (regs == NULL)
     nregs = 1;
-  else if (BE (bufp->regs_allocated == REGS_FIXED
-              && regs->num_regs <= bufp->re_nsub, 0))
+  else if (__glibc_unlikely (bufp->regs_allocated == REGS_FIXED
+                            && regs->num_regs <= bufp->re_nsub))
     {
       nregs = regs->num_regs;
-      if (BE (nregs < 1, 0))
+      if (__glibc_unlikely (nregs < 1))
        {
          /* Nothing can be copied to regs.  */
          regs = NULL;
@@ -415,7 +416,7 @@ re_search_stub (struct re_pattern_buffer *bufp, const char 
*string, Idx length,
   else
     nregs = bufp->re_nsub + 1;
   pmatch = re_malloc (regmatch_t, nregs);
-  if (BE (pmatch == NULL, 0))
+  if (__glibc_unlikely (pmatch == NULL))
     {
       rval = -2;
       goto out;
@@ -434,11 +435,11 @@ re_search_stub (struct re_pattern_buffer *bufp, const 
char *string, Idx length,
       /* If caller wants register contents data back, copy them.  */
       bufp->regs_allocated = re_copy_regs (regs, pmatch, nregs,
                                           bufp->regs_allocated);
-      if (BE (bufp->regs_allocated == REGS_UNALLOCATED, 0))
+      if (__glibc_unlikely (bufp->regs_allocated == REGS_UNALLOCATED))
        rval = -2;
     }
 
-  if (BE (rval == 0, 1))
+  if (__glibc_likely (rval == 0))
     {
       if (ret_len)
        {
@@ -468,10 +469,10 @@ re_copy_regs (struct re_registers *regs, regmatch_t 
*pmatch, Idx nregs,
   if (regs_allocated == REGS_UNALLOCATED)
     { /* No.  So allocate them with malloc.  */
       regs->start = re_malloc (regoff_t, need_regs);
-      if (BE (regs->start == NULL, 0))
+      if (__glibc_unlikely (regs->start == NULL))
        return REGS_UNALLOCATED;
       regs->end = re_malloc (regoff_t, need_regs);
-      if (BE (regs->end == NULL, 0))
+      if (__glibc_unlikely (regs->end == NULL))
        {
          re_free (regs->start);
          return REGS_UNALLOCATED;
@@ -482,14 +483,14 @@ re_copy_regs (struct re_registers *regs, regmatch_t 
*pmatch, Idx nregs,
     { /* Yes.  If we need more elements than were already
         allocated, reallocate them.  If we need fewer, just
         leave it alone.  */
-      if (BE (need_regs > regs->num_regs, 0))
+      if (__glibc_unlikely (need_regs > regs->num_regs))
        {
          regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs);
          regoff_t *new_end;
-         if (BE (new_start == NULL, 0))
+         if (__glibc_unlikely (new_start == NULL))
            return REGS_UNALLOCATED;
          new_end = re_realloc (regs->end, regoff_t, need_regs);
-         if (BE (new_end == NULL, 0))
+         if (__glibc_unlikely (new_end == NULL))
            {
              re_free (new_start);
              return REGS_UNALLOCATED;
@@ -615,9 +616,10 @@ re_search_internal (const regex_t *preg, const char 
*string, Idx length,
   nmatch -= extra_nmatch;
 
   /* Check if the DFA haven't been compiled.  */
-  if (BE (preg->used == 0 || dfa->init_state == NULL
-         || dfa->init_state_word == NULL || dfa->init_state_nl == NULL
-         || dfa->init_state_begbuf == NULL, 0))
+  if (__glibc_unlikely (preg->used == 0 || dfa->init_state == NULL
+                       || dfa->init_state_word == NULL
+                       || dfa->init_state_nl == NULL
+                       || dfa->init_state_begbuf == NULL))
     return REG_NOMATCH;
 
 #ifdef DEBUG
@@ -644,14 +646,14 @@ re_search_internal (const regex_t *preg, const char 
*string, Idx length,
   err = re_string_allocate (&mctx.input, string, length, dfa->nodes_len + 1,
                            preg->translate, (preg->syntax & RE_ICASE) != 0,
                            dfa);
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     goto free_return;
   mctx.input.stop = stop;
   mctx.input.raw_stop = stop;
   mctx.input.newline_anchor = preg->newline_anchor;
 
   err = match_ctx_init (&mctx, eflags, dfa->nbackref * 2);
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     goto free_return;
 
   /* We will log all the DFA states through which the dfa pass,
@@ -661,15 +663,15 @@ re_search_internal (const regex_t *preg, const char 
*string, Idx length,
   if (nmatch > 1 || dfa->has_mb_node)
     {
       /* Avoid overflow.  */
-      if (BE ((MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *))
-               <= mctx.input.bufs_len), 0))
+      if (__glibc_unlikely ((MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *))
+                            <= mctx.input.bufs_len)))
        {
          err = REG_ESPACE;
          goto free_return;
        }
 
       mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1);
-      if (BE (mctx.state_log == NULL, 0))
+      if (__glibc_unlikely (mctx.state_log == NULL))
        {
          err = REG_ESPACE;
          goto free_return;
@@ -713,19 +715,19 @@ re_search_internal (const regex_t *preg, const char 
*string, Idx length,
 
        case 7:
          /* Fastmap with single-byte translation, match forward.  */
-         while (BE (match_first < right_lim, 1)
+         while (__glibc_likely (match_first < right_lim)
                 && !fastmap[t[(unsigned char) string[match_first]]])
            ++match_first;
          goto forward_match_found_start_or_reached_end;
 
        case 6:
          /* Fastmap without translation, match forward.  */
-         while (BE (match_first < right_lim, 1)
+         while (__glibc_likely (match_first < right_lim)
                 && !fastmap[(unsigned char) string[match_first]])
            ++match_first;
 
        forward_match_found_start_or_reached_end:
-         if (BE (match_first == right_lim, 0))
+         if (__glibc_unlikely (match_first == right_lim))
            {
              ch = match_first >= length
                       ? 0 : (unsigned char) string[match_first];
@@ -758,11 +760,12 @@ re_search_internal (const regex_t *preg, const char 
*string, Idx length,
              /* If MATCH_FIRST is out of the valid range, reconstruct the
                 buffers.  */
              __re_size_t offset = match_first - mctx.input.raw_mbs_idx;
-             if (BE (offset >= (__re_size_t) mctx.input.valid_raw_len, 0))
+             if (__glibc_unlikely (offset
+                                   >= (__re_size_t) mctx.input.valid_raw_len))
                {
                  err = re_string_reconstruct (&mctx.input, match_first,
                                               eflags);
-                 if (BE (err != REG_NOERROR, 0))
+                 if (__glibc_unlikely (err != REG_NOERROR))
                    goto free_return;
 
                  offset = match_first - mctx.input.raw_mbs_idx;
@@ -786,7 +789,7 @@ re_search_internal (const regex_t *preg, const char 
*string, Idx length,
       /* Reconstruct the buffers so that the matcher can assume that
         the matching starts from the beginning of the buffer.  */
       err = re_string_reconstruct (&mctx.input, match_first, eflags);
-      if (BE (err != REG_NOERROR, 0))
+      if (__glibc_unlikely (err != REG_NOERROR))
        goto free_return;
 
 #ifdef RE_ENABLE_I18N
@@ -803,7 +806,7 @@ re_search_internal (const regex_t *preg, const char 
*string, Idx length,
                                   start <= last_start ? &match_first : NULL);
       if (match_last != -1)
        {
-         if (BE (match_last == -2, 0))
+         if (__glibc_unlikely (match_last == -2))
            {
              err = REG_ESPACE;
              goto free_return;
@@ -823,7 +826,7 @@ re_search_internal (const regex_t *preg, const char 
*string, Idx length,
                  err = prune_impossible_nodes (&mctx);
                  if (err == REG_NOERROR)
                    break;
-                 if (BE (err != REG_NOMATCH, 0))
+                 if (__glibc_unlikely (err != REG_NOMATCH))
                    goto free_return;
                  match_last = -1;
                }
@@ -860,7 +863,7 @@ re_search_internal (const regex_t *preg, const char 
*string, Idx length,
        {
          err = set_regs (preg, &mctx, nmatch, pmatch,
                          dfa->has_plural_match && dfa->nbackref > 0);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            goto free_return;
        }
 
@@ -871,7 +874,7 @@ re_search_internal (const regex_t *preg, const char 
*string, Idx length,
        if (pmatch[reg_idx].rm_so != -1)
          {
 #ifdef RE_ENABLE_I18N
-           if (BE (mctx.input.offsets_needed != 0, 0))
+           if (__glibc_unlikely (mctx.input.offsets_needed != 0))
              {
                pmatch[reg_idx].rm_so =
                  (pmatch[reg_idx].rm_so == mctx.input.valid_len
@@ -930,11 +933,12 @@ prune_impossible_nodes (re_match_context_t *mctx)
   halt_node = mctx->last_node;
 
   /* Avoid overflow.  */
-  if (BE (MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *)) <= match_last, 0))
+  if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *))
+                       <= match_last))
     return REG_ESPACE;
 
   sifted_states = re_malloc (re_dfastate_t *, match_last + 1);
-  if (BE (sifted_states == NULL, 0))
+  if (__glibc_unlikely (sifted_states == NULL))
     {
       ret = REG_ESPACE;
       goto free_return;
@@ -942,7 +946,7 @@ prune_impossible_nodes (re_match_context_t *mctx)
   if (dfa->nbackref)
     {
       lim_states = re_malloc (re_dfastate_t *, match_last + 1);
-      if (BE (lim_states == NULL, 0))
+      if (__glibc_unlikely (lim_states == NULL))
        {
          ret = REG_ESPACE;
          goto free_return;
@@ -955,7 +959,7 @@ prune_impossible_nodes (re_match_context_t *mctx)
                         match_last);
          ret = sift_states_backward (mctx, &sctx);
          re_node_set_free (&sctx.limits);
-         if (BE (ret != REG_NOERROR, 0))
+         if (__glibc_unlikely (ret != REG_NOERROR))
              goto free_return;
          if (sifted_states[0] != NULL || lim_states[0] != NULL)
            break;
@@ -977,7 +981,7 @@ prune_impossible_nodes (re_match_context_t *mctx)
                               match_last + 1);
       re_free (lim_states);
       lim_states = NULL;
-      if (BE (ret != REG_NOERROR, 0))
+      if (__glibc_unlikely (ret != REG_NOERROR))
        goto free_return;
     }
   else
@@ -985,7 +989,7 @@ prune_impossible_nodes (re_match_context_t *mctx)
       sift_ctx_init (&sctx, sifted_states, lim_states, halt_node, match_last);
       ret = sift_states_backward (mctx, &sctx);
       re_node_set_free (&sctx.limits);
-      if (BE (ret != REG_NOERROR, 0))
+      if (__glibc_unlikely (ret != REG_NOERROR))
        goto free_return;
       if (sifted_states[0] == NULL)
        {
@@ -1068,7 +1072,7 @@ check_matching (re_match_context_t *mctx, bool 
fl_longest_match,
   err = REG_NOERROR;
   cur_state = acquire_init_state_context (&err, mctx, cur_str_idx);
   /* An initial state must not be NULL (invalid).  */
-  if (BE (cur_state == NULL, 0))
+  if (__glibc_unlikely (cur_state == NULL))
     {
       assert (err == REG_ESPACE);
       return -2;
@@ -1080,24 +1084,24 @@ check_matching (re_match_context_t *mctx, bool 
fl_longest_match,
 
       /* Check OP_OPEN_SUBEXP in the initial state in case that we use them
         later.  E.g. Processing back references.  */
-      if (BE (dfa->nbackref, 0))
+      if (__glibc_unlikely (dfa->nbackref))
        {
          at_init_state = false;
          err = check_subexp_matching_top (mctx, &cur_state->nodes, 0);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            return err;
 
          if (cur_state->has_backref)
            {
              err = transit_state_bkref (mctx, &cur_state->nodes);
-             if (BE (err != REG_NOERROR, 0))
+             if (__glibc_unlikely (err != REG_NOERROR))
                return err;
            }
        }
     }
 
   /* If the RE accepts NULL string.  */
-  if (BE (cur_state->halt, 0))
+  if (__glibc_unlikely (cur_state->halt))
     {
       if (!cur_state->has_constraint
          || check_halt_state_context (mctx, cur_state, cur_str_idx))
@@ -1117,13 +1121,13 @@ check_matching (re_match_context_t *mctx, bool 
fl_longest_match,
       re_dfastate_t *old_state = cur_state;
       Idx next_char_idx = re_string_cur_idx (&mctx->input) + 1;
 
-      if ((BE (next_char_idx >= mctx->input.bufs_len, 0)
+      if ((__glibc_unlikely (next_char_idx >= mctx->input.bufs_len)
           && mctx->input.bufs_len < mctx->input.len)
-         || (BE (next_char_idx >= mctx->input.valid_len, 0)
+         || (__glibc_unlikely (next_char_idx >= mctx->input.valid_len)
              && mctx->input.valid_len < mctx->input.len))
        {
          err = extend_buffers (mctx, next_char_idx + 1);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            {
              assert (err == REG_ESPACE);
              return -2;
@@ -1139,7 +1143,7 @@ check_matching (re_match_context_t *mctx, bool 
fl_longest_match,
          /* Reached the invalid state or an error.  Try to recover a valid
             state using the state log, if available and if we have not
             already found a valid (even if not the longest) match.  */
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            return -2;
 
          if (mctx->state_log == NULL
@@ -1148,7 +1152,7 @@ check_matching (re_match_context_t *mctx, bool 
fl_longest_match,
            break;
        }
 
-      if (BE (at_init_state, 0))
+      if (__glibc_unlikely (at_init_state))
        {
          if (old_state == cur_state)
            next_start_idx = next_char_idx;
@@ -1237,7 +1241,7 @@ proceed_next_node (const re_match_context_t *mctx, Idx 
nregs, regmatch_t *regs,
       re_node_set *edests = &dfa->edests[node];
       Idx dest_node;
       ok = re_node_set_insert (eps_via_nodes, node);
-      if (BE (! ok, 0))
+      if (__glibc_unlikely (! ok))
        return -2;
       /* Pick up a valid destination, or return -1 if none
         is found.  */
@@ -1299,7 +1303,7 @@ proceed_next_node (const re_match_context_t *mctx, Idx 
nregs, regmatch_t *regs,
            {
              Idx dest_node;
              ok = re_node_set_insert (eps_via_nodes, node);
-             if (BE (! ok, 0))
+             if (__glibc_unlikely (! ok))
                return -2;
              dest_node = dfa->edests[node].elems[0];
              if (re_node_set_contains (&mctx->state_log[*pidx]->nodes,
@@ -1449,9 +1453,9 @@ set_regs (const regex_t *preg, const re_match_context_t 
*mctx, size_t nmatch,
       cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node,
                                    &eps_via_nodes, fs);
 
-      if (BE (cur_node < 0, 0))
+      if (__glibc_unlikely (cur_node < 0))
        {
-         if (BE (cur_node == -2, 0))
+         if (__glibc_unlikely (cur_node == -2))
            {
              re_node_set_free (&eps_via_nodes);
              if (prev_idx_match_malloced)
@@ -1579,10 +1583,10 @@ sift_states_backward (const re_match_context_t *mctx, 
re_sift_context_t *sctx)
   /* Build sifted state_log[str_idx].  It has the nodes which can epsilon
      transit to the last_node and the last_node itself.  */
   err = re_node_set_init_1 (&cur_dest, sctx->last_node);
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     return err;
   err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest);
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     goto free_return;
 
   /* Then check each states in the state_log.  */
@@ -1603,7 +1607,7 @@ sift_states_backward (const re_match_context_t *mctx, 
re_sift_context_t *sctx)
       if (mctx->state_log[str_idx])
        {
          err = build_sifted_states (mctx, sctx, str_idx, &cur_dest);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            goto free_return;
        }
 
@@ -1612,7 +1616,7 @@ sift_states_backward (const re_match_context_t *mctx, 
re_sift_context_t *sctx)
         - It is in CUR_SRC.
         And update state_log.  */
       err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest);
-      if (BE (err != REG_NOERROR, 0))
+      if (__glibc_unlikely (err != REG_NOERROR))
        goto free_return;
     }
   err = REG_NOERROR;
@@ -1674,7 +1678,7 @@ build_sifted_states (const re_match_context_t *mctx, 
re_sift_context_t *sctx,
            continue;
        }
       ok = re_node_set_insert (cur_dest, prev_node);
-      if (BE (! ok, 0))
+      if (__glibc_unlikely (! ok))
        return REG_ESPACE;
     }
 
@@ -1695,7 +1699,7 @@ clean_state_log_if_needed (re_match_context_t *mctx, Idx 
next_state_log_idx)
     {
       reg_errcode_t err;
       err = extend_buffers (mctx, next_state_log_idx + 1);
-      if (BE (err != REG_NOERROR, 0))
+      if (__glibc_unlikely (err != REG_NOERROR))
        return err;
     }
 
@@ -1723,11 +1727,11 @@ merge_state_array (const re_dfa_t *dfa, re_dfastate_t 
**dst,
          re_node_set merged_set;
          err = re_node_set_init_union (&merged_set, &dst[st_idx]->nodes,
                                        &src[st_idx]->nodes);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            return err;
          dst[st_idx] = re_acquire_state (&err, dfa, &merged_set);
          re_node_set_free (&merged_set);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            return err;
        }
     }
@@ -1754,7 +1758,7 @@ update_cur_sifted_state (const re_match_context_t *mctx,
          /* At first, add the nodes which can epsilon transit to a node in
             DEST_NODE.  */
          err = add_epsilon_src_nodes (dfa, dest_nodes, candidates);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            return err;
 
          /* Then, check the limitations in the current sift_context.  */
@@ -1762,20 +1766,20 @@ update_cur_sifted_state (const re_match_context_t *mctx,
            {
              err = check_subexp_limits (dfa, dest_nodes, candidates, 
&sctx->limits,
                                         mctx->bkref_ents, str_idx);
-             if (BE (err != REG_NOERROR, 0))
+             if (__glibc_unlikely (err != REG_NOERROR))
                return err;
            }
        }
 
       sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes);
-      if (BE (err != REG_NOERROR, 0))
+      if (__glibc_unlikely (err != REG_NOERROR))
        return err;
     }
 
   if (candidates && mctx->state_log[str_idx]->has_backref)
     {
       err = sift_states_bkref (mctx, sctx, str_idx, candidates);
-      if (BE (err != REG_NOERROR, 0))
+      if (__glibc_unlikely (err != REG_NOERROR))
        return err;
     }
   return REG_NOERROR;
@@ -1790,19 +1794,19 @@ add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set 
*dest_nodes,
   Idx i;
 
   re_dfastate_t *state = re_acquire_state (&err, dfa, dest_nodes);
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     return err;
 
   if (!state->inveclosure.alloc)
     {
       err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem);
-      if (BE (err != REG_NOERROR, 0))
+      if (__glibc_unlikely (err != REG_NOERROR))
        return REG_ESPACE;
       for (i = 0; i < dest_nodes->nelem; i++)
        {
          err = re_node_set_merge (&state->inveclosure,
                                   dfa->inveclosures + dest_nodes->elems[i]);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            return REG_ESPACE;
        }
     }
@@ -1837,7 +1841,7 @@ sub_epsilon_src_nodes (const re_dfa_t *dfa, Idx node, 
re_node_set *dest_nodes,
              {
                err = re_node_set_add_intersect (&except_nodes, candidates,
                                                 dfa->inveclosures + cur_node);
-               if (BE (err != REG_NOERROR, 0))
+               if (__glibc_unlikely (err != REG_NOERROR))
                  {
                    re_node_set_free (&except_nodes);
                    return err;
@@ -2043,7 +2047,7 @@ check_subexp_limits (const re_dfa_t *dfa, re_node_set 
*dest_nodes,
            {
              err = sub_epsilon_src_nodes (dfa, ops_node, dest_nodes,
                                           candidates);
-             if (BE (err != REG_NOERROR, 0))
+             if (__glibc_unlikely (err != REG_NOERROR))
                return err;
            }
 
@@ -2061,7 +2065,7 @@ check_subexp_limits (const re_dfa_t *dfa, re_node_set 
*dest_nodes,
                       Remove it form the current sifted state.  */
                    err = sub_epsilon_src_nodes (dfa, node, dest_nodes,
                                                 candidates);
-                   if (BE (err != REG_NOERROR, 0))
+                   if (__glibc_unlikely (err != REG_NOERROR))
                      return err;
                    --node_idx;
                  }
@@ -2081,7 +2085,7 @@ check_subexp_limits (const re_dfa_t *dfa, re_node_set 
*dest_nodes,
                     Remove it form the current sifted state.  */
                  err = sub_epsilon_src_nodes (dfa, node, dest_nodes,
                                               candidates);
-                 if (BE (err != REG_NOERROR, 0))
+                 if (__glibc_unlikely (err != REG_NOERROR))
                    return err;
                }
            }
@@ -2147,27 +2151,27 @@ sift_states_bkref (const re_match_context_t *mctx, 
re_sift_context_t *sctx,
            {
              local_sctx = *sctx;
              err = re_node_set_init_copy (&local_sctx.limits, &sctx->limits);
-             if (BE (err != REG_NOERROR, 0))
+             if (__glibc_unlikely (err != REG_NOERROR))
                goto free_return;
            }
          local_sctx.last_node = node;
          local_sctx.last_str_idx = str_idx;
          ok = re_node_set_insert (&local_sctx.limits, enabled_idx);
-         if (BE (! ok, 0))
+         if (__glibc_unlikely (! ok))
            {
              err = REG_ESPACE;
              goto free_return;
            }
          cur_state = local_sctx.sifted_states[str_idx];
          err = sift_states_backward (mctx, &local_sctx);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            goto free_return;
          if (sctx->limited_states != NULL)
            {
              err = merge_state_array (dfa, sctx->limited_states,
                                       local_sctx.sifted_states,
                                       str_idx + 1);
-             if (BE (err != REG_NOERROR, 0))
+             if (__glibc_unlikely (err != REG_NOERROR))
                goto free_return;
            }
          local_sctx.sifted_states[str_idx] = cur_state;
@@ -2229,10 +2233,10 @@ transit_state (reg_errcode_t *err, re_match_context_t 
*mctx,
 
 #ifdef RE_ENABLE_I18N
   /* If the current state can accept multibyte.  */
-  if (BE (state->accept_mb, 0))
+  if (__glibc_unlikely (state->accept_mb))
     {
       *err = transit_state_mb (mctx, state);
-      if (BE (*err != REG_NOERROR, 0))
+      if (__glibc_unlikely (*err != REG_NOERROR))
        return NULL;
     }
 #endif /* RE_ENABLE_I18N */
@@ -2249,11 +2253,11 @@ transit_state (reg_errcode_t *err, re_match_context_t 
*mctx,
   for (;;)
     {
       trtable = state->trtable;
-      if (BE (trtable != NULL, 1))
+      if (__glibc_likely (trtable != NULL))
        return trtable[ch];
 
       trtable = state->word_trtable;
-      if (BE (trtable != NULL, 1))
+      if (__glibc_likely (trtable != NULL))
        {
          unsigned int context;
          context
@@ -2309,7 +2313,7 @@ merge_state_with_log (reg_errcode_t *err, 
re_match_context_t *mctx,
          table_nodes = next_state->entrance_nodes;
          *err = re_node_set_init_union (&next_nodes, table_nodes,
                                             log_nodes);
-         if (BE (*err != REG_NOERROR, 0))
+         if (__glibc_unlikely (*err != REG_NOERROR))
            return NULL;
        }
       else
@@ -2329,21 +2333,21 @@ merge_state_with_log (reg_errcode_t *err, 
re_match_context_t *mctx,
        re_node_set_free (&next_nodes);
     }
 
-  if (BE (dfa->nbackref, 0) && next_state != NULL)
+  if (__glibc_unlikely (dfa->nbackref) && next_state != NULL)
     {
       /* Check OP_OPEN_SUBEXP in the current state in case that we use them
         later.  We must check them here, since the back references in the
         next state might use them.  */
       *err = check_subexp_matching_top (mctx, &next_state->nodes,
                                        cur_idx);
-      if (BE (*err != REG_NOERROR, 0))
+      if (__glibc_unlikely (*err != REG_NOERROR))
        return NULL;
 
       /* If the next state has back references.  */
       if (next_state->has_backref)
        {
          *err = transit_state_bkref (mctx, &next_state->nodes);
-         if (BE (*err != REG_NOERROR, 0))
+         if (__glibc_unlikely (*err != REG_NOERROR))
            return NULL;
          next_state = mctx->state_log[cur_idx];
        }
@@ -2407,7 +2411,7 @@ check_subexp_matching_top (re_match_context_t *mctx, 
re_node_set *cur_nodes,
              & ((bitset_word_t) 1 << dfa->nodes[node].opr.idx)))
        {
          err = match_ctx_add_subtop (mctx, node, str_idx);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            return err;
        }
     }
@@ -2429,7 +2433,7 @@ transit_state_sb (reg_errcode_t *err, re_match_context_t 
*mctx,
   unsigned int context;
 
   *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1);
-  if (BE (*err != REG_NOERROR, 0))
+  if (__glibc_unlikely (*err != REG_NOERROR))
     return NULL;
   for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt)
     {
@@ -2438,7 +2442,7 @@ transit_state_sb (reg_errcode_t *err, re_match_context_t 
*mctx,
        {
          *err = re_node_set_merge (&next_nodes,
                                    dfa->eclosures + dfa->nexts[cur_node]);
-         if (BE (*err != REG_NOERROR, 0))
+         if (__glibc_unlikely (*err != REG_NOERROR))
            {
              re_node_set_free (&next_nodes);
              return NULL;
@@ -2497,7 +2501,7 @@ transit_state_mb (re_match_context_t *mctx, re_dfastate_t 
*pstate)
       mctx->max_mb_elem_len = ((mctx->max_mb_elem_len < naccepted) ? naccepted
                               : mctx->max_mb_elem_len);
       err = clean_state_log_if_needed (mctx, dest_idx);
-      if (BE (err != REG_NOERROR, 0))
+      if (__glibc_unlikely (err != REG_NOERROR))
        return err;
 #ifdef DEBUG
       assert (dfa->nexts[cur_node_idx] != -1);
@@ -2511,7 +2515,7 @@ transit_state_mb (re_match_context_t *mctx, re_dfastate_t 
*pstate)
        {
          err = re_node_set_init_union (&dest_nodes,
                                        dest_state->entrance_nodes, new_nodes);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            return err;
        }
       context = re_string_context_at (&mctx->input, dest_idx - 1,
@@ -2520,7 +2524,8 @@ transit_state_mb (re_match_context_t *mctx, re_dfastate_t 
*pstate)
        = re_acquire_state_context (&err, dfa, &dest_nodes, context);
       if (dest_state != NULL)
        re_node_set_free (&dest_nodes);
-      if (BE (mctx->state_log[dest_idx] == NULL && err != REG_NOERROR, 0))
+      if (__glibc_unlikely (mctx->state_log[dest_idx] == NULL
+                           && err != REG_NOERROR))
        return err;
     }
   return REG_NOERROR;
@@ -2559,7 +2564,7 @@ transit_state_bkref (re_match_context_t *mctx, const 
re_node_set *nodes)
         Check the substring which the substring matched.  */
       bkc_idx = mctx->nbkref_ents;
       err = get_subexp (mctx, node_idx, cur_str_idx);
-      if (BE (err != REG_NOERROR, 0))
+      if (__glibc_unlikely (err != REG_NOERROR))
        goto free_return;
 
       /* And add the epsilon closures (which is 'new_dest_nodes') of
@@ -2592,8 +2597,8 @@ transit_state_bkref (re_match_context_t *mctx, const 
re_node_set *nodes)
              mctx->state_log[dest_str_idx]
                = re_acquire_state_context (&err, dfa, new_dest_nodes,
                                            context);
-             if (BE (mctx->state_log[dest_str_idx] == NULL
-                     && err != REG_NOERROR, 0))
+             if (__glibc_unlikely (mctx->state_log[dest_str_idx] == NULL
+                                   && err != REG_NOERROR))
                goto free_return;
            }
          else
@@ -2602,7 +2607,7 @@ transit_state_bkref (re_match_context_t *mctx, const 
re_node_set *nodes)
              err = re_node_set_init_union (&dest_nodes,
                                            dest_state->entrance_nodes,
                                            new_dest_nodes);
-             if (BE (err != REG_NOERROR, 0))
+             if (__glibc_unlikely (err != REG_NOERROR))
                {
                  re_node_set_free (&dest_nodes);
                  goto free_return;
@@ -2610,8 +2615,8 @@ transit_state_bkref (re_match_context_t *mctx, const 
re_node_set *nodes)
              mctx->state_log[dest_str_idx]
                = re_acquire_state_context (&err, dfa, &dest_nodes, context);
              re_node_set_free (&dest_nodes);
-             if (BE (mctx->state_log[dest_str_idx] == NULL
-                     && err != REG_NOERROR, 0))
+             if (__glibc_unlikely (mctx->state_log[dest_str_idx] == NULL
+                                   && err != REG_NOERROR))
                goto free_return;
            }
          /* We need to check recursively if the backreference can epsilon
@@ -2621,10 +2626,10 @@ transit_state_bkref (re_match_context_t *mctx, const 
re_node_set *nodes)
            {
              err = check_subexp_matching_top (mctx, new_dest_nodes,
                                               cur_str_idx);
-             if (BE (err != REG_NOERROR, 0))
+             if (__glibc_unlikely (err != REG_NOERROR))
                goto free_return;
              err = transit_state_bkref (mctx, new_dest_nodes);
-             if (BE (err != REG_NOERROR, 0))
+             if (__glibc_unlikely (err != REG_NOERROR))
                goto free_return;
            }
        }
@@ -2685,7 +2690,8 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx 
bkref_str_idx)
             at the back reference?  */
          if (sl_str_diff > 0)
            {
-             if (BE (bkref_str_off + sl_str_diff > mctx->input.valid_len, 0))
+             if (__glibc_unlikely (bkref_str_off + sl_str_diff
+                                   > mctx->input.valid_len))
                {
                  /* Not enough chars for a successful match.  */
                  if (bkref_str_off + sl_str_diff > mctx->input.len)
@@ -2694,7 +2700,7 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx 
bkref_str_idx)
                  err = clean_state_log_if_needed (mctx,
                                                   bkref_str_off
                                                   + sl_str_diff);
-                 if (BE (err != REG_NOERROR, 0))
+                 if (__glibc_unlikely (err != REG_NOERROR))
                    return err;
                  buf = (const char *) re_string_get_buffer (&mctx->input);
                }
@@ -2713,7 +2719,7 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx 
bkref_str_idx)
 
          if (err == REG_NOMATCH)
            continue;
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            return err;
        }
 
@@ -2732,14 +2738,14 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, 
Idx bkref_str_idx)
             at the back reference?  */
          if (sl_str_off > 0)
            {
-             if (BE (bkref_str_off >= mctx->input.valid_len, 0))
+             if (__glibc_unlikely (bkref_str_off >= mctx->input.valid_len))
                {
                  /* If we are at the end of the input, we cannot match.  */
                  if (bkref_str_off >= mctx->input.len)
                    break;
 
                  err = extend_buffers (mctx, bkref_str_off + 1);
-                 if (BE (err != REG_NOERROR, 0))
+                 if (__glibc_unlikely (err != REG_NOERROR))
                    return err;
 
                  buf = (const char *) re_string_get_buffer (&mctx->input);
@@ -2770,10 +2776,10 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, 
Idx bkref_str_idx)
                               OP_CLOSE_SUBEXP);
          if (err == REG_NOMATCH)
              continue;
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
              return err;
          sub_last = match_ctx_add_sublast (sub_top, cls_node, sl_str);
-         if (BE (sub_last == NULL, 0))
+         if (__glibc_unlikely (sub_last == NULL))
            return REG_ESPACE;
          err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node,
                                bkref_str_idx);
@@ -2804,7 +2810,7 @@ get_subexp_sub (re_match_context_t *mctx, const 
re_sub_match_top_t *sub_top,
     return err;
   err = match_ctx_add_entry (mctx, bkref_node, bkref_str, sub_top->str_idx,
                             sub_last->str_idx);
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     return err;
   to_idx = bkref_str + sub_last->str_idx - sub_top->str_idx;
   return clean_state_log_if_needed (mctx, to_idx);
@@ -2854,19 +2860,19 @@ check_arrival (re_match_context_t *mctx, state_array_t 
*path, Idx top_node,
 
   subexp_num = dfa->nodes[top_node].opr.idx;
   /* Extend the buffer if we need.  */
-  if (BE (path->alloc < last_str + mctx->max_mb_elem_len + 1, 0))
+  if (__glibc_unlikely (path->alloc < last_str + mctx->max_mb_elem_len + 1))
     {
       re_dfastate_t **new_array;
       Idx old_alloc = path->alloc;
       Idx incr_alloc = last_str + mctx->max_mb_elem_len + 1;
       Idx new_alloc;
-      if (BE (IDX_MAX - old_alloc < incr_alloc, 0))
+      if (__glibc_unlikely (IDX_MAX - old_alloc < incr_alloc))
        return REG_ESPACE;
       new_alloc = old_alloc + incr_alloc;
-      if (BE (SIZE_MAX / sizeof (re_dfastate_t *) < new_alloc, 0))
+      if (__glibc_unlikely (SIZE_MAX / sizeof (re_dfastate_t *) < new_alloc))
        return REG_ESPACE;
       new_array = re_realloc (path->array, re_dfastate_t *, new_alloc);
-      if (BE (new_array == NULL, 0))
+      if (__glibc_unlikely (new_array == NULL))
        return REG_ESPACE;
       path->array = new_array;
       path->alloc = new_alloc;
@@ -2887,10 +2893,10 @@ check_arrival (re_match_context_t *mctx, state_array_t 
*path, Idx top_node,
   if (str_idx == top_str)
     {
       err = re_node_set_init_1 (&next_nodes, top_node);
-      if (BE (err != REG_NOERROR, 0))
+      if (__glibc_unlikely (err != REG_NOERROR))
        return err;
       err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type);
-      if (BE (err != REG_NOERROR, 0))
+      if (__glibc_unlikely (err != REG_NOERROR))
        {
          re_node_set_free (&next_nodes);
          return err;
@@ -2902,7 +2908,7 @@ check_arrival (re_match_context_t *mctx, state_array_t 
*path, Idx top_node,
       if (cur_state && cur_state->has_backref)
        {
          err = re_node_set_init_copy (&next_nodes, &cur_state->nodes);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            return err;
        }
       else
@@ -2914,14 +2920,14 @@ check_arrival (re_match_context_t *mctx, state_array_t 
*path, Idx top_node,
        {
          err = expand_bkref_cache (mctx, &next_nodes, str_idx,
                                    subexp_num, type);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            {
              re_node_set_free (&next_nodes);
              return err;
            }
        }
       cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context);
-      if (BE (cur_state == NULL && err != REG_NOERROR, 0))
+      if (__glibc_unlikely (cur_state == NULL && err != REG_NOERROR))
        {
          re_node_set_free (&next_nodes);
          return err;
@@ -2936,7 +2942,7 @@ check_arrival (re_match_context_t *mctx, state_array_t 
*path, Idx top_node,
        {
          err = re_node_set_merge (&next_nodes,
                                   &mctx->state_log[str_idx + 1]->nodes);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            {
              re_node_set_free (&next_nodes);
              return err;
@@ -2947,7 +2953,7 @@ check_arrival (re_match_context_t *mctx, state_array_t 
*path, Idx top_node,
          err = check_arrival_add_next_nodes (mctx, str_idx,
                                              &cur_state->non_eps_nodes,
                                              &next_nodes);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            {
              re_node_set_free (&next_nodes);
              return err;
@@ -2957,14 +2963,14 @@ check_arrival (re_match_context_t *mctx, state_array_t 
*path, Idx top_node,
       if (next_nodes.nelem)
        {
          err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            {
              re_node_set_free (&next_nodes);
              return err;
            }
          err = expand_bkref_cache (mctx, &next_nodes, str_idx,
                                    subexp_num, type);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            {
              re_node_set_free (&next_nodes);
              return err;
@@ -2972,7 +2978,7 @@ check_arrival (re_match_context_t *mctx, state_array_t 
*path, Idx top_node,
        }
       context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags);
       cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context);
-      if (BE (cur_state == NULL && err != REG_NOERROR, 0))
+      if (__glibc_unlikely (cur_state == NULL && err != REG_NOERROR))
        {
          re_node_set_free (&next_nodes);
          return err;
@@ -3041,22 +3047,22 @@ check_arrival_add_next_nodes (re_match_context_t *mctx, 
Idx str_idx,
              if (dest_state)
                {
                  err = re_node_set_merge (&union_set, &dest_state->nodes);
-                 if (BE (err != REG_NOERROR, 0))
+                 if (__glibc_unlikely (err != REG_NOERROR))
                    {
                      re_node_set_free (&union_set);
                      return err;
                    }
                }
              ok = re_node_set_insert (&union_set, next_node);
-             if (BE (! ok, 0))
+             if (__glibc_unlikely (! ok))
                {
                  re_node_set_free (&union_set);
                  return REG_ESPACE;
                }
              mctx->state_log[next_idx] = re_acquire_state (&err, dfa,
                                                            &union_set);
-             if (BE (mctx->state_log[next_idx] == NULL
-                     && err != REG_NOERROR, 0))
+             if (__glibc_unlikely (mctx->state_log[next_idx] == NULL
+                                   && err != REG_NOERROR))
                {
                  re_node_set_free (&union_set);
                  return err;
@@ -3068,7 +3074,7 @@ check_arrival_add_next_nodes (re_match_context_t *mctx, 
Idx str_idx,
          || check_node_accept (mctx, dfa->nodes + cur_node, str_idx))
        {
          ok = re_node_set_insert (next_nodes, dfa->nexts[cur_node]);
-         if (BE (! ok, 0))
+         if (__glibc_unlikely (! ok))
            {
              re_node_set_free (&union_set);
              return REG_ESPACE;
@@ -3096,7 +3102,7 @@ check_arrival_expand_ecl (const re_dfa_t *dfa, 
re_node_set *cur_nodes,
   assert (cur_nodes->nelem);
 #endif
   err = re_node_set_alloc (&new_nodes, cur_nodes->nelem);
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     return err;
   /* Create a new node set NEW_NODES with the nodes which are epsilon
      closures of the node in CUR_NODES.  */
@@ -3110,7 +3116,7 @@ check_arrival_expand_ecl (const re_dfa_t *dfa, 
re_node_set *cur_nodes,
        {
          /* There are no problematic nodes, just merge them.  */
          err = re_node_set_merge (&new_nodes, eclosure);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            {
              re_node_set_free (&new_nodes);
              return err;
@@ -3121,7 +3127,7 @@ check_arrival_expand_ecl (const re_dfa_t *dfa, 
re_node_set *cur_nodes,
          /* There are problematic nodes, re-calculate incrementally.  */
          err = check_arrival_expand_ecl_sub (dfa, &new_nodes, cur_node,
                                              ex_subexp, type);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            {
              re_node_set_free (&new_nodes);
              return err;
@@ -3153,13 +3159,13 @@ check_arrival_expand_ecl_sub (const re_dfa_t *dfa, 
re_node_set *dst_nodes,
          if (type == OP_CLOSE_SUBEXP)
            {
              ok = re_node_set_insert (dst_nodes, cur_node);
-             if (BE (! ok, 0))
+             if (__glibc_unlikely (! ok))
                return REG_ESPACE;
            }
          break;
        }
       ok = re_node_set_insert (dst_nodes, cur_node);
-      if (BE (! ok, 0))
+      if (__glibc_unlikely (! ok))
        return REG_ESPACE;
       if (dfa->edests[cur_node].nelem == 0)
        break;
@@ -3169,7 +3175,7 @@ check_arrival_expand_ecl_sub (const re_dfa_t *dfa, 
re_node_set *dst_nodes,
          err = check_arrival_expand_ecl_sub (dfa, dst_nodes,
                                              dfa->edests[cur_node].elems[1],
                                              ex_subexp, type);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            return err;
        }
       cur_node = dfa->edests[cur_node].elems[0];
@@ -3221,8 +3227,8 @@ expand_bkref_cache (re_match_context_t *mctx, re_node_set 
*cur_nodes,
          err2 = check_arrival_expand_ecl (dfa, &new_dests, subexp_num, type);
          err3 = re_node_set_merge (cur_nodes, &new_dests);
          re_node_set_free (&new_dests);
-         if (BE (err != REG_NOERROR || err2 != REG_NOERROR
-                 || err3 != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR || err2 != REG_NOERROR
+                               || err3 != REG_NOERROR))
            {
              err = (err != REG_NOERROR ? err
                     : (err2 != REG_NOERROR ? err2 : err3));
@@ -3244,7 +3250,7 @@ expand_bkref_cache (re_match_context_t *mctx, re_node_set 
*cur_nodes,
              err = re_node_set_init_copy (&union_set,
                                           &mctx->state_log[to_idx]->nodes);
              ok = re_node_set_insert (&union_set, next_node);
-             if (BE (err != REG_NOERROR || ! ok, 0))
+             if (__glibc_unlikely (err != REG_NOERROR || ! ok))
                {
                  re_node_set_free (&union_set);
                  err = err != REG_NOERROR ? err : REG_ESPACE;
@@ -3254,13 +3260,13 @@ expand_bkref_cache (re_match_context_t *mctx, 
re_node_set *cur_nodes,
          else
            {
              err = re_node_set_init_1 (&union_set, next_node);
-             if (BE (err != REG_NOERROR, 0))
+             if (__glibc_unlikely (err != REG_NOERROR))
                return err;
            }
          mctx->state_log[to_idx] = re_acquire_state (&err, dfa, &union_set);
          re_node_set_free (&union_set);
-         if (BE (mctx->state_log[to_idx] == NULL
-                 && err != REG_NOERROR, 0))
+         if (__glibc_unlikely (mctx->state_log[to_idx] == NULL
+                               && err != REG_NOERROR))
            return err;
        }
     }
@@ -3303,7 +3309,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
   else
     {
       dests_alloc = re_malloc (struct dests_alloc, 1);
-      if (BE (dests_alloc == NULL, 0))
+      if (__glibc_unlikely (dests_alloc == NULL))
        return false;
       dests_node_malloced = true;
     }
@@ -3316,7 +3322,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
   /* At first, group all nodes belonging to 'state' into several
      destinations.  */
   ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch);
-  if (BE (ndests <= 0, 0))
+  if (__glibc_unlikely (ndests <= 0))
     {
       if (dests_node_malloced)
        re_free (dests_alloc);
@@ -3325,7 +3331,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
        {
          state->trtable = (re_dfastate_t **)
            calloc (sizeof (re_dfastate_t *), SBC_MAX);
-          if (BE (state->trtable == NULL, 0))
+          if (__glibc_unlikely (state->trtable == NULL))
             return false;
          return true;
        }
@@ -3333,14 +3339,14 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t 
*state)
     }
 
   err = re_node_set_alloc (&follows, ndests + 1);
-  if (BE (err != REG_NOERROR, 0))
+  if (__glibc_unlikely (err != REG_NOERROR))
     goto out_free;
 
   /* Avoid arithmetic overflow in size calculation.  */
-  if (BE ((((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX)
-           / (3 * sizeof (re_dfastate_t *)))
-          < ndests),
-         0))
+  size_t ndests_max
+    = ((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX)
+       / (3 * sizeof (re_dfastate_t *)));
+  if (__glibc_unlikely (ndests_max < ndests))
     goto out_free;
 
   if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX
@@ -3350,7 +3356,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
   else
     {
       dest_states = re_malloc (re_dfastate_t *, ndests * 3);
-      if (BE (dest_states == NULL, 0))
+      if (__glibc_unlikely (dest_states == NULL))
        {
 out_free:
          if (dest_states_malloced)
@@ -3380,12 +3386,12 @@ out_free:
          if (next_node != -1)
            {
              err = re_node_set_merge (&follows, dfa->eclosures + next_node);
-             if (BE (err != REG_NOERROR, 0))
+             if (__glibc_unlikely (err != REG_NOERROR))
                goto out_free;
            }
        }
       dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0);
-      if (BE (dest_states[i] == NULL && err != REG_NOERROR, 0))
+      if (__glibc_unlikely (dest_states[i] == NULL && err != REG_NOERROR))
        goto out_free;
       /* If the new state has context constraint,
         build appropriate states for these contexts.  */
@@ -3393,7 +3399,8 @@ out_free:
        {
          dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows,
                                                          CONTEXT_WORD);
-         if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0))
+         if (__glibc_unlikely (dest_states_word[i] == NULL
+                               && err != REG_NOERROR))
            goto out_free;
 
          if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1)
@@ -3401,7 +3408,7 @@ out_free:
 
          dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
                                                        CONTEXT_NEWLINE);
-         if (BE (dest_states_nl[i] == NULL && err != REG_NOERROR, 0))
+         if (__glibc_unlikely (dest_states_nl[i] == NULL && err != 
REG_NOERROR))
            goto out_free;
        }
       else
@@ -3412,7 +3419,7 @@ out_free:
       bitset_merge (acceptable, dests_ch[i]);
     }
 
-  if (!BE (need_word_trtable, 0))
+  if (!__glibc_unlikely (need_word_trtable))
     {
       /* We don't care about whether the following character is a word
         character, or we are in a single-byte character set so we can
@@ -3420,7 +3427,7 @@ out_free:
         256-entry transition table.  */
       trtable = state->trtable =
        (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX);
-      if (BE (trtable == NULL, 0))
+      if (__glibc_unlikely (trtable == NULL))
        goto out_free;
 
       /* For all characters ch...:  */
@@ -3428,7 +3435,7 @@ out_free:
        for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1;
             elem;
             mask <<= 1, elem >>= 1, ++ch)
-         if (BE (elem & 1, 0))
+         if (__glibc_unlikely (elem & 1))
            {
              /* There must be exactly one destination which accepts
                 character ch.  See group_nodes_into_DFAstates.  */
@@ -3451,7 +3458,7 @@ out_free:
         starting at trtable[SBC_MAX].  */
       trtable = state->word_trtable =
        (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX);
-      if (BE (trtable == NULL, 0))
+      if (__glibc_unlikely (trtable == NULL))
        goto out_free;
 
       /* For all characters ch...:  */
@@ -3459,7 +3466,7 @@ out_free:
        for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1;
             elem;
             mask <<= 1, elem >>= 1, ++ch)
-         if (BE (elem & 1, 0))
+         if (__glibc_unlikely (elem & 1))
            {
              /* There must be exactly one destination which accepts
                 character ch.  See group_nodes_into_DFAstates.  */
@@ -3658,14 +3665,14 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const 
re_dfastate_t *state,
              bitset_copy (dests_ch[ndests], remains);
              bitset_copy (dests_ch[j], intersec);
              err = re_node_set_init_copy (dests_node + ndests, &dests_node[j]);
-             if (BE (err != REG_NOERROR, 0))
+             if (__glibc_unlikely (err != REG_NOERROR))
                goto error_return;
              ++ndests;
            }
 
          /* Put the position in the current group. */
          ok = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]);
-         if (BE (! ok, 0))
+         if (__glibc_unlikely (! ok))
            goto error_return;
 
          /* If all characters are consumed, go to next node. */
@@ -3677,7 +3684,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const 
re_dfastate_t *state,
        {
          bitset_copy (dests_ch[ndests], accepts);
          err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]);
-         if (BE (err != REG_NOERROR, 0))
+         if (__glibc_unlikely (err != REG_NOERROR))
            goto error_return;
          ++ndests;
          bitset_empty (accepts);
@@ -3711,10 +3718,10 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx 
node_idx,
   int char_len, elem_len;
   Idx i;
 
-  if (BE (node->type == OP_UTF8_PERIOD, 0))
+  if (__glibc_unlikely (node->type == OP_UTF8_PERIOD))
     {
       unsigned char c = re_string_byte_at (input, str_idx), d;
-      if (BE (c < 0xc2, 1))
+      if (__glibc_likely (c < 0xc2))
        return 0;
 
       if (str_idx + 2 > input->len)
@@ -4049,15 +4056,15 @@ extend_buffers (re_match_context_t *mctx, int min_len)
   re_string_t *pstr = &mctx->input;
 
   /* Avoid overflow.  */
-  if (BE (MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *)) / 2
-          <= pstr->bufs_len, 0))
+  if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *)) / 2
+                       <= pstr->bufs_len))
     return REG_ESPACE;
 
   /* Double the lengths of the buffers, but allocate at least MIN_LEN.  */
   ret = re_string_realloc_buffers (pstr,
                                   MAX (min_len,
                                        MIN (pstr->len, pstr->bufs_len * 2)));
-  if (BE (ret != REG_NOERROR, 0))
+  if (__glibc_unlikely (ret != REG_NOERROR))
     return ret;
 
   if (mctx->state_log != NULL)
@@ -4068,7 +4075,7 @@ extend_buffers (re_match_context_t *mctx, int min_len)
         does not have the right size.  */
       re_dfastate_t **new_array = re_realloc (mctx->state_log, re_dfastate_t *,
                                              pstr->bufs_len + 1);
-      if (BE (new_array == NULL, 0))
+      if (__glibc_unlikely (new_array == NULL))
        return REG_ESPACE;
       mctx->state_log = new_array;
     }
@@ -4080,7 +4087,7 @@ extend_buffers (re_match_context_t *mctx, int min_len)
       if (pstr->mb_cur_max > 1)
        {
          ret = build_wcs_upper_buffer (pstr);
-         if (BE (ret != REG_NOERROR, 0))
+         if (__glibc_unlikely (ret != REG_NOERROR))
            return ret;
        }
       else
@@ -4119,12 +4126,12 @@ match_ctx_init (re_match_context_t *mctx, int eflags, 
Idx n)
       size_t max_object_size =
        MAX (sizeof (struct re_backref_cache_entry),
             sizeof (re_sub_match_top_t *));
-      if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) < n, 0))
+      if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size) < n))
        return REG_ESPACE;
 
       mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n);
       mctx->sub_tops = re_malloc (re_sub_match_top_t *, n);
-      if (BE (mctx->bkref_ents == NULL || mctx->sub_tops == NULL, 0))
+      if (__glibc_unlikely (mctx->bkref_ents == NULL || mctx->sub_tops == 
NULL))
        return REG_ESPACE;
     }
   /* Already zero-ed by the caller.
@@ -4195,7 +4202,7 @@ match_ctx_add_entry (re_match_context_t *mctx, Idx node, 
Idx str_idx, Idx from,
       struct re_backref_cache_entry* new_entry;
       new_entry = re_realloc (mctx->bkref_ents, struct re_backref_cache_entry,
                              mctx->abkref_ents * 2);
-      if (BE (new_entry == NULL, 0))
+      if (__glibc_unlikely (new_entry == NULL))
        {
          re_free (mctx->bkref_ents);
          return REG_ESPACE;
@@ -4264,19 +4271,19 @@ match_ctx_add_subtop (re_match_context_t *mctx, Idx 
node, Idx str_idx)
   assert (mctx->sub_tops != NULL);
   assert (mctx->asub_tops > 0);
 #endif
-  if (BE (mctx->nsub_tops == mctx->asub_tops, 0))
+  if (__glibc_unlikely (mctx->nsub_tops == mctx->asub_tops))
     {
       Idx new_asub_tops = mctx->asub_tops * 2;
       re_sub_match_top_t **new_array = re_realloc (mctx->sub_tops,
                                                   re_sub_match_top_t *,
                                                   new_asub_tops);
-      if (BE (new_array == NULL, 0))
+      if (__glibc_unlikely (new_array == NULL))
        return REG_ESPACE;
       mctx->sub_tops = new_array;
       mctx->asub_tops = new_asub_tops;
     }
   mctx->sub_tops[mctx->nsub_tops] = calloc (1, sizeof (re_sub_match_top_t));
-  if (BE (mctx->sub_tops[mctx->nsub_tops] == NULL, 0))
+  if (__glibc_unlikely (mctx->sub_tops[mctx->nsub_tops] == NULL))
     return REG_ESPACE;
   mctx->sub_tops[mctx->nsub_tops]->node = node;
   mctx->sub_tops[mctx->nsub_tops++]->str_idx = str_idx;
@@ -4290,19 +4297,19 @@ static re_sub_match_last_t *
 match_ctx_add_sublast (re_sub_match_top_t *subtop, Idx node, Idx str_idx)
 {
   re_sub_match_last_t *new_entry;
-  if (BE (subtop->nlasts == subtop->alasts, 0))
+  if (__glibc_unlikely (subtop->nlasts == subtop->alasts))
     {
       Idx new_alasts = 2 * subtop->alasts + 1;
       re_sub_match_last_t **new_array = re_realloc (subtop->lasts,
                                                    re_sub_match_last_t *,
                                                    new_alasts);
-      if (BE (new_array == NULL, 0))
+      if (__glibc_unlikely (new_array == NULL))
        return NULL;
       subtop->lasts = new_array;
       subtop->alasts = new_alasts;
     }
   new_entry = calloc (1, sizeof (re_sub_match_last_t));
-  if (BE (new_entry != NULL, 1))
+  if (__glibc_likely (new_entry != NULL))
     {
       subtop->lasts[subtop->nlasts] = new_entry;
       new_entry->node = node;
diff --git a/lisp/autorevert.el b/lisp/autorevert.el
index fc3469e..2cf5b42 100644
--- a/lisp/autorevert.el
+++ b/lisp/autorevert.el
@@ -515,32 +515,43 @@ will use an up-to-date value of `auto-revert-interval'"
 
 (defun auto-revert-notify-add-watch ()
   "Enable file notification for current buffer's associated file."
-  ;; We can assume that `buffer-file-name' and
-  ;; `auto-revert-notify-watch-descriptor' are non-nil.
+  ;; We can assume that `auto-revert-notify-watch-descriptor' is nil.
   (unless (or auto-revert-notify-watch-descriptor
               (string-match auto-revert-notify-exclude-dir-regexp
                            (expand-file-name default-directory))
              (file-symlink-p (or buffer-file-name default-directory)))
-    (setq auto-revert-notify-watch-descriptor
-         (ignore-errors
-           (if buffer-file-name
-               (file-notify-add-watch
-                (expand-file-name buffer-file-name default-directory)
-                '(change attribute-change)
-                'auto-revert-notify-handler)
-             (file-notify-add-watch
-              (expand-file-name default-directory)
-              '(change)
-              'auto-revert-notify-handler))))
-    (when auto-revert-notify-watch-descriptor
-      (setq auto-revert-notify-modified-p t)
-      (puthash
-      auto-revert-notify-watch-descriptor
-       (cons (current-buffer)
-            (gethash auto-revert-notify-watch-descriptor
-                     auto-revert-notify-watch-descriptor-hash-list))
+    ;; Check, whether this has been activated already.
+    (let ((file (if buffer-file-name
+                   (expand-file-name buffer-file-name default-directory)
+                 (expand-file-name default-directory))))
+      (maphash
+       (lambda (key _value)
+         (when (and
+                (equal (file-notify--watch-absolute-filename
+                        (gethash key file-notify-descriptors))
+                       (directory-file-name file))
+                (equal (file-notify--watch-callback
+                        (gethash key file-notify-descriptors))
+                       'auto-revert-notify-handler))
+         (setq auto-revert-notify-watch-descriptor key)))
        auto-revert-notify-watch-descriptor-hash-list)
-      (add-hook 'kill-buffer-hook #'auto-revert-notify-rm-watch nil t))))
+      ;; Create a new watch if needed.
+      (unless auto-revert-notify-watch-descriptor
+        (setq auto-revert-notify-watch-descriptor
+             (ignore-errors
+               (file-notify-add-watch
+                file
+                 (if buffer-file-name '(change attribute-change) '(change))
+                 'auto-revert-notify-handler))))
+      (when auto-revert-notify-watch-descriptor
+        (setq auto-revert-notify-modified-p t)
+        (puthash
+         auto-revert-notify-watch-descriptor
+         (cons (current-buffer)
+              (gethash auto-revert-notify-watch-descriptor
+                       auto-revert-notify-watch-descriptor-hash-list))
+         auto-revert-notify-watch-descriptor-hash-list)
+        (add-hook 'kill-buffer-hook #'auto-revert-notify-rm-watch nil t)))))
 
 ;; If we have file notifications, we want to update the auto-revert buffers
 ;; immediately when a notification occurs. Since file updates can happen very
@@ -626,10 +637,7 @@ no more reverts are possible until the next call of
                           auto-revert-buffers-counter)
                   (auto-revert-handler)
                   (setq auto-revert-buffers-counter-lockedout
-                        auto-revert-buffers-counter))
-
-                ;; No need to check other buffers.
-                (cl-return)))))))))
+                        auto-revert-buffers-counter))))))))))
 
 (defun auto-revert-active-p ()
   "Check if auto-revert is active (in current buffer or globally)."
diff --git a/lisp/cedet/semantic/symref/grep.el 
b/lisp/cedet/semantic/symref/grep.el
index 93bda6a..661e101 100644
--- a/lisp/cedet/semantic/symref/grep.el
+++ b/lisp/cedet/semantic/symref/grep.el
@@ -173,14 +173,16 @@ This shell should support pipe redirect syntax."
          ;; find . -type f -print0 | xargs -0 -e grep -nH -e
          ;; Note : I removed -e as it is not posix, nor necessary it seems.
 
-         (let ((cmd (concat "find " default-directory " -type f " filepattern 
" -print0 "
+         (let ((cmd (concat "find " (file-local-name rootdir)
+                             " -type f " filepattern " -print0 "
                             "| xargs -0 grep -H " grepflags "-e " greppat)))
            ;;(message "Old command: %s" cmd)
-           (call-process semantic-symref-grep-shell nil b nil
+           (process-file semantic-symref-grep-shell nil b nil
                           shell-command-switch cmd)
            )
-       (let ((cmd (semantic-symref-grep-use-template rootdir filepattern 
grepflags greppat)))
-         (call-process semantic-symref-grep-shell nil b nil
+       (let ((cmd (semantic-symref-grep-use-template
+                    (file-local-name rootdir) filepattern grepflags greppat)))
+         (process-file semantic-symref-grep-shell nil b nil
                         shell-command-switch cmd))
        ))
     (setq ans (semantic-symref-parse-tool-output tool b))
diff --git a/lisp/char-fold.el b/lisp/char-fold.el
index 86bd603..907d49e 100644
--- a/lisp/char-fold.el
+++ b/lisp/char-fold.el
@@ -170,7 +170,7 @@ from which to start."
     ;; need to keep them grouped together like this: "\\(  \\|[ ...][ ...]\\)".
     (while (< i end)
       (pcase (aref string i)
-        (`?\s (setq spaces (1+ spaces)))
+        (?\s (setq spaces (1+ spaces)))
         (c (when (> spaces 0)
              (push (char-fold--make-space-string spaces) out)
              (setq spaces 0))
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el
index 723cd50..b69a63b 100644
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@ -917,7 +917,7 @@ the current value of the variable, otherwise `symbol-value' 
is used.
 If optional COMMENT argument is non-nil, also prompt for a comment and return
 it as the third element in the list."
   (let* ((var (read-variable prompt-var))
-        (minibuffer-help-form '(describe-variable var))
+        (minibuffer-help-form `(describe-variable ',var))
         (val
          (let ((prop (get var 'variable-interactive))
                (type (get var 'custom-type))
diff --git a/lisp/cus-start.el b/lisp/cus-start.el
index e33fe6e..133e94f 100644
--- a/lisp/cus-start.el
+++ b/lisp/cus-start.el
@@ -685,7 +685,7 @@ since it could result in memory overflow and make Emacs 
crash."
                      ((string-match "selection" (symbol-name symbol))
                       (fboundp 'x-selection-exists-p))
                      ((string-match "fringe" (symbol-name symbol))
-                      (fboundp 'define-fringe-bitmap))
+                      (boundp 'fringe-bitmaps))
                      ((string-match "\\`imagemagick" (symbol-name symbol))
                       (fboundp 'imagemagick-types))
                      ((equal "font-use-system-font" (symbol-name symbol))
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 1f13204..72c16da 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -763,16 +763,17 @@ can be produced by `dired-get-marked-files', for example."
                    (y-or-n-p (format-message
                               "Confirm--do you mean to use `?' as a wildcard? 
")))
                   (t))))
-    (when ok
-      (if on-each
-         (dired-bunch-files (- 10000 (length command))
-                            (lambda (&rest files)
-                              (dired-run-shell-command
-                                (dired-shell-stuff-it command files t arg)))
-                            nil file-list)
-       ;; execute the shell command
-       (dired-run-shell-command
-        (dired-shell-stuff-it command file-list nil arg)))))))
+    (cond ((not ok) (message "Command canceled"))
+          (t
+           (if on-each
+              (dired-bunch-files (- 10000 (length command))
+                                 (lambda (&rest files)
+                                   (dired-run-shell-command
+                                     (dired-shell-stuff-it command files t 
arg)))
+                                 nil file-list)
+            ;; execute the shell command
+            (dired-run-shell-command
+             (dired-shell-stuff-it command file-list nil arg))))))))
 
 ;; Might use {,} for bash or csh:
 (defvar dired-mark-prefix ""
@@ -1737,7 +1738,7 @@ or with the current marker character if MARKER-CHAR is t."
           (let* ((overwrite (file-exists-p to))
                  (dired-overwrite-confirmed ; for dired-handle-overwrite
                   (and overwrite
-                       (let ((help-form '(format-message "\
+                       (let ((help-form (format-message "\
 Type SPC or `y' to overwrite file `%s',
 DEL or `n' to skip to next,
 ESC or `q' to not overwrite any of the remaining files,
diff --git a/lisp/dired.el b/lisp/dired.el
index 5c7bb95..f2f2b76 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -3046,10 +3046,10 @@ TRASH non-nil means to trash the file instead of 
deleting, provided
                              ("no"   ?n "skip to next")
                              ("all"  ?! "delete all remaining directories with 
no more questions")
                              ("quit" ?q "exit")))
-                     ('"all" (setq recursive 'always dired-recursive-deletes 
recursive))
-                     ('"yes" (if (eq recursive 'top) (setq recursive 'always)))
-                     ('"no" (setq recursive nil))
-                     ('"quit" (keyboard-quit))
+                     ("all" (setq recursive 'always dired-recursive-deletes 
recursive))
+                     ("yes" (if (eq recursive 'top) (setq recursive 'always)))
+                     ("no" (setq recursive nil))
+                     ("quit" (keyboard-quit))
                      (_ (keyboard-quit))))) ; catch all unknown answers
              (setq recursive nil)) ; Empty dir or recursive is nil.
            (delete-directory file recursive trash))))
diff --git a/lisp/doc-view.el b/lisp/doc-view.el
index 2b2c687..31e266f 100644
--- a/lisp/doc-view.el
+++ b/lisp/doc-view.el
@@ -1764,27 +1764,28 @@ toggle between displaying the document or editing it as 
text.
     (doc-view-make-safe-dir doc-view-cache-directory)
     ;; Handle compressed files, remote files, files inside archives
     (setq-local doc-view--buffer-file-name
-                (cond
-                 (jka-compr-really-do-compress
-                  ;; FIXME: there's a risk of name conflicts here.
-                  (expand-file-name
-                   (file-name-nondirectory
-                    (file-name-sans-extension buffer-file-name))
-                   doc-view-cache-directory))
-                 ;; Is the file readable by local processes?
-                 ;; We used to use `file-remote-p' but it's unclear what it's
-                 ;; supposed to return nil for things like local files accessed
-                 ;; via `su' or via file://...
-                 ((let ((file-name-handler-alist nil))
-                    (not (and buffer-file-name
-                              (file-readable-p buffer-file-name))))
-                  ;; FIXME: there's a risk of name conflicts here.
-                  (expand-file-name
-                   (if buffer-file-name
-                       (file-name-nondirectory buffer-file-name)
-                     (buffer-name))
-                   doc-view-cache-directory))
-                 (t buffer-file-name)))
+               (convert-standard-filename
+                 (cond
+                  (jka-compr-really-do-compress
+                   ;; FIXME: there's a risk of name conflicts here.
+                   (expand-file-name
+                    (file-name-nondirectory
+                     (file-name-sans-extension buffer-file-name))
+                    doc-view-cache-directory))
+                  ;; Is the file readable by local processes?
+                  ;; We used to use `file-remote-p' but it's unclear what it's
+                  ;; supposed to return nil for things like local files 
accessed
+                  ;; via `su' or via file://...
+                  ((let ((file-name-handler-alist nil))
+                     (not (and buffer-file-name
+                               (file-readable-p buffer-file-name))))
+                   ;; FIXME: there's a risk of name conflicts here.
+                   (expand-file-name
+                    (if buffer-file-name
+                       (file-name-nondirectory buffer-file-name)
+                      (buffer-name))
+                    doc-view-cache-directory))
+                  (t buffer-file-name))))
     (when (not (string= doc-view--buffer-file-name buffer-file-name))
       (write-region nil nil doc-view--buffer-file-name))
 
diff --git a/lisp/emacs-lisp/autoload.el b/lisp/emacs-lisp/autoload.el
index c9ee532..22aac95 100644
--- a/lisp/emacs-lisp/autoload.el
+++ b/lisp/emacs-lisp/autoload.el
@@ -1047,7 +1047,7 @@ write its autoloads into the specified file instead."
                        ;; we don't want to depend on whether Emacs was
                        ;; built with or without modules support, nor
                        ;; what is the suffix for the underlying OS.
-                      (unless (string-match "\\.\\(elc\\|\\so\\|dll\\)" suf)
+                      (unless (string-match "\\.\\(elc\\|so\\|dll\\)" suf)
                          (push suf tmp)))
                      (concat "^[^=.].*" (regexp-opt tmp t) "\\'")))
         (files (apply #'nconc
diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el
index 83929be..86d211c 100644
--- a/lisp/emacs-lisp/checkdoc.el
+++ b/lisp/emacs-lisp/checkdoc.el
@@ -884,9 +884,8 @@ a separate buffer."
 ;;;###autoload
 (defun checkdoc-continue (&optional take-notes)
   "Find the next doc string in the current buffer which has a style error.
-Prefix argument TAKE-NOTES means to continue through the whole buffer and
-save warnings in a separate buffer.  Second optional argument START-POINT
-is the starting location.  If this is nil, `point-min' is used instead."
+Prefix argument TAKE-NOTES means to continue through the whole
+buffer and save warnings in a separate buffer."
   (interactive "P")
   (let ((wrong nil) (msg nil)
        ;; Assign a flag to spellcheck flag
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index 1731733..c7f0c48 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -345,6 +345,9 @@ the specializer used will be the one returned by BODY."
                                    . ,(lambda () spec-args))
                                  macroexpand-all-environment)))
       (require 'cl-lib)        ;Needed to expand `cl-flet' and `cl-function'.
+      (when (interactive-form (cadr fun))
+        (message "Interactive forms unsupported in generic functions: %S"
+                 (interactive-form (cadr fun))))
       ;; First macroexpand away the cl-function stuff (e.g. &key and
       ;; destructuring args, `declare' and whatnot).
       (pcase (macroexpand fun macroenv)
diff --git a/lisp/emacs-lisp/derived.el b/lisp/emacs-lisp/derived.el
index 6b47ffe..483d6fb 100644
--- a/lisp/emacs-lisp/derived.el
+++ b/lisp/emacs-lisp/derived.el
@@ -193,10 +193,10 @@ See Info node `(elisp)Derived Modes' for more details."
     ;; Process the keyword args.
     (while (keywordp (car body))
       (pcase (pop body)
-       (`:group (setq group (pop body)))
-       (`:abbrev-table (setq abbrev (pop body)) (setq declare-abbrev nil))
-       (`:syntax-table (setq syntax (pop body)) (setq declare-syntax nil))
-        (`:after-hook (setq after-hook (pop body)))
+       (:group (setq group (pop body)))
+       (:abbrev-table (setq abbrev (pop body)) (setq declare-abbrev nil))
+       (:syntax-table (setq syntax (pop body)) (setq declare-syntax nil))
+        (:after-hook (setq after-hook (pop body)))
        (_ (pop body))))
 
     (setq docstring (derived-mode-make-docstring
diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el
index 4d8a502..d74c3dd 100644
--- a/lisp/emacs-lisp/easy-mmode.el
+++ b/lisp/emacs-lisp/easy-mmode.el
@@ -217,30 +217,30 @@ For example, you could write
     (while (keywordp (setq keyw (car body)))
       (setq body (cdr body))
       (pcase keyw
-       (`:init-value (setq init-value (pop body)))
-       (`:lighter (setq lighter (purecopy (pop body))))
-       (`:global (setq globalp (pop body))
-         (when (and globalp (symbolp mode))
-           (setq setter `(setq-default ,mode))
-           (setq getter `(default-value ',mode))))
-       (`:extra-args (setq extra-args (pop body)))
-       (`:set (setq set (list :set (pop body))))
-       (`:initialize (setq initialize (list :initialize (pop body))))
-       (`:group (setq group (nconc group (list :group (pop body)))))
-       (`:type (setq type (list :type (pop body))))
-       (`:require (setq require (pop body)))
-       (`:keymap (setq keymap (pop body)))
-        (`:variable (setq variable (pop body))
-         (if (not (and (setq tmp (cdr-safe variable))
-                       (or (symbolp tmp)
-                           (functionp tmp))))
-             ;; PLACE is not of the form (GET . SET).
-             (progn
-               (setq setter `(setf ,variable))
-               (setq getter variable))
-           (setq getter (car variable))
-           (setq setter `(funcall #',(cdr variable)))))
-       (`:after-hook (setq after-hook (pop body)))
+       (:init-value (setq init-value (pop body)))
+       (:lighter (setq lighter (purecopy (pop body))))
+       (:global (setq globalp (pop body))
+                 (when (and globalp (symbolp mode))
+                   (setq setter `(setq-default ,mode))
+                   (setq getter `(default-value ',mode))))
+       (:extra-args (setq extra-args (pop body)))
+       (:set (setq set (list :set (pop body))))
+       (:initialize (setq initialize (list :initialize (pop body))))
+       (:group (setq group (nconc group (list :group (pop body)))))
+       (:type (setq type (list :type (pop body))))
+       (:require (setq require (pop body)))
+       (:keymap (setq keymap (pop body)))
+        (:variable (setq variable (pop body))
+                   (if (not (and (setq tmp (cdr-safe variable))
+                                 (or (symbolp tmp)
+                                     (functionp tmp))))
+                       ;; PLACE is not of the form (GET . SET).
+                       (progn
+                         (setq setter `(setf ,variable))
+                         (setq getter variable))
+                     (setq getter (car variable))
+                     (setq setter `(funcall #',(cdr variable)))))
+       (:after-hook (setq after-hook (pop body)))
        (_ (push keyw extra-keywords) (push (pop body) extra-keywords))))
 
     (setq keymap-sym (if (and keymap (symbolp keymap)) keymap
@@ -407,8 +407,8 @@ on if the hook has explicitly disabled it."
     (while (keywordp (setq keyw (car keys)))
       (setq keys (cdr keys))
       (pcase keyw
-       (`:group (setq group (nconc group (list :group (pop keys)))))
-       (`:global (setq keys (cdr keys)))
+       (:group (setq group (nconc group (list :group (pop keys)))))
+       (:global (setq keys (cdr keys)))
        (_ (push keyw extra-keywords) (push (pop keys) extra-keywords))))
 
     (unless group
@@ -533,11 +533,11 @@ Valid keywords and arguments are:
       (let ((key (pop args))
            (val (pop args)))
        (pcase key
-        (`:name (setq name val))
-        (`:dense (setq dense val))
-        (`:inherit (setq inherit val))
-        (`:suppress (setq suppress val))
-        (`:group)
+         (:name (setq name val))
+         (:dense (setq dense val))
+         (:inherit (setq inherit val))
+         (:suppress (setq suppress val))
+         (:group)
         (_ (message "Unknown argument %s in defmap" key)))))
     (unless (keymapp m)
       (setq bs (append m bs))
diff --git a/lisp/emacs-lisp/easymenu.el b/lisp/emacs-lisp/easymenu.el
index 94d035f..403829a 100644
--- a/lisp/emacs-lisp/easymenu.el
+++ b/lisp/emacs-lisp/easymenu.el
@@ -226,14 +226,14 @@ possibly preceded by keyword pairs as described in 
`easy-menu-define'."
       (let ((arg (cadr menu-items)))
         (setq menu-items (cddr menu-items))
         (pcase keyword
-          (`:filter
+          (:filter
            (setq filter (lambda (menu)
                           (easy-menu-filter-return (funcall arg menu)
                                                    menu-name))))
-          ((or `:enable `:active) (setq enable (or arg ''nil)))
-          (`:label (setq label arg))
-          (`:help (setq help arg))
-          ((or `:included `:visible) (setq visible (or arg ''nil))))))
+          ((or :enable :active) (setq enable (or arg ''nil)))
+          (:label (setq label arg))
+          (:help (setq help arg))
+          ((or :included :visible) (setq visible (or arg ''nil))))))
     (if (equal visible ''nil)
        nil                             ; Invisible menu entry, return nil.
       (if (and visible (not (easy-menu-always-true-p visible)))
@@ -325,15 +325,15 @@ ITEM defines an item as in `easy-menu-define'."
                (setq arg (aref item (1+ count)))
                (setq count (+ 2 count))
                (pcase keyword
-                  ((or `:included `:visible) (setq visible (or arg ''nil)))
-                  (`:key-sequence (setq cache arg cache-specified t))
-                  (`:keys (setq keys arg no-name nil))
-                  (`:label (setq label arg))
-                  ((or `:active `:enable) (setq active (or arg ''nil)))
-                  (`:help (setq prop (cons :help (cons arg prop))))
-                  (`:suffix (setq suffix arg))
-                  (`:style (setq style arg))
-                  (`:selected (setq selected (or arg ''nil)))))
+                  ((or :included :visible) (setq visible (or arg ''nil)))
+                  (:key-sequence (setq cache arg cache-specified t))
+                  (:keys (setq keys arg no-name nil))
+                  (:label (setq label arg))
+                  ((or :active :enable) (setq active (or arg ''nil)))
+                  (:help (setq prop (cons :help (cons arg prop))))
+                  (:suffix (setq suffix arg))
+                  (:style (setq style arg))
+                  (:selected (setq selected (or arg ''nil)))))
              (if suffix
                  (setq label
                        (if (stringp suffix)
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index fb567c9..15f68a6 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -373,6 +373,8 @@ Return the result of the last expression in BODY."
         (t (split-window (minibuffer-selected-window)))))
   (set-window-buffer window buffer)
   (select-window window)
+  (unless (memq (framep (selected-frame)) '(nil t pc))
+    (x-focus-frame (selected-frame)))
   (set-window-hscroll window 0)) ;; should this be??
 
 (defun edebug-get-displayed-buffer-points ()
@@ -2328,6 +2330,7 @@ and run its entry function, and set up `edebug-before' and
               (debugger edebug-debugger) ; only while edebug is active.
               (edebug-outside-debug-on-error debug-on-error)
               (edebug-outside-debug-on-quit debug-on-quit)
+              (outside-frame (selected-frame))
               ;; Binding these may not be the right thing to do.
               ;; We want to allow the global values to be changed.
               (debug-on-error (or debug-on-error edebug-on-error))
@@ -2338,7 +2341,10 @@ and run its entry function, and set up `edebug-before' 
and
                                                 edebug-initial-mode
                                                 edebug-execution-mode)
                       edebug-next-execution-mode nil)
-                (edebug-default-enter function args body))))
+                (edebug-default-enter function args body))
+            (if (and (frame-live-p outside-frame)
+                     (not (memq (framep outside-frame) '(nil t pc))))
+                (x-focus-frame outside-frame))))
 
       (let* ((edebug-data (get function 'edebug))
              (edebug-def-mark (car edebug-data)) ; mark at def start
@@ -2647,6 +2653,8 @@ See `edebug-behavior-alist' for implementations.")
          (edebug-eval-display eval-result-list)
          ;; The evaluation list better not have deleted edebug-window-data.
          (select-window (car edebug-window-data))
+          (if (not (memq (framep (selected-frame)) '(nil t pc)))
+              (x-focus-frame (selected-frame)))
          (set-buffer edebug-buffer)
 
          (setq edebug-buffer-outside-point (point))
diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el
index e5ea33c..e5c4f19 100644
--- a/lisp/emacs-lisp/eieio-core.el
+++ b/lisp/emacs-lisp/eieio-core.el
@@ -388,9 +388,9 @@ See `defclass' for more information."
        ;; Clean up the meaning of protection.
         (setq prot
               (pcase prot
-                ((or 'nil 'public ':public) nil)
-                ((or 'protected ':protected) 'protected)
-                ((or 'private ':private) 'private)
+                ((or 'nil 'public :public) nil)
+                ((or 'protected :protected) 'protected)
+                ((or 'private :private) 'private)
                 (_ (signal 'invalid-slot-type (list :protection prot)))))
 
        ;; The default type specifier is supposed to be t, meaning anything.
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index afb7cbd..4619919 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -839,6 +839,10 @@ by more than one line to cross a string literal."
     (prog1
         (let (indent)
           (cond ((= (forward-line 1) 1) nil)
+                ;; Negative depth, probably some kind of syntax error.
+                ((null indent-stack)
+                 ;; Reset state.
+                 (setq ppss (parse-partial-sexp (point) (point))))
                 ((car indent-stack))
                 ((integerp (setq indent (calculate-lisp-indent ppss)))
                  (setf (car indent-stack) indent))
diff --git a/lisp/emacs-lisp/lisp.el b/lisp/emacs-lisp/lisp.el
index 5a89923..3fda1dd 100644
--- a/lisp/emacs-lisp/lisp.el
+++ b/lisp/emacs-lisp/lisp.el
@@ -723,11 +723,13 @@ This command assumes point is not in a string or comment."
   (interactive "P")
   (insert-pair arg ?\( ?\)))
 
-(defun delete-pair ()
-  "Delete a pair of characters enclosing the sexp that follows point."
-  (interactive)
-  (save-excursion (forward-sexp 1) (delete-char -1))
-  (delete-char 1))
+(defun delete-pair (&optional arg)
+  "Delete a pair of characters enclosing ARG sexps following point.
+A negative ARG deletes a pair of characters around preceding ARG sexps."
+  (interactive "p")
+  (unless arg (setq arg 1))
+  (save-excursion (forward-sexp arg) (delete-char (if (> arg 0) -1 1)))
+  (delete-char (if (> arg 0) 1 -1)))
 
 (defun raise-sexp (&optional arg)
   "Raise ARG sexps higher up the tree."
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index 2ddab65..f2ffef8 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -689,8 +689,9 @@ PKG-DESC is a `package-desc' object."
 Load the autoloads file, and ensure `load-path' is setup.  If
 RELOAD is non-nil, also load all files in the package that
 correspond to previously loaded files."
-  (let* ((loaded-files-list (when reload
-                              (package--list-loaded-files (package-desc-dir 
pkg-desc)))))
+  (let* ((loaded-files-list
+          (when reload
+            (package--list-loaded-files (package-desc-dir pkg-desc)))))
     ;; Add to load path, add autoloads, and activate the package.
     (package--activate-autoloads-and-load-path pkg-desc)
     ;; Call `load' on all files in `package-desc-dir' already present in
@@ -2910,17 +2911,17 @@ PKG is a `package-desc' object.
 Return (PKG-DESC [NAME VERSION STATUS DOC])."
   (let* ((status  (package-desc-status pkg))
          (face (pcase status
-                 (`"built-in"  'package-status-built-in)
-                 (`"external"  'package-status-external)
-                 (`"available" 'package-status-available)
-                 (`"avail-obso" 'package-status-avail-obso)
-                 (`"new"       'package-status-new)
-                 (`"held"      'package-status-held)
-                 (`"disabled"  'package-status-disabled)
-                 (`"installed" 'package-status-installed)
-                 (`"dependency" 'package-status-dependency)
-                 (`"unsigned"  'package-status-unsigned)
-                 (`"incompat"  'package-status-incompat)
+                 ("built-in"  'package-status-built-in)
+                 ("external"  'package-status-external)
+                 ("available" 'package-status-available)
+                 ("avail-obso" 'package-status-avail-obso)
+                 ("new"       'package-status-new)
+                 ("held"      'package-status-held)
+                 ("disabled"  'package-status-disabled)
+                 ("installed" 'package-status-installed)
+                 ("dependency" 'package-status-dependency)
+                 ("unsigned"  'package-status-unsigned)
+                 ("incompat"  'package-status-incompat)
                  (_            'font-lock-warning-face)))) ; obsolete.
     (list pkg
           `[(,(symbol-name (package-desc-name pkg))
@@ -3450,6 +3451,40 @@ The list is displayed in a buffer named `*Packages*'."
   (interactive)
   (list-packages t))
 
+;;;###autoload
+(defun package-get-version ()
+  "Return the version number of the package in which this is used.
+Assumes it is used from an Elisp file placed inside the top-level directory
+of an installed ELPA package.
+The return value is a string (or nil in case we can't find it)."
+  ;; In a sense, this is a lie, but it does just what we want: precompute
+  ;; the version at compile time and hardcodes it into the .elc file!
+  (declare (pure t))
+  ;; Hack alert!
+  (let ((file
+         (or (if (boundp 'byte-compile-current-file) byte-compile-current-file)
+             load-file-name
+             buffer-file-name)))
+    (cond
+     ((null file) nil)
+     ;; Packages are normally installed into directories named "<pkg>-<vers>",
+     ;; so get the version number from there.
+     ((string-match 
"/[^/]+-\\([0-9]\\(?:[0-9.]\\|pre\\|beta\\|alpha\\|snapshot\\)+\\)/[^/]+\\'" 
file)
+      (match-string 1 file))
+     ;; For packages run straight from the an elpa.git clone, there's no
+     ;; "-<vers>" in the directory name, so we have to fetch the version
+     ;; the hard way.
+     (t
+      (let* ((pkgdir (file-name-directory file))
+             (pkgname (file-name-nondirectory (directory-file-name pkgdir)))
+             (mainfile (expand-file-name (concat pkgname ".el") pkgdir)))
+        (when (file-readable-p mainfile)
+          (require 'lisp-mnt)
+          (with-temp-buffer
+            (insert-file-contents mainfile)
+            (or (lm-header "package-version")
+                (lm-header "version")))))))))
+
 ;;;; Quickstart: precompute activation actions for faster start up.
 
 ;; Activating packages via `package-initialize' is costly: for N installed
@@ -3536,7 +3571,7 @@ activations need to be changed, such as when 
`package-load-list' is modified."
       (insert "
 ;; Local\sVariables:
 ;; version-control: never
-;; no-byte-compile: t
+;;\sno-byte-compile: t
 ;; no-update-autoloads: t
 ;; End:
 "))))
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
index 4a69244..a2143bf 100644
--- a/lisp/emacs-lisp/pcase.el
+++ b/lisp/emacs-lisp/pcase.el
@@ -264,9 +264,14 @@ variable name being but a special case of it)."
 
 ;;;###autoload
 (defmacro pcase-let* (bindings &rest body)
-  "Like `let*' but where you can use `pcase' patterns for bindings.
-BODY should be an expression, and BINDINGS should be a list of bindings
-of the form (PAT EXP)."
+  "Like `let*', but supports destructuring BINDINGS using `pcase' patterns.
+As with `pcase-let', BINDINGS are of the form (PATTERN EXP), but the
+EXP in each binding in BINDINGS can use the results of the destructuring
+bindings that precede it in BINDINGS' order.
+
+Each EXP should match (i.e. be of compatible structure) to its
+respective PATTERN; a mismatch may signal an error or may go
+undetected, binding variables to arbitrary values, such as nil."
   (declare (indent 1)
            (debug ((&rest (pcase-PAT &optional form)) body)))
   (let ((cached (gethash bindings pcase--memoize)))
@@ -279,12 +284,16 @@ of the form (PAT EXP)."
 
 ;;;###autoload
 (defmacro pcase-let (bindings &rest body)
-  "Like `let' but where you can use `pcase' patterns for bindings.
-BODY should be a list of expressions, and BINDINGS should be a list of bindings
-of the form (PAT EXP).
-The macro is expanded and optimized under the assumption that those
-patterns *will* match, so a mismatch may go undetected or may cause
-any kind of error."
+  "Like `let', but supports destructuring BINDINGS using `pcase' patterns.
+BODY should be a list of expressions, and BINDINGS should be a list of
+bindings of the form (PATTERN EXP).
+All EXPs are evaluated first, and then used to perform destructuring
+bindings by matching each EXP against its respective PATTERN.  Then
+BODY is evaluated with those bindings in effect.
+
+Each EXP should match (i.e. be of compatible structure) to its
+respective PATTERN; a mismatch may signal an error or may go
+undetected, binding variables to arbitrary values, such as nil."
   (declare (indent 1) (debug pcase-let*))
   (if (null (cdr bindings))
       `(pcase-let* ,bindings ,@body)
@@ -302,7 +311,15 @@ any kind of error."
 
 ;;;###autoload
 (defmacro pcase-dolist (spec &rest body)
-  "Like `dolist' but where the binding can be a `pcase' pattern.
+  "Eval BODY once for each set of bindings defined by PATTERN and LIST 
elements.
+PATTERN should be a `pcase' pattern describing the structure of
+LIST elements, and LIST is a list of objects that match PATTERN,
+i.e. have a structure that is compatible with PATTERN.
+For each element of LIST, this macro binds the variables in
+PATTERN to the corresponding subfields of the LIST element, and
+then evaluates BODY with these bindings in effect.  The
+destructuring bindings of variables in PATTERN to the subfields
+of the elements of LIST is performed as if by `pcase-let'.
 \n(fn (PATTERN LIST) BODY...)"
   (declare (indent 1) (debug ((pcase-PAT form) body)))
   (if (pcase--trivial-upat-p (car spec))
@@ -870,7 +887,8 @@ Otherwise, it defers to REST which is a list of branches of 
the form
                (else-rest (cdr splitrest)))
           (pcase--if (cond
                       ((null val) `(null ,sym))
-                      ((or (integerp val) (symbolp val))
+                      ((integerp val) `(eql ,sym ,val))
+                      ((symbolp val)
                        (if (pcase--self-quoting-p val)
                            `(eq ,sym ,val)
                          `(eq ,sym ',val)))
diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el
index bb75901..1230df4 100644
--- a/lisp/emacs-lisp/rx.el
+++ b/lisp/emacs-lisp/rx.el
@@ -1060,7 +1060,7 @@ CHAR
      `chinese-two-byte'                        (\\cC)
      `greek-two-byte'                  (\\cG)
      `japanese-hiragana-two-byte'      (\\cH)
-     `indian-tow-byte'                 (\\cI)
+     `indian-two-byte'                 (\\cI)
      `japanese-katakana-two-byte'      (\\cK)
      `korean-hangul-two-byte'          (\\cN)
      `cyrillic-two-byte'               (\\cY)
diff --git a/lisp/emacs-lisp/smie.el b/lisp/emacs-lisp/smie.el
index c01a401..4b82172 100644
--- a/lisp/emacs-lisp/smie.el
+++ b/lisp/emacs-lisp/smie.el
@@ -1856,9 +1856,9 @@ KEYWORDS are additional arguments, which can use the 
following keywords:
     (let ((k (pop keywords))
           (v (pop keywords)))
       (pcase k
-        (`:forward-token
+        (:forward-token
          (set (make-local-variable 'smie-forward-token-function) v))
-        (`:backward-token
+        (:backward-token
          (set (make-local-variable 'smie-backward-token-function) v))
         (_ (message "smie-setup: ignoring unknown keyword %s" k)))))
   (let ((ca (cdr (assq :smie-closer-alist grammar))))
diff --git a/lisp/emacs-lisp/syntax.el b/lisp/emacs-lisp/syntax.el
index ad1a966..a4b7015 100644
--- a/lisp/emacs-lisp/syntax.el
+++ b/lisp/emacs-lisp/syntax.el
@@ -176,7 +176,7 @@ Note: back-references in REGEXPs do not work."
          (re
           (mapconcat
            (lambda (rule)
-             (let* ((orig-re (eval (car rule)))
+             (let* ((orig-re (eval (car rule) t))
                     (re orig-re))
                (when (and (assq 0 rule) (cdr rules))
                  ;; If there's more than 1 rule, and the rule want to apply
@@ -190,7 +190,7 @@ Note: back-references in REGEXPs do not work."
                       (cond
                        ((assq 0 rule) (if (zerop offset) t
                                         `(match-beginning ,offset)))
-                       ((null (cddr rule))
+                       ((and (cdr rule) (null (cddr rule)))
                         `(match-beginning ,(+ offset (car (cadr rule)))))
                        (t
                         `(or ,@(mapcar
diff --git a/lisp/emacs-lisp/timer.el b/lisp/emacs-lisp/timer.el
index 927e640..56323c8 100644
--- a/lisp/emacs-lisp/timer.el
+++ b/lisp/emacs-lisp/timer.el
@@ -100,10 +100,16 @@ of SECS seconds since the epoch.  SECS may be a fraction."
                            (integerp (cdr time)) (< 0 (cdr time)))
                       time
                     (encode-time time 1000000000000)))
+        (ticks (car ticks-hz))
         (hz (cdr ticks-hz))
-        (s-ticks (* secs hz))
-        (more-ticks (+ (car ticks-hz) s-ticks)))
-    (encode-time (cons (- more-ticks (% more-ticks s-ticks)) hz))))
+        trunc-s-ticks)
+    (while (let ((s-ticks (* secs hz)))
+            (setq trunc-s-ticks (truncate s-ticks))
+            (/= s-ticks trunc-s-ticks))
+      (setq ticks (ash ticks 1))
+      (setq hz (ash hz 1)))
+    (let ((more-ticks (+ ticks trunc-s-ticks)))
+      (encode-time (cons (- more-ticks (% more-ticks trunc-s-ticks)) hz)))))
 
 (defun timer-relative-time (time secs &optional usecs psecs)
   "Advance TIME by SECS seconds and optionally USECS microseconds
diff --git a/lisp/epg.el b/lisp/epg.el
index 8f26cd3..c8f24eb 100644
--- a/lisp/epg.el
+++ b/lisp/epg.el
@@ -655,7 +655,7 @@ callback data (if any)."
                                  :command (cons (epg-context-program context)
                                                 args)
                                  :connection-type 'pipe
-                                 :coding '(binary . binary)
+                                 :coding 'raw-text
                                  :filter #'epg--process-filter
                                  :stderr error-process
                                  :noquery t)))
@@ -946,10 +946,7 @@ callback data (if any)."
    (cons (cons 'no-seckey string)
         (epg-context-result-for context 'error))))
 
-(defun epg--time-from-seconds (seconds)
-  (let ((number-seconds (string-to-number (concat seconds ".0"))))
-    (cons (floor (/ number-seconds 65536))
-         (floor (mod number-seconds 65536)))))
+(defalias 'epg--time-from-seconds #'string-to-number)
 
 (defun epg--status-ERRSIG (context string)
   (if (string-match "\\`\\([^ ]+\\) \\([0-9]+\\) \\([0-9]+\\) \
diff --git a/lisp/eshell/em-rebind.el b/lisp/eshell/em-rebind.el
index e6f04b6..064dcc7 100644
--- a/lisp/eshell/em-rebind.el
+++ b/lisp/eshell/em-rebind.el
@@ -223,7 +223,7 @@ lock it at that."
   (interactive "P")
   (let ((count (prefix-numeric-value n)))
     (if (eshell-point-within-input-p (- (point) count))
-       (delete-backward-char count n)
+       (delete-char (- count) n)
       (beep))))
 
 (defun eshell-delchar-or-maybe-eof (arg)
diff --git a/lisp/faces.el b/lisp/faces.el
index 18b821a..a8c1546 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -1084,27 +1084,27 @@ of a set of discrete values.  Value is `integerp' if 
ATTRIBUTE expects
 an integer value."
   (let ((valid
          (pcase attribute
-           (`:family
+           (:family
             (if (window-system frame)
                 (mapcar (lambda (x) (cons x x))
                         (font-family-list))
              ;; Only one font on TTYs.
              (list (cons "default" "default"))))
-           (`:foundry
+           (:foundry
            (list nil))
-          (`:width
+          (:width
            (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1)))
                    font-width-table))
-           (`:weight
+           (:weight
            (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1)))
                    font-weight-table))
-          (`:slant
+          (:slant
            (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1)))
                    font-slant-table))
-          (`:inverse-video
+          (:inverse-video
            (mapcar #'(lambda (x) (cons (symbol-name x) x))
                    (internal-lisp-face-attribute-values attribute)))
-           ((or `:underline `:overline `:strike-through `:box)
+           ((or :underline :overline :strike-through :box)
             (if (window-system frame)
                 (nconc (mapcar #'(lambda (x) (cons (symbol-name x) x))
                                (internal-lisp-face-attribute-values attribute))
@@ -1112,12 +1112,12 @@ an integer value."
                                (defined-colors frame)))
              (mapcar #'(lambda (x) (cons (symbol-name x) x))
                      (internal-lisp-face-attribute-values attribute))))
-           ((or `:foreground `:background)
+           ((or :foreground :background)
             (mapcar #'(lambda (c) (cons c c))
                     (defined-colors frame)))
-           (`:height
+           (:height
             'integerp)
-           (`:stipple
+           (:stipple
             (and (memq (window-system frame) '(x ns)) ; No stipple on w32
                  (mapcar #'list
                          (apply #'nconc
@@ -1126,7 +1126,7 @@ an integer value."
                                                (file-directory-p dir)
                                                (directory-files dir)))
                                         x-bitmap-file-path)))))
-           (`:inherit
+           (:inherit
             (cons '("none" . nil)
                   (mapcar #'(lambda (c) (cons (symbol-name c) c))
                           (face-list))))
diff --git a/lisp/filenotify.el b/lisp/filenotify.el
index 59a8c0e..a133f9e 100644
--- a/lisp/filenotify.el
+++ b/lisp/filenotify.el
@@ -45,11 +45,11 @@ could use another implementation.")
                (:constructor nil)
                (:constructor
                 file-notify--watch-make (directory filename callback)))
-  ;; Watched directory
+  ;; Watched directory.
   directory
   ;; Watched relative filename, nil if watching the directory.
   filename
-  ;; Function to propagate events to
+  ;; Function to propagate events to.
   callback)
 
 (defun file-notify--watch-absolute-filename (watch)
@@ -242,11 +242,10 @@ EVENT is the cadr of the event in 
`file-notify-handle-event'
             ;;(message
             ;;"file-notify-callback %S %S %S %S %S"
             ;;desc action file file1 watch)
-            (if file1
-                (funcall (file-notify--watch-callback watch)
-                         `(,desc ,action ,file ,file1))
-              (funcall (file-notify--watch-callback watch)
-                       `(,desc  ,action ,file))))
+            (funcall (file-notify--watch-callback watch)
+                     (if file1
+                         `(,desc ,action ,file ,file1)
+                       `(,desc ,action ,file))))
 
           ;; Send `stopped' event.
           (when (or stopped
diff --git a/lisp/files.el b/lisp/files.el
index 2a770df..5764a43 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -1982,12 +1982,13 @@ started Emacs, set `abbreviated-home-dir' to nil so it 
will be recalculated)."
       (unless abbreviated-home-dir
         (put 'abbreviated-home-dir 'home (expand-file-name "~"))
         (setq abbreviated-home-dir
-              (let ((abbreviated-home-dir "$foo"))
-                (setq abbreviated-home-dir
+              (let* ((abbreviated-home-dir "\\`\\'.") ;Impossible regexp.
+                     (regexp
                       (concat "\\`"
-                              (abbreviate-file-name
-                               (get 'abbreviated-home-dir 'home))
-                              "\\(/\\|\\'\\)"))
+                              (regexp-quote
+                               (abbreviate-file-name
+                                (get 'abbreviated-home-dir 'home)))
+                              "\\(/\\|\\'\\)")))
                 ;; Depending on whether default-directory does or
                 ;; doesn't include non-ASCII characters, the value
                 ;; of abbreviated-home-dir could be multibyte or
@@ -1995,9 +1996,9 @@ started Emacs, set `abbreviated-home-dir' to nil so it 
will be recalculated)."
                 ;; it.  Note that this function is called for the
                 ;; first time (from startup.el) when
                 ;; locale-coding-system is already set up.
-                (if (multibyte-string-p abbreviated-home-dir)
-                    abbreviated-home-dir
-                  (decode-coding-string abbreviated-home-dir
+                (if (multibyte-string-p regexp)
+                    regexp
+                  (decode-coding-string regexp
                                         (if (eq system-type 'windows-nt)
                                             'utf-8
                                           locale-coding-system))))))
@@ -2010,22 +2011,22 @@ started Emacs, set `abbreviated-home-dir' to nil so it 
will be recalculated)."
       ;; is likely temporary (eg for testing).
       ;; FIXME Is it even worth caching abbreviated-home-dir?
       ;; Ref: https://debbugs.gnu.org/19657#20
-      (if (and (string-match abbreviated-home-dir filename)
-              ;; If the home dir is just /, don't change it.
-              (not (and (= (match-end 0) 1)
-                        (= (aref filename 0) ?/)))
-              ;; MS-DOS root directories can come with a drive letter;
-              ;; Novell Netware allows drive letters beyond `Z:'.
-              (not (and (memq system-type '(ms-dos windows-nt cygwin))
-                        (save-match-data
-                          (string-match "^[a-zA-`]:/$" filename))))
-               (equal (get 'abbreviated-home-dir 'home)
-                      (save-match-data (expand-file-name "~"))))
-         (setq filename
-               (concat "~"
-                       (match-string 1 filename)
-                       (substring filename (match-end 0)))))
-      filename)))
+      (let (mb1)
+        (if (and (string-match abbreviated-home-dir filename)
+                 (setq mb1 (match-beginning 1))
+                ;; If the home dir is just /, don't change it.
+                (not (and (= (match-end 0) 1)
+                          (= (aref filename 0) ?/)))
+                ;; MS-DOS root directories can come with a drive letter;
+                ;; Novell Netware allows drive letters beyond `Z:'.
+                (not (and (memq system-type '(ms-dos windows-nt cygwin))
+                          (string-match "\\`[a-zA-`]:/\\'" filename)))
+                 (equal (get 'abbreviated-home-dir 'home)
+                        (expand-file-name "~")))
+           (setq filename
+                 (concat "~"
+                         (substring filename mb1))))
+        filename))))
 
 (defun find-buffer-visiting (filename &optional predicate)
   "Return the buffer visiting file FILENAME (a string).
@@ -2422,9 +2423,9 @@ Do you want to revisit the file normally now? ")
               ;; If they fail too, set error.
               (setq error t)))))
       ;; Record the file's truename, and maybe use that as visited name.
-      (if (equal filename buffer-file-name)
-         (setq buffer-file-truename truename)
-       (setq buffer-file-truename
+      (setq buffer-file-truename
+            (if (equal filename buffer-file-name)
+                truename
              (abbreviate-file-name (file-truename buffer-file-name))))
       (setq buffer-file-number number)
       (if find-file-visit-truename
@@ -4115,6 +4116,8 @@ those in the first."
       (dolist (f (list file-2 file-1))
         (when (and f
                    (file-readable-p f)
+                   ;; FIXME: Aren't file-regular-p and
+                   ;; file-directory-p mutually exclusive?
                    (file-regular-p f)
                    (not (file-directory-p f)))
           (push f out)))
@@ -6119,7 +6122,7 @@ an auto-save file."
   (interactive "FRecover file: ")
   (setq file (expand-file-name file))
   (if (auto-save-file-name-p (file-name-nondirectory file))
-      (error "%s is an auto-save file" (abbreviate-file-name file)))
+      (user-error "%s is an auto-save file" (abbreviate-file-name file)))
   (let ((file-name (let ((buffer-file-name file))
                     (make-auto-save-file-name))))
     (cond ((and (file-exists-p file)
@@ -6129,8 +6132,8 @@ an auto-save file."
           ((if (file-exists-p file)
               (not (file-newer-than-file-p file-name file))
             (not (file-exists-p file-name)))
-          (error "Auto-save file %s not current"
-                 (abbreviate-file-name file-name)))
+          (user-error "Auto-save file %s not current"
+                       (abbreviate-file-name file-name)))
          ((with-temp-buffer-window
            "*Directory*" nil
            #'(lambda (window _value)
diff --git a/lisp/filesets.el b/lisp/filesets.el
index c1e6ef1..8ccfa57 100644
--- a/lisp/filesets.el
+++ b/lisp/filesets.el
@@ -1559,7 +1559,7 @@ SAVE-FUNCTION takes no argument, but works on the current 
buffer."
 (defun filesets-get-fileset-from-name (name &optional mode)
   "Get fileset definition for NAME."
   (pcase mode
-    ((or `:ingroup `:tree) name)
+    ((or :ingroup :tree) name)
     (_ (assoc name filesets-data))))
 
 
diff --git a/lisp/follow.el b/lisp/follow.el
index e2d3a11..ed7b7d2 100644
--- a/lisp/follow.el
+++ b/lisp/follow.el
@@ -311,6 +311,17 @@ are \" Fw\", or simply \"\"."
           (remove-hook 'find-file-hook 'follow-find-file-hook))
         (set-default symbol value)))
 
+(defcustom follow-hide-ghost-cursors t  ; Maybe this should be nil.
+  "When non-nil, Follow mode attempts to hide the obtrusive cursors
+in the non-selected windows of a window group.
+
+This variable takes effect when `follow-mode' is initialized.
+
+Due to limitations in Emacs, this only operates on the followers
+of the selected window."
+  :type 'boolean
+  :group 'follow)
+
 (defvar follow-cache-command-list
   '(next-line previous-line forward-char backward-char right-char left-char)
   "List of commands that don't require recalculation.
@@ -427,6 +438,8 @@ Keys specific to Follow mode:
 
         (when isearch-lazy-highlight
           (setq-local isearch-lazy-highlight 'all-windows))
+        (when follow-hide-ghost-cursors
+          (setq-local cursor-in-non-selected-windows nil))
 
         (setq window-group-start-function 'follow-window-start)
         (setq window-group-end-function 'follow-window-end)
@@ -456,6 +469,8 @@ Keys specific to Follow mode:
     (kill-local-variable 'window-group-end-function)
     (kill-local-variable 'window-group-start-function)
 
+    (kill-local-variable 'cursor-in-non-selected-windows)
+
     (remove-hook 'ispell-update-post-hook 'follow-post-command-hook t)
     (remove-hook 'replace-update-post-hook 'follow-post-command-hook t)
     (remove-hook 'isearch-update-post-hook 'follow-post-command-hook t)
@@ -1262,6 +1277,10 @@ non-first windows in Follow mode."
 
 ;;; Pre Display Function
 
+(defvar follow-prev-buffer nil
+  "The buffer current at the last call to `follow-adjust-window' or nil.
+follow-mode is not necessarily enabled in this buffer.")
+
 ;; This function is added to `pre-display-function' and is thus called
 ;; before each redisplay operation.  It supersedes (2018-09) the
 ;; former use of the post command hook, and now does the right thing
@@ -1310,6 +1329,24 @@ non-first windows in Follow mode."
 (defun follow-adjust-window (win)
   ;; Adjust the window WIN and its followers.
   (cl-assert (eq (window-buffer win) (current-buffer)))
+
+  ;; Have we moved out of or into a follow-mode window group?
+  ;; If so, attend to the visibility of the cursors.
+  (when (not (eq (current-buffer) follow-prev-buffer))
+    ;; Do we need to switch off cursor handling in the previous buffer?
+    (when (buffer-live-p follow-prev-buffer)
+      (with-current-buffer follow-prev-buffer
+        (when (and follow-mode
+                   (local-variable-p 'cursor-in-non-selected-windows))
+          (setq cursor-in-non-selected-windows
+                (default-value 'cursor-in-non-selected-windows)))))
+    ;; Do we need to switch on cursor handling in the current buffer?
+    (when (and follow-mode
+               (local-variable-p 'cursor-in-non-selected-windows))
+      (setq cursor-in-non-selected-windows nil))
+    (when (buffer-live-p (current-buffer))
+      (setq follow-prev-buffer (current-buffer))))
+
   (when (and follow-mode
              (not (window-minibuffer-p win)))
     (let ((windows (follow-all-followers win)))
@@ -1405,7 +1442,13 @@ non-first windows in Follow mode."
          (unless (eq win (selected-window))
            (let ((p (window-point win)))
              (set-window-start win (window-start win) nil)
-             (set-window-point win p))))
+              (if (nth 2 (pos-visible-in-window-p p win t))
+                  ;; p is in a partially visible line.  We can't leave
+                  ;; window-point there, because C-x o back into WIN
+                  ;; would then fail.
+                  (with-selected-window win
+                    (forward-line)) ; redisplay will recenter it in WIN.
+               (set-window-point win p)))))
 
        (unless visible
          ;; If point may not be visible in the selected window,
diff --git a/lisp/fringe.el b/lisp/fringe.el
index a806b4e..583a0e2 100644
--- a/lisp/fringe.el
+++ b/lisp/fringe.el
@@ -1,4 +1,4 @@
-;;; fringe.el --- fringe setup and control
+;;; fringe.el --- fringe setup and control  -*- lexical-binding:t -*-
 
 ;; Copyright (C) 2002-2018 Free Software Foundation, Inc.
 
@@ -291,6 +291,24 @@ SIDE must be the symbol `left' or `right'."
               0)
            (float (frame-char-width))))
 
+;;;###autoload
+(unless (fboundp 'define-fringe-bitmap)
+  (defun define-fringe-bitmap (_bitmap _bits &optional _height _width _align)
+    "Define fringe bitmap BITMAP from BITS of size HEIGHT x WIDTH.
+BITMAP is a symbol identifying the new fringe bitmap.
+BITS is either a string or a vector of integers.
+HEIGHT is height of bitmap.  If HEIGHT is nil, use length of BITS.
+WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
+Optional fifth arg ALIGN may be one of ‘top’, ‘center’, or ‘bottom’,
+indicating the positioning of the bitmap relative to the rows where it
+is used; the default is to center the bitmap.  Fifth arg may also be a
+list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
+should be repeated.
+If BITMAP already exists, the existing definition is replaced."
+    ;; This is a fallback for non-GUI builds.
+    ;; The real implementation is in src/fringe.c.
+    ))
+
 (provide 'fringe)
 
 ;;; fringe.el ends here
diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el
index 1b0dde9..f28e6db 100644
--- a/lisp/gnus/gnus-art.el
+++ b/lisp/gnus/gnus-art.el
@@ -2243,9 +2243,7 @@ This only works if the article in question is HTML."
                     start end)))))))
 
 (defun gnus-article-treat-fold-newsgroups ()
-  "Unfold folded message headers.
-Only the headers that fit into the current window width will be
-unfolded."
+  "Fold the Newsgroups and Followup-To message headers."
   (interactive)
   (gnus-with-article-headers
     (while (gnus-article-goto-header "newsgroups\\|followup-to")
diff --git a/lisp/gnus/gnus-spec.el b/lisp/gnus/gnus-spec.el
index 379a7f2..4b5f15f 100644
--- a/lisp/gnus/gnus-spec.el
+++ b/lisp/gnus/gnus-spec.el
@@ -271,9 +271,7 @@ Return a list of updated types."
               (insert " ")))
         (insert-char ?  (max (- ,column (current-column)) 0))))))
 
-(defun gnus-correct-length (string)
-  "Return the correct width of STRING."
-  (apply #'+ (mapcar #'char-width string)))
+(define-obsolete-function-alias 'gnus-correct-length 'string-width "27.1")
 
 (defun gnus-correct-substring (string start &optional end)
   (let ((wstart 0)
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index f56b822..f9fae37 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -83,12 +83,12 @@ If an unread article in the group refers to an older, 
already
 read (or just marked as read) article, the old article will not
 normally be displayed in the Summary buffer.  If this variable is
 t, Gnus will attempt to grab the headers to the old articles, and
-thereby build complete threads.  If it has the value `some', all
-old headers will be fetched but only enough headers to connect
+thereby build complete threads.  If the value is the symbol `some',
+all old headers will be fetched but only enough headers to connect
 otherwise loose threads will be displayed.  This variable can
 also be a number.  In that case, no more than that number of old
-headers will be fetched.  If it has the value `invisible', all
-old headers will be fetched, but none will be displayed.
+headers will be fetched.  If the value is the symbol `invisible',
+all old headers will be fetched, but none will be displayed.
 
 The server has to support NOV for any of this to work.
 
@@ -203,9 +203,10 @@ Useful functions to put in this list include:
 
 (defcustom gnus-build-sparse-threads nil
   "If non-nil, fill in the gaps in threads.
-If `some', only fill in the gaps that are needed to tie loose threads
-together.  If `more', fill in all leaf nodes that Gnus can find.  If
-non-nil and non-`some', fill in all gaps that Gnus manages to guess."
+If set to the symbol `some', only fill in the gaps that are
+needed to tie loose threads together.  If the symbol `more', fill
+in all leaf nodes that Gnus can find.  If t (or any other value),
+fill in all gaps that Gnus manages to guess."
   :group 'gnus-thread
   :type '(choice (const :tag "off" nil)
                 (const some)
diff --git a/lisp/gnus/mm-util.el b/lisp/gnus/mm-util.el
index 25b1568..14a232f 100644
--- a/lisp/gnus/mm-util.el
+++ b/lisp/gnus/mm-util.el
@@ -827,7 +827,7 @@ decompressed data.  The buffer's multibyteness must be 
turned off."
                                            (insert-file-contents err-file)
                                            (buffer-string)
                                          (erase-buffer))
-                                        t)
+                                       nil t)
                                       " ")
                            "\n")
                    (setq err-msg
diff --git a/lisp/gnus/nnir.el b/lisp/gnus/nnir.el
index 7e5f56e..ea7257d 100644
--- a/lisp/gnus/nnir.el
+++ b/lisp/gnus/nnir.el
@@ -518,6 +518,26 @@ that it is for notmuch, not Namazu."
   :type '(regexp)
   :group 'nnir)
 
+(defcustom nnir-notmuch-filter-group-names-function
+  #'gnus-group-short-name
+  "Whether and how to use Gnus group names as \"path:\" search terms.
+When nil, the groups being searched in are not used as notmuch
+:path search terms.  It's still possible to use \"path:\" terms
+manually within the search query, however.
+
+When a function, map this function over all the group names.  By
+default this runs them through `gnus-group-short-name', and it is
+recommended to use this transform, at least.  Further
+transforms (for instance, converting \".\" to \"/\") can be
+added like so:
+
+\(add-function :filter-return
+   nnir-notmuch-filter-group-names-function
+   (lambda (g) (replace-regexp-in-string \"\\\\.\" \"/\" g)))"
+  :version "27.1"
+  :type '(choice function
+                nil))
+
 ;;; Developer Extension Variable:
 
 (defvar nnir-engines
@@ -1505,23 +1525,30 @@ Tested with Namazu 2.0.6 on a GNU/Linux system."
                                (> (nnir-artitem-rsv x)
                                   (nnir-artitem-rsv y)))))))))
 
-(defun nnir-run-notmuch (query server &optional _group)
+(defun nnir-run-notmuch (query server &optional groups)
   "Run QUERY against notmuch.
 Returns a vector of (group name, file name) pairs (also vectors,
-actually)."
-
-  ;; (when group
-  ;;   (error "The notmuch backend cannot search specific groups"))
+actually).  If GROUPS is a list of group names, use them to
+construct path: search terms (see the variable
+`nnir-notmuch-filter-group-names-function')."
 
   (save-excursion
-    (let ( (qstring (cdr (assq 'query query)))
-          (groupspec (cdr (assq 'notmuch-group query)))
+    (let* ((qstring (cdr (assq 'query query)))
           (prefix (nnir-read-server-parm 'nnir-notmuch-remove-prefix server))
            artlist
           (article-pattern (if (string-match "\\`nnmaildir:"
                                              (gnus-group-server server))
-                              ":[0-9]+"
-                            "^[0-9]+$"))
+                               ":[0-9]+"
+                             "^[0-9]+$"))
+          (groups (when nnir-notmuch-filter-group-names-function
+                    (mapcar nnir-notmuch-filter-group-names-function
+                            groups)))
+          (pathquery (when groups
+                       (concat "("
+                        (mapconcat (lambda (g)
+                                     (format " path:%s" g))
+                                   groups " or")
+                        ")")))
            artno dirnam filenam)
 
       (when (equal "" qstring)
@@ -1530,10 +1557,14 @@ actually)."
       (set-buffer (get-buffer-create nnir-tmp-buffer))
       (erase-buffer)
 
-      (if groupspec
-          (message "Doing notmuch query %s on %s..." qstring groupspec)
+      (if groups
+          (message "Doing notmuch query %s on %s..."
+                  qstring (mapconcat #'identity groups " "))
         (message "Doing notmuch query %s..." qstring))
 
+      (when groups
+       (setq qstring (concat qstring pathquery)))
+
       (let* ((cp-list `( ,nnir-notmuch-program
                          nil            ; input from /dev/null
                          t              ; output
@@ -1571,10 +1602,7 @@ actually)."
         (when (string-match article-pattern artno)
           (when (not (null dirnam))
 
-           ;; maybe limit results to matching groups.
-           (when (or (not groupspec)
-                     (string-match groupspec dirnam))
-             (nnir-add-result dirnam artno "" prefix server artlist)))))
+           (nnir-add-result dirnam artno "" prefix server artlist))))
 
       (message "Massaging notmuch output...done")
 
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index ec46a47..7979ef3 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -1141,7 +1141,7 @@ current buffer and the selected frame, respectively."
                                    (format
                                      "Describe symbol (default %s): " v-or-f)
                                  "Describe symbol: ")
-                               obarray
+                               #'help--symbol-completion-table
                                (lambda (vv)
                                   (cl-some (lambda (x) (funcall (nth 1 x) vv))
                                            describe-symbol-backends))
diff --git a/lisp/help.el b/lisp/help.el
index 28288e5..ad782f7 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -1326,7 +1326,7 @@ puts the buffer specified by BUFFER-OR-NAME in 
`help-mode' and
 displays a message about how to delete the help window when it's no
 longer needed.  The help window will be selected if
 `help-window-select' is non-nil.
-Most of this  is done by `help-window-setup', which see."
+Most of this is done by `help-window-setup', which see."
   (declare (indent 1) (debug t))
   `(progn
      ;; Make `help-window-point-marker' point nowhere.  The only place
diff --git a/lisp/image-mode.el b/lisp/image-mode.el
index 19fa28d..606c661 100644
--- a/lisp/image-mode.el
+++ b/lisp/image-mode.el
@@ -145,7 +145,7 @@ otherwise it defaults to t, used for times when the buffer 
is not displayed."
   (unless (listp image-mode-winprops-alist)
     (setq image-mode-winprops-alist nil))
   (add-hook 'window-configuration-change-hook
-           'image-mode-reapply-winprops nil t))
+           #'image-mode-reapply-winprops nil t))
 
 ;;; Image scrolling functions
 
@@ -572,8 +572,8 @@ Key bindings:
        ;; Keep track of [vh]scroll when switching buffers
        (image-mode-setup-winprops)
 
-       (add-hook 'change-major-mode-hook 'image-toggle-display-text nil t)
-       (add-hook 'after-revert-hook 'image-after-revert-hook nil t)
+       (add-hook 'change-major-mode-hook #'image-toggle-display-text nil t)
+       (add-hook 'after-revert-hook #'image-after-revert-hook nil t)
        (run-mode-hooks 'image-mode-hook)
        (let ((image (image-get-display-property))
              (msg1 (substitute-command-keys
@@ -692,6 +692,7 @@ on these modes."
 Remove text properties that display the image."
   (let ((inhibit-read-only t)
        (buffer-undo-list t)
+       (create-lockfiles nil) ; avoid changing dir mtime by lock_file
        (modified (buffer-modified-p)))
     (remove-list-of-text-properties (point-min) (point-max)
                                    '(display read-nonsticky ;; intangible
@@ -724,10 +725,14 @@ was inserted."
                            (not (and (boundp 'epa-file-encrypt-to)
                                      (local-variable-p
                                       'epa-file-encrypt-to))))))
-        (file-or-data (if data-p
-                          (string-make-unibyte
-                           (buffer-substring-no-properties (point-min) 
(point-max)))
-                        filename))
+        (file-or-data
+          (if data-p
+             (let ((str
+                    (buffer-substring-no-properties (point-min) (point-max))))
+                (if enable-multibyte-characters
+                    (encode-coding-string str buffer-file-coding-system)
+                  str))
+           filename))
         ;; If we have a `fit-width' or a `fit-height', don't limit
         ;; the size of the image to the window size.
         (edges (and (null image-transform-resize)
@@ -781,8 +786,9 @@ was inserted."
 (defun image--imagemagick-wanted-p (filename)
   (and (fboundp 'imagemagick-types)
        (not (eq imagemagick-types-inhibit t))
-       (not (memq (intern (upcase (file-name-extension filename)) obarray)
-                  imagemagick-types-inhibit))))
+       (not (and (file-name-extension filename)
+                 (memq (intern (upcase (file-name-extension filename)) obarray)
+                       imagemagick-types-inhibit)))))
 
 (defun image-toggle-hex-display ()
   "Toggle between image and hex display."
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 1e785a4..580b3ac 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -304,9 +304,9 @@ are `word-search-regexp' \(`\\[isearch-toggle-word]'), 
`isearch-symbol-regexp'
 
 (defcustom isearch-lazy-highlight t
   "Controls the lazy-highlighting during incremental search.
-When non-nil, all text in the buffer matching the current search
-string is highlighted lazily (see `lazy-highlight-initial-delay'
-and `lazy-highlight-interval').
+When non-nil, all text currently visible on the screen
+matching the current search string is highlighted lazily
+(see `lazy-highlight-initial-delay' and `lazy-highlight-interval').
 
 When multiple windows display the current buffer, the
 highlighting is displayed only on the selected window, unless
@@ -351,6 +351,27 @@ A value of nil means highlight all matches shown on the 
screen."
                 (integer :tag "Some"))
   :group 'lazy-highlight)
 
+(defcustom lazy-highlight-buffer-max-at-a-time 20
+  "Maximum matches to highlight at a time (for `lazy-highlight-buffer').
+Larger values may reduce Isearch's responsiveness to user input;
+smaller values make matches highlight slowly.
+A value of nil means highlight all matches in the buffer."
+  :type '(choice (const :tag "All" nil)
+                (integer :tag "Some"))
+  :group 'lazy-highlight
+  :version "27.1")
+
+(defcustom lazy-highlight-buffer nil
+  "Controls the lazy-highlighting of the full buffer.
+When non-nil, all text in the buffer matching the current search
+string is highlighted lazily (see `lazy-highlight-initial-delay',
+`lazy-highlight-interval' and `lazy-highlight-buffer-max-at-a-time').
+This is useful when `lazy-highlight-cleanup' is customized to nil
+and doesn't remove full-buffer highlighting after a search."
+  :type 'boolean
+  :group 'lazy-highlight
+  :version "27.1")
+
 (defface lazy-highlight
   '((((class color) (min-colors 88) (background light))
      (:background "paleturquoise"))
@@ -1984,11 +2005,14 @@ and reads its face argument using 
`hi-lock-read-face-name'."
 
 
 (defun isearch-delete-char ()
-  "Discard last input item and move point back.
-Last input means the last character or the last isearch command
-that added or deleted characters from the search string,
-moved point, toggled regexp mode or case-sensitivity, etc.
-If no previous match was done, just beep."
+  "Undo last input item during a search.
+
+An input item is the result of a command that pushes a new state
+of isearch (as recorded by the `isearch--state' structure) to
+`isearch-cmds'.  Info node `(emacs)Basic Isearch' explains when
+Emacs records a new input item.
+
+If no input items have been entered yet, just beep."
   (interactive)
   (if (null (cdr isearch-cmds))
       (ding)
@@ -3178,6 +3202,7 @@ since they have special meaning in a regexp."
 (defvar isearch-lazy-highlight-window-group nil)
 (defvar isearch-lazy-highlight-window-start nil)
 (defvar isearch-lazy-highlight-window-end nil)
+(defvar isearch-lazy-highlight-buffer nil)
 (defvar isearch-lazy-highlight-case-fold-search nil)
 (defvar isearch-lazy-highlight-regexp nil)
 (defvar isearch-lazy-highlight-lax-whitespace nil)
@@ -3226,10 +3251,12 @@ by other Emacs features."
                          isearch-lax-whitespace))
                 (not (eq isearch-lazy-highlight-regexp-lax-whitespace
                          isearch-regexp-lax-whitespace))
-                 (not (= (window-group-start)
-                         isearch-lazy-highlight-window-start))
-                 (not (= (window-group-end) ; Window may have been 
split/joined.
-                        isearch-lazy-highlight-window-end))
+                (not (or lazy-highlight-buffer
+                         (= (window-group-start)
+                            isearch-lazy-highlight-window-start)))
+                (not (or lazy-highlight-buffer
+                         (= (window-group-end) ; Window may have been 
split/joined.
+                            isearch-lazy-highlight-window-end)))
                 (not (eq isearch-forward
                          isearch-lazy-highlight-forward))
                 ;; In case we are recovering from an error.
@@ -3247,6 +3274,7 @@ by other Emacs features."
           isearch-lazy-highlight-window-group (selected-window-group)
          isearch-lazy-highlight-window-start (window-group-start)
          isearch-lazy-highlight-window-end   (window-group-end)
+         isearch-lazy-highlight-buffer       lazy-highlight-buffer
          ;; Start lazy-highlighting at the beginning of the found
          ;; match (`isearch-other-end').  If no match, use point.
          ;; One of the next two variables (depending on search direction)
@@ -3264,12 +3292,22 @@ by other Emacs features."
          isearch-lazy-highlight-regexp-lax-whitespace 
isearch-regexp-lax-whitespace
          isearch-lazy-highlight-regexp-function  isearch-regexp-function
          isearch-lazy-highlight-forward      isearch-forward)
+    ;; Extend start/end to match whole string at point (bug#19353)
+    (if isearch-lazy-highlight-forward
+        (setq isearch-lazy-highlight-start
+             (min (+ isearch-lazy-highlight-start
+                     (1- (length isearch-lazy-highlight-last-string)))
+                  (point-max)))
+      (setq isearch-lazy-highlight-end
+           (max (- isearch-lazy-highlight-end
+                   (1- (length isearch-lazy-highlight-last-string)))
+                (point-min))))
     (unless (equal isearch-string "")
       (setq isearch-lazy-highlight-timer
             (run-with-idle-timer lazy-highlight-initial-delay nil
                                  'isearch-lazy-highlight-start)))))
 
-(defun isearch-lazy-highlight-search ()
+(defun isearch-lazy-highlight-search (string bound)
   "Search ahead for the next or previous match, for lazy highlighting.
 Attempt to do the search exactly the way the pending Isearch would."
   (condition-case nil
@@ -3283,24 +3321,10 @@ Attempt to do the search exactly the way the pending 
Isearch would."
            (isearch-forward isearch-lazy-highlight-forward)
            (search-invisible nil)      ; don't match invisible text
            (retry t)
-           (success nil)
-           (bound (if isearch-lazy-highlight-forward
-                      (min (or isearch-lazy-highlight-end-limit (point-max))
-                           (if isearch-lazy-highlight-wrapped
-                               (+ isearch-lazy-highlight-start
-                                  ;; Extend bound to match whole string at 
point
-                                  (1- (length 
isearch-lazy-highlight-last-string)))
-                             (window-group-end)))
-                    (max (or isearch-lazy-highlight-start-limit (point-min))
-                         (if isearch-lazy-highlight-wrapped
-                             (- isearch-lazy-highlight-end
-                                ;; Extend bound to match whole string at point
-                                (1- (length 
isearch-lazy-highlight-last-string)))
-                           (window-group-start))))))
+           (success nil))
        ;; Use a loop like in `isearch-search'.
        (while retry
-         (setq success (isearch-search-string
-                        isearch-lazy-highlight-last-string bound t))
+         (setq success (isearch-search-string string bound t))
          ;; Clear RETRY unless the search predicate says
          ;; to skip this search hit.
          (if (or (not success)
@@ -3312,6 +3336,17 @@ Attempt to do the search exactly the way the pending 
Isearch would."
        success)
     (error nil)))
 
+(defun isearch-lazy-highlight-match (mb me)
+  (let ((ov (make-overlay mb me)))
+    (push ov isearch-lazy-highlight-overlays)
+    ;; 1000 is higher than ediff's 100+,
+    ;; but lower than isearch main overlay's 1001
+    (overlay-put ov 'priority 1000)
+    (overlay-put ov 'face 'lazy-highlight)
+    (unless (or (eq isearch-lazy-highlight 'all-windows)
+                isearch-lazy-highlight-buffer)
+      (overlay-put ov 'window (selected-window)))))
+
 (defun isearch-lazy-highlight-start ()
   "Start a new lazy-highlight updating loop."
   (lazy-highlight-cleanup t) ;remove old overlays
@@ -3321,19 +3356,32 @@ Attempt to do the search exactly the way the pending 
Isearch would."
   "Update highlighting of other matches for current search."
   (let ((max lazy-highlight-max-at-a-time)
         (looping t)
-        nomore)
+        nomore window-start window-end)
     (with-local-quit
       (save-selected-window
        (if (and (window-live-p isearch-lazy-highlight-window)
                 (not (memq (selected-window) 
isearch-lazy-highlight-window-group)))
            (select-window isearch-lazy-highlight-window))
+       (setq window-start (window-group-start))
+       (setq window-end (window-group-end))
        (save-excursion
          (save-match-data
            (goto-char (if isearch-lazy-highlight-forward
                           isearch-lazy-highlight-end
                         isearch-lazy-highlight-start))
            (while looping
-             (let ((found (isearch-lazy-highlight-search)))
+             (let* ((bound (if isearch-lazy-highlight-forward
+                               (min (or isearch-lazy-highlight-end-limit 
(point-max))
+                                    (if isearch-lazy-highlight-wrapped
+                                        isearch-lazy-highlight-start
+                                      window-end))
+                             (max (or isearch-lazy-highlight-start-limit 
(point-min))
+                                  (if isearch-lazy-highlight-wrapped
+                                      isearch-lazy-highlight-end
+                                    window-start))))
+                    (found (isearch-lazy-highlight-search
+                            isearch-lazy-highlight-last-string
+                            bound)))
                (when max
                  (setq max (1- max))
                  (if (<= max 0)
@@ -3345,24 +3393,17 @@ Attempt to do the search exactly the way the pending 
Isearch would."
                          (if isearch-lazy-highlight-forward
                              (if (= mb (if isearch-lazy-highlight-wrapped
                                            isearch-lazy-highlight-start
-                                         (window-group-end)))
+                                         window-end))
                                  (setq found nil)
                                (forward-char 1))
                            (if (= mb (if isearch-lazy-highlight-wrapped
                                          isearch-lazy-highlight-end
-                                       (window-group-start)))
+                                       window-start))
                                (setq found nil)
                              (forward-char -1)))
 
                        ;; non-zero-length match
-                       (let ((ov (make-overlay mb me)))
-                         (push ov isearch-lazy-highlight-overlays)
-                         ;; 1000 is higher than ediff's 100+,
-                         ;; but lower than isearch main overlay's 1001
-                         (overlay-put ov 'priority 1000)
-                         (overlay-put ov 'face 'lazy-highlight)
-                         (unless (eq isearch-lazy-highlight 'all-windows)
-                            (overlay-put ov 'window (selected-window)))))
+                       (isearch-lazy-highlight-match mb me))
                      ;; Remember the current position of point for
                      ;; the next call of `isearch-lazy-highlight-update'
                      ;; when `lazy-highlight-max-at-a-time' is too small.
@@ -3378,17 +3419,82 @@ Attempt to do the search exactly the way the pending 
Isearch would."
                      (setq isearch-lazy-highlight-wrapped t)
                      (if isearch-lazy-highlight-forward
                          (progn
-                           (setq isearch-lazy-highlight-end 
(window-group-start))
+                           (setq isearch-lazy-highlight-end window-start)
                            (goto-char (max (or 
isearch-lazy-highlight-start-limit (point-min))
-                                           (window-group-start))))
-                       (setq isearch-lazy-highlight-start (window-group-end))
+                                           window-start)))
+                       (setq isearch-lazy-highlight-start window-end)
                        (goto-char (min (or isearch-lazy-highlight-end-limit 
(point-max))
-                                       (window-group-end))))))))
-           (unless nomore
+                                       window-end)))))))
+           (if nomore
+               (when isearch-lazy-highlight-buffer
+                 (if isearch-lazy-highlight-forward
+                     (setq isearch-lazy-highlight-end (point-min))
+                   (setq isearch-lazy-highlight-start (point-max)))
+                 (run-at-time lazy-highlight-interval nil
+                              'isearch-lazy-highlight-buffer-update))
              (setq isearch-lazy-highlight-timer
                    (run-at-time lazy-highlight-interval nil
                                 'isearch-lazy-highlight-update)))))))))
 
+(defun isearch-lazy-highlight-buffer-update ()
+  "Update highlighting of other matches in the full buffer."
+  (let ((max lazy-highlight-buffer-max-at-a-time)
+        (looping t)
+        nomore window-start window-end)
+    (with-local-quit
+      (save-selected-window
+       (if (and (window-live-p isearch-lazy-highlight-window)
+                (not (memq (selected-window) 
isearch-lazy-highlight-window-group)))
+           (select-window isearch-lazy-highlight-window))
+       (setq window-start (window-group-start))
+       (setq window-end (window-group-end))
+       (save-excursion
+         (save-match-data
+           (goto-char (if isearch-lazy-highlight-forward
+                          isearch-lazy-highlight-end
+                        isearch-lazy-highlight-start))
+           (while looping
+             (let* ((bound (if isearch-lazy-highlight-forward
+                               (or isearch-lazy-highlight-end-limit 
(point-max))
+                             (or isearch-lazy-highlight-start-limit 
(point-min))))
+                    (found (isearch-lazy-highlight-search
+                            isearch-lazy-highlight-last-string
+                            bound)))
+               (when max
+                 (setq max (1- max))
+                 (if (<= max 0)
+                     (setq looping nil)))
+               (if found
+                   (let ((mb (match-beginning 0))
+                         (me (match-end 0)))
+                     (if (= mb me)     ;zero-length match
+                         (if isearch-lazy-highlight-forward
+                             (if (= mb (point-max))
+                                 (setq found nil)
+                               (forward-char 1))
+                           (if (= mb (point-min))
+                               (setq found nil)
+                             (forward-char -1)))
+                       ;; Already highlighted by isearch-lazy-highlight-update
+                       (unless (and (>= mb window-start) (<= me window-end))
+                         ;; non-zero-length match
+                         (isearch-lazy-highlight-match mb me)))
+                     ;; Remember the current position of point for
+                     ;; the next call of `isearch-lazy-highlight-update'
+                     ;; when `lazy-highlight-buffer-max-at-a-time' is too 
small.
+                     (if isearch-lazy-highlight-forward
+                         (setq isearch-lazy-highlight-end (point))
+                       (setq isearch-lazy-highlight-start (point)))))
+
+               ;; not found or zero-length match at the search bound
+               (if (not found)
+                   (setq looping nil
+                         nomore  t))))
+           (unless nomore
+             (setq isearch-lazy-highlight-timer
+                   (run-at-time lazy-highlight-interval nil
+                                'isearch-lazy-highlight-buffer-update)))))))))
+
 (defun isearch-resume (string regexp word forward message case-fold)
   "Resume an incremental search.
 STRING is the string or regexp searched for.
diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el
index 5ff0898..eda67cd 100644
--- a/lisp/ldefs-boot.el
+++ b/lisp/ldefs-boot.el
@@ -7469,7 +7469,7 @@ You can also switch between context diff and unified diff 
with \\[diff-context->
 or vice versa with \\[diff-unified->context] and you can also reverse the 
direction of
 a diff with \\[diff-reverse-direction].
 
-   \\{diff-mode-map}
+\\{diff-mode-map}
 
 \(fn)" t nil)
 
@@ -13804,6 +13804,8 @@ Interactively, reads the register using 
`register-read-with-preview'.
 ;;;### (autoloads nil "fringe" "fringe.el" (0 0 0 0))
 ;;; Generated autoloads from fringe.el
 
+(unless (fboundp 'define-fringe-bitmap) (defun define-fringe-bitmap (_bitmap 
_bits &optional _height _width _align) "Define fringe bitmap BITMAP from BITS 
of size HEIGHT x WIDTH.\nBITMAP is a symbol identifying the new fringe 
bitmap.\nBITS is either a string or a vector of integers.\nHEIGHT is height of 
bitmap.  If HEIGHT is nil, use length of BITS.\nWIDTH must be an integer 
between 1 and 16, or nil which defaults to 8.\nOptional fifth arg ALIGN may be 
one of ‘top’, ‘center’, or ‘bottom’ [...]
+
 (if (fboundp 'register-definition-prefixes) (register-definition-prefixes 
"fringe" '("fringe-" "set-fringe-")))
 
 ;;;***
@@ -13908,7 +13910,7 @@ detailed description of this mode.
 
 \(fn COMMAND-LINE)" t nil)
 
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes 
"gdb-mi" '("breakpoint-" "def-gdb-" "gdb" "gud-" "nil")))
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes 
"gdb-mi" '("breakpoint" "def-gdb-" "gdb" "gud-" "hollow-right-triangle" "nil")))
 
 ;;;***
 
@@ -23452,6 +23454,12 @@ Many aspects this mode can be customized using
 
 ;;;### (autoloads nil "octave" "progmodes/octave.el" (0 0 0 0))
 ;;; Generated autoloads from progmodes/octave.el
+ (add-to-list 'auto-mode-alist '("\\.m\\'" . octave-maybe-mode))
+
+(autoload 'octave-maybe-mode "octave" "\
+Select `octave-mode' if the current buffer seems to hold Octave code.
+
+\(fn)" nil nil)
 
 (autoload 'octave-mode "octave" "\
 Major mode for editing Octave code.
@@ -24820,6 +24828,16 @@ short description.
 
 (defalias 'package-list-packages 'list-packages)
 
+(autoload 'package-get-version "package" "\
+Return the version number of the package in which this is used.
+Assumes it is used from an Elisp file placed inside the top-level directory
+of an installed ELPA package.
+The return value is a string (or nil in case we can't find it).
+
+\(fn)" nil nil)
+
+(function-put 'package-get-version 'pure 't)
+
 (if (fboundp 'register-definition-prefixes) (register-definition-prefixes 
"package" '("bad-signature" "define-package" "describe-package-1" "package-")))
 
 ;;;***
@@ -25036,7 +25054,8 @@ variable name being but a special case of it).
 (autoload 'pcase-let* "pcase" "\
 Like `let*' but where you can use `pcase' patterns for bindings.
 BODY should be an expression, and BINDINGS should be a list of bindings
-of the form (PAT EXP).
+of the form (PATTERN EXP).
+See `pcase-let' for discussion of how PATTERN is matched.
 
 \(fn BINDINGS &rest BODY)" nil t)
 
@@ -25045,17 +25064,22 @@ of the form (PAT EXP).
 (autoload 'pcase-let "pcase" "\
 Like `let' but where you can use `pcase' patterns for bindings.
 BODY should be a list of expressions, and BINDINGS should be a list of bindings
-of the form (PAT EXP).
-The macro is expanded and optimized under the assumption that those
-patterns *will* match, so a mismatch may go undetected or may cause
-any kind of error.
+of the form (PATTERN EXP).
+The PATTERNs are only used to extract data, so the code does not test
+whether the data does match the corresponding patterns: a mismatch
+may signal an error or may go undetected, binding variables to arbitrary
+values, such as nil.
 
 \(fn BINDINGS &rest BODY)" nil t)
 
 (function-put 'pcase-let 'lisp-indent-function '1)
 
 (autoload 'pcase-dolist "pcase" "\
-Like `dolist' but where the binding can be a `pcase' pattern.
+Superset of `dolist' where the VAR binding can be a `pcase' PATTERN.
+More specifically, this is just a shorthand for the following combination
+of `dolist' and `pcase-let':
+
+    (dolist (x LIST) (pcase-let ((PATTERN x)) BODY...))
 
 \(fn (PATTERN LIST) BODY...)" nil t)
 
@@ -28882,7 +28906,7 @@ CHAR
      `chinese-two-byte'                        (\\cC)
      `greek-two-byte'                  (\\cG)
      `japanese-hiragana-two-byte'      (\\cH)
-     `indian-tow-byte'                 (\\cI)
+     `indian-two-byte'                 (\\cI)
      `japanese-katakana-two-byte'      (\\cK)
      `korean-hangul-two-byte'          (\\cN)
      `cyrillic-two-byte'               (\\cY)
@@ -29063,9 +29087,26 @@ also enable the mode if ARG is omitted or nil, and 
toggle it
 if ARG is `toggle'; disable the mode otherwise.
 
 When Savehist mode is enabled, minibuffer history is saved
-periodically and when exiting Emacs.  When Savehist mode is
-enabled for the first time in an Emacs session, it loads the
-previous minibuffer history from `savehist-file'.
+to `savehist-file' periodically and when exiting Emacs.  When
+Savehist mode is enabled for the first time in an Emacs session,
+it loads the previous minibuffer histories from `savehist-file'.
+The variable `savehist-autosave-interval' controls the
+periodicity of saving minibuffer histories.
+
+If `savehist-save-minibuffer-history' is non-nil (the default),
+all recorded minibuffer histories will be saved.  You can arrange
+for additional history variables to be saved and restored by
+customizing `savehist-additional-variables', which by default is
+an empty list.  For example, to save the history of commands
+invoked via \\[execute-extended-command], add `command-history' to the list in
+`savehist-additional-variables'.
+
+Alternatively, you could customize `savehist-save-minibuffer-history'
+to nil, and add to `savehist-additional-variables' only those
+history variables you want to save.
+
+To ignore some history variables, add their symbols to the list
+in `savehist-ignored-variables'.
 
 This mode should normally be turned on from your Emacs init file.
 Calling it at any other time replaces your current minibuffer
@@ -31015,7 +31056,7 @@ then `snmpv2-mode-hook'.
 
 ;;;### (autoloads nil "soap-client" "net/soap-client.el" (0 0 0 0))
 ;;; Generated autoloads from net/soap-client.el
-(push (purecopy '(soap-client 3 1 4)) package--builtin-versions)
+(push (purecopy '(soap-client 3 1 5)) package--builtin-versions)
 
 (if (fboundp 'register-definition-prefixes) (register-definition-prefixes 
"soap-client" '("soap-")))
 
@@ -34139,10 +34180,7 @@ If DATE lacks timezone information, GMT is assumed.
 
 (defalias 'time-to-seconds 'float-time)
 
-(autoload 'seconds-to-time "time-date" "\
-Convert SECONDS to a time value.
-
-\(fn SECONDS)" nil nil)
+(defalias 'seconds-to-time 'encode-time)
 
 (autoload 'days-to-time "time-date" "\
 Convert DAYS into a time value.
@@ -34711,14 +34749,14 @@ match file names at root of the underlying local file 
system,
 like \"/sys\" or \"/C:\".")
 
 (defun tramp-autoload-file-name-handler (operation &rest args) "\
-Load Tramp file name handler, and perform OPERATION." (if tramp-mode (let 
((default-directory temporary-file-directory)) (load "tramp" 'noerror 
'nomessage)) (tramp-unload-file-name-handlers)) (apply operation args))
+Load Tramp file name handler, and perform OPERATION." 
(tramp-unload-file-name-handlers) (if tramp-mode (let ((default-directory 
temporary-file-directory)) (load "tramp" 'noerror 'nomessage))) (apply 
operation args))
 
 (defun tramp-register-autoload-file-name-handlers nil "\
 Add Tramp file name handlers to `file-name-handler-alist' during autoload." 
(add-to-list 'file-name-handler-alist (cons tramp-autoload-file-name-regexp 
'tramp-autoload-file-name-handler)) (put 'tramp-autoload-file-name-handler 
'safe-magic t))
  (tramp-register-autoload-file-name-handlers)
 
 (defun tramp-unload-file-name-handlers nil "\
-Unload Tramp file name handlers from `file-name-handler-alist'." (dolist (fnh 
'(tramp-file-name-handler tramp-completion-file-name-handler 
tramp-archive-file-name-handler tramp-autoload-file-name-handler)) (let ((a1 
(rassq fnh file-name-handler-alist))) (setq file-name-handler-alist (delq a1 
file-name-handler-alist)))))
+Unload Tramp file name handlers from `file-name-handler-alist'." (dolist (fnh 
file-name-handler-alist) (when (and (symbolp (cdr fnh)) (string-prefix-p 
"tramp-" (symbol-name (cdr fnh)))) (setq file-name-handler-alist (delq fnh 
file-name-handler-alist)))))
 
 (defvar tramp-completion-mode nil "\
 If non-nil, external packages signal that they are in file name completion.")
@@ -34757,8 +34795,10 @@ It must be supported by libarchive(3).")
 (defmacro tramp-archive-autoload-file-name-regexp nil "\
 Regular expression matching archive file names." `(concat "\\`" "\\(" ".+" 
"\\." (regexp-opt tramp-archive-suffixes) "\\(?:" "\\." (regexp-opt 
tramp-archive-compression-suffixes) "\\)*" "\\)" "\\(" "/" ".*" "\\)" "\\'"))
 
+(defalias 'tramp-archive-autoload-file-name-handler 
'tramp-autoload-file-name-handler)
+
 (defun tramp-register-archive-file-name-handler nil "\
-Add archive file name handler to `file-name-handler-alist'." (when 
tramp-archive-enabled (add-to-list 'file-name-handler-alist (cons 
(tramp-archive-autoload-file-name-regexp) 'tramp-autoload-file-name-handler)) 
(put 'tramp-archive-file-name-handler 'safe-magic t)))
+Add archive file name handler to `file-name-handler-alist'." (when 
tramp-archive-enabled (add-to-list 'file-name-handler-alist (cons 
(tramp-archive-autoload-file-name-regexp) 
'tramp-archive-autoload-file-name-handler)) (put 
'tramp-archive-autoload-file-name-handler 'safe-magic t)))
 
 (add-hook 'after-init-hook 'tramp-register-archive-file-name-handler)
 
@@ -36290,6 +36330,7 @@ If NAME is empty, it refers to the latest revisions of 
the current branch.
 If locking is used for the files in DIR, then there must not be any
 locked files at or below DIR (but if NAME is empty, locked files are
 allowed and simply skipped).
+This function runs the hook `vc-retrieve-tag-hook' when finished.
 
 \(fn DIR NAME)" t nil)
 
diff --git a/lisp/mail/rmailsum.el b/lisp/mail/rmailsum.el
index 10345b6..f8adf77 100644
--- a/lisp/mail/rmailsum.el
+++ b/lisp/mail/rmailsum.el
@@ -1694,7 +1694,7 @@ Deleted messages are skipped and don't count.
 When called from Lisp code, N may be omitted and defaults to 1.
 
 This command always outputs the complete message header,
-even the header display is currently pruned."
+even if the header display is currently pruned."
   (interactive
    (progn (require 'rmailout)
          (list (rmail-output-read-file-name)
diff --git a/lisp/mail/smtpmail.el b/lisp/mail/smtpmail.el
index 8bc3cc7..8a1e86b 100644
--- a/lisp/mail/smtpmail.el
+++ b/lisp/mail/smtpmail.el
@@ -150,7 +150,8 @@ and sent with `smtpmail-send-queued-mail'."
   :group 'smtpmail)
 
 (defcustom smtpmail-queue-dir "~/Mail/queued-mail/"
-  "Directory where `smtpmail.el' stores queued mail."
+  "Directory where `smtpmail.el' stores queued mail.
+This directory should not be writable by other users."
   :type 'directory
   :group 'smtpmail)
 
@@ -360,9 +361,7 @@ for `smtpmail-try-auth-method'.")
                     smtpmail-queue-dir))
                   (file-data (convert-standard-filename file-data))
                   (file-elisp (concat file-data ".el"))
-                  (buffer-data (create-file-buffer file-data))
-                  (buffer-elisp (create-file-buffer file-elisp))
-                  (buffer-scratch "*queue-mail*"))
+                  (buffer-data (create-file-buffer file-data)))
              (unless (file-exists-p smtpmail-queue-dir)
                (make-directory smtpmail-queue-dir t))
              (with-current-buffer buffer-data
@@ -377,22 +376,16 @@ for `smtpmail-try-auth-method'.")
                 nil t)
                (insert-buffer-substring tembuf)
                (write-file file-data)
-               (set-buffer buffer-elisp)
-               (erase-buffer)
-               (insert (concat
-                        "(setq smtpmail-recipient-address-list '"
+                (write-region
+                 (concat "(setq smtpmail-recipient-address-list '"
                         (prin1-to-string smtpmail-recipient-address-list)
-                        ")\n"))
-               (write-file file-elisp)
-               (set-buffer (generate-new-buffer buffer-scratch))
-               (insert (concat file-data "\n"))
-               (append-to-file (point-min)
-                               (point-max)
-                                (expand-file-name smtpmail-queue-index-file
-                                                  smtpmail-queue-dir)))
-             (kill-buffer buffer-scratch)
-             (kill-buffer buffer-data)
-             (kill-buffer buffer-elisp))))
+                        ")\n")
+                 nil file-elisp nil 'silent)
+               (write-region (concat file-data "\n") nil
+                              (expand-file-name smtpmail-queue-index-file
+                                                smtpmail-queue-dir)
+                              t 'silent))
+             (kill-buffer buffer-data))))
       (kill-buffer tembuf)
       (if (bufferp errbuf)
          (kill-buffer errbuf)))))
@@ -404,21 +397,35 @@ for `smtpmail-try-auth-method'.")
   (with-temp-buffer
     ;; Get index, get first mail, send it, update index, get second
     ;; mail, send it, etc...
-    (let ((file-msg "")
+    (let (file-data file-elisp
           (qfile (expand-file-name smtpmail-queue-index-file
                                    smtpmail-queue-dir))
          result)
       (insert-file-contents qfile)
       (goto-char (point-min))
       (while (not (eobp))
-       (setq file-msg (buffer-substring (point) (line-end-position)))
-       (load file-msg)
+       (setq file-data (buffer-substring (point) (line-end-position)))
+       (setq file-elisp (concat file-data ".el"))
+        ;; FIXME: Avoid `load' which can execute arbitrary code and is hence
+        ;; a source of security holes.  Better read the file and extract the
+        ;; data "by hand".
+       ;;(load file-elisp)
+        (with-temp-buffer
+          (insert-file-contents file-elisp)
+          (goto-char (point-min))
+          (pcase (read (current-buffer))
+            (`(setq smtpmail-recipient-address-list ',v)
+             (skip-chars-forward " \n\t")
+             (unless (eobp) (message "Ignoring trailing text in %S"
+                                     file-elisp))
+             (setq smtpmail-recipient-address-list v))
+            (sexp (error "Unexpected code in %S: %S" file-elisp sexp))))
        ;; Insert the message literally: it is already encoded as per
        ;; the MIME headers, and code conversions might guess the
        ;; encoding wrongly.
        (with-temp-buffer
          (let ((coding-system-for-read 'no-conversion))
-           (insert-file-contents file-msg))
+           (insert-file-contents file-data))
           (let ((smtpmail-mail-address
                  (or (and mail-specify-envelope-from (mail-envelope-from))
                      user-mail-address)))
@@ -428,8 +435,8 @@ for `smtpmail-try-auth-method'.")
                                    (current-buffer)))
                  (error "Sending failed: %s" result))
               (error "Sending failed; no recipients"))))
-       (delete-file file-msg)
-       (delete-file (concat file-msg ".el"))
+       (delete-file file-data)
+       (delete-file file-elisp)
        (delete-region (point-at-bol) (point-at-bol 2)))
       (write-region (point-min) (point-max) qfile))))
 
diff --git a/lisp/mouse.el b/lisp/mouse.el
index cb63ca5..ca61e36 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -29,6 +29,8 @@
 
 ;;; Code:
 
+(eval-when-compile (require 'rect))
+
 ;;; Utility functions.
 
 ;; Indent track-mouse like progn.
@@ -169,7 +171,10 @@ items `Turn Off' and `Help'."
                 (mouse-menu-non-singleton menu)
               (if (fboundp mm-fun)      ; bug#20201
                   `(keymap
-                    ,indicator
+                    ,(format "%s - %s" indicator
+                            (capitalize
+                             (replace-regexp-in-string
+                              "-" " " (format "%S" minor-mode))))
                     (turn-off menu-item "Turn off minor mode" ,mm-fun)
                     (help menu-item "Help for minor mode"
                           (lambda () (interactive)
@@ -1606,8 +1611,8 @@ if `mouse-drag-copy-region' is non-nil)"
       (if mouse-drag-copy-region
           ;; Region already saved in the previous click;
           ;; don't make a duplicate entry, just delete.
-          (delete-region (mark t) (point))
-        (kill-region (mark t) (point)))
+          (funcall region-extract-function 'delete-only)
+        (kill-region (mark t) (point) 'region))
       (setq mouse-selection-click-count 0)
       (setq mouse-save-then-kill-posn nil))
 
@@ -1632,7 +1637,7 @@ if `mouse-drag-copy-region' is non-nil)"
        (mouse-set-region-1)
         (when mouse-drag-copy-region
           ;; Region already copied to kill-ring once, so replace.
-          (kill-new (filter-buffer-substring (mark t) (point)) t))
+          (kill-new (funcall region-extract-function nil) t))
        ;; Arrange for a repeated mouse-3 to kill the region.
        (setq mouse-save-then-kill-posn click-pt)))
 
@@ -2411,7 +2416,13 @@ is copied instead of being cut."
          (buffer (current-buffer))
          (window (selected-window))
          (text-from-read-only buffer-read-only)
-         (mouse-drag-and-drop-overlay (make-overlay start end))
+         ;; Use multiple overlays to cover cases where the region has more
+         ;; than one boundary.
+         (mouse-drag-and-drop-overlays (mapcar (lambda (bounds)
+                                                 (make-overlay (car bounds)
+                                                               (cdr bounds)))
+                                               (region-bounds)))
+         (region-noncontiguous (region-noncontiguous-p))
          point-to-paste
          point-to-paste-read-only
          window-to-paste
@@ -2455,7 +2466,7 @@ is copied instead of being cut."
           ;; Obtain the dragged text in region.  When the loop was
           ;; skipped, value-selection remains nil.
           (unless value-selection
-            (setq value-selection (buffer-substring start end))
+            (setq value-selection (funcall region-extract-function nil))
             (when mouse-drag-and-drop-region-show-tooltip
               (let ((text-size mouse-drag-and-drop-region-show-tooltip))
                 (setq text-tooltip
@@ -2468,12 +2479,14 @@ is copied instead of being cut."
                         value-selection))))
 
             ;; Check if selected text is read-only.
-            (setq text-from-read-only (or text-from-read-only
-                                          (get-text-property start 'read-only)
-                                          (not (equal
-                                                
(next-single-char-property-change
-                                                 start 'read-only nil end)
-                                                end)))))
+            (setq text-from-read-only
+                  (or text-from-read-only
+                      (catch 'loop
+                        (dolist (bound (region-bounds))
+                          (when (text-property-not-all
+                                 (car bound) (cdr bound) 'read-only nil)
+                            (throw 'loop t)))))))
+
           (setq window-to-paste (posn-window (event-end event)))
           (setq point-to-paste (posn-point (event-end event)))
           ;; Set nil when target buffer is minibuffer.
@@ -2499,13 +2512,34 @@ is copied instead of being cut."
             ;; the original region.  When modifier is pressed, the
             ;; text will be inserted to inside of the original
             ;; region.
+            ;;
+            ;; If the region is rectangular, check if the newly inserted
+            ;; rectangular text would intersect the already selected
+            ;; region. If it would, then set "drag-but-negligible" to t.
+            ;; As a special case, allow dragging the region freely anywhere
+            ;; to the left, as this will never trigger its contents to be
+            ;; inserted into the overlays tracking it.
             (setq drag-but-negligible
-                  (and (eq (overlay-buffer mouse-drag-and-drop-overlay)
+                  (and (eq (overlay-buffer (car mouse-drag-and-drop-overlays))
                            buffer-to-paste)
-                       (<= (overlay-start mouse-drag-and-drop-overlay)
-                          point-to-paste)
-                       (<= point-to-paste
-                          (overlay-end mouse-drag-and-drop-overlay)))))
+                       (if region-noncontiguous
+                           (let ((dimensions (rectangle-dimensions start end))
+                                 (start-coordinates
+                                  (rectangle-position-as-coordinates start))
+                                 (point-to-paste-coordinates
+                                  (rectangle-position-as-coordinates
+                                   point-to-paste)))
+                             (and (rectangle-intersect-p
+                                   start-coordinates dimensions
+                                   point-to-paste-coordinates dimensions)
+                                  (not (< (car point-to-paste-coordinates)
+                                           (car start-coordinates)))))
+                         (and (<= (overlay-start
+                                   (car mouse-drag-and-drop-overlays))
+                                  point-to-paste)
+                              (<= point-to-paste
+                                  (overlay-end
+                                   (car mouse-drag-and-drop-overlays))))))))
 
           ;; Show a tooltip.
           (if mouse-drag-and-drop-region-show-tooltip
@@ -2524,8 +2558,9 @@ is copied instead of being cut."
                                (t
                                 'bar)))
             (when cursor-in-text-area
-              (overlay-put mouse-drag-and-drop-overlay
-                           'face 'mouse-drag-and-drop-region)
+              (dolist (overlay mouse-drag-and-drop-overlays)
+                (overlay-put overlay
+                           'face 'mouse-drag-and-drop-region))
               (deactivate-mark)     ; Maintain region in other window.
               (mouse-set-point event)))))
 
@@ -2581,7 +2616,9 @@ is copied instead of being cut."
           (select-window window)
           (goto-char point)
           (setq deactivate-mark nil)
-          (activate-mark))
+          (activate-mark)
+          (when region-noncontiguous
+            (rectangle-mark-mode)))
          ;; Modify buffers.
          (t
           ;; * DESTINATION BUFFER::
@@ -2590,11 +2627,14 @@ is copied instead of being cut."
           (setq window-exempt window-to-paste)
           (goto-char point-to-paste)
           (push-mark)
-          (insert value-selection)
+          (insert-for-yank value-selection)
+
           ;; On success, set the text as region on destination buffer.
           (when (not (equal (mark) (point)))
             (setq deactivate-mark nil)
-            (activate-mark))
+            (activate-mark)
+            (when region-noncontiguous
+              (rectangle-mark-mode)))
 
           ;; * SOURCE BUFFER::
           ;; Set back the original text as region or delete the original
@@ -2604,8 +2644,9 @@ is copied instead of being cut."
               ;; remove the original text.
               (when no-modifier-on-drop
                 (let (deactivate-mark)
-                  (delete-region (overlay-start mouse-drag-and-drop-overlay)
-                                 (overlay-end mouse-drag-and-drop-overlay))))
+                  (dolist (overlay mouse-drag-and-drop-overlays)
+                    (delete-region (overlay-start overlay)
+                                   (overlay-end overlay)))))
             ;; When source buffer and destination buffer are different,
             ;; keep (set back the original text as region) or remove the
             ;; original text.
@@ -2615,15 +2656,17 @@ is copied instead of being cut."
             (if mouse-drag-and-drop-region-cut-when-buffers-differ
                 ;; Remove the dragged text from source buffer like
                 ;; operation `cut'.
-                (delete-region (overlay-start mouse-drag-and-drop-overlay)
-                               (overlay-end mouse-drag-and-drop-overlay))
+                (dolist (overlay mouse-drag-and-drop-overlays)
+                    (delete-region (overlay-start overlay)
+                                   (overlay-end overlay)))
               ;; Set back the dragged text as region on source buffer
               ;; like operation `copy'.
               (activate-mark))
             (select-window window-to-paste))))))
 
     ;; Clean up.
-    (delete-overlay mouse-drag-and-drop-overlay)
+    (dolist (overlay mouse-drag-and-drop-overlays)
+      (delete-overlay overlay))
 
     ;; Restore old states but for the window where the drop
     ;; occurred. Restore cursor types for all windows.
diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el
index fe9c71a..0c72e47 100644
--- a/lisp/net/rcirc.el
+++ b/lisp/net/rcirc.el
@@ -168,6 +168,14 @@ underneath each nick."
                 (string :tag "Prefix text"))
   :group 'rcirc)
 
+(defcustom rcirc-url-max-length nil
+  "Maximum number of characters in displayed URLs.
+If nil, no maximum is applied."
+  :version "27.1"
+  :type '(choice (const :tag "No maximum" nil)
+                 (integer :tag "Number of characters"))
+  :group 'rcirc)
+
 (defvar rcirc-ignore-buffer-activity-flag nil
   "If non-nil, ignore activity in this buffer.")
 (make-variable-buffer-local 'rcirc-ignore-buffer-activity-flag)
@@ -751,12 +759,12 @@ Function is called with PROCESS, COMMAND, SENDER, ARGS 
and LINE.")
   (with-rcirc-process-buffer process
     (setq rcirc-last-server-message-time (current-time))
     (setq rcirc-process-output (concat rcirc-process-output output))
-    (when (= (aref rcirc-process-output
-                   (1- (length rcirc-process-output))) ?\n)
-      (mapc (lambda (line)
-              (rcirc-process-server-response process line))
-            (split-string rcirc-process-output "[\n\r]" t))
-      (setq rcirc-process-output nil))))
+    (when (= ?\n (aref rcirc-process-output
+                       (1- (length rcirc-process-output))))
+      (let ((lines (split-string rcirc-process-output "[\n\r]" t)))
+        (setq rcirc-process-output nil)
+        (dolist (line lines)
+          (rcirc-process-server-response process line))))))
 
 (defun rcirc-reschedule-timeout (process)
   (with-rcirc-process-buffer process
@@ -2485,24 +2493,26 @@ If ARG is given, opens the URL in a new browser window."
        (rcirc-record-activity (current-buffer) 'nick)))))
 
 (defun rcirc-markup-urls (_sender _response)
-  (while (and rcirc-url-regexp ;; nil means disable URL catching
+  (while (and rcirc-url-regexp ; nil means disable URL catching.
               (re-search-forward rcirc-url-regexp nil t))
     (let* ((start (match-beginning 0))
-           (end (match-end 0))
-           (url (match-string-no-properties 0))
-           (link-text (buffer-substring-no-properties start end)))
+           (url   (buffer-substring-no-properties start (point))))
+      (when rcirc-url-max-length
+        ;; Replace match with truncated URL.
+        (delete-region start (point))
+        (insert (url-truncate-url-for-viewing url rcirc-url-max-length)))
       ;; Add a button for the URL.  Note that we use `make-text-button',
       ;; rather than `make-button', as text-buttons are much faster in
       ;; large buffers.
-      (make-text-button start end
+      (make-text-button start (point)
                        'face 'rcirc-url
                        'follow-link t
                        'rcirc-url url
                        'action (lambda (button)
                                  (browse-url (button-get button 'rcirc-url))))
-      ;; record the url if it is not already the latest stored url
-      (when (not (string= link-text (caar rcirc-urls)))
-        (push (cons link-text start) rcirc-urls)))))
+      ;; Record the URL if it is not already the latest stored URL.
+      (unless (string= url (caar rcirc-urls))
+        (push (cons url start) rcirc-urls)))))
 
 (defun rcirc-markup-keywords (sender response)
   (when (and (string= response "PRIVMSG")
diff --git a/lisp/net/sieve-mode.el b/lisp/net/sieve-mode.el
index 34a4cb6..b9f424f 100644
--- a/lisp/net/sieve-mode.el
+++ b/lisp/net/sieve-mode.el
@@ -100,23 +100,20 @@
 
 (defconst sieve-font-lock-keywords
   (eval-when-compile
-    (list
-     ;; control commands
-     (cons (regexp-opt '("require" "if" "else" "elsif" "stop")
-                       'words)
-          'sieve-control-commands)
-     ;; action commands
-     (cons (regexp-opt '("fileinto" "redirect" "reject" "keep" "discard")
-                       'words)
-          'sieve-action-commands)
-     ;; test commands
-     (cons (regexp-opt '("address" "allof" "anyof" "exists" "false"
-                        "true" "header" "not" "size" "envelope"
-                         "body")
-                       'words)
-          'sieve-test-commands)
-     (cons "\\Sw+:\\sw+"
-          'sieve-tagged-arguments))))
+    `(
+      ;; control commands
+      (,(regexp-opt '("require" "if" "else" "elsif" "stop") 'words)
+       . 'sieve-control-commands)
+      ;; action commands
+      (,(regexp-opt '("fileinto" "redirect" "reject" "keep" "discard") 'words)
+       . 'sieve-action-commands)
+      ;; test commands
+      (,(regexp-opt '("address" "allof" "anyof" "exists" "false"
+                     "true" "header" "not" "size" "envelope"
+                      "body")
+                    'words)
+       . 'sieve-test-commands)
+      ("\\Sw+:\\sw+" . 'sieve-tagged-arguments))))
 
 ;; Syntax table
 
diff --git a/lisp/net/sieve.el b/lisp/net/sieve.el
index 1f80ccc..ef7bb5c 100644
--- a/lisp/net/sieve.el
+++ b/lisp/net/sieve.el
@@ -345,11 +345,14 @@ Used to bracket operations which move point in the 
sieve-buffer."
 ;;;###autoload
 (defun sieve-upload (&optional name)
   (interactive)
-  (when (or (get-buffer sieve-buffer) (call-interactively 'sieve-manage))
-    (let ((script (buffer-string)) err)
+  (when (or (get-buffer sieve-buffer)
+            (save-current-buffer (call-interactively 'sieve-manage)))
+    (let ((script (buffer-string))
+          (script-name (file-name-sans-extension (buffer-name)))
+          err)
       (with-current-buffer (get-buffer sieve-buffer)
        (setq err (sieve-manage-putscript
-                   (or name sieve-buffer-script-name (buffer-name))
+                   (or name sieve-buffer-script-name script-name)
                    script sieve-manage-buffer))
        (if (sieve-manage-ok-p err)
            (message (substitute-command-keys
diff --git a/lisp/net/soap-client.el b/lisp/net/soap-client.el
index f5de05d..7c40966 100644
--- a/lisp/net/soap-client.el
+++ b/lisp/net/soap-client.el
@@ -5,7 +5,7 @@
 ;; Author: Alexandru Harsanyi <address@hidden>
 ;; Author: Thomas Fitzsimmons <address@hidden>
 ;; Created: December, 2009
-;; Version: 3.1.4
+;; Version: 3.1.5
 ;; Keywords: soap, web-services, comm, hypermedia
 ;; Package: soap-client
 ;; Homepage: https://github.com/alex-hhh/emacs-soap-client
@@ -2337,6 +2337,14 @@ traverse an element tree."
 (defun soap-parse-server-response ()
   "Error-check and parse the XML contents of the current buffer."
   (let ((mime-part (mm-dissect-buffer t t)))
+    (when (and
+           (equal (mm-handle-media-type mime-part) "multipart/related")
+           (equal (get-text-property 0 'type (mm-handle-media-type mime-part))
+                  "text/xml"))
+      (setq mime-part
+            (mm-make-handle
+             (get-text-property 0 'buffer (mm-handle-media-type mime-part))
+             `(,(get-text-property 0 'type (mm-handle-media-type 
mime-part))))))
     (unless mime-part
       (error "Failed to decode response from server"))
     (unless (equal (car (mm-handle-type mime-part)) "text/xml")
diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el
index 22d3431..b3a0f74 100644
--- a/lisp/net/tramp-compat.el
+++ b/lisp/net/tramp-compat.el
@@ -29,6 +29,11 @@
 
 ;;; Code:
 
+;; In Emacs 24 and 25, `tramp-unload-file-name-handlers' is not
+;; autoloaded.  So we declare it here in order to avoid recursive
+;; load.  This will be overwritten in tramp.el.
+(defun tramp-unload-file-name-handlers ())
+
 (require 'auth-source)
 (require 'advice)
 (require 'cl-lib)
@@ -289,4 +294,7 @@ A nil value for either argument stands for the current 
time."
 
 ;;; TODO:
 
+;; * When we get rid of Emacs 24, replace "(mapconcat 'identity" by
+;;   "(string-join".
+
 ;;; tramp-compat.el ends here
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index e86971b..db9d9e1 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -4478,7 +4478,8 @@ means discard it)."
     (if (stringp output) (concat " >" output) ""))))
 
 (defconst tramp-inline-compress-commands
-  '(("gzip" "gzip -d")
+  '(;; Suppress warnings about obsolete environment variable GZIP.
+    ("env GZIP= gzip" "env GZIP= gzip -d")
     ("bzip2" "bzip2 -d")
     ("xz" "xz -d")
     ("compress" "compress -d"))
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 755ca21..4c23392 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -1267,7 +1267,7 @@ entry does not exist, return nil."
 (defun tramp-find-method (method user host)
   "Return the right method string to use.
 This is METHOD, if non-nil. Otherwise, do a lookup in
-`tramp-default-method-alist'."
+`tramp-default-method-alist' and `tramp-default-method'."
   (when (and method
             (or (string-equal method "")
                 (string-equal method tramp-default-method-marker)))
@@ -1292,7 +1292,7 @@ This is METHOD, if non-nil. Otherwise, do a lookup in
 (defun tramp-find-user (method user host)
   "Return the right user string to use.
 This is USER, if non-nil. Otherwise, do a lookup in
-`tramp-default-user-alist'."
+`tramp-default-user-alist' and `tramp-default-user'."
   (let ((result
         (or user
             (let ((choices tramp-default-user-alist)
@@ -1312,18 +1312,24 @@ This is USER, if non-nil. Otherwise, do a lookup in
 
 (defun tramp-find-host (method user host)
   "Return the right host string to use.
-This is HOST, if non-nil. Otherwise, it is `tramp-default-host'."
-  (or (and (> (length host) 0) host)
-      (let ((choices tramp-default-host-alist)
-           lhost item)
-       (while choices
-         (setq item (pop choices))
-         (when (and (string-match (or (nth 0 item) "") (or method ""))
-                    (string-match (or (nth 1 item) "") (or user "")))
-           (setq lhost (nth 2 item))
-           (setq choices nil)))
-       lhost)
-      tramp-default-host))
+This is HOST, if non-nil. Otherwise, do a lookup in
+`tramp-default-host-alist' and `tramp-default-host'."
+  (let ((result
+        (or (and (> (length host) 0) host)
+            (let ((choices tramp-default-host-alist)
+                  lhost item)
+              (while choices
+                (setq item (pop choices))
+                (when (and (string-match (or (nth 0 item) "") (or method ""))
+                           (string-match (or (nth 1 item) "") (or user "")))
+                  (setq lhost (nth 2 item))
+                  (setq choices nil)))
+              lhost)
+            tramp-default-host)))
+    ;; We must mark, whether a default value has been used.
+    (if (or (> (length host) 0) (null result))
+       result
+      (propertize result 'tramp-default t))))
 
 (defun tramp-dissect-file-name (name &optional nodefault)
   "Return a `tramp-file-name' structure of NAME, a remote file name.
@@ -1343,7 +1349,7 @@ default values are used."
            (host      (match-string (nth 3 tramp-file-name-structure) name))
            (localname (match-string (nth 4 tramp-file-name-structure) name))
            (hop       (match-string (nth 5 tramp-file-name-structure) name))
-           domain port)
+           domain port v)
        (when user
          (when (string-match tramp-user-with-domain-regexp user)
            (setq domain (match-string 2 user)
@@ -1359,14 +1365,34 @@ default values are used."
            (setq host (replace-match "" nil t host))))
 
        (unless nodefault
-         (setq method (tramp-find-method method user host)
-               user (tramp-find-user method user host)
-               host (tramp-find-host method user host)))
+         (when hop
+           (setq v (tramp-dissect-hop-name hop)
+                 hop (and hop (tramp-make-tramp-hop-name v))))
+         (let ((tramp-default-host
+                (or (and v (not (string-match "%h" (tramp-file-name-host v)))
+                         (tramp-file-name-host v))
+                    tramp-default-host)))
+           (setq method (tramp-find-method method user host)
+                 user (tramp-find-user method user host)
+                 host (tramp-find-host method user host)
+                 hop
+                 (and hop
+                      (format-spec hop (format-spec-make ?h host ?u user))))))
 
        (make-tramp-file-name
         :method method :user user :domain domain :host host :port port
         :localname localname :hop hop)))))
 
+(defun tramp-dissect-hop-name (name &optional nodefault)
+  "Return a `tramp-file-name' structure of `hop' part of NAME.
+See `tramp-dissect-file-name' for details."
+  (tramp-dissect-file-name
+   (concat
+    tramp-prefix-format
+    (replace-regexp-in-string
+     (concat tramp-postfix-hop-regexp "$") tramp-postfix-host-format name))
+   nodefault))
+
 (defun tramp-buffer-name (vec)
   "A name for the connection buffer VEC."
   (let ((method (tramp-file-name-method vec))
@@ -1413,7 +1439,9 @@ the form (METHOD USER DOMAIN HOST PORT LOCALNAME 
&optional HOP)."
              localname (nth 5 args)
              hop (nth 6 args))))
 
-    (when (zerop (length method))
+    ;; Unless `tramp-syntax' is `simplified', we need a method.
+    (when (and (not (zerop (length tramp-postfix-method-format)))
+              (zerop (length method)))
       (signal 'wrong-type-argument (list 'stringp method)))
     (concat tramp-prefix-format hop
            (unless (zerop (length tramp-postfix-method-format))
@@ -1433,6 +1461,14 @@ the form (METHOD USER DOMAIN HOST PORT LOCALNAME 
&optional HOP)."
            tramp-postfix-host-format
            localname)))
 
+(defun tramp-make-tramp-hop-name (vec)
+  "Construct a Tramp hop name from VEC."
+  (replace-regexp-in-string
+   tramp-prefix-regexp ""
+   (replace-regexp-in-string
+    (concat tramp-postfix-host-regexp "$") tramp-postfix-hop-format
+    (tramp-make-tramp-file-name vec 'noloc))))
+
 (defun tramp-completion-make-tramp-file-name (method user host localname)
   "Construct a Tramp file name from METHOD, USER, HOST and LOCALNAME.
 It must not be a complete Tramp file name, but as long as there are
@@ -1556,9 +1592,8 @@ The outline level is equal to the verbosity of the Tramp 
message."
        (outline-mode))
       (set (make-local-variable 'outline-level) 'tramp-debug-outline-level)
       (set (make-local-variable 'font-lock-keywords)
-          `(t
-            (eval ,tramp-debug-font-lock-keywords)
-            ,(eval tramp-debug-font-lock-keywords)))
+          `(t (eval ,tramp-debug-font-lock-keywords)
+              ,(eval tramp-debug-font-lock-keywords)))
       ;; Do not edit the debug buffer.
       (set-keymap-parent (current-local-map) special-mode-map))
     (current-buffer)))
@@ -1963,6 +1998,8 @@ For definition of that list see 
`tramp-set-completion-function'."
   (append
    `(;; Default settings are taken into account.
      (tramp-parse-default-user-host ,method)
+     ;; Hits from auth-sources.
+     (tramp-parse-auth-sources ,method)
      ;; Hosts visited once shall be remembered.
      (tramp-parse-connection-properties ,method))
    ;; The method related defaults.
@@ -2297,7 +2334,7 @@ If Emacs is compiled --with-threads, the body is 
protected by a mutex."
                        (when (autoloadp sf)
                          (let ((default-directory
                                  (tramp-compat-temporary-file-directory))
-                               file-name-handler-alist)
+                               file-name-handler-alist)
                            (load (cadr sf) 'noerror 'nomessage)))
                        ;; (tramp-message
                        ;;  v 4 "Running `%s'..." (cons operation args))
@@ -2793,6 +2830,23 @@ This function is added always in 
`tramp-get-completion-function'
 for all methods.  Resulting data are derived from default settings."
   `((,(tramp-find-user method nil nil) ,(tramp-find-host method nil nil))))
 
+(defcustom tramp-completion-use-auth-sources auth-source-do-cache
+  "Whether to use `auth-source-search' for completion of user and host names.
+This could be disturbing, if it requires a password / passphrase,
+as for \"~/.authinfo.gpg\"."
+  :group 'tramp
+  :version "27.1"
+  :type 'boolean)
+
+(defun tramp-parse-auth-sources (method)
+  "Return a list of (user host) tuples allowed to access for METHOD.
+This function is added always in `tramp-get-completion-function'
+for all methods.  Resulting data are derived from default settings."
+  (and tramp-completion-use-auth-sources
+       (mapcar
+       (lambda (x) `(,(plist-get x :user) ,(plist-get x :host)))
+       (auth-source-search :port method :max most-positive-fixnum))))
+
 ;; Generic function.
 (defun tramp-parse-group (regexp match-level skip-regexp)
    "Return a (user host) tuple allowed to access.
@@ -4549,13 +4603,7 @@ Invokes `password-read' if available, `read-passwd' 
else."
        (hop (tramp-file-name-hop vec)))
     (when hop
       ;; Clear also the passwords of the hops.
-      (tramp-clear-passwd
-       (tramp-dissect-file-name
-       (concat
-        tramp-prefix-format
-        (replace-regexp-in-string
-         (concat tramp-postfix-hop-regexp "$")
-         tramp-postfix-host-format hop)))))
+      (tramp-clear-passwd (tramp-dissect-hop-name hop)))
     (auth-source-forget
      `(:max 1 ,(and user-domain :user) ,user-domain
        :host ,host-port :port ,method))
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index 4f256e1..0269c01 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -1640,6 +1640,8 @@ No indentation or other \"electric\" behavior is 
performed."
                  paren-state orig-point-min orig-point-max))
        (setq where 'in-block))))
 
+(def-edebug-spec c-while-widening-to-decl-block t)
+
 (defun c-beginning-of-defun (&optional arg)
   "Move backward to the beginning of a defun.
 Every top level declaration that contains a brace paren block is
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index f41a7cf..972d214 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -1316,20 +1316,36 @@ with value CHAR in the region [FROM to)."
 ;(eval-after-load "edebug" ; 2006-07-09: def-edebug-spec is now in subr.el.
 ;  '(progn
 (def-edebug-spec cc-eval-when-compile (&rest def-form))
+(def-edebug-spec c--mapcan t)
+(def-edebug-spec c--set-difference (form form &rest [symbolp form]))
+(def-edebug-spec c--intersection (form form &rest [symbolp form]))
+(def-edebug-spec c--delete-duplicates (form &rest [symbolp form]))
 (def-edebug-spec c-point t)
+(def-edebug-spec c-next-single-property-change t)
+(def-edebug-spec c-delete-and-extract-region t)
 (def-edebug-spec c-set-region-active t)
 (def-edebug-spec c-set-keymap-parent t)
 (def-edebug-spec c-safe t)
+(def-edebug-spec c-int-to-char t)
+(def-edebug-spec c-characterp t)
 (def-edebug-spec c-save-buffer-state let*)
 (def-edebug-spec c-tentative-buffer-changes t)
 (def-edebug-spec c-forward-syntactic-ws t)
 (def-edebug-spec c-backward-syntactic-ws t)
 (def-edebug-spec c-forward-sexp t)
 (def-edebug-spec c-backward-sexp t)
+(def-edebug-spec c-safe-scan-lists t)
+(def-edebug-spec c-go-list-forward t)
+(def-edebug-spec c-go-list-backward t)
 (def-edebug-spec c-up-list-forward t)
 (def-edebug-spec c-up-list-backward t)
 (def-edebug-spec c-down-list-forward t)
 (def-edebug-spec c-down-list-backward t)
+(def-edebug-spec c-go-up-list-forward t)
+(def-edebug-spec c-go-up-list-backward t)
+(def-edebug-spec c-go-down-list-forward t)
+(def-edebug-spec c-go-down-list-backward t)
+(def-edebug-spec c-at-vsemi-p t)
 (def-edebug-spec c-add-syntax t)
 (def-edebug-spec c-add-class-syntax t)
 (def-edebug-spec c-benign-error t)
@@ -1337,15 +1353,28 @@ with value CHAR in the region [FROM to)."
 (def-edebug-spec c-skip-ws-forward t)
 (def-edebug-spec c-skip-ws-backward t)
 (def-edebug-spec c-major-mode-is t)
+(def-edebug-spec c-search-forward-char-property t)
+(def-edebug-spec c-search-backward-char-property t)
 (def-edebug-spec c-put-char-property t)
 (def-edebug-spec c-get-char-property t)
 (def-edebug-spec c-clear-char-property t)
+(def-edebug-spec c-clear-char-property-with-value t)
 (def-edebug-spec c-clear-char-property-with-value-on-char t)
 (def-edebug-spec c-put-char-properties-on-char t)
 (def-edebug-spec c-clear-char-properties t)
 (def-edebug-spec c-put-overlay t)
 (def-edebug-spec c-delete-overlay t)
-(def-edebug-spec c-self-bind-state-cache t);))
+(def-edebug-spec c-mark-<-as-paren t)
+(def-edebug-spec c-mark->-as-paren t)
+(def-edebug-spec c-unmark-<->-as-paren t)
+(def-edebug-spec c-with-<->-as-parens-suppressed (body))
+(def-edebug-spec c-self-bind-state-cache (body))
+(def-edebug-spec c-sc-scan-lists-no-category+1+1 t)
+(def-edebug-spec c-sc-scan-lists-no-category+1-1 t)
+(def-edebug-spec c-sc-scan-lists-no-category-1+1 t)
+(def-edebug-spec c-sc-scan-lists-no-category-1-1 t)
+(def-edebug-spec c-sc-scan-lists t)
+(def-edebug-spec c-sc-parse-partial-sexp t);))
 
 
 ;;; Functions.
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 3ec7dbc..7a6cfdd 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -3879,9 +3879,10 @@ comment at the start of cc-engine.el for more info."
 (defmacro c-state-maybe-marker (place marker)
   ;; If PLACE is non-nil, return a marker marking it, otherwise nil.
   ;; We (re)use MARKER.
-  `(and ,place
-       (or ,marker (setq ,marker (make-marker)))
-       (set-marker ,marker ,place)))
+  `(let ((-place- ,place))
+     (and -place-
+         (or ,marker (setq ,marker (make-marker)))
+         (set-marker ,marker -place-))))
 
 (defun c-parse-state ()
   ;; This is a wrapper over `c-parse-state-1'.  See that function for a
@@ -13254,6 +13255,18 @@ Cannot combine absolute offsets %S and %S in `add' 
method"
       indent)))
 
 
+(def-edebug-spec c-bos-pop-state t)
+(def-edebug-spec c-bos-save-error-info t)
+(def-edebug-spec c-state-cache-top-lparen t)
+(def-edebug-spec c-state-cache-top-paren t)
+(def-edebug-spec c-state-cache-after-top-paren t)
+(def-edebug-spec c-state-maybe-marker (form symbolp))
+(def-edebug-spec c-record-type-id t)
+(def-edebug-spec c-record-ref-id t)
+(def-edebug-spec c-forward-keyword-prefixed-id t)
+(def-edebug-spec c-forward-id-comma-list t)
+(def-edebug-spec c-pull-open-brace (symbolp))
+
 (cc-provide 'cc-engine)
 
 ;; Local Variables:
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 9d2517f..79254ff 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -488,6 +488,9 @@
 
 ;  (eval-after-load "edebug" ; 2006-07-09: def-edebug-spec is now in subr.el.
 ;    '(progn
+(def-edebug-spec c-put-font-lock-face t)
+(def-edebug-spec c-remove-font-lock-face t)
+(def-edebug-spec c-put-font-lock-string-face t)
   (def-edebug-spec c-fontify-types-and-refs let*)
   (def-edebug-spec c-make-syntactic-matcher t)
   ;; If there are literal quoted or backquoted highlight specs in
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 1b44c75..de49ad7 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -205,6 +205,7 @@ the evaluated constant value at compile time."
 ;  '
 (def-edebug-spec c-lang-defvar
   (&define name def-form &optional &or ("quote" symbolp) stringp))
+(def-edebug-spec c-lang-setvar (&define name def-form))
 
 ;; Suppress "might not be defined at runtime" warning.
 ;; This file is only used when compiling other cc files.
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 09c30e2..cc1991a 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -1232,21 +1232,21 @@ Note that the style variables are always made local to 
the buffer."
       (if (eq beg-literal-type 'string)
          (setq c-new-BEG (min (car beg-limits) c-new-BEG))))
 
-     ((< c-new-END (point-max))
-      (goto-char (1+ c-new-END))       ; might be a newline.
+     ((< end (point-max))
+      (goto-char (1+ end))     ; might be a newline.
       ;; In the following regexp, the initial \n caters for a newline getting
       ;; joined to a preceding \ by the removal of what comes between.
       (re-search-forward "[\n\r]?\\(\\\\\\(.\\|\n\\|\r\\)\\|[^\\\n\r]\\)*"
                         nil t)
       ;; We're at an EOLL or point-max.
-      (setq c-new-END (min (1+ (point)) (point-max)))
-      (goto-char c-new-END)
-      (if (equal (c-get-char-property (1- (point)) 'syntax-table) '(15))
-         (if (memq (char-before) '(?\n ?\r))
+      (setq c-new-END (max c-new-END (min (1+ (point)) (point-max))))
+      (if (equal (c-get-char-property (point) 'syntax-table) '(15))
+         (if (memq (char-after) '(?\n ?\r))
              ;; Normally terminated invalid string.
-             (progn
+             (let ((eoll-1 (point)))
+               (forward-char)
                (backward-sexp)
-               (c-clear-char-property (1- c-new-END) 'syntax-table)
+               (c-clear-char-property eoll-1 'syntax-table)
                (c-clear-char-property (point) 'syntax-table))
            ;; Opening " at EOB.
            (c-clear-char-property (1- (point)) 'syntax-table))
@@ -1254,7 +1254,7 @@ Note that the style variables are always made local to 
the buffer."
            ;; Opening " on last line of text (without EOL).
            (c-clear-char-property (point) 'syntax-table))))
 
-     (t (goto-char c-new-END)
+     (t (goto-char end)                        ; point-max
        (if (c-search-backward-char-property 'syntax-table '(15) c-new-BEG)
            (c-clear-char-property (point) 'syntax-table))))
 
@@ -1343,9 +1343,9 @@ Note that the style variables are always made local to 
the buffer."
             (while (progn
                      (setq s (parse-partial-sexp (point) c-new-END nil
                                                  nil s 'syntax-table))
-                     (and (not (nth 3 s))
-                          (< (point) c-new-END)
-                          (not (memq (char-before) c-string-delims)))))
+                      (and (< (point) c-new-END)
+                           (or (not (nth 3 s))
+                               (not (memq (char-before) c-string-delims))))))
             ;; We're at the start of a string.
             (memq (char-before) c-string-delims)))
        (if (c-unescaped-nls-in-string-p (1- (point)))
@@ -1463,7 +1463,7 @@ Note that this is a strict tail, so won't match, e.g. 
\"0x....\".")
                 (goto-char (match-beginning 0))
                 (save-excursion (search-forward "'" (match-end 0) t)))))))))
 
-(defun c-parse-quotes-before-change (beg end)
+(defun c-parse-quotes-before-change (_beg _end)
   ;; This function analyzes 's near the region (c-new-BEG c-new-END), amending
   ;; those two variables as needed to include 's into that region when they
   ;; might be syntactically relevant to the change in progress.
@@ -1550,7 +1550,7 @@ Note that this is a strict tail, so won't match, e.g. 
\"0x....\".")
         'c-digit-separator t
         ?')))))
 
-(defun c-parse-quotes-after-change (beg end old-len)
+(defun c-parse-quotes-after-change (_beg _end _old-len)
   ;; This function applies syntax-table properties (value '(1)) and
   ;; c-digit-separator properties as needed to 's within the range (c-new-BEG
   ;; c-new-END).  This operation is performed even within strings and
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index 18a7232..7d08843 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -8786,7 +8786,7 @@ do extra unwind via `cperl-unwind-to-safe'."
        (goto-char new-beg)))
     (setq beg (point))
     (goto-char end)
-    (while (and end
+    (while (and end (< end (point-max))
                (progn
                  (or (bolp) (condition-case nil
                                 (forward-line 1)
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el
index 60d1660..f0f93f1 100644
--- a/lisp/progmodes/flymake.el
+++ b/lisp/progmodes/flymake.el
@@ -219,25 +219,24 @@ Specifically, start it when the saved buffer is actually 
displayed."
   :version "26.1"
   :type 'boolean)
 
-(when (fboundp 'define-fringe-bitmap)
-  (define-fringe-bitmap 'flymake-double-exclamation-mark
-    (vector #b00000000
-            #b00000000
-            #b00000000
-            #b00000000
-            #b01100110
-            #b01100110
-            #b01100110
-            #b01100110
-            #b01100110
-            #b01100110
-            #b01100110
-            #b01100110
-            #b00000000
-            #b01100110
-            #b00000000
-            #b00000000
-            #b00000000)))
+(define-fringe-bitmap 'flymake-double-exclamation-mark
+  (vector #b00000000
+          #b00000000
+          #b00000000
+          #b00000000
+          #b01100110
+          #b01100110
+          #b01100110
+          #b01100110
+          #b01100110
+          #b01100110
+          #b01100110
+          #b01100110
+          #b00000000
+          #b01100110
+          #b00000000
+          #b00000000
+          #b00000000))
 
 (defvar-local flymake-timer nil
   "Timer for starting syntax check.")
@@ -1184,20 +1183,17 @@ default) no filter is applied."
       ,@(unless (or all-disabled
                     (null known))
           (cl-loop
-           for (type . severity)
-           in (cl-sort (mapcar (lambda (type)
-                                 (cons type (flymake--severity type)))
-                               (cl-union (hash-table-keys diags-by-type)
-                                         '(:error :warning)
-                                         :key #'flymake--severity))
-                       #'>
-                       :key #'cdr)
+           with types = (hash-table-keys diags-by-type)
+           with _augmented = (cl-loop for extra in '(:error :warning)
+                                      do (cl-pushnew extra types
+                                                     :key #'flymake--severity))
+           for type in (cl-sort types #'> :key #'flymake--severity)
            for diags = (gethash type diags-by-type)
            for face = (flymake--lookup-type-property type
                                                      'mode-line-face
                                                      'compilation-error)
-           when (or diags
-                    (>= severity (warning-numeric-level :warning)))
+           when (or diags (>= (flymake--severity type)
+                              (warning-numeric-level :warning)))
            collect `(:propertize
                      ,(format "%d" (length diags))
                      face ,face
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index da979de..32bdc31 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -1741,16 +1741,12 @@ static char *magick[] = {
 (defvar breakpoint-disabled-icon nil
   "Icon for disabled breakpoint in display margin.")
 
-(declare-function define-fringe-bitmap "fringe.c"
-                 (bitmap bits &optional height width align))
-
-(and (display-images-p)
-     ;; Bitmap for breakpoint in fringe
-     (define-fringe-bitmap 'breakpoint
-       "\x3c\x7e\xff\xff\xff\xff\x7e\x3c")
-     ;; Bitmap for gud-overlay-arrow in fringe
-     (define-fringe-bitmap 'hollow-right-triangle
-       "\xe0\x90\x88\x84\x84\x88\x90\xe0"))
+;; Bitmap for breakpoint in fringe
+(define-fringe-bitmap 'breakpoint
+  "\x3c\x7e\xff\xff\xff\xff\x7e\x3c")
+;; Bitmap for gud-overlay-arrow in fringe
+(define-fringe-bitmap 'hollow-right-triangle
+  "\xe0\x90\x88\x84\x84\x88\x90\xe0")
 
 (defface breakpoint-enabled
   '((t
diff --git a/lisp/progmodes/modula2.el b/lisp/progmodes/modula2.el
index 582e495..ef12352 100644
--- a/lisp/progmodes/modula2.el
+++ b/lisp/progmodes/modula2.el
@@ -232,11 +232,11 @@
 ;; FIXME: "^." are two tokens, not one.
 (defun m2-smie-forward-token ()
   (pcase (smie-default-forward-token)
-    (`"VAR" (if (zerop (car (syntax-ppss))) "VAR" "VAR-arg"))
-    (`"CONST" (if (zerop (car (syntax-ppss))) "CONST" "CONST-arg"))
-    (`";" (save-excursion (m2-smie-refine-semi)))
-    (`"OF" (save-excursion (forward-char -2) (m2-smie-refine-of)))
-    (`":" (save-excursion (forward-char -1) (m2-smie-refine-colon)))
+    ("VAR" (if (zerop (car (syntax-ppss))) "VAR" "VAR-arg"))
+    ("CONST" (if (zerop (car (syntax-ppss))) "CONST" "CONST-arg"))
+    (";" (save-excursion (m2-smie-refine-semi)))
+    ("OF" (save-excursion (forward-char -2) (m2-smie-refine-of)))
+    (":" (save-excursion (forward-char -1) (m2-smie-refine-colon)))
     ;; (`"END" (if (and (looking-at "[ \t\n]*\\(\\(?:\\sw\\|\\s_\\)+\\)")
     ;;                  (not (assoc (match-string 1) m2-smie-grammar)))
     ;;             "END-proc" "END"))
@@ -244,11 +244,11 @@
 
 (defun m2-smie-backward-token ()
   (pcase (smie-default-backward-token)
-    (`"VAR" (if (zerop (car (syntax-ppss))) "VAR" "VAR-arg"))
-    (`"CONST" (if (zerop (car (syntax-ppss))) "CONST" "CONST-arg"))
-    (`";" (save-excursion (forward-char 1) (m2-smie-refine-semi)))
-    (`"OF" (save-excursion (m2-smie-refine-of)))
-    (`":" (save-excursion (m2-smie-refine-colon)))
+    ("VAR" (if (zerop (car (syntax-ppss))) "VAR" "VAR-arg"))
+    ("CONST" (if (zerop (car (syntax-ppss))) "CONST" "CONST-arg"))
+    (";" (save-excursion (forward-char 1) (m2-smie-refine-semi)))
+    ("OF" (save-excursion (m2-smie-refine-of)))
+    (":" (save-excursion (m2-smie-refine-colon)))
     ;; (`"END" (if (and (looking-at "\\sw+[ \t\n]+\\(\\(?:\\sw\\|\\s_\\)+\\)")
     ;;                  (not (assoc (match-string 1) m2-smie-grammar)))
     ;;             "END-proc" "END"))
@@ -272,7 +272,7 @@
   (pcase (cons kind token)
     (`(:elem . basic) m2-indent)
     (`(:after . ":=") (or m2-indent smie-indent-basic))
-    (`(:after . ,(or `"CONST" `"VAR" `"TYPE"))
+    (`(:after . ,(or "CONST" "VAR" "TYPE"))
      (or m2-indent smie-indent-basic))
     ;; (`(:before . ,(or `"VAR" `"TYPE" `"CONST"))
     ;;  (if (smie-rule-parent-p "PROCEDURE") 0))
diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el
index 984bb73..cce5e17 100644
--- a/lisp/progmodes/octave.el
+++ b/lisp/progmodes/octave.el
@@ -170,8 +170,8 @@ parenthetical grouping.")
     (modify-syntax-entry ?. "."   table)
     (modify-syntax-entry ?\" "\"" table)
     (modify-syntax-entry ?_ "_"   table)
-    ;; The "b" flag only applies to the second letter of the comstart
-    ;; and the first letter of the comend, i.e. the "4b" below is ineffective.
+    ;; The "b" flag only applies to the second letter of the comstart and
+    ;; the first letter of the comend, i.e. a "4b" below would be ineffective.
     ;; If we try to put `b' on the single-line comments, we get a similar
     ;; problem where the % and # chars appear as first chars of the 2-char
     ;; comend, so the multi-line ender is also turned into style-b.
@@ -533,6 +533,27 @@ Non-nil means always go to the next Octave code line after 
sending."
 
 (defvar electric-layout-rules)
 
+;; FIXME: cc-mode.el also adds an entry for .m files, mapping them to
+;; objc-mode.  We here rely on the fact that loaddefs.el is filled in
+;; alphabetical order, so cc-mode.el comes before octave-mode.el, which lets
+;; our entry come first!
+;;;###autoload (add-to-list 'auto-mode-alist '("\\.m\\'" . octave-maybe-mode))
+
+;;;###autoload
+(defun octave-maybe-mode ()
+  "Select `octave-mode' if the current buffer seems to hold Octave code."
+  (if (save-excursion
+        (with-syntax-table octave-mode-syntax-table
+          (goto-char (point-min))
+          (forward-comment (point-max))
+          ;; FIXME: What about Octave files which don't start with "function"?
+          (looking-at "function")))
+      (octave-mode)
+    (let ((x (rassq 'octave-maybe-mode auto-mode-alist)))
+      (when x
+        (let ((auto-mode-alist (remove x auto-mode-alist)))
+          (set-auto-mode))))))
+
 ;;;###autoload
 (define-derived-mode octave-mode prog-mode "Octave"
   "Major mode for editing Octave code.
@@ -1044,8 +1065,8 @@ directory and makes this the current buffer's default 
directory."
              (unless found (goto-char orig))
              found))))
     (pcase (and buffer-file-name (file-name-extension buffer-file-name))
-      (`"cc" (funcall search
-                      
"\\_<DEFUN\\(?:_DLD\\)?\\s-*(\\s-*\\(\\(?:\\sw\\|\\s_\\)+\\)" 1))
+      ("cc" (funcall search
+                     
"\\_<DEFUN\\(?:_DLD\\)?\\s-*(\\s-*\\(\\(?:\\sw\\|\\s_\\)+\\)" 1))
       (_ (funcall search octave-function-header-regexp 3)))))
 
 (defun octave-function-file-p ()
@@ -1114,19 +1135,19 @@ q: Don't fix\n" func file))
                       (read-char-choice
                        "Which name to use? (a/b/q) " '(?a ?b ?q))))))
           (pcase c
-            (`?a (let ((newname (expand-file-name
-                                 (concat func (file-name-extension
-                                               buffer-file-name t)))))
-                   (when (or (not (file-exists-p newname))
-                             (yes-or-no-p
-                              (format "Target file %s exists; proceed? " 
newname)))
-                     (when (file-exists-p buffer-file-name)
-                       (rename-file buffer-file-name newname t))
-                     (set-visited-file-name newname))))
-            (`?b (save-excursion
-                   (goto-char name-start)
-                   (delete-region name-start name-end)
-                   (insert file)))))))))
+            (?a (let ((newname (expand-file-name
+                                (concat func (file-name-extension
+                                              buffer-file-name t)))))
+                  (when (or (not (file-exists-p newname))
+                            (yes-or-no-p
+                             (format "Target file %s exists; proceed? " 
newname)))
+                    (when (file-exists-p buffer-file-name)
+                      (rename-file buffer-file-name newname t))
+                    (set-visited-file-name newname))))
+            (?b (save-excursion
+                  (goto-char name-start)
+                  (delete-region name-start name-end)
+                  (insert file)))))))))
 
 (defun octave-update-function-file-comment (beg end)
   "Query replace function names in function file comment."
@@ -1780,19 +1801,19 @@ If the environment variable OCTAVE_SRCDIR is set, it is 
searched first."
 (defun octave-find-definition-default-filename (name)
   "Default value for `octave-find-definition-filename-function'."
   (pcase (file-name-extension name)
-    (`"oct"
+    ("oct"
      (octave-find-definition-default-filename
       (concat "libinterp/dldfcn/"
               (file-name-sans-extension (file-name-nondirectory name))
               ".cc")))
-    (`"cc"
+    ("cc"
      (let ((file (or (locate-file name (octave-source-directories))
                      (locate-file (file-name-nondirectory name)
                                   (octave-source-directories)))))
        (or (and file (file-exists-p file))
            (error "File `%s' not found" name))
        file))
-    (`"mex"
+    ("mex"
      (if (yes-or-no-p (format-message "File `%s' may be binary; open? "
                                      (file-name-nondirectory name)))
          name
diff --git a/lisp/progmodes/opascal.el b/lisp/progmodes/opascal.el
index 4606621..7d055b7 100644
--- a/lisp/progmodes/opascal.el
+++ b/lisp/progmodes/opascal.el
@@ -393,17 +393,17 @@ routine.")
         (if (null (nth 8 ppss))
             (when (looking-at opascal--literal-start-re)
               (pcase (char-after)
-                (`?/  'comment-single-line)
-                (`?\{ 'comment-multi-line-1)
-                (`?\( 'comment-multi-line-2)
-                (`?\' 'string)
-                (`?\" 'double-quoted-string)))
+                (?/  'comment-single-line)
+                (?\{ 'comment-multi-line-1)
+                (?\( 'comment-multi-line-2)
+                (?\' 'string)
+                (?\" 'double-quoted-string)))
           (if (nth 3 ppss)   ;String.
               (if (eq (nth 3 ppss) ?\")
                   'double-quoted-string 'string)
             (pcase (nth 7 ppss)
-              (`2 'comment-single-line)
-              (`1 'comment-multi-line-2)
+              (2 'comment-single-line)
+              (1 'comment-multi-line-2)
               (_  'comment-multi-line-1))))))))
 
 (defun opascal-literal-start-pattern (literal-kind)
diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el
index b96aad7..a61d1ad 100644
--- a/lisp/progmodes/perl-mode.el
+++ b/lisp/progmodes/perl-mode.el
@@ -323,8 +323,8 @@
               (cons (car (string-to-syntax "< c"))
                     ;; Remember the names of heredocs found on this line.
                     (cons (cons (pcase (aref name 0)
-                                  (`?\\ (substring name 1))
-                                  ((or `?\" `?\' `?\`) (substring name 1 -1))
+                                  (?\\ (substring name 1))
+                                  ((or ?\" ?\' ?\`) (substring name 1 -1))
                                   (_ name))
                                 indented)
                           (cdr st)))))))
diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el
index 3bcc9be..b530c61 100644
--- a/lisp/progmodes/prolog.el
+++ b/lisp/progmodes/prolog.el
@@ -954,9 +954,9 @@ This is really kludgy, and unneeded (i.e. obsolete) in 
Emacs>=24."
     ;;    ->  thenrule
     ;;    ;   elserule
     ;;    )
-    (`(:before . ,(or `"->" `";"))
+    (`(:before . ,(or "->" ";"))
      (and (smie-rule-bolp) (smie-rule-parent-p "(") (smie-rule-parent 0)))
-    (`(:after . ,(or `"->" `"*->"))
+    (`(:after . ,(or "->" "*->"))
      ;; We distinguish
      ;;
      ;;     (a ->
@@ -3247,11 +3247,11 @@ the following comma and whitespace, if any."
 
 (defun prolog-post-self-insert ()
   (pcase last-command-event
-    (`?_ (prolog-electric--underscore))
-    (`?- (prolog-electric--dash))
-    (`?: (prolog-electric--colon))
-    ((or `?\( `?\; `?>) (prolog-electric--if-then-else))
-    (`?. (prolog-electric--dot))))
+    (?_ (prolog-electric--underscore))
+    (?- (prolog-electric--dash))
+    (?: (prolog-electric--colon))
+    ((or ?\( ?\; ?>) (prolog-electric--if-then-else))
+    (?. (prolog-electric--dot))))
 
 (defun prolog-find-term (functor arity &optional prefix)
   "Go to the position at the start of the next occurrence of a term.
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index fad7bc1..9256dfc 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -217,19 +217,16 @@ This should only be called after matching against 
`ruby-here-doc-beg-re'."
 (defcustom ruby-indent-tabs-mode nil
   "Indentation can insert tabs in Ruby mode if this is non-nil."
   :type 'boolean
-  :group 'ruby
   :safe 'booleanp)
 
 (defcustom ruby-indent-level 2
   "Indentation of Ruby statements."
   :type 'integer
-  :group 'ruby
   :safe 'integerp)
 
 (defcustom ruby-comment-column (default-value 'comment-column)
   "Indentation column of comments."
   :type 'integer
-  :group 'ruby
   :safe 'integerp)
 
 (defconst ruby-alignable-keywords '(if while unless until begin case for def)
@@ -265,7 +262,6 @@ Only has effect when `ruby-use-smie' is t."
                   (choice ,@(mapcar
                              (lambda (kw) (list 'const kw))
                              ruby-alignable-keywords))))
-  :group 'ruby
   :safe 'listp
   :version "24.4")
 
@@ -277,7 +273,6 @@ of its parent.
 
 Only has effect when `ruby-use-smie' is t."
   :type 'boolean
-  :group 'ruby
   :safe 'booleanp
   :version "24.4")
 
@@ -286,7 +281,6 @@ Only has effect when `ruby-use-smie' is t."
 Also ignores spaces after parenthesis when `space'.
 Only has effect when `ruby-use-smie' is nil."
   :type 'boolean
-  :group 'ruby
   :safe 'booleanp)
 
 ;; FIXME Woefully under documented.  What is the point of the last t?.
@@ -301,14 +295,12 @@ Only has effect when `ruby-use-smie' is nil."
                                  (cons character (choice (const nil)
                                                          (const t)))
                                  (const t) ; why?
-                                 )))
-  :group 'ruby)
+                                 ))))
 
 (defcustom ruby-deep-indent-paren-style 'space
   "Default deep indent style.
 Only has effect when `ruby-use-smie' is nil."
-  :type '(choice (const t) (const nil) (const space))
-  :group 'ruby)
+  :type '(choice (const t) (const nil) (const space)))
 
 (defcustom ruby-encoding-map
   '((us-ascii       . nil)       ;; Do not put coding: us-ascii
@@ -318,8 +310,7 @@ Only has effect when `ruby-use-smie' is nil."
   "Alist to map encoding name from Emacs to Ruby.
 Associating an encoding name with nil means it needs not be
 explicitly declared in magic comment."
-  :type '(repeat (cons (symbol :tag "From") (symbol :tag "To")))
-  :group 'ruby)
+  :type '(repeat (cons (symbol :tag "From") (symbol :tag "To"))))
 
 (defcustom ruby-insert-encoding-magic-comment t
   "Insert a magic Ruby encoding comment upon save if this is non-nil.
@@ -336,14 +327,12 @@ even if it's not required."
           (const :tag "Emacs Style" emacs)
           (const :tag "Ruby Style" ruby)
           (const :tag "Custom Style" custom))
-  :group 'ruby
   :version "24.4")
 
 (defcustom ruby-custom-encoding-magic-comment-template "# encoding: %s"
   "A custom encoding comment template.
 It is used when `ruby-encoding-magic-comment-style' is set to `custom'."
   :type 'string
-  :group 'ruby
   :version "24.4")
 
 (defcustom ruby-use-encoding-map t
@@ -612,7 +601,7 @@ It is used when `ruby-encoding-magic-comment-style' is set 
to `custom'."
       ;; For (invalid) code between switch and case.
       ;; (if (smie-parent-p "switch") 4)
       ))
-    (`(:before . ,(or `"(" `"[" `"{"))
+    (`(:before . ,(or "(" "[" "{"))
      (cond
       ((and (equal token "{")
             (not (smie-rule-prev-p "(" "{" "[" "," "=>" "=" "return" ";"))
@@ -639,7 +628,7 @@ It is used when `ruby-encoding-magic-comment-style' is set 
to `custom'."
            (forward-char -1))
          (smie-indent-virtual))
         (t (smie-rule-parent))))))
-    (`(:after . ,(or `"(" "[" "{"))
+    (`(:after . ,(or "(" "[" "{"))
      ;; FIXME: Shouldn't this be the default behavior of
      ;; `smie-indent-after-keyword'?
      (save-excursion
@@ -660,7 +649,7 @@ It is used when `ruby-encoding-magic-comment-style' is set 
to `custom'."
        (smie-backward-sexp ".")
        (cons 'column (+ (current-column)
                         ruby-indent-level))))
-    (`(:before . ,(or `"else" `"then" `"elsif" `"rescue" `"ensure"))
+    (`(:before . ,(or "else" "then" "elsif" "rescue" "ensure"))
      (smie-rule-parent))
     (`(:before . "when")
      ;; Align to the previous `when', but look up the virtual
@@ -741,7 +730,7 @@ It is used when `ruby-encoding-magic-comment-style' is set 
to `custom'."
           (back-to-indentation)
           (narrow-to-region (point) end)
           (smie-forward-sexp))
-      (while (and (setq state (apply 'ruby-parse-partial end state))
+      (while (and (setq state (apply #'ruby-parse-partial end state))
                     (>= (nth 2 state) 0) (< (point) end))))))
 
 (defun ruby-mode-variables ()
@@ -751,7 +740,7 @@ It is used when `ruby-encoding-magic-comment-style' is set 
to `custom'."
       (smie-setup ruby-smie-grammar #'ruby-smie-rules
                   :forward-token  #'ruby-smie--forward-token
                   :backward-token #'ruby-smie--backward-token)
-    (setq-local indent-line-function 'ruby-indent-line))
+    (setq-local indent-line-function #'ruby-indent-line))
   (setq-local comment-start "# ")
   (setq-local comment-end "")
   (setq-local comment-column ruby-comment-column)
@@ -986,6 +975,7 @@ delimiter."
         ((eq c ?\( ) ruby-deep-arglist)))
 
 (defun ruby-parse-partial (&optional end in-string nest depth pcol indent)
+  ;; FIXME: Document why we can't just use parse-partial-sexp.
   "TODO: document throughout function body."
   (or depth (setq depth 0))
   (or indent (setq indent 0))
@@ -1160,7 +1150,7 @@ delimiter."
                  (state (list in-string nest depth pcol indent)))
             ;; parse the rest of the line
             (while (and (> line-end-position (point))
-                        (setq state (apply 'ruby-parse-partial
+                        (setq state (apply #'ruby-parse-partial
                                            line-end-position state))))
             (setq in-string (car state)
                   nest (nth 1 state)
@@ -1197,7 +1187,7 @@ delimiter."
       (save-restriction
         (narrow-to-region (point) end)
         (while (and (> end (point))
-                    (setq state (apply 'ruby-parse-partial end state))))))
+                    (setq state (apply #'ruby-parse-partial end state))))))
     (list (nth 0 state)                 ; in-string
           (car (nth 1 state))           ; nest
           (nth 2 state)                 ; depth
@@ -1544,8 +1534,8 @@ With ARG, do it many times.  Negative ARG means move 
forward."
             (cond ((looking-at "\\s)")
                    (goto-char (scan-sexps (1+ (point)) -1))
                    (pcase (char-before)
-                     (`?% (forward-char -1))
-                     ((or `?q `?Q `?w `?W `?r `?x)
+                     (?% (forward-char -1))
+                     ((or ?q ?Q ?w ?W ?r ?x)
                       (if (eq (char-before (1- (point))) ?%)
                           (forward-char -2))))
                    nil)
@@ -1562,13 +1552,13 @@ With ARG, do it many times.  Negative ARG means move 
forward."
                    (forward-char 1)
                    (while (progn (forward-word-strictly -1)
                                  (pcase (char-before)
-                                   (`?_ t)
-                                   (`?. (forward-char -1) t)
-                                   ((or `?$ `?@)
+                                   (?_ t)
+                                   (?. (forward-char -1) t)
+                                   ((or ?$ ?@)
                                     (forward-char -1)
                                     (and (eq (char-before) (char-after))
                                          (forward-char -1)))
-                                   (`?:
+                                   (?:
                                     (forward-char -1)
                                     (eq (char-before) :)))))
                    (if (looking-at ruby-block-end-re)
@@ -2034,13 +2024,6 @@ It will be properly highlighted even when the call omits 
parens.")
                  context)))
         t)))
 
-(defvar ruby-font-lock-syntax-table
-  (let ((tbl (make-syntax-table ruby-mode-syntax-table)))
-    (modify-syntax-entry ?_ "w" tbl)
-    tbl)
-  "The syntax table to use for fontifying Ruby mode buffers.
-See `font-lock-syntax-table'.")
-
 (defconst ruby-font-lock-keyword-beg-re 
"\\(?:^\\|address@hidden:]\\|\\.\\.\\)")
 
 (defconst ruby-font-lock-keywords
@@ -2219,7 +2202,8 @@ See `font-lock-syntax-table'.")
     ;; Conversion methods on Kernel.
     (,(concat ruby-font-lock-keyword-beg-re
               (regexp-opt '("Array" "Complex" "Float" "Hash"
-                            "Integer" "Rational" "String") 'symbols))
+                            "Integer" "Rational" "String")
+                          'symbols))
      (1 font-lock-builtin-face))
     ;; Expression expansion.
     (ruby-match-expression-expansion
@@ -2316,14 +2300,12 @@ See `font-lock-syntax-table'.")
 Only takes effect if RuboCop is installed."
   :version "26.1"
   :type 'boolean
-  :group 'ruby
   :safe 'booleanp)
 
 (defcustom ruby-rubocop-config ".rubocop.yml"
   "Configuration file for `ruby-flymake-rubocop'."
   :version "26.1"
   :type 'string
-  :group 'ruby
   :safe 'stringp)
 
 (defun ruby-flymake-rubocop (report-fn &rest _args)
@@ -2393,18 +2375,17 @@ Only takes effect if RuboCop is installed."
   "Major mode for editing Ruby code."
   (ruby-mode-variables)
 
-  (setq-local imenu-create-index-function 'ruby-imenu-create-index)
-  (setq-local add-log-current-defun-function 'ruby-add-log-current-method)
-  (setq-local beginning-of-defun-function 'ruby-beginning-of-defun)
-  (setq-local end-of-defun-function 'ruby-end-of-defun)
+  (setq-local imenu-create-index-function #'ruby-imenu-create-index)
+  (setq-local add-log-current-defun-function #'ruby-add-log-current-method)
+  (setq-local beginning-of-defun-function #'ruby-beginning-of-defun)
+  (setq-local end-of-defun-function #'ruby-end-of-defun)
 
-  (add-hook 'after-save-hook 'ruby-mode-set-encoding nil 'local)
-  (add-hook 'electric-indent-functions 'ruby--electric-indent-p nil 'local)
-  (add-hook 'flymake-diagnostic-functions 'ruby-flymake-auto nil 'local)
+  (add-hook 'after-save-hook #'ruby-mode-set-encoding nil 'local)
+  (add-hook 'electric-indent-functions #'ruby--electric-indent-p nil 'local)
+  (add-hook 'flymake-diagnostic-functions #'ruby-flymake-auto nil 'local)
 
-  (setq-local font-lock-defaults '((ruby-font-lock-keywords) nil nil))
-  (setq-local font-lock-keywords ruby-font-lock-keywords)
-  (setq-local font-lock-syntax-table ruby-font-lock-syntax-table)
+  (setq-local font-lock-defaults '((ruby-font-lock-keywords) nil nil
+                                   ((?_ . "w"))))
 
   (setq-local syntax-propertize-function #'ruby-syntax-propertize))
 
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index aaa86b5..46c9e6e 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -959,8 +959,8 @@ See `sh-feature'.")
            ;; ((...)) or $((...)) or $[...] or ${...}. Nested
            ;; parenthesis can occur inside the first of these forms, so
            ;; parse backward recursively.
-           (`?\( (eq ?\( (char-before)))
-           ((or `?\{ `?\[) (eq ?\$ (char-before))))
+           (?\( (eq ?\( (char-before)))
+           ((or ?\{ ?\[) (eq ?\$ (char-before))))
          (sh--inside-noncommand-expression (1- (point))))))))
 
 (defun sh-font-lock-open-heredoc (start string eol)
@@ -2038,7 +2038,7 @@ May return nil if the line should not be treated as 
continued."
     (`(:elem . basic) sh-basic-offset)
     (`(:after . "case-)") (- (sh-var-value 'sh-indent-for-case-alt)
                              (sh-var-value 'sh-indent-for-case-label)))
-    (`(:before . ,(or `"(" `"{" `"[" "while" "if" "for" "case"))
+    (`(:before . ,(or "(" "{" "[" "while" "if" "for" "case"))
      (if (not (smie-rule-prev-p "&&" "||" "|"))
          (when (smie-rule-hanging-p)
            (smie-rule-parent))
@@ -2047,11 +2047,11 @@ May return nil if the line should not be treated as 
continued."
         `(column . ,(smie-indent-virtual)))))
     ;; FIXME: Maybe this handling of ;; should be made into
     ;; a smie-rule-terminator function that takes the substitute ";" as arg.
-    (`(:before . ,(or `";;" `";&" `";;&"))
+    (`(:before . ,(or ";;" ";&" ";;&"))
      (if (and (smie-rule-bolp) (looking-at ";;?&?[ \t]*\\(#\\|$\\)"))
          (cons 'column (smie-indent-keyword ";"))
        (smie-rule-separator kind)))
-    (`(:after . ,(or `";;" `";&" `";;&"))
+    (`(:after . ,(or ";;" ";&" ";;&"))
      (with-demoted-errors
        (smie-backward-sexp token)
        (cons 'column
@@ -2062,7 +2062,7 @@ May return nil if the line should not be treated as 
continued."
                             (smie-rule-bolp))))
                  (current-column)
                (smie-indent-calculate)))))
-    (`(:before . ,(or `"|" `"&&" `"||"))
+    (`(:before . ,(or "|" "&&" "||"))
      (unless (smie-rule-parent-p token)
        (smie-backward-sexp token)
        `(column . ,(+ (funcall smie-rules-function :elem 'basic)
@@ -2081,7 +2081,7 @@ May return nil if the line should not be treated as 
continued."
     ;; sh-indent-after-done: aligned completely differently.
     (`(:after . "in") (sh-var-value 'sh-indent-for-case-label))
     ;; sh-indent-for-continuation: Line continuations are handled differently.
-    (`(:after . ,(or `"(" `"{" `"["))
+    (`(:after . ,(or "(" "{" "["))
      (if (not (looking-at ".[ \t]*[^\n \t#]"))
          (sh-var-value 'sh-indent-after-open)
        (goto-char (1- (match-end 0)))
@@ -2253,7 +2253,7 @@ Point should be before the newline."
      (save-excursion
        (when (sh-smie--rc-after-special-arg-p)
          `(column . ,(current-column)))))
-    (`(:before . ,(or `"(" `"{" `"["))
+    (`(:before . ,(or "(" "{" "["))
      (if (smie-rule-hanging-p) (smie-rule-parent)))
     ;; FIXME: SMIE parses "if (exp) cmd" as "(if ((exp) cmd))" so "cmd" is
     ;; treated as an arg to (exp) by default, which indents it all wrong.
@@ -2262,7 +2262,7 @@ Point should be before the newline."
     ;; rule we have is the :list-intro hack, which we use here to align "cmd"
     ;; with "(exp)", which is rarely the right thing to do, but is better
     ;; than nothing.
-    (`(:list-intro . ,(or `"for" `"if" `"while")) t)
+    (`(:list-intro . ,(or "for" "if" "while")) t)
     ;; sh-indent-after-switch: handled implicitly by the default { rule.
     ))
 
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index c7ae40e..6b1421a 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -992,7 +992,7 @@ IGNORES is a list of glob patterns."
        ;; do that reliably enough, without creating false negatives?
        (command (xref--rgrep-command (xref--regexp-to-extended regexp)
                                      files
-                                     (expand-file-name dir)
+                                     (file-local-name (expand-file-name dir))
                                      ignores))
        (def default-directory)
        (buf (get-buffer-create " *xref-grep*"))
@@ -1003,7 +1003,7 @@ IGNORES is a list of glob patterns."
       (erase-buffer)
       (setq default-directory def)
       (setq status
-            (call-process-shell-command command nil t))
+            (process-file-shell-command command nil t))
       (goto-char (point-min))
       ;; Can't use the exit status: Grep exits with 1 to mean "no
       ;; matches found".  Find exits with 1 if any of the invocations
@@ -1105,6 +1105,7 @@ Such as the current syntax table and the applied syntax 
properties."
 
 (defun xref--collect-matches (hit regexp tmp-buffer)
   (pcase-let* ((`(,line ,file ,text) hit)
+               (file (and file (concat (file-remote-p default-directory) 
file)))
                (buf (xref--find-buffer-visiting file))
                (syntax-needed (xref--regexp-syntax-dependent-p regexp)))
     (if buf
diff --git a/lisp/rect.el b/lisp/rect.el
index 8ccf051..6b6906a 100644
--- a/lisp/rect.el
+++ b/lisp/rect.el
@@ -167,6 +167,45 @@ The final point after the last operation will be returned."
                  (<= (point) endpt))))
       final-point)))
 
+(defun rectangle-position-as-coordinates (position)
+   "Return cons of the column and line values of POSITION.
+POSITION specifies a position of the current buffer.  The value
+returned has the form (COLUMN . LINE)."
+  (save-excursion
+    (goto-char position)
+    (let ((col (current-column))
+          (line (line-number-at-pos)))
+      (cons col line))))
+
+(defun rectangle-intersect-p (pos1 size1 pos2 size2)
+   "Return non-nil if two rectangles intersect.
+POS1 and POS2 specify the positions of the upper-left corners of
+the first and second rectangles as conses of the form (COLUMN . LINE).
+SIZE1 and SIZE2 specify the dimensions of the first and second
+rectangles, as conses of the form (WIDTH . HEIGHT)."
+  (let ((x1 (car pos1))
+        (y1 (cdr pos1))
+        (x2 (car pos2))
+        (y2 (cdr pos2))
+        (w1 (car size1))
+        (h1 (cdr size1))
+        (w2 (car size2))
+        (h2 (cdr size2)))
+    (not (or (<= (+ x1 w1) x2)
+             (<= (+ x2 w2) x1)
+             (<= (+ y1 h1) y2)
+             (<= (+ y2 h2) y1)))))
+
+(defun rectangle-dimensions (start end)
+  "Return the dimensions of the rectangle with corners at START
+and END. The returned value has the form of (WIDTH . HEIGHT)."
+  (save-excursion
+    (let* ((height (1+ (abs (- (line-number-at-pos end)
+                               (line-number-at-pos start)))))
+           (cols (rectangle--pos-cols start end))
+           (width (abs (- (cdr cols) (car cols)))))
+      (cons width height))))
+
 (defun delete-rectangle-line (startcol endcol fill)
   (when (= (move-to-column startcol (if fill t 'coerce)) startcol)
     (delete-region (point)
diff --git a/lisp/registry.el b/lisp/registry.el
index 4928dd9..c3184a8 100644
--- a/lisp/registry.el
+++ b/lisp/registry.el
@@ -358,7 +358,7 @@ return LIMIT such candidates.  If SORTFUNC is provided, sort
 entries first and return candidates from beginning of list."
   (let* ((precious (oref db precious))
         (precious-p (lambda (entry-key)
-                      (cdr (memq (car-safe entry-key) precious))))
+                      (memq (car-safe entry-key) precious)))
         (data (oref db data))
         (candidates (cl-loop for k being the hash-keys of data
                              using (hash-values v)
diff --git a/lisp/server.el b/lisp/server.el
index 50684a2..d0a8ca3 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -1112,16 +1112,16 @@ The following commands are accepted by the client:
            (while args-left
               (pcase (pop args-left)
                 ;; -version CLIENT-VERSION: obsolete at birth.
-                (`"-version" (pop args-left))
+                ("-version" (pop args-left))
 
                 ;; -nowait:  Emacsclient won't wait for a result.
-                (`"-nowait" (setq nowait t))
+                ("-nowait" (setq nowait t))
 
                 ;; -current-frame:  Don't create frames.
-                (`"-current-frame" (setq use-current-frame t))
+                ("-current-frame" (setq use-current-frame t))
 
                 ;; -frame-parameters: Set frame parameters
-                (`"-frame-parameters"
+                ("-frame-parameters"
                  (let ((alist (pop args-left)))
                    (if coding-system
                        (setq alist (decode-coding-string alist coding-system)))
@@ -1129,24 +1129,24 @@ The following commands are accepted by the client:
 
                 ;; -display DISPLAY:
                 ;; Open X frames on the given display instead of the default.
-                (`"-display"
+                ("-display"
                  (setq display (pop args-left))
                  (if (zerop (length display)) (setq display nil)))
 
                 ;; -parent-id ID:
                 ;; Open X frame within window ID, via XEmbed.
-                (`"-parent-id"
+                ("-parent-id"
                  (setq parent-id (pop args-left))
                  (if (zerop (length parent-id)) (setq parent-id nil)))
 
                 ;; -window-system:  Open a new X frame.
-                (`"-window-system"
+                ("-window-system"
                 (if (fboundp 'x-create-frame)
                     (setq dontkill t
                           tty-name 'window-system)))
 
                 ;; -resume:  Resume a suspended tty frame.
-                (`"-resume"
+                ("-resume"
                  (let ((terminal (process-get proc 'terminal)))
                    (setq dontkill t)
                    (push (lambda ()
@@ -1157,7 +1157,7 @@ The following commands are accepted by the client:
                 ;; -suspend:  Suspend the client's frame.  (In case we
                 ;; get out of sync, and a C-z sends a SIGTSTP to
                 ;; emacsclient.)
-                (`"-suspend"
+                ("-suspend"
                  (let ((terminal (process-get proc 'terminal)))
                    (setq dontkill t)
                    (push (lambda ()
@@ -1167,13 +1167,13 @@ The following commands are accepted by the client:
 
                 ;; -ignore COMMENT:  Noop; useful for debugging emacsclient.
                 ;; (The given comment appears in the server log.)
-                (`"-ignore"
+                ("-ignore"
                  (setq dontkill t)
                  (pop args-left))
 
                ;; -tty DEVICE-NAME TYPE:  Open a new tty frame.
                ;; (But if we see -window-system later, use that.)
-                (`"-tty"
+                ("-tty"
                  (setq tty-name (pop args-left)
                        tty-type (pop args-left)
                        dontkill (or dontkill
@@ -1192,7 +1192,7 @@ The following commands are accepted by the client:
 
                 ;; -position LINE[:COLUMN]:  Set point to the given
                 ;;  position in the next file.
-                (`"-position"
+                ("-position"
                  (if (not (string-match "\\+\\([0-9]+\\)\\(?::\\([0-9]+\\)\\)?"
                                         (car args-left)))
                      (error "Invalid -position command in client args"))
@@ -1203,7 +1203,7 @@ The following commands are accepted by the client:
                                                      ""))))))
 
                 ;; -file FILENAME:  Load the given file.
-                (`"-file"
+                ("-file"
                  (let ((file (pop args-left)))
                    (if coding-system
                        (setq file (decode-coding-string file coding-system)))
@@ -1221,7 +1221,7 @@ The following commands are accepted by the client:
                  (setq filepos nil))
 
                 ;; -eval EXPR:  Evaluate a Lisp expression.
-                (`"-eval"
+                ("-eval"
                  (if use-current-frame
                      (setq use-current-frame 'always))
                  (let ((expr (pop args-left)))
@@ -1232,14 +1232,14 @@ The following commands are accepted by the client:
                    (setq filepos nil)))
 
                 ;; -env NAME=VALUE:  An environment variable.
-                (`"-env"
+                ("-env"
                  (let ((var (pop args-left)))
                    ;; XXX Variables should be encoded as in getenv/setenv.
                    (process-put proc 'env
                                 (cons var (process-get proc 'env)))))
 
                 ;; -dir DIRNAME:  The cwd of the emacsclient process.
-                (`"-dir"
+                ("-dir"
                  (setq dir (pop args-left))
                  (if coding-system
                      (setq dir (decode-coding-string dir coding-system)))
diff --git a/lisp/simple.el b/lisp/simple.el
index 17bcb06..a8d438b 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1071,13 +1071,16 @@ instead of deleted."
         (filter-buffer-substring (region-beginning) (region-end) method)))))
   "Function to get the region's content.
 Called with one argument METHOD which can be:
-- nil: return the content as a string.
+- nil: return the content as a string (list of strings for
+  non-contiguous regions).
 - `delete-only': delete the region; the return value is undefined.
-- `bounds': return the boundaries of the region as a list of cons
-  cells of the form (START . END).
+- `bounds': return the boundaries of the region as a list of one
+  or more cons cells of the form (START . END).
 - anything else: delete the region and return its content
-  as a string, after filtering it with `filter-buffer-substring', which
-  is called with METHOD as its 3rd argument.")
+  as a string (or list of strings for non-contiguous regions),
+  after filtering it with `filter-buffer-substring', which
+  is called, for each contiguous sub-region, with METHOD as its
+  3rd argument.")
 
 (defvar region-insert-function
   (lambda (lines)
@@ -3959,6 +3962,7 @@ support pty association, if PROGRAM is nil."
                                ;; name "*Async Shell Command*<10>" (bug#30016)
                               ("Buffer"  25 t)
                               ("TTY"     12 t)
+                              ("Thread"  12 t)
                               ("Command"  0 t)])
   (make-local-variable 'process-menu-query-only)
   (setq tabulated-list-sort-key (cons "Process" nil))
@@ -4000,6 +4004,11 @@ Also, delete any process that is exited or signaled."
                                   action process-menu-visit-buffer)
                               "--"))
                  (tty (or (process-tty-name p) "--"))
+                 (thread
+                   (cond
+                    ((null (process-thread p)) "--")
+                    ((eq (process-thread p) main-thread) "Main")
+                    ((thread-name (process-thread p)))))
                  (cmd
                   (if (memq type '(network serial))
                       (let ((contact (process-contact p t)))
@@ -4022,7 +4031,7 @@ Also, delete any process that is exited or signaled."
                                         (format " at %s b/s" speed)
                                       "")))))
                     (mapconcat 'identity (process-command p) " "))))
-            (push (list p (vector name pid status buf-label tty cmd))
+            (push (list p (vector name pid status buf-label tty thread cmd))
                   tabulated-list-entries)))))
   (tabulated-list-init-header))
 
@@ -4304,7 +4313,7 @@ unless a hook has been set.
 Use `filter-buffer-substring' instead of `buffer-substring',
 `buffer-substring-no-properties', or `delete-and-extract-region' when
 you want to allow filtering to take place.  For example, major or minor
-modes can use `filter-buffer-substring-function' to extract characters
+modes can use `filter-buffer-substring-function' to exclude text properties
 that are special to a buffer, and should not be copied into other buffers."
   (funcall filter-buffer-substring-function beg end delete))
 
@@ -5568,8 +5577,10 @@ also checks the value of `use-empty-active-region'."
        (progn (cl-assert (mark)) t)))
 
 (defun region-bounds ()
-  "Return the boundaries of the region as a pair of positions.
-Value is a list of cons cells of the form (START . END)."
+  "Return the boundaries of the region.
+Value is a list of one or more cons cells of the form (START . END).
+It will have more than one cons cell when the region is non-contiguous,
+see `region-noncontiguous-p' and `extract-rectangle-bounds'."
   (funcall region-extract-function 'bounds))
 
 (defun region-noncontiguous-p ()
@@ -7976,7 +7987,7 @@ With a prefix argument, set VARIABLE to VALUE 
buffer-locally."
                   (read-variable (format "Set variable (default %s): " 
default-var)
                                  default-var)
                 (read-variable "Set variable: ")))
-         (minibuffer-help-form '(describe-variable var))
+         (minibuffer-help-form `(describe-variable ',var))
          (prop (get var 'variable-interactive))
           (obsolete (car (get var 'byte-obsolete-variable)))
          (prompt (format "Set %s %s to value: " var
diff --git a/lisp/subr.el b/lisp/subr.el
index b36d952..1d3aa6a 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -4820,7 +4820,7 @@ command is called from a keyboard macro?"
                           i frame nextframe)))
                (pcase skip
                  (`nil nil)
-                 (`0 t)
+                 (0 t)
                  (_ (setq i (+ i skip -1)) (funcall get-next-frame)))))))
       ;; Now `frame' should be "the function from which we were called".
       (pcase (cons frame nextframe)
diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el
index 31ce638..63c8631 100644
--- a/lisp/textmodes/css-mode.el
+++ b/lisp/textmodes/css-mode.el
@@ -1219,7 +1219,7 @@ for determining whether point is within a selector."
     (`(:elem . basic) css-indent-offset)
     (`(:elem . arg) 0)
     ;; "" stands for BOB (bug#15467).
-    (`(:list-intro . ,(or `";" `"" `":-property")) t)
+    (`(:list-intro . ,(or ";" "" ":-property")) t)
     (`(:before . "{")
      (when (or (smie-rule-hanging-p) (smie-rule-bolp))
        (smie-backward-sexp ";")
diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el
index c223af4..8b06777 100644
--- a/lisp/textmodes/tex-mode.el
+++ b/lisp/textmodes/tex-mode.el
@@ -1170,7 +1170,7 @@ subshell is initiated, `tex-shell-hook' is run."
   (setq-local fill-indent-according-to-mode t)
   (add-hook 'completion-at-point-functions
             #'latex-complete-data nil 'local)
-  (add-hook 'flymake-diagnostic-functions 'tex-chktex nil t)
+  (add-hook 'flymake-diagnostic-functions #'tex-chktex nil t)
   (setq-local outline-regexp latex-outline-regexp)
   (setq-local outline-level #'latex-outline-level)
   (setq-local forward-sexp-function #'latex-forward-sexp)
@@ -1261,8 +1261,8 @@ Entering SliTeX mode runs the hook `text-mode-hook', then 
the hook
   (setq-local comment-start-skip
              "\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)\\(%+ *\\)")
   (setq-local parse-sexp-ignore-comments t)
-  (setq-local compare-windows-whitespace 'tex-categorize-whitespace)
-  (setq-local facemenu-add-face-function 'tex-facemenu-add-face-function)
+  (setq-local compare-windows-whitespace #'tex-categorize-whitespace)
+  (setq-local facemenu-add-face-function #'tex-facemenu-add-face-function)
   (setq-local facemenu-end-add-face "}")
   (setq-local facemenu-remove-face-function t)
   (setq-local font-lock-defaults
@@ -1591,7 +1591,7 @@ Puts point on a blank line between them."
 (defvar latex-complete-bibtex-cache nil)
 
 (define-obsolete-function-alias 'latex-string-prefix-p
-  'string-prefix-p "24.3")
+  #'string-prefix-p "24.3")
 
 (defvar bibtex-reference-key)
 (declare-function reftex-get-bibfile-list "reftex-cite.el" ())
@@ -2109,7 +2109,7 @@ If NOT-ALL is non-nil, save the `.dvi' file."
            (delete-file (concat dir (car list))))
           (setq list (cdr list))))))
 
-(add-hook 'kill-emacs-hook 'tex-delete-last-temp-files)
+(add-hook 'kill-emacs-hook #'tex-delete-last-temp-files)
 
 ;;
 ;; Machinery to guess the command that the user wants to execute.
@@ -2168,7 +2168,7 @@ IN can be either a string (with the same % escapes in it) 
indicating
 OUT describes the output file and is either a %-escaped string
   or nil to indicate that there is no output file.")
 
-(define-obsolete-function-alias 'tex-string-prefix-p 'string-prefix-p "24.3")
+(define-obsolete-function-alias 'tex-string-prefix-p #'string-prefix-p "24.3")
 
 (defun tex-guess-main-file (&optional all)
   "Find a likely `tex-main-file'.
@@ -2263,9 +2263,11 @@ FILE is typically the output DVI or PDF file."
                (> (save-excursion
                      ;; Usually page numbers are output as [N], but
                      ;; I've already seen things like
-                     ;; [1{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}]
-                     (or (re-search-backward "\\[[0-9]+\\({[^}]*}\\)?\\]"
-                                             nil t)
+                     ;; [N{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}]
+                     ;; as well as [N.N] (e.g. with 'acmart' style).
+                     (or (re-search-backward
+                          "\\[[0-9]+\\({[^}]*}\\|\\.[0-9]+\\)?\\]"
+                          nil t)
                         (point-min)))
                   (save-excursion
                     (or (re-search-backward "Rerun" nil t)
@@ -2993,7 +2995,7 @@ There might be text before point."
               (lambda (x)
                 (pcase (car-safe x)
                   (`font-lock-syntactic-face-function
-                   (cons (car x) 'doctex-font-lock-syntactic-face-function))
+                   (cons (car x) #'doctex-font-lock-syntactic-face-function))
                   (_ x)))
               (cdr font-lock-defaults))))
   (setq-local syntax-propertize-function
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index 6c189c1..cf52368 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -1341,6 +1341,13 @@ See `after-change-functions' for the meaning of BEG, END 
and LEN."
   (diff-hunk-next arg)
   (diff-goto-source))
 
+(defun diff--font-lock-cleanup ()
+  (remove-overlays nil nil 'diff-mode 'fine)
+  (when font-lock-mode
+    (make-local-variable 'font-lock-extra-managed-props)
+    ;; Added when diff--font-lock-prettify is non-nil!
+    (cl-pushnew 'display font-lock-extra-managed-props)))
+
 (defvar whitespace-style)
 (defvar whitespace-trailing-regexp)
 
@@ -1358,12 +1365,10 @@ You can also switch between context diff and unified 
diff with \\[diff-context->
 or vice versa with \\[diff-unified->context] and you can also reverse the 
direction of
 a diff with \\[diff-reverse-direction].
 
-   \\{diff-mode-map}"
+\\{diff-mode-map}"
 
   (set (make-local-variable 'font-lock-defaults) diff-font-lock-defaults)
-  (add-hook 'font-lock-mode-hook
-            (lambda () (remove-overlays nil nil 'diff-mode 'fine))
-            nil 'local)
+  (add-hook 'font-lock-mode-hook #'diff--font-lock-cleanup nil 'local)
   (set (make-local-variable 'outline-regexp) diff-outline-regexp)
   (set (make-local-variable 'imenu-generic-expression)
        diff-imenu-generic-expression)
@@ -1408,6 +1413,8 @@ a diff with \\[diff-reverse-direction].
        #'diff-current-defun)
   (set (make-local-variable 'add-log-buffer-file-name-function)
        (lambda () (diff-find-file-name nil 'noprompt)))
+  (add-function :filter-return (local 'filter-buffer-substring-function)
+                #'diff--filter-substring)
   (unless (buffer-file-name)
     (hack-dir-local-variables-non-file-buffer)))
 
@@ -2088,6 +2095,7 @@ Return new point, if it was moved."
             (diff--refine-hunk beg end)
             (let ((ol (make-overlay beg end)))
               (overlay-put ol 'diff--font-lock-refined t)
+              (overlay-put ol 'diff-mode 'fine)
               (overlay-put ol 'evaporate t)
               (overlay-put ol 'modification-hooks
                            '(diff--font-lock-refine--refresh))))
@@ -2204,19 +2212,80 @@ fixed, visit it in a buffer."
 
 ;;; Prettifying from font-lock
 
+(define-fringe-bitmap 'diff-fringe-add
+  [#b00000000
+   #b00000000
+   #b00010000
+   #b00010000
+   #b01111100
+   #b00010000
+   #b00010000
+   #b00000000
+   #b00000000]
+  nil nil 'center)
+
+(define-fringe-bitmap 'diff-fringe-del
+  [#b00000000
+   #b00000000
+   #b00000000
+   #b00000000
+   #b01111100
+   #b00000000
+   #b00000000
+   #b00000000
+   #b00000000]
+  nil nil 'center)
+
+(define-fringe-bitmap 'diff-fringe-rep
+  [#b00000000
+   #b00010000
+   #b00010000
+   #b00010000
+   #b00010000
+   #b00010000
+   #b00000000
+   #b00010000
+   #b00000000]
+  nil nil 'center)
+
+(define-fringe-bitmap 'diff-fringe-nul
+  ;; Maybe there should be such an "empty" bitmap defined by default?
+  [#b00000000
+   #b00000000
+   #b00000000
+   #b00000000
+   #b00000000
+   #b00000000
+   #b00000000
+   #b00000000
+   #b00000000]
+  nil nil 'center)
+
 (defun diff--font-lock-prettify (limit)
-  ;; Mimicks the output of Magit's diff.
-  ;; FIXME: This has only been tested with Git's diff output.
   (when diff-font-lock-prettify
+    (save-excursion
+      ;; FIXME: Include the first space for context-style hunks!
+      (while (re-search-forward "^[-+! ]" limit t)
+        (let ((spec (alist-get (char-before)
+                               '((?+ . (left-fringe diff-fringe-add 
diff-added))
+                                 (?- . (left-fringe diff-fringe-del 
diff-removed))
+                                 (?! . (left-fringe diff-fringe-rep 
diff-changed))
+                                 (?\s . (left-fringe diff-fringe-nul))))))
+          (put-text-property (match-beginning 0) (match-end 0) 'display 
spec))))
+    ;; Mimicks the output of Magit's diff.
+    ;; FIXME: This has only been tested with Git's diff output.
     (while (re-search-forward "^diff " limit t)
+      ;; FIXME: Switching between context<->unified leads to messed up
+      ;; file headers by cutting the `display' property in chunks!
       (when (save-excursion
-                  (forward-line 0)
-                  (looking-at (eval-when-compile
-                                (concat "diff.*\n"
-                                        "\\(?:\\(?:new 
file\\|deleted\\).*\n\\)?"
-                                        "\\(?:index.*\n\\)?"
-                                        "--- \\(?:/dev/null\\|a/\\(.*\\)\\)\n"
-                                        "\\+\\+\\+ 
\\(?:/dev/null\\|b/\\(.*\\)\\)\n"))))
+              (forward-line 0)
+              (looking-at
+               (eval-when-compile
+                 (concat "diff.*\n"
+                         "\\(?:\\(?:new file\\|deleted\\).*\n\\)?"
+                         "\\(?:index.*\n\\)?"
+                         "--- \\(?:/dev/null\\|a/\\(.*\\)\\)\n"
+                         "\\+\\+\\+ \\(?:/dev/null\\|b/\\(.*\\)\\)\n"))))
         (put-text-property (match-beginning 0)
                            (or (match-beginning 2) (match-beginning 1))
                            'display (propertize
@@ -2230,6 +2299,28 @@ fixed, visit it in a buffer."
                              'display "")))))
   nil)
 
+(defun diff--filter-substring (str)
+  (when diff-font-lock-prettify
+    ;; Strip the `display' properties added by diff-font-lock-prettify,
+    ;; since they look weird when you kill&yank!
+    (remove-text-properties 0 (length str) '(display nil) str)
+    ;; We could also try to only remove those `display' properties actually
+    ;; added by diff-font-lock-prettify rather than removing them all blindly.
+    ;; E.g.:
+    ;;(let ((len (length str))
+    ;;      (i 0))
+    ;;  (while (and (< i len)
+    ;;              (setq i (text-property-not-all i len 'display nil str)))
+    ;;    (let* ((val (get-text-property i 'display str))
+    ;;           (end (or (text-property-not-all i len 'display val str) len)))
+    ;;      ;; FIXME: Check for display props that prettify the file header!
+    ;;      (when (eq 'left-fringe (car-safe val))
+    ;;        ;; FIXME: Should we check that it's a diff-fringe-* bitmap?
+    ;;        (remove-text-properties i end '(display nil) str))
+    ;;      (setq i end))))
+    )
+  str)
+
 ;;; Support for converting a diff to diff3 markers via `wiggle'.
 
 ;; Wiggle can be found at http://neil.brown.name/wiggle/ or in your nearest
@@ -2255,7 +2346,7 @@ conflict."
           (set-buffer (prog1 tmpbuf (setq tmpbuf (current-buffer))))
           (when (buffer-modified-p filebuf)
             (save-some-buffers nil (lambda () (eq (current-buffer) filebuf)))
-            (if (buffer-modified-p filebuf) (error "Abort!")))
+            (if (buffer-modified-p filebuf) (user-error "Abort!")))
           (write-region (car bounds) (cadr bounds) patchfile nil 'silent)
           (let ((exitcode
                  (call-process "wiggle" nil (list tmpbuf errfile) nil
diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el
index 3696573..d528813 100644
--- a/lisp/vc/vc-hg.el
+++ b/lisp/vc/vc-hg.el
@@ -1142,11 +1142,9 @@ REV is the revision to check out into WORKFILE."
 
 (defun vc-hg-find-file-hook ()
   (when (and buffer-file-name
-             (file-exists-p (concat buffer-file-name ".orig"))
              ;; Hg does not seem to have a "conflict" status, eg
              ;; hg http://bz.selenic.com/show_bug.cgi?id=2724
-             (memq (vc-file-getprop buffer-file-name 'vc-state)
-                   '(edited conflict))
+             (memq (vc-state buffer-file-name) '(edited conflict))
              ;; Maybe go on to check that "hg resolve -l" says "U"?
              ;; If "hg resolve -l" says there's a conflict but there are no
              ;; conflict markers, it's not clear what we should do.
diff --git a/lisp/windmove.el b/lisp/windmove.el
index f565068..42e10b5 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -464,12 +464,7 @@ movement is relative to."
 (defun windmove-find-other-window (dir &optional arg window)
   "Return the window object in direction DIR.
 DIR, ARG, and WINDOW are handled as by `windmove-other-window-loc'."
-  (window-in-direction
-   (cond
-    ((eq dir 'up) 'above)
-    ((eq dir 'down) 'below)
-    (t dir))
-   window nil arg windmove-wrap-around t))
+  (window-in-direction dir window nil arg windmove-wrap-around t))
 
 ;; Selects the window that's hopefully at the location returned by
 ;; `windmove-other-window-loc', or screams if there's no window there.
diff --git a/lisp/window.el b/lisp/window.el
index 8ff8497..bcd4fa2 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -2262,14 +2262,14 @@ SIDE can be any of the symbols `left', `top', `right' or
   "Return window in DIRECTION as seen from WINDOW.
 More precisely, return the nearest window in direction DIRECTION
 as seen from the position of `window-point' in window WINDOW.
-DIRECTION must be one of `above', `below', `left' or `right'.
+DIRECTION should be one of 'above', 'below', 'left' or 'right'.
 WINDOW must be a live window and defaults to the selected one.
 
-Do not return a window whose `no-other-window' parameter is
-non-nil.  If the nearest window's `no-other-window' parameter is
+Do not return a window whose 'no-other-window' parameter is
+non-nil.  If the nearest window's 'no-other-window' parameter is
 non-nil, try to find another window in the indicated direction.
 If, however, the optional argument IGNORE is non-nil, return that
-window even if its `no-other-window' parameter is non-nil.
+window even if its 'no-other-window' parameter is non-nil.
 
 Optional argument SIGN a negative number means to use the right
 or bottom edge of WINDOW as reference position instead of
@@ -2278,7 +2278,7 @@ top edge of WINDOW as reference position.
 
 Optional argument WRAP non-nil means to wrap DIRECTION around
 frame borders.  This means to return for WINDOW at the top of the
-frame and DIRECTION `above' the minibuffer window if the frame
+frame and DIRECTION 'above' the minibuffer window if the frame
 has one, and a window at the bottom of the frame otherwise.
 
 Optional argument MINI nil means to return the minibuffer window
@@ -2288,8 +2288,13 @@ if WRAP is non-nil, always act as if MINI were nil.
 
 Return nil if no suitable window can be found."
   (setq window (window-normalize-window window t))
-  (unless (memq direction '(above below left right))
-    (error "Wrong direction %s" direction))
+  (cond
+   ((eq direction 'up)
+    (setq direction 'above))
+   ((eq direction 'down)
+    (setq direction 'below))
+   ((not (memq direction '(above below left right)))
+    (error "Wrong direction %s" direction)))
   (let* ((frame (window-frame window))
         (hor (memq direction '(left right)))
         (first (if hor
@@ -4912,26 +4917,29 @@ absolute value can be less than `window-min-height' or
 small as one line or two columns.  SIZE defaults to half of
 WINDOW's size.
 
-Optional third argument SIDE nil (or `below') specifies that the
-new window shall be located below WINDOW.  SIDE `above' means the
+Optional third argument SIDE nil (or 'below') specifies that the
+new window shall be located below WINDOW.  SIDE 'above' means the
 new window shall be located above WINDOW.  In both cases SIZE
 specifies the new number of lines for WINDOW (or the new window
 if SIZE is negative) including space reserved for the mode and/or
 header line.
 
-SIDE t (or `right') specifies that the new window shall be
-located on the right side of WINDOW.  SIDE `left' means the new
+SIDE t (or 'right') specifies that the new window shall be
+located on the right side of WINDOW.  SIDE 'left' means the new
 window shall be located on the left of WINDOW.  In both cases
 SIZE specifies the new number of columns for WINDOW (or the new
 window provided SIZE is negative) including space reserved for
-fringes and the scrollbar or a divider column.  Any other non-nil
-value for SIDE is currently handled like t (or `right').
+fringes and the scrollbar or a divider column.
+
+For compatibility reasons, SIDE 'up' and 'down' are interpreted
+as 'above' and 'below'.  Any other non-nil value for SIDE is
+currently handled like t (or 'right').
 
 PIXELWISE, if non-nil, means to interpret SIZE pixelwise.
 
 If the variable `ignore-window-parameters' is non-nil or the
-`split-window' parameter of WINDOW equals t, do not process any
-parameters of WINDOW.  Otherwise, if the `split-window' parameter
+'split-window' parameter of WINDOW equals t, do not process any
+parameters of WINDOW.  Otherwise, if the 'split-window' parameter
 of WINDOW specifies a function, call that function with all three
 arguments and return the value returned by that function.
 
@@ -4947,6 +4955,8 @@ frame.  The selected window is not changed by this 
function."
   (setq window (window-normalize-window window))
   (let* ((side (cond
                ((not side) 'below)
+                ((eq side 'up) 'above)
+                ((eq side 'down) 'below)
                ((memq side '(below above right left)) side)
                (t 'right)))
         (horizontal (not (memq side '(below above))))
@@ -4970,10 +4980,10 @@ frame.  The selected window is not changed by this 
function."
     (catch 'done
       (cond
        ;; Ignore window parameters if either `ignore-window-parameters'
-       ;; is t or the `split-window' parameter equals t.
+       ;; is t or the 'split-window' parameter equals t.
        ((or ignore-window-parameters (eq function t)))
        ((functionp function)
-       ;; The `split-window' parameter specifies the function to call.
+       ;; The 'split-window' parameter specifies the function to call.
        ;; If that function is `ignore', do nothing.
        (throw 'done (funcall function window size side)))
        ;; If WINDOW is part of an atomic window, split the root window
@@ -5006,10 +5016,10 @@ frame.  The selected window is not changed by this 
function."
        (setq window-combination-limit t))
 
       (let* ((parent-pixel-size
-             ;; `parent-pixel-size' is the pixel size of WINDOW's
+             ;; 'parent-pixel-size' is the pixel size of WINDOW's
              ;; parent, provided it has one.
              (when parent (window-size parent horizontal t)))
-            ;; `resize' non-nil means we are supposed to resize other
+            ;; 'resize' non-nil means we are supposed to resize other
             ;; windows in WINDOW's combination.
             (resize
              (and window-combination-resize
@@ -5018,9 +5028,9 @@ frame.  The selected window is not changed by this 
function."
                   (not (eq window-combination-limit t))
                   ;; Resize makes sense in iso-combinations only.
                   (window-combined-p window horizontal)))
-            ;; `old-pixel-size' is the current pixel size of WINDOW.
+            ;; 'old-pixel-size' is the current pixel size of WINDOW.
             (old-pixel-size (window-size window horizontal t))
-            ;; `new-size' is the specified or calculated size of the
+            ;; 'new-size' is the specified or calculated size of the
             ;; new window.
             new-pixel-size new-parent new-normal)
        (cond
@@ -5541,6 +5551,15 @@ specific buffers."
           (t 'leaf)))
         (buffer (window-buffer window))
         (selected (eq window (selected-window)))
+        (next-buffers (when (window-live-p window)
+                        (delq nil (mapcar (lambda (buffer)
+                                             (and (buffer-live-p buffer) 
buffer))
+                                           (window-next-buffers window)))))
+        (prev-buffers (when (window-live-p window)
+                        (delq nil (mapcar (lambda (entry)
+                                             (and (buffer-live-p (nth 0 entry))
+                                                  entry))
+                                           (window-prev-buffers window)))))
         (head
          `(,type
             ,@(unless (window-next-sibling window) `((last . t)))
@@ -5575,7 +5594,7 @@ specific buffers."
                (let ((point (window-point window))
                      (start (window-start window)))
                  `((buffer
-                    ,(buffer-name buffer)
+                    ,(if writable (buffer-name buffer) buffer)
                     (selected . ,selected)
                     (hscroll . ,(window-hscroll window))
                     (fringes . ,(window-fringes window))
@@ -5593,7 +5612,22 @@ specific buffers."
                     (start . ,(if writable
                                    start
                                  (with-current-buffer buffer
-                                   (copy-marker start))))))))))
+                                   (copy-marker start))))))))
+            ,@(when next-buffers
+                `((next-buffers
+                   . ,(if writable
+                          (mapcar (lambda (buffer) (buffer-name buffer))
+                                  next-buffers)
+                        next-buffers))))
+            ,@(when prev-buffers
+                `((prev-buffers
+                   . ,(if writable
+                          (mapcar (lambda (entry)
+                                    (list (buffer-name (nth 0 entry))
+                                          (marker-position (nth 1 entry))
+                                          (marker-position (nth 2 entry))))
+                                  prev-buffers)
+                        prev-buffers))))))
         (tail
          (when (memq type '(vc hc))
            (let (list)
@@ -5736,7 +5770,9 @@ value can be also stored on disk and read back in a new 
session."
     (let ((window (car item))
          (combination-limit (cdr (assq 'combination-limit item)))
          (parameters (cdr (assq 'parameters item)))
-         (state (cdr (assq 'buffer item))))
+         (state (cdr (assq 'buffer item)))
+         (next-buffers (cdr (assq 'next-buffers item)))
+         (prev-buffers (cdr (assq 'prev-buffers item))))
       (when combination-limit
        (set-window-combination-limit window combination-limit))
       ;; Reset window's parameters and assign saved ones (we might want
@@ -5748,7 +5784,8 @@ value can be also stored on disk and read back in a new 
session."
          (set-window-parameter window (car parameter) (cdr parameter))))
       ;; Process buffer related state.
       (when state
-       (let ((buffer (get-buffer (car state))))
+       (let ((buffer (get-buffer (car state)))
+             (state (cdr state)))
          (if buffer
              (with-current-buffer buffer
                (set-window-buffer window buffer)
@@ -5817,7 +5854,30 @@ value can be also stored on disk and read back in a new 
session."
                  (set-window-point window (cdr (assq 'point state))))
                ;; Select window if it's the selected one.
                (when (cdr (assq 'selected state))
-                 (select-window window)))
+                 (select-window window))
+                (when next-buffers
+                  (set-window-next-buffers
+                   window
+                   (delq nil (mapcar (lambda (buffer)
+                                       (setq buffer (get-buffer buffer))
+                                       (when (buffer-live-p buffer) buffer))
+                                     next-buffers))))
+                (when prev-buffers
+                  (set-window-prev-buffers
+                   window
+                   (delq nil (mapcar (lambda (entry)
+                                       (let ((buffer (get-buffer (nth 0 
entry)))
+                                             (m1 (nth 1 entry))
+                                             (m2 (nth 2 entry)))
+                                         (when (buffer-live-p buffer)
+                                           (list buffer
+                                                 (if (markerp m1) m1
+                                                   (set-marker (make-marker) m1
+                                                               buffer))
+                                                 (if (markerp m2) m2
+                                                   (set-marker (make-marker) m2
+                                                               buffer))))))
+                                     prev-buffers)))))
            ;; We don't want to raise an error in case the buffer does
            ;; not exist anymore, so we switch to a previous one and
            ;; save the window with the intention of deleting it later
diff --git a/m4/__inline.m4 b/m4/__inline.m4
new file mode 100644
index 0000000..3d0c479
--- /dev/null
+++ b/m4/__inline.m4
@@ -0,0 +1,22 @@
+# Test for __inline keyword
+dnl Copyright 2017-2018 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl___INLINE],
+[
+  AC_CACHE_CHECK([whether the compiler supports the __inline keyword],
+    [gl_cv_c___inline],
+    [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM(
+         [[typedef int foo_t;
+           static __inline foo_t foo (void) { return 0; }]],
+         [[return foo ();]])],
+       [gl_cv_c___inline=yes],
+       [gl_cv_c___inline=no])])
+  if test $gl_cv_c___inline = yes; then
+    AC_DEFINE([HAVE___INLINE], [1],
+      [Define to 1 if the compiler supports the keyword '__inline'.])
+  fi
+])
diff --git a/m4/environ.m4 b/m4/environ.m4
index 68b67ea..acee536 100644
--- a/m4/environ.m4
+++ b/m4/environ.m4
@@ -1,4 +1,4 @@
-# environ.m4 serial 6
+# environ.m4 serial 7
 dnl Copyright (C) 2001-2004, 2006-2018 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -29,16 +29,14 @@ AC_DEFUN_ONCE([gl_ENVIRON],
 AC_DEFUN([gt_CHECK_VAR_DECL],
 [
   define([gt_cv_var], [gt_cv_var_]$2[_declaration])
-  AC_MSG_CHECKING([if $2 is properly declared])
-  AC_CACHE_VAL([gt_cv_var], [
-    AC_COMPILE_IFELSE(
-      [AC_LANG_PROGRAM(
-         [[$1
-           extern struct { int foo; } $2;]],
-         [[$2.foo = 1;]])],
-      [gt_cv_var=no],
-      [gt_cv_var=yes])])
-  AC_MSG_RESULT([$gt_cv_var])
+  AC_CACHE_CHECK([if $2 is properly declared], [gt_cv_var],
+    [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM(
+          [[$1
+            extern struct { int foo; } $2;]],
+          [[$2.foo = 1;]])],
+       [gt_cv_var=no],
+       [gt_cv_var=yes])])
   if test $gt_cv_var = yes; then
     AC_DEFINE([HAVE_]m4_translit($2, [a-z], [A-Z])[_DECL], 1,
               [Define if you have the declaration of $2.])
diff --git a/m4/fsusage.m4 b/m4/fsusage.m4
index f9dfbcb..aab4024 100644
--- a/m4/fsusage.m4
+++ b/m4/fsusage.m4
@@ -1,4 +1,4 @@
-# serial 32
+# serial 33
 # Obtaining file system usage information.
 
 # Copyright (C) 1997-1998, 2000-2001, 2003-2018 Free Software Foundation, Inc.
@@ -29,27 +29,30 @@ AC_DEFUN([gl_FSUSAGE],
 
 AC_DEFUN([gl_FILE_SYSTEM_USAGE],
 [
-dnl Enable large-file support. This has the effect of changing the size
-dnl of field f_blocks in 'struct statvfs' from 32 bit to 64 bit on
-dnl glibc/Hurd, HP-UX 11, Solaris (32-bit mode). It also changes the size
-dnl of field f_blocks in 'struct statfs' from 32 bit to 64 bit on
-dnl Mac OS X >= 10.5 (32-bit mode).
-AC_REQUIRE([AC_SYS_LARGEFILE])
+  dnl Enable large-file support. This has the effect of changing the size
+  dnl of field f_blocks in 'struct statvfs' from 32 bit to 64 bit on
+  dnl glibc/Hurd, HP-UX 11, Solaris (32-bit mode). It also changes the size
+  dnl of field f_blocks in 'struct statfs' from 32 bit to 64 bit on
+  dnl Mac OS X >= 10.5 (32-bit mode).
+  AC_REQUIRE([AC_SYS_LARGEFILE])
 
-AC_MSG_CHECKING([how to get file system space usage])
-ac_fsusage_space=no
+  AC_MSG_CHECKING([how to get file system space usage])
+  ac_fsusage_space=no
 
-# Perform only the link test since it seems there are no variants of the
-# statvfs function.  This check is more than just AC_CHECK_FUNCS([statvfs])
-# because that got a false positive on SCO OSR5.  Adding the declaration
-# of a 'struct statvfs' causes this test to fail (as it should) on such
-# systems.  That system is reported to work fine with STAT_STATFS4 which
-# is what it gets when this test fails.
-if test $ac_fsusage_space = no; then
-  # glibc/{Hurd,kFreeBSD}, FreeBSD >= 5.0, NetBSD >= 3.0,
-  # OpenBSD >= 4.4, AIX, HP-UX, IRIX, Solaris, Cygwin, Interix, BeOS.
-  AC_CACHE_CHECK([for statvfs function (SVR4)], [fu_cv_sys_stat_statvfs],
-                 [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
+  # Perform only the link test since it seems there are no variants of the
+  # statvfs function.  This check is more than just AC_CHECK_FUNCS([statvfs])
+  # because that got a false positive on SCO OSR5.  Adding the declaration
+  # of a 'struct statvfs' causes this test to fail (as it should) on such
+  # systems.  That system is reported to work fine with STAT_STATFS4 which
+  # is what it gets when this test fails.
+  if test $ac_fsusage_space = no; then
+    # glibc/{Hurd,kFreeBSD}, FreeBSD >= 5.0, NetBSD >= 3.0,
+    # OpenBSD >= 4.4, AIX, HP-UX, IRIX, Solaris, Cygwin, Interix, BeOS.
+    AC_CACHE_CHECK([for statvfs function (SVR4)],
+      [fu_cv_sys_stat_statvfs],
+      [AC_LINK_IFELSE(
+         [AC_LANG_PROGRAM([[
+#include <sys/types.h>
 #ifdef __osf__
 "Do not use Tru64's statvfs implementation"
 #endif
@@ -68,45 +71,47 @@ struct statvfs fsd;
 int check_f_blocks_size[sizeof fsd.f_blocks * CHAR_BIT <= 32 ? -1 : 1];
 #endif
 ]],
-                                    [[statvfs (0, &fsd);]])],
-                                 [fu_cv_sys_stat_statvfs=yes],
-                                 [fu_cv_sys_stat_statvfs=no])])
-  if test $fu_cv_sys_stat_statvfs = yes; then
-    ac_fsusage_space=yes
-    # AIX >= 5.2 has statvfs64 that has a wider f_blocks field than statvfs.
-    # glibc, HP-UX, IRIX, Solaris have statvfs64 as well, but on these systems
-    # statvfs with large-file support is already equivalent to statvfs64.
-    AC_CACHE_CHECK([whether to use statvfs64],
-      [fu_cv_sys_stat_statvfs64],
-      [AC_LINK_IFELSE(
-         [AC_LANG_PROGRAM(
-            [[#include <sys/types.h>
-              #include <sys/statvfs.h>
-              struct statvfs64 fsd;
-              int check_f_blocks_larger_in_statvfs64
-                [sizeof (((struct statvfs64 *) 0)->f_blocks)
-                 > sizeof (((struct statvfs *) 0)->f_blocks)
-                 ? 1 : -1];
-            ]],
-            [[statvfs64 (0, &fsd);]])],
-         [fu_cv_sys_stat_statvfs64=yes],
-         [fu_cv_sys_stat_statvfs64=no])
+            [[statvfs (0, &fsd);]])],
+         [fu_cv_sys_stat_statvfs=yes],
+         [fu_cv_sys_stat_statvfs=no])
       ])
-    if test $fu_cv_sys_stat_statvfs64 = yes; then
-      AC_DEFINE([STAT_STATVFS64], [1],
-                [  Define if statvfs64 should be preferred over statvfs.])
-    else
-      AC_DEFINE([STAT_STATVFS], [1],
-                [  Define if there is a function named statvfs.  (SVR4)])
+    if test $fu_cv_sys_stat_statvfs = yes; then
+      ac_fsusage_space=yes
+      # AIX >= 5.2 has statvfs64 that has a wider f_blocks field than statvfs.
+      # glibc, HP-UX, IRIX, Solaris have statvfs64 as well, but on these 
systems
+      # statvfs with large-file support is already equivalent to statvfs64.
+      AC_CACHE_CHECK([whether to use statvfs64],
+        [fu_cv_sys_stat_statvfs64],
+        [AC_LINK_IFELSE(
+           [AC_LANG_PROGRAM(
+              [[#include <sys/types.h>
+                #include <sys/statvfs.h>
+                struct statvfs64 fsd;
+                int check_f_blocks_larger_in_statvfs64
+                  [sizeof (((struct statvfs64 *) 0)->f_blocks)
+                   > sizeof (((struct statvfs *) 0)->f_blocks)
+                   ? 1 : -1];
+              ]],
+              [[statvfs64 (0, &fsd);]])],
+           [fu_cv_sys_stat_statvfs64=yes],
+           [fu_cv_sys_stat_statvfs64=no])
+        ])
+      if test $fu_cv_sys_stat_statvfs64 = yes; then
+        AC_DEFINE([STAT_STATVFS64], [1],
+          [Define if statvfs64 should be preferred over statvfs.])
+      else
+        AC_DEFINE([STAT_STATVFS], [1],
+          [Define if there is a function named statvfs.  (SVR4)])
+      fi
     fi
   fi
-fi
 
-# Check for this unconditionally so we have a
-# good fallback on glibc/Linux > 2.6 < 2.6.36
-AC_MSG_CHECKING([for two-argument statfs with statfs.f_frsize member])
-AC_CACHE_VAL([fu_cv_sys_stat_statfs2_frsize],
-[AC_RUN_IFELSE([AC_LANG_SOURCE([[
+  # Check for this unconditionally so we have a
+  # good fallback on glibc/Linux > 2.6 < 2.6.36
+  AC_CACHE_CHECK([for two-argument statfs with statfs.f_frsize member],
+    [fu_cv_sys_stat_statfs2_frsize],
+    [AC_RUN_IFELSE(
+       [AC_LANG_SOURCE([[
 #ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
 #endif
@@ -119,26 +124,26 @@ AC_CACHE_VAL([fu_cv_sys_stat_statfs2_frsize],
   int
   main ()
   {
-  struct statfs fsd;
-  fsd.f_frsize = 0;
-  return statfs (".", &fsd) != 0;
+    struct statfs fsd;
+    fsd.f_frsize = 0;
+    return statfs (".", &fsd) != 0;
   }]])],
-  [fu_cv_sys_stat_statfs2_frsize=yes],
-  [fu_cv_sys_stat_statfs2_frsize=no],
-  [fu_cv_sys_stat_statfs2_frsize=no])])
-AC_MSG_RESULT([$fu_cv_sys_stat_statfs2_frsize])
-if test $fu_cv_sys_stat_statfs2_frsize = yes; then
+       [fu_cv_sys_stat_statfs2_frsize=yes],
+       [fu_cv_sys_stat_statfs2_frsize=no],
+       [fu_cv_sys_stat_statfs2_frsize=no])
+    ])
+  if test $fu_cv_sys_stat_statfs2_frsize = yes; then
     ac_fsusage_space=yes
     AC_DEFINE([STAT_STATFS2_FRSIZE], [1],
-[  Define if statfs takes 2 args and struct statfs has a field named f_frsize.
-   (glibc/Linux > 2.6)])
-fi
+      [Define if statfs takes 2 args and struct statfs has a field named 
f_frsize.
+       (glibc/Linux > 2.6)])
+  fi
 
-if test $ac_fsusage_space = no; then
-  # DEC Alpha running OSF/1
-  AC_MSG_CHECKING([for 3-argument statfs function (DEC OSF/1)])
-  AC_CACHE_VAL([fu_cv_sys_stat_statfs3_osf1],
-  [AC_RUN_IFELSE([AC_LANG_SOURCE([[
+  if test $ac_fsusage_space = no; then
+    # DEC Alpha running OSF/1
+    AC_CACHE_CHECK([for 3-argument statfs function (DEC OSF/1)],
+      [fu_cv_sys_stat_statfs3_osf1],
+      [AC_RUN_IFELSE([AC_LANG_SOURCE([[
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/mount.h>
@@ -149,28 +154,27 @@ if test $ac_fsusage_space = no; then
     fsd.f_fsize = 0;
     return statfs (".", &fsd, sizeof (struct statfs)) != 0;
   }]])],
-    [fu_cv_sys_stat_statfs3_osf1=yes],
-    [fu_cv_sys_stat_statfs3_osf1=no],
-    [fu_cv_sys_stat_statfs3_osf1=no])])
-  AC_MSG_RESULT([$fu_cv_sys_stat_statfs3_osf1])
-  if test $fu_cv_sys_stat_statfs3_osf1 = yes; then
-    ac_fsusage_space=yes
-    AC_DEFINE([STAT_STATFS3_OSF1], [1],
-              [   Define if  statfs takes 3 args.  (DEC Alpha running OSF/1)])
+         [fu_cv_sys_stat_statfs3_osf1=yes],
+         [fu_cv_sys_stat_statfs3_osf1=no],
+         [fu_cv_sys_stat_statfs3_osf1=no])
+      ])
+    if test $fu_cv_sys_stat_statfs3_osf1 = yes; then
+      ac_fsusage_space=yes
+      AC_DEFINE([STAT_STATFS3_OSF1], [1],
+        [Define if statfs takes 3 args.  (DEC Alpha running OSF/1)])
+    fi
   fi
-fi
 
-if test $ac_fsusage_space = no; then
-  # glibc/Linux, Mac OS X, FreeBSD < 5.0, NetBSD < 3.0, OpenBSD < 4.4.
-  # (glibc/{Hurd,kFreeBSD}, FreeBSD >= 5.0, NetBSD >= 3.0,
-  # OpenBSD >= 4.4, AIX, HP-UX, OSF/1, Cygwin already handled above.)
-  # (On IRIX you need to include <sys/statfs.h>, not only <sys/mount.h> and
-  # <sys/vfs.h>.)
-  # (On Solaris, statfs has 4 arguments.)
-  AC_MSG_CHECKING([for two-argument statfs with statfs.f_bsize dnl
-member (AIX, 4.3BSD)])
-  AC_CACHE_VAL([fu_cv_sys_stat_statfs2_bsize],
-  [AC_RUN_IFELSE([AC_LANG_SOURCE([[
+  if test $ac_fsusage_space = no; then
+    # glibc/Linux, Mac OS X, FreeBSD < 5.0, NetBSD < 3.0, OpenBSD < 4.4.
+    # (glibc/{Hurd,kFreeBSD}, FreeBSD >= 5.0, NetBSD >= 3.0,
+    # OpenBSD >= 4.4, AIX, HP-UX, OSF/1, Cygwin already handled above.)
+    # (On IRIX you need to include <sys/statfs.h>, not only <sys/mount.h> and
+    # <sys/vfs.h>.)
+    # (On Solaris, statfs has 4 arguments.)
+    AC_CACHE_CHECK([for two-argument statfs with statfs.f_bsize member (AIX, 
4.3BSD)],
+      [fu_cv_sys_stat_statfs2_bsize],
+      [AC_RUN_IFELSE([AC_LANG_SOURCE([[
 #ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
 #endif
@@ -183,57 +187,56 @@ member (AIX, 4.3BSD)])
   int
   main ()
   {
-  struct statfs fsd;
-  fsd.f_bsize = 0;
-  return statfs (".", &fsd) != 0;
+    struct statfs fsd;
+    fsd.f_bsize = 0;
+    return statfs (".", &fsd) != 0;
   }]])],
-    [fu_cv_sys_stat_statfs2_bsize=yes],
-    [fu_cv_sys_stat_statfs2_bsize=no],
-    [fu_cv_sys_stat_statfs2_bsize=no])])
-  AC_MSG_RESULT([$fu_cv_sys_stat_statfs2_bsize])
-  if test $fu_cv_sys_stat_statfs2_bsize = yes; then
-    ac_fsusage_space=yes
-    AC_DEFINE([STAT_STATFS2_BSIZE], [1],
-[  Define if statfs takes 2 args and struct statfs has a field named f_bsize.
-   (4.3BSD, SunOS 4, HP-UX, AIX PS/2)])
+         [fu_cv_sys_stat_statfs2_bsize=yes],
+         [fu_cv_sys_stat_statfs2_bsize=no],
+         [fu_cv_sys_stat_statfs2_bsize=no])
+      ])
+    if test $fu_cv_sys_stat_statfs2_bsize = yes; then
+      ac_fsusage_space=yes
+      AC_DEFINE([STAT_STATFS2_BSIZE], [1],
+        [Define if statfs takes 2 args and struct statfs has a field named 
f_bsize.
+         (4.3BSD, SunOS 4, HP-UX, AIX PS/2)])
+    fi
   fi
-fi
 
-if test $ac_fsusage_space = no; then
-  # SVR3
-  # (Solaris already handled above.)
-  AC_MSG_CHECKING([for four-argument statfs (AIX-3.2.5, SVR3)])
-  AC_CACHE_VAL([fu_cv_sys_stat_statfs4],
-  [AC_RUN_IFELSE([AC_LANG_SOURCE([[
+  if test $ac_fsusage_space = no; then
+    # SVR3
+    # (Solaris already handled above.)
+    AC_CACHE_CHECK([for four-argument statfs (AIX-3.2.5, SVR3)],
+      [fu_cv_sys_stat_statfs4],
+      [AC_RUN_IFELSE([AC_LANG_SOURCE([[
 #include <sys/types.h>
 #include <sys/statfs.h>
   int
   main ()
   {
-  struct statfs fsd;
-  return statfs (".", &fsd, sizeof fsd, 0) != 0;
+    struct statfs fsd;
+    return statfs (".", &fsd, sizeof fsd, 0) != 0;
   }]])],
-    [fu_cv_sys_stat_statfs4=yes],
-    [fu_cv_sys_stat_statfs4=no],
-    [fu_cv_sys_stat_statfs4=no])])
-  AC_MSG_RESULT([$fu_cv_sys_stat_statfs4])
-  if test $fu_cv_sys_stat_statfs4 = yes; then
-    ac_fsusage_space=yes
-    AC_DEFINE([STAT_STATFS4], [1],
-      [  Define if statfs takes 4 args.  (SVR3, Dynix, old Irix, old AIX, 
Dolphin)])
+         [fu_cv_sys_stat_statfs4=yes],
+         [fu_cv_sys_stat_statfs4=no],
+         [fu_cv_sys_stat_statfs4=no])
+      ])
+    if test $fu_cv_sys_stat_statfs4 = yes; then
+      ac_fsusage_space=yes
+      AC_DEFINE([STAT_STATFS4], [1],
+        [Define if statfs takes 4 args.  (SVR3, Dynix, old Irix, old AIX, 
Dolphin)])
+    fi
   fi
-fi
 
-if test $ac_fsusage_space = no; then
-  # 4.4BSD and older NetBSD
-  # (OSF/1 already handled above.)
-  # (On AIX, you need to include <sys/statfs.h>, not only <sys/mount.h>.)
-  # (On Solaris, statfs has 4 arguments and 'struct statfs' is not declared in
-  # <sys/mount.h>.)
-  AC_MSG_CHECKING([for two-argument statfs with statfs.f_fsize dnl
-member (4.4BSD and NetBSD)])
-  AC_CACHE_VAL([fu_cv_sys_stat_statfs2_fsize],
-  [AC_RUN_IFELSE([AC_LANG_SOURCE([[
+  if test $ac_fsusage_space = no; then
+    # 4.4BSD and older NetBSD
+    # (OSF/1 already handled above.)
+    # (On AIX, you need to include <sys/statfs.h>, not only <sys/mount.h>.)
+    # (On Solaris, statfs has 4 arguments and 'struct statfs' is not declared 
in
+    # <sys/mount.h>.)
+    AC_CACHE_CHECK([for two-argument statfs with statfs.f_fsize member (4.4BSD 
and NetBSD)],
+      [fu_cv_sys_stat_statfs2_fsize],
+      [AC_RUN_IFELSE([AC_LANG_SOURCE([[
 #include <sys/types.h>
 #ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
@@ -244,27 +247,27 @@ member (4.4BSD and NetBSD)])
   int
   main ()
   {
-  struct statfs fsd;
-  fsd.f_fsize = 0;
-  return statfs (".", &fsd) != 0;
+    struct statfs fsd;
+    fsd.f_fsize = 0;
+    return statfs (".", &fsd) != 0;
   }]])],
-    [fu_cv_sys_stat_statfs2_fsize=yes],
-    [fu_cv_sys_stat_statfs2_fsize=no],
-    [fu_cv_sys_stat_statfs2_fsize=no])])
-  AC_MSG_RESULT([$fu_cv_sys_stat_statfs2_fsize])
-  if test $fu_cv_sys_stat_statfs2_fsize = yes; then
-    ac_fsusage_space=yes
-    AC_DEFINE([STAT_STATFS2_FSIZE], [1],
-[  Define if statfs takes 2 args and struct statfs has a field named f_fsize.
-   (4.4BSD, NetBSD)])
+         [fu_cv_sys_stat_statfs2_fsize=yes],
+         [fu_cv_sys_stat_statfs2_fsize=no],
+         [fu_cv_sys_stat_statfs2_fsize=no])
+      ])
+    if test $fu_cv_sys_stat_statfs2_fsize = yes; then
+      ac_fsusage_space=yes
+      AC_DEFINE([STAT_STATFS2_FSIZE], [1],
+        [Define if statfs takes 2 args and struct statfs has a field named 
f_fsize.
+         (4.4BSD, NetBSD)])
+    fi
   fi
-fi
 
-if test $ac_fsusage_space = no; then
-  # Ultrix
-  AC_MSG_CHECKING([for two-argument statfs with struct fs_data (Ultrix)])
-  AC_CACHE_VAL([fu_cv_sys_stat_fs_data],
-  [AC_RUN_IFELSE([AC_LANG_SOURCE([[
+  if test $ac_fsusage_space = no; then
+    # Ultrix
+    AC_CACHE_CHECK([for two-argument statfs with struct fs_data (Ultrix)],
+      [fu_cv_sys_stat_fs_data],
+      [AC_RUN_IFELSE([AC_LANG_SOURCE([[
 #include <sys/types.h>
 #ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
@@ -278,24 +281,24 @@ if test $ac_fsusage_space = no; then
   int
   main ()
   {
-  struct fs_data fsd;
-  /* Ultrix's statfs returns 1 for success,
-     0 for not mounted, -1 for failure.  */
-  return statfs (".", &fsd) != 1;
+    struct fs_data fsd;
+    /* Ultrix's statfs returns 1 for success,
+       0 for not mounted, -1 for failure.  */
+    return statfs (".", &fsd) != 1;
   }]])],
-    [fu_cv_sys_stat_fs_data=yes],
-    [fu_cv_sys_stat_fs_data=no],
-    [fu_cv_sys_stat_fs_data=no])])
-  AC_MSG_RESULT([$fu_cv_sys_stat_fs_data])
-  if test $fu_cv_sys_stat_fs_data = yes; then
-    ac_fsusage_space=yes
-    AC_DEFINE([STAT_STATFS2_FS_DATA], [1],
-[  Define if statfs takes 2 args and the second argument has
-   type struct fs_data.  (Ultrix)])
+         [fu_cv_sys_stat_fs_data=yes],
+         [fu_cv_sys_stat_fs_data=no],
+         [fu_cv_sys_stat_fs_data=no])
+      ])
+    if test $fu_cv_sys_stat_fs_data = yes; then
+      ac_fsusage_space=yes
+      AC_DEFINE([STAT_STATFS2_FS_DATA], [1],
+        [Define if statfs takes 2 args and the second argument has
+         type struct fs_data.  (Ultrix)])
+    fi
   fi
-fi
 
-AS_IF([test $ac_fsusage_space = yes], [$1], [$2])
+  AS_IF([test $ac_fsusage_space = yes], [$1], [$2])
 
 ])
 
@@ -305,18 +308,22 @@ AS_IF([test $ac_fsusage_space = yes], [$1], [$2])
 # enable the work-around code in fsusage.c.
 AC_DEFUN([gl_STATFS_TRUNCATES],
 [
-  AC_MSG_CHECKING([for statfs that truncates block counts])
-  AC_CACHE_VAL([fu_cv_sys_truncating_statfs],
-  [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+  AC_CACHE_CHECK([for statfs that truncates block counts],
+    [fu_cv_sys_truncating_statfs],
+    [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM([[
 #if !defined(sun) && !defined(__sun)
 choke -- this is a workaround for a Sun-specific problem
 #endif
 #include <sys/types.h>
-#include <sys/vfs.h>]],
-      [[struct statfs t; long c = *(t.f_spare);
-        if (c) return 0;]])],
-    [fu_cv_sys_truncating_statfs=yes],
-    [fu_cv_sys_truncating_statfs=no])])
+#include <sys/vfs.h>
+         ]],
+         [[struct statfs t; long c = *(t.f_spare);
+           if (c) return 0;
+         ]])],
+       [fu_cv_sys_truncating_statfs=yes],
+       [fu_cv_sys_truncating_statfs=no])
+    ])
   if test $fu_cv_sys_truncating_statfs = yes; then
     AC_DEFINE([STATFS_TRUNCATES_BLOCK_COUNTS], [1],
       [Define if the block counts reported by statfs may be truncated to 2GB
@@ -324,7 +331,6 @@ choke -- this is a workaround for a Sun-specific problem
        (SunOS 4.1.2, 4.1.3, and 4.1.3_U1 are reported to have this problem.
        SunOS 4.1.1 seems not to be affected.)])
   fi
-  AC_MSG_RESULT([$fu_cv_sys_truncating_statfs])
 ])
 
 
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 61aabaa..74f2817 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -109,6 +109,7 @@ AC_DEFUN([gl_EARLY],
   # Code from module inttypes-incomplete:
   # Code from module largefile:
   AC_REQUIRE([AC_SYS_LARGEFILE])
+  # Code from module libc-config:
   # Code from module limits-h:
   # Code from module localtime-buffer:
   # Code from module lstat:
@@ -441,6 +442,7 @@ AC_DEFUN([gl_INIT],
   gl_gnulib_enabled_getgroups=false
   gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=false
   gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1=false
+  gl_gnulib_enabled_21ee726a3540c09237a8e70c0baf7467=false
   gl_gnulib_enabled_2049e887c7e5308faad27b3f894bb8c9=false
   gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31=false
   gl_gnulib_enabled_open=false
@@ -554,6 +556,13 @@ AC_DEFUN([gl_INIT],
       fi
     fi
   }
+  func_gl_gnulib_m4code_21ee726a3540c09237a8e70c0baf7467 ()
+  {
+    if ! $gl_gnulib_enabled_21ee726a3540c09237a8e70c0baf7467; then
+      gl___INLINE
+      gl_gnulib_enabled_21ee726a3540c09237a8e70c0baf7467=true
+    fi
+  }
   func_gl_gnulib_m4code_2049e887c7e5308faad27b3f894bb8c9 ()
   {
     if ! $gl_gnulib_enabled_2049e887c7e5308faad27b3f894bb8c9; then
@@ -669,6 +678,9 @@ AC_DEFUN([gl_INIT],
   if test $ac_use_included_regex = yes; then
     func_gl_gnulib_m4code_37f71b604aa9c54446783d80f42fe547
   fi
+  if test $ac_use_included_regex = yes; then
+    func_gl_gnulib_m4code_21ee726a3540c09237a8e70c0baf7467
+  fi
   if { test $HAVE_DECL_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1; } && test 
$ac_cv_type_long_long_int = yes; then
     func_gl_gnulib_m4code_strtoll
   fi
@@ -686,6 +698,7 @@ AC_DEFUN([gl_INIT],
   AM_CONDITIONAL([gl_GNULIB_ENABLED_getgroups], [$gl_gnulib_enabled_getgroups])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36], 
[$gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1], 
[$gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1])
+  AM_CONDITIONAL([gl_GNULIB_ENABLED_21ee726a3540c09237a8e70c0baf7467], 
[$gl_gnulib_enabled_21ee726a3540c09237a8e70c0baf7467])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_2049e887c7e5308faad27b3f894bb8c9], 
[$gl_gnulib_enabled_2049e887c7e5308faad27b3f894bb8c9])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_5264294aa0a5557541b53c8c741f7f31], 
[$gl_gnulib_enabled_5264294aa0a5557541b53c8c741f7f31])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_open], [$gl_gnulib_enabled_open])
@@ -858,6 +871,7 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/c-strncasecmp.c
   lib/careadlinkat.c
   lib/careadlinkat.h
+  lib/cdefs.h
   lib/cloexec.c
   lib/cloexec.h
   lib/close-stream.c
@@ -920,6 +934,7 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/ignore-value.h
   lib/intprops.h
   lib/inttypes.in.h
+  lib/libc-config.h
   lib/limits.in.h
   lib/localtime-buffer.c
   lib/localtime-buffer.h
@@ -1002,6 +1017,7 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/warn-on-use.h
   lib/xalloc-oversized.h
   m4/00gnulib.m4
+  m4/__inline.m4
   m4/absolute-header.m4
   m4/acl.m4
   m4/alloca.m4
diff --git a/m4/manywarnings.m4 b/m4/manywarnings.m4
index 516c587..d831ed2 100644
--- a/m4/manywarnings.m4
+++ b/m4/manywarnings.m4
@@ -1,4 +1,4 @@
-# manywarnings.m4 serial 16
+# manywarnings.m4 serial 17
 dnl Copyright (C) 2008-2018 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -51,54 +51,53 @@ m4_defun([gl_MANYWARN_ALL_GCC(C)],
 
     dnl Check if -W -Werror -Wno-missing-field-initializers is supported
     dnl with the current $CC $CFLAGS $CPPFLAGS.
-    AC_MSG_CHECKING([whether -Wno-missing-field-initializers is supported])
-    AC_CACHE_VAL([gl_cv_cc_nomfi_supported], [
-      gl_save_CFLAGS="$CFLAGS"
-      CFLAGS="$CFLAGS -W -Werror -Wno-missing-field-initializers"
-      AC_COMPILE_IFELSE(
-        [AC_LANG_PROGRAM([[]], [[]])],
-        [gl_cv_cc_nomfi_supported=yes],
-        [gl_cv_cc_nomfi_supported=no])
-      CFLAGS="$gl_save_CFLAGS"])
-    AC_MSG_RESULT([$gl_cv_cc_nomfi_supported])
+    AC_CACHE_CHECK([whether -Wno-missing-field-initializers is supported],
+      [gl_cv_cc_nomfi_supported],
+      [gl_save_CFLAGS="$CFLAGS"
+       CFLAGS="$CFLAGS -W -Werror -Wno-missing-field-initializers"
+       AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM([[]], [[]])],
+         [gl_cv_cc_nomfi_supported=yes],
+         [gl_cv_cc_nomfi_supported=no])
+       CFLAGS="$gl_save_CFLAGS"
+      ])
 
     if test "$gl_cv_cc_nomfi_supported" = yes; then
       dnl Now check whether -Wno-missing-field-initializers is needed
       dnl for the { 0, } construct.
-      AC_MSG_CHECKING([whether -Wno-missing-field-initializers is needed])
-      AC_CACHE_VAL([gl_cv_cc_nomfi_needed], [
-        gl_save_CFLAGS="$CFLAGS"
-        CFLAGS="$CFLAGS -W -Werror"
-        AC_COMPILE_IFELSE(
-          [AC_LANG_PROGRAM(
-             [[int f (void)
-               {
-                 typedef struct { int a; int b; } s_t;
-                 s_t s1 = { 0, };
-                 return s1.b;
-               }
-             ]],
-             [[]])],
-          [gl_cv_cc_nomfi_needed=no],
-          [gl_cv_cc_nomfi_needed=yes])
-        CFLAGS="$gl_save_CFLAGS"
-      ])
-      AC_MSG_RESULT([$gl_cv_cc_nomfi_needed])
+      AC_CACHE_CHECK([whether -Wno-missing-field-initializers is needed],
+        [gl_cv_cc_nomfi_needed],
+        [gl_save_CFLAGS="$CFLAGS"
+         CFLAGS="$CFLAGS -W -Werror"
+         AC_COMPILE_IFELSE(
+           [AC_LANG_PROGRAM(
+              [[int f (void)
+                {
+                  typedef struct { int a; int b; } s_t;
+                  s_t s1 = { 0, };
+                  return s1.b;
+                }
+              ]],
+              [[]])],
+           [gl_cv_cc_nomfi_needed=no],
+           [gl_cv_cc_nomfi_needed=yes])
+         CFLAGS="$gl_save_CFLAGS"
+        ])
     fi
 
     dnl Next, check if -Werror -Wuninitialized is useful with the
     dnl user's choice of $CFLAGS; some versions of gcc warn that it
     dnl has no effect if -O is not also used
-    AC_MSG_CHECKING([whether -Wuninitialized is supported])
-    AC_CACHE_VAL([gl_cv_cc_uninitialized_supported], [
-      gl_save_CFLAGS="$CFLAGS"
-      CFLAGS="$CFLAGS -Werror -Wuninitialized"
-      AC_COMPILE_IFELSE(
-        [AC_LANG_PROGRAM([[]], [[]])],
-        [gl_cv_cc_uninitialized_supported=yes],
-        [gl_cv_cc_uninitialized_supported=no])
-      CFLAGS="$gl_save_CFLAGS"])
-    AC_MSG_RESULT([$gl_cv_cc_uninitialized_supported])
+    AC_CACHE_CHECK([whether -Wuninitialized is supported],
+      [gl_cv_cc_uninitialized_supported],
+      [gl_save_CFLAGS="$CFLAGS"
+       CFLAGS="$CFLAGS -Werror -Wuninitialized"
+       AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM([[]], [[]])],
+         [gl_cv_cc_uninitialized_supported=yes],
+         [gl_cv_cc_uninitialized_supported=no])
+       CFLAGS="$gl_save_CFLAGS"
+      ])
 
   fi
 
diff --git a/m4/socklen.m4 b/m4/socklen.m4
index f2d996d..fa79b07 100644
--- a/m4/socklen.m4
+++ b/m4/socklen.m4
@@ -1,4 +1,4 @@
-# socklen.m4 serial 10
+# socklen.m4 serial 11
 dnl Copyright (C) 2005-2007, 2009-2018 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -15,8 +15,8 @@ dnl So we have to test to find something that will work.
 AC_DEFUN([gl_TYPE_SOCKLEN_T],
   [AC_REQUIRE([gl_CHECK_SOCKET_HEADERS])dnl
    AC_CHECK_TYPE([socklen_t], ,
-     [AC_MSG_CHECKING([for socklen_t equivalent])
-      AC_CACHE_VAL([gl_cv_socklen_t_equiv],
+     [AC_CACHE_CHECK([for socklen_t equivalent],
+        [gl_cv_socklen_t_equiv],
         [# Systems have either "struct sockaddr *" or
          # "void *" as the second argument to getpeername
          gl_cv_socklen_t_equiv=
@@ -34,11 +34,10 @@ AC_DEFUN([gl_TYPE_SOCKLEN_T],
            done
            test "$gl_cv_socklen_t_equiv" != "" && break
          done
-      ])
-      if test "$gl_cv_socklen_t_equiv" = ""; then
-        AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
-      fi
-      AC_MSG_RESULT([$gl_cv_socklen_t_equiv])
+         if test "$gl_cv_socklen_t_equiv" = ""; then
+           AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
+         fi
+        ])
       AC_DEFINE_UNQUOTED([socklen_t], [$gl_cv_socklen_t_equiv],
         [type to use in place of socklen_t if not defined])],
      [gl_SOCKET_HEADERS])])
diff --git a/nextstep/templates/Info.plist.in b/nextstep/templates/Info.plist.in
index 9960f08..406d6f7 100644
--- a/nextstep/templates/Info.plist.in
+++ b/nextstep/templates/Info.plist.in
@@ -675,5 +675,7 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.
        </array>
        <key>NSAppleScriptEnabled</key>
        <string>YES</string>
+        <key>NSAppleEventsUsageDescription</key>
+        <string>Emacs requires permission to send AppleEvents to other 
applications.</string>
 </dict>
 </plist>
diff --git a/src/alloc.c b/src/alloc.c
index 3b15079..0e48b33 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -5863,6 +5863,8 @@ garbage_collect_1 (void *end)
   VECTOR_UNMARK (&buffer_defaults);
   VECTOR_UNMARK (&buffer_local_symbols);
 
+  unmark_main_thread ();
+
   check_cons_list ();
 
   gc_in_progress = 0;
diff --git a/src/buffer.c b/src/buffer.c
index 024e64f..ac2de7d 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -3991,6 +3991,16 @@ buffer.  */)
 
       unchain_both (ob, overlay);
     }
+  else
+    /* An overlay not associated with any buffer will normally have its
+       `next' field set to NULL, but not always: when killing a buffer,
+       we just set its overlays_after and overlays_before to NULL without
+       manually setting each overlay's `next' field to NULL.
+       Let's correct it here, to simplify subsequent assertions.
+       FIXME: Maybe the better fix is to change `kill-buffer'!?  */
+    XOVERLAY (overlay)->next = NULL;
+
+  eassert (XOVERLAY (overlay)->next == NULL);
 
   /* Set the overlay boundaries, which may clip them.  */
   Fset_marker (OVERLAY_START (overlay), beg, buffer);
@@ -4020,10 +4030,20 @@ buffer.  */)
        modify_overlay (b, min (o_beg, n_beg), max (o_end, n_end));
     }
 
+  eassert (XOVERLAY (overlay)->next == NULL);
+
   /* Delete the overlay if it is empty after clipping and has the
      evaporate property.  */
   if (n_beg == n_end && !NILP (Foverlay_get (overlay, Qevaporate)))
-    return unbind_to (count, Fdelete_overlay (overlay));
+    { /* We used to call `Fdelete_overlay' here, but it causes problems:
+         - At this stage, `overlay' is not included in its buffer's lists
+           of overlays (the data-structure is in an inconsistent state),
+           contrary to `Fdelete_overlay's assumptions.
+         - Most of the work done by Fdelete_overlay has already been done
+           here for other reasons.  */
+      drop_overlay (XBUFFER (buffer), XOVERLAY (overlay));
+      return unbind_to (count, overlay);
+    }
 
   /* Put the overlay into the new buffer's overlay lists, first on the
      wrong list.  */
diff --git a/src/bytecode.c b/src/bytecode.c
index 17457fc..40389e0 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -369,6 +369,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, 
Lisp_Object maxdepth,
   ptrdiff_t item_bytes = stack_items * word_size;
   Lisp_Object *stack_base = ptr_bounds_clip (alloc, item_bytes);
   Lisp_Object *top = stack_base;
+  *top = vector; /* Ensure VECTOR survives GC (Bug#33014).  */
   Lisp_Object *stack_lim = stack_base + stack_items;
   unsigned char *bytestr_data = alloc;
   bytestr_data = ptr_bounds_clip (bytestr_data + item_bytes, bytestr_length);
diff --git a/src/callproc.c b/src/callproc.c
index e6a8180..a2cfd2e 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -221,15 +221,20 @@ DEFUN ("call-process", Fcall_process, Scall_process, 1, 
MANY, 0,
        doc: /* Call PROGRAM synchronously in separate process.
 The remaining arguments are optional.
 The program's input comes from file INFILE (nil means `/dev/null').
-Insert output in DESTINATION before point; t means current buffer; nil for 
DESTINATION
- means discard it; 0 means discard and don't wait; and `(:file FILE)', where
- FILE is a file name string, means that it should be written to that file
- (if the file already exists it is overwritten).
+
+Third argument DESTINATION specifies how to handle program's output.
+If DESTINATION is a buffer, or t that stands for the current buffer,
+ it means insert output in that buffer before point.
+If DESTINATION is nil, it means discard output; 0 means discard
+ and don't wait for the program to terminate.
+If DESTINATION is `(:file FILE)', where FILE is a file name string,
+ it means that output should be written to that file (if the file
+ already exists it is overwritten).
 DESTINATION can also have the form (REAL-BUFFER STDERR-FILE); in that case,
-REAL-BUFFER says what to do with standard output, as above,
-while STDERR-FILE says what to do with standard error in the child.
-STDERR-FILE may be nil (discard standard error output),
-t (mix it with ordinary output), or a file name string.
+ REAL-BUFFER says what to do with standard output, as above,
+ while STDERR-FILE says what to do with standard error in the child.
+ STDERR-FILE may be nil (discard standard error output),
+ t (mix it with ordinary output), or a file name string.
 
 Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted.
 Remaining arguments are strings passed as command arguments to PROGRAM.
diff --git a/src/conf_post.h b/src/conf_post.h
index 683a96f..2f8b264 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -55,9 +55,11 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #endif
 
 /* The type of bool bitfields.  Needed to compile Objective-C with
-   standard GCC.  It was also needed to port to pre-C99 compilers,
-   although we don't care about that any more.  */
-#if NS_IMPL_GNUSTEP
+   standard GCC, and to make sure adjacent bool_bf fields are packed
+   into the same 1-, 2-, or 4-byte allocation unit in the MinGW
+   builds.  It was also needed to port to pre-C99 compilers, although
+   we don't care about that any more.  */
+#if NS_IMPL_GNUSTEP || defined(__MINGW32__)
 typedef unsigned int bool_bf;
 #else
 typedef bool bool_bf;
diff --git a/src/data.c b/src/data.c
index 538081e..f8b991e 100644
--- a/src/data.c
+++ b/src/data.c
@@ -758,7 +758,9 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0,
   register Lisp_Object function;
   CHECK_SYMBOL (symbol);
   /* Perhaps not quite the right error signal, but seems good enough.  */
-  if (NILP (symbol))
+  if (NILP (symbol) && !NILP (definition))
+    /* There are so many other ways to shoot oneself in the foot, I don't
+       think this one little sanity check is worth its cost, but anyway.  */
     xsignal1 (Qsetting_constant, symbol);
 
   function = XSYMBOL (symbol)->u.s.function;
diff --git a/src/dispnew.c b/src/dispnew.c
index 798413d..8742d58 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -4123,7 +4123,12 @@ scrolling_window (struct window *w, bool header_line_p)
     }
 
 #ifdef HAVE_XWIDGETS
-  /* Currently this seems needed to detect xwidget movement reliably. */
+  /* Currently this seems needed to detect xwidget movement reliably.
+     This is most probably because an xwidget glyph is represented in
+     struct glyph's 'union u' by a pointer to a struct, which takes 8
+     bytes in 64-bit builds, and thus the comparison of u.val values
+     done by GLYPH_EQUAL_P doesn't work reliably, since it assumes the
+     size of the union is 4 bytes.  FIXME.  */
     return 0;
 #endif
 
diff --git a/src/eval.c b/src/eval.c
index 42c275d..a51d0c9 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -3429,6 +3429,7 @@ record_unwind_protect (void (*function) (Lisp_Object), 
Lisp_Object arg)
   specpdl_ptr->unwind.kind = SPECPDL_UNWIND;
   specpdl_ptr->unwind.func = function;
   specpdl_ptr->unwind.arg = arg;
+  specpdl_ptr->unwind.eval_depth = lisp_eval_depth;
   grow_specpdl ();
 }
 
@@ -3501,6 +3502,7 @@ do_one_unbind (union specbinding *this_binding, bool 
unwinding,
   switch (this_binding->kind)
     {
     case SPECPDL_UNWIND:
+      lisp_eval_depth = this_binding->unwind.eval_depth;
       this_binding->unwind.func (this_binding->unwind.arg);
       break;
     case SPECPDL_UNWIND_ARRAY:
@@ -3595,6 +3597,7 @@ set_unwind_protect (ptrdiff_t count, void (*func) 
(Lisp_Object),
   p->unwind.kind = SPECPDL_UNWIND;
   p->unwind.func = func;
   p->unwind.arg = arg;
+  p->unwind.eval_depth = lisp_eval_depth;
 }
 
 void
diff --git a/src/fringe.c b/src/fringe.c
index 6a44de1..a1016ad 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -909,6 +909,12 @@ draw_window_fringes (struct window *w, bool no_fringe_p)
   if (w->pseudo_window_p)
     return updated_p;
 
+  /* We must switch to the window's buffer to use its local value of
+     the fringe face, in case it's been remapped in face-remapping-alist.  */
+  Lisp_Object window_buffer = w->contents;
+  struct buffer *oldbuf = current_buffer;
+  set_buffer_internal_1 (XBUFFER (window_buffer));
+
   /* Must draw line if no fringe */
   if (no_fringe_p
       && (WINDOW_LEFT_FRINGE_WIDTH (w) == 0
@@ -926,6 +932,8 @@ draw_window_fringes (struct window *w, bool no_fringe_p)
       updated_p = 1;
     }
 
+  set_buffer_internal_1 (oldbuf);
+
   return updated_p;
 }
 
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 6212e1a..da4a0ae 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1509,6 +1509,7 @@ xg_set_background_color (struct frame *f, unsigned long 
bg)
       block_input ();
       xg_set_widget_bg (f, FRAME_GTK_WIDGET (f), FRAME_BACKGROUND_PIXEL (f));
 
+#ifdef USE_TOOLKIT_SCROLL_BARS
       Lisp_Object bar;
       for (bar = FRAME_SCROLL_BARS (f);
            !NILP (bar);
@@ -1519,7 +1520,7 @@ xg_set_background_color (struct frame *f, unsigned long 
bg)
           GtkWidget *webox = gtk_widget_get_parent (scrollbar);
           xg_set_widget_bg (f, webox, FRAME_BACKGROUND_PIXEL (f));
         }
-
+#endif
       unblock_input ();
     }
 }
diff --git a/src/image.c b/src/image.c
index 24decbc..ad4f95b 100644
--- a/src/image.c
+++ b/src/image.c
@@ -4309,7 +4309,7 @@ xpm_load_image (struct frame *f,
   return 1;
 
  failure:
-  image_error ("Invalid XPM file (%s)", img->spec);
+  image_error ("Invalid XPM3 file (%s)", img->spec);
   x_destroy_x_image (ximg);
   x_destroy_x_image (mask_img);
   x_clear_image (f, img);
diff --git a/src/json.c b/src/json.c
index 17cc096..e5c0dc2 100644
--- a/src/json.c
+++ b/src/json.c
@@ -624,42 +624,54 @@ struct json_buffer_and_size
 {
   const char *buffer;
   ptrdiff_t size;
+  /* This tracks how many bytes were inserted by the callback since
+     json_dump_callback was called.  */
+  ptrdiff_t inserted_bytes;
 };
 
 static Lisp_Object
 json_insert (void *data)
 {
   struct json_buffer_and_size *buffer_and_size = data;
-  /* FIXME: This should be possible without creating an intermediate
-     string object.  */
-  Lisp_Object string
-    = json_make_string (buffer_and_size->buffer, buffer_and_size->size);
-  insert1 (string);
+  ptrdiff_t len = buffer_and_size->size;
+  ptrdiff_t inserted_bytes = buffer_and_size->inserted_bytes;
+  ptrdiff_t gap_size = GAP_SIZE - inserted_bytes;
+
+  /* Enlarge the gap if necessary.  */
+  if (gap_size < len)
+    make_gap (len - gap_size);
+
+  /* Copy this chunk of data into the gap.  */
+  memcpy ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE + inserted_bytes,
+         buffer_and_size->buffer, len);
+  buffer_and_size->inserted_bytes += len;
   return Qnil;
 }
 
 struct json_insert_data
 {
+  /* This tracks how many bytes were inserted by the callback since
+     json_dump_callback was called.  */
+  ptrdiff_t inserted_bytes;
   /* nil if json_insert succeeded, otherwise the symbol
      Qcatch_all_memory_full or a cons (ERROR-SYMBOL . ERROR-DATA).  */
   Lisp_Object error;
 };
 
-/* Callback for json_dump_callback that inserts the UTF-8 string in
-   [BUFFER, BUFFER + SIZE) into the current buffer.
-   If [BUFFER, BUFFER + SIZE) does not contain a valid UTF-8 string,
-   an unspecified string is inserted into the buffer.  DATA must point
-   to a structure of type json_insert_data.  This function may not
-   exit nonlocally.  It catches all nonlocal exits and stores them in
-   data->error for reraising.  */
+/* Callback for json_dump_callback that inserts a JSON representation
+   as a unibyte string into the gap.  DATA must point to a structure
+   of type json_insert_data.  This function may not exit nonlocally.
+   It catches all nonlocal exits and stores them in data->error for
+   reraising.  */
 
 static int
 json_insert_callback (const char *buffer, size_t size, void *data)
 {
   struct json_insert_data *d = data;
   struct json_buffer_and_size buffer_and_size
-    = {.buffer = buffer, .size = size};
+    = {.buffer = buffer, .size = size, .inserted_bytes = d->inserted_bytes};
   d->error = internal_catch_all (json_insert, &buffer_and_size, Fidentity);
+  d->inserted_bytes = buffer_and_size.inserted_bytes;
   return NILP (d->error) ? 0 : -1;
 }
 
@@ -695,10 +707,15 @@ usage: (json-insert OBJECT &rest ARGS)  */)
   json_t *json = lisp_to_json (args[0], &conf);
   record_unwind_protect_ptr (json_release_object, json);
 
+  prepare_to_modify_buffer (PT, PT, NULL);
+  move_gap_both (PT, PT_BYTE);
   struct json_insert_data data;
+  data.inserted_bytes = 0;
   /* If desired, we might want to add the following flags:
      JSON_DECODE_ANY, JSON_ALLOW_NUL.  */
   int status
+    /* Could have used json_dumpb, but that became available only in
+       Jansson 2.10, whereas we want to support 2.7 and upward.  */
     = json_dump_callback (json, json_insert_callback, &data, JSON_COMPACT);
   if (status == -1)
     {
@@ -708,6 +725,65 @@ usage: (json-insert OBJECT &rest ARGS)  */)
         json_out_of_memory ();
     }
 
+  ptrdiff_t inserted = 0;
+  ptrdiff_t inserted_bytes = data.inserted_bytes;
+  if (inserted_bytes > 0)
+    {
+      /* Make the inserted text part of the buffer, as unibyte text.  */
+      GAP_SIZE -= inserted_bytes;
+      GPT      += inserted_bytes;
+      GPT_BYTE += inserted_bytes;
+      ZV       += inserted_bytes;
+      ZV_BYTE  += inserted_bytes;
+      Z        += inserted_bytes;
+      Z_BYTE   += inserted_bytes;
+
+      if (GAP_SIZE > 0)
+       /* Put an anchor to ensure multi-byte form ends at gap.  */
+       *GPT_ADDR = 0;
+
+      /* If required, decode the stuff we've read into the gap.  */
+      struct coding_system coding;
+      /* JSON strings are UTF-8 encoded strings.  If for some reason
+        the text returned by the Jansson library includes invalid
+        byte sequences, they will be represented by raw bytes in the
+        buffer text.  */
+      setup_coding_system (Qutf_8_unix, &coding);
+      coding.dst_multibyte =
+       !NILP (BVAR (current_buffer, enable_multibyte_characters));
+      if (CODING_MAY_REQUIRE_DECODING (&coding))
+       {
+         move_gap_both (PT, PT_BYTE);
+         GAP_SIZE += inserted_bytes;
+         ZV_BYTE -= inserted_bytes;
+         Z_BYTE -= inserted_bytes;
+         ZV -= inserted_bytes;
+         Z -= inserted_bytes;
+         decode_coding_gap (&coding, inserted_bytes, inserted_bytes);
+         inserted = coding.produced_char;
+       }
+      else
+       {
+         /* The target buffer is unibyte, so we don't need to decode.  */
+         invalidate_buffer_caches (current_buffer,
+                                   PT, PT + inserted_bytes);
+         adjust_after_insert (PT, PT_BYTE,
+                              PT + inserted_bytes,
+                              PT_BYTE + inserted_bytes,
+                              inserted_bytes);
+         inserted = inserted_bytes;
+       }
+    }
+
+  /* Call after-change hooks.  */
+  signal_after_change (PT, 0, inserted);
+  if (inserted > 0)
+    {
+      update_compositions (PT, PT, CHECK_BORDER);
+      /* Move point to after the inserted text.  */
+      SET_PT_BOTH (PT + inserted, PT_BYTE + inserted_bytes);
+    }
+
   return unbind_to (count, Qnil);
 }
 
diff --git a/src/keyboard.c b/src/keyboard.c
index 8ea15d3..be727a6 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3324,7 +3324,7 @@ readable_events (int flags)
   if (flags & READABLE_EVENTS_DO_TIMERS_NOW)
     timer_check ();
 
-  /* If the buffer contains only FOCUS_IN_EVENT events, and
+  /* If the buffer contains only FOCUS_IN/OUT_EVENT events, and
      READABLE_EVENTS_FILTER_EVENTS is set, report it as empty.  */
   if (kbd_fetch_ptr != kbd_store_ptr)
     {
@@ -3344,7 +3344,8 @@ readable_events (int flags)
 #ifdef USE_TOOLKIT_SCROLL_BARS
                    (flags & READABLE_EVENTS_FILTER_EVENTS) &&
 #endif
-                   event->kind == FOCUS_IN_EVENT)
+                   (event->kind == FOCUS_IN_EVENT
+                     || event->kind == FOCUS_OUT_EVENT))
 #ifdef USE_TOOLKIT_SCROLL_BARS
                  && !((flags & READABLE_EVENTS_IGNORE_SQUEEZABLES)
                       && (event->kind == SCROLL_BAR_CLICK_EVENT
diff --git a/src/lisp.h b/src/lisp.h
index 5ecc48b..eb67626 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -229,7 +229,7 @@ extern bool suppress_checking EXTERNALLY_VISIBLE;
    USE_LSB_TAG not only requires the least 3 bits of pointers returned by
    malloc to be 0 but also needs to be able to impose a mult-of-8 alignment
    on some non-GC Lisp_Objects, all of which are aligned via
-   GCALIGNED_UNION_MEMBER, GCALIGNED_STRUCT_MEMBER, and GCALIGNED_STRUCT.  */
+   GCALIGNED_UNION_MEMBER.  */
 
 enum Lisp_Bits
   {
@@ -284,15 +284,14 @@ error !;
 # define GCALIGNMENT 1
 #endif
 
-/* If a struct is always allocated by the GC and is therefore always
-   GC-aligned, put GCALIGNED_STRUCT after its closing '}'; this can
-   help the compiler generate better code.
+/* To cause a union to have alignment of at least GCALIGNMENT, put
+   GCALIGNED_UNION_MEMBER in its member list.
 
-   To cause a union to have alignment of at least GCALIGNMENT, put
-   GCALIGNED_UNION_MEMBER in its member list.  Similarly for a struct
-   and GCALIGNED_STRUCT_MEMBER, although this may make the struct a
-   bit bigger on non-GCC platforms.  Any struct using
-   GCALIGNED_STRUCT_MEMBER should also use GCALIGNED_STRUCT.
+   If a struct is always GC-aligned (either by the GC, or via
+   allocation in a containing union that has GCALIGNED_UNION_MEMBER)
+   and does not contain a GC-aligned struct or union, putting
+   GCALIGNED_STRUCT after its closing '}' can help the compiler
+   generate better code.
 
    Although these macros are reasonably portable, they are not
    guaranteed on non-GCC platforms, as C11 does not require support
@@ -306,10 +305,8 @@ error !;
 
 #define GCALIGNED_UNION_MEMBER char alignas (GCALIGNMENT) gcaligned;
 #if HAVE_STRUCT_ATTRIBUTE_ALIGNED
-# define GCALIGNED_STRUCT_MEMBER
 # define GCALIGNED_STRUCT __attribute__ ((aligned (GCALIGNMENT)))
 #else
-# define GCALIGNED_STRUCT_MEMBER GCALIGNED_UNION_MEMBER
 # define GCALIGNED_STRUCT
 #endif
 #define GCALIGNED(type) (alignof (type) % GCALIGNMENT == 0)
@@ -1970,9 +1967,13 @@ struct Lisp_Subr
     const char *symbol_name;
     const char *intspec;
     EMACS_INT doc;
-    GCALIGNED_STRUCT_MEMBER
   } GCALIGNED_STRUCT;
-verify (GCALIGNED (struct Lisp_Subr));
+union Aligned_Lisp_Subr
+  {
+    struct Lisp_Subr s;
+    GCALIGNED_UNION_MEMBER
+  };
+verify (GCALIGNED (union Aligned_Lisp_Subr));
 
 INLINE bool
 SUBRP (Lisp_Object a)
@@ -1984,7 +1985,7 @@ INLINE struct Lisp_Subr *
 XSUBR (Lisp_Object a)
 {
   eassert (SUBRP (a));
-  return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Subr);
+  return &XUNTAG (a, Lisp_Vectorlike, union Aligned_Lisp_Subr)->s;
 }
 
 enum char_table_specials
@@ -2952,15 +2953,15 @@ CHECK_FIXNUM_CDR (Lisp_Object x)
 /* This version of DEFUN declares a function prototype with the right
    arguments, so we can catch errors with maxargs at compile-time.  */
 #define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc)    \
-   static struct Lisp_Subr sname =                             \
-     { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS },                                
\
+   static union Aligned_Lisp_Subr sname =                              \
+     {{{ PVEC_SUBR << PSEUDOVECTOR_AREA_BITS },                                
\
        { .a ## maxargs = fnname },                                     \
-       minargs, maxargs, lname, intspec, 0};                           \
+       minargs, maxargs, lname, intspec, 0}};                          \
    Lisp_Object fnname
 
 /* defsubr (Sname);
    is how we define the symbol for function `name' at start-up time.  */
-extern void defsubr (struct Lisp_Subr *);
+extern void defsubr (union Aligned_Lisp_Subr *);
 
 enum maxargs
   {
@@ -3071,6 +3072,7 @@ union specbinding
       ENUM_BF (specbind_tag) kind : CHAR_BIT;
       void (*func) (Lisp_Object);
       Lisp_Object arg;
+      EMACS_INT eval_depth;
     } unwind;
     struct {
       ENUM_BF (specbind_tag) kind : CHAR_BIT;
@@ -4010,6 +4012,7 @@ extern void syms_of_module (void);
 
 /* Defined in thread.c.  */
 extern void mark_threads (void);
+extern void unmark_main_thread (void);
 
 /* Defined in editfns.c.  */
 extern void insert1 (Lisp_Object);
diff --git a/src/lread.c b/src/lread.c
index 62616cb..5f38714 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -4409,8 +4409,9 @@ init_obarray (void)
 }
 
 void
-defsubr (struct Lisp_Subr *sname)
+defsubr (union Aligned_Lisp_Subr *aname)
 {
+  struct Lisp_Subr *sname = &aname->s;
   Lisp_Object sym, tem;
   sym = intern_c_string (sname->symbol_name);
   XSETPVECTYPE (sname, PVEC_SUBR);
diff --git a/src/minibuf.c b/src/minibuf.c
index 9395dc8..2b331c6 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -181,12 +181,8 @@ string_to_object (Lisp_Object val, Lisp_Object defalt)
    from read_minibuf to do the job if noninteractive.  */
 
 static Lisp_Object
-read_minibuf_noninteractive (Lisp_Object map, Lisp_Object initial,
-                            Lisp_Object prompt, Lisp_Object backup_n,
-                            bool expflag,
-                            Lisp_Object histvar, Lisp_Object histpos,
-                            Lisp_Object defalt,
-                            bool allow_props, bool inherit_input_method)
+read_minibuf_noninteractive (Lisp_Object prompt, bool expflag,
+                            Lisp_Object defalt)
 {
   ptrdiff_t size, len;
   char *line;
@@ -430,10 +426,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, 
Lisp_Object prompt,
        || (IS_DAEMON && DAEMON_RUNNING))
       && NILP (Vexecuting_kbd_macro))
     {
-      val = read_minibuf_noninteractive (map, initial, prompt,
-                                        make_fixnum (pos),
-                                        expflag, histvar, histpos, defalt,
-                                        allow_props, inherit_input_method);
+      val = read_minibuf_noninteractive (prompt, expflag, defalt);
       return unbind_to (count, val);
     }
 
diff --git a/src/nsterm.m b/src/nsterm.m
index 68ad646..bcc23ff 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -279,7 +279,6 @@ long context_menu_value = 0;
 
 /* display update */
 static int ns_window_num = 0;
-static BOOL gsaved = NO;
 static BOOL ns_fake_keydown = NO;
 #ifdef NS_IMPL_COCOA
 static BOOL ns_menu_bar_is_hidden = NO;
@@ -1234,7 +1233,6 @@ ns_clip_to_rect (struct frame *f, NSRect *r, int n)
             NSRectClipList (r, 2);
           else
             NSRectClip (*r);
-          gsaved = YES;
 
           return YES;
         }
@@ -1258,11 +1256,7 @@ ns_reset_clipping (struct frame *f)
 {
   NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_reset_clipping");
 
-  if (gsaved)
-    {
-      [[NSGraphicsContext currentContext] restoreGraphicsState];
-      gsaved = NO;
-    }
+  [[NSGraphicsContext currentContext] restoreGraphicsState];
 }
 
 
@@ -1288,19 +1282,6 @@ ns_clip_to_row (struct window *w, struct glyph_row *row,
   return ns_clip_to_rect (f, &clip_rect, 1);
 }
 
-
-static void
-ns_flush_display (struct frame *f)
-/* Force the frame to redisplay.  If areas have previously been marked
-   dirty by setNeedsDisplayInRect (in ns_clip_to_rect), then this will call
-   draw_rect: which will "expose" those areas.  */
-{
-  block_input ();
-  [FRAME_NS_VIEW (f) displayIfNeeded];
-  unblock_input ();
-}
-
-
 /* ==========================================================================
 
     Visible bell and beep.
@@ -2837,6 +2818,8 @@ ns_clear_frame_area (struct frame *f, int x, int y, int 
width, int height)
 static void
 ns_copy_bits (struct frame *f, NSRect src, NSRect dest)
 {
+  NSSize delta = NSMakeSize (dest.origin.x - src.origin.x,
+                             dest.origin.y - src.origin.y)
   NSTRACE ("ns_copy_bits");
 
   if (FRAME_NS_VIEW (f))
@@ -2845,9 +2828,21 @@ ns_copy_bits (struct frame *f, NSRect src, NSRect dest)
 
       /* FIXME: scrollRect:by: is deprecated in macOS 10.14.  There is
          no obvious replacement so we may have to come up with our own.  */
-      [FRAME_NS_VIEW (f) scrollRect: src
-                                 by: NSMakeSize (dest.origin.x - src.origin.x,
-                                                 dest.origin.y - 
src.origin.y)];
+      [FRAME_NS_VIEW (f) scrollRect: src by: delta];
+
+#ifdef NS_IMPL_COCOA
+      /* As far as I can tell from the documentation, scrollRect:by:,
+         above, should copy the dirty rectangles from our source
+         rectangle to our destination, however it appears it clips the
+         operation to src.  As a result we need to use
+         translateRectsNeedingDisplayInRect:by: below, and we have to
+         union src and dest so it can pick up the dirty rectangles,
+         and place them, as it also clips to the rectangle.
+
+         FIXME: We need a GNUstep equivalent.  */
+      [FRAME_NS_VIEW (f) translateRectsNeedingDisplayInRect:NSUnionRect (src, 
dest)
+                                                         by:delta];
+#endif
     }
 }
 
@@ -3232,15 +3227,6 @@ ns_draw_window_cursor (struct window *w, struct 
glyph_row *glyph_row,
       else
         [FRAME_CURSOR_COLOR (f) set];
 
-#ifdef NS_IMPL_COCOA
-      /* TODO: This makes drawing of cursor plus that of phys_cursor_glyph
-         atomic.  Cleaner ways of doing this should be investigated.
-         One way would be to set a global variable DRAWING_CURSOR
-         when making the call to draw_phys..(), don't focus in that
-         case, then move the ns_reset_clipping() here after that call.  */
-      NSDisableScreenUpdates ();
-#endif
-
       switch (cursor_type)
         {
         case DEFAULT_CURSOR:
@@ -3274,10 +3260,6 @@ ns_draw_window_cursor (struct window *w, struct 
glyph_row *glyph_row,
       /* draw the character under the cursor */
       if (cursor_type != NO_CURSOR)
         draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
-
-#ifdef NS_IMPL_COCOA
-      NSEnableScreenUpdates ();
-#endif
     }
 }
 
@@ -5118,7 +5100,7 @@ static struct redisplay_interface ns_redisplay_interface =
   ns_after_update_window_line,
   ns_update_window_begin,
   ns_update_window_end,
-  ns_flush_display, /* flush_display */
+  0, /* flush_display */
   x_clear_window_mouse_face,
   x_get_glyph_overhangs,
   x_fix_overlapping_area,
@@ -7113,7 +7095,6 @@ not_in_argv (NSString *arg)
         size_title = xmalloc (strlen (old_title) + 40);
        esprintf (size_title, "%s  —  (%d x %d)", old_title, cols, rows);
         [window setTitle: [NSString stringWithUTF8String: size_title]];
-        [window display];
         xfree (size_title);
       }
   }
@@ -8163,8 +8144,8 @@ not_in_argv (NSString *arg)
 
 - (void)drawRect: (NSRect)rect
 {
-  int x = NSMinX (rect), y = NSMinY (rect);
-  int width = NSWidth (rect), height = NSHeight (rect);
+  const NSRect *rectList;
+  NSInteger numRects;
 
   NSTRACE ("[EmacsView drawRect:" NSTRACE_FMT_RECT "]",
            NSTRACE_ARG_RECT(rect));
@@ -8172,9 +8153,23 @@ not_in_argv (NSString *arg)
   if (!emacsframe || !emacsframe->output_data.ns)
     return;
 
-  ns_clear_frame_area (emacsframe, x, y, width, height);
   block_input ();
-  expose_frame (emacsframe, x, y, width, height);
+
+  /* Get only the precise dirty rectangles to avoid redrawing
+     potentially large areas of the frame that haven't changed.
+
+     I'm not sure this actually provides much of a performance benefit
+     as it's hard to benchmark, but it certainly doesn't seem to
+     hurt.  */
+  [self getRectsBeingDrawn:&rectList count:&numRects];
+  for (int i = 0 ; i < numRects ; i++)
+    {
+      NSRect r = rectList[i];
+      expose_frame (emacsframe,
+                    NSMinX (r), NSMinY (r),
+                    NSWidth (r), NSHeight (r));
+    }
+
   unblock_input ();
 
   /*
diff --git a/src/thread.c b/src/thread.c
index fc93344..6612697 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -27,11 +27,18 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include "syssignal.h"
 #include "keyboard.h"
 
-static struct thread_state main_thread;
+union aligned_thread_state
+{
+  struct thread_state s;
+  GCALIGNED_UNION_MEMBER
+};
+verify (GCALIGNED (union aligned_thread_state));
 
-struct thread_state *current_thread = &main_thread;
+static union aligned_thread_state main_thread;
 
-static struct thread_state *all_threads = &main_thread;
+struct thread_state *current_thread = &main_thread.s;
+
+static struct thread_state *all_threads = &main_thread.s;
 
 static sys_mutex_t global_lock;
 
@@ -113,7 +120,7 @@ maybe_reacquire_global_lock (void)
   /* SIGINT handler is always run on the main thread, see
      deliver_process_signal, so reflect that in our thread-tracking
      variables.  */
-  current_thread = &main_thread;
+  current_thread = &main_thread.s;
 
   if (current_thread->not_holding_lock)
     {
@@ -656,6 +663,12 @@ mark_threads (void)
   flush_stack_call_func (mark_threads_callback, NULL);
 }
 
+void
+unmark_main_thread (void)
+{
+  main_thread.s.header.size &= ~ARRAY_MARK_FLAG;
+}
+
 
 
 static void
@@ -1037,23 +1050,23 @@ thread_check_current_buffer (struct buffer *buffer)
 static void
 init_main_thread (void)
 {
-  main_thread.header.size
+  main_thread.s.header.size
     = PSEUDOVECSIZE (struct thread_state, m_stack_bottom);
-  XSETPVECTYPE (&main_thread, PVEC_THREAD);
-  main_thread.m_last_thing_searched = Qnil;
-  main_thread.m_saved_last_thing_searched = Qnil;
-  main_thread.name = Qnil;
-  main_thread.function = Qnil;
-  main_thread.result = Qnil;
-  main_thread.error_symbol = Qnil;
-  main_thread.error_data = Qnil;
-  main_thread.event_object = Qnil;
+  XSETPVECTYPE (&main_thread.s, PVEC_THREAD);
+  main_thread.s.m_last_thing_searched = Qnil;
+  main_thread.s.m_saved_last_thing_searched = Qnil;
+  main_thread.s.name = Qnil;
+  main_thread.s.function = Qnil;
+  main_thread.s.result = Qnil;
+  main_thread.s.error_symbol = Qnil;
+  main_thread.s.error_data = Qnil;
+  main_thread.s.event_object = Qnil;
 }
 
 bool
 main_thread_p (void *ptr)
 {
-  return ptr == &main_thread;
+  return ptr == &main_thread.s;
 }
 
 bool
@@ -1074,11 +1087,11 @@ void
 init_threads (void)
 {
   init_main_thread ();
-  sys_cond_init (&main_thread.thread_condvar);
+  sys_cond_init (&main_thread.s.thread_condvar);
   sys_mutex_init (&global_lock);
   sys_mutex_lock (&global_lock);
-  current_thread = &main_thread;
-  main_thread.thread_id = sys_thread_self ();
+  current_thread = &main_thread.s;
+  main_thread.s.thread_id = sys_thread_self ();
 }
 
 void
@@ -1124,7 +1137,7 @@ syms_of_threads (void)
   DEFVAR_LISP ("main-thread", Vmain_thread,
     doc: /* The main thread of Emacs.  */);
 #ifdef THREADS_ENABLED
-  XSETTHREAD (Vmain_thread, &main_thread);
+  XSETTHREAD (Vmain_thread, &main_thread.s);
 #else
   Vmain_thread = Qnil;
 #endif
diff --git a/src/timefns.c b/src/timefns.c
index c94d97d..f527d5e 100644
--- a/src/timefns.c
+++ b/src/timefns.c
@@ -171,16 +171,6 @@ emacs_localtime_rz (timezone_t tz, time_t const *t, struct 
tm *tm)
   return tm;
 }
 
-static time_t
-emacs_mktime_z (timezone_t tz, struct tm *tm)
-{
-  errno = 0;
-  time_t t = mktime_z (tz, tm);
-  if (t == (time_t) -1 && errno == ENOMEM)
-    memory_full (SIZE_MAX);
-  return t;
-}
-
 static _Noreturn void
 invalid_time_zone_specification (Lisp_Object zone)
 {
@@ -347,9 +337,14 @@ time_overflow (void)
 }
 
 static _Noreturn void
-invalid_time (void)
+time_error (int err)
 {
-  error ("Invalid time specification");
+  switch (err)
+    {
+    case ENOMEM: memory_full (SIZE_MAX);
+    case EOVERFLOW: time_overflow ();
+    default: error ("Invalid time specification");
+    }
 }
 
 static _Noreturn void
@@ -373,19 +368,19 @@ lo_time (time_t t)
 }
 
 /* Convert T into an Emacs time *RESULT, truncating toward minus infinity.
-   Return true if T is in range, false otherwise.  */
-static bool
+   Return zero if successful, an error number otherwise.  */
+static int
 decode_float_time (double t, struct lisp_time *result)
 {
   if (!isfinite (t))
-    return false;
+    return isnan (t) ? EINVAL : EOVERFLOW;
   /* Actual hz unknown; guess TIMESPEC_HZ.  */
   mpz_set_d (mpz[1], t);
   mpz_set_si (mpz[0], floor ((t - trunc (t)) * TIMESPEC_HZ));
   mpz_addmul_ui (mpz[0], mpz[1], TIMESPEC_HZ);
   result->ticks = make_integer_mpz ();
   result->hz = timespec_hz;
-  return true;
+  return 0;
 }
 
 /* Compute S + NS/TIMESPEC_HZ as a double.
@@ -569,9 +564,9 @@ lisp_time_form_stamp (struct lisp_time t, Lisp_Object form)
    start of the POSIX Epoch.  Unsuccessful calls may or may not store
    results.
 
-   Return true if successful, false if (TICKS . HZ) would not
+   Return zero if successful, an error number if (TICKS . HZ) would not
    be a valid new-format timestamp.  */
-static bool
+static int
 decode_ticks_hz (Lisp_Object ticks, Lisp_Object hz,
                 struct lisp_time *result, double *dresult)
 {
@@ -581,7 +576,7 @@ decode_ticks_hz (Lisp_Object ticks, Lisp_Object hz,
   if (! (INTEGERP (ticks)
         && ((FIXNUMP (hz) && 0 < XFIXNUM (hz))
             || (BIGNUMP (hz) && 0 < mpz_sgn (XBIGNUM (hz)->value)))))
-    return false;
+    return EINVAL;
 
   if (result)
     {
@@ -600,7 +595,7 @@ decode_ticks_hz (Lisp_Object ticks, Lisp_Object hz,
              if (ns < 0)
                s--, ns += TIMESPEC_HZ;
              *dresult = s_ns_to_double (s, ns);
-             return true;
+             return 0;
            }
          ns = mpz_fdiv_q_ui (*q, XBIGNUM (ticks)->value, TIMESPEC_HZ);
        }
@@ -610,7 +605,7 @@ decode_ticks_hz (Lisp_Object ticks, Lisp_Object hz,
          if (FIXNUMP (ticks))
            {
              *dresult = XFIXNUM (ticks);
-             return true;
+             return 0;
            }
          q = &XBIGNUM (ticks)->value;
        }
@@ -624,7 +619,7 @@ decode_ticks_hz (Lisp_Object ticks, Lisp_Object hz,
       *dresult = s_ns_to_double (mpz_get_d (*q), ns);
     }
 
-  return true;
+  return 0;
 }
 
 /* Lisp timestamp classification.  */
@@ -649,9 +644,8 @@ enum timeform
    start of the POSIX Epoch.  Unsuccessful calls may or may not store
    results.
 
-   Return true if successful, false if the components are of the wrong
-   type.  */
-static bool
+   Return zero if successful, an error number otherwise.  */
+static int
 decode_time_components (enum timeform form,
                        Lisp_Object high, Lisp_Object low,
                        Lisp_Object usec, Lisp_Object psec,
@@ -660,7 +654,7 @@ decode_time_components (enum timeform form,
   switch (form)
     {
     case TIMEFORM_INVALID:
-      return false;
+      return EINVAL;
 
     case TIMEFORM_TICKS_HZ:
       return decode_ticks_hz (high, low, result, dresult);
@@ -673,7 +667,7 @@ decode_time_components (enum timeform form,
        else
          {
            *dresult = t;
-           return true;
+           return 0;
          }
       }
 
@@ -687,7 +681,7 @@ decode_time_components (enum timeform form,
          }
        else
          *dresult = s_ns_to_double (now.tv_sec, now.tv_nsec);
-       return true;
+       return 0;
       }
 
     default:
@@ -696,7 +690,7 @@ decode_time_components (enum timeform form,
 
   if (! (INTEGERP (high) && INTEGERP (low)
         && FIXNUMP (usec) && FIXNUMP (psec)))
-    return false;
+    return EINVAL;
   EMACS_INT us = XFIXNUM (usec);
   EMACS_INT ps = XFIXNUM (psec);
 
@@ -740,7 +734,7 @@ decode_time_components (enum timeform form,
   else
     *dresult = mpz_get_d (mpz[0]) + (us * 1e6L + ps) / 1e12L;
 
-  return true;
+  return 0;
 }
 
 enum { DECODE_SECS_ONLY = WARN_OBSOLETE_TIMESTAMPS + 1 };
@@ -758,9 +752,8 @@ enum { DECODE_SECS_ONLY = WARN_OBSOLETE_TIMESTAMPS + 1 };
    start of the POSIX Epoch.  Unsuccessful calls may or may not store
    results.
 
-   Return true if successful, false if SPECIFIED_TIME is
-   not a valid Lisp timestamp.  */
-static bool
+   Signal an error if unsuccessful.  */
+static void
 decode_lisp_time (Lisp_Object specified_time, int flags,
                  enum timeform *pform,
                  struct lisp_time *result, double *dresult)
@@ -820,7 +813,10 @@ decode_lisp_time (Lisp_Object specified_time, int flags,
 
   if (pform)
     *pform = form;
-  return decode_time_components (form, high, low, usec, psec, result, dresult);
+  int err = decode_time_components (form, high, low, usec, psec,
+                                   result, dresult);
+  if (err)
+    time_error (err);
 }
 
 /* Convert Z to time_t, returning true if it fits.  */
@@ -915,8 +911,8 @@ list4_to_timespec (Lisp_Object high, Lisp_Object low,
                   struct timespec *result)
 {
   struct lisp_time t;
-  if (! decode_time_components (TIMEFORM_HI_LO_US_PS, high, low, usec, psec,
-                               &t, 0))
+  if (decode_time_components (TIMEFORM_HI_LO_US_PS, high, low, usec, psec,
+                             &t, 0))
     return false;
   *result = lisp_to_timespec (t);
   return timespec_valid_p (*result);
@@ -928,10 +924,8 @@ list4_to_timespec (Lisp_Object high, Lisp_Object low,
 static struct lisp_time
 lisp_time_struct (Lisp_Object specified_time, enum timeform *pform)
 {
-  int flags = WARN_OBSOLETE_TIMESTAMPS;
   struct lisp_time t;
-  if (! decode_lisp_time (specified_time, flags, pform, &t, 0))
-    invalid_time ();
+  decode_lisp_time (specified_time, WARN_OBSOLETE_TIMESTAMPS, pform, &t, 0);
   return t;
 }
 
@@ -956,8 +950,7 @@ lisp_seconds_argument (Lisp_Object specified_time)
 {
   int flags = WARN_OBSOLETE_TIMESTAMPS | DECODE_SECS_ONLY;
   struct lisp_time lt;
-  if (! decode_lisp_time (specified_time, flags, 0, &lt, 0))
-    invalid_time ();
+  decode_lisp_time (specified_time, flags, 0, &lt, 0);
   struct timespec t = lisp_to_timespec (lt);
   if (! timespec_valid_p (t))
     time_overflow ();
@@ -1126,8 +1119,7 @@ or (if you need time as a string) `format-time-string'.  
*/)
   (Lisp_Object specified_time)
 {
   double t;
-  if (! decode_lisp_time (specified_time, 0, 0, 0, &t))
-    invalid_time ();
+  decode_lisp_time (specified_time, 0, 0, 0, &t);
   return make_float (t);
 }
 
@@ -1200,8 +1192,9 @@ format_time_string (char const *format, ptrdiff_t 
formatlen,
   tmp = emacs_localtime_rz (tz, &tsec, tmp);
   if (! tmp)
     {
+      int localtime_errno = errno;
       xtzfree (tz);
-      time_overflow ();
+      time_error (localtime_errno);
     }
   synchronize_system_time_locale ();
 
@@ -1338,10 +1331,12 @@ usage: (decode-time &optional TIME ZONE)  */)
   struct tm local_tm, gmt_tm;
   timezone_t tz = tzlookup (zone, false);
   struct tm *tm = emacs_localtime_rz (tz, &time_spec, &local_tm);
+  int localtime_errno = errno;
   xtzfree (tz);
 
-  if (! (tm
-        && MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= local_tm.tm_year
+  if (!tm)
+    time_error (localtime_errno);
+  if (! (MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= local_tm.tm_year
         && local_tm.tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE))
     time_overflow ();
 
@@ -1445,7 +1440,6 @@ year values as low as 1901 do work.
 usage: (encode-time &optional TIME FORM &rest OBSOLESCENT-ARGUMENTS)  */)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
-  time_t value;
   struct tm tm;
   Lisp_Object form = Qnil, zone = Qnil;
   Lisp_Object a = args[0];
@@ -1460,8 +1454,7 @@ usage: (encode-time &optional TIME FORM &rest 
OBSOLESCENT-ARGUMENTS)  */)
        if (! CONSP (tail))
          {
            struct lisp_time t;
-           if (! decode_lisp_time (a, 0, 0, &t, 0))
-             invalid_time ();
+           decode_lisp_time (a, 0, 0, &t, 0);
            return lisp_time_form_stamp (t, form);
          }
       tm.tm_sec  = check_tm_member (XCAR (a), 0); a = XCDR (a);
@@ -1492,11 +1485,13 @@ usage: (encode-time &optional TIME FORM &rest 
OBSOLESCENT-ARGUMENTS)  */)
     }
 
   timezone_t tz = tzlookup (zone, false);
-  value = emacs_mktime_z (tz, &tm);
+  tm.tm_wday = -1;
+  time_t value = mktime_z (tz, &tm);
+  int mktime_errno = errno;
   xtzfree (tz);
 
-  if (value == (time_t) -1)
-    time_overflow ();
+  if (tm.tm_wday < 0)
+    time_error (mktime_errno);
 
   return time_form_stamp (value, form);
 }
@@ -1544,9 +1539,10 @@ without consideration for daylight saving time.  */)
      range -999 .. 9999.  */
   struct tm tm;
   struct tm *tmp = emacs_localtime_rz (tz, &value, &tm);
+  int localtime_errno = errno;
   xtzfree (tz);
   if (! tmp)
-    time_overflow ();
+    time_error (localtime_errno);
 
   static char const wday_name[][4] =
     { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
diff --git a/src/window.c b/src/window.c
index 6cdc52f..20084a1 100644
--- a/src/window.c
+++ b/src/window.c
@@ -7362,6 +7362,8 @@ value.  */)
 
 DEFUN ("window-vscroll", Fwindow_vscroll, Swindow_vscroll, 0, 2, 0,
        doc: /* Return the amount by which WINDOW is scrolled vertically.
+This takes effect when displaying tall lines or images.
+
 If WINDOW is omitted or nil, it defaults to the selected window.
 Normally, value is a multiple of the canonical character height of WINDOW;
 optional second arg PIXELS-P means value is measured in pixels.  */)
@@ -7384,6 +7386,8 @@ optional second arg PIXELS-P means value is measured in 
pixels.  */)
 DEFUN ("set-window-vscroll", Fset_window_vscroll, Sset_window_vscroll,
        2, 3, 0,
        doc: /* Set amount by which WINDOW should be scrolled vertically to 
VSCROLL.
+This takes effect when displaying tall lines or images.
+
 WINDOW nil means use the selected window.  Normally, VSCROLL is a
 non-negative multiple of the canonical character height of WINDOW;
 optional third arg PIXELS-P non-nil means that VSCROLL is in pixels.
diff --git a/src/xdisp.c b/src/xdisp.c
index d61d421..fa7691c 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2302,7 +2302,10 @@ get_phys_cursor_geometry (struct window *w, struct 
glyph_row *row,
      ascent value, lest the hollow cursor looks funny.  */
   y = w->phys_cursor.y;
   ascent = row->ascent;
-  if (row->ascent < glyph->ascent)
+  /* The test for row at ZV is for when line numbers are displayed and
+     point is at EOB: the cursor could then be smaller or larger than
+     the default face's font.  */
+  if (!row->ends_at_zv_p && row->ascent < glyph->ascent)
     {
       y -= glyph->ascent - row->ascent;
       ascent = glyph->ascent;
@@ -2312,6 +2315,9 @@ get_phys_cursor_geometry (struct window *w, struct 
glyph_row *row,
   h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
 
   h = max (h0, ascent + glyph->descent);
+  /* Don't let the cursor exceed the dimensions of the row, so that
+     the upper/lower side of the box aren't clipped.  */
+  h = min (h, row->height);
   h0 = min (h0, ascent + glyph->descent);
 
   y0 = WINDOW_HEADER_LINE_HEIGHT (w);
@@ -21232,14 +21238,11 @@ maybe_produce_line_number (struct it *it)
   for (const char *p = lnum_buf; *p; p++)
     {
       /* For continuation lines and lines after ZV, instead of a line
-        number, produce a blank prefix of the same width.  Use the
-        default face for the blank field beyond ZV.  */
-      if (beyond_zv)
-       tem_it.face_id = it->base_face_id;
-      else if (lnum_face_id != current_lnum_face_id
-              && (EQ (Vdisplay_line_numbers, Qvisual)
-                  ? this_line == 0
-                  : this_line == it->pt_lnum))
+        number, produce a blank prefix of the same width.  */
+      if (lnum_face_id != current_lnum_face_id
+         && (EQ (Vdisplay_line_numbers, Qvisual)
+             ? this_line == 0
+             : this_line == it->pt_lnum))
        tem_it.face_id = current_lnum_face_id;
       else
        tem_it.face_id = lnum_face_id;
@@ -21292,23 +21295,30 @@ maybe_produce_line_number (struct it *it)
        }
     }
 
-  /* Update IT's metrics due to glyphs produced for line numbers.  */
-  if (it->glyph_row)
+  /* Update IT's metrics due to glyphs produced for line numbers.
+     Don't do that for rows beyond ZV, to avoid displaying a cursor of
+     different dimensions there.  */
+  if (!beyond_zv)
     {
-      struct glyph_row *row = it->glyph_row;
+      if (it->glyph_row)
+       {
+         struct glyph_row *row = it->glyph_row;
 
-      it->max_ascent = max (row->ascent, tem_it.max_ascent);
-      it->max_descent = max (row->height - row->ascent, tem_it.max_descent);
-      it->max_phys_ascent = max (row->phys_ascent, tem_it.max_phys_ascent);
-      it->max_phys_descent = max (row->phys_height - row->phys_ascent,
-                                 tem_it.max_phys_descent);
-    }
-  else
-    {
-      it->max_ascent = max (it->max_ascent, tem_it.max_ascent);
-      it->max_descent = max (it->max_descent, tem_it.max_descent);
-      it->max_phys_ascent = max (it->max_phys_ascent, tem_it.max_phys_ascent);
-      it->max_phys_descent = max (it->max_phys_descent, 
tem_it.max_phys_descent);
+         it->max_ascent = max (row->ascent, tem_it.max_ascent);
+         it->max_descent = max (row->height - row->ascent, tem_it.max_descent);
+         it->max_phys_ascent = max (row->phys_ascent, tem_it.max_phys_ascent);
+         it->max_phys_descent = max (row->phys_height - row->phys_ascent,
+                                     tem_it.max_phys_descent);
+       }
+      else
+       {
+         it->max_ascent = max (it->max_ascent, tem_it.max_ascent);
+         it->max_descent = max (it->max_descent, tem_it.max_descent);
+         it->max_phys_ascent = max (it->max_phys_ascent,
+                                    tem_it.max_phys_ascent);
+         it->max_phys_descent = max (it->max_phys_descent,
+                                     tem_it.max_phys_descent);
+       }
     }
 
   it->line_number_produced_p = true;
@@ -32242,6 +32252,18 @@ expose_window (struct window *w, XRectangle *fr)
         y0 or y1 is negative (can happen for tall images).  */
       int r_bottom = r.y + r.height;
 
+      /* We must temporarily switch to the window's buffer, in case
+        the fringe face has been remapped in that buffer's
+        face-remapping-alist, so that draw_row_fringe_bitmaps,
+        called from expose_line, will use the right face.  */
+      bool buffer_changed = false;
+      struct buffer *oldbuf = current_buffer;
+      if (!w->pseudo_window_p)
+       {
+         set_buffer_internal_1 (XBUFFER (w->contents));
+         buffer_changed = true;
+       }
+
       /* Update lines intersecting rectangle R.  */
       first_overlapping_row = last_overlapping_row = NULL;
       for (row = w->current_matrix->rows;
@@ -32287,6 +32309,9 @@ expose_window (struct window *w, XRectangle *fr)
            break;
        }
 
+      if (buffer_changed)
+       set_buffer_internal_1 (oldbuf);
+
       /* Display the mode line if there is one.  */
       if (window_wants_mode_line (w)
          && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
diff --git a/src/xfaces.c b/src/xfaces.c
index 50593f6..76b23a3 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -6093,7 +6093,14 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
     int face_id;
 
     if (base_face_id >= 0)
-      face_id = base_face_id;
+      {
+       face_id = base_face_id;
+       /* Make sure the base face ID is usable: if someone freed the
+          cached faces since we've looked up the base face, we need
+          to look it up again.  */
+       if (!FACE_FROM_ID_OR_NULL (f, face_id))
+         face_id = lookup_basic_face (w, f, DEFAULT_FACE_ID);
+      }
     else if (NILP (Vface_remapping_alist))
       face_id = DEFAULT_FACE_ID;
     else
@@ -6755,6 +6762,7 @@ Because Emacs normally only redraws screen areas when the 
underlying
 buffer contents change, you may need to call `redraw-display' after
 changing this variable for it to take effect.  */);
   Vface_remapping_alist = Qnil;
+  DEFSYM (Qface_remapping_alist,"face-remapping-alist");
 
   DEFVAR_LISP ("face-font-rescale-alist", Vface_font_rescale_alist,
               doc: /* Alist of fonts vs the rescaling factors.
diff --git a/src/xmenu.c b/src/xmenu.c
index 10e882a..31034f7 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -2420,6 +2420,6 @@ syms_of_xmenu (void)
 #if defined (USE_GTK) || defined (USE_X_TOOLKIT)
   defsubr (&Sx_menu_bar_open_internal);
   Ffset (intern_c_string ("accelerate-menu"),
-        intern_c_string (Sx_menu_bar_open_internal.symbol_name));
+        intern_c_string (Sx_menu_bar_open_internal.s.symbol_name));
 #endif
 }
diff --git a/test/lisp/emacs-lisp/pcase-tests.el 
b/test/lisp/emacs-lisp/pcase-tests.el
index 774a488..c706c10 100644
--- a/test/lisp/emacs-lisp/pcase-tests.el
+++ b/test/lisp/emacs-lisp/pcase-tests.el
@@ -53,7 +53,7 @@
   (should (pcase-tests-grep
            'memq (macroexpand-all '(pcase x ((or 1 2 3) body)))))
   (should (pcase-tests-grep
-           'member (macroexpand-all '(pcase x ((or '"a" '2 '3) body)))))
+           'member (macroexpand-all '(pcase x ((or "a" 2 3) body)))))
   (should-not (pcase-tests-grep
                'memq (macroexpand-all '(pcase x ((or "a" 2 3) body)))))
   (let ((exp (macroexpand-all
diff --git a/test/lisp/emacs-lisp/timer-tests.el 
b/test/lisp/emacs-lisp/timer-tests.el
index c5971ee..e463b9e 100644
--- a/test/lisp/emacs-lisp/timer-tests.el
+++ b/test/lisp/emacs-lisp/timer-tests.el
@@ -44,4 +44,24 @@
           (timer-next-integral-multiple-of-time '(0 0 0 1) (1+ (ash 1 53)))
           (list (ash 1 (- 53 16)) 1))))
 
+(ert-deftest timer-next-integral-multiple-of-time-2 ()
+  "Test bug#33071."
+  (let* ((tc (current-time))
+         (delta-ticks 1000)
+         (hz 128000)
+         (tce (encode-time tc hz))
+         (tc+delta (time-add tce (cons delta-ticks hz)))
+         (tc+deltae (encode-time tc+delta hz))
+         (tc+delta-ticks (car tc+deltae))
+         (tc-nexte (cons (- tc+delta-ticks (% tc+delta-ticks delta-ticks)) hz))
+         (nt (timer-next-integral-multiple-of-time
+              tc (/ (float delta-ticks) hz)))
+         (nte (encode-time nt hz)))
+    (should (equal tc-nexte nte))))
+
+(ert-deftest timer-next-integral-multiple-of-time-3 ()
+  "Test bug#33071."
+  (let ((nt (timer-next-integral-multiple-of-time '(32770 . 65539) 0.5)))
+    (should (time-equal-p 1 nt))))
+
 ;;; timer-tests.el ends here
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index 0523d8b..6bc36cf 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -763,8 +763,8 @@ handled properly.  BODY shall not contain a timeout."
        "|-:address@hidden"
        "|-:address@hidden:/path/to/file"))
       (format "/%s:address@hidden|%s:address@hidden|%s:address@hidden:"
-             "-" "user1" "host1"
-             "-" "user2" "host2"
+             "method1" "user1" "host1"
+             "method2" "user2" "host2"
              "method3" "user3" "host3")))
 
     ;; Expand `tramp-default-user-alist'.
@@ -778,9 +778,9 @@ handled properly.  BODY shall not contain a timeout."
        "/method1:host1"
        "|method2:host2"
        "|method3:host3:/path/to/file"))
-      (format "/%s:%s|%s:%s|%s:address@hidden:"
-             "method1" "host1"
-             "method2" "host2"
+      (format "/%s:address@hidden|%s:address@hidden|%s:address@hidden:"
+             "method1" "user1" "host1"
+             "method2" "user2" "host2"
              "method3" "user3" "host3")))
 
     ;; Expand `tramp-default-host-alist'.
@@ -794,9 +794,36 @@ handled properly.  BODY shall not contain a timeout."
        "/method1:user1@"
        "|method2:user2@"
        "|method3:user3@:/path/to/file"))
-      (format "/%s:%s@|%s:%s@|%s:address@hidden:"
-             "method1" "user1"
-             "method2" "user2"
+      (format "/%s:address@hidden|%s:address@hidden|%s:address@hidden:"
+             "method1" "user1" "host1"
+             "method2" "user2" "host2"
+             "method3" "user3" "host3")))
+
+    ;; Ad-hoc user name and host name expansion.
+    (setq tramp-default-method-alist nil
+         tramp-default-user-alist nil
+         tramp-default-host-alist nil)
+    (should
+     (string-equal
+      (file-remote-p
+       (concat
+       "/method1:address@hidden"
+       "|method2:user2@"
+       "|method3:user3@:/path/to/file"))
+      (format "/%s:address@hidden|%s:address@hidden|%s:address@hidden:"
+             "method1" "user1" "host1"
+             "method2" "user2" "host1"
+             "method3" "user3" "host1")))
+    (should
+     (string-equal
+      (file-remote-p
+       (concat
+       "/method1:address@hidden"
+       "|method2:address@hidden"
+       "|method3:address@hidden:/path/to/file"))
+      (format "/%s:address@hidden|%s:address@hidden|%s:address@hidden:"
+             "method1" "user3" "host3"
+             "method2" "user3" "host3"
              "method3" "user3" "host3")))))
 
 (ert-deftest tramp-test02-file-name-dissect-simplified ()
@@ -1067,9 +1094,9 @@ handled properly.  BODY shall not contain a timeout."
              "/host1"
              "|host2"
              "|host3:/path/to/file"))
-           (format "/%s|%s|address@hidden:"
-                   "host1"
-                   "host2"
+           (format "/address@hidden|address@hidden|address@hidden:"
+                   "user1" "host1"
+                   "user2" "host2"
                    "user3" "host3")))
 
          ;; Expand `tramp-default-host-alist'.
@@ -1083,9 +1110,35 @@ handled properly.  BODY shall not contain a timeout."
              "/user1@"
              "|user2@"
              "|user3@:/path/to/file"))
-           (format "/%s@|%s@|address@hidden:"
-                   "user1"
-                   "user2"
+           (format "/address@hidden|address@hidden|address@hidden:"
+                   "user1" "host1"
+                   "user2" "host2"
+                   "user3" "host3")))
+
+         ;; Ad-hoc user name and host name expansion.
+         (setq tramp-default-user-alist nil
+               tramp-default-host-alist nil)
+         (should
+          (string-equal
+           (file-remote-p
+            (concat
+             "/address@hidden"
+             "|user2@"
+             "|user3@:/path/to/file"))
+           (format "/address@hidden|address@hidden|address@hidden:"
+                   "user1" "host1"
+                   "user2" "host1"
+                   "user3" "host1")))
+         (should
+          (string-equal
+           (file-remote-p
+            (concat
+             "/address@hidden"
+             "|address@hidden"
+             "|address@hidden:/path/to/file"))
+           (format "/address@hidden|address@hidden|address@hidden:"
+                   "user3" "host3"
+                   "user3" "host3"
                    "user3" "host3"))))
 
       ;; Exit.
@@ -1670,9 +1723,9 @@ handled properly.  BODY shall not contain a timeout."
              "/[/address@hidden"
              "|/address@hidden"
              "|/address@hidden/path/to/file"))
-           (format "/[/address@hidden|/address@hidden|%s/address@hidden"
-                   "user1" "host1"
-                   "user2" "host2"
+           (format "/[%s/address@hidden|%s/address@hidden|%s/address@hidden"
+                   "method1" "user1" "host1"
+                   "method2" "user2" "host2"
                    "method3" "user3" "host3")))
 
          ;; Expand `tramp-default-user-alist'.
@@ -1686,9 +1739,9 @@ handled properly.  BODY shall not contain a timeout."
              "/[method1/host1"
              "|method2/host2"
              "|method3/host3]/path/to/file"))
-           (format "/[%s/%s|%s/%s|%s/address@hidden"
-                   "method1" "host1"
-                   "method2" "host2"
+           (format "/[%s/address@hidden|%s/address@hidden|%s/address@hidden"
+                   "method1" "user1" "host1"
+                   "method2" "user2" "host2"
                    "method3" "user3" "host3")))
 
          ;; Expand `tramp-default-host-alist'.
@@ -1702,9 +1755,36 @@ handled properly.  BODY shall not contain a timeout."
              "/[method1/user1@"
              "|method2/user2@"
              "|method3/address@hidden/path/to/file"))
-           (format "/[%s/%s@|%s/%s@|%s/address@hidden"
-                   "method1" "user1"
-                   "method2" "user2"
+           (format "/[%s/address@hidden|%s/address@hidden|%s/address@hidden"
+                   "method1" "user1" "host1"
+                   "method2" "user2" "host2"
+                   "method3" "user3" "host3")))
+
+         ;; Ad-hoc user name and host name expansion.
+         (setq tramp-default-method-alist nil
+               tramp-default-user-alist nil
+               tramp-default-host-alist nil)
+         (should
+          (string-equal
+           (file-remote-p
+            (concat
+             "/[method1/address@hidden"
+             "|method2/user2@"
+             "|method3/address@hidden/path/to/file"))
+           (format "/[%s/address@hidden|%s/address@hidden|%s/address@hidden"
+                   "method1" "user1" "host1"
+                   "method2" "user2" "host1"
+                   "method3" "user3" "host1")))
+         (should
+          (string-equal
+           (file-remote-p
+            (concat
+             "/[method1/address@hidden"
+             "|method2/address@hidden"
+             "|method3/address@hidden/path/to/file"))
+           (format "/[%s/address@hidden|%s/address@hidden|%s/address@hidden"
+                   "method1" "user3" "host3"
+                   "method2" "user3" "host3"
                    "method3" "user3" "host3"))))
 
       ;; Exit.
@@ -3491,6 +3571,7 @@ This tests also `make-symbolic-link', `file-truename' and 
`add-name-to-file'."
   (when (not (memq system-type '(cygwin windows-nt)))
     (let ((method (file-remote-p tramp-test-temporary-file-directory 'method))
          (host (file-remote-p tramp-test-temporary-file-directory 'host))
+         (vec (tramp-dissect-file-name tramp-test-temporary-file-directory))
           (orig-syntax tramp-syntax))
       (when (and (stringp host) (string-match tramp-host-with-port-regexp 
host))
        (setq host (match-string 1 host)))
@@ -3501,6 +3582,10 @@ This tests also `make-symbolic-link', `file-truename' 
and `add-name-to-file'."
               (if (tramp--test-expensive-test)
                   (tramp-syntax-values) `(,orig-syntax)))
             (tramp-change-syntax syntax)
+           ;; This has cleaned up all connection data, which are used
+           ;; for completion.  We must refill the cache.
+           (tramp-set-connection-property vec "property" nil)
+
             (let ;; This is needed for the `simplified' syntax.
                 ((method-marker
                   (if (zerop (length tramp-method-regexp))
diff --git a/test/src/buffer-tests.el b/test/src/buffer-tests.el
index 0e4fd36..609585f 100644
--- a/test/src/buffer-tests.el
+++ b/test/src/buffer-tests.el
@@ -79,4 +79,19 @@ with parameters from the *Messages* buffer modification."
   (with-temp-buffer
     (should (eq (buffer-base-buffer (current-buffer)) nil))))
 
+(ert-deftest overlay-evaporation-after-killed-buffer ()
+  (let* ((ols (with-temp-buffer
+                (insert "toto")
+                (list
+                 (make-overlay (point-min) (point-max))
+                 (make-overlay (point-min) (point-max))
+                 (make-overlay (point-min) (point-max)))))
+         (ol (nth 1 ols)))
+    (overlay-put ol 'evaporate t)
+    ;; Evaporation within move-overlay of an overlay that was deleted because
+    ;; of a kill-buffer, triggered an assertion failure in unchain_both.
+    (with-temp-buffer
+      (insert "toto")
+      (move-overlay ol (point-min) (point-min)))))
+
 ;;; buffer-tests.el ends here
diff --git a/test/src/eval-tests.el b/test/src/eval-tests.el
index 281d959..0c24291 100644
--- a/test/src/eval-tests.el
+++ b/test/src/eval-tests.el
@@ -139,4 +139,34 @@ crash/abort/malloc assert failure on the next test."
                   (defvaralias 'eval-tests--foo-alias 'eval-tests--foo)
                   'no-warning)))))
 
+(ert-deftest eval-tests-byte-code-being-evaluated-is-protected-from-gc ()
+  "Regression test for Bug#33014.
+Check that byte-compiled objects being executed by exec-byte-code
+are found on the stack and therefore not garbage collected."
+  (should (string= (eval-tests-33014-func)
+                   "before after: ok foo: (e) bar: (a b c d e) baz: a bop: 
c")))
+
+(defvar eval-tests-33014-var "ok")
+(defun eval-tests-33014-func ()
+  "A function which has a non-trivial constants vector when byte-compiled."
+  (let ((result "before "))
+    (eval-tests-33014-redefine)
+    (garbage-collect)
+    (setq result (concat result (format "after: %s" eval-tests-33014-var)))
+    (let ((vals '(0 1 2 3))
+          (things '(a b c d e)))
+      (dolist (val vals)
+        (setq result
+              (concat result " "
+                      (cond
+                       ((= val 0) (format "foo: %s" (last things)))
+                       ((= val 1) (format "bar: %s" things))
+                       ((= val 2) (format "baz: %s" (car things)))
+                       (t (format "bop: %s" (nth 2 things))))))))
+    result))
+
+(defun eval-tests-33014-redefine ()
+  "Remove the Lisp reference to the byte-compiled object."
+  (setf (symbol-function #'eval-tests-33014-func) nil))
+
 ;;; eval-tests.el ends here
diff --git a/test/src/json-tests.el b/test/src/json-tests.el
index 911bc49..bffee8f 100644
--- a/test/src/json-tests.el
+++ b/test/src/json-tests.el
@@ -272,10 +272,11 @@ Test with both unibyte and multibyte strings."
                   (cl-incf calls)
                   (throw 'test-tag 'throw-value))
                 :local)
-      (should-error
-       (catch 'test-tag
-         (json-insert '((a . "b") (c . 123) (d . [1 2 t :false]))))
-       :type 'no-catch)
+      (should
+       (equal
+        (catch 'test-tag
+          (json-insert '((a . "b") (c . 123) (d . [1 2 t :false]))))
+        'throw-value))
       (should (equal calls 1)))))
 
 (ert-deftest json-serialize/bignum ()
diff --git a/test/src/thread-tests.el b/test/src/thread-tests.el
index 109e711..36bb637 100644
--- a/test/src/thread-tests.el
+++ b/test/src/thread-tests.el
@@ -388,4 +388,8 @@
     (should (= (length (all-threads)) 1))
     (should (equal (thread-last-error) '(error "Die, die, die!")))))
 
+(ert-deftest threads-test-bug33073 ()
+  (let ((th (make-thread 'ignore)))
+    (should-not (equal th main-thread))))
+
 ;;; threads.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]