13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier * troff3.c
33e12c5d1SDavid du Colombier *
43e12c5d1SDavid du Colombier * macro and string routines, storage allocation
53e12c5d1SDavid du Colombier */
63e12c5d1SDavid du Colombier
73e12c5d1SDavid du Colombier #include "tdef.h"
83e12c5d1SDavid du Colombier #include "fns.h"
93e12c5d1SDavid du Colombier #include "ext.h"
103e12c5d1SDavid du Colombier
113e12c5d1SDavid du Colombier Tchar *argtop;
123e12c5d1SDavid du Colombier int pagech = '%';
133e12c5d1SDavid du Colombier int strflg;
143e12c5d1SDavid du Colombier
153e12c5d1SDavid du Colombier #define MHASHSIZE 128 /* must be 2**n */
163e12c5d1SDavid du Colombier #define MHASH(x) ((x>>6)^x) & (MHASHSIZE-1)
173e12c5d1SDavid du Colombier Contab *mhash[MHASHSIZE];
183e12c5d1SDavid du Colombier
193e12c5d1SDavid du Colombier
203e12c5d1SDavid du Colombier Blockp *blist; /* allocated blocks for macros and strings */
213e12c5d1SDavid du Colombier int nblist; /* how many there are */
22219b2ee8SDavid du Colombier int bfree = -1; /* first (possible) free block in the list */
23219b2ee8SDavid du Colombier
24219b2ee8SDavid du Colombier Contab *contabp = NULL;
25219b2ee8SDavid du Colombier #define MDELTA 500
26219b2ee8SDavid du Colombier int nm = 0;
27219b2ee8SDavid du Colombier
28219b2ee8SDavid du Colombier int savname; /* name of macro/string being defined */
29219b2ee8SDavid du Colombier int savslot; /* place in Contab of savname */
30219b2ee8SDavid du Colombier int freeslot = -1; /* first (possible) free slot in contab */
31219b2ee8SDavid du Colombier
prcontab(Contab * p)32219b2ee8SDavid du Colombier void prcontab(Contab *p)
33219b2ee8SDavid du Colombier {
34219b2ee8SDavid du Colombier int i;
35219b2ee8SDavid du Colombier for (i = 0; i < nm; i++)
36219b2ee8SDavid du Colombier if (p)
37219b2ee8SDavid du Colombier if (p[i].rq != 0)
38219b2ee8SDavid du Colombier fprintf(stderr, "slot %d, %-2.2s\n", i, unpair(p[i].rq));
39219b2ee8SDavid du Colombier else
40219b2ee8SDavid du Colombier fprintf(stderr, "slot %d empty\n", i);
41219b2ee8SDavid du Colombier else
42219b2ee8SDavid du Colombier fprintf(stderr, "slot %d empty\n", i);
43219b2ee8SDavid du Colombier }
44219b2ee8SDavid du Colombier
453e12c5d1SDavid du Colombier
blockinit(void)463e12c5d1SDavid du Colombier void blockinit(void)
473e12c5d1SDavid du Colombier {
483e12c5d1SDavid du Colombier blist = (Blockp *) calloc(NBLIST, sizeof(Blockp));
493e12c5d1SDavid du Colombier if (blist == NULL) {
503e12c5d1SDavid du Colombier ERROR "not enough room for %d blocks", NBLIST WARN;
513e12c5d1SDavid du Colombier done2(1);
523e12c5d1SDavid du Colombier }
533e12c5d1SDavid du Colombier nblist = NBLIST;
543e12c5d1SDavid du Colombier blist[0].nextoff = blist[1].nextoff = -1;
553e12c5d1SDavid du Colombier blist[0].bp = (Tchar *) calloc(BLK, sizeof(Tchar));
563e12c5d1SDavid du Colombier blist[1].bp = (Tchar *) calloc(BLK, sizeof(Tchar));
573e12c5d1SDavid du Colombier /* -1 prevents blist[0] from being used; temporary fix */
583e12c5d1SDavid du Colombier /* for a design botch: offset==0 is overloaded. */
593e12c5d1SDavid du Colombier /* blist[1] reserved for .rd indicator -- also unused. */
603e12c5d1SDavid du Colombier /* but someone unwittingly looks at these, so allocate something */
61219b2ee8SDavid du Colombier bfree = 2;
623e12c5d1SDavid du Colombier }
633e12c5d1SDavid du Colombier
643e12c5d1SDavid du Colombier
grow(char * ptr,int num,int size)65219b2ee8SDavid du Colombier char *grow(char *ptr, int num, int size) /* make array bigger */
66219b2ee8SDavid du Colombier {
67*14f51593SDavid du Colombier char *p;
68219b2ee8SDavid du Colombier
69219b2ee8SDavid du Colombier if (ptr == NULL)
70219b2ee8SDavid du Colombier p = (char *) calloc(num, size);
71219b2ee8SDavid du Colombier else
72219b2ee8SDavid du Colombier p = (char *) realloc(ptr, num * size);
73219b2ee8SDavid du Colombier return p;
74219b2ee8SDavid du Colombier }
75219b2ee8SDavid du Colombier
mnspace(void)76219b2ee8SDavid du Colombier void mnspace(void)
77219b2ee8SDavid du Colombier {
78219b2ee8SDavid du Colombier nm = sizeof(contab)/sizeof(Contab) + MDELTA;
79219b2ee8SDavid du Colombier freeslot = sizeof(contab)/sizeof(Contab) + 1;
80219b2ee8SDavid du Colombier contabp = (Contab *) grow((char *) contabp, nm, sizeof(Contab));
81219b2ee8SDavid du Colombier if (contabp == NULL) {
82219b2ee8SDavid du Colombier ERROR "not enough memory for namespace of %d marcos", nm WARN;
83219b2ee8SDavid du Colombier exit(1);
84219b2ee8SDavid du Colombier }
85219b2ee8SDavid du Colombier contabp = (Contab *) memcpy((char *) contabp, (char *)contab,
86219b2ee8SDavid du Colombier sizeof(contab));
87219b2ee8SDavid du Colombier if (contabp == NULL) {
88219b2ee8SDavid du Colombier ERROR "Cannot reinitialize macro/request name list" WARN;
89219b2ee8SDavid du Colombier exit(1);
90219b2ee8SDavid du Colombier }
91219b2ee8SDavid du Colombier
92219b2ee8SDavid du Colombier }
93219b2ee8SDavid du Colombier
caseig(void)943e12c5d1SDavid du Colombier void caseig(void)
953e12c5d1SDavid du Colombier {
963e12c5d1SDavid du Colombier int i;
973e12c5d1SDavid du Colombier Offset oldoff = offset;
983e12c5d1SDavid du Colombier
993e12c5d1SDavid du Colombier offset = 0;
1003e12c5d1SDavid du Colombier i = copyb();
1013e12c5d1SDavid du Colombier offset = oldoff;
1023e12c5d1SDavid du Colombier if (i != '.')
1033e12c5d1SDavid du Colombier control(i, 1);
1043e12c5d1SDavid du Colombier }
1053e12c5d1SDavid du Colombier
1063e12c5d1SDavid du Colombier
casern(void)1073e12c5d1SDavid du Colombier void casern(void)
1083e12c5d1SDavid du Colombier {
109219b2ee8SDavid du Colombier int i, j, k;
1103e12c5d1SDavid du Colombier
1113e12c5d1SDavid du Colombier lgf++;
1123e12c5d1SDavid du Colombier skip();
1133e12c5d1SDavid du Colombier if ((i = getrq()) == 0 || (oldmn = findmn(i)) < 0)
1143e12c5d1SDavid du Colombier return;
1153e12c5d1SDavid du Colombier skip();
1163e12c5d1SDavid du Colombier clrmn(findmn(j = getrq()));
1173e12c5d1SDavid du Colombier if (j) {
118219b2ee8SDavid du Colombier munhash(&contabp[oldmn]);
119219b2ee8SDavid du Colombier contabp[oldmn].rq = j;
120219b2ee8SDavid du Colombier maddhash(&contabp[oldmn]);
121219b2ee8SDavid du Colombier if (dip != d )
122219b2ee8SDavid du Colombier for (k = dilev; k; k--)
123219b2ee8SDavid du Colombier if (d[k].curd == i)
124219b2ee8SDavid du Colombier d[k].curd = j;
1253e12c5d1SDavid du Colombier }
1263e12c5d1SDavid du Colombier }
1273e12c5d1SDavid du Colombier
maddhash(Contab * rp)1283e12c5d1SDavid du Colombier void maddhash(Contab *rp)
1293e12c5d1SDavid du Colombier {
1303e12c5d1SDavid du Colombier Contab **hp;
1313e12c5d1SDavid du Colombier
1323e12c5d1SDavid du Colombier if (rp->rq == 0)
1333e12c5d1SDavid du Colombier return;
1343e12c5d1SDavid du Colombier hp = &mhash[MHASH(rp->rq)];
1353e12c5d1SDavid du Colombier rp->link = *hp;
1363e12c5d1SDavid du Colombier *hp = rp;
1373e12c5d1SDavid du Colombier }
1383e12c5d1SDavid du Colombier
munhash(Contab * mp)1393e12c5d1SDavid du Colombier void munhash(Contab *mp)
1403e12c5d1SDavid du Colombier {
1413e12c5d1SDavid du Colombier Contab *p;
1423e12c5d1SDavid du Colombier Contab **lp;
1433e12c5d1SDavid du Colombier
1443e12c5d1SDavid du Colombier if (mp->rq == 0)
1453e12c5d1SDavid du Colombier return;
1463e12c5d1SDavid du Colombier lp = &mhash[MHASH(mp->rq)];
1473e12c5d1SDavid du Colombier p = *lp;
1483e12c5d1SDavid du Colombier while (p) {
1493e12c5d1SDavid du Colombier if (p == mp) {
1503e12c5d1SDavid du Colombier *lp = p->link;
1513e12c5d1SDavid du Colombier p->link = 0;
1523e12c5d1SDavid du Colombier return;
1533e12c5d1SDavid du Colombier }
1543e12c5d1SDavid du Colombier lp = &p->link;
1553e12c5d1SDavid du Colombier p = p->link;
1563e12c5d1SDavid du Colombier }
1573e12c5d1SDavid du Colombier }
1583e12c5d1SDavid du Colombier
mrehash(void)1593e12c5d1SDavid du Colombier void mrehash(void)
1603e12c5d1SDavid du Colombier {
1613e12c5d1SDavid du Colombier Contab *p;
1623e12c5d1SDavid du Colombier int i;
1633e12c5d1SDavid du Colombier
1643e12c5d1SDavid du Colombier for (i=0; i < MHASHSIZE; i++)
1653e12c5d1SDavid du Colombier mhash[i] = 0;
166219b2ee8SDavid du Colombier for (p=contabp; p < &contabp[nm]; p++)
1673e12c5d1SDavid du Colombier p->link = 0;
168219b2ee8SDavid du Colombier for (p=contabp; p < &contabp[nm]; p++) {
1693e12c5d1SDavid du Colombier if (p->rq == 0)
1703e12c5d1SDavid du Colombier continue;
1713e12c5d1SDavid du Colombier i = MHASH(p->rq);
1723e12c5d1SDavid du Colombier p->link = mhash[i];
1733e12c5d1SDavid du Colombier mhash[i] = p;
1743e12c5d1SDavid du Colombier }
1753e12c5d1SDavid du Colombier }
1763e12c5d1SDavid du Colombier
caserm(void)1773e12c5d1SDavid du Colombier void caserm(void)
1783e12c5d1SDavid du Colombier {
179*14f51593SDavid du Colombier int j, k;
1803e12c5d1SDavid du Colombier
1813e12c5d1SDavid du Colombier lgf++;
182219b2ee8SDavid du Colombier g0:
183219b2ee8SDavid du Colombier while (!skip() && (j = getrq()) != 0) {
184219b2ee8SDavid du Colombier if (dip != d)
185219b2ee8SDavid du Colombier for (k = dilev; k; k--)
186219b2ee8SDavid du Colombier if (d[k].curd == j) {
187219b2ee8SDavid du Colombier ERROR "cannot remove diversion %s during definition",
188219b2ee8SDavid du Colombier unpair(j) WARN;
189219b2ee8SDavid du Colombier goto g0;
190219b2ee8SDavid du Colombier }
1913e12c5d1SDavid du Colombier clrmn(findmn(j));
192219b2ee8SDavid du Colombier }
1933e12c5d1SDavid du Colombier lgf--;
1943e12c5d1SDavid du Colombier }
1953e12c5d1SDavid du Colombier
1963e12c5d1SDavid du Colombier
caseas(void)1973e12c5d1SDavid du Colombier void caseas(void)
1983e12c5d1SDavid du Colombier {
1993e12c5d1SDavid du Colombier app++;
2003e12c5d1SDavid du Colombier caseds();
2013e12c5d1SDavid du Colombier }
2023e12c5d1SDavid du Colombier
2033e12c5d1SDavid du Colombier
caseds(void)2043e12c5d1SDavid du Colombier void caseds(void)
2053e12c5d1SDavid du Colombier {
2063e12c5d1SDavid du Colombier ds++;
2073e12c5d1SDavid du Colombier casede();
2083e12c5d1SDavid du Colombier }
2093e12c5d1SDavid du Colombier
2103e12c5d1SDavid du Colombier
caseam(void)2113e12c5d1SDavid du Colombier void caseam(void)
2123e12c5d1SDavid du Colombier {
2133e12c5d1SDavid du Colombier app++;
2143e12c5d1SDavid du Colombier casede();
2153e12c5d1SDavid du Colombier }
2163e12c5d1SDavid du Colombier
2173e12c5d1SDavid du Colombier
casede(void)2183e12c5d1SDavid du Colombier void casede(void)
2193e12c5d1SDavid du Colombier {
2203e12c5d1SDavid du Colombier int i, req;
2213e12c5d1SDavid du Colombier Offset savoff;
2223e12c5d1SDavid du Colombier
2233e12c5d1SDavid du Colombier req = '.';
2243e12c5d1SDavid du Colombier lgf++;
2253e12c5d1SDavid du Colombier skip();
2263e12c5d1SDavid du Colombier if ((i = getrq()) == 0)
2273e12c5d1SDavid du Colombier goto de1;
2283e12c5d1SDavid du Colombier if ((offset = finds(i)) == 0)
2293e12c5d1SDavid du Colombier goto de1;
230219b2ee8SDavid du Colombier if (newmn)
231219b2ee8SDavid du Colombier savslot = newmn;
232219b2ee8SDavid du Colombier else
233219b2ee8SDavid du Colombier savslot = findmn(i);
234219b2ee8SDavid du Colombier savname = i;
2353e12c5d1SDavid du Colombier if (ds)
2363e12c5d1SDavid du Colombier copys();
2373e12c5d1SDavid du Colombier else
2383e12c5d1SDavid du Colombier req = copyb();
2393e12c5d1SDavid du Colombier clrmn(oldmn);
2403e12c5d1SDavid du Colombier if (newmn) {
241219b2ee8SDavid du Colombier if (contabp[newmn].rq)
242219b2ee8SDavid du Colombier munhash(&contabp[newmn]);
243219b2ee8SDavid du Colombier contabp[newmn].rq = i;
244219b2ee8SDavid du Colombier maddhash(&contabp[newmn]);
245219b2ee8SDavid du Colombier
2463e12c5d1SDavid du Colombier }
2473e12c5d1SDavid du Colombier if (apptr) {
2483e12c5d1SDavid du Colombier savoff = offset;
2493e12c5d1SDavid du Colombier offset = apptr;
2503e12c5d1SDavid du Colombier wbf((Tchar) IMP);
251*14f51593SDavid du Colombier offset = savoff; /* pointless */
2523e12c5d1SDavid du Colombier }
2533e12c5d1SDavid du Colombier offset = dip->op;
2543e12c5d1SDavid du Colombier if (req != '.')
2553e12c5d1SDavid du Colombier control(req, 1);
2563e12c5d1SDavid du Colombier de1:
2573e12c5d1SDavid du Colombier ds = app = 0;
2583e12c5d1SDavid du Colombier }
2593e12c5d1SDavid du Colombier
2603e12c5d1SDavid du Colombier
findmn(int i)2613e12c5d1SDavid du Colombier int findmn(int i)
2623e12c5d1SDavid du Colombier {
2633e12c5d1SDavid du Colombier Contab *p;
2643e12c5d1SDavid du Colombier
2653e12c5d1SDavid du Colombier for (p = mhash[MHASH(i)]; p; p = p->link)
2663e12c5d1SDavid du Colombier if (i == p->rq)
267219b2ee8SDavid du Colombier return(p - contabp);
2683e12c5d1SDavid du Colombier return(-1);
2693e12c5d1SDavid du Colombier }
2703e12c5d1SDavid du Colombier
2713e12c5d1SDavid du Colombier
clrmn(int i)2723e12c5d1SDavid du Colombier void clrmn(int i)
2733e12c5d1SDavid du Colombier {
2743e12c5d1SDavid du Colombier if (i >= 0) {
275219b2ee8SDavid du Colombier if (contabp[i].mx)
276219b2ee8SDavid du Colombier ffree(contabp[i].mx);
277219b2ee8SDavid du Colombier munhash(&contabp[i]);
278219b2ee8SDavid du Colombier contabp[i].rq = 0;
279219b2ee8SDavid du Colombier contabp[i].mx = 0;
280219b2ee8SDavid du Colombier contabp[i].emx = 0;
281219b2ee8SDavid du Colombier contabp[i].f = 0;
282219b2ee8SDavid du Colombier if (contabp[i].divsiz != NULL) {
283219b2ee8SDavid du Colombier free(contabp[i].divsiz);
284219b2ee8SDavid du Colombier contabp[i].divsiz = NULL;
285219b2ee8SDavid du Colombier }
286219b2ee8SDavid du Colombier if (freeslot > i)
287219b2ee8SDavid du Colombier freeslot = i;
288219b2ee8SDavid du Colombier }
289219b2ee8SDavid du Colombier }
290219b2ee8SDavid du Colombier
growcontab(void)291219b2ee8SDavid du Colombier void growcontab(void)
292219b2ee8SDavid du Colombier {
293219b2ee8SDavid du Colombier nm += MDELTA;
294219b2ee8SDavid du Colombier contabp = (Contab *) grow((char *) contabp , nm, sizeof(Contab));
295219b2ee8SDavid du Colombier if (contabp == NULL) {
296219b2ee8SDavid du Colombier ERROR "Too many (%d) string/macro names", nm WARN;
297219b2ee8SDavid du Colombier done2(02);
298219b2ee8SDavid du Colombier } else {
299219b2ee8SDavid du Colombier memset((char *)(contabp) + (nm - MDELTA) * sizeof(Contab),
300219b2ee8SDavid du Colombier 0, MDELTA * sizeof(Contab));
301219b2ee8SDavid du Colombier mrehash();
3023e12c5d1SDavid du Colombier }
3033e12c5d1SDavid du Colombier }
3043e12c5d1SDavid du Colombier
3053e12c5d1SDavid du Colombier
finds(int mn)3063e12c5d1SDavid du Colombier Offset finds(int mn)
3073e12c5d1SDavid du Colombier {
3083e12c5d1SDavid du Colombier int i;
3093e12c5d1SDavid du Colombier Offset savip;
3103e12c5d1SDavid du Colombier
3113e12c5d1SDavid du Colombier oldmn = findmn(mn);
3123e12c5d1SDavid du Colombier newmn = 0;
3133e12c5d1SDavid du Colombier apptr = 0;
314219b2ee8SDavid du Colombier if (app && oldmn >= 0 && contabp[oldmn].mx) {
3153e12c5d1SDavid du Colombier savip = ip;
316219b2ee8SDavid du Colombier ip = contabp[oldmn].emx;
3173e12c5d1SDavid du Colombier oldmn = -1;
3183e12c5d1SDavid du Colombier apptr = ip;
3193e12c5d1SDavid du Colombier if (!diflg)
3203e12c5d1SDavid du Colombier ip = incoff(ip);
3213e12c5d1SDavid du Colombier nextb = ip;
3223e12c5d1SDavid du Colombier ip = savip;
3233e12c5d1SDavid du Colombier } else {
324219b2ee8SDavid du Colombier for (i = freeslot; i < nm; i++) {
325219b2ee8SDavid du Colombier if (contabp[i].rq == 0)
3263e12c5d1SDavid du Colombier break;
3273e12c5d1SDavid du Colombier }
328219b2ee8SDavid du Colombier if (i == nm)
329219b2ee8SDavid du Colombier growcontab();
330219b2ee8SDavid du Colombier freeslot = i + 1;
331219b2ee8SDavid du Colombier if ((nextb = alloc()) == -1) {
3323e12c5d1SDavid du Colombier app = 0;
3333e12c5d1SDavid du Colombier if (macerr++ > 1)
3343e12c5d1SDavid du Colombier done2(02);
3353e12c5d1SDavid du Colombier if (nextb == 0)
336219b2ee8SDavid du Colombier ERROR "Not enough space for string/macro names" WARN;
3373e12c5d1SDavid du Colombier edone(04);
3383e12c5d1SDavid du Colombier return(offset = 0);
3393e12c5d1SDavid du Colombier }
340219b2ee8SDavid du Colombier contabp[i].mx = nextb;
3413e12c5d1SDavid du Colombier if (!diflg) {
3423e12c5d1SDavid du Colombier newmn = i;
3433e12c5d1SDavid du Colombier if (oldmn == -1)
344219b2ee8SDavid du Colombier contabp[i].rq = -1;
3453e12c5d1SDavid du Colombier } else {
346219b2ee8SDavid du Colombier contabp[i].rq = mn;
347219b2ee8SDavid du Colombier maddhash(&contabp[i]);
3483e12c5d1SDavid du Colombier }
3493e12c5d1SDavid du Colombier }
3503e12c5d1SDavid du Colombier app = 0;
3513e12c5d1SDavid du Colombier return(offset = nextb);
3523e12c5d1SDavid du Colombier }
3533e12c5d1SDavid du Colombier
skip(void)3543e12c5d1SDavid du Colombier int skip(void)
3553e12c5d1SDavid du Colombier {
3563e12c5d1SDavid du Colombier Tchar i;
3573e12c5d1SDavid du Colombier
358219b2ee8SDavid du Colombier while (cbits(i = getch()) == ' ' || ismot(i))
3593e12c5d1SDavid du Colombier ;
3603e12c5d1SDavid du Colombier ch = i;
3613e12c5d1SDavid du Colombier return(nlflg);
3623e12c5d1SDavid du Colombier }
3633e12c5d1SDavid du Colombier
3643e12c5d1SDavid du Colombier
copyb(void)3653e12c5d1SDavid du Colombier int copyb(void)
3663e12c5d1SDavid du Colombier {
3673e12c5d1SDavid du Colombier int i, j, state;
3683e12c5d1SDavid du Colombier Tchar ii;
3693e12c5d1SDavid du Colombier int req, k;
3703e12c5d1SDavid du Colombier Offset savoff;
371219b2ee8SDavid du Colombier Uchar *p;
3723e12c5d1SDavid du Colombier
3733e12c5d1SDavid du Colombier if (skip() || !(j = getrq()))
3743e12c5d1SDavid du Colombier j = '.';
3753e12c5d1SDavid du Colombier req = j;
3763e12c5d1SDavid du Colombier p = unpair(j);
3773e12c5d1SDavid du Colombier /* was: k = j >> BYTE; j &= BYTEMASK; */
3783e12c5d1SDavid du Colombier j = p[0];
3793e12c5d1SDavid du Colombier k = p[1];
3803e12c5d1SDavid du Colombier copyf++;
3813e12c5d1SDavid du Colombier flushi();
3823e12c5d1SDavid du Colombier nlflg = 0;
3833e12c5d1SDavid du Colombier state = 1;
384*14f51593SDavid du Colombier savoff = 0;
3853e12c5d1SDavid du Colombier
3863e12c5d1SDavid du Colombier /* state 0 eat up
3873e12c5d1SDavid du Colombier * state 1 look for .
3883e12c5d1SDavid du Colombier * state 2 look for first char of end macro
3893e12c5d1SDavid du Colombier * state 3 look for second char of end macro
3903e12c5d1SDavid du Colombier */
3913e12c5d1SDavid du Colombier
3923e12c5d1SDavid du Colombier while (1) {
3933e12c5d1SDavid du Colombier i = cbits(ii = getch());
3943e12c5d1SDavid du Colombier if (state == 3) {
3953e12c5d1SDavid du Colombier if (i == k)
3963e12c5d1SDavid du Colombier break;
3973e12c5d1SDavid du Colombier if (!k) {
3983e12c5d1SDavid du Colombier ch = ii;
3993e12c5d1SDavid du Colombier i = getach();
4003e12c5d1SDavid du Colombier ch = ii;
4013e12c5d1SDavid du Colombier if (!i)
4023e12c5d1SDavid du Colombier break;
4033e12c5d1SDavid du Colombier }
4043e12c5d1SDavid du Colombier state = 0;
4053e12c5d1SDavid du Colombier goto c0;
4063e12c5d1SDavid du Colombier }
4073e12c5d1SDavid du Colombier if (i == '\n') {
4083e12c5d1SDavid du Colombier state = 1;
4093e12c5d1SDavid du Colombier nlflg = 0;
4103e12c5d1SDavid du Colombier goto c0;
4113e12c5d1SDavid du Colombier }
4123e12c5d1SDavid du Colombier if (state == 1 && i == '.') {
4133e12c5d1SDavid du Colombier state++;
4143e12c5d1SDavid du Colombier savoff = offset;
4153e12c5d1SDavid du Colombier goto c0;
4163e12c5d1SDavid du Colombier }
4173e12c5d1SDavid du Colombier if (state == 2 && i == j) {
4183e12c5d1SDavid du Colombier state++;
4193e12c5d1SDavid du Colombier goto c0;
4203e12c5d1SDavid du Colombier }
4213e12c5d1SDavid du Colombier state = 0;
4223e12c5d1SDavid du Colombier c0:
4233e12c5d1SDavid du Colombier if (offset)
4243e12c5d1SDavid du Colombier wbf(ii);
4253e12c5d1SDavid du Colombier }
4263e12c5d1SDavid du Colombier if (offset) {
4273e12c5d1SDavid du Colombier offset = savoff;
4283e12c5d1SDavid du Colombier wbf((Tchar)0);
4293e12c5d1SDavid du Colombier }
4303e12c5d1SDavid du Colombier copyf--;
4313e12c5d1SDavid du Colombier return(req);
4323e12c5d1SDavid du Colombier }
4333e12c5d1SDavid du Colombier
4343e12c5d1SDavid du Colombier
copys(void)4353e12c5d1SDavid du Colombier void copys(void)
4363e12c5d1SDavid du Colombier {
4373e12c5d1SDavid du Colombier Tchar i;
4383e12c5d1SDavid du Colombier
4393e12c5d1SDavid du Colombier copyf++;
4403e12c5d1SDavid du Colombier if (skip())
4413e12c5d1SDavid du Colombier goto c0;
4423e12c5d1SDavid du Colombier if (cbits(i = getch()) != '"')
4433e12c5d1SDavid du Colombier wbf(i);
4443e12c5d1SDavid du Colombier while (cbits(i = getch()) != '\n')
4453e12c5d1SDavid du Colombier wbf(i);
4463e12c5d1SDavid du Colombier c0:
4473e12c5d1SDavid du Colombier wbf((Tchar)0);
4483e12c5d1SDavid du Colombier copyf--;
4493e12c5d1SDavid du Colombier }
4503e12c5d1SDavid du Colombier
4513e12c5d1SDavid du Colombier
alloc(void)4523e12c5d1SDavid du Colombier Offset alloc(void) /* return free Offset in nextb */
4533e12c5d1SDavid du Colombier {
4543e12c5d1SDavid du Colombier int i, j;
4553e12c5d1SDavid du Colombier
456219b2ee8SDavid du Colombier for (i = bfree; i < nblist; i++)
4573e12c5d1SDavid du Colombier if (blist[i].nextoff == 0)
4583e12c5d1SDavid du Colombier break;
4593e12c5d1SDavid du Colombier if (i == nblist) {
4603e12c5d1SDavid du Colombier blist = (Blockp *) realloc((char *) blist, 2 * nblist * sizeof(Blockp));
4613e12c5d1SDavid du Colombier if (blist == NULL) {
4623e12c5d1SDavid du Colombier ERROR "can't grow blist for string/macro defns" WARN;
4633e12c5d1SDavid du Colombier done2(2);
4643e12c5d1SDavid du Colombier }
4653e12c5d1SDavid du Colombier nblist *= 2;
4663e12c5d1SDavid du Colombier for (j = i; j < nblist; j++) {
4673e12c5d1SDavid du Colombier blist[j].nextoff = 0;
4683e12c5d1SDavid du Colombier blist[j].bp = 0;
4693e12c5d1SDavid du Colombier }
4703e12c5d1SDavid du Colombier }
4713e12c5d1SDavid du Colombier blist[i].nextoff = -1; /* this block is the end */
472219b2ee8SDavid du Colombier bfree = i + 1;
4733e12c5d1SDavid du Colombier if (blist[i].bp == 0)
4743e12c5d1SDavid du Colombier blist[i].bp = (Tchar *) calloc(BLK, sizeof(Tchar));
475219b2ee8SDavid du Colombier if (blist[i].bp == NULL) {
476219b2ee8SDavid du Colombier ERROR "can't allocate memory for string/macro definitions" WARN;
477219b2ee8SDavid du Colombier done2(2);
478219b2ee8SDavid du Colombier }
4793e12c5d1SDavid du Colombier nextb = (Offset) i * BLK;
4803e12c5d1SDavid du Colombier return nextb;
4813e12c5d1SDavid du Colombier }
4823e12c5d1SDavid du Colombier
4833e12c5d1SDavid du Colombier
ffree(Offset i)4843e12c5d1SDavid du Colombier void ffree(Offset i) /* free list of blocks starting at blist(o) */
4853e12c5d1SDavid du Colombier { /* (doesn't actually free the blocks, just the pointers) */
4863e12c5d1SDavid du Colombier int j;
4873e12c5d1SDavid du Colombier
4883e12c5d1SDavid du Colombier for ( ; blist[j = bindex(i)].nextoff != -1; ) {
489219b2ee8SDavid du Colombier if (bfree > j)
490219b2ee8SDavid du Colombier bfree = j;
4913e12c5d1SDavid du Colombier i = blist[j].nextoff;
4923e12c5d1SDavid du Colombier blist[j].nextoff = 0;
4933e12c5d1SDavid du Colombier }
4943e12c5d1SDavid du Colombier blist[j].nextoff = 0;
4953e12c5d1SDavid du Colombier }
4963e12c5d1SDavid du Colombier
4973e12c5d1SDavid du Colombier
wbf(Tchar i)4983e12c5d1SDavid du Colombier void wbf(Tchar i) /* store i into offset, get ready for next one */
4993e12c5d1SDavid du Colombier {
5003e12c5d1SDavid du Colombier int j, off;
5013e12c5d1SDavid du Colombier
5023e12c5d1SDavid du Colombier if (!offset)
5033e12c5d1SDavid du Colombier return;
5043e12c5d1SDavid du Colombier j = bindex(offset);
505219b2ee8SDavid du Colombier if (i == 0)
506219b2ee8SDavid du Colombier contabp[savslot].emx = offset;
5073e12c5d1SDavid du Colombier off = boffset(offset);
508*14f51593SDavid du Colombier blist[j].bp[off] = i;
5093e12c5d1SDavid du Colombier offset++;
5103e12c5d1SDavid du Colombier if (pastend(offset)) { /* off the end of this block */
5113e12c5d1SDavid du Colombier if (blist[j].nextoff == -1) {
5123e12c5d1SDavid du Colombier if ((nextb = alloc()) == -1) {
5133e12c5d1SDavid du Colombier ERROR "Out of temp file space" WARN;
5143e12c5d1SDavid du Colombier done2(01);
5153e12c5d1SDavid du Colombier }
5163e12c5d1SDavid du Colombier blist[j].nextoff = nextb;
5173e12c5d1SDavid du Colombier }
5183e12c5d1SDavid du Colombier offset = blist[j].nextoff;
5193e12c5d1SDavid du Colombier }
5203e12c5d1SDavid du Colombier }
5213e12c5d1SDavid du Colombier
5223e12c5d1SDavid du Colombier
rbf(void)5233e12c5d1SDavid du Colombier Tchar rbf(void) /* return next char from blist[] block */
5243e12c5d1SDavid du Colombier {
5253e12c5d1SDavid du Colombier Tchar i, j;
5263e12c5d1SDavid du Colombier
5273e12c5d1SDavid du Colombier if (ip == RD_OFFSET) { /* for rdtty */
5283e12c5d1SDavid du Colombier if (j = rdtty())
5293e12c5d1SDavid du Colombier return(j);
5303e12c5d1SDavid du Colombier else
5313e12c5d1SDavid du Colombier return(popi());
5323e12c5d1SDavid du Colombier }
5333e12c5d1SDavid du Colombier
5343e12c5d1SDavid du Colombier i = rbf0(ip);
5353e12c5d1SDavid du Colombier if (i == 0) {
5363e12c5d1SDavid du Colombier if (!app)
5373e12c5d1SDavid du Colombier i = popi();
5383e12c5d1SDavid du Colombier return(i);
5393e12c5d1SDavid du Colombier }
5403e12c5d1SDavid du Colombier ip = incoff(ip);
5413e12c5d1SDavid du Colombier return(i);
5423e12c5d1SDavid du Colombier }
5433e12c5d1SDavid du Colombier
5443e12c5d1SDavid du Colombier
xxxincoff(Offset p)5453e12c5d1SDavid du Colombier Offset xxxincoff(Offset p) /* get next blist[] block */
5463e12c5d1SDavid du Colombier {
5473e12c5d1SDavid du Colombier p++;
5483e12c5d1SDavid du Colombier if (pastend(p)) { /* off the end of this block */
5493e12c5d1SDavid du Colombier if ((p = blist[bindex(p-1)].nextoff) == -1) { /* and nothing was allocated after it */
5503e12c5d1SDavid du Colombier ERROR "Bad storage allocation" WARN;
5513e12c5d1SDavid du Colombier done2(-5);
5523e12c5d1SDavid du Colombier }
5533e12c5d1SDavid du Colombier }
5543e12c5d1SDavid du Colombier return(p);
5553e12c5d1SDavid du Colombier }
5563e12c5d1SDavid du Colombier
5573e12c5d1SDavid du Colombier
popi(void)5583e12c5d1SDavid du Colombier Tchar popi(void)
5593e12c5d1SDavid du Colombier {
5603e12c5d1SDavid du Colombier Stack *p;
5613e12c5d1SDavid du Colombier
5623e12c5d1SDavid du Colombier if (frame == stk)
5633e12c5d1SDavid du Colombier return(0);
5643e12c5d1SDavid du Colombier if (strflg)
5653e12c5d1SDavid du Colombier strflg--;
5663e12c5d1SDavid du Colombier p = nxf = frame;
5673e12c5d1SDavid du Colombier p->nargs = 0;
5683e12c5d1SDavid du Colombier frame = p->pframe;
5693e12c5d1SDavid du Colombier ip = p->pip;
5703e12c5d1SDavid du Colombier pendt = p->ppendt;
5713e12c5d1SDavid du Colombier lastpbp = p->lastpbp;
5723e12c5d1SDavid du Colombier return(p->pch);
5733e12c5d1SDavid du Colombier }
5743e12c5d1SDavid du Colombier
5753e12c5d1SDavid du Colombier /*
5763e12c5d1SDavid du Colombier * test that the end of the allocation is above a certain location
5773e12c5d1SDavid du Colombier * in memory
5783e12c5d1SDavid du Colombier */
5793e12c5d1SDavid du Colombier #define SPACETEST(base, size) \
5803e12c5d1SDavid du Colombier if ((char*)base + size >= (char*)stk+STACKSIZE) \
5813e12c5d1SDavid du Colombier ERROR "Stacksize overflow in n3" WARN
5823e12c5d1SDavid du Colombier
pushi(Offset newip,int mname)5833e12c5d1SDavid du Colombier Offset pushi(Offset newip, int mname)
5843e12c5d1SDavid du Colombier {
5853e12c5d1SDavid du Colombier Stack *p;
5863e12c5d1SDavid du Colombier
5873e12c5d1SDavid du Colombier SPACETEST(nxf, sizeof(Stack));
5883e12c5d1SDavid du Colombier p = nxf;
5893e12c5d1SDavid du Colombier p->pframe = frame;
5903e12c5d1SDavid du Colombier p->pip = ip;
5913e12c5d1SDavid du Colombier p->ppendt = pendt;
5923e12c5d1SDavid du Colombier p->pch = ch;
5933e12c5d1SDavid du Colombier p->lastpbp = lastpbp;
5943e12c5d1SDavid du Colombier p->mname = mname;
5953e12c5d1SDavid du Colombier lastpbp = pbp;
5963e12c5d1SDavid du Colombier pendt = ch = 0;
5973e12c5d1SDavid du Colombier frame = nxf;
5983e12c5d1SDavid du Colombier if (nxf->nargs == 0)
5993e12c5d1SDavid du Colombier nxf += 1;
6003e12c5d1SDavid du Colombier else
6013e12c5d1SDavid du Colombier nxf = (Stack *)argtop;
6023e12c5d1SDavid du Colombier return(ip = newip);
6033e12c5d1SDavid du Colombier }
6043e12c5d1SDavid du Colombier
6053e12c5d1SDavid du Colombier
setbrk(int x)6063e12c5d1SDavid du Colombier void *setbrk(int x)
6073e12c5d1SDavid du Colombier {
6083e12c5d1SDavid du Colombier char *i;
6093e12c5d1SDavid du Colombier
6103e12c5d1SDavid du Colombier if ((i = (char *) calloc(x, 1)) == 0) {
6113e12c5d1SDavid du Colombier ERROR "Core limit reached" WARN;
6123e12c5d1SDavid du Colombier edone(0100);
6133e12c5d1SDavid du Colombier }
6143e12c5d1SDavid du Colombier return(i);
6153e12c5d1SDavid du Colombier }
6163e12c5d1SDavid du Colombier
6173e12c5d1SDavid du Colombier
getsn(void)6183e12c5d1SDavid du Colombier int getsn(void)
6193e12c5d1SDavid du Colombier {
6203e12c5d1SDavid du Colombier int i;
6213e12c5d1SDavid du Colombier
6223e12c5d1SDavid du Colombier if ((i = getach()) == 0)
6233e12c5d1SDavid du Colombier return(0);
6243e12c5d1SDavid du Colombier if (i == '(')
6253e12c5d1SDavid du Colombier return(getrq());
6263e12c5d1SDavid du Colombier else
6273e12c5d1SDavid du Colombier return(i);
6283e12c5d1SDavid du Colombier }
6293e12c5d1SDavid du Colombier
6303e12c5d1SDavid du Colombier
setstr(void)6313e12c5d1SDavid du Colombier Offset setstr(void)
6323e12c5d1SDavid du Colombier {
6333e12c5d1SDavid du Colombier int i, j;
6343e12c5d1SDavid du Colombier
6353e12c5d1SDavid du Colombier lgf++;
636219b2ee8SDavid du Colombier if ((i = getsn()) == 0 || (j = findmn(i)) == -1 || !contabp[j].mx) {
6373e12c5d1SDavid du Colombier lgf--;
6383e12c5d1SDavid du Colombier return(0);
6393e12c5d1SDavid du Colombier } else {
6403e12c5d1SDavid du Colombier SPACETEST(nxf, sizeof(Stack));
6413e12c5d1SDavid du Colombier nxf->nargs = 0;
6423e12c5d1SDavid du Colombier strflg++;
6433e12c5d1SDavid du Colombier lgf--;
644219b2ee8SDavid du Colombier return pushi(contabp[j].mx, i);
6453e12c5d1SDavid du Colombier }
6463e12c5d1SDavid du Colombier }
6473e12c5d1SDavid du Colombier
6483e12c5d1SDavid du Colombier
6493e12c5d1SDavid du Colombier
collect(void)6503e12c5d1SDavid du Colombier void collect(void)
6513e12c5d1SDavid du Colombier {
6523e12c5d1SDavid du Colombier int j;
6533e12c5d1SDavid du Colombier Tchar i, *strp, *lim, **argpp, **argppend;
6543e12c5d1SDavid du Colombier int quote;
6553e12c5d1SDavid du Colombier Stack *savnxf;
6563e12c5d1SDavid du Colombier
6573e12c5d1SDavid du Colombier copyf++;
6583e12c5d1SDavid du Colombier nxf->nargs = 0;
6593e12c5d1SDavid du Colombier savnxf = nxf;
6603e12c5d1SDavid du Colombier if (skip())
6613e12c5d1SDavid du Colombier goto rtn;
6623e12c5d1SDavid du Colombier
6633e12c5d1SDavid du Colombier {
6643e12c5d1SDavid du Colombier char *memp;
6653e12c5d1SDavid du Colombier memp = (char *)savnxf;
6663e12c5d1SDavid du Colombier /*
6673e12c5d1SDavid du Colombier * 1 s structure for the macro descriptor
6683e12c5d1SDavid du Colombier * APERMAC Tchar *'s for pointers into the strings
6693e12c5d1SDavid du Colombier * space for the Tchar's themselves
6703e12c5d1SDavid du Colombier */
6713e12c5d1SDavid du Colombier memp += sizeof(Stack);
6723e12c5d1SDavid du Colombier /*
6733e12c5d1SDavid du Colombier * CPERMAC = the total # of characters for ALL arguments
6743e12c5d1SDavid du Colombier */
6753e12c5d1SDavid du Colombier #define CPERMAC 200
6763e12c5d1SDavid du Colombier #define APERMAC 9
6773e12c5d1SDavid du Colombier memp += APERMAC * sizeof(Tchar *);
6783e12c5d1SDavid du Colombier memp += CPERMAC * sizeof(Tchar);
6793e12c5d1SDavid du Colombier nxf = (Stack *)memp;
6803e12c5d1SDavid du Colombier }
6813e12c5d1SDavid du Colombier lim = (Tchar *)nxf;
6823e12c5d1SDavid du Colombier argpp = (Tchar **)(savnxf + 1);
6833e12c5d1SDavid du Colombier argppend = &argpp[APERMAC];
6843e12c5d1SDavid du Colombier SPACETEST(argppend, sizeof(Tchar *));
6853e12c5d1SDavid du Colombier strp = (Tchar *)argppend;
6863e12c5d1SDavid du Colombier /*
6873e12c5d1SDavid du Colombier * Zero out all the string pointers before filling them in.
6883e12c5d1SDavid du Colombier */
6893e12c5d1SDavid du Colombier for (j = 0; j < APERMAC; j++)
6903e12c5d1SDavid du Colombier argpp[j] = 0;
6913e12c5d1SDavid du Colombier /* ERROR "savnxf=0x%x,nxf=0x%x,argpp=0x%x,strp=argppend=0x%x, lim=0x%x",
6923e12c5d1SDavid du Colombier * savnxf, nxf, argpp, strp, lim WARN;
6933e12c5d1SDavid du Colombier */
6943e12c5d1SDavid du Colombier strflg = 0;
6953e12c5d1SDavid du Colombier while (argpp != argppend && !skip()) {
6963e12c5d1SDavid du Colombier *argpp++ = strp;
6973e12c5d1SDavid du Colombier quote = 0;
6983e12c5d1SDavid du Colombier if (cbits(i = getch()) == '"')
6993e12c5d1SDavid du Colombier quote++;
7003e12c5d1SDavid du Colombier else
7013e12c5d1SDavid du Colombier ch = i;
7023e12c5d1SDavid du Colombier while (1) {
7033e12c5d1SDavid du Colombier i = getch();
7043e12c5d1SDavid du Colombier /* fprintf(stderr, "collect %c %d\n", cbits(i), cbits(i)); */
7053e12c5d1SDavid du Colombier if (nlflg || (!quote && argpp != argppend && cbits(i) == ' '))
7063e12c5d1SDavid du Colombier break; /* collects rest into $9 */
7073e12c5d1SDavid du Colombier if ( quote
7083e12c5d1SDavid du Colombier && cbits(i) == '"'
7093e12c5d1SDavid du Colombier && cbits(i = getch()) != '"') {
7103e12c5d1SDavid du Colombier ch = i;
7113e12c5d1SDavid du Colombier break;
7123e12c5d1SDavid du Colombier }
7133e12c5d1SDavid du Colombier *strp++ = i;
7143e12c5d1SDavid du Colombier if (strflg && strp >= lim) {
7153e12c5d1SDavid du Colombier /* ERROR "strp=0x%x, lim = 0x%x", strp, lim WARN; */
7163e12c5d1SDavid du Colombier ERROR "Macro argument too long" WARN;
7173e12c5d1SDavid du Colombier copyf--;
7183e12c5d1SDavid du Colombier edone(004);
7193e12c5d1SDavid du Colombier }
7203e12c5d1SDavid du Colombier SPACETEST(strp, 3 * sizeof(Tchar));
7213e12c5d1SDavid du Colombier }
7223e12c5d1SDavid du Colombier *strp++ = 0;
7233e12c5d1SDavid du Colombier }
7243e12c5d1SDavid du Colombier nxf = savnxf;
7253e12c5d1SDavid du Colombier nxf->nargs = argpp - (Tchar **)(savnxf + 1);
7263e12c5d1SDavid du Colombier argtop = strp;
7273e12c5d1SDavid du Colombier rtn:
7283e12c5d1SDavid du Colombier copyf--;
7293e12c5d1SDavid du Colombier }
7303e12c5d1SDavid du Colombier
7313e12c5d1SDavid du Colombier
seta(void)7323e12c5d1SDavid du Colombier void seta(void)
7333e12c5d1SDavid du Colombier {
7343e12c5d1SDavid du Colombier int i;
7353e12c5d1SDavid du Colombier
7363e12c5d1SDavid du Colombier i = cbits(getch()) - '0';
7373e12c5d1SDavid du Colombier if (i > 0 && i <= APERMAC && i <= frame->nargs)
7383e12c5d1SDavid du Colombier pushback(*(((Tchar **)(frame + 1)) + i - 1));
7393e12c5d1SDavid du Colombier }
7403e12c5d1SDavid du Colombier
7413e12c5d1SDavid du Colombier
caseda(void)7423e12c5d1SDavid du Colombier void caseda(void)
7433e12c5d1SDavid du Colombier {
7443e12c5d1SDavid du Colombier app++;
7453e12c5d1SDavid du Colombier casedi();
7463e12c5d1SDavid du Colombier }
7473e12c5d1SDavid du Colombier
casegd(void)748219b2ee8SDavid du Colombier void casegd(void)
749219b2ee8SDavid du Colombier {
750219b2ee8SDavid du Colombier int i, j;
751219b2ee8SDavid du Colombier
752219b2ee8SDavid du Colombier skip();
753219b2ee8SDavid du Colombier if ((i = getrq()) == 0)
754219b2ee8SDavid du Colombier return;
755219b2ee8SDavid du Colombier if ((j = findmn(i)) >= 0) {
756219b2ee8SDavid du Colombier if (contabp[j].divsiz != NULL) {
757219b2ee8SDavid du Colombier numtabp[DN].val = contabp[j].divsiz->dix;
758219b2ee8SDavid du Colombier numtabp[DL].val = contabp[j].divsiz->diy;
759219b2ee8SDavid du Colombier }
760219b2ee8SDavid du Colombier }
761219b2ee8SDavid du Colombier }
762219b2ee8SDavid du Colombier
763219b2ee8SDavid du Colombier #define FINDDIV(o) if ((o = findmn(dip->curd)) < 0) \
764219b2ee8SDavid du Colombier ERROR "lost diversion %s", unpair(dip->curd) WARN
7653e12c5d1SDavid du Colombier
casedi(void)7663e12c5d1SDavid du Colombier void casedi(void)
7673e12c5d1SDavid du Colombier {
7683e12c5d1SDavid du Colombier int i, j, *k;
7693e12c5d1SDavid du Colombier
7703e12c5d1SDavid du Colombier lgf++;
7713e12c5d1SDavid du Colombier if (skip() || (i = getrq()) == 0) {
772219b2ee8SDavid du Colombier if (dip != d) {
773219b2ee8SDavid du Colombier FINDDIV(savslot);
7743e12c5d1SDavid du Colombier wbf((Tchar)0);
775219b2ee8SDavid du Colombier }
7763e12c5d1SDavid du Colombier if (dilev > 0) {
777219b2ee8SDavid du Colombier numtabp[DN].val = dip->dnl;
778219b2ee8SDavid du Colombier numtabp[DL].val = dip->maxl;
779219b2ee8SDavid du Colombier FINDDIV(j);
780219b2ee8SDavid du Colombier if ((contabp[j].divsiz = (Divsiz *) malloc(sizeof(Divsiz))) == NULL) {
78180ee5cbfSDavid du Colombier ERROR "Cannot alloc diversion size" WARN;
782219b2ee8SDavid du Colombier done2(1);
783219b2ee8SDavid du Colombier } else {
784219b2ee8SDavid du Colombier contabp[j].divsiz->dix = numtabp[DN].val;
785219b2ee8SDavid du Colombier contabp[j].divsiz->diy = numtabp[DL].val;
786219b2ee8SDavid du Colombier }
7873e12c5d1SDavid du Colombier dip = &d[--dilev];
7883e12c5d1SDavid du Colombier offset = dip->op;
7893e12c5d1SDavid du Colombier }
7903e12c5d1SDavid du Colombier goto rtn;
7913e12c5d1SDavid du Colombier }
7923e12c5d1SDavid du Colombier if (++dilev == NDI) {
7933e12c5d1SDavid du Colombier --dilev;
7943e12c5d1SDavid du Colombier ERROR "Diversions nested too deep" WARN;
7953e12c5d1SDavid du Colombier edone(02);
7963e12c5d1SDavid du Colombier }
797219b2ee8SDavid du Colombier if (dip != d) {
798219b2ee8SDavid du Colombier FINDDIV(j);
799219b2ee8SDavid du Colombier savslot = j;
8003e12c5d1SDavid du Colombier wbf((Tchar)0);
801219b2ee8SDavid du Colombier }
8023e12c5d1SDavid du Colombier diflg++;
8033e12c5d1SDavid du Colombier dip = &d[dilev];
8043e12c5d1SDavid du Colombier dip->op = finds(i);
8053e12c5d1SDavid du Colombier dip->curd = i;
8063e12c5d1SDavid du Colombier clrmn(oldmn);
8073e12c5d1SDavid du Colombier k = (int *) & dip->dnl;
8083e12c5d1SDavid du Colombier for (j = 0; j < 10; j++)
8093e12c5d1SDavid du Colombier k[j] = 0; /*not op and curd*/
8103e12c5d1SDavid du Colombier rtn:
8113e12c5d1SDavid du Colombier app = 0;
8123e12c5d1SDavid du Colombier diflg = 0;
8133e12c5d1SDavid du Colombier }
8143e12c5d1SDavid du Colombier
8153e12c5d1SDavid du Colombier
casedt(void)8163e12c5d1SDavid du Colombier void casedt(void)
8173e12c5d1SDavid du Colombier {
8183e12c5d1SDavid du Colombier lgf++;
8193e12c5d1SDavid du Colombier dip->dimac = dip->ditrap = dip->ditf = 0;
8203e12c5d1SDavid du Colombier skip();
8213e12c5d1SDavid du Colombier dip->ditrap = vnumb((int *)0);
8223e12c5d1SDavid du Colombier if (nonumb)
8233e12c5d1SDavid du Colombier return;
8243e12c5d1SDavid du Colombier skip();
8253e12c5d1SDavid du Colombier dip->dimac = getrq();
8263e12c5d1SDavid du Colombier }
8273e12c5d1SDavid du Colombier
828219b2ee8SDavid du Colombier #define LNSIZE 4000
casetl(void)8293e12c5d1SDavid du Colombier void casetl(void)
8303e12c5d1SDavid du Colombier {
8313e12c5d1SDavid du Colombier int j;
8323e12c5d1SDavid du Colombier int w[3];
8333e12c5d1SDavid du Colombier Tchar buf[LNSIZE];
8343e12c5d1SDavid du Colombier Tchar *tp;
8353e12c5d1SDavid du Colombier Tchar i, delim;
8363e12c5d1SDavid du Colombier
8373e12c5d1SDavid du Colombier /*
8383e12c5d1SDavid du Colombier * bug fix
8393e12c5d1SDavid du Colombier *
8403e12c5d1SDavid du Colombier * if .tl is the first thing in the file, the p1
8413e12c5d1SDavid du Colombier * doesn't come out, also the pagenumber will be 0
8423e12c5d1SDavid du Colombier *
8433e12c5d1SDavid du Colombier * tends too confuse the device filter (and the user as well)
8443e12c5d1SDavid du Colombier */
845219b2ee8SDavid du Colombier if (dip == d && numtabp[NL].val == -1)
8463e12c5d1SDavid du Colombier newline(1);
8473e12c5d1SDavid du Colombier dip->nls = 0;
8483e12c5d1SDavid du Colombier skip();
8493e12c5d1SDavid du Colombier if (ismot(delim = getch())) {
8503e12c5d1SDavid du Colombier ch = delim;
8513e12c5d1SDavid du Colombier delim = '\'';
8523e12c5d1SDavid du Colombier } else
8533e12c5d1SDavid du Colombier delim = cbits(delim);
8543e12c5d1SDavid du Colombier tp = buf;
855219b2ee8SDavid du Colombier numtabp[HP].val = 0;
8563e12c5d1SDavid du Colombier w[0] = w[1] = w[2] = 0;
8573e12c5d1SDavid du Colombier j = 0;
8583e12c5d1SDavid du Colombier while (cbits(i = getch()) != '\n') {
8593e12c5d1SDavid du Colombier if (cbits(i) == cbits(delim)) {
8603e12c5d1SDavid du Colombier if (j < 3)
861219b2ee8SDavid du Colombier w[j] = numtabp[HP].val;
862219b2ee8SDavid du Colombier numtabp[HP].val = 0;
863219b2ee8SDavid du Colombier if (w[j] != 0)
864219b2ee8SDavid du Colombier *tp++ = WORDSP;
8653e12c5d1SDavid du Colombier j++;
8663e12c5d1SDavid du Colombier *tp++ = 0;
8673e12c5d1SDavid du Colombier } else {
8683e12c5d1SDavid du Colombier if (cbits(i) == pagech) {
869219b2ee8SDavid du Colombier setn1(numtabp[PN].val, numtabp[findr('%')].fmt,
8703e12c5d1SDavid du Colombier i&SFMASK);
8713e12c5d1SDavid du Colombier continue;
8723e12c5d1SDavid du Colombier }
873219b2ee8SDavid du Colombier numtabp[HP].val += width(i);
874219b2ee8SDavid du Colombier if (tp < &buf[LNSIZE-10]) {
875219b2ee8SDavid du Colombier if (cbits(i) == ' ' && *tp != WORDSP)
876219b2ee8SDavid du Colombier *tp++ = WORDSP;
8773e12c5d1SDavid du Colombier *tp++ = i;
878219b2ee8SDavid du Colombier } else {
879219b2ee8SDavid du Colombier ERROR "Overflow in casetl" WARN;
880219b2ee8SDavid du Colombier }
8813e12c5d1SDavid du Colombier }
8823e12c5d1SDavid du Colombier }
8833e12c5d1SDavid du Colombier if (j<3)
884219b2ee8SDavid du Colombier w[j] = numtabp[HP].val;
8853e12c5d1SDavid du Colombier *tp++ = 0;
8863e12c5d1SDavid du Colombier *tp++ = 0;
8873e12c5d1SDavid du Colombier *tp = 0;
8883e12c5d1SDavid du Colombier tp = buf;
8893e12c5d1SDavid du Colombier if (NROFF)
8903e12c5d1SDavid du Colombier horiz(po);
8913e12c5d1SDavid du Colombier while (i = *tp++)
8923e12c5d1SDavid du Colombier pchar(i);
8933e12c5d1SDavid du Colombier if (w[1] || w[2])
8943e12c5d1SDavid du Colombier horiz(j = quant((lt - w[1]) / 2 - w[0], HOR));
8953e12c5d1SDavid du Colombier while (i = *tp++)
8963e12c5d1SDavid du Colombier pchar(i);
8973e12c5d1SDavid du Colombier if (w[2]) {
8983e12c5d1SDavid du Colombier horiz(lt - w[0] - w[1] - w[2] - j);
8993e12c5d1SDavid du Colombier while (i = *tp++)
9003e12c5d1SDavid du Colombier pchar(i);
9013e12c5d1SDavid du Colombier }
9023e12c5d1SDavid du Colombier newline(0);
9033e12c5d1SDavid du Colombier if (dip != d) {
9043e12c5d1SDavid du Colombier if (dip->dnl > dip->hnl)
9053e12c5d1SDavid du Colombier dip->hnl = dip->dnl;
9063e12c5d1SDavid du Colombier } else {
907219b2ee8SDavid du Colombier if (numtabp[NL].val > dip->hnl)
908219b2ee8SDavid du Colombier dip->hnl = numtabp[NL].val;
9093e12c5d1SDavid du Colombier }
9103e12c5d1SDavid du Colombier }
9113e12c5d1SDavid du Colombier
9123e12c5d1SDavid du Colombier
casepc(void)9133e12c5d1SDavid du Colombier void casepc(void)
9143e12c5d1SDavid du Colombier {
9153e12c5d1SDavid du Colombier pagech = chget(IMP);
9163e12c5d1SDavid du Colombier }
9173e12c5d1SDavid du Colombier
9183e12c5d1SDavid du Colombier
casepm(void)9193e12c5d1SDavid du Colombier void casepm(void)
9203e12c5d1SDavid du Colombier {
9213e12c5d1SDavid du Colombier int i, k;
9223e12c5d1SDavid du Colombier int xx, cnt, tcnt, kk, tot;
9233e12c5d1SDavid du Colombier Offset j;
9243e12c5d1SDavid du Colombier
9253e12c5d1SDavid du Colombier kk = cnt = tcnt = 0;
9263e12c5d1SDavid du Colombier tot = !skip();
9273e12c5d1SDavid du Colombier stackdump();
928219b2ee8SDavid du Colombier for (i = 0; i < nm; i++) {
929219b2ee8SDavid du Colombier if ((xx = contabp[i].rq) == 0 || contabp[i].mx == 0)
9303e12c5d1SDavid du Colombier continue;
9313e12c5d1SDavid du Colombier tcnt++;
932219b2ee8SDavid du Colombier j = contabp[i].mx;
9333e12c5d1SDavid du Colombier for (k = 1; (j = blist[bindex(j)].nextoff) != -1; )
9343e12c5d1SDavid du Colombier k++;
9353e12c5d1SDavid du Colombier cnt++;
9363e12c5d1SDavid du Colombier kk += k;
9373e12c5d1SDavid du Colombier if (!tot)
9383e12c5d1SDavid du Colombier fprintf(stderr, "%-2.2s %d\n", unpair(xx), k);
9393e12c5d1SDavid du Colombier }
9403e12c5d1SDavid du Colombier fprintf(stderr, "pm: total %d, macros %d, space %d\n", tcnt, cnt, kk);
9413e12c5d1SDavid du Colombier }
9423e12c5d1SDavid du Colombier
stackdump(void)9433e12c5d1SDavid du Colombier void stackdump(void) /* dumps stack of macros in process */
9443e12c5d1SDavid du Colombier {
9453e12c5d1SDavid du Colombier Stack *p;
9463e12c5d1SDavid du Colombier
9473e12c5d1SDavid du Colombier if (frame != stk) {
9483e12c5d1SDavid du Colombier fprintf(stderr, "stack: ");
9493e12c5d1SDavid du Colombier for (p = frame; p != stk; p = p->pframe)
9503e12c5d1SDavid du Colombier fprintf(stderr, "%s ", unpair(p->mname));
9513e12c5d1SDavid du Colombier fprintf(stderr, "\n");
9523e12c5d1SDavid du Colombier }
9533e12c5d1SDavid du Colombier }
954