xref: /illumos-gate/usr/src/cmd/troff/n7.c (revision e0dcd5777d9e44d1373002785b840efbaa46e340)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28 /*	  All Rights Reserved	*/
29 
30 /*
31  * University Copyright- Copyright (c) 1982, 1986, 1988
32  * The Regents of the University of California
33  * All Rights Reserved
34  *
35  * University Acknowledgment- Portions of this document are derived from
36  * software developed by the University of California, Berkeley, and its
37  * contributors.
38  */
39 
40 #ifdef EUC
41 #ifdef NROFF
42 #include <stdlib.h>
43 #include <widec.h>
44 #include <limits.h>
45 #endif /* NROFF */
46 #endif /* EUC */
47 #include "tdef.h"
48 #ifdef NROFF
49 #include "tw.h"
50 #endif
51 #ifdef NROFF
52 #define GETCH gettch
53 tchar	gettch();
54 #endif
55 #ifndef NROFF
56 #define GETCH getch
57 #endif
58 
59 /*
60  * troff7.c
61  *
62  * text
63  */
64 
65 #include <ctype.h>
66 #ifdef EUC
67 #ifdef NROFF
68 #include <wctype.h>
69 #endif /* NROFF */
70 #endif /* EUC */
71 #include "ext.h"
72 #ifdef EUC
73 #ifdef NROFF
74 char	mbbuf2[MB_LEN_MAX + 1];
75 char	*mbbuf2p = mbbuf2;
76 tchar	mtbuf[MB_LEN_MAX + 1];
77 tchar	*mtbufp;
78 int	pendmb = 0;
79 wchar_t	cwc, owc, wceoll;
80 #endif /* NROFF */
81 #endif /* EUC */
82 int	brflg;
83 
84 int
tbreak()85 tbreak()
86 {
87 	int	pad, k;
88 	tchar	*i, j;
89 	int resol = 0;
90 #ifdef EUC
91 #ifdef NROFF
92 	tchar	l;
93 #endif /* NROFF */
94 #endif /* EUC */
95 
96 	trap = 0;
97 	if (nb)
98 		return (0);
99 	if (dip == d && numtab[NL].val == -1) {
100 		newline(1);
101 		return (0);
102 	}
103 	if (!nc) {
104 		setnel();
105 		if (!wch)
106 			return (0);
107 		if (pendw)
108 			getword(1);
109 		movword();
110 	} else if (pendw && !brflg) {
111 		getword(1);
112 		movword();
113 	}
114 	*linep = dip->nls = 0;
115 #ifdef NROFF
116 	if (dip == d)
117 		horiz(po);
118 #endif
119 	if (lnmod)
120 		donum();
121 	lastl = ne;
122 	if (brflg != 1) {
123 		totout = 0;
124 	} else if (ad) {
125 		if ((lastl = ll - un) < ne)
126 			lastl = ne;
127 	}
128 	if (admod && ad && (brflg != 2)) {
129 		lastl = ne;
130 		adsp = adrem = 0;
131 		if (admod == 1)
132 			un +=  quant(nel / 2, HOR);
133 		else if (admod == 2)
134 			un += nel;
135 	}
136 	totout++;
137 	brflg = 0;
138 	if (lastl + un > dip->maxl)
139 		dip->maxl = lastl + un;
140 	horiz(un);
141 #ifdef NROFF
142 	if (adrem % t.Adj)
143 		resol = t.Hor;
144 	else
145 		resol = t.Adj;
146 #else
147 	resol = HOR;
148 #endif
149 	adrem = (adrem / resol) * resol;
150 	for (i = line; nc > 0; ) {
151 #ifndef EUC
152 		if ((cbits(j = *i++)) == ' ') {
153 #else
154 #ifndef NROFF
155 		if ((cbits(j = *i++)) == ' ') {
156 #else
157 		if ((cbits(j = *i++) & ~MBMASK) == ' ') {
158 #endif /* NROFF */
159 #endif /* EUC */
160 			pad = 0;
161 			do {
162 				pad += width(j);
163 				nc--;
164 #ifndef EUC
165 			} while ((cbits(j = *i++)) == ' ');
166 #else
167 #ifndef NROFF
168 			} while ((cbits(j = *i++)) == ' ');
169 #else
170 			} while ((cbits(j = *i++) & ~MBMASK) == ' ');
171 #endif /* NROFF */
172 #endif /* EUC */
173 			i--;
174 			pad += adsp;
175 			--nwd;
176 			if (adrem) {
177 				if (adrem < 0) {
178 					pad -= resol;
179 					adrem += resol;
180 				} else if ((totout & 01) || adrem / resol >= nwd) {
181 					pad += resol;
182 					adrem -= resol;
183 				}
184 			}
185 			pchar((tchar) WORDSP);
186 			horiz(pad);
187 		} else {
188 			pchar(j);
189 			nc--;
190 		}
191 	}
192 	if (ic) {
193 		if ((k = ll - un - lastl + ics) > 0)
194 			horiz(k);
195 		pchar(ic);
196 	}
197 	if (icf)
198 		icf++;
199 	else
200 		ic = 0;
201 	ne = nwd = 0;
202 	un = in;
203 	setnel();
204 	newline(0);
205 	if (dip != d) {
206 		if (dip->dnl > dip->hnl)
207 			dip->hnl = dip->dnl;
208 	} else {
209 		if (numtab[NL].val > dip->hnl)
210 			dip->hnl = numtab[NL].val;
211 	}
212 	for (k = ls - 1; k > 0 && !trap; k--)
213 		newline(0);
214 	spread = 0;
215 
216 	return (0);
217 }
218 
219 int
donum()220 donum()
221 {
222 	int	i, nw;
223 	extern int pchar();
224 
225 	nrbits = nmbits;
226 	nw = width('1' | nrbits);
227 	if (nn) {
228 		nn--;
229 		goto d1;
230 	}
231 	if (numtab[LN].val % ndf) {
232 		numtab[LN].val++;
233 d1:
234 		un += nw * (3 + nms + ni);
235 		return (0);
236 	}
237 	i = 0;
238 	if (numtab[LN].val < 100)
239 		i++;
240 	if (numtab[LN].val < 10)
241 		i++;
242 	horiz(nw * (ni + i));
243 	nform = 0;
244 	fnumb(numtab[LN].val, pchar);
245 	un += nw * nms;
246 	numtab[LN].val++;
247 
248 	return (0);
249 }
250 
251 extern int logf;
252 
253 int
text()254 text()
255 {
256 	tchar i;
257 	static int	spcnt;
258 
259 	nflush++;
260 	numtab[HP].val = 0;
261 	if ((dip == d) && (numtab[NL].val == -1)) {
262 		newline(1);
263 		return (0);
264 	}
265 	setnel();
266 	if (ce || !fi) {
267 		nofill();
268 		return (0);
269 	}
270 	if (pendw)
271 		goto t4;
272 	if (pendt)
273 		if (spcnt)
274 			goto t2;
275 		else
276 			goto t3;
277 	pendt++;
278 	if (spcnt)
279 		goto t2;
280 	while ((cbits(i = GETCH())) == ' ') {
281 		spcnt++;
282 		numtab[HP].val += sps;
283 		widthp = sps;
284 	}
285 	if (nlflg) {
286 t1:
287 		nflush = pendt = ch = spcnt = 0;
288 		callsp();
289 		return (0);
290 	}
291 	ch = i;
292 	if (spcnt) {
293 t2:
294 		tbreak();
295 		if (nc || wch)
296 			goto rtn;
297 		un += spcnt * sps;
298 		spcnt = 0;
299 		setnel();
300 		if (trap)
301 			goto rtn;
302 		if (nlflg)
303 			goto t1;
304 	}
305 t3:
306 	if (spread)
307 		goto t5;
308 	if (pendw || !wch)
309 t4:
310 		if (getword(0))
311 			goto t6;
312 	if (!movword())
313 		goto t3;
314 t5:
315 	if (nlflg)
316 		pendt = 0;
317 	adsp = adrem = 0;
318 	if (ad) {
319 		if (nwd == 1)
320 			adsp = nel;
321 		else
322 			adsp = nel / (nwd - 1);
323 		adsp = (adsp / HOR) * HOR;
324 		adrem = nel - adsp*(nwd-1);
325 	}
326 	brflg = 1;
327 	tbreak();
328 	spread = 0;
329 	if (!trap)
330 		goto t3;
331 	if (!nlflg)
332 		goto rtn;
333 t6:
334 	pendt = 0;
335 	ckul();
336 rtn:
337 	nflush = 0;
338 
339 	return (0);
340 }
341 
342 
343 int
nofill()344 nofill()
345 {
346 	int	j;
347 	tchar i;
348 
349 	if (!pendnf) {
350 		over = 0;
351 		tbreak();
352 		if (trap)
353 			goto rtn;
354 		if (nlflg) {
355 			ch = nflush = 0;
356 			callsp();
357 			return (0);
358 		}
359 		adsp = adrem = 0;
360 		nwd = 10000;
361 	}
362 	while ((j = (cbits(i = GETCH()))) != '\n') {
363 		if (j == ohc)
364 			continue;
365 		if (j == CONT) {
366 			pendnf++;
367 			nflush = 0;
368 			flushi();
369 			ckul();
370 			return (0);
371 		}
372 		j = width(i);
373 		widthp = j;
374 		numtab[HP].val += j;
375 		storeline(i, j);
376 	}
377 	if (ce) {
378 		ce--;
379 		if ((i = quant(nel / 2, HOR)) > 0)
380 			un += i;
381 	}
382 	if (!nc)
383 		storeline((tchar)FILLER, 0);
384 	brflg = 2;
385 	tbreak();
386 	ckul();
387 rtn:
388 	pendnf = nflush = 0;
389 
390 	return (0);
391 }
392 
393 
394 int
callsp()395 callsp()
396 {
397 	int	i;
398 
399 	if (flss)
400 		i = flss;
401 	else
402 		i = lss;
403 	flss = 0;
404 	casesp(i);
405 
406 	return (0);
407 }
408 
409 
410 int
ckul()411 ckul()
412 {
413 	if (ul && (--ul == 0)) {
414 		cu = 0;
415 		font = sfont;
416 		mchbits();
417 	}
418 	if (it && (--it == 0) && itmac)
419 		control(itmac, 0);
420 
421 	return (0);
422 }
423 
424 
425 int
storeline(tchar c,int w)426 storeline(tchar c, int w)
427 {
428 	if (linep >= line + lnsize - 1) {
429 		if (!over) {
430 			flusho();
431 			errprint(gettext("Line overflow."));
432 			over++;
433 			c = LEFTHAND;
434 			w = -1;
435 			goto s1;
436 		}
437 		return (0);
438 	}
439 s1:
440 	if (w == -1)
441 		w = width(c);
442 	ne += w;
443 	nel -= w;
444 	*linep++ = c;
445 	nc++;
446 
447 	return (0);
448 }
449 
450 
451 int
newline(a)452 newline(a)
453 int	a;
454 {
455 	int	i, j, nlss;
456 	int	opn;
457 
458 	if (a)
459 		goto nl1;
460 	if (dip != d) {
461 		j = lss;
462 		pchar1((tchar)FLSS);
463 		if (flss)
464 			lss = flss;
465 		i = lss + dip->blss;
466 		dip->dnl += i;
467 		pchar1((tchar)i);
468 		pchar1((tchar)'\n');
469 		lss = j;
470 		dip->blss = flss = 0;
471 		if (dip->alss) {
472 			pchar1((tchar)FLSS);
473 			pchar1((tchar)dip->alss);
474 			pchar1((tchar)'\n');
475 			dip->dnl += dip->alss;
476 			dip->alss = 0;
477 		}
478 		if (dip->ditrap && !dip->ditf && dip->dnl >= dip->ditrap && dip->dimac)
479 			if (control(dip->dimac, 0)) {
480 				trap++;
481 				dip->ditf++;
482 			}
483 		return (0);
484 	}
485 	j = lss;
486 	if (flss)
487 		lss = flss;
488 	nlss = dip->alss + dip->blss + lss;
489 	numtab[NL].val += nlss;
490 #ifndef NROFF
491 	if (ascii) {
492 		dip->alss = dip->blss = 0;
493 	}
494 #endif
495 	pchar1((tchar)'\n');
496 	flss = 0;
497 	lss = j;
498 	if (numtab[NL].val < pl)
499 		goto nl2;
500 nl1:
501 	ejf = dip->hnl = numtab[NL].val = 0;
502 	ejl = frame;
503 	if (donef) {
504 		if ((!nc && !wch) || ndone)
505 			done1(0);
506 		ndone++;
507 		donef = 0;
508 		if (frame == stk)
509 			nflush++;
510 	}
511 	opn = numtab[PN].val;
512 	numtab[PN].val++;
513 	if (npnflg) {
514 		numtab[PN].val = npn;
515 		npn = npnflg = 0;
516 	}
517 nlpn:
518 	if (numtab[PN].val == pfrom) {
519 		print++;
520 		pfrom = -1;
521 	} else if (opn == pto) {
522 		print = 0;
523 		opn = -1;
524 		chkpn();
525 		goto nlpn;
526 	}
527 	if (print)
528 		newpage(numtab[PN].val);	/* supposedly in a clean state so can pause */
529 	if (stop && print) {
530 		dpn++;
531 		if (dpn >= stop) {
532 			dpn = 0;
533 			dostop();
534 		}
535 	}
536 nl2:
537 	trap = 0;
538 	if (numtab[NL].val == 0) {
539 		if ((j = findn(0)) != NTRAP)
540 			trap = control(mlist[j], 0);
541 	} else if ((i = findt(numtab[NL].val - nlss)) <= nlss) {
542 		if ((j = findn1(numtab[NL].val - nlss + i)) == NTRAP) {
543 			flusho();
544 			errprint(gettext("Trap botch."));
545 			done2(-5);
546 		}
547 		trap = control(mlist[j], 0);
548 	}
549 
550 	return (0);
551 }
552 
553 
554 int
findn1(a)555 findn1(a)
556 int	a;
557 {
558 	int	i, j;
559 
560 	for (i = 0; i < NTRAP; i++) {
561 		if (mlist[i]) {
562 			if ((j = nlist[i]) < 0)
563 				j += pl;
564 			if (j == a)
565 				break;
566 		}
567 	}
568 	return(i);
569 }
570 
571 int
chkpn()572 chkpn()
573 {
574 	pto = *(pnp++);
575 	pfrom = pto>=0 ? pto : -pto;
576 	if (pto == -32767) {
577 		flusho();
578 		done1(0);
579 	}
580 	if (pto < 0) {
581 		pto = -pto;
582 		print++;
583 		pfrom = 0;
584 	}
585 
586 	return (0);
587 }
588 
589 
590 int
findt(a)591 findt(a)
592 int	a;
593 {
594 	int	i, j, k;
595 
596 	k = 32767;
597 	if (dip != d) {
598 		if (dip->dimac && (i = dip->ditrap - a) > 0)
599 			k = i;
600 		return(k);
601 	}
602 	for (i = 0; i < NTRAP; i++) {
603 		if (mlist[i]) {
604 			if ((j = nlist[i]) < 0)
605 				j += pl;
606 			if ((j -= a) <= 0)
607 				continue;
608 			if (j < k)
609 				k = j;
610 		}
611 	}
612 	i = pl - a;
613 	if (k > i)
614 		k = i;
615 	return(k);
616 }
617 
618 
619 int
findt1()620 findt1()
621 {
622 	int	i;
623 
624 	if (dip != d)
625 		i = dip->dnl;
626 	else
627 		i = numtab[NL].val;
628 	return(findt(i));
629 }
630 
631 
632 int
eject(a)633 eject(a)
634 struct s *a;
635 {
636 	int	savlss;
637 
638 	if (dip != d)
639 		return (0);
640 	ejf++;
641 	if (a)
642 		ejl = a;
643 	else
644 		ejl = frame;
645 	if (trap)
646 		return (0);
647 e1:
648 	savlss = lss;
649 	lss = findt(numtab[NL].val);
650 	newline(0);
651 	lss = savlss;
652 	if (numtab[NL].val && !trap)
653 		goto e1;
654 
655 	return (0);
656 }
657 
658 
659 int
movword()660 movword()
661 {
662 	int	w;
663 	tchar i, *wp;
664 	int	savwch, hys;
665 
666 	over = 0;
667 	wp = wordp;
668 	if (!nwd) {
669 #ifndef EUC
670 		while (cbits(i = *wp++) == ' ') {
671 #else
672 #ifndef NROFF
673 		while (cbits(i = *wp++) == ' ') {
674 #else
675 		while ((cbits(i = *wp++) & ~MBMASK) == ' ') {
676 #endif /* NROFF */
677 #endif /* EUC */
678 			wch--;
679 			wne -= sps;
680 		}
681 		wp--;
682 	}
683 	if (wne > nel && !hyoff && hyf && (!nwd || nel > 3 * sps) &&
684 	   (!(hyf & 02) || (findt1() > lss)))
685 		hyphen(wp);
686 	savwch = wch;
687 	hyp = hyptr;
688 	nhyp = 0;
689 	while (*hyp && *hyp <= wp)
690 		hyp++;
691 	while (wch) {
692 		if (hyoff != 1 && *hyp == wp) {
693 			hyp++;
694 			if (!wdstart || (wp > wdstart + 1 && wp < wdend &&
695 			   (!(hyf & 04) || wp < wdend - 1) &&		/* 04 => last 2 */
696 			   (!(hyf & 010) || wp > wdstart + 2))) {	/* 010 => 1st 2 */
697 				nhyp++;
698 				storeline((tchar)IMP, 0);
699 			}
700 		}
701 		i = *wp++;
702 		w = width(i);
703 		wne -= w;
704 		wch--;
705 		storeline(i, w);
706 	}
707 	if (nel >= 0) {
708 		nwd++;
709 		return(0);	/* line didn't fill up */
710 	}
711 #ifndef NROFF
712 	xbits((tchar)HYPHEN, 1);
713 #endif
714 	hys = width((tchar)HYPHEN);
715 m1:
716 	if (!nhyp) {
717 		if (!nwd)
718 			goto m3;
719 		if (wch == savwch)
720 			goto m4;
721 	}
722 	if (*--linep != IMP)
723 		goto m5;
724 	if (!(--nhyp))
725 		if (!nwd)
726 			goto m2;
727 	if (nel < hys) {
728 		nc--;
729 		goto m1;
730 	}
731 m2:
732 	if ((i = cbits(*(linep - 1))) != '-' && i != EMDASH) {
733 		*linep = (*(linep - 1) & SFMASK) | HYPHEN;
734 		w = width(*linep);
735 		nel -= w;
736 		ne += w;
737 		linep++;
738 	}
739 m3:
740 	nwd++;
741 m4:
742 	wordp = wp;
743 	return(1);	/* line filled up */
744 m5:
745 	nc--;
746 	w = width(*linep);
747 	ne -= w;
748 	nel += w;
749 	wne += w;
750 	wch++;
751 	wp--;
752 	goto m1;
753 }
754 
755 
756 int
757 horiz(i)
758 int	i;
759 {
760 	vflag = 0;
761 	if (i)
762 		pchar(makem(i));
763 
764 	return (0);
765 }
766 
767 
768 int
769 setnel()
770 {
771 	if (!nc) {
772 		linep = line;
773 		if (un1 >= 0) {
774 			un = un1;
775 			un1 = -1;
776 		}
777 		nel = ll - un;
778 		ne = adsp = adrem = 0;
779 	}
780 
781 	return (0);
782 }
783 
784 int
785 getword(x)
786 int	x;
787 {
788 	int j, k;
789 	tchar i, *wp;
790 	int noword;
791 #ifdef EUC
792 #ifdef NROFF
793 	wchar_t *wddelim;
794 	char mbbuf3[MB_LEN_MAX + 1];
795 	char *mbbuf3p;
796 	int wbf, n;
797 	tchar m;
798 #endif /* NROFF */
799 #endif /* EUC */
800 
801 	noword = 0;
802 	if (x)
803 		if (pendw) {
804 			*pendw = 0;
805 			goto rtn;
806 		}
807 	if (wordp = pendw)
808 		goto g1;
809 	hyp = hyptr;
810 	wordp = word;
811 	over = wne = wch = 0;
812 	hyoff = 0;
813 #ifdef EUC
814 #ifdef NROFF
815 	mtbufp = mtbuf;
816 	if (pendmb) {
817 		while(*mtbufp) {
818 			switch(*mtbufp & MBMASK) {
819 			case LASTOFMB:
820 			case BYTE_CHR:
821 				storeword(*mtbufp++, -1);
822 				break;
823 
824 			default:
825 				storeword(*mtbufp++, 0);
826 			}
827 		}
828 		mtbufp = mtbuf;
829 		pendmb = 0;
830 		goto g1;
831 	}
832 #endif /* NROFF */
833 #endif /* EUC */
834 	while (1) {	/* picks up 1st char of word */
835 		j = cbits(i = GETCH());
836 #ifdef EUC
837 #ifdef NROFF
838 		if (multi_locale)
839 			if (collectmb(i))
840 				continue;
841 #endif /* NROFF */
842 #endif /* EUC */
843 		if (j == '\n') {
844 			wne = wch = 0;
845 			noword = 1;
846 			goto rtn;
847 		}
848 		if (j == ohc) {
849 			hyoff = 1;	/* 1 => don't hyphenate */
850 			continue;
851 		}
852 		if (j == ' ') {
853 			numtab[HP].val += sps;
854 			widthp = sps;
855 			storeword(i, sps);
856 			continue;
857 		}
858 		break;
859 	}
860 #ifdef EUC
861 #ifdef NROFF
862 	if (!multi_locale)
863 		goto a0;
864 	if (wddlm && iswprint(wceoll) && iswprint(cwc) &&
865 	    (!iswascii(wceoll) || !iswascii(cwc)) &&
866 	    !iswspace(wceoll) && !iswspace(cwc)) {
867 		wddelim = (*wddlm)(wceoll, cwc, 1);
868 		wceoll = 0;
869 		if (*wddelim != ' ') {
870 			if (!*wddelim) {
871 				storeword(((*wdbdg)(wceoll, cwc, 1) < 3) ?
872 					  ZWDELIM(1) : ZWDELIM(2), 0);
873 			} else {
874 				while (*wddelim) {
875 					if ((n = wctomb(mbbuf3, *wddelim++))
876 					    > 0) {
877 						mbbuf3[n] = 0;
878 						n--;
879 						mbbuf3p = mbbuf3 + n;
880 						while(n) {
881 							m = *(mbbuf3p-- - n--) &
882 							    0xff | MIDDLEOFMB |
883 							    ZBIT;
884 							storeword(m, 0);
885 						}
886 						m = *mbbuf3p & 0xff | LASTOFMB;
887 						storeword(m, -1);
888 					} else {
889 						storeword(' ' | chbits, sps);
890 						break;
891 					}
892 				}
893 			}
894 			spflg = 0;
895 			goto g0;
896 		}
897 	}
898 a0:
899 #endif /* NROFF */
900 #endif /* EUC */
901 	storeword(' ' | chbits, sps);
902 	if (spflg) {
903 		storeword(' ' | chbits, sps);
904 		spflg = 0;
905 	}
906 g0:
907 	if (j == CONT) {
908 		pendw = wordp;
909 		nflush = 0;
910 		flushi();
911 		return(1);
912 	}
913 	if (hyoff != 1) {
914 		if (j == ohc) {
915 			hyoff = 2;
916 			*hyp++ = wordp;
917 			if (hyp > (hyptr + NHYP - 1))
918 				hyp = hyptr + NHYP - 1;
919 			goto g1;
920 		}
921 		if (j == '-' || j == EMDASH)
922 			if (wordp > word + 1) {
923 				hyoff = 2;
924 				*hyp++ = wordp + 1;
925 				if (hyp > (hyptr + NHYP - 1))
926 					hyp = hyptr + NHYP - 1;
927 			}
928 	}
929 	j = width(i);
930 	numtab[HP].val += j;
931 #ifndef EUC
932 	storeword(i, j);
933 #else
934 #ifndef NROFF
935 	storeword(i, j);
936 #else
937 	if (multi_locale) {
938 		mtbufp = mtbuf;
939 		while(*mtbufp) {
940 			switch(*mtbufp & MBMASK) {
941 			case LASTOFMB:
942 			case BYTE_CHR:
943 				storeword(*mtbufp++, j);
944 				break;
945 
946 			default:
947 				storeword(*mtbufp++, 0);
948 			}
949 		}
950 		mtbufp = mtbuf;
951 	} else {
952 		storeword(i, j);
953 	}
954 #endif /* NROFF */
955 #endif /* EUC */
956 g1:
957 	j = cbits(i = GETCH());
958 #ifdef EUC
959 #ifdef NROFF
960 	if (multi_locale)
961 		if (collectmb(i))
962 			goto g1;
963 #endif /* NROFF */
964 #endif /* EUC */
965 	if (j != ' ') {
966 		static char *sentchar = ".?!:";	/* sentence terminators */
967 		if (j != '\n')
968 #ifdef EUC
969 #ifdef NROFF
970 			if (!multi_locale)
971 #endif /* NROFF */
972 #endif /* EUC */
973 			goto g0;
974 #ifdef EUC
975 #ifdef NROFF
976 			else {
977 				if (!wdbdg || (iswascii(cwc) && iswascii(owc)))
978 					goto g0;
979 				if ((wbf = (*wdbdg)(owc, cwc, 1)) < 5) {
980 					pendmb++;
981 					storeword((wbf < 3) ? ZWDELIM(1) :
982 						  ZWDELIM(2), 0);
983 					*wordp = 0;
984 					goto rtn;
985 				} else goto g0;
986 			}
987 #endif /* NROFF */
988 #endif /* EUC */
989 		wp = wordp-1;	/* handle extra space at end of sentence */
990 		while (wp >= word) {
991 			j = cbits(*wp--);
992 			if (j=='"' || j=='\'' || j==')' || j==']' || j=='*' || j==DAGGER)
993 				continue;
994 			for (k = 0; sentchar[k]; k++)
995 				if (j == sentchar[k]) {
996 					spflg++;
997 					break;
998 				}
999 			break;
1000 		}
1001 	}
1002 #ifdef EUC
1003 #ifdef NROFF
1004 	wceoll = owc;
1005 #endif /* NROFF */
1006 #endif /* EUC */
1007 	*wordp = 0;
1008 	numtab[HP].val += sps;
1009 rtn:
1010 	for (wp = word; *wp; wp++) {
1011 		j = cbits(*wp);
1012 		if (j == ' ')
1013 			continue;
1014 		if (!ischar(j) || (!isdigit(j) && j != '-'))
1015 			break;
1016 	}
1017 	if (*wp == 0)	/* all numbers, so don't hyphenate */
1018 		hyoff = 1;
1019 	wdstart = 0;
1020 	wordp = word;
1021 	pendw = 0;
1022 	*hyp++ = 0;
1023 	setnel();
1024 	return(noword);
1025 }
1026 
1027 
1028 int
1029 storeword(c, w)
1030 tchar c;
1031 int	w;
1032 {
1033 
1034 	if (wordp >= &word[WDSIZE - 3]) {
1035 		if (!over) {
1036 			flusho();
1037 			errprint(gettext("Word overflow."));
1038 			over++;
1039 			c = LEFTHAND;
1040 			w = -1;
1041 			goto s1;
1042 		}
1043 		return (0);
1044 	}
1045 s1:
1046 	if (w == -1)
1047 		w = width(c);
1048 	widthp = w;
1049 	wne += w;
1050 	*wordp++ = c;
1051 	wch++;
1052 
1053 	return (0);
1054 }
1055 
1056 
1057 #ifdef NROFF
1058 tchar gettch()
1059 {
1060 	extern int c_isalnum;
1061 	tchar i;
1062 	int j;
1063 
1064 	i = getch();
1065 	j = cbits(i);
1066 	if (ismot(i) || fbits(i) != ulfont)
1067 		return(i);
1068 	if (cu) {
1069 		if (trtab[j] == ' ') {
1070 			setcbits(i, '_');
1071 			setfbits(i, FT);	/* default */
1072 		}
1073 		return(i);
1074 	}
1075 	/* should test here for characters that ought to be underlined */
1076 	/* in the old nroff, that was the 200 bit on the width! */
1077 	/* for now, just do letters, digits and certain special chars */
1078 	if (j <= 127) {
1079 		if (!isalnum(j))
1080 			setfbits(i, FT);
1081 	} else {
1082 		if (j < c_isalnum)
1083 			setfbits(i, FT);
1084 	}
1085 	return(i);
1086 }
1087 
1088 
1089 #endif
1090 #ifdef EUC
1091 #ifdef NROFF
1092 int
1093 collectmb(i)
1094 tchar	i;
1095 {
1096 	int busy;
1097 
1098 	*mtbufp++ = i;
1099 	*mbbuf2p++ = i & BYTEMASK;
1100 	*mtbufp = *mbbuf2p = 0;
1101 	if (ismot(i)) {
1102 		mtbufp = mtbuf;
1103 		mbbuf2p = mbbuf2;
1104 		owc = 0;
1105 		cwc = 0;
1106 		return(busy = 0);
1107 	}
1108 	if ((i & MBMASK) == MIDDLEOFMB) {
1109 		if (mtbufp <= (mtbuf + MB_CUR_MAX)) {
1110 			busy = 1;
1111 		} else {
1112 			*(mtbufp - 1) &= ~MBMASK;
1113 			goto gotmb;
1114 		}
1115 	} else {
1116 		if ((i & MBMASK) == LASTOFMB)
1117 			*(mtbufp - 1) &= ~MBMASK;
1118 gotmb:
1119 		mtbufp = mtbuf;
1120 		owc = cwc;
1121 		if (mbtowc(&cwc, mbbuf2, MB_CUR_MAX) <= 0) {
1122 			mtbufp = mtbuf;
1123 			while (*mtbufp) {
1124 				setcbits(*mtbufp, (*mtbufp & 0x1ff));
1125 				mtbufp++;
1126 			}
1127 			mtbufp = mtbuf;
1128 		}
1129 		mbbuf2p = mbbuf2;
1130 		busy = 0;
1131 	}
1132 	return(busy);
1133 }
1134 
1135 
1136 #endif /* NROFF */
1137 #endif /* EUC */
1138