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

1.1     ! root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
        !             2: static char rcsid[] = "$Header: eval.c,v 2.3 84/07/19 11:47:18 guido Exp $";
        !             3: 
        !             4: /*
        !             5:  * B editor -- Width attribute evaluation.
        !             6:  */
        !             7: 
        !             8: #include "b.h"
        !             9: #include "node.h"
        !            10: #include "gram.h"
        !            11: #include "eval.h"
        !            12: 
        !            13: 
        !            14: /*
        !            15:  * The following convention is used throughout the editor to indicate
        !            16:  * the sizes of objects.
        !            17:  * - A zero or positive `width' value means the object contains no
        !            18:  *   linefeeds.  The width is counted in characters.
        !            19:  * - A negative `width' means the object (or its children) contains
        !            20:  *   at leasty one linefeed (return is treated as a linefeed here).
        !            21:  *   The number of linefeeds is -width.
        !            22:  *   There is no indication whether the object fits on that number of
        !            23:  *   physical lines, as logical lines may have arbitrary length.
        !            24:  *
        !            25:  * For coordinates the following convention is used.
        !            26:  * (Note that, in accordance to the convention in curses(3), the
        !            27:  * `y' coordinate always precedes the `x' coorxdinate.)
        !            28:  * - `Y' is the line number, counted from the beginning of the unit.
        !            29:  *   These are logical lines rather than physical lines.
        !            30:  *   The first line has line number 0.
        !            31:  * - `X' is the column number.  The first column is 0.  For x < 0,
        !            32:  *   see the important notice below.
        !            33:  * - `Level' is the indentation level, indicating where a new line
        !            34:  *   would start if inserted at the current position.
        !            35:  *   The initial `x' position of such a line is `level*TABS'.
        !            36:  *
        !            37:  * ***** IMPORTANT NOTICE *****
        !            38:  * A special case is x = -1.  This means that the current x position is
        !            39:  * unknown.  Further output on the same line is suppressed, until a
        !            40:  * linefeed is encountered.  This feature is necessary because while
        !            41:  * calculating coordinates, when an object has width < 0, only the y
        !            42:  * coordinate of the end of that object is known.  In this case, the
        !            43:  * next non-empty object MUST START WITH A LINEFEED, or it will not
        !            44:  * be visible on the screen (in practice, a space is sometimes present
        !            45:  * in the parse tree which is not shown then).
        !            46:  */
        !            47: 
        !            48: 
        !            49: /*
        !            50:  * Compute the (y, x) coordinates and indent level just before
        !            51:  * the beginning of the j'th child, if the current node starts
        !            52:  * at the initial values of (y, x) and level.
        !            53:  */
        !            54: 
        !            55: Visible Procedure
        !            56: evalcoord(n, jch, py, px, plevel)
        !            57:        register node n;
        !            58:        register int jch;
        !            59:        int *py;
        !            60:        int *px;
        !            61:        int *plevel;
        !            62: {
        !            63:        node nn;
        !            64:        register int i;
        !            65:        register string *rp = noderepr(n);
        !            66:        register int k;
        !            67:        register int y = 0;
        !            68:        int x = *px;
        !            69:        int level = *plevel;
        !            70:        int nch = Type(n) == Tex ? 0 : nchildren(n);
        !            71: 
        !            72:        if (jch > nch)
        !            73:                jch = nch+1;
        !            74:        for (i = 0; i < jch; ++i) {
        !            75:                if (i) {
        !            76:                        nn = child(n, i);
        !            77:                        k = width(nn);
        !            78:                        if (k < 0) {
        !            79:                                y += -k;
        !            80:                                x = k;
        !            81:                        }
        !            82:                        else if (x >= 0)
        !            83:                                x += k;
        !            84:                }
        !            85:                k = Fwidth(rp[i]);
        !            86:                if (k < 0) {
        !            87:                        y += -k;
        !            88:                        x = rp[i][0] == '\r' ? 0 : TABS*level;
        !            89:                        x += strlen(rp[i]) - 1;
        !            90:                }
        !            91:                else {
        !            92:                        if (x >= 0)
        !            93:                                x += k;
        !            94:                        if (rp[i]) {
        !            95:                                if (rp[i][k] == '\t')
        !            96:                                        ++level;
        !            97:                                else if (rp[i][k] == '\b')
        !            98:                                        --level;
        !            99:                        }
        !           100:                }
        !           101:        }
        !           102: 
        !           103:        *py += y;
        !           104:        *px = x;
        !           105:        *plevel = level;
        !           106: }
        !           107: 
        !           108: 
        !           109: /*
        !           110:  * Yield the width of a piece of fixed text as found in a node's repr,
        !           111:  * excluding \b or \t.  If \n or \r is found, -1 is returned.
        !           112:  * It assumes that \n or \r only occur as first
        !           113:  * character, and \b or \t only as last.
        !           114:  */
        !           115: 
        !           116: Visible int
        !           117: fwidth(str)
        !           118:        register string str;
        !           119: {
        !           120:        register int c;
        !           121:        register int n = 0;
        !           122: 
        !           123:        if (!str)
        !           124:                return 0;
        !           125:        c = str[0];
        !           126:        if (c == '\r' || c == '\n')
        !           127:                return -1;
        !           128:        for (; c; c = *++str)
        !           129:                ++n;
        !           130:        if (n > 0) {
        !           131:                c = str[-1];
        !           132:                if (c == '\t' || c == '\b')
        !           133:                        --n;
        !           134:        }
        !           135:        return n;
        !           136: }
        !           137: 
        !           138: 
        !           139: /*
        !           140:  * Evaluate the width of node n, assuming the widths of its children
        !           141:  * have correctly been calculated.
        !           142:  */
        !           143: 
        !           144: Visible int
        !           145: evalwidth(n)
        !           146:        register node n;
        !           147: {
        !           148:        register int w;
        !           149:        register int i;
        !           150:        register string *rp;
        !           151:        register int y = 0;
        !           152:        register int x = 0;
        !           153:        register int nch;
        !           154:        register node nn;
        !           155: 
        !           156:        rp = noderepr(n);
        !           157:        nch = Type(n) == Tex ? 0 : nchildren(n);
        !           158:        for (i = 0; i <= nch; ++i) {
        !           159:                if (i) {
        !           160:                        nn = child(n, i);
        !           161:                        w = width(nn);
        !           162:                        if (w < 0) {
        !           163:                                y += -w;
        !           164:                                x = w;
        !           165:                        }
        !           166:                        else
        !           167:                                x += w;
        !           168:                }
        !           169:                w = Fwidth(rp[i]);
        !           170:                if (w < 0) {
        !           171:                        y += -w;
        !           172:                        x = 0;
        !           173:                }
        !           174:                else
        !           175:                        x += w;
        !           176:        }
        !           177:        if (y > 0)
        !           178:                return -y;
        !           179:        return x;
        !           180: }

unix.superglobalmegacorp.com

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