/*
 * 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], "%ld", 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 "%s", 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);
}
