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

Defined functions

abc defined in line 223; used 1 times
abc0 defined in line 229; used 2 times
atoi0 defined in line 250; used 5 times
atoi1 defined in line 344; used 4 times
caseaf defined in line 468; used 2 times
casenr defined in line 451; used 2 times
caserr defined in line 437; used 2 times
ckph defined in line 331; used 11 times
decml defined in line 183; used 2 times
hnumb defined in line 490; used 7 times
roman defined in line 193; used 1 times
roman0 defined in line 201; used 3 times
setn defined in line 64; used 1 times
wrc defined in line 238; used 2 times

Defined variables

regcnt defined in line 62; used 3 times
sccsid defined in line 2; never used
Last modified: 1982-08-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4354
Valid CSS Valid XHTML 1.0 Strict