/*
 * troff3.c
 * 
 * macro and string routines, storage allocation
 */

#include "tdef.h"
#include "fns.h"
#include "ext.h"

Tchar	*argtop;
int	pagech = '%';
int	strflg;

#define	MHASHSIZE	128	/* must be 2**n */
#define	MHASH(x)	((x>>6)^x) & (MHASHSIZE-1)
Contab	*mhash[MHASHSIZE];


Blockp	*blist;		/* allocated blocks for macros and strings */
int	nblist;		/* how many there are */
int	bfree = -1;	/* first (possible) free block in the list */

Contab *contabp = NULL;
#define MDELTA 500
int	nm = 0;

int savname;		/* name of macro/string being defined */
int savslot;		/* place in Contab of savname */
int freeslot = -1;	/* first (possible) free slot in contab */

void prcontab(Contab *p)
{
	int i;
	for (i = 0; i < nm; i++)
		if (p)
			if (p[i].rq != 0)
				fprintf(stderr, "slot %d, %-2.2s\n", i, unpair(p[i].rq));
			else
				fprintf(stderr, "slot %d empty\n", i);
		else
			fprintf(stderr, "slot %d empty\n", i);
}


void blockinit(void)
{
	blist = (Blockp *) calloc(NBLIST, sizeof(Blockp));
	if (blist == NULL) {
		ERROR "not enough room for %d blocks", NBLIST WARN;
		done2(1);
	}
	nblist = NBLIST;
	blist[0].nextoff = blist[1].nextoff = -1;
	blist[0].bp = (Tchar *) calloc(BLK, sizeof(Tchar));
	blist[1].bp = (Tchar *) calloc(BLK, sizeof(Tchar));
		/* -1 prevents blist[0] from being used; temporary fix */
		/* for a design botch: offset==0 is overloaded. */
		/* blist[1] reserved for .rd indicator -- also unused. */
		/* but someone unwittingly looks at these, so allocate something */
	bfree = 2;
}


char *grow(char *ptr, int num, int size)	/* make array bigger */
{
	char *p, new;

	if (ptr == NULL)
		p = (char *) calloc(num, size);
	else
		p = (char *) realloc(ptr, num * size);
	return p;
}

void mnspace(void)
{
	nm = sizeof(contab)/sizeof(Contab) + MDELTA;
	freeslot = sizeof(contab)/sizeof(Contab) + 1;
	contabp = (Contab *) grow((char *) contabp, nm, sizeof(Contab));
	if (contabp == NULL) {
		ERROR "not enough memory for namespace of %d marcos", nm WARN;
		exit(1);
	}
	contabp = (Contab *) memcpy((char *) contabp, (char *)contab,
							sizeof(contab));
	if (contabp == NULL) {
		ERROR "Cannot reinitialize macro/request name list" WARN;
		exit(1);
	}

}

void caseig(void)
{
	int i;
	Offset oldoff = offset;

	offset = 0;
	i = copyb();
	offset = oldoff;
	if (i != '.')
		control(i, 1);
}


void casern(void)
{
	int i, j, k;

	lgf++;
	skip();
	if ((i = getrq()) == 0 || (oldmn = findmn(i)) < 0)
		return;
	skip();
	clrmn(findmn(j = getrq()));
	if (j) {
		munhash(&contabp[oldmn]);
		contabp[oldmn].rq = j;
		maddhash(&contabp[oldmn]);
		if (dip != d )
			for (k = dilev; k; k--)
				if (d[k].curd == i)
					d[k].curd = j;
	}
}

void maddhash(Contab *rp)
{
	Contab **hp;

	if (rp->rq == 0)
		return;
	hp = &mhash[MHASH(rp->rq)];
	rp->link = *hp;
	*hp = rp;
}

