Annotation of 43BSD/contrib/B/src/bed/outp.c, revision 1.1.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.