V8/usr/src/cmd/qed/main.c

Compare this file to the similar file:
Show the results in this format:

/*% cc -c -O %
 */
#include "vars.h"
#define	UP	1
#define DOWN	0
char lchars[]="pPlL";
struct buffer *curbuf = buffer;
char	*linp = line;
int	appflag = 0;
int	pagesize = PAGESIZE;
int	prflag = 0;	/* prflag==1 ==> much code to get it right. use the startup buffer */
int	lastttyc = '\n';
int	gflag = 0;
int	tflag = 0;
int	vflag = 0;	/* initialization code turns it on */
int	uflag = 's';
int	dflag = 0;
int	initflag = 1;
int	*option[] = {
	&cflag,	&dflag,	&eflag,	&iflag,	&prflag,&tflag,	&vflag,
};
char	opcs[] = "cdeipTv";
int	tfile = -1;
struct	sgttyb ttybuf = { 0, 0, '\b', '\b', /*0*/};
char	QEDFILE[]="QEDFILE";
int	(*pending)();

rescue()
{
	/* Save in qed.hup:[ab]q on hangup */
	signal(SIGHUP,1);
	if (lock) {
		pending = rescue;
		return;
	}
	startstring();
	copystring("qed.hup");
	setstring(FILEBUF);
	savall();
	exit(SIGHUP);
}
char *filea()
{
	register struct string *sp;
	register int i, d;
	char c;

	sp = &string[FILEBUF];
	startstring();
	d = 0;
	i = 0;
	while((c=sp->str[i]) != '\0'){
		addstring(c);
		i++;
		if(c == '/')
			d = i;
	}
	if((i-d) > 12)		/* file name is >= 13 characters long */
		string[NSTRING].str -= (i-(d+12));	/* truncate string */
	copystring(":aq");
	setstring(FILEBUF);
	return(sp->str);
}

char *fileb()
{
	register struct string *sp;

	sp = &string[FILEBUF];
	sp->str[sp->len-2] = 'b';
	return(sp->str);
}
savall()
{
	register fi;

	syncbuf();
	addr1 = buffer[0].zero + 1;
	addr2 = buffer[NBUFS-1].dol;
	if(addr1 > addr2){
		error('$');
		return;
	}
	if((io = creat(filea(), 0644)) < 0)
		error('o'|FILERR);
	putfile();
	exfile();
	if((fi = creat(fileb(), 0644)) < 0)
		error('o'|FILERR);
	write(fi, (char *)buffer, sizeof buffer);
	write(fi, strarea, sizeof strarea);
	lock++;
	shiftstring(DOWN);
	write(fi, (char *)string, sizeof string);
	shiftstring(UP);
	unlock();
	close(fi);
}
restor()
{
	register i, t;
	register struct buffer *b;
	int fi;
	int getfile();
	curbuf = buffer;
	i = (int)curbuf->zero;
	if((t = open(filea(), 0)) < 0){
		lastc = '\n';
		error('o'|FILERR);
	}
	initio();
	init();
	io = t;
	ninbuf = 0;
	append(getfile, dol);
	exfile();
	if((fi = open(fileb(),0)) < 0)
		error('o'|FILERR);
	lock++;
	if(read(fi,(char *)buffer,sizeof buffer) != sizeof buffer
		|| read(fi, strarea, sizeof strarea) != sizeof strarea
		|| read(fi, (char *)string, sizeof string) != sizeof string)
		error('R');
	close(fi);
	shiftstring(UP);
	/*
	 * This code is incredibly sleazy and machine dependent for the 11.
	 * Sorry. There is no good reason why we don't have a shiftbuf():
	 * feel free to write one (but lock before you call it!).
	 */
	t = (int)buffer[0].zero;
	if(i != t){
		i -= t;
		i >>= 1;
		for(b = buffer;b <= &buffer[NBUFS-1];b++){
			b->zero += i;
			b->dot += i;
			b->dol += i;
		}
	}
	newbuf(0);
	error(0);	/* ==> error, but don't print anything. calls unlock() */
}

