|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 10636 (0x298c)
Types: TextFile
Notes: UNIX file
Names: »sed3.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦f4b8d8c84⟧ UNIX Filesystem
└─⟦this⟧ »cmd/sed/sed3.c«
/*
* A stream editor.
* Execution.
*/
#include <stdio.h>
#include <ctype.h>
#include "sed.h"
char *match();
/*
* Execute the compiled commands on each line of the input file.
*/
process()
{
FILE *fp;
QCL **qcrpp, *qcrp, *lqp, *qp;
int n, subflag;
char com;
register COM *cp;
register char *bp1, *bp2;
subflag = 0;
cp = NULL;
com = '\0';
lno = 0;
qcrpp = &qcrp;
dolflag = 0;
pattlen = 0;
holdlen = 0;
pattbuf[0] = '\0';
holdbuf[0] = '\0';
for (;;) {
while (cp == NULL) {
if (com != 'D') {
if (nflag==0 && pattlen!=0)
printf("%s\n", pattbuf);
pattlen = 0;
}
*qcrpp = NULL;
qp = qcrp;
while (qp != NULL) {
cp = qp->q_comp;
lqp = qp;
qp = qp->q_next;
free(lqp);
switch (cp->c_name) {
case 'a':
printf("%s\n", cp->c_p.p_buf);
break;
case 'r':
bp1 = cp->c_p.p_buf;
if ((fp=fopen(bp1, "r")) == NULL) {
printe("Cannot open %s", bp1);
continue;
}
while (fgets(linebuf, LHPSIZE, fp))
printf("%s", linebuf);
fclose(fp);
}
}
if (com == 'q')
exit(0);
if (com != 'D') {
if (readpat() == 0)
exit(0);
}
cp = comp;
qcrpp = &qcrp;
com = '\0';
}
if (admitr(cp) == 0) {
cp = cp->c_next;
continue;
}
switch (com=cp->c_name) {
case '=':
printf("%d\n", lno);
break;
case '{':
cp = cp->c_p.p_com;
continue;
case '}':
break;
case 'a':
*qcrpp = qp = (QCL *)salloc(sizeof (QCL));
qp->q_comp = cp;
qcrpp = &qp->q_next;
break;
case 'b':
cp = cp->c_p.p_lab->l_comp;
continue;
case 'c':
if (cp->c_iran == 0)
printf("%s\n", cp->c_p.p_buf);
case 'd':
pattlen = 0;
cp = NULL;
continue;
case 'D':
bp1 = bp2 = pattbuf;
pattlen = 0;
while (*bp2 != '\0') {
if (*bp2++ == '\n') {
pattlen = 1;
break;
}
}
while (*bp1++=*bp2++)
pattlen++;
if (pattlen == 0)
com = 'd';
cp = NULL;
continue;
case 'g':
n = pattlen = holdlen;
bp1 = pattbuf;
bp2 = holdbuf;
while (n--)
*bp1++ = *bp2++;
break;
case 'G':
if (pattlen+holdlen > LHPSIZE) {
printe("Pattern buffer overflow");
break;
}
bp1 = &pattbuf[pattlen];
bp2 = &holdbuf[0];
if (pattlen != 0)
bp1[-1] = '\n';
pattlen += n = holdlen;
while (n--)
*bp1++ = *bp2++;
break;
case 'h':
n = holdlen = pattlen;
bp1 = holdbuf;
bp2 = pattbuf;
while (n--)
*bp1++ = *bp2++;
break;
case 'H':
if (holdlen+pattlen > LHPSIZE) {
printe("Hold buffer overflow");
break;
}
bp1 = &holdbuf[holdlen];
bp2 = &pattbuf[0];
if (holdlen != 0)
bp1[-1] = '\n';
holdlen += n = pattlen;
while (n--)
*bp1++ = *bp2++;
break;
case 'i':
printf("%s\n", cp->c_p.p_buf);
break;
case 'l':
execlis();
break;
case 'n':
if (pattlen != 0)
printf("%s\n", pattbuf);
pattlen = 0;
case 'N':
if (readpat() == 0) {
com = 'q';
cp = NULL;
continue;
}
break;
case 'p':
if (pattlen != 0)
printf("%s\n", pattbuf);
break;
case 'P':
bp1 = pattbuf;
while (*bp1!='\0' && *bp1!='\n')
putchar(*bp1++);
putchar('\n');
break;
case 'q':
cp = NULL;
continue;
case 'r':
*qcrpp = qp = (QCL *)salloc(sizeof (QCL));
qp->q_comp = cp;
qcrpp = &qp->q_next;
break;
case 's':
subflag = execsub(cp->c_p.p_sub);
break;
case 't':
if (subflag) {
cp = cp->c_p.p_lab->l_comp;
continue;
}
break;
case 'w':
fprintf(cp->c_p.p_fil->f_filp, "%s\n", pattbuf);
break;
case 'x':
n = pattlen;
bp1 = linebuf;
bp2 = pattbuf;
while (n--)
*bp1++ = *bp2++;
n = holdlen;
bp1 = pattbuf;
bp2 = holdbuf;
while (n--)
*bp1++ = *bp2++;
n = pattlen;
bp1 = holdbuf;
bp2 = linebuf;
while (n--)
*bp1++ = *bp2++;
n = pattlen;
pattlen = holdlen;
holdlen = n;
break;
case 'y':
bp2 = cp->c_p.p_buf;
for (bp1=pattbuf; *bp1; bp1++)
*bp1 = bp2[*bp1];
break;
}
cp = cp->c_next;
}
}
/*
* See if a the current line is within a given line range.
*/
admitr(cp)
register COM *cp;
{
register int n;
switch (cp->c_nadd) {
case 0:
cp->c_iran = 0;
n = 1;
break;
case 1:
cp->c_iran = 0;
n = admits(&cp->c_a[0]);
break;
case 2:
if (cp->c_iran == 0) {
n = cp->c_iran = admits(&cp->c_a[0]);
} else {
if (admits(&cp->c_a[1]) != 0)
cp->c_iran = 0;
n = 1;
}
}
return (cp->c_notf!=n);
}
/*
* See if the current line matches the given line address.
*/
admits(ap)
register ADD *ap;
{
if (ap->a_lno == 0)
return (execute(ap->a_pat));
if (ap->a_lno == HUGE)
return (dolflag);
return (ap->a_lno-1 == lno);
}
/*
* Append a line into the pattern buffer. The current line number
* is incremented. If the line overflows, an error message is
* printed out.
*/
readpat()
{
static int lastc = '\0';
register int c, n;
register char *cp;
if (dolflag)
return (0);
cp = &pattbuf[pattlen];
if (pattlen != 0)
cp[-1] = '\n';
n = &pattbuf[LHPSIZE-1] - cp;
if (lastc == '\0')
c = getp();
else {
c = lastc;
lastc = '\0';
}
while (c!='\n' && c!=EOF) {
if (n-- <= 0) {
fprintf(stderr, "%d: Line too long\n", lno);
exit(1);
}
*cp++ = c;
c = getp();
}
*cp++ = '\0';
pattlen = cp - pattbuf;
lno++;
if (c==EOF || (c=getp())==EOF)
dolflag++;
else
lastc = c;
return (1);
}
/*
* Get a character.
*/
getp()
{
ECL *ep;
register int c;
while (ifp==NULL || (c=getc(ifp))==EOF) {
if (ifp != NULL)
fclose(ifp);
if ((ep=eclp) == NULL)
return (EOF);
if ((ifp=fopen(ep->e_argp, "r")) == NULL) {
fprintf(stderr, "Cannot open %s\n", ep->e_argp);
exit(1);
}
eclp = ep->e_next;
free(ep);
}
return (c);
}
/*
* Print out the contents of the pattern buffer in an unambigous
* form. All non-printing characters are escaped.
*/
execlis()
{
register int n;
register char *cp;
n = 0;
for (cp=pattbuf; *cp; cp++) {
if (n++ >= 72) {
n = 0;
printf("\\\n");
}
switch (*cp) {
case '\b':
printf("-\b<");
continue;
case '\t':
printf("-\b>");
continue;
case '\\':
printf("\\\\");
continue;
default:
if (isascii(*cp) && !iscntrl(*cp)) {
putchar(*cp);
continue;
}
printf("\\%03o", *cp);
n += 3;
}
}
putchar('\n');
}
/*
* Execute substitute command.
*/
execsub(sp)
SUB *sp;
{
register char *np;
register char *pp;
register int n;
register char *lp;
register char *rp;
register int nth;
register int len;
register int subflag;
register int subnths;
subflag = 0;
subnths = sp->s_nth;
for (n=0; n<1+NBRC; n++) {
brcl[n].b_bp = NULL;
brcl[n].b_ep = NULL;
}
brcl[0].b_ep = pattbuf;
lp = pattbuf;
np = linebuf;
nth = 0;
for (;;) {
pp = sp->s_pat;
if (*pp == CSSOL) {
if (lp != pattbuf)
break;
pp++;
}
if ((pp=match(lp, pp)) == NULL) {
if (*lp++ == '\0')
break;
continue;
}
nth++;
if (subnths) {
if (nth < subnths) {
lp = pp;
continue;
}
if (nth > subnths)
goto done;
}
subflag = 1;
len = pp - lp;
brcl[0].b_bp = lp;
lp = pp;
pp = brcl[0].b_ep;
brcl[0].b_ep = lp;
n = brcl[0].b_bp - pp;
if (np+n >= &linebuf[LHPSIZE-1])
goto ovf;
while (n--)
*np++ = *pp++;
rp = sp->s_rep;
while (*rp) {
if (np >= &linebuf[LHPSIZE-4])
goto ovf;
if (*rp != '\\') {
*np++ = *rp++;
continue;
}
if (*++rp == '\\') {
*np++ = *rp++;
continue;
}
n = *rp++ - '0';
if ((pp=brcl[n].b_bp) == NULL)
continue;
n = brcl[n].b_ep-pp;
if (np+n >= &linebuf[LHPSIZE-4])
goto ovf;
while (n--)
*np++ = *pp++;
}
if (*lp == '\0')
break;
if (len == 0)
lp++;
if (subnths!=0 && nth==subnths)
break;
}
done:
pp = brcl[0].b_ep;
while (*pp) {
if (np >= &linebuf[LHPSIZE-1])
goto ovf;
*np++ = *pp++;
}
*np++ = '\0';
pattlen = n = np - linebuf;
pp = pattbuf;
np = linebuf;
do {
*pp++ = *np++;
} while (--n);
if (subflag) {
if (sp->s_cop)
printf("%s\n", pattbuf);
if (sp->s_fil)
fprintf(sp->s_fil->f_filp, "%s\n", pattbuf);
}
return (subflag);
ovf:
printc("Line buffer overflow");
return (0);
}
/*
* See if the compiled pattern `pat' matches the line in pattbuf.
*/
execute(pat)
char *pat;
{
register int i;
register char *lp, *ep;
for (i=0; i<1+NBRC; i++) {
brcl[i].b_bp = NULL;
brcl[i].b_ep = NULL;
}
if (pat[0] == CSSOL)
ep = match(lp=pattbuf, &pat[1]);
else {
ep = NULL;
lp = pattbuf;
do {
if (ep=match(lp, pat))
break;
} while (*lp++);
}
if (ep) {
brcl[0].b_bp = lp;
brcl[0].b_ep = ep;
}
return (ep ? 1 : 0);
}
/*
* Given a pointer to a compiled expression, `cp', and a pointer to
* a line, `lp', return 1 if the expression matches, else 0.
*/
char *
match(lp, cp)
register char *lp, *cp;
{
register int n;
char *llp, *lcp;
for (;;) {
switch (*cp++) {
case CSNUL:
return (lp);
case CSEOL:
if (*lp)
return (NULL);
return (lp);
case CSOPR:
brcl[*cp++].b_bp = lp;
continue;
case CSCPR:
brcl[*cp++].b_ep = lp;
continue;
case CSBRN:
n = *cp++;
lcp = cp;
cp = brcl[n].b_bp;
n = brcl[n].b_ep - cp;
if (n > LHPSIZE)
return (NULL);
while (n-- > 0)
if (*lp++ != *cp++)
return (NULL);
cp = lcp;
continue;
case CSDOT:
if (*lp++ == '\0')
return (NULL);
continue;
case CMDOT:
llp = lp;
while (*lp)
lp++;
goto star;
case CSCHR:
if (*cp++ != *lp++)
return (NULL);
continue;
case CMCHR:
llp = lp;
while (*cp == *lp)
lp++;
cp++;
goto star;
case CSSCC:
if (*cp++ == tolower(*lp++))
continue;
return (NULL);
case CMSCC:
llp = lp;
while (*cp == tolower(*lp++))
;
cp++;
goto star;
case CSCCL:
n = *cp++;
while (*cp++ != *lp)
if (--n == 0)
return (NULL);
lp++;
cp += n-1;
continue;
case CMCCL:
llp = lp;
lcp = cp;
while (*lp) {
cp = lcp;
n = *cp++;
while (*cp++ != *lp)
if (--n == 0)
goto star;
lp++;
}
cp = lcp + *lcp + 1;
goto star;
case CSNCL:
if (*lp == '\0')
return (NULL);
n = *cp++;
while (n--)
if (*cp++ == *lp)
return (NULL);
lp++;
continue;
case CMNCL:
llp = lp;
lcp = cp;
while (*lp) {
cp = lcp;
n = *cp++;
while (n--) {
if (*cp++ == *lp) {
cp = lcp + *lcp + 1;
goto star;
}
}
lp++;
}
cp = lcp + *lcp + 1;
star:
do {
if (lcp=match(lp, cp))
return (lcp);
} while (--lp >= llp);
return (NULL);
}
}
}
/*
* Print out an execution error message.
*/
printe(s)
{
fprintf(stderr, "%r", &s);
putc('\n', stderr);
}