1 #ifndef lint 2 static char sccsid[] = "@(#)n5.c 2.1 (CWI) 85/07/18"; 3 #endif lint 4 #include "tdef.h" 5 #include <sgtty.h> 6 #include "ext.h" 7 8 /* 9 * troff5.c 10 * 11 * misc processing requests 12 */ 13 14 int iflist[NIF]; 15 int ifx; 16 17 casead() 18 { 19 register i; 20 21 ad = 1; 22 /*leave admod alone*/ 23 if (skip()) 24 return; 25 switch (i = cbits(getch())) { 26 case 'r': /*right adj, left ragged*/ 27 admod = 2; 28 break; 29 case 'l': /*left adj, right ragged*/ 30 admod = ad = 0; /*same as casena*/ 31 break; 32 case 'c': /*centered adj*/ 33 admod = 1; 34 break; 35 case 'b': 36 case 'n': 37 admod = 0; 38 break; 39 case '0': 40 case '2': 41 case '4': 42 ad = 0; 43 case '1': 44 case '3': 45 case '5': 46 admod = (i - '0') / 2; 47 } 48 } 49 50 51 casena() 52 { 53 ad = 0; 54 } 55 56 57 casefi() 58 { 59 tbreak(); 60 fi++; 61 pendnf = 0; 62 lnsize = LNSIZE; 63 } 64 65 66 casenf() 67 { 68 tbreak(); 69 fi = 0; 70 } 71 72 73 casers() 74 { 75 dip->nls = 0; 76 } 77 78 79 casens() 80 { 81 dip->nls++; 82 } 83 84 85 chget(c) 86 int c; 87 { 88 tchar i; 89 90 if (skip() || ismot(i = getch()) || cbits(i) == ' ' || cbits(i) == '\n') { 91 ch = i; 92 return(c); 93 } else 94 return(i & BYTEMASK); 95 } 96 97 98 casecc() 99 { 100 cc = chget('.'); 101 } 102 103 104 casec2() 105 { 106 c2 = chget('\''); 107 } 108 109 110 casehc() 111 { 112 ohc = chget(OHC); 113 } 114 115 116 casetc() 117 { 118 tabc = chget(0); 119 } 120 121 122 caselc() 123 { 124 dotc = chget(0); 125 } 126 127 128 casehy() 129 { 130 register i; 131 132 hyf = 1; 133 if (skip()) 134 return; 135 noscale++; 136 i = atoi(); 137 noscale = 0; 138 if (nonumb) 139 return; 140 hyf = max(i, 0); 141 } 142 143 144 casenh() 145 { 146 hyf = 0; 147 } 148 149 150 max(aa, bb) 151 int aa, bb; 152 { 153 if (aa > bb) 154 return(aa); 155 else 156 return(bb); 157 } 158 159 160 casece() 161 { 162 register i; 163 164 noscale++; 165 skip(); 166 i = max(atoi(), 0); 167 if (nonumb) 168 i = 1; 169 tbreak(); 170 ce = i; 171 noscale = 0; 172 } 173 174 175 casein() 176 { 177 register i; 178 179 if (skip()) 180 i = in1; 181 else 182 i = max(hnumb(&in), 0); 183 tbreak(); 184 in1 = in; 185 in = i; 186 if (!nc) { 187 un = in; 188 setnel(); 189 } 190 } 191 192 193 casell() 194 { 195 register i; 196 197 if (skip()) 198 i = ll1; 199 else 200 i = max(hnumb(&ll), INCH / 10); 201 ll1 = ll; 202 ll = i; 203 setnel(); 204 } 205 206 207 caselt() 208 { 209 register i; 210 211 if (skip()) 212 i = lt1; 213 else 214 i = max(hnumb(<), 0); 215 lt1 = lt; 216 lt = i; 217 } 218 219 220 caseti() 221 { 222 register i; 223 224 if (skip()) 225 return; 226 i = max(hnumb(&in), 0); 227 tbreak(); 228 un1 = i; 229 setnel(); 230 } 231 232 233 casels() 234 { 235 register i; 236 237 noscale++; 238 if (skip()) 239 i = ls1; 240 else 241 i = max(inumb(&ls), 1); 242 ls1 = ls; 243 ls = i; 244 noscale = 0; 245 } 246 247 248 casepo() 249 { 250 register i; 251 252 if (skip()) 253 i = po1; 254 else 255 i = max(hnumb(&po), 0); 256 po1 = po; 257 po = i; 258 #ifndef NROFF 259 if (!ascii) 260 esc += po - po1; 261 #endif 262 } 263 264 265 casepl() 266 { 267 register i; 268 269 skip(); 270 if ((i = vnumb(&pl)) == 0) 271 pl = 11 * INCH; /*11in*/ 272 else 273 pl = i; 274 if (numtab[NL].val > pl) 275 numtab[NL].val = pl; 276 } 277 278 279 casewh() 280 { 281 register i, j, k; 282 283 lgf++; 284 skip(); 285 i = vnumb((int *)0); 286 if (nonumb) 287 return; 288 skip(); 289 j = getrq(); 290 if ((k = findn(i)) != NTRAP) { 291 mlist[k] = j; 292 return; 293 } 294 for (k = 0; k < NTRAP; k++) 295 if (mlist[k] == 0) 296 break; 297 if (k == NTRAP) { 298 flusho(); 299 errprint("cannot plant trap."); 300 return; 301 } 302 mlist[k] = j; 303 nlist[k] = i; 304 } 305 306 307 casech() 308 { 309 register i, j, k; 310 311 lgf++; 312 skip(); 313 if (!(j = getrq())) 314 return; 315 else 316 for (k = 0; k < NTRAP; k++) 317 if (mlist[k] == j) 318 break; 319 if (k == NTRAP) 320 return; 321 skip(); 322 i = vnumb((int *)0); 323 if (nonumb) 324 mlist[k] = 0; 325 nlist[k] = i; 326 } 327 328 329 findn(i) 330 int i; 331 { 332 register k; 333 334 for (k = 0; k < NTRAP; k++) 335 if ((nlist[k] == i) && (mlist[k] != 0)) 336 break; 337 return(k); 338 } 339 340 341 casepn() 342 { 343 register i; 344 345 skip(); 346 noscale++; 347 i = max(inumb(&numtab[PN].val), 0); 348 noscale = 0; 349 if (!nonumb) { 350 npn = i; 351 npnflg++; 352 } 353 } 354 355 356 casebp() 357 { 358 register i; 359 register struct s *savframe; 360 361 if (dip != d) 362 return; 363 savframe = frame; 364 skip(); 365 if ((i = inumb(&numtab[PN].val)) < 0) 366 i = 0; 367 tbreak(); 368 if (!nonumb) { 369 npn = i; 370 npnflg++; 371 } else if (dip->nls) 372 return; 373 eject(savframe); 374 } 375 376 377 casetm(ab) 378 int ab; 379 { 380 register i; 381 char tmbuf[NTM]; 382 383 lgf++; 384 copyf++; 385 skip(); 386 for (i = 0; i < NTM - 2; ) 387 if ((tmbuf[i++] = getch()) == '\n') 388 break; 389 if (i == NTM - 2) 390 tmbuf[i++] = '\n'; 391 tmbuf[i] = 0; 392 if (ab) /* truncate output */ 393 obufp = obuf; /* should be a function in n2.c */ 394 flusho(); 395 fdprintf(stderr, "%s", tmbuf); 396 copyf--; 397 lgf--; 398 } 399 400 401 casesp(a) 402 int a; 403 { 404 register i, j, savlss; 405 406 tbreak(); 407 if (dip->nls || trap) 408 return; 409 i = findt1(); 410 if (!a) { 411 skip(); 412 j = vnumb((int *)0); 413 if (nonumb) 414 j = lss; 415 } else 416 j = a; 417 if (j == 0) 418 return; 419 if (i < j) 420 j = i; 421 savlss = lss; 422 if (dip != d) 423 i = dip->dnl; 424 else 425 i = numtab[NL].val; 426 if ((i + j) < 0) 427 j = -i; 428 lss = j; 429 newline(0); 430 lss = savlss; 431 } 432 433 434 casert() 435 { 436 register a, *p; 437 438 skip(); 439 if (dip != d) 440 p = &dip->dnl; 441 else 442 p = &numtab[NL].val; 443 a = vnumb(p); 444 if (nonumb) 445 a = dip->mkline; 446 if ((a < 0) || (a >= *p)) 447 return; 448 nb++; 449 casesp(a - *p); 450 } 451 452 453 caseem() 454 { 455 lgf++; 456 skip(); 457 em = getrq(); 458 } 459 460 461 casefl() 462 { 463 tbreak(); 464 flusho(); 465 } 466 467 468 caseev() 469 { 470 register nxev; 471 472 if (skip()) { 473 e0: 474 if (evi == 0) 475 return; 476 nxev = evlist[--evi]; 477 goto e1; 478 } 479 noscale++; 480 nxev = atoi(); 481 noscale = 0; 482 if (nonumb) 483 goto e0; 484 flushi(); 485 if ((nxev >= NEV) || (nxev < 0) || (evi >= EVLSZ)) { 486 flusho(); 487 errprint("cannot do ev."); 488 if (error) 489 done2(040); 490 else 491 edone(040); 492 return; 493 } 494 evlist[evi++] = ev; 495 e1: 496 if (ev == nxev) 497 return; 498 lseek(ibf, ev * (long)sizeof(env), 0); 499 write(ibf, (char *) & env, sizeof(env)); 500 lseek(ibf, nxev * (long)sizeof(env), 0); 501 read(ibf, (char *) & env, sizeof(env)); 502 ev = nxev; 503 } 504 505 506 caseel() 507 { 508 if (--ifx < 0) { 509 ifx = 0; 510 iflist[0] = 0; 511 } 512 caseif(2); 513 } 514 515 516 caseie() 517 { 518 if (ifx >= NIF) { 519 errprint("if-else overflow."); 520 ifx = 0; 521 edone(040); 522 } 523 caseif(1); 524 ifx++; 525 } 526 527 528 caseif(x) 529 int x; 530 { 531 extern int falsef; 532 register notflag, true; 533 tchar i; 534 535 if (x == 2) { 536 notflag = 0; 537 true = iflist[ifx]; 538 goto i1; 539 } 540 true = 0; 541 skip(); 542 if ((cbits(i = getch())) == '!') { 543 notflag = 1; 544 } else { 545 notflag = 0; 546 ch = i; 547 } 548 i = atoi(); 549 if (!nonumb) { 550 if (i > 0) 551 true++; 552 goto i1; 553 } 554 i = getch(); 555 switch (cbits(i)) { 556 case 'e': 557 if (!(numtab[PN].val & 01)) 558 true++; 559 break; 560 case 'o': 561 if (numtab[PN].val & 01) 562 true++; 563 break; 564 #ifdef NROFF 565 case 'n': 566 true++; 567 case 't': 568 #endif 569 #ifndef NROFF 570 case 't': 571 true++; 572 case 'n': 573 #endif 574 case ' ': 575 break; 576 default: 577 true = cmpstr(i); 578 } 579 i1: 580 true ^= notflag; 581 if (x == 1) 582 iflist[ifx] = !true; 583 if (true) { 584 i2: 585 while ((cbits(i = getch())) == ' ') 586 ; 587 if (cbits(i) == LEFT) 588 goto i2; 589 ch = i; 590 nflush++; 591 } else { 592 copyf++; 593 falsef++; 594 eatblk(0); 595 copyf--; 596 falsef--; 597 } 598 } 599 600 eatblk(inblk) 601 int inblk; 602 { register int cnt, i; 603 604 cnt = 0; 605 do { 606 if (ch) { 607 i = cbits(ch); 608 ch = 0; 609 } else 610 i = cbits(getch0()); 611 if (i == ESC) 612 cnt++; 613 else { 614 if (cnt == 1) 615 switch (i) { 616 case '{': i = LEFT; break; 617 case '}': i = RIGHT; break; 618 case '\n': i = 'x'; break; 619 } 620 cnt = 0; 621 } 622 if (i == LEFT) eatblk(1); 623 } while ((!inblk && (i != '\n')) || (inblk && (i != RIGHT))); 624 if (i == '\n') 625 nlflg++; 626 } 627 628 629 cmpstr(c) 630 tchar c; 631 { 632 register j, delim; 633 register tchar i; 634 register val; 635 int savapts, savapts1, savfont, savfont1, savpts, savpts1; 636 tchar string[1280]; 637 register tchar *sp; 638 639 if (ismot(c)) 640 return(0); 641 delim = cbits(c); 642 savapts = apts; 643 savapts1 = apts1; 644 savfont = font; 645 savfont1 = font1; 646 savpts = pts; 647 savpts1 = pts1; 648 sp = string; 649 while ((j = cbits(i = getch()))!=delim && j!='\n' && sp<&string[1280-1]) 650 *sp++ = i; 651 if (sp >= string + 1280) { 652 errprint("too-long string compare."); 653 edone(0100); 654 } 655 if (nlflg) { 656 val = sp==string; 657 goto rtn; 658 } 659 *sp++ = 0; 660 apts = savapts; 661 apts1 = savapts1; 662 font = savfont; 663 font1 = savfont1; 664 pts = savpts; 665 pts1 = savpts1; 666 mchbits(); 667 val = 1; 668 sp = string; 669 while ((j = cbits(i = getch())) != delim && j != '\n') { 670 if (*sp != i) { 671 eat(delim); 672 val = 0; 673 goto rtn; 674 } 675 sp++; 676 } 677 if (*sp) 678 val = 0; 679 rtn: 680 apts = savapts; 681 apts1 = savapts1; 682 font = savfont; 683 font1 = savfont1; 684 pts = savpts; 685 pts1 = savpts1; 686 mchbits(); 687 return(val); 688 } 689 690 691 caserd() 692 { 693 694 lgf++; 695 skip(); 696 getname(); 697 if (!iflg) { 698 if (quiet) { 699 ttys.sg_flags &= ~ECHO; 700 stty(0, &ttys); 701 flusho(); 702 fdprintf(stderr, "\007"); /*bell*/ 703 } else { 704 if (nextf[0]) { 705 fdprintf(stderr, "%s:", nextf); 706 } else { 707 fdprintf(stderr, "\007"); /*bell*/ 708 } 709 } 710 } 711 collect(); 712 tty++; 713 pushi(NBLIST*BLK, PAIR('r','d')); 714 } 715 716 717 rdtty() 718 { 719 char onechar; 720 721 onechar = 0; 722 if (read(0, &onechar, 1) == 1) { 723 if (onechar == '\n') 724 tty++; 725 else 726 tty = 1; 727 if (tty != 3) 728 return(onechar); 729 } 730 popi(); 731 tty = 0; 732 if (quiet) { 733 ttys.sg_flags |= ECHO; 734 stty(0, &ttys); 735 } 736 return(0); 737 } 738 739 740 caseec() 741 { 742 eschar = chget('\\'); 743 } 744 745 746 caseeo() 747 { 748 eschar = 0; 749 } 750 751 752 caseta() 753 { 754 register i; 755 756 tabtab[0] = nonumb = 0; 757 for (i = 0; ((i < (NTAB - 1)) && !nonumb); i++) { 758 if (skip()) 759 break; 760 tabtab[i] = max(hnumb(&tabtab[max(i-1,0)]), 0) & TABMASK; 761 if (!nonumb) 762 switch (cbits(ch)) { 763 case 'C': 764 tabtab[i] |= CTAB; 765 break; 766 case 'R': 767 tabtab[i] |= RTAB; 768 break; 769 default: /*includes L*/ 770 break; 771 } 772 nonumb = ch = 0; 773 } 774 tabtab[i] = 0; 775 } 776 777 778 casene() 779 { 780 register i, j; 781 782 skip(); 783 i = vnumb((int *)0); 784 if (nonumb) 785 i = lss; 786 if (i > (j = findt1())) { 787 i = lss; 788 lss = j; 789 dip->nls = 0; 790 newline(0); 791 lss = i; 792 } 793 } 794 795 796 casetr() 797 { 798 register i, j; 799 tchar k; 800 801 lgf++; 802 skip(); 803 while ((i = cbits(k=getch())) != '\n') { 804 if (ismot(k)) 805 return; 806 if (ismot(k = getch())) 807 return; 808 if ((j = cbits(k)) == '\n') 809 j = ' '; 810 trtab[i] = j; 811 } 812 } 813 814 815 casecu() 816 { 817 cu++; 818 caseul(); 819 } 820 821 822 caseul() 823 { 824 register i; 825 826 noscale++; 827 if (skip()) 828 i = 1; 829 else 830 i = atoi(); 831 if (ul && (i == 0)) { 832 font = sfont; 833 ul = cu = 0; 834 } 835 if (i) { 836 if (!ul) { 837 sfont = font; 838 font = ulfont; 839 } 840 ul = i; 841 } 842 noscale = 0; 843 mchbits(); 844 } 845 846 847 caseuf() 848 { 849 register i, j; 850 851 if (skip() || !(i = getrq()) || i == 'S' || (j = findft(i)) == -1) 852 ulfont = ULFONT; /*default underline position*/ 853 else 854 ulfont = j; 855 #ifdef NROFF 856 if (ulfont == FT) 857 ulfont = ULFONT; 858 #endif 859 } 860 861 862 caseit() 863 { 864 register i; 865 866 lgf++; 867 it = itmac = 0; 868 noscale++; 869 skip(); 870 i = atoi(); 871 skip(); 872 if (!nonumb && (itmac = getrq())) 873 it = i; 874 noscale = 0; 875 } 876 877 878 casemc() 879 { 880 register i; 881 882 if (icf > 1) 883 ic = 0; 884 icf = 0; 885 if (skip()) 886 return; 887 ic = getch(); 888 icf = 1; 889 skip(); 890 i = max(hnumb((int *)0), 0); 891 if (!nonumb) 892 ics = i; 893 } 894 895 896 casemk() 897 { 898 register i, j; 899 900 if (dip != d) 901 j = dip->dnl; 902 else 903 j = numtab[NL].val; 904 if (skip()) { 905 dip->mkline = j; 906 return; 907 } 908 if ((i = getrq()) == 0) 909 return; 910 numtab[findr(i)].val = j; 911 } 912 913 914 casesv() 915 { 916 register i; 917 918 skip(); 919 if ((i = vnumb((int *)0)) < 0) 920 return; 921 if (nonumb) 922 i = 1; 923 sv += i; 924 caseos(); 925 } 926 927 928 caseos() 929 { 930 register savlss; 931 932 if (sv <= findt1()) { 933 savlss = lss; 934 lss = sv; 935 newline(0); 936 lss = savlss; 937 sv = 0; 938 } 939 } 940 941 942 casenm() 943 { 944 register i; 945 946 lnmod = nn = 0; 947 if (skip()) 948 return; 949 lnmod++; 950 noscale++; 951 i = inumb(&numtab[LN].val); 952 if (!nonumb) 953 numtab[LN].val = max(i, 0); 954 getnm(&ndf, 1); 955 getnm(&nms, 0); 956 getnm(&ni, 0); 957 noscale = 0; 958 nmbits = chbits; 959 } 960 961 962 getnm(p, min) 963 int *p, min; 964 { 965 register i; 966 967 eat(' '); 968 if (skip()) 969 return; 970 i = atoi(); 971 if (nonumb) 972 return; 973 *p = max(i, min); 974 } 975 976 977 casenn() 978 { 979 noscale++; 980 skip(); 981 nn = max(atoi(), 1); 982 noscale = 0; 983 } 984 985 986 caseab() 987 { 988 casetm(1); 989 done3(0); 990 } 991