/*
 *	On INTR, generate error '?'
 */

interrupt()
{
	signal(SIGINT, interrupt);
	if (lock) {
		pending = interrupt;
		return;
	}
	if(iflag){
		unlink(tfname);
		exit(SIGINT);
	}
	linp=line;
	putchar('\n');
	lastc = '\n';
	error('?');
}

/*
 * Unlock: exit a critical section, invoking any pending signal routines.
 */

unlock()
{
	register (*p)();

	p = pending;
	pending = 0;
	lock = 0;
	if (p)
		(*p)();
}

char cleanup[] = "ba z~:\n";
char setvflag[] = "ov?";
char boot1[] = "G/^[";
char boot2[] = "].+\t./r\n";

main(argc, argv)
char **argv;
{
	register char *p1;
	register i;
	char buf;
	int rvflag;
	char *startup=(char *)0;

	argv++;
	onquit = signal(SIGQUIT, 1);
	onhup = signal(SIGHUP, 1);
	onintr = signal(SIGINT, 1);
	rvflag = 1;
	for(i=0;i!=NSTRING;i++){
		string[i].str = nullstr;
		string[i].len=0;
	}
	/* initialize strfree */
	string[NSTRING].str = strchars;
	while(argc > 1 && **argv=='-'){
		switch(argv[0][1]){
		casedefault:
		default:
			rvflag = 0;
			break;
		case 'q':
		/* allow debugging quits? */
			signal(SIGQUIT, 0);
			break;
		case 'i':
		/* allow interrupt quits? */
			iflag++;
			break;
		case 'e':
		/* Exit on error? */
			eflag++;
			break;
		case 'x':
			if(argc == 2)
				goto casedefault;
			startup = argv[1];
			argv++;
			--argc;
		}
		argv++;
		--argc;
	}
	gtty(0,&ttybuf);
	if(startup==0)
		startup = getenv(QEDFILE);
	fendcore = (int *)sbrk(0);
	curbuf = &buffer[0];
	init();
	if (onhup != 1)
		signal(SIGHUP, rescue);
	if (onintr != 1)
		signal(SIGINT, interrupt);
	/*
	 * Build the initialization code in register z~
	 */
	if(startup){
		startstring();
		copystring(startup);
		setstring(FILE(NBUFS-1));
		p1 = "b~ r\n\\b~\n";
	} else
		p1 = "";
	startstring();
	copystring(p1);
	setvflag[2] = "rs"[rvflag];
	copystring(setvflag);
	/*
	 * z~ now has startup-buffer initialization; prepare the file list
	 * and generate a GLOBUF to read them in
	 */
	if(--argc > 0) {
		if(argc >= 53)	/* buffer names a-zA-Z */
			puts("?i");
		else {
			copystring(boot1);
			for(i=0; i<argc; i++)	/* argument files only */
				addstring(bname[i]);
			copystring(boot2);
			copystring(cleanup);
			setstring(NBUFS-1);
			buf = 0;
			while(argc > 0) {
				startstring();
				copystring(*argv);
				setstring(FILE(buf++));
				--argc;
				argv++;
			}
		}
	}
	else{
		copystring(cleanup);
		setstring(NBUFS-1);
	}
	pushinp(STRING, NBUFS-1, FALSE);
	setexit();
	lastttyc = '\n';
	commands();
	unlink(tfname);
	exit(lasterr);
}

