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