n7.c 12 KB

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