comparison src/keymap.c @ 30134:784ef95b020b

(get_keymap_1): Add comment that this function can GC. (where_is_internal_2, where_is_internal_1): Add GCPROs, add comment that functions can GC. (Fset_keymap_parent): GCPRO arg KEYMAP.
author Gerd Moellmann <gerd@gnu.org>
date Mon, 10 Jul 2000 14:10:51 +0000
parents 94dcb1b07998
children 16a291eedbd8
comparison
equal deleted inserted replaced
30133:8db9c1163258 30134:784ef95b020b
210 210
211 Note that most of the time, we don't want to pursue autoloads. 211 Note that most of the time, we don't want to pursue autoloads.
212 Functions like Faccessible_keymaps which scan entire keymap trees 212 Functions like Faccessible_keymaps which scan entire keymap trees
213 shouldn't load every autoloaded keymap. I'm not sure about this, 213 shouldn't load every autoloaded keymap. I'm not sure about this,
214 but it seems to me that only read_key_sequence, Flookup_key, and 214 but it seems to me that only read_key_sequence, Flookup_key, and
215 Fdefine_key should cause keymaps to be autoloaded. */ 215 Fdefine_key should cause keymaps to be autoloaded.
216
217 This function can GC when AUTOLOAD is non-zero, because it calls
218 do_autoload which can GC. */
216 219
217 Lisp_Object 220 Lisp_Object
218 get_keymap_1 (object, error, autoload) 221 get_keymap_1 (object, error, autoload)
219 Lisp_Object object; 222 Lisp_Object object;
220 int error, autoload; 223 int error, autoload;
303 PARENT should be nil or another keymap.") 306 PARENT should be nil or another keymap.")
304 (keymap, parent) 307 (keymap, parent)
305 Lisp_Object keymap, parent; 308 Lisp_Object keymap, parent;
306 { 309 {
307 Lisp_Object list, prev; 310 Lisp_Object list, prev;
311 struct gcpro gcpro1;
308 int i; 312 int i;
309 313
310 keymap = get_keymap_1 (keymap, 1, 1); 314 keymap = get_keymap_1 (keymap, 1, 1);
315 GCPRO1 (keymap);
316
311 if (!NILP (parent)) 317 if (!NILP (parent))
312 parent = get_keymap_1 (parent, 1, 1); 318 parent = get_keymap_1 (parent, 1, 1);
313 319
314 /* Skip past the initial element `keymap'. */ 320 /* Skip past the initial element `keymap'. */
315 prev = keymap; 321 prev = keymap;
321 if (! CONSP (list) || EQ (Qkeymap, XCAR (list))) 327 if (! CONSP (list) || EQ (Qkeymap, XCAR (list)))
322 { 328 {
323 /* If we already have the right parent, return now 329 /* If we already have the right parent, return now
324 so that we avoid the loops below. */ 330 so that we avoid the loops below. */
325 if (EQ (XCDR (prev), parent)) 331 if (EQ (XCDR (prev), parent))
326 return parent; 332 RETURN_UNGCPRO (parent);
327 333
328 XCDR (prev) = parent; 334 XCDR (prev) = parent;
329 break; 335 break;
330 } 336 }
331 prev = list; 337 prev = list;
358 map_char_table (fix_submap_inheritance, Qnil, XCAR (list), 364 map_char_table (fix_submap_inheritance, Qnil, XCAR (list),
359 keymap, 0, indices); 365 keymap, 0, indices);
360 } 366 }
361 } 367 }
362 368
363 return parent; 369 RETURN_UNGCPRO (parent);
364 } 370 }
365 371
366 /* EVENT is defined in MAP as a prefix, and SUBMAP is its definition. 372 /* EVENT is defined in MAP as a prefix, and SUBMAP is its definition.
367 if EVENT is also a prefix in MAP's parent, 373 if EVENT is also a prefix in MAP's parent,
368 make sure that SUBMAP inherits that definition as its own parent. */ 374 make sure that SUBMAP inherits that definition as its own parent. */
633 } 639 }
634 640
635 /* If the contents are (KEYMAP . ELEMENT), go indirect. */ 641 /* If the contents are (KEYMAP . ELEMENT), go indirect. */
636 else 642 else
637 { 643 {
638 register Lisp_Object map; 644 Lisp_Object map;
645
639 map = get_keymap_1 (Fcar_safe (object), 0, autoload); 646 map = get_keymap_1 (Fcar_safe (object), 0, autoload);
640 if (NILP (map)) 647 if (NILP (map))
641 /* Invalid keymap */ 648 /* Invalid keymap */
642 return object; 649 return object;
643 else 650 else
2201 args = Fcons (Fcons (Fcons (definition, noindirect), 2208 args = Fcons (Fcons (Fcons (definition, noindirect),
2202 Fcons (xkeymap, Qnil)), 2209 Fcons (xkeymap, Qnil)),
2203 Fcons (Fcons (this, last), 2210 Fcons (Fcons (this, last),
2204 Fcons (make_number (nomenus), 2211 Fcons (make_number (nomenus),
2205 make_number (last_is_meta)))); 2212 make_number (last_is_meta))));
2206
2207 map_char_table (where_is_internal_2, Qnil, elt, args, 2213 map_char_table (where_is_internal_2, Qnil, elt, args,
2208 0, indices); 2214 0, indices);
2209 sequences = XCDR (XCDR (XCAR (args))); 2215 sequences = XCDR (XCDR (XCAR (args)));
2210 } 2216 }
2211 else if (CONSP (elt)) 2217 else if (CONSP (elt))
2263 ARGS has the form 2269 ARGS has the form
2264 (((DEFINITION . NOINDIRECT) . (KEYMAP . RESULT)) 2270 (((DEFINITION . NOINDIRECT) . (KEYMAP . RESULT))
2265 . 2271 .
2266 ((THIS . LAST) . (NOMENUS . LAST_IS_META))) 2272 ((THIS . LAST) . (NOMENUS . LAST_IS_META)))
2267 Since map_char_table doesn't really use the return value from this function, 2273 Since map_char_table doesn't really use the return value from this function,
2268 we the result append to RESULT, the slot in ARGS. */ 2274 we the result append to RESULT, the slot in ARGS.
2275
2276 This function can GC because it calls where_is_internal_1 which can
2277 GC. */
2269 2278
2270 static void 2279 static void
2271 where_is_internal_2 (args, key, binding) 2280 where_is_internal_2 (args, key, binding)
2272 Lisp_Object args, key, binding; 2281 Lisp_Object args, key, binding;
2273 { 2282 {
2274 Lisp_Object definition, noindirect, keymap, this, last; 2283 Lisp_Object definition, noindirect, keymap, this, last;
2275 Lisp_Object result, sequence; 2284 Lisp_Object result, sequence;
2276 int nomenus, last_is_meta; 2285 int nomenus, last_is_meta;
2277 2286 struct gcpro gcpro1, gcpro2, gcpro3;
2287
2288 GCPRO3 (args, key, binding);
2278 result = XCDR (XCDR (XCAR (args))); 2289 result = XCDR (XCDR (XCAR (args)));
2279 definition = XCAR (XCAR (XCAR (args))); 2290 definition = XCAR (XCAR (XCAR (args)));
2280 noindirect = XCDR (XCAR (XCAR (args))); 2291 noindirect = XCDR (XCAR (XCAR (args)));
2281 keymap = XCAR (XCDR (XCAR (args))); 2292 keymap = XCAR (XCDR (XCAR (args)));
2282 this = XCAR (XCAR (XCDR (args))); 2293 this = XCAR (XCAR (XCDR (args)));
2286 2297
2287 sequence = where_is_internal_1 (binding, key, definition, noindirect, keymap, 2298 sequence = where_is_internal_1 (binding, key, definition, noindirect, keymap,
2288 this, last, nomenus, last_is_meta); 2299 this, last, nomenus, last_is_meta);
2289 2300
2290 if (!NILP (sequence)) 2301 if (!NILP (sequence))
2291 XCDR (XCDR (XCAR (args))) 2302 XCDR (XCDR (XCAR (args))) = Fcons (sequence, result);
2292 = Fcons (sequence, result); 2303
2293 } 2304 UNGCPRO;
2305 }
2306
2307
2308 /* This function can GC.because Flookup_key calls get_keymap_1 with
2309 non-zero argument AUTOLOAD. */
2294 2310
2295 static Lisp_Object 2311 static Lisp_Object
2296 where_is_internal_1 (binding, key, definition, noindirect, keymap, this, last, 2312 where_is_internal_1 (binding, key, definition, noindirect, keymap, this, last,
2297 nomenus, last_is_meta) 2313 nomenus, last_is_meta)
2298 Lisp_Object binding, key, definition, noindirect, keymap, this, last; 2314 Lisp_Object binding, key, definition, noindirect, keymap, this, last;
2299 int nomenus, last_is_meta; 2315 int nomenus, last_is_meta;
2300 { 2316 {
2301 Lisp_Object sequence; 2317 Lisp_Object sequence;
2302 int keymap_specified = !NILP (keymap); 2318 int keymap_specified = !NILP (keymap);
2319 struct gcpro gcpro1, gcpro2;
2303 2320
2304 /* Search through indirections unless that's not wanted. */ 2321 /* Search through indirections unless that's not wanted. */
2305 if (NILP (noindirect)) 2322 if (NILP (noindirect))
2306 { 2323 {
2307 if (nomenus) 2324 if (nomenus)
2358 it is defined and does not match what we found then 2375 it is defined and does not match what we found then
2359 ignore this key. 2376 ignore this key.
2360 2377
2361 Either nil or number as value from Flookup_key 2378 Either nil or number as value from Flookup_key
2362 means undefined. */ 2379 means undefined. */
2380 GCPRO2 (sequence, binding);
2363 if (keymap_specified) 2381 if (keymap_specified)
2364 { 2382 {
2365 binding = Flookup_key (keymap, sequence, Qnil); 2383 binding = Flookup_key (keymap, sequence, Qnil);
2366 if (!NILP (binding) && !INTEGERP (binding)) 2384 if (!NILP (binding) && !INTEGERP (binding))
2367 { 2385 {
2368 if (CONSP (definition)) 2386 if (CONSP (definition))
2369 { 2387 {
2370 Lisp_Object tem; 2388 Lisp_Object tem;
2371 tem = Fequal (binding, definition); 2389 tem = Fequal (binding, definition);
2372 if (NILP (tem)) 2390 if (NILP (tem))
2373 return Qnil; 2391 RETURN_UNGCPRO (Qnil);
2374 } 2392 }
2375 else 2393 else
2376 if (!EQ (binding, definition)) 2394 if (!EQ (binding, definition))
2377 return Qnil; 2395 RETURN_UNGCPRO (Qnil);
2378 } 2396 }
2379 } 2397 }
2380 else 2398 else
2381 { 2399 {
2382 binding = Fkey_binding (sequence, Qnil); 2400 binding = Fkey_binding (sequence, Qnil);
2383 if (!EQ (binding, definition)) 2401 if (!EQ (binding, definition))
2384 return Qnil; 2402 RETURN_UNGCPRO (Qnil);
2385 } 2403 }
2386 2404
2387 return sequence; 2405 RETURN_UNGCPRO (sequence);
2388 } 2406 }
2389 2407
2390 /* describe-bindings - summarizing all the bindings in a set of keymaps. */ 2408 /* describe-bindings - summarizing all the bindings in a set of keymaps. */
2391 2409
2392 DEFUN ("describe-bindings-internal", Fdescribe_bindings_internal, Sdescribe_bindings_internal, 0, 2, "", 2410 DEFUN ("describe-bindings-internal", Fdescribe_bindings_internal, Sdescribe_bindings_internal, 0, 2, "",