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

📄 readline.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/* readline.c -- a general facility for reading lines of input   with emacs style editing and completion.  *//* Copyright 1987, 1989, 1991, 1992 Free Software Foundation, Inc.   This file contains the Readline Library (the Library), a set of   routines for providing Emacs style line input to programs that ask   for it.   The 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 of the License, or   (at your option) any later version.   The 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.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  *//* Remove these declarations when we have a complete libgnu.a. *//* #define STATIC_MALLOC */#if !defined (STATIC_MALLOC)extern char *xmalloc (), *xrealloc ();#elsestatic char *xmalloc (), *xrealloc ();#endif /* STATIC_MALLOC */#include "sysdep.h"#include <sys/types.h>#include <stdio.h>#include <fcntl.h>#ifndef	NO_SYS_FILE#include <sys/file.h>#endif#include <signal.h>#if defined (HAVE_UNISTD_H)#  include <unistd.h>#endif#define NEW_TTY_DRIVER#define HAVE_BSD_SIGNALS/* #define USE_XON_XOFF */#ifdef __MSDOS__#undef NEW_TTY_DRIVER#undef HAVE_BSD_SIGNALS#endif/* Some USG machines have BSD signal handling (sigblock, sigsetmask, etc.) */#if defined (USG) && !defined (hpux)#undef HAVE_BSD_SIGNALS#endif/* System V machines use termio. */#if !defined (_POSIX_VERSION)#  if defined (USG) || defined (hpux) || defined (Xenix) || defined (sgi) || defined (DGUX)#    undef NEW_TTY_DRIVER#    define TERMIO_TTY_DRIVER#    include <termio.h>#    if !defined (TCOON)#      define TCOON 1#    endif#  endif /* USG || hpux || Xenix || sgi || DUGX */#endif /* !_POSIX_VERSION *//* Posix systems use termios and the Posix signal functions. */#if defined (_POSIX_VERSION)#  if !defined (TERMIOS_MISSING)#    undef NEW_TTY_DRIVER#    define TERMIOS_TTY_DRIVER#    include <termios.h>#  endif /* !TERMIOS_MISSING */#  define HAVE_POSIX_SIGNALS#  if !defined (O_NDELAY)#    define O_NDELAY O_NONBLOCK	/* Posix-style non-blocking i/o */#  endif /* O_NDELAY */#endif /* _POSIX_VERSION *//* Other (BSD) machines use sgtty. */#if defined (NEW_TTY_DRIVER)#include <sgtty.h>#endif/* Define _POSIX_VDISABLE if we are not using the `new' tty driver and   it is not already defined.  It is used both to determine if a   special character is disabled and to disable certain special   characters.  Posix systems should set to 0, USG systems to -1. */#if !defined (NEW_TTY_DRIVER) && !defined (_POSIX_VDISABLE)#  if defined (_POSIX_VERSION)#    define _POSIX_VDISABLE 0#  else /* !_POSIX_VERSION */#    define _POSIX_VDISABLE -1#  endif /* !_POSIX_VERSION */#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE *//* Define some macros for dealing with assorted signalling disciplines.   These macros provide a way to use signal blocking and disabling   without smothering your code in a pile of #ifdef's.   SIGNALS_UNBLOCK;			Stop blocking all signals.   {     SIGNALS_DECLARE_SAVED (name);	Declare a variable to save the 					signal blocking state.	...     SIGNALS_BLOCK (SIGSTOP, name);	Block a signal, and save the previous					state for restoration later.	...     SIGNALS_RESTORE (name);		Restore previous signals.   }*/#ifdef HAVE_POSIX_SIGNALS							/* POSIX signals */#define	SIGNALS_UNBLOCK \      do { sigset_t set;	\	sigemptyset (&set);	\	sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);	\      } while (0)#define	SIGNALS_DECLARE_SAVED(name)	sigset_t name#define	SIGNALS_BLOCK(SIG, saved)	\	do { sigset_t set;		\	  sigemptyset (&set);		\	  sigaddset (&set, SIG);	\	  sigprocmask (SIG_BLOCK, &set, &saved);	\	} while (0)#define	SIGNALS_RESTORE(saved)		\  sigprocmask (SIG_SETMASK, &saved, (sigset_t *)NULL)#else	/* HAVE_POSIX_SIGNALS */#ifdef HAVE_BSD_SIGNALS							/* BSD signals */#define	SIGNALS_UNBLOCK			sigsetmask (0)#define	SIGNALS_DECLARE_SAVED(name)	int name#define	SIGNALS_BLOCK(SIG, saved)	saved = sigblock (sigmask (SIG))#define	SIGNALS_RESTORE(saved)		sigsetmask (saved)#else  /* HAVE_BSD_SIGNALS */							/* None of the Above */#define	SIGNALS_UNBLOCK			/* nothing */#define	SIGNALS_DECLARE_SAVED(name)	/* nothing */#define	SIGNALS_BLOCK(SIG, saved)	/* nothing */#define	SIGNALS_RESTORE(saved)		/* nothing */#endif /* HAVE_BSD_SIGNALS */#endif /* HAVE_POSIX_SIGNALS *//*  End of signal handling definitions.  */#include <errno.h>extern int errno;#include <setjmp.h>#include <sys/stat.h>/* Posix macro to check file in statbuf for directory-ness. */#if defined (S_IFDIR) && !defined (S_ISDIR)#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)#endif#ifndef __MSDOS__/* These next are for filename completion.  Perhaps this belongs   in a different place. */#include <pwd.h>#endif /* __MSDOS__ */#if defined (USG) && !defined (isc386) && !defined (sgi)struct passwd *getpwuid (), *getpwent ();#endif/* #define HACK_TERMCAP_MOTION *//* Some standard library routines. */#include "readline.h"#include "history.h"#ifndef digit#define digit(c)  ((c) >= '0' && (c) <= '9')#endif#ifndef isletter#define isletter(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))#endif#ifndef digit_value#define digit_value(c) ((c) - '0')#endif#ifndef member#define member(c, s) ((c) ? index ((s), (c)) : 0)#endif#ifndef isident#define isident(c) ((isletter(c) || digit(c) || c == '_'))#endif#ifndef exchange#define exchange(x, y) {int temp = x; x = y; y = temp;}#endif#if !defined (rindex)extern char *rindex ();#endif /* rindex */#if !defined (index)extern char *index ();#endif /* index */extern char *getenv ();extern char *tilde_expand ();static update_line ();static void output_character_function ();static delete_chars ();static void insert_some_chars ();#if defined (VOID_SIGHANDLER)#  define sighandler void#else#  define sighandler int#endif /* VOID_SIGHANDLER *//* This typedef is equivalant to the one for Function; it allows us   to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */typedef sighandler SigHandler ();/* If on, then readline handles signals in a way that doesn't screw. */#define HANDLE_SIGNALS#ifdef __GO32__#include <sys/pc.h>#undef HANDLE_SIGNALS#endif/* **************************************************************** *//*								    *//*			Line editing input utility		    *//*								    *//* **************************************************************** *//* A pointer to the keymap that is currently in use.   By default, it is the standard emacs keymap. */Keymap keymap = emacs_standard_keymap;#define no_mode -1#define vi_mode 0#define emacs_mode 1/* 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 char *running_in_emacs = (char *)NULL;/* 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, *rl_outstream;/* Non-zero means echo characters as they are read. */int readline_echoing_p = 1;/* Current prompt. */char *rl_prompt;/* 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;/* If non-zero, then this is the address of a function to call when   completing on a directory name.  The function is called with   the address of a string (the current directory name) as an arg. */Function *rl_symbolic_link_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. */static int 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;/* Line buffer and maintenence. */char *rl_line_buffer = (char *)NULL;int rl_line_buffer_len = 0;#define DEFAULT_BUFFER_SIZE 256/* **************************************************************** *//*								    *//*			`Forward' declarations  		    *//*								    *//* **************************************************************** *//* Non-zero means do not parse any lines other than comments and   parser directives. */static unsigned char parsing_conditionalized_out = 0;/* Caseless strcmp (). */static int stricmp (), strnicmp ();static char *strpbrk ();/* Non-zero means to save keys that we dispatch on in a kbd macro. */static int defining_kbd_macro = 0;/* **************************************************************** *//*								    *//*			Top Level Functions			    *//*								    *//* **************************************************************** */static void rl_prep_terminal (), rl_deprep_terminal ();static void clear_to_eol (), rl_generic_bind ();/* 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 *readline_internal ();  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_initialize ();  rl_prep_terminal ();#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. */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 = 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 eof_char typed to blank line, and not as the	 previous character is interpreted as EOF. */      if (((c == eof_char && lastc != c) || c == EOF) && !rl_end)	{	  eof_found = 1;	  break;	}      lastc = c;      rl_dispatch (c, 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 && 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);	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));}/* **************************************************************** *//*					        		    *//*			   Signal Handling                          *//*								    *//* **************************************************************** */#if defined (SIGWINCH)static SigHandler *old_sigwinch = (SigHandler *)NULL;

⌨️ 快捷键说明

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