Annotation of 43BSDTahoe/new/B/src/bed/line.c, revision 1.1

1.1     ! root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
        !             2: static char rcsid[] = "$Header: line.c,v 2.4 85/08/22 16:04:53 timo Exp $";
        !             3: 
        !             4: /*
        !             5:  * B editor -- Routines for treating the parse tree as a sequence of lines.
        !             6:  *
        !             7:  * WARNING: The routines in this file (and many others!) assume that a
        !             8:  * `newline' can only occur in the zero'th representation string of a node
        !             9:  * (i.e., rp[0]).
        !            10:  */
        !            11: 
        !            12: #include "b.h"
        !            13: #include "bobj.h"
        !            14: #include "node.h"
        !            15: #include "gram.h"
        !            16: #include "supr.h"
        !            17: 
        !            18: 
        !            19: /*
        !            20:  * Compute equality of subtrees, based on common descent.
        !            21:  * Strings are not checked for characterwise equality, but must
        !            22:  * be the same pointer; other nodes must have the same symbol and
        !            23:  * their children must be equal in this sense (equal pointers are
        !            24:  * always used as a shortcut).
        !            25:  *
        !            26:  * (Used by screen update algorithm only.)
        !            27:  */
        !            28: 
        !            29: Visible bool
        !            30: eqlines(n1, n2)
        !            31:        node n1;
        !            32:        node n2;
        !            33: {
        !            34:        register node nn1;
        !            35:        register node nn2;
        !            36:        register int w1;
        !            37:        register int w2;
        !            38:        register int nch;
        !            39:        register int i;
        !            40: 
        !            41:        if (n1 == n2)
        !            42:                return Yes;
        !            43:        if (Type(n1) != Nod || Type(n2) != Nod)
        !            44:                return No;
        !            45:        if (symbol(n1) != symbol(n2))
        !            46:                return No;
        !            47:        nch = nchildren(n1);
        !            48:        Assert(nch == nchildren(n2));
        !            49:        for (i = 1; i <= nch; ++i) {
        !            50:                nn1 = child(n1, i);
        !            51:                nn2 = child(n2, i);
        !            52:                w1 = width(nn1);
        !            53:                w2 = width(nn2);
        !            54:                if (w1 >= 0 && w2 >= 0) {
        !            55:                        if (!eqlines(nn1, nn2))
        !            56:                                return No;
        !            57:                }
        !            58:                else {
        !            59:                        if (nn1 == nn2)
        !            60:                                return Yes;
        !            61:                        if (fwidth(noderepr(nn1)[0]) < 0 || fwidth(noderepr(nn2)[0]) < 0)
        !            62:                                return linelen(n1) == linelen(n2);
        !            63:                        return eqlines(nn1, nn2);
        !            64:                }
        !            65:        }
        !            66:        return Yes;
        !            67: }
        !            68: 
        !            69: 
        !            70: /*
        !            71:  * Compute the length of the line beginning at the current node.
        !            72:  */
        !            73:  
        !            74: Visible int
        !            75: linelen(n)
        !            76:        node n;
        !            77: {
        !            78:        register node nn;
        !            79:        register string *rp = noderepr(n);
        !            80:        register int w;
        !            81:        register int nch = nchildren(n);
        !            82:        register int i;
        !            83:        register int len = fwidth(rp[0]);
        !            84: 
        !            85:        if (len < 0)
        !            86:                len = 0;
        !            87:        for (i = 1; i <= nch; ++i) {
        !            88:                nn = child(n, i);
        !            89:                w = width(nn);
        !            90:                if (w >= 0)
        !            91:                        len += w;
        !            92:                else {
        !            93:                        n = nn;
        !            94:                        i = 0;
        !            95:                        nch = nchildren(n);
        !            96:                        rp = noderepr(n);
        !            97:                }
        !            98:                w = Fwidth(rp[i]);
        !            99:                if (w < 0)
        !           100:                        break;
        !           101:                len += w;
        !           102:        }
        !           103:        return len;
        !           104: }
        !           105: 
        !           106: 
        !           107: /*
        !           108:  * Move the focus to the next line.
        !           109:  * NB: This is a building block for use in the 'show' module;
        !           110:  * it cannot set ep->mode or call higher() properly!
        !           111:  */
        !           112: 
        !           113: Visible bool
        !           114: nextline(pp)
        !           115:        register path *pp;
        !           116: {
        !           117:        register node n;
        !           118:        register node nn;
        !           119:        register int w;
        !           120:        register int nch;
        !           121:        register int i = 0;
        !           122: 
        !           123:        for (;;) {
        !           124:                n = tree(*pp);
        !           125:                if (width(n) < 0) {
        !           126:                        nch = nchildren(n);
        !           127:                        while (++i <= nch) {
        !           128:                                nn = child(n, i);
        !           129:                                w = width(nn);
        !           130:                                if (w < 0) {
        !           131:                                        downi(pp, i) || Abort();
        !           132:                                        n = tree(*pp);
        !           133:                                        if (fwidth(noderepr(n)[0]) < 0)
        !           134:                                                return Yes;
        !           135:                                        nch = nchildren(n);
        !           136:                                        i = 0;
        !           137:                                }
        !           138:                        }
        !           139:                }
        !           140:                /* Must go upward in the tree */
        !           141:                i = ichild(*pp);
        !           142:                if (!up(pp))
        !           143:                        return No;
        !           144:        }
        !           145: }
        !           146: 
        !           147: 
        !           148: /*
        !           149:  * Compute the current line number.  If the current node begins with
        !           150:  * a `newline', add one because the first character is actually
        !           151:  * on the next line.
        !           152:  */
        !           153: 
        !           154: Visible int
        !           155: lineno(ep)
        !           156:        register environ *ep;
        !           157: {
        !           158:        register int y;
        !           159: 
        !           160:        y = -focoffset(ep);
        !           161:        if (y < 0)
        !           162:                y = 0;
        !           163:        if (focchar(ep) == '\n')
        !           164:                ++y;
        !           165:        return y + Ycoord(ep->focus);
        !           166: }
        !           167: 
        !           168: /*
        !           169:  * Similarly, compute the current column number.
        !           170:  * (Hope the abovementioned trick isn't necessary.)
        !           171:  */
        !           172: 
        !           173: Visible int
        !           174: colno(ep)
        !           175:        environ *ep;
        !           176: {
        !           177:        int x= focoffset(ep);
        !           178: 
        !           179:        if (x < 0)
        !           180:                x= 0; /* In fact, give up */
        !           181:        return x + Xcoord(ep->focus);
        !           182: }
        !           183: 
        !           184: 
        !           185: /*
        !           186:  * Make the focus exactly one line wide (if at all possible).
        !           187:  */
        !           188: 
        !           189: Visible Procedure
        !           190: oneline(ep)
        !           191:        register environ *ep;
        !           192: {
        !           193:        register node n;
        !           194:        node nn;
        !           195:        register string *rp;
        !           196:        register int s1;
        !           197:        register int s2;
        !           198:        register int len;
        !           199:        int ich;
        !           200:        int nch;
        !           201: 
        !           202:        ich = 1;
        !           203:        while (width(tree(ep->focus)) >= 0) {
        !           204:                ich = ichild(ep->focus);
        !           205:                if (!up(&ep->focus)) {
        !           206:                        ep->mode = WHOLE;
        !           207:                        higher(ep);
        !           208:                        return;
        !           209:                }
        !           210:        }
        !           211:        higher(ep);
        !           212:        n = tree(ep->focus);
        !           213:        nch = nchildren(n);
        !           214:        rp = noderepr(n);
        !           215:        for (s1 = 2*ich-1; s1 >= 1; --s1) {
        !           216:                if (s1&1)
        !           217:                        len = fwidth(rp[s1/2]);
        !           218:                else {
        !           219:                        nn = child(n, s1/2);
        !           220:                        len = width(nn);
        !           221:                }
        !           222:                if (len < 0)
        !           223:                        break;
        !           224:        }
        !           225:        for (s2 = 2*ich+1; s2 <= 2*nch+1; ++s2) {
        !           226:                if (s2&1)
        !           227:                        len = fwidth(rp[s2/2]);
        !           228:                else {
        !           229:                        nn = child(n, s2/2);
        !           230:                        len = width(nn);
        !           231:                }
        !           232:                if (len < 0)
        !           233:                        break;
        !           234:        }
        !           235:        ep->mode = SUBSET;
        !           236:        ep->s1 = s1+1;
        !           237:        ep->s2 = s2-1;
        !           238: }

unix.superglobalmegacorp.com

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