This commit was generated by cvs2svn to compensate for changes in r1383,
[chise/xemacs-chise.git.1] / src / keymap.c
index efab47d..046c5e8 100644 (file)
@@ -30,7 +30,6 @@ Boston, MA 02111-1307, USA.  */
 
 #include "buffer.h"
 #include "bytecode.h"
 
 #include "buffer.h"
 #include "bytecode.h"
-#include "commands.h"
 #include "console.h"
 #include "elhash.h"
 #include "events.h"
 #include "console.h"
 #include "elhash.h"
 #include "events.h"
@@ -142,7 +141,7 @@ Boston, MA 02111-1307, USA.  */
    Since keymaps are opaque, the only way to extract information from them
    is with the functions lookup-key, key-binding, local-key-binding, and
    global-key-binding, which work just as before, and the new function
    Since keymaps are opaque, the only way to extract information from them
    is with the functions lookup-key, key-binding, local-key-binding, and
    global-key-binding, which work just as before, and the new function
-   map-keymap, which is roughly analagous to maphash.
+   map-keymap, which is roughly analogous to maphash.
 
    Note that map-keymap perpetuates the illusion that the "bucky" submaps
    don't exist: if you map over a keymap with bucky submaps, it will also
 
    Note that map-keymap perpetuates the illusion that the "bucky" submaps
    don't exist: if you map over a keymap with bucky submaps, it will also
@@ -157,39 +156,26 @@ Boston, MA 02111-1307, USA.  */
 
  */
 
 
  */
 
-struct keymap
+struct Lisp_Keymap
 {
   struct lcrecord_header header;
 {
   struct lcrecord_header header;
-  Lisp_Object parents;         /* Keymaps to be searched after this one
-                                *  An ordered list */
+  Lisp_Object parents;         /* Keymaps to be searched after this one.
+                                  An ordered list */
   Lisp_Object prompt;           /* Qnil or a string to print in the minibuffer
   Lisp_Object prompt;           /* Qnil or a string to print in the minibuffer
-                                 *  when reading from this keymap */
-
+                                   when reading from this keymap */
   Lisp_Object table;           /* The contents of this keymap */
   Lisp_Object inverse_table;   /* The inverse mapping of the above */
   Lisp_Object table;           /* The contents of this keymap */
   Lisp_Object inverse_table;   /* The inverse mapping of the above */
-
   Lisp_Object default_binding;  /* Use this if no other binding is found
   Lisp_Object default_binding;  /* Use this if no other binding is found
-                                 *  (this overrides parent maps and the
-                                 *   normal global-map lookup). */
-
-
+                                   (this overrides parent maps and the
+                                   normal global-map lookup). */
   Lisp_Object sub_maps_cache;  /* Cache of directly inferior keymaps;
                                   This holds an alist, of the key and the
                                   maps, or the modifier bit and the map.
                                   If this is the symbol t, then the cache
   Lisp_Object sub_maps_cache;  /* Cache of directly inferior keymaps;
                                   This holds an alist, of the key and the
                                   maps, or the modifier bit and the map.
                                   If this is the symbol t, then the cache
-                                  needs to be recomputed.
-                                */
-  int fullness;                        /* How many entries there are in this table.
-                                  This should be the same as the fullness
-                                  of the `table', but hash.c is broken. */
+                                  needs to be recomputed. */
   Lisp_Object name;             /* Just for debugging convenience */
 };
 
   Lisp_Object name;             /* Just for debugging convenience */
 };
 
-#define XKEYMAP(x) XRECORD (x, keymap, struct keymap)
-#define XSETKEYMAP(x, p) XSETRECORD (x, p, keymap)
-#define KEYMAPP(x) RECORDP (x, keymap)
-#define CHECK_KEYMAP(x) CHECK_RECORD (x, keymap)
-
 #define MAKE_MODIFIER_HASH_KEY(modifier) make_int (modifier)
 #define MODIFIER_HASH_KEY_BITS(x) (INTP (x) ? XINT (x) : 0)
 
 #define MAKE_MODIFIER_HASH_KEY(modifier) make_int (modifier)
 #define MODIFIER_HASH_KEY_BITS(x) (INTP (x) ? XINT (x) : 0)
 
@@ -197,7 +183,7 @@ struct keymap
 
 /* Actually allocate storage for these variables */
 
 
 /* Actually allocate storage for these variables */
 
-static Lisp_Object Vcurrent_global_map; /* Always a keymap */
+Lisp_Object Vcurrent_global_map; /* Always a keymap */
 
 static Lisp_Object Vmouse_grabbed_buffer;
 
 
 static Lisp_Object Vmouse_grabbed_buffer;
 
@@ -236,6 +222,7 @@ static void describe_map (Lisp_Object keymap, Lisp_Object elt_prefix,
                          Lisp_Object shadow,
                          int mice_only_p,
                          Lisp_Object buffer);
                          Lisp_Object shadow,
                          int mice_only_p,
                          Lisp_Object buffer);
+static Lisp_Object keymap_submaps (Lisp_Object keymap);
 
 Lisp_Object Qcontrol, Qctrl, Qmeta, Qsuper, Qhyper, Qalt, Qshift;
 Lisp_Object Qbutton0, Qbutton1, Qbutton2, Qbutton3;
 
 Lisp_Object Qcontrol, Qctrl, Qmeta, Qsuper, Qhyper, Qalt, Qshift;
 Lisp_Object Qbutton0, Qbutton1, Qbutton2, Qbutton3;
@@ -258,15 +245,15 @@ Lisp_Object QLFD, QTAB, QRET, QESC, QDEL, QSPC, QBS;
 /************************************************************************/
 
 static Lisp_Object
 /************************************************************************/
 
 static Lisp_Object
-mark_keymap (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_keymap (Lisp_Object obj)
 {
 {
-  struct keymap *keymap = XKEYMAP (obj);
-  ((markobj) (keymap->parents));
-  ((markobj) (keymap->prompt));
-  ((markobj) (keymap->inverse_table));
-  ((markobj) (keymap->sub_maps_cache));
-  ((markobj) (keymap->default_binding));
-  ((markobj) (keymap->name));
+  Lisp_Keymap *keymap = XKEYMAP (obj);
+  mark_object (keymap->parents);
+  mark_object (keymap->prompt);
+  mark_object (keymap->inverse_table);
+  mark_object (keymap->sub_maps_cache);
+  mark_object (keymap->default_binding);
+  mark_object (keymap->name);
   return keymap->table;
 }
 
   return keymap->table;
 }
 
@@ -274,27 +261,37 @@ static void
 print_keymap (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
 {
   /* This function can GC */
 print_keymap (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
 {
   /* This function can GC */
-  struct keymap *keymap = XKEYMAP (obj);
+  Lisp_Keymap *keymap = XKEYMAP (obj);
   char buf[200];
   char buf[200];
-  int size = XINT (Fkeymap_fullness (obj));
   if (print_readably)
     error ("printing unreadable object #<keymap 0x%x>", keymap->header.uid);
   write_c_string ("#<keymap ", printcharfun);
   if (!NILP (keymap->name))
   if (print_readably)
     error ("printing unreadable object #<keymap 0x%x>", keymap->header.uid);
   write_c_string ("#<keymap ", printcharfun);
   if (!NILP (keymap->name))
-    print_internal (keymap->name, printcharfun, 1);
-  /* #### Yuck!  This is no way to form plural!  --hniksic */
-  sprintf (buf, "%s%d entr%s 0x%x>",
-           ((NILP (keymap->name)) ? "" : " "),
-           size,
-           ((size == 1) ? "y" : "ies"),
-           keymap->header.uid);
+    {
+      print_internal (keymap->name, printcharfun, 1);
+      write_c_string (" ", printcharfun);
+    }
+  sprintf (buf, "size %ld 0x%x>",
+          (long) XINT (Fkeymap_fullness (obj)), keymap->header.uid);
   write_c_string (buf, printcharfun);
 }
 
   write_c_string (buf, printcharfun);
 }
 
+static const struct lrecord_description keymap_description[] = {
+  { XD_LISP_OBJECT, offsetof (Lisp_Keymap, parents) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Keymap, prompt) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Keymap, table) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Keymap, inverse_table) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Keymap, default_binding) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Keymap, sub_maps_cache) },
+  { XD_LISP_OBJECT, offsetof (Lisp_Keymap, name) },
+  { XD_END }
+};
+
 /* No need for keymap_equal #### Why not? */
 DEFINE_LRECORD_IMPLEMENTATION ("keymap", keymap,
                                mark_keymap, print_keymap, 0, 0, 0,
 /* No need for keymap_equal #### Why not? */
 DEFINE_LRECORD_IMPLEMENTATION ("keymap", keymap,
                                mark_keymap, print_keymap, 0, 0, 0,
-                              struct keymap);
+                              keymap_description,
+                              Lisp_Keymap);
 \f
 /************************************************************************/
 /*                Traversing keymaps and their parents                  */
 \f
 /************************************************************************/
 /*                Traversing keymaps and their parents                  */