void munhash(Contab *mp)
{	
	Contab *p;
	Contab **lp;

	if (mp->rq == 0)
		return;
	lp = &mhash[MHASH(mp->rq)];
	p = *lp;
	while (p) {
		if (p == mp) {
			*lp = p->link;
			p->link = 0;
			return;
		}
		lp = &p->link;
		p = p->link;
	}
}

void mrehash(void)
{
	Contab *p;
	int i;

	for (i=0; i < MHASHSIZE; i++)
		mhash[i] = 0;
	for (p=contabp; p < &contabp[nm]; p++)
		p->link = 0;
	for (p=contabp; p < &contabp[nm]; p++) {
		if (p->rq == 0)
			continue;
		i = MHASH(p->rq);
		p->link = mhash[i];
		mhash[i] = p;
	}
}

void caserm(void)
{
	int j;
	int k = 0;

	lgf++;
g0:
	while (!skip() && (j = getrq()) != 0) {
		if (dip != d)
			for (k = dilev; k; k--)
				if (d[k].curd == j) {
					ERROR "cannot remove diversion %s during definition",
								unpair(j) WARN;
					goto g0;
				}
		clrmn(findmn(j));
	}
	lgf--;
}


void caseas(void)
{
	app++;
	caseds();
}


void caseds(void)
{
	ds++;
	casede();
}


void caseam(void)
{
	app++;
	casede();
}


void casede(void)
{
	int i, req;
	Offset savoff;

	req = '.';
	lgf++;
	skip();
	if ((i = getrq()) == 0)
		goto de1;
	if ((offset = finds(i)) == 0)
		goto de1;
	if (newmn)
		savslot = newmn;
	else
		savslot = findmn(i);
	savname = i;
	if (ds)
		copys();
	else
		req = copyb();
	clrmn(oldmn);
	if (newmn) {
		if (contabp[newmn].rq)
			munhash(&contabp[newmn]);
		contabp[newmn].rq = i;
		maddhash(&contabp[newmn]);

	}
	if (apptr) {
		savoff = offset;
		offset = apptr;
		wbf((Tchar) IMP);
		offset = savoff;
	}
	offset = dip->op;
	if (req != '.')
		control(req, 1);
de1:
	ds = app = 0;
}


int findmn(int i)
{
	Contab *p;

	for (p = mhash[MHASH(i)]; p; p = p->link)
		if (i == p->rq)
			return(p - contabp);
	return(-1);
}


void clrmn(int i)
{
	if (i >= 0) {
		if (contabp[i].mx)
			ffree(contabp[i].mx);
		munhash(&contabp[i]);
		contabp[i].rq = 0;
		contabp[i].mx = 0;
		contabp[i].emx = 0;
		contabp[i].f = 0;
		if (contabp[i].divsiz != NULL) {
			free(contabp[i].divsiz);
			contabp[i].divsiz = NULL;
		}
		if (freeslot > i)
			freeslot = i;
	}
}

void growcontab(void)
{
	nm += MDELTA;
	contabp = (Contab *) grow((char *) contabp , nm, sizeof(Contab));
	if (contabp == NULL) {
		ERROR "Too many (%d) string/macro names", nm WARN;
		done2(02);
	} else {
		memset((char *)(contabp) + (nm - MDELTA) * sizeof(Contab),
						0, MDELTA * sizeof(Contab));
		mrehash();
	}
}


Offset finds(int mn)
{
	int i;
	Tchar j = IMP;
	Offset savip;

	oldmn = findmn(mn);
	newmn = 0;
	apptr = 0;
	if (app && oldmn >= 0 && contabp[oldmn].mx) {
		savip = ip;
		ip = contabp[oldmn].emx;
		oldmn = -1;
		apptr = ip;
		if (!diflg)
			ip = incoff(ip);
		nextb = ip;
		ip = savip;
	} else {
		for (i = freeslot; i < nm; i++) {
			if (contabp[i].rq == 0)
				break;
		}
		if (i == nm) 
			growcontab();
		freeslot = i + 1;
		if ((nextb = alloc()) == -1) {
			app = 0;
			if (macerr++ > 1)
				done2(02);
			if (nextb == 0)
				ERROR "Not enough space for string/macro names" WARN;
			edone(04);
			return(offset = 0);
		}
		contabp[i].mx = nextb;
		if (!diflg) {
			newmn = i;
			if (oldmn == -1)
				contabp[i].rq = -1;
		} else {
			contabp[i].rq = mn;
			maddhash(&contabp[i]);
		}
	}
	app = 0;
	return(offset = nextb);
}

