emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] xwidget_mvp 8a5b2d3: Merge branch 'master' into xwidget_mv


From: Joakim Verona
Subject: [Emacs-diffs] xwidget_mvp 8a5b2d3: Merge branch 'master' into xwidget_mvp
Date: Thu, 19 Mar 2015 22:39:57 +0000

branch: xwidget_mvp
commit 8a5b2d3e3eb28eea2cf6f44d76a83b438e14dc28
Merge: 293c6a2 a68aa2e
Author: Joakim Verona <address@hidden>
Commit: Joakim Verona <address@hidden>

    Merge branch 'master' into xwidget_mvp
---
 ChangeLog                                 |   19 +
 configure.ac                              |   87 +++--
 doc/emacs/ChangeLog                       |   20 +
 doc/emacs/ack.texi                        |    2 +-
 doc/emacs/basic.texi                      |    4 +-
 doc/emacs/buffers.texi                    |    2 +-
 doc/emacs/cmdargs.texi                    |   49 ++-
 doc/emacs/display.texi                    |    4 +-
 doc/emacs/frames.texi                     |    2 +-
 doc/emacs/killing.texi                    |    2 +-
 doc/emacs/mini.texi                       |    2 +-
 doc/emacs/misc.texi                       |    2 +-
 doc/emacs/msdos-xtra.texi                 |    2 +-
 doc/emacs/msdos.texi                      |    2 +-
 doc/emacs/mule.texi                       |    2 +-
 doc/emacs/programs.texi                   |    4 +-
 doc/emacs/text.texi                       |    2 +-
 doc/emacs/trouble.texi                    |   10 +-
 doc/lispintro/emacs-lisp-intro.texi       |    6 +-
 doc/lispref/ChangeLog                     |    4 +
 doc/lispref/commands.texi                 |    6 +-
 doc/lispref/display.texi                  |    2 +-
 doc/lispref/elisp.texi                    |    4 +-
 doc/lispref/frames.texi                   |    4 +-
 doc/lispref/functions.texi                |    4 +-
 doc/lispref/internals.texi                |    2 +-
 doc/lispref/loading.texi                  |    2 +-
 doc/lispref/minibuf.texi                  |    4 +-
 doc/lispref/numbers.texi                  |    2 +-
 doc/lispref/streams.texi                  |    2 +-
 doc/lispref/text.texi                     |    4 +-
 doc/misc/ChangeLog                        |   10 +-
 doc/misc/auth.texi                        |    4 +-
 doc/misc/calc.texi                        |    2 +-
 doc/misc/cc-mode.texi                     |    4 +-
 doc/misc/efaq-w32.texi                    |  425 +++++++++-----------
 doc/misc/efaq.texi                        |   12 +-
 doc/misc/eieio.texi                       |    2 +-
 doc/misc/erc.texi                         |    6 +-
 doc/misc/eshell.texi                      |    2 +-
 doc/misc/eww.texi                         |    4 +-
 doc/misc/gnus.texi                        |    6 +-
 doc/misc/htmlfontify.texi                 |    4 +-
 doc/misc/idlwave.texi                     |    4 +-
 doc/misc/ido.texi                         |    2 +-
 doc/misc/newsticker.texi                  |    2 +-
 doc/misc/org.texi                         |    8 +-
 doc/misc/pgg.texi                         |    2 +-
 doc/misc/reftex.texi                      |    6 +-
 doc/misc/todo-mode.texi                   |    4 +-
 doc/misc/tramp.texi                       |    2 +-
 doc/misc/vhdl-mode.texi                   |    6 +-
 doc/misc/vip.texi                         |    2 +-
 doc/misc/viper.texi                       |    2 +-
 doc/misc/woman.texi                       |    2 +-
 lib/dirent.in.h                           |    2 +
 lib/dirfd.c                               |   32 ++
 lib/fdopendir.c                           |   13 +-
 lib/gnulib.mk                             |   11 +
 lisp/ChangeLog                            |  160 +++++++-
 lisp/emacs-lisp/byte-run.el               |   28 +-
 lisp/emacs-lisp/cl-generic.el             |   64 ++--
 lisp/emacs-lisp/cl-macs.el                |  198 +++++----
 lisp/emacs-lisp/cl-preloaded.el           |  233 ++++++++++--
 lisp/emacs-lisp/debug.el                  |    8 +-
 lisp/emacs-lisp/eieio-base.el             |   36 +-
 lisp/emacs-lisp/eieio-compat.el           |   21 +-
 lisp/emacs-lisp/eieio-core.el             |  632 +++++++++++------------------
 lisp/emacs-lisp/eieio-custom.el           |  161 ++++----
 lisp/emacs-lisp/eieio-datadebug.el        |   68 ++--
 lisp/emacs-lisp/eieio-opt.el              |   90 ++---
 lisp/emacs-lisp/eieio.el                  |  135 ++++---
 lisp/emacs-lisp/lisp-mode.el              |   49 +--
 lisp/emacs-lisp/macroexp.el               |    8 +-
 lisp/emacs-lisp/pcase.el                  |   35 +-
 lisp/leim/quail/hangul.el                 |    4 +-
 lisp/net/browse-url.el                    |   43 +-
 lisp/net/tramp-sh.el                      |   10 +-
 lisp/progmodes/cperl-mode.el              |    6 +-
 lisp/progmodes/gud.el                     |    2 +-
 lisp/progmodes/ruby-mode.el               |    9 +-
 lisp/textmodes/css-mode.el                |  275 +++++++------
 lwlib/ChangeLog                           |    4 +
 lwlib/xlwmenu.c                           |   58 ++--
 m4/dirfd.m4                               |   83 ++++
 m4/gnulib-comp.m4                         |   20 +
 src/ChangeLog                             |   23 +-
 src/alloc.c                               |   43 +-
 src/frame.h                               |    2 +-
 test/ChangeLog                            |   13 +
 test/automated/eieio-test-methodinvoke.el |    2 +-
 test/automated/eieio-test-persist.el      |   17 +-
 test/automated/eieio-tests.el             |   57 ++--
 93 files changed, 1967 insertions(+), 1474 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4f6523e..d268ba0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2015-03-19  Paul Eggert  <address@hidden>
+
+       Better port of pthread usage to FreeBSD
+       * configure.ac (ac_func_list): Omit pthread_sigmask, since
+       we check for that ourselves rather than relying on gnulib.
+       (HAVE_PTHREAD, LIB_PTHREAD, _THREAD_SAFE): Port better to FreeBSD,
+       by also checking for pthread_create, pthread_self, pthread_sigmask.
+       Tighten the test for pthread_atfork while we're at it.
+       Fixes: bug#20136
+
+       Merge from gnulib
+       This incorporates:
+       2015-03-19 fdopendir: port better to MinGW
+       2015-03-18 fdopendir: fix typo in comment
+       2015-02-24 glob, etc.: port to MSVC v18 on MS-Windows 8.1
+       * lib/dirent.in.h, lib/fdopendir.c: Update from gnulib.
+       * lib/dirfd.c, m4/dirfd.m4: New files from gnulib.
+       * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate.
+
 2015-03-02  Robert Pluim  <address@hidden>  (tiny change)
 
        * configure.ac: Error out if with-file-notification=w32 is
diff --git a/configure.ac b/configure.ac
index 45eb198..649ba2c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -783,6 +783,12 @@ AC_DEFUN([gl_CRYPTO_CHECK])
 # Avoid gnulib's tests for HAVE_WORKING_O_NOATIME and HAVE_WORKING_O_NOFOLLOW,
 # as we don't use them.
 AC_DEFUN([gl_FCNTL_O_FLAGS])
+# Avoid gnulib's test for pthread_sigmask.
+funcs=
+for func in $ac_func_list; do
+  test $func = pthread_sigmask || AS_VAR_APPEND([funcs], [" $func"])
+done
+ac_func_list=$funcs
 # Use the system putenv even if it lacks GNU features, as we don't need them,
 # and the gnulib replacement runs afoul of a FreeBSD 10.1 bug; see Bug#19874.
 AC_CHECK_FUNCS_ONCE([putenv])
@@ -2182,39 +2188,62 @@ AC_CHECK_LIB(Xbsd, main, 
LD_SWITCH_X_SITE="$LD_SWITCH_X_SITE -lXbsd")
 
 dnl Check for the POSIX thread library.
 LIB_PTHREAD=
-if test "$opsys" != "mingw32"; then
 AC_CHECK_HEADERS_ONCE(pthread.h)
-if test "$ac_cv_header_pthread_h"; then
-  dnl gmalloc.c uses pthread_atfork, which is not available on older-style
-  dnl hosts such as MirBSD 10, so test for pthread_atfork instead of merely
-  dnl testing for pthread_kill if Emacs uses gmalloc.c.
-  if test "$GMALLOC_OBJ" = gmalloc.o; then
-    emacs_pthread_function=pthread_atfork
-  else
-    emacs_pthread_function=pthread_kill
-  fi
-  OLD_LIBS=$LIBS
-  AC_SEARCH_LIBS([$emacs_pthread_function], [pthread],
-    [AC_DEFINE([HAVE_PTHREAD], [1],
-       [Define to 1 if you have pthread (-lpthread).])
-     # Some systems optimize for single-threaded programs by default, and
-     # need special flags to disable these optimizations. For example, the
-     # definition of 'errno' in <errno.h>.
-     case $opsys in
-       sol*)
-         AC_DEFINE([_REENTRANT], 1,
-       [Define to 1 if your system requires this in multithreaded code.]);;
-       aix4-2)
-         AC_DEFINE([_THREAD_SAFE], 1,
-       [Define to 1 if your system requires this in multithreaded code.]);;
-     esac])
- if test "X$LIBS" != "X$OLD_LIBS"; then
-    eval LIB_PTHREAD=\$ac_cv_search_$emacs_pthread_function
+if test "$ac_cv_header_pthread_h" && test "$opsys" != "mingw32"; then
+  AC_CACHE_CHECK([for pthread library],
+    [emacs_cv_pthread_lib],
+    [emacs_cv_pthread_lib=no
+     OLD_CPPFLAGS=$CPPFLAGS
+     OLD_LIBS=$LIBS
+     for emacs_pthread_lib in 'none needed' -lpthread; do
+       case $emacs_pthread_lib in
+        -*) LIBS="$OLD_LIBS $emacs_pthread_lib";;
+       esac
+       AC_LINK_IFELSE(
+        [AC_LANG_PROGRAM(
+           [[#include <pthread.h>
+             #include <signal.h>
+             sigset_t old_mask, new_mask;
+             void noop (void) {}]],
+           [[pthread_t th = pthread_self ();
+             int status = 0;
+             status += pthread_create (&th, 0, 0, 0);
+             status += pthread_sigmask (SIG_BLOCK, &new_mask, &old_mask);
+             status += pthread_kill (th, 0);
+             #if ! (defined SYSTEM_MALLOC || defined HYBRID_MALLOC \
+                    || defined DOUG_LEA_MALLOC)
+             /* Test for pthread_atfork only if gmalloc uses it,
+                as older-style hosts like MirBSD 10 lack it.  */
+             status += pthread_atfork (noop, noop, noop);
+             #endif
+             return status;]])],
+        [emacs_cv_pthread_lib=$emacs_pthread_lib])
+       LIBS=$OLD_LIBS
+       if test "$emacs_cv_pthread_lib" != no; then
+        break
+       fi
+     done
+     CPPFLAGS=$OLD_CPPFLAGS])
+  if test "$emacs_cv_pthread_lib" != no; then
+    AC_DEFINE([HAVE_PTHREAD], 1, [Define to 1 if you have POSIX threads.])
+    case $emacs_cv_pthread_lib in
+      -*) LIB_PTHREAD=$emacs_cv_pthread_lib;;
+    esac
+    ac_cv_func_pthread_sigmask=yes
+    # Some systems optimize for single-threaded programs by default, and
+    # need special flags to disable these optimizations. For example, the
+    # definition of 'errno' in <errno.h>.
+    case $opsys in
+      hpux* | sol*)
+       AC_DEFINE([_REENTRANT], 1,
+         [Define to 1 if your system requires this in multithreaded code.]);;
+      aix4-2 | darwin | freebsd)
+       AC_DEFINE([_THREAD_SAFE], 1,
+         [Define to 1 if your system requires this in multithreaded code.]);;
+    esac
   fi
-  LIBS=$OLD_LIBS
 fi
 AC_SUBST([LIB_PTHREAD])
-fi
 
 dnl Check for need for bigtoc support on IBM AIX
 
diff --git a/doc/emacs/ChangeLog b/doc/emacs/ChangeLog
index 1353640..644281c 100644
--- a/doc/emacs/ChangeLog
+++ b/doc/emacs/ChangeLog
@@ -1,3 +1,23 @@
+2015-03-18  Eli Zaretskii  <address@hidden>
+
+       * misc.texi (Term Mode):
+       * programs.texi (Basic Indent, Custom C Indent):
+       * mini.texi (Minibuffer History):
+       * text.texi (Org Mode):
+       * display.texi (View Mode): Use @kbd where @key was mistakenly
+       used.  (Bug#20135)
+
+2015-03-18  Eli Zaretskii  <address@hidden>
+
+       * basic.texi (Moving Point): Improve indexing for HOME and END.
+
+       * cmdargs.texi (General Variables): Improve indexing for
+       environment variables.
+
+       * msdog.texi (Windows HOME):
+       * msdog-xtra.texi (MS-DOS File Names): Remove markup from HOME in
+       the index entries.  (Bug#20105)
+
 2015-02-26  Eli Zaretskii  <address@hidden>
 
        * msdog.texi (Windows Files): Document characters invalid in
diff --git a/doc/emacs/ack.texi b/doc/emacs/ack.texi
index f97964b..151c3f1 100644
--- a/doc/emacs/ack.texi
+++ b/doc/emacs/ack.texi
@@ -204,7 +204,7 @@ for Korean Hanja.
 
 @item
 Andrew Choi and Yamamoto Mitsuharu wrote the Carbon support, used
-prior to Emacs 23 for Mac OS.  Yamamoto Mitsuharu continued to
+prior to Emacs 23 for Mac address@hidden  Yamamoto Mitsuharu continued to
 contribute to Mac OS support in the newer Nextstep port; and also
 improved support for multi-monitor displays.
 
diff --git a/doc/emacs/basic.texi b/doc/emacs/basic.texi
index 2594608..be45856 100644
--- a/doc/emacs/basic.texi
+++ b/doc/emacs/basic.texi
@@ -206,14 +206,14 @@ preserves position within the line, like @kbd{C-n}.
 @item C-a
 @itemx @key{Home}
 @kindex C-a
address@hidden HOME
address@hidden HOME key
 @findex move-beginning-of-line
 Move to the beginning of the line (@code{move-beginning-of-line}).
 
 @item C-e
 @itemx @key{End}
 @kindex C-e
address@hidden END
address@hidden END key
 @findex move-end-of-line
 Move to the end of the line (@code{move-end-of-line}).
 
diff --git a/doc/emacs/buffers.texi b/doc/emacs/buffers.texi
index 88a122c..25b13d6 100644
--- a/doc/emacs/buffers.texi
+++ b/doc/emacs/buffers.texi
@@ -642,7 +642,7 @@ the directory names in reverse order, so that 
@file{/top/middle/file}
 becomes @samp{file\middle\top}, while @code{post-forward} puts them in
 forward order after the file name, as in @samp{file|top/middle}.  If
 @code{uniquify-buffer-name-style} is set to @code{nil}, the buffer
-names simply get @samp{<2>}, @samp{<3>}, etc. appended.
+names simply get @samp{<2>}, @samp{<3>}, etc.@: appended.
 
   Which rule to follow for putting the directory names in the buffer
 name is not very important if you are going to @emph{look} at the
diff --git a/doc/emacs/cmdargs.texi b/doc/emacs/cmdargs.texi
index 42c8e33..071cd68 100644
--- a/doc/emacs/cmdargs.texi
+++ b/doc/emacs/cmdargs.texi
@@ -442,22 +442,31 @@ special meanings in Emacs.  Most of these variables are 
also used by
 some other programs.  Emacs does not require any of these environment
 variables to be set, but it uses their values if they are set.
 
address@hidden @env
address@hidden This used to be @vtable, but that enters the variables alone into
address@hidden the Variable Index, which in some cases, like ``HOME'', might be
address@hidden confused with keys by that name, and other cases, like ``NAME'',
address@hidden might be confused with general-purpose phrases.
address@hidden @env
 @item CDPATH
address@hidden CDPATH, environment variable
 Used by the @code{cd} command to search for the directory you specify,
 when you specify a relative directory name.
 @item DBUS_SESSION_BUS_ADDRESS
address@hidden DBUS_SESSION_BUS_ADDRESS, environment variable
 Used by D-Bus when Emacs is compiled with it.  Usually, there is no
 need to change it.  Setting it to a dummy address, like
 @samp{unix:path=/dev/null}, suppresses connections to the D-Bus session
 bus as well as autolaunching the D-Bus session bus if not running yet.
 @item EMACSDATA
address@hidden EMACSDATA, environment variable
 Directory for the architecture-independent files that come with Emacs.
 This is used to initialize the variable @code{data-directory}.
 @item EMACSDOC
+#vindex EMACSDOC, environment variable
 Directory for the documentation string file, which is used to
 initialize the Lisp variable @code{doc-directory}.
 @item EMACSLOADPATH
+#vindex EMACSLOADPATH, environment variable
 A colon-separated list of address@hidden and below,
 whenever we say ``colon-separated list of directories'', it pertains
 to Unix and GNU/Linux systems.  On MS-DOS and MS-Windows, the
@@ -471,23 +480,28 @@ the default @code{load-path}.  To specify an empty 
element in the
 middle of the list, use 2 colons in a row, as in
 @samp{EMACSLOADPATH="/tmp::/foo"}.
 @item EMACSPATH
address@hidden EMACSPATH, environment variable
 A colon-separated list of directories to search for executable files.
 If set, Emacs uses this in addition to @env{PATH} (see below) when
 initializing the variable @code{exec-path} (@pxref{Shell}).
 @item EMAIL
address@hidden EMAIL, environment variable
 @vindex address@hidden, initialization}
 Your email address; used to initialize the Lisp variable
 @code{user-mail-address}, which the Emacs mail interface puts into the
 @samp{From} header of outgoing messages (@pxref{Mail Headers}).
 @item ESHELL
address@hidden ESHELL, environment variable
 Used for shell-mode to override the @env{SHELL} environment variable
 (@pxref{Interactive Shell}).
 @item HISTFILE
address@hidden HISTFILE, environment variable
 The name of the file that shell commands are saved in between logins.
 This variable defaults to @file{~/.bash_history} if you use Bash, to
 @file{~/.sh_history} if you use ksh, and to @file{~/.history}
 otherwise.
 @item HOME
address@hidden HOME, environment variable
 The location of your files in the directory tree; used for
 expansion of file names starting with a tilde (@file{~}).  On MS-DOS,
 it defaults to the directory from which Emacs was started, with
@@ -499,6 +513,7 @@ where @var{username} is your user name), though for 
backwards
 compatibility @file{C:/} will be used instead if a @file{.emacs} file
 is found there.
 @item HOSTNAME
address@hidden HOSTNAME, environment variable
 The name of the machine that Emacs is running on.
 @c complete.el is obsolete since 24.1.
 @ignore
@@ -507,15 +522,24 @@ A colon-separated list of directories.  Used by the 
@code{complete} package
 to search for files.
 @end ignore
 @item INFOPATH
address@hidden INFOPATH, environment variable
 A colon-separated list of directories in which to search for Info files.
 @item LC_ALL
address@hidden LC_ALL, environment variable
 @itemx LC_COLLATE
address@hidden LC_COLLATE, environment variable
 @itemx LC_CTYPE
address@hidden LC_CTYPE, environment variable
 @itemx LC_MESSAGES
address@hidden LC_MESSAGES, environment variable
 @itemx LC_MONETARY
address@hidden LC_MONETARY, environment variable
 @itemx LC_NUMERIC
address@hidden LC_NUMERIC, environment variable
 @itemx LC_TIME
address@hidden LC_TIME, environment variable
 @itemx LANG
address@hidden LANG, environment variable
 The user's preferred locale.  The locale has six categories, specified
 by the environment variables @env{LC_COLLATE} for sorting,
 @env{LC_CTYPE} for character encoding, @env{LC_MESSAGES} for system
@@ -537,73 +561,92 @@ matched against entries in @code{locale-language-names},
 @code{locale-preferred-coding-systems}, to select a default language
 environment and coding system.  @xref{Language Environments}.
 @item LOGNAME
address@hidden LOGNAME, environment variable
 The user's login name.  See also @env{USER}.
 @item MAIL
address@hidden MAIL, environment variable
 The name of your system mail inbox.
 @ifnottex
 @item MH
address@hidden MH, environment variable
 Name of setup file for the mh system.  @xref{Top,,MH-E,mh-e, The Emacs
 Interface to MH}.
 @end ifnottex
 @item NAME
address@hidden NAME, environment variable
 Your real-world name.  This is used to initialize the variable
 @code{user-full-name} (@pxref{Mail Headers}).
 @item NNTPSERVER
address@hidden NNTPSERVER, environment variable
 The name of the news server.  Used by the mh and Gnus packages.
 @item ORGANIZATION
