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