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

📄 readline.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
static sighandlerrl_handle_sigwinch (sig)     int sig;{  char *term;  term = rl_terminal_name;  if (readline_echoing_p)    {      if (!term)	term = getenv ("TERM");      if (!term)	term = "dumb";      rl_reset_terminal (term);#if defined (NOTDEF)      crlf ();      rl_forced_update_display ();#endif /* NOTDEF */    }  if (old_sigwinch &&      old_sigwinch != (SigHandler *)SIG_IGN &&      old_sigwinch != (SigHandler *)SIG_DFL)    (*old_sigwinch) (sig);#if !defined (VOID_SIGHANDLER)  return (0);#endif /* VOID_SIGHANDLER */}#endif  /* SIGWINCH */#if defined (HANDLE_SIGNALS)/* Interrupt handling. */static SigHandler  *old_int  = (SigHandler *)NULL,  *old_tstp = (SigHandler *)NULL,  *old_ttou = (SigHandler *)NULL,  *old_ttin = (SigHandler *)NULL,  *old_cont = (SigHandler *)NULL,  *old_alrm = (SigHandler *)NULL;/* Handle an interrupt character. */static sighandlerrl_signal_handler (sig)     int sig;{#if !defined (HAVE_BSD_SIGNALS)  /* Since the signal will not be blocked while we are in the signal     handler, ignore it until rl_clear_signals resets the catcher. */  if (sig == SIGINT)    signal (sig, SIG_IGN);#endif /* !HAVE_BSD_SIGNALS */  switch (sig)    {    case SIGINT:      free_undo_list ();      rl_clear_message ();      rl_init_argument ();#if defined (SIGTSTP)    case SIGTSTP:    case SIGTTOU:    case SIGTTIN:#endif /* SIGTSTP */    case SIGALRM:      rl_clean_up_for_exit ();      rl_deprep_terminal ();      rl_clear_signals ();      rl_pending_input = 0;      kill (getpid (), sig);      SIGNALS_UNBLOCK;      rl_prep_terminal ();      rl_set_signals ();    }#if !defined (VOID_SIGHANDLER)  return (0);#endif /* !VOID_SIGHANDLER */}rl_set_signals (){  old_int = (SigHandler *)signal (SIGINT, rl_signal_handler);  if (old_int == (SigHandler *)SIG_IGN)    signal (SIGINT, SIG_IGN);  old_alrm = (SigHandler *)signal (SIGALRM, rl_signal_handler);  if (old_alrm == (SigHandler *)SIG_IGN)    signal (SIGALRM, SIG_IGN);#if defined (SIGTSTP)  old_tstp = (SigHandler *)signal (SIGTSTP, rl_signal_handler);  if (old_tstp == (SigHandler *)SIG_IGN)    signal (SIGTSTP, SIG_IGN);#endif#if defined (SIGTTOU)  old_ttou = (SigHandler *)signal (SIGTTOU, rl_signal_handler);  old_ttin = (SigHandler *)signal (SIGTTIN, rl_signal_handler);  if (old_tstp == (SigHandler *)SIG_IGN)    {      signal (SIGTTOU, SIG_IGN);      signal (SIGTTIN, SIG_IGN);    }#endif#if defined (SIGWINCH)  old_sigwinch = (SigHandler *)signal (SIGWINCH, rl_handle_sigwinch);#endif}rl_clear_signals (){  signal (SIGINT, old_int);  signal (SIGALRM, old_alrm);#if defined (SIGTSTP)  signal (SIGTSTP, old_tstp);#endif#if defined (SIGTTOU)  signal (SIGTTOU, old_ttou);  signal (SIGTTIN, old_ttin);#endif#if defined (SIGWINCH)      signal (SIGWINCH, old_sigwinch);#endif}#endif  /* HANDLE_SIGNALS *//* **************************************************************** *//*								    *//*			Character Input Buffering       	    *//*								    *//* **************************************************************** */#if defined (USE_XON_XOFF)/* If the terminal was in xoff state when we got to it, then xon_char   contains the character that is supposed to start it again. */static int xon_char, xoff_state;#endif /* USE_XON_XOFF */static int pop_index = 0, push_index = 0, ibuffer_len = 511;static unsigned char ibuffer[512];/* Non-null means it is a pointer to a function to run while waiting for   character input. */Function *rl_event_hook = (Function *)NULL;#define any_typein (push_index != pop_index)/* Add KEY to the buffer of characters to be read. */rl_stuff_char (key)     int key;{  if (key == EOF)    {      key = NEWLINE;      rl_pending_input = EOF;    }  ibuffer[push_index++] = key;  if (push_index >= ibuffer_len)    push_index = 0;}/* Return the amount of space available in the   buffer for stuffing characters. */intibuffer_space (){  if (pop_index > push_index)    return (pop_index - push_index);  else    return (ibuffer_len - (push_index - pop_index));}/* Get a key from the buffer of characters to be read.   Return the key in KEY.   Result is KEY if there was a key, or 0 if there wasn't. */intrl_get_char (key)     int *key;{  if (push_index == pop_index)    return (0);  *key = ibuffer[pop_index++];  if (pop_index >= ibuffer_len)    pop_index = 0;  return (1);}/* Stuff KEY into the *front* of the input buffer.   Returns non-zero if successful, zero if there is   no space left in the buffer. */intrl_unget_char (key)     int key;{  if (ibuffer_space ())    {      pop_index--;      if (pop_index < 0)	pop_index = ibuffer_len - 1;      ibuffer[pop_index] = key;      return (1);    }  return (0);}/* If a character is available to be read, then read it   and stuff it into IBUFFER.  Otherwise, just return. */rl_gather_tyi (){#ifdef __GO32__  char input;  if (isatty(0))  {    int i = rl_getc();    if (i != EOF)      rl_stuff_char(i);  }  else    if (kbhit() && ibuffer_space())      rl_stuff_char(getkey());#else  int tty = fileno (in_stream);  register int tem, result = -1;  long chars_avail;  char input;#if defined (FIONREAD)  result = ioctl (tty, FIONREAD, &chars_avail);#endif  if (result == -1)    {      int flags;      flags = fcntl (tty, F_GETFL, 0);      fcntl (tty, F_SETFL, (flags | O_NDELAY));      chars_avail = read (tty, &input, 1);      fcntl (tty, F_SETFL, flags);      if (chars_avail == -1 && errno == EAGAIN)	return;    }  /* If there's nothing available, don't waste time trying to read     something. */  if (chars_avail == 0)    return;  tem = ibuffer_space ();  if (chars_avail > tem)    chars_avail = tem;  /* One cannot read all of the available input.  I can only read a single     character at a time, or else programs which require input can be     thwarted.  If the buffer is larger than one character, I lose.     Damn! */  if (tem < ibuffer_len)    chars_avail = 0;  if (result != -1)    {      while (chars_avail--)	rl_stuff_char (rl_getc (in_stream));    }  else    {      if (chars_avail)	rl_stuff_char (input);    }#endif /* def __GO32__/else */}static int next_macro_key ();/* Read a key, including pending input. */intrl_read_key (){  int c;  rl_key_sequence_length++;  if (rl_pending_input)    {      c = rl_pending_input;      rl_pending_input = 0;    }  else    {      /* If input is coming from a macro, then use that. */      if (c = next_macro_key ())	return (c);      /* If the user has an event function, then call it periodically. */      if (rl_event_hook)	{	  while (rl_event_hook && !rl_get_char (&c))	    {	      (*rl_event_hook) ();	      rl_gather_tyi ();	    }	}      else	{	  if (!rl_get_char (&c))	    c = rl_getc (in_stream);	}    }  return (c);}/* I'm beginning to hate the declaration rules for various compilers. */static void add_macro_char (), with_macro_input ();/* Do the command associated with KEY in MAP.   If the associated command is really a keymap, then read   another key, and dispatch into that map. */rl_dispatch (key, map)     register int key;     Keymap map;{  if (defining_kbd_macro)    add_macro_char (key);  if (key > 127 && key < 256)    {      if (map[ESC].type == ISKMAP)	{	  map = (Keymap)map[ESC].function;	  key -= 128;	  rl_dispatch (key, map);	}      else	ding ();      return;    }  switch (map[key].type)    {    case ISFUNC:      {	Function *func = map[key].function;	if (func != (Function *)NULL)	  {	    /* Special case rl_do_lowercase_version (). */	    if (func == rl_do_lowercase_version)	      {		rl_dispatch (to_lower (key), map);		return;	      }	    (*map[key].function)(rl_numeric_arg * rl_arg_sign, key);	    /* If we have input pending, then the last command was a prefix	       command.  Don't change the state of rl_last_func.  Otherwise,	       remember the last command executed in this variable. */	    if (!rl_pending_input)	      rl_last_func = map[key].function;	  }	else	  {	    rl_abort ();	    return;	  }      }      break;    case ISKMAP:      if (map[key].function != (Function *)NULL)	{	  int newkey;	  rl_key_sequence_length++;	  newkey = rl_read_key ();	  rl_dispatch (newkey, (Keymap)map[key].function);	}      else	{	  rl_abort ();	  return;	}      break;    case ISMACR:      if (map[key].function != (Function *)NULL)	{	  char *macro;	  macro = savestring ((char *)map[key].function);	  with_macro_input (macro);	  return;	}      break;    }}/* **************************************************************** *//*								    *//*			Hacking Keyboard Macros 		    *//*								    *//* **************************************************************** *//* The currently executing macro string.  If this is non-zero,   then it is a malloc ()'ed string where input is coming from. */static char *executing_macro = (char *)NULL;/* The offset in the above string to the next character to be read. */static int executing_macro_index = 0;/* The current macro string being built.  Characters get stuffed   in here by add_macro_char (). */static char *current_macro = (char *)NULL;/* The size of the buffer allocated to current_macro. */static int current_macro_size = 0;/* The index at which characters are being added to current_macro. */static int current_macro_index = 0;/* A structure used to save nested macro strings.   It is a linked list of string/index for each saved macro. */struct saved_macro {  struct saved_macro *next;  char *string;  int index;};/* The list of saved macros. */struct saved_macro *macro_list = (struct saved_macro *)NULL;/* Forward declarations of static functions.  Thank you C. */static void push_executing_macro (), pop_executing_macro ();/* This one has to be declared earlier in the file. *//* static void add_macro_char (); *//* Set up to read subsequent input from STRING.   STRING is free ()'ed when we are done with it. */static voidwith_macro_input (string)     char *string;{  push_executing_macro ();  executing_macro = string;  executing_macro_index = 0;}/* Return the next character available from a macro, or 0 if   there are no macro characters. */static intnext_macro_key (){  if (!executing_macro)    return (0);  if (!executing_macro[executing_macro_index])    {      pop_executing_macro ();      return (next_macro_key ());    }  return (executing_macro[executing_macro_index++]);}/* Save the currently executing macro on a stack of saved macros. */static voidpush_executing_macro (){  struct saved_macro *saver;  saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro));  saver->next = macro_list;  saver->index = executing_macro_index;  saver->string = executing_macro;  macro_list = saver;}/* Discard the current macro, replacing it with the one   on the top of the stack of saved macros. */static voidpop_executing_macro (){  if (executing_macro)    free (executing_macro);  executing_macro = (char *)NULL;  executing_macro_index = 0;  if (macro_list)    {      struct saved_macro *disposer = macro_list;      executing_macro = macro_list->string;      executing_macro_index = macro_list->index;      macro_list = macro_list->next;      free (disposer);    }}/* Add a character to the macro being built. */static voidadd_macro_char (c)     int c;{  if (current_macro_index + 1 >= current_macro_size)    {      if (!current_macro)	current_macro = (char *)xmalloc (current_macro_size = 25);      else	current_macro =	  (char *)xrealloc (current_macro, current_macro_size += 25);    }  current_macro[current_macro_index++] = c;  current_macro[current_macro_index] = '\0';}

⌨️ 快捷键说明

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