home *** CD-ROM | disk | FTP | other *** search
- #include "tdef.h"
- extern
- #include "d.h"
- extern
- #include "v.h"
- #ifdef NROFF
- extern
- #include "tw.h"
- #endif
- #include "s.h"
- /*
- troff4.c
-
- number registers, conversion, arithmetic
- */
-
- 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 = cwidth; 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': 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<NN;j++){
- if(i == r[j])break;
- }
- if(j != NN)return(j);
- for(j=0; j<NN; j++){
- if(r[j] == 0){
- r[j] = i;
- regcnt++;
- break;
- }
- }
- if(j==NN){
- if(!numerr)prstrfl("Too many number registers.\n");
- if(++numerr > 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;
- 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<NN; j++){ /*NNAMES predefined names*/
- if(i == r[j])break;
- }
- if(j!=NN){
- r[j]=vlist[j]=inc[j]=fmt[j]=0;
- regcnt--;
- }
- }
- }
- casenr(){
- register i, j;
-
- lgf++;
- skip();
- if((i = findr(getrq())) == -1)goto rtn;
- skip();
- j = inumb(&vlist[i]);
- if(nonumb)goto rtn;
- vlist[i] = j;
- skip();
- j = atoi();
- if(nonumb)goto rtn;
- inc[i] = j;
- rtn:
- return;
- }
- caseaf(){
- register i, j, k;
-
- lgf++;
- if(skip() || !(i = getrq()) || skip())return;
- k = 0;
- if(!alph(j=getch())){
- ch = j;
- while(((j = getch() & CMASK) >= '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);
- }
-