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; }
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; }
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; }
void Bclean(Buffer *b) { if(b->dirty){ Bflush(b); b->c1 = b->c2 = 0; Strzero(&b->cache); } }