+/* Global, local, and minor mode keymap stuff. */
+
+/* We can't put these variables inside current_minor_maps, since under
+ some systems, static gets macro-defined to be the empty string.
+ Ickypoo. */
+static Lisp_Object *cmm_modes, *cmm_maps;
+static int cmm_size;
+
+/* Store a pointer to an array of the keymaps of the currently active
+ minor modes in *buf, and return the number of maps it contains.
+
+ This function always returns a pointer to the same buffer, and may
+ free or reallocate it, so if you want to keep it for a long time or
+ hand it out to lisp code, copy it. This procedure will be called
+ for every key sequence read, so the nice lispy approach (return a
+ new assoclist, list, what have you) for each invocation would
+ result in a lot of consing over time.
+
+ If we used xrealloc/xmalloc and ran out of memory, they would throw
+ back to the command loop, which would try to read a key sequence,
+ which would call this function again, resulting in an infinite
+ loop. Instead, we'll use realloc/malloc and silently truncate the
+ list, let the key sequence be read, and hope some other piece of
+ code signals the error. */
+int
+current_minor_maps (modeptr, mapptr)
+ Lisp_Object **modeptr, **mapptr;
+{
+ int i = 0;
+ Lisp_Object alist, assoc, var, val;
+
+ for (alist = Vminor_mode_map_alist;
+ CONSP (alist);
+ alist = XCONS (alist)->cdr)
+ if ((assoc = XCONS (alist)->car, CONSP (assoc))
+ && (var = XCONS (assoc)->car, SYMBOLP (var))
+ && (val = find_symbol_value (var), ! EQ (val, Qunbound))
+ && ! NILP (val))
+ {
+ if (i >= cmm_size)
+ {
+ Lisp_Object *newmodes, *newmaps;
+
+ if (cmm_maps)
+ {
+ BLOCK_INPUT;
+ cmm_size *= 2;
+ newmodes
+ = (Lisp_Object *) realloc (cmm_modes,
+ cmm_size * sizeof (Lisp_Object));
+ newmaps
+ = (Lisp_Object *) realloc (cmm_maps,
+ cmm_size * sizeof (Lisp_Object));
+ UNBLOCK_INPUT;
+ }
+ else
+ {
+ BLOCK_INPUT;
+ cmm_size = 30;
+ newmodes
+ = (Lisp_Object *) malloc (cmm_size * sizeof (Lisp_Object));
+ newmaps
+ = (Lisp_Object *) malloc (cmm_size * sizeof (Lisp_Object));
+ UNBLOCK_INPUT;
+ }
+
+ if (newmaps && newmodes)
+ {
+ cmm_modes = newmodes;
+ cmm_maps = newmaps;
+ }
+ else
+ break;
+ }
+ cmm_modes[i] = var;
+ cmm_maps [i] = Findirect_function (XCONS (assoc)->cdr);
+ i++;
+ }
+
+ if (modeptr) *modeptr = cmm_modes;
+ if (mapptr) *mapptr = cmm_maps;
+ return i;
+}
+
+/* GC is possible in this function if it autoloads a keymap. */
+
+DEFUN ("key-binding", Fkey_binding, Skey_binding, 1, 2, 0,