document distributed with 4.1BSD
[unix-history] / usr / src / old / roff / common_source / n7.c
CommitLineData
7965bccf
RH
1#ifndef lint
2static char sccsid[] = "@(#)n7.c 4.1 %G%";
3#endif lint
4
5#include "tdef.h"
6extern
7#include "d.h"
8extern
9#include "v.h"
10#ifdef NROFF
11extern
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/*
23troff7.c
24
25text
26*/
27
28extern struct s *frame, *stk;
29extern struct s *ejl;
30
31extern int pl;
32extern int trap;
33extern int flss;
34extern int npnflg;
35extern int npn;
36extern int stop;
37extern int nflush;
38extern int ejf;
39extern int ascii;
40extern int donef;
41extern int nc;
42extern int wch;
43extern int dpn;
44extern int ndone;
45extern int lss;
46extern int pto;
47extern int pfrom;
48extern int print;
49extern int nlist[NTRAP];
50extern int mlist[NTRAP];
51extern int *pnp;
52extern int nb;
53extern int ic;
54extern int icf;
55extern int ics;
56extern int ne;
57extern int ll;
58extern int un;
59extern int un1;
60extern int in;
61extern int ls;
62extern int spread;
63extern int totout;
64extern int nwd;
65extern int *pendw;
66extern int *linep;
67extern int line[];
68extern int lastl;
69extern int ch;
70extern int ce;
71extern int fi;
72extern int nlflg;
73extern int pendt;
74extern int sps;
75extern int adsp;
76extern int pendnf;
77extern int over;
78extern int adrem;
79extern int nel;
80extern int ad;
81extern int ohc;
82extern int hyoff;
83extern int nhyp;
84extern int spflg;
85extern int word[];
86extern int *wordp;
87extern int wne;
88extern int chbits;
89extern int cwidth;
90extern int widthp;
91extern int hyf;
92extern int xbitf;
93extern int vflag;
94extern int ul;
95extern int cu;
96extern int font;
97extern int sfont;
98extern int it;
99extern int itmac;
100extern int *hyptr[NHYP];
101extern int **hyp;
102extern int *wdstart, *wdend;
103extern int lnmod;
104extern int admod;
105extern int nn;
106extern int nms;
107extern int ndf;
108extern int ni;
109extern int nform;
110extern int lnsize;
111extern int po;
112extern int ulbit;
113extern int *vlist;
114extern int nrbits;
115extern int nmbits;
116extern char trtab[];
117extern int xxx;
118int brflg;
119
120tbreak(){
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}
218donum(){
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}
243text(){
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 }
276t3:
277 if(spread)goto t5;
278 if(pendw || !wch)
279 t4:
280 if(getword(0))goto t6;
281 if(!movword())goto t3;
282t5:
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;
297t6:
298 pendt = 0;
299 ckul();
300rtn:
301 nflush = 0;
302}
303nofill(){
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();
337rtn:
338 pendnf = nflush = 0;
339}
340callsp(){
341 register i;
342
343 if(flss)i = flss; else i = lss;
344 flss = 0;
345 casesp(i);
346}
347ckul(){
348 if(ul && (--ul == 0)){
349 cu = 0;
350 font = sfont;
351 mchbits();
352 }
353 if(it && (--it == 0) && itmac)control(itmac,0);
354}
355storeline(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 }
372s1:
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}
383newline(a)
384int 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;
423nl1:
424 ejf = dip->hnl = v.nl = 0;
425 ejl = frame;
426 if(donef){
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 }
438nlpn:
439 if(v.pn == pfrom){
440 print++;
441 pfrom = -1;
442 }else if(opn == 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 }
455nl2:
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}
468findn1(a)
469int 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}
481chkpn(){
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}
494findt(a)
495int 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}
515findt1(){
516 register i;
517
518 if(dip != d)i = dip->dnl;
519 else i = v.nl;
520 return(findt(i));
521}
522eject(a)
523struct 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;
532e1:
533 savlss = lss;
534 lss = findt(v.nl);
535 newline(0);
536 lss = savlss;
537 if(v.nl && !trap)goto e1;
538}
539movword(){
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*/
587m1:
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 }
599m2:
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 }
612m3:
613 nwd++;
614m4:
615 wordp = wp;
616 return(1);
617m5:
618 nc--;
619 w = width(*linep);
620 ne -= w;
621 nel += w;
622 wne += w;
623 wch++;
624 wp--;
625 goto m1;
626}
627horiz(i)
628int i;
629{
630 vflag = 0;
631 if(i)pchar(makem(i));
632}
633setnel(){
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}
644getword(x)
645int 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;
684g0:
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 */
707g1:
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;
717rtn:
718 wdstart = 0;
719 wordp = word;
720 pendw = 0;
721 *hyp++ = 0;
722 setnel();
723 return(noword);
724}
725storeword(c,w)
726int 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 }
739s1:
740 if(w == -1)w = width(c);
741 wne += w;
742 *wordp++ = c;
743 wch++;
744}
745#ifdef NROFF
746extern char trtab[];
747gettch(){
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