Annotation of coherent/d/bin/ed/ed3.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * An editor.
                      3:  * Regular expressions and the substitute and global commands.
                      4:  */
                      5: #include <stdio.h>
                      6: #include <ctype.h>
                      7: #include "ed.h"
                      8: 
                      9: /*
                     10:  * Global command.
                     11:  */
                     12: global(a1, a2, not)
                     13: {
                     14:        register int a, c;
                     15:        register char *gp;
                     16: 
                     17:        if (a1>a2 || a1<1 || a2>doladd) {
                     18:                derror("Address out of range");
                     19:                return (0);
                     20:        }
                     21:        if (gcp != NULL) {
                     22:                derror("Global inside global not allowed");
                     23:                return (0);
                     24:        }
                     25:        if ((c=getx()) == '\n') {
                     26:                ungetx(c);
                     27:                derror("Syntax error");
                     28:                return (0);
                     29:        }
                     30:        if (compile(c) == 0)
                     31:                return;
                     32:        gp = globbuf;
                     33:        while ((c=getx()) != '\n') {
                     34:                if (gp >= &globbuf[GBSIZE-3]) {
                     35:                        derror("Global buffer overflow");
                     36:                        return (0);
                     37:                }
                     38:                if (c == '\\')
                     39:                        if ((c=getx())!='\n' && c!='\\')
                     40:                                *gp++ = '\\';
                     41:                *gp++ = c;
                     42:        }
                     43:        if (gp == globbuf)
                     44:                goto out;
                     45:        *gp++ = '\n';
                     46:        *gp = '\0';
                     47:        for (a=a1; a<=a2; a++) {
                     48:                if (intflag)
                     49:                        goto out;
                     50:                if (execute(a) != not)
                     51:                        line[a] |= 1;
                     52:        }
                     53:        a = 1;
                     54:        while (a <= doladd) {
                     55:                if (intflag)
                     56:                        goto out;
                     57:                if ((line[a]&1) == 0) {
                     58:                        a++;
                     59:                        continue;
                     60:                }
                     61:                --line[a];
                     62:                dotadd = a;
                     63:                gcp = globbuf;
                     64:                while (*gcp != '\0')
                     65:                        if (command() == 0)
                     66:                                goto out;
                     67:                a = 1;
                     68:        }
                     69: out:
                     70:        for (a=1; a<=doladd; a++)
                     71:                line[a] &= ~1;
                     72:        gcp = NULL;
                     73:        ungetx('\n');
                     74:        return (1);
                     75: }
                     76: 
                     77: /*
                     78:  * Substitute part 1.
                     79:  * Check that address range is legal and parse substitute command.
                     80:  */
                     81: subs1(a1, a2)
                     82: {
                     83:        register int ec, c;
                     84:        register char *sp;
                     85: 
                     86:        if (a1>a2 || a1<1 || a2>doladd) {
                     87:                derror("Address out of range");
                     88:                return (0);
                     89:        }
                     90:        subnewl = 0;
                     91:        subnths = 1;
                     92:        if (isascii(c=getx()) && isdigit(c)) {
                     93:                subnths = 0;
                     94:                while (isascii(c) && isdigit(c)) {
                     95:                        subnths = subnths*10 + c-'0';
                     96:                        c = getx();
                     97:                }
                     98:        }
                     99:        if ((ec=c) == '\n') {
                    100:                ungetx(c);
                    101:                derror("Syntax error");
                    102:                return (0);
                    103:        }
                    104:        if (compile(ec) == 0)
                    105:                return (0);
                    106:        sp = subsbuf;
                    107:        while ((c=getx()) != ec) {
                    108:                if (sp >= &subsbuf[SBSIZE-4]) {
                    109:                        derror("Temporary buffer overflow");
                    110:                        return (0);
                    111:                }
                    112:                switch (c) {
                    113:                case '\n':
                    114:                        ungetx(c);
                    115:                        derror("Syntax error");
                    116:                        return (0);
                    117:                case '&':
                    118:                        *sp++ = '\\';
                    119:                        *sp++ = '0';
                    120:                        continue;
                    121:                case '\\':
                    122:                        if ((c=getx()) == '\\') {
                    123:                                *sp++ = '\\';
                    124:                                *sp++ = '\\';
                    125:                                continue;
                    126:                        }
                    127:                        if (c >= '1'  &&  c <= '9') {
                    128:                                *sp++ = '\\';
                    129:                                *sp++ = c;
                    130:                                continue;
                    131:                        }
                    132:                        if (c == '\n')
                    133:                                subnewl++;
                    134:                default:
                    135:                        *sp++ = c;
                    136:                        continue;
                    137:                }
                    138:        }
                    139:        *sp++ = '\0';
                    140:        if ((c=getx()) == 'g')
                    141:                subnths = 0;
                    142:        else
                    143:                ungetx(c);
                    144:        return (1);
                    145: }
                    146: 
                    147: /*
                    148:  * Substitute (part 2).
                    149:  * Execute substitute command.
                    150:  */
                    151: subs2(a1, a2)
                    152: {
                    153:        long seek, mark;
                    154:        int len, nth, err, a;
                    155:        char *mp, *sp;
                    156:        register int n;
                    157:        register char *lp, *rp;
                    158: 
                    159:        err = 1;
                    160:        for (a=a1; a<=a2; a++) {
                    161:                if (intflag)
                    162:                        return (1);
                    163:                if (getline(a, tempbuf) == 0)
                    164:                        return (0);
                    165:                for (n=0; n<1+BRSIZE; n++) {
                    166:                        brace[n].b_bp = NULL;
                    167:                        brace[n].b_ep = NULL;
                    168:                }
                    169:                brace[0].b_ep = tempbuf;
                    170:                mp = tempbuf;
                    171:                lp = linebuf;
                    172:                nth = 0;
                    173:                for (;;) {
                    174:                        rp = codebuf;
                    175:                        if (*rp == CSSOL) {
                    176:                                if (mp != tempbuf)
                    177:                                        break;
                    178:                                rp++;
                    179:                        }
                    180:                        if ((rp=match(mp, rp)) == NULL) {
                    181:                                if (*mp++ == '\0')
                    182:                                        break;
                    183:                                continue;
                    184:                        }
                    185:                        nth++;
                    186:                        if (subnths) {
                    187:                                if (nth < subnths) {
                    188:                                        mp = rp;
                    189:                                        continue;
                    190:                                }
                    191:                                if (nth > subnths)
                    192:                                        goto done;
                    193:                        }
                    194:                        err = 0;
                    195:                        saved = 0;
                    196:                        dotadd = a;
                    197:                        brace[0].b_bp = mp;
                    198:                        mp = rp;
                    199:                        rp = brace[0].b_ep;
                    200:                        brace[0].b_ep = mp;
                    201:                        len = mp - brace[0].b_bp;
                    202:                        n = brace[0].b_bp - rp;
                    203:                        if (lp+n >= &linebuf[LBSIZE-1])
                    204:                                goto ovf;
                    205:                        while (n--)
                    206:                                *lp++ = *rp++;
                    207:                        sp = subsbuf;
                    208:                        while (*sp) {
                    209:                                if (lp >= &linebuf[LBSIZE-4])
                    210:                                        goto ovf;
                    211:                                if (*sp != '\\') {
                    212:                                        *lp++ = *sp++;
                    213:                                        continue;
                    214:                                }
                    215:                                if (*++sp == '\\') {
                    216:                                        *lp++ = *sp++;
                    217:                                        continue;
                    218:                                }
                    219:                                n = *sp++ - '0';
                    220:                                if ((rp=brace[n].b_bp) == NULL)
                    221:                                        continue;
                    222:                                n = brace[n].b_ep-rp;
                    223:                                if (lp+n >= &linebuf[LBSIZE-4])
                    224:                                        goto ovf;
                    225:                                while (n--)
                    226:                                        *lp++ = *rp++;
                    227:                        }
                    228:                        if (*mp == '\0')
                    229:                                break;
                    230:                        if (len == 0)
                    231:                                mp++;
                    232:                        if (subnths!=0 && nth==subnths)
                    233:                                break;
                    234:                }
                    235:        done:
                    236:                if (dotadd != a)
                    237:                        continue;
                    238:                rp = brace[0].b_ep;
                    239:                while (*rp) {
                    240:                        if (lp >= &linebuf[LBSIZE-1])
                    241:                                goto ovf;
                    242:                        *lp++ = *rp++;
                    243:                }
                    244:                *lp++ = '\0';
                    245:                seek = linead();
                    246:                if (subnewl) {
                    247:                        lp = linebuf;
                    248:                        while (*lp != '\n')
                    249:                                lp++;
                    250:                        *lp++ = '\0';
                    251:                }
                    252:                if (putline(linebuf, lp-linebuf) == 0)
                    253:                        return (0);
                    254:                suborig = line[a];
                    255:                if (suborig&1)
                    256:                        --suborig;
                    257:                subseek = seek|1;
                    258:                line[a] = seek;
                    259:                mark = suborig|1;
                    260:                for (n=0; n<MKSIZE; n++)
                    261:                        if (marklin[n] == mark)
                    262:                                marklin[n] = subseek;
                    263:                if (subnewl != 0) {
                    264:                        n = 1;
                    265:                        do {
                    266:                                mp = lp;
                    267:                                while (*lp!='\n' && *lp!='\0')
                    268:                                        lp++;
                    269:                                if (*lp == '\0')
                    270:                                        n = 0;
                    271:                                *lp++ = '\0';
                    272:                                seek = linead();
                    273:                                if (putline(mp, lp-mp) == 0)
                    274:                                        return (0);
                    275:                                if (expand(a) == 0)
                    276:                                        return (0);
                    277:                                line[++a] = seek;
                    278:                                dotadd = a;
                    279:                                a2++;
                    280:                        } while (n);
                    281:                }
                    282:        }
                    283:        if (err!=0 && gcp==NULL) {
                    284:                derror("Pattern not matched");
                    285:                return (0);
                    286:        }
                    287:        return (1);
                    288: 
                    289: ovf:
                    290:        derror("Temporary buffer overflow");
                    291:        return (0);
                    292: }
                    293: 
                    294: /*
                    295:  * Compile a regular expression.  `ec' is the character upon which
                    296:  * the regular expression ends.  If an error is encountered, the
                    297:  * pattern is restored and input characters are thrown away until
                    298:  * a new line is found.
                    299:  */
                    300: compile(ec)
                    301: {
                    302:        int bstack[BRSIZE], bcount, blevel, n;
                    303:        register int c;
                    304:        register char *cp, *lcp;
                    305: 
                    306:        bcopy(tempbuf, codebuf);
                    307:        bcount = 1;
                    308:        blevel = 0;
                    309:        cp = &codebuf[0];
                    310:        if ((c=getx()) == ec) {
                    311:                if (*cp == CSNUL) {
                    312:                        derror("No saved pattern");
                    313:                        goto err;
                    314:                }
                    315:                return (1);
                    316:        }
                    317:        if (c == '^') {
                    318:                *cp++ = CSSOL;
                    319:                c = getx();
                    320:        }
                    321:        while (c != ec) {
                    322:                if (c == '\n') {
                    323:                        goto nwl;
                    324:                }
                    325:                if (cp > &codebuf[CBSIZE-4])
                    326:                        goto ovf;
                    327:                switch (c) {
                    328:                case '*':
                    329:                        goto syn;
                    330:                case '.':
                    331:                        if ((c=getx()) != '*') {
                    332:                                *cp++ = CSDOT;
                    333:                                continue;
                    334:                        }
                    335:                        *cp++ = CMDOT;
                    336:                        c = getx();
                    337:                        continue;
                    338:                case '$':
                    339:                        if ((c=getx()) != ec) {
                    340:                                ungetx(c);
                    341:                                c = '$';
                    342:                                goto character;
                    343:                        }
                    344:                        *cp++ = CSEOL;
                    345:                        continue;
                    346:                case '[':
                    347:                        lcp = cp;
                    348:                        if ((c=getx()) == '^')
                    349:                                *cp++ = CSNCL;
                    350:                        else {
                    351:                                ungetx(c);
                    352:                                *cp++ = CSCCL;
                    353:                        }
                    354:                        *cp++ = 0;
                    355:                        if ((c=getx()) == ']')
                    356:                                *cp++ = c;
                    357:                        else
                    358:                                ungetx(c);
                    359:                        while ((c=getx()) != ']') {
                    360:                                if (c == '\n')
                    361:                                        goto nwl;
                    362:                                if (c!='-' || cp==lcp+2) {
                    363:                                        if (cp >= &codebuf[CBSIZE-4])
                    364:                                                goto ovf;
                    365:                                        *cp++ = c;
                    366:                                        if (sflag && isascii(c) && isallet(c))
                    367:                                                *cp++ = toother(c);
                    368:                                        continue;
                    369:                                }
                    370:                                if ((c=getx()) == '\n')
                    371:                                        goto nwl;
                    372:                                if (c == ']') {
                    373:                                        *cp++ = '-';
                    374:                                        ungetx(c);
                    375:                                        continue;
                    376:                                }
                    377:                                if ((n=cp[-1]) > c)
                    378:                                        goto syn;
                    379:                                while (++n <= c) {
                    380:                                        if (cp >= &codebuf[CBSIZE-4])
                    381:                                                goto ovf;
                    382:                                        *cp++ = n;
                    383:                                        if (sflag && isascii(c) && isallet(c))
                    384:                                                *cp++ = toother(c);
                    385:                                }
                    386:                        }
                    387:                        if ((c=getx()) == '*') {
                    388:                                (*lcp)++;
                    389:                                c = getx();
                    390:                        }
                    391:                        if ((n=cp-(lcp+2)) > 255) {
                    392:                                derror("Character class too large");
                    393:                                goto err;
                    394:                        }
                    395:                        *++lcp = n;
                    396:                        continue;
                    397:                case '\\':
                    398:                        switch (c=getx()) {
                    399:                        case '\n':
                    400:                                goto nwl;
                    401:                        case '(':
                    402:                                if (bcount > BRSIZE) {
                    403:                                        derror("Too many \\(");
                    404:                                        goto err;
                    405:                                }
                    406:                                *cp++ = CSOPR;
                    407:                                *cp++ = bstack[blevel++] = bcount++;
                    408:                                c = getx();
                    409:                                continue;
                    410:                        case ')':
                    411:                                if (blevel == 0)
                    412:                                        goto syn;
                    413:                                *cp++ = CSCPR;
                    414:                                *cp++ = bstack[--blevel];
                    415:                                c = getx();
                    416:                                continue;
                    417:                        default:
                    418:                                if (isascii(c) && isdigit(c)) {
                    419:                                        *cp++ = CSBRN;
                    420:                                        *cp++ = c-'0';
                    421:                                        c = getx();
                    422:                                        continue;
                    423:                                }
                    424:                        }
                    425:                default:
                    426:                character:
                    427:                        if (sflag && isascii(c) && isallet(c)) {
                    428:                                *cp++ = CSSCC;
                    429:                                if (isupper(c))
                    430:                                        c = tolower(c);
                    431:                        } else
                    432:                                *cp++ = CSCHR;
                    433:                        *cp++ = c;
                    434:                        if ((c=getx()) == '*') {
                    435:                                cp[-2]++;
                    436:                                c = getx();
                    437:                        }
                    438:                }
                    439:        }
                    440:        *cp++ = CSNUL;
                    441:        return (1);
                    442: ovf:
                    443:        derror("Code buffer overflow");
                    444:        bcopy(codebuf, tempbuf);
                    445:        return (0);
                    446: nwl:
                    447:        ungetx(c);
                    448: syn:
                    449:        derror("Syntax error");
                    450: err:
                    451:        bcopy(codebuf, tempbuf);
                    452:        return (0);
                    453: }
                    454: 
                    455: /*
                    456:  * Copy BSIZE buffer into dest from source
                    457:  */
                    458: bcopy(dest, source)
                    459: register char *dest;
                    460: register char *source;
                    461: {
                    462:        register int n;
                    463: 
                    464:        n = CBSIZE;
                    465:        do
                    466:                *dest++ = *source++;
                    467:        while (--n > 0);
                    468: }
                    469: 
                    470: /*
                    471:  * Return 1 if the compiled expression in `codebuf' matches the line in
                    472:  * `linebuf', else 0.
                    473:  */
                    474: execute(a)
                    475: {
                    476:        register int i;
                    477:        register char *lp, *ep;
                    478: 
                    479:        if (getline(a, linebuf) == 0)
                    480:                return (0);
                    481:        for (i=0; i<1+BRSIZE; i++) {
                    482:                brace[i].b_bp = NULL;
                    483:                brace[i].b_ep = NULL;
                    484:        }
                    485:        if (codebuf[0] == CSSOL)
                    486:                ep = match(lp=linebuf, &codebuf[1]);
                    487:        else {
                    488:                ep = NULL;
                    489:                lp = linebuf;
                    490:                do {
                    491:                        if (ep=match(lp, codebuf))
                    492:                                break;
                    493:                } while (*lp++);
                    494:        }
                    495:        if (ep) {
                    496:                brace[0].b_bp = lp;
                    497:                brace[0].b_ep = ep;
                    498:        }
                    499:        return (ep ? 1 : 0);
                    500: }
                    501: 
                    502: /*
                    503:  * Given a pointer to a compiled expression, `cp', and a pointer to
                    504:  * a line, `lp', return 1 if the expression matches, else 0.
                    505:  */
                    506: char *
                    507: match(lp, cp)
                    508: register char *lp, *cp;
                    509: {
                    510:        register int n;
                    511:        char *llp, *lcp;
                    512: 
                    513:        for (;;) {
                    514:                switch (*cp++) {
                    515:                case CSNUL:
                    516:                        return (lp);
                    517:                case CSEOL:
                    518:                        if (*lp)
                    519:                                return (NULL);
                    520:                        return (lp);
                    521:                case CSOPR:
                    522:                        brace[*cp++].b_bp = lp;
                    523:                        continue;
                    524:                case CSCPR:
                    525:                        brace[*cp++].b_ep = lp;
                    526:                        continue;
                    527:                case CSBRN:
                    528:                        n = *cp++;
                    529:                        lcp = cp;
                    530:                        cp = brace[n].b_bp;
                    531:                        n = brace[n].b_ep - cp;
                    532:                        if (n > LBSIZE)
                    533:                                return (NULL);
                    534:                        while (n-- > 0)
                    535:                                if (*lp++ != *cp++)
                    536:                                        return (NULL);
                    537:                        cp = lcp;
                    538:                        continue;
                    539:                case CSDOT:
                    540:                        if (*lp++ == '\0')
                    541:                                return (NULL);
                    542:                        continue;
                    543:                case CMDOT:
                    544:                        llp = lp;
                    545:                        while (*lp)
                    546:                                lp++;
                    547:                        goto star;
                    548:                case CSCHR:
                    549:                        if (*cp++ != *lp++)
                    550:                                return (NULL);
                    551:                        continue;
                    552:                case CMCHR:
                    553:                        llp = lp;
                    554:                        while (*cp == *lp)
                    555:                                lp++;
                    556:                        cp++;
                    557:                        goto star;
                    558:                case CSSCC:
                    559:                        if (*cp++ == tolower(*lp++))
                    560:                                continue;
                    561:                        return (NULL);
                    562:                case CMSCC:
                    563:                        llp = lp;
                    564:                        while (*cp == tolower(*lp++))
                    565:                                ;
                    566:                        cp++;
                    567:                        goto star;
                    568:                case CSCCL:
                    569:                        n = *cp++;
                    570:                        while (*cp++ != *lp)
                    571:                                if (--n == 0)
                    572:                                        return (NULL);
                    573:                        lp++;
                    574:                        cp += n-1;
                    575:                        continue;
                    576:                case CMCCL:
                    577:                        llp = lp;
                    578:                        lcp = cp;
                    579:                        while (*lp) {
                    580:                                cp = lcp;
                    581:                                n = *cp++;
                    582:                                while (*cp++ != *lp)
                    583:                                        if (--n == 0)
                    584:                                                goto star;
                    585:                                lp++;
                    586:                        }
                    587:                        cp = lcp + *lcp + 1;
                    588:                        goto star;
                    589:                case CSNCL:
                    590:                        if (*lp == '\0')
                    591:                                return (NULL);
                    592:                        n = *cp++;
                    593:                        while (n--)
                    594:                                if (*cp++ == *lp)
                    595:                                        return (NULL);
                    596:                        lp++;
                    597:                        continue;
                    598:                case CMNCL:
                    599:                        llp = lp;
                    600:                        lcp = cp;
                    601:                        while (*lp) {
                    602:                                cp = lcp;
                    603:                                n = *cp++;
                    604:                                while (n--) {
                    605:                                        if (*cp++ == *lp) {
                    606:                                                cp = lcp + *lcp + 1;
                    607:                                                goto star;
                    608:                                        }
                    609:                                }
                    610:                                lp++;
                    611:                        }
                    612:                        cp = lcp + *lcp + 1;
                    613:                star:
                    614:                        do {
                    615:                                if (lcp=match(lp, cp))
                    616:                                        return (lcp);
                    617:                        } while (--lp >= llp);
                    618:                        return (NULL);
                    619:                }
                    620:        }
                    621: }

unix.superglobalmegacorp.com

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