123881Sjaap #ifndef lint
2*45477Skarels /*
330220Sjaap static char sccsid[] = "@(#)n3.c 2.3 (CWI) 86/11/27";
4*45477Skarels */
5*45477Skarels static char sccsid[] = "@(#)n3.c 2.4 (Berkeley) 11/03/90";
623881Sjaap #endif lint
723903Sjaap /* @(#)n3.c 1.1 */
823903Sjaap /*
923903Sjaap * troff3.c
1023903Sjaap *
1123903Sjaap * macro and string routines, storage allocation
1223903Sjaap */
1323881Sjaap
1423903Sjaap
1523881Sjaap #include "tdef.h"
1623881Sjaap #ifdef NROFF
1723881Sjaap #include "tw.h"
1823881Sjaap #endif
1923881Sjaap #include <sgtty.h>
2023881Sjaap #include "ext.h"
2123903Sjaap
2223903Sjaap #define MHASH(x) ((x>>6)^x)&0177
2323903Sjaap struct contab *mhash[128]; /* 128 == the 0177 on line above */
2423903Sjaap #define blisti(i) (((i)-NEV*(int)sizeof(env))/BLK)
2523881Sjaap filep blist[NBLIST];
2623881Sjaap tchar *argtop;
2723881Sjaap int pagech = '%';
2823881Sjaap int strflg;
2923881Sjaap
3023881Sjaap tchar *wbuf;
3123903Sjaap tchar corebuf[NEV*sizeof(env)/sizeof(tchar) + NBLIST*BLK+ 1];
3223881Sjaap
caseig()3323881Sjaap caseig()
3423881Sjaap {
3523881Sjaap register i;
3623881Sjaap
3723881Sjaap offset = 0;
3823881Sjaap if ((i = copyb()) != '.')
3923881Sjaap control(i, 1);
4023881Sjaap }
4123881Sjaap
4223881Sjaap
casern()4323881Sjaap casern()
4423881Sjaap {
4523881Sjaap register i, j;
4623881Sjaap
4723881Sjaap lgf++;
4823881Sjaap skip();
4923881Sjaap if ((i = getrq()) == 0 || (oldmn = findmn(i)) < 0)
5023881Sjaap return;
5123881Sjaap skip();
5223881Sjaap clrmn(findmn(j = getrq()));
5323903Sjaap if (j) {
5423903Sjaap munhash(&contab[oldmn]);
5523903Sjaap contab[oldmn].rq = j;
5623903Sjaap maddhash(&contab[oldmn]);
5723903Sjaap }
5823881Sjaap }
5923881Sjaap
maddhash(rp)6023903Sjaap maddhash(rp)
6123903Sjaap register struct contab *rp;
6223903Sjaap {
6323903Sjaap register struct contab **hp;
6423881Sjaap
6523903Sjaap if (rp->rq == 0)
6623903Sjaap return;
6723903Sjaap hp = &mhash[MHASH(rp->rq)];
6823903Sjaap rp->link = *hp;
6923903Sjaap *hp = rp;
7023903Sjaap }
7123903Sjaap
munhash(mp)7223903Sjaap munhash(mp)
7323903Sjaap register struct contab *mp;
7423903Sjaap {
7523903Sjaap register struct contab *p;
7623903Sjaap register struct contab **lp;
7723903Sjaap
7823903Sjaap if (mp->rq == 0)
7923903Sjaap return;
8023903Sjaap lp = &mhash[MHASH(mp->rq)];
8123903Sjaap p = *lp;
8223903Sjaap while (p) {
8323903Sjaap if (p == mp) {
8423903Sjaap *lp = p->link;
8523903Sjaap p->link = 0;
8623903Sjaap return;
8723903Sjaap }
8823903Sjaap lp = &p->link;
8923903Sjaap p = p->link;
9023903Sjaap }
9123903Sjaap }
9223903Sjaap
mrehash()9323903Sjaap mrehash()
9423903Sjaap {
9523903Sjaap register struct contab *p;
9623903Sjaap register i;
9723903Sjaap
9823903Sjaap for (i=0; i<128; i++)
9923903Sjaap mhash[i] = 0;
10023903Sjaap for (p=contab; p < &contab[NM]; p++)
10123903Sjaap p->link = 0;
10223903Sjaap for (p=contab; p < &contab[NM]; p++) {
10323903Sjaap if (p->rq == 0)
10423903Sjaap continue;
10523903Sjaap i = MHASH(p->rq);
10623903Sjaap p->link = mhash[i];
10723903Sjaap mhash[i] = p;
10823903Sjaap }
10923903Sjaap }
11023903Sjaap
caserm()11123881Sjaap caserm()
11223881Sjaap {
11323903Sjaap int j;
11423903Sjaap
11523881Sjaap lgf++;
11623903Sjaap while (!skip() && (j = getrq()) != 0)
11723903Sjaap clrmn(findmn(j));
11823903Sjaap lgf--;
11923881Sjaap }
12023881Sjaap
12123881Sjaap
caseas()12223881Sjaap caseas()
12323881Sjaap {
12423881Sjaap app++;
12523881Sjaap caseds();
12623881Sjaap }
12723881Sjaap
12823881Sjaap
caseds()12923881Sjaap caseds()
13023881Sjaap {
13123881Sjaap ds++;
13223881Sjaap casede();
13323881Sjaap }
13423881Sjaap
13523881Sjaap
caseam()13623881Sjaap caseam()
13723881Sjaap {
13823881Sjaap app++;
13923881Sjaap casede();
14023881Sjaap }
14123881Sjaap
14223881Sjaap
casede()14323881Sjaap casede()
14423881Sjaap {
14523881Sjaap register i, req;
14623881Sjaap register filep savoff;
14723881Sjaap extern filep finds();
14823881Sjaap
14923881Sjaap if (dip != d)
15023881Sjaap wbfl();
15123881Sjaap req = '.';
15223881Sjaap lgf++;
15323881Sjaap skip();
15423881Sjaap if ((i = getrq()) == 0)
15523881Sjaap goto de1;
15623881Sjaap if ((offset = finds(i)) == 0)
15723881Sjaap goto de1;
15823881Sjaap if (ds)
15923881Sjaap copys();
16023881Sjaap else
16123881Sjaap req = copyb();
16223881Sjaap wbfl();
16323881Sjaap clrmn(oldmn);
16423903Sjaap if (newmn) {
16523903Sjaap if (contab[newmn].rq)
16623903Sjaap munhash(&contab[newmn]);
16723903Sjaap contab[newmn].rq = i;
16823903Sjaap maddhash(&contab[newmn]);
16923903Sjaap }
17023881Sjaap if (apptr) {
17123881Sjaap savoff = offset;
17223881Sjaap offset = apptr;
17323881Sjaap wbt((tchar) IMP);
17423881Sjaap offset = savoff;
17523881Sjaap }
17623881Sjaap offset = dip->op;
17723881Sjaap if (req != '.')
17823881Sjaap control(req, 1);
17923881Sjaap de1:
18023881Sjaap ds = app = 0;
18123881Sjaap return;
18223881Sjaap }
18323881Sjaap
18423881Sjaap
findmn(i)18523881Sjaap findmn(i)
18623881Sjaap register int i;
18723881Sjaap {
18823881Sjaap register struct contab *p;
18923881Sjaap
19023903Sjaap for (p = mhash[MHASH(i)]; p; p = p->link)
19123903Sjaap if (i == p->rq)
19223903Sjaap return(p - contab);
19323903Sjaap return(-1);
19423881Sjaap }
19523881Sjaap
19623881Sjaap
clrmn(i)19723881Sjaap clrmn(i)
19823881Sjaap register int i;
19923881Sjaap {
20023881Sjaap if (i >= 0) {
20123903Sjaap if (contab[i].mx)
20223903Sjaap ffree((filep)contab[i].mx);
20323903Sjaap munhash(&contab[i]);
20423881Sjaap contab[i].rq = 0;
20523903Sjaap contab[i].mx = 0;
20623903Sjaap contab[i].f = 0;
20723881Sjaap }
20823881Sjaap }
20923881Sjaap
21023881Sjaap
finds(mn)21123881Sjaap filep finds(mn)
21223881Sjaap register int mn;
21323881Sjaap {
21423881Sjaap register i;
21523881Sjaap register filep savip;
21623881Sjaap extern filep alloc();
21723881Sjaap extern filep incoff();
21823881Sjaap
21923881Sjaap oldmn = findmn(mn);
22023881Sjaap newmn = 0;
22123881Sjaap apptr = (filep)0;
22223903Sjaap if (app && oldmn >= 0 && contab[oldmn].mx) {
22323881Sjaap savip = ip;
22423903Sjaap ip = (filep)contab[oldmn].mx;
22523881Sjaap oldmn = -1;
22623881Sjaap while ((i = rbf()) != 0)
22723881Sjaap ;
22823881Sjaap apptr = ip;
22923881Sjaap if (!diflg)
23023881Sjaap ip = incoff(ip);
23123881Sjaap nextb = ip;
23223881Sjaap ip = savip;
23323881Sjaap } else {
23423881Sjaap for (i = 0; i < NM; i++) {
23523881Sjaap if (contab[i].rq == 0)
23623881Sjaap break;
23723881Sjaap }
23823881Sjaap if (i == NM || (nextb = alloc()) == 0) {
23923881Sjaap app = 0;
24023881Sjaap if (macerr++ > 1)
24123881Sjaap done2(02);
24223903Sjaap errprint("Too many (%d) string/macro names", NM);
24323881Sjaap edone(04);
24423881Sjaap return(offset = 0);
24523881Sjaap }
24623903Sjaap contab[i].mx = (unsigned) nextb;
24723881Sjaap if (!diflg) {
24823881Sjaap newmn = i;
24923881Sjaap if (oldmn == -1)
25023881Sjaap contab[i].rq = -1;
25123881Sjaap } else {
25223903Sjaap contab[i].rq = mn;
25323903Sjaap maddhash(&contab[i]);
25423881Sjaap }
25523881Sjaap }
25623881Sjaap app = 0;
25723881Sjaap return(offset = nextb);
25823881Sjaap }
25923881Sjaap
26023881Sjaap
skip()26123881Sjaap skip()
26223881Sjaap {
26323903Sjaap register tchar i;
26423881Sjaap
26523881Sjaap while (cbits(i = getch()) == ' ')
26623881Sjaap ;
26723881Sjaap ch = i;
26823881Sjaap return(nlflg);
26923881Sjaap }
27023881Sjaap
27123881Sjaap
copyb()27223881Sjaap copyb()
27323881Sjaap {
27423903Sjaap register i, j, state;
27523903Sjaap register tchar ii;
27623903Sjaap int req, k;
27723881Sjaap filep savoff;
27823881Sjaap
27923881Sjaap if (skip() || !(j = getrq()))
28023881Sjaap j = '.';
28123881Sjaap req = j;
28223881Sjaap k = j >> BYTE;
28323903Sjaap j &= BYTEMASK;
28423881Sjaap copyf++;
28523881Sjaap flushi();
28623881Sjaap nlflg = 0;
28723881Sjaap state = 1;
28823881Sjaap while (1) {
28923881Sjaap i = cbits(ii = getch());
29023881Sjaap if (state == 3) {
29123881Sjaap if (i == k)
29223881Sjaap break;
29323881Sjaap if (!k) {
29423881Sjaap ch = ii;
29523881Sjaap i = getach();
29623881Sjaap ch = ii;
29723881Sjaap if (!i)
29823881Sjaap break;
29923881Sjaap }
30023881Sjaap state = 0;
30123881Sjaap goto c0;
30223881Sjaap }
30323881Sjaap if (i == '\n') {
30423881Sjaap state = 1;
30523881Sjaap nlflg = 0;
30623881Sjaap goto c0;
30723881Sjaap }
30823881Sjaap if (state == 1 && i == '.') {
30923881Sjaap state++;
31023881Sjaap savoff = offset;
31123881Sjaap goto c0;
31223881Sjaap }
31323881Sjaap if ((state == 2) && (i == j)) {
31423881Sjaap state++;
31523881Sjaap goto c0;
31623881Sjaap }
31723881Sjaap state = 0;
31823881Sjaap c0:
31923881Sjaap if (offset)
32023881Sjaap wbf(ii);
32123881Sjaap }
32223881Sjaap if (offset) {
32323881Sjaap wbfl();
32423881Sjaap offset = savoff;
32523881Sjaap wbt((tchar)0);
32623881Sjaap }
32723881Sjaap copyf--;
32823881Sjaap return(req);
32923881Sjaap }
33023881Sjaap
33123881Sjaap
copys()33223881Sjaap copys()
33323881Sjaap {
33423903Sjaap register tchar i;
33523881Sjaap
33623881Sjaap copyf++;
33723881Sjaap if (skip())
33823881Sjaap goto c0;
33923881Sjaap if (cbits(i = getch()) != '"')
34023881Sjaap wbf(i);
34123881Sjaap while (cbits(i = getch()) != '\n')
34223881Sjaap wbf(i);
34323881Sjaap c0:
34423881Sjaap wbt((tchar)0);
34523881Sjaap copyf--;
34623881Sjaap }
34723881Sjaap
34823881Sjaap
alloc()34923881Sjaap filep alloc()
35023881Sjaap {
35123881Sjaap register i;
35223903Sjaap register filep j;
35323881Sjaap
35423881Sjaap for (i = 0; i < NBLIST; i++) {
35523881Sjaap if (blist[i] == 0)
35623881Sjaap break;
35723881Sjaap }
35823881Sjaap if (i == NBLIST) {
35923881Sjaap j = 0;
36023881Sjaap } else {
36123881Sjaap blist[i] = -1;
36223903Sjaap if ((j = ((filep)i * BLK + NEV*(int)sizeof(env))) < NEV*(int)sizeof(env))
36323881Sjaap j = 0;
36423881Sjaap }
36523881Sjaap return(nextb = j);
36623881Sjaap }
36723881Sjaap
36823881Sjaap
ffree(i)36923881Sjaap ffree(i)
37023881Sjaap filep i;
37123881Sjaap {
37223881Sjaap register j;
37323881Sjaap
37423903Sjaap while (blist[j = blisti(i)] != (unsigned) ~0) {
37523903Sjaap i = (filep) blist[j];
37623881Sjaap blist[j] = 0;
37723881Sjaap }
37823881Sjaap blist[j] = 0;
37923881Sjaap }
38023881Sjaap
wbt(i)38123881Sjaap wbt(i)
38223881Sjaap tchar i;
38323881Sjaap {
38423881Sjaap wbf(i);
38523881Sjaap wbfl();
38623881Sjaap }
38723881Sjaap
38823881Sjaap
wbf(i)38923881Sjaap wbf(i)
39023903Sjaap register tchar i;
39123881Sjaap {
39223881Sjaap register j;
39323881Sjaap
39423881Sjaap if (!offset)
39523881Sjaap return;
39623881Sjaap if (!woff) {
39723881Sjaap woff = offset;
39823881Sjaap wbuf = &corebuf[woff]; /* INCORE only */
39923881Sjaap wbfi = 0;
40023881Sjaap }
40123881Sjaap wbuf[wbfi++] = i;
40223881Sjaap if (!((++offset) & (BLK - 1))) {
40323881Sjaap wbfl();
40423903Sjaap j = blisti(--offset);
40523903Sjaap if (j < 0 || j >= NBLIST) {
40623903Sjaap errprint("Out of temp file space");
40723903Sjaap done2(01);
40823903Sjaap }
40923903Sjaap if (blist[j] == (unsigned) ~0) {
41023881Sjaap if (alloc() == 0) {
41123903Sjaap errprint("Out of temp file space");
41223881Sjaap done2(01);
41323881Sjaap }
41423881Sjaap blist[j] = (unsigned)(nextb);
41523881Sjaap }
41623881Sjaap offset = ((filep)blist[j]);
41723881Sjaap }
41823881Sjaap if (wbfi >= BLK)
41923881Sjaap wbfl();
42023881Sjaap }
42123881Sjaap
42223881Sjaap
wbfl()42323881Sjaap wbfl()
42423881Sjaap {
42523881Sjaap if (woff == 0)
42623881Sjaap return;
42723881Sjaap if ((woff & (~(BLK - 1))) == (roff & (~(BLK - 1))))
42823881Sjaap roff = -1;
42923881Sjaap woff = 0;
43023881Sjaap }
43123881Sjaap
43223881Sjaap
rbf()43323881Sjaap tchar rbf()
43423881Sjaap {
43523903Sjaap register tchar i;
43623881Sjaap register filep j, p;
43723881Sjaap extern filep incoff();
43823881Sjaap
43923903Sjaap if (ip == NBLIST*BLK) { /* for rdtty */
44023903Sjaap if (j = rdtty())
44123903Sjaap return(j);
44223903Sjaap else
44323903Sjaap return(popi());
44423903Sjaap }
44523881Sjaap /* this is an inline expansion of rbf0: dirty! */
44623903Sjaap i = corebuf[ip];
44723881Sjaap /* end of rbf0 */
44823881Sjaap if (i == 0) {
44923881Sjaap if (!app)
45023881Sjaap i = popi();
45123903Sjaap return(i);
45223903Sjaap }
45323903Sjaap /* this is an inline expansion of incoff: also dirty */
45423903Sjaap p = ++ip;
45523903Sjaap if ((p & (BLK - 1)) == 0) {
45623903Sjaap if ((ip = blist[blisti(p-1)]) == (unsigned) ~0) {
45723903Sjaap ip = 0;
45823903Sjaap errprint("Bad storage allocation");
45923903Sjaap done2(-5);
46023881Sjaap }
46123903Sjaap /* this was meant to protect against people removing
46223903Sjaap /* the macro they were standing on, but it's too
46323903Sjaap /* sensitive to block boundaries.
46423903Sjaap /* if (ip == 0) {
46523903Sjaap /* errprint("Block removed while in use");
46623903Sjaap /* done2(-6);
46723903Sjaap /* }
46823903Sjaap */
46923881Sjaap }
47023881Sjaap return(i);
47123881Sjaap }
47223881Sjaap
47323881Sjaap
rbf0(p)47423881Sjaap tchar rbf0(p)
47523881Sjaap register filep p;
47623881Sjaap {
47723903Sjaap return(corebuf[p]);
47823881Sjaap }
47923881Sjaap
48023881Sjaap
incoff(p)48123881Sjaap filep incoff(p)
48223881Sjaap register filep p;
48323881Sjaap {
48423903Sjaap p++;
48523903Sjaap if ((p & (BLK - 1)) == 0) {
48623903Sjaap if ((p = blist[blisti(p-1)]) == (unsigned) ~0) {
48723903Sjaap errprint("Bad storage allocation");
48823881Sjaap done2(-5);
48923881Sjaap }
49023881Sjaap }
49123903Sjaap return(p);
49223881Sjaap }
49323881Sjaap
49423881Sjaap
popi()49523881Sjaap tchar popi()
49623881Sjaap {
49723881Sjaap register struct s *p;
49823881Sjaap
49923881Sjaap if (frame == stk)
50023881Sjaap return(0);
50123881Sjaap if (strflg)
50223881Sjaap strflg--;
50323881Sjaap p = nxf = frame;
50423881Sjaap p->nargs = 0;
50523881Sjaap frame = p->pframe;
50623881Sjaap ip = p->pip;
50723881Sjaap pendt = p->ppendt;
50823903Sjaap lastpbp = p->lastpbp;
50923881Sjaap return(p->pch);
51023881Sjaap }
51123881Sjaap
51223881Sjaap /*
51323881Sjaap * test that the end of the allocation is above a certain location
51423881Sjaap * in memory
51523881Sjaap */
516*45477Skarels #ifdef notdef
51723881Sjaap #define SPACETEST(base, size) while ((enda - (size)) <= (char *)(base)){setbrk(DELTA);}
518*45477Skarels #else
519*45477Skarels #define SPACETEST(base, size)
520*45477Skarels #endif
52123881Sjaap
pushi(newip,mname)52223903Sjaap pushi(newip, mname)
52323881Sjaap filep newip;
52423903Sjaap int mname;
52523881Sjaap {
52623881Sjaap register struct s *p;
52723881Sjaap
52823881Sjaap SPACETEST(nxf, sizeof(struct s));
52923881Sjaap p = nxf;
53023881Sjaap p->pframe = frame;
53123881Sjaap p->pip = ip;
53223881Sjaap p->ppendt = pendt;
53323881Sjaap p->pch = ch;
53423903Sjaap p->lastpbp = lastpbp;
53523903Sjaap p->mname = mname;
53623903Sjaap lastpbp = pbp;
53723903Sjaap pendt = ch = 0;
53823881Sjaap frame = nxf;
53923881Sjaap if (nxf->nargs == 0)
54023881Sjaap nxf += 1;
54123881Sjaap else
54223881Sjaap nxf = (struct s *)argtop;
54323881Sjaap return(ip = newip);
54423881Sjaap }
54523881Sjaap
getsn()54623881Sjaap getsn()
54723881Sjaap {
54823881Sjaap register i;
54923881Sjaap
55023881Sjaap if ((i = getach()) == 0)
55123881Sjaap return(0);
55223881Sjaap if (i == '(')
55323881Sjaap return(getrq());
55423881Sjaap else
55523881Sjaap return(i);
55623881Sjaap }
55723881Sjaap
55823881Sjaap
setstr()55923881Sjaap setstr()
56023881Sjaap {
56123903Sjaap register i, j;
56223881Sjaap
56323881Sjaap lgf++;
56423903Sjaap if ((i = getsn()) == 0 || (j = findmn(i)) == -1 || !contab[j].mx) {
56523881Sjaap lgf--;
56623881Sjaap return(0);
56723881Sjaap } else {
56823881Sjaap SPACETEST(nxf, sizeof(struct s));
56923881Sjaap nxf->nargs = 0;
57023881Sjaap strflg++;
57123881Sjaap lgf--;
57223903Sjaap return pushi((filep)contab[j].mx, i);
57323881Sjaap }
57423881Sjaap }
57523881Sjaap
57623881Sjaap
57723881Sjaap
collect()57823881Sjaap collect()
57923881Sjaap {
58023881Sjaap register j;
58123903Sjaap register tchar i;
58223881Sjaap register tchar *strp;
58323881Sjaap tchar * lim;
58423881Sjaap tchar * *argpp, **argppend;
58523881Sjaap int quote;
58623881Sjaap struct s *savnxf;
58723881Sjaap
58823881Sjaap copyf++;
58923881Sjaap nxf->nargs = 0;
59023881Sjaap savnxf = nxf;
59123881Sjaap if (skip())
59223881Sjaap goto rtn;
59323881Sjaap
59423881Sjaap {
59523881Sjaap char *memp;
59623881Sjaap memp = (char *)savnxf;
59723881Sjaap /*
59823881Sjaap * 1 s structure for the macro descriptor
59923881Sjaap * APERMAC tchar *'s for pointers into the strings
60023881Sjaap * space for the tchar's themselves
60123881Sjaap */
60223881Sjaap memp += sizeof(struct s);
60323881Sjaap /*
60423881Sjaap * CPERMAC (the total # of characters for ALL arguments)
60523881Sjaap * to a macros, has been carefully chosen
60623881Sjaap * so that the distance between stack frames is < DELTA
60723881Sjaap */
60823881Sjaap #define CPERMAC 200
60923881Sjaap #define APERMAC 9
61023881Sjaap memp += APERMAC * sizeof(tchar *);
61123881Sjaap memp += CPERMAC * sizeof(tchar);
61223881Sjaap nxf = (struct s*)memp;
61323881Sjaap }
61423881Sjaap lim = (tchar *)nxf;
61523881Sjaap argpp = (tchar **)(savnxf + 1);
61623881Sjaap argppend = &argpp[APERMAC];
61723881Sjaap SPACETEST(argppend, sizeof(tchar *));
61823881Sjaap strp = (tchar *)argppend;
61923881Sjaap /*
62023881Sjaap * Zero out all the string pointers before filling them in.
62123881Sjaap */
62223881Sjaap for (j = 0; j < APERMAC; j++){
62323881Sjaap argpp[j] = (tchar *)0;
62423881Sjaap }
62523881Sjaap #if 0
62623903Sjaap errprint("savnxf=0x%x,nxf=0x%x,argpp=0x%x,strp=argppend=0x%x,lim=0x%x,enda=0x%x",
62723881Sjaap savnxf, nxf, argpp, strp, lim, enda);
62823881Sjaap #endif 0
62923881Sjaap strflg = 0;
63023881Sjaap while ((argpp != argppend) && (!skip())) {
63123881Sjaap *argpp++ = strp;
63223881Sjaap quote = 0;
63323881Sjaap if (cbits(i = getch()) == '"')
63423881Sjaap quote++;
63523881Sjaap else
63623881Sjaap ch = i;
63723881Sjaap while (1) {
63823881Sjaap i = getch();
63923903Sjaap if (nlflg || (!quote && cbits(i) == ' '))
64023881Sjaap break;
64123881Sjaap if ( quote
64223881Sjaap && (cbits(i) == '"')
64323881Sjaap && (cbits(i = getch()) != '"')) {
64423881Sjaap ch = i;
64523881Sjaap break;
64623881Sjaap }
64723881Sjaap *strp++ = i;
64823903Sjaap if (strflg && strp >= lim) {
64923903Sjaap errprint("Macro argument too long");
65023881Sjaap copyf--;
65123881Sjaap edone(004);
65223881Sjaap }
65323881Sjaap SPACETEST(strp, 3 * sizeof(tchar));
65423881Sjaap }
65523881Sjaap *strp++ = 0;
65623881Sjaap }
65723881Sjaap nxf = savnxf;
65823881Sjaap nxf->nargs = argpp - (tchar **)(savnxf + 1);
65923881Sjaap argtop = strp;
66023881Sjaap rtn:
66123881Sjaap copyf--;
66223881Sjaap }
66323881Sjaap
66423881Sjaap
seta()66523881Sjaap seta()
66623881Sjaap {
66723881Sjaap register i;
66823881Sjaap
66923881Sjaap i = cbits(getch()) - '0';
67023903Sjaap if (i > 0 && i <= APERMAC && i <= frame->nargs)
67123903Sjaap pushback(*(((tchar **)(frame + 1)) + i - 1));
67223881Sjaap }
67323881Sjaap
67423881Sjaap
caseda()67523881Sjaap caseda()
67623881Sjaap {
67723881Sjaap app++;
67823881Sjaap casedi();
67923881Sjaap }
68023881Sjaap
68123881Sjaap
casedi()68223881Sjaap casedi()
68323881Sjaap {
68423881Sjaap register i, j;
68523881Sjaap register *k;
68623881Sjaap
68723881Sjaap lgf++;
68823903Sjaap if (skip() || (i = getrq()) == 0) {
68923881Sjaap if (dip != d)
69023881Sjaap wbt((tchar)0);
69123881Sjaap if (dilev > 0) {
69223903Sjaap numtab[DN].val = dip->dnl;
69323903Sjaap numtab[DL].val = dip->maxl;
69423881Sjaap dip = &d[--dilev];
69523881Sjaap offset = dip->op;
69623881Sjaap }
69723881Sjaap goto rtn;
69823881Sjaap }
69923881Sjaap if (++dilev == NDI) {
70023881Sjaap --dilev;
70123903Sjaap errprint("Diversions nested too deep");
70223881Sjaap edone(02);
70323881Sjaap }
70423881Sjaap if (dip != d)
70523881Sjaap wbt((tchar)0);
70623881Sjaap diflg++;
70723881Sjaap dip = &d[dilev];
70823881Sjaap dip->op = finds(i);
70923881Sjaap dip->curd = i;
71023881Sjaap clrmn(oldmn);
71123881Sjaap k = (int *) & dip->dnl;
71223881Sjaap for (j = 0; j < 10; j++)
71323881Sjaap k[j] = 0; /*not op and curd*/
71423881Sjaap rtn:
71523881Sjaap app = 0;
71623881Sjaap diflg = 0;
71723881Sjaap }
71823881Sjaap
71923881Sjaap
casedt()72023881Sjaap casedt()
72123881Sjaap {
72223881Sjaap lgf++;
72323881Sjaap dip->dimac = dip->ditrap = dip->ditf = 0;
72423881Sjaap skip();
72523881Sjaap dip->ditrap = vnumb((int *)0);
72623881Sjaap if (nonumb)
72723881Sjaap return;
72823881Sjaap skip();
72923881Sjaap dip->dimac = getrq();
73023881Sjaap }
73123881Sjaap
73223881Sjaap
casetl()73323881Sjaap casetl()
73423881Sjaap {
73523881Sjaap register j;
73623903Sjaap int w[3];
73723903Sjaap tchar buf[LNSIZE];
73823903Sjaap register tchar *tp;
73923881Sjaap tchar i, delim;
74023881Sjaap
74124287Sjaap /*
74224287Sjaap * bug fix
74324287Sjaap *
74424287Sjaap * if .tl is the first thing in the file, the p1
74524287Sjaap * doesn't come out, also the pagenumber will be 0
74624287Sjaap *
74724287Sjaap * tends too confuse the device filter (and the user as well)
74824287Sjaap */
74924287Sjaap if( dip == d && numtab[NL].val == -1)
75024287Sjaap newline(1);
75124287Sjaap
75224287Sjaap /* end fix */
75323881Sjaap dip->nls = 0;
75423881Sjaap skip();
75523881Sjaap if (ismot(delim = getch())) {
75623881Sjaap ch = delim;
75723881Sjaap delim = '\'';
75823881Sjaap } else
75923881Sjaap delim = cbits(delim);
76023903Sjaap tp = buf;
76123903Sjaap numtab[HP].val = 0;
76223903Sjaap w[0] = w[1] = w[2] = 0;
76323903Sjaap j = 0;
76423903Sjaap while (cbits(i = getch()) != '\n') {
76523903Sjaap if (cbits(i) == cbits(delim)) {
76623903Sjaap if (j < 3)
76723903Sjaap w[j] = numtab[HP].val;
76823903Sjaap numtab[HP].val = 0;
76923903Sjaap j++;
77023903Sjaap *tp++ = 0;
77123903Sjaap } else {
77223903Sjaap if (cbits(i) == pagech) {
77323903Sjaap setn1(numtab[PN].val, numtab[findr('%')].fmt,
77423903Sjaap i&SFMASK);
77523903Sjaap continue;
77623903Sjaap }
77723903Sjaap numtab[HP].val += width(i);
77823903Sjaap if (tp < &buf[LNSIZE-10])
77923903Sjaap *tp++ = i;
78023881Sjaap }
78123903Sjaap }
78223903Sjaap if (j<3)
78323903Sjaap w[j] = numtab[HP].val;
78423903Sjaap *tp++ = 0;
78523903Sjaap *tp++ = 0;
78623903Sjaap *tp++ = 0;
78723903Sjaap tp = buf;
78823881Sjaap #ifdef NROFF
78923903Sjaap horiz(po);
79023881Sjaap #endif
79123903Sjaap while (i = *tp++)
79223903Sjaap pchar(i);
79323903Sjaap if (w[1] || w[2])
79423903Sjaap horiz(j = quant((lt - w[1]) / 2 - w[0], HOR));
79523903Sjaap while (i = *tp++)
79623903Sjaap pchar(i);
79723903Sjaap if (w[2]) {
79823903Sjaap horiz(lt - w[0] - w[1] - w[2] - j);
79923903Sjaap while (i = *tp++)
80023903Sjaap pchar(i);
80123881Sjaap }
80223881Sjaap newline(0);
80323881Sjaap if (dip != d) {
80423881Sjaap if (dip->dnl > dip->hnl)
80523881Sjaap dip->hnl = dip->dnl;
80623881Sjaap } else {
80723903Sjaap if (numtab[NL].val > dip->hnl)
80823903Sjaap dip->hnl = numtab[NL].val;
80923881Sjaap }
81023881Sjaap }
81123881Sjaap
81223881Sjaap
casepc()81323881Sjaap casepc()
81423881Sjaap {
81523881Sjaap pagech = chget(IMP);
81623881Sjaap }
81723881Sjaap
81823881Sjaap
casepm()81923881Sjaap casepm()
82023881Sjaap {
82123881Sjaap register i, k;
82223881Sjaap register char *p;
82323881Sjaap int xx, cnt, tcnt, kk, tot;
82423881Sjaap filep j;
82523881Sjaap char pmline[10];
82623881Sjaap
82723881Sjaap kk = cnt = tcnt = 0;
82823881Sjaap tot = !skip();
82923881Sjaap for (i = 0; i < NM; i++) {
83030220Sjaap if ((xx = contab[i].rq) == 0 || contab[i].mx == 0)
83123881Sjaap continue;
83223903Sjaap tcnt++;
83323881Sjaap p = pmline;
83423903Sjaap j = (filep) contab[i].mx;
83523881Sjaap k = 1;
83623903Sjaap while ((j = blist[blisti(j)]) != (unsigned) ~0) {
83723881Sjaap k++;
83823881Sjaap }
83923881Sjaap cnt++;
84023881Sjaap kk += k;
84123881Sjaap if (!tot) {
84223881Sjaap *p++ = xx & 0177;
84323881Sjaap if (!(*p++ = (xx >> BYTE) & 0177))
84423881Sjaap *(p - 1) = ' ';
84523881Sjaap *p++ = 0;
84623903Sjaap fdprintf(stderr, "%s %d\n", pmline, k);
84723881Sjaap }
84823881Sjaap }
84923903Sjaap fdprintf(stderr, "pm: total %d, macros %d, space %d\n", tcnt, cnt, kk);
85023881Sjaap }
85123881Sjaap
stackdump()85223903Sjaap stackdump() /* dumps stack of macros in process */
85323903Sjaap {
85423903Sjaap struct s *p;
85523881Sjaap
85623903Sjaap if (p != stk) {
85723903Sjaap for (p = frame; p != stk; p = p->pframe)
85823903Sjaap fdprintf(stderr, "%c%c ", p->mname&0177, (p->mname>>BYTE)&0177);
85923903Sjaap fdprintf(stderr, "\n");
86023903Sjaap }
86123881Sjaap }
862