bind.c revision 26497
197883Sgibbs/* bind.c -- key binding and startup file support for the readline library. */
297883Sgibbs
397883Sgibbs/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
497883Sgibbs
5102681Sgibbs   This file is part of the GNU Readline Library, a library for
697883Sgibbs   reading lines of text with interactive input and history editing.
797883Sgibbs
897883Sgibbs   The GNU Readline Library is free software; you can redistribute it
997883Sgibbs   and/or modify it under the terms of the GNU General Public License
1097883Sgibbs   as published by the Free Software Foundation; either version 1, or
1197883Sgibbs   (at your option) any later version.
1297883Sgibbs
1397883Sgibbs   The GNU Readline Library is distributed in the hope that it will be
1497883Sgibbs   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
1597883Sgibbs   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1697883Sgibbs   GNU General Public License for more details.
1797883Sgibbs
1897883Sgibbs   The GNU General Public License is often shipped with GNU software, and
1997883Sgibbs   is generally kept in a file called COPYING or LICENSE.  If you do not
2097883Sgibbs   have a copy of the license, write to the Free Software Foundation,
2197883Sgibbs   675 Mass Ave, Cambridge, MA 02139, USA. */
2297883Sgibbs#define READLINE_LIBRARY
2397883Sgibbs
2497883Sgibbs#if defined (HAVE_CONFIG_H)
2597883Sgibbs#  include <config.h>
2697883Sgibbs#endif
2797883Sgibbs
2897883Sgibbs#include <stdio.h>
2997883Sgibbs#include <sys/types.h>
3097883Sgibbs#include <fcntl.h>
3197883Sgibbs#if defined (HAVE_SYS_FILE_H)
3297883Sgibbs#  include <sys/file.h>
3397883Sgibbs#endif /* HAVE_SYS_FILE_H */
3497883Sgibbs
3597883Sgibbs#if defined (HAVE_UNISTD_H)
3697883Sgibbs#  include <unistd.h>
3797883Sgibbs#endif /* HAVE_UNISTD_H */
3897883Sgibbs
3997883Sgibbs#if defined (HAVE_STDLIB_H)
4097883Sgibbs#  include <stdlib.h>
4197883Sgibbs#else
42107623Sscottl#  include "ansi_stdlib.h"
4397883Sgibbs#endif /* HAVE_STDLIB_H */
4497883Sgibbs
4597883Sgibbs#include <signal.h>
4697883Sgibbs#include <errno.h>
4797883Sgibbs
4897883Sgibbs#if !defined (errno)
4997883Sgibbsextern int errno;
5097883Sgibbs#endif /* !errno */
5197883Sgibbs
5297883Sgibbs#include "posixstat.h"
5397883Sgibbs
5497883Sgibbs/* System-specific feature definitions and include files. */
5597883Sgibbs#include "rldefs.h"
5697883Sgibbs
5797883Sgibbs/* Some standard library routines. */
5897883Sgibbs#include "readline.h"
59104023Sgibbs#include "history.h"
60104023Sgibbs
61104023Sgibbs#if !defined (strchr) && !defined (__STDC__)
62104023Sgibbsextern char *strchr (), *strrchr ();
63104023Sgibbs#endif /* !strchr && !__STDC__ */
64104023Sgibbs
65104023Sgibbsextern int _rl_horizontal_scroll_mode;
66104023Sgibbsextern int _rl_mark_modified_lines;
6797883Sgibbsextern int _rl_bell_preference;
68104023Sgibbsextern int _rl_meta_flag;
69104023Sgibbsextern int _rl_convert_meta_chars_to_ascii;
70104023Sgibbsextern int _rl_output_meta_chars;
71104023Sgibbsextern int _rl_complete_show_all;
72104023Sgibbsextern int _rl_complete_mark_directories;
73104023Sgibbsextern int _rl_enable_keypad;
74104023Sgibbs#if defined (PAREN_MATCHING)
75107441Sscottlextern int rl_blink_matching_paren;
76107441Sscottl#endif /* PAREN_MATCHING */
77107441Sscottl#if defined (VISIBLE_STATS)
78107441Sscottlextern int rl_visible_stats;
79107441Sscottl#endif /* VISIBLE_STATS */
80107441Sscottlextern int rl_complete_with_tilde_expansion;
81104023Sgibbsextern int rl_completion_query_items;
82107441Sscottlextern int rl_inhibit_completion;
83107441Sscottlextern char *_rl_comment_begin;
84107441Sscottl
85107441Sscottlextern int rl_explicit_arg;
86107441Sscottlextern int rl_editing_mode;
87107441Sscottlextern unsigned char _rl_parsing_conditionalized_out;
88107441Sscottlextern Keymap _rl_keymap;
8997883Sgibbs
9097883Sgibbsextern char *possible_control_prefixes[], *possible_meta_prefixes[];
9197883Sgibbs
9297883Sgibbs/* Functions imported from funmap.c */
9397883Sgibbsextern char **rl_funmap_names ();
9497883Sgibbsextern int rl_add_funmap_entry ();
9597883Sgibbs
9697883Sgibbs/* Functions imported from util.c */
9797883Sgibbsextern char *_rl_strindex ();
98102681Sgibbs
99102681Sgibbs/* Functions imported from shell.c */
10097883Sgibbsextern char *get_env_value ();
10197883Sgibbs
10297883Sgibbs/* Variables exported by this file. */
10397883SgibbsKeymap rl_binding_keymap;
10497883Sgibbs
10597883Sgibbs/* Forward declarations */
10697883Sgibbsvoid rl_set_keymap_from_edit_mode ();
10797883Sgibbs
10897883Sgibbsstatic int glean_key_from_name ();
10997883Sgibbsstatic int substring_member_of_array ();
11097883Sgibbs
11197883Sgibbsextern char *xmalloc (), *xrealloc ();
112102681Sgibbs
113102681Sgibbs/* **************************************************************** */
114102681Sgibbs/*								    */
115102681Sgibbs/*			Binding keys				    */
116102681Sgibbs/*								    */
117102681Sgibbs/* **************************************************************** */
118102681Sgibbs
119102681Sgibbs/* rl_add_defun (char *name, Function *function, int key)
12097883Sgibbs   Add NAME to the list of named functions.  Make FUNCTION be the function
12197883Sgibbs   that gets called.  If KEY is not -1, then bind it. */
12297883Sgibbsint
12397883Sgibbsrl_add_defun (name, function, key)
12497883Sgibbs     char *name;
12597883Sgibbs     Function *function;
12697883Sgibbs     int key;
12797883Sgibbs{
12897883Sgibbs  if (key != -1)
129102681Sgibbs    rl_bind_key (key, function);
130107441Sscottl  rl_add_funmap_entry (name, function);
131107441Sscottl  return 0;
132102681Sgibbs}
133102681Sgibbs
134102681Sgibbs/* Bind KEY to FUNCTION.  Returns non-zero if KEY is out of range. */
135102681Sgibbsint
136102681Sgibbsrl_bind_key (key, function)
13797883Sgibbs     int key;
13897883Sgibbs     Function *function;
13997883Sgibbs{
14097883Sgibbs  if (key < 0)
14197883Sgibbs    return (key);
14297883Sgibbs
143102681Sgibbs  if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
14497883Sgibbs    {
14597883Sgibbs      if (_rl_keymap[ESC].type == ISKMAP)
14697883Sgibbs	{
14797883Sgibbs	  Keymap escmap;
14897883Sgibbs
14997883Sgibbs	  escmap = FUNCTION_TO_KEYMAP (_rl_keymap, ESC);
15097883Sgibbs	  key = UNMETA (key);
15197883Sgibbs	  escmap[key].type = ISFUNC;
152102681Sgibbs	  escmap[key].function = function;
153102681Sgibbs	  return (0);
15497883Sgibbs	}
15597883Sgibbs      return (key);
15697883Sgibbs    }
15797883Sgibbs
158102681Sgibbs  _rl_keymap[key].type = ISFUNC;
15997883Sgibbs  _rl_keymap[key].function = function;
16097883Sgibbs  rl_binding_keymap = _rl_keymap;
16197883Sgibbs  return (0);
16297883Sgibbs}
163102681Sgibbs
16497883Sgibbs/* Bind KEY to FUNCTION in MAP.  Returns non-zero in case of invalid
16597883Sgibbs   KEY. */
16697883Sgibbsint
16797883Sgibbsrl_bind_key_in_map (key, function, map)
16897883Sgibbs     int key;
169102681Sgibbs     Function *function;
170102681Sgibbs     Keymap map;
171102681Sgibbs{
172102681Sgibbs  int result;
173102681Sgibbs  Keymap oldmap;
174102681Sgibbs
175107441Sscottl  oldmap = _rl_keymap;
176107441Sscottl  _rl_keymap = map;
177107441Sscottl  result = rl_bind_key (key, function);
178107441Sscottl  _rl_keymap = oldmap;
179107441Sscottl  return (result);
180107441Sscottl}
181102681Sgibbs
18297883Sgibbs/* Make KEY do nothing in the currently selected keymap.
18397883Sgibbs   Returns non-zero in case of error. */
18497883Sgibbsint
18597883Sgibbsrl_unbind_key (key)
18697883Sgibbs     int key;
18797883Sgibbs{
18897883Sgibbs  return (rl_bind_key (key, (Function *)NULL));
18997883Sgibbs}
190102681Sgibbs
191102681Sgibbs/* Make KEY do nothing in MAP.
192102681Sgibbs   Returns non-zero in case of error. */
193107623Sscottlint
194102681Sgibbsrl_unbind_key_in_map (key, map)
195102681Sgibbs     int key;
196102681Sgibbs     Keymap map;
197102681Sgibbs{
19897883Sgibbs  return (rl_bind_key_in_map (key, (Function *)NULL, map));
19997883Sgibbs}
20097883Sgibbs
20197883Sgibbs/* Bind the key sequence represented by the string KEYSEQ to
20297883Sgibbs   FUNCTION.  This makes new keymaps as necessary.  The initial
20397883Sgibbs   place to do bindings is in MAP. */
20497883Sgibbsint
20597883Sgibbsrl_set_key (keyseq, function, map)
206102681Sgibbs     char *keyseq;
207102681Sgibbs     Function *function;
208102681Sgibbs     Keymap map;
209102681Sgibbs{
210102681Sgibbs  return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));
211102681Sgibbs}
212102681Sgibbs
21397883Sgibbs/* Bind the key sequence represented by the string KEYSEQ to
21497883Sgibbs   the string of characters MACRO.  This makes new keymaps as
21597883Sgibbs   necessary.  The initial place to do bindings is in MAP. */
21697883Sgibbsint
21797883Sgibbsrl_macro_bind (keyseq, macro, map)
21897883Sgibbs     char *keyseq, *macro;
21997883Sgibbs     Keymap map;
22097883Sgibbs{
221102681Sgibbs  char *macro_keys;
222102681Sgibbs  int macro_keys_len;
223102681Sgibbs
224102681Sgibbs  macro_keys = (char *)xmalloc ((2 * strlen (macro)) + 1);
225102681Sgibbs
226102681Sgibbs  if (rl_translate_keyseq (macro, macro_keys, &macro_keys_len))
227102681Sgibbs    {
22897883Sgibbs      free (macro_keys);
22997883Sgibbs      return -1;
23097883Sgibbs    }
23197883Sgibbs  rl_generic_bind (ISMACR, keyseq, macro_keys, map);
23297883Sgibbs  return 0;
23397883Sgibbs}
23497883Sgibbs
23597883Sgibbs/* Bind the key sequence represented by the string KEYSEQ to
23697883Sgibbs   the arbitrary pointer DATA.  TYPE says what kind of data is
237102681Sgibbs   pointed to by DATA, right now this can be a function (ISFUNC),
238102681Sgibbs   a macro (ISMACR), or a keymap (ISKMAP).  This makes new keymaps
239102681Sgibbs   as necessary.  The initial place to do bindings is in MAP. */
240102681Sgibbsint
241102681Sgibbsrl_generic_bind (type, keyseq, data, map)
242102681Sgibbs     int type;
243102681Sgibbs     char *keyseq, *data;
244102681Sgibbs     Keymap map;
24597883Sgibbs{
24697883Sgibbs  char *keys;
24797883Sgibbs  int keys_len;
24897883Sgibbs  register int i;
24997883Sgibbs
25097883Sgibbs  /* If no keys to bind to, exit right away. */
25197883Sgibbs  if (!keyseq || !*keyseq)
25297883Sgibbs    {
25397883Sgibbs      if (type == ISMACR)
25497883Sgibbs	free (data);
25597883Sgibbs      return -1;
25697883Sgibbs    }
25797883Sgibbs
25897883Sgibbs  keys = xmalloc (1 + (2 * strlen (keyseq)));
25997883Sgibbs
26097883Sgibbs  /* Translate the ASCII representation of KEYSEQ into an array of
26197883Sgibbs     characters.  Stuff the characters into KEYS, and the length of
26297883Sgibbs     KEYS into KEYS_LEN. */
26397883Sgibbs  if (rl_translate_keyseq (keyseq, keys, &keys_len))
26497883Sgibbs    {
26597883Sgibbs      free (keys);
26697883Sgibbs      return -1;
26797883Sgibbs    }
26897883Sgibbs
26997883Sgibbs  /* Bind keys, making new keymaps as necessary. */
27097883Sgibbs  for (i = 0; i < keys_len; i++)
27197883Sgibbs    {
27297883Sgibbs      int ic = (int) ((unsigned char)keys[i]);
27397883Sgibbs
27497883Sgibbs      if (_rl_convert_meta_chars_to_ascii && META_CHAR (ic))
27597883Sgibbs	{
27697883Sgibbs	  ic = UNMETA (ic);
27797883Sgibbs	  if (map[ESC].type == ISKMAP)
27897883Sgibbs	    map = FUNCTION_TO_KEYMAP (map, ESC);
279102681Sgibbs	}
280102681Sgibbs
281102681Sgibbs      if ((i + 1) < keys_len)
282102681Sgibbs	{
283102681Sgibbs	  if (map[ic].type != ISKMAP)
28497883Sgibbs	    {
28597883Sgibbs	      if (map[ic].type == ISMACR)
28697883Sgibbs		free ((char *)map[ic].function);
28797883Sgibbs
28897883Sgibbs	      map[ic].type = ISKMAP;
28997883Sgibbs	      map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap());
29097883Sgibbs	    }
29197883Sgibbs	  map = FUNCTION_TO_KEYMAP (map, ic);
292102681Sgibbs	}
293102681Sgibbs      else
294102681Sgibbs	{
295102681Sgibbs	  if (map[ic].type == ISMACR)
296102681Sgibbs	    free ((char *)map[ic].function);
29797883Sgibbs
29897883Sgibbs	  map[ic].function = KEYMAP_TO_FUNCTION (data);
29997883Sgibbs	  map[ic].type = type;
30097883Sgibbs	}
30197883Sgibbs
30297883Sgibbs      rl_binding_keymap = map;
30397883Sgibbs    }
30497883Sgibbs  free (keys);
30597883Sgibbs  return 0;
30697883Sgibbs}
30797883Sgibbs
30897883Sgibbs/* Translate the ASCII representation of SEQ, stuffing the values into ARRAY,
30997883Sgibbs   an array of characters.  LEN gets the final length of ARRAY.  Return
31097883Sgibbs   non-zero if there was an error parsing SEQ. */
31197883Sgibbsint
31297883Sgibbsrl_translate_keyseq (seq, array, len)
31397883Sgibbs     char *seq, *array;
31497883Sgibbs     int *len;
31597883Sgibbs{
31697883Sgibbs  register int i, c, l;
31797883Sgibbs
31897883Sgibbs  for (i = l = 0; c = seq[i]; i++)
31997883Sgibbs    {
32097883Sgibbs      if (c == '\\')
32197883Sgibbs	{
32297883Sgibbs	  c = seq[++i];
32397883Sgibbs
32497883Sgibbs	  if (c == 0)
32597883Sgibbs	    break;
32697883Sgibbs
32797883Sgibbs	  if (((c == 'C' || c == 'M') && seq[i + 1] == '-') || (c == 'e'))
32897883Sgibbs	    {
32997883Sgibbs	      /* Handle special case of backwards define. */
33097883Sgibbs	      if (strncmp (&seq[i], "C-\\M-", 5) == 0)
33197883Sgibbs		{
33297883Sgibbs		  array[l++] = ESC;
33397883Sgibbs		  i += 5;
33497883Sgibbs		  array[l++] = CTRL (_rl_to_upper (seq[i]));
33597883Sgibbs		  if (!seq[i])
33697883Sgibbs		    i--;
33797883Sgibbs		  continue;
33897883Sgibbs		}
33997883Sgibbs
34097883Sgibbs	      switch (c)
34197883Sgibbs		{
34297883Sgibbs		case 'M':
34397883Sgibbs		  i++;
344102681Sgibbs		  array[l++] = ESC;	/* XXX */
345102681Sgibbs		  break;
346102681Sgibbs
347102681Sgibbs		case 'C':
348102681Sgibbs		  i += 2;
349102681Sgibbs		  /* Special hack for C-?... */
350102681Sgibbs		  array[l++] = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i]));
351102681Sgibbs		  break;
352102681Sgibbs
353102681Sgibbs		case 'e':
354102681Sgibbs		  array[l++] = ESC;
355102681Sgibbs		}
356102681Sgibbs
357102681Sgibbs	      continue;
358102681Sgibbs	    }
359102681Sgibbs	}
360102681Sgibbs      array[l++] = c;
361102681Sgibbs    }
362102681Sgibbs
36397883Sgibbs  *len = l;
36497883Sgibbs  array[l] = '\0';
36597883Sgibbs  return (0);
36697883Sgibbs}
36797883Sgibbs
36897883Sgibbschar *
36997883Sgibbsrl_untranslate_keyseq (seq)
37097883Sgibbs     int seq;
371102681Sgibbs{
372102681Sgibbs  static char kseq[16];
373102681Sgibbs  int i, c;
374102681Sgibbs
375102681Sgibbs  i = 0;
376102681Sgibbs  c = seq;
377102681Sgibbs  if (META_CHAR (c))
378102681Sgibbs    {
37997883Sgibbs      kseq[i++] = '\\';
38097883Sgibbs      kseq[i++] = 'M';
38197883Sgibbs      kseq[i++] = '-';
38297883Sgibbs      c = UNMETA (c);
38397883Sgibbs    }
38497883Sgibbs  else if (CTRL_CHAR (c))
38597883Sgibbs    {
38697883Sgibbs      kseq[i++] = '\\';
38797883Sgibbs      kseq[i++] = 'C';
388102681Sgibbs      kseq[i++] = '-';
389107441Sscottl      c = _rl_to_lower (UNCTRL (c));
390102681Sgibbs    }
391102681Sgibbs  else if (c == RUBOUT)
392102681Sgibbs    {
393102681Sgibbs      kseq[i++] = '\\';
394102681Sgibbs      kseq[i++] = 'C';
395102681Sgibbs      kseq[i++] = '-';
396102681Sgibbs      c = '?';
397102681Sgibbs    }
398102681Sgibbs
39997883Sgibbs  if (c == ESC)
40097883Sgibbs    {
40197883Sgibbs      kseq[i++] = '\\';
40297883Sgibbs      c = 'e';
40397883Sgibbs    }
40497883Sgibbs  else if (c == '\\' || c == '"')
40597883Sgibbs    {
40697883Sgibbs      kseq[i++] = '\\';
40797883Sgibbs    }
408102681Sgibbs
409102681Sgibbs  kseq[i++] = (unsigned char) c;
410102681Sgibbs  kseq[i] = '\0';
411102681Sgibbs  return kseq;
412102681Sgibbs}
413102681Sgibbs
41497883Sgibbsstatic char *
41597883Sgibbs_rl_untranslate_macro_value (seq)
41697883Sgibbs     char *seq;
41797883Sgibbs{
41897883Sgibbs  char *ret, *r, *s;
41997883Sgibbs  int c;
42097883Sgibbs
42197883Sgibbs  r = ret = xmalloc (7 * strlen (seq) + 1);
42297883Sgibbs  for (s = seq; *s; s++)
423102681Sgibbs    {
424102681Sgibbs      c = *s;
425102681Sgibbs      if (META_CHAR (c))
426102681Sgibbs	{
427102681Sgibbs	  *r++ = '\\';
428102681Sgibbs	  *r++ = 'M';
429102681Sgibbs	  *r++ = '-';
43097883Sgibbs	  c = UNMETA (c);
43197883Sgibbs	}
43297883Sgibbs      else if (CTRL_CHAR (c) && c != ESC)
43397883Sgibbs	{
43497883Sgibbs	  *r++ = '\\';
43597883Sgibbs	  *r++ = 'C';
43697883Sgibbs	  *r++ = '-';
43797883Sgibbs	  c = _rl_to_lower (UNCTRL (c));
43897883Sgibbs	}
439102681Sgibbs      else if (c == RUBOUT)
440102681Sgibbs 	{
441102681Sgibbs 	  *r++ = '\\';
44297883Sgibbs 	  *r++ = 'C';
44397883Sgibbs 	  *r++ = '-';
44497883Sgibbs 	  c = '?';
44597883Sgibbs 	}
44697883Sgibbs
44797883Sgibbs      if (c == ESC)
448102681Sgibbs	{
449102681Sgibbs	  *r++ = '\\';
450102681Sgibbs	  c = 'e';
451102681Sgibbs	}
45297883Sgibbs      else if (c == '\\' || c == '"')
45397883Sgibbs	*r++ = '\\';
45497883Sgibbs
45597883Sgibbs      *r++ = (unsigned char)c;
45697883Sgibbs    }
45797883Sgibbs  *r = '\0';
45897883Sgibbs  return ret;
45997883Sgibbs}
46097883Sgibbs
461102681Sgibbs/* Return a pointer to the function that STRING represents.
462102681Sgibbs   If STRING doesn't have a matching function, then a NULL pointer
463102681Sgibbs   is returned. */
46497883SgibbsFunction *
46597883Sgibbsrl_named_function (string)
46697883Sgibbs     char *string;
46797883Sgibbs{
46897883Sgibbs  register int i;
46997883Sgibbs
47097883Sgibbs  rl_initialize_funmap ();
47197883Sgibbs
47297883Sgibbs  for (i = 0; funmap[i]; i++)
47397883Sgibbs    if (_rl_stricmp (funmap[i]->name, string) == 0)
47497883Sgibbs      return (funmap[i]->function);
47597883Sgibbs  return ((Function *)NULL);
47697883Sgibbs}
47797883Sgibbs
47897883Sgibbs/* Return the function (or macro) definition which would be invoked via
47997883Sgibbs   KEYSEQ if executed in MAP.  If MAP is NULL, then the current keymap is
48097883Sgibbs   used.  TYPE, if non-NULL, is a pointer to an int which will receive the
48197883Sgibbs   type of the object pointed to.  One of ISFUNC (function), ISKMAP (keymap),
48297883Sgibbs   or ISMACR (macro). */
48397883SgibbsFunction *
48497883Sgibbsrl_function_of_keyseq (keyseq, map, type)
48597883Sgibbs     char *keyseq;
48697883Sgibbs     Keymap map;
487107441Sscottl     int *type;
488107441Sscottl{
489107441Sscottl  register int i;
490107441Sscottl
491107441Sscottl  if (!map)
492107441Sscottl    map = _rl_keymap;
493107441Sscottl
494107441Sscottl  for (i = 0; keyseq && keyseq[i]; i++)
495107441Sscottl    {
496107441Sscottl      int ic = keyseq[i];
497107441Sscottl
49897883Sgibbs      if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
49997883Sgibbs	{
50097883Sgibbs	  if (map[ESC].type != ISKMAP)
50197883Sgibbs	    {
50297883Sgibbs	      if (type)
50397883Sgibbs		*type = map[ESC].type;
50497883Sgibbs
50597883Sgibbs	      return (map[ESC].function);
50697883Sgibbs	    }
50797883Sgibbs	  else
50897883Sgibbs	    {
50997883Sgibbs	      map = FUNCTION_TO_KEYMAP (map, ESC);
51097883Sgibbs	      ic = UNMETA (ic);
51197883Sgibbs	    }
51297883Sgibbs	}
51397883Sgibbs
51497883Sgibbs      if (map[ic].type == ISKMAP)
51597883Sgibbs	{
51697883Sgibbs	  /* If this is the last key in the key sequence, return the
51797883Sgibbs	     map. */
51897883Sgibbs	  if (!keyseq[i + 1])
51997883Sgibbs	    {
52097883Sgibbs	      if (type)
52197883Sgibbs		*type = ISKMAP;
52297883Sgibbs
52397883Sgibbs	      return (map[ic].function);
52497883Sgibbs	    }
52597883Sgibbs	  else
52697883Sgibbs	    map = FUNCTION_TO_KEYMAP (map, ic);
52797883Sgibbs	}
52897883Sgibbs      else
52997883Sgibbs	{
53097883Sgibbs	  if (type)
53197883Sgibbs	    *type = map[ic].type;
53297883Sgibbs
53397883Sgibbs	  return (map[ic].function);
53497883Sgibbs	}
53597883Sgibbs    }
53697883Sgibbs  return ((Function *) NULL);
53797883Sgibbs}
53897883Sgibbs
53997883Sgibbs/* The last key bindings file read. */
54097883Sgibbsstatic char *last_readline_init_file = (char *)NULL;
54197883Sgibbs
54297883Sgibbs/* The file we're currently reading key bindings from. */
54397883Sgibbsstatic char *current_readline_init_file;
54497883Sgibbsstatic int current_readline_init_lineno;
54597883Sgibbs
54697883Sgibbs/* Re-read the current keybindings file. */
54797883Sgibbsint
54897883Sgibbsrl_re_read_init_file (count, ignore)
54997883Sgibbs     int count, ignore;
55097883Sgibbs{
55197883Sgibbs  int r;
55297883Sgibbs  r = rl_read_init_file ((char *)NULL);
55397883Sgibbs  rl_set_keymap_from_edit_mode ();
55497883Sgibbs  return r;
55597883Sgibbs}
55697883Sgibbs
55797883Sgibbs/* Do key bindings from a file.  If FILENAME is NULL it defaults
55897883Sgibbs   to the first non-null filename from this list:
55997883Sgibbs     1. the filename used for the previous call
56097883Sgibbs     2. the value of the shell variable `INPUTRC'
56197883Sgibbs     3. ~/.inputrc
56297883Sgibbs   If the file existed and could be opened and read, 0 is returned,
56397883Sgibbs   otherwise errno is returned. */
56497883Sgibbsint
56597883Sgibbsrl_read_init_file (filename)
56697883Sgibbs     char *filename;
56797883Sgibbs{
56897883Sgibbs  register int i;
56997883Sgibbs  char *buffer, *openname, *line, *end;
57097883Sgibbs  struct stat finfo;
571102681Sgibbs  int file;
572102681Sgibbs
573102681Sgibbs  /* Default the filename. */
574102681Sgibbs  if (filename == 0)
575102681Sgibbs    {
576102681Sgibbs      filename = last_readline_init_file;
577102681Sgibbs      if (filename == 0)
578102681Sgibbs        filename = get_env_value ("INPUTRC");
579102681Sgibbs      if (filename == 0)
580102681Sgibbs	filename = DEFAULT_INPUTRC;
581102681Sgibbs    }
582102681Sgibbs
583102681Sgibbs  if (*filename == 0)
584102681Sgibbs    filename = DEFAULT_INPUTRC;
585102681Sgibbs
586102681Sgibbs  current_readline_init_file = filename;
587102681Sgibbs  openname = tilde_expand (filename);
588102681Sgibbs
589102681Sgibbs  if ((stat (openname, &finfo) < 0) ||
590102681Sgibbs      (file = open (openname, O_RDONLY, 0666)) < 0)
59197883Sgibbs    {
59297883Sgibbs      free (openname);
59397883Sgibbs      return (errno);
59497883Sgibbs    }
59597883Sgibbs  else
59697883Sgibbs    free (openname);
59797883Sgibbs
59897883Sgibbs  if (filename != last_readline_init_file)
59997883Sgibbs    {
60097883Sgibbs      if (last_readline_init_file)
60197883Sgibbs	free (last_readline_init_file);
60297883Sgibbs
60397883Sgibbs      last_readline_init_file = savestring (filename);
60497883Sgibbs    }
60597883Sgibbs
60697883Sgibbs  /* Read the file into BUFFER. */
60797883Sgibbs  buffer = (char *)xmalloc ((int)finfo.st_size + 1);
608102681Sgibbs  i = read (file, buffer, finfo.st_size);
609102681Sgibbs  close (file);
610102681Sgibbs
611102681Sgibbs  if (i != finfo.st_size)
61297883Sgibbs    return (errno);
61397883Sgibbs
61497883Sgibbs  /* Loop over the lines in the file.  Lines that start with `#' are
61597883Sgibbs     comments; all other lines are commands for readline initialization. */
61697883Sgibbs  current_readline_init_lineno = 1;
61797883Sgibbs  line = buffer;
61897883Sgibbs  end = buffer + finfo.st_size;
61997883Sgibbs  while (line < end)
62097883Sgibbs    {
62197883Sgibbs      /* Find the end of this line. */
62297883Sgibbs      for (i = 0; line + i != end && line[i] != '\n'; i++);
62397883Sgibbs
62497883Sgibbs      /* Mark end of line. */
62597883Sgibbs      line[i] = '\0';
62697883Sgibbs
62797883Sgibbs      /* Skip leading whitespace. */
62897883Sgibbs      while (*line && whitespace (*line))
629102681Sgibbs        {
630102681Sgibbs	  line++;
63197883Sgibbs	  i--;
63297883Sgibbs        }
63397883Sgibbs
63497883Sgibbs      /* If the line is not a comment, then parse it. */
63597883Sgibbs      if (*line && *line != '#')
63697883Sgibbs	rl_parse_and_bind (line);
63797883Sgibbs
63897883Sgibbs      /* Move to the next line. */
63997883Sgibbs      line += i + 1;
640102681Sgibbs      current_readline_init_lineno++;
641102681Sgibbs    }
64297883Sgibbs  free (buffer);
64397883Sgibbs  return (0);
64497883Sgibbs}
64597883Sgibbs
64697883Sgibbsstatic void
64797883Sgibbs_rl_init_file_error (msg)
64897883Sgibbs     char *msg;
64997883Sgibbs{
65097883Sgibbs  fprintf (stderr, "readline: %s: line %d: %s\n", current_readline_init_file,
651102681Sgibbs 		   current_readline_init_lineno,
652102681Sgibbs 		   msg);
65397883Sgibbs}
65497883Sgibbs
65597883Sgibbs/* **************************************************************** */
65697883Sgibbs/*								    */
65797883Sgibbs/*			Parser Directives       		    */
65897883Sgibbs/*								    */
65997883Sgibbs/* **************************************************************** */
66097883Sgibbs
66197883Sgibbs/* Conditionals. */
662102681Sgibbs
663102681Sgibbs/* Calling programs set this to have their argv[0]. */
664102681Sgibbschar *rl_readline_name = "other";
665102681Sgibbs
666102681Sgibbs/* Stack of previous values of parsing_conditionalized_out. */
667102681Sgibbsstatic unsigned char *if_stack = (unsigned char *)NULL;
66897883Sgibbsstatic int if_stack_depth;
66997883Sgibbsstatic int if_stack_size;
67097883Sgibbs
67197883Sgibbs/* Push _rl_parsing_conditionalized_out, and set parser state based
67297883Sgibbs   on ARGS. */
67397883Sgibbsstatic int
67497883Sgibbsparser_if (args)
67597883Sgibbs     char *args;
67697883Sgibbs{
677102681Sgibbs  register int i;
67897883Sgibbs
67997883Sgibbs  /* Push parser state. */
68097883Sgibbs  if (if_stack_depth + 1 >= if_stack_size)
68197883Sgibbs    {
68297883Sgibbs      if (!if_stack)
68397883Sgibbs	if_stack = (unsigned char *)xmalloc (if_stack_size = 20);
68497883Sgibbs      else
68597883Sgibbs	if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20);
68697883Sgibbs    }
687102681Sgibbs  if_stack[if_stack_depth++] = _rl_parsing_conditionalized_out;
68897883Sgibbs
68997883Sgibbs  /* If parsing is turned off, then nothing can turn it back on except
69097883Sgibbs     for finding the matching endif.  In that case, return right now. */
69197883Sgibbs  if (_rl_parsing_conditionalized_out)
69297883Sgibbs    return 0;
69397883Sgibbs
69497883Sgibbs  /* Isolate first argument. */
69597883Sgibbs  for (i = 0; args[i] && !whitespace (args[i]); i++);
69697883Sgibbs
697102681Sgibbs  if (args[i])
69897883Sgibbs    args[i++] = '\0';
69997883Sgibbs
70097883Sgibbs  /* Handle "if term=foo" and "if mode=emacs" constructs.  If this
70197883Sgibbs     isn't term=foo, or mode=emacs, then check to see if the first
70297883Sgibbs     word in ARGS is the same as the value stored in rl_readline_name. */
70397883Sgibbs  if (rl_terminal_name && _rl_strnicmp (args, "term=", 5) == 0)
70497883Sgibbs    {
70597883Sgibbs      char *tem, *tname;
70697883Sgibbs
707102681Sgibbs      /* Terminals like "aaa-60" are equivalent to "aaa". */
708102681Sgibbs      tname = savestring (rl_terminal_name);
709102681Sgibbs      tem = strchr (tname, '-');
710102681Sgibbs      if (tem)
711102681Sgibbs	*tem = '\0';
712102681Sgibbs
71397883Sgibbs      /* Test the `long' and `short' forms of the terminal name so that
71497883Sgibbs	 if someone has a `sun-cmd' and does not want to have bindings
71597883Sgibbs	 that will be executed if the terminal is a `sun', they can put
71697883Sgibbs	 `$if term=sun-cmd' into their .inputrc. */
71797883Sgibbs      _rl_parsing_conditionalized_out = _rl_stricmp (args + 5, tname) &&
71897883Sgibbs					_rl_stricmp (args + 5, rl_terminal_name);
71997883Sgibbs      free (tname);
72097883Sgibbs    }
72197883Sgibbs#if defined (VI_MODE)
722102681Sgibbs  else if (_rl_strnicmp (args, "mode=", 5) == 0)
72397883Sgibbs    {
72497883Sgibbs      int mode;
72597883Sgibbs
72697883Sgibbs      if (_rl_stricmp (args + 5, "emacs") == 0)
72797883Sgibbs	mode = emacs_mode;
72897883Sgibbs      else if (_rl_stricmp (args + 5, "vi") == 0)
72997883Sgibbs	mode = vi_mode;
73097883Sgibbs      else
73197883Sgibbs	mode = no_mode;
732102681Sgibbs
73397883Sgibbs      _rl_parsing_conditionalized_out = mode != rl_editing_mode;
73497883Sgibbs    }
73597883Sgibbs#endif /* VI_MODE */
73697883Sgibbs  /* Check to see if the first word in ARGS is the same as the
73797883Sgibbs     value stored in rl_readline_name. */
73897883Sgibbs  else if (_rl_stricmp (args, rl_readline_name) == 0)
73997883Sgibbs    _rl_parsing_conditionalized_out = 0;
74097883Sgibbs  else
74197883Sgibbs    _rl_parsing_conditionalized_out = 1;
742102681Sgibbs  return 0;
74397883Sgibbs}
74497883Sgibbs
74597883Sgibbs/* Invert the current parser state if there is anything on the stack. */
74697883Sgibbsstatic int
74797883Sgibbsparser_else (args)
74897883Sgibbs     char *args;
74997883Sgibbs{
75097883Sgibbs  register int i;
75197883Sgibbs
75297883Sgibbs  if (!if_stack_depth)
75397883Sgibbs    {
75497883Sgibbs      /* Error message? */
75597883Sgibbs      return 0;
75697883Sgibbs    }
75797883Sgibbs
75897883Sgibbs  /* Check the previous (n - 1) levels of the stack to make sure that
75997883Sgibbs     we haven't previously turned off parsing. */
76097883Sgibbs  for (i = 0; i < if_stack_depth - 1; i++)
761102681Sgibbs    if (if_stack[i] == 1)
76297883Sgibbs      return 0;
76397883Sgibbs
76497883Sgibbs  /* Invert the state of parsing if at top level. */
76597883Sgibbs  _rl_parsing_conditionalized_out = !_rl_parsing_conditionalized_out;
76697883Sgibbs  return 0;
76797883Sgibbs}
76897883Sgibbs
76997883Sgibbs/* Terminate a conditional, popping the value of
77097883Sgibbs   _rl_parsing_conditionalized_out from the stack. */
771102681Sgibbsstatic int
77297883Sgibbsparser_endif (args)
77397883Sgibbs     char *args;
77497883Sgibbs{
77597883Sgibbs  if (if_stack_depth)
77697883Sgibbs    _rl_parsing_conditionalized_out = if_stack[--if_stack_depth];
77797883Sgibbs  else
77897883Sgibbs    {
77997883Sgibbs      /* *** What, no error message? *** */
78097883Sgibbs    }
781102681Sgibbs  return 0;
78297883Sgibbs}
78397883Sgibbs
78497883Sgibbs/* Associate textual names with actual functions. */
78597883Sgibbsstatic struct {
78697883Sgibbs  char *name;
78797883Sgibbs  Function *function;
78897883Sgibbs} parser_directives [] = {
78997883Sgibbs  { "if", parser_if },
79097883Sgibbs  { "endif", parser_endif },
791102681Sgibbs  { "else", parser_else },
792102681Sgibbs  { (char *)0x0, (Function *)0x0 }
793102681Sgibbs};
794102681Sgibbs
795102681Sgibbs/* Handle a parser directive.  STATEMENT is the line of the directive
796102681Sgibbs   without any leading `$'. */
797102681Sgibbsstatic int
79897883Sgibbshandle_parser_directive (statement)
79997883Sgibbs     char *statement;
80097883Sgibbs{
80197883Sgibbs  register int i;
80297883Sgibbs  char *directive, *args;
80397883Sgibbs
80497883Sgibbs  /* Isolate the actual directive. */
80597883Sgibbs
80697883Sgibbs  /* Skip whitespace. */
80797883Sgibbs  for (i = 0; whitespace (statement[i]); i++);
80897883Sgibbs
80997883Sgibbs  directive = &statement[i];
81097883Sgibbs
81197883Sgibbs  for (; statement[i] && !whitespace (statement[i]); i++);
81297883Sgibbs
81397883Sgibbs  if (statement[i])
81497883Sgibbs    statement[i++] = '\0';
81597883Sgibbs
81697883Sgibbs  for (; statement[i] && whitespace (statement[i]); i++);
81797883Sgibbs
81897883Sgibbs  args = &statement[i];
81997883Sgibbs
82097883Sgibbs  /* Lookup the command, and act on it. */
82197883Sgibbs  for (i = 0; parser_directives[i].name; i++)
82297883Sgibbs    if (_rl_stricmp (directive, parser_directives[i].name) == 0)
82397883Sgibbs      {
82497883Sgibbs	(*parser_directives[i].function) (args);
82597883Sgibbs	return (0);
82697883Sgibbs      }
82797883Sgibbs
82897883Sgibbs  /* *** Should an error message be output? */
82997883Sgibbs  return (1);
83097883Sgibbs}
83197883Sgibbs
83297883Sgibbs/* Read the binding command from STRING and perform it.
83397883Sgibbs   A key binding command looks like: Keyname: function-name\0,
83497883Sgibbs   a variable binding command looks like: set variable value.
835102681Sgibbs   A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */
836102681Sgibbsint
837102681Sgibbsrl_parse_and_bind (string)
838102681Sgibbs     char *string;
839102681Sgibbs{
840102681Sgibbs  char *funname, *kname;
841102681Sgibbs  register int c, i;
842102681Sgibbs  int key, equivalency;
84397883Sgibbs
84497883Sgibbs  while (string && whitespace (*string))
84597883Sgibbs    string++;
84697883Sgibbs
84797883Sgibbs  if (!string || !*string || *string == '#')
84897883Sgibbs    return 0;
84997883Sgibbs
85097883Sgibbs  /* If this is a parser directive, act on it. */
85197883Sgibbs  if (*string == '$')
852102681Sgibbs    {
853102681Sgibbs      handle_parser_directive (&string[1]);
854102681Sgibbs      return 0;
855102681Sgibbs    }
856102681Sgibbs
857102681Sgibbs  /* If we aren't supposed to be parsing right now, then we're done. */
858102681Sgibbs  if (_rl_parsing_conditionalized_out)
859102681Sgibbs    return 0;
86097883Sgibbs
86197883Sgibbs  i = 0;
86297883Sgibbs  /* If this keyname is a complex key expression surrounded by quotes,
86397883Sgibbs     advance to after the matching close quote.  This code allows the
86497883Sgibbs     backslash to quote characters in the key expression. */
86597883Sgibbs  if (*string == '"')
86697883Sgibbs    {
86797883Sgibbs      int passc = 0;
86897883Sgibbs
869102681Sgibbs      for (i = 1; c = string[i]; i++)
870102681Sgibbs	{
871102681Sgibbs	  if (passc)
872102681Sgibbs	    {
873102681Sgibbs	      passc = 0;
874102681Sgibbs	      continue;
875102681Sgibbs	    }
876102681Sgibbs
87797883Sgibbs	  if (c == '\\')
87897883Sgibbs	    {
87997883Sgibbs	      passc++;
88097883Sgibbs	      continue;
88197883Sgibbs	    }
88297883Sgibbs
88397883Sgibbs	  if (c == '"')
88497883Sgibbs	    break;
88597883Sgibbs	}
886102681Sgibbs      /* If we didn't find a closing quote, abort the line. */
88797883Sgibbs      if (string[i] == '\0')
88897883Sgibbs        {
88997883Sgibbs          _rl_init_file_error ("no closing `\"' in key binding");
89097883Sgibbs          return 1;
89197883Sgibbs        }
89297883Sgibbs    }
89397883Sgibbs
89497883Sgibbs  /* Advance to the colon (:) or whitespace which separates the two objects. */
89597883Sgibbs  for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ );
896102681Sgibbs
89797883Sgibbs  equivalency = (c == ':' && string[i + 1] == '=');
89897883Sgibbs
89997883Sgibbs  /* Mark the end of the command (or keyname). */
90097883Sgibbs  if (string[i])
90197883Sgibbs    string[i++] = '\0';
90297883Sgibbs
90397883Sgibbs  /* If doing assignment, skip the '=' sign as well. */
90497883Sgibbs  if (equivalency)
90597883Sgibbs    string[i++] = '\0';
906102681Sgibbs
90797883Sgibbs  /* If this is a command to set a variable, then do that. */
90897883Sgibbs  if (_rl_stricmp (string, "set") == 0)
90997883Sgibbs    {
91097883Sgibbs      char *var = string + i;
91197883Sgibbs      char *value;
91297883Sgibbs
91397883Sgibbs      /* Make VAR point to start of variable name. */
91497883Sgibbs      while (*var && whitespace (*var)) var++;
91597883Sgibbs
916102681Sgibbs      /* Make value point to start of value string. */
917102681Sgibbs      value = var;
91897883Sgibbs      while (*value && !whitespace (*value)) value++;
91997883Sgibbs      if (*value)
92097883Sgibbs	*value++ = '\0';
92197883Sgibbs      while (*value && whitespace (*value)) value++;
92297883Sgibbs
92397883Sgibbs      rl_variable_bind (var, value);
92497883Sgibbs      return 0;
92597883Sgibbs    }
92697883Sgibbs
927102681Sgibbs  /* Skip any whitespace between keyname and funname. */
92897883Sgibbs  for (; string[i] && whitespace (string[i]); i++);
92997883Sgibbs  funname = &string[i];
93097883Sgibbs
93197883Sgibbs  /* Now isolate funname.
93297883Sgibbs     For straight function names just look for whitespace, since
93397883Sgibbs     that will signify the end of the string.  But this could be a
93497883Sgibbs     macro definition.  In that case, the string is quoted, so skip
93597883Sgibbs     to the matching delimiter.  We allow the backslash to quote the
93697883Sgibbs     delimiter characters in the macro body. */
937102681Sgibbs  /* This code exists to allow whitespace in macro expansions, which
93897883Sgibbs     would otherwise be gobbled up by the next `for' loop.*/
93997883Sgibbs  /* XXX - it may be desirable to allow backslash quoting only if " is
94097883Sgibbs     the quoted string delimiter, like the shell. */
94197883Sgibbs  if (*funname == '\'' || *funname == '"')
94297883Sgibbs    {
94397883Sgibbs      int delimiter = string[i++];
94497883Sgibbs      int passc = 0;
94597883Sgibbs
94697883Sgibbs      for (; c = string[i]; i++)
947102681Sgibbs	{
94897883Sgibbs	  if (passc)
94997883Sgibbs	    {
95097883Sgibbs	      passc = 0;
95197883Sgibbs	      continue;
95297883Sgibbs	    }
95397883Sgibbs
95497883Sgibbs	  if (c == '\\')
95597883Sgibbs	    {
95697883Sgibbs	      passc = 1;
957102681Sgibbs	      continue;
95897883Sgibbs	    }
95997883Sgibbs
96097883Sgibbs	  if (c == delimiter)
96197883Sgibbs	    break;
96297883Sgibbs	}
96397883Sgibbs      if (c)
96497883Sgibbs	i++;
96597883Sgibbs    }
96697883Sgibbs
967102681Sgibbs  /* Advance to the end of the string.  */
968102681Sgibbs  for (; string[i] && !whitespace (string[i]); i++);
96997883Sgibbs
97097883Sgibbs  /* No extra whitespace at the end of the string. */
97197883Sgibbs  string[i] = '\0';
97297883Sgibbs
97397883Sgibbs  /* Handle equivalency bindings here.  Make the left-hand side be exactly
97497883Sgibbs     whatever the right-hand evaluates to, including keymaps. */
97597883Sgibbs  if (equivalency)
97697883Sgibbs    {
97797883Sgibbs      return 0;
978102681Sgibbs    }
97997883Sgibbs
98097883Sgibbs  /* If this is a new-style key-binding, then do the binding with
98197883Sgibbs     rl_set_key ().  Otherwise, let the older code deal with it. */
98297883Sgibbs  if (*string == '"')
98397883Sgibbs    {
98497883Sgibbs      char *seq = xmalloc (1 + strlen (string));
98597883Sgibbs      register int j, k = 0;
98697883Sgibbs      int passc = 0;
98797883Sgibbs
988102681Sgibbs      for (j = 1; string[j]; j++)
989102681Sgibbs	{
99097883Sgibbs	  /* Allow backslash to quote characters, but leave them in place.
99197883Sgibbs	     This allows a string to end with a backslash quoting another
99297883Sgibbs	     backslash, or with a backslash quoting a double quote.  The
99397883Sgibbs	     backslashes are left in place for rl_translate_keyseq (). */
99497883Sgibbs	  if (passc || (string[j] == '\\'))
99597883Sgibbs	    {
99697883Sgibbs	      seq[k++] = string[j];
99797883Sgibbs	      passc = !passc;
99897883Sgibbs	      continue;
99997883Sgibbs	    }
100097883Sgibbs
100197883Sgibbs	  if (string[j] == '"')
100297883Sgibbs	    break;
100397883Sgibbs
100497883Sgibbs	  seq[k++] = string[j];
100597883Sgibbs	}
100697883Sgibbs      seq[k] = '\0';
100797883Sgibbs
1008102681Sgibbs      /* Binding macro? */
100997883Sgibbs      if (*funname == '\'' || *funname == '"')
101097883Sgibbs	{
101197883Sgibbs	  j = strlen (funname);
101297883Sgibbs
101397883Sgibbs	  /* Remove the delimiting quotes from each end of FUNNAME. */
101497883Sgibbs	  if (j && funname[j - 1] == *funname)
101597883Sgibbs	    funname[j - 1] = '\0';
101697883Sgibbs
101797883Sgibbs	  rl_macro_bind (seq, &funname[1], _rl_keymap);
1018102681Sgibbs	}
1019102681Sgibbs      else
102097883Sgibbs	rl_set_key (seq, rl_named_function (funname), _rl_keymap);
102197883Sgibbs
102297883Sgibbs      free (seq);
102397883Sgibbs      return 0;
102497883Sgibbs    }
102597883Sgibbs
102697883Sgibbs  /* Get the actual character we want to deal with. */
102797883Sgibbs  kname = strrchr (string, '-');
102897883Sgibbs  if (!kname)
102997883Sgibbs    kname = string;
1030102681Sgibbs  else
103197883Sgibbs    kname++;
103297883Sgibbs
103397883Sgibbs  key = glean_key_from_name (kname);
103497883Sgibbs
103597883Sgibbs  /* Add in control and meta bits. */
103697883Sgibbs  if (substring_member_of_array (string, possible_control_prefixes))
103797883Sgibbs    key = CTRL (_rl_to_upper (key));
103897883Sgibbs
1039102681Sgibbs  if (substring_member_of_array (string, possible_meta_prefixes))
1040102681Sgibbs    key = META (key);
1041102681Sgibbs
1042102681Sgibbs  /* Temporary.  Handle old-style keyname with macro-binding. */
1043102681Sgibbs  if (*funname == '\'' || *funname == '"')
1044102681Sgibbs    {
1045102681Sgibbs      unsigned char useq[2];
1046102681Sgibbs      int fl = strlen (funname);
104797883Sgibbs
104897883Sgibbs      useq[0] = key; useq[1] = '\0';
104997883Sgibbs      if (fl && funname[fl - 1] == *funname)
105097883Sgibbs	funname[fl - 1] = '\0';
105197883Sgibbs
105297883Sgibbs      rl_macro_bind (useq, &funname[1], _rl_keymap);
105397883Sgibbs    }
105497883Sgibbs#if defined (PREFIX_META_HACK)
105597883Sgibbs  /* Ugly, but working hack to keep prefix-meta around. */
1056102681Sgibbs  else if (_rl_stricmp (funname, "prefix-meta") == 0)
105797883Sgibbs    {
105897883Sgibbs      char seq[2];
105997883Sgibbs
106097883Sgibbs      seq[0] = key;
106197883Sgibbs      seq[1] = '\0';
106297883Sgibbs      rl_generic_bind (ISKMAP, seq, (char *)emacs_meta_keymap, _rl_keymap);
106397883Sgibbs    }
106497883Sgibbs#endif /* PREFIX_META_HACK */
106597883Sgibbs  else
1066102681Sgibbs    rl_bind_key (key, rl_named_function (funname));
1067102681Sgibbs  return 0;
106897883Sgibbs}
106997883Sgibbs
107097883Sgibbs/* Simple structure for boolean readline variables (i.e., those that can
107197883Sgibbs   have one of two values; either "On" or 1 for truth, or "Off" or 0 for
107297883Sgibbs   false. */
107397883Sgibbs
107497883Sgibbsstatic struct {
107597883Sgibbs  char *name;
107697883Sgibbs  int *value;
1077102681Sgibbs} boolean_varlist [] = {
1078102681Sgibbs#if defined (PAREN_MATCHING)
1079102681Sgibbs  { "blink-matching-paren",	&rl_blink_matching_paren },
1080102681Sgibbs#endif
1081102681Sgibbs  { "convert-meta",		&_rl_convert_meta_chars_to_ascii },
1082102681Sgibbs  { "disable-completion",	&rl_inhibit_completion },
1083102681Sgibbs  { "enable-keypad",		&_rl_enable_keypad },
1084102681Sgibbs  { "expand-tilde",		&rl_complete_with_tilde_expansion },
108597883Sgibbs  { "horizontal-scroll-mode",	&_rl_horizontal_scroll_mode },
108697883Sgibbs  { "input-meta",		&_rl_meta_flag },
108797883Sgibbs  { "mark-directories",		&_rl_complete_mark_directories },
108897883Sgibbs  { "mark-modified-lines",	&_rl_mark_modified_lines },
108997883Sgibbs  { "meta-flag",		&_rl_meta_flag },
109097883Sgibbs  { "output-meta",		&_rl_output_meta_chars },
109197883Sgibbs  { "show-all-if-ambiguous",	&_rl_complete_show_all },
109297883Sgibbs#if defined (VISIBLE_STATS)
109397883Sgibbs  { "visible-stats",		&rl_visible_stats },
1094102681Sgibbs#endif /* VISIBLE_STATS */
1095102681Sgibbs  { (char *)NULL, (int *)NULL }
1096102681Sgibbs};
1097102681Sgibbs
1098102681Sgibbsint
1099102681Sgibbsrl_variable_bind (name, value)
1100102681Sgibbs     char *name, *value;
1101102681Sgibbs{
110297883Sgibbs  register int i;
110397883Sgibbs
110497883Sgibbs  /* Check for simple variables first. */
110597883Sgibbs  for (i = 0; boolean_varlist[i].name; i++)
110697883Sgibbs    {
110797883Sgibbs      if (_rl_stricmp (name, boolean_varlist[i].name) == 0)
110897883Sgibbs	{
110997883Sgibbs	  /* A variable is TRUE if the "value" is "on", "1" or "". */
111097883Sgibbs	  *boolean_varlist[i].value = *value == 0 ||
1111102681Sgibbs	  			      _rl_stricmp (value, "on") == 0 ||
1112102681Sgibbs				      (value[0] == '1' && value[1] == '\0');
1113102681Sgibbs	  return 0;
1114102681Sgibbs	}
1115102681Sgibbs    }
1116102681Sgibbs
1117102681Sgibbs  /* Not a boolean variable, so check for specials. */
111897883Sgibbs
111997883Sgibbs  /* Editing mode change? */
112097883Sgibbs  if (_rl_stricmp (name, "editing-mode") == 0)
112197883Sgibbs    {
112297883Sgibbs      if (_rl_strnicmp (value, "vi", 2) == 0)
112397883Sgibbs	{
112497883Sgibbs#if defined (VI_MODE)
112597883Sgibbs	  _rl_keymap = vi_insertion_keymap;
112697883Sgibbs	  rl_editing_mode = vi_mode;
1127102681Sgibbs#endif /* VI_MODE */
1128102681Sgibbs	}
1129102681Sgibbs      else if (_rl_strnicmp (value, "emacs", 5) == 0)
1130102681Sgibbs	{
1131102681Sgibbs	  _rl_keymap = emacs_standard_keymap;
1132102681Sgibbs	  rl_editing_mode = emacs_mode;
1133102681Sgibbs	}
1134102681Sgibbs    }
113597883Sgibbs
113697883Sgibbs  /* Comment string change? */
113797883Sgibbs  else if (_rl_stricmp (name, "comment-begin") == 0)
113897883Sgibbs    {
113997883Sgibbs      if (*value)
114097883Sgibbs	{
114197883Sgibbs	  if (_rl_comment_begin)
114297883Sgibbs	    free (_rl_comment_begin);
114397883Sgibbs
1144102681Sgibbs	  _rl_comment_begin = savestring (value);
1145102681Sgibbs	}
1146102681Sgibbs    }
1147102681Sgibbs  else if (_rl_stricmp (name, "completion-query-items") == 0)
1148102681Sgibbs    {
1149102681Sgibbs      int nval = 100;
1150102681Sgibbs      if (*value)
115197883Sgibbs	{
115297883Sgibbs	  nval = atoi (value);
115397883Sgibbs	  if (nval < 0)
115497883Sgibbs	    nval = 0;
115597883Sgibbs	}
115697883Sgibbs      rl_completion_query_items = nval;
115797883Sgibbs    }
115897883Sgibbs  else if (_rl_stricmp (name, "keymap") == 0)
115997883Sgibbs    {
1160102681Sgibbs      Keymap kmap;
1161102681Sgibbs      kmap = rl_get_keymap_by_name (value);
1162102681Sgibbs      if (kmap)
1163102681Sgibbs        rl_set_keymap (kmap);
1164102681Sgibbs    }
1165102681Sgibbs  else if (_rl_stricmp (name, "bell-style") == 0)
116697883Sgibbs    {
116797883Sgibbs      if (!*value)
116897883Sgibbs        _rl_bell_preference = AUDIBLE_BELL;
116997883Sgibbs      else
117097883Sgibbs        {
117197883Sgibbs          if (_rl_stricmp (value, "none") == 0 || _rl_stricmp (value, "off") == 0)
1172107623Sscottl            _rl_bell_preference = NO_BELL;
117397883Sgibbs          else if (_rl_stricmp (value, "audible") == 0 || _rl_stricmp (value, "on") == 0)
117497883Sgibbs            _rl_bell_preference = AUDIBLE_BELL;
1175102681Sgibbs          else if (_rl_stricmp (value, "visible") == 0)
1176102681Sgibbs            _rl_bell_preference = VISIBLE_BELL;
1177102681Sgibbs        }
1178102681Sgibbs    }
117997883Sgibbs  else if (_rl_stricmp (name, "prefer-visible-bell") == 0)
118097883Sgibbs    {
118197883Sgibbs      /* Backwards compatibility. */
118297883Sgibbs      if (*value && (_rl_stricmp (value, "on") == 0 ||
118397883Sgibbs		     (*value == '1' && !value[1])))
118497883Sgibbs        _rl_bell_preference = VISIBLE_BELL;
118597883Sgibbs      else
118697883Sgibbs        _rl_bell_preference = AUDIBLE_BELL;
118797883Sgibbs    }
118897883Sgibbs
118997883Sgibbs  return 0;
119097883Sgibbs}
119197883Sgibbs
119297883Sgibbs/* Return the character which matches NAME.
119397883Sgibbs   For example, `Space' returns ' '. */
119497883Sgibbs
119597883Sgibbstypedef struct {
119697883Sgibbs  char *name;
119797883Sgibbs  int value;
119897883Sgibbs} assoc_list;
119997883Sgibbs
120097883Sgibbsstatic assoc_list name_key_alist[] = {
120197883Sgibbs  { "DEL", 0x7f },
120297883Sgibbs  { "ESC", '\033' },
120397883Sgibbs  { "Escape", '\033' },
120497883Sgibbs  { "LFD", '\n' },
120597883Sgibbs  { "Newline", '\n' },
120697883Sgibbs  { "RET", '\r' },
120797883Sgibbs  { "Return", '\r' },
120897883Sgibbs  { "Rubout", 0x7f },
120997883Sgibbs  { "SPC", ' ' },
121097883Sgibbs  { "Space", ' ' },
121197883Sgibbs  { "Tab", 0x09 },
121297883Sgibbs  { (char *)0x0, 0 }
121397883Sgibbs};
121497883Sgibbs
121597883Sgibbsstatic int
121697883Sgibbsglean_key_from_name (name)
121797883Sgibbs     char *name;
121897883Sgibbs{
121997883Sgibbs  register int i;
122097883Sgibbs
122197883Sgibbs  for (i = 0; name_key_alist[i].name; i++)
122297883Sgibbs    if (_rl_stricmp (name, name_key_alist[i].name) == 0)
122397883Sgibbs      return (name_key_alist[i].value);
122497883Sgibbs
122597883Sgibbs  return (*(unsigned char *)name);	/* XXX was return (*name) */
122697883Sgibbs}
122797883Sgibbs
122897883Sgibbs/* Auxiliary functions to manage keymaps. */
122997883Sgibbsstatic struct {
123097883Sgibbs  char *name;
123197883Sgibbs  Keymap map;
123297883Sgibbs} keymap_names[] = {
123397883Sgibbs  { "emacs", emacs_standard_keymap },
123497883Sgibbs  { "emacs-standard", emacs_standard_keymap },
123597883Sgibbs  { "emacs-meta", emacs_meta_keymap },
123697883Sgibbs  { "emacs-ctlx", emacs_ctlx_keymap },
123797883Sgibbs#if defined (VI_MODE)
123897883Sgibbs  { "vi", vi_movement_keymap },
123997883Sgibbs  { "vi-move", vi_movement_keymap },
124097883Sgibbs  { "vi-command", vi_movement_keymap },
124197883Sgibbs  { "vi-insert", vi_insertion_keymap },
124297883Sgibbs#endif /* VI_MODE */
124397883Sgibbs  { (char *)0x0, (Keymap)0x0 }
124497883Sgibbs};
124597883Sgibbs
124697883SgibbsKeymap
124797883Sgibbsrl_get_keymap_by_name (name)
124897883Sgibbs     char *name;
124997883Sgibbs{
125097883Sgibbs  register int i;
125197883Sgibbs
125297883Sgibbs  for (i = 0; keymap_names[i].name; i++)
125397883Sgibbs    if (strcmp (name, keymap_names[i].name) == 0)
125497883Sgibbs      return (keymap_names[i].map);
125597883Sgibbs  return ((Keymap) NULL);
125697883Sgibbs}
125797883Sgibbs
125897883Sgibbschar *
125997883Sgibbsrl_get_keymap_name (map)
126097883Sgibbs     Keymap map;
126197883Sgibbs{
126297883Sgibbs  register int i;
126397883Sgibbs  for (i = 0; keymap_names[i].name; i++)
126497883Sgibbs    if (map == keymap_names[i].map)
126597883Sgibbs      return (keymap_names[i].name);
126697883Sgibbs  return ((char *)NULL);
126797883Sgibbs}
126897883Sgibbs
126997883Sgibbsvoid
127097883Sgibbsrl_set_keymap (map)
127197883Sgibbs     Keymap map;
127297883Sgibbs{
127397883Sgibbs  if (map)
127497883Sgibbs    _rl_keymap = map;
127597883Sgibbs}
127697883Sgibbs
127797883SgibbsKeymap
127897883Sgibbsrl_get_keymap ()
127997883Sgibbs{
128097883Sgibbs  return (_rl_keymap);
128197883Sgibbs}
128297883Sgibbs
128397883Sgibbsvoid
128497883Sgibbsrl_set_keymap_from_edit_mode ()
128597883Sgibbs{
128697883Sgibbs  if (rl_editing_mode == emacs_mode)
128797883Sgibbs    _rl_keymap = emacs_standard_keymap;
128897883Sgibbs#if defined (VI_MODE)
128997883Sgibbs  else if (rl_editing_mode == vi_mode)
129097883Sgibbs    _rl_keymap = vi_insertion_keymap;
129197883Sgibbs#endif /* VI_MODE */
129297883Sgibbs}
129397883Sgibbs
129497883Sgibbschar *
129597883Sgibbsrl_get_keymap_name_from_edit_mode ()
129697883Sgibbs{
129797883Sgibbs  if (rl_editing_mode == emacs_mode)
129897883Sgibbs    return "emacs";
129997883Sgibbs#if defined (VI_MODE)
130097883Sgibbs  else if (rl_editing_mode == vi_mode)
130197883Sgibbs    return "vi";
130297883Sgibbs#endif /* VI_MODE */
130397883Sgibbs  else
130497883Sgibbs    return "none";
130597883Sgibbs}
130697883Sgibbs
130797883Sgibbs/* **************************************************************** */
130897883Sgibbs/*								    */
130997883Sgibbs/*		  Key Binding and Function Information		    */
131097883Sgibbs/*								    */
131197883Sgibbs/* **************************************************************** */
131297883Sgibbs
131397883Sgibbs/* Each of the following functions produces information about the
131497883Sgibbs   state of keybindings and functions known to Readline.  The info
131597883Sgibbs   is always printed to rl_outstream, and in such a way that it can
131697883Sgibbs   be read back in (i.e., passed to rl_parse_and_bind (). */
131797883Sgibbs
131897883Sgibbs/* Print the names of functions known to Readline. */
131997883Sgibbsvoid
132097883Sgibbsrl_list_funmap_names ()
132197883Sgibbs{
132297883Sgibbs  register int i;
132397883Sgibbs  char **funmap_names;
132497883Sgibbs
132597883Sgibbs  funmap_names = rl_funmap_names ();
132697883Sgibbs
1327102681Sgibbs  if (!funmap_names)
1328102681Sgibbs    return;
1329102681Sgibbs
1330102681Sgibbs  for (i = 0; funmap_names[i]; i++)
1331102681Sgibbs    fprintf (rl_outstream, "%s\n", funmap_names[i]);
1332102681Sgibbs
1333102681Sgibbs  free (funmap_names);
1334102681Sgibbs}
1335102681Sgibbs
1336102681Sgibbsstatic char *
1337102681Sgibbs_rl_get_keyname (key)
1338102681Sgibbs     int key;
1339102681Sgibbs{
1340102681Sgibbs  char *keyname;
1341102681Sgibbs  int i, c;
1342102681Sgibbs
1343102681Sgibbs  keyname = (char *)xmalloc (8);
1344102681Sgibbs
1345102681Sgibbs  c = key;
1346102681Sgibbs  /* Since this is going to be used to write out keysequence-function
1347102681Sgibbs     pairs for possible inclusion in an inputrc file, we don't want to
1348102681Sgibbs     do any special meta processing on KEY. */
1349102681Sgibbs
1350102681Sgibbs#if 0
1351102681Sgibbs  /* We might want to do this, but the old version of the code did not. */
1352102681Sgibbs
1353102681Sgibbs  /* If this is an escape character, we don't want to do any more processing.
135497883Sgibbs     Just add the special ESC key sequence and return. */
135597883Sgibbs  if (c == ESC)
135697883Sgibbs    {
135797883Sgibbs      keyseq[0] = '\\';
135897883Sgibbs      keyseq[1] = 'e';
135997883Sgibbs      keyseq[2] = '\0';
136097883Sgibbs      return keyseq;
136197883Sgibbs    }
136297883Sgibbs#endif
136397883Sgibbs
136497883Sgibbs  /* RUBOUT is translated directly into \C-? */
136597883Sgibbs  if (key == RUBOUT)
136697883Sgibbs    {
136797883Sgibbs      keyname[0] = '\\';
136897883Sgibbs      keyname[1] = 'C';
136997883Sgibbs      keyname[2] = '-';
137097883Sgibbs      keyname[3] = '?';
137197883Sgibbs      keyname[4] = '\0';
137297883Sgibbs      return keyname;
137397883Sgibbs    }
137497883Sgibbs
137597883Sgibbs  i = 0;
137697883Sgibbs  /* Now add special prefixes needed for control characters.  This can
137797883Sgibbs     potentially change C. */
137897883Sgibbs  if (CTRL_CHAR (c))
137997883Sgibbs    {
138097883Sgibbs      keyname[i++] = '\\';
138197883Sgibbs      keyname[i++] = 'C';
138297883Sgibbs      keyname[i++] = '-';
138397883Sgibbs      c = _rl_to_lower (UNCTRL (c));
138497883Sgibbs    }
138597883Sgibbs
138697883Sgibbs  /* Now, if the character needs to be quoted with a backslash, do that. */
138797883Sgibbs  if (c == '\\' || c == '"')
138897883Sgibbs    keyname[i++] = '\\';
138997883Sgibbs
139097883Sgibbs  /* Now add the key, terminate the string, and return it. */
139197883Sgibbs  keyname[i++] = (char) c;
139297883Sgibbs  keyname[i] = '\0';
139397883Sgibbs
139497883Sgibbs  return keyname;
139597883Sgibbs}
139697883Sgibbs
139797883Sgibbs/* Return a NULL terminated array of strings which represent the key
139897883Sgibbs   sequences that are used to invoke FUNCTION in MAP. */
139997883Sgibbschar **
140097883Sgibbsrl_invoking_keyseqs_in_map (function, map)
140197883Sgibbs     Function *function;
140297883Sgibbs     Keymap map;
140397883Sgibbs{
140497883Sgibbs  register int key;
140597883Sgibbs  char **result;
140697883Sgibbs  int result_index, result_size;
140797883Sgibbs
140897883Sgibbs  result = (char **)NULL;
140997883Sgibbs  result_index = result_size = 0;
141097883Sgibbs
141197883Sgibbs  for (key = 0; key < KEYMAP_SIZE; key++)
141297883Sgibbs    {
141397883Sgibbs      switch (map[key].type)
141497883Sgibbs	{
141597883Sgibbs	case ISMACR:
141697883Sgibbs	  /* Macros match, if, and only if, the pointers are identical.
141797883Sgibbs	     Thus, they are treated exactly like functions in here. */
141897883Sgibbs	case ISFUNC:
141997883Sgibbs	  /* If the function in the keymap is the one we are looking for,
142097883Sgibbs	     then add the current KEY to the list of invoking keys. */
142197883Sgibbs	  if (map[key].function == function)
142297883Sgibbs	    {
142397883Sgibbs	      char *keyname;
142497883Sgibbs
142597883Sgibbs	      keyname = _rl_get_keyname (key);
142697883Sgibbs
142797883Sgibbs	      if (result_index + 2 > result_size)
142897883Sgibbs	        {
142997883Sgibbs	          result_size += 10;
143097883Sgibbs		  result = (char **) xrealloc (result, result_size * sizeof (char *));
143197883Sgibbs	        }
143297883Sgibbs
1433102681Sgibbs	      result[result_index++] = keyname;
1434102681Sgibbs	      result[result_index] = (char *)NULL;
1435102681Sgibbs	    }
1436102681Sgibbs	  break;
143797883Sgibbs
143897883Sgibbs	case ISKMAP:
143997883Sgibbs	  {
144097883Sgibbs	    char **seqs;
144197883Sgibbs	    register int i;
144297883Sgibbs
144397883Sgibbs	    /* Find the list of keyseqs in this map which have FUNCTION as
144497883Sgibbs	       their target.  Add the key sequences found to RESULT. */
144597883Sgibbs	    if (map[key].function)
1446102681Sgibbs	      seqs =
1447102681Sgibbs	        rl_invoking_keyseqs_in_map (function, FUNCTION_TO_KEYMAP (map, key));
1448102681Sgibbs	    else
144997883Sgibbs	      break;
145097883Sgibbs
145197883Sgibbs	    if (seqs == 0)
145297883Sgibbs	      break;
145397883Sgibbs
145497883Sgibbs	    for (i = 0; seqs[i]; i++)
145597883Sgibbs	      {
145697883Sgibbs		char *keyname = (char *)xmalloc (6 + strlen (seqs[i]));
145797883Sgibbs
1458102681Sgibbs		if (key == ESC)
1459102681Sgibbs		  sprintf (keyname, "\\e");
1460102681Sgibbs		else if (CTRL_CHAR (key))
1461102681Sgibbs		  sprintf (keyname, "\\C-%c", _rl_to_lower (UNCTRL (key)));
1462102681Sgibbs		else if (key == RUBOUT)
1463102681Sgibbs		  sprintf (keyname, "\\C-?");
1464102681Sgibbs		else if (key == '\\' || key == '"')
1465102681Sgibbs		  {
146697883Sgibbs		    keyname[0] = '\\';
146797883Sgibbs		    keyname[1] = (char) key;
146897883Sgibbs		    keyname[2] = '\0';
146997883Sgibbs		  }
147097883Sgibbs		else
147197883Sgibbs		  {
147297883Sgibbs		    keyname[0] = (char) key;
147397883Sgibbs		    keyname[1] = '\0';
147497883Sgibbs		  }
1475102681Sgibbs
1476102681Sgibbs		strcat (keyname, seqs[i]);
1477102681Sgibbs		free (seqs[i]);
1478102681Sgibbs
1479102681Sgibbs		if (result_index + 2 > result_size)
1480102681Sgibbs		  {
148197883Sgibbs		    result_size += 10;
148297883Sgibbs		    result = (char **) xrealloc (result, result_size * sizeof (char *));
148397883Sgibbs		  }
148497883Sgibbs
148597883Sgibbs		result[result_index++] = keyname;
148697883Sgibbs		result[result_index] = (char *)NULL;
148797883Sgibbs	      }
148897883Sgibbs
148997883Sgibbs	    free (seqs);
1490102681Sgibbs	  }
1491102681Sgibbs	  break;
1492102681Sgibbs	}
1493102681Sgibbs    }
1494102681Sgibbs  return (result);
149597883Sgibbs}
149697883Sgibbs
149797883Sgibbs/* Return a NULL terminated array of strings which represent the key
149897883Sgibbs   sequences that can be used to invoke FUNCTION using the current keymap. */
149997883Sgibbschar **
150097883Sgibbsrl_invoking_keyseqs (function)
150197883Sgibbs     Function *function;
150297883Sgibbs{
150397883Sgibbs  return (rl_invoking_keyseqs_in_map (function, _rl_keymap));
1504102681Sgibbs}
1505102681Sgibbs
1506102681Sgibbs/* Print all of the functions and their bindings to rl_outstream.  If
150797883Sgibbs   PRINT_READABLY is non-zero, then print the output in such a way
150897883Sgibbs   that it can be read back in. */
150997883Sgibbsvoid
151097883Sgibbsrl_function_dumper (print_readably)
151197883Sgibbs     int print_readably;
151297883Sgibbs{
151397883Sgibbs  register int i;
151497883Sgibbs  char **names;
151597883Sgibbs  char *name;
1516102681Sgibbs
1517102681Sgibbs  names = rl_funmap_names ();
1518102681Sgibbs
1519102681Sgibbs  fprintf (rl_outstream, "\n");
1520102681Sgibbs
1521102681Sgibbs  for (i = 0; name = names[i]; i++)
152297883Sgibbs    {
152397883Sgibbs      Function *function;
152497883Sgibbs      char **invokers;
152597883Sgibbs
152697883Sgibbs      function = rl_named_function (name);
152797883Sgibbs      invokers = rl_invoking_keyseqs_in_map (function, _rl_keymap);
152897883Sgibbs
152997883Sgibbs      if (print_readably)
153097883Sgibbs	{
1531102681Sgibbs	  if (!invokers)
1532102681Sgibbs	    fprintf (rl_outstream, "# %s (not bound)\n", name);
1533102681Sgibbs	  else
1534102681Sgibbs	    {
153597883Sgibbs	      register int j;
153697883Sgibbs
153797883Sgibbs	      for (j = 0; invokers[j]; j++)
153897883Sgibbs		{
153997883Sgibbs		  fprintf (rl_outstream, "\"%s\": %s\n",
154097883Sgibbs			   invokers[j], name);
154197883Sgibbs		  free (invokers[j]);
154297883Sgibbs		}
154397883Sgibbs
1544102681Sgibbs	      free (invokers);
1545102681Sgibbs	    }
1546102681Sgibbs	}
1547102681Sgibbs      else
1548102681Sgibbs	{
1549102681Sgibbs	  if (!invokers)
1550102681Sgibbs	    fprintf (rl_outstream, "%s is not bound to any keys\n",
155197883Sgibbs		     name);
155297883Sgibbs	  else
155397883Sgibbs	    {
155497883Sgibbs	      register int j;
155597883Sgibbs
155697883Sgibbs	      fprintf (rl_outstream, "%s can be found on ", name);
155797883Sgibbs
155897883Sgibbs	      for (j = 0; invokers[j] && j < 5; j++)
155997883Sgibbs		{
1560102681Sgibbs		  fprintf (rl_outstream, "\"%s\"%s", invokers[j],
1561102681Sgibbs			   invokers[j + 1] ? ", " : ".\n");
1562102681Sgibbs		}
156397883Sgibbs
156497883Sgibbs	      if (j == 5 && invokers[j])
156597883Sgibbs		fprintf (rl_outstream, "...\n");
156697883Sgibbs
156797883Sgibbs	      for (j = 0; invokers[j]; j++)
156897883Sgibbs		free (invokers[j]);
156997883Sgibbs
157097883Sgibbs	      free (invokers);
157197883Sgibbs	    }
157297883Sgibbs	}
157397883Sgibbs    }
157497883Sgibbs}
157597883Sgibbs
157697883Sgibbs/* Print all of the current functions and their bindings to
157797883Sgibbs   rl_outstream.  If an explicit argument is given, then print
157897883Sgibbs   the output in such a way that it can be read back in. */
157997883Sgibbsint
158097883Sgibbsrl_dump_functions (count, key)
158197883Sgibbs     int count, key;
158297883Sgibbs{
158397883Sgibbs  if (rl_dispatching)
158497883Sgibbs    fprintf (rl_outstream, "\r\n");
158597883Sgibbs  rl_function_dumper (rl_explicit_arg);
158697883Sgibbs  rl_on_new_line ();
158797883Sgibbs  return (0);
158897883Sgibbs}
158997883Sgibbs
159097883Sgibbsstatic void
159197883Sgibbs_rl_macro_dumper_internal (print_readably, map, prefix)
159297883Sgibbs     int print_readably;
159397883Sgibbs     Keymap map;
1594102681Sgibbs     char *prefix;
1595102681Sgibbs{
1596107441Sscottl  register int key;
1597107441Sscottl  char *keyname, *out;
1598107441Sscottl  int prefix_len;
1599107441Sscottl
1600107441Sscottl  for (key = 0; key < KEYMAP_SIZE; key++)
1601107441Sscottl    {
1602107441Sscottl      switch (map[key].type)
1603107441Sscottl	{
1604107441Sscottl	case ISMACR:
1605107441Sscottl	  keyname = _rl_get_keyname (key);
1606107441Sscottl#if 0
1607107441Sscottl	  out = (char *)map[key].function;
1608107441Sscottl#else
1609107441Sscottl	  out = _rl_untranslate_macro_value ((char *)map[key].function);
161097883Sgibbs#endif
161197883Sgibbs	  if (print_readably)
1612107441Sscottl	    fprintf (rl_outstream, "\"%s%s\": \"%s\"\n", prefix ? prefix : "",
1613107441Sscottl						         keyname,
161497883Sgibbs						         out ? out : "");
161597883Sgibbs	  else
161697883Sgibbs	    fprintf (rl_outstream, "%s%s outputs %s\n", prefix ? prefix : "",
161797883Sgibbs							keyname,
161897883Sgibbs							out ? out : "");
161997883Sgibbs	  free (keyname);
162097883Sgibbs#if 1
162197883Sgibbs	  free (out);
162297883Sgibbs#endif
162397883Sgibbs	  break;
162497883Sgibbs	case ISFUNC:
162597883Sgibbs	  break;
162697883Sgibbs	case ISKMAP:
162797883Sgibbs	  prefix_len = prefix ? strlen (prefix) : 0;
162897883Sgibbs	  if (key == ESC)
162997883Sgibbs	    {
163097883Sgibbs	      keyname = xmalloc (3 + prefix_len);
163197883Sgibbs	      if (prefix)
1632102681Sgibbs		strcpy (keyname, prefix);
1633102681Sgibbs	      keyname[prefix_len] = '\\';
1634102681Sgibbs	      keyname[prefix_len + 1] = 'e';
1635102681Sgibbs	      keyname[prefix_len + 2] = '\0';
1636102681Sgibbs	    }
1637102681Sgibbs	  else
1638102681Sgibbs	    {
1639102681Sgibbs	      keyname = _rl_get_keyname (key);
164097883Sgibbs	      if (prefix)
164197883Sgibbs		{
164297883Sgibbs		  out = xmalloc (strlen (keyname) + prefix_len + 1);
1643102681Sgibbs		  strcpy (out, prefix);
1644102681Sgibbs		  strcpy (out + prefix_len, keyname);
1645102681Sgibbs		  free (keyname);
1646102681Sgibbs		  keyname = out;
1647102681Sgibbs		}
1648102681Sgibbs	    }
1649102681Sgibbs
1650102681Sgibbs	  _rl_macro_dumper_internal (print_readably, FUNCTION_TO_KEYMAP (map, key), keyname);
1651102681Sgibbs	  free (keyname);
1652102681Sgibbs	  break;
165397883Sgibbs	}
165497883Sgibbs    }
165597883Sgibbs}
165697883Sgibbs
165797883Sgibbsvoid
165897883Sgibbsrl_macro_dumper (print_readably)
1659102681Sgibbs     int print_readably;
1660102681Sgibbs{
1661102681Sgibbs  _rl_macro_dumper_internal (print_readably, _rl_keymap, (char *)NULL);
1662102681Sgibbs}
1663102681Sgibbs
1664102681Sgibbsint
1665102681Sgibbsrl_dump_macros (count, key)
1666102681Sgibbs     int count, key;
166797883Sgibbs{
166897883Sgibbs  if (rl_dispatching)
166997883Sgibbs    fprintf (rl_outstream, "\r\n");
1670102681Sgibbs  rl_macro_dumper (rl_explicit_arg);
1671102681Sgibbs  rl_on_new_line ();
1672102681Sgibbs  return (0);
1673102681Sgibbs}
1674102681Sgibbs
1675102681Sgibbsvoid
1676102681Sgibbsrl_variable_dumper (print_readably)
1677102681Sgibbs     int print_readably;
1678102681Sgibbs{
1679102681Sgibbs  int i;
168097883Sgibbs  char *kname;
168197883Sgibbs
168297883Sgibbs  for (i = 0; boolean_varlist[i].name; i++)
168397883Sgibbs    {
168497883Sgibbs      if (print_readably)
168597883Sgibbs        fprintf (rl_outstream, "set %s %s\n", boolean_varlist[i].name,
168697883Sgibbs			       *boolean_varlist[i].value ? "on" : "off");
168797883Sgibbs      else
168897883Sgibbs        fprintf (rl_outstream, "%s is set to `%s'\n", boolean_varlist[i].name,
168997883Sgibbs			       *boolean_varlist[i].value ? "on" : "off");
169097883Sgibbs    }
169197883Sgibbs
169297883Sgibbs  /* bell-style */
169397883Sgibbs  switch (_rl_bell_preference)
169497883Sgibbs    {
169597883Sgibbs    case NO_BELL: kname = "none"; break;
169697883Sgibbs    case VISIBLE_BELL: kname = "visible"; break;
169797883Sgibbs    case AUDIBLE_BELL:
169897883Sgibbs    default: kname = "audible"; break;
169997883Sgibbs    }
1700102681Sgibbs  if (print_readably)
1701102681Sgibbs    fprintf (rl_outstream, "set bell-style %s\n", kname);
1702102681Sgibbs  else
1703102681Sgibbs    fprintf (rl_outstream, "bell-style is set to `%s'\n", kname);
1704102681Sgibbs
1705102681Sgibbs  /* comment-begin */
1706102681Sgibbs  if (print_readably)
1707102681Sgibbs    fprintf (rl_outstream, "set comment-begin %s\n", _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
170897883Sgibbs  else
170997883Sgibbs    fprintf (rl_outstream, "comment-begin is set to `%s'\n", _rl_comment_begin ? _rl_comment_begin : "");
171097883Sgibbs
171197883Sgibbs  /* completion-query-items */
171297883Sgibbs  if (print_readably)
171397883Sgibbs    fprintf (rl_outstream, "set completion-query-items %d\n", rl_completion_query_items);
171497883Sgibbs  else
171597883Sgibbs    fprintf (rl_outstream, "completion-query-items is set to `%d'\n", rl_completion_query_items);
171697883Sgibbs
171797883Sgibbs  /* editing-mode */
171897883Sgibbs  if (print_readably)
171997883Sgibbs    fprintf (rl_outstream, "set editing-mode %s\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi");
172097883Sgibbs  else
172197883Sgibbs    fprintf (rl_outstream, "editing-mode is set to `%s'\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi");
172297883Sgibbs
172397883Sgibbs  /* keymap */
172497883Sgibbs  kname = rl_get_keymap_name (_rl_keymap);
172597883Sgibbs  if (kname == 0)
172697883Sgibbs    kname = rl_get_keymap_name_from_edit_mode ();
172797883Sgibbs  if (print_readably)
172897883Sgibbs    fprintf (rl_outstream, "set keymap %s\n", kname ? kname : "none");
172997883Sgibbs  else
173097883Sgibbs    fprintf (rl_outstream, "keymap is set to `%s'\n", kname ? kname : "none");
173197883Sgibbs}
173297883Sgibbs
173397883Sgibbs/* Print all of the current variables and their values to
173497883Sgibbs   rl_outstream.  If an explicit argument is given, then print
173597883Sgibbs   the output in such a way that it can be read back in. */
173697883Sgibbsint
173797883Sgibbsrl_dump_variables (count, key)
173897883Sgibbs     int count, key;
173997883Sgibbs{
174097883Sgibbs  if (rl_dispatching)
174197883Sgibbs    fprintf (rl_outstream, "\r\n");
174297883Sgibbs  rl_variable_dumper (rl_explicit_arg);
174397883Sgibbs  rl_on_new_line ();
174497883Sgibbs  return (0);
174597883Sgibbs}
1746102681Sgibbs
1747102681Sgibbs/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. */
174897883Sgibbsvoid
174997883Sgibbs_rl_bind_if_unbound (keyseq, default_func)
175097883Sgibbs     char *keyseq;
175197883Sgibbs     Function *default_func;
175297883Sgibbs{
175397883Sgibbs  Function *func;
175497883Sgibbs
175597883Sgibbs  if (keyseq)
175697883Sgibbs    {
175797883Sgibbs      func = rl_function_of_keyseq (keyseq, _rl_keymap, (int *)NULL);
175897883Sgibbs      if (!func || func == rl_do_lowercase_version)
1759102681Sgibbs	rl_set_key (keyseq, default_func, _rl_keymap);
1760102681Sgibbs    }
176197883Sgibbs}
176297883Sgibbs
176397883Sgibbs/* Return non-zero if any members of ARRAY are a substring in STRING. */
176497883Sgibbsstatic int
176597883Sgibbssubstring_member_of_array (string, array)
176697883Sgibbs     char *string, **array;
176797883Sgibbs{
176897883Sgibbs  while (*array)
176997883Sgibbs    {
177097883Sgibbs      if (_rl_strindex (string, *array))
177197883Sgibbs	return (1);
1772102681Sgibbs      array++;
1773102681Sgibbs    }
1774102681Sgibbs  return (0);
1775102681Sgibbs}
1776102681Sgibbs