PWB1/sys/source/s2/sed1.c
#include "sed.h"
execute(file)
{
extern fout;
register char *p1, *p2;
register c;
int i, fi;
char cflag;
if (file) {
if ((f = open(file, 0)) < 0) {
printf2("Can't open %s\n", file);
}
} else
f = 0;
ebp = ibuf;
cbp = ibuf;
if(pending) {
rep = pending;
cflag = 1;
pending = 0;
goto com;
}
for(;;) {
if((spend = gline(linebuf)) == -1) {
close(f);
return(0);
}
for(rep = ptrspace; rep->command; ) {
p1 = rep->ad1;
p2 = rep->ad2;
cflag = 0;
if(p1) {
if(rep->inar) {
cflag++;
if(*p2 == CEND) {
p1 = 0;
goto com;
}
if(*p2 == CLNUM) {
c = p2[1];
if(lnum == tlno[c]) {
rep->inar = 0;
}
if(lnum > tlno[c])
rep->inar =
cflag = 0;
goto com;
}
if(match(p2, 0) || dolflag){
rep->inar = 0;
}
} else if(*p1 == CEND) {
if(dolflag) cflag++;
goto com;
}else if(*p1 == CLNUM) {
c = p1[1];
if(lnum == tlno[c]) {
cflag++;
if(p2)
rep->inar = 1;
goto com;
}
if(lnum > tlno[c]) {
rep++;
continue;
}
} else {
if(match(p1, 0)) {
cflag++;
if(p2)
rep->inar = 1;
}
}
} else
cflag++;
com:
if(cflag) command();
if(delflag)
break;
if(jflag) {
jflag = 0;
rep = rep->re1;
} else
rep++;
}
if(!nflag && !delflag)
printf("%s\n", linebuf);
if(aptr > abuf) {
arout();
}
delflag = 0;
}
}
match(expbuf, gf)
char *expbuf;
{
register char *p1, *p2, c;
if(gf) {
if(*expbuf) return(0);
p1 = linebuf;
p2 = genbuf;
while(*p1++ = *p2++);
locs = p1 = loc2;
} else {
p1 = linebuf;
locs = 0;
}
p2 = expbuf;
if(*p2++) {
loc1 = p1;
return(advance(p1, p2));
}
/* fast check for first character */
if(*p2 == CCHR) {
c = p2[1];
do {
if(*p1 != c)
continue;
if(advance(p1, p2)) {
loc1 = p1;
return(1);
}
} while(*p1++);
return(0);
}
do {
if(advance(p1, p2)) {
loc1 = p1;
return(1);
}
} while(*p1++);
return(0);
}
advance(alp, aep)
{
register char *lp, *ep, *curlp;
char c;
char *nextep, *bbeg;
int ct;
/* printf("*lp = %c, %o\n*ep = %c, %o\n", *lp, *lp, *ep, *ep); /*DEBUG*/
lp = alp;
ep = aep;
for (;;) switch (*ep++) {
case CCHR:
if (*ep++ == *lp++)
continue;
return(0);
case CDOT:
if (*lp++)
continue;
return(0);
case CNL:
case CDOL:
if (*lp==0)
continue;
return(0);
case CEOF:
loc2 = lp;
return(1);
case CCL:
c = *lp++ & 0177;
if(ep[c>>3] & bittab[c & 07]) {
ep =+ 16;
continue;
}
return(0);
case CBRA:
braslist[*ep++] = lp;
continue;
case CKET:
braelist[*ep++] = lp;
continue;
case CBACK:
bbeg = braslist[*ep];
ct = braelist[*ep++] - bbeg;
if(ecmp(bbeg, lp, ct)) {
lp =+ ct;
continue;
}
return(0);
case CBACK|STAR:
bbeg = braslist[*ep];
ct = braelist[*ep++] - bbeg;
curlp = lp;
while(ecmp(bbeg, lp, ct))
lp =+ ct;
while(lp >= curlp) {
if(advance(lp, ep)) return(1);
lp =- ct;
}
return(0);
case CDOT|STAR:
curlp = lp;
while (*lp++);
goto star;
case CCHR|STAR:
curlp = lp;
while (*lp++ == *ep);
ep++;
goto star;
case CCL|STAR:
curlp = lp;
do {
c = *lp++ & 0177;
} while(ep[c>>3] & bittab[c & 07]);
ep =+ 16;
goto star;
star:
if(--lp == curlp) {
continue;
}
if(*ep == CCHR) {
c = ep[1];
do {
if(*lp != c)
continue;
if(advance(lp, ep))
return(1);
} while(lp-- > curlp);
return(0);
}
do {
if(lp == locs) break;
if (advance(lp, ep))
return(1);
} while (lp-- > curlp);
return(0);
default:
printf2("RE botch\n");
}
}
substitute()
{
if(match(rep->re1, 0) == 0) return(0);
sflag = 1;
dosub(rep->rhs);
if(rep->gfl) {
while(*loc2) {
if(match(rep->re1, 1) == 0) break;
dosub(rep->rhs);
}
}
return(1);
}
cclass(aset, ac, af)
{
register char *set, c;
register n;
set = aset;
if ((c = ac) == 0)
return(0);
n = *set++;
while (--n)
if (*set++ == c)
return(af);
return(!af);
}
dosub(rhsbuf)
char *rhsbuf;
{
register char *lp, *sp, *rp;
int c;
lp = linebuf;
sp = genbuf;
rp = rhsbuf;
while (lp < loc1)
*sp++ = *lp++;
while(c = *rp++) {
if (c=='&') {
sp = place(sp, loc1, loc2);
continue;
} else if (c<0 && (c =& 0177) >='1' && c < NBRA+'1') {
sp = place(sp, braslist[c-'1'], braelist[c-'1']);
continue;
}
*sp++ = c&0177;
if (sp >= &genbuf[LBSIZE])
printf2("output line too long.\n");
}
lp = loc2;
loc2 = sp + linebuf - genbuf;
while (*sp++ = *lp++)
if (sp >= &genbuf[LBSIZE]) {
printf2("Output line too long.\n");
}
lp = linebuf;
sp = genbuf;
while (*lp++ = *sp++);
spend = lp;
}
place(asp, al1, al2)
{
register char *sp, *l1, *l2;
sp = asp;
l1 = al1;
l2 = al2;
while (l1 < l2) {
*sp++ = *l1++;
if (sp >= &genbuf[LBSIZE])
printf2("Output line too long.\n");
}
return(sp);
}
command()
{
register int i;
register char *p1, *p2;
if(rep->command & GCOM)
if(match(rep->re2, 0) == 0)
return;
if(rep->command & VCOM)
if(match(rep->re2, 0) == 1)
return;
switch(rep->command & ~(GCOM | VCOM)) {
case ACOM:
*aptr++ = rep;
if(aptr >= &abuf[ABUFSIZE]) {
printf2("Too many appends after line %ld\n",
lnum);
}
*aptr = 0;
break;
case CCOM:
delflag = 1;
if(!rep->inar)
printf("%s\n", rep->re1);
break;
case DCOM:
delflag++;
break;
case CDCOM:
p1 = p2 = linebuf;
while(*p1 != '\n') {
if(*p1++ == 0) {
delflag++;
return(0);
}
}
p1++;
while(*p2++ = *p1++);
spend = p2;
jflag++;
break;
case EQCOM:
printf("%ld\n", lnum);
break;
case ICOM:
printf("%s\n", rep->re1);
break;
case JCOM:
jflag = 1;
break;
case LCOM:
break;
case NCOM:
if(!nflag)
printf("%s\n", linebuf);
if(aptr > abuf)
arout();
if((spend = gline(linebuf)) == -1) {
pending = rep;
delflag = 1;
}
break;
case CNCOM:
if(aptr > abuf)
arout();
spend[-1] = '\n';
if((spend = gline(spend)) == -1) {
pending = rep;
delflag = 1;
}
break;
case PCOM:
if(nflag)
printf("%s\n", linebuf);
break;
case CPCOM:
if(nflag) {
cpcom:
p1 = linebuf;
while(*p1 != '\n' && *p1 != '\0')
p1++;
i = *p1;
*p1 = '\0';
printf("%s\n", linebuf);
*p1 = i;
}
break;
case QCOM:
if(!nflag)
printf("%s\n", linebuf);
if(aptr > abuf) arout();
flush();
exit(0);
case RCOM:
*aptr++ = rep;
if(aptr >= &abuf[ABUFSIZE])
printf2("Too many reads after line%ld\n",
lnum);
*aptr = 0;
break;
case SCOM:
i = substitute();
if(i && nflag && rep->pfl)
if(rep->pfl == 1)
printf("%s\n", linebuf);
else
goto cpcom;
if(i && rep->fcode)
goto wcom;
break;
case TCOM:
if(sflag == 0) break;
sflag = 0;
jflag = 1;
break;
wcom:
case WCOM:
i = 0;
while(linebuf[i++]);
linebuf[--i] = '\n';
write(rep->fcode, linebuf, i + 1);
linebuf[i] = '\0';
break;
}
}
gline(address)
char *address;
{
register char *p1, *p2;
register c;
p1 = address;
p2 = cbp;
for (;;) {
if (p2 >= ebp) {
if ((c = read(f, ibuf, 512)) <= 0) {
return(-1);
}
p2 = ibuf;
ebp = ibuf+c;
}
if ((c = *p2++) == '\n') {
if(p2 >= ebp) {
if((c = read(f, ibuf, 512)) <= 0) {
close(f);
if(eargc == 0)
dolflag = 1;
}
p2 = ibuf;
ebp = ibuf + c;
}
break;
}
if(c)
if(p1 < lbend)
*p1++ = c;
}
lnum++;
*p1++ = 0;
cbp = p2;
return(p1);
}
ecmp(a, b, count)
char *a, *b;
{
while(count--)
if(*a++ != *b++) return(0);
return(1);
}
arout()
{
int i, fi;
aptr = abuf - 1;
while(*++aptr) {
if(((*aptr)->command & ~(GCOM|VCOM))==ACOM)
printf("%s\n", (*aptr)->re1);
else {
if((fi = open((*aptr)->re1, 0))
< 0)
continue;
flush();
while((i = read(fi, genbuf, 512))
== 512)
write(fout, genbuf, 512);
if(i) write(fout, genbuf, i);
close(fi);
}
}
aptr = abuf;
*aptr = 0;
}