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