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