|
|
1.1 ! root 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(){}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.