예제 #1
0
파일: buffer.c 프로젝트: 4ad/sam
void
Binsert(Buffer *b, String *s, Posn p0)
{
	if(b->c2>b->disc->nrunes || b->c1>b->disc->nrunes)
		panic("binsert cache");
	if(p0<0)
		panic("Binsert p0<0");
	if(s->n == 0)
		return;
	if(incache(b, p0, p0) && b->cache.n+s->n<=STRSIZE){
		Strinsert(&b->cache, s, p0-b->c1);
		b->dirty = TRUE;
		if(b->cache.n > BLOCKSIZE*2){
			b->nrunes += s->n;
			Bflush(b);
			/* try to leave some cache around p0 */
			if(p0 >= b->c1+BLOCKSIZE){
				/* first BLOCKSIZE can go */
				Strdelete(&b->cache, 0, BLOCKSIZE);
				b->c1 += BLOCKSIZE;
			}else if(p0 <= b->c2-BLOCKSIZE){
				/* last BLOCKSIZE can go */
				b->cache.n -= BLOCKSIZE;
				b->c2 -= BLOCKSIZE;
			}else{
				/* too hard; negate the cache and pick up next time */
				Strzero(&b->cache);
				b->c1 = b->c2 = 0;
			}
			return;
		}
	}else{
		Bflush(b);
		if(s->n >= BLOCKSIZE/2){
			b->cache.n = 0;
			b->c1 = b->c2 = 0;
			Dinsert(b->disc, s->s, s->n, p0);
		}else{
			int m;
			Posn minp;
			if(b->nrunes-p0 > BLOCKSIZE/2)
				m = BLOCKSIZE/2;
			else
				m = b->nrunes-p0;
			minp = p0-BLOCKSIZE/2;
			if(minp < 0)
				minp = 0;
			m += p0-minp;
			Strinsure(&b->cache, m);
			if(Dread(b->disc, b->cache.s, m, minp)!=m)
				panic("Bread");
			b->cache.n = m;
			b->c1 = minp;
			b->c2 = minp+m;
			Strinsert(&b->cache, s, p0-b->c1);
			b->dirty = TRUE;
		}
	}
	b->nrunes += s->n;
}
예제 #2
0
파일: cmd.c 프로젝트: CoryXie/nix-os
String*				/* BUGGERED */
getregexp(int delim)
{
	String *r = newre();
	int c;

	for(Strzero(&genstr); ; Straddc(&genstr, c))
		if((c = getch())=='\\'){
			if(nextc()==delim)
				c = getch();
			else if(nextc()=='\\'){
				Straddc(&genstr, c);
				c = getch();
			}
		}else if(c==delim || c=='\n')
			break;
	if(c!=delim && c)
		ungetch();
	if(genstr.n > 0){
		patset = TRUE;
		Strduplstr(&lastpat, &genstr);
		Straddc(&lastpat, '\0');
	}
	if(lastpat.n <= 1)
		error(Epattern);
	Strduplstr(r, &lastpat);
	return r;
}
예제 #3
0
파일: xec.c 프로젝트: 00001/plan9port
int
s_cmd(File *f, Cmd *cp)
{
	int i, j, c, n;
	Posn p1, op, didsub = 0, delta = 0;

	n = cp->num;
	op= -1;
	compile(cp->re);
	for(p1 = addr.r.p1; p1<=addr.r.p2 && execute(f, p1, addr.r.p2); ){
		if(sel.p[0].p1==sel.p[0].p2){	/* empty match? */
			if(sel.p[0].p1==op){
				p1++;
				continue;
			}
			p1 = sel.p[0].p2+1;
		}else
			p1 = sel.p[0].p2;
		op = sel.p[0].p2;
		if(--n>0)
			continue;
		Strzero(&genstr);
		for(i = 0; i<cp->ctext->n; i++)
			if((c = cp->ctext->s[i])=='\\' && i<cp->ctext->n-1){
				c = cp->ctext->s[++i];
				if('1'<=c && c<='9') {
					j = c-'0';
					if(sel.p[j].p2-sel.p[j].p1>BLOCKSIZE)
						error(Elongtag);
					bufread(&f->b, sel.p[j].p1, genbuf, sel.p[j].p2-sel.p[j].p1);
					Strinsert(&genstr, tmprstr(genbuf, (sel.p[j].p2-sel.p[j].p1)), genstr.n);
				}else
				 	Straddc(&genstr, c);
			}else if(c!='&')
				Straddc(&genstr, c);
			else{
				if(sel.p[0].p2-sel.p[0].p1>BLOCKSIZE)
					error(Elongrhs);
				bufread(&f->b, sel.p[0].p1, genbuf, sel.p[0].p2-sel.p[0].p1);
				Strinsert(&genstr,
					tmprstr(genbuf, (int)(sel.p[0].p2-sel.p[0].p1)),
					genstr.n);
			}
		if(sel.p[0].p1!=sel.p[0].p2){
			logdelete(f, sel.p[0].p1, sel.p[0].p2);
			delta-=sel.p[0].p2-sel.p[0].p1;
		}
		if(genstr.n){
			loginsert(f, sel.p[0].p2, genstr.s, genstr.n);
			delta+=genstr.n;
		}
		didsub = 1;
		if(!cp->flag)
			break;
	}
	if(!didsub && nest==0)
		error(Enosub);
	f->ndot.r.p1 = addr.r.p1, f->ndot.r.p2 = addr.r.p2+delta;
	return TRUE;
}
예제 #4
0
파일: buffer.c 프로젝트: 4ad/sam
void
Bclean(Buffer *b)
{
	if(b->dirty){
		Bflush(b);
		b->c1 = b->c2 = 0;
		Strzero(&b->cache);
	}
}