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: }
Defined functions
fwidth
defined in line
116; used 26 times
- in /usr/src/new/PORT/B/src/bed/deco.c line
145,
191,
259,
349
- in /usr/src/new/PORT/B/src/bed/goto.c line
280
- in /usr/src/new/PORT/B/src/bed/gram.h line
38
- in /usr/src/new/PORT/B/src/bed/ins2.c line
309
- in /usr/src/new/PORT/B/src/bed/line.c line
61(2),
83,
133,
217,
227
- in /usr/src/new/PORT/B/src/bed/que1.c line
205
- in /usr/src/new/PORT/B/src/bed/que2.c line
155,
407,
489
- in /usr/src/new/PORT/B/src/bed/supr.c line
27,
102,
382,
416,
463,
485,
598,
698,
839
Defined variables
rcsid
defined in line
2;
never used