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