Annotation of coherent/d/bin/ed/ed3.c, revision 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.