121308Sache/* bind.c -- key binding and startup file support for the readline library. */ 221308Sache 3165670Sache/* Copyright (C) 1987-2006 Free Software Foundation, Inc. 421308Sache 521308Sache This file is part of the GNU Readline Library, a library for 621308Sache reading lines of text with interactive input and history editing. 721308Sache 821308Sache The GNU Readline Library is free software; you can redistribute it 921308Sache and/or modify it under the terms of the GNU General Public License 1058310Sache as published by the Free Software Foundation; either version 2, or 1121308Sache (at your option) any later version. 1221308Sache 1321308Sache The GNU Readline Library is distributed in the hope that it will be 1421308Sache useful, but WITHOUT ANY WARRANTY; without even the implied warranty 1521308Sache of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1621308Sache GNU General Public License for more details. 1721308Sache 1821308Sache The GNU General Public License is often shipped with GNU software, and 1921308Sache is generally kept in a file called COPYING or LICENSE. If you do not 2021308Sache have a copy of the license, write to the Free Software Foundation, 2158310Sache 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ 22136644Sache 2321308Sache#define READLINE_LIBRARY 2421308Sache 25136644Sache#if defined (__TANDEM) 26136644Sache# include <floss.h> 27136644Sache#endif 28136644Sache 2921308Sache#if defined (HAVE_CONFIG_H) 3021308Sache# include <config.h> 3121308Sache#endif 3221308Sache 3321308Sache#include <stdio.h> 3421308Sache#include <sys/types.h> 3521308Sache#include <fcntl.h> 3621308Sache#if defined (HAVE_SYS_FILE_H) 3721308Sache# include <sys/file.h> 3821308Sache#endif /* HAVE_SYS_FILE_H */ 3921308Sache 4021308Sache#if defined (HAVE_UNISTD_H) 4121308Sache# include <unistd.h> 4221308Sache#endif /* HAVE_UNISTD_H */ 4321308Sache 4421308Sache#if defined (HAVE_STDLIB_H) 4521308Sache# include <stdlib.h> 4621308Sache#else 4721308Sache# include "ansi_stdlib.h" 4821308Sache#endif /* HAVE_STDLIB_H */ 4921308Sache 5021308Sache#include <errno.h> 5121308Sache 5221308Sache#if !defined (errno) 5321308Sacheextern int errno; 5421308Sache#endif /* !errno */ 5521308Sache 5621308Sache#include "posixstat.h" 5721308Sache 5821308Sache/* System-specific feature definitions and include files. */ 5921308Sache#include "rldefs.h" 6021308Sache 6121308Sache/* Some standard library routines. */ 6221308Sache#include "readline.h" 6321308Sache#include "history.h" 6421308Sache 6558310Sache#include "rlprivate.h" 6658310Sache#include "rlshell.h" 6758310Sache#include "xmalloc.h" 6858310Sache 6921308Sache#if !defined (strchr) && !defined (__STDC__) 7021308Sacheextern char *strchr (), *strrchr (); 7121308Sache#endif /* !strchr && !__STDC__ */ 7221308Sache 7321308Sache/* Variables exported by this file. */ 7421308SacheKeymap rl_binding_keymap; 7521308Sache 76119610Sachestatic char *_rl_read_file PARAMS((char *, size_t *)); 77119610Sachestatic void _rl_init_file_error PARAMS((const char *)); 78119610Sachestatic int _rl_read_init_file PARAMS((const char *, int)); 79119610Sachestatic int glean_key_from_name PARAMS((char *)); 80157184Sachestatic int find_boolean_var PARAMS((const char *)); 81157184Sache 82157184Sachestatic char *_rl_get_string_variable_value PARAMS((const char *)); 83119610Sachestatic int substring_member_of_array PARAMS((char *, const char **)); 8421308Sache 8558310Sachestatic int currently_reading_init_file; 8621308Sache 8758310Sache/* used only in this file */ 8858310Sachestatic int _rl_prefer_visible_bell = 1; 8921308Sache 9021308Sache/* **************************************************************** */ 9121308Sache/* */ 9221308Sache/* Binding keys */ 9321308Sache/* */ 9421308Sache/* **************************************************************** */ 9521308Sache 9675406Sache/* rl_add_defun (char *name, rl_command_func_t *function, int key) 9721308Sache Add NAME to the list of named functions. Make FUNCTION be the function 9821308Sache that gets called. If KEY is not -1, then bind it. */ 9921308Sacheint 10021308Sacherl_add_defun (name, function, key) 10175406Sache const char *name; 10275406Sache rl_command_func_t *function; 10321308Sache int key; 10421308Sache{ 10521308Sache if (key != -1) 10621308Sache rl_bind_key (key, function); 10721308Sache rl_add_funmap_entry (name, function); 10821308Sache return 0; 10921308Sache} 11021308Sache 11121308Sache/* Bind KEY to FUNCTION. Returns non-zero if KEY is out of range. */ 11221308Sacheint 11321308Sacherl_bind_key (key, function) 11421308Sache int key; 11575406Sache rl_command_func_t *function; 11621308Sache{ 11721308Sache if (key < 0) 11821308Sache return (key); 11921308Sache 12021308Sache if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii) 12121308Sache { 12221308Sache if (_rl_keymap[ESC].type == ISKMAP) 12321308Sache { 12421308Sache Keymap escmap; 12521308Sache 12621308Sache escmap = FUNCTION_TO_KEYMAP (_rl_keymap, ESC); 12721308Sache key = UNMETA (key); 12821308Sache escmap[key].type = ISFUNC; 12921308Sache escmap[key].function = function; 13021308Sache return (0); 13121308Sache } 13221308Sache return (key); 13321308Sache } 13421308Sache 13521308Sache _rl_keymap[key].type = ISFUNC; 13621308Sache _rl_keymap[key].function = function; 13721308Sache rl_binding_keymap = _rl_keymap; 13821308Sache return (0); 13921308Sache} 14021308Sache 14121308Sache/* Bind KEY to FUNCTION in MAP. Returns non-zero in case of invalid 14221308Sache KEY. */ 14321308Sacheint 14421308Sacherl_bind_key_in_map (key, function, map) 14521308Sache int key; 14675406Sache rl_command_func_t *function; 14721308Sache Keymap map; 14821308Sache{ 14921308Sache int result; 15021308Sache Keymap oldmap; 15121308Sache 15221308Sache oldmap = _rl_keymap; 15321308Sache _rl_keymap = map; 15421308Sache result = rl_bind_key (key, function); 15521308Sache _rl_keymap = oldmap; 15621308Sache return (result); 15721308Sache} 15821308Sache 159136644Sache/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right 160136644Sache now, this is always used to attempt to bind the arrow keys, hence the 161136644Sache check for rl_vi_movement_mode. */ 162136644Sacheint 163136644Sacherl_bind_key_if_unbound_in_map (key, default_func, kmap) 164136644Sache int key; 165136644Sache rl_command_func_t *default_func; 166136644Sache Keymap kmap; 167136644Sache{ 168136644Sache char keyseq[2]; 169136644Sache 170136644Sache keyseq[0] = (unsigned char)key; 171136644Sache keyseq[1] = '\0'; 172136644Sache return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap)); 173136644Sache} 174136644Sache 175136644Sacheint 176136644Sacherl_bind_key_if_unbound (key, default_func) 177136644Sache int key; 178136644Sache rl_command_func_t *default_func; 179136644Sache{ 180136644Sache char keyseq[2]; 181136644Sache 182136644Sache keyseq[0] = (unsigned char)key; 183136644Sache keyseq[1] = '\0'; 184136644Sache return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap)); 185136644Sache} 186136644Sache 18721308Sache/* Make KEY do nothing in the currently selected keymap. 18821308Sache Returns non-zero in case of error. */ 18921308Sacheint 19021308Sacherl_unbind_key (key) 19121308Sache int key; 19221308Sache{ 19375406Sache return (rl_bind_key (key, (rl_command_func_t *)NULL)); 19421308Sache} 19521308Sache 19621308Sache/* Make KEY do nothing in MAP. 19721308Sache Returns non-zero in case of error. */ 19821308Sacheint 19921308Sacherl_unbind_key_in_map (key, map) 20021308Sache int key; 20121308Sache Keymap map; 20221308Sache{ 20375406Sache return (rl_bind_key_in_map (key, (rl_command_func_t *)NULL, map)); 20421308Sache} 20521308Sache 20635486Sache/* Unbind all keys bound to FUNCTION in MAP. */ 20735486Sacheint 20835486Sacherl_unbind_function_in_map (func, map) 20975406Sache rl_command_func_t *func; 21035486Sache Keymap map; 21135486Sache{ 21247558Sache register int i, rval; 21335486Sache 21447558Sache for (i = rval = 0; i < KEYMAP_SIZE; i++) 21535486Sache { 21635486Sache if (map[i].type == ISFUNC && map[i].function == func) 21747558Sache { 21875406Sache map[i].function = (rl_command_func_t *)NULL; 21947558Sache rval = 1; 22047558Sache } 22135486Sache } 22247558Sache return rval; 22335486Sache} 22435486Sache 22535486Sacheint 22635486Sacherl_unbind_command_in_map (command, map) 22775406Sache const char *command; 22835486Sache Keymap map; 22935486Sache{ 23075406Sache rl_command_func_t *func; 23135486Sache 23235486Sache func = rl_named_function (command); 23335486Sache if (func == 0) 23435486Sache return 0; 23535486Sache return (rl_unbind_function_in_map (func, map)); 23635486Sache} 23735486Sache 23821308Sache/* Bind the key sequence represented by the string KEYSEQ to 239136644Sache FUNCTION, starting in the current keymap. This makes new 240136644Sache keymaps as necessary. */ 241136644Sacheint 242136644Sacherl_bind_keyseq (keyseq, function) 243136644Sache const char *keyseq; 244136644Sache rl_command_func_t *function; 245136644Sache{ 246136644Sache return (rl_generic_bind (ISFUNC, keyseq, (char *)function, _rl_keymap)); 247136644Sache} 248136644Sache 249136644Sache/* Bind the key sequence represented by the string KEYSEQ to 25021308Sache FUNCTION. This makes new keymaps as necessary. The initial 25121308Sache place to do bindings is in MAP. */ 25221308Sacheint 253136644Sacherl_bind_keyseq_in_map (keyseq, function, map) 254136644Sache const char *keyseq; 255136644Sache rl_command_func_t *function; 256136644Sache Keymap map; 257136644Sache{ 258136644Sache return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map)); 259136644Sache} 260136644Sache 261136644Sache/* Backwards compatibility; equivalent to rl_bind_keyseq_in_map() */ 262136644Sacheint 26321308Sacherl_set_key (keyseq, function, map) 26475406Sache const char *keyseq; 26575406Sache rl_command_func_t *function; 26621308Sache Keymap map; 26721308Sache{ 26826497Sache return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map)); 26921308Sache} 27021308Sache 271136644Sache/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right 272136644Sache now, this is always used to attempt to bind the arrow keys, hence the 273136644Sache check for rl_vi_movement_mode. */ 274136644Sacheint 275136644Sacherl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap) 276136644Sache const char *keyseq; 277136644Sache rl_command_func_t *default_func; 278136644Sache Keymap kmap; 279136644Sache{ 280136644Sache rl_command_func_t *func; 281136644Sache 282136644Sache if (keyseq) 283136644Sache { 284136644Sache func = rl_function_of_keyseq (keyseq, kmap, (int *)NULL); 285136644Sache#if defined (VI_MODE) 286136644Sache if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode) 287136644Sache#else 288136644Sache if (!func || func == rl_do_lowercase_version) 289136644Sache#endif 290136644Sache return (rl_bind_keyseq_in_map (keyseq, default_func, kmap)); 291136644Sache else 292136644Sache return 1; 293136644Sache } 294136644Sache return 0; 295136644Sache} 296136644Sache 297136644Sacheint 298136644Sacherl_bind_keyseq_if_unbound (keyseq, default_func) 299136644Sache const char *keyseq; 300136644Sache rl_command_func_t *default_func; 301136644Sache{ 302136644Sache return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap)); 303136644Sache} 304136644Sache 30521308Sache/* Bind the key sequence represented by the string KEYSEQ to 30621308Sache the string of characters MACRO. This makes new keymaps as 30721308Sache necessary. The initial place to do bindings is in MAP. */ 30821308Sacheint 30921308Sacherl_macro_bind (keyseq, macro, map) 31075406Sache const char *keyseq, *macro; 31121308Sache Keymap map; 31221308Sache{ 31321308Sache char *macro_keys; 31421308Sache int macro_keys_len; 31521308Sache 31621308Sache macro_keys = (char *)xmalloc ((2 * strlen (macro)) + 1); 31721308Sache 31821308Sache if (rl_translate_keyseq (macro, macro_keys, ¯o_keys_len)) 31921308Sache { 32021308Sache free (macro_keys); 32121308Sache return -1; 32221308Sache } 32321308Sache rl_generic_bind (ISMACR, keyseq, macro_keys, map); 32421308Sache return 0; 32521308Sache} 32621308Sache 32721308Sache/* Bind the key sequence represented by the string KEYSEQ to 32821308Sache the arbitrary pointer DATA. TYPE says what kind of data is 32921308Sache pointed to by DATA, right now this can be a function (ISFUNC), 33021308Sache a macro (ISMACR), or a keymap (ISKMAP). This makes new keymaps 33121308Sache as necessary. The initial place to do bindings is in MAP. */ 33221308Sacheint 33321308Sacherl_generic_bind (type, keyseq, data, map) 33421308Sache int type; 33575406Sache const char *keyseq; 33675406Sache char *data; 33721308Sache Keymap map; 33821308Sache{ 33921308Sache char *keys; 34021308Sache int keys_len; 34121308Sache register int i; 342119610Sache KEYMAP_ENTRY k; 34321308Sache 344119610Sache k.function = 0; 345119610Sache 34621308Sache /* If no keys to bind to, exit right away. */ 347157184Sache if (keyseq == 0 || *keyseq == 0) 34821308Sache { 34921308Sache if (type == ISMACR) 35021308Sache free (data); 35121308Sache return -1; 35221308Sache } 35321308Sache 354119610Sache keys = (char *)xmalloc (1 + (2 * strlen (keyseq))); 35521308Sache 35621308Sache /* Translate the ASCII representation of KEYSEQ into an array of 35721308Sache characters. Stuff the characters into KEYS, and the length of 35821308Sache KEYS into KEYS_LEN. */ 35921308Sache if (rl_translate_keyseq (keyseq, keys, &keys_len)) 36021308Sache { 36121308Sache free (keys); 36221308Sache return -1; 36321308Sache } 36421308Sache 36521308Sache /* Bind keys, making new keymaps as necessary. */ 36621308Sache for (i = 0; i < keys_len; i++) 36721308Sache { 368119610Sache unsigned char uc = keys[i]; 369119610Sache int ic; 37021308Sache 371119610Sache ic = uc; 372119610Sache if (ic < 0 || ic >= KEYMAP_SIZE) 373165670Sache { 374165670Sache free (keys); 375165670Sache return -1; 376165670Sache } 377119610Sache 378157184Sache if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii) 37921308Sache { 38021308Sache ic = UNMETA (ic); 38121308Sache if (map[ESC].type == ISKMAP) 38221308Sache map = FUNCTION_TO_KEYMAP (map, ESC); 38321308Sache } 38421308Sache 38521308Sache if ((i + 1) < keys_len) 38621308Sache { 38721308Sache if (map[ic].type != ISKMAP) 38821308Sache { 389119610Sache /* We allow subsequences of keys. If a keymap is being 390119610Sache created that will `shadow' an existing function or macro 391119610Sache key binding, we save that keybinding into the ANYOTHERKEY 392119610Sache index in the new map. The dispatch code will look there 393119610Sache to find the function to execute if the subsequence is not 394119610Sache matched. ANYOTHERKEY was chosen to be greater than 395119610Sache UCHAR_MAX. */ 396119610Sache k = map[ic]; 39721308Sache 39821308Sache map[ic].type = ISKMAP; 39921308Sache map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap()); 40021308Sache } 40121308Sache map = FUNCTION_TO_KEYMAP (map, ic); 402119610Sache /* The dispatch code will return this function if no matching 403119610Sache key sequence is found in the keymap. This (with a little 404119610Sache help from the dispatch code in readline.c) allows `a' to be 405119610Sache mapped to something, `abc' to be mapped to something else, 406119610Sache and the function bound to `a' to be executed when the user 407119610Sache types `abx', leaving `bx' in the input queue. */ 408125759Sache if (k.function && ((k.type == ISFUNC && k.function != rl_do_lowercase_version) || k.type == ISMACR)) 409119610Sache { 410119610Sache map[ANYOTHERKEY] = k; 411119610Sache k.function = 0; 412119610Sache } 41321308Sache } 41421308Sache else 41521308Sache { 41621308Sache if (map[ic].type == ISMACR) 41721308Sache free ((char *)map[ic].function); 418119610Sache else if (map[ic].type == ISKMAP) 419119610Sache { 420119610Sache map = FUNCTION_TO_KEYMAP (map, ic); 421119610Sache ic = ANYOTHERKEY; 422119610Sache } 42321308Sache 42421308Sache map[ic].function = KEYMAP_TO_FUNCTION (data); 42521308Sache map[ic].type = type; 42621308Sache } 42721308Sache 42821308Sache rl_binding_keymap = map; 42921308Sache } 43021308Sache free (keys); 43121308Sache return 0; 43221308Sache} 43321308Sache 43421308Sache/* Translate the ASCII representation of SEQ, stuffing the values into ARRAY, 43521308Sache an array of characters. LEN gets the final length of ARRAY. Return 43621308Sache non-zero if there was an error parsing SEQ. */ 43721308Sacheint 43821308Sacherl_translate_keyseq (seq, array, len) 43975406Sache const char *seq; 44075406Sache char *array; 44121308Sache int *len; 44221308Sache{ 44335486Sache register int i, c, l, temp; 44421308Sache 44521308Sache for (i = l = 0; c = seq[i]; i++) 44621308Sache { 44721308Sache if (c == '\\') 44821308Sache { 44921308Sache c = seq[++i]; 45021308Sache 45121308Sache if (c == 0) 45221308Sache break; 45321308Sache 45435486Sache /* Handle \C- and \M- prefixes. */ 45535486Sache if ((c == 'C' || c == 'M') && seq[i + 1] == '-') 45621308Sache { 45721308Sache /* Handle special case of backwards define. */ 45821308Sache if (strncmp (&seq[i], "C-\\M-", 5) == 0) 45921308Sache { 460119610Sache array[l++] = ESC; /* ESC is meta-prefix */ 46121308Sache i += 5; 46221308Sache array[l++] = CTRL (_rl_to_upper (seq[i])); 46335486Sache if (seq[i] == '\0') 46421308Sache i--; 46521308Sache } 46635486Sache else if (c == 'M') 46721308Sache { 468165670Sache i++; /* seq[i] == '-' */ 469165670Sache /* XXX - obey convert-meta setting */ 470157184Sache if (_rl_convert_meta_chars_to_ascii && _rl_keymap[ESC].type == ISKMAP) 471157184Sache array[l++] = ESC; /* ESC is meta-prefix */ 472165670Sache else if (seq[i+1] == '\\' && seq[i+2] == 'C' && seq[i+3] == '-') 473165670Sache { 474165670Sache i += 4; 475165670Sache temp = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i])); 476165670Sache array[l++] = META (temp); 477165670Sache } 478157184Sache else 479157184Sache { 480165670Sache /* This doesn't yet handle things like \M-\a, which may 481165670Sache or may not have any reasonable meaning. You're 482165670Sache probably better off using straight octal or hex. */ 483157184Sache i++; 484157184Sache array[l++] = META (seq[i]); 485157184Sache } 48635486Sache } 48735486Sache else if (c == 'C') 48835486Sache { 48921308Sache i += 2; 49021308Sache /* Special hack for C-?... */ 49121308Sache array[l++] = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i])); 49221308Sache } 49335486Sache continue; 49435486Sache } 49521308Sache 49635486Sache /* Translate other backslash-escaped characters. These are the 49735486Sache same escape sequences that bash's `echo' and `printf' builtins 49835486Sache handle, with the addition of \d -> RUBOUT. A backslash 49935486Sache preceding a character that is not special is stripped. */ 50035486Sache switch (c) 50135486Sache { 50235486Sache case 'a': 50335486Sache array[l++] = '\007'; 50435486Sache break; 50535486Sache case 'b': 50635486Sache array[l++] = '\b'; 50735486Sache break; 50835486Sache case 'd': 50935486Sache array[l++] = RUBOUT; /* readline-specific */ 51035486Sache break; 51135486Sache case 'e': 51235486Sache array[l++] = ESC; 51335486Sache break; 51435486Sache case 'f': 51535486Sache array[l++] = '\f'; 51635486Sache break; 51735486Sache case 'n': 51835486Sache array[l++] = NEWLINE; 51935486Sache break; 52035486Sache case 'r': 52135486Sache array[l++] = RETURN; 52235486Sache break; 52335486Sache case 't': 52435486Sache array[l++] = TAB; 52535486Sache break; 52635486Sache case 'v': 52735486Sache array[l++] = 0x0B; 52835486Sache break; 52935486Sache case '\\': 53035486Sache array[l++] = '\\'; 53135486Sache break; 53235486Sache case '0': case '1': case '2': case '3': 53335486Sache case '4': case '5': case '6': case '7': 53435486Sache i++; 53535486Sache for (temp = 2, c -= '0'; ISOCTAL (seq[i]) && temp--; i++) 53635486Sache c = (c * 8) + OCTVALUE (seq[i]); 53735486Sache i--; /* auto-increment in for loop */ 538119610Sache array[l++] = c & largest_char; 53935486Sache break; 54035486Sache case 'x': 54135486Sache i++; 542119610Sache for (temp = 2, c = 0; ISXDIGIT ((unsigned char)seq[i]) && temp--; i++) 54335486Sache c = (c * 16) + HEXVALUE (seq[i]); 544119610Sache if (temp == 2) 54535486Sache c = 'x'; 54635486Sache i--; /* auto-increment in for loop */ 547119610Sache array[l++] = c & largest_char; 54835486Sache break; 54935486Sache default: /* backslashes before non-special chars just add the char */ 55035486Sache array[l++] = c; 55135486Sache break; /* the backslash is stripped */ 55221308Sache } 55335486Sache continue; 55421308Sache } 55535486Sache 55621308Sache array[l++] = c; 55721308Sache } 55821308Sache 55921308Sache *len = l; 56021308Sache array[l] = '\0'; 56121308Sache return (0); 56221308Sache} 56321308Sache 56421308Sachechar * 56521308Sacherl_untranslate_keyseq (seq) 56621308Sache int seq; 56721308Sache{ 56821308Sache static char kseq[16]; 56921308Sache int i, c; 57021308Sache 57121308Sache i = 0; 57221308Sache c = seq; 57321308Sache if (META_CHAR (c)) 57421308Sache { 57521308Sache kseq[i++] = '\\'; 57621308Sache kseq[i++] = 'M'; 57721308Sache kseq[i++] = '-'; 57821308Sache c = UNMETA (c); 57921308Sache } 580165670Sache else if (c == ESC) 581165670Sache { 582165670Sache kseq[i++] = '\\'; 583165670Sache c = 'e'; 584165670Sache } 58521308Sache else if (CTRL_CHAR (c)) 58621308Sache { 58721308Sache kseq[i++] = '\\'; 58821308Sache kseq[i++] = 'C'; 58921308Sache kseq[i++] = '-'; 59026497Sache c = _rl_to_lower (UNCTRL (c)); 59121308Sache } 59221308Sache else if (c == RUBOUT) 59321308Sache { 59421308Sache kseq[i++] = '\\'; 59521308Sache kseq[i++] = 'C'; 59621308Sache kseq[i++] = '-'; 59721308Sache c = '?'; 59821308Sache } 59921308Sache 60021308Sache if (c == ESC) 60121308Sache { 60221308Sache kseq[i++] = '\\'; 60326497Sache c = 'e'; 60421308Sache } 60521308Sache else if (c == '\\' || c == '"') 60621308Sache { 60721308Sache kseq[i++] = '\\'; 60821308Sache } 60921308Sache 61021308Sache kseq[i++] = (unsigned char) c; 61121308Sache kseq[i] = '\0'; 61221308Sache return kseq; 61321308Sache} 61421308Sache 61526497Sachestatic char * 61626497Sache_rl_untranslate_macro_value (seq) 61726497Sache char *seq; 61826497Sache{ 61926497Sache char *ret, *r, *s; 62026497Sache int c; 62126497Sache 622119610Sache r = ret = (char *)xmalloc (7 * strlen (seq) + 1); 62326497Sache for (s = seq; *s; s++) 62426497Sache { 62526497Sache c = *s; 62626497Sache if (META_CHAR (c)) 62726497Sache { 62826497Sache *r++ = '\\'; 62926497Sache *r++ = 'M'; 63026497Sache *r++ = '-'; 63126497Sache c = UNMETA (c); 63226497Sache } 633165670Sache else if (c == ESC) 63426497Sache { 63526497Sache *r++ = '\\'; 636165670Sache c = 'e'; 637165670Sache } 638165670Sache else if (CTRL_CHAR (c)) 639165670Sache { 640165670Sache *r++ = '\\'; 64126497Sache *r++ = 'C'; 64226497Sache *r++ = '-'; 64326497Sache c = _rl_to_lower (UNCTRL (c)); 64426497Sache } 64526497Sache else if (c == RUBOUT) 64626497Sache { 64726497Sache *r++ = '\\'; 64826497Sache *r++ = 'C'; 64926497Sache *r++ = '-'; 65026497Sache c = '?'; 65126497Sache } 65226497Sache 65326497Sache if (c == ESC) 65426497Sache { 65526497Sache *r++ = '\\'; 65626497Sache c = 'e'; 65726497Sache } 65826497Sache else if (c == '\\' || c == '"') 65926497Sache *r++ = '\\'; 66026497Sache 66126497Sache *r++ = (unsigned char)c; 66226497Sache } 66326497Sache *r = '\0'; 66426497Sache return ret; 66526497Sache} 66626497Sache 66721308Sache/* Return a pointer to the function that STRING represents. 66821308Sache If STRING doesn't have a matching function, then a NULL pointer 66921308Sache is returned. */ 67075406Sacherl_command_func_t * 67121308Sacherl_named_function (string) 67275406Sache const char *string; 67321308Sache{ 67421308Sache register int i; 67521308Sache 67621308Sache rl_initialize_funmap (); 67721308Sache 67821308Sache for (i = 0; funmap[i]; i++) 67921308Sache if (_rl_stricmp (funmap[i]->name, string) == 0) 68021308Sache return (funmap[i]->function); 68175406Sache return ((rl_command_func_t *)NULL); 68221308Sache} 68321308Sache 68421308Sache/* Return the function (or macro) definition which would be invoked via 68521308Sache KEYSEQ if executed in MAP. If MAP is NULL, then the current keymap is 68621308Sache used. TYPE, if non-NULL, is a pointer to an int which will receive the 68721308Sache type of the object pointed to. One of ISFUNC (function), ISKMAP (keymap), 68821308Sache or ISMACR (macro). */ 68975406Sacherl_command_func_t * 69021308Sacherl_function_of_keyseq (keyseq, map, type) 69175406Sache const char *keyseq; 69221308Sache Keymap map; 69321308Sache int *type; 69421308Sache{ 69521308Sache register int i; 69621308Sache 697165670Sache if (map == 0) 69821308Sache map = _rl_keymap; 69921308Sache 70021308Sache for (i = 0; keyseq && keyseq[i]; i++) 70121308Sache { 702119610Sache unsigned char ic = keyseq[i]; 70321308Sache 70421308Sache if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii) 70521308Sache { 706165670Sache if (map[ESC].type == ISKMAP) 70721308Sache { 708165670Sache map = FUNCTION_TO_KEYMAP (map, ESC); 709165670Sache ic = UNMETA (ic); 710165670Sache } 711165670Sache /* XXX - should we just return NULL here, since this obviously 712165670Sache doesn't match? */ 713165670Sache else 714165670Sache { 71521308Sache if (type) 71621308Sache *type = map[ESC].type; 71721308Sache 71821308Sache return (map[ESC].function); 71921308Sache } 72021308Sache } 72121308Sache 72221308Sache if (map[ic].type == ISKMAP) 72321308Sache { 72421308Sache /* If this is the last key in the key sequence, return the 72521308Sache map. */ 726165670Sache if (keyseq[i + 1] == '\0') 72721308Sache { 72821308Sache if (type) 72921308Sache *type = ISKMAP; 73021308Sache 73121308Sache return (map[ic].function); 73221308Sache } 73321308Sache else 73421308Sache map = FUNCTION_TO_KEYMAP (map, ic); 73521308Sache } 736165670Sache /* If we're not at the end of the key sequence, and the current key 737165670Sache is bound to something other than a keymap, then the entire key 738165670Sache sequence is not bound. */ 739165670Sache else if (map[ic].type != ISKMAP && keyseq[i+1]) 740165670Sache return ((rl_command_func_t *)NULL); 741165670Sache else /* map[ic].type != ISKMAP && keyseq[i+1] == 0 */ 74221308Sache { 74321308Sache if (type) 74421308Sache *type = map[ic].type; 74521308Sache 74621308Sache return (map[ic].function); 74721308Sache } 74821308Sache } 74975406Sache return ((rl_command_func_t *) NULL); 75021308Sache} 75121308Sache 75221308Sache/* The last key bindings file read. */ 75321308Sachestatic char *last_readline_init_file = (char *)NULL; 75421308Sache 75521308Sache/* The file we're currently reading key bindings from. */ 75675406Sachestatic const char *current_readline_init_file; 75735486Sachestatic int current_readline_init_include_level; 75821308Sachestatic int current_readline_init_lineno; 75921308Sache 76035486Sache/* Read FILENAME into a locally-allocated buffer and return the buffer. 76135486Sache The size of the buffer is returned in *SIZEP. Returns NULL if any 76235486Sache errors were encountered. */ 76335486Sachestatic char * 76435486Sache_rl_read_file (filename, sizep) 76535486Sache char *filename; 76635486Sache size_t *sizep; 76735486Sache{ 76835486Sache struct stat finfo; 76935486Sache size_t file_size; 77035486Sache char *buffer; 77135486Sache int i, file; 77235486Sache 77335486Sache if ((stat (filename, &finfo) < 0) || (file = open (filename, O_RDONLY, 0666)) < 0) 77435486Sache return ((char *)NULL); 77535486Sache 77635486Sache file_size = (size_t)finfo.st_size; 77735486Sache 77835486Sache /* check for overflow on very large files */ 77935486Sache if (file_size != finfo.st_size || file_size + 1 < file_size) 78035486Sache { 78135486Sache if (file >= 0) 78235486Sache close (file); 78335486Sache#if defined (EFBIG) 78435486Sache errno = EFBIG; 78535486Sache#endif 78635486Sache return ((char *)NULL); 78735486Sache } 78835486Sache 78935486Sache /* Read the file into BUFFER. */ 79035486Sache buffer = (char *)xmalloc (file_size + 1); 79135486Sache i = read (file, buffer, file_size); 79235486Sache close (file); 79335486Sache 79447558Sache if (i < 0) 79535486Sache { 79635486Sache free (buffer); 79735486Sache return ((char *)NULL); 79835486Sache } 79935486Sache 80058310Sache buffer[i] = '\0'; 80158310Sache if (sizep) 80258310Sache *sizep = i; 80358310Sache 80435486Sache return (buffer); 80535486Sache} 80635486Sache 80721308Sache/* Re-read the current keybindings file. */ 80821308Sacheint 80921308Sacherl_re_read_init_file (count, ignore) 81021308Sache int count, ignore; 81121308Sache{ 81221308Sache int r; 81375406Sache r = rl_read_init_file ((const char *)NULL); 81421308Sache rl_set_keymap_from_edit_mode (); 81521308Sache return r; 81621308Sache} 81721308Sache 81821308Sache/* Do key bindings from a file. If FILENAME is NULL it defaults 81921308Sache to the first non-null filename from this list: 82021308Sache 1. the filename used for the previous call 82121308Sache 2. the value of the shell variable `INPUTRC' 82221308Sache 3. ~/.inputrc 823165670Sache 4. /etc/inputrc 82421308Sache If the file existed and could be opened and read, 0 is returned, 82521308Sache otherwise errno is returned. */ 82621308Sacheint 82721308Sacherl_read_init_file (filename) 82875406Sache const char *filename; 82921308Sache{ 83021308Sache /* Default the filename. */ 83121308Sache if (filename == 0) 832165670Sache filename = last_readline_init_file; 833165670Sache if (filename == 0) 834165670Sache filename = sh_get_env_value ("INPUTRC"); 835165670Sache if (filename == 0 || *filename == 0) 83621308Sache { 837165670Sache filename = DEFAULT_INPUTRC; 838165670Sache /* Try to read DEFAULT_INPUTRC; fall back to SYS_INPUTRC on failure */ 839165670Sache if (_rl_read_init_file (filename, 0) == 0) 840165670Sache return 0; 841165670Sache filename = SYS_INPUTRC; 84221308Sache } 84321308Sache 84458310Sache#if defined (__MSDOS__) 84558310Sache if (_rl_read_init_file (filename, 0) == 0) 84658310Sache return 0; 84758310Sache filename = "~/_inputrc"; 84858310Sache#endif 84935486Sache return (_rl_read_init_file (filename, 0)); 85035486Sache} 85135486Sache 85235486Sachestatic int 85335486Sache_rl_read_init_file (filename, include_level) 85475406Sache const char *filename; 85535486Sache int include_level; 85635486Sache{ 85735486Sache register int i; 85835486Sache char *buffer, *openname, *line, *end; 85935486Sache size_t file_size; 86035486Sache 86121308Sache current_readline_init_file = filename; 86235486Sache current_readline_init_include_level = include_level; 86335486Sache 86421308Sache openname = tilde_expand (filename); 86535486Sache buffer = _rl_read_file (openname, &file_size); 86647558Sache free (openname); 86747558Sache 86835486Sache if (buffer == 0) 86935486Sache return (errno); 87035486Sache 87135486Sache if (include_level == 0 && filename != last_readline_init_file) 87221308Sache { 87335486Sache FREE (last_readline_init_file); 87421308Sache last_readline_init_file = savestring (filename); 87521308Sache } 87621308Sache 87758310Sache currently_reading_init_file = 1; 87858310Sache 87921308Sache /* Loop over the lines in the file. Lines that start with `#' are 88021308Sache comments; all other lines are commands for readline initialization. */ 88121308Sache current_readline_init_lineno = 1; 88221308Sache line = buffer; 88335486Sache end = buffer + file_size; 88421308Sache while (line < end) 88521308Sache { 88621308Sache /* Find the end of this line. */ 88721308Sache for (i = 0; line + i != end && line[i] != '\n'; i++); 88821308Sache 88975406Sache#if defined (__CYGWIN__) 89058310Sache /* ``Be liberal in what you accept.'' */ 89158310Sache if (line[i] == '\n' && line[i-1] == '\r') 89258310Sache line[i - 1] = '\0'; 89358310Sache#endif 89458310Sache 89521308Sache /* Mark end of line. */ 89621308Sache line[i] = '\0'; 89721308Sache 89821308Sache /* Skip leading whitespace. */ 89921308Sache while (*line && whitespace (*line)) 90021308Sache { 90121308Sache line++; 90221308Sache i--; 90321308Sache } 90421308Sache 90521308Sache /* If the line is not a comment, then parse it. */ 90621308Sache if (*line && *line != '#') 90721308Sache rl_parse_and_bind (line); 90821308Sache 90921308Sache /* Move to the next line. */ 91021308Sache line += i + 1; 91121308Sache current_readline_init_lineno++; 91221308Sache } 91335486Sache 91421308Sache free (buffer); 91558310Sache currently_reading_init_file = 0; 91621308Sache return (0); 91721308Sache} 91821308Sache 91921308Sachestatic void 92021308Sache_rl_init_file_error (msg) 921119610Sache const char *msg; 92221308Sache{ 92358310Sache if (currently_reading_init_file) 92458310Sache fprintf (stderr, "readline: %s: line %d: %s\n", current_readline_init_file, 92558310Sache current_readline_init_lineno, msg); 92658310Sache else 92758310Sache fprintf (stderr, "readline: %s\n", msg); 92821308Sache} 92921308Sache 93021308Sache/* **************************************************************** */ 93121308Sache/* */ 93221308Sache/* Parser Directives */ 93321308Sache/* */ 93421308Sache/* **************************************************************** */ 93521308Sache 936119610Sachetypedef int _rl_parser_func_t PARAMS((char *)); 93775406Sache 93875406Sache/* Things that mean `Control'. */ 93975406Sacheconst char *_rl_possible_control_prefixes[] = { 94075406Sache "Control-", "C-", "CTRL-", (const char *)NULL 94175406Sache}; 94275406Sache 94375406Sacheconst char *_rl_possible_meta_prefixes[] = { 94475406Sache "Meta", "M-", (const char *)NULL 94575406Sache}; 94675406Sache 94721308Sache/* Conditionals. */ 94821308Sache 94921308Sache/* Calling programs set this to have their argv[0]. */ 95075406Sacheconst char *rl_readline_name = "other"; 95121308Sache 95221308Sache/* Stack of previous values of parsing_conditionalized_out. */ 95321308Sachestatic unsigned char *if_stack = (unsigned char *)NULL; 95421308Sachestatic int if_stack_depth; 95521308Sachestatic int if_stack_size; 95621308Sache 95721308Sache/* Push _rl_parsing_conditionalized_out, and set parser state based 95821308Sache on ARGS. */ 95921308Sachestatic int 96021308Sacheparser_if (args) 96121308Sache char *args; 96221308Sache{ 96321308Sache register int i; 96421308Sache 96521308Sache /* Push parser state. */ 96621308Sache if (if_stack_depth + 1 >= if_stack_size) 96721308Sache { 96821308Sache if (!if_stack) 96921308Sache if_stack = (unsigned char *)xmalloc (if_stack_size = 20); 97021308Sache else 97121308Sache if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20); 97221308Sache } 97321308Sache if_stack[if_stack_depth++] = _rl_parsing_conditionalized_out; 97421308Sache 97521308Sache /* If parsing is turned off, then nothing can turn it back on except 97621308Sache for finding the matching endif. In that case, return right now. */ 97721308Sache if (_rl_parsing_conditionalized_out) 97821308Sache return 0; 97921308Sache 98021308Sache /* Isolate first argument. */ 98121308Sache for (i = 0; args[i] && !whitespace (args[i]); i++); 98221308Sache 98321308Sache if (args[i]) 98421308Sache args[i++] = '\0'; 98521308Sache 98635486Sache /* Handle "$if term=foo" and "$if mode=emacs" constructs. If this 98721308Sache isn't term=foo, or mode=emacs, then check to see if the first 98821308Sache word in ARGS is the same as the value stored in rl_readline_name. */ 98921308Sache if (rl_terminal_name && _rl_strnicmp (args, "term=", 5) == 0) 99021308Sache { 99121308Sache char *tem, *tname; 99221308Sache 99321308Sache /* Terminals like "aaa-60" are equivalent to "aaa". */ 99421308Sache tname = savestring (rl_terminal_name); 99521308Sache tem = strchr (tname, '-'); 99621308Sache if (tem) 99721308Sache *tem = '\0'; 99821308Sache 99921308Sache /* Test the `long' and `short' forms of the terminal name so that 100021308Sache if someone has a `sun-cmd' and does not want to have bindings 100121308Sache that will be executed if the terminal is a `sun', they can put 100221308Sache `$if term=sun-cmd' into their .inputrc. */ 100321308Sache _rl_parsing_conditionalized_out = _rl_stricmp (args + 5, tname) && 100421308Sache _rl_stricmp (args + 5, rl_terminal_name); 100521308Sache free (tname); 100621308Sache } 100721308Sache#if defined (VI_MODE) 100821308Sache else if (_rl_strnicmp (args, "mode=", 5) == 0) 100921308Sache { 101021308Sache int mode; 101121308Sache 101221308Sache if (_rl_stricmp (args + 5, "emacs") == 0) 101321308Sache mode = emacs_mode; 101421308Sache else if (_rl_stricmp (args + 5, "vi") == 0) 101521308Sache mode = vi_mode; 101621308Sache else 101721308Sache mode = no_mode; 101821308Sache 101921308Sache _rl_parsing_conditionalized_out = mode != rl_editing_mode; 102021308Sache } 102121308Sache#endif /* VI_MODE */ 102221308Sache /* Check to see if the first word in ARGS is the same as the 102321308Sache value stored in rl_readline_name. */ 102421308Sache else if (_rl_stricmp (args, rl_readline_name) == 0) 102521308Sache _rl_parsing_conditionalized_out = 0; 102621308Sache else 102721308Sache _rl_parsing_conditionalized_out = 1; 102821308Sache return 0; 102921308Sache} 103021308Sache 103121308Sache/* Invert the current parser state if there is anything on the stack. */ 103221308Sachestatic int 103321308Sacheparser_else (args) 103421308Sache char *args; 103521308Sache{ 103621308Sache register int i; 103721308Sache 103835486Sache if (if_stack_depth == 0) 103921308Sache { 104035486Sache _rl_init_file_error ("$else found without matching $if"); 104121308Sache return 0; 104221308Sache } 104321308Sache 1044136644Sache#if 0 104521308Sache /* Check the previous (n - 1) levels of the stack to make sure that 104621308Sache we haven't previously turned off parsing. */ 104721308Sache for (i = 0; i < if_stack_depth - 1; i++) 1048136644Sache#else 1049136644Sache /* Check the previous (n) levels of the stack to make sure that 1050136644Sache we haven't previously turned off parsing. */ 1051136644Sache for (i = 0; i < if_stack_depth; i++) 1052136644Sache#endif 105321308Sache if (if_stack[i] == 1) 105421308Sache return 0; 105521308Sache 105621308Sache /* Invert the state of parsing if at top level. */ 105721308Sache _rl_parsing_conditionalized_out = !_rl_parsing_conditionalized_out; 105821308Sache return 0; 105921308Sache} 106021308Sache 106121308Sache/* Terminate a conditional, popping the value of 106221308Sache _rl_parsing_conditionalized_out from the stack. */ 106321308Sachestatic int 106421308Sacheparser_endif (args) 106521308Sache char *args; 106621308Sache{ 106721308Sache if (if_stack_depth) 106821308Sache _rl_parsing_conditionalized_out = if_stack[--if_stack_depth]; 106921308Sache else 107035486Sache _rl_init_file_error ("$endif without matching $if"); 107121308Sache return 0; 107221308Sache} 107321308Sache 107435486Sachestatic int 107535486Sacheparser_include (args) 107635486Sache char *args; 107735486Sache{ 107875406Sache const char *old_init_file; 107975406Sache char *e; 108035486Sache int old_line_number, old_include_level, r; 108135486Sache 108235486Sache if (_rl_parsing_conditionalized_out) 108335486Sache return (0); 108435486Sache 108535486Sache old_init_file = current_readline_init_file; 108635486Sache old_line_number = current_readline_init_lineno; 108735486Sache old_include_level = current_readline_init_include_level; 108835486Sache 108935486Sache e = strchr (args, '\n'); 109035486Sache if (e) 109135486Sache *e = '\0'; 109275406Sache r = _rl_read_init_file ((const char *)args, old_include_level + 1); 109335486Sache 109435486Sache current_readline_init_file = old_init_file; 109535486Sache current_readline_init_lineno = old_line_number; 109635486Sache current_readline_init_include_level = old_include_level; 109735486Sache 109835486Sache return r; 109935486Sache} 110035486Sache 110121308Sache/* Associate textual names with actual functions. */ 110221308Sachestatic struct { 110375406Sache const char *name; 110475406Sache _rl_parser_func_t *function; 110521308Sache} parser_directives [] = { 110621308Sache { "if", parser_if }, 110721308Sache { "endif", parser_endif }, 110821308Sache { "else", parser_else }, 110935486Sache { "include", parser_include }, 111075406Sache { (char *)0x0, (_rl_parser_func_t *)0x0 } 111121308Sache}; 111221308Sache 111321308Sache/* Handle a parser directive. STATEMENT is the line of the directive 111421308Sache without any leading `$'. */ 111521308Sachestatic int 111621308Sachehandle_parser_directive (statement) 111721308Sache char *statement; 111821308Sache{ 111921308Sache register int i; 112021308Sache char *directive, *args; 112121308Sache 112221308Sache /* Isolate the actual directive. */ 112321308Sache 112421308Sache /* Skip whitespace. */ 112521308Sache for (i = 0; whitespace (statement[i]); i++); 112621308Sache 112721308Sache directive = &statement[i]; 112821308Sache 112921308Sache for (; statement[i] && !whitespace (statement[i]); i++); 113021308Sache 113121308Sache if (statement[i]) 113221308Sache statement[i++] = '\0'; 113321308Sache 113421308Sache for (; statement[i] && whitespace (statement[i]); i++); 113521308Sache 113621308Sache args = &statement[i]; 113721308Sache 113821308Sache /* Lookup the command, and act on it. */ 113921308Sache for (i = 0; parser_directives[i].name; i++) 114021308Sache if (_rl_stricmp (directive, parser_directives[i].name) == 0) 114121308Sache { 114221308Sache (*parser_directives[i].function) (args); 114321308Sache return (0); 114421308Sache } 114521308Sache 114635486Sache /* display an error message about the unknown parser directive */ 114735486Sache _rl_init_file_error ("unknown parser directive"); 114821308Sache return (1); 114921308Sache} 115021308Sache 115121308Sache/* Read the binding command from STRING and perform it. 115221308Sache A key binding command looks like: Keyname: function-name\0, 115321308Sache a variable binding command looks like: set variable value. 115421308Sache A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */ 115521308Sacheint 115621308Sacherl_parse_and_bind (string) 115721308Sache char *string; 115821308Sache{ 115921308Sache char *funname, *kname; 116021308Sache register int c, i; 116121308Sache int key, equivalency; 116221308Sache 116321308Sache while (string && whitespace (*string)) 116421308Sache string++; 116521308Sache 116621308Sache if (!string || !*string || *string == '#') 116721308Sache return 0; 116821308Sache 116921308Sache /* If this is a parser directive, act on it. */ 117021308Sache if (*string == '$') 117121308Sache { 117221308Sache handle_parser_directive (&string[1]); 117321308Sache return 0; 117421308Sache } 117521308Sache 117621308Sache /* If we aren't supposed to be parsing right now, then we're done. */ 117721308Sache if (_rl_parsing_conditionalized_out) 117821308Sache return 0; 117921308Sache 118021308Sache i = 0; 118121308Sache /* If this keyname is a complex key expression surrounded by quotes, 118221308Sache advance to after the matching close quote. This code allows the 118321308Sache backslash to quote characters in the key expression. */ 118421308Sache if (*string == '"') 118521308Sache { 118621308Sache int passc = 0; 118721308Sache 118821308Sache for (i = 1; c = string[i]; i++) 118921308Sache { 119021308Sache if (passc) 119121308Sache { 119221308Sache passc = 0; 119321308Sache continue; 119421308Sache } 119521308Sache 119621308Sache if (c == '\\') 119721308Sache { 119821308Sache passc++; 119921308Sache continue; 120021308Sache } 120121308Sache 120221308Sache if (c == '"') 120321308Sache break; 120421308Sache } 120521308Sache /* If we didn't find a closing quote, abort the line. */ 120621308Sache if (string[i] == '\0') 120721308Sache { 120821308Sache _rl_init_file_error ("no closing `\"' in key binding"); 120921308Sache return 1; 121021308Sache } 121121308Sache } 121221308Sache 121321308Sache /* Advance to the colon (:) or whitespace which separates the two objects. */ 121421308Sache for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ ); 121521308Sache 121621308Sache equivalency = (c == ':' && string[i + 1] == '='); 121721308Sache 121821308Sache /* Mark the end of the command (or keyname). */ 121921308Sache if (string[i]) 122021308Sache string[i++] = '\0'; 122121308Sache 122221308Sache /* If doing assignment, skip the '=' sign as well. */ 122321308Sache if (equivalency) 122421308Sache string[i++] = '\0'; 122521308Sache 122621308Sache /* If this is a command to set a variable, then do that. */ 122721308Sache if (_rl_stricmp (string, "set") == 0) 122821308Sache { 1229157184Sache char *var, *value, *e; 123021308Sache 1231157184Sache var = string + i; 123221308Sache /* Make VAR point to start of variable name. */ 123321308Sache while (*var && whitespace (*var)) var++; 123421308Sache 1235119610Sache /* Make VALUE point to start of value string. */ 123621308Sache value = var; 123721308Sache while (*value && !whitespace (*value)) value++; 123821308Sache if (*value) 123921308Sache *value++ = '\0'; 124021308Sache while (*value && whitespace (*value)) value++; 124121308Sache 1242157184Sache /* Strip trailing whitespace from values to boolean variables. Temp 1243157184Sache fix until I get a real quoted-string parser here. */ 1244157184Sache i = find_boolean_var (var); 1245157184Sache if (i >= 0) 1246157184Sache { 1247157184Sache /* remove trailing whitespace */ 1248157184Sache e = value + strlen (value) - 1; 1249157184Sache while (e >= value && whitespace (*e)) 1250157184Sache e--; 1251157184Sache e++; /* skip back to whitespace or EOS */ 1252157184Sache if (*e && e >= value) 1253157184Sache *e = '\0'; 1254157184Sache } 1255157184Sache 125621308Sache rl_variable_bind (var, value); 125721308Sache return 0; 125821308Sache } 125921308Sache 126021308Sache /* Skip any whitespace between keyname and funname. */ 126121308Sache for (; string[i] && whitespace (string[i]); i++); 126221308Sache funname = &string[i]; 126321308Sache 126421308Sache /* Now isolate funname. 126521308Sache For straight function names just look for whitespace, since 126621308Sache that will signify the end of the string. But this could be a 126721308Sache macro definition. In that case, the string is quoted, so skip 126821308Sache to the matching delimiter. We allow the backslash to quote the 126921308Sache delimiter characters in the macro body. */ 127021308Sache /* This code exists to allow whitespace in macro expansions, which 127121308Sache would otherwise be gobbled up by the next `for' loop.*/ 127221308Sache /* XXX - it may be desirable to allow backslash quoting only if " is 127321308Sache the quoted string delimiter, like the shell. */ 127421308Sache if (*funname == '\'' || *funname == '"') 127521308Sache { 1276157184Sache int delimiter, passc; 127721308Sache 1278157184Sache delimiter = string[i++]; 127935486Sache for (passc = 0; c = string[i]; i++) 128021308Sache { 128121308Sache if (passc) 128221308Sache { 128321308Sache passc = 0; 128421308Sache continue; 128521308Sache } 128621308Sache 128721308Sache if (c == '\\') 128821308Sache { 128921308Sache passc = 1; 129021308Sache continue; 129121308Sache } 129221308Sache 129321308Sache if (c == delimiter) 129421308Sache break; 129521308Sache } 129621308Sache if (c) 129721308Sache i++; 129821308Sache } 129921308Sache 130021308Sache /* Advance to the end of the string. */ 130121308Sache for (; string[i] && !whitespace (string[i]); i++); 130221308Sache 130321308Sache /* No extra whitespace at the end of the string. */ 130421308Sache string[i] = '\0'; 130521308Sache 130621308Sache /* Handle equivalency bindings here. Make the left-hand side be exactly 130721308Sache whatever the right-hand evaluates to, including keymaps. */ 130821308Sache if (equivalency) 130921308Sache { 131021308Sache return 0; 131121308Sache } 131221308Sache 131321308Sache /* If this is a new-style key-binding, then do the binding with 1314136644Sache rl_bind_keyseq (). Otherwise, let the older code deal with it. */ 131521308Sache if (*string == '"') 131621308Sache { 131735486Sache char *seq; 131835486Sache register int j, k, passc; 131921308Sache 1320119610Sache seq = (char *)xmalloc (1 + strlen (string)); 132135486Sache for (j = 1, k = passc = 0; string[j]; j++) 132221308Sache { 132321308Sache /* Allow backslash to quote characters, but leave them in place. 132421308Sache This allows a string to end with a backslash quoting another 132521308Sache backslash, or with a backslash quoting a double quote. The 132621308Sache backslashes are left in place for rl_translate_keyseq (). */ 132721308Sache if (passc || (string[j] == '\\')) 132821308Sache { 132921308Sache seq[k++] = string[j]; 133021308Sache passc = !passc; 133121308Sache continue; 133221308Sache } 133321308Sache 133421308Sache if (string[j] == '"') 133521308Sache break; 133621308Sache 133721308Sache seq[k++] = string[j]; 133821308Sache } 133921308Sache seq[k] = '\0'; 134021308Sache 134121308Sache /* Binding macro? */ 134221308Sache if (*funname == '\'' || *funname == '"') 134321308Sache { 134421308Sache j = strlen (funname); 134521308Sache 134621308Sache /* Remove the delimiting quotes from each end of FUNNAME. */ 134721308Sache if (j && funname[j - 1] == *funname) 134821308Sache funname[j - 1] = '\0'; 134921308Sache 135021308Sache rl_macro_bind (seq, &funname[1], _rl_keymap); 135121308Sache } 135221308Sache else 1353136644Sache rl_bind_keyseq (seq, rl_named_function (funname)); 135421308Sache 135521308Sache free (seq); 135621308Sache return 0; 135721308Sache } 135821308Sache 135921308Sache /* Get the actual character we want to deal with. */ 136021308Sache kname = strrchr (string, '-'); 136121308Sache if (!kname) 136221308Sache kname = string; 136321308Sache else 136421308Sache kname++; 136521308Sache 136621308Sache key = glean_key_from_name (kname); 136721308Sache 136821308Sache /* Add in control and meta bits. */ 136975406Sache if (substring_member_of_array (string, _rl_possible_control_prefixes)) 137021308Sache key = CTRL (_rl_to_upper (key)); 137121308Sache 137275406Sache if (substring_member_of_array (string, _rl_possible_meta_prefixes)) 137321308Sache key = META (key); 137421308Sache 137521308Sache /* Temporary. Handle old-style keyname with macro-binding. */ 137621308Sache if (*funname == '\'' || *funname == '"') 137721308Sache { 1378119610Sache char useq[2]; 137921308Sache int fl = strlen (funname); 138021308Sache 138126497Sache useq[0] = key; useq[1] = '\0'; 138221308Sache if (fl && funname[fl - 1] == *funname) 138321308Sache funname[fl - 1] = '\0'; 138421308Sache 138526497Sache rl_macro_bind (useq, &funname[1], _rl_keymap); 138621308Sache } 138721308Sache#if defined (PREFIX_META_HACK) 138821308Sache /* Ugly, but working hack to keep prefix-meta around. */ 138921308Sache else if (_rl_stricmp (funname, "prefix-meta") == 0) 139021308Sache { 139121308Sache char seq[2]; 139221308Sache 139321308Sache seq[0] = key; 139421308Sache seq[1] = '\0'; 139521308Sache rl_generic_bind (ISKMAP, seq, (char *)emacs_meta_keymap, _rl_keymap); 139621308Sache } 139721308Sache#endif /* PREFIX_META_HACK */ 139821308Sache else 139921308Sache rl_bind_key (key, rl_named_function (funname)); 140021308Sache return 0; 140121308Sache} 140221308Sache 140321308Sache/* Simple structure for boolean readline variables (i.e., those that can 140421308Sache have one of two values; either "On" or 1 for truth, or "Off" or 0 for 140521308Sache false. */ 140621308Sache 140758310Sache#define V_SPECIAL 0x1 140858310Sache 140921308Sachestatic struct { 141075406Sache const char *name; 141121308Sache int *value; 141258310Sache int flags; 141321308Sache} boolean_varlist [] = { 1414157184Sache { "bind-tty-special-chars", &_rl_bind_stty_chars, 0 }, 141558310Sache { "blink-matching-paren", &rl_blink_matching_paren, V_SPECIAL }, 1416119610Sache { "byte-oriented", &rl_byte_oriented, 0 }, 141758310Sache { "completion-ignore-case", &_rl_completion_case_fold, 0 }, 141858310Sache { "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 }, 141958310Sache { "disable-completion", &rl_inhibit_completion, 0 }, 142058310Sache { "enable-keypad", &_rl_enable_keypad, 0 }, 142158310Sache { "expand-tilde", &rl_complete_with_tilde_expansion, 0 }, 1422119610Sache { "history-preserve-point", &_rl_history_preserve_point, 0 }, 142358310Sache { "horizontal-scroll-mode", &_rl_horizontal_scroll_mode, 0 }, 142458310Sache { "input-meta", &_rl_meta_flag, 0 }, 142558310Sache { "mark-directories", &_rl_complete_mark_directories, 0 }, 142658310Sache { "mark-modified-lines", &_rl_mark_modified_lines, 0 }, 1427119610Sache { "mark-symlinked-directories", &_rl_complete_mark_symlink_dirs, 0 }, 1428119610Sache { "match-hidden-files", &_rl_match_hidden_files, 0 }, 142958310Sache { "meta-flag", &_rl_meta_flag, 0 }, 143058310Sache { "output-meta", &_rl_output_meta_chars, 0 }, 1431119610Sache { "page-completions", &_rl_page_completions, 0 }, 143258310Sache { "prefer-visible-bell", &_rl_prefer_visible_bell, V_SPECIAL }, 143358310Sache { "print-completions-horizontally", &_rl_print_completions_horizontally, 0 }, 143458310Sache { "show-all-if-ambiguous", &_rl_complete_show_all, 0 }, 1435136644Sache { "show-all-if-unmodified", &_rl_complete_show_unmodified, 0 }, 143621308Sache#if defined (VISIBLE_STATS) 143758310Sache { "visible-stats", &rl_visible_stats, 0 }, 143821308Sache#endif /* VISIBLE_STATS */ 143921308Sache { (char *)NULL, (int *)NULL } 144021308Sache}; 144121308Sache 144258310Sachestatic int 144358310Sachefind_boolean_var (name) 1444119610Sache const char *name; 144558310Sache{ 144658310Sache register int i; 144758310Sache 144858310Sache for (i = 0; boolean_varlist[i].name; i++) 144958310Sache if (_rl_stricmp (name, boolean_varlist[i].name) == 0) 145058310Sache return i; 145158310Sache return -1; 145258310Sache} 145358310Sache 145458310Sache/* Hooks for handling special boolean variables, where a 145558310Sache function needs to be called or another variable needs 145658310Sache to be changed when they're changed. */ 145758310Sachestatic void 145858310Sachehack_special_boolean_var (i) 145958310Sache int i; 146058310Sache{ 146175406Sache const char *name; 146258310Sache 146358310Sache name = boolean_varlist[i].name; 146458310Sache 146558310Sache if (_rl_stricmp (name, "blink-matching-paren") == 0) 146658310Sache _rl_enable_paren_matching (rl_blink_matching_paren); 146758310Sache else if (_rl_stricmp (name, "prefer-visible-bell") == 0) 146858310Sache { 146958310Sache if (_rl_prefer_visible_bell) 147058310Sache _rl_bell_preference = VISIBLE_BELL; 147158310Sache else 147258310Sache _rl_bell_preference = AUDIBLE_BELL; 147358310Sache } 147458310Sache} 147558310Sache 1476119610Sachetypedef int _rl_sv_func_t PARAMS((const char *)); 147775406Sache 147858310Sache/* These *must* correspond to the array indices for the appropriate 147958310Sache string variable. (Though they're not used right now.) */ 148058310Sache#define V_BELLSTYLE 0 148158310Sache#define V_COMBEGIN 1 148258310Sache#define V_EDITMODE 2 148358310Sache#define V_ISRCHTERM 3 148458310Sache#define V_KEYMAP 4 148558310Sache 148658310Sache#define V_STRING 1 148758310Sache#define V_INT 2 148858310Sache 148958310Sache/* Forward declarations */ 1490119610Sachestatic int sv_bell_style PARAMS((const char *)); 1491119610Sachestatic int sv_combegin PARAMS((const char *)); 1492119610Sachestatic int sv_compquery PARAMS((const char *)); 1493119610Sachestatic int sv_editmode PARAMS((const char *)); 1494119610Sachestatic int sv_isrchterm PARAMS((const char *)); 1495119610Sachestatic int sv_keymap PARAMS((const char *)); 149658310Sache 149758310Sachestatic struct { 149875406Sache const char *name; 149958310Sache int flags; 150075406Sache _rl_sv_func_t *set_func; 150158310Sache} string_varlist[] = { 150258310Sache { "bell-style", V_STRING, sv_bell_style }, 150358310Sache { "comment-begin", V_STRING, sv_combegin }, 150458310Sache { "completion-query-items", V_INT, sv_compquery }, 150558310Sache { "editing-mode", V_STRING, sv_editmode }, 150658310Sache { "isearch-terminators", V_STRING, sv_isrchterm }, 150758310Sache { "keymap", V_STRING, sv_keymap }, 150858310Sache { (char *)NULL, 0 } 150958310Sache}; 151058310Sache 151158310Sachestatic int 151258310Sachefind_string_var (name) 1513119610Sache const char *name; 151458310Sache{ 151558310Sache register int i; 151658310Sache 151758310Sache for (i = 0; string_varlist[i].name; i++) 151858310Sache if (_rl_stricmp (name, string_varlist[i].name) == 0) 151958310Sache return i; 152058310Sache return -1; 152158310Sache} 152258310Sache 152358310Sache/* A boolean value that can appear in a `set variable' command is true if 152458310Sache the value is null or empty, `on' (case-insenstive), or "1". Any other 152558310Sache values result in 0 (false). */ 152658310Sachestatic int 152758310Sachebool_to_int (value) 1528157184Sache const char *value; 152958310Sache{ 153058310Sache return (value == 0 || *value == '\0' || 153158310Sache (_rl_stricmp (value, "on") == 0) || 153258310Sache (value[0] == '1' && value[1] == '\0')); 153358310Sache} 153458310Sache 1535157184Sachechar * 1536157184Sacherl_variable_value (name) 1537157184Sache const char *name; 1538157184Sache{ 1539157184Sache register int i; 1540157184Sache 1541157184Sache /* Check for simple variables first. */ 1542157184Sache i = find_boolean_var (name); 1543157184Sache if (i >= 0) 1544157184Sache return (*boolean_varlist[i].value ? "on" : "off"); 1545157184Sache 1546157184Sache i = find_string_var (name); 1547157184Sache if (i >= 0) 1548157184Sache return (_rl_get_string_variable_value (string_varlist[i].name)); 1549157184Sache 1550157184Sache /* Unknown variable names return NULL. */ 1551157184Sache return 0; 1552157184Sache} 1553157184Sache 155421308Sacheint 155521308Sacherl_variable_bind (name, value) 155675406Sache const char *name, *value; 155721308Sache{ 155821308Sache register int i; 155958310Sache int v; 156021308Sache 156121308Sache /* Check for simple variables first. */ 156258310Sache i = find_boolean_var (name); 156358310Sache if (i >= 0) 156421308Sache { 156558310Sache *boolean_varlist[i].value = bool_to_int (value); 156658310Sache if (boolean_varlist[i].flags & V_SPECIAL) 156758310Sache hack_special_boolean_var (i); 156858310Sache return 0; 156921308Sache } 157021308Sache 157158310Sache i = find_string_var (name); 157221308Sache 157358310Sache /* For the time being, unknown variable names or string names without a 157458310Sache handler function are simply ignored. */ 157558310Sache if (i < 0 || string_varlist[i].set_func == 0) 157658310Sache return 0; 157758310Sache 157858310Sache v = (*string_varlist[i].set_func) (value); 157958310Sache return v; 158058310Sache} 158158310Sache 158258310Sachestatic int 158358310Sachesv_editmode (value) 158475406Sache const char *value; 158558310Sache{ 158658310Sache if (_rl_strnicmp (value, "vi", 2) == 0) 158721308Sache { 158821308Sache#if defined (VI_MODE) 158958310Sache _rl_keymap = vi_insertion_keymap; 159058310Sache rl_editing_mode = vi_mode; 159121308Sache#endif /* VI_MODE */ 159258310Sache return 0; 159321308Sache } 159458310Sache else if (_rl_strnicmp (value, "emacs", 5) == 0) 159558310Sache { 159658310Sache _rl_keymap = emacs_standard_keymap; 159758310Sache rl_editing_mode = emacs_mode; 159858310Sache return 0; 159958310Sache } 160058310Sache return 1; 160158310Sache} 160221308Sache 160358310Sachestatic int 160458310Sachesv_combegin (value) 160575406Sache const char *value; 160658310Sache{ 160758310Sache if (value && *value) 160821308Sache { 160958310Sache FREE (_rl_comment_begin); 161058310Sache _rl_comment_begin = savestring (value); 161158310Sache return 0; 161258310Sache } 161358310Sache return 1; 161458310Sache} 161521308Sache 161658310Sachestatic int 161758310Sachesv_compquery (value) 161875406Sache const char *value; 161958310Sache{ 162058310Sache int nval = 100; 162158310Sache 162258310Sache if (value && *value) 162321308Sache { 162458310Sache nval = atoi (value); 162558310Sache if (nval < 0) 162658310Sache nval = 0; 162721308Sache } 162858310Sache rl_completion_query_items = nval; 162958310Sache return 0; 163058310Sache} 163158310Sache 163258310Sachestatic int 163358310Sachesv_keymap (value) 163475406Sache const char *value; 163558310Sache{ 163658310Sache Keymap kmap; 163758310Sache 163858310Sache kmap = rl_get_keymap_by_name (value); 163958310Sache if (kmap) 164021308Sache { 164158310Sache rl_set_keymap (kmap); 164258310Sache return 0; 164321308Sache } 164458310Sache return 1; 164558310Sache} 164658310Sache 164758310Sachestatic int 164858310Sachesv_bell_style (value) 164975406Sache const char *value; 165058310Sache{ 165158310Sache if (value == 0 || *value == '\0') 1652119610Sache _rl_bell_preference = AUDIBLE_BELL; 165358310Sache else if (_rl_stricmp (value, "none") == 0 || _rl_stricmp (value, "off") == 0) 1654119610Sache _rl_bell_preference = NO_BELL; 165558310Sache else if (_rl_stricmp (value, "audible") == 0 || _rl_stricmp (value, "on") == 0) 1656119610Sache _rl_bell_preference = AUDIBLE_BELL; 165758310Sache else if (_rl_stricmp (value, "visible") == 0) 1658119610Sache _rl_bell_preference = VISIBLE_BELL; 165958310Sache else 166058310Sache return 1; 1661119610Sache return 0; 166258310Sache} 166358310Sache 166458310Sachestatic int 166558310Sachesv_isrchterm (value) 166675406Sache const char *value; 166758310Sache{ 166858310Sache int beg, end, delim; 166958310Sache char *v; 167058310Sache 167158310Sache if (value == 0) 167258310Sache return 1; 167358310Sache 167458310Sache /* Isolate the value and translate it into a character string. */ 167558310Sache v = savestring (value); 167658310Sache FREE (_rl_isearch_terminators); 167758310Sache if (v[0] == '"' || v[0] == '\'') 167821308Sache { 167958310Sache delim = v[0]; 168058310Sache for (beg = end = 1; v[end] && v[end] != delim; end++) 168158310Sache ; 168221308Sache } 168358310Sache else 168421308Sache { 168558310Sache for (beg = end = 0; whitespace (v[end]) == 0; end++) 168658310Sache ; 168721308Sache } 168821308Sache 168958310Sache v[end] = '\0'; 169047558Sache 169158310Sache /* The value starts at v + beg. Translate it into a character string. */ 1692119610Sache _rl_isearch_terminators = (char *)xmalloc (2 * strlen (v) + 1); 169358310Sache rl_translate_keyseq (v + beg, _rl_isearch_terminators, &end); 169458310Sache _rl_isearch_terminators[end] = '\0'; 169558310Sache 169658310Sache free (v); 169721308Sache return 0; 169821308Sache} 169958310Sache 170021308Sache/* Return the character which matches NAME. 170121308Sache For example, `Space' returns ' '. */ 170221308Sache 170321308Sachetypedef struct { 170475406Sache const char *name; 170521308Sache int value; 170621308Sache} assoc_list; 170721308Sache 170821308Sachestatic assoc_list name_key_alist[] = { 170921308Sache { "DEL", 0x7f }, 171021308Sache { "ESC", '\033' }, 171121308Sache { "Escape", '\033' }, 171221308Sache { "LFD", '\n' }, 171321308Sache { "Newline", '\n' }, 171421308Sache { "RET", '\r' }, 171521308Sache { "Return", '\r' }, 171621308Sache { "Rubout", 0x7f }, 171721308Sache { "SPC", ' ' }, 171821308Sache { "Space", ' ' }, 171921308Sache { "Tab", 0x09 }, 172021308Sache { (char *)0x0, 0 } 172121308Sache}; 172221308Sache 172321308Sachestatic int 172421308Sacheglean_key_from_name (name) 172521308Sache char *name; 172621308Sache{ 172721308Sache register int i; 172821308Sache 172921308Sache for (i = 0; name_key_alist[i].name; i++) 173021308Sache if (_rl_stricmp (name, name_key_alist[i].name) == 0) 173121308Sache return (name_key_alist[i].value); 173221308Sache 173321308Sache return (*(unsigned char *)name); /* XXX was return (*name) */ 173421308Sache} 173521308Sache 173621308Sache/* Auxiliary functions to manage keymaps. */ 173721308Sachestatic struct { 173875406Sache const char *name; 173921308Sache Keymap map; 174021308Sache} keymap_names[] = { 174121308Sache { "emacs", emacs_standard_keymap }, 174221308Sache { "emacs-standard", emacs_standard_keymap }, 174321308Sache { "emacs-meta", emacs_meta_keymap }, 174421308Sache { "emacs-ctlx", emacs_ctlx_keymap }, 174521308Sache#if defined (VI_MODE) 174621308Sache { "vi", vi_movement_keymap }, 174721308Sache { "vi-move", vi_movement_keymap }, 174821308Sache { "vi-command", vi_movement_keymap }, 174921308Sache { "vi-insert", vi_insertion_keymap }, 175021308Sache#endif /* VI_MODE */ 175121308Sache { (char *)0x0, (Keymap)0x0 } 175221308Sache}; 175321308Sache 175421308SacheKeymap 175521308Sacherl_get_keymap_by_name (name) 175675406Sache const char *name; 175721308Sache{ 175821308Sache register int i; 175921308Sache 176021308Sache for (i = 0; keymap_names[i].name; i++) 176175406Sache if (_rl_stricmp (name, keymap_names[i].name) == 0) 176221308Sache return (keymap_names[i].map); 176321308Sache return ((Keymap) NULL); 176421308Sache} 176521308Sache 176621308Sachechar * 176721308Sacherl_get_keymap_name (map) 176821308Sache Keymap map; 176921308Sache{ 177021308Sache register int i; 177121308Sache for (i = 0; keymap_names[i].name; i++) 177221308Sache if (map == keymap_names[i].map) 177375406Sache return ((char *)keymap_names[i].name); 177421308Sache return ((char *)NULL); 177521308Sache} 177621308Sache 177721308Sachevoid 177821308Sacherl_set_keymap (map) 177921308Sache Keymap map; 178021308Sache{ 178121308Sache if (map) 178221308Sache _rl_keymap = map; 178321308Sache} 178421308Sache 178521308SacheKeymap 178621308Sacherl_get_keymap () 178721308Sache{ 178821308Sache return (_rl_keymap); 178921308Sache} 179021308Sache 179121308Sachevoid 179221308Sacherl_set_keymap_from_edit_mode () 179321308Sache{ 179421308Sache if (rl_editing_mode == emacs_mode) 179521308Sache _rl_keymap = emacs_standard_keymap; 179621308Sache#if defined (VI_MODE) 179721308Sache else if (rl_editing_mode == vi_mode) 179821308Sache _rl_keymap = vi_insertion_keymap; 179921308Sache#endif /* VI_MODE */ 180021308Sache} 180121308Sache 180221308Sachechar * 180321308Sacherl_get_keymap_name_from_edit_mode () 180421308Sache{ 180521308Sache if (rl_editing_mode == emacs_mode) 180621308Sache return "emacs"; 180721308Sache#if defined (VI_MODE) 180821308Sache else if (rl_editing_mode == vi_mode) 180921308Sache return "vi"; 181021308Sache#endif /* VI_MODE */ 181121308Sache else 181221308Sache return "none"; 181321308Sache} 181421308Sache 181521308Sache/* **************************************************************** */ 181621308Sache/* */ 181721308Sache/* Key Binding and Function Information */ 181821308Sache/* */ 181921308Sache/* **************************************************************** */ 182021308Sache 182121308Sache/* Each of the following functions produces information about the 182221308Sache state of keybindings and functions known to Readline. The info 182321308Sache is always printed to rl_outstream, and in such a way that it can 1824136644Sache be read back in (i.e., passed to rl_parse_and_bind ()). */ 182521308Sache 182621308Sache/* Print the names of functions known to Readline. */ 182721308Sachevoid 182821308Sacherl_list_funmap_names () 182921308Sache{ 183021308Sache register int i; 183175406Sache const char **funmap_names; 183221308Sache 183321308Sache funmap_names = rl_funmap_names (); 183421308Sache 183521308Sache if (!funmap_names) 183621308Sache return; 183721308Sache 183821308Sache for (i = 0; funmap_names[i]; i++) 183921308Sache fprintf (rl_outstream, "%s\n", funmap_names[i]); 184021308Sache 184121308Sache free (funmap_names); 184221308Sache} 184321308Sache 184421308Sachestatic char * 184521308Sache_rl_get_keyname (key) 184621308Sache int key; 184721308Sache{ 184821308Sache char *keyname; 184947558Sache int i, c; 185021308Sache 185121308Sache keyname = (char *)xmalloc (8); 185221308Sache 185321308Sache c = key; 185421308Sache /* Since this is going to be used to write out keysequence-function 185521308Sache pairs for possible inclusion in an inputrc file, we don't want to 185621308Sache do any special meta processing on KEY. */ 185721308Sache 1858119610Sache#if 1 1859119610Sache /* XXX - Experimental */ 186021308Sache /* We might want to do this, but the old version of the code did not. */ 186121308Sache 186221308Sache /* If this is an escape character, we don't want to do any more processing. 186321308Sache Just add the special ESC key sequence and return. */ 186421308Sache if (c == ESC) 186521308Sache { 1866119610Sache keyname[0] = '\\'; 1867119610Sache keyname[1] = 'e'; 1868119610Sache keyname[2] = '\0'; 1869119610Sache return keyname; 187021308Sache } 187121308Sache#endif 187221308Sache 187321308Sache /* RUBOUT is translated directly into \C-? */ 187421308Sache if (key == RUBOUT) 187521308Sache { 187621308Sache keyname[0] = '\\'; 187721308Sache keyname[1] = 'C'; 187821308Sache keyname[2] = '-'; 187921308Sache keyname[3] = '?'; 188021308Sache keyname[4] = '\0'; 188121308Sache return keyname; 188221308Sache } 188321308Sache 188421308Sache i = 0; 188521308Sache /* Now add special prefixes needed for control characters. This can 188621308Sache potentially change C. */ 188721308Sache if (CTRL_CHAR (c)) 188821308Sache { 188921308Sache keyname[i++] = '\\'; 189021308Sache keyname[i++] = 'C'; 189121308Sache keyname[i++] = '-'; 189221308Sache c = _rl_to_lower (UNCTRL (c)); 189321308Sache } 189421308Sache 189535486Sache /* XXX experimental code. Turn the characters that are not ASCII or 189635486Sache ISO Latin 1 (128 - 159) into octal escape sequences (\200 - \237). 189735486Sache This changes C. */ 189835486Sache if (c >= 128 && c <= 159) 189935486Sache { 190035486Sache keyname[i++] = '\\'; 190135486Sache keyname[i++] = '2'; 190235486Sache c -= 128; 190335486Sache keyname[i++] = (c / 8) + '0'; 190435486Sache c = (c % 8) + '0'; 190535486Sache } 190635486Sache 190721308Sache /* Now, if the character needs to be quoted with a backslash, do that. */ 190821308Sache if (c == '\\' || c == '"') 190921308Sache keyname[i++] = '\\'; 191021308Sache 191121308Sache /* Now add the key, terminate the string, and return it. */ 191221308Sache keyname[i++] = (char) c; 191321308Sache keyname[i] = '\0'; 191421308Sache 191521308Sache return keyname; 191621308Sache} 191721308Sache 191821308Sache/* Return a NULL terminated array of strings which represent the key 191921308Sache sequences that are used to invoke FUNCTION in MAP. */ 192021308Sachechar ** 192121308Sacherl_invoking_keyseqs_in_map (function, map) 192275406Sache rl_command_func_t *function; 192321308Sache Keymap map; 192421308Sache{ 192521308Sache register int key; 192621308Sache char **result; 192721308Sache int result_index, result_size; 192821308Sache 192921308Sache result = (char **)NULL; 193021308Sache result_index = result_size = 0; 193121308Sache 193221308Sache for (key = 0; key < KEYMAP_SIZE; key++) 193321308Sache { 193421308Sache switch (map[key].type) 193521308Sache { 193621308Sache case ISMACR: 193721308Sache /* Macros match, if, and only if, the pointers are identical. 193821308Sache Thus, they are treated exactly like functions in here. */ 193921308Sache case ISFUNC: 194021308Sache /* If the function in the keymap is the one we are looking for, 194121308Sache then add the current KEY to the list of invoking keys. */ 194221308Sache if (map[key].function == function) 194321308Sache { 194421308Sache char *keyname; 194521308Sache 194621308Sache keyname = _rl_get_keyname (key); 194721308Sache 194821308Sache if (result_index + 2 > result_size) 194921308Sache { 195021308Sache result_size += 10; 1951119610Sache result = (char **)xrealloc (result, result_size * sizeof (char *)); 195221308Sache } 195321308Sache 195421308Sache result[result_index++] = keyname; 195521308Sache result[result_index] = (char *)NULL; 195621308Sache } 195721308Sache break; 195821308Sache 195921308Sache case ISKMAP: 196021308Sache { 196121308Sache char **seqs; 196221308Sache register int i; 196321308Sache 196421308Sache /* Find the list of keyseqs in this map which have FUNCTION as 196521308Sache their target. Add the key sequences found to RESULT. */ 196621308Sache if (map[key].function) 196721308Sache seqs = 196821308Sache rl_invoking_keyseqs_in_map (function, FUNCTION_TO_KEYMAP (map, key)); 196921308Sache else 197021308Sache break; 197121308Sache 197221308Sache if (seqs == 0) 197321308Sache break; 197421308Sache 197521308Sache for (i = 0; seqs[i]; i++) 197621308Sache { 197721308Sache char *keyname = (char *)xmalloc (6 + strlen (seqs[i])); 197821308Sache 197921308Sache if (key == ESC) 1980165670Sache { 1981165670Sache /* If ESC is the meta prefix and we're converting chars 1982165670Sache with the eighth bit set to ESC-prefixed sequences, then 1983165670Sache we can use \M-. Otherwise we need to use the sequence 1984165670Sache for ESC. */ 1985165670Sache if (_rl_convert_meta_chars_to_ascii && map[ESC].type == ISKMAP) 1986165670Sache sprintf (keyname, "\\M-"); 1987165670Sache else 1988165670Sache sprintf (keyname, "\\e"); 1989165670Sache } 199021308Sache else if (CTRL_CHAR (key)) 199121308Sache sprintf (keyname, "\\C-%c", _rl_to_lower (UNCTRL (key))); 199221308Sache else if (key == RUBOUT) 199321308Sache sprintf (keyname, "\\C-?"); 199421308Sache else if (key == '\\' || key == '"') 199521308Sache { 199621308Sache keyname[0] = '\\'; 199721308Sache keyname[1] = (char) key; 199821308Sache keyname[2] = '\0'; 199921308Sache } 200021308Sache else 200121308Sache { 200221308Sache keyname[0] = (char) key; 200321308Sache keyname[1] = '\0'; 200421308Sache } 200521308Sache 200621308Sache strcat (keyname, seqs[i]); 200721308Sache free (seqs[i]); 200821308Sache 200921308Sache if (result_index + 2 > result_size) 201021308Sache { 201121308Sache result_size += 10; 2012119610Sache result = (char **)xrealloc (result, result_size * sizeof (char *)); 201321308Sache } 201421308Sache 201521308Sache result[result_index++] = keyname; 201621308Sache result[result_index] = (char *)NULL; 201721308Sache } 201821308Sache 201921308Sache free (seqs); 202021308Sache } 202121308Sache break; 202221308Sache } 202321308Sache } 202421308Sache return (result); 202521308Sache} 202621308Sache 202721308Sache/* Return a NULL terminated array of strings which represent the key 202821308Sache sequences that can be used to invoke FUNCTION using the current keymap. */ 202921308Sachechar ** 203021308Sacherl_invoking_keyseqs (function) 203175406Sache rl_command_func_t *function; 203221308Sache{ 203321308Sache return (rl_invoking_keyseqs_in_map (function, _rl_keymap)); 203421308Sache} 203521308Sache 203621308Sache/* Print all of the functions and their bindings to rl_outstream. If 203721308Sache PRINT_READABLY is non-zero, then print the output in such a way 203821308Sache that it can be read back in. */ 203921308Sachevoid 204021308Sacherl_function_dumper (print_readably) 204121308Sache int print_readably; 204221308Sache{ 204321308Sache register int i; 204475406Sache const char **names; 204575406Sache const char *name; 204621308Sache 204721308Sache names = rl_funmap_names (); 204821308Sache 204921308Sache fprintf (rl_outstream, "\n"); 205021308Sache 205121308Sache for (i = 0; name = names[i]; i++) 205221308Sache { 205375406Sache rl_command_func_t *function; 205421308Sache char **invokers; 205521308Sache 205621308Sache function = rl_named_function (name); 205721308Sache invokers = rl_invoking_keyseqs_in_map (function, _rl_keymap); 205821308Sache 205921308Sache if (print_readably) 206021308Sache { 206121308Sache if (!invokers) 206221308Sache fprintf (rl_outstream, "# %s (not bound)\n", name); 206321308Sache else 206421308Sache { 206521308Sache register int j; 206621308Sache 206721308Sache for (j = 0; invokers[j]; j++) 206821308Sache { 206921308Sache fprintf (rl_outstream, "\"%s\": %s\n", 207021308Sache invokers[j], name); 207121308Sache free (invokers[j]); 207221308Sache } 207321308Sache 207421308Sache free (invokers); 207521308Sache } 207621308Sache } 207721308Sache else 207821308Sache { 207921308Sache if (!invokers) 208021308Sache fprintf (rl_outstream, "%s is not bound to any keys\n", 208121308Sache name); 208221308Sache else 208321308Sache { 208421308Sache register int j; 208521308Sache 208621308Sache fprintf (rl_outstream, "%s can be found on ", name); 208721308Sache 208821308Sache for (j = 0; invokers[j] && j < 5; j++) 208921308Sache { 209021308Sache fprintf (rl_outstream, "\"%s\"%s", invokers[j], 209121308Sache invokers[j + 1] ? ", " : ".\n"); 209221308Sache } 209321308Sache 209421308Sache if (j == 5 && invokers[j]) 209521308Sache fprintf (rl_outstream, "...\n"); 209621308Sache 209721308Sache for (j = 0; invokers[j]; j++) 209821308Sache free (invokers[j]); 209921308Sache 210021308Sache free (invokers); 210121308Sache } 210221308Sache } 210321308Sache } 210421308Sache} 210521308Sache 210621308Sache/* Print all of the current functions and their bindings to 210721308Sache rl_outstream. If an explicit argument is given, then print 210821308Sache the output in such a way that it can be read back in. */ 210921308Sacheint 211021308Sacherl_dump_functions (count, key) 211121308Sache int count, key; 211221308Sache{ 211326497Sache if (rl_dispatching) 211426497Sache fprintf (rl_outstream, "\r\n"); 211521308Sache rl_function_dumper (rl_explicit_arg); 211621308Sache rl_on_new_line (); 211721308Sache return (0); 211821308Sache} 211921308Sache 212021308Sachestatic void 212121308Sache_rl_macro_dumper_internal (print_readably, map, prefix) 212221308Sache int print_readably; 212321308Sache Keymap map; 212421308Sache char *prefix; 212521308Sache{ 212621308Sache register int key; 212721308Sache char *keyname, *out; 212821308Sache int prefix_len; 212921308Sache 213021308Sache for (key = 0; key < KEYMAP_SIZE; key++) 213121308Sache { 213221308Sache switch (map[key].type) 213321308Sache { 213421308Sache case ISMACR: 213521308Sache keyname = _rl_get_keyname (key); 213626497Sache out = _rl_untranslate_macro_value ((char *)map[key].function); 2137119610Sache 213821308Sache if (print_readably) 213921308Sache fprintf (rl_outstream, "\"%s%s\": \"%s\"\n", prefix ? prefix : "", 214021308Sache keyname, 214121308Sache out ? out : ""); 214221308Sache else 214321308Sache fprintf (rl_outstream, "%s%s outputs %s\n", prefix ? prefix : "", 214421308Sache keyname, 214521308Sache out ? out : ""); 214621308Sache free (keyname); 214726497Sache free (out); 214821308Sache break; 214921308Sache case ISFUNC: 215021308Sache break; 215121308Sache case ISKMAP: 215221308Sache prefix_len = prefix ? strlen (prefix) : 0; 215321308Sache if (key == ESC) 215421308Sache { 2155119610Sache keyname = (char *)xmalloc (3 + prefix_len); 215621308Sache if (prefix) 215721308Sache strcpy (keyname, prefix); 215821308Sache keyname[prefix_len] = '\\'; 215921308Sache keyname[prefix_len + 1] = 'e'; 216021308Sache keyname[prefix_len + 2] = '\0'; 216121308Sache } 216221308Sache else 216321308Sache { 216421308Sache keyname = _rl_get_keyname (key); 216521308Sache if (prefix) 216621308Sache { 2167119610Sache out = (char *)xmalloc (strlen (keyname) + prefix_len + 1); 216821308Sache strcpy (out, prefix); 216921308Sache strcpy (out + prefix_len, keyname); 217021308Sache free (keyname); 217121308Sache keyname = out; 217221308Sache } 217321308Sache } 217421308Sache 217521308Sache _rl_macro_dumper_internal (print_readably, FUNCTION_TO_KEYMAP (map, key), keyname); 217621308Sache free (keyname); 217721308Sache break; 217821308Sache } 217921308Sache } 218021308Sache} 218121308Sache 218221308Sachevoid 218321308Sacherl_macro_dumper (print_readably) 218421308Sache int print_readably; 218521308Sache{ 218621308Sache _rl_macro_dumper_internal (print_readably, _rl_keymap, (char *)NULL); 218721308Sache} 218821308Sache 218921308Sacheint 219021308Sacherl_dump_macros (count, key) 219121308Sache int count, key; 219221308Sache{ 219326497Sache if (rl_dispatching) 219426497Sache fprintf (rl_outstream, "\r\n"); 219521308Sache rl_macro_dumper (rl_explicit_arg); 219621308Sache rl_on_new_line (); 219721308Sache return (0); 219821308Sache} 219921308Sache 2200157184Sachestatic char * 2201157184Sache_rl_get_string_variable_value (name) 2202157184Sache const char *name; 2203157184Sache{ 2204157184Sache static char numbuf[32]; 2205157184Sache char *ret; 2206157184Sache 2207157184Sache if (_rl_stricmp (name, "bell-style") == 0) 2208157184Sache { 2209157184Sache switch (_rl_bell_preference) 2210157184Sache { 2211157184Sache case NO_BELL: 2212157184Sache return "none"; 2213157184Sache case VISIBLE_BELL: 2214157184Sache return "visible"; 2215157184Sache case AUDIBLE_BELL: 2216157184Sache default: 2217157184Sache return "audible"; 2218157184Sache } 2219157184Sache } 2220157184Sache else if (_rl_stricmp (name, "comment-begin") == 0) 2221157184Sache return (_rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT); 2222157184Sache else if (_rl_stricmp (name, "completion-query-items") == 0) 2223157184Sache { 2224157184Sache sprintf (numbuf, "%d", rl_completion_query_items); 2225157184Sache return (numbuf); 2226157184Sache } 2227157184Sache else if (_rl_stricmp (name, "editing-mode") == 0) 2228157184Sache return (rl_get_keymap_name_from_edit_mode ()); 2229157184Sache else if (_rl_stricmp (name, "isearch-terminators") == 0) 2230157184Sache { 2231157184Sache if (_rl_isearch_terminators == 0) 2232157184Sache return 0; 2233157184Sache ret = _rl_untranslate_macro_value (_rl_isearch_terminators); 2234157184Sache if (ret) 2235157184Sache { 2236157184Sache strncpy (numbuf, ret, sizeof (numbuf) - 1); 2237157184Sache free (ret); 2238157184Sache numbuf[sizeof(numbuf) - 1] = '\0'; 2239157184Sache } 2240157184Sache else 2241157184Sache numbuf[0] = '\0'; 2242157184Sache return numbuf; 2243157184Sache } 2244157184Sache else if (_rl_stricmp (name, "keymap") == 0) 2245157184Sache { 2246157184Sache ret = rl_get_keymap_name (_rl_keymap); 2247157184Sache if (ret == 0) 2248157184Sache ret = rl_get_keymap_name_from_edit_mode (); 2249157184Sache return (ret ? ret : "none"); 2250157184Sache } 2251157184Sache else 2252157184Sache return (0); 2253157184Sache} 2254157184Sache 225521308Sachevoid 225621308Sacherl_variable_dumper (print_readably) 225721308Sache int print_readably; 225821308Sache{ 225921308Sache int i; 2260157184Sache char *v; 226121308Sache 226221308Sache for (i = 0; boolean_varlist[i].name; i++) 226321308Sache { 226421308Sache if (print_readably) 226521308Sache fprintf (rl_outstream, "set %s %s\n", boolean_varlist[i].name, 226621308Sache *boolean_varlist[i].value ? "on" : "off"); 226721308Sache else 226821308Sache fprintf (rl_outstream, "%s is set to `%s'\n", boolean_varlist[i].name, 226921308Sache *boolean_varlist[i].value ? "on" : "off"); 227021308Sache } 227121308Sache 2272157184Sache for (i = 0; string_varlist[i].name; i++) 227321308Sache { 2274157184Sache v = _rl_get_string_variable_value (string_varlist[i].name); 2275157184Sache if (v == 0) /* _rl_isearch_terminators can be NULL */ 2276157184Sache continue; 227747558Sache if (print_readably) 2278157184Sache fprintf (rl_outstream, "set %s %s\n", string_varlist[i].name, v); 227947558Sache else 2280157184Sache fprintf (rl_outstream, "%s is set to `%s'\n", string_varlist[i].name, v); 228147558Sache } 228221308Sache} 228321308Sache 228421308Sache/* Print all of the current variables and their values to 228521308Sache rl_outstream. If an explicit argument is given, then print 228621308Sache the output in such a way that it can be read back in. */ 228721308Sacheint 228821308Sacherl_dump_variables (count, key) 228921308Sache int count, key; 229021308Sache{ 229126497Sache if (rl_dispatching) 229226497Sache fprintf (rl_outstream, "\r\n"); 229321308Sache rl_variable_dumper (rl_explicit_arg); 229421308Sache rl_on_new_line (); 229521308Sache return (0); 229621308Sache} 229721308Sache 229821308Sache/* Return non-zero if any members of ARRAY are a substring in STRING. */ 229921308Sachestatic int 230021308Sachesubstring_member_of_array (string, array) 230175406Sache char *string; 230275406Sache const char **array; 230321308Sache{ 230421308Sache while (*array) 230521308Sache { 230621308Sache if (_rl_strindex (string, *array)) 230721308Sache return (1); 230821308Sache array++; 230921308Sache } 231021308Sache return (0); 231121308Sache} 2312