Use zero_vector where appropriate.
[bpt/emacs.git] / src / keymap.c
index c968b14..510c5ea 100644 (file)
@@ -1,5 +1,5 @@
 /* Manipulation of keymaps
 /* Manipulation of keymaps
-   Copyright (C) 1985-1988, 1993-1995, 1998-2011 Free Software Foundation, Inc.
+   Copyright (C) 1985-1988, 1993-1995, 1998-2012 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 
 This file is part of GNU Emacs.
 
@@ -43,8 +43,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <setjmp.h>
 #include "lisp.h"
 #include "commands.h"
 #include <setjmp.h>
 #include "lisp.h"
 #include "commands.h"
-#include "buffer.h"
 #include "character.h"
 #include "character.h"
+#include "buffer.h"
 #include "charset.h"
 #include "keyboard.h"
 #include "frame.h"
 #include "charset.h"
 #include "keyboard.h"
 #include "frame.h"
@@ -92,7 +92,6 @@ static Lisp_Object where_is_cache;
 /* Which keymaps are reverse-stored in the cache.  */
 static Lisp_Object where_is_cache_keymaps;
 
 /* Which keymaps are reverse-stored in the cache.  */
 static Lisp_Object where_is_cache_keymaps;
 
-static Lisp_Object Flookup_key (Lisp_Object, Lisp_Object, Lisp_Object);
 static Lisp_Object store_in_keymap (Lisp_Object, Lisp_Object, Lisp_Object);
 
 static Lisp_Object define_as_prefix (Lisp_Object, Lisp_Object);
 static Lisp_Object store_in_keymap (Lisp_Object, Lisp_Object, Lisp_Object);
 
 static Lisp_Object define_as_prefix (Lisp_Object, Lisp_Object);
