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