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

📄 ed.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
			c = *lp++;			if(c == 0) {				if(Bputrune(&iobuf, '\n') < 0)					error(Q);				break;			}			if(Bputrune(&iobuf, c) < 0)				error(Q);		}	} while(a1 <= addr2);	if(Bflush(&iobuf) < 0)		error(Q);}intappend(int (*f)(void), int *a){	int *a1, *a2, *rdot, nline, tl;	nline = 0;	dot = a;	while((*f)() == 0) {		if((dol-zero) >= nlall) {			nlall += 512;			a1 = realloc(zero, (nlall+5)*sizeof(int*));			if(a1 == 0) {				error("MEM?");				rescue();			}			tl = a1 - zero;	/* relocate pointers */			zero += tl;			addr1 += tl;			addr2 += tl;			dol += tl;			dot += tl;		}		tl = putline();		nline++;		a1 = ++dol;		a2 = a1+1;		rdot = ++dot;		while(a1 > rdot)			*--a2 = *--a1;		*rdot = tl;	}	return nline;}voidadd(int i){	if(i && (given || dol > zero)) {		addr1--;		addr2--;	}	squeeze(0);	newline();	append(gettty, addr2);}voidbrowse(void){	int forward, n;	static bformat, bnum; /* 0 */	forward = 1;	peekc = getchr();	if(peekc != '\n'){		if(peekc == '-' || peekc == '+') {			if(peekc == '-')				forward = 0;			getchr();		}		n = getnum();		if(n > 0)			bpagesize = n;	}	newline();	if(pflag) {		bformat = listf;		bnum = listn;	} else {		listf = bformat;		listn = bnum;	}	if(forward) {		addr1 = addr2;		addr2 += bpagesize;		if(addr2 > dol)			addr2 = dol;	} else {		addr1 = addr2-bpagesize;		if(addr1 <= zero)			addr1 = zero+1;	}	printcom();}voidcallunix(void){	int c, pid;	Rune rune;	char buf[512];	char *p;	setnoaddr();	p = buf;	while((c=getchr()) != EOF && c != '\n')		if(p < &buf[sizeof(buf) - 6]) {			rune = c;			p += runetochar(p, &rune);		}	*p = 0;	pid = fork();	if(pid == 0) {		execl("/bin/rc", "rc", "-c", buf, nil);		exits("execl failed");	}	waiting = 1;	while(waitpid() != pid)		;	waiting = 0;	if(vflag)		putst("!");}voidquit(void){	if(vflag && fchange && dol!=zero) {		fchange = 0;		error(Q);	}	remove(tfname);	exits(0);}voidonquit(int sig){	USED(sig);	quit();}voidrdelete(int *ad1, int *ad2){	int *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;}voidgdelete(void){	int *a1, *a2, *a3;	a3 = dol;	for(a1=zero; (*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;}Rune*getline(int tl){	Rune *lp, *bp;	int nl;	lp = linebuf;	bp = getblock(tl, OREAD);	nl = nleft;	tl &= ~((BLKSIZE/2) - 1);	while(*lp++ = *bp++) {		nl -= sizeof(Rune);		if(nl == 0) {			bp = getblock(tl += BLKSIZE/2, OREAD);			nl = nleft;		}	}	return linebuf;}intputline(void){	Rune *lp, *bp;	int nl, tl;	fchange = 1;	lp = linebuf;	tl = tline;	bp = getblock(tl, OWRITE);	nl = nleft;	tl &= ~((BLKSIZE/2)-1);	while(*bp = *lp++) {		if(*bp++ == '\n') {			bp[-1] = 0;			linebp = lp;			break;		}		nl -= sizeof(Rune);		if(nl == 0) {			tl += BLKSIZE/2;			bp = getblock(tl, OWRITE);			nl = nleft;		}	}	nl = tline;	tline += ((lp-linebuf) + 03) & 077776;	return nl;}voidblkio(int b, uchar *buf, long (*iofcn)(int, void *, long)){	seek(tfile, b*BLKSIZE, 0);	if((*iofcn)(tfile, buf, BLKSIZE) != BLKSIZE) {		error(T);	}}Rune*getblock(int atl, int iof){	int bno, off;		static uchar ibuff[BLKSIZE];	static uchar obuff[BLKSIZE];	bno = atl / (BLKSIZE/2);	off = (atl<<1) & (BLKSIZE-1) & ~03;	if(bno >= NBLK) {		lastc = '\n';		error(T);	}	nleft = BLKSIZE - off;	if(bno == iblock) {		ichanged |= iof;		return (Rune*)(ibuff+off);	}	if(bno == oblock)		return (Rune*)(obuff+off);	if(iof == OREAD) {		if(ichanged)			blkio(iblock, ibuff, write);		ichanged = 0;		iblock = bno;		blkio(bno, ibuff, read);		return (Rune*)(ibuff+off);	}	if(oblock >= 0)		blkio(oblock, obuff, write);	oblock = bno;	return (Rune*)(obuff+off);}voidinit(void){	int *markp;	close(tfile);	tline = 2;	for(markp = names; markp < &names[26]; )		*markp++ = 0;	subnewa = 0;	anymarks = 0;	iblock = -1;	oblock = -1;	ichanged = 0;	if((tfile = create(tfname, ORDWR, 0600)) < 0){		error1(T);		exits(0);	}	dot = dol = zero;}voidglobal(int k){	Rune *gp, globuf[GBSIZE];	int c, *a1;	if(globp)		error(Q);	setwide();	squeeze(dol > zero);	c = getchr();	if(c == '\n')		error(Q);	compile(c);	gp = globuf;	while((c=getchr()) != '\n') {		if(c == EOF)			error(Q);		if(c == '\\') {			c = getchr();			if(c != '\n')				*gp++ = '\\';		}		*gp++ = c;		if(gp >= &globuf[GBSIZE-2])			error(Q);	}	if(gp == globuf)		*gp++ = 'p';	*gp++ = '\n';	*gp = 0;	for(a1=zero; a1<=dol; a1++) {		*a1 &= ~01;		if(a1 >= addr1 && a1 <= addr2 && match(a1) == k)			*a1 |= 01;	}	/*	 * Special case: g/.../d (avoid n^2 algorithm)	 */	if(globuf[0] == 'd' && globuf[1] == '\n' && globuf[2] == 0) {		gdelete();		return;	}	for(a1=zero; a1<=dol; a1++) {		if(*a1 & 01) {			*a1 &= ~01;			dot = a1;			globp = globuf;			commands();			a1 = zero;		}	}}voidjoin(void){	Rune *gp, *lp;	int *a1;	nonzero();	gp = genbuf;	for(a1=addr1; a1<=addr2; a1++) {		lp = getline(*a1);		while(*gp = *lp++)			if(gp++ >= &genbuf[LBSIZE-2])				error(Q);	}	lp = linebuf;	gp = genbuf;	while(*lp++ = *gp++)		;	*addr1 = putline();	if(addr1 < addr2)		rdelete(addr1+1, addr2);	dot = addr1;}voidsubstitute(int inglob){	int *mp, *a1, nl, gsubf, n;	n = getnum();	/* OK even if n==0 */	gsubf = compsub();	for(a1 = addr1; a1 <= addr2; a1++) {		if(match(a1)){			int *ozero;			int m = n;			do {				int span = loc2-loc1;				if(--m <= 0) {					dosub();					if(!gsubf)						break;					if(span == 0) {	/* null RE match */						if(*loc2 == 0)							break;						loc2++;					}				}			} while(match(0));			if(m <= 0) {				inglob |= 01;				subnewa = putline();				*a1 &= ~01;				if(anymarks) {					for(mp=names; mp<&names[26]; mp++)						if(*mp == *a1)							*mp = subnewa;				}				subolda = *a1;				*a1 = subnewa;				ozero = zero;				nl = append(getsub, a1);				addr2 += nl;				nl += zero-ozero;				a1 += nl;			}		}	}	if(inglob == 0)		error(Q);}intcompsub(void){	int seof, c;	Rune *p;	seof = getchr();	if(seof == '\n' || seof == ' ')		error(Q);	compile(seof);	p = rhsbuf;	for(;;) {		c = getchr();		if(c == '\\') {			c = getchr();			*p++ = ESCFLG;			if(p >= &rhsbuf[LBSIZE/2])				error(Q);		} else		if(c == '\n' && (!globp || !globp[0])) {			peekc = c;			pflag++;			break;		} else		if(c == seof)			break;		*p++ = c;		if(p >= &rhsbuf[LBSIZE/2])			error(Q);	}	*p = 0;	peekc = getchr();	if(peekc == 'g') {		peekc = 0;		newline();		return 1;	}	newline();	return 0;}intgetsub(void){	Rune *p1, *p2;	p1 = linebuf;	if((p2 = linebp) == 0)		return EOF;	while(*p1++ = *p2++)		;	linebp = 0;	return 0;}voiddosub(void){	Rune *lp, *sp, *rp;	int c, n;	lp = linebuf;	sp = genbuf;	rp = rhsbuf;	while(lp < loc1)		*sp++ = *lp++;	while(c = *rp++) {		if(c == '&'){			sp = place(sp, loc1, loc2);			continue;		}		if(c == ESCFLG && (c = *rp++) >= '1' && c < MAXSUB+'0') {			n = c-'0';			if(subexp[n].rsp && subexp[n].rep) {				sp = place(sp, subexp[n].rsp, subexp[n].rep);				continue;			}			error(Q);		}		*sp++ = c;		if(sp >= &genbuf[LBSIZE])			error(Q);	}	lp = loc2;	loc2 = sp - genbuf + linebuf;	while(*sp++ = *lp++)		if(sp >= &genbuf[LBSIZE])			error(Q);	lp = linebuf;	sp = genbuf;	while(*lp++ = *sp++)		;}Rune*place(Rune *sp, Rune *l1, Rune *l2){	while(l1 < l2) {		*sp++ = *l1++;		if(sp >= &genbuf[LBSIZE])			error(Q);	}	return sp;}voidmove(int cflag){	int *adt, *ad1, *ad2;	nonzero();	if((adt = address())==0)	/* address() guarantees addr is in range */		error(Q);	newline();	if(cflag) {		int *ozero, delta;		ad1 = dol;		ozero = zero;		append(getcopy, ad1++);		ad2 = dol;		delta = zero - ozero;		ad1 += delta;		adt += delta;	} else {		ad2 = addr2;		for(ad1 = addr1; ad1 <= ad2;)			*ad1++ &= ~01;		ad1 = addr1;	}	ad2++;	if(adt<ad1) {		dot = adt + (ad2-ad1);		if((++adt)==ad1)			return;		reverse(adt, ad1);		reverse(ad1, ad2);		reverse(adt, ad2);	} else	if(adt >= ad2) {		dot = adt++;		reverse(ad1, ad2);		reverse(ad2, adt);		reverse(ad1, adt);	} else		error(Q);	fchange = 1;}voidreverse(int *a1, int *a2){	int t;	for(;;) {		t = *--a2;		if(a2 <= a1)			return;		*a2 = *a1;		*a1++ = t;	}}intgetcopy(void){	if(addr1 > addr2)		return EOF;	getline(*addr1++);	return 0;}voidcompile(int eof){	Rune c;	char *ep;	char expbuf[ESIZE];	if((c = getchr()) == '\n') {		peekc = c;		c = eof;	}	if(c == eof) {		if(!pattern)			error(Q);		return;	}	if(pattern) {		free(pattern);		pattern = 0;	}	ep = expbuf;	do {		if(c == '\\') {			if(ep >= expbuf+sizeof(expbuf)) {				error(Q);				return;			}			ep += runetochar(ep, &c);			if((c = getchr()) == '\n') {				error(Q);				return;			}		}		if(ep >= expbuf+sizeof(expbuf)) {			error(Q);			return;		}		ep += runetochar(ep, &c);	} while((c = getchr()) != eof && c != '\n');	if(c == '\n')		peekc = c;	*ep = 0;	pattern = regcomp(expbuf);}intmatch(int *addr){	if(!pattern)		return 0;	if(addr){		if(addr == zero)			return 0;		subexp[0].rsp = getline(*addr);	} else		subexp[0].rsp = loc2;	subexp[0].rep = 0;	if(rregexec(pattern, linebuf, subexp, MAXSUB)) {		loc1 = subexp[0].rsp;		loc2 = subexp[0].rep;		return 1;	}	loc1 = loc2 = 0;	return 0;	}voidputd(void){	int r;	r = count%10;	count /= 10;	if(count)		putd();	putchr(r + L'0');}voidputst(char *sp){	Rune r;	col = 0;	for(;;) {		sp += chartorune(&r, sp);		if(r == 0)			break;		putchr(r);	}	putchr(L'\n');}voidputshst(Rune *sp){	col = 0;	while(*sp)		putchr(*sp++);	putchr(L'\n');}voidputchr(int ac){	char *lp;	int c;	Rune rune;	lp = linp;	c = ac;	if(listf) {		if(c == '\n') {			if(linp != line && linp[-1] == ' ') {				*lp++ = '\\';				*lp++ = 'n';			}		} else {			if(col > (72-6-2)) {				col = 8;				*lp++ = '\\';				*lp++ = '\n';				*lp++ = '\t';			}			col++;			if(c=='\b' || c=='\t' || c=='\\') {				*lp++ = '\\';				if(c == '\b')					c = 'b';				else				if(c == '\t')					c = 't';				col++;			} else			if(c<' ' || c>='\177') {				*lp++ = '\\';				*lp++ = 'x';				*lp++ =  hex[c>>12];				*lp++ =  hex[c>>8&0xF];				*lp++ =  hex[c>>4&0xF];				c     =  hex[c&0xF];				col += 5;			}		}	}	rune = c;	lp += runetochar(lp, &rune);	if(c == '\n' || lp >= &line[sizeof(line)-5]) {		linp = line;		write(oflag? 2: 1, line, lp-line);		return;	}	linp = lp;}char*mktemp(char *as){	char *s;	unsigned pid;	int i;	pid = getpid();	s = as;	while(*s++)		;	s--;	while(*--s == 'X') {		*s = pid % 10 + '0';		pid /= 10;	}	s++;	i = 'a';	while(access(as, 0) != -1) {		if(i == 'z')			return "/";		*s = i++;	}	return as;}voidregerror(char *s){	USED(s);	error(Q);}

⌨️ 快捷键说明

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