/*
 * troff4.c
 *
 * number registers, conversion, arithmetic
 */

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


int	regcnt = NNAMES;
int	falsef	= 0;	/* on if inside false branch of if */

#define	NHASHSIZE	128	/* must be 2**n */
#define	NHASH(i)	((i>>6)^i) & (NHASHSIZE-1)
Numtab	*nhash[NHASHSIZE];

Numtab *numtabp = NULL;
#define NDELTA 400
int ncnt = 0;

void setn(void)
{
	int i, j, f;
	Tchar ii;
	Uchar *p;
	char buf[NTM];		/* for \n(.S */

	f = nform = 0;
	if ((i = cbits(ii = getach())) == '+')
		f = 1;
	else if (i == '-')
		f = -1;
	else if (ii)	/* don't put it back if it's already back (thanks to jaap) */
		ch = ii;
	if (falsef)
		f = 0;
	if ((i = getsn()) == 0)
		return;
	p = unpair(i);
	if (p[0] == '.')
		switch (p[1]) {
		case 's':
			i = pts;
			break;
		case 'v':
			i = lss;
			break;
		case 'f':
			i = font;
			break;
		case 'p':
			i = pl;
			break;
		case 't':
			i = findt1();
			break;
		case 'o':
			i = po;
			break;
		case 'l':
			i = ll;
			break;
		case 'i':
			i = in;
			break;
		case '$':
			i = frame->nargs;
			break;
		case 'A':
			i = ascii;
			break;
		case 'c':
			i = numtabp[CD].val;
			break;
		case 'n':
			i = lastl;
			break;
		case 'a':
			i = ralss;
			break;
		case 'h':
			i = dip->hnl;
			break;
		case 'd':
			if (dip != d)
				i = dip->dnl;
			else
				i = numtabp[NL].val;
			break;
		case 'u':
			i = fi;
			break;
		case 'j':
			i = ad + 2 * admod;
			break;
		case 'w':
			i = widthp;
			break;
		case 'x':
			i = nel;
			break;
		case 'y':
			i = un;
			break;
		case 'T':
			i = dotT;
			break;	 /* -Tterm used in nroff */
		case 'V':
			i = VERT;
			break;
		case 'H':
			i = HOR;
			break;
		case 'k':
			i = ne;
			break;
		case 'P':
			i = print;
			break;
		case 'L':
			i = ls;
			break;
		case 'R':	/* maximal # of regs that can be addressed */
			i = 255*256 - regcnt; 
			break;
		case 'z':
			p = unpair(dip->curd);
			*pbp++ = p[1];	/* watch order */
			*pbp++ = p[0];
			return;
		case 'b':
			i = bdtab[font];
			break;
		case 'F':
			cpushback(cfname[ifi]);
			return;
 		case 'S':
 			buf[0] = j = 0;	
 			for( i = 0; tabtab[i] != 0 && i < NTAB; i++) {
 				if (i > 0)
 					buf[j++] = ' ';
 				sprintf(&buf[j], "%d", tabtab[i] & TABMASK);
 				j = strlen(buf);
 				if ( tabtab[i] & RTAB)
 					sprintf(&buf[j], "uR");
 				else if (tabtab[i] & CTAB)
 					sprintf(&buf[j], "uC");
 				else
 					sprintf(&buf[j], "uL");
 				j += 2;
 			}
 			cpushback(buf);
 			return;
		default:
			goto s0;
		}
	else {
s0:
		if ((j = findr(i)) == -1)
			i = 0;
		else {
			i = numtabp[j].val = numtabp[j].val + numtabp[j].inc * f;
			nform = numtabp[j].fmt;
		}
	}
	setn1(i, nform, (Tchar) 0);
}

Tchar	numbuf[25];
Tchar	*numbufp;

int wrc(Tchar i)
{
	if (numbufp >= &numbuf[24])
		return(0);
	*numbufp++ = i;
	return(1);
}



/* insert into input number i, in format form, with size-font bits bits */
void setn1(int i, int form, Tchar bits)
{
	numbufp = numbuf;
	nrbits = bits;
	nform = form;
	fnumb(i, wrc);
	*numbufp = 0;
	pushback(numbuf);
}

void prnumtab(Numtab *p)
{
	int i;
	for (i = 0; i < ncnt; i++)
		if (p)
			if (p[i].r != 0)
				fprintf(stderr, "slot %d, %s, val %d\n", i, unpair(p[i].r), p[i].val);
			else
				fprintf(stderr, "slot %d empty\n", i);
		else
			fprintf(stderr, "slot %d empty\n", i);
}

