Annotation of 43BSD/contrib/B/src/bed/outp.c, revision 1.1

1.1     ! root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
        !             2: static char rcsid[] = "$Header: outp.c,v 2.4 85/08/22 16:05:48 timo Exp $";
        !             3: 
        !             4: /*
        !             5:  * B editor -- Screen management package, lower level output part.
        !             6:  */
        !             7: 
        !             8: #include <ctype.h>
        !             9: 
        !            10: #include "b.h"
        !            11: #include "bobj.h"
        !            12: #include "node.h"
        !            13: #include "supr.h"
        !            14: #include "gram.h"
        !            15: #include "cell.h"
        !            16: 
        !            17: 
        !            18: #define SOBIT 0200
        !            19: #define CHAR 0177
        !            20: 
        !            21: 
        !            22: /*
        !            23:  * Variables used for communication with outfocus.
        !            24:  */
        !            25: 
        !            26: Hidden node thefocus;
        !            27: Hidden environ wherebuf;
        !            28: Hidden environ *where = &wherebuf;
        !            29: Hidden bool realvhole;
        !            30: Hidden int multiline; /* Height of focus */
        !            31: Hidden int yfocus;
        !            32: 
        !            33: Visible int focy; /* Where the cursor must go */
        !            34: Visible int focx;
        !            35: 
        !            36: 
        !            37: /*
        !            38:  * Save position of the focus for use by outnode/outfocus.
        !            39:  */
        !            40: 
        !            41: Visible Procedure
        !            42: savefocus(ep)
        !            43:        register environ *ep;
        !            44: {
        !            45:        register int sym;
        !            46:        register int w;
        !            47: 
        !            48:        realvhole = No;
        !            49:        thefocus = Nnil;
        !            50:        multiline = 0;
        !            51:        yfocus = Ycoord(ep->focus);
        !            52:        w = focoffset(ep);
        !            53:        if (w < 0)
        !            54:                yfocus += -w;
        !            55:        w = focwidth(ep);
        !            56:        if (w < 0) {
        !            57:                multiline = -w;
        !            58:                if (focchar(ep) == '\n')
        !            59:                        ++yfocus;
        !            60:                else
        !            61:                        ++multiline;
        !            62:                return;
        !            63:        }
        !            64:        if (ep->mode == WHOLE) {
        !            65:                sym = symbol(tree(ep->focus));
        !            66:                if (sym == Optional)
        !            67:                        ep->mode = ATBEGIN;
        !            68:        }
        !            69:        switch(ep->mode) {
        !            70:        case VHOLE:
        !            71:                if (ep->s1&1)
        !            72:                        ep->mode = FHOLE;
        !            73:        case ATBEGIN:
        !            74:        case ATEND:
        !            75:        case FHOLE:
        !            76:                ritevhole(ep);
        !            77:                switch (ep->mode) {
        !            78:                case ATBEGIN:
        !            79:                case FHOLE:
        !            80:                        sym = symbol(tree(ep->focus));
        !            81:                        if (sym == Hole && (ep->mode == ATBEGIN || ep->s2 == 0)) {
        !            82:                                ep->mode = WHOLE;
        !            83:                                break;
        !            84:                        }
        !            85:                        /* Fall through */
        !            86:                case VHOLE:
        !            87:                case ATEND:
        !            88:                        leftvhole(ep);
        !            89:                        realvhole = 1 + ep->spflag;
        !            90:                }
        !            91:        }
        !            92:        touchpath(&ep->focus); /* Make sure it is a unique pointer */
        !            93:        thefocus = tree(ep->focus); /* No copy; used for comparison only! */
        !            94:        where->mode = ep->mode;
        !            95:        where->s1 = ep->s1;
        !            96:        where->s2 = ep->s2;
        !            97:        where->s3 = ep->s3;
        !            98:        where->spflag = ep->spflag;
        !            99: }
        !           100: 
        !           101: 
        !           102: /*
        !           103:  * Incorporate the information saved about the focus.
        !           104:  */
        !           105: 
        !           106: Visible Procedure
        !           107: setfocus(tops)
        !           108:        register cell *tops;
        !           109: {
        !           110:        register cell *p;
        !           111:        register int i;
        !           112: 
        !           113:        for (p = tops, i = 0; i < yfocus; ++i, p = p->c_link) {
        !           114:                if (!p) {
        !           115: #ifndef NDEBUG
        !           116:                        debug("[Focus lost (setfocus)]");
        !           117: #endif NDEBUG
        !           118:                        return;
        !           119:                }
        !           120:        }
        !           121:        p->c_newvhole = realvhole;
        !           122:        i = multiline;
        !           123:        do {
        !           124:                p->c_newfocus = Yes;
        !           125:                p = p->c_link;
        !           126:        } while (--i > 0);
        !           127: }
        !           128: 
        !           129: 
        !           130: /*
        !           131:  * Signal that actual updata is started.
        !           132:  */
        !           133: 
        !           134: Visible Procedure
        !           135: startactupdate(nofocus)
        !           136:        bool nofocus;
        !           137: {
        !           138:        if (nofocus) {
        !           139:                multiline = 0;
        !           140:                thefocus = Nnil;
        !           141:        }
        !           142: }
        !           143: 
        !           144: 
        !           145: /*
        !           146:  * Signal the end of the actual update.
        !           147:  */
        !           148: 
        !           149: Visible Procedure
        !           150: endactupdate()
        !           151: {
        !           152: }
        !           153: 
        !           154: 
        !           155: /*
        !           156:  * Output a line of text.
        !           157:  */
        !           158: 
        !           159: Visible Procedure
        !           160: outline(p, lineno)
        !           161:        register cell *p;
        !           162:        register int lineno;
        !           163: {
        !           164:        register node n = p->c_data;
        !           165:        register int w = width(n);
        !           166:        register string buf =
        !           167:            malloc((unsigned) (p->c_newindent + 4 + (w < 0 ? linelen(n) : w)));
        !           168:                        /* some 4 extra for spflag and vhole */
        !           169:        auto string bp = buf;
        !           170:        register int i;
        !           171:        register int endarea = lineno+Space(p)-1;
        !           172: 
        !           173:        if (endarea >= winheight)
        !           174:                endarea = winheight-1;
        !           175:        for (i = p->c_newindent; i-- > 0; )
        !           176:                *bp++ = ' ';
        !           177:        if (!p->c_newfocus) {
        !           178:                smash(&bp, n, 0);
        !           179:                *bp = 0;
        !           180:        }
        !           181:        else {
        !           182:                if (multiline)
        !           183:                        smash(&bp, n, SOBIT);
        !           184:                else if (n == thefocus)
        !           185:                        focsmash(&bp, n);
        !           186:                else
        !           187:                        smash(&bp, n, 0);
        !           188:                *bp = 0;
        !           189:                for (bp = buf; *bp && !(*bp&SOBIT); ++bp)
        !           190:                        ;
        !           191:                if (*bp&SOBIT) {
        !           192:                        if (focy == Nowhere) {
        !           193:                                focx = indent + bp-buf;
        !           194:                                focy = lineno + focx/llength;
        !           195:                                focx %= llength;
        !           196:                        }
        !           197:                        if (multiline <= 1 && !(bp[1]&SOBIT))
        !           198:                                *bp &= ~SOBIT; /* Clear mask if just one char in focus */
        !           199:                }
        !           200:        }
        !           201:        trmputdata(lineno, endarea, indent, buf);
        !           202: }
        !           203: 
        !           204: 
        !           205: /*
        !           206:  * Smash -- produce a linear version of a node in a buffer (which had
        !           207:  * better be long enough!).  The buffer pointer is moved to the end of
        !           208:  * the resulting string.
        !           209:  * Care is taken to represent the focus.
        !           210:  * Characters in the focus have their upper bit set.
        !           211:  */
        !           212: 
        !           213: #define Outvhole() \
        !           214:        (where->spflag && strsmash(pbuf, " ", 0), strsmash(pbuf, "?", SOBIT))
        !           215: 
        !           216: Hidden Procedure
        !           217: focsmash(pbuf, n)
        !           218:        string *pbuf;
        !           219:        node n;
        !           220: {
        !           221:        value v;
        !           222:        string str;
        !           223:        register string *rp;
        !           224:        register int maxs2;
        !           225:        register int i;
        !           226:        register bool ok;
        !           227:        register int j;
        !           228:        register int mask;
        !           229: 
        !           230:        switch (where->mode) {
        !           231: 
        !           232:        case WHOLE:
        !           233:                smash(pbuf, n, SOBIT);
        !           234:                break;
        !           235: 
        !           236:        case ATBEGIN:
        !           237:                Outvhole();
        !           238:                smash(pbuf, n, 0);
        !           239:                break;
        !           240: 
        !           241:        case ATEND:
        !           242:                smash(pbuf, n, 0);
        !           243:                Outvhole();
        !           244:                break;
        !           245: 
        !           246:        case VHOLE:
        !           247:                if (!(where->s1&1)) {
        !           248:                        v = (value) child(n, where->s1/2);
        !           249:                        Assert(Type(v) == Tex);
        !           250:                        subsmash(pbuf, Str(v), where->s2, 0);
        !           251:                        Outvhole();
        !           252:                        strsmash(pbuf, Str(v) + where->s2, 0);
        !           253:                        break;
        !           254:                }
        !           255:                /* Else, fall through */
        !           256:        case FHOLE:
        !           257:                rp = noderepr(n);
        !           258:                maxs2 = 2*nchildren(n) + 1;
        !           259:                for (ok = Yes, i = 1; ok && i <= maxs2; ++i) {
        !           260:                        if (i&1) {
        !           261:                                if (i == where->s1) {
        !           262:                                        subsmash(pbuf, rp[i/2], where->s2, 0);
        !           263:                                        Outvhole();
        !           264:                                        if (rp[i/2])
        !           265:                                                strsmash(pbuf, rp[i/2] + where->s2, 0);
        !           266:                                }
        !           267:                                else
        !           268:                                        strsmash(pbuf, rp[i/2], 0);
        !           269:                        }
        !           270:                        else
        !           271:                                ok = chismash(pbuf, n, i/2, 0);
        !           272:                }
        !           273:                break;
        !           274: 
        !           275:        case SUBRANGE:
        !           276:                rp = noderepr(n);
        !           277:                maxs2 = 2*nchildren(n) + 1;
        !           278:                for (ok = Yes, i = 1; ok && i <= maxs2; ++i) {
        !           279:                        if (i&1) {
        !           280:                                if (i == where->s1) {
        !           281:                                        subsmash(pbuf, rp[i/2], where->s2,0);
        !           282:                                        if (rp[i/2])
        !           283:                                                subsmash(pbuf, rp[i/2] + where->s2,
        !           284:                                                        where->s3 - where->s2 + 1, SOBIT);
        !           285:                                        if (rp[i/2])
        !           286:                                                strsmash(pbuf, rp[i/2] + where->s3 + 1, 0);
        !           287:                                }
        !           288:                                else
        !           289:                                        strsmash(pbuf, rp[i/2], 0);
        !           290:                        }
        !           291:                        else if (i == where->s1) {
        !           292:                                v = (value)child(n, i/2);
        !           293:                                Assert(Type(v) == Tex);
        !           294:                                str = Str(v);
        !           295:                                subsmash(pbuf, str, where->s2, 0);
        !           296:                                subsmash(pbuf, str + where->s2, where->s3 - where->s2 + 1,
        !           297:                                        SOBIT);
        !           298:                                strsmash(pbuf, str + where->s3 + 1, 0);
        !           299:                        }
        !           300:                        else
        !           301:                                ok = chismash(pbuf, n, i/2, 0);
        !           302:                }
        !           303:                break;
        !           304: 
        !           305:        case SUBLIST:
        !           306:                for (ok = Yes, j = where->s3; j > 0; --j) {
        !           307:                        rp = noderepr(n);
        !           308:                        maxs2 = 2*nchildren(n) - 1;
        !           309:                        for (i = 1; ok && i <= maxs2; ++i) {
        !           310:                                if (i&1)
        !           311:                                        strsmash(pbuf, rp[i/2], SOBIT);
        !           312:                                else
        !           313:                                        ok = chismash(pbuf, n, i/2, SOBIT);
        !           314:                        }
        !           315:                        if (ok)
        !           316:                                n = lastchild(n);
        !           317:                }
        !           318:                if (ok)
        !           319:                        smash(pbuf, n, 0);
        !           320:                break;
        !           321: 
        !           322:        case SUBSET:
        !           323:                rp = noderepr(n);
        !           324:                maxs2 = 2*nchildren(n) + 1;
        !           325:                mask = 0;
        !           326:                for (ok = Yes, i = 1; ok && i <= maxs2; ++i) {
        !           327:                        if (i == where->s1)
        !           328:                                mask = SOBIT;
        !           329:                        if (i&1)
        !           330:                                strsmash(pbuf, rp[i/2], mask);
        !           331:                        else
        !           332:                                ok = chismash(pbuf, n, i/2, mask);
        !           333:                        if (i == where->s2)
        !           334:                                mask = 0;
        !           335:                }
        !           336:                break;
        !           337: 
        !           338:        default:
        !           339:                Abort();
        !           340:        }
        !           341: }
        !           342: 
        !           343: Hidden Procedure
        !           344: smash(pbuf, n, mask)
        !           345:        register string *pbuf;
        !           346:        register node n;
        !           347:        register int mask;
        !           348: {
        !           349:        register string *rp;
        !           350:        register int i;
        !           351:        register int nch;
        !           352: 
        !           353:        rp = noderepr(n);
        !           354:        strsmash(pbuf, rp[0], mask);
        !           355:        nch = nchildren(n);
        !           356:        for (i = 1; i <= nch; ++i) {
        !           357:                if (!chismash(pbuf, n, i, mask))
        !           358:                        break;
        !           359:                strsmash(pbuf, rp[i], mask);
        !           360:        }
        !           361: }
        !           362: 
        !           363: Hidden Procedure
        !           364: strsmash(pbuf, str, mask)
        !           365:        register string *pbuf;
        !           366:        register string str;
        !           367:        register int mask;
        !           368: {
        !           369:        if (!str)
        !           370:                return;
        !           371:        for (; *str; ++str) {
        !           372:                if (isprint(*str) || *str == ' ')
        !           373:                        **pbuf = *str|mask, ++*pbuf;
        !           374:        }
        !           375: }
        !           376: 
        !           377: Hidden Procedure
        !           378: subsmash(pbuf, str, len, mask)
        !           379:        register string *pbuf;
        !           380:        register string str;
        !           381:        register int len;
        !           382:        register int mask;
        !           383: {
        !           384:        if (!str)
        !           385:                return;
        !           386:        for (; len > 0 && *str; --len, ++str) {
        !           387:                if (isprint(*str) || *str == ' ')
        !           388:                        **pbuf = *str|mask, ++*pbuf;
        !           389:        }
        !           390: }
        !           391: 
        !           392: 
        !           393: /*
        !           394:  * Smash a node's child.
        !           395:  * Return No if it contained a newline (to stop the parent).
        !           396:  */
        !           397: 
        !           398: Hidden bool
        !           399: chismash(pbuf, n, i, mask)
        !           400:        register string *pbuf;
        !           401:        register node n;
        !           402:        register int i;
        !           403: {
        !           404:        register node nn = child(n, i);
        !           405:        register int w;
        !           406: 
        !           407:        if (Type(nn) == Tex) {
        !           408:                strsmash(pbuf, Str((value)nn), mask);
        !           409:                return Yes;
        !           410:        }
        !           411:        w = width(nn);
        !           412:        if (w < 0 && Fw_negative(noderepr(nn)[0]))
        !           413:                return No;
        !           414:        if (nn == thefocus)
        !           415:                focsmash(pbuf, nn);
        !           416:        else
        !           417:                smash(pbuf, nn, mask);
        !           418:        return w >= 0;
        !           419: }

unix.superglobalmegacorp.com

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