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