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

📄 rasp.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include "sam.h"/* * GROWDATASIZE must be big enough that all errors go out as Hgrowdata's, * so they will be scrolled into visibility in the ~~sam~~ window (yuck!). */#define	GROWDATASIZE	50	/* if size is > this, send data with grow */void	rcut(List*, Posn, Posn);int	rterm(List*, Posn);void	rgrow(List*, Posn, Posn);static	Posn	growpos;static	Posn	grown;static	Posn	shrinkpos;static	Posn	shrunk;/* * rasp routines inform the terminal of changes to the file. * * a rasp is a list of spans within the file, and an indication * of whether the terminal knows about the span. * * optimize by coalescing multiple updates to the same span * if it is not known by the terminal. * * other possible optimizations: flush terminal's rasp by cut everything, * insert everything if rasp gets too large. *//* * only called for initial load of file */voidraspload(File *f){	if(f->rasp == nil)		return;	grown = f->nc;	growpos = 0;	if(f->nc)		rgrow(f->rasp, 0, f->nc);	raspdone(f, 1);}voidraspstart(File *f){	if(f->rasp == nil)		return;	grown = 0;	shrunk = 0;	noflush = 1;}voidraspdone(File *f, int toterm){	if(f->dot.r.p1 > f->nc)		f->dot.r.p1 = f->nc;	if(f->dot.r.p2 > f->nc)		f->dot.r.p2 = f->nc;	if(f->mark.p1 > f->nc)		f->mark.p1 = f->nc;	if(f->mark.p2 > f->nc)		f->mark.p2 = f->nc;	if(f->rasp == nil)		return;	if(grown)		outTsll(Hgrow, f->tag, growpos, grown);	else if(shrunk)		outTsll(Hcut, f->tag, shrinkpos, shrunk);	if(toterm)		outTs(Hcheck0, f->tag);	outflush();	noflush = 0;	if(f == cmd){		cmdpt += cmdptadv;		cmdptadv = 0;	}}voidraspdelete(File *f, uint p1, uint p2, int toterm){	long n;	n = p2 - p1;	if(n == 0)		return;	if(p2 <= f->dot.r.p1){		f->dot.r.p1 -= n;		f->dot.r.p2 -= n;	}	if(p2 <= f->mark.p1){		f->mark.p1 -= n;		f->mark.p2 -= n;	}	if(f->rasp == nil)		return;	if(f==cmd && p1<cmdpt){		if(p2 <= cmdpt)			cmdpt -= n;		else			cmdpt = p1;	}	if(toterm){		if(grown){			outTsll(Hgrow, f->tag, growpos, grown);			grown = 0;		}else if(shrunk && shrinkpos!=p1 && shrinkpos!=p2){			outTsll(Hcut, f->tag, shrinkpos, shrunk);			shrunk = 0;		}		if(!shrunk || shrinkpos==p2)			shrinkpos = p1;		shrunk += n;	}	rcut(f->rasp, p1, p2);}voidraspinsert(File *f, uint p1, Rune *buf, uint n, int toterm){	Range r;	if(n == 0)		return;	if(p1 < f->dot.r.p1){		f->dot.r.p1 += n;		f->dot.r.p2 += n;	}	if(p1 < f->mark.p1){		f->mark.p1 += n;		f->mark.p2 += n;	}	if(f->rasp == nil)		return;	if(f==cmd && p1<cmdpt)		cmdpt += n;	if(toterm){		if(shrunk){			outTsll(Hcut, f->tag, shrinkpos, shrunk);			shrunk = 0;		}		if(n>GROWDATASIZE || !rterm(f->rasp, p1)){			rgrow(f->rasp, p1, n);			if(grown && growpos+grown!=p1 && growpos!=p1){				outTsll(Hgrow, f->tag, growpos, grown);				grown = 0;			}			if(!grown)				growpos = p1;			grown += n;		}else{			if(grown){				outTsll(Hgrow, f->tag, growpos, grown);				grown = 0;			}			rgrow(f->rasp, p1, n);			r = rdata(f->rasp, p1, n);			if(r.p1!=p1 || r.p2!=p1+n)				panic("rdata in toterminal");			outTsllS(Hgrowdata, f->tag, p1, n, tmprstr(buf, n));		}	}else{		rgrow(f->rasp, p1, n);		r = rdata(f->rasp, p1, n);		if(r.p1!=p1 || r.p2!=p1+n)			panic("rdata in toterminal");	}}#define	M	0x80000000L#define	P(i)	r->posnptr[i]#define	T(i)	(P(i)&M)	/* in terminal */#define	L(i)	(P(i)&~M)	/* length of this piece */voidrcut(List *r, Posn p1, Posn p2){	Posn p, x;	int i;	if(p1 == p2)		panic("rcut 0");	for(p=0,i=0; i<r->nused && p+L(i)<=p1; p+=L(i++))		;	if(i == r->nused)		panic("rcut 1");	if(p < p1){	/* chop this piece */		if(p+L(i) < p2){			x = p1-p;			p += L(i);		}else{			x = L(i)-(p2-p1);			p = p2;		}		if(T(i))			P(i) = x|M;		else			P(i) = x;		i++;	}	while(i<r->nused && p+L(i)<=p2){		p += L(i);		dellist(r, i);	}	if(p < p2){		if(i == r->nused)			panic("rcut 2");		x = L(i)-(p2-p);		if(T(i))			P(i) = x|M;		else			P(i) = x;	}	/* can we merge i and i-1 ? */	if(i>0 && i<r->nused && T(i-1)==T(i)){		x = L(i-1)+L(i);		dellist(r, i--);		if(T(i))			P(i)=x|M;		else			P(i)=x;	}}voidrgrow(List *r, Posn p1, Posn n){	Posn p;	int i;	if(n == 0)		panic("rgrow 0");	for(p=0,i=0; i<r->nused && p+L(i)<=p1; p+=L(i++))		;	if(i == r->nused){	/* stick on end of file */		if(p!=p1)			panic("rgrow 1");		if(i>0 && !T(i-1))			P(i-1)+=n;		else			inslist(r, i, n);	}else if(!T(i))		/* goes in this empty piece */		P(i)+=n;	else if(p==p1 && i>0 && !T(i-1))	/* special case; simplifies life */		P(i-1)+=n;	else if(p==p1)		inslist(r, i, n);	else{			/* must break piece in terminal */		inslist(r, i+1, (L(i)-(p1-p))|M);		inslist(r, i+1, n);		P(i) = (p1-p)|M;	}}intrterm(List *r, Posn p1){	Posn p;	int i;	for(p = 0,i = 0; i<r->nused && p+L(i)<=p1; p+=L(i++))		;	if(i==r->nused && (i==0 || !T(i-1)))		return 0;	return T(i);}Rangerdata(List *r, Posn p1, Posn n){	Posn p;	int i;	Range rg;	if(n==0)		panic("rdata 0");	for(p = 0,i = 0; i<r->nused && p+L(i)<=p1; p+=L(i++))		;	if(i==r->nused)		panic("rdata 1");	if(T(i)){		n-=L(i)-(p1-p);		if(n<=0){			rg.p1 = rg.p2 = p1;			return rg;		}		p+=L(i++);		p1 = p;	}	if(T(i) || i==r->nused)		panic("rdata 2");	if(p+L(i)<p1+n)		n = L(i)-(p1-p);	rg.p1 = p1;	rg.p2 = p1+n;	if(p!=p1){		inslist(r, i+1, L(i)-(p1-p));		P(i)=p1-p;		i++;	}	if(L(i)!=n){		inslist(r, i+1, L(i)-n);		P(i)=n;	}	P(i)|=M;	/* now i is set; can we merge? */	if(i<r->nused-1 && T(i+1)){		P(i)=(n+=L(i+1))|M;		dellist(r, i+1);	}	if(i>0 && T(i-1)){		P(i)=(n+L(i-1))|M;		dellist(r, i-1);	}	return rg;}

⌨️ 快捷键说明

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