xref: /illumos-gate/usr/src/cmd/troff/n5.c (revision fc910014e8a32a65612105835a10995f2c13d942)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 /*
31  * University Copyright- Copyright (c) 1982, 1986, 1988
32  * The Regents of the University of California
33  * All Rights Reserved
34  *
35  * University Acknowledgment- Portions of this document are derived from
36  * software developed by the University of California, Berkeley, and its
37  * contributors.
38  */
39 
40 #ifdef 	EUC
41 #ifdef	NROFF
42 #include <stddef.h>
43 #include <stdlib.h>
44 #include <widec.h>
45 #endif	/* NROFF */
46 #endif	/* EUC */
47 #include <string.h>
48 #include "tdef.h"
49 #include "ext.h"
50 
51 /*
52  * troff5.c
53  *
54  * misc processing requests
55  */
56 
57 int	iflist[NIF];
58 int	ifx;
59 
60 int
61 casead()
62 {
63 	int	i;
64 
65 	ad = 1;
66 	/*leave admod alone*/
67 	if (skip())
68 		return (0);
69 	switch (i = cbits(getch())) {
70 	case 'r':	/*right adj, left ragged*/
71 		admod = 2;
72 		break;
73 	case 'l':	/*left adj, right ragged*/
74 		admod = ad = 0;	/*same as casena*/
75 		break;
76 	case 'c':	/*centered adj*/
77 		admod = 1;
78 		break;
79 	case 'b':
80 	case 'n':
81 		admod = 0;
82 		break;
83 	case '0':
84 	case '2':
85 	case '4':
86 		ad = 0;
87 	case '1':
88 	case '3':
89 	case '5':
90 		admod = (i - '0') / 2;
91 	}
92 
93 	return (0);
94 }
95 
96 
97 int
98 casena()
99 {
100 	ad = 0;
101 
102 	return (0);
103 }
104 
105 
106 int
107 casefi()
108 {
109 	tbreak();
110 	fi++;
111 	pendnf = 0;
112 	lnsize = LNSIZE;
113 
114 	return (0);
115 }
116 
117 
118 int
119 casenf()
120 {
121 	tbreak();
122 	fi = 0;
123 
124 	return (0);
125 }
126 
127 
128 int
129 casers()
130 {
131 	dip->nls = 0;
132 
133 	return (0);
134 }
135 
136 
137 int
138 casens()
139 {
140 	dip->nls++;
141 
142 	return (0);
143 }
144 
145 
146 int
147 chget(c)
148 int	c;
149 {
150 	tchar i;
151 
152 	if (skip() || ismot(i = getch()) || cbits(i) == ' ' || cbits(i) == '\n') {
153 		ch = i;
154 		return(c);
155 	} else
156 		return(i & BYTEMASK);
157 }
158 
159 
160 int
161 casecc()
162 {
163 	cc = chget('.');
164 
165 	return (0);
166 }
167 
168 
169 int
170 casec2()
171 {
172 	c2 = chget('\'');
173 
174 	return (0);
175 }
176 
177 
178 int
179 casehc()
180 {
181 	ohc = chget(OHC);
182 
183 	return (0);
184 }
185 
186 
187 int
188 casetc()
189 {
190 	tabc = chget(0);
191 
192 	return (0);
193 }
194 
195 
196 int
197 caselc()
198 {
199 	dotc = chget(0);
200 
201 	return (0);
202 }
203 
204 
205 int
206 casehy()
207 {
208 	int	i;
209 
210 	hyf = 1;
211 	if (skip())
212 		return (0);
213 	noscale++;
214 	i = atoi();
215 	noscale = 0;
216 	if (nonumb)
217 		return (0);
218 	hyf = max(i, 0);
219 
220 	return (0);
221 }
222 
223 
224 int
225 casenh()
226 {
227 	hyf = 0;
228 
229 	return (0);
230 }
231 
232 
233 int
234 max(aa, bb)
235 int	aa, bb;
236 {
237 	if (aa > bb)
238 		return(aa);
239 	else
240 		return(bb);
241 }
242 
243 
244 int
245 casece()
246 {
247 	int	i;
248 
249 	noscale++;
250 	skip();
251 	i = max(atoi(), 0);
252 	if (nonumb)
253 		i = 1;
254 	tbreak();
255 	ce = i;
256 	noscale = 0;
257 
258 	return (0);
259 }
260 
261 
262 int
263 casein()
264 {
265 	int	i;
266 
267 	if (skip())
268 		i = in1;
269 	else
270 		i = max(hnumb(&in), 0);
271 	tbreak();
272 	in1 = in;
273 	in = i;
274 	if (!nc) {
275 		un = in;
276 		setnel();
277 	}
278 
279 	return (0);
280 }
281 
282 
283 int
284 casell()
285 {
286 	int	i;
287 
288 	if (skip())
289 		i = ll1;
290 	else
291 		i = max(hnumb(&ll), INCH / 10);
292 	ll1 = ll;
293 	ll = i;
294 	setnel();
295 
296 	return (0);
297 }
298 
299 
300 int
301 caselt()
302 {
303 	int	i;
304 
305 	if (skip())
306 		i = lt1;
307 	else
308 		i = max(hnumb(&lt), 0);
309 	lt1 = lt;
310 	lt = i;
311 
312 	return (0);
313 }
314 
315 
316 int
317 caseti()
318 {
319 	int	i;
320 
321 	if (skip())
322 		return (0);
323 	i = max(hnumb(&in), 0);
324 	tbreak();
325 	un1 = i;
326 	setnel();
327 
328 	return (0);
329 }
330 
331 
332 int
333 casels()
334 {
335 	int	i;
336 
337 	noscale++;
338 	if (skip())
339 		i = ls1;
340 	else
341 		i = max(inumb(&ls), 1);
342 	ls1 = ls;
343 	ls = i;
344 	noscale = 0;
345 
346 	return (0);
347 }
348 
349 
350 int
351 casepo()
352 {
353 	int	i;
354 
355 	if (skip())
356 		i = po1;
357 	else
358 		i = max(hnumb(&po), 0);
359 	po1 = po;
360 	po = i;
361 #ifndef NROFF
362 	if (!ascii)
363 		esc += po - po1;
364 #endif
365 	return (0);
366 }
367 
368 
369 int
370 casepl()
371 {
372 	int	i;
373 
374 	skip();
375 	if ((i = vnumb(&pl)) == 0)
376 		pl = 11 * INCH; /*11in*/
377 	else
378 		pl = i;
379 	if (numtab[NL].val > pl)
380 		numtab[NL].val = pl;
381 
382 	return (0);
383 }
384 
385 
386 int
387 casewh()
388 {
389 	int	i, j, k;
390 
391 	lgf++;
392 	skip();
393 	i = vnumb((int *)0);
394 	if (nonumb)
395 		return (0);
396 	skip();
397 	j = getrq();
398 	if ((k = findn(i)) != NTRAP) {
399 		mlist[k] = j;
400 		return (0);
401 	}
402 	for (k = 0; k < NTRAP; k++)
403 		if (mlist[k] == 0)
404 			break;
405 	if (k == NTRAP) {
406 		flusho();
407 		errprint(gettext("cannot plant trap."));
408 		return (0);
409 	}
410 	mlist[k] = j;
411 	nlist[k] = i;
412 
413 	return (0);
414 }
415 
416 
417 int
418 casech()
419 {
420 	int	i, j, k;
421 
422 	lgf++;
423 	skip();
424 	if (!(j = getrq()))
425 		return (0);
426 	else
427 		for (k = 0; k < NTRAP; k++)
428 			if (mlist[k] == j)
429 				break;
430 	if (k == NTRAP)
431 		return (0);
432 	skip();
433 	i = vnumb((int *)0);
434 	if (nonumb)
435 		mlist[k] = 0;
436 	nlist[k] = i;
437 
438 	return (0);
439 }
440 
441 
442 int
443 findn(i)
444 int	i;
445 {
446 	int	k;
447 
448 	for (k = 0; k < NTRAP; k++)
449 		if ((nlist[k] == i) && (mlist[k] != 0))
450 			break;
451 	return(k);
452 }
453 
454 
455 int
456 casepn()
457 {
458 	int	i;
459 
460 	skip();
461 	noscale++;
462 	i = max(inumb(&numtab[PN].val), 0);
463 	noscale = 0;
464 	if (!nonumb) {
465 		npn = i;
466 		npnflg++;
467 	}
468 
469 	return (0);
470 }
471 
472 
473 int
474 casebp()
475 {
476 	int	i;
477 	struct s *savframe;
478 
479 	if (dip != d)
480 		return (0);
481 	savframe = frame;
482 	skip();
483 	if ((i = inumb(&numtab[PN].val)) < 0)
484 		i = 0;
485 	tbreak();
486 	if (!nonumb) {
487 		npn = i;
488 		npnflg++;
489 	} else if (dip->nls)
490 		return (0);
491 	eject(savframe);
492 
493 	return (0);
494 }
495 
496 
497 int
498 casetm(ab)
499 	int ab;
500 {
501 	int	i;
502 	char	tmbuf[NTM];
503 
504 	lgf++;
505 	copyf++;
506 	if (skip() && ab)
507 		errprint(gettext("User Abort"));
508 	for (i = 0; i < NTM - 2; )
509 		if ((tmbuf[i++] = getch()) == '\n')
510 			break;
511 	if (i == NTM - 2)
512 		tmbuf[i++] = '\n';
513 	tmbuf[i] = 0;
514 	if (ab)	/* truncate output */
515 		obufp = obuf;	/* should be a function in n2.c */
516 	flusho();
517 	fdprintf(stderr, "%s", tmbuf);
518 	copyf--;
519 	lgf--;
520 
521 	return (0);
522 }
523 
524 
525 int
526 casesp(a)
527 int	a;
528 {
529 	int	i, j, savlss;
530 
531 	tbreak();
532 	if (dip->nls || trap)
533 		return (0);
534 	i = findt1();
535 	if (!a) {
536 		skip();
537 		j = vnumb((int *)0);
538 		if (nonumb)
539 			j = lss;
540 	} else
541 		j = a;
542 	if (j == 0)
543 		return (0);
544 	if (i < j)
545 		j = i;
546 	savlss = lss;
547 	if (dip != d)
548 		i = dip->dnl;
549 	else
550 		i = numtab[NL].val;
551 	if ((i + j) < 0)
552 		j = -i;
553 	lss = j;
554 	newline(0);
555 	lss = savlss;
556 
557 	return (0);
558 }
559 
560 
561 int
562 casert()
563 {
564 	int	a, *p;
565 
566 	skip();
567 	if (dip != d)
568 		p = &dip->dnl;
569 	else
570 		p = &numtab[NL].val;
571 	a = vnumb(p);
572 	if (nonumb)
573 		a = dip->mkline;
574 	if ((a < 0) || (a >= *p))
575 		return (0);
576 	nb++;
577 	casesp(a - *p);
578 
579 	return (0);
580 }
581 
582 
583 int
584 caseem()
585 {
586 	lgf++;
587 	skip();
588 	em = getrq();
589 
590 	return (0);
591 }
592 
593 
594 int
595 casefl()
596 {
597 	tbreak();
598 	flusho();
599 
600 	return (0);
601 }
602 
603 
604 int
605 caseev()
606 {
607 	int	nxev;
608 
609 	if (skip()) {
610 e0:
611 		if (evi == 0)
612 			return (0);
613 		nxev =  evlist[--evi];
614 		goto e1;
615 	}
616 	noscale++;
617 	nxev = atoi();
618 	noscale = 0;
619 	if (nonumb)
620 		goto e0;
621 	flushi();
622 	if ((nxev >= NEV) || (nxev < 0) || (evi >= EVLSZ)) {
623 		flusho();
624 		errprint(gettext("cannot do ev."));
625 		if (error)
626 			done2(040);
627 		else
628 			edone(040);
629 		return (0);
630 	}
631 	evlist[evi++] = ev;
632 e1:
633 	if (ev == nxev)
634 		return (0);
635 #ifdef INCORE
636 	{
637 		extern tchar corebuf[];
638 		*(struct env *)&corebuf[ev * sizeof(env)/sizeof(tchar)] = env;
639 		env = *(struct env *)&corebuf[nxev * sizeof(env)/sizeof(tchar)];
640 	}
641 #else
642 	lseek(ibf, ev * (long)sizeof(env), 0);
643 	write(ibf, (char *) & env, sizeof(env));
644 	lseek(ibf, nxev * (long)sizeof(env), 0);
645 	read(ibf, (char *) & env, sizeof(env));
646 #endif
647 	ev = nxev;
648 
649 	return (0);
650 }
651 
652 int
653 caseel()
654 {
655 	if (--ifx < 0) {
656 		ifx = 0;
657 		iflist[0] = 0;
658 	}
659 	caseif(2);
660 
661 	return (0);
662 }
663 
664 
665 int
666 caseie()
667 {
668 	if (ifx >= NIF) {
669 		errprint(gettext("if-else overflow."));
670 		ifx = 0;
671 		edone(040);
672 	}
673 	caseif(1);
674 	ifx++;
675 
676 	return (0);
677 }
678 
679 
680 int
681 caseif(x)
682 int	x;
683 {
684 	extern int falsef;
685 	int	notflag, true;
686 	tchar i;
687 
688 	if (x == 2) {
689 		notflag = 0;
690 		true = iflist[ifx];
691 		goto i1;
692 	}
693 	true = 0;
694 	skip();
695 	if ((cbits(i = getch())) == '!') {
696 		notflag = 1;
697 	} else {
698 		notflag = 0;
699 		ch = i;
700 	}
701 	i = atoi();
702 	if (!nonumb) {
703 		if (i > 0)
704 			true++;
705 		goto i1;
706 	}
707 	i = getch();
708 	switch (cbits(i)) {
709 	case 'e':
710 		if (!(numtab[PN].val & 01))
711 			true++;
712 		break;
713 	case 'o':
714 		if (numtab[PN].val & 01)
715 			true++;
716 		break;
717 #ifdef NROFF
718 	case 'n':
719 		true++;
720 	case 't':
721 #endif
722 #ifndef NROFF
723 	case 't':
724 		true++;
725 	case 'n':
726 #endif
727 	case ' ':
728 		break;
729 	default:
730 		true = cmpstr(i);
731 	}
732 i1:
733 	true ^= notflag;
734 	if (x == 1)
735 		iflist[ifx] = !true;
736 	if (true) {
737 i2:
738 		while ((cbits(i = getch())) == ' ')
739 			;
740 		if (cbits(i) == LEFT)
741 			goto i2;
742 		ch = i;
743 		nflush++;
744 	} else {
745 		copyf++;
746 		falsef++;
747 		eatblk(0);
748 		copyf--;
749 		falsef--;
750 	}
751 
752 	return (0);
753 }
754 
755 int
756 eatblk(inblk)
757 int inblk;
758 {	int cnt, i;
759 
760 	cnt = 0;
761 	do {
762 		if (ch)	{
763 			i = cbits(ch);
764 			ch = 0;
765 		} else
766 			i = cbits(getch0());
767 		if (i == ESC)
768 			cnt++;
769 		else {
770 			if (cnt == 1)
771 				switch (i) {
772 				case '{':  i = LEFT; break;
773 				case '}':  i = RIGHT; break;
774 				case '\n': i = 'x'; break;
775 				}
776 			cnt = 0;
777 		}
778 		if (i == LEFT) eatblk(1);
779 	} while ((!inblk && (i != '\n')) || (inblk && (i != RIGHT)));
780 	if (i == '\n')
781 		nlflg++;
782 
783 	return (0);
784 }
785 
786 
787 int
788 cmpstr(c)
789 tchar c;
790 {
791 	int	j, delim;
792 	tchar i;
793 	int	val;
794 	int savapts, savapts1, savfont, savfont1, savpts, savpts1;
795 	tchar string[1280];
796 	tchar *sp;
797 
798 	if (ismot(c))
799 		return(0);
800 	delim = cbits(c);
801 	savapts = apts;
802 	savapts1 = apts1;
803 	savfont = font;
804 	savfont1 = font1;
805 	savpts = pts;
806 	savpts1 = pts1;
807 	sp = string;
808 	while ((j = cbits(i = getch()))!=delim && j!='\n' && sp<&string[1280-1])
809 		*sp++ = i;
810 	if (sp >= string + 1280) {
811 		errprint(gettext("too-long string compare."));
812 		edone(0100);
813 	}
814 	if (nlflg) {
815 		val = sp==string;
816 		goto rtn;
817 	}
818 	*sp++ = 0;
819 	apts = savapts;
820 	apts1 = savapts1;
821 	font = savfont;
822 	font1 = savfont1;
823 	pts = savpts;
824 	pts1 = savpts1;
825 	mchbits();
826 	val = 1;
827 	sp = string;
828 	while ((j = cbits(i = getch())) != delim && j != '\n') {
829 		if (*sp != i) {
830 			eat(delim);
831 			val = 0;
832 			goto rtn;
833 		}
834 		sp++;
835 	}
836 	if (*sp)
837 		val = 0;
838 rtn:
839 	apts = savapts;
840 	apts1 = savapts1;
841 	font = savfont;
842 	font1 = savfont1;
843 	pts = savpts;
844 	pts1 = savpts1;
845 	mchbits();
846 	return(val);
847 }
848 
849 
850 int
851 caserd()
852 {
853 
854 	lgf++;
855 	skip();
856 	getname();
857 	if (!iflg) {
858 		if (quiet) {
859 #ifdef	NROFF
860 			echo_off();
861 			flusho();
862 #endif	/* NROFF */
863 			fdprintf(stderr, "\007"); /*bell*/
864 		} else {
865 			if (nextf[0]) {
866 				fdprintf(stderr, "%s:", nextf);
867 			} else {
868 				fdprintf(stderr, "\007"); /*bell*/
869 			}
870 		}
871 	}
872 	collect();
873 	tty++;
874 	pushi(NBLIST*BLK, PAIR('r','d'));
875 
876 	return (0);
877 }
878 
879 
880 int
881 rdtty()
882 {
883 	char	onechar;
884 #ifdef EUC
885 #ifdef NROFF
886 	int	i, n, col_index;
887 #endif /* NROFF */
888 #endif /* EUC */
889 
890 	onechar = 0;
891 	if (read(0, &onechar, 1) == 1) {
892 		if (onechar == '\n')
893 			tty++;
894 		else
895 			tty = 1;
896 #ifndef EUC
897 		if (tty != 3)
898 			return(onechar);
899 #else
900 #ifndef NROFF
901 		if (tty != 3)
902 			return(onechar);
903 #else
904 		if (tty != 3) {
905 			if (!multi_locale)
906 				return(onechar);
907 			i = onechar & 0377;
908 			*mbbuf1p++ = i;
909 			*mbbuf1p = 0;
910 			if ((n = mbtowc(&twc, mbbuf1, MB_CUR_MAX)) <= 0) {
911 				if (mbbuf1p >= mbbuf1 + MB_CUR_MAX) {
912 					i &= ~(MBMASK | CSMASK);
913 					twc = 0;
914 					mbbuf1p = mbbuf1;
915 					*mbbuf1p = 0;
916 				} else {
917 					i |= (MIDDLEOFMB);
918 				}
919 			} else {
920 				if (n > 1)
921 					i |= (LASTOFMB);
922 				else
923 					i |= (BYTE_CHR);
924 				if (isascii(twc)) {
925 					col_index = 0;
926 				} else {
927 					if ((col_index = wcwidth(twc)) < 0)
928 						col_index = 0;
929 				}
930 				setcsbits(i, col_index);
931 				twc = 0;
932 				mbbuf1p = mbbuf1;
933 			}
934 			return(i);
935 		}
936 #endif /* NROFF */
937 #endif /* EUC */
938 	}
939 	popi();
940 	tty = 0;
941 #ifdef	NROFF
942 	if (quiet)
943 		echo_on();
944 #endif	/* NROFF */
945 	return(0);
946 }
947 
948 
949 int
950 caseec()
951 {
952 	eschar = chget('\\');
953 
954 	return (0);
955 }
956 
957 
958 int
959 caseeo()
960 {
961 	eschar = 0;
962 
963 	return (0);
964 }
965 
966 
967 int
968 caseta()
969 {
970 	int	i;
971 
972 	tabtab[0] = nonumb = 0;
973 	for (i = 0; ((i < (NTAB - 1)) && !nonumb); i++) {
974 		if (skip())
975 			break;
976 		tabtab[i] = max(hnumb(&tabtab[max(i-1,0)]), 0) & TABMASK;
977 		if (!nonumb)
978 			switch (cbits(ch)) {
979 			case 'C':
980 				tabtab[i] |= CTAB;
981 				break;
982 			case 'R':
983 				tabtab[i] |= RTAB;
984 				break;
985 			default: /*includes L*/
986 				break;
987 			}
988 		nonumb = ch = 0;
989 	}
990 	tabtab[i] = 0;
991 
992 	return (0);
993 }
994 
995 
996 int
997 casene()
998 {
999 	int	i, j;
1000 
1001 	skip();
1002 	i = vnumb((int *)0);
1003 	if (nonumb)
1004 		i = lss;
1005 	if (i > (j = findt1())) {
1006 		i = lss;
1007 		lss = j;
1008 		dip->nls = 0;
1009 		newline(0);
1010 		lss = i;
1011 	}
1012 
1013 	return (0);
1014 }
1015 
1016 
1017 int
1018 casetr()
1019 {
1020 	int	i, j;
1021 	tchar k;
1022 
1023 	lgf++;
1024 	skip();
1025 	while ((i = cbits(k=getch())) != '\n') {
1026 		if (ismot(k))
1027 			return (0);
1028 		if (ismot(k = getch()))
1029 			return (0);
1030 		if ((j = cbits(k)) == '\n')
1031 			j = ' ';
1032 		trtab[i] = j;
1033 	}
1034 
1035 	return (0);
1036 }
1037 
1038 
1039 int
1040 casecu()
1041 {
1042 	cu++;
1043 	caseul();
1044 
1045 	return (0);
1046 }
1047 
1048 
1049 int
1050 caseul()
1051 {
1052 	int	i;
1053 
1054 	noscale++;
1055 	if (skip())
1056 		i = 1;
1057 	else
1058 		i = atoi();
1059 	if (ul && (i == 0)) {
1060 		font = sfont;
1061 		ul = cu = 0;
1062 	}
1063 	if (i) {
1064 		if (!ul) {
1065 			sfont = font;
1066 			font = ulfont;
1067 		}
1068 		ul = i;
1069 	}
1070 	noscale = 0;
1071 	mchbits();
1072 
1073 	return (0);
1074 }
1075 
1076 
1077 int
1078 caseuf()
1079 {
1080 	int	i, j;
1081 
1082 	if (skip() || !(i = getrq()) || i == 'S' ||  (j = findft(i))  == -1)
1083 		ulfont = ULFONT; /*default underline position*/
1084 	else
1085 		ulfont = j;
1086 #ifdef NROFF
1087 	if (ulfont == FT)
1088 		ulfont = ULFONT;
1089 #endif
1090 	return (0);
1091 }
1092 
1093 
1094 int
1095 caseit()
1096 {
1097 	int	i;
1098 
1099 	lgf++;
1100 	it = itmac = 0;
1101 	noscale++;
1102 	skip();
1103 	i = atoi();
1104 	skip();
1105 	if (!nonumb && (itmac = getrq()))
1106 		it = i;
1107 	noscale = 0;
1108 
1109 	return (0);
1110 }
1111 
1112 
1113 int
1114 casemc()
1115 {
1116 	int	i;
1117 
1118 	if (icf > 1)
1119 		ic = 0;
1120 	icf = 0;
1121 	if (skip())
1122 		return (0);
1123 	ic = getch();
1124 	icf = 1;
1125 	skip();
1126 	i = max(hnumb((int *)0), 0);
1127 	if (!nonumb)
1128 		ics = i;
1129 
1130 	return (0);
1131 }
1132 
1133 
1134 int
1135 casemk()
1136 {
1137 	int	i, j;
1138 
1139 	if (dip != d)
1140 		j = dip->dnl;
1141 	else
1142 		j = numtab[NL].val;
1143 	if (skip()) {
1144 		dip->mkline = j;
1145 		return (0);
1146 	}
1147 	if ((i = getrq()) == 0)
1148 		return (0);
1149 	numtab[findr(i)].val = j;
1150 
1151 	return (0);
1152 }
1153 
1154 
1155 int
1156 casesv()
1157 {
1158 	int	i;
1159 
1160 	skip();
1161 	if ((i = vnumb((int *)0)) < 0)
1162 		return (0);
1163 	if (nonumb)
1164 		i = 1;
1165 	sv += i;
1166 	caseos();
1167 
1168 	return (0);
1169 }
1170 
1171 
1172 int
1173 caseos()
1174 {
1175 	int	savlss;
1176 
1177 	if (sv <= findt1()) {
1178 		savlss = lss;
1179 		lss = sv;
1180 		newline(0);
1181 		lss = savlss;
1182 		sv = 0;
1183 	}
1184 
1185 	return (0);
1186 }
1187 
1188 
1189 int
1190 casenm()
1191 {
1192 	int	i;
1193 
1194 	lnmod = nn = 0;
1195 	if (skip())
1196 		return (0);
1197 	lnmod++;
1198 	noscale++;
1199 	i = inumb(&numtab[LN].val);
1200 	if (!nonumb)
1201 		numtab[LN].val = max(i, 0);
1202 	getnm(&ndf, 1);
1203 	getnm(&nms, 0);
1204 	getnm(&ni, 0);
1205 	noscale = 0;
1206 	nmbits = chbits;
1207 
1208 	return (0);
1209 }
1210 
1211 
1212 int
1213 getnm(p, min)
1214 int	*p, min;
1215 {
1216 	int	i;
1217 
1218 	eat(' ');
1219 	if (skip())
1220 		return (0);
1221 	i = atoi();
1222 	if (nonumb)
1223 		return (0);
1224 	*p = max(i, min);
1225 
1226 	return (0);
1227 }
1228 
1229 
1230 int
1231 casenn()
1232 {
1233 	noscale++;
1234 	skip();
1235 	nn = max(atoi(), 1);
1236 	noscale = 0;
1237 
1238 	return (0);
1239 }
1240 
1241 
1242 int
1243 caseab()
1244 {
1245 	casetm(1);
1246 	done3(0);
1247 
1248 	return (0);
1249 }
1250 
1251 
1252 #ifdef	NROFF
1253 /*
1254  * The following routines are concerned with setting terminal options.
1255  *	The manner of doing this differs between research/Berkeley systems
1256  *	and UNIX System V systems (i.e. DOCUMENTER'S WORKBENCH)
1257  *	The distinction is controlled by the #define'd variable USG,
1258  *	which must be set by System V users.
1259  */
1260 
1261 
1262 #ifdef	USG
1263 #include <termio.h>
1264 #define	ECHO_USG (ECHO | ECHOE | ECHOK | ECHONL)
1265 struct termio	ttys;
1266 #else
1267 #include <sgtty.h>
1268 struct	sgttyb	ttys[2];
1269 #endif	/* USG */
1270 
1271 int	ttysave[2] = {-1, -1};
1272 
1273 int
1274 save_tty()			/*save any tty settings that may be changed*/
1275 {
1276 
1277 #ifdef	USG
1278 	if (ioctl(0, TCGETA, &ttys) >= 0)
1279 		ttysave[0] = ttys.c_lflag;
1280 #else
1281 	if (gtty(0, &ttys[0]) >= 0)
1282 		ttysave[0] = ttys[0].sg_flags;
1283 	if (gtty(1, &ttys[1]) >= 0)
1284 		ttysave[1] = ttys[1].sg_flags;
1285 #endif	/* USG */
1286 
1287 	return (0);
1288 }
1289 
1290 
1291 int
1292 restore_tty()			/*restore tty settings from beginning*/
1293 {
1294 
1295 	if (ttysave[0] != -1) {
1296 #ifdef	USG
1297 		ttys.c_lflag = ttysave[0];
1298 		ioctl(0, TCSETAW, &ttys);
1299 #else
1300 		ttys[0].sg_flags = ttysave[0];
1301 		stty(0, &ttys[0]);
1302 	}
1303 	if (ttysave[1] != -1) {
1304 		ttys[1].sg_flags = ttysave[1];
1305 		stty(1, &ttys[1]);
1306 #endif	/* USG */
1307 	}
1308 
1309 	return (0);
1310 }
1311 
1312 
1313 int
1314 set_tty()			/*this replaces the use of bset and breset*/
1315 {
1316 
1317 #ifndef	USG			/*for research/BSD only, reset CRMOD*/
1318 	if (ttysave[1] == -1)
1319 		save_tty();
1320 	if (ttysave[1] != -1) {
1321 		ttys[1].sg_flags &= ~CRMOD;
1322 		stty(1, &ttys[1]);
1323 	}
1324 #endif	/* USG */
1325 
1326 	return (0);
1327 }
1328 
1329 
1330 int
1331 echo_off()			/*turn off ECHO for .rd in "-q" mode*/
1332 {
1333 	if (ttysave[0] == -1)
1334 		return (0);
1335 
1336 #ifdef	USG
1337 	ttys.c_lflag &= ~ECHO_USG;
1338 	ioctl(0, TCSETAW, &ttys);
1339 #else
1340 	ttys[0].sg_flags &= ~ECHO;
1341 	stty(0, &ttys[0]);
1342 #endif	/* USG */
1343 
1344 	return (0);
1345 
1346 }
1347 
1348 
1349 int
1350 echo_on()			/*restore ECHO after .rd in "-q" mode*/
1351 {
1352 	if (ttysave[0] == -1)
1353 		return (0);
1354 
1355 #ifdef	USG
1356 	ttys.c_lflag |= ECHO_USG;
1357 	ioctl(0, TCSETAW, &ttys);
1358 #else
1359 	ttys[0].sg_flags |= ECHO;
1360 	stty(0, &ttys[0]);
1361 #endif	/* USG */
1362 
1363 	return (0);
1364 }
1365 #endif	/* NROFF */
1366