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: /*
  13: troff3.c
  14: 
  15: macro and string routines, storage allocation
  16: */
  17: 
  18: unsigned blist[NBLIST];
  19: extern struct s *frame, *stk, *nxf;
  20: extern filep ip;
  21: extern filep offset;
  22: extern filep nextb;
  23: extern char *enda;
  24: 
  25: extern int ch;
  26: extern int ibf;
  27: extern int lgf;
  28: extern int copyf;
  29: extern int ch0;
  30: extern int app;
  31: extern int ds;
  32: extern int nlflg;
  33: extern int *argtop;
  34: extern int *ap;
  35: extern int nchar;
  36: extern int pendt;
  37: extern int rchar;
  38: extern int dilev;
  39: extern int nonumb;
  40: extern int lt;
  41: extern int nrbits;
  42: extern int nform;
  43: extern int fmt[];
  44: extern int oldmn;
  45: extern int newmn;
  46: extern int macerr;
  47: extern filep apptr;
  48: extern int diflg;
  49: extern filep woff;
  50: extern filep roff;
  51: extern int wbfi;
  52: extern int po;
  53: extern int *cp;
  54: extern int xxx;
  55: int pagech = '%';
  56: int strflg;
  57: extern struct contab {
  58:     int rq;
  59:     union {
  60:         int (*f)();
  61:         unsigned mx;
  62:     }x;
  63: }contab[NM];
  64: int wbuf[BLK];
  65: int rbuf[BLK];
  66: 
  67: caseig(){
  68:     register i;
  69: 
  70:     offset = 0;
  71:     if((i = copyb()) != '.')control(i,1);
  72: }
  73: casern(){
  74:     register i,j;
  75: 
  76:     lgf++;
  77:     skip();
  78:     if(((i=getrq())==0) || ((oldmn=findmn(i)) < 0))return;
  79:     skip();
  80:     clrmn(findmn(j=getrq()));
  81:     if(j)contab[oldmn].rq = (contab[oldmn].rq & MMASK) | j;
  82: }
  83: caserm(){
  84:     lgf++;
  85:     while(!skip()){
  86:         clrmn(findmn(getrq()));
  87:     }
  88: }
  89: caseas(){
  90:     app++;
  91:     caseds();
  92: }
  93: caseds(){
  94:     ds++;
  95:     casede();
  96: }
  97: caseam(){
  98:     app++;
  99:     casede();
 100: }
 101: casede(){
 102:     register i, req;
 103:     register filep savoff;
 104:     extern filep finds();
 105: 
 106:     if(dip != d)wbfl();
 107:     req = '.';
 108:     lgf++;
 109:     skip();
 110:     if((i=getrq())==0)goto de1;
 111:     if((offset=finds(i)) == 0)goto de1;
 112:     if(ds)copys();
 113:         else req = copyb();
 114:     wbfl();
 115:     clrmn(oldmn);
 116:     if(newmn)contab[newmn].rq = i | MMASK;
 117:     if(apptr){
 118:         savoff = offset;
 119:         offset = apptr;
 120:         wbt(IMP);
 121:         offset = savoff;
 122:     }
 123:     offset = dip->op;
 124:     if(req != '.')control(req,1);
 125: de1:
 126:     ds = app = 0;
 127:     return;
 128: }
 129: findmn(i)
 130: int i;
 131: {
 132:     register j;
 133: 
 134:     for(j=0;j<NM;j++){
 135:         if(i == (contab[j].rq & ~MMASK))break;
 136:     }
 137:     if(j==NM)j = -1;
 138:     return(j);
 139: }
 140: clrmn(i)
 141: int i;
 142: {
 143:     extern filep boff();
 144:     if(i >= 0){
 145:         if(contab[i].rq & MMASK)ffree(((filep)contab[i].x.mx)<<BLKBITS);
 146:         contab[i].rq = 0;
 147:         contab[i].x.mx = 0;
 148:     }
 149: }
 150: filep finds(mn)
 151: int mn;
 152: {
 153:     register i;
 154:     extern filep boff();
 155:     register filep savip;
 156:     extern filep alloc();
 157:     extern filep incoff();
 158: 
 159:     oldmn = findmn(mn);
 160:     newmn = 0;
 161:     apptr = (filep)0;
 162:     if(app && (oldmn >= 0) && (contab[oldmn].rq & MMASK)){
 163:             savip = ip;
 164:             ip = (((filep)contab[oldmn].x.mx)<<BLKBITS);
 165:             oldmn = -1;
 166:             while((i=rbf()) != 0);
 167:             apptr = ip;
 168:             if(!diflg)ip = incoff(ip);
 169:             nextb = ip;
 170:             ip = savip;
 171:     }else{
 172:         for(i=0;i<NM;i++){
 173:             if(contab[i].rq == 0)break;
 174:         }
 175:         if((i==NM) ||
 176:            (nextb = alloc()) == 0){
 177:             app = 0;
 178:             if(macerr++ > 1)done2(02);
 179:             prstr("Too many string/macro names.\n");
 180:             edone(04);
 181:             return(offset = 0);
 182:         }
 183:             contab[i].x.mx = (unsigned)(nextb>>BLKBITS);
 184:         if(!diflg){
 185:             newmn = i;
 186:             if(oldmn == -1)contab[i].rq = -1;
 187:         }else{
 188:             contab[i].rq = mn | MMASK;
 189:         }
 190:     }
 191: 
 192:     app = 0;
 193:     return(offset = nextb);
 194: }
 195: skip(){
 196:     register i;
 197: 
 198:     while(((i=getch()) & CMASK) == ' ');
 199:     ch=i;
 200:     return(nlflg);
 201: }
 202: copyb()
 203: {
 204:     register i, j, k;
 205:     int ii, req, state;
 206:     filep savoff;
 207: 
 208:     if(skip() || !(j=getrq()))j = '.';
 209:     req = j;
 210:     k = j>>BYTE;
 211:     j &= BMASK;
 212:     copyf++;
 213:     flushi();
 214:     nlflg = 0;
 215:     state = 1;
 216:     while(1){
 217:         i = (ii = getch()) & CMASK;
 218:         if(state == 3){
 219:             if(i == k)break;
 220:             if(!k){
 221:                 ch = ii;
 222:                 i = getach();
 223:                 ch = ii;
 224:                 if(!i)break;
 225:             }
 226:             state = 0;
 227:             goto c0;
 228:         }
 229:         if(i == '\n'){
 230:             state = 1;
 231:             nlflg = 0;
 232:             goto c0;
 233:         }
 234:         if((state == 1) && (i == '.')){
 235:             state++;
 236:             savoff = offset;
 237:             goto c0;
 238:         }
 239:         if((state == 2) && (i == j)){
 240:             state++;
 241:             goto c0;
 242:         }
 243:         state = 0;
 244: c0:
 245:         if(offset)wbf(ii);
 246:     }
 247:     if(offset){
 248:         wbfl();
 249:         offset = savoff;
 250:         wbt(0);
 251:     }
 252:     copyf--;
 253:     return(req);
 254: }
 255: copys()
 256: {
 257:     register i;
 258: 
 259:     copyf++;
 260:     if(skip())goto c0;
 261:     if(((i=getch()) & CMASK) != '"')wbf(i);
 262:     while(((i=getch()) & CMASK) != '\n')wbf(i);
 263: c0:
 264:     wbt(0);
 265:     copyf--;
 266: }
 267: filep alloc()
 268: {
 269:     register i;
 270:     extern filep boff();
 271:     filep j;
 272: 
 273:     for(i=0;i<NBLIST;i++){
 274:         if(blist[i] == 0)break;
 275:     }
 276:     if(i==NBLIST){
 277:         j = 0;
 278:     }else{
 279:         blist[i] = -1;
 280:         if((j = boff(i)) < NEV*EVS)j = 0;
 281:     }
 282:     return(nextb = j);
 283: }
 284: ffree(i)
 285: filep i;
 286: {
 287:     register j;
 288: 
 289:     while((blist[j = blisti(i)]) != -1){
 290:         i = ((filep)blist[j])<<BLKBITS;
 291:         blist[j] = 0;
 292:     }
 293:     blist[j] = 0;
 294: }
 295: filep boff(i)
 296: int i;
 297: {
 298:     return(((filep)i)*BLK + NEV*EVS);
 299: }
 300: wbt(i)
 301: int i;
 302: {
 303:     wbf(i);
 304:     wbfl();
 305: }
 306: wbf(i)
 307: int i;
 308: {
 309:     register j;
 310: 
 311:     if(!offset)return;
 312:     if(!woff){
 313:         woff = offset;
 314:         wbfi = 0;
 315:     }
 316:     wbuf[wbfi++] = i;
 317:     if(!((++offset) & (BLK-1))){
 318:         wbfl();
 319:         if(blist[j = blisti(--offset)] == -1){
 320:             if(alloc() == 0){
 321:                 prstr("Out of temp file space.\n");
 322:                 done2(01);
 323:             }
 324:             blist[j] = (unsigned)(nextb>>BLKBITS);
 325:         }
 326:         offset = ((filep)blist[j])<<BLKBITS;
 327:     }
 328:     if(wbfi >= BLK)wbfl();
 329: }
 330: wbfl(){
 331:     if(woff == 0)return;
 332:     lseek(ibf, ((long)woff) * sizeof(int), 0);
 333:     write(ibf, (char *)wbuf, wbfi * sizeof(int));
 334:     if((woff & (~(BLK-1))) == (roff & (~(BLK-1))))roff = -1;
 335:     woff = 0;
 336: }
 337: blisti(i)
 338: filep i;
 339: {
 340:     return((i-NEV*EVS)/(BLK));
 341: }
 342: rbf(){
 343:     register i;
 344:     extern filep incoff();
 345: 
 346:     if((i=rbf0(ip)) == 0){
 347:         if(!app)i = popi();
 348:     }else{
 349:         ip = incoff(ip);
 350:     }
 351:     return(i);
 352: }
 353: rbf0(p)
 354: filep p;
 355: {
 356:     register filep i;
 357: 
 358:     if((i = (p & (~(BLK-1)))) != roff){
 359:         roff = i;
 360:         lseek(ibf, ((long)roff) * sizeof(int), 0);
 361:         if(read(ibf, (char *)rbuf, BLK * sizeof(int)) == 0)return(0);
 362:     }
 363:     return(rbuf[p & (BLK-1)]);
 364: }
 365: filep incoff(p)
 366: filep p;
 367: {
 368:     register i;
 369:     register filep j;
 370:     if(!((j = (++p)) & (BLK-1))){
 371:         if((i = blist[blisti(--p)]) == -1){
 372:             prstr("Bad storage allocation.\n");
 373:             done2(-5);
 374:         }
 375:         j = ((filep)i)<<BLKBITS;
 376:     }
 377:     return(j);
 378: }
 379: popi(){
 380:     register struct s *p;
 381: 
 382:     if(frame == stk)return(0);
 383:     if(strflg)strflg--;
 384:     p = nxf = frame;
 385:     p->nargs = 0;
 386:     frame = p->pframe;
 387:     ip = p->pip;
 388:     nchar = p->pnchar;
 389:     rchar = p->prchar;
 390:     pendt = p->ppendt;
 391:     ap = p->pap;
 392:     cp = p->pcp;
 393:     ch0 = p->pch0;
 394:     return(p->pch);
 395: }
 396: pushi(newip)
 397: filep newip;
 398: {
 399:     register struct s *p;
 400:     extern char *setbrk();
 401: 
 402:     if((enda - sizeof(struct s)) < (char *)nxf)setbrk(DELTA);
 403:     p = nxf;
 404:     p->pframe = frame;
 405:     p->pip = ip;
 406:     p->pnchar = nchar;
 407:     p->prchar = rchar;
 408:     p->ppendt = pendt;
 409:     p->pap = ap;
 410:     p->pcp = cp;
 411:     p->pch0 = ch0;
 412:     p->pch = ch;
 413:     cp = ap = 0;
 414:     nchar = rchar = pendt = ch0 = ch = 0;
 415:     frame = nxf;
 416:     if(nxf->nargs == 0) nxf += 1;
 417:         else nxf = (struct s *)argtop;
 418:     return(ip = newip);
 419: }
 420: char *setbrk(x)
 421: int x;
 422: {
 423:     register char *i;
 424:     char *sbrk();
 425: 
 426:     if((i = sbrk(x)) == MAXPTR){
 427:         prstrfl("Core limit reached.\n");
 428:         edone(0100);
 429:     }else{
 430:         enda = i + x;
 431:     }
 432:     return(i);
 433: }
 434: getsn(){
 435:     register i;
 436: 
 437:     if((i=getach()) == 0)return(0);
 438:     if(i == '(')return(getrq());
 439:         else return(i);
 440: }
 441: setstr(){
 442:     register i;
 443: 
 444:     lgf++;
 445:     if(((i=getsn()) == 0) ||
 446:        ((i=findmn(i)) == -1) ||
 447:        !(contab[i].rq & MMASK)){
 448:         lgf--;
 449:         return(0);
 450:     }else{
 451:         if((enda-2) < (char *)nxf)setbrk(DELTA);
 452:         nxf->nargs = 0;
 453:         strflg++;
 454:         lgf--;
 455:         return(pushi(((filep)contab[i].x.mx)<<BLKBITS));
 456:     }
 457: }
 458: collect()
 459: {
 460:     register i;
 461:     register int *strp;
 462:     int *lim;
 463:     int **argpp, **argppend;
 464:     int quote;
 465:     struct s *savnxf;
 466: 
 467:     copyf++;
 468:     nxf->nargs = 0;
 469:     savnxf = nxf;
 470:     if(skip())goto rtn;
 471:     lim = (int *)(nxf = savnxf + sizeof(struct s)/sizeof(savnxf));
 472:     strflg = 0;
 473:     if((argppend =
 474:         (argpp = (int **)savnxf+(sizeof(struct s)/sizeof(int **))) + (sizeof(struct s)-1))
 475:         > (int **)enda)setbrk(DELTA);
 476:     strp = (int *)argppend;
 477:     for(i=8; i>=0; i--)argpp[i] = 0;
 478:     while((argpp != argppend) && (!skip())){
 479:         *argpp++ = strp;
 480:         quote = 0;
 481:         if(((i = getch()) & CMASK) == '"')quote++;
 482:             else ch = i;
 483:         while(1){
 484:             i = getch();
 485:             if( nlflg ||
 486:               ((!quote) && ((i & CMASK) == ' ')))break;
 487:             if(quote && ((i & CMASK) == '"') &&
 488:               (((i=getch()) & CMASK) != '"')){
 489:                 ch = i;
 490:                 break;
 491:             }
 492:             *strp++ = i;
 493:             if(strflg && (strp >= lim)){
 494:                 prstrfl("Macro argument too long.\n");
 495:                 copyf--;
 496:                 edone(004);
 497:             }
 498:             if((enda-4) <= (char *)strp)setbrk(DELTA);
 499:         }
 500:         *strp++ = 0;
 501:     }
 502:     nxf = savnxf;
 503:     nxf->nargs = argpp -(int **)(nxf + 1);
 504:     argtop = strp;
 505: rtn:
 506:     copyf--;
 507: }
 508: seta()
 509: {
 510:     register i;
 511: 
 512:     if(((i = (getch() & CMASK) - '0') > 0) &&
 513:         (i <= 9) && (i <= frame->nargs))ap = *((int **)frame + i-1 + (sizeof(struct s)/sizeof(int **)));
 514: }
 515: caseda(){
 516:     app++;
 517:     casedi();
 518: }
 519: casedi(){
 520:     register i, j;
 521:     register *k;
 522: 
 523:     lgf++;
 524:     if(skip() || ((i=getrq()) == 0)){
 525:         if(dip != d)wbt(0);
 526:         if(dilev > 0){
 527:             v.dn = dip->dnl;
 528:             v.dl = dip->maxl;
 529:             dip = &d[--dilev];
 530:             offset = dip->op;
 531:         }
 532:         goto rtn;
 533:     }
 534:     if(++dilev == NDI){
 535:         --dilev;
 536:         prstr("Cannot divert.\n");
 537:         edone(02);
 538:     }
 539:     if(dip != d)wbt(0);
 540:     diflg++;
 541:     dip = &d[dilev];
 542:     dip->op = finds(i);
 543:     dip->curd = i;
 544:     clrmn(oldmn);
 545:     k = (int *)&dip->dnl;
 546:     for(j=0; j<10; j++)k[j] = 0;    /*not op and curd*/
 547: rtn:
 548:     app = 0;
 549:     diflg = 0;
 550: }
 551: casedt(){
 552:     lgf++;
 553:     dip->dimac = dip->ditrap = dip->ditf = 0;
 554:     skip();
 555:     dip->ditrap = vnumb((int *)0);
 556:     if(nonumb)return;
 557:     skip();
 558:     dip->dimac = getrq();
 559: }
 560: casetl(){
 561:     register i, j;
 562:     int w1, w2, w3, delim;
 563:     filep begin;
 564:     extern width(), pchar();
 565: 
 566:     dip->nls = 0;
 567:     skip();
 568:     if(dip != d)wbfl();
 569:     if((offset = begin = alloc()) == 0)return;
 570:     if((delim = getch()) & MOT){
 571:         ch = delim;
 572:         delim = '\'';
 573:     }else delim &= CMASK;
 574:     if(!nlflg)
 575:         while(((i = getch()) & CMASK) != '\n'){
 576:             if((i & CMASK) == delim)i = IMP;
 577:             wbf(i);
 578:         }
 579:     wbf(IMP);wbf(IMP);wbt(0);
 580: 
 581:     w1 = hseg(width,begin);
 582:     w2 = hseg(width,(filep)0);
 583:     w3 = hseg(width,(filep)0);
 584:     offset = dip->op;
 585: #ifdef NROFF
 586:     if(!offset)horiz(po);
 587: #endif
 588:     hseg(pchar,begin);
 589:     if(w2 || w3)horiz(j=quant((lt - w2)/2-w1,HOR));
 590:     hseg(pchar,(filep)0);
 591:     if(w3){
 592:         horiz(lt-w1-w2-w3-j);
 593:         hseg(pchar,(filep)0);
 594:     }
 595:     newline(0);
 596:     if(dip != d){if(dip->dnl > dip->hnl)dip->hnl = dip->dnl;}
 597:     else{if(v.nl > dip->hnl)dip->hnl = v.nl;}
 598:     ffree(begin);
 599: }
 600: casepc(){
 601:     pagech = chget(IMP);
 602: }
 603: hseg(f,p)
 604: int (*f)();
 605: filep p;
 606: {
 607:     register acc, i;
 608:     static filep q;
 609: 
 610:     acc = 0;
 611:     if(p)q = p;
 612:     while(1){
 613:         i = rbf0(q);
 614:         q = incoff(q);
 615:         if(!i || (i == IMP))return(acc);
 616:         if((i & CMASK) == pagech){
 617:             nrbits = i & ~CMASK;
 618:             nform = fmt[findr('%')];
 619:             acc += fnumb(v.pn,f);
 620:         }else acc += (*f)(i);
 621:     }
 622: }
 623: casepm(){
 624:     register i, k;
 625:     register char *p;
 626:     int xx, cnt, kk, tot;
 627:     filep j;
 628:     char *kvt();
 629:     char pmline[10];
 630: 
 631:     kk = cnt = 0;
 632:     tot = !skip();
 633:     for(i = 0; i<NM; i++){
 634:         if(!((xx = contab[i].rq) & MMASK))continue;
 635:         p = pmline;
 636:         j = (((filep)contab[i].x.mx)<<BLKBITS);
 637:         k = 1;
 638:         while((j = blist[blisti(j)]) != -1){k++; j <<= BLKBITS;}
 639:         cnt++;
 640:         kk += k;
 641:         if(!tot){
 642:             *p++ = xx & 0177;
 643:             if(!(*p++ = (xx >> BYTE) & 0177))*(p-1) = ' ';
 644:             *p++ = ' ';
 645:             kvt(k,p);
 646:             prstr(pmline);
 647:         }
 648:     }
 649:     if(tot || (cnt > 1)){
 650:         kvt(kk,pmline);
 651:         prstr(pmline);
 652:     }
 653: }
 654: char *kvt(k,p)
 655: int k;
 656: char *p;
 657: {
 658:     if(k>=100)*p++ = k/100 + '0';
 659:     if(k>=10)*p++ = (k%100)/10 + '0';
 660:     *p++ = k%10 + '0';
 661:     *p++ = '\n';
 662:     *p = 0;
 663:     return(p);
 664: }
 665: dummy(){}