@@ -150,17 +149,6 @@ in case you use it as a menu with `x-popup-menu'.  */)
   return Fcons (Qkeymap, Qnil);
 }
 
   return Fcons (Qkeymap, Qnil);
 }
 
-DEFUN ("make-composed-keymap", Fmake_composed_keymap, Smake_composed_keymap,
-       0, MANY, 0,
-       doc: /* Construct and return a new keymap composed of KEYMAPS.
-When looking up a key in the returned map, the key is looked in each
-keymap in turn until a binding is found.
-usage: (make-composed-keymap &rest KEYMAPS)  */)
-  (ptrdiff_t nargs, Lisp_Object *args)
-{
-  return Fcons (Qkeymap, Flist (nargs, args));
-}
-
 /* This function is used for installing the standard key bindings
    at initialization time.
 
 /* This function is used for installing the standard key bindings
    at initialization time.
 
@@ -967,8 +955,6 @@ store_in_keymap (Lisp_Object keymap, register Lisp_Object idx, Lisp_Object def)
   return def;
 }
 
   return def;
 }
 
-static Lisp_Object Fcopy_keymap (Lisp_Object);
-
 static Lisp_Object
 copy_keymap_item (Lisp_Object elt)
 {
 static Lisp_Object
 copy_keymap_item (Lisp_Object elt)
 {
@@ -1009,7 +995,7 @@ copy_keymap_item (Lisp_Object elt)
     }
   else
     {
     }
   else
     {
-      /* It may be an old fomat menu item.
+      /* It may be an old format menu item.
         Skip the optional menu string.  */
       if (STRINGP (XCAR (tem)))
        {
         Skip the optional menu string.  */
       if (STRINGP (XCAR (tem)))
        {
@@ -1128,12 +1114,12 @@ binding is altered.  If there is no binding for KEY, the new pair
 binding KEY to DEF is added at the front of KEYMAP.  */)
   (Lisp_Object keymap, Lisp_Object key, Lisp_Object def)
 {
 binding KEY to DEF is added at the front of KEYMAP.  */)
   (Lisp_Object keymap, Lisp_Object key, Lisp_Object def)
 {
-  register int idx;
+  register ptrdiff_t idx;
   register Lisp_Object c;
   register Lisp_Object cmd;
   int metized = 0;
   int meta_bit;
   register Lisp_Object c;
   register Lisp_Object cmd;
   int metized = 0;
   int meta_bit;
-  int length;
+  ptrdiff_t length;
   struct gcpro gcpro1, gcpro2, gcpro3;
 
   GCPRO3 (keymap, key, def);
   struct gcpro gcpro1, gcpro2, gcpro3;
 
   GCPRO3 (keymap, key, def);
@@ -1154,7 +1140,7 @@ binding KEY to DEF is added at the front of KEYMAP.  */)
   if (VECTORP (def) && ASIZE (def) > 0 && CONSP (AREF (def, 0)))
     { /* DEF is apparently an XEmacs-style keyboard macro.  */
       Lisp_Object tmp = Fmake_vector (make_number (ASIZE (def)), Qnil);
   if (VECTORP (def) && ASIZE (def) > 0 && CONSP (AREF (def, 0)))
     { /* DEF is apparently an XEmacs-style keyboard macro.  */
       Lisp_Object tmp = Fmake_vector (make_number (ASIZE (def)), Qnil);
-      int i = ASIZE (def);
+      ptrdiff_t i = ASIZE (def);
       while (--i >= 0)
        {
          Lisp_Object defi = AREF (def, i);
       while (--i >= 0)
        {
          Lisp_Object defi = AREF (def, i);
@@ -1216,13 +1202,20 @@ binding KEY to DEF is added at the front of KEYMAP.  */)
 
       keymap = get_keymap (cmd, 0, 1);
       if (!CONSP (keymap))
 
       keymap = get_keymap (cmd, 0, 1);
       if (!CONSP (keymap))
-       /* We must use Fkey_description rather than just passing key to
-          error; key might be a vector, not a string.  */
-       error ("Key sequence %s starts with non-prefix key %s",
-              SDATA (Fkey_description (key, Qnil)),
-              SDATA (Fkey_description (Fsubstring (key, make_number (0),
-                                                   make_number (idx)),
-                                       Qnil)));
+       {
+         const char *trailing_esc = ((EQ (c, meta_prefix_char) && metized)
+                                     ? (idx == 0 ? "ESC" : " ESC")
+                                     : "");
+
+         /* We must use Fkey_description rather than just passing key to
+            error; key might be a vector, not a string.  */
+         error ("Key sequence %s starts with non-prefix key %s%s",
+                SDATA (Fkey_description (key, Qnil)),
+                SDATA (Fkey_description (Fsubstring (key, make_number (0),
+                                                     make_number (idx)),
+                                         Qnil)),
+                trailing_esc);
+       }
     }
 }
 
     }
 }
 
@@ -1278,10 +1271,10 @@ third optional argument ACCEPT-DEFAULT is non-nil, `lookup-key' will
 recognize the default bindings, just as `read-key-sequence' does.  */)
   (Lisp_Object keymap, Lisp_Object key, Lisp_Object accept_default)
 {
 recognize the default bindings, just as `read-key-sequence' does.  */)
   (Lisp_Object keymap, Lisp_Object key, Lisp_Object accept_default)
 {
-  register int idx;
+  register ptrdiff_t idx;
   register Lisp_Object cmd;
   register Lisp_Object c;
   register Lisp_Object cmd;
   register Lisp_Object c;
-  int length;
+  ptrdiff_t length;
   int t_ok = !NILP (accept_default);
   struct gcpro gcpro1, gcpro2;
 
   int t_ok = !NILP (accept_default);
   struct gcpro gcpro1, gcpro2;
 
@@ -1485,7 +1478,7 @@ current_minor_maps (Lisp_Object **modeptr, Lisp_Object **mapptr)
                /* Use malloc here.  See the comment above this function.
                   Avoid realloc here; it causes spurious traps on GNU/Linux [KFS] */
                BLOCK_INPUT;
                /* Use malloc here.  See the comment above this function.
                   Avoid realloc here; it causes spurious traps on GNU/Linux [KFS] */
                BLOCK_INPUT;
-               newmodes = (Lisp_Object *) malloc (allocsize);
+               newmodes = malloc (allocsize);
                if (newmodes)
                  {
                    if (cmm_modes)
                if (newmodes)
                  {
                    if (cmm_modes)
@@ -1497,7 +1490,7 @@ current_minor_maps (Lisp_Object **modeptr, Lisp_Object **mapptr)
                    cmm_modes = newmodes;
                  }
 
                    cmm_modes = newmodes;
                  }
 
-               newmaps = (Lisp_Object *) malloc (allocsize);
+               newmaps = malloc (allocsize);
                if (newmaps)
                  {
                    if (cmm_maps)
                if (newmaps)
                  {
                    if (cmm_maps)
@@ -1531,6 +1524,19 @@ current_minor_maps (Lisp_Object **modeptr, Lisp_Object **mapptr)
   return i;
 }
 
   return i;
 }
 
+/* Return the offset of POSITION, a click position, in the style of
+   the respective argument of Fkey_binding.  */
+static ptrdiff_t
+click_position (Lisp_Object position)
+{
+  EMACS_INT pos = (INTEGERP (position) ? XINT (position)
+                  : MARKERP (position) ? marker_position (position)
+                  : PT);
+  if (! (BEGV <= pos && pos <= ZV))
+    args_out_of_range (Fcurrent_buffer (), position);
+  return pos;
+}
+
 DEFUN ("current-active-maps", Fcurrent_active_maps, Scurrent_active_maps,
        0, 2, 0,
        doc: /* Return a list of the currently active keymaps.
 DEFUN ("current-active-maps", Fcurrent_active_maps, Scurrent_active_maps,
        0, 2, 0,
        doc: /* Return a list of the currently active keymaps.
@@ -1539,7 +1545,7 @@ OLP if non-nil indicates that we should obey `overriding-local-map' and
 like in the respective argument of `key-binding'. */)
   (Lisp_Object olp, Lisp_Object position)
 {
 like in the respective argument of `key-binding'. */)
   (Lisp_Object olp, Lisp_Object position)
 {
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
 
   Lisp_Object keymaps = Fcons (current_global_map, Qnil);
 
 
   Lisp_Object keymaps = Fcons (current_global_map, Qnil);
 
@@ -1586,10 +1592,7 @@ like in the respective argument of `key-binding'. */)
     {
       Lisp_Object *maps;
       int nmaps, i;
     {
       Lisp_Object *maps;
       int nmaps, i;
-      EMACS_INT pt
-       = INTEGERP (position) ? XINT (position)
-       : MARKERP (position) ? marker_position (position)
-       : PT;
+      ptrdiff_t pt = click_position (position);
       /* This usually returns the buffer's local map,
         but that can be overridden by a `local-map' property.  */
       Lisp_Object local_map = get_local_map (pt, current_buffer, Qlocal_map);
       /* This usually returns the buffer's local map,
         but that can be overridden by a `local-map' property.  */
       Lisp_Object local_map = get_local_map (pt, current_buffer, Qlocal_map);
@@ -1908,10 +1911,10 @@ accessible_keymaps_1 (Lisp_Object key, Lisp_Object cmd, Lisp_Object args, void *
   while (!NILP (tem = Frassq (cmd, maps)))
     {
       Lisp_Object prefix = XCAR (tem);
   while (!NILP (tem = Frassq (cmd, maps)))
     {
       Lisp_Object prefix = XCAR (tem);
-      int lim = XINT (Flength (XCAR (tem)));
+      ptrdiff_t lim = XINT (Flength (XCAR (tem)));
       if (lim <= XINT (Flength (thisseq)))
        { /* This keymap was already seen with a smaller prefix.  */
       if (lim <= XINT (Flength (thisseq)))
        { /* This keymap was already seen with a smaller prefix.  */
-         int i = 0;
+         ptrdiff_t i = 0;
          while (i < lim && EQ (Faref (prefix, make_number (i)),
                                Faref (thisseq, make_number (i))))
            i++;
          while (i < lim && EQ (Faref (prefix, make_number (i)),
                                Faref (thisseq, make_number (i))))
            i++;
@@ -1964,7 +1967,7 @@ then the value includes only maps for prefixes that start with PREFIX.  */)
   (Lisp_Object keymap, Lisp_Object prefix)
 {
   Lisp_Object maps, tail;
   (Lisp_Object keymap, Lisp_Object prefix)
 {
   Lisp_Object maps, tail;
-  int prefixlen = XINT (Flength (prefix));
+  EMACS_INT prefixlen = XFASTINT (Flength (prefix));
 
   /* no need for gcpro because we don't autoload any keymaps.  */
 
 
   /* no need for gcpro because we don't autoload any keymaps.  */
 
@@ -2007,9 +2010,7 @@ then the value includes only maps for prefixes that start with PREFIX.  */)
        return Qnil;
     }
   else
        return Qnil;
     }
   else
-    maps = Fcons (Fcons (Fmake_vector (make_number (0), Qnil),
-                        get_keymap (keymap, 1, 0)),
-                 Qnil);
+    maps = Fcons (Fcons (zero_vector, get_keymap (keymap, 1, 0)), Qnil);
 
   /* For each map in the list maps,
      look at any other maps it points to,
 
   /* For each map in the list maps,
      look at any other maps it points to,
@@ -2047,24 +2048,30 @@ static Lisp_Object Qsingle_key_description, Qkey_description;
 DEFUN ("key-description", Fkey_description, Skey_description, 1, 2, 0,
        doc: /* Return a pretty description of key-sequence KEYS.
 Optional arg PREFIX is the sequence of keys leading up to KEYS.
 DEFUN ("key-description", Fkey_description, Skey_description, 1, 2, 0,
        doc: /* Return a pretty description of key-sequence KEYS.
 Optional arg PREFIX is the sequence of keys leading up to KEYS.
-Control characters turn into "C-foo" sequences, meta into "M-foo",
-spaces are put between sequence elements, etc.  */)
+For example, [?\C-x ?l] is converted into the string \"C-x l\".
+
+The `kbd' macro is an approximate inverse of this.  */)
   (Lisp_Object keys, Lisp_Object prefix)
 {
   (Lisp_Object keys, Lisp_Object prefix)
 {
-  int len = 0;
-  int i, i_byte;
+  ptrdiff_t len = 0;
+  EMACS_INT i;
+  ptrdiff_t i_byte;
   Lisp_Object *args;
   Lisp_Object *args;
-  int size = XINT (Flength (keys));
+  EMACS_INT size = XINT (Flength (keys));
   Lisp_Object list;
   Lisp_Object sep = build_string (" ");
   Lisp_Object key;
   Lisp_Object list;
   Lisp_Object sep = build_string (" ");
   Lisp_Object key;
+  Lisp_Object result;
   int add_meta = 0;
   int add_meta = 0;
+  USE_SAFE_ALLOCA;
 
   if (!NILP (prefix))
     size += XINT (Flength (prefix));
 
   /* This has one extra element at the end that we don't pass to Fconcat.  */
 
   if (!NILP (prefix))
     size += XINT (Flength (prefix));
 
   /* This has one extra element at the end that we don't pass to Fconcat.  */
-  args = (Lisp_Object *) alloca (size * 4 * sizeof (Lisp_Object));
+  if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Lisp_Object) / 4 < size)
+    memory_full (SIZE_MAX);
+  SAFE_ALLOCA_LISP (args, size * 4);
 
   /* In effect, this computes
      (mapconcat 'single-key-description keys " ")
 
   /* In effect, this computes
      (mapconcat 'single-key-description keys " ")
@@ -2080,11 +2087,14 @@ spaces are put between sequence elements, etc.  */)
       if (add_meta)
        {
          args[len] = Fsingle_key_description (meta_prefix_char, Qnil);
       if (add_meta)
        {
          args[len] = Fsingle_key_description (meta_prefix_char, Qnil);
-         len += 2;
+         result = Fconcat (len + 1, args);
        }
       else if (len == 0)
        }
       else if (len == 0)
-       return empty_unibyte_string;
-      return Fconcat (len - 1, args);
+       result = empty_unibyte_string;
+      else
+       result = Fconcat (len - 1, args);
+      SAFE_FREE ();
+      return result;
     }
 
   if (STRINGP (list))
     }
 
   if (STRINGP (list))
@@ -2147,12 +2157,12 @@ spaces are put between sequence elements, etc.  */)
 
 
 char *
 
 
 char *
-push_key_description (register unsigned int c, register char *p, int force_multibyte)
+push_key_description (EMACS_INT ch, char *p, int force_multibyte)
 {
 {
-  unsigned c2;
+  int c, c2;
 
   /* Clear all the meaningless bits above the meta bit.  */
 
   /* Clear all the meaningless bits above the meta bit.  */
-  c &= meta_modifier | ~ - meta_modifier;
+  c = ch & (meta_modifier | ~ - meta_modifier);
   c2 = c & ~(alt_modifier | ctrl_modifier | hyper_modifier
             | meta_modifier | shift_modifier | super_modifier);
 
   c2 = c & ~(alt_modifier | ctrl_modifier | hyper_modifier
             | meta_modifier | shift_modifier | super_modifier);
 
@@ -2274,23 +2284,35 @@ around function keys and event symbols.  */)
   if (CONSP (key) && lucid_event_type_list_p (key))
     key = Fevent_convert_list (key);
 
   if (CONSP (key) && lucid_event_type_list_p (key))
     key = Fevent_convert_list (key);
 
+  if (CONSP (key) && INTEGERP (XCAR (key)) && INTEGERP (XCDR (key)))
+    /* An interval from a map-char-table.  */
+    return concat3 (Fsingle_key_description (XCAR (key), no_angles),
+                   build_string (".."),
+                   Fsingle_key_description (XCDR (key), no_angles));
+
   key = EVENT_HEAD (key);
 
   key = EVENT_HEAD (key);
 
-  if (INTEGERP (key))          /* Normal character */
+  if (INTEGERP (key))          /* Normal character */
     {
     {
-      char tem[KEY_DESCRIPTION_SIZE];
+      char tem[KEY_DESCRIPTION_SIZE], *p;
 
 
-      *push_key_description (XINT (key), tem, 1) = 0;
-      return build_string (tem);
+      p = push_key_description (XINT (key), tem, 1);
+      *p = 0;
+      return make_specified_string (tem, -1, p - tem, 1);
     }
     }
-  else if (SYMBOLP (key))      /* Function key or event-symbol */
+  else if (SYMBOLP (key))      /* Function key or event-symbol */
     {
       if (NILP (no_angles))
        {
     {
       if (NILP (no_angles))
        {
-         char *buffer
-           = (char *) alloca (SBYTES (SYMBOL_NAME (key)) + 5);
-         sprintf (buffer, "<%s>", SDATA (SYMBOL_NAME (key)));
-         return build_string (buffer);
+         char *buffer;
+         Lisp_Object result;
+         USE_SAFE_ALLOCA;
+         SAFE_ALLOCA (buffer, char *,
+                      sizeof "<>" + SBYTES (SYMBOL_NAME (key)));
+         esprintf (buffer, "<%s>", SDATA (SYMBOL_NAME (key)));
+         result = build_string (buffer);
+         SAFE_FREE ();
+         return result;
        }
       else
        return Fsymbol_name (key);
        }
       else
        return Fsymbol_name (key);
@@ -2341,7 +2363,7 @@ See Info node `(elisp)Describing Characters' for examples.  */)
   char str[6];
   int c;
 
   char str[6];
   int c;
 
-  CHECK_NUMBER (character);
+  CHECK_CHARACTER (character);
 
   c = XINT (character);
   if (!ASCII_CHAR_P (c))
 
   c = XINT (character);
   if (!ASCII_CHAR_P (c))
@@ -2364,8 +2386,8 @@ static int where_is_preferred_modifier;
 static int
 preferred_sequence_p (Lisp_Object seq)
 {
 static int
 preferred_sequence_p (Lisp_Object seq)
 {
-  int i;
-  int len = XINT (Flength (seq));
+  EMACS_INT i;
+  EMACS_INT len = XFASTINT (Flength (seq));
   int result = 1;
 
   for (i = 0; i < len; i++)
   int result = 1;
 
   for (i = 0; i < len; i++)
@@ -2544,7 +2566,8 @@ where_is_internal (Lisp_Object definition, Lisp_Object keymaps,
 DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 5, 0,
        doc: /* Return list of keys that invoke DEFINITION.
 If KEYMAP is a keymap, search only KEYMAP and the global keymap.
 DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 5, 0,
        doc: /* Return list of keys that invoke DEFINITION.
 If KEYMAP is a keymap, search only KEYMAP and the global keymap.
-If KEYMAP is nil, search all the currently active keymaps.
+If KEYMAP is nil, search all the currently active keymaps, except
+ for `overriding-local-map' (which is ignored).
 If KEYMAP is a list of keymaps, search only those keymaps.
 
 If optional 3rd arg FIRSTONLY is non-nil, return the first key sequence found,
 If KEYMAP is a list of keymaps, search only those keymaps.
 
 If optional 3rd arg FIRSTONLY is non-nil, return the first key sequence found,
@@ -2559,9 +2582,17 @@ If optional 4th arg NOINDIRECT is non-nil, don't follow indirections
 to other keymaps or slots.  This makes it possible to search for an
 indirect definition itself.
 
 to other keymaps or slots.  This makes it possible to search for an
 indirect definition itself.
 
-If optional 5th arg NO-REMAP is non-nil, don't search for key sequences
-that invoke a command which is remapped to DEFINITION, but include the
-remapped command in the returned list.  */)
+The optional 5th arg NO-REMAP alters how command remapping is handled:
+
+- If another command OTHER-COMMAND is remapped to DEFINITION, normally
+  search for the bindings of OTHER-COMMAND and include them in the
+  returned list.  But if NO-REMAP is non-nil, include the vector
+  [remap OTHER-COMMAND] in the returned list instead, without
+  searching for those other bindings.
+
+- If DEFINITION is remapped to OTHER-COMMAND, normally return the
+  bindings for OTHER-COMMAND.  But if NO-REMAP is non-nil, return the
+  bindings for DEFINITION instead, ignoring its remapping.  */)
   (Lisp_Object definition, Lisp_Object keymap, Lisp_Object firstonly, Lisp_Object noindirect, Lisp_Object no_remap)
 {
   /* The keymaps in which to search.  */
   (Lisp_Object definition, Lisp_Object keymap, Lisp_Object firstonly, Lisp_Object noindirect, Lisp_Object no_remap)
 {
   /* The keymaps in which to search.  */
@@ -2622,11 +2653,11 @@ remapped command in the returned list.  */)
       /* We have a list of advertised bindings.  */
       while (CONSP (tem))
        if (EQ (shadow_lookup (keymaps, XCAR (tem), Qnil, 0), definition))
       /* We have a list of advertised bindings.  */
       while (CONSP (tem))
        if (EQ (shadow_lookup (keymaps, XCAR (tem), Qnil, 0), definition))
-         return XCAR (tem);
+         RETURN_UNGCPRO (XCAR (tem));
        else
          tem = XCDR (tem);
       if (EQ (shadow_lookup (keymaps, tem, Qnil, 0), definition))
        else
          tem = XCDR (tem);
       if (EQ (shadow_lookup (keymaps, tem, Qnil, 0), definition))
-       return tem;
+       RETURN_UNGCPRO (tem);
     }
 
   sequences = Freverse (where_is_internal (definition, keymaps,
     }
 
   sequences = Freverse (where_is_internal (definition, keymaps,
@@ -2890,7 +2921,7 @@ You type        Translation\n\
          if (!SYMBOLP (modes[i]))
            abort ();
 
          if (!SYMBOLP (modes[i]))
            abort ();
 
-         p = title = (char *) alloca (42 + SCHARS (SYMBOL_NAME (modes[i])));
+         p = title = alloca (42 + SCHARS (SYMBOL_NAME (modes[i])));
          *p++ = '\f';
          *p++ = '\n';
          *p++ = '`';
          *p++ = '\f';
          *p++ = '\n';
          *p++ = '`';
@@ -2960,9 +2991,9 @@ You type        Translation\n\
    If MENTION_SHADOW is nonzero, then when something is shadowed by SHADOW,
    don't omit it; instead, mention it but say it is shadowed.
 
    If MENTION_SHADOW is nonzero, then when something is shadowed by SHADOW,
    don't omit it; instead, mention it but say it is shadowed.
 
-   Return whether something was inserted or not.  */
+   Any inserted text ends in two newlines (used by `help-make-xrefs').  */
 
 
-int
+void
 describe_map_tree (Lisp_Object startmap, int partial, Lisp_Object shadow,
                   Lisp_Object prefix, const char *title, int nomenu, int transl,
                   int always_title, int mention_shadow)
 describe_map_tree (Lisp_Object startmap, int partial, Lisp_Object shadow,
                   Lisp_Object prefix, const char *title, int nomenu, int transl,
                   int always_title, int mention_shadow)
@@ -3072,8 +3103,10 @@ key             binding\n\
     skip: ;
     }
 
     skip: ;
     }
 
+  if (something)
+    insert_string ("\n");
+
   UNGCPRO;
   UNGCPRO;
-  return something;
 }
 
 static int previous_description_column;
 }
 
 static int previous_description_column;
@@ -3082,7 +3115,7 @@ static void
 describe_command (Lisp_Object definition, Lisp_Object args)
 {
   register Lisp_Object tem1;
 describe_command (Lisp_Object definition, Lisp_Object args)
 {
   register Lisp_Object tem1;
-  EMACS_INT column = current_column ();
+  ptrdiff_t column = current_column ();
   int description_column;
 
   /* If column 16 is no good, go to col 32;
   int description_column;
 
   /* If column 16 is no good, go to col 32;
@@ -3365,7 +3398,7 @@ This is text showing the elements of vector matched against indices.
 DESCRIBER is the output function used; nil means use `princ'.  */)
   (Lisp_Object vector, Lisp_Object describer)
 {
 DESCRIBER is the output function used; nil means use `princ'.  */)
   (Lisp_Object vector, Lisp_Object describer)
 {
-  int count = SPECPDL_INDEX ();
+  ptrdiff_t count = SPECPDL_INDEX ();
   if (NILP (describer))
     describer = intern ("princ");
   specbind (Qstandard_output, Fcurrent_buffer ());
   if (NILP (describer))
     describer = intern ("princ");
   specbind (Qstandard_output, Fcurrent_buffer ());
@@ -3670,11 +3703,11 @@ syms_of_keymap (void)
   Ffset (intern_c_string ("Control-X-prefix"), control_x_map);
 
   exclude_keys
   Ffset (intern_c_string ("Control-X-prefix"), control_x_map);
 
   exclude_keys
-    = pure_cons (pure_cons (make_pure_c_string ("DEL"), make_pure_c_string ("\\d")),
-                pure_cons (pure_cons (make_pure_c_string ("TAB"), make_pure_c_string ("\\t")),
-                   pure_cons (pure_cons (make_pure_c_string ("RET"), make_pure_c_string ("\\r")),
-                          pure_cons (pure_cons (make_pure_c_string ("ESC"), make_pure_c_string ("\\e")),
-                                 pure_cons (pure_cons (make_pure_c_string ("SPC"), make_pure_c_string (" ")),
+    = pure_cons (pure_cons (build_pure_c_string ("DEL"), build_pure_c_string ("\\d")),
+                pure_cons (pure_cons (build_pure_c_string ("TAB"), build_pure_c_string ("\\t")),
+                   pure_cons (pure_cons (build_pure_c_string ("RET"), build_pure_c_string ("\\r")),
+                          pure_cons (pure_cons (build_pure_c_string ("ESC"), build_pure_c_string ("\\e")),
+                                 pure_cons (pure_cons (build_pure_c_string ("SPC"), build_pure_c_string (" ")),
                                         Qnil)))));
   staticpro (&exclude_keys);
 
                                         Qnil)))));
   staticpro (&exclude_keys);
 
@@ -3761,7 +3794,6 @@ be preferred.  */);
   defsubr (&Sset_keymap_parent);
   defsubr (&Smake_keymap);
   defsubr (&Smake_sparse_keymap);
   defsubr (&Sset_keymap_parent);
   defsubr (&Smake_keymap);
   defsubr (&Smake_sparse_keymap);
-  defsubr (&Smake_composed_keymap);
   defsubr (&Smap_keymap_internal);
   defsubr (&Smap_keymap);
   defsubr (&Scopy_keymap);
   defsubr (&Smap_keymap_internal);
   defsubr (&Smap_keymap);
   defsubr (&Scopy_keymap);