1 /*
2  * troff5.c
3  *
4  * misc processing requests
5  */
6 
7 #include "tdef.h"
8 #include "fns.h"
9 #include "ext.h"
10 
11 int	iflist[NIF];
12 int	ifx;
13 int	ifnum = 0;	/* trying numeric expression for .if or .ie condition */
14 
casead(void)15 void casead(void)
16 {
17 	int i;
18 
19 	ad = 1;
20 	/* leave admod alone */
21 	if (skip())
22 		return;
23 	switch (i = cbits(getch())) {
24 	case 'r':	/* right adj, left ragged */
25 		admod = 2;
26 		break;
27 	case 'l':	/* left adj, right ragged */
28 		admod = ad = 0;	/* same as casena */
29 		break;
30 	case 'c':	/*centered adj*/
31 		admod = 1;
32 		break;
33 	case 'b':
34 	case 'n':
35 		admod = 0;
36 		break;
37 	case '0':
38 	case '2':
39 	case '4':
40 		ad = 0;
41 	case '1':
42 	case '3':
43 	case '5':
44 		admod = (i - '0') / 2;
45 	}
46 }
47 
48 
casena(void)49 void casena(void)
50 {
51 	ad = 0;
52 }
53 
54 
casefi(void)55 void casefi(void)
56 {
57 	tbreak();
58 	fi = 1;
59 	pendnf = 0;
60 }
61 
62 
casenf(void)63 void casenf(void)
64 {
65 	tbreak();
66 	fi = 0;
67 }
68 
69 
casers(void)70 void casers(void)
71 {
72 	dip->nls = 0;
73 }
74 
75 
casens(void)76 void casens(void)
77 {
78 	dip->nls++;
79 }
80 
81 int
chget(int c)82 chget(int c)
83 {
84 	Tchar i;
85 
86 	i = 0;
87 	if (skip() || ismot(i = getch()) || cbits(i) == ' ' || cbits(i) == '\n') {
88 		ch = i;
89 		return(c);
90 	} else
91 		return cbits(i);	/* was (i & BYTEMASK) */
92 }
93 
94 
casecc(void)95 void casecc(void)
96 {
97 	cc = chget('.');
98 }
99 
100 
casec2(void)101 void casec2(void)
102 {
103 	c2 = chget('\'');
104 }
105 
106 
casehc(void)107 void casehc(void)
108 {
109 	ohc = chget(OHC);
110 }
111 
112 
casetc(void)113 void casetc(void)
114 {
115 	tabc = chget(0);
116 }
117 
118 
caselc(void)119 void caselc(void)
120 {
121 	dotc = chget(0);
122 }
123 
124 
casehy(void)125 void casehy(void)
126 {
127 	int i;
128 
129 	hyf = 1;
130 	if (skip())
131 		return;
132 	noscale++;
133 	i = atoi0();
134 	noscale = 0;
135 	if (nonumb)
136 		return;
137 	hyf = max(i, 0);
138 }
139 
140 
casenh(void)141 void casenh(void)
142 {
143 	hyf = 0;
144 }
145 
146 int
max(int aa,int bb)147 max(int aa, int bb)
148 {
149 	if (aa > bb)
150 		return(aa);
151 	else
152 		return(bb);
153 }
154 
155 
casece(void)156 void casece(void)
157 {
158 	int i;
159 
160 	noscale++;
161 	skip();
162 	i = max(atoi0(), 0);
163 	if (nonumb)
164 		i = 1;
165 	tbreak();
166 	ce = i;
167 	noscale = 0;
168 }
169 
170 
casein(void)171 void casein(void)
172 {
173 	int i;
174 
175 	if (skip())
176 		i = in1;
177 	else {
178 		i = max(hnumb(&in), 0);
179 		if (nonumb)
180 			i = in1;
181 	}
182 	tbreak();
183 	in1 = in;
184 	in = i;
185 	if (!nc) {
186 		un = in;
187 		setnel();
188 	}
189 }
190 
191 
casell(void)192 void casell(void)
193 {
194 	int i;
195 
196 	if (skip())
197 		i = ll1;
198 	else {
199 		i = max(hnumb(&ll), INCH / 10);
200 		if (nonumb)
201 			i = ll1;
202 	}
203 	ll1 = ll;
204 	ll = i;
205 	setnel();
206 }
207 
208 
caselt(void)209 void caselt(void)
210 {
211 	int i;
212 
213 	if (skip())
214 		i = lt1;
215 	else {
216 		i = max(hnumb(&lt), 0);
217 		if (nonumb)
218 			i = lt1;
219 	}
220 	lt1 = lt;
221 	lt = i;
222 }
223 
224 
caseti(void)225 void caseti(void)
226 {
227 	int i;
228 
229 	if (skip())
230 		return;
231 	i = max(hnumb(&in), 0);
232 	tbreak();
233 	un1 = i;
234 	setnel();
235 }
236 
237 
casels(void)238 void casels(void)
239 {
240 	int i;
241 
242 	noscale++;
243 	if (skip())
244 		i = ls1;
245 	else {
246 		i = max(inumb(&ls), 1);
247 		if (nonumb)
248 			i = ls1;
249 	}
250 	ls1 = ls;
251 	ls = i;
252 	noscale = 0;
253 }
254 
255 
casepo(void)256 void casepo(void)
257 {
258 	int i;
259 
260 	if (skip())
261 		i = po1;
262 	else {
263 		i = max(hnumb(&po), 0);
264 		if (nonumb)
265 			i = po1;
266 	}
267 	po1 = po;
268 	po = i;
269 	if (TROFF & !ascii)
270 		esc += po - po1;
271 }
272 
273 
casepl(void)274 void casepl(void)
275 {
276 	int i;
277 
278 	skip();
279 	if ((i = vnumb(&pl)) == 0)
280 		pl = 11 * INCH; /*11in*/
281 	else
282 		pl = i;
283 	if (numtabp[NL].val > pl)
284 		numtabp[NL].val = pl;
285 }
286 
287 
casewh(void)288 void casewh(void)
289 {
290 	int i, j, k;
291 
292 	lgf++;
293 	skip();
294 	i = vnumb((int *)0);
295 	if (nonumb)
296 		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++)
304 		if (mlist[k] == 0)
305 			break;
306 	if (k == NTRAP) {
307 		flusho();
308 		ERROR "cannot plant trap." WARN;
309 		return;
310 	}
311 	mlist[k] = j;
312 	nlist[k] = i;
313 }
314 
315 
casech(void)316 void casech(void)
317 {
318 	int i, j, k;
319 
320 	lgf++;
321 	skip();
322 	if (!(j = getrq()))
323 		return;
324 	else
325 		for (k = 0; k < NTRAP; k++)
326 			if (mlist[k] == j)
327 				break;
328 	if (k == NTRAP)
329 		return;
330 	skip();
331 	i = vnumb((int *)0);
332 	if (nonumb)
333 		mlist[k] = 0;
334 	nlist[k] = i;
335 }
336 
337 int
findn(int i)338 findn(int i)
339 {
340 	int k;
341 
342 	for (k = 0; k < NTRAP; k++)
343 		if ((nlist[k] == i) && (mlist[k] != 0))
344 			break;
345 	return(k);
346 }
347 
348 
casepn(void)349 void casepn(void)
350 {
351 	int i;
352 
353 	skip();
354 	noscale++;
355 	i = max(inumb(&numtabp[PN].val), 0);
356 	noscale = 0;
357 	if (!nonumb) {
358 		npn = i;
359 		npnflg++;
360 	}
361 }
362 
363 
casebp(void)364 void casebp(void)
365 {
366 	int i;
367 	Stack *savframe;
368 
369 	if (dip != d)
370 		return;
371 	savframe = frame;
372 	skip();
373 	if ((i = inumb(&numtabp[PN].val)) < 0)
374 		i = 0;
375 	tbreak();
376 	if (!nonumb) {
377 		npn = i;
378 		npnflg++;
379 	} else if (dip->nls)
380 		return;
381 	eject(savframe);
382 }
383 
casetm(void)384 void casetm(void)
385 {
386 	casetm1(0, stderr);
387 }
388 
389 
casefm(void)390 void casefm(void)
391 {
392 	static struct fcache {
393 		char *name;
394 		FILE *fp;
395 	} fcache[15];
396 	int i;
397 
398 	if ( skip() || !getname()) {
399 		ERROR "fm: missing filename" WARN;
400 		return;
401 	}
402 
403 	for (i = 0; i < 15 && fcache[i].fp != NULL; i++) {
404 		if (strcmp(nextf, fcache[i].name) == 0)
405 			break;
406 	}
407 	if (i >= 15) {
408 		ERROR "fm: too many streams" WARN;
409 		return;
410 	}
411 	if (fcache[i].fp == NULL) {
412 		if( (fcache[i].fp = fopen(unsharp(nextf), "w")) == NULL) {
413 			ERROR "fm: cannot open %s", nextf WARN;
414 			return;
415 		}
416 		fcache[i].name = strdupl(nextf);
417 	}
418 	casetm1(0, fcache[i].fp);
419 }
420 
casetm1(int ab,FILE * out)421 void casetm1(int ab, FILE *out)
422 {
423 	int i, j, c;
424 	char *p;
425 	char tmbuf[NTM];
426 
427 	lgf++;
428 	copyf++;
429 	if (ab) {
430 		if (skip())
431 			ERROR "User Abort" WARN;
432 		else {
433 			extern int error;
434 			int savtrac = trace;
435 			i = trace = 0;
436 			noscale++;
437 			i = inumb(&trace);
438 			noscale--;
439 			if (i) {
440 				error = i;
441 				if (nlflg || skip())
442 					ERROR "User Abort, exit code %d", i WARN;
443 			}
444 			trace = savtrac;
445 		}
446 	} else
447 		skip();
448 	for (i = 0; i < NTM - 2; ) {
449 		if ((c = cbits(getch())) == '\n' || c == RIGHT)
450 			break;
451 		else if (c == MINUS) {	/* special pleading for strange encodings */
452 			tmbuf[i++] = '\\';
453 			tmbuf[i++] = '-';
454 		} else if (c == PRESC) {
455 			tmbuf[i++] = '\\';
456 			tmbuf[i++] = 'e';
457 		} else if (c == FILLER) {
458 			tmbuf[i++] = '\\';
459 			tmbuf[i++] = '&';
460 		} else if (c == UNPAD) {
461 			tmbuf[i++] = '\\';
462 			tmbuf[i++] = ' ';
463 		} else if (c == OHC) {
464 			tmbuf[i++] = '\\';
465 			tmbuf[i++] = '%';
466 		} else if (c >= ALPHABET) {
467 			p = chname(c);
468 			switch (*p) {
469 			case MBchar:
470 				strcpy(&tmbuf[i], p+1);
471 				break;
472 			case Number:
473 				sprintf(&tmbuf[i], "\\N'%s'", p+1);
474 				break;
475 			case Troffchar:
476 				if ((j = strlen(p+1)) == 2)
477 					sprintf(&tmbuf[i], "\\(%s", p+1);
478 				else
479 					sprintf(&tmbuf[i], "\\C'%s'", p+1);
480 				break;
481 			default:
482 				sprintf(&tmbuf[i]," %s? ", p);
483 				break;
484 			}
485 			j = strlen(&tmbuf[i]);
486 			i += j;
487 		} else
488 			tmbuf[i++] = c;
489 	}
490 	tmbuf[i] = 0;
491 	if (ab)	/* truncate output */
492 		obufp = obuf;	/* should be a function in n2.c */
493 	flusho();
494 	if (i)
495 		fprintf(out, "%s\n", tmbuf);
496 	fflush(out);
497 	copyf--;
498 	lgf--;
499 }
500 
501 
casesp(void)502 void casesp(void)
503 {
504 	casesp1(0);
505 }
506 
casesp1(int a)507 void casesp1(int a)
508 {
509 	int i, j, savlss;
510 
511 	tbreak();
512 	if (dip->nls || trap)
513 		return;
514 	i = findt1();
515 	if (!a) {
516 		skip();
517 		j = vnumb((int *)0);
518 		if (nonumb)
519 			j = lss;
520 	} else
521 		j = a;
522 	if (j == 0)
523 		return;
524 	if (i < j)
525 		j = i;
526 	savlss = lss;
527 	if (dip != d)
528 		i = dip->dnl;
529 	else
530 		i = numtabp[NL].val;
531 	if ((i + j) < 0)
532 		j = -i;
533 	lss = j;
534 	newline(0);
535 	lss = savlss;
536 }
537 
538 
casert(void)539 void casert(void)
540 {
541 	int a, *p;
542 
543 	skip();
544 	if (dip != d)
545 		p = &dip->dnl;
546 	else
547 		p = &numtabp[NL].val;
548 	a = vnumb(p);
549 	if (nonumb)
550 		a = dip->mkline;
551 	if ((a < 0) || (a >= *p))
552 		return;
553 	nb++;
554 	casesp1(a - *p);
555 }
556 
557 
caseem(void)558 void caseem(void)
559 {
560 	lgf++;
561 	skip();
562 	em = getrq();
563 }
564 
565 
casefl(void)566 void casefl(void)
567 {
568 	tbreak();
569 	if (!ascii)
570 		ptflush();
571 	flusho();
572 }
573 
574 
caseev(void)575 void caseev(void)
576 {
577 	int nxev;
578 
579 	if (skip()) {
580 e0:
581 		if (evi == 0)
582 			return;
583 		nxev =  evlist[--evi];
584 		goto e1;
585 	}
586 	noscale++;
587 	nxev = atoi0();
588 	noscale = 0;
589 	if (nonumb)
590 		goto e0;
591 	flushi();
592 	if (nxev >= NEV || nxev < 0 || evi >= EVLSZ) {
593 		flusho();
594 		ERROR "cannot do .ev %d", nxev WARN;
595 		if (error)
596 			done2(040);
597 		else
598 			edone(040);
599 		return;
600 	}
601 	evlist[evi++] = ev;
602 e1:
603 	if (ev == nxev)
604 		return;
605 	ev = nxev;
606 	envp = &env[ev];
607 }
608 
envcopy(Env * e1,Env * e2)609 void envcopy(Env *e1, Env *e2)	/* copy env e2 to e1 */
610 {
611 	*e1 = *e2;	/* rumor hath that this fails on some machines */
612 }
613 
614 
caseel(void)615 void caseel(void)
616 {
617 	if (--ifx < 0) {
618 		ifx = 0;
619 		iflist[0] = 0;
620 	}
621 	caseif1(2);
622 }
623 
624 
caseie(void)625 void caseie(void)
626 {
627 	if (ifx >= NIF) {
628 		ERROR "if-else overflow." WARN;
629 		ifx = 0;
630 		edone(040);
631 	}
632 	caseif1(1);
633 	ifx++;
634 }
635 
636 
caseif(void)637 void caseif(void)
638 {
639 	caseif1(0);
640 }
641 
caseif1(int x)642 void caseif1(int x)
643 {
644 	extern int falsef;
645 	int notflag, true;
646 	Tchar i;
647 
648 	if (x == 2) {
649 		notflag = 0;
650 		true = iflist[ifx];
651 		goto i1;
652 	}
653 	true = 0;
654 	skip();
655 	if ((cbits(i = getch())) == '!') {
656 		notflag = 1;
657 	} else {
658 		notflag = 0;
659 		ch = i;
660 	}
661 	ifnum++;
662 	i = atoi0();
663 	ifnum = 0;
664 	if (!nonumb) {
665 		if (i > 0)
666 			true++;
667 		goto i1;
668 	}
669 	i = getch();
670 	switch (cbits(i)) {
671 	case 'e':
672 		if (!(numtabp[PN].val & 01))
673 			true++;
674 		break;
675 	case 'o':
676 		if (numtabp[PN].val & 01)
677 			true++;
678 		break;
679 	case 'n':
680 		if (NROFF)
681 			true++;
682 		break;
683 	case 't':
684 		if (TROFF)
685 			true++;
686 		break;
687 	case ' ':
688 		break;
689 	default:
690 		true = cmpstr(i);
691 	}
692 i1:
693 	true ^= notflag;
694 	if (x == 1)
695 		iflist[ifx] = !true;
696 	if (true) {
697 i2:
698 		while ((cbits(i = getch())) == ' ')
699 			;
700 		if (cbits(i) == LEFT)
701 			goto i2;
702 		ch = i;
703 		nflush++;
704 	} else {
705 		if (!nlflg) {
706 			copyf++;
707 			falsef++;
708 			eatblk(0);
709 			copyf--;
710 			falsef--;
711 		}
712 	}
713 }
714 
eatblk(int inblk)715 void eatblk(int inblk)
716 {
717 	int cnt, i;
718 
719 	cnt = 0;
720 	do {
721 		if (ch)	{
722 			i = cbits(ch);
723 			ch = 0;
724 		} else
725 			i = cbits(getch0());
726 		if (i == ESC)
727 			cnt++;
728 		else {
729 			if (cnt == 1)
730 				switch (i) {
731 				case '{':  i = LEFT; break;
732 				case '}':  i = RIGHT; break;
733 				case '\n': i = 'x'; break;
734 				}
735 			cnt = 0;
736 		}
737 		if (i == LEFT) eatblk(1);
738 	} while ((!inblk && (i != '\n')) || (inblk && (i != RIGHT)));
739 	if (i == '\n') {
740 		nlflg++;
741 		if (ip == 0)
742 			numtabp[CD].val++;
743 	}
744 }
745 
746 int
cmpstr(Tchar c)747 cmpstr(Tchar c)
748 {
749 	int j, delim;
750 	Tchar i;
751 	int val;
752 	int savapts, savapts1, savfont, savfont1, savpts, savpts1;
753 	Tchar string[1280];
754 	Tchar *sp;
755 
756 	if (ismot(c))
757 		return(0);
758 	delim = cbits(c);
759 	savapts = apts;
760 	savapts1 = apts1;
761 	savfont = font;
762 	savfont1 = font1;
763 	savpts = pts;
764 	savpts1 = pts1;
765 	sp = string;
766 	while ((j = cbits(i = getch()))!=delim && j!='\n' && sp<&string[1280-1])
767 		*sp++ = i;
768 	if (sp >= string + 1280) {
769 		ERROR "too-long string compare." WARN;
770 		edone(0100);
771 	}
772 	if (nlflg) {
773 		val = sp==string;
774 		goto rtn;
775 	}
776 	*sp = 0;
777 	apts = savapts;
778 	apts1 = savapts1;
779 	font = savfont;
780 	font1 = savfont1;
781 	pts = savpts;
782 	pts1 = savpts1;
783 	mchbits();
784 	val = 1;
785 	sp = string;
786 	while ((j = cbits(i = getch())) != delim && j != '\n') {
787 		if (*sp != i) {
788 			eat(delim);
789 			val = 0;
790 			goto rtn;
791 		}
792 		sp++;
793 	}
794 	if (*sp)
795 		val = 0;
796 rtn:
797 	apts = savapts;
798 	apts1 = savapts1;
799 	font = savfont;
800 	font1 = savfont1;
801 	pts = savpts;
802 	pts1 = savpts1;
803 	mchbits();
804 	return(val);
805 }
806 
807 
caserd(void)808 void caserd(void)
809 {
810 
811 	lgf++;
812 	skip();
813 	getname();
814 	if (!iflg) {
815 		if (quiet) {
816 			if (NROFF) {
817 				echo_off();
818 				flusho();
819 			}
820 			fprintf(stderr, "\007"); /*bell*/
821 		} else {
822 			if (nextf[0]) {
823 				fprintf(stderr, "%s:", nextf);
824 			} else {
825 				fprintf(stderr, "\007"); /*bell*/
826 			}
827 		}
828 	}
829 	collect();
830 	tty++;
831 	pushi(RD_OFFSET, PAIR('r','d'));
832 }
833 
834 int
rdtty(void)835 rdtty(void)
836 {
837 	char	onechar;
838 
839 	onechar = 0;
840 	if (read(0, &onechar, 1) == 1) {
841 		if (onechar == '\n')
842 			tty++;
843 		else
844 			tty = 1;
845 		if (tty != 3)
846 			return(onechar);
847 	}
848 	tty = 0;
849 	if (NROFF && quiet)
850 		echo_on();
851 	return(0);
852 }
853 
854 
caseec(void)855 void caseec(void)
856 {
857 	eschar = chget('\\');
858 }
859 
860 
caseeo(void)861 void caseeo(void)
862 {
863 	eschar = 0;
864 }
865 
866 
caseta(void)867 void caseta(void)
868 {
869 	int i, j, k;
870 
871 	tabtab[0] = nonumb = 0;
872 	for (i = 0; ((i < (NTAB - 1)) && !nonumb); i++) {
873 		if (skip())
874 			break;
875 		k = tabtab[max(i-1, 0)] & TABMASK;
876 		if ((j = max(hnumb(&k), 0)) > TABMASK) {
877 			ERROR "Tab too far away" WARN;
878 			j = TABMASK;
879 		}
880 		tabtab[i] = j & TABMASK;
881 		if (!nonumb)
882 			switch (cbits(ch)) {
883 			case 'C':
884 				tabtab[i] |= CTAB;
885 				break;
886 			case 'R':
887 				tabtab[i] |= RTAB;
888 				break;
889 			default: /*includes L*/
890 				break;
891 			}
892 		nonumb = ch = 0;
893 	}
894 	if (!skip())
895 		ERROR "Too many tab stops" WARN;
896 	tabtab[i] = 0;
897 }
898 
899 
casene(void)900 void casene(void)
901 {
902 	int i, j;
903 
904 	skip();
905 	i = vnumb((int *)0);
906 	if (nonumb)
907 		i = lss;
908 	if (dip == d && numtabp[NL].val == -1) {
909 		newline(1);
910 		return;
911 	}
912 	if (i > (j = findt1())) {
913 		i = lss;
914 		lss = j;
915 		dip->nls = 0;
916 		newline(0);
917 		lss = i;
918 	}
919 }
920 
921 
casetr(void)922 void casetr(void)
923 {
924 	int i, j;
925 	Tchar k;
926 
927 	lgf++;
928 	skip();
929 	while ((i = cbits(k=getch())) != '\n') {
930 		if (ismot(k))
931 			return;
932 		if (ismot(k = getch()))
933 			return;
934 		if ((j = cbits(k)) == '\n')
935 			j = ' ';
936 		trtab[i] = j;
937 	}
938 }
939 
940 
casecu(void)941 void casecu(void)
942 {
943 	cu++;
944 	caseul();
945 }
946 
947 
caseul(void)948 void caseul(void)
949 {
950 	int i;
951 
952 	noscale++;
953 	skip();
954 	i = max(atoi0(), 0);
955 	if (nonumb)
956 		i = 1;
957 	if (ul && (i == 0)) {
958 		font = sfont;
959 		ul = cu = 0;
960 	}
961 	if (i) {
962 		if (!ul) {
963 			sfont = font;
964 			font = ulfont;
965 		}
966 		ul = i;
967 	}
968 	noscale = 0;
969 	mchbits();
970 }
971 
972 
caseuf(void)973 void caseuf(void)
974 {
975 	int i, j;
976 
977 	if (skip() || !(i = getrq()) || i == 'S' ||  (j = findft(i))  == -1)
978 		ulfont = ULFONT; /*default underline position*/
979 	else
980 		ulfont = j;
981 	if (NROFF && ulfont == FT)
982 		ulfont = ULFONT;
983 }
984 
985 
caseit(void)986 void caseit(void)
987 {
988 	int i;
989 
990 	lgf++;
991 	it = itmac = 0;
992 	noscale++;
993 	skip();
994 	i = atoi0();
995 	skip();
996 	if (!nonumb && (itmac = getrq()))
997 		it = i;
998 	noscale = 0;
999 }
1000 
1001 
casemc(void)1002 void casemc(void)
1003 {
1004 	int i;
1005 
1006 	if (icf > 1)
1007 		ic = 0;
1008 	icf = 0;
1009 	if (skip())
1010 		return;
1011 	ic = getch();
1012 	icf = 1;
1013 	skip();
1014 	i = max(hnumb((int *)0), 0);
1015 	if (!nonumb)
1016 		ics = i;
1017 }
1018 
1019 
casemk(void)1020 void casemk(void)
1021 {
1022 	int i, j;
1023 
1024 	if (dip != d)
1025 		j = dip->dnl;
1026 	else
1027 		j = numtabp[NL].val;
1028 	if (skip()) {
1029 		dip->mkline = j;
1030 		return;
1031 	}
1032 	if ((i = getrq()) == 0)
1033 		return;
1034 	numtabp[findr(i)].val = j;
1035 }
1036 
1037 
casesv(void)1038 void casesv(void)
1039 {
1040 	int i;
1041 
1042 	skip();
1043 	if ((i = vnumb((int *)0)) < 0)
1044 		return;
1045 	if (nonumb)
1046 		i = 1;
1047 	sv += i;
1048 	caseos();
1049 }
1050 
1051 
caseos(void)1052 void caseos(void)
1053 {
1054 	int savlss;
1055 
1056 	if (sv <= findt1()) {
1057 		savlss = lss;
1058 		lss = sv;
1059 		newline(0);
1060 		lss = savlss;
1061 		sv = 0;
1062 	}
1063 }
1064 
1065 
casenm(void)1066 void casenm(void)
1067 {
1068 	int i;
1069 
1070 	lnmod = nn = 0;
1071 	if (skip())
1072 		return;
1073 	lnmod++;
1074 	noscale++;
1075 	i = inumb(&numtabp[LN].val);
1076 	if (!nonumb)
1077 		numtabp[LN].val = max(i, 0);
1078 	getnm(&ndf, 1);
1079 	getnm(&nms, 0);
1080 	getnm(&ni, 0);
1081 	getnm(&nmwid, 3);	/* really kludgy! */
1082 	noscale = 0;
1083 	nmbits = chbits;
1084 }
1085 
1086 /*
1087  * .nm relies on the fact that illegal args are skipped; don't warn
1088  * for illegality of these
1089  */
getnm(int * p,int min)1090 void getnm(int *p, int min)
1091 {
1092 	int i;
1093 	int savtr = trace;
1094 
1095 	eat(' ');
1096 	if (skip())
1097 		return;
1098 	trace = 0;
1099 	i = atoi0();
1100 	if (nonumb)
1101 		return;
1102 	*p = max(i, min);
1103 	trace = savtr;
1104 }
1105 
1106 
casenn(void)1107 void casenn(void)
1108 {
1109 	noscale++;
1110 	skip();
1111 	nn = max(atoi0(), 1);
1112 	noscale = 0;
1113 }
1114 
1115 
caseab(void)1116 void caseab(void)
1117 {
1118 	casetm1(1, stderr);
1119 	done3(0);
1120 }
1121 
1122 
1123 /* nroff terminal handling has been pretty well excised */
1124 /* as part of the merge with troff.  these are ghostly remnants, */
1125 /* called, but doing nothing. restore them at your peril. */
1126 
1127 
save_tty(void)1128 void save_tty(void)			/*save any tty settings that may be changed*/
1129 {
1130 }
1131 
1132 
restore_tty(void)1133 void restore_tty(void)			/*restore tty settings from beginning*/
1134 {
1135 }
1136 
1137 
set_tty(void)1138 void set_tty(void)
1139 {
1140 }
1141 
1142 
echo_off(void)1143 void echo_off(void)			/*turn off ECHO for .rd in "-q" mode*/
1144 {
1145 }
1146 
1147 
echo_on(void)1148 void echo_on(void)			/*restore ECHO after .rd in "-q" mode*/
1149 {
1150 }
1151