changeset 1517:72b7bbcaf7d8

* keymap.c (Fdefine_key, Flookup_key, describe_map): Don't assume that Flength returns an integer. * keymap.c: Deal with autoloaded keymaps properly. (get_keymap_1): Renamed to inner_get_keymap; made static. New argument AUTOLOAD says to pursue autoloads if non-zero. (Fkeymapp, get_keymap, get_keyelt, Flookup_key): Ask get_keymap_1 not to perform autoloads. (Fdefine_key): Ask get_keymap_1 to perform autoloads. Since autoloading may GC, remember that we have to GCPRO our local variables now. (Fminor_mode_key_binding): Call get_keymap instead of calling get_keymap_1 with equivalent arguments.
author Jim Blandy <jimb@redhat.com>
date Sat, 31 Oct 1992 05:24:47 +0000
parents 02bd6870de86
children eda3ace74d74
files src/keymap.c
diffstat 1 files changed, 52 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/src/keymap.c	Sat Oct 31 05:24:03 1992 +0000
+++ b/src/keymap.c	Sat Oct 31 05:24:47 1992 +0000
@@ -175,34 +175,65 @@
   (object)
      Lisp_Object object;
 {
-  return (NILP (get_keymap_1 (object, 0)) ? Qnil : Qt);
+  return (NILP (get_keymap_1 (object, 0, 0)) ? Qnil : Qt);
 }
 
 /* Check that OBJECT is a keymap (after dereferencing through any
-   symbols).  If it is, return it; otherwise, return nil, or signal an
-   error if ERROR != 0.  */
+   symbols).  If it is, return it.
+
+   If AUTOLOAD is non-zero and OBJECT is a symbol whose function value
+   is an autoload form, do the autoload and try again.
+
+   ERROR controls how we respond if OBJECT isn't a keymap.
+   If ERROR is non-zero, signal an error; otherwise, just return Qnil.
+
+   Note that most of the time, we don't want to pursue autoloads.
+   Functions like Faccessible_keymaps which scan entire keymap trees
+   shouldn't load every autoloaded keymap.  I'm not sure about this,
+   but it seems to me that only read_key_sequence, Flookup_key, and
+   Fdefine_key should cause keymaps to be autoloaded.  */
+
 Lisp_Object
-get_keymap_1 (object, error)
+get_keymap_1 (object, error, autoload)
      Lisp_Object object;
-     int error;
+     int error, autoload;
 {
-  register Lisp_Object tem;
+  Lisp_Object tem;
 
+ autoload_retry:
   tem = indirect_function (object);
   if (CONSP (tem) && EQ (XCONS (tem)->car, Qkeymap))
     return tem;
 
+  /* Should we do an autoload?  */
+  if (autoload
+      && XTYPE (object) == Lisp_Symbol
+      && CONSP (tem)
+      && EQ (XCONS (tem)->car, Qautoload))
+    {
+      struct gcpro gcpro1, gcpro2;
+
+      GCPRO2 (tem, object)
+      do_autoload (tem, object);
+      UNGCPRO;
+
+      goto autoload_retry;
+    }
+
   if (error)
     wrong_type_argument (Qkeymapp, object);
   else
     return Qnil;
 }
 
+
+/* Follow any symbol chaining, and return the keymap denoted by OBJECT.
+   If OBJECT doesn't denote a keymap at all, signal an error.  */
 Lisp_Object
 get_keymap (object)
      Lisp_Object object;
 {
-  return get_keymap_1 (object, 1);
+  return get_keymap_1 (object, 0, 0);
 }
 
 
@@ -285,7 +316,7 @@
       register Lisp_Object map, tem;
 
       /* If the contents are (KEYMAP . ELEMENT), go indirect.  */
-      map = get_keymap_1 (Fcar_safe (object), 0);
+      map = get_keymap_1 (Fcar_safe (object), 0, 0);
       tem = Fkeymapp (map);
       if (!NILP (tem))
 	object = access_keymap (map, Fcdr (object), 0);
@@ -459,7 +490,7 @@
 If KEYMAP is a sparse keymap, the pair binding KEY to DEF is added at\n\
 the front of KEYMAP.")
   (keymap, key, def)
-     register Lisp_Object keymap;
+     Lisp_Object keymap;
      Lisp_Object key;
      Lisp_Object def;
 {
@@ -469,6 +500,7 @@
   register Lisp_Object cmd;
   int metized = 0;
   int length;
+  struct gcpro gcpro1, gcpro2, gcpro3;
 
   keymap = get_keymap (keymap);
 
@@ -476,10 +508,12 @@
       && XTYPE (key) != Lisp_String)
     key = wrong_type_argument (Qarrayp, key);
 
-  length = Flength (key);
+  length = XFASTINT (Flength (key));
   if (length == 0)
     return Qnil;
 
+  GCPRO3 (keymap, key, def);
+
   idx = 0;
   while (1)
     {
@@ -502,7 +536,7 @@
 	}
 
       if (idx == length)
-	return store_in_keymap (keymap, c, def);
+	RETURN_UNGCPRO (store_in_keymap (keymap, c, def));
 
       cmd = get_keyelt (access_keymap (keymap, c, 0));
 
@@ -512,12 +546,10 @@
 	  store_in_keymap (keymap, c, cmd);
 	}
 
-      tem = Fkeymapp (cmd);
-      if (NILP (tem))
+      keymap = get_keymap_1 (cmd, 0, 1);
+      if (NILP (keymap))
 	error ("Key sequence %s uses invalid prefix characters",
 	       XSTRING (key)->data);
-
-      keymap = get_keymap (cmd);
     }
 }
 
@@ -548,7 +580,7 @@
       && XTYPE (key) != Lisp_String)
     key = wrong_type_argument (Qarrayp, key);
 
-  length = Flength (key);
+  length = XFASTINT (Flength (key));
   if (length == 0)
     return keymap;
 
@@ -577,11 +609,10 @@
       if (idx == length)
 	return cmd;
 
-      tem = Fkeymapp (cmd);
-      if (NILP (tem))
+      keymap = get_keymap_1 (cmd, 0, 0);
+      if (NILP (keymap))
 	return make_number (idx);
 
-      keymap = get_keymap (cmd);
       QUIT;
     }
 }
@@ -765,7 +796,7 @@
 	&& ! NILP (binding = Flookup_key (maps[i], key))
 	&& XTYPE (binding) != Lisp_Int)
       {
-	if (! NILP (get_keymap_1 (binding, 0)))
+	if (! NILP (get_keymap (binding)))
 	  maps[j++] = Fcons (modes[i], binding);
 	else if (j == 0)
 	  return Fcons (Fcons (modes[i], binding), Qnil);
@@ -1582,7 +1613,7 @@
 {
   register Lisp_Object keysdesc;
 
-  if (!NILP (keys) && Flength (keys) > 0)
+  if (!NILP (keys) && XFASTINT (Flength (keys)) > 0)
     keysdesc = concat2 (Fkey_description (keys),
 			build_string (" "));
   else