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

Defined functions

abc defined in line 218; used 1 times
abc0 defined in line 224; used 2 times
atoi0 defined in line 245; used 5 times
atoi1 defined in line 339; used 4 times
caseaf defined in line 463; used 2 times
casenr defined in line 446; used 2 times
caserr defined in line 432; used 2 times
ckph defined in line 326; used 11 times
decml defined in line 178; used 2 times
findr defined in line 134; used 8 times
fnumb defined in line 158; used 3 times
hnumb defined in line 485; used 7 times
inumb defined in line 492; used 11 times
roman defined in line 188; used 1 times
roman0 defined in line 196; used 3 times
setn defined in line 59; used 1 times
setn1 defined in line 123; used 3 times
vnumb defined in line 477; used 8 times
wrc defined in line 233; used 2 times

Defined variables

regcnt defined in line 57; used 3 times
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1381
Valid CSS Valid XHTML 1.0 Strict