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