#ifndef lint static char sccsid[] = "@(#)n4.c 4.1 6/7/82"; #endif lint #include "tdef.h" extern #include "d.h" extern #include "v.h" #ifdef NROFF extern #include "tw.h" #endif #include "sdef.h" /* troff4.c number registers, conversion, arithmetic */ extern int inchar[LNSIZE], *pinchar; /* XXX */ extern struct s *frame; extern int ascii; extern int cbuf[NC]; extern int *cp; extern int r[NN]; extern int *vlist; extern int inc[NN]; extern int fmt[NN]; extern int ch; extern int lgf; extern int pl; extern int lastl; extern int ralss; extern int totout; extern int nrbits; extern int nonumb; extern int vflag; extern int noscale; extern int dfact; extern int dfactd; extern int po; extern int nform; extern int ll; extern int in; extern int font; extern int bdtab[]; extern int lss; extern int pts; extern int fi; extern int res; extern int cwidth; extern int dotT; extern int ev; extern int ne; extern int ad, admod; extern int print; extern int ls; extern int nel, un; extern int xxx; int regcnt = NNAMES; setn() { register i,j; int f; f = nform = 0; if((i=getch() & CMASK) == '+')f = 1; else if(i == '-')f = -1; else ch = i; if((i=getsn()) == 0)return; if((i & 0177) == '.')switch(i>>BYTE){ case 's': i = pts & 077; break; case 'v': i = lss; break; case 'f': i = font + 1; 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 = v.cd; 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 = v.nl; break; case 'u': i = fi; break; case 'j': i = ad + 2*admod; break; case 'w': i = width(*(pinchar-1)); break; /* XXX */ 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': i = NN - regcnt; break; case 'z': i = dip->curd; cbuf[0] = i & BMASK; cbuf[1] = (i >> BYTE) & BMASK; cbuf[2] = 0; cp = cbuf; return; #ifndef NROFF case 'b': i = bdtab[font]; break; #endif default: goto s0; } else{ s0: if((j=findr(i)) == -1)i = 0; else{ i = (vlist[j] = (vlist[j] + inc[j]*f)); nform = fmt[j]; } } setn1(i); cp = cbuf; } setn1(i) int i; { extern int wrc(); cp = cbuf; nrbits = 0; fnumb(i,wrc); *cp = 0; cp = cbuf; } findr(i) int i; { register j; static int numerr; if(i == 0)return(-1); for(j=0;j 1)done2(04); else edone(04); } return(j); } fnumb(i,f) int i, (*f)(); { register 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); } } decml(i,f) int i, (*f)(); { register j,k; k = 0; nform--; if((j=i/10) || (nform > 0))k = decml(j,f); return(k + (*f)((i%10 + '0') | nrbits)); } roman(i,f) int i, (*f)(); { if(!i)return((*f)('0' | nrbits)); if(nform == 'i')return(roman0(i,f,"ixcmz","vldw")); else return(roman0(i,f,"IXCMZ","VLDW")); } roman0(i,f,onesp,fivesp) int i, (*f)(); char *onesp, *fivesp; { register q, rem, k; k = 0; 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); } abc(i,f) int i, (*f)(); { if(!i)return((*f)('0' | nrbits)); else return(abc0(i-1,f)); } abc0(i,f) int i, (*f)(); { register j, k; k = 0; if(j=i/26)k = abc0(j-1,f); return(k + (*f)((i%26 + nform) | nrbits)); } wrc(i) int i; { if(cp >= &cbuf[NC])return(0); *cp++ = i; return(1); } atoi(){ extern long atoi0(); return((int)atoi0()); } long atoi0() { register ii, k, cnt; long i, acc; extern long ckph(); i = 0; acc = 0; nonumb = 0; cnt = -1; a0: cnt++; switch((ii=getch()) & CMASK){ 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){ prstrfl("Divide by zero.\n"); 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(((ii=getch()) & CMASK) != '=')ch = ii; i = ckph(); if(nonumb){acc = 0; break;} if(i == acc)acc = 1; else acc = 0; goto a0; case '>': k = 0; if(((ii=getch()) & CMASK) == '=')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(((ii=getch()) & CMASK) == '=')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(){ register i; long j; extern long atoi0(); extern long atoi1(); if(((i = getch()) & CMASK) == '(')j = atoi0(); else{ ch = i; j = atoi1(); } return(j); } long atoi1() { register i, j, digits; long acc; int neg, abs, field; neg = abs = field = digits = 0; acc = 0; a0: switch((i = getch()) & CMASK){ default: ch = i; break; case '+': goto a0; case '-': neg = 1; goto a0; case '|': abs = 1 + neg; neg = 0; goto a0; } a1: while(((j = ((i = getch()) & CMASK) - '0') >= 0) && (j <= 9)){ field++; digits++; acc = 10*acc + j; } if((i & CMASK) == '.'){ field++; digits = 0; goto a1; } ch = i; if(!field)goto a2; switch((i = getch()) & CMASK){ case 'u': i = j = 1; break; case 'v': /*VSs - vert spacing*/ j = lss; i = 1; break; case 'm': /*Ems*/ j = EM; i = 1; break; case 'n': /*Ens*/ j = EM; #ifndef NROFF i = 2; #endif #ifdef NROFF i = 1; /*Same as Ems in NROFF*/ #endif break; case 'p': /*Points*/ j = INCH; i = 72; break; case 'i': /*Inches*/ j = INCH; i = 1; break; case 'c': /*Centimeters*/ j = INCH*50; i = 127; break; case 'P': /*Picas*/ j = INCH; i = 6; break; default: j = dfact; ch = i; 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 = v.nl; if(!vflag)j = v.hp = sumhp(); /* XXX */ if(abs == 2)j = -j; acc -= j; } a2: nonumb = !field; return(acc); } caserr(){ register i,j; lgf++; while(!skip() && (i=getrq()) ){ for(j=NNAMES; j= '0') && (j <= '9'))k++; } if(!k)k=j; fmt[findr(i)] = k & BMASK; } vnumb(i) int *i; { vflag++; dfact = lss; res = VERT; return(inumb(i)); } hnumb(i) int *i; { dfact = EM; res = HOR; return(inumb(i)); } inumb(n) int *n; { register i, j, f; f = 0; if(n){ if((j = (i = getch()) & CMASK) == '+')f = 1; else if(j == '-')f = -1; else ch = i; } i = atoi(); if(n && f)i = *n + f*i; i = quant(i,res); vflag = 0; res = dfactd = dfact = 1; if(nonumb)i = 0; return(i); } quant(n,m) int n, m; { register i, neg; neg = 0; if(n<0){ neg++; n = -n; } i = n/m; if((n - m*i) > (m/2))i += 1; i *= m; if(neg)i = -i; return(i); }