void nnspace(void)
{
	ncnt = sizeof(numtab)/sizeof(Numtab) + NDELTA;
	numtabp = (Numtab *) grow((char *)numtabp, ncnt, sizeof(Numtab));
	if (numtabp == NULL) {
		ERROR "not enough memory for registers (%d)", ncnt WARN;
		exit(1);
	}
	numtabp = (Numtab *) memcpy((char *)numtabp, (char *)numtab,
							sizeof(numtab));
	if (numtabp == NULL) {
		ERROR "Cannot initialize registers" WARN;
		exit(1);
	}
}

void grownumtab(void)
{
	ncnt += NDELTA;
	numtabp = (Numtab *) grow((char *) numtabp, ncnt, sizeof(Numtab));
	if (numtabp == NULL) {
		ERROR "Too many number registers (%d)", ncnt WARN;
		done2(04);
	} else {
		memset((char *)(numtabp) + (ncnt - NDELTA) * sizeof(Numtab),
						0, NDELTA * sizeof(Numtab));
		nrehash();
	}
}

void nrehash(void)
{
	Numtab *p;
	int i;

	for (i=0; i<NHASHSIZE; i++)
		nhash[i] = 0;
	for (p=numtabp; p < &numtabp[ncnt]; p++)
		p->link = 0;
	for (p=numtabp; p < &numtabp[ncnt]; p++) {
		if (p->r == 0)
			continue;
		i = NHASH(p->r);
		p->link = nhash[i];
		nhash[i] = p;
	}
}

void nunhash(Numtab *rp)
{
	Numtab *p;
	Numtab **lp;

	if (rp->r == 0)
		return;
	lp = &nhash[NHASH(rp->r)];
	p = *lp;
	while (p) {
		if (p == rp) {
			*lp = p->link;
			p->link = 0;
			return;
		}
		lp = &p->link;
		p = p->link;
	}
}

int findr(int i)
{
	Numtab *p;
	int h = NHASH(i);

	if (i == 0)
		return(-1);
a0:
	for (p = nhash[h]; p; p = p->link)
		if (i == p->r)
			return(p - numtabp);
	for (p = numtabp; p < &numtabp[ncnt]; p++) {
		if (p->r == 0) {
			p->r = i;
			p->link = nhash[h];
			nhash[h] = p;
			regcnt++;
			return(p - numtabp);
		}
	}
	grownumtab();
	goto a0;
}

int usedr(int i)	/* returns -1 if nr i has never been used */
{
	Numtab *p;

	if (i == 0)
		return(-1);
	for (p = nhash[NHASH(i)]; p; p = p->link)
		if (i == p->r)
			return(p - numtabp);
	return -1;
}


int fnumb(int i, int (*f)(Tchar))
{
	int j;

	j = 0;
	if (i < 0) {
		j = (*f)('-' | nrbits);
		i = -i;
	}
	switch (nform) {
	default:
	case '1':
	case 0:
		return decml(i, f) + j;
	case 'i':
	case 'I':
		return roman(i, f) + j;
	case 'a':
	case 'A':
		return abc(i, f) + j;
	}
}


int decml(int i, int (*f)(Tchar))
{
	int j, k;

	k = 0;
	nform--;
	if ((j = i / 10) || (nform > 0))
		k = decml(j, f);
	return(k + (*f)((i % 10 + '0') | nrbits));
}


int roman(int i, int (*f)(Tchar))
{

	if (!i)
		return((*f)('0' | nrbits));
	if (nform == 'i')
		return(roman0(i, f, "ixcmz", "vldw"));
	else
		return(roman0(i, f, "IXCMZ", "VLDW"));
}


int roman0(int i, int (*f)(Tchar), char *onesp, char *fivesp)
{
	int q, rem, k;

	if (!i)
		return(0);
	k = roman0(i / 10, f, onesp + 1, fivesp + 1);
	q = (i = i % 10) / 5;
	rem = i % 5;
	if (rem == 4) {
		k += (*f)(*onesp | nrbits);
		if (q)
			i = *(onesp + 1);
		else
			i = *fivesp;
		return(k += (*f)(i | nrbits));
	}
	if (q)
		k += (*f)(*fivesp | nrbits);
	while (--rem >= 0)
		k += (*f)(*onesp | nrbits);
	return(k);
}


int abc(int i, int (*f)(Tchar))
{
	if (!i)
		return((*f)('0' | nrbits));
	else
		return(abc0(i - 1, f));
}


