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