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