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