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

📄 ed.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Editor */#include <signal.h>#include <sgtty.h>#include <setjmp.h>#define	NULL	0#define	FNSIZE	64#define	LBSIZE	512#define	ESIZE	128#define	GBSIZE	256#define	NBRA	5#define	EOF	-1#define	KSIZE	9#define	CBRA	1#define	CCHR	2#define	CDOT	4#define	CCL	6#define	NCCL	8#define	CDOL	10#define	CEOF	11#define	CKET	12#define	CBACK	14#define	STAR	01char	Q[]	= "";char	T[]	= "TMP";#define	READ	0#define	WRITE	1int	peekc;int	lastc;char	savedfile[FNSIZE];char	file[FNSIZE];char	linebuf[LBSIZE];char	rhsbuf[LBSIZE/2];char	expbuf[ESIZE+4];int	circfl;int	*zero;int	*dot;int	*dol;int	*addr1;int	*addr2;char	genbuf[LBSIZE];long	count;char	*nextip;char	*linebp;int	ninbuf;int	io;int	pflag;long	lseek();int	(*oldhup)();int	(*oldquit)();int	vflag	= 1;int	xflag;int	xtflag;int	kflag;char	key[KSIZE + 1];char	crbuf[512];char	perm[768];char	tperm[768];int	listf;int	col;char	*globp;int	tfile	= -1;int	tline;char	*tfname;char	*loc1;char	*loc2;char	*locs;char	ibuff[512];int	iblock	= -1;char	obuff[512];int	oblock	= -1;int	ichanged;int	nleft;char	WRERR[]	= "WRITE ERROR";int	names[26];int	anymarks;char	*braslist[NBRA];char	*braelist[NBRA];int	nbra;int	subnewa;int	subolda;int	fchange;int	wrapp;unsigned nlall = 128;int	*address();char	*getline();char	*getblock();char	*place();char	*mktemp();char	*malloc();char	*realloc();jmp_buf	savej;main(argc, argv)char **argv;{	register char *p1, *p2;	extern int onintr(), quit(), onhup();	int (*oldintr)();	oldquit = signal(SIGQUIT, SIG_IGN);	oldhup = signal(SIGHUP, SIG_IGN);	oldintr = signal(SIGINT, SIG_IGN);	if ((int)signal(SIGTERM, SIG_IGN) == 0)		signal(SIGTERM, quit);	argv++;	while (argc > 1 && **argv=='-') {		switch((*argv)[1]) {		case '\0':			vflag = 0;			break;		case 'q':			signal(SIGQUIT, SIG_DFL);			vflag = 1;			break;		case 'x':			xflag = 1;			break;		}		argv++;		argc--;	}	if(xflag){		getkey();		kflag = crinit(key, perm);	}	if (argc>1) {		p1 = *argv;		p2 = savedfile;		while (*p2++ = *p1++)			;		globp = "r";	}	zero = (int *)malloc(nlall*sizeof(int));	tfname = mktemp("/tmp/eXXXXX");	init();	if (((int)oldintr&01) == 0)		signal(SIGINT, onintr);	if (((int)oldhup&01) == 0)		signal(SIGHUP, onhup);	setjmp(savej);	commands();	quit();}commands(){	int getfile(), gettty();	register *a1, c;	for (;;) {	if (pflag) {		pflag = 0;		addr1 = addr2 = dot;		goto print;	}	addr1 = 0;	addr2 = 0;	do {		addr1 = addr2;		if ((a1 = address())==0) {			c = getchr();			break;		}		addr2 = a1;		if ((c=getchr()) == ';') {			c = ',';			dot = a1;		}	} while (c==',');	if (addr1==0)		addr1 = addr2;	switch(c) {	case 'a':		setdot();		newline();		append(gettty, addr2);		continue;	case 'c':		delete();		append(gettty, addr1-1);		continue;	case 'd':		delete();		continue;	case 'E':		fchange = 0;		c = 'e';	case 'e':		setnoaddr();		if (vflag && fchange) {			fchange = 0;			error(Q);		}		filename(c);		init();		addr2 = zero;		goto caseread;	case 'f':		setnoaddr();		filename(c);		puts(savedfile);		continue;	case 'g':		global(1);		continue;	case 'i':		setdot();		nonzero();		newline();		append(gettty, addr2-1);		continue;	case 'j':		if (addr2==0) {			addr1 = dot;			addr2 = dot+1;		}		setdot();		newline();		nonzero();		join();		continue;	case 'k':		if ((c = getchr()) < 'a' || c > 'z')			error(Q);		newline();		setdot();		nonzero();		names[c-'a'] = *addr2 & ~01;		anymarks |= 01;		continue;	case 'm':		move(0);		continue;	case '\n':		if (addr2==0)			addr2 = dot+1;		addr1 = addr2;		goto print;	case 'l':		listf++;	case 'p':	case 'P':		newline();	print:		setdot();		nonzero();		a1 = addr1;		do {			puts(getline(*a1++));		} while (a1 <= addr2);		dot = addr2;		listf = 0;		continue;	case 'Q':		fchange = 0;	case 'q':		setnoaddr();		newline();		quit();	case 'r':		filename(c);	caseread:		if ((io = open(file, 0)) < 0) {			lastc = '\n';			error(file);		}		setall();		ninbuf = 0;		c = zero != dol;		append(getfile, addr2);		exfile();		fchange = c;		continue;	case 's':		setdot();		nonzero();		substitute(globp!=0);		continue;	case 't':		move(1);		continue;	case 'u':		setdot();		nonzero();		newline();		if ((*addr2&~01) != subnewa)			error(Q);		*addr2 = subolda;		dot = addr2;		continue;	case 'v':		global(0);		continue;	case 'W':		wrapp++;	case 'w':		setall();		nonzero();		filename(c);		if(!wrapp ||		  ((io = open(file,1)) == -1) ||		  ((lseek(io, 0L, 2)) == -1))			if ((io = creat(file, 0666)) < 0)				error(file);		wrapp = 0;		putfile();		exfile();		if (addr1==zero+1 && addr2==dol)			fchange = 0;		continue;	case 'x':		setnoaddr();		newline();		xflag = 1;		puts("Entering encrypting mode!");		getkey();		kflag = crinit(key, perm);		continue;	case '=':		setall();		newline();		count = (addr2-zero)&077777;		putd();		putchr('\n');		continue;	case '!':		callunix();		continue;	case EOF:		return;	}	error(Q);	}}int *address(){	register *a1, minus, c;	int n, relerr;	minus = 0;	a1 = 0;	for (;;) {		c = getchr();		if ('0'<=c && c<='9') {			n = 0;			do {				n *= 10;				n += c - '0';			} while ((c = getchr())>='0' && c<='9');			peekc = c;			if (a1==0)				a1 = zero;			if (minus<0)				n = -n;			a1 += n;			minus = 0;			continue;		}		relerr = 0;		if (a1 || minus)			relerr++;		switch(c) {		case ' ':		case '\t':			continue;			case '+':			minus++;			if (a1==0)				a1 = dot;			continue;		case '-':		case '^':			minus--;			if (a1==0)				a1 = dot;			continue;			case '?':		case '/':			compile(c);			a1 = dot;			for (;;) {				if (c=='/') {					a1++;					if (a1 > dol)						a1 = zero;				} else {					a1--;					if (a1 < zero)						a1 = dol;				}				if (execute(0, a1))					break;				if (a1==dot)					error(Q);			}			break;			case '$':			a1 = dol;			break;			case '.':			a1 = dot;			break;		case '\'':			if ((c = getchr()) < 'a' || c > 'z')				error(Q);			for (a1=zero; a1<=dol; a1++)				if (names[c-'a'] == (*a1 & ~01))					break;			break;			default:			peekc = c;			if (a1==0)				return(0);			a1 += minus;			if (a1<zero || a1>dol)				error(Q);			return(a1);		}		if (relerr)			error(Q);	}}setdot(){	if (addr2 == 0)		addr1 = addr2 = dot;	if (addr1 > addr2)		error(Q);}setall(){	if (addr2==0) {		addr1 = zero+1;		addr2 = dol;		if (dol==zero)			addr1 = zero;	}	setdot();}setnoaddr(){	if (addr2)		error(Q);}nonzero(){	if (addr1<=zero || addr2>dol)		error(Q);}newline(){	register c;	if ((c = getchr()) == '\n')		return;	if (c=='p' || c=='l') {		pflag++;		if (c=='l')			listf++;		if (getchr() == '\n')			return;	}	error(Q);}filename(comm){	register char *p1, *p2;	register c;	count = 0;	c = getchr();	if (c=='\n' || c==EOF) {		p1 = savedfile;		if (*p1==0 && comm!='f')			error(Q);		p2 = file;		while (*p2++ = *p1++)			;		return;	}	if (c!=' ')		error(Q);	while ((c = getchr()) == ' ')		;	if (c=='\n')		error(Q);	p1 = file;	do {		*p1++ = c;		if (c==' ' || c==EOF)			error(Q);	} while ((c = getchr()) != '\n');	*p1++ = 0;	if (savedfile[0]==0 || comm=='e' || comm=='f') {		p1 = savedfile;		p2 = file;		while (*p1++ = *p2++)			;	}}exfile(){	close(io);	io = -1;	if (vflag) {		putd();		putchr('\n');	}}onintr(){	signal(SIGINT, onintr);	putchr('\n');	lastc = '\n';	error(Q);}onhup(){	signal(SIGINT, SIG_IGN);	signal(SIGHUP, SIG_IGN);	if (dol > zero) {		addr1 = zero+1;		addr2 = dol;		io = creat("ed.hup", 0666);		if (io > 0)			putfile();	}	fchange = 0;	quit();}error(s)char *s;{	register c;	wrapp = 0;	listf = 0;	putchr('?');	puts(s);	count = 0;	lseek(0, (long)0, 2);	pflag = 0;	if (globp)		lastc = '\n';	globp = 0;	peekc = lastc;	if(lastc)		while ((c = getchr()) != '\n' && c != EOF)			;	if (io > 0) {		close(io);		io = -1;	}	longjmp(savej, 1);}getchr(){	char c;	if (lastc=peekc) {		peekc = 0;		return(lastc);	}	if (globp) {		if ((lastc = *globp++) != 0)			return(lastc);		globp = 0;		return(EOF);	}	if (read(0, &c, 1) <= 0)		return(lastc = EOF);	lastc = c&0177;	return(lastc);}gettty(){	register c;	register char *gf;	register char *p;	p = linebuf;	gf = globp;	while ((c = getchr()) != '\n') {		if (c==EOF) {			if (gf)				peekc = c;			return(c);		}		if ((c &= 0177) == 0)			continue;		*p++ = c;		if (p >= &linebuf[LBSIZE-2])			error(Q);	}	*p++ = 0;	if (linebuf[0]=='.' && linebuf[1]==0)		return(EOF);	return(0);}getfile(){	register c;	register char *lp, *fp;	lp = linebuf;	fp = nextip;	do {		if (--ninbuf < 0) {			if ((ninbuf = read(io, genbuf, LBSIZE)-1) < 0)				return(EOF);			fp = genbuf;			while(fp < &genbuf[ninbuf]) {				if (*fp++ & 0200) {					if (kflag)						crblock(perm, genbuf, ninbuf+1, count);					break;				}			}			fp = genbuf;		}		c = *fp++;		if (c=='\0')			continue;		if (c&0200 || lp >= &linebuf[LBSIZE]) {			lastc = '\n';			error(Q);		}		*lp++ = c;		count++;	} while (c != '\n');	*--lp = 0;	nextip = fp;	return(0);}putfile(){	int *a1, n;	register char *fp, *lp;	register nib;	nib = 512;	fp = genbuf;	a1 = addr1;	do {		lp = getline(*a1++);		for (;;) {			if (--nib < 0) {				n = fp-genbuf;				if(kflag)					crblock(perm, genbuf, n, count-n);				if(write(io, genbuf, n) != n) {					puts(WRERR);					error(Q);				}				nib = 511;				fp = genbuf;			}			count++;			if ((*fp++ = *lp++) == 0) {				fp[-1] = '\n';				break;			}		}	} while (a1 <= addr2);	n = fp-genbuf;	if(kflag)		crblock(perm, genbuf, n, count-n);	if(write(io, genbuf, n) != n) {		puts(WRERR);		error(Q);	}}append(f, a)int *a;int (*f)();{	register *a1, *a2, *rdot;	int nline, tl;	nline = 0;	dot = a;	while ((*f)() == 0) {		if ((dol-zero)+1 >= nlall) {			int *ozero = zero;			nlall += 512;			free((char *)zero);			if ((zero = (int *)realloc((char *)zero, nlall*sizeof(int)))==NULL) {				lastc = '\n';				zero = ozero;				error("MEM?");			}			dot += zero - ozero;			dol += zero - ozero;		}		tl = putline();		nline++;		a1 = ++dol;		a2 = a1+1;		rdot = ++dot;		while (a1 > rdot)			*--a2 = *--a1;		*rdot = tl;	}	return(nline);}callunix(){	register (*savint)(), pid, rpid;	int retcode;	setnoaddr();	if ((pid = fork()) == 0) {		signal(SIGHUP, oldhup);		signal(SIGQUIT, oldquit);		execl("/bin/sh", "sh", "-t", 0);		exit(0100);	}	savint = signal(SIGINT, SIG_IGN);	while ((rpid = wait(&retcode)) != pid && rpid != -1)		;	signal(SIGINT, savint);	puts("!");}quit(){	if (vflag && fchange && dol!=zero) {		fchange = 0;		error(Q);	}	unlink(tfname);	exit(0);}delete(){	setdot();	newline();	nonzero();	rdelete(addr1, addr2);}rdelete(ad1, ad2)int *ad1, *ad2;{	register *a1, *a2, *a3;	a1 = ad1;	a2 = ad2+1;	a3 = dol;	dol -= a2 - a1;	do {		*a1++ = *a2++;	} while (a2 <= a3);	a1 = ad1;	if (a1 > dol)		a1 = dol;	dot = a1;	fchange = 1;}gdelete(){	register *a1, *a2, *a3;	a3 = dol;	for (a1=zero+1; (*a1&01)==0; a1++)		if (a1>=a3)			return;	for (a2=a1+1; a2<=a3;) {		if (*a2&01) {			a2++;			dot = a1;		} else			*a1++ = *a2++;	}	dol = a1-1;	if (dot>dol)		dot = dol;	fchange = 1;}char *getline(tl){	register char *bp, *lp;	register nl;	lp = linebuf;	bp = getblock(tl, READ);	nl = nleft;	tl &= ~0377;	while (*lp++ = *bp++)		if (--nl == 0) {			bp = getblock(tl+=0400, READ);			nl = nleft;		}	return(linebuf);}putline(){	register char *bp, *lp;	register nl;	int tl;	fchange = 1;	lp = linebuf;	tl = tline;	bp = getblock(tl, WRITE);	nl = nleft;	tl &= ~0377;	while (*bp = *lp++) {		if (*bp++ == '\n') {			*--bp = 0;			linebp = lp;			break;		}		if (--nl == 0) {			bp = getblock(tl+=0400, WRITE);

⌨️ 快捷键说明

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