int skip(void)
{
	Tchar i;

	while (cbits(i = getch()) == ' ' || ismot(i))
		;
	ch = i;
	return(nlflg);
}


int copyb(void)
{
	int i, j, state;
	Tchar ii;
	int req, k;
	Offset savoff;
	Uchar *p;

	if (skip() || !(j = getrq()))
		j = '.';
	req = j;
	p = unpair(j);
	/* was: k = j >> BYTE; j &= BYTEMASK; */
	j = p[0];
	k = p[1];
	copyf++;
	flushi();
	nlflg = 0;
	state = 1;

/* state 0	eat up
 * state 1	look for .
 * state 2	look for first char of end macro
 * state 3	look for second char of end macro
 */

	while (1) {
		i = cbits(ii = getch());
		if (state == 3) {
			if (i == k)
				break;
			if (!k) {
				ch = ii;
				i = getach();
				ch = ii;
				if (!i)
					break;
			}
			state = 0;
			goto c0;
		}
		if (i == '\n') {
			state = 1;
			nlflg = 0;
			goto c0;
		}
		if (state == 1 && i == '.') {
			state++;
			savoff = offset;
			goto c0;
		}
		if (state == 2 && i == j) {
			state++;
			goto c0;
		}
		state = 0;
c0:
		if (offset)
			wbf(ii);
	}
	if (offset) {
		offset = savoff;
		wbf((Tchar)0);
	}
	copyf--;
	return(req);
}


void copys(void)
{
	Tchar i;

	copyf++;
	if (skip())
		goto c0;
	if (cbits(i = getch()) != '"')
		wbf(i);
	while (cbits(i = getch()) != '\n')
		wbf(i);
c0:
	wbf((Tchar)0);
	copyf--;
}


Offset alloc(void)	/* return free Offset in nextb */
{
	int i, j;

	for (i = bfree; i < nblist; i++)
		if (blist[i].nextoff == 0)
			break;
	if (i == nblist) {
		blist = (Blockp *) realloc((char *) blist, 2 * nblist * sizeof(Blockp));
		if (blist == NULL) {
			ERROR "can't grow blist for string/macro defns" WARN;
			done2(2);
		}
		nblist *= 2;
		for (j = i; j < nblist; j++) {
			blist[j].nextoff = 0;
			blist[j].bp = 0;
		}
	}
	blist[i].nextoff = -1;	/* this block is the end */
	bfree = i + 1;
	if (blist[i].bp == 0)
		blist[i].bp = (Tchar *) calloc(BLK, sizeof(Tchar));
	if (blist[i].bp == NULL) {
		ERROR "can't allocate memory for string/macro definitions" WARN;
		done2(2);
	}
	nextb = (Offset) i * BLK;
	return nextb;
}


void ffree(Offset i)	/* free list of blocks starting at blist(o) */
{			/* (doesn't actually free the blocks, just the pointers) */
	int j;

	for ( ; blist[j = bindex(i)].nextoff != -1; ) {
		if (bfree > j)
			bfree = j;
		i = blist[j].nextoff;
		blist[j].nextoff = 0;
	}
	blist[j].nextoff = 0;
}


