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