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