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