Import GNU Readline 8.1
[deliverable/binutils-gdb.git] / readline / readline / bind.c
CommitLineData
d60d9f65
SS
1/* bind.c -- key binding and startup file support for the readline library. */
2
b4f26d54 3/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
d60d9f65 4
cc88a640
JK
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.
d60d9f65 7
cc88a640
JK
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
d60d9f65
SS
11 (at your option) any later version.
12
cc88a640
JK
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
d60d9f65
SS
16 GNU General Public License for more details.
17
cc88a640
JK
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*/
5bdf8622 21
d60d9f65
SS
22#define READLINE_LIBRARY
23
5bdf8622
DJ
24#if defined (__TANDEM)
25# include <floss.h>
26#endif
27
d60d9f65
SS
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
d60d9f65
SS
49#include <errno.h>
50
51#if !defined (errno)
52extern 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
1b17e766
EZ
64#include "rlprivate.h"
65#include "rlshell.h"
66#include "xmalloc.h"
67
d60d9f65
SS
68#if !defined (strchr) && !defined (__STDC__)
69extern char *strchr (), *strrchr ();
70#endif /* !strchr && !__STDC__ */
71
d60d9f65
SS
72/* Variables exported by this file. */
73Keymap rl_binding_keymap;
74
775e241e
TT
75static int _rl_skip_to_delim PARAMS((char *, int, int));
76
77#if defined (USE_VARARGS) && defined (PREFER_STDARG)
78static void _rl_init_file_error (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
79#else
80static void _rl_init_file_error ();
81#endif
82
cb41b9e7
TT
83static rl_command_func_t *_rl_function_of_keyseq_internal PARAMS((const char *, size_t, Keymap, int *));
84
9255ee31 85static char *_rl_read_file PARAMS((char *, size_t *));
9255ee31
EZ
86static int _rl_read_init_file PARAMS((const char *, int));
87static int glean_key_from_name PARAMS((char *));
775e241e 88
5bdf8622 89static int find_boolean_var PARAMS((const char *));
775e241e 90static int find_string_var PARAMS((const char *));
5bdf8622 91
cb41b9e7
TT
92static const char *boolean_varname PARAMS((int));
93static const char *string_varname PARAMS((int));
94
5bdf8622 95static char *_rl_get_string_variable_value PARAMS((const char *));
cc88a640 96static int substring_member_of_array PARAMS((const char *, const char * const *));
d60d9f65 97
cb41b9e7
TT
98static int _rl_get_keymap_by_name PARAMS((const char *));
99static int _rl_get_keymap_by_map PARAMS((Keymap));
100
1b17e766 101static int currently_reading_init_file;
d60d9f65 102
1b17e766
EZ
103/* used only in this file */
104static int _rl_prefer_visible_bell = 1;
d60d9f65 105
cb41b9e7
TT
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
d60d9f65
SS
116/* **************************************************************** */
117/* */
118/* Binding keys */
119/* */
120/* **************************************************************** */
121
9255ee31 122/* rl_add_defun (char *name, rl_command_func_t *function, int key)
d60d9f65
SS
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. */
125int
cb41b9e7 126rl_add_defun (const char *name, rl_command_func_t *function, int key)
d60d9f65
SS
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. */
135int
cb41b9e7 136rl_bind_key (int key, rl_command_func_t *function)
d60d9f65 137{
b4f26d54 138 char keyseq[4];
775e241e
TT
139 int l;
140
b4f26d54 141 if (key < 0 || key > largest_char)
d60d9f65
SS
142 return (key);
143
b4f26d54 144 /* Want to make this a multi-character key sequence with an ESC prefix */
d60d9f65
SS
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 }
b4f26d54
TT
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;
d60d9f65
SS
165 }
166
775e241e
TT
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
b4f26d54
TT
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. */
775e241e
TT
171 if (_rl_keymap[key].type != ISKMAP)
172 {
b4f26d54
TT
173 if (_rl_keymap[key].type == ISMACR)
174 xfree ((char *)_rl_keymap[key].function);
775e241e
TT
175 _rl_keymap[key].type = ISFUNC;
176 _rl_keymap[key].function = function;
177 }
178 else
179 {
180 l = 0;
b4f26d54 181bind_keyseq:
775e241e 182 if (key == '\\')
b4f26d54
TT
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;
775e241e
TT
194 keyseq[l] = '\0';
195 rl_bind_keyseq (keyseq, function);
196 }
d60d9f65
SS
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. */
203int
cb41b9e7 204rl_bind_key_in_map (int key, rl_command_func_t *function, Keymap map)
d60d9f65
SS
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
5bdf8622 216/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right
cb41b9e7 217 now, this is always used to attempt to bind the arrow keys. */
5bdf8622 218int
cb41b9e7 219rl_bind_key_if_unbound_in_map (int key, rl_command_func_t *default_func, Keymap kmap)
5bdf8622 220{
cb41b9e7 221 char *keyseq;
5bdf8622 222
cb41b9e7 223 keyseq = rl_untranslate_keyseq ((unsigned char)key);
5bdf8622
DJ
224 return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap));
225}
226
227int
cb41b9e7 228rl_bind_key_if_unbound (int key, rl_command_func_t *default_func)
5bdf8622 229{
cb41b9e7 230 char *keyseq;
5bdf8622 231
cb41b9e7 232 keyseq = rl_untranslate_keyseq ((unsigned char)key);
5bdf8622
DJ
233 return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap));
234}
235
d60d9f65 236/* Make KEY do nothing in the currently selected keymap.
cb41b9e7
TT
237 Returns non-zero in case of error. This is not the same as self-insert;
238 this makes it a dead key. */
d60d9f65 239int
cb41b9e7 240rl_unbind_key (int key)
d60d9f65 241{
9255ee31 242 return (rl_bind_key (key, (rl_command_func_t *)NULL));
d60d9f65
SS
243}
244
cb41b9e7 245/* Make KEY do nothing in MAP. Returns non-zero in case of error. */
d60d9f65 246int
cb41b9e7 247rl_unbind_key_in_map (int key, Keymap map)
d60d9f65 248{
9255ee31 249 return (rl_bind_key_in_map (key, (rl_command_func_t *)NULL, map));
d60d9f65
SS
250}
251
252/* Unbind all keys bound to FUNCTION in MAP. */
253int
cb41b9e7 254rl_unbind_function_in_map (rl_command_func_t *func, Keymap map)
d60d9f65 255{
c862e87b 256 register int i, rval;
d60d9f65 257
c862e87b 258 for (i = rval = 0; i < KEYMAP_SIZE; i++)
d60d9f65
SS
259 {
260 if (map[i].type == ISFUNC && map[i].function == func)
c862e87b 261 {
9255ee31 262 map[i].function = (rl_command_func_t *)NULL;
c862e87b
JM
263 rval = 1;
264 }
b4f26d54
TT
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 }
d60d9f65 272 }
c862e87b 273 return rval;
d60d9f65
SS
274}
275
cb41b9e7 276/* Unbind all keys bound to COMMAND, which is a bindable command name, in MAP */
d60d9f65 277int
cb41b9e7 278rl_unbind_command_in_map (const char *command, Keymap map)
d60d9f65 279{
9255ee31 280 rl_command_func_t *func;
d60d9f65
SS
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
5bdf8622
DJ
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. */
291int
cb41b9e7 292rl_bind_keyseq (const char *keyseq, rl_command_func_t *function)
5bdf8622
DJ
293{
294 return (rl_generic_bind (ISFUNC, keyseq, (char *)function, _rl_keymap));
295}
296
d60d9f65
SS
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. */
300int
cb41b9e7 301rl_bind_keyseq_in_map (const char *keyseq, rl_command_func_t *function, Keymap map)
5bdf8622
DJ
302{
303 return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));
304}
305
306/* Backwards compatibility; equivalent to rl_bind_keyseq_in_map() */
307int
cb41b9e7 308rl_set_key (const char *keyseq, rl_command_func_t *function, Keymap map)
d60d9f65
SS
309{
310 return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));
311}
312
5bdf8622
DJ
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. */
316int
cb41b9e7 317rl_bind_keyseq_if_unbound_in_map (const char *keyseq, rl_command_func_t *default_func, Keymap kmap)
5bdf8622
DJ
318{
319 rl_command_func_t *func;
cb41b9e7
TT
320 char *keys;
321 int keys_len;
5bdf8622
DJ
322
323 if (keyseq)
324 {
cb41b9e7
TT
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);
5bdf8622
DJ
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
347int
cb41b9e7 348rl_bind_keyseq_if_unbound (const char *keyseq, rl_command_func_t *default_func)
5bdf8622
DJ
349{
350 return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap));
351}
352
d60d9f65
SS
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. */
356int
cb41b9e7 357rl_macro_bind (const char *keyseq, const char *macro, Keymap map)
d60d9f65
SS
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 {
cc88a640 366 xfree (macro_keys);
d60d9f65
SS
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. */
378int
cb41b9e7 379rl_generic_bind (int type, const char *keyseq, char *data, Keymap map)
d60d9f65
SS
380{
381 char *keys;
b4f26d54 382 int keys_len, prevkey, ic;
d60d9f65 383 register int i;
9255ee31 384 KEYMAP_ENTRY k;
cb41b9e7 385 Keymap prevmap;
9255ee31
EZ
386
387 k.function = 0;
d60d9f65
SS
388
389 /* If no keys to bind to, exit right away. */
5bdf8622 390 if (keyseq == 0 || *keyseq == 0)
d60d9f65
SS
391 {
392 if (type == ISMACR)
cc88a640 393 xfree (data);
d60d9f65
SS
394 return -1;
395 }
396
9255ee31 397 keys = (char *)xmalloc (1 + (2 * strlen (keyseq)));
d60d9f65
SS
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 {
cc88a640 404 xfree (keys);
d60d9f65
SS
405 return -1;
406 }
407
cb41b9e7
TT
408 prevmap = map;
409 prevkey = keys[0];
410
d60d9f65
SS
411 /* Bind keys, making new keymaps as necessary. */
412 for (i = 0; i < keys_len; i++)
413 {
9255ee31 414 unsigned char uc = keys[i];
9255ee31 415
cb41b9e7
TT
416 if (i > 0)
417 prevkey = ic;
418
9255ee31
EZ
419 ic = uc;
420 if (ic < 0 || ic >= KEYMAP_SIZE)
cc88a640
JK
421 {
422 xfree (keys);
423 return -1;
424 }
d60d9f65 425
b4f26d54
TT
426 /* We now rely on rl_translate_keyseq to do this conversion, so this
427 check is superfluous. */
428#if 0
5bdf8622 429 if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
d60d9f65
SS
430 {
431 ic = UNMETA (ic);
432 if (map[ESC].type == ISKMAP)
cb41b9e7
TT
433 {
434 prevmap = map;
435 map = FUNCTION_TO_KEYMAP (map, ESC);
436 }
d60d9f65 437 }
b4f26d54 438#endif
d60d9f65
SS
439
440 if ((i + 1) < keys_len)
441 {
442 if (map[ic].type != ISKMAP)
443 {
9255ee31
EZ
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];
d60d9f65
SS
452
453 map[ic].type = ISKMAP;
454 map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap());
455 }
cb41b9e7 456 prevmap = map;
d60d9f65 457 map = FUNCTION_TO_KEYMAP (map, ic);
9255ee31
EZ
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. */
5af408ce 464 if (k.function && ((k.type == ISFUNC && k.function != rl_do_lowercase_version) || k.type == ISMACR))
9255ee31
EZ
465 {
466 map[ANYOTHERKEY] = k;
467 k.function = 0;
468 }
d60d9f65
SS
469 }
470 else
471 {
b4f26d54 472 if (map[ic].type == ISKMAP)
9255ee31 473 {
cb41b9e7 474 prevmap = map;
9255ee31
EZ
475 map = FUNCTION_TO_KEYMAP (map, ic);
476 ic = ANYOTHERKEY;
cc88a640
JK
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;
9255ee31 484 }
b4f26d54
TT
485 if (map[ic].type == ISMACR)
486 xfree ((char *)map[ic].function);
d60d9f65
SS
487
488 map[ic].function = KEYMAP_TO_FUNCTION (data);
489 map[ic].type = type;
490 }
491
492 rl_binding_keymap = map;
cb41b9e7 493
d60d9f65 494 }
cb41b9e7
TT
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
cc88a640 515 xfree (keys);
d60d9f65
SS
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. */
522int
cb41b9e7 523rl_translate_keyseq (const char *seq, char *array, int *len)
d60d9f65 524{
b4f26d54
TT
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;
d60d9f65 531
b4f26d54
TT
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++)
d60d9f65 537 {
b4f26d54
TT
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')
d60d9f65
SS
543 {
544 c = seq[++i];
545
b4f26d54
TT
546 /* Handle \C- and \M- prefixes. */
547 if (c == 'C' && seq[i + 1] == '-')
cb41b9e7 548 {
b4f26d54
TT
549 i++;
550 has_control = 1;
551 continue;
cb41b9e7 552 }
b4f26d54 553 else if (c == 'M' && seq[i + 1] == '-')
d60d9f65 554 {
b4f26d54
TT
555 i++;
556 has_meta = 1;
d60d9f65
SS
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':
b4f26d54 567 c = '\007';
d60d9f65
SS
568 break;
569 case 'b':
b4f26d54 570 c = '\b';
d60d9f65
SS
571 break;
572 case 'd':
b4f26d54 573 c = RUBOUT; /* readline-specific */
d60d9f65
SS
574 break;
575 case 'e':
b4f26d54 576 c = ESC;
d60d9f65
SS
577 break;
578 case 'f':
b4f26d54 579 c = '\f';
d60d9f65
SS
580 break;
581 case 'n':
b4f26d54 582 c = NEWLINE;
d60d9f65
SS
583 break;
584 case 'r':
b4f26d54 585 c = RETURN;
d60d9f65
SS
586 break;
587 case 't':
b4f26d54 588 c = TAB;
d60d9f65
SS
589 break;
590 case 'v':
b4f26d54 591 c = 0x0B;
d60d9f65
SS
592 break;
593 case '\\':
b4f26d54 594 c = '\\';
d60d9f65
SS
595 break;
596 case '0': case '1': case '2': case '3':
597 case '4': case '5': case '6': case '7':
598 i++;
775e241e 599 for (temp = 2, c -= '0'; ISOCTAL ((unsigned char)seq[i]) && temp--; i++)
d60d9f65
SS
600 c = (c * 8) + OCTVALUE (seq[i]);
601 i--; /* auto-increment in for loop */
b4f26d54 602 c &= largest_char;
d60d9f65
SS
603 break;
604 case 'x':
605 i++;
9255ee31 606 for (temp = 2, c = 0; ISXDIGIT ((unsigned char)seq[i]) && temp--; i++)
d60d9f65 607 c = (c * 16) + HEXVALUE (seq[i]);
9255ee31 608 if (temp == 2)
d60d9f65
SS
609 c = 'x';
610 i--; /* auto-increment in for loop */
b4f26d54 611 c &= largest_char;
d60d9f65
SS
612 break;
613 default: /* backslashes before non-special chars just add the char */
b4f26d54 614 c &= largest_char;
d60d9f65
SS
615 break; /* the backslash is stripped */
616 }
d60d9f65
SS
617 }
618
b4f26d54
TT
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;
d60d9f65
SS
645 }
646
647 *len = l;
648 array[l] = '\0';
649 return (0);
650}
651
775e241e 652static int
cb41b9e7 653_rl_isescape (int c)
775e241e
TT
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
668static int
cb41b9e7 669_rl_escchar (int c)
775e241e
TT
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
d60d9f65 684char *
cb41b9e7 685rl_untranslate_keyseq (int seq)
d60d9f65
SS
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 }
cc88a640
JK
699 else if (c == ESC)
700 {
701 kseq[i++] = '\\';
702 c = 'e';
703 }
d60d9f65
SS
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
775e241e 734char *
cb41b9e7 735_rl_untranslate_macro_value (char *seq, int use_escapes)
d60d9f65
SS
736{
737 char *ret, *r, *s;
738 int c;
739
9255ee31 740 r = ret = (char *)xmalloc (7 * strlen (seq) + 1);
d60d9f65
SS
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 }
cc88a640
JK
751 else if (c == ESC)
752 {
753 *r++ = '\\';
754 c = 'e';
755 }
756 else if (CTRL_CHAR (c))
d60d9f65
SS
757 {
758 *r++ = '\\';
775e241e
TT
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 }
d60d9f65
SS
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
b4f26d54 792 is returned. The string match is case-insensitive. */
9255ee31 793rl_command_func_t *
cb41b9e7 794rl_named_function (const char *string)
d60d9f65
SS
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);
9255ee31 803 return ((rl_command_func_t *)NULL);
d60d9f65
SS
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). */
cb41b9e7
TT
811static rl_command_func_t *
812_rl_function_of_keyseq_internal (const char *keyseq, size_t len, Keymap map, int *type)
d60d9f65
SS
813{
814 register int i;
815
cc88a640 816 if (map == 0)
d60d9f65
SS
817 map = _rl_keymap;
818
cb41b9e7 819 for (i = 0; keyseq && i < len; i++)
d60d9f65 820 {
9255ee31 821 unsigned char ic = keyseq[i];
d60d9f65
SS
822
823 if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
824 {
cc88a640
JK
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
d60d9f65
SS
833 {
834 if (type)
835 *type = map[ESC].type;
836
837 return (map[ESC].function);
838 }
d60d9f65
SS
839 }
840
841 if (map[ic].type == ISKMAP)
842 {
843 /* If this is the last key in the key sequence, return the
844 map. */
b4f26d54 845 if (i + 1 == len)
d60d9f65
SS
846 {
847 if (type)
848 *type = ISKMAP;
849
850 return (map[ic].function);
851 }
852 else
853 map = FUNCTION_TO_KEYMAP (map, ic);
854 }
cc88a640
JK
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. */
b4f26d54 858 else if (map[ic].type != ISKMAP && i+1 < len)
cc88a640 859 return ((rl_command_func_t *)NULL);
b4f26d54 860 else /* map[ic].type != ISKMAP && i+1 == len */
d60d9f65
SS
861 {
862 if (type)
863 *type = map[ic].type;
864
865 return (map[ic].function);
866 }
867 }
9255ee31 868 return ((rl_command_func_t *) NULL);
d60d9f65
SS
869}
870
cb41b9e7
TT
871rl_command_func_t *
872rl_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
877rl_command_func_t *
878rl_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
d60d9f65
SS
883/* The last key bindings file read. */
884static char *last_readline_init_file = (char *)NULL;
885
886/* The file we're currently reading key bindings from. */
9255ee31 887static const char *current_readline_init_file;
d60d9f65
SS
888static int current_readline_init_include_level;
889static 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. */
894static char *
cb41b9e7 895_rl_read_file (char *filename, size_t *sizep)
d60d9f65
SS
896{
897 struct stat finfo;
898 size_t file_size;
899 char *buffer;
900 int i, file;
901
cb41b9e7
TT
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 }
d60d9f65
SS
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
c862e87b 928 if (i < 0)
d60d9f65 929 {
cc88a640 930 xfree (buffer);
d60d9f65
SS
931 return ((char *)NULL);
932 }
933
cc88a640
JK
934 RL_CHECK_SIGNALS ();
935
1b17e766
EZ
936 buffer[i] = '\0';
937 if (sizep)
938 *sizep = i;
1b17e766 939
d60d9f65
SS
940 return (buffer);
941}
942
943/* Re-read the current keybindings file. */
944int
cb41b9e7 945rl_re_read_init_file (int count, int ignore)
d60d9f65
SS
946{
947 int r;
9255ee31 948 r = rl_read_init_file ((const char *)NULL);
d60d9f65
SS
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
cc88a640 958 4. /etc/inputrc
d60d9f65
SS
959 If the file existed and could be opened and read, 0 is returned,
960 otherwise errno is returned. */
961int
cb41b9e7 962rl_read_init_file (const char *filename)
d60d9f65
SS
963{
964 /* Default the filename. */
965 if (filename == 0)
cc88a640
JK
966 filename = last_readline_init_file;
967 if (filename == 0)
968 filename = sh_get_env_value ("INPUTRC");
969 if (filename == 0 || *filename == 0)
d60d9f65 970 {
cc88a640
JK
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;
d60d9f65
SS
976 }
977
1b17e766
EZ
978#if defined (__MSDOS__)
979 if (_rl_read_init_file (filename, 0) == 0)
980 return 0;
981 filename = "~/_inputrc";
a27688aa 982#endif
d60d9f65
SS
983 return (_rl_read_init_file (filename, 0));
984}
985
986static int
cb41b9e7 987_rl_read_init_file (const char *filename, int include_level)
d60d9f65
SS
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);
cc88a640 998 xfree (openname);
c862e87b 999
cc88a640 1000 RL_CHECK_SIGNALS ();
d60d9f65
SS
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
1b17e766
EZ
1010 currently_reading_init_file = 1;
1011
d60d9f65
SS
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
9255ee31 1022#if defined (__CYGWIN__)
1b17e766
EZ
1023 /* ``Be liberal in what you accept.'' */
1024 if (line[i] == '\n' && line[i-1] == '\r')
1025 line[i - 1] = '\0';
1026#endif
1027
d60d9f65
SS
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
cc88a640 1047 xfree (buffer);
1b17e766 1048 currently_reading_init_file = 0;
d60d9f65
SS
1049 return (0);
1050}
1051
1052static void
775e241e
TT
1053#if defined (PREFER_STDARG)
1054_rl_init_file_error (const char *format, ...)
1055#else
1056_rl_init_file_error (va_alist)
1057 va_dcl
1058#endif
d60d9f65 1059{
775e241e
TT
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: ");
1b17e766 1073 if (currently_reading_init_file)
775e241e
TT
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);
d60d9f65
SS
1082}
1083
cb41b9e7
TT
1084/* **************************************************************** */
1085/* */
1086/* Parser Helper Functions */
1087/* */
1088/* **************************************************************** */
1089
1090static int
1091parse_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
d60d9f65
SS
1140/* **************************************************************** */
1141/* */
1142/* Parser Directives */
1143/* */
1144/* **************************************************************** */
1145
9255ee31
EZ
1146typedef int _rl_parser_func_t PARAMS((char *));
1147
1148/* Things that mean `Control'. */
cc88a640 1149const char * const _rl_possible_control_prefixes[] = {
9255ee31
EZ
1150 "Control-", "C-", "CTRL-", (const char *)NULL
1151};
1152
cc88a640 1153const char * const _rl_possible_meta_prefixes[] = {
9255ee31
EZ
1154 "Meta", "M-", (const char *)NULL
1155};
1156
d60d9f65
SS
1157/* Conditionals. */
1158
1159/* Calling programs set this to have their argv[0]. */
9255ee31 1160const char *rl_readline_name = "other";
d60d9f65
SS
1161
1162/* Stack of previous values of parsing_conditionalized_out. */
1163static unsigned char *if_stack = (unsigned char *)NULL;
1164static int if_stack_depth;
1165static int if_stack_size;
1166
1167/* Push _rl_parsing_conditionalized_out, and set parser state based
1168 on ARGS. */
1169static int
cb41b9e7 1170parser_if (char *args)
d60d9f65 1171{
cb41b9e7
TT
1172 int i, llen, boolvar, strvar;
1173
1174 boolvar = strvar = -1;
d60d9f65
SS
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
cb41b9e7
TT
1191 llen = strlen (args);
1192
d60d9f65
SS
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);
cc88a640 1218 xfree (tname);
d60d9f65
SS
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 */
cb41b9e7
TT
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 }
d60d9f65
SS
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;
cb41b9e7
TT
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 }
d60d9f65
SS
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. */
1373static int
cb41b9e7 1374parser_else (char *args)
d60d9f65
SS
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
5bdf8622 1384#if 0
d60d9f65
SS
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++)
5bdf8622
DJ
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
d60d9f65
SS
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. */
1403static int
cb41b9e7 1404parser_endif (char *args)
d60d9f65
SS
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
1413static int
cb41b9e7 1414parser_include (char *args)
d60d9f65 1415{
9255ee31
EZ
1416 const char *old_init_file;
1417 char *e;
d60d9f65
SS
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';
9255ee31 1430 r = _rl_read_init_file ((const char *)args, old_include_level + 1);
d60d9f65
SS
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. */
cc88a640
JK
1440static const struct {
1441 const char * const name;
9255ee31 1442 _rl_parser_func_t *function;
d60d9f65
SS
1443} parser_directives [] = {
1444 { "if", parser_if },
1445 { "endif", parser_endif },
1446 { "else", parser_else },
1447 { "include", parser_include },
9255ee31 1448 { (char *)0x0, (_rl_parser_func_t *)0x0 }
d60d9f65
SS
1449};
1450
1451/* Handle a parser directive. STATEMENT is the line of the directive
1452 without any leading `$'. */
1453static int
cb41b9e7 1454handle_parser_directive (char *statement)
d60d9f65
SS
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 */
775e241e 1484 _rl_init_file_error ("%s: unknown parser directive", directive);
d60d9f65
SS
1485 return (1);
1486}
1487
775e241e
TT
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. */
1490static int
cb41b9e7 1491_rl_skip_to_delim (char *string, int start, int delim)
775e241e
TT
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
d60d9f65
SS
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. */
1522int
cb41b9e7 1523rl_parse_and_bind (char *string)
d60d9f65
SS
1524{
1525 char *funname, *kname;
1526 register int c, i;
775e241e 1527 int key, equivalency, foundmod, foundsep;
d60d9f65
SS
1528
1529 while (string && whitespace (*string))
1530 string++;
1531
775e241e 1532 if (string == 0 || *string == 0 || *string == '#')
d60d9f65
SS
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 {
775e241e 1552 i = _rl_skip_to_delim (string, 1, '"');
5836a818 1553
d60d9f65
SS
1554 /* If we didn't find a closing quote, abort the line. */
1555 if (string[i] == '\0')
1556 {
775e241e 1557 _rl_init_file_error ("%s: no closing `\"' in key binding", string);
d60d9f65
SS
1558 return 1;
1559 }
775e241e
TT
1560 else
1561 i++; /* skip past closing double quote */
d60d9f65
SS
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
cb41b9e7
TT
1567 if (i == 0)
1568 {
1569 _rl_init_file_error ("`%s': invalid key binding: missing key sequence", string);
1570 return 1;
1571 }
1572
d60d9f65
SS
1573 equivalency = (c == ':' && string[i + 1] == '=');
1574
775e241e
TT
1575 foundsep = c != 0;
1576
d60d9f65
SS
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 {
5bdf8622 1588 char *var, *value, *e;
775e241e 1589 int s;
d60d9f65 1590
5bdf8622 1591 var = string + i;
d60d9f65
SS
1592 /* Make VAR point to start of variable name. */
1593 while (*var && whitespace (*var)) var++;
1594
9255ee31 1595 /* Make VALUE point to start of value string. */
d60d9f65 1596 value = var;
775e241e 1597 while (*value && whitespace (*value) == 0) value++;
d60d9f65
SS
1598 if (*value)
1599 *value++ = '\0';
1600 while (*value && whitespace (*value)) value++;
1601
775e241e
TT
1602 /* Strip trailing whitespace from values of boolean variables. */
1603 if (find_boolean_var (var) >= 0)
5bdf8622 1604 {
b4f26d54
TT
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 */
5bdf8622 1610 }
775e241e
TT
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
b4f26d54
TT
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 }
775e241e 1631 }
b4f26d54
TT
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
d60d9f65
SS
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 {
775e241e
TT
1659 i = _rl_skip_to_delim (string, i+1, *funname);
1660 if (string[i])
d60d9f65 1661 i++;
cb41b9e7
TT
1662 else
1663 {
1664 _rl_init_file_error ("`%s': missing closing quote for macro", funname);
1665 return 1;
1666 }
d60d9f65
SS
1667 }
1668
1669 /* Advance to the end of the string. */
775e241e 1670 for (; string[i] && whitespace (string[i]) == 0; i++);
d60d9f65
SS
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
775e241e
TT
1682 if (foundsep == 0)
1683 {
1684 _rl_init_file_error ("%s: no key sequence terminator", string);
1685 return 1;
1686 }
1687
d60d9f65 1688 /* If this is a new-style key-binding, then do the binding with
5bdf8622 1689 rl_bind_keyseq (). Otherwise, let the older code deal with it. */
d60d9f65
SS
1690 if (*string == '"')
1691 {
1692 char *seq;
1693 register int j, k, passc;
1694
9255ee31 1695 seq = (char *)xmalloc (1 + strlen (string));
d60d9f65
SS
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
5bdf8622 1728 rl_bind_keyseq (seq, rl_named_function (funname));
d60d9f65 1729
cc88a640 1730 xfree (seq);
d60d9f65
SS
1731 return 0;
1732 }
1733
1734 /* Get the actual character we want to deal with. */
1735 kname = strrchr (string, '-');
775e241e 1736 if (kname == 0)
d60d9f65
SS
1737 kname = string;
1738 else
1739 kname++;
1740
1741 key = glean_key_from_name (kname);
1742
1743 /* Add in control and meta bits. */
775e241e 1744 foundmod = 0;
9255ee31 1745 if (substring_member_of_array (string, _rl_possible_control_prefixes))
775e241e
TT
1746 {
1747 key = CTRL (_rl_to_upper (key));
1748 foundmod = 1;
1749 }
d60d9f65 1750
9255ee31 1751 if (substring_member_of_array (string, _rl_possible_meta_prefixes))
775e241e
TT
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 }
d60d9f65
SS
1762
1763 /* Temporary. Handle old-style keyname with macro-binding. */
1764 if (*funname == '\'' || *funname == '"')
1765 {
9255ee31 1766 char useq[2];
d60d9f65
SS
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));
775e241e 1788
d60d9f65
SS
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
1b17e766
EZ
1796#define V_SPECIAL 0x1
1797
cc88a640
JK
1798static const struct {
1799 const char * const name;
d60d9f65 1800 int *value;
1b17e766 1801 int flags;
d60d9f65 1802} boolean_varlist [] = {
5bdf8622 1803 { "bind-tty-special-chars", &_rl_bind_stty_chars, 0 },
1b17e766 1804 { "blink-matching-paren", &rl_blink_matching_paren, V_SPECIAL },
9255ee31 1805 { "byte-oriented", &rl_byte_oriented, 0 },
775e241e
TT
1806#if defined (COLOR_SUPPORT)
1807 { "colored-completion-prefix",&_rl_colored_completion_prefix, 0 },
1808 { "colored-stats", &_rl_colored_stats, 0 },
1809#endif
1b17e766 1810 { "completion-ignore-case", &_rl_completion_case_fold, 0 },
cc88a640 1811 { "completion-map-case", &_rl_completion_case_map, 0 },
1b17e766
EZ
1812 { "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 },
1813 { "disable-completion", &rl_inhibit_completion, 0 },
cc88a640 1814 { "echo-control-characters", &_rl_echo_control_chars, 0 },
b4f26d54 1815 { "enable-bracketed-paste", &_rl_enable_bracketed_paste, V_SPECIAL },
1b17e766 1816 { "enable-keypad", &_rl_enable_keypad, 0 },
cc88a640 1817 { "enable-meta-key", &_rl_enable_meta, 0 },
1b17e766 1818 { "expand-tilde", &rl_complete_with_tilde_expansion, 0 },
9255ee31 1819 { "history-preserve-point", &_rl_history_preserve_point, 0 },
1b17e766
EZ
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 },
9255ee31
EZ
1824 { "mark-symlinked-directories", &_rl_complete_mark_symlink_dirs, 0 },
1825 { "match-hidden-files", &_rl_match_hidden_files, 0 },
cc88a640 1826 { "menu-complete-display-prefix", &_rl_menu_complete_prefix_first, 0 },
1b17e766
EZ
1827 { "meta-flag", &_rl_meta_flag, 0 },
1828 { "output-meta", &_rl_output_meta_chars, 0 },
9255ee31 1829 { "page-completions", &_rl_page_completions, 0 },
1b17e766
EZ
1830 { "prefer-visible-bell", &_rl_prefer_visible_bell, V_SPECIAL },
1831 { "print-completions-horizontally", &_rl_print_completions_horizontally, 0 },
cc88a640 1832 { "revert-all-at-newline", &_rl_revert_all_at_newline, 0 },
1b17e766 1833 { "show-all-if-ambiguous", &_rl_complete_show_all, 0 },
5bdf8622 1834 { "show-all-if-unmodified", &_rl_complete_show_unmodified, 0 },
775e241e 1835 { "show-mode-in-prompt", &_rl_show_mode_in_prompt, 0 },
cc88a640 1836 { "skip-completed-text", &_rl_skip_completed_text, 0 },
d60d9f65 1837#if defined (VISIBLE_STATS)
1b17e766 1838 { "visible-stats", &rl_visible_stats, 0 },
d60d9f65 1839#endif /* VISIBLE_STATS */
cc88a640 1840 { (char *)NULL, (int *)NULL, 0 }
d60d9f65
SS
1841};
1842
1b17e766 1843static int
cb41b9e7 1844find_boolean_var (const char *name)
1b17e766
EZ
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
cb41b9e7
TT
1854static const char *
1855boolean_varname (int i)
1856{
1857 return ((i >= 0) ? boolean_varlist[i].name : (char *)NULL);
1858}
1859
1b17e766
EZ
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. */
1863static void
cb41b9e7 1864hack_special_boolean_var (int i)
1b17e766 1865{
9255ee31 1866 const char *name;
1b17e766
EZ
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 }
775e241e
TT
1879 else if (_rl_stricmp (name, "show-mode-in-prompt") == 0)
1880 _rl_reset_prompt ();
b4f26d54
TT
1881 else if (_rl_stricmp (name, "enable-bracketed-paste") == 0)
1882 _rl_enable_active_region = _rl_enable_bracketed_paste;
1b17e766
EZ
1883}
1884
9255ee31
EZ
1885typedef int _rl_sv_func_t PARAMS((const char *));
1886
1b17e766
EZ
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 */
9255ee31
EZ
1899static int sv_bell_style PARAMS((const char *));
1900static int sv_combegin PARAMS((const char *));
cc88a640 1901static int sv_dispprefix PARAMS((const char *));
9255ee31 1902static int sv_compquery PARAMS((const char *));
cc88a640 1903static int sv_compwidth PARAMS((const char *));
9255ee31 1904static int sv_editmode PARAMS((const char *));
775e241e 1905static int sv_emacs_modestr PARAMS((const char *));
cc88a640 1906static int sv_histsize PARAMS((const char *));
9255ee31
EZ
1907static int sv_isrchterm PARAMS((const char *));
1908static int sv_keymap PARAMS((const char *));
775e241e
TT
1909static int sv_seqtimeout PARAMS((const char *));
1910static int sv_viins_modestr PARAMS((const char *));
1911static int sv_vicmd_modestr PARAMS((const char *));
1b17e766 1912
cc88a640
JK
1913static const struct {
1914 const char * const name;
1b17e766 1915 int flags;
9255ee31 1916 _rl_sv_func_t *set_func;
1b17e766
EZ
1917} string_varlist[] = {
1918 { "bell-style", V_STRING, sv_bell_style },
1919 { "comment-begin", V_STRING, sv_combegin },
cc88a640
JK
1920 { "completion-display-width", V_INT, sv_compwidth },
1921 { "completion-prefix-display-length", V_INT, sv_dispprefix },
1b17e766
EZ
1922 { "completion-query-items", V_INT, sv_compquery },
1923 { "editing-mode", V_STRING, sv_editmode },
775e241e 1924 { "emacs-mode-string", V_STRING, sv_emacs_modestr },
cc88a640 1925 { "history-size", V_INT, sv_histsize },
1b17e766
EZ
1926 { "isearch-terminators", V_STRING, sv_isrchterm },
1927 { "keymap", V_STRING, sv_keymap },
775e241e
TT
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 },
cc88a640 1931 { (char *)NULL, 0, (_rl_sv_func_t *)0 }
1b17e766
EZ
1932};
1933
1934static int
cb41b9e7 1935find_string_var (const char *name)
1b17e766
EZ
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
cb41b9e7
TT
1945static const char *
1946string_varname (int i)
1947{
1948 return ((i >= 0) ? string_varlist[i].name : (char *)NULL);
1949}
1950
1b17e766 1951/* A boolean value that can appear in a `set variable' command is true if
b4f26d54 1952 the value is null or empty, `on' (case-insensitive), or "1". All other
1b17e766
EZ
1953 values result in 0 (false). */
1954static int
cb41b9e7 1955bool_to_int (const char *value)
1b17e766
EZ
1956{
1957 return (value == 0 || *value == '\0' ||
1958 (_rl_stricmp (value, "on") == 0) ||
1959 (value[0] == '1' && value[1] == '\0'));
1960}
1961
5bdf8622 1962char *
cb41b9e7 1963rl_variable_value (const char *name)
5bdf8622
DJ
1964{
1965 register int i;
5bdf8622
DJ
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. */
b4f26d54 1977 return (char *)NULL;
5bdf8622
DJ
1978}
1979
d60d9f65 1980int
cb41b9e7 1981rl_variable_bind (const char *name, const char *value)
d60d9f65
SS
1982{
1983 register int i;
1b17e766 1984 int v;
d60d9f65
SS
1985
1986 /* Check for simple variables first. */
1b17e766
EZ
1987 i = find_boolean_var (name);
1988 if (i >= 0)
d60d9f65 1989 {
1b17e766
EZ
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;
d60d9f65
SS
1994 }
1995
1b17e766
EZ
1996 i = find_string_var (name);
1997
775e241e
TT
1998 /* For the time being, string names without a handler function are simply
1999 ignored. */
1b17e766 2000 if (i < 0 || string_varlist[i].set_func == 0)
775e241e
TT
2001 {
2002 if (i < 0)
2003 _rl_init_file_error ("%s: unknown variable name", name);
2004 return 0;
2005 }
d60d9f65 2006
1b17e766 2007 v = (*string_varlist[i].set_func) (value);
b4f26d54
TT
2008 if (v != 0)
2009 _rl_init_file_error ("%s: could not set value to `%s'", name, value);
1b17e766
EZ
2010 return v;
2011}
2012
2013static int
cb41b9e7 2014sv_editmode (const char *value)
1b17e766
EZ
2015{
2016 if (_rl_strnicmp (value, "vi", 2) == 0)
d60d9f65 2017 {
d60d9f65 2018#if defined (VI_MODE)
1b17e766
EZ
2019 _rl_keymap = vi_insertion_keymap;
2020 rl_editing_mode = vi_mode;
d60d9f65 2021#endif /* VI_MODE */
1b17e766 2022 return 0;
d60d9f65 2023 }
1b17e766 2024 else if (_rl_strnicmp (value, "emacs", 5) == 0)
d60d9f65 2025 {
1b17e766
EZ
2026 _rl_keymap = emacs_standard_keymap;
2027 rl_editing_mode = emacs_mode;
2028 return 0;
d60d9f65 2029 }
1b17e766
EZ
2030 return 1;
2031}
2032
2033static int
cb41b9e7 2034sv_combegin (const char *value)
1b17e766
EZ
2035{
2036 if (value && *value)
d60d9f65 2037 {
1b17e766
EZ
2038 FREE (_rl_comment_begin);
2039 _rl_comment_begin = savestring (value);
2040 return 0;
d60d9f65 2041 }
1b17e766
EZ
2042 return 1;
2043}
2044
cc88a640 2045static int
cb41b9e7 2046sv_dispprefix (const char *value)
cc88a640
JK
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
1b17e766 2060static int
cb41b9e7 2061sv_compquery (const char *value)
1b17e766
EZ
2062{
2063 int nval = 100;
2064
2065 if (value && *value)
d60d9f65 2066 {
1b17e766
EZ
2067 nval = atoi (value);
2068 if (nval < 0)
2069 nval = 0;
d60d9f65 2070 }
1b17e766
EZ
2071 rl_completion_query_items = nval;
2072 return 0;
2073}
2074
cc88a640 2075static int
cb41b9e7 2076sv_compwidth (const char *value)
cc88a640
JK
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
2087static int
cb41b9e7 2088sv_histsize (const char *value)
cc88a640 2089{
775e241e 2090 int nval;
cc88a640 2091
775e241e 2092 nval = 500;
cc88a640
JK
2093 if (value && *value)
2094 {
2095 nval = atoi (value);
2096 if (nval < 0)
775e241e
TT
2097 {
2098 unstifle_history ();
2099 return 0;
2100 }
cc88a640
JK
2101 }
2102 stifle_history (nval);
2103 return 0;
2104}
2105
1b17e766 2106static int
cb41b9e7 2107sv_keymap (const char *value)
1b17e766
EZ
2108{
2109 Keymap kmap;
2110
2111 kmap = rl_get_keymap_by_name (value);
2112 if (kmap)
d60d9f65 2113 {
1b17e766
EZ
2114 rl_set_keymap (kmap);
2115 return 0;
d60d9f65 2116 }
1b17e766
EZ
2117 return 1;
2118}
2119
775e241e 2120static int
cb41b9e7 2121sv_seqtimeout (const char *value)
775e241e
TT
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
1b17e766 2136static int
cb41b9e7 2137sv_bell_style (const char *value)
1b17e766
EZ
2138{
2139 if (value == 0 || *value == '\0')
9255ee31 2140 _rl_bell_preference = AUDIBLE_BELL;
1b17e766 2141 else if (_rl_stricmp (value, "none") == 0 || _rl_stricmp (value, "off") == 0)
9255ee31 2142 _rl_bell_preference = NO_BELL;
1b17e766 2143 else if (_rl_stricmp (value, "audible") == 0 || _rl_stricmp (value, "on") == 0)
9255ee31 2144 _rl_bell_preference = AUDIBLE_BELL;
1b17e766 2145 else if (_rl_stricmp (value, "visible") == 0)
9255ee31 2146 _rl_bell_preference = VISIBLE_BELL;
1b17e766
EZ
2147 else
2148 return 1;
9255ee31 2149 return 0;
1b17e766 2150}
1b17e766
EZ
2151
2152static int
cb41b9e7 2153sv_isrchterm (const char *value)
1b17e766
EZ
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] == '\'')
d60d9f65 2165 {
1b17e766
EZ
2166 delim = v[0];
2167 for (beg = end = 1; v[end] && v[end] != delim; end++)
2168 ;
d60d9f65 2169 }
1b17e766 2170 else
c862e87b 2171 {
775e241e 2172 for (beg = end = 0; v[end] && whitespace (v[end]) == 0; end++)
1b17e766
EZ
2173 ;
2174 }
d60d9f65 2175
1b17e766 2176 v[end] = '\0';
c862e87b 2177
1b17e766 2178 /* The value starts at v + beg. Translate it into a character string. */
9255ee31 2179 _rl_isearch_terminators = (char *)xmalloc (2 * strlen (v) + 1);
1b17e766
EZ
2180 rl_translate_keyseq (v + beg, _rl_isearch_terminators, &end);
2181 _rl_isearch_terminators[end] = '\0';
2182
cc88a640 2183 xfree (v);
d60d9f65
SS
2184 return 0;
2185}
775e241e
TT
2186
2187extern char *_rl_emacs_mode_str;
2188
2189static int
cb41b9e7 2190sv_emacs_modestr (const char *value)
775e241e
TT
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
2217static int
cb41b9e7 2218sv_viins_modestr (const char *value)
775e241e
TT
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
2245static int
cb41b9e7 2246sv_vicmd_modestr (const char *value)
775e241e
TT
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
d60d9f65
SS
2273/* Return the character which matches NAME.
2274 For example, `Space' returns ' '. */
2275
2276typedef struct {
cc88a640 2277 const char * const name;
d60d9f65
SS
2278 int value;
2279} assoc_list;
2280
cc88a640 2281static const assoc_list name_key_alist[] = {
d60d9f65
SS
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
2296static int
cb41b9e7 2297glean_key_from_name (char *name)
d60d9f65
SS
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. */
cb41b9e7
TT
2309struct name_and_keymap {
2310 char *name;
d60d9f65 2311 Keymap map;
cb41b9e7
TT
2312};
2313
2314static struct name_and_keymap builtin_keymap_names[] = {
d60d9f65
SS
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
cb41b9e7
TT
2328/* -1 for NULL entry */
2329#define NUM_BUILTIN_KEYMAPS (sizeof (builtin_keymap_names) / sizeof (builtin_keymap_names[0]) - 1)
2330
2331static struct name_and_keymap *keymap_names = builtin_keymap_names;
2332
2333static int
2334_rl_get_keymap_by_name (const char *name)
d60d9f65
SS
2335{
2336 register int i;
2337
2338 for (i = 0; keymap_names[i].name; i++)
9255ee31 2339 if (_rl_stricmp (name, keymap_names[i].name) == 0)
cb41b9e7
TT
2340 return (i);
2341 return -1;
d60d9f65
SS
2342}
2343
cb41b9e7
TT
2344Keymap
2345rl_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
2353static int
2354_rl_get_keymap_by_map (Keymap map)
d60d9f65
SS
2355{
2356 register int i;
cb41b9e7 2357
d60d9f65
SS
2358 for (i = 0; keymap_names[i].name; i++)
2359 if (map == keymap_names[i].map)
cb41b9e7
TT
2360 return (i);
2361 return -1;
d60d9f65 2362}
cb41b9e7
TT
2363
2364char *
2365rl_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
2373int
2374rl_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
d60d9f65 2423void
cb41b9e7 2424rl_set_keymap (Keymap map)
d60d9f65
SS
2425{
2426 if (map)
2427 _rl_keymap = map;
2428}
2429
2430Keymap
cb41b9e7 2431rl_get_keymap (void)
d60d9f65
SS
2432{
2433 return (_rl_keymap);
2434}
2435
2436void
cb41b9e7 2437rl_set_keymap_from_edit_mode (void)
d60d9f65
SS
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
2447char *
cb41b9e7 2448rl_get_keymap_name_from_edit_mode (void)
d60d9f65
SS
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
5bdf8622 2469 be read back in (i.e., passed to rl_parse_and_bind ()). */
d60d9f65
SS
2470
2471/* Print the names of functions known to Readline. */
2472void
cb41b9e7 2473rl_list_funmap_names (void)
d60d9f65
SS
2474{
2475 register int i;
9255ee31 2476 const char **funmap_names;
d60d9f65
SS
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
cc88a640 2486 xfree (funmap_names);
d60d9f65
SS
2487}
2488
2489static char *
cb41b9e7 2490_rl_get_keyname (int key)
d60d9f65
SS
2491{
2492 char *keyname;
c862e87b 2493 int i, c;
d60d9f65
SS
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
9255ee31
EZ
2502#if 1
2503 /* XXX - Experimental */
d60d9f65
SS
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 {
9255ee31
EZ
2510 keyname[0] = '\\';
2511 keyname[1] = 'e';
2512 keyname[2] = '\0';
2513 return keyname;
d60d9f65
SS
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. */
2564char **
cb41b9e7 2565rl_invoking_keyseqs_in_map (rl_command_func_t *function, Keymap map)
d60d9f65
SS
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;
9255ee31 2593 result = (char **)xrealloc (result, result_size * sizeof (char *));
d60d9f65
SS
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)
cc88a640
JK
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 }
d60d9f65
SS
2632 else
2633 {
b4f26d54
TT
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';
d60d9f65
SS
2648 }
2649
2650 strcat (keyname, seqs[i]);
cc88a640 2651 xfree (seqs[i]);
d60d9f65
SS
2652
2653 if (result_index + 2 > result_size)
2654 {
2655 result_size += 10;
9255ee31 2656 result = (char **)xrealloc (result, result_size * sizeof (char *));
d60d9f65
SS
2657 }
2658
2659 result[result_index++] = keyname;
2660 result[result_index] = (char *)NULL;
2661 }
2662
cc88a640 2663 xfree (seqs);
d60d9f65
SS
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. */
2673char **
cb41b9e7 2674rl_invoking_keyseqs (rl_command_func_t *function)
d60d9f65
SS
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. */
2682void
cb41b9e7 2683rl_function_dumper (int print_readably)
d60d9f65
SS
2684{
2685 register int i;
9255ee31
EZ
2686 const char **names;
2687 const char *name;
d60d9f65
SS
2688
2689 names = rl_funmap_names ();
2690
2691 fprintf (rl_outstream, "\n");
2692
2693 for (i = 0; name = names[i]; i++)
2694 {
9255ee31 2695 rl_command_func_t *function;
d60d9f65
SS
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);
cc88a640 2713 xfree (invokers[j]);
d60d9f65
SS
2714 }
2715
cc88a640 2716 xfree (invokers);
d60d9f65
SS
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++)
cc88a640 2740 xfree (invokers[j]);
d60d9f65 2741
cc88a640 2742 xfree (invokers);
d60d9f65
SS
2743 }
2744 }
2745 }
775e241e
TT
2746
2747 xfree (names);
d60d9f65
SS
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. */
2753int
cb41b9e7 2754rl_dump_functions (int count, int key)
d60d9f65
SS
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
2763static void
cb41b9e7 2764_rl_macro_dumper_internal (int print_readably, Keymap map, char *prefix)
d60d9f65
SS
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);
775e241e 2776 out = _rl_untranslate_macro_value ((char *)map[key].function, 0);
9255ee31 2777
d60d9f65
SS
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 : "");
cc88a640
JK
2786 xfree (keyname);
2787 xfree (out);
d60d9f65
SS
2788 break;
2789 case ISFUNC:
2790 break;
2791 case ISKMAP:
2792 prefix_len = prefix ? strlen (prefix) : 0;
2793 if (key == ESC)
2794 {
9255ee31 2795 keyname = (char *)xmalloc (3 + prefix_len);
d60d9f65
SS
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 {
9255ee31 2807 out = (char *)xmalloc (strlen (keyname) + prefix_len + 1);
d60d9f65
SS
2808 strcpy (out, prefix);
2809 strcpy (out + prefix_len, keyname);
cc88a640 2810 xfree (keyname);
d60d9f65
SS
2811 keyname = out;
2812 }
2813 }
2814
2815 _rl_macro_dumper_internal (print_readably, FUNCTION_TO_KEYMAP (map, key), keyname);
cc88a640 2816 xfree (keyname);
d60d9f65
SS
2817 break;
2818 }
2819 }
2820}
2821
2822void
cb41b9e7 2823rl_macro_dumper (int print_readably)
d60d9f65
SS
2824{
2825 _rl_macro_dumper_internal (print_readably, _rl_keymap, (char *)NULL);
2826}
2827
2828int
cb41b9e7 2829rl_dump_macros (int count, int key)
d60d9f65
SS
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
5bdf8622 2838static char *
cb41b9e7 2839_rl_get_string_variable_value (const char *name)
5bdf8622
DJ
2840{
2841 static char numbuf[32];
2842 char *ret;
5bdf8622
DJ
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);
cc88a640
JK
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 }
5bdf8622
DJ
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 ());
cc88a640
JK
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 }
5bdf8622
DJ
2881 else if (_rl_stricmp (name, "isearch-terminators") == 0)
2882 {
2883 if (_rl_isearch_terminators == 0)
2884 return 0;
775e241e 2885 ret = _rl_untranslate_macro_value (_rl_isearch_terminators, 0);
5bdf8622
DJ
2886 if (ret)
2887 {
2888 strncpy (numbuf, ret, sizeof (numbuf) - 1);
cc88a640 2889 xfree (ret);
5bdf8622
DJ
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 }
775e241e
TT
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);
5bdf8622
DJ
2914 else
2915 return (0);
2916}
2917
d60d9f65 2918void
cb41b9e7 2919rl_variable_dumper (int print_readably)
d60d9f65
SS
2920{
2921 int i;
5bdf8622 2922 char *v;
d60d9f65
SS
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
5bdf8622 2934 for (i = 0; string_varlist[i].name; i++)
c862e87b 2935 {
5bdf8622
DJ
2936 v = _rl_get_string_variable_value (string_varlist[i].name);
2937 if (v == 0) /* _rl_isearch_terminators can be NULL */
2938 continue;
c862e87b 2939 if (print_readably)
5bdf8622 2940 fprintf (rl_outstream, "set %s %s\n", string_varlist[i].name, v);
c862e87b 2941 else
5bdf8622 2942 fprintf (rl_outstream, "%s is set to `%s'\n", string_varlist[i].name, v);
c862e87b 2943 }
d60d9f65
SS
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. */
2949int
cb41b9e7 2950rl_dump_variables (int count, int key)
d60d9f65
SS
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
d60d9f65
SS
2959/* Return non-zero if any members of ARRAY are a substring in STRING. */
2960static int
cb41b9e7 2961substring_member_of_array (const char *string, const char * const *array)
d60d9f65
SS
2962{
2963 while (*array)
2964 {
2965 if (_rl_strindex (string, *array))
2966 return (1);
2967 array++;
2968 }
2969 return (0);
2970}
This page took 1.338057 seconds and 4 git commands to generate.