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