Commit | Line | Data |
---|---|---|
65917c16 | 1 | #ifndef lint |
b84acc55 | 2 | static char sccsid[] = "@(#)n3.c 2.3 (CWI) 86/11/27"; |
65917c16 | 3 | #endif lint |
655e9788 JA |
4 | /* @(#)n3.c 1.1 */ |
5 | /* | |
6 | * troff3.c | |
7 | * | |
8 | * macro and string routines, storage allocation | |
9 | */ | |
10 | ||
65917c16 JA |
11 | |
12 | #include "tdef.h" | |
65917c16 | 13 | #ifdef NROFF |
65917c16 JA |
14 | #include "tw.h" |
15 | #endif | |
65917c16 JA |
16 | #include <sgtty.h> |
17 | #include "ext.h" | |
655e9788 JA |
18 | |
19 | #define MHASH(x) ((x>>6)^x)&0177 | |
20 | struct contab *mhash[128]; /* 128 == the 0177 on line above */ | |
21 | #define blisti(i) (((i)-NEV*(int)sizeof(env))/BLK) | |
65917c16 JA |
22 | filep blist[NBLIST]; |
23 | tchar *argtop; | |
24 | int pagech = '%'; | |
25 | int strflg; | |
65917c16 JA |
26 | |
27 | #ifdef INCORE | |
28 | tchar *wbuf; | |
655e9788 | 29 | tchar corebuf[NEV*sizeof(env)/sizeof(tchar) + NBLIST*BLK+ 1]; |
65917c16 JA |
30 | #else |
31 | tchar wbuf[BLK]; | |
32 | tchar rbuf[BLK]; | |
33 | #endif | |
34 | ||
35 | caseig() | |
36 | { | |
37 | register i; | |
38 | ||
39 | offset = 0; | |
40 | if ((i = copyb()) != '.') | |
41 | control(i, 1); | |
42 | } | |
43 | ||
44 | ||
45 | casern() | |
46 | { | |
47 | register i, j; | |
48 | ||
49 | lgf++; | |
50 | skip(); | |
51 | if ((i = getrq()) == 0 || (oldmn = findmn(i)) < 0) | |
52 | return; | |
53 | skip(); | |
54 | clrmn(findmn(j = getrq())); | |
655e9788 JA |
55 | if (j) { |
56 | munhash(&contab[oldmn]); | |
57 | contab[oldmn].rq = j; | |
58 | maddhash(&contab[oldmn]); | |
59 | } | |
65917c16 JA |
60 | } |
61 | ||
655e9788 JA |
62 | maddhash(rp) |
63 | register struct contab *rp; | |
64 | { | |
65 | register struct contab **hp; | |
66 | ||
67 | if (rp->rq == 0) | |
68 | return; | |
69 | hp = &mhash[MHASH(rp->rq)]; | |
70 | rp->link = *hp; | |
71 | *hp = rp; | |
72 | } | |
73 | ||
74 | munhash(mp) | |
75 | register struct contab *mp; | |
76 | { | |
77 | register struct contab *p; | |
78 | register struct contab **lp; | |
79 | ||
80 | if (mp->rq == 0) | |
81 | return; | |
82 | lp = &mhash[MHASH(mp->rq)]; | |
83 | p = *lp; | |
84 | while (p) { | |
85 | if (p == mp) { | |
86 | *lp = p->link; | |
87 | p->link = 0; | |
88 | return; | |
89 | } | |
90 | lp = &p->link; | |
91 | p = p->link; | |
92 | } | |
93 | } | |
94 | ||
95 | mrehash() | |
96 | { | |
97 | register struct contab *p; | |
98 | register i; | |
99 | ||
100 | for (i=0; i<128; i++) | |
101 | mhash[i] = 0; | |
102 | for (p=contab; p < &contab[NM]; p++) | |
103 | p->link = 0; | |
104 | for (p=contab; p < &contab[NM]; p++) { | |
105 | if (p->rq == 0) | |
106 | continue; | |
107 | i = MHASH(p->rq); | |
108 | p->link = mhash[i]; | |
109 | mhash[i] = p; | |
110 | } | |
111 | } | |
65917c16 JA |
112 | |
113 | caserm() | |
114 | { | |
655e9788 JA |
115 | int j; |
116 | ||
65917c16 | 117 | lgf++; |
655e9788 JA |
118 | while (!skip() && (j = getrq()) != 0) |
119 | clrmn(findmn(j)); | |
120 | lgf--; | |
65917c16 JA |
121 | } |
122 | ||
123 | ||
124 | caseas() | |
125 | { | |
126 | app++; | |
127 | caseds(); | |
128 | } | |
129 | ||
130 | ||
131 | caseds() | |
132 | { | |
133 | ds++; | |
134 | casede(); | |
135 | } | |
136 | ||
137 | ||
138 | caseam() | |
139 | { | |
140 | app++; | |
141 | casede(); | |
142 | } | |
143 | ||
144 | ||
145 | casede() | |
146 | { | |
147 | register i, req; | |
148 | register filep savoff; | |
149 | extern filep finds(); | |
150 | ||
151 | if (dip != d) | |
152 | wbfl(); | |
153 | req = '.'; | |
154 | lgf++; | |
155 | skip(); | |
156 | if ((i = getrq()) == 0) | |
157 | goto de1; | |
158 | if ((offset = finds(i)) == 0) | |
159 | goto de1; | |
160 | if (ds) | |
161 | copys(); | |
162 | else | |
163 | req = copyb(); | |
164 | wbfl(); | |
165 | clrmn(oldmn); | |
655e9788 JA |
166 | if (newmn) { |
167 | if (contab[newmn].rq) | |
168 | munhash(&contab[newmn]); | |
169 | contab[newmn].rq = i; | |
170 | maddhash(&contab[newmn]); | |
171 | } | |
65917c16 JA |
172 | if (apptr) { |
173 | savoff = offset; | |
174 | offset = apptr; | |
175 | wbt((tchar) IMP); | |
176 | offset = savoff; | |
177 | } | |
178 | offset = dip->op; | |
179 | if (req != '.') | |
180 | control(req, 1); | |
181 | de1: | |
182 | ds = app = 0; | |
183 | return; | |
184 | } | |
185 | ||
186 | ||
187 | findmn(i) | |
188 | register int i; | |
189 | { | |
65917c16 JA |
190 | register struct contab *p; |
191 | ||
655e9788 JA |
192 | for (p = mhash[MHASH(i)]; p; p = p->link) |
193 | if (i == p->rq) | |
194 | return(p - contab); | |
195 | return(-1); | |
65917c16 JA |
196 | } |
197 | ||
198 | ||
199 | clrmn(i) | |
200 | register int i; | |
201 | { | |
202 | if (i >= 0) { | |
655e9788 JA |
203 | if (contab[i].mx) |
204 | ffree((filep)contab[i].mx); | |
205 | munhash(&contab[i]); | |
65917c16 | 206 | contab[i].rq = 0; |
655e9788 JA |
207 | contab[i].mx = 0; |
208 | contab[i].f = 0; | |
65917c16 JA |
209 | } |
210 | } | |
211 | ||
212 | ||
213 | filep finds(mn) | |
214 | register int mn; | |
215 | { | |
216 | register i; | |
217 | register filep savip; | |
218 | extern filep alloc(); | |
219 | extern filep incoff(); | |
220 | ||
221 | oldmn = findmn(mn); | |
222 | newmn = 0; | |
223 | apptr = (filep)0; | |
655e9788 | 224 | if (app && oldmn >= 0 && contab[oldmn].mx) { |
65917c16 | 225 | savip = ip; |
655e9788 | 226 | ip = (filep)contab[oldmn].mx; |
65917c16 JA |
227 | oldmn = -1; |
228 | while ((i = rbf()) != 0) | |
229 | ; | |
230 | apptr = ip; | |
231 | if (!diflg) | |
232 | ip = incoff(ip); | |
233 | nextb = ip; | |
234 | ip = savip; | |
235 | } else { | |
236 | for (i = 0; i < NM; i++) { | |
237 | if (contab[i].rq == 0) | |
238 | break; | |
239 | } | |
240 | if (i == NM || (nextb = alloc()) == 0) { | |
241 | app = 0; | |
242 | if (macerr++ > 1) | |
243 | done2(02); | |
655e9788 | 244 | errprint("Too many (%d) string/macro names", NM); |
65917c16 JA |
245 | edone(04); |
246 | return(offset = 0); | |
247 | } | |
655e9788 | 248 | contab[i].mx = (unsigned) nextb; |
65917c16 JA |
249 | if (!diflg) { |
250 | newmn = i; | |
251 | if (oldmn == -1) | |
252 | contab[i].rq = -1; | |
253 | } else { | |
655e9788 JA |
254 | contab[i].rq = mn; |
255 | maddhash(&contab[i]); | |
65917c16 JA |
256 | } |
257 | } | |
258 | app = 0; | |
259 | return(offset = nextb); | |
260 | } | |
261 | ||
262 | ||
263 | skip() | |
264 | { | |
655e9788 | 265 | register tchar i; |
65917c16 JA |
266 | |
267 | while (cbits(i = getch()) == ' ') | |
268 | ; | |
269 | ch = i; | |
270 | return(nlflg); | |
271 | } | |
272 | ||
273 | ||
274 | copyb() | |
275 | { | |
655e9788 JA |
276 | register i, j, state; |
277 | register tchar ii; | |
278 | int req, k; | |
65917c16 JA |
279 | filep savoff; |
280 | ||
281 | if (skip() || !(j = getrq())) | |
282 | j = '.'; | |
283 | req = j; | |
284 | k = j >> BYTE; | |
655e9788 | 285 | j &= BYTEMASK; |
65917c16 JA |
286 | copyf++; |
287 | flushi(); | |
288 | nlflg = 0; | |
289 | state = 1; | |
290 | while (1) { | |
291 | i = cbits(ii = getch()); | |
292 | if (state == 3) { | |
293 | if (i == k) | |
294 | break; | |
295 | if (!k) { | |
296 | ch = ii; | |
297 | i = getach(); | |
298 | ch = ii; | |
299 | if (!i) | |
300 | break; | |
301 | } | |
302 | state = 0; | |
303 | goto c0; | |
304 | } | |
305 | if (i == '\n') { | |
306 | state = 1; | |
307 | nlflg = 0; | |
308 | goto c0; | |
309 | } | |
310 | if (state == 1 && i == '.') { | |
311 | state++; | |
312 | savoff = offset; | |
313 | goto c0; | |
314 | } | |
315 | if ((state == 2) && (i == j)) { | |
316 | state++; | |
317 | goto c0; | |
318 | } | |
319 | state = 0; | |
320 | c0: | |
321 | if (offset) | |
322 | wbf(ii); | |
323 | } | |
324 | if (offset) { | |
325 | wbfl(); | |
326 | offset = savoff; | |
327 | wbt((tchar)0); | |
328 | } | |
329 | copyf--; | |
330 | return(req); | |
331 | } | |
332 | ||
333 | ||
334 | copys() | |
335 | { | |
655e9788 | 336 | register tchar i; |
65917c16 JA |
337 | |
338 | copyf++; | |
339 | if (skip()) | |
340 | goto c0; | |
341 | if (cbits(i = getch()) != '"') | |
342 | wbf(i); | |
343 | while (cbits(i = getch()) != '\n') | |
344 | wbf(i); | |
345 | c0: | |
346 | wbt((tchar)0); | |
347 | copyf--; | |
348 | } | |
349 | ||
350 | ||
351 | filep alloc() | |
352 | { | |
353 | register i; | |
655e9788 | 354 | register filep j; |
65917c16 JA |
355 | |
356 | for (i = 0; i < NBLIST; i++) { | |
357 | if (blist[i] == 0) | |
358 | break; | |
359 | } | |
360 | if (i == NBLIST) { | |
361 | j = 0; | |
362 | } else { | |
363 | blist[i] = -1; | |
655e9788 | 364 | if ((j = ((filep)i * BLK + NEV*(int)sizeof(env))) < NEV*(int)sizeof(env)) |
65917c16 JA |
365 | j = 0; |
366 | } | |
367 | return(nextb = j); | |
368 | } | |
369 | ||
370 | ||
371 | ffree(i) | |
372 | filep i; | |
373 | { | |
374 | register j; | |
375 | ||
655e9788 JA |
376 | while (blist[j = blisti(i)] != (unsigned) ~0) { |
377 | i = (filep) blist[j]; | |
65917c16 JA |
378 | blist[j] = 0; |
379 | } | |
380 | blist[j] = 0; | |
381 | } | |
382 | ||
65917c16 JA |
383 | wbt(i) |
384 | tchar i; | |
385 | { | |
386 | wbf(i); | |
387 | wbfl(); | |
388 | } | |
389 | ||
390 | ||
391 | wbf(i) | |
655e9788 | 392 | register tchar i; |
65917c16 JA |
393 | { |
394 | register j; | |
395 | ||
396 | if (!offset) | |
397 | return; | |
398 | if (!woff) { | |
399 | woff = offset; | |
400 | #ifdef INCORE | |
401 | wbuf = &corebuf[woff]; /* INCORE only */ | |
402 | #endif | |
403 | wbfi = 0; | |
404 | } | |
405 | wbuf[wbfi++] = i; | |
406 | if (!((++offset) & (BLK - 1))) { | |
407 | wbfl(); | |
655e9788 JA |
408 | j = blisti(--offset); |
409 | if (j < 0 || j >= NBLIST) { | |
410 | errprint("Out of temp file space"); | |
411 | done2(01); | |
412 | } | |
413 | if (blist[j] == (unsigned) ~0) { | |
65917c16 | 414 | if (alloc() == 0) { |
655e9788 | 415 | errprint("Out of temp file space"); |
65917c16 JA |
416 | done2(01); |
417 | } | |
418 | blist[j] = (unsigned)(nextb); | |
419 | } | |
420 | offset = ((filep)blist[j]); | |
421 | } | |
422 | if (wbfi >= BLK) | |
423 | wbfl(); | |
424 | } | |
425 | ||
426 | ||
427 | wbfl() | |
428 | { | |
429 | if (woff == 0) | |
430 | return; | |
431 | #ifndef INCORE | |
432 | lseek(ibf, ((long)woff) * sizeof(tchar), 0); | |
433 | write(ibf, (char *)wbuf, wbfi * sizeof(tchar)); | |
434 | #endif | |
435 | if ((woff & (~(BLK - 1))) == (roff & (~(BLK - 1)))) | |
436 | roff = -1; | |
437 | woff = 0; | |
438 | } | |
439 | ||
440 | ||
441 | tchar rbf() | |
442 | { | |
655e9788 | 443 | register tchar i; |
65917c16 JA |
444 | register filep j, p; |
445 | extern filep incoff(); | |
446 | ||
655e9788 JA |
447 | if (ip == NBLIST*BLK) { /* for rdtty */ |
448 | if (j = rdtty()) | |
449 | return(j); | |
450 | else | |
451 | return(popi()); | |
452 | } | |
65917c16 | 453 | /* this is an inline expansion of rbf0: dirty! */ |
65917c16 | 454 | #ifndef INCORE |
655e9788 JA |
455 | j = ip & ~(BLK - 1); |
456 | if (j != roff) { | |
457 | roff = j; | |
458 | lseek(ibf, (long)j * sizeof(tchar), 0); | |
459 | if (read(ibf, (char *)rbuf, BLK * sizeof(tchar)) <= 0) | |
65917c16 JA |
460 | i = 0; |
461 | else | |
462 | i = rbuf[ip & (BLK-1)]; | |
65917c16 JA |
463 | } else |
464 | i = rbuf[ip & (BLK-1)]; | |
655e9788 JA |
465 | #else |
466 | i = corebuf[ip]; | |
467 | #endif | |
65917c16 JA |
468 | /* end of rbf0 */ |
469 | if (i == 0) { | |
470 | if (!app) | |
471 | i = popi(); | |
655e9788 JA |
472 | return(i); |
473 | } | |
474 | /* this is an inline expansion of incoff: also dirty */ | |
475 | p = ++ip; | |
476 | if ((p & (BLK - 1)) == 0) { | |
477 | if ((ip = blist[blisti(p-1)]) == (unsigned) ~0) { | |
478 | ip = 0; | |
479 | errprint("Bad storage allocation"); | |
480 | done2(-5); | |
65917c16 | 481 | } |
655e9788 JA |
482 | /* this was meant to protect against people removing |
483 | /* the macro they were standing on, but it's too | |
484 | /* sensitive to block boundaries. | |
485 | /* if (ip == 0) { | |
486 | /* errprint("Block removed while in use"); | |
487 | /* done2(-6); | |
488 | /* } | |
489 | */ | |
65917c16 JA |
490 | } |
491 | return(i); | |
492 | } | |
493 | ||
494 | ||
495 | tchar rbf0(p) | |
496 | register filep p; | |
497 | { | |
655e9788 | 498 | #ifndef INCORE |
65917c16 JA |
499 | register filep i; |
500 | ||
501 | if ((i = p & ~(BLK - 1)) != roff) { | |
502 | roff = i; | |
65917c16 JA |
503 | lseek(ibf, (long)roff * sizeof(tchar), 0); |
504 | if (read(ibf, (char *)rbuf, BLK * sizeof(tchar)) == 0) | |
505 | return(0); | |
65917c16 JA |
506 | } |
507 | return(rbuf[p & (BLK-1)]); | |
655e9788 JA |
508 | #else |
509 | return(corebuf[p]); | |
510 | #endif | |
65917c16 JA |
511 | } |
512 | ||
513 | ||
514 | filep incoff(p) | |
515 | register filep p; | |
516 | { | |
655e9788 JA |
517 | p++; |
518 | if ((p & (BLK - 1)) == 0) { | |
519 | if ((p = blist[blisti(p-1)]) == (unsigned) ~0) { | |
520 | errprint("Bad storage allocation"); | |
65917c16 JA |
521 | done2(-5); |
522 | } | |
65917c16 | 523 | } |
655e9788 | 524 | return(p); |
65917c16 JA |
525 | } |
526 | ||
527 | ||
528 | tchar popi() | |
529 | { | |
530 | register struct s *p; | |
531 | ||
532 | if (frame == stk) | |
533 | return(0); | |
534 | if (strflg) | |
535 | strflg--; | |
536 | p = nxf = frame; | |
537 | p->nargs = 0; | |
538 | frame = p->pframe; | |
539 | ip = p->pip; | |
65917c16 | 540 | pendt = p->ppendt; |
655e9788 | 541 | lastpbp = p->lastpbp; |
65917c16 JA |
542 | return(p->pch); |
543 | } | |
544 | ||
545 | /* | |
546 | * test that the end of the allocation is above a certain location | |
547 | * in memory | |
548 | */ | |
549 | #define SPACETEST(base, size) while ((enda - (size)) <= (char *)(base)){setbrk(DELTA);} | |
550 | ||
655e9788 | 551 | pushi(newip, mname) |
65917c16 | 552 | filep newip; |
655e9788 | 553 | int mname; |
65917c16 JA |
554 | { |
555 | register struct s *p; | |
655e9788 | 556 | extern char *setbrk(); |
65917c16 JA |
557 | |
558 | SPACETEST(nxf, sizeof(struct s)); | |
559 | p = nxf; | |
560 | p->pframe = frame; | |
561 | p->pip = ip; | |
65917c16 | 562 | p->ppendt = pendt; |
65917c16 | 563 | p->pch = ch; |
655e9788 JA |
564 | p->lastpbp = lastpbp; |
565 | p->mname = mname; | |
566 | lastpbp = pbp; | |
567 | pendt = ch = 0; | |
65917c16 JA |
568 | frame = nxf; |
569 | if (nxf->nargs == 0) | |
570 | nxf += 1; | |
571 | else | |
572 | nxf = (struct s *)argtop; | |
573 | return(ip = newip); | |
574 | } | |
575 | ||
576 | ||
577 | char *setbrk(x) | |
578 | int x; | |
579 | { | |
580 | register char *i; | |
655e9788 | 581 | register j; |
65917c16 JA |
582 | char *sbrk(); |
583 | ||
655e9788 JA |
584 | if (j = x % sizeof(int)) /*allocate only whole words for 3B*/ |
585 | x += sizeof(int) - j; | |
586 | if ((i = sbrk(x)) == (char *) -1) { | |
587 | errprint("Core limit reached"); | |
65917c16 JA |
588 | edone(0100); |
589 | } else { | |
655e9788 JA |
590 | if ((unsigned)i % sizeof(int)) { /*check alignment for 3B*/ |
591 | errprint("alignment problem"); | |
592 | edone(0100); | |
593 | } | |
65917c16 JA |
594 | enda = i + x; |
595 | } | |
596 | return(i); | |
597 | } | |
598 | ||
599 | ||
600 | getsn() | |
601 | { | |
602 | register i; | |
603 | ||
604 | if ((i = getach()) == 0) | |
605 | return(0); | |
606 | if (i == '(') | |
607 | return(getrq()); | |
608 | else | |
609 | return(i); | |
610 | } | |
611 | ||
612 | ||
613 | setstr() | |
614 | { | |
655e9788 | 615 | register i, j; |
65917c16 JA |
616 | |
617 | lgf++; | |
655e9788 | 618 | if ((i = getsn()) == 0 || (j = findmn(i)) == -1 || !contab[j].mx) { |
65917c16 JA |
619 | lgf--; |
620 | return(0); | |
621 | } else { | |
622 | SPACETEST(nxf, sizeof(struct s)); | |
623 | nxf->nargs = 0; | |
624 | strflg++; | |
625 | lgf--; | |
655e9788 | 626 | return pushi((filep)contab[j].mx, i); |
65917c16 JA |
627 | } |
628 | } | |
629 | ||
630 | ||
631 | ||
632 | collect() | |
633 | { | |
634 | register j; | |
655e9788 | 635 | register tchar i; |
65917c16 JA |
636 | register tchar *strp; |
637 | tchar * lim; | |
638 | tchar * *argpp, **argppend; | |
639 | int quote; | |
640 | struct s *savnxf; | |
641 | ||
642 | copyf++; | |
643 | nxf->nargs = 0; | |
644 | savnxf = nxf; | |
645 | if (skip()) | |
646 | goto rtn; | |
647 | ||
648 | { | |
649 | char *memp; | |
650 | memp = (char *)savnxf; | |
651 | /* | |
652 | * 1 s structure for the macro descriptor | |
653 | * APERMAC tchar *'s for pointers into the strings | |
654 | * space for the tchar's themselves | |
655 | */ | |
656 | memp += sizeof(struct s); | |
657 | /* | |
658 | * CPERMAC (the total # of characters for ALL arguments) | |
659 | * to a macros, has been carefully chosen | |
660 | * so that the distance between stack frames is < DELTA | |
661 | */ | |
662 | #define CPERMAC 200 | |
663 | #define APERMAC 9 | |
664 | memp += APERMAC * sizeof(tchar *); | |
665 | memp += CPERMAC * sizeof(tchar); | |
666 | nxf = (struct s*)memp; | |
667 | } | |
668 | lim = (tchar *)nxf; | |
669 | argpp = (tchar **)(savnxf + 1); | |
670 | argppend = &argpp[APERMAC]; | |
671 | SPACETEST(argppend, sizeof(tchar *)); | |
672 | strp = (tchar *)argppend; | |
673 | /* | |
674 | * Zero out all the string pointers before filling them in. | |
675 | */ | |
676 | for (j = 0; j < APERMAC; j++){ | |
677 | argpp[j] = (tchar *)0; | |
678 | } | |
679 | #if 0 | |
655e9788 | 680 | errprint("savnxf=0x%x,nxf=0x%x,argpp=0x%x,strp=argppend=0x%x,lim=0x%x,enda=0x%x", |
65917c16 JA |
681 | savnxf, nxf, argpp, strp, lim, enda); |
682 | #endif 0 | |
683 | strflg = 0; | |
684 | while ((argpp != argppend) && (!skip())) { | |
685 | *argpp++ = strp; | |
686 | quote = 0; | |
687 | if (cbits(i = getch()) == '"') | |
688 | quote++; | |
689 | else | |
690 | ch = i; | |
691 | while (1) { | |
692 | i = getch(); | |
655e9788 | 693 | if (nlflg || (!quote && cbits(i) == ' ')) |
65917c16 JA |
694 | break; |
695 | if ( quote | |
696 | && (cbits(i) == '"') | |
697 | && (cbits(i = getch()) != '"')) { | |
698 | ch = i; | |
699 | break; | |
700 | } | |
701 | *strp++ = i; | |
655e9788 | 702 | if (strflg && strp >= lim) { |
65917c16 | 703 | #if 0 |
655e9788 | 704 | errprint("strp=0x%x, lim = 0x%x", |
65917c16 JA |
705 | strp, lim); |
706 | #endif 0 | |
655e9788 | 707 | errprint("Macro argument too long"); |
65917c16 JA |
708 | copyf--; |
709 | edone(004); | |
710 | } | |
711 | SPACETEST(strp, 3 * sizeof(tchar)); | |
712 | } | |
713 | *strp++ = 0; | |
714 | } | |
715 | nxf = savnxf; | |
716 | nxf->nargs = argpp - (tchar **)(savnxf + 1); | |
717 | argtop = strp; | |
718 | rtn: | |
719 | copyf--; | |
720 | } | |
721 | ||
722 | ||
723 | seta() | |
724 | { | |
725 | register i; | |
726 | ||
727 | i = cbits(getch()) - '0'; | |
655e9788 JA |
728 | if (i > 0 && i <= APERMAC && i <= frame->nargs) |
729 | pushback(*(((tchar **)(frame + 1)) + i - 1)); | |
65917c16 JA |
730 | } |
731 | ||
732 | ||
733 | caseda() | |
734 | { | |
735 | app++; | |
736 | casedi(); | |
737 | } | |
738 | ||
739 | ||
740 | casedi() | |
741 | { | |
742 | register i, j; | |
743 | register *k; | |
744 | ||
745 | lgf++; | |
655e9788 | 746 | if (skip() || (i = getrq()) == 0) { |
65917c16 JA |
747 | if (dip != d) |
748 | wbt((tchar)0); | |
749 | if (dilev > 0) { | |
655e9788 JA |
750 | numtab[DN].val = dip->dnl; |
751 | numtab[DL].val = dip->maxl; | |
65917c16 JA |
752 | dip = &d[--dilev]; |
753 | offset = dip->op; | |
754 | } | |
755 | goto rtn; | |
756 | } | |
757 | if (++dilev == NDI) { | |
758 | --dilev; | |
655e9788 | 759 | errprint("Diversions nested too deep"); |
65917c16 JA |
760 | edone(02); |
761 | } | |
762 | if (dip != d) | |
763 | wbt((tchar)0); | |
764 | diflg++; | |
765 | dip = &d[dilev]; | |
766 | dip->op = finds(i); | |
767 | dip->curd = i; | |
768 | clrmn(oldmn); | |
769 | k = (int *) & dip->dnl; | |
770 | for (j = 0; j < 10; j++) | |
771 | k[j] = 0; /*not op and curd*/ | |
772 | rtn: | |
773 | app = 0; | |
774 | diflg = 0; | |
775 | } | |
776 | ||
777 | ||
778 | casedt() | |
779 | { | |
780 | lgf++; | |
781 | dip->dimac = dip->ditrap = dip->ditf = 0; | |
782 | skip(); | |
783 | dip->ditrap = vnumb((int *)0); | |
784 | if (nonumb) | |
785 | return; | |
786 | skip(); | |
787 | dip->dimac = getrq(); | |
788 | } | |
789 | ||
790 | ||
791 | casetl() | |
792 | { | |
793 | register j; | |
655e9788 JA |
794 | int w[3]; |
795 | tchar buf[LNSIZE]; | |
796 | register tchar *tp; | |
65917c16 | 797 | tchar i, delim; |
655e9788 | 798 | |
f3d75343 JA |
799 | /* |
800 | * bug fix | |
801 | * | |
802 | * if .tl is the first thing in the file, the p1 | |
803 | * doesn't come out, also the pagenumber will be 0 | |
804 | * | |
805 | * tends too confuse the device filter (and the user as well) | |
806 | */ | |
807 | if( dip == d && numtab[NL].val == -1) | |
808 | newline(1); | |
809 | ||
810 | /* end fix */ | |
65917c16 JA |
811 | dip->nls = 0; |
812 | skip(); | |
65917c16 JA |
813 | if (ismot(delim = getch())) { |
814 | ch = delim; | |
815 | delim = '\''; | |
816 | } else | |
817 | delim = cbits(delim); | |
655e9788 JA |
818 | tp = buf; |
819 | numtab[HP].val = 0; | |
820 | w[0] = w[1] = w[2] = 0; | |
821 | j = 0; | |
822 | while (cbits(i = getch()) != '\n') { | |
823 | if (cbits(i) == cbits(delim)) { | |
824 | if (j < 3) | |
825 | w[j] = numtab[HP].val; | |
826 | numtab[HP].val = 0; | |
827 | j++; | |
828 | *tp++ = 0; | |
829 | } else { | |
830 | if (cbits(i) == pagech) { | |
831 | setn1(numtab[PN].val, numtab[findr('%')].fmt, | |
832 | i&SFMASK); | |
833 | continue; | |
834 | } | |
835 | numtab[HP].val += width(i); | |
836 | if (tp < &buf[LNSIZE-10]) | |
837 | *tp++ = i; | |
65917c16 | 838 | } |
655e9788 JA |
839 | } |
840 | if (j<3) | |
841 | w[j] = numtab[HP].val; | |
842 | *tp++ = 0; | |
843 | *tp++ = 0; | |
844 | *tp++ = 0; | |
845 | tp = buf; | |
65917c16 | 846 | #ifdef NROFF |
655e9788 | 847 | horiz(po); |
65917c16 | 848 | #endif |
655e9788 JA |
849 | while (i = *tp++) |
850 | pchar(i); | |
851 | if (w[1] || w[2]) | |
852 | horiz(j = quant((lt - w[1]) / 2 - w[0], HOR)); | |
853 | while (i = *tp++) | |
854 | pchar(i); | |
855 | if (w[2]) { | |
856 | horiz(lt - w[0] - w[1] - w[2] - j); | |
857 | while (i = *tp++) | |
858 | pchar(i); | |
65917c16 JA |
859 | } |
860 | newline(0); | |
861 | if (dip != d) { | |
862 | if (dip->dnl > dip->hnl) | |
863 | dip->hnl = dip->dnl; | |
864 | } else { | |
655e9788 JA |
865 | if (numtab[NL].val > dip->hnl) |
866 | dip->hnl = numtab[NL].val; | |
65917c16 | 867 | } |
65917c16 JA |
868 | } |
869 | ||
870 | ||
871 | casepc() | |
872 | { | |
873 | pagech = chget(IMP); | |
874 | } | |
875 | ||
876 | ||
65917c16 JA |
877 | casepm() |
878 | { | |
879 | register i, k; | |
880 | register char *p; | |
881 | int xx, cnt, tcnt, kk, tot; | |
882 | filep j; | |
883 | char pmline[10]; | |
884 | ||
885 | kk = cnt = tcnt = 0; | |
886 | tot = !skip(); | |
887 | for (i = 0; i < NM; i++) { | |
b84acc55 | 888 | if ((xx = contab[i].rq) == 0 || contab[i].mx == 0) |
65917c16 | 889 | continue; |
655e9788 | 890 | tcnt++; |
65917c16 | 891 | p = pmline; |
655e9788 | 892 | j = (filep) contab[i].mx; |
65917c16 | 893 | k = 1; |
655e9788 | 894 | while ((j = blist[blisti(j)]) != (unsigned) ~0) { |
65917c16 JA |
895 | k++; |
896 | } | |
897 | cnt++; | |
898 | kk += k; | |
899 | if (!tot) { | |
900 | *p++ = xx & 0177; | |
901 | if (!(*p++ = (xx >> BYTE) & 0177)) | |
902 | *(p - 1) = ' '; | |
903 | *p++ = 0; | |
655e9788 | 904 | fdprintf(stderr, "%s %d\n", pmline, k); |
65917c16 JA |
905 | } |
906 | } | |
655e9788 | 907 | fdprintf(stderr, "pm: total %d, macros %d, space %d\n", tcnt, cnt, kk); |
65917c16 JA |
908 | } |
909 | ||
655e9788 | 910 | stackdump() /* dumps stack of macros in process */ |
65917c16 | 911 | { |
655e9788 JA |
912 | struct s *p; |
913 | ||
914 | if (p != stk) { | |
915 | for (p = frame; p != stk; p = p->pframe) | |
916 | fdprintf(stderr, "%c%c ", p->mname&0177, (p->mname>>BYTE)&0177); | |
917 | fdprintf(stderr, "\n"); | |
918 | } | |
65917c16 | 919 | } |