void wbf(Tchar i)	/* store i into offset, get ready for next one */
{
	int j, off;

	if (!offset)
		return;
	j = bindex(offset);
	if (i == 0)
		contabp[savslot].emx = offset;
	off = boffset(offset);
	blist[j].bp[off++] = i;
	offset++;
	if (pastend(offset)) {	/* off the end of this block */
		if (blist[j].nextoff == -1) {
			if ((nextb = alloc()) == -1) {
				ERROR "Out of temp file space" WARN;
				done2(01);
			}
			blist[j].nextoff = nextb;
		}
		offset = blist[j].nextoff;
	}
}


Tchar rbf(void)	/* return next char from blist[] block */
{
	Tchar i, j;

	if (ip == RD_OFFSET) {		/* for rdtty */
		if (j = rdtty())
			return(j);
		else
			return(popi());
	}
	
	i = rbf0(ip);
	if (i == 0) {
		if (!app)
			i = popi();
		return(i);
	}
	ip = incoff(ip);
	return(i);
}


Offset xxxincoff(Offset p)		/* get next blist[] block */
{
	p++;
	if (pastend(p)) {		/* off the end of this block */
		if ((p = blist[bindex(p-1)].nextoff) == -1) {	/* and nothing was allocated after it */
			ERROR "Bad storage allocation" WARN;
			done2(-5);
		}
	}
	return(p);
}


Tchar popi(void)
{
	Stack *p;

	if (frame == stk)
		return(0);
	if (strflg)
		strflg--;
	p = nxf = frame;
	p->nargs = 0;
	frame = p->pframe;
	ip = p->pip;
	pendt = p->ppendt;
	lastpbp = p->lastpbp;
	return(p->pch);
}

/*
 *	test that the end of the allocation is above a certain location
 *	in memory
 */
#define SPACETEST(base, size) \
	if ((char*)base + size >= (char*)stk+STACKSIZE) \
		ERROR "Stacksize overflow in n3" WARN

Offset pushi(Offset newip, int  mname)
{
	Stack *p;

	SPACETEST(nxf, sizeof(Stack));
	p = nxf;
	p->pframe = frame;
	p->pip = ip;
	p->ppendt = pendt;
	p->pch = ch;
	p->lastpbp = lastpbp;
	p->mname = mname;
	lastpbp = pbp;
	pendt = ch = 0;
	frame = nxf;
	if (nxf->nargs == 0) 
		nxf += 1;
	else 
		nxf = (Stack *)argtop;
	return(ip = newip);
}


void *setbrk(int x)
{
	char *i;

	if ((i = (char *) calloc(x, 1)) == 0) {
		ERROR "Core limit reached" WARN;
		edone(0100);
	}
	return(i);
}


int getsn(void)
{
	int i;

	if ((i = getach()) == 0)
		return(0);
	if (i == '(')
		return(getrq());
	else 
		return(i);
}


Offset setstr(void)
{
	int i, j;

	lgf++;
	if ((i = getsn()) == 0 || (j = findmn(i)) == -1 || !contabp[j].mx) {
		lgf--;
		return(0);
	} else {
		SPACETEST(nxf, sizeof(Stack));
		nxf->nargs = 0;
		strflg++;
		lgf--;
		return pushi(contabp[j].mx, i);
	}
}



