emacs-diffs
[Top][All Lists]
Advanced

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

feature/native-comp-macos-fixes f0f8d7b: Merge branch 'feature/native-co


From: Vibhav Pant
Subject: feature/native-comp-macos-fixes f0f8d7b: Merge branch 'feature/native-comp' into feature/native-comp-macos-fixes
Date: Fri, 21 Aug 2020 06:23:25 -0400 (EDT)

branch: feature/native-comp-macos-fixes
commit f0f8d7b82492e741950c363a03b886965c91b1b0
Merge: 9e64a08 c818c29
Author: Vibhav Pant <vibhavp@gmail.com>
Commit: Vibhav Pant <vibhavp@gmail.com>

    Merge branch 'feature/native-comp' into feature/native-comp-macos-fixes
---
 ChangeLog.3                               | 100 +++++++++-
 Makefile.in                               |  20 +-
 admin/release-process                     |   8 +-
 configure.ac                              |  31 +++-
 doc/emacs/basic.texi                      |   2 +-
 doc/emacs/custom.texi                     |   1 +
 doc/emacs/fixit.texi                      |  10 +-
 doc/emacs/frames.texi                     |   8 +-
 doc/emacs/maintaining.texi                |   5 +-
 doc/emacs/mini.texi                       |   7 +
 doc/emacs/misc.texi                       |   4 +-
 doc/lispref/commands.texi                 |   7 +
 doc/lispref/functions.texi                |   9 +-
 doc/lispref/searching.texi                |   2 +-
 doc/lispref/sequences.texi                |   6 +-
 doc/lispref/tips.texi                     |   2 +-
 doc/misc/efaq.texi                        |   7 +-
 doc/misc/gnus.texi                        |   8 +-
 doc/misc/message.texi                     |   2 +-
 doc/misc/url.texi                         |   2 -
 etc/HISTORY                               |   2 +-
 etc/NEWS                                  | 217 ++++++++++++++++++----
 etc/NEWS.27                               |  16 +-
 etc/PROBLEMS                              |  38 ----
 lib/c++defs.h                             |  10 +
 lib/canonicalize-lgpl.c                   |   4 +-
 lib/cdefs.h                               |   9 +-
 lib/dup2.c                                |   4 +-
 lib/fcntl.in.h                            |  18 ++
 lib/getopt-cdefs.in.h                     |   2 +-
 lib/gnulib.mk.in                          |   4 +-
 lib/intprops.h                            |   2 +-
 lib/md5.h                                 |   2 +-
 lib/mktime.c                              |   2 +-
 lib/nstrftime.c                           |  22 ++-
 lib/open.c                                |   4 +
 lib/regcomp.c                             |   2 +-
 lib/regex_internal.h                      |   2 +-
 lib/stdio.in.h                            |  46 ++++-
 lib/stdlib.in.h                           |  29 +++
 lib/strftime.h                            |   7 +-
 lib/string.in.h                           |  15 ++
 lib/sys_random.in.h                       |   4 +
 lib/sys_select.in.h                       |   6 +-
 lib/sys_stat.in.h                         |  14 ++
 lib/sys_time.in.h                         |   2 +-
 lib/time.in.h                             |  12 +-
 lib/time_rz.c                             |  51 ++----
 lib/unistd.in.h                           | 159 ++++++++++++++++
 lib/verify.h                              |  41 +++--
 lisp/Makefile.in                          |  13 +-
 lisp/abbrev.el                            |  10 -
 lisp/bookmark.el                          |  13 --
 lisp/buff-menu.el                         |   3 -
 lisp/cedet/ede/make.el                    |  24 +--
 lisp/cedet/semantic/bovine/c.el           |  25 +--
 lisp/cedet/semantic/dep.el                |  18 +-
 lisp/cedet/semantic/lex-spp.el            |   4 +-
 lisp/comint.el                            |  16 +-
 lisp/cus-edit.el                          |  27 ++-
 lisp/descr-text.el                        |   3 +-
 lisp/desktop.el                           |   2 +-
 lisp/dirtrack.el                          |   3 -
 lisp/doc-view.el                          |  46 +++--
 lisp/emacs-lisp/bytecomp.el               |   6 +-
 lisp/emacs-lisp/chart.el                  |   4 +-
 lisp/emacs-lisp/comp.el                   |  64 +++----
 lisp/emacs-lisp/crm.el                    |   6 -
 lisp/emacs-lisp/derived.el                |   1 +
 lisp/emacs-lisp/easymenu.el               |  10 -
 lisp/emacs-lisp/ert.el                    |   9 +-
 lisp/emacs-lisp/find-func.el              |  11 +-
 lisp/emacs-lisp/lisp-mode.el              |   6 +-
 lisp/emacs-lisp/rx.el                     |   4 +-
 lisp/emulation/viper-cmd.el               |  27 ++-
 lisp/emulation/viper-mous.el              |   2 +-
 lisp/emulation/viper-util.el              |  20 +-
 lisp/epa.el                               |   4 -
 lisp/epg.el                               |  16 +-
 lisp/erc/erc-backend.el                   |   3 +-
 lisp/erc/erc-dcc.el                       |   8 +-
 lisp/erc/erc-fill.el                      |   2 +-
 lisp/erc/erc-goodies.el                   |   3 +-
 lisp/erc/erc-log.el                       |   2 +-
 lisp/erc/erc-match.el                     |  67 ++++---
 lisp/erc/erc-notify.el                    |   2 +-
 lisp/erc/erc-pcomplete.el                 |   1 -
 lisp/erc/erc-stamp.el                     |   1 -
 lisp/erc/erc-track.el                     |  12 +-
 lisp/erc/erc.el                           |  27 ++-
 lisp/eshell/em-rebind.el                  |   1 -
 lisp/eshell/esh-io.el                     |   7 +-
 lisp/eshell/esh-mode.el                   |  75 ++++----
 lisp/eshell/eshell.el                     |   9 -
 lisp/ffap.el                              | 139 +++++++++++++-
 lisp/files.el                             |  13 +-
 lisp/forms.el                             |  25 +--
 lisp/gnus/gnus-sum.el                     |   3 +-
 lisp/gnus/message.el                      |  63 ++++---
 lisp/gnus/mml-smime.el                    |   1 -
 lisp/gnus/mml1991.el                      |   1 -
 lisp/gnus/mml2015.el                      |   1 -
 lisp/gnus/smiley.el                       |  13 +-
 lisp/help-fns.el                          |   6 +-
 lisp/hi-lock.el                           |   6 -
 lisp/hilit-chg.el                         |  16 --
 lisp/htmlfontify.el                       |   5 +-
 lisp/icomplete.el                         |  11 +-
 lisp/ido.el                               |  12 +-
 lisp/image/gravatar.el                    | 111 ++++++++---
 lisp/international/mule-cmds.el           |   5 -
 lisp/international/mule-diag.el           |   4 -
 lisp/international/mule-util.el           |   9 -
 lisp/international/mule.el                | 135 +-------------
 lisp/ldefs-boot.el                        |   6 +-
 lisp/loadup.el                            |  44 ++---
 lisp/mail/binhex.el                       |  10 +-
 lisp/mail/emacsbug.el                     |  12 --
 lisp/mail/flow-fill.el                    |  36 ++--
 lisp/mail/rmail.el                        |  19 --
 lisp/mail/rmailedit.el                    |   4 +-
 lisp/mail/uudecode.el                     |  14 +-
 lisp/minibuffer.el                        |  28 +--
 lisp/mouse.el                             |  28 ---
 lisp/mwheel.el                            |  29 ++-
 lisp/net/eudc-bob.el                      | 130 +++++--------
 lisp/net/eww.el                           |  25 ++-
 lisp/net/newst-treeview.el                |  30 +--
 lisp/net/ntlm.el                          |  44 ++---
 lisp/net/tramp-sh.el                      |  98 ----------
 lisp/net/tramp.el                         | 103 ++++++++++-
 lisp/{erc => obsolete}/erc-compat.el      |   1 +
 lisp/obsolete/tpu-edt.el                  |  12 +-
 lisp/password-cache.el                    |  16 --
 lisp/progmodes/cc-engine.el               |   2 +-
 lisp/progmodes/compile.el                 |   9 +-
 lisp/progmodes/cperl-mode.el              |   3 +
 lisp/progmodes/ebnf2ps.el                 |   4 +-
 lisp/progmodes/elisp-mode.el              |  10 +-
 lisp/progmodes/etags.el                   |   4 +
 lisp/progmodes/idlw-help.el               |   3 +-
 lisp/progmodes/idlw-shell.el              |   7 +-
 lisp/progmodes/idlwave.el                 | 193 ++++----------------
 lisp/progmodes/perl-mode.el               |   4 +-
 lisp/progmodes/project.el                 |  22 +--
 lisp/progmodes/python.el                  |  19 +-
 lisp/progmodes/subword.el                 |   2 +
 lisp/progmodes/xref.el                    |  43 +++--
 lisp/ps-def.el                            |  18 +-
 lisp/ps-print.el                          |   8 +-
 lisp/savehist.el                          |   4 +-
 lisp/shell.el                             |  57 +++---
 lisp/simple.el                            |  22 ++-
 lisp/so-long.el                           |  64 ++++++-
 lisp/speedbar.el                          |  28 +--
 lisp/startup.el                           |  14 +-
 lisp/subr.el                              |  10 +-
 lisp/t-mouse.el                           |   2 -
 lisp/term.el                              |  32 +++-
 lisp/term/w32-win.el                      |   4 -
 lisp/textmodes/bibtex.el                  |   1 +
 lisp/textmodes/flyspell.el                |  61 +++----
 lisp/textmodes/ispell.el                  |  16 +-
 lisp/textmodes/remember.el                |   3 -
 lisp/thingatpt.el                         |   2 +-
 lisp/time.el                              | 294 ++++++++++++++++--------------
 lisp/tooltip.el                           |   2 -
 lisp/url/url-expand.el                    |   2 +-
 lisp/url/url-util.el                      |  25 ---
 lisp/url/url-vars.el                      |   7 -
 lisp/vc/diff-mode.el                      |   2 +-
 lisp/vc/ediff-init.el                     |   5 +-
 lisp/vc/ediff-util.el                     |  22 +--
 lisp/vc/vc-git.el                         |  18 +-
 lisp/vc/vc-hooks.el                       |   8 -
 lisp/vc/vc-mtn.el                         |   1 -
 lisp/vc/vc.el                             |   3 -
 lisp/vcursor.el                           |   3 -
 lisp/vt-control.el                        |   2 +-
 lisp/window.el                            |  21 ++-
 lisp/woman.el                             |   4 +-
 m4/00gnulib.m4                            |  38 +---
 m4/absolute-header.m4                     |  10 +-
 m4/alloca.m4                              |   4 +-
 m4/canonicalize.m4                        |  14 +-
 m4/dup2.m4                                |   3 +-
 m4/fchmodat.m4                            |   4 +-
 m4/fcntl.m4                               |   3 +-
 m4/fdopendir.m4                           |  20 +-
 m4/fpending.m4                            |   4 +-
 m4/futimens.m4                            |   5 +-
 m4/getdtablesize.m4                       |  19 +-
 m4/getloadavg.m4                          |   4 +-
 m4/getrandom.m4                           |   5 +-
 m4/gnulib-common.m4                       |  82 +++++++--
 m4/include_next.m4                        |  18 +-
 m4/largefile.m4                           |   6 +-
 m4/manywarnings.m4                        |   8 +-
 m4/mktime.m4                              |   8 +-
 m4/nstrftime.m4                           |   4 +-
 m4/open-slash.m4                          |   3 +-
 m4/pselect.m4                             |   5 +-
 m4/pthread_sigmask.m4                     |   3 +-
 m4/sys_random_h.m4                        |   5 +-
 m4/time_h.m4                              |   1 -
 m4/utimens.m4                             |   5 +-
 m4/utimensat.m4                           |   5 +-
 m4/utimes.m4                              |   3 +-
 m4/warnings.m4                            |  21 +--
 src/Makefile.in                           |   6 +-
 src/ccl.c                                 | 115 +++++++++---
 src/charset.c                             |   9 +-
 src/coding.c                              |  12 +-
 src/comp.c                                | 150 +++++++++++++--
 src/comp.h                                |   2 +
 src/composite.c                           |   4 +-
 src/emacs.c                               |  16 +-
 src/fns.c                                 |  30 +--
 src/font.c                                |  74 ++++----
 src/fontset.c                             |  27 +--
 src/ftfont.c                              |  12 +-
 src/hbfont.c                              |  11 +-
 src/image.c                               |  71 +++++---
 src/lisp.h                                |  18 +-
 src/lread.c                               | 214 ++++++++--------------
 src/macfont.m                             |   6 +-
 src/minibuf.c                             |   2 +-
 src/nsselect.m                            |   2 +-
 src/nsterm.m                              |  23 +--
 src/nsxwidget.m                           |   4 +-
 src/pdumper.c                             |  38 +++-
 src/search.c                              |  13 +-
 src/syntax.c                              |   4 +-
 src/sysdep.c                              |  35 +++-
 src/timefns.c                             |  33 ++--
 src/window.c                              |   2 +-
 src/xdisp.c                               |   8 +-
 src/xfaces.c                              |  28 ++-
 src/xfns.c                                |  13 +-
 src/xrdb.c                                |   4 +-
 src/xselect.c                             |  21 ++-
 src/xterm.c                               |  21 +++
 src/xterm.h                               |   1 +
 src/xwidget.c                             |   4 +-
 test/lisp/cedet/srecode-utest-template.el |   5 +-
 test/lisp/emacs-lisp/bytecomp-tests.el    |  43 ++---
 test/lisp/emacs-lisp/cl-lib-tests.el      |  16 ++
 test/lisp/ffap-tests.el                   |  40 ++++
 test/lisp/mail/flow-fill-tests.el         |   3 +-
 test/lisp/progmodes/compile-tests.el      |   4 +-
 test/lisp/progmodes/cperl-mode-tests.el   |  51 ++++++
 test/lisp/simple-tests.el                 |   7 +
 test/lisp/textmodes/bibtex-tests.el       |  57 ++++++
 test/lisp/textmodes/paragraphs-tests.el   |   4 +-
 test/lisp/url/url-expand-tests.el         |   7 +
 test/manual/etags/c-src/abbrev.c          |  14 --
 test/manual/image-circular-tests.el       | 144 +++++++++++++++
 test/src/comp-tests.el                    |   3 +-
 test/src/fns-tests.el                     |   6 +
 259 files changed, 3220 insertions(+), 2489 deletions(-)

diff --git a/ChangeLog.3 b/ChangeLog.3
index c8dd40b..1a53011 100644
--- a/ChangeLog.3
+++ b/ChangeLog.3
@@ -1,3 +1,99 @@
+2020-08-03  Phil Sainty  <psainty@orcon.net.nz>
+
+       lisp/so-long.el: Improve support for major mode hooks
+
+       * lisp/so-long.el (so-long-remember-all, so-long-disable-minor-modes)
+       (so-long-override-variables): Store and use the `so-long-minor-modes'
+       and `so-long-variable-overrides' values seen by the original major
+       mode, so that buffer-local changes made in the major mode hook will be
+       respected.
+
+       Add documentation of this and other major mode hook usage.
+
+2020-08-02  Grégory Mounié  <Gregory.Mounie@imag.fr>  (tiny change)
+
+       Avoid segfaults if XIM is set but not xim_styles
+
+       Emacs segfaults at the X11 initialization if XIM is set
+       and xim_styles is NULL.  This patch avoids the crash.
+       * src/xfns.c: Check also if FRAME_X_XIM_STYLES(f) is NULL.
+       (Bug#42676)  (Bug#42673)  (Bug#42677)
+
+2020-07-31  Philipp Stephani  <phst@google.com>
+
+       Backport: Make checking for liveness of global values more precise.
+
+       We can't just use a hash lookup because a global and a local reference
+       might refer to the same Lisp object.
+
+       * src/emacs-module.c (module_free_global_ref): More precise check for
+       global liveness.
+
+       (cherry picked from commit 9f01ce6327af886f26399924a9aadf16cdd4fd9f)
+
+2020-07-31  Philipp Stephani  <phst@google.com>
+
+       Backport: Fix subtle bug when checking liveness of module values.
+
+       We can't simply look up the Lisp object in the global reference table
+       because an invalid local and a valid global reference might refer to
+       the same object.  Instead, we have to test the address of the global
+       reference against the stored references.
+
+       * src/emacs-module.c (module_global_reference_p): New helper function.
+       (value_to_lisp): Use it.
+
+       (cherry picked from commit 6355a3ec62f43c9b99d483982ff851d32dd78891)
+
+2020-07-31  Philipp Stephani  <phst@google.com>
+
+       Backport: Fix memory leak for global module objects (Bug#42482).
+
+       Instead of storing the global values in a global 'emacs_value_storage'
+       object, store them as hash values alongside the reference counts.
+       That way the garbage collector takes care of cleaning them up.
+
+       * src/emacs-module.c (global_storage): Remove.
+       (struct module_global_reference): New pseudovector type.
+       (XMODULE_GLOBAL_REFERENCE): New helper function.
+       (module_make_global_ref, module_free_global_ref): Use
+       'module_global_reference' struct for global reference values.
+       (value_to_lisp, module_handle_nonlocal_exit): Adapt to deletion of
+       'global_storage'.
+
+       (cherry picked from commit 5c5eb9790898e4ab10bcbbdb6871947ed3018569)
+
+2020-07-30  Nicolas Petton  <nicolas@petton.fr>
+
+       * admin/authors.el (authors-aliases): Remove a faulty regexp.
+
+2020-07-29  Stefan Kangas  <stefankangas@gmail.com>
+
+       * doc/lispref/symbols.texi (Definitions): Fix typo.
+
+2020-07-28  Nicolas Petton  <nicolas@petton.fr>
+
+       * etc/HISTORY: Add Emacs 27.1 release date.
+
+2020-07-28  Nicolas Petton  <nicolas@petton.fr>
+
+       Bump Emacs version to 27.1
+
+       * README:
+       * configure.ac:
+       * msdos/sed2v2.inp:
+       * nt/README.W32: Bump Emacs version.
+
+2020-07-28  Nicolas Petton  <nicolas@petton.fr>
+
+       * etc/AUTHORS: Update.
+
+2020-07-28  Nicolas Petton  <nicolas@petton.fr>
+
+       Update authors.el
+
+       * admin/authors.el (authors-aliases): Add author aliases.
+
 2020-07-28  Nicolas Petton  <nicolas@petton.fr>
 
        * etc/NEWS: Remove temporary markup.
@@ -2862,7 +2958,7 @@
        * doc/lispref/searching.texi (Rx Constructs): Document.
        * lisp/emacs-lisp/rx.el (rx--normalise-or-arg)
        (rx--all-string-or-args): New.
-       (rx--translate-or): Normalise arguments first, and check for strings
+       (rx--translate-or): Normalize arguments first, and check for strings
        in subforms.
        (rx--expand-eval): Extracted from rx--translate-eval.
        (rx--translate-eval): Call rx--expand-eval.
@@ -142382,7 +142478,7 @@
 
 This file records repository revisions from
 commit 9d56a21e6a696ad19ac65c4b405aeca44785884a (exclusive) to
-commit 56f958807c0b8ea8f45e3c088157ca144a1b1fac (inclusive).
+commit 1ca4da054be7eb340c511d817f3ec89c8b819db7 (inclusive).
 See ChangeLog.2 for earlier changes.
 
 ;; Local Variables:
diff --git a/Makefile.in b/Makefile.in
index 03dd881..e951c4f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -108,6 +108,8 @@ am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
 am__v_at_0 = @
 am__v_at_1 =
 
+HAVE_NATIVE_COMP = @HAVE_NATIVE_COMP@
+
 # ==================== Where To Install Things ====================
 
 # Location to install Emacs.app under GNUstep / macOS.
@@ -330,6 +332,8 @@ CONFIG_STATUS_FILES_IN = \
 COPYDIR = ${srcdir}/etc ${srcdir}/lisp
 COPYDESTS = "$(DESTDIR)${etcdir}" "$(DESTDIR)${lispdir}"
 
+ELN_DESTDIR = "$(DESTDIR)${libexecdir}/emacs/${version}/${configuration}/"
+
 all: ${SUBDIR} info
 
 .PHONY: all ${SUBDIR} blessmail epaths-force epaths-force-w32 etc-emacsver
@@ -423,11 +427,12 @@ VCSWITNESS = $(if $(wildcard 
$(srcdir)/$(dirstate)),$$(srcdir)/../$(dirstate))
 src: Makefile
 ifeq (${ns_self_contained},no)
        $(MAKE) -C $@ VCSWITNESS='$(VCSWITNESS)' 
BIN_DESTDIR='$(DESTDIR)${bindir}/' \
-                LISP_DESTDIR='$(DESTDIR)${lispdir}/' all
+                ELN_DESTDIR='$(ELN_DESTDIR)' all
 else
        $(MAKE) -C $@ VCSWITNESS='$(VCSWITNESS)' BIN_DESTDIR='${ns_appbindir}/' 
\
-                LISP_DESTDIR='$(DESTDIR)${lispdir}/' all
+                ELN_DESTDIR='$(ELN_DESTDIR)' all
 endif
+
 blessmail: Makefile src
        $(MAKE) -C lib-src maybe-blessmail
 
@@ -466,14 +471,14 @@ $(srcdir)/configure: $(srcdir)/configure.ac 
$(srcdir)/m4/*.m4
 # ==================== Installation ====================
 
 .PHONY: install install-arch-dep install-arch-indep install-etcdoc install-info
-.PHONY: install-man install-etc install-strip install-$(NTDIR)
+.PHONY: install-man install-etc install-strip install-$(NTDIR) install-eln
 .PHONY: uninstall uninstall-$(NTDIR)
 
 ## If we let lib-src do its own installation, that means we
 ## don't have to duplicate the list of utilities to install in
 ## this Makefile as well.
 
-install: all install-arch-indep install-etcdoc install-arch-dep 
install-$(NTDIR) blessmail
+install: all install-arch-indep install-etcdoc install-arch-dep 
install-$(NTDIR) blessmail install-eln
        @true
 
 ## Ensure that $subdir contains a subdirs.el file.
@@ -757,6 +762,12 @@ install-etc:
          done ; \
        done
 
+### Install native compiled Lisp files.
+install-eln:
+ifeq ($(HAVE_NATIVE_COMP),yes)
+       find eln-cache -type f -exec ${INSTALL_DATA} -D "{}" "$(ELN_DESTDIR){}" 
\;
+endif
+
 ### Build Emacs and install it, stripping binaries while installing them.
 install-strip:
        $(MAKE) INSTALL_STRIP=-s install
@@ -867,6 +878,7 @@ clean: $(clean_dirs:=_clean)
        [ ! -d test ] || $(MAKE) -C test $@
        -rm -f ./*.tmp etc/*.tmp*
        -rm -rf info-dir.*
+       -rm -rf eln-cache
 
 ### 'bootclean'
 ###      Delete all files that need to be remade for a clean bootstrap.
diff --git a/admin/release-process b/admin/release-process
index 1ed7a2e..b8587e6 100644
--- a/admin/release-process
+++ b/admin/release-process
@@ -192,16 +192,14 @@ sk        Miroslav Vaško
 ** Check for modes which bind M-s that conflicts with a new global binding M-s
 and change key bindings where necessary.  The current list of modes:
 
-1. Gnus binds 'M-s' to 'gnus-summary-search-article-forward'.
-
-2. Minibuffer binds 'M-s' to 'next-matching-history-element'
+1. Minibuffer binds 'M-s' to 'next-matching-history-element'
    (not useful any more since C-s can now search in the history).
 
-3. PCL-CVS binds 'M-s' to 'cvs-status', and log-edit-mode binds it to
+2. PCL-CVS binds 'M-s' to 'cvs-status', and log-edit-mode binds it to
    'log-edit-comment-search-forward'.  Perhaps search commands
    on the global key binding 'M-s' are useless in these modes.
 
-4. Rmail binds '\es' to 'rmail-search'/'rmail-summary-search'.
+3. Rmail binds '\es' to 'rmail-search'/'rmail-summary-search'.
 
 
 * DOCUMENTATION
diff --git a/configure.ac b/configure.ac
index 4b8497b..0582b2f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -219,6 +219,21 @@ AC_DEFUN([OPTION_DEFAULT_OFF], [dnl
     m4_bpatsubst([with_$1], [[^0-9a-z]], [_])=no])dnl
 ])dnl
 
+dnl OPTION_DEFAULT_IFAVAILABLE(NAME, HELP-STRING)
+dnl Create a new --with option that defaults to 'ifavailable'.
+dnl NAME is the base name of the option.  The shell variable with_NAME
+dnl   will be set to either the user's value (if the option is
+dnl   specified; 'yes' for a plain --with-NAME) or to 'ifavailable' (if the
+dnl   option is not specified).  Note that the shell variable name is
+dnl   constructed as autoconf does, by replacing non-alphanumeric
+dnl   characters with "_".
+dnl HELP-STRING is the help text for the option.
+AC_DEFUN([OPTION_DEFAULT_IFAVAILABLE], [dnl
+  AC_ARG_WITH([$1],[AS_HELP_STRING([--with-$1],[$2])],[],[dnl
+    m4_bpatsubst([with_$1], [[^0-9a-z]], [_])=ifavailable])dnl
+])dnl
+
+
 dnl OPTION_DEFAULT_ON(NAME, HELP-STRING)
 dnl Create a new --with option that defaults to $with_features.
 dnl NAME is the base name of the option.  The shell variable with_NAME
@@ -438,7 +453,7 @@ OPTION_DEFAULT_ON([cairo],[don't compile with Cairo 
drawing])
 OPTION_DEFAULT_ON([xml2],[don't compile with XML parsing support])
 OPTION_DEFAULT_OFF([imagemagick],[compile with ImageMagick image support])
 OPTION_DEFAULT_ON([native-image-api], [don't use native image APIs (GDI+ on 
Windows)])
-OPTION_DEFAULT_ON([json], [don't compile with native JSON support])
+OPTION_DEFAULT_IFAVAILABLE([json], [don't compile with native JSON support])
 
 OPTION_DEFAULT_ON([xft],[don't use XFT for anti aliased fonts])
 OPTION_DEFAULT_ON([harfbuzz],[don't use HarfBuzz for text shaping])
@@ -709,7 +724,7 @@ case "${canonical}" in
   *-apple-darwin* )
     case "${canonical}" in
       *-apple-darwin[0-9].*) unported=yes ;;
-      i[3456]86-* | x86_64-* )  ;;
+      i[3456]86-* | x86_64-* | arm-* )  ;;
       * )            unported=yes ;;
     esac
     opsys=darwin
@@ -1012,7 +1027,10 @@ AS_IF([test $gl_gcc_warnings = no],
     [# Use -fanalyzer and related options only if --enable-gcc-warnings,
      # as they slow GCC considerably.
      nw="$nw -fanalyzer -Wno-analyzer-double-free -Wno-analyzer-malloc-leak"
-     nw="$nw -Wno-analyzer-null-dereference -Wno-analyzer-use-after-free"])
+     nw="$nw -Wno-analyzer-null-dereference -Wno-analyzer-use-after-free"
+     # Use -Wsuggest-attribute=malloc only if --enable-gcc-warnings,
+     # as it doesn't flag code that is wrong in any way.
+     nw="$nw -Wsuggest-attribute=malloc"])
 
   nw="$nw -Wcast-align=strict"      # Emacs is tricky with pointers.
   nw="$nw -Wduplicated-branches"    # Too many false alarms
@@ -2927,7 +2945,7 @@ AC_SUBST(LIBSYSTEMD_CFLAGS)
 HAVE_JSON=no
 JSON_OBJ=
 
-if test "${with_json}" = yes; then
+if test "${with_json}" != no; then
   EMACS_CHECK_MODULES([JSON], [jansson >= 2.7],
     [HAVE_JSON=yes], [HAVE_JSON=no])
   if test "${HAVE_JSON}" = yes; then
@@ -3965,6 +3983,11 @@ case $with_gnutls,$HAVE_GNUTLS in
   *) MISSING="$MISSING gnutls"
      WITH_IFAVAILABLE="$WITH_IFAVAILABLE --with-gnutls=ifavailable";;
 esac
+case $with_json,$HAVE_JSON in
+  no,* | ifavailable,* | *,yes) ;;
+  *) MISSING="$MISSING json"
+     WITH_IFAVAILABLE="$WITH_IFAVAILABLE --with-json=ifavailable";;
+esac
 if test "X${MISSING}" != X; then
   AC_MSG_ERROR([The following required libraries were not found:
     $MISSING
diff --git a/doc/emacs/basic.texi b/doc/emacs/basic.texi
index abb385f..0b685fa 100644
--- a/doc/emacs/basic.texi
+++ b/doc/emacs/basic.texi
@@ -115,7 +115,7 @@ just like digits.  Case is ignored.
 starting with @kbd{C-x 8}.  For example, @kbd{C-x 8 [} inserts @t{‘}
 which is Unicode code-point U+2018 @sc{left single quotation mark},
 sometimes called a left single ``curved quote'' or ``curly quote''.
-Similarly, @kbd{C-x 8 ]}, @kbd{C-x 8 @{} and @kbd{C-x 8 @}} insert the
+Similarly, @w{@kbd{C-x 8 ]}}, @kbd{C-x 8 @{} and @kbd{C-x 8 @}} insert the
 curved quotes @t{’}, @t{“} and @t{”}, respectively.  Also, a working
 @key{Alt} key acts like @kbd{C-x 8} (unless followed by @key{RET});
 e.g., @kbd{A-[} acts like @kbd{C-x 8 [} and inserts @t{‘}.  To see
diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi
index acd7fb1..a512fd1 100644
--- a/doc/emacs/custom.texi
+++ b/doc/emacs/custom.texi
@@ -2605,6 +2605,7 @@ the function or facility is available, like this:
 (if (fboundp 'blink-cursor-mode)
     (blink-cursor-mode 0))
 
+@c FIXME: Find better example since `set-coding-priority' is removed.
 (if (boundp 'coding-category-utf-8)
     (set-coding-priority '(coding-category-utf-8)))
 @end example
diff --git a/doc/emacs/fixit.texi b/doc/emacs/fixit.texi
index 5046146..6633848 100644
--- a/doc/emacs/fixit.texi
+++ b/doc/emacs/fixit.texi
@@ -445,12 +445,14 @@ use @code{flyspell-region} or @code{flyspell-buffer} for 
that.
 @findex flyspell-correct-word-before-point
   When Flyspell mode highlights a word as misspelled, you can click on
 it with @kbd{mouse-2} (@code{flyspell-correct-word}) to display a menu
-of possible corrections and actions.  In addition, @kbd{C-.} or
+of possible corrections and actions.  If you want this menu on
+@kbd{mouse-3} instead, customize the variable
+@code{flyspell-use-mouse-3-for-menu}.  In addition, @kbd{C-.} or
 @kbd{@key{ESC}-@key{TAB}} (@code{flyspell-auto-correct-word}) will
 propose various successive corrections for the word at point, and
-@w{@kbd{C-c $}} (@code{flyspell-correct-word-before-point}) will pop up a
-menu of possible corrections.  Of course, you can always correct the
-misspelled word by editing it manually in any way you like.
+@w{@kbd{C-c $}} (@code{flyspell-correct-word-before-point}) will pop
+up a menu of possible corrections.  Of course, you can always correct
+the misspelled word by editing it manually in any way you like.
 
 @findex flyspell-prog-mode
   Flyspell Prog mode works just like ordinary Flyspell mode, except
diff --git a/doc/emacs/frames.texi b/doc/emacs/frames.texi
index b99d8ab..b748876 100644
--- a/doc/emacs/frames.texi
+++ b/doc/emacs/frames.texi
@@ -366,9 +366,13 @@ instead of running the @code{mouse-save-then-kill} 
command, rebind
 @kbd{mouse-3} by adding the following line to your init file
 (@pxref{Init Rebinding}):
 
-@c FIXME: `mouse-popup-menubar-stuff' is obsolete since 23.1.
 @smallexample
-(global-set-key [mouse-3] 'mouse-popup-menubar-stuff)
+(global-set-key [mouse-3]
+  '(menu-item "Menu Bar" ignore
+    :filter (lambda (_)
+              (if (zerop (or (frame-parameter nil 'menu-bar-lines) 0))
+                  (mouse-menu-bar-map)
+                (mouse-menu-major-mode-map)))))
 @end smallexample
 
 @node Mode Line Mouse
diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi
index 43ec2d4..9f550b4 100644
--- a/doc/emacs/maintaining.texi
+++ b/doc/emacs/maintaining.texi
@@ -1793,13 +1793,12 @@ for a buffer to switch and considering only the current 
project's
 buffers as candidates for completion.
 
 @findex project-kill-buffers
-@vindex project-kill-buffers-ignores
+@vindex project-kill-buffer-conditions
   When you finish working on the project, you may wish to kill all the
 buffers that belong to the project, to keep your Emacs session
 smaller.  The command @kbd{C-x p k} (@code{project-kill-buffers})
 accomplishes that: it kills all the buffers that belong to the current
-project, except if @code{project-kill-buffers-ignores} tells
-otherwise.
+project that satisfy any of @code{project-kill-buffer-conditions}.
 
 @node Switching Projects
 @subsection Switching Projects
diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi
index 55e41e3..54f046a 100644
--- a/doc/emacs/mini.texi
+++ b/doc/emacs/mini.texi
@@ -518,6 +518,13 @@ between @samp{foo} and @samp{bar}, that matches
 @samp{@var{a}foo@var{b}bar@var{c}}, where @var{a}, @var{b}, and
 @var{c} can be any string including the empty string.
 
+@item flex
+@cindex @code{flex}, completion style
+This aggressive completion style, also known as @code{flx} or
+@code{fuzzy} or @code{scatter} completion, attempts to complete using
+in-order substrings.  For example, it can consider @samp{foo} to match
+@samp{frodo} or @samp{fbarbazoo}.
+
 @item initials
 @cindex @code{initials}, completion style
 This very aggressive completion style attempts to complete acronyms
diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi
index f3c9d76..317a197 100644
--- a/doc/emacs/misc.texi
+++ b/doc/emacs/misc.texi
@@ -245,13 +245,13 @@ Do an incremental search on the selected article buffer
 (@code{gnus-summary-isearch-article}), as if you switched to the
 buffer and typed @kbd{C-s} (@pxref{Incremental Search}).
 
-@kindex M-s @r{(Gnus Summary mode)}
+@kindex M-s M-s @r{(Gnus Summary mode)}
 @findex gnus-summary-search-article-forward
 @item M-s @var{regexp} @key{RET}
 Search forward for articles containing a match for @var{regexp}
 (@code{gnus-summary-search-article-forward}).
 
-@kindex M-r @r{(Gnus Summary mode)}
+@kindex M-s M-r @r{(Gnus Summary mode)}
 @findex gnus-summary-search-article-backward
 @item M-r @var{regexp} @key{RET}
 Search back for articles containing a match for @var{regexp}
diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index d25f009..25f6574 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -1845,6 +1845,13 @@ is, after a prefix key---then Emacs reorders the events 
so that this
 event comes either before or after the multi-event key sequence, not
 within it.
 
+  Some of these special events, such as @code{delete-frame}, invoke
+Emacs commands by default; others are not bound.  If you want to
+arrange for a special event to invoke a command, you can do that via
+@code{special-event-map}.  The command you bind to a function key in
+that map can then examine the full event which invoked it in
+@code{last-input-event}.  @xref{Special Events}.
+
 @node Event Examples
 @subsection Event Examples
 
diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi
index bc8ec0e..2898cb4 100644
--- a/doc/lispref/functions.texi
+++ b/doc/lispref/functions.texi
@@ -267,7 +267,8 @@ reason functions are defined to start with @code{lambda} is 
so that
 other lists, intended for other uses, will not accidentally be valid as
 functions.
 
-  The second element is a list of symbols---the argument variable names.
+  The second element is a list of symbols---the argument variable
+names (@pxref{Argument List}).
 This is called the @dfn{lambda list}.  When a Lisp function is called,
 the argument values are matched up against the variables in the lambda
 list, which are given local bindings with the values provided.
@@ -342,7 +343,7 @@ stored as symbol function definitions to produce named 
functions
 (@pxref{Function Names}).
 
 @node Argument List
-@subsection Other Features of Argument Lists
+@subsection Features of Argument Lists
 @kindex wrong-number-of-arguments
 @cindex argument binding
 @cindex binding arguments
@@ -583,8 +584,8 @@ a function.
 @defmac defun name args [doc] [declare] [interactive] body@dots{}
 @code{defun} is the usual way to define new Lisp functions.  It
 defines the symbol @var{name} as a function with argument list
-@var{args} and body forms given by @var{body}.  Neither @var{name} nor
-@var{args} should be quoted.
+@var{args} (@pxref{Argument List}) and body forms given by @var{body}.
+Neither @var{name} nor @var{args} should be quoted.
 
 @var{doc}, if present, should be a string specifying the function's
 documentation string (@pxref{Function Documentation}).  @var{declare},
diff --git a/doc/lispref/searching.texi b/doc/lispref/searching.texi
index c8a12bd..b6242c5 100644
--- a/doc/lispref/searching.texi
+++ b/doc/lispref/searching.texi
@@ -342,7 +342,7 @@ this choice, the rest of the regexp matches successfully.
 long time, if they lead to ambiguous matching.  For
 example, trying to match the regular expression @samp{\(x+y*\)*a}
 against the string @samp{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz} could
-take hours before it ultimately fails.  Emacs must try each way of
+take hours before it ultimately fails.  Emacs may try each way of
 grouping the @samp{x}s before concluding that none of them can work.
 In general, avoid expressions that can match the same string in
 multiple ways.
diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi
index 91c3049..ca52369 100644
--- a/doc/lispref/sequences.texi
+++ b/doc/lispref/sequences.texi
@@ -791,11 +791,11 @@ use instead of the default @code{equal}.
 
 @example
 @group
-(seq-contains '(symbol1 symbol2) 'symbol1)
-@result{} symbol1
+(seq-contains-p '(symbol1 symbol2) 'symbol1)
+@result{} t
 @end group
 @group
-(seq-contains '(symbol1 symbol2) 'symbol3)
+(seq-contains-p '(symbol1 symbol2) 'symbol3)
 @result{} nil
 @end group
 @end example
diff --git a/doc/lispref/tips.texi b/doc/lispref/tips.texi
index 6292054..1826e8f 100644
--- a/doc/lispref/tips.texi
+++ b/doc/lispref/tips.texi
@@ -956,7 +956,7 @@ multiple sub-sections.  Even though that was the only 
recommended
 approach for a long time, many people have chosen to use multiple
 top-level code sections instead.  You may chose either style.
 
-Using multiple top-level code sections has the advanatage that it
+Using multiple top-level code sections has the advantage that it
 avoids introducing an additional nesting level but it also means that
 the section named @samp{Code} does not contain all the code, which is
 awkward.  To avoid that, you should put no code at all inside that
diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi
index 8246704..3c12441 100644
--- a/doc/misc/efaq.texi
+++ b/doc/misc/efaq.texi
@@ -3464,7 +3464,6 @@ see @ref{Packages that do not come with Emacs}.
 @cindex Finding other packages
 @cindex Lisp packages that do not come with Emacs
 @cindex Packages, those that do not come with Emacs
-@cindex Emacs Lisp List
 @cindex Emacs Lisp Archive
 
 The easiest way to add more features to your Emacs is to use the
@@ -3500,10 +3499,6 @@ 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
-Lisp List (ELL)}, has pointers to many Emacs Lisp files, but at time
-of writing it is no longer being updated.
-
 It is impossible for us to list here all the sites that offer Emacs
 Lisp packages.  If you are interested in a specific feature, then
 after checking Emacs itself and GNU ELPA, a web search is often the
@@ -4192,7 +4187,7 @@ You can get the old behavior by binding @kbd{SPC} to
 (define-key minibuffer-local-filename-completion-map (kbd "SPC")
   'minibuffer-complete-word)
 
-(define-key minibuffer-local-must-match-filename-map (kbd "SPC")
+(define-key minibuffer-local-filename-must-match-map (kbd "SPC")
   'minibuffer-complete-word)
 @end lisp
 
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index 584c546..332926a 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -11029,14 +11029,14 @@ Go to the Gnus info node (@code{gnus-info-find-node}).
 
 @table @kbd
 
-@item M-s
-@kindex M-s @r{(Summary)}
+@item M-s M-s
+@kindex M-s M-s @r{(Summary)}
 @findex gnus-summary-search-article-forward
 Search through all subsequent (raw) articles for a regexp
 (@code{gnus-summary-search-article-forward}).
 
-@item M-r
-@kindex M-r @r{(Summary)}
+@item M-s M-r
+@kindex M-s M-r @r{(Summary)}
 @findex gnus-summary-search-article-backward
 Search through all previous (raw) articles for a regexp
 (@code{gnus-summary-search-article-backward}).
diff --git a/doc/misc/message.texi b/doc/misc/message.texi
index 204a638..55b166e 100644
--- a/doc/misc/message.texi
+++ b/doc/misc/message.texi
@@ -1265,7 +1265,7 @@ for a long time.  For more details, see
 To use this in Message, say:
 
 @lisp
-(add-hook 'message-send-hook 'message-add-openpgp-header)
+(add-hook 'message-header-setup-hook 'message-add-openpgp-header)
 @end lisp
 
 @noindent
diff --git a/doc/misc/url.texi b/doc/misc/url.texi
index 8d9b102..0304ff4 100644
--- a/doc/misc/url.texi
+++ b/doc/misc/url.texi
@@ -1312,8 +1312,6 @@ repeated visits do not require repeated domain lookups.
 @end defopt
 @defopt url-max-password-attempts
 @end defopt
-@defopt url-temporary-directory
-@end defopt
 @defopt url-show-status
 @end defopt
 @defopt url-confirmation-func
diff --git a/etc/HISTORY b/etc/HISTORY
index f0fd7d6..a6b9f57 100644
--- a/etc/HISTORY
+++ b/etc/HISTORY
@@ -220,7 +220,7 @@ GNU Emacs 26.2 (2019-04-12) emacs-26.2
 
 GNU Emacs 26.3 (2019-08-28) emacs-26.3
 
-GNU Emacs 27.1 (2020-08-06) emacs-27.1
+GNU Emacs 27.1 (2020-08-10) emacs-27.1
 
 
 ----------------------------------------------------------------------
diff --git a/etc/NEWS b/etc/NEWS
index 2be9743..34d078b 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -199,7 +199,7 @@ and variables.
 displayed and which are kept hidden.
 
 ---
-*** New command bound to 'C': 'archive-copy-file'
+*** New command bound to 'C': 'archive-copy-file'.
 This command extracts the file under point and writes the data to a
 file.
 
@@ -216,16 +216,16 @@ as a data list rather than as a piece of code.
 
 +++
 *** New user option 'calendar-time-zone-style'.
-If 'numeric, calendar functions (eg calendar-sunrise-sunset) that display
+If 'numeric', calendar functions (eg 'calendar-sunrise-sunset') that display
 time zones will use a form like "+0100" instead of "CET".
 
 ** Dired
 
 +++
 *** New user option 'dired-copy-dereference'.
-If set, Dired will dereferences symbolic links when copying.  This can
-be switched off on a per-usage basis by providing 'dired-do-copy' with
-a 'C-u' prefix.
+If set to non-nil, Dired will dereference symbolic links when copying.
+This can be switched off on a per-usage basis by providing
+'dired-do-copy' with a 'C-u' prefix.
 
 *** New user option 'dired-mark-region' affects all Dired commands
 that mark files.  When non-nil and the region is active in Transient
@@ -259,9 +259,20 @@ invoke 'C-u C-x v s' ('vc-create-tag').
 ---
 *** 'vc-hg' now uses 'hg summary' to populate extra 'vc-dir' headers.
 
+---
+*** New variable 'vc-git-revision-complete-only-branches'
+If non-nil, only branches and remotes are considered when doing
+completion over branch names.
 
 ** Gnus
 
++++
+*** The key binding of 'gnus-summary-search-article-forward' has changed.
+This command was previously on 'M-s' and shadowed the global 'M-s'
+search prefix.  The command has now been moved to 'M-s M-s'.  (For
+consistency, the 'M-s M-r' key binding has been added for the
+'gnus-summary-search-article-backward' command.)
+
 ---
 *** The value of "all" in the 'large-newsgroup-initial' group parameter 
changes.
 It was previously nil, which didn't work, because nil is
@@ -293,23 +304,23 @@ To generate these headers, add the new function
 be generated according to the new 'message-openpgp-header' variable.
 
 ---
-*** A change to how Mail-Copies-To: never is handled.
-If a user has specified Mail-Copies-To: never, and Message was asked
+*** A change to how "Mail-Copies-To: never" is handled.
+If a user has specified "Mail-Copies-To: never", and Message was asked
 to do a "wide reply", some other arbitrary recipient would end up in
-the resulting To header, while the remaining recipients would be put
-in the Cc header.  This is somewhat misleading, as it looks like
+the resulting "To" header, while the remaining recipients would be put
+in the "Cc" header.  This is somewhat misleading, as it looks like
 you're responding to a specific person in particular.  This has been
-changed so that all the recipients are put in the To header in these
+changed so that all the recipients are put in the "To" header in these
 instances.
 
 +++
 *** New function to start Emacs in Message mode to send an email.
 Emacs can be defined as a handler for the "x-scheme-handler/mailto"
 MIME type with the following command: "emacs -f message-mailto %u".
-An emacs-mail.desktop file has been included, suitable for installing
-in desktop directories like /usr/share/applications.  Clicking on a
-mailto: link in other applications will then open Emacs with headers
-filled out according to the link, e.g.
+An "emacs-mail.desktop" file has been included, suitable for
+installing in desktop directories like "/usr/share/applications".
+Clicking on a 'mailto:' link in other applications will then open
+Emacs with headers filled out according to the link, e.g.
 "mailto:larsi@gnus.org?subject=This+is+a+test";.
 
 ---
@@ -324,7 +335,7 @@ this user option.
 *** New command to take screenshots.
 In Message mode buffers, the 'C-c C-p' ('message-insert-screenshot')
 command has been added.  It depends on using an external program to
-take the actual screenshot, and defaults to ImageMagick "import".
+take the actual screenshot, and defaults to "ImageMagick import".
 
 ** Help
 
@@ -345,7 +356,7 @@ This file was a compatibility kludge which is no longer 
needed.
 
 ---
 ** Lisp mode now uses 'common-lisp-indent-function'.
-To revert to the previous behaviour,
+To revert to the previous behavior,
 '(setq lisp-indent-function 'lisp-indent-function)' from 'lisp-mode-hook'.
 
 ** Edebug
@@ -491,7 +502,7 @@ Defaults to 'libravatar', with 'unicornify' and 'gravatar' 
as options.
 
 *** Regexp matching of messages is now case-sensitive by default.
 The variable 'compilation-error-case-fold-search' can be set for
-case-insensitive matching of messages when the old behaviour is
+case-insensitive matching of messages when the old behavior is
 required, but the recommended solution is to use a correctly matching
 regexp instead.
 
@@ -523,10 +534,10 @@ This is used when invoking 'texi2dvi' from 
'texinfo-tex-buffer'.
 
 ---
 *** New commands for moving in and between environments.
-An "environment" is something that ends with @end.  The commands are
+An "environment" is something that ends with '@end'.  The commands are
 'C-c C-c C-f' (next end), 'C-c C-c C-b' (previous end),
 'C-c C-c C-n' (next start) and 'C-c C-c C-p' (previous start), as well
-as 'C-c .', which will alternate between the start end the end of the
+as 'C-c .', which will alternate between the start and the end of the
 current environment.
 
 ** Rmail
@@ -650,8 +661,8 @@ mode buffer.
 +++
 *** New Emacs command line convenience function.
 The 'eww-browse' command has been added, which allows you to register
-Emacs as a MIME handler for "text/x-uri", and will call eww on the
-supplied URL.  Usage example: emacs -f eww-browse https://gnu.org
+Emacs as a MIME handler for "text/x-uri", and will call 'eww' on the
+supplied URL.  Usage example: "emacs -f eww-browse https://gnu.org";.
 
 +++
 *** 'eww-download-directory' will now use the XDG location, if defined.
@@ -714,13 +725,25 @@ https://www.w3.org/TR/xml/#charsets).  Now it rejects 
such strings.
 ** erc
 
 ---
-*** The /ignore command will now ask for a timeout to stop ignoring the user.
+*** The '/ignore' command will now ask for a timeout to stop ignoring the user.
 Allowed inputs are seconds or ISO8601-like periods like "1h" or "4h30m".
 
 ---
-*** ERC now recognizes C-] for italic text.
+*** ERC now recognizes 'C-]' for italic text.
 Italic text is displayed in the new 'erc-italic-face'.
 
+---
+*** The erc-compat.el library is now marked obsolete.
+This file contained ERC compatibility code for Emacs 21 and XEmacs
+which is no longer needed.
+
+---
+*** erc-match.el now supports 'message' highlight type (not including the 
nick).
+The 'erc-current-nick-highlight-type', 'erc-pal-highlight-type',
+'erc-fool-highlight-type', 'erc-keyword-highlight-type', and
+'erc-dangerous-host-highlight-type' variables now support a 'message'
+type for highlighting the entire message but not the sender's nick.
+
 ** Battery
 
 ---
@@ -771,18 +794,68 @@ The recentf files are no longer backed up.
 ** Calc
 
 ---
-*** The behaviour when doing forward-delete has been changed.
+*** The behavior when doing forward-delete has been changed.
 Previously, using the 'C-d' command would delete the final number in
 the input field, no matter where point was.  This has been changed to
 work more traditionally, with 'C-d' deleting the next character.
 Likewise, point isn't moved to the end of the string before inserting
 digits.
 
+** term-mode
+
+---
+*** New user option 'term-scroll-snap-to-bottom'.
+By default, 'term' and 'ansi-term' will now recenter the buffer so
+that the prompt is on the final line in the window.  Setting this new
+user option to nil inhibits this behavior.
+
+---
+*** New user option 'term-set-terminal-size'
+If non-nil, the 'LINES' and 'COLUMNS' environment variables will be set
+based on the current window size.  In previous versions of Emacs, this
+was always done (and that could lead to odd displays when resizing the
+window after starting).  This variable defaults to nil.
+
+
 ** Miscellaneous
 
-*** The new library hierarchy.el has been added.
-It's a library to create, query, navigate and display hierarchy
-structures.
+---
+*** 'C-s' in 'M-x' now searches over completions again.
+In Emacs 23, typing 'M-x' ('read-extended-command') and then 'C-s' (to
+do an interactive search) would search over possible completions.
+This was lost in Emacs 24, but is now back again.
+
+---
+*** 'M-x report-emacs-bug' will no longer include "Recent messages" section.
+These were taken from the "*Messages*" buffer, and may inadvertently
+leak information from the reporting user.
+
+---
+*** 'count-windows' now takes an optional parameter ALL-FRAMES.
+The semantics are as with 'walk-windows'.
+
+---
+*** Killing virtual ido buffers interactively will make them go away.
+Previously, killing a virtual ido buffer with 'ido-kill-buffer' didn't
+do anything.  This has now been changed, and killing virtual buffers
+with that command will remove the buffer from recentf.
+
+---
+*** New variable 'ffap-file-name-with-spaces'.
+If non-nil, 'find-file-at-point' and friends will try to guess more
+expansively to identify a file name with spaces.
+
+---
+*** Two new commands for centering in 'doc-view-mode'.
+The new commands 'doc-view-center-page-horizontally' (bound to 'c h')
+and 'doc-view-center-page-vertically' (bound to 'c v') center the page
+horizontally and vertically, respectively.
+
+---
+*** Change in meaning of 'icomplete-show-matches-on-no-input'.
+Previously, choosing a different completion with commands like 'C-.'
+and then hitting 'RET' would choose the default completion.  Doing this
+will now choose the completion under point instead.
 
 ---
 *** The width of the buffer-name column in 'list-buffers' is now dynamic.
@@ -791,23 +864,23 @@ wider than the length of the longest buffer name, except 
that it will
 never be narrower than 19 characters.
 
 *** Bookmarks can now be targets for new tabs.
-When the 'bookmark.el' library is loaded, a customize choice is added
+When the bookmark.el library is loaded, a customize choice is added
 to 'tab-bar-new-tab-choice' for new tabs to show the bookmark list.
 
 
 ** xwidget-webkit mode
 
-*** New xwidget functions
+*** New xwidget functions.
 'xwidget-webkit-uri' (return the current URL), 'xwidget-webkit-title'
 (return the current title), and 'xwidget-webkit-goto-history' (goto a
 point in history).
 
-*** Pixel-based scrolling
+*** Pixel-based scrolling.
 The 'xwidget-webkit-scroll-up', 'xwidget-webkit-scroll-down' commands
 now supports scrolling arbitrary pixel values.  It now treats the
 optional 2nd argument as the pixel values to scroll.
 
-*** New commands for scrolling
+*** New commands for scrolling.
 The new commands 'xwidget-webkit-scroll-up-line',
 'xwidget-webkit-scroll-down-line', 'xwidget-webkit-scroll-forward',
 'xwidget-webkit-scroll-backward' can be used to scroll webkit by the
@@ -817,6 +890,41 @@ height of lines or width of chars.
 When non-nil, use a new xwidget webkit session after bookmark jump.
 Otherwise, it will use 'xwidget-webkit-last-session'.
 
+** Flyspell mode
+
++++
+*** Corrections and actions menu can be optionally bound to 'mouse-3'.
+When Flyspell mode highlights a word as misspelled, you can click on
+it to display a menu of possible corrections and actions.  You can now
+easily bind this menu to 'down-mouse-3' (usually the right mouse button)
+instead of 'mouse-2' (the default) by customizing the new user option
+'flyspell-use-mouse-3-for-menu'.
+
+** Time
+
+---
+*** 'display-time-world' has been renamed to 'world-clock'.
+'world-clock' creates a buffer with an updating time display using
+several time zones.  It is hoped that the new names are more
+discoverable.
+
+The following functions have been renamed:
+
+  'display-time-world'         to 'world-clock'
+  'display-time-world-mode'    to 'world-clock-mode'
+  'display-time-world-display' to 'world-clock-display'
+  'display-time-world-timer'   to 'world-clock-update'
+
+The following user options have been renamed:
+
+  'display-time-world-list'         to 'world-clock-list'
+  'display-time-world-time-format'  to 'world-clock-time-format'
+  'display-time-world-buffer-name'  to 'world-clock-buffer-name'
+  'display-time-world-timer-enable' to 'world-clock-timer-enable'
+  'display-time-world-timer-second' to 'world-clock-timer-second'
+
+The old names are now obsolete.
+
 
 * New Modes and Packages in Emacs 28.1
 
@@ -827,6 +935,10 @@ composed of Lisp symbolic expressions that do not form a 
computer
 program.  The ".dir-locals.el" file is automatically set to use this
 mode, as are other data files produced by Emacs.
 
+** hierarchy.el
+
+It's a library to create, query, navigate and display hierarchy structures.
+
 
 * Incompatible Editing Changes in Emacs 28.1
 
@@ -889,7 +1001,41 @@ have now been removed.
 
 ---
 ** Some libraries obsolete since Emacs 23 have been removed:
-'ledit.el', 'lmenu.el', 'lucid.el and 'old-whitespace.el'.
+ledit.el, lmenu.el, lucid.el and old-whitespace.el.
+
+---
+** Some functions and variables obsolete since Emacs 23 have been removed:
+
+'GOLD-map', 'bookmark-jump-noselect',
+'bookmark-read-annotation-text-func', 'buffer-menu-mode-hook',
+'char-coding-system-table', 'char-valid-p', 'charset-bytes',
+'charset-id', 'charset-list' (function), 'complete-in-turn',
+'completion-common-substring', 'crm-minibuffer-complete',
+'crm-minibuffer-complete-and-exit', 'crm-minibuffer-completion-help',
+'custom-mode', 'custom-mode-hook', 'detect-coding-with-priority',
+'dirtrack-debug' (function), 'dirtrack-debug-toggle',
+'dynamic-completion-table',
+'easy-menu-precalculate-equivalent-keybindings',
+'epa-display-verify-result', 'epg-passphrase-callback-function',
+'eshell-report-bug', 'ffap-bug', 'ffap-submit-bug', 'forward-point',
+'generic-char-p', 'global-highlight-changes', 'hi-lock-face-history',
+'hi-lock-regexp-history', 'highlight-changes-active-string',
+'highlight-changes-initial-state', 'highlight-changes-passive-string',
+'ispell-aspell-supports-utf8', 'lisp-mode-auto-fill',
+'locate-file-completion', 'make-coding-system',
+'minibuffer-local-must-match-filename-map', 'mouse-major-mode-menu',
+'mouse-popup-menubar', 'mouse-popup-menubar-stuff',
+'newsticker-groups-filename', 'non-iso-charset-alist',
+'nonascii-insert-offset', 'nonascii-translation-table',
+'password-read-and-add', 'pre-abbrev-expand-hook',
+'process-filter-multibyte-p', 'remember-buffer' (function),
+'rmail-message-filter', 'set-coding-priority',
+'set-process-filter-multibyte', 'shell-dirtrack-toggle',
+'t-mouse-mode', 'tooltip-hook', 'tpu-have-ispell',
+'url-generate-unique-filename', 'url-temporary-directory',
+'vc-arch-command', 'vc-default-working-revision' (variable),
+'vc-mtn-command', 'vc-revert-buffer', 'vc-workfile-version',
+'vcursor-toggle-vcursor-map', 'w32-focus-frame', 'w32-select-font'.
 
 
 * Lisp Changes in Emacs 28.1
@@ -899,6 +1045,12 @@ have now been removed.
 ignore invisible lines.
 
 ---
+** 'count-words' now crosses field boundaries.
+Originally, 'count-words' would stop counting at the first field
+boundary it encountered; now it keeps counting all the way to the
+region's (or buffer's) end.
+
+---
 ** New function 'custom-add-choice'.
 This function can be used by modes to add elements to the
 'choice' customization type of a variable.
@@ -1039,7 +1191,6 @@ 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/>.
 
-
 
 Local variables:
 coding: utf-8
diff --git a/etc/NEWS.27 b/etc/NEWS.27
index a056f5c..31b6902 100644
--- a/etc/NEWS.27
+++ b/etc/NEWS.27
@@ -202,10 +202,11 @@ it won't work right without some adjustment:
 
 ** Emacs now notifies systemd when startup finishes or shutdown begins.
 Units that are ordered after 'emacs.service' will only be started
-after Emacs has finished initialization and is ready for use.
-(If your Emacs is installed in a non-standard location and you copied the
-emacs.service file to e.g. "~/.config/systemd/user/", you will need to copy
-the new version of the file again.)
+after Emacs has finished initialization and is ready for use, and
+Emacs needs to be built with systemd support.  (If your Emacs is
+installed in a non-standard location and you copied the emacs.service
+file to e.g. "~/.config/systemd/user/", you will need to copy the new
+version of the file again.)
 
 
 * Changes in Emacs 27.1
@@ -595,7 +596,7 @@ the node "(emacs) Directory Variables" of the user manual.
 
 ** Network connections using 'local' can now use IPv6.
 'make-network-process' now uses the correct loopback address when
-asked to use ':host 'local' and ':family 'ipv6'.
+asked to use ":host 'local" and ":family 'ipv6".
 
 ** The new function 'replace-region-contents' replaces the current
 region using a given replacement-function in a non-destructive manner
@@ -1917,6 +1918,11 @@ The value of the new 'sender' slot (if a string) is used 
to set gpg's
 'mml-secure-openpgp-sign-with-sender'.  See gpg(1) manual page about
 "--sender" for more information.
 
+*** 'epg-find-configuration' no longer finds GnuPG 2.0 through 2.1.5.
+Previously, it found these versions by mistake.  The intent was to
+find GnuPG 2.1.6 or later, or find GnuPG 1.4.3 or later within the
+GnuPG 1 series.
+
 ** Rmail
 
 *** New user option 'rmail-output-reset-deleted-flag'.
diff --git a/etc/PROBLEMS b/etc/PROBLEMS
index 598a79f..f68a183 100644
--- a/etc/PROBLEMS
+++ b/etc/PROBLEMS
@@ -419,27 +419,6 @@ EMACSLOADPATH overrides which directories the function 
"load" will search.
 If you observe strange problems, check for this variable in your
 environment.
 
-*** Using epop3.el package causes Emacs to signal an error.
-
-The error message might be something like this:
-
-  "Lisp nesting exceeds max-lisp-eval-depth"
-
-This happens because epop3 redefines the function gethash, which is a
-built-in primitive beginning with Emacs 21.1.  We don't have a patch
-for epop3 to fix it, but perhaps a newer version of epop3 corrects that.
-
-*** Buffers from 'with-output-to-temp-buffer' get set up in Help mode.
-
-Changes in Emacs 20.4 to the hooks used by that function cause
-problems for some packages, specifically BBDB.  See the function's
-documentation for the hooks involved.  BBDB 2.00.06 fixes the problem.
-
-*** The Hyperbole package causes *Help* buffers not to be displayed in
-Help mode due to setting 'temp-buffer-show-hook' rather than using
-'add-hook'.  Using '(add-hook 'temp-buffer-show-hook 'help-mode-finish)'
-after loading Hyperbole should fix this.
-
 ** Keyboard problems
 
 *** Unable to enter the M-| key on some German keyboards.
@@ -575,13 +554,6 @@ For example, simply moving through a file that contains 
hundreds of
 thousands of characters per line is slow, and consumes a lot of CPU.
 This is a known limitation of Emacs with no solution at this time.
 
-*** Emacs uses 100% of CPU time
-
-This was a known problem with some old versions of the Semantic package.
-The solution was to upgrade Semantic to version 2.0pre4 (distributed
-with CEDET 1.0pre4) or later.  Note that Emacs includes Semantic since
-23.2, and this issue does not apply to the included version.
-
 *** Display artifacts on GUI frames on X-based systems.
 
 This is known to be caused by using double-buffering (which is enabled
@@ -1952,11 +1924,6 @@ A few versions of the Linux kernel have timer bugs that 
break CPU
 profiling; see Bug#34235.  To fix the problem, upgrade to one of the
 kernel versions 4.14.97, 4.19.19, or 4.20.6, or later.
 
-*** GNU/Linux: Process output is corrupted.
-
-There is a bug in Linux kernel 2.6.10 PTYs that can cause emacs to
-read corrupted process output.
-
 *** GNU/Linux: Remote access to CVS with SSH causes file corruption.
 
 If you access a remote CVS repository via SSH, files may be corrupted
@@ -2740,11 +2707,6 @@ library on these systems.  The solution is to 
reconfigure Emacs while
 disabling all the features that require libgio: rsvg, dbus, gconf, and
 imagemagick.
 
-*** Building Emacs for Cygwin can fail with GCC 3
-
-As of Emacs 22.1, there have been stability problems with Cygwin
-builds of Emacs using GCC 3.  Cygwin users are advised to use GCC 4.
-
 *** Building Emacs 23.3 and later will fail under Cygwin 1.5.19
 
 This is a consequence of a change to src/dired.c on 2010-07-27.  The
diff --git a/lib/c++defs.h b/lib/c++defs.h
index 90e6fd6..6a9bf29 100644
--- a/lib/c++defs.h
+++ b/lib/c++defs.h
@@ -146,6 +146,16 @@
     _GL_EXTERN_C int _gl_cxxalias_dummy
 #endif
 
+/* _GL_CXXALIAS_MDA (func, rettype, parameters);
+   is to be used when func is a Microsoft deprecated alias, on native Windows.
+   It declares a C++ alias called GNULIB_NAMESPACE::func
+   that redirects to _func, if GNULIB_NAMESPACE is defined.
+   Example:
+     _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...));
+ */
+#define _GL_CXXALIAS_MDA(func,rettype,parameters) \
+  _GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters)
+
 /* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);
    is like  _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);
    except that the C function rpl_func may have a slightly different
diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c
index 9f99098..0b89d2a 100644
--- a/lib/canonicalize-lgpl.c
+++ b/lib/canonicalize-lgpl.c
@@ -52,7 +52,9 @@
 # include "pathmax.h"
 # include "malloca.h"
 # include "filename.h"
-# if HAVE_GETCWD
+# if defined _WIN32 && !defined __CYGWIN__
+#  define __getcwd _getcwd
+# elif HAVE_GETCWD
 #  if IN_RELOCWRAPPER
     /* When building the relocatable program wrapper, use the system's getcwd
        function, not the gnulib override, otherwise we would get a link error.
diff --git a/lib/cdefs.h b/lib/cdefs.h
index 4f89f4e..b1870fd 100644
--- a/lib/cdefs.h
+++ b/lib/cdefs.h
@@ -85,7 +85,7 @@
 #  define __NTH(fct)   __attribute__ ((__nothrow__ __LEAF)) fct
 #  define __NTHNL(fct)  __attribute__ ((__nothrow__)) fct
 # else
-#  if defined __cplusplus && __GNUC_PREREQ (2,8)
+#  if defined __cplusplus && (__GNUC_PREREQ (2,8) || __clang_major >= 4)
 #   define __THROW     throw ()
 #   define __THROWNL   throw ()
 #   define __NTH(fct)  __LEAF_ATTR fct throw ()
@@ -148,7 +148,7 @@
 # define __warnattr(msg) __attribute__((__warning__ (msg)))
 # define __errordecl(name, msg) \
   extern void name (void) __attribute__((__error__ (msg)))
-#elif __glibc_clang_has_attribute (__diagnose_if__)
+#elif __glibc_clang_has_attribute (__diagnose_if__) && 0 /* fails on Fedora 31 
with Clang 9.  */
 # define __warndecl(name, msg) \
   extern void name (void) __attribute__((__diagnose_if__ (1, msg, "warning")))
 # define __warnattr(msg) __attribute__((__diagnose_if__ (1, msg, "warning")))
@@ -194,7 +194,7 @@
    Example:
    int __REDIRECT(setpgrp, (__pid_t pid, __pid_t pgrp), setpgid); */
 
-#if defined __GNUC__ && __GNUC__ >= 2
+#if (defined __GNUC__ && __GNUC__ >= 2) || (__clang_major__ >= 4)
 
 # define __REDIRECT(name, proto, alias) name proto __asm__ (__ASMNAME (#alias))
 # ifdef __cplusplus
@@ -465,7 +465,8 @@
 
 #if (!defined _Static_assert && !defined __cplusplus \
      && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
-     && (!__GNUC_PREREQ (4, 6) || defined __STRICT_ANSI__))
+     && (!(__GNUC_PREREQ (4, 6) || __clang_major__ >= 4) \
+         || defined __STRICT_ANSI__))
 # define _Static_assert(expr, diagnostic) \
     extern int (*__Static_assert_function (void)) \
       [!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })]
diff --git a/lib/dup2.c b/lib/dup2.c
index 9bc3951..323e19b 100644
--- a/lib/dup2.c
+++ b/lib/dup2.c
@@ -52,7 +52,7 @@ dup2_nothrow (int fd, int desired_fd)
 
   TRY_MSVC_INVAL
     {
-      result = dup2 (fd, desired_fd);
+      result = _dup2 (fd, desired_fd);
     }
   CATCH_MSVC_INVAL
     {
@@ -64,7 +64,7 @@ dup2_nothrow (int fd, int desired_fd)
   return result;
 }
 # else
-#  define dup2_nothrow dup2
+#  define dup2_nothrow _dup2
 # endif
 
 static int
diff --git a/lib/fcntl.in.h b/lib/fcntl.in.h
index 0a21c95..6f16bc6 100644
--- a/lib/fcntl.in.h
+++ b/lib/fcntl.in.h
@@ -97,6 +97,12 @@
 _GL_FUNCDECL_RPL (creat, int, (const char *filename, mode_t mode)
                              _GL_ARG_NONNULL ((1)));
 _GL_CXXALIAS_RPL (creat, int, (const char *filename, mode_t mode));
+# elif defined _WIN32 && !defined __CYGWIN__
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef creat
+#   define creat _creat
+#  endif
+_GL_CXXALIAS_MDA (creat, int, (const char *filename, mode_t mode));
 # else
 _GL_CXXALIAS_SYS (creat, int, (const char *filename, mode_t mode));
 # endif
@@ -106,6 +112,9 @@ _GL_CXXALIASWARN (creat);
 /* Assume creat is always declared.  */
 _GL_WARN_ON_USE (creat, "creat is not always POSIX compliant - "
                  "use gnulib module creat for portability");
+#elif defined _WIN32 && !defined __CYGWIN__
+# undef creat
+# define creat _creat
 #endif
 
 #if @GNULIB_FCNTL@
@@ -146,6 +155,12 @@ _GL_WARN_ON_USE (fcntl, "fcntl is not always POSIX 
compliant - "
 _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)
                              _GL_ARG_NONNULL ((1)));
 _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
+# elif defined _WIN32 && !defined __CYGWIN__
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef open
+#   define open _open
+#  endif
+_GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...));
 # else
 _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
 # endif
@@ -159,6 +174,9 @@ _GL_CXXALIASWARN (open);
 /* Assume open is always declared.  */
 _GL_WARN_ON_USE (open, "open is not always POSIX compliant - "
                  "use gnulib module open for portability");
+#elif defined _WIN32 && !defined __CYGWIN__
+# undef open
+# define open _open
 #endif
 
 #if @GNULIB_OPENAT@
diff --git a/lib/getopt-cdefs.in.h b/lib/getopt-cdefs.in.h
index c510ab1..674838c 100644
--- a/lib/getopt-cdefs.in.h
+++ b/lib/getopt-cdefs.in.h
@@ -57,7 +57,7 @@
 #endif
 
 #ifndef __THROW
-# if defined __cplusplus && __GNUC_PREREQ (2,8)
+# if defined __cplusplus && (__GNUC_PREREQ (2,8) || __clang_major__ >= 4)
 #  define __THROW       throw ()
 # else
 #  define __THROW
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index 92d0621..7b4fc74 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -682,7 +682,6 @@ HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@
 HAVE_TIMEGM = @HAVE_TIMEGM@
 HAVE_TIMEZONE_T = @HAVE_TIMEZONE_T@
 HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@
-HAVE_TZSET = @HAVE_TZSET@
 HAVE_UNISTD_H = @HAVE_UNISTD_H@
 HAVE_UNLINKAT = @HAVE_UNLINKAT@
 HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
@@ -1159,7 +1158,7 @@ ifeq (,$(OMIT_GNULIB_MODULE_absolute-header))
 # Use this preprocessor expression to decide whether #include_next works.
 # Do not rely on a 'configure'-time test for this, since the expression
 # might appear in an installed header, which is used by some other compiler.
-HAVE_INCLUDE_NEXT = (__GNUC__ || 60000000 <= __DECC_VER)
+HAVE_INCLUDE_NEXT = (__GNUC__ || __clang__ || 60000000 <= __DECC_VER)
 
 endif
 ## end   gnulib module absolute-header
@@ -3185,7 +3184,6 @@ time.h: time.in.h $(top_builddir)/config.status 
$(CXXDEFS_H) $(ARG_NONNULL_H) $(
              -e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \
              -e 's|@''HAVE_TIMEGM''@|$(HAVE_TIMEGM)|g' \
              -e 's|@''HAVE_TIMEZONE_T''@|$(HAVE_TIMEZONE_T)|g' \
-             -e 's|@''HAVE_TZSET''@|$(HAVE_TZSET)|g' \
              -e 's|@''REPLACE_CTIME''@|$(REPLACE_CTIME)|g' \
              -e 's|@''REPLACE_GMTIME''@|$(REPLACE_GMTIME)|g' \
              -e 's|@''REPLACE_LOCALTIME''@|$(REPLACE_LOCALTIME)|g' \
diff --git a/lib/intprops.h b/lib/intprops.h
index 220f532..f2f70b3 100644
--- a/lib/intprops.h
+++ b/lib/intprops.h
@@ -396,7 +396,7 @@
    For now, assume all versions of GCC-like compilers generate bogus
    warnings for _Generic.  This matters only for compilers that
    lack relevant builtins.  */
-#if __GNUC__
+#if __GNUC__ || defined __clang__
 # define _GL__GENERIC_BOGUS 1
 #else
 # define _GL__GENERIC_BOGUS 0
diff --git a/lib/md5.h b/lib/md5.h
index 3c60482..c728ba1 100644
--- a/lib/md5.h
+++ b/lib/md5.h
@@ -40,7 +40,7 @@
 #endif
 
 #ifndef __THROW
-# if defined __cplusplus && __GNUC_PREREQ (2,8)
+# if defined __cplusplus && (__GNUC_PREREQ (2,8) || __clang_major__ >= 4)
 #  define __THROW       throw ()
 # else
 #  define __THROW
diff --git a/lib/mktime.c b/lib/mktime.c
index 92c00b2..5b4c144 100644
--- a/lib/mktime.c
+++ b/lib/mktime.c
@@ -94,7 +94,7 @@ my_tzset (void)
   const char *tz = getenv ("TZ");
   if (tz != NULL && strchr (tz, '/') != NULL)
     _putenv ("TZ=");
-# elif HAVE_TZSET
+# else
   tzset ();
 # endif
 }
diff --git a/lib/nstrftime.c b/lib/nstrftime.c
index 2816cf4..7d5a97f 100644
--- a/lib/nstrftime.c
+++ b/lib/nstrftime.c
@@ -21,7 +21,6 @@
 # define HAVE_TM_GMTOFF 1
 # define HAVE_TM_ZONE 1
 # define HAVE_TZNAME 1
-# define HAVE_TZSET 1
 # include "../locale/localeinfo.h"
 #else
 # include <config.h>
@@ -34,6 +33,7 @@
 #endif
 
 #include <ctype.h>
+#include <errno.h>
 #include <time.h>
 
 #if HAVE_TZNAME && !HAVE_DECL_TZNAME
@@ -163,7 +163,10 @@ extern char *tzname[];
       size_t _w = pad == L_('-') || width < 0 ? 0 : width;                    \
       size_t _incr = _n < _w ? _w : _n;                                       \
       if (_incr >= maxsize - i)                                               \
-        return 0;                                                             \
+        {                                                                     \
+          errno = ERANGE;                                                     \
+          return 0;                                                           \
+        }                                                                     \
       if (p)                                                                  \
         {                                                                     \
           if (_n < _w)                                                        \
@@ -365,7 +368,7 @@ tm_diff (const struct tm *a, const struct tm *b)
 #define ISO_WEEK1_WDAY 4 /* Thursday */
 #define YDAY_MINIMUM (-366)
 static int iso_week_days (int, int);
-#ifdef __GNUC__
+#if defined __GNUC__ || defined __clang__
 __inline__
 #endif
 static int
@@ -389,7 +392,6 @@ iso_week_days (int yday, int wday)
 #endif
 
 #ifdef my_strftime
-# undef HAVE_TZSET
 # define extra_args , tz, ns
 # define extra_args_spec , timezone_t tz, int ns
 #else
@@ -449,6 +451,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG 
(size_t maxsize)
   size_t maxsize = (size_t) -1;
 #endif
 
+  int saved_errno = errno;
   int hour12 = tp->tm_hour;
 #ifdef _NL_CURRENT
   /* We cannot make the following values variables since we must delay
@@ -523,7 +526,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG 
(size_t maxsize)
     {
       /* POSIX.1 requires that local time zone information be used as
          though strftime called tzset.  */
-# if HAVE_TZSET
+# ifndef my_strftime
       if (!*tzset_called)
         {
           tzset ();
@@ -1188,7 +1191,13 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG 
(size_t maxsize)
             time_t t;
 
             ltm = *tp;
+            ltm.tm_yday = -1;
             t = mktime_z (tz, &ltm);
+            if (ltm.tm_yday < 0)
+              {
+                errno = EOVERFLOW;
+                return 0;
+              }
 
             /* Generate string value for T using time_t arithmetic;
                this works even if sizeof (long) < sizeof (time_t).  */
@@ -1417,7 +1426,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG 
(size_t maxsize)
 
                 /* POSIX.1 requires that local time zone information be used as
                    though strftime called tzset.  */
-# if HAVE_TZSET
+# ifndef my_strftime
                 if (!*tzset_called)
                   {
                     tzset ();
@@ -1486,5 +1495,6 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG 
(size_t maxsize)
     *p = L_('\0');
 #endif
 
+  errno = saved_errno;
   return i;
 }
diff --git a/lib/open.c b/lib/open.c
index 751b42d..0f7c6e9 100644
--- a/lib/open.c
+++ b/lib/open.c
@@ -30,7 +30,11 @@
 static int
 orig_open (const char *filename, int flags, mode_t mode)
 {
+#if defined _WIN32 && !defined __CYGWIN__
+  return _open (filename, flags, mode);
+#else
   return open (filename, flags, mode);
+#endif
 }
 
 /* Specification.  */
diff --git a/lib/regcomp.c b/lib/regcomp.c
index 84044be..a4b95b0 100644
--- a/lib/regcomp.c
+++ b/lib/regcomp.c
@@ -558,7 +558,7 @@ weak_alias (__regerror, regerror)
 static const bitset_t utf8_sb_map =
 {
   /* Set the first 128 bits.  */
-# if defined __GNUC__ && !defined __STRICT_ANSI__
+# if (defined __GNUC__ || __clang_major__ >= 4) && !defined __STRICT_ANSI__
   [0 ... 0x80 / BITSET_WORD_BITS - 1] = BITSET_WORD_MAX
 # else
 #  if 4 * BITSET_WORD_BITS < ASCII_CHARS
diff --git a/lib/regex_internal.h b/lib/regex_internal.h
index 9a0c2ed..0c72e3f 100644
--- a/lib/regex_internal.h
+++ b/lib/regex_internal.h
@@ -335,7 +335,7 @@ typedef struct
     Idx idx;                   /* for BACK_REF */
     re_context_type ctx_type;  /* for ANCHOR */
   } opr;
-#if __GNUC__ >= 2 && !defined __STRICT_ANSI__
+#if (__GNUC__ >= 2 || defined __clang__) && !defined __STRICT_ANSI__
   re_token_type_t type : 8;
 #else
   re_token_type_t type;
diff --git a/lib/stdio.in.h b/lib/stdio.in.h
index cbebc84..6d12cd8 100644
--- a/lib/stdio.in.h
+++ b/lib/stdio.in.h
@@ -215,6 +215,11 @@ _GL_WARN_ON_USE (fclose, "fclose is not always POSIX 
compliant - "
                  "use gnulib module fclose for portable POSIX compliance");
 #endif
 
+#if defined _WIN32 && !defined __CYGWIN__
+# undef fcloseall
+# define fcloseall _fcloseall
+#endif
+
 #if @GNULIB_FDOPEN@
 # if @REPLACE_FDOPEN@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
@@ -224,6 +229,12 @@ _GL_WARN_ON_USE (fclose, "fclose is not always POSIX 
compliant - "
 _GL_FUNCDECL_RPL (fdopen, FILE *, (int fd, const char *mode)
                                   _GL_ARG_NONNULL ((2)));
 _GL_CXXALIAS_RPL (fdopen, FILE *, (int fd, const char *mode));
+# elif defined _WIN32 && !defined __CYGWIN__
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef fdopen
+#   define fdopen _fdopen
+#  endif
+_GL_CXXALIAS_MDA (fdopen, FILE *, (int fd, const char *mode));
 # else
 _GL_CXXALIAS_SYS (fdopen, FILE *, (int fd, const char *mode));
 # endif
@@ -233,6 +244,9 @@ _GL_CXXALIASWARN (fdopen);
 /* Assume fdopen is always declared.  */
 _GL_WARN_ON_USE (fdopen, "fdopen on native Windows platforms is not POSIX 
compliant - "
                  "use gnulib module fdopen for portability");
+#elif defined _WIN32 && !defined __CYGWIN__
+# undef fdopen
+# define fdopen _fdopen
 #endif
 
 #if @GNULIB_FFLUSH@
@@ -297,6 +311,11 @@ _GL_CXXALIASWARN (fgets);
 # endif
 #endif
 
+#if defined _WIN32 && !defined __CYGWIN__
+# undef fileno
+# define fileno _fileno
+#endif
+
 #if @GNULIB_FOPEN@
 # if @REPLACE_FOPEN@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
@@ -824,6 +843,11 @@ _GL_WARN_ON_USE (getline, "getline is unportable - "
 _GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
 #endif
 
+#if defined _WIN32 && !defined __CYGWIN__
+# undef getw
+# define getw _getw
+#endif
+
 #if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@
 struct obstack;
 /* Grow an obstack with formatted output.  Return the number of
@@ -940,7 +964,7 @@ _GL_WARN_ON_USE (popen, "popen is buggy on some platforms - 
"
 #if @GNULIB_PRINTF_POSIX@ || @GNULIB_PRINTF@
 # if (@GNULIB_PRINTF_POSIX@ && @REPLACE_PRINTF@) \
      || (@GNULIB_PRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && 
(@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@))
-#  if defined __GNUC__
+#  if defined __GNUC__ || defined __clang__
 #   if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 /* Don't break __attribute__((format(printf,M,N))).  */
 #    define printf __printf__
@@ -1037,6 +1061,11 @@ _GL_CXXALIASWARN (puts);
 # endif
 #endif
 
+#if defined _WIN32 && !defined __CYGWIN__
+# undef putw
+# define putw _putw
+#endif
+
 #if @GNULIB_REMOVE@
 # if @REPLACE_REMOVE@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
@@ -1114,7 +1143,7 @@ _GL_WARN_ON_USE (renameat, "renameat is not portable - "
 
 #if @GNULIB_SCANF@
 # if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@
-#  if defined __GNUC__
+#  if defined __GNUC__ || defined __clang__
 #   if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #    undef scanf
 /* Don't break __attribute__((format(scanf,M,N))).  */
@@ -1170,7 +1199,9 @@ _GL_CXXALIAS_SYS (snprintf, int,
                   (char *restrict str, size_t size,
                    const char *restrict format, ...));
 # endif
+# if __GLIBC__ >= 2
 _GL_CXXALIASWARN (snprintf);
+# endif
 #elif defined GNULIB_POSIXCHECK
 # undef snprintf
 # if HAVE_RAW_DECL_SNPRINTF
@@ -1214,6 +1245,11 @@ _GL_WARN_ON_USE (sprintf, "sprintf is not always POSIX 
compliant - "
                  "POSIX compliance");
 #endif
 
+#if defined _WIN32 && !defined __CYGWIN__
+# undef tempnam
+# define tempnam _tempnam
+#endif
+
 #if @GNULIB_TMPFILE@
 # if @REPLACE_TMPFILE@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
@@ -1382,7 +1418,9 @@ _GL_CXXALIAS_SYS (vfscanf, int,
                   (FILE *restrict stream,
                    const char *restrict format, va_list args));
 # endif
+# if __GLIBC__ >= 2
 _GL_CXXALIASWARN (vfscanf);
+# endif
 #endif
 
 #if @GNULIB_VPRINTF_POSIX@ || @GNULIB_VPRINTF@
@@ -1436,7 +1474,9 @@ _GL_CXXALIAS_RPL (vscanf, int, (const char *restrict 
format, va_list args));
 # else
 _GL_CXXALIAS_SYS (vscanf, int, (const char *restrict format, va_list args));
 # endif
+# if __GLIBC__ >= 2
 _GL_CXXALIASWARN (vscanf);
+# endif
 #endif
 
 #if @GNULIB_VSNPRINTF@
@@ -1464,7 +1504,9 @@ _GL_CXXALIAS_SYS (vsnprintf, int,
                   (char *restrict str, size_t size,
                    const char *restrict format, va_list args));
 # endif
+# if __GLIBC__ >= 2
 _GL_CXXALIASWARN (vsnprintf);
+# endif
 #elif defined GNULIB_POSIXCHECK
 # undef vsnprintf
 # if HAVE_RAW_DECL_VSNPRINTF
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index 5c598a2..47a1309 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -217,6 +217,21 @@ _GL_WARN_ON_USE (canonicalize_file_name,
 # endif
 #endif
 
+#if defined _WIN32 && !defined __CYGWIN__
+# undef ecvt
+# define ecvt _ecvt
+#endif
+
+#if defined _WIN32 && !defined __CYGWIN__
+# undef fcvt
+# define fcvt _fcvt
+#endif
+
+#if defined _WIN32 && !defined __CYGWIN__
+# undef gcvt
+# define gcvt _gcvt
+#endif
+
 #if @GNULIB_GETLOADAVG@
 /* Store max(NELEM,3) load average numbers in LOADAVG[].
    The three numbers are the load average of the last 1 minute, the last 5
@@ -468,6 +483,11 @@ _GL_WARN_ON_USE (mkstemps, "mkstemps is unportable - "
 # endif
 #endif
 
+#if defined _WIN32 && !defined __CYGWIN__
+# undef mktemp
+# define mktemp _mktemp
+#endif
+
 #if @GNULIB_POSIX_OPENPT@
 /* Return an FD open to the master side of a pseudo-terminal.  Flags should
    include O_RDWR, and may also include O_NOCTTY.  */
@@ -546,10 +566,19 @@ _GL_WARN_ON_USE (ptsname_r, "ptsname_r is not portable - "
 #  endif
 _GL_FUNCDECL_RPL (putenv, int, (char *string) _GL_ARG_NONNULL ((1)));
 _GL_CXXALIAS_RPL (putenv, int, (char *string));
+# elif defined _WIN32 && !defined __CYGWIN__
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef putenv
+#   define putenv _putenv
+#  endif
+_GL_CXXALIAS_MDA (putenv, int, (char *string));
 # else
 _GL_CXXALIAS_SYS (putenv, int, (char *string));
 # endif
 _GL_CXXALIASWARN (putenv);
+#elif defined _WIN32 && !defined __CYGWIN__
+# undef putenv
+# define putenv _putenv
 #endif
 
 #if @GNULIB_QSORT_R@
diff --git a/lib/strftime.h b/lib/strftime.h
index e850163..fe0c419 100644
--- a/lib/strftime.h
+++ b/lib/strftime.h
@@ -24,7 +24,12 @@ extern "C" {
 /* Just like strftime, but with two more arguments:
    POSIX requires that strftime use the local timezone information.
    Use the timezone __TZ instead.  Use __NS as the number of
-   nanoseconds in the %N directive.  */
+   nanoseconds in the %N directive.
+
+   On error, set errno and return 0.  Otherwise, return the number of
+   bytes generated (not counting the trailing NUL), preserving errno
+   if the number is 0.  This errno behavior is in draft POSIX 202x
+   plus some requested changes to POSIX.  */
 size_t nstrftime (char *restrict, size_t, char const *, struct tm const *,
                   timezone_t __tz, int __ns);
 
diff --git a/lib/string.in.h b/lib/string.in.h
index c0c1a54..7d83668 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -123,6 +123,12 @@ _GL_WARN_ON_USE (ffsll, "ffsll is not portable - use the 
ffsll module");
 #endif
 
 
+#if defined _WIN32 && !defined __CYGWIN__
+# undef memccpy
+# define memccpy _memccpy
+#endif
+
+
 /* Return the first instance of C within N bytes of S, or NULL.  */
 #if @GNULIB_MEMCHR@
 # if @REPLACE_MEMCHR@
@@ -384,6 +390,12 @@ _GL_WARN_ON_USE (strchrnul, "strchrnul is unportable - "
 #  endif
 _GL_FUNCDECL_RPL (strdup, char *, (char const *__s) _GL_ARG_NONNULL ((1)));
 _GL_CXXALIAS_RPL (strdup, char *, (char const *__s));
+# elif defined _WIN32 && !defined __CYGWIN__
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef strdup
+#   define strdup _strdup
+#  endif
+_GL_CXXALIAS_MDA (strdup, char *, (char const *__s));
 # else
 #  if defined __cplusplus && defined GNULIB_NAMESPACE && defined strdup
     /* strdup exists as a function and as a macro.  Get rid of the macro.  */
@@ -401,6 +413,9 @@ _GL_CXXALIASWARN (strdup);
 _GL_WARN_ON_USE (strdup, "strdup is unportable - "
                  "use gnulib module strdup for portability");
 # endif
+#elif defined _WIN32 && !defined __CYGWIN__
+# undef strdup
+# define strdup _strdup
 #endif
 
 /* Append no more than N characters from SRC onto DEST.  */
diff --git a/lib/sys_random.in.h b/lib/sys_random.in.h
index f14ac1f..a82d716 100644
--- a/lib/sys_random.in.h
+++ b/lib/sys_random.in.h
@@ -23,6 +23,10 @@
 
 #if @HAVE_SYS_RANDOM_H@
 
+/* On uClibc, <sys/random.h> assumes prior inclusion of <stddef.h>.  */
+# if defined __UCLIBC__
+#  include <stddef.h>
+# endif
 /* On Mac OS X 10.5, <sys/random.h> assumes prior inclusion of <sys/types.h>.
    On Max OS X 10.13, <sys/random.h> assumes prior inclusion of a file that
    includes <Availability.h>, such as <stdlib.h> or <unistd.h>.  */
diff --git a/lib/sys_select.in.h b/lib/sys_select.in.h
index 7a7b157..72cb9ba 100644
--- a/lib/sys_select.in.h
+++ b/lib/sys_select.in.h
@@ -177,14 +177,14 @@ rpl_fd_isset (SOCKET fd, fd_set * set)
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   undef close
 #   define close close_used_without_including_unistd_h
-#  else
+#  elif !defined __clang__
     _GL_WARN_ON_USE (close,
                      "close() used without including <unistd.h>");
 #  endif
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   undef gethostname
 #   define gethostname gethostname_used_without_including_unistd_h
-#  else
+#  elif !defined __clang__
     _GL_WARN_ON_USE (gethostname,
                      "gethostname() used without including <unistd.h>");
 #  endif
@@ -219,7 +219,7 @@ rpl_fd_isset (SOCKET fd, fd_set * set)
 #   define setsockopt          setsockopt_used_without_including_sys_socket_h
 #   undef shutdown
 #   define shutdown            shutdown_used_without_including_sys_socket_h
-#  else
+#  elif !defined __clang__
     _GL_WARN_ON_USE (socket,
                      "socket() used without including <sys/socket.h>");
     _GL_WARN_ON_USE (connect,
diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h
index 89e167f..3e0e4b2 100644
--- a/lib/sys_stat.in.h
+++ b/lib/sys_stat.in.h
@@ -391,6 +391,12 @@ struct stat
 #endif
 
 
+#if defined _WIN32 && !defined __CYGWIN__
+# undef chmod
+# define chmod _chmod
+#endif
+
+
 #if @GNULIB_FCHMODAT@
 # if @REPLACE_FCHMODAT@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
@@ -432,7 +438,9 @@ _GL_CXXALIAS_RPL (fstat, int, (int fd, struct stat *buf));
 # else
 _GL_CXXALIAS_SYS (fstat, int, (int fd, struct stat *buf));
 # endif
+# if __GLIBC__ >= 2
 _GL_CXXALIASWARN (fstat);
+# endif
 #elif @GNULIB_OVERRIDES_STRUCT_STAT@
 # undef fstat
 # define fstat fstat_used_without_requesting_gnulib_module_fstat
@@ -800,6 +808,12 @@ _GL_WARN_ON_USE (stat, "stat is unportable - "
 #endif
 
 
+#if defined _WIN32 && !defined __CYGWIN__
+# undef umask
+# define umask _umask
+#endif
+
+
 #if @GNULIB_UTIMENSAT@
 /* Use the rpl_ prefix also on Solaris <= 9, because on Solaris 9 our utimensat
    implementation relies on futimesat, which on Solaris 10 makes an invocation
diff --git a/lib/sys_time.in.h b/lib/sys_time.in.h
index d30b267..1c12d5f 100644
--- a/lib/sys_time.in.h
+++ b/lib/sys_time.in.h
@@ -135,7 +135,7 @@ _GL_WARN_ON_USE (gettimeofday, "gettimeofday is unportable 
- "
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   undef close
 #   define close close_used_without_including_unistd_h
-#  else
+#  elif !defined __clang__
      _GL_WARN_ON_USE (close,
                       "close() used without including <unistd.h>");
 #  endif
diff --git a/lib/time.in.h b/lib/time.in.h
index 1d11650..32e6ec0 100644
--- a/lib/time.in.h
+++ b/lib/time.in.h
@@ -135,13 +135,19 @@ _GL_CXXALIASWARN (nanosleep);
 #   endif
 _GL_FUNCDECL_RPL (tzset, void, (void));
 _GL_CXXALIAS_RPL (tzset, void, (void));
-#  else
-#   if ! @HAVE_TZSET@
-_GL_FUNCDECL_SYS (tzset, void, (void));
+#  elif defined _WIN32 && !defined __CYGWIN__
+#   if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#    undef tzset
+#    define tzset _tzset
 #   endif
+_GL_CXXALIAS_MDA (tzset, void, (void));
+#  else
 _GL_CXXALIAS_SYS (tzset, void, (void));
 #  endif
 _GL_CXXALIASWARN (tzset);
+# elif defined _WIN32 && !defined __CYGWIN__
+#  undef tzset
+#  define tzset _tzset
 # endif
 
 /* Return the 'time_t' representation of TP and normalize TP.  */
diff --git a/lib/time_rz.c b/lib/time_rz.c
index 5d85963..95438cf 100644
--- a/lib/time_rz.c
+++ b/lib/time_rz.c
@@ -54,31 +54,6 @@ enum { ABBR_SIZE_MIN = DEFAULT_MXFAST - offsetof (struct 
tm_zone, abbrs) };
    matters; the pointer is never dereferenced.  */
 static timezone_t const local_tz = (timezone_t) 1;
 
-#if HAVE_TM_ZONE || HAVE_TZNAME
-
-/* Return true if the values A and B differ according to the rules for
-   tm_isdst: A and B differ if one is zero and the other positive.  */
-static bool
-isdst_differ (int a, int b)
-{
-  return !a != !b && 0 <= a && 0 <= b;
-}
-
-/* Return true if A and B are equal.  */
-static int
-equal_tm (const struct tm *a, const struct tm *b)
-{
-  return ! ((a->tm_sec ^ b->tm_sec)
-            | (a->tm_min ^ b->tm_min)
-            | (a->tm_hour ^ b->tm_hour)
-            | (a->tm_mday ^ b->tm_mday)
-            | (a->tm_mon ^ b->tm_mon)
-            | (a->tm_year ^ b->tm_year)
-            | isdst_differ (a->tm_isdst, b->tm_isdst));
-}
-
-#endif
-
 /* Copy to ABBRS the abbreviation at ABBR with size ABBR_SIZE (this
    includes its trailing null byte).  Append an extra null byte to
    mark the end of ABBRS.  */
@@ -327,17 +302,25 @@ mktime_z (timezone_t tz, struct tm *tm)
       timezone_t old_tz = set_tz (tz);
       if (old_tz)
         {
-          time_t t = mktime (tm);
-#if HAVE_TM_ZONE || HAVE_TZNAME
-          time_t badtime = -1;
           struct tm tm_1;
-          if ((t != badtime
-               || (localtime_r (&t, &tm_1) && equal_tm (tm, &tm_1)))
-              && !save_abbr (tz, tm))
-            t = badtime;
+          tm_1.tm_sec = tm->tm_sec;
+          tm_1.tm_min = tm->tm_min;
+          tm_1.tm_hour = tm->tm_hour;
+          tm_1.tm_mday = tm->tm_mday;
+          tm_1.tm_mon = tm->tm_mon;
+          tm_1.tm_year = tm->tm_year;
+          tm_1.tm_yday = -1;
+          tm_1.tm_isdst = tm->tm_isdst;
+          time_t t = mktime (&tm_1);
+          bool ok = 0 <= tm_1.tm_yday;
+#if HAVE_TM_ZONE || HAVE_TZNAME
+          ok = ok && save_abbr (tz, &tm_1);
 #endif
-          if (revert_tz (old_tz))
-            return t;
+          if (revert_tz (old_tz) && ok)
+            {
+              *tm = tm_1;
+              return t;
+            }
         }
       return -1;
     }
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index a81a14f..357a35e 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -273,6 +273,12 @@ _GL_INLINE_HEADER_BEGIN
 _GL_FUNCDECL_RPL (access, int, (const char *file, int mode)
                                _GL_ARG_NONNULL ((1)));
 _GL_CXXALIAS_RPL (access, int, (const char *file, int mode));
+# elif defined _WIN32 && !defined __CYGWIN__
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef access
+#   define access _access
+#  endif
+_GL_CXXALIAS_MDA (access, int, (const char *file, int mode));
 # else
 _GL_CXXALIAS_SYS (access, int, (const char *file, int mode));
 # endif
@@ -286,11 +292,22 @@ _GL_WARN_ON_USE (access, "access does not always support 
X_OK - "
                  "also, this function is a security risk - "
                  "use the gnulib module faccessat instead");
 # endif
+#elif defined _WIN32 && !defined __CYGWIN__
+# undef access
+# define access _access
 #endif
 
 
 #if @GNULIB_CHDIR@
+# if defined _WIN32 && !defined __CYGWIN__
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef chdir
+#   define chdir _chdir
+#  endif
+_GL_CXXALIAS_MDA (chdir, int, (const char *file));
+# else
 _GL_CXXALIAS_SYS (chdir, int, (const char *file) _GL_ARG_NONNULL ((1)));
+# endif
 _GL_CXXALIASWARN (chdir);
 #elif defined GNULIB_POSIXCHECK
 # undef chdir
@@ -298,6 +315,9 @@ _GL_CXXALIASWARN (chdir);
 _GL_WARN_ON_USE (chown, "chdir is not always in <unistd.h> - "
                  "use gnulib module chdir for portability");
 # endif
+#elif defined _WIN32 && !defined __CYGWIN__
+# undef chdir
+# define chdir _chdir
 #endif
 
 
@@ -342,6 +362,12 @@ _GL_WARN_ON_USE (chown, "chown fails to follow symlinks on 
some systems and "
 #  endif
 _GL_FUNCDECL_RPL (close, int, (int fd));
 _GL_CXXALIAS_RPL (close, int, (int fd));
+# elif defined _WIN32 && !defined __CYGWIN__
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef close
+#   define close _close
+#  endif
+_GL_CXXALIAS_MDA (close, int, (int fd));
 # else
 _GL_CXXALIAS_SYS (close, int, (int fd));
 # endif
@@ -354,6 +380,9 @@ _GL_CXXALIASWARN (close);
 /* Assume close is always declared.  */
 _GL_WARN_ON_USE (close, "close does not portably work on sockets - "
                  "use gnulib module close for portability");
+#elif defined _WIN32 && !defined __CYGWIN__
+# undef close
+# define close _close
 #endif
 
 
@@ -382,6 +411,12 @@ _GL_WARN_ON_USE (copy_file_range,
 #  endif
 _GL_FUNCDECL_RPL (dup, int, (int oldfd));
 _GL_CXXALIAS_RPL (dup, int, (int oldfd));
+# elif defined _WIN32 && !defined __CYGWIN__
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef dup
+#   define dup _dup
+#  endif
+_GL_CXXALIAS_MDA (dup, int, (int oldfd));
 # else
 _GL_CXXALIAS_SYS (dup, int, (int oldfd));
 # endif
@@ -392,6 +427,9 @@ _GL_CXXALIASWARN (dup);
 _GL_WARN_ON_USE (dup, "dup is unportable - "
                  "use gnulib module dup for portability");
 # endif
+#elif defined _WIN32 && !defined __CYGWIN__
+# undef dup
+# define dup _dup
 #endif
 
 
@@ -407,6 +445,12 @@ _GL_WARN_ON_USE (dup, "dup is unportable - "
 #  endif
 _GL_FUNCDECL_RPL (dup2, int, (int oldfd, int newfd));
 _GL_CXXALIAS_RPL (dup2, int, (int oldfd, int newfd));
+# elif defined _WIN32 && !defined __CYGWIN__
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef dup2
+#   define dup2 _dup2
+#  endif
+_GL_CXXALIAS_MDA (dup2, int, (int oldfd, int newfd));
 # else
 _GL_CXXALIAS_SYS (dup2, int, (int oldfd, int newfd));
 # endif
@@ -417,6 +461,9 @@ _GL_CXXALIASWARN (dup2);
 _GL_WARN_ON_USE (dup2, "dup2 is unportable - "
                  "use gnulib module dup2 for portability");
 # endif
+#elif defined _WIN32 && !defined __CYGWIN__
+# undef dup2
+# define dup2 _dup2
 #endif
 
 
@@ -517,6 +564,43 @@ _GL_WARN_ON_USE (euidaccess, "euidaccess is unportable - "
 #endif
 
 
+#if defined _WIN32 && !defined __CYGWIN__
+# undef execl
+# define execl _execl
+#endif
+
+#if defined _WIN32 && !defined __CYGWIN__
+# undef execle
+# define execle _execle
+#endif
+
+#if defined _WIN32 && !defined __CYGWIN__
+# undef execlp
+# define execlp _execlp
+#endif
+
+
+#if defined _WIN32 && !defined __CYGWIN__
+# undef execv
+# define execv _execv
+#endif
+
+#if defined _WIN32 && !defined __CYGWIN__
+# undef execve
+# define execve _execve
+#endif
+
+#if defined _WIN32 && !defined __CYGWIN__
+# undef execvp
+# define execvp _execvp
+#endif
+
+#if defined _WIN32 && !defined __CYGWIN__
+# undef execvpe
+# define execvpe _execvpe
+#endif
+
+
 #if @GNULIB_FACCESSAT@
 # if @REPLACE_FACCESSAT@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
@@ -692,6 +776,12 @@ _GL_WARN_ON_USE (ftruncate, "ftruncate is unportable - "
 #  endif
 _GL_FUNCDECL_RPL (getcwd, char *, (char *buf, size_t size));
 _GL_CXXALIAS_RPL (getcwd, char *, (char *buf, size_t size));
+# elif defined _WIN32 && !defined __CYGWIN__
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef getcwd
+#   define getcwd _getcwd
+#  endif
+_GL_CXXALIAS_MDA (getcwd, char *, (char *buf, size_t size));
 # else
 /* Need to cast, because on mingw, the second parameter is
                                                    int size.  */
@@ -704,6 +794,9 @@ _GL_CXXALIASWARN (getcwd);
 _GL_WARN_ON_USE (getcwd, "getcwd is unportable - "
                  "use gnulib module getcwd for portability");
 # endif
+#elif defined _WIN32 && !defined __CYGWIN__
+# undef getcwd
+# define getcwd _getcwd
 #endif
 
 
@@ -1038,6 +1131,12 @@ _GL_WARN_ON_USE (getpass, "getpass is unportable - "
 #endif
 
 
+#if defined _WIN32 && !defined __CYGWIN__
+# undef getpid
+# define getpid _getpid
+#endif
+
+
 #if @GNULIB_GETUSERSHELL@
 /* Return the next valid login shell on the system, or NULL when the end of
    the list has been reached.  */
@@ -1110,6 +1209,12 @@ _GL_WARN_ON_USE (group_member, "group_member is 
unportable - "
 #  endif
 _GL_FUNCDECL_RPL (isatty, int, (int fd));
 _GL_CXXALIAS_RPL (isatty, int, (int fd));
+# elif defined _WIN32 && !defined __CYGWIN__
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef isatty
+#   define isatty _isatty
+#  endif
+_GL_CXXALIAS_MDA (isatty, int, (int fd));
 # else
 _GL_CXXALIAS_SYS (isatty, int, (int fd));
 # endif
@@ -1120,6 +1225,9 @@ _GL_CXXALIASWARN (isatty);
 _GL_WARN_ON_USE (isatty, "isatty has portability problems on native Windows - "
                  "use gnulib module isatty for portability");
 # endif
+#elif defined _WIN32 && !defined __CYGWIN__
+# undef isatty
+# define isatty _isatty
 #endif
 
 
@@ -1231,6 +1339,12 @@ _GL_WARN_ON_USE (linkat, "linkat is unportable - "
 #  endif
 _GL_FUNCDECL_RPL (lseek, off_t, (int fd, off_t offset, int whence));
 _GL_CXXALIAS_RPL (lseek, off_t, (int fd, off_t offset, int whence));
+# elif defined _WIN32 && !defined __CYGWIN__
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef lseek
+#   define lseek _lseek
+#  endif
+_GL_CXXALIAS_MDA (lseek, off_t, (int fd, off_t offset, int whence));
 # else
 _GL_CXXALIAS_SYS (lseek, off_t, (int fd, off_t offset, int whence));
 # endif
@@ -1241,6 +1355,9 @@ _GL_CXXALIASWARN (lseek);
 _GL_WARN_ON_USE (lseek, "lseek does not fail with ESPIPE on pipes on some "
                  "systems - use gnulib module lseek for portability");
 # endif
+#elif defined _WIN32 && !defined __CYGWIN__
+# undef lseek
+# define lseek _lseek
 #endif
 
 
@@ -1373,6 +1490,12 @@ _GL_WARN_ON_USE (pwrite, "pwrite is unportable - "
 _GL_FUNCDECL_RPL (read, ssize_t, (int fd, void *buf, size_t count)
                                  _GL_ARG_NONNULL ((2)));
 _GL_CXXALIAS_RPL (read, ssize_t, (int fd, void *buf, size_t count));
+# elif defined _WIN32 && !defined __CYGWIN__
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef read
+#   define read _read
+#  endif
+_GL_CXXALIAS_MDA (read, ssize_t, (int fd, void *buf, size_t count));
 # else
 /* Need to cast, because on mingw, the third parameter is
                                                           unsigned int count
@@ -1380,6 +1503,9 @@ _GL_CXXALIAS_RPL (read, ssize_t, (int fd, void *buf, 
size_t count));
 _GL_CXXALIAS_SYS_CAST (read, ssize_t, (int fd, void *buf, size_t count));
 # endif
 _GL_CXXALIASWARN (read);
+#elif defined _WIN32 && !defined __CYGWIN__
+# undef read
+# define read _read
 #endif
 
 
@@ -1462,6 +1588,12 @@ _GL_WARN_ON_USE (readlinkat, "readlinkat is not portable 
- "
 #  endif
 _GL_FUNCDECL_RPL (rmdir, int, (char const *name) _GL_ARG_NONNULL ((1)));
 _GL_CXXALIAS_RPL (rmdir, int, (char const *name));
+# elif defined _WIN32 && !defined __CYGWIN__
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef rmdir
+#   define rmdir _rmdir
+#  endif
+_GL_CXXALIAS_MDA (rmdir, int, (char const *name));
 # else
 _GL_CXXALIAS_SYS (rmdir, int, (char const *name));
 # endif
@@ -1472,6 +1604,9 @@ _GL_CXXALIASWARN (rmdir);
 _GL_WARN_ON_USE (rmdir, "rmdir is unportable - "
                  "use gnulib module rmdir for portability");
 # endif
+#elif defined _WIN32 && !defined __CYGWIN__
+# undef rmdir
+# define rmdir _rmdir
 #endif
 
 
@@ -1530,6 +1665,12 @@ _GL_WARN_ON_USE (sleep, "sleep is unportable - "
 #endif
 
 
+#if defined _WIN32 && !defined __CYGWIN__
+# undef swab
+# define swab _swab
+#endif
+
+
 #if @GNULIB_SYMLINK@
 # if @REPLACE_SYMLINK@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
@@ -1654,6 +1795,12 @@ _GL_WARN_ON_USE (ttyname_r, "ttyname_r is not portable - 
"
 #  endif
 _GL_FUNCDECL_RPL (unlink, int, (char const *file) _GL_ARG_NONNULL ((1)));
 _GL_CXXALIAS_RPL (unlink, int, (char const *file));
+# elif defined _WIN32 && !defined __CYGWIN__
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef unlink
+#   define unlink _unlink
+#  endif
+_GL_CXXALIAS_MDA (unlink, int, (char const *file));
 # else
 _GL_CXXALIAS_SYS (unlink, int, (char const *file));
 # endif
@@ -1664,6 +1811,9 @@ _GL_CXXALIASWARN (unlink);
 _GL_WARN_ON_USE (unlink, "unlink is not portable - "
                  "use gnulib module unlink for portability");
 # endif
+#elif defined _WIN32 && !defined __CYGWIN__
+# undef unlink
+# define unlink _unlink
 #endif
 
 
@@ -1735,6 +1885,12 @@ _GL_WARN_ON_USE (usleep, "usleep is unportable - "
 _GL_FUNCDECL_RPL (write, ssize_t, (int fd, const void *buf, size_t count)
                                   _GL_ARG_NONNULL ((2)));
 _GL_CXXALIAS_RPL (write, ssize_t, (int fd, const void *buf, size_t count));
+# elif defined _WIN32 && !defined __CYGWIN__
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef write
+#   define write _write
+#  endif
+_GL_CXXALIAS_MDA (write, ssize_t, (int fd, const void *buf, size_t count));
 # else
 /* Need to cast, because on mingw, the third parameter is
                                                              unsigned int count
@@ -1742,6 +1898,9 @@ _GL_CXXALIAS_RPL (write, ssize_t, (int fd, const void 
*buf, size_t count));
 _GL_CXXALIAS_SYS_CAST (write, ssize_t, (int fd, const void *buf, size_t 
count));
 # endif
 _GL_CXXALIASWARN (write);
+#elif defined _WIN32 && !defined __CYGWIN__
+# undef write
+# define write _write
 #endif
 
 _GL_INLINE_HEADER_END
diff --git a/lib/verify.h b/lib/verify.h
index 58172f3..d485a02 100644
--- a/lib/verify.h
+++ b/lib/verify.h
@@ -23,11 +23,15 @@
 
 /* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert (R, DIAGNOSTIC)
    works as per C11.  This is supported by GCC 4.6.0 and later, in C
-   mode.
+   mode, and by clang (also in C++ mode).
 
    Define _GL_HAVE__STATIC_ASSERT1 to 1 if _Static_assert (R) works as
-   per C2X, and define _GL_HAVE_STATIC_ASSERT1 if static_assert (R)
-   works as per C++17.  This is supported by GCC 9.1 and later.
+   per C2X.  This is supported by GCC 9.1 and later, and by clang in
+   C++1z mode.
+
+   Define _GL_HAVE_STATIC_ASSERT1 if static_assert (R) works as per
+   C++17.  This is supported by GCC 9.1 and later, and by clang in
+   C++1z mode.
 
    Support compilers claiming conformance to the relevant standard,
    and also support GCC when not pedantic.  If we were willing to slow
@@ -35,7 +39,8 @@
    since this affects only the quality of diagnostics, why bother?  */
 #ifndef __cplusplus
 # if (201112L <= __STDC_VERSION__ \
-      || (!defined __STRICT_ANSI__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)))
+      || (!defined __STRICT_ANSI__ \
+          && (4 < __GNUC__ + (6 <= __GNUC_MINOR__) || 4 <= __clang_major__)))
 #  define _GL_HAVE__STATIC_ASSERT 1
 # endif
 # if (202000L <= __STDC_VERSION__ \
@@ -43,7 +48,15 @@
 #  define _GL_HAVE__STATIC_ASSERT1 1
 # endif
 #else
-# if 201703L <= __cplusplus || 9 <= __GNUC__
+# if 4 <= __clang_major__
+#  define _GL_HAVE__STATIC_ASSERT 1
+# endif
+# if 4 <= __clang_major__ && 201411 <= __cpp_static_assert
+#  define _GL_HAVE__STATIC_ASSERT1 1
+# endif
+# if 201703L <= __cplusplus \
+     || 9 <= __GNUC__ \
+     || (4 <= __clang_major__ && 201411 <= __cpp_static_assert)
 #  define _GL_HAVE_STATIC_ASSERT1 1
 # endif
 #endif
@@ -233,13 +246,6 @@ template <int w>
 
 /* @assert.h omit start@  */
 
-#if defined __has_builtin
-/* <https://clang.llvm.org/docs/LanguageExtensions.html#builtin-functions> */
-# define _GL_HAS_BUILTIN_ASSUME __has_builtin (__builtin_assume)
-#else
-# define _GL_HAS_BUILTIN_ASSUME 0
-#endif
-
 #if 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__))
 # define _GL_HAS_BUILTIN_TRAP 1
 #elif defined __has_builtin
@@ -299,11 +305,14 @@ template <int w>
 
    Although assuming R can help a compiler generate better code or
    diagnostics, performance can suffer if R uses hard-to-optimize
-   features such as function calls not inlined by the compiler.  */
+   features such as function calls not inlined by the compiler.
+
+   Avoid Clang’s __builtin_assume, as clang 9.0.1 -Wassume can
+   generate a bogus diagnostic "the argument to '__builtin_assume' has
+   side effects that will be discarded" even when the argument has no
+   side effects.  */
 
-#if _GL_HAS_BUILTIN_ASSUME
-# define assume(R) __builtin_assume (R)
-#elif _GL_HAS_BUILTIN_UNREACHABLE
+#if _GL_HAS_BUILTIN_UNREACHABLE
 # define assume(R) ((R) ? (void) 0 : __builtin_unreachable ())
 #elif 1200 <= _MSC_VER
 # define assume(R) __assume (R)
diff --git a/lisp/Makefile.in b/lisp/Makefile.in
index 9bccece..164e4a0 100644
--- a/lisp/Makefile.in
+++ b/lisp/Makefile.in
@@ -302,7 +302,7 @@ endif
 # subdirectories, to make sure require's and load's in the files being
 # compiled find the right files.
 
-.SUFFIXES: .eln .elc .el
+.SUFFIXES: .elc .el
 
 # An old-fashioned suffix rule, which, according to the GNU Make manual,
 # cannot have prerequisites.
@@ -357,13 +357,6 @@ compile-main: gen-lisp compile-clean
                  TARGETS="$$chunk";                 \
        done
 
-.PHONY: native-compile-clean
-native-compile-clean:
-# Erase all eln output compilation folders.
-ifeq ($(HAVE_NATIVE_COMP),yes)
-       find $(lisp) -regex ".*/eln-.*-[0-9a-z]+\\'" -type d | xargs rm -rf
-endif
-
 .PHONY: compile-clean
 # Erase left-over .elc files that do not have a corresponding .el file.
 compile-clean:
@@ -400,7 +393,7 @@ compile: $(LOADDEFS) autoloads compile-first
 # Compile all Lisp files.  This is like 'compile' but compiles files
 # unconditionally.  Some files don't actually get compiled because they
 # set the local variable no-byte-compile.
-compile-always: native-compile-clean
+compile-always:
        find $(lisp) -name '*.elc' $(FIND_DELETE)
        $(MAKE) compile
 
@@ -490,7 +483,7 @@ $(CAL_DIR)/hol-loaddefs.el: $(CAL_SRC) 
$(CAL_DIR)/diary-loaddefs.el
 
 .PHONY: bootstrap-clean distclean maintainer-clean extraclean
 
-bootstrap-clean: native-compile-clean
+bootstrap-clean:
        find $(lisp) -name '*.elc' $(FIND_DELETE)
        rm -f $(AUTOGENEL)
 
diff --git a/lisp/abbrev.el b/lisp/abbrev.el
index 2d61a96..468b0d9 100644
--- a/lisp/abbrev.el
+++ b/lisp/abbrev.el
@@ -517,14 +517,6 @@ It is nil if the abbrev has already been unexpanded.")
 ;;   "Local (mode-specific) abbrev table of current buffer.")
 ;; (make-variable-buffer-local 'local-abbrev-table)
 
-(defcustom pre-abbrev-expand-hook nil
-  "Function or functions to be called before abbrev expansion is done.
-This is the first thing that `expand-abbrev' does, and so this may change
-the current abbrev table before abbrev lookup happens."
-  :type 'hook
-  :group 'abbrev-mode)
-(make-obsolete-variable 'pre-abbrev-expand-hook 'abbrev-expand-function "23.1")
-
 (defun clear-abbrev-table (table)
   "Undefine all abbrevs in abbrev table TABLE, leaving it empty."
   (setq abbrevs-changed t)
@@ -836,12 +828,10 @@ Takes no argument and should return the abbrev symbol if 
expansion took place.")
 (defun expand-abbrev ()
   "Expand the abbrev before point, if there is an abbrev there.
 Effective when explicitly called even when `abbrev-mode' is nil.
-Before doing anything else, runs `pre-abbrev-expand-hook'.
 Calls the value of `abbrev-expand-function' with no argument to do
 the work, and returns whatever it does.  (That return value should
 be the abbrev symbol if expansion occurred, else nil.)"
   (interactive)
-  (run-hooks 'pre-abbrev-expand-hook)
   (funcall abbrev-expand-function))
 
 (defun abbrev--default-expand ()
diff --git a/lisp/bookmark.el b/lisp/bookmark.el
index 36a361c..8a3bcf8 100644
--- a/lisp/bookmark.el
+++ b/lisp/bookmark.el
@@ -923,8 +923,6 @@ annotations."
          "#  Date:    " (current-time-string) "\n"))
 
 
-(define-obsolete-variable-alias 'bookmark-read-annotation-text-func
-  'bookmark-edit-annotation-text-func "23.1")
 (defvar bookmark-edit-annotation-text-func 'bookmark-default-annotation-text
   "Function to return default text to use for a bookmark annotation.
 It takes one argument, the name of the bookmark, as a string.")
@@ -1143,17 +1141,6 @@ DISPLAY-FUNC would be `switch-to-buffer-other-window'."
   (let ((pop-up-frames t))
     (bookmark-jump-other-window bookmark)))
 
-(defun bookmark-jump-noselect (bookmark)
-  "Return the location pointed to by BOOKMARK (see `bookmark-jump').
-The return value has the form (BUFFER . POINT).
-
-Note: this function is deprecated and is present for Emacs 22
-compatibility only."
-  (declare (obsolete bookmark-handle-bookmark "23.1"))
-  (save-excursion
-    (bookmark-handle-bookmark bookmark)
-    (cons (current-buffer) (point))))
-
 (defun bookmark-handle-bookmark (bookmark-name-or-record)
   "Call BOOKMARK-NAME-OR-RECORD's handler or `bookmark-default-handler'
 if it has none.  This changes current buffer and point and returns nil,
diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el
index aa5c47c..d06ba28 100644
--- a/lisp/buff-menu.el
+++ b/lisp/buff-menu.el
@@ -229,9 +229,6 @@ commands.")
     map)
   "Local keymap for `Buffer-menu-mode' buffers.")
 
-(define-obsolete-variable-alias 'buffer-menu-mode-hook
-  'Buffer-menu-mode-hook "23.1")
-
 (define-derived-mode Buffer-menu-mode tabulated-list-mode "Buffer Menu"
   "Major mode for Buffer Menu buffers.
 The Buffer Menu is invoked by the commands \\[list-buffers],
diff --git a/lisp/cedet/ede/make.el b/lisp/cedet/ede/make.el
index ecce3e7..140e738 100644
--- a/lisp/cedet/ede/make.el
+++ b/lisp/cedet/ede/make.el
@@ -32,29 +32,15 @@
 
 (declare-function inversion-check-version "inversion")
 
-(if (fboundp 'locate-file)
-    (defsubst ede--find-executable (exec)
-      "Return an expanded file name for a program EXEC on the exec path."
-      (locate-file exec exec-path))
-
-  ;; Else, older version of Emacs.
-
-  (defsubst ede--find-executable (exec)
-    "Return an expanded file name for a program EXEC on the exec path."
-    (let ((p exec-path)
-         (found nil))
-      (while (and p (not found))
-        (let ((f (expand-file-name exec (car p))))
-         (if (file-exists-p f)
-             (setq found f)))
-        (setq p (cdr p)))
-      found))
-  )
+(defsubst ede--find-executable (exec)
+  "Return an expanded file name for a program EXEC on the exec path."
+  (declare (obsolete locate-file "28.1"))
+  (locate-file exec exec-path))
 
 (defvar ede-make-min-version "3.0"
   "Minimum version of GNU make required.")
 
-(defcustom ede-make-command (cond ((ede--find-executable "gmake")
+(defcustom ede-make-command (cond ((executable-find "gmake")
                                   "gmake")
                                  (t "make")) ;; What to do?
   "The MAKE command to use for EDE when compiling.
diff --git a/lisp/cedet/semantic/bovine/c.el b/lisp/cedet/semantic/bovine/c.el
index 358829a..3649d1c 100644
--- a/lisp/cedet/semantic/bovine/c.el
+++ b/lisp/cedet/semantic/bovine/c.el
@@ -46,27 +46,10 @@
 (declare-function c-forward-conditional "cc-cmds")
 (declare-function ede-system-include-path "ede")
 
-;;; Compatibility
-;;
 (eval-when-compile (require 'cc-mode))
 
-(if (fboundp 'c-end-of-macro)
-    (eval-and-compile
-      (defalias 'semantic-c-end-of-macro 'c-end-of-macro))
-  ;; From cc-mode 5.30
-  (defun semantic-c-end-of-macro ()
-    "Go to the end of a preprocessor directive.
-More accurately, move point to the end of the closest following line
-that doesn't end with a line continuation backslash.
-
-This function does not do any hidden buffer changes."
-    (while (progn
-             (end-of-line)
-             (when (and (eq (char-before) ?\\)
-                        (not (eobp)))
-               (forward-char)
-               t))))
-  )
+(define-obsolete-function-alias 'semantic-c-end-of-macro
+  #'c-end-of-macro "28.1")
 
 ;;; Code:
 (with-suppressed-warnings ((obsolete define-child-mode))
@@ -266,7 +249,7 @@ Return the defined symbol as a special spp lex token."
           (semantic-lex-analyzer #'semantic-cpp-lexer)
           (raw-stream
            (semantic-lex-spp-stream-for-macro (save-excursion
-                                                (semantic-c-end-of-macro)
+                                                (c-end-of-macro)
                                                 ;; HACK - If there's a C 
comment after
                                                 ;; the macro, do not parse it.
                                                 (if (looking-back "/\\*.*" 
beginning-of-define)
@@ -590,7 +573,7 @@ case, we must skip it since it is the ELSE part."
 (define-lex-regex-analyzer semantic-lex-c-macrobits
   "Ignore various forms of #if/#else/#endif conditionals."
   "^\\s-*#\\s-*\\(if\\(n?def\\)?\\|endif\\|elif\\|else\\)"
-  (semantic-c-end-of-macro)
+  (c-end-of-macro)
   (setq semantic-lex-end-point (point))
   nil)
 
diff --git a/lisp/cedet/semantic/dep.el b/lisp/cedet/semantic/dep.el
index 47afa25..60ab603 100644
--- a/lisp/cedet/semantic/dep.el
+++ b/lisp/cedet/semantic/dep.el
@@ -183,16 +183,8 @@ macro 
`defcustom-mode-local-semantic-dependency-system-include-path'."
 ;;
 ;; methods for finding files on a provided path.
 (defmacro semantic--dependency-find-file-on-path (file path)
-  (if (fboundp 'locate-file)
-      `(locate-file ,file ,path)
-    `(let ((p ,path)
-          (found nil))
-       (while (and p (not found))
-        (let ((f (expand-file-name ,file (car p))))
-          (if (file-exists-p f)
-              (setq found f)))
-        (setq p (cdr p)))
-       found)))
+  (declare (obsolete locate-file "28.1"))
+  `(locate-file ,file ,path))
 
 (defvar ede-minor-mode)
 (defvar ede-object)
@@ -216,11 +208,11 @@ provided mode, not from the current major mode."
     (when (file-exists-p file)
       (setq found file))
     (when (and (not found) (not systemp))
-      (setq found (semantic--dependency-find-file-on-path file locp)))
+      (setq found (locate-file file locp)))
     (when (and (not found) edesys)
-      (setq found (semantic--dependency-find-file-on-path file edesys)))
+      (setq found (locate-file file edesys)))
     (when (not found)
-      (setq found (semantic--dependency-find-file-on-path file sysp)))
+      (setq found (locate-file file sysp)))
     (if found (expand-file-name found))))
 
 
diff --git a/lisp/cedet/semantic/lex-spp.el b/lisp/cedet/semantic/lex-spp.el
index b8812de..e6e124e 100644
--- a/lisp/cedet/semantic/lex-spp.el
+++ b/lisp/cedet/semantic/lex-spp.el
@@ -70,7 +70,7 @@
 (require 'semantic)
 (require 'semantic/lex)
 
-(declare-function semantic-c-end-of-macro "semantic/bovine/c")
+(declare-function c-end-of-macro "cc-engine")
 
 ;;; Code:
 (defvar semantic-lex-spp-macro-symbol-obarray nil
@@ -946,7 +946,7 @@ by another macro."
     (save-excursion
       (let ((start (match-beginning 0))
            (end (match-end 0))
-           (peom (save-excursion (semantic-c-end-of-macro) (point))))
+           (peom (save-excursion (c-end-of-macro) (point))))
        (condition-case nil
           (progn
             ;; This will throw an error if no closing paren can be found.
diff --git a/lisp/comint.el b/lisp/comint.el
index c3cb439..092902d 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -223,6 +223,13 @@ This variable is buffer-local."
                 (other :tag "on" t))
   :group 'comint)
 
+(defcustom comint-highlight-input t
+  "If non-nil, highlight input with `comint-highlight-input' face.
+Otherwise keep the original highlighting untouched."
+  :version "28.1"
+  :type 'boolean
+  :group 'comint)
+
 (defface comint-highlight-input '((t (:weight bold)))
   "Face to use to highlight user input."
   :group 'comint)
@@ -1897,9 +1904,10 @@ Similarly for Soar, Scheme, etc."
               (end (if no-newline (point) (1- (point)))))
           (with-silent-modifications
             (when (> end beg)
-              (add-text-properties beg end
-                                   '(front-sticky t
-                                     font-lock-face comint-highlight-input))
+              (when comint-highlight-input
+                (add-text-properties beg end
+                                     '( font-lock-face comint-highlight-input
+                                        front-sticky t )))
               (unless comint-use-prompt-regexp
                 ;; Give old user input a field property of `input', to
                 ;; distinguish it from both process output and unsent
@@ -3852,7 +3860,7 @@ REGEXP-GROUP is the regular expression group in REGEXP to 
use."
       (set-buffer output-buffer)
       (goto-char (point-min))
       ;; Skip past the command, if it was echoed
-      (and (looking-at command)
+      (and (looking-at (regexp-quote command))
           (forward-line))
       (while (and (not (eobp))
                  (re-search-forward regexp nil t))
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el
index 1669596..23ceb3a 100644
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@ -801,16 +801,19 @@ has been executed, nil otherwise."
 If a setting was edited and set before, this saves it.  If a
 setting was merely edited before, this sets it then saves it."
   (interactive)
-  (when (custom-command-apply
-        (lambda (child)
-          (when (memq (widget-get child :custom-state)
-                      '(modified set changed rogue))
-            (widget-apply child :custom-mark-to-save)))
-        "Save all settings in this buffer? " t)
-    ;; Save changes to buffer and redraw.
-    (custom-save-all)
-    (dolist (child custom-options)
-      (widget-apply child :custom-state-set-and-redraw))))
+  (let (edited-widgets)
+    (when (custom-command-apply
+          (lambda (child)
+            (when (memq (widget-get child :custom-state)
+                        '(modified set changed rogue))
+               (push child edited-widgets)
+              (widget-apply child :custom-mark-to-save)))
+          "Save all settings in this buffer? " t)
+      ;; Save changes to buffer.
+      (custom-save-all)
+      ;; Redraw and recalculate the state when necessary.
+      (dolist (widget edited-widgets)
+        (widget-apply widget :custom-state-set-and-redraw)))))
 
 (defun custom-reset (_widget &optional event)
   "Select item from reset menu."
@@ -4868,8 +4871,6 @@ If several parents are listed, go to the first of them."
               (parent (downcase (widget-get  button :tag))))
          (customize-group parent)))))
 
-(define-obsolete-variable-alias 'custom-mode-hook 'Custom-mode-hook "23.1")
-
 (defcustom Custom-mode-hook nil
   "Hook called when entering Custom mode."
   :type 'hook
@@ -4940,8 +4941,6 @@ if that value is non-nil."
 
 (put 'Custom-mode 'mode-class 'special)
 
-(define-obsolete-function-alias 'custom-mode 'Custom-mode "23.1")
-
 ;;; The End.
 
 (provide 'cus-edit)
diff --git a/lisp/descr-text.el b/lisp/descr-text.el
index 55f0b7d..d6da428 100644
--- a/lisp/descr-text.el
+++ b/lisp/descr-text.el
@@ -141,8 +141,7 @@ otherwise."
         (wid-field (get-char-property pos 'field))
         (wid-button (get-char-property pos 'button))
         (wid-doc (get-char-property pos 'widget-doc))
-        ;; If button.el is not loaded, we have no buttons in the text.
-        (button (and (fboundp 'button-at) (button-at pos)))
+        (button (button-at pos))
         (button-type (and button (button-type button)))
         (button-label (and button (button-label button)))
         (widget (or wid-field wid-button wid-doc)))
diff --git a/lisp/desktop.el b/lisp/desktop.el
index 7fe5f73..7a7f1d0 100644
--- a/lisp/desktop.el
+++ b/lisp/desktop.el
@@ -1037,7 +1037,7 @@ file.
 
 To upgrade a version 206 file to version 208, call this command
 explicitly with a prefix argument: \\[universal-argument] \\[desktop-save].
-If you are upgrading from Emacs 24 or older, we recommed to do
+If you are upgrading from Emacs 24 or older, we recommend to do
 this once you decide you no longer need compatibility with versions
 of Emacs before 25.1.
 
diff --git a/lisp/dirtrack.el b/lisp/dirtrack.el
index 3a0bbd2..ad0c18d 100644
--- a/lisp/dirtrack.el
+++ b/lisp/dirtrack.el
@@ -196,9 +196,6 @@ directory."
     (remove-hook 'comint-preoutput-filter-functions 'dirtrack t)))
 
 
-(define-obsolete-function-alias 'dirtrack-debug-toggle 'dirtrack-debug-mode
-  "23.1")
-(define-obsolete-variable-alias 'dirtrack-debug 'dirtrack-debug-mode "23.1")
 (define-minor-mode dirtrack-debug-mode
   "Toggle Dirtrack debugging."
   nil nil nil
diff --git a/lisp/doc-view.el b/lisp/doc-view.el
index de342f1..77c06a8 100644
--- a/lisp/doc-view.el
+++ b/lisp/doc-view.el
@@ -435,6 +435,9 @@ Typically \"page-%s.png\".")
     (define-key map (kbd "c m")       'doc-view-set-slice-using-mouse)
     (define-key map (kbd "c b")       'doc-view-set-slice-from-bounding-box)
     (define-key map (kbd "c r")       'doc-view-reset-slice)
+    ;; Centering the image
+    (define-key map (kbd "c h")       'doc-view-center-page-horizontally)
+    (define-key map (kbd "c v")       'doc-view-center-page-vertically)
     ;; Searching
     (define-key map (kbd "C-s")       'doc-view-search)
     (define-key map (kbd "<find>")    'doc-view-search)
@@ -740,8 +743,7 @@ It's a subdirectory of `doc-view-cache-directory'."
 Document types are symbols like `dvi', `ps', `pdf', or `odf' (any
 OpenDocument format)."
   (and (display-graphic-p)
-       (or (image-type-available-p 'imagemagick)
-          (image-type-available-p 'png))
+       (image-type-available-p 'png)
        (cond
        ((eq type 'dvi)
         (and (doc-view-mode-p 'pdf)
@@ -769,10 +771,7 @@ OpenDocument format)."
 (defun doc-view-enlarge (factor)
   "Enlarge the document by FACTOR."
   (interactive (list doc-view-shrink-factor))
-  (if (and doc-view-scale-internally
-           (eq (plist-get (cdr (doc-view-current-image)) :type)
-               'imagemagick))
-      ;; ImageMagick supports on-the-fly-rescaling.
+  (if doc-view-scale-internally
       (let ((new (ceiling (* factor doc-view-image-width))))
         (unless (equal new doc-view-image-width)
           (setq-local doc-view-image-width new)
@@ -792,9 +791,7 @@ OpenDocument format)."
 (defun doc-view-scale-reset ()
   "Reset the document size/zoom level to the initial one."
   (interactive)
-  (if (and doc-view-scale-internally
-           (eq (plist-get (cdr (doc-view-current-image)) :type)
-               'imagemagick))
+  (if doc-view-scale-internally
       (progn
        (kill-local-variable 'doc-view-image-width)
        (doc-view-insert-image
@@ -927,6 +924,32 @@ Resize the containing frame if needed."
     (when new-frame-params
       (modify-frame-parameters (selected-frame) new-frame-params))))
 
+(defun doc-view-center-page-horizontally ()
+  "Center page horizontally when page is wider than window."
+  (interactive)
+  (let ((page-width (car (image-size (doc-view-current-image) 'pixel)))
+        (window-width (window-body-width nil 'pixel))
+        ;; How much do we scroll in order to center the page?
+        (pixel-hscroll 0)
+        ;; How many pixels are there in a column?
+        (col-in-pixel (/ (window-body-width nil 'pixel)
+                         (window-body-width nil))))
+    (when (> page-width window-width)
+      (setq pixel-hscroll (/ (- page-width window-width) 2))
+      (set-window-hscroll (selected-window)
+                          (/ pixel-hscroll col-in-pixel)))))
+
+(defun doc-view-center-page-vertically ()
+  "Center page vertically when page is wider than window."
+  (interactive)
+  (let ((page-height (cdr (image-size (doc-view-current-image) 'pixel)))
+        (window-height (window-body-height nil 'pixel))
+        ;; How much do we scroll in order to center the page?
+        (pixel-scroll 0))
+    (when (> page-height window-height)
+      (setq pixel-scroll (/ (- page-height window-height) 2))
+      (set-window-vscroll (selected-window) pixel-scroll 'pixel))))
+
 (defun doc-view-reconvert-doc ()
   "Reconvert the current document.
 Should be invoked when the cached images aren't up-to-date."
@@ -1393,12 +1416,11 @@ ARGS is a list of image descriptors."
     ;; Only insert the image if the buffer is visible.
     (when (window-live-p (overlay-get ol 'window))
       (let* ((image (if (and file (file-readable-p file))
-                       (if (not (and doc-view-scale-internally
-                                     (fboundp 'imagemagick-types)))
+                       (if (not doc-view-scale-internally)
                            (apply #'create-image file doc-view--image-type nil 
args)
                          (unless (member :width args)
                            (setq args `(,@args :width ,doc-view-image-width)))
-                         (apply #'create-image file 'imagemagick nil args))))
+                         (apply #'create-image file doc-view--image-type nil 
args))))
             (slice (doc-view-current-slice))
             (img-width (and image (car (image-size image))))
             (displayed-img-width (if (and image slice)
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 20a481a..507cfe7 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -2041,7 +2041,8 @@ The value is non-nil if there were no errors, nil if 
errors."
        (with-current-buffer output-buffer
          (goto-char (point-max))
          (insert "\n")                 ; aaah, unix.
-         (if (file-writable-p target-file)
+         (if (or (file-writable-p target-file)
+                  byte-native-compiling)
              ;; We must disable any code conversion here.
              (progn
                (let* ((coding-system-for-write 'no-conversion)
@@ -2050,7 +2051,8 @@ The value is non-nil if there were no errors, nil if 
errors."
                       ;; parallel bootstrap), it does not risk getting a
                       ;; half-finished file.  (Bug#4196)
                       (tempfile
-                       (make-temp-file (expand-file-name target-file)))
+                       (make-temp-file (when (file-writable-p target-file)
+                                          (expand-file-name target-file))))
                       (default-modes (default-file-modes))
                       (temp-modes (logand default-modes #o600))
                       (desired-modes (logand default-modes #o666))
diff --git a/lisp/emacs-lisp/chart.el b/lisp/emacs-lisp/chart.el
index 2321ac1..964836a 100644
--- a/lisp/emacs-lisp/chart.el
+++ b/lisp/emacs-lisp/chart.el
@@ -105,9 +105,7 @@ Useful if new Emacs is used on B&W display.")
                                       (car cl)
                                     "white"))
           (set-face-foreground nf "black")
-          (if (and chart-face-use-pixmaps
-                   pl
-                   (fboundp 'set-face-background-pixmap))
+          (if (and chart-face-use-pixmaps pl)
               (condition-case nil
                   (set-face-background-pixmap nf (car pl))
                 (error (message "Cannot set background pixmap %s" (car pl)))))
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index a92392f..3176351 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -36,18 +36,12 @@
 (require 'gv)
 (require 'rx)
 (require 'subr-x)
+(require 'warnings)
 
 (defgroup comp nil
   "Emacs Lisp native compiler."
   :group 'lisp)
 
-(defcustom comp-deferred-compilation nil
-  "If non-nil compile asyncronously all .elc files being loaded.
-Once compilation happened each function definition is updated to
-the native compiled one."
-  :type 'boolean
-  :group 'comp)
-
 (defcustom comp-speed 2
   "Compiler optimization level.  From -1 to 3.
 - -1 functions are kept in bytecode form and no native compilation is 
performed.
@@ -143,6 +137,9 @@ before compilation.  Usable to modify the compiler 
environment."
 (defvar comp-dry-run nil
   "When non nil run everything but the C back-end.")
 
+(defconst comp-valid-source-re (rx ".el" (? ".gz") eos)
+  "Regexp to match filename of valid input source files.")
+
 (defconst comp-log-buffer-name "*Native-compile-Log*"
   "Name of the native-compiler log buffer.")
 
@@ -569,28 +566,6 @@ VERBOSITY is a number between 0 and 3."
 
 
 
-(defun comp-output-directory (src)
-  "Return the compilation direcotry for source SRC."
-  (let* ((src (if (symbolp src) (symbol-name src) src))
-         (expanded-filename (expand-file-name src)))
-    (file-name-as-directory
-     (concat (file-name-directory expanded-filename)
-             comp-native-path-postfix))))
-
-(defun comp-output-base-filename (src)
-  "Output filename sans extention for SRC file being native compiled."
-  (let* ((src (if (symbolp src) (symbol-name src) src))
-         (expanded-filename (expand-file-name src))
-         (output-dir (comp-output-directory src))
-         (output-filename
-          (file-name-sans-extension
-           (file-name-nondirectory expanded-filename))))
-    (expand-file-name output-filename output-dir)))
-
-(defun comp-output-filename (src)
-  "Output filename for SRC file being native compiled."
-  (concat (comp-output-base-filename src) ".eln"))
-
 (defmacro comp-loop-insn-in-block (basic-block &rest body)
   "Loop over all insns in BASIC-BLOCK executning BODY.
 Inside BODY `insn' can be used to read or set the current
@@ -2486,7 +2461,7 @@ Prepare every function for final compilation and drive 
the C back-end."
     (unless (file-exists-p dir)
       ;; In case it's created in the meanwhile.
       (ignore-error 'file-already-exists
-        (make-directory dir)))
+        (make-directory dir t)))
     (unless comp-dry-run
       (comp--compile-ctxt-to-file name))))
 
@@ -2592,17 +2567,20 @@ display a message."
         (cl-loop
          for (source-file . load) = (pop comp-files-queue)
          while source-file
-         do (cl-assert (string-match-p (rx ".el" eos) source-file) nil
+         do (cl-assert (string-match-p comp-valid-source-re source-file) nil
                        "`comp-files-queue' should be \".el\" files: %s"
                        source-file)
          when (or comp-always-compile
+                  load ; Always compile when the compilation is
+                       ; commanded for late load.
                   (file-newer-than-file-p source-file
-                                          (comp-output-filename source-file)))
+                                          (comp-el-to-eln-filename 
source-file)))
          do (let* ((expr `(progn
                             (require 'comp)
                             (setf comp-speed ,comp-speed
                                   comp-debug ,comp-debug
                                   comp-verbose ,comp-verbose
+                                  comp-eln-load-path ',comp-eln-load-path
                                   load-path ',load-path)
                             ,comp-async-env-modifier-form
                             (message "Compiling %s..." ,source-file)
@@ -2636,7 +2614,7 @@ display a message."
                                (when (and load1
                                           (zerop (process-exit-status 
process)))
                                  (native-elisp-load
-                                  (comp-output-filename source-file1)
+                                  (comp-el-to-eln-filename source-file1)
                                   (eq load1 'late)))
                                (comp-run-async-workers)))))
               (puthash source-file process comp-async-compilations))
@@ -2676,7 +2654,11 @@ Return the compilation unit file name."
          (byte-compile-debug t)
          (comp-ctxt
           (make-comp-ctxt
-           :output (comp-output-base-filename function-or-file)
+           :output (comp-el-to-eln-filename (if (symbolp function-or-file)
+                                                (symbol-name function-or-file)
+                                              function-or-file)
+                                            (when byte-native-for-bootstrap
+                                              (car (last comp-eln-load-path))))
            :with-late-load with-late-load)))
     (comp-log "\n\n" 1)
     (condition-case err
@@ -2746,8 +2728,8 @@ LOAD can be nil t or 'late."
     (dolist (path paths)
       (cond ((file-directory-p path)
              (dolist (file (if recursively
-                               (directory-files-recursively path (rx ".el" 
eos))
-                             (directory-files path t (rx ".el" eos))))
+                               (directory-files-recursively path 
comp-valid-source-re)
+                             (directory-files path t comp-valid-source-re)))
                (push file files)))
             ((file-exists-p path) (push path files))
             (t (signal 'native-compiler-error
@@ -2770,11 +2752,11 @@ queued with LOAD %"
                     (and (eq load 'late)
                          (cl-some (lambda (re) (string-match re file))
                                   comp-deferred-compilation-black-list)))
-          (let ((out-dir (comp-output-directory file))
-                (out-filename (comp-output-filename file)))
-            (if (or (file-writable-p out-filename)
-                    (and (not (file-exists-p out-dir))
-                         (file-writable-p (substring out-dir 0 -1))))
+          (let* ((out-filename (comp-el-to-eln-filename file))
+                 (out-dir (file-name-directory out-filename)))
+            (unless (file-exists-p out-dir)
+              (make-directory out-dir t))
+            (if (file-writable-p out-filename)
                 (setf comp-files-queue
                       (append comp-files-queue `((,file . ,load))))
               (display-warning 'comp
diff --git a/lisp/emacs-lisp/crm.el b/lisp/emacs-lisp/crm.el
index 65483d0..89d106e 100644
--- a/lisp/emacs-lisp/crm.el
+++ b/lisp/emacs-lisp/crm.el
@@ -270,12 +270,6 @@ with empty strings removed."
     (remove-hook 'choose-completion-string-functions
                 'crm--choose-completion-string)))
 
-(define-obsolete-function-alias 'crm-minibuffer-complete 'crm-complete "23.1")
-(define-obsolete-function-alias
-  'crm-minibuffer-completion-help 'crm-completion-help "23.1")
-(define-obsolete-function-alias
-  'crm-minibuffer-complete-and-exit 'crm-complete-and-exit "23.1")
-
 ;; testing and debugging
 ;; (defun crm-init-test-environ ()
 ;;   "Set up some variables for testing."
diff --git a/lisp/emacs-lisp/derived.el b/lisp/emacs-lisp/derived.el
index 3eafad1..6a11f1c 100644
--- a/lisp/emacs-lisp/derived.el
+++ b/lisp/emacs-lisp/derived.el
@@ -364,6 +364,7 @@ which more-or-less shadow%s %s's corresponding table%s."
 
 (defsubst derived-mode-setup-function-name (mode)
   "Construct a setup-function name based on a MODE name."
+  (declare (obsolete nil "28.1"))
   (intern (concat (symbol-name mode) "-setup")))
 
 
diff --git a/lisp/emacs-lisp/easymenu.el b/lisp/emacs-lisp/easymenu.el
index 6ba8b99..73dabef 100644
--- a/lisp/emacs-lisp/easymenu.el
+++ b/lisp/emacs-lisp/easymenu.el
@@ -29,16 +29,6 @@
 
 ;;; Code:
 
-(defvar easy-menu-precalculate-equivalent-keybindings nil
-  "Determine when equivalent key bindings are computed for easy-menu menus.
-It can take some time to calculate the equivalent key bindings that are shown
-in a menu.  If the variable is on, then this calculation gives a (maybe
-noticeable) delay when a mode is first entered.  If the variable is off, then
-this delay will come when a menu is displayed the first time.  If you never use
-menus, turn this variable off, otherwise it is probably better to keep it on.")
-(make-obsolete-variable
- 'easy-menu-precalculate-equivalent-keybindings nil "23.1")
-
 (defsubst easy-menu-intern (s)
   (if (stringp s) (intern s) s))
 
diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el
index 764354b..241eece 100644
--- a/lisp/emacs-lisp/ert.el
+++ b/lisp/emacs-lisp/ert.el
@@ -515,7 +515,14 @@ Returns nil if they are."
                        `(cdr ,cdr-x)
                      (cl-assert (equal a b) t)
                      nil))))))))
-      ((pred arrayp)
+      ((pred cl-struct-p)
+       (cl-loop for slot in (cl-struct-slot-info (type-of a))
+                for ai across a
+                for bi across b
+                for xf = (ert--explain-equal-rec ai bi)
+                do (when xf (cl-return `(struct-field ,(car slot) ,xf)))
+                finally (cl-assert (equal a b) t)))
+      ((or (pred arrayp) (pred recordp))
        ;; For mixed unibyte/multibyte string comparisons, make both multibyte.
        (when (and (stringp a)
                   (xor (multibyte-string-p a) (multibyte-string-p b)))
diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el
index efbcfb3..60b1625 100644
--- a/lisp/emacs-lisp/find-func.el
+++ b/lisp/emacs-lisp/find-func.el
@@ -188,11 +188,7 @@ LIBRARY should be a string (the name of the library)."
    ((string-match "\\.el\\(c\\(\\..*\\)?\\)\\'" library)
     (setq library (replace-match "" t t library)))
    ((string-match "\\.eln\\'" library)
-    ;; From help-fns.el.
-    (setq library (expand-file-name (concat (file-name-base library)
-                                            ".el")
-                                   (concat (file-name-directory library)
-                                            "..")))))
+    (setq library (gethash (file-name-nondirectory library) 
comp-eln-to-el-h))))
   (or
    (locate-file library
                 (or find-function-source-path load-path)
@@ -300,12 +296,13 @@ if non-nil)."
                          (find-library-suffixes)
                          "\\|"))
          (table (cl-loop for dir in (or find-function-source-path load-path)
-                         when (file-readable-p dir)
+                         for dir-or-default = (or dir default-directory)
+                         when (file-readable-p dir-or-default)
                          append (mapcar
                                  (lambda (file)
                                    (replace-regexp-in-string suffix-regexp
                                                              "" file))
-                                 (directory-files dir nil
+                                 (directory-files dir-or-default nil
                                                   suffix-regexp))))
          (def (if (eq (function-called-at-point) 'require)
                   ;; `function-called-at-point' may return 'require
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index 1311d94..584ed8c 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -200,7 +200,9 @@
     (save-excursion
       (ignore-errors
         (goto-char pos)
-        (or (eql (char-before) ?\')
+        ;; '(lambda ..) is not a funcall position, but #'(lambda ...) is.
+        (or (and (eql (char-before) ?\')
+                 (not (eql (char-before (1- (point))) ?#)))
             (let* ((ppss (syntax-ppss))
                    (paren-posns (nth 9 ppss))
                    (parent
@@ -785,8 +787,6 @@ or to switch back to an existing one."
             nil)))
       (comment-indent-default)))
 
-(define-obsolete-function-alias 'lisp-mode-auto-fill 'do-auto-fill "23.1")
-
 (defcustom lisp-indent-offset nil
   "If non-nil, indent second line of expressions that many more columns."
   :group 'lisp
diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el
index 88bb0a8..8d8d071 100644
--- a/lisp/emacs-lisp/rx.el
+++ b/lisp/emacs-lisp/rx.el
@@ -255,9 +255,9 @@ Left-fold the list L, starting with X, by the binary 
function F."
   x)
 
 (defun rx--normalise-or-arg (form)
-  "Normalise the `or' argument FORM.
+  "Normalize the `or' argument FORM.
 Characters become strings, user-definitions and `eval' forms are expanded,
-and `or' forms are normalised recursively."
+and `or' forms are normalized recursively."
   (cond ((characterp form)
          (char-to-string form))
         ((and (consp form) (memq (car form) '(or |)))
diff --git a/lisp/emulation/viper-cmd.el b/lisp/emulation/viper-cmd.el
index 77f1b29..dd7648c 100644
--- a/lisp/emulation/viper-cmd.el
+++ b/lisp/emulation/viper-cmd.el
@@ -694,7 +694,7 @@
 ARG is used as the prefix value for the executed command.  If
 EVENTS is a list of events, which become the beginning of the command."
   (interactive "P")
-  (if (viper= (viper-last-command-char) ?\\)
+  (if (viper= last-command-event ?\\)
       (message "Switched to EMACS state for the next command..."))
   (viper-escape-to-state arg events 'emacs-state))
 
@@ -1149,7 +1149,7 @@ as a Meta key and any number of multiple escapes are 
allowed."
   "Begin numeric argument for the next command."
   (interactive "P")
   (viper-prefix-arg-value
-   (viper-last-command-char) (if (consp arg) (cdr arg) nil)))
+   last-command-event (if (consp arg) (cdr arg) nil)))
 
 (defun viper-command-argument (arg)
   "Accept a motion command as an argument."
@@ -1157,7 +1157,7 @@ as a Meta key and any number of multiple escapes are 
allowed."
   (let ((viper-intermediate-command 'viper-command-argument))
     (condition-case nil
        (viper-prefix-arg-com
-        (viper-last-command-char)
+        last-command-event
         (cond ((null arg) nil)
               ((consp arg) (car arg))
               ((integerp arg) arg)
@@ -1564,7 +1564,7 @@ invokes the command before that, etc."
 
 ;; Hook used in viper-undo
 (defun viper-after-change-undo-hook (beg end _len)
-  (if (and (boundp 'undo-in-progress) undo-in-progress)
+  (if undo-in-progress
       (setq undo-beg-posn beg
            undo-end-posn (or end beg))
     ;; some other hooks may be changing various text properties in
@@ -1598,9 +1598,9 @@ invokes the command before that, etc."
                   (pos-visible-in-window-p before-undo-pt))
              (progn
                (push-mark (point-marker) t)
-               (viper-sit-for-short 300)
+               (sit-for 0.3)
                (goto-char undo-end-posn)
-               (viper-sit-for-short 300)
+               (sit-for 0.3)
                (if (pos-visible-in-window-p undo-beg-posn)
                    (goto-char before-undo-pt)
                  (goto-char undo-beg-posn)))
@@ -1886,15 +1886,11 @@ Undo previous insertion and inserts new."
     (or unread-command-events
        executing-kbd-macro
        (sit-for 840))
-    (if (fboundp 'minibuffer-prompt-end)
-       (delete-region (minibuffer-prompt-end) (point-max))
-      (erase-buffer))
+    (delete-region (minibuffer-prompt-end) (point-max))
     (insert viper-initial)))
 
 (defsubst viper-minibuffer-real-start ()
-  (if (fboundp 'minibuffer-prompt-end)
-      (minibuffer-prompt-end)
-    (point-min)))
+  (minibuffer-prompt-end))
 
 (defun viper-minibuffer-post-command-hook()
   (when (active-minibuffer-window)
@@ -1908,7 +1904,7 @@ Undo previous insertion and inserts new."
   "Exit minibuffer Viper way."
   (interactive)
   (let (command)
-    (setq command (local-key-binding (char-to-string 
(viper-last-command-char))))
+    (setq command (local-key-binding (char-to-string last-command-event)))
     (run-hooks 'viper-minibuffer-exit-hook)
     (if command
        (command-execute command)
@@ -2883,7 +2879,7 @@ If point is on a widget or a button, simulate clicking on 
that widget/button."
                (and (consp widget)
                     (get (widget-type widget) 'widget-type))))
         (widget-button-press (point))
-      (if (and (fboundp 'button-at) (fboundp 'push-button) (button-at (point)))
+      (if (button-at (point))
           (push-button)
        ;; not a widget or a button
         (save-excursion
@@ -4738,8 +4734,7 @@ Please, specify your level now: "))
        (viper-color-display-p (if (viper-window-display-p)
                              (viper-color-display-p)
                               'non-x))
-        (viper-frame-parameters (if (fboundp 'frame-parameters)
-                                    (frame-parameters (selected-frame))))
+        (viper-frame-parameters (frame-parameters (selected-frame)))
        (viper-minibuffer-emacs-face (if (viper-has-face-support-p)
                                          (facep
                                           viper-minibuffer-emacs-face)
diff --git a/lisp/emulation/viper-mous.el b/lisp/emulation/viper-mous.el
index 6ecfec5..928a3ef 100644
--- a/lisp/emulation/viper-mous.el
+++ b/lisp/emulation/viper-mous.el
@@ -98,7 +98,7 @@ considered related."
 ;;; Code
 
 (defsubst viper-multiclick-p ()
-  (not (viper-sit-for-short viper-multiclick-timeout t)))
+  (not (sit-for (/ viper-multiclick-timeout 1000.0) t)))
 
 ;; Returns window where click occurs
 (defun viper-mouse-click-window (click)
diff --git a/lisp/emulation/viper-util.el b/lisp/emulation/viper-util.el
index 1561204..83e45e1 100644
--- a/lisp/emulation/viper-util.el
+++ b/lisp/emulation/viper-util.el
@@ -786,14 +786,11 @@ Otherwise return the normal value."
 (defun viper-check-minibuffer-overlay ()
   (if (overlayp viper-minibuffer-overlay)
       (move-overlay
-       viper-minibuffer-overlay
-       (if (fboundp 'minibuffer-prompt-end) (minibuffer-prompt-end) 1)
-       (1+ (buffer-size)))
+       viper-minibuffer-overlay (minibuffer-prompt-end) (1+ (buffer-size)))
     (setq viper-minibuffer-overlay
          ;; make overlay open-ended
          (make-overlay
-          (if (fboundp 'minibuffer-prompt-end) (minibuffer-prompt-end) 1)
-          (1+ (buffer-size))
+          (minibuffer-prompt-end) (1+ (buffer-size))
           (current-buffer) nil 'rear-advance))))
 
 
@@ -808,9 +805,8 @@ Otherwise return the normal value."
 (define-obsolete-function-alias 'viper-abbreviate-file-name
   'abbreviate-file-name "27.1")
 
-;; Sit for VAL milliseconds.  XEmacs doesn't support the millisecond arg
-;; in sit-for, so this function smooths out the differences.
 (defsubst viper-sit-for-short (val &optional nodisp)
+  (declare (obsolete nil "28.1"))
   (sit-for (/ val 1000.0) nodisp))
 
 ;; EVENT may be a single event of a sequence of events
@@ -868,11 +864,10 @@ Otherwise return the normal value."
 
 ;; Uses different timeouts for ESC-sequences and others
 (defun viper-fast-keysequence-p ()
-  (not (viper-sit-for-short
-       (if (viper-ESC-event-p last-input-event)
-           (viper-ESC-keyseq-timeout)
-         viper-fast-keyseq-timeout)
-       t)))
+  (not (sit-for (/ (if (viper-ESC-event-p last-input-event)
+                      (viper-ESC-keyseq-timeout)
+                    viper-fast-keyseq-timeout) 1000.0)
+               t)))
 
 (define-obsolete-function-alias 'viper-read-event-convert-to-char
   'read-event "27.1")
@@ -920,6 +915,7 @@ Otherwise return the normal value."
       basis)))
 
 (defun viper-last-command-char ()
+  (declare (obsolete nil "28.1"))
   last-command-event)
 
 (defun viper-key-to-emacs-key (key)
diff --git a/lisp/epa.el b/lisp/epa.el
index d190824..5140d3f 100644
--- a/lisp/epa.el
+++ b/lisp/epa.el
@@ -666,10 +666,6 @@ If SECRET is non-nil, list secret keys instead of public 
keys."
          (goto-char (point-min)))
        (display-buffer buffer)))))
 
-(defun epa-display-verify-result (verify-result)
-  (declare (obsolete epa-display-info "23.1"))
-  (epa-display-info (epg-verify-result-to-string verify-result)))
-
 (defun epa-passphrase-callback-function (context key-id handback)
   (if (eq key-id 'SYM)
       (read-passwd
diff --git a/lisp/epg.el b/lisp/epg.el
index 96af3ad..920b853 100644
--- a/lisp/epg.el
+++ b/lisp/epg.el
@@ -190,6 +190,7 @@
   (string nil :read-only t))
 
 ;;;; Context Struct
+(declare-function epa-passphrase-callback-function "epa.el")
 
 (cl-defstruct (epg-context
                (:constructor nil)
@@ -215,7 +216,7 @@
   cipher-algorithm
   digest-algorithm
   compress-algorithm
-  (passphrase-callback (list #'epg-passphrase-callback-function))
+  (passphrase-callback (list #'epa-passphrase-callback-function))
   progress-callback
   edit-callback
   signers
@@ -1246,19 +1247,6 @@ callback data (if any)."
 
 ;;; Functions
 
-(defun epg-passphrase-callback-function (context key-id _handback)
-  (declare (obsolete epa-passphrase-callback-function "23.1"))
-  (if (eq key-id 'SYM)
-      (read-passwd "Passphrase for symmetric encryption: "
-                  (eq (epg-context-operation context) 'encrypt))
-    (read-passwd
-     (if (eq key-id 'PIN)
-       "Passphrase for PIN: "
-       (let ((entry (assoc key-id epg-user-id-alist)))
-        (if entry
-            (format "Passphrase for %s %s: " key-id (cdr entry))
-          (format "Passphrase for %s: " key-id)))))))
-
 (defun epg--list-keys-1 (context name mode)
   (let ((args (append (if (epg-context-home-directory context)
                          (list "--homedir"
diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el
index 4f3d85b..1cf0bb4 100644
--- a/lisp/erc/erc-backend.el
+++ b/lisp/erc/erc-backend.el
@@ -98,7 +98,6 @@
 
 ;;; Code:
 
-(require 'erc-compat)
 (eval-when-compile (require 'cl-lib))
 ;; There's a fairly strong mutual dependency between erc.el and erc-backend.el.
 ;; Luckily, erc.el does not need erc-backend.el for macroexpansion whereas the
@@ -782,7 +781,7 @@ value of `erc-server-coding-system'."
           (pop precedence))
         (when precedence
           (setq coding (car precedence)))))
-    (erc-decode-coding-string str coding)))
+    (decode-coding-string str coding t)))
 
 ;; proposed name, not used by anything yet
 (defun erc-send-line (text display-fn)
diff --git a/lisp/erc/erc-dcc.el b/lisp/erc/erc-dcc.el
index bf98eb8..477f148 100644
--- a/lisp/erc/erc-dcc.el
+++ b/lisp/erc/erc-dcc.el
@@ -419,7 +419,7 @@ where FOO is one of CLOSE, GET, SEND, LIST, CHAT, etc."
   (pcomplete-here
    (pcase (intern (downcase (pcomplete-arg 1)))
      ('chat (mapcar (lambda (elt) (plist-get elt :nick))
-                    (erc-remove-if-not
+                    (cl-remove-if-not
                      #'(lambda (elt)
                          (eq (plist-get elt :type) 'CHAT))
                      erc-dcc-list)))
@@ -427,7 +427,7 @@ where FOO is one of CLOSE, GET, SEND, LIST, CHAT, etc."
               (mapcar (lambda (elt) (symbol-name (plist-get elt :type)))
                       erc-dcc-list)))
      ('get (mapcar #'erc-dcc-nick
-                   (erc-remove-if-not
+                   (cl-remove-if-not
                     #'(lambda (elt)
                         (eq (plist-get elt :type) 'GET))
                     erc-dcc-list)))
@@ -435,7 +435,7 @@ where FOO is one of CLOSE, GET, SEND, LIST, CHAT, etc."
   (pcomplete-here
    (pcase (intern (downcase (pcomplete-arg 2)))
      ('get (mapcar (lambda (elt) (plist-get elt :file))
-                   (erc-remove-if-not
+                   (cl-remove-if-not
                     #'(lambda (elt)
                         (and (eq (plist-get elt :type) 'GET)
                              (erc-nick-equal-p (erc-extract-nick
@@ -443,7 +443,7 @@ where FOO is one of CLOSE, GET, SEND, LIST, CHAT, etc."
                                                (pcomplete-arg 1))))
                     erc-dcc-list)))
      ('close (mapcar #'erc-dcc-nick
-                     (erc-remove-if-not
+                     (cl-remove-if-not
                       #'(lambda (elt)
                           (eq (plist-get elt :type)
                               (intern (upcase (pcomplete-arg 1)))))
diff --git a/lisp/erc/erc-fill.el b/lisp/erc/erc-fill.el
index 39a8be5..d09caf7 100644
--- a/lisp/erc/erc-fill.el
+++ b/lisp/erc/erc-fill.el
@@ -38,7 +38,7 @@
   :group 'erc)
 
 ;;;###autoload(autoload 'erc-fill-mode "erc-fill" nil t)
-(erc-define-minor-mode erc-fill-mode
+(define-minor-mode erc-fill-mode
   "Toggle ERC fill mode.
 With a prefix argument ARG, enable ERC fill mode if ARG is
 positive, and disable it otherwise.  If called from Lisp, enable
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index ff7a77f..a475f0a 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -399,8 +399,7 @@ See `erc-interpret-controls-p' and 
`erc-interpret-mirc-color' for options."
                         (start (match-beginning 0))
                         (end (+ (match-beginning 0)
                                 (length (match-string 5 s)))))
-                    (setq s (erc-replace-match-subexpression-in-string
-                             "" s control 1 start))
+                    (setq s (replace-match "" nil nil s 1))
                     (cond ((and erc-interpret-mirc-color (or fg-color 
bg-color))
                            (setq fg fg-color)
                            (setq bg bg-color))
diff --git a/lisp/erc/erc-log.el b/lisp/erc/erc-log.el
index e2c066d..2166123 100644
--- a/lisp/erc/erc-log.el
+++ b/lisp/erc/erc-log.el
@@ -267,7 +267,7 @@ The current buffer is given by BUFFER."
     (with-current-buffer buffer
       (auto-save-mode -1)
       (setq buffer-file-name nil)
-      (erc-set-write-file-functions '(erc-save-buffer-in-logs))
+      (set (make-local-variable 'write-file-functions) 
'(erc-save-buffer-in-logs))
       (when erc-log-insert-log-on-open
        (ignore-errors
          (save-excursion
diff --git a/lisp/erc/erc-match.el b/lisp/erc/erc-match.el
index 6e87a18..b314567 100644
--- a/lisp/erc/erc-match.el
+++ b/lisp/erc/erc-match.el
@@ -94,7 +94,9 @@ The following values are allowed:
  `nick-or-keyword' - highlight the nick of the user who typed your nickname,
                      or all instances of the current nickname if there was
                      no sending user
- `all'             - highlight the entire message where current nickname occurs
+ `message'         - highlight the entire message where current nickname occurs
+ `all'             - highlight the entire message (including the nick) where
+                     current nickname occurs
 
 Any other value disables highlighting of current nickname altogether."
   :group 'erc-match
@@ -102,6 +104,7 @@ Any other value disables highlighting of current nickname 
altogether."
                 (const nick)
                 (const keyword)
                 (const nick-or-keyword)
+                 (const message)
                 (const all)))
 
 (defcustom erc-pal-highlight-type 'nick
@@ -110,14 +113,17 @@ See `erc-pals'.
 
 The following values are allowed:
 
-    nil    - do not highlight the message at all
-    `nick' - highlight pal's nickname only
-    `all'  - highlight the entire message from pal
+    nil       - do not highlight the message at all
+    `nick'    - highlight pal's nickname only
+    `message' - highlight the entire message from pal
+    `all'     - highlight the entire message (including the nick)
+                from pal
 
 Any other value disables pal highlighting altogether."
   :group 'erc-match
   :type '(choice (const nil)
                 (const nick)
+                 (const message)
                 (const all)))
 
 (defcustom erc-fool-highlight-type 'nick
@@ -126,14 +132,17 @@ See `erc-fools'.
 
 The following values are allowed:
 
-    nil    - do not highlight the message at all
-    `nick' - highlight fool's nickname only
-    `all'  - highlight the entire message from fool
+    nil       - do not highlight the message at all
+    `nick'    - highlight fool's nickname only
+    `message' - highlight the entire message from fool
+    `all'     - highlight the entire message (including the nick)
+                from fool
 
 Any other value disables fool highlighting altogether."
   :group 'erc-match
   :type '(choice (const nil)
                 (const nick)
+                 (const message)
                 (const all)))
 
 (defcustom erc-keyword-highlight-type 'keyword
@@ -143,12 +152,15 @@ See variable `erc-keywords'.
 The following values are allowed:
 
     `keyword' - highlight keyword only
-    `all'     - highlight the entire message containing keyword
+    `message' - highlight the entire message containing keyword
+    `all'     - highlight the entire message (including the nick)
+                containing keyword
 
 Any other value disables keyword highlighting altogether."
   :group 'erc-match
   :type '(choice (const nil)
                 (const keyword)
+                 (const message)
                 (const all)))
 
 (defcustom erc-dangerous-host-highlight-type 'nick
@@ -157,13 +169,16 @@ See `erc-dangerous-hosts'.
 
 The following values are allowed:
 
-    `nick' - highlight nick from dangerous-host only
-    `all'  - highlight the entire message from dangerous-host
+    `nick'    - highlight nick from dangerous-host only
+    `message' - highlight the entire message from dangerous-host
+    `all'     - highlight the entire message (including the nick)
+                from dangerous-host
 
 Any other value disables dangerous-host highlighting altogether."
   :group 'erc-match
   :type '(choice (const nil)
                 (const nick)
+                 (const message)
                 (const all)))
 
 
@@ -449,19 +464,18 @@ Use this defun with `erc-insert-modify-hook'."
                        (match-beginning 0)))
         (nick-end (when nick-beg
                     (match-end 0)))
-        (message (buffer-substring
-                  (if (and nick-end
-                           (<= (+ 2 nick-end) (point-max)))
-                      ;; Message starts 2 characters after the nick
-                      ;; except for CTCP ACTION messages.  Nick
-                      ;; surrounded by angle brackets only in normal
-                      ;; messages.
-                      (+ nick-end
-                         (if (eq ?> (char-after nick-end))
-                             2
-                           1))
-                    (point-min))
-                  (point-max))))
+         (message-beg (if (and nick-end
+                               (<= (+ 2 nick-end) (point-max)))
+                          ;; Message starts 2 characters after the
+                          ;; nick except for CTCP ACTION messages.
+                          ;; Nick surrounded by angle brackets only in
+                          ;; normal messages.
+                          (+ nick-end
+                             (if (eq ?> (char-after nick-end))
+                                 2
+                               1))
+                        (point-min)))
+         (message (buffer-substring message-beg (point-max))))
     (when (and vector
               (not (and erc-match-exclude-server-buffer
                         (erc-server-buffer-p))))
@@ -498,7 +512,12 @@ Use this defun with `erc-insert-modify-hook'."
                 (while (re-search-forward match-regex nil t)
                   (erc-put-text-property (match-beginning 0) (match-end 0)
                                          'font-lock-face match-face))))
-             ;; Highlight the whole message
+              ;; Highlight the whole message (not including the nick)
+              ((eq match-htype 'message)
+               (erc-put-text-property
+                message-beg (point-max)
+                'font-lock-face match-face (current-buffer)))
+             ;; Highlight the whole message (including the nick)
              ((eq match-htype 'all)
               (erc-put-text-property
                (point-min) (point-max)
diff --git a/lisp/erc/erc-notify.el b/lisp/erc/erc-notify.el
index 1b092c8..144a981 100644
--- a/lisp/erc/erc-notify.el
+++ b/lisp/erc/erc-notify.el
@@ -181,7 +181,7 @@ nick from `erc-last-ison' to prevent any further 
notifications."
   (let ((nick (erc-extract-nick (erc-response.sender parsed))))
     (when (and (erc-member-ignore-case nick erc-notify-list)
               (erc-member-ignore-case nick erc-last-ison))
-      (setq erc-last-ison (erc-delete-if
+      (setq erc-last-ison (cl-delete-if
                           (let ((nick-down (erc-downcase nick)))
                             (lambda (el)
                               (string= nick-down (erc-downcase el))))
diff --git a/lisp/erc/erc-pcomplete.el b/lisp/erc/erc-pcomplete.el
index 7643fa8..f8b7e13 100644
--- a/lisp/erc/erc-pcomplete.el
+++ b/lisp/erc/erc-pcomplete.el
@@ -41,7 +41,6 @@
 
 (require 'pcomplete)
 (require 'erc)
-(require 'erc-compat)
 (require 'time-date)
 
 (defgroup erc-pcomplete nil
diff --git a/lisp/erc/erc-stamp.el b/lisp/erc/erc-stamp.el
index cbab2f9..08970f2 100644
--- a/lisp/erc/erc-stamp.el
+++ b/lisp/erc/erc-stamp.el
@@ -35,7 +35,6 @@
 ;;; Code:
 
 (require 'erc)
-(require 'erc-compat)
 
 (defgroup erc-stamp nil
   "For long conversation on IRC it is sometimes quite
diff --git a/lisp/erc/erc-track.el b/lisp/erc/erc-track.el
index 41d8fc1..3398c8b 100644
--- a/lisp/erc/erc-track.el
+++ b/lisp/erc/erc-track.el
@@ -36,7 +36,6 @@
 
 (eval-when-compile (require 'cl-lib))
 (require 'erc)
-(require 'erc-compat)
 (require 'erc-match)
 
 ;;; Code:
@@ -329,9 +328,8 @@ important."
 
 (defun erc-track-remove-from-mode-line ()
   "Remove `erc-track-modified-channels' from the mode-line."
-  (when (boundp 'mode-line-modes)
-    (setq mode-line-modes
-         (remove '(t erc-modified-channels-object) mode-line-modes)))
+  (setq mode-line-modes
+       (remove '(t erc-modified-channels-object) mode-line-modes))
   (when (consp global-mode-string)
     (setq global-mode-string
          (delq 'erc-modified-channels-object global-mode-string))))
@@ -341,12 +339,10 @@ important."
 See `erc-track-position-in-mode-line' for possible values."
   ;; CVS Emacs has a new format string, and global-mode-string
   ;; is very far to the right.
-  (cond ((and (eq position 'before-modes)
-             (boundp 'mode-line-modes))
+  (cond ((eq position 'before-modes)
         (add-to-list 'mode-line-modes
                      '(t erc-modified-channels-object)))
-       ((and (eq position 'after-modes)
-             (boundp 'mode-line-modes))
+       ((eq position 'after-modes)
         (add-to-list 'mode-line-modes
                      '(t erc-modified-channels-object) t))
        ((eq position t)
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index 41d7516..8712113 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -57,12 +57,12 @@
 
 (load "erc-loaddefs" nil t)
 
-(eval-when-compile (require 'cl-lib))
+(require 'cl-lib)
 (require 'font-lock)
+(require 'format-spec)
 (require 'pp)
 (require 'thingatpt)
 (require 'auth-source)
-(require 'erc-compat)
 (require 'time-date)
 (require 'iso8601)
 (eval-when-compile (require 'subr-x))
@@ -877,8 +877,8 @@ See `erc-server-flood-margin' for other flood-related 
parameters.")
 ;; Script parameters
 
 (defcustom erc-startup-file-list
-  (list (concat erc-user-emacs-directory ".ercrc.el")
-        (concat erc-user-emacs-directory ".ercrc")
+  (list (concat user-emacs-directory ".ercrc.el")
+        (concat user-emacs-directory ".ercrc")
         "~/.ercrc.el" "~/.ercrc" ".ercrc.el" ".ercrc")
   "List of files to try for a startup script.
 The first existent and readable one will get executed.
@@ -1306,7 +1306,7 @@ Example:
          (enable (intern (format "erc-%s-enable" (downcase sn))))
          (disable (intern (format "erc-%s-disable" (downcase sn)))))
     `(progn
-       (erc-define-minor-mode
+       (define-minor-mode
         ,mode
         ,(format "Toggle ERC %S mode.
 With a prefix argument ARG, enable %s if ARG is positive,
@@ -1489,8 +1489,7 @@ Defaults to the server buffer."
 (define-derived-mode erc-mode fundamental-mode "ERC"
   "Major mode for Emacs IRC."
   (setq local-abbrev-table erc-mode-abbrev-table)
-  (when (boundp 'next-line-add-newlines)
-    (set (make-local-variable 'next-line-add-newlines) nil))
+  (set (make-local-variable 'next-line-add-newlines) nil)
   (setq line-move-ignore-invisible t)
   (set (make-local-variable 'paragraph-separate)
        (concat "\C-l\\|\\(^" (regexp-quote (erc-prompt)) "\\)"))
@@ -2688,7 +2687,7 @@ displayed hostnames."
 otherwise `erc-server-announced-name'.  SERVER is matched against
 `erc-common-server-suffixes'."
   (when server
-    (or (cdar (erc-remove-if-not
+    (or (cdar (cl-remove-if-not
                (lambda (net) (string-match (car net) server))
                erc-common-server-suffixes))
         erc-server-announced-name)))
@@ -3725,8 +3724,9 @@ the message given by REASON."
                                                       x-toolkit-scroll-bars)))
                                "")
                              (if (featurep 'multi-tty) ", multi-tty" ""))
-                            (if erc-emacs-build-time
-                                (concat " of " erc-emacs-build-time)
+                            (if emacs-build-time
+                                (concat " of " (format-time-string
+                                                "%Y-%m-%d" emacs-build-time))
                               "")))
   t)
 
@@ -4573,7 +4573,7 @@ See also: `erc-echo-notice-in-user-buffers',
                 ((string-match "^-" mode)
                  ;; Remove the unbanned masks from the ban list
                  (setq erc-channel-banlist
-                       (erc-delete-if
+                       (cl-delete-if
                         #'(lambda (y)
                             (member (upcase (cdr y))
                                     (mapcar #'upcase
@@ -4594,7 +4594,7 @@ See also: `erc-echo-notice-in-user-buffers',
   "Group LIST into sublists of length N."
   (cond ((null list) nil)
         ((null (nthcdr n list)) (list list))
-        (t (cons (erc-subseq list 0 n) (erc-group-list (nthcdr n list) n)))))
+        (t (cons (cl-subseq list 0 n) (erc-group-list (nthcdr n list) n)))))
 
 
 ;;; MOTD numreplies
@@ -6183,8 +6183,7 @@ non-nil value is found.
           output        (apply #'format format-args))
     ;; Change all "1 units" to "1 unit".
     (while (string-match "\\([^0-9]\\|^\\)1 \\S-+\\(s\\)" output)
-      (setq output (erc-replace-match-subexpression-in-string
-                    "" output (match-string 2 output) 2 (match-beginning 2))))
+      (setq output (replace-match "" nil nil output 2)))
     output))
 
 
diff --git a/lisp/eshell/em-rebind.el b/lisp/eshell/em-rebind.el
index bf5a4bf..7991c63 100644
--- a/lisp/eshell/em-rebind.el
+++ b/lisp/eshell/em-rebind.el
@@ -114,7 +114,6 @@ This is default behavior of shells like bash."
     backward-list
     forward-page
     backward-page
-    forward-point
     forward-paragraph
     backward-paragraph
     backward-prefix-chars
diff --git a/lisp/eshell/esh-io.el b/lisp/eshell/esh-io.el
index 0aa4ec4..b415486 100644
--- a/lisp/eshell/esh-io.el
+++ b/lisp/eshell/esh-io.el
@@ -382,12 +382,7 @@ it defaults to `insert'."
   "Set handle INDEX, using MODE, to point to TARGET."
   (when target
     (if (and (stringp target)
-            (or (cond
-                 ((boundp 'null-device)
-                  (string= target null-device))
-                 ((boundp 'grep-null-device)
-                  (string= target grep-null-device))
-                 (t nil))
+            (or (string= target null-device)
                 (string= target "/dev/null")))
        (aset eshell-current-handles index nil)
       (let ((where (eshell-get-target target mode))
diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el
index d0147b3..8799007 100644
--- a/lisp/eshell/esh-mode.el
+++ b/lisp/eshell/esh-mode.el
@@ -690,46 +690,47 @@ newline."
   "Send the output from PROCESS (STRING) to the interactive display.
 This is done after all necessary filtering has been done."
   (let ((oprocbuf (if process (process-buffer process)
-                   (current-buffer)))
-       (inhibit-point-motion-hooks t)
-       (inhibit-modification-hooks t))
-    (let ((functions eshell-preoutput-filter-functions))
-      (while (and functions string)
-       (setq string (funcall (car functions) string))
-       (setq functions (cdr functions))))
-    (if (and string oprocbuf (buffer-name oprocbuf))
-       (let (opoint obeg oend)
-         (with-current-buffer oprocbuf
-           (setq opoint (point))
-           (setq obeg (point-min))
-           (setq oend (point-max))
-           (let ((buffer-read-only nil)
-                 (nchars (length string))
-                 (ostart nil))
-             (widen)
-             (goto-char eshell-last-output-end)
-             (setq ostart (point))
-             (if (<= (point) opoint)
-                 (setq opoint (+ opoint nchars)))
-             (if (< (point) obeg)
-                 (setq obeg (+ obeg nchars)))
-             (if (<= (point) oend)
-                 (setq oend (+ oend nchars)))
+                    (current-buffer)))
+        (inhibit-point-motion-hooks t)
+        (inhibit-modification-hooks t))
+    (when (and string oprocbuf (buffer-name oprocbuf))
+      (with-current-buffer oprocbuf
+        (let ((functions eshell-preoutput-filter-functions))
+          (while (and functions string)
+            (setq string (funcall (car functions) string))
+            (setq functions (cdr functions))))
+        (when string
+          (let (opoint obeg oend)
+            (setq opoint (point))
+            (setq obeg (point-min))
+            (setq oend (point-max))
+            (let ((buffer-read-only nil)
+                  (nchars (length string))
+                  (ostart nil))
+              (widen)
+              (goto-char eshell-last-output-end)
+              (setq ostart (point))
+              (if (<= (point) opoint)
+                  (setq opoint (+ opoint nchars)))
+              (if (< (point) obeg)
+                  (setq obeg (+ obeg nchars)))
+              (if (<= (point) oend)
+                  (setq oend (+ oend nchars)))
               ;; Let the ansi-color overlay hooks run.
               (let ((inhibit-modification-hooks nil))
                 (insert-before-markers string))
-             (if (= (window-start) (point))
-                 (set-window-start (selected-window)
-                                   (- (point) nchars)))
-             (if (= (point) eshell-last-input-end)
-                 (set-marker eshell-last-input-end
-                             (- eshell-last-input-end nchars)))
-             (set-marker eshell-last-output-start ostart)
-             (set-marker eshell-last-output-end (point))
-             (force-mode-line-update))
-           (narrow-to-region obeg oend)
-           (goto-char opoint)
-           (eshell-run-output-filters))))))
+              (if (= (window-start) (point))
+                  (set-window-start (selected-window)
+                                    (- (point) nchars)))
+              (if (= (point) eshell-last-input-end)
+                  (set-marker eshell-last-input-end
+                              (- eshell-last-input-end nchars)))
+              (set-marker eshell-last-output-start ostart)
+              (set-marker eshell-last-output-end (point))
+              (force-mode-line-update))
+            (narrow-to-region obeg oend)
+            (goto-char opoint)
+            (eshell-run-output-filters)))))))
 
 (defun eshell-run-output-filters ()
   "Run the `eshell-output-filter-functions' on the current output."
diff --git a/lisp/eshell/eshell.el b/lisp/eshell/eshell.el
index 5ffb159..6698ca4 100644
--- a/lisp/eshell/eshell.el
+++ b/lisp/eshell/eshell.el
@@ -384,15 +384,6 @@ corresponding to a successful execution."
              (set status-var eshell-last-command-status))
          (cadr result))))))
 
-;;;_* Reporting bugs
-;;
-;; If you do encounter a bug, on any system, please report
-;; it -- in addition to any particular oddities in your configuration
-;; -- so that the problem may be corrected for the benefit of others.
-
-;;;###autoload
-(define-obsolete-function-alias 'eshell-report-bug 'report-emacs-bug "23.1")
-
 ;;; Code:
 
 (defun eshell-unload-all-modules ()
diff --git a/lisp/ffap.el b/lisp/ffap.el
index ceba9d2..28f566d 100644
--- a/lisp/ffap.el
+++ b/lisp/ffap.el
@@ -1109,6 +1109,121 @@ The arguments CHARS, BEG and END are handled as 
described in
   ;; Added at suggestion of RHOGEE (for ff-paths), 7/24/95.
   "Last string returned by the function `ffap-string-at-point'.")
 
+(defcustom ffap-file-name-with-spaces nil
+  "If non-nil, enable looking for paths with spaces in `ffap-string-at-point'.
+Enabling this variable may lead to `find-file-at-point' guessing
+wrong more often when trying to find a file name intermingled
+with normal text, but can be useful when working on systems that
+normally use spaces in file names (like Microsoft Windows and the
+like)."
+  :type 'boolean
+  :version "28.1")
+
+(defun ffap-search-backward-file-end (&optional dir-separator end)
+  "Search backward position point where file would probably end.
+Optional DIR-SEPARATOR defaults to \"/\". The search maximum is
+`line-end-position' or optional END point.
+
+Suppose the cursor is somewhere that might be near end of file,
+the guessing would position point before punctuation (like comma)
+after the file extension:
+
+  C:\temp\file.log, which contain ....
+  =============================== (before)
+  ---------------- (after)
+
+
+  C:\temp\file.log on Windows or /tmp/file.log on Unix
+  =============================== (before)
+  ---------------- (after)
+
+The strategy is to search backward until DIR-SEPARATOR which defaults to
+\"/\" and then take educated guesses.
+
+Move point and return point if an adjustment was done."
+  (unless dir-separator
+    (setq dir-separator "/"))
+  (let ((opoint (point))
+       point punct end whitespace-p)
+    (when (re-search-backward
+          (regexp-quote dir-separator) (line-beginning-position) t)
+      ;; Move to the beginning of the match..
+      (forward-char 1)
+      ;; ... until typical punctuation.
+      (when (re-search-forward "\\([][<>()\"'`,.:;]\\)"
+                              (or end
+                                  (line-end-position))
+                              t)
+       (setq end (match-end 0))
+       (setq punct (match-string 1))
+       (setq whitespace-p (looking-at "[ \t\r\n]\\|$"))
+       (goto-char end)
+       (cond
+        ((and (string-equal punct ".")
+              whitespace-p)            ;end of sentence
+         (setq point (1- (point))))
+        ((and (string-equal punct ".")
+              (looking-at "[a-zA-Z0-9.]+")) ;possibly file extension
+         (setq point (match-end 0)))
+        (t
+         (setq point (point)))))
+      (goto-char opoint)
+      (when point
+       (goto-char point)
+       point))))
+
+(defun ffap-search-forward-file-end (&optional dir-separator)
+  "Search DIR-SEPARATOR and position point at file's maximum ending.
+This includes spaces.
+Optional DIR-SEPARATOR defaults to \"/\".
+Call `ffap-search-backward-file-end' to refine the ending point."
+  (unless dir-separator
+    (setq dir-separator "/"))
+  (let* ((chars                         ;expected chars in file name
+         (concat "[^][^<>()\"'`;,#*|"
+                 ;; exclude the opposite as we know the separator
+                 (if (string-equal dir-separator "/")
+                     "\\\\"
+                   "/")
+                 "\t\r\n]"))
+        (re (concat
+             chars "*"
+             (if dir-separator
+                 (regexp-quote dir-separator)
+               "/")
+             chars "*")))
+    (when (looking-at re)
+      (goto-char (match-end 0)))))
+
+(defun ffap-dir-separator-near-point ()
+  "Search backward and forward for closest slash or backlash in line.
+Return string slash or backslash. Point is moved to closest position."
+  (let ((point (point))
+       str pos)
+    (when (looking-at ".*?/")
+      (setq str "/"
+           pos (match-end 0)))
+    (when (and (looking-at ".*?\\\\")
+               (or (null pos)
+                  (< (match-end 0) pos)))
+      (setq str "\\"
+           pos (match-end 0)))
+    (goto-char point)
+    (when (and (re-search-backward "/" (line-beginning-position) t)
+               (or (null pos)
+                  (< (- point (point)) (- pos point))))
+      (setq str "/"
+           pos (1+ (point)))) ;1+ to keep cursor at the end of char
+    (goto-char point)
+    (when (and (re-search-backward "\\\\" (line-beginning-position) t)
+               (or (null pos)
+                  (< (- point (point)) (- pos point))))
+      (setq str "\\"
+           pos (1+ (point))))
+    (when pos
+      (goto-char pos))
+    str))
+
 (defun ffap-string-at-point (&optional mode)
   "Return a string of characters from around point.
 
@@ -1128,7 +1243,8 @@ Set the variables `ffap-string-at-point' and
 
 When the region is active and larger than `ffap-max-region-length',
 return an empty string, and set `ffap-string-at-point-region' to '(1 1)."
-  (let* ((args
+  (let* (dir-separator
+         (args
          (cdr
           (or (assq (or mode major-mode) ffap-string-at-point-mode-alist)
               (assq 'file ffap-string-at-point-mode-alist))))
@@ -1137,14 +1253,25 @@ return an empty string, and set 
`ffap-string-at-point-region' to '(1 1)."
          (beg (if region-selected
                  (region-beginning)
                (save-excursion
-                 (skip-chars-backward (car args))
-                 (skip-chars-forward (nth 1 args) pt)
+                 (if (and ffap-file-name-with-spaces
+                          (memq mode '(nil file)))
+                     (when (setq dir-separator (ffap-dir-separator-near-point))
+                       (while (re-search-backward
+                               (regexp-quote dir-separator)
+                               (line-beginning-position) t)
+                         (goto-char (match-beginning 0))))
+                   (skip-chars-backward (car args))
+                   (skip-chars-forward (nth 1 args) pt))
                  (point))))
          (end (if region-selected
                  (region-end)
                (save-excursion
                  (skip-chars-forward (car args))
                  (skip-chars-backward (nth 2 args) pt)
+                 (when (and ffap-file-name-with-spaces
+                            (memq mode '(nil file)))
+                   (ffap-search-forward-file-end dir-separator)
+                   (ffap-search-backward-file-end dir-separator))
                  (point))))
          (region-len (- (max beg end) (min beg end))))
 
@@ -1825,12 +1952,6 @@ Only intended for interactive use."
 (defalias 'find-file-literally-at-point 'ffap-literally)
 
 
-;;; Bug Reporter:
-
-(define-obsolete-function-alias 'ffap-bug 'report-emacs-bug "23.1")
-(define-obsolete-function-alias 'ffap-submit-bug 'report-emacs-bug "23.1")
-
-
 ;;; Hooks for Gnus, VM, Rmail:
 ;;
 ;; If you do not like these bindings, write versions with whatever
diff --git a/lisp/files.el b/lisp/files.el
index 9270f33..975f78e 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -926,7 +926,10 @@ one or more of those symbols."
          (logior (if (memq 'executable predicate) 1 0)
                  (if (memq 'writable predicate) 2 0)
                  (if (memq 'readable predicate) 4 0))))
-  (locate-file-internal filename path suffixes predicate))
+  (let ((file (locate-file-internal filename path suffixes predicate)))
+    (if (and file (string-match "\\.eln\\'" file))
+        (gethash (file-name-nondirectory file) comp-eln-to-el-h)
+      file)))
 
 (defun locate-file-completion-table (dirs suffixes string pred action)
   "Do completion for file names passed to `locate-file'."
@@ -985,14 +988,6 @@ one or more of those symbols."
       (completion-table-with-context
        string-dir names string-file pred action)))))
 
-(defun locate-file-completion (string path-and-suffixes action)
-  "Do completion for file names passed to `locate-file'.
-PATH-AND-SUFFIXES is a pair of lists, (DIRECTORIES . SUFFIXES)."
-  (declare (obsolete locate-file-completion-table "23.1"))
-  (locate-file-completion-table (car path-and-suffixes)
-                                (cdr path-and-suffixes)
-                                string nil action))
-
 (defvar locate-dominating-stop-dir-regexp
   (purecopy 
"\\`\\(?:[\\/][\\/][^\\/]+[\\/]\\|/\\(?:net\\|afs\\|\\.\\.\\.\\)/\\)\\'")
   "Regexp of directory names that stop the search in `locate-dominating-file'.
diff --git a/lisp/forms.el b/lisp/forms.el
index fcb6075..83daabd 100644
--- a/lisp/forms.el
+++ b/lisp/forms.el
@@ -504,12 +504,9 @@ Commands:                        Equivalent keys in 
read-only mode:
        (setq forms-new-record-filter nil)
        (setq forms-modified-record-filter nil)
 
-       ;; If running Emacs 19 under X, setup faces to show read-only and
-       ;; read-write fields.
-       (if (fboundp 'make-face)
-           (progn
-             (make-local-variable 'forms-ro-face)
-             (make-local-variable 'forms-rw-face)))
+       ;; Setup faces to show read-only and read-write fields.
+       (make-local-variable 'forms-ro-face)
+       (make-local-variable 'forms-rw-face)
 
        ;; eval the buffer, should set variables
        ;;(message "forms: processing control file...")
@@ -609,16 +606,14 @@ Commands:                        Equivalent keys in 
read-only mode:
   (setq forms--mode-setup t)
 
   ;; Copy desired faces to the actual variables used by the forms formatter.
-  (if (fboundp 'make-face)
+  (make-local-variable 'forms--ro-face)
+  (make-local-variable 'forms--rw-face)
+  (if forms-read-only
       (progn
-       (make-local-variable 'forms--ro-face)
-       (make-local-variable 'forms--rw-face)
-       (if forms-read-only
-           (progn
-             (setq forms--ro-face forms-ro-face)
-             (setq forms--rw-face forms-ro-face))
-         (setq forms--ro-face forms-ro-face)
-         (setq forms--rw-face forms-rw-face))))
+       (setq forms--ro-face forms-ro-face)
+       (setq forms--rw-face forms-ro-face))
+    (setq forms--ro-face forms-ro-face)
+    (setq forms--rw-face forms-rw-face))
 
   ;; Make more local variables.
   (make-local-variable 'forms--file-buffer)
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index 4363860..c53f81f 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -1913,7 +1913,8 @@ increase the score of each group you read."
   "," gnus-summary-best-unread-article
   "[" gnus-summary-prev-unseen-article
   "]" gnus-summary-next-unseen-article
-  "\M-s" gnus-summary-search-article-forward
+  "\M-s\M-s" gnus-summary-search-article-forward
+  "\M-s\M-r" gnus-summary-search-article-backward
   "\M-r" gnus-summary-search-article-backward
   "\M-S" gnus-summary-repeat-search-article-forward
   "\M-R" gnus-summary-repeat-search-article-backward
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index ab625be..07ff489 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -2751,16 +2751,17 @@ OpenPGP header will be left out.  If all the values are 
nil,
 or `message-openpgp-header' is itself nil, the OpenPGP header
 will not be inserted."
   :type '(choice
-         (const nil :tag "Don't add OpenPGP header")
-         (list (choice (string :tag "ID")
-                       (const nil :tag "No ID"))
+         (const :tag "Don't add OpenPGP header" nil)
+         (list :tag "Use OpenPGP header"
+               (choice (string :tag "ID")
+                       (const :tag "No ID" nil))
                (choice (string :tag "Key")
-                       (const nil :tag "No Key"))
-               (choice (other nil :tag "None")
-                       (const "unprotected" :tag "Unprotected")
-                       (const "sign" :tag "Sign")
-                       (const "encrypt" :tag "Encrypt")
-                       (const "signencrypt" :tag "Sign and Encrypt"))))
+                       (const :tag "No Key" nil))
+               (choice (other :tag "None" nil)
+                       (const :tag "Unprotected" "unprotected")
+                       (const :tag "Sign" "sign")
+                       (const :tag "Encrypt" "encrypt")
+                       (const :tag "Sign and Encrypt" "signencrypt"))))
   :version "28.1")
 
 (defun message-add-openpgp-header ()
@@ -2768,32 +2769,34 @@ will not be inserted."
 
 Header will be constructed as specified in `message-openpgp-header'.
 
-Consider adding this function to `message-send-hook'."
+Consider adding this function to `message-header-setup-hook'"
   ;; See https://tools.ietf.org/html/draft-josefsson-openpgp-mailnews-header
   (when (and message-openpgp-header
             (or (nth 0 message-openpgp-header)
                 (nth 1 message-openpgp-header)
                 (nth 2 message-openpgp-header)))
-    (with-temp-buffer
-      (insert "OpenPGP: ")
-      ;; add ID
-      (let (need-sep)
-       (when (nth 0 message-openpgp-header)
-         (insert "id=" (nth 0 message-openpgp-header))
-         (setq need-sep t))
-       ;; add URL
-       (when (nth 1 message-openpgp-header)
-         (when need-sep (insert "; "))
-         (if (string-match-p ";")
-             (insert "url=\"" (nth 1 message-openpgp-header) "\"")
-           (insert "url=\"" (nth 1 message-openpgp-header) "\""))
-         (setq need-sep t))
-       ;; add preference
-       (when (nth 2 message-openpgp-header)
-         (when need-sep (insert "; "))
-         (insert "preference=" (nth 2 message-openpgp-header))))
-      ;; insert header
-      (message-add-header (buffer-string)))))
+    (message-add-header
+     (with-temp-buffer
+       (insert "OpenPGP: ")
+       ;; add ID
+       (let (need-sep)
+        (when (nth 0 message-openpgp-header)
+          (insert "id=" (nth 0 message-openpgp-header))
+          (setq need-sep t))
+        ;; add URL
+        (when (nth 1 message-openpgp-header)
+          (when need-sep (insert "; "))
+          (if (string-match-p ";")
+              (insert "url=\"" (nth 1 message-openpgp-header) "\"")
+            (insert "url=\"" (nth 1 message-openpgp-header) "\""))
+          (setq need-sep t))
+        ;; add preference
+        (when (nth 2 message-openpgp-header)
+          (when need-sep (insert "; "))
+          (insert "preference=" (nth 2 message-openpgp-header))))
+       ;; insert header
+       (buffer-string)))
+    (message-sort-headers)))
 
 
 
diff --git a/lisp/gnus/mml-smime.el b/lisp/gnus/mml-smime.el
index 4754f37..acddb30 100644
--- a/lisp/gnus/mml-smime.el
+++ b/lisp/gnus/mml-smime.el
@@ -329,7 +329,6 @@ Whether the passphrase is cached at all is controlled by
   (autoload 'epg-verify-string "epg")
   (autoload 'epg-sign-string "epg")
   (autoload 'epg-encrypt-string "epg")
-  (autoload 'epg-passphrase-callback-function "epg")
   (autoload 'epg-context-set-passphrase-callback "epg")
   (autoload 'epg-sub-key-fingerprint "epg")
   (autoload 'epg-configuration "epg-config")
diff --git a/lisp/gnus/mml1991.el b/lisp/gnus/mml1991.el
index 8be1b84..88864ea 100644
--- a/lisp/gnus/mml1991.el
+++ b/lisp/gnus/mml1991.el
@@ -242,7 +242,6 @@ Whether the passphrase is cached at all is controlled by
 (defvar epg-user-id-alist)
 
 (autoload 'epg-make-context "epg")
-(autoload 'epg-passphrase-callback-function "epg")
 (autoload 'epa-select-keys "epa")
 (autoload 'epg-list-keys "epg")
 (autoload 'epg-context-set-armor "epg")
diff --git a/lisp/gnus/mml2015.el b/lisp/gnus/mml2015.el
index d1d150a..45c9bbf 100644
--- a/lisp/gnus/mml2015.el
+++ b/lisp/gnus/mml2015.el
@@ -712,7 +712,6 @@ If set, it overrides the setting of 
`mml2015-sign-with-sender'."
 (autoload 'epg-verify-string "epg")
 (autoload 'epg-sign-string "epg")
 (autoload 'epg-encrypt-string "epg")
-(autoload 'epg-passphrase-callback-function "epg")
 (autoload 'epg-context-set-passphrase-callback "epg")
 (autoload 'epg-key-sub-key-list "epg")
 (autoload 'epg-sub-key-capability "epg")
diff --git a/lisp/gnus/smiley.el b/lisp/gnus/smiley.el
index d41f328..5504a52 100644
--- a/lisp/gnus/smiley.el
+++ b/lisp/gnus/smiley.el
@@ -56,14 +56,11 @@
 
 (defvar smiley-data-directory)
 
-(defcustom smiley-style
-  (if (and (fboundp 'face-attribute)
-          ;; In batch mode, attributes can be unspecified.
-          (condition-case nil
-              (>= (face-attribute 'default :height) 160)
-            (error nil)))
-      'medium
-    'low-color)
+;; In batch mode, attributes can be unspecified.
+(defcustom smiley-style (if (ignore-errors
+                             (>= (face-attribute 'default :height) 160))
+                           'medium
+                         'low-color)
   "Smiley style."
   :type '(choice (const :tag "small, 3 colors" low-color)  ;; 13x14
                 (const :tag "medium, ~10 colors" medium)  ;; 16x16
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index afca2cd..49cdb4e 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -333,10 +333,8 @@ suitable file is found, return nil."
                         object (or (if (symbolp type) type) 'defun))))
          (file-name (if (and true-name
                              (string-match "[.]eln\\'" true-name))
-                        (expand-file-name (concat (file-name-base true-name)
-                                                  ".el")
-                                         (concat (file-name-directory 
true-name)
-                                                  ".."))
+                        (gethash (file-name-nondirectory true-name)
+                                 comp-eln-to-el-h)
                      true-name)))
     (cond
      (autoloaded
diff --git a/lisp/hi-lock.el b/lisp/hi-lock.el
index 33ca40f..0ffe77d 100644
--- a/lisp/hi-lock.el
+++ b/lisp/hi-lock.el
@@ -237,17 +237,11 @@ Instead, each hi-lock command will cycle through the 
faces in
   "Human-readable lighters for `hi-lock-interactive-patterns'.")
 (put 'hi-lock-interactive-lighters 'permanent-local t)
 
-(define-obsolete-variable-alias 'hi-lock-face-history
-                                'hi-lock-face-defaults "23.1")
 (defvar hi-lock-face-defaults
   '("hi-yellow" "hi-pink" "hi-green" "hi-blue" "hi-salmon" "hi-aquamarine"
     "hi-black-b" "hi-blue-b" "hi-red-b" "hi-green-b" "hi-black-hb")
   "Default faces for hi-lock interactive functions.")
 
-(define-obsolete-variable-alias 'hi-lock-regexp-history
-                                'regexp-history
-                                "23.1")
-
 (defvar hi-lock-file-patterns-prefix "Hi-lock"
   "String used to identify hi-lock patterns at the start of files.")
 
diff --git a/lisp/hilit-chg.el b/lisp/hilit-chg.el
index 04a5ccd..ae97bb0 100644
--- a/lisp/hilit-chg.el
+++ b/lisp/hilit-chg.el
@@ -224,9 +224,6 @@ colors then use this, if you want fancier faces then set
 ;; When you invoke highlight-changes-mode, should 
highlight-changes-visible-mode
 ;; be on or off?
 
-(define-obsolete-variable-alias 'highlight-changes-initial-state
-  'highlight-changes-visibility-initial-state "23.1")
-
 (defcustom highlight-changes-visibility-initial-state t
   "Controls whether changes are initially visible in Highlight Changes mode.
 
@@ -236,13 +233,7 @@ When a buffer is in Highlight Changes mode the function
   :type 'boolean
   :group 'highlight-changes)
 
-;; highlight-changes-global-initial-state has been removed
-
-
-
 ;; These are the strings displayed in the mode-line for the minor mode:
-(define-obsolete-variable-alias 'highlight-changes-active-string
-  'highlight-changes-visible-string "23.1")
 
 (defcustom highlight-changes-visible-string " +Chg"
   "The string used when in Highlight Changes mode and changes are visible.
@@ -252,9 +243,6 @@ a string with a leading space."
                 (const :tag "None"  nil))
   :group 'highlight-changes)
 
-(define-obsolete-variable-alias 'highlight-changes-passive-string
-  'highlight-changes-invisible-string "23.1")
-
 (defcustom highlight-changes-invisible-string " -Chg"
   "The string used when in Highlight Changes mode and changes are hidden.
 This should be set to nil if no indication is desired, or to
@@ -957,10 +945,6 @@ changes are made, so \\[highlight-changes-next-change] and
 (define-globalized-minor-mode global-highlight-changes-mode
   highlight-changes-mode highlight-changes-mode-turn-on)
 
-(define-obsolete-function-alias
- 'global-highlight-changes
-  'global-highlight-changes-mode "23.1")
-
 (defun highlight-changes-mode-turn-on ()
   "See if Highlight Changes mode should be turned on for this buffer.
 This is called when `global-highlight-changes-mode' is turned on."
diff --git a/lisp/htmlfontify.el b/lisp/htmlfontify.el
index 6265537..4d65397 100644
--- a/lisp/htmlfontify.el
+++ b/lisp/htmlfontify.el
@@ -556,10 +556,7 @@ If a window system is unavailable, calls 
`hfy-fallback-color-values'."
        '(1 2 3))
     ;;(message ">> %s" color)
     (if window-system
-        (if (fboundp 'color-values)
-            (color-values color)
-          ;;(message "[%S]" window-system)
-          (x-color-values color))
+        (color-values color)
       ;; blarg - tty colors are no good - go fetch some X colors:
       (hfy-fallback-color-values color))))
 (define-obsolete-function-alias 'hfy-colour-vals #'hfy-color-vals "27.1")
diff --git a/lisp/icomplete.el b/lisp/icomplete.el
index 3747ae3..8a68df8 100644
--- a/lisp/icomplete.el
+++ b/lisp/icomplete.el
@@ -75,7 +75,11 @@ everything preceding the ~/ is discarded so the interactive
 selection process starts again from the user's $HOME.")
 
 (defcustom icomplete-show-matches-on-no-input nil
-  "When non-nil, show completions when first prompting for input."
+  "When non-nil, show completions when first prompting for input.
+This also means that if you traverse the list of completions with
+commands like `C-.' and just hit `C-j' (enter) without typing any
+characters, the match under point will be chosen instead of the
+default."
   :type 'boolean
   :version "24.4")
 
@@ -709,7 +713,10 @@ matches exist."
                (push comp prospects)
              (setq limit t))))
        (setq prospects (nreverse prospects))
-       ;; Decorate first of the prospects.
+        ;; Return the first match if the user hits enter.
+        (when icomplete-show-matches-on-no-input
+          (setq completion-content-when-empty (car prospects)))
+        ;; Decorate first of the prospects.
        (when prospects
          (let ((first (copy-sequence (pop prospects))))
            (put-text-property 0 (length first)
diff --git a/lisp/ido.el b/lisp/ido.el
index e834916..c83b700 100644
--- a/lisp/ido.el
+++ b/lisp/ido.el
@@ -1523,8 +1523,10 @@ Removes badly formatted data and ignored directories."
   (remove-function read-file-name-function #'ido-read-file-name)
   (remove-function read-buffer-function #'ido-read-buffer)
   (when ido-everywhere
-    (add-function :override read-file-name-function #'ido-read-file-name)
-    (add-function :override read-buffer-function #'ido-read-buffer)))
+    (if (not ido-mode)
+        (ido-mode 'both)
+      (add-function :override read-file-name-function #'ido-read-file-name)
+      (add-function :override read-buffer-function #'ido-read-buffer))))
 
 (defvar ido-minor-mode-map-entry nil)
 
@@ -2216,7 +2218,10 @@ If cursor is not at the end of the user input, move to 
end of input."
        ((and ido-enable-virtual-buffers
             ido-virtual-buffers
             (setq filename (assoc buf ido-virtual-buffers)))
-       (ido-visit-buffer (find-file-noselect (cdr filename)) method t))
+        (if (eq method 'kill)
+            (setq recentf-list
+                 (delete (cdr filename) recentf-list))
+         (ido-visit-buffer (find-file-noselect (cdr filename)) method t)))
 
        ((and (eq ido-create-new-buffer 'prompt)
             (null require-match)
@@ -4073,6 +4078,7 @@ Record command in `command-history' if optional RECORD is 
non-nil."
       (setq buffer (buffer-name buffer)))
   (let (win newframe)
     (cond
+     ;; "Killing" of virtual buffers is handled in `ido-buffer-internal'.
      ((eq method 'kill)
       (if record
          (ido-record-command 'kill-buffer buffer))
diff --git a/lisp/image/gravatar.el b/lisp/image/gravatar.el
index d1091e5..3543be6 100644
--- a/lisp/image/gravatar.el
+++ b/lisp/image/gravatar.el
@@ -39,6 +39,7 @@
   "Whether to cache retrieved gravatars."
   :type 'boolean
   :group 'gravatar)
+(make-obsolete-variable 'gravatar-automatic-caching nil "28.1")
 
 (defcustom gravatar-cache-ttl 2592000
   "Time to live in seconds for gravatar cache entries.
@@ -48,6 +49,7 @@ is retrieved anew.  The default value is 30 days."
   ;; Restricted :type to number of seconds.
   :version "27.1"
   :group 'gravatar)
+(make-obsolete-variable 'gravatar-cache-ttl nil "28.1")
 
 (defcustom gravatar-rating "g"
   "Most explicit Gravatar rating level to allow.
@@ -156,18 +158,58 @@ to track whether you're reading a specific mail."
         (setq func
               (lambda (result)
                 (cond
-                 (result
-                  (funcall callback (format "%s://%s/avatar"
-                                            (cdar records) result)))
-                 ((> (length records) 1)
-                  (pop records)
+                 ((and
+                   result               ;there is a result
+                   (let* ((data (mapcar (lambda (record)
+                                          (dns-get 'data (cdr record)))
+                                        (dns-get 'answers result)))
+                          (priorities (mapcar (lambda (r)
+                                                (dns-get 'priority r))
+                                              data))
+                          (max-priority (if priorities
+                                            (apply #'max priorities)
+                                          0))
+                          (sum 0) top)
+                     ;; Attempt to find all records with the same maximal
+                     ;; priority, and calculate the sum of their weights.
+                     (dolist (ent data)
+                       (when (= max-priority (dns-get 'priority ent))
+                         (setq sum (+ sum (dns-get 'weight ent)))
+                         (push ent top)))
+                     ;; In case there is more than one maximal priority
+                     ;; record, choose one at random, while taking the
+                     ;; individual record weights into consideration.
+                     (catch 'done
+                       (dolist (ent top)
+                         (when (and (or (= 0 sum)
+                                        (<= 0 (random sum)
+                                            (dns-get 'weight ent)))
+                                    ;; Ensure that port and domain data are
+                                    ;; valid. In case non of the results
+                                    ;; were valid, `catch' will evaluate to
+                                    ;; nil, and the next cond clause will be
+                                    ;; tested.
+                                    (<= 1 (dns-get 'port ent) 65535)
+                                    (string-match-p "\\`[-.0-9A-Za-z]+\\'"
+                                                    (dns-get 'target ent)))
+                           (funcall callback
+                                    (url-normalize-url
+                                     (format "%s://%s:%s/avatar"
+                                             (cdar records)
+                                             (dns-get 'target ent)
+                                             (dns-get 'port ent))))
+                           (throw 'done t))
+                         (setq sum (- sum (dns-get 'weight ent))))))))
+                 ((setq records (cdr records))
+                  ;; In case there are at least two methods.
                   (dns-query-asynchronous
                    (concat (caar records) "._tcp." domain)
                    func 'SRV))
-                 (t
+                 (t                     ;fallback
                   (funcall callback "https://seccdn.libravatar.org/avatar";)))))
         (dns-query-asynchronous
-         (concat (caar records) "._tcp." domain) func 'SRV)))))
+         (concat (caar records) "._tcp." domain)
+         func 'SRV t)))))
 
 (defun gravatar-hash (mail-address)
   "Return the Gravatar hash for MAIL-ADDRESS."
@@ -206,19 +248,50 @@ to track whether you're reading a specific mail."
          (search-forward "\n\n" nil t)
          (buffer-substring (point) (point-max)))))
 
+(defvar gravatar--cache (make-hash-table :test 'equal)
+  "Cache for gravatars.")
+
 ;;;###autoload
 (defun gravatar-retrieve (mail-address callback &optional cbargs)
   "Asynchronously retrieve a gravatar for MAIL-ADDRESS.
 When finished, call CALLBACK as (apply CALLBACK GRAVATAR CBARGS),
 where GRAVATAR is either an image descriptor, or the symbol
 `error' if the retrieval failed."
-  (gravatar-build-url
-   mail-address
-   (lambda (url)
-     (if (url-cache-expired url gravatar-cache-ttl)
-         (url-retrieve url #'gravatar-retrieved (list callback cbargs) t)
-       (with-current-buffer (url-fetch-from-cache url)
-         (gravatar-retrieved () callback cbargs))))))
+  (let ((cached (gethash mail-address gravatar--cache)))
+    (gravatar--prune-cache)
+    (if cached
+        (apply callback (cdr cached) cbargs)
+      ;; Nothing in the cache, fetch it.
+      (gravatar-build-url
+       mail-address
+       (lambda (url)
+         (url-retrieve
+          url
+          (lambda (status)
+            (let* ((data (and (not (plist-get status :error))
+                              (gravatar-get-data)))
+                   (image (and data (create-image data nil t))))
+              ;; Store the image in the cache.
+              (when image
+                (setf (gethash mail-address gravatar--cache)
+                      (cons (time-convert (current-time) 'integer)
+                            image)))
+              (prog1
+                  (apply callback (if data image 'error) cbargs)
+                (kill-buffer))))
+          nil t))))))
+
+(defun gravatar--prune-cache ()
+  (let ((expired nil)
+        (time (- (time-convert (current-time) 'integer)
+                 ;; Twelve hours.
+                 (* 12 60 60))))
+    (maphash (lambda (key val)
+               (when (< (car val) time)
+                 (push key expired)))
+             gravatar--cache)
+    (dolist (key expired)
+      (remhash key gravatar--cache))))
 
 ;;;###autoload
 (defun gravatar-retrieve-synchronously (mail-address)
@@ -229,10 +302,8 @@ retrieval failed."
     (gravatar-build-url mail-address (lambda (u) (setq url u)))
     (while (not url)
       (sleep-for 0.01))
-    (with-current-buffer (if (url-cache-expired url gravatar-cache-ttl)
-                             (url-retrieve-synchronously url t)
-                           (url-fetch-from-cache url))
-      (gravatar-retrieved () #'identity))))
+    (with-current-buffer (url-retrieve-synchronously url t)
+      (gravatar-retrieved nil #'identity))))
 
 (defun gravatar-retrieved (status cb &optional cbargs)
   "Handle Gravatar response data in current buffer.
@@ -241,10 +312,6 @@ an image descriptor, or the symbol `error' on failure.
 This function is intended as a callback for `url-retrieve'."
   (let ((data (unless (plist-get status :error)
                 (gravatar-get-data))))
-    (and data                      ; Only cache on success.
-         url-current-object        ; Only cache if not already cached.
-         gravatar-automatic-caching
-         (url-store-in-cache))
     (prog1 (apply cb (if data (create-image data nil t) 'error) cbargs)
       (kill-buffer))))
 
diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el
index 7714a77..5fe931d 100644
--- a/lisp/international/mule-cmds.el
+++ b/lisp/international/mule-cmds.el
@@ -2968,11 +2968,6 @@ on encoding."
 ;; Doc said "obsolete" in 23.1, this statement only added in 24.1.
 (make-obsolete 'unify-8859-on-decoding-mode "don't use it." "23.1")
 
-(defvar nonascii-insert-offset 0)
-(make-obsolete-variable 'nonascii-insert-offset "do not use it." "23.1")
-(defvar nonascii-translation-table nil)
-(make-obsolete-variable 'nonascii-translation-table "do not use it." "23.1")
-
 (defvar ucs-names nil
   "Hash table of cached CHAR-NAME keys to CHAR-CODE values.")
 
diff --git a/lisp/international/mule-diag.el b/lisp/international/mule-diag.el
index 80e78ef..b13bde5 100644
--- a/lisp/international/mule-diag.el
+++ b/lisp/international/mule-diag.el
@@ -200,10 +200,6 @@ Character sets for defining other charsets, or for 
backward compatibility
 ;;;               (charset-iso-graphic-plane charset)
                   (charset-description charset)))))
 
-(defvar non-iso-charset-alist nil
-  "Obsolete.")
-(make-obsolete-variable 'non-iso-charset-alist "no longer relevant." "23.1")
-
 ;; A variable to hold charset input history.
 (defvar charset-history nil)
 
diff --git a/lisp/international/mule-util.el b/lisp/international/mule-util.el
index 5cc10b1..660ac58 100644
--- a/lisp/international/mule-util.el
+++ b/lisp/international/mule-util.el
@@ -275,15 +275,6 @@ operations such as `find-coding-systems-region'."
 (put 'with-coding-priority 'edebug-form-spec t)
 
 ;;;###autoload
-(defmacro detect-coding-with-priority (from to priority-list)
-  "Detect a coding system of the text between FROM and TO with PRIORITY-LIST.
-PRIORITY-LIST is an alist of coding categories vs the corresponding
-coding systems ordered by priority."
-  (declare (obsolete with-coding-priority "23.1"))
-  `(with-coding-priority (mapcar #'cdr ,priority-list)
-     (detect-coding-region ,from ,to)))
-
-;;;###autoload
 (defun detect-coding-with-language-environment (from to lang-env)
   "Detect a coding system for the text between FROM and TO with LANG-ENV.
 The detection takes into account the coding system priorities for the
diff --git a/lisp/international/mule.el b/lisp/international/mule.el
index 5fb04bc..958fc0d 100644
--- a/lisp/international/mule.el
+++ b/lisp/international/mule.el
@@ -409,16 +409,6 @@ PLIST (property list) may contain any type of information 
a user
 ;; because that makes a bootstrapping problem
 ;; if you need to recompile all the Lisp files using interpreted code.
 
-(defun charset-id (_charset)
-  "Always return 0.  This is provided for backward compatibility."
-  (declare (obsolete nil "23.1"))
-  0)
-
-(defmacro charset-bytes (_charset)
-  "Always return 0.  This is provided for backward compatibility."
-  (declare (obsolete nil "23.1"))
-  0)
-
 (defun get-charset-property (charset propname)
   "Return the value of CHARSET's PROPNAME property.
 This is the last value stored with
@@ -464,19 +454,8 @@ Return -1 if charset isn't an ISO 2022 one."
   "Return long name of CHARSET."
   (plist-get (charset-plist charset) :long-name))
 
-(defun charset-list ()
-  "Return list of all charsets ever defined."
-  (declare (obsolete charset-list "23.1"))
-  charset-list)
-
 
 ;;; CHARACTER
-(define-obsolete-function-alias 'char-valid-p 'characterp "23.1")
-
-(defun generic-char-p (_char)
-  "Always return nil.  This is provided for backward compatibility."
-  (declare (obsolete nil "23.1"))
-  nil)
 
 (defun make-char-internal (charset-id &optional code1 code2)
   (let ((charset (aref emacs-mule-charset-table charset-id)))
@@ -1086,14 +1065,11 @@ formats (e.g. iso-latin-1-unix, koi8-r-dos)."
              (setq codings (cons alias codings))))))
     codings))
 
-(defconst char-coding-system-table nil
-  "It exists just for backward compatibility, and the value is always nil.")
-(make-obsolete-variable 'char-coding-system-table nil "23.1")
-
 (defun transform-make-coding-system-args (name type &optional doc-string props)
   "For internal use only.
 Transform XEmacs style args for `make-coding-system' to Emacs style.
 Value is a list of transformed arguments."
+  (declare (obsolete nil "28.1"))
   (let ((mnemonic (string-to-char (or (plist-get props 'mnemonic) "?")))
        (eol-type (plist-get props 'eol-type))
        properties tmp)
@@ -1171,106 +1147,6 @@ Value is a list of transformed arguments."
       (error "unsupported XEmacs style make-coding-style arguments: %S"
             `(,name ,type ,doc-string ,props))))))
 
-(defun make-coding-system (coding-system type mnemonic doc-string
-                                        &optional
-                                        flags
-                                        properties
-                                        eol-type)
-  "Define a new coding system CODING-SYSTEM (symbol).
-This function is provided for backward compatibility."
-  (declare (obsolete define-coding-system "23.1"))
-  ;; For compatibility with XEmacs, we check the type of TYPE.  If it
-  ;; is a symbol, perhaps, this function is called with XEmacs-style
-  ;; arguments.  Here, try to transform that kind of arguments to
-  ;; Emacs style.
-  (if (symbolp type)
-      (let ((args (transform-make-coding-system-args coding-system type
-                                                    mnemonic doc-string)))
-       (setq coding-system (car args)
-             type (nth 1 args)
-             mnemonic (nth 2 args)
-             doc-string (nth 3 args)
-             flags (nth 4 args)
-             properties (nth 5 args)
-             eol-type (nth 6 args))))
-
-  (setq type
-       (cond ((eq type 0) 'emacs-mule)
-             ((eq type 1) 'shift-jis)
-             ((eq type 2) 'iso2022)
-             ((eq type 3) 'big5)
-             ((eq type 4) 'ccl)
-             ((eq type 5) 'raw-text)
-             (t
-              (error "Invalid coding system type: %s" type))))
-
-  (setq properties
-       (let ((plist nil) key)
-         (dolist (elt properties)
-           (setq key (car elt))
-           (cond ((eq key 'post-read-conversion)
-                  (setq key :post-read-conversion))
-                 ((eq key 'pre-write-conversion)
-                  (setq key :pre-write-conversion))
-                 ((eq key 'translation-table-for-decode)
-                  (setq key :decode-translation-table))
-                 ((eq key 'translation-table-for-encode)
-                  (setq key :encode-translation-table))
-                 ((eq key 'safe-charsets)
-                  (setq key :charset-list))
-                 ((eq key 'mime-charset)
-                  (setq key :mime-charset))
-                 ((eq key 'valid-codes)
-                  (setq key :valids)))
-           (setq plist (plist-put plist key (cdr elt))))
-         plist))
-  (setq properties (plist-put properties :mnemonic mnemonic))
-  (plist-put properties :coding-type type)
-  (cond ((eq eol-type 0) (setq eol-type 'unix))
-       ((eq eol-type 1) (setq eol-type 'dos))
-       ((eq eol-type 2) (setq eol-type 'mac))
-       ((vectorp eol-type) (setq eol-type nil)))
-  (plist-put properties :eol-type eol-type)
-
-  (cond
-   ((eq type 'iso2022)
-    (plist-put properties :flags
-              (list (and (or (consp (nth 0 flags))
-                             (consp (nth 1 flags))
-                             (consp (nth 2 flags))
-                             (consp (nth 3 flags))) 'designation)
-                    (or (nth 4 flags) 'long-form)
-                    (and (nth 5 flags) 'ascii-at-eol)
-                    (and (nth 6 flags) 'ascii-at-cntl)
-                    (and (nth 7 flags) '7-bit)
-                    (and (nth 8 flags) 'locking-shift)
-                    (and (nth 9 flags) 'single-shift)
-                    (and (nth 10 flags) 'use-roman)
-                    (and (nth 11 flags) 'use-oldjis)
-                    (or (nth 12 flags) 'direction)
-                    (and (nth 13 flags) 'init-at-bol)
-                    (and (nth 14 flags) 'designate-at-bol)
-                    (and (nth 15 flags) 'safe)
-                    (and (nth 16 flags) 'latin-extra)))
-    (plist-put properties :designation
-              (let ((vec (make-vector 4 nil)))
-                (dotimes (i 4)
-                  (let ((spec (nth i flags)))
-                    (if (eq spec t)
-                        (aset vec i '(94 96))
-                    (if (consp spec)
-                        (progn
-                          (if (memq t spec)
-                              (setq spec (append (delq t spec) '(94 96))))
-                          (aset vec i spec))))))
-                vec)))
-
-   ((eq type 'ccl)
-    (plist-put properties :ccl-decoder (car flags))
-    (plist-put properties :ccl-encoder (cdr flags))))
-
-  (apply 'define-coding-system coding-system doc-string properties))
-
 (defun merge-coding-systems (first second)
   "Fill in any unspecified aspects of coding system FIRST from SECOND.
 Return the resulting coding system."
@@ -1617,15 +1493,6 @@ This setting is effective for the next communication 
only."
 
   (setq next-selection-coding-system coding-system))
 
-(defun set-coding-priority (arg)
-  "Set priority of coding categories according to ARG.
-ARG is a list of coding categories ordered by priority.
-
-This function is provided for backward compatibility."
-  (declare (obsolete set-coding-system-priority "23.1"))
-  (apply 'set-coding-system-priority
-        (mapcar #'(lambda (x) (symbol-value x)) arg)))
-
 ;;; X selections
 
 (defvar ctext-non-standard-encodings-alist
diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el
index ae58bfc..7077925 100644
--- a/lisp/ldefs-boot.el
+++ b/lisp/ldefs-boot.el
@@ -31062,7 +31062,7 @@ values), despite potential performance issues, type 
\\[so-long-revert].
 
 Use \\[so-long-commentary] for more information.
 
-Use \\[so-long-customize] to configure the behavior.
+Use \\[so-long-customize] to configure the behaviour.
 
 \(fn)" t nil)
 
@@ -31099,7 +31099,7 @@ or call the function `global-so-long-mode'.")
 (custom-autoload 'global-so-long-mode "so-long" nil)
 
 (autoload 'global-so-long-mode "so-long" "\
-Toggle automated performance mitigation for files with long lines.
+Toggle automated performance mitigations for files with long lines.
 
 If called interactively, enable Global So-Long mode if ARG is
 positive, and disable it if ARG is zero or negative.  If called from
@@ -31118,7 +31118,7 @@ When such files are detected by `so-long-predicate', we 
invoke the selected
 
 Use \\[so-long-commentary] for more information.
 
-Use \\[so-long-customize] to configure the behavior.
+Use \\[so-long-customize] to configure the behaviour.
 
 \(fn &optional ARG)" t nil)
 
diff --git a/lisp/loadup.el b/lisp/loadup.el
index 31843fc..aaa5888 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -449,33 +449,33 @@ lost after dumping")))
 ;; At this point, we're ready to resume undo recording for scratch.
 (buffer-enable-undo "*scratch*")
 
-(when (native-comp-available-p)
+(when (boundp 'comp-ctxt)
   ;; Fix the compilation unit filename to have it working when
   ;; when installed or if the source directory got moved.  This is set to be
   ;; a pair in the form: (rel-path-from-install-bin . rel-path-from-local-bin).
   (let ((h (make-hash-table :test #'eq))
-        (lisp-src-dir (expand-file-name (concat default-directory "../lisp")))
         (bin-dest-dir (cadr (member "--bin-dest" command-line-args)))
-        (lisp-dest-dir (cadr (member "--lisp-dest" command-line-args))))
-    (mapatoms (lambda (s)
-                (let ((f (symbol-function s)))
-                  (when (subr-native-elisp-p f)
-                    (puthash (subr-native-comp-unit f) nil h)))))
-    (maphash (lambda (cu _)
-               (native-comp-unit-set-file
-                cu
-               (cons
-                 ;; Relative path from the installed binary.
-                 (file-relative-name
-                  (concat lisp-dest-dir
-                         (replace-regexp-in-string
-                           (regexp-quote lisp-src-dir) ""
-                           (native-comp-unit-file cu)))
-                 bin-dest-dir)
-                 ;; Relative path from the built uninstalled binary.
-                 (file-relative-name (native-comp-unit-file cu)
-                                     invocation-directory))))
-            h)))
+        (eln-dest-dir (cadr (member "--eln-dest" command-line-args))))
+    (when (and bin-dest-dir eln-dest-dir)
+      (setq eln-dest-dir
+            (concat eln-dest-dir "eln-cache/" comp-native-path-postfix "/"))
+      (mapatoms (lambda (s)
+                  (let ((f (symbol-function s)))
+                    (when (subr-native-elisp-p f)
+                      (puthash (subr-native-comp-unit f) nil h)))))
+      (maphash (lambda (cu _)
+                 (native-comp-unit-set-file
+                  cu
+                 (cons
+                   ;; Relative path from the installed binary.
+                   (file-relative-name (concat eln-dest-dir
+                                               (file-name-nondirectory
+                                                (native-comp-unit-file cu)))
+                                       bin-dest-dir)
+                   ;; Relative path from the built uninstalled binary.
+                   (file-relative-name (native-comp-unit-file cu)
+                                       invocation-directory))))
+              h))))
 
 (when (hash-table-p purify-flag)
   (let ((strings 0)
diff --git a/lisp/mail/binhex.el b/lisp/mail/binhex.el
index 896f82d..2c77f88 100644
--- a/lisp/mail/binhex.el
+++ b/lisp/mail/binhex.el
@@ -83,10 +83,8 @@ input and write the converted data to its standard output."
   "^[^:]...............................................................$")
 (defconst binhex-end-line ":$")                ; unused
 
-(defvar binhex-temporary-file-directory
-  (cond ((fboundp 'temp-directory) (temp-directory))
-       ((boundp 'temporary-file-directory) temporary-file-directory)
-       ("/tmp/")))
+(make-obsolete-variable 'binhex-temporary-file-directory
+                        'temporary-file-directory "28.1")
 
 (defun binhex-insert-char (char &optional count ignored buffer)
   "Insert COUNT copies of CHARACTER into BUFFER."
@@ -285,7 +283,7 @@ If HEADER-ONLY is non-nil only decode header and return 
filename."
        (file-name (expand-file-name
                    (concat (binhex-decode-region-internal start end t)
                            ".data")
-                   binhex-temporary-file-directory)))
+                   temporary-file-directory)))
     (save-excursion
       (goto-char start)
       (when (re-search-forward binhex-begin-line nil t)
@@ -296,7 +294,7 @@ If HEADER-ONLY is non-nil only decode header and return 
filename."
                                  (generate-new-buffer " *binhex-work*")))
                (buffer-disable-undo work-buffer)
                (insert-buffer-substring cbuf firstline end)
-               (cd binhex-temporary-file-directory)
+               (cd temporary-file-directory)
                (apply 'call-process-region
                       (point-min)
                       (point-max)
diff --git a/lisp/mail/emacsbug.el b/lisp/mail/emacsbug.el
index efbc066..6b9e1db 100644
--- a/lisp/mail/emacsbug.el
+++ b/lisp/mail/emacsbug.el
@@ -324,18 +324,6 @@ usually do not have translators for other 
languages.\n\n")))
     (let ((os (ignore-errors (report-emacs-bug--os-description))))
       (if (stringp os)
           (insert "System Description: " os "\n\n")))
-    (let ((message-buf (get-buffer "*Messages*")))
-      (if message-buf
-         (let (beg-pos
-               (end-pos message-end-point))
-           (with-current-buffer message-buf
-             (goto-char end-pos)
-             (forward-line -10)
-             (setq beg-pos (point)))
-            (terpri (current-buffer) t)
-           (insert "Recent messages:\n")
-           (insert-buffer-substring message-buf beg-pos end-pos))))
-    (insert "\n")
     (when (and system-configuration-options
               (not (equal system-configuration-options "")))
       (insert "Configured using:\n 'configure "
diff --git a/lisp/mail/flow-fill.el b/lisp/mail/flow-fill.el
index af3b493..f4b5503 100644
--- a/lisp/mail/flow-fill.el
+++ b/lisp/mail/flow-fill.el
@@ -131,31 +131,37 @@ lines."
             (goto-char (match-end 0))
             (unless (looking-at " ")
               (insert " "))
-            (end-of-line)
-            (when (and (not (eobp))
-                       (save-excursion
-                         (forward-line 1)
-                         (looking-at (format "\\(%s ?\\)[^>]" prefix))))
-              ;; Delete the newline and the quote at the start of the
-              ;; next line.
-              (delete-region (point) (match-end 1))
-              (ignore-errors
+            (while (and (eq (char-before (line-end-position)) ?\s)
+                        (not (eobp))
+                        (save-excursion
+                          (forward-line 1)
+                          (looking-at (format "\\(%s ?\\)[^>]" prefix))))
+              (end-of-line)
+              (when (and (not (eobp))
+                         (save-excursion
+                           (forward-line 1)
+                           (looking-at (format "\\(%s ?\\)[^>]" prefix))))
+                ;; Delete the newline and the quote at the start of the
+                ;; next line.
+                (delete-region (point) (match-end 1))))
+                (ignore-errors
                  (let ((fill-prefix (concat prefix " "))
                        adaptive-fill-mode)
                    (fill-region (line-beginning-position)
                                  (line-end-position)
-                                'left 'nosqueeze))))))
-         (t
+                                'left 'nosqueeze)))))
+          (t
           ;; Delete the newline.
           (when (eq (following-char) ?\s)
             (delete-char 1))
           ;; Hack: Don't do the flowing on the signature line.
           (when (and (not (looking-at "-- $"))
                      (eq (char-before (line-end-position)) ?\s))
-            (end-of-line)
-            (when delete-space
-              (delete-char -1))
-            (delete-char 1)
+            (while (eq (char-before (line-end-position)) ?\s)
+              (end-of-line)
+              (when delete-space
+                (delete-char -1))
+              (delete-char 1))
             (ignore-errors
                (let ((fill-prefix ""))
                  (fill-region (line-beginning-position)
diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el
index 44cde7c..312baff 100644
--- a/lisp/mail/rmail.el
+++ b/lisp/mail/rmail.el
@@ -521,25 +521,6 @@ still the current message in the Rmail buffer.")
 (defvar rmail-mmdf-delim2 "^\001\001\001\001\n"
   "Regexp marking the end of an mmdf message.")
 
-;; FIXME Post-mbox, this is now unused.
-;; In Emacs-22, this was called:
-;;  i) the very first time a message was shown.
-;; ii) when toggling the headers to the normal state, every time.
-;; It's not clear what it should do now, since there is nothing that
-;; records when a message is shown for the first time (unseen is not
-;; necessarily the same thing).
-;; See https://lists.gnu.org/r/emacs-devel/2009-03/msg00013.html
-(defcustom rmail-message-filter nil
-  "If non-nil, a filter function for new messages in RMAIL.
-Called with region narrowed to the message, including headers,
-before obeying `rmail-ignored-headers'."
-  :group 'rmail-headers
-  :type '(choice (const nil) function))
-
-(make-obsolete-variable 'rmail-message-filter
-                       "it is not used (try `rmail-show-message-hook')."
-                       "23.1")
-
 (defcustom rmail-automatic-folder-directives nil
   "List of directives specifying how to automatically file messages.
 Whenever Rmail shows a message in the folder that `rmail-file-name'
diff --git a/lisp/mail/rmailedit.el b/lisp/mail/rmailedit.el
index ba6ebad..3026283 100644
--- a/lisp/mail/rmailedit.el
+++ b/lisp/mail/rmailedit.el
@@ -63,9 +63,7 @@ This function runs the hooks `text-mode-hook' and 
`rmail-edit-mode-hook'.
     (use-local-map rmail-edit-map)
     (setq major-mode 'rmail-edit-mode)
     (setq mode-name "RMAIL Edit")
-    (if (boundp 'mode-line-modified)
-       (setq mode-line-modified (default-value 'mode-line-modified))
-      (setq mode-line-format (default-value 'mode-line-format)))
+    (setq mode-line-modified (default-value 'mode-line-modified))
     ;; Don't turn off auto-saving based on the size of the buffer
     ;; because that code does not understand buffer-swapping.
     (make-local-variable 'auto-save-include-big-deletions)
diff --git a/lisp/mail/uudecode.el b/lisp/mail/uudecode.el
index 9423275..945bff3 100644
--- a/lisp/mail/uudecode.el
+++ b/lisp/mail/uudecode.el
@@ -61,10 +61,8 @@ input and write the converted data to its standard output."
       (setq str (concat str "[^a-z]")))
     (concat str ".?$")))
 
-(defvar uudecode-temporary-file-directory
-  (cond ((fboundp 'temp-directory) (temp-directory))
-       ((boundp 'temporary-file-directory) temporary-file-directory)
-       ("/tmp")))
+(make-obsolete-variable 'uudecode-temporary-file-directory
+                        'temporary-file-directory "28.1")
 
 ;;;###autoload
 (defun uudecode-decode-region-external (start end &optional file-name)
@@ -86,13 +84,7 @@ used is specified by `uudecode-decoder-program'."
                                               (match-string 1)))))
        (setq tempfile (if file-name
                           (expand-file-name file-name)
-                          (if (fboundp 'make-temp-file)
-                              (let ((temporary-file-directory
-                                     uudecode-temporary-file-directory))
-                                (make-temp-file "uu"))
-                            (expand-file-name
-                             (make-temp-name "uu")
-                             uudecode-temporary-file-directory))))
+                        (make-temp-file "uu")))
        (let ((cdir default-directory)
              (default-process-coding-system nil))
          (unwind-protect
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index d2c3f90..641a2e5 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -685,13 +685,6 @@ for use at QPOS."
                completions)
        qboundary))))
 
-;; (defmacro complete-in-turn (a b) `(completion-table-in-turn ,a ,b))
-;; (defmacro dynamic-completion-table (fun) `(completion-table-dynamic ,fun))
-(define-obsolete-function-alias
-  'complete-in-turn #'completion-table-in-turn "23.1")
-(define-obsolete-function-alias
-  'dynamic-completion-table #'completion-table-dynamic "23.1")
-
 ;;; Minibuffer completion
 
 (defgroup minibuffer nil
@@ -1126,6 +1119,7 @@ completion candidates than this number."
 (defvar-local completion-all-sorted-completions nil)
 (defvar-local completion--all-sorted-completions-location nil)
 (defvar completion-cycling nil)      ;Function that takes down the cycling map.
+(defvar completion-content-when-empty nil)
 
 (defvar completion-fail-discreetly nil
   "If non-nil, stay quiet when there  is no match.")
@@ -1510,8 +1504,13 @@ If `minibuffer-completion-confirm' is 
`confirm-after-completion',
 COMPLETION-FUNCTION is called if the current buffer's content does not
 appear to be a match."
     (cond
-     ;; Allow user to specify null string
-   ((= beg end) (funcall exit-function))
+     ;; Allow user to specify null string.  In the case that
+     ;; `completion-content-when-empty' is set, use that instead.
+     ((= beg end)
+      (when completion-content-when-empty
+        (completion--replace beg end completion-content-when-empty))
+      (funcall exit-function))
+
      ((test-completion (buffer-substring beg end)
                        minibuffer-completion-table
                        minibuffer-completion-predicate)
@@ -1770,9 +1769,6 @@ It also eliminates runs of equal strings."
                              ;; Round up to a whole number of columns.
                              (* colwidth (ceiling length colwidth))))))))))))
 
-(defvar completion-common-substring nil)
-(make-obsolete-variable 'completion-common-substring nil "23.1")
-
 (defvar completion-setup-hook nil
   "Normal hook run at the end of setting up a completion list buffer.
 When this hook is run, the current buffer is the one in which the
@@ -1864,11 +1860,7 @@ It can find the completion buffer in `standard-output'."
         (insert "Possible completions are:\n")
         (completion--insert-strings completions))))
 
-  ;; The hilit used to be applied via completion-setup-hook, so there
-  ;; may still be some code that uses completion-common-substring.
-  (with-no-warnings
-    (let ((completion-common-substring common-substring))
-      (run-hooks 'completion-setup-hook)))
+  (run-hooks 'completion-setup-hook)
   nil)
 
 (defvar completion-extra-properties nil
@@ -2374,8 +2366,6 @@ The completion method is determined by 
`completion-at-point-functions'."
 Gets combined either with `minibuffer-local-completion-map' or
 with `minibuffer-local-must-match-map'.")
 
-(define-obsolete-variable-alias 'minibuffer-local-must-match-filename-map
-  'minibuffer-local-filename-must-match-map "23.1")
 (defvar minibuffer-local-filename-must-match-map (make-sparse-keymap))
 (make-obsolete-variable 'minibuffer-local-filename-must-match-map nil "24.1")
 
diff --git a/lisp/mouse.el b/lisp/mouse.el
index d369545..a06ca2a 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -274,34 +274,6 @@ not it is actually displayed."
            local-menu
            minor-mode-menus)))
 
-(defun mouse-major-mode-menu (event &optional prefix)
-  "Pop up a mode-specific menu of mouse commands.
-Default to the Edit menu if the major mode doesn't define a menu."
-  (declare (obsolete mouse-menu-major-mode-map "23.1"))
-  (interactive "@e\nP")
-  (run-hooks 'activate-menubar-hook 'menu-bar-update-hook)
-  (popup-menu (mouse-menu-major-mode-map) event prefix))
-
-(defun mouse-popup-menubar (event prefix)
-  "Pop up a menu equivalent to the menu bar for keyboard EVENT with PREFIX.
-The contents are the items that would be in the menu bar whether or
-not it is actually displayed."
-  (declare (obsolete mouse-menu-bar-map "23.1"))
-  (interactive "@e \nP")
-  (run-hooks 'activate-menubar-hook 'menu-bar-update-hook)
-  (popup-menu (mouse-menu-bar-map) (unless (integerp event) event) prefix))
-
-(defun mouse-popup-menubar-stuff (event prefix)
-  "Popup a menu like either `mouse-major-mode-menu' or `mouse-popup-menubar'.
-Use the former if the menu bar is showing, otherwise the latter."
-  (declare (obsolete nil "23.1"))
-  (interactive "@e\nP")
-  (run-hooks 'activate-menubar-hook 'menu-bar-update-hook)
-  (popup-menu
-   (if (zerop (or (frame-parameter nil 'menu-bar-lines) 0))
-       (mouse-menu-bar-map)
-     (mouse-menu-major-mode-map))
-   event prefix))
 
 ;; Commands that operate on windows.
 
diff --git a/lisp/mwheel.el b/lisp/mwheel.el
index 317f2cd..8e2039b 100644
--- a/lisp/mwheel.el
+++ b/lisp/mwheel.el
@@ -162,23 +162,18 @@ Also see `mouse-wheel-tilt-scroll'."
   :type 'boolean
   :version "26.1")
 
-(eval-and-compile
-  (if (fboundp 'event-button)
-      (fset 'mwheel-event-button 'event-button)
-    (defun mwheel-event-button (event)
-      (let ((x (event-basic-type event)))
-       ;; Map mouse-wheel events to appropriate buttons
-       (if (eq 'mouse-wheel x)
-           (let ((amount (car (cdr (cdr (cdr event))))))
-             (if (< amount 0)
-                 mouse-wheel-up-event
-               mouse-wheel-down-event))
-         x))))
-
-  (if (fboundp 'event-window)
-      (fset 'mwheel-event-window 'event-window)
-    (defun mwheel-event-window (event)
-      (posn-window (event-start event)))))
+(defun mwheel-event-button (event)
+  (let ((x (event-basic-type event)))
+    ;; Map mouse-wheel events to appropriate buttons
+    (if (eq 'mouse-wheel x)
+        (let ((amount (car (cdr (cdr (cdr event))))))
+          (if (< amount 0)
+              mouse-wheel-up-event
+            mouse-wheel-down-event))
+      x)))
+
+(defun mwheel-event-window (event)
+  (posn-window (event-start event)))
 
 (defvar mwheel-inhibit-click-event-timer nil
   "Timer running while mouse wheel click event is inhibited.")
diff --git a/lisp/net/eudc-bob.el b/lisp/net/eudc-bob.el
index 56ea033..bb66825 100644
--- a/lisp/net/eudc-bob.el
+++ b/lisp/net/eudc-bob.el
@@ -1,4 +1,4 @@
-;;; eudc-bob.el --- Binary Objects Support for EUDC
+;;; eudc-bob.el --- Binary Objects Support for EUDC  -*- lexical-binding: t; 
-*-
 
 ;; Copyright (C) 1999-2020 Free Software Foundation, Inc.
 
@@ -39,19 +39,41 @@
 
 (require 'eudc)
 
-(defvar eudc-bob-generic-keymap nil
+(defvar eudc-bob-generic-keymap
+  (let ((map (make-sparse-keymap)))
+    (define-key map "s" 'eudc-bob-save-object)
+    (define-key map "!" 'eudc-bob-pipe-object-to-external-program)
+    (define-key map [down-mouse-3] 'eudc-bob-popup-menu)
+    map)
   "Keymap for multimedia objects.")
 
-(defvar eudc-bob-image-keymap nil
+(defvar eudc-bob-image-keymap
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map eudc-bob-generic-keymap)
+    (define-key map "t" 'eudc-bob-toggle-inline-display)
+    map)
   "Keymap for inline images.")
 
-(defvar eudc-bob-sound-keymap nil
+(defvar eudc-bob-sound-keymap
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map eudc-bob-generic-keymap)
+    (define-key map (kbd "RET") 'eudc-bob-play-sound-at-point)
+    (define-key map [down-mouse-2] 'eudc-bob-play-sound-at-mouse)
+    map)
   "Keymap for inline sounds.")
 
-(defvar eudc-bob-url-keymap nil
+(defvar eudc-bob-url-keymap
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "RET") 'browse-url-at-point)
+    (define-key map [down-mouse-2] 'browse-url-at-mouse)
+    map)
   "Keymap for inline urls.")
 
-(defvar eudc-bob-mail-keymap nil
+(defvar eudc-bob-mail-keymap
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "RET") 'goto-address-at-point)
+    (define-key map [down-mouse-2] 'goto-address-at-point)
+    map)
   "Keymap for inline e-mail addresses.")
 
 (defvar eudc-bob-generic-menu
@@ -74,13 +96,6 @@
      (fboundp 'play-sound-internal)]
     ,@(cdr (cdr eudc-bob-generic-menu))))
 
-(defun eudc-jump-to-event (event)
-  "Jump to the window and point where EVENT occurred."
-  (if (fboundp 'event-closest-point)
-      (goto-char (event-closest-point event))
-    (set-buffer (window-buffer (posn-window (event-start event))))
-    (goto-char (posn-point (event-start event)))))
-
 (defun eudc-bob-get-overlay-prop (prop)
   "Get property PROP from one of the overlays around."
   (let ((overlays (append (overlays-at (1- (point)))
@@ -205,42 +220,30 @@ display a button."
   "Play the sound data contained in the button where EVENT occurred."
   (interactive "e")
   (save-excursion
-    (eudc-jump-to-event event)
+    (mouse-set-point event)
     (eudc-bob-play-sound-at-point)))
 
-(defun eudc-bob-save-object ()
+(defun eudc-bob-save-object (filename)
   "Save the object data of the button at point."
-  (interactive)
+  (interactive "fWrite file: ")
   (let ((data (eudc-bob-get-overlay-prop 'object-data))
-       (buffer (generate-new-buffer "*eudc-tmp*")))
-    (save-excursion
-      (set-buffer-file-coding-system 'binary)
-      (set-buffer buffer)
-      (set-buffer-multibyte nil)
-      (insert data)
-      (save-buffer))
-    (kill-buffer buffer)))
+       (coding-system-for-write 'binary)) ;Inhibit EOL conversion.
+    (write-region data nil filename)))
 
-(defun eudc-bob-pipe-object-to-external-program ()
+(defun eudc-bob-pipe-object-to-external-program (program)
   "Pipe the object data of the button at point to an external program."
-  (interactive)
+  (interactive (list (completing-read "Viewer: " eudc-external-viewers)))
   (let ((data (eudc-bob-get-overlay-prop 'object-data))
-       (buffer (generate-new-buffer "*eudc-tmp*"))
-       program
-       viewer)
-    (condition-case nil
-       (save-excursion
-         (set-buffer-file-coding-system 'binary)
-         (set-buffer buffer)
-         (insert data)
-         (setq program (completing-read "Viewer: " eudc-external-viewers))
-         (if (setq viewer (assoc program eudc-external-viewers))
-             (call-process-region (point-min) (point-max)
-                                  (car (cdr viewer))
-                                  (cdr (cdr viewer)))
-           (call-process-region (point-min) (point-max) program)))
-      (error
-       (kill-buffer buffer)))))
+       (viewer (assoc program eudc-external-viewers)))
+    (with-temp-buffer
+      (set-buffer-multibyte nil)
+      (insert data)
+      (let ((coding-system-for-write 'binary)) ;Inhibit EOL conversion
+       (if viewer
+           (call-process-region (point-min) (point-max)
+                                (car (cdr viewer))
+                                (cdr (cdr viewer)))
+         (call-process-region (point-min) (point-max) program))))))
 
 (defun eudc-bob-menu ()
   "Retrieve the menu attached to a binary object."
@@ -250,47 +253,8 @@ display a button."
   "Pop-up a menu of EUDC multimedia commands."
   (interactive "@e")
   (run-hooks 'activate-menubar-hook)
-  (eudc-jump-to-event event)
-  (let ((result (x-popup-menu t (eudc-bob-menu)))
-       command)
-    (if result
-       (progn
-         (setq command (lookup-key (eudc-bob-menu)
-                                   (apply 'vector result)))
-         (command-execute command)))))
-
-(setq eudc-bob-generic-keymap
-      (let ((map (make-sparse-keymap)))
-       (define-key map "s" 'eudc-bob-save-object)
-       (define-key map "!" 'eudc-bob-pipe-object-to-external-program)
-       (define-key map [down-mouse-3] 'eudc-bob-popup-menu)
-       map))
-
-(setq eudc-bob-image-keymap
-      (let ((map (make-sparse-keymap)))
-       (define-key map "t" 'eudc-bob-toggle-inline-display)
-       map))
-
-(setq eudc-bob-sound-keymap
-      (let ((map (make-sparse-keymap)))
-       (define-key map [return] 'eudc-bob-play-sound-at-point)
-       (define-key map [down-mouse-2] 'eudc-bob-play-sound-at-mouse)
-       map))
-
-(setq eudc-bob-url-keymap
-      (let ((map (make-sparse-keymap)))
-       (define-key map [return] 'browse-url-at-point)
-       (define-key map [down-mouse-2] 'browse-url-at-mouse)
-       map))
-
-(setq eudc-bob-mail-keymap
-      (let ((map (make-sparse-keymap)))
-       (define-key map [return] 'goto-address-at-point)
-       (define-key map [down-mouse-2] 'goto-address-at-point)
-       map))
-
-(set-keymap-parent eudc-bob-image-keymap eudc-bob-generic-keymap)
-(set-keymap-parent eudc-bob-sound-keymap eudc-bob-generic-keymap)
+  (mouse-set-point event)
+  (popup-menu (eudc-bob-menu) event))
 
 ;; If the first arguments can be nil here, then these 3 can be
 ;; defconsts once more.
diff --git a/lisp/net/eww.el b/lisp/net/eww.el
index e7170b3..04deb5b 100644
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@ -672,9 +672,30 @@ Currently this means either text/html or 
application/xhtml+xml."
   (setq header-line-format
        (and eww-header-line-format
             (let ((title (plist-get eww-data :title))
-                  (peer (plist-get eww-data :peer)))
+                  (peer (plist-get eww-data :peer))
+                   (url (plist-get eww-data :url)))
               (when (zerop (length title))
                 (setq title "[untitled]"))
+               ;; Limit the length of the title so that the host name
+               ;; of the URL is always visible.
+               (when url
+                 (let* ((parsed (url-generic-parse-url url))
+                        (host-length (length (format "%s://%s"
+                                                     (url-type parsed)
+                                                     (url-host parsed))))
+                        (width (window-width)))
+                   (cond
+                    ;; The host bit is wider than the window, so nix
+                    ;; the title.
+                    ((> (+ host-length 5) width)
+                     (setq title ""))
+                    ;; Trim the title.
+                    ((> (+ (length title) host-length 2) width)
+                     (setq title (concat
+                                  (substring title 0 (- width
+                                                        host-length
+                                                        5))
+                                  "..."))))))
               ;; This connection has is https.
               (when peer
                 (setq title
@@ -686,7 +707,7 @@ Currently this means either text/html or 
application/xhtml+xml."
                "%" "%%"
                (format-spec
                 eww-header-line-format
-                `((?u . ,(or (plist-get eww-data :url) ""))
+                `((?u . ,(or url ""))
                   (?t . ,title))))))))
 
 (defun eww-tag-title (dom)
diff --git a/lisp/net/newst-treeview.el b/lisp/net/newst-treeview.el
index 1bed61f..ff8a447 100644
--- a/lisp/net/newst-treeview.el
+++ b/lisp/net/newst-treeview.el
@@ -131,14 +131,6 @@ groupcontent := feedname | groupdefinition)
 Example: (\"Topmost group\" \"feed1\" (\"subgroup1\" \"feed 2\")
 \"feed3\")")
 
-(defcustom newsticker-groups-filename
-  nil
-  "Name of the newsticker groups settings file."
-  :version "25.1"                       ; changed default value to nil
-  :type '(choice (const nil) string)
-  :group 'newsticker-treeview)
-(make-obsolete-variable 'newsticker-groups-filename 'newsticker-dir "23.1")
-
 ;; ======================================================================
 ;;; internal variables
 ;; ======================================================================
@@ -1265,29 +1257,9 @@ Note: does not update the layout."
 (defun newsticker--treeview-load ()
   "Load treeview settings."
   (let* ((coding-system-for-read 'utf-8)
-         (filename
-          (or (and newsticker-groups-filename
-                   (not (string=
-                         (expand-file-name newsticker-groups-filename)
-                         (expand-file-name (concat newsticker-dir "/groups"))))
-                   (file-exists-p newsticker-groups-filename)
-                   (y-or-n-p
-                    (format-message
-                     (concat "Obsolete variable `newsticker-groups-filename' "
-                             "points to existing file \"%s\".\n"
-                             "Read it? ")
-                     newsticker-groups-filename))
-                   newsticker-groups-filename)
-              (concat newsticker-dir "/groups")))
+         (filename (concat newsticker-dir "/groups"))
          (buf (and (file-exists-p filename)
                    (find-file-noselect filename))))
-    (and newsticker-groups-filename
-         (file-exists-p newsticker-groups-filename)
-        (y-or-n-p (format-message
-                    (concat "Delete the file \"%s\",\nto which the obsolete "
-                            "variable `newsticker-groups-filename' points ? ")
-                    newsticker-groups-filename))
-        (delete-file newsticker-groups-filename))
     (when buf
       (set-buffer buf)
       (goto-char (point-min))
diff --git a/lisp/net/ntlm.el b/lisp/net/ntlm.el
index ebcd219..9401430 100644
--- a/lisp/net/ntlm.el
+++ b/lisp/net/ntlm.el
@@ -69,7 +69,6 @@
 
 (require 'md4)
 (require 'hmac-md5)
-(require 'calc)
 
 (defgroup ntlm nil
   "NTLM (NT LanManager) authentication."
@@ -133,32 +132,27 @@ is not given."
            domain                              ;buffer field
            ))))
 
-(defun ntlm-compute-timestamp ()
-  "Compute an NTLMv2 timestamp.
+(defun ntlm--time-to-timestamp (time)
+  "Convert TIME to an NTLMv2 timestamp.
 Return a unibyte string representing the number of tenths of a
 microsecond since January 1, 1601 as a 64-bit little-endian
-signed integer."
-  ;; FIXME: This can likely be significantly simplified using the new
-  ;; bignums support!
-  (let* ((s-to-tenths-of-us "mul(add(lsh($1,16),$2),10000000)")
-        (us-to-tenths-of-us "mul($3,10)")
-        (ps-to-tenths-of-us "idiv($4,100000)")
-        (tenths-of-us-since-jan-1-1601
-         (apply #'calc-eval (concat "add(add(add("
-                                   s-to-tenths-of-us ","
-                                   us-to-tenths-of-us "),"
-                                   ps-to-tenths-of-us "),"
-                                   ;; tenths of microseconds between
-                                   ;; 1601-01-01 and 1970-01-01
-                                   "116444736000000000)")
-                'rawnum (time-convert nil 'list)))
-        result-bytes)
-    (dotimes (_byte 8)
-      (push (calc-eval "and($1,16#FF)" 'rawnum tenths-of-us-since-jan-1-1601)
-           result-bytes)
-      (setq tenths-of-us-since-jan-1-1601
-           (calc-eval "rsh($1,8,64)" 'rawnum tenths-of-us-since-jan-1-1601)))
-    (apply #'unibyte-string (nreverse result-bytes))))
+signed integer.  TIME must be on the form (HIGH LOW USEC PSEC)."
+  (let* ((s (+ (ash (nth 0 time) 16) (nth 1 time)))
+         (us (nth 2 time))
+         (ps (nth 3 time))
+         (tenths-of-us-since-jan-1-1601
+          (+ (* s 10000000) (* us 10) (/ ps 100000)
+            ;; tenths of microseconds between 1601-01-01 and 1970-01-01
+            116444736000000000)))
+    (apply #'unibyte-string
+           (mapcar (lambda (i)
+                     (logand (ash tenths-of-us-since-jan-1-1601 (* i -8))
+                             #xff))
+                   (number-sequence 0 7)))))
+
+(defun ntlm-compute-timestamp ()
+  "Current time as an NTLMv2 timestamp, as a unibyte string."
+  (ntlm--time-to-timestamp (time-convert nil 'list)))
 
 (defun ntlm-generate-nonce ()
   "Generate a random nonce, not to be used more than once.
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index ca43475..fae15fe 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -4781,104 +4781,6 @@ Goes through the list `tramp-inline-compress-commands'."
        (tramp-message
         vec 2 "Couldn't find an inline transfer compress command")))))
 
-;;;###tramp-autoload
-(defun tramp-multi-hop-p (vec)
-  "Whether the method of VEC is capable of multi-hops."
-  (and (tramp-sh-file-name-handler-p vec)
-       (not (tramp-get-method-parameter vec 'tramp-copy-program))))
-
-(defun tramp-compute-multi-hops (vec)
-  "Expands VEC according to `tramp-default-proxies-alist'."
-  (let ((saved-tdpa tramp-default-proxies-alist)
-       (target-alist `(,vec))
-       (hops (or (tramp-file-name-hop vec) ""))
-       (item vec)
-       choices proxy)
-
-    ;; Ad-hoc proxy definitions.
-    (dolist (proxy (reverse (split-string hops tramp-postfix-hop-regexp 
'omit)))
-      (let* ((host-port (tramp-file-name-host-port item))
-            (user-domain (tramp-file-name-user-domain item))
-            (proxy (concat
-                    tramp-prefix-format proxy tramp-postfix-host-format))
-            (entry
-             (list (and (stringp host-port)
-                        (concat "^" (regexp-quote host-port) "$"))
-                   (and (stringp user-domain)
-                        (concat "^" (regexp-quote user-domain) "$"))
-                   (propertize proxy 'tramp-ad-hoc t))))
-       (tramp-message vec 5 "Add %S to `tramp-default-proxies-alist'" entry)
-       ;; Add the hop.
-       (add-to-list 'tramp-default-proxies-alist entry)
-       (setq item (tramp-dissect-file-name proxy))))
-    ;; Save the new value.
-    (when (and hops tramp-save-ad-hoc-proxies)
-      (customize-save-variable
-       'tramp-default-proxies-alist tramp-default-proxies-alist))
-
-    ;; Look for proxy hosts to be passed.
-    (setq choices tramp-default-proxies-alist)
-    (while choices
-      (setq item (pop choices)
-           proxy (eval (nth 2 item)))
-      (when (and
-            ;; Host.
-            (string-match-p
-             (or (eval (nth 0 item)) "")
-             (or (tramp-file-name-host-port (car target-alist)) ""))
-            ;; User.
-            (string-match-p
-             (or (eval (nth 1 item)) "")
-             (or (tramp-file-name-user-domain (car target-alist)) "")))
-       (if (null proxy)
-           ;; No more hops needed.
-           (setq choices nil)
-         ;; Replace placeholders.
-         (setq proxy
-               (format-spec
-                proxy
-                (format-spec-make
-                 ?u (or (tramp-file-name-user (car target-alist)) "")
-                 ?h (or (tramp-file-name-host (car target-alist)) ""))))
-         (with-parsed-tramp-file-name proxy l
-           ;; Add the hop.
-           (push l target-alist)
-           ;; Start next search.
-           (setq choices tramp-default-proxies-alist)))))
-
-    ;; Foreign and out-of-band methods are not supported for multi-hops.
-    (when (cdr target-alist)
-      (setq choices target-alist)
-      (while (setq item (pop choices))
-       (unless (tramp-multi-hop-p item)
-         (setq tramp-default-proxies-alist saved-tdpa)
-         (tramp-user-error
-          vec "Method `%s' is not supported for multi-hops."
-          (tramp-file-name-method item)))))
-
-    ;; Some methods ("su", "sg", "sudo", "doas", "ksu") do not use the
-    ;; host name in their command template.  In this case, the remote
-    ;; file name must use either a local host name (first hop), or a
-    ;; host name matching the previous hop.
-    (let ((previous-host (or tramp-local-host-regexp "")))
-      (setq choices target-alist)
-      (while (setq item (pop choices))
-       (let ((host (tramp-file-name-host item)))
-         (unless
-             (or
-              ;; The host name is used for the remote shell command.
-              (member
-               '("%h") (tramp-get-method-parameter item 'tramp-login-args))
-              ;; The host name must match previous hop.
-              (string-match-p previous-host host))
-           (setq tramp-default-proxies-alist saved-tdpa)
-           (tramp-user-error
-            vec "Host name `%s' does not match `%s'" host previous-host))
-         (setq previous-host (concat "^" (regexp-quote host) "$")))))
-
-    ;; Result.
-    target-alist))
-
 (defun tramp-ssh-controlmaster-options (vec)
   "Return the Control* arguments of the local ssh."
   (cond
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index ab52bec..83ade66 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -3634,12 +3634,109 @@ User is always nil."
              (delete-file local-copy)))))
       t)))
 
+(defun tramp-multi-hop-p (vec)
+  "Whether the method of VEC is capable of multi-hops."
+  (and (tramp-sh-file-name-handler-p vec)
+       (not (tramp-get-method-parameter vec 'tramp-copy-program))))
+
+(defun tramp-compute-multi-hops (vec)
+  "Expands VEC according to `tramp-default-proxies-alist'."
+  (let ((saved-tdpa tramp-default-proxies-alist)
+       (target-alist `(,vec))
+       (hops (or (tramp-file-name-hop vec) ""))
+       (item vec)
+       choices proxy)
+
+    ;; Ad-hoc proxy definitions.
+    (dolist (proxy (reverse (split-string hops tramp-postfix-hop-regexp 
'omit)))
+      (let* ((host-port (tramp-file-name-host-port item))
+            (user-domain (tramp-file-name-user-domain item))
+            (proxy (concat
+                    tramp-prefix-format proxy tramp-postfix-host-format))
+            (entry
+             (list (and (stringp host-port)
+                        (concat "^" (regexp-quote host-port) "$"))
+                   (and (stringp user-domain)
+                        (concat "^" (regexp-quote user-domain) "$"))
+                   (propertize proxy 'tramp-ad-hoc t))))
+       (tramp-message vec 5 "Add %S to `tramp-default-proxies-alist'" entry)
+       ;; Add the hop.
+       (add-to-list 'tramp-default-proxies-alist entry)
+       (setq item (tramp-dissect-file-name proxy))))
+    ;; Save the new value.
+    (when (and hops tramp-save-ad-hoc-proxies)
+      (customize-save-variable
+       'tramp-default-proxies-alist tramp-default-proxies-alist))
+
+    ;; Look for proxy hosts to be passed.
+    (setq choices tramp-default-proxies-alist)
+    (while choices
+      (setq item (pop choices)
+           proxy (eval (nth 2 item)))
+      (when (and
+            ;; Host.
+            (string-match-p
+             (or (eval (nth 0 item)) "")
+             (or (tramp-file-name-host-port (car target-alist)) ""))
+            ;; User.
+            (string-match-p
+             (or (eval (nth 1 item)) "")
+             (or (tramp-file-name-user-domain (car target-alist)) "")))
+       (if (null proxy)
+           ;; No more hops needed.
+           (setq choices nil)
+         ;; Replace placeholders.
+         (setq proxy
+               (format-spec
+                proxy
+                (format-spec-make
+                 ?u (or (tramp-file-name-user (car target-alist)) "")
+                 ?h (or (tramp-file-name-host (car target-alist)) ""))))
+         (with-parsed-tramp-file-name proxy l
+           ;; Add the hop.
+           (push l target-alist)
+           ;; Start next search.
+           (setq choices tramp-default-proxies-alist)))))
+
+    ;; Foreign and out-of-band methods are not supported for multi-hops.
+    (when (cdr target-alist)
+      (setq choices target-alist)
+      (while (setq item (pop choices))
+       (unless (tramp-multi-hop-p item)
+         (setq tramp-default-proxies-alist saved-tdpa)
+         (tramp-user-error
+          vec "Method `%s' is not supported for multi-hops."
+          (tramp-file-name-method item)))))
+
+    ;; Some methods ("su", "sg", "sudo", "doas", "ksu") do not use the
+    ;; host name in their command template.  In this case, the remote
+    ;; file name must use either a local host name (first hop), or a
+    ;; host name matching the previous hop.
+    (let ((previous-host (or tramp-local-host-regexp "")))
+      (setq choices target-alist)
+      (while (setq item (pop choices))
+       (let ((host (tramp-file-name-host item)))
+         (unless
+             (or
+              ;; The host name is used for the remote shell command.
+              (member
+               '("%h") (tramp-get-method-parameter item 'tramp-login-args))
+              ;; The host name must match previous hop.
+              (string-match-p previous-host host))
+           (setq tramp-default-proxies-alist saved-tdpa)
+           (tramp-user-error
+            vec "Host name `%s' does not match `%s'" host previous-host))
+         (setq previous-host (concat "^" (regexp-quote host) "$")))))
+
+    ;; Result.
+    target-alist))
+
 (defun tramp-direct-async-process-p (&rest args)
   "Whether direct async `make-process' can be called."
   (let ((v (tramp-dissect-file-name default-directory)))
-    (and (tramp-get-connection-property v"direct-async-process" nil)
-          (not (tramp-multi-hop-p v))
-          (not (plist-get args :stderr)))))
+    (and (tramp-get-connection-property v "direct-async-process" nil)
+        (= (length (tramp-compute-multi-hops v)) 1)
+        (not (plist-get args :stderr)))))
 
 ;; We use BUFFER also as connection buffer during setup. Because of
 ;; this, its original contents must be saved, and restored once
diff --git a/lisp/erc/erc-compat.el b/lisp/obsolete/erc-compat.el
similarity index 99%
rename from lisp/erc/erc-compat.el
rename to lisp/obsolete/erc-compat.el
index d71221b..7ef30d8 100644
--- a/lisp/erc/erc-compat.el
+++ b/lisp/obsolete/erc-compat.el
@@ -5,6 +5,7 @@
 ;; Author: Alex Schroeder <alex@gnu.org>
 ;; Maintainer: Amin Bandali <bandali@gnu.org>
 ;; URL: https://www.emacswiki.org/emacs/ERC
+;; Obsolete-since: 28.1
 
 ;; This file is part of GNU Emacs.
 
diff --git a/lisp/obsolete/tpu-edt.el b/lisp/obsolete/tpu-edt.el
index d71f79c..0de7aa0 100644
--- a/lisp/obsolete/tpu-edt.el
+++ b/lisp/obsolete/tpu-edt.el
@@ -287,14 +287,6 @@
 ;;;
 ;;;  User Configurable Variables
 ;;;
-(defcustom tpu-have-ispell t
-  "Non-nil means `tpu-spell-check' uses `ispell-region' for spell checking.
-Otherwise, use `spell-region'."
-  :type 'boolean
-  :group 'tpu)
-(make-obsolete-variable 'tpu-have-ispell "the `spell' package is obsolete."
-                        "23.1")
-
 (defcustom tpu-kill-buffers-silently nil
   "If non-nil, TPU-edt kills modified buffers without asking."
   :type 'boolean
@@ -315,7 +307,6 @@ Otherwise, use `spell-region'."
 ;;;  Global Keymaps
 ;;;
 
-(define-obsolete-variable-alias 'GOLD-map 'tpu-gold-map "23.1")
 (defvar tpu-gold-map
   (let ((map (make-keymap)))
     ;; Previously we used escape sequences here.  We now instead presume
@@ -892,8 +883,7 @@ With argument, fill and justify."
 if no region is selected."
   (interactive)
   (let ((m (tpu-mark)))
-    (apply (if tpu-have-ispell 'ispell-region
-             'spell-region)
+    (apply 'ispell-region
            (if m
                (if (> m (point)) (list (point) m)
                  (list m (point)))
diff --git a/lisp/password-cache.el b/lisp/password-cache.el
index f500757..2443f37 100644
--- a/lisp/password-cache.el
+++ b/lisp/password-cache.el
@@ -94,22 +94,6 @@ The variable `password-cache' control whether the cache is 
used."
   (or (password-read-from-cache key)
       (read-passwd prompt)))
 
-(defun password-read-and-add (prompt &optional key)
-  "Read password, for use with KEY, from user, or from cache if wanted.
-Then store the password in the cache.  Uses `password-read' and
-`password-cache-add'.  Custom variables `password-cache' and
-`password-cache-expiry' regulate cache behavior.
-
-Warning: the password is cached without checking that it is
-correct.  It is better to check the password before caching.  If
-you must use this function, take care to check passwords and
-remove incorrect ones from the cache."
-  (declare (obsolete password-read "23.1"))
-  (let ((password (password-read prompt key)))
-    (when (and password key)
-      (password-cache-add key password))
-    password))
-
 (defun password-cache-remove (key)
   "Remove password indexed by KEY from password cache.
 This is typically run by a timer setup from `password-cache-add',
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index c3a98d9..7b8b174 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -384,7 +384,7 @@ comment at the start of cc-engine.el for more info."
              c-macro-cache-syntactic nil
              c-macro-cache-no-comment nil))
       (save-match-data
-       (let ((safe-pos (point)))       ; a point ouside any literal.
+       (let ((safe-pos (point)))       ; a point outside any literal.
          ;; Move over stuff followed by a multiline block comment lacking
          ;; escaped newlines each time around this loop.
          (while
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
index 0b9f417..a043bbc 100644
--- a/lisp/progmodes/compile.el
+++ b/lisp/progmodes/compile.el
@@ -316,8 +316,8 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1))
     (gcc-include
      "^\\(?:In file included \\|                 \\|\t\\)from \
 \\([0-9]*[^0-9\n]\\(?:[^\n :]\\| [^-/\n]\\|:[^ \n]\\)*?\\):\
-\\([0-9]+\\)\\(?::\\([0-9]+\\)\\)?\\(?:\\(:\\)\\|\\(,\\|$\\)\\)?"
-     1 2 3 (4 . 5))
+\\([0-9]+\\)\\(?::\\([0-9]+\\)\\)?\\(?:\\([:,]\\|$\\)\\)?"
+     1 2 3 (nil . 4))
 
     (ruby-Test::Unit
      "^    [[ ]?\\([^ (].*\\):\\([1-9][0-9]*\\)\\(\\]\\)?:in " 1 2)
@@ -2417,12 +2417,9 @@ and runs `compilation-filter-hook'."
                                                 &optional object limit)
   (let (parsed res)
     (while (progn
-             ;; We parse the buffer here "on-demand" by chunks of 500 chars.
-             ;; But we could also just parse the whole buffer.
              (compilation--ensure-parse
               (setq parsed (max compilation--parsed
-                                (min (+ position 500)
-                                     (or limit (point-max))))))
+                                (or limit (point-max)))))
              (and (or (not (setq res (next-single-property-change
                                       position prop object limit)))
                       (eq res limit))
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index 6122caf..2d2713a 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -3979,6 +3979,9 @@ the sections using `cperl-pod-head-face', 
`cperl-pod-face',
                                    (and (eq (preceding-char) ?.)
                                         (eq (char-after (- (point) 2)) ?.))
                                    (bobp))
+                               ;; { $a++ / $b } doesn't start a regex, nor 
does $a--
+                               (not (and (memq (preceding-char) '(?+ ?-))
+                                         (eq (preceding-char) (char-before (1- 
(point))))))
                                ;;  m|blah| ? foo : bar;
                                (not
                                 (and (eq c ?\?)
diff --git a/lisp/progmodes/ebnf2ps.el b/lisp/progmodes/ebnf2ps.el
index 08cf802..22c70bf 100644
--- a/lisp/progmodes/ebnf2ps.el
+++ b/lisp/progmodes/ebnf2ps.el
@@ -4527,7 +4527,7 @@ end
   (let* ((ebnf-tree tree)
          (ps-color-p           (and ebnf-color-p (ps-color-device)))
         (ps-print-color-scale (if ps-color-p
-                                  (float (car (ps-color-values "white")))
+                                  (float (car (color-values "white")))
                                 1.0))
         (ebnf-total           (length ebnf-tree))
         (ebnf-nprod           0)
@@ -4629,7 +4629,7 @@ end
   (let* ((ebnf-tree tree)
          (ps-color-p           (and ebnf-color-p (ps-color-device)))
         (ps-print-color-scale (if ps-color-p
-                                  (float (car (ps-color-values "white")))
+                                  (float (car (color-values "white")))
                                 1.0))
         ps-zebra-stripes ps-line-number ps-razzle-dazzle
         ps-print-hook
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index 2f44118..21ba42a 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -1420,10 +1420,12 @@ Intended for `eldoc-documentation-functions' (which 
see)."
 (defun elisp-eldoc-var-docstring (callback &rest _ignored)
   "Document variable at point.
 Intended for `eldoc-documentation-functions' (which see)."
-  (let ((sym (elisp--current-symbol)))
-    (when sym (funcall callback (elisp-get-var-docstring sym)
-                       :thing sym
-                       :face 'font-lock-variable-name-face))))
+  (let* ((sym (elisp--current-symbol))
+        (docstring (and sym (elisp-get-var-docstring sym))))
+    (when docstring
+      (funcall callback docstring
+               :thing sym
+               :face 'font-lock-variable-name-face))))
 
 (defun elisp-get-fnsym-args-string (sym &optional index)
   "Return a string containing the parameter list of the function SYM.
diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el
index edadbbd..2c5c365 100644
--- a/lisp/progmodes/etags.el
+++ b/lisp/progmodes/etags.el
@@ -1424,6 +1424,10 @@ hits the start of file."
          (goto-func goto-tag-location-function)
          tag tag-info pt)
     (forward-line 1)
+    ;; Exuberant ctags add a line starting with the DEL character;
+    ;; skip past it.
+    (when (looking-at "\177")
+      (forward-line 1))
     (while (not (or (eobp) (looking-at "\f")))
       ;; We used to use explicit tags when available, but the current goto-func
       ;; can only handle implicit tags.
diff --git a/lisp/progmodes/idlw-help.el b/lisp/progmodes/idlw-help.el
index d3a2308..ec4fd58 100644
--- a/lisp/progmodes/idlw-help.el
+++ b/lisp/progmodes/idlw-help.el
@@ -267,7 +267,6 @@ support."
 (declare-function idlwave-find-class-definition "idlwave")
 (declare-function idlwave-find-inherited-class "idlwave")
 (declare-function idlwave-find-struct-tag "idlwave")
-(declare-function idlwave-get-buffer-visiting "idlwave")
 (declare-function idlwave-in-quote "idlwave")
 (declare-function idlwave-make-full-name "idlwave")
 (declare-function idlwave-members-only "idlwave")
@@ -880,7 +879,7 @@ This function can be used as `idlwave-extra-help-function'."
          (setq in-buf ; structure-tag completion is always in current buffer
                (if struct-tag
                    idlwave-current-tags-buffer
-                 (idlwave-get-buffer-visiting file)))
+                  (find-buffer-visiting file)))
          ;; see if file is in a visited buffer, insert those contents
          (if in-buf
              (progn
diff --git a/lisp/progmodes/idlw-shell.el b/lisp/progmodes/idlw-shell.el
index f875915..99ac087 100644
--- a/lisp/progmodes/idlw-shell.el
+++ b/lisp/progmodes/idlw-shell.el
@@ -2640,7 +2640,7 @@ Assumes that `idlwave-shell-sources-alist' contains an 
entry for that module."
     (if (or (not source-file)
            (not (file-regular-p source-file))
            (not (setq buf
-                      (or (idlwave-get-buffer-visiting source-file)
+                       (or (find-buffer-visiting source-file)
                           (find-file-noselect source-file)))))
        (progn
          (message "The source file for module %s is probably not compiled"
@@ -3241,8 +3241,7 @@ Does not work for a region with multiline blocks - use
   "Delete the temporary files and kill associated buffers."
   (if (stringp idlwave-shell-temp-pro-file)
       (condition-case nil
-         (let ((buf (idlwave-get-buffer-visiting
-                     idlwave-shell-temp-pro-file)))
+          (let ((buf (find-buffer-visiting idlwave-shell-temp-pro-file)))
            (if (buffer-live-p buf)
                (kill-buffer buf))
            (delete-file idlwave-shell-temp-pro-file))
@@ -3788,7 +3787,7 @@ handled by this command."
       (save-buffer)
       (setq idlwave-shell-last-save-and-action-file (buffer-file-name)))
      (idlwave-shell-last-save-and-action-file
-      (if (setq buf (idlwave-get-buffer-visiting
+      (if (setq buf (find-buffer-visiting
                     idlwave-shell-last-save-and-action-file))
          (with-current-buffer buf
            (save-buffer))))
diff --git a/lisp/progmodes/idlwave.el b/lisp/progmodes/idlwave.el
index f7e53ec..153f257 100644
--- a/lisp/progmodes/idlwave.el
+++ b/lisp/progmodes/idlwave.el
@@ -581,12 +581,7 @@ like this:
 MyMethod <Class1,Class2,Class3>
 
 The value of this variable may be nil to inhibit display, or an integer to
-indicate the maximum number of classes to display.
-
-On XEmacs, a full list of classes will also be placed into a `help-echo'
-property on the completion items, so that the list of classes for the current
-item is displayed in the echo area.  If the value of this variable is a
-negative integer, the `help-echo' property will be suppressed."
+indicate the maximum number of classes to display."
   :group 'idlwave-completion
   :type '(choice (const :tag "Don't show" nil)
                 (integer :tag "Number of classes shown" 1)))
@@ -1054,7 +1049,6 @@ goto                 Goto Statements
 common-blocks        Common Blocks
 keyword-parameters   Keyword Parameters in routine definitions and calls
 system-variables     System Variables
-fixme                FIXME: Warning in comments (on XEmacs only v. 21.0 and up)
 class-arrows         Object Arrows with class property"
   :group 'idlwave-misc
   :type '(set
@@ -1069,7 +1063,6 @@ class-arrows         Object Arrows with class property"
          (const :tag "Common Blocks"                     common-blocks)
          (const :tag "Keyword Parameters"                keyword-parameters)
          (const :tag "System Variables"                  system-variables)
-         (const :tag "FIXME: Warning"                    fixme)
          (const :tag "Object Arrows with class property " class-arrows)))
 
 (defcustom idlwave-mode-hook nil
@@ -1138,23 +1131,16 @@ As a user, you should not set this to t.")
        ;; Common blocks
        (common-blocks
        '("\\<\\(common\\)\\>[ \t]*\\(\\sw+\\)?[ \t]*,?"
-         (1 font-lock-keyword-face)              ; "common"
-         (2 font-lock-constant-face nil t)      ; block name
+         (1 font-lock-keyword-face)        ; "common"
+         (2 font-lock-constant-face nil t) ; block name
          ("[ \t]*\\(\\sw+\\)[ ,]*"
           ;; Start with point after block name and comma
-          (goto-char (match-end 0))  ; needed for XEmacs, could be nil
-          nil
-          (1 font-lock-variable-name-face)       ; variable names
-          )))
+          nil nil (1 font-lock-variable-name-face))))       ; variable names
 
        ;; Batch files
        (batch-files
        '("^[ \t]*\\(@[^ \t\n]+\\)" (1 font-lock-string-face)))
 
-       ;; FIXME warning.
-       (fixme
-       '("\\<FIXME:" (0 font-lock-warning-face t)))
-
        ;; Labels
        (label
        '("^[ \t]*\\([a-zA-Z]\\sw*:\\)" (1 font-lock-constant-face)))
@@ -1241,9 +1227,6 @@ As a user, you should not set this to t.")
     ((?$ . "w") (?_ . "w") (?. . "w") (?| . "w") (?& . "w"))
     beginning-of-line))
 
-(put 'idlwave-mode 'font-lock-defaults
-     idlwave-font-lock-defaults) ; XEmacs
-
 (defconst idlwave-comment-line-start-skip "^[ \t]*;"
   "Regexp to match the start of a full-line comment.
 That is the _beginning_ of a line containing a comment delimiter `;' preceded
@@ -1479,9 +1462,7 @@ Otherwise ARGS forms a list that is evaluated."
     (define-key map "\M-\C-i" 'idlwave-complete)
     (define-key map "\C-c\C-i" 'idlwave-update-routine-info)
     (define-key map "\C-c="    'idlwave-resolve)
-    (define-key map
-      (if (featurep 'xemacs) [(shift button3)] [(shift mouse-3)])
-      'idlwave-mouse-context-help)
+    (define-key map [(shift mouse-3)] 'idlwave-mouse-context-help)
     map)
   "Keymap used in IDL mode.")
 
@@ -1916,8 +1897,6 @@ The main features of this mode are
       (add-to-list 'tag-table-alist '("\\.pro$" . "IDLTAGS")))
 
   ;; Font-lock additions
-  ;; Following line is for Emacs - XEmacs uses the corresponding property
-  ;; on the `idlwave-mode' symbol.
   (set (make-local-variable 'font-lock-defaults) idlwave-font-lock-defaults)
   (set (make-local-variable 'font-lock-mark-block-function)
        'idlwave-mark-subprogram)
@@ -3814,15 +3793,8 @@ If PATTERN is omitted, it defaults to \"[ 
\\f\\t\\n\\r\\v]+\"."
       (setq start (match-end 0)))
     (setq ret_string (concat ret_string (substring string start last)))))
 
-(defun idlwave-get-buffer-visiting (file)
-  ;; Return the buffer currently visiting FILE
-  (cond
-   ((boundp 'find-file-compare-truenames) ; XEmacs
-    (let ((find-file-compare-truenames t))
-      (get-file-buffer file)))
-   ((fboundp 'find-buffer-visiting)       ; Emacs
-    (find-buffer-visiting file))
-   (t (error "This should not happen (idlwave-get-buffer-visiting)"))))
+(define-obsolete-function-alias 'idlwave-get-buffer-visiting
+  #'find-buffer-visiting "28.1")
 
 (defvar idlwave-outlawed-buffers nil
   "List of buffers pulled up by IDLWAVE for special reasons.
@@ -3830,7 +3802,7 @@ Buffers in this list may be killed by 
`idlwave-kill-autoloaded-buffers'.")
 
 (defun idlwave-find-file-noselect (file &optional why)
   ;; Return a buffer visiting file.
-  (or (idlwave-get-buffer-visiting file)
+  (or (find-buffer-visiting file)
       (let ((buf (find-file-noselect file)))
        (if why (add-to-list 'idlwave-outlawed-buffers (cons buf why)))
        buf)))
@@ -6618,7 +6590,6 @@ This function is not general, can only be used for 
completion stuff."
   "A form to evaluate after completion selection in *Completions* buffer.")
 (defconst idlwave-completion-mark (make-marker)
   "A mark pointing to the beginning of the completion string.")
-(defvar completion-highlight-first-word-only) ;XEmacs.
 
 (defun idlwave-complete-in-buffer (type stype list selector prompt isa
                                        &optional prepare-display-function
@@ -6697,12 +6668,7 @@ accumulate information on matching completions."
              list))
       (let* ((list all-completions)
             ;; "complete" means, this is already a valid completion
-            (complete (memq spart all-completions))
-            (completion-highlight-first-word-only t)) ; XEmacs
-            ;; (completion-fixup-function             ; Emacs
-            ;;  (lambda () (and (eq (preceding-char) ?>)
-            ;;               (re-search-backward " <" beg t)))))
-
+            (complete (memq spart all-completions)))
        (setq list (sort list (lambda (a b)
                                (string< (downcase a) (downcase b)))))
        (if prepare-display-function
@@ -6764,7 +6730,6 @@ accumulate information on matching completions."
     (let* ((do-prop (and (>= show-classes 0)
                         (>= emacs-major-version 21)))
           (do-buf (not (= show-classes 0)))
-          ;; (do-dots (featurep 'xemacs))
           (do-dots t)
           (inherit (if (and (not (eq type 'class-tag)) super-classes)
                        (cons class-selector super-classes)))
@@ -6830,10 +6795,6 @@ accumulate information on matching completions."
 ;;----------------------------------------------------------------------
 ;;----------------------------------------------------------------------
 ;;----------------------------------------------------------------------
-(when (featurep 'xemacs)
-  (defvar rtn)
-  (defun idlwave-pset (item)
-    (set 'rtn item)))
 
 (defun idlwave-popup-select (ev list title &optional sort)
   "Select an item in LIST with a popup menu.
@@ -6844,17 +6805,6 @@ sort the list before displaying."
     (cond ((null list))
          ((= 1 (length list))
           (setq rtn (car list)))
-         ((featurep 'xemacs)
-          (if sort (setq list (sort list (lambda (a b)
-                                           (string< (upcase a) (upcase b))))))
-          (setq menu
-                (append (list title)
-                        (mapcar (lambda (x) (vector x (list 'idlwave-pset
-                                                            x)))
-                                list)))
-          (setq menu (idlwave-split-menu-xemacs menu maxpopup))
-          (let ((resp (get-popup-menu-response menu)))
-             (funcall (event-function resp) (event-object resp))))
          (t
           (if sort (setq list (sort list (lambda (a b)
                                            (string< (upcase a) (upcase b))))))
@@ -6862,36 +6812,14 @@ sort the list before displaying."
                            (list
                             (append (list "")
                                     (mapcar (lambda(x) (cons x x)) list)))))
-          (setq menu (idlwave-split-menu-emacs menu maxpopup))
+          (setq menu (idlwave-split-menu menu maxpopup))
           (setq rtn (x-popup-menu ev menu))))
     rtn))
 
-(defun idlwave-split-menu-xemacs (menu N)
-  "Split the MENU into submenus of maximum length N."
-  (if (<= (length menu) (1+ N))
-      ;; No splitting needed
-      menu
-    (let* ((title (car menu))
-          (entries (cdr menu))
-          (menu (list title))
-          (cnt 0)
-          (nextmenu nil))
-      (while entries
-       (while (and entries (< cnt N))
-         (setq cnt (1+ cnt)
-               nextmenu (cons (car entries) nextmenu)
-               entries (cdr entries)))
-       (setq nextmenu (nreverse nextmenu))
-       (setq nextmenu (cons (format "%s...%s"
-                                    (aref (car nextmenu) 0)
-                                    (aref (nth (1- cnt) nextmenu) 0))
-                            nextmenu))
-       (setq menu (cons nextmenu menu)
-             nextmenu nil
-             cnt 0))
-      (nreverse menu))))
+(define-obsolete-function-alias 'idlwave-split-menu-emacs
+  #'idlwave-split-menu "28.1")
 
-(defun idlwave-split-menu-emacs (menu N)
+(defun idlwave-split-menu (menu N)
   "Split the MENU into submenus of maximum length N."
   (if (<= (length (nth 1 menu)) (1+ N))
       ;; No splitting needed
@@ -6946,10 +6874,7 @@ sort the list before displaying."
     (move-marker idlwave-completion-mark beg)
     (setq idlwave-before-completion-wconf (current-window-configuration)))
 
-  (if (featurep 'xemacs)
-      (idlwave-display-completion-list-xemacs
-       list)
-    (idlwave-display-completion-list-emacs list))
+  (idlwave-display-completion-list-1 list)
 
   ;; Store a special value in `this-command'.  When `idlwave-complete'
   ;; finds this in `last-command', it will scroll the *Completions* buffer.
@@ -7007,8 +6932,7 @@ The key which is associated with each option is generated 
automatically.
 First, the strings are checked for preselected keys, like in \"[P]rint\".
 If these don't exist, a letter in the string is automatically selected."
   (let* ((alist (symbol-value sym))
-         (temp-buffer-show-hook (if (fboundp 'fit-window-to-buffer)
-                                   '(fit-window-to-buffer)))
+         (temp-buffer-show-hook '(fit-window-to-buffer))
          keys-alist char)
     ;; First check the cache
     (if (and (eq (symbol-value sym) (get sym :one-key-alist-last)))
@@ -7094,42 +7018,17 @@ If these don't exist, a letter in the string is 
automatically selected."
     (and (local-variable-p var (current-buffer))
         (symbol-value var))))
 
-;; In XEmacs, we can use :activate-callback directly to advice the
-;; choose functions.  We use the private keymap only for the online
-;; help feature.
-
 (defvar idlwave-completion-map nil
   "Keymap for `completion-list-mode' with `idlwave-complete'.")
 
-(defun idlwave-display-completion-list-xemacs (list &rest cl-args)
-  (with-output-to-temp-buffer "*Completions*"
-    (apply 'display-completion-list list
-          ':activate-callback 'idlwave-default-choose-completion
-          cl-args))
-  (with-current-buffer "*Completions*"
-    (use-local-map
-     (or idlwave-completion-map
-        (setq idlwave-completion-map
-              (idlwave-make-modified-completion-map-xemacs
-               (current-local-map)))))))
-
 (defun idlwave-default-choose-completion (&rest args)
   "Execute `default-choose-completion' and then restore the win-conf."
   (apply 'idlwave-choose 'default-choose-completion args))
 
-(defun idlwave-make-modified-completion-map-xemacs (old-map)
-  "Replace `choose-completion' and `mouse-choose-completion' in OLD-MAP."
-  (let ((new-map (copy-keymap old-map)))
-    (define-key new-map [button3up] 'idlwave-mouse-completion-help)
-    (define-key new-map [button3] (lambda ()
-                                   (interactive)
-                                   (setq this-command last-command)))
-    new-map))
-
-;; In Emacs we also replace keybindings in the completion
-;; map in order to install our wrappers.
+(define-obsolete-function-alias 'idlwave-display-completion-list-emacs
+  #'idlwave-display-completion-list-1 "28.1")
 
-(defun idlwave-display-completion-list-emacs (list)
+(defun idlwave-display-completion-list-1 (list)
   "Display completion list and install the choose wrappers."
   (with-output-to-temp-buffer "*Completions*"
     (display-completion-list list))
@@ -7137,10 +7036,12 @@ If these don't exist, a letter in the string is 
automatically selected."
     (use-local-map
      (or idlwave-completion-map
         (setq idlwave-completion-map
-              (idlwave-make-modified-completion-map-emacs
-               (current-local-map)))))))
+              (idlwave-make-modified-completion-map (current-local-map)))))))
 
-(defun idlwave-make-modified-completion-map-emacs (old-map)
+(define-obsolete-function-alias 'idlwave-make-modified-completion-map-emacs
+  #'idlwave-make-modified-completion-map "28.1")
+
+(defun idlwave-make-modified-completion-map (old-map)
   "Replace `choose-completion' and `mouse-choose-completion' in OLD-MAP."
   (let ((new-map (copy-keymap old-map)))
     (substitute-key-definition
@@ -7352,7 +7253,7 @@ class/struct definition."
         (file (idlwave-routine-source-file
                (nth 3 (idlwave-rinfo-assoc pro 'pro nil
                                            (idlwave-routines))))))
-    (cons file (if file (idlwave-get-buffer-visiting file)))))
+    (cons file (if file (find-buffer-visiting file)))))
 
 
 (defun idlwave-scan-class-info (class)
@@ -8223,15 +8124,9 @@ If we do not know about MODULE, just return KEYWORD 
literally."
 
 (defvar idlwave-rinfo-mouse-map
   (let ((map (make-sparse-keymap)))
-    (define-key map
-      (if (featurep 'xemacs) [button2] [mouse-2])
-      'idlwave-mouse-active-rinfo)
-    (define-key map
-      (if (featurep 'xemacs) [(shift button2)] [(shift mouse-2)])
-      'idlwave-mouse-active-rinfo-shift)
-    (define-key map
-      (if (featurep 'xemacs) [button3] [mouse-3])
-      'idlwave-mouse-active-rinfo-right)
+    (define-key map [mouse-2] 'idlwave-mouse-active-rinfo)
+    (define-key map [(shift mouse-2)] 'idlwave-mouse-active-rinfo-shift)
+    (define-key map [mouse-3] 'idlwave-mouse-active-rinfo-right)
     (define-key map " " 'idlwave-active-rinfo-space)
     (define-key map "q" 'idlwave-quit-help)
     map))
@@ -8283,7 +8178,6 @@ If we do not know about MODULE, just return KEYWORD 
literally."
          "Button2: Display info about same method in superclass")
         (col 0)
         (data (list name type class (current-buffer) nil initial-class))
-        (km-prop (if (featurep 'xemacs) 'keymap 'local-map))
         (face 'idlwave-help-link)
         beg props win cnt total)
     ;; Fix keywords, but don't add chained super-classes, since these
@@ -8308,7 +8202,7 @@ If we do not know about MODULE, just return KEYWORD 
literally."
                                  idlwave-current-obj_new-class)
        (when superclasses
          (setq props (list 'mouse-face 'highlight
-                           km-prop idlwave-rinfo-mouse-map
+                           'local-map idlwave-rinfo-mouse-map
                            'help-echo help-echo-class
                            'data (cons 'class data)))
          (let ((classes (cons initial-class superclasses)) c)
@@ -8324,7 +8218,7 @@ If we do not know about MODULE, just return KEYWORD 
literally."
                    (add-text-properties beg (point) props))))
            (insert "\n")))
        (setq props (list 'mouse-face 'highlight
-                         km-prop idlwave-rinfo-mouse-map
+                         'local-map idlwave-rinfo-mouse-map
                          'help-echo help-echo-use
                          'data (cons 'usage data)))
        (if html-file (setq props (append (list 'face face 'link html-file)
@@ -8352,7 +8246,7 @@ If we do not know about MODULE, just return KEYWORD 
literally."
             (setq beg (point)
                   ;; Relevant keywords already have link property attached
                   props (list 'mouse-face 'highlight
-                              km-prop idlwave-rinfo-mouse-map
+                              'local-map idlwave-rinfo-mouse-map
                               'data (cons 'keyword data)
                               'help-echo help-echo-kwd
                               'keyword (car x)))
@@ -8366,7 +8260,7 @@ If we do not know about MODULE, just return KEYWORD 
literally."
        ;; Here entry is (key file (list of type-conses))
        (while (setq entry (pop all))
          (setq props (list 'mouse-face 'highlight
-                           km-prop idlwave-rinfo-mouse-map
+                           'local-map idlwave-rinfo-mouse-map
                            'help-echo help-echo-src
                            'source (list (car (car (nth 2 entry))) ;type
                                          (nth 1 entry)
@@ -8471,8 +8365,7 @@ to it."
       (add-text-properties beg (point) (list 'face 'bold)))
     (when (and file (not (equal file "")))
       (setq beg (point))
-      (insert (apply 'abbreviate-file-name
-                    (if (featurep 'xemacs) (list file t) (list file))))
+      (insert (apply 'abbreviate-file-name (list file)))
       (if file-props
          (add-text-properties beg (point) file-props)))))
 
@@ -8632,10 +8525,9 @@ can be used to detect possible name clashes during this 
process."
                           idlwave-user-catalog-routines
                           idlwave-buffer-routines
                           nil))
-        (km-prop (if (featurep 'xemacs) 'keymap 'local-map))
         (keymap (make-sparse-keymap))
         (props (list 'mouse-face 'highlight
-                     km-prop keymap
+                     'local-map keymap
                      'help-echo "Mouse2: Find source"))
         (nroutines (length (or special-routines routines)))
         (step (/ nroutines 100))
@@ -8658,7 +8550,7 @@ can be used to detect possible name clashes during this 
process."
                                               (nth 2 b) (car b)))))))
     (message "Sorting routines...done")
 
-    (define-key keymap (if (featurep 'xemacs) [(button2)] [(mouse-2)])
+    (define-key keymap [(mouse-2)]
       (lambda (ev)
        (interactive "e")
        (mouse-set-point ev)
@@ -9020,23 +8912,6 @@ Assumes that point is at the beginning of the unit as 
found by
                 'imenu)
             (error nil)))))
 
-;; Here we hack func-menu.el in order to support this new mode.
-;; The latest versions of func-menu.el already have this stuff in, so
-;; we hack only if it is not already there.
-(when (featurep 'xemacs)
-  (eval-after-load "func-menu"
-    '(progn
-       (or (assq 'idlwave-mode fume-function-name-regexp-alist)
-          (not (boundp 'fume-function-name-regexp-idl))      ; avoid problems
-          (setq fume-function-name-regexp-alist
-                (cons '(idlwave-mode . fume-function-name-regexp-idl)
-                      fume-function-name-regexp-alist)))
-       (or (assq 'idlwave-mode fume-find-function-name-method-alist)
-          (not (fboundp 'fume-find-next-idl-function-name))  ; avoid problems
-          (setq fume-find-function-name-method-alist
-                (cons '(idlwave-mode . fume-find-next-idl-function-name)
-                      fume-find-function-name-method-alist))))))
-
 (defun idlwave-edit-in-idlde ()
   "Edit the current file in IDL Development environment."
   (interactive)
diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el
index ff0b6a3..127b24c 100644
--- a/lisp/progmodes/perl-mode.el
+++ b/lisp/progmodes/perl-mode.el
@@ -214,7 +214,9 @@
   (defconst perl--syntax-exp-intro-regexp
     (concat "\\(?:\\(?:^\\|[^$@&%[:word:]]\\)"
             (regexp-opt perl--syntax-exp-intro-keywords)
-            "\\|[-?:.,;|&+*=!~({[]\\|\\(^\\)\\)[ \t\n]*")))
+            "\\|[?:.,;|&*=!~({[]"
+            "\\|[^-+][-+]"    ;Bug#42168: `+' is intro but `++' isn't!
+            "\\|\\(^\\)\\)[ \t\n]*")))
 
 (defun perl-syntax-propertize-function (start end)
   (let ((case-fold-search nil))
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index b616135..8afd5ce 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -1,8 +1,8 @@
 ;;; project.el --- Operations on the current project  -*- lexical-binding: t; 
-*-
 
 ;; Copyright (C) 2015-2020 Free Software Foundation, Inc.
-;; Version: 0.5.0
-;; Package-Requires: ((emacs "26.3"))
+;; Version: 0.5.1
+;; Package-Requires: ((emacs "26.3") (xref "1.0.2"))
 
 ;; This is a GNU ELPA :core package.  Avoid using functionality that
 ;; not compatible with the version of Emacs recorded above.
@@ -731,24 +731,6 @@ pattern to search for."
       (user-error "No matches for: %s" regexp))
     xrefs))
 
-(defun project--process-file-region (start end program
-                                     &optional buffer display
-                                     &rest args)
-  ;; FIXME: This branching shouldn't be necessary, but
-  ;; call-process-region *is* measurably faster, even for a program
-  ;; doing some actual work (for a period of time). Even though
-  ;; call-process-region also creates a temp file internally
-  ;; (http://lists.gnu.org/archive/html/emacs-devel/2019-01/msg00211.html).
-  (if (not (file-remote-p default-directory))
-      (apply #'call-process-region
-             start end program nil buffer display args)
-    (let ((infile (make-temp-file "ppfr")))
-      (unwind-protect
-          (progn
-            (write-region start end infile nil 'silent)
-            (apply #'process-file program infile buffer display args))
-        (delete-file infile)))))
-
 (defun project--read-regexp ()
   (let ((sym (thing-at-point 'symbol)))
     (read-regexp "Find regexp" (and sym (regexp-quote sym)))))
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 3af55be..d83af83 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -283,24 +283,6 @@
   :link '(emacs-commentary-link "python"))
 
 
-;;; 24.x Compat
-
-
-(eval-and-compile
-  (unless (fboundp 'prog-first-column)
-    (defun prog-first-column ()
-      0))
-  (unless (fboundp 'file-local-name)
-    (defun file-local-name (file)
-      "Return the local name component of FILE.
-It returns a file name which can be used directly as argument of
-`process-file', `start-file-process', or `shell-command'."
-      (or (file-remote-p file 'localname) file))))
-
-;; In Emacs 24.3 and earlier, `define-derived-mode' does not define
-;; the hook variable, it only puts documentation on the symbol.
-(defvar inferior-python-mode-hook)
-
 
 ;;; Bindings
 
@@ -2809,6 +2791,7 @@ variable.
          python-shell-comint-watch-for-first-prompt-output-filter
          python-comint-postoutput-scroll-to-bottom
          comint-watch-for-password-prompt))
+  (setq-local comint-highlight-input nil)
   (set (make-local-variable 'compilation-error-regexp-alist)
        python-shell-compilation-regexp-alist)
   (add-hook 'completion-at-point-functions
diff --git a/lisp/progmodes/subword.el b/lisp/progmodes/subword.el
index f9b069f..0f2c943 100644
--- a/lisp/progmodes/subword.el
+++ b/lisp/progmodes/subword.el
@@ -115,6 +115,8 @@ treat nomenclature boundaries as word boundaries."
     (when subword-mode (superword-mode -1))
     (subword-setup-buffer))
 
+;; This is defined also in cc-cmds.el, but as obsolete since 24.3.
+;; Let's keep this until the other one can also be removed.
 (define-obsolete-function-alias 'c-subword-mode 'subword-mode "23.2")
 
 ;;;###autoload
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 3e3a37f..bbf899e 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -1,8 +1,8 @@
 ;;; xref.el --- Cross-referencing commands              -*-lexical-binding:t-*-
 
 ;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-;; Version: 1.0.1
-;; Package-Requires: ((emacs "26.3") (project "0.1.1"))
+;; Version: 1.0.2
+;; Package-Requires: ((emacs "26.3"))
 
 ;; This is a GNU ELPA :core package.  Avoid functionality that is not
 ;; compatible with the version of Emacs recorded above.
@@ -263,13 +263,16 @@ be found, return nil.
 
 The default implementation uses `semantic-symref-tool-alist' to
 find a search tool; by default, this uses \"find | grep\" in the
-`project-current' roots."
+current project's main and external roots."
   (mapcan
    (lambda (dir)
      (xref-references-in-directory identifier dir))
    (let ((pr (project-current t)))
      (cons
-      (project-root pr)
+      (if (fboundp 'project-root)
+          (project-root pr)
+        (with-no-warnings
+          (project-roots pr)))
       (project-external-roots pr)))))
 
 (cl-defgeneric xref-backend-apropos (backend pattern)
@@ -1281,13 +1284,13 @@ FILES must be a list of absolute file names."
         (insert (mapconcat #'identity files "\0"))
         (setq default-directory dir)
         (setq status
-              (project--process-file-region (point-min)
-                                            (point-max)
-                                            shell-file-name
-                                            output
-                                            nil
-                                            shell-command-switch
-                                            command)))
+              (xref--process-file-region (point-min)
+                                         (point-max)
+                                         shell-file-name
+                                         output
+                                         nil
+                                         shell-command-switch
+                                         command)))
       (goto-char (point-min))
       (when (and (/= (point-min) (point-max))
                  (not (looking-at grep-re))
@@ -1302,6 +1305,24 @@ FILES must be a list of absolute file names."
               hits)))
     (xref--convert-hits (nreverse hits) regexp)))
 
+(defun xref--process-file-region ( start end program
+                                   &optional buffer display
+                                   &rest args)
+  ;; FIXME: This branching shouldn't be necessary, but
+  ;; call-process-region *is* measurably faster, even for a program
+  ;; doing some actual work (for a period of time). Even though
+  ;; call-process-region also creates a temp file internally
+  ;; (http://lists.gnu.org/archive/html/emacs-devel/2019-01/msg00211.html).
+  (if (not (file-remote-p default-directory))
+      (apply #'call-process-region
+             start end program nil buffer display args)
+    (let ((infile (make-temp-file "ppfr")))
+      (unwind-protect
+          (progn
+            (write-region start end infile nil 'silent)
+            (apply #'process-file program infile buffer display args))
+        (delete-file infile)))))
+
 (defun xref--rgrep-command (regexp files dir ignores)
   (require 'find-dired)      ; for `find-name-arg'
   (defvar grep-find-template)
diff --git a/lisp/ps-def.el b/lisp/ps-def.el
index f532511..65e8011 100644
--- a/lisp/ps-def.el
+++ b/lisp/ps-def.el
@@ -58,21 +58,11 @@
 (define-obsolete-function-alias 'ps-frame-parameter #'frame-parameter "28.1")
 
 ;; Return t if the device (which can be changed during an emacs session) can
-;; handle colors.  This function is not yet implemented for GNU emacs.
+;; handle colors.
 (defun ps-color-device ()
-  (if (fboundp 'color-values)
-      (funcall 'color-values "Green")
-    t))
-
-
-(defun ps-color-values (x-color)
-  (cond
-   ((fboundp 'color-values)
-    (funcall 'color-values x-color))
-   ((fboundp 'x-color-values)
-    (funcall 'x-color-values x-color))
-   (t
-    (error "No available function to determine X color values"))))
+  (color-values "Green"))
+
+(define-obsolete-function-alias 'ps-color-values #'color-values "28.1")
 
 
 (defun ps-face-bold-p (face)
diff --git a/lisp/ps-print.el b/lisp/ps-print.el
index 17b486b..1ca4a23 100644
--- a/lisp/ps-print.el
+++ b/lisp/ps-print.el
@@ -3856,7 +3856,7 @@ It can be retrieved with `(ps-get ALIST-SYM KEY)'."
 (defun ps-color-scale (color)
   ;; Scale 16-bit X-COLOR-VALUE to PostScript color value in [0, 1] interval.
   (mapcar #'(lambda (value) (/ value ps-print-color-scale))
-         (ps-color-values color)))
+         (color-values color)))
 
 
 (defun ps-face-underlined-p (face)
@@ -5752,7 +5752,7 @@ XSTART YSTART are the relative position for the first 
page in a sheet.")
        ;; evaluated at dump-time because X isn't initialized.
        ps-color-p            (and ps-print-color-p (ps-color-device))
        ps-print-color-scale  (if ps-color-p
-                                 (float (car (ps-color-values "white")))
+                                 (float (car (color-values "white")))
                                1.0)
        ps-default-background (ps-rgb-color
                               (cond
@@ -6275,10 +6275,6 @@ If FACE is not a valid face name, use default face."
   (goto-char to))
 
 
-;; Ensure that face-list is fbound.
-(or (fboundp 'face-list) (defalias 'face-list 'list-faces))
-
-
 (defun ps-build-reference-face-lists ()
   (setq ps-print-face-alist nil)
   (if ps-auto-font-detect
diff --git a/lisp/savehist.el b/lisp/savehist.el
index fcfdb47..4e52efe 100644
--- a/lisp/savehist.el
+++ b/lisp/savehist.el
@@ -4,7 +4,7 @@
 
 ;; Author: Hrvoje Nikšić <hrvoje.niksic@avl.com>
 ;; Maintainer: emacs-devel@gnu.org
-;; Keywords: minibuffer
+;; Keywords: convenience, minibuffer
 ;; Version: 24
 
 ;; This file is part of GNU Emacs.
@@ -27,7 +27,7 @@
 ;; Many editors (e.g. Vim) have the feature of saving minibuffer
 ;; history to an external file after exit.  This package provides the
 ;; same feature in Emacs.  When set up, it saves recorded minibuffer
-;; histories to a file (`~/.emacs-history' by default).  Additional
+;; histories to a file (`~/.emacs.d/history' by default).  Additional
 ;; variables may be specified by customizing
 ;; `savehist-additional-variables'.
 
diff --git a/lisp/shell.el b/lisp/shell.el
index f5e18bb..9667dab 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -990,9 +990,6 @@ this feature; see the function `dirtrack-mode'."
       (add-hook 'comint-input-filter-functions #'shell-directory-tracker nil t)
     (remove-hook 'comint-input-filter-functions #'shell-directory-tracker t)))
 
-(define-obsolete-function-alias 'shell-dirtrack-toggle #'shell-dirtrack-mode
-  "23.1")
-
 (defun shell-cd (dir)
   "Do normal `cd' to DIR, and set `list-buffers-directory'."
   (cd dir)
@@ -1038,25 +1035,41 @@ command again."
          (accept-process-output proc)
          (goto-char pt)))
       (goto-char pmark) (delete-char 1) ; remove the extra newline
-      ;; That's the dirlist. grab it & parse it.
-      (let* ((dl (buffer-substring (match-beginning 2) (1- (match-end 2))))
-            (dl-len (length dl))
-            (ds '())                   ; new dir stack
-            (i 0))
-       (while (< i dl-len)
-         ;; regexp = optional whitespace, (non-whitespace), optional whitespace
-         (string-match "\\s *\\(\\S +\\)\\s *" dl i) ; pick off next dir
-         (setq ds (cons (concat comint-file-name-prefix
-                                (substring dl (match-beginning 1)
-                                           (match-end 1)))
-                        ds))
-         (setq i (match-end 0)))
-       (let ((ds (nreverse ds)))
-         (with-demoted-errors "Couldn't cd: %s"
-           (shell-cd (car ds))
-           (setq shell-dirstack (cdr ds)
-                 shell-last-dir (car shell-dirstack))
-           (shell-dirstack-message)))))
+      ;; That's the dirlist.  Grab it & parse it.
+      (let* ((dls (buffer-substring-no-properties
+                   (match-beginning 0) (1- (match-end 0))))
+             (dlsl nil)
+             (pos 0)
+             (ds nil))
+        ;; Split the dirlist into whitespace and non-whitespace chunks.
+        ;; dlsl will be a reversed list of tokens.
+        (while (string-match "\\(\\S-+\\|\\s-+\\)" dls pos)
+          (push (match-string 1 dls) dlsl)
+          (setq pos (match-end 1)))
+
+        ;; Prepend trailing entries until they form an existing directory,
+        ;; whitespace and all.  Discard the next whitespace and repeat.
+        (while dlsl
+          (let ((newelt "")
+                tem1 tem2)
+            (while newelt
+              ;; We need tem1 because we don't want to prepend
+              ;; `comint-file-name-prefix' repeatedly into newelt via tem2.
+              (setq tem1 (pop dlsl)
+                    tem2 (concat comint-file-name-prefix tem1 newelt))
+              (cond ((file-directory-p tem2)
+                     (push tem2 ds)
+                     (when (string= " " (car dlsl))
+                       (pop dlsl))
+                     (setq newelt nil))
+                    (t
+                     (setq newelt (concat tem1 newelt)))))))
+
+        (with-demoted-errors "Couldn't cd: %s"
+          (shell-cd (car ds))
+          (setq shell-dirstack (cdr ds)
+                shell-last-dir (car shell-dirstack))
+          (shell-dirstack-message))))
     (if started-at-pmark (goto-char (marker-position pmark)))))
 
 ;; For your typing convenience:
diff --git a/lisp/simple.el b/lisp/simple.el
index 6f72c3b..f080153 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -247,7 +247,7 @@ from which next-error navigated, and a target buffer 
TO-BUFFER."
                                                         extra-test-exclusive)
   "Try the current buffer when outside navigation.
 But return nil if we navigated to the current buffer by the means
-of `next-error' command.  Othewise, return it if it's next-error
+of `next-error' command.  Otherwise, return it if it's next-error
 capable."
   ;; Check that next-error-buffer has no buffer-local value
   ;; (i.e. we never navigated to the current buffer from another),
@@ -1323,7 +1323,9 @@ If called from Lisp, return the number of words between 
START and
 END, without printing any message."
   (interactive (list nil nil))
   (cond ((not (called-interactively-p 'any))
-        (let ((words 0))
+        (let ((words 0)
+               ;; Count across field boundaries. (Bug#41761)
+               (inhibit-field-text-motion t))
           (save-excursion
             (save-restriction
               (narrow-to-region start end)
@@ -1556,6 +1558,8 @@ in *Help* buffer.  See also the command `describe-char'."
     ;; Might as well bind TAB to completion, since inserting a TAB char is
     ;; much too rarely useful.
     (define-key m "\t" 'completion-at-point)
+    (define-key m "\r" 'read--expression-try-read)
+    (define-key m "\n" 'read--expression-try-read)
     (set-keymap-parent m minibuffer-local-map)
     m))
 
@@ -1652,8 +1656,6 @@ function `read-from-minibuffer'."
           (set-syntax-table emacs-lisp-mode-syntax-table)
           (add-hook 'completion-at-point-functions
                     #'elisp-completion-at-point nil t)
-          (local-set-key "\r" 'read--expression-try-read)
-          (local-set-key "\n" 'read--expression-try-read)
           (run-hooks 'eval-expression-minibuffer-setup-hook))
       (read-from-minibuffer prompt initial-contents
                             read-expression-map t
@@ -1845,9 +1847,15 @@ to get different commands to edit and resubmit."
             (lambda ()
               ;; Get a command name at point in the original buffer
               ;; to propose it after M-n.
-              (with-current-buffer (window-buffer (minibuffer-selected-window))
-                (and (commandp (function-called-at-point))
-                     (format "%S" (function-called-at-point)))))))
+              (let ((def (with-current-buffer
+                             (window-buffer (minibuffer-selected-window))
+                           (and (commandp (function-called-at-point))
+                                (format "%S" (function-called-at-point)))))
+                    (all (sort (minibuffer-default-add-completions)
+                                #'string<)))
+                (if def
+                    (cons def (delete def all))
+                  all)))))
     ;; Read a string, completing from and restricting to the set of
     ;; all defined commands.  Don't provide any initial input.
     ;; Save the command read on the extended-command history list.
diff --git a/lisp/so-long.el b/lisp/so-long.el
index f2c078b..f8a5cc9 100644
--- a/lisp/so-long.el
+++ b/lisp/so-long.el
@@ -255,8 +255,7 @@
 ;; `so-long-mode', completely bypassing the automated decision process.
 ;; Refer to M-: (info "(emacs) Specifying File Variables") RET
 ;;
-;; If so-long itself is causing problems, it can be inhibited by setting the
-;; `so-long-enabled' variable to nil, or by disabling the global mode with
+;; If so-long itself causes problems, disable the automated behaviour with
 ;; M-- M-x global-so-long-mode, or M-: (global-so-long-mode 0)
 
 ;; * Example configuration
@@ -282,6 +281,43 @@
 ;;           '((show-trailing-whitespace . nil)
 ;;             (truncate-lines . nil))))
 
+;; * Mode-specific configuration
+;; -----------------------------
+;; The `so-long-predicate' function is called in the context of the buffer's
+;; original major mode, and therefore major mode hooks can be used to control
+;; the criteria for calling `so-long' in any given mode (plus its derivatives)
+;; by setting buffer-local values for the variables in question.  This includes
+;; `so-long-predicate' itself, as well as any variables used by the predicate
+;; when determining the result.  By default this means `so-long-max-lines',
+;; `so-long-skip-leading-comments', and `so-long-threshold'.  E.g.:
+;;
+;;   (add-hook 'js-mode-hook 'my-js-mode-hook)
+;;
+;;   (defun my-js-mode-hook ()
+;;     "Custom `js-mode' behaviours."
+;;     (setq-local so-long-max-lines 100)
+;;     (setq-local so-long-threshold 1000))
+;;
+;; `so-long-variable-overrides' and `so-long-minor-modes' may also be given
+;; buffer-local values in order to apply different settings to different types
+;; of file.  For example, the Bidirectional Parentheses Algorithm does not 
apply
+;; to `<' and `>' characters by default, and therefore one might prefer to not
+;; set `bidi-inhibit-bpa' in XML files, on the basis that XML files with long
+;; lines are less likely to trigger BPA-related performance problems:
+;;
+;;   (add-hook 'nxml-mode-hook 'my-nxml-mode-hook)
+;;
+;;   (defun my-nxml-mode-hook ()
+;;     "Custom `nxml-mode' behaviours."
+;;     (require 'so-long)
+;;     (setq-local so-long-variable-overrides
+;;                 (remove '(bidi-inhibit-bpa . t) 
so-long-variable-overrides)))
+;;
+;; Finally, note that setting `so-long-target-modes' to nil buffer-locally in
+;; a major mode hook would prevent that mode from ever being targeted.  With
+;; `prog-mode' being targeted by default, specific derivatives of `prog-mode'
+;; could therefore be un-targeted if desired.
+
 ;; * Other ways of using so-long
 ;; -----------------------------
 ;; It may prove useful to automatically invoke major mode `so-long-mode' for
@@ -376,7 +412,6 @@
 ;;       - Added mode-line indicator, user option `so-long-mode-line-label',
 ;;         and faces `so-long-mode-line-active', `so-long-mode-line-inactive'.
 ;;       - New help commands `so-long-commentary' and `so-long-customize'.
-;;       - Renamed `so-long-mode-enabled' to `so-long-enabled'.
 ;;       - Refactored the default hook values using variable overrides
 ;;         (and returning all the hooks to nil default values).
 ;;       - Performance improvements for `so-long-detected-long-line-p'.
@@ -416,9 +451,14 @@
 (declare-function longlines-mode "longlines")
 (defvar longlines-mode)
 (defvar so-long-enabled nil
-  "Set to nil to prevent `so-long' from being triggered automatically.
-
-Has no effect if `global-so-long-mode' is not enabled.")
+  ;; This was initially a renaming of the old `so-long-mode-enabled' and
+  ;; documented as "Set to nil to prevent `so-long' from being triggered
+  ;; automatically."; however `so-long--ensure-enabled' may forcibly re-enable
+  ;; it contrary to the user's expectations, so for the present this should be
+  ;; considered internal-use only (with `global-so-long-mode' the interface
+  ;; for enabling or disabling the automated behaviour).  FIXME: Establish a
+  ;; way to support the original use-case, or rename to `so-long--enabled'.
+  "Internal use.  Non-nil when any so-long functionality has been used.")
 
 (defvar-local so-long--active nil ; internal use
   "Non-nil when `so-long' mitigations are in effect.")
@@ -886,9 +926,15 @@ buffer-local."
 Stores the existing value for each entry in `so-long-variable-overrides'.
 Stores the name of each enabled mode from the list `so-long-minor-modes'.
 
+The lists themselves are also remembered, so that major mode hooks can
+provide buffer-local modifications which are still accessible after changing
+to `so-long-mode'.
+
 If RESET is non-nil, remove any existing values before storing the new ones."
   (when reset
     (setq so-long-original-values nil))
+  (so-long-remember 'so-long-variable-overrides)
+  (so-long-remember 'so-long-minor-modes)
   (dolist (ovar so-long-variable-overrides)
     (so-long-remember (car ovar)))
   (dolist (mode so-long-minor-modes)
@@ -1288,7 +1334,7 @@ Calls `so-long-disable-minor-modes' and 
`so-long-override-variables'."
 
 (defun so-long-disable-minor-modes ()
   "Disable any active minor modes listed in `so-long-minor-modes'."
-  (dolist (mode so-long-minor-modes)
+  (dolist (mode (so-long-original 'so-long-minor-modes))
     (when (and (boundp mode) mode)
       (funcall mode 0))))
 
@@ -1304,7 +1350,7 @@ The modes are enabled in accordance with what was 
remembered in `so-long'."
 
 (defun so-long-override-variables ()
   "Set the buffer-local values defined by `so-long-variable-overrides'."
-  (dolist (ovar so-long-variable-overrides)
+  (dolist (ovar (so-long-original 'so-long-variable-overrides))
     (set (make-local-variable (car ovar)) (cdr ovar))))
 
 (defun so-long-restore-variables ()
@@ -1879,7 +1925,7 @@ If it appears in `%s', you should remove it."
 ; LocalWords:  defadvice nadvice whitespace ie bos eos eobp origmode un Un setq
 ; LocalWords:  docstring auf Wiedersehen longlines alist autoload Refactored 
Inc
 ; LocalWords:  MERCHANTABILITY RET REGEXP VAR ELPA WS mitigations EmacsWiki 
eval
-; LocalWords:  rx filename filenames bidi bpa
+; LocalWords:  rx filename filenames js defun bidi bpa prog FIXME
 
 ;; So long, farewell, auf Wiedersehen, goodbye
 ;; You have to go, this code is minified
diff --git a/lisp/speedbar.el b/lisp/speedbar.el
index e9c15b7..5b98eb36 100644
--- a/lisp/speedbar.el
+++ b/lisp/speedbar.el
@@ -3240,19 +3240,21 @@ With universal argument ARG, flush cached data."
   "Expand the line under the cursor and all descendants.
 Optional argument ARG indicates that any cache should be flushed."
   (interactive "P")
-  (speedbar-expand-line arg)
-  ;; Now, inside the area expanded here, expand all subnodes of
-  ;; the same descendant type.
-  (save-excursion
-    (speedbar-next 1) ;; Move into the list.
-    (let ((err nil))
-      (while (not err)
-       (condition-case nil
-           (progn
-             (speedbar-expand-line-descendants arg)
-             (speedbar-restricted-next 1))
-         (error (setq err t))))))
-  )
+  (save-restriction
+    (narrow-to-region (line-beginning-position)
+                      (line-beginning-position 2))
+    (speedbar-expand-line arg)
+    ;; Now, inside the area expanded here, expand all subnodes of
+    ;; the same descendant type.
+    (save-excursion
+      (speedbar-next 1) ;; Move into the list.
+      (let ((err nil))
+        (while (not err)
+         (condition-case nil
+             (progn
+               (speedbar-expand-line-descendants arg)
+               (speedbar-restricted-next 1))
+           (error (setq err t))))))))
 
 (defun speedbar-contract-line-descendants ()
   "Expand the line under the cursor and all descendants."
diff --git a/lisp/startup.el b/lisp/startup.el
index e58f27e..536a3de 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -537,6 +537,9 @@ It is the default value of the variable `top-level'."
     (setq user-emacs-directory
          (startup--xdg-or-homedot startup--xdg-config-home-emacs nil))
 
+    (when (boundp 'comp-eln-load-path)
+      (setq comp-eln-load-path (cons (concat user-emacs-directory "eln-cache/")
+                                     comp-eln-load-path)))
     ;; Look in each dir in load-path for a subdirs.el file.  If we
     ;; find one, load it, which will add the appropriate subdirs of
     ;; that dir into load-path.  This needs to be done before setting
@@ -649,11 +652,12 @@ It is the default value of the variable `top-level'."
           ;; Use FOO/., so that if FOO is a symlink, file-attributes
           ;; describes the directory linked to, not FOO itself.
           (or (and default-directory
-                   (equal (file-attributes
-                      (concat (file-name-as-directory pwd) "."))
-                     (file-attributes
-                      (concat (file-name-as-directory default-directory)
-                              "."))))
+                   (ignore-errors
+                     (equal (file-attributes
+                             (concat (file-name-as-directory pwd) "."))
+                            (file-attributes
+                             (concat (file-name-as-directory default-directory)
+                                     ".")))))
               (setq process-environment
                     (delete (concat "PWD=" pwd)
                             process-environment)))))
diff --git a/lisp/subr.el b/lisp/subr.el
index 0ae636b..093cacc 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1588,11 +1588,6 @@ be a list of the form returned by `event-start' and 
`event-end'."
 (make-obsolete 'string-as-multibyte "use `decode-coding-string'." "26.1")
 (make-obsolete 'string-make-multibyte "use `decode-coding-string'." "26.1")
 
-(defun forward-point (n)
-  "Return buffer position N characters after (before if N negative) point."
-  (declare (obsolete "use (+ (point) N) instead." "23.1"))
-  (+ (point) n))
-
 (defun log10 (x)
   "Return (log X 10), the log base 10 of X."
   (declare (obsolete log "24.4"))
@@ -1617,8 +1612,6 @@ be a list of the form returned by `event-start' and 
`event-end'."
 (make-obsolete 'set-window-redisplay-end-trigger nil "23.1")
 
 (make-obsolete 'run-window-configuration-change-hook nil "27.1")
-(make-obsolete 'process-filter-multibyte-p nil "23.1")
-(make-obsolete 'set-process-filter-multibyte nil "23.1")
 
 (make-obsolete-variable 'command-debug-status
                         "expect it to be removed in a future version." "25.2")
@@ -1661,7 +1654,8 @@ be a list of the form returned by `event-start' and 
`event-end'."
 (defalias 'point-at-eol 'line-end-position)
 (defalias 'point-at-bol 'line-beginning-position)
 
-(defalias 'user-original-login-name 'user-login-name)
+(define-obsolete-function-alias 'user-original-login-name
+  'user-login-name "28.1")
 
 
 ;;;; Hook manipulation functions.
diff --git a/lisp/t-mouse.el b/lisp/t-mouse.el
index a1af53d..4feab71 100644
--- a/lisp/t-mouse.el
+++ b/lisp/t-mouse.el
@@ -63,8 +63,6 @@
   (set-terminal-parameter nil 'gpm-mouse-active nil))
 
 ;;;###autoload
-(define-obsolete-function-alias 't-mouse-mode 'gpm-mouse-mode "23.1")
-;;;###autoload
 (define-minor-mode gpm-mouse-mode
   "Toggle mouse support in GNU/Linux consoles (GPM Mouse mode).
 
diff --git a/lisp/term.el b/lisp/term.el
index b990c83..99f1bf4 100644
--- a/lisp/term.el
+++ b/lisp/term.el
@@ -467,6 +467,11 @@ Customize this option to nil if you want the previous 
behavior."
   :type 'boolean
   :group 'term)
 
+(defcustom term-set-terminal-size nil
+  "If non-nil, set the LINES and COLUMNS environment variables."
+  :type 'boolean
+  :version "28.1")
+
 (defcustom term-char-mode-point-at-process-mark t
   "If non-nil, keep point at the process mark in char mode.
 
@@ -501,6 +506,14 @@ This variable is buffer-local."
   :type 'boolean
   :group 'term)
 
+(defcustom term-scroll-snap-to-bottom t
+  "Control whether to keep the prompt at the bottom of the window.
+If non-nil, when the prompt is visible within the window, then
+scroll so that the prompt is on the bottom on any input or
+output."
+  :version "28.1"
+  :type 'boolean)
+
 (defcustom term-scroll-show-maximum-output nil
   "Controls how interpreter output causes window to scroll.
 If non-nil, then show the maximum output when the window is scrolled.
@@ -1543,9 +1556,12 @@ Nil if unknown.")
           (format term-termcap-format "TERMCAP="
                   term-term-name term-height term-width)
 
-          (format "INSIDE_EMACS=%s,term:%s" emacs-version 
term-protocol-version)
-          (format "LINES=%d" term-height)
-          (format "COLUMNS=%d" term-width))
+          (format "INSIDE_EMACS=%s,term:%s"
+                   emacs-version term-protocol-version))
+          (when term-set-terminal-size
+            (list
+             (format "LINES=%d" term-height)
+            (format "COLUMNS=%d" term-width)))
          process-environment))
        (process-connection-type t)
        ;; We should suppress conversion of end-of-line format.
@@ -3108,15 +3124,19 @@ See `term-prompt-regexp'."
                                    (or (eq scroll 'this) (not save-point)))
                               (and (eq scroll 'others)
                                    (not (eq selected win))))
-                      (goto-char term-home-marker)
-                      (recenter 0)
+                      (when term-scroll-snap-to-bottom
+                        (goto-char term-home-marker)
+                        (recenter 0))
                       (goto-char (process-mark proc))
                       (if (not (pos-visible-in-window-p (point) win))
                           (recenter -1)))
                     ;; Optionally scroll so that the text
                     ;; ends at the bottom of the window.
                     (when (and term-scroll-show-maximum-output
-                               (>= (point) (process-mark proc)))
+                               (>= (point) (process-mark proc))
+                               (or term-scroll-snap-to-bottom
+                                   (not (pos-visible-in-window-p
+                                          (point-max) win))))
                       (save-excursion
                         (goto-char (point-max))
                         (recenter -1)))))
diff --git a/lisp/term/w32-win.el b/lisp/term/w32-win.el
index 6b9716c..f153378 100644
--- a/lisp/term/w32-win.el
+++ b/lisp/term/w32-win.el
@@ -78,12 +78,8 @@
 (require 'dnd)
 (require 'w32-vars)
 
-;; Keep an obsolete alias for w32-focus-frame and w32-select-font in case
-;; they are used by code outside Emacs.
-(define-obsolete-function-alias 'w32-focus-frame 'x-focus-frame "23.1")
 (declare-function x-select-font "w32font.c"
                   (&optional frame exclude-proportional))
-(define-obsolete-function-alias 'w32-select-font 'x-select-font "23.1")
 
 (defvar w32-color-map) ;; defined in w32fns.c
 (make-obsolete 'w32-default-color-map nil "24.1")
diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el
index 0018b89..910bd7d 100644
--- a/lisp/textmodes/bibtex.el
+++ b/lisp/textmodes/bibtex.el
@@ -3445,6 +3445,7 @@ if that value is non-nil.
   (set (make-local-variable 'syntax-propertize-function)
        (syntax-propertize-via-font-lock
         bibtex-font-lock-syntactic-keywords))
+  (bibtex-set-dialect nil t)
   ;; Allow `bibtex-dialect' as a file-local variable.
   (add-hook 'hack-local-variables-hook #'bibtex-set-dialect nil t))
 
diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el
index 39a1b48..23f96d7 100644
--- a/lisp/textmodes/flyspell.el
+++ b/lisp/textmodes/flyspell.el
@@ -57,7 +57,6 @@
 (defcustom flyspell-highlight-flag t
   "How Flyspell should indicate misspelled words.
 Non-nil means use highlight, nil means use minibuffer messages."
-  :group 'flyspell
   :type 'boolean)
 
 (defcustom flyspell-mark-duplications-flag t
@@ -65,12 +64,10 @@ Non-nil means use highlight, nil means use minibuffer 
messages."
 See `flyspell-mark-duplications-exceptions' to add exceptions to this rule.
 Detection of repeated words is not implemented in
 \"large\" regions; see variable `flyspell-large-region'."
-  :group 'flyspell
   :type 'boolean)
 
 (defcustom flyspell-case-fold-duplications t
   "Non-nil means Flyspell matches duplicate words case-insensitively."
-  :group 'flyspell
   :type 'boolean
   :version "27.1")
 
@@ -87,7 +84,6 @@ dictionary name (`ispell-local-dictionary' or
 
 EXCEPTION-LIST is a list of strings.  The checked word is
 downcased before comparing with these exceptions."
-  :group 'flyspell
   :type '(alist :key-type (choice (const :tag "All dictionaries" nil)
                                  regexp)
                :value-type (repeat string))
@@ -97,7 +93,6 @@ downcased before comparing with these exceptions."
   "If non-nil, sort the corrections before popping them.
 The sorting is controlled by the `flyspell-sort-corrections-function'
 variable, and defaults to sorting alphabetically."
-  :group 'flyspell
   :version "21.1"
   :type 'boolean)
 
@@ -109,8 +104,7 @@ function takes three parameters -- the two correction 
candidates
 to be sorted, and the third parameter is the word that's being
 corrected."
   :version "26.1"
-  :type 'function
-  :group 'flyspell)
+  :type 'function)
 
 (defun flyspell-sort-corrections-alphabetically (corr1 corr2 _)
   (string< corr1 corr2))
@@ -130,14 +124,12 @@ Flyspell uses a different face (`flyspell-duplicate') to 
highlight it.
 This variable specifies how far to search to find such a duplicate.
 -1 means no limit (search the whole buffer).
 0 means do not search for duplicate unrecognized spellings."
-  :group 'flyspell
   :version "24.5"                      ; -1 -> 400000
   :type '(choice (const :tag "no limit" -1)
                 number))
 
 (defcustom flyspell-delay 3
   "The number of seconds to wait before checking, after a \"delayed\" command."
-  :group 'flyspell
   :type 'number)
 
 (defcustom flyspell-persistent-highlight t
@@ -147,12 +139,10 @@ is highlighted, and the highlight is turned off as soon 
as point moves
 off the misspelled word.
 
 Make sure this variable is non-nil if you use `flyspell-region'."
-  :group 'flyspell
   :type 'boolean)
 
 (defcustom flyspell-highlight-properties t
   "Non-nil means highlight incorrect words even if a property exists for this 
word."
-  :group 'flyspell
   :type 'boolean)
 
 (defcustom flyspell-default-delayed-commands
@@ -164,7 +154,6 @@ Make sure this variable is non-nil if you use 
`flyspell-region'."
     backward-delete-char-untabify)
   "The standard list of delayed commands for Flyspell.
 See `flyspell-delayed-commands'."
-  :group 'flyspell
   :version "21.1"
   :type '(repeat (symbol)))
 
@@ -172,7 +161,6 @@ See `flyspell-delayed-commands'."
   "List of commands that are \"delayed\" for Flyspell mode.
 After these commands, Flyspell checking is delayed for a short time,
 whose length is specified by `flyspell-delay'."
-  :group 'flyspell
   :type '(repeat (symbol)))
 
 (defcustom flyspell-default-deplacement-commands
@@ -182,7 +170,6 @@ whose length is specified by `flyspell-delay'."
     scroll-down)
   "The standard list of deplacement commands for Flyspell.
 See variable `flyspell-deplacement-commands'."
-  :group 'flyspell
   :version "21.1"
   :type '(repeat (symbol)))
 
@@ -190,18 +177,15 @@ See variable `flyspell-deplacement-commands'."
   "List of commands that are \"deplacement\" for Flyspell mode.
 After these commands, Flyspell checking is performed only if the previous
 command was not the very same command."
-  :group 'flyspell
   :version "21.1"
   :type '(repeat (symbol)))
 
 (defcustom flyspell-issue-welcome-flag t
   "Non-nil means that Flyspell should display a welcome message when started."
-  :group 'flyspell
   :type 'boolean)
 
 (defcustom flyspell-issue-message-flag t
   "Non-nil means that Flyspell emits messages when checking words."
-  :group 'flyspell
   :type 'boolean)
 
 (defcustom flyspell-incorrect-hook nil
@@ -213,7 +197,6 @@ of possible corrections as returned by 
`ispell-parse-output'.
 
 If any of the functions return non-nil, the word is not highlighted as
 incorrect."
-  :group 'flyspell
   :version "21.1"
   :type 'hook)
 
@@ -225,14 +208,12 @@ when flyspell is started, the value of that variable is 
used instead
 of `flyspell-default-dictionary' to select the default dictionary.
 Otherwise, if `flyspell-default-dictionary' is nil, it means to use
 Ispell's ultimate default dictionary."
-  :group 'flyspell
   :version "21.1"
   :type '(choice string (const :tag "Default" nil)))
 
 (defcustom flyspell-tex-command-regexp
   "\\(\\(begin\\|end\\)[ 
\t]*{\\|\\(cite[a-z*]*\\|label\\|ref\\|eqref\\|usepackage\\|documentclass\\)[ 
\t]*\\(\\[[^]]*\\]\\)?{[^{}]*\\)"
   "A string that is the regular expression that matches TeX commands."
-  :group 'flyspell
   :version "21.1"
   :type 'regexp)
 
@@ -241,34 +222,29 @@ Ispell's ultimate default dictionary."
 TeX math environments are discovered by `texmathp', implemented
 inside AUCTeX package.  That package may be found at
 URL `https://www.gnu.org/software/auctex/'"
-  :group 'flyspell
   :type 'boolean)
 
 (defcustom flyspell-dictionaries-that-consider-dash-as-word-delimiter
   '("francais" "deutsch8" "norsk")
   "List of dictionary names that consider `-' as word delimiter."
-  :group 'flyspell
   :version "21.1"
   :type '(repeat (string)))
 
 (defcustom flyspell-abbrev-p
   nil
   "If non-nil, add correction to abbreviation table."
-  :group 'flyspell
   :version "21.1"
   :type 'boolean)
 
 (defcustom flyspell-use-global-abbrev-table-p
   nil
   "If non-nil, prefer global abbrev table to local abbrev table."
-  :group 'flyspell
   :version "21.1"
   :type 'boolean)
 
 (defcustom flyspell-mode-line-string " Fly"
   "String displayed on the mode line when flyspell is active.
 Set this to nil if you don't want a mode line indicator."
-  :group 'flyspell
   :type '(choice string (const :tag "None" nil)))
 
 (defcustom flyspell-large-region 1000
@@ -282,30 +258,25 @@ Doubled words are not detected in a large region, because 
Ispell
 does not check for them.
 
 If this variable is nil, all regions are treated as small."
-  :group 'flyspell
   :version "21.1"
   :type '(choice number (const :tag "All small" nil)))
 
 (defcustom flyspell-insert-function (function insert)
   "Function for inserting word by flyspell upon correction."
-  :group 'flyspell
   :type 'function)
 
 (defcustom flyspell-before-incorrect-word-string nil
   "String used to indicate an incorrect word starting."
-  :group 'flyspell
   :type '(choice string (const nil)))
 
 (defcustom flyspell-after-incorrect-word-string nil
   "String used to indicate an incorrect word ending."
-  :group 'flyspell
   :type '(choice string (const nil)))
 
 (defvar flyspell-mode-map)
 
 (defcustom flyspell-use-meta-tab t
   "Non-nil means that flyspell uses M-TAB to correct word."
-  :group 'flyspell
   :type 'boolean
   :initialize 'custom-initialize-default
   :set (lambda (sym val)
@@ -316,8 +287,7 @@ If this variable is nil, all regions are treated as small."
 (defcustom flyspell-auto-correct-binding
   [(control ?\;)]
   "The key binding for flyspell auto correction."
-  :type 'key-sequence
-  :group 'flyspell)
+  :type 'key-sequence)
 
 ;;*---------------------------------------------------------------------*/
 ;;*    Mode specific options                                            */
@@ -475,6 +445,22 @@ like <img alt=\"Some thing.\">."
     map)
   "Minor mode keymap for Flyspell mode--for the whole buffer.")
 
+;; correct on mouse 3
+(defun flyspell--set-use-mouse-3-for-menu (var value)
+  (set-default var value)
+  (if value
+      (progn (define-key flyspell-mouse-map [mouse-2] nil)
+             (define-key flyspell-mouse-map [down-mouse-3] 
'flyspell-correct-word))
+    (define-key flyspell-mouse-map [mouse-2] 'flyspell-correct-word)
+    (define-key flyspell-mouse-map [down-mouse-3] nil)))
+
+(defcustom flyspell-use-mouse-3-for-menu nil
+  "Non-nil means to bind `mouse-3' to `flyspell-correct-word'.
+If this is set, also unbind `mouse-2'."
+  :type 'boolean
+  :set 'flyspell--set-use-mouse-3-for-menu
+  :version "28.1")
+
 ;; dash character machinery
 (defvar flyspell-consider-dash-as-word-delimiter-flag nil
   "Non-nil means that the `-' char is considered as a word delimiter.")
@@ -493,8 +479,7 @@ like <img alt=\"Some thing.\">."
     (t
      :underline t :inherit error))
   "Flyspell face for misspelled words."
-  :version "24.4"
-  :group 'flyspell)
+  :version "24.4")
 
 (defface flyspell-duplicate
   '((((supports :underline (:style wave)))
@@ -503,8 +488,7 @@ like <img alt=\"Some thing.\">."
      :underline t :inherit warning))
   "Flyspell face for words that appear twice in a row.
 See also `flyspell-duplicate-distance'."
-  :version "24.4"
-  :group 'flyspell)
+  :version "24.4")
 
 (defvar flyspell-overlay nil)
 
@@ -546,7 +530,10 @@ in your init file.
   :group 'flyspell
   (if flyspell-mode
       (condition-case err
-         (flyspell-mode-on)
+          (progn
+            (when flyspell-use-mouse-3-for-menu
+              (flyspell--set-use-mouse-3-for-menu 
'flyspell-use-mouse-3-for-menu t))
+           (flyspell-mode-on))
        (error (message "Error enabling Flyspell mode:\n%s" (cdr err))
               (flyspell-mode -1)))
     (flyspell-mode-off)))
diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el
index 65f6164..b2ccbc8 100644
--- a/lisp/textmodes/ispell.el
+++ b/lisp/textmodes/ispell.el
@@ -621,15 +621,6 @@ For Aspell, non-nil also means to try to automatically 
find its dictionaries.
 Earlier Aspell versions do not consistently support charset encoding.  Handling
 this would require some extra guessing in `ispell-aspell-find-dictionary'.")
 
-(defvar ispell-aspell-supports-utf8 nil
-  "Non-nil if Aspell has consistent command line UTF-8 support.  Obsolete.
-ispell.el and flyspell.el will use for this purpose the more generic
-variable `ispell-encoding8-command' for both Aspell and Hunspell.  Is left
-here just for backwards compatibility.")
-
-(make-obsolete-variable 'ispell-aspell-supports-utf8
-                        'ispell-encoding8-command "23.1")
-
 (defvar ispell-dicts-name2locale-equivs-alist
   '(("american"      "en_US")
     ("brasileiro"    "pt_BR")
@@ -682,9 +673,7 @@ Otherwise returns the library directory name, if that is 
defined."
   ;; all versions, since versions earlier than 3.0.09 didn't identify
   ;; themselves on startup.
   (interactive "p")
-  (let ((default-directory (or (and (boundp 'temporary-file-directory)
-                                   temporary-file-directory)
-                              default-directory))
+  (let ((default-directory (or temporary-file-directory default-directory))
        (get-config-var
         (lambda (var)
           (when (re-search-forward
@@ -3734,8 +3723,7 @@ looking for a dictionary, please see the distribution of 
the GNU ispell
 program, or do an Internet search; there are various dictionaries
 available on the net."
   (interactive)
-  (if (and (boundp 'transient-mark-mode) transient-mark-mode
-          (boundp 'mark-active) mark-active)
+  (if (and transient-mark-mode mark-active)
       (ispell-region (region-beginning) (region-end))
     (ispell-buffer)))
 
diff --git a/lisp/textmodes/remember.el b/lisp/textmodes/remember.el
index 279dbb4..7bc7dc1 100644
--- a/lisp/textmodes/remember.el
+++ b/lisp/textmodes/remember.el
@@ -487,9 +487,6 @@ Most useful for remembering things from other applications."
   (interactive)
   (remember-region (point-min) (point-max)))
 
-;; Org needs this
-(define-obsolete-function-alias 'remember-buffer 'remember-finalize "23.1")
-
 (defun remember-destroy ()
   "Destroy the current *Remember* buffer."
   (interactive)
diff --git a/lisp/thingatpt.el b/lisp/thingatpt.el
index 483a2c9..3c2d766 100644
--- a/lisp/thingatpt.el
+++ b/lisp/thingatpt.el
@@ -258,7 +258,7 @@ E.g.:
 
 ;;  Filenames
 
-(defvar thing-at-point-file-name-chars "-~/[:alnum:]_.${}#%,:"
+(defvar thing-at-point-file-name-chars "-@~/[:alnum:]_.${}#%,:"
   "Characters allowable in filenames.")
 
 (define-thing-chars filename thing-at-point-file-name-chars)
diff --git a/lisp/time.el b/lisp/time.el
index 44fd1a7..96b49dd 100644
--- a/lisp/time.el
+++ b/lisp/time.el
@@ -25,8 +25,7 @@
 ;; Facilities to display current time/date and a new-mail indicator
 ;; in the Emacs mode line.  The entry point is `display-time'.
 
-;; Display time world in a buffer, the entry point is
-;; `display-time-world'.
+;; Use `world-clock' to display world clock in a buffer.
 
 ;;; Code:
 
@@ -35,23 +34,20 @@
   :group 'mode-line
   :group 'mail)
 
-
 (defcustom display-time-mail-file nil
   "File name of mail inbox file, for indicating existence of new mail.
 Non-nil and not a string means don't check for mail; nil means use
 default, which is system-dependent, and is the same as used by Rmail."
   :type '(choice (const :tag "None" none)
                 (const :tag "Default" nil)
-                (file :format "%v"))
-  :group 'display-time)
+                (file :format "%v")))
 
 (defcustom display-time-mail-directory nil
   "Name of mail inbox directory, for indicating existence of new mail.
 Any nonempty regular file in the directory is regarded as newly arrived mail.
 If nil, do not check a directory for arriving mail."
   :type '(choice (const :tag "None" nil)
-                (directory :format "%v"))
-  :group 'display-time)
+                (directory :format "%v")))
 
 (defcustom display-time-mail-function nil
   "Function to call, for indicating existence of new mail.
@@ -59,8 +55,7 @@ If nil, that means use the default method: check that the file
 specified by `display-time-mail-file' is nonempty or that the
 directory `display-time-mail-directory' contains nonempty files."
   :type '(choice (const :tag "Default" nil)
-                (function))
-  :group 'display-time)
+                (function)))
 
 (defcustom display-time-default-load-average 0
   "Which load average value will be shown in the mode line.
@@ -75,8 +70,7 @@ The value can be one of:
   :type '(choice (const :tag "1 minute load" 0)
                 (const :tag "5 minutes load" 1)
                 (const :tag "15 minutes load" 2)
-                (const :tag "None" nil))
-  :group 'display-time)
+                (const :tag "None" nil)))
 
 (defvar display-time-load-average nil
   "Value of the system's load average currently shown on the mode line.
@@ -86,27 +80,23 @@ This is an internal variable; setting it has no effect.")
 
 (defcustom display-time-load-average-threshold 0.1
   "Load-average values below this value won't be shown in the mode line."
-  :type 'number
-  :group 'display-time)
+  :type 'number)
 
 ;;;###autoload
 (defcustom display-time-day-and-date nil "\
 Non-nil means \\[display-time] should display day and date as well as time."
-  :type 'boolean
-  :group 'display-time)
+  :type 'boolean)
 
 (defvar display-time-timer nil)
 
 (defcustom display-time-interval 60
   "Seconds between updates of time in the mode line."
-  :type 'integer
-  :group 'display-time)
+  :type 'integer)
 
 (defcustom display-time-24hr-format nil
   "Non-nil indicates time should be displayed as hh:mm, 0 <= hh <= 23.
 A value of nil means 1 <= hh <= 12, and an AM/PM suffix is used."
-  :type 'boolean
-  :group 'display-time)
+  :type 'boolean)
 
 (defvar display-time-string nil
   "String used in mode lines to display a time string.
@@ -116,103 +106,12 @@ It should not be set directly, but is instead updated by 
the
 
 (defcustom display-time-hook nil
   "List of functions to be called when the time is updated on the mode line."
-  :type 'hook
-  :group 'display-time)
+  :type 'hook)
 
 (defvar display-time-server-down-time nil
    "Time when mail file's file system was recorded to be down.
 If that file system seems to be up, the value is nil.")
 
-(defcustom zoneinfo-style-world-list
-  '(("America/Los_Angeles" "Seattle")
-    ("America/New_York" "New York")
-    ("Europe/London" "London")
-    ("Europe/Paris" "Paris")
-    ("Asia/Calcutta" "Bangalore")
-    ("Asia/Tokyo" "Tokyo"))
-  "Alist of zoneinfo-style time zones and places for `display-time-world'.
-Each element has the form (TIMEZONE LABEL).
-TIMEZONE should be a string of the form AREA/LOCATION, where AREA is
-the name of a region -- a continent or ocean, and LOCATION is the name
-of a specific location, e.g., a city, within that region.
-LABEL is a string to display as the label of that TIMEZONE's time."
-  :group 'display-time
-  :type '(repeat (list string string))
-  :version "23.1")
-
-(defcustom legacy-style-world-list
-  '(("PST8PDT" "Seattle")
-    ("EST5EDT" "New York")
-    ("GMT0BST" "London")
-    ("CET-1CDT" "Paris")
-    ("IST-5:30" "Bangalore")
-    ("JST-9" "Tokyo"))
-  "Alist of traditional-style time zones and places for `display-time-world'.
-Each element has the form (TIMEZONE LABEL).
-TIMEZONE should be a string of the form:
-
-     std[+|-]offset[dst[offset][,date[/time],date[/time]]]
-
-See the documentation of the TZ environment variable on your system,
-for more details about the format of TIMEZONE.
-LABEL is a string to display as the label of that TIMEZONE's time."
-  :group 'display-time
-  :type '(repeat (list string string))
-  :version "23.1")
-
-(defcustom display-time-world-list t
-  "Alist of time zones and places for `display-time-world' to display.
-Each element has the form (TIMEZONE LABEL).
-TIMEZONE should be in a format supported by your system.  See the
-documentation of `zoneinfo-style-world-list' and
-`legacy-style-world-list' for two widely used formats.  LABEL is
-a string to display as the label of that TIMEZONE's time.
-
-If the value is t instead of an alist, use the value of
-`zoneinfo-style-world-list' if it works on this platform, and of
-`legacy-style-world-list' otherwise."
-
-  :group 'display-time
-  :type '(choice (const :tag "Default" t)
-                 (repeat :tag "List of zones and labels"
-                         (list (string :tag "Zone") (string :tag "Label"))))
-  :version "23.1")
-
-(defun time--display-world-list ()
-  (if (listp display-time-world-list)
-      display-time-world-list
-    ;; Determine if zoneinfo style timezones are supported by testing that
-    ;; America/New York and Europe/London return different timezones.
-    (let ((nyt (format-time-string "%z" nil "America/New_York"))
-         (gmt (format-time-string "%z" nil "Europe/London")))
-      (if (string-equal nyt gmt)
-         legacy-style-world-list
-       zoneinfo-style-world-list))))
-
-(defcustom display-time-world-time-format "%A %d %B %R %Z"
-  "Format of the time displayed, see `format-time-string'."
-  :group 'display-time
-  :type 'string
-  :version "23.1")
-
-(defcustom display-time-world-buffer-name "*wclock*"
-  "Name of the world clock buffer."
-  :group 'display-time
-  :type 'string
-  :version "23.1")
-
-(defcustom display-time-world-timer-enable t
-  "If non-nil, a timer will update the world clock."
-  :group 'display-time
-  :type 'boolean
-  :version "23.1")
-
-(defcustom display-time-world-timer-second 60
-  "Interval in seconds for updating the world clock."
-  :group 'display-time
-  :type 'integer
-  :version "23.1")
-
 ;;;###autoload
 (defun display-time ()
   "Enable display of time, load level, and mail flag in mode lines.
@@ -249,14 +148,12 @@ See `display-time-use-mail-icon' and 
`display-time-mail-face'.")
   "Non-nil means use an icon as mail indicator on a graphic display.
 Otherwise use `display-time-mail-string'.  The icon may consume less
 of the mode line.  It is specified by `display-time-mail-icon'."
-  :group 'display-time
   :type 'boolean)
 
 ;; Fixme: maybe default to the character if we can display Unicode.
 (defcustom display-time-mail-string "Mail"
   "String to use as the mail indicator in `display-time-string-forms'.
 This can use the Unicode letter character if you can display it."
-  :group 'display-time
   :version "22.1"
   :type '(choice (const "Mail")
                 ;; Use :tag here because the Lucid menu won't display
@@ -270,8 +167,7 @@ See the function `format-time-string' for an explanation of
 how to write this string.  If this is nil, the defaults
 depend on `display-time-day-and-date' and `display-time-24hr-format'."
   :type '(choice (const :tag "Default" nil)
-                string)
-  :group 'display-time)
+                string))
 
 (defcustom display-time-string-forms
   '((if (and (not display-time-format) display-time-day-and-date)
@@ -325,8 +221,7 @@ For example:
     (if mail \" Mail\" \"\"))
 
 would give mode line times like `94/12/30 21:07:48 (UTC)'."
-  :type '(repeat sexp)
-  :group 'display-time)
+  :type '(repeat sexp))
 
 (defun display-time-event-handler ()
   (display-time-update)
@@ -508,13 +403,129 @@ runs the normal hook `display-time-hook' after each 
update."
     (remove-hook 'rmail-after-get-new-mail-hook
                 'display-time-event-handler)))
 
+
+;;; Obsolete names
+
+(define-obsolete-variable-alias 'display-time-world-list
+  'world-clock-list "28.1")
+(define-obsolete-variable-alias 'display-time-world-time-format
+  'world-clock-time-format "28.1")
+(define-obsolete-variable-alias 'display-time-world-buffer-name
+  'world-clock-buffer-name "28.1")
+(define-obsolete-variable-alias 'display-time-world-timer-enable
+  'world-clock-timer-enable "28.1")
+(define-obsolete-variable-alias 'display-time-world-timer-second
+  'world-clock-timer-second "28.1")
+
+(define-obsolete-function-alias 'display-time-world-mode
+  #'world-clock-mode "28.1")
+(define-obsolete-function-alias 'display-time-world-display
+  #'world-clock-display "28.1")
+(define-obsolete-function-alias 'display-time-world
+  #'world-clock "28.1")
+(define-obsolete-function-alias 'display-time-world-timer
+  #'world-clock-update "28.1")
+
+
+;;; World clock
+
+(defgroup world-clock nil
+  "Display a world clock."
+  :group 'display-time)
+
+(defcustom zoneinfo-style-world-list
+  '(("America/Los_Angeles" "Seattle")
+    ("America/New_York" "New York")
+    ("Europe/London" "London")
+    ("Europe/Paris" "Paris")
+    ("Asia/Calcutta" "Bangalore")
+    ("Asia/Tokyo" "Tokyo"))
+  "Alist of zoneinfo-style time zones and places for `world-clock'.
+Each element has the form (TIMEZONE LABEL).
+TIMEZONE should be a string of the form AREA/LOCATION, where AREA is
+the name of a region -- a continent or ocean, and LOCATION is the name
+of a specific location, e.g., a city, within that region.
+LABEL is a string to display as the label of that TIMEZONE's time."
+  :type '(repeat (list string string))
+  :version "23.1")
+
+(defcustom legacy-style-world-list
+  '(("PST8PDT" "Seattle")
+    ("EST5EDT" "New York")
+    ("GMT0BST" "London")
+    ("CET-1CDT" "Paris")
+    ("IST-5:30" "Bangalore")
+    ("JST-9" "Tokyo"))
+  "Alist of traditional-style time zones and places for `world-clock'.
+Each element has the form (TIMEZONE LABEL).
+TIMEZONE should be a string of the form:
+
+     std[+|-]offset[dst[offset][,date[/time],date[/time]]]
+
+See the documentation of the TZ environment variable on your system,
+for more details about the format of TIMEZONE.
+LABEL is a string to display as the label of that TIMEZONE's time."
+  :type '(repeat (list string string))
+  :version "23.1")
+
+(defcustom world-clock-list t
+  "Alist of time zones and places for `world-clock' to display.
+Each element has the form (TIMEZONE LABEL).
+TIMEZONE should be in a format supported by your system.  See the
+documentation of `zoneinfo-style-world-list' and
+`legacy-style-world-list' for two widely used formats.  LABEL is
+a string to display as the label of that TIMEZONE's time.
+
+If the value is t instead of an alist, use the value of
+`zoneinfo-style-world-list' if it works on this platform, and of
+`legacy-style-world-list' otherwise."
+  :type '(choice (const :tag "Default" t)
+                 (repeat :tag "List of zones and labels"
+                         (list (string :tag "Zone") (string :tag "Label"))))
+  :version "28.1")
+
+(defun time--display-world-list ()
+  (if (listp world-clock-list)
+      world-clock-list
+    ;; Determine if zoneinfo style timezones are supported by testing that
+    ;; America/New York and Europe/London return different timezones.
+    (let ((nyt (format-time-string "%z" nil "America/New_York"))
+         (gmt (format-time-string "%z" nil "Europe/London")))
+      (if (string-equal nyt gmt)
+         legacy-style-world-list
+       zoneinfo-style-world-list))))
+
+(defcustom world-clock-time-format "%A %d %B %R %Z"
+  "Time format for `world-clock', see `format-time-string'."
+  :type 'string
+  :version "28.1")
+
+(defcustom world-clock-buffer-name "*wclock*"
+  "Name of the `world-clock' buffer."
+  :type 'string
+  :version "28.1")
+
+(defcustom world-clock-timer-enable t
+  "If non-nil, a timer will update the `world-clock' buffer."
+  :type 'boolean
+  :version "28.1")
+
+(defcustom world-clock-timer-second 60
+  "Interval in seconds for updating the `world-clock' buffer."
+  :type 'integer
+  :version "28.1")
+
+(defface world-clock-label
+  '((t :inherit font-lock-variable-name-face))
+  "Face for time zone label in `world-clock' buffer.")
 
-(define-derived-mode display-time-world-mode special-mode "World clock"
+(define-derived-mode world-clock-mode special-mode "World clock"
   "Major mode for buffer that displays times in various time zones.
-See `display-time-world'."
+See `world-clock'."
+  (setq revert-buffer-function #'world-clock-update)
   (setq show-trailing-whitespace nil))
 
-(defun display-time-world-display (alist)
+(defun world-clock-display (alist)
   "Replace current buffer text with times in various zones, based on ALIST."
   (let ((inhibit-read-only t)
        (buffer-undo-list t)
@@ -526,42 +537,45 @@ See `display-time-world'."
       (let* ((label (cadr zone))
             (width (string-width label)))
        (push (cons label
-                   (format-time-string display-time-world-time-format
+                   (format-time-string world-clock-time-format
                                        now (car zone)))
              result)
        (when (> width max-width)
          (setq max-width width))))
     (setq fmt (concat "%-" (int-to-string max-width) "s %s\n"))
     (dolist (timedata (nreverse result))
-      (insert (format fmt (car timedata) (cdr timedata))))
+      (insert (format fmt
+                      (propertize (car timedata)
+                                  'face 'world-clock-label)
+                      (cdr timedata))))
     (delete-char -1))
   (goto-char (point-min)))
 
 ;;;###autoload
-(defun display-time-world ()
-  "Enable updating display of times in various time zones.
-`display-time-world-list' specifies the zones.
-To turn off the world time display, go to that window and type `q'."
+(defun world-clock ()
+  "Display a world clock buffer with times in various time zones.
+The variable `world-clock-list' specifies which time zones to use.
+To turn off the world time display, go to the window and type 
`\\[quit-window]'."
   (interactive)
-  (when (and display-time-world-timer-enable
-             (not (get-buffer display-time-world-buffer-name)))
-    (run-at-time t display-time-world-timer-second 'display-time-world-timer))
-  (with-current-buffer (get-buffer-create display-time-world-buffer-name)
-    (display-time-world-display (time--display-world-list))
-    (display-buffer display-time-world-buffer-name
-                   (cons nil '((window-height . fit-window-to-buffer))))
-    (display-time-world-mode)))
-
-(defun display-time-world-timer ()
-  (if (get-buffer display-time-world-buffer-name)
-      (with-current-buffer (get-buffer display-time-world-buffer-name)
-        (display-time-world-display (time--display-world-list)))
+  (when (and world-clock-timer-enable
+             (not (get-buffer world-clock-buffer-name)))
+    (run-at-time t world-clock-timer-second #'world-clock-update))
+  (pop-to-buffer world-clock-buffer-name)
+  (world-clock-display (time--display-world-list))
+  (world-clock-mode)
+  (fit-window-to-buffer))
+
+(defun world-clock-update (&optional _arg _noconfirm)
+  "Update the `world-clock' buffer."
+  (if (get-buffer world-clock-buffer-name)
+      (with-current-buffer (get-buffer world-clock-buffer-name)
+        (world-clock-display (time--display-world-list)))
     ;; cancel timer
     (let ((list timer-list))
       (while list
         (let ((elt (pop list)))
           (when (equal (symbol-name (timer--function elt))
-                      "display-time-world-timer")
+                      "world-clock-update")
             (cancel-timer elt)))))))
 
 ;;;###autoload
diff --git a/lisp/tooltip.el b/lisp/tooltip.el
index f35f6b9..5f5a478 100644
--- a/lisp/tooltip.el
+++ b/lisp/tooltip.el
@@ -167,8 +167,6 @@ This variable has effect only on GUI frames."
 
 ;;; Variables that are not customizable.
 
-(define-obsolete-variable-alias 'tooltip-hook 'tooltip-functions "23.1")
-
 (defvar tooltip-functions nil
   "Functions to call to display tooltips.
 Each function is called with one argument EVENT which is a copy
diff --git a/lisp/url/url-expand.el b/lisp/url/url-expand.el
index f34ef81..be9b542 100644
--- a/lisp/url/url-expand.el
+++ b/lisp/url/url-expand.el
@@ -120,7 +120,7 @@ path components followed by `..' are removed, along with 
the `..' itself."
       ;; Well, they told us the scheme, let's just go with it.
       nil
     (setf (url-type urlobj) (or (url-type urlobj) (url-type defobj)))
-    (setf (url-port urlobj) (or (url-portspec urlobj)
+    (setf (url-portspec urlobj) (or (url-portspec urlobj)
                                 (and (string= (url-type urlobj)
                                               (url-type defobj))
                                     (url-port defobj))))
diff --git a/lisp/url/url-util.el b/lisp/url/url-util.el
index 6dd7a9c..0a7e7e2 100644
--- a/lisp/url/url-util.el
+++ b/lisp/url/url-util.el
@@ -569,31 +569,6 @@ Has a preference for looking backward when not directly on 
a symbol."
          (setq url nil))
       url)))
 
-(defun url-generate-unique-filename (&optional fmt)
-  "Generate a unique filename in `url-temporary-directory'."
-  (declare (obsolete make-temp-file "23.1"))
-  ;; This variable is obsolete, but so is this function.
-  (let ((tempdir (with-no-warnings url-temporary-directory)))
-    (if (not fmt)
-       (let ((base (format "url-tmp.%d" (user-real-uid)))
-             (fname "")
-             (x 0))
-         (setq fname (format "%s%d" base x))
-         (while (file-exists-p
-                 (expand-file-name fname tempdir))
-           (setq x (1+ x)
-                 fname (concat base (int-to-string x))))
-         (expand-file-name fname tempdir))
-      (let ((base (concat "url" (int-to-string (user-real-uid))))
-           (fname "")
-           (x 0))
-       (setq fname (format fmt (concat base (int-to-string x))))
-       (while (file-exists-p
-               (expand-file-name fname tempdir))
-         (setq x (1+ x)
-               fname (format fmt (concat base (int-to-string x)))))
-       (expand-file-name fname tempdir)))))
-
 (defun url-extract-mime-headers ()
   "Set `url-current-mime-headers' in current buffer."
   (save-excursion
diff --git a/lisp/url/url-vars.el b/lisp/url/url-vars.el
index d9277cf..e35823a 100644
--- a/lisp/url/url-vars.el
+++ b/lisp/url/url-vars.el
@@ -312,13 +312,6 @@ Applies when a protected document is denied by the server."
   :type 'integer
   :group 'url)
 
-(defcustom url-temporary-directory (or (getenv "TMPDIR") "/tmp")
-  "Where temporary files go."
-  :type 'directory
-  :group 'url-file)
-(make-obsolete-variable 'url-temporary-directory
-                       'temporary-file-directory "23.1")
-
 (defcustom url-show-status t
   "Whether to show a running total of bytes transferred.
 Can cause a large hit if using a remote X display over a slow link, or
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index d194d6c..bd5ac9b 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -2518,7 +2518,7 @@ fixed, visit it in a buffer."
                                '((?+ . (left-fringe diff-fringe-add 
diff-indicator-added))
                                  (?- . (left-fringe diff-fringe-del 
diff-indicator-removed))
                                  (?! . (left-fringe diff-fringe-rep 
diff-indicator-changed))
-                                 (?\s . (left-fringe diff-fringe-nul))))))
+                                 (?\s . (left-fringe diff-fringe-nul 
fringe))))))
           (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.
diff --git a/lisp/vc/ediff-init.el b/lisp/vc/ediff-init.el
index f5177bc..04926af 100644
--- a/lisp/vc/ediff-init.el
+++ b/lisp/vc/ediff-init.el
@@ -1573,9 +1573,8 @@ This default should work without changes."
 
 
 (defun ediff-convert-standard-filename (fname)
-  (if (fboundp 'convert-standard-filename)
-      (convert-standard-filename fname)
-    fname))
+  (declare (obsolete convert-standard-filename "28.1"))
+  (convert-standard-filename fname))
 
 (define-obsolete-function-alias 'ediff-with-syntax-table
   #'with-syntax-table "27.1")
diff --git a/lisp/vc/ediff-util.el b/lisp/vc/ediff-util.el
index 4a84c1e..f56d31c 100644
--- a/lisp/vc/ediff-util.el
+++ b/lisp/vc/ediff-util.el
@@ -240,18 +240,16 @@ to invocation.")
                             startup-hooks setup-parameters
                             &optional merge-buffer-file)
   (run-hooks 'ediff-before-setup-hook)
-  ;; ediff-convert-standard-filename puts file names in the form appropriate
+  ;; convert-standard-filename puts file names in the form appropriate
   ;; for the OS at hand.
-  (setq file-A (ediff-convert-standard-filename (expand-file-name file-A)))
-  (setq file-B (ediff-convert-standard-filename (expand-file-name file-B)))
+  (setq file-A (convert-standard-filename (expand-file-name file-A)))
+  (setq file-B (convert-standard-filename (expand-file-name file-B)))
   (if (stringp file-C)
-      (setq file-C
-           (ediff-convert-standard-filename (expand-file-name file-C))))
+      (setq file-C (convert-standard-filename (expand-file-name file-C))))
   (if (stringp merge-buffer-file)
       (progn
        (setq merge-buffer-file
-             (ediff-convert-standard-filename
-              (expand-file-name merge-buffer-file)))
+             (convert-standard-filename (expand-file-name merge-buffer-file)))
        ;; check the directory exists
        (or (file-exists-p (file-name-directory merge-buffer-file))
            (error "Directory %s given as place to save the merge doesn't exist"
@@ -3069,10 +3067,8 @@ Hit \\[ediff-recenter] to reset the windows afterward."
 
 
 ;; for compatibility
-(defmacro ediff-minibuffer-with-setup-hook (fun &rest body)
-  `(if (fboundp 'minibuffer-with-setup-hook)
-       (minibuffer-with-setup-hook ,fun ,@body)
-     ,@body))
+(define-obsolete-function-alias 'ediff-minibuffer-with-setup-hook
+  #'minibuffer-with-setup-hook "28.1")
 
 ;; This is adapted from a similar function in `emerge.el'.
 ;; PROMPT should not have a trailing ': ', so that it can be modified
@@ -3101,7 +3097,7 @@ Hit \\[ediff-recenter] to reset the windows afterward."
                        (and default-file (list default-file))
                        default-dir)))
        f)
-    (setq f (ediff-minibuffer-with-setup-hook
+    (setq f (minibuffer-with-setup-hook
                (lambda () (when defaults
                             (setq minibuffer-default defaults)))
              (read-file-name
@@ -3134,7 +3130,7 @@ Hit \\[ediff-recenter] to reset the windows afterward."
 ;; Also, save buffer from START to END in the file.
 ;; START defaults to (point-min), END to (point-max)
 (defun ediff-make-temp-file (buff &optional prefix given-file start end)
-  (let* ((p (ediff-convert-standard-filename (or prefix "ediff")))
+  (let* ((p (convert-standard-filename (or prefix "ediff")))
         (short-p p)
         (coding-system-for-write ediff-coding-system-for-write)
         f short-f)
diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el
index 78a2fa0..84aeb0a 100644
--- a/lisp/vc/vc-git.el
+++ b/lisp/vc/vc-git.el
@@ -210,6 +210,16 @@ toggle display of the entire list."
                               widget))))
   :version "27.1")
 
+(defcustom vc-git-revision-complete-only-branches nil
+  "Control whether tags are returned by revision completion for Git.
+
+When non-nil, only branches and remotes will be returned by
+`vc-git-revision-completion-table'.  This is used by various VC
+commands when completing branch names.  When nil, tags are also
+included in the completions."
+  :type 'boolean
+  :version "28.1")
+
 ;; History of Git commands.
 (defvar vc-git-history nil)
 
@@ -1415,9 +1425,11 @@ This requires git 1.8.4 or later, for the \"-L\" option 
of \"git log\"."
     (with-temp-buffer
       (vc-git-command t nil nil "for-each-ref" "--format=%(refname)")
       (goto-char (point-min))
-      (while (re-search-forward "^refs/\\(heads\\|tags\\|remotes\\)/\\(.*\\)$"
-                                nil t)
-        (push (match-string 2) table)))
+      (let ((regexp (if vc-git-revision-complete-only-branches
+                        "^refs/\\(heads\\|remotes\\)/\\(.*\\)$"
+                      "^refs/\\(heads\\|tags\\|remotes\\)/\\(.*\\)$")))
+        (while (re-search-forward regexp nil t)
+          (push (match-string 2) table))))
     table))
 
 (defun vc-git-revision-completion-table (files)
diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el
index ce72a49..f09cedd 100644
--- a/lisp/vc/vc-hooks.el
+++ b/lisp/vc/vc-hooks.el
@@ -505,14 +505,6 @@ If FILE is not registered, this function always returns 
nil."
                            (vc-call-backend
                             backend 'working-revision file))))))
 
-;; Backward compatibility.
-(define-obsolete-function-alias
-  'vc-workfile-version 'vc-working-revision "23.1")
-(defun vc-default-working-revision (backend file)
-  (message
-   "`working-revision' not found: using the old `workfile-version' instead")
-  (vc-call-backend backend 'workfile-version file))
-
 (defun vc-default-registered (backend file)
   "Check if FILE is registered in BACKEND using vc-BACKEND-master-templates."
   (let ((sym (vc-make-backend-sym backend 'master-templates)))
diff --git a/lisp/vc/vc-mtn.el b/lisp/vc/vc-mtn.el
index 092d8b5..3c26ffc 100644
--- a/lisp/vc/vc-mtn.el
+++ b/lisp/vc/vc-mtn.el
@@ -60,7 +60,6 @@ switches."
   :version "25.1"
   :group 'vc-mtn)
 
-(define-obsolete-variable-alias 'vc-mtn-command 'vc-mtn-program "23.1")
 (defcustom vc-mtn-program "mtn"
   "Name of the monotone executable."
   :type 'string
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index 65775f8..5561292 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -2710,9 +2710,6 @@ to the working revision (except for keyword expansion)."
       (message "Reverting %s...done" (vc-delistify files)))))
 
 ;;;###autoload
-(define-obsolete-function-alias 'vc-revert-buffer 'vc-revert "23.1")
-
-;;;###autoload
 (defun vc-pull (&optional arg)
   "Update the current fileset or branch.
 You must be visiting a version controlled file, or in a `vc-dir' buffer.
diff --git a/lisp/vcursor.el b/lisp/vcursor.el
index fa0cbb7..3601abc 100644
--- a/lisp/vcursor.el
+++ b/lisp/vcursor.el
@@ -1132,9 +1132,6 @@ line is treated like ordinary characters."
     (vcursor-copy (if (or (= count 0) arg) (1+ count) count)))
   )
 
-(define-obsolete-function-alias
-  'vcursor-toggle-vcursor-map 'vcursor-use-vcursor-map "23.1")
-
 (defun vcursor-post-command ()
   (and vcursor-auto-disable (not vcursor-last-command)
        vcursor-overlay
diff --git a/lisp/vt-control.el b/lisp/vt-control.el
index fc3a514..d4c1419 100644
--- a/lisp/vt-control.el
+++ b/lisp/vt-control.el
@@ -1,4 +1,4 @@
-;;; vt-control.el --- Common VTxxx control functions
+;;; vt-control.el --- Common VTxxx control functions  -*- lexical-binding:t -*-
 
 ;; Copyright (C) 1993-1994, 2001-2020 Free Software Foundation, Inc.
 
diff --git a/lisp/window.el b/lisp/window.el
index f20940f..bb34a6d 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -2642,12 +2642,17 @@ and no others."
   "Return t if WINDOW is the currently active minibuffer window."
   (and (window-live-p window) (eq window (active-minibuffer-window))))
 
-(defun count-windows (&optional minibuf)
+(defun count-windows (&optional minibuf all-frames)
    "Return the number of live windows on the selected frame.
+
 The optional argument MINIBUF specifies whether the minibuffer
-window shall be counted.  See `walk-windows' for the precise
-meaning of this argument."
-   (length (window-list-1 nil minibuf)))
+window is included in the count.
+
+If ALL-FRAMES is non-nil, count the windows in all frames instead
+just the selected frame.
+
+See `walk-windows' for the precise meaning of this argument."
+   (length (window-list-1 nil minibuf all-frames)))
 
 ;;; Resizing windows.
 (defun window--size-to-pixel (window size &optional horizontal pixelwise 
round-maybe)
@@ -5729,10 +5734,10 @@ window."
 WINDOW defaults to the selected window.  DIRECTION can be
 nil (i.e. any), `height' or `width'."
   (with-current-buffer (window-buffer window)
-    (when (and (boundp 'window-size-fixed) window-size-fixed)
-      (not (and direction
-               (member (cons direction window-size-fixed)
-                       '((height . width) (width . height))))))))
+    (and window-size-fixed
+         (not (and direction
+                  (member (cons direction window-size-fixed)
+                          '((height . width) (width . height))))))))
 
 ;;; A different solution to balance-windows.
 (defvar window-area-factor 1
diff --git a/lisp/woman.el b/lisp/woman.el
index c0e27c5..891a126 100644
--- a/lisp/woman.el
+++ b/lisp/woman.el
@@ -914,8 +914,8 @@ Troff emulation is experimental and largely untested.
   :group 'faces)
 
 (defcustom woman-fontify
-  (or (and (fboundp 'display-color-p) (display-color-p))
-      (and (fboundp 'display-graphic-p) (display-graphic-p))
+  (or (display-color-p)
+      (display-graphic-p)
       (x-display-color-p))
   "If non-nil then WoMan assumes that face support is available.
 It defaults to a non-nil value if the display supports either colors
diff --git a/m4/00gnulib.m4 b/m4/00gnulib.m4
index 06eff4f..14628c3 100644
--- a/m4/00gnulib.m4
+++ b/m4/00gnulib.m4
@@ -1,44 +1,12 @@
-# 00gnulib.m4 serial 7
+# 00gnulib.m4 serial 8
 dnl Copyright (C) 2009-2020 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.
 
 dnl This file must be named something that sorts before all other
-dnl gnulib-provided .m4 files.  The first part is needed until such time
-dnl as we can assume Autoconf 2.64, with its improved AC_DEFUN_ONCE and
-dnl m4_divert semantics.  The second part is needed until the clang fix
-dnl has been included in Autoconf.
-
-# Until autoconf 2.63, handling of the diversion stack required m4_init
-# to be called first; but this does not happen with aclocal.  Wrapping
-# the entire execution in another layer of the diversion stack fixes this.
-# Worse, prior to autoconf 2.62, m4_wrap depended on the underlying m4
-# for whether it was FIFO or LIFO; in order to properly balance with
-# m4_init, we need to undo our push just before anything wrapped within
-# the m4_init body.  The way to ensure this is to wrap both sides of
-# m4_init with a one-shot macro that does the pop at the right time.
-m4_ifndef([_m4_divert_diversion],
-[m4_divert_push([KILL])
-m4_define([gl_divert_fixup], [m4_divert_pop()m4_define([$0])])
-m4_define([m4_init],
-  [gl_divert_fixup()]m4_defn([m4_init])[gl_divert_fixup()])])
-
-
-# AC_DEFUN_ONCE([NAME], VALUE)
-# ----------------------------
-# Define NAME to expand to VALUE on the first use (whether by direct
-# expansion, or by AC_REQUIRE), and to nothing on all subsequent uses.
-# Avoid bugs in AC_REQUIRE in Autoconf 2.63 and earlier.  This
-# definition is slower than the version in Autoconf 2.64, because it
-# can only use interfaces that existed since 2.59; but it achieves the
-# same effect.  Quoting is necessary to avoid confusing Automake.
-m4_version_prereq([2.63.263], [],
-[m4_define([AC][_DEFUN_ONCE],
-  [AC][_DEFUN([$1],
-    [AC_REQUIRE([_gl_DEFUN_ONCE([$1])],
-      [m4_indir([_gl_DEFUN_ONCE([$1])])])])]dnl
-[AC][_DEFUN([_gl_DEFUN_ONCE([$1])], [$2])])])
+dnl gnulib-provided .m4 files.  It is needed until the clang fix has
+dnl been included in Autoconf.
 
 # The following definitions arrange to use a compiler option
 # -Werror=implicit-function-declaration in AC_CHECK_DECL, when the
diff --git a/m4/absolute-header.m4 b/m4/absolute-header.m4
index 39726ba..c043233 100644
--- a/m4/absolute-header.m4
+++ b/m4/absolute-header.m4
@@ -1,4 +1,4 @@
-# absolute-header.m4 serial 16
+# absolute-header.m4 serial 17
 dnl Copyright (C) 2006-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -22,23 +22,21 @@ dnl From Derek Price.
 AC_DEFUN([gl_ABSOLUTE_HEADER],
 [AC_REQUIRE([AC_CANONICAL_HOST])
 AC_LANG_PREPROC_REQUIRE()dnl
-dnl FIXME: gl_absolute_header and ac_header_exists must be used unquoted
-dnl until we can assume autoconf 2.64 or newer.
 m4_foreach_w([gl_HEADER_NAME], [$1],
   [AS_VAR_PUSHDEF([gl_absolute_header],
                   [gl_cv_absolute_]m4_defn([gl_HEADER_NAME]))dnl
   AC_CACHE_CHECK([absolute name of <]m4_defn([gl_HEADER_NAME])[>],
-    m4_defn([gl_absolute_header]),
+    [gl_absolute_header],
     [AS_VAR_PUSHDEF([ac_header_exists],
                     [ac_cv_header_]m4_defn([gl_HEADER_NAME]))dnl
     AC_CHECK_HEADERS_ONCE(m4_defn([gl_HEADER_NAME]))dnl
-    if test AS_VAR_GET(ac_header_exists) = yes; then
+    if test AS_VAR_GET([ac_header_exists]) = yes; then
       gl_ABSOLUTE_HEADER_ONE(m4_defn([gl_HEADER_NAME]))
     fi
     AS_VAR_POPDEF([ac_header_exists])dnl
     ])dnl
   AC_DEFINE_UNQUOTED(AS_TR_CPP([ABSOLUTE_]m4_defn([gl_HEADER_NAME])),
-                     ["AS_VAR_GET(gl_absolute_header)"],
+                     ["AS_VAR_GET([gl_absolute_header])"],
                      [Define this to an absolute name of 
<]m4_defn([gl_HEADER_NAME])[>.])
   AS_VAR_POPDEF([gl_absolute_header])dnl
 ])dnl
diff --git a/m4/alloca.m4 b/m4/alloca.m4
index b777f84..d841489 100644
--- a/m4/alloca.m4
+++ b/m4/alloca.m4
@@ -1,4 +1,4 @@
-# alloca.m4 serial 17
+# alloca.m4 serial 18
 dnl Copyright (C) 2002-2004, 2006-2007, 2009-2020 Free Software Foundation,
 dnl Inc.
 dnl This file is free software; the Free Software Foundation
@@ -102,7 +102,7 @@ AH_VERBATIM([STACK_DIRECTION],
         STACK_DIRECTION > 0 => grows toward higher addresses
         STACK_DIRECTION < 0 => grows toward lower addresses
         STACK_DIRECTION = 0 => direction of growth unknown */
-@%:@undef STACK_DIRECTION])dnl
+#undef STACK_DIRECTION])dnl
 AC_DEFINE_UNQUOTED(STACK_DIRECTION, $ac_cv_c_stack_direction)
 ])
 ])
diff --git a/m4/canonicalize.m4 b/m4/canonicalize.m4
index bdc5c8f..14ea3e1 100644
--- a/m4/canonicalize.m4
+++ b/m4/canonicalize.m4
@@ -1,4 +1,4 @@
-# canonicalize.m4 serial 31
+# canonicalize.m4 serial 33
 
 dnl Copyright (C) 2003-2007, 2009-2020 Free Software Foundation, Inc.
 
@@ -56,7 +56,16 @@ AC_DEFUN([gl_CANONICALIZE_LGPL],
 AC_DEFUN([gl_CANONICALIZE_LGPL_SEPARATE],
 [
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
-  AC_CHECK_FUNCS_ONCE([canonicalize_file_name getcwd readlink])
+  AC_CHECK_FUNCS_ONCE([canonicalize_file_name readlink])
+
+  dnl On native Windows, we use _getcwd(), regardless whether getcwd() is
+  dnl available through the linker option '-loldnames'.
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  case "$host_os" in
+    mingw*) ;;
+    *)      AC_CHECK_FUNCS([getcwd]) ;;
+  esac
+
   AC_REQUIRE([gl_DOUBLE_SLASH_ROOT])
   AC_REQUIRE([gl_FUNC_REALPATH_WORKS])
   AC_CHECK_HEADERS_ONCE([sys/param.h])
@@ -70,6 +79,7 @@ AC_DEFUN([gl_FUNC_REALPATH_WORKS],
   AC_CHECK_FUNCS_ONCE([realpath])
   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
   AC_CACHE_CHECK([whether realpath works], [gl_cv_func_realpath_works], [
+    rm -rf conftest.a conftest.d
     touch conftest.a
     mkdir conftest.d
     AC_RUN_IFELSE([
diff --git a/m4/dup2.m4 b/m4/dup2.m4
index 462bfd0..a82798d 100644
--- a/m4/dup2.m4
+++ b/m4/dup2.m4
@@ -1,4 +1,4 @@
-#serial 26
+#serial 27
 dnl Copyright (C) 2002, 2005, 2007, 2009-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -16,6 +16,7 @@ AC_DEFUN([gl_FUNC_DUP2],
            #include <limits.h>
            #include <sys/resource.h>
            #include <unistd.h>
+           ]GL_MDA_DEFINES[
            #ifndef RLIM_SAVED_CUR
            # define RLIM_SAVED_CUR RLIM_INFINITY
            #endif
diff --git a/m4/fchmodat.m4 b/m4/fchmodat.m4
index e3f2f04..cf5c879 100644
--- a/m4/fchmodat.m4
+++ b/m4/fchmodat.m4
@@ -1,4 +1,4 @@
-# fchmodat.m4 serial 4
+# fchmodat.m4 serial 5
 dnl Copyright (C) 2004-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -40,7 +40,7 @@ AC_DEFUN([gl_FUNC_FCHMODAT],
               #ifndef S_IRWXO
                #define S_IRWXO 0007
               #endif
-            ]],
+            ]GL_MDA_DEFINES],
             [[
               int permissive = S_IRWXU | S_IRWXG | S_IRWXO;
               int desired = S_IRUSR | S_IWUSR;
diff --git a/m4/fcntl.m4 b/m4/fcntl.m4
index 562ae23..ea24f3d 100644
--- a/m4/fcntl.m4
+++ b/m4/fcntl.m4
@@ -1,4 +1,4 @@
-# fcntl.m4 serial 9
+# fcntl.m4 serial 10
 dnl Copyright (C) 2009-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -34,6 +34,7 @@ AC_DEFUN([gl_FUNC_FCNTL],
               #include <limits.h>
               #include <sys/resource.h>
               #include <unistd.h>
+              ]GL_MDA_DEFINES[
               #ifndef RLIM_SAVED_CUR
               # define RLIM_SAVED_CUR RLIM_INFINITY
               #endif
diff --git a/m4/fdopendir.m4 b/m4/fdopendir.m4
index d9cc1a0..9937a74 100644
--- a/m4/fdopendir.m4
+++ b/m4/fdopendir.m4
@@ -1,4 +1,4 @@
-# serial 12
+# serial 14
 # See if we need to provide fdopendir.
 
 dnl Copyright (C) 2009-2020 Free Software Foundation, Inc.
@@ -25,10 +25,12 @@ AC_DEFUN([gl_FUNC_FDOPENDIR],
   else
     AC_CACHE_CHECK([whether fdopendir works],
       [gl_cv_func_fdopendir_works],
-      [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+      [AC_RUN_IFELSE(
+         [AC_LANG_PROGRAM([[
 #include <dirent.h>
 #include <fcntl.h>
 #include <unistd.h>
+]GL_MDA_DEFINES[
 #if !HAVE_DECL_FDOPENDIR
 extern
 # ifdef __cplusplus
@@ -36,12 +38,14 @@ extern
 # endif
 DIR *fdopendir (int);
 #endif
-]], [int result = 0;
-     int fd = open ("conftest.c", O_RDONLY);
-     if (fd < 0) result |= 1;
-     if (fdopendir (fd)) result |= 2;
-     if (close (fd)) result |= 4;
-     return result;])],
+]],
+            [[int result = 0;
+              int fd = open ("conftest.c", O_RDONLY);
+              if (fd < 0) result |= 1;
+              if (fdopendir (fd)) result |= 2;
+              if (close (fd)) result |= 4;
+              return result;
+            ]])],
          [gl_cv_func_fdopendir_works=yes],
          [gl_cv_func_fdopendir_works=no],
          [case "$host_os" in
diff --git a/m4/fpending.m4 b/m4/fpending.m4
index ea9725e..edabcec 100644
--- a/m4/fpending.m4
+++ b/m4/fpending.m4
@@ -1,4 +1,4 @@
-# serial 22
+# serial 23
 
 # Copyright (C) 2000-2001, 2004-2020 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
@@ -25,7 +25,7 @@ AC_DEFUN([gl_FUNC_FPENDING],
   AC_CACHE_CHECK([for __fpending], [gl_cv_func___fpending],
     [
       AC_LINK_IFELSE(
-        [AC_LANG_PROGRAM([$fp_headers],
+        [AC_LANG_PROGRAM([[$fp_headers]],
            [[return ! __fpending (stdin);]])],
         [gl_cv_func___fpending=yes],
         [gl_cv_func___fpending=no])
diff --git a/m4/futimens.m4 b/m4/futimens.m4
index dc5cfa9..145b8ff 100644
--- a/m4/futimens.m4
+++ b/m4/futimens.m4
@@ -1,4 +1,4 @@
-# serial 8
+# serial 9
 # See if we need to provide futimens replacement.
 
 dnl Copyright (C) 2009-2020 Free Software Foundation, Inc.
@@ -24,7 +24,8 @@ AC_DEFUN([gl_FUNC_FUTIMENS],
 #include <sys/stat.h>
 #include <unistd.h>
 #include <errno.h>
-]], [[struct timespec ts[2];
+]GL_MDA_DEFINES],
+     [[struct timespec ts[2];
       int fd = creat ("conftest.file", 0600);
       struct stat st;
       if (fd < 0) return 1;
diff --git a/m4/getdtablesize.m4 b/m4/getdtablesize.m4
index ab2e3fe..af32864 100644
--- a/m4/getdtablesize.m4
+++ b/m4/getdtablesize.m4
@@ -1,4 +1,4 @@
-# getdtablesize.m4 serial 7
+# getdtablesize.m4 serial 8
 dnl Copyright (C) 2008-2020 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,13 +29,16 @@ AC_DEFUN([gl_FUNC_GETDTABLESIZE],
            dnl correctly require setrlimit before getdtablesize() can report
            dnl a larger value.
            AC_RUN_IFELSE([
-             AC_LANG_PROGRAM([[#include <unistd.h>]],
-               [int size = getdtablesize();
-                if (dup2 (0, getdtablesize()) != -1)
-                  return 1;
-                if (size != getdtablesize())
-                  return 2;
-               ])],
+             AC_LANG_PROGRAM(
+               [[#include <unistd.h>]
+                GL_MDA_DEFINES
+               ],
+               [[int size = getdtablesize();
+                 if (dup2 (0, getdtablesize()) != -1)
+                   return 1;
+                 if (size != getdtablesize())
+                   return 2;
+               ]])],
              [gl_cv_func_getdtablesize_works=yes],
              [gl_cv_func_getdtablesize_works=no],
              [case "$host_os" in
diff --git a/m4/getloadavg.m4 b/m4/getloadavg.m4
index 8e96965..9fe328e 100644
--- a/m4/getloadavg.m4
+++ b/m4/getloadavg.m4
@@ -7,7 +7,7 @@
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-#serial 9
+#serial 10
 
 # Autoconf defines AC_FUNC_GETLOADAVG, but that is obsolescent.
 # New applications should use gl_GETLOADAVG instead.
@@ -147,7 +147,7 @@ fi
 AC_CHECK_HEADERS([nlist.h],
 [AC_CHECK_MEMBERS([struct nlist.n_un.n_name],
                   [], [],
-                  [@%:@include <nlist.h>])
+                  [#include <nlist.h>])
  AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <nlist.h>]],
                    [[struct nlist x;
                     #ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME
diff --git a/m4/getrandom.m4 b/m4/getrandom.m4
index 424c2fa..d6da71a 100644
--- a/m4/getrandom.m4
+++ b/m4/getrandom.m4
@@ -1,4 +1,4 @@
-# getrandom.m4 serial 7
+# getrandom.m4 serial 8
 dnl Copyright 2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -18,7 +18,8 @@ AC_DEFUN([gl_FUNC_GETRANDOM],
       [gl_cv_func_getrandom_ok],
       [AC_COMPILE_IFELSE(
          [AC_LANG_PROGRAM(
-            [[/* Additional includes are needed before <sys/random.h> on Mac 
OS X.  */
+            [[/* Additional includes are needed before <sys/random.h> on uClibc
+                 and Mac OS X.  */
               #include <sys/types.h>
               #include <stdlib.h>
               #include <sys/random.h>
diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4
index 03da228..33e56fa 100644
--- a/m4/gnulib-common.m4
+++ b/m4/gnulib-common.m4
@@ -1,4 +1,4 @@
-# gnulib-common.m4 serial 55
+# gnulib-common.m4 serial 57
 dnl Copyright (C) 2007-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -480,14 +480,6 @@ AC_DEFUN([gl_FEATURES_H],
   AC_SUBST([HAVE_FEATURES_H])
 ])
 
-# AS_VAR_IF(VAR, VALUE, [IF-MATCH], [IF-NOT-MATCH])
-# ----------------------------------------------------
-# Backport of autoconf-2.63b's macro.
-# Remove this macro when we can assume autoconf >= 2.64.
-m4_ifndef([AS_VAR_IF],
-[m4_define([AS_VAR_IF],
-[AS_IF([test x"AS_VAR_GET([$1])" = x""$2], [$3], [$4])])])
-
 # gl_PROG_CC_C99
 # Modifies the value of the shell variable CC in an attempt to make $CC
 # understand ISO C99 source code.
@@ -660,6 +652,72 @@ AC_DEFUN([gl_CACHE_VAL_SILENT],
   as_echo_n="$saved_as_echo_n"
 ])
 
-# AS_VAR_COPY was added in autoconf 2.63b
-m4_define_default([AS_VAR_COPY],
-[AS_LITERAL_IF([$1[]$2], [$1=$$2], [eval $1=\$$2])])
+dnl Expands to some code for use in .c programs that, on native Windows, 
defines
+dnl the Microsoft deprecated alias function names to the underscore-prefixed
+dnl actual function names. With this macro, these function names are available
+dnl without linking with '-loldnames' and without generating warnings.
+dnl Usage: Use it after all system header files are included.
+dnl          #include <...>
+dnl          #include <...>
+dnl          ]GL_MDA_DEFINES[
+dnl          ...
+AC_DEFUN([GL_MDA_DEFINES],[
+AC_REQUIRE([_GL_MDA_DEFINES])
+[$gl_mda_defines]
+])
+AC_DEFUN([_GL_MDA_DEFINES],
+[gl_mda_defines='
+#if defined _WIN32 && !defined __CYGWIN__
+#define access    _access
+#define chdir     _chdir
+#define chmod     _chmod
+#define close     _close
+#define creat     _creat
+#define dup       _dup
+#define dup2      _dup2
+#define ecvt      _ecvt
+#define execl     _execl
+#define execle    _execle
+#define execlp    _execlp
+#define execv     _execv
+#define execve    _execve
+#define execvp    _execvp
+#define execvpe   _execvpe
+#define fcloseall _fcloseall
+#define fcvt      _fcvt
+#define fdopen    _fdopen
+#define fileno    _fileno
+#define gcvt      _gcvt
+#define getcwd    _getcwd
+#define getpid    _getpid
+#define getw      _getw
+#define isatty    _isatty
+#define j0        _j0
+#define j1        _j1
+#define jn        _jn
+#define lfind     _lfind
+#define lsearch   _lsearch
+#define lseek     _lseek
+#define memccpy   _memccpy
+#define mkdir     _mkdir
+#define mktemp    _mktemp
+#define open      _open
+#define putenv    _putenv
+#define putw      _putw
+#define read      _read
+#define rmdir     _rmdir
+#define strdup    _strdup
+#define swab      _swab
+#define tempnam   _tempnam
+#define tzset     _tzset
+#define umask     _umask
+#define unlink    _unlink
+#define utime     _utime
+#define wcsdup    _wcsdup
+#define write     _write
+#define y0        _y0
+#define y1        _y1
+#define yn        _yn
+#endif
+'
+])
diff --git a/m4/include_next.m4 b/m4/include_next.m4
index 9009e29..33601aa 100644
--- a/m4/include_next.m4
+++ b/m4/include_next.m4
@@ -1,4 +1,4 @@
-# include_next.m4 serial 24
+# include_next.m4 serial 25
 dnl Copyright (C) 2006-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -176,42 +176,40 @@ AC_DEFUN([gl_NEXT_HEADERS_INTERNAL],
     [AC_CHECK_HEADERS_ONCE([$1])
     ])
 
-dnl FIXME: gl_next_header and gl_header_exists must be used unquoted
-dnl until we can assume autoconf 2.64 or newer.
   m4_foreach_w([gl_HEADER_NAME], [$1],
     [AS_VAR_PUSHDEF([gl_next_header],
                     [gl_cv_next_]m4_defn([gl_HEADER_NAME]))
      if test $gl_cv_have_include_next = yes; then
-       AS_VAR_SET(gl_next_header, ['<'gl_HEADER_NAME'>'])
+       AS_VAR_SET([gl_next_header], ['<'gl_HEADER_NAME'>'])
      else
        AC_CACHE_CHECK(
          [absolute name of <]m4_defn([gl_HEADER_NAME])[>],
-         m4_defn([gl_next_header]),
+         [gl_next_header],
          [m4_if([$2], [check],
             [AS_VAR_PUSHDEF([gl_header_exists],
                             [ac_cv_header_]m4_defn([gl_HEADER_NAME]))
-             if test AS_VAR_GET(gl_header_exists) = yes; then
+             if test AS_VAR_GET([gl_header_exists]) = yes; then
              AS_VAR_POPDEF([gl_header_exists])
             ])
            gl_ABSOLUTE_HEADER_ONE(gl_HEADER_NAME)
            AS_VAR_COPY([gl_header], [gl_cv_absolute_]AS_TR_SH(gl_HEADER_NAME))
-           AS_VAR_SET(gl_next_header, ['"'$gl_header'"'])
+           AS_VAR_SET([gl_next_header], ['"'$gl_header'"'])
           m4_if([$2], [check],
             [else
-               AS_VAR_SET(gl_next_header, ['<'gl_HEADER_NAME'>'])
+               AS_VAR_SET([gl_next_header], ['<'gl_HEADER_NAME'>'])
              fi
             ])
          ])
      fi
      AC_SUBST(
        AS_TR_CPP([NEXT_]m4_defn([gl_HEADER_NAME])),
-       [AS_VAR_GET(gl_next_header)])
+       [AS_VAR_GET([gl_next_header])])
      if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = 
buggy; then
        # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next'
        gl_next_as_first_directive='<'gl_HEADER_NAME'>'
      else
        # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include'
-       gl_next_as_first_directive=AS_VAR_GET(gl_next_header)
+       gl_next_as_first_directive=AS_VAR_GET([gl_next_header])
      fi
      AC_SUBST(
        AS_TR_CPP([NEXT_AS_FIRST_DIRECTIVE_]m4_defn([gl_HEADER_NAME])),
diff --git a/m4/largefile.m4 b/m4/largefile.m4
index f7140dd..f4c5d3a 100644
--- a/m4/largefile.m4
+++ b/m4/largefile.m4
@@ -30,12 +30,12 @@ m4_version_prereq([2.70], [] ,[
 # _AC_SYS_LARGEFILE_TEST_INCLUDES
 # -------------------------------
 m4_define([_AC_SYS_LARGEFILE_TEST_INCLUDES],
-[@%:@include <sys/types.h>
+[#include <sys/types.h>
  /* Check that off_t can represent 2**63 - 1 correctly.
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-@%:@define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
+#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31))
   int off_t_is_large[[(LARGE_OFF_T % 2147483629 == 721
                        && LARGE_OFF_T % 2147483647 == 1)
                       ? 1 : -1]];[]dnl
@@ -54,7 +54,7 @@ m4_define([_AC_SYS_LARGEFILE_MACRO_VALUE],
     [AC_LANG_PROGRAM([$5], [$6])],
     [$3=no; break])
   m4_ifval([$6], [AC_LINK_IFELSE], [AC_COMPILE_IFELSE])(
-    [AC_LANG_PROGRAM([@%:@define $1 $2
+    [AC_LANG_PROGRAM([#define $1 $2
 $5], [$6])],
     [$3=$2; break])
   $3=unknown
diff --git a/m4/manywarnings.m4 b/m4/manywarnings.m4
index d18da04..a37cd15 100644
--- a/m4/manywarnings.m4
+++ b/m4/manywarnings.m4
@@ -1,4 +1,4 @@
-# manywarnings.m4 serial 20
+# manywarnings.m4 serial 21
 dnl Copyright (C) 2008-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -39,8 +39,7 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC],
 [_AC_LANG_DISPATCH([$0], _AC_LANG, $@)])
 
 # Specialization for _AC_LANG = C.
-# Use of m4_defun rather than AC_DEFUN works around a bug in autoconf < 2.63b.
-m4_defun([gl_MANYWARN_ALL_GCC(C)],
+AC_DEFUN([gl_MANYWARN_ALL_GCC(C)],
 [
   AC_LANG_PUSH([C])
 
@@ -210,8 +209,7 @@ m4_defun([gl_MANYWARN_ALL_GCC(C)],
 ])
 
 # Specialization for _AC_LANG = C++.
-# Use of m4_defun rather than AC_DEFUN works around a bug in autoconf < 2.63b.
-m4_defun([gl_MANYWARN_ALL_GCC(C++)],
+AC_DEFUN([gl_MANYWARN_ALL_GCC(C++)],
 [
   gl_MANYWARN_ALL_GCC_CXX_IMPL([$1])
 ])
diff --git a/m4/mktime.m4 b/m4/mktime.m4
index 8d9b827..4e7e423 100644
--- a/m4/mktime.m4
+++ b/m4/mktime.m4
@@ -1,4 +1,4 @@
-# serial 32
+# serial 35
 dnl Copyright (C) 2002-2003, 2005-2007, 2009-2020 Free Software Foundation,
 dnl Inc.
 dnl This file is free software; the Free Software Foundation
@@ -31,7 +31,6 @@ AC_DEFUN([gl_FUNC_MKTIME_WORKS],
   dnl in Autoconf and because it invokes AC_LIBOBJ.
   AC_CHECK_HEADERS_ONCE([unistd.h])
   AC_CHECK_DECLS_ONCE([alarm])
-  AC_CHECK_FUNCS_ONCE([tzset])
   AC_REQUIRE([gl_MULTIARCH])
   AC_CACHE_CHECK([for working mktime], [gl_cv_func_working_mktime],
     [if test $APPLE_UNIVERSAL_BUILD = 1; then
@@ -55,13 +54,12 @@ AC_DEFUN([gl_FUNC_MKTIME_WORKS],
 # include <signal.h>
 #endif
 
+]GL_MDA_DEFINES[
+
 #ifndef TIME_T_IS_SIGNED
 # define TIME_T_IS_SIGNED 0
 #endif
 
-/* Work around redefinition to rpl_putenv by other config tests.  */
-#undef putenv
-
 static time_t time_t_max;
 static time_t time_t_min;
 
diff --git a/m4/nstrftime.m4 b/m4/nstrftime.m4
index 6f2762a..e4eb87d 100644
--- a/m4/nstrftime.m4
+++ b/m4/nstrftime.m4
@@ -1,4 +1,4 @@
-# serial 35
+# serial 36
 
 # Copyright (C) 1996-1997, 1999-2007, 2009-2020 Free Software Foundation, Inc.
 #
@@ -17,8 +17,6 @@ AC_DEFUN([gl_FUNC_GNU_STRFTIME],
 
  AC_REQUIRE([gl_TM_GMTOFF])
 
- AC_CHECK_FUNCS_ONCE([tzset])
-
  AC_DEFINE([my_strftime], [nstrftime],
    [Define to the name of the strftime replacement function.])
 ])
diff --git a/m4/open-slash.m4 b/m4/open-slash.m4
index 1e57c96..5d84f2b 100644
--- a/m4/open-slash.m4
+++ b/m4/open-slash.m4
@@ -1,4 +1,4 @@
-# open-slash.m4 serial 1
+# open-slash.m4 serial 2
 dnl Copyright (C) 2007-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -25,6 +25,7 @@ AC_DEFUN([gl_OPEN_TRAILING_SLASH_BUG],
 #if HAVE_UNISTD_H
 # include <unistd.h>
 #endif
+]GL_MDA_DEFINES[
 int main ()
 {
   int result = 0;
diff --git a/m4/pselect.m4 b/m4/pselect.m4
index f3e5afe..08a5823 100644
--- a/m4/pselect.m4
+++ b/m4/pselect.m4
@@ -1,4 +1,4 @@
-# pselect.m4 serial 8
+# pselect.m4 serial 9
 dnl Copyright (C) 2011-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -37,7 +37,8 @@ AC_DEFUN([gl_FUNC_PSELECT],
 #endif
 #include <unistd.h>
 #include <errno.h>
-]],[[
+]GL_MDA_DEFINES],
+[[
   fd_set set;
   dup2(0, 16);
   FD_ZERO(&set);
diff --git a/m4/pthread_sigmask.m4 b/m4/pthread_sigmask.m4
index d67511f..030862d 100644
--- a/m4/pthread_sigmask.m4
+++ b/m4/pthread_sigmask.m4
@@ -1,4 +1,4 @@
-# pthread_sigmask.m4 serial 18
+# pthread_sigmask.m4 serial 19
 dnl Copyright (C) 2011-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -220,6 +220,7 @@ int main ()
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+]GL_MDA_DEFINES[
 static volatile int sigint_occurred;
 static void
 sigint_handler (int sig)
diff --git a/m4/sys_random_h.m4 b/m4/sys_random_h.m4
index a964b15..8c5d537 100644
--- a/m4/sys_random_h.m4
+++ b/m4/sys_random_h.m4
@@ -1,4 +1,4 @@
-# sys_random_h.m4 serial 4
+# sys_random_h.m4 serial 5
 dnl Copyright (C) 2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -25,7 +25,8 @@ AC_DEFUN([gl_HEADER_SYS_RANDOM],
   dnl corresponding gnulib module is not in use.
   gl_WARN_ON_USE_PREPARE([[
 #if HAVE_SYS_RANDOM_H
-/* Additional includes are needed before <sys/random.h> on Mac OS X.  */
+/* Additional includes are needed before <sys/random.h> on uClibc
+   and Mac OS X.  */
 # include <sys/types.h>
 # include <stdlib.h>
 # include <sys/random.h>
diff --git a/m4/time_h.m4 b/m4/time_h.m4
index d0f8932..a15c09d 100644
--- a/m4/time_h.m4
+++ b/m4/time_h.m4
@@ -121,7 +121,6 @@ AC_DEFUN([gl_HEADER_TIME_H_DEFAULTS],
   HAVE_NANOSLEEP=1;                      AC_SUBST([HAVE_NANOSLEEP])
   HAVE_STRPTIME=1;                       AC_SUBST([HAVE_STRPTIME])
   HAVE_TIMEGM=1;                         AC_SUBST([HAVE_TIMEGM])
-  HAVE_TZSET=1;                          AC_SUBST([HAVE_TZSET])
   dnl Even GNU libc does not have timezone_t yet.
   HAVE_TIMEZONE_T=0;                     AC_SUBST([HAVE_TIMEZONE_T])
   dnl If another module says to replace or to not replace, do that.
diff --git a/m4/utimens.m4 b/m4/utimens.m4
index 65617ac..3d31085 100644
--- a/m4/utimens.m4
+++ b/m4/utimens.m4
@@ -3,7 +3,7 @@ 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.
 
-dnl serial 10
+dnl serial 11
 
 AC_DEFUN([gl_UTIMENS],
 [
@@ -24,7 +24,8 @@ AC_DEFUN([gl_UTIMENS],
 #include <stddef.h>
 #include <sys/times.h>
 #include <fcntl.h>
-]], [[    int fd = open ("conftest.file", O_RDWR);
+]GL_MDA_DEFINES],
+        [[int fd = open ("conftest.file", O_RDWR);
           if (fd < 0) return 1;
           if (futimesat (fd, NULL, NULL)) return 2;
         ]])],
diff --git a/m4/utimensat.m4 b/m4/utimensat.m4
index 2bc1bfe..e9e4f26 100644
--- a/m4/utimensat.m4
+++ b/m4/utimensat.m4
@@ -1,4 +1,4 @@
-# serial 6
+# serial 7
 # See if we need to provide utimensat replacement.
 
 dnl Copyright (C) 2009-2020 Free Software Foundation, Inc.
@@ -23,7 +23,8 @@ AC_DEFUN([gl_FUNC_UTIMENSAT],
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <unistd.h>
-]],         [[int result = 0;
+]GL_MDA_DEFINES],
+            [[int result = 0;
               const char *f = "conftest.file";
               if (close (creat (f, 0600)))
                 return 1;
diff --git a/m4/utimes.m4 b/m4/utimes.m4
index e1056bb..877bfd2 100644
--- a/m4/utimes.m4
+++ b/m4/utimes.m4
@@ -1,5 +1,5 @@
 # Detect some bugs in glibc's implementation of utimes.
-# serial 7
+# serial 8
 
 dnl Copyright (C) 2003-2005, 2009-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
@@ -34,6 +34,7 @@ AC_DEFUN([gl_FUNC_UTIMES],
 #include <stdio.h>
 #include <utime.h>
 #include <errno.h>
+]GL_MDA_DEFINES[
 
 static int
 inorder (time_t a, time_t b, time_t c)
diff --git a/m4/warnings.m4 b/m4/warnings.m4
index d272365..d4e4b07 100644
--- a/m4/warnings.m4
+++ b/m4/warnings.m4
@@ -1,4 +1,4 @@
-# warnings.m4 serial 14
+# warnings.m4 serial 16
 dnl Copyright (C) 2008-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -23,8 +23,6 @@ m4_ifdef([AS_VAR_APPEND],
 # The effects of this macro depend on the current language (_AC_LANG).
 AC_DEFUN([gl_COMPILER_OPTION_IF],
 [
-dnl FIXME: gl_Warn must be used unquoted until we can assume Autoconf
-dnl 2.64 or newer.
 AS_VAR_PUSHDEF([gl_Warn], [gl_cv_warn_[]_AC_LANG_ABBREV[]_$1])dnl
 AS_VAR_PUSHDEF([gl_Flags], [_AC_LANG_PREFIX[]FLAGS])dnl
 AS_LITERAL_IF([$1],
@@ -34,13 +32,13 @@ case $gl_positive in
   -Wno-*) gl_positive=-W`expr "X$gl_positive" : 'X-Wno-\(.*\)'` ;;
 esac
 m4_pushdef([gl_Positive], [$gl_positive])])dnl
-AC_CACHE_CHECK([whether _AC_LANG compiler handles $1], m4_defn([gl_Warn]), [
+AC_CACHE_CHECK([whether _AC_LANG compiler handles $1], [gl_Warn], [
   gl_save_compiler_FLAGS="$gl_Flags"
   gl_AS_VAR_APPEND(m4_defn([gl_Flags]),
     [" $gl_unknown_warnings_are_errors ]m4_defn([gl_Positive])["])
-  AC_LINK_IFELSE([m4_default([$4], [AC_LANG_PROGRAM([])])],
-                 [AS_VAR_SET(gl_Warn, [yes])],
-                 [AS_VAR_SET(gl_Warn, [no])])
+  AC_LINK_IFELSE([m4_default([$4], [AC_LANG_PROGRAM([[]])])],
+                 [AS_VAR_SET([gl_Warn], [yes])],
+                 [AS_VAR_SET([gl_Warn], [no])])
   gl_Flags="$gl_save_compiler_FLAGS"
 ])
 AS_VAR_IF(gl_Warn, [yes], [$2], [$3])
@@ -59,8 +57,7 @@ AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS],
 [_AC_LANG_DISPATCH([$0], _AC_LANG, $@)])
 
 # Specialization for _AC_LANG = C. This macro can be AC_REQUIREd.
-# Use of m4_defun rather than AC_DEFUN works around a bug in autoconf < 2.63b.
-m4_defun([gl_UNKNOWN_WARNINGS_ARE_ERRORS(C)],
+AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS(C)],
 [
   AC_LANG_PUSH([C])
   gl_UNKNOWN_WARNINGS_ARE_ERRORS_IMPL
@@ -68,8 +65,7 @@ m4_defun([gl_UNKNOWN_WARNINGS_ARE_ERRORS(C)],
 ])
 
 # Specialization for _AC_LANG = C++. This macro can be AC_REQUIREd.
-# Use of m4_defun rather than AC_DEFUN works around a bug in autoconf < 2.63b.
-m4_defun([gl_UNKNOWN_WARNINGS_ARE_ERRORS(C++)],
+AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS(C++)],
 [
   AC_LANG_PUSH([C++])
   gl_UNKNOWN_WARNINGS_ARE_ERRORS_IMPL
@@ -77,8 +73,7 @@ m4_defun([gl_UNKNOWN_WARNINGS_ARE_ERRORS(C++)],
 ])
 
 # Specialization for _AC_LANG = Objective C. This macro can be AC_REQUIREd.
-# Use of m4_defun rather than AC_DEFUN works around a bug in autoconf < 2.63b.
-m4_defun([gl_UNKNOWN_WARNINGS_ARE_ERRORS(Objective C)],
+AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS(Objective C)],
 [
   AC_LANG_PUSH([Objective C])
   gl_UNKNOWN_WARNINGS_ARE_ERRORS_IMPL
diff --git a/src/Makefile.in b/src/Makefile.in
index 63a4aa8..31a5a7e 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -587,7 +587,7 @@ endif
 ifeq ($(DUMPING),pdumper)
 $(pdmp): emacs$(EXEEXT)
        LC_ALL=C $(RUN_TEMACS) -batch $(BUILD_DETAILS) -l loadup --temacs=pdump 
\
-               --bin-dest $(BIN_DESTDIR) --lisp-dest $(LISP_DESTDIR)
+               --bin-dest $(BIN_DESTDIR) --eln-dest $(ELN_DESTDIR)
        cp -f $@ $(bootstrap_pdmp)
 endif
 
@@ -790,10 +790,6 @@ tags: TAGS ../lisp/TAGS $(lwlibdir)/TAGS
        @$(MAKE) $(AM_V_NO_PD) -C ../lisp EMACS="$(bootstrap_exe)"\
                THEFILE=$< $<c
 
-%.eln: %.el | bootstrap-emacs$(EXEEXT) $(bootstrap_pdmp)
-       @$(MAKE)  $(AM_V_NO_PD) -C ../lisp EMACS="$(bootstrap_exe)"\
-               THEFILE=$< $<n
-
 ## VCSWITNESS points to the file that holds info about the current checkout.
 ## We use it as a heuristic to decide when to rebuild loaddefs.el.
 ## If empty it is ignored; the parent makefile can set it to some other value.
diff --git a/src/ccl.c b/src/ccl.c
index ef059ff..86debee 100644
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -1142,19 +1142,52 @@ ccl_driver (struct ccl_program *ccl, int *source, int 
*destination, int src_size
        ccl_expr_self:
          switch (op)
            {
-           case CCL_PLUS: reg[rrr] += i; break;
-           case CCL_MINUS: reg[rrr] -= i; break;
-           case CCL_MUL: reg[rrr] *= i; break;
-           case CCL_DIV: reg[rrr] /= i; break;
+           case CCL_PLUS: INT_ADD_WRAPV (reg[rrr], i, &reg[rrr]); break;
+           case CCL_MINUS: INT_SUBTRACT_WRAPV (reg[rrr], i, &reg[rrr]); break;
+           case CCL_MUL: INT_MULTIPLY_WRAPV (reg[rrr], i, &reg[rrr]); break;
+           case CCL_DIV:
+             if (!i)
+               CCL_INVALID_CMD;
+             if (!INT_DIVIDE_OVERFLOW (reg[rrr], i))
+               reg[rrr] /= i;
+             break;
            case CCL_MOD: reg[rrr] %= i; break;
+             if (!i)
+               CCL_INVALID_CMD;
+             reg[rrr] = i == -1 ? 0 : reg[rrr] % i;
+             break;
            case CCL_AND: reg[rrr] &= i; break;
            case CCL_OR: reg[rrr] |= i; break;
            case CCL_XOR: reg[rrr] ^= i; break;
-           case CCL_LSH: reg[rrr] <<= i; break;
-           case CCL_RSH: reg[rrr] >>= i; break;
-           case CCL_LSH8: reg[rrr] <<= 8; reg[rrr] |= i; break;
+           case CCL_LSH:
+             if (i < 0)
+               CCL_INVALID_CMD;
+             reg[rrr] = i < UINT_WIDTH ? (unsigned) reg[rrr] << i : 0;
+             break;
+           case CCL_RSH:
+             if (i < 0)
+               CCL_INVALID_CMD;
+             reg[rrr] = reg[rrr] >> min (i, INT_WIDTH - 1);
+             break;
+           case CCL_LSH8:
+             reg[rrr] = (unsigned) reg[rrr] << 8;
+             reg[rrr] |= i;
+             break;
            case CCL_RSH8: reg[7] = reg[rrr] & 0xFF; reg[rrr] >>= 8; break;
-           case CCL_DIVMOD: reg[7] = reg[rrr] % i; reg[rrr] /= i; break;
+           case CCL_DIVMOD:
+             if (!i)
+               CCL_INVALID_CMD;
+             if (i == -1)
+               {
+                 reg[7] = 0;
+                 INT_SUBTRACT_WRAPV (0, reg[rrr], &reg[rrr]);
+               }
+             else
+               {
+                 reg[7] = reg[rrr] % i;
+                 reg[rrr] /= i;
+               }
+             break;
            case CCL_LS: reg[rrr] = reg[rrr] < i; break;
            case CCL_GT: reg[rrr] = reg[rrr] > i; break;
            case CCL_EQ: reg[rrr] = reg[rrr] == i; break;
@@ -1204,19 +1237,52 @@ ccl_driver (struct ccl_program *ccl, int *source, int 
*destination, int src_size
        ccl_set_expr:
          switch (op)
            {
-           case CCL_PLUS: reg[rrr] = i + j; break;
-           case CCL_MINUS: reg[rrr] = i - j; break;
-           case CCL_MUL: reg[rrr] = i * j; break;
-           case CCL_DIV: reg[rrr] = i / j; break;
-           case CCL_MOD: reg[rrr] = i % j; break;
+           case CCL_PLUS: INT_ADD_WRAPV (i, j, &reg[rrr]); break;
+           case CCL_MINUS: INT_SUBTRACT_WRAPV (i, j, &reg[rrr]); break;
+           case CCL_MUL: INT_MULTIPLY_WRAPV (i, j, &reg[rrr]); break;
+           case CCL_DIV:
+             if (!j)
+               CCL_INVALID_CMD;
+             if (!INT_DIVIDE_OVERFLOW (i, j))
+               i /= j;
+             reg[rrr] = i;
+             break;
+           case CCL_MOD:
+             if (!j)
+               CCL_INVALID_CMD;
+             reg[rrr] = j == -1 ? 0 : i % j;
+             break;
            case CCL_AND: reg[rrr] = i & j; break;
            case CCL_OR: reg[rrr] = i | j; break;
            case CCL_XOR: reg[rrr] = i ^ j; break;
-           case CCL_LSH: reg[rrr] = i << j; break;
-           case CCL_RSH: reg[rrr] = i >> j; break;
-           case CCL_LSH8: reg[rrr] = (i << 8) | j; break;
+           case CCL_LSH:
+             if (j < 0)
+               CCL_INVALID_CMD;
+             reg[rrr] = j < UINT_WIDTH ? (unsigned) i << j : 0;
+             break;
+           case CCL_RSH:
+             if (j < 0)
+               CCL_INVALID_CMD;
+             reg[rrr] = i >> min (j, INT_WIDTH - 1);
+             break;
+           case CCL_LSH8:
+             reg[rrr] = ((unsigned) i << 8) | j;
+             break;
            case CCL_RSH8: reg[rrr] = i >> 8; reg[7] = i & 0xFF; break;
-           case CCL_DIVMOD: reg[rrr] = i / j; reg[7] = i % j; break;
+           case CCL_DIVMOD:
+             if (!j)
+               CCL_INVALID_CMD;
+             if (j == -1)
+               {
+                 INT_SUBTRACT_WRAPV (0, reg[rrr], &reg[rrr]);
+                 reg[7] = 0;
+               }
+             else
+               {
+                 reg[rrr] = i / j;
+                 reg[7] = i % j;
+               }
+             break;
            case CCL_LS: reg[rrr] = i < j; break;
            case CCL_GT: reg[rrr] = i > j; break;
            case CCL_EQ: reg[rrr] = i == j; break;
@@ -1225,7 +1291,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int 
*destination, int src_size
            case CCL_NE: reg[rrr] = i != j; break;
            case CCL_DECODE_SJIS:
              {
-               i = (i << 8) | j;
+               i = ((unsigned) i << 8) | j;
                SJIS_TO_JIS (i);
                reg[rrr] = i >> 8;
                reg[7] = i & 0xFF;
@@ -1233,7 +1299,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int 
*destination, int src_size
              }
            case CCL_ENCODE_SJIS:
              {
-               i = (i << 8) | j;
+               i = ((unsigned) i << 8) | j;
                JIS_TO_SJIS (i);
                reg[rrr] = i >> 8;
                reg[7] = i & 0xFF;
@@ -2219,15 +2285,8 @@ Return index number of the registered CCL program.  */)
     /* Extend the table.  */
     Vccl_program_table = larger_vector (Vccl_program_table, 1, -1);
 
-  {
-    Lisp_Object elt = make_uninit_vector (4);
-
-    ASET (elt, 0, name);
-    ASET (elt, 1, ccl_prog);
-    ASET (elt, 2, resolved);
-    ASET (elt, 3, Qt);
-    ASET (Vccl_program_table, idx, elt);
-  }
+  ASET (Vccl_program_table, idx,
+       CALLN (Fvector, name, ccl_prog, resolved, Qt));
 
   Fput (name, Qccl_program_idx, make_fixnum (idx));
   return make_fixnum (idx);
diff --git a/src/charset.c b/src/charset.c
index 8635aad..520dd3a 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -1035,12 +1035,9 @@ usage: (define-charset-internal ...)  */)
       CHECK_FIXNAT (parent_max_code);
       parent_code_offset = Fnth (make_fixnum (3), val);
       CHECK_FIXNUM (parent_code_offset);
-      val = make_uninit_vector (4);
-      ASET (val, 0, make_fixnum (parent_charset->id));
-      ASET (val, 1, parent_min_code);
-      ASET (val, 2, parent_max_code);
-      ASET (val, 3, parent_code_offset);
-      ASET (attrs, charset_subset, val);
+      ASET (attrs, charset_subset,
+           CALLN (Fvector, make_fixnum (parent_charset->id),
+                  parent_min_code, parent_max_code, parent_code_offset));
 
       charset.method = CHARSET_METHOD_SUBSET;
       /* Here, we just copy the parent's fast_map.  It's not accurate,
diff --git a/src/coding.c b/src/coding.c
index 071124b..51bd441 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -10856,20 +10856,17 @@ HIGHESTP non-nil means just return the highest 
priority one.  */)
   return Fnreverse (val);
 }
 
-static const char *const suffixes[] = { "-unix", "-dos", "-mac" };
-
 static Lisp_Object
 make_subsidiaries (Lisp_Object base)
 {
-  Lisp_Object subsidiaries;
+  static char const suffixes[][8] = { "-unix", "-dos", "-mac" };
   ptrdiff_t base_name_len = SBYTES (SYMBOL_NAME (base));
   USE_SAFE_ALLOCA;
   char *buf = SAFE_ALLOCA (base_name_len + 6);
-  int i;
 
   memcpy (buf, SDATA (SYMBOL_NAME (base)), base_name_len);
-  subsidiaries = make_uninit_vector (3);
-  for (i = 0; i < 3; i++)
+  Lisp_Object subsidiaries = make_nil_vector (3);
+  for (int i = 0; i < 3; i++)
     {
       strcpy (buf + base_name_len, suffixes[i]);
       ASET (subsidiaries, i, intern (buf));
@@ -11829,8 +11826,7 @@ Each element is one element list of coding system name.
 This variable is given to `completing-read' as COLLECTION argument.
 
 Do not alter the value of this variable manually.  This variable should be
-updated by the functions `make-coding-system' and
-`define-coding-system-alias'.  */);
+updated by `define-coding-system-alias'.  */);
   Vcoding_system_alist = Qnil;
 
   DEFVAR_LISP ("coding-category-list", Vcoding_category_list,
diff --git a/src/comp.c b/src/comp.c
index 704bd4b..ff73245 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -29,6 +29,7 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include <stdio.h>
 #include <signal.h>
 #include <libgccjit.h>
+#include <epaths.h>
 
 #include "puresize.h"
 #include "window.h"
@@ -393,6 +394,8 @@ load_gccjit_if_necessary (bool mandatory)
 }
 
 
+#define ELN_FILENAME_HASH_LEN 64
+
 /* C symbols emitted for the load relocation mechanism.  */
 #define CURRENT_THREAD_RELOC_SYM "current_thread_reloc"
 #define PURE_RELOC_SYM "pure_reloc"
@@ -634,6 +637,16 @@ format_string (const char *format, ...)
   return scratch_area;
 }
 
+static Lisp_Object
+comp_hash_string (Lisp_Object string)
+{
+  Lisp_Object digest = make_uninit_string (SHA512_DIGEST_SIZE * 2);
+  sha512_buffer (SSDATA (string), SCHARS (string), SSDATA (digest));
+  hexbuf_digest (SSDATA (digest), SDATA (digest), SHA512_DIGEST_SIZE);
+
+  return digest;
+}
+
 /* Produce a key hashing Vcomp_subr_list.  */
 
 void
@@ -641,10 +654,7 @@ hash_native_abi (void)
 {
   Lisp_Object string = Fmapconcat (intern_c_string ("subr-name"),
                                   Vcomp_subr_list, build_string (" "));
-  Lisp_Object digest = make_uninit_string (SHA512_DIGEST_SIZE * 2);
-
-  sha512_buffer (SSDATA (string), SCHARS (string), SSDATA (digest));
-  hexbuf_digest (SSDATA (digest), SDATA (digest), SHA512_DIGEST_SIZE);
+  Lisp_Object digest = comp_hash_string (string);
 
   /* Check runs once.  */
   eassert (NILP (Vcomp_abi_hash));
@@ -652,8 +662,7 @@ hash_native_abi (void)
   /* If 10 characters are usually sufficient for git I guess 16 are
      fine for us here.  */
   Vcomp_native_path_postfix =
-    concat3 (make_string ("eln-", 4),
-            Vsystem_configuration,
+    concat2 (Vsystem_configuration,
             concat2 (make_string ("-", 1),
                      Fsubstring_no_properties (Vcomp_abi_hash,
                                                make_fixnum (0),
@@ -3852,6 +3861,71 @@ compile_function (Lisp_Object func)
 /* Entry points exposed to lisp.  */
 /**********************************/
 
+/* In use by Fcomp_el_to_eln_filename.  */
+static Lisp_Object loadsearch_re_list;
+
+DEFUN ("comp-el-to-eln-filename", Fcomp_el_to_eln_filename,
+       Scomp_el_to_eln_filename, 1, 2, 0,
+       doc: /* Given a source file return the corresponding .eln true filename.
+If BASE-DIR is nil use the first entry in `comp-eln-load-path'.  */)
+  (Lisp_Object filename, Lisp_Object base_dir)
+{
+  CHECK_STRING (filename);
+
+  if (suffix_p (filename, ".gz"))
+    filename = Fsubstring (filename, Qnil, make_fixnum (-3));
+  filename = Fexpand_file_name (filename, Qnil);
+
+  /* We create eln filenames with an hash in order to look-up these
+     starting from the source filename, IOW have a relation
+     /absolute/path/filename.el -> eln-cache/filename-hash.eln.
+
+     As installing .eln files compiled during the build changes their
+     absolute path we need an hashing mechanism that is not sensitive
+     to that.  For this we replace if match PATH_DUMPLOADSEARCH or
+     PATH_LOADSEARCH with '//' before generating the hash.
+
+     Another approach would be to hash using the source file content
+     but this may have a measurable performance impact.  */
+
+  if (NILP (loadsearch_re_list))
+    {
+      Lisp_Object loadsearch_list =
+       Fcons (build_string (PATH_DUMPLOADSEARCH),
+              Fcons (build_string (PATH_LOADSEARCH), Qnil));
+      FOR_EACH_TAIL (loadsearch_list)
+       loadsearch_re_list =
+         Fcons (Fregexp_quote (XCAR (loadsearch_list)), loadsearch_re_list);
+    }
+  Lisp_Object loadsearch_res = loadsearch_re_list;
+  FOR_EACH_TAIL (loadsearch_res)
+    {
+      Lisp_Object match_idx =
+       Fstring_match (XCAR (loadsearch_res), filename, Qnil);
+      if (EQ (match_idx, make_fixnum (0)))
+       {
+         filename =
+           Freplace_match (build_string ("//"), Qt, Qt, filename, Qnil);
+         break;
+       }
+    }
+
+  Lisp_Object hash = Fsubstring (comp_hash_string (filename), Qnil,
+                                make_fixnum (ELN_FILENAME_HASH_LEN));
+  filename = concat2 (Ffile_name_nondirectory (Fsubstring (filename, Qnil,
+                                                          make_fixnum (-3))),
+                      build_string ("-"));
+  filename = concat3 (filename, hash, build_string (NATIVE_ELISP_SUFFIX));
+  if (NILP (base_dir))
+    base_dir = XCAR (Vcomp_eln_load_path);
+
+  if (!file_name_absolute_p (SSDATA (base_dir)))
+    base_dir = Fexpand_file_name (base_dir, Vinvocation_directory);
+
+  return Fexpand_file_name (filename,
+                           concat2 (base_dir, Vcomp_native_path_postfix));
+}
+
 DEFUN ("comp--init-ctxt", Fcomp__init_ctxt, Scomp__init_ctxt,
        0, 0, 0,
        doc: /* Initialize the native compiler context. Return t on success.  
*/)
@@ -4039,11 +4113,12 @@ DEFUN ("comp--compile-ctxt-to-file", 
Fcomp__compile_ctxt_to_file,
        Scomp__compile_ctxt_to_file,
        1, 1, 0,
        doc: /* Compile as native code the current context to file.  */)
-  (Lisp_Object base_name)
+  (Lisp_Object file_name)
 {
   load_gccjit_if_necessary (true);
 
-  CHECK_STRING (base_name);
+  CHECK_STRING (file_name);
+  Lisp_Object base_name = Fsubstring (file_name, Qnil, make_fixnum (-4));
 
   gcc_jit_context_set_int_option (comp.ctxt,
                                  GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
@@ -4105,19 +4180,18 @@ DEFUN ("comp--compile-ctxt-to-file", 
Fcomp__compile_ctxt_to_file,
 
   AUTO_STRING (dot_so, NATIVE_ELISP_SUFFIX);
 
-  Lisp_Object out_file = CALLN (Fconcat, base_name, dot_so);
   Lisp_Object tmp_file =
     Fmake_temp_file_internal (base_name, Qnil, dot_so, Qnil);
   gcc_jit_context_compile_to_file (comp.ctxt,
                                   GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY,
                                   SSDATA (tmp_file));
 
-  CALL2I (comp--replace-output-file, out_file, tmp_file);
+  CALL2I (comp--replace-output-file, file_name, tmp_file);
 
   if (!noninteractive)
     unbind_to (count, Qnil);
 
-  return out_file;
+  return file_name;
 }
 
 DEFUN ("comp-libgccjit-version", Fcomp_libgccjit_version,
@@ -4462,7 +4536,11 @@ maybe_defer_native_compilation (Lisp_Object 
function_name,
     concat2 (CALL1I (file-name-sans-extension, Vload_true_file_name),
             build_pure_c_string (".el"));
   if (NILP (Ffile_exists_p (src)))
-    return;
+    {
+      src = concat2 (src, build_pure_c_string (".gz"));
+      if (NILP (Ffile_exists_p (src)))
+       return;
+    }
 
   /* This is to have deferred compilaiton able to compile comp
      dependecies breaking circularity.  */
@@ -4497,6 +4575,27 @@ maybe_defer_native_compilation (Lisp_Object 
function_name,
 /* Functions used to load eln files.  */
 /**************************************/
 
+/* Fixup the system eln-cache dir.  This is the last entry in
+   `comp-eln-load-path'.  */
+void
+fixup_eln_load_path (Lisp_Object directory)
+{
+  Lisp_Object last_cell = Qnil;
+  Lisp_Object tmp = Vcomp_eln_load_path;
+  FOR_EACH_TAIL (tmp)
+    if (CONSP (tmp))
+      last_cell = tmp;
+
+  Lisp_Object eln_cache_sys =
+    Ffile_name_directory (concat2 (Vinvocation_directory,
+                                  directory));
+  /* One directory up...  */
+  eln_cache_sys =
+    Ffile_name_directory (Fsubstring (eln_cache_sys, Qnil,
+                                     make_fixnum (-1)));
+  Fsetcar (last_cell, eln_cache_sys);
+}
+
 typedef char *(*comp_lit_str_func) (void);
 
 /* Deserialize read and return static object.  */
@@ -4869,7 +4968,13 @@ syms_of_comp (void)
 #ifdef HAVE_NATIVE_COMP
   /* Compiler control customizes.  */
   DEFVAR_BOOL ("comp-deferred-compilation", comp_deferred_compilation,
-              doc: /* If t compile asyncronously every .elc file loaded.  */);
+              doc: /* If non-nil compile asyncronously all .elc files
+being loaded.
+
+Once compilation happened each function definition is updated to the
+native compiled one.  */);
+  comp_deferred_compilation = true;
+
   DEFSYM (Qcomp_speed, "comp-speed");
   DEFSYM (Qcomp_debug, "comp-debug");
 
@@ -4971,6 +5076,7 @@ syms_of_comp (void)
         build_pure_c_string ("eln file inconsistent with current runtime "
                             "configuration, please recompile"));
 
+  defsubr (&Scomp_el_to_eln_filename);
   defsubr (&Scomp__init_ctxt);
   defsubr (&Scomp__release_ctxt);
   defsubr (&Scomp__compile_ctxt_to_file);
@@ -4989,6 +5095,8 @@ syms_of_comp (void)
   comp.emitter_dispatcher = Qnil;
   staticpro (&delayed_sources);
   delayed_sources = Qnil;
+  staticpro (&loadsearch_re_list);
+  loadsearch_re_list = Qnil;
 
 #ifdef WINDOWSNT
   staticpro (&all_loaded_comp_units_h);
@@ -5015,6 +5123,22 @@ syms_of_comp (void)
                       internal use during  */);
   Vcomp_deferred_pending_h = CALLN (Fmake_hash_table, QCtest, Qeq);
 
+  DEFVAR_LISP ("comp-eln-to-el-h", Vcomp_eln_to_el_h,
+              doc: /* Hash table eln-filename -> el-filename.  */);
+  Vcomp_eln_to_el_h = CALLN (Fmake_hash_table, QCtest, Qequal);
+
+  DEFVAR_LISP ("comp-eln-load-path", Vcomp_eln_load_path,
+              doc: /* List of eln cache directories.
+
+If a directory is non absolute is assumed to be relative to
+`invocation-directory'.
+The last directory of this list is assumed to be the system one.  */);
+
+  /* Temporary value in use for boostrap.  We can't do better as
+     `invocation-directory' is still unset, will be fixed up during
+     dump reload.  */
+  Vcomp_eln_load_path = Fcons (build_string ("../eln-cache/"), Qnil);
+
 #endif /* #ifdef HAVE_NATIVE_COMP */
 
   defsubr (&Snative_comp_available_p);
diff --git a/src/comp.h b/src/comp.h
index 687e426..9270f8b 100644
--- a/src/comp.h
+++ b/src/comp.h
@@ -101,6 +101,8 @@ extern void dispose_all_remaining_comp_units (void);
 
 extern void clean_package_user_dir_of_old_comp_units (void);
 
+extern void fixup_eln_load_path (Lisp_Object directory);
+
 #else /* #ifdef HAVE_NATIVE_COMP */
 
 static inline void
diff --git a/src/composite.c b/src/composite.c
index ec2b832..984e0d9 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -1258,7 +1258,7 @@ composition_reseat_it (struct composition_it *cmp_it, 
ptrdiff_t charpos,
             is backward in the buffer, which can only happen if the
             display routines were called to perform the bidi
             reordering.  But it doesn't harm to test for that, and
-            avoid someon raising their brows and thinking it's a
+            avoid someone raising their brows and thinking it's a
             subtle bug...  */
          if (bidi_level < 0)
            direction = Qnil;
@@ -1939,7 +1939,7 @@ syms_of_composite (void)
   staticpro (&gstring_hash_table);
 
   staticpro (&gstring_work_headers);
-  gstring_work_headers = make_uninit_vector (8);
+  gstring_work_headers = make_nil_vector (8);
   for (i = 0; i < 8; i++)
     ASET (gstring_work_headers, i, make_nil_vector (i + 2));
   staticpro (&gstring_work);
diff --git a/src/emacs.c b/src/emacs.c
index 288ddb4..8e52da7 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1643,23 +1643,27 @@ Using an Emacs configured with --with-x-toolkit=lucid 
does not have this problem
     {
 #ifdef NS_IMPL_COCOA
       /* Started from GUI? */
-      /* FIXME: Do the right thing if get_homedir returns "", or if
-         chdir fails.  */
-      if (! inhibit_window_system && ! isatty (STDIN_FILENO) && ! ch_to_dir)
-        chdir (get_homedir ());
+      bool go_home = (!ch_to_dir && !inhibit_window_system
+                     && !isatty (STDIN_FILENO));
       if (skip_args < argc)
         {
           if (!strncmp (argv[skip_args], "-psn", 4))
             {
               skip_args += 1;
-              if (! ch_to_dir) chdir (get_homedir ());
+             go_home |= !ch_to_dir;
             }
           else if (skip_args+1 < argc && !strncmp (argv[skip_args+1], "-psn", 
4))
             {
               skip_args += 2;
-              if (! ch_to_dir) chdir (get_homedir ());
+             go_home |= !ch_to_dir;
             }
         }
+      if (go_home)
+       {
+         char const *home = get_homedir ();
+         if (*home && chdir (home) == 0)
+           emacs_wd = emacs_get_current_dir_name ();
+       }
 #endif  /* COCOA */
     }
 #endif /* HAVE_NS */
diff --git a/src/fns.c b/src/fns.c
index 9199178..a3b8d6e 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -1747,25 +1747,27 @@ changing the value of a sequence `foo'.  */)
 {
   if (VECTORP (seq))
     {
-      ptrdiff_t i, n;
+      ptrdiff_t n = 0;
+      ptrdiff_t size = ASIZE (seq);
+      USE_SAFE_ALLOCA;
+      Lisp_Object *kept = SAFE_ALLOCA (size * sizeof *kept);
 
-      for (i = n = 0; i < ASIZE (seq); ++i)
-       if (NILP (Fequal (AREF (seq, i), elt)))
-         ++n;
-
-      if (n != ASIZE (seq))
+      for (ptrdiff_t i = 0; i < size; i++)
        {
-         struct Lisp_Vector *p = allocate_vector (n);
+         kept[n] = AREF (seq, i);
+         n += NILP (Fequal (AREF (seq, i), elt));
+       }
 
-         for (i = n = 0; i < ASIZE (seq); ++i)
-           if (NILP (Fequal (AREF (seq, i), elt)))
-             p->contents[n++] = AREF (seq, i);
+      if (n != size)
+       seq = Fvector (n, kept);
 
-         XSETVECTOR (seq, p);
-       }
+      SAFE_FREE ();
     }
   else if (STRINGP (seq))
     {
+      if (!CHARACTERP (elt))
+       return seq;
+
       ptrdiff_t i, ibyte, nchars, nbytes, cbytes;
       int c;
 
@@ -1784,7 +1786,7 @@ changing the value of a sequence `foo'.  */)
              cbytes = 1;
            }
 
-         if (!FIXNUMP (elt) || c != XFIXNUM (elt))
+         if (c != XFIXNUM (elt))
            {
              ++nchars;
              nbytes += cbytes;
@@ -1814,7 +1816,7 @@ changing the value of a sequence `foo'.  */)
                  cbytes = 1;
                }
 
-             if (!FIXNUMP (elt) || c != XFIXNUM (elt))
+             if (c != XFIXNUM (elt))
                {
                  unsigned char *from = SDATA (seq) + ibyte;
                  unsigned char *to   = SDATA (tem) + nbytes;
diff --git a/src/font.c b/src/font.c
index ab00402..5c01c7f 100644
--- a/src/font.c
+++ b/src/font.c
@@ -4847,21 +4847,18 @@ If the font is not OpenType font, CAPABILITY is nil.  
*/)
   (Lisp_Object font_object)
 {
   struct font *font = CHECK_FONT_GET_OBJECT (font_object);
-  Lisp_Object val = make_uninit_vector (9);
-
-  ASET (val, 0, AREF (font_object, FONT_NAME_INDEX));
-  ASET (val, 1, AREF (font_object, FONT_FILE_INDEX));
-  ASET (val, 2, make_fixnum (font->pixel_size));
-  ASET (val, 3, make_fixnum (font->max_width));
-  ASET (val, 4, make_fixnum (font->ascent));
-  ASET (val, 5, make_fixnum (font->descent));
-  ASET (val, 6, make_fixnum (font->space_width));
-  ASET (val, 7, make_fixnum (font->average_width));
-  if (font->driver->otf_capability)
-    ASET (val, 8, Fcons (Qopentype, font->driver->otf_capability (font)));
-  else
-    ASET (val, 8, Qnil);
-  return val;
+  return CALLN (Fvector,
+               AREF (font_object, FONT_NAME_INDEX),
+               AREF (font_object, FONT_FILE_INDEX),
+               make_fixnum (font->pixel_size),
+               make_fixnum (font->max_width),
+               make_fixnum (font->ascent),
+               make_fixnum (font->descent),
+               make_fixnum (font->space_width),
+               make_fixnum (font->average_width),
+               (font->driver->otf_capability
+                ? Fcons (Qopentype, font->driver->otf_capability (font))
+                : Qnil));
 }
 
 DEFUN ("font-get-glyphs", Ffont_get_glyphs, Sfont_get_glyphs, 3, 4, 0,
@@ -4889,7 +4886,7 @@ the corresponding element is nil.  */)
 {
   struct font *font = CHECK_FONT_GET_OBJECT (font_object);
   ptrdiff_t len;
-  Lisp_Object *chars, vec;
+  Lisp_Object *chars;
   USE_SAFE_ALLOCA;
 
   if (NILP (object))
@@ -4957,7 +4954,7 @@ the corresponding element is nil.  */)
   else
     wrong_type_argument (Qarrayp, object);
 
-  vec = make_uninit_vector (len);
+  Lisp_Object vec = make_nil_vector (len);
   for (ptrdiff_t i = 0; i < len; i++)
     {
       Lisp_Object g;
@@ -5168,24 +5165,23 @@ If the named font cannot be opened and loaded, return 
nil.  */)
     return Qnil;
   font = XFONT_OBJECT (font_object);
 
-  info = make_uninit_vector (14);
-  ASET (info, 0, AREF (font_object, FONT_NAME_INDEX));
-  ASET (info, 1, AREF (font_object, FONT_FULLNAME_INDEX));
-  ASET (info, 2, make_fixnum (font->pixel_size));
-  ASET (info, 3, make_fixnum (font->height));
-  ASET (info, 4, make_fixnum (font->baseline_offset));
-  ASET (info, 5, make_fixnum (font->relative_compose));
-  ASET (info, 6, make_fixnum (font->default_ascent));
-  ASET (info, 7, make_fixnum (font->max_width));
-  ASET (info, 8, make_fixnum (font->ascent));
-  ASET (info, 9, make_fixnum (font->descent));
-  ASET (info, 10, make_fixnum (font->space_width));
-  ASET (info, 11, make_fixnum (font->average_width));
-  ASET (info, 12, AREF (font_object, FONT_FILE_INDEX));
-  if (font->driver->otf_capability)
-    ASET (info, 13, Fcons (Qopentype, font->driver->otf_capability (font)));
-  else
-    ASET (info, 13, Qnil);
+  info = CALLN (Fvector,
+               AREF (font_object, FONT_NAME_INDEX),
+               AREF (font_object, FONT_FULLNAME_INDEX),
+               make_fixnum (font->pixel_size),
+               make_fixnum (font->height),
+               make_fixnum (font->baseline_offset),
+               make_fixnum (font->relative_compose),
+               make_fixnum (font->default_ascent),
+               make_fixnum (font->max_width),
+               make_fixnum (font->ascent),
+               make_fixnum (font->descent),
+               make_fixnum (font->space_width),
+               make_fixnum (font->average_width),
+               AREF (font_object, FONT_FILE_INDEX),
+               (font->driver->otf_capability
+                ? Fcons (Qopentype, font->driver->otf_capability (font))
+                : Qnil));
 
 #if 0
   /* As font_object is still in FONT_OBJLIST of the entity, we can't
@@ -5203,7 +5199,7 @@ If the named font cannot be opened and loaded, return 
nil.  */)
 static Lisp_Object
 build_style_table (const struct table_entry *entry, int nelement)
 {
-  Lisp_Object table = make_uninit_vector (nelement);
+  Lisp_Object table = make_nil_vector (nelement);
   for (int i = 0; i < nelement; i++)
     {
       int j;
@@ -5494,10 +5490,8 @@ This variable cannot be set; trying to do so will signal 
an error.  */);
   make_symbol_constant (intern_c_string ("font-width-table"));
 
   staticpro (&font_style_table);
-  font_style_table = make_uninit_vector (3);
-  ASET (font_style_table, 0, Vfont_weight_table);
-  ASET (font_style_table, 1, Vfont_slant_table);
-  ASET (font_style_table, 2, Vfont_width_table);
+  font_style_table = CALLN (Fvector, Vfont_weight_table, Vfont_slant_table,
+                           Vfont_width_table);
 
   DEFVAR_LISP ("font-log", Vfont_log, doc: /*
 A list that logs font-related actions and results, for debugging.
diff --git a/src/fontset.c b/src/fontset.c
index c2bb8b2..8c86075 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -252,14 +252,13 @@ set_fontset_fallback (Lisp_Object fontset, Lisp_Object 
fallback)
 
 #define BASE_FONTSET_P(fontset) (NILP (FONTSET_BASE (fontset)))
 
-/* Macros for FONT-DEF and RFONT-DEF of fontset.  */
-#define FONT_DEF_NEW(font_def, font_spec, encoding, repertory) \
-  do {                                                         \
-    (font_def) = make_uninit_vector (3);                       \
-    ASET ((font_def), 0, font_spec);                           \
-    ASET ((font_def), 1, encoding);                            \
-    ASET ((font_def), 2, repertory);                           \
-  } while (0)
+/* Definitions for FONT-DEF and RFONT-DEF of fontset.  */
+static Lisp_Object
+font_def_new (Lisp_Object font_spec, Lisp_Object encoding,
+             Lisp_Object repertory)
+{
+  return CALLN (Fvector, font_spec, encoding, repertory);
+}
 
 #define FONT_DEF_SPEC(font_def) AREF (font_def, 0)
 #define FONT_DEF_ENCODING(font_def) AREF (font_def, 1)
@@ -1547,7 +1546,7 @@ appended.  By default, FONT-SPEC overrides the previous 
settings.  */)
              repertory = CHARSET_SYMBOL_ID (repertory);
            }
        }
-      FONT_DEF_NEW (font_def, font_spec, encoding, repertory);
+      font_def = font_def_new (font_spec, encoding, repertory);
     }
   else
     font_def = Qnil;
@@ -1619,14 +1618,8 @@ appended.  By default, FONT-SPEC overrides the previous 
settings.  */)
 
   if (charset)
     {
-      Lisp_Object arg;
-
-      arg = make_uninit_vector (5);
-      ASET (arg, 0, fontset);
-      ASET (arg, 1, font_def);
-      ASET (arg, 2, add);
-      ASET (arg, 3, ascii_changed ? Qt : Qnil);
-      ASET (arg, 4, range_list);
+      Lisp_Object arg = CALLN (Fvector, fontset, font_def, add,
+                              ascii_changed ? Qt : Qnil, range_list);
 
       map_charset_chars (set_fontset_font, Qnil, arg, charset,
                         CHARSET_MIN_CODE (charset),
diff --git a/src/ftfont.c b/src/ftfont.c
index 696f5e6..a904007 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -2826,14 +2826,10 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font 
*font,
       LGLYPH_SET_ASCENT (lglyph, g->g.ascent >> 6);
       LGLYPH_SET_DESCENT (lglyph, g->g.descent >> 6);
       if (g->g.adjusted)
-       {
-         Lisp_Object vec = make_uninit_vector (3);
-
-         ASET (vec, 0, make_fixnum (g->g.xoff >> 6));
-         ASET (vec, 1, make_fixnum (g->g.yoff >> 6));
-         ASET (vec, 2, make_fixnum (g->g.xadv >> 6));
-         LGLYPH_SET_ADJUSTMENT (lglyph, vec);
-       }
+       LGLYPH_SET_ADJUSTMENT (lglyph, CALLN (Fvector,
+                                             make_fixnum (g->g.xoff >> 6),
+                                             make_fixnum (g->g.yoff >> 6),
+                                             make_fixnum (g->g.xadv >> 6)));
     }
   return make_fixnum (i);
 }
diff --git a/src/hbfont.c b/src/hbfont.c
index 4b3f64e..82b115e 100644
--- a/src/hbfont.c
+++ b/src/hbfont.c
@@ -594,13 +594,10 @@ hbfont_shape (Lisp_Object lgstring, Lisp_Object direction)
       yoff = - lround (pos[i].y_offset * position_unit);
       wadjust = lround (pos[i].x_advance * position_unit);
       if (xoff || yoff || wadjust != metrics.width)
-       {
-         Lisp_Object vec = make_uninit_vector (3);
-         ASET (vec, 0, make_fixnum (xoff));
-         ASET (vec, 1, make_fixnum (yoff));
-         ASET (vec, 2, make_fixnum (wadjust));
-         LGLYPH_SET_ADJUSTMENT (lglyph, vec);
-       }
+       LGLYPH_SET_ADJUSTMENT (lglyph, CALLN (Fvector,
+                                             make_fixnum (xoff),
+                                             make_fixnum (yoff),
+                                             make_fixnum (wadjust)));
     }
 
   return make_fixnum (glyph_len);
diff --git a/src/image.c b/src/image.c
index e236b38..643b3d0 100644
--- a/src/image.c
+++ b/src/image.c
@@ -803,17 +803,23 @@ valid_image_p (Lisp_Object object)
     {
       Lisp_Object tail = XCDR (object);
       FOR_EACH_TAIL_SAFE (tail)
-       if (EQ (XCAR (tail), QCtype))
-         {
-           tail = XCDR (tail);
-           if (CONSP (tail))
-             {
-               struct image_type const *type = lookup_image_type (XCAR (tail));
-               if (type)
-                 return type->valid_p (object);
-             }
-           break;
-         }
+       {
+         if (EQ (XCAR (tail), QCtype))
+           {
+             tail = XCDR (tail);
+             if (CONSP (tail))
+               {
+                 struct image_type const *type =
+                   lookup_image_type (XCAR (tail));
+                 if (type)
+                   return type->valid_p (object);
+               }
+             break;
+           }
+         tail = XCDR (tail);
+         if (! CONSP (tail))
+           return false;
+       }
     }
 
   return false;
@@ -899,7 +905,7 @@ parse_image_spec (Lisp_Object spec, struct image_keyword 
*keywords,
     return false;
 
   plist = XCDR (spec);
-  while (CONSP (plist))
+  FOR_EACH_TAIL_SAFE (plist)
     {
       Lisp_Object key, value;
 
@@ -913,7 +919,6 @@ parse_image_spec (Lisp_Object spec, struct image_keyword 
*keywords,
       if (!CONSP (plist))
        return false;
       value = XCAR (plist);
-      plist = XCDR (plist);
 
       /* Find key in KEYWORDS.  Error if not found.  */
       for (i = 0; i < nkeywords; ++i)
@@ -921,7 +926,7 @@ parse_image_spec (Lisp_Object spec, struct image_keyword 
*keywords,
          break;
 
       if (i == nkeywords)
-       continue;
+       goto maybe_done;
 
       /* Record that we recognized the keyword.  If a keyword
         was found more than once, it's an error.  */
@@ -1009,14 +1014,20 @@ parse_image_spec (Lisp_Object spec, struct 
image_keyword *keywords,
       if (EQ (key, QCtype)
          && !(EQ (type, value) || EQ (type, Qnative_image)))
        return false;
-    }
 
-  /* Check that all mandatory fields are present.  */
-  for (i = 0; i < nkeywords; ++i)
-    if (keywords[i].count < keywords[i].mandatory_p)
-      return false;
+    maybe_done:
+      if (EQ (XCDR (plist), Qnil))
+       {
+         /* Check that all mandatory fields are present.  */
+         for (i = 0; i < nkeywords; ++i)
+           if (keywords[i].mandatory_p && keywords[i].count == 0)
+             return false;
+
+         return true;
+       }
+    }
 
-  return NILP (plist);
+  return false;
 }
 
 
@@ -1031,9 +1042,8 @@ image_spec_value (Lisp_Object spec, Lisp_Object key, bool 
*found)
 
   eassert (valid_image_p (spec));
 
-  for (tail = XCDR (spec);
-       CONSP (tail) && CONSP (XCDR (tail));
-       tail = XCDR (XCDR (tail)))
+  tail = XCDR (spec);
+  FOR_EACH_TAIL_SAFE (tail)
     {
       if (EQ (XCAR (tail), key))
        {
@@ -1041,6 +1051,9 @@ image_spec_value (Lisp_Object spec, Lisp_Object key, bool 
*found)
            *found = 1;
          return XCAR (XCDR (tail));
        }
+      tail = XCDR (tail);
+      if (! CONSP (tail))
+       break;
     }
 
   if (found)
@@ -1584,6 +1597,16 @@ make_image_cache (void)
   return c;
 }
 
+/* Compare two lists (one of which must be proper), comparing each
+   element with `eq'.  */
+static bool
+equal_lists (Lisp_Object a, Lisp_Object b)
+{
+  while (CONSP (a) && CONSP (b) && EQ (XCAR (a), XCAR (b)))
+    a = XCDR (a), b = XCDR (b);
+
+  return EQ (a, b);
+}
 
 /* Find an image matching SPEC in the cache, and return it.  If no
    image is found, return NULL.  */
@@ -1610,7 +1633,7 @@ search_image_cache (struct frame *f, Lisp_Object spec, 
EMACS_UINT hash)
 
   for (img = c->buckets[i]; img; img = img->next)
     if (img->hash == hash
-       && !NILP (Fequal (img->spec, spec))
+       && !equal_lists (img->spec, spec)
        && img->frame_foreground == FRAME_FOREGROUND_PIXEL (f)
        && img->frame_background == FRAME_BACKGROUND_PIXEL (f))
       break;
diff --git a/src/lisp.h b/src/lisp.h
index 5f913b7..ddaeb0c 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1812,7 +1812,8 @@ bool_vector_uchar_data (Lisp_Object a)
 INLINE bool
 bool_vector_bitref (Lisp_Object a, EMACS_INT i)
 {
-  eassume (0 <= i && i < bool_vector_size (a));
+  eassume (0 <= i);
+  eassert (i < bool_vector_size (a));
   return !! (bool_vector_uchar_data (a)[i / BOOL_VECTOR_BITS_PER_CHAR]
             & (1 << (i % BOOL_VECTOR_BITS_PER_CHAR)));
 }
@@ -1828,11 +1829,11 @@ bool_vector_ref (Lisp_Object a, EMACS_INT i)
 INLINE void
 bool_vector_set (Lisp_Object a, EMACS_INT i, bool b)
 {
-  unsigned char *addr;
-
-  eassume (0 <= i && i < bool_vector_size (a));
-  addr = &bool_vector_uchar_data (a)[i / BOOL_VECTOR_BITS_PER_CHAR];
+  eassume (0 <= i);
+  eassert (i < bool_vector_size (a));
 
+  unsigned char *addr
+    = &bool_vector_uchar_data (a)[i / BOOL_VECTOR_BITS_PER_CHAR];
   if (b)
     *addr |= 1 << (i % BOOL_VECTOR_BITS_PER_CHAR);
   else
@@ -3926,7 +3927,6 @@ build_string (const char *str)
 
 extern Lisp_Object pure_cons (Lisp_Object, Lisp_Object);
 extern Lisp_Object make_vector (ptrdiff_t, Lisp_Object);
-extern struct Lisp_Vector *allocate_vector (ptrdiff_t);
 extern struct Lisp_Vector *allocate_nil_vector (ptrdiff_t);
 
 /* Make an uninitialized vector for SIZE objects.  NOTE: you must
@@ -3936,7 +3936,11 @@ extern struct Lisp_Vector *allocate_nil_vector 
(ptrdiff_t);
    v = make_uninit_vector (3);
    ASET (v, 0, obj0);
    ASET (v, 1, Ffunction_can_gc ());
-   ASET (v, 2, obj1);  */
+   ASET (v, 2, obj1);
+
+   allocate_vector has a similar problem.  */
+
+extern struct Lisp_Vector *allocate_vector (ptrdiff_t);
 
 INLINE Lisp_Object
 make_uninit_vector (ptrdiff_t size)
diff --git a/src/lread.c b/src/lread.c
index f5a7d44..521da4e 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1099,7 +1099,7 @@ close_infile_unwind (void *arg)
   infile = prev_infile;
 }
 
-static Lisp_Object
+static ATTRIBUTE_UNUSED Lisp_Object
 parent_directory (Lisp_Object directory)
 {
   return Ffile_name_directory (Fsubstring (directory,
@@ -1231,8 +1231,7 @@ Return t if the file exists and loads successfully.  */)
            suffixes = CALLN (Fappend, suffixes, Vload_file_rep_suffixes);
        }
 
-      fd =
-       openp (Vload_path, file, suffixes, &found, Qnil, load_prefer_newer);
+      fd = openp (Vload_path, file, suffixes, &found, Qnil, load_prefer_newer);
     }
 
   if (fd == -1)
@@ -1478,9 +1477,8 @@ Return t if the file exists and loads successfully.  */)
         same folder of their respective sources therfore not to break
         packages we fake `load-file-name' here.  The non faked
         version of it is `load-true-file-name'. */
-      specbind (Qload_file_name,
-               concat2 (parent_directory (Ffile_name_directory (found)),
-                        Ffile_name_nondirectory (found)));
+      specbind (Qload_file_name, Fgethash (Ffile_name_nondirectory (found),
+                                          Vcomp_eln_to_el_h, Qnil));
     }
   else
     specbind (Qload_file_name, found);
@@ -1608,118 +1606,52 @@ directories, make sure the PREDICATE function returns 
`dir-ok' for them.  */)
   return file;
 }
 
-/* This function turns a list of suffixes into a list of middle dirs
-   and suffixes.  If the suffix is not NATIVE_ELISP_SUFFIX then its
-   suffix is nil and it is added to the list as is.  Instead, if it
-   suffix is NATIVE_ELISP_SUFFIX then two elements are added to the
-   list.  The first one has middledir equal to nil and the second uses
-   comp-native-path-postfix as middledir.  This is because we'd like
-   to search for dir/foo.eln before dir/middledir/foo.eln.
-
-For example, it turns this:
-
-(".eln" ".elc" ".elc.gz" ".el" ".el.gz")
+/* Look for a suitable .eln file to be loaded in place of FILENAME.
+   If found replace the content of FILENAME and FD. */
 
- into this:
-
-((nil . ".eln")
- (comp-native-path-postfix . ".eln")
- (nil . ".elc")
- (nil . ".elc.gz")
- (nil . ".el")
- (nil . ".el.gz"))
-*/
-static Lisp_Object
-openp_add_middle_dir_to_suffixes (Lisp_Object suffixes)
+static void
+maybe_swap_for_eln (Lisp_Object *filename, int *fd, struct timespec mtime)
 {
-  Lisp_Object tail = suffixes;
-  Lisp_Object extended_suf = Qnil;
-  FOR_EACH_TAIL_SAFE (tail)
-    {
-      /*  suffixes may be a stack-based cons pointing to stack-based
-          strings.  We must copy the suffix if we are putting it into
-          a heap-based cons to avoid a dangling reference.  This would
-          lead to crashes during the GC.  */
-      CHECK_STRING_CAR (tail);
-      char * suf = SSDATA (XCAR (tail));
-      Lisp_Object copied_suffix = build_string (suf);
 #ifdef HAVE_NATIVE_COMP
-      if (strcmp (NATIVE_ELISP_SUFFIX, suf) == 0)
-        {
-          CHECK_STRING (Vcomp_native_path_postfix);
-          /* Here we add them in the opposite order so that nreverse
-             corrects it.  */
-          extended_suf = Fcons (Fcons (Qnil, copied_suffix), extended_suf);
-          extended_suf = Fcons (Fcons (Vcomp_native_path_postfix,
-                                       copied_suffix),
-                                extended_suf);
-        }
-      else
-#endif
-       extended_suf = Fcons (Fcons (Qnil, copied_suffix), extended_suf);
-    }
+  struct stat eln_st;
 
-  suffixes = Fnreverse (extended_suf);
-  return suffixes;
-}
+  if (load_no_native
+      || !suffix_p (*filename, ".elc"))
+    return;
 
-/*  This function takes a list of middledirs and suffixes and returns
-    the maximum buffer space that this part of the filename will
-    need.  */
-static ptrdiff_t
-openp_max_middledir_and_suffix_len (Lisp_Object middledir_and_suffixes)
-{
-  ptrdiff_t max_extra_len = 0;
-  Lisp_Object tail = middledir_and_suffixes;
-  FOR_EACH_TAIL_SAFE (tail)
+  /* Search eln in the eln-cache directories.  */
+  Lisp_Object eln_path_tail = Vcomp_eln_load_path;
+  FOR_EACH_TAIL_SAFE (eln_path_tail)
     {
-      Lisp_Object middledir_and_suffix = XCAR (tail);
-      Lisp_Object middledir = XCAR (middledir_and_suffix);
-      Lisp_Object suffix = XCDR (middledir_and_suffix);
-      ptrdiff_t len = SBYTES (suffix);
-      if (!NILP (middledir))
-          len += 2 + SBYTES (middledir); /* Add two slashes.  */
-      max_extra_len = max (max_extra_len, len);
-    }
-  return max_extra_len;
-}
+      Lisp_Object el_name =
+       Fsubstring (*filename, Qnil, make_fixnum (-1));
+      Lisp_Object eln_name =
+       Fcomp_el_to_eln_filename (el_name, XCAR (eln_path_tail));
+      int eln_fd = emacs_open (SSDATA (ENCODE_FILE (eln_name)), O_RDONLY, 0);
 
-/*  This function completes the FN buffer with the middledir,
-    basenameme, and suffix.  It takes the directory length in DIRNAME,
-    but it requires that it has been copied already to the start of
-    the buffer.
-
-    After this function the FN buffer will be (depending on middledir)
-    dirname/middledir/basename.suffix
-    or
-    dirname/basename.suffix
-*/
-static ptrdiff_t
-openp_fill_filename_buffer (char *fn, ptrdiff_t dirnamelen,
-                            Lisp_Object basenamewext,
-                            Lisp_Object middledir_and_suffix)
-{
-  Lisp_Object middledir = XCAR (middledir_and_suffix);
-  Lisp_Object suffix = XCDR (middledir_and_suffix);
-  ptrdiff_t basenamewext_len = SBYTES (basenamewext);
-  ptrdiff_t fnlen, lsuffix = SBYTES (suffix);
-  ptrdiff_t lmiddledir = 0;
-  if (!NILP (middledir))
-    {
-      /* Add 1 for the slash.  */
-      lmiddledir = SBYTES (middledir) + 1;
-      memcpy (fn + dirnamelen, SDATA (middledir),
-              lmiddledir - 1);
-      fn[dirnamelen + (lmiddledir - 1)] = '/';
+      if (eln_fd > 0)
+       {
+         if (fstat (eln_fd, &eln_st) || S_ISDIR (eln_st.st_mode))
+           emacs_close (eln_fd);
+         else
+           {
+             struct timespec eln_mtime = get_stat_mtime (&eln_st);
+             if (timespec_cmp (eln_mtime, mtime) > 0)
+               {
+                 *filename = eln_name;
+                 emacs_close (*fd);
+                 *fd = eln_fd;
+                 /* Store the eln -> el relation.  */
+                 Fputhash (Ffile_name_nondirectory (eln_name),
+                           el_name, Vcomp_eln_to_el_h);
+                 return;
+               }
+             else
+               emacs_close (eln_fd);
+           }
+       }
     }
-
-  memcpy (fn + dirnamelen + lmiddledir, SDATA (basenamewext),
-          basenamewext_len);
-  /* Make complete filename by appending SUFFIX.  */
-  memcpy (fn + dirnamelen + lmiddledir + basenamewext_len,
-          SDATA (suffix), lsuffix + 1);
-  fnlen = dirnamelen + lmiddledir + basenamewext_len + lsuffix;
-  return fnlen;
+#endif
 }
 
 /* Search for a file whose name is STR, looking in directories
@@ -1759,21 +1691,23 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object 
suffixes,
   ptrdiff_t want_length;
   Lisp_Object filename;
   Lisp_Object string, tail, encoded_fn, save_string;
-  Lisp_Object middledir_and_suffixes;
-  ptrdiff_t max_extra_len = 0;
+  ptrdiff_t max_suffix_len = 0;
   int last_errno = ENOENT;
   int save_fd = -1;
   USE_SAFE_ALLOCA;
-
   /* The last-modified time of the newest matching file found.
      Initialize it to something less than all valid timestamps.  */
   struct timespec save_mtime = make_timespec (TYPE_MINIMUM (time_t), -1);
 
   CHECK_STRING (str);
 
-  middledir_and_suffixes = openp_add_middle_dir_to_suffixes (suffixes);
-
-  max_extra_len = openp_max_middledir_and_suffix_len (middledir_and_suffixes);
+  tail = suffixes;
+  FOR_EACH_TAIL_SAFE (tail)
+    {
+      CHECK_STRING_CAR (tail);
+      max_suffix_len = max (max_suffix_len,
+                           SBYTES (XCAR (tail)));
+    }
 
   string = filename = encoded_fn = save_string = Qnil;
 
@@ -1790,7 +1724,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object 
suffixes,
      executable. */
   FOR_EACH_TAIL_SAFE (path)
    {
-    ptrdiff_t dirnamelen, prefixlen;
+    ptrdiff_t baselen, prefixlen;
 
     if (EQ (path, just_use_str))
       filename = str;
@@ -1807,40 +1741,35 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object 
suffixes,
          continue;
       }
 
-
     /* Calculate maximum length of any filename made from
        this path element/specified file name and any possible suffix.  */
-    want_length = max_extra_len + SBYTES (filename);
+    want_length = max_suffix_len + SBYTES (filename);
     if (fn_size <= want_length)
       {
        fn_size = 100 + want_length;
        fn = SAFE_ALLOCA (fn_size);
       }
 
-    Lisp_Object dirnamewslash = Ffile_name_directory (filename);
-    Lisp_Object basenamewext = Ffile_name_nondirectory (filename);
-
     /* Copy FILENAME's data to FN but remove starting /: if any.  */
-    prefixlen = ((SCHARS (dirnamewslash) > 2
-                 && SREF (dirnamewslash, 0) == '/'
-                 && SREF (dirnamewslash, 1) == ':')
+    prefixlen = ((SCHARS (filename) > 2
+                 && SREF (filename, 0) == '/'
+                 && SREF (filename, 1) == ':')
                 ? 2 : 0);
-    dirnamelen = SBYTES (dirnamewslash) - prefixlen;
-    memcpy (fn, SDATA (dirnamewslash) + prefixlen, dirnamelen);
+    baselen = SBYTES (filename) - prefixlen;
+    memcpy (fn, SDATA (filename) + prefixlen, baselen);
 
-    /* Loop over middledir_and_suffixes.  */
-    AUTO_LIST1 (empty_string_only, Fcons (Qnil, empty_unibyte_string));
-    tail = NILP (middledir_and_suffixes) ? empty_string_only
-                                         : middledir_and_suffixes;
+    /* Loop over suffixes.  */
+    AUTO_LIST1 (empty_string_only, empty_unibyte_string);
+    tail = NILP (suffixes) ? empty_string_only : suffixes;
     FOR_EACH_TAIL_SAFE (tail)
       {
-       Lisp_Object middledir_and_suffix = XCAR (tail);
-        Lisp_Object suffix = XCDR (middledir_and_suffix);
+       Lisp_Object suffix = XCAR (tail);
+       ptrdiff_t fnlen, lsuffix = SBYTES (suffix);
        Lisp_Object handler;
 
-        ptrdiff_t fnlen = openp_fill_filename_buffer (fn, dirnamelen,
-                                                      basenamewext,
-                                                      middledir_and_suffix);
+       /* Make complete filename by appending SUFFIX.  */
+       memcpy (fn + baselen, SDATA (suffix), lsuffix + 1);
+       fnlen = baselen + lsuffix;
 
        /* Check that the file exists and is not a directory.  */
        /* We used to only check for handlers on non-absolute file names:
@@ -1962,9 +1891,11 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object 
suffixes,
                  }
                else
                  {
+                   maybe_swap_for_eln (&string, &fd, get_stat_mtime (&st));
                    /* We succeeded; return this descriptor and filename.  */
                    if (storeptr)
                      *storeptr = string;
+
                    SAFE_FREE ();
                    return fd;
                  }
@@ -1973,6 +1904,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object 
suffixes,
            /* No more suffixes.  Return the newest.  */
            if (0 <= save_fd && ! CONSP (XCDR (tail)))
              {
+               maybe_swap_for_eln (&save_string, &save_fd, save_mtime);
                if (storeptr)
                  *storeptr = save_string;
                SAFE_FREE ();
@@ -5030,11 +4962,8 @@ to the specified file name if a suffix is allowed or 
required.  */);
   Vload_suffixes =
     Fcons (build_pure_c_string (MODULES_SECONDARY_SUFFIX), Vload_suffixes);
 #endif
-#endif
-#ifdef HAVE_NATIVE_COMP
-  Vload_suffixes = Fcons (build_pure_c_string (NATIVE_ELISP_SUFFIX), 
Vload_suffixes);
-#endif
 
+#endif
   DEFVAR_LISP ("module-file-suffix", Vmodule_file_suffix,
               doc: /* Suffix of loadable module file, or nil if modules are 
not supported.  */);
 #ifdef HAVE_MODULES
@@ -5228,6 +5157,11 @@ Note that if you customize this, obviously it will not 
affect files
 that are loaded before your customizations are read!  */);
   load_prefer_newer = 0;
 
+  DEFVAR_BOOL ("load-no-native", load_no_native,
+               doc: /* Do not try to load the a .eln file in place of
+                      a .elc one.  */);
+  load_no_native = false;
+
   /* Vsource_directory was initialized in init_lread.  */
 
   DEFSYM (Qcurrent_load_list, "current-load-list");
diff --git a/src/macfont.m b/src/macfont.m
index c7430d3..9048146 100644
--- a/src/macfont.m
+++ b/src/macfont.m
@@ -3137,10 +3137,8 @@ macfont_shape (Lisp_Object lgstring, Lisp_Object 
direction)
        wadjust = lround (gl->advance);
       if (xoff != 0 || yoff != 0 || wadjust != metrics.width)
         {
-          Lisp_Object vec = make_uninit_vector (3);
-          ASET (vec, 0, make_fixnum (xoff));
-          ASET (vec, 1, make_fixnum (yoff));
-          ASET (vec, 2, make_fixnum (wadjust));
+          Lisp_Object vec = CALLN (Fvector, make_fixnum (xoff),
+                                  make_fixnum (yoff), make_fixnum (wadjust));
           LGLYPH_SET_ADJUSTMENT (lglyph, vec);
         }
     }
diff --git a/src/minibuf.c b/src/minibuf.c
index cb302c5..e18ff17 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -251,7 +251,7 @@ read_minibuf_noninteractive (Lisp_Object prompt, bool 
expflag,
   else
     {
       xfree (line);
-      error ("Error reading from stdin");
+      xsignal1 (Qend_of_file, build_string ("Error reading from stdin"));
     }
 
   /* If Lisp form desired instead of string, parse it.  */
diff --git a/src/nsselect.m b/src/nsselect.m
index 38ac66e..7b1937f 100644
--- a/src/nsselect.m
+++ b/src/nsselect.m
@@ -114,7 +114,7 @@ clean_local_selection_data (Lisp_Object obj)
 
       if (size == 1)
         return clean_local_selection_data (AREF (obj, 0));
-      copy = make_uninit_vector (size);
+      copy = make_nil_vector (size);
       for (i = 0; i < size; i++)
         ASET (copy, i, clean_local_selection_data (AREF (obj, i)));
       return copy;
diff --git a/src/nsterm.m b/src/nsterm.m
index 9f5916d..98c5b69 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -7669,11 +7669,8 @@ not_in_argv (NSString *arg)
   /* macOS Sierra automatically enables tabbed windows.  We can't
      allow this to be enabled until it's available on a Free system.
      Currently it only happens by accident and is buggy anyway.  */
-#if defined (NS_IMPL_COCOA) \
-  && MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 101200
+#ifdef NS_IMPL_COCOA
   if ([win respondsToSelector: @selector(setTabbingMode:)])
-#endif
     [win setTabbingMode: NSWindowTabbingModeDisallowed];
 #endif
 
@@ -8424,25 +8421,17 @@ not_in_argv (NSString *arg)
 
 
 - (void)windowDidChangeBackingProperties:(NSNotification *)notification
-  /* Update the drawing buffer when the backing scale factor changes.  */
+  /* Update the drawing buffer when the backing properties change.  */
 {
   NSTRACE ("EmacsView windowDidChangeBackingProperties:]");
 
   if (! [self wantsUpdateLayer])
     return;
 
-  CGFloat old = [[[notification userInfo]
-                    objectForKey:@"NSBackingPropertyOldScaleFactorKey"]
-                  doubleValue];
-  CGFloat new = [[self window] backingScaleFactor];
-
-  if (old != new)
-    {
-      NSRect frame = [self frame];
-      [self createDrawingBuffer];
-      ns_clear_frame (emacsframe);
-      expose_frame (emacsframe, 0, 0, NSWidth (frame), NSHeight (frame));
-    }
+  NSRect frame = [self frame];
+  [self createDrawingBuffer];
+  ns_clear_frame (emacsframe);
+  expose_frame (emacsframe, 0, 0, NSWidth (frame), NSHeight (frame));
 }
 #endif /* NS_DRAW_TO_BUFFER */
 
diff --git a/src/nsxwidget.m b/src/nsxwidget.m
index 370abee..e81ca7f 100644
--- a/src/nsxwidget.m
+++ b/src/nsxwidget.m
@@ -388,7 +388,7 @@ js_to_lisp (id value)
       NSArray *nsarr = (NSArray *) value;
       EMACS_INT n = nsarr.count;
       Lisp_Object obj;
-      struct Lisp_Vector *p = allocate_vector (n);
+      struct Lisp_Vector *p = allocate_nil_vector (n);
 
       for (ptrdiff_t i = 0; i < n; ++i)
         p->contents[i] = js_to_lisp ([nsarr objectAtIndex:i]);
@@ -401,7 +401,7 @@ js_to_lisp (id value)
       NSArray *keys = nsdict.allKeys;
       ptrdiff_t n = keys.count;
       Lisp_Object obj;
-      struct Lisp_Vector *p = allocate_vector (n);
+      struct Lisp_Vector *p = allocate_nil_vector (n);
 
       for (ptrdiff_t i = 0; i < n; ++i)
         {
diff --git a/src/pdumper.c b/src/pdumper.c
index 629d096..9c615a9 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -4903,14 +4903,19 @@ struct dump_bitset
 };
 
 static bool
-dump_bitset_init (struct dump_bitset *bitset, size_t number_bits)
+dump_bitsets_init (struct dump_bitset bitset[2], size_t number_bits)
 {
-  int xword_size = sizeof (bitset->bits[0]);
+  int xword_size = sizeof (bitset[0].bits[0]);
   int bits_per_word = xword_size * CHAR_BIT;
   ptrdiff_t words_needed = divide_round_up (number_bits, bits_per_word);
-  bitset->number_words = words_needed;
-  bitset->bits = calloc (words_needed, xword_size);
-  return bitset->bits != NULL;
+  dump_bitset_word *bits = calloc (words_needed, 2 * xword_size);
+  if (!bits)
+    return false;
+  bitset[0].bits = bits;
+  bitset[0].number_words = bitset[1].number_words = words_needed;
+  bitset[1].bits = memset (bits + words_needed, UCHAR_MAX,
+                          words_needed * xword_size);
+  return true;
 }
 
 static dump_bitset_word *
@@ -4971,7 +4976,7 @@ struct pdumper_loaded_dump_private
   /* Copy of the header we read from the dump.  */
   struct dump_header header;
   /* Mark bits for objects in the dump; used during GC.  */
-  struct dump_bitset mark_bits;
+  struct dump_bitset mark_bits, last_mark_bits;
   /* Time taken to load the dump.  */
   double load_time;
   /* Dump file name.  */
@@ -5094,6 +5099,10 @@ pdumper_find_object_type_impl (const void *obj)
   dump_off offset = ptrdiff_t_to_dump_off ((uintptr_t) obj - 
dump_public.start);
   if (offset % DUMP_ALIGNMENT != 0)
     return PDUMPER_NO_OBJECT;
+  ptrdiff_t bitno = offset / DUMP_ALIGNMENT;
+  if (offset < dump_private.header.discardable_start
+      && !dump_bitset_bit_set_p (&dump_private.last_mark_bits, bitno))
+    return PDUMPER_NO_OBJECT;
   const struct dump_reloc *reloc =
     dump_find_relocation (&dump_private.header.object_starts, offset);
   return (reloc != NULL && dump_reloc_get_offset (*reloc) == offset)
@@ -5122,12 +5131,16 @@ pdumper_set_marked_impl (const void *obj)
   eassert (offset < dump_private.header.cold_start);
   eassert (offset < dump_private.header.discardable_start);
   ptrdiff_t bitno = offset / DUMP_ALIGNMENT;
+  eassert (dump_bitset_bit_set_p (&dump_private.last_mark_bits, bitno));
   dump_bitset_set_bit (&dump_private.mark_bits, bitno);
 }
 
 void
 pdumper_clear_marks_impl (void)
 {
+  dump_bitset_word *swap = dump_private.last_mark_bits.bits;
+  dump_private.last_mark_bits.bits = dump_private.mark_bits.bits;
+  dump_private.mark_bits.bits = swap;
   dump_bitset_clear (&dump_private.mark_bits);
 }
 
@@ -5249,9 +5262,13 @@ dump_do_dump_relocation (const uintptr_t dump_base,
              {
                fclose (file);
                installation_state = INSTALLED;
+               fixup_eln_load_path (XCAR (comp_u->file));
              }
            else
-             installation_state = LOCAL_BUILD;
+             {
+               installation_state = LOCAL_BUILD;
+               fixup_eln_load_path (XCDR (comp_u->file));
+             }
          }
 
        comp_u->file =
@@ -5423,7 +5440,7 @@ pdumper_load (const char *dump_filename, char *argv0, 
char const *original_pwd)
   int dump_page_size;
   dump_off adj_discardable_start;
 
-  struct dump_bitset mark_bits;
+  struct dump_bitset mark_bits[2];
   size_t mark_bits_needed;
 
   struct dump_header header_buf = { 0 };
@@ -5537,7 +5554,7 @@ pdumper_load (const char *dump_filename, char *argv0, 
char const *original_pwd)
   err = PDUMPER_LOAD_ERROR;
   mark_bits_needed =
     divide_round_up (header->discardable_start, DUMP_ALIGNMENT);
-  if (!dump_bitset_init (&mark_bits, mark_bits_needed))
+  if (!dump_bitsets_init (mark_bits, mark_bits_needed))
     goto out;
 
   /* Point of no return.  */
@@ -5545,7 +5562,8 @@ pdumper_load (const char *dump_filename, char *argv0, 
char const *original_pwd)
   dump_base = (uintptr_t) sections[DS_HOT].mapping;
   gflags.dumped_with_pdumper_ = true;
   dump_private.header = *header;
-  dump_private.mark_bits = mark_bits;
+  dump_private.mark_bits = mark_bits[0];
+  dump_private.last_mark_bits = mark_bits[1];
   dump_public.start = dump_base;
   dump_public.end = dump_public.start + dump_size;
 
diff --git a/src/search.c b/src/search.c
index 38c64ca..6fb3716 100644
--- a/src/search.c
+++ b/src/search.c
@@ -3271,7 +3271,7 @@ the buffer.  If the buffer doesn't have a cache, the 
value is nil.  */)
                TYPE_MAXIMUM (ptrdiff_t), &nl_count_cache, NULL, true);
 
   /* Create vector and populate it.  */
-  cache_newlines = make_uninit_vector (nl_count_cache);
+  cache_newlines = make_vector (nl_count_cache, make_fixnum (-1));
 
   if (nl_count_cache)
     {
@@ -3285,15 +3285,12 @@ the buffer.  If the buffer doesn't have a cache, the 
value is nil.  */)
            break;
          ASET (cache_newlines, i, make_fixnum (found - 1));
        }
-      /* Fill the rest of slots with an invalid position.  */
-      for ( ; i < nl_count_cache; i++)
-       ASET (cache_newlines, i, make_fixnum (-1));
     }
 
   /* Now do the same, but without using the cache.  */
   find_newline1 (BEGV, BEGV_BYTE, ZV, ZV_BYTE,
                 TYPE_MAXIMUM (ptrdiff_t), &nl_count_buf, NULL, true);
-  buf_newlines = make_uninit_vector (nl_count_buf);
+  buf_newlines = make_vector (nl_count_buf, make_fixnum (-1));
   if (nl_count_buf)
     {
       for (from = BEGV, found = from, i = 0; from < ZV; from = found, i++)
@@ -3306,14 +3303,10 @@ the buffer.  If the buffer doesn't have a cache, the 
value is nil.  */)
            break;
          ASET (buf_newlines, i, make_fixnum (found - 1));
        }
-      for ( ; i < nl_count_buf; i++)
-       ASET (buf_newlines, i, make_fixnum (-1));
     }
 
   /* Construct the value and return it.  */
-  val = make_uninit_vector (2);
-  ASET (val, 0, cache_newlines);
-  ASET (val, 1, buf_newlines);
+  val = CALLN (Fvector, cache_newlines, buf_newlines);
 
   if (old != NULL)
     set_buffer_internal_1 (old);
diff --git a/src/syntax.c b/src/syntax.c
index a03202d..9f77ea5 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -3617,9 +3617,9 @@ init_syntax_once (void)
   DEFSYM (Qsyntax_table, "syntax-table");
 
   /* Create objects which can be shared among syntax tables.  */
-  Vsyntax_code_object = make_uninit_vector (Smax);
+  Vsyntax_code_object = make_nil_vector (Smax);
   for (i = 0; i < Smax; i++)
-    ASET (Vsyntax_code_object, i, Fcons (make_fixnum (i), Qnil));
+    ASET (Vsyntax_code_object, i, list1 (make_fixnum (i)));
 
   /* Now we are ready to set up this property, so we can
      create syntax tables.  */
diff --git a/src/sysdep.c b/src/sysdep.c
index 6b54ed3..a1050c4 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -49,10 +49,14 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 # include <cygwin/fs.h>
 #endif
 
-#if defined DARWIN_OS || defined __FreeBSD__
+#if defined DARWIN_OS || defined __FreeBSD__ || defined __OpenBSD__
 # include <sys/sysctl.h>
 #endif
 
+#ifdef DARWIN_OS
+# include <libproc.h>
+#endif
+
 #ifdef __FreeBSD__
 /* Sparc/ARM machine/frame.h has 'struct frame' which conflicts with Emacs's
    'struct frame', so rename it.  */
@@ -3061,37 +3065,43 @@ list_system_processes (void)
   return proclist;
 }
 
-#elif defined DARWIN_OS || defined __FreeBSD__
+#elif defined DARWIN_OS || defined __FreeBSD__ || defined __OpenBSD__
 
 Lisp_Object
 list_system_processes (void)
 {
 #ifdef DARWIN_OS
   int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
+#elif defined __OpenBSD__
+  int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0,
+    sizeof (struct kinfo_proc), 4096};
 #else
   int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PROC};
 #endif
   size_t len;
+  size_t mibsize = sizeof mib / sizeof mib[0];
   struct kinfo_proc *procs;
   size_t i;
 
   Lisp_Object proclist = Qnil;
 
-  if (sysctl (mib, 3, NULL, &len, NULL, 0) != 0 || len == 0)
+  if (sysctl (mib, mibsize, NULL, &len, NULL, 0) != 0 || len == 0)
     return proclist;
 
   procs = xmalloc (len);
-  if (sysctl (mib, 3, procs, &len, NULL, 0) != 0 || len == 0)
+  if (sysctl (mib, mibsize, procs, &len, NULL, 0) != 0 || len == 0)
     {
       xfree (procs);
       return proclist;
     }
 
-  len /= sizeof (struct kinfo_proc);
+  len /= sizeof procs[0];
   for (i = 0; i < len; i++)
     {
 #ifdef DARWIN_OS
       proclist = Fcons (INT_TO_INTEGER (procs[i].kp_proc.p_pid), proclist);
+#elif defined __OpenBSD__
+      proclist = Fcons (INT_TO_INTEGER (procs[i].p_pid), proclist);
 #else
       proclist = Fcons (INT_TO_INTEGER (procs[i].ki_pid), proclist);
 #endif
@@ -3865,8 +3875,21 @@ system_process_attributes (Lisp_Object pid)
   if (gr)
     attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
 
+  char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
+  char *comm;
+
+  if (proc_pidpath (proc_id, pathbuf, sizeof(pathbuf)) > 0)
+    {
+      if ((comm = strrchr (pathbuf, '/')))
+        comm++;
+      else
+        comm = pathbuf;
+    }
+  else
+    comm = proc.kp_proc.p_comm;
+
   decoded_comm = (code_convert_string_norecord
-                 (build_unibyte_string (proc.kp_proc.p_comm),
+                 (build_unibyte_string (comm),
                   Vlocale_coding_system, 0));
 
   attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs);
diff --git a/src/timefns.c b/src/timefns.c
index 94cfddf..71d5e10 100644
--- a/src/timefns.c
+++ b/src/timefns.c
@@ -1312,11 +1312,12 @@ or (if you need time as a string) `format-time-string'. 
 */)
    ((size_t) -1) for MAXSIZE.
 
    This function behaves like nstrftime, except it allows NUL
-   bytes in FORMAT and it does not support nanoseconds.  */
+   bytes in FORMAT.  */
 static size_t
 emacs_nmemftime (char *s, size_t maxsize, const char *format,
                 size_t format_len, const struct tm *tp, timezone_t tz, int ns)
 {
+  int saved_errno = errno;
   size_t total = 0;
 
   /* Loop through all the NUL-terminated strings in the format
@@ -1326,30 +1327,25 @@ emacs_nmemftime (char *s, size_t maxsize, const char 
*format,
      '\0' byte so we must invoke it separately for each such string.  */
   for (;;)
     {
-      size_t len;
-      size_t result;
-
+      errno = 0;
+      size_t result = nstrftime (s, maxsize, format, tp, tz, ns);
+      if (result == 0 && errno != 0)
+       return result;
       if (s)
-       s[0] = '\1';
-
-      result = nstrftime (s, maxsize, format, tp, tz, ns);
-
-      if (s)
-       {
-         if (result == 0 && s[0] != '\0')
-           return 0;
-         s += result + 1;
-       }
+       s += result + 1;
 
       maxsize -= result + 1;
       total += result;
-      len = strlen (format);
+      size_t len = strlen (format);
       if (len == format_len)
-       return total;
+       break;
       total++;
       format += len + 1;
       format_len -= len + 1;
     }
+
+  errno = saved_errno;
+  return total;
 }
 
 static Lisp_Object
@@ -1379,10 +1375,11 @@ format_time_string (char const *format, ptrdiff_t 
formatlen,
 
   while (true)
     {
-      buf[0] = '\1';
+      errno = 0;
       len = emacs_nmemftime (buf, size, format, formatlen, tmp, tz, ns);
-      if ((0 < len && len < size) || (len == 0 && buf[0] == '\0'))
+      if (len != 0 || errno == 0)
        break;
+      eassert (errno == ERANGE);
 
       /* Buffer was too small, so make it bigger and try again.  */
       len = emacs_nmemftime (NULL, SIZE_MAX, format, formatlen, tmp, tz, ns);
diff --git a/src/window.c b/src/window.c
index e2dea8b..ef58f43 100644
--- a/src/window.c
+++ b/src/window.c
@@ -7465,7 +7465,7 @@ saved by this function.  */)
   data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window 
: Qnil;
   data->root_window = FRAME_ROOT_WINDOW (f);
   data->focus_frame = FRAME_FOCUS_FRAME (f);
-  Lisp_Object tem = make_uninit_vector (n_windows);
+  Lisp_Object tem = make_nil_vector (n_windows);
   data->saved_windows = tem;
   for (ptrdiff_t i = 0; i < n_windows; i++)
     ASET (tem, i, make_nil_vector (VECSIZE (struct saved_window)));
diff --git a/src/xdisp.c b/src/xdisp.c
index 4fe1c42..ad03ac4 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -180,8 +180,8 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
    present (non-empty) only if the corresponding display margin is
    shown in the window.  If the glyph array for a marginal area is not
    present its beginning and end coincide, i.e. such arrays are
-   actually empty (they contain no glyphs).  Frame glyph matrics, used
-   on text-mode terminals (see below) never have marginal areas, they
+   actually empty (they contain no glyphs).  Frame glyph matrices, used
+   on text-mode terminals (see below) never have marginal areas; they
    treat the entire frame-wide row of glyphs as a single large "text
    area".
 
@@ -7555,7 +7555,7 @@ get_next_display_element (struct it *it)
                  /* Merge `nobreak-space' into the current face.  */
                  face_id = merge_faces (it->w, Qnobreak_space, 0,
                                         it->face_id);
-                 XSETINT (it->ctl_chars[0], ' ');
+                 XSETINT (it->ctl_chars[0], it->c);
                  ctl_len = 1;
                  goto display_control;
                }
@@ -7568,7 +7568,7 @@ get_next_display_element (struct it *it)
                  /* Merge `nobreak-space' into the current face.  */
                  face_id = merge_faces (it->w, Qnobreak_hyphen, 0,
                                         it->face_id);
-                 XSETINT (it->ctl_chars[0], '-');
+                 XSETINT (it->ctl_chars[0], it->c);
                  ctl_len = 1;
                  goto display_control;
                }
diff --git a/src/xfaces.c b/src/xfaces.c
index 2c6e593..06d2f99 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -1572,22 +1572,18 @@ the face font sort order.  */)
   for (i = nfonts - 1; i >= 0; --i)
     {
       Lisp_Object font = AREF (vec, i);
-      Lisp_Object v = make_uninit_vector (8);
-      int point;
-      Lisp_Object spacing;
-
-      ASET (v, 0, AREF (font, FONT_FAMILY_INDEX));
-      ASET (v, 1, FONT_WIDTH_SYMBOLIC (font));
-      point = PIXEL_TO_POINT (XFIXNUM (AREF (font, FONT_SIZE_INDEX)) * 10,
-                             FRAME_RES_Y (f));
-      ASET (v, 2, make_fixnum (point));
-      ASET (v, 3, FONT_WEIGHT_SYMBOLIC (font));
-      ASET (v, 4, FONT_SLANT_SYMBOLIC (font));
-      spacing = Ffont_get (font, QCspacing);
-      ASET (v, 5, (NILP (spacing) || EQ (spacing, Qp)) ? Qnil : Qt);
-      ASET (v, 6, Ffont_xlfd_name (font, Qnil));
-      ASET (v, 7, AREF (font, FONT_REGISTRY_INDEX));
-
+      int point = PIXEL_TO_POINT (XFIXNUM (AREF (font, FONT_SIZE_INDEX)) * 10,
+                                 FRAME_RES_Y (f));
+      Lisp_Object spacing = Ffont_get (font, QCspacing);
+      Lisp_Object v = CALLN (Fvector,
+                            AREF (font, FONT_FAMILY_INDEX),
+                            FONT_WIDTH_SYMBOLIC (font),
+                            make_fixnum (point),
+                            FONT_WEIGHT_SYMBOLIC (font),
+                            FONT_SLANT_SYMBOLIC (font),
+                            NILP (spacing) || EQ (spacing, Qp) ? Qnil : Qt,
+                            Ffont_xlfd_name (font, Qnil),
+                            AREF (font, FONT_REGISTRY_INDEX));
       result = Fcons (v, result);
     }
 
diff --git a/src/xfns.c b/src/xfns.c
index 09dcbbf..78f977b 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -5890,7 +5890,8 @@ If WINDOW-ID is non-nil, change the property of that 
window instead
       elsize = element_format == 32 ? sizeof (long) : element_format >> 3;
       data = xnmalloc (nelements, elsize);
 
-      x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
+      x_fill_property_data (FRAME_X_DISPLAY (f), value, data, nelements,
+                            element_format);
     }
   else
     {
@@ -6196,10 +6197,10 @@ Otherwise, the return value is a vector with the 
following fields:
     {
       XFree (tmp_data);
 
-      prop_attr = make_uninit_vector (3);
-      ASET (prop_attr, 0, make_fixnum (actual_type));
-      ASET (prop_attr, 1, make_fixnum (actual_format));
-      ASET (prop_attr, 2, make_fixnum (bytes_remaining / (actual_format >> 
3)));
+      prop_attr = CALLN (Fvector,
+                        make_fixnum (actual_type),
+                        make_fixnum (actual_format),
+                        make_fixnum (bytes_remaining / (actual_format >> 3)));
     }
 
   unblock_input ();
@@ -8027,7 +8028,7 @@ If this equals the symbol 'resize-mode', Emacs uses GTK's 
resize mode to
 always trigger an immediate resize of the child frame.  This method is
 deprecated by GTK and may not work in future versions of that toolkit.
 It also may freeze Emacs when used with other desktop environments.  It
-avoids, however, the unpleasent flicker induced by the hiding approach.
+avoids, however, the unpleasant flicker induced by the hiding approach.
 
 This variable is considered a temporary workaround and will be hopefully
 eliminated in future versions of Emacs.  */);
diff --git a/src/xrdb.c b/src/xrdb.c
index e3a1fcb..3d7f715 100644
--- a/src/xrdb.c
+++ b/src/xrdb.c
@@ -289,9 +289,9 @@ get_user_app (const char *class)
       /* Check in the home directory.  This is a bit of a hack; let's
         hope one's home directory doesn't contain ':' or '%'.  */
       char const *home = get_homedir ();
-      db = search_magic_path (home, class, "%L/%N");
+      db = search_magic_path (home, class, "/%L/%N");
       if (! db)
-       db = search_magic_path (home, class, "%N");
+       db = search_magic_path (home, class, "/%N");
     }
 
   return db;
diff --git a/src/xselect.c b/src/xselect.c
index 48d6215..383aebf 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -1594,7 +1594,7 @@ selection_data_to_lisp_data (struct x_display_info 
*dpyinfo,
        return x_atom_to_symbol (dpyinfo, (Atom) idata[0]);
       else
        {
-         Lisp_Object v = make_uninit_vector (size / sizeof (int));
+         Lisp_Object v = make_nil_vector (size / sizeof (int));
 
          for (i = 0; i < size / sizeof (int); i++)
            ASET (v, i, x_atom_to_symbol (dpyinfo, (Atom) idata[i]));
@@ -1653,7 +1653,7 @@ selection_data_to_lisp_data (struct x_display_info 
*dpyinfo,
   else
     {
       ptrdiff_t i;
-      Lisp_Object v = make_uninit_vector (size / X_LONG_SIZE);
+      Lisp_Object v = make_nil_vector (size / X_LONG_SIZE);
 
       if (type == XA_INTEGER)
         {
@@ -1860,7 +1860,7 @@ clean_local_selection_data (Lisp_Object obj)
       Lisp_Object copy;
       if (size == 1)
        return clean_local_selection_data (AREF (obj, 0));
-      copy = make_uninit_vector (size);
+      copy = make_nil_vector (size);
       for (i = 0; i < size; i++)
        ASET (copy, i, clean_local_selection_data (AREF (obj, i)));
       return copy;
@@ -2276,23 +2276,28 @@ x_check_property_data (Lisp_Object data)
 
    DPY is the display use to look up X atoms.
    DATA is a Lisp list of values to be converted.
-   RET is the C array that contains the converted values.  It is assumed
-   it is big enough to hold all values.
+   RET is the C array that contains the converted values.
+   NELEMENTS_MAX is the number of values that will fit in RET.
+   Any excess values in DATA are ignored.
    FORMAT is 8, 16 or 32 and denotes char/short/long for each C value to
    be stored in RET.  Note that long is used for 32 even if long is more
    than 32 bits (see man pages for XChangeProperty, XGetWindowProperty and
    XClientMessageEvent).  */
 
 void
-x_fill_property_data (Display *dpy, Lisp_Object data, void *ret, int format)
+x_fill_property_data (Display *dpy, Lisp_Object data, void *ret,
+                     int nelements_max, int format)
 {
   unsigned long val;
   unsigned long  *d32 = (unsigned long  *) ret;
   unsigned short *d16 = (unsigned short *) ret;
   unsigned char  *d08 = (unsigned char  *) ret;
+  int nelements;
   Lisp_Object iter;
 
-  for (iter = data; CONSP (iter); iter = XCDR (iter))
+  for (iter = data, nelements = 0;
+       CONSP (iter) && nelements < nelements_max;
+       iter = XCDR (iter), nelements++)
     {
       Lisp_Object o = XCAR (iter);
 
@@ -2593,7 +2598,9 @@ x_send_client_event (Lisp_Object display, Lisp_Object 
dest, Lisp_Object from,
   event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest;
 
   memset (event.xclient.data.l, 0, sizeof (event.xclient.data.l));
+  /* event.xclient.data can hold 20 chars, 10 shorts, or 5 longs.  */
   x_fill_property_data (dpyinfo->display, values, event.xclient.data.b,
+                        5 * 32 / event.xclient.format,
                         event.xclient.format);
 
   /* If event mask is 0 the event is sent to the client that created
diff --git a/src/xterm.c b/src/xterm.c
index 6340700..2e0407a 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8760,6 +8760,20 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       goto OTHER;
 
     case FocusIn:
+      /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap
+         minimized/iconified windows; thus, for those WMs we won't get
+         a MapNotify when unminimizing/deconifying.  Check here if we
+         are deconizing a window (Bug42655). */
+      f = any;
+      if (f && FRAME_ICONIFIED_P (f))
+       {
+          SET_FRAME_VISIBLE (f, 1);
+          SET_FRAME_ICONIFIED (f, false);
+          f->output_data.x->has_been_visible = true;
+          inev.ie.kind = DEICONIFY_EVENT;
+          XSETFRAME (inev.ie.frame_or_window, f);
+        }
+
       x_detect_focus_change (dpyinfo, any, event, &inev.ie);
       goto OTHER;
 
@@ -9907,6 +9921,13 @@ x_uncatch_errors (void)
 {
   struct x_error_message_stack *tmp;
 
+  /* In rare situations when running Emacs run in daemon mode,
+     shutting down an emacsclient via delete-frame can cause
+     x_uncatch_errors to be called when x_error_message is set to
+     NULL.  */
+  if (x_error_message == NULL)
+    return;
+
   block_input ();
 
   /* The display may have been closed before this function is called.
diff --git a/src/xterm.h b/src/xterm.h
index bc10043..db8d584 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1207,6 +1207,7 @@ extern int x_check_property_data (Lisp_Object);
 extern void x_fill_property_data (Display *,
                                   Lisp_Object,
                                   void *,
+                                 int,
                                   int);
 extern Lisp_Object x_property_data_to_lisp (struct frame *,
                                             const unsigned char *,
diff --git a/src/xwidget.c b/src/xwidget.c
index c61f5be..154b3e9 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -343,7 +343,7 @@ webkit_js_to_lisp (JSCValue *value)
        memory_full (SIZE_MAX);
 
       ptrdiff_t n = dlen;
-      struct Lisp_Vector *p = allocate_vector (n);
+      struct Lisp_Vector *p = allocate_nil_vector (n);
 
       for (ptrdiff_t i = 0; i < n; ++i)
        {
@@ -361,7 +361,7 @@ webkit_js_to_lisp (JSCValue *value)
       Lisp_Object obj;
       if (PTRDIFF_MAX < n)
        memory_full (n);
-      struct Lisp_Vector *p = allocate_vector (n);
+      struct Lisp_Vector *p = allocate_nil_vector (n);
 
       for (ptrdiff_t i = 0; i < n; ++i)
        {
diff --git a/test/lisp/cedet/srecode-utest-template.el 
b/test/lisp/cedet/srecode-utest-template.el
index 63c33a3..7c5bbc5 100644
--- a/test/lisp/cedet/srecode-utest-template.el
+++ b/test/lisp/cedet/srecode-utest-template.el
@@ -323,7 +323,6 @@ INSIDE SECTION: ARG HANDLER ONE")
 
 (ert-deftest srecode-utest-project ()
   "Test that project filtering works."
-  :expected-result (if (getenv "EMACS_HYDRA_CI") :failed :passed) ; fixme
   (save-excursion
     (let ((testbuff (find-file-noselect srecode-utest-testfile))
          (temp nil))
@@ -347,6 +346,10 @@ INSIDE SECTION: ARG HANDLER ONE")
       ;; Load the application templates, and make sure we can find them.
       (srecode-load-tables-for-mode major-mode 'tests)
 
+      (dolist (table (oref (srecode-table) tables))
+        (when (gethash "test" (oref table contexthash))
+          (oset table project default-directory)))
+
       (setq temp (srecode-template-get-table (srecode-table)
                                             "test-project"
                                             "test"
diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el 
b/test/lisp/emacs-lisp/bytecomp-tests.el
index 8949143..834e3b6 100644
--- a/test/lisp/emacs-lisp/bytecomp-tests.el
+++ b/test/lisp/emacs-lisp/bytecomp-tests.el
@@ -365,24 +365,24 @@ bytecompiled code, and their results compared.")
 (defun bytecomp-check-1 (pat)
   "Return non-nil if PAT is the same whether directly evalled or compiled."
   (let ((warning-minimum-log-level :emergency)
-       (byte-compile-warnings nil)
-       (v0 (condition-case nil
+        (byte-compile-warnings nil)
+       (v0 (condition-case err
                (eval pat)
-             (error 'bytecomp-check-error)))
-       (v1 (condition-case nil
+             (error (list 'bytecomp-check-error (car err)))))
+       (v1 (condition-case err
                (funcall (byte-compile (list 'lambda nil pat)))
-             (error 'bytecomp-check-error))))
+             (error (list 'bytecomp-check-error (car err))))))
     (equal v0 v1)))
 
 (put 'bytecomp-check-1 'ert-explainer 'bytecomp-explain-1)
 
 (defun bytecomp-explain-1 (pat)
-  (let ((v0 (condition-case nil
+  (let ((v0 (condition-case err
                (eval pat)
-             (error 'bytecomp-check-error)))
-       (v1 (condition-case nil
+             (error (list 'bytecomp-check-error (car err)))))
+       (v1 (condition-case err
                (funcall (byte-compile (list 'lambda nil pat)))
-             (error 'bytecomp-check-error))))
+             (error (list 'bytecomp-check-error (car err))))))
     (format "Expression `%s' gives `%s' if directly evalled, `%s' if compiled."
            pat v0 v1)))
 
@@ -405,12 +405,12 @@ Subtests signal errors if something goes wrong."
        (print-quoted t)
        v0 v1)
     (dolist (pat byte-opt-testsuite-arith-data)
-      (condition-case nil
+      (condition-case err
          (setq v0 (eval pat))
-       (error (setq v0 'bytecomp-check-error)))
-      (condition-case nil
+       (error (setq v0 (list 'bytecomp-check-error (car err)))))
+      (condition-case err
          (setq v1 (funcall (byte-compile (list 'lambda nil pat))))
-       (error (setq v1 'bytecomp-check-error)))
+       (error (setq v1 (list 'bytecomp-check-error (car err)))))
       (insert (format "%s" pat))
       (indent-to-column 65)
       (if (equal v0 v1)
@@ -479,6 +479,7 @@ Subtests signal errors if something goes wrong."
 (ert-deftest bytecomp-tests--warnings ()
   (with-current-buffer (get-buffer-create "*Compile-Log*")
     (let ((inhibit-read-only t)) (erase-buffer)))
+  (mapc #'fmakunbound '(my-test0 my--test11 my--test12 my--test2))
   (test-byte-comp-compile-and-load t
     '(progn
        (defun my-test0 ()
@@ -564,25 +565,25 @@ bytecompiled code, and their results compared.")
   "Return non-nil if PAT is the same whether directly evalled or compiled."
   (let ((warning-minimum-log-level :emergency)
        (byte-compile-warnings nil)
-       (v0 (condition-case nil
+       (v0 (condition-case err
                (eval pat t)
-             (error 'bytecomp-check-error)))
-       (v1 (condition-case nil
+             (error (list 'bytecomp-check-error (car err)))))
+       (v1 (condition-case err
                (funcall (let ((lexical-binding t))
                            (byte-compile `(lambda nil ,pat))))
-             (error 'bytecomp-check-error))))
+             (error (list 'bytecomp-check-error (car err))))))
     (equal v0 v1)))
 
 (put 'bytecomp-lexbind-check-1 'ert-explainer 'bytecomp-lexbind-explain-1)
 
 (defun bytecomp-lexbind-explain-1 (pat)
-  (let ((v0 (condition-case nil
+  (let ((v0 (condition-case err
                (eval pat t)
-             (error 'bytecomp-check-error)))
-       (v1 (condition-case nil
+             (error (list 'bytecomp-check-error (car err)))))
+       (v1 (condition-case err
                (funcall (let ((lexical-binding t))
                            (byte-compile (list 'lambda nil pat))))
-             (error 'bytecomp-check-error))))
+             (error (list 'bytecomp-check-error (car err))))))
     (format "Expression `%s' gives `%s' if directly evalled, `%s' if compiled."
            pat v0 v1)))
 
diff --git a/test/lisp/emacs-lisp/cl-lib-tests.el 
b/test/lisp/emacs-lisp/cl-lib-tests.el
index 57b9d23..40dd7e4 100644
--- a/test/lisp/emacs-lisp/cl-lib-tests.el
+++ b/test/lisp/emacs-lisp/cl-lib-tests.el
@@ -242,6 +242,22 @@
     (should (= (cl-the integer (cl-incf side-effect)) 1))
     (should (= side-effect 1))))
 
+(ert-deftest cl-lib-test-incf ()
+  (let ((var 0))
+    (should (= (cl-incf var) 1))
+    (should (= var 1)))
+  (let ((alist))
+    (should (= (cl-incf (alist-get 'a alist 0)) 1))
+    (should (= (alist-get 'a alist 0) 1))))
+
+(ert-deftest cl-lib-test-decf ()
+  (let ((var 1))
+    (should (= (cl-decf var) 0))
+    (should (= var 0)))
+  (let ((alist))
+    (should (= (cl-decf (alist-get 'a alist 0)) -1))
+    (should (= (alist-get 'a alist 0) -1))))
+
 (ert-deftest cl-lib-test-plusp ()
   (should-not (cl-plusp -1.0e+INF))
   (should-not (cl-plusp -1.5e2))
diff --git a/test/lisp/ffap-tests.el b/test/lisp/ffap-tests.el
index 30c8f79..e8c1266 100644
--- a/test/lisp/ffap-tests.el
+++ b/test/lisp/ffap-tests.el
@@ -77,6 +77,46 @@ left alone when opening a URL in an external browser."
     (should (compare-window-configurations (current-window-configuration) old))
     (should (equal urls '("https://www.gnu.org";)))))
 
+(defun ffap-test-string (space string)
+  (let ((ffap-file-name-with-spaces space))
+    (with-temp-buffer
+      (insert string)
+      (goto-char (point-min))
+      (forward-char 10)
+      (ffap-string-at-point))))
+
+(ert-deftest ffap-test-with-spaces ()
+  (should
+   (equal
+    (ffap-test-string
+     t "c:/Program Files/Open Text Evaluation Media/Open Text Exceed 14 
x86/Program here.txt")
+    "/Program Files/Open Text Evaluation Media/Open Text Exceed 14 x86/Program 
here.txt"))
+  (should
+   (equal
+    (ffap-test-string
+     nil "c:/Program Files/Open Text Evaluation Media/Open Text Exceed 14 
x86/Program here.txt")
+    "c:/Program"))
+  (should
+   (equal
+    (ffap-test-string
+     t "c:/Program Files/Open Text Evaluation Media/Open Text Exceed 14 
x86/Program Files/Hummingbird/")
+    "/Program Files/Open Text Evaluation Media/Open Text Exceed 14 x86/Program 
Files/Hummingbird/"))
+  (should
+   (equal
+    (ffap-test-string
+     t "c:\\Program Files\\Open Text Evaluation Media\\Open Text Exceed 14 
x86\\Program Files\\Hummingbird\\")
+    "\\Program Files\\Open Text Evaluation Media\\Open Text Exceed 14 
x86\\Program Files\\Hummingbird\\"))
+  (should
+   (equal
+    (ffap-test-string
+     t "c:\\Program Files\\Freescale\\CW for MPC55xx and MPC56xx 
2.10\\PowerPC_EABI_Tools\\Command_Line_Tools\\CLT_Usage_Notes.txt")
+    "\\Program Files\\Freescale\\CW for MPC55xx and MPC56xx 
2.10\\PowerPC_EABI_Tools\\Command_Line_Tools\\CLT_Usage_Notes.txt"))
+  (should
+   (equal
+    (ffap-test-string
+     t "C:\\temp\\program.log on Windows or /var/log/program.log on Unix.")
+    "\\temp\\program.log")))
+
 (provide 'ffap-tests)
 
 ;;; ffap-tests.el ends here
diff --git a/test/lisp/mail/flow-fill-tests.el 
b/test/lisp/mail/flow-fill-tests.el
index 4d435ae..c2e4178 100644
--- a/test/lisp/mail/flow-fill-tests.el
+++ b/test/lisp/mail/flow-fill-tests.el
@@ -35,7 +35,8 @@
           ">>> unmuzzled ratsbane!\n"
           ">>>> Henceforth, the coding style is to be strictly \n"
           ">>>> enforced, including the use of only upper case.\n"
-          ">>>>> I've noticed a lack of adherence to the coding \n"
+          ">>>>> I've noticed a lack of adherence to \n"
+          ">>>>> the coding \n"
           ">>>>> styles, of late.\n"
           ">>>>>> Any complaints?\n"))
         (output
diff --git a/test/lisp/progmodes/compile-tests.el 
b/test/lisp/progmodes/compile-tests.el
index cd73649..d566e7d 100644
--- a/test/lisp/progmodes/compile-tests.el
+++ b/test/lisp/progmodes/compile-tests.el
@@ -435,8 +435,8 @@ The test data is in `compile-tests--test-regexps-data'."
           (compilation-num-infos-found 0))
       (mapc #'compile--test-error-line compile-tests--test-regexps-data)
       (should (eq compilation-num-errors-found 94))
-      (should (eq compilation-num-warnings-found 37))
-      (should (eq compilation-num-infos-found 26)))))
+      (should (eq compilation-num-warnings-found 35))
+      (should (eq compilation-num-infos-found 28)))))
 
 (ert-deftest compile-test-grep-regexps ()
   "Test the `grep-regexp-alist' regexps.
diff --git a/test/lisp/progmodes/cperl-mode-tests.el 
b/test/lisp/progmodes/cperl-mode-tests.el
new file mode 100644
index 0000000..be8b42d
--- /dev/null
+++ b/test/lisp/progmodes/cperl-mode-tests.el
@@ -0,0 +1,51 @@
+;;; cperl-mode-tests --- Test for cperl-mode  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2020 Free Software Foundation, Inc.
+
+;; Author: Harald Jörg <haj@posteo.de>
+;; Maintainer: Harald Jörg
+;; Keywords: internal
+;; Homepage: https://github.com/HaraldJoerg/cperl-mode
+
+;;; Commentary:
+
+;; This is a collection of tests for the fontification of CPerl-mode.
+
+;; Run these tests interactively:
+;; (ert-run-tests-interactively '(tag :fontification))
+
+;;; Code:
+
+(defvar cperl-test-mode #'cperl-mode)
+
+(defun cperl-test-ppss (text regexp)
+  "Return the `syntax-ppss' of the first character matched by REGEXP in TEXT."
+  (interactive)
+  (with-temp-buffer
+    (insert text)
+    (funcall cperl-test-mode)
+    (goto-char (point-min))
+    (re-search-forward regexp)
+    (syntax-ppss)))
+
+(ert-deftest cperl-mode-test-bug-42168 ()
+  "Verify that '/' is a division after ++ or --, not a regexp.
+Reported in https://github.com/jrockway/cperl-mode/issues/45.
+If seen as regular expression, then the slash is displayed using
+font-lock-constant-face.  If seen as a division, then it doesn't
+have a face property."
+  :tags '(:fontification)
+  ;; The next two Perl expressions have divisions.  Perl "punctuation"
+  ;; operators don't get a face.
+  (let ((code "{ $a++ / $b }"))
+    (should (equal (nth 8 (cperl-test-ppss code "/")) nil)))
+  (let ((code "{ $a-- / $b }"))
+    (should (equal (nth 8 (cperl-test-ppss code "/")) nil)))
+  ;; The next two Perl expressions have regular expressions.  The
+  ;; delimiter of a RE is fontified with font-lock-constant-face.
+  (let ((code "{ $a+ / $b } # /"))
+    (should (equal (nth 8 (cperl-test-ppss code "/")) 7)))
+  (let ((code "{ $a- / $b } # /"))
+    (should (equal (nth 8 (cperl-test-ppss code "/")) 7))))
+
+;;; cperl-mode-tests.el ends here
diff --git a/test/lisp/simple-tests.el b/test/lisp/simple-tests.el
index 4adcacb..63e504b 100644
--- a/test/lisp/simple-tests.el
+++ b/test/lisp/simple-tests.el
@@ -39,6 +39,13 @@
      (with-no-warnings (simple-test--buffer-substrings))))
 
 
+;;; `count-words'
+(ert-deftest simple-test-count-words-bug-41761 ()
+  (with-temp-buffer
+    (dotimes (i 10) (insert (propertize "test " 'field (cons nil nil))))
+    (should (= (count-words (point-min) (point-max)) 10))))
+
+
 ;;; `transpose-sexps'
 (defmacro simple-test--transpositions (&rest body)
   (declare (indent 0)
diff --git a/test/lisp/textmodes/bibtex-tests.el 
b/test/lisp/textmodes/bibtex-tests.el
new file mode 100644
index 0000000..b3858de
--- /dev/null
+++ b/test/lisp/textmodes/bibtex-tests.el
@@ -0,0 +1,57 @@
+;;; bibtex-tests.el --- Test suite for bibtex.
+
+;; Copyright (C) 2013-2020 Free Software Foundation, Inc.
+
+;; Keywords: bibtex
+
+;; This file is part of GNU Emacs.
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'ert)
+(require 'bibtex)
+
+(ert-deftest bibtex-test-set-dialect ()
+  "Tests if `bibtex-set-dialect' is executed."
+  (with-temp-buffer
+    (insert "@article{someID,
+  author = {some author},
+  title = {some title},
+}")
+    (bibtex-mode)
+    (should-not (null bibtex-dialect))
+    (should-not (null bibtex-entry-type))
+    (should-not (null bibtex-entry-head))
+    (should-not (null bibtex-reference-key))
+    (should-not (null bibtex-entry-head))
+    (should-not (null bibtex-entry-maybe-empty-head))
+    (should-not (null bibtex-any-valid-entry-type))))
+
+(ert-deftest bibtex-test-parse-buffers-stealthily ()
+  "Tests if `bibtex-parse-buffers-stealthily' can be executed."
+  (with-temp-buffer
+    (insert "@article{someID,
+  author = {some author},
+  title = {some title},
+}")
+    (bibtex-mode)
+    (should (progn (bibtex-parse-buffers-stealthily) t))))
+
+(provide 'bibtex-tests)
+
+;;; bibtex-tests.el ends here
diff --git a/test/lisp/textmodes/paragraphs-tests.el 
b/test/lisp/textmodes/paragraphs-tests.el
index fc839fe..0b264e7 100644
--- a/test/lisp/textmodes/paragraphs-tests.el
+++ b/test/lisp/textmodes/paragraphs-tests.el
@@ -50,8 +50,8 @@
     (goto-char (point-min))
     (mark-paragraph)
     (should mark-active)
-    (should (equal (mark) 7)))
-  (should-error (mark-paragraph 0)))
+    (should (equal (mark) 7))))
+;;;  (should-error (mark-paragraph 0)))
 
 (ert-deftest paragraphs-tests-kill-paragraph ()
   (with-temp-buffer
diff --git a/test/lisp/url/url-expand-tests.el 
b/test/lisp/url/url-expand-tests.el
index 6e0ce86..3b0b6fb 100644
--- a/test/lisp/url/url-expand-tests.el
+++ b/test/lisp/url/url-expand-tests.el
@@ -100,6 +100,13 @@
   (should (equal (url-expand-file-name "foo#bar" "http://host/foobar";) 
"http://host/foo#bar";))
   (should (equal (url-expand-file-name "foo#bar" "http://host/foobar/";) 
"http://host/foobar/foo#bar";)))
 
+(ert-deftest url-expand-file-name/relative-resolution-file-url ()
+  "RFC 3986, Section 5.4 Reference Resolution Examples / Section 5.4.1. Normal 
Examples"
+  (should (equal (url-expand-file-name "bar.html"          
"file:///a/b/c/foo.html") "file:///a/b/c/bar.html"))
+  (should (equal (url-expand-file-name "bar.html"          "file:///a/b/c/")   
      "file:///a/b/c/bar.html"))
+  (should (equal (url-expand-file-name "../d/bar.html"     "file:///a/b/c/")   
      "file:///a/b/d/bar.html"))
+  (should (equal (url-expand-file-name "../d/bar.html"     
"file:///a/b/c/foo.html") "file:///a/b/d/bar.html")))
+
 (provide 'url-expand-tests)
 
 ;;; url-expand-tests.el ends here
diff --git a/test/manual/etags/c-src/abbrev.c b/test/manual/etags/c-src/abbrev.c
index 03b9f0e..44563d6 100644
--- a/test/manual/etags/c-src/abbrev.c
+++ b/test/manual/etags/c-src/abbrev.c
@@ -78,9 +78,6 @@ Lisp_Object Vlast_abbrev_text;
 
 int last_abbrev_point;
 
-/* Hook to run before expanding any abbrev.  */
-
-Lisp_Object Vpre_abbrev_expand_hook, Qpre_abbrev_expand_hook;
 
 DEFUN ("make-abbrev-table", Fmake_abbrev_table, Smake_abbrev_table, 0, 0, 0,
   "Create a new, empty abbrev table object.")
@@ -232,9 +229,6 @@ Returns the abbrev symbol, if expansion took place.")
 
   value = Qnil;
 
-  if (!NILP (Vrun_hooks))
-    call1 (Vrun_hooks, Qpre_abbrev_expand_hook);
-
   wordstart = 0;
   if (!(BUFFERP (Vabbrev_start_location_buffer)
        && XBUFFER (Vabbrev_start_location_buffer) == current_buffer))
@@ -595,14 +589,6 @@ This causes `save-some-buffers' to offer to save the 
abbrevs.");
     "*Set non-nil means expand multi-word abbrevs all caps if abbrev was so.");
   abbrev_all_caps = 0;
 
-  DEFVAR_LISP ("pre-abbrev-expand-hook", &Vpre_abbrev_expand_hook,
-    "Function or functions to be called before abbrev expansion is done.\n\
-This is the first thing that `expand-abbrev' does, and so this may change\n\
-the current abbrev table before abbrev lookup happens.");
-  Vpre_abbrev_expand_hook = Qnil;
-  Qpre_abbrev_expand_hook = intern ("pre-abbrev-expand-hook");
-  staticpro (&Qpre_abbrev_expand_hook);
-
   defsubr (&Smake_abbrev_table);
   defsubr (&Sclear_abbrev_table);
   defsubr (&Sdefine_abbrev);
diff --git a/test/manual/image-circular-tests.el 
b/test/manual/image-circular-tests.el
new file mode 100644
index 0000000..33ea3ea
--- /dev/null
+++ b/test/manual/image-circular-tests.el
@@ -0,0 +1,144 @@
+;;; image-tests.el --- Test suite for image-related functions.
+
+;; Copyright (C) 2019 Free Software Foundation, Inc.
+
+;; Author: Pip Cet <pipcet@gmail.com>
+;; Keywords:       internal
+;; Human-Keywords: internal
+
+;; This file is part of GNU Emacs.
+
+;; 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:
+
+;;; Code:
+
+(require 'ert)
+
+(ert-deftest image-test-duplicate-keywords ()
+  "Test that duplicate keywords in an image spec lead to rejection."
+  (should-error (image-size `(image :type xbm :type xbm :width 1 :height 1
+                                    :data ,(bool-vector t))
+                            t)))
+
+(ert-deftest image-test-circular-plist ()
+  "Test that a circular image spec is rejected."
+  (should-error
+   (let ((l `(image :type xbm :width 1 :height 1 :data ,(bool-vector t))))
+     (setcdr (last l) '#1=(:invalid . #1#))
+     (image-size l t))))
+
+(ert-deftest image-test-:type-property-value ()
+  "Test that :type is allowed as a property value in an image spec."
+  (should (equal (image-size `(image :dummy :type :type xbm :width 1 :height 1
+                                        :data ,(bool-vector t))
+                                t)
+                 (cons 1 1))))
+
+(ert-deftest image-test-circular-specs ()
+  "Test that circular image spec property values do not cause infinite 
recursion."
+  (should
+   (let* ((circ1 (cons :dummy nil))
+          (circ2 (cons :dummy nil))
+          (spec1 `(image :type xbm :width 1 :height 1
+                         :data ,(bool-vector 1) :ignored ,circ1))
+          (spec2 `(image :type xbm :width 1 :height 1
+                        :data ,(bool-vector 1) :ignored ,circ2)))
+     (setcdr circ1 circ1)
+     (setcdr circ2 circ2)
+     (and (equal (image-size spec1 t) (cons 1 1))
+          (equal (image-size spec2 t) (cons 1 1))))))
+
+(provide 'image-tests)
+;;; image-tests.el ends here.
+;;; image-tests.el --- tests for image.el -*- lexical-binding: t -*-
+
+;; Copyright (C) 2019-2020 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; 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/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'image)
+(eval-when-compile
+  (require 'cl-lib))
+
+(defconst image-tests--emacs-images-directory
+  (expand-file-name "../etc/images" (getenv "EMACS_TEST_DIRECTORY"))
+  "Directory containing Emacs images.")
+
+(ert-deftest image--set-property ()
+  "Test `image--set-property' behavior."
+  (let ((image (list 'image)))
+    ;; Add properties.
+    (setf (image-property image :scale) 1)
+    (should (equal image '(image :scale 1)))
+    (setf (image-property image :width) 8)
+    (should (equal image '(image :scale 1 :width 8)))
+    (setf (image-property image :height) 16)
+    (should (equal image '(image :scale 1 :width 8 :height 16)))
+    ;; Delete properties.
+    (setf (image-property image :type) nil)
+    (should (equal image '(image :scale 1 :width 8 :height 16)))
+    (setf (image-property image :scale) nil)
+    (should (equal image '(image :width 8 :height 16)))
+    (setf (image-property image :height) nil)
+    (should (equal image '(image :width 8)))
+    (setf (image-property image :width) nil)
+    (should (equal image '(image)))))
+
+(ert-deftest image-type-from-file-header-test ()
+  "Test image-type-from-file-header."
+  (should (eq (if (image-type-available-p 'svg) 'svg)
+             (image-type-from-file-header
+              (expand-file-name "splash.svg"
+                                image-tests--emacs-images-directory)))))
+
+(ert-deftest image-rotate ()
+  "Test `image-rotate'."
+  (cl-letf* ((image (list 'image))
+             ((symbol-function 'image--get-imagemagick-and-warn)
+              (lambda () image)))
+    (let ((current-prefix-arg '(4)))
+      (call-interactively #'image-rotate))
+    (should (equal image '(image :rotation 270.0)))
+    (call-interactively #'image-rotate)
+    (should (equal image '(image :rotation 0.0)))
+    (image-rotate)
+    (should (equal image '(image :rotation 90.0)))
+    (image-rotate 0)
+    (should (equal image '(image :rotation 90.0)))
+    (image-rotate 1)
+    (should (equal image '(image :rotation 91.0)))
+    (image-rotate 1234.5)
+    (should (equal image '(image :rotation 245.5)))
+    (image-rotate -154.5)
+    (should (equal image '(image :rotation 91.0)))))
+
+;;; image-tests.el ends here
diff --git a/test/src/comp-tests.el b/test/src/comp-tests.el
index 0925045..33b307b 100644
--- a/test/src/comp-tests.el
+++ b/test/src/comp-tests.el
@@ -54,7 +54,8 @@ Check that the resulting binaries do not differ."
          (comp-debug 0))
     (copy-file comp-src comp1-src t)
     (copy-file comp-src comp2-src t)
-    (load (concat comp-src "c") nil nil t t)
+    (let ((load-no-native t))
+      (load (concat comp-src "c") nil nil t t))
     (should-not (subr-native-elisp-p (symbol-function #'native-compile)))
     (message "Compiling stage1...")
     (let ((comp1-eln (native-compile comp1-src)))
diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el
index f1faf58..400e912 100644
--- a/test/src/fns-tests.el
+++ b/test/src/fns-tests.el
@@ -895,3 +895,9 @@
   ;; This does not test randomness; it's merely a format check.
   (should (string-match "\\`[0-9a-f]\\{128\\}\\'"
                         (secure-hash 'sha512 'iv-auto 100))))
+
+(ert-deftest test-vector-delete ()
+  (let ((v1 (make-vector 1000 1)))
+    (should (equal (delete t [nil t]) [nil]))
+    (should (equal (delete 1 v1) (vector)))
+    (should (equal (delete 2 v1) v1))))



reply via email to

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