xref: /original-bsd/old/roff/common_source/n5.c (revision 62734ea8)
1 #ifndef lint
2 static char sccsid[] = "@(#)n5.c	4.1 06/07/82";
3 #endif lint
4 
5 #include "tdef.h"
6 #include <sgtty.h>
7 extern
8 #include "d.h"
9 extern
10 #include "v.h"
11 #include "sdef.h"
12 
13 /*
14 troff5.c
15 
16 misc processing requests
17 */
18 
19 extern	int	inchar[LNSIZE], *pinchar;	/* XXX */
20 extern struct s *frame;
21 extern struct s *litlev;
22 extern filep ip;
23 extern filep offset;
24 
25 extern int ascii;
26 extern int nonumb;
27 extern int admod;
28 extern int ad;
29 extern int fi;
30 extern int cc;
31 extern int c2;
32 extern int ohc;
33 extern int tabc;
34 extern int dotc;
35 extern int pendnf;
36 extern int hyf;
37 extern int ce;
38 extern int po;
39 extern int po1;
40 extern int nc;
41 extern int in;
42 extern int un;
43 extern int un1;
44 extern int in1;
45 extern int ll;
46 extern int ll1;
47 extern int lt;
48 extern int lt1;
49 extern int nlist[NTRAP];
50 extern int mlist[NTRAP];
51 extern int lgf;
52 extern int pl;
53 extern int npn;
54 extern int npnflg;
55 extern int copyf;
56 extern char nextf[];
57 extern int trap;
58 extern int lss;
59 extern int em;
60 extern int evlist[EVLSZ];
61 extern int evi;
62 extern int ibf;
63 extern int ev;
64 extern int ch;
65 extern int nflush;
66 extern int tty;
67 extern struct sgttyb ttys;
68 extern int quiet;
69 extern int iflg;
70 extern int eschar;
71 extern int lit;
72 extern int ls;
73 extern int ls1;
74 extern int tabtab[];
75 extern char trtab[];
76 extern int ul;
77 extern int cu;
78 extern int sfont;
79 extern int font;
80 extern int fontlab[];
81 extern int it;
82 extern int itmac;
83 extern int noscale;
84 extern int ic;
85 extern int icf;
86 extern int ics;
87 extern int *vlist;
88 extern int sv;
89 extern int esc;
90 extern int nn;
91 extern int nms;
92 extern int ndf;
93 extern int lnmod;
94 extern int ni;
95 extern int lnsize;
96 extern int nb;
97 extern int nlflg;
98 extern int apts, apts1, pts, pts1, font, font1;
99 extern int ulfont;
100 extern int ulbit;
101 extern int error;
102 extern int nmbits;
103 extern int chbits;
104 extern int tdelim;
105 extern int xxx;
106 int iflist[NIF];
107 int ifx;
108 
109 casead(){
110 	register i;
111 
112 	ad = 1;
113 	/*leave admod alone*/
114 	if(skip())return;
115 	switch(i = getch() & CMASK){
116 		case 'r':	/*right adj, left ragged*/
117 			admod = 2;
118 			break;
119 		case 'l':	/*left adj, right ragged*/
120 			admod = ad = 0;	/*same as casena*/
121 			break;
122 		case 'c':	/*centered adj*/
123 			admod = 1;
124 			break;
125 		case 'b': case 'n':
126 			admod = 0;
127 			break;
128 		case '0': case '2': case '4':
129 			ad = 0;
130 		case '1': case '3': case '5':
131 			admod = (i - '0')/2;
132 	}
133 }
134 casena(){
135 	ad = 0;
136 }
137 casefi(){
138 	tbreak();
139 	fi++;
140 	pendnf = 0;
141 	lnsize = LNSIZE;
142 }
143 casenf(){
144 	tbreak();
145 	fi = 0;
146 /* can't do while oline is only LNSIZE
147 	lnsize = LNSIZE + WDSIZE;
148 */
149 }
150 casers(){
151 	dip->nls = 0;
152 }
153 casens(){
154 	dip->nls++;
155 }
156 chget(c)
157 int c;
158 {
159 	register i;
160 
161 	if(skip() ||
162 	  ((i = getch()) & MOT) ||
163 	  ((i&CMASK) == ' ') ||
164 	  ((i&CMASK) == '\n')){
165 		ch = i;
166 		return(c);
167 	}else return(i & BMASK);
168 }
169 casecc(){
170 	cc = chget('.');
171 }
172 casec2(){
173 	c2 = chget('\'');
174 }
175 casehc(){
176 	ohc = chget(OHC);
177 }
178 casetc(){
179 	tabc = chget(0);
180 }
181 caselc(){
182 	dotc = chget(0);
183 }
184 casehy(){
185 	register i;
186 
187 	hyf = 1;
188 	if(skip())return;
189 	noscale++;
190 	i = atoi();
191 	noscale = 0;
192 	if(nonumb)return;
193 	hyf = max(i,0);
194 }
195 casenh(){
196 	hyf = 0;
197 }
198 max(aa,bb)
199 int aa,bb;
200 {
201 	if(aa>bb)return(aa);
202 	else return(bb);
203 }
204 casece(){
205 	register i;
206 
207 	noscale++;
208 	skip();
209 	i = max(atoi(),0);
210 	if(nonumb)i = 1;
211 	tbreak();
212 	ce = i;
213 	noscale = 0;
214 }
215 casein(){
216 	register i;
217 
218 	if(skip())i = in1;
219 	else i = max(hnumb(&in),0);
220 	tbreak();
221 	in1 = in;
222 	in = i;
223 	if(!nc){
224 		un = in;
225 		setnel();
226 	}
227 }
228 casell(){
229 	register i;
230 
231 	if(skip())i = ll1;
232 	else i = max(hnumb(&ll),INCH/10);
233 	ll1 = ll;
234 	ll = i;
235 	setnel();
236 }
237 caselt(){
238 	register i;
239 
240 	if(skip())i = lt1;
241 	else i = max(hnumb(&lt),0);
242 	lt1 = lt;
243 	lt = i;
244 }
245 caseti(){
246 	register i;
247 
248 	if(skip())return;
249 	i = max(hnumb(&in),0);
250 	tbreak();
251 	un1 = i;
252 	setnel();
253 }
254 casels(){
255 	register i;
256 
257 	noscale++;
258 	if(skip())i = ls1;
259 	else i = max(inumb(&ls),1);
260 	ls1 = ls;
261 	ls = i;
262 	noscale = 0;
263 }
264 casepo(){
265 	register i;
266 
267 	if(skip())i = po1;
268 	else i = max(hnumb(&po),0);
269 	po1 = po;
270 	po = i;
271 #ifndef NROFF
272 	if(!ascii)esc += po - po1;
273 #endif
274 }
275 casepl(){
276 	register i;
277 
278 	skip();
279 	if((i = vnumb(&pl)) == 0)pl = 11 * INCH; /*11in*/
280 		else pl = i;
281 	if(v.nl > pl)v.nl = pl;
282 }
283 casewh(){
284 	register i, j, k;
285 
286 	lgf++;
287 	skip();
288 	i = vnumb((int *)0);
289 	if(nonumb)return;
290 	skip();
291 	j = getrq();
292 	if((k=findn(i)) != NTRAP){
293 		mlist[k] = j;
294 		return;
295 	}
296 	for(k=0; k<NTRAP; k++)if(mlist[k] == 0)break;
297 	if(k == NTRAP){
298 		prstrfl("Cannot plant trap.\n");
299 		return;
300 	}
301 	mlist[k] = j;
302 	nlist[k] = i;
303 }
304 casech(){
305 	register i, j, k;
306 
307 	lgf++;
308 	skip();
309 	if(!(j=getrq()))return;
310 		else for(k=0; k<NTRAP; k++)if(mlist[k] == j)break;
311 	if(k == NTRAP)return;
312 	skip();
313 	i = vnumb((int *)0);
314 	if(nonumb)mlist[k] = 0;
315 	nlist[k] = i;
316 }
317 findn(i)
318 int i;
319 {
320 	register k;
321 
322 	for(k=0; k<NTRAP; k++)
323 		if((nlist[k] == i) && (mlist[k] != 0))break;
324 	return(k);
325 }
326 casepn(){
327 	register i;
328 
329 	skip();
330 	noscale++;
331 	i = max(inumb(&v.pn),0);
332 	noscale = 0;
333 	if(!nonumb){
334 		npn = i;
335 		npnflg++;
336 	}
337 }
338 casebp(){
339 	register i;
340 	register struct s *savframe;
341 
342 	if(dip != d)return;
343 	savframe = frame;
344 	skip();
345 	if((i = inumb(&v.pn)) < 0)i = 0;
346 	tbreak();
347 	if(!nonumb){
348 		npn = i;
349 		npnflg++;
350 	}else if(dip->nls)return;
351 	eject(savframe);
352 }
353 casetm(x) int x;{
354 	register i;
355 	char tmbuf[NTM];
356 
357 	lgf++;
358 	copyf++;
359 	if(skip() && x)prstrfl("User Abort.");
360 	for(i=0; i<NTM-2;)if((tmbuf[i++]=getch()) == '\n')break;
361 	if(i == NTM-2)tmbuf[i++] = '\n';
362 	tmbuf[i] = 0;
363 	prstrfl(tmbuf);
364 	copyf--;
365 }
366 casesp(a)
367 int a;
368 {
369 	register i, j, savlss;
370 
371 	tbreak();
372 	if(dip->nls || trap)return;
373 	i = findt1();
374 	if(!a){
375 		skip();
376 		j = vnumb((int *)0);
377 		if(nonumb)j = lss;
378 	}else j = a;
379 	if(j == 0)return;
380 	if(i < j)j = i;
381 	savlss = lss;
382 	if(dip != d)i = dip->dnl; else i = v.nl;
383 	if((i + j) < 0)j = -i;
384 	lss = j;
385 	newline(0);
386 	lss = savlss;
387 }
388 casert(){
389 	register a, *p;
390 
391 	skip();
392 	if(dip != d)p = &dip->dnl; else p = &v.nl;
393 	a = vnumb(p);
394 	if(nonumb)a = dip->mkline;
395 	if((a < 0) || (a >= *p))return;
396 	nb++;
397 	casesp(a - *p);
398 }
399 caseem(){
400 	lgf++;
401 	skip();
402 	em = getrq();
403 }
404 casefl(){
405 	tbreak();
406 	flusho();
407 }
408 caseev(){
409 	register nxev;
410 	extern int block;
411 
412 	if(skip()){
413 e0:
414 		if(evi == 0)return;
415 		nxev =  evlist[--evi];
416 		goto e1;
417 	}
418 	noscale++;
419 	nxev = atoi();
420 	noscale = 0;
421 	if(nonumb)goto e0;
422 	flushi();
423 	if((nxev >= NEV) || (nxev < 0) || (evi >= EVLSZ)){
424 		prstrfl("Cannot do ev.\n");
425 		if(error)done2(040);else edone(040);
426 		return;
427 	}
428 	evlist[evi++] = ev;
429 e1:
430 	if(ev == nxev)return;
431 	lseek(ibf, (long)(ev*EVS*sizeof(int)), 0);
432 	write(ibf,(char *)&block, EVS*sizeof(int));
433 	lseek(ibf, (long)(nxev*EVS*sizeof(int)), 0);
434 	read(ibf,(char *)&block, EVS*sizeof(int));
435 	ev = nxev;
436 }
437 caseel(){
438 	if(--ifx < 0){
439 		ifx = 0;
440 		iflist[0] = 0;
441 	}
442 	caseif(2);
443 }
444 caseie(){
445 	if(ifx >= NIF){
446 		prstr("if-else overflow.\n");
447 		ifx = 0;
448 		edone(040);
449 	}
450 	caseif(1);
451 	ifx++;
452 }
453 caseif(x)
454 int x;
455 {
456 	register i, notflag, true;
457 
458 	if(x == 2){
459 		notflag = 0;
460 		true = iflist[ifx];
461 		goto i1;
462 	}
463 	true = 0;
464 	skip();
465 	if(((i = getch()) & CMASK) == '!'){
466 		notflag = 1;
467 	}else{
468 		notflag = 0;
469 		ch = i;
470 	}
471 	i = atoi();
472 	if(!nonumb){
473 		if(i > 0)true++;
474 		goto i1;
475 	}
476 	switch((i = getch()) & CMASK){
477 		case 'e':
478 			if(!(v.pn & 01))true++;
479 			break;
480 		case 'o':
481 			if(v.pn & 01)true++;
482 			break;
483 #ifdef NROFF
484 		case 'n':
485 			true++;
486 		case 't':
487 #endif
488 #ifndef NROFF
489 		case 't':
490 			true++;
491 		case 'n':
492 #endif
493 		case ' ':
494 			break;
495 		default:
496 			true = cmpstr(i);
497 	}
498 i1:
499 	true ^= notflag;
500 	if(x == 1)iflist[ifx] = !true;
501 	if(true){
502 	i2:
503 		do{
504 		v.hp = 0;
505 		pinchar = inchar;	/* XXX */
506 		}
507 		while(((i = getch()) & CMASK) == ' ');
508 		if((i & CMASK) == LEFT)goto i2;
509 		ch = i;
510 		nflush++;
511 	}else{
512 		copyf++;
513 		if(eat(LEFT) == LEFT){
514 			while(eatblk(RIGHT,LEFT) != RIGHT)nlflg = 0;
515 		}
516 		copyf--;
517 	}
518 }
519 eatblk(right,left)
520 int right,left;
521 {
522 	register i;
523 
524 e0:
525 	while(((i = getch() & CMASK) != right) &&
526 		(i != left) &&
527 		(i != '\n'));
528 	if(i == left){
529 		while((i=eatblk(right,left)) != right)nlflg = 0;
530 		goto e0;
531 	}
532 	return(i);
533 }
534 cmpstr(delim)
535 int delim;
536 {
537 	register i, j;
538 	register filep p;
539 	extern filep alloc();
540 	extern filep incoff();
541 	filep begin;
542 	int cnt, k;
543 	int savapts, savapts1, savfont, savfont1,
544 		savpts, savpts1;
545 
546 	if(delim & MOT)return(0);
547 	delim &= CMASK;
548 	if(dip != d)wbfl();
549 	if((offset = begin = alloc()) == (filep)0)return(0);
550 	cnt = 0;
551 	v.hp = 0;
552 	pinchar = inchar;	/* XXX */
553 	savapts = apts;
554 	savapts1 = apts1;
555 	savfont = font;
556 	savfont1 = font1;
557 	savpts = pts;
558 	savpts1 = pts1;
559 	while(((j = (i=getch()) & CMASK) != delim) && (j != '\n')){
560 		wbf(i);
561 		cnt++;
562 	}
563 	wbt(0);
564 	k = !cnt;
565 	if(nlflg)goto rtn;
566 	p = begin;
567 	apts = savapts;
568 	apts1 = savapts1;
569 	font = savfont;
570 	font1 = savfont1;
571 	pts = savpts;
572 	pts1 = savpts1;
573 	mchbits();
574 	v.hp = 0;
575 	pinchar = inchar;	/* XXX */
576 	while(((j = (i=getch()) & CMASK) != delim) && (j != '\n')){
577 		if(rbf0(p) != i){
578 			eat(delim);
579 			k = 0;
580 			break;
581 		}
582 		p = incoff(p);
583 		k = !(--cnt);
584 	}
585 rtn:
586 	apts = savapts;
587 	apts1 = savapts1;
588 	font = savfont;
589 	font1 = savfont1;
590 	pts = savpts;
591 	pts1 = savpts1;
592 	mchbits();
593 	offset = dip->op;
594 	ffree(begin);
595 	return(k);
596 }
597 caserd(){
598 
599 	lgf++;
600 	skip();
601 	getname();
602 	if(!iflg){
603 		if(quiet){
604 			ttys.sg_flags &= ~ECHO;
605 			stty(0, &ttys);
606 			prstrfl(""); /*bell*/
607 		}else{
608 			if(nextf[0]){
609 				prstr(nextf);
610 				prstr(":");
611 			}else{
612 				prstr(""); /*bell*/
613 			}
614 		}
615 	}
616 	collect();
617 	tty++;
618 	pushi((filep)-1);
619 }
620 rdtty(){
621 	char onechar;
622 
623 	onechar = 0;
624 	if(read(0, &onechar, 1) == 1){
625 		if(onechar == '\n')tty++;
626 			else tty = 1;
627 		if(tty != 3)return(onechar);
628 	}
629 	popi();
630 	tty = 0;
631 	if(quiet){
632 		ttys.sg_flags |= ECHO;
633 		stty(0, &ttys);
634 	}
635 	return(0);
636 }
637 caseec(){
638 	eschar = chget('\\');
639 }
640 caseeo(){
641 	eschar = 0;
642 }
643 caseli(){
644 
645 	skip();
646 	lit = max(inumb((int *)0),1);
647 	litlev = frame;
648 	if((dip == d) && (v.nl == -1))newline(1);
649 }
650 caseta(){
651 	register i;
652 
653 	tabtab[0] = nonumb = 0;
654 	for(i=0; ((i < (NTAB-1)) && !nonumb); i++){
655 		if(skip())break;
656 		tabtab[i] = max(hnumb(&tabtab[max(i-1,0)]),0) & TMASK;
657 		if(!nonumb) switch(ch & CMASK){
658 			case 'C':
659 				tabtab[i] |= CTAB;
660 				break;
661 			case 'R':
662 				tabtab[i] |= RTAB;
663 				break;
664 			default: /*includes L*/
665 				break;
666 			}
667 		nonumb = ch = 0;
668 	}
669 	tabtab[i] = 0;
670 }
671 casene(){
672 	register i, j;
673 
674 	skip();
675 	i = vnumb((int *)0);
676 	if(nonumb)i = lss;
677 	if(i > (j = findt1())){
678 		i = lss;
679 		lss = j;
680 		dip->nls = 0;
681 		newline(0);
682 		lss = i;
683 	}
684 }
685 casetr(){
686 	register i, j;
687 
688 	lgf++;
689 	skip();
690 	while((i = getch() & CMASK) != '\n'){
691 		if((i & MOT) || ((j = getch()) & MOT))return;
692 		if((j &= CMASK) == '\n')j = ' ';
693 		trtab[i] = j;
694 	}
695 }
696 casecu(){
697 	cu++;
698 	caseul();
699 }
700 caseul(){
701 	register i;
702 
703 	noscale++;
704 	if(skip())i = 1;
705 	else i = atoi();
706 	if(ul && (i == 0)){
707 		font = sfont;
708 		ul = cu = 0;
709 	}
710 	if(i){
711 		if(!ul){
712 			sfont = font;
713 			font = ulfont;
714 		}
715 		ul = i;
716 	}
717 	noscale = 0;
718 	mchbits();
719 }
720 caseuf(){
721 	register i, j;
722 
723 	if(skip() || !(i = getrq()) || (i == 'S') ||
724 		((j = find(i,fontlab))  == -1))
725 			ulfont = 1; /*default position 2*/
726 	else ulfont = j;
727 #ifdef NROFF
728 	if(ulfont == 0)ulfont = 1;
729 #endif
730 	ulbit = ulfont<<9;
731 }
732 caseit(){
733 	register i;
734 
735 	lgf++;
736 	it = itmac = 0;
737 	noscale++;
738 	skip();
739 	i = atoi();
740 	skip();
741 	if(!nonumb && (itmac = getrq()))it = i;
742 	noscale = 0;
743 }
744 casemc(){
745 	register i;
746 
747 	if(icf > 1)ic = 0;
748 	icf = 0;
749 	if(skip())return;
750 	ic = getch();
751 	icf = 1;
752 	skip();
753 	i = max(hnumb((int *)0),0);
754 	if(!nonumb)ics = i;
755 }
756 casemk(){
757 	register i, j;
758 
759 	if(dip != d)j = dip->dnl; else j = v.nl;
760 	if(skip()){
761 		dip->mkline = j;
762 		return;
763 	}
764 	if((i = getrq()) == 0)return;
765 	vlist[findr(i)] = j;
766 }
767 casesv(){
768 	register i;
769 
770 	skip();
771 	if((i = vnumb((int *)0)) < 0)return;
772 	if(nonumb)i = 1;
773 	sv += i;
774 	caseos();
775 }
776 caseos(){
777 	register savlss;
778 
779 	if(sv <= findt1()){
780 		savlss = lss;
781 		lss = sv;
782 		newline(0);
783 		lss = savlss;
784 		sv = 0;
785 	}
786 }
787 casenm(){
788 	register i;
789 
790 	lnmod = nn = 0;
791 	if(skip())return;
792 	lnmod++;
793 	noscale++;
794 	i = inumb(&v.ln);
795 	if(!nonumb)v.ln = max(i,0);
796 	getnm(&ndf,1);
797 	getnm(&nms,0);
798 	getnm(&ni,0);
799 	noscale = 0;
800 	nmbits = chbits;
801 }
802 getnm(p,min)
803 int *p, min;
804 {
805 	register i;
806 
807 	eat(' ');
808 	if(skip())return;
809 	i = atoi();
810 	if(nonumb)return;
811 	*p = max(i,min);
812 }
813 casenn(){
814 	noscale++;
815 	skip();
816 	nn = max(atoi(),1);
817 	noscale = 0;
818 }
819 caseab(){
820 	dummy();
821 	casetm(1);
822 	done2(0);
823 }
824