address@hidden ORGANIZATION, environment variable
 The name of the organization to which you belong.  Used for setting the
 `Organization:' header in your posts from the Gnus package.
 @item PATH
address@hidden PATH, environment variable
 A colon-separated list of directories containing executable files.
 This is used to initialize the variable @code{exec-path}
 (@pxref{Shell}).
 @item PWD
address@hidden PWD, environment variable
 If set, this should be the default directory when Emacs was started.
 @item REPLYTO
address@hidden REPLYTO, environment variable
 If set, this specifies an initial value for the variable
 @code{mail-default-reply-to} (@pxref{Mail Headers}).
 @item SAVEDIR
address@hidden SAVEDIR, environment variable
 The name of a directory in which news articles are saved by default.
 Used by the Gnus package.
 @item SHELL
address@hidden SHELL, environment variable
 The name of an interpreter used to parse and execute programs run from
 inside Emacs.
 @item SMTPSERVER
address@hidden SMTPSERVER, environment variable
 The name of the outgoing mail server.  This is used to initialize the
 variable @code{smtpmail-smtp-server} (@pxref{Mail Sending}).
 @cindex background mode, on @command{xterm}
 @item TERM
address@hidden TERM, environment variable
 The type of the terminal that Emacs is using.  This variable must be
 set unless Emacs is run in batch mode.  On MS-DOS, it defaults to
 @samp{internal}, which specifies a built-in terminal emulation that
 handles the machine's own display.
 @item TERMCAP
address@hidden TERMCAP, environment variable
 The name of the termcap library file describing how to program the
 terminal specified by @env{TERM}.  This defaults to
 @file{/etc/termcap}.
 @item TMPDIR
address@hidden TMPDIR, environment variable
 @itemx TMP
address@hidden TMP, environment variable
 @itemx TEMP
address@hidden TEMP, environment variable
 These environment variables are used to initialize the variable
 @code{temporary-file-directory}, which specifies a directory in which
 to put temporary files (@pxref{Backup}).  Emacs tries to use
 @env{TMPDIR} first.  If that is unset, Emacs normally falls back on
 @file{/tmp}, but on MS-Windows and MS-DOS it instead falls back on
 @env{TMP}, then @env{TEMP}, and finally @file{c:/temp}.
-
 @item TZ
address@hidden TZ, environment variable
 This specifies the current time zone and possibly also daylight
 saving time information.  On MS-DOS, if @env{TZ} is not set in the
 environment when Emacs starts, Emacs defines a default value as
 appropriate for the country code returned by address@hidden  On MS-Windows, 
Emacs
 does not use @env{TZ} at all.
 @item USER
address@hidden USER, environment variable
 The user's login name.  See also @env{LOGNAME}.  On MS-DOS, this
 defaults to @samp{root}.
 @item VERSION_CONTROL
address@hidden VERSION_CONTROL, environment variable
 Used to initialize the @code{version-control} variable (@pxref{Backup
 Names}).
address@hidden vtable
address@hidden table
 
 @node Misc Variables
 @appendixsubsec Miscellaneous Variables
diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi
index ae723b8..083bb2e 100644
--- a/doc/emacs/display.texi
+++ b/doc/emacs/display.texi
@@ -138,7 +138,7 @@ instructs the scrolling commands not to fontify 
(@pxref{Font Lock})
 any unfontified text they scroll over, instead to assume it has the
 default face.  This can cause Emacs to scroll to somewhat wrong buffer
 positions when the faces in use are not all the same size, even with
-single (i.e. without auto-repeat) scrolling operations.
+single (i.e., without auto-repeat) scrolling operations.
 
 @vindex scroll-up
 @vindex scroll-down
@@ -441,7 +441,7 @@ it.  @xref{Disabling}.
 screenfuls.  It provides commands for scrolling through the buffer
 conveniently but not for changing it.  Apart from the usual Emacs
 cursor motion commands, you can type @key{SPC} to scroll forward one
-windowful, @address@hidden or @key{DEL} to scroll backward, and @kbd{s} to
+windowful, @address@hidden or @key{DEL} to scroll backward, and @kbd{s} to
 start an incremental search.
 
 @kindex q @r{(View mode)}
diff --git a/doc/emacs/frames.texi b/doc/emacs/frames.texi
index b5b9dbd..f401c8f 100644
--- a/doc/emacs/frames.texi
+++ b/doc/emacs/frames.texi
@@ -955,7 +955,7 @@ bar width, change the @code{scroll-bar-width} frame 
parameter
 @cindex overscrolling
 If you're using Emacs on X (with GTK+ or Motif), you can customize the
 variable @code{scroll-bar-adjust-thumb-portion} to control
address@hidden of the scroll bar, i.e. dragging the thumb down even
address@hidden of the scroll bar, i.e., dragging the thumb down even
 when the end of the buffer is visible.  If its value is
 address@hidden, the scroll bar can be dragged downwards even if the
 end of the buffer is shown; if @code{nil}, the thumb will be at the
diff --git a/doc/emacs/killing.texi b/doc/emacs/killing.texi
index 3092d34..4b90bf4 100644
--- a/doc/emacs/killing.texi
+++ b/doc/emacs/killing.texi
@@ -848,7 +848,7 @@ shifting the original text to the right.
   The command @kbd{C-x @key{SPC}} (@code{rectangle-mark-mode}) toggles
 whether the region-rectangle or the standard region is highlighted
 (first activating the region if necessary).  When this mode is enabled,
-commands that resize the region (@kbd{C-f}, @kbd{C-n} etc.) do
+commands that resize the region (@kbd{C-f}, @kbd{C-n} etc.)@: do
 so in a rectangular fashion, and killing and yanking operate on the
 rectangle.  @xref{Killing}.  The mode persists only as long as the
 region is active.
diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi
index 2a86af3..f0bedf8 100644
--- a/doc/emacs/mini.texi
+++ b/doc/emacs/mini.texi
@@ -622,7 +622,7 @@ typed @kbd{M-p}), Emacs tries fetching from a list of 
default
 arguments: values that you are likely to enter.  You can think of this
 as moving through the ``future history'' list.
 
-  If you edit the text inserted by the @kbd{M-p} or @key{M-n}
+  If you edit the text inserted by the @kbd{M-p} or @kbd{M-n}
 minibuffer history commands, this does not change its entry in the
 history list.  However, the edited argument does go at the end of the
 history list when you submit it.
diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi
index e12fca7..46585ed 100644
--- a/doc/emacs/misc.texi
+++ b/doc/emacs/misc.texi
@@ -1426,7 +1426,7 @@ char mode.
 
 @table @kbd
 @item C-c C-c
-Send a literal @key{C-c} to the sub-shell.
+Send a literal @kbd{C-c} to the sub-shell.
 
 @item C-c @var{char}
 This is equivalent to @kbd{C-x @var{char}} in normal Emacs.  For
diff --git a/doc/emacs/msdos-xtra.texi b/doc/emacs/msdos-xtra.texi
index b0fa3e9..9996158 100644
--- a/doc/emacs/msdos-xtra.texi
+++ b/doc/emacs/msdos-xtra.texi
@@ -351,7 +351,7 @@ long file name support, set the environment variable 
@env{LFN} to
 DOS programs to access long file names, so Emacs built for MS-DOS will
 only see their short 8+3 aliases.
 
address@hidden @env{HOME} directory under MS-DOS
address@hidden HOME directory under MS-DOS
   MS-DOS has no notion of home directory, so Emacs on MS-DOS pretends
 that the directory where it is installed is the value of the @env{HOME}
 environment variable.  That is, if your Emacs binary,
diff --git a/doc/emacs/msdos.texi b/doc/emacs/msdos.texi
index 10e7923..f1cdb26 100644
--- a/doc/emacs/msdos.texi
+++ b/doc/emacs/msdos.texi
@@ -425,7 +425,7 @@ names, which might cause misalignment of columns in Dired 
display.
 
 @node Windows HOME
 @section HOME and Startup Directories on MS-Windows
address@hidden @code{HOME} directory on MS-Windows
address@hidden HOME directory on MS-Windows
 
   The Windows equivalent of @code{HOME} is the @dfn{user-specific
 application data directory}.  The actual location depends on the
diff --git a/doc/emacs/mule.texi b/doc/emacs/mule.texi
index f8b06bd..a80f942 100644
--- a/doc/emacs/mule.texi
+++ b/doc/emacs/mule.texi
@@ -266,7 +266,7 @@ for more information about the language environment 
@var{lang-env}.
 Supported language environments include:
 
 @c @cindex entries below are split between portions of the list to
address@hidden make them more accurate, i.e. land on the line that mentions the
address@hidden make them more accurate, i.e., land on the line that mentions the
 @c language.  However, makeinfo 4.x doesn't fill inside @quotation
 @c lines that follow a @cindex entry and whose text has no whitespace.
 @c To work around, we group the language environments together, so
diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index 73aed08..b161a0c 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -383,7 +383,7 @@ the preceding lines; if the region is active, @key{TAB} 
indents each
 line within the region, not just the current line.
 
   The command @key{RET} (@code{newline}), which was documented in
address@hidden Text}, does the same as @key{C-j} followed by
address@hidden Text}, does the same as @kbd{C-j} followed by
 @key{TAB}: it inserts a new line, then adjusts the line's indentation.
 
   When indenting a line that starts within a parenthetical grouping,
@@ -559,7 +559,7 @@ predefined styles, including @code{gnu}, @code{k&r}, 
@code{bsd},
 styles are primarily intended for one language, but any of them can be
 used with any of the languages supported by these modes.  To find out
 what a style looks like, select it and reindent some code, e.g., by
-typing @key{C-M-q} at the start of a function definition.
+typing @kbd{C-M-q} at the start of a function definition.
 
 @kindex C-c . @r{(C mode)}
 @findex c-set-style
diff --git a/doc/emacs/text.texi b/doc/emacs/text.texi
index 11b916a..9bc5ade 100644
--- a/doc/emacs/text.texi
+++ b/doc/emacs/text.texi
@@ -1293,7 +1293,7 @@ executed.
 
 @kindex S-TAB @r{(Org Mode)}
 @findex org-shifttab
-  Typing @key{S-TAB} (@code{org-shifttab}) anywhere in an Org mode
+  Typing @address@hidden (@code{org-shifttab}) anywhere in an Org mode
 buffer cycles the visibility of the entire outline structure, between
 (i) showing only top-level heading lines, (ii) showing all heading
 lines but no body lines, and (iii) showing everything.
diff --git a/doc/emacs/trouble.texi b/doc/emacs/trouble.texi
index 2faa5d9..22ec215 100644
--- a/doc/emacs/trouble.texi
+++ b/doc/emacs/trouble.texi
@@ -342,7 +342,7 @@ Here, @var{backtrace} is the name of a text file containing 
a copy of
 the backtrace, @var{bindir} is the name of the directory that
 contains the Emacs executable, and @var{emacs-binary} is the name of
 the Emacs executable file, normally @file{emacs} on GNU and Unix
-systems and @file{emacs.exe} on MS-Windows and MS-DOS.  Omit the
+systems and @file{emacs.exe} on MS-Windows and address@hidden  Omit the
 @option{-p} option if your version of @command{addr2line} is too old
 to have it.
 
@@ -1142,7 +1142,7 @@ making diffs of C code.  This shows the name of the 
function that each
 change occurs in.
 
 If you are using the Emacs repository, make sure your copy is
-up-to-date (e.g. with @code{git pull}).  You can commit your changes
+up-to-date (e.g., with @code{git pull}).  You can commit your changes
 to a private branch and generate a patch from the master version by
 using @code{git format-patch master}. Or you can leave your changes
 uncommitted and use @code{git diff}.
@@ -1173,7 +1173,7 @@ explanation in comments in the code.  It will be more 
useful there.
 Please look at the change log entries of recent commits to see what
 sorts of information to put in, and to learn the style that we use. Note that,
 unlike some other projects, we do require change logs for
-documentation, i.e. Texinfo files.
+documentation, i.e., Texinfo files.
 @xref{Change Log},
 @ifset WWW_GNU_ORG
 see
@@ -1389,7 +1389,7 @@ user freedom and to defend the rights of all free 
software users.
 For general information, see the website @url{http://www.fsf.org/}.
 
 Generally speaking, for non-trivial contributions to GNU Emacs we
-require that the copyright be assigned to the FSF.  For the reasons
+require that the copyright be assigned to the address@hidden  For the reasons
 behind this, see @url{http://www.gnu.org/licenses/why-assign.html}.
 
 Copyright assignment is a simple process.  Residents of some countries
@@ -1408,7 +1408,7 @@ is not enough).  Also, a disclaimer cannot be applied to 
future work, it
 has to be repeated each time you want to send something new.
 
 We can accept small changes (roughly, fewer than 15 lines) without
-an assignment.  This is a cumulative limit (e.g. three separate 5 line
+an assignment.  This is a cumulative limit (e.g., three separate 5 line
 patches) over all your contributions.
 
 @node Service
diff --git a/doc/lispintro/emacs-lisp-intro.texi 
b/doc/lispintro/emacs-lisp-intro.texi
index b6eff2d..c67623d 100644
--- a/doc/lispintro/emacs-lisp-intro.texi
+++ b/doc/lispintro/emacs-lisp-intro.texi
@@ -387,7 +387,7 @@ Truth and Falsehood in Emacs Lisp
 * Point and mark::              A review of various locations.
 * Template for save-excursion::
 
-A Few Buffer--Related Functions
+A Few Buffer-Related Functions
 
 * Finding More::                How to find more information.
 * simplified-beginning-of-buffer::  Shows @code{goto-char},
@@ -4547,7 +4547,7 @@ and if so, prints an appropriate message.
 @end itemize
 
 @node Buffer Walk Through
address@hidden A Few Buffer--Related Functions
address@hidden A Few Buffer-Related Functions
 
 In this chapter we study in detail several of the functions used in GNU
 Emacs.  This is called a ``walk-through''.  These functions are used as
@@ -12114,7 +12114,7 @@ Internet, see
 @uref{http://www.gnu.org/software/texinfo/manual/texinfo/}
 @end ifhtml
 @iftex
-``Indicating Definitions, Commands, etc.'' in @cite{Texinfo, The GNU
+``Indicating Definitions, Commands, etc.''@: in @cite{Texinfo, The GNU
 Documentation Format}.
 @end iftex
 @end itemize
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog
index 260656c..3644d40 100644
--- a/doc/lispref/ChangeLog
+++ b/doc/lispref/ChangeLog
@@ -1,3 +1,7 @@
+2015-03-18  Eli Zaretskii  <address@hidden>
+
+       * minibuf.texi (Basic Completion): Fix a typo.  (Bug#20108)
+
 2015-03-09  Nicolas Petton <address@hidden>
 
        * sequences.texi (seq-into): Add documentation for the new
diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index 6fdc8e2..b81d0f8 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -132,7 +132,7 @@ byte compiler to warn if the command is called from Lisp.  
The output
 of @code{describe-function} will include similar information.
 The value of the property can be: a string, which the byte-compiler
 will use directly in its warning (it should end with a period, and not
-start with a capital, e.g. ``use @dots{} instead.''); @code{t}; any
+start with a capital, e.g., ``use @dots{} instead.''); @code{t}; any
 other symbol, which should be an alternative function to use in Lisp
 code.
 
@@ -1043,8 +1043,8 @@ the current Emacs session.  If a symbol has not yet been 
so used,
 @end defun
 
 @menu
-* Keyboard Events::             Ordinary characters--keys with symbols on them.
-* Function Keys::               Function keys--keys with names, not symbols.
+* Keyboard Events::             Ordinary characters -- keys with symbols on 
them.
+* Function Keys::               Function keys -- keys with names, not symbols.
 * Mouse Events::                Overview of mouse events.
 * Click Events::                Pushing and releasing a mouse button.
 * Drag Events::                 Moving the mouse before releasing the button.
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 5dd74d2..b73e70d 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -2154,7 +2154,7 @@ stipple patterns.
 Alternative foreground color, a string.  This is like @code{:foreground}
 but the color is only used as a foreground when the background color is
 near to the foreground that would have been used.  This is useful for
-example when marking text (i.e. the region face).  If the text has a foreground
+example when marking text (i.e., the region face).  If the text has a 
foreground
 that is visible with the region face, that foreground is used.
 If the foreground is near the region face background,
 @code{:distant-foreground} is used instead so the text is readable.
diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi
index fc552be..fc8ba7b 100644
--- a/doc/lispref/elisp.texi
+++ b/doc/lispref/elisp.texi
@@ -753,8 +753,8 @@ Defining Commands
 
 Input Events
 
-* Keyboard Events::         Ordinary characters--keys with symbols on them.
-* Function Keys::           Function keys--keys with names, not symbols.
+* Keyboard Events::         Ordinary characters -- keys with symbols on them.
+* Function Keys::           Function keys -- keys with names, not symbols.
 * Mouse Events::            Overview of mouse events.
 * Click Events::            Pushing and releasing a mouse button.
 * Drag Events::             Moving the mouse before releasing the button.
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index 0b8106d..85695c6 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -360,7 +360,7 @@ coordinates might be negative.
 Position of the top-left corner and size of the work area (``usable''
 space) in pixels as @samp{(@var{x} @var{y} @var{width} @var{height})}.
 This may be different from @samp{geometry} in that space occupied by
-various window manager features (docks, taskbars, etc.) may be
+various window manager features (docks, taskbars, etc.)@: may be
 excluded from the work area.  Whether or not such features actually
 subtract from the work area depends on the platform and environment.
 Again, if the monitor is not the primary monitor, some of the
@@ -1218,7 +1218,7 @@ These functions return the canonical height and width of 
a character in
 @var{frame}, measured in pixels.  Together, these values establish the
 size of the default font on @var{frame}.  The values depend on the
 choice of font for @var{frame}, see @ref{Font and Color Parameters}.
address@hidden defun                                                            
          
address@hidden defun
 
 The default font can be also set directly with the following function:
 
diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi
index 40b8322..a853d2f 100644
--- a/doc/lispref/functions.texi
+++ b/doc/lispref/functions.texi
@@ -1222,7 +1222,7 @@ This macro is the handy way to add the advice 
@var{function} to the function
 stored in @var{place} (@pxref{Generalized Variables}).
 
 @var{where} determines how @var{function} is composed with the
-existing function, e.g. whether @var{function} should be called before, or
+existing function, e.g., whether @var{function} should be called before, or
 after the original function.  @xref{Advice combinators}, for the list of
 available ways to compose the two functions.
 
@@ -1310,7 +1310,7 @@ and its properties.
 @defun advice-eval-interactive-spec spec
 Evaluate the interactive @var{spec} just like an interactive call to a function
 with such a spec would, and then return the corresponding list of arguments
-that was built.  E.g. @code{(advice-eval-interactive-spec "r\nP")} will
+that was built.  E.g., @code{(advice-eval-interactive-spec "r\nP")} will
 return a list of three elements, containing the boundaries of the region and
 the current prefix argument.
 @end defun
diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi
index 2627ab7..a5fff72 100644
--- a/doc/lispref/internals.texi
+++ b/doc/lispref/internals.texi
@@ -1624,7 +1624,7 @@ similar advice may apply to the unsigned counterparts 
(e.g.,
 of @code{intptr_t}).
 
 @item
-Prefer @code{int} for Emacs character codes, in the range 0 ..@: 0x3FFFFF.
+Prefer @code{int} for Emacs character codes, in the range 0 ..@: address@hidden
 More generally, prefer @code{int} for integers known to be in
 @code{int} range, e.g., screen column counts.
 
diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi
index cf2f000..0ae8fbd 100644
--- a/doc/lispref/loading.texi
+++ b/doc/lispref/loading.texi
@@ -95,7 +95,7 @@ suffix), unless it contains an explicit directory name.
 
 If the option @code{load-prefer-newer} is address@hidden, then when
 searching suffixes, @code{load} selects whichever version of a file
-(@samp{.elc}, @samp{.el}, etc.) has been modified most recently.
+(@samp{.elc}, @samp{.el}, etc.)@: has been modified most recently.
 
 If @var{filename} is a relative file name, such as @file{foo} or
 @file{baz/foo.bar}, @code{load} searches for the file using the variable
diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi
index 82039ba..24c7559 100644
--- a/doc/lispref/minibuf.texi
+++ b/doc/lispref/minibuf.texi
@@ -102,7 +102,7 @@ the minibuffer is in a separate frame.  @xref{Minibuffers 
and Frames}.
   When Emacs is running in batch mode, any request to read from the
 minibuffer actually reads a line from the standard input descriptor that
 was supplied when Emacs was started.  This supports only basic input:
-none of the special minibuffer features (history, completion, etc.)
+none of the special minibuffer features (history, completion, etc.)@:
 are available in batch mode.
 
 @node Text from Minibuffer
@@ -723,7 +723,7 @@ just one matching completion, and the match is exact, it 
returns
 @code{t}.  Otherwise, it returns the longest initial sequence common
 to all possible matching completions.
 
-If @var{collection} is an list, the permissible completions are
+If @var{collection} is a list, the permissible completions are
 specified by the elements of the list, each of which should be either
 a string, or a cons cell whose @sc{car} is either a string or a symbol
 (a symbol is converted to a string using @code{symbol-name}).  If the
diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi
index 1ee7050..8d1d3a7 100644
--- a/doc/lispref/numbers.texi
+++ b/doc/lispref/numbers.texi
@@ -261,7 +261,7 @@ If @var{x} is finite, then @var{s} is a floating-point 
number between 0.5
 @math{x = s 2^e}.
 @end tex
 If @var{x} is zero or infinity, then @var{s} is the same as @var{x}.
-If @var{x} is a NaN, then @var{s} is also a NaN.
+If @var{x} is a NaN, then @var{s} is also a address@hidden
 If @var{x} is zero, then @var{e} is 0.
 @end defun
 
diff --git a/doc/lispref/streams.texi b/doc/lispref/streams.texi
index e52a543..dfad2d8 100644
--- a/doc/lispref/streams.texi
+++ b/doc/lispref/streams.texi
@@ -344,7 +344,7 @@ When reading or writing from the standard input/output 
streams of the
 Emacs process in batch mode, it is sometimes required to make sure any
 arbitrary binary data will be read/written verbatim, and/or that no
 translation of newlines to or from CR-LF pairs are performed.  This
-issue does not exist on Posix hosts, only on MS-Windows and MS-DOS.
+issue does not exist on Posix hosts, only on MS-Windows and address@hidden
 The following function allows to control the I/O mode of any standard
 stream of the Emacs process.
 
diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index a7cfb22..da67ec2 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -811,7 +811,7 @@ Delete trailing whitespace in the region defined by 
@var{start} and
 This command deletes whitespace characters after the last
 non-whitespace character in each line in the region.
 
-If this command acts on the entire buffer (i.e. if called
+If this command acts on the entire buffer (i.e., if called
 interactively with the mark inactive, or called from Lisp with
 @var{end} @code{nil}), it also deletes all trailing lines at the end of the
 buffer if the variable @code{delete-trailing-lines} is address@hidden
@@ -2720,7 +2720,7 @@ text properties are considered, since strings never have 
overlays.
 @defun get-pos-property position prop &optional object
 This function is like @code{get-char-property}, except that it pays
 attention to properties' stickiness and overlays' advancement settings
-instead of the property of the character at (i.e. right after)
+instead of the property of the character at (i.e., right after)
 @var{position}.
 @end defun
 
diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog
index fc85bd9..62f5651 100644
--- a/doc/misc/ChangeLog
+++ b/doc/misc/ChangeLog
@@ -1,3 +1,11 @@
+2015-03-18  Eli Zaretskii  <address@hidden>
+
+       * efaq-w32.texi: Remove outdated information and update.
+
+2015-03-18  Martin Rudalics  <address@hidden>
+
+       * efaq.texi (Fullscreen mode on MS-Windows): Fix description 
(Bug#20110).
+
 2015-03-04  Michael Albinus  <address@hidden>
 
        * tramp.texi (External methods) <adb>: Explain, when Tramp
@@ -12,7 +20,7 @@
 
        * erc.texi (Advanced Usage, Options): Add descriptions and examples
        for erc-format-nick-function and erc-rename-buffers options.
-       (Connecting): fix typo
+       (Connecting): Fix typo
 
 2015-03-02  Daniel Colascione  <address@hidden>
 
diff --git a/doc/misc/auth.texi b/doc/misc/auth.texi
index 8dbde4d..7a2fd9b 100644
--- a/doc/misc/auth.texi
+++ b/doc/misc/auth.texi
@@ -111,9 +111,9 @@ You can use spaces inside a password or other token by 
surrounding the
 token with either single or double quotes.
 
 You can use single quotes inside a password or other token by
-surrounding it with double quotes, e.g. @code{"he'llo"}. Similarly you
+surrounding it with double quotes, e.g., @code{"he'llo"}. Similarly you
 can use double quotes inside a password or other token by surrounding
-it with single quotes, e.g. @code{'he"llo'}. You can't mix both (so a
+it with single quotes, e.g., @code{'he"llo'}. You can't mix both (so a
 password or other token can't have both single and double quotes).
 
 All this is optional. You could just say (but we don't recommend it,
diff --git a/doc/misc/calc.texi b/doc/misc/calc.texi
index 30e39c4..62a81b8 100644
--- a/doc/misc/calc.texi
+++ b/doc/misc/calc.texi
@@ -36800,7 +36800,7 @@ desired function, or with @kbd{x} or @kbd{z} followed 
by a function name,
 or with @kbd{$} to take a formula from the top of the stack, or with
 @kbd{'} and a typed formula.  In the last two cases, the formula may
 be a nameless function like @samp{<#1+#2>} or @samp{<x, y : x+y>}, or it
-may include @kbd{$}, @kbd{$$}, etc. (where @kbd{$} will correspond to the
+may include @kbd{$}, @kbd{$$}, etc.@: (where @kbd{$} will correspond to the
 last argument of the created function), or otherwise you will be
 prompted for an argument list.  The number of vectors popped from the
 stack by @kbd{V M} depends on the number of arguments of the function.
diff --git a/doc/misc/cc-mode.texi b/doc/misc/cc-mode.texi
index 1b79640..068706a 100644
--- a/doc/misc/cc-mode.texi
+++ b/doc/misc/cc-mode.texi
@@ -1038,7 +1038,7 @@ Movement}.  They might be removed from a future release 
of @ccmode{}.
 Since there's a lot of normal text in comments and string literals,
 @ccmode{} provides features to edit these like in text mode.  The goal
 is to do it seamlessly, i.e., you can use auto fill mode, sentence and
-paragraph movement, paragraph filling, adaptive filling etc. wherever
+paragraph movement, paragraph filling, adaptive filling etc.@: wherever
 there's a piece of normal text without having to think much about it.
 @ccmode{} keeps the indentation, fixes suitable comment line prefixes,
 and so on.
@@ -7140,7 +7140,7 @@ of XEmacs since 19.16.
 Due to release schedule skew, it is likely that all of these Emacsen
 have old versions of @ccmode{} and so should be upgraded.  Access to the
 @ccmode{} source code, as well as more detailed information on Emacsen
-compatibility, etc. are all available on the web site:
+compatibility, etc.@: are all available on the web site:
 
 @quotation
 @uref{http://cc-mode.sourceforge.net/}
diff --git a/doc/misc/efaq-w32.texi b/doc/misc/efaq-w32.texi
index 9691a73..d95fa7e 100644
--- a/doc/misc/efaq-w32.texi
+++ b/doc/misc/efaq-w32.texi
@@ -128,10 +128,12 @@ systems.
 @cindex supported versions of Windows
 
 Emacs @value{EMACSVER} is known to run on all versions of Windows from
address@hidden FIXME does it really still support Windows 98?  Does it matter?
-Windows 98 and Windows NT 4.0 through to Windows 7.  The Windows port is
-built using the Win32 API and supports most features of the X version,
-including variable width fonts, images and tooltips.
+Windows 98 and Windows NT 4.0 through to Windows 8.1.  The Windows
+port is built using the Win32 API and supports most features of the X
+version, including variable width fonts, images and tooltips.
+
+Emacs on Windows can be compiled as either a 32-bit or a 64-bit
+executable, using the MinGW GCC compiler and development tools.
 
 @node Other versions of Emacs
 @section What other versions of Emacs run on Windows?
@@ -163,10 +165,12 @@ instructions (requires DJGPP).
 @cindex where to get Emacs binaries
 Pre-compiled versions are distributed from
 @uref{http://ftpmirror.gnu.org/emacs/windows/, ftp.gnu.org mirrors}.
-Emacs binaries are distributed as zip files, digitally
-signed by the developer who built them.  Generally most users will
-want the file @address@hidden, which
-contains everything you need to get started.
+Emacs binaries are distributed as zip files, digitally signed by the
+developer who built them.  Generally most users will want the file
address@hidden@value{EMACSVER}-bin-i686-pc-mingw.zip} for the 32-bit
+build, and @address@hidden
+for the 64-bit build.  The zip archive contains everything you need to
+get started.
 
 @cindex where to get sources
 @cindex Emacs source code
@@ -187,17 +191,18 @@ development site.
 @section How can I compile Emacs myself?
 @cindex compiling Emacs
 
-To compile Emacs on Windows, you will need the MingW or Cygwin port of
-GCC with MingW make, or a Microsoft C compiler with nmake and the
-single threaded C runtime library.  Recent versions of Microsoft
-Visual Studio no longer come with the single threaded C runtime
-library, which is required for certain POSIX compatibility, so MingW
-is usually the best choice.  Image support requires external
-libraries, the headers and import libraries for which will need to be
-installed where your compiler can find them.  You will also need ports
-of GNU @command{rm} and @command{cp}, as the Windows native
-equivalents are not consistent between versions.  GNU texinfo will be
-required to build the manuals.  @xref{Other useful ports}.
+To compile Emacs on Windows, you will need the MinGW port of GCC and
+Binutils, the MinGW runtime and development environment, and the MSYS
+suite of tools.  For the details, see the file @file{nt/INSTALL} in
+the Emacs source distribution.
+
+Support for displaying images, as well as XML/HTML rendering and TLS
+networking requires external libraries, the headers and import
+libraries for which will need to be installed where your compiler can
+find them.  Again, the details, including URLs of sites where you can
+download these libraries are in @file{nt/INSTALL}.  @xref{Other useful
+ports}, for auxiliary tools you may wish to install and use in
+conjunction with Emacs.
 
 After unpacking the source, or checking out of the repository, be sure
 to read the instructions in @file{nt/README} and @file{nt/INSTALL}.
@@ -211,39 +216,25 @@ to read the instructions in @file{nt/README} and 
@file{nt/INSTALL}.
 By default, Emacs is compiled with debugging on, and optimizations enabled.
 The optimizations may interfere with some types of debugging; the debugger
 may not show clearly where it is, or may not be able to inspect certain
-variables.  If this is the case, reconfigure with @option{--no-opt}.
+variables.  If this is the case, reconfigure with @kbd{CFLAGS='-O0 -g3'}
 
 The file @file{etc/DEBUG} contains general debugging hints, as well as
-specific notes about debugging Emacs with both gdb and Microsoft debuggers.
-
address@hidden
-* GDB::
-* Microsoft Developer Studio::
address@hidden menu
+specific notes about debugging Emacs.
 
address@hidden GDB
address@hidden GDB
address@hidden GDB, debugging Emacs with
 @cindex debugging Emacs with GDB
-
 GDB is the GNU debugger, which can be used to debug Emacs when it has
-been compiled with GCC.  The best results will be obtained if you
-start gdb from the @file{src} directory as @samp{gdb oo/i386/emacs.exe}.
-This will load the init file @file{.gdbinit} in that directory, to
-define some extra commands for working with lisp while debugging, and
-set up breakpoints to catch abnormal aborts.
-
address@hidden Microsoft Developer Studio
address@hidden Microsoft Developer Studio
address@hidden MSVC++, debugging Emacs with
address@hidden DevStudio, debugging Emacs with
address@hidden debugging Emacs with MS DevStudio
-
-MS DevStudio can be used to debug Emacs when it has been compiled with
-a Microsoft compiler.  To view lisp variables, you can call the
-function @code{debug_print} from the Quickwatch window.  Some
address@hidden://www.gnu.org/software/emacs/windows/ntemacs/discuss/debug.txt,
-old tips} are probably still valid.
+been compiled with MinGW GCC.  The best results will be obtained if
+you start gdb from the @file{src} directory as @kbd{gdb ./emacs.exe}.
+This will load the init file @address@hidden
+Latest versions of GDB might refuse to load the init file for security
+reasons, unless you customize GDB; alternatively, use an explicit
address@hidden ./gdbinit} command after entering GDB.
+} in that directory, to define some extra commands for working with
+lisp while debugging, and set up breakpoints to catch abnormal
+aborts.
+
+A Windows port of GDB can be found on MinGW download sites and on some
+others.
 
 @c ------------------------------------------------------------
 @node Installing Emacs
@@ -251,7 +242,7 @@ old tips} are probably still valid.
 
 @menu
 * Unpacking::
-* Installing::
+* Installing binaries::
 * Image support::
 * Init file::
 * Location of init file::
@@ -279,24 +270,27 @@ old tips} are probably still valid.
 The binary distributions are distributed as zip files, which are handled
 natively by Windows XP and later.  For earlier versions, there are many
 tools that can handle the zip format, from InfoZip's command line unzip
-tool, to 7zip's multi-format graphical archive explorer.  Although
+tool, to 7zip's multi-format graphical archive explorer.  (Although
 popular, WinZip has caused problems with line-ends in the past, and is not
-Free software, so we do not recommend it.
+Free software, so we do not recommend it.)
 
-Source distributions are distributed as gzipped tar files.  7zip and
-similar multi-format graphical tools can handle these, or you can get
-Windows ports of the command line gzip and tar tools from multiple sources.
+Source distributions are distributed as @file{.tar.gz} or
address@hidden files.  7zip and similar multi-format graphical tools
+can handle these, or you can get Windows ports of the command line
+gzip and tar tools from multiple sources, or use @command{bsdtar}.
 @xref{Other useful ports}.
 
 The command to unpack a source distribution from the command line is:
+
 @example
 tar xzf address@hidden
 @end example
 
 If this does not work with the versions of tar and gzip that you have,
 you may need to try a two step process:
+
 @example
-gzip -dc address@hidden | tar xvf -
+gzip -dc address@hidden | tar xf -
 @end example
 
 You may see many messages from tar complaining about being unable to change
@@ -304,8 +298,21 @@ the modification time on directories, and from gzip 
complaining about a
 broken pipe.  These messages are usually harmless, caused by incomplete ports
 that are not fully aware of the limitations of Windows.
 
address@hidden Installing
address@hidden How do I install Emacs after unpacking?
+And here's an example of using @command{bsdtar} (from the
address@hidden package) to unpack a @file{.tar.xz} archive:
+
address@hidden
+bsdtar -xf address@hidden
address@hidden example
+
+Expect @command{bsdtar} to unpack the whole distribution without any
+complaints.
+
+Once you unpack the source distribution, look in @file{nt/INSTALL}
+file for build instructions.
+
address@hidden Installing binaries
address@hidden How do I install Emacs after unpacking the binary zip?
 @cindex installing Emacs
 @pindex addpm
 @cindex Start Menu, creating icons for Emacs
@@ -313,7 +320,8 @@ that are not fully aware of the limitations of Windows.
 You can run Emacs without any extra steps, but if you want icons in your
 Start Menu, or for Emacs to detect the image libraries that are already
 installed on your system as part of GTK, then you should run the program
address@hidden@value{EMACSVER}\bin\addpm.exe}.
address@hidden, which is usually installed into the same @file{bin}
+directory with @file{emacs.exe}.
 
 @node Image support
 @section How do I get image support?
@@ -323,6 +331,7 @@ installed on your system as part of GTK, then you should 
run the program
 @cindex gif, installing image support in Emacs
 @cindex tiff, installing image support in Emacs
 @cindex xpm, installing image support in Emacs
address@hidden rsvg, installing image support in Emacs
 @cindex toolbar, installing color icons in
 @cindex color images, installing support for images in Emacs
 @cindex monochrome images, getting color images in Emacs
@@ -330,12 +339,12 @@ installed on your system as part of GTK, then you should 
run the program
 
 Emacs has built in support for XBM and PBM/PGM/PPM images.  This is
 sufficient to see the monochrome splash screen and tool-bar icons.
-Since 22.2, the official precompiled binaries for Windows have bundled
+Since v22.2, the official precompiled binaries for Windows have bundled
 libXpm, which is required to display the color versions of those images.
 
-Emacs is compiled to recognize JPEG, PNG, GIF and TIFF images also,
-but displaying these image types require external DLLs which are not
-bundled with Emacs.  @xref{Other useful ports}.
+Emacs is compiled to recognize JPEG, PNG, GIF, TIFF, and RSVG images
+also, but displaying these image types require external DLLs which are
+not bundled with Emacs.  @xref{Other useful ports}.
 
 @node Init file
 @section What is my init file?
@@ -344,11 +353,11 @@ bundled with Emacs.  @xref{Other useful ports}.
 
 When Emacs starts up, it attempts to load and execute the contents of
 a file commonly called @file{.emacs} (though it may have other names,
address@hidden Emacs,,Where do I put my init file?}) which contains any
-customizations you have made.  You can manually add lisp code to your
-.emacs, or you can use the Customization interface accessible from the
address@hidden menu.  If the file does not exist, Emacs will start
-with the default settings.
address@hidden of init file,,Where do I put my init file?}) which
+contains any customizations you have made.  You can manually add lisp
+code to your .emacs, or you can use the Customization interface
+accessible from the @emph{Options} menu.  If the file does not exist,
+Emacs will start with the default settings.
 
 @node Location of init file
 @section Where do I put my init file?
@@ -358,15 +367,15 @@ with the default settings.
 @cindex init.el
 @cindex registry, setting the HOME directory in
 
-On Windows, the .emacs file may be called _emacs for backward
-compatibility with DOS and FAT filesystems where filenames could not
-start with a dot.  Some users prefer to continue using such a name,
-because Explorer cannot create a file with a name starting with a dot,
-even though the filesystem and most other programs can handle it.
-In Emacs 22 and later, the init file may also be called
address@hidden/init.el}.  Many of the other files that are created
-by lisp packages are now stored in the @file{.emacs.d} directory too,
-so this keeps all your Emacs related files in one place.
+On Windows, the @file{.emacs} file may be called @file{_emacs} for
+backward compatibility with DOS and FAT filesystems where filenames
+could not start with a dot.  Some users prefer to continue using such
+a name due to historical problems various Windows tools had in the
+past with file names that begin with a dot.  In Emacs 22 and later,
+the init file may also be called @file{.emacs.d/init.el}.  Many of the
+other files that are created by lisp packages are now stored in the
address@hidden directory too, so this keeps all your Emacs related
+files in one place.
 
 All the files mentioned above should go in your @env{HOME} directory.
 The @env{HOME} directory is determined by following the steps below:
@@ -387,14 +396,14 @@ backward compatibility, as previous versions defaulted to 
@file{C:/}
 if @env{HOME} was not set.
 @item
 Use the user's AppData directory, usually a directory called
address@hidden Data} under the user's profile directory, the location
address@hidden under the user's profile directory, the location
 of which varies according to Windows version and whether the computer is
 part of a domain.
 @end enumerate
 
 Within Emacs, @key{~} at the beginning of a file name is expanded to your
address@hidden directory, so you can always find your .emacs file with
address@hidden C-f ~/.emacs}.
address@hidden directory, so you can always find your @file{.emacs} file
+by typing the command @kbd{C-x C-f ~/.emacs}.
 
 @node Troubleshooting init file
 @section Troubleshooting init file problems
@@ -409,15 +418,16 @@ to.  You can do this by evaluating the following 
expression in the
 @file{*scratch*} buffer using @kbd{C-x C-e}:
 
 @example
-(insert (getenv "HOME"))
+(getenv "HOME")
 @end example
 
-Look carefully at what is printed and make sure the value is
-valid.  For example, if the value has trailing whitespace, Emacs won't
-be able to find the directory.  Also, be sure that the value isn't a
-relative drive letter (e.g., @file{d:} without a backslash); if it is,
-then @env{HOME} is going to be whatever the current directory on that
-drive is, which is likely not what you want to happen.
+Look carefully at what is printed in the echo area, and make sure the
+value is valid.  For example, if the value has trailing whitespace,
+Emacs won't be able to find the directory.  Also, be sure that the
+value isn't a relative drive letter (e.g., @file{d:} without a
+backslash or a forward slash after the colon); if it is, then
address@hidden is going to be whatever the current directory on that drive
+is, which is likely not what you want to happen.
 
 @node Associate files with Emacs
 @section How do I associate files with Emacs?
@@ -488,9 +498,9 @@ Thanks to Jason Rumney and Sigbjorn Finne for these tips.
 
 The location of the Desktop varies between different versions of
 Windows, and in a corporate environment can be moved around by the
-network administrator.  On NT derivatives, you can use the value of
-the @env{USERPROFILE} environment variable to find where the desktop
-might be:
+network administrator.  On latest Windows versions, you can use the
+value of the @env{USERPROFILE} environment variable to find where the
+desktop might be:
 
 @example
 @kbd{C-x C-f $USERPROFILE/Desktop}
@@ -512,7 +522,7 @@ menu by default).  Once you have a file from the Desktop 
inside Emacs,
 @end menu
 
 @node Focus follows mouse
address@hidden How do it make the active window follow the mouse?
address@hidden How do I make the active window follow the mouse?
 @vindex focus-follows-mouse
 @cindex point to focus
 @cindex mouse over to focus
@@ -524,6 +534,11 @@ even though Windows has a click to focus policy by default 
(there is
 software available to change that though).  The latter can be used to
 make Emacs use a focus-follow-mouse policy within its own frames.
 
+You can also change the Windows click-to-focus policy by changing
+settings in the Registry.  The details vary according to your Windows
+version; look on the Internet for instructions to enable ``active
+window tracking'' for your version of Windows.
+
 @node Swap CapsLock and Control
 @subsection How do I swap CapsLock and Control?
 @cindex scan codes, modifying
@@ -576,7 +591,7 @@ Date: 04 Dec 1996 14:36:21 -0600
 Message-ID: <fawg21mm4hm.fsf@@mordor.rsn.hp.com>
 Subject: Re: Re[2]: problem with caps/ctrl swap on NT 4.0
 @end ignore
address@hidden
address@hidden
 It's a binary value that lets you map keystrokes in the low-level keyboard
 drivers in NT.  As a result you don't have to worry about applications
 bypassing mappings that you've done at a higher level (i.e. it just works).
@@ -600,7 +615,7 @@ lock key will behave as caps-lock.  To swap, you also need 
to map 0x3a to
 
 This registry value is system wide, and can't be made user-specific.  It
 also only takes affect on reboot.
address@hidden example
address@hidden smallexample
 @item
 Ulfar Erlingsson has provided a registry file that sets the CapsLock key
 to be a Control key and the Windows key to be an Alt key:
@@ -663,7 +678,8 @@ buffers etc. will instead act on the region.  An inactive 
mark needs
 to be reactivated to operate on it, unless @code{mark-even-if-inactive}
 is set.  Secondly, @code{transient-mark-mode} also highlights the
 region when it is active, providing the same visual clue that you get
-in other programs.
+in other programs.  This mode is turned on by default in latest
+versions of Emacs.
 
 In addition to seeing the highlighting, new Emacs users often expect
 editing commands to replace the region when it is active.  This behavior
@@ -717,14 +733,16 @@ message as documented in Microsoft's API documentation.
 @cindex delete Emacs directory
 
 Emacs does not come with an uninstall program.  No files are installed
-outside of the Emacs base directory, so deleting that directory is
-sufficient to clean away the files.  If you ran @command{addpm},
-you'll need to delete the Start Menu group too.  The registry entries
-inserted by @command{addpm} will not cause any problems if you leave
-them there, but for the sake of completeness, you can use @command{regedit}
-to remove the keys under @code{HKEY_LOCAL_MACHINE} orx
address@hidden: @code{SOFTWARE\GNU\Emacs}, and the key
address@hidden Paths\emacs.exe} if it exists.
+outside of the directories you find in the binary zip archive, so
+deleting those directories is sufficient to clean away the files.  If
+you ran @command{addpm}, you'll need to delete the Start Menu group
+too.  The registry entries inserted by @command{addpm} will not cause
+any problems if you leave them there, but for the sake of
+completeness, you can use @command{regedit} to remove the keys under
address@hidden or @code{HKEY_CURRENT_USER}:
address@hidden, and the key
address@hidden
+Paths\emacs.exe} if it exists.
 
 @node Does not run
 @section When I run Emacs nothing happens
@@ -751,9 +769,10 @@ been truncated to CONTRIBU or CONTRI~1, your distribution 
has been
 corrupted while unpacking and Emacs will not start.
 @end enumerate
 
-If it is still not working, send mail to the list, describing what
-you've done, and what you are seeing. (The more information you send
-the more likely it is that you'll receive a helpful response..
+If it is still not working, send mail to the
address@hidden@@gnu.org} mailing list, describing what you've
+done, and what you are seeing. (The more information you send the more
+likely it is that you'll receive a helpful response.)
 
 @node Virus
 @section Does Emacs contain a virus?
@@ -880,7 +899,6 @@ The doc string contains a list of the system sounds you can 
use.
 * Font names::
 * Bold and italic::
 * Multilingual fonts::
-* BDF fonts::
 * Font menu::
 * Line ends::
 @end menu
@@ -910,9 +928,9 @@ an indication of whether the font is outline (.TTF, .ATM) 
or raster (.FON)
 based when fonts are listed, which may let you differentiate between two
 fonts with the same name and different technologies.
 
-From Emacs 23, the preferred font name format will be moving to the simpler
-and more flexible fontconfig format.  XLFD names will continue to be
-supported for backward compatibility.
+Starting with Emacs 23, the preferred font name format will be moving
+to the simpler and more flexible fontconfig format.  XLFD names will
+continue to be supported for backward compatibility.
 
 @example
 XLFD: -*-Courier New-normal-r-*-*-13-*-*-*-c-*-iso8859-1
@@ -959,6 +977,9 @@ and manually set the font for italic, bold and bold-italic 
as follows:
 (set-face-font 'bold-italic "-*-Courier New-bold-i-*-*-11-*-*-*-c-*-iso8859-1")
 @end example
 
+The @code{w32-enable-synthesized-fonts} variable is obsolete starting
+from Emacs 24.4, as Emacs no longer has this limitation.
+
 @node Multilingual fonts
 @section Multilingual font support
 @cindex multilingual display, fonts
@@ -985,11 +1006,8 @@ require the BDF fonts from the GNU intlfonts package.
 
 For many languages, native truetype fonts are sufficient, and in Emacs
 23 the need for BDF fonts will disappear for almost all languages.  At
-the time of writing, some Arabic characters in the HELLO file still do
-not display with native fonts, because they are pre-composed characters
-from MULE character sets rather than standard Unicode Arabic, but all
-other characters are able to be displayed with appropriate truetype or
-opentype fonts.
+the time of writing, all supported characters are able to be displayed
+with appropriate truetype or opentype fonts.
 
 @node Non-latin display
 @subsection How do I get Emacs to display non-latin characters?
@@ -1025,6 +1043,12 @@ new fontset with @code{create-fontset-from-ascii-font} or
  chinese-big5-2:-*-MingLiU-normal-r-*-*-12-*-*-*-c-*-big5-*" t)
 @end example
 
+Alternatively, you can augment the default fontset with information of
+which fonts to use for certain ranges of characters or for specific
+scripts/character sets.  @xref{Modifying Fontsets,, Modifying
+Fontsets, emacs, The GNU Emacs Manual}, for details and some useful
+examples.
+
 @node International fonts
 @subsection Where can I find fonts for other languages?
 @cindex language support, finding fonts
@@ -1037,10 +1061,10 @@ new fontset with @code{create-fontset-from-ascii-font} 
or
 In addition to the wide range of fonts that come with the language
 support packages of various components of Windows itself, GNU/Linux
 distributions these days come with a number of Free truetype fonts
-that cover a wide range of languages.  The GNU intlfonts source
-distribution contains BDF fonts covering all of the languages that can
-be displayed by Emacs 22, and can be downloaded from
address@hidden://ftpmirror.gnu.org/intlfonts, ftp.gnu.org mirrors}.
+that cover a wide range of languages.  The GNU Unifont project
+contains glyphs for most of the Unicode codespace, and can be
+downloaded from @uref{http://ftpmirror.gnu.org/unifont, ftp.gnu.org
+mirrors}.
 
 @node Third-party multibyte
 @subsection How do I use third party programs to display multibyte characters?
@@ -1058,12 +1082,6 @@ for that language, but the third party software is 
intercepting it
 and using a different font behind the scenes).
 @xref{Non-latin display}.
 
-In addition to defining a fontset with the expected font, you may also need
-to disable unicode output with:
address@hidden
-(setq w32-enable-unicode-output nil)
address@hidden example
-
 @node Localized fonts
 @subsection Can I use a font with a name in my language?
 @cindex fonts, localized font names
@@ -1073,87 +1091,9 @@ Normally Emacs should initialize 
@code{locale-coding-system} appropriately
 based on your locale, which will let Emacs use font names in your local
 language successfully.
 
address@hidden BDF fonts
address@hidden How do I use bdf fonts with Emacs?
address@hidden BDF fonts, using
address@hidden GNU intlfonts, using
address@hidden intlfonts, using
address@hidden w32-bdf-filename-alist
address@hidden bdf-directory-alist
address@hidden font-encoding-alist
address@hidden w32-find-bdf-fonts
address@hidden set-frame-font
-
-To use bdf fonts with Emacs, you need to tell Emacs where the fonts
-are located, create fontsets for them, and then use them.  We'll use
-the 16 dot international fonts from @uref{http://ftpmirror.gnu.org/intlfonts,
-ftp.gnu.org/gnu/intlfonts} as an
-example put together by Jason Rumney.
-
-Download @file{16dots.tar.gz} and unpack it; I'll assume that they are in
address@hidden:\intlfonts}.  Then set @code{w32-bdf-filename-alist} to the list 
of
-fonts returned by using @code{w32-find-bdf-fonts} to enumerate all of
-the font files.  It is a good idea to set the variable
address@hidden at the same time so @code{ps-print} knows where
-to find the fonts:
address@hidden
-(setq bdf-directory-list
-      '("c:/intlfonts/Asian" "c:/intlfonts/Chinese"
-        "c:/intlfonts/Chinese-X" "c:/intlfonts/Ethiopic"
-       "c:/intlfonts/European" "c:/intlfonts/Japanese"
-        "c:/intlfonts/Japanese-X" "c:/intlfonts/Korean-X"
-       "c:/intlfonts/Misc/"))
-
-(setq w32-bdf-filename-alist (w32-find-bdf-fonts bdf-directory-list))
address@hidden example
-
-Then create fontsets for the BDF fonts:
-
address@hidden
-(create-fontset-from-fontset-spec
- "-*-fixed-medium-r-normal-*-16-*-*-*-c-*-fontset-bdf,
-japanese-jisx0208:-*-*-medium-r-normal-*-16-*-*-*-c-*-jisx0208.1983-*,
-katakana-jisx0201:-*-*-medium-r-normal-*-16-*-*-*-c-*-jisx0201*-*,
-latin-jisx0201:-*-*-medium-r-normal-*-16-*-*-*-c-*-jisx0201*-*,
-japanese-jisx0208-1978:-*-*-medium-r-normal-*-16-*-*-*-c-*-jisx0208.1978-*,
-thai-tis620:-misc-fixed-medium-r-normal--16-160-72-72-m-80-tis620.2529-1,
-lao:-misc-fixed-medium-r-normal--16-160-72-72-m-80-MuleLao-1,
-tibetan-1-column:-TibMdXA-fixed-medium-r-normal--16-160-72-72-m-80-MuleTibetan-1,
-ethiopic:-Admas-Ethiomx16f-Medium-R-Normal--16-150-100-100-M-160-Ethiopic-Unicode,
-tibetan:-TibMdXA-fixed-medium-r-normal--16-160-72-72-m-160-MuleTibetan-0")
address@hidden example
-
-Many of the international bdf fonts from gnu.org are type 0, and therefore
-need to be added to font-encoding-alist:
-
address@hidden
-;; Need to add some fonts to font-encoding-alist since the bdf fonts
-;; are type 0 not the default type 1.
-(setq font-encoding-alist
-      (append '(("MuleTibetan-0" (tibetan . 0))
-                ("GB2312"        (chinese-gb2312 . 0))
-                ("JISX0208"      (japanese-jisx0208 . 0))
-                ("JISX0212"      (japanese-jisx0212 . 0))
-                ("VISCII"        (vietnamese-viscii-lower . 0))
-                ("KSC5601"       (korean-ksc5601 . 0))
-                ("MuleArabic-0"  (arabic-digit . 0))
-                ("MuleArabic-1"  (arabic-1-column . 0))
-                ("MuleArabic-2"  (arabic-2-column . 0))) font-encoding-alist))
address@hidden example
-
-You can now use the Emacs font menu (@pxref{Fonts and text
-translation,,How can I have Emacs use a font menu like on X?}) to
-select the @emph{bdf: 16-dot medium} fontset, or you can select it by
-setting the default font:
-
address@hidden
-    (set-frame-font "fontset-bdf")
address@hidden example
-
-Try loading the file @file{etc/HELLO}, and you should be able to see the
-various international fonts displayed (except for Hindi, which is not
-included in the 16-dot font distribution).
-
address@hidden This feature disappeared in Emacs 23, but I'm keeping its
address@hidden description here, since I think it was a mistake to remove it, 
and
address@hidden resurrecting it doesn't sound too problematic.
 @node Font menu
 @section How can I have Emacs use a font menu like on X?
 @cindex fonts, displaying a menu
@@ -1171,6 +1111,8 @@ Place the following in your init file:
 * Add fonts to menu::
 @end menu
 
address@hidden This variable still exists, but will have no effect until
address@hidden w32-use-w32-font-dialog support is resurrected, see above.
 @node Add fonts to menu
 @subsection How can I add my font to the font menu?
 @cindex font menu, adding fonts
@@ -1204,7 +1146,6 @@ this collection of email messages} on the topic.
 
 @menu
 * Automatic line ends::
-* Line ends by filename::
 * Line ends by file system::
 @end menu
 
@@ -1220,19 +1161,6 @@ file in Unix (LF) mode with the Ctrl-M characters 
displayed as @samp{^M}.
 It does this to be safe, as no data loss will occur if the file is really
 binary and the Ctrl-M characters are significant.
 
address@hidden Line ends by filename
address@hidden CR/LF translation by file extension
address@hidden line ends, determining by filename
address@hidden binary files, determining by file name
address@hidden file-name-buffer-file-type-alist
-
-The variable @code{file-name-buffer-file-type-alist} holds a list of
-filename patterns and their associated type; binary or text.  Files marked
-as binary will not have line-end detection performed on them, and instead
-will always be displayed as is.  With auto-detection in recent versions of
-Emacs, this is seldom useful for existing files, but can still be used
-to influence the choice of line ends for newly created files.
-
 @node Line ends by file system
 @subsection CR/LF translation by file system
 @cindex line ends, determining by filesystem
@@ -1260,8 +1188,9 @@ MS Windows, but this has still been insufficient to keep 
up with
 changes in printing technology from text and postscript based printers
 connected via ports that can be accessed directly, to graphical
 printers that are only accessible via USB.  For details, see
address@hidden://www.emacswiki.org/cgi-bin/wiki/PrintingFromEmacs, Emacs
-Wiki}.
address@hidden://www.emacswiki.org/emacs/PrintingFromEmacs, Emacs
+Wiki}, @uref{http://www.emacswiki.org/emacs/PrintWithWebBrowser}, and
address@hidden://www.emacswiki.org/emacs/PrintFromWindowsExplorer}.
 
 @c ------------------------------------------------------------
 @node Sub-processes
@@ -1293,9 +1222,7 @@ Wiki}.
 The quoting rules for native Windows shells and Cygwin shells have
 some subtle differences.  When Emacs spawns subprocesses, it tries to
 determine whether the process is a Cygwin program and changes its
-quoting mechanism appropriately.  See this
address@hidden://www.gnu.org/software/emacs/windows/ntemacs/discuss/shell-quoting,
-previous discussion} for details.
+quoting mechanism appropriately.
 
 @node Subprocess hang
 @section Programs reading input hang
@@ -1357,9 +1284,11 @@ you can use @code{setbuf} and @code{setvbuf} to 
manipulate
 the buffering semantics.
 
 Some programs handle this by having an explicit flag to control their
-buffering behavior, typically @option{-i} for interactive.  Other
-programs manage to detect that they are running under Emacs, by
-using @samp{getenv("emacs")} internally.
+buffering behavior, typically @option{-i} for interactive, or by a
+special environment variable.  Other programs manage to detect that
+they are running under Emacs, by using @samp{getenv("emacs")}
+internally.  Look in the program's documentation for the way around
+this issue.
 
 @menu
 * Perl script buffering::
@@ -1428,6 +1357,7 @@ this discussion} for more details.
 @vindex explicit-shell-file-name
 
 You can start an interactive shell in Emacs by typing @kbd{M-x shell}.
+By default, this will start the standard Windows shell @file{cmd.exe}.
 Emacs uses the @env{SHELL} environment variable to determine which
 program to use as the shell.  To instruct Emacs to use a non-default
 shell, you can either set this environment variable, or customize
@@ -1467,11 +1397,6 @@ default shell in Emacs, you can place the following in 
your init file:
 (add-hook 'shell-mode-hook 'my-shell-setup)
 @end example
 
-If you find that you are having trouble with Emacs tracking drive
-changes with bash, see Mike Fabian's
address@hidden://www.gnu.org/software/emacs/windows/ntemacs/discuss/drive-tracking,
-note}.
-
 WARNING: Some versions of bash set and use the environment variable
 PID.  For some as yet unknown reason, if @env{PID} is set and Emacs
 passes it on to bash subshells, bash dies (Emacs can inherit the
@@ -1489,7 +1414,7 @@ continue to use bash as your subshell:
 @cindex cygwin mount points, using within Emacs
 
 The package
address@hidden://www.emacswiki.org/cgi-bin/wiki/cygwin-mount.el,
address@hidden://www.emacswiki.org/emacs/cygwin-mount.el,
 cygwin-mount.el} teaches Emacs about Cygwin mount points.
 
 @node Dired ls
@@ -1849,11 +1774,15 @@ your type (@code{flyspell}).  Both packages depend on a 
copy of
 @command{ispell} 3.2 or a compatible spell-checking program.
 GNU Aspell is a popular choice these days, Windows installers are
 available from the @uref{http://aspell.net/win32/, official site}.
+Another possibility is Hunspell, which is available from
address@hidden://sourceforge.net/projects/ezwinports/files/?source=navbar,
+the ezwinports site}.
 
 Once installed, you will need to configure @code{ispell-program-name}
-to tell ispell and flyspell to use @command{aspell} as a replacement for
-ispell.  You can include the full path to the @file{aspell} binary, which
-means you do not need to add its installation directory to the @env{PATH}.
+to tell ispell and flyspell to use @command{aspell} or
address@hidden as a replacement for ispell.  You can include the
+full path to the @file{aspell}/@file{hunspell} binary, which means you
+do not need to add its installation directory to the @env{PATH}.
 
 @node Encryption
 @section Emacs and encryption
@@ -1942,6 +1871,13 @@ of grep is to use @samp{findstr /n /r}.
 @node Developing with Emacs
 @chapter Developing with Emacs
 
+We recommend using the GNU Compiler Collection for developing C/C++
+code from Emacs.  The MinGW development toolchain provides Windows
+ports of GCC and other compilers.
+
+The rest of this chapter describes other alternatives which you may
+need to use.
+
 @menu
 * MSVC::
 * Borland C++ Builder::
@@ -1971,7 +1907,7 @@ tools to build your project.
 
 Christopher Payne wrote a Visual Studio add-in that makes Emacs the
 default text editor, this has now been taken over by Jeff Paquette.
-See the following two URLS for details:
+See the following two URLs for details:
 @itemize
 @item @uref{http://sourceforge.net/projects/visemacs/} for the latest version.
 @item @uref{http://www.smathers.net/VisEmacs.htm} for notes on usage.
@@ -2178,6 +2114,7 @@ suggestions} for improving the interaction of perldb and 
Emacs.
 @menu
 * Cygwin::
 * MinGW::
+* EZWinPorts::
 * UWIN::
 * GnuWin32::
 * GTK::
@@ -2230,6 +2167,17 @@ filesystem mapping to appear more POSIX like to the 
scripts that it
 runs.  This is intended to complement the MinGW tools to make it easier
 to port software to Windows.
 
address@hidden EZWinPorts
address@hidden EZWinPorts
address@hidden ezwinports
+
+The @uref{https://sourceforge.net/projects/ezwinports/, EZWinPorts
+project} provides many useful ports of recent versions of GNU and Unix
+software.  This includes all the optional libraries used by Emacs
+(image libraries, libxml2, GnuTLS), RCS, Texinfo, a clone of
address@hidden command, Grep, xz, bzip2, bsdtar, ID Utils, Findutils,
+Hunspell, Gawk, GNU Make, Groff, GDB.
+
 @node UWIN
 @section UWIN
 @cindex uwin environment
@@ -2251,8 +2199,8 @@ is @command{ksh}, the Korn shell.
 @uref{http://gnuwin32.sourceforge.net/}
 
 GnuWin32 provides precompiled native Windows ports of a wide selection
-of Free software and libraries.  Tools available here that are useful
-for Emacs include:
+of Free software and libraries.  Unfortunately, the ports are
+outdated.  Tools available here that are useful for Emacs include:
 
 @itemize
 @item Arc - used by @code{archive-mode} to edit .arc files.
@@ -2302,7 +2250,8 @@ Man pages for Emacs and other ported programs that you 
have can be
 read using Emacs' built-in manual reader @code{woman}.  This
 requires no external programs, but if you do have a port of
 @command{man}, there is also an Emacs wrapper @code{man} that
-which may be slightly faster.
+which may be slightly faster.  A Windows version of @command{man} is
+available from the EZWinPorts site (@pxref{EZWinPorts}).
 
 @c ------------------------------------------------------------
 @node Further information
diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi
index 8417827..cdf9440 100644
--- a/doc/misc/efaq.texi
+++ b/doc/misc/efaq.texi
@@ -2674,8 +2674,16 @@ variable in the environment.
 @cindex Maximize frame
 @cindex Fullscreen mode
 
-Use the function @code{w32-send-sys-command}.  For example, you can
-put the following in your @file{.emacs} file:
+Beginning with Emacs 24.4 either run Emacs with the @samp{--maximized}
+command-line option or put the following form in your @file{.emacs}
+file:
+
address@hidden
+(add-hook 'emacs-startup-hook 'toggle-frame-maximized)
address@hidden lisp
+
+With older versions use the function @code{w32-send-sys-command}.  For
+example, you can put the following in your @file{.emacs} file:
 
 @lisp
 (add-hook 'emacs-startup-hook
diff --git a/doc/misc/eieio.texi b/doc/misc/eieio.texi
index 3f42862..f17fd31 100644
--- a/doc/misc/eieio.texi
+++ b/doc/misc/eieio.texi
@@ -178,7 +178,7 @@ error.  @ref{Signals}.
 
 First off, please note that this manual cannot serve as a complete
 introduction to object oriented programming and generic functions in
-LISP.  Although EIEIO is not a complete implementation of the Common
address@hidden  Although EIEIO is not a complete implementation of the Common
 Lisp Object System (CLOS) and also differs from it in several aspects,
 it follows the same basic concepts.  Therefore, it is highly
 recommended to learn those from a textbook or tutorial first,
diff --git a/doc/misc/erc.texi b/doc/misc/erc.texi
index 2f4ffae..3a86e1b 100644
--- a/doc/misc/erc.texi
+++ b/doc/misc/erc.texi
@@ -716,8 +716,8 @@ stuff, to the current ERC buffer."
 (setq erc-autojoin-channels-alist '(("freenode.net" "#emacs" "#erc")))
 
 ;; Rename server buffers to reflect the current network name instead
-;; of SERVER:PORT. (e.g. "freenode" instead of "irc.freenode.net:6667"). This
-;; is useful when using a bouncer like ZNC where you have multiple
+;; of SERVER:PORT (e.g., "freenode" instead of "irc.freenode.net:6667").
+;; This is useful when using a bouncer like ZNC where you have multiple
 ;; connections to the same server.
 (setq erc-rename-buffers t)
 
@@ -780,7 +780,7 @@ or if you have bugs to report, there are several places you 
can go.
 
 @item
 @uref{http://www.emacswiki.org/cgi-bin/wiki/ERC} is the
-emacswiki.org page for address@hidden  Anyone may add tips, hints, etc. to it.
+emacswiki.org page for address@hidden  Anyone may add tips, hints, etc.@: to 
it.
 
 @item
 You can ask questions about using ERC on the Emacs mailing list,
diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi
index ca90573..6d57a78 100644
--- a/doc/misc/eshell.texi
+++ b/doc/misc/eshell.texi
@@ -649,7 +649,7 @@ Programs that need a terminal to display output properly 
are referred
 to in this manual as ``visual commands,'' because they are not simply
 line-oriented.  You must tell Eshell which commands are visual, by
 adding them to @code{eshell-visual-commands}; for commands that are
-visual for only certain @emph{sub}-commands -- e.g. @samp{git log} but
+visual for only certain @emph{sub}-commands -- e.g., @samp{git log} but
 not @samp{git status} -- use @code{eshell-visual-subcommands}; and for
 commands that are visual only when passed certain options, use
 @code{eshell-visual-options}.
diff --git a/doc/misc/eww.texi b/doc/misc/eww.texi
index f60354d..c7f84b5 100644
--- a/doc/misc/eww.texi
+++ b/doc/misc/eww.texi
@@ -126,7 +126,7 @@ specified in @code{eww-download-directory} (Default: 
@file{~/Downloads/}).
 @cindex History
   EWW remembers the URLs you have visited to allow you to go back and
 forth between them.  By pressing @kbd{l} (@code{eww-back-url}) you go
-to the previous URL.  You can go forward again with @kbd{r}
+to the previous address@hidden  You can go forward again with @kbd{r}
 (@code{eww-forward-url}).  If you want an overview of your browsing
 history press @kbd{H} (@code{eww-list-histories}) to open the history
 buffer @file{*eww history*}.  The history is lost when EWW is quit.
@@ -247,7 +247,7 @@ Sessions, , emacs, The GNU Emacs Manual}.
 
 @vindex eww-desktop-remove-duplicates
   EWW history may sensibly contain multiple entries for the same page
-URI.  At run-time, these entries may still have different associated
address@hidden  At run-time, these entries may still have different associated
 point positions or the actual Web page contents.
 The latter, however, tend to be overly large to preserve in the
 desktop file, so they get omitted, thus rendering the respective
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index d714656..ed4d1a5 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -11482,7 +11482,7 @@ who wrote the article, the date it was written and the 
subject of the
 article.  That's well and nice, but there's also lots of information
 most people do not want to see---what systems the article has passed
 through before reaching you, the @code{Message-ID}, the
address@hidden, etc. ad nauseam---and you'll probably want to get rid
address@hidden, etc.@: ad nauseam---and you'll probably want to get rid
 of some of those lines.  If you want to keep all those lines in the
 article buffer, you can set @code{gnus-show-all-headers} to @code{t}.
 
@@ -25905,7 +25905,7 @@ Store custom flags and keywords
 The registry can store custom flags and keywords for a message.  For
 instance, you can mark a message ``To-Do'' this way and the flag will
 persist whether the message is in the nnimap, nnml, nnmaildir,
-etc. backends.
+etc.@: backends.
 
 @item
 Store arbitrary data
@@ -25988,7 +25988,7 @@ registry will be pruned back to less than
 @code{gnus-registry-max-entries}.  This option controls exactly how
 much less: the target is calculated as the maximum number of entries
 minus the maximum number times this factor.  The default is 0.1:
-i.e. if your registry is limited to 50000 entries, pruning will try to
+i.e., if your registry is limited to 50000 entries, pruning will try to
 cut back to 45000 entries.  Entries with keys marked as precious will
 not be pruned.
 @end defvar
diff --git a/doc/misc/htmlfontify.texi b/doc/misc/htmlfontify.texi
index 630b5f7..6579cd6 100644
--- a/doc/misc/htmlfontify.texi
+++ b/doc/misc/htmlfontify.texi
@@ -839,7 +839,7 @@ See @ref{hfy-display-class} for details of valid values for 
@var{class}.
 (hfy-face-at P)
 @end lisp
 
-Find face in effect at point P.  If overlays are to be considered
+Find face in effect at point address@hidden  If overlays are to be considered
 (see @ref{hfy-optimisations}) then this may return a @code{defface} style
 list of face properties instead of a face symbol.
 
@@ -1418,7 +1418,7 @@ Add @samp{<div class="default"> </div>} tags around the 
fontified body.
 a page with different colors than the fontified code.)
 
 @item keep-overlays
-Preserve overlay highlighting (c.f. @code{ediff} or @code{goo-font-lock})
+Preserve overlay highlighting (cf.@: @code{ediff} or @code{goo-font-lock})
 as well as basic faces.  Can result in extremely verbose highlighting
 if there are many overlays (as is the case with @code{goo-font-lock}).
 
diff --git a/doc/misc/idlwave.texi b/doc/misc/idlwave.texi
index 1858a51..7cf9673 100644
--- a/doc/misc/idlwave.texi
+++ b/doc/misc/idlwave.texi
@@ -1010,7 +1010,7 @@ address@hidden means use last match on line for
 @cindex Highlighting of syntax
 @cindex Font lock
 
-Highlighting of keywords, comments, strings etc. can be accomplished
+Highlighting of keywords, comments, strings etc.@: can be accomplished
 with @code{font-lock}.  If you are using @code{global-font-lock-mode}
 (in Emacs), or have @code{font-lock} turned on in any other buffer in
 XEmacs, it should also automatically work in IDLWAVE buffers.  If you'd
@@ -3111,7 +3111,7 @@ window, but is useful for immediate stepping, etc.
 @kindex C-c C-d C-p
 Do you find yourself repeatedly typing, e.g., @code{print,n_elements(x)},
 and similar statements to remind yourself of the
-type/size/structure/value/etc. of variables and expressions in your code
+type/size/structure/value/etc.@: of variables and expressions in your code
 or at the command line?  IDLWAVE has a suite of special commands to
 automate these types of variable or expression examinations.  They work
 by sending statements to the shell formatted to include the indicated
diff --git a/doc/misc/ido.texi b/doc/misc/ido.texi
index 25380c0..a80620f 100644
--- a/doc/misc/ido.texi
+++ b/doc/misc/ido.texi
@@ -305,7 +305,7 @@ the files in that directory, simply move the directory to 
the head
 of the list and hit @key{RET}.
 
 To go up to the parent directory, delete any partial file name already
-specified (e.g. using @key{DEL}) and hit @key{DEL}.
+specified (e.g., using @key{DEL}) and hit @key{DEL}.
 
 @c @deffn Command ido-delete-backward-updir
 
diff --git a/doc/misc/newsticker.texi b/doc/misc/newsticker.texi
index a9ebc20..aa1ad72 100644
--- a/doc/misc/newsticker.texi
+++ b/doc/misc/newsticker.texi
@@ -123,7 +123,7 @@ You may select any number of feeds from this list of 
(sample) news feeds.
 @vindex newsticker-url-list
 @item newsticker-url-list
 All your personal news feeds are defined here.  Each feed is
-identified by its name and an URL.  You may set the start-time and the
+identified by its name and an address@hidden  You may set the start-time and 
the
 retrieval interval for each feed as well as the retrieval command
 arguments in case that the default values do not fit a certain feed.
 
diff --git a/doc/misc/org.texi b/doc/misc/org.texi
index 2cb80ab..d2721f6 100644
--- a/doc/misc/org.texi
+++ b/doc/misc/org.texi
@@ -891,7 +891,7 @@ Recent Emacs distributions include a packaging system which 
lets you install
 Elisp libraries.  You can install Org with @kbd{M-x package-install RET org}.
 
 @noindent @b{Important}: you need to do this in a session where no @code{.org} 
file has
-been visited, i.e. where no Org built-in function have been loaded.
+been visited, i.e., where no Org built-in function have been loaded.
 Otherwise autoload Org functions will mess up the installation.
 
 Then, to make sure your Org configuration is taken into account, initialize
@@ -10444,7 +10444,7 @@ You can change the default state of this option by 
setting
 
 @item C-v
 Toggle visible-only export.  Only export the text that is currently
-visible, i.e. not hidden by outline visibility in the buffer.
+visible, i.e., not hidden by outline visibility in the buffer.
 
 @end table
 
@@ -12103,7 +12103,7 @@ Internet-style links for all other links.
 A link with no description and destined to a regular (un-itemized) outline
 heading is replaced with a cross-reference and section number of the heading.
 
-A @address@hidden@}}-style reference to an image, table etc. is replaced
+A @address@hidden@}}-style reference to an image, table etc.@: is replaced
 with a cross-reference and sequence number of the labeled entity.
 @xref{Labels and captions in ODT export}.
 
@@ -13410,7 +13410,7 @@ from it (e.g., @code{beamer}).
 
 This is obviously the most powerful customization, since the changes happen
 at the parser level.  Indeed, some export back-ends are built as extensions
-of other ones (e.g. Markdown back-end an extension of HTML back-end).
+of other ones (e.g., Markdown back-end an extension of HTML back-end).
 
 Extending a back-end means that if an element type is not transcoded by the
 new back-end, it will be handled by the original one.  Hence you can extend
diff --git a/doc/misc/pgg.texi b/doc/misc/pgg.texi
index 4518de4..a46c0fb 100644
--- a/doc/misc/pgg.texi
+++ b/doc/misc/pgg.texi
@@ -82,7 +82,7 @@ communication.  Even though Mailcrypt has similar feature, it 
does not
 deal with detached PGP messages, normally used in PGP/MIME
 infrastructure.  This was the main reason why I wrote the new library.
 
-Note that the PGG library is now obsolete, replaced by EasyPG.
+Note that the PGG library is now obsolete, replaced by address@hidden
 @xref{Top,, EasyPG, epa, EasyPG Assistant User's Manual}.
 
 PGP/MIME is an application of MIME Object Security Services (RFC1848).
diff --git a/doc/misc/reftex.texi b/doc/misc/reftex.texi
index facfb43..1497b1f 100644
--- a/doc/misc/reftex.texi
+++ b/doc/misc/reftex.texi
@@ -608,7 +608,7 @@ Show calling point in another window.  This is the point 
from where
 
 @item <
 Promote the current section.  This will convert @code{\section} to
address@hidden, @code{\subsection} to @code{\section} etc. If there is
address@hidden, @code{\subsection} to @code{\section} etc.  If there is
 an active region, all sections in the region will be promoted, including
 the one at point.  To avoid mistakes, @RefTeX{} requires a fresh
 document scan before executing this command; if necessary, it will
@@ -1567,7 +1567,7 @@ Here is the setup:
 @cindex @code{linguex}, LaTeX package
 @cindex LaTeX packages, @code{linguex}
 A more complex example is the @file{linguex.sty} package which defines
-list macros @samp{\ex.}, @samp{\a.}, @samp{\b.} etc. for lists which are
+list macros @samp{\ex.}, @samp{\a.}, @samp{\b.} etc.@: for lists which are
 terminated by @samp{\z.} or by an empty line.
 
 @example
@@ -5906,7 +5906,7 @@ When no BibTeX database files are specified, citations 
can also use
 @noindent @b{Version 3.11}
 @itemize @bullet
 @item
-Fixed bug which led to naked label in (e.g.@:) footnotes.
+Fixed bug which led to naked label in (e.g.)@: footnotes.
 @item
 Added scroll-other-window functions to RefTeX-Select.
 @end itemize
diff --git a/doc/misc/todo-mode.texi b/doc/misc/todo-mode.texi
index 6f684de..f58965c 100644
--- a/doc/misc/todo-mode.texi
+++ b/doc/misc/todo-mode.texi
@@ -1421,7 +1421,7 @@ Advance point to the next button.
 Put point on the previous button.
 @end table
 
-These commands are cyclic, e.g. when point is on the last button,
+These commands are cyclic, e.g., when point is on the last button,
 pressing @kbd{n} moves it to the first button.
 
 Typing @kbd{q} exits Todo Categories mode, killing the buffer and returning
@@ -1787,7 +1787,7 @@ current file:
 @item F h
 @itemx h
 Hide the item headers if visible, or show them if they are hidden.
-With done items, only the done header (i.e. the done tag and date-time
+With done items, only the done header (i.e., the done tag and date-time
 string inserted when the item was marked done) is hidden, the original
 date-time string is not. With filtered items, the category (or
 category-file) tag is not hidden.
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index 5d02d90..d9cb933 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -1001,7 +1001,7 @@ name.
 This special method uses the Android Debug Bridge for accessing
 Android devices.  The Android Debug Bridge must be installed locally.
 Some GNU/Linux distributions offer it for installation, otherwise it
-can be installed as part of the Android SDK.  If the @command{adb}
+can be installed as part of the Android address@hidden  If the @command{adb}
 program is not found via the @env{PATH} environment variable, the
 variable @var{tramp-adb-program} must point to its absolute path.
 
diff --git a/doc/misc/vhdl-mode.texi b/doc/misc/vhdl-mode.texi
index 524a534..777bb10 100644
--- a/doc/misc/vhdl-mode.texi
+++ b/doc/misc/vhdl-mode.texi
@@ -159,7 +159,7 @@ the construct on that line.  A @dfn{syntactic component} 
consists of a
 pair of information (in lisp parlance, a @emph{cons cell}), where the
 first part is a @dfn{syntactic symbol}, and the second part is a
 @dfn{relative buffer position}.  Syntactic symbols describe elements of
-VHDL code, e.g. @code{statement}, @code{comment}, @code{block-open},
+VHDL code, e.g., @code{statement}, @code{comment}, @code{block-open},
 @code{block-close}, etc.  @xref{Syntactic Symbols}, for a complete list
 of currently recognized syntactic symbols and their semantics.  Also,
 the variable @code{vhdl-offsets-alist} contains the list of currently
@@ -633,8 +633,8 @@ similar to what is allowed in @code{vhdl-offsets-alist}.  
When the file is
 visited, VHDL Mode will automatically institute these offsets using
 @code{vhdl-set-offset}.  @xref{Customizing Indentation}.
 
-Note that file style settings (i.e. @code{vhdl-file-style}) are applied
-before file offset settings (i.e. @code{vhdl-file-offsets}).
+Note that file style settings (i.e., @code{vhdl-file-style}) are applied
+before file offset settings (i.e., @code{vhdl-file-offsets}).
 
 
 @node     Advanced Customizations
diff --git a/doc/misc/vip.texi b/doc/misc/vip.texi
index 9a5255d..ebb1494 100644
--- a/doc/misc/vip.texi
+++ b/doc/misc/vip.texi
@@ -436,7 +436,7 @@ Jump to mark (and pop mark off the mark ring).
 
 @cindex region
 
-Vi operators like @kbd{d}, @kbd{c} etc. are usually used in combination
+Vi operators like @kbd{d}, @kbd{c} etc.@: are usually used in combination
 with motion commands.  It is now possible to use current region as the
 argument to these operators.  (A @dfn{region} is a part of buffer
 delimited by point and mark.)  The key @kbd{r} is used for this purpose.
diff --git a/doc/misc/viper.texi b/doc/misc/viper.texi
index bea7f47..0ccc6ac 100644
--- a/doc/misc/viper.texi
+++ b/doc/misc/viper.texi
@@ -1224,7 +1224,7 @@ Facilities like this make Vi's @kbd{:ab} command obsolete.
 @cindex Ex style motion
 @cindex line editor motion
 
-Viper can be set free from the line--limited movements in Vi, such as @kbd{l}
+Viper can be set free from the line-limited movements in Vi, such as @kbd{l}
 refusing to move beyond the line, @key{ESC} moving one character back,
 etc.  These derive from Ex, which is a line editor.  If your
 Viper customization file contains
diff --git a/doc/misc/woman.texi b/doc/misc/woman.texi
index d199afc..a259249 100644
--- a/doc/misc/woman.texi
+++ b/doc/misc/woman.texi
@@ -1141,7 +1141,7 @@ headings.  Default is @code{t}.  [Heading emboldening is 
@emph{not} standard
 @code{man} behavior.]
 
 @item woman-ignore
-A boolean value.  If address@hidden then unrecognized requests etc. are
+A boolean value.  If address@hidden then unrecognized requests etc.@: are
 ignored.  Default is @code{t}.  This gives the standard @code{roff} behavior.
 If @code{nil} then they are left in the buffer, which may aid debugging.
 
diff --git a/lib/dirent.in.h b/lib/dirent.in.h
index ddd3b84..154d268 100644
--- a/lib/dirent.in.h
+++ b/lib/dirent.in.h
@@ -77,6 +77,7 @@ typedef struct gl_directory DIR;
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   undef opendir
 #   define opendir rpl_opendir
+#   define GNULIB_defined_opendir 1
 #  endif
 _GL_FUNCDECL_RPL (opendir, DIR *, (const char *dir_name) _GL_ARG_NONNULL 
((1)));
 _GL_CXXALIAS_RPL (opendir, DIR *, (const char *dir_name));
@@ -128,6 +129,7 @@ _GL_WARN_ON_USE (rewinddir, "rewinddir is not portable - "
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   undef closedir
 #   define closedir rpl_closedir
+#   define GNULIB_defined_closedir 1
 #  endif
 _GL_FUNCDECL_RPL (closedir, int, (DIR *dirp) _GL_ARG_NONNULL ((1)));
 _GL_CXXALIAS_RPL (closedir, int, (DIR *dirp));
diff --git a/lib/dirfd.c b/lib/dirfd.c
new file mode 100644
index 0000000..c91f8e5
--- /dev/null
+++ b/lib/dirfd.c
@@ -0,0 +1,32 @@
+/* dirfd.c -- return the file descriptor associated with an open DIR*
+
+   Copyright (C) 2001, 2006, 2008-2015 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Written by Jim Meyering. */
+
+#include <config.h>
+
+#include <dirent.h>
+#include <errno.h>
+
+int
+dirfd (DIR *dir_p)
+{
+  int fd = DIR_TO_FD (dir_p);
+  if (fd == -1)
+    errno = ENOTSUP;
+  return fd;
+}
diff --git a/lib/fdopendir.c b/lib/fdopendir.c
index 9dc1e7b..837a821 100644
--- a/lib/fdopendir.c
+++ b/lib/fdopendir.c
@@ -93,7 +93,7 @@ fdopendir (int fd)
    That way, barring race conditions, fd_clone_opendir returns a
    stream whose file descriptor is FD.
 
-   If REPLACE_CHDIR or CWD is null, use opendir ("/proc/self/fd/...",
+   If REPLACE_FCHDIR or CWD is null, use opendir ("/proc/self/fd/...",
    falling back on fchdir metadata.  Otherwise, CWD is a saved version
    of the working directory; use fchdir/opendir(".")/restore_cwd(CWD).  */
 static DIR *
@@ -156,7 +156,16 @@ fd_clone_opendir (int fd, struct saved_cwd const *cwd)
       if (! dir && EXPECTED_ERRNO (saved_errno))
         {
           char const *name = _gl_directory_name (fd);
-          return (name ? opendir (name) : NULL);
+          DIR *dp = name ? opendir (name) : NULL;
+
+          /* The caller has done an elaborate dance to arrange for opendir to
+             consume just the right file descriptor.  If dirfd returns -1,
+             though, we're on a system like mingw where opendir does not
+             consume a file descriptor.  Consume it via 'dup' instead.  */
+          if (dp && dirfd (dp) < 0)
+            dup (fd);
+
+          return dp;
         }
 # endif
       errno = saved_errno;
diff --git a/lib/gnulib.mk b/lib/gnulib.mk
index 1b671e7..7703cbf 100644
--- a/lib/gnulib.mk
+++ b/lib/gnulib.mk
@@ -237,6 +237,17 @@ EXTRA_DIST += dirent.in.h
 
 ## end   gnulib module dirent
 
+## begin gnulib module dirfd
+
+if gl_GNULIB_ENABLED_dirfd
+
+endif
+EXTRA_DIST += dirfd.c
+
+EXTRA_libgnu_a_SOURCES += dirfd.c
+
+## end   gnulib module dirfd
+
 ## begin gnulib module dosname
 
 if gl_GNULIB_ENABLED_dosname
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index cf4eeae..df2211b 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,6 +1,158 @@
+2015-03-19  Vibhav Pant  <address@hidden>
+
+       * lisp/progmodes/cperl-mode.el (cperl-electric-backspace):
+       Call delete-backward-space interactively instead of delete-char.
+
+2015-03-19  Stefan Monnier  <address@hidden>
+
+       * emacs-lisp/pcase.el (pcase-lambda): Rewrite.
+
+       * emacs-lisp/eieio.el (object-slots): Return slot names as before
+       (bug#20141).
+
+2015-03-19  Stefan Monnier  <address@hidden>
+
+       EIEIO: Change class's representation to unify instance and class slots
+       * emacs-lisp/eieio-core.el (eieio--class): Change field names and order
+       to match those of cl--class; use cl--slot for both instance slots and
+       class slots.
+       (eieio--object-num-slots): Use cl-struct-slot-info.
+       (eieio--object-class): Rename from eieio--object-class-object.
+       (eieio--object-class-name): Remove.
+       (eieio-defclass-internal): Adjust to new slot representation.
+       Store doc in class rather than in `variable-documentation'.
+       (eieio--perform-slot-validation-for-default): Change API to take
+       a slot object.
+       (eieio--slot-override): New function.
+       (eieio--add-new-slot): Rewrite.
+       (eieio-copy-parents-into-subclass): Rewrite.
+       (eieio--validate-slot-value, eieio--validate-class-slot-value)
+       (eieio-oref-default, eieio-oset-default)
+       (eieio--class-slot-name-index, eieio-set-defaults): Adjust to new
+       slot representation.
+       (eieio--c3-merge-lists): Simplify.
+       (eieio--class/struct-parents): New function.
+       (eieio--class-precedence-bfs): Use it.
+
+       * emacs-lisp/eieio.el (with-slots): Use macroexp-let2.
+       (object-class-fast): Change recommend replacement.
+       (eieio-object-class): Rewrite.
+       (slot-exists-p): Adjust to new slot representation.
+       (initialize-instance): Adjust to new slot representation.
+       (object-write): Adjust to new slot representation.
+
+       * emacs-lisp/eieio-opt.el (eieio--help-print-slot): New function
+       extracted from eieio-help-class-slots.
+       (eieio-help-class-slots): Use it.  Adjust to new slot representation.
+
+       * emacs-lisp/eieio-datadebug.el (data-debug/eieio-insert-slots):
+       Declare to silence warnings.
+       (data-debug-insert-object-button): Avoid `object-slots'.
+       (data-debug/eieio-insert-slots): Adjust to new slot representation.
+
+       * emacs-lisp/eieio-custom.el (eieio-object-value-create)
+       (eieio-object-value-get): Adjust to new slot representation.
+
+       * emacs-lisp/eieio-compat.el
+       (eieio--generic-static-symbol-specializers):
+       Extract from eieio--generic-static-symbol-generalizer.
+       (eieio--generic-static-symbol-generalizer): Use it.
+
+       * emacs-lisp/eieio-base.el (eieio-persistent-convert-list-to-object):
+       Manually map initargs to slot names.
+       (eieio-persistent-validate/fix-slot-value): Adjust to new
+       slot representation.
+
+       * emacs-lisp/cl-preloaded.el (cl--class): Fix type of `parents'.
+
+2015-03-19  Vibhav Pant  <address@hidden>
+
+       * lisp/leim/quail/hangul.el (hangul-delete-backward-char)
+       (hangul-to-hanja-conversion):
+       * lisp/progmodes/cperl-mode.el (cperl-electric-keyword)
+       (cperl-electric-backspace): Use delete-char instead of
+       delete-backward-char, fixes compilation warnings.
+
+2015-03-18  Michael Albinus  <address@hidden>
+
+       * net/tramp-sh.el (tramp-do-directory-files-and-attributes-with-stat):
+       Mark apostrophs with ?/ instead of \037.  (Bug#20117)
+
+2015-03-18  Stefan Monnier  <address@hidden>
+
+       Add classes as run-time descriptors of cl-structs.
+       * emacs-lisp/cl-preloaded.el (cl--struct-get-class): New function.
+       (cl--make-slot-desc): New constructor.
+       (cl--plist-remove, cl--struct-register-child): New functions.
+       (cl-struct-define): Rewrite.
+       (cl-structure-class, cl-structure-object, cl-slot-descriptor)
+       (cl--class): New structs.
+       (cl--struct-default-parent): Initialize it here.
+       * emacs-lisp/cl-macs.el (cl--find-class): New macro.
+       (cl-defsubst, cl--defsubst-expand, cl--sublis): Move before first use.
+       (cl--struct-default-parent): New var.
+       (cl-defstruct): Adjust to new representation of classes; add
+       default parent.  In accessors, signal `wrong-type-argument' rather than
+       a generic error.
+       (cl-struct-sequence-type, cl-struct-slot-info)
+       (cl-struct-slot-offset): Rewrite.
+       * emacs-lisp/cl-generic.el (cl--generic-struct-specializers)
+       (cl-generic-generalizers): Rewrite.
+
+       * emacs-lisp/macroexp.el (macroexp--debug-eager): New var.
+       (internal-macroexpand-for-load): Use it.
+
+       * emacs-lisp/debug.el (debug--implement-debug-on-entry):
+       Bind inhibit-debug-on-entry here...
+       (debug): Instead of here.
+
+2015-03-18  Dima Kogan  <address@hidden>
+
+       Have gud-display-line not display source buffer in gud window.
+       * lisp/progmodes/gud.el (gud-display-line): Make display-buffer
+       not reuse selected window.  (Bug#17675, Bug#19901, Bug#20034)
+
+2015-03-17  Tassilo Horn  <address@hidden>
+
+       * emacs-lisp/byte-run.el (macro-declarations-alist):
+       New declaration no-font-lock-keyword.
+       (defmacro): Flush font-lock in existing elisp buffers.
+
+       * emacs-lisp/lisp-mode.el (lisp--el-update-after-load)
+       (lisp--el-update-macro-regexp, lisp--el-macro-regexp):
+       Delete functions and defconst.
+       (lisp--el-match-keyword): Rename from lisp--el-match-macro.
+       (lisp--el-font-lock-flush-elisp-buffers): New function.
+       (lisp-mode-variables): Remove code for updating
+       lisp--el-macro-regexp, and add
+       lisp--el-font-lock-flush-elisp-buffers to after-load-functions.
+
+2015-03-17  Simen Heggestøyl  <address@hidden>
+
+       * textmodes/css-mode.el (css--font-lock-keywords):
+       Discriminate between pseudo-classes and pseudo-elements.
+       (css-pseudo-ids): Remove.
+       (css-pseudo-class-ids, css-pseudo-element-ids): New variables.
+       (css--complete-property): New function for completing CSS properties.
+       (css--complete-pseudo-element-or-class): New function
+       completing CSS pseudo-elements and pseudo-classes.
+       (css--complete-at-rule): New function for completing CSS at-rules.
+       (css-completion-at-point): New function.
+       (css-mode): Add support for completion.
+       (css-extract-keyword-list, css-extract-parse-val-grammar)
+       (css-extract-props-and-vals): Remove function in favor of manual
+       extraction.
+       (css-at-ids): Update list of CSS at-rule ids.
+       (css-property-ids): Update list of CSS properties.
+
+2015-03-17  Bozhidar Batsov  <address@hidden>
+
+       * progmodes/ruby-mode.el (ruby-font-lock-keywords): Font-lock
+       more Kernel methods.
+
 2015-03-17  Michael Albinus  <address@hidden>
 
-       * tramp-sh.el (tramp-maybe-send-script): Avoid leading tabs in
+       * net/tramp-sh.el (tramp-maybe-send-script): Avoid leading tabs in
        shell scripts.  (Bug#20118)
 
 2015-03-17  Eli Zaretskii  <address@hidden>
@@ -113,7 +265,7 @@
 
        * progmodes/sql.el: Version 3.5
        (sql-starts-with-prompt-re, sql-ends-with-prompt-re): Match password 
prompts.
-       (sql-interactive-remove-continuation-prompt): Fixed regression. 
(Bug#6686)
+       (sql-interactive-remove-continuation-prompt): Fix regression. (Bug#6686)
 
 2015-03-14  Daniel Colascione  <address@hidden>
 
@@ -128,8 +280,8 @@
        info-look fixes for Texinfo 5
        * info-look.el (c-mode, bison-mode, makefile-mode)
        (makefile-automake-mode, texinfo-mode, autoconf-mode, awk-mode)
-       (latex-mode, emacs-lisp-mode, sh-mode, cfengine-mode): Match
-       `foo' and 'foo' and ‘foo’ for @item and similar.
+       (latex-mode, emacs-lisp-mode, sh-mode, cfengine-mode):
+       Match `foo' and 'foo' and ‘foo’ for @item and similar.
        (latex-mode): Match multi-arg \frac{num}{den} or \sqrt[root]{n} in
        suffix regexp.
 
diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el
index caa7e3d..e0d6c3e 100644
--- a/lisp/emacs-lisp/byte-run.el
+++ b/lisp/emacs-lisp/byte-run.el
@@ -147,11 +147,16 @@ This is used by `declare'.")
 (defvar macro-declarations-alist
   (cons
    (list 'debug
-         #'(lambda (name _args spec)
-             (list 'progn :autoload-end
-                   (list 'put (list 'quote name)
-                         ''edebug-form-spec (list 'quote spec)))))
-   defun-declarations-alist)
+        #'(lambda (name _args spec)
+            (list 'progn :autoload-end
+                  (list 'put (list 'quote name)
+                        ''edebug-form-spec (list 'quote spec)))))
+   (cons
+    (list 'no-font-lock-keyword
+         #'(lambda (name _args val)
+             (list 'function-put (list 'quote name)
+                   ''no-font-lock-keyword (list 'quote val))))
+    defun-declarations-alist))
   "List associating properties of macros to their macro expansion.
 Each element of the list takes the form (PROP FUN) where FUN is a function.
 For each (PROP . VALUES) in a macro's declaration, the FUN corresponding
@@ -201,6 +206,19 @@ The return value is undefined.
                          (message "Warning: Unknown macro property %S in %S"
                                   (car x) name))))
                  decls)))
+          ;; Refresh font-lock if this is a new macro, or it is an
+          ;; existing macro whose 'no-font-lock-keyword declaration
+          ;; has changed.
+          (if (and
+               ;; If lisp-mode hasn't been loaded, there's no reason
+               ;; to flush.
+               (fboundp 'lisp--el-font-lock-flush-elisp-buffers)
+               (or (not (fboundp name)) ;; new macro
+                   (and (fboundp name)  ;; existing macro
+                        (member `(function-put ',name 'no-font-lock-keyword
+                                               ',(get name 
'no-font-lock-keyword))
+                                declarations))))
+              (lisp--el-font-lock-flush-elisp-buffers))
           (if declarations
               (cons 'prog1 (cons def declarations))
             def))))))
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index 41c760e..fb11a3e 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -857,6 +857,18 @@ Can only be used from within the lexical body of a primary 
or around method."
 ;;; Support for cl-defstructs specializers.
 
 (defun cl--generic-struct-tag (name)
+  ;; It's tempting to use (and (vectorp ,name) (aref ,name 0))
+  ;; but that would suffer from some problems:
+  ;; - the vector may have size 0.
+  ;; - when called on an actual vector (rather than an object), we'd
+  ;;   end up returning an arbitrary value, possibly colliding with
+  ;;   other tagcode's values.
+  ;; - it can also result in returning all kinds of irrelevant
+  ;;   values which would end up filling up the method-cache with
+  ;;   lots of irrelevant/redundant entries.
+  ;; FIXME: We could speed this up by introducing a dedicated
+  ;; vector type at the C level, so we could do something like
+  ;; (and (vector-objectp ,name) (aref ,name 0))
   `(and (vectorp ,name)
         (> (length ,name) 0)
         (let ((tag (aref ,name 0)))
@@ -864,14 +876,18 @@ Can only be used from within the lexical body of a 
primary or around method."
               tag))))
 
 (defun cl--generic-struct-specializers (tag)
-  (and (symbolp tag)
-       ;; A method call shouldn't itself mess with the match-data.
-       (string-match-p "\\`cl-struct-\\(.*\\)" (symbol-name tag))
-       (let ((types (list (intern (substring (symbol-name tag) 10)))))
-        (while (get (car types) 'cl-struct-include)
-          (push (get (car types) 'cl-struct-include) types))
-        (push 'cl-structure-object types) ;The "parent type" of all cl-structs.
-        (nreverse types))))
+  (and (symbolp tag) (boundp tag)
+       (let ((class (symbol-value tag)))
+         (when (cl-typep class 'cl-structure-class)
+           (let ((types ())
+                 (classes (list class)))
+             ;; BFS precedence.
+             (while (let ((class (pop classes)))
+                      (push (cl--class-name class) types)
+                      (setq classes
+                            (append classes
+                                    (cl--class-parents class)))))
+             (nreverse types))))))
 
 (defconst cl--generic-struct-generalizer
   (cl-generic-make-generalizer
@@ -881,27 +897,17 @@ Can only be used from within the lexical body of a 
primary or around method."
 (cl-defmethod cl-generic-generalizers :extra "cl-struct" (type)
   "Support for dispatch on cl-struct types."
   (or
-   (and (symbolp type)
-        (get type 'cl-struct-type)
-        (or (null (car (get type 'cl-struct-type)))
-            (error "Can't dispatch on cl-struct %S: type is %S"
-                   type (car (get type 'cl-struct-type))))
-        (or (equal '(cl-tag-slot) (car (get type 'cl-struct-slots)))
-            (error "Can't dispatch on cl-struct %S: no tag in slot 0"
-                   type))
-        ;; It's tempting to use (and (vectorp ,name) (aref ,name 0))
-        ;; but that would suffer from some problems:
-        ;; - the vector may have size 0.
-        ;; - when called on an actual vector (rather than an object), we'd
-        ;;   end up returning an arbitrary value, possibly colliding with
-        ;;   other tagcode's values.
-        ;; - it can also result in returning all kinds of irrelevant
-        ;;   values which would end up filling up the method-cache with
-        ;;   lots of irrelevant/redundant entries.
-        ;; FIXME: We could speed this up by introducing a dedicated
-        ;; vector type at the C level, so we could do something like
-        ;; (and (vector-objectp ,name) (aref ,name 0))
-        (list cl--generic-struct-generalizer))
+   (when (symbolp type)
+     ;; Use the "cl--struct-class*" (inlinable) functions/macros rather than
+     ;; the "cl-struct-*" variants which aren't inlined, so that dispatch can
+     ;; take place without requiring cl-lib.
+     (let ((class (cl--find-class type)))
+       (and (cl-typep class 'cl-structure-class)
+            (or (null (cl--struct-class-type class))
+               (error "Can't dispatch on cl-struct %S: type is %S"
+                     type (cl--struct-class-type class)))
+            (progn (cl-assert (null (cl--struct-class-named class))) t)
+            (list cl--generic-struct-generalizer))))
    (cl-call-next-method)))
 
 ;;; Dispatch on "system types".
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 56fbcf0..d386678 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -2434,8 +2434,79 @@ Like `cl-callf', but PLACE is the second argument of 
FUNC, not the first.
                    (if (symbolp func) (cons func rargs)
                      `(funcall #',func ,@rargs))))))))
 
+;;;###autoload
+(defmacro cl-defsubst (name args &rest body)
+  "Define NAME as a function.
+Like `defun', except the function is automatically declared `inline' and
+the arguments are immutable.
+ARGLIST allows full Common Lisp conventions, and BODY is implicitly
+surrounded by (cl-block NAME ...).
+The function's arguments should be treated as immutable.
+
+\(fn NAME ARGLIST [DOCSTRING] BODY...)"
+  (declare (debug cl-defun) (indent 2))
+  (let* ((argns (cl--arglist-args args))
+         (p argns)
+         ;; (pbody (cons 'progn body))
+         )
+    (while (and p (eq (cl--expr-contains args (car p)) 1)) (pop p))
+    `(progn
+       ,(if p nil   ; give up if defaults refer to earlier args
+          `(cl-define-compiler-macro ,name
+             ,(if (memq '&key args)
+                  `(&whole cl-whole &cl-quote ,@args)
+                (cons '&cl-quote args))
+             (cl--defsubst-expand
+              ',argns '(cl-block ,name ,@body)
+              ;; We used to pass `simple' as
+              ;; (not (or unsafe (cl-expr-access-order pbody argns)))
+              ;; But this is much too simplistic since it
+              ;; does not pay attention to the argvs (and
+              ;; cl-expr-access-order itself is also too naive).
+              nil
+              ,(and (memq '&key args) 'cl-whole) nil ,@argns)))
+       (cl-defun ,name ,args ,@body))))
+
+(defun cl--defsubst-expand (argns body simple whole _unsafe &rest argvs)
+  (if (and whole (not (cl--safe-expr-p (cons 'progn argvs)))) whole
+    (if (cl--simple-exprs-p argvs) (setq simple t))
+    (let* ((substs ())
+           (lets (delq nil
+                       (cl-mapcar (lambda (argn argv)
+                                    (if (or simple (macroexp-const-p argv))
+                                        (progn (push (cons argn argv) substs)
+                                               nil)
+                                      (list argn argv)))
+                                  argns argvs))))
+      ;; FIXME: `sublis/subst' will happily substitute the symbol
+      ;; `argn' in places where it's not used as a reference
+      ;; to a variable.
+      ;; FIXME: `sublis/subst' will happily copy `argv' to a different
+      ;; scope, leading to name capture.
+      (setq body (cond ((null substs) body)
+                       ((null (cdr substs))
+                        (cl-subst (cdar substs) (caar substs) body))
+                       (t (cl--sublis substs body))))
+      (if lets `(let ,lets ,body) body))))
+
+(defun cl--sublis (alist tree)
+  "Perform substitutions indicated by ALIST in TREE (non-destructively)."
+  (let ((x (assq tree alist)))
+    (cond
+     (x (cdr x))
+     ((consp tree)
+      (cons (cl--sublis alist (car tree)) (cl--sublis alist (cdr tree))))
+     (t tree))))
+
 ;;; Structures.
 
+(defmacro cl--find-class (type)
+  `(get ,type 'cl--class))
+
+;; Rather than hard code cl-structure-object, we indirect through this variable
+;; for bootstrapping reasons.
+(defvar cl--struct-default-parent nil)
+
 ;;;###autoload
 (defmacro cl-defstruct (struct &rest descs)
   "Define a struct type.
@@ -2491,6 +2562,7 @@ non-nil value, that slot cannot be set via `setf'.
         (tag (intern (format "cl-struct-%s" name)))
         (tag-symbol (intern (format "cl-struct-%s-tags" name)))
         (include-descs nil)
+        (include-name nil)
         (type nil)
         (named nil)
         (forms nil)
@@ -2520,12 +2592,14 @@ non-nil value, that slot cannot be set via `setf'.
              ((eq opt :predicate)
               (if args (setq predicate (car args))))
              ((eq opt :include)
-               (when include (error "Can't :include more than once"))
-              (setq include (car args)
-                    include-descs (mapcar (function
-                                           (lambda (x)
-                                             (if (consp x) x (list x))))
-                                          (cdr args))))
+               ;; FIXME: Actually, we can include more than once as long as
+               ;; we include EIEIO classes rather than cl-structs!
+               (when include-name (error "Can't :include more than once"))
+               (setq include-name (car args))
+               (setq include-descs (mapcar (function
+                                            (lambda (x)
+                                              (if (consp x) x (list x))))
+                                           (cdr args))))
              ((eq opt :print-function)
               (setq print-func (car args)))
              ((eq opt :type)
@@ -2537,19 +2611,21 @@ non-nil value, that slot cannot be set via `setf'.
                                  descs)))
              (t
               (error "Slot option %s unrecognized" opt)))))
+    (unless (or include-name type)
+      (setq include-name cl--struct-default-parent))
+    (when include-name (setq include (cl--struct-get-class include-name)))
     (if print-func
        (setq print-func
               `(progn (funcall #',print-func cl-x cl-s cl-n) t))
-      (or type (and include (not (get include 'cl-struct-print)))
+      (or type (and include (not (cl--struct-class-print include)))
          (setq print-auto t
                print-func (and (or (not (or include type)) (null print-func))
                                `(progn
                                    (princ ,(format "#S(%s" name) cl-s))))))
     (if include
-       (let ((inc-type (get include 'cl-struct-type))
-             (old-descs (get include 'cl-struct-slots)))
-         (or inc-type (error "%s is not a struct name" include))
-         (and type (not (eq (car inc-type) type))
+       (let* ((inc-type (cl--struct-class-type include))
+               (old-descs (cl-struct-slot-info include)))
+         (and type (not (eq inc-type type))
               (error ":type disagrees with :include for %s" name))
          (while include-descs
            (setcar (memq (or (assq (caar include-descs) old-descs)
@@ -2558,9 +2634,9 @@ non-nil value, that slot cannot be set via `setf'.
                          old-descs)
                    (pop include-descs)))
          (setq descs (append old-descs (delq (assq 'cl-tag-slot descs) descs))
-               type (car inc-type)
-               named (assq 'cl-tag-slot descs))
-         (if (cadr inc-type) (setq tag name named t)))
+               type inc-type
+               named (if type (assq 'cl-tag-slot descs) 'true))
+         (if (cl--struct-class-named include) (setq tag name named t)))
       (if type
          (progn
            (or (memq type '(vector list))
@@ -2605,8 +2681,8 @@ non-nil value, that slot cannot be set via `setf'.
                        (declare (side-effect-free t))
                        ,@(and pred-check
                              (list `(or ,pred-check
-                                         (error "%s accessing a non-%s"
-                                                ',accessor ',name))))
+                                         (signal 'wrong-type-argument
+                                                 (list ',name cl-x)))))
                        ,(if (memq type '(nil vector)) `(aref cl-x ,pos)
                           (if (= pos 0) '(car cl-x)
                             `(nth ,pos cl-x))))
@@ -2682,8 +2758,11 @@ non-nil value, that slot cannot be set via `setf'.
     `(progn
        (defvar ,tag-symbol)
        ,@(nreverse forms)
+       ;; Call cl-struct-define during compilation as well, so that
+       ;; a subsequent cl-defstruct in the same file can correctly include this
+       ;; struct as a parent.
        (eval-and-compile
-         (cl-struct-define ',name ,docstring ',include
+         (cl-struct-define ',name ,docstring ',include-name
                            ',type ,(eq named t) ',descs ',tag-symbol ',tag
                            ',print-auto))
        ',name)))
@@ -2693,7 +2772,7 @@ non-nil value, that slot cannot be set via `setf'.
 STRUCT-TYPE is a symbol naming a struct type.  Return 'vector or
 'list, or nil if STRUCT-TYPE is not a struct type. "
   (declare (side-effect-free t) (pure t))
-  (car (get struct-type 'cl-struct-type)))
+  (cl--struct-class-type (cl--struct-get-class struct-type)))
 
 (defun cl-struct-slot-info (struct-type)
   "Return a list of slot names of struct STRUCT-TYPE.
@@ -2702,7 +2781,19 @@ slot name symbol and OPTS is a list of slot options 
given to
 `cl-defstruct'.  Dummy slots that represent the struct name and
 slots skipped by :initial-offset may appear in the list."
   (declare (side-effect-free t) (pure t))
-  (get struct-type 'cl-struct-slots))
+  (let* ((class (cl--struct-get-class struct-type))
+         (slots (cl--struct-class-slots class))
+         (type (cl--struct-class-type class))
+         (descs (if type () (list '(cl-tag-slot)))))
+    (dotimes (i (length slots))
+      (let ((slot (aref slots i)))
+        (push `(,(cl--slot-descriptor-name slot)
+                ,(cl--slot-descriptor-initform slot)
+                ,@(if (not (eq (cl--slot-descriptor-type slot) t))
+                      `(:type ,(cl--slot-descriptor-type slot)))
+                ,@(cl--slot-descriptor-props slot))
+              descs)))
+    (nreverse descs)))
 
 (defun cl-struct-slot-offset (struct-type slot-name)
   "Return the offset of slot SLOT-NAME in STRUCT-TYPE.
@@ -2711,9 +2802,8 @@ the structure data type and is adjusted for any structure 
name
 and :initial-offset slots.  Signal error if struct STRUCT-TYPE
 does not contain SLOT-NAME."
   (declare (side-effect-free t) (pure t))
-  (or (cl-position slot-name
-                   (cl-struct-slot-info struct-type)
-                   :key #'car :test #'eq)
+  (or (gethash slot-name
+               (cl--class-index-table (cl--struct-get-class struct-type)))
       (error "struct %s has no slot %s" struct-type slot-name)))
 
 (defvar byte-compile-function-environment)
@@ -2898,70 +2988,6 @@ macro that returns its `&whole' argument."
     (if cl-found (setcdr cl-found t)))
   `(throw ,cl-tag ,cl-value))
 
-;;;###autoload
-(defmacro cl-defsubst (name args &rest body)
-  "Define NAME as a function.
-Like `defun', except the function is automatically declared `inline' and
-the arguments are immutable.
-ARGLIST allows full Common Lisp conventions, and BODY is implicitly
-surrounded by (cl-block NAME ...).
-The function's arguments should be treated as immutable.
-
-\(fn NAME ARGLIST [DOCSTRING] BODY...)"
-  (declare (debug cl-defun) (indent 2))
-  (let* ((argns (cl--arglist-args args))
-         (p argns)
-         ;; (pbody (cons 'progn body))
-         )
-    (while (and p (eq (cl--expr-contains args (car p)) 1)) (pop p))
-    `(progn
-       ,(if p nil   ; give up if defaults refer to earlier args
-          `(cl-define-compiler-macro ,name
-             ,(if (memq '&key args)
-                  `(&whole cl-whole &cl-quote ,@args)
-                (cons '&cl-quote args))
-             (cl--defsubst-expand
-              ',argns '(cl-block ,name ,@body)
-              ;; We used to pass `simple' as
-              ;; (not (or unsafe (cl-expr-access-order pbody argns)))
-              ;; But this is much too simplistic since it
-              ;; does not pay attention to the argvs (and
-              ;; cl-expr-access-order itself is also too naive).
-              nil
-              ,(and (memq '&key args) 'cl-whole) nil ,@argns)))
-       (cl-defun ,name ,args ,@body))))
-
-(defun cl--defsubst-expand (argns body simple whole _unsafe &rest argvs)
-  (if (and whole (not (cl--safe-expr-p (cons 'progn argvs)))) whole
-    (if (cl--simple-exprs-p argvs) (setq simple t))
-    (let* ((substs ())
-           (lets (delq nil
-                       (cl-mapcar (lambda (argn argv)
-                                    (if (or simple (macroexp-const-p argv))
-                                        (progn (push (cons argn argv) substs)
-                                               nil)
-                                      (list argn argv)))
-                                  argns argvs))))
-      ;; FIXME: `sublis/subst' will happily substitute the symbol
-      ;; `argn' in places where it's not used as a reference
-      ;; to a variable.
-      ;; FIXME: `sublis/subst' will happily copy `argv' to a different
-      ;; scope, leading to name capture.
-      (setq body (cond ((null substs) body)
-                       ((null (cdr substs))
-                        (cl-subst (cdar substs) (caar substs) body))
-                       (t (cl--sublis substs body))))
-      (if lets `(let ,lets ,body) body))))
-
-(defun cl--sublis (alist tree)
-  "Perform substitutions indicated by ALIST in TREE (non-destructively)."
-  (let ((x (assq tree alist)))
-    (cond
-     (x (cdr x))
-     ((consp tree)
-      (cons (cl--sublis alist (car tree)) (cl--sublis alist (cdr tree))))
-     (t tree))))
-
 ;; Compile-time optimizations for some functions defined in this package.
 
 (defun cl--compiler-macro-member (form a list &rest keys)
diff --git a/lisp/emacs-lisp/cl-preloaded.el b/lisp/emacs-lisp/cl-preloaded.el
index 401d34b..ed0639b 100644
--- a/lisp/emacs-lisp/cl-preloaded.el
+++ b/lisp/emacs-lisp/cl-preloaded.el
@@ -21,36 +21,22 @@
 
 ;;; Commentary:
 
-;; The expectation is that structs defined with cl-defstruct do not
-;; need cl-lib at run-time, but we'd like to hide the details of the
-;; cl-struct metadata behind the cl-struct-define function, so we put
-;; it in this pre-loaded file.
+;; The cl-defstruct macro is full of circularities, since it uses the
+;; cl-structure-class type (and its accessors) which is defined with itself,
+;; and it setups a default parent (cl-structure-object) which is also defined
+;; with cl-defstruct, and to make things more interesting, the class of
+;; cl-structure-object is of course an object of type cl-structure-class while
+;; cl-structure-class's parent is cl-structure-object.
+;; Furthermore, the code generated by cl-defstruct generally assumes that the
+;; parent will be loaded when the child is loaded.  But at the same time, the
+;; expectation is that structs defined with cl-defstruct do not need cl-lib at
+;; run-time, which means that the `cl-structure-object' parent can't be in
+;; cl-lib but should be preloaded.  So here's this preloaded circular setup.
 
 ;;; Code:
 
 (eval-when-compile (require 'cl-lib))
-
-(defun cl-struct-define (name docstring parent type named slots children-sym
-                              tag print-auto)
-  (cl-assert (or type (equal '(cl-tag-slot) (car slots))))
-  (cl-assert (or type (not named)))
-  (if (boundp children-sym)
-      (add-to-list children-sym tag)
-    (set children-sym (list tag)))
-  (let* ((parent-class parent))
-    (while parent-class
-      (add-to-list (intern (format "cl-struct-%s-tags" parent-class)) tag)
-      (setq parent-class (get parent-class 'cl-struct-include))))
-  ;; If the cl-generic support, we need to be able to check
-  ;; if a vector is a cl-struct object, without knowing its particular type.
-  ;; So we use the (otherwise) unused function slots of the tag symbol
-  ;; to put a special witness value, to make the check easy and reliable.
-  (unless named (fset tag :quick-object-witness-check))
-  (put name 'cl-struct-slots slots)
-  (put name 'cl-struct-type (list type named))
-  (if parent (put name 'cl-struct-include parent))
-  (if print-auto (put name 'cl-struct-print print-auto))
-  (if docstring (put name 'structure-documentation docstring)))
+(eval-when-compile (require 'cl-macs))  ;For cl--struct-class.
 
 ;; The `assert' macro from the cl package signals
 ;; `cl-assertion-failed' at runtime so always define it.
@@ -63,6 +49,201 @@
         (apply #'error string (append sargs args))
       (signal 'cl-assertion-failed `(,form ,@sargs)))))
 
+;; When we load this (compiled) file during pre-loading, the cl--struct-class
+;; code below will need to access the `cl-struct' info, since it's considered
+;; already as its parent (because `cl-struct' was defined while the file was
+;; compiled).  So let's temporarily setup a fake.
+(defvar cl-struct-cl-structure-object-tags nil)
+(unless (cl--find-class 'cl-structure-object)
+  (setf (cl--find-class 'cl-structure-object) 'dummy))
+
+(fset 'cl--make-slot-desc
+      ;; To break circularity, we pre-define the slot constructor by hand.
+      ;; It's redefined a bit further down as part of the cl-defstruct of
+      ;; cl--slot-descriptor.
+      ;; BEWARE: Obviously, it's important to keep the two in sync!
+      (lambda (name &optional initform type props)
+        (vector 'cl-struct-cl-slot-descriptor
+                name initform type props)))
+
+(defun cl--struct-get-class (name)
+  (or (if (not (symbolp name)) name)
+      (cl--find-class name)
+      (if (not (get name 'cl-struct-type))
+          ;; FIXME: Add a conversion for `eieio--class' so we can
+          ;; create a cl-defstruct that inherits from an eieio class?
+          (error "%S is not a struct name" name)
+        ;; Backward compatibility with a defstruct compiled with a version
+        ;; cl-defstruct from Emacs<25.  Convert to new format.
+        (let ((tag (intern (format "cl-struct-%s" name)))
+              (type-and-named (get name 'cl-struct-type))
+              (descs (get name 'cl-struct-slots)))
+          (cl-struct-define name nil (get name 'cl-struct-include)
+                            (unless (and (eq (car type-and-named) 'vector)
+                                         (null (cadr type-and-named))
+                                         (assq 'cl-tag-slot descs))
+                              (car type-and-named))
+                            (cadr type-and-named)
+                            descs
+                            (intern (format "cl-struct-%s-tags" name))
+                            tag
+                            (get name 'cl-struct-print))
+          (cl--find-class name)))))
+
+(defun cl--plist-remove (plist member)
+  (cond
+   ((null plist) nil)
+   ((null member) plist)
+   ((eq plist member) (cddr plist))
+   (t `(,(car plist) ,(cadr plist) ,@(cl--plist-remove (cddr plist) member)))))
+
+(defun cl--struct-register-child (parent tag)
+  ;; Can't use (cl-typep parent 'cl-structure-class) at this stage
+  ;; because `cl-structure-class' is defined later.
+  (while (vectorp parent)
+    (add-to-list (cl--struct-class-children-sym parent) tag)
+    ;; Only register ourselves as a child of the leftmost parent since structs
+    ;; can only only have one parent.
+    (setq parent (car (cl--struct-class-parents parent)))))
+
+;;;###autoload
+(defun cl-struct-define (name docstring parent type named slots children-sym
+                              tag print)
+  (cl-assert (or type (not named)))
+  (if (boundp children-sym)
+      (add-to-list children-sym tag)
+    (set children-sym (list tag)))
+  (and (null type) (eq (caar slots) 'cl-tag-slot)
+       ;; Hide the tag slot from "standard" (i.e. non-`type'd) structs.
+       (setq slots (cdr slots)))
+  (let* ((parent-class (when parent (cl--struct-get-class parent)))
+         (n (length slots))
+         (index-table (make-hash-table :test 'eq :size n))
+         (vslots (let ((v (make-vector n nil))
+                       (i 0)
+                       (offset (if type 0 1)))
+                   (dolist (slot slots)
+                     (let* ((props (cddr slot))
+                            (typep (plist-member props :type))
+                            (type (if typep (cadr typep) t)))
+                       (aset v i (cl--make-slot-desc
+                                  (car slot) (nth 1 slot)
+                                  type (cl--plist-remove props typep))))
+                     (puthash (car slot) (+ i offset) index-table)
+                     (cl-incf i))
+                   v))
+         (class (cl--struct-new-class
+                 name docstring
+                 (unless (symbolp parent-class) (list parent-class))
+                 type named vslots index-table children-sym tag print)))
+    (unless (symbolp parent-class)
+      (let ((pslots (cl--struct-class-slots parent-class)))
+        (or (>= n (length pslots))
+            (let ((ok t))
+              (dotimes (i (length pslots))
+                (unless (eq (cl--slot-descriptor-name (aref pslots i))
+                            (cl--slot-descriptor-name (aref vslots i)))
+                  (setq ok nil)))
+              ok)
+            (error "Included struct %S has changed since compilation of %S"
+                   parent name))))
+    (cl--struct-register-child parent-class tag)
+    (unless (eq named t)
+      (eval `(defconst ,tag ',class) t)
+      ;; In the cl-generic support, we need to be able to check
+      ;; if a vector is a cl-struct object, without knowing its particular 
type.
+      ;; So we use the (otherwise) unused function slots of the tag symbol
+      ;; to put a special witness value, to make the check easy and reliable.
+      (fset tag :quick-object-witness-check))
+    (setf (cl--find-class name) class)))
+
+(cl-defstruct (cl-structure-class
+               (:conc-name cl--struct-class-)
+               (:predicate cl--struct-class-p)
+               (:constructor nil)
+               (:constructor cl--struct-new-class
+                (name docstring parents type named slots index-table
+                      children-sym tag print))
+               (:copier nil))
+  "The type of CL structs descriptors."
+  ;; The first few fields here are actually inherited from cl--class, but we
+  ;; have to define this one before, to break the circularity, so we manually
+  ;; list the fields here and later "backpatch" cl--class as the parent.
+  ;; BEWARE: Obviously, it's indispensable to keep these two structs in sync!
+  (name nil :type symbol)               ;The type name.
+  (docstring nil :type string)
+  (parents nil :type (list-of cl--class)) ;The included struct.
+  (slots nil :type (vector cl--slot-descriptor))
+  (index-table nil :type hash-table)
+  (tag nil :type symbol) ;Placed in cl-tag-slot.  Holds the struct-class 
object.
+  (type nil :type (memq (vector list)))
+  (named nil :type bool)
+  (print nil :type bool)
+  (children-sym nil :type symbol) ;This sym's value holds the tags of children.
+  )
+
+(cl-defstruct (cl-structure-object
+               (:predicate cl-struct-p)
+               (:constructor nil)
+               (:copier nil))
+  "The root parent of all \"normal\" CL structs")
+
+(setq cl--struct-default-parent 'cl-structure-object)
+
+(cl-defstruct (cl-slot-descriptor
+               (:conc-name cl--slot-descriptor-)
+               (:constructor nil)
+               (:constructor cl--make-slot-descriptor
+                (name &optional initform type props))
+               (:copier cl--copy-slot-descriptor))
+  ;; FIXME: This is actually not used yet, for circularity reasons!
+  "Descriptor of structure slot."
+  name                                  ;Attribute name (symbol).
+  initform
+  type
+  ;; Extra properties, kept in an alist, can include:
+  ;;  :documentation, :protection, :custom, :label, :group, :printer.
+  (props nil :type alist))
+
+(cl-defstruct (cl--class
+               (:constructor nil)
+               (:copier nil))
+  "Type of descriptors for any kind of structure-like data."
+  ;; Intended to be shared between defstruct and defclass.
+  (name nil :type symbol)               ;The type name.
+  (docstring nil :type string)
+  ;; For structs there can only be one parent, but when EIEIO classes inherit
+  ;; from cl--class, we'll need this to hold a list.
+  (parents nil :type (list-of cl--class))
+  (slots nil :type (vector cl-slot-descriptor))
+  (index-table nil :type hash-table))
+
+(cl-assert
+ (let ((sc-slots (cl--struct-class-slots (cl--find-class 'cl-structure-class)))
+       (c-slots (cl--struct-class-slots (cl--find-class 'cl--class)))
+       (eq t))
+   (dotimes (i (length c-slots))
+     (let ((sc-slot (aref sc-slots i))
+           (c-slot (aref c-slots i)))
+       (unless (eq (cl--slot-descriptor-name sc-slot)
+                   (cl--slot-descriptor-name c-slot))
+         (setq eq nil))))
+   eq))
+
+;; Close the recursion between cl-structure-object and cl-structure-class.
+(setf (cl--struct-class-parents (cl--find-class 'cl-structure-class))
+      (list (cl--find-class 'cl--class)))
+(cl--struct-register-child
+ (cl--find-class 'cl--class)
+ (cl--struct-class-tag (cl--find-class 'cl-structure-class)))
+
+(cl-assert (cl--find-class 'cl-structure-class))
+(cl-assert (cl--find-class 'cl-structure-object))
+(cl-assert (cl-struct-p (cl--find-class 'cl-structure-class)))
+(cl-assert (cl-struct-p (cl--find-class 'cl-structure-object)))
+(cl-assert (cl--class-p (cl--find-class 'cl-structure-class)))
+(cl-assert (cl--class-p (cl--find-class 'cl-structure-object)))
+
 ;; Make sure functions defined with cl-defsubst can be inlined even in
 ;; packages which do not require CL.  We don't put an autoload cookie
 ;; directly on that function, since those cookies only go to cl-loaddefs.
diff --git a/lisp/emacs-lisp/debug.el b/lisp/emacs-lisp/debug.el
index 8c1440d..8321328 100644
--- a/lisp/emacs-lisp/debug.el
+++ b/lisp/emacs-lisp/debug.el
@@ -106,10 +106,10 @@ This is to optimize `debugger-make-xrefs'.")
   "Non-nil if we expect to get back in the debugger soon.")
 
 (defvar inhibit-debug-on-entry nil
-  "Non-nil means that debug-on-entry is disabled.")
+  "Non-nil means that `debug-on-entry' is disabled.")
 
 (defvar debugger-jumping-flag nil
-  "Non-nil means that debug-on-entry is disabled.
+  "Non-nil means that `debug-on-entry' is disabled.
 This variable is used by `debugger-jump', `debugger-step-through',
 and `debugger-reenable' to temporarily disable debug-on-entry.")
 
@@ -165,7 +165,6 @@ first will be printed into the backtrace buffer."
       ;; Don't let these magic variables affect the debugger itself.
       (let ((last-command nil) this-command track-mouse
            (inhibit-trace t)
-           (inhibit-debug-on-entry t)
            unread-command-events
            unread-post-input-method-events
            last-input-event last-command-event last-nonmenu-event
@@ -763,7 +762,8 @@ A call to this function is inserted by `debug-on-entry' to 
cause
 functions to break on entry."
   (if (or inhibit-debug-on-entry debugger-jumping-flag)
       nil
-    (funcall debugger 'debug)))
+    (let ((inhibit-debug-on-entry t))
+      (funcall debugger 'debug))))
 
 ;;;###autoload
 (defun debug-on-entry (function)
diff --git a/lisp/emacs-lisp/eieio-base.el b/lisp/emacs-lisp/eieio-base.el
index 1cc9f89..5b3d902 100644
--- a/lisp/emacs-lisp/eieio-base.el
+++ b/lisp/emacs-lisp/eieio-base.el
@@ -254,25 +254,28 @@ malicious code.
 
 Note: This function recurses when a slot of :type of some object is
 identified, and needing more object creation."
-  (let ((objclass (nth 0 inputlist))
-       ;; (objname (nth 1 inputlist))
-       (slots (nthcdr 2 inputlist))
-       (createslots nil))
-
-    ;; If OBJCLASS is an eieio autoload object, then we need to load it.
-    (eieio-class-un-autoload objclass)
+  (let* ((objclass (nth 0 inputlist))
+        ;; (objname (nth 1 inputlist))
+        (slots (nthcdr 2 inputlist))
+        (createslots nil)
+        (class
+         (progn
+           ;; If OBJCLASS is an eieio autoload object, then we need to
+           ;; load it.
+           (eieio-class-un-autoload objclass)
+           (eieio--class-object objclass))))
 
     (while slots
-      (let ((name (car slots))
+      (let ((initarg (car slots))
            (value (car (cdr slots))))
 
        ;; Make sure that the value proposed for SLOT is valid.
        ;; In addition, strip out quotes, list functions, and update
        ;; object constructors as needed.
        (setq value (eieio-persistent-validate/fix-slot-value
-                    (eieio--class-v objclass) name value))
+                    class (eieio--initarg-to-attribute class initarg) value))
 
-       (push name createslots)
+       (push initarg createslots)
        (push value createslots)
        )
 
@@ -290,16 +293,11 @@ constructor functions are considered valid.
 Second, any text properties will be stripped from strings."
   (cond ((consp proposed-value)
         ;; Lists with something in them need special treatment.
-        (let ((slot-idx (eieio--slot-name-index class slot))
-              (type nil)
-              (classtype nil))
-          (setq slot-idx (- slot-idx
+        (let* ((slot-idx (- (eieio--slot-name-index class slot)
                              (eval-when-compile eieio--object-num-slots)))
-          (setq type (aref (eieio--class-public-type class)
-                           slot-idx))
-
-          (setq classtype (eieio-persistent-slot-type-is-class-p
-                           type))
+                (type (cl--slot-descriptor-type (aref (eieio--class-slots 
class)
+                                                      slot-idx)))
+                (classtype (eieio-persistent-slot-type-is-class-p type)))
 
           (cond ((eq (car proposed-value) 'quote)
                  (car (cdr proposed-value)))
diff --git a/lisp/emacs-lisp/eieio-compat.el b/lisp/emacs-lisp/eieio-compat.el
index ee8e731..0283704 100644
--- a/lisp/emacs-lisp/eieio-compat.el
+++ b/lisp/emacs-lisp/eieio-compat.el
@@ -124,19 +124,22 @@ Summary:
        (defgeneric ,method ,args)
        (eieio--defmethod ',method ',key ',class #',code))))
 
+(defun eieio--generic-static-symbol-specializers (tag)
+  (cl-assert (or (null tag) (eieio--class-p tag)))
+  (when (eieio--class-p tag)
+    (let ((superclasses (eieio--generic-subclass-specializers tag))
+         (specializers ()))
+      (dolist (superclass superclasses)
+       (push superclass specializers)
+       (push `(eieio--static ,(cadr superclass)) specializers))
+      (nreverse specializers))))
+
 (defconst eieio--generic-static-symbol-generalizer
   (cl-generic-make-generalizer
    ;; Give it a slightly higher priority than `subclass' so that the
    ;; interleaved list comes before subclass's non-interleaved list.
    61 (lambda (name) `(and (symbolp ,name) (eieio--class-v ,name)))
-   (lambda (tag)
-     (when (eieio--class-p tag)
-       (let ((superclasses (eieio--generic-subclass-specializers tag))
-             (specializers ()))
-         (dolist (superclass superclasses)
-           (push superclass specializers)
-           (push `(eieio--static ,(cadr superclass)) specializers))
-         (nreverse specializers))))))
+   #'eieio--generic-static-symbol-specializers))
 (defconst eieio--generic-static-object-generalizer
   (cl-generic-make-generalizer
    ;; Give it a slightly higher priority than `class' so that the
@@ -148,7 +151,7 @@ Summary:
           (let ((superclasses (eieio--class-precedence-list tag))
                 (specializers ()))
             (dolist (superclass superclasses)
-              (setq superclass (eieio--class-symbol superclass))
+              (setq superclass (eieio--class-name superclass))
               (push superclass specializers)
               (push `(eieio--static ,superclass) specializers))
             (nreverse specializers))))))
diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el
index 1e226c1..6fd9c14 100644
--- a/lisp/emacs-lisp/eieio-core.el
+++ b/lisp/emacs-lisp/eieio-core.el
@@ -85,9 +85,10 @@ Currently under control of this var:
   ;; Arrange for field access not to bother checking if the access is indeed
   ;; made to an eieio--class object.
   (cl-declaim (optimize (safety 0)))
+
 (cl-defstruct (eieio--class
                (:constructor nil)
-               (:constructor eieio--class-make (symbol &aux (tag 'defclass)))
+               (:constructor eieio--class-make (name &aux (tag 'defclass)))
                (:type vector)
                (:copier nil))
   ;; We use an untagged cl-struct, with our own hand-made tag as first field
@@ -96,30 +97,16 @@ Currently under control of this var:
   ;; predicate for us), but that breaks compatibility with .elc files compiled
   ;; against older versions of EIEIO.
   tag
-  symbol ;; symbol (self-referencing)
-  parent children
-  symbol-hashtable ;; hashtable permitting fast access to variable position 
indexes
-  ;; @todo
-  ;; the word "public" here is leftovers from the very first version.
-  ;; Get rid of it!
-  public-a                        ;; class attribute index
-  public-d                        ;; class attribute defaults index
-  public-doc                      ;; class documentation strings for attributes
-  public-type                     ;; class type for a slot
-  public-custom                   ;; class custom type for a slot
-  public-custom-label             ;; class custom group for a slot
-  public-custom-group             ;; class custom group for a slot
-  public-printer                  ;; printer for a slot
-  protection                      ;; protection for a slot
+  ;; Fields we could inherit from cl--class (if we used a tagged cl-struct):
+  (name nil :type symbol)               ;The type name.
+  (docstring nil :type string)
+  (parents nil :type (or eieio--class (list-of eieio--class)))
+  (slots nil :type (vector cl-slot-descriptor))
+  (index-table nil :type hash-table)
+  ;; Fields specific to EIEIO classes:
+  children
   initarg-tuples                  ;; initarg tuples list
-  class-allocation-a              ;; class allocated attributes
-  class-allocation-doc            ;; class allocated documentation
-  class-allocation-type           ;; class allocated value type
-  class-allocation-custom         ;; class allocated custom descriptor
-  class-allocation-custom-label   ;; class allocated custom descriptor
-  class-allocation-custom-group   ;; class allocated custom group
-  class-allocation-printer        ;; class allocated printer for a slot
-  class-allocation-protection     ;; class allocated protection list
+  (class-slots nil :type eieio--slot)
   class-allocation-values         ;; class allocated value vector
   default-object-cache ;; what a newly created object would look like.
                        ; This will speed up instantiation time as
@@ -142,18 +129,13 @@ Currently under control of this var:
   ;; object/struct in its `symbol-value' slot.
   class-tag)
 
-(eval-and-compile
+(eval-when-compile
   (defconst eieio--object-num-slots
-    (length (get 'eieio--object 'cl-struct-slots))))
+    (length (cl-struct-slot-info 'eieio--object))))
 
-(defsubst eieio--object-class-object (obj)
+(defsubst eieio--object-class (obj)
   (symbol-value (eieio--object-class-tag obj)))
 
-(defsubst eieio--object-class-name (obj)
-  ;; FIXME: Most uses of this function should be changed to use
-  ;; eieio--object-class-object instead!
-  (eieio--class-symbol (eieio--object-class-object obj)))
-
 
 ;;; Important macros used internally in eieio.
 
@@ -189,7 +171,7 @@ CLASS is a symbol."                     ;FIXME: Is it a 
vector or a symbol?
   "Return a Lisp like symbol name for CLASS."
   (setq class (eieio--class-object class))
   (cl-check-type class eieio--class)
-  (eieio--class-symbol class))
+  (eieio--class-name class))
 (define-obsolete-function-alias 'class-name #'eieio-class-name "24.4")
 
 (defalias 'eieio--class-constructor #'identity
@@ -354,10 +336,10 @@ See `defclass' for more information."
                  (mapc (lambda (g) (cl-pushnew g groups :test #'equal))
                        (eieio--class-option c :custom-groups))
                  ;; Save parent in child.
-                  (push c (eieio--class-parent newc))))))
+                  (push c (eieio--class-parents newc))))))
          ;; Reverse the list of our parents so that they are prioritized in
          ;; the same order as specified in the code.
-         (cl-callf nreverse (eieio--class-parent newc)))
+         (cl-callf nreverse (eieio--class-parents newc)))
       ;; If there is nothing to loop over, then inherit from the
       ;; default superclass.
       (unless (eq cname 'eieio-default-superclass)
@@ -366,7 +348,7 @@ See `defclass' for more information."
         ;; save new child in parent
         (cl-pushnew cname (eieio--class-children eieio-default-superclass))
         ;; save parent in child
-        (setf (eieio--class-parent newc) (list eieio-default-superclass))))
+        (setf (eieio--class-parents newc) (list eieio-default-superclass))))
 
     ;; turn this into a usable self-pointing symbol;  FIXME: Why?
     (when eieio-backward-compatibility
@@ -442,62 +424,70 @@ See `defclass' for more information."
                    (make-obsolete-variable
                     initarg (format "use '%s instead" initarg) "25.1"))))
 
-       ;; The customgroup should be a list of symbols
-       (cond ((null customg)
+       ;; The customgroup should be a list of symbols.
+       (cond ((and (null customg) custom)
               (setq customg '(default)))
              ((not (listp customg))
               (setq customg (list customg))))
-       ;; The customgroup better be a symbol, or list of symbols.
-       (mapc (lambda (cg)
-               (if (not (symbolp cg))
-                   (signal 'invalid-slot-type (list :group cg))))
-               customg)
+       ;; The customgroup better be a list of symbols.
+       (dolist (cg customg)
+          (unless (symbolp cg)
+            (signal 'invalid-slot-type (list :group cg))))
 
        ;; First up, add this slot into our new class.
-       (eieio--add-new-slot newc name init docstr type custom label customg 
printer
-                            prot initarg alloc 'defaultoverride skip-nil)
+       (eieio--add-new-slot
+         newc (cl--make-slot-descriptor
+               name init type
+               `(,@(if docstr `((:documentation . ,docstr)))
+                 ,@(if custom  `((:custom . ,custom)))
+                 ,@(if label   `((:label . ,label)))
+                 ,@(if customg `((:group . ,customg)))
+                 ,@(if printer `((:printer . ,printer)))
+                 ,@(if prot    `((:protection . ,prot)))))
+         initarg alloc 'defaultoverride skip-nil)
 
        ;; We need to id the group, and store them in a group list attribute.
        (dolist (cg customg)
-          (cl-pushnew cg groups :test 'equal))
+          (cl-pushnew cg groups :test #'equal))
        ))
 
     ;; Now that everything has been loaded up, all our lists are backwards!
-    ;; Fix that up now.
-    (cl-callf nreverse (eieio--class-public-a newc))
-    (cl-callf nreverse (eieio--class-public-d newc))
-    (cl-callf nreverse (eieio--class-public-doc newc))
-    (cl-callf (lambda (types) (apply #'vector (nreverse types)))
-        (eieio--class-public-type newc))
-    (cl-callf nreverse (eieio--class-public-custom newc))
-    (cl-callf nreverse (eieio--class-public-custom-label newc))
-    (cl-callf nreverse (eieio--class-public-custom-group newc))
-    (cl-callf nreverse (eieio--class-public-printer newc))
-    (cl-callf nreverse (eieio--class-protection newc))
+    ;; Fix that up now and then them into vectors.
+    (cl-callf (lambda (slots) (apply #'vector (nreverse slots)))
+        (eieio--class-slots newc))
     (cl-callf nreverse (eieio--class-initarg-tuples newc))
 
     ;; The storage for class-class-allocation-type needs to be turned into
     ;; a vector now.
-    (cl-callf (lambda (cat) (apply #'vector cat))
-        (eieio--class-class-allocation-type newc))
-
-    ;; Also, take class allocated values, and vectorize them for speed.
-    (cl-callf (lambda (cavs) (apply #'vector cavs))
-        (eieio--class-class-allocation-values newc))
+    (cl-callf (lambda (slots) (apply #'vector slots))
+        (eieio--class-class-slots newc))
+
+    ;; Also, setup the class allocated values.
+    (let* ((slots (eieio--class-class-slots newc))
+           (n (length slots))
+           (v (make-vector n nil)))
+      (dotimes (i n)
+        (setf (aref v i) (eieio-default-eval-maybe
+                          (cl--slot-descriptor-initform (aref slots i)))))
+      (setf (eieio--class-class-allocation-values newc) v))
 
     ;; Attach slot symbols into a hashtable, and store the index of
     ;; this slot as the value this table.
-    (let* ((cnt 0)
+    (let* ((slots (eieio--class-slots newc))
+          ;; (cslots (eieio--class-class-slots newc))
           (oa (make-hash-table :test #'eq)))
-      (dolist (pubsym (eieio--class-public-a newc))
-        (setf (gethash pubsym oa) cnt)
-        (setq cnt (1+ cnt)))
-      (setf (eieio--class-symbol-hashtable newc) oa))
+      ;; (dotimes (cnt (length cslots))
+      ;;   (setf (gethash (cl--slot-descriptor-name (aref cslots cnt)) oa) (- 
-1 cnt)))
+      (dotimes (cnt (length slots))
+        (setf (gethash (cl--slot-descriptor-name (aref slots cnt)) oa) cnt))
+      (setf (eieio--class-index-table newc) oa))
 
     ;; Set up a specialized doc string.
     ;; Use stored value since it is calculated in a non-trivial way
-    (put cname 'variable-documentation
-        (eieio--class-option-assoc options :documentation))
+    (let ((docstring (eieio--class-option-assoc options :documentation)))
+      (setf (eieio--class-docstring newc) docstring)
+      (when eieio-backward-compatibility
+        (put cname 'variable-documentation docstring)))
 
     ;; Save the file location where this class is defined.
     (add-to-list 'current-load-list `(eieio-defclass . ,cname))
@@ -514,10 +504,10 @@ See `defclass' for more information."
 
     ;; if this is a superclass, clear out parent (which was set to the
     ;; default superclass eieio-default-superclass)
-    (if clearparent (setf (eieio--class-parent newc) nil))
+    (if clearparent (setf (eieio--class-parents newc) nil))
 
     ;; Create the cached default object.
-    (let ((cache (make-vector (+ (length (eieio--class-public-a newc))
+    (let ((cache (make-vector (+ (length (eieio--class-slots newc))
                                  (eval-when-compile eieio--object-num-slots))
                               nil))
           ;; We don't strictly speaking need to use a symbol, but the old
@@ -544,239 +534,133 @@ See `defclass' for more information."
   "Whether the default value VAL should be evaluated for use."
   (and (consp val) (symbolp (car val)) (fboundp (car val))))
 
-(defun eieio--perform-slot-validation-for-default (slot spec value skipnil)
-  "For SLOT, signal if SPEC does not match VALUE.
-If SKIPNIL is non-nil, then if VALUE is nil return t instead."
-  (if (not (or (eieio-eval-default-p value) ;FIXME: Why?
-               eieio-skip-typecheck
-               (and skipnil (null value))
-               (eieio--perform-slot-validation spec value)))
-      (signal 'invalid-slot-type (list slot spec value))))
-
-(defun eieio--add-new-slot (newc a d doc type cust label custg print prot init 
alloc
+(defun eieio--perform-slot-validation-for-default (slot skipnil)
+  "For SLOT, signal if its type does not match its default value.
+If SKIPNIL is non-nil, then if default value is nil return t instead."
+  (let ((value (cl--slot-descriptor-initform slot))
+        (spec (cl--slot-descriptor-type slot)))
+    (if (not (or (eieio-eval-default-p value) ;FIXME: Why?
+                 eieio-skip-typecheck
+                 (and skipnil (null value))
+                 (eieio--perform-slot-validation spec value)))
+        (signal 'invalid-slot-type (list (cl--slot-descriptor-name slot) spec 
value)))))
+
+(defun eieio--slot-override (old new skipnil)
+  (cl-assert (eq (cl--slot-descriptor-name old) (cl--slot-descriptor-name 
new)))
+  ;; There is a match, and we must override the old value.
+  (let* ((a (cl--slot-descriptor-name old))
+         (tp (cl--slot-descriptor-type old))
+         (d (cl--slot-descriptor-initform new))
+         (type (cl--slot-descriptor-type new))
+         (oprops (cl--slot-descriptor-props old))
+         (nprops (cl--slot-descriptor-props new))
+         (custg (alist-get :group nprops)))
+    ;; If type is passed in, is it the same?
+    (if (not (eq type t))
+        (if (not (equal type tp))
+            (error
+             "Child slot type `%s' does not match inherited type `%s' for `%s'"
+             type tp a))
+      (setf (cl--slot-descriptor-type new) tp))
+    ;; If we have a repeat, only update the initarg...
+    (unless (eq d eieio-unbound)
+      (eieio--perform-slot-validation-for-default new skipnil)
+      (setf (cl--slot-descriptor-initform old) d))
+
+    ;; PLN Tue Jun 26 11:57:06 2007 : The protection is
+    ;; checked and SHOULD match the superclass
+    ;; protection. Otherwise an error is thrown. However
+    ;; I wonder if a more flexible schedule might be
+    ;; implemented.
+    ;;
+    ;; EML - We used to have (if prot... here,
+    ;;       but a prot of 'nil means public.
+    ;;
+    (let ((super-prot (alist-get :protection oprops))
+          (prot (alist-get :protection nprops)))
+      (if (not (eq prot super-prot))
+          (error "Child slot protection `%s' does not match inherited 
protection `%s' for `%s'"
+                 prot super-prot a)))
+    ;; End original PLN
+
+    ;; PLN Tue Jun 26 11:57:06 2007 :
+    ;; Do a non redundant combination of ancient custom
+    ;; groups and new ones.
+    (when custg
+      (let* ((list1 (alist-get :group oprops)))
+        (dolist (elt custg)
+          (unless (memq elt list1)
+            (push elt list1)))
+        (setf (alist-get :group (cl--slot-descriptor-props old)) list1)))
+    ;;  End PLN
+
+    ;;  PLN Mon Jun 25 22:44:34 2007 : If a new cust is
+    ;;  set, simply replaces the old one.
+    (dolist (prop '(:custom :label :documentation :printer))
+      (when (alist-get prop (cl--slot-descriptor-props new))
+        (setf (alist-get prop (cl--slot-descriptor-props old))
+              (alist-get prop (cl--slot-descriptor-props new))))
+
+      )  ))
+
+(defun eieio--add-new-slot (newc slot init alloc
                                 &optional defaultoverride skipnil)
-  "Add into NEWC attribute A.
-If A already exists in NEWC, then do nothing.  If it doesn't exist,
-then also add in D (default), DOC, TYPE, CUST, LABEL, CUSTG, PRINT, PROT, and 
INIT arg.
+  "Add into NEWC attribute SLOT.
+If a slot of that name already exists in NEWC, then do nothing.  If it doesn't 
exist,
+INIT is the initarg, if any.
 Argument ALLOC specifies if the slot is allocated per instance, or per class.
 If optional DEFAULTOVERRIDE is non-nil, then if A exists in NEWC,
 we must override its value for a default.
 Optional argument SKIPNIL indicates if type checking should be skipped
 if default value is nil."
   ;; Make sure we duplicate those items that are sequences.
+  (let* ((a (cl--slot-descriptor-name slot))
+         (d (cl--slot-descriptor-initform slot))
+         (old (car (cl-member a (eieio--class-slots newc)
+                              :key #'cl--slot-descriptor-name)))
+         (cold (car (cl-member a (eieio--class-class-slots newc)
+                               :key #'cl--slot-descriptor-name))))
   (condition-case nil
       (if (sequencep d) (setq d (copy-sequence d)))
-    ;; This copy can fail on a cons cell with a non-cons in the cdr.  Let's 
skip it if it doesn't work.
+    ;; This copy can fail on a cons cell with a non-cons in the cdr.  Let's
+    ;; skip it if it doesn't work.
     (error nil))
-  (if (sequencep type) (setq type (copy-sequence type)))
-  (if (sequencep cust) (setq cust (copy-sequence cust)))
-  (if (sequencep custg) (setq custg (copy-sequence custg)))
+  ;; (if (sequencep type) (setq type (copy-sequence type)))
+  ;; (if (sequencep cust) (setq cust (copy-sequence cust)))
+  ;; (if (sequencep custg) (setq custg (copy-sequence custg)))
 
   ;; To prevent override information w/out specification of storage,
   ;; we need to do this little hack.
-  (if (member a (eieio--class-class-allocation-a newc)) (setq alloc :class))
+  (if cold (setq alloc :class))
 
-  (if (or (not alloc) (and (symbolp alloc) (eq alloc :instance)))
+  (if (memq alloc '(nil :instance))
       ;; In this case, we modify the INSTANCE version of a given slot.
-
       (progn
-
-       ;; Only add this element if it is so-far unique
-       (if (not (member a (eieio--class-public-a newc)))
-           (progn
-             (eieio--perform-slot-validation-for-default a type d skipnil)
-             (push a (eieio--class-public-a newc))
-             (push d (eieio--class-public-d newc))
-             (push doc (eieio--class-public-doc newc))
-             (push type (eieio--class-public-type newc))
-             (push cust (eieio--class-public-custom newc))
-             (push label (eieio--class-public-custom-label newc))
-             (push custg (eieio--class-public-custom-group newc))
-             (push print (eieio--class-public-printer newc))
-             (push prot (eieio--class-protection newc))
-             (setf (eieio--class-initarg-tuples newc) (cons (cons init a) 
(eieio--class-initarg-tuples newc)))
-             )
-         ;; When defaultoverride is true, we are usually adding new local
-         ;; attributes which must override the default value of any slot
-         ;; passed in by one of the parent classes.
-         (when defaultoverride
-           ;; There is a match, and we must override the old value.
-           (let* ((ca (eieio--class-public-a newc))
-                  (np (member a ca))
-                  (num (- (length ca) (length np)))
-                  (dp (if np (nthcdr num (eieio--class-public-d newc))
-                        nil))
-                  (tp (if np (nth num (eieio--class-public-type newc))))
-                  )
-             (if (not np)
-                 (error "EIEIO internal error overriding default value for %s"
-                        a)
-               ;; If type is passed in, is it the same?
-               (if (not (eq type t))
-                   (if (not (equal type tp))
-                       (error
-                        "Child slot type `%s' does not match inherited type 
`%s' for `%s'"
-                        type tp a)))
-               ;; If we have a repeat, only update the initarg...
-               (unless (eq d eieio-unbound)
-                 (eieio--perform-slot-validation-for-default a tp d skipnil)
-                 (setcar dp d))
-               ;; If we have a new initarg, check for it.
-               (when init
-                 (let* ((inits (eieio--class-initarg-tuples newc))
-                        (inita (rassq a inits)))
-                   ;; Replace the CAR of the associate INITA.
-                   ;;(message "Initarg: %S replace %s" inita init)
-                   (setcar inita init)
-                   ))
-
-               ;; PLN Tue Jun 26 11:57:06 2007 : The protection is
-               ;; checked and SHOULD match the superclass
-               ;; protection. Otherwise an error is thrown. However
-               ;; I wonder if a more flexible schedule might be
-               ;; implemented.
-               ;;
-               ;; EML - We used to have (if prot... here,
-               ;;       but a prot of 'nil means public.
-               ;;
-               (let ((super-prot (nth num (eieio--class-protection newc)))
-                     )
-                 (if (not (eq prot super-prot))
-                     (error "Child slot protection `%s' does not match 
inherited protection `%s' for `%s'"
-                            prot super-prot a)))
-               ;; End original PLN
-
-               ;; PLN Tue Jun 26 11:57:06 2007 :
-               ;; Do a non redundant combination of ancient custom
-               ;; groups and new ones.
-               (when custg
-                 (let* ((groups
-                         (nthcdr num (eieio--class-public-custom-group newc)))
-                        (list1 (car groups))
-                        (list2 (if (listp custg) custg (list custg))))
-                   (if (< (length list1) (length list2))
-                       (setq list1 (prog1 list2 (setq list2 list1))))
-                   (dolist (elt list2)
-                     (unless (memq elt list1)
-                       (push elt list1)))
-                   (setcar groups list1)))
-               ;;  End PLN
-
-               ;;  PLN Mon Jun 25 22:44:34 2007 : If a new cust is
-               ;;  set, simply replaces the old one.
-               (when cust
-                 ;; (message "Custom type redefined to %s" cust)
-                 (setcar (nthcdr num (eieio--class-public-custom newc)) cust))
-
-               ;; If a new label is specified, it simply replaces
-               ;; the old one.
-               (when label
-                 ;; (message "Custom label redefined to %s" label)
-                 (setcar (nthcdr num (eieio--class-public-custom-label newc)) 
label))
-               ;;  End PLN
-
-               ;; PLN Sat Jun 30 17:24:42 2007 : when a new
-               ;; doc is specified, simply replaces the old one.
-               (when doc
-                 ;;(message "Documentation redefined to %s" doc)
-                 (setcar (nthcdr num (eieio--class-public-doc newc))
-                         doc))
-               ;; End PLN
-
-               ;; If a new printer is specified, it simply replaces
-               ;; the old one.
-               (when print
-                 ;; (message "printer redefined to %s" print)
-                 (setcar (nthcdr num (eieio--class-public-printer newc)) 
print))
-
-               )))
-         ))
+        ;; Only add this element if it is so-far unique
+        (if (not old)
+            (progn
+              (eieio--perform-slot-validation-for-default slot skipnil)
+              (push slot (eieio--class-slots newc))
+              )
+          ;; When defaultoverride is true, we are usually adding new local
+          ;; attributes which must override the default value of any slot
+          ;; passed in by one of the parent classes.
+          (when defaultoverride
+            (eieio--slot-override old slot skipnil)))
+        (when init
+          (cl-pushnew (cons init a) (eieio--class-initarg-tuples newc)
+                      :test #'equal)))
 
     ;; CLASS ALLOCATED SLOTS
-    (let ((value (eieio-default-eval-maybe d)))
-      (if (not (member a (eieio--class-class-allocation-a newc)))
-         (progn
-           (eieio--perform-slot-validation-for-default a type value skipnil)
-           ;; Here we have found a :class version of a slot.  This
-           ;; requires a very different approach.
-           (push a (eieio--class-class-allocation-a newc))
-           (push doc (eieio--class-class-allocation-doc newc))
-           (push type (eieio--class-class-allocation-type newc))
-           (push cust (eieio--class-class-allocation-custom newc))
-           (push label (eieio--class-class-allocation-custom-label newc))
-           (push custg (eieio--class-class-allocation-custom-group newc))
-           (push prot (eieio--class-class-allocation-protection newc))
-           ;; Default value is stored in the 'values section, since new objects
-           ;; can't initialize from this element.
-           (push value (eieio--class-class-allocation-values newc)))
-       (when defaultoverride
-         ;; There is a match, and we must override the old value.
-         (let* ((ca (eieio--class-class-allocation-a newc))
-                (np (member a ca))
-                (num (- (length ca) (length np)))
-                (dp (if np
-                        (nthcdr num
-                                (eieio--class-class-allocation-values newc))
-                      nil))
-                (tp (if np (nth num (eieio--class-class-allocation-type newc))
-                      nil)))
-           (if (not np)
-               (error "EIEIO internal error overriding default value for %s"
-                      a)
-             ;; If type is passed in, is it the same?
-             (if (not (eq type t))
-                 (if (not (equal type tp))
-                     (error
-                      "Child slot type `%s' does not match inherited type `%s' 
for `%s'"
-                      type tp a)))
-             ;; EML - Note: the only reason to override a class bound slot
-             ;;       is to change the default, so allow unbound in.
-
-             ;; If we have a repeat, only update the value...
-             (eieio--perform-slot-validation-for-default a tp value skipnil)
-             (setcar dp value))
-
-           ;; PLN Tue Jun 26 11:57:06 2007 : The protection is
-           ;; checked and SHOULD match the superclass
-           ;; protection. Otherwise an error is thrown. However
-           ;; I wonder if a more flexible schedule might be
-           ;; implemented.
-           (let ((super-prot
-                  (car (nthcdr num (eieio--class-class-allocation-protection 
newc)))))
-             (if (not (eq prot super-prot))
-                 (error "Child slot protection `%s' does not match inherited 
protection `%s' for `%s'"
-                        prot super-prot a)))
-           ;; Do a non redundant combination of ancient custom groups
-           ;; and new ones.
-           (when custg
-             (let* ((groups
-                     (nthcdr num (eieio--class-class-allocation-custom-group 
newc)))
-                    (list1 (car groups))
-                    (list2 (if (listp custg) custg (list custg))))
-               (if (< (length list1) (length list2))
-                   (setq list1 (prog1 list2 (setq list2 list1))))
-               (dolist (elt list2)
-                 (unless (memq elt list1)
-                   (push elt list1)))
-               (setcar groups list1)))
-
-           ;; PLN Sat Jun 30 17:24:42 2007 : when a new
-           ;; doc is specified, simply replaces the old one.
-           (when doc
-             ;;(message "Documentation redefined to %s" doc)
-             (setcar (nthcdr num (eieio--class-class-allocation-doc newc))
-                     doc))
-           ;; End PLN
-
-           ;; If a new printer is specified, it simply replaces
-           ;; the old one.
-           (when print
-             ;; (message "printer redefined to %s" print)
-             (setcar (nthcdr num (eieio--class-class-allocation-printer newc)) 
print))
-
-           ))
-       ))
-    ))
+    (if (not cold)
+        (progn
+          (eieio--perform-slot-validation-for-default slot skipnil)
+          ;; Here we have found a :class version of a slot.  This
+          ;; requires a very different approach.
+          (push slot (eieio--class-class-slots newc)))
+      (when defaultoverride
+        ;; There is a match, and we must override the old value.
+        (eieio--slot-override cold slot skipnil))))))
 
 (defun eieio-copy-parents-into-subclass (newc)
   "Copy into NEWC the slots of PARENTS.
@@ -784,63 +668,22 @@ Follow the rules of not overwriting early parents when 
applying to
 the new child class."
   (let ((sn (eieio--class-option-assoc (eieio--class-options newc)
                                        :allow-nil-initform)))
-    (dolist (pcv (eieio--class-parent newc))
+    (dolist (pcv (eieio--class-parents newc))
       ;; First, duplicate all the slots of the parent.
-      (let ((pa (eieio--class-public-a pcv))
-            (pd (eieio--class-public-d pcv))
-            (pdoc (eieio--class-public-doc pcv))
-            (ptype (eieio--class-public-type pcv))
-            (pcust (eieio--class-public-custom pcv))
-            (plabel (eieio--class-public-custom-label pcv))
-            (pcustg (eieio--class-public-custom-group pcv))
-            (printer (eieio--class-public-printer pcv))
-            (pprot (eieio--class-protection pcv))
-            (pinit (eieio--class-initarg-tuples pcv))
-            (i 0))
-        (while pa
-          (eieio--add-new-slot newc
-                               (car pa) (car pd) (car pdoc) (aref ptype i)
-                               (car pcust) (car plabel) (car pcustg)
-                               (car printer)
-                               (car pprot) (car-safe (car pinit)) nil nil sn)
+      (let ((pslots (eieio--class-slots pcv))
+            (pinit (eieio--class-initarg-tuples pcv)))
+        (dotimes (i (length pslots))
+          (eieio--add-new-slot newc (cl--copy-slot-descriptor (aref pslots i))
+                               (car-safe (car pinit)) nil nil sn)
           ;; Increment each value.
-          (setq pa (cdr pa)
-                pd (cdr pd)
-                pdoc (cdr pdoc)
-                i (1+ i)
-                pcust (cdr pcust)
-                plabel (cdr plabel)
-                pcustg (cdr pcustg)
-                printer (cdr printer)
-                pprot (cdr pprot)
-                pinit (cdr pinit))
+          (setq pinit (cdr pinit))
           )) ;; while/let
       ;; Now duplicate all the class alloc slots.
-      (let ((pa (eieio--class-class-allocation-a pcv))
-            (pdoc (eieio--class-class-allocation-doc pcv))
-            (ptype (eieio--class-class-allocation-type pcv))
-            (pcust (eieio--class-class-allocation-custom pcv))
-            (plabel (eieio--class-class-allocation-custom-label pcv))
-            (pcustg (eieio--class-class-allocation-custom-group pcv))
-            (printer (eieio--class-class-allocation-printer pcv))
-            (pprot (eieio--class-class-allocation-protection pcv))
-            (pval (eieio--class-class-allocation-values pcv))
-            (i 0))
-        (while pa
-          (eieio--add-new-slot newc
-                               (car pa) (aref pval i) (car pdoc) (aref ptype i)
-                               (car pcust) (car plabel) (car pcustg)
-                               (car printer)
-                               (car pprot) nil :class sn)
-          ;; Increment each value.
-          (setq pa (cdr pa)
-                pdoc (cdr pdoc)
-                pcust (cdr pcust)
-                plabel (cdr plabel)
-                pcustg (cdr pcustg)
-                printer (cdr printer)
-                pprot (cdr pprot)
-                i (1+ i))
+      (let ((pcslots (eieio--class-class-slots pcv)))
+        (dotimes (i (length pcslots))
+          (eieio--add-new-slot newc (cl--copy-slot-descriptor
+                                     (aref pcslots i))
+                               nil :class sn)
           )))))
 
 
@@ -865,10 +708,11 @@ an error."
       nil
     ;; Trim off object IDX junk added in for the object index.
     (setq slot-idx (- slot-idx (eval-when-compile eieio--object-num-slots)))
-    (let ((st (aref (eieio--class-public-type class) slot-idx)))
+    (let ((st (cl--slot-descriptor-type (aref (eieio--class-slots class)
+                                              slot-idx))))
       (if (not (eieio--perform-slot-validation st value))
          (signal 'invalid-slot-type
-                  (list (eieio--class-symbol class) slot st value))))))
+                  (list (eieio--class-name class) slot st value))))))
 
 (defun eieio--validate-class-slot-value (class slot-idx value slot)
   "Make sure that for CLASS referencing SLOT-IDX, VALUE is valid.
@@ -877,11 +721,11 @@ SLOT is the slot that is being checked, and is only used 
when throwing
 an error."
   (if eieio-skip-typecheck
       nil
-    (let ((st (aref (eieio--class-class-allocation-type class)
-                   slot-idx)))
+    (let ((st (cl--slot-descriptor-type (aref (eieio--class-class-slots class)
+                                              slot-idx))))
       (if (not (eieio--perform-slot-validation st value))
          (signal 'invalid-slot-type
-                  (list (eieio--class-symbol class) slot st value))))))
+                  (list (eieio--class-name class) slot st value))))))
 
 (defun eieio-barf-if-slot-unbound (value instance slotname fn)
   "Throw a signal if VALUE is a representation of an UNBOUND slot.
@@ -889,7 +733,7 @@ INSTANCE is the object being referenced.  SLOTNAME is the 
offending
 slot.  If the slot is ok, return VALUE.
 Argument FN is the function calling this verifier."
   (if (and (eq value eieio-unbound) (not eieio-skip-typecheck))
-      (slot-unbound instance (eieio--object-class-object instance) slotname fn)
+      (slot-unbound instance (eieio--object-class instance) slotname fn)
     value))
 
 
@@ -904,7 +748,7 @@ Argument FN is the function calling this verifier."
                        (let ((c (eieio--class-v obj)))
                          (if (eieio--class-p c) (eieio-class-un-autoload obj))
                          c))
-                      (t (eieio--object-class-object obj))))
+                      (t (eieio--object-class obj))))
         (c (eieio--slot-name-index class slot)))
     (if (not c)
        ;; It might be missing because it is a :class allocated slot.
@@ -928,7 +772,7 @@ Fills in OBJ's SLOT with its default value."
   (cl-check-type obj (or eieio-object class))
   (cl-check-type slot symbol)
   (let* ((cl (cond ((symbolp obj) (eieio--class-v obj))
-                   (t (eieio--object-class-object obj))))
+                   (t (eieio--object-class obj))))
         (c (eieio--slot-name-index cl slot)))
     (if (not c)
        ;; It might be missing because it is a :class allocated slot.
@@ -942,10 +786,11 @@ Fills in OBJ's SLOT with its default value."
          ;;(signal 'invalid-slot-name (list (class-name cl) slot))
          )
       (eieio-barf-if-slot-unbound
-       (let ((val (nth (- c (eval-when-compile eieio--object-num-slots))
-                       (eieio--class-public-d cl))))
+       (let ((val (cl--slot-descriptor-initform
+                   (aref (eieio--class-slots cl)
+                         (- c (eval-when-compile eieio--object-num-slots))))))
         (eieio-default-eval-maybe val))
-       obj (eieio--class-symbol cl) 'oref-default))))
+       obj (eieio--class-name cl) 'oref-default))))
 
 (defun eieio-default-eval-maybe (val)
   "Check VAL, and return what `oref-default' would provide."
@@ -966,7 +811,7 @@ Fills in OBJ's SLOT with its default value."
 Fills in OBJ's SLOT with VALUE."
   (cl-check-type obj eieio-object)
   (cl-check-type slot symbol)
-  (let* ((class (eieio--object-class-object obj))
+  (let* ((class (eieio--object-class obj))
          (c (eieio--slot-name-index class slot)))
     (if (not c)
        ;; It might be missing because it is a :class allocated slot.
@@ -1001,13 +846,24 @@ Fills in the default value in CLASS' in SLOT with VALUE."
               (eieio--validate-class-slot-value class c value slot)
               (aset (eieio--class-class-allocation-values class) c
                     value))
-          (signal 'invalid-slot-name (list (eieio--class-symbol class) slot)))
+          (signal 'invalid-slot-name (list (eieio--class-name class) slot)))
+      ;; `oset-default' on an instance-allocated slot is allowed by EIEIO but
+      ;; not by CLOS and is mildly inconsistent with the :initform thingy, so
+      ;; it'd be nice to get of it.  This said, it is/was used at one place by
+      ;; gnus/registry.el, so it might be used elsewhere as well, so let's
+      ;; keep it for now.
+      ;; FIXME: Generate a compile-time warning for it!
+      ;; (error "Can't `oset-default' an instance-allocated slot: %S of %S"
+      ;;        slot class)
       (eieio--validate-slot-value class c value slot)
       ;; Set this into the storage for defaults.
       (if (eieio-eval-default-p value)
           (error "Can't set default to a sexp that gets evaluated again"))
-      (setcar (nthcdr (- c (eval-when-compile eieio--object-num-slots))
-                      (eieio--class-public-d class))
+      (setf (cl--slot-descriptor-initform
+             ;; FIXME: Apparently we set it both in `slots' and in
+             ;; `object-cache', which seems redundant.
+             (aref (eieio--class-slots class)
+                   (- c (eval-when-compile eieio--object-num-slots))))
               value)
       ;; Take the value, and put it into our cache object.
       (eieio-oset (eieio--class-default-object-cache class)
@@ -1023,11 +879,16 @@ The slot is a symbol which is installed in CLASS by the 
`defclass' call.
 If SLOT is the value created with :initarg instead,
 reverse-lookup that name, and recurse with the associated slot value."
   ;; Removed checks to outside this call
-  (let* ((fsi (gethash slot (eieio--class-symbol-hashtable class))))
+  (let* ((fsi (gethash slot (eieio--class-index-table class))))
     (if (integerp fsi)
         (+ (eval-when-compile eieio--object-num-slots) fsi)
       (let ((fn (eieio--initarg-to-attribute class slot)))
-       (if fn (eieio--slot-name-index class fn) nil)))))
+       (if fn
+            ;; Accessing a slot via its :initarg is accepted by EIEIO
+            ;; (but not CLOS) but is a bad idea (for one: it's slower).
+            ;; FIXME: We should emit a compile-time warning when this happens!
+            (eieio--slot-name-index class fn)
+          nil)))))
 
 (defun eieio--class-slot-name-index (class slot)
   "In CLASS find the index of the named SLOT.
@@ -1036,13 +897,12 @@ call.  If SLOT is the value created with :initarg 
instead,
 reverse-lookup that name, and recurse with the associated slot value."
   ;; This will happen less often, and with fewer slots.  Do this the
   ;; storage cheap way.
-  (let* ((a (eieio--class-class-allocation-a class))
-        (l1 (length a))
-        (af (memq slot a))
-        (l2 (length af)))
-    ;; Slot # is length of the total list, minus the remaining list of
-    ;; the found slot.
-    (if af (- l1 l2))))
+  (let ((index nil)
+        (slots (eieio--class-class-slots class)))
+    (dotimes (i (length slots))
+      (if (eq slot (cl--slot-descriptor-name (aref slots i)))
+          (setq index i)))
+    index))
 
 ;;;
 ;; Way to assign slots based on a list.  Used for constructors, or
@@ -1053,12 +913,12 @@ reverse-lookup that name, and recurse with the 
associated slot value."
 If SET-ALL is non-nil, then when a default is nil, that value is
 reset.  If SET-ALL is nil, the slots are only reset if the default is
 not nil."
-  (let ((pub (eieio--class-public-a (eieio--object-class-object obj))))
-    (while pub
-      (let ((df (eieio-oref-default obj (car pub))))
+  (let ((slots (eieio--class-slots (eieio--object-class obj))))
+    (dotimes (i (length slots))
+      (let* ((name (cl--slot-descriptor-name (aref slots i)))
+             (df (eieio-oref-default obj name)))
         (if (or df set-all)
-            (eieio-oset obj (car pub) df)))
-      (setq pub (cdr pub)))))
+            (eieio-oset obj name df))))))
 
 (defun eieio--initarg-to-attribute (class initarg)
   "For CLASS, convert INITARG to the actual attribute name.
@@ -1085,11 +945,8 @@ need be... May remove that later...)"
 (defun eieio--c3-merge-lists (reversed-partial-result remaining-inputs)
   "Merge REVERSED-PARTIAL-RESULT REMAINING-INPUTS in a consistent order, if 
possible.
 If a consistent order does not exist, signal an error."
-  (if (let ((tail remaining-inputs)
-           (found nil))
-       (while (and tail (not found))
-         (setq found (car tail) tail (cdr tail)))
-       (not found))
+  (setq remaining-inputs (delq nil remaining-inputs))
+  (if (null remaining-inputs)
       ;; If all remaining inputs are empty lists, we are done.
       (nreverse reversed-partial-result)
     ;; Otherwise, we try to find the next element of the result. This
@@ -1100,9 +957,8 @@ If a consistent order does not exist, signal an error."
           (tail remaining-inputs)
           (next (progn
                   (while (and tail (not found))
-                    (setq found (and (car tail)
-                                     (eieio--c3-candidate (caar tail)
-                                                           remaining-inputs))
+                    (setq found (eieio--c3-candidate (caar tail)
+                                                      remaining-inputs)
                           tail (cdr tail)))
                   found)))
       (if next
@@ -1116,9 +972,13 @@ If a consistent order does not exist, signal an error."
        ;; The graph is inconsistent, give up
        (signal 'inconsistent-class-hierarchy (list remaining-inputs))))))
 
+(defsubst eieio--class/struct-parents (class)
+  (or (eieio--class-parents class)
+      `(,eieio-default-superclass)))
+
 (defun eieio--class-precedence-c3 (class)
   "Return all parents of CLASS in c3 order."
-  (let ((parents (eieio--class-parent (eieio--class-v class))))
+  (let ((parents (eieio--class-parents (eieio--class-v class))))
     (eieio--c3-merge-lists
      (list class)
      (append
@@ -1132,7 +992,7 @@ If a consistent order does not exist, signal an error."
 
 (defun eieio--class-precedence-dfs (class)
   "Return all parents of CLASS in depth-first order."
-  (let* ((parents (eieio--class-parent class))
+  (let* ((parents (eieio--class-parents class))
         (classes (copy-sequence
                   (apply #'append
                          (list class)
@@ -1155,15 +1015,13 @@ If a consistent order does not exist, signal an error."
 (defun eieio--class-precedence-bfs (class)
   "Return all parents of CLASS in breadth-first order."
   (let* ((result)
-         (queue (or (eieio--class-parent class)
-                    `(,eieio-default-superclass))))
+         (queue (eieio--class/struct-parents class)))
     (while queue
       (let ((head (pop queue)))
        (unless (member head result)
          (push head result)
          (unless (eq head eieio-default-superclass)
-           (setq queue (append queue (or (eieio--class-parent head)
-                                         `(,eieio-default-superclass))))))))
+           (setq queue (append queue (eieio--class/struct-parents head)))))))
     (cons class (nreverse result)))
   )
 
@@ -1177,7 +1035,7 @@ method invocation orders of the involved classes."
   (if (or (null class) (eq class eieio-default-superclass))
       nil
     (unless (eieio--class-default-object-cache class)
-      (eieio-class-un-autoload (eieio--class-symbol class)))
+      (eieio-class-un-autoload (eieio--class-name class)))
     (cl-case (eieio--class-method-invocation-order class)
       (:depth-first
        (eieio--class-precedence-dfs class))
@@ -1211,7 +1069,7 @@ method invocation orders of the involved classes."
    50 #'cl--generic-struct-tag
    (lambda (tag)
         (and (symbolp tag) (boundp tag) (eieio--class-p (symbol-value tag))
-             (mapcar #'eieio--class-symbol
+             (mapcar #'eieio--class-name
                      (eieio--class-precedence-list (symbol-value tag)))))))
 
 (cl-defmethod cl-generic-generalizers :extra "class" (specializer)
@@ -1235,7 +1093,7 @@ method invocation orders of the involved classes."
 (defun eieio--generic-subclass-specializers (tag)
   (when (eieio--class-p tag)
     (mapcar (lambda (class)
-              `(subclass ,(eieio--class-symbol class)))
+              `(subclass ,(eieio--class-name class)))
             (eieio--class-precedence-list tag))))
 
 (defconst eieio--generic-subclass-generalizer
@@ -1247,7 +1105,7 @@ method invocation orders of the involved classes."
   (list eieio--generic-subclass-generalizer))
 
 
-;;;### (autoloads nil "eieio-compat" "eieio-compat.el" 
"25a66814a400e7dea16bf0f3bfe245ed")
+;;;### (autoloads nil "eieio-compat" "eieio-compat.el" 
"0609a7bdcd6f38876b7f5647047ddca9")
 ;;; Generated autoloads from eieio-compat.el
 
 (autoload 'eieio--defalias "eieio-compat" "\
diff --git a/lisp/emacs-lisp/eieio-custom.el b/lisp/emacs-lisp/eieio-custom.el
index 0e0b31e..26fc452 100644
--- a/lisp/emacs-lisp/eieio-custom.el
+++ b/lisp/emacs-lisp/eieio-custom.el
@@ -193,12 +193,8 @@ Optional argument IGNORE is an extraneous parameter."
   (let* ((chil nil)
         (obj (widget-get widget :value))
         (master-group (widget-get widget :eieio-group))
-        (cv (eieio--object-class-object obj))
-        (slots (eieio--class-public-a cv))
-        (flabel (eieio--class-public-custom-label cv))
-        (fgroup (eieio--class-public-custom-group cv))
-        (fdoc (eieio--class-public-doc cv))
-        (fcust (eieio--class-public-custom cv)))
+        (cv (eieio--object-class obj))
+        (slots (eieio--class-slots cv)))
     ;; First line describes the object, but may not editable.
     (if (widget-get widget :eieio-show-name)
        (setq chil (cons (widget-create-child-and-convert
@@ -208,7 +204,7 @@ Optional argument IGNORE is an extraneous parameter."
                         chil)))
     ;; Display information about the group being shown
     (when master-group
-      (let ((groups (eieio--class-option (eieio--object-class-object obj)
+      (let ((groups (eieio--class-option (eieio--object-class obj)
                                          :custom-groups)))
        (widget-insert "Groups:")
        (while groups
@@ -225,63 +221,59 @@ Optional argument IGNORE is an extraneous parameter."
          (setq groups (cdr groups)))
        (widget-insert "\n\n")))
     ;; Loop over all the slots, creating child widgets.
-    (while slots
-      ;; Output this slot if it has a customize flag associated with it.
-      (when (and (car fcust)
-                (or (not master-group) (member master-group (car fgroup)))
-                (slot-boundp obj (car slots)))
-       ;; In this case, this slot has a custom type.  Create its
-       ;; children widgets.
-       (let ((type (eieio-filter-slot-type widget (car fcust)))
-             (stuff nil))
-         ;; This next bit is an evil hack to get some EDE functions
-         ;; working the way I like.
-         (if (and (listp type)
-                  (setq stuff (member :slotofchoices type)))
-             (let ((choices (eieio-oref obj (car (cdr stuff))))
-                   (newtype nil))
-               (while (not (eq (car type) :slotofchoices))
-                 (setq newtype (cons (car type) newtype)
-                       type (cdr type)))
-               (while choices
-                 (setq newtype (cons (list 'const (car choices))
-                                     newtype)
-                       choices (cdr choices)))
-               (setq type (nreverse newtype))))
-         (setq chil (cons (widget-create-child-and-convert
-                           widget 'object-slot
-                           :childtype type
-                           :sample-face 'eieio-custom-slot-tag-face
-                           :tag
-                           (concat
-                            (make-string
-                             (or (widget-get widget :indent) 0)
-                             ? )
-                            (if (car flabel)
-                                (car flabel)
-                              (let ((s (symbol-name
-                                        (or
-                                         (eieio--class-slot-initarg
-                                          (eieio--object-class-object obj)
-                                          (car slots))
-                                         (car slots)))))
-                                (capitalize
-                                 (if (string-match "^:" s)
-                                     (substring s (match-end 0))
-                                   s)))))
-                           :value (slot-value obj (car slots))
-                           :doc  (if (car fdoc) (car fdoc)
-                                   "Slot not Documented.")
-                           :eieio-custom-visibility 'visible
-                           )
-                          chil))
-         )
-       )
-      (setq slots (cdr slots)
-           fdoc (cdr fdoc)
-           fcust (cdr fcust)
-           flabel (cdr flabel)
-           fgroup (cdr fgroup)))
+    (dotimes (i (length slots))
+      (let* ((slot (aref slots i))
+             (props (cl--slot-descriptor-props slot)))
+        ;; Output this slot if it has a customize flag associated with it.
+        (when (and (alist-get :custom props)
+                   (or (not master-group)
+                       (member master-group (alist-get :group props)))
+                   (slot-boundp obj (cl--slot-descriptor-name slot)))
+          ;; In this case, this slot has a custom type.  Create its
+          ;; children widgets.
+          (let ((type (eieio-filter-slot-type widget (alist-get :custom 
props)))
+                (stuff nil))
+            ;; This next bit is an evil hack to get some EDE functions
+            ;; working the way I like.
+            (if (and (listp type)
+                     (setq stuff (member :slotofchoices type)))
+                (let ((choices (eieio-oref obj (car (cdr stuff))))
+                      (newtype nil))
+                  (while (not (eq (car type) :slotofchoices))
+                    (setq newtype (cons (car type) newtype)
+                          type (cdr type)))
+                  (while choices
+                    (setq newtype (cons (list 'const (car choices))
+                                        newtype)
+                          choices (cdr choices)))
+                  (setq type (nreverse newtype))))
+            (setq chil (cons (widget-create-child-and-convert
+                              widget 'object-slot
+                              :childtype type
+                              :sample-face 'eieio-custom-slot-tag-face
+                              :tag
+                              (concat
+                               (make-string
+                                (or (widget-get widget :indent) 0)
+                                ?\s)
+                               (or (alist-get :label props)
+                                   (let ((s (symbol-name
+                                             (or
+                                              (eieio--class-slot-initarg
+                                               (eieio--object-class obj)
+                                               (car slots))
+                                              (car slots)))))
+                                     (capitalize
+                                      (if (string-match "^:" s)
+                                          (substring s (match-end 0))
+                                        s)))))
+                              :value (slot-value obj (car slots))
+                              :doc  (or (alist-get :documentation props)
+                                        "Slot not Documented.")
+                              :eieio-custom-visibility 'visible
+                              )
+                             chil))
+            ))))
     (widget-put widget :children (nreverse chil))
     ))
 
@@ -289,34 +281,33 @@ Optional argument IGNORE is an extraneous parameter."
   "Get the value of WIDGET."
   (let* ((obj (widget-get widget :value))
         (master-group eieio-cog)
-        (cv (eieio--object-class-object obj))
-        (fgroup (eieio--class-public-custom-group cv))
         (wids (widget-get widget :children))
         (name (if (widget-get widget :eieio-show-name)
                   (car (widget-apply (car wids) :value-inline))
                 nil))
         (chil (if (widget-get widget :eieio-show-name)
                   (nthcdr 1 wids) wids))
-        (cv (eieio--object-class-object obj))
-        (slots (eieio--class-public-a cv))
-        (fcust (eieio--class-public-custom cv)))
+        (cv (eieio--object-class obj))
+         (i 0)
+        (slots (eieio--class-slots cv)))
     ;; If there are any prefix widgets, clear them.
     ;; -- None yet
     ;; Create a batch of initargs for each slot.
-    (while (and slots chil)
-      (if (and (car fcust)
-              (or eieio-custom-ignore-eieio-co
-                  (not master-group) (member master-group (car fgroup)))
-              (slot-boundp obj (car slots)))
-         (progn
-           ;; Only customized slots have widgets
-           (let ((eieio-custom-ignore-eieio-co t))
-             (eieio-oset obj (car slots)
-                         (car (widget-apply (car chil) :value-inline))))
-           (setq chil (cdr chil))))
-      (setq slots (cdr slots)
-           fgroup (cdr fgroup)
-           fcust (cdr fcust)))
+    (while (and (< i (length slots)) chil)
+      (let* ((slot (aref slots i))
+             (props (cl--slot-descriptor-props slot))
+             (cust (alist-get :custom props)))
+        (if (and cust
+                 (or eieio-custom-ignore-eieio-co
+                     (not master-group)
+                     (member master-group (alist-get :group props)))
+              (slot-boundp obj (cl--slot-descriptor-name slot)))
+            (progn
+              ;; Only customized slots have widgets
+              (let ((eieio-custom-ignore-eieio-co t))
+                (eieio-oset obj (cl--slot-descriptor-name slot)
+                            (car (widget-apply (car chil) :value-inline))))
+              (setq chil (cdr chil))))))
     ;; Set any name updates on it.
     (if name (eieio-object-set-name-string obj name))
     ;; This is the same object we had before.
@@ -452,7 +443,7 @@ Must return the created widget."
            (vector (concat "Group " (symbol-name group))
                    (list 'customize-object obj (list 'quote group))
                    t))
-         (eieio--class-option (eieio--object-class-object obj) 
:custom-groups)))
+         (eieio--class-option (eieio--object-class obj) :custom-groups)))
 
 (defvar eieio-read-custom-group-history nil
   "History for the custom group reader.")
@@ -460,7 +451,7 @@ Must return the created widget."
 (cl-defmethod eieio-read-customization-group ((obj eieio-default-superclass))
   "Do a completing read on the name of a customization group in OBJ.
 Return the symbol for the group, or nil"
-  (let ((g (eieio--class-option (eieio--object-class-object obj)
+  (let ((g (eieio--class-option (eieio--object-class obj)
                                 :custom-groups)))
     (if (= (length g) 1)
        (car g)
diff --git a/lisp/emacs-lisp/eieio-datadebug.el 
b/lisp/emacs-lisp/eieio-datadebug.el
index 8234919..c820180 100644
--- a/lisp/emacs-lisp/eieio-datadebug.el
+++ b/lisp/emacs-lisp/eieio-datadebug.el
@@ -31,6 +31,9 @@
 
 ;;; Code:
 
+(declare-function data-debug/eieio-insert-slots "eieio-datadebug"
+                  (obj eieio-default-superclass))
+
 (defun data-debug-insert-object-slots (object prefix)
   "Insert all the slots of OBJECT.
 PREFIX specifies what to insert at the start of each line."
@@ -54,16 +57,17 @@ PREFIX specifies what to insert at the start of each line."
   "Insert a button representing OBJECT.
 PREFIX is the text that precedes the button.
 PREBUTTONTEXT is some text between PREFIX and the object button."
-  (let ((start (point))
-       (end nil)
-       (str (object-print object))
-       (tip (format "Object %s\nClass: %S\nParent(s): %S\n%d slots"
-                    (eieio-object-name-string object)
-                    (eieio-object-class object)
-                    (eieio-class-parents (eieio-object-class object))
-                    (length (object-slots object))
-                    ))
-       )
+  (let* ((start (point))
+         (end nil)
+         (str (object-print object))
+         (class (eieio-object-class object))
+         (tip (format "Object %s\nClass: %S\nParent(s): %S\n%d slots"
+                      (eieio-object-name-string object)
+                      class
+                      (eieio-class-parents class)
+                      (length (eieio-class-slots class))
+                      ))
+         )
     (insert prefix prebuttontext str)
     (setq end (point))
     (put-text-property (- end (length str)) end 'face 'font-lock-keyword-face)
@@ -80,41 +84,31 @@ PREBUTTONTEXT is some text between PREFIX and the object 
button."
 ;; Each object should have an opportunity to show stuff about itself.
 
 (cl-defmethod data-debug/eieio-insert-slots ((obj eieio-default-superclass)
-                                         prefix)
+                                             prefix)
   "Insert the slots of OBJ into the current DDEBUG buffer."
   (let ((inhibit-read-only t))
     (data-debug-insert-thing (eieio-object-name-string obj)
                             prefix
                             "Name: ")
-    (let* ((cl (eieio-object-class obj))
-          (cv (eieio--class-v cl)))
-      (data-debug-insert-thing (eieio--class-constructor cl)
+    (let* ((cv (eieio--object-class obj)))
+      (data-debug-insert-thing (eieio--class-name cv)
                               prefix
                               "Class: ")
       ;; Loop over all the public slots
-      (let ((publa (eieio--class-public-a cv))
-           )
-       (while publa
-         (if (slot-boundp obj (car publa))
-             (let* ((i (eieio--class-slot-initarg (eieio--class-v cl)
-                                                   (car publa)))
-                    (v (eieio-oref obj (car publa))))
-               (data-debug-insert-thing
-                v prefix (concat
-                          (if i (symbol-name i)
-                            (symbol-name (car publa)))
-                          " ")))
-           ;; Unbound case
-           (let ((i (eieio--class-slot-initarg (eieio--class-v cl)
-                                                (car publa))))
-             (data-debug-insert-custom
-              "#unbound" prefix
-              (concat (if i (symbol-name i)
-                        (symbol-name (car publa)))
-                      " ")
-              'font-lock-keyword-face))
-           )
-         (setq publa (cdr publa)))))))
+      (let ((slots (eieio--class-slots cv)))
+       (dotimes (i (length slots))
+          (let* ((slot (aref slots i))
+                 (sname (cl--slot-descriptor-name slot))
+                 (i (eieio--class-slot-initarg cv sname))
+                 (sstr (concat (symbol-name (or i sname)) " ")))
+            (if (slot-boundp obj sname)
+                (let* ((v (eieio-oref obj sname)))
+                  (data-debug-insert-thing v prefix sstr))
+              ;; Unbound case
+              (data-debug-insert-custom
+               "#unbound" prefix sstr
+               'font-lock-keyword-face)
+              )))))))
 
 ;;; Augment the Data debug thing display list.
 (data-debug-add-specialized-thing (lambda (thing) (eieio-object-p thing))
diff --git a/lisp/emacs-lisp/eieio-opt.el b/lisp/emacs-lisp/eieio-opt.el
index a769ca7..7f98730 100644
--- a/lisp/emacs-lisp/eieio-opt.el
+++ b/lisp/emacs-lisp/eieio-opt.el
@@ -99,7 +99,7 @@ If CLASS is actually an object, then also display current 
values of that object.
     (when pl
       (insert " Inherits from ")
       (while (setq cur (pop pl))
-       (setq cur (eieio--class-symbol cur))
+       (setq cur (eieio--class-name cur))
        (insert "`")
        (help-insert-xref-button (symbol-name cur)
                                 'help-function cur)
@@ -136,74 +136,40 @@ If CLASS is actually an object, then also display current 
values of that object.
                   (or doc "")))
        (insert "\n\n")))))
 
+(defun eieio--help-print-slot (slot)
+  (insert
+   (concat
+    (propertize "Slot: " 'face 'bold)
+    (prin1-to-string (cl--slot-descriptor-name slot))
+    (unless (eq (cl--slot-descriptor-type slot) t)
+      (concat "    type = "
+              (prin1-to-string (cl--slot-descriptor-type slot))))
+    (unless (eq (cl--slot-descriptor-initform slot) eieio-unbound)
+      (concat "    default = "
+              (prin1-to-string (cl--slot-descriptor-initform slot))))
+    (when (alist-get :printer (cl--slot-descriptor-props slot))
+      (concat "    printer = "
+              (prin1-to-string
+               (alist-get :printer (cl--slot-descriptor-props slot)))))
+    (when (alist-get :documentation (cl--slot-descriptor-props slot))
+      (concat "\n  " (alist-get :documentation (cl--slot-descriptor-props 
slot))
+              "\n")))
+   "\n"))
+
 (defun eieio-help-class-slots (class)
   "Print help description for the slots in CLASS.
 Outputs to the current buffer."
   (let* ((cv (eieio--class-v class))
-        (docs   (eieio--class-public-doc cv))
-        (names  (eieio--class-public-a cv))
-        (deflt  (eieio--class-public-d cv))
-        (types  (eieio--class-public-type cv))
-        (publp (eieio--class-public-printer cv))
-        (i      0)
-        (prot   (eieio--class-protection cv))
-        )
+         (slots (eieio--class-slots cv))
+         (cslots (eieio--class-class-slots cv)))
     (insert (propertize "Instance Allocated Slots:\n\n"
                        'face 'bold))
-    (while names
-      (insert
-       (concat
-       (when (car prot)
-         (propertize "Private " 'face 'bold))
-       (propertize "Slot: " 'face 'bold)
-       (prin1-to-string (car names))
-       (unless (eq (aref types i) t)
-         (concat "    type = "
-                 (prin1-to-string (aref types i))))
-       (unless (eq (car deflt) eieio-unbound)
-         (concat "    default = "
-                 (prin1-to-string (car deflt))))
-       (when (car publp)
-         (concat "    printer = "
-                 (prin1-to-string (car publp))))
-       (when (car docs)
-         (concat "\n  " (car docs) "\n"))
-       "\n"))
-      (setq names (cdr names)
-           docs (cdr docs)
-           deflt (cdr deflt)
-           publp (cdr publp)
-           prot (cdr prot)
-           i (1+ i)))
-    (setq docs  (eieio--class-class-allocation-doc cv)
-         names (eieio--class-class-allocation-a cv)
-         types (eieio--class-class-allocation-type cv)
-         i     0
-         prot  (eieio--class-class-allocation-protection cv))
-    (when names
+    (dotimes (i (length slots))
+      (eieio--help-print-slot (aref slots i)))
+    (when (> (length cslots) 0)
       (insert (propertize "\nClass Allocated Slots:\n\n" 'face 'bold)))
-    (while names
-      (insert
-       (concat
-       (when (car prot)
-         "Private ")
-       "Slot: "
-       (prin1-to-string (car names))
-       (unless (eq (aref types i) t)
-         (concat "    type = "
-                 (prin1-to-string (aref types i))))
-       (condition-case nil
-           (let ((value (eieio-oref class (car names))))
-             (concat "   value = "
-                     (prin1-to-string value)))
-         (error nil))
-       (when (car docs)
-         (concat "\n\n " (car docs) "\n"))
-       "\n"))
-      (setq names (cdr names)
-           docs (cdr docs)
-           prot (cdr prot)
-           i (1+ i)))))
+    (dotimes (i (length cslots))
+      (eieio--help-print-slot (aref cslots i)))))
 
 (defun eieio-build-class-alist (&optional class instantiable-only buildlist)
   "Return an alist of all currently active classes for completion purposes.
diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el
index cdf1992..8d76df8 100644
--- a/lisp/emacs-lisp/eieio.el
+++ b/lisp/emacs-lisp/eieio.el
@@ -320,19 +320,21 @@ variable name of the same name as the slot."
   (declare (indent 2) (debug (sexp sexp def-body)))
   (require 'cl-lib)
   ;; Transform the spec-list into a cl-symbol-macrolet spec-list.
-  (let ((mappings (mapcar (lambda (entry)
-                           (let ((var  (if (listp entry) (car entry) entry))
-                                 (slot (if (listp entry) (cadr entry) entry)))
-                             (list var `(slot-value ,object ',slot))))
-                         spec-list)))
-    (append (list 'cl-symbol-macrolet mappings)
-           body)))
+  (macroexp-let2 nil object object
+    `(cl-symbol-macrolet
+         ,(mapcar (lambda (entry)
+                    (let ((var  (if (listp entry) (car entry) entry))
+                          (slot (if (listp entry) (cadr entry) entry)))
+                      (list var `(slot-value ,object ',slot))))
+                  spec-list)
+       ,@body)))
 
 ;;; Simple generators, and query functions.  None of these would do
 ;;  well embedded into an object.
 ;;
+
 (define-obsolete-function-alias
-  'object-class-fast #'eieio--object-class-name "24.4")
+  'object-class-fast #'eieio-object-class "24.4")
 
 (cl-defgeneric eieio-object-name-string (obj)
   "Return a string which is OBJ's name."
@@ -342,7 +344,7 @@ variable name of the same name as the slot."
   "Return a printed representation for object OBJ.
 If EXTRA, include that in the string returned to represent the symbol."
   (cl-check-type obj eieio-object)
-  (format "#<%s %s%s>" (eieio--object-class-name obj)
+  (format "#<%s %s%s>" (eieio-object-class obj)
          (eieio-object-name-string obj) (or extra "")))
 (define-obsolete-function-alias 'object-name #'eieio-object-name "24.4")
 
@@ -370,7 +372,7 @@ If EXTRA, include that in the string returned to represent 
the symbol."
   "Return the class struct defining OBJ."
   ;; FIXME: We say we return a "struct" but we return a symbol instead!
   (cl-check-type obj eieio-object)
-  (eieio--object-class-name obj))
+  (eieio--class-name (eieio--object-class obj)))
 (define-obsolete-function-alias 'object-class #'eieio-object-class "24.4")
 ;; CLOS name, maybe?
 (define-obsolete-function-alias 'class-of #'eieio-object-class "24.4")
@@ -378,7 +380,7 @@ If EXTRA, include that in the string returned to represent 
the symbol."
 (defun eieio-object-class-name (obj)
   "Return a Lisp like symbol name for OBJ's class."
   (cl-check-type obj eieio-object)
-  (eieio-class-name (eieio--object-class-object obj)))
+  (eieio-class-name (eieio--object-class obj)))
 (define-obsolete-function-alias
   'object-class-name 'eieio-object-class-name "24.4")
 
@@ -386,7 +388,7 @@ If EXTRA, include that in the string returned to represent 
the symbol."
   "Return parent classes to CLASS.  (overload of variable).
 
 The CLOS function `class-direct-superclasses' is aliased to this function."
-  (eieio--class-parent (eieio--class-object class)))
+  (eieio--class-parents (eieio--class-object class)))
 
 (define-obsolete-function-alias 'class-parents #'eieio-class-parents "24.4")
 
@@ -414,13 +416,13 @@ The CLOS function `class-direct-subclasses' is aliased to 
this function."
   (setq class (eieio--class-object class))
   (cl-check-type class eieio--class)
   (cl-check-type obj eieio-object)
-  (eq (eieio--object-class-object obj) class))
+  (eq (eieio--object-class obj) class))
 
 (defun object-of-class-p (obj class)
   "Return non-nil if OBJ is an instance of CLASS or CLASS' subclasses."
   (cl-check-type obj eieio-object)
   ;; class will be checked one layer down
-  (child-of-class-p (eieio--object-class-object obj) class))
+  (child-of-class-p (eieio--object-class obj) class))
 ;; Backwards compatibility
 (defalias 'obj-of-class-p 'object-of-class-p)
 
@@ -428,36 +430,37 @@ The CLOS function `class-direct-subclasses' is aliased to 
this function."
   "Return non-nil if CHILD class is a subclass of CLASS."
   (setq child (eieio--class-object child))
   (cl-check-type child eieio--class)
-  ;; `eieio-default-superclass' is never mentioned in eieio--class-parent,
+  ;; `eieio-default-superclass' is never mentioned in eieio--class-parents,
   ;; so we have to special case it here.
   (or (eq class 'eieio-default-superclass)
       (let ((p nil))
         (setq class (eieio--class-object class))
         (cl-check-type class eieio--class)
         (while (and child (not (eq child class)))
-          (setq p (append p (eieio--class-parent child))
+          (setq p (append p (eieio--class-parents child))
                 child (pop p)))
         (if child t))))
 
-(defun eieio-slot-descriptor-name (slot) slot)
+(defun eieio-slot-descriptor-name (slot)
+  (cl--slot-descriptor-name slot))
 
 (defun eieio-class-slots (class)
   "Return list of slots available in instances of CLASS."
   ;; FIXME: This only gives the instance slots and ignores the
   ;; class-allocated slots.
-  ;; FIXME: It only gives the slot's *names* rather than actual
-  ;; slot descriptors.
   (setq class (eieio--class-object class))
   (cl-check-type class eieio--class)
-  (eieio--class-public-a class))
+  (mapcar #'identity (eieio--class-slots class)))
 
 (defun object-slots (obj)
-  "Return list of slots available in OBJ."
+  "Return list of slot names available in OBJ."
   (declare (obsolete eieio-class-slots "25.1"))
   (cl-check-type obj eieio-object)
-  (eieio-class-slots (eieio--object-class-object obj)))
+  (mapcar #'cl--slot-descriptor-name
+         (eieio-class-slots (eieio--object-class obj))))
 
-(defun eieio--class-slot-initarg (class slot) "Fetch from CLASS, SLOT's 
:initarg."
+(defun eieio--class-slot-initarg (class slot)
+  "Fetch from CLASS, SLOT's :initarg."
   (cl-check-type class eieio--class)
   (let ((ia (eieio--class-initarg-tuples class))
        (f nil))
@@ -507,12 +510,18 @@ OBJECT can be an instance or a class."
 (defun slot-exists-p (object-or-class slot)
   "Return non-nil if OBJECT-OR-CLASS has SLOT."
   (let ((cv (cond ((eieio-object-p object-or-class)
-                   (eieio--object-class-object object-or-class))
+                   (eieio--object-class object-or-class))
                   ((eieio--class-p object-or-class) object-or-class)
                   (t (find-class object-or-class 'error)))))
-    (or (memq slot (eieio--class-public-a cv))
-       (memq slot (eieio--class-class-allocation-a cv)))
-    ))
+    (or (gethash slot (eieio--class-index-table cv))
+        ;; FIXME: We could speed this up by adding class slots into the
+        ;; index-table (e.g. with a negative index?).
+       (let ((cs (eieio--class-class-slots cv))
+             found)
+         (dotimes (i (length cs))
+           (if (eq slot (cl--slot-descriptor-name (aref cs i)))
+               (setq found t)))
+         found))))
 
 (defun find-class (symbol &optional errorp)
   "Return the class that SYMBOL represents.
@@ -671,7 +680,7 @@ Called from the constructor routine.")
   "Set slots of OBJ with SLOTS which is a list of name/value pairs.
 Called from the constructor routine."
   (while slots
-    (let ((rn (eieio--initarg-to-attribute (eieio--object-class-object obj)
+    (let ((rn (eieio--initarg-to-attribute (eieio--object-class obj)
                                            (car slots))))
       (if (not rn)
           (slot-missing obj (car slots) 'oset (car (cdr slots)))
@@ -694,9 +703,9 @@ not taken, then new objects of your class will not have 
their values
 dynamically set from SLOTS."
   ;; First, see if any of our defaults are `lambda', and
   ;; re-evaluate them and apply the value to our slots.
-  (let* ((this-class (eieio--object-class-object this))
-        (defaults (eieio--class-public-d this-class)))
-    (dolist (slot (eieio--class-public-a this-class))
+  (let* ((this-class (eieio--object-class this))
+         (slots (eieio--class-slots this-class)))
+    (dotimes (i (length slots))
       ;; For each slot, see if we need to evaluate it.
       ;;
       ;; Paul Landes said in an email:
@@ -704,11 +713,12 @@ dynamically set from SLOTS."
       ;; > the quoted thing as you already have.  This is by the
       ;; > Sonya E. Keene book and other things I've look at on the
       ;; > web.
-      (let ((dflt (eieio-default-eval-maybe (car defaults))))
-       (when (not (eq dflt (car defaults)))
-         (eieio-oset this slot dflt) ))
-      ;; Next.
-      (setq defaults (cdr defaults))))
+      (let* ((slot (aref slots i))
+             (initform (cl--slot-descriptor-initform slot))
+             (dflt (eieio-default-eval-maybe initform)))
+        (when (not (eq dflt initform))
+          ;; FIXME: We should be able to just do (aset this (+ i <cst>) dflt)!
+          (eieio-oset this (cl--slot-descriptor-name slot) dflt)))))
   ;; Shared initialize will parse our slots for us.
   (shared-initialize this slots))
 
@@ -825,32 +835,31 @@ this object."
     (prin1 (eieio-object-name-string this))
     (princ "\n")
     ;; Loop over all the public slots
-    (let ((publa (eieio--class-public-a cv))
-         (publd (eieio--class-public-d cv))
-         (publp (eieio--class-public-printer cv))
+    (let ((slots (eieio--class-slots cv))
          (eieio-print-depth (1+ eieio-print-depth)))
-      (while publa
-       (when (slot-boundp this (car publa))
-         (let ((i (eieio--class-slot-initarg cv (car publa)))
-               (v (eieio-oref this (car publa)))
-               )
-           (unless (or (not i) (equal v (car publd)))
-             (unless (bolp)
-               (princ "\n"))
-             (princ (make-string (* eieio-print-depth 2) ? ))
-             (princ (symbol-name i))
-             (if (car publp)
-                 ;; Use our public printer
-                 (progn
-                   (princ " ")
-                   (funcall (car publp) v))
-               ;; Use our generic override prin1 function.
-               (princ (if (or (eieio-object-p v)
-                               (eieio-object-p (car-safe v)))
-                           "\n" " "))
-               (eieio-override-prin1 v)))))
-       (setq publa (cdr publa) publd (cdr publd)
-             publp (cdr publp))))
+      (dotimes (i (length slots))
+        (let ((slot (aref slots i)))
+          (when (slot-boundp this (cl--slot-descriptor-name slot))
+            (let ((i (eieio--class-slot-initarg
+                      cv (cl--slot-descriptor-name slot)))
+                  (v (eieio-oref this (cl--slot-descriptor-name slot))))
+              (unless (or (not i) (equal v (cl--slot-descriptor-initform 
slot)))
+                (unless (bolp)
+                  (princ "\n"))
+                (princ (make-string (* eieio-print-depth 2) ? ))
+                (princ (symbol-name i))
+                (if (alist-get :printer (cl--slot-descriptor-props slot))
+                    ;; Use our public printer
+                    (progn
+                      (princ " ")
+                      (funcall (alist-get :printer
+                                          (cl--slot-descriptor-props slot))
+                               v))
+                  ;; Use our generic override prin1 function.
+                  (princ (if (or (eieio-object-p v)
+                                 (eieio-object-p (car-safe v)))
+                             "\n" " "))
+                  (eieio-override-prin1 v))))))))
     (princ ")")
     (when (= eieio-print-depth 0)
       (princ "\n"))))
@@ -919,7 +928,7 @@ variable PRINT-FUNCTION.  Optional argument NOESCAPE is 
passed to
 
 ;;; Start of automatically extracted autoloads.
 
-;;;### (autoloads nil "eieio-custom" "eieio-custom.el" 
"2ec91e473fcad1ff20cd76edc4aab706")
+;;;### (autoloads nil "eieio-custom" "eieio-custom.el" 
"813d32fbf76d4248fc6b4dc97ebcd720")
 ;;; Generated autoloads from eieio-custom.el
 
 (autoload 'customize-object "eieio-custom" "\
@@ -930,7 +939,7 @@ Optional argument GROUP is the sub-group of slots to 
display.
 
 ;;;***
 
-;;;### (autoloads nil "eieio-opt" "eieio-opt.el" 
"d1910eb455f102989fc33bb3f5a9b614")
+;;;### (autoloads nil "eieio-opt" "eieio-opt.el" 
"3005b815c6b30eccbf0642170b3f82a5")
 ;;; Generated autoloads from eieio-opt.el
 
 (autoload 'eieio-browse "eieio-opt" "\
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index b4f87fd..6b30773 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -181,32 +181,25 @@
             nil)))
     res))
 
-(defconst lisp--el-macro-regexp nil
-  "A regular expression matching all loaded elisp macros.
-Can be updated using `lisp--el-update-macro-regexp' after new
-macros were defined.")
-
-(defun lisp--el-update-macro-regexp ()
-  "Update `lisp--el-update-macro-regexp' from `obarray'.
-Return non-nil only if the old and new value are different."
-  (let ((old-regex lisp--el-macro-regexp)
-       (elisp-macros nil))
-    (mapatoms (lambda (a)
-               (when (or (macrop a) (special-form-p a))
-                 (push (symbol-name a) elisp-macros))))
-    (setq lisp--el-macro-regexp
-         (concat "(" (regexp-opt elisp-macros t) "\\_>"))
-    (not (string= old-regex lisp--el-macro-regexp))))
-
-(defun lisp--el-update-after-load (_file)
-  "Update `lisp--el-macro-regexp' and adjust font-lock in existing buffers."
-  (when (lisp--el-update-macro-regexp)
+(defun lisp--el-match-keyword (limit)
+  (catch 'found
+    (while (re-search-forward "(\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>" limit t)
+      (let ((sym (intern-soft (match-string 1))))
+       (when (or (special-form-p sym)
+                 (and (macrop sym)
+                      (not (get sym 'no-font-lock-keyword))))
+         (throw 'found t))))))
+
+(defun lisp--el-font-lock-flush-elisp-buffers (&optional file)
+  ;; Don't flush during load unless called from after-load-functions.
+  ;; In that case, FILE is non-nil.  It's somehow strange that
+  ;; load-in-progress is t when an after-load-function is called since
+  ;; that should run *after* the load...
+  (when (or (not load-in-progress) file)
     (dolist (buf (buffer-list))
-      (when (derived-mode-p 'emacs-lisp-mode)
-       (font-lock-flush)))))
-
-(defun lisp--el-match-macro (limit)
-  (re-search-forward lisp--el-macro-regexp limit t))
+      (with-current-buffer buf
+       (when (derived-mode-p 'emacs-lisp-mode)
+         (font-lock-flush))))))
 
 (pcase-let
     ((`(,vdefs ,tdefs
@@ -362,7 +355,7 @@ Return non-nil only if the old and new value are different."
      `( ;; Regexp negated char group.
        ("\\[\\(\\^\\)" 1 font-lock-negation-char-face prepend)
        ;; Control structures.  Common Lisp forms.
-       (lisp--el-match-macro . 1)
+       (lisp--el-match-keyword . 1)
        ;; Exit/Feature symbols as constants.
        (,(concat "(\\(catch\\|throw\\|featurep\\|provide\\|require\\)\\_>"
                  "[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?")
@@ -543,9 +536,7 @@ font-lock keywords will not be case sensitive."
           . lisp-font-lock-syntactic-face-function)))
   (setq-local prettify-symbols-alist lisp--prettify-symbols-alist)
   (when elisp
-    (unless lisp--el-macro-regexp
-      (lisp--el-update-macro-regexp))
-    (add-hook 'after-load-functions #'lisp--el-update-after-load)
+    (add-hook 'after-load-functions #'lisp--el-font-lock-flush-elisp-buffers)
     (setq-local electric-pair-text-pairs
                 (cons '(?\` . ?\') electric-pair-text-pairs)))
   (setq-local electric-pair-skip-whitespace 'chomp)
diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
index 68bf4f6..f0410f8 100644
--- a/lisp/emacs-lisp/macroexp.el
+++ b/lisp/emacs-lisp/macroexp.el
@@ -465,6 +465,8 @@ itself or not."
 (defvar macroexp--pending-eager-loads nil
   "Stack of files currently undergoing eager macro-expansion.")
 
+(defvar macroexp--debug-eager nil)
+
 (defun internal-macroexpand-for-load (form full-p)
   ;; Called from the eager-macroexpansion in readevalloop.
   (cond
@@ -480,8 +482,10 @@ itself or not."
            (tail (member elem (cdr (member elem bt)))))
       (if tail (setcdr tail (list '…)))
       (if (eq (car-safe (car bt)) 'macroexpand-all) (setq bt (cdr bt)))
-      (message "Warning: Eager macro-expansion skipped due to cycle:\n  %s"
-               (mapconcat #'prin1-to-string (nreverse bt) " => "))
+      (if macroexp--debug-eager
+          (debug 'eager-macroexp-cycle)
+        (message "Warning: Eager macro-expansion skipped due to cycle:\n  %s"
+                 (mapconcat #'prin1-to-string (nreverse bt) " => ")))
       (push 'skip macroexp--pending-eager-loads)
       form))
    (t
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
index 4706be5..0e8a969 100644
--- a/lisp/emacs-lisp/pcase.el
+++ b/lisp/emacs-lisp/pcase.el
@@ -166,23 +166,26 @@ like `(,a . ,(pred (< a))) or, with more checks:
 
 ;;;###autoload
 (defmacro pcase-lambda (lambda-list &rest body)
-  "Like `lambda' but allow each argument to be a pattern.
-`&rest' argument is supported."
+  "Like `lambda' but allow each argument to be a UPattern.
+I.e. accepts the usual &optional and &rest keywords, but every
+formal argument can be any pattern accepted by `pcase' (a mere
+variable name being but a special case of it)."
   (declare (doc-string 2) (indent defun)
-           (debug ((&rest pcase-UPAT &optional ["&rest" pcase-UPAT]) body)))
-  (let ((args (make-symbol "args"))
-        (pats (mapcar (lambda (u)
-                        (unless (eq u '&rest)
-                          (if (eq (car-safe u) '\`) (cadr u) (list '\, u))))
-                      lambda-list))
-        (body (macroexp-parse-body body)))
-    ;; Handle &rest
-    (when (eq nil (car (last pats 2)))
-      (setq pats (append (butlast pats 2) (car (last pats)))))
-    `(lambda (&rest ,args)
-       ,@(car body)
-       (pcase ,args
-         (,(list '\` pats) . ,(cdr body))))))
+           (debug ((&rest pcase-UPAT) body)))
+  (let* ((bindings ())
+         (parsed-body (macroexp-parse-body body))
+         (args (mapcar (lambda (pat)
+                         (if (symbolp pat)
+                             ;; Simple vars and &rest/&optional are just passed
+                             ;; through unchanged.
+                             pat
+                           (let ((arg (make-symbol
+                                       (format "arg%s" (length bindings)))))
+                             (push `(,pat ,arg) bindings)
+                             arg)))
+                       lambda-list)))
+    `(lambda ,args ,@(car parsed-body)
+       (pcase-let* ,(nreverse bindings) ,@(cdr parsed-body)))))
 
 (defun pcase--let* (bindings body)
   (cond
diff --git a/lisp/leim/quail/hangul.el b/lisp/leim/quail/hangul.el
index 243fa04..12d7358 100644
--- a/lisp/leim/quail/hangul.el
+++ b/lisp/leim/quail/hangul.el
@@ -351,7 +351,7 @@ Other parts are the same as a `hangul3-input-method-cho'."
     (aset hangul-queue i 0))
   (if (notzerop (apply '+ (append hangul-queue nil)))
       (hangul-insert-character hangul-queue)
-    (delete-backward-char 1)))
+    (delete-char -1)))
 
 (defun hangul-to-hanja-conversion ()
   "Convert the previous hangul character to the corresponding hanja character.
@@ -363,7 +363,7 @@ When a Korean input method is off, convert the following 
hangul character."
     (if (and (overlayp quail-overlay) (overlay-start quail-overlay))
         (progn
          (setq hanja-character (hangul-to-hanja-char (preceding-char)))
-         (setq delete-func (lambda () (delete-backward-char 1))))
+         (setq delete-func (lambda () (delete-char -1))))
       (setq hanja-character (hangul-to-hanja-char (following-char)))
       (setq delete-func (lambda () (delete-char 1))))
     (when hanja-character
diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el
index 4b64d95..b44bb71 100644
--- a/lisp/net/browse-url.el
+++ b/lisp/net/browse-url.el
@@ -42,7 +42,7 @@
 ;; browse-url-netscape                Netscape    1.1b1
 ;; browse-url-mosaic                  XMosaic/mMosaic <= 2.4
 ;; browse-url-cci                     XMosaic     2.5
-;; browse-url-conkeror                Conkeror    Dont know
+;; browse-url-conkeror                Conkeror    Don't know
 ;; browse-url-w3                      w3          0
 ;; browse-url-w3-gnudoit              w3 remotely
 ;; browse-url-text-*                 Any text browser     0
@@ -62,7 +62,7 @@
 ;; control.  <URL:http://www.netscape.com/newsref/std/x-remote.html>.
 
 ;; Browsers can cache Web pages so it may be necessary to tell them to
-;; reload the current page if it has changed (e.g. if you have edited
+;; reload the current page if it has changed (e.g., if you have edited
 ;; it).  There is currently no perfect automatic solution to this.
 
 ;; Netscape allows you to specify the id of the window you want to
@@ -420,8 +420,8 @@ functionality is not available there."
 
 (defcustom browse-url-conkeror-new-window-is-buffer nil
   "Whether to open up new windows in a buffer or a new window.
-If non-nill, then open the URL in a new buffer rather than a new window if
-`browse-url-conkeror' is asked to open it in a new window"
+If non-nil, then open the URL in a new buffer rather than a new window if
+`browse-url-conkeror' is asked to open it in a new window."
   :type 'boolean
   :group 'browse-url)
 
@@ -823,7 +823,7 @@ narrowed."
 ;;;###autoload
 (defun browse-url (url &rest args)
   "Ask a WWW browser to load URL.
-Prompts for a URL, defaulting to the URL at or before point.  Variable
+Prompt for a URL, defaulting to the URL at or before point.  Variable
 `browse-url-browser-function' says which browser to use.
 If the URL is a mailto: URL, consult `browse-url-mailto-function'
 first, if that exists."
@@ -862,8 +862,7 @@ first, if that exists."
 ;;;###autoload
 (defun browse-url-at-point (&optional arg)
   "Ask a WWW browser to load the URL at or before point.
-Doesn't let you edit the URL like `browse-url'.  Variable
-`browse-url-browser-function' says which browser to use."
+Variable `browse-url-browser-function' says which browser to use."
   (interactive "P")
   (let ((url (browse-url-url-at-point)))
     (if url
@@ -876,9 +875,8 @@ Doesn't let you edit the URL like `browse-url'.  Variable
 (defun browse-url-at-mouse (event)
   "Ask a WWW browser to load a URL clicked with the mouse.
 The URL is the one around or before the position of the mouse click
-but point is not changed.  Doesn't let you edit the URL like
-`browse-url'.  Variable `browse-url-browser-function' says which browser
-to use."
+but point is not changed.  Variable `browse-url-browser-function'
+says which browser to use."
   (interactive "e")
   (save-excursion
     (mouse-set-point event)
@@ -1384,20 +1382,21 @@ used instead of `browse-url-new-window-flag'."
 ;;;###autoload
 (defun browse-url-conkeror (url &optional new-window)
   "Ask the Conkeror WWW browser to load URL.
-Default to the URL around or before point. The strings in the variable
-`browse-url-conkeror-arguments' are also passed to Conkeror.
+Default to the URL around or before point.  Also pass the strings
+in the variable `browse-url-conkeror-arguments' to Conkeror.
 
-When called interactively, if variable `browse-url-new-window-flag'
-is non-nil, load the document in a new Conkeror window, otherwise use a random
-existing one. A non-nil interactive prefix argument reverses the effect of
-`browse-url-new-window-flag'
+When called interactively, if variable
+`browse-url-new-window-flag' is non-nil, load the document in a
+new Conkeror window, otherwise use a random existing one.  A
+non-nil interactive prefix argument reverses the effect of
+`browse-url-new-window-flag'.
 
-If `browse-url-conkeror-new-window-is-buffer' then whenever a document would
-otherwise be loaded in a new window, it is loaded in a new buffer in an 
existing
-window instead.
+If variable `browse-url-conkeror-new-window-is-buffer' is
+non-nil, then whenever a document would otherwise be loaded in a
+new window, load it in a new buffer in an existing window instead.
 
-When called non-interatively, optional second argument NEW-WINDOW is used 
instead of
-`browse-url-new-window-flag'"
+When called non-interactively, use optional second argument
+NEW-WINDOW instead of `browse-url-new-window-flag'."
   (interactive (browse-url-interactive-arg "URL: "))
   (setq url (browse-url-encode-url url))
   (let* ((process-environment (browse-url-process-environment)))
@@ -1495,7 +1494,7 @@ used instead of `browse-url-new-window-flag'."
         (n browse-url-text-input-attempts))
     (require 'term)
     (if (and (browse-url-maybe-new-window new-buffer) buf)
-       ;; Rename away the OLD buffer. This isn't very polite, but
+       ;; Rename away the OLD buffer.  This isn't very polite, but
        ;; term insists on working in a buffer named *lynx* and would
        ;; choke on *lynx*<1>
        (progn (set-buffer buf)
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 133d886..b82b4de 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -1719,12 +1719,12 @@ be non-negative integers."
      ;; "-"; this would confuse xargs.  "ls -aQ" might be a solution,
      ;; but it does not work on all remote systems.  Therefore, we
      ;; use \000 as file separator.
-     ;; Apostrophes in the stat output are masked as \037 characters, in
+     ;; Apostrophes in the stat output are masked as ?/ characters, in
      ;; order to make a proper shell escape of them in file names.
      "cd %s && echo \"(\"; (%s %s -a | "
      "xargs %s -c "
-     "'(\037%%n\037 (\037%%N\037) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 
\037%%A\037 t %%ie0 -1)'"
-     " -- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/\037/\"/g'); echo \")\"")
+     "'(/%%n/ (/%%N/) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 /%%A/ t %%ie0 -1)' "
+     "-- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/\\//\"/g'); echo \")\"")
     (tramp-shell-quote-argument localname)
     (tramp-get-ls-command vec)
     ;; On systems which have no quoting style, file names with
@@ -1732,8 +1732,8 @@ be non-negative integers."
     (if (tramp-get-ls-command-with-quoting-style vec)
        "--quoting-style=shell" "")
     (tramp-get-remote-stat vec)
-    (if (eq id-format 'integer) "%ue0" "\037%U\037")
-    (if (eq id-format 'integer) "%ge0" "\037%G\037"))))
+    (if (eq id-format 'integer) "%ue0" "/%U/")
+    (if (eq id-format 'integer) "%ge0" "/%G/"))))
 
 ;; This function should return "foo/" for directories and "bar" for
 ;; files.
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index 3b8742e..2acfc10 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -2281,8 +2281,8 @@ to nil."
             (search-backward ")")
             (if (eq last-command-event ?\()
                 (progn                 ; Avoid "if (())"
-                  (delete-backward-char 1)
-                  (delete-backward-char -1))))
+                  (delete-char -1)
+                  (delete-char 1))))
           (if delete
               (cperl-putback-char cperl-del-back-ch))
           (if cperl-message-electric-keyword
@@ -2588,7 +2588,7 @@ Will untabify if `cperl-electric-backspace-untabify' is 
non-nil."
          (delete-region (point) p))
       (if cperl-electric-backspace-untabify
          (backward-delete-char-untabify arg)
-       (delete-backward-char arg)))))
+       (call-interactively 'delete-backward-char)))))
 
 (put 'cperl-electric-backspace 'delete-selection 'supersede)
 
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index 29a6dc6..9ab0667 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -2813,7 +2813,7 @@ Obeying it means displaying in another window the 
specified file and line."
            (gud-find-file true-file)))
         (window (and buffer
                      (or (get-buffer-window buffer)
-                         (display-buffer buffer))))
+                         (display-buffer buffer '(nil (inhibit-same-window . 
t))))))
         (pos))
     (when buffer
       (with-current-buffer buffer
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 060bc84..921ca31 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -2069,13 +2069,11 @@ See `font-lock-syntax-table'.")
        ruby-font-lock-keyword-beg-re
        (regexp-opt
         '( ;; built-in methods on Kernel
-          "at_exit"
           "autoload"
           "autoload?"
           "catch"
           "eval"
           "exec"
-          "fork"
           "format"
           "lambda"
           "load"
@@ -2093,7 +2091,10 @@ See `font-lock-syntax-table'.")
           "sprintf"
           "syscall"
           "system"
+          "throw"
+          "trace_var"
           "trap"
+          "untrace_var"
           "warn"
           ;; keyword-like private methods on Module
           "alias_method"
@@ -2126,10 +2127,14 @@ See `font-lock-syntax-table'.")
           "at_exit"
           "binding"
           "block_given?"
+          "callcc"
           "caller"
           "exit"
           "exit!"
           "fail"
+          "fork"
+          "global_variables"
+          "local_variables"
           "private"
           "protected"
           "public"
diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el
index 44dc4df..3e7612a 100644
--- a/lisp/textmodes/css-mode.el
+++ b/lisp/textmodes/css-mode.el
@@ -3,6 +3,7 @@
 ;; Copyright (C) 2006-2015 Free Software Foundation, Inc.
 
 ;; Author: Stefan Monnier <address@hidden>
+;; Maintainer: Simen Heggestøyl <address@hidden>
 ;; Keywords: hypermedia
 
 ;; This file is part of GNU Emacs.
@@ -28,7 +29,7 @@
 
 ;; - electric ; and }
 ;; - filling code with auto-fill-mode
-;; - completion
+;; - attribute value completion
 ;; - fix font-lock errors with multi-line selectors
 
 ;;; Code:
@@ -37,96 +38,20 @@
   "Cascading Style Sheets (CSS) editing mode."
   :group 'languages)
 
+(defconst css-pseudo-class-ids
+  '("active" "checked" "disabled" "empty" "enabled" "first"
+    "first-child" "first-of-type" "focus" "hover" "indeterminate" "lang"
+    "last-child" "last-of-type" "left" "link" "nth-child"
+    "nth-last-child" "nth-last-of-type" "nth-of-type" "only-child"
+    "only-of-type" "right" "root" "target" "visited")
+  "Identifiers for pseudo-classes.")
 
-(defun css-extract-keyword-list (res)
-  (with-temp-buffer
-    (url-insert-file-contents "http://www.w3.org/TR/REC-CSS2/css2.txt";)
-    (goto-char (point-max))
-    (search-backward "Appendix H. Index")
-    (forward-line)
-    (delete-region (point-min) (point))
-    (let ((result nil)
-          keys)
-      (dolist (re res)
-        (goto-char (point-min))
-        (setq keys nil)
-        (while (re-search-forward (cdr re) nil t)
-          (push (match-string 1) keys))
-        (push (cons (car re) (sort keys 'string-lessp)) result))
-      (nreverse result))))
-
-(defun css-extract-parse-val-grammar (string env)
-  (let ((start 0)
-        (elems ())
-        name)
-    (while (string-match
-            (concat "\\(?:"
-                    (concat "<a [^>]+><span [^>]+>\\(?:"
-                            "&lt;\\([^&]+\\)&gt;\\|'\\([^']+\\)'"
-                            "\\)</span></a>")
-                    "\\|" "\\(\\[\\)"
-                    "\\|" "\\(]\\)"
-                    "\\|" "\\(||\\)"
-                    "\\|" "\\(|\\)"
-                    "\\|" "\\([*+?]\\)"
-                    "\\|" "\\({[^}]+}\\)"
-                    "\\|" "\\(\\w+\\(?:-\\w+\\)*\\)"
-                    "\\)[ \t\n]*")
-            string start)
-      ;; (assert (eq start (match-beginning 0)))
-      (setq start (match-end 0))
-      (cond
-       ;; Reference to a type of value.
-       ((setq name (match-string-no-properties 1 string))
-        (push (intern name) elems))
-       ;; Reference to another property's values.
-       ((setq name (match-string-no-properties 2 string))
-        (setq elems (delete-dups (append (cdr (assoc name env)) elems))))
-       ;; A literal
-       ((setq name (match-string-no-properties 9 string))
-        (push name elems))
-       ;; We just ignore the rest.  I.e. we ignore the structure because
-       ;; it's too difficult to exploit anyway (it would allow us to only
-       ;; complete top/center/bottom after one of left/center/right and
-       ;; vice-versa).
-       (t nil)))
-    elems))
-
-
-(defun css-extract-props-and-vals ()
-  (with-temp-buffer
-    (url-insert-file-contents "http://www.w3.org/TR/CSS21/propidx.html";)
-    (goto-char (point-min))
-    (let ((props ()))
-      (while (re-search-forward "#propdef-\\([^\"]+\\)\"><span 
class=\"propinst-\\1 xref\">'\\1'</span></a>" nil t)
-        (let ((prop (match-string-no-properties 1)))
-          (save-excursion
-            (goto-char (match-end 0))
-            (search-forward "<td>")
-            (let ((vals-string (buffer-substring (point)
-                                                 (progn
-                                                   (re-search-forward "[ 
\t\n]+|[ \t\n]+<a href=\"cascade.html#value-def-inherit\" 
class=\"noxref\"><span class=\"value-inst-inherit\">inherit</span></a>")
-                                                   (match-beginning 0)))))
-              ;;
-              (push (cons prop (css-extract-parse-val-grammar vals-string 
props))
-                    props)))))
-      props)))
-
-;; Extraction was done with:
-;; (css-extract-keyword-list
-;;  '((pseudo . "^ +\\* :\\([^ \n,]+\\)")
-;;    (at . "^ +\\* @\\([^ \n,]+\\)")
-;;    (descriptor . "^ +\\* '\\([^ '\n]+\\)' (descriptor)")
-;;    (media . "^ +\\* '\\([^ '\n]+\\)' media group")
-;;    (property . "^ +\\* '\\([^ '\n]+\\)',")))
-
-(defconst css-pseudo-ids
-  '("active" "after" "before" "first" "first-child" "first-letter" "first-line"
-    "focus" "hover" "lang" "left" "link" "right" "visited")
-  "Identifiers for pseudo-elements and pseudo-classes.")
+(defconst css-pseudo-element-ids
+  '("after" "before" "first-letter" "first-line")
+  "Identifiers for pseudo-elements.")
 
 (defconst css-at-ids
-  '("charset" "font-face" "import" "media" "page")
+  '("charset" "font-face" "import" "media" "namespace" "page")
   "Identifiers that appear in the form @foo.")
 
 (defconst css-descriptor-ids
@@ -142,36 +67,103 @@
   "Identifiers for types of media.")
 
 (defconst css-property-ids
-  '("azimuth" "background" "background-attachment" "background-color"
-    "background-image" "background-position" "background-repeat" "block"
-    "border" "border-bottom" "border-bottom-color" "border-bottom-style"
-    "border-bottom-width" "border-collapse" "border-color" "border-left"
-    "border-left-color" "border-left-style" "border-left-width" "border-right"
+  '(;; CSS 2.1 properties (http://www.w3.org/TR/CSS21/propidx.html).
+    ;;
+    ;; Properties duplicated by any of the CSS3 modules below have
+    ;; been removed.
+    "azimuth" "border-collapse" "border-spacing" "bottom"
+    "caption-side" "clear" "clip" "content" "counter-increment"
+    "counter-reset" "cue" "cue-after" "cue-before" "direction" "display"
+    "elevation" "empty-cells" "float" "height" "left" "line-height"
+    "list-style" "list-style-image" "list-style-position"
+    "list-style-type" "margin" "margin-bottom" "margin-left"
+    "margin-right" "margin-top" "max-height" "max-width" "min-height"
+    "min-width" "orphans" "overflow" "padding" "padding-bottom"
+    "padding-left" "padding-right" "padding-top" "page-break-after"
+    "page-break-before" "page-break-inside" "pause" "pause-after"
+    "pause-before" "pitch" "pitch-range" "play-during" "position"
+    "quotes" "richness" "right" "speak" "speak-header" "speak-numeral"
+    "speak-punctuation" "speech-rate" "stress" "table-layout" "top"
+    "unicode-bidi" "vertical-align" "visibility" "voice-family" "volume"
+    "widows" "width" "z-index"
+
+    ;; CSS Animations
+    ;; (http://www.w3.org/TR/css3-animations/#property-index)
+    "animation" "animation-delay" "animation-direction"
+    "animation-duration" "animation-fill-mode"
+    "animation-iteration-count" "animation-name"
+    "animation-play-state" "animation-timing-function"
+
+    ;; CSS Backgrounds and Borders Module Level 3
+    ;; (http://www.w3.org/TR/css3-background/#property-index)
+    "background" "background-attachment" "background-clip"
+    "background-color" "background-image" "background-origin"
+    "background-position" "background-repeat" "background-size"
+    "border" "border-bottom" "border-bottom-color"
+    "border-bottom-left-radius" "border-bottom-right-radius"
+    "border-bottom-style" "border-bottom-width" "border-color"
+    "border-image" "border-image-outset" "border-image-repeat"
+    "border-image-slice" "border-image-source" "border-image-width"
+    "border-left" "border-left-color" "border-left-style"
+    "border-left-width" "border-radius" "border-right"
     "border-right-color" "border-right-style" "border-right-width"
-    "border-spacing" "border-style" "border-top" "border-top-color"
-    "border-top-style" "border-top-width" "border-width" "bottom"
-    "caption-side" "clear" "clip" "color" "compact" "content"
-    "counter-increment" "counter-reset" "cue" "cue-after" "cue-before"
-    "cursor" "dashed" "direction" "display" "dotted" "double" "elevation"
-    "empty-cells" "float" "font" "font-family" "font-size" "font-size-adjust"
-    "font-stretch" "font-style" "font-variant" "font-weight" "groove" "height"
-    "hidden" "inline" "inline-table" "inset" "left" "letter-spacing"
-    "line-height" "list-item" "list-style" "list-style-image"
-    "list-style-position" "list-style-type" "margin" "margin-bottom"
-    "margin-left" "margin-right" "margin-top" "marker-offset" "marks"
-    "max-height" "max-width" "min-height" "min-width" "orphans" "outline"
-    "outline-color" "outline-style" "outline-width" "outset" "overflow"
-    "padding" "padding-bottom" "padding-left" "padding-right" "padding-top"
-    "page" "page-break-after" "page-break-before" "page-break-inside" "pause"
-    "pause-after" "pause-before" "pitch" "pitch-range" "play-during" "position"
-    "quotes" "richness" "ridge" "right" "run-in" "size" "solid" "speak"
-    "speak-header" "speak-numeral" "speak-punctuation" "speech-rate" "stress"
-    "table" "table-caption" "table-cell" "table-column" "table-column-group"
-    "table-footer-group" "table-header-group" "table-layout" "table-row"
-    "table-row-group" "text-align" "text-decoration" "text-indent"
-    "text-shadow" "text-transform" "top" "unicode-bidi" "vertical-align"
-    "visibility" "voice-family" "volume" "white-space" "widows" "width"
-    "word-spacing" "z-index")
+    "border-style" "border-top" "border-top-color"
+    "border-top-left-radius" "border-top-right-radius"
+    "border-top-style" "border-top-width" "border-width" "box-shadow"
+
+    ;; CSS Basic User Interface Module Level 3 (CSS3 UI)
+    ;; (http://www.w3.org/TR/css3-ui/#property-index)
+    "box-sizing" "caret-color" "cursor" "nav-down" "nav-left"
+    "nav-right" "nav-up" "outline" "outline-color" "outline-offset"
+    "outline-style" "outline-width" "resize" "text-overflow"
+
+    ;; CSS Color Module Level 3
+    ;; (http://www.w3.org/TR/css3-color/#property)
+    "color" "opacity"
+
+    ;; CSS Flexible Box Layout Module Level 1
+    ;; (http://www.w3.org/TR/css-flexbox-1/#property-index)
+    "align-content" "align-items" "align-self" "flex" "flex-basis"
+    "flex-direction" "flex-flow" "flex-grow" "flex-shrink" "flex-wrap"
+    "justify-content" "order"
+
+    ;; CSS Fonts Module Level 3
+    ;; (http://www.w3.org/TR/css3-fonts/#property-index)
+    "font" "font-family" "font-feature-settings" "font-kerning"
+    "font-language-override" "font-size" "font-size-adjust"
+    "font-stretch" "font-style" "font-synthesis" "font-variant"
+    "font-variant-alternates" "font-variant-caps"
+    "font-variant-east-asian" "font-variant-ligatures"
+    "font-variant-numeric" "font-variant-position" "font-weight"
+
+    ;; CSS Text Decoration Module Level 3
+    ;; (http://dev.w3.org/csswg/css-text-decor-3/#property-index)
+    "text-decoration" "text-decoration-color" "text-decoration-line"
+    "text-decoration-skip" "text-decoration-style" "text-emphasis"
+    "text-emphasis-color" "text-emphasis-position" "text-emphasis-style"
+    "text-shadow" "text-underline-position"
+
+    ;; CSS Text Module Level 3
+    ;; (http://www.w3.org/TR/css3-text/#property-index)
+    "hanging-punctuation" "hyphens" "letter-spacing" "line-break"
+    "overflow-wrap" "tab-size" "text-align" "text-align-last"
+    "text-indent" "text-justify" "text-transform" "white-space"
+    "word-break" "word-spacing" "word-wrap"
+
+    ;; CSS Transforms Module Level 1
+    ;; (http://www.w3.org/TR/css3-2d-transforms/#property-index)
+    "backface-visibility" "perspective" "perspective-origin"
+    "transform" "transform-origin" "transform-style"
+
+    ;; CSS Transitions
+    ;; (http://www.w3.org/TR/css3-transitions/#property-index)
+    "transition" "transition-delay" "transition-duration"
+    "transition-property" "transition-timing-function"
+
+    ;; Filter Effects Module Level 1
+    ;; (http://www.w3.org/TR/filter-effects/#property-index)
+    "color-interpolation-filters" "filter" "flood-color"
+    "flood-opacity" "lighting-color")
   "Identifiers for properties.")
 
 (defcustom css-electric-keys '(?\} ?\;) ;; '()
@@ -258,7 +250,11 @@
          (concat "\\(?:" scss--hash-re
                  "\\|[^@/:{} \t\n#]\\)"
                  "[^:{}#]*\\(?:" scss--hash-re "[^:{}#]*\\)*"))
-       "\\(?::" (regexp-opt css-pseudo-ids t)
+       ;; Even though pseudo-elements should be prefixed by ::, a
+       ;; single colon is accepted for backward compatibility.
+       "\\(?:\\(:" (regexp-opt (append css-pseudo-class-ids
+                                       css-pseudo-element-ids) t)
+       "\\|\\::" (regexp-opt css-pseudo-element-ids t) "\\)"
        "\\(?:([^\)]+)\\)?"
        (if (not sassy)
            "[^:{}\n]*"
@@ -334,6 +330,45 @@
     (`(:before . ,(or "{" "("))
      (if (smie-rule-hanging-p) (smie-rule-parent 0)))))
 
+;;; Completion
+
+(defun css--complete-property ()
+  "Complete property at point."
+  (save-excursion
+    (let ((pos (point)))
+      (skip-chars-backward "-[:alnum:]")
+      (let ((start (point)))
+        (skip-chars-backward " \t\r\n")
+        (when (memq (char-before) '(?\{ ?\;))
+          (list start pos css-property-ids))))))
+
+(defun css--complete-pseudo-element-or-class ()
+  "Complete pseudo-element or pseudo-class at point."
+  (save-excursion
+    (let ((pos (point)))
+      (skip-chars-backward "-[:alnum:]")
+      (when (eq (char-before) ?\:)
+        (list (point) pos
+              (if (eq (char-before (- (point) 1)) ?\:)
+                  css-pseudo-element-ids
+                css-pseudo-class-ids))))))
+
+(defun css--complete-at-rule ()
+  "Complete at-rule (statement beginning with `@') at point."
+  (save-excursion
+    (let ((pos (point)))
+      (skip-chars-backward "-[:alnum:]")
+      (when (eq (char-before) ?\@)
+        (list (point) pos css-at-ids)))))
+
+(defun css-completion-at-point ()
+  "Complete current symbol at point.
+Currently supports completion of CSS properties, pseudo-elements,
+pseudo-classes, and at-rules."
+  (or (css--complete-property)
+      (css--complete-pseudo-element-or-class)
+      (css--complete-at-rule)))
+
 ;;;###autoload
 (define-derived-mode css-mode fundamental-mode "CSS"
   "Major mode to edit Cascading Style Sheets."
@@ -349,7 +384,9 @@
               :forward-token #'css-smie--forward-token
               :backward-token #'css-smie--backward-token)
   (setq-local electric-indent-chars
-              (append css-electric-keys electric-indent-chars)))
+              (append css-electric-keys electric-indent-chars))
+  (add-hook 'completion-at-point-functions
+            #'css-completion-at-point nil 'local))
 
 (defvar comment-continue)
 
diff --git a/lwlib/ChangeLog b/lwlib/ChangeLog
index c98d725..e5dfed2 100644
--- a/lwlib/ChangeLog
+++ b/lwlib/ChangeLog
@@ -1,3 +1,7 @@
+2015-03-18  Stefan Monnier  <address@hidden>
+
+       * xlwmenu.c (pop_up_menu): Remove debugging code.
+
 2015-02-28  Jan Djärv  <address@hidden>
 
        * xlwmenu.c (remap_menubar): Re-realize menu to force move under
diff --git a/lwlib/xlwmenu.c b/lwlib/xlwmenu.c
index f781b7e..9317dea 100644
--- a/lwlib/xlwmenu.c
+++ b/lwlib/xlwmenu.c
@@ -1719,7 +1719,7 @@ make_shadow_gcs (XlwMenuWidget mw)
                                            1.2, 0x8000))
 #else
       XQueryColor (dpy, cmap, &topc);
-      /* don't overflow/wrap! */
+      /* Don't overflow/wrap!  */
       topc.red   = MINL (65535, topc.red   * 1.2);
       topc.green = MINL (65535, topc.green * 1.2);
       topc.blue  = MINL (65535, topc.blue  * 1.2);
@@ -1780,8 +1780,8 @@ make_shadow_gcs (XlwMenuWidget mw)
        }
     }
 
-  if (!mw->menu.top_shadow_pixmap &&
-      mw->menu.top_shadow_color == mw->core.background_pixel)
+  if (!mw->menu.top_shadow_pixmap
+      && mw->menu.top_shadow_color == mw->core.background_pixel)
     {
       mw->menu.top_shadow_pixmap = mw->menu.gray_pixmap;
       if (mw->menu.free_top_shadow_color_p)
@@ -1791,8 +1791,8 @@ make_shadow_gcs (XlwMenuWidget mw)
        }
       mw->menu.top_shadow_color = mw->menu.foreground;
     }
-  if (!mw->menu.bottom_shadow_pixmap &&
-      mw->menu.bottom_shadow_color == mw->core.background_pixel)
+  if (!mw->menu.bottom_shadow_pixmap
+      && mw->menu.bottom_shadow_color == mw->core.background_pixel)
     {
       mw->menu.bottom_shadow_pixmap = mw->menu.gray_pixmap;
       if (mw->menu.free_bottom_shadow_color_p)
@@ -1856,7 +1856,7 @@ openXftFont (XlwMenuWidget mw)
   if (fname && strcmp (fname, "none") != 0)
     {
       int screen = XScreenNumberOfScreen (mw->core.screen);
-      int len = strlen (fname), i = len-1;
+      int len = strlen (fname), i = len - 1;
       /* Try to convert Gtk-syntax (Sans 9) to Xft syntax Sans-9.  */
       while (i > 0 && '0' <= fname[i] && fname[i] <= '9')
         --i;
@@ -1880,7 +1880,7 @@ openXftFont (XlwMenuWidget mw)
 static void
 XlwMenuInitialize (Widget request, Widget w, ArgList args, Cardinal *num_args)
 {
-  /* Get the GCs and the widget size */
+  /* Get the GCs and the widget size.  */
   XlwMenuWidget mw = (XlwMenuWidget) w;
   Window window = RootWindowOfScreen (DefaultScreenOfDisplay (XtDisplay (mw)));
   Display* display = XtDisplay (mw);
@@ -2014,7 +2014,7 @@ XlwMenuRealize (Widget w, Mask *valueMask, 
XSetWindowAttributes *attributes)
 
 /* Only the toplevel menubar/popup is a widget so it's the only one that
    receives expose events through Xt.  So we repaint all the other panes
-   when receiving an Expose event. */
+   when receiving an Expose event.  */
 static void
 XlwMenuRedisplay (Widget w, XEvent *ev, Region region)
 {
@@ -2056,14 +2056,14 @@ XlwMenuDestroy (Widget w)
   release_drawing_gcs (mw);
   release_shadow_gcs (mw);
 
-  /* this doesn't come from the resource db but is created explicitly
-     so we must free it ourselves. */
+  /* This doesn't come from the resource db but is created explicitly
+     so we must free it ourselves.  */
   XFreePixmap (XtDisplay (mw), mw->menu.gray_pixmap);
   mw->menu.gray_pixmap = (Pixmap) -1;
 
   /* Don't free mw->menu.contents because that comes from our creator.
      The `*_stack' elements are just pointers into `contents' so leave
-     that alone too.  But free the stacks themselves. */
+     that alone too.  But free the stacks themselves.  */
   if (mw->menu.old_stack) XtFree ((char *) mw->menu.old_stack);
   if (mw->menu.new_stack) XtFree ((char *) mw->menu.new_stack);
 
@@ -2093,7 +2093,7 @@ XlwMenuDestroy (Widget w)
 
   if (mw->menu.windows [0].pixmap != None)
     XFreePixmap (XtDisplay (mw), mw->menu.windows [0].pixmap);
-  /* start from 1 because the one in slot 0 is w->core.window */
+  /* Start from 1 because the one in slot 0 is w->core.window.  */
   for (i = 1; i < mw->menu.windows_length; i++)
     {
       if (mw->menu.windows [i].pixmap != None)
@@ -2170,7 +2170,7 @@ XlwMenuSetValues (Widget current, Widget request, Widget 
new,
            XSetWindowBackground (XtDisplay (oldmw),
                                  oldmw->menu.windows [i].window,
                                  newmw->core.background_pixel);
-           /* clear windows and generate expose events */
+           /* Clear windows and generate expose events.  */
            XClearArea (XtDisplay (oldmw), oldmw->menu.windows[i].window,
                        0, 0, 0, 0, True);
          }
@@ -2244,7 +2244,7 @@ handle_single_motion_event (XlwMenuWidget mw, 
XMotionEvent *ev)
     set_new_state (mw, val, level);
   remap_menubar (mw);
 
-  /* Sync with the display.  Makes it feel better on X terms. */
+  /* Sync with the display.  Makes it feel better on X terms.  */
   XSync (XtDisplay (mw), False);
 }
 
@@ -2256,7 +2256,7 @@ handle_motion_event (XlwMenuWidget mw, XMotionEvent *ev)
   int state = ev->state;
   XMotionEvent oldev = *ev;
 
-  /* allow motion events to be generated again */
+  /* Allow motion events to be generated again.  */
   if (ev->is_hint
       && XQueryPointer (XtDisplay (mw), ev->window,
                        &ev->root, &ev->subwindow,
@@ -2293,11 +2293,11 @@ Start (Widget w, XEvent *ev, String *params, Cardinal 
*num_params)
         releasing the button should always pop the menu down.  */
       next_release_must_exit = 1;
 
-      /* notes the absolute position of the menubar window */
+      /* Notes the absolute position of the menubar window.  */
       mw->menu.windows [0].x = ev->xmotion.x_root - ev->xmotion.x;
       mw->menu.windows [0].y = ev->xmotion.y_root - ev->xmotion.y;
 
-      /* handles the down like a move, slots are compatible */
+      /* Handles the down like a move, slots are compatible.  */
       ev->xmotion.is_hint = 0;
       handle_motion_event (mw, &ev->xmotion);
     }
@@ -2327,7 +2327,7 @@ find_first_selectable (XlwMenuWidget mw, widget_value 
*item, int skip_titles)
   while (lw_separator_p (current->name, &separator, 0) || !current->enabled
          || (skip_titles && !current->call_data && !current->contents))
     if (current->next)
-      current=current->next;
+      current = current->next;
     else
       return NULL;
 
@@ -2340,9 +2340,9 @@ find_next_selectable (XlwMenuWidget mw, widget_value 
*item, int skip_titles)
   widget_value *current = item;
   enum menu_separator separator;
 
-  while (current->next && (current=current->next) &&
-        (lw_separator_p (current->name, &separator, 0) || !current->enabled
-          || (skip_titles && !current->call_data && !current->contents)))
+  while (current->next && (current = current->next)
+        && (lw_separator_p (current->name, &separator, 0) || !current->enabled
+            || (skip_titles && !current->call_data && !current->contents)))
     ;
 
   if (current == item)
@@ -2357,7 +2357,7 @@ find_next_selectable (XlwMenuWidget mw, widget_value 
*item, int skip_titles)
                  && !current->contents))
        {
          if (current->next)
-           current=current->next;
+           current = current->next;
 
          if (current == item)
            break;
@@ -2374,12 +2374,12 @@ find_prev_selectable (XlwMenuWidget mw, widget_value 
*item, int skip_titles)
   widget_value *current = item;
   widget_value *prev = item;
 
-  while ((current=find_next_selectable (mw, current, skip_titles))
+  while ((current = find_next_selectable (mw, current, skip_titles))
          != item)
     {
       if (prev == current)
        break;
-      prev=current;
+      prev = current;
     }
 
   return prev;
@@ -2560,7 +2560,7 @@ Select (Widget w, XEvent *ev, String *params, Cardinal 
*num_params)
          < XtGetMultiClickTime (XtDisplay (w))))
     return;
 
-  /* pop down everything.  */
+  /* Pop down everything.  */
   mw->menu.new_depth = 1;
   remap_menubar (mw);
 
@@ -2582,7 +2582,7 @@ Select (Widget w, XEvent *ev, String *params, Cardinal 
*num_params)
 }
 
 
-/* Special code to pop-up a menu */
+/* Special code to pop-up a menu.  */
 static void
 pop_up_menu (XlwMenuWidget mw, XButtonPressedEvent *event)
 {
@@ -2619,14 +2619,14 @@ pop_up_menu (XlwMenuWidget mw, XButtonPressedEvent 
*event)
   mw->menu.popped_up = True;
   if (XtIsShell (XtParent ((Widget)mw)))
     {
-      fprintf(stderr, "Config %d %d\n", x, y);
+      /* fprintf (stderr, "Config %d %d\n", x, y); */
       XtConfigureWidget (XtParent ((Widget)mw), x, y, w, h,
                         XtParent ((Widget)mw)->core.border_width);
       XtPopup (XtParent ((Widget)mw), XtGrabExclusive);
       display_menu (mw, 0, False, NULL, NULL, NULL);
       mw->menu.windows [0].x = x + borderwidth;
       mw->menu.windows [0].y = y + borderwidth;
-      mw->menu.top_depth = 1;  /* Popup menus don't have a bar so top is 1  */
+      mw->menu.top_depth = 1;  /* Popup menus don't have a bar so top is 1.  */
     }
   else
     {
@@ -2634,7 +2634,7 @@ pop_up_menu (XlwMenuWidget mw, XButtonPressedEvent *event)
 
       XtAddGrab ((Widget) mw, True, True);
 
-      /* notes the absolute position of the menubar window */
+      /* Notes the absolute position of the menubar window.  */
       mw->menu.windows [0].x = ev->xmotion.x_root - ev->xmotion.x;
       mw->menu.windows [0].y = ev->xmotion.y_root - ev->xmotion.y;
       mw->menu.top_depth = 2;
diff --git a/m4/dirfd.m4 b/m4/dirfd.m4
new file mode 100644
index 0000000..ce56cff
--- /dev/null
+++ b/m4/dirfd.m4
@@ -0,0 +1,83 @@
+# serial 22   -*- Autoconf -*-
+
+dnl Find out how to get the file descriptor associated with an open DIR*.
+
+# Copyright (C) 2001-2006, 2008-2015 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+dnl From Jim Meyering
+
+AC_DEFUN([gl_FUNC_DIRFD],
+[
+  AC_REQUIRE([gl_DIRENT_H_DEFAULTS])
+
+  dnl Persuade glibc <dirent.h> to declare dirfd().
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+  AC_CHECK_FUNCS([dirfd])
+  AC_CHECK_DECLS([dirfd], , ,
+    [[#include <sys/types.h>
+      #include <dirent.h>]])
+  if test $ac_cv_have_decl_dirfd = no; then
+    HAVE_DECL_DIRFD=0
+  fi
+
+  AC_CACHE_CHECK([whether dirfd is a macro],
+    gl_cv_func_dirfd_macro,
+    [AC_EGREP_CPP([dirent_header_defines_dirfd], [
+#include <sys/types.h>
+#include <dirent.h>
+#ifdef dirfd
+ dirent_header_defines_dirfd
+#endif],
+       gl_cv_func_dirfd_macro=yes,
+       gl_cv_func_dirfd_macro=no)])
+
+  # Use the replacement only if we have no function or macro with that name.
+  if test $ac_cv_func_dirfd = no && test $gl_cv_func_dirfd_macro = no; then
+    if test $ac_cv_have_decl_dirfd = yes; then
+      # If the system declares dirfd already, let's declare rpl_dirfd instead.
+      REPLACE_DIRFD=1
+    fi
+  fi
+])
+
+dnl Prerequisites of lib/dirfd.c.
+AC_DEFUN([gl_PREREQ_DIRFD],
+[
+  AC_CACHE_CHECK([how to get the file descriptor associated with an open DIR*],
+                 [gl_cv_sys_dir_fd_member_name],
+    [
+      dirfd_save_CFLAGS=$CFLAGS
+      for ac_expr in d_fd dd_fd; do
+
+        CFLAGS="$CFLAGS -DDIR_FD_MEMBER_NAME=$ac_expr"
+        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+           #include <sys/types.h>
+           #include <dirent.h>]],
+          [[DIR *dir_p = opendir("."); (void) dir_p->DIR_FD_MEMBER_NAME;]])],
+          [dir_fd_found=yes]
+        )
+        CFLAGS=$dirfd_save_CFLAGS
+        test "$dir_fd_found" = yes && break
+      done
+      test "$dir_fd_found" = yes || ac_expr=no_such_member
+
+      gl_cv_sys_dir_fd_member_name=$ac_expr
+    ]
+  )
+  if test $gl_cv_sys_dir_fd_member_name != no_such_member; then
+    AC_DEFINE_UNQUOTED([DIR_FD_MEMBER_NAME],
+      [$gl_cv_sys_dir_fd_member_name],
+      [the name of the file descriptor member of DIR])
+  fi
+  AH_VERBATIM([DIR_TO_FD],
+              [#ifdef DIR_FD_MEMBER_NAME
+# define DIR_TO_FD(Dir_p) ((Dir_p)->DIR_FD_MEMBER_NAME)
+#else
+# define DIR_TO_FD(Dir_p) -1
+#endif
+])
+])
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 5763fae..949dd0e 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -56,6 +56,7 @@ AC_DEFUN([gl_EARLY],
   # Code from module crypto/sha256:
   # Code from module crypto/sha512:
   # Code from module dirent:
+  # Code from module dirfd:
   # Code from module dosname:
   # Code from module dtoastr:
   # Code from module dtotimespec:
@@ -394,6 +395,7 @@ AC_DEFUN([gl_INIT],
   gl_UTIMENS
   AC_C_VARARRAYS
   gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b=false
+  gl_gnulib_enabled_dirfd=false
   gl_gnulib_enabled_dosname=false
   gl_gnulib_enabled_euidaccess=false
   gl_gnulib_enabled_getdtablesize=false
@@ -416,6 +418,18 @@ AC_DEFUN([gl_INIT],
       gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b=true
     fi
   }
+  func_gl_gnulib_m4code_dirfd ()
+  {
+    if ! $gl_gnulib_enabled_dirfd; then
+      gl_FUNC_DIRFD
+      if test $ac_cv_func_dirfd = no && test $gl_cv_func_dirfd_macro = no; then
+        AC_LIBOBJ([dirfd])
+        gl_PREREQ_DIRFD
+      fi
+      gl_DIRENT_MODULE_INDICATOR([dirfd])
+      gl_gnulib_enabled_dirfd=true
+    fi
+  }
   func_gl_gnulib_m4code_dosname ()
   {
     if ! $gl_gnulib_enabled_dosname; then
@@ -595,6 +609,9 @@ AC_DEFUN([gl_INIT],
   if test $HAVE_FDOPENDIR = 0; then
     func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b
   fi
+  if test $HAVE_FDOPENDIR = 0; then
+    func_gl_gnulib_m4code_dirfd
+  fi
   if test $HAVE_FSTATAT = 0 || test $REPLACE_FSTATAT = 1; then
     func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b
   fi
@@ -636,6 +653,7 @@ AC_DEFUN([gl_INIT],
   fi
   m4_pattern_allow([^gl_GNULIB_ENABLED_])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b], 
[$gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b])
+  AM_CONDITIONAL([gl_GNULIB_ENABLED_dirfd], [$gl_gnulib_enabled_dirfd])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_dosname], [$gl_gnulib_enabled_dosname])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_euidaccess], 
[$gl_gnulib_enabled_euidaccess])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_getdtablesize], 
[$gl_gnulib_enabled_getdtablesize])
@@ -822,6 +840,7 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/count-trailing-zeros.c
   lib/count-trailing-zeros.h
   lib/dirent.in.h
+  lib/dirfd.c
   lib/dosname.h
   lib/dtoastr.c
   lib/dtotimespec.c
@@ -940,6 +959,7 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/count-one-bits.m4
   m4/count-trailing-zeros.m4
   m4/dirent_h.m4
+  m4/dirfd.m4
   m4/dup2.m4
   m4/environ.m4
   m4/errno_h.m4
diff --git a/src/ChangeLog b/src/ChangeLog
index fbf8fb4..bdec3c9 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,12 @@
+2015-03-18  Glenn Morris  <address@hidden>
+
+       * frame.h (x_set_bitmap_icon): Don't set the icon if icon-type is
+       nil/not present in the parameter alist.  (Bug#19680)
+
+2015-03-18  Stefan Monnier  <address@hidden>
+
+       * alloc.c (purecopy): Handle hash-tables.
+
 2015-03-16  Stefan Monnier  <address@hidden>
 
        * minibuf.c (Fread_buffer): Add `predicate' argument.
@@ -6,13 +15,11 @@
 2015-03-15  Eli Zaretskii  <address@hidden>
 
        * xdisp.c (handle_invisible_prop): Fix up it->position even when
-       we are going to load overlays at the beginning of the invisible
-       text.
+       we are going to load overlays at the beginning of the invisible text.
        (setup_for_ellipsis): Reset the ignore_overlay_strings_at_pos_p
        flag also here.
        (next_overlay_string): Set the overlay_strings_at_end_processed_p
-       flag only if the overlays just processed were actually loaded at
-       EOB.
+       flag only if the overlays just processed were actually loaded at EOB.
 
 2015-03-14  Daniel Colascione  <address@hidden>
 
@@ -183,8 +190,8 @@
 
 2015-02-28  Martin Rudalics  <address@hidden>
 
-       * frame.c (make_initial_frame, Fmake_terminal_frame): Set
-       can_x_set_window_size and after_make_frame (Bug#19962).
+       * frame.c (make_initial_frame, Fmake_terminal_frame):
+       Set can_x_set_window_size and after_make_frame (Bug#19962).
 
 2015-02-28  Eli Zaretskii  <address@hidden>
 
@@ -454,8 +461,8 @@
 
        * indent.c (Fvertical_motion): Accept an additional argument
        CUR-COL and use it as the starting screen coordinate.
-       * window.c (window_scroll_line_based, Fmove_to_window_line): All
-       callers of vertical-motion changed.
+       * window.c (window_scroll_line_based, Fmove_to_window_line):
+       All callers of vertical-motion changed.
 
 2015-02-09  Dima Kogan  <address@hidden>
 
diff --git a/src/alloc.c b/src/alloc.c
index 0227825..1f4b1a4 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -3423,7 +3423,7 @@ union aligned_Lisp_Misc
 };
 
 /* Allocation of markers and other objects that share that structure.
-   Works like allocation of conses. */
+   Works like allocation of conses.  */
 
 #define MARKER_BLOCK_SIZE \
   ((1020 - sizeof (struct marker_block *)) / sizeof (union aligned_Lisp_Misc))
@@ -4744,7 +4744,7 @@ mark_maybe_pointer (void *p)
 #endif
 
 /* Mark Lisp objects referenced from the address range START+OFFSET..END
-   or END+OFFSET..START. */
+   or END+OFFSET..START.  */
 
 static void ATTRIBUTE_NO_SANITIZE_ADDRESS
 mark_memory (void *start, void *end)
@@ -5356,7 +5356,6 @@ make_pure_vector (ptrdiff_t len)
   return new;
 }
 
-
 DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0,
        doc: /* Make a copy of object OBJ in pure storage.
 Recursively copies contents of vectors and cons cells.
@@ -5391,28 +5390,26 @@ purecopy (Lisp_Object obj)
   else if (FLOATP (obj))
     obj = make_pure_float (XFLOAT_DATA (obj));
   else if (STRINGP (obj))
-    obj = make_pure_string (SSDATA (obj), SCHARS (obj),
-                           SBYTES (obj),
-                           STRING_MULTIBYTE (obj));
-  else if (COMPILEDP (obj) || VECTORP (obj))
     {
-      register struct Lisp_Vector *vec;
+      if (XSTRING (obj)->intervals)
+       message ("Dropping text-properties when making string pure");
+      obj = make_pure_string (SSDATA (obj), SCHARS (obj),
+                             SBYTES (obj),
+                             STRING_MULTIBYTE (obj));
+    }
+  else if (COMPILEDP (obj) || VECTORP (obj) || HASH_TABLE_P (obj))
+    {
+      struct Lisp_Vector *objp = XVECTOR (obj);
+      ptrdiff_t nbytes = vector_nbytes (objp);
+      struct Lisp_Vector *vec = pure_alloc (nbytes, Lisp_Vectorlike);
       register ptrdiff_t i;
-      ptrdiff_t size;
-
-      size = ASIZE (obj);
+      ptrdiff_t size = ASIZE (obj);
       if (size & PSEUDOVECTOR_FLAG)
        size &= PSEUDOVECTOR_SIZE_MASK;
-      vec = XVECTOR (make_pure_vector (size));
+      memcpy (vec, objp, nbytes);
       for (i = 0; i < size; i++)
-       vec->contents[i] = purecopy (AREF (obj, i));
-      if (COMPILEDP (obj))
-       {
-         XSETPVECTYPE (vec, PVEC_COMPILED);
-         XSETCOMPILED (obj, vec);
-       }
-      else
-       XSETVECTOR (obj, vec);
+       vec->contents[i] = purecopy (vec->contents[i]);
+      XSETVECTOR (obj, vec);
     }
   else if (SYMBOLP (obj))
     {
@@ -5422,6 +5419,7 @@ purecopy (Lisp_Object obj)
          XSYMBOL (obj)->pinned = true;
          symbol_block_pinned = symbol_block;
        }
+      /* Don't hash-cons it.  */
       return obj;
     }
   else
@@ -6229,13 +6227,14 @@ mark_discard_killed_buffers (Lisp_Object list)
 void
 mark_object (Lisp_Object arg)
 {
-  register Lisp_Object obj = arg;
+  register Lisp_Object obj;
   void *po;
 #ifdef GC_CHECK_MARKED_OBJECTS
   struct mem_node *m;
 #endif
   ptrdiff_t cdr_count = 0;
 
+  obj = arg;
  loop:
 
   po = XPNTR (obj);
@@ -6870,7 +6869,7 @@ sweep_symbols (void)
   total_free_symbols = num_free;
 }
 
-NO_INLINE /* For better stack traces */
+NO_INLINE /* For better stack traces.  */
 static void
 sweep_misc (void)
 {
diff --git a/src/frame.h b/src/frame.h
index ddbf93e..d4dfd1c 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -1425,7 +1425,7 @@ x_set_bitmap_icon (struct frame *f)
 {
   Lisp_Object obj = assq_no_quit (Qicon_type, f->param_alist);
 
-  if (CONSP (obj))
+  if (CONSP (obj) && !NILP (XCDR (obj)))
     x_bitmap_icon (f, XCDR (obj));
 }
 
diff --git a/test/ChangeLog b/test/ChangeLog
index e150aba..15408a3 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,16 @@
+2015-03-19  Stefan Monnier  <address@hidden>
+
+       * automated/eieio-tests.el (eieio-test-17-virtual-slot): Don't use
+       initarg in `oset'.
+       (eieio-test-32-slot-attribute-override-2): Adjust to new
+       slot representation.
+
+       * automated/eieio-test-persist.el (persist-test-save-and-compare):
+       Adjust to new slot representation.
+
+       * automated/eieio-test-methodinvoke.el (make-instance): Use new-style
+       `subclass' specializer for a change.
+
 2015-03-17  Stefan Monnier  <address@hidden>
 
        * automated/cl-lib-tests.el: Use lexical-binding.
diff --git a/test/automated/eieio-test-methodinvoke.el 
b/test/automated/eieio-test-methodinvoke.el
index 62f5603..52630134 100644
--- a/test/automated/eieio-test-methodinvoke.el
+++ b/test/automated/eieio-test-methodinvoke.el
@@ -184,7 +184,7 @@
   (if (next-method-p) (call-next-method))
   )
 
-(defmethod make-instance :STATIC ((p C) &rest args)
+(cl-defmethod make-instance ((p (subclass C)) &rest args)
   (eieio-test-method-store :STATIC 'C)
   (call-next-method)
   )
diff --git a/test/automated/eieio-test-persist.el 
b/test/automated/eieio-test-persist.el
index 7bb2f1c..6710ead 100644
--- a/test/automated/eieio-test-persist.el
+++ b/test/automated/eieio-test-persist.el
@@ -45,20 +45,20 @@ This is usually a symbol that starts with `:'."
 
   (eieio-persistent-save original)
 
-  (let* ((file (oref original :file))
+  (let* ((file (oref original file))
         (class (eieio-object-class original))
         (fromdisk (eieio-persistent-read file class))
         (cv (eieio--class-v class))
-        (slot-names  (eieio--class-public-a cv))
-        (slot-deflt  (eieio--class-public-d cv))
+        (slots  (eieio--class-slots cv))
         )
     (unless (object-of-class-p fromdisk class)
       (error "Persistent class %S != original class %S"
             (eieio-object-class fromdisk)
             class))
 
-    (while slot-names
-      (let* ((oneslot (car slot-names))
+    (dotimes (i (length slots))
+      (let* ((slot (aref slots i))
+             (oneslot (cl--slot-descriptor-name slot))
             (origvalue (eieio-oref original oneslot))
             (fromdiskvalue (eieio-oref fromdisk oneslot))
             (initarg-p (eieio--attribute-to-initarg
@@ -70,12 +70,9 @@ This is usually a symbol that starts with `:'."
              (error "Slot %S Original Val %S != Persistent Val %S"
                     oneslot origvalue fromdiskvalue))
          ;; Else !initarg-p
-         (unless (equal (car slot-deflt) fromdiskvalue)
+         (unless (equal (cl--slot-descriptor-initform slot) fromdiskvalue)
            (error "Slot %S Persistent Val %S != Default Value %S"
-                  oneslot fromdiskvalue (car slot-deflt))))
-       
-       (setq slot-names (cdr slot-names)
-             slot-deflt (cdr slot-deflt))
+                  oneslot fromdiskvalue (cl--slot-descriptor-initform slot))))
        ))))
 
 ;;; Simple Case
diff --git a/test/automated/eieio-tests.el b/test/automated/eieio-tests.el
index 7532609..01131d8 100644
--- a/test/automated/eieio-tests.el
+++ b/test/automated/eieio-tests.el
@@ -406,21 +406,21 @@ METHOD is the method that was attempting to be called."
 (ert-deftest eieio-test-17-virtual-slot ()
   (setq eitest-vsca (virtual-slot-class :base-value 1))
   ;; Check slot values
-  (should (= (oref eitest-vsca :base-value) 1))
+  (should (= (oref eitest-vsca base-value) 1))
   (should (= (oref eitest-vsca :derived-value) 2))
 
-  (oset eitest-vsca :derived-value 3)
-  (should (= (oref eitest-vsca :base-value) 2))
+  (oset eitest-vsca derived-value 3)
+  (should (= (oref eitest-vsca base-value) 2))
   (should (= (oref eitest-vsca :derived-value) 3))
 
-  (oset eitest-vsca :base-value 3)
-  (should (= (oref eitest-vsca :base-value) 3))
+  (oset eitest-vsca base-value 3)
+  (should (= (oref eitest-vsca base-value) 3))
   (should (= (oref eitest-vsca :derived-value) 4))
 
   ;; should also be possible to initialize instance using virtual slot
 
   (setq eitest-vscb (virtual-slot-class :derived-value 5))
-  (should (= (oref eitest-vscb :base-value) 4))
+  (should (= (oref eitest-vscb base-value) 4))
   (should (= (oref eitest-vscb :derived-value) 5)))
 
 (ert-deftest eieio-test-18-slot-unbound ()
@@ -560,7 +560,8 @@ METHOD is the method that was attempting to be called."
   (setq eitest-t1 (class-c))
   ;; Slot initialization
   (should (eq (oref eitest-t1 slot-1) 'moose))
-  (should (eq (oref eitest-t1 :moose) 'moose))
+  ;; Accessing via the initarg name is deprecated!
+  ;; (should (eq (oref eitest-t1 :moose) 'moose))
   ;; Don't pass reference of private slot
   ;;PRIVATE (should-error (oref eitest-t1 slot-2) :type 'invalid-slot-name)
   ;; Check private slot accessor
@@ -580,7 +581,8 @@ METHOD is the method that was attempting to be called."
   ;; See previous test, nor for subclass
   (setq eitest-t2 (class-subc))
   (should (eq (oref eitest-t2 slot-1) 'moose))
-  (should (eq (oref eitest-t2 :moose) 'moose))
+  ;; Accessing via the initarg name is deprecated!
+  ;;(should (eq (oref eitest-t2 :moose) 'moose))
   (should (string= (get-slot-2 eitest-t2) "linux"))
   ;;PRIVATE (should-error (oref eitest-t2 slot-2) :type 'invalid-slot-name)
   (should (string= (get-slot-2 eitest-t2) "linux"))
@@ -802,30 +804,24 @@ Subclasses to override slot attributes.")
 
 (ert-deftest eieio-test-32-slot-attribute-override-2 ()
   (let* ((cv (eieio--class-v 'slotattr-ok))
-        (docs   (eieio--class-public-doc cv))
-        (names  (eieio--class-public-a cv))
-        (cust   (eieio--class-public-custom cv))
-        (label  (eieio--class-public-custom-label cv))
-        (group  (eieio--class-public-custom-group cv))
-        (types  (eieio--class-public-type cv))
-        (args   (eieio--class-initarg-tuples cv))
-        (i 0))
+         (slots  (eieio--class-slots cv))
+        (args   (eieio--class-initarg-tuples cv)))
     ;; :initarg should override for subclass
     (should (assoc :initblarg args))
 
-  (while (< i (length names))
-    (cond
-     ((eq (nth i names) 'custom)
-      ;; Custom slot attributes must override
-      (should (eq (nth i cust) 'string))
-      ;; Custom label slot attribute must override
-      (should (string= (nth i label) "One String"))
-      (let ((grp (nth i group)))
-       ;; Custom group slot attribute must combine
-       (should (and (memq 'moose grp) (memq 'cow grp)))))
-     (t nil))
-
-    (setq i (1+ i)))))
+    (dotimes (i (length slots))
+      (let* ((slot (aref slots i))
+             (props (cl--slot-descriptor-props slot)))
+        (cond
+         ((eq (cl--slot-descriptor-name slot) 'custom)
+          ;; Custom slot attributes must override
+          (should (eq (alist-get :custom props) 'string))
+          ;; Custom label slot attribute must override
+          (should (string= (alist-get :label props) "One String"))
+          (let ((grp (alist-get :group props)))
+            ;; Custom group slot attribute must combine
+            (should (and (memq 'moose grp) (memq 'cow grp)))))
+         (t nil))))))
 
 (defvar eitest-CLONETEST1 nil)
 (defvar eitest-CLONETEST2 nil)
@@ -891,8 +887,7 @@ Subclasses to override slot attributes.")
   (should (= (length (eieio-build-class-alist 'opt-test1 nil)) 2))
   (should (= (length (eieio-build-class-alist 'opt-test1 t)) 1)))
 
-(defclass eieio--testing ()
-  ())
+(defclass eieio--testing () ())
 
 (defmethod constructor :static ((_x eieio--testing) newname &rest _args)
   (list newname 2))



reply via email to

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