@@ -318,19 +315,19 @@ traverse_keymaps (Lisp_Object start_keymap, Lisp_Object start_parents,
   start_keymap = get_keymap (start_keymap, 1, 1);
   keymap = start_keymap;
   /* Hack special-case parents at top-level */
   start_keymap = get_keymap (start_keymap, 1, 1);
   keymap = start_keymap;
   /* Hack special-case parents at top-level */
-  tail = ((!NILP (tail)) ? tail : XKEYMAP (keymap)->parents);
+  tail = !NILP (tail) ? tail : XKEYMAP (keymap)->parents;
 
   for (;;)
     {
       Lisp_Object result;
 
       QUIT;
 
   for (;;)
     {
       Lisp_Object result;
 
       QUIT;
-      result = ((mapper) (keymap, mapper_arg));
+      result = mapper (keymap, mapper_arg);
       if (!NILP (result))
        {
          while (CONSP (malloc_bites))
            {
       if (!NILP (result))
        {
          while (CONSP (malloc_bites))
            {
-             struct Lisp_Cons *victim = XCONS (malloc_bites);
+             Lisp_Cons *victim = XCONS (malloc_bites);
              malloc_bites = victim->cdr;
              free_cons (victim);
            }
              malloc_bites = victim->cdr;
              free_cons (victim);
            }
@@ -347,7 +344,7 @@ traverse_keymaps (Lisp_Object start_keymap, Lisp_Object start_parents,
          stack_depth--;
          if (CONSP (malloc_bites))
            {
          stack_depth--;
          if (CONSP (malloc_bites))
            {
-             struct Lisp_Cons *victim = XCONS (malloc_bites);
+             Lisp_Cons *victim = XCONS (malloc_bites);
              tail = victim->car;
              malloc_bites = victim->cdr;
              free_cons (victim);
              tail = victim->car;
              malloc_bites = victim->cdr;
              free_cons (victim);
@@ -439,7 +436,7 @@ control_meta_superify (Lisp_Object frob, unsigned int modifiers)
 }
 
 static Lisp_Object
 }
 
 static Lisp_Object
-make_key_description (CONST struct key_data *key, int prettify)
+make_key_description (const struct key_data *key, int prettify)
 {
   Lisp_Object keysym = key->keysym;
   unsigned int modifiers = key->modifiers;
 {
   Lisp_Object keysym = key->keysym;
   unsigned int modifiers = key->modifiers;
@@ -467,7 +464,7 @@ make_key_description (CONST struct key_data *key, int prettify)
 
 static Lisp_Object
 raw_lookup_key (Lisp_Object keymap,
 
 static Lisp_Object
 raw_lookup_key (Lisp_Object keymap,
-                CONST struct key_data *raw_keys, int raw_keys_count,
+                const struct key_data *raw_keys, int raw_keys_count,
                 int keys_so_far, int accept_default);
 
 /* Relies on caller to gc-protect args */
                 int keys_so_far, int accept_default);
 
 /* Relies on caller to gc-protect args */
@@ -475,7 +472,7 @@ static Lisp_Object
 keymap_lookup_directly (Lisp_Object keymap,
                         Lisp_Object keysym, unsigned int modifiers)
 {
 keymap_lookup_directly (Lisp_Object keymap,
                         Lisp_Object keysym, unsigned int modifiers)
 {
-  struct keymap *k;
+  Lisp_Keymap *k;
 
   if ((modifiers & ~(MOD_CONTROL | MOD_META | MOD_SUPER | MOD_HYPER
                      | MOD_ALT | MOD_SHIFT)) != 0)
 
   if ((modifiers & ~(MOD_CONTROL | MOD_META | MOD_SUPER | MOD_HYPER
                      | MOD_ALT | MOD_SHIFT)) != 0)
@@ -534,7 +531,7 @@ keymap_store_inverse_internal (Lisp_Object inverse_table,
     }
   else
     {
     }
   else
     {
-      while (CONSP (Fcdr (keys)))
+      while (CONSP (XCDR (keys)))
        keys = XCDR (keys);
       XCDR (keys) = Fcons (XCDR (keys), keysym);
       /* No need to call puthash because we've destructively
        keys = XCDR (keys);
       XCDR (keys) = Fcons (XCDR (keys), keysym);
       /* No need to call puthash because we've destructively
@@ -582,38 +579,57 @@ keymap_delete_inverse_internal (Lisp_Object inverse_table,
    */
 }
 
    */
 }
 
+/* Prevent luser from shooting herself in the foot using something like
+   (define-key ctl-x-4-map "p" global-map) */
+static void
+check_keymap_definition_loop (Lisp_Object def, Lisp_Keymap *to_keymap)
+{
+  def = get_keymap (def, 0, 0);
+
+  if (KEYMAPP (def))
+    {
+      Lisp_Object maps;
+
+      if (XKEYMAP (def) == to_keymap)
+       signal_simple_error ("Cyclic keymap definition", def);
+
+      for (maps = keymap_submaps (def);
+          CONSP (maps);
+          maps = XCDR (maps))
+       check_keymap_definition_loop (XCDR (XCAR (maps)), to_keymap);
+    }
+}
 
 static void
 
 static void
-keymap_store_internal (Lisp_Object keysym, struct keymap *keymap,
-                      Lisp_Object value)
+keymap_store_internal (Lisp_Object keysym, Lisp_Keymap *keymap,
+                      Lisp_Object def)
 {
 {
-  Lisp_Object prev_value = Fgethash (keysym, keymap->table, Qnil);
+  Lisp_Object prev_def = Fgethash (keysym, keymap->table, Qnil);
 
 
-  if (EQ (prev_value, value))
+  if (EQ (prev_def, def))
       return;
       return;
-  if (!NILP (prev_value))
+
+  check_keymap_definition_loop (def, keymap);
+
+  if (!NILP (prev_def))
     keymap_delete_inverse_internal (keymap->inverse_table,
     keymap_delete_inverse_internal (keymap->inverse_table,
-                                    keysym, prev_value);
-  if (NILP (value))
+                                    keysym, prev_def);
+  if (NILP (def))
     {
     {
-      keymap->fullness--;
-      if (keymap->fullness < 0) abort ();
       Fremhash (keysym, keymap->table);
     }
   else
     {
       Fremhash (keysym, keymap->table);
     }
   else
     {
-      if (NILP (prev_value))
-       keymap->fullness++;
-      Fputhash (keysym, value, keymap->table);
+      Fputhash (keysym, def, keymap->table);
       keymap_store_inverse_internal (keymap->inverse_table,
       keymap_store_inverse_internal (keymap->inverse_table,
-                                     keysym, value);
+                                     keysym, def);
     }
   keymap_tick++;
 }
 
 
 static Lisp_Object
     }
   keymap_tick++;
 }
 
 
 static Lisp_Object
-create_bucky_submap (struct keymap *k, unsigned int modifiers,
+create_bucky_submap (Lisp_Keymap *k, unsigned int modifiers,
                      Lisp_Object parent_for_debugging_info)
 {
   Lisp_Object submap = Fmake_sparse_keymap (Qnil);
                      Lisp_Object parent_for_debugging_info)
 {
   Lisp_Object submap = Fmake_sparse_keymap (Qnil);
@@ -629,26 +645,19 @@ create_bucky_submap (struct keymap *k, unsigned int modifiers,
 
 /* Relies on caller to gc-protect keymap, keysym, value */
 static void
 
 /* Relies on caller to gc-protect keymap, keysym, value */
 static void
-keymap_store (Lisp_Object keymap, CONST struct key_data *key,
+keymap_store (Lisp_Object keymap, const struct key_data *key,
               Lisp_Object value)
 {
   Lisp_Object keysym = key->keysym;
   unsigned int modifiers = key->modifiers;
               Lisp_Object value)
 {
   Lisp_Object keysym = key->keysym;
   unsigned int modifiers = key->modifiers;
-  struct keymap *k;
-
-  if ((modifiers & ~(MOD_CONTROL | MOD_META | MOD_SUPER | MOD_HYPER
-                     | MOD_ALT | MOD_SHIFT)) != 0)
-    abort ();
+  Lisp_Keymap *k = XKEYMAP (keymap);
 
 
-  k = XKEYMAP (keymap);
+  assert ((modifiers & ~(MOD_CONTROL | MOD_META | MOD_SUPER | MOD_HYPER
+                        | MOD_ALT | MOD_SHIFT)) == 0);
 
   /* If the keysym is a one-character symbol, use the char code instead. */
   if (SYMBOLP (keysym) && string_char_length (XSYMBOL (keysym)->name) == 1)
 
   /* If the keysym is a one-character symbol, use the char code instead. */
   if (SYMBOLP (keysym) && string_char_length (XSYMBOL (keysym)->name) == 1)
-    {
-      Lisp_Object run_the_gcc_developers_over_with_a_steamroller =
-       make_char (string_char (XSYMBOL (keysym)->name, 0));
-      keysym = run_the_gcc_developers_over_with_a_steamroller;
-    }
+    keysym = make_char (string_char (XSYMBOL (keysym)->name, 0));
 
   if (modifiers & MOD_META)     /* Utterly hateful ESC lossage */
     {
 
   if (modifiers & MOD_META)     /* Utterly hateful ESC lossage */
     {
@@ -683,32 +692,27 @@ struct keymap_submaps_closure
 };
 
 static int
 };
 
 static int
-keymap_submaps_mapper_0 (CONST void *hash_key, void *hash_contents,
+keymap_submaps_mapper_0 (Lisp_Object key, Lisp_Object value,
                          void *keymap_submaps_closure)
 {
   /* This function can GC */
                          void *keymap_submaps_closure)
 {
   /* This function can GC */
-  Lisp_Object contents;
-  VOID_TO_LISP (contents, hash_contents);
   /* Perform any autoloads, etc */
   /* Perform any autoloads, etc */
-  Fkeymapp (contents);
+  Fkeymapp (value);
   return 0;
 }
 
 static int
   return 0;
 }
 
 static int
-keymap_submaps_mapper (CONST void *hash_key, void *hash_contents,
+keymap_submaps_mapper (Lisp_Object key, Lisp_Object value,
                        void *keymap_submaps_closure)
 {
   /* This function can GC */
                        void *keymap_submaps_closure)
 {
   /* This function can GC */
-  Lisp_Object key, contents;
   Lisp_Object *result_locative;
   struct keymap_submaps_closure *cl =
     (struct keymap_submaps_closure *) keymap_submaps_closure;
   Lisp_Object *result_locative;
   struct keymap_submaps_closure *cl =
     (struct keymap_submaps_closure *) keymap_submaps_closure;
-  CVOID_TO_LISP (key, hash_key);
-  VOID_TO_LISP (contents, hash_contents);
   result_locative = cl->result_locative;
 
   result_locative = cl->result_locative;
 
-  if (!NILP (Fkeymapp (contents)))
-    *result_locative = Fcons (Fcons (key, contents), *result_locative);
+  if (!NILP (Fkeymapp (value)))
+    *result_locative = Fcons (Fcons (key, value), *result_locative);
   return 0;
 }
 
   return 0;
 }
 
@@ -719,7 +723,7 @@ static Lisp_Object
 keymap_submaps (Lisp_Object keymap)
 {
   /* This function can GC */
 keymap_submaps (Lisp_Object keymap)
 {
   /* This function can GC */
-  struct keymap *k = XKEYMAP (keymap);
+  Lisp_Keymap *k = XKEYMAP (keymap);
 
   if (EQ (k->sub_maps_cache, Qt)) /* Unknown */
     {
 
   if (EQ (k->sub_maps_cache, Qt)) /* Unknown */
     {
@@ -750,28 +754,30 @@ keymap_submaps (Lisp_Object keymap)
 /************************************************************************/
 
 static Lisp_Object
 /************************************************************************/
 
 static Lisp_Object
-make_keymap (int size)
+make_keymap (size_t size)
 {
   Lisp_Object result;
 {
   Lisp_Object result;
-  struct keymap *keymap = alloc_lcrecord_type (struct keymap, lrecord_keymap);
+  Lisp_Keymap *keymap = alloc_lcrecord_type (Lisp_Keymap, &lrecord_keymap);
 
   XSETKEYMAP (result, keymap);
 
 
   XSETKEYMAP (result, keymap);
 
-  keymap->parents = Qnil;
-  keymap->table = Qnil;
-  keymap->prompt = Qnil;
+  keymap->parents         = Qnil;
+  keymap->prompt          = Qnil;
+  keymap->table           = Qnil;
+  keymap->inverse_table   = Qnil;
   keymap->default_binding = Qnil;
   keymap->default_binding = Qnil;
-  keymap->inverse_table = Qnil;
-  keymap->sub_maps_cache = Qnil; /* No possible submaps */
-  keymap->fullness = 0;
+  keymap->sub_maps_cache  = Qnil; /* No possible submaps */
+  keymap->name            = Qnil;
+
   if (size != 0) /* hack for copy-keymap */
     {
   if (size != 0) /* hack for copy-keymap */
     {
-      keymap->table = Fmake_hashtable (make_int (size), Qnil);
+      keymap->table =
+       make_lisp_hash_table (size, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
       /* Inverse table is often less dense because of duplicate key-bindings.
          If not, it will grow anyway. */
       /* Inverse table is often less dense because of duplicate key-bindings.
          If not, it will grow anyway. */
-      keymap->inverse_table = Fmake_hashtable (make_int (size * 3 / 4), Qnil);
+      keymap->inverse_table =
+       make_lisp_hash_table (size * 3 / 4, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
     }
     }
-  keymap->name = Qnil;
   return result;
 }
 
   return result;
 }
 
@@ -1052,7 +1058,7 @@ get_keyelt (Lisp_Object object, int accept_default)
       struct key_data indirection;
       if (CHARP (idx))
        {
       struct key_data indirection;
       if (CHARP (idx))
        {
-         struct Lisp_Event event;
+         Lisp_Event event;
          event.event_type = empty_event;
          character_to_event (XCHAR (idx), &event,
                              XCONSOLE (Vselected_console), 0, 0);
          event.event_type = empty_event;
          character_to_event (XCHAR (idx), &event,
                              XCONSOLE (Vselected_console), 0, 0);
@@ -1063,7 +1069,7 @@ get_keyelt (Lisp_Object object, int accept_default)
          if (!INTP (XCDR (idx)))
            return Qnil;
          indirection.keysym = XCAR (idx);
          if (!INTP (XCDR (idx)))
            return Qnil;
          indirection.keysym = XCAR (idx);
-         indirection.modifiers = XINT (XCDR (idx));
+         indirection.modifiers = (unsigned char) XINT (XCDR (idx));
        }
       else if (SYMBOLP (idx))
        {
        }
       else if (SYMBOLP (idx))
        {
@@ -1094,7 +1100,7 @@ get_keyelt (Lisp_Object object, int accept_default)
 }
 
 static Lisp_Object
 }
 
 static Lisp_Object
-keymap_lookup_1 (Lisp_Object keymap, CONST struct key_data *key,
+keymap_lookup_1 (Lisp_Object keymap, const struct key_data *key,
                  int accept_default)
 {
   /* This function can GC */
                  int accept_default)
 {
   /* This function can GC */
@@ -1114,38 +1120,34 @@ struct copy_keymap_inverse_closure
 };
 
 static int
 };
 
 static int
-copy_keymap_inverse_mapper (CONST void *hash_key, void *hash_contents,
+copy_keymap_inverse_mapper (Lisp_Object key, Lisp_Object value,
                             void *copy_keymap_inverse_closure)
 {
                             void *copy_keymap_inverse_closure)
 {
-  Lisp_Object key, inverse_table, inverse_contents;
   struct copy_keymap_inverse_closure *closure =
     (struct copy_keymap_inverse_closure *) copy_keymap_inverse_closure;
 
   struct copy_keymap_inverse_closure *closure =
     (struct copy_keymap_inverse_closure *) copy_keymap_inverse_closure;
 
-  VOID_TO_LISP (inverse_table, closure);
-  VOID_TO_LISP (inverse_contents, hash_contents);
-  CVOID_TO_LISP (key, hash_key);
   /* copy-sequence deals with dotted lists. */
   /* copy-sequence deals with dotted lists. */
-  if (CONSP (inverse_contents))
-    inverse_contents = Fcopy_sequence (inverse_contents);
-  Fputhash (key, inverse_contents, closure->inverse_table);
+  if (CONSP (value))
+    value = Fcopy_list (value);
+  Fputhash (key, value, closure->inverse_table);
 
   return 0;
 }
 
 
 static Lisp_Object
 
   return 0;
 }
 
 
 static Lisp_Object
-copy_keymap_internal (struct keymap *keymap)
+copy_keymap_internal (Lisp_Keymap *keymap)
 {
   Lisp_Object nkm = make_keymap (0);
 {
   Lisp_Object nkm = make_keymap (0);
-  struct keymap *new_keymap = XKEYMAP (nkm);
+  Lisp_Keymap *new_keymap = XKEYMAP (nkm);
   struct copy_keymap_inverse_closure copy_keymap_inverse_closure;
   copy_keymap_inverse_closure.inverse_table = keymap->inverse_table;
 
   struct copy_keymap_inverse_closure copy_keymap_inverse_closure;
   copy_keymap_inverse_closure.inverse_table = keymap->inverse_table;
 
-  new_keymap->parents = Fcopy_sequence (keymap->parents);
-  new_keymap->fullness = keymap->fullness;
+  new_keymap->parents        = Fcopy_sequence (keymap->parents);
   new_keymap->sub_maps_cache = Qnil; /* No submaps */
   new_keymap->sub_maps_cache = Qnil; /* No submaps */
-  new_keymap->table = Fcopy_hashtable (keymap->table);
-  new_keymap->inverse_table = Fcopy_hashtable (keymap->inverse_table);
+  new_keymap->table          = Fcopy_hash_table (keymap->table);
+  new_keymap->inverse_table  = Fcopy_hash_table (keymap->inverse_table);
+  new_keymap->default_binding = keymap->default_binding;
   /* After copying the inverse map, we need to copy the conses which
      are its values, lest they be shared by the copy, and mangled.
    */
   /* After copying the inverse map, we need to copy the conses which
      are its values, lest they be shared by the copy, and mangled.
    */
@@ -1159,30 +1161,26 @@ static Lisp_Object copy_keymap (Lisp_Object keymap);
 
 struct copy_keymap_closure
 {
 
 struct copy_keymap_closure
 {
-  struct keymap *self;
+  Lisp_Keymap *self;
 };
 
 static int
 };
 
 static int
-copy_keymap_mapper (CONST void *hash_key, void *hash_contents,
+copy_keymap_mapper (Lisp_Object key, Lisp_Object value,
                     void *copy_keymap_closure)
 {
   /* This function can GC */
                     void *copy_keymap_closure)
 {
   /* This function can GC */
-  Lisp_Object key, contents;
   struct copy_keymap_closure *closure =
     (struct copy_keymap_closure *) copy_keymap_closure;
 
   struct copy_keymap_closure *closure =
     (struct copy_keymap_closure *) copy_keymap_closure;
 
-  CVOID_TO_LISP (key, hash_key);
-  VOID_TO_LISP (contents, hash_contents);
   /* When we encounter a keymap which is indirected through a
      symbol, we need to copy the sub-map.  In v18, the form
        (lookup-key (copy-keymap global-map) "\C-x")
      returned a new keymap, not the symbol 'Control-X-prefix.
    */
   /* When we encounter a keymap which is indirected through a
      symbol, we need to copy the sub-map.  In v18, the form
        (lookup-key (copy-keymap global-map) "\C-x")
      returned a new keymap, not the symbol 'Control-X-prefix.
    */
-  contents = get_keymap (contents,
-                        0, 1); /* #### autoload GC-safe here? */
-  if (KEYMAPP (contents))
+  value = get_keymap (value, 0, 1); /* #### autoload GC-safe here? */
+  if (KEYMAPP (value))
     keymap_store_internal (key, closure->self,
     keymap_store_internal (key, closure->self,
-                          copy_keymap (contents));
+                          copy_keymap (value));
   return 0;
 }
 
   return 0;
 }
 
@@ -1223,16 +1221,17 @@ keymap_fullness (Lisp_Object keymap)
   struct gcpro gcpro1, gcpro2;
 
   keymap = get_keymap (keymap, 1, 1);
   struct gcpro gcpro1, gcpro2;
 
   keymap = get_keymap (keymap, 1, 1);
-  fullness = XKEYMAP (keymap)->fullness;
-  sub_maps = keymap_submaps (keymap);
+  fullness = XINT (Fhash_table_count (XKEYMAP (keymap)->table));
   GCPRO2 (keymap, sub_maps);
   GCPRO2 (keymap, sub_maps);
-  for (; !NILP (sub_maps); sub_maps = XCDR (sub_maps))
+  for (sub_maps = keymap_submaps (keymap);
+       !NILP (sub_maps);
+       sub_maps = XCDR (sub_maps))
     {
       if (MODIFIER_HASH_KEY_BITS (XCAR (XCAR (sub_maps))) != 0)
        {
     {
       if (MODIFIER_HASH_KEY_BITS (XCAR (XCAR (sub_maps))) != 0)
        {
-         Lisp_Object sub_map = XCDR (XCAR (sub_maps));
-         fullness--; /* don't count bucky maps */
-         fullness += keymap_fullness (sub_map);
+         Lisp_Object bucky_map = XCDR (XCAR (sub_maps));
+         fullness--; /* don't count bucky maps themselves. */
+         fullness += keymap_fullness (bucky_map);
        }
     }
   UNGCPRO;
        }
     }
   UNGCPRO;
@@ -1284,19 +1283,17 @@ define_key_check_and_coerce_keysym (Lisp_Object spec,
       /* #### This bites!  I want to be able to write (control shift a) */
       if (modifiers & MOD_SHIFT)
        signal_simple_error
       /* #### This bites!  I want to be able to write (control shift a) */
       if (modifiers & MOD_SHIFT)
        signal_simple_error
-         ("the `shift' modifier may not be applied to ASCII keysyms",
+         ("The `shift' modifier may not be applied to ASCII keysyms",
           spec);
     }
   else
     {
           spec);
     }
   else
     {
-      signal_simple_error ("unknown keysym specifier",
-                          *keysym);
+      signal_simple_error ("Unknown keysym specifier", *keysym);
     }
 
   if (SYMBOLP (*keysym))
     {
     }
 
   if (SYMBOLP (*keysym))
     {
-      char *name = (char *)
-       string_data (XSYMBOL (*keysym)->name);
+      char *name = (char *) string_data (XSYMBOL (*keysym)->name);
 
       /* FSFmacs uses symbols with the printed representation of keysyms in
         their names, like 'M-x, and we use the syntax '(meta x).  So, to avoid
 
       /* FSFmacs uses symbols with the printed representation of keysyms in
         their names, like 'M-x, and we use the syntax '(meta x).  So, to avoid
@@ -1359,6 +1356,8 @@ define_key_check_and_coerce_keysym (Lisp_Object spec,
        *keysym = QKescape;
       else if (EQ (*keysym, QDEL))
        *keysym = QKdelete;
        *keysym = QKescape;
       else if (EQ (*keysym, QDEL))
        *keysym = QKdelete;
+      else if (EQ (*keysym, QSPC))
+       *keysym = QKspace;
       else if (EQ (*keysym, QBS))
        *keysym = QKbackspace;
       /* Emacs compatibility */
       else if (EQ (*keysym, QBS))
        *keysym = QKbackspace;
       /* Emacs compatibility */
@@ -1398,7 +1397,7 @@ define_key_parser (Lisp_Object spec, struct key_data *returned_value)
 {
   if (CHAR_OR_CHAR_INTP (spec))
     {
 {
   if (CHAR_OR_CHAR_INTP (spec))
     {
-      struct Lisp_Event event;
+      Lisp_Event event;
       event.event_type = empty_event;
       character_to_event (XCHAR_OR_CHAR_INT (spec), &event,
                          XCONSOLE (Vselected_console), 0, 0);
       event.event_type = empty_event;
       character_to_event (XCHAR_OR_CHAR_INT (spec), &event,
                          XCONSOLE (Vselected_console), 0, 0);
@@ -1474,19 +1473,19 @@ define_key_parser (Lisp_Object spec, struct key_data *returned_value)
          if (!NILP (XCDR (rest)))
            {
              if (! modifier)
          if (!NILP (XCDR (rest)))
            {
              if (! modifier)
-               signal_simple_error ("unknown modifier", keysym);
+               signal_simple_error ("Unknown modifier", keysym);
            }
          else
            {
              if (modifier)
            }
          else
            {
              if (modifier)
-               signal_simple_error ("nothing but modifiers here",
+               signal_simple_error ("Nothing but modifiers here",
                                     spec);
            }
          rest = XCDR (rest);
          QUIT;
        }
       if (!NILP (rest))
                                     spec);
            }
          rest = XCDR (rest);
          QUIT;
        }
       if (!NILP (rest))
-        signal_simple_error ("dotted list", spec);
+        signal_simple_error ("List must be nil-terminated", spec);
 
       define_key_check_and_coerce_keysym (spec, &keysym, modifiers);
       returned_value->keysym = keysym;
 
       define_key_check_and_coerce_keysym (spec, &keysym, modifiers);
       returned_value->keysym = keysym;
@@ -1494,7 +1493,7 @@ define_key_parser (Lisp_Object spec, struct key_data *returned_value)
     }
   else
     {
     }
   else
     {
-      signal_simple_error ("unknown key-sequence specifier",
+      signal_simple_error ("Unknown key-sequence specifier",
                           spec);
     }
 }
                           spec);
     }
 }
@@ -1513,7 +1512,7 @@ key_desc_list_to_event (Lisp_Object list, Lisp_Object event,
     {
       Lisp_Object fn, arg;
       if (! NILP (Fcdr (Fcdr (list))))
     {
       Lisp_Object fn, arg;
       if (! NILP (Fcdr (Fcdr (list))))
-       signal_simple_error ("invalid menu event desc", list);
+       signal_simple_error ("Invalid menu event desc", list);
       arg = Fcar (Fcdr (list));
       if (SYMBOLP (arg))
        fn = Qcall_interactively;
       arg = Fcar (Fcdr (list));
       if (SYMBOLP (arg))
        fn = Qcall_interactively;
@@ -1546,8 +1545,7 @@ key_desc_list_to_event (Lisp_Object list, Lisp_Object event,
 
 
 int
 
 
 int
-event_matches_key_specifier_p (struct Lisp_Event *event,
-                              Lisp_Object key_specifier)
+event_matches_key_specifier_p (Lisp_Event *event, Lisp_Object key_specifier)
 {
   Lisp_Object event2;
   int retval;
 {
   Lisp_Object event2;
   int retval;
@@ -1598,9 +1596,9 @@ event_matches_key_specifier_p (struct Lisp_Event *event,
 }
 
 static int
 }
 
 static int
-meta_prefix_char_p (CONST struct key_data *key)
+meta_prefix_char_p (const struct key_data *key)
 {
 {
-  struct Lisp_Event event;
+  Lisp_Event event;
 
   event.event_type = key_press_event;
   event.channel = Vselected_console;
 
   event.event_type = key_press_event;
   event.channel = Vselected_console;
@@ -1621,6 +1619,12 @@ This can be useful, e.g., to determine if the user pressed `help-char' or
          ? Qt : Qnil);
 }
 
          ? Qt : Qnil);
 }
 
+#define MACROLET(k,m) do {             \
+  returned_value->keysym = (k);                \
+  returned_value->modifiers = (m);     \
+  RETURN_SANS_WARNINGS;                        \
+} while (0)
+
 /* ASCII grunge.
    Given a keysym, return another keysym/modifier pair which could be
    considered the same key in an ASCII world.  Backspace returns ^H, for
 /* ASCII grunge.
    Given a keysym, return another keysym/modifier pair which could be
    considered the same key in an ASCII world.  Backspace returns ^H, for
@@ -1636,9 +1640,6 @@ define_key_alternate_name (struct key_data *key,
   unsigned int modifiers_sans_meta = (modifiers & (~MOD_META));
   returned_value->keysym = Qnil; /* By default, no "alternate" key */
   returned_value->modifiers = 0;
   unsigned int modifiers_sans_meta = (modifiers & (~MOD_META));
   returned_value->keysym = Qnil; /* By default, no "alternate" key */
   returned_value->modifiers = 0;
-#define MACROLET(k,m) do { returned_value->keysym = (k); \
-                          returned_value->modifiers = (m); \
-                           RETURN__; } while (0)
   if (modifiers_sans_meta == MOD_CONTROL)
     {
       if EQ (keysym, QKspace)
   if (modifiers_sans_meta == MOD_CONTROL)
     {
       if EQ (keysym, QKspace)
@@ -1903,20 +1904,17 @@ these features.
                 (defvar my-escape-map (lookup-key my-map "\e"))
                 if the luser really wants the map in a variable.
                 */
                 (defvar my-escape-map (lookup-key my-map "\e"))
                 if the luser really wants the map in a variable.
                 */
-             Lisp_Object mmap;
+             Lisp_Object meta_map;
               struct gcpro ngcpro1;
 
               NGCPRO1 (c);
               struct gcpro ngcpro1;
 
               NGCPRO1 (c);
-              mmap = Fgethash (MAKE_MODIFIER_HASH_KEY (MOD_META),
-                               XKEYMAP (keymap)->table, Qnil);
-             if (!NILP (mmap)
-                 && keymap_fullness (mmap) != 0)
-               {
-                  Lisp_Object desc
-                    = Fsingle_key_description (Vmeta_prefix_char);
-                 signal_simple_error_2
-                   ("Map contains meta-bindings, can't bind", desc, keymap);
-               }
+              meta_map = Fgethash (MAKE_MODIFIER_HASH_KEY (MOD_META),
+                                  XKEYMAP (keymap)->table, Qnil);
+             if (!NILP (meta_map)
+                 && keymap_fullness (meta_map) != 0)
+               signal_simple_error_2
+                 ("Map contains meta-bindings, can't bind",
+                  Fsingle_key_description (Vmeta_prefix_char), keymap);
               NUNGCPRO;
            }
          else
               NUNGCPRO;
            }
          else
@@ -1937,7 +1935,7 @@ these features.
 
       if (metized)
        {
 
       if (metized)
        {
-         raw_key1.modifiers  |= MOD_META;
+         raw_key1.modifiers |= MOD_META;
          raw_key2.modifiers |= MOD_META;
          metized = 0;
        }
          raw_key2.modifiers |= MOD_META;
          metized = 0;
        }
@@ -1970,7 +1968,7 @@ these features.
            keymap_store (keymap, &raw_key1, cmd);
          }
        if (NILP (Fkeymapp (cmd)))
            keymap_store (keymap, &raw_key1, cmd);
          }
        if (NILP (Fkeymapp (cmd)))
-          signal_simple_error_2 ("invalid prefix keys in sequence",
+          signal_simple_error_2 ("Invalid prefix keys in sequence",
                                 c, keys);
 
        if (ascii_hack && !NILP (raw_key2.keysym) &&
                                 c, keys);
 
        if (ascii_hack && !NILP (raw_key2.keysym) &&
@@ -1994,7 +1992,7 @@ these features.
 struct raw_lookup_key_mapper_closure
 {
   int remaining;
 struct raw_lookup_key_mapper_closure
 {
   int remaining;
-  CONST struct key_data *raw_keys;
+  const struct key_data *raw_keys;
   int raw_keys_count;
   int keys_so_far;
   int accept_default;
   int raw_keys_count;
   int keys_so_far;
   int accept_default;
@@ -2005,7 +2003,7 @@ static Lisp_Object raw_lookup_key_mapper (Lisp_Object k, void *);
 /* Caller should gc-protect args (keymaps may autoload) */
 static Lisp_Object
 raw_lookup_key (Lisp_Object keymap,
 /* Caller should gc-protect args (keymaps may autoload) */
 static Lisp_Object
 raw_lookup_key (Lisp_Object keymap,
-                CONST struct key_data *raw_keys, int raw_keys_count,
+                const struct key_data *raw_keys, int raw_keys_count,
                 int keys_so_far, int accept_default)
 {
   /* This function can GC */
                 int keys_so_far, int accept_default)
 {
   /* This function can GC */
@@ -2028,7 +2026,7 @@ raw_lookup_key_mapper (Lisp_Object k, void *arg)
   int accept_default = c->accept_default;
   int remaining = c->remaining;
   int keys_so_far = c->keys_so_far;
   int accept_default = c->accept_default;
   int remaining = c->remaining;
   int keys_so_far = c->keys_so_far;
-  CONST struct key_data *raw_keys = c->raw_keys;
+  const struct key_data *raw_keys = c->raw_keys;
   Lisp_Object cmd;
 
   if (! meta_prefix_char_p (&(raw_keys[0])))
   Lisp_Object cmd;
 
   if (! meta_prefix_char_p (&(raw_keys[0])))
@@ -2057,7 +2055,7 @@ raw_lookup_key_mapper (Lisp_Object k, void *arg)
        * element is the meta-prefix-char will return the keymap that
        * the "meta" keys are stored in, if there is no binding for
        * the meta-prefix-char (and if this map has a "meta" submap).
        * element is the meta-prefix-char will return the keymap that
        * the "meta" keys are stored in, if there is no binding for
        * the meta-prefix-char (and if this map has a "meta" submap).
-       * If this map doesnt have a "meta" submap, then the
+       * If this map doesn't have a "meta" submap, then the
        * meta-prefix-char is looked up just like any other key.
        */
       if (remaining == 0)
        * meta-prefix-char is looked up just like any other key.
        */
       if (remaining == 0)
@@ -2119,7 +2117,7 @@ lookup_keys (Lisp_Object keymap, int nkeys, Lisp_Object *keys,
   if (nkeys == 0)
     return Qnil;
 
   if (nkeys == 0)
     return Qnil;
 
-  if (nkeys < (countof (kkk)))
+  if (nkeys < countof (kkk))
     raw_keys = kkk;
   else
     raw_keys = alloca_array (struct key_data, nkeys);
     raw_keys = kkk;
   else
     raw_keys = alloca_array (struct key_data, nkeys);
@@ -2149,7 +2147,7 @@ lookup_events (Lisp_Object event_head, int nmaps, Lisp_Object keymaps[],
 
   nkeys = event_chain_count (event_head);
 
 
   nkeys = event_chain_count (event_head);
 
-  if (nkeys < (countof (kkk)))
+  if (nkeys < countof (kkk))
     raw_keys = kkk;
   else
     raw_keys = alloca_array (struct key_data, nkeys);
     raw_keys = kkk;
   else
     raw_keys = alloca_array (struct key_data, nkeys);
@@ -2226,7 +2224,7 @@ it takes to reach a non-prefix command.
    map of the buffer in which the mouse was clicked in event0 is a click.
 
    It would be kind of nice if this were in Lisp so that this semi-hairy
    map of the buffer in which the mouse was clicked in event0 is a click.
 
    It would be kind of nice if this were in Lisp so that this semi-hairy
-   semi-heuristic command-lookup behaviour could be readily understood and
+   semi-heuristic command-lookup behavior could be readily understood and
    customised.  However, this needs to be pretty fast, or performance of
    keyboard macros goes to shit; putting this in lisp slows macros down
    2-3x.  And they're already slower than v18 by 5-6x.
    customised.  However, this needs to be pretty fast, or performance of
    keyboard macros goes to shit; putting this in lisp slows macros down
    2-3x.  And they're already slower than v18 by 5-6x.
@@ -2375,8 +2373,7 @@ get_relevant_keymaps (Lisp_Object keys,
                  get_relevant_extent_keymaps
                    (Fevent_modeline_position (terminal),
                     XBUFFER (buffer)->generated_modeline_string,
                  get_relevant_extent_keymaps
                    (Fevent_modeline_position (terminal),
                     XBUFFER (buffer)->generated_modeline_string,
-                    /* #### third arg should maybe be a glyph. */
-                    Qnil, &closure);
+                    Fevent_glyph_extent (terminal), &closure);
 
                  if (!UNBOUNDP (map) && !NILP (map))
                    relevant_map_push (get_keymap (map, 1, 1), &closure);
 
                  if (!UNBOUNDP (map) && !NILP (map))
                    relevant_map_push (get_keymap (map, 1, 1), &closure);
@@ -2410,7 +2407,7 @@ get_relevant_keymaps (Lisp_Object keys,
 
   {
     int nmaps = closure.nmaps;
 
   {
     int nmaps = closure.nmaps;
-    /* Silently truncate at 100 keymaps to prevent infinite losssage */
+    /* Silently truncate at 100 keymaps to prevent infinite lossage */
     if (nmaps >= max_maps && max_maps > 0)
       maps[max_maps - 1] = Vcurrent_global_map;
     else
     if (nmaps >= max_maps && max_maps > 0)
       maps[max_maps - 1] = Vcurrent_global_map;
     else
@@ -2426,7 +2423,7 @@ get_relevant_keymaps (Lisp_Object keys,
    first element in the list returned.  This is so we can correctly
    search the keymaps associated with glyphs which may be physically
    disjoint from their extents: for example, if a glyph is out in the
    first element in the list returned.  This is so we can correctly
    search the keymaps associated with glyphs which may be physically
    disjoint from their extents: for example, if a glyph is out in the
-   margin, we should still consult the kemyap of that glyph's extent,
+   margin, we should still consult the keymap of that glyph's extent,
    which may not itself be under the mouse.
  */
 
    which may not itself be under the mouse.
  */
 
@@ -2744,33 +2741,29 @@ Return the current global keymap.
 
 struct map_keymap_unsorted_closure
 {
 
 struct map_keymap_unsorted_closure
 {
-  void (*fn) (CONST struct key_data *, Lisp_Object binding, void *arg);
+  void (*fn) (const struct key_data *, Lisp_Object binding, void *arg);
   void *arg;
   unsigned int modifiers;
 };
 
 /* used by map_keymap() */
 static int
   void *arg;
   unsigned int modifiers;
 };
 
 /* used by map_keymap() */
 static int
-map_keymap_unsorted_mapper (CONST void *hash_key, void *hash_contents,
+map_keymap_unsorted_mapper (Lisp_Object keysym, Lisp_Object value,
                             void *map_keymap_unsorted_closure)
 {
   /* This function can GC */
                             void *map_keymap_unsorted_closure)
 {
   /* This function can GC */
-  Lisp_Object keysym;
-  Lisp_Object contents;
   struct map_keymap_unsorted_closure *closure =
     (struct map_keymap_unsorted_closure *) map_keymap_unsorted_closure;
   unsigned int modifiers = closure->modifiers;
   unsigned int mod_bit;
   struct map_keymap_unsorted_closure *closure =
     (struct map_keymap_unsorted_closure *) map_keymap_unsorted_closure;
   unsigned int modifiers = closure->modifiers;
   unsigned int mod_bit;
-  CVOID_TO_LISP (keysym, hash_key);
-  VOID_TO_LISP (contents, hash_contents);
   mod_bit = MODIFIER_HASH_KEY_BITS (keysym);
   if (mod_bit != 0)
     {
       int omod = modifiers;
       closure->modifiers = (modifiers | mod_bit);
   mod_bit = MODIFIER_HASH_KEY_BITS (keysym);
   if (mod_bit != 0)
     {
       int omod = modifiers;
       closure->modifiers = (modifiers | mod_bit);
-      contents = get_keymap (contents, 1, 0);
+      value = get_keymap (value, 1, 0);
       elisp_maphash (map_keymap_unsorted_mapper,
       elisp_maphash (map_keymap_unsorted_mapper,
-                    XKEYMAP (contents)->table,
+                    XKEYMAP (value)->table,
                     map_keymap_unsorted_closure);
       closure->modifiers = omod;
     }
                     map_keymap_unsorted_closure);
       closure->modifiers = omod;
     }
@@ -2779,7 +2772,7 @@ map_keymap_unsorted_mapper (CONST void *hash_key, void *hash_contents,
       struct key_data key;
       key.keysym = keysym;
       key.modifiers = modifiers;
       struct key_data key;
       key.keysym = keysym;
       key.modifiers = modifiers;
-      ((*closure->fn) (&key, contents, closure->arg));
+      ((*closure->fn) (&key, value, closure->arg));
     }
   return 0;
 }
     }
   return 0;
 }
@@ -2792,16 +2785,13 @@ struct map_keymap_sorted_closure
 
 /* used by map_keymap_sorted() */
 static int
 
 /* used by map_keymap_sorted() */
 static int
-map_keymap_sorted_mapper (CONST void *hash_key, void *hash_contents,
+map_keymap_sorted_mapper (Lisp_Object key, Lisp_Object value,
                           void *map_keymap_sorted_closure)
 {
   struct map_keymap_sorted_closure *cl =
     (struct map_keymap_sorted_closure *) map_keymap_sorted_closure;
                           void *map_keymap_sorted_closure)
 {
   struct map_keymap_sorted_closure *cl =
     (struct map_keymap_sorted_closure *) map_keymap_sorted_closure;
-  Lisp_Object key, contents;
   Lisp_Object *list = cl->result_locative;
   Lisp_Object *list = cl->result_locative;
-  CVOID_TO_LISP (key, hash_key);
-  VOID_TO_LISP (contents, hash_contents);
-  *list = Fcons (Fcons (key, contents), *list);
+  *list = Fcons (Fcons (key, value), *list);
   return 0;
 }
 
   return 0;
 }
 
@@ -2890,7 +2880,7 @@ map_keymap_sort_predicate (Lisp_Object obj1, Lisp_Object obj2,
 static void
 map_keymap_sorted (Lisp_Object keymap_table,
                    unsigned int modifiers,
 static void
 map_keymap_sorted (Lisp_Object keymap_table,
                    unsigned int modifiers,
-                   void (*function) (CONST struct key_data *key,
+                   void (*function) (const struct key_data *key,
                                      Lisp_Object binding,
                                      void *map_keymap_sorted_closure),
                    void *map_keymap_sorted_closure)
                                      Lisp_Object binding,
                                      void *map_keymap_sorted_closure),
                    void *map_keymap_sorted_closure)
@@ -2899,7 +2889,7 @@ map_keymap_sorted (Lisp_Object keymap_table,
   struct gcpro gcpro1;
   Lisp_Object contents = Qnil;
 
   struct gcpro gcpro1;
   Lisp_Object contents = Qnil;
 
-  if (XINT (Fhashtable_fullness (keymap_table)) == 0)
+  if (XINT (Fhash_table_count (keymap_table)) == 0)
     return;
 
   GCPRO1 (contents);
     return;
 
   GCPRO1 (contents);
@@ -2935,7 +2925,7 @@ map_keymap_sorted (Lisp_Object keymap_table,
 
 /* used by Fmap_keymap() */
 static void
 
 /* used by Fmap_keymap() */
 static void
-map_keymap_mapper (CONST struct key_data *key,
+map_keymap_mapper (const struct key_data *key,
                    Lisp_Object binding,
                    void *function)
 {
                    Lisp_Object binding,
                    void *function)
 {
@@ -2948,7 +2938,7 @@ map_keymap_mapper (CONST struct key_data *key,
 
 static void
 map_keymap (Lisp_Object keymap_table, int sort_first,
 
 static void
 map_keymap (Lisp_Object keymap_table, int sort_first,
-            void (*function) (CONST struct key_data *key,
+            void (*function) (const struct key_data *key,
                               Lisp_Object binding,
                               void *fn_arg),
             void *fn_arg)
                               Lisp_Object binding,
                               void *fn_arg),
             void *fn_arg)
@@ -3104,23 +3094,28 @@ then the value includes only maps for prefixes that start with PREFIX.
   c.tail = Qnil;
   GCPRO4 (accessible_keymaps, c.tail, prefix, keymap);
 
   c.tail = Qnil;
   GCPRO4 (accessible_keymaps, c.tail, prefix, keymap);
 
- retry:
   keymap = get_keymap (keymap, 1, 1);
   keymap = get_keymap (keymap, 1, 1);
+
+ retry:
   if (NILP (prefix))
   if (NILP (prefix))
-    prefix = make_vector (0, Qnil);
-  else if (!VECTORP (prefix) || STRINGP (prefix))
     {
     {
-      prefix = wrong_type_argument (Qarrayp, prefix);
-      goto retry;
+      prefix = make_vector (0, Qnil);
     }
     }
-  else
+  else if (VECTORP (prefix) || STRINGP (prefix))
     {
       int len = XINT (Flength (prefix));
     {
       int len = XINT (Flength (prefix));
-      Lisp_Object def = Flookup_key (keymap, prefix, Qnil);
+      Lisp_Object def;
       Lisp_Object p;
       int iii;
       struct gcpro ngcpro1;
 
       Lisp_Object p;
       int iii;
       struct gcpro ngcpro1;
 
+      if (len == 0)
+       {
+         prefix = Qnil;
+         goto retry;
+       }
+
+      def = Flookup_key (keymap, prefix, Qnil);
       def = get_keymap (def, 0, 1);
       if (!KEYMAPP (def))
        goto RETURN;
       def = get_keymap (def, 0, 1);
       if (!KEYMAPP (def))
        goto RETURN;
@@ -3137,12 +3132,16 @@ then the value includes only maps for prefixes that start with PREFIX.
       NUNGCPRO;
       prefix = p;
     }
       NUNGCPRO;
       prefix = p;
     }
+  else
+    {
+      prefix = wrong_type_argument (Qarrayp, prefix);
+      goto retry;
+    }
 
   accessible_keymaps = list1 (Fcons (prefix, keymap));
 
 
   accessible_keymaps = list1 (Fcons (prefix, keymap));
 
-  /* For each map in the list maps,
-     look at any other maps it points to
-     and stick them at the end if they are not already in the list */
+  /* For each map in the list maps, look at any other maps it points
+     to and stick them at the end if they are not already in the list */
 
   for (c.tail = accessible_keymaps;
        !NILP (c.tail);
 
   for (c.tail = accessible_keymaps;
        !NILP (c.tail);
@@ -3187,9 +3186,9 @@ spaces are put between sequence elements, etc...
       for (i = 0; i < size; i++)
        {
          Lisp_Object s2 = Fsingle_key_description
       for (i = 0; i < size; i++)
        {
          Lisp_Object s2 = Fsingle_key_description
-           (((STRINGP (keys))
-             ? make_char (string_char (XSTRING (keys), i))
-             : XVECTOR_DATA (keys)[i]));
+           (STRINGP (keys)
+            ? make_char (string_char (XSTRING (keys), i))
+            : XVECTOR_DATA (keys)[i]);
 
          if (i == 0)
            string = s2;
 
          if (i == 0)
            string = s2;
@@ -3220,7 +3219,7 @@ of a key read from the user rather than a character from a buffer.
       char buf [255];
       if (!EVENTP (key))
        {
       char buf [255];
       if (!EVENTP (key))
        {
-         struct Lisp_Event event;
+         Lisp_Event event;
          event.event_type = empty_event;
          CHECK_CHAR_COERCE_INT (key);
          character_to_event (XCHAR (key), &event,
          event.event_type = empty_event;
          CHECK_CHAR_COERCE_INT (key);
          character_to_event (XCHAR (key), &event,
@@ -3269,7 +3268,7 @@ of a key read from the user rather than a character from a buffer.
 #endif
                strcpy (bufp, (char *) string_data (XSYMBOL (keysym)->name));
              if (!NILP (XCDR (rest)))
 #endif
                strcpy (bufp, (char *) string_data (XSYMBOL (keysym)->name));
              if (!NILP (XCDR (rest)))
-               signal_simple_error ("invalid key description",
+               signal_simple_error ("Invalid key description",
                                     key);
            }
        }
                                     key);
            }
        }
@@ -3469,7 +3468,7 @@ static void
 format_raw_keys (struct key_data *keys, int count, char *buf)
 {
   int i;
 format_raw_keys (struct key_data *keys, int count, char *buf)
 {
   int i;
-  struct Lisp_Event event;
+  Lisp_Event event;
   event.event_type = key_press_event;
   event.channel = Vselected_console;
   for (i = 0; i < count; i++)
   event.event_type = key_press_event;
   event.channel = Vselected_console;
   for (i = 0; i < count; i++)
@@ -3526,9 +3525,9 @@ where_is_recursive_mapper (Lisp_Object map, void *arg)
   /* This function can GC */
   struct where_is_closure *c = (struct where_is_closure *) arg;
   Lisp_Object definition = c->definition;
   /* This function can GC */
   struct where_is_closure *c = (struct where_is_closure *) arg;
   Lisp_Object definition = c->definition;
-  CONST int firstonly = c->firstonly;
-  CONST unsigned int keys_count = c->keys_count;
-  CONST unsigned int modifiers_so_far = c->modifiers_so_far;
+  const int firstonly = c->firstonly;
+  const unsigned int keys_count = c->keys_count;
+  const unsigned int modifiers_so_far = c->modifiers_so_far;
   char *target_buffer = c->target_buffer;
   Lisp_Object keys = Fgethash (definition,
                                XKEYMAP (map)->inverse_table,
   char *target_buffer = c->target_buffer;
   Lisp_Object keys = Fgethash (definition,
                                XKEYMAP (map)->inverse_table,
@@ -3546,7 +3545,7 @@ where_is_recursive_mapper (Lisp_Object map, void *arg)
 
       for (;;) /* loop over all keys that match */
        {
 
       for (;;) /* loop over all keys that match */
        {
-         Lisp_Object k = ((CONSP (keys)) ? XCAR (keys) : keys);
+         Lisp_Object k = CONSP (keys) ? XCAR (keys) : keys;
          int i;
 
          so_far [keys_count].keysym = k;
          int i;
 
          so_far [keys_count].keysym = k;
@@ -3644,7 +3643,7 @@ where_is_recursive_mapper (Lisp_Object map, void *arg)
          if (! c->keys_so_far_malloced)
            {
              struct key_data *new = xnew_array (struct key_data, size);
          if (! c->keys_so_far_malloced)
            {
              struct key_data *new = xnew_array (struct key_data, size);
-             memcpy ((void *)new, (CONST void *)c->keys_so_far,
+             memcpy ((void *)new, (const void *)c->keys_so_far,
                      c->keys_so_far_total_size * sizeof (struct key_data));
            }
          else
                      c->keys_so_far_total_size * sizeof (struct key_data));
            }
          else
@@ -3752,7 +3751,7 @@ Fifth argument MOUSE-ONLY-P says to only print bindings for mouse clicks.
 }
 
 
 }
 
 
-/* Insert a desription of the key bindings in STARTMAP,
+/* Insert a description of the key bindings in STARTMAP,
     followed by those of all maps reachable through STARTMAP.
    If PARTIAL is nonzero, omit certain "uninteresting" commands
     (such as `undefined').
     followed by those of all maps reachable through STARTMAP.
    If PARTIAL is nonzero, omit certain "uninteresting" commands
     (such as `undefined').
@@ -3897,7 +3896,7 @@ struct describe_map_closure
 
 struct describe_map_shadow_closure
   {
 
 struct describe_map_shadow_closure
   {
-    CONST struct key_data *raw_key;
+    const struct key_data *raw_key;
     Lisp_Object self;
   };
 
     Lisp_Object self;
   };
 
@@ -3926,7 +3925,7 @@ keymap_lookup_inherited_mapper (Lisp_Object km, void *arg)
 
 
 static void
 
 
 static void
-describe_map_mapper (CONST struct key_data *key,
+describe_map_mapper (const struct key_data *key,
                      Lisp_Object binding,
                     void *describe_map_closure)
 {
                      Lisp_Object binding,
                     void *describe_map_closure)
 {
@@ -3936,7 +3935,7 @@ describe_map_mapper (CONST struct key_data *key,
   Lisp_Object keysym = key->keysym;
   unsigned int modifiers = key->modifiers;
 
   Lisp_Object keysym = key->keysym;
   unsigned int modifiers = key->modifiers;
 
-  /* Dont mention suppressed commands.  */
+  /* Don't mention suppressed commands.  */
   if (SYMBOLP (binding)
       && !NILP (closure->partial)
       && !NILP (Fget (binding, closure->partial, Qnil)))
   if (SYMBOLP (binding)
       && !NILP (closure->partial)
       && !NILP (Fget (binding, closure->partial, Qnil)))
@@ -4143,7 +4142,7 @@ describe_map (Lisp_Object keymap, Lisp_Object elt_prefix,
            {
              Lisp_Object code = Fget (keysym, Vcharacter_set_property, Qnil);
              Emchar c = (CHAR_OR_CHAR_INTP (code)
            {
              Lisp_Object code = Fget (keysym, Vcharacter_set_property, Qnil);
              Emchar c = (CHAR_OR_CHAR_INTP (code)
-                         ? XCHAR_OR_CHAR_INT (code) : -1);
+                         ? XCHAR_OR_CHAR_INT (code) : (Emchar) -1);
              /* Calling Fsingle_key_description() would cons more */
 #if 0                           /* This is bogus */
              if (EQ (keysym, QKlinefeed))
              /* Calling Fsingle_key_description() would cons more */
 #if 0                           /* This is bogus */
              if (EQ (keysym, QKlinefeed))
@@ -4205,6 +4204,8 @@ describe_map (Lisp_Object keymap, Lisp_Object elt_prefix,
 void
 syms_of_keymap (void)
 {
 void
 syms_of_keymap (void)
 {
+  INIT_LRECORD_IMPLEMENTATION (keymap);
+
   defsymbol (&Qminor_mode_map_alist, "minor-mode-map-alist");
 
   defsymbol (&Qkeymapp, "keymapp");
   defsymbol (&Qminor_mode_map_alist, "minor-mode-map-alist");
 
   defsymbol (&Qkeymapp, "keymapp");
@@ -4286,6 +4287,7 @@ syms_of_keymap (void)
   defsymbol (&QRET, "RET");
   defsymbol (&QESC, "ESC");
   defsymbol (&QDEL, "DEL");
   defsymbol (&QRET, "RET");
   defsymbol (&QESC, "ESC");
   defsymbol (&QDEL, "DEL");
+  defsymbol (&QSPC, "SPC");
   defsymbol (&QBS, "BS");
 }
 
   defsymbol (&QBS, "BS");
 }
 
@@ -4325,10 +4327,12 @@ Keymap of key translations that can override keymaps.
 This keymap works like `function-key-map', but comes after that,
 and applies even for keys that have ordinary bindings.
 */ );
 This keymap works like `function-key-map', but comes after that,
 and applies even for keys that have ordinary bindings.
 */ );
+  Vkey_translation_map = Qnil;
 
   DEFVAR_LISP ("vertical-divider-map", &Vvertical_divider_map /*
 Keymap which handles mouse clicks over vertical dividers.
 */ );
 
   DEFVAR_LISP ("vertical-divider-map", &Vvertical_divider_map /*
 Keymap which handles mouse clicks over vertical dividers.
 */ );
+  Vvertical_divider_map = Qnil;
 
   DEFVAR_INT ("keymap-tick", &keymap_tick /*
 Incremented for each change to any keymap.
 
   DEFVAR_INT ("keymap-tick", &keymap_tick /*
 Incremented for each change to any keymap.
@@ -4337,7 +4341,7 @@ Incremented for each change to any keymap.
 
   staticpro (&Vcurrent_global_map);
 
 
   staticpro (&Vcurrent_global_map);
 
-  Vsingle_space_string = make_pure_string ((CONST Bufbyte *) " ", 1, Qnil, 1);
+  Vsingle_space_string = make_string ((const Bufbyte *) " ", 1);
   staticpro (&Vsingle_space_string);
 }
 
   staticpro (&Vsingle_space_string);
 }