int abc0(int i, int (*f)(Tchar))
{
	int j, k;

	k = 0;
	if (j = i / 26)
		k = abc0(j - 1, f);
	return(k + (*f)((i % 26 + nform) | nrbits));
}

long atoi0(void)
{
	int c, k, cnt;
	Tchar ii;
	long i, acc;

	acc = 0;
	nonumb = 0;
	cnt = -1;
a0:
	cnt++;
	ii = getch();
	c = cbits(ii);
	switch (c) {
	default:
		ch = ii;
		if (cnt)
			break;
	case '+':
		i = ckph();
		if (nonumb)
			break;
		acc += i;
		goto a0;
	case '-':
		i = ckph();
		if (nonumb)
			break;
		acc -= i;
		goto a0;
	case '*':
		i = ckph();
		if (nonumb)
			break;
		acc *= i;
		goto a0;
	case '/':
		i = ckph();
		if (nonumb)
			break;
		if (i == 0) {
			flusho();
			ERROR "divide by zero." WARN;
			acc = 0;
		} else
			acc /= i;
		goto a0;
	case '%':
		i = ckph();
		if (nonumb)
			break;
		acc %= i;
		goto a0;
	case '&':	/*and*/
		i = ckph();
		if (nonumb)
			break;
		if ((acc > 0) && (i > 0))
			acc = 1;
		else
			acc = 0;
		goto a0;
	case ':':	/*or*/
		i = ckph();
		if (nonumb)
			break;
		if ((acc > 0) || (i > 0))
			acc = 1;
		else
			acc = 0;
		goto a0;
	case '=':
		if (cbits(ii = getch()) != '=')
			ch = ii;
		i = ckph();
		if (nonumb) {
			acc = 0;
			break;
		}
		if (i == acc)
			acc = 1;
		else
			acc = 0;
		goto a0;
	case '>':
		k = 0;
		if (cbits(ii = getch()) == '=')
			k++;
		else
			ch = ii;
		i = ckph();
		if (nonumb) {
			acc = 0;
			break;
		}
		if (acc > (i - k))
			acc = 1;
		else
			acc = 0;
		goto a0;
	case '<':
		k = 0;
		if (cbits(ii = getch()) == '=')
			k++;
		else
			ch = ii;
		i = ckph();
		if (nonumb) {
			acc = 0;
			break;
		}
		if (acc < (i + k))
			acc = 1;
		else
			acc = 0;
		goto a0;
	case ')':
		break;
	case '(':
		acc = atoi0();
		goto a0;
	}
	return(acc);
}


long ckph(void)
{
	Tchar i;
	long j;

	if (cbits(i = getch()) == '(')
		j = atoi0();
	else {
		j = atoi1(i);
	}
	return(j);
}


/*
 * print error about illegal numeric argument;
 */
void prnumerr(void)
{
	char err_buf[40];
	static char warn[] = "Numeric argument expected";
	int savcd = numtabp[CD].val;

	if (numerr.type == RQERR)
		sprintf(err_buf, "%c%s: %s", nb ? cbits(c2) : cbits(cc),
						unpair(numerr.req), warn);
	else
		sprintf(err_buf, "\\%c'%s': %s", numerr.esc, &numerr.escarg,
									warn);
	if (frame != stk)	/* uncertainty correction */
		numtabp[CD].val--;
	ERROR err_buf WARN;
	numtabp[CD].val = savcd;
}


