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