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[] = "@(#)n7.c 4.6 (Berkeley) 05/02/91"; 10 #endif /* not lint */ 11 12 #include "tdef.h" 13 extern 14 #include "d.h" 15 extern 16 #include "v.h" 17 #ifdef NROFF 18 extern 19 #include "tw.h" 20 #endif 21 #include "sdef.h" 22 #ifdef NROFF 23 #define GETCH gettch 24 #endif 25 #ifndef NROFF 26 #define GETCH getch 27 #endif 28 29 /* 30 troff7.c 31 32 text 33 */ 34 35 extern struct s *frame, *stk; 36 extern struct s *ejl; 37 38 extern int pl; 39 extern int trap; 40 extern int flss; 41 extern int npnflg; 42 extern int npn; 43 extern int stop; 44 extern int nflush; 45 extern int ejf; 46 extern int ascii; 47 extern int donef; 48 extern int nc; 49 extern int wch; 50 extern int dpn; 51 extern int ndone; 52 extern int lss; 53 extern int pto; 54 extern int pfrom; 55 extern int print; 56 extern int nlistx[NTRAP]; 57 extern int mlist[NTRAP]; 58 extern int *pnp; 59 extern int nb; 60 extern int ic; 61 extern int icf; 62 extern int ics; 63 extern int ne; 64 extern int ll; 65 extern int un; 66 extern int un1; 67 extern int in; 68 extern int ls; 69 extern int spread; 70 extern int totout; 71 extern int nwd; 72 extern int *pendw; 73 extern int *linep; 74 extern int line[]; 75 extern int lastl; 76 extern int ch; 77 extern int ce; 78 extern int fi; 79 extern int nlflg; 80 extern int pendt; 81 extern int sps; 82 extern int adsp; 83 extern int pendnf; 84 extern int over; 85 extern int adrem; 86 extern int nel; 87 extern int ad; 88 extern int ohc; 89 extern int hyoff; 90 extern int nhyp; 91 extern int spflg; 92 extern int word[]; 93 extern int *wordp; 94 extern int wne; 95 extern int chbits; 96 extern int cwidth; 97 extern int widthp; 98 extern int hyf; 99 extern int xbitf; 100 extern int vflag; 101 extern int ul; 102 extern int cu; 103 extern int font; 104 extern int sfont; 105 extern int it; 106 extern int itmac; 107 extern int *hyptr[NHYP]; 108 extern int **hyp; 109 extern int *wdstart, *wdend; 110 extern int lnmod; 111 extern int admod; 112 extern int nn; 113 extern int nms; 114 extern int ndf; 115 extern int ni; 116 extern int nform; 117 extern int lnsize; 118 extern int po; 119 extern int ulbit; 120 extern int *vlist; 121 extern int nrbits; 122 extern int nmbits; 123 extern char trtab[]; 124 extern int xxx; 125 int brflg; 126 127 tbreak(){ 128 register *i, j, pad; 129 int res; 130 131 trap = 0; 132 if(nb)return; 133 if((dip == d) && (v.nl == -1)){ 134 newline(1); 135 return; 136 } 137 if(!nc){ 138 setnel(); 139 if(!wch)return; 140 if(pendw)getword(1); 141 movword(); 142 }else if(pendw && !brflg){ 143 getword(1); 144 movword(); 145 } 146 *linep = dip->nls = 0; 147 #ifdef NROFF 148 if(dip == d)horiz(po); 149 #endif 150 if(lnmod)donum(); 151 lastl = ne; 152 if(brflg != 1){ 153 totout = 0; 154 }else if(ad){ 155 if((lastl = (ll - un)) < ne)lastl = ne; 156 } 157 if(admod && ad && (brflg != 2)){ 158 lastl = ne; 159 adsp = adrem = 0; 160 #ifdef NROFF 161 if(admod == 1)un += quant(nel/2,t.Adj); 162 #endif 163 #ifndef NROFF 164 if(admod == 1)un += nel/2; 165 #endif 166 else if(admod ==2)un += nel; 167 } 168 totout++; 169 brflg = 0; 170 if((lastl+un) > dip->maxl)dip->maxl = (lastl+un); 171 horiz(un); 172 #ifdef NROFF 173 if(adrem%t.Adj)res = t.Hor; else res = t.Adj; 174 #endif 175 for(i = line;nc > 0;){ 176 if(((j = *i++) & CMASK) == ' '){ 177 pad = 0; 178 do{ 179 pad += width(j); 180 nc--; 181 }while(((j = *i++) & CMASK) == ' '); 182 i--; 183 pad += adsp; 184 --nwd; 185 if(adrem){ 186 if(adrem < 0){ 187 #ifdef NROFF 188 pad -= res; 189 adrem += res; 190 }else if((totout&01) || 191 ((adrem/res)>=(nwd))){ 192 pad += res; 193 adrem -= res; 194 #endif 195 #ifndef NROFF 196 pad--; 197 adrem++; 198 }else{ 199 pad++; 200 adrem--; 201 #endif 202 } 203 } 204 horiz(pad); 205 }else{ 206 pchar(j); 207 nc--; 208 } 209 } 210 if(ic){ 211 if((j = ll - un - lastl + ics) > 0)horiz(j); 212 pchar(ic); 213 } 214 if(icf)icf++; 215 else ic = 0; 216 ne = nwd = 0; 217 un = in; 218 setnel(); 219 newline(0); 220 if(dip != d){if(dip->dnl > dip->hnl)dip->hnl = dip->dnl;} 221 else{if(v.nl > dip->hnl)dip->hnl = v.nl;} 222 for(j=ls-1; (j >0) && !trap; j--)newline(0); 223 spread = 0; 224 } 225 donum(){ 226 register i, nw; 227 extern pchar(); 228 229 nrbits = nmbits; 230 nw = width('1' | nrbits); 231 if(nn){ 232 nn--; 233 goto d1; 234 } 235 if(v.ln%ndf){ 236 v.ln++; 237 d1: 238 un += nw*(3+nms+ni); 239 return; 240 } 241 i = 0; 242 if(v.ln<100)i++; 243 if(v.ln<10)i++; 244 horiz(nw*(ni+i)); 245 nform = 0; 246 fnumb(v.ln,pchar); 247 un += nw*nms; 248 v.ln++; 249 } 250 text(){ 251 register i; 252 static int spcnt; 253 254 nflush++; 255 if((dip == d) && (v.nl == -1)){newline(1); return;} 256 setnel(); 257 if(ce || !fi){ 258 nofill(); 259 return; 260 } 261 if(pendw)goto t4; 262 if(pendt)if(spcnt)goto t2; else goto t3; 263 pendt++; 264 if(spcnt)goto t2; 265 while(((i = GETCH()) & CMASK) == ' ')spcnt++; 266 if(nlflg){ 267 t1: 268 nflush = pendt = ch = spcnt = 0; 269 callsp(); 270 return; 271 } 272 ch = i; 273 if(spcnt){ 274 t2: 275 tbreak(); 276 if(nc || wch)goto rtn; 277 un += spcnt*sps; 278 spcnt = 0; 279 setnel(); 280 if(trap)goto rtn; 281 if(nlflg)goto t1; 282 } 283 t3: 284 if(spread)goto t5; 285 if(pendw || !wch) 286 t4: 287 if(getword(0))goto t6; 288 if(!movword())goto t3; 289 t5: 290 if(nlflg)pendt = 0; 291 adsp = adrem = 0; 292 if(ad){ 293 /* jfr */ if (nwd==1) adsp=nel; else adsp=nel/(nwd-1); 294 #ifdef NROFF 295 adsp = (adsp/t.Adj)*t.Adj; 296 #endif 297 adrem = nel - adsp*(nwd-1); 298 } 299 brflg = 1; 300 tbreak(); 301 spread = 0; 302 if(!trap)goto t3; 303 if(!nlflg)goto rtn; 304 t6: 305 pendt = 0; 306 ckul(); 307 rtn: 308 nflush = 0; 309 } 310 nofill(){ 311 register i, j; 312 313 if(!pendnf){ 314 over = 0; 315 tbreak(); 316 if(trap)goto rtn; 317 if(nlflg){ 318 ch = nflush = 0; 319 callsp(); 320 return; 321 } 322 adsp = adrem = 0; 323 nwd = 10000; 324 } 325 while((j = ((i = GETCH()) & CMASK)) != '\n'){ 326 if(j == ohc)continue; 327 if(j == CONT){ 328 pendnf++; 329 nflush = 0; 330 flushi(); 331 ckul(); 332 return; 333 } 334 storeline(i,-1); 335 } 336 if(ce){ 337 ce--; 338 if((i=quant(nel/2,HOR)) > 0)un += i; 339 } 340 if(!nc)storeline(FILLER,0); 341 brflg = 2; 342 tbreak(); 343 ckul(); 344 rtn: 345 pendnf = nflush = 0; 346 } 347 callsp(){ 348 register i; 349 350 if(flss)i = flss; else i = lss; 351 flss = 0; 352 casesp(i); 353 } 354 ckul(){ 355 if(ul && (--ul == 0)){ 356 cu = 0; 357 font = sfont; 358 mchbits(); 359 } 360 if(it && (--it == 0) && itmac)control(itmac,0); 361 } 362 storeline(c,w){ 363 register i; 364 365 if((c & CMASK) == JREG){ 366 if((i=findr(c>>BYTE)) != -1)vlist[i] = ne; 367 return; 368 } 369 if(linep >= (line + lnsize - 1)){ 370 if(!over){ 371 prstrfl("Line overflow.\n"); 372 over++; 373 c = 0343; 374 w = -1; 375 goto s1; 376 } 377 return; 378 } 379 s1: 380 if(w == -1)w = width(c); 381 ne += w; 382 nel -= w; 383 /* 384 * if( cu && !(c & MOT) && (trtab[(c & CMASK)] == ' ')) 385 * c = ((c & ~ulbit) & ~CMASK) | '_'; 386 */ 387 *linep++ = c; 388 nc++; 389 } 390 newline(a) 391 int a; 392 { 393 register i, j, nlss; 394 int opn; 395 396 if(a)goto nl1; 397 if(dip != d){ 398 j = lss; 399 pchar1(FLSS); 400 if(flss)lss = flss; 401 i = lss + dip->blss; 402 dip->dnl += i; 403 pchar1(i); 404 pchar1('\n'); 405 lss = j; 406 dip->blss = flss = 0; 407 if(dip->alss){ 408 pchar1(FLSS); 409 pchar1(dip->alss); 410 pchar1('\n'); 411 dip->dnl += dip->alss; 412 dip->alss = 0; 413 } 414 if(dip->ditrap && !dip->ditf && 415 (dip->dnl >= dip->ditrap) && dip->dimac) 416 if(control(dip->dimac,0)){trap++; dip->ditf++;} 417 return; 418 } 419 j = lss; 420 if(flss)lss = flss; 421 nlss = dip->alss + dip->blss + lss; 422 v.nl += nlss; 423 #ifndef NROFF 424 if(ascii){dip->alss = dip->blss = 0;} 425 #endif 426 pchar1('\n'); 427 flss = 0; 428 lss = j; 429 if(v.nl < pl)goto nl2; 430 nl1: 431 ejf = dip->hnl = v.nl = 0; 432 ejl = frame; 433 if(donef == 1){ 434 if((!nc && !wch) || ndone)done1(0); 435 ndone++; 436 donef = 0; 437 if(frame == stk)nflush++; 438 } 439 opn = v.pn; 440 v.pn++; 441 if(npnflg){ 442 v.pn = npn; 443 npn = npnflg = 0; 444 } 445 nlpn: 446 if(v.pn == pfrom){ 447 print++; 448 }else if(opn == pto || v.pn > pto){ 449 print = 0; 450 chkpn(); 451 goto nlpn; 452 } 453 if(stop && print){ 454 dpn++; 455 if(dpn >= stop){ 456 dpn = 0; 457 dostop(); 458 } 459 } 460 nl2: 461 trap = 0; 462 if(v.nl == 0){ 463 if((j = findn(0)) != NTRAP) 464 trap = control(mlist[j],0); 465 } else if((i = findt(v.nl-nlss)) <= nlss){ 466 if((j = findn1(v.nl-nlss+i)) == NTRAP){ 467 prstrfl("Trap botch.\n"); 468 done2(-5); 469 } 470 trap = control(mlist[j],0); 471 } 472 } 473 findn1(a) 474 int a; 475 { 476 register i, j; 477 478 for(i=0; i<NTRAP; i++){ 479 if(mlist[i]){ 480 if((j = nlistx[i]) < 0)j += pl; 481 if(j == a)break; 482 } 483 } 484 return(i); 485 } 486 chkpn(){ 487 pfrom = pto = *(pnp++); 488 if(pto == -1){ 489 flusho(); 490 done1(0); 491 } 492 if(pto == -2){ 493 print++; 494 pfrom = 0; 495 pto = 10000; 496 } 497 else if(pto & MOT){ 498 print++; 499 pto &= ~MOT; 500 pfrom = 0; 501 } 502 } 503 findt(a) 504 int a; 505 { 506 register i, j, k; 507 508 k = 32767; 509 if(dip != d){ 510 if(dip->dimac && ((i = dip->ditrap -a) > 0))k = i; 511 return(k); 512 } 513 for(i=0; i<NTRAP; i++){ 514 if(mlist[i]){ 515 if((j = nlistx[i]) < 0)j += pl; 516 if((j -= a) <= 0)continue; 517 if(j < k)k = j; 518 } 519 } 520 i = pl - a; 521 if(k > i)k = i; 522 return(k); 523 } 524 findt1(){ 525 register i; 526 527 if(dip != d)i = dip->dnl; 528 else i = v.nl; 529 return(findt(i)); 530 } 531 eject(a) 532 struct s *a; 533 { 534 register savlss; 535 536 if(dip != d)return; 537 ejf++; 538 if(a)ejl = a; 539 else ejl = frame; 540 if(trap)return; 541 e1: 542 savlss = lss; 543 lss = findt(v.nl); 544 newline(0); 545 lss = savlss; 546 if(v.nl && !trap)goto e1; 547 } 548 movword(){ 549 register i, w, *wp; 550 int savwch, hys; 551 552 over = 0; 553 wp = wordp; 554 if(!nwd){ 555 while(((i = *wp++) & CMASK) == ' '){ 556 wch--; 557 wne -= width(i); 558 } 559 wp--; 560 } 561 if((wne > nel) && 562 !hyoff && hyf && 563 (!nwd || (nel > 3*sps)) && 564 (!(hyf & 02) || (findt1() > lss)) 565 )hyphen(wp); 566 savwch = wch; 567 hyp = hyptr; 568 nhyp = 0; 569 while(*hyp && (*hyp <= wp))hyp++; 570 while(wch){ 571 if((hyoff != 1) && (*hyp == wp)){ 572 hyp++; 573 if(!wdstart || 574 ((wp > (wdstart+1)) && 575 (wp < wdend) && 576 (!(hyf & 04) || (wp < (wdend-1))) && 577 (!(hyf & 010) || (wp > (wdstart+2))) 578 ) 579 ){ 580 nhyp++; 581 storeline(IMP,0); 582 } 583 } 584 i = *wp++; 585 w = width(i); 586 wne -= w; 587 wch--; 588 storeline(i,w); 589 } 590 if(nel >= 0){ 591 nwd++; 592 return(0); 593 } 594 xbitf = 1; 595 hys = width(0200); /*hyphen*/ 596 m1: 597 if(!nhyp){ 598 if(!nwd)goto m3; 599 if(wch == savwch)goto m4; 600 } 601 if(*--linep != IMP)goto m5; 602 if(!(--nhyp)) 603 if(!nwd)goto m2; 604 if(nel < hys){ 605 nc--; 606 goto m1; 607 } 608 m2: 609 if(((i = *(linep-1) & CMASK) != '-') && 610 (i != 0203) 611 ){ 612 *linep = (*(linep-1) & ~CMASK) | 0200; 613 w = width(*linep); 614 nel -= w; 615 ne += w; 616 linep++; 617 /* 618 hsend(); 619 */ 620 } 621 m3: 622 nwd++; 623 m4: 624 wordp = wp; 625 return(1); 626 m5: 627 nc--; 628 w = width(*linep); 629 ne -= w; 630 nel += w; 631 wne += w; 632 wch++; 633 wp--; 634 goto m1; 635 } 636 horiz(i) 637 int i; 638 { 639 vflag = 0; 640 if(i)pchar(makem(i)); 641 } 642 setnel(){ 643 if(!nc){ 644 linep = line; 645 if(un1 >= 0){ 646 un = un1; 647 un1 = -1; 648 } 649 nel = ll - un; 650 ne = adsp = adrem = 0; 651 } 652 } 653 getword(x) 654 int x; 655 { 656 register i, j, swp; 657 int noword; 658 659 noword = 0; 660 if(x)if(pendw){ 661 *pendw = 0; 662 goto rtn; 663 } 664 if(wordp = pendw)goto g1; 665 hyp = hyptr; 666 wordp = word; 667 over = wne = wch = 0; 668 hyoff = 0; 669 while(1){ 670 j = (i = GETCH()) & CMASK; 671 if(j == '\n'){ 672 wne = wch = 0; 673 noword = 1; 674 goto rtn; 675 } 676 if(j == ohc){ 677 hyoff = 1; 678 continue; 679 } 680 if(j == ' '){ 681 storeword(i,width(i)); /* XXX */ 682 continue; 683 } 684 break; 685 } 686 swp = widthp; 687 storeword(' ' | chbits, -1); 688 if(spflg){ 689 storeword(' ' | chbits, -1); 690 spflg = 0; 691 } 692 widthp = swp; 693 g0: 694 if(j == CONT){ 695 pendw = wordp; 696 nflush = 0; 697 flushi(); 698 return(1); 699 } 700 if(hyoff != 1){ 701 if(j == ohc){ 702 hyoff = 2; 703 *hyp++ = wordp; 704 if(hyp > (hyptr+NHYP-1))hyp = hyptr+NHYP-1; 705 goto g1; 706 } 707 if((j == '-') || 708 (j == 0203) /*3/4 Em dash*/ 709 )if(wordp > word+1){ 710 hyoff = 2; 711 *hyp++ = wordp + 1; 712 if(hyp > (hyptr+NHYP-1))hyp = hyptr+NHYP-1; 713 } 714 } 715 storeword(i,width(i)); /* XXX */ 716 g1: 717 j = (i = GETCH()) & CMASK; 718 if(j != ' '){ 719 if(j != '\n')goto g0; 720 j = *(wordp-1) & CMASK; 721 if((j == '.') || 722 (j == '!') || 723 (j == '?'))spflg++; 724 } 725 *wordp = 0; 726 rtn: 727 wdstart = 0; 728 wordp = word; 729 pendw = 0; 730 *hyp++ = 0; 731 setnel(); 732 return(noword); 733 } 734 storeword(c,w) 735 int c, w; 736 { 737 738 if(wordp >= &word[WDSIZE - 1]){ 739 if(!over){ 740 prstrfl("Word overflow.\n"); 741 over++; 742 c = 0343; 743 w = -1; 744 goto s1; 745 } 746 return; 747 } 748 s1: 749 if(w == -1)w = width(c); 750 wne += w; 751 *wordp++ = c; 752 wch++; 753 } 754 #ifdef NROFF 755 extern char trtab[]; 756 gettch(){ 757 register int i, j; 758 759 if(!((i = getch()) & MOT) && (i & ulbit)){ 760 j = i&CMASK; 761 if(cu && (trtab[j] == ' ')) 762 i = ((i & ~ulbit)& ~CMASK) | '_'; 763 if(!cu && (j>32) && (j<0370) && !(*t.codetab[j-32] & 0200)) 764 i &= ~ulbit; 765 } 766 return(i); 767 } 768 #endif 769