Annotation of coherent/d/bin/sed/sed3.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * A stream editor.
                      3:  * Execution.
                      4:  */
                      5: #include <stdio.h>
                      6: #include <ctype.h>
                      7: #include "sed.h"
                      8: 
                      9: char   *match();
                     10: 
                     11: /*
                     12:  * Execute the compiled commands on each line of the input file.
                     13:  */
                     14: process()
                     15: {
                     16:        FILE *fp;
                     17:        QCL **qcrpp, *qcrp, *lqp, *qp;
                     18:        int n, subflag;
                     19:        char com;
                     20:        register COM *cp;
                     21:        register char *bp1, *bp2;
                     22: 
                     23:        subflag = 0;
                     24:        cp = NULL;
                     25:        com = '\0';
                     26:        lno = 0;
                     27:        qcrpp = &qcrp;
                     28:        dolflag = 0;
                     29:        pattlen = 0;
                     30:        holdlen = 0;
                     31:        pattbuf[0] = '\0';
                     32:        holdbuf[0] = '\0';
                     33:        for (;;) {
                     34:                while (cp == NULL) {
                     35:                        if (com != 'D') {
                     36:                                if (nflag==0 && pattlen!=0)
                     37:                                        printf("%s\n", pattbuf);
                     38:                                pattlen = 0;
                     39:                        }
                     40:                        *qcrpp = NULL;
                     41:                        qp = qcrp;
                     42:                        while (qp != NULL) {
                     43:                                cp = qp->q_comp;
                     44:                                lqp = qp;
                     45:                                qp = qp->q_next;
                     46:                                free(lqp);
                     47:                                switch (cp->c_name) {
                     48:                                case 'a':
                     49:                                        printf("%s\n", cp->c_p.p_buf);
                     50:                                        break;
                     51:                                case 'r':
                     52:                                        bp1 = cp->c_p.p_buf;
                     53:                                        if ((fp=fopen(bp1, "r")) == NULL) {
                     54:                                                printe("Cannot open %s", bp1);
                     55:                                                continue;
                     56:                                        }
                     57:                                        while (fgets(linebuf, LHPSIZE, fp))
                     58:                                                printf("%s", linebuf);
                     59:                                        fclose(fp);
                     60:                                }
                     61:                        }
                     62:                        if (com == 'q')
                     63:                                exit(0);
                     64:                        if (com != 'D') {
                     65:                                if (readpat() == 0)
                     66:                                        exit(0);
                     67:                        }
                     68:                        cp = comp;
                     69:                        qcrpp = &qcrp;
                     70:                        com = '\0';
                     71:                }
                     72:                if (admitr(cp) == 0) {
                     73:                        cp = cp->c_next;
                     74:                        continue;
                     75:                }
                     76:                switch (com=cp->c_name) {
                     77:                case '=':
                     78:                        printf("%d\n", lno);
                     79:                        break;
                     80:                case '{':
                     81:                        cp = cp->c_p.p_com;
                     82:                        continue;
                     83:                case '}':
                     84:                        break;
                     85:                case 'a':
                     86:                        *qcrpp = qp = (QCL *)salloc(sizeof (QCL));
                     87:                        qp->q_comp = cp;
                     88:                        qcrpp = &qp->q_next;
                     89:                        break;
                     90:                case 'b':
                     91:                        cp = cp->c_p.p_lab->l_comp;
                     92:                        continue;
                     93:                case 'c':
                     94:                        if (cp->c_iran == 0)
                     95:                                printf("%s\n", cp->c_p.p_buf);
                     96:                case 'd':
                     97:                        pattlen = 0;
                     98:                        cp = NULL;
                     99:                        continue;
                    100:                case 'D':
                    101:                        bp1 = bp2 = pattbuf;
                    102:                        pattlen = 0;
                    103:                        while (*bp2 != '\0') {
                    104:                                if (*bp2++ == '\n') {
                    105:                                        pattlen = 1;
                    106:                                        break;
                    107:                                }
                    108:                        }
                    109:                        while (*bp1++=*bp2++)
                    110:                                pattlen++;
                    111:                        if (pattlen == 0)
                    112:                                com = 'd';
                    113:                        cp = NULL;
                    114:                        continue;
                    115:                case 'g':
                    116:                        n = pattlen = holdlen;
                    117:                        bp1 = pattbuf;
                    118:                        bp2 = holdbuf;
                    119:                        while (n--)
                    120:                                *bp1++ = *bp2++;
                    121:                        break;
                    122:                case 'G':
                    123:                        if (pattlen+holdlen > LHPSIZE) {
                    124:                                printe("Pattern buffer overflow");
                    125:                                break;
                    126:                        }
                    127:                        bp1 = &pattbuf[pattlen];
                    128:                        bp2 = &holdbuf[0];
                    129:                        if (pattlen != 0)
                    130:                                bp1[-1] = '\n';
                    131:                        pattlen += n = holdlen;
                    132:                        while (n--)
                    133:                                *bp1++ = *bp2++;
                    134:                        break;
                    135:                case 'h':
                    136:                        n = holdlen = pattlen;
                    137:                        bp1 = holdbuf;
                    138:                        bp2 = pattbuf;
                    139:                        while (n--)
                    140:                                *bp1++ = *bp2++;
                    141:                        break;
                    142:                case 'H':
                    143:                        if (holdlen+pattlen > LHPSIZE) {
                    144:                                printe("Hold buffer overflow");
                    145:                                break;
                    146:                        }
                    147:                        bp1 = &holdbuf[holdlen];
                    148:                        bp2 = &pattbuf[0];
                    149:                        if (holdlen != 0)
                    150:                                bp1[-1] = '\n';
                    151:                        holdlen += n = pattlen;
                    152:                        while (n--)
                    153:                                *bp1++ = *bp2++;
                    154:                        break;
                    155:                case 'i':
                    156:                        printf("%s\n", cp->c_p.p_buf);
                    157:                        break;
                    158:                case 'l':
                    159:                        execlis();
                    160:                        break;
                    161:                case 'n':
                    162:                        if (pattlen != 0)
                    163:                                printf("%s\n", pattbuf);
                    164:                        pattlen = 0;
                    165:                case 'N':
                    166:                        if (readpat() == 0) {
                    167:                                com = 'q';
                    168:                                cp = NULL;
                    169:                                continue;
                    170:                        }
                    171:                        break;
                    172:                case 'p':
                    173:                        if (pattlen != 0)
                    174:                                printf("%s\n", pattbuf);
                    175:                        break;
                    176:                case 'P':
                    177:                        bp1 = pattbuf;
                    178:                        while (*bp1!='\0' && *bp1!='\n')
                    179:                                putchar(*bp1++);
                    180:                        putchar('\n');
                    181:                        break;
                    182:                case 'q':
                    183:                        cp = NULL;
                    184:                        continue;
                    185:                case 'r':
                    186:                        *qcrpp = qp = (QCL *)salloc(sizeof (QCL));
                    187:                        qp->q_comp = cp;
                    188:                        qcrpp = &qp->q_next;
                    189:                        break;
                    190:                case 's':
                    191:                        subflag = execsub(cp->c_p.p_sub);
                    192:                        break;
                    193:                case 't':
                    194:                        if (subflag) {
                    195:                                cp = cp->c_p.p_lab->l_comp;
                    196:                                continue;
                    197:                        }
                    198:                        break;
                    199:                case 'w':
                    200:                        fprintf(cp->c_p.p_fil->f_filp, "%s\n", pattbuf);
                    201:                        break;
                    202:                case 'x':
                    203:                        n = pattlen;
                    204:                        bp1 = linebuf;
                    205:                        bp2 = pattbuf;
                    206:                        while (n--)
                    207:                                *bp1++ = *bp2++;
                    208:                        n = holdlen;
                    209:                        bp1 = pattbuf;
                    210:                        bp2 = holdbuf;
                    211:                        while (n--)
                    212:                                *bp1++ = *bp2++;
                    213:                        n = pattlen;
                    214:                        bp1 = holdbuf;
                    215:                        bp2 = linebuf;
                    216:                        while (n--)
                    217:                                *bp1++ = *bp2++;
                    218:                        n = pattlen;
                    219:                        pattlen = holdlen;
                    220:                        holdlen = n;
                    221:                        break;
                    222:                case 'y':
                    223:                        bp2 = cp->c_p.p_buf;
                    224:                        for (bp1=pattbuf; *bp1; bp1++)
                    225:                                *bp1 = bp2[*bp1];
                    226:                        break;
                    227:                }
                    228:                cp = cp->c_next;
                    229:        }
                    230: }
                    231: 
                    232: /*
                    233:  * See if a the current line is within a given line range.
                    234:  */
                    235: admitr(cp)
                    236: register COM *cp;
                    237: {
                    238:        register int n;
                    239: 
                    240:        switch (cp->c_nadd) {
                    241:        case 0:
                    242:                cp->c_iran = 0;
                    243:                n = 1;
                    244:                break;
                    245:        case 1:
                    246:                cp->c_iran = 0;
                    247:                n = admits(&cp->c_a[0]);
                    248:                break;
                    249:        case 2:
                    250:                if (cp->c_iran == 0) {
                    251:                        n = cp->c_iran = admits(&cp->c_a[0]);
                    252:                } else {
                    253:                        if (admits(&cp->c_a[1]) != 0)
                    254:                                cp->c_iran = 0;
                    255:                        n = 1;
                    256:                }
                    257:        }
                    258:        return (cp->c_notf!=n);
                    259: }
                    260: 
                    261: /*
                    262:  * See if the current line matches the given line address.
                    263:  */
                    264: admits(ap)
                    265: register ADD *ap;
                    266: {
                    267:        if (ap->a_lno == 0)
                    268:                return (execute(ap->a_pat));
                    269:        if (ap->a_lno == HUGE)
                    270:                return (dolflag);
                    271:        return (ap->a_lno-1 == lno);
                    272: }
                    273: 
                    274: /*
                    275:  * Append a line into the pattern buffer.  The current line number
                    276:  * is incremented.  If the line overflows, an error message is
                    277:  * printed out.
                    278:  */
                    279: readpat()
                    280: {
                    281:        static int lastc = '\0';
                    282:        register int c, n;
                    283:        register char *cp;
                    284: 
                    285:        if (dolflag)
                    286:                return (0);
                    287:        cp = &pattbuf[pattlen];
                    288:        if (pattlen != 0)
                    289:                cp[-1] = '\n';
                    290:        n = &pattbuf[LHPSIZE-1] - cp;
                    291:        if (lastc == '\0')
                    292:                c = getp();
                    293:        else {
                    294:                c = lastc;
                    295:                lastc = '\0';
                    296:        }
                    297:        while (c!='\n' && c!=EOF) {
                    298:                if (n-- <= 0) {
                    299:                        fprintf(stderr, "%d: Line too long\n", lno);
                    300:                        exit(1);
                    301:                }
                    302:                *cp++ = c;
                    303:                c = getp();
                    304:        }
                    305:        *cp++ = '\0';
                    306:        pattlen = cp - pattbuf;
                    307:        lno++;
                    308:        if (c==EOF || (c=getp())==EOF)
                    309:                dolflag++;
                    310:        else
                    311:                lastc = c;
                    312:        return (1);
                    313: }
                    314: 
                    315: /*
                    316:  * Get a character.
                    317:  */
                    318: getp()
                    319: {
                    320:        ECL *ep;
                    321:        register int c;
                    322: 
                    323:        while (ifp==NULL || (c=getc(ifp))==EOF) {
                    324:                if (ifp != NULL)
                    325:                        fclose(ifp);
                    326:                if ((ep=eclp) == NULL)
                    327:                        return (EOF);
                    328:                if ((ifp=fopen(ep->e_argp, "r")) == NULL) {
                    329:                        fprintf(stderr, "Cannot open %s\n", ep->e_argp);
                    330:                        exit(1);
                    331:                }
                    332:                eclp = ep->e_next;
                    333:                free(ep);
                    334:        }
                    335:        return (c);
                    336: }
                    337: 
                    338: /*
                    339:  * Print out the contents of the pattern buffer in an unambigous
                    340:  * form.  All non-printing characters are escaped.
                    341:  */
                    342: execlis()
                    343: {
                    344:        register int n;
                    345:        register char *cp;
                    346: 
                    347:        n = 0;
                    348:        for (cp=pattbuf; *cp; cp++) {
                    349:                if (n++ >= 72) {
                    350:                        n = 0;
                    351:                        printf("\\\n");
                    352:                }
                    353:                switch (*cp) {
                    354:                case '\b':
                    355:                        printf("-\b<");
                    356:                        continue;
                    357:                case '\t':
                    358:                        printf("-\b>");
                    359:                        continue;
                    360:                case '\\':
                    361:                        printf("\\\\");
                    362:                        continue;
                    363:                default:
                    364:                        if (isascii(*cp) && !iscntrl(*cp)) {
                    365:                                putchar(*cp);
                    366:                                continue;
                    367:                        }
                    368:                        printf("\\%03o", *cp);
                    369:                        n += 3;
                    370:                }
                    371:        }
                    372:        putchar('\n');
                    373: }
                    374: 
                    375: /*
                    376:  * Execute substitute command.
                    377:  */
                    378: execsub(sp)
                    379: SUB *sp;
                    380: {
                    381:        register char *np;
                    382:        register char *pp;
                    383:        register int n;
                    384:        register char *lp;
                    385:        register char *rp;
                    386:        register int nth;
                    387:        register int len;
                    388:        register int subflag;
                    389:        register int subnths;
                    390: 
                    391:        subflag = 0;
                    392:        subnths = sp->s_nth;
                    393:        for (n=0; n<1+NBRC; n++) {
                    394:                brcl[n].b_bp = NULL;
                    395:                brcl[n].b_ep = NULL;
                    396:        }
                    397:        brcl[0].b_ep = pattbuf;
                    398:        lp = pattbuf;
                    399:        np = linebuf;
                    400:        nth = 0;
                    401:        for (;;) {
                    402:                pp = sp->s_pat;
                    403:                if (*pp == CSSOL) {
                    404:                        if (lp != pattbuf)
                    405:                                break;
                    406:                        pp++;
                    407:                }
                    408:                if ((pp=match(lp, pp)) == NULL) {
                    409:                        if (*lp++ == '\0')
                    410:                                break;
                    411:                        continue;
                    412:                }
                    413:                nth++;
                    414:                if (subnths) {
                    415:                        if (nth < subnths) {
                    416:                                lp = pp;
                    417:                                continue;
                    418:                        }
                    419:                        if (nth > subnths)
                    420:                                goto done;
                    421:                }
                    422:                subflag = 1;
                    423:                len = pp - lp;
                    424:                brcl[0].b_bp = lp;
                    425:                lp = pp;
                    426:                pp = brcl[0].b_ep;
                    427:                brcl[0].b_ep = lp;
                    428:                n = brcl[0].b_bp - pp;
                    429:                if (np+n >= &linebuf[LHPSIZE-1])
                    430:                        goto ovf;
                    431:                while (n--)
                    432:                        *np++ = *pp++;
                    433:                rp = sp->s_rep;
                    434:                while (*rp) {
                    435:                        if (np >= &linebuf[LHPSIZE-4])
                    436:                                goto ovf;
                    437:                        if (*rp != '\\') {
                    438:                                *np++ = *rp++;
                    439:                                continue;
                    440:                        }
                    441:                        if (*++rp == '\\') {
                    442:                                *np++ = *rp++;
                    443:                                continue;
                    444:                        }
                    445:                        n = *rp++ - '0';
                    446:                        if ((pp=brcl[n].b_bp) == NULL)
                    447:                                continue;
                    448:                        n = brcl[n].b_ep-pp;
                    449:                        if (np+n >= &linebuf[LHPSIZE-4])
                    450:                                goto ovf;
                    451:                        while (n--)
                    452:                                *np++ = *pp++;
                    453:                }
                    454:                if (*lp == '\0')
                    455:                        break;
                    456:                if (len == 0)
                    457:                        lp++;
                    458:                if (subnths!=0 && nth==subnths)
                    459:                        break;
                    460:        }
                    461: done:
                    462:        pp = brcl[0].b_ep;
                    463:        while (*pp) {
                    464:                if (np >= &linebuf[LHPSIZE-1])
                    465:                        goto ovf;
                    466:                *np++ = *pp++;
                    467:        }
                    468:        *np++ = '\0';
                    469:        pattlen = n = np - linebuf;
                    470:        pp = pattbuf;
                    471:        np = linebuf;
                    472:        do {
                    473:                *pp++ = *np++;
                    474:        } while (--n);
                    475:        if (subflag) {
                    476:                if (sp->s_cop)
                    477:                        printf("%s\n", pattbuf);
                    478:                if (sp->s_fil)
                    479:                        fprintf(sp->s_fil->f_filp, "%s\n", pattbuf);
                    480:        }
                    481:        return (subflag);
                    482: ovf:
                    483:        printc("Line buffer overflow");
                    484:        return (0);
                    485: }
                    486: 
                    487: /*
                    488:  * See if the compiled pattern `pat' matches the line in pattbuf.
                    489:  */
                    490: execute(pat)
                    491: char *pat;
                    492: {
                    493:        register int i;
                    494:        register char *lp, *ep;
                    495: 
                    496:        for (i=0; i<1+NBRC; i++) {
                    497:                brcl[i].b_bp = NULL;
                    498:                brcl[i].b_ep = NULL;
                    499:        }
                    500:        if (pat[0] == CSSOL)
                    501:                ep = match(lp=pattbuf, &pat[1]);
                    502:        else {
                    503:                ep = NULL;
                    504:                lp = pattbuf;
                    505:                do {
                    506:                        if (ep=match(lp, pat))
                    507:                                break;
                    508:                } while (*lp++);
                    509:        }
                    510:        if (ep) {
                    511:                brcl[0].b_bp = lp;
                    512:                brcl[0].b_ep = ep;
                    513:        }
                    514:        return (ep ? 1 : 0);
                    515: }
                    516: 
                    517: /*
                    518:  * Given a pointer to a compiled expression, `cp', and a pointer to
                    519:  * a line, `lp', return 1 if the expression matches, else 0.
                    520:  */
                    521: char *
                    522: match(lp, cp)
                    523: register char *lp, *cp;
                    524: {
                    525:        register int n;
                    526:        char *llp, *lcp;
                    527: 
                    528:        for (;;) {
                    529:                switch (*cp++) {
                    530:                case CSNUL:
                    531:                        return (lp);
                    532:                case CSEOL:
                    533:                        if (*lp)
                    534:                                return (NULL);
                    535:                        return (lp);
                    536:                case CSOPR:
                    537:                        brcl[*cp++].b_bp = lp;
                    538:                        continue;
                    539:                case CSCPR:
                    540:                        brcl[*cp++].b_ep = lp;
                    541:                        continue;
                    542:                case CSBRN:
                    543:                        n = *cp++;
                    544:                        lcp = cp;
                    545:                        cp = brcl[n].b_bp;
                    546:                        n = brcl[n].b_ep - cp;
                    547:                        if (n > LHPSIZE)
                    548:                                return (NULL);
                    549:                        while (n-- > 0)
                    550:                                if (*lp++ != *cp++)
                    551:                                        return (NULL);
                    552:                        cp = lcp;
                    553:                        continue;
                    554:                case CSDOT:
                    555:                        if (*lp++ == '\0')
                    556:                                return (NULL);
                    557:                        continue;
                    558:                case CMDOT:
                    559:                        llp = lp;
                    560:                        while (*lp)
                    561:                                lp++;
                    562:                        goto star;
                    563:                case CSCHR:
                    564:                        if (*cp++ != *lp++)
                    565:                                return (NULL);
                    566:                        continue;
                    567:                case CMCHR:
                    568:                        llp = lp;
                    569:                        while (*cp == *lp)
                    570:                                lp++;
                    571:                        cp++;
                    572:                        goto star;
                    573:                case CSSCC:
                    574:                        if (*cp++ == tolower(*lp++))
                    575:                                continue;
                    576:                        return (NULL);
                    577:                case CMSCC:
                    578:                        llp = lp;
                    579:                        while (*cp == tolower(*lp++))
                    580:                                ;
                    581:                        cp++;
                    582:                        goto star;
                    583:                case CSCCL:
                    584:                        n = *cp++;
                    585:                        while (*cp++ != *lp)
                    586:                                if (--n == 0)
                    587:                                        return (NULL);
                    588:                        lp++;
                    589:                        cp += n-1;
                    590:                        continue;
                    591:                case CMCCL:
                    592:                        llp = lp;
                    593:                        lcp = cp;
                    594:                        while (*lp) {
                    595:                                cp = lcp;
                    596:                                n = *cp++;
                    597:                                while (*cp++ != *lp)
                    598:                                        if (--n == 0)
                    599:                                                goto star;
                    600:                                lp++;
                    601:                        }
                    602:                        cp = lcp + *lcp + 1;
                    603:                        goto star;
                    604:                case CSNCL:
                    605:                        if (*lp == '\0')
                    606:                                return (NULL);
                    607:                        n = *cp++;
                    608:                        while (n--)
                    609:                                if (*cp++ == *lp)
                    610:                                        return (NULL);
                    611:                        lp++;
                    612:                        continue;
                    613:                case CMNCL:
                    614:                        llp = lp;
                    615:                        lcp = cp;
                    616:                        while (*lp) {
                    617:                                cp = lcp;
                    618:                                n = *cp++;
                    619:                                while (n--) {
                    620:                                        if (*cp++ == *lp) {
                    621:                                                cp = lcp + *lcp + 1;
                    622:                                                goto star;
                    623:                                        }
                    624:                                }
                    625:                                lp++;
                    626:                        }
                    627:                        cp = lcp + *lcp + 1;
                    628:                star:
                    629:                        do {
                    630:                                if (lcp=match(lp, cp))
                    631:                                        return (lcp);
                    632:                        } while (--lp >= llp);
                    633:                        return (NULL);
                    634:                }
                    635:        }
                    636: }
                    637: 
                    638: 
                    639: /*
                    640:  * Print out an execution error message.
                    641:  */
                    642: printe(s)
                    643: {
                    644:        fprintf(stderr, "%r", &s);
                    645:        putc('\n', stderr);
                    646: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.