xref: /freebsd/contrib/less/optfunc.c (revision 82ea1a07b4894bea20c61afbf702cc46f0711ead)
1 /*
2  * Copyright (C) 1984-2021  Mark Nudelman
3  *
4  * You may distribute under the terms of either the GNU General Public
5  * License or the Less License, as specified in the README file.
6  *
7  * For more information, see the README file.
8  */
9 
10 
11 /*
12  * Handling functions for command line options.
13  *
14  * Most options are handled by the generic code in option.c.
15  * But all string options, and a few non-string options, require
16  * special handling specific to the particular option.
17  * This special processing is done by the "handling functions" in this file.
18  *
19  * Each handling function is passed a "type" and, if it is a string
20  * option, the string which should be "assigned" to the option.
21  * The type may be one of:
22  *      INIT    The option is being initialized from the command line.
23  *      TOGGLE  The option is being changed from within the program.
24  *      QUERY   The setting of the option is merely being queried.
25  */
26 
27 #include "less.h"
28 #include "option.h"
29 
30 extern int nbufs;
31 extern int bufspace;
32 extern int pr_type;
33 extern int plusoption;
34 extern int swindow;
35 extern int sc_width;
36 extern int sc_height;
37 extern int secure;
38 extern int dohelp;
39 extern int is_tty;
40 extern char openquote;
41 extern char closequote;
42 extern char *prproto[];
43 extern char *eqproto;
44 extern char *hproto;
45 extern char *wproto;
46 extern char *every_first_cmd;
47 extern IFILE curr_ifile;
48 extern char version[];
49 extern int jump_sline;
50 extern long jump_sline_fraction;
51 extern int shift_count;
52 extern long shift_count_fraction;
53 extern char rscroll_char;
54 extern int rscroll_attr;
55 extern int mousecap;
56 extern int wheel_lines;
57 extern int less_is_more;
58 extern int linenum_width;
59 extern int status_col_width;
60 extern int use_color;
61 #if LOGFILE
62 extern char *namelogfile;
63 extern int force_logfile;
64 extern int logfile;
65 #endif
66 #if TAGS
67 public char *tagoption = NULL;
68 extern char *tags;
69 extern char ztags[];
70 #endif
71 #if LESSTEST
72 extern char *ttyin_name;
73 extern int rstat_file;
74 #endif /*LESSTEST*/
75 #if MSDOS_COMPILER
76 extern int nm_fg_color, nm_bg_color;
77 extern int bo_fg_color, bo_bg_color;
78 extern int ul_fg_color, ul_bg_color;
79 extern int so_fg_color, so_bg_color;
80 extern int bl_fg_color, bl_bg_color;
81 extern int sgr_mode;
82 #if MSDOS_COMPILER==WIN32C
83 #ifndef COMMON_LVB_UNDERSCORE
84 #define COMMON_LVB_UNDERSCORE 0x8000
85 #endif
86 #endif
87 #endif
88 
89 
90 #if LOGFILE
91 /*
92  * Handler for -o option.
93  */
94 	public void
95 opt_o(type, s)
96 	int type;
97 	char *s;
98 {
99 	PARG parg;
100 	char *filename;
101 
102 	if (secure)
103 	{
104 		error("log file support is not available", NULL_PARG);
105 		return;
106 	}
107 	switch (type)
108 	{
109 	case INIT:
110 		namelogfile = save(s);
111 		break;
112 	case TOGGLE:
113 		if (ch_getflags() & CH_CANSEEK)
114 		{
115 			error("Input is not a pipe", NULL_PARG);
116 			return;
117 		}
118 		if (logfile >= 0)
119 		{
120 			error("Log file is already in use", NULL_PARG);
121 			return;
122 		}
123 		s = skipsp(s);
124 		if (namelogfile != NULL)
125 			free(namelogfile);
126 		filename = lglob(s);
127 		namelogfile = shell_unquote(filename);
128 		free(filename);
129 		use_logfile(namelogfile);
130 		sync_logfile();
131 		break;
132 	case QUERY:
133 		if (logfile < 0)
134 			error("No log file", NULL_PARG);
135 		else
136 		{
137 			parg.p_string = namelogfile;
138 			error("Log file \"%s\"", &parg);
139 		}
140 		break;
141 	}
142 }
143 
144 /*
145  * Handler for -O option.
146  */
147 	public void
148 opt__O(type, s)
149 	int type;
150 	char *s;
151 {
152 	force_logfile = TRUE;
153 	opt_o(type, s);
154 }
155 #endif
156 
157 /*
158  * Handlers for -j option.
159  */
160 	public void
161 opt_j(type, s)
162 	int type;
163 	char *s;
164 {
165 	PARG parg;
166 	char buf[16];
167 	int len;
168 	int err;
169 
170 	switch (type)
171 	{
172 	case INIT:
173 	case TOGGLE:
174 		if (*s == '.')
175 		{
176 			s++;
177 			jump_sline_fraction = getfraction(&s, "j", &err);
178 			if (err)
179 				error("Invalid line fraction", NULL_PARG);
180 			else
181 				calc_jump_sline();
182 		} else
183 		{
184 			int sline = getnum(&s, "j", &err);
185 			if (err)
186 				error("Invalid line number", NULL_PARG);
187 			else
188 			{
189 				jump_sline = sline;
190 				jump_sline_fraction = -1;
191 			}
192 		}
193 		break;
194 	case QUERY:
195 		if (jump_sline_fraction < 0)
196 		{
197 			parg.p_int =  jump_sline;
198 			error("Position target at screen line %d", &parg);
199 		} else
200 		{
201 
202 			sprintf(buf, ".%06ld", jump_sline_fraction);
203 			len = (int) strlen(buf);
204 			while (len > 2 && buf[len-1] == '0')
205 				len--;
206 			buf[len] = '\0';
207 			parg.p_string = buf;
208 			error("Position target at screen position %s", &parg);
209 		}
210 		break;
211 	}
212 }
213 
214 	public void
215 calc_jump_sline(VOID_PARAM)
216 {
217 	if (jump_sline_fraction < 0)
218 		return;
219 	jump_sline = sc_height * jump_sline_fraction / NUM_FRAC_DENOM;
220 }
221 
222 /*
223  * Handlers for -# option.
224  */
225 	public void
226 opt_shift(type, s)
227 	int type;
228 	char *s;
229 {
230 	PARG parg;
231 	char buf[16];
232 	int len;
233 	int err;
234 
235 	switch (type)
236 	{
237 	case INIT:
238 	case TOGGLE:
239 		if (*s == '.')
240 		{
241 			s++;
242 			shift_count_fraction = getfraction(&s, "#", &err);
243 			if (err)
244 				error("Invalid column fraction", NULL_PARG);
245 			else
246 				calc_shift_count();
247 		} else
248 		{
249 			int hs = getnum(&s, "#", &err);
250 			if (err)
251 				error("Invalid column number", NULL_PARG);
252 			else
253 			{
254 				shift_count = hs;
255 				shift_count_fraction = -1;
256 			}
257 		}
258 		break;
259 	case QUERY:
260 		if (shift_count_fraction < 0)
261 		{
262 			parg.p_int = shift_count;
263 			error("Horizontal shift %d columns", &parg);
264 		} else
265 		{
266 
267 			sprintf(buf, ".%06ld", shift_count_fraction);
268 			len = (int) strlen(buf);
269 			while (len > 2 && buf[len-1] == '0')
270 				len--;
271 			buf[len] = '\0';
272 			parg.p_string = buf;
273 			error("Horizontal shift %s of screen width", &parg);
274 		}
275 		break;
276 	}
277 }
278 	public void
279 calc_shift_count(VOID_PARAM)
280 {
281 	if (shift_count_fraction < 0)
282 		return;
283 	shift_count = sc_width * shift_count_fraction / NUM_FRAC_DENOM;
284 }
285 
286 #if USERFILE
287 	public void
288 opt_k(type, s)
289 	int type;
290 	char *s;
291 {
292 	PARG parg;
293 
294 	switch (type)
295 	{
296 	case INIT:
297 		if (lesskey(s, 0))
298 		{
299 			parg.p_string = s;
300 			error("Cannot use lesskey file \"%s\"", &parg);
301 		}
302 		break;
303 	}
304 }
305 #endif
306 
307 #if TAGS
308 /*
309  * Handler for -t option.
310  */
311 	public void
312 opt_t(type, s)
313 	int type;
314 	char *s;
315 {
316 	IFILE save_ifile;
317 	POSITION pos;
318 
319 	switch (type)
320 	{
321 	case INIT:
322 		tagoption = save(s);
323 		/* Do the rest in main() */
324 		break;
325 	case TOGGLE:
326 		if (secure)
327 		{
328 			error("tags support is not available", NULL_PARG);
329 			break;
330 		}
331 		findtag(skipsp(s));
332 		save_ifile = save_curr_ifile();
333 		/*
334 		 * Try to open the file containing the tag
335 		 * and search for the tag in that file.
336 		 */
337 		if (edit_tagfile() || (pos = tagsearch()) == NULL_POSITION)
338 		{
339 			/* Failed: reopen the old file. */
340 			reedit_ifile(save_ifile);
341 			break;
342 		}
343 		unsave_ifile(save_ifile);
344 		jump_loc(pos, jump_sline);
345 		break;
346 	}
347 }
348 
349 /*
350  * Handler for -T option.
351  */
352 	public void
353 opt__T(type, s)
354 	int type;
355 	char *s;
356 {
357 	PARG parg;
358 	char *filename;
359 
360 	switch (type)
361 	{
362 	case INIT:
363 		tags = save(s);
364 		break;
365 	case TOGGLE:
366 		s = skipsp(s);
367 		if (tags != NULL && tags != ztags)
368 			free(tags);
369 		filename = lglob(s);
370 		tags = shell_unquote(filename);
371 		free(filename);
372 		break;
373 	case QUERY:
374 		parg.p_string = tags;
375 		error("Tags file \"%s\"", &parg);
376 		break;
377 	}
378 }
379 #endif
380 
381 /*
382  * Handler for -p option.
383  */
384 	public void
385 opt_p(type, s)
386 	int type;
387 	char *s;
388 {
389 	switch (type)
390 	{
391 	case INIT:
392 		/*
393 		 * Unget a command for the specified string.
394 		 */
395 		if (less_is_more)
396 		{
397 			/*
398 			 * In "more" mode, the -p argument is a command,
399 			 * not a search string, so we don't need a slash.
400 			 */
401 			every_first_cmd = save(s);
402 		} else
403 		{
404 			plusoption = TRUE;
405 			 /*
406 			  * {{ This won't work if the "/" command is
407 			  *    changed or invalidated by a .lesskey file. }}
408 			  */
409 			ungetsc("/");
410 			ungetsc(s);
411 			ungetcc_back(CHAR_END_COMMAND);
412 		}
413 		break;
414 	}
415 }
416 
417 /*
418  * Handler for -P option.
419  */
420 	public void
421 opt__P(type, s)
422 	int type;
423 	char *s;
424 {
425 	char **proto;
426 	PARG parg;
427 
428 	switch (type)
429 	{
430 	case INIT:
431 	case TOGGLE:
432 		/*
433 		 * Figure out which prototype string should be changed.
434 		 */
435 		switch (*s)
436 		{
437 		case 's':  proto = &prproto[PR_SHORT];  s++;    break;
438 		case 'm':  proto = &prproto[PR_MEDIUM]; s++;    break;
439 		case 'M':  proto = &prproto[PR_LONG];   s++;    break;
440 		case '=':  proto = &eqproto;            s++;    break;
441 		case 'h':  proto = &hproto;             s++;    break;
442 		case 'w':  proto = &wproto;             s++;    break;
443 		default:   proto = &prproto[PR_SHORT];          break;
444 		}
445 		free(*proto);
446 		*proto = save(s);
447 		break;
448 	case QUERY:
449 		parg.p_string = prproto[pr_type];
450 		error("%s", &parg);
451 		break;
452 	}
453 }
454 
455 /*
456  * Handler for the -b option.
457  */
458 	/*ARGSUSED*/
459 	public void
460 opt_b(type, s)
461 	int type;
462 	char *s;
463 {
464 	switch (type)
465 	{
466 	case INIT:
467 	case TOGGLE:
468 		/*
469 		 * Set the new number of buffers.
470 		 */
471 		ch_setbufspace(bufspace);
472 		break;
473 	case QUERY:
474 		break;
475 	}
476 }
477 
478 /*
479  * Handler for the -i option.
480  */
481 	/*ARGSUSED*/
482 	public void
483 opt_i(type, s)
484 	int type;
485 	char *s;
486 {
487 	switch (type)
488 	{
489 	case TOGGLE:
490 		chg_caseless();
491 		break;
492 	case QUERY:
493 	case INIT:
494 		break;
495 	}
496 }
497 
498 /*
499  * Handler for the -V option.
500  */
501 	/*ARGSUSED*/
502 	public void
503 opt__V(type, s)
504 	int type;
505 	char *s;
506 {
507 	switch (type)
508 	{
509 	case TOGGLE:
510 	case QUERY:
511 		dispversion();
512 		break;
513 	case INIT:
514 		set_output(1); /* Force output to stdout per GNU standard for --version output. */
515 		putstr("less ");
516 		putstr(version);
517 		putstr(" (");
518 		putstr(pattern_lib_name());
519 		putstr(" regular expressions)\n");
520 		{
521 			char constant *copyright = "Copyright (C) 1984-2021  Mark Nudelman\n\n";
522 			if (copyright[0] == '@')
523 				copyright = "Copyright (C) 1984  Mark Nudelman\n\n";
524 			putstr(copyright);
525 		}
526 		if (version[strlen(version)-1] == 'x')
527 		{
528 			putstr("** This is an EXPERIMENTAL build of the 'less' software,\n");
529 			putstr("** and may not function correctly.\n");
530 			putstr("** Obtain release builds from the web page below.\n\n");
531 		}
532 		putstr("less comes with NO WARRANTY, to the extent permitted by law.\n");
533 		putstr("For information about the terms of redistribution,\n");
534 		putstr("see the file named README in the less distribution.\n");
535 		putstr("Home page: https://greenwoodsoftware.com/less\n");
536 		quit(QUIT_OK);
537 		break;
538 	}
539 }
540 
541 #if MSDOS_COMPILER
542 /*
543  * Parse an MSDOS color descriptor.
544  */
545 	static void
546 colordesc(s, fg_color, bg_color)
547 	char *s;
548 	int *fg_color;
549 	int *bg_color;
550 {
551 	int fg, bg;
552 #if MSDOS_COMPILER==WIN32C
553 	int ul = 0;
554 
555 	if (*s == 'u')
556 	{
557 		ul = COMMON_LVB_UNDERSCORE;
558 		s++;
559 		if (*s == '\0')
560 		{
561 			*fg_color = nm_fg_color | ul;
562 			*bg_color = nm_bg_color;
563 			return;
564 		}
565 	}
566 #endif
567 	if (parse_color(s, &fg, &bg) == CT_NULL)
568 	{
569 		PARG p;
570 		p.p_string = s;
571 		error("Invalid color string \"%s\"", &p);
572 	} else
573 	{
574 		if (fg == CV_NOCHANGE)
575 			fg = nm_fg_color;
576 		if (bg == CV_NOCHANGE)
577 			bg = nm_bg_color;
578 #if MSDOS_COMPILER==WIN32C
579 		fg |= ul;
580 #endif
581 		*fg_color = fg;
582 		*bg_color = bg;
583 	}
584 }
585 #endif
586 
587 	static int
588 color_from_namechar(namechar)
589 	char namechar;
590 {
591 	switch (namechar)
592 	{
593 	case 'A': return AT_COLOR_ATTN;
594 	case 'B': return AT_COLOR_BIN;
595 	case 'C': return AT_COLOR_CTRL;
596 	case 'E': return AT_COLOR_ERROR;
597 	case 'M': return AT_COLOR_MARK;
598 	case 'N': return AT_COLOR_LINENUM;
599 	case 'P': return AT_COLOR_PROMPT;
600 	case 'R': return AT_COLOR_RSCROLL;
601 	case 'S': return AT_COLOR_SEARCH;
602 	case 'n': return AT_NORMAL;
603 	case 's': return AT_STANDOUT;
604 	case 'd': return AT_BOLD;
605 	case 'u': return AT_UNDERLINE;
606 	case 'k': return AT_BLINK;
607 	default:  return -1;
608 	}
609 }
610 
611 /*
612  * Handler for the -D option.
613  */
614 	/*ARGSUSED*/
615 	public void
616 opt_D(type, s)
617 	int type;
618 	char *s;
619 {
620 	PARG p;
621 	int attr;
622 
623 	switch (type)
624 	{
625 	case INIT:
626 	case TOGGLE:
627 #if MSDOS_COMPILER
628 		if (*s == 'a')
629 		{
630 			sgr_mode = !sgr_mode;
631 			break;
632 		}
633 #endif
634 		attr = color_from_namechar(s[0]);
635 		if (attr < 0)
636 		{
637 			p.p_char = s[0];
638 			error("Invalid color specifier '%c'", &p);
639 			return;
640 		}
641 		if (!use_color && (attr & AT_COLOR))
642 		{
643 			error("Set --use-color before changing colors", NULL_PARG);
644 			return;
645 		}
646 		s++;
647 #if MSDOS_COMPILER
648 		if (!(attr & AT_COLOR))
649 		{
650 			switch (attr)
651 			{
652 			case AT_NORMAL:
653 				colordesc(s, &nm_fg_color, &nm_bg_color);
654 				break;
655 			case AT_BOLD:
656 				colordesc(s, &bo_fg_color, &bo_bg_color);
657 				break;
658 			case AT_UNDERLINE:
659 				colordesc(s, &ul_fg_color, &ul_bg_color);
660 				break;
661 			case AT_BLINK:
662 				colordesc(s, &bl_fg_color, &bl_bg_color);
663 				break;
664 			case AT_STANDOUT:
665 				colordesc(s, &so_fg_color, &so_bg_color);
666 				break;
667 			}
668 			if (type == TOGGLE)
669 			{
670 				at_enter(AT_STANDOUT);
671 				at_exit();
672 			}
673 		} else
674 #endif
675 		if (set_color_map(attr, s) < 0)
676 		{
677 			p.p_string = s;
678 			error("Invalid color string \"%s\"", &p);
679 			return;
680 		}
681 		break;
682 #if MSDOS_COMPILER
683 	case QUERY:
684 		p.p_string = (sgr_mode) ? "on" : "off";
685 		error("SGR mode is %s", &p);
686 		break;
687 #endif
688 	}
689 }
690 
691 /*
692  * Handler for the -x option.
693  */
694 	public void
695 opt_x(type, s)
696 	int type;
697 	char *s;
698 {
699 	extern int tabstops[];
700 	extern int ntabstops;
701 	extern int tabdefault;
702 	char msg[60+(4*TABSTOP_MAX)];
703 	int i;
704 	PARG p;
705 
706 	switch (type)
707 	{
708 	case INIT:
709 	case TOGGLE:
710 		/* Start at 1 because tabstops[0] is always zero. */
711 		for (i = 1;  i < TABSTOP_MAX;  )
712 		{
713 			int n = 0;
714 			s = skipsp(s);
715 			while (*s >= '0' && *s <= '9')
716 				n = (10 * n) + (*s++ - '0');
717 			if (n > tabstops[i-1])
718 				tabstops[i++] = n;
719 			s = skipsp(s);
720 			if (*s++ != ',')
721 				break;
722 		}
723 		if (i < 2)
724 			return;
725 		ntabstops = i;
726 		tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2];
727 		break;
728 	case QUERY:
729 		strcpy(msg, "Tab stops ");
730 		if (ntabstops > 2)
731 		{
732 			for (i = 1;  i < ntabstops;  i++)
733 			{
734 				if (i > 1)
735 					strcat(msg, ",");
736 				sprintf(msg+strlen(msg), "%d", tabstops[i]);
737 			}
738 			sprintf(msg+strlen(msg), " and then ");
739 		}
740 		sprintf(msg+strlen(msg), "every %d spaces",
741 			tabdefault);
742 		p.p_string = msg;
743 		error("%s", &p);
744 		break;
745 	}
746 }
747 
748 
749 /*
750  * Handler for the -" option.
751  */
752 	public void
753 opt_quote(type, s)
754 	int type;
755 	char *s;
756 {
757 	char buf[3];
758 	PARG parg;
759 
760 	switch (type)
761 	{
762 	case INIT:
763 	case TOGGLE:
764 		if (s[0] == '\0')
765 		{
766 			openquote = closequote = '\0';
767 			break;
768 		}
769 		if (s[1] != '\0' && s[2] != '\0')
770 		{
771 			error("-\" must be followed by 1 or 2 chars", NULL_PARG);
772 			return;
773 		}
774 		openquote = s[0];
775 		if (s[1] == '\0')
776 			closequote = openquote;
777 		else
778 			closequote = s[1];
779 		break;
780 	case QUERY:
781 		buf[0] = openquote;
782 		buf[1] = closequote;
783 		buf[2] = '\0';
784 		parg.p_string = buf;
785 		error("quotes %s", &parg);
786 		break;
787 	}
788 }
789 
790 /*
791  * Handler for the --rscroll option.
792  */
793 	/*ARGSUSED*/
794 	public void
795 opt_rscroll(type, s)
796 	int type;
797 	char *s;
798 {
799 	PARG p;
800 
801 	switch (type)
802 	{
803 	case INIT:
804 	case TOGGLE: {
805 		char *fmt;
806 		int attr = AT_STANDOUT;
807 		setfmt(s, &fmt, &attr, "*s>");
808 		if (strcmp(fmt, "-") == 0)
809 		{
810 			rscroll_char = 0;
811 		} else
812 		{
813 			rscroll_char = *fmt ? *fmt : '>';
814 			rscroll_attr = attr|AT_COLOR_RSCROLL;
815 		}
816 		break; }
817 	case QUERY: {
818 		p.p_string = rscroll_char ? prchar(rscroll_char) : "-";
819 		error("rscroll char is %s", &p);
820 		break; }
821 	}
822 }
823 
824 /*
825  * "-?" means display a help message.
826  * If from the command line, exit immediately.
827  */
828 	/*ARGSUSED*/
829 	public void
830 opt_query(type, s)
831 	int type;
832 	char *s;
833 {
834 	switch (type)
835 	{
836 	case QUERY:
837 	case TOGGLE:
838 		error("Use \"h\" for help", NULL_PARG);
839 		break;
840 	case INIT:
841 		dohelp = 1;
842 	}
843 }
844 
845 /*
846  * Handler for the --mouse option.
847  */
848 	/*ARGSUSED*/
849 	public void
850 opt_mousecap(type, s)
851 	int type;
852 	char *s;
853 {
854 	switch (type)
855 	{
856 	case TOGGLE:
857 		if (mousecap == OPT_OFF)
858 			deinit_mouse();
859 		else
860 			init_mouse();
861 		break;
862 	case INIT:
863 	case QUERY:
864 		break;
865 	}
866 }
867 
868 /*
869  * Handler for the --wheel-lines option.
870  */
871 	/*ARGSUSED*/
872 	public void
873 opt_wheel_lines(type, s)
874 	int type;
875 	char *s;
876 {
877 	switch (type)
878 	{
879 	case INIT:
880 	case TOGGLE:
881 		if (wheel_lines <= 0)
882 			wheel_lines = default_wheel_lines();
883 		break;
884 	case QUERY:
885 		break;
886 	}
887 }
888 
889 /*
890  * Handler for the --line-number-width option.
891  */
892 	/*ARGSUSED*/
893 	public void
894 opt_linenum_width(type, s)
895 	int type;
896 	char *s;
897 {
898 	PARG parg;
899 
900 	switch (type)
901 	{
902 	case INIT:
903 	case TOGGLE:
904 		if (linenum_width > MAX_LINENUM_WIDTH)
905 		{
906 			parg.p_int = MAX_LINENUM_WIDTH;
907 			error("Line number width must not be larger than %d", &parg);
908 			linenum_width = MIN_LINENUM_WIDTH;
909 		}
910 		break;
911 	case QUERY:
912 		break;
913 	}
914 }
915 
916 /*
917  * Handler for the --status-column-width option.
918  */
919 	/*ARGSUSED*/
920 	public void
921 opt_status_col_width(type, s)
922 	int type;
923 	char *s;
924 {
925 	PARG parg;
926 
927 	switch (type)
928 	{
929 	case INIT:
930 	case TOGGLE:
931 		if (status_col_width > MAX_STATUSCOL_WIDTH)
932 		{
933 			parg.p_int = MAX_STATUSCOL_WIDTH;
934 			error("Status column width must not be larger than %d", &parg);
935 			status_col_width = 2;
936 		}
937 		break;
938 	case QUERY:
939 		break;
940 	}
941 }
942 
943 #if LESSTEST
944 /*
945  * Handler for the --tty option.
946  */
947 	/*ARGSUSED*/
948 	public void
949 opt_ttyin_name(type, s)
950 	int type;
951 	char *s;
952 {
953 	switch (type)
954 	{
955 	case INIT:
956 		ttyin_name = s;
957 		is_tty = 1;
958 		break;
959 	}
960 }
961 
962 /*
963  * Handler for the --rstat option.
964  */
965 	/*ARGSUSED*/
966 	public void
967 opt_rstat(type, s)
968 	int type;
969 	char *s;
970 {
971 	switch (type)
972 	{
973 	case INIT:
974 		rstat_file = open(s, O_WRONLY|O_CREAT, 0664);
975 		if (rstat_file < 0)
976 		{
977 			PARG parg;
978 			parg.p_string = s;
979 			error("Cannot create rstat file \"%s\"", &parg);
980 		}
981 		break;
982 	}
983 }
984 #endif /*LESSTEST*/
985 
986 /*
987  * Get the "screen window" size.
988  */
989 	public int
990 get_swindow(VOID_PARAM)
991 {
992 	if (swindow > 0)
993 		return (swindow);
994 	return (sc_height + swindow);
995 }
996 
997