int	noaddr;
commands()
{
	register int *a;
	register c, lastsep;
	int getfile(), gettty();
	int r;
	int changed;
	long locn, lseek();
	int startline;

	for (;;) {
	startline = (lastttyc == '\n' && peekc == 0);
	cprflag=prflag;
	c = '\n';
	for (addr1=0;;) {
		lastsep = c;
		a=address();
		c=getchar();
		if (c!=',' && c!=';')
			break;
		if (lastsep==',')
			error('a');
		if (a==0) {
			a = zero+1;
			if (a>dol)
				--a;
		}
		addr1 = a;
		if (c==';')
			dot = a;
	}
	if (lastsep!='\n' && a==0)
		a=dol;
	if((addr2=a) == 0) {
		addr2=dot;
		noaddr = TRUE;
	} else
		noaddr = FALSE;

	if(addr1 == 0)
		addr1 = addr2;

	cprflag=FALSE;
	switch(c){
	case 'a':
		setdot();
		setapp();
		append(gettty, addr2);
		continue;
	case 'b':
		if(posn((c=nextchar()), bname)<0){	/* browse command */
			setdot();
			nonzero();
			bcom();
			continue;
		}
		c = getaz('b');
		setnoaddr();
		chngbuf(c);
		continue;
	case 'c':
		setdot();
		nonzero();
		setapp();
		append(gettty, addr2);
		a = dot-(addr2-addr1+1);
		delete();
		dot = a;
		continue;
	case 'd':
		if(posn(nextchar(),"\377\npPlL \t") < 0)
			error('x');
		delete();
		continue;
	case 'E':
	case 'e':
		setnoaddr();
		if(c=='e' && !eok && cflag){
			eok=TRUE;
			error('e');
		}
		newfile(TRUE, SAVEALWAYS, "");
		delall();
		addr1 = zero;
		addr2 = zero;
		modified();	/* In case file open causes error */
		goto caseread;
	case 'f':
		setnoaddr();
		if((c = getchar()) != '\n'){
			ungetchar(c);
			if(newfile(FALSE, SAVEALWAYS, string[savedfile].str))
				modified();
			if(vflag)
				ncom('f');
		}
		else
			ncom('f');
		continue;
	case 'g':
		global(TRUE);
		continue;
	case 'G':
		globuf(TRUE);
		continue;
	case 'h':
		setnoaddr();
		if(nextchar()=='\n')
			error('x');
		if('0'<=peekc && peekc<='9')
			until(TRUE, getnum());
		else
			until(FALSE, 0);
		continue;
	case 'i':
		setdot();
		nonzero();
		setapp();
		append(gettty, addr2-1);
		continue;
	case 'j':
		setdot();
		if (addr1 == addr2 && lastsep == '\n'){
			addr1--;
			if(addr1 <= zero)
				error('$');
		}
		nonzero();
		join();
		continue;
	case 'k':
		c = getaz(c);
		setdot();
		nonzero();
		names[c] = *addr2 | 01;
		continue;
	case 'm':
		move(FALSE);
		continue;
	case 'n':
	case 'N':
		ncom(c);
		continue;
	case 'o':
		setnoaddr();
		c = getchar();
		r=posn(c, opcs);
		if(r >= 0)
			setreset(option[r]);
		else switch(c) {
		case 'B':
			if(nextchar() == '\n')
				clearstring(BROWSE);
			else {
				startstring();
				while((c=getchar()) != '\n')
					addstring(c);
				copystring("\\N");
				setstring(BROWSE);
			}
			break;
		case '?':
			if ((r = posn(getchar(), opcs)) < 0)
				error('O');
			settruth(*option[r]);
			break;
		case 'q':
			c = getchar();
			if(c=='s' || c =='r')
				signal(SIGQUIT, c=='r');
			else
				error('x');
			break;
		case 'u':
			c = getchar();
			if(c == 'r')
				uflag = 0;
			else if(posn(c, "slu") >= 0)
				uflag = c;
			else
				error('x');
			break;
		case 'b':
			if((r=getnum()) > 0)
				pagesize = r;
			if(posn(nextchar(), lchars) >=0)
				bformat = getchar();
			break;
		default:
			error('x');
		}
		continue;
	case '\n':
		if (a==0) {
			if(stackp != &stack[0] || !startline)
				continue;
			if(*string[BROWSE].str){
				pushinp(BRWS, 0, FALSE);
				continue;
			}
			a = dot+1;
			addr2 = a;
			addr1 = a;
		}
		if (lastsep==';')
			addr1 = a;
		c = 'p';	/* fall through */
	case 'L':
	case 'l':
	case 'p':
	case 'P':
		display(c);
		continue;
	case EOF:
		return;
	case 'Q':
	case 'q':
		setnoaddr();
		if(c!=EOF && (!startline || getchar()!='\n'))
			error('x');
		if(c!='Q' && !qok){
			register struct buffer *bp;
			syncbuf();
			qok=TRUE;
			for(bp=buffer; bp<&buffer[NBUFS]; bp++)
				if(bp->cflag && (bp->dol>bp->zero ||
					string[FILE(bp-buffer)].str[0]))
					error('q');
		}
		unlink(tfname);
		exit(lasterr);
	case 'r':
		newfile(TRUE, SAVEIFFIRST, string[savedfile].str);
	caseread:
		if((io = open(string[FILEBUF].str, 0)) < 0){
			if(initflag){
				putchar('?');
				putchar('o');
				putchar(' ');
				puts(string[FILEBUF].str);
				continue;
			}
			lastc = '\n';
			error('o'|FILERR);
		}
		setall();
		changed = (zero!=dol);
		ninbuf = 0;
		append(getfile, addr2);
		if(eqstr(string[savedfile].str, string[FILEBUF].str))
			if(cflag = changed)	/* Assignment = */
				modified();
		/* else append got cflag right */
		exfile();
		continue;
	case 'R':
		setnoaddr();
		newfile(TRUE, SAVENEVER, "q");
		restor();
		continue;
	case 's':
		setdot();
		nonzero();
		substitute(stackp != &stack[0], -1);
		continue;
	case 'S':
		setnoaddr();
		newfile(TRUE, SAVENEVER, "q");
		savall();
		continue;
	case 't':
		move(TRUE);
		continue;
	case 'u':
		setnoaddr();
		undo();
		modified();
		continue;
	case 'v':
		global(FALSE);
		continue;
	case 'V':
		globuf(FALSE);
		continue;
	case 'W':
	case 'w':
		if(addr2==0 && dol==zero)
			error('$');
		setall();
		if(newfile(TRUE, SAVEIFFIRST, string[savedfile].str))
			changed = cflag;
		else
			changed = (addr1>(zero+1) || addr2!=dol);
		if(c=='w' || (io=open(string[FILEBUF].str,1))==-1){
		  Create:
			if ((io = creat(string[FILEBUF].str, 0666)) < 0)
				error('o'|FILERR);
		}else{
			if((locn=lseek(io, 0L, 2)) == -1L)
				goto Create;
			if(locn != 0L)	/* W on non-empty file */
				changed = TRUE;	/* PHEW! figured it out */
		}
		putfile();
		if(cflag = changed)	/* Assignment = */
			modified();
		exfile();
		continue;
	case 'x':
		setdot();
		nonzero();
		xform();
		continue;
	case 'y':
		jump();
		continue;
	case 'z':
		strcom(getaz('z'));
		continue;
	case 'Z':
		setnoaddr();
		if((c=getchar())!=' ' && c!='\n')
			error('x');
		delall();
		cflag=FALSE;
		clearstring(savedfile);
		continue;
	case '"':
		setdot();
		dot=addr2;
		comment();
		continue;
	case '=':
		setall();
		putdn((addr2-zero)&077777);
		continue;
	case '>':
	case '<':
	case '|':
		setall();
	case '!':
		Unix(c);
		continue;
	case '#':
		setnoaddr();
		allnums();
		continue;
	case '%':
		setnoaddr();
		allstrs();
		continue;
	}
	error('x');
	}
}
setreset(opt)
	register int *opt;
{
	register c;

	c = getchar();
	if(c!='s' && c!= 'r')
		error('x');
	*opt = (c=='s');
}
delall(){
	if(dol!=zero){
		addr1=zero+1;
		addr2=dol;
		delete();
	}
}