/*
 * 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;

	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;
	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;

	savoff = 0;
	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");
	}
}
