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

📄 getline.c

📁 linux下ftp的库源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic char     rcsid[] ="$Id: getline.c,v 5.0 1995/12/10 10:34:21 orel Exp $";static char    *copyright = "Copyright (C) 1991, 1992, 1993, Chris Thewalt";#endif/* * Copyright (C) 1991, 1992, 1993 by Chris Thewalt (thewalt@ce.berkeley.edu) * * Permission to use, copy, modify, and distribute this software  * for any purpose and without fee is hereby granted, provided * that the above copyright notices appear in all copies and that both the * copyright notice and this permission notice appear in supporting * documentation.  This software is provided "as is" without express or * implied warranty. * * Thanks to the following people who have provided enhancements and fixes: *   Ron Ueberschaer, Christoph Keller, Scott Schwartz, Steven List, *   DaviD W. Sanderson, Goran Bostrom, Michael Gleason, Glenn Kasten, *   Edin Hodzic, Eric J Bivona, Kai Uwe Rommel */#ifdef _AIX#define POSIX#endif#include       "getline.h"static int      gl_tab();  /* forward reference needed for gl_tab_hook *//******************** imported interface *********************************/#include <string.h>#include <ctype.h>#include <errno.h>#include <signal.h>extern int      isatty();	extern void    *malloc();extern void     free();extern int      kill();	/********************* exported interface ********************************/char           *getline();		/* read a line of input */void            gl_setwidth();		/* specify width of screen */void            gl_histadd();		/* adds entries to hist */void		gl_strwidth();		/* to bind gl_strlen */int 		(*gl_in_hook)() = 0;int 		(*gl_out_hook)() = 0;int 		(*gl_tab_hook)() = gl_tab;/******************** internal interface *********************************/#define BUF_SIZE 1024static int      gl_init_done = -1;	/* terminal mode flag  */static int      gl_termw = 80;		/* actual terminal width */static int      gl_scroll = 27;		/* width of EOL scrolling region */static int      gl_width = 0;		/* net size available for input */static int      gl_extent = 0;		/* how far to redraw, 0 means all */static int      gl_overwrite = 0;	/* overwrite mode */static int      gl_pos, gl_cnt = 0;     /* position and size of input */static char     gl_buf[BUF_SIZE];       /* input buffer */static char     gl_killbuf[BUF_SIZE]=""; /* killed text */static char    *gl_prompt;		/* to save the prompt string */static char     gl_intrc = 0;		/* keyboard SIGINT char */static char     gl_quitc = 0;		/* keyboard SIGQUIT char */static char     gl_suspc = 0;		/* keyboard SIGTSTP char */static char     gl_dsuspc = 0;		/* delayed SIGTSTP char */static int      gl_search_mode = 0;	/* search mode flag */static void     gl_init();		/* prepare to edit a line */static void     gl_cleanup();		/* to undo gl_init */void     gl_char_init();		/* get ready for no echo input */void     gl_char_cleanup();	/* undo gl_char_init */static size_t 	(*gl_strlen)() = (size_t(*)())strlen; 					/* returns printable prompt width */static void     gl_addchar();		/* install specified char */static void     gl_del();		/* del, either left (-1) or cur (0) */static void     gl_error();		/* write error msg and die */static void     gl_fixup();		/* fixup state variables and screen */static int      gl_getc();		/* read one char from terminal */static void     gl_kill();		/* delete to EOL */static void     gl_newline();		/* handle \n or \r */static void     gl_putc();		/* write one char to terminal */static void     gl_puts();		/* write a line to terminal */static void     gl_redraw();		/* issue \n and redraw all */static void     gl_transpose();		/* transpose two chars */static void     gl_yank();		/* yank killed text */static void     gl_word();		/* move a word */static void     hist_init();	/* initializes hist pointers */static char    *hist_next();	/* return ptr to next item */static char    *hist_prev();	/* return ptr to prev item */static char    *hist_save();	/* makes copy of a string, without NL */static void     search_addchar();	/* increment search string */static void     search_term();		/* reset with current contents */static void     search_back();		/* look back for current string */static void     search_forw();		/* look forw for current string *//************************ nonportable part *********************************/extern int      write();extern void     exit();#ifdef _IBMR2#define unix#endif#ifdef MSDOS#include <bios.h>#endif#ifdef unixextern int      read();extern int      ioctl();#ifdef POSIX		/* use POSIX interface */#include <termios.h>struct termios  new_termios, old_termios;#else /* not POSIX */#include <sys/ioctl.h>#ifdef M_XENIX	/* does not really use bsd terminal interface */#undef TIOCSETN#endif /* M_XENIX */#ifdef TIOCSETN		/* use BSD interface */#include <sgtty.h>struct sgttyb   new_tty, old_tty;struct tchars   tch;struct ltchars  ltch;#else			/* use SYSV interface */#include <termio.h>struct termio   new_termio, old_termio;#endif /* TIOCSETN */#endif /* POSIX */#endif	/* unix */#ifdef vms#include <descrip.h>#include <ttdef.h>#include <iodef.h>#include unixio   static int   setbuff[2];             /* buffer to set terminal attributes */static short chan = -1;              /* channel to terminal */struct dsc$descriptor_s descrip;     /* VMS descriptor */#endifvoidgl_char_init()			/* turn off input echo */{#ifdef unix#ifdef POSIX    tcgetattr(0, &old_termios);    gl_intrc = old_termios.c_cc[VINTR];    gl_quitc = old_termios.c_cc[VQUIT];#ifdef VSUSP    gl_suspc = old_termios.c_cc[VSUSP];#endif#ifdef VDSUSP    gl_dsuspc = old_termios.c_cc[VDSUSP];#endif    new_termios = old_termios;    new_termios.c_iflag &= ~(BRKINT|ISTRIP|IXON|IXOFF);    new_termios.c_iflag |= (IGNBRK|IGNPAR);    new_termios.c_lflag &= ~(ICANON|ISIG|IEXTEN|ECHO);    new_termios.c_cc[VMIN] = 1;    new_termios.c_cc[VTIME] = 0;    tcsetattr(0, TCSANOW, &new_termios);#else				/* not POSIX */#ifdef TIOCSETN			/* BSD */    ioctl(0, TIOCGETC, &tch);    ioctl(0, TIOCGLTC, &ltch);    gl_intrc = tch.t_intrc;    gl_quitc = tch.t_quitc;    gl_suspc = ltch.t_suspc;    gl_dsuspc = ltch.t_dsuspc;    ioctl(0, TIOCGETP, &old_tty);    new_tty = old_tty;    new_tty.sg_flags |= RAW;    new_tty.sg_flags &= ~ECHO;    ioctl(0, TIOCSETN, &new_tty);#else				/* SYSV */    ioctl(0, TCGETA, &old_termio);    gl_intrc = old_termio.c_cc[VINTR];    gl_quitc = old_termio.c_cc[VQUIT];    new_termio = old_termio;    new_termio.c_iflag &= ~(BRKINT|ISTRIP|IXON|IXOFF);    new_termio.c_iflag |= (IGNBRK|IGNPAR);    new_termio.c_lflag &= ~(ICANON|ISIG|ECHO);    new_termio.c_cc[VMIN] = 1;    new_termio.c_cc[VTIME] = 0;    ioctl(0, TCSETA, &new_termio);#endif /* TIOCSETN */#endif /* POSIX */#endif /* unix */#ifdef vms    descrip.dsc$w_length  = strlen("tt:");    descrip.dsc$b_dtype   = DSC$K_DTYPE_T;    descrip.dsc$b_class   = DSC$K_CLASS_S;    descrip.dsc$a_pointer = "tt:";    (void)sys$assign(&descrip,&chan,0,0);    (void)sys$qiow(0,chan,IO$_SENSEMODE,0,0,0,setbuff,8,0,0,0,0);    setbuff[1] |= TT$M_NOECHO;    (void)sys$qiow(0,chan,IO$_SETMODE,0,0,0,setbuff,8,0,0,0,0);#endif /* vms */}voidgl_char_cleanup()		/* undo effects of gl_char_init */{#ifdef unix#ifdef POSIX     tcsetattr(0, TCSANOW, &old_termios);#else 			/* not POSIX */#ifdef TIOCSETN		/* BSD */    old_tty.sg_flags &= ~RAW;        ioctl(0, TIOCSETN, &old_tty);#else			/* SYSV */    ioctl(0, TCSETA, &old_termio);#endif /* TIOCSETN */#endif /* POSIX */#endif /* unix */#ifdef vms    setbuff[1] &= ~TT$M_NOECHO;    (void)sys$qiow(0,chan,IO$_SETMODE,0,0,0,setbuff,8,0,0,0,0);    sys$dassgn(chan);    chan = -1;#endif }#if MSDOS || __EMX__int pc_keymap(c)int c;{    switch (c) {    case 72: c = 16;   /* up -> ^P */        break;    case 80: c = 14;   /* down -> ^N */        break;    case 75: c = 2;    /* left -> ^B */        break;    case 77: c = 6;    /* right -> ^F */        break;    default: c = 0;    /* make it garbage */    }    return c;}#endif /* MSDOS || __EMCX__ */static intgl_getc()/* get a character without echoing it to screen */{    int             c;    char            ch;#ifdef unix    c = (read(0, &ch, 1) > 0)? ch : -1;#endif#ifdef MSDOS    c = _bios_keybrd(_NKEYBRD_READ);    if ((c & 0377) == 224) {	c = pc_keymap((c >> 8) & 0377);    } else {	c &= 0377;    }#endif#ifdef __TURBOC__    while(!bioskey(1))	;    c = bioskey(0) & 0xff;#endif#ifdef __EMX__#define getch() _read_kbd(0, 1, 0)    c = getch();    if (c == 224 || c == 0) {        c = pc_keymap(getch());    } else {        c &= 0377;    }#endif#ifdef vms    if(chan < 0) {       c='\0';    }    (void)sys$qiow(0,chan,IO$_TTYREADALL,0,0,0,&c,1,0,0,0,0);    c &= 0177;                        /* get a char */#endif    return c;}static voidgl_putc(c)int     c;{    char   ch = c;    write(1, &ch, 1);    if (ch == '\n') {	ch = '\r';        write(1, &ch, 1);	/* RAW mode needs '\r', does not hurt */    }}/******************** fairly portable part *********************************/static voidgl_puts(buf)char *buf;{    int len;         if (buf) {        len = strlen(buf);        write(1, buf, len);    }}static voidgl_error(buf)char *buf;{    int len = strlen(buf);    gl_cleanup();    write(2, buf, len);    exit(1);}static voidgl_init()/* set up variables and terminal */{    if (gl_init_done < 0) {		/* -1 only on startup */        hist_init();    }    if (isatty(0) == 0 || isatty(1) == 0)	gl_error("\n*** Error: getline(): not interactive, use stdio.\n");    gl_char_init();    gl_init_done = 1;}static voidgl_cleanup()/* undo effects of gl_init, as necessary */{    if (gl_init_done > 0)        gl_char_cleanup();    gl_init_done = 0;}voidgl_setwidth(w)int  w;{    if (w > 20) {	gl_termw = w;	gl_scroll = w / 3;    } else {	gl_error("\n*** Error: minimum screen width is 21\n");    }}char *getline(prompt)char *prompt;{    int             c, loc, tmp;    int	            sig;    gl_init();	    gl_prompt = (prompt)? prompt : "";    gl_buf[0] = 0;    if (gl_in_hook)	gl_in_hook(gl_buf);    gl_fixup(gl_prompt, -2, BUF_SIZE);    while ((c = gl_getc()) >= 0) {	gl_extent = 0;  	/* reset to full extent */	if (isprint(c)) {	    if (gl_search_mode)	       search_addchar(c);	    else	       gl_addchar(c);	} else {	    if (gl_search_mode) {	        if (c == '\033' || c == '\016' || c == '\020') {	            search_term();	            c = 0;     		/* ignore the character */		} else if (c == '\010' || c == '\177') {		    search_addchar(-1); /* unwind search string */		    c = 0;		} else if (c != '\022' && c != '\023') {		    search_term();	/* terminate and handle char */		}	    }	    switch (c) {	      case '\n': case '\r': 			/* newline */		gl_newline();		gl_cleanup();		return gl_buf;		/*NOTREACHED*/		break; 	      case '\001': gl_fixup(gl_prompt, -1, 0);		/* ^A */		break;	      case '\002': gl_fixup(gl_prompt, -1, gl_pos-1);	/* ^B */		break;	      case '\004':					/* ^D */		if (gl_cnt == 0) {		    gl_buf[0] = 0;		    gl_cleanup();		    gl_putc('\n');		    return gl_buf;		} else {		    gl_del(0);		}		break;	      case '\005': gl_fixup(gl_prompt, -1, gl_cnt);	/* ^E */		break;	      case '\006': gl_fixup(gl_prompt, -1, gl_pos+1);	/* ^F */		break;	      case '\010': case '\177': gl_del(-1);	/* ^H and DEL */		break;	      case '\t':        				/* TAB */                if (gl_tab_hook) {		    tmp = gl_pos;	            loc = gl_tab_hook(gl_buf, gl_strlen(gl_prompt), &tmp);	            if (loc >= 0 || tmp != gl_pos)	                gl_fixup(gl_prompt, loc, tmp);                }		break;	      case '\013': gl_kill(gl_pos);			/* ^K */		break;	      case '\014': gl_redraw();				/* ^L */		break;	      case '\016': 					/* ^N */		strcpy(gl_buf, hist_next());                if (gl_in_hook)	            gl_in_hook(gl_buf);		gl_fixup(gl_prompt, 0, BUF_SIZE);		break;	      case '\017': gl_overwrite = !gl_overwrite;       	/* ^O */		break;	      case '\020': 					/* ^P */		strcpy(gl_buf, hist_prev());                if (gl_in_hook)	            gl_in_hook(gl_buf);		gl_fixup(gl_prompt, 0, BUF_SIZE);		break;	      case '\022': search_back(1);			/* ^R */		break;	      case '\023': search_forw(1);			/* ^S */		break;	      case '\024': gl_transpose();			/* ^T */		break;              case '\025': gl_kill(0);				/* ^U */		break;	      case '\031': gl_yank();				/* ^Y */		break;	      case '\033':				/* ansi arrow keys */		c = gl_getc();		if (c == '[') {		    switch(c = gl_getc()) {		      case 'A':             			/* up */		        strcpy(gl_buf, hist_prev());                        if (gl_in_hook)	                    gl_in_hook(gl_buf);		        gl_fixup(gl_prompt, 0, BUF_SIZE);		        break;		      case 'B':                         	/* down */		        strcpy(gl_buf, hist_next());                        if (gl_in_hook)	                    gl_in_hook(gl_buf);		        gl_fixup(gl_prompt, 0, BUF_SIZE);		        break;		      case 'C': gl_fixup(gl_prompt, -1, gl_pos+1); /* right */		        break;		      case 'D': gl_fixup(gl_prompt, -1, gl_pos-1); /* left */		        break;		      default: gl_putc('\007');         /* who knows */		        break;		    }		} else if (c == 'f' || c == 'F') {		    gl_word(1);		} else if (c == 'b' || c == 'B') {		    gl_word(-1);		} else		    gl_putc('\007');		break;	      default:		/* check for a terminal signal */#ifdef unix	        if (c > 0) {	/* ignore 0 (reset above) */	            sig = 0;#ifdef SIGINT	            if (c == gl_intrc)	                sig = SIGINT;#endif#ifdef SIGQUIT	            if (c == gl_quitc)	                sig = SIGQUIT;#endif#ifdef SIGTSTP	            if (c == gl_suspc || c == gl_dsuspc)	                sig = SIGTSTP;#endif                    if (sig != 0) {	                gl_cleanup();	                kill(0, sig);	                gl_init();	                gl_redraw();			c = 0;		    } 		}#endif /* unix */                if (c > 0)		    gl_putc('\007');		break;	    }	}    }    gl_cleanup();    gl_buf[0] = 0;    return gl_buf;}static voidgl_addchar(c)int c;/* adds the character c to the input buffer at current location */{    int  i;    if (gl_cnt >= BUF_SIZE - 1)	gl_error("\n*** Error: getline(): input buffer overflow\n");    if (gl_overwrite == 0 || gl_pos == gl_cnt) {        for (i=gl_cnt; i >= gl_pos; i--)            gl_buf[i+1] = gl_buf[i];        gl_buf[gl_pos] = c;        gl_fixup(gl_prompt, gl_pos, gl_pos+1);    } else {	gl_buf[gl_pos] = c;	gl_extent = 1;        gl_fixup(gl_prompt, gl_pos, gl_pos+1);    }}static voidgl_yank()/* adds the kill buffer to the input buffer at current location */{    int  i, len;

⌨️ 快捷键说明

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