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

📄 pg.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef lintstatic	char	*sccsid = "@(#)pg.c	4.2	(ULTRIX)	11/14/90";#endif lint/************************************************************************ *									* *       Copyright (c) Digital Equipment Corporation, 1988, 1990	* *									* *   All Rights Reserved.  Unpublished rights  reserved  under  the	* *   copyright laws of the United States.				* *									* *   The software contained on this media  is  proprietary  to  and	* *   embodies  the  confidential  technology  of  Digital Equipment	* *   Corporation.  Possession, use, duplication or dissemination of	* *   the  software and media is authorized only pursuant to a valid	* *   written license from Digital Equipment Corporation.		* *									* *   RESTRICTED RIGHTS LEGEND   Use, duplication, or disclosure  by	* *   the U.S. Government is subject to restrictions as set forth in	* *   Subparagraph (c)(1)(ii)  of  DFARS  252.227-7013,  or  in  FAR	* *   52.227-19, as applicable.						* *									* *   This software is derived  from  software  received  from  Bell	* *   Laboratories.   Use,  duplication, or disclosure is subject to	* *   restrictions under license agreements with AT&T.			* *									* ************************************************************************//**//*************************************************************************     Systems V static char sccsid[] = "@(#)pg.c	1.5";           *************************************************************************//**************************************************************************		Modification History**    13-Jun-88	Tim Burke*		#include <sys/termio.h>**    09-Jun-88	Mark Parenti*		Changed signal handlers to void.**    22-Apr-88  David Gray *               Modified so the user responses are echoed.**    20-Nov-88	Jon Reeves for Dave Long*		Fixed missing arg on call to set_state().**    15-Oct-90  GWS*		changed #include <curses.h> to #include <cursesX.h> because*		  this uses X/Open (System V-based) "curses".*************************************************************************/#include <signal.h>#include <setjmp.h>#include <sys/types.h>#include <sys/dir.h>#include <sys/stat.h>#include <ctype.h>#include <stdio.h>#include <cursesX.h>#include <term.h>#include <sys/termio.h>/* *      pg -- paginator for crt terminals * *	Includes the ability to display pages that have *	already passed by. Also gives the user the ability *	to search forward and backwards for regular expressions. *	This works for piped input by copying to a temporary file, *	and resolving backreferences from there. * *	Note:	The reason that there are so many commands to do *		the same types of things is to try to accommodate *		users of other paginators. */#define LINSIZ	1024#define QUIT	'\034'#define BOF	(EOF - 1)	/* Begining of File */#define STOP    (EOF - 2)#define PROMPTSIZE	256struct line {			/* how line addresses are stored */	long	l_addr;		/* file offset */	int	l_no;		/* line number in file */};typedef	struct line	LINE;LINE		*zero = NULL,		/* first line */		*dot,		/* current line */		*dol,		/* last line */		*contig;	/* where contiguous (non-aged) lines start */short           nlall;          /* room for how many LINEs in memory */FILE		*in_file,	/* current input stream */		*tmp_fin,	/* pipe temporary file in */		*tmp_fou;	/* pipe temporary file out */char		*tmp_name = "/tmp/pgXXXXXX";long		ftell();char		*malloc(),		*realloc();short		sign;		/* sign of command input */int             fnum,           /* which file argument we're in */		pipe_in,	/* set when stdin is a pipe */		out_is_tty;	/* set if stdout is a tty */void		on_brk(),		end_it();short		brk_hit;	/* interrupt handling is pending flag */int             window = 0;	/* window size in lines */short		eof_pause = 1;	/* pause w/ prompt at end of files */short		soflag = 0;	/* output all messages in standout mode */short           promptlen;      /* length of the current prompt */short           firstf = 1;	/* set before first file has been processed */short           inwait,		/* set while waiting for user input */		errors;         /* set if error message has been printed.				 * if so, need to erase it and prompt */char		**fnames;short		fflag = 0;	/* set if the f option is used */short		nflag = 0;	/* set for "no newline" input option */short		clropt = 0;	/* set if the clear option is used */int		initopt = 0;	/* set if the line option is used */int		srchopt = 0;	/* set if the search option is used */int		initline;char		initbuf[BUFSIZ];char            leave_search = 't';     /* where on the page to leave a found string */short           nfiles;char		*shell;char		*promptstr = ":";char		*setprompt();short		lenprompt;		/* length of prompt string */int		nchars;			/* return from getline in find() */jmp_buf		restore;char		Line[LINSIZ+2];struct screen_stat {	int	first_line;	int	last_line;	short	is_eof;	};struct screen_stat old_ss = { 0, 0, 0 };struct screen_stat new_ss;short		eoflag;		/* set whenever at end of current file */short		doliseof;	/* set when last line of file is known */int		eofl_no;	/* what the last line of the file is */#define USAGE() { fprintf(stderr,"Usage: pg [-number] [-p string] [-cefs] [+line] [+/pattern/] files\n"); exit(1); }main(argc, argv)int argc;char *argv[];{	register char	*s;	register char	*p;	register char	ch;	int		prnames = 0; 	char		*getenv();	FILE		*checkf();	nfiles = argc;	fnames = argv;	while (--nfiles > 0) {		if ((ch = (*++fnames)[0]) == '-') {			if (fnames[0][1] == '\0' )				break;			for (s = fnames[0]+1; *s != '\0'; s++)				if (isdigit(*s)) {					window = 0;					do {						window = window*10+*s-'0';					} while (isdigit(*++s));					if (*s != '\0')						USAGE();					break;				}				else if (*s == 'c')					clropt = 1;				else if (*s == 'e')					eof_pause = 0;				else if (*s == 'f')					fflag = 1;				else if (*s == 'n')					nflag = 1;				else if (*s == 's')					soflag = 1;	/* standout mode */				else if (*s == 'p') {					if (*++s != '\0')						promptstr = setprompt(s);					else if (nfiles > 1) {						promptstr = setprompt(*++fnames);						nfiles--;					}					else						USAGE();					break;				}				else					USAGE();		}		else if (ch == '+') {			s = *fnames;			if (*++s == '/') {				srchopt++;				initopt = 0;				for (++s, p=initbuf; *s!='\0' && *s!='/';)					if (p < initbuf + sizeof(initbuf))						*p++ = *s++;					else {						fprintf(stderr,"pg: pattern too long\n");						exit(1);					}				*p = '\0';			}			else {				initopt++;				srchopt = 0;				for (; isdigit(*s); s++)					initline = initline*10 + *s -'0';				if (*s != '\0')					USAGE();			}		}		else			break;	}	signal(SIGQUIT,end_it);	signal(SIGINT,end_it);	out_is_tty = isatty(1);	if (out_is_tty) {		terminit();		signal(SIGQUIT,on_brk);		signal(SIGINT,on_brk);	}	if (window == 0)		window = lines - 1;	lenprompt = strlen(promptstr);	if (window <= 1)		window = 2;	if (initline <= 0)		initline = 1;	if (nfiles > 1)		prnames++;	if (nfiles == 0) {		fnames[0] = "-";		nfiles++;	}	while (fnum < nfiles) {		if (strcmp(fnames[fnum],"") == 0)			fnames[fnum] = "-";		if ((in_file = checkf(fnames[fnum])) == NULL)			fnum++;		else {			if (out_is_tty)				fnum += screen(fnames[fnum]);			else {				if (prnames) {					pr("::::::::::::::\n");					pr(fnames[fnum]);					pr("\n::::::::::::::\n");				}				copy_file(in_file,stdout);				fnum++;			}			fflush(stdout);			if (pipe_in)				save_pipe();			else			if (in_file != tmp_fin)				fclose(in_file);		}	}	end_it();}char *setprompt(s)register char *s;{	register int i = 0;	register int pct_d = 0;	static char pstr[PROMPTSIZE];	while (i < PROMPTSIZE - 2)		switch(pstr[i++] = *s++) {		case '\0':			return(pstr);		case '%':			if (*s == 'd' && !pct_d) {				pct_d++;			}			else if (*s != '%')				pstr[i++] = '%';			if ((pstr[i++] = *s++) == '\0')				return(pstr);			break;		default:			break;		}	fprintf(stderr,"pg: prompt too long\n");	exit(1);}/* * Print out the contents of the file f, one screenful at a time. */screen(file_name)char *file_name;{	int cmd_ret = 0;	int start;	short hadchance = 0;	old_ss.is_eof = 0;	old_ss.first_line = 0;	old_ss.last_line = 0;	new_ss = old_ss;	if (!firstf)		cmd_ret = command(file_name);	else {		firstf = 0;		if (initopt) {			initopt = 0;			new_ss.first_line = initline;			new_ss.last_line = initline + window - 1;		}		else		if (srchopt) {			srchopt = 0;			if (!search(initbuf,1))				cmd_ret = command(file_name);		}		else {			new_ss.first_line = 1;			new_ss.last_line = window;		}	}	for (;;) {		if (cmd_ret)			return(cmd_ret);		if (hadchance && new_ss.first_line >= eofl_no - 1)			return(1);		hadchance = 0;		if (new_ss.last_line < window)			new_ss.last_line = window;		if (find(0,new_ss.last_line + 1) != EOF)			new_ss.is_eof = 0;		else {			new_ss.is_eof = 1;			new_ss.last_line = eofl_no - 1;			new_ss.first_line = new_ss.last_line - window + 1;		}		if (new_ss.first_line < 1)			new_ss.first_line = 1;		if (clropt) {			doclear();			start = new_ss.first_line;		}		else {			if (new_ss.first_line == old_ss.last_line)				start = new_ss.first_line + 1;			else			if (new_ss.first_line > old_ss.last_line)				start = new_ss.first_line;			else			if (old_ss.first_line < new_ss.first_line)				start = old_ss.last_line + 1;			else				start = new_ss.first_line;			if (start < old_ss.first_line)				sopr("...skipping backward\n",0);			else			if (start > old_ss.last_line + 1)				sopr("...skipping forward\n",0);		}		for(; start <= new_ss.last_line; start++) {			find(0,start);			pr(Line);			if (brk_hit) {				new_ss.last_line = find(1,0);				new_ss.is_eof = 0;				break;			}		}		brk_hit = 0;		fflush(stdout);		if (new_ss.is_eof) {			if (!eof_pause || eofl_no == 1)				return(1);			hadchance++;			error("(EOF)");		}		old_ss = new_ss;		cmd_ret = command((char *)NULL);	}}char	cmdbuf[LINSIZ], *cmdptr;#define BEEP()		if (bell) { putp(bell); fflush(stdout); }#define	BLANKS(p)	while (*p == ' ' || *p == '\t') p++#define CHECKEND()	BLANKS(cmdptr); if (*cmdptr) { BEEP(); break; }/* * Read a command and do it. A command consists of an optional integer * argument followed by the command character.  Return the number of files * to skip, 0 if we're still talking about the same file. */command (filename)char *filename;{	register int nlines;	register int retval;	register char c;	FILE *sf;	char *cmdend;	short checkit = 0;	int id;	int skip;	for (;;) {		/* Wait for output to drain before going on.     */		/* This is done so that the user will not hit    */		/* break and quit before he has seen the prompt. */		ioctl(1,TCSBRK,1);		if (setjmp(restore) != 0)			end_it();		inwait = 1;		brk_hit = 0;		if (errors)			errors = 0;		else {			kill_line();			prompt(filename);		}		fflush(stdout);		if (ttyin())			continue;		cmdptr = cmdbuf;		nlines = number();		BLANKS(cmdptr);		switch (*cmdptr++) {		case 'h':			CHECKEND();			help();			break;		case '\014': /* ^L */		case '.':       /* redisplay current window */			CHECKEND();			new_ss.first_line = old_ss.first_line;			new_ss.last_line = new_ss.first_line + window - 1;			inwait = 0;			return(0);		case 'w':       /* set window size */		case 'z':			if (sign == -1) {				BEEP();				break;			}			CHECKEND();			if (nlines == 0)				nlines = window;			else 			if (nlines > 1)				window = nlines;			else {				BEEP();				break;			}			new_ss.first_line = old_ss.last_line;			new_ss.last_line = new_ss.first_line + window - 1;			inwait = 0;			return(0);		case '\004': /* ^D */		case 'd':			CHECKEND();			if (sign == 0)				sign = 1;			new_ss.last_line = old_ss.last_line + sign*window/2;			new_ss.first_line = new_ss.last_line - window + 1;			inwait = 0;			return(0);		case 's':			/*			* save input in filename.			* Check for filename, access, etc.			*/			BLANKS(cmdptr);			if (!*cmdptr) {				BEEP();				break;			}			if (setjmp(restore) != 0) {				BEEP();			}			else {				if ((sf=fopen(cmdptr,"w")) == NULL) {					error("cannot open save file");

⌨️ 快捷键说明

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