xref: /titanic_50/usr/src/cmd/troff/n3.c (revision e5190c108bde19ca4d7c03b1d1eab7b00bd3a1ed)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
287c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
327c478bd9Sstevel@tonic-gate  * The Regents of the University of California
337c478bd9Sstevel@tonic-gate  * All Rights Reserved
347c478bd9Sstevel@tonic-gate  *
357c478bd9Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
367c478bd9Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
377c478bd9Sstevel@tonic-gate  * contributors.
387c478bd9Sstevel@tonic-gate  */
397c478bd9Sstevel@tonic-gate 
40*e5190c10Smuffin #pragma ident	"%Z%%M%	%I%	%E% SMI"
41*e5190c10Smuffin 
427c478bd9Sstevel@tonic-gate /*
437c478bd9Sstevel@tonic-gate  * troff3.c
447c478bd9Sstevel@tonic-gate  *
457c478bd9Sstevel@tonic-gate  * macro and string routines, storage allocation
467c478bd9Sstevel@tonic-gate  */
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate #include "tdef.h"
507c478bd9Sstevel@tonic-gate #ifdef NROFF
517c478bd9Sstevel@tonic-gate #include "tw.h"
527c478bd9Sstevel@tonic-gate #endif
537c478bd9Sstevel@tonic-gate #include "ext.h"
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate #define	MHASH(x)	((x>>6)^x)&0177
567c478bd9Sstevel@tonic-gate struct	contab *mhash[128];	/* 128 == the 0177 on line above */
577c478bd9Sstevel@tonic-gate #define	blisti(i)	(((i)-ENV_BLK*BLK) / BLK)
587c478bd9Sstevel@tonic-gate filep	blist[NBLIST];
597c478bd9Sstevel@tonic-gate tchar	*argtop;
607c478bd9Sstevel@tonic-gate int	pagech = '%';
617c478bd9Sstevel@tonic-gate int	strflg;
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate #ifdef	INCORE
647c478bd9Sstevel@tonic-gate 	tchar *wbuf;
657c478bd9Sstevel@tonic-gate 	tchar corebuf[(ENV_BLK + NBLIST + 1) * BLK];
667c478bd9Sstevel@tonic-gate #else
677c478bd9Sstevel@tonic-gate 	tchar wbuf[BLK];
687c478bd9Sstevel@tonic-gate 	tchar rbuf[BLK];
697c478bd9Sstevel@tonic-gate #endif
707c478bd9Sstevel@tonic-gate 
71*e5190c10Smuffin int
caseig()727c478bd9Sstevel@tonic-gate caseig()
737c478bd9Sstevel@tonic-gate {
74*e5190c10Smuffin 	int	i;
75*e5190c10Smuffin 	filep oldoff;
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate 	oldoff = offset;
787c478bd9Sstevel@tonic-gate 	offset = 0;
797c478bd9Sstevel@tonic-gate 	i = copyb();
807c478bd9Sstevel@tonic-gate 	offset = oldoff;
817c478bd9Sstevel@tonic-gate 	if (i != '.')
827c478bd9Sstevel@tonic-gate 		control(i, 1);
83*e5190c10Smuffin 
84*e5190c10Smuffin 	return (0);
857c478bd9Sstevel@tonic-gate }
867c478bd9Sstevel@tonic-gate 
87*e5190c10Smuffin int
casern()887c478bd9Sstevel@tonic-gate casern()
897c478bd9Sstevel@tonic-gate {
90*e5190c10Smuffin 	int	i, j;
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	lgf++;
937c478bd9Sstevel@tonic-gate 	skip();
947c478bd9Sstevel@tonic-gate 	if ((i = getrq()) == 0 || (oldmn = findmn(i)) < 0)
95*e5190c10Smuffin 		return (0);
967c478bd9Sstevel@tonic-gate 	skip();
977c478bd9Sstevel@tonic-gate 	clrmn(findmn(j = getrq()));
987c478bd9Sstevel@tonic-gate 	if (j) {
997c478bd9Sstevel@tonic-gate 		munhash(&contab[oldmn]);
1007c478bd9Sstevel@tonic-gate 		contab[oldmn].rq = j;
1017c478bd9Sstevel@tonic-gate 		maddhash(&contab[oldmn]);
1027c478bd9Sstevel@tonic-gate 	}
103*e5190c10Smuffin 
104*e5190c10Smuffin 	return (0);
1057c478bd9Sstevel@tonic-gate }
1067c478bd9Sstevel@tonic-gate 
107*e5190c10Smuffin int
maddhash(rp)1087c478bd9Sstevel@tonic-gate maddhash(rp)
109*e5190c10Smuffin struct contab *rp;
1107c478bd9Sstevel@tonic-gate {
111*e5190c10Smuffin 	struct contab **hp;
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate 	if (rp->rq == 0)
114*e5190c10Smuffin 		return (0);
1157c478bd9Sstevel@tonic-gate 	hp = &mhash[MHASH(rp->rq)];
1167c478bd9Sstevel@tonic-gate 	rp->link = *hp;
1177c478bd9Sstevel@tonic-gate 	*hp = rp;
118*e5190c10Smuffin 
119*e5190c10Smuffin 	return (0);
1207c478bd9Sstevel@tonic-gate }
1217c478bd9Sstevel@tonic-gate 
122*e5190c10Smuffin int
munhash(mp)1237c478bd9Sstevel@tonic-gate munhash(mp)
124*e5190c10Smuffin struct contab *mp;
1257c478bd9Sstevel@tonic-gate {
126*e5190c10Smuffin 	struct contab *p;
127*e5190c10Smuffin 	struct contab **lp;
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 	if (mp->rq == 0)
130*e5190c10Smuffin 		return (0);
1317c478bd9Sstevel@tonic-gate 	lp = &mhash[MHASH(mp->rq)];
1327c478bd9Sstevel@tonic-gate 	p = *lp;
1337c478bd9Sstevel@tonic-gate 	while (p) {
1347c478bd9Sstevel@tonic-gate 		if (p == mp) {
1357c478bd9Sstevel@tonic-gate 			*lp = p->link;
1367c478bd9Sstevel@tonic-gate 			p->link = 0;
137*e5190c10Smuffin 			return (0);
1387c478bd9Sstevel@tonic-gate 		}
1397c478bd9Sstevel@tonic-gate 		lp = &p->link;
1407c478bd9Sstevel@tonic-gate 		p = p->link;
1417c478bd9Sstevel@tonic-gate 	}
142*e5190c10Smuffin 
143*e5190c10Smuffin 	return (0);
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate 
146*e5190c10Smuffin int
mrehash()1477c478bd9Sstevel@tonic-gate mrehash()
1487c478bd9Sstevel@tonic-gate {
149*e5190c10Smuffin 	struct contab *p;
150*e5190c10Smuffin 	int	i;
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate 	for (i=0; i<128; i++)
1537c478bd9Sstevel@tonic-gate 		mhash[i] = 0;
1547c478bd9Sstevel@tonic-gate 	for (p=contab; p < &contab[NM]; p++)
1557c478bd9Sstevel@tonic-gate 		p->link = 0;
1567c478bd9Sstevel@tonic-gate 	for (p=contab; p < &contab[NM]; p++) {
1577c478bd9Sstevel@tonic-gate 		if (p->rq == 0)
1587c478bd9Sstevel@tonic-gate 			continue;
1597c478bd9Sstevel@tonic-gate 		i = MHASH(p->rq);
1607c478bd9Sstevel@tonic-gate 		p->link = mhash[i];
1617c478bd9Sstevel@tonic-gate 		mhash[i] = p;
1627c478bd9Sstevel@tonic-gate 	}
163*e5190c10Smuffin 
164*e5190c10Smuffin 	return (0);
1657c478bd9Sstevel@tonic-gate }
1667c478bd9Sstevel@tonic-gate 
167*e5190c10Smuffin int
caserm()1687c478bd9Sstevel@tonic-gate caserm()
1697c478bd9Sstevel@tonic-gate {
1707c478bd9Sstevel@tonic-gate 	int j;
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate 	lgf++;
1737c478bd9Sstevel@tonic-gate 	while (!skip() && (j = getrq()) != 0)
1747c478bd9Sstevel@tonic-gate 		clrmn(findmn(j));
1757c478bd9Sstevel@tonic-gate 	lgf--;
176*e5190c10Smuffin 
177*e5190c10Smuffin 	return (0);
1787c478bd9Sstevel@tonic-gate }
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate 
181*e5190c10Smuffin int
caseas()1827c478bd9Sstevel@tonic-gate caseas()
1837c478bd9Sstevel@tonic-gate {
1847c478bd9Sstevel@tonic-gate 	app++;
1857c478bd9Sstevel@tonic-gate 	caseds();
186*e5190c10Smuffin 
187*e5190c10Smuffin 	return (0);
1887c478bd9Sstevel@tonic-gate }
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate 
191*e5190c10Smuffin int
caseds()1927c478bd9Sstevel@tonic-gate caseds()
1937c478bd9Sstevel@tonic-gate {
1947c478bd9Sstevel@tonic-gate 	ds++;
1957c478bd9Sstevel@tonic-gate 	casede();
196*e5190c10Smuffin 
197*e5190c10Smuffin 	return (0);
1987c478bd9Sstevel@tonic-gate }
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate 
201*e5190c10Smuffin int
caseam()2027c478bd9Sstevel@tonic-gate caseam()
2037c478bd9Sstevel@tonic-gate {
2047c478bd9Sstevel@tonic-gate 	app++;
2057c478bd9Sstevel@tonic-gate 	casede();
206*e5190c10Smuffin 
207*e5190c10Smuffin 	return (0);
2087c478bd9Sstevel@tonic-gate }
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate 
211*e5190c10Smuffin int
casede()2127c478bd9Sstevel@tonic-gate casede()
2137c478bd9Sstevel@tonic-gate {
214*e5190c10Smuffin 	int	i, req;
215*e5190c10Smuffin 	filep savoff;
2167c478bd9Sstevel@tonic-gate 	extern filep finds();
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 	if (dip != d)
2197c478bd9Sstevel@tonic-gate 		wbfl();
2207c478bd9Sstevel@tonic-gate 	req = '.';
2217c478bd9Sstevel@tonic-gate 	lgf++;
2227c478bd9Sstevel@tonic-gate 	skip();
2237c478bd9Sstevel@tonic-gate 	if ((i = getrq()) == 0)
2247c478bd9Sstevel@tonic-gate 		goto de1;
2257c478bd9Sstevel@tonic-gate 	if ((offset = finds(i)) == 0)
2267c478bd9Sstevel@tonic-gate 		goto de1;
2277c478bd9Sstevel@tonic-gate 	if (ds)
2287c478bd9Sstevel@tonic-gate 		copys();
2297c478bd9Sstevel@tonic-gate 	else
2307c478bd9Sstevel@tonic-gate 		req = copyb();
2317c478bd9Sstevel@tonic-gate 	wbfl();
2327c478bd9Sstevel@tonic-gate 	clrmn(oldmn);
2337c478bd9Sstevel@tonic-gate 	if (newmn) {
2347c478bd9Sstevel@tonic-gate 		if (contab[newmn].rq)
2357c478bd9Sstevel@tonic-gate 			munhash(&contab[newmn]);
2367c478bd9Sstevel@tonic-gate 		contab[newmn].rq = i;
2377c478bd9Sstevel@tonic-gate 		maddhash(&contab[newmn]);
2387c478bd9Sstevel@tonic-gate 	}
2397c478bd9Sstevel@tonic-gate 	if (apptr) {
2407c478bd9Sstevel@tonic-gate 		savoff = offset;
2417c478bd9Sstevel@tonic-gate 		offset = apptr;
2427c478bd9Sstevel@tonic-gate 		wbt((tchar) IMP);
2437c478bd9Sstevel@tonic-gate 		offset = savoff;
2447c478bd9Sstevel@tonic-gate 	}
2457c478bd9Sstevel@tonic-gate 	offset = dip->op;
2467c478bd9Sstevel@tonic-gate 	if (req != '.')
2477c478bd9Sstevel@tonic-gate 		control(req, 1);
2487c478bd9Sstevel@tonic-gate de1:
2497c478bd9Sstevel@tonic-gate 	ds = app = 0;
250*e5190c10Smuffin 	return (0);
2517c478bd9Sstevel@tonic-gate }
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate 
254*e5190c10Smuffin int
findmn(i)2557c478bd9Sstevel@tonic-gate findmn(i)
256*e5190c10Smuffin int	i;
2577c478bd9Sstevel@tonic-gate {
258*e5190c10Smuffin 	struct contab *p;
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate 	for (p = mhash[MHASH(i)]; p; p = p->link)
2617c478bd9Sstevel@tonic-gate 		if (i == p->rq)
2627c478bd9Sstevel@tonic-gate 			return(p - contab);
2637c478bd9Sstevel@tonic-gate 	return(-1);
2647c478bd9Sstevel@tonic-gate }
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate 
267*e5190c10Smuffin int
clrmn(i)2687c478bd9Sstevel@tonic-gate clrmn(i)
269*e5190c10Smuffin int	i;
2707c478bd9Sstevel@tonic-gate {
2717c478bd9Sstevel@tonic-gate 	if (i >= 0) {
2727c478bd9Sstevel@tonic-gate 		if (contab[i].mx)
2737c478bd9Sstevel@tonic-gate 			ffree((filep)contab[i].mx);
2747c478bd9Sstevel@tonic-gate 		munhash(&contab[i]);
2757c478bd9Sstevel@tonic-gate 		contab[i].rq = 0;
2767c478bd9Sstevel@tonic-gate 		contab[i].mx = 0;
2777c478bd9Sstevel@tonic-gate 		contab[i].f = 0;
2787c478bd9Sstevel@tonic-gate 	}
279*e5190c10Smuffin 
280*e5190c10Smuffin 	return (0);
2817c478bd9Sstevel@tonic-gate }
2827c478bd9Sstevel@tonic-gate 
2837c478bd9Sstevel@tonic-gate 
finds(mn)2847c478bd9Sstevel@tonic-gate filep finds(mn)
285*e5190c10Smuffin int	mn;
2867c478bd9Sstevel@tonic-gate {
287*e5190c10Smuffin 	int	i;
288*e5190c10Smuffin 	filep savip;
2897c478bd9Sstevel@tonic-gate 	extern filep alloc();
2907c478bd9Sstevel@tonic-gate 	extern filep incoff();
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate 	oldmn = findmn(mn);
2937c478bd9Sstevel@tonic-gate 	newmn = 0;
2947c478bd9Sstevel@tonic-gate 	apptr = (filep)0;
2957c478bd9Sstevel@tonic-gate 	if (app && oldmn >= 0 && contab[oldmn].mx) {
2967c478bd9Sstevel@tonic-gate 		savip = ip;
2977c478bd9Sstevel@tonic-gate 		ip = (filep)contab[oldmn].mx;
2987c478bd9Sstevel@tonic-gate 		oldmn = -1;
2997c478bd9Sstevel@tonic-gate 		while ((i = rbf()) != 0)
3007c478bd9Sstevel@tonic-gate 			;
3017c478bd9Sstevel@tonic-gate 		apptr = ip;
3027c478bd9Sstevel@tonic-gate 		if (!diflg)
3037c478bd9Sstevel@tonic-gate 			ip = incoff(ip);
3047c478bd9Sstevel@tonic-gate 		nextb = ip;
3057c478bd9Sstevel@tonic-gate 		ip = savip;
3067c478bd9Sstevel@tonic-gate 	} else {
3077c478bd9Sstevel@tonic-gate 		for (i = 0; i < NM; i++) {
3087c478bd9Sstevel@tonic-gate 			if (contab[i].rq == 0)
3097c478bd9Sstevel@tonic-gate 				break;
3107c478bd9Sstevel@tonic-gate 		}
3117c478bd9Sstevel@tonic-gate 		if (i == NM || (nextb = alloc()) == 0) {
3127c478bd9Sstevel@tonic-gate 			app = 0;
3137c478bd9Sstevel@tonic-gate 			if (macerr++ > 1)
3147c478bd9Sstevel@tonic-gate 				done2(02);
3157c478bd9Sstevel@tonic-gate 			errprint(gettext("Too many (%d) string/macro names"),
3167c478bd9Sstevel@tonic-gate 					 NM);
3177c478bd9Sstevel@tonic-gate 			edone(04);
3187c478bd9Sstevel@tonic-gate 			return(offset = 0);
3197c478bd9Sstevel@tonic-gate 		}
3207c478bd9Sstevel@tonic-gate 		contab[i].mx = (unsigned) nextb;
3217c478bd9Sstevel@tonic-gate 		if (!diflg) {
3227c478bd9Sstevel@tonic-gate 			newmn = i;
3237c478bd9Sstevel@tonic-gate 			if (oldmn == -1)
3247c478bd9Sstevel@tonic-gate 				contab[i].rq = -1;
3257c478bd9Sstevel@tonic-gate 		} else {
3267c478bd9Sstevel@tonic-gate 			contab[i].rq = mn;
3277c478bd9Sstevel@tonic-gate 			maddhash(&contab[i]);
3287c478bd9Sstevel@tonic-gate 		}
3297c478bd9Sstevel@tonic-gate 	}
3307c478bd9Sstevel@tonic-gate 	app = 0;
3317c478bd9Sstevel@tonic-gate 	return(offset = nextb);
3327c478bd9Sstevel@tonic-gate }
3337c478bd9Sstevel@tonic-gate 
3347c478bd9Sstevel@tonic-gate 
335*e5190c10Smuffin int
skip()3367c478bd9Sstevel@tonic-gate skip()			/*skip over blanks; return nlflg*/
3377c478bd9Sstevel@tonic-gate {
338*e5190c10Smuffin 	tchar i;
3397c478bd9Sstevel@tonic-gate 
3407c478bd9Sstevel@tonic-gate 	while (cbits(i = getch()) == ' ')
3417c478bd9Sstevel@tonic-gate 		;
3427c478bd9Sstevel@tonic-gate 	ch = i;
3437c478bd9Sstevel@tonic-gate 	return(nlflg);
3447c478bd9Sstevel@tonic-gate }
3457c478bd9Sstevel@tonic-gate 
3467c478bd9Sstevel@tonic-gate 
347*e5190c10Smuffin int
copyb()3487c478bd9Sstevel@tonic-gate copyb()
3497c478bd9Sstevel@tonic-gate {
350*e5190c10Smuffin 	int	i, j, state;
351*e5190c10Smuffin 	tchar ii;
3527c478bd9Sstevel@tonic-gate 	int	req, k;
3537c478bd9Sstevel@tonic-gate 	filep savoff;
3547c478bd9Sstevel@tonic-gate 
3557c478bd9Sstevel@tonic-gate 	if (skip() || !(j = getrq()))
3567c478bd9Sstevel@tonic-gate 		j = '.';
3577c478bd9Sstevel@tonic-gate 	req = j;
3587c478bd9Sstevel@tonic-gate 	k = j >> BYTE;
3597c478bd9Sstevel@tonic-gate 	j &= BYTEMASK;
3607c478bd9Sstevel@tonic-gate 	copyf++;
3617c478bd9Sstevel@tonic-gate 	flushi();
3627c478bd9Sstevel@tonic-gate 	nlflg = 0;
3637c478bd9Sstevel@tonic-gate 	state = 1;
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate /* state 0	eat up
3667c478bd9Sstevel@tonic-gate  * state 1	look for .
3677c478bd9Sstevel@tonic-gate  * state 2	look for first char of end macro
3687c478bd9Sstevel@tonic-gate  * state 3	look for second char of end macro
3697c478bd9Sstevel@tonic-gate  */
3707c478bd9Sstevel@tonic-gate 
3717c478bd9Sstevel@tonic-gate 	while (1) {
3727c478bd9Sstevel@tonic-gate 		i = cbits(ii = getch());
3737c478bd9Sstevel@tonic-gate 		if (state == 3) {
3747c478bd9Sstevel@tonic-gate 			if (i == k)
3757c478bd9Sstevel@tonic-gate 				break;
3767c478bd9Sstevel@tonic-gate 			if (!k) {
3777c478bd9Sstevel@tonic-gate 				ch = ii;
3787c478bd9Sstevel@tonic-gate 				i = getach();
3797c478bd9Sstevel@tonic-gate 				ch = ii;
3807c478bd9Sstevel@tonic-gate 				if (!i)
3817c478bd9Sstevel@tonic-gate 					break;
3827c478bd9Sstevel@tonic-gate 			}
3837c478bd9Sstevel@tonic-gate 			state = 0;
3847c478bd9Sstevel@tonic-gate 			goto c0;
3857c478bd9Sstevel@tonic-gate 		}
3867c478bd9Sstevel@tonic-gate 		if (i == '\n') {
3877c478bd9Sstevel@tonic-gate 			state = 1;
3887c478bd9Sstevel@tonic-gate 			nlflg = 0;
3897c478bd9Sstevel@tonic-gate 			goto c0;
3907c478bd9Sstevel@tonic-gate 		}
3917c478bd9Sstevel@tonic-gate 		if (state == 1 && i == '.') {
3927c478bd9Sstevel@tonic-gate 			state++;
3937c478bd9Sstevel@tonic-gate 			savoff = offset;
3947c478bd9Sstevel@tonic-gate 			goto c0;
3957c478bd9Sstevel@tonic-gate 		}
3967c478bd9Sstevel@tonic-gate 		if ((state == 2) && (i == j)) {
3977c478bd9Sstevel@tonic-gate 			state++;
3987c478bd9Sstevel@tonic-gate 			goto c0;
3997c478bd9Sstevel@tonic-gate 		}
4007c478bd9Sstevel@tonic-gate 		state = 0;
4017c478bd9Sstevel@tonic-gate c0:
4027c478bd9Sstevel@tonic-gate 		if (offset)
4037c478bd9Sstevel@tonic-gate 			wbf(ii);
4047c478bd9Sstevel@tonic-gate 	}
4057c478bd9Sstevel@tonic-gate 	if (offset) {
4067c478bd9Sstevel@tonic-gate 		wbfl();
4077c478bd9Sstevel@tonic-gate 		offset = savoff;
4087c478bd9Sstevel@tonic-gate 		wbt((tchar)0);
4097c478bd9Sstevel@tonic-gate 	}
4107c478bd9Sstevel@tonic-gate 	copyf--;
4117c478bd9Sstevel@tonic-gate 	return(req);
4127c478bd9Sstevel@tonic-gate }
4137c478bd9Sstevel@tonic-gate 
4147c478bd9Sstevel@tonic-gate 
415*e5190c10Smuffin int
copys()4167c478bd9Sstevel@tonic-gate copys()
4177c478bd9Sstevel@tonic-gate {
418*e5190c10Smuffin 	tchar i;
4197c478bd9Sstevel@tonic-gate 
4207c478bd9Sstevel@tonic-gate 	copyf++;
4217c478bd9Sstevel@tonic-gate 	if (skip())
4227c478bd9Sstevel@tonic-gate 		goto c0;
4237c478bd9Sstevel@tonic-gate 	if (cbits(i = getch()) != '"')
4247c478bd9Sstevel@tonic-gate 		wbf(i);
4257c478bd9Sstevel@tonic-gate 	while (cbits(i = getch()) != '\n')
4267c478bd9Sstevel@tonic-gate 		wbf(i);
4277c478bd9Sstevel@tonic-gate c0:
4287c478bd9Sstevel@tonic-gate 	wbt((tchar)0);
4297c478bd9Sstevel@tonic-gate 	copyf--;
430*e5190c10Smuffin 
431*e5190c10Smuffin 	return (0);
4327c478bd9Sstevel@tonic-gate }
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate 
alloc()4357c478bd9Sstevel@tonic-gate filep alloc()		/*return free blist[] block in nextb*/
4367c478bd9Sstevel@tonic-gate {
437*e5190c10Smuffin 	int	i;
438*e5190c10Smuffin 	filep j;
4397c478bd9Sstevel@tonic-gate 
4407c478bd9Sstevel@tonic-gate 	for (i = 0; i < NBLIST; i++) {
4417c478bd9Sstevel@tonic-gate 		if (blist[i] == 0)
4427c478bd9Sstevel@tonic-gate 			break;
4437c478bd9Sstevel@tonic-gate 	}
4447c478bd9Sstevel@tonic-gate 	if (i == NBLIST) {
4457c478bd9Sstevel@tonic-gate 		j = 0;
4467c478bd9Sstevel@tonic-gate 	} else {
4477c478bd9Sstevel@tonic-gate 		blist[i] = -1;
4487c478bd9Sstevel@tonic-gate 		j = (filep)i * BLK + ENV_BLK * BLK;
4497c478bd9Sstevel@tonic-gate 	}
4507c478bd9Sstevel@tonic-gate #ifdef	DEBUG
4517c478bd9Sstevel@tonic-gate 	if (debug & DB_ALLC) {
4527c478bd9Sstevel@tonic-gate 		char cc1, cc2;
4537c478bd9Sstevel@tonic-gate 		fdprintf(stderr, "alloc: ");
4547c478bd9Sstevel@tonic-gate 		if (oldmn >= 0 && oldmn < NM) {
4557c478bd9Sstevel@tonic-gate 			cc1 = contab[oldmn].rq & 0177;
4567c478bd9Sstevel@tonic-gate 			if ((cc2 = (contab[oldmn].rq >> BYTE) & 0177) == 0)
4577c478bd9Sstevel@tonic-gate 				cc2 = ' ';
4587c478bd9Sstevel@tonic-gate 			fdprintf(stderr, "oldmn %d %c%c, ", oldmn, cc1, cc2);
4597c478bd9Sstevel@tonic-gate 		}
4607c478bd9Sstevel@tonic-gate 		fdprintf(stderr, "newmn %d; nextb was %x, will be %x\n",
4617c478bd9Sstevel@tonic-gate 			newmn, nextb, j);
4627c478bd9Sstevel@tonic-gate 	}
463*e5190c10Smuffin #endif	/* DEBUG */
4647c478bd9Sstevel@tonic-gate 	return(nextb = j);
4657c478bd9Sstevel@tonic-gate }
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate 
468*e5190c10Smuffin int
ffree(i)4697c478bd9Sstevel@tonic-gate ffree(i)		/*free blist[i] and blocks pointed to*/
4707c478bd9Sstevel@tonic-gate filep i;
4717c478bd9Sstevel@tonic-gate {
472*e5190c10Smuffin 	int	j;
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 	while (blist[j = blisti(i)] != (unsigned) ~0) {
4757c478bd9Sstevel@tonic-gate 		i = (filep) blist[j];
4767c478bd9Sstevel@tonic-gate 		blist[j] = 0;
4777c478bd9Sstevel@tonic-gate 	}
4787c478bd9Sstevel@tonic-gate 	blist[j] = 0;
479*e5190c10Smuffin 
480*e5190c10Smuffin 	return (0);
4817c478bd9Sstevel@tonic-gate }
4827c478bd9Sstevel@tonic-gate 
483*e5190c10Smuffin int
wbt(i)4847c478bd9Sstevel@tonic-gate wbt(i)
4857c478bd9Sstevel@tonic-gate tchar i;
4867c478bd9Sstevel@tonic-gate {
4877c478bd9Sstevel@tonic-gate 	wbf(i);
4887c478bd9Sstevel@tonic-gate 	wbfl();
489*e5190c10Smuffin 
490*e5190c10Smuffin 	return (0);
4917c478bd9Sstevel@tonic-gate }
4927c478bd9Sstevel@tonic-gate 
4937c478bd9Sstevel@tonic-gate 
494*e5190c10Smuffin int
wbf(i)4957c478bd9Sstevel@tonic-gate wbf(i)			/*store i into blist[offset] (?) */
496*e5190c10Smuffin tchar i;
4977c478bd9Sstevel@tonic-gate {
498*e5190c10Smuffin 	int	j;
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate 	if (!offset)
501*e5190c10Smuffin 		return (0);
5027c478bd9Sstevel@tonic-gate 	if (!woff) {
5037c478bd9Sstevel@tonic-gate 		woff = offset;
5047c478bd9Sstevel@tonic-gate #ifdef INCORE
5057c478bd9Sstevel@tonic-gate 		wbuf = &corebuf[woff];	/* INCORE only */
5067c478bd9Sstevel@tonic-gate #endif
5077c478bd9Sstevel@tonic-gate 		wbfi = 0;
5087c478bd9Sstevel@tonic-gate 	}
5097c478bd9Sstevel@tonic-gate 	wbuf[wbfi++] = i;
5107c478bd9Sstevel@tonic-gate 	if (!((++offset) & (BLK - 1))) {
5117c478bd9Sstevel@tonic-gate 		wbfl();
5127c478bd9Sstevel@tonic-gate 		j = blisti(--offset);
5137c478bd9Sstevel@tonic-gate 		if (j < 0 || j >= NBLIST) {
5147c478bd9Sstevel@tonic-gate 			errprint(gettext("Out of temp file space"));
5157c478bd9Sstevel@tonic-gate 			done2(01);
5167c478bd9Sstevel@tonic-gate 		}
5177c478bd9Sstevel@tonic-gate 		if (blist[j] == (unsigned) ~0) {
5187c478bd9Sstevel@tonic-gate 			if (alloc() == 0) {
5197c478bd9Sstevel@tonic-gate 				errprint(gettext("Out of temp file space"));
5207c478bd9Sstevel@tonic-gate 				done2(01);
5217c478bd9Sstevel@tonic-gate 			}
5227c478bd9Sstevel@tonic-gate 			blist[j] = (unsigned)(nextb);
5237c478bd9Sstevel@tonic-gate 		}
5247c478bd9Sstevel@tonic-gate 		offset = ((filep)blist[j]);
5257c478bd9Sstevel@tonic-gate 	}
5267c478bd9Sstevel@tonic-gate 	if (wbfi >= BLK)
5277c478bd9Sstevel@tonic-gate 		wbfl();
528*e5190c10Smuffin 
529*e5190c10Smuffin 	return (0);
5307c478bd9Sstevel@tonic-gate }
5317c478bd9Sstevel@tonic-gate 
5327c478bd9Sstevel@tonic-gate 
533*e5190c10Smuffin int
wbfl()5347c478bd9Sstevel@tonic-gate wbfl()			/*flush current blist[] block*/
5357c478bd9Sstevel@tonic-gate {
5367c478bd9Sstevel@tonic-gate 	if (woff == 0)
537*e5190c10Smuffin 		return (0);
5387c478bd9Sstevel@tonic-gate #ifndef INCORE
5397c478bd9Sstevel@tonic-gate 	lseek(ibf, ((long)woff) * sizeof(tchar), 0);
5407c478bd9Sstevel@tonic-gate 	write(ibf, (char *)wbuf, wbfi * sizeof(tchar));
5417c478bd9Sstevel@tonic-gate #endif
5427c478bd9Sstevel@tonic-gate 	if ((woff & (~(BLK - 1))) == (roff & (~(BLK - 1))))
5437c478bd9Sstevel@tonic-gate 		roff = -1;
5447c478bd9Sstevel@tonic-gate 	woff = 0;
545*e5190c10Smuffin 
546*e5190c10Smuffin 	return (0);
5477c478bd9Sstevel@tonic-gate }
5487c478bd9Sstevel@tonic-gate 
5497c478bd9Sstevel@tonic-gate 
rbf()5507c478bd9Sstevel@tonic-gate tchar rbf()		/*return next char from blist[] block*/
5517c478bd9Sstevel@tonic-gate {
552*e5190c10Smuffin 	tchar i;
553*e5190c10Smuffin 	filep j, p;
5547c478bd9Sstevel@tonic-gate 	extern filep incoff();
5557c478bd9Sstevel@tonic-gate 
5567c478bd9Sstevel@tonic-gate 	if (ip == NBLIST*BLK) {		/* for rdtty */
5577c478bd9Sstevel@tonic-gate 		if (j = rdtty())
5587c478bd9Sstevel@tonic-gate 			return(j);
5597c478bd9Sstevel@tonic-gate 		else
5607c478bd9Sstevel@tonic-gate 			return(popi());
5617c478bd9Sstevel@tonic-gate 	}
5627c478bd9Sstevel@tonic-gate 	/* this is an inline expansion of rbf0: dirty! */
5637c478bd9Sstevel@tonic-gate #ifndef INCORE
5647c478bd9Sstevel@tonic-gate 	j = ip & ~(BLK - 1);
5657c478bd9Sstevel@tonic-gate 	if (j != roff) {
5667c478bd9Sstevel@tonic-gate 		roff = j;
5677c478bd9Sstevel@tonic-gate 		lseek(ibf, (long)j * sizeof(tchar), 0);
5687c478bd9Sstevel@tonic-gate 		if (read(ibf, (char *)rbuf, BLK * sizeof(tchar)) <= 0)
5697c478bd9Sstevel@tonic-gate 			i = 0;
5707c478bd9Sstevel@tonic-gate 		else
5717c478bd9Sstevel@tonic-gate 			i = rbuf[ip & (BLK-1)];
5727c478bd9Sstevel@tonic-gate 	} else
5737c478bd9Sstevel@tonic-gate 		i = rbuf[ip & (BLK-1)];
5747c478bd9Sstevel@tonic-gate #else
5757c478bd9Sstevel@tonic-gate 	i = corebuf[ip];
5767c478bd9Sstevel@tonic-gate #endif
5777c478bd9Sstevel@tonic-gate 	/* end of rbf0 */
5787c478bd9Sstevel@tonic-gate 	if (i == 0) {
5797c478bd9Sstevel@tonic-gate 		if (!app)
5807c478bd9Sstevel@tonic-gate 			i = popi();
5817c478bd9Sstevel@tonic-gate 		return(i);
5827c478bd9Sstevel@tonic-gate 	}
5837c478bd9Sstevel@tonic-gate 	/* this is an inline expansion of incoff: also dirty */
5847c478bd9Sstevel@tonic-gate 	p = ++ip;
5857c478bd9Sstevel@tonic-gate 	if ((p & (BLK - 1)) == 0) {
5867c478bd9Sstevel@tonic-gate 		if ((ip = blist[blisti(p-1)]) == (unsigned) ~0) {
5877c478bd9Sstevel@tonic-gate 			errprint(gettext("Bad storage allocation"));
5887c478bd9Sstevel@tonic-gate 			ip = 0;
5897c478bd9Sstevel@tonic-gate 			done2(-5);
5907c478bd9Sstevel@tonic-gate 		}
5917c478bd9Sstevel@tonic-gate 		/* this was meant to protect against people removing
5927c478bd9Sstevel@tonic-gate 		 * the macro they were standing on, but it's too
5937c478bd9Sstevel@tonic-gate 		 * sensitive to block boundaries.
5947c478bd9Sstevel@tonic-gate 		 * if (ip == 0) {
5957c478bd9Sstevel@tonic-gate 		 *	errprint(gettext("Block removed while in use"));
5967c478bd9Sstevel@tonic-gate 		 *	done2(-6);
5977c478bd9Sstevel@tonic-gate 		 * }
5987c478bd9Sstevel@tonic-gate 		 */
5997c478bd9Sstevel@tonic-gate 	}
6007c478bd9Sstevel@tonic-gate 	return(i);
6017c478bd9Sstevel@tonic-gate }
6027c478bd9Sstevel@tonic-gate 
6037c478bd9Sstevel@tonic-gate 
rbf0(p)6047c478bd9Sstevel@tonic-gate tchar rbf0(p)
605*e5190c10Smuffin filep p;
6067c478bd9Sstevel@tonic-gate {
6077c478bd9Sstevel@tonic-gate #ifndef INCORE
608*e5190c10Smuffin 	filep i;
6097c478bd9Sstevel@tonic-gate 
6107c478bd9Sstevel@tonic-gate 	if ((i = p & ~(BLK - 1)) != roff) {
6117c478bd9Sstevel@tonic-gate 		roff = i;
6127c478bd9Sstevel@tonic-gate 		lseek(ibf, (long)roff * sizeof(tchar), 0);
6137c478bd9Sstevel@tonic-gate 		if (read(ibf, (char *)rbuf, BLK * sizeof(tchar)) == 0)
6147c478bd9Sstevel@tonic-gate 			return(0);
6157c478bd9Sstevel@tonic-gate 	}
6167c478bd9Sstevel@tonic-gate 	return(rbuf[p & (BLK-1)]);
6177c478bd9Sstevel@tonic-gate #else
6187c478bd9Sstevel@tonic-gate 	return(corebuf[p]);
6197c478bd9Sstevel@tonic-gate #endif
6207c478bd9Sstevel@tonic-gate }
6217c478bd9Sstevel@tonic-gate 
6227c478bd9Sstevel@tonic-gate 
incoff(p)6237c478bd9Sstevel@tonic-gate filep incoff(p)		/*get next blist[] block*/
624*e5190c10Smuffin filep p;
6257c478bd9Sstevel@tonic-gate {
6267c478bd9Sstevel@tonic-gate 	p++;
6277c478bd9Sstevel@tonic-gate 	if ((p & (BLK - 1)) == 0) {
6287c478bd9Sstevel@tonic-gate 		if ((p = blist[blisti(p-1)]) == (unsigned) ~0) {
6297c478bd9Sstevel@tonic-gate 			errprint(gettext("Bad storage allocation"));
6307c478bd9Sstevel@tonic-gate 			done2(-5);
6317c478bd9Sstevel@tonic-gate 		}
6327c478bd9Sstevel@tonic-gate 	}
6337c478bd9Sstevel@tonic-gate 	return(p);
6347c478bd9Sstevel@tonic-gate }
6357c478bd9Sstevel@tonic-gate 
6367c478bd9Sstevel@tonic-gate 
popi()6377c478bd9Sstevel@tonic-gate tchar popi()
6387c478bd9Sstevel@tonic-gate {
639*e5190c10Smuffin 	struct s *p;
6407c478bd9Sstevel@tonic-gate 
6417c478bd9Sstevel@tonic-gate 	if (frame == stk)
6427c478bd9Sstevel@tonic-gate 		return(0);
6437c478bd9Sstevel@tonic-gate 	if (strflg)
6447c478bd9Sstevel@tonic-gate 		strflg--;
6457c478bd9Sstevel@tonic-gate 	p = nxf = frame;
6467c478bd9Sstevel@tonic-gate 	p->nargs = 0;
6477c478bd9Sstevel@tonic-gate 	frame = p->pframe;
6487c478bd9Sstevel@tonic-gate 	ip = p->pip;
6497c478bd9Sstevel@tonic-gate 	pendt = p->ppendt;
6507c478bd9Sstevel@tonic-gate 	lastpbp = p->lastpbp;
6517c478bd9Sstevel@tonic-gate 	return(p->pch);
6527c478bd9Sstevel@tonic-gate }
6537c478bd9Sstevel@tonic-gate 
6547c478bd9Sstevel@tonic-gate /*
6557c478bd9Sstevel@tonic-gate  *	test that the end of the allocation is above a certain location
6567c478bd9Sstevel@tonic-gate  *	in memory
6577c478bd9Sstevel@tonic-gate  */
6587c478bd9Sstevel@tonic-gate #define SPACETEST(base, size) while ((enda - (size)) <= (char *)(base)){setbrk(DELTA);}
6597c478bd9Sstevel@tonic-gate 
660*e5190c10Smuffin int
pushi(newip,mname)6617c478bd9Sstevel@tonic-gate pushi(newip, mname)
6627c478bd9Sstevel@tonic-gate filep newip;
6637c478bd9Sstevel@tonic-gate int mname;
6647c478bd9Sstevel@tonic-gate {
665*e5190c10Smuffin 	struct s *p;
6667c478bd9Sstevel@tonic-gate 	extern char *setbrk();
6677c478bd9Sstevel@tonic-gate 
6687c478bd9Sstevel@tonic-gate 	SPACETEST(nxf, sizeof(struct s));
6697c478bd9Sstevel@tonic-gate 	p = nxf;
6707c478bd9Sstevel@tonic-gate 	p->pframe = frame;
6717c478bd9Sstevel@tonic-gate 	p->pip = ip;
6727c478bd9Sstevel@tonic-gate 	p->ppendt = pendt;
6737c478bd9Sstevel@tonic-gate 	p->pch = ch;
6747c478bd9Sstevel@tonic-gate 	p->lastpbp = lastpbp;
6757c478bd9Sstevel@tonic-gate 	p->mname = mname;
6767c478bd9Sstevel@tonic-gate 	lastpbp = pbp;
6777c478bd9Sstevel@tonic-gate 	pendt = ch = 0;
6787c478bd9Sstevel@tonic-gate 	frame = nxf;
6797c478bd9Sstevel@tonic-gate 	if (nxf->nargs == 0)
6807c478bd9Sstevel@tonic-gate 		nxf += 1;
6817c478bd9Sstevel@tonic-gate 	else
6827c478bd9Sstevel@tonic-gate 		nxf = (struct s *)argtop;
6837c478bd9Sstevel@tonic-gate 	return(ip = newip);
6847c478bd9Sstevel@tonic-gate }
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate 
setbrk(x)6877c478bd9Sstevel@tonic-gate char	*setbrk(x)
6887c478bd9Sstevel@tonic-gate int	x;
6897c478bd9Sstevel@tonic-gate {
690*e5190c10Smuffin 	char	*i, *k;
691*e5190c10Smuffin 	int	j;
6927c478bd9Sstevel@tonic-gate 	char	*sbrk();
6937c478bd9Sstevel@tonic-gate 
6947c478bd9Sstevel@tonic-gate 	if ((i = sbrk(x)) == (char *) -1) {
6957c478bd9Sstevel@tonic-gate 		errprint(gettext("Core limit reached"));
6967c478bd9Sstevel@tonic-gate 		edone(0100);
6977c478bd9Sstevel@tonic-gate 	}
6987c478bd9Sstevel@tonic-gate 	if (j = (unsigned)i % sizeof(int)) {	/*check alignment for 3B*/
6997c478bd9Sstevel@tonic-gate 		j = sizeof(int) - j;		/*only init calls should need this*/
7007c478bd9Sstevel@tonic-gate 		if ((k = sbrk(j)) == (char *) -1) {
7017c478bd9Sstevel@tonic-gate 			errprint("Core limit reached");
7027c478bd9Sstevel@tonic-gate 			edone(0100);
7037c478bd9Sstevel@tonic-gate 		}
7047c478bd9Sstevel@tonic-gate 		if (k != i + x) {	/*there must have been an intervening sbrk*/
7057c478bd9Sstevel@tonic-gate 			errprint ("internal error in setbrk: i=%x, j=%d, k=%x",
7067c478bd9Sstevel@tonic-gate 				i, j, k);
7077c478bd9Sstevel@tonic-gate 			edone(0100);
7087c478bd9Sstevel@tonic-gate 		}
7097c478bd9Sstevel@tonic-gate 		i += j;
7107c478bd9Sstevel@tonic-gate 	}
7117c478bd9Sstevel@tonic-gate 	enda = i + x;
7127c478bd9Sstevel@tonic-gate 	return(i);
7137c478bd9Sstevel@tonic-gate }
7147c478bd9Sstevel@tonic-gate 
7157c478bd9Sstevel@tonic-gate 
716*e5190c10Smuffin int
getsn()7177c478bd9Sstevel@tonic-gate getsn()
7187c478bd9Sstevel@tonic-gate {
719*e5190c10Smuffin 	int	i;
7207c478bd9Sstevel@tonic-gate 
7217c478bd9Sstevel@tonic-gate 	if ((i = getach()) == 0)
7227c478bd9Sstevel@tonic-gate 		return(0);
7237c478bd9Sstevel@tonic-gate 	if (i == '(')
7247c478bd9Sstevel@tonic-gate 		return(getrq());
7257c478bd9Sstevel@tonic-gate 	else
7267c478bd9Sstevel@tonic-gate 		return(i);
7277c478bd9Sstevel@tonic-gate }
7287c478bd9Sstevel@tonic-gate 
7297c478bd9Sstevel@tonic-gate 
730*e5190c10Smuffin int
setstr()7317c478bd9Sstevel@tonic-gate setstr()
7327c478bd9Sstevel@tonic-gate {
733*e5190c10Smuffin 	int	i, j;
7347c478bd9Sstevel@tonic-gate 
7357c478bd9Sstevel@tonic-gate 	lgf++;
7367c478bd9Sstevel@tonic-gate 	if ((i = getsn()) == 0 || (j = findmn(i)) == -1 || !contab[j].mx) {
7377c478bd9Sstevel@tonic-gate 		lgf--;
7387c478bd9Sstevel@tonic-gate 		return(0);
7397c478bd9Sstevel@tonic-gate 	} else {
7407c478bd9Sstevel@tonic-gate 		SPACETEST(nxf, sizeof(struct s));
7417c478bd9Sstevel@tonic-gate 		nxf->nargs = 0;
7427c478bd9Sstevel@tonic-gate 		strflg++;
7437c478bd9Sstevel@tonic-gate 		lgf--;
7447c478bd9Sstevel@tonic-gate 		return pushi((filep)contab[j].mx, i);
7457c478bd9Sstevel@tonic-gate 	}
7467c478bd9Sstevel@tonic-gate }
7477c478bd9Sstevel@tonic-gate 
7487c478bd9Sstevel@tonic-gate 
749*e5190c10Smuffin int
collect()7507c478bd9Sstevel@tonic-gate collect()
7517c478bd9Sstevel@tonic-gate {
752*e5190c10Smuffin 	int	j;
753*e5190c10Smuffin 	tchar i;
754*e5190c10Smuffin 	tchar *strp;
7557c478bd9Sstevel@tonic-gate 	tchar * lim;
7567c478bd9Sstevel@tonic-gate 	tchar * *argpp, **argppend;
7577c478bd9Sstevel@tonic-gate 	int	quote;
7587c478bd9Sstevel@tonic-gate 	struct s *savnxf;
7597c478bd9Sstevel@tonic-gate 
7607c478bd9Sstevel@tonic-gate 	copyf++;
7617c478bd9Sstevel@tonic-gate 	nxf->nargs = 0;
7627c478bd9Sstevel@tonic-gate 	savnxf = nxf;
7637c478bd9Sstevel@tonic-gate 	if (skip())
7647c478bd9Sstevel@tonic-gate 		goto rtn;
7657c478bd9Sstevel@tonic-gate 
7667c478bd9Sstevel@tonic-gate 	{
7677c478bd9Sstevel@tonic-gate 		char *memp;
7687c478bd9Sstevel@tonic-gate 		memp = (char *)savnxf;
7697c478bd9Sstevel@tonic-gate 		/*
7707c478bd9Sstevel@tonic-gate 		 *	1 s structure for the macro descriptor
7717c478bd9Sstevel@tonic-gate 		 *	APERMAC tchar *'s for pointers into the strings
7727c478bd9Sstevel@tonic-gate 		 *	space for the tchar's themselves
7737c478bd9Sstevel@tonic-gate 		 */
7747c478bd9Sstevel@tonic-gate 		memp += sizeof(struct s);
7757c478bd9Sstevel@tonic-gate 		/*
7767c478bd9Sstevel@tonic-gate 		 *	CPERMAC (the total # of characters for ALL arguments)
7777c478bd9Sstevel@tonic-gate 		 *	to a macros, has been carefully chosen
7787c478bd9Sstevel@tonic-gate 		 *	so that the distance between stack frames is < DELTA
7797c478bd9Sstevel@tonic-gate 		 */
7807c478bd9Sstevel@tonic-gate #define	CPERMAC	200
7817c478bd9Sstevel@tonic-gate #define	APERMAC	9
7827c478bd9Sstevel@tonic-gate 		memp += APERMAC * sizeof(tchar *);
7837c478bd9Sstevel@tonic-gate 		memp += CPERMAC * sizeof(tchar);
7847c478bd9Sstevel@tonic-gate 		nxf = (struct s*)memp;
7857c478bd9Sstevel@tonic-gate 	}
7867c478bd9Sstevel@tonic-gate 	lim = (tchar *)nxf;
7877c478bd9Sstevel@tonic-gate 	argpp = (tchar **)(savnxf + 1);
7887c478bd9Sstevel@tonic-gate 	argppend = &argpp[APERMAC];
7897c478bd9Sstevel@tonic-gate 	SPACETEST(argppend, sizeof(tchar *));
7907c478bd9Sstevel@tonic-gate 	strp = (tchar *)argppend;
7917c478bd9Sstevel@tonic-gate 	/*
7927c478bd9Sstevel@tonic-gate 	 *	Zero out all the string pointers before filling them in.
7937c478bd9Sstevel@tonic-gate 	 */
7947c478bd9Sstevel@tonic-gate 	for (j = 0; j < APERMAC; j++){
7957c478bd9Sstevel@tonic-gate 		argpp[j] = (tchar *)0;
7967c478bd9Sstevel@tonic-gate 	}
7977c478bd9Sstevel@tonic-gate #if 0
7987c478bd9Sstevel@tonic-gate 	errprint("savnxf=0x%x,nxf=0x%x,argpp=0x%x,strp=argppend=0x%x,lim=0x%x,enda=0x%x",
7997c478bd9Sstevel@tonic-gate 		savnxf, nxf, argpp, strp, lim, enda);
800*e5190c10Smuffin #endif
8017c478bd9Sstevel@tonic-gate 	strflg = 0;
8027c478bd9Sstevel@tonic-gate 	while ((argpp != argppend) && (!skip())) {
8037c478bd9Sstevel@tonic-gate 		*argpp++ = strp;
8047c478bd9Sstevel@tonic-gate 		quote = 0;
8057c478bd9Sstevel@tonic-gate 		if (cbits(i = getch()) == '"')
8067c478bd9Sstevel@tonic-gate 			quote++;
8077c478bd9Sstevel@tonic-gate 		else
8087c478bd9Sstevel@tonic-gate 			ch = i;
8097c478bd9Sstevel@tonic-gate 		while (1) {
8107c478bd9Sstevel@tonic-gate 			i = getch();
8117c478bd9Sstevel@tonic-gate 			if (nlflg || (!quote && cbits(i) == ' '))
8127c478bd9Sstevel@tonic-gate 				break;
8137c478bd9Sstevel@tonic-gate 			if (   quote
8147c478bd9Sstevel@tonic-gate 			    && (cbits(i) == '"')
8157c478bd9Sstevel@tonic-gate 			    && (cbits(i = getch()) != '"')) {
8167c478bd9Sstevel@tonic-gate 				ch = i;
8177c478bd9Sstevel@tonic-gate 				break;
8187c478bd9Sstevel@tonic-gate 			}
8197c478bd9Sstevel@tonic-gate 			*strp++ = i;
8207c478bd9Sstevel@tonic-gate 			if (strflg && strp >= lim) {
8217c478bd9Sstevel@tonic-gate #if 0
8227c478bd9Sstevel@tonic-gate 				errprint("strp=0x%x, lim = 0x%x",
8237c478bd9Sstevel@tonic-gate 					strp, lim);
824*e5190c10Smuffin #endif
8257c478bd9Sstevel@tonic-gate 				errprint(gettext("Macro argument too long"));
8267c478bd9Sstevel@tonic-gate 				copyf--;
8277c478bd9Sstevel@tonic-gate 				edone(004);
8287c478bd9Sstevel@tonic-gate 			}
8297c478bd9Sstevel@tonic-gate 			SPACETEST(strp, 3 * sizeof(tchar));
8307c478bd9Sstevel@tonic-gate 		}
8317c478bd9Sstevel@tonic-gate 		*strp++ = 0;
8327c478bd9Sstevel@tonic-gate 	}
8337c478bd9Sstevel@tonic-gate 	nxf = savnxf;
8347c478bd9Sstevel@tonic-gate 	nxf->nargs = argpp - (tchar **)(savnxf + 1);
8357c478bd9Sstevel@tonic-gate 	argtop = strp;
8367c478bd9Sstevel@tonic-gate rtn:
8377c478bd9Sstevel@tonic-gate 	copyf--;
838*e5190c10Smuffin 
839*e5190c10Smuffin 	return (0);
8407c478bd9Sstevel@tonic-gate }
8417c478bd9Sstevel@tonic-gate 
8427c478bd9Sstevel@tonic-gate 
843*e5190c10Smuffin int
seta()8447c478bd9Sstevel@tonic-gate seta()
8457c478bd9Sstevel@tonic-gate {
846*e5190c10Smuffin 	int	i;
8477c478bd9Sstevel@tonic-gate 
8487c478bd9Sstevel@tonic-gate 	i = cbits(getch()) - '0';
8497c478bd9Sstevel@tonic-gate 	if (i > 0 && i <= APERMAC && i <= frame->nargs)
8507c478bd9Sstevel@tonic-gate 		pushback(*(((tchar **)(frame + 1)) + i - 1));
851*e5190c10Smuffin 
852*e5190c10Smuffin 	return (0);
8537c478bd9Sstevel@tonic-gate }
8547c478bd9Sstevel@tonic-gate 
8557c478bd9Sstevel@tonic-gate 
856*e5190c10Smuffin int
caseda()8577c478bd9Sstevel@tonic-gate caseda()
8587c478bd9Sstevel@tonic-gate {
8597c478bd9Sstevel@tonic-gate 	app++;
8607c478bd9Sstevel@tonic-gate 	casedi();
861*e5190c10Smuffin 
862*e5190c10Smuffin 	return (0);
8637c478bd9Sstevel@tonic-gate }
8647c478bd9Sstevel@tonic-gate 
8657c478bd9Sstevel@tonic-gate 
866*e5190c10Smuffin int
casedi()8677c478bd9Sstevel@tonic-gate casedi()
8687c478bd9Sstevel@tonic-gate {
869*e5190c10Smuffin 	int	i, j;
870*e5190c10Smuffin 	int	*k;
8717c478bd9Sstevel@tonic-gate 
8727c478bd9Sstevel@tonic-gate 	lgf++;
8737c478bd9Sstevel@tonic-gate 	if (skip() || (i = getrq()) == 0) {
8747c478bd9Sstevel@tonic-gate 		if (dip != d)
8757c478bd9Sstevel@tonic-gate 			wbt((tchar)0);
8767c478bd9Sstevel@tonic-gate 		if (dilev > 0) {
8777c478bd9Sstevel@tonic-gate 			numtab[DN].val = dip->dnl;
8787c478bd9Sstevel@tonic-gate 			numtab[DL].val = dip->maxl;
8797c478bd9Sstevel@tonic-gate 			dip = &d[--dilev];
8807c478bd9Sstevel@tonic-gate 			offset = dip->op;
8817c478bd9Sstevel@tonic-gate 		}
8827c478bd9Sstevel@tonic-gate 		goto rtn;
8837c478bd9Sstevel@tonic-gate 	}
8847c478bd9Sstevel@tonic-gate 	if (++dilev == NDI) {
8857c478bd9Sstevel@tonic-gate 		--dilev;
8867c478bd9Sstevel@tonic-gate 		errprint(gettext("Diversions nested too deep"));
8877c478bd9Sstevel@tonic-gate 		edone(02);
8887c478bd9Sstevel@tonic-gate 	}
8897c478bd9Sstevel@tonic-gate 	if (dip != d)
8907c478bd9Sstevel@tonic-gate 		wbt((tchar)0);
8917c478bd9Sstevel@tonic-gate 	diflg++;
8927c478bd9Sstevel@tonic-gate 	dip = &d[dilev];
8937c478bd9Sstevel@tonic-gate 	dip->op = finds(i);
8947c478bd9Sstevel@tonic-gate 	dip->curd = i;
8957c478bd9Sstevel@tonic-gate 	clrmn(oldmn);
8967c478bd9Sstevel@tonic-gate 	k = (int *) & dip->dnl;
8977c478bd9Sstevel@tonic-gate 	for (j = 0; j < 10; j++)
8987c478bd9Sstevel@tonic-gate 		k[j] = 0;	/*not op and curd*/
8997c478bd9Sstevel@tonic-gate rtn:
9007c478bd9Sstevel@tonic-gate 	app = 0;
9017c478bd9Sstevel@tonic-gate 	diflg = 0;
902*e5190c10Smuffin 
903*e5190c10Smuffin 	return (0);
9047c478bd9Sstevel@tonic-gate }
9057c478bd9Sstevel@tonic-gate 
9067c478bd9Sstevel@tonic-gate 
907*e5190c10Smuffin int
casedt()9087c478bd9Sstevel@tonic-gate casedt()
9097c478bd9Sstevel@tonic-gate {
9107c478bd9Sstevel@tonic-gate 	lgf++;
9117c478bd9Sstevel@tonic-gate 	dip->dimac = dip->ditrap = dip->ditf = 0;
9127c478bd9Sstevel@tonic-gate 	skip();
9137c478bd9Sstevel@tonic-gate 	dip->ditrap = vnumb((int *)0);
9147c478bd9Sstevel@tonic-gate 	if (nonumb)
915*e5190c10Smuffin 		return (0);
9167c478bd9Sstevel@tonic-gate 	skip();
9177c478bd9Sstevel@tonic-gate 	dip->dimac = getrq();
918*e5190c10Smuffin 
919*e5190c10Smuffin 	return (0);
9207c478bd9Sstevel@tonic-gate }
9217c478bd9Sstevel@tonic-gate 
9227c478bd9Sstevel@tonic-gate 
923*e5190c10Smuffin int
casetl()9247c478bd9Sstevel@tonic-gate casetl()
9257c478bd9Sstevel@tonic-gate {
926*e5190c10Smuffin 	int	j;
9277c478bd9Sstevel@tonic-gate 	int w[3];
9287c478bd9Sstevel@tonic-gate 	tchar buf[LNSIZE];
929*e5190c10Smuffin 	tchar *tp;
9307c478bd9Sstevel@tonic-gate 	tchar i, delim;
9317c478bd9Sstevel@tonic-gate 
9327c478bd9Sstevel@tonic-gate 	dip->nls = 0;
9337c478bd9Sstevel@tonic-gate 	skip();
9347c478bd9Sstevel@tonic-gate 	if (ismot(delim = getch())) {
9357c478bd9Sstevel@tonic-gate 		ch = delim;
9367c478bd9Sstevel@tonic-gate 		delim = '\'';
9377c478bd9Sstevel@tonic-gate 	} else
9387c478bd9Sstevel@tonic-gate 		delim = cbits(delim);
9397c478bd9Sstevel@tonic-gate 	tp = buf;
9407c478bd9Sstevel@tonic-gate 	numtab[HP].val = 0;
9417c478bd9Sstevel@tonic-gate 	w[0] = w[1] = w[2] = 0;
9427c478bd9Sstevel@tonic-gate 	j = 0;
9437c478bd9Sstevel@tonic-gate 	while (cbits(i = getch()) != '\n') {
9447c478bd9Sstevel@tonic-gate 		if (cbits(i) == cbits(delim)) {
9457c478bd9Sstevel@tonic-gate 			if (j < 3)
9467c478bd9Sstevel@tonic-gate 				w[j] = numtab[HP].val;
9477c478bd9Sstevel@tonic-gate 			numtab[HP].val = 0;
9487c478bd9Sstevel@tonic-gate 			j++;
9497c478bd9Sstevel@tonic-gate 			*tp++ = 0;
9507c478bd9Sstevel@tonic-gate 		} else {
9517c478bd9Sstevel@tonic-gate 			if (cbits(i) == pagech) {
9527c478bd9Sstevel@tonic-gate 				setn1(numtab[PN].val, numtab[findr('%')].fmt,
9537c478bd9Sstevel@tonic-gate 				      i&SFMASK);
9547c478bd9Sstevel@tonic-gate 				continue;
9557c478bd9Sstevel@tonic-gate 			}
9567c478bd9Sstevel@tonic-gate 			numtab[HP].val += width(i);
9577c478bd9Sstevel@tonic-gate 			if (tp < &buf[LNSIZE-10])
9587c478bd9Sstevel@tonic-gate 				*tp++ = i;
9597c478bd9Sstevel@tonic-gate 		}
9607c478bd9Sstevel@tonic-gate 	}
9617c478bd9Sstevel@tonic-gate 	if (j<3)
9627c478bd9Sstevel@tonic-gate 		w[j] = numtab[HP].val;
9637c478bd9Sstevel@tonic-gate 	*tp++ = 0;
9647c478bd9Sstevel@tonic-gate 	*tp++ = 0;
9657c478bd9Sstevel@tonic-gate 	*tp++ = 0;
9667c478bd9Sstevel@tonic-gate 	tp = buf;
9677c478bd9Sstevel@tonic-gate #ifdef NROFF
9687c478bd9Sstevel@tonic-gate 	horiz(po);
9697c478bd9Sstevel@tonic-gate #endif
9707c478bd9Sstevel@tonic-gate 	while (i = *tp++)
9717c478bd9Sstevel@tonic-gate 		pchar(i);
9727c478bd9Sstevel@tonic-gate 	if (w[1] || w[2])
9737c478bd9Sstevel@tonic-gate 		horiz(j = quant((lt - w[1]) / 2 - w[0], HOR));
9747c478bd9Sstevel@tonic-gate 	while (i = *tp++)
9757c478bd9Sstevel@tonic-gate 		pchar(i);
9767c478bd9Sstevel@tonic-gate 	if (w[2]) {
9777c478bd9Sstevel@tonic-gate 		horiz(lt - w[0] - w[1] - w[2] - j);
9787c478bd9Sstevel@tonic-gate 		while (i = *tp++)
9797c478bd9Sstevel@tonic-gate 			pchar(i);
9807c478bd9Sstevel@tonic-gate 	}
9817c478bd9Sstevel@tonic-gate 	newline(0);
9827c478bd9Sstevel@tonic-gate 	if (dip != d) {
9837c478bd9Sstevel@tonic-gate 		if (dip->dnl > dip->hnl)
9847c478bd9Sstevel@tonic-gate 			dip->hnl = dip->dnl;
9857c478bd9Sstevel@tonic-gate 	} else {
9867c478bd9Sstevel@tonic-gate 		if (numtab[NL].val > dip->hnl)
9877c478bd9Sstevel@tonic-gate 			dip->hnl = numtab[NL].val;
9887c478bd9Sstevel@tonic-gate 	}
989*e5190c10Smuffin 
990*e5190c10Smuffin 	return (0);
9917c478bd9Sstevel@tonic-gate }
9927c478bd9Sstevel@tonic-gate 
9937c478bd9Sstevel@tonic-gate 
994*e5190c10Smuffin int
casepc()9957c478bd9Sstevel@tonic-gate casepc()
9967c478bd9Sstevel@tonic-gate {
9977c478bd9Sstevel@tonic-gate 	pagech = chget(IMP);
998*e5190c10Smuffin 
999*e5190c10Smuffin 	return (0);
10007c478bd9Sstevel@tonic-gate }
10017c478bd9Sstevel@tonic-gate 
10027c478bd9Sstevel@tonic-gate 
1003*e5190c10Smuffin int
casepm()10047c478bd9Sstevel@tonic-gate casepm()
10057c478bd9Sstevel@tonic-gate {
1006*e5190c10Smuffin 	int	i, k;
1007*e5190c10Smuffin 	char	*p;
10087c478bd9Sstevel@tonic-gate 	int	xx, cnt, tcnt, kk, tot;
10097c478bd9Sstevel@tonic-gate 	filep j;
10107c478bd9Sstevel@tonic-gate 	char	pmline[10];
10117c478bd9Sstevel@tonic-gate 
10127c478bd9Sstevel@tonic-gate 	kk = cnt = tcnt = 0;
10137c478bd9Sstevel@tonic-gate 	tot = !skip();
10147c478bd9Sstevel@tonic-gate 	for (i = 0; i < NM; i++) {
10157c478bd9Sstevel@tonic-gate 		if ((xx = contab[i].rq) == 0 || contab[i].mx == 0)
10167c478bd9Sstevel@tonic-gate 			continue;
10177c478bd9Sstevel@tonic-gate 		tcnt++;
10187c478bd9Sstevel@tonic-gate 		p = pmline;
10197c478bd9Sstevel@tonic-gate 		j = (filep) contab[i].mx;
10207c478bd9Sstevel@tonic-gate 		k = 1;
10217c478bd9Sstevel@tonic-gate 		while ((j = blist[blisti(j)]) != (unsigned) ~0) {
10227c478bd9Sstevel@tonic-gate 			k++;
10237c478bd9Sstevel@tonic-gate 		}
10247c478bd9Sstevel@tonic-gate 		cnt++;
10257c478bd9Sstevel@tonic-gate 		kk += k;
10267c478bd9Sstevel@tonic-gate 		if (!tot) {
10277c478bd9Sstevel@tonic-gate 			*p++ = xx & 0177;
10287c478bd9Sstevel@tonic-gate 			if (!(*p++ = (xx >> BYTE) & 0177))
10297c478bd9Sstevel@tonic-gate 				*(p - 1) = ' ';
10307c478bd9Sstevel@tonic-gate 			*p++ = 0;
10317c478bd9Sstevel@tonic-gate 			fdprintf(stderr, "%s %d\n", pmline, k);
10327c478bd9Sstevel@tonic-gate 		}
10337c478bd9Sstevel@tonic-gate 	}
10347c478bd9Sstevel@tonic-gate 	fdprintf(stderr, "pm: total %d, macros %d, space %d\n", tcnt, cnt, kk);
1035*e5190c10Smuffin 
1036*e5190c10Smuffin 	return (0);
10377c478bd9Sstevel@tonic-gate }
10387c478bd9Sstevel@tonic-gate 
1039*e5190c10Smuffin int
stackdump()10407c478bd9Sstevel@tonic-gate stackdump()	/* dumps stack of macros in process */
10417c478bd9Sstevel@tonic-gate {
10427c478bd9Sstevel@tonic-gate 	struct s *p;
10437c478bd9Sstevel@tonic-gate 
10447c478bd9Sstevel@tonic-gate 	if (frame != stk) {
10457c478bd9Sstevel@tonic-gate 		for (p = frame; p != stk; p = p->pframe)
10467c478bd9Sstevel@tonic-gate 			fdprintf(stderr, "%c%c ", p->mname&0177, (p->mname>>BYTE)&0177);
10477c478bd9Sstevel@tonic-gate 		fdprintf(stderr, "\n");
10487c478bd9Sstevel@tonic-gate 	}
1049*e5190c10Smuffin 
1050*e5190c10Smuffin 	return (0);
10517c478bd9Sstevel@tonic-gate }
1052