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