void collect(void)
{
	int j;
	Tchar i, *strp, *lim, **argpp, **argppend;
	int quote;
	Stack *savnxf;

	copyf++;
	nxf->nargs = 0;
	savnxf = nxf;
	if (skip())
		goto rtn;

	{
		char *memp;
		memp = (char *)savnxf;
		/*
		 *	1 s structure for the macro descriptor
		 *	APERMAC Tchar *'s for pointers into the strings
		 *	space for the Tchar's themselves
		 */
		memp += sizeof(Stack);
		/*
		 *	CPERMAC = the total # of characters for ALL arguments
		 */
#define	CPERMAC	200
#define	APERMAC	9
		memp += APERMAC * sizeof(Tchar *);
		memp += CPERMAC * sizeof(Tchar);
		nxf = (Stack *)memp;
	}
	lim = (Tchar *)nxf;
	argpp = (Tchar **)(savnxf + 1);
	argppend = &argpp[APERMAC];
	SPACETEST(argppend, sizeof(Tchar *));
	strp = (Tchar *)argppend;
	/*
	 *	Zero out all the string pointers before filling them in.
	 */
	for (j = 0; j < APERMAC; j++)
		argpp[j] = 0;
	/* ERROR "savnxf=0x%x,nxf=0x%x,argpp=0x%x,strp=argppend=0x%x, lim=0x%x",
	 * 	savnxf, nxf, argpp, strp, lim WARN;
	 */
	strflg = 0;
	while (argpp != argppend && !skip()) {
		*argpp++ = strp;
		quote = 0;
		if (cbits(i = getch()) == '"')
			quote++;
		else 
			ch = i;
		while (1) {
			i = getch();
/* fprintf(stderr, "collect %c %d\n", cbits(i), cbits(i)); */
			if (nlflg || (!quote && argpp != argppend && cbits(i) == ' '))
				break;	/* collects rest into $9 */
			if (   quote
			    && cbits(i) == '"'
			    && cbits(i = getch()) != '"') {
				ch = i;
				break;
			}
			*strp++ = i;
			if (strflg && strp >= lim) {
				/* ERROR "strp=0x%x, lim = 0x%x", strp, lim WARN; */
				ERROR "Macro argument too long" WARN;
				copyf--;
				edone(004);
			}
			SPACETEST(strp, 3 * sizeof(Tchar));
		}
		*strp++ = 0;
	}
	nxf = savnxf;
	nxf->nargs = argpp - (Tchar **)(savnxf + 1);
	argtop = strp;
rtn:
	copyf--;
}


void seta(void)
{
	int i;

	i = cbits(getch()) - '0';
	if (i > 0 && i <= APERMAC && i <= frame->nargs)
		pushback(*(((Tchar **)(frame + 1)) + i - 1));
}


void caseda(void)
{
	app++;
	casedi();
}

void casegd(void)
{
	int i, j;

	skip();
	if ((i = getrq()) == 0)
		return;
	if ((j = findmn(i)) >= 0) {
		if (contabp[j].divsiz != NULL) {
			numtabp[DN].val = contabp[j].divsiz->dix;
			numtabp[DL].val = contabp[j].divsiz->diy;
		}
	}
}

#define FINDDIV(o) if ((o =  findmn(dip->curd)) < 0) \
			ERROR "lost diversion %s", unpair(dip->curd) WARN

void casedi(void)
{
	int i, j, *k;

	lgf++;
	if (skip() || (i = getrq()) == 0) {
		if (dip != d) {
			FINDDIV(savslot);
			wbf((Tchar)0);
		}
		if (dilev > 0) {
			numtabp[DN].val = dip->dnl;
			numtabp[DL].val = dip->maxl;
			FINDDIV(j);
			if ((contabp[j].divsiz = (Divsiz *) malloc(sizeof(Divsiz))) == NULL) {
				ERROR "Cannot alloc diversion size" WARN;
				done2(1);
			} else {
				contabp[j].divsiz->dix = numtabp[DN].val;
				contabp[j].divsiz->diy = numtabp[DL].val;
			}
			dip = &d[--dilev];
			offset = dip->op;
		}
		goto rtn;
	}
	if (++dilev == NDI) {
		--dilev;
		ERROR "Diversions nested too deep" WARN;
		edone(02);
	}
	if (dip != d) {
		FINDDIV(j);
		savslot = j;
		wbf((Tchar)0);
	}
	diflg++;
	dip = &d[dilev];
	dip->op = finds(i);
	dip->curd = i;
	clrmn(oldmn);
	k = (int *) & dip->dnl;
	for (j = 0; j < 10; j++)
		k[j] = 0;	/*not op and curd*/
rtn:
	app = 0;
	diflg = 0;
}


