|
|
1.1 ! root 1: /* @(#)roff:n3.c 2.7 */ ! 2: /* ! 3: * troff3.c ! 4: * ! 5: * macro and string routines, storage allocation ! 6: */ ! 7: ! 8: ! 9: #include "tdef.h" ! 10: #ifdef NROFF ! 11: #include "tw.h" ! 12: #endif ! 13: #include "ext.h" ! 14: ! 15: #define MHASH(x) ((x>>6)^x)&0177 ! 16: struct contab *mhash[128]; /* 128 == the 0177 on line above */ ! 17: #define blisti(i) (((i)-ENV_BLK*BLK) / BLK) ! 18: filep blist[NBLIST]; ! 19: tchar *argtop; ! 20: int pagech = '%'; ! 21: int strflg; ! 22: ! 23: #ifdef INCORE ! 24: tchar *wbuf; ! 25: tchar corebuf[(ENV_BLK + NBLIST + 1) * BLK]; ! 26: #else ! 27: tchar wbuf[BLK]; ! 28: tchar rbuf[BLK]; ! 29: #endif ! 30: ! 31: caseig() ! 32: { ! 33: register i; ! 34: ! 35: offset = 0; ! 36: if ((i = copyb()) != '.') ! 37: control(i, 1); ! 38: } ! 39: ! 40: ! 41: casern() ! 42: { ! 43: register i, j; ! 44: ! 45: lgf++; ! 46: skip(); ! 47: if ((i = getrq()) == 0 || (oldmn = findmn(i)) < 0) ! 48: return; ! 49: skip(); ! 50: clrmn(findmn(j = getrq())); ! 51: if (j) { ! 52: munhash(&contab[oldmn]); ! 53: contab[oldmn].rq = j; ! 54: maddhash(&contab[oldmn]); ! 55: } ! 56: } ! 57: ! 58: maddhash(rp) ! 59: register struct contab *rp; ! 60: { ! 61: register struct contab **hp; ! 62: ! 63: if (rp->rq == 0) ! 64: return; ! 65: hp = &mhash[MHASH(rp->rq)]; ! 66: rp->link = *hp; ! 67: *hp = rp; ! 68: } ! 69: ! 70: munhash(mp) ! 71: register struct contab *mp; ! 72: { ! 73: register struct contab *p; ! 74: register struct contab **lp; ! 75: ! 76: if (mp->rq == 0) ! 77: return; ! 78: lp = &mhash[MHASH(mp->rq)]; ! 79: p = *lp; ! 80: while (p) { ! 81: if (p == mp) { ! 82: *lp = p->link; ! 83: p->link = 0; ! 84: return; ! 85: } ! 86: lp = &p->link; ! 87: p = p->link; ! 88: } ! 89: } ! 90: ! 91: mrehash() ! 92: { ! 93: register struct contab *p; ! 94: register i; ! 95: ! 96: for (i=0; i<128; i++) ! 97: mhash[i] = 0; ! 98: for (p=contab; p < &contab[NM]; p++) ! 99: p->link = 0; ! 100: for (p=contab; p < &contab[NM]; p++) { ! 101: if (p->rq == 0) ! 102: continue; ! 103: i = MHASH(p->rq); ! 104: p->link = mhash[i]; ! 105: mhash[i] = p; ! 106: } ! 107: } ! 108: ! 109: caserm() ! 110: { ! 111: int j; ! 112: ! 113: lgf++; ! 114: while (!skip() && (j = getrq()) != 0) ! 115: clrmn(findmn(j)); ! 116: lgf--; ! 117: } ! 118: ! 119: ! 120: caseas() ! 121: { ! 122: app++; ! 123: caseds(); ! 124: } ! 125: ! 126: ! 127: caseds() ! 128: { ! 129: ds++; ! 130: casede(); ! 131: } ! 132: ! 133: ! 134: caseam() ! 135: { ! 136: app++; ! 137: casede(); ! 138: } ! 139: ! 140: ! 141: casede() ! 142: { ! 143: register i, req; ! 144: register filep savoff; ! 145: extern filep finds(); ! 146: ! 147: if (dip != d) ! 148: wbfl(); ! 149: req = '.'; ! 150: lgf++; ! 151: skip(); ! 152: if ((i = getrq()) == 0) ! 153: goto de1; ! 154: if ((offset = finds(i)) == 0) ! 155: goto de1; ! 156: if (ds) ! 157: copys(); ! 158: else ! 159: req = copyb(); ! 160: wbfl(); ! 161: clrmn(oldmn); ! 162: if (newmn) { ! 163: if (contab[newmn].rq) ! 164: munhash(&contab[newmn]); ! 165: contab[newmn].rq = i; ! 166: maddhash(&contab[newmn]); ! 167: } ! 168: if (apptr) { ! 169: savoff = offset; ! 170: offset = apptr; ! 171: wbt((tchar) IMP); ! 172: offset = savoff; ! 173: } ! 174: offset = dip->op; ! 175: if (req != '.') ! 176: control(req, 1); ! 177: de1: ! 178: ds = app = 0; ! 179: return; ! 180: } ! 181: ! 182: ! 183: findmn(i) ! 184: register int i; ! 185: { ! 186: register struct contab *p; ! 187: ! 188: for (p = mhash[MHASH(i)]; p; p = p->link) ! 189: if (i == p->rq) ! 190: return(p - contab); ! 191: return(-1); ! 192: } ! 193: ! 194: ! 195: clrmn(i) ! 196: register int i; ! 197: { ! 198: if (i >= 0) { ! 199: if (contab[i].mx) ! 200: ffree((filep)contab[i].mx); ! 201: munhash(&contab[i]); ! 202: contab[i].rq = 0; ! 203: contab[i].mx = 0; ! 204: contab[i].f = 0; ! 205: } ! 206: } ! 207: ! 208: ! 209: filep finds(mn) ! 210: register int mn; ! 211: { ! 212: register i; ! 213: register filep savip; ! 214: extern filep alloc(); ! 215: extern filep incoff(); ! 216: ! 217: oldmn = findmn(mn); ! 218: newmn = 0; ! 219: apptr = (filep)0; ! 220: if (app && oldmn >= 0 && contab[oldmn].mx) { ! 221: savip = ip; ! 222: ip = (filep)contab[oldmn].mx; ! 223: oldmn = -1; ! 224: while ((i = rbf()) != 0) ! 225: ; ! 226: apptr = ip; ! 227: if (!diflg) ! 228: ip = incoff(ip); ! 229: nextb = ip; ! 230: ip = savip; ! 231: } else { ! 232: for (i = 0; i < NM; i++) { ! 233: if (contab[i].rq == 0) ! 234: break; ! 235: } ! 236: if (i == NM || (nextb = alloc()) == 0) { ! 237: app = 0; ! 238: if (macerr++ > 1) ! 239: done2(02); ! 240: errprint("Too many (%d) string/macro names", NM); ! 241: edone(04); ! 242: return(offset = 0); ! 243: } ! 244: contab[i].mx = (unsigned) nextb; ! 245: if (!diflg) { ! 246: newmn = i; ! 247: if (oldmn == -1) ! 248: contab[i].rq = -1; ! 249: } else { ! 250: contab[i].rq = mn; ! 251: maddhash(&contab[i]); ! 252: } ! 253: } ! 254: app = 0; ! 255: return(offset = nextb); ! 256: } ! 257: ! 258: ! 259: skip() ! 260: { ! 261: register tchar i; ! 262: ! 263: while (cbits(i = getch()) == ' ') ! 264: ; ! 265: ch = i; ! 266: return(nlflg); ! 267: } ! 268: ! 269: ! 270: copyb() ! 271: { ! 272: register i, j, state; ! 273: register tchar ii; ! 274: int req, k; ! 275: filep savoff; ! 276: ! 277: if (skip() || !(j = getrq())) ! 278: j = '.'; ! 279: req = j; ! 280: k = j >> BYTE; ! 281: j &= BYTEMASK; ! 282: copyf++; ! 283: flushi(); ! 284: nlflg = 0; ! 285: state = 1; ! 286: ! 287: /* state 0 eat up ! 288: * state 1 look for . ! 289: * state 2 look for first char of end macro ! 290: * state 3 look for second char of end macro ! 291: */ ! 292: ! 293: while (1) { ! 294: i = cbits(ii = getch()); ! 295: if (state == 3) { ! 296: if (i == k) ! 297: break; ! 298: if (!k) { ! 299: ch = ii; ! 300: i = getach(); ! 301: ch = ii; ! 302: if (!i) ! 303: break; ! 304: } ! 305: state = 0; ! 306: goto c0; ! 307: } ! 308: if (i == '\n') { ! 309: state = 1; ! 310: nlflg = 0; ! 311: goto c0; ! 312: } ! 313: if (state == 1 && i == '.') { ! 314: state++; ! 315: savoff = offset; ! 316: goto c0; ! 317: } ! 318: if ((state == 2) && (i == j)) { ! 319: state++; ! 320: goto c0; ! 321: } ! 322: state = 0; ! 323: c0: ! 324: if (offset) ! 325: wbf(ii); ! 326: } ! 327: if (offset) { ! 328: wbfl(); ! 329: offset = savoff; ! 330: wbt((tchar)0); ! 331: } ! 332: copyf--; ! 333: return(req); ! 334: } ! 335: ! 336: ! 337: copys() ! 338: { ! 339: register tchar i; ! 340: ! 341: copyf++; ! 342: if (skip()) ! 343: goto c0; ! 344: if (cbits(i = getch()) != '"') ! 345: wbf(i); ! 346: while (cbits(i = getch()) != '\n') ! 347: wbf(i); ! 348: c0: ! 349: wbt((tchar)0); ! 350: copyf--; ! 351: } ! 352: ! 353: ! 354: filep alloc() /* return free blist[] block in nextb */ ! 355: { ! 356: register i; ! 357: register filep j; ! 358: ! 359: for (i = 0; i < NBLIST; i++) { ! 360: if (blist[i] == 0) ! 361: break; ! 362: } ! 363: if (i == NBLIST) { ! 364: j = 0; ! 365: } else { ! 366: blist[i] = -1; ! 367: j = (filep)i * BLK + ENV_BLK * BLK; ! 368: } ! 369: return(nextb = j); ! 370: } ! 371: ! 372: ! 373: ffree(i) /* free blist[i] and blocks pointed to */ ! 374: filep i; ! 375: { ! 376: register j; ! 377: ! 378: while (blist[j = blisti(i)] != (unsigned) ~0) { ! 379: i = (filep) blist[j]; ! 380: blist[j] = 0; ! 381: } ! 382: blist[j] = 0; ! 383: } ! 384: ! 385: wbt(i) ! 386: tchar i; ! 387: { ! 388: wbf(i); ! 389: wbfl(); ! 390: } ! 391: ! 392: ! 393: wbf(i) /* store i into blist[offset] */ ! 394: register tchar i; ! 395: { ! 396: register j; ! 397: ! 398: if (!offset) ! 399: return; ! 400: if (!woff) { ! 401: woff = offset; ! 402: #ifdef INCORE ! 403: wbuf = &corebuf[woff]; /* INCORE only */ ! 404: #endif ! 405: wbfi = 0; ! 406: } ! 407: wbuf[wbfi++] = i; ! 408: if (!((++offset) & (BLK - 1))) { ! 409: wbfl(); ! 410: j = blisti(--offset); ! 411: if (j < 0 || j >= NBLIST) { ! 412: errprint("Out of temp file space"); ! 413: done2(01); ! 414: } ! 415: if (blist[j] == (unsigned) ~0) { ! 416: if (alloc() == 0) { ! 417: errprint("Out of temp file space"); ! 418: done2(01); ! 419: } ! 420: blist[j] = (unsigned)(nextb); ! 421: } ! 422: offset = ((filep)blist[j]); ! 423: } ! 424: if (wbfi >= BLK) ! 425: wbfl(); ! 426: } ! 427: ! 428: ! 429: wbfl() /* flush current blist[] block */ ! 430: { ! 431: if (woff == 0) ! 432: return; ! 433: #ifndef INCORE ! 434: lseek(ibf, ((long)woff) * sizeof(tchar), 0); ! 435: write(ibf, (char *)wbuf, wbfi * sizeof(tchar)); ! 436: #endif ! 437: if ((woff & (~(BLK - 1))) == (roff & (~(BLK - 1)))) ! 438: roff = -1; ! 439: woff = 0; ! 440: } ! 441: ! 442: ! 443: tchar rbf() /* return next char from blist[] block */ ! 444: { ! 445: register tchar i; ! 446: register filep j, p; ! 447: extern filep incoff(); ! 448: ! 449: if (ip == NBLIST*BLK) { /* for rdtty */ ! 450: if (j = rdtty()) ! 451: return(j); ! 452: else ! 453: return(popi()); ! 454: } ! 455: /* this is an inline expansion of rbf0: dirty! */ ! 456: #ifndef INCORE ! 457: j = ip & ~(BLK - 1); ! 458: if (j != roff) { ! 459: roff = j; ! 460: lseek(ibf, (long)j * sizeof(tchar), 0); ! 461: if (read(ibf, (char *)rbuf, BLK * sizeof(tchar)) <= 0) ! 462: i = 0; ! 463: else ! 464: i = rbuf[ip & (BLK-1)]; ! 465: } else ! 466: i = rbuf[ip & (BLK-1)]; ! 467: #else ! 468: i = corebuf[ip]; ! 469: #endif ! 470: /* end of rbf0 */ ! 471: if (i == 0) { ! 472: if (!app) ! 473: i = popi(); ! 474: return(i); ! 475: } ! 476: /* this is an inline expansion of incoff: also dirty */ ! 477: p = ++ip; ! 478: if ((p & (BLK - 1)) == 0) { ! 479: if ((ip = blist[blisti(p-1)]) == (unsigned) ~0) { ! 480: ip = 0; ! 481: errprint("Bad storage allocation"); ! 482: done2(-5); ! 483: } ! 484: /* this was meant to protect against people removing ! 485: /* the macro they were standing on, but it's too ! 486: /* sensitive to block boundaries. ! 487: /* if (ip == 0) { ! 488: /* errprint("Block removed while in use"); ! 489: /* done2(-6); ! 490: /* } ! 491: */ ! 492: } ! 493: return(i); ! 494: } ! 495: ! 496: ! 497: tchar rbf0(p) ! 498: register filep p; ! 499: { ! 500: #ifndef INCORE ! 501: register filep i; ! 502: ! 503: if ((i = p & ~(BLK - 1)) != roff) { ! 504: roff = i; ! 505: lseek(ibf, (long)roff * sizeof(tchar), 0); ! 506: if (read(ibf, (char *)rbuf, BLK * sizeof(tchar)) == 0) ! 507: return(0); ! 508: } ! 509: return(rbuf[p & (BLK-1)]); ! 510: #else ! 511: return(corebuf[p]); ! 512: #endif ! 513: } ! 514: ! 515: ! 516: filep incoff(p) /* get next blist[] block */ ! 517: register filep p; ! 518: { ! 519: p++; ! 520: if ((p & (BLK - 1)) == 0) { ! 521: if ((p = blist[blisti(p-1)]) == (unsigned) ~0) { ! 522: errprint("Bad storage allocation"); ! 523: done2(-5); ! 524: } ! 525: } ! 526: return(p); ! 527: } ! 528: ! 529: ! 530: tchar popi() ! 531: { ! 532: register struct s *p; ! 533: ! 534: if (frame == stk) ! 535: return(0); ! 536: if (strflg) ! 537: strflg--; ! 538: p = nxf = frame; ! 539: p->nargs = 0; ! 540: frame = p->pframe; ! 541: ip = p->pip; ! 542: pendt = p->ppendt; ! 543: lastpbp = p->lastpbp; ! 544: return(p->pch); ! 545: } ! 546: ! 547: /* ! 548: * test that the end of the allocation is above a certain location ! 549: * in memory ! 550: */ ! 551: #define SPACETEST(base, size) while ((enda - (size)) <= (char *)(base)){setbrk(DELTA);} ! 552: ! 553: pushi(newip, mname) ! 554: filep newip; ! 555: int mname; ! 556: { ! 557: register struct s *p; ! 558: extern char *setbrk(); ! 559: ! 560: SPACETEST(nxf, sizeof(struct s)); ! 561: p = nxf; ! 562: p->pframe = frame; ! 563: p->pip = ip; ! 564: p->ppendt = pendt; ! 565: p->pch = ch; ! 566: p->lastpbp = lastpbp; ! 567: p->mname = mname; ! 568: lastpbp = pbp; ! 569: pendt = ch = 0; ! 570: frame = nxf; ! 571: if (nxf->nargs == 0) ! 572: nxf += 1; ! 573: else ! 574: nxf = (struct s *)argtop; ! 575: return(ip = newip); ! 576: } ! 577: ! 578: ! 579: char *setbrk(x) ! 580: int x; ! 581: { ! 582: register char *i, *k; ! 583: register j; ! 584: char *sbrk(); ! 585: ! 586: if ((i = sbrk(x)) == (char *) -1) { ! 587: errprint("Core limit reached"); ! 588: edone(0100); ! 589: } ! 590: if (j = (unsigned)i % sizeof(int)) { /*check alignment for 3B*/ ! 591: j = sizeof(int) - j; /*only init calls should need this*/ ! 592: if ((k = sbrk(j)) == (char *) -1) { ! 593: errprint("Core limit reached"); ! 594: edone(0100); ! 595: } ! 596: if (k != i + x) { /*there must have been an intervening sbrk*/ ! 597: errprint ("internal error in setbrk: i=%x, j=%d, k=%x", ! 598: i, j, k); ! 599: edone(0100); ! 600: } ! 601: i += j; ! 602: } ! 603: enda = i + x; ! 604: return(i); ! 605: } ! 606: ! 607: ! 608: getsn() ! 609: { ! 610: register i; ! 611: ! 612: if ((i = getach()) == 0) ! 613: return(0); ! 614: if (i == '(') ! 615: return(getrq()); ! 616: else ! 617: return(i); ! 618: } ! 619: ! 620: ! 621: setstr() ! 622: { ! 623: register i, j; ! 624: ! 625: lgf++; ! 626: if ((i = getsn()) == 0 || (j = findmn(i)) == -1 || !contab[j].mx) { ! 627: lgf--; ! 628: return(0); ! 629: } else { ! 630: SPACETEST(nxf, sizeof(struct s)); ! 631: nxf->nargs = 0; ! 632: strflg++; ! 633: lgf--; ! 634: return pushi((filep)contab[j].mx, i); ! 635: } ! 636: } ! 637: ! 638: ! 639: ! 640: collect() ! 641: { ! 642: register j; ! 643: register tchar i; ! 644: register tchar *strp; ! 645: tchar * lim; ! 646: tchar * *argpp, **argppend; ! 647: int quote; ! 648: struct s *savnxf; ! 649: ! 650: copyf++; ! 651: nxf->nargs = 0; ! 652: savnxf = nxf; ! 653: if (skip()) ! 654: goto rtn; ! 655: ! 656: { ! 657: char *memp; ! 658: memp = (char *)savnxf; ! 659: /* ! 660: * 1 s structure for the macro descriptor ! 661: * APERMAC tchar *'s for pointers into the strings ! 662: * space for the tchar's themselves ! 663: */ ! 664: memp += sizeof(struct s); ! 665: /* ! 666: * CPERMAC (the total # of characters for ALL arguments) ! 667: * to a macros, has been carefully chosen ! 668: * so that the distance between stack frames is < DELTA ! 669: */ ! 670: #define CPERMAC 200 ! 671: #define APERMAC 9 ! 672: memp += APERMAC * sizeof(tchar *); ! 673: memp += CPERMAC * sizeof(tchar); ! 674: nxf = (struct s*)memp; ! 675: } ! 676: lim = (tchar *)nxf; ! 677: argpp = (tchar **)(savnxf + 1); ! 678: argppend = &argpp[APERMAC]; ! 679: SPACETEST(argppend, sizeof(tchar *)); ! 680: strp = (tchar *)argppend; ! 681: /* ! 682: * Zero out all the string pointers before filling them in. ! 683: */ ! 684: for (j = 0; j < APERMAC; j++){ ! 685: argpp[j] = (tchar *)0; ! 686: } ! 687: #if 0 ! 688: errprint("savnxf=0x%x,nxf=0x%x,argpp=0x%x,strp=argppend=0x%x,lim=0x%x,enda=0x%x", ! 689: savnxf, nxf, argpp, strp, lim, enda); ! 690: #endif 0 ! 691: strflg = 0; ! 692: while (argpp != argppend && !skip()) { ! 693: *argpp++ = strp; ! 694: quote = 0; ! 695: if (cbits(i = getch()) == '"') ! 696: quote++; ! 697: else ! 698: ch = i; ! 699: while (1) { ! 700: i = getch(); ! 701: if (nlflg || (!quote && argpp != argppend && cbits(i) == ' ')) ! 702: break; /* collects rest into $9 */ ! 703: if ( quote ! 704: && cbits(i) == '"' ! 705: && cbits(i = getch()) != '"') { ! 706: ch = i; ! 707: break; ! 708: } ! 709: *strp++ = i; ! 710: if (strflg && strp >= lim) { ! 711: #if 0 ! 712: errprint("strp=0x%x, lim = 0x%x", ! 713: strp, lim); ! 714: #endif 0 ! 715: errprint("Macro argument too long"); ! 716: copyf--; ! 717: edone(004); ! 718: } ! 719: SPACETEST(strp, 3 * sizeof(tchar)); ! 720: } ! 721: *strp++ = 0; ! 722: } ! 723: nxf = savnxf; ! 724: nxf->nargs = argpp - (tchar **)(savnxf + 1); ! 725: argtop = strp; ! 726: rtn: ! 727: copyf--; ! 728: } ! 729: ! 730: ! 731: seta() ! 732: { ! 733: register i; ! 734: ! 735: i = cbits(getch()) - '0'; ! 736: if (i > 0 && i <= APERMAC && i <= frame->nargs) ! 737: pushback(*(((tchar **)(frame + 1)) + i - 1)); ! 738: } ! 739: ! 740: ! 741: caseda() ! 742: { ! 743: app++; ! 744: casedi(); ! 745: } ! 746: ! 747: ! 748: casedi() ! 749: { ! 750: register i, j; ! 751: register *k; ! 752: ! 753: lgf++; ! 754: if (skip() || (i = getrq()) == 0) { ! 755: if (dip != d) ! 756: wbt((tchar)0); ! 757: if (dilev > 0) { ! 758: numtab[DN].val = dip->dnl; ! 759: numtab[DL].val = dip->maxl; ! 760: dip = &d[--dilev]; ! 761: offset = dip->op; ! 762: } ! 763: goto rtn; ! 764: } ! 765: if (++dilev == NDI) { ! 766: --dilev; ! 767: errprint("Diversions nested too deep"); ! 768: edone(02); ! 769: } ! 770: if (dip != d) ! 771: wbt((tchar)0); ! 772: diflg++; ! 773: dip = &d[dilev]; ! 774: dip->op = finds(i); ! 775: dip->curd = i; ! 776: clrmn(oldmn); ! 777: k = (int *) & dip->dnl; ! 778: for (j = 0; j < 10; j++) ! 779: k[j] = 0; /*not op and curd*/ ! 780: rtn: ! 781: app = 0; ! 782: diflg = 0; ! 783: } ! 784: ! 785: ! 786: casedt() ! 787: { ! 788: lgf++; ! 789: dip->dimac = dip->ditrap = dip->ditf = 0; ! 790: skip(); ! 791: dip->ditrap = vnumb((int *)0); ! 792: if (nonumb) ! 793: return; ! 794: skip(); ! 795: dip->dimac = getrq(); ! 796: } ! 797: ! 798: ! 799: casetl() ! 800: { ! 801: register j; ! 802: int w[3]; ! 803: tchar buf[LNSIZE]; ! 804: register tchar *tp; ! 805: tchar i, delim; ! 806: ! 807: /* ! 808: * bug fix ! 809: * ! 810: * if .tl is the first thing in the file, the p1 ! 811: * doesn't come out, also the pagenumber will be 0 ! 812: * ! 813: * tends too confuse the device filter (and the user as well) ! 814: */ ! 815: if (dip == d && numtab[NL].val == -1) ! 816: newline(1); ! 817: dip->nls = 0; ! 818: skip(); ! 819: if (ismot(delim = getch())) { ! 820: ch = delim; ! 821: delim = '\''; ! 822: } else ! 823: delim = cbits(delim); ! 824: tp = buf; ! 825: numtab[HP].val = 0; ! 826: w[0] = w[1] = w[2] = 0; ! 827: j = 0; ! 828: while (cbits(i = getch()) != '\n') { ! 829: if (cbits(i) == cbits(delim)) { ! 830: if (j < 3) ! 831: w[j] = numtab[HP].val; ! 832: numtab[HP].val = 0; ! 833: j++; ! 834: *tp++ = 0; ! 835: } else { ! 836: if (cbits(i) == pagech) { ! 837: setn1(numtab[PN].val, numtab[findr('%')].fmt, ! 838: i&SFMASK); ! 839: continue; ! 840: } ! 841: numtab[HP].val += width(i); ! 842: if (tp < &buf[LNSIZE-10]) ! 843: *tp++ = i; ! 844: } ! 845: } ! 846: if (j<3) ! 847: w[j] = numtab[HP].val; ! 848: *tp++ = 0; ! 849: *tp++ = 0; ! 850: *tp++ = 0; ! 851: tp = buf; ! 852: #ifdef NROFF ! 853: horiz(po); ! 854: #endif ! 855: while (i = *tp++) ! 856: pchar(i); ! 857: if (w[1] || w[2]) ! 858: horiz(j = quant((lt - w[1]) / 2 - w[0], HOR)); ! 859: while (i = *tp++) ! 860: pchar(i); ! 861: if (w[2]) { ! 862: horiz(lt - w[0] - w[1] - w[2] - j); ! 863: while (i = *tp++) ! 864: pchar(i); ! 865: } ! 866: newline(0); ! 867: if (dip != d) { ! 868: if (dip->dnl > dip->hnl) ! 869: dip->hnl = dip->dnl; ! 870: } else { ! 871: if (numtab[NL].val > dip->hnl) ! 872: dip->hnl = numtab[NL].val; ! 873: } ! 874: } ! 875: ! 876: ! 877: casepc() ! 878: { ! 879: pagech = chget(IMP); ! 880: } ! 881: ! 882: ! 883: casepm() ! 884: { ! 885: register i, k; ! 886: register char *p; ! 887: int xx, cnt, tcnt, kk, tot; ! 888: filep j; ! 889: char pmline[10]; ! 890: ! 891: kk = cnt = tcnt = 0; ! 892: tot = !skip(); ! 893: for (i = 0; i < NM; i++) { ! 894: if ((xx = contab[i].rq) == 0 || contab[i].mx == 0) ! 895: continue; ! 896: tcnt++; ! 897: p = pmline; ! 898: j = (filep) contab[i].mx; ! 899: k = 1; ! 900: while ((j = blist[blisti(j)]) != (unsigned) ~0) { ! 901: k++; ! 902: } ! 903: cnt++; ! 904: kk += k; ! 905: if (!tot) { ! 906: *p++ = xx & 0177; ! 907: if (!(*p++ = (xx >> BYTE) & 0177)) ! 908: *(p - 1) = ' '; ! 909: *p++ = 0; ! 910: fdprintf(stderr, "%s %d\n", pmline, k); ! 911: } ! 912: } ! 913: fdprintf(stderr, "pm: total %d, macros %d, space %d\n", tcnt, cnt, kk); ! 914: } ! 915: ! 916: stackdump() /* dumps stack of macros in process */ ! 917: { ! 918: struct s *p; ! 919: ! 920: if (frame != stk) { ! 921: fdprintf(stderr, "stack: "); ! 922: for (p = frame; p != stk; p = p->pframe) ! 923: fdprintf(stderr, "%c%c ", p->mname&0177, (p->mname>>BYTE)&0177); ! 924: fdprintf(stderr, "\n"); ! 925: } ! 926: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.