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