1 #ifndef lint
2 static char sccsid[] = "@(#)n5.c	2.1 (CWI) 85/07/18";
3 #endif lint
4 #include "tdef.h"
5 #include <sgtty.h>
6 #include "ext.h"
7 
8 /*
9  * troff5.c
10  *
11  * misc processing requests
12  */
13 
14 int	iflist[NIF];
15 int	ifx;
16 
17 casead()
18 {
19 	register i;
20 
21 	ad = 1;
22 	/*leave admod alone*/
23 	if (skip())
24 		return;
25 	switch (i = cbits(getch())) {
26 	case 'r':	/*right adj, left ragged*/
27 		admod = 2;
28 		break;
29 	case 'l':	/*left adj, right ragged*/
30 		admod = ad = 0;	/*same as casena*/
31 		break;
32 	case 'c':	/*centered adj*/
33 		admod = 1;
34 		break;
35 	case 'b':
36 	case 'n':
37 		admod = 0;
38 		break;
39 	case '0':
40 	case '2':
41 	case '4':
42 		ad = 0;
43 	case '1':
44 	case '3':
45 	case '5':
46 		admod = (i - '0') / 2;
47 	}
48 }
49 
50 
51 casena()
52 {
53 	ad = 0;
54 }
55 
56 
57 casefi()
58 {
59 	tbreak();
60 	fi++;
61 	pendnf = 0;
62 	lnsize = LNSIZE;
63 }
64 
65 
66 casenf()
67 {
68 	tbreak();
69 	fi = 0;
70 }
71 
72 
73 casers()
74 {
75 	dip->nls = 0;
76 }
77 
78 
79 casens()
80 {
81 	dip->nls++;
82 }
83 
84 
85 chget(c)
86 int	c;
87 {
88 	tchar i;
89 
90 	if (skip() || ismot(i = getch()) || cbits(i) == ' ' || cbits(i) == '\n') {
91 		ch = i;
92 		return(c);
93 	} else
94 		return(i & BYTEMASK);
95 }
96 
97 
98 casecc()
99 {
100 	cc = chget('.');
101 }
102 
103 
104 casec2()
105 {
106 	c2 = chget('\'');
107 }
108 
109 
110 casehc()
111 {
112 	ohc = chget(OHC);
113 }
114 
115 
116 casetc()
117 {
118 	tabc = chget(0);
119 }
120 
121 
122 caselc()
123 {
124 	dotc = chget(0);
125 }
126 
127 
128 casehy()
129 {
130 	register i;
131 
132 	hyf = 1;
133 	if (skip())
134 		return;
135 	noscale++;
136 	i = atoi();
137 	noscale = 0;
138 	if (nonumb)
139 		return;
140 	hyf = max(i, 0);
141 }
142 
143 
144 casenh()
145 {
146 	hyf = 0;
147 }
148 
149 
150 max(aa, bb)
151 int	aa, bb;
152 {
153 	if (aa > bb)
154 		return(aa);
155 	else
156 		return(bb);
157 }
158 
159 
160 casece()
161 {
162 	register i;
163 
164 	noscale++;
165 	skip();
166 	i = max(atoi(), 0);
167 	if (nonumb)
168 		i = 1;
169 	tbreak();
170 	ce = i;
171 	noscale = 0;
172 }
173 
174 
175 casein()
176 {
177 	register i;
178 
179 	if (skip())
180 		i = in1;
181 	else
182 		i = max(hnumb(&in), 0);
183 	tbreak();
184 	in1 = in;
185 	in = i;
186 	if (!nc) {
187 		un = in;
188 		setnel();
189 	}
190 }
191 
192 
193 casell()
194 {
195 	register i;
196 
197 	if (skip())
198 		i = ll1;
199 	else
200 		i = max(hnumb(&ll), INCH / 10);
201 	ll1 = ll;
202 	ll = i;
203 	setnel();
204 }
205 
206 
207 caselt()
208 {
209 	register i;
210 
211 	if (skip())
212 		i = lt1;
213 	else
214 		i = max(hnumb(&lt), 0);
215 	lt1 = lt;
216 	lt = i;
217 }
218 
219 
220 caseti()
221 {
222 	register i;
223 
224 	if (skip())
225 		return;
226 	i = max(hnumb(&in), 0);
227 	tbreak();
228 	un1 = i;
229 	setnel();
230 }
231 
232 
233 casels()
234 {
235 	register i;
236 
237 	noscale++;
238 	if (skip())
239 		i = ls1;
240 	else
241 		i = max(inumb(&ls), 1);
242 	ls1 = ls;
243 	ls = i;
244 	noscale = 0;
245 }
246 
247 
248 casepo()
249 {
250 	register i;
251 
252 	if (skip())
253 		i = po1;
254 	else
255 		i = max(hnumb(&po), 0);
256 	po1 = po;
257 	po = i;
258 #ifndef NROFF
259 	if (!ascii)
260 		esc += po - po1;
261 #endif
262 }
263 
264 
265 casepl()
266 {
267 	register i;
268 
269 	skip();
270 	if ((i = vnumb(&pl)) == 0)
271 		pl = 11 * INCH; /*11in*/
272 	else
273 		pl = i;
274 	if (numtab[NL].val > pl)
275 		numtab[NL].val = pl;
276 }
277 
278 
279 casewh()
280 {
281 	register i, j, k;
282 
283 	lgf++;
284 	skip();
285 	i = vnumb((int *)0);
286 	if (nonumb)
287 		return;
288 	skip();
289 	j = getrq();
290 	if ((k = findn(i)) != NTRAP) {
291 		mlist[k] = j;
292 		return;
293 	}
294 	for (k = 0; k < NTRAP; k++)
295 		if (mlist[k] == 0)
296 			break;
297 	if (k == NTRAP) {
298 		flusho();
299 		errprint("cannot plant trap.");
300 		return;
301 	}
302 	mlist[k] = j;
303 	nlist[k] = i;
304 }
305 
306 
307 casech()
308 {
309 	register i, j, k;
310 
311 	lgf++;
312 	skip();
313 	if (!(j = getrq()))
314 		return;
315 	else
316 		for (k = 0; k < NTRAP; k++)
317 			if (mlist[k] == j)
318 				break;
319 	if (k == NTRAP)
320 		return;
321 	skip();
322 	i = vnumb((int *)0);
323 	if (nonumb)
324 		mlist[k] = 0;
325 	nlist[k] = i;
326 }
327 
328 
329 findn(i)
330 int	i;
331 {
332 	register k;
333 
334 	for (k = 0; k < NTRAP; k++)
335 		if ((nlist[k] == i) && (mlist[k] != 0))
336 			break;
337 	return(k);
338 }
339 
340 
341 casepn()
342 {
343 	register i;
344 
345 	skip();
346 	noscale++;
347 	i = max(inumb(&numtab[PN].val), 0);
348 	noscale = 0;
349 	if (!nonumb) {
350 		npn = i;
351 		npnflg++;
352 	}
353 }
354 
355 
356 casebp()
357 {
358 	register i;
359 	register struct s *savframe;
360 
361 	if (dip != d)
362 		return;
363 	savframe = frame;
364 	skip();
365 	if ((i = inumb(&numtab[PN].val)) < 0)
366 		i = 0;
367 	tbreak();
368 	if (!nonumb) {
369 		npn = i;
370 		npnflg++;
371 	} else if (dip->nls)
372 		return;
373 	eject(savframe);
374 }
375 
376 
377 casetm(ab)
378 	int ab;
379 {
380 	register i;
381 	char	tmbuf[NTM];
382 
383 	lgf++;
384 	copyf++;
385 	skip();
386 	for (i = 0; i < NTM - 2; )
387 		if ((tmbuf[i++] = getch()) == '\n')
388 			break;
389 	if (i == NTM - 2)
390 		tmbuf[i++] = '\n';
391 	tmbuf[i] = 0;
392 	if (ab)	/* truncate output */
393 		obufp = obuf;	/* should be a function in n2.c */
394 	flusho();
395 	fdprintf(stderr, "%s", tmbuf);
396 	copyf--;
397 	lgf--;
398 }
399 
400 
401 casesp(a)
402 int	a;
403 {
404 	register i, j, savlss;
405 
406 	tbreak();
407 	if (dip->nls || trap)
408 		return;
409 	i = findt1();
410 	if (!a) {
411 		skip();
412 		j = vnumb((int *)0);
413 		if (nonumb)
414 			j = lss;
415 	} else
416 		j = a;
417 	if (j == 0)
418 		return;
419 	if (i < j)
420 		j = i;
421 	savlss = lss;
422 	if (dip != d)
423 		i = dip->dnl;
424 	else
425 		i = numtab[NL].val;
426 	if ((i + j) < 0)
427 		j = -i;
428 	lss = j;
429 	newline(0);
430 	lss = savlss;
431 }
432 
433 
434 casert()
435 {
436 	register a, *p;
437 
438 	skip();
439 	if (dip != d)
440 		p = &dip->dnl;
441 	else
442 		p = &numtab[NL].val;
443 	a = vnumb(p);
444 	if (nonumb)
445 		a = dip->mkline;
446 	if ((a < 0) || (a >= *p))
447 		return;
448 	nb++;
449 	casesp(a - *p);
450 }
451 
452 
453 caseem()
454 {
455 	lgf++;
456 	skip();
457 	em = getrq();
458 }
459 
460 
461 casefl()
462 {
463 	tbreak();
464 	flusho();
465 }
466 
467 
468 caseev()
469 {
470 	register nxev;
471 
472 	if (skip()) {
473 e0:
474 		if (evi == 0)
475 			return;
476 		nxev =  evlist[--evi];
477 		goto e1;
478 	}
479 	noscale++;
480 	nxev = atoi();
481 	noscale = 0;
482 	if (nonumb)
483 		goto e0;
484 	flushi();
485 	if ((nxev >= NEV) || (nxev < 0) || (evi >= EVLSZ)) {
486 		flusho();
487 		errprint("cannot do ev.");
488 		if (error)
489 			done2(040);
490 		else
491 			edone(040);
492 		return;
493 	}
494 	evlist[evi++] = ev;
495 e1:
496 	if (ev == nxev)
497 		return;
498 	lseek(ibf, ev * (long)sizeof(env), 0);
499 	write(ibf, (char *) & env, sizeof(env));
500 	lseek(ibf, nxev * (long)sizeof(env), 0);
501 	read(ibf, (char *) & env, sizeof(env));
502 	ev = nxev;
503 }
504 
505 
506 caseel()
507 {
508 	if (--ifx < 0) {
509 		ifx = 0;
510 		iflist[0] = 0;
511 	}
512 	caseif(2);
513 }
514 
515 
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 
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 
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 
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 
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 
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 
740 caseec()
741 {
742 	eschar = chget('\\');
743 }
744 
745 
746 caseeo()
747 {
748 	eschar = 0;
749 }
750 
751 
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 
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 
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 
815 casecu()
816 {
817 	cu++;
818 	caseul();
819 }
820 
821 
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 
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 
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 
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 
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 
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 
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 
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 
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 
977 casenn()
978 {
979 	noscale++;
980 	skip();
981 	nn = max(atoi(), 1);
982 	noscale = 0;
983 }
984 
985 
986 caseab()
987 {
988 	casetm(1);
989 	done3(0);
990 }
991