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