Release 2.33.1
[external/binutils.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 }