|
|
1.1 ! root 1: /* ! 2: * n1.c ! 3: * ! 4: * consume options, initialization, main loop, ! 5: * input routines, escape function calling ! 6: */ ! 7: ! 8: #include <ctype.h> ! 9: #include <signal.h> ! 10: #include <sys/types.h> ! 11: #include <sys/stat.h> ! 12: #include <setjmp.h> ! 13: ! 14: #include "tdef.h" ! 15: #include "ext.h" ! 16: ! 17: #ifdef NROFF ! 18: #include "tw.h" ! 19: #endif ! 20: ! 21: jmp_buf sjbuf; ! 22: extern char *sprintf(); ! 23: static char *sprintn(); ! 24: static printn(); ! 25: filep ipl[NSO]; ! 26: long offl[NSO]; ! 27: long ioff; ! 28: char cfname[NSO+1][NS] = { "<standard input>" }; /*file name stack*/ ! 29: int cfline[NSO]; /*input line count stack*/ ! 30: char *progname; /* program name (troff) */ ! 31: ! 32: main(argc, argv) ! 33: int argc; ! 34: char **argv; ! 35: { ! 36: register char *p; ! 37: register j; ! 38: register tchar i; ! 39: extern catch(), kcatch(); ! 40: char **oargv, *getenv(); ! 41: ! 42: progname = argv[0]; ! 43: signal(SIGHUP, catch); ! 44: if (signal(SIGINT, catch) == SIG_IGN) { ! 45: signal(SIGHUP, SIG_IGN); ! 46: signal(SIGINT, SIG_IGN); ! 47: signal(SIGQUIT, SIG_IGN); ! 48: } ! 49: signal(SIGPIPE, catch); ! 50: signal(SIGTERM, kcatch); ! 51: oargv = argv; ! 52: mrehash(); ! 53: nrehash(); ! 54: init0(); ! 55: ! 56: #ifdef NROFF ! 57: if ((p = getenv("NROFFTERM")) != 0) ! 58: strcpy(devname, p); ! 59: #else ! 60: if ((p = getenv("TYPESETTER")) != 0) ! 61: strcpy(devname, p); ! 62: #endif ! 63: ! 64: while (--argc > 0 && (++argv)[0][0] == '-') ! 65: switch (argv[0][1]) { ! 66: ! 67: case 'F': /* switch font tables from default */ ! 68: if (argv[0][2] != '\0') { ! 69: strcpy(termtab, &argv[0][2]); ! 70: strcpy(fontdir, &argv[0][2]); ! 71: } else { ! 72: argv++; argc--; ! 73: strcpy(termtab, argv[0]); ! 74: strcpy(fontdir, argv[0]); ! 75: } ! 76: continue; ! 77: case 0: ! 78: goto start; ! 79: case 'i': ! 80: stdi++; ! 81: continue; ! 82: case 'q': ! 83: #ifdef NROFF ! 84: quiet++; ! 85: save_tty(); ! 86: #else ! 87: errprint("-q option ignored in troff"); ! 88: #endif NROFF ! 89: continue; ! 90: case 'n': ! 91: npn = ctoi(&argv[0][2]); ! 92: continue; ! 93: case 'u': /* set emboldening amount */ ! 94: bdtab[3] = ctoi(&argv[0][2]); ! 95: if (bdtab[3] < 0 || bdtab[3] > 50) ! 96: bdtab[3] = 0; ! 97: continue; ! 98: case 's': ! 99: if (!(stop = ctoi(&argv[0][2]))) ! 100: stop++; ! 101: continue; ! 102: case 'r': ! 103: eibuf = sprintf(ibuf+strlen(ibuf), ".nr %c %s\n", ! 104: argv[0][2], &argv[0][3]); ! 105: continue; ! 106: case 'c': ! 107: case 'm': ! 108: if (mflg++ >= NMF) { ! 109: errprint("Too many macro packages: %s", argv[0]); ! 110: continue; ! 111: } ! 112: strcpy (mfiles[nmfi], nextf); ! 113: strcat (mfiles[nmfi++], &argv[0][2]); ! 114: continue; ! 115: case 'o': ! 116: getpn(&argv[0][2]); ! 117: continue; ! 118: case 'T': ! 119: strcpy(devname, &argv[0][2]); ! 120: dotT++; ! 121: continue; ! 122: #ifdef NROFF ! 123: case 'h': ! 124: hflg++; ! 125: continue; ! 126: case 'z': ! 127: no_out++; ! 128: continue; ! 129: case 'e': ! 130: eqflg++; ! 131: continue; ! 132: #endif ! 133: #ifndef NROFF ! 134: case 'z': ! 135: no_out++; ! 136: case 'a': ! 137: ascii = 1; ! 138: nofeed++; ! 139: continue; ! 140: case 'f': ! 141: nofeed++; ! 142: continue; ! 143: #endif ! 144: default: ! 145: errprint("unknown option %s", argv[0]); ! 146: done(02); ! 147: } ! 148: ! 149: start: ! 150: init1(oargv[0][0]); ! 151: argp = argv; ! 152: rargc = argc; ! 153: nmfi = 0; ! 154: init2(); ! 155: setjmp(sjbuf); ! 156: loop: ! 157: copyf = lgf = nb = nflush = nlflg = 0; ! 158: if (ip && rbf0(ip) == 0 && ejf && frame->pframe <= ejl) { ! 159: nflush++; ! 160: trap = 0; ! 161: eject((struct s *)0); ! 162: goto loop; ! 163: } ! 164: i = getch(); ! 165: if (pendt) ! 166: goto Lt; ! 167: if ((j = cbits(i)) == XPAR) { ! 168: copyf++; ! 169: tflg++; ! 170: while (cbits(i) != '\n') ! 171: pchar(i = getch()); ! 172: tflg = 0; ! 173: copyf--; ! 174: goto loop; ! 175: } ! 176: if (j == cc || j == c2) { ! 177: if (j == c2) ! 178: nb++; ! 179: copyf++; ! 180: while ((j = cbits(i = getch())) == ' ' || j == '\t') ! 181: ; ! 182: ch = i; ! 183: copyf--; ! 184: control(getrq(), 1); ! 185: flushi(); ! 186: goto loop; ! 187: } ! 188: Lt: ! 189: ch = i; ! 190: text(); ! 191: if (nlflg) ! 192: numtab[HP].val = 0; ! 193: goto loop; ! 194: } ! 195: ! 196: ! 197: catch() ! 198: { ! 199: done3(01); ! 200: } ! 201: ! 202: ! 203: kcatch() ! 204: { ! 205: signal(SIGTERM, SIG_IGN); ! 206: done3(01); ! 207: } ! 208: ! 209: ! 210: init0() ! 211: { ! 212: eibuf = ibufp = ibuf; ! 213: ibuf[0] = 0; ! 214: numtab[NL].val = -1; ! 215: } ! 216: ! 217: ! 218: init1(a) ! 219: char a; ! 220: { ! 221: register char *p; ! 222: char *mktemp(); ! 223: register i; ! 224: ! 225: p = mktemp("/usr/tmp/trtmpXXXXX"); ! 226: if (a == 'a') ! 227: p = &p[9]; ! 228: if ((close(creat(p, 0600))) < 0) { ! 229: errprint("cannot create temp file."); ! 230: exit(-1); ! 231: } ! 232: ibf = open(p, 2); ! 233: unlkp = p; ! 234: for (i = NTRTAB; --i; ) ! 235: trtab[i] = i; ! 236: trtab[UNPAD] = ' '; ! 237: } ! 238: ! 239: ! 240: init2() ! 241: { ! 242: register i; ! 243: extern char *setbrk(); ! 244: ! 245: ttyod = 2; ! 246: iflg = 0; ! 247: obufp = obuf; ! 248: ptinit(); ! 249: mchbits(); ! 250: cvtime(); ! 251: numtab[PID].val = getpid(); ! 252: olinep = oline; ! 253: ioff = 0; ! 254: numtab[HP].val = init = 0; ! 255: numtab[NL].val = -1; ! 256: nfo = 0; ! 257: ifile = 0; ! 258: copyf = raw = 0; ! 259: eibuf = sprintf(ibuf+strlen(ibuf), ".ds .T %s\n", devname); ! 260: numtab[CD].val = -1; /* compensation */ ! 261: cpushback(ibuf); ! 262: ibufp = ibuf; ! 263: nx = mflg; ! 264: frame = stk = (struct s *)setbrk(DELTA); ! 265: dip = &d[0]; ! 266: nxf = frame + 1; ! 267: #ifdef INCORE ! 268: for (i = 0; i < NEV; i++) { ! 269: extern tchar corebuf[]; ! 270: envcopy((struct env *) &corebuf[i * sizeof(env)/sizeof(tchar)], &env); ! 271: } ! 272: #else ! 273: for (i = NEV; i--; ) ! 274: write(ibf, (char *) & env, sizeof(env)); ! 275: #endif ! 276: } ! 277: ! 278: #include <time.h> ! 279: ! 280: cvtime() ! 281: { ! 282: long tt; ! 283: struct tm *ltime, *localtime(); ! 284: ! 285: time(&tt); ! 286: ltime = localtime(&tt); ! 287: numtab[YR].val = ltime->tm_year; ! 288: numtab[MO].val = ltime->tm_mon + 1; /* troff uses 1..12 */ ! 289: numtab[DY].val = ltime->tm_mday; ! 290: numtab[DW].val = ltime->tm_wday + 1; /* troff uses 1..7 */ ! 291: ! 292: /* register i; ! 293: /* static int ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; ! 294: /* tt -= 3600 * ZONE; /* 5hrs for EST */ ! 295: /* numtab[DY].val = (tt / 86400L) + 1; ! 296: /* numtab[DW].val = (numtab[DY].val + 3) % 7 + 1; ! 297: /* for (numtab[YR].val = 70; ; numtab[YR].val++) { ! 298: /* if ((numtab[YR].val) % 4) ! 299: /* ms[1] = 28; ! 300: /* else ! 301: /* ms[1] = 29; ! 302: /* for (i = 0; i < 12; ) { ! 303: /* if (numtab[DY].val <= ms[i]) { ! 304: /* numtab[MO].val = i + 1; ! 305: /* return; ! 306: /* } ! 307: /* numtab[DY].val -= ms[i++]; ! 308: /* } ! 309: /* } ! 310: */ ! 311: } ! 312: ! 313: ! 314: ctoi(s) ! 315: register char *s; ! 316: { ! 317: register n; ! 318: ! 319: while (*s == ' ') ! 320: s++; ! 321: n = 0; ! 322: while (isdigit(*s)) ! 323: n = 10 * n + *s++ - '0'; ! 324: return n; ! 325: } ! 326: ! 327: ! 328: errprint(s, s1, s2, s3, s4, s5) /* error message printer */ ! 329: char *s, *s1, *s2, *s3, *s4, *s5; ! 330: { ! 331: fdprintf(stderr, "%s: ", progname); ! 332: fdprintf(stderr, s, s1, s2, s3, s4, s5); ! 333: if (numtab[CD].val > 0) ! 334: fdprintf(stderr, "; line %d, file %s", numtab[CD].val, cfname[ifi]); ! 335: fdprintf(stderr, "\n"); ! 336: stackdump(); ! 337: } ! 338: ! 339: ! 340: /* ! 341: * Scaled down version of C Library printf. ! 342: * Only %s %u %d (==%u) %o %c %x %D are recognized. ! 343: */ ! 344: #define putchar(n) (*pfbp++ = (n)) /* NO CHECKING! */ ! 345: ! 346: static char pfbuf[NTM]; ! 347: static char *pfbp = pfbuf; ! 348: int stderr = 2; /* NOT stdio value */ ! 349: ! 350: /* VARARGS2 */ ! 351: fdprintf(fd, fmt, x1) ! 352: int fd; ! 353: register char *fmt; ! 354: { ! 355: register c; ! 356: register char *adx; ! 357: char *s; ! 358: register i; ! 359: ! 360: pfbp = pfbuf; ! 361: adx = (char*)&x1; ! 362: loop: ! 363: while ((c = *fmt++) != '%') { ! 364: if (c == '\0') { ! 365: if (fd == stderr) ! 366: write(stderr, pfbuf, (int)(pfbp - pfbuf)); ! 367: else { ! 368: *pfbp = 0; ! 369: pfbp = pfbuf; ! 370: while (*pfbp) { ! 371: *obufp++ = *pfbp++; ! 372: if (obufp >= &obuf[OBUFSZ]) ! 373: flusho(); ! 374: } ! 375: } ! 376: return; ! 377: } ! 378: putchar(c); ! 379: } ! 380: c = *fmt++; ! 381: if (c == 'd') { ! 382: i = *(int*)adx; ! 383: if (i < 0) { ! 384: putchar('-'); ! 385: i = -i; ! 386: } ! 387: printn((long)i, 10); ! 388: adx += sizeof(int); ! 389: } else if (c == 'u' || c == 'o' || c == 'x') { ! 390: i = *(int*)adx; ! 391: printn((long)i, c == 'o' ? 8 : (c == 'x' ? 16 : 10)); ! 392: adx += sizeof(int); ! 393: } ! 394: else if (c == 'c') { ! 395: c = *(int*)adx & 0377; ! 396: if (c > 0177 || (c < 040 && c != '\n' && c != '\t')) ! 397: putchar('\\'); ! 398: putchar(c & 0177); ! 399: adx += sizeof(int); ! 400: } else if (c == 's') { ! 401: s = *(char**)adx; ! 402: while (c = *s++) ! 403: putchar(c); ! 404: adx += sizeof(char**); ! 405: } else if (c == 'D') { ! 406: printn(*(long*)adx, 10); ! 407: adx += sizeof(long); ! 408: } else if (c == 'O') { ! 409: printn(*(long*)adx, 8); ! 410: adx += sizeof(long); ! 411: } ! 412: goto loop; ! 413: } ! 414: ! 415: ! 416: /* ! 417: * Print an unsigned integer in base b. ! 418: */ ! 419: static printn(n, b) ! 420: register long n; ! 421: register b; ! 422: { ! 423: char s[20]; ! 424: register char *p; ! 425: register c; ! 426: ! 427: if (n < b) { ! 428: if(n >= 0) { ! 429: putchar("0123456789ABCDEF"[n]); ! 430: return; ! 431: } ! 432: putchar('-'); ! 433: n = -n; ! 434: } ! 435: p = s+20; ! 436: *--p = 0; ! 437: for(;;) { ! 438: *--p = "0123456789ABCDEF"[n % b]; ! 439: if(!(n /= b)) ! 440: break; ! 441: } ! 442: while(c = *p++) ! 443: putchar(c); ! 444: } ! 445: ! 446: /* scaled down version of library sprintf */ ! 447: /* same limits as fdprintf */ ! 448: /* returns pointer to \0 that ends the string */ ! 449: ! 450: /* VARARGS2 */ ! 451: char *sprintf(str, fmt, x1) ! 452: char *str; ! 453: char *fmt; ! 454: { ! 455: register c; ! 456: register char *adx; ! 457: char *s; ! 458: register i; ! 459: ! 460: adx = (char*)&x1; ! 461: loop: ! 462: while ((c = *fmt++) != '%') { ! 463: if (c == '\0') { ! 464: *str = 0; ! 465: return str; ! 466: } ! 467: *str++ = c; ! 468: } ! 469: c = *fmt++; ! 470: if (c == 'd') { ! 471: i = *(int*)adx; ! 472: if (i < 0) { ! 473: *str++ = '-'; ! 474: i = -i; ! 475: } ! 476: str = sprintn(str, (long)i, 10); ! 477: adx += sizeof(int); ! 478: } else if (c == 'u' || c == 'o' || c == 'x') { ! 479: i = *(int*)adx; ! 480: str = sprintn(str, (long)i, c == 'o' ? 8 : (c == 'x' ? 16 : 10)); ! 481: adx += sizeof(int); ! 482: } ! 483: else if (c == 'c') { ! 484: c = *(int*)adx & 0377; ! 485: if (c > 0177 || c < 040) ! 486: *str++ = '\\'; ! 487: *str++ = c & 0177; ! 488: adx += sizeof(int); ! 489: } else if (c == 's') { ! 490: s = *(char**)adx; ! 491: while (c = *s++) ! 492: *str++ = c; ! 493: adx += sizeof(char**); ! 494: } else if (c == 'D') { ! 495: str = sprintn(str, *(long*)adx, 10); ! 496: adx += sizeof(long); ! 497: } else if (c == 'O') { ! 498: str = sprintn(str, *(long*)adx, 8); ! 499: adx += sizeof(long); ! 500: } ! 501: goto loop; ! 502: } ! 503: ! 504: /* ! 505: * Print an unsigned integer in base b. ! 506: */ ! 507: static char *sprintn(s, n, b) ! 508: register char *s; ! 509: register long n; ! 510: { ! 511: register long a; ! 512: ! 513: if (n < 0) { /* shouldn't happen */ ! 514: *s++ = '-'; ! 515: n = -n; ! 516: } ! 517: if (a = n / b) ! 518: s = sprintn(s, a, b); ! 519: *s++ = "0123456789ABCDEF"[(int)(n%b)]; ! 520: return s; ! 521: } ! 522: ! 523: ! 524: control(a, b) ! 525: register int a, b; ! 526: { ! 527: register int j; ! 528: ! 529: if (a == 0 || (j = findmn(a)) == -1) ! 530: return(0); ! 531: if (contab[j].f == 0) { ! 532: nxf->nargs = 0; ! 533: if (b) ! 534: collect(); ! 535: flushi(); ! 536: return pushi(contab[j].mx, a); ! 537: } else if (b) ! 538: return((*contab[j].f)(0)); ! 539: else ! 540: return(0); ! 541: } ! 542: ! 543: ! 544: getrq() ! 545: { ! 546: register i, j; ! 547: ! 548: if (((i = getach()) == 0) || ((j = getach()) == 0)) ! 549: goto rtn; ! 550: i = PAIR(i, j); ! 551: rtn: ! 552: return(i); ! 553: } ! 554: ! 555: /* ! 556: * table encodes some special characters, to speed up tests ! 557: * in getchar, viz FLSS, RPT, f, \b, \n, fc, tabch, ldrch ! 558: */ ! 559: ! 560: char ! 561: gchtab[] = { ! 562: 000,004,000,000,010,000,000,000, /* fc, ldr */ ! 563: 001,002,001,000,001,000,000,000, /* \b, tab, nl, RPT */ ! 564: 000,000,000,000,000,000,000,000, ! 565: 000,001,000,000,000,000,000,000, /* FLSS */ ! 566: 000,000,000,000,000,000,000,000, ! 567: 000,000,000,000,000,000,000,000, ! 568: 000,000,000,000,000,000,000,000, ! 569: 000,000,000,000,000,000,000,000, ! 570: 000,000,000,000,000,000,000,000, ! 571: 000,000,000,000,000,000,000,000, ! 572: 000,000,000,000,000,000,000,000, ! 573: 000,000,000,000,000,000,000,000, ! 574: 000,000,000,000,000,000,001,000, /* f */ ! 575: 000,000,000,000,000,000,000,000, ! 576: 000,000,000,000,000,000,000,000, ! 577: 000,000,000,000,000,000,000,000, ! 578: }; ! 579: ! 580: tchar ! 581: getch() ! 582: { ! 583: register int k; ! 584: register tchar i, j; ! 585: tchar setht(), setslant(); ! 586: ! 587: g0: ! 588: if(ch) { ! 589: i = ch; ! 590: if (cbits(i) == '\n') ! 591: nlflg++; ! 592: ch = 0; ! 593: return(i); ! 594: } ! 595: ! 596: if (nlflg) ! 597: return('\n'); ! 598: i = getch0(); ! 599: if (ismot(i)) ! 600: return(i); ! 601: k = cbits(i); ! 602: if (k != ESC) { ! 603: if (k >= sizeof(gchtab)/sizeof(gchtab[0]) || gchtab[k] == 0) ! 604: return(i); ! 605: if (k == '\n') { ! 606: if (cbits(i) == '\n') { ! 607: nlflg++; ! 608: if (ip == 0) ! 609: numtab[CD].val++; /* line number */ ! 610: } ! 611: return(k); ! 612: } ! 613: if (k == FLSS) { ! 614: copyf++; ! 615: raw++; ! 616: i = getch0(); ! 617: if (!fi) ! 618: flss = i; ! 619: copyf--; ! 620: raw--; ! 621: goto g0; ! 622: } ! 623: if (k == RPT) { ! 624: setrpt(); ! 625: goto g0; ! 626: } ! 627: if (!copyf) { ! 628: if (k == 'f' && lg && !lgf) { ! 629: i = getlg(i); ! 630: return(i); ! 631: } ! 632: if (k == fc || k == tabch || k == ldrch) { ! 633: if ((i = setfield(k)) == 0) ! 634: goto g0; ! 635: else ! 636: return(i); ! 637: } ! 638: if (k == '\b') { ! 639: i = makem(-width(' ' | chbits)); ! 640: return(i); ! 641: } ! 642: } ! 643: return(i); ! 644: } ! 645: k = cbits(j = getch0()); ! 646: if (ismot(j)) ! 647: return(j); ! 648: switch (k) { ! 649: ! 650: case '\n': /* concealed newline */ ! 651: goto g0; ! 652: case 'n': /* number register */ ! 653: setn(); ! 654: goto g0; ! 655: case '*': /* string indicator */ ! 656: setstr(); ! 657: goto g0; ! 658: case '$': /* argument indicator */ ! 659: seta(); ! 660: goto g0; ! 661: case '{': /* LEFT */ ! 662: i = LEFT; ! 663: goto gx; ! 664: case '}': /* RIGHT */ ! 665: i = RIGHT; ! 666: goto gx; ! 667: case '"': /* comment */ ! 668: while (cbits(i = getch0()) != '\n') ! 669: ; ! 670: nlflg++; ! 671: if (ip == 0) ! 672: numtab[CD].val++; ! 673: return(i); ! 674: case ESC: /* double backslash */ ! 675: i = eschar; ! 676: goto gx; ! 677: case 'e': /* printable version of current eschar */ ! 678: i = PRESC; ! 679: goto gx; ! 680: case ' ': /* unpaddable space */ ! 681: i = UNPAD; ! 682: goto gx; ! 683: case '\'': /* \(aa */ ! 684: i = ACUTE; ! 685: goto gx; ! 686: case '`': /* \(ga */ ! 687: i = GRAVE; ! 688: goto gx; ! 689: case '_': /* \(ul */ ! 690: i = UNDERLINE; ! 691: goto gx; ! 692: case '-': /* current font minus */ ! 693: i = MINUS; ! 694: goto gx; ! 695: case '&': /* filler */ ! 696: i = FILLER; ! 697: goto gx; ! 698: case 'c': /* to be continued */ ! 699: i = CONT; ! 700: goto gx; ! 701: case '!': /* transparent indicator */ ! 702: i = XPAR; ! 703: goto gx; ! 704: case 't': /* tab */ ! 705: i = '\t'; ! 706: return(i); ! 707: case 'a': /* leader (SOH) */ ! 708: /* old: *pbp++ = LEADER; goto g0; */ ! 709: i = LEADER; ! 710: return i; ! 711: case '%': /* ohc */ ! 712: i = OHC; ! 713: return(i); ! 714: case 'g': /* return format of a number register */ ! 715: setaf(); ! 716: goto g0; ! 717: case '.': /* . */ ! 718: i = '.'; ! 719: gx: ! 720: setsfbits(i, sfbits(j)); ! 721: return(i); ! 722: } ! 723: if (copyf) { ! 724: *pbp++ = j; ! 725: return(eschar); ! 726: } ! 727: switch (k) { ! 728: ! 729: case 'p': /* spread */ ! 730: spread++; ! 731: goto g0; ! 732: case '(': /* special char name \(xx */ ! 733: case 'C': /* \C'...' */ ! 734: if ((i = setch(k)) == 0) ! 735: goto g0; ! 736: return(i); ! 737: case 'N': /* absolute character number */ ! 738: if ((i = setabs()) == 0) ! 739: goto g0; ! 740: return i; ! 741: case 's': /* size indicator */ ! 742: setps(); ! 743: goto g0; ! 744: case 'H': /* character height */ ! 745: return(setht()); ! 746: case 'S': /* slant */ ! 747: return(setslant()); ! 748: case 'f': /* font indicator */ ! 749: setfont(0); ! 750: goto g0; ! 751: case 'w': /* width function */ ! 752: setwd(); ! 753: goto g0; ! 754: case 'v': /* vert mot */ ! 755: if (i = vmot()) ! 756: return(i); ! 757: goto g0; ! 758: case 'h': /* horiz mot */ ! 759: if (i = hmot()) ! 760: return(i); ! 761: goto g0; ! 762: case 'z': /* zero with char */ ! 763: return(setz()); ! 764: case 'l': /* hor line */ ! 765: setline(); ! 766: goto g0; ! 767: case 'L': /* vert line */ ! 768: setvline(); ! 769: goto g0; ! 770: case 'D': /* drawing function */ ! 771: setdraw(); ! 772: goto g0; ! 773: case 'X': /* \X'...' for copy through */ ! 774: setxon(); ! 775: goto g0; ! 776: case 'b': /* bracket */ ! 777: setbra(); ! 778: goto g0; ! 779: case 'o': /* overstrike */ ! 780: setov(); ! 781: goto g0; ! 782: case 'k': /* mark hor place */ ! 783: if ((k = findr(getsn())) != -1) { ! 784: numtab[k].val = numtab[HP].val; ! 785: } ! 786: goto g0; ! 787: case '0': /* number space */ ! 788: return(makem(width('0' | chbits))); ! 789: #ifdef NROFF ! 790: case '|': ! 791: case '^': ! 792: goto g0; ! 793: #else ! 794: case '|': /* narrow space */ ! 795: return(makem((int)(EM)/6)); ! 796: case '^': /* half narrow space */ ! 797: return(makem((int)(EM)/12)); ! 798: #endif ! 799: case 'x': /* extra line space */ ! 800: if (i = xlss()) ! 801: return(i); ! 802: goto g0; ! 803: case 'u': /* half em up */ ! 804: case 'r': /* full em up */ ! 805: case 'd': /* half em down */ ! 806: return(sethl(k)); ! 807: default: ! 808: return(j); ! 809: } ! 810: /* NOTREACHED */ ! 811: } ! 812: ! 813: setxon() /* \X'...' for copy through */ ! 814: { ! 815: tchar xbuf[NC]; ! 816: register tchar *i; ! 817: tchar c; ! 818: int delim, k; ! 819: ! 820: if (ismot(c = getch())) ! 821: return; ! 822: delim = cbits(c); ! 823: i = xbuf; ! 824: *i++ = XON | chbits; ! 825: while ((k = cbits(c = getch())) != delim && k != '\n' && i < xbuf+NC-1) { ! 826: if (k == ' ') ! 827: setcbits(c, UNPAD); ! 828: *i++ = c | ZBIT; ! 829: } ! 830: *i++ = XOFF | chbits; ! 831: *i = 0; ! 832: pushback(xbuf); ! 833: } ! 834: ! 835: ! 836: char ifilt[32] = { ! 837: 0, 001, 002, 003, 0, 005, 006, 007, 010, 011, 012}; ! 838: ! 839: tchar ! 840: getch0() ! 841: { ! 842: register int j; ! 843: register tchar i; ! 844: ! 845: again: ! 846: if (pbp > lastpbp) ! 847: i = *--pbp; ! 848: else if (ip) { ! 849: #ifdef INCORE ! 850: extern tchar corebuf[]; ! 851: i = corebuf[ip]; ! 852: if (i == 0) ! 853: i = rbf(); ! 854: else { ! 855: if ((++ip & (BLK - 1)) == 0) { ! 856: --ip; ! 857: (void)rbf(); ! 858: } ! 859: } ! 860: #else ! 861: i = rbf(); ! 862: #endif ! 863: } else { ! 864: if (donef || ndone) ! 865: done(0); ! 866: if (nx || ibufp >= eibuf) { ! 867: if (nfo==0) { ! 868: g0: ! 869: if (nextfile()) { ! 870: if (ip) ! 871: goto again; ! 872: if (ibufp < eibuf) ! 873: goto g2; ! 874: } ! 875: } ! 876: nx = 0; ! 877: if ((j = read(ifile, ibuf, IBUFSZ)) <= 0) ! 878: goto g0; ! 879: ibufp = ibuf; ! 880: eibuf = ibuf + j; ! 881: if (ip) ! 882: goto again; ! 883: } ! 884: g2: ! 885: i = *ibufp++ & 0177; ! 886: ioff++; ! 887: if (i >= 040 && i < 0177) ! 888: goto g4; ! 889: if (i != 0177) ! 890: i = ifilt[i]; ! 891: } ! 892: if (cbits(i) == IMP && !raw) ! 893: goto again; ! 894: if ((i == 0 || i == 0177) && !init && !raw) { ! 895: goto again; ! 896: } ! 897: g4: ! 898: if (ismot(i)) ! 899: return i; ! 900: if (copyf == 0 && sfbits(i) == 0) ! 901: i |= chbits; ! 902: if (cbits(i) == eschar && !raw) ! 903: setcbits(i, ESC); ! 904: return(i); ! 905: } ! 906: ! 907: pushback(b) ! 908: register tchar *b; ! 909: { ! 910: register tchar *ob = b; ! 911: ! 912: while (*b++) ! 913: ; ! 914: b--; ! 915: while (b > ob && pbp < &pbbuf[NC-3]) ! 916: *pbp++ = *--b; ! 917: if (pbp >= &pbbuf[NC-3]) { ! 918: errprint("pushback overflow"); ! 919: done(2); ! 920: } ! 921: } ! 922: ! 923: cpushback(b) ! 924: register char *b; ! 925: { ! 926: register char *ob = b; ! 927: ! 928: while (*b++) ! 929: ; ! 930: b--; ! 931: while (b > ob && pbp < &pbbuf[NC-3]) ! 932: *pbp++ = *--b; ! 933: if (pbp >= &pbbuf[NC-3]) { ! 934: errprint("cpushback overflow"); ! 935: done(2); ! 936: } ! 937: } ! 938: ! 939: nextfile() ! 940: { ! 941: register char *p; ! 942: ! 943: n0: ! 944: if (ifile) ! 945: close(ifile); ! 946: if (nx || nmfi < mflg) { ! 947: p = mfiles[nmfi++]; ! 948: if (*p != 0) ! 949: goto n1; ! 950: } ! 951: if (ifi > 0) { ! 952: if (popf()) ! 953: goto n0; /* popf error */ ! 954: return(1); /* popf ok */ ! 955: } ! 956: if (rargc-- <= 0) { ! 957: if ((nfo -= mflg) && !stdi) ! 958: done(0); ! 959: nfo++; ! 960: numtab[CD].val = ifile = stdi = mflg = 0; ! 961: strcpy(cfname[ifi], "<standard input>"); ! 962: ioff = 0; ! 963: return(0); ! 964: } ! 965: p = (argp++)[0]; ! 966: n1: ! 967: numtab[CD].val = 0; ! 968: if (p[0] == '-' && p[1] == 0) { ! 969: ifile = 0; ! 970: strcpy(cfname[ifi], "<standard input>"); ! 971: } else if ((ifile = open(p, 0)) < 0) { ! 972: errprint("cannot open file %s", p); ! 973: nfo -= mflg; ! 974: done(02); ! 975: } else ! 976: strcpy(cfname[ifi],p); ! 977: nfo++; ! 978: ioff = 0; ! 979: return(0); ! 980: } ! 981: ! 982: ! 983: popf() ! 984: { ! 985: register i; ! 986: register char *p, *q; ! 987: ! 988: ioff = offl[--ifi]; ! 989: numtab[CD].val = cfline[ifi]; /*restore line counter*/ ! 990: ip = ipl[ifi]; ! 991: if ((ifile = ifl[ifi]) == 0) { ! 992: p = xbuf; ! 993: q = ibuf; ! 994: ibufp = xbufp; ! 995: eibuf = xeibuf; ! 996: while (q < eibuf) ! 997: *q++ = *p++; ! 998: return(0); ! 999: } ! 1000: if (lseek(ifile, (long)(ioff & ~(IBUFSZ-1)), 0) == (long) -1 ! 1001: || (i = read(ifile, ibuf, IBUFSZ)) < 0) ! 1002: return(1); ! 1003: eibuf = ibuf + i; ! 1004: ibufp = ibuf; ! 1005: /* ! 1006: if (ttyname(ifile) == 0) ! 1007: */ ! 1008: if ((ibufp = ibuf + (int)(ioff & (IBUFSZ - 1))) > eibuf) ! 1009: return(1); ! 1010: return(0); ! 1011: } ! 1012: ! 1013: ! 1014: flushi() ! 1015: { ! 1016: if (nflush) ! 1017: return; ! 1018: ch = 0; ! 1019: copyf++; ! 1020: while (!nlflg) { ! 1021: if (donef && (frame == stk)) ! 1022: break; ! 1023: getch(); ! 1024: } ! 1025: copyf--; ! 1026: } ! 1027: ! 1028: ! 1029: getach() ! 1030: { ! 1031: register tchar i; ! 1032: register j; ! 1033: ! 1034: lgf++; ! 1035: j = cbits(i = getch()); ! 1036: /* this test ought to be more general and more careful */ ! 1037: if (ismot(i) || j == ' ' || j == '\n' || j == RIGHT || j & 0200) { ! 1038: ch = i; ! 1039: j = 0; ! 1040: } ! 1041: lgf--; ! 1042: return(j & 0177); ! 1043: } ! 1044: ! 1045: ! 1046: casenx() ! 1047: { ! 1048: lgf++; ! 1049: skip(); ! 1050: getname(); ! 1051: nx++; ! 1052: if (nmfi > 0) ! 1053: nmfi--; ! 1054: strcpy(mfiles[nmfi], nextf); ! 1055: nextfile(); ! 1056: nlflg++; ! 1057: ip = 0; ! 1058: pendt = 0; ! 1059: frame = stk; ! 1060: nxf = frame + 1; ! 1061: } ! 1062: ! 1063: ! 1064: getname() ! 1065: { ! 1066: register int j, k; ! 1067: tchar i; ! 1068: ! 1069: lgf++; ! 1070: for (k = 0; k < (NS - 1); k++) { ! 1071: if (((j = cbits(i = getch())) <= ' ') || (j > 0176)) ! 1072: break; ! 1073: nextf[k] = j; ! 1074: } ! 1075: nextf[k] = 0; ! 1076: ch = i; ! 1077: lgf--; ! 1078: return(nextf[0]); ! 1079: } ! 1080: ! 1081: ! 1082: caseso() ! 1083: { ! 1084: register i; ! 1085: register char *p, *q; ! 1086: ! 1087: lgf++; ! 1088: nextf[0] = 0; ! 1089: if (skip() || !getname() || ((i = open(nextf, 0)) < 0) || (ifi >= NSO)) { ! 1090: errprint("can't open file %s", nextf); ! 1091: done(02); ! 1092: } ! 1093: strcpy(cfname[ifi+1], nextf); ! 1094: cfline[ifi] = numtab[CD].val; /*hold line counter*/ ! 1095: numtab[CD].val = 0; ! 1096: flushi(); ! 1097: ifl[ifi] = ifile; ! 1098: ifile = i; ! 1099: offl[ifi] = ioff; ! 1100: ioff = 0; ! 1101: ipl[ifi] = ip; ! 1102: ip = 0; ! 1103: nx++; ! 1104: nflush++; ! 1105: if (!ifl[ifi++]) { ! 1106: p = ibuf; ! 1107: q = xbuf; ! 1108: xbufp = ibufp; ! 1109: xeibuf = eibuf; ! 1110: while (p < eibuf) ! 1111: *q++ = *p++; ! 1112: } ! 1113: } ! 1114: ! 1115: caself() /* set line number and file */ ! 1116: { ! 1117: int n; ! 1118: ! 1119: if (skip()) ! 1120: return; ! 1121: n = atoi(); ! 1122: cfline[ifi] = numtab[CD].val = n - 2; ! 1123: if (skip()) ! 1124: return; ! 1125: if (getname()) ! 1126: strcpy(cfname[ifi], nextf); ! 1127: } ! 1128: ! 1129: ! 1130: casecf() ! 1131: { /* copy file without change */ ! 1132: #ifndef NROFF ! 1133: int fd, n; ! 1134: char buf[512]; ! 1135: extern int hpos, esc, po; ! 1136: ! 1137: lgf++; ! 1138: nextf[0] = 0; ! 1139: if (skip() || !getname() || (fd = open(nextf, 0)) < 0) { ! 1140: errprint("can't open file %s", nextf); ! 1141: done(02); ! 1142: } ! 1143: lgf--; ! 1144: /* make it into a clean state, be sure that everything is out */ ! 1145: tbreak(); ! 1146: hpos = po; ! 1147: esc = 0; ! 1148: ptesc(); /* to left margin */ ! 1149: esc = un; ! 1150: ptesc(); ! 1151: ptlead(); ! 1152: ptps(); ! 1153: ptfont(); ! 1154: flusho(); ! 1155: while ((n = read(fd, buf, sizeof buf)) > 0) ! 1156: write(ptid, buf, n); ! 1157: close(fd); ! 1158: ptps(); ! 1159: ptfont(); ! 1160: #endif ! 1161: } ! 1162: ! 1163: ! 1164: casesy() /* call system */ ! 1165: { ! 1166: char sybuf[NTM]; ! 1167: int i; ! 1168: ! 1169: lgf++; ! 1170: copyf++; ! 1171: skip(); ! 1172: for (i = 0; i < NTM - 2; i++) ! 1173: if ((sybuf[i] = getch()) == '\n' || sybuf[i] == RIGHT) ! 1174: break; ! 1175: sybuf[i] = 0; ! 1176: system(sybuf); ! 1177: copyf--; ! 1178: lgf--; ! 1179: } ! 1180: ! 1181: ! 1182: getpn(a) ! 1183: register char *a; ! 1184: { ! 1185: register int n, neg; ! 1186: ! 1187: if (*a == 0) ! 1188: return; ! 1189: neg = 0; ! 1190: for ( ; *a; a++) ! 1191: switch (*a) { ! 1192: case '+': ! 1193: case ',': ! 1194: continue; ! 1195: case '-': ! 1196: neg = 1; ! 1197: continue; ! 1198: default: ! 1199: n = 0; ! 1200: if (isdigit(*a)) { ! 1201: do ! 1202: n = 10 * n + *a++ - '0'; ! 1203: while (isdigit(*a)); ! 1204: a--; ! 1205: } else ! 1206: n = 9999; ! 1207: *pnp++ = neg ? -n : n; ! 1208: neg = 0; ! 1209: if (pnp >= &pnlist[NPN-2]) { ! 1210: errprint("too many page numbers"); ! 1211: done3(-3); ! 1212: } ! 1213: } ! 1214: if (neg) ! 1215: *pnp++ = -9999; ! 1216: *pnp = -32767; ! 1217: print = 0; ! 1218: pnp = pnlist; ! 1219: if (*pnp != -32767) ! 1220: chkpn(); ! 1221: } ! 1222: ! 1223: ! 1224: setrpt() ! 1225: { ! 1226: tchar i, j; ! 1227: ! 1228: copyf++; ! 1229: raw++; ! 1230: i = getch0(); ! 1231: copyf--; ! 1232: raw--; ! 1233: if (i < 0 || cbits(j = getch0()) == RPT) ! 1234: return; ! 1235: i &= BYTEMASK; ! 1236: while (i>0 && pbp < &pbbuf[NC-3]) { ! 1237: i--; ! 1238: *pbp++ = j; ! 1239: } ! 1240: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.