void casedt(void)
{
	lgf++;
	dip->dimac = dip->ditrap = dip->ditf = 0;
	skip();
	dip->ditrap = vnumb((int *)0);
	if (nonumb)
		return;
	skip();
	dip->dimac = getrq();
}

#define LNSIZE 4000
void casetl(void)
{
	int j;
	int w[3];
	Tchar buf[LNSIZE];
	Tchar *tp;
	Tchar i, delim;

 	/*
 	 * bug fix
 	 *
 	 * if .tl is the first thing in the file, the p1
 	 * doesn't come out, also the pagenumber will be 0
 	 *
 	 * tends too confuse the device filter (and the user as well)
 	 */
 	if (dip == d && numtabp[NL].val == -1)
 		newline(1);
	dip->nls = 0;
	skip();
	if (ismot(delim = getch())) {
		ch = delim;
		delim = '\'';
	} else 
		delim = cbits(delim);
	tp = buf;
	numtabp[HP].val = 0;
	w[0] = w[1] = w[2] = 0;
	j = 0;
	while (cbits(i = getch()) != '\n') {
		if (cbits(i) == cbits(delim)) {
			if (j < 3)
				w[j] = numtabp[HP].val;
			numtabp[HP].val = 0;
			if (w[j] != 0)
				*tp++ = WORDSP;
			j++;
			*tp++ = 0;
		} else {
			if (cbits(i) == pagech) {
				setn1(numtabp[PN].val, numtabp[findr('%')].fmt,
				      i&SFMASK);
				continue;
			}
			numtabp[HP].val += width(i);
			if (tp < &buf[LNSIZE-10]) {
				if (cbits(i) == ' ' && *tp != WORDSP)
					*tp++ = WORDSP;
				*tp++ = i;
			} else {
				ERROR "Overflow in casetl" WARN;
			}
		}
	}
	if (j<3)
		w[j] = numtabp[HP].val;
	*tp++ = 0;
	*tp++ = 0;
	*tp = 0;
	tp = buf;
	if (NROFF)
		horiz(po);
	while (i = *tp++)
		pchar(i);
	if (w[1] || w[2])
		horiz(j = quant((lt - w[1]) / 2 - w[0], HOR));
	while (i = *tp++)
		pchar(i);
	if (w[2]) {
		horiz(lt - w[0] - w[1] - w[2] - j);
		while (i = *tp++)
			pchar(i);
	}
	newline(0);
	if (dip != d) {
		if (dip->dnl > dip->hnl)
			dip->hnl = dip->dnl;
	} else {
		if (numtabp[NL].val > dip->hnl)
			dip->hnl = numtabp[NL].val;
	}
}


void casepc(void)
{
	pagech = chget(IMP);
}


void casepm(void)
{
	int i, k;
	int xx, cnt, tcnt, kk, tot;
	Offset j;

	kk = cnt = tcnt = 0;
	tot = !skip();
	stackdump();
	for (i = 0; i < nm; i++) {
		if ((xx = contabp[i].rq) == 0 || contabp[i].mx == 0)
			continue;
		tcnt++;
		j = contabp[i].mx;
		for (k = 1; (j = blist[bindex(j)].nextoff) != -1; )
			k++; 
		cnt++;
		kk += k;
		if (!tot)
			fprintf(stderr, "%-2.2s %d\n", unpair(xx), k);
	}
	fprintf(stderr, "pm: total %d, macros %d, space %d\n", tcnt, cnt, kk);
}

void stackdump(void)	/* dumps stack of macros in process */
{
	Stack *p;

	if (frame != stk) {
		fprintf(stderr, "stack: ");
		for (p = frame; p != stk; p = p->pframe)
			fprintf(stderr, "%s ", unpair(p->mname));
		fprintf(stderr, "\n");
	}
}
