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

📄 ed.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Editor */#include <u.h>#include <libc.h>#include <bio.h>#include <regexp.h>enum{	FNSIZE	= 128,		/* file name */	LBSIZE	= 4096,		/* max line size */	BLKSIZE	= 4096,		/* block size in temp file */	NBLK	= 8191,		/* max size of temp file */	ESIZE	= 256,		/* max size of reg exp */	GBSIZE	= 256,		/* max size of global command */	MAXSUB	= 9,		/* max number of sub reg exp */	ESCFLG	= 0xFFFF,	/* escape Rune - user defined code */	EOF	= -1,};void	(*oldhup)(int);void	(*oldquit)(int);int*	addr1;int*	addr2;int	anymarks;Biobuf	bcons;int	col;long	count;int*	dol;int*	dot;int	fchange;char	file[FNSIZE];Rune	genbuf[LBSIZE];int	given;Rune*	globp;int	iblock;int	ichanged;int	io;Biobuf	iobuf;int	lastc;char	line[70];Rune*	linebp;Rune	linebuf[LBSIZE];int	listf;int	listn;Rune*	loc1;Rune*	loc2;int	names[26];int	nleft;int	oblock;int	oflag;Reprog	*pattern;int	peekc;int	pflag;int	rescuing;Rune	rhsbuf[LBSIZE/2];char	savedfile[FNSIZE];jmp_buf	savej;int	subnewa;int	subolda;Resub	subexp[MAXSUB];char*	tfname;int	tline;int	waiting;int	wrapp;int*	zero;char	Q[]	= "";char	T[]	= "TMP";char	WRERR[]	= "WRITE ERROR";int	bpagesize = 20;char	hex[]	= "0123456789abcdef";char*	linp	= line;ulong	nlall = 128;int	tfile	= -1;int	vflag	= 1;void	add(int);int*	address(void);int	append(int(*)(void), int*);void	browse(void);void	callunix(void);void	commands(void);void	compile(int);int	compsub(void);void	dosub(void);void	error(char*);int	match(int*);void	exfile(int);void	filename(int);Rune*	getblock(int, int);int	getchr(void);int	getcopy(void);int	getfile(void);Rune*	getline(int);int	getnum(void);int	getsub(void);int	gettty(void);void	global(int);void	init(void);void	join(void);void	move(int);void	newline(void);void	nonzero(void);void	notifyf(void*, char*);Rune*	place(Rune*, Rune*, Rune*);void	printcom(void);void	putchr(int);void	putd(void);void	putfile(void);int	putline(void);void	putshst(Rune*);void	putst(char*);void	quit(void);void	rdelete(int*, int*);void	regerror(char *);void	reverse(int*, int*);void	setnoaddr(void);void	setwide(void);void	squeeze(int);void	substitute(int);voidmain(int argc, char *argv[]){	char *p1, *p2;	Binit(&bcons, 0, OREAD);	notify(notifyf);	ARGBEGIN {	case 'o':		oflag = 1;		vflag = 0;		break;	} ARGEND	USED(argc);	if(*argv && (strcmp(*argv, "-") == 0)) {		argv++;		vflag = 0;	}	if(oflag) {		p1 = "/fd/1";		p2 = savedfile;		while(*p2++ = *p1++)			;		globp = L"a";	} else	if(*argv) {		p1 = *argv;		p2 = savedfile;		while(*p2++ = *p1++)			if(p2 >= &savedfile[sizeof(savedfile)])				p2--;		globp = L"r";	}	zero = malloc((nlall+5)*sizeof(int*));	tfname = mktemp("/tmp/eXXXXX");	init();	setjmp(savej);	commands();	quit();}voidcommands(void){	int *a1, c, temp;	char lastsep;	Dir *d;	for(;;) {		if(pflag) {			pflag = 0;			addr1 = addr2 = dot;			printcom();		}		c = '\n';		for(addr1 = 0;;) {			lastsep = c;			a1 = address();			c = getchr();			if(c != ',' && c != ';')				break;			if(lastsep == ',')				error(Q);			if(a1 == 0) {				a1 = zero+1;				if(a1 > dol)					a1--;			}			addr1 = a1;			if(c == ';')				dot = a1;		}		if(lastsep != '\n' && a1 == 0)			a1 = dol;		if((addr2=a1) == 0) {			given = 0;			addr2 = dot;			} else			given = 1;		if(addr1 == 0)			addr1 = addr2;		switch(c) {		case 'a':			add(0);			continue;		case 'b':			nonzero();			browse();			continue;		case 'c':			nonzero();			newline();			rdelete(addr1, addr2);			append(gettty, addr1-1);			continue;		case 'd':			nonzero();			newline();			rdelete(addr1, addr2);			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);			putst(savedfile);			continue;		case 'g':			global(1);			continue;		case 'i':			add(-1);			continue;		case 'j':			if(!given)				addr2++;			newline();			join();			continue;		case 'k':			nonzero();			c = getchr();			if(c < 'a' || c > 'z')				error(Q);			newline();			names[c-'a'] = *addr2 & ~01;			anymarks |= 01;			continue;		case 'm':			move(0);			continue;		case 'n':			listn++;			newline();			printcom();			continue;		case '\n':			if(a1==0) {				a1 = dot+1;				addr2 = a1;				addr1 = a1;			}			if(lastsep==';')				addr1 = a1;			printcom();			continue;		case 'l':			listf++;		case 'p':		case 'P':			newline();			printcom();			continue;		case 'Q':			fchange = 0;		case 'q':			setnoaddr();			newline();			quit();		case 'r':			filename(c);		caseread:			if((io=open(file, OREAD)) < 0) {				lastc = '\n';				error(file);			}			if((d = dirfstat(io)) != nil){				if(d->mode & DMAPPEND)					print("warning: %s is append only\n", file);				free(d);			}			Binit(&iobuf, io, OREAD);			setwide();			squeeze(0);			c = zero != dol;			append(getfile, addr2);			exfile(OREAD);			fchange = c;			continue;		case 's':			nonzero();			substitute(globp != 0);			continue;		case 't':			move(1);			continue;		case 'u':			nonzero();			newline();			if((*addr2&~01) != subnewa)				error(Q);			*addr2 = subolda;			dot = addr2;			continue;		case 'v':			global(0);			continue;		case 'W':			wrapp++;		case 'w':			setwide();			squeeze(dol>zero);			temp = getchr();			if(temp != 'q' && temp != 'Q') {				peekc = temp;				temp = 0;			}			filename(c);			if(!wrapp ||			  ((io = open(file, OWRITE)) == -1) ||			  ((seek(io, 0L, 2)) == -1))				if((io = create(file, OWRITE, 0666)) < 0)					error(file);			Binit(&iobuf, io, OWRITE);			wrapp = 0;			if(dol > zero)				putfile();			exfile(OWRITE);			if(addr1<=zero+1 && addr2==dol)				fchange = 0;			if(temp == 'Q')				fchange = 0;			if(temp)				quit();			continue;		case '=':			setwide();			squeeze(0);			newline();			count = addr2 - zero;			putd();			putchr(L'\n');			continue;		case '!':			callunix();			continue;		case EOF:			return;		}		error(Q);	}}voidprintcom(void){	int *a1;	nonzero();	a1 = addr1;	do {		if(listn) {			count = a1-zero;			putd();			putchr(L'\t');		}		putshst(getline(*a1++));	} while(a1 <= addr2);	dot = addr2;	listf = 0;	listn = 0;	pflag = 0;}int*address(void){	int sign, *a, opcnt, nextopand, *b, c;	nextopand = -1;	sign = 1;	opcnt = 0;	a = dot;	do {		do {			c = getchr();		} while(c == ' ' || c == '\t');		if(c >= '0' && c <= '9') {			peekc = c;			if(!opcnt)				a = zero;			a += sign*getnum();		} else		switch(c) {		case '$':			a = dol;		case '.':			if(opcnt)				error(Q);			break;		case '\'':			c = getchr();			if(opcnt || c < 'a' || c > 'z')				error(Q);			a = zero;			do {				a++;			} while(a <= dol && names[c-'a'] != (*a & ~01));			break;		case '?':			sign = -sign;		case '/':			compile(c);			b = a;			for(;;) {				a += sign;				if(a <= zero)					a = dol;				if(a > dol)					a = zero;				if(match(a))					break;				if(a == b)					error(Q);			}			break;		default:			if(nextopand == opcnt) {				a += sign;				if(a < zero || dol < a)					continue;       /* error(Q); */			}			if(c != '+' && c != '-' && c != '^') {				peekc = c;				if(opcnt == 0)					a = 0;				return a;			}			sign = 1;			if(c != '+')				sign = -sign;			nextopand = ++opcnt;			continue;		}		sign = 1;		opcnt++;	} while(zero <= a && a <= dol);	error(Q);	return 0;}intgetnum(void){	int r, c;	r = 0;	for(;;) {		c = getchr();		if(c < '0' || c > '9')			break;		r = r*10 + (c-'0');	}	peekc = c;	return r;}voidsetwide(void){	if(!given) {		addr1 = zero + (dol>zero);		addr2 = dol;	}}voidsetnoaddr(void){	if(given)		error(Q);}voidnonzero(void){	squeeze(1);}voidsqueeze(int i){	if(addr1 < zero+i || addr2 > dol || addr1 > addr2)		error(Q);}voidnewline(void){	int c;	c = getchr();	if(c == '\n' || c == EOF)		return;	if(c == 'p' || c == 'l' || c == 'n') {		pflag++;		if(c == 'l')			listf++;		else		if(c == 'n')			listn++;		c = getchr();		if(c == '\n')			return;	}	error(Q);}voidfilename(int comm){	char *p1, *p2;	Rune rune;	int 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 {		if(p1 >= &file[sizeof(file)-6] || c == ' ' || c == EOF)			error(Q);		rune = c;		p1 += runetochar(p1, &rune);	} while((c=getchr()) != '\n');	*p1 = 0;	if(savedfile[0] == 0 || comm == 'e' || comm == 'f') {		p1 = savedfile;		p2 = file;		while(*p1++ = *p2++)			;	}}voidexfile(int om){	if(om == OWRITE)		if(Bflush(&iobuf) < 0)			error(Q);	close(io);	io = -1;	if(vflag) {		putd();		putchr(L'\n');	}}voiderror1(char *s){	int c;	wrapp = 0;	listf = 0;	listn = 0;	count = 0;	seek(0, 0, 2);	pflag = 0;	if(globp)		lastc = '\n';	globp = 0;	peekc = lastc;	if(lastc)		for(;;) {			c = getchr();			if(c == '\n' || c == EOF)				break;		}	if(io > 0) {		close(io);		io = -1;	}	putchr(L'?');	putst(s);}voiderror(char *s){	error1(s);	longjmp(savej, 1);}voidrescue(void){	rescuing = 1;	if(dol > zero) {		addr1 = zero+1;		addr2 = dol;		io = create("ed.hup", OWRITE, 0666);		if(io > 0){			Binit(&iobuf, io, OWRITE);			putfile();		}	}	fchange = 0;	quit();}voidnotifyf(void *a, char *s){	if(strcmp(s, "interrupt") == 0){		if(rescuing || waiting)			noted(NCONT);		putchr(L'\n');		lastc = '\n';		error1(Q);		notejmp(a, savej, 0);	}	if(strcmp(s, "hangup") == 0){		if(rescuing)			noted(NDFLT);		rescue();	}	fprint(2, "ed: note: %s\n", s);	abort();}intgetchr(void){	if(lastc = peekc) {		peekc = 0;		return lastc;	}	if(globp) {		if((lastc=*globp++) != 0)			return lastc;		globp = 0;		return EOF;	}	lastc = Bgetrune(&bcons);	return lastc;}intgety(void){	int c;	Rune *gf, *p;	p = linebuf;	gf = globp;	for(;;) {		c = getchr();		if(c == '\n') {			*p = 0;			return 0;		}		if(c == EOF) {			if(gf)				peekc = c;			return c;		}		if(c == 0)			continue;		*p++ = c;		if(p >= &linebuf[LBSIZE-2])			error(Q);	}}intgettty(void){	int rc;	rc = gety();	if(rc)		return rc;	if(linebuf[0] == '.' && linebuf[1] == 0)		return EOF;	return 0;}intgetfile(void){	int c;	Rune *lp;	lp = linebuf;	do {		c = Bgetrune(&iobuf);		if(c < 0) {			if(lp > linebuf) {				putst("'\\n' appended");				c = '\n';			} else				return EOF;		}		if(lp >= &linebuf[LBSIZE]) {			lastc = '\n';			error(Q);		}		*lp++ = c;		count++;	} while(c != '\n');	lp[-1] = 0;	return 0;}voidputfile(void){	int *a1;	Rune *lp;	long c;	a1 = addr1;	do {		lp = getline(*a1++);		for(;;) {			count++;

⌨️ 快捷键说明

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