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