1*7068Srrh #ifndef lint 2*7068Srrh static char sccsid[] = "@(#)n4.c 4.1 06/07/82"; 3*7068Srrh #endif lint 4*7068Srrh 5*7068Srrh #include "tdef.h" 6*7068Srrh extern 7*7068Srrh #include "d.h" 8*7068Srrh extern 9*7068Srrh #include "v.h" 10*7068Srrh #ifdef NROFF 11*7068Srrh extern 12*7068Srrh #include "tw.h" 13*7068Srrh #endif 14*7068Srrh #include "sdef.h" 15*7068Srrh /* 16*7068Srrh troff4.c 17*7068Srrh 18*7068Srrh number registers, conversion, arithmetic 19*7068Srrh */ 20*7068Srrh 21*7068Srrh extern int inchar[LNSIZE], *pinchar; /* XXX */ 22*7068Srrh extern struct s *frame; 23*7068Srrh 24*7068Srrh extern int ascii; 25*7068Srrh extern int cbuf[NC]; 26*7068Srrh extern int *cp; 27*7068Srrh extern int r[NN]; 28*7068Srrh extern int *vlist; 29*7068Srrh extern int inc[NN]; 30*7068Srrh extern int fmt[NN]; 31*7068Srrh extern int ch; 32*7068Srrh extern int lgf; 33*7068Srrh extern int pl; 34*7068Srrh extern int lastl; 35*7068Srrh extern int ralss; 36*7068Srrh extern int totout; 37*7068Srrh extern int nrbits; 38*7068Srrh extern int nonumb; 39*7068Srrh extern int vflag; 40*7068Srrh extern int noscale; 41*7068Srrh extern int dfact; 42*7068Srrh extern int dfactd; 43*7068Srrh extern int po; 44*7068Srrh extern int nform; 45*7068Srrh extern int ll; 46*7068Srrh extern int in; 47*7068Srrh extern int font; 48*7068Srrh extern int bdtab[]; 49*7068Srrh extern int lss; 50*7068Srrh extern int pts; 51*7068Srrh extern int fi; 52*7068Srrh extern int res; 53*7068Srrh extern int cwidth; 54*7068Srrh extern int dotT; 55*7068Srrh extern int ev; 56*7068Srrh extern int ne; 57*7068Srrh extern int ad, admod; 58*7068Srrh extern int print; 59*7068Srrh extern int ls; 60*7068Srrh extern int nel, un; 61*7068Srrh extern int xxx; 62*7068Srrh int regcnt = NNAMES; 63*7068Srrh 64*7068Srrh setn() 65*7068Srrh { 66*7068Srrh register i,j; 67*7068Srrh int f; 68*7068Srrh 69*7068Srrh f = nform = 0; 70*7068Srrh if((i=getch() & CMASK) == '+')f = 1; 71*7068Srrh else if(i == '-')f = -1; 72*7068Srrh else ch = i; 73*7068Srrh if((i=getsn()) == 0)return; 74*7068Srrh if((i & 0177) == '.')switch(i>>BYTE){ 75*7068Srrh case 's': i = pts & 077; break; 76*7068Srrh case 'v': i = lss; break; 77*7068Srrh case 'f': i = font + 1; break; 78*7068Srrh case 'p': i = pl; break; 79*7068Srrh case 't': i = findt1(); break; 80*7068Srrh case 'o': i = po; break; 81*7068Srrh case 'l': i = ll; break; 82*7068Srrh case 'i': i = in; break; 83*7068Srrh case '$': i = frame->nargs; break; 84*7068Srrh case 'A': i = ascii; break; 85*7068Srrh case 'c': i = v.cd; break; 86*7068Srrh case 'n': i = lastl; break; 87*7068Srrh case 'a': i = ralss; break; 88*7068Srrh case 'h': i = dip->hnl; break; 89*7068Srrh case 'd': 90*7068Srrh if(dip != d)i = dip->dnl; else i = v.nl; 91*7068Srrh break; 92*7068Srrh case 'u': i = fi; break; 93*7068Srrh case 'j': i = ad + 2*admod; break; 94*7068Srrh case 'w': i = width(*(pinchar-1)); break; /* XXX */ 95*7068Srrh case 'x': i = nel; break; 96*7068Srrh case 'y': i = un; break; 97*7068Srrh case 'T': i = dotT; break; /*-Tterm used in nroff*/ 98*7068Srrh case 'V': i = VERT; break; 99*7068Srrh case 'H': i = HOR; break; 100*7068Srrh case 'k': i = ne; break; 101*7068Srrh case 'P': i = print; break; 102*7068Srrh case 'L': i = ls; break; 103*7068Srrh case 'R': i = NN - regcnt; break; 104*7068Srrh case 'z': i = dip->curd; 105*7068Srrh cbuf[0] = i & BMASK; 106*7068Srrh cbuf[1] = (i >> BYTE) & BMASK; 107*7068Srrh cbuf[2] = 0; 108*7068Srrh cp = cbuf; 109*7068Srrh return; 110*7068Srrh #ifndef NROFF 111*7068Srrh case 'b': i = bdtab[font]; break; 112*7068Srrh #endif 113*7068Srrh 114*7068Srrh default: 115*7068Srrh goto s0; 116*7068Srrh } 117*7068Srrh else{ 118*7068Srrh s0: 119*7068Srrh if((j=findr(i)) == -1)i = 0; 120*7068Srrh else{ 121*7068Srrh i = (vlist[j] = (vlist[j] + inc[j]*f)); 122*7068Srrh nform = fmt[j]; 123*7068Srrh } 124*7068Srrh } 125*7068Srrh setn1(i); 126*7068Srrh cp = cbuf; 127*7068Srrh } 128*7068Srrh setn1(i) 129*7068Srrh int i; 130*7068Srrh { 131*7068Srrh extern int wrc(); 132*7068Srrh 133*7068Srrh cp = cbuf; 134*7068Srrh nrbits = 0; 135*7068Srrh fnumb(i,wrc); 136*7068Srrh *cp = 0; 137*7068Srrh cp = cbuf; 138*7068Srrh } 139*7068Srrh findr(i) 140*7068Srrh int i; 141*7068Srrh { 142*7068Srrh register j; 143*7068Srrh static int numerr; 144*7068Srrh 145*7068Srrh if(i == 0)return(-1); 146*7068Srrh for(j=0;j<NN;j++){ 147*7068Srrh if(i == r[j])break; 148*7068Srrh } 149*7068Srrh if(j != NN)return(j); 150*7068Srrh for(j=0; j<NN; j++){ 151*7068Srrh if(r[j] == 0){ 152*7068Srrh r[j] = i; 153*7068Srrh regcnt++; 154*7068Srrh break; 155*7068Srrh } 156*7068Srrh } 157*7068Srrh if(j==NN){ 158*7068Srrh if(!numerr)prstrfl("Too many number registers.\n"); 159*7068Srrh if(++numerr > 1)done2(04); else edone(04); 160*7068Srrh } 161*7068Srrh return(j); 162*7068Srrh } 163*7068Srrh fnumb(i,f) 164*7068Srrh int i, (*f)(); 165*7068Srrh { 166*7068Srrh register j; 167*7068Srrh 168*7068Srrh j = 0; 169*7068Srrh if(i < 0){ 170*7068Srrh j = (*f)('-' | nrbits); 171*7068Srrh i = -i; 172*7068Srrh } 173*7068Srrh switch(nform){ 174*7068Srrh default: 175*7068Srrh case '1': 176*7068Srrh case 0: return(decml(i,f) + j); 177*7068Srrh case 'i': 178*7068Srrh case 'I': return(roman(i,f) + j); 179*7068Srrh case 'a': 180*7068Srrh case 'A': return(abc(i,f) + j); 181*7068Srrh } 182*7068Srrh } 183*7068Srrh decml(i,f) 184*7068Srrh int i, (*f)(); 185*7068Srrh { 186*7068Srrh register j,k; 187*7068Srrh 188*7068Srrh k = 0; 189*7068Srrh nform--; 190*7068Srrh if((j=i/10) || (nform > 0))k = decml(j,f); 191*7068Srrh return(k + (*f)((i%10 + '0') | nrbits)); 192*7068Srrh } 193*7068Srrh roman(i,f) 194*7068Srrh int i, (*f)(); 195*7068Srrh { 196*7068Srrh 197*7068Srrh if(!i)return((*f)('0' | nrbits)); 198*7068Srrh if(nform == 'i')return(roman0(i,f,"ixcmz","vldw")); 199*7068Srrh else return(roman0(i,f,"IXCMZ","VLDW")); 200*7068Srrh } 201*7068Srrh roman0(i,f,onesp,fivesp) 202*7068Srrh int i, (*f)(); 203*7068Srrh char *onesp, *fivesp; 204*7068Srrh { 205*7068Srrh register q, rem, k; 206*7068Srrh 207*7068Srrh k = 0; 208*7068Srrh if(!i)return(0); 209*7068Srrh k = roman0(i/10,f,onesp+1,fivesp+1); 210*7068Srrh q = (i=i%10)/5; 211*7068Srrh rem = i%5; 212*7068Srrh if(rem == 4){ 213*7068Srrh k += (*f)(*onesp | nrbits); 214*7068Srrh if(q)i = *(onesp+1); 215*7068Srrh else i = *fivesp; 216*7068Srrh return(k += (*f)(i | nrbits)); 217*7068Srrh } 218*7068Srrh if(q)k += (*f)(*fivesp | nrbits); 219*7068Srrh while(--rem >= 0) 220*7068Srrh k += (*f)(*onesp | nrbits); 221*7068Srrh return(k); 222*7068Srrh } 223*7068Srrh abc(i,f) 224*7068Srrh int i, (*f)(); 225*7068Srrh { 226*7068Srrh if(!i)return((*f)('0' | nrbits)); 227*7068Srrh else return(abc0(i-1,f)); 228*7068Srrh } 229*7068Srrh abc0(i,f) 230*7068Srrh int i, (*f)(); 231*7068Srrh { 232*7068Srrh register j, k; 233*7068Srrh 234*7068Srrh k = 0; 235*7068Srrh if(j=i/26)k = abc0(j-1,f); 236*7068Srrh return(k + (*f)((i%26 + nform) | nrbits)); 237*7068Srrh } 238*7068Srrh wrc(i) 239*7068Srrh int i; 240*7068Srrh { 241*7068Srrh if(cp >= &cbuf[NC])return(0); 242*7068Srrh *cp++ = i; 243*7068Srrh return(1); 244*7068Srrh } 245*7068Srrh atoi(){ 246*7068Srrh extern long atoi0(); 247*7068Srrh 248*7068Srrh return((int)atoi0()); 249*7068Srrh } 250*7068Srrh long atoi0() 251*7068Srrh { 252*7068Srrh register ii, k, cnt; 253*7068Srrh long i, acc; 254*7068Srrh extern long ckph(); 255*7068Srrh 256*7068Srrh i = 0; acc = 0; 257*7068Srrh nonumb = 0; 258*7068Srrh cnt = -1; 259*7068Srrh a0: 260*7068Srrh cnt++; 261*7068Srrh switch((ii=getch()) & CMASK){ 262*7068Srrh default: 263*7068Srrh ch = ii; 264*7068Srrh if(cnt)break; 265*7068Srrh case '+': 266*7068Srrh i = ckph(); 267*7068Srrh if(nonumb)break; 268*7068Srrh acc += i; 269*7068Srrh goto a0; 270*7068Srrh case '-': 271*7068Srrh i = ckph(); 272*7068Srrh if(nonumb)break; 273*7068Srrh acc -= i; 274*7068Srrh goto a0; 275*7068Srrh case '*': 276*7068Srrh i = ckph(); 277*7068Srrh if(nonumb)break; 278*7068Srrh acc *= i; 279*7068Srrh goto a0; 280*7068Srrh case '/': 281*7068Srrh i = ckph(); 282*7068Srrh if(nonumb)break; 283*7068Srrh if(i == 0){ 284*7068Srrh prstrfl("Divide by zero.\n"); 285*7068Srrh acc = 0; 286*7068Srrh }else acc /= i; 287*7068Srrh goto a0; 288*7068Srrh case '%': 289*7068Srrh i = ckph(); 290*7068Srrh if(nonumb)break; 291*7068Srrh acc %= i; 292*7068Srrh goto a0; 293*7068Srrh case '&': /*and*/ 294*7068Srrh i = ckph(); 295*7068Srrh if(nonumb)break; 296*7068Srrh if((acc > 0) && (i > 0))acc = 1; else acc = 0; 297*7068Srrh goto a0; 298*7068Srrh case ':': /*or*/ 299*7068Srrh i = ckph(); 300*7068Srrh if(nonumb)break; 301*7068Srrh if((acc > 0) || (i > 0))acc = 1; else acc = 0; 302*7068Srrh goto a0; 303*7068Srrh case '=': 304*7068Srrh if(((ii=getch()) & CMASK) != '=')ch = ii; 305*7068Srrh i = ckph(); 306*7068Srrh if(nonumb){acc = 0; break;} 307*7068Srrh if(i == acc)acc = 1; 308*7068Srrh else acc = 0; 309*7068Srrh goto a0; 310*7068Srrh case '>': 311*7068Srrh k = 0; 312*7068Srrh if(((ii=getch()) & CMASK) == '=')k++; else ch =ii; 313*7068Srrh i = ckph(); 314*7068Srrh if(nonumb){acc = 0; break;} 315*7068Srrh if(acc > (i - k))acc = 1; else acc = 0; 316*7068Srrh goto a0; 317*7068Srrh case '<': 318*7068Srrh k = 0; 319*7068Srrh if(((ii=getch()) & CMASK) == '=')k++; else ch =ii; 320*7068Srrh i = ckph(); 321*7068Srrh if(nonumb){acc = 0; break;} 322*7068Srrh if(acc < (i + k))acc = 1; else acc = 0; 323*7068Srrh goto a0; 324*7068Srrh case ')': break; 325*7068Srrh case '(': 326*7068Srrh acc = atoi0(); 327*7068Srrh goto a0; 328*7068Srrh } 329*7068Srrh return(acc); 330*7068Srrh } 331*7068Srrh long ckph(){ 332*7068Srrh register i; 333*7068Srrh long j; 334*7068Srrh extern long atoi0(); 335*7068Srrh extern long atoi1(); 336*7068Srrh 337*7068Srrh if(((i = getch()) & CMASK) == '(')j = atoi0(); 338*7068Srrh else{ 339*7068Srrh ch = i; 340*7068Srrh j = atoi1(); 341*7068Srrh } 342*7068Srrh return(j); 343*7068Srrh } 344*7068Srrh long atoi1() 345*7068Srrh { 346*7068Srrh register i, j, digits; 347*7068Srrh long acc; 348*7068Srrh int neg, abs, field; 349*7068Srrh 350*7068Srrh neg = abs = field = digits = 0; 351*7068Srrh acc = 0; 352*7068Srrh a0: 353*7068Srrh switch((i = getch()) & CMASK){ 354*7068Srrh default: 355*7068Srrh ch = i; 356*7068Srrh break; 357*7068Srrh case '+': 358*7068Srrh goto a0; 359*7068Srrh case '-': 360*7068Srrh neg = 1; 361*7068Srrh goto a0; 362*7068Srrh case '|': 363*7068Srrh abs = 1 + neg; 364*7068Srrh neg = 0; 365*7068Srrh goto a0; 366*7068Srrh } 367*7068Srrh a1: 368*7068Srrh while(((j = ((i = getch()) & CMASK) - '0') >= 0) && (j <= 9)){ 369*7068Srrh field++; 370*7068Srrh digits++; 371*7068Srrh acc = 10*acc + j; 372*7068Srrh } 373*7068Srrh if((i & CMASK) == '.'){ 374*7068Srrh field++; 375*7068Srrh digits = 0; 376*7068Srrh goto a1; 377*7068Srrh } 378*7068Srrh ch = i; 379*7068Srrh if(!field)goto a2; 380*7068Srrh switch((i = getch()) & CMASK){ 381*7068Srrh case 'u': 382*7068Srrh i = j = 1; 383*7068Srrh break; 384*7068Srrh case 'v': /*VSs - vert spacing*/ 385*7068Srrh j = lss; 386*7068Srrh i = 1; 387*7068Srrh break; 388*7068Srrh case 'm': /*Ems*/ 389*7068Srrh j = EM; 390*7068Srrh i = 1; 391*7068Srrh break; 392*7068Srrh case 'n': /*Ens*/ 393*7068Srrh j = EM; 394*7068Srrh #ifndef NROFF 395*7068Srrh i = 2; 396*7068Srrh #endif 397*7068Srrh #ifdef NROFF 398*7068Srrh i = 1; /*Same as Ems in NROFF*/ 399*7068Srrh #endif 400*7068Srrh break; 401*7068Srrh case 'p': /*Points*/ 402*7068Srrh j = INCH; 403*7068Srrh i = 72; 404*7068Srrh break; 405*7068Srrh case 'i': /*Inches*/ 406*7068Srrh j = INCH; 407*7068Srrh i = 1; 408*7068Srrh break; 409*7068Srrh case 'c': /*Centimeters*/ 410*7068Srrh j = INCH*50; 411*7068Srrh i = 127; 412*7068Srrh break; 413*7068Srrh case 'P': /*Picas*/ 414*7068Srrh j = INCH; 415*7068Srrh i = 6; 416*7068Srrh break; 417*7068Srrh default: 418*7068Srrh j = dfact; 419*7068Srrh ch = i; 420*7068Srrh i = dfactd; 421*7068Srrh } 422*7068Srrh if(neg) acc = -acc; 423*7068Srrh if(!noscale){ 424*7068Srrh acc = (acc*j)/i; 425*7068Srrh } 426*7068Srrh if((field != digits) && (digits > 0))while(digits--)acc /= 10; 427*7068Srrh if(abs){ 428*7068Srrh if(dip != d)j = dip->dnl; else j = v.nl; 429*7068Srrh if(!vflag)j = v.hp = sumhp(); /* XXX */ 430*7068Srrh if(abs == 2)j = -j; 431*7068Srrh acc -= j; 432*7068Srrh } 433*7068Srrh a2: 434*7068Srrh nonumb = !field; 435*7068Srrh return(acc); 436*7068Srrh } 437*7068Srrh caserr(){ 438*7068Srrh register i,j; 439*7068Srrh 440*7068Srrh lgf++; 441*7068Srrh while(!skip() && (i=getrq()) ){ 442*7068Srrh for(j=NNAMES; j<NN; j++){ /*NNAMES predefined names*/ 443*7068Srrh if(i == r[j])break; 444*7068Srrh } 445*7068Srrh if(j!=NN){ 446*7068Srrh r[j]=vlist[j]=inc[j]=fmt[j]=0; 447*7068Srrh regcnt--; 448*7068Srrh } 449*7068Srrh } 450*7068Srrh } 451*7068Srrh casenr(){ 452*7068Srrh register i, j; 453*7068Srrh 454*7068Srrh lgf++; 455*7068Srrh skip(); 456*7068Srrh if((i = findr(getrq())) == -1)goto rtn; 457*7068Srrh skip(); 458*7068Srrh j = inumb(&vlist[i]); 459*7068Srrh if(nonumb)goto rtn; 460*7068Srrh vlist[i] = j; 461*7068Srrh skip(); 462*7068Srrh j = atoi(); 463*7068Srrh if(nonumb)goto rtn; 464*7068Srrh inc[i] = j; 465*7068Srrh rtn: 466*7068Srrh return; 467*7068Srrh } 468*7068Srrh caseaf(){ 469*7068Srrh register i, j, k; 470*7068Srrh 471*7068Srrh lgf++; 472*7068Srrh if(skip() || !(i = getrq()) || skip())return; 473*7068Srrh k = 0; 474*7068Srrh if(!alph(j=getch())){ 475*7068Srrh ch = j; 476*7068Srrh while(((j = getch() & CMASK) >= '0') && 477*7068Srrh (j <= '9'))k++; 478*7068Srrh } 479*7068Srrh if(!k)k=j; 480*7068Srrh fmt[findr(i)] = k & BMASK; 481*7068Srrh } 482*7068Srrh vnumb(i) 483*7068Srrh int *i; 484*7068Srrh { 485*7068Srrh vflag++; 486*7068Srrh dfact = lss; 487*7068Srrh res = VERT; 488*7068Srrh return(inumb(i)); 489*7068Srrh } 490*7068Srrh hnumb(i) 491*7068Srrh int *i; 492*7068Srrh { 493*7068Srrh dfact = EM; 494*7068Srrh res = HOR; 495*7068Srrh return(inumb(i)); 496*7068Srrh } 497*7068Srrh inumb(n) 498*7068Srrh int *n; 499*7068Srrh { 500*7068Srrh register i, j, f; 501*7068Srrh 502*7068Srrh f = 0; 503*7068Srrh if(n){ 504*7068Srrh if((j = (i = getch()) & CMASK) == '+')f = 1; 505*7068Srrh else if(j == '-')f = -1; 506*7068Srrh else ch = i; 507*7068Srrh } 508*7068Srrh i = atoi(); 509*7068Srrh if(n && f)i = *n + f*i; 510*7068Srrh i = quant(i,res); 511*7068Srrh vflag = 0; 512*7068Srrh res = dfactd = dfact = 1; 513*7068Srrh if(nonumb)i = 0; 514*7068Srrh return(i); 515*7068Srrh } 516*7068Srrh quant(n,m) 517*7068Srrh int n, m; 518*7068Srrh { 519*7068Srrh register i, neg; 520*7068Srrh 521*7068Srrh neg = 0; 522*7068Srrh if(n<0){ 523*7068Srrh neg++; 524*7068Srrh n = -n; 525*7068Srrh } 526*7068Srrh i = n/m; 527*7068Srrh if((n - m*i) > (m/2))i += 1; 528*7068Srrh i *= m; 529*7068Srrh if(neg)i = -i; 530*7068Srrh return(i); 531*7068Srrh } 532