1 | /* bind.c -- key binding and startup file support for the readline library. */ |
2 | |
3 | /* Copyright (C) 1987-2006 Free Software Foundation, Inc. |
4 | |
5 | This file is part of the GNU Readline Library, a library for |
6 | reading lines of text with interactive input and history editing. |
7 | |
8 | The GNU Readline Library is free software; you can redistribute it |
9 | and/or modify it under the terms of the GNU General Public License |
10 | as published by the Free Software Foundation; either version 2, or |
11 | (at your option) any later version. |
12 | |
13 | The GNU Readline Library is distributed in the hope that it will be |
14 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty |
15 | of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. |
17 | |
18 | The GNU General Public License is often shipped with GNU software, and |
19 | is generally kept in a file called COPYING or LICENSE. If you do not |
20 | have a copy of the license, write to the Free Software Foundation, |
21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
22 | |
23 | #define READLINE_LIBRARY |
24 | |
25 | #if defined (__TANDEM) |
26 | # include <floss.h> |
27 | #endif |
28 | |
29 | #if defined (HAVE_CONFIG_H) |
30 | # include "config_readline.h" |
31 | #endif |
32 | |
33 | #include <stdio.h> |
34 | #include <sys/types.h> |
35 | #include <fcntl.h> |
36 | #if defined (HAVE_SYS_FILE_H) |
37 | # include <sys/file.h> |
38 | #endif /* HAVE_SYS_FILE_H */ |
39 | |
40 | #if defined (HAVE_UNISTD_H) |
41 | # include <unistd.h> |
42 | #endif /* HAVE_UNISTD_H */ |
43 | |
44 | #if defined (HAVE_STDLIB_H) |
45 | # include <stdlib.h> |
46 | #else |
47 | # include "ansi_stdlib.h" |
48 | #endif /* HAVE_STDLIB_H */ |
49 | |
50 | #include <errno.h> |
51 | |
52 | #if !defined (errno) |
53 | extern int errno; |
54 | #endif /* !errno */ |
55 | |
56 | #include "posixstat.h" |
57 | |
58 | /* System-specific feature definitions and include files. */ |
59 | #include "rldefs.h" |
60 | |
61 | /* Some standard library routines. */ |
62 | #include "readline.h" |
63 | #include "history.h" |
64 | |
65 | #include "rlprivate.h" |
66 | #include "rlshell.h" |
67 | #include "xmalloc.h" |
68 | |
69 | #if !defined (strchr) && !defined (__STDC__) |
70 | extern char *strchr (), *strrchr (); |
71 | #endif /* !strchr && !__STDC__ */ |
72 | |
73 | /* Variables exported by this file. */ |
74 | Keymap rl_binding_keymap; |
75 | |
76 | static char *_rl_read_file PARAMS((char *, size_t *)); |
77 | static void _rl_init_file_error PARAMS((const char *)); |
78 | static int _rl_read_init_file PARAMS((const char *, int)); |
79 | static int glean_key_from_name PARAMS((char *)); |
80 | static int find_boolean_var PARAMS((const char *)); |
81 | |
82 | static const char *_rl_get_string_variable_value PARAMS((const char *)); |
83 | static int substring_member_of_array PARAMS((char *, const char **)); |
84 | |
85 | static int currently_reading_init_file; |
86 | |
87 | /* used only in this file */ |
88 | static int _rl_prefer_visible_bell = 1; |
89 | |
90 | /* **************************************************************** */ |
91 | /* */ |
92 | /* Binding keys */ |
93 | /* */ |
94 | /* **************************************************************** */ |
95 | |
96 | /* rl_add_defun (char *name, rl_command_func_t *function, int key) |
97 | Add NAME to the list of named functions. Make FUNCTION be the function |
98 | that gets called. If KEY is not -1, then bind it. */ |
99 | int |
100 | rl_add_defun (name, function, key) |
101 | const char *name; |
102 | rl_command_func_t *function; |
103 | int key; |
104 | { |
105 | if (key != -1) |
106 | rl_bind_key (key, function); |
107 | rl_add_funmap_entry (name, function); |
108 | return 0; |
109 | } |
110 | |
111 | /* Bind KEY to FUNCTION. Returns non-zero if KEY is out of range. */ |
112 | int |
113 | rl_bind_key (key, function) |
114 | int key; |
115 | rl_command_func_t *function; |
116 | { |
117 | if (key < 0) |
118 | return (key); |
119 | |
120 | if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii) |
121 | { |
122 | if (_rl_keymap[ESC].type == ISKMAP) |
123 | { |
124 | Keymap escmap; |
125 | |
126 | escmap = FUNCTION_TO_KEYMAP (_rl_keymap, ESC); |
127 | key = UNMETA (key); |
128 | escmap[key].type = ISFUNC; |
129 | escmap[key].function = function; |
130 | return (0); |
131 | } |
132 | return (key); |
133 | } |
134 | |
135 | _rl_keymap[key].type = ISFUNC; |
136 | _rl_keymap[key].function = function; |
137 | rl_binding_keymap = _rl_keymap; |
138 | return (0); |
139 | } |
140 | |
141 | /* Bind KEY to FUNCTION in MAP. Returns non-zero in case of invalid |
142 | KEY. */ |
143 | int |
144 | rl_bind_key_in_map (key, function, map) |
145 | int key; |
146 | rl_command_func_t *function; |
147 | Keymap map; |
148 | { |
149 | int result; |
150 | Keymap oldmap; |
151 | |
152 | oldmap = _rl_keymap; |
153 | _rl_keymap = map; |
154 | result = rl_bind_key (key, function); |
155 | _rl_keymap = oldmap; |
156 | return (result); |
157 | } |
158 | |
159 | /* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right |
160 | now, this is always used to attempt to bind the arrow keys, hence the |
161 | check for rl_vi_movement_mode. */ |
162 | int |
163 | rl_bind_key_if_unbound_in_map (key, default_func, kmap) |
164 | int key; |
165 | rl_command_func_t *default_func; |
166 | Keymap kmap; |
167 | { |
168 | char keyseq[2]; |
169 | |
170 | keyseq[0] = (unsigned char)key; |
171 | keyseq[1] = '\0'; |
172 | return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap)); |
173 | } |
174 | |
175 | int |
176 | rl_bind_key_if_unbound (key, default_func) |
177 | int key; |
178 | rl_command_func_t *default_func; |
179 | { |
180 | char keyseq[2]; |
181 | |
182 | keyseq[0] = (unsigned char)key; |
183 | keyseq[1] = '\0'; |
184 | return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap)); |
185 | } |
186 | |
187 | /* Make KEY do nothing in the currently selected keymap. |
188 | Returns non-zero in case of error. */ |
189 | int |
190 | rl_unbind_key (key) |
191 | int key; |
192 | { |
193 | return (rl_bind_key (key, (rl_command_func_t *)NULL)); |
194 | } |
195 | |
196 | /* Make KEY do nothing in MAP. |
197 | Returns non-zero in case of error. */ |
198 | int |
199 | rl_unbind_key_in_map (key, map) |
200 | int key; |
201 | Keymap map; |
202 | { |
203 | return (rl_bind_key_in_map (key, (rl_command_func_t *)NULL, map)); |
204 | } |
205 | |
206 | /* Unbind all keys bound to FUNCTION in MAP. */ |
207 | int |
208 | rl_unbind_function_in_map (func, map) |
209 | rl_command_func_t *func; |
210 | Keymap map; |
211 | { |
212 | register int i, rval; |
213 | |
214 | for (i = rval = 0; i < KEYMAP_SIZE; i++) |
215 | { |
216 | if (map[i].type == ISFUNC && map[i].function == func) |
217 | { |
218 | map[i].function = (rl_command_func_t *)NULL; |
219 | rval = 1; |
220 | } |
221 | } |
222 | return rval; |
223 | } |
224 | |
225 | int |
226 | rl_unbind_command_in_map (command, map) |
227 | const char *command; |
228 | Keymap map; |
229 | { |
230 | rl_command_func_t *func; |
231 | |
232 | func = rl_named_function (command); |
233 | if (func == 0) |
234 | return 0; |
235 | return (rl_unbind_function_in_map (func, map)); |
236 | } |
237 | |
238 | /* Bind the key sequence represented by the string KEYSEQ to |
239 | FUNCTION, starting in the current keymap. This makes new |
240 | keymaps as necessary. */ |
241 | int |
242 | rl_bind_keyseq (keyseq, function) |
243 | const char *keyseq; |
244 | rl_command_func_t *function; |
245 | { |
246 | return (rl_generic_bind (ISFUNC, keyseq, (char *)function, _rl_keymap)); |
247 | } |
248 | |
249 | /* Bind the key sequence represented by the string KEYSEQ to |
250 | FUNCTION. This makes new keymaps as necessary. The initial |
251 | place to do bindings is in MAP. */ |
252 | int |
253 | rl_bind_keyseq_in_map (keyseq, function, map) |
254 | const char *keyseq; |
255 | rl_command_func_t *function; |
256 | Keymap map; |
257 | { |
258 | return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map)); |
259 | } |
260 | |
261 | /* Backwards compatibility; equivalent to rl_bind_keyseq_in_map() */ |
262 | int |
263 | rl_set_key (keyseq, function, map) |
264 | const char *keyseq; |
265 | rl_command_func_t *function; |
266 | Keymap map; |
267 | { |
268 | return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map)); |
269 | } |
270 | |
271 | /* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right |
272 | now, this is always used to attempt to bind the arrow keys, hence the |
273 | check for rl_vi_movement_mode. */ |
274 | int |
275 | rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap) |
276 | const char *keyseq; |
277 | rl_command_func_t *default_func; |
278 | Keymap kmap; |
279 | { |
280 | rl_command_func_t *func; |
281 | |
282 | if (keyseq) |
283 | { |
284 | func = rl_function_of_keyseq (keyseq, kmap, (int *)NULL); |
285 | #if defined (VI_MODE) |
286 | if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode) |
287 | #else |
288 | if (!func || func == rl_do_lowercase_version) |
289 | #endif |
290 | return (rl_bind_keyseq_in_map (keyseq, default_func, kmap)); |
291 | else |
292 | return 1; |
293 | } |
294 | return 0; |
295 | } |
296 | |
297 | int |
298 | rl_bind_keyseq_if_unbound (keyseq, default_func) |
299 | const char *keyseq; |
300 | rl_command_func_t *default_func; |
301 | { |
302 | return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap)); |
303 | } |
304 | |
305 | /* Bind the key sequence represented by the string KEYSEQ to |
306 | the string of characters MACRO. This makes new keymaps as |
307 | necessary. The initial place to do bindings is in MAP. */ |
308 | int |
309 | rl_macro_bind (keyseq, macro, map) |
310 | const char *keyseq, *macro; |
311 | Keymap map; |
312 | { |
313 | char *macro_keys; |
314 | int macro_keys_len; |
315 | |
316 | macro_keys = (char *)xmalloc ((2 * strlen (macro)) + 1); |
317 | |
318 | if (rl_translate_keyseq (macro, macro_keys, ¯o_keys_len)) |
319 | { |
320 | free (macro_keys); |
321 | return -1; |
322 | } |
323 | rl_generic_bind (ISMACR, keyseq, macro_keys, map); |
324 | return 0; |
325 | } |
326 | |
327 | /* Bind the key sequence represented by the string KEYSEQ to |
328 | the arbitrary pointer DATA. TYPE says what kind of data is |
329 | pointed to by DATA, right now this can be a function (ISFUNC), |
330 | a macro (ISMACR), or a keymap (ISKMAP). This makes new keymaps |
331 | as necessary. The initial place to do bindings is in MAP. */ |
332 | int |
333 | rl_generic_bind (type, keyseq, data, map) |
334 | int type; |
335 | const char *keyseq; |
336 | char *data; |
337 | Keymap map; |
338 | { |
339 | char *keys; |
340 | int keys_len; |
341 | register int i; |
342 | KEYMAP_ENTRY k= { 0, NULL }; |
343 | |
344 | /* If no keys to bind to, exit right away. */ |
345 | if (keyseq == 0 || *keyseq == 0) |
346 | { |
347 | if (type == ISMACR) |
348 | free (data); |
349 | return -1; |
350 | } |
351 | |
352 | keys = (char *)xmalloc (1 + (2 * strlen (keyseq))); |
353 | |
354 | /* Translate the ASCII representation of KEYSEQ into an array of |
355 | characters. Stuff the characters into KEYS, and the length of |
356 | KEYS into KEYS_LEN. */ |
357 | if (rl_translate_keyseq (keyseq, keys, &keys_len)) |
358 | { |
359 | free (keys); |
360 | return -1; |
361 | } |
362 | |
363 | /* Bind keys, making new keymaps as necessary. */ |
364 | for (i = 0; i < keys_len; i++) |
365 | { |
366 | unsigned char uc = keys[i]; |
367 | int ic; |
368 | |
369 | ic = uc; |
370 | if (ic < 0 || ic >= KEYMAP_SIZE) |
371 | { |
372 | free (keys); |
373 | return -1; |
374 | } |
375 | |
376 | if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii) |
377 | { |
378 | ic = UNMETA (ic); |
379 | if (map[ESC].type == ISKMAP) |
380 | map = FUNCTION_TO_KEYMAP (map, ESC); |
381 | } |
382 | |
383 | if ((i + 1) < keys_len) |
384 | { |
385 | if (map[ic].type != ISKMAP) |
386 | { |
387 | /* We allow subsequences of keys. If a keymap is being |
388 | created that will `shadow' an existing function or macro |
389 | key binding, we save that keybinding into the ANYOTHERKEY |
390 | index in the new map. The dispatch code will look there |
391 | to find the function to execute if the subsequence is not |
392 | matched. ANYOTHERKEY was chosen to be greater than |
393 | UCHAR_MAX. */ |
394 | k = map[ic]; |
395 | |
396 | map[ic].type = ISKMAP; |
397 | map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap()); |
398 | } |
399 | map = FUNCTION_TO_KEYMAP (map, ic); |
400 | /* The dispatch code will return this function if no matching |
401 | key sequence is found in the keymap. This (with a little |
402 | help from the dispatch code in readline.c) allows `a' to be |
403 | mapped to something, `abc' to be mapped to something else, |
404 | and the function bound to `a' to be executed when the user |
405 | types `abx', leaving `bx' in the input queue. */ |
406 | if (k.function && ((k.type == ISFUNC && k.function != rl_do_lowercase_version) || k.type == ISMACR)) |
407 | { |
408 | map[ANYOTHERKEY] = k; |
409 | k.function = 0; |
410 | } |
411 | } |
412 | else |
413 | { |
414 | if (map[ic].type == ISMACR) |
415 | free ((char *)map[ic].function); |
416 | else if (map[ic].type == ISKMAP) |
417 | { |
418 | map = FUNCTION_TO_KEYMAP (map, ic); |
419 | ic = ANYOTHERKEY; |
420 | } |
421 | |
422 | map[ic].function = KEYMAP_TO_FUNCTION (data); |
423 | map[ic].type = type; |
424 | } |
425 | |
426 | rl_binding_keymap = map; |
427 | } |
428 | free (keys); |
429 | return 0; |
430 | } |
431 | |
432 | /* Translate the ASCII representation of SEQ, stuffing the values into ARRAY, |
433 | an array of characters. LEN gets the final length of ARRAY. Return |
434 | non-zero if there was an error parsing SEQ. */ |
435 | int |
436 | rl_translate_keyseq (seq, array, len) |
437 | const char *seq; |
438 | char *array; |
439 | int *len; |
440 | { |
441 | register int i, c, l, temp; |
442 | |
443 | for (i = l = 0; (c = seq[i]); i++) |
444 | { |
445 | if (c == '\\') |
446 | { |
447 | c = seq[++i]; |
448 | |
449 | if (c == 0) |
450 | break; |
451 | |
452 | /* Handle \C- and \M- prefixes. */ |
453 | if ((c == 'C' || c == 'M') && seq[i + 1] == '-') |
454 | { |
455 | /* Handle special case of backwards define. */ |
456 | if (strncmp (&seq[i], "C-\\M-" , 5) == 0) |
457 | { |
458 | array[l++] = ESC; /* ESC is meta-prefix */ |
459 | i += 5; |
460 | array[l++] = CTRL (_rl_to_upper (seq[i])); |
461 | if (seq[i] == '\0') |
462 | i--; |
463 | } |
464 | else if (c == 'M') |
465 | { |
466 | i++; /* seq[i] == '-' */ |
467 | /* XXX - obey convert-meta setting */ |
468 | if (_rl_convert_meta_chars_to_ascii && _rl_keymap[ESC].type == ISKMAP) |
469 | array[l++] = ESC; /* ESC is meta-prefix */ |
470 | else if (seq[i+1] == '\\' && seq[i+2] == 'C' && seq[i+3] == '-') |
471 | { |
472 | i += 4; |
473 | temp = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i])); |
474 | array[l++] = META (temp); |
475 | } |
476 | else |
477 | { |
478 | /* This doesn't yet handle things like \M-\a, which may |
479 | or may not have any reasonable meaning. You're |
480 | probably better off using straight octal or hex. */ |
481 | i++; |
482 | array[l++] = META (seq[i]); |
483 | } |
484 | } |
485 | else if (c == 'C') |
486 | { |
487 | i += 2; |
488 | /* Special hack for C-?... */ |
489 | array[l++] = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i])); |
490 | } |
491 | continue; |
492 | } |
493 | |
494 | /* Translate other backslash-escaped characters. These are the |
495 | same escape sequences that bash's `echo' and `printf' builtins |
496 | handle, with the addition of \d -> RUBOUT. A backslash |
497 | preceding a character that is not special is stripped. */ |
498 | switch (c) |
499 | { |
500 | case 'a': |
501 | array[l++] = '\007'; |
502 | break; |
503 | case 'b': |
504 | array[l++] = '\b'; |
505 | break; |
506 | case 'd': |
507 | array[l++] = RUBOUT; /* readline-specific */ |
508 | break; |
509 | case 'e': |
510 | array[l++] = ESC; |
511 | break; |
512 | case 'f': |
513 | array[l++] = '\f'; |
514 | break; |
515 | case 'n': |
516 | array[l++] = NEWLINE; |
517 | break; |
518 | case 'r': |
519 | array[l++] = RETURN; |
520 | break; |
521 | case 't': |
522 | array[l++] = TAB; |
523 | break; |
524 | case 'v': |
525 | array[l++] = 0x0B; |
526 | break; |
527 | case '\\': |
528 | array[l++] = '\\'; |
529 | break; |
530 | case '0': case '1': case '2': case '3': |
531 | case '4': case '5': case '6': case '7': |
532 | i++; |
533 | for (temp = 2, c -= '0'; ISOCTAL (seq[i]) && temp--; i++) |
534 | c = (c * 8) + OCTVALUE (seq[i]); |
535 | i--; /* auto-increment in for loop */ |
536 | array[l++] = c & largest_char; |
537 | break; |
538 | case 'x': |
539 | i++; |
540 | for (temp = 2, c = 0; ISXDIGIT ((unsigned char)seq[i]) && temp--; i++) |
541 | c = (c * 16) + HEXVALUE (seq[i]); |
542 | if (temp == 2) |
543 | c = 'x'; |
544 | i--; /* auto-increment in for loop */ |
545 | array[l++] = c & largest_char; |
546 | break; |
547 | default: /* backslashes before non-special chars just add the char */ |
548 | array[l++] = c; |
549 | break; /* the backslash is stripped */ |
550 | } |
551 | continue; |
552 | } |
553 | |
554 | array[l++] = c; |
555 | } |
556 | |
557 | *len = l; |
558 | array[l] = '\0'; |
559 | return (0); |
560 | } |
561 | |
562 | char * |
563 | rl_untranslate_keyseq (seq) |
564 | int seq; |
565 | { |
566 | static char kseq[16]; |
567 | int i, c; |
568 | |
569 | i = 0; |
570 | c = seq; |
571 | if (META_CHAR (c)) |
572 | { |
573 | kseq[i++] = '\\'; |
574 | kseq[i++] = 'M'; |
575 | kseq[i++] = '-'; |
576 | c = UNMETA (c); |
577 | } |
578 | else if (c == ESC) |
579 | { |
580 | kseq[i++] = '\\'; |
581 | c = 'e'; |
582 | } |
583 | else if (CTRL_CHAR (c)) |
584 | { |
585 | kseq[i++] = '\\'; |
586 | kseq[i++] = 'C'; |
587 | kseq[i++] = '-'; |
588 | c = _rl_to_lower (UNCTRL (c)); |
589 | } |
590 | else if (c == RUBOUT) |
591 | { |
592 | kseq[i++] = '\\'; |
593 | kseq[i++] = 'C'; |
594 | kseq[i++] = '-'; |
595 | c = '?'; |
596 | } |
597 | |
598 | if (c == ESC) |
599 | { |
600 | kseq[i++] = '\\'; |
601 | c = 'e'; |
602 | } |
603 | else if (c == '\\' || c == '"') |
604 | { |
605 | kseq[i++] = '\\'; |
606 | } |
607 | |
608 | kseq[i++] = (unsigned char) c; |
609 | kseq[i] = '\0'; |
610 | return kseq; |
611 | } |
612 | |
613 | static char * |
614 | _rl_untranslate_macro_value (seq) |
615 | char *seq; |
616 | { |
617 | char *ret, *r, *s; |
618 | int c; |
619 | |
620 | r = ret = (char *)xmalloc (7 * strlen (seq) + 1); |
621 | for (s = seq; *s; s++) |
622 | { |
623 | c = *s; |
624 | if (META_CHAR (c)) |
625 | { |
626 | *r++ = '\\'; |
627 | *r++ = 'M'; |
628 | *r++ = '-'; |
629 | c = UNMETA (c); |
630 | } |
631 | else if (c == ESC) |
632 | { |
633 | *r++ = '\\'; |
634 | c = 'e'; |
635 | } |
636 | else if (CTRL_CHAR (c)) |
637 | { |
638 | *r++ = '\\'; |
639 | *r++ = 'C'; |
640 | *r++ = '-'; |
641 | c = _rl_to_lower (UNCTRL (c)); |
642 | } |
643 | else if (c == RUBOUT) |
644 | { |
645 | *r++ = '\\'; |
646 | *r++ = 'C'; |
647 | *r++ = '-'; |
648 | c = '?'; |
649 | } |
650 | |
651 | if (c == ESC) |
652 | { |
653 | *r++ = '\\'; |
654 | c = 'e'; |
655 | } |
656 | else if (c == '\\' || c == '"') |
657 | *r++ = '\\'; |
658 | |
659 | *r++ = (unsigned char)c; |
660 | } |
661 | *r = '\0'; |
662 | return ret; |
663 | } |
664 | |
665 | /* Return a pointer to the function that STRING represents. |
666 | If STRING doesn't have a matching function, then a NULL pointer |
667 | is returned. */ |
668 | rl_command_func_t * |
669 | rl_named_function (string) |
670 | const char *string; |
671 | { |
672 | register int i; |
673 | |
674 | rl_initialize_funmap (); |
675 | |
676 | for (i = 0; funmap[i]; i++) |
677 | if (_rl_stricmp (funmap[i]->name, string) == 0) |
678 | return (funmap[i]->function); |
679 | return ((rl_command_func_t *)NULL); |
680 | } |
681 | |
682 | /* Return the function (or macro) definition which would be invoked via |
683 | KEYSEQ if executed in MAP. If MAP is NULL, then the current keymap is |
684 | used. TYPE, if non-NULL, is a pointer to an int which will receive the |
685 | type of the object pointed to. One of ISFUNC (function), ISKMAP (keymap), |
686 | or ISMACR (macro). */ |
687 | rl_command_func_t * |
688 | rl_function_of_keyseq (keyseq, map, type) |
689 | const char *keyseq; |
690 | Keymap map; |
691 | int *type; |
692 | { |
693 | register int i; |
694 | |
695 | if (map == 0) |
696 | map = _rl_keymap; |
697 | |
698 | for (i = 0; keyseq && keyseq[i]; i++) |
699 | { |
700 | unsigned char ic = keyseq[i]; |
701 | |
702 | if (META_CHAR_FOR_UCHAR(ic) && _rl_convert_meta_chars_to_ascii) |
703 | { |
704 | if (map[ESC].type == ISKMAP) |
705 | { |
706 | map = FUNCTION_TO_KEYMAP (map, ESC); |
707 | ic = UNMETA (ic); |
708 | } |
709 | /* XXX - should we just return NULL here, since this obviously |
710 | doesn't match? */ |
711 | else |
712 | { |
713 | if (type) |
714 | *type = map[ESC].type; |
715 | |
716 | return (map[ESC].function); |
717 | } |
718 | } |
719 | |
720 | if (map[ic].type == ISKMAP) |
721 | { |
722 | /* If this is the last key in the key sequence, return the |
723 | map. */ |
724 | if (keyseq[i + 1] == '\0') |
725 | { |
726 | if (type) |
727 | *type = ISKMAP; |
728 | |
729 | return (map[ic].function); |
730 | } |
731 | else |
732 | map = FUNCTION_TO_KEYMAP (map, ic); |
733 | } |
734 | /* If we're not at the end of the key sequence, and the current key |
735 | is bound to something other than a keymap, then the entire key |
736 | sequence is not bound. */ |
737 | else if (map[ic].type != ISKMAP && keyseq[i+1]) |
738 | return ((rl_command_func_t *)NULL); |
739 | else /* map[ic].type != ISKMAP && keyseq[i+1] == 0 */ |
740 | { |
741 | if (type) |
742 | *type = map[ic].type; |
743 | |
744 | return (map[ic].function); |
745 | } |
746 | } |
747 | return ((rl_command_func_t *) NULL); |
748 | } |
749 | |
750 | /* The last key bindings file read. */ |
751 | static char *last_readline_init_file = (char *)NULL; |
752 | |
753 | /* The file we're currently reading key bindings from. */ |
754 | static const char *current_readline_init_file; |
755 | static int current_readline_init_include_level; |
756 | static int current_readline_init_lineno; |
757 | |
758 | /* Read FILENAME into a locally-allocated buffer and return the buffer. |
759 | The size of the buffer is returned in *SIZEP. Returns NULL if any |
760 | errors were encountered. */ |
761 | static char * |
762 | _rl_read_file (filename, sizep) |
763 | char *filename; |
764 | size_t *sizep; |
765 | { |
766 | struct stat finfo; |
767 | size_t file_size; |
768 | char *buffer; |
769 | int i, file; |
770 | |
771 | if ((stat (filename, &finfo) < 0) || (file = open (filename, O_RDONLY, 0666)) < 0) |
772 | return ((char *)NULL); |
773 | |
774 | file_size = (size_t)finfo.st_size; |
775 | |
776 | /* check for overflow on very large files */ |
777 | if ((sizeof(off_t) > sizeof(size_t) && finfo.st_size > (off_t)(size_t)~0) || |
778 | file_size + 1 < file_size) |
779 | { |
780 | if (file >= 0) |
781 | close (file); |
782 | #if defined (EFBIG) |
783 | errno = EFBIG; |
784 | #endif |
785 | return ((char *)NULL); |
786 | } |
787 | |
788 | /* Read the file into BUFFER. */ |
789 | buffer = (char *)xmalloc (file_size + 1); |
790 | i = read (file, buffer, file_size); |
791 | close (file); |
792 | |
793 | if (i < 0) |
794 | { |
795 | free (buffer); |
796 | return ((char *)NULL); |
797 | } |
798 | |
799 | buffer[i] = '\0'; |
800 | if (sizep) |
801 | *sizep = i; |
802 | |
803 | return (buffer); |
804 | } |
805 | |
806 | /* Re-read the current keybindings file. */ |
807 | int |
808 | rl_re_read_init_file (count, ignore) |
809 | int count __attribute__((unused)), ignore __attribute__((unused)); |
810 | { |
811 | int r; |
812 | r = rl_read_init_file ((const char *)NULL); |
813 | rl_set_keymap_from_edit_mode (); |
814 | return r; |
815 | } |
816 | |
817 | /* Do key bindings from a file. If FILENAME is NULL it defaults |
818 | to the first non-null filename from this list: |
819 | 1. the filename used for the previous call |
820 | 2. the value of the shell variable `INPUTRC' |
821 | 3. ~/.inputrc |
822 | 4. /etc/inputrc |
823 | If the file existed and could be opened and read, 0 is returned, |
824 | otherwise errno is returned. */ |
825 | int |
826 | rl_read_init_file (filename) |
827 | const char *filename; |
828 | { |
829 | /* Default the filename. */ |
830 | if (filename == 0) |
831 | filename = last_readline_init_file; |
832 | if (filename == 0) |
833 | filename = sh_get_env_value ("INPUTRC" ); |
834 | if (filename == 0 || *filename == 0) |
835 | { |
836 | filename = DEFAULT_INPUTRC; |
837 | /* Try to read DEFAULT_INPUTRC; fall back to SYS_INPUTRC on failure */ |
838 | if (_rl_read_init_file (filename, 0) == 0) |
839 | return 0; |
840 | filename = SYS_INPUTRC; |
841 | } |
842 | |
843 | #if defined (__MSDOS__) |
844 | if (_rl_read_init_file (filename, 0) == 0) |
845 | return 0; |
846 | filename = "~/_inputrc" ; |
847 | #endif |
848 | return (_rl_read_init_file (filename, 0)); |
849 | } |
850 | |
851 | static int |
852 | _rl_read_init_file (filename, include_level) |
853 | const char *filename; |
854 | int include_level; |
855 | { |
856 | register int i; |
857 | char *buffer, *openname, *line, *end; |
858 | size_t file_size = 0; |
859 | |
860 | current_readline_init_file = filename; |
861 | current_readline_init_include_level = include_level; |
862 | |
863 | openname = tilde_expand (filename); |
864 | buffer = _rl_read_file (openname, &file_size); |
865 | free (openname); |
866 | |
867 | if (buffer == 0) |
868 | return (errno); |
869 | |
870 | if (include_level == 0 && filename != last_readline_init_file) |
871 | { |
872 | FREE (last_readline_init_file); |
873 | last_readline_init_file = savestring (filename); |
874 | } |
875 | |
876 | currently_reading_init_file = 1; |
877 | |
878 | /* Loop over the lines in the file. Lines that start with `#' are |
879 | comments; all other lines are commands for readline initialization. */ |
880 | current_readline_init_lineno = 1; |
881 | line = buffer; |
882 | end = buffer + file_size; |
883 | while (line < end) |
884 | { |
885 | /* Find the end of this line. */ |
886 | for (i = 0; line + i != end && line[i] != '\n'; i++); |
887 | |
888 | #if defined (__CYGWIN__) |
889 | /* ``Be liberal in what you accept.'' */ |
890 | if (line[i] == '\n' && line[i-1] == '\r') |
891 | line[i - 1] = '\0'; |
892 | #endif |
893 | |
894 | /* Mark end of line. */ |
895 | line[i] = '\0'; |
896 | |
897 | /* Skip leading whitespace. */ |
898 | while (*line && whitespace (*line)) |
899 | { |
900 | line++; |
901 | i--; |
902 | } |
903 | |
904 | /* If the line is not a comment, then parse it. */ |
905 | if (*line && *line != '#') |
906 | rl_parse_and_bind (line); |
907 | |
908 | /* Move to the next line. */ |
909 | line += i + 1; |
910 | current_readline_init_lineno++; |
911 | } |
912 | |
913 | free (buffer); |
914 | currently_reading_init_file = 0; |
915 | return (0); |
916 | } |
917 | |
918 | static void |
919 | _rl_init_file_error (msg) |
920 | const char *msg; |
921 | { |
922 | if (currently_reading_init_file) |
923 | fprintf (stderr, "readline: %s: line %d: %s\n" , current_readline_init_file, |
924 | current_readline_init_lineno, msg); |
925 | else |
926 | fprintf (stderr, "readline: %s\n" , msg); |
927 | } |
928 | |
929 | /* **************************************************************** */ |
930 | /* */ |
931 | /* Parser Directives */ |
932 | /* */ |
933 | /* **************************************************************** */ |
934 | |
935 | typedef int _rl_parser_func_t PARAMS((char *)); |
936 | |
937 | /* Things that mean `Control'. */ |
938 | const char *_rl_possible_control_prefixes[] = { |
939 | "Control-" , "C-" , "CTRL-" , (const char *)NULL |
940 | }; |
941 | |
942 | const char *_rl_possible_meta_prefixes[] = { |
943 | "Meta" , "M-" , (const char *)NULL |
944 | }; |
945 | |
946 | /* Conditionals. */ |
947 | |
948 | /* Calling programs set this to have their argv[0]. */ |
949 | const char *rl_readline_name = "other" ; |
950 | |
951 | /* Stack of previous values of parsing_conditionalized_out. */ |
952 | static unsigned char *if_stack = (unsigned char *)NULL; |
953 | static int if_stack_depth; |
954 | static int if_stack_size; |
955 | |
956 | /* Push _rl_parsing_conditionalized_out, and set parser state based |
957 | on ARGS. */ |
958 | static int |
959 | parser_if (args) |
960 | char *args; |
961 | { |
962 | register int i; |
963 | |
964 | /* Push parser state. */ |
965 | if (if_stack_depth + 1 >= if_stack_size) |
966 | { |
967 | if (!if_stack) |
968 | if_stack = (unsigned char *)xmalloc (if_stack_size = 20); |
969 | else |
970 | if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20); |
971 | } |
972 | if_stack[if_stack_depth++] = _rl_parsing_conditionalized_out; |
973 | |
974 | /* If parsing is turned off, then nothing can turn it back on except |
975 | for finding the matching endif. In that case, return right now. */ |
976 | if (_rl_parsing_conditionalized_out) |
977 | return 0; |
978 | |
979 | /* Isolate first argument. */ |
980 | for (i = 0; args[i] && !whitespace (args[i]); i++); |
981 | |
982 | if (args[i]) |
983 | args[i++] = '\0'; |
984 | |
985 | /* Handle "$if term=foo" and "$if mode=emacs" constructs. If this |
986 | isn't term=foo, or mode=emacs, then check to see if the first |
987 | word in ARGS is the same as the value stored in rl_readline_name. */ |
988 | if (rl_terminal_name && _rl_strnicmp (args, "term=" , 5) == 0) |
989 | { |
990 | char *tem, *tname; |
991 | |
992 | /* Terminals like "aaa-60" are equivalent to "aaa". */ |
993 | tname = savestring (rl_terminal_name); |
994 | tem = strchr (tname, '-'); |
995 | if (tem) |
996 | *tem = '\0'; |
997 | |
998 | /* Test the `long' and `short' forms of the terminal name so that |
999 | if someone has a `sun-cmd' and does not want to have bindings |
1000 | that will be executed if the terminal is a `sun', they can put |
1001 | `$if term=sun-cmd' into their .inputrc. */ |
1002 | _rl_parsing_conditionalized_out = _rl_stricmp (args + 5, tname) && |
1003 | _rl_stricmp (args + 5, rl_terminal_name); |
1004 | free (tname); |
1005 | } |
1006 | #if defined (VI_MODE) |
1007 | else if (_rl_strnicmp (args, "mode=" , 5) == 0) |
1008 | { |
1009 | int mode; |
1010 | |
1011 | if (_rl_stricmp (args + 5, "emacs" ) == 0) |
1012 | mode = emacs_mode; |
1013 | else if (_rl_stricmp (args + 5, "vi" ) == 0) |
1014 | mode = vi_mode; |
1015 | else |
1016 | mode = no_mode; |
1017 | |
1018 | _rl_parsing_conditionalized_out = mode != rl_editing_mode; |
1019 | } |
1020 | #endif /* VI_MODE */ |
1021 | /* Check to see if the first word in ARGS is the same as the |
1022 | value stored in rl_readline_name. */ |
1023 | else if (_rl_stricmp (args, rl_readline_name) == 0) |
1024 | _rl_parsing_conditionalized_out = 0; |
1025 | else |
1026 | _rl_parsing_conditionalized_out = 1; |
1027 | return 0; |
1028 | } |
1029 | |
1030 | /* Invert the current parser state if there is anything on the stack. */ |
1031 | static int |
1032 | parser_else (args) |
1033 | char *args __attribute__((unused)); |
1034 | { |
1035 | register int i; |
1036 | |
1037 | if (if_stack_depth == 0) |
1038 | { |
1039 | _rl_init_file_error ("$else found without matching $if" ); |
1040 | return 0; |
1041 | } |
1042 | |
1043 | #if 0 |
1044 | /* Check the previous (n - 1) levels of the stack to make sure that |
1045 | we haven't previously turned off parsing. */ |
1046 | for (i = 0; i < if_stack_depth - 1; i++) |
1047 | #else |
1048 | /* Check the previous (n) levels of the stack to make sure that |
1049 | we haven't previously turned off parsing. */ |
1050 | for (i = 0; i < if_stack_depth; i++) |
1051 | #endif |
1052 | if (if_stack[i] == 1) |
1053 | return 0; |
1054 | |
1055 | /* Invert the state of parsing if at top level. */ |
1056 | _rl_parsing_conditionalized_out = !_rl_parsing_conditionalized_out; |
1057 | return 0; |
1058 | } |
1059 | |
1060 | /* Terminate a conditional, popping the value of |
1061 | _rl_parsing_conditionalized_out from the stack. */ |
1062 | static int |
1063 | parser_endif (args) |
1064 | char *args __attribute__((unused)); |
1065 | { |
1066 | if (if_stack_depth) |
1067 | _rl_parsing_conditionalized_out = if_stack[--if_stack_depth]; |
1068 | else |
1069 | _rl_init_file_error ("$endif without matching $if" ); |
1070 | return 0; |
1071 | } |
1072 | |
1073 | static int |
1074 | parser_include (args) |
1075 | char *args; |
1076 | { |
1077 | const char *old_init_file; |
1078 | char *e; |
1079 | int old_line_number, old_include_level, r; |
1080 | |
1081 | if (_rl_parsing_conditionalized_out) |
1082 | return (0); |
1083 | |
1084 | old_init_file = current_readline_init_file; |
1085 | old_line_number = current_readline_init_lineno; |
1086 | old_include_level = current_readline_init_include_level; |
1087 | |
1088 | e = strchr (args, '\n'); |
1089 | if (e) |
1090 | *e = '\0'; |
1091 | r = _rl_read_init_file ((const char *)args, old_include_level + 1); |
1092 | |
1093 | current_readline_init_file = old_init_file; |
1094 | current_readline_init_lineno = old_line_number; |
1095 | current_readline_init_include_level = old_include_level; |
1096 | |
1097 | return r; |
1098 | } |
1099 | |
1100 | /* Associate textual names with actual functions. */ |
1101 | static struct { |
1102 | const char *name; |
1103 | _rl_parser_func_t *function; |
1104 | } parser_directives [] = { |
1105 | { "if" , parser_if }, |
1106 | { "endif" , parser_endif }, |
1107 | { "else" , parser_else }, |
1108 | { "include" , parser_include }, |
1109 | { (char *)0x0, (_rl_parser_func_t *)0x0 } |
1110 | }; |
1111 | |
1112 | /* Handle a parser directive. STATEMENT is the line of the directive |
1113 | without any leading `$'. */ |
1114 | static int |
1115 | handle_parser_directive (statement) |
1116 | char *statement; |
1117 | { |
1118 | register int i; |
1119 | char *directive, *args; |
1120 | |
1121 | /* Isolate the actual directive. */ |
1122 | |
1123 | /* Skip whitespace. */ |
1124 | for (i = 0; whitespace (statement[i]); i++); |
1125 | |
1126 | directive = &statement[i]; |
1127 | |
1128 | for (; statement[i] && !whitespace (statement[i]); i++); |
1129 | |
1130 | if (statement[i]) |
1131 | statement[i++] = '\0'; |
1132 | |
1133 | for (; statement[i] && whitespace (statement[i]); i++); |
1134 | |
1135 | args = &statement[i]; |
1136 | |
1137 | /* Lookup the command, and act on it. */ |
1138 | for (i = 0; parser_directives[i].name; i++) |
1139 | if (_rl_stricmp (directive, parser_directives[i].name) == 0) |
1140 | { |
1141 | (*parser_directives[i].function) (args); |
1142 | return (0); |
1143 | } |
1144 | |
1145 | /* display an error message about the unknown parser directive */ |
1146 | _rl_init_file_error ("unknown parser directive" ); |
1147 | return (1); |
1148 | } |
1149 | |
1150 | /* Read the binding command from STRING and perform it. |
1151 | A key binding command looks like: Keyname: function-name\0, |
1152 | a variable binding command looks like: set variable value. |
1153 | A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */ |
1154 | int |
1155 | rl_parse_and_bind (string) |
1156 | char *string; |
1157 | { |
1158 | char *funname, *kname; |
1159 | register int c, i; |
1160 | int key, equivalency; |
1161 | |
1162 | while (string && whitespace (*string)) |
1163 | string++; |
1164 | |
1165 | if (!string || !*string || *string == '#') |
1166 | return 0; |
1167 | |
1168 | /* If this is a parser directive, act on it. */ |
1169 | if (*string == '$') |
1170 | { |
1171 | handle_parser_directive (&string[1]); |
1172 | return 0; |
1173 | } |
1174 | |
1175 | /* If we aren't supposed to be parsing right now, then we're done. */ |
1176 | if (_rl_parsing_conditionalized_out) |
1177 | return 0; |
1178 | |
1179 | i = 0; |
1180 | /* If this keyname is a complex key expression surrounded by quotes, |
1181 | advance to after the matching close quote. This code allows the |
1182 | backslash to quote characters in the key expression. */ |
1183 | if (*string == '"') |
1184 | { |
1185 | int passc = 0; |
1186 | |
1187 | for (i = 1; (c = string[i]); i++) |
1188 | { |
1189 | if (passc) |
1190 | { |
1191 | passc = 0; |
1192 | continue; |
1193 | } |
1194 | |
1195 | if (c == '\\') |
1196 | { |
1197 | passc++; |
1198 | continue; |
1199 | } |
1200 | |
1201 | if (c == '"') |
1202 | break; |
1203 | } |
1204 | /* If we didn't find a closing quote, abort the line. */ |
1205 | if (string[i] == '\0') |
1206 | { |
1207 | _rl_init_file_error ("no closing `\"' in key binding" ); |
1208 | return 1; |
1209 | } |
1210 | } |
1211 | |
1212 | /* Advance to the colon (:) or whitespace which separates the two objects. */ |
1213 | for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ ); |
1214 | |
1215 | equivalency = (c == ':' && string[i + 1] == '='); |
1216 | |
1217 | /* Mark the end of the command (or keyname). */ |
1218 | if (string[i]) |
1219 | string[i++] = '\0'; |
1220 | |
1221 | /* If doing assignment, skip the '=' sign as well. */ |
1222 | if (equivalency) |
1223 | string[i++] = '\0'; |
1224 | |
1225 | /* If this is a command to set a variable, then do that. */ |
1226 | if (_rl_stricmp (string, "set" ) == 0) |
1227 | { |
1228 | char *var, *value, *e; |
1229 | |
1230 | var = string + i; |
1231 | /* Make VAR point to start of variable name. */ |
1232 | while (*var && whitespace (*var)) var++; |
1233 | |
1234 | /* Make VALUE point to start of value string. */ |
1235 | value = var; |
1236 | while (*value && !whitespace (*value)) value++; |
1237 | if (*value) |
1238 | *value++ = '\0'; |
1239 | while (*value && whitespace (*value)) value++; |
1240 | |
1241 | /* Strip trailing whitespace from values to boolean variables. Temp |
1242 | fix until I get a real quoted-string parser here. */ |
1243 | i = find_boolean_var (var); |
1244 | if (i >= 0) |
1245 | { |
1246 | /* remove trailing whitespace */ |
1247 | e = value + strlen (value) - 1; |
1248 | while (e >= value && whitespace (*e)) |
1249 | e--; |
1250 | e++; /* skip back to whitespace or EOS */ |
1251 | if (*e && e >= value) |
1252 | *e = '\0'; |
1253 | } |
1254 | |
1255 | rl_variable_bind (var, value); |
1256 | return 0; |
1257 | } |
1258 | |
1259 | /* Skip any whitespace between keyname and funname. */ |
1260 | for (; string[i] && whitespace (string[i]); i++); |
1261 | funname = &string[i]; |
1262 | |
1263 | /* Now isolate funname. |
1264 | For straight function names just look for whitespace, since |
1265 | that will signify the end of the string. But this could be a |
1266 | macro definition. In that case, the string is quoted, so skip |
1267 | to the matching delimiter. We allow the backslash to quote the |
1268 | delimiter characters in the macro body. */ |
1269 | /* This code exists to allow whitespace in macro expansions, which |
1270 | would otherwise be gobbled up by the next `for' loop.*/ |
1271 | /* XXX - it may be desirable to allow backslash quoting only if " is |
1272 | the quoted string delimiter, like the shell. */ |
1273 | if (*funname == '\'' || *funname == '"') |
1274 | { |
1275 | int delimiter, passc; |
1276 | |
1277 | delimiter = string[i++]; |
1278 | for (passc = 0; (c = string[i]); i++) |
1279 | { |
1280 | if (passc) |
1281 | { |
1282 | passc = 0; |
1283 | continue; |
1284 | } |
1285 | |
1286 | if (c == '\\') |
1287 | { |
1288 | passc = 1; |
1289 | continue; |
1290 | } |
1291 | |
1292 | if (c == delimiter) |
1293 | break; |
1294 | } |
1295 | if (c) |
1296 | i++; |
1297 | } |
1298 | |
1299 | /* Advance to the end of the string. */ |
1300 | for (; string[i] && !whitespace (string[i]); i++); |
1301 | |
1302 | /* No extra whitespace at the end of the string. */ |
1303 | string[i] = '\0'; |
1304 | |
1305 | /* Handle equivalency bindings here. Make the left-hand side be exactly |
1306 | whatever the right-hand evaluates to, including keymaps. */ |
1307 | if (equivalency) |
1308 | { |
1309 | return 0; |
1310 | } |
1311 | |
1312 | /* If this is a new-style key-binding, then do the binding with |
1313 | rl_bind_keyseq (). Otherwise, let the older code deal with it. */ |
1314 | if (*string == '"') |
1315 | { |
1316 | char *seq; |
1317 | register int j, k, passc; |
1318 | |
1319 | seq = (char *)xmalloc (1 + strlen (string)); |
1320 | for (j = 1, k = passc = 0; string[j]; j++) |
1321 | { |
1322 | /* Allow backslash to quote characters, but leave them in place. |
1323 | This allows a string to end with a backslash quoting another |
1324 | backslash, or with a backslash quoting a double quote. The |
1325 | backslashes are left in place for rl_translate_keyseq (). */ |
1326 | if (passc || (string[j] == '\\')) |
1327 | { |
1328 | seq[k++] = string[j]; |
1329 | passc = !passc; |
1330 | continue; |
1331 | } |
1332 | |
1333 | if (string[j] == '"') |
1334 | break; |
1335 | |
1336 | seq[k++] = string[j]; |
1337 | } |
1338 | seq[k] = '\0'; |
1339 | |
1340 | /* Binding macro? */ |
1341 | if (*funname == '\'' || *funname == '"') |
1342 | { |
1343 | j = strlen (funname); |
1344 | |
1345 | /* Remove the delimiting quotes from each end of FUNNAME. */ |
1346 | if (j && funname[j - 1] == *funname) |
1347 | funname[j - 1] = '\0'; |
1348 | |
1349 | rl_macro_bind (seq, &funname[1], _rl_keymap); |
1350 | } |
1351 | else |
1352 | rl_bind_keyseq (seq, rl_named_function (funname)); |
1353 | |
1354 | free (seq); |
1355 | return 0; |
1356 | } |
1357 | |
1358 | /* Get the actual character we want to deal with. */ |
1359 | kname = strrchr (string, '-'); |
1360 | if (!kname) |
1361 | kname = string; |
1362 | else |
1363 | kname++; |
1364 | |
1365 | key = glean_key_from_name (kname); |
1366 | |
1367 | /* Add in control and meta bits. */ |
1368 | if (substring_member_of_array (string, _rl_possible_control_prefixes)) |
1369 | key = CTRL (_rl_to_upper (key)); |
1370 | |
1371 | if (substring_member_of_array (string, _rl_possible_meta_prefixes)) |
1372 | key = META (key); |
1373 | |
1374 | /* Temporary. Handle old-style keyname with macro-binding. */ |
1375 | if (*funname == '\'' || *funname == '"') |
1376 | { |
1377 | char useq[2]; |
1378 | int fl = strlen (funname); |
1379 | |
1380 | useq[0] = key; useq[1] = '\0'; |
1381 | if (fl && funname[fl - 1] == *funname) |
1382 | funname[fl - 1] = '\0'; |
1383 | |
1384 | rl_macro_bind (useq, &funname[1], _rl_keymap); |
1385 | } |
1386 | #if defined (PREFIX_META_HACK) |
1387 | /* Ugly, but working hack to keep prefix-meta around. */ |
1388 | else if (_rl_stricmp (funname, "prefix-meta" ) == 0) |
1389 | { |
1390 | char seq[2]; |
1391 | |
1392 | seq[0] = key; |
1393 | seq[1] = '\0'; |
1394 | rl_generic_bind (ISKMAP, seq, (char *)emacs_meta_keymap, _rl_keymap); |
1395 | } |
1396 | #endif /* PREFIX_META_HACK */ |
1397 | else |
1398 | rl_bind_key (key, rl_named_function (funname)); |
1399 | return 0; |
1400 | } |
1401 | |
1402 | /* Simple structure for boolean readline variables (i.e., those that can |
1403 | have one of two values; either "On" or 1 for truth, or "Off" or 0 for |
1404 | false. */ |
1405 | |
1406 | #define V_SPECIAL 0x1 |
1407 | |
1408 | static struct { |
1409 | const char *name; |
1410 | int *value; |
1411 | int flags; |
1412 | } boolean_varlist [] = { |
1413 | { "bind-tty-special-chars" , &_rl_bind_stty_chars, 0 }, |
1414 | { "blink-matching-paren" , &rl_blink_matching_paren, V_SPECIAL }, |
1415 | { "byte-oriented" , &rl_byte_oriented, 0 }, |
1416 | { "completion-ignore-case" , &_rl_completion_case_fold, 0 }, |
1417 | { "convert-meta" , &_rl_convert_meta_chars_to_ascii, 0 }, |
1418 | { "disable-completion" , &rl_inhibit_completion, 0 }, |
1419 | { "enable-keypad" , &_rl_enable_keypad, 0 }, |
1420 | { "expand-tilde" , &rl_complete_with_tilde_expansion, 0 }, |
1421 | { "history-preserve-point" , &_rl_history_preserve_point, 0 }, |
1422 | { "horizontal-scroll-mode" , &_rl_horizontal_scroll_mode, 0 }, |
1423 | { "input-meta" , &_rl_meta_flag, 0 }, |
1424 | { "mark-directories" , &_rl_complete_mark_directories, 0 }, |
1425 | { "mark-modified-lines" , &_rl_mark_modified_lines, 0 }, |
1426 | { "mark-symlinked-directories" , &_rl_complete_mark_symlink_dirs, 0 }, |
1427 | { "match-hidden-files" , &_rl_match_hidden_files, 0 }, |
1428 | { "meta-flag" , &_rl_meta_flag, 0 }, |
1429 | { "output-meta" , &_rl_output_meta_chars, 0 }, |
1430 | { "page-completions" , &_rl_page_completions, 0 }, |
1431 | { "prefer-visible-bell" , &_rl_prefer_visible_bell, V_SPECIAL }, |
1432 | { "print-completions-horizontally" , &_rl_print_completions_horizontally, 0 }, |
1433 | { "show-all-if-ambiguous" , &_rl_complete_show_all, 0 }, |
1434 | { "show-all-if-unmodified" , &_rl_complete_show_unmodified, 0 }, |
1435 | #if defined (VISIBLE_STATS) |
1436 | { "visible-stats" , &rl_visible_stats, 0 }, |
1437 | #endif /* VISIBLE_STATS */ |
1438 | { (char *)NULL, (int *)NULL, 0 } |
1439 | }; |
1440 | |
1441 | static int |
1442 | find_boolean_var (name) |
1443 | const char *name; |
1444 | { |
1445 | register int i; |
1446 | |
1447 | for (i = 0; boolean_varlist[i].name; i++) |
1448 | if (_rl_stricmp (name, boolean_varlist[i].name) == 0) |
1449 | return i; |
1450 | return -1; |
1451 | } |
1452 | |
1453 | /* Hooks for handling special boolean variables, where a |
1454 | function needs to be called or another variable needs |
1455 | to be changed when they're changed. */ |
1456 | static void |
1457 | hack_special_boolean_var (i) |
1458 | int i; |
1459 | { |
1460 | const char *name; |
1461 | |
1462 | name = boolean_varlist[i].name; |
1463 | |
1464 | if (_rl_stricmp (name, "blink-matching-paren" ) == 0) |
1465 | _rl_enable_paren_matching (rl_blink_matching_paren); |
1466 | else if (_rl_stricmp (name, "prefer-visible-bell" ) == 0) |
1467 | { |
1468 | if (_rl_prefer_visible_bell) |
1469 | _rl_bell_preference = VISIBLE_BELL; |
1470 | else |
1471 | _rl_bell_preference = AUDIBLE_BELL; |
1472 | } |
1473 | } |
1474 | |
1475 | typedef int _rl_sv_func_t PARAMS((const char *)); |
1476 | |
1477 | /* These *must* correspond to the array indices for the appropriate |
1478 | string variable. (Though they're not used right now.) */ |
1479 | #define V_BELLSTYLE 0 |
1480 | #define V_COMBEGIN 1 |
1481 | #define V_EDITMODE 2 |
1482 | #define V_ISRCHTERM 3 |
1483 | #define V_KEYMAP 4 |
1484 | |
1485 | #define V_STRING 1 |
1486 | #define V_INT 2 |
1487 | |
1488 | /* Forward declarations */ |
1489 | static int sv_bell_style PARAMS((const char *)); |
1490 | static int sv_combegin PARAMS((const char *)); |
1491 | static int sv_compquery PARAMS((const char *)); |
1492 | static int sv_editmode PARAMS((const char *)); |
1493 | static int sv_isrchterm PARAMS((const char *)); |
1494 | static int sv_keymap PARAMS((const char *)); |
1495 | |
1496 | static struct { |
1497 | const char *name; |
1498 | int flags; |
1499 | _rl_sv_func_t *set_func; |
1500 | } string_varlist[] = { |
1501 | { "bell-style" , V_STRING, sv_bell_style }, |
1502 | { "comment-begin" , V_STRING, sv_combegin }, |
1503 | { "completion-query-items" , V_INT, sv_compquery }, |
1504 | { "editing-mode" , V_STRING, sv_editmode }, |
1505 | { "isearch-terminators" , V_STRING, sv_isrchterm }, |
1506 | { "keymap" , V_STRING, sv_keymap }, |
1507 | { (char *)NULL, 0, (_rl_sv_func_t*)NULL } |
1508 | }; |
1509 | |
1510 | static int |
1511 | find_string_var (name) |
1512 | const char *name; |
1513 | { |
1514 | register int i; |
1515 | |
1516 | for (i = 0; string_varlist[i].name; i++) |
1517 | if (_rl_stricmp (name, string_varlist[i].name) == 0) |
1518 | return i; |
1519 | return -1; |
1520 | } |
1521 | |
1522 | /* A boolean value that can appear in a `set variable' command is true if |
1523 | the value is null or empty, `on' (case-insenstive), or "1". Any other |
1524 | values result in 0 (false). */ |
1525 | static int |
1526 | bool_to_int (value) |
1527 | const char *value; |
1528 | { |
1529 | return (value == 0 || *value == '\0' || |
1530 | (_rl_stricmp (value, "on" ) == 0) || |
1531 | (value[0] == '1' && value[1] == '\0')); |
1532 | } |
1533 | |
1534 | const char * |
1535 | rl_variable_value (name) |
1536 | const char *name; |
1537 | { |
1538 | register int i; |
1539 | |
1540 | /* Check for simple variables first. */ |
1541 | i = find_boolean_var (name); |
1542 | if (i >= 0) |
1543 | return (*boolean_varlist[i].value ? "on" : "off" ); |
1544 | |
1545 | i = find_string_var (name); |
1546 | if (i >= 0) |
1547 | return (_rl_get_string_variable_value (string_varlist[i].name)); |
1548 | |
1549 | /* Unknown variable names return NULL. */ |
1550 | return 0; |
1551 | } |
1552 | |
1553 | int |
1554 | rl_variable_bind (name, value) |
1555 | const char *name, *value; |
1556 | { |
1557 | register int i; |
1558 | int v; |
1559 | |
1560 | /* Check for simple variables first. */ |
1561 | i = find_boolean_var (name); |
1562 | if (i >= 0) |
1563 | { |
1564 | *boolean_varlist[i].value = bool_to_int (value); |
1565 | if (boolean_varlist[i].flags & V_SPECIAL) |
1566 | hack_special_boolean_var (i); |
1567 | return 0; |
1568 | } |
1569 | |
1570 | i = find_string_var (name); |
1571 | |
1572 | /* For the time being, unknown variable names or string names without a |
1573 | handler function are simply ignored. */ |
1574 | if (i < 0 || string_varlist[i].set_func == 0) |
1575 | return 0; |
1576 | |
1577 | v = (*string_varlist[i].set_func) (value); |
1578 | return v; |
1579 | } |
1580 | |
1581 | static int |
1582 | sv_editmode (value) |
1583 | const char *value; |
1584 | { |
1585 | if (_rl_strnicmp (value, "vi" , 2) == 0) |
1586 | { |
1587 | #if defined (VI_MODE) |
1588 | _rl_keymap = vi_insertion_keymap; |
1589 | rl_editing_mode = vi_mode; |
1590 | #endif /* VI_MODE */ |
1591 | return 0; |
1592 | } |
1593 | else if (_rl_strnicmp (value, "emacs" , 5) == 0) |
1594 | { |
1595 | _rl_keymap = emacs_standard_keymap; |
1596 | rl_editing_mode = emacs_mode; |
1597 | return 0; |
1598 | } |
1599 | return 1; |
1600 | } |
1601 | |
1602 | static int |
1603 | sv_combegin (value) |
1604 | const char *value; |
1605 | { |
1606 | if (value && *value) |
1607 | { |
1608 | FREE (_rl_comment_begin); |
1609 | _rl_comment_begin = savestring (value); |
1610 | return 0; |
1611 | } |
1612 | return 1; |
1613 | } |
1614 | |
1615 | static int |
1616 | sv_compquery (value) |
1617 | const char *value; |
1618 | { |
1619 | int nval = 100; |
1620 | |
1621 | if (value && *value) |
1622 | { |
1623 | nval = atoi (value); |
1624 | if (nval < 0) |
1625 | nval = 0; |
1626 | } |
1627 | rl_completion_query_items = nval; |
1628 | return 0; |
1629 | } |
1630 | |
1631 | static int |
1632 | sv_keymap (value) |
1633 | const char *value; |
1634 | { |
1635 | Keymap kmap; |
1636 | |
1637 | kmap = rl_get_keymap_by_name (value); |
1638 | if (kmap) |
1639 | { |
1640 | rl_set_keymap (kmap); |
1641 | return 0; |
1642 | } |
1643 | return 1; |
1644 | } |
1645 | |
1646 | static int |
1647 | sv_bell_style (value) |
1648 | const char *value; |
1649 | { |
1650 | if (value == 0 || *value == '\0') |
1651 | _rl_bell_preference = AUDIBLE_BELL; |
1652 | else if (_rl_stricmp (value, "none" ) == 0 || _rl_stricmp (value, "off" ) == 0) |
1653 | _rl_bell_preference = NO_BELL; |
1654 | else if (_rl_stricmp (value, "audible" ) == 0 || _rl_stricmp (value, "on" ) == 0) |
1655 | _rl_bell_preference = AUDIBLE_BELL; |
1656 | else if (_rl_stricmp (value, "visible" ) == 0) |
1657 | _rl_bell_preference = VISIBLE_BELL; |
1658 | else |
1659 | return 1; |
1660 | return 0; |
1661 | } |
1662 | |
1663 | static int |
1664 | sv_isrchterm (value) |
1665 | const char *value; |
1666 | { |
1667 | int beg, end, delim; |
1668 | char *v; |
1669 | |
1670 | if (value == 0) |
1671 | return 1; |
1672 | |
1673 | /* Isolate the value and translate it into a character string. */ |
1674 | v = savestring (value); |
1675 | FREE (_rl_isearch_terminators); |
1676 | if (v[0] == '"' || v[0] == '\'') |
1677 | { |
1678 | delim = v[0]; |
1679 | for (beg = end = 1; v[end] && v[end] != delim; end++) |
1680 | ; |
1681 | } |
1682 | else |
1683 | { |
1684 | for (beg = end = 0; whitespace (v[end]) == 0; end++) |
1685 | ; |
1686 | } |
1687 | |
1688 | v[end] = '\0'; |
1689 | |
1690 | /* The value starts at v + beg. Translate it into a character string. */ |
1691 | _rl_isearch_terminators = (char *)xmalloc (2 * strlen (v) + 1); |
1692 | rl_translate_keyseq (v + beg, _rl_isearch_terminators, &end); |
1693 | _rl_isearch_terminators[end] = '\0'; |
1694 | |
1695 | free (v); |
1696 | return 0; |
1697 | } |
1698 | |
1699 | /* Return the character which matches NAME. |
1700 | For example, `Space' returns ' '. */ |
1701 | |
1702 | typedef struct { |
1703 | const char *name; |
1704 | int value; |
1705 | } assoc_list; |
1706 | |
1707 | static assoc_list name_key_alist[] = { |
1708 | { "DEL" , 0x7f }, |
1709 | { "ESC" , '\033' }, |
1710 | { "Escape" , '\033' }, |
1711 | { "LFD" , '\n' }, |
1712 | { "Newline" , '\n' }, |
1713 | { "RET" , '\r' }, |
1714 | { "Return" , '\r' }, |
1715 | { "Rubout" , 0x7f }, |
1716 | { "SPC" , ' ' }, |
1717 | { "Space" , ' ' }, |
1718 | { "Tab" , 0x09 }, |
1719 | { (char *)0x0, 0 } |
1720 | }; |
1721 | |
1722 | static int |
1723 | glean_key_from_name (name) |
1724 | char *name; |
1725 | { |
1726 | register int i; |
1727 | |
1728 | for (i = 0; name_key_alist[i].name; i++) |
1729 | if (_rl_stricmp (name, name_key_alist[i].name) == 0) |
1730 | return (name_key_alist[i].value); |
1731 | |
1732 | return (*(unsigned char *)name); /* XXX was return (*name) */ |
1733 | } |
1734 | |
1735 | /* Auxiliary functions to manage keymaps. */ |
1736 | static struct { |
1737 | const char *name; |
1738 | Keymap map; |
1739 | } keymap_names[] = { |
1740 | { "emacs" , emacs_standard_keymap }, |
1741 | { "emacs-standard" , emacs_standard_keymap }, |
1742 | { "emacs-meta" , emacs_meta_keymap }, |
1743 | { "emacs-ctlx" , emacs_ctlx_keymap }, |
1744 | #if defined (VI_MODE) |
1745 | { "vi" , vi_movement_keymap }, |
1746 | { "vi-move" , vi_movement_keymap }, |
1747 | { "vi-command" , vi_movement_keymap }, |
1748 | { "vi-insert" , vi_insertion_keymap }, |
1749 | #endif /* VI_MODE */ |
1750 | { (char *)0x0, (Keymap)0x0 } |
1751 | }; |
1752 | |
1753 | Keymap |
1754 | rl_get_keymap_by_name (name) |
1755 | const char *name; |
1756 | { |
1757 | register int i; |
1758 | |
1759 | for (i = 0; keymap_names[i].name; i++) |
1760 | if (_rl_stricmp (name, keymap_names[i].name) == 0) |
1761 | return (keymap_names[i].map); |
1762 | return ((Keymap) NULL); |
1763 | } |
1764 | |
1765 | char * |
1766 | rl_get_keymap_name (map) |
1767 | Keymap map; |
1768 | { |
1769 | register int i; |
1770 | for (i = 0; keymap_names[i].name; i++) |
1771 | if (map == keymap_names[i].map) |
1772 | return ((char *)keymap_names[i].name); |
1773 | return ((char *)NULL); |
1774 | } |
1775 | |
1776 | void |
1777 | rl_set_keymap (map) |
1778 | Keymap map; |
1779 | { |
1780 | if (map) |
1781 | _rl_keymap = map; |
1782 | } |
1783 | |
1784 | Keymap |
1785 | rl_get_keymap () |
1786 | { |
1787 | return (_rl_keymap); |
1788 | } |
1789 | |
1790 | void |
1791 | rl_set_keymap_from_edit_mode () |
1792 | { |
1793 | if (rl_editing_mode == emacs_mode) |
1794 | _rl_keymap = emacs_standard_keymap; |
1795 | #if defined (VI_MODE) |
1796 | else if (rl_editing_mode == vi_mode) |
1797 | _rl_keymap = vi_insertion_keymap; |
1798 | #endif /* VI_MODE */ |
1799 | } |
1800 | |
1801 | const char * |
1802 | rl_get_keymap_name_from_edit_mode () |
1803 | { |
1804 | if (rl_editing_mode == emacs_mode) |
1805 | return "emacs" ; |
1806 | #if defined (VI_MODE) |
1807 | else if (rl_editing_mode == vi_mode) |
1808 | return "vi" ; |
1809 | #endif /* VI_MODE */ |
1810 | else |
1811 | return "none" ; |
1812 | } |
1813 | |
1814 | /* **************************************************************** */ |
1815 | /* */ |
1816 | /* Key Binding and Function Information */ |
1817 | /* */ |
1818 | /* **************************************************************** */ |
1819 | |
1820 | /* Each of the following functions produces information about the |
1821 | state of keybindings and functions known to Readline. The info |
1822 | is always printed to rl_outstream, and in such a way that it can |
1823 | be read back in (i.e., passed to rl_parse_and_bind ()). */ |
1824 | |
1825 | /* Print the names of functions known to Readline. */ |
1826 | void |
1827 | rl_list_funmap_names () |
1828 | { |
1829 | register int i; |
1830 | const char **funmap_names; |
1831 | |
1832 | funmap_names = rl_funmap_names (); |
1833 | |
1834 | if (!funmap_names) |
1835 | return; |
1836 | |
1837 | for (i = 0; funmap_names[i]; i++) |
1838 | fprintf (rl_outstream, "%s\n" , funmap_names[i]); |
1839 | |
1840 | free (funmap_names); |
1841 | } |
1842 | |
1843 | static char * |
1844 | _rl_get_keyname (key) |
1845 | int key; |
1846 | { |
1847 | char *keyname; |
1848 | int i, c; |
1849 | |
1850 | keyname = (char *)xmalloc (8); |
1851 | |
1852 | c = key; |
1853 | /* Since this is going to be used to write out keysequence-function |
1854 | pairs for possible inclusion in an inputrc file, we don't want to |
1855 | do any special meta processing on KEY. */ |
1856 | |
1857 | #if 1 |
1858 | /* XXX - Experimental */ |
1859 | /* We might want to do this, but the old version of the code did not. */ |
1860 | |
1861 | /* If this is an escape character, we don't want to do any more processing. |
1862 | Just add the special ESC key sequence and return. */ |
1863 | if (c == ESC) |
1864 | { |
1865 | keyname[0] = '\\'; |
1866 | keyname[1] = 'e'; |
1867 | keyname[2] = '\0'; |
1868 | return keyname; |
1869 | } |
1870 | #endif |
1871 | |
1872 | /* RUBOUT is translated directly into \C-? */ |
1873 | if (key == RUBOUT) |
1874 | { |
1875 | keyname[0] = '\\'; |
1876 | keyname[1] = 'C'; |
1877 | keyname[2] = '-'; |
1878 | keyname[3] = '?'; |
1879 | keyname[4] = '\0'; |
1880 | return keyname; |
1881 | } |
1882 | |
1883 | i = 0; |
1884 | /* Now add special prefixes needed for control characters. This can |
1885 | potentially change C. */ |
1886 | if (CTRL_CHAR (c)) |
1887 | { |
1888 | keyname[i++] = '\\'; |
1889 | keyname[i++] = 'C'; |
1890 | keyname[i++] = '-'; |
1891 | c = _rl_to_lower (UNCTRL (c)); |
1892 | } |
1893 | |
1894 | /* XXX experimental code. Turn the characters that are not ASCII or |
1895 | ISO Latin 1 (128 - 159) into octal escape sequences (\200 - \237). |
1896 | This changes C. */ |
1897 | if (c >= 128 && c <= 159) |
1898 | { |
1899 | keyname[i++] = '\\'; |
1900 | keyname[i++] = '2'; |
1901 | c -= 128; |
1902 | keyname[i++] = (c / 8) + '0'; |
1903 | c = (c % 8) + '0'; |
1904 | } |
1905 | |
1906 | /* Now, if the character needs to be quoted with a backslash, do that. */ |
1907 | if (c == '\\' || c == '"') |
1908 | keyname[i++] = '\\'; |
1909 | |
1910 | /* Now add the key, terminate the string, and return it. */ |
1911 | keyname[i++] = (char) c; |
1912 | keyname[i] = '\0'; |
1913 | |
1914 | return keyname; |
1915 | } |
1916 | |
1917 | /* Return a NULL terminated array of strings which represent the key |
1918 | sequences that are used to invoke FUNCTION in MAP. */ |
1919 | char ** |
1920 | rl_invoking_keyseqs_in_map (function, map) |
1921 | rl_command_func_t *function; |
1922 | Keymap map; |
1923 | { |
1924 | register int key; |
1925 | char **result; |
1926 | int result_index, result_size; |
1927 | |
1928 | result = (char **)NULL; |
1929 | result_index = result_size = 0; |
1930 | |
1931 | for (key = 0; key < KEYMAP_SIZE; key++) |
1932 | { |
1933 | switch (map[key].type) |
1934 | { |
1935 | case ISMACR: |
1936 | /* Macros match, if, and only if, the pointers are identical. |
1937 | Thus, they are treated exactly like functions in here. */ |
1938 | case ISFUNC: |
1939 | /* If the function in the keymap is the one we are looking for, |
1940 | then add the current KEY to the list of invoking keys. */ |
1941 | if (map[key].function == function) |
1942 | { |
1943 | char *keyname; |
1944 | |
1945 | keyname = _rl_get_keyname (key); |
1946 | |
1947 | if (result_index + 2 > result_size) |
1948 | { |
1949 | result_size += 10; |
1950 | result = (char **)xrealloc (result, result_size * sizeof (char *)); |
1951 | } |
1952 | |
1953 | result[result_index++] = keyname; |
1954 | result[result_index] = (char *)NULL; |
1955 | } |
1956 | break; |
1957 | |
1958 | case ISKMAP: |
1959 | { |
1960 | char **seqs; |
1961 | register int i; |
1962 | |
1963 | /* Find the list of keyseqs in this map which have FUNCTION as |
1964 | their target. Add the key sequences found to RESULT. */ |
1965 | if (map[key].function) |
1966 | seqs = |
1967 | rl_invoking_keyseqs_in_map (function, FUNCTION_TO_KEYMAP (map, key)); |
1968 | else |
1969 | break; |
1970 | |
1971 | if (seqs == 0) |
1972 | break; |
1973 | |
1974 | for (i = 0; seqs[i]; i++) |
1975 | { |
1976 | char *keyname = (char *)xmalloc (6 + strlen (seqs[i])); |
1977 | |
1978 | if (key == ESC) |
1979 | { |
1980 | /* If ESC is the meta prefix and we're converting chars |
1981 | with the eighth bit set to ESC-prefixed sequences, then |
1982 | we can use \M-. Otherwise we need to use the sequence |
1983 | for ESC. */ |
1984 | if (_rl_convert_meta_chars_to_ascii && map[ESC].type == ISKMAP) |
1985 | sprintf (keyname, "\\M-" ); |
1986 | else |
1987 | sprintf (keyname, "\\e" ); |
1988 | } |
1989 | else if (CTRL_CHAR (key)) |
1990 | sprintf (keyname, "\\C-%c" , _rl_to_lower (UNCTRL (key))); |
1991 | else if (key == RUBOUT) |
1992 | sprintf (keyname, "\\C-?" ); |
1993 | else if (key == '\\' || key == '"') |
1994 | { |
1995 | keyname[0] = '\\'; |
1996 | keyname[1] = (char) key; |
1997 | keyname[2] = '\0'; |
1998 | } |
1999 | else |
2000 | { |
2001 | keyname[0] = (char) key; |
2002 | keyname[1] = '\0'; |
2003 | } |
2004 | |
2005 | strcat (keyname, seqs[i]); |
2006 | free (seqs[i]); |
2007 | |
2008 | if (result_index + 2 > result_size) |
2009 | { |
2010 | result_size += 10; |
2011 | result = (char **)xrealloc (result, result_size * sizeof (char *)); |
2012 | } |
2013 | |
2014 | result[result_index++] = keyname; |
2015 | result[result_index] = (char *)NULL; |
2016 | } |
2017 | |
2018 | free (seqs); |
2019 | } |
2020 | break; |
2021 | } |
2022 | } |
2023 | return (result); |
2024 | } |
2025 | |
2026 | /* Return a NULL terminated array of strings which represent the key |
2027 | sequences that can be used to invoke FUNCTION using the current keymap. */ |
2028 | char ** |
2029 | rl_invoking_keyseqs (function) |
2030 | rl_command_func_t *function; |
2031 | { |
2032 | return (rl_invoking_keyseqs_in_map (function, _rl_keymap)); |
2033 | } |
2034 | |
2035 | /* Print all of the functions and their bindings to rl_outstream. If |
2036 | PRINT_READABLY is non-zero, then print the output in such a way |
2037 | that it can be read back in. */ |
2038 | void |
2039 | rl_function_dumper (print_readably) |
2040 | int print_readably; |
2041 | { |
2042 | register int i; |
2043 | const char **names; |
2044 | const char *name; |
2045 | |
2046 | names = rl_funmap_names (); |
2047 | |
2048 | fprintf (rl_outstream, "\n" ); |
2049 | |
2050 | for (i = 0; (name = names[i]); i++) |
2051 | { |
2052 | rl_command_func_t *function; |
2053 | char **invokers; |
2054 | |
2055 | function = rl_named_function (name); |
2056 | invokers = rl_invoking_keyseqs_in_map (function, _rl_keymap); |
2057 | |
2058 | if (print_readably) |
2059 | { |
2060 | if (!invokers) |
2061 | fprintf (rl_outstream, "# %s (not bound)\n" , name); |
2062 | else |
2063 | { |
2064 | register int j; |
2065 | |
2066 | for (j = 0; invokers[j]; j++) |
2067 | { |
2068 | fprintf (rl_outstream, "\"%s\": %s\n" , |
2069 | invokers[j], name); |
2070 | free (invokers[j]); |
2071 | } |
2072 | |
2073 | free (invokers); |
2074 | } |
2075 | } |
2076 | else |
2077 | { |
2078 | if (!invokers) |
2079 | fprintf (rl_outstream, "%s is not bound to any keys\n" , |
2080 | name); |
2081 | else |
2082 | { |
2083 | register int j; |
2084 | |
2085 | fprintf (rl_outstream, "%s can be found on " , name); |
2086 | |
2087 | for (j = 0; invokers[j] && j < 5; j++) |
2088 | { |
2089 | fprintf (rl_outstream, "\"%s\"%s" , invokers[j], |
2090 | invokers[j + 1] ? ", " : ".\n" ); |
2091 | } |
2092 | |
2093 | if (j == 5 && invokers[j]) |
2094 | fprintf (rl_outstream, "...\n" ); |
2095 | |
2096 | for (j = 0; invokers[j]; j++) |
2097 | free (invokers[j]); |
2098 | |
2099 | free (invokers); |
2100 | } |
2101 | } |
2102 | } |
2103 | } |
2104 | |
2105 | /* Print all of the current functions and their bindings to |
2106 | rl_outstream. If an explicit argument is given, then print |
2107 | the output in such a way that it can be read back in. */ |
2108 | int |
2109 | rl_dump_functions (count, key) |
2110 | int count __attribute__((unused)), key __attribute__((unused)); |
2111 | { |
2112 | if (rl_dispatching) |
2113 | fprintf (rl_outstream, "\r\n" ); |
2114 | rl_function_dumper (rl_explicit_arg); |
2115 | rl_on_new_line (); |
2116 | return (0); |
2117 | } |
2118 | |
2119 | static void |
2120 | _rl_macro_dumper_internal (print_readably, map, prefix) |
2121 | int print_readably; |
2122 | Keymap map; |
2123 | char *prefix; |
2124 | { |
2125 | register int key; |
2126 | char *keyname, *out; |
2127 | int prefix_len; |
2128 | |
2129 | for (key = 0; key < KEYMAP_SIZE; key++) |
2130 | { |
2131 | switch (map[key].type) |
2132 | { |
2133 | case ISMACR: |
2134 | keyname = _rl_get_keyname (key); |
2135 | out = _rl_untranslate_macro_value ((char *)map[key].function); |
2136 | |
2137 | if (print_readably) |
2138 | fprintf (rl_outstream, "\"%s%s\": \"%s\"\n" , prefix ? prefix : "" , |
2139 | keyname, |
2140 | out ? out : "" ); |
2141 | else |
2142 | fprintf (rl_outstream, "%s%s outputs %s\n" , prefix ? prefix : "" , |
2143 | keyname, |
2144 | out ? out : "" ); |
2145 | free (keyname); |
2146 | free (out); |
2147 | break; |
2148 | case ISFUNC: |
2149 | break; |
2150 | case ISKMAP: |
2151 | prefix_len = prefix ? strlen (prefix) : 0; |
2152 | if (key == ESC) |
2153 | { |
2154 | keyname = (char *)xmalloc (3 + prefix_len); |
2155 | if (prefix) |
2156 | strcpy (keyname, prefix); |
2157 | keyname[prefix_len] = '\\'; |
2158 | keyname[prefix_len + 1] = 'e'; |
2159 | keyname[prefix_len + 2] = '\0'; |
2160 | } |
2161 | else |
2162 | { |
2163 | keyname = _rl_get_keyname (key); |
2164 | if (prefix) |
2165 | { |
2166 | out = (char *)xmalloc (strlen (keyname) + prefix_len + 1); |
2167 | strcpy (out, prefix); |
2168 | strcpy (out + prefix_len, keyname); |
2169 | free (keyname); |
2170 | keyname = out; |
2171 | } |
2172 | } |
2173 | |
2174 | _rl_macro_dumper_internal (print_readably, FUNCTION_TO_KEYMAP (map, key), keyname); |
2175 | free (keyname); |
2176 | break; |
2177 | } |
2178 | } |
2179 | } |
2180 | |
2181 | void |
2182 | rl_macro_dumper (print_readably) |
2183 | int print_readably; |
2184 | { |
2185 | _rl_macro_dumper_internal (print_readably, _rl_keymap, (char *)NULL); |
2186 | } |
2187 | |
2188 | int |
2189 | rl_dump_macros (count, key) |
2190 | int count __attribute__((unused)), key __attribute__((unused)); |
2191 | { |
2192 | if (rl_dispatching) |
2193 | fprintf (rl_outstream, "\r\n" ); |
2194 | rl_macro_dumper (rl_explicit_arg); |
2195 | rl_on_new_line (); |
2196 | return (0); |
2197 | } |
2198 | |
2199 | static const char * |
2200 | _rl_get_string_variable_value (name) |
2201 | const char *name; |
2202 | { |
2203 | static char numbuf[32]; |
2204 | const char *ret; |
2205 | char *tmp; |
2206 | |
2207 | if (_rl_stricmp (name, "bell-style" ) == 0) |
2208 | { |
2209 | switch (_rl_bell_preference) |
2210 | { |
2211 | case NO_BELL: |
2212 | return "none" ; |
2213 | case VISIBLE_BELL: |
2214 | return "visible" ; |
2215 | case AUDIBLE_BELL: |
2216 | default: |
2217 | return "audible" ; |
2218 | } |
2219 | } |
2220 | else if (_rl_stricmp (name, "comment-begin" ) == 0) |
2221 | return (_rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT); |
2222 | else if (_rl_stricmp (name, "completion-query-items" ) == 0) |
2223 | { |
2224 | sprintf (numbuf, "%d" , rl_completion_query_items); |
2225 | return (numbuf); |
2226 | } |
2227 | else if (_rl_stricmp (name, "editing-mode" ) == 0) |
2228 | return (rl_get_keymap_name_from_edit_mode ()); |
2229 | else if (_rl_stricmp (name, "isearch-terminators" ) == 0) |
2230 | { |
2231 | if (_rl_isearch_terminators == 0) |
2232 | return 0; |
2233 | tmp = _rl_untranslate_macro_value (_rl_isearch_terminators); |
2234 | if (tmp) |
2235 | { |
2236 | strncpy (numbuf, tmp, sizeof (numbuf) - 1); |
2237 | free (tmp); |
2238 | numbuf[sizeof(numbuf) - 1] = '\0'; |
2239 | } |
2240 | else |
2241 | numbuf[0] = '\0'; |
2242 | return numbuf; |
2243 | } |
2244 | else if (_rl_stricmp (name, "keymap" ) == 0) |
2245 | { |
2246 | ret = rl_get_keymap_name (_rl_keymap); |
2247 | if (ret == 0) |
2248 | ret = rl_get_keymap_name_from_edit_mode (); |
2249 | return (ret ? ret : "none" ); |
2250 | } |
2251 | else |
2252 | return (0); |
2253 | } |
2254 | |
2255 | void |
2256 | rl_variable_dumper (print_readably) |
2257 | int print_readably; |
2258 | { |
2259 | int i; |
2260 | const char *v; |
2261 | |
2262 | for (i = 0; boolean_varlist[i].name; i++) |
2263 | { |
2264 | if (print_readably) |
2265 | fprintf (rl_outstream, "set %s %s\n" , boolean_varlist[i].name, |
2266 | *boolean_varlist[i].value ? "on" : "off" ); |
2267 | else |
2268 | fprintf (rl_outstream, "%s is set to `%s'\n" , boolean_varlist[i].name, |
2269 | *boolean_varlist[i].value ? "on" : "off" ); |
2270 | } |
2271 | |
2272 | for (i = 0; string_varlist[i].name; i++) |
2273 | { |
2274 | v = _rl_get_string_variable_value (string_varlist[i].name); |
2275 | if (v == 0) /* _rl_isearch_terminators can be NULL */ |
2276 | continue; |
2277 | if (print_readably) |
2278 | fprintf (rl_outstream, "set %s %s\n" , string_varlist[i].name, v); |
2279 | else |
2280 | fprintf (rl_outstream, "%s is set to `%s'\n" , string_varlist[i].name, v); |
2281 | } |
2282 | } |
2283 | |
2284 | /* Print all of the current variables and their values to |
2285 | rl_outstream. If an explicit argument is given, then print |
2286 | the output in such a way that it can be read back in. */ |
2287 | int |
2288 | rl_dump_variables (count, key) |
2289 | int count __attribute__((unused)), key __attribute__((unused)); |
2290 | { |
2291 | if (rl_dispatching) |
2292 | fprintf (rl_outstream, "\r\n" ); |
2293 | rl_variable_dumper (rl_explicit_arg); |
2294 | rl_on_new_line (); |
2295 | return (0); |
2296 | } |
2297 | |
2298 | /* Return non-zero if any members of ARRAY are a substring in STRING. */ |
2299 | static int |
2300 | substring_member_of_array (string, array) |
2301 | char *string; |
2302 | const char **array; |
2303 | { |
2304 | while (*array) |
2305 | { |
2306 | if (_rl_strindex (string, *array)) |
2307 | return (1); |
2308 | array++; |
2309 | } |
2310 | return (0); |
2311 | } |
2312 | |