Blame


1 5f1cf8e6 2004-05-16 devnull #include <math.h>
2 5f1cf8e6 2004-05-16 devnull #include "misc.h"
3 5f1cf8e6 2004-05-16 devnull #include "slug.h"
4 5f1cf8e6 2004-05-16 devnull #include "range.h"
5 5f1cf8e6 2004-05-16 devnull
6 5f1cf8e6 2004-05-16 devnull void sprange::reheight(int *cv, int *mv)
7 5f1cf8e6 2004-05-16 devnull {
8 5f1cf8e6 2004-05-16 devnull if (*cv != *mv)
9 5f1cf8e6 2004-05-16 devnull ERROR "slug %d: an imbedded SP, line %d\n",
10 5f1cf8e6 2004-05-16 devnull first->serialno(), first->lineno() WARNING;
11 5f1cf8e6 2004-05-16 devnull *cv += dv;
12 5f1cf8e6 2004-05-16 devnull *mv = max(*mv, *cv);
13 5f1cf8e6 2004-05-16 devnull }
14 5f1cf8e6 2004-05-16 devnull
15 5f1cf8e6 2004-05-16 devnull void sprange::rerawht(int *cv, int *mv)
16 5f1cf8e6 2004-05-16 devnull {
17 5f1cf8e6 2004-05-16 devnull *cv += rawht();
18 5f1cf8e6 2004-05-16 devnull *mv = max(*mv, *cv);
19 5f1cf8e6 2004-05-16 devnull }
20 5f1cf8e6 2004-05-16 devnull
21 5f1cf8e6 2004-05-16 devnull void nestrange::restore()
22 5f1cf8e6 2004-05-16 devnull {
23 5f1cf8e6 2004-05-16 devnull subrange->restoreall();
24 5f1cf8e6 2004-05-16 devnull }
25 5f1cf8e6 2004-05-16 devnull
26 5f1cf8e6 2004-05-16 devnull void stream::freeall() // not a destructor; called explicitly
27 5f1cf8e6 2004-05-16 devnull {
28 5f1cf8e6 2004-05-16 devnull strblk *p, *q;
29 5f1cf8e6 2004-05-16 devnull for (p = first; p; p = q) {
30 5f1cf8e6 2004-05-16 devnull q = p->next;
31 5f1cf8e6 2004-05-16 devnull delete p;
32 5f1cf8e6 2004-05-16 devnull }
33 5f1cf8e6 2004-05-16 devnull first = last = curr = 0;
34 5f1cf8e6 2004-05-16 devnull }
35 5f1cf8e6 2004-05-16 devnull
36 5f1cf8e6 2004-05-16 devnull void stream::dump()
37 5f1cf8e6 2004-05-16 devnull {
38 5f1cf8e6 2004-05-16 devnull for (stream s = *this; s.more(); s.advance())
39 5f1cf8e6 2004-05-16 devnull s.current()->dump();
40 5f1cf8e6 2004-05-16 devnull }
41 5f1cf8e6 2004-05-16 devnull
42 5f1cf8e6 2004-05-16 devnull void stream::rdump()
43 5f1cf8e6 2004-05-16 devnull {
44 5f1cf8e6 2004-05-16 devnull for (stream s = *this; s.more(); s.advance())
45 5f1cf8e6 2004-05-16 devnull s.current()->rdump();
46 5f1cf8e6 2004-05-16 devnull }
47 5f1cf8e6 2004-05-16 devnull
48 5f1cf8e6 2004-05-16 devnull int stream::restoreall()
49 5f1cf8e6 2004-05-16 devnull {
50 5f1cf8e6 2004-05-16 devnull for (stream s = *this; s.more(); s.advance())
51 5f1cf8e6 2004-05-16 devnull s.current()->restore();
52 5f1cf8e6 2004-05-16 devnull return measure(this);
53 5f1cf8e6 2004-05-16 devnull }
54 5f1cf8e6 2004-05-16 devnull
55 5f1cf8e6 2004-05-16 devnull range *stream::append(range *r)
56 5f1cf8e6 2004-05-16 devnull {
57 5f1cf8e6 2004-05-16 devnull if (last == 0)
58 5f1cf8e6 2004-05-16 devnull curr = first = last = new strblk;
59 5f1cf8e6 2004-05-16 devnull else {
60 5f1cf8e6 2004-05-16 devnull last->next = new strblk;
61 5f1cf8e6 2004-05-16 devnull last = last->next;
62 5f1cf8e6 2004-05-16 devnull if (curr == 0)
63 5f1cf8e6 2004-05-16 devnull curr = last;
64 5f1cf8e6 2004-05-16 devnull }
65 5f1cf8e6 2004-05-16 devnull last->next = 0;
66 5f1cf8e6 2004-05-16 devnull return last->rp = r;
67 5f1cf8e6 2004-05-16 devnull }
68 5f1cf8e6 2004-05-16 devnull
69 5f1cf8e6 2004-05-16 devnull void stream::split() // duplicate current() range
70 5f1cf8e6 2004-05-16 devnull {
71 5f1cf8e6 2004-05-16 devnull strblk *s2 = new strblk;
72 5f1cf8e6 2004-05-16 devnull range *r2 = curr->rp->clone();
73 5f1cf8e6 2004-05-16 devnull s2->rp = r2;
74 5f1cf8e6 2004-05-16 devnull s2->next = curr->next;
75 5f1cf8e6 2004-05-16 devnull if (last == curr)
76 5f1cf8e6 2004-05-16 devnull last = s2;
77 5f1cf8e6 2004-05-16 devnull curr->next = s2;
78 5f1cf8e6 2004-05-16 devnull curr->rp->killkids(); // children only in the 2nd one
79 5f1cf8e6 2004-05-16 devnull // r2->crosslink(r1);
80 5f1cf8e6 2004-05-16 devnull }
81 5f1cf8e6 2004-05-16 devnull
82 5f1cf8e6 2004-05-16 devnull int stream::height()
83 5f1cf8e6 2004-05-16 devnull {
84 5f1cf8e6 2004-05-16 devnull int h;
85 5f1cf8e6 2004-05-16 devnull stream s = *this;
86 5f1cf8e6 2004-05-16 devnull for (h = 0; s.more(); s.advance())
87 5f1cf8e6 2004-05-16 devnull h += s.current()->height();
88 5f1cf8e6 2004-05-16 devnull return h;
89 5f1cf8e6 2004-05-16 devnull }
90 5f1cf8e6 2004-05-16 devnull
91 5f1cf8e6 2004-05-16 devnull int stream::rawht()
92 5f1cf8e6 2004-05-16 devnull {
93 5f1cf8e6 2004-05-16 devnull int h;
94 5f1cf8e6 2004-05-16 devnull stream s = *this;
95 5f1cf8e6 2004-05-16 devnull for (h = 0; s.more(); s.advance())
96 5f1cf8e6 2004-05-16 devnull h += s.current()->rawht();
97 5f1cf8e6 2004-05-16 devnull return h;
98 5f1cf8e6 2004-05-16 devnull }
99 5f1cf8e6 2004-05-16 devnull
100 5f1cf8e6 2004-05-16 devnull int measure(stream *sp) // record high-water mark of stream
101 5f1cf8e6 2004-05-16 devnull { // sets nested stream heights
102 5f1cf8e6 2004-05-16 devnull stream s = *sp;
103 5f1cf8e6 2004-05-16 devnull int curv, maxv;
104 5f1cf8e6 2004-05-16 devnull for (maxv = curv = 0; s.more(); s.advance())
105 5f1cf8e6 2004-05-16 devnull s.current()->reheight(&curv, &maxv);
106 5f1cf8e6 2004-05-16 devnull return maxv;
107 5f1cf8e6 2004-05-16 devnull }
108 5f1cf8e6 2004-05-16 devnull
109 5f1cf8e6 2004-05-16 devnull int rawmeasure(stream *sp)
110 5f1cf8e6 2004-05-16 devnull {
111 5f1cf8e6 2004-05-16 devnull stream s = *sp;
112 5f1cf8e6 2004-05-16 devnull int curv, maxv;
113 5f1cf8e6 2004-05-16 devnull for (maxv = curv = 0; s.more(); s.advance())
114 5f1cf8e6 2004-05-16 devnull s.current()->rerawht(&curv, &maxv);
115 5f1cf8e6 2004-05-16 devnull return maxv;
116 5f1cf8e6 2004-05-16 devnull }
117 5f1cf8e6 2004-05-16 devnull
118 5f1cf8e6 2004-05-16 devnull void nestrange::rdump()
119 5f1cf8e6 2004-05-16 devnull {
120 5f1cf8e6 2004-05-16 devnull dump();
121 5f1cf8e6 2004-05-16 devnull if (subrange)
122 5f1cf8e6 2004-05-16 devnull subrange->rdump();
123 5f1cf8e6 2004-05-16 devnull }
124 5f1cf8e6 2004-05-16 devnull
125 5f1cf8e6 2004-05-16 devnull void nestrange::killkids()
126 5f1cf8e6 2004-05-16 devnull {
127 5f1cf8e6 2004-05-16 devnull subrange = new stream;
128 5f1cf8e6 2004-05-16 devnull }
129 5f1cf8e6 2004-05-16 devnull
130 5f1cf8e6 2004-05-16 devnull int nestrange::print(int curv, int col)
131 5f1cf8e6 2004-05-16 devnull {
132 5f1cf8e6 2004-05-16 devnull int ocurv = curv;
133 5f1cf8e6 2004-05-16 devnull first->slugout(col);
134 5f1cf8e6 2004-05-16 devnull for (stream s = *subrange; s.more(); s.advance())
135 5f1cf8e6 2004-05-16 devnull curv = s.current()->print(curv, col);
136 5f1cf8e6 2004-05-16 devnull return ocurv + height();
137 5f1cf8e6 2004-05-16 devnull }
138 5f1cf8e6 2004-05-16 devnull
139 5f1cf8e6 2004-05-16 devnull #define macroclone(rangetype) range *rangetype::clone() {\
140 5f1cf8e6 2004-05-16 devnull rangetype *t = new rangetype;\
141 5f1cf8e6 2004-05-16 devnull *t = *this;\
142 5f1cf8e6 2004-05-16 devnull return t; }
143 5f1cf8e6 2004-05-16 devnull
144 5f1cf8e6 2004-05-16 devnull macroclone(usrange);
145 5f1cf8e6 2004-05-16 devnull macroclone(ufrange);
146 5f1cf8e6 2004-05-16 devnull macroclone(bfrange);
147 5f1cf8e6 2004-05-16 devnull
148 5f1cf8e6 2004-05-16 devnull #undef macroclone
149 5f1cf8e6 2004-05-16 devnull
150 5f1cf8e6 2004-05-16 devnull #define macropickgoal(rangetype) void rangetype::pickgoal(int acv, double scale) {\
151 5f1cf8e6 2004-05-16 devnull if (scale > 1) {\
152 5f1cf8e6 2004-05-16 devnull goalV = (int)(scale*goalV);\
153 5f1cf8e6 2004-05-16 devnull goal2 = (int)(scale*goal2);\
154 5f1cf8e6 2004-05-16 devnull }\
155 5f1cf8e6 2004-05-16 devnull if (abs(acv - goalV) > abs(acv-goal2))\
156 5f1cf8e6 2004-05-16 devnull goalV = goal2; }
157 5f1cf8e6 2004-05-16 devnull
158 5f1cf8e6 2004-05-16 devnull macropickgoal(ufrange)
159 5f1cf8e6 2004-05-16 devnull macropickgoal(bfrange)
160 5f1cf8e6 2004-05-16 devnull
161 5f1cf8e6 2004-05-16 devnull #undef macropickgoal
162 5f1cf8e6 2004-05-16 devnull
163 5f1cf8e6 2004-05-16 devnull range *generator::next()
164 5f1cf8e6 2004-05-16 devnull {
165 5f1cf8e6 2004-05-16 devnull range *r;
166 5f1cf8e6 2004-05-16 devnull if (child) {
167 5f1cf8e6 2004-05-16 devnull if ((r = child->next()) != 0)
168 5f1cf8e6 2004-05-16 devnull return r;
169 5f1cf8e6 2004-05-16 devnull delete child;
170 5f1cf8e6 2004-05-16 devnull child = 0;
171 5f1cf8e6 2004-05-16 devnull }
172 5f1cf8e6 2004-05-16 devnull if (!s.more())
173 5f1cf8e6 2004-05-16 devnull return 0;
174 5f1cf8e6 2004-05-16 devnull r = s.current();
175 5f1cf8e6 2004-05-16 devnull if (r->isnested())
176 5f1cf8e6 2004-05-16 devnull child = new generator(r->children());
177 5f1cf8e6 2004-05-16 devnull s.advance();
178 5f1cf8e6 2004-05-16 devnull return r;
179 5f1cf8e6 2004-05-16 devnull }
180 5f1cf8e6 2004-05-16 devnull
181 5f1cf8e6 2004-05-16 devnull range *queue::enqueue(range *r)
182 5f1cf8e6 2004-05-16 devnull {
183 5f1cf8e6 2004-05-16 devnull if (dbg & 8)
184 5f1cf8e6 2004-05-16 devnull printf("#entering queue::enqueue()\n");
185 5f1cf8e6 2004-05-16 devnull check("queue::enqueue");
186 5f1cf8e6 2004-05-16 devnull if (!last || last->rp->serialno() < r->serialno()) // common case
187 5f1cf8e6 2004-05-16 devnull return append(r);
188 5f1cf8e6 2004-05-16 devnull if (dbg & 8)
189 5f1cf8e6 2004-05-16 devnull printf("#queue::enqueue() pushing back\n");
190 5f1cf8e6 2004-05-16 devnull newguy = new strblk;
191 5f1cf8e6 2004-05-16 devnull newguy->rp = r;
192 5f1cf8e6 2004-05-16 devnull if (r->serialno() < first->rp->serialno()) {
193 5f1cf8e6 2004-05-16 devnull newguy->next = first;
194 5f1cf8e6 2004-05-16 devnull curr = first = newguy;
195 5f1cf8e6 2004-05-16 devnull return newguy->rp;
196 5f1cf8e6 2004-05-16 devnull }
197 5f1cf8e6 2004-05-16 devnull if (dbg & 8)
198 5f1cf8e6 2004-05-16 devnull printf("#queue::enqueue() searching down queue\n");
199 5f1cf8e6 2004-05-16 devnull for (curr = first;
200 5f1cf8e6 2004-05-16 devnull next() && next()->serialno() < r->serialno();
201 5f1cf8e6 2004-05-16 devnull curr = curr->next)
202 5f1cf8e6 2004-05-16 devnull ;
203 5f1cf8e6 2004-05-16 devnull newguy->next = curr->next;
204 5f1cf8e6 2004-05-16 devnull curr->next = newguy;
205 5f1cf8e6 2004-05-16 devnull curr = first; // restore important queue condition
206 5f1cf8e6 2004-05-16 devnull return newguy->rp;
207 5f1cf8e6 2004-05-16 devnull }
208 5f1cf8e6 2004-05-16 devnull
209 5f1cf8e6 2004-05-16 devnull range *queue::dequeue()
210 5f1cf8e6 2004-05-16 devnull {
211 5f1cf8e6 2004-05-16 devnull if (dbg & 8)
212 5f1cf8e6 2004-05-16 devnull printf("#entering queue::dequeue()\n");
213 5f1cf8e6 2004-05-16 devnull check("queue::dequeue");
214 5f1cf8e6 2004-05-16 devnull curr = first->next;
215 5f1cf8e6 2004-05-16 devnull range *retval = first->rp;
216 5f1cf8e6 2004-05-16 devnull delete first;
217 5f1cf8e6 2004-05-16 devnull first = curr;
218 5f1cf8e6 2004-05-16 devnull if (!curr)
219 5f1cf8e6 2004-05-16 devnull last = 0;
220 5f1cf8e6 2004-05-16 devnull return retval;
221 5f1cf8e6 2004-05-16 devnull }
222 5f1cf8e6 2004-05-16 devnull
223 5f1cf8e6 2004-05-16 devnull // ================================================================================
224 5f1cf8e6 2004-05-16 devnull
225 5f1cf8e6 2004-05-16 devnull // functions that munge the troff output stored in slugs[]
226 5f1cf8e6 2004-05-16 devnull
227 5f1cf8e6 2004-05-16 devnull // ================================================================================
228 5f1cf8e6 2004-05-16 devnull
229 5f1cf8e6 2004-05-16 devnull static void doprefix(FILE *fp) // copy 1st "x" commands to output
230 5f1cf8e6 2004-05-16 devnull {
231 5f1cf8e6 2004-05-16 devnull int c;
232 5f1cf8e6 2004-05-16 devnull
233 5f1cf8e6 2004-05-16 devnull while ((c = getc(fp)) != EOF) {
234 5f1cf8e6 2004-05-16 devnull if (c != 'x') {
235 5f1cf8e6 2004-05-16 devnull ungetc(c, fp);
236 5f1cf8e6 2004-05-16 devnull break;
237 5f1cf8e6 2004-05-16 devnull }
238 5f1cf8e6 2004-05-16 devnull putchar(c);
239 5f1cf8e6 2004-05-16 devnull do {
240 5f1cf8e6 2004-05-16 devnull putchar(c = getc(fp));
241 5f1cf8e6 2004-05-16 devnull } while (c != '\n');
242 5f1cf8e6 2004-05-16 devnull linenum++;
243 5f1cf8e6 2004-05-16 devnull }
244 5f1cf8e6 2004-05-16 devnull // printf("x font 1 R\n"); // horrible kludge: ensure a font for first f1 command
245 5f1cf8e6 2004-05-16 devnull }
246 5f1cf8e6 2004-05-16 devnull
247 5f1cf8e6 2004-05-16 devnull #define DELTASLUGS 15000
248 5f1cf8e6 2004-05-16 devnull
249 5f1cf8e6 2004-05-16 devnull static slug *slugs = 0;
250 5f1cf8e6 2004-05-16 devnull static int nslugs = 0; // slugs has nslugs slots
251 5f1cf8e6 2004-05-16 devnull static slug *slugp = 0; // next free slug in slugs
252 5f1cf8e6 2004-05-16 devnull
253 5f1cf8e6 2004-05-16 devnull static void readslugs(FILE *fp)
254 5f1cf8e6 2004-05-16 devnull {
255 5f1cf8e6 2004-05-16 devnull if ((slugs = (slug *) malloc((nslugs = DELTASLUGS)*sizeof(slug))) == NULL)
256 5f1cf8e6 2004-05-16 devnull ERROR "no room for %d-slug array\n", nslugs FATAL;
257 5f1cf8e6 2004-05-16 devnull slugp = slugs;
258 5f1cf8e6 2004-05-16 devnull for (slugp = slugs; ; slugp++) {
259 5f1cf8e6 2004-05-16 devnull if (slugp >= slugs+nslugs-2) {
260 5f1cf8e6 2004-05-16 devnull int where = slugp - slugs;
261 5f1cf8e6 2004-05-16 devnull if ((slugs = (slug *) realloc((char *) slugs, (nslugs += DELTASLUGS)*sizeof(slug))) == NULL)
262 5f1cf8e6 2004-05-16 devnull ERROR "no room for %d slugs\n", nslugs FATAL;
263 5f1cf8e6 2004-05-16 devnull ERROR "now slug array can hold %d slugs\n", nslugs WARNING;
264 5f1cf8e6 2004-05-16 devnull slugp = slugs + where;
265 5f1cf8e6 2004-05-16 devnull }
266 5f1cf8e6 2004-05-16 devnull *slugp = getslug(fp);
267 5f1cf8e6 2004-05-16 devnull if (slugp->type == EOF)
268 5f1cf8e6 2004-05-16 devnull break;
269 5f1cf8e6 2004-05-16 devnull }
270 5f1cf8e6 2004-05-16 devnull *++slugp = eofslug();
271 5f1cf8e6 2004-05-16 devnull printf("# %d slugs\n", slugp-slugs);
272 5f1cf8e6 2004-05-16 devnull }
273 5f1cf8e6 2004-05-16 devnull
274 5f1cf8e6 2004-05-16 devnull static slug *findend(slug *sp)
275 5f1cf8e6 2004-05-16 devnull {
276 5f1cf8e6 2004-05-16 devnull slug *p;
277 5f1cf8e6 2004-05-16 devnull for (p = sp; p->type == sp->type; p++) // skip runs
278 5f1cf8e6 2004-05-16 devnull ; // espec UF UF UF
279 5f1cf8e6 2004-05-16 devnull for ( ; p < slugp; p++)
280 5f1cf8e6 2004-05-16 devnull switch (p->type) {
281 5f1cf8e6 2004-05-16 devnull case US:
282 5f1cf8e6 2004-05-16 devnull case UF:
283 5f1cf8e6 2004-05-16 devnull case BF:
284 5f1cf8e6 2004-05-16 devnull case PT:
285 5f1cf8e6 2004-05-16 devnull case BT:
286 5f1cf8e6 2004-05-16 devnull p = findend(p);
287 5f1cf8e6 2004-05-16 devnull break;
288 5f1cf8e6 2004-05-16 devnull case END:
289 5f1cf8e6 2004-05-16 devnull return p;
290 5f1cf8e6 2004-05-16 devnull }
291 5f1cf8e6 2004-05-16 devnull ERROR "walked past EOF in findend looking for %d (%s), line %d\n",
292 5f1cf8e6 2004-05-16 devnull sp->type, sp->typename(), sp->lineno() FATAL;
293 5f1cf8e6 2004-05-16 devnull return sp;
294 5f1cf8e6 2004-05-16 devnull }
295 5f1cf8e6 2004-05-16 devnull
296 5f1cf8e6 2004-05-16 devnull static int markp(int i, int n, int parm)
297 5f1cf8e6 2004-05-16 devnull { // should VBOX i of n be marked to brevent breaking after it?
298 5f1cf8e6 2004-05-16 devnull if (i >= n-1)
299 5f1cf8e6 2004-05-16 devnull return 0;
300 5f1cf8e6 2004-05-16 devnull return i <= parm-2 || i >= n-parm;
301 5f1cf8e6 2004-05-16 devnull }
302 5f1cf8e6 2004-05-16 devnull
303 5f1cf8e6 2004-05-16 devnull static void markbreak(slug *p)
304 5f1cf8e6 2004-05-16 devnull {
305 5f1cf8e6 2004-05-16 devnull // Mark impermissible breakpoints in BS's.
306 5f1cf8e6 2004-05-16 devnull // The parm field of a VBOX is >0 if we shouldn't break after it.
307 75347226 2004-05-17 devnull int parm = 0; // how many lines must stay on page
308 5f1cf8e6 2004-05-16 devnull int goahead = 1; // true until we see the next BS
309 5f1cf8e6 2004-05-16 devnull int nowmark = 0; // true when we should be marking
310 5f1cf8e6 2004-05-16 devnull int n = 0;
311 5f1cf8e6 2004-05-16 devnull while (p->type == BS)
312 5f1cf8e6 2004-05-16 devnull parm = p++->parm; // latest BS parm applies
313 5f1cf8e6 2004-05-16 devnull slug *op = p;
314 5f1cf8e6 2004-05-16 devnull while (goahead) {
315 5f1cf8e6 2004-05-16 devnull switch (p->type) {
316 5f1cf8e6 2004-05-16 devnull case VBOX: // count VBOXes so second pass knows
317 5f1cf8e6 2004-05-16 devnull if (p->dv > 0) // knows how far to end of BS
318 5f1cf8e6 2004-05-16 devnull n++;
319 5f1cf8e6 2004-05-16 devnull break;
320 5f1cf8e6 2004-05-16 devnull case US: // mark around EQ/EN, etc.
321 5f1cf8e6 2004-05-16 devnull nowmark = 1;
322 5f1cf8e6 2004-05-16 devnull p = findend(p);
323 5f1cf8e6 2004-05-16 devnull break;
324 5f1cf8e6 2004-05-16 devnull case UF: // but not around floats, PTs, and BTs
325 5f1cf8e6 2004-05-16 devnull case BF:
326 5f1cf8e6 2004-05-16 devnull case PT:
327 5f1cf8e6 2004-05-16 devnull case BT:
328 5f1cf8e6 2004-05-16 devnull p = findend(p);
329 5f1cf8e6 2004-05-16 devnull break;
330 5f1cf8e6 2004-05-16 devnull case SP: // naked SP: probable macro botch
331 5f1cf8e6 2004-05-16 devnull nowmark = 1; // mark around it anyhow
332 5f1cf8e6 2004-05-16 devnull break;
333 5f1cf8e6 2004-05-16 devnull case BS: // beginning of next paragraph
334 5f1cf8e6 2004-05-16 devnull case END: // probable macro botch
335 5f1cf8e6 2004-05-16 devnull case EOF:
336 5f1cf8e6 2004-05-16 devnull goahead = 0; // stop work after marking
337 5f1cf8e6 2004-05-16 devnull nowmark = 1;
338 5f1cf8e6 2004-05-16 devnull default:
339 5f1cf8e6 2004-05-16 devnull break;
340 5f1cf8e6 2004-05-16 devnull }
341 5f1cf8e6 2004-05-16 devnull p++;
342 5f1cf8e6 2004-05-16 devnull if (nowmark) {
343 5f1cf8e6 2004-05-16 devnull int i = 0; // VBOX counter for second pass
344 5f1cf8e6 2004-05-16 devnull while (op < p) {
345 5f1cf8e6 2004-05-16 devnull switch (op->type) {
346 5f1cf8e6 2004-05-16 devnull case VBOX:
347 5f1cf8e6 2004-05-16 devnull if (op->dv > 0)
348 5f1cf8e6 2004-05-16 devnull op->parm = markp(i, n, parm);
349 5f1cf8e6 2004-05-16 devnull i++;
350 5f1cf8e6 2004-05-16 devnull break;
351 5f1cf8e6 2004-05-16 devnull case US: // caused second pass to begin
352 5f1cf8e6 2004-05-16 devnull case SP:
353 5f1cf8e6 2004-05-16 devnull case BS:
354 5f1cf8e6 2004-05-16 devnull case END:
355 5f1cf8e6 2004-05-16 devnull case EOF:
356 5f1cf8e6 2004-05-16 devnull op = p;
357 5f1cf8e6 2004-05-16 devnull break;
358 5f1cf8e6 2004-05-16 devnull case UF: // skip on this pass too
359 5f1cf8e6 2004-05-16 devnull case BF:
360 5f1cf8e6 2004-05-16 devnull case PT:
361 5f1cf8e6 2004-05-16 devnull case BT:
362 5f1cf8e6 2004-05-16 devnull op = findend(op);
363 5f1cf8e6 2004-05-16 devnull break;
364 5f1cf8e6 2004-05-16 devnull default:
365 5f1cf8e6 2004-05-16 devnull break;
366 5f1cf8e6 2004-05-16 devnull }
367 5f1cf8e6 2004-05-16 devnull op++;
368 5f1cf8e6 2004-05-16 devnull }
369 5f1cf8e6 2004-05-16 devnull if (i != n)
370 5f1cf8e6 2004-05-16 devnull ERROR "markbreak failed : i %d n %d\n",
371 5f1cf8e6 2004-05-16 devnull i, n WARNING;
372 5f1cf8e6 2004-05-16 devnull op = p;
373 5f1cf8e6 2004-05-16 devnull nowmark = n = 0;
374 5f1cf8e6 2004-05-16 devnull }
375 5f1cf8e6 2004-05-16 devnull }
376 5f1cf8e6 2004-05-16 devnull }
377 5f1cf8e6 2004-05-16 devnull
378 5f1cf8e6 2004-05-16 devnull static void fixslugs() // adjust bases and dv's, set parameters, etc.
379 5f1cf8e6 2004-05-16 devnull {
380 5f1cf8e6 2004-05-16 devnull slug *p, *prevV = 0;
381 5f1cf8e6 2004-05-16 devnull for (p = slugs; p < slugp; p++) {
382 5f1cf8e6 2004-05-16 devnull if (p->type == VBOX) {
383 5f1cf8e6 2004-05-16 devnull prevV = p;
384 5f1cf8e6 2004-05-16 devnull continue;
385 5f1cf8e6 2004-05-16 devnull }
386 5f1cf8e6 2004-05-16 devnull if (p->base != 0) {
387 5f1cf8e6 2004-05-16 devnull ERROR "%s slug (type %d) has base = %d, line %d\n",
388 5f1cf8e6 2004-05-16 devnull p->typename(), p->type, p->base, p->lineno() WARNING;
389 5f1cf8e6 2004-05-16 devnull }
390 5f1cf8e6 2004-05-16 devnull if ((p->type == SP) || (p->type == NE))
391 5f1cf8e6 2004-05-16 devnull continue;
392 5f1cf8e6 2004-05-16 devnull if (p->type == PAGE)
393 5f1cf8e6 2004-05-16 devnull prevV = 0;
394 5f1cf8e6 2004-05-16 devnull if (p->dv != 0)
395 5f1cf8e6 2004-05-16 devnull if (prevV) {
396 5f1cf8e6 2004-05-16 devnull prevV->base = max(prevV->base, p->dv);
397 5f1cf8e6 2004-05-16 devnull p->dv = 0;
398 5f1cf8e6 2004-05-16 devnull } else {
399 5f1cf8e6 2004-05-16 devnull ERROR "%s slug (type %d) has dv = %d, line %d\n",
400 5f1cf8e6 2004-05-16 devnull p->typename(), p->type, p->dv, p->lineno() WARNING;
401 5f1cf8e6 2004-05-16 devnull }
402 5f1cf8e6 2004-05-16 devnull }
403 5f1cf8e6 2004-05-16 devnull prevV = 0;
404 5f1cf8e6 2004-05-16 devnull int firstNP = 0, firstFO = 0, firstPL = 0;
405 5f1cf8e6 2004-05-16 devnull for (p = slugs; p < slugp; p++) {
406 5f1cf8e6 2004-05-16 devnull switch (p->type) {
407 5f1cf8e6 2004-05-16 devnull // adjust the dv in a sequence of VBOXes
408 5f1cf8e6 2004-05-16 devnull // by subtracting from each the base of the preceding VBOX
409 5f1cf8e6 2004-05-16 devnull case VBOX:
410 5f1cf8e6 2004-05-16 devnull if (prevV)
411 5f1cf8e6 2004-05-16 devnull p->dv -= prevV->base;
412 5f1cf8e6 2004-05-16 devnull prevV = p;
413 5f1cf8e6 2004-05-16 devnull break;
414 5f1cf8e6 2004-05-16 devnull case SP:
415 5f1cf8e6 2004-05-16 devnull p->dv = max(p->dv, 0);
416 5f1cf8e6 2004-05-16 devnull break;
417 5f1cf8e6 2004-05-16 devnull case PAGE:
418 5f1cf8e6 2004-05-16 devnull p->neutralize();
419 5f1cf8e6 2004-05-16 devnull prevV = 0;
420 5f1cf8e6 2004-05-16 devnull break;
421 5f1cf8e6 2004-05-16 devnull // record only first "declarations" of Page Top and bottom (FO);
422 5f1cf8e6 2004-05-16 devnull case PARM:
423 5f1cf8e6 2004-05-16 devnull switch (p->parm) {
424 5f1cf8e6 2004-05-16 devnull case NP:
425 5f1cf8e6 2004-05-16 devnull if (firstNP++ == 0)
426 5f1cf8e6 2004-05-16 devnull pagetop = p->parm2;
427 5f1cf8e6 2004-05-16 devnull p->neutralize();
428 5f1cf8e6 2004-05-16 devnull break;
429 5f1cf8e6 2004-05-16 devnull case FO:
430 5f1cf8e6 2004-05-16 devnull if (firstFO++ == 0)
431 5f1cf8e6 2004-05-16 devnull pagebot = p->parm2;
432 5f1cf8e6 2004-05-16 devnull p->neutralize();
433 5f1cf8e6 2004-05-16 devnull break;
434 5f1cf8e6 2004-05-16 devnull case PL:
435 5f1cf8e6 2004-05-16 devnull if (firstPL++ == 0)
436 5f1cf8e6 2004-05-16 devnull physbot = p->parm2;
437 5f1cf8e6 2004-05-16 devnull p->neutralize();
438 5f1cf8e6 2004-05-16 devnull break;
439 5f1cf8e6 2004-05-16 devnull }
440 5f1cf8e6 2004-05-16 devnull break;
441 5f1cf8e6 2004-05-16 devnull // things that begin groups; not US, which should nest properly
442 5f1cf8e6 2004-05-16 devnull case UF:
443 5f1cf8e6 2004-05-16 devnull case BF:
444 5f1cf8e6 2004-05-16 devnull while ((p+1)->type == p->type) {
445 5f1cf8e6 2004-05-16 devnull // join adjacent identical
446 5f1cf8e6 2004-05-16 devnull (p+1)->parm2 = p->parm; // parm is latest
447 5f1cf8e6 2004-05-16 devnull // parm2 is previous
448 5f1cf8e6 2004-05-16 devnull p->neutralize(); // so it's not seen later
449 5f1cf8e6 2004-05-16 devnull p++;
450 5f1cf8e6 2004-05-16 devnull }
451 5f1cf8e6 2004-05-16 devnull break;
452 5f1cf8e6 2004-05-16 devnull // none of the above
453 5f1cf8e6 2004-05-16 devnull case US:
454 5f1cf8e6 2004-05-16 devnull case PT:
455 5f1cf8e6 2004-05-16 devnull case BT:
456 5f1cf8e6 2004-05-16 devnull case BS:
457 5f1cf8e6 2004-05-16 devnull case END:
458 5f1cf8e6 2004-05-16 devnull case TM:
459 5f1cf8e6 2004-05-16 devnull case COORD:
460 5f1cf8e6 2004-05-16 devnull case NE:
461 5f1cf8e6 2004-05-16 devnull case MC:
462 5f1cf8e6 2004-05-16 devnull case CMD:
463 5f1cf8e6 2004-05-16 devnull case EOF:
464 5f1cf8e6 2004-05-16 devnull break;
465 5f1cf8e6 2004-05-16 devnull default:
466 5f1cf8e6 2004-05-16 devnull ERROR "Unknown slug type %d in fixslugs, line %d\n",
467 5f1cf8e6 2004-05-16 devnull p->type, p->lineno() WARNING;
468 5f1cf8e6 2004-05-16 devnull break;
469 5f1cf8e6 2004-05-16 devnull }
470 5f1cf8e6 2004-05-16 devnull }
471 5f1cf8e6 2004-05-16 devnull int pagesize = pagebot - pagetop;
472 5f1cf8e6 2004-05-16 devnull if (pagesize == 0)
473 5f1cf8e6 2004-05-16 devnull ERROR "Page dimensions not declared\n" FATAL;
474 5f1cf8e6 2004-05-16 devnull if (physbot == 0)
475 5f1cf8e6 2004-05-16 devnull physbot = pagebot + pagetop;
476 5f1cf8e6 2004-05-16 devnull printf("# page top %d bot %d size %d physbot %d\n",
477 5f1cf8e6 2004-05-16 devnull pagetop, pagebot, pagesize, physbot);
478 5f1cf8e6 2004-05-16 devnull for (p = slugs; p < slugp; p++) {
479 5f1cf8e6 2004-05-16 devnull switch (p->type) {
480 5f1cf8e6 2004-05-16 devnull // normalize float parameters
481 5f1cf8e6 2004-05-16 devnull case BF:
482 5f1cf8e6 2004-05-16 devnull case UF:
483 5f1cf8e6 2004-05-16 devnull // primary goal
484 5f1cf8e6 2004-05-16 devnull p->parm = max(min(p->parm-pagetop, pagesize), 0);
485 5f1cf8e6 2004-05-16 devnull // secondary goal
486 5f1cf8e6 2004-05-16 devnull p->parm2 = max(min(p->parm2-pagetop, pagesize), 0);
487 5f1cf8e6 2004-05-16 devnull break;
488 5f1cf8e6 2004-05-16 devnull // normalize need parameters
489 5f1cf8e6 2004-05-16 devnull case NE:
490 5f1cf8e6 2004-05-16 devnull p->dv = max( min(p->dv, pagesize), 0);
491 5f1cf8e6 2004-05-16 devnull break;
492 5f1cf8e6 2004-05-16 devnull // mark permissible breaks
493 5f1cf8e6 2004-05-16 devnull case BS:
494 5f1cf8e6 2004-05-16 devnull markbreak(p);
495 5f1cf8e6 2004-05-16 devnull break;
496 5f1cf8e6 2004-05-16 devnull }
497 5f1cf8e6 2004-05-16 devnull if (dbg & 1)
498 5f1cf8e6 2004-05-16 devnull p->dump();
499 5f1cf8e6 2004-05-16 devnull }
500 5f1cf8e6 2004-05-16 devnull }
501 5f1cf8e6 2004-05-16 devnull
502 5f1cf8e6 2004-05-16 devnull void checkout()
503 5f1cf8e6 2004-05-16 devnull {
504 5f1cf8e6 2004-05-16 devnull for (slug *p = slugs; p < slugp; p++)
505 5f1cf8e6 2004-05-16 devnull switch (p->type) {
506 5f1cf8e6 2004-05-16 devnull case PT:
507 5f1cf8e6 2004-05-16 devnull case BT:
508 5f1cf8e6 2004-05-16 devnull p = findend(p);
509 5f1cf8e6 2004-05-16 devnull break;
510 5f1cf8e6 2004-05-16 devnull case SP:
511 5f1cf8e6 2004-05-16 devnull case VBOX:
512 5f1cf8e6 2004-05-16 devnull if (p->seen != 1)
513 5f1cf8e6 2004-05-16 devnull ERROR "%s slug %d seen %d times\n",
514 5f1cf8e6 2004-05-16 devnull p->typename(), p->serialno(),
515 5f1cf8e6 2004-05-16 devnull p->seen WARNING;
516 5f1cf8e6 2004-05-16 devnull break;
517 5f1cf8e6 2004-05-16 devnull }
518 5f1cf8e6 2004-05-16 devnull }
519 5f1cf8e6 2004-05-16 devnull
520 5f1cf8e6 2004-05-16 devnull eofrange *lastrange;
521 5f1cf8e6 2004-05-16 devnull stream ptlist, btlist;
522 5f1cf8e6 2004-05-16 devnull
523 5f1cf8e6 2004-05-16 devnull static slug *makeranges(slug *p, stream *s, int level)
524 5f1cf8e6 2004-05-16 devnull {
525 5f1cf8e6 2004-05-16 devnull stream *t;
526 5f1cf8e6 2004-05-16 devnull
527 5f1cf8e6 2004-05-16 devnull for ( ; p < slugp; p++)
528 5f1cf8e6 2004-05-16 devnull switch (p->type) {
529 5f1cf8e6 2004-05-16 devnull case VBOX:
530 5f1cf8e6 2004-05-16 devnull s->append(new vboxrange(p));
531 5f1cf8e6 2004-05-16 devnull break;
532 5f1cf8e6 2004-05-16 devnull case SP:
533 5f1cf8e6 2004-05-16 devnull s->append(new sprange(p));
534 5f1cf8e6 2004-05-16 devnull break;
535 5f1cf8e6 2004-05-16 devnull case BS:
536 5f1cf8e6 2004-05-16 devnull s->append(new bsrange(p));
537 5f1cf8e6 2004-05-16 devnull break;
538 5f1cf8e6 2004-05-16 devnull case US:
539 5f1cf8e6 2004-05-16 devnull s->append(new usrange(p, t = new stream));
540 5f1cf8e6 2004-05-16 devnull p = makeranges(p+1, t, level+1);
541 5f1cf8e6 2004-05-16 devnull break;
542 5f1cf8e6 2004-05-16 devnull case BF:
543 5f1cf8e6 2004-05-16 devnull s->append(new bfrange(p, t = new stream));
544 5f1cf8e6 2004-05-16 devnull p = makeranges(p+1, t, level+1);
545 5f1cf8e6 2004-05-16 devnull break;
546 5f1cf8e6 2004-05-16 devnull case UF:
547 5f1cf8e6 2004-05-16 devnull s->append(new ufrange(p, t = new stream));
548 5f1cf8e6 2004-05-16 devnull p = makeranges(p+1, t, level+1);
549 5f1cf8e6 2004-05-16 devnull break;
550 5f1cf8e6 2004-05-16 devnull case PT:
551 5f1cf8e6 2004-05-16 devnull ptlist.append(new ptrange(p, t = new stream));
552 5f1cf8e6 2004-05-16 devnull p = makeranges(p+1, t, level+1);
553 5f1cf8e6 2004-05-16 devnull break;
554 5f1cf8e6 2004-05-16 devnull case BT:
555 5f1cf8e6 2004-05-16 devnull btlist.append(new btrange(p, t = new stream));
556 5f1cf8e6 2004-05-16 devnull p = makeranges(p+1, t, level+1);
557 5f1cf8e6 2004-05-16 devnull break;
558 5f1cf8e6 2004-05-16 devnull case END:
559 5f1cf8e6 2004-05-16 devnull s->append(new endrange(p));
560 5f1cf8e6 2004-05-16 devnull return p;
561 5f1cf8e6 2004-05-16 devnull case TM:
562 5f1cf8e6 2004-05-16 devnull s->append(new tmrange(p));
563 5f1cf8e6 2004-05-16 devnull break;
564 5f1cf8e6 2004-05-16 devnull case COORD:
565 5f1cf8e6 2004-05-16 devnull s->append(new coordrange(p));
566 5f1cf8e6 2004-05-16 devnull break;
567 5f1cf8e6 2004-05-16 devnull case NE:
568 5f1cf8e6 2004-05-16 devnull if (level) {
569 5f1cf8e6 2004-05-16 devnull ERROR "Nested NE commands are ignored, line %d\n",
570 5f1cf8e6 2004-05-16 devnull p->lineno() WARNING;
571 5f1cf8e6 2004-05-16 devnull p->dv = 0;
572 5f1cf8e6 2004-05-16 devnull }
573 5f1cf8e6 2004-05-16 devnull s->append(new nerange(p));
574 5f1cf8e6 2004-05-16 devnull break;
575 5f1cf8e6 2004-05-16 devnull case MC:
576 5f1cf8e6 2004-05-16 devnull s->append(new mcrange(p));
577 5f1cf8e6 2004-05-16 devnull break;
578 5f1cf8e6 2004-05-16 devnull case CMD:
579 5f1cf8e6 2004-05-16 devnull if (level)
580 5f1cf8e6 2004-05-16 devnull ERROR "Nested command ignored, line %d\n",
581 5f1cf8e6 2004-05-16 devnull p->lineno() WARNING;
582 5f1cf8e6 2004-05-16 devnull s->append(new cmdrange(p));
583 5f1cf8e6 2004-05-16 devnull break;
584 5f1cf8e6 2004-05-16 devnull case PARM:
585 5f1cf8e6 2004-05-16 devnull if (level)
586 5f1cf8e6 2004-05-16 devnull ERROR "Nested parameter ignored, line %d\n",
587 5f1cf8e6 2004-05-16 devnull p->lineno() WARNING;
588 5f1cf8e6 2004-05-16 devnull s->append(new parmrange(p));
589 5f1cf8e6 2004-05-16 devnull break;
590 5f1cf8e6 2004-05-16 devnull case EOF:
591 5f1cf8e6 2004-05-16 devnull lastrange = new eofrange(p);
592 5f1cf8e6 2004-05-16 devnull return 0;
593 5f1cf8e6 2004-05-16 devnull }
594 5f1cf8e6 2004-05-16 devnull return p;
595 5f1cf8e6 2004-05-16 devnull }
596 5f1cf8e6 2004-05-16 devnull
597 5f1cf8e6 2004-05-16 devnull static queue text; // unexamined input ranges; the real data
598 5f1cf8e6 2004-05-16 devnull
599 5f1cf8e6 2004-05-16 devnull void startup(FILE *fp)
600 5f1cf8e6 2004-05-16 devnull {
601 5f1cf8e6 2004-05-16 devnull doprefix(fp); // peel off 'x' commands
602 5f1cf8e6 2004-05-16 devnull readslugs(fp); // read everything into slugs[]
603 5f1cf8e6 2004-05-16 devnull fixslugs(); // measure parameters and clean up
604 5f1cf8e6 2004-05-16 devnull makeranges(slugs, &text, 0); // add range superstructure
605 5f1cf8e6 2004-05-16 devnull measure(&text); // heights of nested things
606 5f1cf8e6 2004-05-16 devnull rawmeasure(&text);
607 5f1cf8e6 2004-05-16 devnull while (text.more()) {
608 5f1cf8e6 2004-05-16 devnull range *r = text.dequeue();
609 5f1cf8e6 2004-05-16 devnull if (dbg & 2)
610 5f1cf8e6 2004-05-16 devnull r->dump();
611 5f1cf8e6 2004-05-16 devnull r->enqueue();
612 5f1cf8e6 2004-05-16 devnull }
613 5f1cf8e6 2004-05-16 devnull }