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