Annotation of 43BSDReno/usr.bin/ex/ex_vops3.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: static char *sccsid = "@(#)ex_vops3.c  7.4 (Berkeley) 3/9/87";
        !             9: #endif not lint
        !            10: 
        !            11: #include "ex.h"
        !            12: #include "ex_tty.h"
        !            13: #include "ex_vis.h"
        !            14: 
        !            15: /*
        !            16:  * Routines to handle structure.
        !            17:  * Operations supported are:
        !            18:  *     ( ) { } [ ]
        !            19:  *
        !            20:  * These cover:                LISP            TEXT
        !            21:  *     ( )             s-exprs         sentences
        !            22:  *     { }             list at same    paragraphs
        !            23:  *     [ ]             defuns          sections
        !            24:  *
        !            25:  * { and } for C used to attempt to do something with matching {}'s, but
        !            26:  * I couldn't find definitions which worked intuitively very well, so I
        !            27:  * scrapped this.
        !            28:  *
        !            29:  * The code here is very hard to understand.
        !            30:  */
        !            31: line   *llimit;
        !            32: int    (*lf)();
        !            33: 
        !            34: #ifdef LISPCODE
        !            35: int    lindent();
        !            36: #endif
        !            37: 
        !            38: bool   wasend;
        !            39: 
        !            40: /*
        !            41:  * Find over structure, repeated count times.
        !            42:  * Don't go past line limit.  F is the operation to
        !            43:  * be performed eventually.  If pastatom then the user said {}
        !            44:  * rather than (), implying past atoms in a list (or a paragraph
        !            45:  * rather than a sentence.
        !            46:  */
        !            47: lfind(pastatom, cnt, f, limit)
        !            48:        bool pastatom;
        !            49:        int cnt, (*f)();
        !            50:        line *limit;
        !            51: {
        !            52:        register int c;
        !            53:        register int rc = 0;
        !            54:        char save[LBSIZE];
        !            55: 
        !            56:        /*
        !            57:         * Initialize, saving the current line buffer state
        !            58:         * and computing the limit; a 0 argument means
        !            59:         * directional end of file.
        !            60:         */
        !            61:        wasend = 0;
        !            62:        lf = f;
        !            63:        strcpy(save, linebuf);
        !            64:        if (limit == 0)
        !            65:                limit = dir < 0 ? one : dol;
        !            66:        llimit = limit;
        !            67:        wdot = dot;
        !            68:        wcursor = cursor;
        !            69: 
        !            70:        if (pastatom >= 2) {
        !            71:                while (cnt > 0 && word(f, cnt))
        !            72:                        cnt--;
        !            73:                if (pastatom == 3)
        !            74:                        eend(f);
        !            75:                if (dot == wdot) {
        !            76:                        wdot = 0;
        !            77:                        if (cursor == wcursor)
        !            78:                                rc = -1;
        !            79:                }
        !            80:        }
        !            81: #ifdef LISPCODE
        !            82:        else if (!value(LISP)) {
        !            83: #else
        !            84:        else {
        !            85: #endif
        !            86:                char *icurs;
        !            87:                line *idot;
        !            88: 
        !            89:                if (linebuf[0] == 0) {
        !            90:                        do
        !            91:                                if (!lnext())
        !            92:                                        goto ret;
        !            93:                        while (linebuf[0] == 0);
        !            94:                        if (dir > 0) {
        !            95:                                wdot--;
        !            96:                                linebuf[0] = 0;
        !            97:                                wcursor = linebuf;
        !            98:                                /*
        !            99:                                 * If looking for sentence, next line
        !           100:                                 * starts one.
        !           101:                                 */
        !           102:                                if (!pastatom) {
        !           103:                                        icurs = wcursor;
        !           104:                                        idot = wdot;
        !           105:                                        goto begin;
        !           106:                                }
        !           107:                        }
        !           108:                }
        !           109:                icurs = wcursor;
        !           110:                idot = wdot;
        !           111: 
        !           112:                /*
        !           113:                 * Advance so as to not find same thing again.
        !           114:                 */
        !           115:                if (dir > 0) {
        !           116:                        if (!lnext()) {
        !           117:                                rc = -1;
        !           118:                                goto ret;
        !           119:                        }
        !           120:                } else
        !           121:                        ignore(lskipa1(""));
        !           122: 
        !           123:                /*
        !           124:                 * Count times find end of sentence/paragraph.
        !           125:                 */
        !           126: begin:
        !           127:                for (;;) {
        !           128:                        while (!endsent(pastatom))
        !           129:                                if (!lnext())
        !           130:                                        goto ret;
        !           131:                        if (!pastatom || wcursor == linebuf && endPS())
        !           132:                                if (--cnt <= 0)
        !           133:                                        break;
        !           134:                        if (linebuf[0] == 0) {
        !           135:                                do
        !           136:                                        if (!lnext())
        !           137:                                                goto ret;
        !           138:                                while (linebuf[0] == 0);
        !           139:                        } else
        !           140:                                if (!lnext())
        !           141:                                        goto ret;
        !           142:                }
        !           143: 
        !           144:                /*
        !           145:                 * If going backwards, and didn't hit the end of the buffer,
        !           146:                 * then reverse direction.
        !           147:                 */
        !           148:                if (dir < 0 && (wdot != llimit || wcursor != linebuf)) {
        !           149:                        dir = 1;
        !           150:                        llimit = dot;
        !           151:                        /*
        !           152:                         * Empty line needs special treatement.
        !           153:                         * If moved to it from other than begining of next line,
        !           154:                         * then a sentence starts on next line.
        !           155:                         */
        !           156:                        if (linebuf[0] == 0 && !pastatom && 
        !           157:                           (wdot != dot - 1 || cursor != linebuf)) {
        !           158:                                ignore(lnext());
        !           159:                                goto ret;
        !           160:                        }
        !           161:                }
        !           162: 
        !           163:                /*
        !           164:                 * If we are not at a section/paragraph division,
        !           165:                 * advance to next.
        !           166:                 */
        !           167:                if (wcursor == icurs && wdot == idot || wcursor != linebuf || !endPS())
        !           168:                        ignore(lskipa1(""));
        !           169:        }
        !           170: #ifdef LISPCODE
        !           171:        else {
        !           172:                c = *wcursor;
        !           173:                /*
        !           174:                 * Startup by skipping if at a ( going left or a ) going
        !           175:                 * right to keep from getting stuck immediately.
        !           176:                 */
        !           177:                if (dir < 0 && c == '(' || dir > 0 && c == ')') {
        !           178:                        if (!lnext()) {
        !           179:                                rc = -1;
        !           180:                                goto ret;
        !           181:                        }
        !           182:                }
        !           183:                /*
        !           184:                 * Now chew up repitition count.  Each time around
        !           185:                 * if at the beginning of an s-exp (going forwards)
        !           186:                 * or the end of an s-exp (going backwards)
        !           187:                 * skip the s-exp.  If not at beg/end resp, then stop
        !           188:                 * if we hit a higher level paren, else skip an atom,
        !           189:                 * counting it unless pastatom.
        !           190:                 */
        !           191:                while (cnt > 0) {
        !           192:                        c = *wcursor;
        !           193:                        if (dir < 0 && c == ')' || dir > 0 && c == '(') {
        !           194:                                if (!lskipbal("()"))
        !           195:                                        goto ret;
        !           196:                                /*
        !           197:                                 * Unless this is the last time going
        !           198:                                 * backwards, skip past the matching paren
        !           199:                                 * so we don't think it is a higher level paren.
        !           200:                                 */
        !           201:                                if (dir < 0 && cnt == 1)
        !           202:                                        goto ret;
        !           203:                                if (!lnext() || !ltosolid())
        !           204:                                        goto ret;
        !           205:                                --cnt;
        !           206:                        } else if (dir < 0 && c == '(' || dir > 0 && c == ')')
        !           207:                                /* Found a higher level paren */
        !           208:                                goto ret;
        !           209:                        else {
        !           210:                                if (!lskipatom())
        !           211:                                        goto ret;
        !           212:                                if (!pastatom)
        !           213:                                        --cnt;
        !           214:                        }
        !           215:                }
        !           216:        }
        !           217: #endif
        !           218: ret:
        !           219:        strcLIN(save);
        !           220:        return (rc);
        !           221: }
        !           222: 
        !           223: /*
        !           224:  * Is this the end of a sentence?
        !           225:  */
        !           226: /* ARGSUSED */
        !           227: endsent(pastatom)
        !           228:        bool pastatom;
        !           229: {
        !           230:        register char *cp = wcursor;
        !           231:        register int d;
        !           232: 
        !           233:        /*
        !           234:         * If this is the beginning of a line, then
        !           235:         * check for the end of a paragraph or section.
        !           236:         */
        !           237:        if (cp == linebuf)
        !           238:                return (endPS());
        !           239: 
        !           240:        /*
        !           241:         * Sentences end with . ! ? not at the beginning
        !           242:         * of the line, and must be either at the end of the line,
        !           243:         * or followed by 2 spaces.  Any number of intervening ) ] ' "
        !           244:         * characters are allowed.
        !           245:         */
        !           246:        if (!any(*cp, ".!?"))
        !           247:                goto tryps;
        !           248:        do
        !           249:                if ((d = *++cp) == 0)
        !           250:                        return (1);
        !           251:        while (any(d, ")]'"));
        !           252:        if (*cp == 0 || *cp++ == ' ' && *cp == ' ')
        !           253:                return (1);
        !           254: tryps:
        !           255:        if (cp[1] == 0)
        !           256:                return (endPS());
        !           257:        return (0);
        !           258: }
        !           259: 
        !           260: /*
        !           261:  * End of paragraphs/sections are respective
        !           262:  * macros as well as blank lines and form feeds.
        !           263:  */
        !           264: endPS()
        !           265: {
        !           266: 
        !           267:        return (linebuf[0] == 0 ||
        !           268:                isa(svalue(PARAGRAPHS)) || isa(svalue(SECTIONS)));
        !           269:            
        !           270: }
        !           271: 
        !           272: #ifdef LISPCODE
        !           273: lindent(addr)
        !           274:        line *addr;
        !           275: {
        !           276:        register int i;
        !           277:        char *swcurs = wcursor;
        !           278:        line *swdot = wdot;
        !           279: 
        !           280: again:
        !           281:        if (addr > one) {
        !           282:                register char *cp;
        !           283:                register int cnt = 0;
        !           284: 
        !           285:                addr--;
        !           286:                getline(*addr);
        !           287:                for (cp = linebuf; *cp; cp++)
        !           288:                        if (*cp == '(')
        !           289:                                cnt++;
        !           290:                        else if (*cp == ')')
        !           291:                                cnt--;
        !           292:                cp = vpastwh(linebuf);
        !           293:                if (*cp == 0)
        !           294:                        goto again;
        !           295:                if (cnt == 0)
        !           296:                        return (whitecnt(linebuf));
        !           297:                addr++;
        !           298:        }
        !           299:        wcursor = linebuf;
        !           300:        linebuf[0] = 0;
        !           301:        wdot = addr;
        !           302:        dir = -1;
        !           303:        llimit = one;
        !           304:        lf = lindent;
        !           305:        if (!lskipbal("()"))
        !           306:                i = 0;
        !           307:        else if (wcursor == linebuf)
        !           308:                i = 2;
        !           309:        else {
        !           310:                register char *wp = wcursor;
        !           311: 
        !           312:                dir = 1;
        !           313:                llimit = wdot;
        !           314:                if (!lnext() || !ltosolid() || !lskipatom()) {
        !           315:                        wcursor = wp;
        !           316:                        i = 1;
        !           317:                } else
        !           318:                        i = 0;
        !           319:                i += column(wcursor) - 1;
        !           320:                if (!inopen)
        !           321:                        i--;
        !           322:        }
        !           323:        wdot = swdot;
        !           324:        wcursor = swcurs;
        !           325:        return (i);
        !           326: }
        !           327: #endif
        !           328: 
        !           329: lmatchp(addr)
        !           330:        line *addr;
        !           331: {
        !           332:        register int i;
        !           333:        register char *parens, *cp;
        !           334: 
        !           335:        for (cp = cursor; !any(*cp, "({[)}]");)
        !           336:                if (*cp++ == 0)
        !           337:                        return (0);
        !           338:        lf = 0;
        !           339:        parens = any(*cp, "()") ? "()" : any(*cp, "[]") ? "[]" : "{}";
        !           340:        if (*cp == parens[1]) {
        !           341:                dir = -1;
        !           342:                llimit = one;
        !           343:        } else {
        !           344:                dir = 1;
        !           345:                llimit = dol;
        !           346:        }
        !           347:        if (addr)
        !           348:                llimit = addr;
        !           349:        if (splitw)
        !           350:                llimit = dot;
        !           351:        wcursor = cp;
        !           352:        wdot = dot;
        !           353:        i = lskipbal(parens);
        !           354:        return (i);
        !           355: }
        !           356: 
        !           357: lsmatch(cp)
        !           358:        char *cp;
        !           359: {
        !           360:        char save[LBSIZE];
        !           361:        register char *sp = save;
        !           362:        register char *scurs = cursor;
        !           363: 
        !           364:        wcursor = cp;
        !           365:        strcpy(sp, linebuf);
        !           366:        *wcursor = 0;
        !           367:        strcpy(cursor, genbuf);
        !           368:        cursor = strend(linebuf) - 1;
        !           369:        if (lmatchp(dot - vcline)) {
        !           370:                register int i = insmode;
        !           371:                register int c = outcol;
        !           372:                register int l = outline;
        !           373: 
        !           374:                if (!MI)
        !           375:                        endim();
        !           376:                vgoto(splitw ? WECHO : LINE(wdot - llimit), column(wcursor) - 1);
        !           377:                flush();
        !           378:                sleep(1);
        !           379:                vgoto(l, c);
        !           380:                if (i)
        !           381:                        goim();
        !           382:        }
        !           383:        else {
        !           384:                strcLIN(sp);
        !           385:                strcpy(scurs, genbuf);
        !           386:                if (!lmatchp((line *) 0))
        !           387:                        beep();
        !           388:        }
        !           389:        strcLIN(sp);
        !           390:        wdot = 0;
        !           391:        wcursor = 0;
        !           392:        cursor = scurs;
        !           393: }
        !           394: 
        !           395: ltosolid()
        !           396: {
        !           397: 
        !           398:        return (ltosol1("()"));
        !           399: }
        !           400: 
        !           401: ltosol1(parens)
        !           402:        register char *parens;
        !           403: {
        !           404:        register char *cp;
        !           405: 
        !           406:        if (*parens && !*wcursor && !lnext())
        !           407:                return (0);
        !           408:        while (isspace(*wcursor) || (*wcursor == 0 && *parens))
        !           409:                if (!lnext())
        !           410:                        return (0);
        !           411:        if (any(*wcursor, parens) || dir > 0)
        !           412:                return (1);
        !           413:        for (cp = wcursor; cp > linebuf; cp--)
        !           414:                if (isspace(cp[-1]) || any(cp[-1], parens))
        !           415:                        break;
        !           416:        wcursor = cp;
        !           417:        return (1);
        !           418: }
        !           419: 
        !           420: lskipbal(parens)
        !           421:        register char *parens;
        !           422: {
        !           423:        register int level = dir;
        !           424:        register int c;
        !           425: 
        !           426:        do {
        !           427:                if (!lnext()) {
        !           428:                        wdot = NOLINE;
        !           429:                        return (0);
        !           430:                }
        !           431:                c = *wcursor;
        !           432:                if (c == parens[1])
        !           433:                        level--;
        !           434:                else if (c == parens[0])
        !           435:                        level++;
        !           436:        } while (level);
        !           437:        return (1);
        !           438: }
        !           439: 
        !           440: lskipatom()
        !           441: {
        !           442: 
        !           443:        return (lskipa1("()"));
        !           444: }
        !           445: 
        !           446: lskipa1(parens)
        !           447:        register char *parens;
        !           448: {
        !           449:        register int c;
        !           450: 
        !           451:        for (;;) {
        !           452:                if (dir < 0 && wcursor == linebuf) {
        !           453:                        if (!lnext())
        !           454:                                return (0);
        !           455:                        break;
        !           456:                }
        !           457:                c = *wcursor;
        !           458:                if (c && (isspace(c) || any(c, parens)))
        !           459:                        break;
        !           460:                if (!lnext())
        !           461:                        return (0);
        !           462:                if (dir > 0 && wcursor == linebuf)
        !           463:                        break;
        !           464:        }
        !           465:        return (ltosol1(parens));
        !           466: }
        !           467: 
        !           468: lnext()
        !           469: {
        !           470: 
        !           471:        if (dir > 0) {
        !           472:                if (*wcursor)
        !           473:                        wcursor++;
        !           474:                if (*wcursor)
        !           475:                        return (1);
        !           476:                if (wdot >= llimit) {
        !           477:                        if (lf == vmove && wcursor > linebuf)
        !           478:                                wcursor--;
        !           479:                        return (0);
        !           480:                }
        !           481:                wdot++;
        !           482:                getline(*wdot);
        !           483:                wcursor = linebuf;
        !           484:                return (1);
        !           485:        } else {
        !           486:                --wcursor;
        !           487:                if (wcursor >= linebuf)
        !           488:                        return (1);
        !           489: #ifdef LISPCODE
        !           490:                if (lf == lindent && linebuf[0] == '(')
        !           491:                        llimit = wdot;
        !           492: #endif
        !           493:                if (wdot <= llimit) {
        !           494:                        wcursor = linebuf;
        !           495:                        return (0);
        !           496:                }
        !           497:                wdot--;
        !           498:                getline(*wdot);
        !           499:                wcursor = linebuf[0] == 0 ? linebuf : strend(linebuf) - 1;
        !           500:                return (1);
        !           501:        }
        !           502: }
        !           503: 
        !           504: lbrack(c, f)
        !           505:        register int c;
        !           506:        int (*f)();
        !           507: {
        !           508:        register line *addr;
        !           509: 
        !           510:        addr = dot;
        !           511:        for (;;) {
        !           512:                addr += dir;
        !           513:                if (addr < one || addr > dol) {
        !           514:                        addr -= dir;
        !           515:                        break;
        !           516:                }
        !           517:                getline(*addr);
        !           518:                if (linebuf[0] == '{' ||
        !           519: #ifdef LISPCODE
        !           520:                    value(LISP) && linebuf[0] == '(' ||
        !           521: #endif
        !           522:                    isa(svalue(SECTIONS))) {
        !           523:                        if (c == ']' && f != vmove) {
        !           524:                                addr--;
        !           525:                                getline(*addr);
        !           526:                        }
        !           527:                        break;
        !           528:                }
        !           529:                if (c == ']' && f != vmove && linebuf[0] == '}')
        !           530:                        break;
        !           531:        }
        !           532:        if (addr == dot)
        !           533:                return (0);
        !           534:        if (f != vmove)
        !           535:                wcursor = c == ']' ? strend(linebuf) : linebuf;
        !           536:        else
        !           537:                wcursor = 0;
        !           538:        wdot = addr;
        !           539:        vmoving = 0;
        !           540:        return (1);
        !           541: }
        !           542: 
        !           543: isa(cp)
        !           544:        register char *cp;
        !           545: {
        !           546: 
        !           547:        if (linebuf[0] != '.')
        !           548:                return (0);
        !           549:        for (; cp[0] && cp[1]; cp += 2)
        !           550:                if (linebuf[1] == cp[0]) {
        !           551:                        if (linebuf[2] == cp[1])
        !           552:                                return (1);
        !           553:                        if (linebuf[2] == 0 && cp[1] == ' ')
        !           554:                                return (1);
        !           555:                }
        !           556:        return (0);
        !           557: }

unix.superglobalmegacorp.com

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