⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bind.c

📁 android-w.song.android.widget
💻 C
📖 第 1 页 / 共 4 页
字号:
/* bind.c -- key binding and startup file support for the readline library. *//* Copyright (C) 1987-2010 Free Software Foundation, Inc.   This file is part of the GNU Readline Library (Readline), a library   for reading lines of text with interactive input and history editing.   Readline is free software: you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation, either version 3 of the License, or   (at your option) any later version.   Readline is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with Readline.  If not, see <http://www.gnu.org/licenses/>.*/#define READLINE_LIBRARY#if defined (__TANDEM)#  include <floss.h>#endif#if defined (HAVE_CONFIG_H)#  include <config.h>#endif#include <stdio.h>#include <sys/types.h>#include <fcntl.h>#if defined (HAVE_SYS_FILE_H)#  include <sys/file.h>#endif /* HAVE_SYS_FILE_H */#if defined (HAVE_UNISTD_H)#  include <unistd.h>#endif /* HAVE_UNISTD_H */#if defined (HAVE_STDLIB_H)#  include <stdlib.h>#else#  include "ansi_stdlib.h"#endif /* HAVE_STDLIB_H */#include <errno.h>#if !defined (errno)extern int errno;#endif /* !errno */#include "posixstat.h"/* System-specific feature definitions and include files. */#include "rldefs.h"/* Some standard library routines. */#include "readline.h"#include "history.h"#include "rlprivate.h"#include "rlshell.h"#include "xmalloc.h"#if !defined (strchr) && !defined (__STDC__)extern char *strchr (), *strrchr ();#endif /* !strchr && !__STDC__ *//* Variables exported by this file. */Keymap rl_binding_keymap;static char *_rl_read_file PARAMS((char *, size_t *));static void _rl_init_file_error PARAMS((const char *));static int _rl_read_init_file PARAMS((const char *, int));static int glean_key_from_name PARAMS((char *));static int find_boolean_var PARAMS((const char *));static char *_rl_get_string_variable_value PARAMS((const char *));static int substring_member_of_array PARAMS((const char *, const char * const *));static int currently_reading_init_file;/* used only in this file */static int _rl_prefer_visible_bell = 1;/* **************************************************************** *//*								    *//*			Binding keys				    *//*								    *//* **************************************************************** *//* rl_add_defun (char *name, rl_command_func_t *function, int key)   Add NAME to the list of named functions.  Make FUNCTION be the function   that gets called.  If KEY is not -1, then bind it. */intrl_add_defun (name, function, key)     const char *name;     rl_command_func_t *function;     int key;{  if (key != -1)    rl_bind_key (key, function);  rl_add_funmap_entry (name, function);  return 0;}/* Bind KEY to FUNCTION.  Returns non-zero if KEY is out of range. */intrl_bind_key (key, function)     int key;     rl_command_func_t *function;{  if (key < 0)    return (key);  if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)    {      if (_rl_keymap[ESC].type == ISKMAP)	{	  Keymap escmap;	  escmap = FUNCTION_TO_KEYMAP (_rl_keymap, ESC);	  key = UNMETA (key);	  escmap[key].type = ISFUNC;	  escmap[key].function = function;	  return (0);	}      return (key);    }  _rl_keymap[key].type = ISFUNC;  _rl_keymap[key].function = function;  rl_binding_keymap = _rl_keymap;  return (0);}/* Bind KEY to FUNCTION in MAP.  Returns non-zero in case of invalid   KEY. */intrl_bind_key_in_map (key, function, map)     int key;     rl_command_func_t *function;     Keymap map;{  int result;  Keymap oldmap;  oldmap = _rl_keymap;  _rl_keymap = map;  result = rl_bind_key (key, function);  _rl_keymap = oldmap;  return (result);}/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound.  Right   now, this is always used to attempt to bind the arrow keys, hence the   check for rl_vi_movement_mode. */intrl_bind_key_if_unbound_in_map (key, default_func, kmap)     int key;     rl_command_func_t *default_func;     Keymap kmap;{  char keyseq[2];  keyseq[0] = (unsigned char)key;  keyseq[1] = '\0';  return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap));}intrl_bind_key_if_unbound (key, default_func)     int key;     rl_command_func_t *default_func;{  char keyseq[2];  keyseq[0] = (unsigned char)key;  keyseq[1] = '\0';  return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap));}/* Make KEY do nothing in the currently selected keymap.   Returns non-zero in case of error. */intrl_unbind_key (key)     int key;{  return (rl_bind_key (key, (rl_command_func_t *)NULL));}/* Make KEY do nothing in MAP.   Returns non-zero in case of error. */intrl_unbind_key_in_map (key, map)     int key;     Keymap map;{  return (rl_bind_key_in_map (key, (rl_command_func_t *)NULL, map));}/* Unbind all keys bound to FUNCTION in MAP. */intrl_unbind_function_in_map (func, map)     rl_command_func_t *func;     Keymap map;{  register int i, rval;  for (i = rval = 0; i < KEYMAP_SIZE; i++)    {      if (map[i].type == ISFUNC && map[i].function == func)	{	  map[i].function = (rl_command_func_t *)NULL;	  rval = 1;	}    }  return rval;}intrl_unbind_command_in_map (command, map)     const char *command;     Keymap map;{  rl_command_func_t *func;  func = rl_named_function (command);  if (func == 0)    return 0;  return (rl_unbind_function_in_map (func, map));}/* Bind the key sequence represented by the string KEYSEQ to   FUNCTION, starting in the current keymap.  This makes new   keymaps as necessary. */intrl_bind_keyseq (keyseq, function)     const char *keyseq;     rl_command_func_t *function;{  return (rl_generic_bind (ISFUNC, keyseq, (char *)function, _rl_keymap));}/* Bind the key sequence represented by the string KEYSEQ to   FUNCTION.  This makes new keymaps as necessary.  The initial   place to do bindings is in MAP. */intrl_bind_keyseq_in_map (keyseq, function, map)     const char *keyseq;     rl_command_func_t *function;     Keymap map;{  return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));}/* Backwards compatibility; equivalent to rl_bind_keyseq_in_map() */intrl_set_key (keyseq, function, map)     const char *keyseq;     rl_command_func_t *function;     Keymap map;{  return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));}/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound.  Right   now, this is always used to attempt to bind the arrow keys, hence the   check for rl_vi_movement_mode. */intrl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap)     const char *keyseq;     rl_command_func_t *default_func;     Keymap kmap;{  rl_command_func_t *func;  if (keyseq)    {      func = rl_function_of_keyseq (keyseq, kmap, (int *)NULL);#if defined (VI_MODE)      if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode)#else      if (!func || func == rl_do_lowercase_version)#endif	return (rl_bind_keyseq_in_map (keyseq, default_func, kmap));      else	return 1;    }  return 0;}intrl_bind_keyseq_if_unbound (keyseq, default_func)     const char *keyseq;     rl_command_func_t *default_func;{  return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap));}/* Bind the key sequence represented by the string KEYSEQ to   the string of characters MACRO.  This makes new keymaps as   necessary.  The initial place to do bindings is in MAP. */intrl_macro_bind (keyseq, macro, map)     const char *keyseq, *macro;     Keymap map;{  char *macro_keys;  int macro_keys_len;  macro_keys = (char *)xmalloc ((2 * strlen (macro)) + 1);  if (rl_translate_keyseq (macro, macro_keys, &macro_keys_len))    {      xfree (macro_keys);      return -1;    }  rl_generic_bind (ISMACR, keyseq, macro_keys, map);  return 0;}/* Bind the key sequence represented by the string KEYSEQ to   the arbitrary pointer DATA.  TYPE says what kind of data is   pointed to by DATA, right now this can be a function (ISFUNC),   a macro (ISMACR), or a keymap (ISKMAP).  This makes new keymaps   as necessary.  The initial place to do bindings is in MAP. */intrl_generic_bind (type, keyseq, data, map)     int type;     const char *keyseq;     char *data;     Keymap map;{  char *keys;  int keys_len;  register int i;  KEYMAP_ENTRY k;  k.function = 0;  /* If no keys to bind to, exit right away. */  if (keyseq == 0 || *keyseq == 0)    {      if (type == ISMACR)	xfree (data);      return -1;    }  keys = (char *)xmalloc (1 + (2 * strlen (keyseq)));  /* Translate the ASCII representation of KEYSEQ into an array of     characters.  Stuff the characters into KEYS, and the length of     KEYS into KEYS_LEN. */  if (rl_translate_keyseq (keyseq, keys, &keys_len))    {      xfree (keys);      return -1;    }  /* Bind keys, making new keymaps as necessary. */  for (i = 0; i < keys_len; i++)    {      unsigned char uc = keys[i];      int ic;      ic = uc;      if (ic < 0 || ic >= KEYMAP_SIZE)        {          xfree (keys);	  return -1;        }      if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)	{	  ic = UNMETA (ic);	  if (map[ESC].type == ISKMAP)	    map = FUNCTION_TO_KEYMAP (map, ESC);	}      if ((i + 1) < keys_len)	{	  if (map[ic].type != ISKMAP)	    {	      /* We allow subsequences of keys.  If a keymap is being		 created that will `shadow' an existing function or macro		 key binding, we save that keybinding into the ANYOTHERKEY		 index in the new map.  The dispatch code will look there		 to find the function to execute if the subsequence is not		 matched.  ANYOTHERKEY was chosen to be greater than		 UCHAR_MAX. */	      k = map[ic];	      map[ic].type = ISKMAP;	      map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap());	    }	  map = FUNCTION_TO_KEYMAP (map, ic);	  /* The dispatch code will return this function if no matching	     key sequence is found in the keymap.  This (with a little	     help from the dispatch code in readline.c) allows `a' to be	     mapped to something, `abc' to be mapped to something else,	     and the function bound  to `a' to be executed when the user	     types `abx', leaving `bx' in the input queue. */	  if (k.function && ((k.type == ISFUNC && k.function != rl_do_lowercase_version) || k.type == ISMACR))	    {	      map[ANYOTHERKEY] = k;	      k.function = 0;	    }	}      else	{	  if (map[ic].type == ISMACR)	    xfree ((char *)map[ic].function);	  else if (map[ic].type == ISKMAP)	    {	      map = FUNCTION_TO_KEYMAP (map, ic);	      ic = ANYOTHERKEY;	      /* If we're trying to override a keymap with a null function		 (e.g., trying to unbind it), we can't use a null pointer		 here because that's indistinguishable from having not been		 overridden.  We use a special bindable function that does		 nothing. */	      if (type == ISFUNC && data == 0)		data = (char *)_rl_null_function;	    }	  map[ic].function = KEYMAP_TO_FUNCTION (data);	  map[ic].type = type;	}      rl_binding_keymap = map;    }  xfree (keys);  return 0;}/* Translate the ASCII representation of SEQ, stuffing the values into ARRAY,   an array of characters.  LEN gets the final length of ARRAY.  Return   non-zero if there was an error parsing SEQ. */intrl_translate_keyseq (seq, array, len)     const char *seq;     char *array;     int *len;{  register int i, c, l, temp;  for (i = l = 0; c = seq[i]; i++)    {      if (c == '\\')	{	  c = seq[++i];	  if (c == 0)	    break;	  /* Handle \C- and \M- prefixes. */	  if ((c == 'C' || c == 'M') && seq[i + 1] == '-')	    {	      /* Handle special case of backwards define. */	      if (strncmp (&seq[i], "C-\\M-", 5) == 0)		{		  array[l++] = ESC;	/* ESC is meta-prefix */		  i += 5;		  array[l++] = CTRL (_rl_to_upper (seq[i]));		  if (seq[i] == '\0')		    i--;		}	      else if (c == 'M')		{		  i++;		/* seq[i] == '-' */		  /* XXX - obey convert-meta setting */		  if (_rl_convert_meta_chars_to_ascii && _rl_keymap[ESC].type == ISKMAP)		    array[l++] = ESC;	/* ESC is meta-prefix */		  else if (seq[i+1] == '\\' && seq[i+2] == 'C' && seq[i+3] == '-')		    {		      i += 4;		      temp = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i]));		      array[l++] = META (temp);		    }		  else		    {		      /* This doesn't yet handle things like \M-\a, which may			 or may not have any reasonable meaning.  You're			 probably better off using straight octal or hex. */		      i++;		      array[l++] = META (seq[i]);		    }		}	      else if (c == 'C')		{		  i += 2;		  /* Special hack for C-?... */		  array[l++] = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i]));		}	      continue;	    }	      	  /* Translate other backslash-escaped characters.  These are the	     same escape sequences that bash's `echo' and `printf' builtins	     handle, with the addition of \d -> RUBOUT.  A backslash	     preceding a character that is not special is stripped. */	  switch (c)	    {	    case 'a':	      array[l++] = '\007';	      break;	    case 'b':	      array[l++] = '\b';	      break;	    case 'd':	      array[l++] = RUBOUT;	/* readline-specific */	      break;	    case 'e':	      array[l++] = ESC;	      break;	    case 'f':	      array[l++] = '\f';	      break;	    case 'n':	      array[l++] = NEWLINE;	      break;	    case 'r':	      array[l++] = RETURN;	      break;	    case 't':	      array[l++] = TAB;	      break;	    case 'v':	      array[l++] = 0x0B;	      break;	    case '\\':	      array[l++] = '\\';	      break;	    case '0': case '1': case '2': case '3':	    case '4': case '5': case '6': case '7':	      i++;	      for (temp = 2, c -= '0'; ISOCTAL (seq[i]) && temp--; i++)	        c = (c * 8) + OCTVALUE (seq[i]);	      i--;	/* auto-increment in for loop */	      array[l++] = c & largest_char;	      break;	    case 'x':	      i++;	      for (temp = 2, c = 0; ISXDIGIT ((unsigned char)seq[i]) && temp--; i++)	        c = (c * 16) + HEXVALUE (seq[i]);	      if (temp == 2)	        c = 'x';	      i--;	/* auto-increment in for loop */	      array[l++] = c & largest_char;	      break;	    default:	/* backslashes before non-special chars just add the char */	      array[l++] = c;	      break;	/* the backslash is stripped */	    }	  continue;	}      array[l++] = c;    }  *len = l;  array[l] = '\0';  return (0);}char *rl_untranslate_keyseq (seq)     int seq;{  static char kseq[16];  int i, c;  i = 0;  c = seq;  if (META_CHAR (c))    {      kseq[i++] = '\\';      kseq[i++] = 'M';      kseq[i++] = '-';      c = UNMETA (c);    }  else if (c == ESC)    {      kseq[i++] = '\\';      c = 'e';    }  else if (CTRL_CHAR (c))    {      kseq[i++] = '\\';      kseq[i++] = 'C';      kseq[i++] = '-';      c = _rl_to_lower (UNCTRL (c));    }  else if (c == RUBOUT)    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -