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