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

📄 bind.c

📁 UNIX下SH的实现源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* bind.c -- key binding and startup file support for the readline library. *//* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.   This file is part of the GNU Readline Library, a library for   reading lines of text with interactive input and history editing.   The GNU Readline Library 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 2, or   (at your option) any later version.   The GNU Readline Library 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.   The GNU General Public License is often shipped with GNU software, and   is generally kept in a file called COPYING or LICENSE.  If you do not   have a copy of the license, write to the Free Software Foundation,   59 Temple Place, Suite 330, Boston, MA 02111 USA. */#define READLINE_LIBRARY#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 int _rl_read_init_file __P((char *, int));static int glean_key_from_name __P((char *));static int substring_member_of_array __P((char *, char **));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, Function *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)     char *name;     Function *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;     Function *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;     Function *function;     Keymap map;{  int result;  Keymap oldmap;  oldmap = _rl_keymap;  _rl_keymap = map;  result = rl_bind_key (key, function);  _rl_keymap = oldmap;  return (result);}/* 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, (Function *)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, (Function *)NULL, map));}/* Unbind all keys bound to FUNCTION in MAP. */intrl_unbind_function_in_map (func, map)     Function *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 = (Function *)NULL;	  rval = 1;	}    }  return rval;}intrl_unbind_command_in_map (command, map)     char *command;     Keymap map;{  Function *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.  This makes new keymaps as necessary.  The initial   place to do bindings is in MAP. */intrl_set_key (keyseq, function, map)     char *keyseq;     Function *function;     Keymap map;{  return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));}/* 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)     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))    {      free (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;     char *keyseq, *data;     Keymap map;{  char *keys;  int keys_len;  register int i;  /* If no keys to bind to, exit right away. */  if (!keyseq || !*keyseq)    {      if (type == ISMACR)	free (data);      return -1;    }  keys = 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))    {      free (keys);      return -1;    }  /* Bind keys, making new keymaps as necessary. */  for (i = 0; i < keys_len; i++)    {      int ic = (int) ((unsigned char)keys[i]);      if (_rl_convert_meta_chars_to_ascii && META_CHAR (ic))	{	  ic = UNMETA (ic);	  if (map[ESC].type == ISKMAP)	    map = FUNCTION_TO_KEYMAP (map, ESC);	}      if ((i + 1) < keys_len)	{	  if (map[ic].type != ISKMAP)	    {	      if (map[ic].type == ISMACR)		free ((char *)map[ic].function);	      map[ic].type = ISKMAP;	      map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap());	    }	  map = FUNCTION_TO_KEYMAP (map, ic);	}      else	{	  if (map[ic].type == ISMACR)	    free ((char *)map[ic].function);	  map[ic].function = KEYMAP_TO_FUNCTION (data);	  map[ic].type = type;	}      rl_binding_keymap = map;    }  free (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)     char *seq, *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;		  i += 5;		  array[l++] = CTRL (_rl_to_upper (seq[i]));		  if (seq[i] == '\0')		    i--;		}	      else if (c == 'M')		{		  i++;		  array[l++] = ESC;	/* XXX */		}	      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 + 1);	      break;	    case 'x':	      i++;	      for (temp = 3, c = 0; isxdigit (seq[i]) && temp--; i++)	        c = (c * 16) + HEXVALUE (seq[i]);	      if (temp == 3)	        c = 'x';	      i--;	/* auto-increment in for loop */	      array[l++] = c % (largest_char + 1);	      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 (CTRL_CHAR (c))    {      kseq[i++] = '\\';      kseq[i++] = 'C';      kseq[i++] = '-';      c = _rl_to_lower (UNCTRL (c));    }  else if (c == RUBOUT)    {      kseq[i++] = '\\';      kseq[i++] = 'C';      kseq[i++] = '-';      c = '?';    }  if (c == ESC)    {      kseq[i++] = '\\';      c = 'e';    }  else if (c == '\\' || c == '"')    {      kseq[i++] = '\\';    }  kseq[i++] = (unsigned char) c;  kseq[i] = '\0';  return kseq;}static char *_rl_untranslate_macro_value (seq)     char *seq;{  char *ret, *r, *s;  int c;  r = ret = xmalloc (7 * strlen (seq) + 1);  for (s = seq; *s; s++)    {      c = *s;      if (META_CHAR (c))	{	  *r++ = '\\';	  *r++ = 'M';	  *r++ = '-';	  c = UNMETA (c);	}      else if (CTRL_CHAR (c) && c != ESC)	{	  *r++ = '\\';	  *r++ = 'C';	  *r++ = '-';	  c = _rl_to_lower (UNCTRL (c));	}      else if (c == RUBOUT) 	{ 	  *r++ = '\\'; 	  *r++ = 'C'; 	  *r++ = '-'; 	  c = '?'; 	}      if (c == ESC)	{	  *r++ = '\\';	  c = 'e';	}      else if (c == '\\' || c == '"')	*r++ = '\\';      *r++ = (unsigned char)c;    }  *r = '\0';  return ret;}/* Return a pointer to the function that STRING represents.   If STRING doesn't have a matching function, then a NULL pointer   is returned. */Function *rl_named_function (string)     char *string;{  register int i;  rl_initialize_funmap ();  for (i = 0; funmap[i]; i++)    if (_rl_stricmp (funmap[i]->name, string) == 0)      return (funmap[i]->function);

⌨️ 快捷键说明

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