long atoi1(Tchar ii)
{
	int i, j, digits;
	double acc;	/* this is the only double in troff! */
	int neg, abs, field, decpnt;
	extern int ifnum;


	neg = abs = field = decpnt = digits = 0;
	acc = 0;
	for (;;) {
		i = cbits(ii);
		switch (i) {
		default:
			break;
		case '+':
			ii = getch();
			continue;
		case '-':
			neg = 1;
			ii = getch();
			continue;
		case '|':
			abs = 1 + neg;
			neg = 0;
			ii = getch();
			continue;
		}
		break;
	}
a1:
	while (i >= '0' && i <= '9') {
		field++;
		digits++;
		acc = 10 * acc + i - '0';
		ii = getch();
		i = cbits(ii);
	}
	if (i == '.' && !decpnt++) {
		field++;
		digits = 0;
		ii = getch();
		i = cbits(ii);
		goto a1;
	}
	if (!field) {
		ch = ii;
		goto a2;
	}
	switch (i) {
	case 'u':
		i = j = 1;	/* should this be related to HOR?? */
		break;
	case 'v':	/*VSs - vert spacing*/
		j = lss;
		i = 1;
		break;
	case 'm':	/*Ems*/
		j = EM;
		i = 1;
		break;
	case 'n':	/*Ens*/
		j = EM;
		if (TROFF)
			i = 2;
		else
			i = 1;	/*Same as Ems in NROFF*/
		break;
	case 'p':	/*Points*/
		j = INCH;
		i = 72;
		break;
	case 'i':	/*Inches*/
		j = INCH;
		i = 1;
		break;
	case 'c':	/*Centimeters*/
		/* if INCH is too big, this will overflow */
		j = INCH * 50;
		i = 127;
		break;
	case 'P':	/*Picas*/
		j = INCH;
		i = 6;
		break;
	default:
		j = dfact;
		ch = ii;
		i = dfactd;
	}
	if (neg)
		acc = -acc;
	if (!noscale) {
		acc = (acc * j) / i;
	}
	if (field != digits && digits > 0)
		while (digits--)
			acc /= 10;
	if (abs) {
		if (dip != d)
			j = dip->dnl;
		else
			j = numtabp[NL].val;
		if (!vflag) {
			j = numtabp[HP].val;
		}
		if (abs == 2)
			j = -j;
		acc -= j;
	}
a2:
	nonumb = (!field || field == decpnt);
	if (nonumb && (trace & TRNARGS) && !ismot(ii) && !nlflg && !ifnum) {
		if (cbits(ii) != RIGHT ) /* Too painful to do right */
			prnumerr();
	}
	return(acc);
}


void caserr(void)
{
	int i, j;
	Numtab *p;

	lgf++;
	while (!skip() && (i = getrq()) ) {
		j = usedr(i);
		if (j < 0)
			continue;
		p = &numtabp[j];
		nunhash(p);
		p->r = p->val = p->inc = p->fmt = 0;
		regcnt--;
	}
}

/*
 * .nr request; if tracing, don't check optional
 * 2nd argument because tbl generates .in 1.5n
 */
void casenr(void)
{
	int i, j;
	int savtr = trace;

	lgf++;
	skip();
	if ((i = findr(getrq())) == -1)
		goto rtn;
	skip();
	j = inumb(&numtabp[i].val);
	if (nonumb)
		goto rtn;
	numtabp[i].val = j;
	skip();
	trace = 0;
	j = atoi0();		/* BUG??? */
	trace = savtr;
	if (nonumb)
		goto rtn;
	numtabp[i].inc = j;
rtn:
	return;
}

void caseaf(void)
{
	int i, k;
	Tchar j;

	lgf++;
	if (skip() || !(i = getrq()) || skip())
		return;
	k = 0;
	j = getch();
	if (!isalpha(cbits(j))) {
		ch = j;
		while ((j = cbits(getch())) >= '0' &&  j <= '9')
			k++;
	}
	if (!k)
		k = j;
	numtabp[findr(i)].fmt = k;	/* was k & BYTEMASK */
}

void setaf(void)	/* return format of number register */
{
	int i, j;

	i = usedr(getsn());
	if (i == -1)
		return;
	if (numtabp[i].fmt > 20)	/* it was probably a, A, i or I */
		*pbp++ = numtabp[i].fmt;
	else
		for (j = (numtabp[i].fmt ? numtabp[i].fmt : 1); j; j--)
			*pbp++ = '0';
}


int vnumb(int *i)
{
	vflag++;
	dfact = lss;
	res = VERT;
	return(inumb(i));
}


int hnumb(int *i)
{
	dfact = EM;
	res = HOR;
	return(inumb(i));
}


int inumb(int *n)
{
	int i, j, f;
	Tchar ii;

	f = 0;
	if (n) {
		if ((j = cbits(ii = getch())) == '+')
			f = 1;
		else if (j == '-')
			f = -1;
		else
			ch = ii;
	}
	i = atoi0();
	if (n && f)
		i = *n + f * i;
	i = quant(i, res);
	vflag = 0;
	res = dfactd = dfact = 1;
	if (nonumb)
		i = 0;
	return(i);
}


int quant(int n, int m)
{
	int i, neg;

	neg = 0;
	if (n < 0) {
		neg++;
		n = -n;
	}
	/* better as i = ((n + m/2)/m)*m */
	i = n / m;
	if (n - m * i > m / 2)
		i += 1;
	i *= m;
	if (neg)
		i = -i;
	return(i);
}
