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