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