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

📄 readline.c

📁 linux下bash的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* readline.c -- a general facility for reading lines of input   with emacs style editing and completion. *//* 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 1, 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,   675 Mass Ave, Cambridge, MA 02139, USA. */#define READLINE_LIBRARY#include <stdio.h>#include <sys/types.h>#include <fcntl.h>#if !defined (NO_SYS_FILE)#  include <sys/file.h>#endif /* !NO_SYS_FILE */#include <signal.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>/* Not all systems declare ERRNO in errno.h... and some systems #define it! */#if !defined (errno)extern int errno;#endif /* !errno */#include <setjmp.h>#include "posixstat.h"/* System-specific feature definitions and include files. */#include "rldefs.h"#if defined (GWINSZ_IN_SYS_IOCTL) || (defined (VSTATUS) && !defined (SunOS4))#  include <sys/ioctl.h>#endif /* GWINSZ_IN_SYS_IOCTL || VSTATUS *//* Some standard library routines. */#include "readline.h"#include "history.h"/* NOTE: Functions and variables prefixed with `_rl_' are   pseudo-global: they are global so they can be shared   between files in the readline library, but are not intended   to be visible to readline callers. *//* Functions imported from other files in the library. */extern char *tgetstr ();extern void rl_prep_terminal (), rl_deprep_terminal ();extern void _rl_bind_if_unbound ();/* External redisplay functions and variables from display.c */extern void _rl_move_vert ();extern void _rl_update_final ();extern void _rl_erase_at_end_of_line ();extern void _rl_move_cursor_relative ();extern int _rl_vis_botlin;extern int _rl_last_c_pos;extern int _rl_horizontal_scroll_mode;extern int rl_display_fixed;extern char *rl_display_prompt;/* Variables imported from complete.c. */extern char *rl_completer_word_break_characters;extern char *rl_basic_word_break_characters;extern int rl_completion_query_items;extern int rl_complete_with_tilde_expansion;#if defined (VI_MODE)extern void _rl_vi_set_last ();extern void _rl_vi_reset_last ();extern void _rl_vi_done_inserting ();#endif /* VI_MODE *//* Forward declarations used in this file. */void _rl_free_history_entry ();int _rl_dispatch ();void _rl_set_screen_size ();int _rl_output_character_function ();static char *readline_internal ();static void readline_initialize_everything ();static int init_terminal_io ();static void start_using_history ();static void bind_arrow_keys ();#if !defined (__GO32__)static void readline_default_bindings ();#endif /* !__GO32__ */#if defined (__GO32__)#  include <sys/pc.h>#  undef HANDLE_SIGNALS#endif /* __GO32__ */#if defined (STATIC_MALLOC)static char *xmalloc (), *xrealloc ();#elseextern char *xmalloc (), *xrealloc ();#endif /* STATIC_MALLOC *//* **************************************************************** *//*								    *//*			Line editing input utility		    *//*								    *//* **************************************************************** */static char *LibraryVersion = "2.0";/* A pointer to the keymap that is currently in use.   By default, it is the standard emacs keymap. */Keymap _rl_keymap = emacs_standard_keymap;/* The current style of editing. */int rl_editing_mode = emacs_mode;/* Non-zero if the previous command was a kill command. */static int last_command_was_kill = 0;/* The current value of the numeric argument specified by the user. */int rl_numeric_arg = 1;/* Non-zero if an argument was typed. */int rl_explicit_arg = 0;/* Temporary value used while generating the argument. */int rl_arg_sign = 1;/* Non-zero means we have been called at least once before. */static int rl_initialized = 0;/* If non-zero, this program is running in an EMACS buffer. */static int running_in_emacs = 0;/* The current offset in the current input line. */int rl_point;/* Mark in the current input line. */int rl_mark;/* Length of the current input line. */int rl_end;/* Make this non-zero to return the current input_line. */int rl_done;/* The last function executed by readline. */Function *rl_last_func = (Function *)NULL;/* Top level environment for readline_internal (). */static jmp_buf readline_top_level;/* The streams we interact with. */static FILE *in_stream, *out_stream;/* The names of the streams that we do input and output to. */FILE *rl_instream = (FILE *)NULL;FILE *rl_outstream = (FILE *)NULL;/* Non-zero means echo characters as they are read. */int readline_echoing_p = 1;/* Current prompt. */char *rl_prompt;int rl_visible_prompt_length = 0;/* The number of characters read in order to type this complete command. */int rl_key_sequence_length = 0;/* If non-zero, then this is the address of a function to call just   before readline_internal () prints the first prompt. */Function *rl_startup_hook = (Function *)NULL;/* What we use internally.  You should always refer to RL_LINE_BUFFER. */static char *the_line;/* The character that can generate an EOF.  Really read from   the terminal driver... just defaulted here. */int _rl_eof_char = CTRL ('D');/* Non-zero makes this the next keystroke to read. */int rl_pending_input = 0;/* Pointer to a useful terminal name. */char *rl_terminal_name = (char *)NULL;/* Non-zero means to always use horizontal scrolling in line display. */int _rl_horizontal_scroll_mode = 0;/* Non-zero means to display an asterisk at the starts of history lines   which have been modified. */int _rl_mark_modified_lines = 0;  /* The style of `bell' notification preferred.  This can be set to NO_BELL,   AUDIBLE_BELL, or VISIBLE_BELL. */int _rl_bell_preference = AUDIBLE_BELL;     /* Line buffer and maintenence. */char *rl_line_buffer = (char *)NULL;int rl_line_buffer_len = 0;#define DEFAULT_BUFFER_SIZE 256/* Forward declarations used by the display and termcap code. */int term_xn;int screenwidth, screenheight, screenchars;/* **************************************************************** *//*								    *//*			`Forward' declarations  		    *//*								    *//* **************************************************************** *//* Non-zero means do not parse any lines other than comments and   parser directives. */unsigned char _rl_parsing_conditionalized_out = 0;/* Non-zero means to save keys that we dispatch on in a kbd macro. */static int defining_kbd_macro = 0;/* Non-zero means to convert characters with the meta bit set to   escape-prefixed characters so we can indirect through   emacs_meta_keymap or vi_escape_keymap. */int _rl_convert_meta_chars_to_ascii = 1;/* Non-zero means to output characters with the meta bit set directly   rather than as a meta-prefixed escape sequence. */int _rl_output_meta_chars = 0;/* Non-zero tells rl_delete_text and rl_insert_text to not add to   the undo list. */static int doing_an_undo = 0;/* **************************************************************** *//*								    *//*			Top Level Functions			    *//*								    *//* **************************************************************** *//* Non-zero means treat 0200 bit in terminal input as Meta bit. */int _rl_meta_flag = 0;	/* Forward declaration *//* Read a line of input.  Prompt with PROMPT.  A NULL PROMPT means   none.  A return value of NULL means that EOF was encountered. */char *readline (prompt)     char *prompt;{  char *value;  rl_prompt = prompt;  /* If we are at EOF return a NULL string. */  if (rl_pending_input == EOF)    {      rl_pending_input = 0;      return ((char *)NULL);    }  rl_visible_prompt_length = rl_expand_prompt (rl_prompt);  rl_initialize ();  rl_prep_terminal (_rl_meta_flag);#if defined (HANDLE_SIGNALS)  rl_set_signals ();#endif  value = readline_internal ();  rl_deprep_terminal ();#if defined (HANDLE_SIGNALS)  rl_clear_signals ();#endif  return (value);}/* Read a line of input from the global rl_instream, doing output on   the global rl_outstream.   If rl_prompt is non-null, then that is our prompt. */static char *readline_internal (){  int lastc, c, eof_found;  in_stream  = rl_instream;  out_stream = rl_outstream;  lastc = -1;  eof_found = 0;  if (rl_startup_hook)    (*rl_startup_hook) ();  if (!readline_echoing_p)    {      if (rl_prompt)	{	  fprintf (out_stream, "%s", rl_prompt);	  fflush (out_stream);	}    }  else    {      rl_on_new_line ();      rl_redisplay ();#if defined (VI_MODE)      if (rl_editing_mode == vi_mode)	rl_vi_insertion_mode ();#endif /* VI_MODE */    }  while (!rl_done)    {      int lk = last_command_was_kill;      int code;      code = setjmp (readline_top_level);      if (code)	rl_redisplay ();      if (!rl_pending_input)	{	  /* Then initialize the argument and number of keys read. */	  rl_init_argument ();	  rl_key_sequence_length = 0;	}      c = rl_read_key ();      /* EOF typed to a non-blank line is a <NL>. */      if (c == EOF && rl_end)	c = NEWLINE;      /* The character _rl_eof_char typed to blank line, and not as the	 previous character is interpreted as EOF. */      if (((c == _rl_eof_char && lastc != c) || c == EOF) && !rl_end)	{	  eof_found = 1;	  break;	}      lastc = c;      _rl_dispatch (c, _rl_keymap);      /* If there was no change in last_command_was_kill, then no kill	 has taken place.  Note that if input is pending we are reading	 a prefix command, so nothing has changed yet. */      if (!rl_pending_input)	{	  if (lk == last_command_was_kill)	    last_command_was_kill = 0;	}#if defined (VI_MODE)      /* In vi mode, when you exit insert mode, the cursor moves back	 over the previous character.  We explicitly check for that here. */      if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)	rl_vi_check ();#endif /* VI_MODE */      if (!rl_done)	rl_redisplay ();    }  /* Restore the original of this history line, iff the line that we     are editing was originally in the history, AND the line has changed. */  {    HIST_ENTRY *entry = current_history ();    if (entry && rl_undo_list)      {	char *temp = savestring (the_line);	rl_revert_line ();	entry = replace_history_entry (where_history (), the_line,				       (HIST_ENTRY *)NULL);	_rl_free_history_entry (entry);	strcpy (the_line, temp);	free (temp);      }  }  /* At any rate, it is highly likely that this line has an undo list.  Get     rid of it now. */  if (rl_undo_list)    free_undo_list ();  if (eof_found)    return (char *)NULL;  else    return (savestring (the_line));}/* **************************************************************** *//*								    *//*			Character Input Buffering       	    *//*								    *//* **************************************************************** */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 push_index;}/* 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. */voidrl_gather_tyi (){#if defined (__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 /* !__GO32__ */  int tty = fileno (in_stream);  register int tem, result = -1;  int chars_avail;  char input;#if defined (FIONREAD)  result = ioctl (tty, FIONREAD, &chars_avail);#endif#if defined (O_NDELAY)  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;    }#endif /* O_NDELAY */  /* 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

⌨️ 快捷键说明

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