Defined functions

alloc defined in line 267; used 6 times
blisti defined in line 337; used 4 times
boff defined in line 295; used 5 times
caseam defined in line 97; used 2 times
caseas defined in line 89; used 2 times
caseda defined in line 515; used 2 times
casede defined in line 101; used 4 times
casedi defined in line 519; used 3 times
caseds defined in line 93; used 3 times
casedt defined in line 551; used 2 times
caseig defined in line 67; used 2 times
casepc defined in line 600; used 2 times
casepm defined in line 623; used 2 times
caserm defined in line 83; used 2 times
casern defined in line 73; used 2 times
casetl defined in line 560; used 2 times
clrmn defined in line 140; used 4 times
collect defined in line 458; used 2 times
copyb defined in line 202; used 2 times
copys defined in line 255; used 1 times
dummy defined in line 665; used 1 times
ffree defined in line 284; used 3 times
findmn defined in line 129; used 6 times
finds defined in line 150; used 3 times
getsn defined in line 434; used 5 times
hseg defined in line 603; used 6 times
incoff defined in line 365; used 7 times
kvt defined in line 654; used 3 times
popi defined in line 379; used 2 times
pushi defined in line 396; used 3 times
rbf defined in line 342; used 2 times
rbf0 defined in line 353; used 4 times
seta defined in line 508; used 1 times
setbrk defined in line 420; used 9 times
setstr defined in line 441; used 1 times
skip defined in line 195; used 84 times
wbf defined in line 306; used 9 times
wbfl defined in line 330; used 8 times
wbt defined in line 300; used 8 times

Defined variables

pagech defined in line 55; used 2 times
rbuf defined in line 65; used 2 times
strflg defined in line 56; used 5 times
wbuf defined in line 64; used 2 times

Defined struct's

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