11acd27e7Smillert /* bind.c -- key binding and startup file support for the readline library. */
21acd27e7Smillert
31acd27e7Smillert /* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
41acd27e7Smillert
51acd27e7Smillert This file is part of the GNU Readline Library, a library for
61acd27e7Smillert reading lines of text with interactive input and history editing.
71acd27e7Smillert
81acd27e7Smillert The GNU Readline Library is free software; you can redistribute it
91acd27e7Smillert and/or modify it under the terms of the GNU General Public License
101acd27e7Smillert as published by the Free Software Foundation; either version 2, or
111acd27e7Smillert (at your option) any later version.
121acd27e7Smillert
131acd27e7Smillert The GNU Readline Library is distributed in the hope that it will be
141acd27e7Smillert useful, but WITHOUT ANY WARRANTY; without even the implied warranty
151acd27e7Smillert of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
161acd27e7Smillert GNU General Public License for more details.
171acd27e7Smillert
181acd27e7Smillert The GNU General Public License is often shipped with GNU software, and
191acd27e7Smillert is generally kept in a file called COPYING or LICENSE. If you do not
201acd27e7Smillert have a copy of the license, write to the Free Software Foundation,
211acd27e7Smillert 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
221acd27e7Smillert #define READLINE_LIBRARY
231acd27e7Smillert
241acd27e7Smillert #if defined (HAVE_CONFIG_H)
251acd27e7Smillert # include <config.h>
261acd27e7Smillert #endif
271acd27e7Smillert
281acd27e7Smillert #include <stdio.h>
291acd27e7Smillert #include <sys/types.h>
301acd27e7Smillert #include <fcntl.h>
311acd27e7Smillert #if defined (HAVE_SYS_FILE_H)
321acd27e7Smillert # include <sys/file.h>
331acd27e7Smillert #endif /* HAVE_SYS_FILE_H */
341acd27e7Smillert
351acd27e7Smillert #if defined (HAVE_UNISTD_H)
361acd27e7Smillert # include <unistd.h>
371acd27e7Smillert #endif /* HAVE_UNISTD_H */
381acd27e7Smillert
391acd27e7Smillert #if defined (HAVE_STDLIB_H)
401acd27e7Smillert # include <stdlib.h>
411acd27e7Smillert #else
421acd27e7Smillert # include "ansi_stdlib.h"
431acd27e7Smillert #endif /* HAVE_STDLIB_H */
441acd27e7Smillert
451acd27e7Smillert #include <errno.h>
461acd27e7Smillert
471acd27e7Smillert #if !defined (errno)
481acd27e7Smillert extern int errno;
491acd27e7Smillert #endif /* !errno */
501acd27e7Smillert
511acd27e7Smillert #include "posixstat.h"
521acd27e7Smillert
531acd27e7Smillert /* System-specific feature definitions and include files. */
541acd27e7Smillert #include "rldefs.h"
551acd27e7Smillert
561acd27e7Smillert /* Some standard library routines. */
571acd27e7Smillert #include "readline.h"
581acd27e7Smillert #include "history.h"
591acd27e7Smillert
601acd27e7Smillert #include "rlprivate.h"
611acd27e7Smillert #include "rlshell.h"
621acd27e7Smillert #include "xmalloc.h"
631acd27e7Smillert
641acd27e7Smillert #if !defined (strchr) && !defined (__STDC__)
651acd27e7Smillert extern char *strchr (), *strrchr ();
661acd27e7Smillert #endif /* !strchr && !__STDC__ */
671acd27e7Smillert
681acd27e7Smillert /* Variables exported by this file. */
691acd27e7Smillert Keymap rl_binding_keymap;
701acd27e7Smillert
71af70c2dfSkettenis static char *_rl_read_file PARAMS((char *, size_t *));
72af70c2dfSkettenis static void _rl_init_file_error PARAMS((const char *));
73af70c2dfSkettenis static int _rl_read_init_file PARAMS((const char *, int));
74af70c2dfSkettenis static int glean_key_from_name PARAMS((char *));
75af70c2dfSkettenis static int substring_member_of_array PARAMS((char *, const char **));
761acd27e7Smillert
771acd27e7Smillert static int currently_reading_init_file;
781acd27e7Smillert
791acd27e7Smillert /* used only in this file */
801acd27e7Smillert static int _rl_prefer_visible_bell = 1;
811acd27e7Smillert
821acd27e7Smillert /* **************************************************************** */
831acd27e7Smillert /* */
841acd27e7Smillert /* Binding keys */
851acd27e7Smillert /* */
861acd27e7Smillert /* **************************************************************** */
871acd27e7Smillert
88af70c2dfSkettenis /* rl_add_defun (char *name, rl_command_func_t *function, int key)
891acd27e7Smillert Add NAME to the list of named functions. Make FUNCTION be the function
901acd27e7Smillert that gets called. If KEY is not -1, then bind it. */
911acd27e7Smillert int
rl_add_defun(name,function,key)921acd27e7Smillert rl_add_defun (name, function, key)
93af70c2dfSkettenis const char *name;
94af70c2dfSkettenis rl_command_func_t *function;
951acd27e7Smillert int key;
961acd27e7Smillert {
971acd27e7Smillert if (key != -1)
981acd27e7Smillert rl_bind_key (key, function);
991acd27e7Smillert rl_add_funmap_entry (name, function);
1001acd27e7Smillert return 0;
1011acd27e7Smillert }
1021acd27e7Smillert
1031acd27e7Smillert /* Bind KEY to FUNCTION. Returns non-zero if KEY is out of range. */
1041acd27e7Smillert int
rl_bind_key(key,function)1051acd27e7Smillert rl_bind_key (key, function)
1061acd27e7Smillert int key;
107af70c2dfSkettenis rl_command_func_t *function;
1081acd27e7Smillert {
1091acd27e7Smillert if (key < 0)
1101acd27e7Smillert return (key);
1111acd27e7Smillert
1121acd27e7Smillert if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
1131acd27e7Smillert {
1141acd27e7Smillert if (_rl_keymap[ESC].type == ISKMAP)
1151acd27e7Smillert {
1161acd27e7Smillert Keymap escmap;
1171acd27e7Smillert
1181acd27e7Smillert escmap = FUNCTION_TO_KEYMAP (_rl_keymap, ESC);
1191acd27e7Smillert key = UNMETA (key);
1201acd27e7Smillert escmap[key].type = ISFUNC;
1211acd27e7Smillert escmap[key].function = function;
1221acd27e7Smillert return (0);
1231acd27e7Smillert }
1241acd27e7Smillert return (key);
1251acd27e7Smillert }
1261acd27e7Smillert
1271acd27e7Smillert _rl_keymap[key].type = ISFUNC;
1281acd27e7Smillert _rl_keymap[key].function = function;
1291acd27e7Smillert rl_binding_keymap = _rl_keymap;
1301acd27e7Smillert return (0);
1311acd27e7Smillert }
1321acd27e7Smillert
1331acd27e7Smillert /* Bind KEY to FUNCTION in MAP. Returns non-zero in case of invalid
1341acd27e7Smillert KEY. */
1351acd27e7Smillert int
rl_bind_key_in_map(key,function,map)1361acd27e7Smillert rl_bind_key_in_map (key, function, map)
1371acd27e7Smillert int key;
138af70c2dfSkettenis rl_command_func_t *function;
1391acd27e7Smillert Keymap map;
1401acd27e7Smillert {
1411acd27e7Smillert int result;
1421acd27e7Smillert Keymap oldmap;
1431acd27e7Smillert
1441acd27e7Smillert oldmap = _rl_keymap;
1451acd27e7Smillert _rl_keymap = map;
1461acd27e7Smillert result = rl_bind_key (key, function);
1471acd27e7Smillert _rl_keymap = oldmap;
1481acd27e7Smillert return (result);
1491acd27e7Smillert }
1501acd27e7Smillert
1511acd27e7Smillert /* Make KEY do nothing in the currently selected keymap.
1521acd27e7Smillert Returns non-zero in case of error. */
1531acd27e7Smillert int
rl_unbind_key(key)1541acd27e7Smillert rl_unbind_key (key)
1551acd27e7Smillert int key;
1561acd27e7Smillert {
157af70c2dfSkettenis return (rl_bind_key (key, (rl_command_func_t *)NULL));
1581acd27e7Smillert }
1591acd27e7Smillert
1601acd27e7Smillert /* Make KEY do nothing in MAP.
1611acd27e7Smillert Returns non-zero in case of error. */
1621acd27e7Smillert int
rl_unbind_key_in_map(key,map)1631acd27e7Smillert rl_unbind_key_in_map (key, map)
1641acd27e7Smillert int key;
1651acd27e7Smillert Keymap map;
1661acd27e7Smillert {
167af70c2dfSkettenis return (rl_bind_key_in_map (key, (rl_command_func_t *)NULL, map));
1681acd27e7Smillert }
1691acd27e7Smillert
1701acd27e7Smillert /* Unbind all keys bound to FUNCTION in MAP. */
1711acd27e7Smillert int
rl_unbind_function_in_map(func,map)1721acd27e7Smillert rl_unbind_function_in_map (func, map)
173af70c2dfSkettenis rl_command_func_t *func;
1741acd27e7Smillert Keymap map;
1751acd27e7Smillert {
1761acd27e7Smillert register int i, rval;
1771acd27e7Smillert
1781acd27e7Smillert for (i = rval = 0; i < KEYMAP_SIZE; i++)
1791acd27e7Smillert {
1801acd27e7Smillert if (map[i].type == ISFUNC && map[i].function == func)
1811acd27e7Smillert {
182af70c2dfSkettenis map[i].function = (rl_command_func_t *)NULL;
1831acd27e7Smillert rval = 1;
1841acd27e7Smillert }
1851acd27e7Smillert }
1861acd27e7Smillert return rval;
1871acd27e7Smillert }
1881acd27e7Smillert
1891acd27e7Smillert int
rl_unbind_command_in_map(command,map)1901acd27e7Smillert rl_unbind_command_in_map (command, map)
191af70c2dfSkettenis const char *command;
1921acd27e7Smillert Keymap map;
1931acd27e7Smillert {
194af70c2dfSkettenis rl_command_func_t *func;
1951acd27e7Smillert
1961acd27e7Smillert func = rl_named_function (command);
1971acd27e7Smillert if (func == 0)
1981acd27e7Smillert return 0;
1991acd27e7Smillert return (rl_unbind_function_in_map (func, map));
2001acd27e7Smillert }
2011acd27e7Smillert
2021acd27e7Smillert /* Bind the key sequence represented by the string KEYSEQ to
2031acd27e7Smillert FUNCTION. This makes new keymaps as necessary. The initial
2041acd27e7Smillert place to do bindings is in MAP. */
2051acd27e7Smillert int
rl_set_key(keyseq,function,map)2061acd27e7Smillert rl_set_key (keyseq, function, map)
207af70c2dfSkettenis const char *keyseq;
208af70c2dfSkettenis rl_command_func_t *function;
2091acd27e7Smillert Keymap map;
2101acd27e7Smillert {
2111acd27e7Smillert return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));
2121acd27e7Smillert }
2131acd27e7Smillert
2141acd27e7Smillert /* Bind the key sequence represented by the string KEYSEQ to
2151acd27e7Smillert the string of characters MACRO. This makes new keymaps as
2161acd27e7Smillert necessary. The initial place to do bindings is in MAP. */
2171acd27e7Smillert int
rl_macro_bind(keyseq,macro,map)2181acd27e7Smillert rl_macro_bind (keyseq, macro, map)
219af70c2dfSkettenis const char *keyseq, *macro;
2201acd27e7Smillert Keymap map;
2211acd27e7Smillert {
2221acd27e7Smillert char *macro_keys;
2231acd27e7Smillert int macro_keys_len;
2241acd27e7Smillert
2251acd27e7Smillert macro_keys = (char *)xmalloc ((2 * strlen (macro)) + 1);
2261acd27e7Smillert
2271acd27e7Smillert if (rl_translate_keyseq (macro, macro_keys, ¯o_keys_len))
2281acd27e7Smillert {
2291acd27e7Smillert free (macro_keys);
2301acd27e7Smillert return -1;
2311acd27e7Smillert }
2321acd27e7Smillert rl_generic_bind (ISMACR, keyseq, macro_keys, map);
2331acd27e7Smillert return 0;
2341acd27e7Smillert }
2351acd27e7Smillert
2361acd27e7Smillert /* Bind the key sequence represented by the string KEYSEQ to
2371acd27e7Smillert the arbitrary pointer DATA. TYPE says what kind of data is
2381acd27e7Smillert pointed to by DATA, right now this can be a function (ISFUNC),
2391acd27e7Smillert a macro (ISMACR), or a keymap (ISKMAP). This makes new keymaps
2401acd27e7Smillert as necessary. The initial place to do bindings is in MAP. */
2411acd27e7Smillert int
rl_generic_bind(type,keyseq,data,map)2421acd27e7Smillert rl_generic_bind (type, keyseq, data, map)
2431acd27e7Smillert int type;
244af70c2dfSkettenis const char *keyseq;
245af70c2dfSkettenis char *data;
2461acd27e7Smillert Keymap map;
2471acd27e7Smillert {
2481acd27e7Smillert char *keys;
2491acd27e7Smillert int keys_len;
2501acd27e7Smillert register int i;
251af70c2dfSkettenis KEYMAP_ENTRY k;
252af70c2dfSkettenis
253af70c2dfSkettenis k.function = 0;
2541acd27e7Smillert
2551acd27e7Smillert /* If no keys to bind to, exit right away. */
2561acd27e7Smillert if (!keyseq || !*keyseq)
2571acd27e7Smillert {
2581acd27e7Smillert if (type == ISMACR)
2591acd27e7Smillert free (data);
2601acd27e7Smillert return -1;
2611acd27e7Smillert }
2621acd27e7Smillert
263af70c2dfSkettenis keys = (char *)xmalloc (1 + (2 * strlen (keyseq)));
2641acd27e7Smillert
2651acd27e7Smillert /* Translate the ASCII representation of KEYSEQ into an array of
2661acd27e7Smillert characters. Stuff the characters into KEYS, and the length of
2671acd27e7Smillert KEYS into KEYS_LEN. */
2681acd27e7Smillert if (rl_translate_keyseq (keyseq, keys, &keys_len))
2691acd27e7Smillert {
2701acd27e7Smillert free (keys);
2711acd27e7Smillert return -1;
2721acd27e7Smillert }
2731acd27e7Smillert
2741acd27e7Smillert /* Bind keys, making new keymaps as necessary. */
2751acd27e7Smillert for (i = 0; i < keys_len; i++)
2761acd27e7Smillert {
277af70c2dfSkettenis unsigned char uc = keys[i];
278af70c2dfSkettenis int ic;
279af70c2dfSkettenis
280af70c2dfSkettenis ic = uc;
281af70c2dfSkettenis if (ic < 0 || ic >= KEYMAP_SIZE)
282af70c2dfSkettenis return -1;
2831acd27e7Smillert
2841acd27e7Smillert if (_rl_convert_meta_chars_to_ascii && META_CHAR (ic))
2851acd27e7Smillert {
2861acd27e7Smillert ic = UNMETA (ic);
2871acd27e7Smillert if (map[ESC].type == ISKMAP)
2881acd27e7Smillert map = FUNCTION_TO_KEYMAP (map, ESC);
2891acd27e7Smillert }
2901acd27e7Smillert
2911acd27e7Smillert if ((i + 1) < keys_len)
2921acd27e7Smillert {
2931acd27e7Smillert if (map[ic].type != ISKMAP)
2941acd27e7Smillert {
295af70c2dfSkettenis /* We allow subsequences of keys. If a keymap is being
296af70c2dfSkettenis created that will `shadow' an existing function or macro
297af70c2dfSkettenis key binding, we save that keybinding into the ANYOTHERKEY
298af70c2dfSkettenis index in the new map. The dispatch code will look there
299af70c2dfSkettenis to find the function to execute if the subsequence is not
300af70c2dfSkettenis matched. ANYOTHERKEY was chosen to be greater than
301af70c2dfSkettenis UCHAR_MAX. */
302af70c2dfSkettenis k = map[ic];
3031acd27e7Smillert
3041acd27e7Smillert map[ic].type = ISKMAP;
3051acd27e7Smillert map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap());
3061acd27e7Smillert }
3071acd27e7Smillert map = FUNCTION_TO_KEYMAP (map, ic);
308af70c2dfSkettenis /* The dispatch code will return this function if no matching
309af70c2dfSkettenis key sequence is found in the keymap. This (with a little
310af70c2dfSkettenis help from the dispatch code in readline.c) allows `a' to be
311af70c2dfSkettenis mapped to something, `abc' to be mapped to something else,
312af70c2dfSkettenis and the function bound to `a' to be executed when the user
313af70c2dfSkettenis types `abx', leaving `bx' in the input queue. */
314af70c2dfSkettenis if (k.function && ((k.type == ISFUNC && k.function != rl_do_lowercase_version) || k.type == ISMACR))
315af70c2dfSkettenis {
316af70c2dfSkettenis map[ANYOTHERKEY] = k;
317af70c2dfSkettenis k.function = 0;
318af70c2dfSkettenis }
3191acd27e7Smillert }
3201acd27e7Smillert else
3211acd27e7Smillert {
3221acd27e7Smillert if (map[ic].type == ISMACR)
3231acd27e7Smillert free ((char *)map[ic].function);
324af70c2dfSkettenis else if (map[ic].type == ISKMAP)
325af70c2dfSkettenis {
326af70c2dfSkettenis map = FUNCTION_TO_KEYMAP (map, ic);
327af70c2dfSkettenis ic = ANYOTHERKEY;
328af70c2dfSkettenis }
3291acd27e7Smillert
3301acd27e7Smillert map[ic].function = KEYMAP_TO_FUNCTION (data);
3311acd27e7Smillert map[ic].type = type;
3321acd27e7Smillert }
3331acd27e7Smillert
3341acd27e7Smillert rl_binding_keymap = map;
3351acd27e7Smillert }
3361acd27e7Smillert free (keys);
3371acd27e7Smillert return 0;
3381acd27e7Smillert }
3391acd27e7Smillert
3401acd27e7Smillert /* Translate the ASCII representation of SEQ, stuffing the values into ARRAY,
3411acd27e7Smillert an array of characters. LEN gets the final length of ARRAY. Return
3421acd27e7Smillert non-zero if there was an error parsing SEQ. */
3431acd27e7Smillert int
rl_translate_keyseq(seq,array,len)3441acd27e7Smillert rl_translate_keyseq (seq, array, len)
345af70c2dfSkettenis const char *seq;
346af70c2dfSkettenis char *array;
3471acd27e7Smillert int *len;
3481acd27e7Smillert {
3491acd27e7Smillert register int i, c, l, temp;
3501acd27e7Smillert
351*af1e7b8cSkrw for (i = l = 0; (c = seq[i]); i++)
3521acd27e7Smillert {
3531acd27e7Smillert if (c == '\\')
3541acd27e7Smillert {
3551acd27e7Smillert c = seq[++i];
3561acd27e7Smillert
3571acd27e7Smillert if (c == 0)
3581acd27e7Smillert break;
3591acd27e7Smillert
3601acd27e7Smillert /* Handle \C- and \M- prefixes. */
3611acd27e7Smillert if ((c == 'C' || c == 'M') && seq[i + 1] == '-')
3621acd27e7Smillert {
3631acd27e7Smillert /* Handle special case of backwards define. */
3641acd27e7Smillert if (strncmp (&seq[i], "C-\\M-", 5) == 0)
3651acd27e7Smillert {
366af70c2dfSkettenis array[l++] = ESC; /* ESC is meta-prefix */
3671acd27e7Smillert i += 5;
3681acd27e7Smillert array[l++] = CTRL (_rl_to_upper (seq[i]));
3691acd27e7Smillert if (seq[i] == '\0')
3701acd27e7Smillert i--;
3711acd27e7Smillert }
3721acd27e7Smillert else if (c == 'M')
3731acd27e7Smillert {
3741acd27e7Smillert i++;
375af70c2dfSkettenis array[l++] = ESC; /* ESC is meta-prefix */
3761acd27e7Smillert }
3771acd27e7Smillert else if (c == 'C')
3781acd27e7Smillert {
3791acd27e7Smillert i += 2;
3801acd27e7Smillert /* Special hack for C-?... */
3811acd27e7Smillert array[l++] = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i]));
3821acd27e7Smillert }
3831acd27e7Smillert continue;
3841acd27e7Smillert }
3851acd27e7Smillert
3861acd27e7Smillert /* Translate other backslash-escaped characters. These are the
3871acd27e7Smillert same escape sequences that bash's `echo' and `printf' builtins
3881acd27e7Smillert handle, with the addition of \d -> RUBOUT. A backslash
3891acd27e7Smillert preceding a character that is not special is stripped. */
3901acd27e7Smillert switch (c)
3911acd27e7Smillert {
3921acd27e7Smillert case 'a':
3931acd27e7Smillert array[l++] = '\007';
3941acd27e7Smillert break;
3951acd27e7Smillert case 'b':
3961acd27e7Smillert array[l++] = '\b';
3971acd27e7Smillert break;
3981acd27e7Smillert case 'd':
3991acd27e7Smillert array[l++] = RUBOUT; /* readline-specific */
4001acd27e7Smillert break;
4011acd27e7Smillert case 'e':
4021acd27e7Smillert array[l++] = ESC;
4031acd27e7Smillert break;
4041acd27e7Smillert case 'f':
4051acd27e7Smillert array[l++] = '\f';
4061acd27e7Smillert break;
4071acd27e7Smillert case 'n':
4081acd27e7Smillert array[l++] = NEWLINE;
4091acd27e7Smillert break;
4101acd27e7Smillert case 'r':
4111acd27e7Smillert array[l++] = RETURN;
4121acd27e7Smillert break;
4131acd27e7Smillert case 't':
4141acd27e7Smillert array[l++] = TAB;
4151acd27e7Smillert break;
4161acd27e7Smillert case 'v':
4171acd27e7Smillert array[l++] = 0x0B;
4181acd27e7Smillert break;
4191acd27e7Smillert case '\\':
4201acd27e7Smillert array[l++] = '\\';
4211acd27e7Smillert break;
4221acd27e7Smillert case '0': case '1': case '2': case '3':
4231acd27e7Smillert case '4': case '5': case '6': case '7':
4241acd27e7Smillert i++;
4251acd27e7Smillert for (temp = 2, c -= '0'; ISOCTAL (seq[i]) && temp--; i++)
4261acd27e7Smillert c = (c * 8) + OCTVALUE (seq[i]);
4271acd27e7Smillert i--; /* auto-increment in for loop */
428af70c2dfSkettenis array[l++] = c & largest_char;
4291acd27e7Smillert break;
4301acd27e7Smillert case 'x':
4311acd27e7Smillert i++;
432af70c2dfSkettenis for (temp = 2, c = 0; ISXDIGIT ((unsigned char)seq[i]) && temp--; i++)
4331acd27e7Smillert c = (c * 16) + HEXVALUE (seq[i]);
434af70c2dfSkettenis if (temp == 2)
4351acd27e7Smillert c = 'x';
4361acd27e7Smillert i--; /* auto-increment in for loop */
437af70c2dfSkettenis array[l++] = c & largest_char;
4381acd27e7Smillert break;
4391acd27e7Smillert default: /* backslashes before non-special chars just add the char */
4401acd27e7Smillert array[l++] = c;
4411acd27e7Smillert break; /* the backslash is stripped */
4421acd27e7Smillert }
4431acd27e7Smillert continue;
4441acd27e7Smillert }
4451acd27e7Smillert
4461acd27e7Smillert array[l++] = c;
4471acd27e7Smillert }
4481acd27e7Smillert
4491acd27e7Smillert *len = l;
4501acd27e7Smillert array[l] = '\0';
4511acd27e7Smillert return (0);
4521acd27e7Smillert }
4531acd27e7Smillert
4541acd27e7Smillert char *
rl_untranslate_keyseq(seq)4551acd27e7Smillert rl_untranslate_keyseq (seq)
4561acd27e7Smillert int seq;
4571acd27e7Smillert {
4581acd27e7Smillert static char kseq[16];
4591acd27e7Smillert int i, c;
4601acd27e7Smillert
4611acd27e7Smillert i = 0;
4621acd27e7Smillert c = seq;
4631acd27e7Smillert if (META_CHAR (c))
4641acd27e7Smillert {
4651acd27e7Smillert kseq[i++] = '\\';
4661acd27e7Smillert kseq[i++] = 'M';
4671acd27e7Smillert kseq[i++] = '-';
4681acd27e7Smillert c = UNMETA (c);
4691acd27e7Smillert }
4701acd27e7Smillert else if (CTRL_CHAR (c))
4711acd27e7Smillert {
4721acd27e7Smillert kseq[i++] = '\\';
4731acd27e7Smillert kseq[i++] = 'C';
4741acd27e7Smillert kseq[i++] = '-';
4751acd27e7Smillert c = _rl_to_lower (UNCTRL (c));
4761acd27e7Smillert }
4771acd27e7Smillert else if (c == RUBOUT)
4781acd27e7Smillert {
4791acd27e7Smillert kseq[i++] = '\\';
4801acd27e7Smillert kseq[i++] = 'C';
4811acd27e7Smillert kseq[i++] = '-';
4821acd27e7Smillert c = '?';
4831acd27e7Smillert }
4841acd27e7Smillert
4851acd27e7Smillert if (c == ESC)
4861acd27e7Smillert {
4871acd27e7Smillert kseq[i++] = '\\';
4881acd27e7Smillert c = 'e';
4891acd27e7Smillert }
4901acd27e7Smillert else if (c == '\\' || c == '"')
4911acd27e7Smillert {
4921acd27e7Smillert kseq[i++] = '\\';
4931acd27e7Smillert }
4941acd27e7Smillert
4951acd27e7Smillert kseq[i++] = (unsigned char) c;
4961acd27e7Smillert kseq[i] = '\0';
4971acd27e7Smillert return kseq;
4981acd27e7Smillert }
4991acd27e7Smillert
5001acd27e7Smillert static char *
_rl_untranslate_macro_value(seq)5011acd27e7Smillert _rl_untranslate_macro_value (seq)
5021acd27e7Smillert char *seq;
5031acd27e7Smillert {
5041acd27e7Smillert char *ret, *r, *s;
5051acd27e7Smillert int c;
5061acd27e7Smillert
507af70c2dfSkettenis r = ret = (char *)xmalloc (7 * strlen (seq) + 1);
5081acd27e7Smillert for (s = seq; *s; s++)
5091acd27e7Smillert {
5101acd27e7Smillert c = *s;
5111acd27e7Smillert if (META_CHAR (c))
5121acd27e7Smillert {
5131acd27e7Smillert *r++ = '\\';
5141acd27e7Smillert *r++ = 'M';
5151acd27e7Smillert *r++ = '-';
5161acd27e7Smillert c = UNMETA (c);
5171acd27e7Smillert }
5181acd27e7Smillert else if (CTRL_CHAR (c) && c != ESC)
5191acd27e7Smillert {
5201acd27e7Smillert *r++ = '\\';
5211acd27e7Smillert *r++ = 'C';
5221acd27e7Smillert *r++ = '-';
5231acd27e7Smillert c = _rl_to_lower (UNCTRL (c));
5241acd27e7Smillert }
5251acd27e7Smillert else if (c == RUBOUT)
5261acd27e7Smillert {
5271acd27e7Smillert *r++ = '\\';
5281acd27e7Smillert *r++ = 'C';
5291acd27e7Smillert *r++ = '-';
5301acd27e7Smillert c = '?';
5311acd27e7Smillert }
5321acd27e7Smillert
5331acd27e7Smillert if (c == ESC)
5341acd27e7Smillert {
5351acd27e7Smillert *r++ = '\\';
5361acd27e7Smillert c = 'e';
5371acd27e7Smillert }
5381acd27e7Smillert else if (c == '\\' || c == '"')
5391acd27e7Smillert *r++ = '\\';
5401acd27e7Smillert
5411acd27e7Smillert *r++ = (unsigned char)c;
5421acd27e7Smillert }
5431acd27e7Smillert *r = '\0';
5441acd27e7Smillert return ret;
5451acd27e7Smillert }
5461acd27e7Smillert
5471acd27e7Smillert /* Return a pointer to the function that STRING represents.
5481acd27e7Smillert If STRING doesn't have a matching function, then a NULL pointer
5491acd27e7Smillert is returned. */
550af70c2dfSkettenis rl_command_func_t *
rl_named_function(string)5511acd27e7Smillert rl_named_function (string)
552af70c2dfSkettenis const char *string;
5531acd27e7Smillert {
5541acd27e7Smillert register int i;
5551acd27e7Smillert
5561acd27e7Smillert rl_initialize_funmap ();
5571acd27e7Smillert
5581acd27e7Smillert for (i = 0; funmap[i]; i++)
5591acd27e7Smillert if (_rl_stricmp (funmap[i]->name, string) == 0)
5601acd27e7Smillert return (funmap[i]->function);
561af70c2dfSkettenis return ((rl_command_func_t *)NULL);
5621acd27e7Smillert }
5631acd27e7Smillert
5641acd27e7Smillert /* Return the function (or macro) definition which would be invoked via
5651acd27e7Smillert KEYSEQ if executed in MAP. If MAP is NULL, then the current keymap is
5661acd27e7Smillert used. TYPE, if non-NULL, is a pointer to an int which will receive the
5671acd27e7Smillert type of the object pointed to. One of ISFUNC (function), ISKMAP (keymap),
5681acd27e7Smillert or ISMACR (macro). */
569af70c2dfSkettenis rl_command_func_t *
rl_function_of_keyseq(keyseq,map,type)5701acd27e7Smillert rl_function_of_keyseq (keyseq, map, type)
571af70c2dfSkettenis const char *keyseq;
5721acd27e7Smillert Keymap map;
5731acd27e7Smillert int *type;
5741acd27e7Smillert {
5751acd27e7Smillert register int i;
5761acd27e7Smillert
5771acd27e7Smillert if (!map)
5781acd27e7Smillert map = _rl_keymap;
5791acd27e7Smillert
5801acd27e7Smillert for (i = 0; keyseq && keyseq[i]; i++)
5811acd27e7Smillert {
582af70c2dfSkettenis unsigned char ic = keyseq[i];
5831acd27e7Smillert
5841acd27e7Smillert if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
5851acd27e7Smillert {
5861acd27e7Smillert if (map[ESC].type != ISKMAP)
5871acd27e7Smillert {
5881acd27e7Smillert if (type)
5891acd27e7Smillert *type = map[ESC].type;
5901acd27e7Smillert
5911acd27e7Smillert return (map[ESC].function);
5921acd27e7Smillert }
5931acd27e7Smillert else
5941acd27e7Smillert {
5951acd27e7Smillert map = FUNCTION_TO_KEYMAP (map, ESC);
5961acd27e7Smillert ic = UNMETA (ic);
5971acd27e7Smillert }
5981acd27e7Smillert }
5991acd27e7Smillert
6001acd27e7Smillert if (map[ic].type == ISKMAP)
6011acd27e7Smillert {
6021acd27e7Smillert /* If this is the last key in the key sequence, return the
6031acd27e7Smillert map. */
6041acd27e7Smillert if (!keyseq[i + 1])
6051acd27e7Smillert {
6061acd27e7Smillert if (type)
6071acd27e7Smillert *type = ISKMAP;
6081acd27e7Smillert
6091acd27e7Smillert return (map[ic].function);
6101acd27e7Smillert }
6111acd27e7Smillert else
6121acd27e7Smillert map = FUNCTION_TO_KEYMAP (map, ic);
6131acd27e7Smillert }
6141acd27e7Smillert else
6151acd27e7Smillert {
6161acd27e7Smillert if (type)
6171acd27e7Smillert *type = map[ic].type;
6181acd27e7Smillert
6191acd27e7Smillert return (map[ic].function);
6201acd27e7Smillert }
6211acd27e7Smillert }
622af70c2dfSkettenis return ((rl_command_func_t *) NULL);
6231acd27e7Smillert }
6241acd27e7Smillert
6251acd27e7Smillert /* The last key bindings file read. */
6261acd27e7Smillert static char *last_readline_init_file = (char *)NULL;
6271acd27e7Smillert
6281acd27e7Smillert /* The file we're currently reading key bindings from. */
629af70c2dfSkettenis static const char *current_readline_init_file;
6301acd27e7Smillert static int current_readline_init_include_level;
6311acd27e7Smillert static int current_readline_init_lineno;
6321acd27e7Smillert
6331acd27e7Smillert /* Read FILENAME into a locally-allocated buffer and return the buffer.
6341acd27e7Smillert The size of the buffer is returned in *SIZEP. Returns NULL if any
6351acd27e7Smillert errors were encountered. */
6361acd27e7Smillert static char *
_rl_read_file(filename,sizep)6371acd27e7Smillert _rl_read_file (filename, sizep)
6381acd27e7Smillert char *filename;
6391acd27e7Smillert size_t *sizep;
6401acd27e7Smillert {
6411acd27e7Smillert struct stat finfo;
6421acd27e7Smillert size_t file_size;
6431acd27e7Smillert char *buffer;
6441acd27e7Smillert int i, file;
6451acd27e7Smillert
6461acd27e7Smillert if ((stat (filename, &finfo) < 0) || (file = open (filename, O_RDONLY, 0666)) < 0)
6471acd27e7Smillert return ((char *)NULL);
6481acd27e7Smillert
6491acd27e7Smillert file_size = (size_t)finfo.st_size;
6501acd27e7Smillert
6511acd27e7Smillert /* check for overflow on very large files */
6521acd27e7Smillert if (file_size != finfo.st_size || file_size + 1 < file_size)
6531acd27e7Smillert {
6541acd27e7Smillert if (file >= 0)
6551acd27e7Smillert close (file);
6561acd27e7Smillert #if defined (EFBIG)
6571acd27e7Smillert errno = EFBIG;
6581acd27e7Smillert #endif
6591acd27e7Smillert return ((char *)NULL);
6601acd27e7Smillert }
6611acd27e7Smillert
6621acd27e7Smillert /* Read the file into BUFFER. */
6631acd27e7Smillert buffer = (char *)xmalloc (file_size + 1);
6641acd27e7Smillert i = read (file, buffer, file_size);
6651acd27e7Smillert close (file);
6661acd27e7Smillert
6671acd27e7Smillert if (i < 0)
6681acd27e7Smillert {
6691acd27e7Smillert free (buffer);
6701acd27e7Smillert return ((char *)NULL);
6711acd27e7Smillert }
6721acd27e7Smillert
6731acd27e7Smillert buffer[i] = '\0';
6741acd27e7Smillert if (sizep)
6751acd27e7Smillert *sizep = i;
6761acd27e7Smillert
6771acd27e7Smillert return (buffer);
6781acd27e7Smillert }
6791acd27e7Smillert
6801acd27e7Smillert /* Re-read the current keybindings file. */
6811acd27e7Smillert int
rl_re_read_init_file(count,ignore)6821acd27e7Smillert rl_re_read_init_file (count, ignore)
6831acd27e7Smillert int count, ignore;
6841acd27e7Smillert {
6851acd27e7Smillert int r;
686af70c2dfSkettenis r = rl_read_init_file ((const char *)NULL);
6871acd27e7Smillert rl_set_keymap_from_edit_mode ();
6881acd27e7Smillert return r;
6891acd27e7Smillert }
6901acd27e7Smillert
6911acd27e7Smillert /* Do key bindings from a file. If FILENAME is NULL it defaults
6921acd27e7Smillert to the first non-null filename from this list:
6931acd27e7Smillert 1. the filename used for the previous call
6941acd27e7Smillert 2. the value of the shell variable `INPUTRC'
6951acd27e7Smillert 3. ~/.inputrc
6961acd27e7Smillert If the file existed and could be opened and read, 0 is returned,
6971acd27e7Smillert otherwise errno is returned. */
6981acd27e7Smillert int
rl_read_init_file(filename)6991acd27e7Smillert rl_read_init_file (filename)
700af70c2dfSkettenis const char *filename;
7011acd27e7Smillert {
7021acd27e7Smillert /* Default the filename. */
7031acd27e7Smillert if (filename == 0)
7041acd27e7Smillert {
7051acd27e7Smillert filename = last_readline_init_file;
7061acd27e7Smillert if (filename == 0)
707af70c2dfSkettenis filename = sh_get_env_value ("INPUTRC");
70894bc1d69Smillert if (filename == 0 || *filename == '\0')
7091acd27e7Smillert filename = DEFAULT_INPUTRC;
7101acd27e7Smillert }
7111acd27e7Smillert
7121acd27e7Smillert if (*filename == 0)
7131acd27e7Smillert filename = DEFAULT_INPUTRC;
7141acd27e7Smillert
7151acd27e7Smillert #if defined (__MSDOS__)
7161acd27e7Smillert if (_rl_read_init_file (filename, 0) == 0)
7171acd27e7Smillert return 0;
7181acd27e7Smillert filename = "~/_inputrc";
7191acd27e7Smillert #endif
7201acd27e7Smillert return (_rl_read_init_file (filename, 0));
7211acd27e7Smillert }
7221acd27e7Smillert
7231acd27e7Smillert static int
_rl_read_init_file(filename,include_level)7241acd27e7Smillert _rl_read_init_file (filename, include_level)
725af70c2dfSkettenis const char *filename;
7261acd27e7Smillert int include_level;
7271acd27e7Smillert {
7281acd27e7Smillert register int i;
7291acd27e7Smillert char *buffer, *openname, *line, *end;
7301acd27e7Smillert size_t file_size;
7311acd27e7Smillert
7321acd27e7Smillert current_readline_init_file = filename;
7331acd27e7Smillert current_readline_init_include_level = include_level;
7341acd27e7Smillert
7351acd27e7Smillert openname = tilde_expand (filename);
7361acd27e7Smillert buffer = _rl_read_file (openname, &file_size);
7371acd27e7Smillert free (openname);
7381acd27e7Smillert
7391acd27e7Smillert if (buffer == 0)
7401acd27e7Smillert return (errno);
7411acd27e7Smillert
7421acd27e7Smillert if (include_level == 0 && filename != last_readline_init_file)
7431acd27e7Smillert {
7441acd27e7Smillert FREE (last_readline_init_file);
7451acd27e7Smillert last_readline_init_file = savestring (filename);
7461acd27e7Smillert }
7471acd27e7Smillert
7481acd27e7Smillert currently_reading_init_file = 1;
7491acd27e7Smillert
7501acd27e7Smillert /* Loop over the lines in the file. Lines that start with `#' are
7511acd27e7Smillert comments; all other lines are commands for readline initialization. */
7521acd27e7Smillert current_readline_init_lineno = 1;
7531acd27e7Smillert line = buffer;
7541acd27e7Smillert end = buffer + file_size;
7551acd27e7Smillert while (line < end)
7561acd27e7Smillert {
7571acd27e7Smillert /* Find the end of this line. */
7581acd27e7Smillert for (i = 0; line + i != end && line[i] != '\n'; i++);
7591acd27e7Smillert
760af70c2dfSkettenis #if defined (__CYGWIN__)
7611acd27e7Smillert /* ``Be liberal in what you accept.'' */
7621acd27e7Smillert if (line[i] == '\n' && line[i-1] == '\r')
7631acd27e7Smillert line[i - 1] = '\0';
7641acd27e7Smillert #endif
7651acd27e7Smillert
7661acd27e7Smillert /* Mark end of line. */
7671acd27e7Smillert line[i] = '\0';
7681acd27e7Smillert
7691acd27e7Smillert /* Skip leading whitespace. */
7701acd27e7Smillert while (*line && whitespace (*line))
7711acd27e7Smillert {
7721acd27e7Smillert line++;
7731acd27e7Smillert i--;
7741acd27e7Smillert }
7751acd27e7Smillert
7761acd27e7Smillert /* If the line is not a comment, then parse it. */
7771acd27e7Smillert if (*line && *line != '#')
7781acd27e7Smillert rl_parse_and_bind (line);
7791acd27e7Smillert
7801acd27e7Smillert /* Move to the next line. */
7811acd27e7Smillert line += i + 1;
7821acd27e7Smillert current_readline_init_lineno++;
7831acd27e7Smillert }
7841acd27e7Smillert
7851acd27e7Smillert free (buffer);
7861acd27e7Smillert currently_reading_init_file = 0;
7871acd27e7Smillert return (0);
7881acd27e7Smillert }
7891acd27e7Smillert
7901acd27e7Smillert static void
_rl_init_file_error(msg)7911acd27e7Smillert _rl_init_file_error (msg)
792af70c2dfSkettenis const char *msg;
7931acd27e7Smillert {
7941acd27e7Smillert if (currently_reading_init_file)
7951acd27e7Smillert fprintf (stderr, "readline: %s: line %d: %s\n", current_readline_init_file,
7961acd27e7Smillert current_readline_init_lineno, msg);
7971acd27e7Smillert else
7981acd27e7Smillert fprintf (stderr, "readline: %s\n", msg);
7991acd27e7Smillert }
8001acd27e7Smillert
8011acd27e7Smillert /* **************************************************************** */
8021acd27e7Smillert /* */
8031acd27e7Smillert /* Parser Directives */
8041acd27e7Smillert /* */
8051acd27e7Smillert /* **************************************************************** */
8061acd27e7Smillert
807af70c2dfSkettenis typedef int _rl_parser_func_t PARAMS((char *));
808af70c2dfSkettenis
809af70c2dfSkettenis /* Things that mean `Control'. */
810af70c2dfSkettenis const char *_rl_possible_control_prefixes[] = {
811af70c2dfSkettenis "Control-", "C-", "CTRL-", (const char *)NULL
812af70c2dfSkettenis };
813af70c2dfSkettenis
814af70c2dfSkettenis const char *_rl_possible_meta_prefixes[] = {
815af70c2dfSkettenis "Meta", "M-", (const char *)NULL
816af70c2dfSkettenis };
817af70c2dfSkettenis
8181acd27e7Smillert /* Conditionals. */
8191acd27e7Smillert
8201acd27e7Smillert /* Calling programs set this to have their argv[0]. */
821af70c2dfSkettenis const char *rl_readline_name = "other";
8221acd27e7Smillert
8231acd27e7Smillert /* Stack of previous values of parsing_conditionalized_out. */
8241acd27e7Smillert static unsigned char *if_stack = (unsigned char *)NULL;
8251acd27e7Smillert static int if_stack_depth;
8261acd27e7Smillert static int if_stack_size;
8271acd27e7Smillert
8281acd27e7Smillert /* Push _rl_parsing_conditionalized_out, and set parser state based
8291acd27e7Smillert on ARGS. */
8301acd27e7Smillert static int
parser_if(args)8311acd27e7Smillert parser_if (args)
8321acd27e7Smillert char *args;
8331acd27e7Smillert {
8341acd27e7Smillert register int i;
8351acd27e7Smillert
8361acd27e7Smillert /* Push parser state. */
8371acd27e7Smillert if (if_stack_depth + 1 >= if_stack_size)
8381acd27e7Smillert {
8391acd27e7Smillert if (!if_stack)
8401acd27e7Smillert if_stack = (unsigned char *)xmalloc (if_stack_size = 20);
8411acd27e7Smillert else
8421acd27e7Smillert if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20);
8431acd27e7Smillert }
8441acd27e7Smillert if_stack[if_stack_depth++] = _rl_parsing_conditionalized_out;
8451acd27e7Smillert
8461acd27e7Smillert /* If parsing is turned off, then nothing can turn it back on except
8471acd27e7Smillert for finding the matching endif. In that case, return right now. */
8481acd27e7Smillert if (_rl_parsing_conditionalized_out)
8491acd27e7Smillert return 0;
8501acd27e7Smillert
8511acd27e7Smillert /* Isolate first argument. */
8521acd27e7Smillert for (i = 0; args[i] && !whitespace (args[i]); i++);
8531acd27e7Smillert
8541acd27e7Smillert if (args[i])
8551acd27e7Smillert args[i++] = '\0';
8561acd27e7Smillert
8571acd27e7Smillert /* Handle "$if term=foo" and "$if mode=emacs" constructs. If this
8581acd27e7Smillert isn't term=foo, or mode=emacs, then check to see if the first
8591acd27e7Smillert word in ARGS is the same as the value stored in rl_readline_name. */
8601acd27e7Smillert if (rl_terminal_name && _rl_strnicmp (args, "term=", 5) == 0)
8611acd27e7Smillert {
8621acd27e7Smillert char *tem, *tname;
8631acd27e7Smillert
8641acd27e7Smillert /* Terminals like "aaa-60" are equivalent to "aaa". */
8651acd27e7Smillert tname = savestring (rl_terminal_name);
8661acd27e7Smillert tem = strchr (tname, '-');
8671acd27e7Smillert if (tem)
8681acd27e7Smillert *tem = '\0';
8691acd27e7Smillert
8701acd27e7Smillert /* Test the `long' and `short' forms of the terminal name so that
8711acd27e7Smillert if someone has a `sun-cmd' and does not want to have bindings
8721acd27e7Smillert that will be executed if the terminal is a `sun', they can put
8731acd27e7Smillert `$if term=sun-cmd' into their .inputrc. */
8741acd27e7Smillert _rl_parsing_conditionalized_out = _rl_stricmp (args + 5, tname) &&
8751acd27e7Smillert _rl_stricmp (args + 5, rl_terminal_name);
8761acd27e7Smillert free (tname);
8771acd27e7Smillert }
8781acd27e7Smillert #if defined (VI_MODE)
8791acd27e7Smillert else if (_rl_strnicmp (args, "mode=", 5) == 0)
8801acd27e7Smillert {
8811acd27e7Smillert int mode;
8821acd27e7Smillert
8831acd27e7Smillert if (_rl_stricmp (args + 5, "emacs") == 0)
8841acd27e7Smillert mode = emacs_mode;
8851acd27e7Smillert else if (_rl_stricmp (args + 5, "vi") == 0)
8861acd27e7Smillert mode = vi_mode;
8871acd27e7Smillert else
8881acd27e7Smillert mode = no_mode;
8891acd27e7Smillert
8901acd27e7Smillert _rl_parsing_conditionalized_out = mode != rl_editing_mode;
8911acd27e7Smillert }
8921acd27e7Smillert #endif /* VI_MODE */
8931acd27e7Smillert /* Check to see if the first word in ARGS is the same as the
8941acd27e7Smillert value stored in rl_readline_name. */
8951acd27e7Smillert else if (_rl_stricmp (args, rl_readline_name) == 0)
8961acd27e7Smillert _rl_parsing_conditionalized_out = 0;
8971acd27e7Smillert else
8981acd27e7Smillert _rl_parsing_conditionalized_out = 1;
8991acd27e7Smillert return 0;
9001acd27e7Smillert }
9011acd27e7Smillert
9021acd27e7Smillert /* Invert the current parser state if there is anything on the stack. */
9031acd27e7Smillert static int
parser_else(args)9041acd27e7Smillert parser_else (args)
9051acd27e7Smillert char *args;
9061acd27e7Smillert {
9071acd27e7Smillert register int i;
9081acd27e7Smillert
9091acd27e7Smillert if (if_stack_depth == 0)
9101acd27e7Smillert {
9111acd27e7Smillert _rl_init_file_error ("$else found without matching $if");
9121acd27e7Smillert return 0;
9131acd27e7Smillert }
9141acd27e7Smillert
9151acd27e7Smillert /* Check the previous (n - 1) levels of the stack to make sure that
9161acd27e7Smillert we haven't previously turned off parsing. */
9171acd27e7Smillert for (i = 0; i < if_stack_depth - 1; i++)
9181acd27e7Smillert if (if_stack[i] == 1)
9191acd27e7Smillert return 0;
9201acd27e7Smillert
9211acd27e7Smillert /* Invert the state of parsing if at top level. */
9221acd27e7Smillert _rl_parsing_conditionalized_out = !_rl_parsing_conditionalized_out;
9231acd27e7Smillert return 0;
9241acd27e7Smillert }
9251acd27e7Smillert
9261acd27e7Smillert /* Terminate a conditional, popping the value of
9271acd27e7Smillert _rl_parsing_conditionalized_out from the stack. */
9281acd27e7Smillert static int
parser_endif(args)9291acd27e7Smillert parser_endif (args)
9301acd27e7Smillert char *args;
9311acd27e7Smillert {
9321acd27e7Smillert if (if_stack_depth)
9331acd27e7Smillert _rl_parsing_conditionalized_out = if_stack[--if_stack_depth];
9341acd27e7Smillert else
9351acd27e7Smillert _rl_init_file_error ("$endif without matching $if");
9361acd27e7Smillert return 0;
9371acd27e7Smillert }
9381acd27e7Smillert
9391acd27e7Smillert static int
parser_include(args)9401acd27e7Smillert parser_include (args)
9411acd27e7Smillert char *args;
9421acd27e7Smillert {
943af70c2dfSkettenis const char *old_init_file;
944af70c2dfSkettenis char *e;
9451acd27e7Smillert int old_line_number, old_include_level, r;
9461acd27e7Smillert
9471acd27e7Smillert if (_rl_parsing_conditionalized_out)
9481acd27e7Smillert return (0);
9491acd27e7Smillert
9501acd27e7Smillert old_init_file = current_readline_init_file;
9511acd27e7Smillert old_line_number = current_readline_init_lineno;
9521acd27e7Smillert old_include_level = current_readline_init_include_level;
9531acd27e7Smillert
9541acd27e7Smillert e = strchr (args, '\n');
9551acd27e7Smillert if (e)
9561acd27e7Smillert *e = '\0';
957af70c2dfSkettenis r = _rl_read_init_file ((const char *)args, old_include_level + 1);
9581acd27e7Smillert
9591acd27e7Smillert current_readline_init_file = old_init_file;
9601acd27e7Smillert current_readline_init_lineno = old_line_number;
9611acd27e7Smillert current_readline_init_include_level = old_include_level;
9621acd27e7Smillert
9631acd27e7Smillert return r;
9641acd27e7Smillert }
9651acd27e7Smillert
9661acd27e7Smillert /* Associate textual names with actual functions. */
9671acd27e7Smillert static struct {
968af70c2dfSkettenis const char *name;
969af70c2dfSkettenis _rl_parser_func_t *function;
9701acd27e7Smillert } parser_directives [] = {
9711acd27e7Smillert { "if", parser_if },
9721acd27e7Smillert { "endif", parser_endif },
9731acd27e7Smillert { "else", parser_else },
9741acd27e7Smillert { "include", parser_include },
975af70c2dfSkettenis { (char *)0x0, (_rl_parser_func_t *)0x0 }
9761acd27e7Smillert };
9771acd27e7Smillert
9781acd27e7Smillert /* Handle a parser directive. STATEMENT is the line of the directive
9791acd27e7Smillert without any leading `$'. */
9801acd27e7Smillert static int
handle_parser_directive(statement)9811acd27e7Smillert handle_parser_directive (statement)
9821acd27e7Smillert char *statement;
9831acd27e7Smillert {
9841acd27e7Smillert register int i;
9851acd27e7Smillert char *directive, *args;
9861acd27e7Smillert
9871acd27e7Smillert /* Isolate the actual directive. */
9881acd27e7Smillert
9891acd27e7Smillert /* Skip whitespace. */
9901acd27e7Smillert for (i = 0; whitespace (statement[i]); i++);
9911acd27e7Smillert
9921acd27e7Smillert directive = &statement[i];
9931acd27e7Smillert
9941acd27e7Smillert for (; statement[i] && !whitespace (statement[i]); i++);
9951acd27e7Smillert
9961acd27e7Smillert if (statement[i])
9971acd27e7Smillert statement[i++] = '\0';
9981acd27e7Smillert
9991acd27e7Smillert for (; statement[i] && whitespace (statement[i]); i++);
10001acd27e7Smillert
10011acd27e7Smillert args = &statement[i];
10021acd27e7Smillert
10031acd27e7Smillert /* Lookup the command, and act on it. */
10041acd27e7Smillert for (i = 0; parser_directives[i].name; i++)
10051acd27e7Smillert if (_rl_stricmp (directive, parser_directives[i].name) == 0)
10061acd27e7Smillert {
10071acd27e7Smillert (*parser_directives[i].function) (args);
10081acd27e7Smillert return (0);
10091acd27e7Smillert }
10101acd27e7Smillert
10111acd27e7Smillert /* display an error message about the unknown parser directive */
10121acd27e7Smillert _rl_init_file_error ("unknown parser directive");
10131acd27e7Smillert return (1);
10141acd27e7Smillert }
10151acd27e7Smillert
10161acd27e7Smillert /* Read the binding command from STRING and perform it.
10171acd27e7Smillert A key binding command looks like: Keyname: function-name\0,
10181acd27e7Smillert a variable binding command looks like: set variable value.
10191acd27e7Smillert A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */
10201acd27e7Smillert int
rl_parse_and_bind(string)10211acd27e7Smillert rl_parse_and_bind (string)
10221acd27e7Smillert char *string;
10231acd27e7Smillert {
10241acd27e7Smillert char *funname, *kname;
10251acd27e7Smillert register int c, i;
10261acd27e7Smillert int key, equivalency;
10271acd27e7Smillert
10281acd27e7Smillert while (string && whitespace (*string))
10291acd27e7Smillert string++;
10301acd27e7Smillert
10311acd27e7Smillert if (!string || !*string || *string == '#')
10321acd27e7Smillert return 0;
10331acd27e7Smillert
10341acd27e7Smillert /* If this is a parser directive, act on it. */
10351acd27e7Smillert if (*string == '$')
10361acd27e7Smillert {
10371acd27e7Smillert handle_parser_directive (&string[1]);
10381acd27e7Smillert return 0;
10391acd27e7Smillert }
10401acd27e7Smillert
10411acd27e7Smillert /* If we aren't supposed to be parsing right now, then we're done. */
10421acd27e7Smillert if (_rl_parsing_conditionalized_out)
10431acd27e7Smillert return 0;
10441acd27e7Smillert
10451acd27e7Smillert i = 0;
10461acd27e7Smillert /* If this keyname is a complex key expression surrounded by quotes,
10471acd27e7Smillert advance to after the matching close quote. This code allows the
10481acd27e7Smillert backslash to quote characters in the key expression. */
10491acd27e7Smillert if (*string == '"')
10501acd27e7Smillert {
10511acd27e7Smillert int passc = 0;
10521acd27e7Smillert
1053*af1e7b8cSkrw for (i = 1; (c = string[i]); i++)
10541acd27e7Smillert {
10551acd27e7Smillert if (passc)
10561acd27e7Smillert {
10571acd27e7Smillert passc = 0;
10581acd27e7Smillert continue;
10591acd27e7Smillert }
10601acd27e7Smillert
10611acd27e7Smillert if (c == '\\')
10621acd27e7Smillert {
10631acd27e7Smillert passc++;
10641acd27e7Smillert continue;
10651acd27e7Smillert }
10661acd27e7Smillert
10671acd27e7Smillert if (c == '"')
10681acd27e7Smillert break;
10691acd27e7Smillert }
10701acd27e7Smillert /* If we didn't find a closing quote, abort the line. */
10711acd27e7Smillert if (string[i] == '\0')
10721acd27e7Smillert {
10731acd27e7Smillert _rl_init_file_error ("no closing `\"' in key binding");
10741acd27e7Smillert return 1;
10751acd27e7Smillert }
10761acd27e7Smillert }
10771acd27e7Smillert
10781acd27e7Smillert /* Advance to the colon (:) or whitespace which separates the two objects. */
10791acd27e7Smillert for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ );
10801acd27e7Smillert
10811acd27e7Smillert equivalency = (c == ':' && string[i + 1] == '=');
10821acd27e7Smillert
10831acd27e7Smillert /* Mark the end of the command (or keyname). */
10841acd27e7Smillert if (string[i])
10851acd27e7Smillert string[i++] = '\0';
10861acd27e7Smillert
10871acd27e7Smillert /* If doing assignment, skip the '=' sign as well. */
10881acd27e7Smillert if (equivalency)
10891acd27e7Smillert string[i++] = '\0';
10901acd27e7Smillert
10911acd27e7Smillert /* If this is a command to set a variable, then do that. */
10921acd27e7Smillert if (_rl_stricmp (string, "set") == 0)
10931acd27e7Smillert {
10941acd27e7Smillert char *var = string + i;
10951acd27e7Smillert char *value;
10961acd27e7Smillert
10971acd27e7Smillert /* Make VAR point to start of variable name. */
10981acd27e7Smillert while (*var && whitespace (*var)) var++;
10991acd27e7Smillert
1100af70c2dfSkettenis /* Make VALUE point to start of value string. */
11011acd27e7Smillert value = var;
11021acd27e7Smillert while (*value && !whitespace (*value)) value++;
11031acd27e7Smillert if (*value)
11041acd27e7Smillert *value++ = '\0';
11051acd27e7Smillert while (*value && whitespace (*value)) value++;
11061acd27e7Smillert
11071acd27e7Smillert rl_variable_bind (var, value);
11081acd27e7Smillert return 0;
11091acd27e7Smillert }
11101acd27e7Smillert
11111acd27e7Smillert /* Skip any whitespace between keyname and funname. */
11121acd27e7Smillert for (; string[i] && whitespace (string[i]); i++);
11131acd27e7Smillert funname = &string[i];
11141acd27e7Smillert
11151acd27e7Smillert /* Now isolate funname.
11161acd27e7Smillert For straight function names just look for whitespace, since
11171acd27e7Smillert that will signify the end of the string. But this could be a
11181acd27e7Smillert macro definition. In that case, the string is quoted, so skip
11191acd27e7Smillert to the matching delimiter. We allow the backslash to quote the
11201acd27e7Smillert delimiter characters in the macro body. */
11211acd27e7Smillert /* This code exists to allow whitespace in macro expansions, which
11221acd27e7Smillert would otherwise be gobbled up by the next `for' loop.*/
11231acd27e7Smillert /* XXX - it may be desirable to allow backslash quoting only if " is
11241acd27e7Smillert the quoted string delimiter, like the shell. */
11251acd27e7Smillert if (*funname == '\'' || *funname == '"')
11261acd27e7Smillert {
11271acd27e7Smillert int delimiter = string[i++], passc;
11281acd27e7Smillert
1129*af1e7b8cSkrw for (passc = 0; (c = string[i]); i++)
11301acd27e7Smillert {
11311acd27e7Smillert if (passc)
11321acd27e7Smillert {
11331acd27e7Smillert passc = 0;
11341acd27e7Smillert continue;
11351acd27e7Smillert }
11361acd27e7Smillert
11371acd27e7Smillert if (c == '\\')
11381acd27e7Smillert {
11391acd27e7Smillert passc = 1;
11401acd27e7Smillert continue;
11411acd27e7Smillert }
11421acd27e7Smillert
11431acd27e7Smillert if (c == delimiter)
11441acd27e7Smillert break;
11451acd27e7Smillert }
11461acd27e7Smillert if (c)
11471acd27e7Smillert i++;
11481acd27e7Smillert }
11491acd27e7Smillert
11501acd27e7Smillert /* Advance to the end of the string. */
11511acd27e7Smillert for (; string[i] && !whitespace (string[i]); i++);
11521acd27e7Smillert
11531acd27e7Smillert /* No extra whitespace at the end of the string. */
11541acd27e7Smillert string[i] = '\0';
11551acd27e7Smillert
11561acd27e7Smillert /* Handle equivalency bindings here. Make the left-hand side be exactly
11571acd27e7Smillert whatever the right-hand evaluates to, including keymaps. */
11581acd27e7Smillert if (equivalency)
11591acd27e7Smillert {
11601acd27e7Smillert return 0;
11611acd27e7Smillert }
11621acd27e7Smillert
11631acd27e7Smillert /* If this is a new-style key-binding, then do the binding with
11641acd27e7Smillert rl_set_key (). Otherwise, let the older code deal with it. */
11651acd27e7Smillert if (*string == '"')
11661acd27e7Smillert {
11671acd27e7Smillert char *seq;
11681acd27e7Smillert register int j, k, passc;
11691acd27e7Smillert
1170af70c2dfSkettenis seq = (char *)xmalloc (1 + strlen (string));
11711acd27e7Smillert for (j = 1, k = passc = 0; string[j]; j++)
11721acd27e7Smillert {
11731acd27e7Smillert /* Allow backslash to quote characters, but leave them in place.
11741acd27e7Smillert This allows a string to end with a backslash quoting another
11751acd27e7Smillert backslash, or with a backslash quoting a double quote. The
11761acd27e7Smillert backslashes are left in place for rl_translate_keyseq (). */
11771acd27e7Smillert if (passc || (string[j] == '\\'))
11781acd27e7Smillert {
11791acd27e7Smillert seq[k++] = string[j];
11801acd27e7Smillert passc = !passc;
11811acd27e7Smillert continue;
11821acd27e7Smillert }
11831acd27e7Smillert
11841acd27e7Smillert if (string[j] == '"')
11851acd27e7Smillert break;
11861acd27e7Smillert
11871acd27e7Smillert seq[k++] = string[j];
11881acd27e7Smillert }
11891acd27e7Smillert seq[k] = '\0';
11901acd27e7Smillert
11911acd27e7Smillert /* Binding macro? */
11921acd27e7Smillert if (*funname == '\'' || *funname == '"')
11931acd27e7Smillert {
11941acd27e7Smillert j = strlen (funname);
11951acd27e7Smillert
11961acd27e7Smillert /* Remove the delimiting quotes from each end of FUNNAME. */
11971acd27e7Smillert if (j && funname[j - 1] == *funname)
11981acd27e7Smillert funname[j - 1] = '\0';
11991acd27e7Smillert
12001acd27e7Smillert rl_macro_bind (seq, &funname[1], _rl_keymap);
12011acd27e7Smillert }
12021acd27e7Smillert else
12031acd27e7Smillert rl_set_key (seq, rl_named_function (funname), _rl_keymap);
12041acd27e7Smillert
12051acd27e7Smillert free (seq);
12061acd27e7Smillert return 0;
12071acd27e7Smillert }
12081acd27e7Smillert
12091acd27e7Smillert /* Get the actual character we want to deal with. */
12101acd27e7Smillert kname = strrchr (string, '-');
12111acd27e7Smillert if (!kname)
12121acd27e7Smillert kname = string;
12131acd27e7Smillert else
12141acd27e7Smillert kname++;
12151acd27e7Smillert
12161acd27e7Smillert key = glean_key_from_name (kname);
12171acd27e7Smillert
12181acd27e7Smillert /* Add in control and meta bits. */
1219af70c2dfSkettenis if (substring_member_of_array (string, _rl_possible_control_prefixes))
12201acd27e7Smillert key = CTRL (_rl_to_upper (key));
12211acd27e7Smillert
1222af70c2dfSkettenis if (substring_member_of_array (string, _rl_possible_meta_prefixes))
12231acd27e7Smillert key = META (key);
12241acd27e7Smillert
12251acd27e7Smillert /* Temporary. Handle old-style keyname with macro-binding. */
12261acd27e7Smillert if (*funname == '\'' || *funname == '"')
12271acd27e7Smillert {
1228af70c2dfSkettenis char useq[2];
12291acd27e7Smillert int fl = strlen (funname);
12301acd27e7Smillert
12311acd27e7Smillert useq[0] = key; useq[1] = '\0';
12321acd27e7Smillert if (fl && funname[fl - 1] == *funname)
12331acd27e7Smillert funname[fl - 1] = '\0';
12341acd27e7Smillert
12351acd27e7Smillert rl_macro_bind (useq, &funname[1], _rl_keymap);
12361acd27e7Smillert }
12371acd27e7Smillert #if defined (PREFIX_META_HACK)
12381acd27e7Smillert /* Ugly, but working hack to keep prefix-meta around. */
12391acd27e7Smillert else if (_rl_stricmp (funname, "prefix-meta") == 0)
12401acd27e7Smillert {
12411acd27e7Smillert char seq[2];
12421acd27e7Smillert
12431acd27e7Smillert seq[0] = key;
12441acd27e7Smillert seq[1] = '\0';
12451acd27e7Smillert rl_generic_bind (ISKMAP, seq, (char *)emacs_meta_keymap, _rl_keymap);
12461acd27e7Smillert }
12471acd27e7Smillert #endif /* PREFIX_META_HACK */
12481acd27e7Smillert else
12491acd27e7Smillert rl_bind_key (key, rl_named_function (funname));
12501acd27e7Smillert return 0;
12511acd27e7Smillert }
12521acd27e7Smillert
12531acd27e7Smillert /* Simple structure for boolean readline variables (i.e., those that can
12541acd27e7Smillert have one of two values; either "On" or 1 for truth, or "Off" or 0 for
12551acd27e7Smillert false. */
12561acd27e7Smillert
12571acd27e7Smillert #define V_SPECIAL 0x1
12581acd27e7Smillert
12591acd27e7Smillert static struct {
1260af70c2dfSkettenis const char *name;
12611acd27e7Smillert int *value;
12621acd27e7Smillert int flags;
12631acd27e7Smillert } boolean_varlist [] = {
12641acd27e7Smillert { "blink-matching-paren", &rl_blink_matching_paren, V_SPECIAL },
1265af70c2dfSkettenis { "byte-oriented", &rl_byte_oriented, 0 },
12661acd27e7Smillert { "completion-ignore-case", &_rl_completion_case_fold, 0 },
12671acd27e7Smillert { "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 },
12681acd27e7Smillert { "disable-completion", &rl_inhibit_completion, 0 },
12691acd27e7Smillert { "enable-keypad", &_rl_enable_keypad, 0 },
12701acd27e7Smillert { "expand-tilde", &rl_complete_with_tilde_expansion, 0 },
1271af70c2dfSkettenis { "history-preserve-point", &_rl_history_preserve_point, 0 },
12721acd27e7Smillert { "horizontal-scroll-mode", &_rl_horizontal_scroll_mode, 0 },
12731acd27e7Smillert { "input-meta", &_rl_meta_flag, 0 },
12741acd27e7Smillert { "mark-directories", &_rl_complete_mark_directories, 0 },
12751acd27e7Smillert { "mark-modified-lines", &_rl_mark_modified_lines, 0 },
1276af70c2dfSkettenis { "mark-symlinked-directories", &_rl_complete_mark_symlink_dirs, 0 },
1277af70c2dfSkettenis { "match-hidden-files", &_rl_match_hidden_files, 0 },
12781acd27e7Smillert { "meta-flag", &_rl_meta_flag, 0 },
12791acd27e7Smillert { "output-meta", &_rl_output_meta_chars, 0 },
1280af70c2dfSkettenis { "page-completions", &_rl_page_completions, 0 },
12811acd27e7Smillert { "prefer-visible-bell", &_rl_prefer_visible_bell, V_SPECIAL },
12821acd27e7Smillert { "print-completions-horizontally", &_rl_print_completions_horizontally, 0 },
12831acd27e7Smillert { "show-all-if-ambiguous", &_rl_complete_show_all, 0 },
12841acd27e7Smillert #if defined (VISIBLE_STATS)
12851acd27e7Smillert { "visible-stats", &rl_visible_stats, 0 },
12861acd27e7Smillert #endif /* VISIBLE_STATS */
12871acd27e7Smillert { (char *)NULL, (int *)NULL }
12881acd27e7Smillert };
12891acd27e7Smillert
12901acd27e7Smillert static int
find_boolean_var(name)12911acd27e7Smillert find_boolean_var (name)
1292af70c2dfSkettenis const char *name;
12931acd27e7Smillert {
12941acd27e7Smillert register int i;
12951acd27e7Smillert
12961acd27e7Smillert for (i = 0; boolean_varlist[i].name; i++)
12971acd27e7Smillert if (_rl_stricmp (name, boolean_varlist[i].name) == 0)
12981acd27e7Smillert return i;
12991acd27e7Smillert return -1;
13001acd27e7Smillert }
13011acd27e7Smillert
13021acd27e7Smillert /* Hooks for handling special boolean variables, where a
13031acd27e7Smillert function needs to be called or another variable needs
13041acd27e7Smillert to be changed when they're changed. */
13051acd27e7Smillert static void
hack_special_boolean_var(i)13061acd27e7Smillert hack_special_boolean_var (i)
13071acd27e7Smillert int i;
13081acd27e7Smillert {
1309af70c2dfSkettenis const char *name;
13101acd27e7Smillert
13111acd27e7Smillert name = boolean_varlist[i].name;
13121acd27e7Smillert
13131acd27e7Smillert if (_rl_stricmp (name, "blink-matching-paren") == 0)
13141acd27e7Smillert _rl_enable_paren_matching (rl_blink_matching_paren);
13151acd27e7Smillert else if (_rl_stricmp (name, "prefer-visible-bell") == 0)
13161acd27e7Smillert {
13171acd27e7Smillert if (_rl_prefer_visible_bell)
13181acd27e7Smillert _rl_bell_preference = VISIBLE_BELL;
13191acd27e7Smillert else
13201acd27e7Smillert _rl_bell_preference = AUDIBLE_BELL;
13211acd27e7Smillert }
13221acd27e7Smillert }
13231acd27e7Smillert
1324af70c2dfSkettenis typedef int _rl_sv_func_t PARAMS((const char *));
1325af70c2dfSkettenis
13261acd27e7Smillert /* These *must* correspond to the array indices for the appropriate
13271acd27e7Smillert string variable. (Though they're not used right now.) */
13281acd27e7Smillert #define V_BELLSTYLE 0
13291acd27e7Smillert #define V_COMBEGIN 1
13301acd27e7Smillert #define V_EDITMODE 2
13311acd27e7Smillert #define V_ISRCHTERM 3
13321acd27e7Smillert #define V_KEYMAP 4
13331acd27e7Smillert
13341acd27e7Smillert #define V_STRING 1
13351acd27e7Smillert #define V_INT 2
13361acd27e7Smillert
13371acd27e7Smillert /* Forward declarations */
1338af70c2dfSkettenis static int sv_bell_style PARAMS((const char *));
1339af70c2dfSkettenis static int sv_combegin PARAMS((const char *));
1340af70c2dfSkettenis static int sv_compquery PARAMS((const char *));
1341af70c2dfSkettenis static int sv_editmode PARAMS((const char *));
1342af70c2dfSkettenis static int sv_isrchterm PARAMS((const char *));
1343af70c2dfSkettenis static int sv_keymap PARAMS((const char *));
13441acd27e7Smillert
13451acd27e7Smillert static struct {
1346af70c2dfSkettenis const char *name;
13471acd27e7Smillert int flags;
1348af70c2dfSkettenis _rl_sv_func_t *set_func;
13491acd27e7Smillert } string_varlist[] = {
13501acd27e7Smillert { "bell-style", V_STRING, sv_bell_style },
13511acd27e7Smillert { "comment-begin", V_STRING, sv_combegin },
13521acd27e7Smillert { "completion-query-items", V_INT, sv_compquery },
13531acd27e7Smillert { "editing-mode", V_STRING, sv_editmode },
13541acd27e7Smillert { "isearch-terminators", V_STRING, sv_isrchterm },
13551acd27e7Smillert { "keymap", V_STRING, sv_keymap },
13561acd27e7Smillert { (char *)NULL, 0 }
13571acd27e7Smillert };
13581acd27e7Smillert
13591acd27e7Smillert static int
find_string_var(name)13601acd27e7Smillert find_string_var (name)
1361af70c2dfSkettenis const char *name;
13621acd27e7Smillert {
13631acd27e7Smillert register int i;
13641acd27e7Smillert
13651acd27e7Smillert for (i = 0; string_varlist[i].name; i++)
13661acd27e7Smillert if (_rl_stricmp (name, string_varlist[i].name) == 0)
13671acd27e7Smillert return i;
13681acd27e7Smillert return -1;
13691acd27e7Smillert }
13701acd27e7Smillert
13711acd27e7Smillert /* A boolean value that can appear in a `set variable' command is true if
13721acd27e7Smillert the value is null or empty, `on' (case-insenstive), or "1". Any other
13731acd27e7Smillert values result in 0 (false). */
13741acd27e7Smillert static int
bool_to_int(value)13751acd27e7Smillert bool_to_int (value)
1376*af1e7b8cSkrw const char *value;
13771acd27e7Smillert {
13781acd27e7Smillert return (value == 0 || *value == '\0' ||
13791acd27e7Smillert (_rl_stricmp (value, "on") == 0) ||
13801acd27e7Smillert (value[0] == '1' && value[1] == '\0'));
13811acd27e7Smillert }
13821acd27e7Smillert
13831acd27e7Smillert int
rl_variable_bind(name,value)13841acd27e7Smillert rl_variable_bind (name, value)
1385af70c2dfSkettenis const char *name, *value;
13861acd27e7Smillert {
13871acd27e7Smillert register int i;
13881acd27e7Smillert int v;
13891acd27e7Smillert
13901acd27e7Smillert /* Check for simple variables first. */
13911acd27e7Smillert i = find_boolean_var (name);
13921acd27e7Smillert if (i >= 0)
13931acd27e7Smillert {
13941acd27e7Smillert *boolean_varlist[i].value = bool_to_int (value);
13951acd27e7Smillert if (boolean_varlist[i].flags & V_SPECIAL)
13961acd27e7Smillert hack_special_boolean_var (i);
13971acd27e7Smillert return 0;
13981acd27e7Smillert }
13991acd27e7Smillert
14001acd27e7Smillert i = find_string_var (name);
14011acd27e7Smillert
14021acd27e7Smillert /* For the time being, unknown variable names or string names without a
14031acd27e7Smillert handler function are simply ignored. */
14041acd27e7Smillert if (i < 0 || string_varlist[i].set_func == 0)
14051acd27e7Smillert return 0;
14061acd27e7Smillert
14071acd27e7Smillert v = (*string_varlist[i].set_func) (value);
14081acd27e7Smillert return v;
14091acd27e7Smillert }
14101acd27e7Smillert
14111acd27e7Smillert static int
sv_editmode(value)14121acd27e7Smillert sv_editmode (value)
1413af70c2dfSkettenis const char *value;
14141acd27e7Smillert {
14151acd27e7Smillert if (_rl_strnicmp (value, "vi", 2) == 0)
14161acd27e7Smillert {
14171acd27e7Smillert #if defined (VI_MODE)
14181acd27e7Smillert _rl_keymap = vi_insertion_keymap;
14191acd27e7Smillert rl_editing_mode = vi_mode;
14201acd27e7Smillert #endif /* VI_MODE */
14211acd27e7Smillert return 0;
14221acd27e7Smillert }
14231acd27e7Smillert else if (_rl_strnicmp (value, "emacs", 5) == 0)
14241acd27e7Smillert {
14251acd27e7Smillert _rl_keymap = emacs_standard_keymap;
14261acd27e7Smillert rl_editing_mode = emacs_mode;
14271acd27e7Smillert return 0;
14281acd27e7Smillert }
14291acd27e7Smillert return 1;
14301acd27e7Smillert }
14311acd27e7Smillert
14321acd27e7Smillert static int
sv_combegin(value)14331acd27e7Smillert sv_combegin (value)
1434af70c2dfSkettenis const char *value;
14351acd27e7Smillert {
14361acd27e7Smillert if (value && *value)
14371acd27e7Smillert {
14381acd27e7Smillert FREE (_rl_comment_begin);
14391acd27e7Smillert _rl_comment_begin = savestring (value);
14401acd27e7Smillert return 0;
14411acd27e7Smillert }
14421acd27e7Smillert return 1;
14431acd27e7Smillert }
14441acd27e7Smillert
14451acd27e7Smillert static int
sv_compquery(value)14461acd27e7Smillert sv_compquery (value)
1447af70c2dfSkettenis const char *value;
14481acd27e7Smillert {
14491acd27e7Smillert int nval = 100;
14501acd27e7Smillert
14511acd27e7Smillert if (value && *value)
14521acd27e7Smillert {
14531acd27e7Smillert nval = atoi (value);
14541acd27e7Smillert if (nval < 0)
14551acd27e7Smillert nval = 0;
14561acd27e7Smillert }
14571acd27e7Smillert rl_completion_query_items = nval;
14581acd27e7Smillert return 0;
14591acd27e7Smillert }
14601acd27e7Smillert
14611acd27e7Smillert static int
sv_keymap(value)14621acd27e7Smillert sv_keymap (value)
1463af70c2dfSkettenis const char *value;
14641acd27e7Smillert {
14651acd27e7Smillert Keymap kmap;
14661acd27e7Smillert
14671acd27e7Smillert kmap = rl_get_keymap_by_name (value);
14681acd27e7Smillert if (kmap)
14691acd27e7Smillert {
14701acd27e7Smillert rl_set_keymap (kmap);
14711acd27e7Smillert return 0;
14721acd27e7Smillert }
14731acd27e7Smillert return 1;
14741acd27e7Smillert }
14751acd27e7Smillert
14761acd27e7Smillert static int
sv_bell_style(value)14771acd27e7Smillert sv_bell_style (value)
1478af70c2dfSkettenis const char *value;
14791acd27e7Smillert {
14801acd27e7Smillert if (value == 0 || *value == '\0')
1481af70c2dfSkettenis _rl_bell_preference = AUDIBLE_BELL;
14821acd27e7Smillert else if (_rl_stricmp (value, "none") == 0 || _rl_stricmp (value, "off") == 0)
1483af70c2dfSkettenis _rl_bell_preference = NO_BELL;
14841acd27e7Smillert else if (_rl_stricmp (value, "audible") == 0 || _rl_stricmp (value, "on") == 0)
1485af70c2dfSkettenis _rl_bell_preference = AUDIBLE_BELL;
14861acd27e7Smillert else if (_rl_stricmp (value, "visible") == 0)
1487af70c2dfSkettenis _rl_bell_preference = VISIBLE_BELL;
14881acd27e7Smillert else
14891acd27e7Smillert return 1;
1490af70c2dfSkettenis return 0;
14911acd27e7Smillert }
14921acd27e7Smillert
14931acd27e7Smillert static int
sv_isrchterm(value)14941acd27e7Smillert sv_isrchterm (value)
1495af70c2dfSkettenis const char *value;
14961acd27e7Smillert {
14971acd27e7Smillert int beg, end, delim;
14981acd27e7Smillert char *v;
14991acd27e7Smillert
15001acd27e7Smillert if (value == 0)
15011acd27e7Smillert return 1;
15021acd27e7Smillert
15031acd27e7Smillert /* Isolate the value and translate it into a character string. */
15041acd27e7Smillert v = savestring (value);
15051acd27e7Smillert FREE (_rl_isearch_terminators);
15061acd27e7Smillert if (v[0] == '"' || v[0] == '\'')
15071acd27e7Smillert {
15081acd27e7Smillert delim = v[0];
15091acd27e7Smillert for (beg = end = 1; v[end] && v[end] != delim; end++)
15101acd27e7Smillert ;
15111acd27e7Smillert }
15121acd27e7Smillert else
15131acd27e7Smillert {
15141acd27e7Smillert for (beg = end = 0; whitespace (v[end]) == 0; end++)
15151acd27e7Smillert ;
15161acd27e7Smillert }
15171acd27e7Smillert
15181acd27e7Smillert v[end] = '\0';
15191acd27e7Smillert
15201acd27e7Smillert /* The value starts at v + beg. Translate it into a character string. */
1521af70c2dfSkettenis _rl_isearch_terminators = (char *)xmalloc (2 * strlen (v) + 1);
15221acd27e7Smillert rl_translate_keyseq (v + beg, _rl_isearch_terminators, &end);
15231acd27e7Smillert _rl_isearch_terminators[end] = '\0';
15241acd27e7Smillert
15251acd27e7Smillert free (v);
15261acd27e7Smillert return 0;
15271acd27e7Smillert }
15281acd27e7Smillert
15291acd27e7Smillert /* Return the character which matches NAME.
15301acd27e7Smillert For example, `Space' returns ' '. */
15311acd27e7Smillert
15321acd27e7Smillert typedef struct {
1533af70c2dfSkettenis const char *name;
15341acd27e7Smillert int value;
15351acd27e7Smillert } assoc_list;
15361acd27e7Smillert
15371acd27e7Smillert static assoc_list name_key_alist[] = {
15381acd27e7Smillert { "DEL", 0x7f },
15391acd27e7Smillert { "ESC", '\033' },
15401acd27e7Smillert { "Escape", '\033' },
15411acd27e7Smillert { "LFD", '\n' },
15421acd27e7Smillert { "Newline", '\n' },
15431acd27e7Smillert { "RET", '\r' },
15441acd27e7Smillert { "Return", '\r' },
15451acd27e7Smillert { "Rubout", 0x7f },
15461acd27e7Smillert { "SPC", ' ' },
15471acd27e7Smillert { "Space", ' ' },
15481acd27e7Smillert { "Tab", 0x09 },
15491acd27e7Smillert { (char *)0x0, 0 }
15501acd27e7Smillert };
15511acd27e7Smillert
15521acd27e7Smillert static int
glean_key_from_name(name)15531acd27e7Smillert glean_key_from_name (name)
15541acd27e7Smillert char *name;
15551acd27e7Smillert {
15561acd27e7Smillert register int i;
15571acd27e7Smillert
15581acd27e7Smillert for (i = 0; name_key_alist[i].name; i++)
15591acd27e7Smillert if (_rl_stricmp (name, name_key_alist[i].name) == 0)
15601acd27e7Smillert return (name_key_alist[i].value);
15611acd27e7Smillert
15621acd27e7Smillert return (*(unsigned char *)name); /* XXX was return (*name) */
15631acd27e7Smillert }
15641acd27e7Smillert
15651acd27e7Smillert /* Auxiliary functions to manage keymaps. */
15661acd27e7Smillert static struct {
1567af70c2dfSkettenis const char *name;
15681acd27e7Smillert Keymap map;
15691acd27e7Smillert } keymap_names[] = {
15701acd27e7Smillert { "emacs", emacs_standard_keymap },
15711acd27e7Smillert { "emacs-standard", emacs_standard_keymap },
15721acd27e7Smillert { "emacs-meta", emacs_meta_keymap },
15731acd27e7Smillert { "emacs-ctlx", emacs_ctlx_keymap },
15741acd27e7Smillert #if defined (VI_MODE)
15751acd27e7Smillert { "vi", vi_movement_keymap },
15761acd27e7Smillert { "vi-move", vi_movement_keymap },
15771acd27e7Smillert { "vi-command", vi_movement_keymap },
15781acd27e7Smillert { "vi-insert", vi_insertion_keymap },
15791acd27e7Smillert #endif /* VI_MODE */
15801acd27e7Smillert { (char *)0x0, (Keymap)0x0 }
15811acd27e7Smillert };
15821acd27e7Smillert
15831acd27e7Smillert Keymap
rl_get_keymap_by_name(name)15841acd27e7Smillert rl_get_keymap_by_name (name)
1585af70c2dfSkettenis const char *name;
15861acd27e7Smillert {
15871acd27e7Smillert register int i;
15881acd27e7Smillert
15891acd27e7Smillert for (i = 0; keymap_names[i].name; i++)
1590af70c2dfSkettenis if (_rl_stricmp (name, keymap_names[i].name) == 0)
15911acd27e7Smillert return (keymap_names[i].map);
15921acd27e7Smillert return ((Keymap) NULL);
15931acd27e7Smillert }
15941acd27e7Smillert
15951acd27e7Smillert char *
rl_get_keymap_name(map)15961acd27e7Smillert rl_get_keymap_name (map)
15971acd27e7Smillert Keymap map;
15981acd27e7Smillert {
15991acd27e7Smillert register int i;
16001acd27e7Smillert for (i = 0; keymap_names[i].name; i++)
16011acd27e7Smillert if (map == keymap_names[i].map)
1602af70c2dfSkettenis return ((char *)keymap_names[i].name);
16031acd27e7Smillert return ((char *)NULL);
16041acd27e7Smillert }
16051acd27e7Smillert
16061acd27e7Smillert void
rl_set_keymap(map)16071acd27e7Smillert rl_set_keymap (map)
16081acd27e7Smillert Keymap map;
16091acd27e7Smillert {
16101acd27e7Smillert if (map)
16111acd27e7Smillert _rl_keymap = map;
16121acd27e7Smillert }
16131acd27e7Smillert
16141acd27e7Smillert Keymap
rl_get_keymap()16151acd27e7Smillert rl_get_keymap ()
16161acd27e7Smillert {
16171acd27e7Smillert return (_rl_keymap);
16181acd27e7Smillert }
16191acd27e7Smillert
16201acd27e7Smillert void
rl_set_keymap_from_edit_mode()16211acd27e7Smillert rl_set_keymap_from_edit_mode ()
16221acd27e7Smillert {
16231acd27e7Smillert if (rl_editing_mode == emacs_mode)
16241acd27e7Smillert _rl_keymap = emacs_standard_keymap;
16251acd27e7Smillert #if defined (VI_MODE)
16261acd27e7Smillert else if (rl_editing_mode == vi_mode)
16271acd27e7Smillert _rl_keymap = vi_insertion_keymap;
16281acd27e7Smillert #endif /* VI_MODE */
16291acd27e7Smillert }
16301acd27e7Smillert
16311acd27e7Smillert char *
rl_get_keymap_name_from_edit_mode()16321acd27e7Smillert rl_get_keymap_name_from_edit_mode ()
16331acd27e7Smillert {
16341acd27e7Smillert if (rl_editing_mode == emacs_mode)
16351acd27e7Smillert return "emacs";
16361acd27e7Smillert #if defined (VI_MODE)
16371acd27e7Smillert else if (rl_editing_mode == vi_mode)
16381acd27e7Smillert return "vi";
16391acd27e7Smillert #endif /* VI_MODE */
16401acd27e7Smillert else
16411acd27e7Smillert return "none";
16421acd27e7Smillert }
16431acd27e7Smillert
16441acd27e7Smillert /* **************************************************************** */
16451acd27e7Smillert /* */
16461acd27e7Smillert /* Key Binding and Function Information */
16471acd27e7Smillert /* */
16481acd27e7Smillert /* **************************************************************** */
16491acd27e7Smillert
16501acd27e7Smillert /* Each of the following functions produces information about the
16511acd27e7Smillert state of keybindings and functions known to Readline. The info
16521acd27e7Smillert is always printed to rl_outstream, and in such a way that it can
16531acd27e7Smillert be read back in (i.e., passed to rl_parse_and_bind (). */
16541acd27e7Smillert
16551acd27e7Smillert /* Print the names of functions known to Readline. */
16561acd27e7Smillert void
rl_list_funmap_names()16571acd27e7Smillert rl_list_funmap_names ()
16581acd27e7Smillert {
16591acd27e7Smillert register int i;
1660af70c2dfSkettenis const char **funmap_names;
16611acd27e7Smillert
16621acd27e7Smillert funmap_names = rl_funmap_names ();
16631acd27e7Smillert
16641acd27e7Smillert if (!funmap_names)
16651acd27e7Smillert return;
16661acd27e7Smillert
16671acd27e7Smillert for (i = 0; funmap_names[i]; i++)
16681acd27e7Smillert fprintf (rl_outstream, "%s\n", funmap_names[i]);
16691acd27e7Smillert
16701acd27e7Smillert free (funmap_names);
16711acd27e7Smillert }
16721acd27e7Smillert
16731acd27e7Smillert static char *
_rl_get_keyname(key)16741acd27e7Smillert _rl_get_keyname (key)
16751acd27e7Smillert int key;
16761acd27e7Smillert {
16771acd27e7Smillert char *keyname;
16781acd27e7Smillert int i, c;
16791acd27e7Smillert
16801acd27e7Smillert keyname = (char *)xmalloc (8);
16811acd27e7Smillert
16821acd27e7Smillert c = key;
16831acd27e7Smillert /* Since this is going to be used to write out keysequence-function
16841acd27e7Smillert pairs for possible inclusion in an inputrc file, we don't want to
16851acd27e7Smillert do any special meta processing on KEY. */
16861acd27e7Smillert
1687af70c2dfSkettenis #if 1
1688af70c2dfSkettenis /* XXX - Experimental */
16891acd27e7Smillert /* We might want to do this, but the old version of the code did not. */
16901acd27e7Smillert
16911acd27e7Smillert /* If this is an escape character, we don't want to do any more processing.
16921acd27e7Smillert Just add the special ESC key sequence and return. */
16931acd27e7Smillert if (c == ESC)
16941acd27e7Smillert {
1695af70c2dfSkettenis keyname[0] = '\\';
1696af70c2dfSkettenis keyname[1] = 'e';
1697af70c2dfSkettenis keyname[2] = '\0';
1698af70c2dfSkettenis return keyname;
16991acd27e7Smillert }
17001acd27e7Smillert #endif
17011acd27e7Smillert
17021acd27e7Smillert /* RUBOUT is translated directly into \C-? */
17031acd27e7Smillert if (key == RUBOUT)
17041acd27e7Smillert {
17051acd27e7Smillert keyname[0] = '\\';
17061acd27e7Smillert keyname[1] = 'C';
17071acd27e7Smillert keyname[2] = '-';
17081acd27e7Smillert keyname[3] = '?';
17091acd27e7Smillert keyname[4] = '\0';
17101acd27e7Smillert return keyname;
17111acd27e7Smillert }
17121acd27e7Smillert
17131acd27e7Smillert i = 0;
17141acd27e7Smillert /* Now add special prefixes needed for control characters. This can
17151acd27e7Smillert potentially change C. */
17161acd27e7Smillert if (CTRL_CHAR (c))
17171acd27e7Smillert {
17181acd27e7Smillert keyname[i++] = '\\';
17191acd27e7Smillert keyname[i++] = 'C';
17201acd27e7Smillert keyname[i++] = '-';
17211acd27e7Smillert c = _rl_to_lower (UNCTRL (c));
17221acd27e7Smillert }
17231acd27e7Smillert
17241acd27e7Smillert /* XXX experimental code. Turn the characters that are not ASCII or
17251acd27e7Smillert ISO Latin 1 (128 - 159) into octal escape sequences (\200 - \237).
17261acd27e7Smillert This changes C. */
17271acd27e7Smillert if (c >= 128 && c <= 159)
17281acd27e7Smillert {
17291acd27e7Smillert keyname[i++] = '\\';
17301acd27e7Smillert keyname[i++] = '2';
17311acd27e7Smillert c -= 128;
17321acd27e7Smillert keyname[i++] = (c / 8) + '0';
17331acd27e7Smillert c = (c % 8) + '0';
17341acd27e7Smillert }
17351acd27e7Smillert
17361acd27e7Smillert /* Now, if the character needs to be quoted with a backslash, do that. */
17371acd27e7Smillert if (c == '\\' || c == '"')
17381acd27e7Smillert keyname[i++] = '\\';
17391acd27e7Smillert
17401acd27e7Smillert /* Now add the key, terminate the string, and return it. */
17411acd27e7Smillert keyname[i++] = (char) c;
17421acd27e7Smillert keyname[i] = '\0';
17431acd27e7Smillert
17441acd27e7Smillert return keyname;
17451acd27e7Smillert }
17461acd27e7Smillert
17471acd27e7Smillert /* Return a NULL terminated array of strings which represent the key
17481acd27e7Smillert sequences that are used to invoke FUNCTION in MAP. */
17491acd27e7Smillert char **
rl_invoking_keyseqs_in_map(function,map)17501acd27e7Smillert rl_invoking_keyseqs_in_map (function, map)
1751af70c2dfSkettenis rl_command_func_t *function;
17521acd27e7Smillert Keymap map;
17531acd27e7Smillert {
17541acd27e7Smillert register int key;
17551acd27e7Smillert char **result;
17561acd27e7Smillert int result_index, result_size;
17571acd27e7Smillert
17581acd27e7Smillert result = (char **)NULL;
17591acd27e7Smillert result_index = result_size = 0;
17601acd27e7Smillert
17611acd27e7Smillert for (key = 0; key < KEYMAP_SIZE; key++)
17621acd27e7Smillert {
17631acd27e7Smillert switch (map[key].type)
17641acd27e7Smillert {
17651acd27e7Smillert case ISMACR:
17661acd27e7Smillert /* Macros match, if, and only if, the pointers are identical.
17671acd27e7Smillert Thus, they are treated exactly like functions in here. */
17681acd27e7Smillert case ISFUNC:
17691acd27e7Smillert /* If the function in the keymap is the one we are looking for,
17701acd27e7Smillert then add the current KEY to the list of invoking keys. */
17711acd27e7Smillert if (map[key].function == function)
17721acd27e7Smillert {
17731acd27e7Smillert char *keyname;
17741acd27e7Smillert
17751acd27e7Smillert keyname = _rl_get_keyname (key);
17761acd27e7Smillert
17771acd27e7Smillert if (result_index + 2 > result_size)
17781acd27e7Smillert {
17791acd27e7Smillert result_size += 10;
17801acd27e7Smillert result = (char **)xrealloc (result, result_size * sizeof (char *));
17811acd27e7Smillert }
17821acd27e7Smillert
17831acd27e7Smillert result[result_index++] = keyname;
17841acd27e7Smillert result[result_index] = (char *)NULL;
17851acd27e7Smillert }
17861acd27e7Smillert break;
17871acd27e7Smillert
17881acd27e7Smillert case ISKMAP:
17891acd27e7Smillert {
17901acd27e7Smillert char **seqs;
17911acd27e7Smillert register int i;
17921acd27e7Smillert
17931acd27e7Smillert /* Find the list of keyseqs in this map which have FUNCTION as
17941acd27e7Smillert their target. Add the key sequences found to RESULT. */
17951acd27e7Smillert if (map[key].function)
17961acd27e7Smillert seqs =
17971acd27e7Smillert rl_invoking_keyseqs_in_map (function, FUNCTION_TO_KEYMAP (map, key));
17981acd27e7Smillert else
17991acd27e7Smillert break;
18001acd27e7Smillert
18011acd27e7Smillert if (seqs == 0)
18021acd27e7Smillert break;
18031acd27e7Smillert
18041acd27e7Smillert for (i = 0; seqs[i]; i++)
18051acd27e7Smillert {
180663bef317Sbeck int len = 6 + strlen(seqs[i]);
180763bef317Sbeck char *keyname = (char *)xmalloc (len);
18081acd27e7Smillert
18091acd27e7Smillert if (key == ESC)
1810af70c2dfSkettenis #if 0
181163bef317Sbeck snprintf(keyname, len, "\\e");
1812af70c2dfSkettenis #else
1813af70c2dfSkettenis /* XXX - experimental */
1814af70c2dfSkettenis snprintf(keyname, len, "\\M-");
1815af70c2dfSkettenis #endif
18161acd27e7Smillert else if (CTRL_CHAR (key))
181763bef317Sbeck snprintf(keyname, len, "\\C-%c", _rl_to_lower (UNCTRL (key)));
18181acd27e7Smillert else if (key == RUBOUT)
181963bef317Sbeck snprintf(keyname, len, "\\C-?");
18201acd27e7Smillert else if (key == '\\' || key == '"')
18211acd27e7Smillert {
18221acd27e7Smillert keyname[0] = '\\';
18231acd27e7Smillert keyname[1] = (char) key;
18241acd27e7Smillert keyname[2] = '\0';
18251acd27e7Smillert }
18261acd27e7Smillert else
18271acd27e7Smillert {
18281acd27e7Smillert keyname[0] = (char) key;
18291acd27e7Smillert keyname[1] = '\0';
18301acd27e7Smillert }
18311acd27e7Smillert
183263bef317Sbeck strlcat (keyname, seqs[i], len);
18331acd27e7Smillert free (seqs[i]);
18341acd27e7Smillert
18351acd27e7Smillert if (result_index + 2 > result_size)
18361acd27e7Smillert {
18371acd27e7Smillert result_size += 10;
18381acd27e7Smillert result = (char **)xrealloc (result, result_size * sizeof (char *));
18391acd27e7Smillert }
18401acd27e7Smillert
18411acd27e7Smillert result[result_index++] = keyname;
18421acd27e7Smillert result[result_index] = (char *)NULL;
18431acd27e7Smillert }
18441acd27e7Smillert
18451acd27e7Smillert free (seqs);
18461acd27e7Smillert }
18471acd27e7Smillert break;
18481acd27e7Smillert }
18491acd27e7Smillert }
18501acd27e7Smillert return (result);
18511acd27e7Smillert }
18521acd27e7Smillert
18531acd27e7Smillert /* Return a NULL terminated array of strings which represent the key
18541acd27e7Smillert sequences that can be used to invoke FUNCTION using the current keymap. */
18551acd27e7Smillert char **
rl_invoking_keyseqs(function)18561acd27e7Smillert rl_invoking_keyseqs (function)
1857af70c2dfSkettenis rl_command_func_t *function;
18581acd27e7Smillert {
18591acd27e7Smillert return (rl_invoking_keyseqs_in_map (function, _rl_keymap));
18601acd27e7Smillert }
18611acd27e7Smillert
18621acd27e7Smillert /* Print all of the functions and their bindings to rl_outstream. If
18631acd27e7Smillert PRINT_READABLY is non-zero, then print the output in such a way
18641acd27e7Smillert that it can be read back in. */
18651acd27e7Smillert void
rl_function_dumper(print_readably)18661acd27e7Smillert rl_function_dumper (print_readably)
18671acd27e7Smillert int print_readably;
18681acd27e7Smillert {
18691acd27e7Smillert register int i;
1870af70c2dfSkettenis const char **names;
1871af70c2dfSkettenis const char *name;
18721acd27e7Smillert
18731acd27e7Smillert names = rl_funmap_names ();
18741acd27e7Smillert
18751acd27e7Smillert fprintf (rl_outstream, "\n");
18761acd27e7Smillert
1877*af1e7b8cSkrw for (i = 0; (name = names[i]); i++)
18781acd27e7Smillert {
1879af70c2dfSkettenis rl_command_func_t *function;
18801acd27e7Smillert char **invokers;
18811acd27e7Smillert
18821acd27e7Smillert function = rl_named_function (name);
18831acd27e7Smillert invokers = rl_invoking_keyseqs_in_map (function, _rl_keymap);
18841acd27e7Smillert
18851acd27e7Smillert if (print_readably)
18861acd27e7Smillert {
18871acd27e7Smillert if (!invokers)
18881acd27e7Smillert fprintf (rl_outstream, "# %s (not bound)\n", name);
18891acd27e7Smillert else
18901acd27e7Smillert {
18911acd27e7Smillert register int j;
18921acd27e7Smillert
18931acd27e7Smillert for (j = 0; invokers[j]; j++)
18941acd27e7Smillert {
18951acd27e7Smillert fprintf (rl_outstream, "\"%s\": %s\n",
18961acd27e7Smillert invokers[j], name);
18971acd27e7Smillert free (invokers[j]);
18981acd27e7Smillert }
18991acd27e7Smillert
19001acd27e7Smillert free (invokers);
19011acd27e7Smillert }
19021acd27e7Smillert }
19031acd27e7Smillert else
19041acd27e7Smillert {
19051acd27e7Smillert if (!invokers)
19061acd27e7Smillert fprintf (rl_outstream, "%s is not bound to any keys\n",
19071acd27e7Smillert name);
19081acd27e7Smillert else
19091acd27e7Smillert {
19101acd27e7Smillert register int j;
19111acd27e7Smillert
19121acd27e7Smillert fprintf (rl_outstream, "%s can be found on ", name);
19131acd27e7Smillert
19141acd27e7Smillert for (j = 0; invokers[j] && j < 5; j++)
19151acd27e7Smillert {
19161acd27e7Smillert fprintf (rl_outstream, "\"%s\"%s", invokers[j],
19171acd27e7Smillert invokers[j + 1] ? ", " : ".\n");
19181acd27e7Smillert }
19191acd27e7Smillert
19201acd27e7Smillert if (j == 5 && invokers[j])
19211acd27e7Smillert fprintf (rl_outstream, "...\n");
19221acd27e7Smillert
19231acd27e7Smillert for (j = 0; invokers[j]; j++)
19241acd27e7Smillert free (invokers[j]);
19251acd27e7Smillert
19261acd27e7Smillert free (invokers);
19271acd27e7Smillert }
19281acd27e7Smillert }
19291acd27e7Smillert }
19301acd27e7Smillert }
19311acd27e7Smillert
19321acd27e7Smillert /* Print all of the current functions and their bindings to
19331acd27e7Smillert rl_outstream. If an explicit argument is given, then print
19341acd27e7Smillert the output in such a way that it can be read back in. */
19351acd27e7Smillert int
rl_dump_functions(count,key)19361acd27e7Smillert rl_dump_functions (count, key)
19371acd27e7Smillert int count, key;
19381acd27e7Smillert {
19391acd27e7Smillert if (rl_dispatching)
19401acd27e7Smillert fprintf (rl_outstream, "\r\n");
19411acd27e7Smillert rl_function_dumper (rl_explicit_arg);
19421acd27e7Smillert rl_on_new_line ();
19431acd27e7Smillert return (0);
19441acd27e7Smillert }
19451acd27e7Smillert
19461acd27e7Smillert static void
_rl_macro_dumper_internal(print_readably,map,prefix)19471acd27e7Smillert _rl_macro_dumper_internal (print_readably, map, prefix)
19481acd27e7Smillert int print_readably;
19491acd27e7Smillert Keymap map;
19501acd27e7Smillert char *prefix;
19511acd27e7Smillert {
19521acd27e7Smillert register int key;
19531acd27e7Smillert char *keyname, *out;
19541acd27e7Smillert int prefix_len;
19551acd27e7Smillert
19561acd27e7Smillert for (key = 0; key < KEYMAP_SIZE; key++)
19571acd27e7Smillert {
19581acd27e7Smillert switch (map[key].type)
19591acd27e7Smillert {
19601acd27e7Smillert case ISMACR:
19611acd27e7Smillert keyname = _rl_get_keyname (key);
19621acd27e7Smillert out = _rl_untranslate_macro_value ((char *)map[key].function);
1963af70c2dfSkettenis
19641acd27e7Smillert if (print_readably)
19651acd27e7Smillert fprintf (rl_outstream, "\"%s%s\": \"%s\"\n", prefix ? prefix : "",
19661acd27e7Smillert keyname,
19671acd27e7Smillert out ? out : "");
19681acd27e7Smillert else
19691acd27e7Smillert fprintf (rl_outstream, "%s%s outputs %s\n", prefix ? prefix : "",
19701acd27e7Smillert keyname,
19711acd27e7Smillert out ? out : "");
19721acd27e7Smillert free (keyname);
19731acd27e7Smillert free (out);
19741acd27e7Smillert break;
19751acd27e7Smillert case ISFUNC:
19761acd27e7Smillert break;
19771acd27e7Smillert case ISKMAP:
19781acd27e7Smillert prefix_len = prefix ? strlen (prefix) : 0;
19791acd27e7Smillert if (key == ESC)
19801acd27e7Smillert {
198163bef317Sbeck int len = 3 + prefix_len;
1982af70c2dfSkettenis keyname = (char *)xmalloc (len);
19831acd27e7Smillert if (prefix)
198463bef317Sbeck strlcpy (keyname, prefix, len);
19851acd27e7Smillert keyname[prefix_len] = '\\';
19861acd27e7Smillert keyname[prefix_len + 1] = 'e';
19871acd27e7Smillert keyname[prefix_len + 2] = '\0';
19881acd27e7Smillert }
19891acd27e7Smillert else
19901acd27e7Smillert {
19911acd27e7Smillert keyname = _rl_get_keyname (key);
19921acd27e7Smillert if (prefix)
19931acd27e7Smillert {
199463bef317Sbeck if (asprintf(&out, "%s%s", prefix, keyname) == -1)
199563bef317Sbeck memory_error_and_abort("asprintf");
19961acd27e7Smillert free (keyname);
19971acd27e7Smillert keyname = out;
19981acd27e7Smillert }
19991acd27e7Smillert }
20001acd27e7Smillert
20011acd27e7Smillert _rl_macro_dumper_internal (print_readably, FUNCTION_TO_KEYMAP (map, key), keyname);
20021acd27e7Smillert free (keyname);
20031acd27e7Smillert break;
20041acd27e7Smillert }
20051acd27e7Smillert }
20061acd27e7Smillert }
20071acd27e7Smillert
20081acd27e7Smillert void
rl_macro_dumper(print_readably)20091acd27e7Smillert rl_macro_dumper (print_readably)
20101acd27e7Smillert int print_readably;
20111acd27e7Smillert {
20121acd27e7Smillert _rl_macro_dumper_internal (print_readably, _rl_keymap, (char *)NULL);
20131acd27e7Smillert }
20141acd27e7Smillert
20151acd27e7Smillert int
rl_dump_macros(count,key)20161acd27e7Smillert rl_dump_macros (count, key)
20171acd27e7Smillert int count, key;
20181acd27e7Smillert {
20191acd27e7Smillert if (rl_dispatching)
20201acd27e7Smillert fprintf (rl_outstream, "\r\n");
20211acd27e7Smillert rl_macro_dumper (rl_explicit_arg);
20221acd27e7Smillert rl_on_new_line ();
20231acd27e7Smillert return (0);
20241acd27e7Smillert }
20251acd27e7Smillert
20261acd27e7Smillert void
rl_variable_dumper(print_readably)20271acd27e7Smillert rl_variable_dumper (print_readably)
20281acd27e7Smillert int print_readably;
20291acd27e7Smillert {
20301acd27e7Smillert int i;
2031af70c2dfSkettenis const char *kname;
20321acd27e7Smillert
20331acd27e7Smillert for (i = 0; boolean_varlist[i].name; i++)
20341acd27e7Smillert {
20351acd27e7Smillert if (print_readably)
20361acd27e7Smillert fprintf (rl_outstream, "set %s %s\n", boolean_varlist[i].name,
20371acd27e7Smillert *boolean_varlist[i].value ? "on" : "off");
20381acd27e7Smillert else
20391acd27e7Smillert fprintf (rl_outstream, "%s is set to `%s'\n", boolean_varlist[i].name,
20401acd27e7Smillert *boolean_varlist[i].value ? "on" : "off");
20411acd27e7Smillert }
20421acd27e7Smillert
20431acd27e7Smillert /* bell-style */
20441acd27e7Smillert switch (_rl_bell_preference)
20451acd27e7Smillert {
20461acd27e7Smillert case NO_BELL:
20471acd27e7Smillert kname = "none"; break;
20481acd27e7Smillert case VISIBLE_BELL:
20491acd27e7Smillert kname = "visible"; break;
20501acd27e7Smillert case AUDIBLE_BELL:
20511acd27e7Smillert default:
20521acd27e7Smillert kname = "audible"; break;
20531acd27e7Smillert }
20541acd27e7Smillert if (print_readably)
20551acd27e7Smillert fprintf (rl_outstream, "set bell-style %s\n", kname);
20561acd27e7Smillert else
20571acd27e7Smillert fprintf (rl_outstream, "bell-style is set to `%s'\n", kname);
20581acd27e7Smillert
20591acd27e7Smillert /* comment-begin */
20601acd27e7Smillert if (print_readably)
20611acd27e7Smillert fprintf (rl_outstream, "set comment-begin %s\n", _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
20621acd27e7Smillert else
2063af70c2dfSkettenis fprintf (rl_outstream, "comment-begin is set to `%s'\n", _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
20641acd27e7Smillert
20651acd27e7Smillert /* completion-query-items */
20661acd27e7Smillert if (print_readably)
20671acd27e7Smillert fprintf (rl_outstream, "set completion-query-items %d\n", rl_completion_query_items);
20681acd27e7Smillert else
20691acd27e7Smillert fprintf (rl_outstream, "completion-query-items is set to `%d'\n", rl_completion_query_items);
20701acd27e7Smillert
20711acd27e7Smillert /* editing-mode */
20721acd27e7Smillert if (print_readably)
20731acd27e7Smillert fprintf (rl_outstream, "set editing-mode %s\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi");
20741acd27e7Smillert else
20751acd27e7Smillert fprintf (rl_outstream, "editing-mode is set to `%s'\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi");
20761acd27e7Smillert
20771acd27e7Smillert /* isearch-terminators */
20781acd27e7Smillert if (_rl_isearch_terminators)
20791acd27e7Smillert {
20801acd27e7Smillert char *disp;
20811acd27e7Smillert
20821acd27e7Smillert disp = _rl_untranslate_macro_value (_rl_isearch_terminators);
20831acd27e7Smillert
20841acd27e7Smillert if (print_readably)
20851acd27e7Smillert fprintf (rl_outstream, "set isearch-terminators \"%s\"\n", disp);
20861acd27e7Smillert else
20871acd27e7Smillert fprintf (rl_outstream, "isearch-terminators is set to \"%s\"\n", disp);
20881acd27e7Smillert
20891acd27e7Smillert free (disp);
20901acd27e7Smillert }
2091af70c2dfSkettenis
2092af70c2dfSkettenis /* keymap */
2093af70c2dfSkettenis kname = rl_get_keymap_name (_rl_keymap);
2094af70c2dfSkettenis if (kname == 0)
2095af70c2dfSkettenis kname = rl_get_keymap_name_from_edit_mode ();
2096af70c2dfSkettenis if (print_readably)
2097af70c2dfSkettenis fprintf (rl_outstream, "set keymap %s\n", kname ? kname : "none");
2098af70c2dfSkettenis else
2099af70c2dfSkettenis fprintf (rl_outstream, "keymap is set to `%s'\n", kname ? kname : "none");
21001acd27e7Smillert }
21011acd27e7Smillert
21021acd27e7Smillert /* Print all of the current variables and their values to
21031acd27e7Smillert rl_outstream. If an explicit argument is given, then print
21041acd27e7Smillert the output in such a way that it can be read back in. */
21051acd27e7Smillert int
rl_dump_variables(count,key)21061acd27e7Smillert rl_dump_variables (count, key)
21071acd27e7Smillert int count, key;
21081acd27e7Smillert {
21091acd27e7Smillert if (rl_dispatching)
21101acd27e7Smillert fprintf (rl_outstream, "\r\n");
21111acd27e7Smillert rl_variable_dumper (rl_explicit_arg);
21121acd27e7Smillert rl_on_new_line ();
21131acd27e7Smillert return (0);
21141acd27e7Smillert }
21151acd27e7Smillert
2116af70c2dfSkettenis /* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right
2117af70c2dfSkettenis now, this is always used to attempt to bind the arrow keys, hence the
2118af70c2dfSkettenis check for rl_vi_movement_mode. */
21191acd27e7Smillert void
_rl_bind_if_unbound(keyseq,default_func)21201acd27e7Smillert _rl_bind_if_unbound (keyseq, default_func)
2121af70c2dfSkettenis const char *keyseq;
2122af70c2dfSkettenis rl_command_func_t *default_func;
21231acd27e7Smillert {
2124af70c2dfSkettenis rl_command_func_t *func;
21251acd27e7Smillert
21261acd27e7Smillert if (keyseq)
21271acd27e7Smillert {
21281acd27e7Smillert func = rl_function_of_keyseq (keyseq, _rl_keymap, (int *)NULL);
2129af70c2dfSkettenis #if defined (VI_MODE)
2130af70c2dfSkettenis if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode)
2131af70c2dfSkettenis #else
21321acd27e7Smillert if (!func || func == rl_do_lowercase_version)
2133af70c2dfSkettenis #endif
21341acd27e7Smillert rl_set_key (keyseq, default_func, _rl_keymap);
21351acd27e7Smillert }
21361acd27e7Smillert }
21371acd27e7Smillert
21381acd27e7Smillert /* Return non-zero if any members of ARRAY are a substring in STRING. */
21391acd27e7Smillert static int
substring_member_of_array(string,array)21401acd27e7Smillert substring_member_of_array (string, array)
2141af70c2dfSkettenis char *string;
2142af70c2dfSkettenis const char **array;
21431acd27e7Smillert {
21441acd27e7Smillert while (*array)
21451acd27e7Smillert {
21461acd27e7Smillert if (_rl_strindex (string, *array))
21471acd27e7Smillert return (1);
21481acd27e7Smillert array++;
21491acd27e7Smillert }
21501acd27e7Smillert return (0);
21511acd27e7Smillert }
2152