xref: /netbsd-src/external/bsd/less/dist/optfunc.c (revision 838f5788460f0f133b15d706e644d692a9d4d6ec)
1*838f5788Ssimonb /*	$NetBSD: optfunc.c,v 1.4 2023/10/06 05:49:49 simonb Exp $	*/
220006a0bStron 
320006a0bStron /*
4*838f5788Ssimonb  * Copyright (C) 1984-2023  Mark Nudelman
520006a0bStron  *
620006a0bStron  * You may distribute under the terms of either the GNU General Public
720006a0bStron  * License or the Less License, as specified in the README file.
820006a0bStron  *
9ec18bca0Stron  * For more information, see the README file.
1020006a0bStron  */
1120006a0bStron 
1220006a0bStron 
1320006a0bStron /*
1420006a0bStron  * Handling functions for command line options.
1520006a0bStron  *
1620006a0bStron  * Most options are handled by the generic code in option.c.
1720006a0bStron  * But all string options, and a few non-string options, require
1820006a0bStron  * special handling specific to the particular option.
1920006a0bStron  * This special processing is done by the "handling functions" in this file.
2020006a0bStron  *
2120006a0bStron  * Each handling function is passed a "type" and, if it is a string
2220006a0bStron  * option, the string which should be "assigned" to the option.
2320006a0bStron  * The type may be one of:
2420006a0bStron  *      INIT    The option is being initialized from the command line.
2520006a0bStron  *      TOGGLE  The option is being changed from within the program.
2620006a0bStron  *      QUERY   The setting of the option is merely being queried.
2720006a0bStron  */
2820006a0bStron 
2920006a0bStron #include "less.h"
3020006a0bStron #include "option.h"
3120006a0bStron 
3220006a0bStron extern int nbufs;
3320006a0bStron extern int bufspace;
3420006a0bStron extern int pr_type;
3520006a0bStron extern int plusoption;
3620006a0bStron extern int swindow;
3720006a0bStron extern int sc_width;
3820006a0bStron extern int sc_height;
3920006a0bStron extern int secure;
4020006a0bStron extern int dohelp;
41*838f5788Ssimonb extern int is_tty;
4220006a0bStron extern char openquote;
4320006a0bStron extern char closequote;
4420006a0bStron extern char *prproto[];
4520006a0bStron extern char *eqproto;
4620006a0bStron extern char *hproto;
4720006a0bStron extern char *wproto;
48*838f5788Ssimonb extern char *every_first_cmd;
4920006a0bStron extern IFILE curr_ifile;
5020006a0bStron extern char version[];
5120006a0bStron extern int jump_sline;
52*838f5788Ssimonb extern long jump_sline_fraction;
5320006a0bStron extern int shift_count;
54*838f5788Ssimonb extern long shift_count_fraction;
55*838f5788Ssimonb extern char rscroll_char;
56*838f5788Ssimonb extern int rscroll_attr;
57*838f5788Ssimonb extern int mousecap;
58*838f5788Ssimonb extern int wheel_lines;
5920006a0bStron extern int less_is_more;
60*838f5788Ssimonb extern int linenum_width;
61*838f5788Ssimonb extern int status_col_width;
62*838f5788Ssimonb extern int use_color;
63*838f5788Ssimonb extern int want_filesize;
64*838f5788Ssimonb extern int header_lines;
65*838f5788Ssimonb extern int header_cols;
66*838f5788Ssimonb extern int def_search_type;
67*838f5788Ssimonb extern int chopline;
68*838f5788Ssimonb extern int tabstops[];
69*838f5788Ssimonb extern int ntabstops;
70*838f5788Ssimonb extern int tabdefault;
71*838f5788Ssimonb extern char intr_char;
7220006a0bStron #if LOGFILE
7320006a0bStron extern char *namelogfile;
7420006a0bStron extern int force_logfile;
7520006a0bStron extern int logfile;
7620006a0bStron #endif
7720006a0bStron #if TAGS
7820006a0bStron public char *tagoption = NULL;
7920006a0bStron extern char *tags;
80*838f5788Ssimonb extern char ztags[];
8120006a0bStron #endif
82*838f5788Ssimonb #if LESSTEST
83*838f5788Ssimonb extern char *ttyin_name;
84*838f5788Ssimonb #endif /*LESSTEST*/
8520006a0bStron #if MSDOS_COMPILER
8620006a0bStron extern int nm_fg_color, nm_bg_color;
8720006a0bStron extern int bo_fg_color, bo_bg_color;
8820006a0bStron extern int ul_fg_color, ul_bg_color;
8920006a0bStron extern int so_fg_color, so_bg_color;
9020006a0bStron extern int bl_fg_color, bl_bg_color;
91*838f5788Ssimonb extern int sgr_mode;
92*838f5788Ssimonb #if MSDOS_COMPILER==WIN32C
93*838f5788Ssimonb #ifndef COMMON_LVB_UNDERSCORE
94*838f5788Ssimonb #define COMMON_LVB_UNDERSCORE 0x8000
95*838f5788Ssimonb #endif
96*838f5788Ssimonb #endif
9720006a0bStron #endif
9820006a0bStron 
9920006a0bStron 
10020006a0bStron #if LOGFILE
10120006a0bStron /*
10220006a0bStron  * Handler for -o option.
10320006a0bStron  */
opt_o(int type,char * s)104*838f5788Ssimonb public void opt_o(int type, char *s)
10520006a0bStron {
10620006a0bStron 	PARG parg;
107*838f5788Ssimonb 	char *filename;
10820006a0bStron 
10920006a0bStron 	if (secure)
11020006a0bStron 	{
11120006a0bStron 		error("log file support is not available", NULL_PARG);
11220006a0bStron 		return;
11320006a0bStron 	}
11420006a0bStron 	switch (type)
11520006a0bStron 	{
11620006a0bStron 	case INIT:
117*838f5788Ssimonb 		namelogfile = save(s);
11820006a0bStron 		break;
11920006a0bStron 	case TOGGLE:
12020006a0bStron 		if (ch_getflags() & CH_CANSEEK)
12120006a0bStron 		{
12220006a0bStron 			error("Input is not a pipe", NULL_PARG);
12320006a0bStron 			return;
12420006a0bStron 		}
12520006a0bStron 		if (logfile >= 0)
12620006a0bStron 		{
12720006a0bStron 			error("Log file is already in use", NULL_PARG);
12820006a0bStron 			return;
12920006a0bStron 		}
13020006a0bStron 		s = skipsp(s);
131*838f5788Ssimonb 		if (namelogfile != NULL)
132*838f5788Ssimonb 			free(namelogfile);
133*838f5788Ssimonb 		filename = lglob(s);
134*838f5788Ssimonb 		namelogfile = shell_unquote(filename);
135*838f5788Ssimonb 		free(filename);
13620006a0bStron 		use_logfile(namelogfile);
13720006a0bStron 		sync_logfile();
13820006a0bStron 		break;
13920006a0bStron 	case QUERY:
14020006a0bStron 		if (logfile < 0)
14120006a0bStron 			error("No log file", NULL_PARG);
14220006a0bStron 		else
14320006a0bStron 		{
14420006a0bStron 			parg.p_string = namelogfile;
14520006a0bStron 			error("Log file \"%s\"", &parg);
14620006a0bStron 		}
14720006a0bStron 		break;
14820006a0bStron 	}
14920006a0bStron }
15020006a0bStron 
15120006a0bStron /*
15220006a0bStron  * Handler for -O option.
15320006a0bStron  */
opt__O(int type,char * s)154*838f5788Ssimonb public void opt__O(int type, char *s)
15520006a0bStron {
15620006a0bStron 	force_logfile = TRUE;
15720006a0bStron 	opt_o(type, s);
15820006a0bStron }
15920006a0bStron #endif
16020006a0bStron 
16120006a0bStron /*
16220006a0bStron  * Handlers for -j option.
16320006a0bStron  */
opt_j(int type,char * s)164*838f5788Ssimonb public void opt_j(int type, char *s)
16520006a0bStron {
16620006a0bStron 	PARG parg;
16720006a0bStron 	int len;
16820006a0bStron 	int err;
16920006a0bStron 
17020006a0bStron 	switch (type)
17120006a0bStron 	{
17220006a0bStron 	case INIT:
17320006a0bStron 	case TOGGLE:
17420006a0bStron 		if (*s == '.')
17520006a0bStron 		{
17620006a0bStron 			s++;
17720006a0bStron 			jump_sline_fraction = getfraction(&s, "j", &err);
17820006a0bStron 			if (err)
17920006a0bStron 				error("Invalid line fraction", NULL_PARG);
18020006a0bStron 			else
18120006a0bStron 				calc_jump_sline();
18220006a0bStron 		} else
18320006a0bStron 		{
18420006a0bStron 			int sline = getnum(&s, "j", &err);
18520006a0bStron 			if (err)
18620006a0bStron 				error("Invalid line number", NULL_PARG);
18720006a0bStron 			else
18820006a0bStron 			{
18920006a0bStron 				jump_sline = sline;
19020006a0bStron 				jump_sline_fraction = -1;
19120006a0bStron 			}
19220006a0bStron 		}
19320006a0bStron 		break;
19420006a0bStron 	case QUERY:
19520006a0bStron 		if (jump_sline_fraction < 0)
19620006a0bStron 		{
19720006a0bStron 			parg.p_int =  jump_sline;
19820006a0bStron 			error("Position target at screen line %d", &parg);
19920006a0bStron 		} else
20020006a0bStron 		{
201*838f5788Ssimonb 			char buf[INT_STRLEN_BOUND(long)+2];
202*838f5788Ssimonb 			SNPRINTF1(buf, sizeof(buf), ".%06ld", jump_sline_fraction);
203*838f5788Ssimonb 			len = (int) strlen(buf);
20420006a0bStron 			while (len > 2 && buf[len-1] == '0')
20520006a0bStron 				len--;
20620006a0bStron 			buf[len] = '\0';
20720006a0bStron 			parg.p_string = buf;
20820006a0bStron 			error("Position target at screen position %s", &parg);
20920006a0bStron 		}
21020006a0bStron 		break;
21120006a0bStron 	}
21220006a0bStron }
21320006a0bStron 
calc_jump_sline(void)214*838f5788Ssimonb public void calc_jump_sline(void)
21520006a0bStron {
21620006a0bStron 	if (jump_sline_fraction < 0)
21720006a0bStron 		return;
218*838f5788Ssimonb 	jump_sline = (int) muldiv(sc_height, jump_sline_fraction, NUM_FRAC_DENOM);
21920006a0bStron }
22020006a0bStron 
22120006a0bStron /*
22220006a0bStron  * Handlers for -# option.
22320006a0bStron  */
opt_shift(int type,char * s)224*838f5788Ssimonb public void opt_shift(int type, char *s)
22520006a0bStron {
22620006a0bStron 	PARG parg;
22720006a0bStron 	int len;
22820006a0bStron 	int err;
22920006a0bStron 
23020006a0bStron 	switch (type)
23120006a0bStron 	{
23220006a0bStron 	case INIT:
23320006a0bStron 	case TOGGLE:
23420006a0bStron 		if (*s == '.')
23520006a0bStron 		{
23620006a0bStron 			s++;
23720006a0bStron 			shift_count_fraction = getfraction(&s, "#", &err);
23820006a0bStron 			if (err)
23920006a0bStron 				error("Invalid column fraction", NULL_PARG);
24020006a0bStron 			else
24120006a0bStron 				calc_shift_count();
24220006a0bStron 		} else
24320006a0bStron 		{
24420006a0bStron 			int hs = getnum(&s, "#", &err);
24520006a0bStron 			if (err)
24620006a0bStron 				error("Invalid column number", NULL_PARG);
24720006a0bStron 			else
24820006a0bStron 			{
24920006a0bStron 				shift_count = hs;
25020006a0bStron 				shift_count_fraction = -1;
25120006a0bStron 			}
25220006a0bStron 		}
25320006a0bStron 		break;
25420006a0bStron 	case QUERY:
25520006a0bStron 		if (shift_count_fraction < 0)
25620006a0bStron 		{
25720006a0bStron 			parg.p_int = shift_count;
25820006a0bStron 			error("Horizontal shift %d columns", &parg);
25920006a0bStron 		} else
26020006a0bStron 		{
261*838f5788Ssimonb 			char buf[INT_STRLEN_BOUND(long)+2];
262*838f5788Ssimonb 			SNPRINTF1(buf, sizeof(buf), ".%06ld", shift_count_fraction);
263*838f5788Ssimonb 			len = (int) strlen(buf);
26420006a0bStron 			while (len > 2 && buf[len-1] == '0')
26520006a0bStron 				len--;
26620006a0bStron 			buf[len] = '\0';
26720006a0bStron 			parg.p_string = buf;
26820006a0bStron 			error("Horizontal shift %s of screen width", &parg);
26920006a0bStron 		}
27020006a0bStron 		break;
27120006a0bStron 	}
27220006a0bStron }
273*838f5788Ssimonb 
calc_shift_count(void)274*838f5788Ssimonb public void calc_shift_count(void)
27520006a0bStron {
27620006a0bStron 	if (shift_count_fraction < 0)
27720006a0bStron 		return;
278*838f5788Ssimonb 	shift_count = (int) muldiv(sc_width, shift_count_fraction, NUM_FRAC_DENOM);
27920006a0bStron }
28020006a0bStron 
28120006a0bStron #if USERFILE
opt_k(int type,char * s)282*838f5788Ssimonb public void opt_k(int type, char *s)
28320006a0bStron {
28420006a0bStron 	PARG parg;
28520006a0bStron 
28620006a0bStron 	switch (type)
28720006a0bStron 	{
28820006a0bStron 	case INIT:
28920006a0bStron 		if (lesskey(s, 0))
29020006a0bStron 		{
29120006a0bStron 			parg.p_string = s;
29220006a0bStron 			error("Cannot use lesskey file \"%s\"", &parg);
29320006a0bStron 		}
29420006a0bStron 		break;
29520006a0bStron 	}
29620006a0bStron }
297*838f5788Ssimonb 
298*838f5788Ssimonb #if HAVE_LESSKEYSRC
opt_ks(int type,char * s)299*838f5788Ssimonb public void opt_ks(int type, char *s)
300*838f5788Ssimonb {
301*838f5788Ssimonb 	PARG parg;
302*838f5788Ssimonb 
303*838f5788Ssimonb 	switch (type)
304*838f5788Ssimonb 	{
305*838f5788Ssimonb 	case INIT:
306*838f5788Ssimonb 		if (lesskey_src(s, 0))
307*838f5788Ssimonb 		{
308*838f5788Ssimonb 			parg.p_string = s;
309*838f5788Ssimonb 			error("Cannot use lesskey source file \"%s\"", &parg);
310*838f5788Ssimonb 		}
311*838f5788Ssimonb 		break;
312*838f5788Ssimonb 	}
313*838f5788Ssimonb }
314*838f5788Ssimonb #endif /* HAVE_LESSKEYSRC */
315*838f5788Ssimonb #endif /* USERFILE */
31620006a0bStron 
31720006a0bStron #if TAGS
31820006a0bStron /*
31920006a0bStron  * Handler for -t option.
32020006a0bStron  */
opt_t(int type,char * s)321*838f5788Ssimonb public void opt_t(int type, char *s)
32220006a0bStron {
32320006a0bStron 	IFILE save_ifile;
32420006a0bStron 	POSITION pos;
32520006a0bStron 
32620006a0bStron 	switch (type)
32720006a0bStron 	{
32820006a0bStron 	case INIT:
329*838f5788Ssimonb 		tagoption = save(s);
33020006a0bStron 		/* Do the rest in main() */
33120006a0bStron 		break;
33220006a0bStron 	case TOGGLE:
33320006a0bStron 		if (secure)
33420006a0bStron 		{
33520006a0bStron 			error("tags support is not available", NULL_PARG);
33620006a0bStron 			break;
33720006a0bStron 		}
33820006a0bStron 		findtag(skipsp(s));
33920006a0bStron 		save_ifile = save_curr_ifile();
34020006a0bStron 		/*
34120006a0bStron 		 * Try to open the file containing the tag
34220006a0bStron 		 * and search for the tag in that file.
34320006a0bStron 		 */
34420006a0bStron 		if (edit_tagfile() || (pos = tagsearch()) == NULL_POSITION)
34520006a0bStron 		{
34620006a0bStron 			/* Failed: reopen the old file. */
34720006a0bStron 			reedit_ifile(save_ifile);
34820006a0bStron 			break;
34920006a0bStron 		}
35020006a0bStron 		unsave_ifile(save_ifile);
35120006a0bStron 		jump_loc(pos, jump_sline);
35220006a0bStron 		break;
35320006a0bStron 	}
35420006a0bStron }
35520006a0bStron 
35620006a0bStron /*
35720006a0bStron  * Handler for -T option.
35820006a0bStron  */
opt__T(int type,char * s)359*838f5788Ssimonb public void opt__T(int type, char *s)
36020006a0bStron {
36120006a0bStron 	PARG parg;
362*838f5788Ssimonb 	char *filename;
36320006a0bStron 
36420006a0bStron 	switch (type)
36520006a0bStron 	{
36620006a0bStron 	case INIT:
367*838f5788Ssimonb 		tags = save(s);
36820006a0bStron 		break;
36920006a0bStron 	case TOGGLE:
37020006a0bStron 		s = skipsp(s);
371*838f5788Ssimonb 		if (tags != NULL && tags != ztags)
372*838f5788Ssimonb 			free(tags);
373*838f5788Ssimonb 		filename = lglob(s);
374*838f5788Ssimonb 		tags = shell_unquote(filename);
375*838f5788Ssimonb 		free(filename);
37620006a0bStron 		break;
37720006a0bStron 	case QUERY:
37820006a0bStron 		parg.p_string = tags;
37920006a0bStron 		error("Tags file \"%s\"", &parg);
38020006a0bStron 		break;
38120006a0bStron 	}
38220006a0bStron }
38320006a0bStron #endif
38420006a0bStron 
38520006a0bStron /*
38620006a0bStron  * Handler for -p option.
38720006a0bStron  */
opt_p(int type,char * s)388*838f5788Ssimonb public void opt_p(int type, char *s)
38920006a0bStron {
39020006a0bStron 	switch (type)
39120006a0bStron 	{
39220006a0bStron 	case INIT:
39320006a0bStron 		/*
394*838f5788Ssimonb 		 * Unget a command for the specified string.
39520006a0bStron 		 */
396*838f5788Ssimonb 		if (less_is_more)
397*838f5788Ssimonb 		{
39820006a0bStron 			/*
39920006a0bStron 			 * In "more" mode, the -p argument is a command,
40020006a0bStron 			 * not a search string, so we don't need a slash.
40120006a0bStron 			 */
402*838f5788Ssimonb 			every_first_cmd = save(s);
403*838f5788Ssimonb 		} else
404*838f5788Ssimonb 		{
405*838f5788Ssimonb 			plusoption = TRUE;
406*838f5788Ssimonb 			 /*
407*838f5788Ssimonb 			  * {{ This won't work if the "/" command is
408*838f5788Ssimonb 			  *    changed or invalidated by a .lesskey file. }}
409*838f5788Ssimonb 			  */
41020006a0bStron 			ungetsc("/");
411*838f5788Ssimonb 			ungetsc(s);
412*838f5788Ssimonb 			ungetcc_back(CHAR_END_COMMAND);
413*838f5788Ssimonb 		}
41420006a0bStron 		break;
41520006a0bStron 	}
41620006a0bStron }
41720006a0bStron 
41820006a0bStron /*
41920006a0bStron  * Handler for -P option.
42020006a0bStron  */
opt__P(int type,char * s)421*838f5788Ssimonb public void opt__P(int type, char *s)
42220006a0bStron {
423*838f5788Ssimonb 	char **proto;
42420006a0bStron 	PARG parg;
42520006a0bStron 
42620006a0bStron 	switch (type)
42720006a0bStron 	{
42820006a0bStron 	case INIT:
42920006a0bStron 	case TOGGLE:
43020006a0bStron 		/*
43120006a0bStron 		 * Figure out which prototype string should be changed.
43220006a0bStron 		 */
43320006a0bStron 		switch (*s)
43420006a0bStron 		{
43520006a0bStron 		case 's':  proto = &prproto[PR_SHORT];  s++;    break;
43620006a0bStron 		case 'm':  proto = &prproto[PR_MEDIUM]; s++;    break;
43720006a0bStron 		case 'M':  proto = &prproto[PR_LONG];   s++;    break;
43820006a0bStron 		case '=':  proto = &eqproto;            s++;    break;
43920006a0bStron 		case 'h':  proto = &hproto;             s++;    break;
44020006a0bStron 		case 'w':  proto = &wproto;             s++;    break;
44120006a0bStron 		default:   proto = &prproto[PR_SHORT];          break;
44220006a0bStron 		}
44320006a0bStron 		free(*proto);
44420006a0bStron 		*proto = save(s);
44520006a0bStron 		break;
44620006a0bStron 	case QUERY:
44720006a0bStron 		parg.p_string = prproto[pr_type];
44820006a0bStron 		error("%s", &parg);
44920006a0bStron 		break;
45020006a0bStron 	}
45120006a0bStron }
45220006a0bStron 
45320006a0bStron /*
45420006a0bStron  * Handler for the -b option.
45520006a0bStron  */
45620006a0bStron 	/*ARGSUSED*/
opt_b(int type,char * s)457*838f5788Ssimonb public void opt_b(int type, char *s)
45820006a0bStron {
45920006a0bStron 	switch (type)
46020006a0bStron 	{
46120006a0bStron 	case INIT:
46220006a0bStron 	case TOGGLE:
46320006a0bStron 		/*
46420006a0bStron 		 * Set the new number of buffers.
46520006a0bStron 		 */
46620006a0bStron 		ch_setbufspace(bufspace);
46720006a0bStron 		break;
46820006a0bStron 	case QUERY:
46920006a0bStron 		break;
47020006a0bStron 	}
47120006a0bStron }
47220006a0bStron 
47320006a0bStron /*
47420006a0bStron  * Handler for the -i option.
47520006a0bStron  */
47620006a0bStron 	/*ARGSUSED*/
opt_i(int type,char * s)477*838f5788Ssimonb public void opt_i(int type, char *s)
47820006a0bStron {
47920006a0bStron 	switch (type)
48020006a0bStron 	{
48120006a0bStron 	case TOGGLE:
48220006a0bStron 		chg_caseless();
48320006a0bStron 		break;
48420006a0bStron 	case QUERY:
48520006a0bStron 	case INIT:
48620006a0bStron 		break;
48720006a0bStron 	}
48820006a0bStron }
48920006a0bStron 
49020006a0bStron /*
49120006a0bStron  * Handler for the -V option.
49220006a0bStron  */
49320006a0bStron 	/*ARGSUSED*/
opt__V(int type,char * s)494*838f5788Ssimonb public void opt__V(int type, char *s)
49520006a0bStron {
49620006a0bStron 	switch (type)
49720006a0bStron 	{
49820006a0bStron 	case TOGGLE:
49920006a0bStron 	case QUERY:
50020006a0bStron 		dispversion();
50120006a0bStron 		break;
50220006a0bStron 	case INIT:
503*838f5788Ssimonb 		set_output(1); /* Force output to stdout per GNU standard for --version output. */
50420006a0bStron 		putstr("less ");
50520006a0bStron 		putstr(version);
506ec18bca0Stron 		putstr(" (");
507*838f5788Ssimonb 		putstr(pattern_lib_name());
508ec18bca0Stron 		putstr(" regular expressions)\n");
509*838f5788Ssimonb 		{
510*838f5788Ssimonb 			char constant *copyright =
511*838f5788Ssimonb 				"Copyright (C) 1984-2023  Mark Nudelman\n\n";
512*838f5788Ssimonb 			putstr(copyright);
513*838f5788Ssimonb 		}
514*838f5788Ssimonb 		if (version[strlen(version)-1] == 'x')
515*838f5788Ssimonb 		{
516*838f5788Ssimonb 			putstr("** This is an EXPERIMENTAL build of the 'less' software,\n");
517*838f5788Ssimonb 			putstr("** and may not function correctly.\n");
518*838f5788Ssimonb 			putstr("** Obtain release builds from the web page below.\n\n");
519*838f5788Ssimonb 		}
520*838f5788Ssimonb #if LESSTEST
521*838f5788Ssimonb 		putstr("This build supports LESSTEST.\n");
522*838f5788Ssimonb #endif /*LESSTEST*/
52320006a0bStron 		putstr("less comes with NO WARRANTY, to the extent permitted by law.\n");
52420006a0bStron 		putstr("For information about the terms of redistribution,\n");
52520006a0bStron 		putstr("see the file named README in the less distribution.\n");
526*838f5788Ssimonb 		putstr("Home page: https://greenwoodsoftware.com/less\n");
52720006a0bStron 		quit(QUIT_OK);
52820006a0bStron 		break;
52920006a0bStron 	}
53020006a0bStron }
53120006a0bStron 
53220006a0bStron #if MSDOS_COMPILER
53320006a0bStron /*
53420006a0bStron  * Parse an MSDOS color descriptor.
53520006a0bStron  */
colordesc(char * s,int * fg_color,int * bg_color)536*838f5788Ssimonb static void colordesc(char *s, int *fg_color, int *bg_color)
53720006a0bStron {
53820006a0bStron 	int fg, bg;
539*838f5788Ssimonb #if MSDOS_COMPILER==WIN32C
540*838f5788Ssimonb 	int ul = 0;
54120006a0bStron 
542*838f5788Ssimonb 	if (*s == 'u')
54320006a0bStron 	{
544*838f5788Ssimonb 		ul = COMMON_LVB_UNDERSCORE;
54520006a0bStron 		s++;
546*838f5788Ssimonb 		if (*s == '\0')
54720006a0bStron 		{
548*838f5788Ssimonb 			*fg_color = nm_fg_color | ul;
549*838f5788Ssimonb 			*bg_color = nm_bg_color;
55020006a0bStron 			return;
55120006a0bStron 		}
55220006a0bStron 	}
553*838f5788Ssimonb #endif
554*838f5788Ssimonb 	if (parse_color(s, &fg, &bg) == CT_NULL)
555*838f5788Ssimonb 	{
556*838f5788Ssimonb 		PARG p;
557*838f5788Ssimonb 		p.p_string = s;
558*838f5788Ssimonb 		error("Invalid color string \"%s\"", &p);
559*838f5788Ssimonb 	} else
560*838f5788Ssimonb 	{
561*838f5788Ssimonb 		if (fg == CV_NOCHANGE)
562*838f5788Ssimonb 			fg = nm_fg_color;
563*838f5788Ssimonb 		if (bg == CV_NOCHANGE)
564*838f5788Ssimonb 			bg = nm_bg_color;
565*838f5788Ssimonb #if MSDOS_COMPILER==WIN32C
566*838f5788Ssimonb 		fg |= ul;
567*838f5788Ssimonb #endif
56820006a0bStron 		*fg_color = fg;
56920006a0bStron 		*bg_color = bg;
57020006a0bStron 	}
571*838f5788Ssimonb }
572*838f5788Ssimonb #endif
573*838f5788Ssimonb 
color_from_namechar(char namechar)574*838f5788Ssimonb static int color_from_namechar(char namechar)
575*838f5788Ssimonb {
576*838f5788Ssimonb 	switch (namechar)
577*838f5788Ssimonb 	{
578*838f5788Ssimonb 	case 'B': return AT_COLOR_BIN;
579*838f5788Ssimonb 	case 'C': return AT_COLOR_CTRL;
580*838f5788Ssimonb 	case 'E': return AT_COLOR_ERROR;
581*838f5788Ssimonb 	case 'H': return AT_COLOR_HEADER;
582*838f5788Ssimonb 	case 'M': return AT_COLOR_MARK;
583*838f5788Ssimonb 	case 'N': return AT_COLOR_LINENUM;
584*838f5788Ssimonb 	case 'P': return AT_COLOR_PROMPT;
585*838f5788Ssimonb 	case 'R': return AT_COLOR_RSCROLL;
586*838f5788Ssimonb 	case 'S': return AT_COLOR_SEARCH;
587*838f5788Ssimonb 	case 'W': case 'A': return AT_COLOR_ATTN;
588*838f5788Ssimonb 	case 'n': return AT_NORMAL;
589*838f5788Ssimonb 	case 's': return AT_STANDOUT;
590*838f5788Ssimonb 	case 'd': return AT_BOLD;
591*838f5788Ssimonb 	case 'u': return AT_UNDERLINE;
592*838f5788Ssimonb 	case 'k': return AT_BLINK;
593*838f5788Ssimonb 	default:
594*838f5788Ssimonb 		if (namechar >= '1' && namechar <= '0'+NUM_SEARCH_COLORS)
595*838f5788Ssimonb 			return AT_COLOR_SUBSEARCH(namechar-'0');
596*838f5788Ssimonb 		return -1;
597*838f5788Ssimonb 	}
598*838f5788Ssimonb }
59920006a0bStron 
60020006a0bStron /*
60120006a0bStron  * Handler for the -D option.
60220006a0bStron  */
60320006a0bStron 	/*ARGSUSED*/
opt_D(int type,char * s)604*838f5788Ssimonb public void opt_D(int type, char *s)
60520006a0bStron {
606*838f5788Ssimonb 	PARG p;
607*838f5788Ssimonb 	int attr;
608*838f5788Ssimonb 
60920006a0bStron 	switch (type)
61020006a0bStron 	{
61120006a0bStron 	case INIT:
61220006a0bStron 	case TOGGLE:
613*838f5788Ssimonb #if MSDOS_COMPILER
614*838f5788Ssimonb 		if (*s == 'a')
61520006a0bStron 		{
616*838f5788Ssimonb 			sgr_mode = !sgr_mode;
617*838f5788Ssimonb 			break;
618*838f5788Ssimonb 		}
619*838f5788Ssimonb #endif
620*838f5788Ssimonb 		attr = color_from_namechar(s[0]);
621*838f5788Ssimonb 		if (attr < 0)
622*838f5788Ssimonb 		{
623*838f5788Ssimonb 			p.p_char = s[0];
624*838f5788Ssimonb 			error("Invalid color specifier '%c'", &p);
625*838f5788Ssimonb 			return;
626*838f5788Ssimonb 		}
627*838f5788Ssimonb 		if (!use_color && (attr & AT_COLOR))
628*838f5788Ssimonb 		{
629*838f5788Ssimonb 			error("Set --use-color before changing colors", NULL_PARG);
630*838f5788Ssimonb 			return;
631*838f5788Ssimonb 		}
632*838f5788Ssimonb 		s++;
633*838f5788Ssimonb #if MSDOS_COMPILER
634*838f5788Ssimonb 		if (!(attr & AT_COLOR))
635*838f5788Ssimonb 		{
636*838f5788Ssimonb 			switch (attr)
637*838f5788Ssimonb 			{
638*838f5788Ssimonb 			case AT_NORMAL:
63920006a0bStron 				colordesc(s, &nm_fg_color, &nm_bg_color);
64020006a0bStron 				break;
641*838f5788Ssimonb 			case AT_BOLD:
64220006a0bStron 				colordesc(s, &bo_fg_color, &bo_bg_color);
64320006a0bStron 				break;
644*838f5788Ssimonb 			case AT_UNDERLINE:
64520006a0bStron 				colordesc(s, &ul_fg_color, &ul_bg_color);
64620006a0bStron 				break;
647*838f5788Ssimonb 			case AT_BLINK:
64820006a0bStron 				colordesc(s, &bl_fg_color, &bl_bg_color);
64920006a0bStron 				break;
650*838f5788Ssimonb 			case AT_STANDOUT:
65120006a0bStron 				colordesc(s, &so_fg_color, &so_bg_color);
65220006a0bStron 				break;
65320006a0bStron 			}
65420006a0bStron 			if (type == TOGGLE)
65520006a0bStron 			{
65620006a0bStron 				at_enter(AT_STANDOUT);
65720006a0bStron 				at_exit();
65820006a0bStron 			}
659*838f5788Ssimonb 		} else
66020006a0bStron #endif
661*838f5788Ssimonb 		if (set_color_map(attr, s) < 0)
662*838f5788Ssimonb 		{
663*838f5788Ssimonb 			p.p_string = s;
664*838f5788Ssimonb 			error("Invalid color string \"%s\"", &p);
665*838f5788Ssimonb 			return;
666*838f5788Ssimonb 		}
667*838f5788Ssimonb 		break;
668*838f5788Ssimonb #if MSDOS_COMPILER
669*838f5788Ssimonb 	case QUERY:
670*838f5788Ssimonb 		p.p_string = (sgr_mode) ? "on" : "off";
671*838f5788Ssimonb 		error("SGR mode is %s", &p);
672*838f5788Ssimonb 		break;
673*838f5788Ssimonb #endif
674*838f5788Ssimonb 	}
675*838f5788Ssimonb }
676*838f5788Ssimonb 
677*838f5788Ssimonb /*
678*838f5788Ssimonb  */
set_tabs(char * s,int len)679*838f5788Ssimonb public void set_tabs(char *s, int len)
680*838f5788Ssimonb {
681*838f5788Ssimonb 	int i;
682*838f5788Ssimonb 	char *es = s + len;
683*838f5788Ssimonb 	/* Start at 1 because tabstops[0] is always zero. */
684*838f5788Ssimonb 	for (i = 1;  i < TABSTOP_MAX;  )
685*838f5788Ssimonb 	{
686*838f5788Ssimonb 		int n = 0;
687*838f5788Ssimonb 		int v = FALSE;
688*838f5788Ssimonb 		while (s < es && *s == ' ')
689*838f5788Ssimonb 			s++;
690*838f5788Ssimonb 		for (; s < es && *s >= '0' && *s <= '9'; s++)
691*838f5788Ssimonb 		{
692*838f5788Ssimonb 			v |= ckd_mul(&n, n, 10);
693*838f5788Ssimonb 			v |= ckd_add(&n, n, *s - '0');
694*838f5788Ssimonb 		}
695*838f5788Ssimonb 		if (!v && n > tabstops[i-1])
696*838f5788Ssimonb 			tabstops[i++] = n;
697*838f5788Ssimonb 		while (s < es && *s == ' ')
698*838f5788Ssimonb 			s++;
699*838f5788Ssimonb 		if (s == es || *s++ != ',')
700*838f5788Ssimonb 			break;
701*838f5788Ssimonb 	}
702*838f5788Ssimonb 	if (i < 2)
703*838f5788Ssimonb 		return;
704*838f5788Ssimonb 	ntabstops = i;
705*838f5788Ssimonb 	tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2];
706*838f5788Ssimonb }
70720006a0bStron 
70820006a0bStron /*
70920006a0bStron  * Handler for the -x option.
71020006a0bStron  */
opt_x(int type,char * s)711*838f5788Ssimonb public void opt_x(int type, char *s)
71220006a0bStron {
713*838f5788Ssimonb 	char msg[60+((INT_STRLEN_BOUND(int)+1)*TABSTOP_MAX)];
71420006a0bStron 	int i;
71520006a0bStron 	PARG p;
71620006a0bStron 
71720006a0bStron 	switch (type)
71820006a0bStron 	{
71920006a0bStron 	case INIT:
72020006a0bStron 	case TOGGLE:
721*838f5788Ssimonb 		set_tabs(s, strlen(s));
72220006a0bStron 		break;
72320006a0bStron 	case QUERY:
72420006a0bStron 		strcpy(msg, "Tab stops ");
72520006a0bStron 		if (ntabstops > 2)
72620006a0bStron 		{
72720006a0bStron 			for (i = 1;  i < ntabstops;  i++)
72820006a0bStron 			{
72920006a0bStron 				if (i > 1)
73020006a0bStron 					strcat(msg, ",");
73120006a0bStron 				sprintf(msg+strlen(msg), "%d", tabstops[i]);
73220006a0bStron 			}
73320006a0bStron 			sprintf(msg+strlen(msg), " and then ");
73420006a0bStron 		}
73520006a0bStron 		sprintf(msg+strlen(msg), "every %d spaces",
73620006a0bStron 			tabdefault);
73720006a0bStron 		p.p_string = msg;
73820006a0bStron 		error("%s", &p);
73920006a0bStron 		break;
74020006a0bStron 	}
74120006a0bStron }
74220006a0bStron 
74320006a0bStron 
74420006a0bStron /*
74520006a0bStron  * Handler for the -" option.
74620006a0bStron  */
opt_quote(int type,char * s)747*838f5788Ssimonb public void opt_quote(int type, char *s)
74820006a0bStron {
74920006a0bStron 	char buf[3];
75020006a0bStron 	PARG parg;
75120006a0bStron 
75220006a0bStron 	switch (type)
75320006a0bStron 	{
75420006a0bStron 	case INIT:
75520006a0bStron 	case TOGGLE:
75620006a0bStron 		if (s[0] == '\0')
75720006a0bStron 		{
75820006a0bStron 			openquote = closequote = '\0';
75920006a0bStron 			break;
76020006a0bStron 		}
76120006a0bStron 		if (s[1] != '\0' && s[2] != '\0')
76220006a0bStron 		{
76320006a0bStron 			error("-\" must be followed by 1 or 2 chars", NULL_PARG);
76420006a0bStron 			return;
76520006a0bStron 		}
76620006a0bStron 		openquote = s[0];
76720006a0bStron 		if (s[1] == '\0')
76820006a0bStron 			closequote = openquote;
76920006a0bStron 		else
77020006a0bStron 			closequote = s[1];
77120006a0bStron 		break;
77220006a0bStron 	case QUERY:
77320006a0bStron 		buf[0] = openquote;
77420006a0bStron 		buf[1] = closequote;
77520006a0bStron 		buf[2] = '\0';
77620006a0bStron 		parg.p_string = buf;
77720006a0bStron 		error("quotes %s", &parg);
77820006a0bStron 		break;
77920006a0bStron 	}
78020006a0bStron }
78120006a0bStron 
78220006a0bStron /*
783*838f5788Ssimonb  * Handler for the --rscroll option.
784*838f5788Ssimonb  */
785*838f5788Ssimonb 	/*ARGSUSED*/
opt_rscroll(int type,char * s)786*838f5788Ssimonb public void opt_rscroll(int type, char *s)
787*838f5788Ssimonb {
788*838f5788Ssimonb 	PARG p;
789*838f5788Ssimonb 
790*838f5788Ssimonb 	switch (type)
791*838f5788Ssimonb 	{
792*838f5788Ssimonb 	case INIT:
793*838f5788Ssimonb 	case TOGGLE: {
794*838f5788Ssimonb 		char *fmt;
795*838f5788Ssimonb 		int attr = AT_STANDOUT;
796*838f5788Ssimonb 		setfmt(s, &fmt, &attr, "*s>", FALSE);
797*838f5788Ssimonb 		if (strcmp(fmt, "-") == 0)
798*838f5788Ssimonb 		{
799*838f5788Ssimonb 			rscroll_char = 0;
800*838f5788Ssimonb 		} else
801*838f5788Ssimonb 		{
802*838f5788Ssimonb 			rscroll_char = *fmt ? *fmt : '>';
803*838f5788Ssimonb 			rscroll_attr = attr|AT_COLOR_RSCROLL;
804*838f5788Ssimonb 		}
805*838f5788Ssimonb 		break; }
806*838f5788Ssimonb 	case QUERY: {
807*838f5788Ssimonb 		p.p_string = rscroll_char ? prchar(rscroll_char) : "-";
808*838f5788Ssimonb 		error("rscroll character is %s", &p);
809*838f5788Ssimonb 		break; }
810*838f5788Ssimonb 	}
811*838f5788Ssimonb }
812*838f5788Ssimonb 
813*838f5788Ssimonb /*
81420006a0bStron  * "-?" means display a help message.
81520006a0bStron  * If from the command line, exit immediately.
81620006a0bStron  */
81720006a0bStron 	/*ARGSUSED*/
opt_query(int type,char * s)818*838f5788Ssimonb public void opt_query(int type, char *s)
81920006a0bStron {
82020006a0bStron 	switch (type)
82120006a0bStron 	{
82220006a0bStron 	case QUERY:
82320006a0bStron 	case TOGGLE:
82420006a0bStron 		error("Use \"h\" for help", NULL_PARG);
82520006a0bStron 		break;
82620006a0bStron 	case INIT:
82720006a0bStron 		dohelp = 1;
82820006a0bStron 	}
82920006a0bStron }
83020006a0bStron 
83120006a0bStron /*
832*838f5788Ssimonb  * Handler for the --mouse option.
833*838f5788Ssimonb  */
834*838f5788Ssimonb 	/*ARGSUSED*/
opt_mousecap(int type,char * s)835*838f5788Ssimonb public void opt_mousecap(int type, char *s)
836*838f5788Ssimonb {
837*838f5788Ssimonb 	switch (type)
838*838f5788Ssimonb 	{
839*838f5788Ssimonb 	case TOGGLE:
840*838f5788Ssimonb 		if (mousecap == OPT_OFF)
841*838f5788Ssimonb 			deinit_mouse();
842*838f5788Ssimonb 		else
843*838f5788Ssimonb 			init_mouse();
844*838f5788Ssimonb 		break;
845*838f5788Ssimonb 	case INIT:
846*838f5788Ssimonb 	case QUERY:
847*838f5788Ssimonb 		break;
848*838f5788Ssimonb 	}
849*838f5788Ssimonb }
850*838f5788Ssimonb 
851*838f5788Ssimonb /*
852*838f5788Ssimonb  * Handler for the --wheel-lines option.
853*838f5788Ssimonb  */
854*838f5788Ssimonb 	/*ARGSUSED*/
opt_wheel_lines(int type,char * s)855*838f5788Ssimonb public void opt_wheel_lines(int type, char *s)
856*838f5788Ssimonb {
857*838f5788Ssimonb 	switch (type)
858*838f5788Ssimonb 	{
859*838f5788Ssimonb 	case INIT:
860*838f5788Ssimonb 	case TOGGLE:
861*838f5788Ssimonb 		if (wheel_lines <= 0)
862*838f5788Ssimonb 			wheel_lines = default_wheel_lines();
863*838f5788Ssimonb 		break;
864*838f5788Ssimonb 	case QUERY:
865*838f5788Ssimonb 		break;
866*838f5788Ssimonb 	}
867*838f5788Ssimonb }
868*838f5788Ssimonb 
869*838f5788Ssimonb /*
870*838f5788Ssimonb  * Handler for the --line-number-width option.
871*838f5788Ssimonb  */
872*838f5788Ssimonb 	/*ARGSUSED*/
opt_linenum_width(int type,char * s)873*838f5788Ssimonb public void opt_linenum_width(int type, char *s)
874*838f5788Ssimonb {
875*838f5788Ssimonb 	PARG parg;
876*838f5788Ssimonb 
877*838f5788Ssimonb 	switch (type)
878*838f5788Ssimonb 	{
879*838f5788Ssimonb 	case INIT:
880*838f5788Ssimonb 	case TOGGLE:
881*838f5788Ssimonb 		if (linenum_width > MAX_LINENUM_WIDTH)
882*838f5788Ssimonb 		{
883*838f5788Ssimonb 			parg.p_int = MAX_LINENUM_WIDTH;
884*838f5788Ssimonb 			error("Line number width must not be larger than %d", &parg);
885*838f5788Ssimonb 			linenum_width = MIN_LINENUM_WIDTH;
886*838f5788Ssimonb 		}
887*838f5788Ssimonb 		break;
888*838f5788Ssimonb 	case QUERY:
889*838f5788Ssimonb 		break;
890*838f5788Ssimonb 	}
891*838f5788Ssimonb }
892*838f5788Ssimonb 
893*838f5788Ssimonb /*
894*838f5788Ssimonb  * Handler for the --status-column-width option.
895*838f5788Ssimonb  */
896*838f5788Ssimonb 	/*ARGSUSED*/
opt_status_col_width(int type,char * s)897*838f5788Ssimonb public void opt_status_col_width(int type, char *s)
898*838f5788Ssimonb {
899*838f5788Ssimonb 	PARG parg;
900*838f5788Ssimonb 
901*838f5788Ssimonb 	switch (type)
902*838f5788Ssimonb 	{
903*838f5788Ssimonb 	case INIT:
904*838f5788Ssimonb 	case TOGGLE:
905*838f5788Ssimonb 		if (status_col_width > MAX_STATUSCOL_WIDTH)
906*838f5788Ssimonb 		{
907*838f5788Ssimonb 			parg.p_int = MAX_STATUSCOL_WIDTH;
908*838f5788Ssimonb 			error("Status column width must not be larger than %d", &parg);
909*838f5788Ssimonb 			status_col_width = 2;
910*838f5788Ssimonb 		}
911*838f5788Ssimonb 		break;
912*838f5788Ssimonb 	case QUERY:
913*838f5788Ssimonb 		break;
914*838f5788Ssimonb 	}
915*838f5788Ssimonb }
916*838f5788Ssimonb 
917*838f5788Ssimonb /*
918*838f5788Ssimonb  * Handler for the --file-size option.
919*838f5788Ssimonb  */
920*838f5788Ssimonb 	/*ARGSUSED*/
opt_filesize(int type,char * s)921*838f5788Ssimonb public void opt_filesize(int type, char *s)
922*838f5788Ssimonb {
923*838f5788Ssimonb 	switch (type)
924*838f5788Ssimonb 	{
925*838f5788Ssimonb 	case INIT:
926*838f5788Ssimonb 	case TOGGLE:
927*838f5788Ssimonb 		if (want_filesize && curr_ifile != NULL && ch_length() == NULL_POSITION)
928*838f5788Ssimonb 			scan_eof();
929*838f5788Ssimonb 		break;
930*838f5788Ssimonb 	case QUERY:
931*838f5788Ssimonb 		break;
932*838f5788Ssimonb 	}
933*838f5788Ssimonb }
934*838f5788Ssimonb 
935*838f5788Ssimonb /*
936*838f5788Ssimonb  * Handler for the --intr option.
937*838f5788Ssimonb  */
938*838f5788Ssimonb 	/*ARGSUSED*/
opt_intr(int type,char * s)939*838f5788Ssimonb public void opt_intr(int type, char *s)
940*838f5788Ssimonb {
941*838f5788Ssimonb 	PARG p;
942*838f5788Ssimonb 
943*838f5788Ssimonb 	switch (type)
944*838f5788Ssimonb 	{
945*838f5788Ssimonb 	case INIT:
946*838f5788Ssimonb 	case TOGGLE:
947*838f5788Ssimonb 		intr_char = *s;
948*838f5788Ssimonb 		if (intr_char == '^' && s[1] != '\0')
949*838f5788Ssimonb 			intr_char = CONTROL(s[1]);
950*838f5788Ssimonb 		break;
951*838f5788Ssimonb 	case QUERY: {
952*838f5788Ssimonb 		p.p_string = prchar(intr_char);
953*838f5788Ssimonb 		error("interrupt character is %s", &p);
954*838f5788Ssimonb 		break; }
955*838f5788Ssimonb 	}
956*838f5788Ssimonb }
957*838f5788Ssimonb 
958*838f5788Ssimonb /*
959*838f5788Ssimonb  * Handler for the --header option.
960*838f5788Ssimonb  */
961*838f5788Ssimonb 	/*ARGSUSED*/
opt_header(int type,char * s)962*838f5788Ssimonb public void opt_header(int type, char *s)
963*838f5788Ssimonb {
964*838f5788Ssimonb 	int err;
965*838f5788Ssimonb 	int n;
966*838f5788Ssimonb 
967*838f5788Ssimonb 	switch (type)
968*838f5788Ssimonb 	{
969*838f5788Ssimonb 	case INIT:
970*838f5788Ssimonb 	case TOGGLE:
971*838f5788Ssimonb 		header_lines = 0;
972*838f5788Ssimonb 		header_cols = 0;
973*838f5788Ssimonb 		if (*s != ',')
974*838f5788Ssimonb 		{
975*838f5788Ssimonb 			n = getnum(&s, "header", &err);
976*838f5788Ssimonb 			if (err)
977*838f5788Ssimonb 			{
978*838f5788Ssimonb 				error("invalid number of lines", NULL_PARG);
979*838f5788Ssimonb 				return;
980*838f5788Ssimonb 			}
981*838f5788Ssimonb 			header_lines = n;
982*838f5788Ssimonb 		}
983*838f5788Ssimonb 		if (*s == ',')
984*838f5788Ssimonb 		{
985*838f5788Ssimonb 			++s;
986*838f5788Ssimonb 			n = getnum(&s, "header", &err);
987*838f5788Ssimonb 			if (err)
988*838f5788Ssimonb 				error("invalid number of columns", NULL_PARG);
989*838f5788Ssimonb 			else
990*838f5788Ssimonb 				header_cols = n;
991*838f5788Ssimonb 		}
992*838f5788Ssimonb 		break;
993*838f5788Ssimonb 	case QUERY:
994*838f5788Ssimonb 		{
995*838f5788Ssimonb 			char buf[2*INT_STRLEN_BOUND(int)+2];
996*838f5788Ssimonb 			PARG parg;
997*838f5788Ssimonb 			SNPRINTF2(buf, sizeof(buf), "%d,%d", header_lines, header_cols);
998*838f5788Ssimonb 			parg.p_string = buf;
999*838f5788Ssimonb 			error("header (lines,columns) is %s", &parg);
1000*838f5788Ssimonb 		}
1001*838f5788Ssimonb 		break;
1002*838f5788Ssimonb 	}
1003*838f5788Ssimonb }
1004*838f5788Ssimonb 
1005*838f5788Ssimonb /*
1006*838f5788Ssimonb  * Handler for the --search-options option.
1007*838f5788Ssimonb  */
1008*838f5788Ssimonb 	/*ARGSUSED*/
opt_search_type(int type,char * s)1009*838f5788Ssimonb public void opt_search_type(int type, char *s)
1010*838f5788Ssimonb {
1011*838f5788Ssimonb 	int st;
1012*838f5788Ssimonb 	PARG parg;
1013*838f5788Ssimonb 	char buf[16];
1014*838f5788Ssimonb 	char *bp;
1015*838f5788Ssimonb 	int i;
1016*838f5788Ssimonb 
1017*838f5788Ssimonb 	switch (type)
1018*838f5788Ssimonb 	{
1019*838f5788Ssimonb 	case INIT:
1020*838f5788Ssimonb 	case TOGGLE:
1021*838f5788Ssimonb 		st = 0;
1022*838f5788Ssimonb 		for (;  *s != '\0';  s++)
1023*838f5788Ssimonb 		{
1024*838f5788Ssimonb 			switch (*s)
1025*838f5788Ssimonb 			{
1026*838f5788Ssimonb 			case 'E': case 'e': case CONTROL('E'): st |= SRCH_PAST_EOF;   break;
1027*838f5788Ssimonb 			case 'F': case 'f': case CONTROL('F'): st |= SRCH_FIRST_FILE; break;
1028*838f5788Ssimonb 			case 'K': case 'k': case CONTROL('K'): st |= SRCH_NO_MOVE;    break;
1029*838f5788Ssimonb 			case 'N': case 'n': case CONTROL('N'): st |= SRCH_NO_MATCH;   break;
1030*838f5788Ssimonb 			case 'R': case 'r': case CONTROL('R'): st |= SRCH_NO_REGEX;   break;
1031*838f5788Ssimonb 			case 'W': case 'w': case CONTROL('W'): st |= SRCH_WRAP;       break;
1032*838f5788Ssimonb 			case '-': st = 0; break;
1033*838f5788Ssimonb 			case '^': break;
1034*838f5788Ssimonb 			default:
1035*838f5788Ssimonb 				if (*s >= '1' && *s <= '0'+NUM_SEARCH_COLORS)
1036*838f5788Ssimonb 				{
1037*838f5788Ssimonb 					st |= SRCH_SUBSEARCH(*s-'0');
1038*838f5788Ssimonb 					break;
1039*838f5788Ssimonb 				}
1040*838f5788Ssimonb 				parg.p_char = *s;
1041*838f5788Ssimonb 				error("invalid search option '%c'", &parg);
1042*838f5788Ssimonb 				return;
1043*838f5788Ssimonb 			}
1044*838f5788Ssimonb 		}
1045*838f5788Ssimonb 		def_search_type = norm_search_type(st);
1046*838f5788Ssimonb 		break;
1047*838f5788Ssimonb 	case QUERY:
1048*838f5788Ssimonb 		bp = buf;
1049*838f5788Ssimonb 		if (def_search_type & SRCH_PAST_EOF)   *bp++ = 'E';
1050*838f5788Ssimonb 		if (def_search_type & SRCH_FIRST_FILE) *bp++ = 'F';
1051*838f5788Ssimonb 		if (def_search_type & SRCH_NO_MOVE)    *bp++ = 'K';
1052*838f5788Ssimonb 		if (def_search_type & SRCH_NO_MATCH)   *bp++ = 'N';
1053*838f5788Ssimonb 		if (def_search_type & SRCH_NO_REGEX)   *bp++ = 'R';
1054*838f5788Ssimonb 		if (def_search_type & SRCH_WRAP)       *bp++ = 'W';
1055*838f5788Ssimonb 		for (i = 1;  i <= NUM_SEARCH_COLORS;  i++)
1056*838f5788Ssimonb 			if (def_search_type & SRCH_SUBSEARCH(i))
1057*838f5788Ssimonb 				*bp++ = '0'+i;
1058*838f5788Ssimonb 		if (bp == buf)
1059*838f5788Ssimonb 			*bp++ = '-';
1060*838f5788Ssimonb 		*bp = '\0';
1061*838f5788Ssimonb 		parg.p_string = buf;
1062*838f5788Ssimonb 		error("search options: %s", &parg);
1063*838f5788Ssimonb 		break;
1064*838f5788Ssimonb 	}
1065*838f5788Ssimonb }
1066*838f5788Ssimonb 
1067*838f5788Ssimonb #if LESSTEST
1068*838f5788Ssimonb /*
1069*838f5788Ssimonb  * Handler for the --tty option.
1070*838f5788Ssimonb  */
1071*838f5788Ssimonb 	/*ARGSUSED*/
opt_ttyin_name(int type,char * s)1072*838f5788Ssimonb public void opt_ttyin_name(int type, char *s)
1073*838f5788Ssimonb {
1074*838f5788Ssimonb 	switch (type)
1075*838f5788Ssimonb 	{
1076*838f5788Ssimonb 	case INIT:
1077*838f5788Ssimonb 		ttyin_name = s;
1078*838f5788Ssimonb 		is_tty = 1;
1079*838f5788Ssimonb 		break;
1080*838f5788Ssimonb 	}
1081*838f5788Ssimonb }
1082*838f5788Ssimonb #endif /*LESSTEST*/
1083*838f5788Ssimonb 
chop_line(void)1084*838f5788Ssimonb public int chop_line(void)
1085*838f5788Ssimonb {
1086*838f5788Ssimonb 	return (chopline || header_cols > 0 || header_lines > 0);
1087*838f5788Ssimonb }
1088*838f5788Ssimonb 
1089*838f5788Ssimonb /*
109020006a0bStron  * Get the "screen window" size.
109120006a0bStron  */
get_swindow(void)1092*838f5788Ssimonb public int get_swindow(void)
109320006a0bStron {
109420006a0bStron 	if (swindow > 0)
109520006a0bStron 		return (swindow);
1096*838f5788Ssimonb 	return (sc_height - header_lines + swindow);
109720006a0bStron }
109820006a0bStron 
1099