# HG changeset patch # User Jim Blandy # Date 720509087 0 # Node ID 72b7bbcaf7d832e72b23fc0b695ab8acc5dd9656 # Parent 02bd6870de868a2bce4c86bdb8bc90c2c41afa51 * 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. diff -r 02bd6870de86 -r 72b7bbcaf7d8 src/keymap.c --- 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